如何在WPF中动态创建数据网格?

4

我在 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>

我正在尝试找到一种方法来动态创建数据网格(在代码中),以便我可以在运行时创建多个副本并将其绑定到不同的数据源。这是否可行?有人知道我如何处理像这样复杂的数据网格吗?

为什么要创建数据网格的副本?只需在运行时更改数据源即可。 - makc
我需要展示许多网格。 - JSchwartz
@JScwartz 是用户在运行时决定的网格数量吗?还是有很多网格但数量固定? - makc
@makc 在运行时决定,而不是由用户决定,取决于从数据库在任何特定时间加载的数据量(行数)。 - JSchwartz
1个回答

10

首先,尽可能将不同的设置移出到可重用的样式(Styles)数据模板(DataTemplates)中,使得DataGrid本身只保留很少的设置:

<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>

然后,使用现有的样式在您的代码后端创建新的数据网格会变得更加容易:
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 = ...

我在使用 Binding = new Binding("Name") 时遇到了问题,因为这会生成编译错误:Error 3 The type or namespace name 'Binding' could not be found (are you missing a using directive or an assembly reference?)。 - JSchwartz
在你的代码文件的最顶部,你应该看到几行像这样的代码:using System...。将这一行添加到列表中:using System.Windows.Data; - Sphinxxx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接