WPF DataGrid 基于 ID 显示数据

WPF DataGrid displaying data based on ID

假设我有 Item class,其中 Category 属性 为 ObjectId类型.

class Item
{
    public ObjectId Id;
    public string Name;
    public ObjectId Category;
}

class Category
{
    public ObjectId Id;
    public string Name;
}

我想使用 ViewModel.Items[=83= 显示 DataGrid 中的所有项目]collection秒。像这样。

Id Name Category
Item.Id Item.Name Category.Name

问题是,我如何从 Category 实例中获取 Name 值并匹配 ID Item.Category 属性?

根据我的发现,有 3 种方法:自定义转换器、使用反射和包装器的通用转换器 objects。

1.自定义转换器

这是 WPF 的黄金标准(反正我不喜欢)。我可以编写一个 CategoryIdToName multi-value 转换器并简单地提供 ViewModel.CategoriesItem.Category 获取类别名称。

缺点是我必须使用样板代码创建很多转换器。

2。通用转换器

这与前面的类似,但使用反射我可以编写 ObjectIdToInstanceValue multi-value 转换器并提供 3 个参数:collection、ObjectId 和属性 名称。此转换器将尝试使用 ObjectId 在 collection 中查找项目,并通过名称获取 属性 值。

缺点是 Reflection 很昂贵(至少据我所知)。但我只需要一个转换器即可。

这两种方法对我没有吸引力。我个人不喜欢转换器,我相信它们会影响应用程序的性能。

3。 Object包装器

我从未见过有人实施甚至建议过这种方法。基本上,我可以创建一个 DataGridItem class,它可以有 ItemCategory特性。然后在 ViewModel 中我可以填充 collection 并直接绑定到属性。

又有意思了,我从来没见过这种方式被用在任何地方。

最好的方法是什么?

如果要在 DataGrid 中显示三列,您应该创建一个视图模型 class,其中每一列都有一个 属性。我想这就是您在问题中所说的 object wrapper

DataGrid 的视图模型将负责将您当前的数据转换为 IEnumerable<T>,其中 T 是具有 Id 的视图模型或包装器类型, NameCategory 属性。

然后您将 DataGridItemsSource 绑定到此 IEnumerable<T> 属性 并将每一列绑定到 T 的 属性和往常一样。

简而言之,这是一个 MVVM 解决方案。

这里有一些伪代码(没有真正检查过)添加到我的评论/@mm8 的解决方案中:

public class GridItem(){
  public string ItemName {get;set;}
  public string CategoryName {get;set;}
}

然后一些方法来查询和建立你的 GridItem collection:

public IEnumerable<GridItem> GetGridItems(){
  return _repository.Items.Select(i => new GridItem{
    ItemName = i.Name,
    CategoryName = i.Category.Name
  })
}