Select to view content in your preferred language

Binding one Data Grid Text Column to different fields

3010
8
06-09-2011 08:18 AM
JoannaLaroussi
Emerging Contributor
I am using data grid to display a query results. Five of my fields are always the same, by the last one depends from the user input; for example, when user enters 01001 (InputPED.Text), I would like to display values for the column called ???S_01001???. Saying this I would like to be able bind my DataGridTextColumn to different fields.

Here is like my code looks like now:

<slData:DataGrid.Columns>
<slData:DataGridTextColumn CanUserSort="True" Width="200" Binding="{Binding Attributes[Street]}" Header="Street Name"/>
<slData:DataGridTextColumn CanUserSort="True" Width="80" Binding="{Binding Attributes[FromLeft]}" Header="From Left"/>
<slData:DataGridTextColumn CanUserSort="True" Width="80" Binding="{Binding Attributes[ToLeft]}" Header="To Left"/>
<slData:DataGridTextColumn CanUserSort="True" Width="81" Binding="{Binding Attributes[FromRight]}" Header="From Right"/>
<slData:DataGridTextColumn CanUserSort="True" Width="80" Binding="{Binding Attributes[ToRight]}" Header="To Right"/>
<slData:DataGridTextColumn CanUserSort="True" Width="50" Binding="{Binding Attributes[S_ + InputPED.Text]}" Header="Code"/>
</slData:DataGrid.Columns>

The last data grid do not returns any results to my grid. How I can bind to different fields each time?
0 Kudos
8 Replies
TerryGiles
Frequent Contributor
I could be wrong but I think the binding is interpreted literally in the XAML, so it's looking for an attribute name 'S_ + InputPED.Text'  in your underlying data.

Maybe in the Loaded event for the datagrid you can do something like this -

In the XAML remove the column from the grid

in the code behind
                string bindName = "Attributes[S_" + InputPED.Text + "]";

                DataGridTextColumn colPED = new DataGridTextColumn();
                colPED.Header = "Code";
                colPED.CanUserSort = true;
                colPED.Width = new DataGridLength(50);
                colPED.Binding = new Binding(bindName);
                // assuming the datagrid is called gridData - replace with the name of your datagrid
                gridData.Columns.Add(colPED);

0 Kudos
JoannaLaroussi
Emerging Contributor
I could be wrong but I think the binding is interpreted literally in the XAML, so it's looking for an attribute name 'S_ + InputPED.Text'  in your underlying data.

Maybe in the Loaded event for the datagrid you can do something like this -

In the XAML remove the column from the grid

in the code behind
                string bindName = "Attributes[S_" + InputPED.Text + "]";

                DataGridTextColumn colPED = new DataGridTextColumn();
                colPED.Header = "Code";
                colPED.CanUserSort = true;
                colPED.Width = new DataGridLength(50);
                colPED.Binding = new Binding(bindName);
                // assuming the datagrid is called gridData - replace with the name of your datagrid
                gridData.Columns.Add(colPED);



Thanks for your answer! I changed one line

colPED.Binding = new Binding(bindName);

to

colPED.Binding = new System.Windows.Data.Binding(bindName);

because of an error: The type or namespace name 'Binding' could not be found (are you missing a using directive or an assembly reference?)

but I am still not there. I have an error for this line:

PEDQueryResultPanelGrid.Columns.Add(colPED);

'System.Windows.Controls.Grid' does not contain a definition for 'Columns' and no extension method 'Columns' accepting a first argument of type 'System.Windows.Controls.Grid' could be found (are you missing a using directive or an assembly reference?)

I am using in XAML data grid and I am not sure that this error is about using data grid (should I use different kind of grid?) or I am missing something else in my code.

I tried to use regular grid

<Grid x:Name="PEDQueryNewDataGrid" Grid.Row="10" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Code" Margin="10" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</Grid>

But this did not solve my problem. Any ideas?
0 Kudos
TerryGiles
Frequent Contributor
The type of the control to add the column to should be a System.Windows.Controls.DataGrid; a System.Windows.Control.Grid is a layout container.  In your original post, you have the XAML for the DataGrid.Columns - what is the name of the data grid those belong to?  That's the name of the control that colPED should be Added to.  Can you post the full XAML of the data grid?
0 Kudos
JoannaLaroussi
Emerging Contributor
I appreciate a lot your help!

I tired System.Windows.Controls.DataGrid

colPED.Binding = new System.Windows.DataGrid.Binding(bindName);

but it did not work: The type or namespace name 'DataGrid' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?)

I am posting a little bigger chunk of XAML for context. The PED grid part is on the end.

<!-- Query Panel -->
<userControls:GlassPanel x:Name="AllQueryPanel" Grid.Row="1" IsOpen="False" HorizontalAlignment="Right" VerticalAlignment="Top" IsResizeable="True" >
<StackPanel Orientation="Vertical">
<Grid  HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,15,15,0" >
<Rectangle Stroke="Gray"  RadiusX="10" RadiusY="10" Fill="#77919191" Margin="0,0,0,5" >
<Rectangle.Effect>
<DropShadowEffect/>
</Rectangle.Effect>
</Rectangle>

<Rectangle Fill="#DDFFFFFF" Stroke="DarkGray" RadiusX="5" RadiusY="5" Margin="10,10,10,15" />
<!--Outer Stack panel-->
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" Margin="30,20,30,30">
<!--SELECT QUERIES COMBO BOX -->
<!--Map Layer Query Stack panel-->
<StackPanel Name="stkLayerQuery" Visibility="Visible" Orientation="Horizontal" HorizontalAlignment="Left" >
<TextBlock Text="Select a Map Layer: " TextAlignment="Right" Margin="3" />
<ComboBox Name="cmboLayerQuery" Width="150" SelectionChanged="cmboLayerQuery_SelectionChanged" Margin="5">
<ComboBoxItem Content="School"></ComboBoxItem>
<ComboBoxItem Content="PED"></ComboBoxItem>
<ComboBoxItem Content="Street"></ComboBoxItem>
<ComboBoxItem Content="School District"></ComboBoxItem>
                               
</ComboBox>
</StackPanel>

<!--Some other code for doing queries and displaing results for different layers -->

<!-- Query for PED -->
<!-- Query PED by OPT code -->
<StackPanel Name="stkPED"  Visibility="Collapsed"  >
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="OPT Code(s): " TextAlignment="Right" HorizontalAlignment="Right" VerticalAlignment="Bottom" Grid.Row="0" Grid.Column="0" Margin="3" />
<TextBox x:Name="InputPED" Text="" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" Width="100" Margin="3" KeyDown="TextBoxEnterKey_KeyDown"/>
<Button x:Name="PEDQueryButton" Content="Query" Width="80" HorizontalAlignment="Center" Grid.Row="1" Grid.Column="0"
Click="PEDQueryButton_Click"  Margin="3"></Button>
<Button x:Name="PEDClearQueryButton" Content="Clear" Width="80" HorizontalAlignment="Center" Grid.Row="1" Grid.Column="1"
Click="PEDClearButton_Click"  Margin="3"></Button>
<Button x:Name="PEDCodeClearAllQueryButton" Content="Clear All" Width="80" HorizontalAlignment="Center" Grid.Row="1" Grid.Column="2"
Click="ClearAllQueryButton_Click"  Margin="3"></Button>
</Grid>
</StackPanel>
</StackPanel>
</Grid>

<!�??And finally Grid for displaying PED query results-->

<!-- PED Query Results Data Grid Stack panel-->
<Grid x:Name="PEDQueryResultPanelGrid" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,15,15" Visibility="Collapsed">
<Rectangle Stroke="Gray"  RadiusX="10" RadiusY="10" Fill="#77919191" Margin="0,0,0,5" >
<Rectangle.Effect>
<DropShadowEffect/>
</Rectangle.Effect>
</Rectangle>
<Rectangle Fill="#FFFFFFFF" Stroke="DarkGray" RadiusX="5" RadiusY="5" Margin="10,17,10,15" />

<StackPanel Orientation="Vertical" HorizontalAlignment="Center" Margin="10,2,15,15">
<TextBlock HorizontalAlignment="Left" Text="Streets Found" Foreground="White" FontSize="9"  FontWeight="Bold" Margin="2,0,0,5" />

<slData:DataGrid x:Name="PEDQueryNewDataGrid" AutoGenerateColumns="False" HeadersVisibility="Column" Background="White"
IsReadOnly="True" Canvas.Left="10" Canvas.Top="50" MaxHeight="150" Width="315"
HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" CanUserSortColumns="True"
RowStyle="{StaticResource HighLightRow}"
SelectionChanged="QueryHighlightDataGrid_SelectionChanged"
LoadingRow="QueryHighlightDataGrid_LoadingRow">
<slData:DataGrid.Columns>
<slData:DataGridTextColumn CanUserSort="True" Width="200" Binding="{Binding Attributes[Street]}" Header="Street Name"/>
<slData:DataGridTextColumn CanUserSort="True" Width="80" Binding="{Binding Attributes[FromLeft]}" Header="From Left"/>
<slData:DataGridTextColumn CanUserSort="True" Width="80" Binding="{Binding Attributes[ToLeft]}" Header="To Left"/>
<slData:DataGridTextColumn CanUserSort="True" Width="81" Binding="{Binding Attributes[FromRight]}" Header="From Right"/>
<slData:DataGridTextColumn CanUserSort="True" Width="80" Binding="{Binding Attributes[ToRight]}" Header="To Right"/>
</slData:DataGrid.Columns>
</slData:DataGrid>
</StackPanel>
                   
</Grid>

<!-- Some other code for results from other queries -- >

</StackPanel>
</userControls:GlassPanel>
0 Kudos
TerryGiles
Frequent Contributor
Sorry, last post was not quite clear.

For the Binding, it should still be System.Windows.Data.Binding(bindName).  The control on to which we're adding the column needs to be of the type System.Windows.Controls.DataGrid....looking at your XAML that would be PEDQueryNewDataGrid.  Try this code -

                string bindName = "Attributes[S_" + InputPED.Text + "]";

                DataGridTextColumn colPED = new DataGridTextColumn();
                colPED.Header = "Code";
                colPED.CanUserSort = true;
                colPED.Width = new DataGridLength(50);
                colPED.Binding = new System.Windows.Data.Binding(bindName);

                PEDQueryNewDataGrid.Columns.Add(colPED);
0 Kudos
JoannaLaroussi
Emerging Contributor
You are right. I worked on it and found the same solution. Now I just  need to find a way to delete columns, because after each query I have one more column called �??Code�?�
0 Kudos
TerryGiles
Frequent Contributor
try something like this above the code which adds Code to the grid

            foreach (DataGridColumn col in PEDQueryNewDataGrid.Columns)
            {
                if (col.Header.ToString().ToLower() == "code")
                {
                    gridUnmapped.Columns.Remove(col);
                    break;
                }
            }
0 Kudos
JoannaLaroussi
Emerging Contributor
Terry �?? thanks a lot for all your time and help. It is working perfectly like I need it. Here is my final code:

case "PED":
                        PEDQueryNewDataGrid.ItemsSource = featureSet.Features;
                        PEDQueryResultPanelGrid.Visibility = Visibility.Visible;

                        //for binding field with S_ opt code in PEDQueryResultPanelGrid
                        foreach (DataGridColumn col in PEDQueryNewDataGrid.Columns)
                        {
                            if (col.Header.ToString().ToLower() == "code")
                            {
                                PEDQueryNewDataGrid.Columns.Remove(col);
                                break;
                            }
                        }
                        string bindName = "Attributes[S_" + InputPED.Text + "]";
                        DataGridTextColumn colPED = new DataGridTextColumn();
                        colPED.Header = "Code";
                        colPED.CanUserSort = true;
                        colPED.Width = new DataGridLength(50);
                        colPED.Binding = new System.Windows.Data.Binding(bindName);
                        PEDQueryNewDataGrid.Columns.Add(colPED);
                        break;
0 Kudos