C# DataGrid的WPF动态列和值
我有两个数据网格。一个列表包含项目列表,另一个包含规范 如果在第一个网格中选择Monitor,则第二个网格应显示其自身的规范。如果我选择CPU,它应该在另一个网格上显示它的规格 我正在寻找一个很好的解决方案。到目前为止,我计划创建一个属性为string和DataTable的模型,这样我就可以创建一个绑定,将动态表绑定到第二个网格。但我正在寻找类似动态属性或更好的解决方案C# DataGrid的WPF动态列和值,c#,wpf,xaml,C#,Wpf,Xaml,我有两个数据网格。一个列表包含项目列表,另一个包含规范 如果在第一个网格中选择Monitor,则第二个网格应显示其自身的规范。如果我选择CPU,它应该在另一个网格上显示它的规格 我正在寻找一个很好的解决方案。到目前为止,我计划创建一个属性为string和DataTable的模型,这样我就可以创建一个绑定,将动态表绑定到第二个网格。但我正在寻找类似动态属性或更好的解决方案 感谢对于这种情况,我使用我的GenericRow和GenericTable类: public class GenericRo
感谢对于这种情况,我使用我的GenericRow和GenericTable类:
public class GenericRow : CustomTypeDescriptor, INotifyPropertyChanged
{
#region Private Fields
List<PropertyDescriptor> _property_list = new List<PropertyDescriptor>();
#endregion
#region INotifyPropertyChange Implementation
public event PropertyChangedEventHandler PropertyChanged = delegate { };
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion INotifyPropertyChange Implementation
#region Public Methods
public void SetPropertyValue<T>(string propertyName, T propertyValue)
{
var properties = this.GetProperties()
.Cast<PropertyDescriptor>()
.Where(prop => prop.Name.Equals(propertyName));
if (properties == null || properties.Count() != 1)
{
throw new Exception("The property doesn't exist.");
}
var property = properties.First();
property.SetValue(this, propertyValue);
OnPropertyChanged(propertyName);
}
public T GetPropertyValue<T>(string propertyName)
{
var properties = this.GetProperties()
.Cast<PropertyDescriptor>()
.Where(prop => prop.Name.Equals(propertyName));
if (properties == null || properties.Count() != 1)
{
throw new Exception("The property doesn't exist.");
}
var property = properties.First();
return (T)property.GetValue(this);
}
public void AddProperty<T, U>(string propertyName) where U : GenericRow
{
var customProperty =
new CustomPropertyDescriptor<T>(
propertyName,
typeof(U));
_property_list.Add(customProperty);
}
#endregion
#region Overriden Methods
public override PropertyDescriptorCollection GetProperties()
{
var properties = base.GetProperties();
return new PropertyDescriptorCollection(
properties.Cast<PropertyDescriptor>()
.Concat(_property_list).ToArray());
}
#endregion
}
公共类GenericRow:CustomTypeDescriptor,INotifyPropertyChanged
{
#区域专用字段
列表_属性_列表=新列表();
#端区
#区域INotifyPropertyChange实现
公共事件PropertyChangedEventHandler PropertyChanged=委托{};
受保护的无效OnPropertyChanged(字符串propertyName)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
#endregion INotifyPropertyChange实现
#区域公共方法
public void SetPropertyValue(字符串propertyName,T propertyValue)
{
var properties=this.GetProperties()
.Cast()
其中(prop=>prop.Name.Equals(propertyName));
if(properties==null | | properties.Count()!=1)
{
抛出新异常(“属性不存在”);
}
var property=properties.First();
SetValue(这是propertyValue);
OnPropertyChanged(propertyName);
}
公共T GetPropertyValue(字符串propertyName)
{
var properties=this.GetProperties()
.Cast()
其中(prop=>prop.Name.Equals(propertyName));
if(properties==null | | properties.Count()!=1)
{
抛出新异常(“属性不存在”);
}
var property=properties.First();
return(T)property.GetValue(this);
}
公共void AddProperty(字符串propertyName),其中U:GenericRow
{
var自定义属性=
新CustomPropertyDescriptor(
propertyName,
(U)型;
_属性列表。添加(customProperty);
}
#端区
#区域覆盖方法
公共重写PropertyDescriptorCollection GetProperties()
{
var properties=base.GetProperties();
返回新属性DescriptorCollection(
properties.Cast()
.Concat(_property_list).ToArray();
}
#端区
}
以及:
公共类可泛化
{
私有字符串tableName=“”;
公共字符串表名
{
获取{return tableName;}
设置{tableName=value;}
}
私人可观测集合;
公共可观测集合列集合
{
获取{return columnCollection;}
私有集{columnCollection=value;}
}
私有可观测集合一般微集合;
公共可观测集合一般微集合
{
获取{return genericRowCollection;}
设置{genericRowCollection=value;}
}
公共通用表(字符串表名)
{
this.TableName=TableName;
ColumnCollection=新的ObservableCollection();
GenericRowCollection=新的ObservableCollection();
}
///
///ColumnName也是绑定属性名
///
///
public void AddColumn(字符串columnName)
{
DataGridTextColumn=新DataGridTextColumn();
column.Header=columnName;
column.Binding=新绑定(columnName);
ColumnCollection.Add(column);
}
公共重写字符串ToString()
{
返回表名;
}
}
您可以使用这两个类来创建动态行和列。使用GenericRow类,可以生成具有所需属性名称的行,并且可以为prober绑定的列使用相同的属性名称
对于XAML方面:
<DataGrid Name="dataGrid"
local:DataGridColumnsBehavior.BindableColumns="{Binding ColumnCollection}"
AutoGenerateColumns="False"
...>
最后是DataGridColumsBehaior:
public class DataGridColumnsBehavior
{
public static readonly DependencyProperty BindableColumnsProperty =
DependencyProperty.RegisterAttached("BindableColumns",
typeof(ObservableCollection<DataGridColumn>),
typeof(DataGridColumnsBehavior),
new UIPropertyMetadata(null, BindableColumnsPropertyChanged));
private static void BindableColumnsPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
DataGrid dataGrid = source as DataGrid;
ObservableCollection<DataGridColumn> columns = e.NewValue as ObservableCollection<DataGridColumn>;
dataGrid.Columns.Clear();
if (columns == null)
{
return;
}
foreach (DataGridColumn column in columns)
{
dataGrid.Columns.Add(column);
}
columns.CollectionChanged += (sender, e2) =>
{
NotifyCollectionChangedEventArgs ne = e2 as NotifyCollectionChangedEventArgs;
if (ne.Action == NotifyCollectionChangedAction.Reset)
{
dataGrid.Columns.Clear();
foreach (DataGridColumn column in ne.NewItems)
{
dataGrid.Columns.Add(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Add)
{
foreach (DataGridColumn column in ne.NewItems)
{
dataGrid.Columns.Add(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Move)
{
dataGrid.Columns.Move(ne.OldStartingIndex, ne.NewStartingIndex);
}
else if (ne.Action == NotifyCollectionChangedAction.Remove)
{
foreach (DataGridColumn column in ne.OldItems)
{
dataGrid.Columns.Remove(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Replace)
{
dataGrid.Columns[ne.NewStartingIndex] = ne.NewItems[0] as DataGridColumn;
}
};
}
public static void SetBindableColumns(DependencyObject element, ObservableCollection<DataGridColumn> value)
{
element.SetValue(BindableColumnsProperty, value);
}
public static ObservableCollection<DataGridColumn> GetBindableColumns(DependencyObject element)
{
return (ObservableCollection<DataGridColumn>)element.GetValue(BindableColumnsProperty);
}
}
公共类DataGridColumnsBehavior
{
公共静态只读从属属性BindableColumnsProperty=
DependencyProperty.RegisterAttached(“BindableColumns”,
类型(可观测采集),
类型(DataGridColumnsBehavior),
新的UIPropertyMetadata(null,BindableColumnsPropertyChanged));
私有静态void BindableColumnsPropertyChanged(DependencyObject源,DependencyPropertyChangedEventArgs e)
{
DataGrid DataGrid=源作为DataGrid;
ObservableCollection columns=e.NewValue作为ObservableCollection;
dataGrid.Columns.Clear();
如果(列==null)
{
返回;
}
foreach(列中的DataGridColumn列)
{
dataGrid.Columns.Add(column);
}
columns.CollectionChanged+=(发送方,e2)=>
{
NotifyCollectionChangedEventArgs ne=e2作为NotifyCollectionChangedEventArgs;
if(ne.Action==NotifyCollectionChangedAction.Reset)
{
dataGrid.Columns.Clear();
foreach(ne.NewItems中的DataGridColumn列)
{
dataGrid.Columns.Add(column);
}
}
else if(ne.Action==NotifyCollectionChangedAction.Add)
{
foreach(ne.NewItems中的DataGridColumn列)
{
dataGrid.Columns.Add(column);
}
}
else if(ne.Action==NotifyCollectionChangedActio
public class DataGridColumnsBehavior
{
public static readonly DependencyProperty BindableColumnsProperty =
DependencyProperty.RegisterAttached("BindableColumns",
typeof(ObservableCollection<DataGridColumn>),
typeof(DataGridColumnsBehavior),
new UIPropertyMetadata(null, BindableColumnsPropertyChanged));
private static void BindableColumnsPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
DataGrid dataGrid = source as DataGrid;
ObservableCollection<DataGridColumn> columns = e.NewValue as ObservableCollection<DataGridColumn>;
dataGrid.Columns.Clear();
if (columns == null)
{
return;
}
foreach (DataGridColumn column in columns)
{
dataGrid.Columns.Add(column);
}
columns.CollectionChanged += (sender, e2) =>
{
NotifyCollectionChangedEventArgs ne = e2 as NotifyCollectionChangedEventArgs;
if (ne.Action == NotifyCollectionChangedAction.Reset)
{
dataGrid.Columns.Clear();
foreach (DataGridColumn column in ne.NewItems)
{
dataGrid.Columns.Add(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Add)
{
foreach (DataGridColumn column in ne.NewItems)
{
dataGrid.Columns.Add(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Move)
{
dataGrid.Columns.Move(ne.OldStartingIndex, ne.NewStartingIndex);
}
else if (ne.Action == NotifyCollectionChangedAction.Remove)
{
foreach (DataGridColumn column in ne.OldItems)
{
dataGrid.Columns.Remove(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Replace)
{
dataGrid.Columns[ne.NewStartingIndex] = ne.NewItems[0] as DataGridColumn;
}
};
}
public static void SetBindableColumns(DependencyObject element, ObservableCollection<DataGridColumn> value)
{
element.SetValue(BindableColumnsProperty, value);
}
public static ObservableCollection<DataGridColumn> GetBindableColumns(DependencyObject element)
{
return (ObservableCollection<DataGridColumn>)element.GetValue(BindableColumnsProperty);
}
}