使用嵌套列表和动态列填充DataGrid

我有一个奇怪的数据模型,我试图在数据网格中生成动态列并正确绑定项目。

我有一个Row对象的列表,我想将它们绑定到DataGrid并使用简单的DataGridTextColumn显示。

<controls:DataGrid
   Grid.Row="1"
   x:Name="dataGrid"
   ItemsSource="{x:Bind ViewModel.CurrentRows}"

我的目标是从第一行中获取列的列表,并在设置绑定时构建网格列。我在弄清楚在RowValue.value上绑定数据的正确方法时遇到了麻烦。

public TablePage()
{
    InitializeComponent();

    dataGrid.ItemsSource = ViewModel.CurrentRows;

    foreach (Column column in ViewModel.CurrentRows.FirstOrDefault().Values.Select(x => x.key))
    {
        dataGrid.Columns.Add(new DataGridTextColumn()
        {
            Header = column.ColumnValidation.column_label,Binding = new Binding() { Path = new PropertyPath("Values.value") }
        });
    }
}

在我的视图模型中,我有:

public ObservableCollection<Row> CurrentRows

Row对象如下所示:

public class Row: INotifyPropertyChanged
{
    public List<RowValue> Values { get; set; } = new List<RowValue>();

    public event PropertyChangedEventHandler PropertyChanged;
}

最后,一个RowValue对象看起来像这样:

public class RowValue: INotifyPropertyChanged
{
    public Column key { get; set; }
    public string value { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
}

列看起来像这样:

public class Column
{
    public string name;
    public ColumnValidation ColumnValidation;
}

ColumnValidation看起来像这样:

public class ColumnValidation
{
    public string column_label;
    public DataTypeEnum data_type;
    public int width;
    public int decimal_places;
    public int display_order;
    public string calculation_formula;
    public string edit_style;
    public string default_value;
    public decimal? minimum_value;
    public decimal? maximum_value;
    public bool is_column_nullable = false;
    public bool inherit_values = false;
    public bool display_column = false;
    public bool is_editable = false;
    public int column_style;
    public string code_table_name;
    public string code_display_name;
    public string code_data_column_name;
}
iCMS 回答:使用嵌套列表和动态列填充DataGrid

我的解决方案最终是使用我的列定义和行数据列表来构建DataTable。这是一个非常肮脏的解决方案,但它适合我的目的。我没有从网格中进行任何编辑或保存,它只是用于显示数据。编辑将在其他地方的对话框中进行。

public TablePage()
{
    InitializeComponent();

    // get list of columns
    List<Column> columns = ViewModel.CurrentTableDefinition.Columns.OrderBy(x => x.ColumnValidation.display_order).ToList();

    // create DataTable
    DataTable dataTable = new DataTable();
    dataTable.Columns.Add(new DataColumn() { ColumnName = "RowObject" }); // add column to store original row object

    // add columns to datagrid and datatable
    for (int i = 0; i < columns.Count; i++)
    {
        // add column to datagrid using the correct header label. bind using index of array.
        dataGrid.Columns.Add(new DataGridTextColumn()
        {
            Header = columns[i].ColumnValidation.column_label,Tag = columns[i].name,Binding = new Binding() { Path = new PropertyPath("[" + i.ToString() + "]") }
        });

        // add corresponding column to datatable
        dataTable.Columns.Add(new DataColumn() { ColumnName = columns[i].name });
    }

    // iterate through rows of data
    foreach (Row row in ViewModel.CurrentRows)
    {
        // create new datatable row
        DataRow dataRow = dataTable.NewRow();

        // set the original row object 
        dataRow["RowObject"] = row;

        // add data from each column in the row to the datatable row
        for (int i = 0; i < columns.Count; i++)
        {
            // add column value to row
            try
            {
                dataRow[i] = row.Values.Where(x => x.key.name == columns[i].name).FirstOrDefault().value;
            }
            
            catch (Exception ex)
            {
                dataRow[i] = null; // insert null if the table has columns defined for which there is no data in the dataset
            }
        }

        // add datable row to datatable
        dataTable.Rows.Add(dataRow);
    }

    // convert datatable to collection of 'object'
    ObservableCollection<object> collection = new ObservableCollection<object>();

    foreach(DataRow row in dataTable.Rows)
        collection.Add(row.ItemArray);

    // bind to datagrid
    dataGrid.ItemsSource = collection;
}
本文链接:https://www.f2er.com/1708745.html

大家都在问