2012-01-03 54 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)); 
    } 
}