WPF数据网格绑定到具有单元格模板列的数组列表
本文关键字:列表 数组 单元格 数据网 数据 网格 绑定 WPF | 更新日期: 2023-09-27 18:27:27
我有一个数据网格,它绑定到一个列表,其中每个ViewModel都有一个由字符串索引的字段数组,例如RowVM["AKey"]。使用类似的东西我可以得到一个文本块来显示正确的元素,例如
textColumn.Binding= new Binding("[" + columnHeaderText + "].Name");
但这只允许我在TextBlock中显示一个值。
我需要显示indexed属性中的两个字段,所以我想使用DataGridTemplateColumn
而不是DataGridTextColumn
,但无法使新绑定正确链接到列标题文本。
对于每一列,我的代码当前为
tmpltColumn = new DataGridTemplateColumn();
tmpltColumn.Header = t.FirstName + " " + t.LastName;
tmpltColumn.CellTemplate = TimeTableGrid.FindResource("TimeTableCellTemplate") as DataTemplate;
TimeTableGrid.Columns.Add(tmpltColumn);
其中CCD_ 3定义了两个文本块。
如果我将文本块的文本定义为
Text="{Binding Column.Header, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}}}"
则文本块正确地显示列标题。
我不能为文本块找到任何绑定,这些绑定将定位列标题文本并将其用作索引。
[编辑:]
原始TextColumn的绑定是在我构建列时创建的,并将相关键值硬编码在索引括号中,例如[columnHeaderText].Name(请参阅上面的TextColumn.binding)。
当我转到TemplateColumns时,Template包含Binding表达式,并且不是特定于特定列的。
所以我有以下(简化):
<DataGrid.Resources>
<DataTemplate x:Key="TimeTableCellTemplate" >
<StackPanel Width="Auto" Height="Auto" Orientation="Vertical" >
<TextBlock Text="{Binding Column.Header, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}}}" />
</StackPanel>
</DataTemplate>
</DataGrid.Resources>
显示的Binding正确地显示了TextBlock
中的实际Column.Header,但我需要做的是在RowViewModel的索引中使用该值。在充满希望的情况下,我尝试了这样做,即在CellTemplate绑定中嵌入Column.Header绑定:
<TextBlock Text="{Binding [{Binding Column.Header, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}}}].Name}" />
这当然不起作用。
我是不是错过了一些显而易见的东西?
[完]
有解决方案吗?还是我必须切换到网格并手动加载每个单元格?
如果有帮助的话,我不需要双向绑定,尽管需要拖放到单元格。
我已经找到了一个迄今为止有效的解决方案,遵循本链接中描述的模式。
带有简单TextBlock的原始版本将密钥(列标题)硬编码到绑定中,例如[key].Name
新版本创建了一个带有嵌套TextBlocks的模板,该模板具有相同的Binding,同样是硬编码的。
为了完整性,完整的代码调用以下内容:
private DataGridTemplatColumn CreateColumn(string key)
{
DataGridTemplateColumn tmpltColumn = new DataGridTemplateColumn();
tmpltColumn.Header = key;
// Make the parts for the template
FrameworkElementFactory tb = new FrameworkElementFactory(typeof(TextBlock));
Binding b = new Binding($"[{key}].Name");
tb.SetBinding(TextBlock.TextProperty, b);
FrameworkElementFactory tb1 = new FrameworkElementFactory(typeof(TextBlock));
Binding b1 = new Binding();
b1.Path = new PropertyPath($"[{key}].Room");
tb1.SetBinding(TextBlock.TextProperty, b1);
FrameworkElementFactory sb = new FrameworkElementFactory(typeof(StackPanel));
sb.AppendChild(tb);
sb.AppendChild(tb1);
DataTemplate dt = new DataTemplate { VisualTree = sb };
dt.Seal();
tmpltColumn.CellTemplate = dt;
return tmpltColumn;
}
然后将模板列添加到DataGrid中,一切都很好。
当我问这个问题时,我想让一个模板(在XAML中定义)适用于所有列,这看起来更优雅,但这很简单易懂,这也很好。