2012-01-03 55 views
2

我有一个类,我绑定到我的视图模型。它基本上是一个完整的UI显示的字符串的结构:快速暴露类属性为可绑定

class DisplayVO 
{ 
    public string Title { get; set; } 
    public string Description { get; set; } 
    // ... about a dozen more properties 
} 

基本上DisplayVO包装一堆绑定到UI属性。此操作一直运行到UI的一部分修改属性为止(例如用户可以编辑Description),所以我想用新的修改更新UI。

所以,我通常会做的是落实INotifyPropertyChanged接口,并覆盖每个set方法广播PropertyChanged(this, new PropertyChangedEventArgs(info));

我懒洋洋的感觉 - 是有办法有这样的类的所有成员都做了什么?在Flex我可以这样做:

[Bindable] 
public class DisplayVO 
{ 
    private var Title:String; 
    private var Description:String; 
} 

,并奇迹般地全部DisplayVO属性将被包裹,没有我写的所有的样板自动播出的变化。有没有相当于C#和WPF?

+0

[更好的方式来触发OnPropertyChanged]的可能重复(http://stackoverflow.com/questions/7063902/better-way-to-trigger-onpropertychanged) – 2012-01-03 23:05:06

回答

2

你应该看看NotifyPropertyWeaver http://github.com/SimonCropp/NotifyPropertyWeaver它运行后生成的任务,不正是你所追求的。

+0

我不一定非常喜欢这是后期制作,但它与我之后最接近,所以对于复选标记来说足够好。我其实已经过去了,并亲自写下了样板。只有几个属性在初始化后实际发生了变化(并且需要UI重绘),所以我现在可以忍受代码膨胀。 – 2012-01-06 18:56:39

1

你可以写一个填充样板的代码片段。这里的广播事件一个,我用(我有一个方法,OnPropertyChanged():

<?xml version="1.0" encoding="utf-8"?> 
<CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> 
    <Header> 
    <Title>ObservableProperty</Title> 
    <Author>Scott Austen</Author> 
    <Shortcut>#ObsProp</Shortcut> 
    <Description>Inserts property definition with private backing field, calling RaisePropertyChanged</Description> 
    <SnippetTypes> 
     <SnippetType>Expansion</SnippetType> 
    </SnippetTypes> 
    </Header> 
    <Snippet> 
    <Declarations> 
     <Literal> 
     <ID>Type</ID> 
     <Default>Type</Default> 
     </Literal> 
     <Literal> 
     <ID>PropertyName</ID> 
     <Default>P</Default> 
     </Literal> 
    </Declarations> 
    <Code Language="CSharp"> 
     <![CDATA[public $Type$ $PropertyName$ 
     { 
     get { return _$PropertyName$; } 
     set 
     { 
      _$PropertyName$ = value;   
      OnPropertyChanged("$PropertyName$"); 
     } 
     } 

     private $Type$ _$PropertyName$;]]> 
    </Code> 
    </Snippet> 
</CodeSnippet> 

那么所有你需要做的就是输入obsprop TAB TAB {type} TAB TAB {propertyName} ENTER.

+0

虽然这是一个相当不体面的实现,事件被解雇,即使该物业可能甚至没有因事件的名称而改变。 – 2012-01-04 00:21:23

+0

我还没有发现它是一个问题。除了小幅的性能收益,检查变更有什么好处? – saus 2012-01-04 01:06:57

+0

事件只有在*应该*的时候才会被触发,这样做就像下载事件发生时一样,即使下载还没有完成,它的语义错误也会给想要使用事件的人造成麻烦。 – 2012-01-04 10:27:34

1

我使用的是财产申报片断调用OnPropertyChanged它。还填充从位于System.ComponentModel命名空间中的一些属性...

Description: a brief phrase about what the property does 
DisplayName: how the property should be labelled 
DefaultValue: the initial value of the property 

这个片段也使用DebuggerStepThroughAttribute,这样调试器将无法进入getter和setter,但如果你不希望这个应该被删除那种效果...

<?xml version="1.0" encoding="utf-8" ?> 
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> 
    <CodeSnippet Format="1.0.0"> 
     <Header> 
      <Title>Full property declaration</Title> 
      <Shortcut>propfull</Shortcut> 
      <Description>Code snippet for property and backing field</Description> 
      <Author>GJV</Author> 
      <SnippetTypes> 
       <SnippetType>Expansion</SnippetType> 
      </SnippetTypes> 
     </Header> 
     <Snippet> 
      <Declarations> 
       <Literal> 
        <ID>type</ID> 
        <ToolTip>Property type</ToolTip> 
        <Default>string</Default> 
       </Literal> 
       <Literal> 
        <ID>property</ID> 
        <ToolTip>Property name</ToolTip> 
        <Default>MyProperty</Default> 
       </Literal> 
       <Literal> 
        <ID>field</ID> 
      <ToolTip>The variable backing this property</ToolTip> 
        <Default>myProperty</Default> 
       </Literal> 
       <Literal> 
        <ID>desc</ID> 
        <ToolTip>What the property is about</ToolTip> 
        <Default>My description...</Default> 
       </Literal> 
       <Literal> 
        <ID>dispname</ID> 
        <ToolTip>Column header</ToolTip> 
        <Default>DisplayName</Default> 
       </Literal> 
       <Literal> 
        <ID>defaultvalue</ID> 
        <ToolTip>Default value</ToolTip> 
        <Default>""</Default> 
       </Literal> 
      </Declarations> 
      <Code Language="csharp"> 
     <![CDATA[private $type$ $field$; 
    [Description("$desc$"), DisplayName("$dispname$"), DefaultValue($defaultvalue$)] 
    public $type$ $property$ 
    { 
      [DebuggerStepThrough]get{return $field$;} 
      [DebuggerStepThrough]set 
      { 
       if(value!=$field$) 
       { 
        $field$ = value; 
        OnPropertyChanged("$property$"); 
       } 
      } 
    } 
    $end$]]> 
      </Code> 
     </Snippet> 
    </CodeSnippet> 
</CodeSnippets> 

说明属性是为了提取和用于工具提示文本,但它也可以提供一些文档值。

这段代码假定您的基本视图模型类有这样的方法......

protected void OnPropertyChanged(string propertyName) 
{ 
    if(PropertyChanged!=null) 
    { 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
}