WPF 使用数据模板将视图模型绑定到多个视图

时间:2021-07-22 10:15:49

标签: wpf

我成功地使用 ResourceDictionary 将我的视图模型绑定到视图,但我无法将相同的视图模型绑定到两个不同的视图。

这是我目前的代码:

资源字典 XAML:

<ResourceDictionary>
    <DataTemplate x:Key="Template1" DataType="{x:Type domain:MyViewModel}">
        <views:MyView/>
    </DataTemplate>

    <DataTemplate x:Key="Template2" DataType="{x:Type domain:MyViewModel}">
        <views:MyOtherView/>
    </DataTemplate>
</ResourceDictionary>

查看 XAML:

<UserControl x:Class="MyProject.Views.MyView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MyProject.Views"
             xmlns:i= "http://schemas.microsoft.com/xaml/behaviors"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="400"
             Content="{Binding MyViewModel}"
             ContentTemplate="{DynamicResource Template1}">
    <Grid>
    </Grid>
</UserControl>

这显然是完全错误的,因为我现在收到 xaml 错误“UserControl.Content 已设置多次”,以及网格下的绿线。

然后我尝试删除 UserControl 的 Content 属性,它允许它构建但当然也不绑定到视图模型。

那么我应该如何使用数据模板键正确设置内容?

1 个答案:

答案 0 :(得分:1)

您设置了 Content 属性两次。

当您在 ContentControl 的标记之间添加 UI 元素(UserControlContentControl)时,此元素会隐式分配给 Content 属性。在您的示例中,Grid 被隐式分配给 ContentMyView 属性。同时,您通过在 Content 上设置数据绑定来显式分配 MyView.Content 属性。

摆脱异常的解决方案是删除 GridContent 属性上的绑定。这将修复您的异常,但会直接导致新的异常。

通过将视图模型分配给 Content 属性,同时为 DateTemplate 属性定义了 ContentTemplate,您指示 WPF 将 DataTemplate 的内容添加到您的 Content (UserControl) 的 MyView。由于 MyView 是模板化控件,同时也是 DataTemplate 的内容,因此您基本上是在尝试将 MyView 添加到 {{1} 的 Content }}。这会导致无限循环,因为一旦将 MyView 添加到 MyView,它就会将另外第三个 MyView 添加到第二个 MyView,依此类推。很容易预测这将导致 MyView

您可能想要的是将视图模型的同一个实例绑定到多个控件。

对于这个,解决方案是将共享视图模型的一个实例添加到全局 App.xaml ResourceDictionary 并使用 StaticResource 从那里引用它:

App.xaml

StackOverfloException

查看 1

<Application>
  <Application.Resources>
    <ViewModel x:Key="SharedViewModel" />
  <Application.Resources>
<Application>

查看 2

<Window DataContext="{StaticResource SharedViewModel}">

</Window>

请注意,在 XAML 中创建视图模型的实例需要您的视图模型具有无参数构造函数。
还要记住在整个应用程序中使用 App.xaml 中定义的实例(无论何时需要引用相同的视图模型)。因此,您必须删除之前的视图模型分配(例如 <UserControl DataContext="{StaticResource SharedViewModel}"> </UserControl> )。