在WPF中实现MVVM模式的正确方法 [英] Proper way of implementing MVVM Pattern in WPF

查看:37
本文介绍了在WPF中实现MVVM模式的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始学习来自Java Swing和WinForms的WPF.我决定尝试一些新事物,以学习用于开发程序的其他概念和技术.上次,我对MVC模式的概念进行了介绍.据我了解,这是一种将UI逻辑,业务逻辑和数据分离的方法.我发现WPF的关键概念之一是绑定和MVVM模式.

I just started learning WPF coming from Java Swing and WinForms. I decided to try something new to learn other concepts and technologies for developing programs. Last time, I was introduced on the concept of MVC Pattern. For what I have learned, it is a way of separating the UI logic, business logic, and data. I found out that one of the key concepts of WPF is Binding and the MVVM Pattern.

这是我尝试实现MVVM的代码的一部分.

Here is a part of my code where i tried implementing MVVM.

MainWindowModel.cs

MainWindowModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows.Controls;

namespace DocNanzDCMS.Model
{
    public class MainWindowModel : INotifyPropertyChanged
    {
        private PropertyChangedEventArgs pce;

        public MainWindowModel()
        {
            pce = new PropertyChangedEventArgs("");
        }

        private UserControl userControl;
        #region ControlProperty
        public UserControl ContentProperty {
            get
            {
                return userControl;
            }

            set
            {
                userControl = value;
                PropertyChanged(this, pce);
            }
        }
        #endregion

        private DateTime dateTime;
        #region DateProperty
        public String DateProperty
        {
            get
            {
                return dateTime.ToLongDateString();
            }
            set
            {
                dateTime = DateTime.Parse(value);
                PropertyChanged(this, pce);
            }
        }
        #endregion

        public String TimeProperty
        #region TimeProperty
        {
            get
            {
                return dateTime.ToLongTimeString();
            }
            set
            {
                dateTime = DateTime.Parse(value);
                PropertyChanged(this, pce);
            }
        }
        #endregion

        private String title;
        public String TitleProperty
        #region TitleProperty
        {
            get
            {
                return title;
            }
            set
            {
                title = value;
                PropertyChanged(this, pce);
            }
        }
        #endregion

        public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { };
    }
}

MainWindowViewModel.cs

MainWindowViewModel.cs

using DocNanzDCMS.Model;
using DocNanzDCMS.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace DocNanzDCMS.ViewModel
{
    public class MainWindowViewModel
    {
        private MainWindow mainWindow;
        private MainWindowModel mainWindowModel;
        private Thread mainWindowThread;

        private LoginModel loginModel;
        private LoginViewModel loginViewModel;
        private LoginView loginView;

        private String title;

        public MainWindowViewModel(MainWindowModel mainWindowModel, MainWindow mainWindow)
        {
            this.mainWindowModel = mainWindowModel;
            this.mainWindow = mainWindow;
            initialize();
        }

        private void initialize()
        {
            loginModel = new LoginModel();
            loginView = new LoginView();
            loginViewModel = new LoginViewModel(loginModel, loginView);

            mainWindow.DataContext = mainWindowModel;
            mainWindowThread = new Thread(BackgroundProcess);
            mainWindowThread.IsBackground = true;
            mainWindowThread.Start();

            gotoLogin();
        }

        private void BackgroundProcess()
        {
            while(true)
            {
                updateTitle();
                updateTime();
                try
                {
                    Thread.Sleep(100);
                }
                catch(ThreadInterruptedException e)
                {
                }
            }
        }

        public void gotoLogin()
        {
            mainWindowModel.ContentProperty = loginView;
            title = "Login";
        }

        private void updateTime()
        {
            mainWindowModel.DateProperty = DateTime.Now.ToString();
            mainWindowModel.TimeProperty = DateTime.Now.ToString();
        }

        public void updateTitle()
        {
            mainWindowModel.TitleProperty = "Doc Nanz Dental | "+title;
        }
    }
}

MainWindow.cs

MainWindow.cs

using DocNanzDCMS.Model;
using DocNanzDCMS.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DocNanzDCMS
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private MainWindowModel mainWindowModel;
        private MainWindowViewModel mainWindowViewModel;

        public MainWindow()
        {
            InitializeComponent();
            initializeApp();
        }

        private void initializeApp()
        {
            mainWindowModel = new MainWindowModel();
            mainWindowViewModel = new MainWindowViewModel(mainWindowModel, this);
        }
    }
}

MainWindow.xaml

MainWindow.xaml

<Window x:Class="DocNanzDCMS.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DocNanzDCMS"
        mc:Ignorable="d"
        Title="{Binding TitleProperty}" Height="600" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="75"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>
        <!--Banner-->
        <Grid Grid.Row="0" Background="AliceBlue">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="225"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="200"/>
            </Grid.ColumnDefinitions>
            <!--Date and Time Panel-->
            <Grid Grid.Column="2" Background="Aquamarine">
                <Grid.RowDefinitions>
                    <RowDefinition Height="1.5*"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <!--Date Background-->
                <StackPanel Grid.Row="0" Background="BurlyWood"/>
                <!--Date-->
                <Label Grid.Row="0" Content="{Binding DateProperty}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                <!--Time Background-->
                <StackPanel Grid.Row="1" Background="BlanchedAlmond"/>
                <!--Time-->
                <Label Grid.Row="1" Content="{Binding TimeProperty}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Grid>
        </Grid>
        <!--Content-->
        <ScrollViewer Grid.Row="1" Content="{Binding ContentProperty}"/>
        <!--Status Bar-->
        <Grid Grid.Row="2">

        </Grid>
    </Grid>
</Window>

我创建了一个模型和视图,并在ViewModel中对其进行了操作.我不确定这是实现MVVM的正确方法还是什至是MVVM,因为我将其视为MVC模式.

I created a Model and View and manipulated those in ViewModel. I am not sure if this is a proper way of implementing MVVM or is it even an MVVM, because I am seeing it as MVC pattern.

在Wikipedia上说:

On Wikipedia, it says:

这些组件分别是Model,View,ViewModel和Binder.

The components are, Model, View, ViewModel, and Binder.

我的代码的这一部分显示带有标语的窗口,标语的最右边是显示日期和时间的标签.它可以工作,但是我担心的是,我的制作方法是否实际上遵循了MVVM模式.

This part of my code displays a window with a banner, and on rightmost part of the banner are labels that displays date and time. It works, but my concern is if the way I made it is actually following MVVM pattern.

推荐答案

您的问题非常广泛,但是这里有一些想法.

Your question is very broad but here are some thoughts.

视图模型应该对视图一无所知.而不是通过引用 MainWindow 注入 MainWindowViewModel ,您只需将 MainWindow DataContext 设置为视图模型的实例:

A view model shouldn't know anything about the view. Instead of injecting the MainWindowViewModel with a reference to the MainWindow, you should simply set the DataContext of the MainWindow to an instance of the view model:

public MainWindow()
{
        InitializeComponent();
        DataContext = new MainWindowViewModel();
}

当视图绑定到视图模型时, MainWindowViewModel 然后可以初始化模型和/或与模型通信.

The MainWindowViewModel can then initialize and/or communicate with the model while the view binds to the view model.

此外,视图模型不应公开任何 UIElements ,例如 UserControl . UIElements 在视图中定义.

Also, a view model shouldn't expose any UIElements such as for example a UserControl. UIElements are defined in the view.

这篇关于在WPF中实现MVVM模式的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆