C# 将类中包含的字典绑定到DataGrid
我有以下数据结构的列表,我想在datagrid中显示这些数据结构:C# 将类中包含的字典绑定到DataGrid,c#,data-binding,datagrid,C#,Data Binding,Datagrid,我有以下数据结构的列表,我想在datagrid中显示这些数据结构: public class receiver { public string Name { get; set; } public string Mail { get; set; } public Dictionary<string, string> ReplacementText { get; set; } } public void Init() { List<receiver> rec
public class receiver
{
public string Name { get; set; }
public string Mail { get; set; }
public Dictionary<string, string> ReplacementText { get; set; }
}
public void Init()
{
List<receiver> receivers = new List<receiver>();
// add some instances of receivers
MyDataGrid.DataContext = receivers;
}
用户应该能够编辑所有数据。显然,我不能像上面的例子那样简单地绑定列表。此外,ReplacementText字典中的条目是动态的(即,用户可以添加更多的键,这些键也应该在datagrid中可见)。有没有想过,我怎么会做出这样的行为
提前感谢,弗兰克我的建议
字典
转换为数据表
DataTable dt=ConvertTo(接收方[i].ReplacementText)代码>
DataTable
///
///Converts a Dictionary of the given type to a DataTable
///
public static DataTable ConvertTo<T>(Dictionary<string, T> list, string dataTableName)
{
DataTable table = CreateTable1<T>(dataTableName);
Type entityType = typeof(T);
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType);
foreach (KeyValuePair<string, T> item in list)
{
DataRow row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
{
if (prop.PropertyType.FullName == "System.String")
{
if (prop.GetValue(item.Value) == null)
{
row[prop.Name] = prop.GetValue(item.Value);
}
else
{
row[prop.Name] = prop.GetValue(item.Value).ToString().Replace("'", "''");
}
}
else
{
row[prop.Name] = prop.GetValue(item.Value);
}
}
table.Rows.Add(row);
}
return table;
}
///
/// Create a DataTable wich columns based on the properties of the given type <T>
///
public static DataTable CreateTable<T>(string dataTableName)
{
Type entityType = typeof(T);
DataTable table = new DataTable(dataTableName);
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType);
foreach (PropertyDescriptor prop in properties)
{
table.Columns.Add(prop.Name, prop.PropertyType);
}
return table;
}
///
///将给定类型的字典转换为数据表
///
公共静态DataTable ConvertTo(字典列表、字符串dataTableName)
{
DataTable=CreateTable1(dataTableName);
类型entityType=类型(T);
PropertyDescriptorCollection属性=TypeDescriptor.GetProperties(entityType);
foreach(列表中的KeyValuePair项)
{
DataRow行=table.NewRow();
foreach(属性中的PropertyDescriptor属性)
{
if(prop.PropertyType.FullName==“System.String”)
{
if(prop.GetValue(item.Value)==null)
{
行[prop.Name]=prop.GetValue(item.Value);
}
其他的
{
行[prop.Name]=prop.GetValue(item.Value).ToString().Replace(“,”);
}
}
其他的
{
行[prop.Name]=prop.GetValue(item.Value);
}
}
table.Rows.Add(行);
}
返回表;
}
///
///基于给定类型的属性创建包含列的DataTable
///
公共静态DataTable CreateTable(字符串dataTableName)
{
类型entityType=类型(T);
DataTable=新的DataTable(dataTableName);
PropertyDescriptorCollection属性=TypeDescriptor.GetProperties(entityType);
foreach(属性中的PropertyDescriptor属性)
{
table.Columns.Add(prop.Name,prop.PropertyType);
}
返回表;
}
不能在双向模式下绑定dictionary对象,因为它的键和值属性是只读的。但是,您可以使用此代码替换字典部分
public class KeyValueRow<K,V>:INotifyPropertyChanged
{
public KeyValueRow(K key,V value)
{
this.Key = key;
this.Value = value;
}
private K _key;
private V _value;
public K Key
{
get { return _key; }
set
{
if (!EqualityComparer<K>.Default.Equals(_key, value))
{
_key = value;
RaisePropertyChanged("Key");
}
}
}
private void RaisePropertyChanged(string p)
{
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
public V Value
{
get { return _value; }
set
{
if (!EqualityComparer<V>.Default.Equals(_value, value))
{
_value = value;
RaisePropertyChanged("Value");
}
}
}
//prefarble way as it evit to check the for null when raising event
public event PropertyChangedEventHandler PropertyChanged = delegate{};
}
公共类KeyValueRow:INotifyPropertyChanged
{
公钥值行(K键,V值)
{
这个。键=键;
这个。值=值;
}
私钥;
私人V_值;
公钥
{
获取{return\u key;}
设置
{
如果(!EqualityComparer.Default.Equals(_键,值))
{
_键=值;
RaisePropertyChanged(“密钥”);
}
}
}
私有void raiseProperty已更改(字符串p)
{
房地产变更(这是新的房地产变更发展(p));
}
公共价值
{
获取{返回_值;}
设置
{
如果(!EqualityComparer.Default.Equals(_值,值))
{
_价值=价值;
提升财产变更(“价值”);
}
}
}
//在引发事件时检查空值时,使用prefarble方法
公共事件PropertyChangedEventHandler PropertyChanged=委托{};
}
你可以用它来代替字典
public ObservableCollection<KeyValueRow<string, string>> ReplacementText { get; set; }
public observeCollection ReplacementText{get;set;}
最后应用主细节场景,如示例所示
希望这些帮助谢谢你的提示,朱莉!我不需要更改dict中的条目,我只需要更改dict中irems值的内容。我确实更改了一些类,因此我能够绑定ReplacementText[0]。不幸的是,ReplacementText[“Name”]不起作用,因为您不能在绑定中使用感叹号。谢谢您的提示,但是这些值将在列中,但我需要在行中使用它们。我试了一下,把dict改成了,这样我就可以用ReplacementText[I]代替bin了
public class KeyValueRow<K,V>:INotifyPropertyChanged
{
public KeyValueRow(K key,V value)
{
this.Key = key;
this.Value = value;
}
private K _key;
private V _value;
public K Key
{
get { return _key; }
set
{
if (!EqualityComparer<K>.Default.Equals(_key, value))
{
_key = value;
RaisePropertyChanged("Key");
}
}
}
private void RaisePropertyChanged(string p)
{
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
public V Value
{
get { return _value; }
set
{
if (!EqualityComparer<V>.Default.Equals(_value, value))
{
_value = value;
RaisePropertyChanged("Value");
}
}
}
//prefarble way as it evit to check the for null when raising event
public event PropertyChangedEventHandler PropertyChanged = delegate{};
}
public ObservableCollection<KeyValueRow<string, string>> ReplacementText { get; set; }