【问题标题】:Set a DataContext through DataTemplateSelector通过 DataTemplateSelector 设置 DataContext
【发布时间】:2020-12-10 19:17:42
【问题描述】:

我在通过 DataTemplateSelector 实例化数据模板时将数据上下文设置为数据模板内的控件时遇到问题。

这是我的 CustomView 代码结构。

我有一个 ListBox,我为其分配要填充的项目列表。

一些 DataTemplatesCustomView 中定义为资源:

<DataTemplate x:Key="Template1">
      <views:CustomControl DataContext="{Binding ???}"/>
</DataTemplate>

<DataTemplate x:Key="Template2">
      <views:CustomControl DataContext="{Binding ???}"/>
</DataTemplate>

每个 ListBox 项都经过一个 DataTemplateSelector

<GridViewColumn Header="Change" Width="330">
    <GridViewColumn.CellTemplate>
         <DataTemplate>
              <ContentControl Content="{Binding}" ContentTemplateSelector="{StaticResource ResolverTemplateSelector}"/>
         </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

ResolverTemplateSelector 所做的只是检查当前 Item 的属性并返回正确的 DataTemplate:

CustomControl control = GetRootControl(container);

if (Item is ObjectType object)
{
    DataTemplate template;
    switch (object.Property)
    {
        case PropertyValue1:
            template = FindTemplateFromString("Template1", control);
            break;

        case PropertyValue2:
            template = FindTemplateFromString("Template2", control);
            break;
    }
    object.DataTemplate = template;
    return template;

这很好用,模板已设置,我可以在视图中看到它。 问题是我无法使用我需要的设置模板中实例化的 CustomControlDataContext。 我需要使用存储在 CustomViewViewModel 中的属性来设置它的 DataContext。 我试过了:

<DataTemplate x:Key="Template1">
    <views:CustomControl DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type views:CustomView}}, Path=DataContext}"/>
</DataTemplate>

至少尝试让 DataContext 与 CustomView 相同,这样我就可以在后面的代码中访问它的属性,但没有运气。 DataContext 始终为 null

有什么想法吗?也许我做错了什么?

谢谢。

【问题讨论】:

  • 尝试中的每个事物的数据上下文 TEMSControl 是项。您绑定 itemssource。模板为每一行创建 ui,每行的数据上下文是对应的项。使用数据类型将数据模板与行/项目视图模型类型相关联也很常见。数据模板选择器在 uwp 应用程序中是必需的,但在 wpf 中很少见。
  • 换一种说法。您已经有一个数据上下文。 datatemplateselector 正在选择一个数据模板,该模板将用于为该数据上下文(行的)生成 UI。
  • 是的,这就是我的想法,但是查看本地人或尝试访问它会引发异常,因为这些项目的 DataContext(在这些项目中产生的 CustomControl)始终为空。
  • 您的绑定通常可以工作。但在这种特殊情况下,它不会。这是因为GridView 的列不是逻辑树的一部分。在这种情况下,如果源在模板之外,则无法解析 Binding.RelativeSource
  • 您的项目的视觉效果不是基于它所代表的数据项目的原因是什么?看来您的数据设计需要一些重构。项目模板所需的所有信息都应由项目的模型提供(DataTemplateDataContext)。

标签: c# wpf datatemplate datacontext


【解决方案1】:

最后我可以完成这项工作。 对于其他尝试相同事情的人:

  <views:CustomControl DataContext="{Binding ElementName=ParentView, Path=TargetViewModel}"/>

【讨论】:

    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-26
    • 1970-01-01
    • 2012-11-09
    • 2014-12-20
    • 2016-04-01
    相关资源
    最近更新 更多