C# 使用ObservableCollection<;字典<;字符串,对象>&燃气轮机;作为WPF中的DataGrid Itemsource

C# 使用ObservableCollection<;字典<;字符串,对象>&燃气轮机;作为WPF中的DataGrid Itemsource,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我有一个DataGrid,我设置ItemsSource是一个observedcollection对象 通常,我只需定义一个ClassA并将observateCollection设置为ItemsSource,就可以将属性名称绑定到ClassA的列(DataGridTextColumn) 但我不知道如何绑定字典的键/值 有什么支持吗?您的问题相当复杂,为了创建observedictionary您应该创建一个实现以下功能的类: IDictionary INotifyCollectionChanged

我有一个
DataGrid
,我设置
ItemsSource
是一个
observedcollection
对象

通常,我只需定义一个
ClassA
并将
observateCollection
设置为ItemsSource,就可以将属性名称绑定到ClassA的列(
DataGridTextColumn

但我不知道如何绑定字典的键/值


有什么支持吗?

您的问题相当复杂,为了创建
observedictionary
您应该创建一个实现以下功能的类:

IDictionary
INotifyCollectionChanged
INotifyPropertyChanged 
ICollection<KeyValuePair<TKey,TValue>>
IEnumerable<KeyValuePair<TKey,TValue>>
IEnumerable
IDictionary
INotifyCollectionChanged
InotifyProperty已更改
I收集
数不清
数不清
接口。在这里。这种实现的一个例子是:

class ObservableDictionary<TKey, TValue> : IDictionary, INotifyCollectionChanged, INotifyPropertyChanged
{
    private Dictionary<TKey, TValue> mDictionary;

    //Methods & Properties for IDictionary implementation would defer to mDictionary:
    public void Add(TKey key, TValue value)
    {
        mDictionary.Add(key, value);
        OnCollectionChanged(NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value)
        return;
    }

    //Implementation of INotifyCollectionChanged:
    public event NotifyCollectionChangedEventHandler CollectionChanged;
    protected void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
    {
        //event fire implementation
    }

    //Implementation of INotifyProperyChanged:
    public event ProperyChangedEventHandler ProperyChanged;
    protected void OnPropertyChanged(PropertyChangedEventArgs args)
    {
        //event fire implementation
    }
}
类ObservalEdictionary:IDictionary、INotifyCollectionChanged、INotifyPropertyChanged
{
私人词典;
//IDictionary实现的方法和属性将遵从mDictionary:
公共无效添加(TKey键,TValue值)
{
mDictionary.Add(键、值);
OnCollectionChanged(NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,value)
返回;
}
//InotifyCollection的实施已更改:
公共事件通知CollectionChangedEventHandler CollectionChanged;
CollectionChanged上受保护的void(NotifyCollectionChangedEventArgs args)
{
//事件火实现
}
//InotifyProperty的实施已更改:
公共事件属性更改事件处理程序属性更改;
PropertyChanged上受保护的无效(PropertyChangedEventArgs args)
{
//事件火实现
}
}

另一种是可绑定动态词典,它将每个词典条目作为属性公开

public sealed class BindableDynamicDictionary : DynamicObject, INotifyPropertyChanged
{
    /// <summary>
    /// The internal dictionary.
    /// </summary>
    private readonly Dictionary<string, object> _dictionary;

    /// <summary>
    /// Creates a new BindableDynamicDictionary with an empty internal dictionary.
    /// </summary>
    public BindableDynamicDictionary()
    {
        _dictionary = new Dictionary<string, object>();
    }

    /// <summary>
    /// Copies the contents of the given dictionary to initilize the internal dictionary.
    /// </summary>
    public BindableDynamicDictionary(IDictionary<string, object> source)
    {
        _dictionary = new Dictionary<string, object>(source);
    }

    /// <summary>
    /// You can still use this as a dictionary.
    /// </summary>
    public object this[string key]
    {
        get { return _dictionary[key]; }
        set
        {
            _dictionary[key] = value;
            RaisePropertyChanged(key);
        }
    }

    /// <summary>
    /// This allows you to get properties dynamically.
    /// </summary>
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        return _dictionary.TryGetValue(binder.Name, out result);
    }

    /// <summary>
    /// This allows you to set properties dynamically.
    /// </summary>
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _dictionary[binder.Name] = value;
        RaisePropertyChanged(binder.Name);
        return true;
    }

    /// <summary>
    /// This is used to list the current dynamic members.
    /// </summary>
    public override IEnumerable<string> GetDynamicMemberNames()
    {
        return _dictionary.Keys;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName)
    {
        var propChange = PropertyChanged;
        if (propChange == null) return;
        propChange(this, new PropertyChangedEventArgs(propertyName));
    }
}
公共密封类BindableDynamicDictionary:DynamicObject,INotifyPropertyChanged
{
/// 
///内部字典。
/// 
私人只读词典;
/// 
///使用空的内部字典创建新的BindableDynamicDictionary。
/// 
公共BindableDynamicDictionary()
{
_字典=新字典();
}
/// 
///复制给定词典的内容以初始化内部词典。
/// 
公共BindableDynamicDictionary(IDictionary源)
{
_字典=新字典(来源);
}
/// 
///你仍然可以把它用作字典。
/// 
公共对象此[字符串键]
{
获取{return _dictionary[key];}
设置
{
_字典[键]=值;
RaisePropertyChanged(键);
}
}
/// 
///这允许您动态获取属性。
/// 
公共重写bool TryGetMember(GetMemberBinder绑定器,输出对象结果)
{
返回_dictionary.TryGetValue(binder.Name,out结果);
}
/// 
///这允许您动态设置属性。
/// 
public override bool TrySetMember(SetMemberBinder绑定器,对象值)
{
_字典[binder.Name]=值;
RaisePropertyChanged(活页夹名称);
返回true;
}
/// 
///用于列出当前动态成员。
/// 
公共重写IEnumerable GetDynamicMemberNames()
{
返回_dictionary.Keys;
}
公共事件属性更改事件处理程序属性更改;
私有void RaisePropertyChanged(字符串propertyName)
{
var propChange=PROPERTYCHANGE;
if(propChange==null)返回;
propChange(这是新的PropertyChangedEventArgs(propertyName));
}
}
然后你可以这样使用它:

private void testButton1_Click(object sender, RoutedEventArgs e)
{
    var dd = new BindableDynamicDictionary(); // Creating a dynamic dictionary.
    dd["Age"] = 32; //access like any dictionary

    dynamic person = dd; //or as a dynamic
    person.FirstName = "Alan"; // Adding new dynamic properties. The TrySetMember method is called.
    person.LastName = "Evans";

    //hacky for short example, should have a view model and use datacontext
    var collection = new ObservableCollection<object>();
    collection.Add(person);
    dataGrid1.ItemsSource = collection;
}
private void testButton1\u单击(对象发送者,路由目标)
{
var dd=new BindableDynamicDictionary();//创建动态字典。
dd[“Age”]=32;//像任何字典一样访问
dynamic person=dd;//或作为动态
person.FirstName=“Alan”//添加新的动态属性。调用TrySetMember方法。
person.LastName=“Evans”;
//例如,hacky应该有一个视图模型并使用datacontext
var collection=新的ObservableCollection();
收集。添加(人);
dataGrid1.ItemsSource=集合;
}
Datagrid需要自定义代码来构建列:

XAML:


AutoGeneratedColumns事件:

private void dataGrid1_AutoGeneratedColumns(object sender, EventArgs e)
{
    var dg = sender as DataGrid;
    var first = dg.ItemsSource.Cast<object>().FirstOrDefault() as DynamicObject;
    if (first == null) return;
    var names = first.GetDynamicMemberNames();
    foreach(var name in names)
    {
        dg.Columns.Add(new DataGridTextColumn { Header = name, Binding = new Binding(name) });            
    }            
}
private void dataGrid1\u自动生成列(对象发送方,事件参数e)
{
var dg=发送方作为数据网格;
var first=dg.ItemsSource.Cast().FirstOrDefault()作为DynamicObject;
if(first==null)返回;
var name=first.GetDynamicMemberNames();
foreach(名称中的变量名称)
{
Add(newdatagridtextcolumn{Header=name,Binding=newbinding(name)});
}            
}

您的问题相当复杂,为了创建
observedictionary
您应该创建一个实现以下功能的类:

IDictionary
INotifyCollectionChanged
INotifyPropertyChanged 
ICollection<KeyValuePair<TKey,TValue>>
IEnumerable<KeyValuePair<TKey,TValue>>
IEnumerable
IDictionary
INotifyCollectionChanged
InotifyProperty已更改
I收集
数不清
数不清
接口。在这里。此类实现的一个示例是:

class ObservableDictionary<TKey, TValue> : IDictionary, INotifyCollectionChanged, INotifyPropertyChanged
{
    private Dictionary<TKey, TValue> mDictionary;

    //Methods & Properties for IDictionary implementation would defer to mDictionary:
    public void Add(TKey key, TValue value)
    {
        mDictionary.Add(key, value);
        OnCollectionChanged(NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value)
        return;
    }

    //Implementation of INotifyCollectionChanged:
    public event NotifyCollectionChangedEventHandler CollectionChanged;
    protected void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
    {
        //event fire implementation
    }

    //Implementation of INotifyProperyChanged:
    public event ProperyChangedEventHandler ProperyChanged;
    protected void OnPropertyChanged(PropertyChangedEventArgs args)
    {
        //event fire implementation
    }
}
类ObservalEdictionary:IDictionary、INotifyCollectionChanged、INotifyPropertyChanged
{
私人词典;
//IDictionary实现的方法和属性将遵从mDictionary:
公共无效添加(TKey键,TValue值)
{
mDictionary.Add(键、值);
OnCollectionChanged(NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,value)
返回;
}
//InotifyCollection的实施已更改:
公共事件通知CollectionChangedEventHandler CollectionChanged;
CollectionChanged上受保护的void(NotifyCollectionChangedEventArgs args)
{
//事件火实现
}
//InotifyProperty的实施已更改:
公共事件属性更改事件处理程序属性更改;
保护空隙