首页 > 解决方案 > 在 DataTemplateSelector 中修改基于 XAML 的 DataTemplate

问题描述

有没有办法DataTemplate在返回之前进行修改DataTemplateSelector

DataTemplate在 XAML 中定义。此模板中有一个元素需要我为其设置绑定,但其绑定路径仅在运行时确定。模板如下所示:

<DataTemplate DataType="vm:FormField">
  <StackPanel>
    <ComboBox ItemsSource="{Binding ValueList.DefaultView}">
      <ComboBox.ItemTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding Mode=OneWay}" />         <!--This is the problem child-->
        </DataTemplate>
      </ComboBox.ItemTemplate>
    </ComboBox>
  </StackPanel>
</DataTemplate>

TextBlock.Text需要将其绑定路径设置为将由基础数据项提供的属性。我DataTemplateSelector使用以下代码为其分配新路径:

public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
  //MultiValueTemplate is the above template
  var Content = MultiValueTemplate.LoadContent() as StackPanel;

  var ComboItemText = (Content.Children[0] as ComboBox).ItemTemplate.LoadContent() as TextBlock;

  //Underlying item contains the field name that I want this to bind to.
  ComboItemText.SetBinding(TextBlock.TextProperty, (item as MyItemVM).FieldName);

  return MultiValueTemplate;
}

这行不通。代码运行,但输出未设置TextProperty绑定。我需要更改/添加什么?

注意:我已经使用FrameworkElementFactory方法解决了这个问题,但是我不得不DataTemplate在代码中重新定义整个代码(即使对于像上面这样的简单模板也是一种痛苦)。我想使用我已经在 XAML 中定义的那个。

注意2FrameworkElementFactory方法DataTemplate.VisualTree在最后一步中将构造的模板对象分配给,就在返回之前。我认为这是我缺少的那部分,但是没有办法这样做,因为VisualTree要求一个FrameworkElementFactory类型的对象,而在使用基于 XAML 的模板时我们没有。

背景

我们基本上是从服务器端获取 JSON 结构,如下所示:

`[ 
   "Person": 
   { 
     "Name": "Peter", 
     "Score": 53000 
   },
   "Person": 
   { 
     "Name": "dotNET", 
     "Score": 24000 
   }
   ,...
 ]

JSON 中将包含哪些字段将由服务器确定。我们的应用程序需要解析这个 JSON,然后显示与字段一样多的 ComboBox。然后每个 ComboBox 将在其中列出一个字段。因此,在上面的示例中,将有一个名称组合和一个分数组合。用户可以从第一个或第二个 ComboBox 中选择一个选项,但从一个组合中选择将自动从其他组合中选择相应的项目。

现在你可能会问,到底是谁设计了这个愚蠢的用户界面?不幸的是,我们既不知道也不控制这个决定。我要求客户端改为使用ONE Combo(而不是多个)和 DataGrid 作为其下拉列表,以便我们可以在每个网格行显示一个数据项,并且用户可以选择其中一项。清晰而简单。但管理层不同意,在这里我们试图模仿同步组合框。哈哈。

所以我们目前正在做的是将传入的 JSON 转换为DataTableon-the-fly。此 DataTable 为每个 JSON 字段获取一列,以及与它们的项目一样多的行;你可以说是一种旋转。然后我们创建 ComboBoes 并将每个 ComboBoes 绑定到此 DataTable 的单个字段。这个字段名称当然是动态的,并且是在运行时决定的,这意味着我必须DataTemplate在运行时修改,这就提出了这个问题。

希望它不会变得太无聊!:)

标签: wpfxamldatatemplatedatatemplateselector

解决方案


看起来你可以绑定SelectedValuePathDisplayMemberPathFieldName 并完成:

<ComboBox SelectedValuePath="{Binding RelativeSource={RelativeSource AncestorType=ComboBox}, Path=DataContext.FieldName}"
          DisplayMemberPath="{Binding RelativeSource={RelativeSource AncestorType=ComboBox}, Path=DataContext.FieldName}"/>

推荐阅读