如何解决使用嵌套列表和动态列填充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;
}
解决方法
我的解决方案最终是使用我的列定义和行数据列表来构建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;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。