c# - 如何创建可以显示不同类型对象的 C# WPF DataGrid?

标签 c# wpf mvvm data-binding

我刚刚开始学习 C#,我正在尝试使用 MVVM 原则创建一个 WPF 应用程序,但我对数据绑定(bind)和数据网格的工作方式有些困惑。基本上现在我有一个执行以下操作的简单应用程序:

  • 我有一个实现 IGraphType 接口(interface)的 GraphType1 对象和 GraphType2 对象。
  • GraphType1 和 GraphType2 对象分别包含 GraphType1Series 和 GraphType2Series 对象的 ObservableCollection,它们实现了 IGraphTypeSeries 接口(interface)
  • 我有一个 ListBox,可让您添加和删除 IGraphType 对象。当您选择一个 IGraphType 对象时,它会变成 CurrentGraphObject
  • 我有一个显示 CurrentGraphObject 的 IGraphTypeSeries 集合的 DataGrid

我的问题是,我如何设置 DataGrid,以便 DataGrid 列反射(reflect)当前所选 IGraphType 的 IGraphTypeSeries 的属性,而不管它是 GraphType1Series 还是 GraphType2Series,因为这两个将具有不同的属性?我没有使用 AutoGenerateColumns=true,因为我希望其中一列成为其中一个属性的 ComboBox 列。

下面是我当前的 DataGrid 代码。它有两个列绑定(bind)到 IGraphTypeSeries 对象的 MachineName 和 MetricName 属性。但并非所有 IGraphTypeSeries 都具有这些属性。我不确定如何创建数据网格,以便列和列绑定(bind)根据用户在列表框中选择的 CurrentGraphObject 的类型而改变。

<DataGrid Margin="0,0,0,0" AutoGenerateColumns="False" CanUserDeleteRows="True" CanUserAddRows="True" ItemsSource="{Binding Path=CurrentGraphObject.SeriesList}">
            <DataGrid.Columns>
                <DataGridTextColumn  Header="Machine Name" IsReadOnly="False" Binding="{Binding MachineName}">
                </DataGridTextColumn>
                <DataGridComboBoxColumn
                    Header="Metric Name"
                    ItemsSource="{DynamicResource MetricObjects}"
                    SelectedValueBinding="{Binding MetricName}"
                    SelectedValuePath="Path"
                    DisplayMemberPath="Alias"
                    >
                </DataGridComboBoxColumn>
            </DataGrid.Columns>
        </DataGrid>

我不确定是否需要为每个图形类型创建单独的 View 或数据网格,或者我是否可以编辑此数据网格。我尝试使用 DataTrigger,但我无法弄清楚如何让 DataTrigger 编辑 DataGrid 列的属性的语法。

最佳答案

我想提出两种可能的解决方案。

解决方案 A:创建特定于显示的 View 模型

与其将不同的图形对象绑定(bind)到网格,不如创建一个专用于数据显示的单独 View 模型。 然后,您可以使用不同的图形对象初始化此 View 模型。在您的网格中,您始终可以绑定(bind)到与 DataGrid 的列相匹配的显示特定 View 模型的属性。

这本质上就是 MVVM 的目的, View 模型充当 View 和模型之间的层。在您的例子中,模型是图形对象, View 模型将它们包装起来以显示在 View 中。

这种方法的想法也是将复杂性从 View (xaml) 转移到 View 模型,以避免复杂的 xaml 定义。


解决方案 B:使用 ListBox 而不是 DataGridItemTemplateSelector

本教程展示了如何将 ItemTemplateSelector 与 ListView 控件结合使用:How to use a DataTemplateSelector to switch the Template depending on the data

这里的想法是为特定的绑定(bind)源类型选择合适的 DataTemplate

您写道您想要使用 DataGrid。我不确定是否可以将 ItemTemplateSelectorDataGrid 一起使用,因为那时您需要在 DataTemplate 中创建一个行对象,并且我不知道这是如何实现的。

但我更喜欢解决方案 A。

关于c# - 如何创建可以显示不同类型对象的 C# WPF DataGrid?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33572779/

相关文章:

c# - 如何在处理空值和逗号时连接 C# 中的地址成员

c# - 单击wpf中的RepeatButton时如何将光标聚焦在文本框中?

c# - WPF XAML : The specified conversion is not valid 中不受控制的异常

silverlight - 如何动态发现 Silverlight prism 应用程序中所有模块中的所有 XAML 文件

c# - 异步任务中出现大量 ping - 出现异常 "An asynchronous call is already in progress."

c# - 在 C# 中使用数据库值填充 ConcurrentDictionary 的锁定注意事项

wpf - 强制三态复选框不移动到不确定状态

wpf - Silverlight 绑定(bind)到字典中的项目

c# - 在WPF TreeView (MVVM)中取消选择所选项目

c# - 如何让标签来回滚动一个词?