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. PipelineDB On Kafka

    PipelineDB 安装yum install https://s3-us-west-2.amazonaws.com/download.pipelinedb.com/pipelinedb-0.9.8 ...

  2. Lambda 表达式浅谈- 01

    已经有一段时间没有发布博文了... 今天就写一写lambda的一些简单的使用方法 Lambda 在Msdn 上的描述: Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数. 通过使用 ...

  3. Enabling Remote Errors in SSRS

    January 18, 2011 By default the remote errors property in SQL Server Reporting Services is set to fa ...

  4. leetcode 84. 柱状图中最大的矩形 JAVA

    题目: 给定 n 个非负整数,用来表示柱状图中各个柱子的高度.每个柱子彼此相邻,且宽度为 1 . 求在该柱状图中,能够勾勒出来的矩形的最大面积. 以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高 ...

  5. API接口文档范例

  6. CentOS运行C++语言的Hello World

    1,编写代码,hello.cpp #include <iostream> using namespace std; int main(){ cout<<"hello ...

  7. 【bash】今天你坑队友了吗

    需求: 压缩日志并删除压缩过的文件 很日常的运维需求!!! 好,来看代码 echo 'start' quke.log rm -f quke.log echo 'delete' 不管是初级运维还是高级运 ...

  8. httpclient4.5 https请求 忽略身份验证

    import org.apache.commons.collections.MapUtils; import org.apache.http.*; import org.apache.http.cli ...

  9. java使用Redis8--3.0集群

    Redis集群至少需要3个主节点 # cd /usr/redis 创建一个目录 # mkdir cluster # cd cluster 1.复制一个配置文件 # cp ../redis.conf 9 ...

  10. django基础2

    一. 使用原生sql,了解即可 使用原生sql的目的:解决一些复杂的sql不能用ORM方式写出的问题 有三种方式如下 1. extra: 结果集修改器,一种提供额外查询参数的机制 2. raw:执行原 ...