C# WPF MVVM:单击按钮从一个用户控件切换到另一个用户控件
我一直在慢慢地玩弄MVVM,从那时起,这个概念就开始流行起来。我有一个应用程序窗口和两个用户控件,每个控件都连接了viewModels。我想单击第一个用户控件中的一个按钮,然后转到第二个用户控件 我看过一些教程,例如: 这两种方法都在主窗口视图模型中更改屏幕,但我希望在用户控件本身中进行更改。可以传递命令将窗口更改回主应用程序视图模型,或者让用户控件模型在单击按钮时更改视图C# WPF MVVM:单击按钮从一个用户控件切换到另一个用户控件,c#,wpf,mvvm,C#,Wpf,Mvvm,我一直在慢慢地玩弄MVVM,从那时起,这个概念就开始流行起来。我有一个应用程序窗口和两个用户控件,每个控件都连接了viewModels。我想单击第一个用户控件中的一个按钮,然后转到第二个用户控件 我看过一些教程,例如: 这两种方法都在主窗口视图模型中更改屏幕,但我希望在用户控件本身中进行更改。可以传递命令将窗口更改回主应用程序视图模型,或者让用户控件模型在单击按钮时更改视图 编辑:我想我需要将其作为命令传递,但我不确定如何传递希望随它一起传递的视图 在MVVM中,命令通常在ViewModel级
编辑:我想我需要将其作为命令传递,但我不确定如何传递希望随它一起传递的视图 在MVVM中,命令通常在ViewModel级别工作,与视图层无关(或不了解视图层)。要实现您所描述的功能,请创建一个控制要查看的视图类型的公共属性。例如(使用MVVM灯光): 编辑 回答你的评论: 视图并不真正与viewModel交互:这是错误的。视图总是与VM交互,VM对视图一无所知。关于您的困惑,请理解您不需要为每个用户控件创建一个VM。VM是根据视图而不是控件创建的。因此,您可能会有一个名为MainVM的ViewModel,公开视图将绑定到的所有公共属性。然后,每个用户控件只能使用它感兴趣的属性。然后,当底层VM的特定属性发生更改时,触发器可以将视图从一个用户控件切换到另一个用户控件。新的用户控件将显示正确的数据,因为它将绑定到它想要使用的VM属性
请记住,VM不想(也没有办法)知道view是如何使用它的。它只需要正确地保持其状态。视图随后可以响应状态更改并相应地更新自身。
DataTemplates
用于此目的。将每个用户控件作为数据模板添加到窗口中。在ViewModel中,创建控制要查看的视图类型的公共属性。在您的窗口中,创建一个DataTrigger,用于根据此属性的值切换DataTemplate。还要了解,命令通常在ViewModel级别工作,与视图层无关(或不了解视图层)。您的命令将简单地操作公共属性的值(如上所述),视图中的DataTriggers将相应地响应以加载适当的DataTemplate。因此,我将阅读一些关于数据触发器的内容,但我认为让我困惑的是实际上切换视图的内容。用户控件1是否将数据传递给主窗口viewModel,或者用户控件1视图模型是否实际将视图更改为用户控件2。我知道视图并不真正与viewModel交互,但两个用户控件都包含在主窗口中,因此我认为主窗口viewModel实际上应该切换窗口。
class YourViewModel : ViewModelBase
{
public string ActiveView
{
get { return _ApplicationMessage; }
//Note that this setter performs notification
set { Set(ref _ApplicationMessage, value); }
}
private RelayCommand<string> _SetViewCommand = null;
public RelayCommand<string> SetViewCommand
{
get
{
if (_SetViewCommand == null)
{
_SetViewCommand = new RelayCommand<string>((v) =>
{
ActiveView = v;
}
}
return _SetViewCommand;
}
}
}
<Button Content="Normal" Command="{Binding SetViewCommand}" CommandParameter="Normal" />
<Button Content="Edit" Command="{Binding SetViewCommand}" CommandParameter="Edit" />
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding ActiveView}" Value="Normal">
<Setter Property="Content">
<Setter.Value>
<UserControl1 />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ActiveView}" Value="Edit">
<Setter Property="Content">
<Setter.Value>
<UserControl2 />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>