WPF - 显示"dynamic"表



我想在 WPF 中显示一个项目表。一般来说,这并不难,除了:

  • 我知道,我只想在运行时显示哪些列(用户以某种方式定义它们),以及
  • 我想避免使用代码隐藏:XAML,我想显示表的地方在DataTemplate内,在另一个DataTemplate内等。 引入 CodeBehind 会有问题(尽管如果我没有其他选择,我会这样做)。

我虽然使用 WPF 的DataGrid,它足够聪明,可以在运行时提取列名(取决于集合项的属性),但我知道我只想在运行时显示哪些列 - 我必须在运行时创建具有特定属性的对象,这也是有问题的(如果可能的话)。

另外,我真的不需要专门使用DataGrid,因为这将是仅用于预览的简单字符串表 - 它可能也可以显示,例如,在带有 ItemsControl 的网格中 - 我只需要提供一个带有列和行的视图。

所以问题是:

  • 如何仅从 ViewModel (DataContext) 和 XAML 自定义 DataGrid 中显示的列?,或者
  • 当列仅在运行时已知时,如何显示预览数据的表格?

由于似乎对这个问题感兴趣并且我自己找到了解决方案,因此它就在这里(附加属性规则!

为了清楚起见,我创建了模型类来包装字符串列表:

public class TableDataRow
{
public TableDataRow(List<string> cells)
{
Cells = cells;
}
public List<string> Cells { get; }
}
public class TableData
{
public TableData(List<string> columnHeaders, List<TableDataRow> rows)
{
for (int i = 0; i < rows.Count; i++)
if (rows[i].Cells.Count != columnHeaders.Count)
throw new ArgumentException(nameof(rows));
ColumnHeaders = columnHeaders;
Rows = rows;
}
public List<string> ColumnHeaders { get; }
public List<TableDataRow> Rows { get; }
}

现在我们定义附加属性:

public static class DataGridHelper
{
private static void TableDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var dataGrid = d as DataGrid;
var tableData = e.NewValue as TableData;
if (dataGrid != null && tableData != null)
{
dataGrid.Columns.Clear();
for (int i = 0; i < tableData.ColumnHeaders.Count; i++)
{
DataGridColumn column = new DataGridTextColumn
{
Binding = new Binding($"Cells[{i}]"),
Header = tableData.ColumnHeaders[i]
};
dataGrid.Columns.Add(column);
}
dataGrid.ItemsSource = tableData.Rows;
}
}
public static TableData GetTableData(DependencyObject obj)
{
return (TableData)obj.GetValue(TableDataProperty);
}
public static void SetTableData(DependencyObject obj, TableData value)
{
obj.SetValue(TableDataProperty, value);
}
// Using a DependencyProperty as the backing store for TableData.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty TableDataProperty =
DependencyProperty.RegisterAttached("TableData", 
typeof(TableData), 
typeof(DataGridHelper), 
new PropertyMetadata(null, TableDataChanged));
}

用法很简单:

(...)
xmlns:h="clr-namespace:<namespace-of-DataGridHelper>"
(...)    
<DataGrid AutoGenerateColumns="False" h:DataGridHelper.TableData="{Binding ResultData}" />

显然,DataContext必须通过ResultData发布TableData。不要忘记AutoGenerateColumns,否则您将收到额外的"单元格"列。

相关内容

  • 没有找到相关文章

最新更新