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}" />

这当然不起作用。

我是不是错过了一些显而易见的东西?

[完]

有解决方案吗?还是我必须切换到网格并手动加载每个单元格?

如果有帮助的话,我不需要双向绑定,尽管需要拖放到单元格。

WPF数据网格绑定到具有单元格模板列的数组列表

我已经找到了一个迄今为止有效的解决方案,遵循本链接中描述的模式。

带有简单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中定义)适用于所有列,这看起来更优雅,但这很简单易懂,这也很好。