Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF Datagrid数据绑定到具有静态属性和包含动态属性值项的字典的类_C#_Wpf_Datagrid_Propertydescriptor_Icustomtypedescriptor - Fatal编程技术网

C# WPF Datagrid数据绑定到具有静态属性和包含动态属性值项的字典的类

C# WPF Datagrid数据绑定到具有静态属性和包含动态属性值项的字典的类,c#,wpf,datagrid,propertydescriptor,icustomtypedescriptor,C#,Wpf,Datagrid,Propertydescriptor,Icustomtypedescriptor,更新 我之所以更新这篇文章,是因为我读了更多的书,并决定重新实施我的解决方案 原始问题:我有一个具有静态属性的类,还有一个属性是属性的动态集合(通过字典)。我想将我的类数据绑定到一个wpf数据网格,其中每个静态属性都应该是一列,每个字典条目都应该是网格中的一列 在做了更多的研究之后,我决定实现一个PropertyBag类,它将包含我的属性和值字典。现在几乎一切都在运转。我的网格显示了所有正确的列,并且静态属性值应用正确 但是,现在我无法从字典中获得任何要应用于网格的值,我也不知道从这里可以走到哪

更新

我之所以更新这篇文章,是因为我读了更多的书,并决定重新实施我的解决方案

原始问题:我有一个具有静态属性的类,还有一个属性是属性的动态集合(通过字典)。我想将我的类数据绑定到一个wpf数据网格,其中每个静态属性都应该是一列,每个字典条目都应该是网格中的一列

在做了更多的研究之后,我决定实现一个PropertyBag类,它将包含我的属性和值字典。现在几乎一切都在运转。我的网格显示了所有正确的列,并且静态属性值应用正确

但是,现在我无法从字典中获得任何要应用于网格的值,我也不知道从这里可以走到哪里

更多信息:

我的数据库有3个表,一个plate、一个category和一个CategoryPlate关联表。每个板可以有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;
        }
    }
}
修订的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]}"/>