WPF:绑定(bind)到类内的列表

标签 wpf

我有一个文件类定义如下

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

我需要绑定(bind)一个List<File>到 DataGrid,显示文件名。另外,我想为每个 Property 创建一列在 PropertyList , 字符串值为 PropertyName作为列标题,PropertyValue 的字符串值作为列的值。

这在 WPF 中可能吗?

谢谢

最佳答案

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

首先是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 一次,所以如果我有以下
我的文件1
-名称1
-姓名2
-姓名3
我的文件2
-名称1
-名称4
-姓名5
生成的列应为 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。

alt text

关于WPF:绑定(bind)到类内的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3971220/

相关文章:

c# - TextBox文本作为参数n Double事件

c# - 获取winform列表框的所有项目

c# - 列表框项目删除

c# - 将文本框拆分为 4 个独立的文本框,但保存在一个 EF 字段中

c# - MVVM,我是否必须将每个命令保留在自己的类中?

c# - 拖动 WPF 用户控件

c# - 尝试添加命令行支持后无法使用断点

wpf - 带边框的透明窗口

c# - yt:在YouTube供稿中找不到统计信息

c# - 只有托盘图标的 WPF 应用程序