xaml mvvm(2)之属性绑定
通过微软INotifyPropertyChanged接口,可以实现对UI实时更新,不管是数据源或者目标对象,可以实现相互通知。
下面我们根据INotifyPropertyChanged编写一个扩展类。该类是基于C#5.0特性,这里我们介绍一下System.Runtime.CompilerServices命名空间下的CallerMemberName特性,当RaisePropertyChanged的属性名称参数为空,而通过编译器可以智能加上,可以通过反编译工具知晓,这点改进这点很人性化。注:如果开发版本framework 4.0,则需要安装KB2468871补丁或者更新framework 4.0以上版本。
为这个扩展类添加命名空间如下。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected PropertyChangedEventHandler PropertyChangedHandler
{
get
{
return this.PropertyChanged;
}
}
[Conditional("DEBUG"), DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
Type type = base.GetType();
if (!string.IsNullOrEmpty(propertyName) && type.GetTypeInfo().GetDeclaredProperty(propertyName) == null)
{
throw new ArgumentException("Property not found", propertyName);
}
}
protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
protected virtual void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression)
{
PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if (propertyChanged != null)
{
string propertyName = ObservableObject.GetPropertyName<T>(propertyExpression);
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
protected static string GetPropertyName<T>(Expression<Func<T>> propertyExpression)
{
if (propertyExpression == null)
{
throw new ArgumentNullException("propertyExpression");
}
MemberExpression memberExpression = propertyExpression.Body as MemberExpression;
if (memberExpression == null)
{
throw new ArgumentException("Invalid argument", "propertyExpression");
}
PropertyInfo propertyInfo = memberExpression.Member as PropertyInfo;
if (propertyInfo == null)
{
throw new ArgumentException("Argument is not a property", "propertyExpression");
}
return propertyInfo.Name;
}
protected bool Set<T>(Expression<Func<T>> propertyExpression, ref T field, T newValue)
{
if (EqualityComparer<T>.Default.Equals(field, newValue))
{
return false;
}
field = newValue;
this.RaisePropertyChanged<T>(propertyExpression);
return true;
}
protected bool Set<T>(string propertyName, ref T field, T newValue)
{
if (EqualityComparer<T>.Default.Equals(field, newValue))
{
return false;
}
field = newValue;
this.RaisePropertyChanged(propertyName);
return true;
}
protected bool Set<T>(ref T field, T newValue, [CallerMemberName] string propertyName = null)
{
return this.Set<T>(propertyName, ref field, newValue);
}
}
下面我们来继承这个类编写一个Animal类对象。在这里我们用到RaisePropertyChanged三种不同的实现方式,达到一样的绑定效果。
public class Animal : ObservableObject
{
private string m_Cat;
public string Cat
{
get { return m_Cat; }
set { m_Cat = value; RaisePropertyChanged("Cat"); }
} private string m_Dog;
public string Dog
{
get { return m_Dog; }
set { m_Dog = value; RaisePropertyChanged(); }
} private string m_Tiger;
public string Tiger
{
get { return m_Tiger; }
set { m_Tiger = value; RaisePropertyChanged(() => this.Tiger); }
}
}
下面我们来建立model视图类。在该类中用的事件绑定和model对象实现,我们会在后续介绍。
public class MainPageViewModel : Core.ViewModelBase
{
public MainPageViewModel()
{
MyAnimal = new Animal();
} private Animal m_MyAnimal;
public Animal MyAnimal
{
get { return m_MyAnimal; }
set { m_MyAnimal = value; RaisePropertyChanged("MyAnimal"); }
} public ICommand OKCommand
{
get
{
return new RelayCommand(() =>
{
MyAnimal.Dog = "eating";
MyAnimal.Cat = "sleeping";
MyAnimal.Tiger = "hungry";
});
}
}
}
前台xaml。
<Grid DataContext="{Binding Path=MainPageViewModel}">
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="" Text="cat is:" />
<TextBlock FontSize="" Text="{Binding MyAnimal.Cat}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="" Text="dog is:" />
<TextBlock FontSize="" Text="{Binding MyAnimal.Dog}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="" Text="Tiger is:" />
<TextBlock FontSize="" Text="{Binding MyAnimal.Tiger}" />
</StackPanel>
<Button Width="" Content="OK" Command="{Binding OKCommand}" />
</StackPanel>
</Grid>
运行效果。

xaml mvvm(2)之属性绑定的更多相关文章
- WPF使用MVVM(一)-属性绑定
WPF使用MVVM(一)-属性绑定 简单介绍MVVM MVVM是Model(数据类型),View(界面),ViewModel(数据与界面之间的桥梁)的缩写,是一种编程模式,优点一劳永逸,初步增加一些逻 ...
- xaml mvvm(1)之结构
在微软winstore.wp和silverlight中xaml是用来构建UI视图的标记语言,全名Extensible Application Markup Language.在结构上类似于html,但 ...
- 【WPF】如何把一个枚举属性绑定到多个RadioButton
一.说明 很多时候,我们要把一个枚举的属性的绑定到一组RadioButton上.大家都知道是使用IValueConverter来做,但到底怎么做才好? 而且多个RadioButton的Checked和 ...
- WPF属性绑定实现双向变化
WPF依赖项属性可以实现属性的绑定,成功绑定之后只要修改后台绑定的属性,即可UI同步自动更新绑定的值,无需手动刷新界面:同样,前台的值变化后,通过获取绑定的属性值也可获取UI变化后的值,实现双向变化的 ...
- 2019-11-29-WPF-依赖属性绑定不上调试方法
原文:2019-11-29-WPF-依赖属性绑定不上调试方法 title author date CreateTime categories WPF 依赖属性绑定不上调试方法 lindexi 2019 ...
- 2019-8-2-WPF-依赖属性绑定不上调试方法
title author date CreateTime categories WPF 依赖属性绑定不上调试方法 lindexi 2019-08-02 19:56:32 +0800 2019-8-2 ...
- Knockoutjs实例 - 属性绑定(Bindings)之流程控制(Control flow)
一.foreach binding 使用此功能可以方便我们循环遍历输出某个数组.集合中的内容. (1).循环遍历输出数组 View Row Code 1 <script type="t ...
- grootJs的属性绑定指令
index6.html 绑定文本text gt-text="{属性名}" 绑定标签属性attr gt-attr="vm属性名称(标签属性,value表达式)" ...
- 控制文本和外观------Attr Binding(attr属性绑定)
Attr Binding(attr属性绑定) 目的 attr 绑定提供了一种方式可以设置DOM元素的任何属性值.你可以设置img的src属性,连接的href属性.使用绑定,当模型属性改变的时候,它会自 ...
随机推荐
- SpringAOP的两种实现方式
1.SpringAOP,面向切面编程.在实际应用汇总很常见,一般用于日志.异常保存.也可以针对于相应的业务做处理 AOP核心概念 1.横切关注点 对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横 ...
- 在Ubuntu 16.04上使用bazel交叉编译tensorflow
鸽了这么久,正式开工 Author: carbon email: ecras_y@163.com 参考资料: https://github.com/tensorflow/tensorflow http ...
- python之解析csv
使用csv包 读取信息 csvfile = file('csv_test.csv', 'rb') reader = csv.reader(csvfile) for line in reader: pr ...
- 常用工具&网址
工具 I tell you http://www.win7999.com/news/197912345.html VisualSVN Server(免费) http://www.visualsvn.c ...
- WPF TabControl控件-事件相关问题
TabControl控件的TabItem的Content元素,例如:DataGrid控件,在对事件的处理时,需要对事件的源引起关注,当需要处理DataGrid的事件时,事件会传递到TabControl ...
- 跟我学算法-match-LSTM(向唐老师看齐)
对于match-lstm,将hi文本与输出的match-lstm(由si,hi,qi)组合重新输入到LSTM网络中,以端对端的操作理念. 参考的博客:https://blog.csdn.net/lad ...
- Zabbix 监控 Cisco ASA5525 流量
简介: Zabbix 监控 Cisco ASA5525 网络接口流量 一.Zabbix 支持 SNMP.Cisco 开启 SNMP 二.测试 shell > snmpwalk -v 2c -c ...
- LevelDB Version
[LevelDB Version] Version 保存了当前磁盘以及内存中所有的文件信息,一般只有一个Version叫做"current" version(当前版本).Level ...
- open中的mode
[open中的mode] 当使用O_CREAT标志的open来创建文件时,我们必须使用三个参数格式的open调用.第三个参数mode 是几个标志按位OR后得到的.他们是: S_IRUSR: 读权限,文 ...
- Linux运维实战之DNS(bind)服务器的安装与配置
转自http://sweetpotato.blog.51cto.com/533893/1598225 上次博文我们讨论了DNS的基础,本次博文我们重点来看看如何配置一台DNS服务器. [本次博文的主要 ...