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属性.使用绑定,当模型属性改变的时候,它会自 ...
随机推荐
- python学习-day 2
1.执行Python脚本的两种方式1)调用解释器 Python +绝对路径+文件名称2)调用解释器 Python +相对路径+文件名称 2.简述位.字节的关系8位为1个字节 3.简述ASCII.uni ...
- Java各种Utils小结
原文地址:http://trinea.iteye.com/blog/1533616 最新内容建议直接访问原文:Android常用的工具类 主要介绍总结的Android开发中常用的工具类,大部分同样适用 ...
- VS2010生成的文件在别的机器上运行提示“丢失MSVCR100D.dll”<转>
用vs2010编写的程序经常会发生的一个问题.在自己的机器上运行的好好的,但是在别的机器上就会发生没有找到MSVCR100D.dll.这是 个很头疼的问题.对于一些代码量几百行的小程序,我不可能要求其 ...
- window10上安装python+CUDA+CuDNN+TensorFlow
软件 版本 Window10 X64 python 3.6.4(64位) CUDA CUDA Toolkit 9.0 (Sept 2017) CuDNN cuDNN v7.0.5 (Dec 5, 20 ...
- sass对象的定义
sass在3.3引入map类型,它与JS的对象非常相似,它有两种定义模式.外面都是用小括号括括起来,每个键值对可以像JS那样与逗号分开.不同之后是,键名与键值之间的冒号不是 必须的 不用对象的情况 @ ...
- WeakHashMap, NOT A CACHE
Overview Base Map的实现 基于WeakReference的Entity实现 基于Reference和ReferenceQueue实现 它的弱引用是键,而不是值 它的key会被全自动回收 ...
- mongoTemplate.aggregate()聚合查询
一.概述 1. 聚合的表达式 MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果.有点类似sql语句中的 count(*). 下表展示了一些聚 ...
- python传值&值引用
[python传值&值引用] 和其他语言不一样,传递参数的时候,python不允许程序员选择采用传值还是传引用.Python参数传递采用的肯定是“传对象引用”的方式.实际上,这种方式相当于传值 ...
- grep 过滤.svn文件
[grep 过滤.svn文件] 问题: 在repository搜索代码时,常常会搜索到.svn的代码,如果不想搜索.svn目录下的相关代码怎么办? 1.使用管道进行双层“过滤”,其中第二次gre ...
- jsp页面拨打电话和QQ聊天
拨打电话: <a href="tel:手机号">拨打电话</a> 这种方式塞班.安卓与iphone都支持. 参考文章:https://blog.csdn.n ...