我有一个File类定义如下
public class File
{
public string FileName {set;get;}
public List<Property> PropertyList;
}
以下是Property类的外观:
public class Property
{
public string PropertyName { set; get;};
public string PropertyValue { set; get;};
...
}
我需要将List<File>
绑定到DataGrid,显示FileName。另外,我想为Property
中的每个PropertyList
创建一个列,
字符串值PropertyName
作为列标题,字符串值PropertyValue作为列的值。
这可以在WPF中使用吗?
谢谢,
答案 0 :(得分:1)
只需要尝试这个,奇怪但有趣的问题:-)通过使用以下方法管理它。 很抱歉很长的答案,可能详细说明:-)
首先是DataGrid。简单明了
<DataGrid Name="c_dataGrid" AutoGenerateColumns="False"
CanUserAddRows="False" CanUserDeleteRows="False"/>
然后是File类,名为MyFile
public class MyFile
{
public MyFile() : this(string.Empty) {}
public MyFile(string fileName)
{
FileName = fileName;
MyPropertyList = new ObservableCollection<MyProperty>();
}
public string FileName
{
set;
get;
}
public ObservableCollection<MyProperty> MyPropertyList
{
get;
set;
}
}
属性类,名为MyProperty
public class MyProperty
{
public MyProperty() : this(string.Empty, string.Empty) {}
public MyProperty(string propertyName, string propertyValue)
{
MyPropertyName = propertyName;
MyPropertyValue = propertyValue;
}
public string MyPropertyName
{
set;
get;
}
public string MyPropertyValue
{
set;
get;
}
}
包含MyFiles的列表
public ObservableCollection<MyFile> MyFileList{ get; set; }
创建一些虚拟数据来填充列表并在DataGrid上设置ItemsSource
MyFile myFile1 = new MyFile("MyFile1");
myFile1.MyPropertyList.Add(new MyProperty("Name1", "Value1"));
myFile1.MyPropertyList.Add(new MyProperty("Name2", "Value2"));
myFile1.MyPropertyList.Add(new MyProperty("Name3", "Value3"));
MyFile myFile2 = new MyFile("MyFile2");
myFile2.MyPropertyList.Add(new MyProperty("Name1", "Value1"));
myFile2.MyPropertyList.Add(new MyProperty("Name4", "Value4"));
myFile2.MyPropertyList.Add(new MyProperty("Name5", "Value5"));
MyFileList = new ObservableCollection<MyFile>();
MyFileList.Add(myFile1);
MyFileList.Add(myFile2);
c_dataGrid.ItemsSource = MyFileList;
为FileName属性添加了DataGridTextColumn
c_dataGrid.Columns.Add(GetNewMyFileNameColumn());
private DataGridColumn GetNewMyFileNameColumn()
{
DataGridTextColumn myFileNameColumn = new DataGridTextColumn();
myFileNameColumn.Header = "FileName";
myFileNameColumn.Width = new DataGridLength(1.0, DataGridLengthUnitType.Auto);
Binding valueBinding = new Binding();
valueBinding.Path = new PropertyPath("FileName");
valueBinding.Mode = BindingMode.TwoWay;
valueBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
valueBinding.NotifyOnSourceUpdated = true;
valueBinding.NotifyOnTargetUpdated = true;
myFileNameColumn.Binding = valueBinding;
return myFileNameColumn;
}
然后是MyPropertyList。我只想添加每个MyPropertyName,如果我有以下
MyFile1
-Name1
-Name2
-Name3
MyFile2
-Name1
-Name4
-Name5
生成的列应为Name1,Name2,Name3,Name4和Name5。
foreach (MyFile myFile in MyFileList)
{
foreach (MyProperty myProperty in myFile.MyPropertyList)
{
if (ColumnAlreadyAdded(myProperty.MyPropertyName) == false)
{
c_dataGrid.Columns.Add(GetNewMyPropertyColumn(myProperty.MyPropertyName));
}
}
}
private bool ColumnAlreadyAdded(string myPropertyName)
{
foreach (DataGridColumn dataGridColumn in c_dataGrid.Columns)
{
if (dataGridColumn.Header.ToString() == myPropertyName)
{
return true;
}
}
return false;
}
private DataGridColumn GetNewMyPropertyColumn(string myPropertyName)
{
DataGridTextColumn myFileNameColumn = new DataGridTextColumn();
myFileNameColumn.Header = myPropertyName;
myFileNameColumn.Width = new DataGridLength(1.0, DataGridLengthUnitType.Auto);
Binding valueBinding = new Binding();
valueBinding.Path = new PropertyPath("MyPropertyList");
valueBinding.Converter = new MyPropertyConverter(myPropertyName);
valueBinding.Mode = BindingMode.TwoWay;
valueBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
valueBinding.NotifyOnSourceUpdated = true;
valueBinding.NotifyOnTargetUpdated = true;
myFileNameColumn.Binding = valueBinding;
return myFileNameColumn;
}
我必须将MyPropertyName提供给Converter的构造函数,以便知道要查找的属性。
最后转换器
public class MyPropertyConverter : IValueConverter
{
private string m_propertyName = string.Empty;
ObservableCollection<MyProperty> m_myPropertyList = null;
public MyPropertyConverter(string propertyName)
{
m_propertyName = propertyName;
}
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
m_myPropertyList = value as ObservableCollection<MyProperty>;
if (m_myPropertyList == null)
{
return null;
}
foreach (MyProperty myProperty in m_myPropertyList)
{
if (myProperty.MyPropertyName == m_propertyName)
{
return myProperty.MyPropertyValue;
}
}
return null;
}
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (m_myPropertyList != null)
{
foreach (MyProperty myProperty in m_myPropertyList)
{
if (myProperty.MyPropertyName == m_propertyName)
{
myProperty.MyPropertyValue = value.ToString();
break;
}
}
}
return m_myPropertyList;
}
}
在转换中,它将检查给定的MyPropertyName,如果找到它,则返回MyPropertyValue,否则返回null。 ConvertBack方法也是如此,但它会将MyPropertyValue设置为具有给定MyPropertyName的MyProperty的新值,然后返回列表或列表为null。
不在MyFile列表中的属性将不可编辑,它们只会在离开单元格时变回null(这可能是重点)。
这将导致DataGrid看起来像这样。