通过微软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>

运行效果。

最新文章

  1. java的关闭钩子(Shutdown Hook)
  2. spring boot 配置启动后执行sql, 中文乱码
  3. 进军Linux
  4. SQL Server中查询某个数据库中表的个数
  5. h.Connector的SSL属性实现
  6. 二十二、【轻量级开源框架】EFW框架Web前端开发之JqueryEasyUI
  7. C#Json序列化和反序列化
  8. hdu4576 概率dp n^2的矩阵
  9. C/C++:类模板
  10. No identifier specified for entity
  11. java中输入方式Scanner和BufferedReader
  12. Linux下Oracle常见安装错误[Z]
  13. android-包签名
  14. Getting Started with Core Data
  15. .net core中引用webservice,并忽略https证书验证
  16. 2017-2018-1 20155205 实现mypwd
  17. Gitflow工作流程
  18. springboot+shiro 一个项目部署多个,session名冲突问题
  19. Spring,Spring MVC及Spring Boot区别
  20. charles抓包出现乱码 SSL Proxying not enabled for this host:enable in Proxy Setting,SSL locations

热门文章

  1. Tornado模板转义处理
  2. css踩过的坑
  3. centos7使用tinyproxy搭建简单http(s)服务器,无用户密码验证
  4. plsql 中文乱码
  5. MySQL GTID (三)
  6. Linux CPU 100%, kill -9 杀不掉进程
  7. java JDBC数据库连接操作
  8. Linux中shell变量$0,$?等含义
  9. InfoPanel
  10. QEMU 代码分析:BIOS 的加载过程