2

最近我一直在试验 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 相互绑定。在每个视图的代码隐藏中,我根据用户输入更新此 ViewState 属性,并将其传播到父视图,父视图进而触发 DataTemplateSelector。到现在为止还挺好。导航效果很好。

查看模型信息

父视图有一个 ViewModel,它实现了 INotifyPropertyChanged 作为它的 DataContext。我正在尝试使用这个单一的 ViewModel 将属性绑定到父视图和子视图。问题是上面 DataTemplate 片段中的 DataContext 绑定不起作用。(这对我来说很奇怪,因为 ViewState 绑定确实如此。)在多次尝试使其工作之后,子视图上的 DataContext 要么为空,要么为 ViewState 控制变量。

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

各种尝试

以下是我尝试过的其他各种失败的事情:

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

2)在UnityContainer中将ViewModel注册为单例,然后在子View上使用Property Injection来设置DataContext。(不起作用。我认为这是由于在 Xaml 中实例化对象时 UnityContainer 不起作用。)

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

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

结论

在过去的几天里,我在这个网站上找到了大多数这些尝试的解决方案。我没有在 WPF、Xaml 和 MVVM 方面接受过任何正式培训,所以我怀疑我遗漏了一些明显的东西,或者正在尝试做一些不可能的事情。我将继续尝试上述变化并进行研究,直到找到可行的方法,但我想我会利用这里的集体知识来帮助我找到解决方案。

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

感谢您的时间!

4

1 回答 1

2

我以前也遇到过类似的问题,我在使用 RelativeSource 绑定时很幸运。也许尝试这样的事情:

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

只是一个想法。

于 2015-09-24T19:41:37.730 回答