简体   繁体   English

将一个 Model 连接到 MVVM WPF 中的多个 ViewModel

[英]Connecting One Model to Multiple ViewModels in MVVM WPF

I am trying to accomplish a navigation bar and a content screen in.NetFramework WPF application.我正在尝试在.NetFramework WPF 应用程序中完成导航栏和内容屏幕。 My goal is to implement MVVM pattern.我的目标是实现 MVVM 模式。 The main objective is when I hit Users button in navigation bar, I want my Body page to render "Users" text.主要目标是当我点击导航栏中的用户按钮时,我希望我的正文页面呈现“用户”文本。 And when I press Actions button, body page must render "Actions" text.当我按下动作按钮时,正文页面必须呈现“动作”文本。 Navigation buttons are "Users" and "Actions".导航按钮是“用户”和“操作”。 I have 3 View pages that are OperationPage, Navbar and Body.我有 3 个视图页面,它们是 OperationPage、Navbar 和 Body。 OperationPage is using Navbar and Body XAML to create view. OperationPage 正在使用 Navbar 和 Body XAML 创建视图。 The grid code is as following:网格代码如下:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="20*" />
        <RowDefinition Height="80*" />
    </Grid.RowDefinitions>
    <Grid Grid.Row="0">
        <local:Navbar/>
    </Grid>
    <Grid Grid.Row="1">
        <local:Body/>
    </Grid>
</Grid>

Navbar grid is as follows:导航栏网格如下:

<UserControl.DataContext>
    <vm:NavbarViewModel/>
</UserControl.DataContext>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="50*" />
        <RowDefinition Height="25*" />
        <RowDefinition Height="25*"/>
    </Grid.RowDefinitions>
    <Grid Grid.Row="0">
        <TextBlock Text="{Binding Path=CurrentPage}" FontSize="30"/>
    </Grid>
    <Grid Grid.Row="1">
        <Button Content="Users" Width="75"/>
    </Grid>
    <Grid Grid.Row="2">
        <Button Content="Actions" Width="75"/>
    </Grid>
</Grid>

And Finally Body grid is as following:最后身体网格如下:

<Grid>
    <TextBlock Text="{Binding Path=CurrentPage}" FontSize="30"></TextBlock>
</Grid>

I have created a ViewModel classes for both Navigation and Body that implements INotifyPropertyChanged.我为实现 INotifyPropertyChanged 的 Navigation 和 Body 创建了一个 ViewModel 类。 I can change the text from these classes.我可以更改这些类的文本。 One of them is as following for navigation bar.其中之一是如下导航栏。

    class NavbarViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyChange(string changedVar) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(changedVar));

    private string _currentPage = "Navbar Data";
    public string CurrentPage
    {
        get { return _currentPage; }
        set
        {
            _currentPage = value;
            NotifyChange("CurrentPage");
        }
    }


}

But I am stuck with connecting these two classes to a Singleton ViewState class.但我坚持将这两个类连接到 Singleton ViewState class。 Should I again implement two-way binding with INotifyPropertyChanged to my model class or Should I follow another way?我应该再次使用 INotifyPropertyChanged 实现双向绑定到我的 model class 还是应该遵循另一种方式? I tried implementing the INotifyPropertyChanged class again in my Model class but I could'not find a way to create connection between the ViewModel class and model. I tried implementing the INotifyPropertyChanged class again in my Model class but I could'not find a way to create connection between the ViewModel class and model.

You might solve this in a couple of ways .您可以通过几种方式解决这个问题。 The first way is to strongly-couple your ViewModels, like this.第一种方法是像这样强耦合 ViewModel。

OperationPage View操作页面视图

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="20*" />
            <RowDefinition Height="80*" />
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <local:Navbar DataContext="{Binding NavbarViewModel}"/>
        </Grid>
        <Grid Grid.Row="1">
            <local:Body DataContext="{Binding BodyViewModel}"/>
        </Grid>
    </Grid>

Then implements the OperationPageViewModel .然后实现OperationPageViewModel This ViewModel should implement the INotifyPropertyChanged interface and it must have the 2 properties named NavbarViewModel and BodyViewModel of types NavbarViewModel and BodyViewModel respectively.此 ViewModel 应实现 INotifyPropertyChanged 接口,并且它必须具有分别名为NavbarViewModelBodyViewModel类型的NavbarViewModelBodyViewModel的 2 个属性。

You might need to add to NavbarViewModel 2 events binded to Users' button clicked and Groups' button clicked in order to expose them outside and OperationPageViewModel should monitor those events (it has the instance of NavbarViewModel) then for example set CurrentPage property of BodyViewModel accordingly on user's button click.您可能需要添加绑定到单击用户按钮和单击组按钮NavbarViewModel 2 事件,以便将它们暴露在外部,并且OperationPageViewModel应该监视这些事件(它具有 NavbarViewModel 的实例)然后例如相应地设置BodyViewModelCurrentPage属性用户的按钮单击。

Another solution might be to decouple ViewModels.另一种解决方案可能是解耦 ViewModel。

This solution get you better code maintenance and also let you code less than the first solution.这个解决方案可以让你更好地维护代码,也让你的代码比第一个解决方案少。

You need to use Message Broker design pattern https://en.wikipedia.org/wiki/Message_broker you can implement your own Message Broker or simply use one of any MVVM Toolkit libraries that already implement it.您需要使用 Message Broker 设计模式https://en.wikipedia.org/wiki/Message_broker您可以实现自己的 Message Broker 或简单地使用已经实现它的任何 MVVM Toolkit 库之一。 Most of the existing MVVM Toolkits have their own Message Broker implementation.大多数现有的 MVVM 工具包都有自己的 Message Broker 实现。 So no need to re-invent the whell.所以没有必要重新发明。

For example, the MVVM Light Toolkit Message Broker is explained here: https://docs.microsoft.com/en-us/archive/msdn-magazine/2014/june/mvvm-the-mvvm-light-messenger-in-depth#using-messages例如,这里解释了MVVM Light Toolkit Message Broker: https://docs.microsoft.com/en-us/archive/msdn-magazine/2014/june/mvvm-the-mvvm-light-messenger-in-depth #使用消息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM