INotifyPropertyChanged接口的辅助snippets

在Silverlight与WPF的开发过程中,为了使用Binding技术,往往要将自己的实体类实现INotifyPropertyChanged接口。但为每一个Property书写调用接口,并不是省时省力的事情,而且在硬编码属性的NAME,也可能会在以后的重构过程中引入潜在的Bug。在参考了下面两篇文章后,使用Lambda表达式与snippet快速的完成实体类的属性声明。

 

http://www.jphamilton.net/post/MVVM-with-Type-Safe-INotifyPropertyChanged.aspx

http://www.designerwpf.com/2009/04/30/inotifypropertychanged-snippets-and-why-you-should-use-these-instead-of-dependencyproperties/

 首先定义基类,所有的实体类,均需从ViewModel<>类派生出来。

      public abstract class ViewModel<MODEL> : INotifyPropertyChanged
      {
          public event PropertyChangedEventHandler PropertyChanged;
          protected void RaisePropertyChanged<R>(Expression<Func<MODEL, R>> x)
         {
             var body = x.Body as MemberExpression;
             if (body == null)
                 throw new ArgumentException("请输入属性的引用");
             string propertyName = body.Member.Name;
             PropertyChangedEventHandler handler = this.PropertyChanged;
             if (handler != null)
             {
                 var e = new PropertyChangedEventArgs(propertyName);
                 handler(this, e);
             }
         }
     }

  之后,创建一个snippet。将下面的代码,另存为INotifyProperty.snippet,并保存到Visual Studio的相应目录中,例如我的VS2008中,目录为:C:\Program Files\Microsoft Visual Studio 9.0\VC#\Snippets\2052\Visual C#---其他文章里的INotifyProperty.snippet在VS2010下有些错误,这里已经更正

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>INotifyPropertyChanged Property: Use this to create a new property INotifyPropertyChanged implementation.</Title>
      <Shortcut>notifyp</Shortcut>
      <Description>This class must inherited from ViewModel or implements RaisePropertyChanged method.</Description>
      <Author>alexou</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>PropertyName</ID>
          <ToolTip>The name of the private property</ToolTip>
          <Default>MyProperty</Default>
        </Literal>
        <Literal>
          <ID>type</ID>
          <ToolTip>The type of the property (e.g. string, double, bool, Brush, etc.)</ToolTip>
          <Default>string</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp">
        <![CDATA[
        private $type$ _$PropertyName$;
                
        public $type$ $PropertyName$ 
        {
            get{ return _$PropertyName$;}
            set
            {
                _$PropertyName$ = value;
                RaisePropertyChanged(item => item.$PropertyName$);
            }
        }
        $end$]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

 现在开始声明自己的实体类,举个简单的例子:声明一个Person类,里面应当由诸如Name,Age,Sex,Phone等通用属性,只需要按照下面的方式,就可以非常快速并且安全的声明相应的成员变量和INotifyPropertyChanged接口的调用方法。

      public abstract class ViewModel<MODEL> : INotifyPropertyChanged
      {
          public event PropertyChangedEventHandler PropertyChanged;
          protected void RaisePropertyChanged<R>(Expression<Func<MODEL, R>> x)
         {
             var body = x.Body as MemberExpression;
             if (body == null)
                 throw new ArgumentException("请输入属性的引用");
             string propertyName = body.Member.Name;
             PropertyChangedEventHandler handler = this.PropertyChanged;
             if (handler != null)
             {
                 var e = new PropertyChangedEventArgs(propertyName);
                 handler(this, e);
             }
         }
     }

 

posted @ 2012-01-14 11:07  Mccc  阅读(234)  评论(0)    收藏  举报