[转]WPF/MVVM快速开始手册
I will quickly introduce some topics, then show an example that explains or demonstrates each point. Accordingly, I haven't really attempted to make the GUIs pretty, that's not the point of this article (see the bullet points above).
The Basics
- The most important thing about WPF is data binding. In short, you have some data, typically in a collection of some sort, and you want to display it to the user. You can 'bind' your XAML to the data.
- WPF has two parts, the XAML which describes your GUI layout and effects, and the code-behind that is tied to the XAML.
- The neatest and probably most reusable way to organise your code is to use the 'MVVM' pattern: Model, View, ViewModel. This has the aim of ensuring that your View contains minimal (or no) code, and should be XAML-only.
The Key Points You Need to Know
- The collection you should use to hold your data is the
ObservableCollection<>. Not alist, not adictionary, but anObservableCollection. The word 'Observable' is the clue here: the WPF window needs to be able to 'observe' your data collection. This collection class implements certain interfaces that WPF uses. - Every WPF control (including 'Window's) has a '
DataContext' andCollectioncontrols have an 'ItemsSource' attribute to bind to. - The interface '
INotifyPropertyChanged' will be used extensively to communicate any changes in the data between the GUI and your code.
Example 1: INotifyPropertyChanged
public class SongViewModel : INotifyPropertyChanged
{
#region Construction
/// Constructs the default instance of a SongViewModel
public SongViewModel()
{
_song = new Song { ArtistName = "Unknown", SongTitle = "Unknown" };
}
#endregion #region Members
Song _song;
#endregion #region Properties
public Song Song
{
get
{
return _song;
}
set
{
_song = value;
}
} public string ArtistName
{
get { return Song.ArtistName; }
set
{
if (Song.ArtistName != value)
{
Song.ArtistName = value;
RaisePropertyChanged("ArtistName");
}
}
}
#endregion #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; #endregion #region Methods private void RaisePropertyChanged(string propertyName)
{
// take a copy to prevent thread issues
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
There are several things now happening here. Firstly, we check to see if we are going to really change the property: this improves performance slightly for more complex objects. Secondly, if the value has changed, we raise the PropertyChanged event to any listeners.
So now we have a Model, and a ViewModel. We just need to define our View. This is just our MainWindow:
<Window x:Class="Example2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Example2"
Title="Example 2" SizeToContent="WidthAndHeight" ResizeMode="NoResize"
Height="350" Width="525">
<Window.DataContext>
<!-- Declaratively create an instance of our SongViewModel -->
<local:SongViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="Example 2 - this works!" />
<Label Grid.Column="0" Grid.Row="1" Content="Artist: " />
<Label Grid.Column="1" Grid.Row="1" Content="{Binding ArtistName}" />
<Button Grid.Column="1" Grid.Row="2" Name="ButtonUpdateArtist"
Content="Update Artist Name" Click="ButtonUpdateArtist_Click" />
</Grid>
</Window>
To test the databinding, we can take the traditional approach and create a button and wire to its OnClick event, so the XAML above has a button, and Click event, giving the code behind:
public partial class MainWindow : Window
{
#region Members
SongViewModel _viewModel;
int _count = ;
#endregion public MainWindow()
{
InitializeComponent(); // We have declared the view model instance declaratively in the xaml.
// Get the reference to it here, so we can use it in the button click event.
_viewModel = (SongViewModel)base.DataContext;
} private void ButtonUpdateArtist_Click(object sender, RoutedEventArgs e)
{
++_count;
_viewModel.ArtistName = string.Format("Elvis ({0})", _count);
}
}
Example 2: Commands
Binding to GUI events is problematic. WPF offers you a better way. This is ICommand. Many controls have a Command attribute. These obey binding in the same way as Content and ItemsSource, except you need to bind it to a *property* that returns an ICommand. For the trivial example that we are looking at here, we just implement a trivial class called 'RelayCommand' that implements ICommand.
ICommand requires the user to define two methods: bool CanExecute, and void Execute. The CanExecute method really just says to the user, can I execute this command? This is useful for controlling the context in which you can perform GUI actions. In our example, we don't care, so we return true, meaning that the framework can always call our 'Execute' method. It could be that you have a situation where you have a command bound to button, and it can only execute if you have selected an item in a list. You would implement that logic in the 'CanExecute' method.
Since we want to reuse the ICommand code, we use the RelayCommand class that contains all the repeatable code we do not want to keep writing.
To show how easy it is to reuse the ICommand, we bind the Update Artist command to both a button and a menu item. Notice that we no longer bind to Button specific Click event, or Menu specific Click event.
更多内容在本文转载出处:http://www.codeproject.com/Articles/165368/WPF-MVVM-Quick-Start-Tutorial
[转]WPF/MVVM快速开始手册的更多相关文章
- WPF/MVVM 快速开始指南(译)(转)
WPF/MVVM 快速开始指南(译) 本篇文章是Barry Lapthorn创作的,感觉写得很好,翻译一下,做个纪念.由于英文水平实在太烂,所以翻译有错或者译得不好的地方请多指正.另外由于原文是针对W ...
- WPF/MVVM Quick Start Tutorial - WPF/MVVM 快速入门教程 -原文,翻译及一点自己的补充
转载自 https://www.codeproject.com/articles/165368/wpf-mvvm-quick-start-tutorial WPF/MVVM Quick Start T ...
- WPF/MVVM 快速开发
http://www.codeproject.com/Articles/165368/WPF-MVVM-Quick-Start-Tutorial 这篇文章醍醐灌顶,入门良药啊! Introductio ...
- WPF/MVVM快速指引
简介 最近微软推出了UWA,又是一波新的C#+xaml学习热.好多小伙伴都对MVVM感觉很好奇,但是有些地方也有点难以理解.特意写了这边文章,希望对你有帮助. 这边文章会很长,所以我会用几个例子的形式 ...
- WPF MVVM UI分离之《交互与数据分离》 基础才是重中之重~delegate里的Invoke和BeginInvoke 将不确定变为确定系列~目录(“机器最能证明一切”) 爱上MVC3系列~全局异常处理与异常日志 基础才是重中之重~lock和monitor的区别 将不确定变成确定~我想监视我的对象,如果是某个值,就叫另一些方法自动运行 将不确定变成确定~LINQ DBML模型可以对
WPF MVVM UI分离之<交互与数据分离> 在我们使用WPF过程中,不可避免并且超级喜欢使用MVVM框架. 那么,使用MVVM的出发点是视觉与业务逻辑分离,即UI与数据分离 诸如下 ...
- WPF MVVM 验证
WPF MVVM(Caliburn.Micro) 数据验证 书接前文 前文中仅是WPF验证中的一种,我们暂且称之为View端的验证(因为其验证规是写在Xaml文件中的). 还有一种我们称之为Model ...
- Github快速入门手册
最近在试用Github,开源的思想也让人觉得把一些经验分享出来是非常好的事情.附件是doc文件,如有需要请注意查收.希望能对你有帮助. GITHUB基于互联网的版本控制快速入门手册 如有不妥,欢迎指正 ...
- WPF MVVM初体验
首先MVVM设计模式的结构, Views: 由Window/Page/UserControl等构成,通过DataBinding与ViewModels建立关联: ViewModels:由一组命令,可以绑 ...
- WPF MVVM实现TreeView
今天有点时间,做个小例子WPF MVVM 实现TreeView 只是一个思路大家可以自由扩展 文章最后给出了源码下载地址 图1 图2 模版加上了一个checkbox,选中父类的checkb ...
随机推荐
- web前端基础——补充
1 布局和事件 布局效果如下(标题和内容都居中,两边留空白) 布局代码如下 <!DOCTYPE html> <html lang="en"> <he ...
- TableView didSelectRowAtIndexPath 不执行
1.父类事件设置代理 UIGestureRecognizer *tapGesture ... tapGesture.delegate = self; 2.覆盖方法 - (BOOL)gestureRe ...
- C# 热敏打印机 Socket 网络链接 打印 图片
C# 热敏打印机 Socket 网络链接 打印 图片 (一) http://www.cnblogs.com/rinack/p/4838211.html C# 热敏打印机 Socket 网络链接 打印 ...
- Node.js的颠覆者:PHP的Swoole扩展
最近2年Node.js很火,异步与协程是网络开发方面热门的话题.在追求新技术的同时,也应该反思下这里面存在的陷阱.Node.js确实是一门有趣好玩有个性的语言和技术,动态性,全异步回调的方 ...
- 禁用iOS的UIView长按默认操作
* { -webkit-touch-callout: none; -webkit-user-select: none; -webkit-tap-highlight-color: rg ...
- RTL8710 ROM 符号表 函数,常量,变量
函数 Name Address Ordinal ---- ------- ------- __vectors_table Reset_Handler NMI_Handler HardFault_Han ...
- 如何获得WPA握手包&EWSA破解WPA密码教程[zz]
获得WPA\WPA2 握手包的方法有很多,下面介绍通过aircrack-ng工具包来载获握手数据包. 1.下载aircrack-ng工具包. 2.终端里输入 sudo airmon-ng start ...
- Win7下VS2010使用“ASP.Net 3.5 Claims-aware Template”创建ClaimsAwareWebSite报"HRESULT: 0x80041FEB"错误的解决办法
问题描述: 使用VS2010的WIF开发模板创建“Claims-aware ASP.NET Site”.“Claims-aware WCF Service”,下载安装后,创建网站时,报错"H ...
- (转)c#.net常用字符串函数
Compare 比较字符串的内容,考虑文化背景(场所),确定某些字符是否相等 CompareOrdinal 与Compare一样,但不考虑文化背景 Format 格式化包含各种值的字符串和如何格式化每 ...
- 使用React、Node.js、MongoDB、Socket.IO开发一个角色投票应用的学习过程(三)
这几篇都是我原来首发在 segmentfault 上的地址:https://segmentfault.com/a/1190000005040834 突然想起来我这个博客冷落了好多年了,也该更新一下,呵 ...