WPF自学入门(十二)WPF MVVM模式提取函数
我们平时在写代码时为了不重复写代码,会进行复制代码或者写通用方法。今天我们就来把上传做的函数提取成为通用的方法调用。把上次写的函数提取为两个主要的文件:ObserableObject和RelayCommand。步骤如下:
新建Mvvm项目,将实例三中的文件复制到Mvvm项目中即可。新建ObserableObject类文件,代码如下:
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq.Expressions;
/***********************作者:黄昏前黎明后**********************************
* 作者:黄昏前黎明后
* CLR版本:4.0.30319.42000
* 创建时间:2018-04-15 22:09:56
* 命名空间:Mvvm
* 唯一标识:b9043d4c-fdd7-4e0f-a324-00f0f09286d0
* 机器名称:HLPC
* 联系人邮箱:hl@cn-bi.com
*
* 描述说明:
*
* 修改历史:
*
*
*****************************************************************/
namespace Mvvm
{
[Serializable]
public abstract class ObservableObject : INotifyPropertyChanged
{
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, e);
}
}
protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpresssion)
{
var propertyName = PropertySupport.ExtractPropertyName(propertyExpresssion);
this.RaisePropertyChanged(propertyName);
}
protected void RaisePropertyChanged(String propertyName)
{
VerifyPropertyName(propertyName);
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyPropertyName(String propertyName)
{
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
{
Debug.Fail("无效属性名: " + propertyName);
}
}
}
}
前面我们都是使用单个的用户名,接下来我们尝试使用多个用户名。按照我们一开始所说的,我们需要一个ObservableCollection的集合。所以我们需要新增一个ViewModel名称NamesViewModel:
using Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows.Input;
/****************************************************************
* 作者:黄昏前黎明后
* CLR版本:4.0.30319.42000
* 创建时间:2018-04-15 22:32:29
* 命名空间:Example4.ViewModel
* 唯一标识:d500d890-7083-4f05-a82a-45f27eaa26d9
* 机器名称:HLPC
* 联系人邮箱:hl@cn-bi.com
*
* 描述说明:
*
* 修改历史:
*
*
*****************************************************************/
namespace Example4
{
public class NamesViewModel
{
#region 字段
ObservableCollection<NameViewModel> _names = new ObservableCollection<NameViewModel>();
#endregion
#region 属性
public ObservableCollection<NameViewModel> names
{
get { return _names; }
set { _names = value; }
}
#endregion
public NamesViewModel()
{
_names.Add(new NameViewModel() { UserName = "hl", CompanyName = "中软易通" });
_names.Add(new NameViewModel() { UserName = "lq", CompanyName = "中软" });
_names.Add(new NameViewModel() { UserName = "tp", CompanyName = "软易通" });
}
#region 命令
void AddNameExecute()
{
_names.Add(new NameViewModel { UserName = "黄昏前黎明后", CompanyName = "中软易通科技" });
}
bool CanAddNameExecute()
{
return true;
}
void UpdateNameExecute(NameViewModel name)
{
if (name == null) return;
name.CompanyName= "无";
}
bool CanUpdateNameExecute(NameViewModel name)
{
return true;
}
public ICommand AddName { get { return new RelayCommand(AddNameExecute, CanAddNameExecute); } }
public ICommand UpdateName { get { return new RelayCommand<NameViewModel>(new Action<NameViewModel>(UpdateNameExecute), new Predicate<NameViewModel>(CanUpdateNameExecute)); } }
#endregion
}
}
我们实现了两个命令,一个是新增用户,一个是把所有集合里的公司名更改为无。然后我们把这个ViewModel绑定到界面上:
<Window x:Class="Example4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Example4"
Title="Example4" Height="147.806" Width="407.044" ResizeMode="NoResize">
<Window.DataContext>
<!--声明创建一个NamesViewModel的实例-->
<local:NamesViewModel></local:NamesViewModel>
</Window.DataContext>
<StackPanel Orientation="Horizontal">
<ListView ItemsSource="{Binding names}" Width="" Name="lv">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding UserName}" />
<Label Content="{Binding CompanyName}" FontSize="" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackPanel>
<Button Content="新增用户" Height="" Margin="" Command="{Binding AddName}"/>
<Button Content="更新选中用户" Height="" Margin="" Command="{Binding UpdateName}" CommandParameter="{Binding ElementName=lv,Path=SelectedItem}"/>
</StackPanel>
</StackPanel>
</Window>
本文程序demo下载地址:链接:https://pan.baidu.com/s/12EEoVVVRbI5EiRNusSz1zg 密码:hbwb
结束语:WPF自学入门系列中对WPF的一些基本概念做了一些演示,但是还是有一些缺失,只是希望能对初学者起到一定的帮助。
最后,感谢你能看到最后。从下周开始学习Component One控件使用。
WPF自学入门(十二)WPF MVVM模式提取函数的更多相关文章
- WPF自学入门(二)WPF-XAML布局控件
上一篇介绍了xaml基本知识,我们已经知道了WPF简单的语法.那么接下来,我们要认识一下WPF的布局容器.布局容器可以使控件按照分类显示,我们一起来看看WPF里面可以使用哪些布局容器用来布局. 在WP ...
- WPF自学入门(六)WPF带标题的内容控件简单介绍
在WPF自学入门(二)WPF-XAML布局控件的文章中分别介绍StackPanel,WarpPanel,DockPanel,Grid,Canvas五种布局容器的使用,可以让我们大致了解容器可以使用在什 ...
- WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍
WPF自学入门(十一)WPF MVVM模式Command命令 在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式 ...
- WPF自学入门(十一)WPF MVVM模式Command命令
在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式.正如上一篇文章中在开始说的,MVVM的目的是为了最大限度地降低了 ...
- WPF自学入门(三)WPF路由事件之内置路由事件
有没有想过在.NET中已经有了事件机制,为什么在WPF中不直接使用.NET事件要加入路由事件来取代事件呢?最直观的原因就是典型的WPF应用程序使用很多元素关联和组合起来,是否还记得在WPF自学入门(一 ...
- Java设计模式(十二) 策略模式
原创文章,同步发自作者个人博客,http://www.jasongj.com/design_pattern/strategy/ 策略模式介绍 策略模式定义 策略模式(Strategy Pattern) ...
- 设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型)
设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就 ...
- Java 设计模式系列(十二)策略模式(Strategy)
Java 设计模式系列(十二)策略模式(Strategy) 策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以 ...
- 设计模式 ( 十二 ) 职责链模式(Chain of Responsibility)(对象行为)
设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决.不能解决就 ...
随机推荐
- 学习sbtenv
背景 最近由于工作需要, 我总是在不同的scala项目间流动开发. 这就遇到一个很棘手的问题, 这几个项目用的sbt版本不一致, 老项目用的是 sbt 0.13.15, 新项目用的是 sbt 1.0. ...
- Node.js 从入门到茫然系列——入门篇
在创建服务的时候,我们一般代码就是: var http = require("http"); var server = http.createServer(function(req ...
- expdp 简单例子
expdp 的使用步骤比较简单. 但是需要注意: 以OS级别的oracle用户身份,建立好目录(导出的dump文件将位于此目录) 在oracle 中,建立directory 给directory赋予权 ...
- SQL Server 中SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
1.INSERT INTO SELECT语句 语句形式为:Insert into Table2(field1,field2,...) select value1,value2,... from Tab ...
- 设计模式之module模式及其改进
写在前面 编写易于维护的代码,其中最重要的方面就是能够找到代码中重复出现的主题并优化他们,这也是设计模式最有价值的地方 <head first设计模式>里有一篇文章,是说使用模式的心智, ...
- MGR的debug版本
debug版本的MGR 相较于 非 debug 版本, applier性能差距有40倍之多.
- 【轮子狂魔】手把手教你自造Redis Client
为什么做Redis Client? Redis Client顾名思义,redis的客户端,主要是封装了一些对于Redis的操作. 而目前用的比较广泛的 ServiceStack.Redis 不学好,居 ...
- Linux之linux基础命令2
目录相关: 创建目录: mkdir 目录名 递归创建a/b c/d: mkdir -p a/b c/d 递归创建test/a,b,c,d四个目录: mkdir - p test{a,b,c,d} 递归 ...
- stl源码分析之hash table
本文主要分析g++ stl中哈希表的实现方法.stl中,除了以红黑树为底层存储结构的map和set,还有用哈希表实现的hash_map和hash_set.map和set的查询时间是对数级的,而hash ...
- TensorFlow Python2.7环境下的源码编译(一)环境准备
参考: https://blog.csdn.net/yhily2008/article/details/79967118 https://tensorflow.google.cn/install/in ...