WPF:绑定到类内的列表

2024-03-25

我有一个文件类定义如下

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,显示文件名。另外,我想为每个创建一个列Property in the PropertyList, 字符串值为PropertyName作为列标题,PropertyValue 的字符串值作为列的值。

这在 WPF 中可能吗?

Thanks,


只是不得不尝试这个,奇怪但有趣的问题:-)设法通过使用以下内容使其工作。 抱歉回答太长,可能要详细一点:-)

首先,数据网格。干净利落

<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;
    }
}

在 Convert 中,它将检查给定的 MyPropertyName,如果找到,则返回 MyPropertyValue,否则返回 null。 ConvertBack 方法也是如此,但它会将 MyPropertyValue 设置为具有给定 MyPropertyName 的 MyProperty 的新值,然后返回列表(列表或 null)。

不在 MyFile 列表中的属性将不可编辑,它们只会在离开单元格时变回 null(这可能就是重点)。

这将产生如下所示的 DataGrid。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WPF:绑定到类内的列表 的相关文章

随机推荐