首页 文章

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

提问于
浏览
0

我有一个绑定到List的datagrid,其中每个ViewModel都有一个由字符串索引的字段数组,例如RowVM ["AKey"] . 使用类似于this的东西,我可以得到一个TextBlock来显示正确的元素,例如

textColumn.Binding= new Binding("[" + columnHeaderText + "].Name");

但这只允许我在TextBlock中显示一个值 .

我需要显示索引属性中的两个字段,所以我认为我使用 DataGridTemplateColumn 而不是 DataGridTextColumn ,但是无法使新绑定正确链接到列 Headers 文本 .

我的代码目前是每列

tmpltColumn = new DataGridTemplateColumn();
tmpltColumn.Header = t.FirstName + " " + t.LastName;
tmpltColumn.CellTemplate = TimeTableGrid.FindResource("TimeTableCellTemplate") as DataTemplate;
TimeTableGrid.Columns.Add(tmpltColumn);

其中 TimeTableCellTemplate 定义了两个文本块 .

如果我将TextBlocks的Text定义为

Text="{Binding Column.Header, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}}}"

然后文本块正确显示列 Headers .

我不能做的是找到将找到列 Headers 文本并将其用作索引的文本块的任何绑定 .

[编辑:]

我构建列时创建了原始TextColumn的绑定,并在索引括号中硬编码了相关的键值,例如[columnHeaderText] .Name(参见上面的textColumn.Binding) .

当我移动到TemplateColumns时,模板包含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}" />

这当然没有用 .

我错过了一些非常明显的东西吗?

[结束]

这有解决方案吗?或者我将不得不切换到网格并手动加载每个单元格?

我不需要双向绑定,如果这有帮助,尽管需要拖放到单元格和从单元格拖放 .

1 回答

  • 0

    我找到了一个迄今为止有效的解决方案,遵循this link中描述的模式 .

    带有简单TextBlock的原始版本将密钥(Column Headers )硬编码到Binding中,例如 [key].Name

    新版本创建了一个模板,嵌套的TextBlocks具有相同的Bindings,再次硬编码 .

    为完整起见,完整的代码调用以下内容:

    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中定义),这看起来更优雅,但这很简单易懂,也很好 .

相关问题