1

I'm trying to create an DataGrid that automatically generates itself according to the Property and Fields coming from the different classes. Each class is created as a row and each property or field as a column. These classes have thousands of same Fields and Properties, but their values ​​are different.

There is no way to bind fields to DataGrid. So thats why i created columns dynamically like in this post: How to add Fields to DataGrid in WPF?. After running the code snippet below, I put the created properties from dynamic List (named dataObjects) to columns and then added the columns i created to DataGrid.

//Get all properties and fields from classes and send them into dynamic list
private void Property_ve_Field_Dinamik_Objeye_At()
{
    //Sinif_Tutucu is an ObservableCollection which holds all Classes.
    foreach (var item in Sinif_Tutucu)
    {
        //Get all fields from class
        var fields = item.GetType().GetFields();
        //Gett all properties from class
        var properties = item.GetType().GetProperties();

        dataObject = new System.Dynamic.ExpandoObject();

        foreach (var field in fields)
        {
            dataObjectValues = (IDictionary<string, object>)dataObject;
            dataObjectValues[field.Name] = field.GetValue(item);
        }
        foreach (var property in properties)
        {
            dataObjectValues = (IDictionary<string, object>)dataObject;
            dataObjectValues[property.Name] = property.GetValue(item);
        }

        dataObjects.Add(dataObject);
    }

    dataObjectValues = dataObjects[0];
}

Here is definitions of variables used in the code above;

//Holds all classes
private ObservableCollection<object> _Sinif_Tutucu_ = new ObservableCollection<object>();
public ObservableCollection<object> Sinif_Tutucu //<--I'm getting the properties and fields from the classes in it.
{
    get { return _Sinif_Tutucu_; }
    set
    {
        if (value != _Sinif_Tutucu_)
        {
            this._Sinif_Tutucu_ = value;
        }
    }
}

//Holds rows and columns dynamically
private List<dynamic> _dataObjects_ = new List<dynamic>();
public List<dynamic> dataObjects //<-- This list is updating when i edit an item.
{
    get { return _dataObjects_; }
    set
    {
        if (value != _dataObjects_)
        {
            this._dataObjects_ = value;
        }
    }
}

dynamic dataObject;

IDictionary<string, object> dataObjectValues;

And DataGrid's source is like this;

DataGrid_1.ItemsSource = dataObjects;

Everything is so beautiful up to here. My DataGrid gets all fields and properties from all classes i have defined and shows their values correctly. When I edit the cells, I want it set the properties and fields in the classes. (SelectionMode = Single and SelectionUnit = Cell) But it doesn't update because I used the code I put above. Thats why, the values ​​in the DataGrid are no longer directly binded to the class. They are binded to the dynamic List. When I edit the values in the DataGrid, dynamic List is updated only instead of the property or fields in the classes.

When a value is edited, I tried to set it in the class it belongs to. But i don't want to do this manually. Because there is thousands of property and field. So i can't set them one by one. Program should understand which value i am changing in the DataGrid and which property or field going to be updated. Then it should update property or field in that class.

Or the list I am currently using is already being updated. It can be in a system that sets all values ​​in the list to properties and fields in classes when I press the button. (If anyone can tell me how to to this, this would be more useful. But any other solutions are can be too)

I tried to do the solutions I mentioned in the last two paragraphs but failed. I am new in the WPF world and still have problems coding. If there is any mistake in my English, sorry for that. I am learning English too. Finally, I've included a diagram below to make it clearer what I'm trying to do. Here is the diagram.

Airn5475
  • 2,452
  • 29
  • 51
Schia
  • 232
  • 1
  • 11

1 Answers1

1

No answers.

It took me 8 days and I found the solution by trying. Here is the solution;

dataObjects' type is List<dynamic> and dataObjectValues' type is IDictionary<string, object>. It consists of dataObjects dataObjectValues. DataGrid's ItemSource is dataObjects. When i edit DataGrid, values are written to the list. Then I update the classes one by one using the list.

public void Siniflara_Veri_Yaz()
{
    //Loop for rows
    for (int i = 0; i<dataObjects.Count; i++)
    {
        //Get row
        dataObjectValues = dataObjects[i];

        //Loop for Column
        for (int j = 0; j < dataObjectValues.Count; j++)
        {
            string Binding_Path = DataGrid_1.Columns[j].SortMemberPath;
            //Get PropertyInfo if exist
            PropertyInfo propInfo = Sinif_Tutucu[i].GetType().GetProperty(Binding_Path);

            //If doesn't exist, it have to be a Field
            if(propInfo != null)
            {
                //DataGrid uses textColumn (string)
                //Get column types from Classes and cast string to whatever type the column is.
                dataObjectValues[Binding_Path] = Tip_Degistir(propInfo.PropertyType.Name, dataObjectValues[Binding_Path].ToString());
                propInfo.SetValue(Sinif_Tutucu[i], dataObjectValues[Binding_Path]);
            }
            //Same thing but for fields
            else
            {
                FieldInfo fieldInfo = Sinif_Tutucu[i].GetType().GetField(Binding_Path);
                dataObjectValues[Binding_Path] = Tip_Degistir(fieldInfo.FieldType.Name, dataObjectValues[Binding_Path].ToString());
                fieldInfo.SetValue(Sinif_Tutucu[i], dataObjectValues[Binding_Path]);
            }
        }
    }
}

Edit 1:

Sinif_Tutucu is an ObservableCollection which holds all classes I added to the DataGrid.

Schia
  • 232
  • 1
  • 11