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接口,代码如下:

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace MVVMTest.ViewModels
{
public class NotificationObject:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged; public void RaisePropertyChanged(string property)
{
if (this.PropertyChanged != null)
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(property)); }
}
}

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

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input; namespace MVVMTest.Commands
{
public class DelegateCommand:ICommand
{
public bool CanExecute(object parameter)
{
if (this.CanExecuteFunc == null)
{
return true;
} return this.CanExecuteFunc(parameter);
} public event EventHandler CanExecuteChanged; public void Execute(object parameter)
{
if (this.ExecuteAction == null)
{
return;
}
this.ExecuteAction(parameter);
} public Action<object> ExecuteAction { get; set; }
public Func<object, bool> CanExecuteFunc { get; set; }
}
}

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

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

 <?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>propn</Title>
<Shortcut>propn</Shortcut>
<Description>Code snippet for NotificationObject property and backing field</Description>
<Author>Microsoft Corporation</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>type</ID>
<ToolTip>Property type</ToolTip>
<Default>int</Default>
</Literal>
<Literal>
<ID>property</ID>
<ToolTip>Property name</ToolTip>
<Default>MyProperty</Default>
</Literal>
<Literal>
<ID>field</ID>
<ToolTip>The variable backing this property</ToolTip>
<Default>myVar</Default>
</Literal>
</Declarations>
<Code Language="csharp"><![CDATA[private $type$ $field$; public $type$ $property$
{
get { return $field$;}
set {
$field$ = value;
this.RaisePropertyChanged("$property$");
}
}
$end$]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

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

 using MVVMTest.Commands;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace MVVMTest.ViewModels
{
public class MainWindowViewModel:NotificationObject
{
private string txt1; public string Txt1
{
get { return txt1; }
set
{
txt1 = value;
this.RaisePropertyChanged("Txt1");
}
} private string txt2; public string Txt2
{
get { return txt2; }
set
{
txt2 = value;
this.RaisePropertyChanged("Txt2");
}
} private string result; public string Result
{
get { return result; }
set
{
result = value;
this.RaisePropertyChanged("Result");
}
} public DelegateCommand ConcatCommand { get; set; }
public void Concat(object parameter)
{
Result = Txt1 + " and " + Txt2;
} public MainWindowViewModel()
{
ConcatCommand = new DelegateCommand();
ConcatCommand.ExecuteAction = new Action<object>(Concat);
} }
}

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

 using MVVMTest.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 MVVMTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainWindowViewModel();
}
}
}

3.5.在View中绑定数据:

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

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

WPF简单MVVM实现的更多相关文章

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

    从0到1:使用Caliburn.Micro(WPF和MVVM)开发简单的计算器 之前时间一直在使用Caliburn.Micro这种应用了MVVM模式的WPF框架做开发,是时候总结一下了. Calibu ...

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

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. .NET CORE(C#) WPF简单菜单MVVM绑定 阅读导航 本文背景 代码实现 本文参考 ...

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

    今天主要记录的就是发送QQ表情, WPF 微信 MVVM里写了,后期为了发送QQ表情,需要把TextBox替换为RichTextBox,接下来就说说替换的过程. 一.支持Binding的RichTex ...

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

    CleanAOP实战系列--WPF中MVVM自动更新 作者: 立地 邮箱: jarvin_g@126.com QQ: 511363759 CleanAOP介绍:https://github.com/J ...

  5. WPF Prism MVVM 中 弹出新窗体. 放入用户控件

    原文:WPF Prism MVVM 中 弹出新窗体. 放入用户控件 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_37214567/artic ...

  6. WPF之MVVM模式(3)

    有种想写一个MVVM框架的冲动!!! 1.Model中的属性应不应该支持OnPropertyChanged事件? 不应该.应该有ViewModel对该属性进行封装,由ViewModel提供OnProp ...

  7. 【WPF】MVVM模式的3种command

    原文:[WPF]MVVM模式的3种command 1.DelegateCommand 2.RelayCommand 3.AttachbehaviorCommand 因为MVVM模式适合于WPF和SL, ...

  8. WPF和MVVM的结合使用方法,不可错过

    Model:存储数据模型(类) 也在此业务逻辑,主要负责类文件的存储. ViewModel:连接View和Model,借助Command来负责界面的跳转和调用Model中方法来操作Model的数据. ...

  9. WPF使用MVVM(一)-属性绑定

    WPF使用MVVM(一)-属性绑定 简单介绍MVVM MVVM是Model(数据类型),View(界面),ViewModel(数据与界面之间的桥梁)的缩写,是一种编程模式,优点一劳永逸,初步增加一些逻 ...

随机推荐

  1. lambda distinct

    public ActionResult Index() { IList<RegisterModel> regList = new List<RegisterModel>() { ...

  2. ASP.NET Core2实现静默获取微信公众号的用户OpenId

    最近在做个微信公众号的项目,需要将入口放置在公众号二级菜单内,通过点击该菜单链接后进入到该项目中去,进入到项目后程序会自动通过微信公众号的API完成用户的OpenId获取.需求很简单,实现起来也不复杂 ...

  3. c#格式化字符

    1.格式化货币(跟系统的环境有关,中文系统默认格式化人民币,英文系统格式化美元) string.Format("{0:C}",0.2) 结果为:¥0.20 (英文操作系统结果:$0 ...

  4. Xshell传输文件

    用rz,sz命令在xshell传输文件 很好用,然后有时候想在windows和linux上传或下载某个文件,其实有个很简单的方法就是rz,sz 首先你的Ubuntu需要安装rz.sz(如果没有安装请执 ...

  5. Tempdb--Row version

    Trigger:在SQL SERVER 2005之前,触发器需要使用日志来获取DELETED AND INSERTED的数据,因此会打乱日志顺序写的模式,造成磁盘压力,在SQL Server2005 ...

  6. Rest-assured 写日志到 log4j

    背景: 采用Rest-assured,日志采用log4j,发现Rest-assured本身只支持打印日志到控制台,但期望打印到文件中以便排查问题 请求打印的语句只能输出到控制台 given().log ...

  7. [ruby]rubyGem出现ERROR: Could not find a valid gem时的处理方法

    场景: 想安装SASS的时候,打开cmd,输入gem install sass的时候却出现了: ERROR:  Could not find a valid gem 'sass' (>= 0), ...

  8. driver.get()和driver.navigate().to()到底有什么不同?-----Selenium快速入门(四)

    大家都知道,这两个方法都是跳转到指定的url地址,那么这两个方法有什么不同呢?遇到这种情况,第一反应就是查查官方的文档. 官方文档的说法是:Load a new web page in the cur ...

  9. c# in out ref关键字

    class in_out_ref { #region in 关键字 delegate void DContravariant<in A>(A argumen); static void o ...

  10. UWP开发入门(十)——通过继承来扩展ListView

    本篇之所以起这样一个名字,是因为重点并非如何自定义控件,不涉及创建CustomControl和UserControl使用的Template和XAML概念.而是通过继承的方法来扩展一个现有的类,在继承的 ...