【问题标题】:WPF: Inject DataContext into DataTemplate ViewWPF:将 DataContext 注入 DataTemplate 视图
【发布时间】:2016-07-13 23:11:19
【问题描述】:

我有一个控件,它有一个子 ContentControl,其视图是通过 DataTrigger 和 DataTemplate 设置的。我想做的是将这些控件的 DataContext 设置为我的主 DataContextViewModel 的属性。我的视图代码是这样的。

    <UserControl.Resources>
        <DataTemplate x:Key="ManageTags">
            <local:TagsEditView DataContext="{Binding Path=TagsEditViewModel}">        
             </local:TagsEditView>
        </DataTemplate>
        <DataTemplate x:Key="ExportTags">
             <local:TagsExportView DataContext="{Binding Path=TagsExportViewModel}">
             </local:TagsExportView>
        </DataTemplate>
        <DataTemplate x:Key="ImportTags">
             <local:TagsImportView DataContext="{Binding Path=TagsImportViewModel}">
              </local:TagsImportView>
      </DataTemplate>

在包含视图的 ViewModel 上,我已确认已正确设置和更新以下属性:

    public TagsExportViewModel TagsExportViewModel { get; set; }
    public TagsImportViewModel TagsImportViewModel { get; set; }
    public TagsEditViewModel TagsEditViewModel { get; set; }

一切都很好,直到我窥探子视图(TagsEditView、TagsImportView..)然后我看到 DataContext 没有被设置。

究竟如何将这些 ViewModel 放入这些视图中?还是我走错了路?

非常感谢任何帮助。

【问题讨论】:

  • 你的本地控件是什么类型的:TagsImportView 和其他自定义控件?他们继承了什么?您的 DataTemplate 对其数据进行模板化的控件是什么?

标签: wpf dependency-injection


【解决方案1】:

对于 ContentControl,您需要设置 Content 属性,而不是 DataContext 属性。然后,所有子控件将从 ContentControl 的 Content 属性中获取它们的 DataContext。

【讨论】:

  • 所以没有办法根据 ContentControl 中呈现的视图来更改 DataContext?
  • @FlexFiend 你能解释一下为什么你认为你需要改变 DataContext 吗?
  • 我不需要更改数据上下文,我需要在那些视图上设置它。
  • A ContentControl 不对本地 DataContext 做任何事情。相反,它呈现 Content 属性。
  • 我不想将它注入到 ContentControl 中,我想将它注入到将占据 ContentControl 的触发视图中。
【解决方案2】:

我不太确定,但这应该是应该的。

<DataTemplate x:Key="ManageTags" DataType="{x:Type vm:TagsEditViewModel}">
    <local:TagsEditView />
</DataTemplate>
<DataTemplate x:Key="ExportTags" DataType="{x:Type vm:TagsExportViewModel}">
    <local:TagsExportView />
</DataTemplate>
<DataTemplate x:Key="ImportTags" DataType="{x:Type vm:TagsImportViewModel}">
    <local:TagsImportView />
</DataTemplate>

这就是他们所说的“ViewModel-first-MVVM”。

就我个人而言,我只将它用于TabControl,所以我也不是这方面的专家。大多数时候我只是去“View-first-MVVM”。

<local:TagsEditView>
    <local:TagsEditView.DataContext>
        <vm:TagsEditViewModel />
    </local:TagsEditView.DataContext>
</local:TagsEditView>
<local:TagsExportView>
    <local:TagsExportView.DataContext>
        <vm:TagsExportViewModel />
    </local:TagsExportView.DataContext>
</local:TagsExportView>
<local:TagsImportView>
    <local:TagsImportView.DataContext>
        <vm:TagsImportViewModel />
    </local:TagsImportView.DataContext>
</local:TagsImportView>

【讨论】:

    【解决方案3】:

    您正在使用ContentControl 及其ContentTemplate

    ContentTemplate 用于自定义Content

    因此,在您的情况下,您必须在您的DataTrigger's Setter 中设置Content。一切都会到位。请参阅下面的示例:

    <DataTrigger Binding="{Binding CurrentVMindex}" Value="1">
      <Setter Property="Content" Value="{Binding VM1}"/>
      <Setter Property="ContentTemplate" Value="{StaticResource VM1Key}"/>
    </DataTrigger>
    
    <DataTemplate x:Key="VM1Key">
        <TextBlock Background="Green" Text="{Binding Name, Mode=OneWay}"/>
    </DataTemplate>
    

    因此,在您的情况下,请从您的 DataTemplate 中删除 DataContext

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-19
      • 1970-01-01
      • 2015-06-27
      • 2011-02-16
      • 2011-01-25
      • 2010-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多