繁体   English   中英

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

[英]WPF Datagrid binding to list of arrays with Cell Template Column

我有一个绑定到列表的数据网格,其中每个ViewModel都有一个由字符串索引的字段数组,例如RowVM [“ AKey”]。 使用类似的东西这个我可以得到一个TextBlock来显示正确的元素如

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);

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

如果我将TextBlocks的文本定义为

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的索引中使用该值。 为了满怀希望,我尝试了这一点,即将Column.Header绑定嵌入到CellTemplate绑定中:

<TextBlock Text="{Binding [{Binding Column.Header, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}}}].Name}" />

哪个当然不起作用。

我错过了令人眼花obvious乱的明显东西吗?

[结束]

有解决方案吗? 还是我将不得不例如切换到网格并手动加载每个单元格?

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

按照链接中描述的模式,我已经找到了一种可行的解决方案。

带有简单TextBlock的原始版本将键(列标题)硬编码到Binding中,例如[key].Name

新版本使用带有相同绑定的嵌套TextBlocks创建模板,再次对其进行硬编码。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM