WPF简单MVVM实现

1. MVVM介绍:

MVVM就是: Model -- 模型(现实中对象的抽象)

View -- UI(用户界面)

       ViewModel -- UI界面的抽象(给View提供数据,并响应View的操作)

2. 关键是要能准确的进行ViewModel的建模,处理好View与ViewModel之间的关系

2.1. 只有2种关系:

数据传递 --- 双向,使用Binding实现;

操作传递 --- 单向(只从View传递给ViewModel),使用命令Command实现;

3. 开始

3.1. 首先创建NotificationObject,它是所以ViewModel的基类

因为要使用Binding,而ViewModel就充当数据源的角色,而要实现当值有变化时会自动响应,就必须实现INotifyPropertyChanged接口,代码如下:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7
 8 namespace MVVMTest.ViewModels
 9 {
10     public class NotificationObject:INotifyPropertyChanged
11     {
12         public event PropertyChangedEventHandler PropertyChanged;
13
14         public void RaisePropertyChanged(string property)
15         {
16             if (this.PropertyChanged != null)
17                 this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(property));
18
19         }
20     }
21 }

3.2.接着要创建DelegateCommand,实现了ICommand接口,用来处理View发送到ViewModel的命令,代码如下:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Windows.Input;
 7
 8 namespace MVVMTest.Commands
 9 {
10     public class DelegateCommand:ICommand
11     {
12         public bool CanExecute(object parameter)
13         {
14             if (this.CanExecuteFunc == null)
15             {
16                 return true;
17             }
18
19              return this.CanExecuteFunc(parameter);
20         }
21
22         public event EventHandler CanExecuteChanged;
23
24         public void Execute(object parameter)
25         {
26             if (this.ExecuteAction == null)
27             {
28                 return;
29             }
30             this.ExecuteAction(parameter);
31         }
32
33         public Action<object> ExecuteAction { get; set; }
34         public Func<object, bool> CanExecuteFunc { get; set; }
35     }
36 }

3.3.为了方便开发,这里推荐自定义一个code snippet(代码块):

放到此目录下C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC#\Snippets\1033\Visual C#

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
 3     <CodeSnippet Format="1.0.0">
 4         <Header>
 5             <Title>propn</Title>
 6             <Shortcut>propn</Shortcut>
 7             <Description>Code snippet for NotificationObject property and backing field</Description>
 8             <Author>Microsoft Corporation</Author>
 9             <SnippetTypes>
10                 <SnippetType>Expansion</SnippetType>
11             </SnippetTypes>
12         </Header>
13         <Snippet>
14             <Declarations>
15                 <Literal>
16                     <ID>type</ID>
17                     <ToolTip>Property type</ToolTip>
18                     <Default>int</Default>
19                 </Literal>
20                 <Literal>
21                     <ID>property</ID>
22                     <ToolTip>Property name</ToolTip>
23                     <Default>MyProperty</Default>
24                 </Literal>
25                 <Literal>
26                     <ID>field</ID>
27                     <ToolTip>The variable backing this property</ToolTip>
28                     <Default>myVar</Default>
29                 </Literal>
30             </Declarations>
31             <Code Language="csharp"><![CDATA[private $type$ $field$;
32
33     public $type$ $property$
34     {
35         get { return $field$;}
36         set {
37             $field$ = value;
38             this.RaisePropertyChanged("$property$");
39         }
40     }
41     $end$]]>
42             </Code>
43         </Snippet>
44     </CodeSnippet>
45 </CodeSnippets>

3.4. 由于这个例子较简单,所以没有设计到Model的设计,而直接到ViewModel的设计,一般的规则是每个View就有一个对应的ViewModel,而ViewModel是充当View的数据源的,所以只需要考虑View需要什么数据、含有哪些操作,创建MainWindow的ViewModel,MainWindowViewModel,代码如下:

 1 using MVVMTest.Commands;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7
 8 namespace MVVMTest.ViewModels
 9 {
10     public class MainWindowViewModel:NotificationObject
11     {
12         private string txt1;
13
14         public string Txt1
15         {
16             get { return txt1; }
17             set
18             {
19                 txt1 = value;
20                 this.RaisePropertyChanged("Txt1");
21             }
22         }
23
24         private string txt2;
25
26         public string Txt2
27         {
28             get { return txt2; }
29             set
30             {
31                 txt2 = value;
32                 this.RaisePropertyChanged("Txt2");
33             }
34         }
35
36         private string result;
37
38         public string Result
39         {
40             get { return result; }
41             set
42             {
43                 result = value;
44                 this.RaisePropertyChanged("Result");
45             }
46         }
47
48         public DelegateCommand ConcatCommand { get; set; }
49         public void Concat(object parameter)
50         {
51             Result = Txt1 + " and " + Txt2;
52         }
53
54
55         public MainWindowViewModel()
56         {
57             ConcatCommand = new DelegateCommand();
58             ConcatCommand.ExecuteAction = new Action<object>(Concat);
59         }
60
61
62
63     }
64 }

3.4.将ViewModel作为数据源赋值给View的DataContext

 1 using MVVMTest.ViewModels;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 using System.Windows;
 8 using System.Windows.Controls;
 9 using System.Windows.Data;
10 using System.Windows.Documents;
11 using System.Windows.Input;
12 using System.Windows.Media;
13 using System.Windows.Media.Imaging;
14 using System.Windows.Navigation;
15 using System.Windows.Shapes;
16
17 namespace MVVMTest
18 {
19     /// <summary>
20     /// Interaction logic for MainWindow.xaml
21     /// </summary>
22     public partial class MainWindow : Window
23     {
24         public MainWindow()
25         {
26             InitializeComponent();
27             this.DataContext = new MainWindowViewModel();
28         }
29     }
30 }

3.5.在View中绑定数据:

 1 <Window x:Class="MVVMTest.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525">
 5     <Grid>
 6         <TextBox Margin="40,51,311,216" Text="{Binding Txt1}"/>
 7         <TextBox Margin="230,51,114,216" Text="{Binding Txt2}"/>
 8         <TextBox Margin="128,152,176,139" Text="{Binding Result}"/>
 9         <Button Margin="313,241,64,23" Command="{Binding ConcatCommand}"/>
10     </Grid>
11 </Window>

源代码:http://yunpan.cn/c3c7AAXm4U2dP  访问密码 8788

时间: 2024-10-14 05:19:38

WPF简单MVVM实现的相关文章

从0到1:使用Caliburn.Micro(WPF和MVVM)开发简单的计算器

从0到1:使用Caliburn.Micro(WPF和MVVM)开发简单的计算器 之前时间一直在使用Caliburn.Micro这种应用了MVVM模式的WPF框架做开发,是时候总结一下了. Caliburn.Micro(Caliburn.Micro框架概述 - https://blog.csdn.net/lzuacm/article/details/78886436) 是一个轻量级的WPF框架,简化了WPF中的不少用法,推荐做WPF开发时优先使用. 真正快速而熟练地掌握一门技术就可以尝试着用最快的

.NET CORE(C#) WPF简单菜单MVVM绑定

原文:.NET CORE(C#) WPF简单菜单MVVM绑定 微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. .NET CORE(C#) WPF简单菜单MVVM绑定 阅读导航 本文背景 代码实现 本文参考 源码 1. 本文背景 WPF中垂直导航菜单大家应该都常用,本文介绍使用MVVM的方式怎么绑定菜单,真的很简单. 2. 代码实现 使用 .Net Core 3.1 创建名为 "MenuMVVM" 的WPF模板项目,添加两个Nug

WPF之MVVM(Step4)&mdash;&mdash;使用Prism(2)

上一篇简单介绍使用Prism中的NotificationObject,以及DelegateCommand.这一篇更是简单,仅仅描述下DelegateCommand<T>如何使用. ICommand接口一开始提供的就是带参数的方法,而我们使用时经常会遇到那个参数毫无用处的情况,Prism也就帮了偶们一把啦.当然,Prism并没有忘记我们有时还是要参数滴.   在定义上,我们使用ICommand定义,DelegateCommand和DelegateCommand<T>一样.在实例化时有

WPF 微信 MVVM 【续】发送部分QQ表情

今天主要记录的就是发送QQ表情, WPF 微信 MVVM里写了,后期为了发送QQ表情,需要把TextBox替换为RichTextBox,接下来就说说替换的过程. 一.支持Binding的RichTextBox RichTextBox虽然支持文字,图片,链接,但是,原生的它不支持Binding,这个对于MVVM是很不方便的,因此,需要给RichTextBox设置一个依赖属性Document,来让它支持绑定,这样才能继续下一步. public class BindableRichTextBox :

浅析WPF中MVVM模式下命令与委托的关系

??各位朋友大家好,我是Payne,欢迎大家关注我的博客,我的博客地址是http://qinyuanpei.com.最近因为项目上的原因开始接触WPF,或许这样一个在现在来讲显得过时的东西,我猜大家不会有兴趣去了解,可是你不会明白对某些保守的项目来讲,安全性比先进性更为重要,所以当你发现银行这类机构还在使用各种"复古"的软件系统的时候,你应该相信这类东西的确有它们存在的意义.与此同时,你会更加深刻地明白一个道理:技术是否先进性和其流行程度本身并无直接联系.由此我们可以推论出:一项不流行

CleanAOP实战系列--WPF中MVVM自动更新

CleanAOP实战系列--WPF中MVVM自动更新 作者: 立地 邮箱: [email protected] QQ: 511363759 CleanAOP介绍:https://github.com/Jarvin-Guan/CleanAOP 前言 讲起WPF,开发模式MVVM是必不可少的,使用MVVM模式以后可以在View中写界面,需要使用到的数据则使用绑定的方式写到标签中,那么控制权就放到了ViewModel中,那么有一个需求是每一个使用MVVM者都会有的,就是在后台改变ViewModel的属

WPF之MVVM模式(3)

有种想写一个MVVM框架的冲动!!! 1.Model中的属性应不应该支持OnPropertyChanged事件? 不应该.应该有ViewModel对该属性进行封装,由ViewModel提供OnPropertyChanged事件.WPF之MVVM(1)中有实例 2.如何将控件事件转换为命令? 在“扩展”中添加“System.Windows.Interractivity”引用 xaml中添加xmlns:i="http://schemas.microsoft.com/expression/2010/i

【WPF】MVVM模式的3种command

原文:[WPF]MVVM模式的3种command 1.DelegateCommand 2.RelayCommand 3.AttachbehaviorCommand 因为MVVM模式适合于WPF和SL,所以这3种模式中也有一些小差异,比如RelayCommand下面的CommandManager方法就是WPF下面的,SL下面无法使用,不过我认为这3种方法中的基本思路都如出一辙,都是出自那位外国牛人的文章里面.主要的区别在于和VIEW中的控件的绑定使用上.有点不同的attachbehaviorcom

WPF之MVVM(Step2)&mdash;&mdash;自己实现DelegateCommand:ICommand

在自己实现MVVM时,上一篇的实现方式基本是不用,因其对于命令的处理不够方便,没写一个命令都需要另加一个Command的类.此篇主要介绍DelegateCommand来解决上面所遇到的问题. 首先,我们创建自己的DelegateCommand. 代码如下: /// <summary> /// 实现DelegateCommand /// </summary> class MyDelegateCommand : ICommand { /// <summary> /// 命令