4

I have the following datagrid in XAML:

<DataGrid ItemsSource="{Binding View}" AutoGenerateColumns="False" IsReadOnly="True"
          GridLinesVisibility="None" CanUserAddRows="False" CanUserDeleteRows="False" 
          CanUserResizeColumns="False" CanUserResizeRows="False" 
          CanUserReorderColumns="False" >
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="{x:Type DataGridColumnHeader}">
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="FontSize" Value="12" />
        </Style>
    </DataGrid.ColumnHeaderStyle>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Type" Width="200" FontSize="12" 
                            Binding="{Binding Path=Name}" />
        <DataGridTemplateColumn Header="Ingredients" Width="*">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                  <DataGrid ItemsSource="{Binding Ingredients}" 
                            AutoGenerateColumns="False" IsReadOnly="True"
                            GridLinesVisibility="None" CanUserAddRows="False" 
                            CanUserDeleteRows="False" CanUserResizeColumns="False"
                            CanUserResizeRows="False" CanUserReorderColumns="False" >
                        <DataGrid.ColumnHeaderStyle>
                            <Style TargetType="{x:Type DataGridColumnHeader}">
                                <Setter Property="FontWeight" Value="Bold" />
                                <Setter Property="FontSize" Value="12" />
                            </Style>
                        </DataGrid.ColumnHeaderStyle>
                        <DataGrid.Columns>
                            <DataGridTextColumn Header="Ingredients" 
                                            Width="*" FontSize="12"
                                            Binding="{Binding Path=IngredientName}"/>
                            <DataGridTextColumn Header="Quantite" Width="*" 
                                          FontSize="12" Binding="{Binding Path=Qty}"/>
                        </DataGrid.Columns>
                    </DataGrid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

I am trying to find a way to create the datagrid dynamically (in-code) so that I can create multiple copies of it and bind it to different datasources at run-time.

Is this possible? Anyone know how I could go about it for a datagrid complicated like this?

4
  • Why would you like to creat copies of the data grid? Just change the dataSource at run time Commented Apr 20, 2013 at 12:01
  • I need to show MANY grids Commented Apr 20, 2013 at 16:16
  • @JScwartz is the number of grids decided at run time by user action ? or its just many grids but const number? Commented Apr 21, 2013 at 5:43
  • @makc Decided at run-time but not by the user, by the amount (# of rows) of data I get from the DB at load at any particular time Commented Apr 21, 2013 at 17:54

1 Answer 1

10

First, move as much as possible of the different settings out into reusable Styles and DataTemplates, leaving very little in the DataGrid itself:

<UserControl ... >
  <UserControl.Resources>
  <Style x:Key="GridHeaderStyle" 
         TargetType="{x:Type DataGridColumnHeader}">
     <Setter Property="FontWeight" Value="Bold" />
     <Setter Property="FontSize" Value="12" />
  </Style>
  <Style x:Key="ReadOnlyGridStyle" TargetType="{x:Type DataGrid}" >
      <Setter Property="AutoGenerateColumns" Value="False" />
      <Setter Property="IsReadOnly" Value="True" />
      <Setter Property="GridLinesVisibility" Value="None" />
      <Setter Property="CanUserAddRows" Value="False" />
      <Setter Property="CanUserDeleteRows" Value="False" />
      <Setter Property="CanUserResizeColumns" Value="False" />
      <Setter Property="CanUserResizeRows" Value="False" />
      <Setter Property="CanUserReorderColumns" Value="False" />
      <Setter Property="ColumnHeaderStyle" 
              Value="{StaticResource GridHeaderStyle}" />
  </Style>

  <DataTemplate x:Key="IngredientsCellTemplate">
    <DataGrid ItemsSource="{Binding Ingredients}" 
               Style="{StaticResource ReadOnlyGridStyle}">
     <DataGrid.Columns>
       <DataGridTextColumn Header="Ingredients" Width="*" 
                         FontSize="12"
               Binding="{Binding Path=IngredientName}" />
       <DataGridTextColumn Header="Quantite" Width="*" 
                         FontSize="12"
               Binding="{Binding Path=Qty}" />
     </DataGrid.Columns>
    </DataGrid>
  </DataTemplate>
</UserControl.Resources>

 <!-- A DataGrid using our Styles: -->
 <DataGrid ItemsSource="{Binding View}" 
          Style="{StaticResource ReadOnlyGridStyle}" >
  <DataGrid.Columns>
     <DataGridTextColumn Header="Type" 
       Width="200" FontSize="12"
       Binding="{Binding Path=Name}" />
     <DataGridTemplateColumn Header="Ingredients" 
       Width="*"
       CellTemplate="{StaticResource IngredientsCellTemplate}" />
  </DataGrid.Columns>
 </DataGrid>
</UserControl>

Then it gets a lot easier to create new DataGrids in your code-behind, using the existing Styles:

var datagrid = new DataGrid();
datagrid.Style = FindResource("ReadOnlyGridStyle") as Style;

datagrid.Columns.Add(new DataGridTextColumn()
{
    Header = "Type",
    Width = new DataGridLength(200),
    FontSize = 12,
    Binding = new Binding("Name")
});
datagrid.Columns.Add(new DataGridTemplateColumn()
{
    Header = "Ingredients",
    Width = new DataGridLength(1, DataGridLengthUnitType.Star),
    CellTemplate = FindResource("IngredientsCellTemplate") as DataTemplate
});

datagrid.ItemsSource = ...
Sign up to request clarification or add additional context in comments.

2 Comments

I am having issues with the line Binding = new Binding("Name") as this is generated a compilation error: Error 3 The type or namespace name 'Binding' could not be found (are you missing a using directive or an assembly reference?)
At the very top in your code file you should see a few lines like this: using System.... Add this line to that list: using System.Windows.Data;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.