WPF: binding to a list inside a class

I have a File class defined as

public class File
{
 public string FileName {set;get;}
 public List<Property> PropertyList;
}

Here's what the property class looks like:

public class Property
{
 public string PropertyName { set; get;};
 public string PropertyValue { set; get;};
 ...
}

I need to bind List<File>to DataGrid, display file_name. In addition, I want to create a column for each Propertyin PropertyList, with a string value PropertyNameas the column heading and a string value PropertyValue as the column value.

Is this possible in WPF?

Thank,

+3
source share
1 answer

I just had to try this strange but funny problem :-) I managed to get it to work using the following. Sorry for the long answer, maybe the path to detail :-)

First up is the DataGrid. Simple and simple

<DataGrid Name="c_dataGrid" AutoGenerateColumns="False"
          CanUserAddRows="False" CanUserDeleteRows="False"/>

Then the File class called 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;
    }
}

A class property called 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; }

, ItemsSource DataGrid

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;

DataGridTextColumn FileName

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 , , .
, ,

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 MyProperty MyPropertyName , , .

, MyFile, , (, , ).

DataGrid, .

alt text

+1

Source: https://habr.com/ru/post/1770364/


All Articles