C# WPF Datagrid数据绑定到具有静态属性和包含动态属性值项的字典的类
更新 我之所以更新这篇文章,是因为我读了更多的书,并决定重新实施我的解决方案 原始问题:我有一个具有静态属性的类,还有一个属性是属性的动态集合(通过字典)。我想将我的类数据绑定到一个wpf数据网格,其中每个静态属性都应该是一列,每个字典条目都应该是网格中的一列 在做了更多的研究之后,我决定实现一个PropertyBag类,它将包含我的属性和值字典。现在几乎一切都在运转。我的网格显示了所有正确的列,并且静态属性值应用正确 但是,现在我无法从字典中获得任何要应用于网格的值,我也不知道从这里可以走到哪里 更多信息: 我的数据库有3个表,一个plate、一个category和一个CategoryPlate关联表。每个板可以有0到多个类别。现在,我用所有类别填充每个盘子,并将字符串设置为空。然后,当一个关联被返回时(在一个板块和类别之间),我正在设置特定类别名称的真实值。这一切都发生在网格创建之前 财产袋:C# WPF Datagrid数据绑定到具有静态属性和包含动态属性值项的字典的类,c#,wpf,datagrid,propertydescriptor,icustomtypedescriptor,C#,Wpf,Datagrid,Propertydescriptor,Icustomtypedescriptor,更新 我之所以更新这篇文章,是因为我读了更多的书,并决定重新实施我的解决方案 原始问题:我有一个具有静态属性的类,还有一个属性是属性的动态集合(通过字典)。我想将我的类数据绑定到一个wpf数据网格,其中每个静态属性都应该是一列,每个字典条目都应该是网格中的一列 在做了更多的研究之后,我决定实现一个PropertyBag类,它将包含我的属性和值字典。现在几乎一切都在运转。我的网格显示了所有正确的列,并且静态属性值应用正确 但是,现在我无法从字典中获得任何要应用于网格的值,我也不知道从这里可以走到哪
public class PropertyBag
{
private readonly Dictionary<string, string> values = new Dictionary<string, string>();
public string this[string key]
{
get
{
string value;
values.TryGetValue(key, out value);
return value;
}
set
{
if (value == null) values.Remove(key);
else values[key] = value;
}
}
}
修订的CustomTypeDescriptor:
public override PropertyDescriptorCollection GetProperties()
{
return GetProperties(null);
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
var properties = new ArrayList();
foreach (PropertyDescriptor propertyDescriptor in base.GetProperties(attributes))
{
if(propertyDescriptor.PropertyType.Equals(typeof(PropertyBag)))
{
//Static list of all category names
var categoryNames = Categories.GetAll();
foreach (var categoryName in categoryNames)
{
properties.Add(new PropertyBagPropertyDescriptor(categoryName));
}
}
else
{
properties.Add(propertyDescriptor);
}
}
var props = (PropertyDescriptor[])properties.ToArray(typeof(PropertyDescriptor));
return new PropertyDescriptorCollection(props);
}
修订的PropertyDescriptor
public class PropertyBagPropertyDescriptor : PropertyDescriptor
{
public PropertyBagPropertyDescriptor(string name) : base(name, null)
{}
public override bool CanResetValue(object component)
{
return true;
}
public override object GetValue(object component)
{
return ((PropertyBag) component)[Name];
}
public override void ResetValue(object component)
{
((PropertyBag)component)[Name] = null;
}
public override void SetValue(object component, object value)
{
((PropertyBag) component)[Name] = (string) value;
}
public override bool ShouldSerializeValue(object component)
{
return ((PropertyBag)component)[Name] != null;
}
public override Type ComponentType
{
get { return typeof(PropertyBag); }
}
public override bool IsReadOnly
{
get { return false; }
}
public override Type PropertyType
{
get { return typeof(string); }
}
}
简单视图模型
public TestPlateAdministratorViewModel()
{
CommandAggregator = new TestPlateAdministratorCommandAggregator(this);
LoadData();
}
public static TestPlateAdministratorCommandAggregator CommandAggregator { get; set; }
public ObservableCollection<Plate> TestPlates{ get; set; }
private static void LoadData()
{
CommandAggregator.LoadPlatesCommand.Execute(null);
CommandAggregator.LoadCategoriesCommand.Execute(null);
}
}
公共测试平台管理员视图模型()
{
CommandAggregator=新的TestPlateAdministratorCommandAggregator(此);
LoadData();
}
公共静态TestPlateAdministratorCommandAggregator命令聚合器{get;set;}
公共可观察收集测试板{get;set;}
私有静态void LoadData()
{
CommandAggregator.LoadPlatesCommand.Execute(null);
CommandAggregator.LoadCategoriesCommand.Execute(null);
}
}
您的PropertyBag中的词典是否有固定大小,或者密钥是否已知 您没有为datagrid发布xaml,但是从propertybag到一列的绑定可能如下所示:
<DataGridTextColumn Header="Col4TestKey" Binding="{Binding CustomCategories[test]}"/>
我真的不知道你的PropertyBag setter是否能与binding一起工作。总之,如果你有一套字典的钥匙,这一切都会起作用
顺便说一句,我在我的项目中使用平面数据表来处理此类动态内容,它们非常容易处理。您是否将一个平板对象或一组平板对象绑定到数据网格?您的datagrid应该是什么样子,应该显示什么?顺便说一句,我真的不知道为什么要使用PropertyDescriptor。我将ObservableCollection绑定到datagrid。我使用PropertyDescriptor作为操纵网格中显示的属性的一种方式。这是我无法工作的部分。我想将字典中的每个条目设置为plate的属性,其中名称是属性名称,值是属性值。我是不是走错了方向?在运行时从数据库加载类别名称(字典的键)之前,我不会知道它们的集合。用户可以从数据库中添加和删除类别,因此我无法硬编码类别名称。但是,你是对的,如果我事先知道名字,这将是一个简单的问题来解决。
<DataGridTextColumn Header="Col4TestKey" Binding="{Binding CustomCategories[test]}"/>