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.Categories 和 Item.Category 获取类别名称。
缺点是我必须使用样板代码创建很多转换器。
2。通用转换器
这与前面的类似,但使用反射我可以编写 ObjectIdToInstanceValue multi-value 转换器并提供 3 个参数:collection、ObjectId 和属性 名称。此转换器将尝试使用 ObjectId 在 collection 中查找项目,并通过名称获取 属性 值。
缺点是 Reflection 很昂贵(至少据我所知)。但我只需要一个转换器即可。
这两种方法对我没有吸引力。我个人不喜欢转换器,我相信它们会影响应用程序的性能。
3。 Object包装器
我从未见过有人实施甚至建议过这种方法。基本上,我可以创建一个 DataGridItem class,它可以有 Item 和 Category特性。然后在 ViewModel 中我可以填充 collection 并直接绑定到属性。
又有意思了,我从来没见过这种方式被用在任何地方。
最好的方法是什么?
如果要在 DataGrid
中显示三列,您应该创建一个视图模型 class,其中每一列都有一个 属性。我想这就是您在问题中所说的 object wrapper。
DataGrid
的视图模型将负责将您当前的数据转换为 IEnumerable<T>
,其中 T
是具有 Id
的视图模型或包装器类型, Name
和 Category
属性。
然后您将 DataGrid
的 ItemsSource
绑定到此 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
})
}
假设我有 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.Categories 和 Item.Category 获取类别名称。
缺点是我必须使用样板代码创建很多转换器。
2。通用转换器
这与前面的类似,但使用反射我可以编写 ObjectIdToInstanceValue multi-value 转换器并提供 3 个参数:collection、ObjectId 和属性 名称。此转换器将尝试使用 ObjectId 在 collection 中查找项目,并通过名称获取 属性 值。
缺点是 Reflection 很昂贵(至少据我所知)。但我只需要一个转换器即可。
这两种方法对我没有吸引力。我个人不喜欢转换器,我相信它们会影响应用程序的性能。
3。 Object包装器
我从未见过有人实施甚至建议过这种方法。基本上,我可以创建一个 DataGridItem class,它可以有 Item 和 Category特性。然后在 ViewModel 中我可以填充 collection 并直接绑定到属性。
又有意思了,我从来没见过这种方式被用在任何地方。
最好的方法是什么?
如果要在 DataGrid
中显示三列,您应该创建一个视图模型 class,其中每一列都有一个 属性。我想这就是您在问题中所说的 object wrapper。
DataGrid
的视图模型将负责将您当前的数据转换为 IEnumerable<T>
,其中 T
是具有 Id
的视图模型或包装器类型, Name
和 Category
属性。
然后您将 DataGrid
的 ItemsSource
绑定到此 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
})
}