已更新
我之所以更新这篇文章,是因为我做了更多的阅读,并决定重新实现我的解决方案。
原始问题:我有一个具有静态属性的类,还有一个属性是属性的动态集合(通过字典)。我希望将我的类数据绑定到wpf数据网格,其中每个静态属性都应该是一个列,每个字典条目都应该是网格中的一个列。
在做了进一步的研究之后,我决定实现一个PropertyBag类,它将包含我的属性和值字典。现在几乎所有的东西都可以工作了。我的网格显示了所有正确的列,静态属性值也得到了正确的应用。
但是,现在我不能从字典中获得任何要应用于网格的值,并且我不确定从哪里开始。
更多信息:
我的数据库有3个表,一个盘子,一个类别和一个类别平台关联表。每个板块可以有0到多个类别。现在,我用所有类别填充每个模板,并将字符串设置为空。然后,当返回关联时(车牌和类别之间),我将在特定类别名称上设置实际值。这一切都发生在网格创建之前。
属性包:
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;
}
}
}修订后的板块类别
[TypeDescriptionProvider(typeof(PlateTypeDescriptionProvider))]
public class Plate : INotifyPropertyChanged
{
public int ID;
private string name;
private string status;
private string creator;
private Uri location;
private string description;
public Plate()
{
CustomCategories = new PropertyBag();
}
public PropertyBag CustomCategories { get; set; }
public string Name
{
get { return name;}
set
{
name = value;
NotifyPropertyChanged("Name");
}
}
public string Status
{
get { return status; }
set
{
status = value;
NotifyPropertyChanged("Status");
}
}
public string Creator
{
get { return creator; }
set
{
creator = value;
NotifyPropertyChanged("Creator");
}
}
public Uri Location
{
get { return location; }
set
{
location = value;
NotifyPropertyChanged("Location");
}
}
public string Description
{
get { return description; }
set
{
description = value;
NotifyPropertyChanged("Description");
}
}
public static Plate ConvertDataPlateToBusinessPlate(TestPlate dataPlate)
{
var plate = new Plate
{
Name = dataPlate.Name,
Status = dataPlate.Status,
Creator = dataPlate.Creator,
Description = dataPlate.Description,
Location = new Uri(dataPlate.Location)
};
return plate;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}修订后的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); }
}
}简单的ViewModel
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);
}
}发布于 2011-05-25 00:53:59
您的PropertyBag中的字典有固定的大小吗?或者键是已知的吗?
您没有发布datagrid的xaml,但是从propertybag到一列的绑定可能如下所示:
<DataGridTextColumn Header="Col4TestKey" Binding="{Binding CustomCategories[test]}"/>我真的不知道你的PropertyBag设置器是否能与绑定一起工作。总而言之,如果你的字典有一组已知的关键字,这一切都会起作用。
顺便说一下,我在我的项目中使用平面数据表来处理这种动态的东西,真的很容易处理。
https://stackoverflow.com/questions/6104541
复制相似问题