问题描述
我刚刚开始学习来自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模式的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!