【问题标题】:wpf DataGrid of UserControls用户控件的 wpf DataGrid
【发布时间】:2014-07-21 00:26:41
【问题描述】:

我正在尝试有一个 DataGrid,它在其行的每个单元格中显示一个用户控件。强调 DataGrid 必须是动态的,因为列数对于每种使用情况都是动态的。

在我的 xaml 代码 (XAML) 中,我将此作为 DataGrid 的声明:

<Grid Grid.Column="1" Margin="0,10,0,0">
      <DataGrid AutoGenerateColumns="False" x:Name="planningTable" FrozenColumnCount="1"/> 
</Grid>

我的用户控件看起来像这样(UserControl 已经完成并且运行良好):

作为 DataGrid 的结果,我希望在 DataGrid 的每个单元格中都有这个 UserControl 这意味着 DataGrid Rows 必须在每个 Cell 中显示此 UserControl。 我为这个技巧搜索了很多,但似乎 DataGrid 无法在单元格中托管 UserControl。

我想要执行此操作的 C# 代码,请不要使用 XAML 代码,因为它都是动态的!

【问题讨论】:

  • 您可以以 XAML 方式拥有它(这太简洁和动态将起作用)。但是您需要添加更多详细信息,例如您想要多少列和行? ItemsSource 是否绑定到某个集合?
  • 是的,确实可以通过 DataBinding 使用 XAML 动态实现这一点。但我想要执行此操作的 c# 代码,因为我没有使用数据绑定!

标签: c# wpf datagrid user-controls advanceddatagrid


【解决方案1】:

就像我在评论中提到的那样,您只能使用 XAML 动态地执行此操作。 在后面的代码中执行此操作,您最终可能会编写大量代码并松懈 WPF 的重要功能。最重要的是 UI Virtualization 如果您自己手动创建行。


如果您不想要任何绑定支持并希望显示所有单元格都填充了 UserControl 的纯 dataGrid,您可以这样做:

它将显示 2 列和 100 行填充有您的自定义用户控件:

<Grid>
    <Grid.Resources>
        <ObjectDataProvider x:Key="EnumerableRange"
                 xmlns:sys="clr-namespace:System;assembly=mscorlib"
                 xmlns:linq="clr-namespace:System.Linq;assembly=System.Core"
                 ObjectType="{x:Type linq:Enumerable}" MethodName="Range">
            <ObjectDataProvider.MethodParameters>
                <sys:Int32>1</sys:Int32>
                <sys:Int32>100</sys:Int32>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Grid.Resources>
    <DataGrid AutoGenerateColumns="False" IsReadOnly="True"
            CanUserAddRows="False"
            CanUserDeleteRows="False"
            ItemsSource="{Binding Source={StaticResource EnumerableRange}}">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Test1">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <local:SampleUserControl/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="Test2">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <local:SampleUserControl/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

更新

如果您想动态设置列,就像我在 cmets 中提到的那样,您必须将 AutoGenerateColumns 设置为 False 并手动添加 Columns 集合。除了手动创建 DataGridTemplateColumns 之外,您还可以在 DataGrid 的资源部分声明它并在后面的代码中使用它。

XAML

<Grid>
    <Grid.Resources>
        <ObjectDataProvider x:Key="EnumerableRange"
            xmlns:sys="clr-namespace:System;assembly=mscorlib"
            xmlns:linq="clr-namespace:System.Linq;assembly=System.Core"
            ObjectType="{x:Type linq:Enumerable}" MethodName="Range">
            <ObjectDataProvider.MethodParameters>
                <sys:Int32>1</sys:Int32>
                <sys:Int32>100</sys:Int32>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Grid.Resources>
    <DataGrid AutoGenerateColumns="False"
                x:Name="dataGrid"
                IsReadOnly="True"
                CanUserAddRows="False"
                CanUserDeleteRows="False"
                ItemsSource="{Binding Source={StaticResource EnumerableRange}}">
        <DataGrid.Resources>
            <DataGridTemplateColumn x:Key="TemplateColumn" x:Shared="False">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <local:SampleUserControl/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Resources>
    </DataGrid>
</Grid>

背后的代码

public partial class MainWindow : Window
{
    private void CreateDataGridColumns()
    {
        for (int i = 0; i < 10; i++) // Change number of columns here.
        {
            DataGridTemplateColumn templateColumn = 
                  (DataGridTemplateColumn)dataGrid.Resources["TemplateColumn"];
            templateColumn.Header = String.Format("Test {0}", i + 1);
            dataGrid.Columns.Add(templateColumn);
        }
    }

    public MainWindow()
    {
        InitializeComponent();
        CreateDataGridColumns();
    }
}

【讨论】:

  • 非常感谢@Rohit,它工作得很好!!!我太棒了,你能告诉我如何使列计数为动态,例如有时它是 6 列和 X 列在其他时间
  • 您能告诉我如何使 DataGrid 列计数为动态吗?我会很高兴的。
  • 另一种方法是在 dataGrid 加载时从后面的代码中手动添加列。但就像我说的那样,如果你这样做,你将失去 UI 虚拟化,即如果你添加例如 10 列,你会看到在 UI 上呈现的一些滞后。但如果你在 XAML 中手动添加 10 列,它会立即显示出来。
  • 我已经更新了另一种方法来回答。看看这是否适合你。 (显然绑定是更好的方法,但如果你不想绑定任何东西,这也可以)。
  • 非常感谢兄弟!!!你太棒了!!!!非常感谢!!
猜你喜欢
  • 2021-11-25
  • 1970-01-01
  • 2010-12-06
  • 1970-01-01
  • 2012-08-14
  • 2014-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多