[转]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 ...
随机推荐
- c#之第二课
输出语句: /////////////////////////////// public class Hello1 { public static void Main() { System.Conso ...
- C#中服务端接受前端JSON字符串转换成字典集合
我们是否可以把从前端接受的JSON字符串转换成字典集合呢? 比如从前端接收:{'size':'10', 'weight':'10kg'} 在服务端转换成:[{size:"10"}, ...
- 如何实现在H5里调起高德地图APP?(上)
这一篇文章,将讲述如何在H5里调起高德地图APP,并展示兴趣点.适合于展示某个餐馆,商场等,让用户自行选择前往方式. 场景一.在高德地图上展示Marker点或者POI标记 在一些基于位置分享的应用开发 ...
- 田渊栋:AlphaGo系统即使在单机上也有职业水平
Facebook人工智能组研究员田渊栋博士在知乎专栏上更新了一篇文章,详细分析了AlphaGo在<自然>杂志上发表的论文,他认为AlphaGo整个系统即使在单机上也已具有了职业水平,与李世 ...
- Angular学习笔记--last_update 20151106
参考来源:http://www.angularjs.cn/tag/AngularJS?p=1&s=50 基本要求:一周搞定33篇学习文章 目标:develop/refactor lms系统an ...
- Linux内核同步方法
1.原子操作,是其它同步方法的基础. 2.自旋锁,线程试图获取一个已经被别人持有的自旋锁,当前线程处于忙等待,占用cpu资源. 3.读写自旋锁,根据通用性和针对性的特点,普通自旋锁在特定场景下的表现会 ...
- mysql 日期对比,varchar类型装换为datetime类型
select * from tb_gps WHERE str_to_date(intime,'%Y-%m-%d %H:%i:%s') BETWEEN '2013-9-2 14:40:33' and ' ...
- 不停止MySQL服务增加从库的两种方式
不停止MySQL服务增加从库的两种方式 转载自:http://lizhenliang.blog.51cto.com/7876557/1669829 现在生产环境MySQL数据库是一主一从,由于业务量访 ...
- Quartz.Net 作业调度后台管理系统,基于Extjs
Quartz.Net是一个开源的.非常灵活的作业调度框架,具体使用方法和教程:http://www.cnblogs.com/shanyou/archive/2007/08/25/quartznettu ...
- OpenCV 2.4.8组件结构全解析
转自: http://blog.csdn.net/huang9012/article/details/21811271 之前啃了不少OpenCV的官方文档,发现如果了解了一些OpenCV整体的模块架构 ...