C# 如何使用Prism'将多个ViewModels连接到单个视图;什么是视图定位器?
我使用Prism的viewlocator连接View和ViewModel,并遵循惯例,将视图放置在View文件夹中,将ViewModel放置在ViewModel文件夹中,还将后缀ViewModel添加到ViewModel类的名称中。一切都很好。我只是想知道如何将多个viewmodels连接到一个视图 例如,我有: 查看:C# 如何使用Prism'将多个ViewModels连接到单个视图;什么是视图定位器?,c#,wpf,xaml,mvvm,prism,C#,Wpf,Xaml,Mvvm,Prism,我使用Prism的viewlocator连接View和ViewModel,并遵循惯例,将视图放置在View文件夹中,将ViewModel放置在ViewModel文件夹中,还将后缀ViewModel添加到ViewModel类的名称中。一切都很好。我只是想知道如何将多个viewmodels连接到一个视图 例如,我有: 查看:CustomerView 在XAML中,我只需使用:prism:ViewModelLocator.AutoWireViewModel=“True” ViewVodel:Custo
CustomerView
在XAML中,我只需使用:prism:ViewModelLocator.AutoWireViewModel=“True”
ViewVodel:CustomerViewModel
现在我想添加
CustomerViewModel2
,但它不起作用,因为它与视图的名称不匹配您可以将子视图模型作为页面主视图模型的属性公开,然后在绑定中的子视图模型路径前面加上属性名。您可以将子视图模型作为页面主视图模型的属性公开,然后在绑定中的子视图模型路径前面加上属性名。正如我在评论中提到的,不可能将单个视图直接连接到多个(同一级别)视图模型
您必须将视图拆分为一个主视图和(多个)子视图(逻辑上在XAML中,或者物理上通过将子视图移动到单独的UserControl
s)
以下是我的建议
<Window>
<StackPanel Orientation="Vertical">
<ContentControl prism:RegionManager.RegionName="Region1"/>
<ContentControl prism:RegionManager.RegionName="Region2"/>
</StackPanel>
</Window>
每个子视图都有自己的视图模型。可以使用棱柱体的视图模型定位器自动关联它们
<Window>
<Window.Resources>
<DataTemplate DataType="vm:ViewModel1">
<v:UserControl1/>
</DataTemplate>
<DataTemplate DataType="vm:ViewModel2">
<v:UserControl2/>
</DataTemplate>
</Window.Resources>
<ItemsControl ItemsSource="{Binding Items}"/>
</Window>
当然,您可以使用DI来实例化视图模型
class MainViewModel : BindableBase
{
public ViewModel1 ViewModel1 { get; private set; }
public ViewModel2 ViewModel2 { get; private set; }
}
在主视图中,必须相应地设置绑定
<Window>
<StackPanel>
<TextBlock Text="{Binding ViewModel1.SomeValue}"/>
<TextBox Text="{Binding ViewModel2.SomeValue}"/>
</StackPanel>
</Window>
正如我在评论中提到的,不可能直接将单个视图与多个(相同级别)视图模型连接起来 您必须将视图拆分为一个主视图和(多个)子视图(逻辑上在XAML中,或者物理上通过将子视图移动到单独的
UserControl
s)
以下是我的建议
<Window>
<StackPanel Orientation="Vertical">
<ContentControl prism:RegionManager.RegionName="Region1"/>
<ContentControl prism:RegionManager.RegionName="Region2"/>
</StackPanel>
</Window>
每个子视图都有自己的视图模型。可以使用棱柱体的视图模型定位器自动关联它们
<Window>
<Window.Resources>
<DataTemplate DataType="vm:ViewModel1">
<v:UserControl1/>
</DataTemplate>
<DataTemplate DataType="vm:ViewModel2">
<v:UserControl2/>
</DataTemplate>
</Window.Resources>
<ItemsControl ItemsSource="{Binding Items}"/>
</Window>
当然,您可以使用DI来实例化视图模型
class MainViewModel : BindableBase
{
public ViewModel1 ViewModel1 { get; private set; }
public ViewModel2 ViewModel2 { get; private set; }
}
在主视图中,必须相应地设置绑定
<Window>
<StackPanel>
<TextBlock Text="{Binding ViewModel1.SomeValue}"/>
<TextBox Text="{Binding ViewModel2.SomeValue}"/>
</StackPanel>
</Window>
将viewmodels设置为分部类 将viewmodels设置为分部类 你想达到什么目标?一个视图只有一个DataContext
属性,因此它只能有一个视图模型。当然,子视图或视图的某些部分可以具有不同的视图模型,但这不能使用PRISM的视图模型定位器来实现。为此,您必须使用数据模板或视图注入/区域。我的ViewModel类变得太大和混乱,因此我想将其拆分为更多的ViewModels,类似于模型。这听起来可能是重构代码的好时机。将一些代码转移到其他有意义的类中可以减少一些混乱。至少,使用区域对代码进行分组,以便在需要时可以折叠/展开代码。您试图实现什么?一个视图只有一个DataContext
属性,因此它只能有一个视图模型。当然,子视图或视图的某些部分可以具有不同的视图模型,但这不能使用PRISM的视图模型定位器来实现。为此,您必须使用数据模板或视图注入/区域。我的ViewModel类变得太大和混乱,因此我想将其拆分为更多的ViewModels,类似于模型。这听起来可能是重构代码的好时机。将一些代码转移到其他有意义的类中可以减少一些混乱。至少,使用区域对代码进行分组,以便在需要时可以折叠/展开代码。感谢您的详细回答。我真的很喜欢区域的概念,我记得我以前试过使用它。问题是,我正在使用的视图是我导航到的页面。所以如果我这样做:“regionManager.RegisterViewWithRegion(“Region1”,typeof(UserControl1));”然后,该视图(页面)在应用程序启动后立即可见。我目前使用的是“RegisterForNavigation”方法,但这种方法与“RegisterViewWithRegion”相冲突,谢谢您的详细回答。我真的很喜欢区域的概念,我记得我以前试过使用它。问题是,我正在使用的视图是我导航到的页面。所以如果我这样做:“regionManager.RegisterViewWithRegion(“Region1”,typeof(UserControl1));”然后,该视图(页面)在应用程序启动后立即可见。我目前使用的是“RegisterForNavigation”方法,但这种方法与“RegisterViewWithRegion”在技术上存在冲突,这个答案是不正确的,因为部分类定义描述了一个单独的类-将只实例化一个对象。虽然这看起来像是OP的解决方案,但一般来说,这不是一个。从技术上讲,这个答案是不正确的,因为部分类定义描述了一个单独的类-只有一个对象被实例化。虽然这看起来像是OP的解决方案,但总的来说,它不是。