将父视图DataContext绑定到DataTemplate子视图DataContexts

时间:2015-09-24 17:32:39

标签: wpf xaml mvvm data-binding datatemplateselector

我最近一直在尝试WPF,Xaml,MVVM和DependencyInjection。因此,我正在使用MVVM原则创建UI。 UI的某个部分被设计成像向导一样,其中并非所有可用选项同时呈现给用户。每个选项部分都是自己的视图(子视图),其中一个视图(父视图)在ContentControl中托管这些子视图。用户设置某些选项并使用按钮从一个部分移动到另一个部分。

查看导航

要在这些视图之间切换,我正在使用DataTemplateSelector,每个子视图在我的Xaml资源中定义为DataTemplate。

主视图中的内容控制:

        <ContentControl Content="{Binding ElementName=ParentViewControl, Path=ViewState, Mode=TwoWay}"
                    ContentTemplateSelector="{StaticResource MyTemplateSelector}" />

示例子视图数据模板:

    <DataTemplate x:Key="SubViewATemplate">
        <local:SubViewAView x:Name="SVAView" DataContext="{Binding ElementName=ParentViewControl, Path=DataContext}" ViewState="{Binding ElementName=ParentViewControl, Path=ViewState, Mode=TwoWay }" />
    </DataTemplate>

在父视图和每个子视图上,我创建了一个名为ViewState(枚举)的依赖属性。它们通过DataTemplates相互绑定。在每个View的代码隐藏中,我根据用户输入更新此ViewState属性,并将其传播到Parent View,后者又触发DataTemplateSelector。到现在为止还挺好。导航效果很好。

ViewModel信息

父视图有一个ViewModel,它实现了INotifyPropertyChanged作为其DataContext。我正在尝试使用此单个ViewModel将Properties绑定到Parent View和子视图。问题是上面的DataTemplate片段中的DataContext绑定不起作用。 (自从ViewState绑定以来,这对我来说很奇怪。)经过各种尝试使其工作,子视图上的DataContext为null或ViewState控制变量。

我目前正在使用UnityContainer作为我的依赖注入器。

各种尝试

以下是我尝试过的所有失败的其他事情:

1)将ViewModel注册为UnityContainer中的单例,从而在子视图上使用构造函数注入来设置DataContext。 (不起作用,因为DataTemplate资源必须有一个无参数的构造函数。)

2)将ViewModel注册为UnityContainer中的单例,然后在子视图上使用Property Injection来设置DataContext。 (不起作用。我认为这是因为在Xaml中实例化对象时UnityContainer无法正常工作。)

3)为需要ViewModel的每个子视图创建子ViewModel,以显示父ViewModel上已存在的属性。我之前用过这个来解决UnityContainer的Xaml实例化问题。然后,我将DataTemplate中的DataContext绑定替换为关联的子ViewModel。 (因为某些原因,我的父视图的DataContext被设置为ViewState变量而不是保留我在视图的构造函数中设置的ViewModel。这反过来意味着我的父ViewModel上的子ViewModel属性可以找不到绑定到子视图的DataContext。)UserControls的Content和DataContext是同一个东西吗?设置一个会影响另一个吗?

4)将ViewState依赖项属性从View移动到ViewModel,然后将ContentControl的Content设置为绑定到ViewModel。这违反了MVVM原则,但此时我正在尝试任何方法来实现这一点。 (它不起作用,因为在视图的代码隐藏中更改ViewState时ViewModel不会触发更改。)我没有进一步使用这个,因为我不想更深入地违反MVVM。

结论

在过去的几天里,我在这个网站上发现了大部分这些尝试过的解决方案。我没有接受WPF,Xaml和MVVM的正式培训,因此我怀疑我遗漏了一些明显的东西,或者我正在尝试做一些不可能的事情。我将继续尝试对上述内容进行修改并进行研究,直到找到可行的方法,但我想我会在这里利用集体知识来帮助我找到解决方案。

我更喜欢的是让视图组使用单个ViewModel作为其DataContext,这样我就可以将属性绑定到它们的控件。并且可以通过DataTemplateSelector控制Views的导航。有没有办法做到这一点,我没有看到?

感谢您的时间!

1 个答案:

答案 0 :(得分:0)

之前我遇到过类似的问题,我使用RelativeSource绑定运气好。也许尝试这样的事情:

DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContentControl},Path=DataContext}"

只是一个想法。