【问题标题】:Binding DataGrid to Collection<List>将 DataGrid 绑定到 Collection<List>
【发布时间】:2012-08-16 16:22:53
【问题描述】:

DataGrid 可以绑定到 Collection&lt;List&gt; 类型吗?

有几个关于将DataGrid 绑定到Collection&lt;Collection&gt; 的问题,它也对我有用。但是,我正在寻找 DataGrid Collection&lt;List&gt;。


当我尝试时,List 只是在DataGrid 上显示为一个对象,例如:

姓名
- System.Collections.Generic.List'1[System.Int32]
值
鲍勃
23
43000
+ System.Collections.Generic.List'1[System.Int32]


在这种情况下,List 与 Collection 有何不同?

List 没有条目标识符,因此列表中的条目无法自动分组到 DataGrid 中的列中。

示例:

在Collection&lt;List&gt;:
entry1 包含 List: "Bob", 23, 43000 和
entry2 包含 List: "Alice", 42, 71000。

我能否将DataTemplate 用于List 以获得以下显示?
姓名 |年龄 |工资
鲍勃 | 23 | 43000
爱丽丝 | 42 | 71000

请注意,字符串 Name、Age 和 Salary 不是 Lists 的一部分。


我的计划

  1. 将标题行绑定到List&lt;String&gt;,以获取DataGrid's标题中的列名。
  2. 将剩余行绑定到Collection&lt;List&gt;,以获取DataGrid中填充的数据。

具体来说,我想知道是否可以将这 3 个字符串(姓名、年龄、工资)放入 List&lt;String&gt; 并仅将标题行绑定到它。 DataGrid 的其余行可以绑定到 Collection。

这可能吗?


理想情况下,我想使用 Infragistics' XamDataGrid,但 DataGrid 的任何解决方案都是一个很好的起点。


编辑

我为什么不用Collection&lt;Employee&gt;? 我只想在DataGrid 中显示列的子集。

我有大约 5 个屏幕,显示来自 Employee 和 EmployeeDetails 两种类型的列。这两种类型都有大约 100 个不同的属性,我只对在每个屏幕上将大约 20 个属性显示为列感兴趣。因此,我为每个仅包含这 20 个属性的 Employee/EmployeeDetails 对象创建了一个 List。

子集是在运行时通过读取一些配置文件来定义的。因此,我无法静态定义我需要展示的内容。

【问题讨论】:

    标签: wpf data-binding wpfdatagrid infragistics


    【解决方案1】:

    您可以使用绑定转换器来提取列表中的成员:

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is List<string> && parameter is int)
        {
            return ((List<string>)value)[(int)parameter];
        }
    
        return null;
    }
    

    ...但老实说,我不明白你想要达到什么目的。你的字符串列表代表一个对象的属性,为什么不直接使用Collection&lt;Employee&gt; Employee 是

    public class Employee : INotifyPropertyChanged
    {
        public string Bob
        {
            ...
        }
    
        public int Age
        {
            ...
        }
    
        public double Salary
        {
            ...
        }
    }
    

    强类型,更易读,更易维护。


    编辑:

    阅读您的编辑后:绝对不要使用List&lt;string&gt;。只是不要让您的 XamDataGrid 为每个字段自动生成一列。您还 some examples 讨论了如何隐藏列。


    编辑:

    与公开Collection&lt;List&lt;string&gt;&gt;相比,公开Collection&lt;Employee&gt;属性+在后面编写一些代码对MVVM更友好。

    请记住,XamDataGrid 控件的限制纯粹与 MVVM 模式的视图部分相关。 不要因此而更改 ViewModel 逻辑。

    还有一个相关的问题可能会有所帮助:XamDataGrid column visibilty is not working using MVVM

    【讨论】:

    • 当我考虑你的答案时,请参阅编辑了解我为什么不使用Collection&lt;Employee&gt;。
    • 另外,子集是在运行时通过读取一些配置文件来定义的。因此,我无法静态定义我需要展示的内容。
    • @user640378 如果需要,您可以在运行时动态隐藏列(参见示例)
    • 感谢您的更新。动态隐藏列的问题是我需要使用XamDataGrid 的FieldLayout。这将要求我在代码隐藏中包含代码;我正在研究 MVVM 风格的方法。
    【解决方案2】:

    这听起来不对。您在集合中显示的项目只是具有属性的对象。为什么不只是拥有具有这些属性的对象集合呢?

    为了迭代第二个列表,您需要在绑定到该列表的绑定行中使用另一个 ItemsControl 作为其数据源。否则,您将始终只收到 System.Collections.Generic.List'1[System.Int32] 绑定值,因为这是正在迭代的内容的当前级别。

    如果你想让它保持通用,你甚至可以绑定到一个集合,允许对象定义它的属性,并且在 Datagrid 中,只绑定到它认为应该可见的属性(无论对象是否支持) )。

    【讨论】:

    • 关闭自动生成列,您不必担心“创建列的子集”。您只需定义要显示的内容,这就是显示的内容。
    • 好吧,子集是在运行时通过读取一些配置文件来定义的。因此,我无法静态定义我需要展示的内容。
    猜你喜欢
    • 2013-12-07
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 2017-05-13
    • 2011-07-09
    • 1970-01-01
    相关资源
    最近更新 更多