2014-02-05 78 views
0

感謝Marc Gravell的真棒answer我能夠在我的課程中實現屬性更改跟蹤。但是,首次初始化對象並首次設置屬性時,所有屬性都將被標記爲髒。處理屬性的初始設置的最佳方法是什麼,以便在首次加載對象時不會將其標記爲髒?如何處理具有屬性更改跟蹤的對象的初始化

因此當ExtendedFieldDto屬性第一次設置時dirtyProperties總是有一個計數等於繼承類的屬性,在這種情況下ExtendedFieldDto

public abstract class NotifyPropertyChanged { 
    public IDictionary<string, object> dirtyProperties { get; private set; } 

    protected NotifyPropertyChanged() { 
     dirtyProperties = new Dictionary<string, object>(); 
    } 

    protected void setProperty<T>(ref T property, T value, string propertyName) { 
     if (!EqualityComparer<T>.Default.Equals(property, value)) { 
      property = value; 
      if (dirtyProperties.Keys.Contains(propertyName)) 
       dirtyProperties[propertyName] = property; 
      else 
       dirtyProperties.Add(propertyName, property); 
     } 
    } 
} 

public class ExtendedFieldDto : NotifyPropertyChanged { 
    private string _id; 
    public string id { 
     get { return _id; } 
     set { setProperty(ref _id, value, "id"); } 
    } 

    private int _idLocation; 
    public int idLocation { 
     get { return _idLocation; } 
     set { setProperty(ref _idLocation, value, "idLocation"); } 
    } 

    private string _columnName; 
    public string columnName { 
     get { return _columnName; } 
     set { setProperty(ref _columnName, value, "columnName"); } 
    } 

    private string _description; 
    public string description { 
     get { return _description; } 
     set { setProperty(ref _description, value, "description"); } 
    } 

    private string _help; 
    public string help { 
     get { return _help; } 
     set { setProperty(ref _help, value, "help"); } 
    } 
} 

的DTO當前正被用作其中我存儲在ViewState對象(從遺留碼的要求)aspx頁上的proprety。所以我不確定如何使用ExtendedFieldDto的構造函數來設置這種類型的實現的私有屬性。

private ExtendedFieldDto extendedField { 
    get { 
     if (ViewState[EXTENDED_FIELD_VIEWSTATE_KEY] == null) 
      ViewState[EXTENDED_FIELD_VIEWSTATE_KEY] = new ExtendedFieldDto(); 
     return (ExtendedFieldDto)ViewState[EXTENDED_FIELD_VIEWSTATE_KEY]; 
    } 
    set { ViewState[EXTENDED_FIELD_VIEWSTATE_KEY] = value; } 
} 
+0

你可以使用一個構造函數來設置你的私人領域?這不應該觸發setProperty。 – Vlad

+0

@Vlad是的,這將會解決工作,但真正的對象有超過20個屬性,它使對象的管理(即:添加/刪除屬性)類型的痛苦。這可能是最好的方法,雖然:/ – bflemi3

+0

@Vlad此外,與我目前的實施,我將這個對象存儲在ViewState中,所以我有一個aspx對象的屬性,在getter上,初始化對象,如果ViewState KeyValue對不存在。所以不知道如何通過所有的屬性。 'get {if(ViewState [EXTENDED_FIELD_VIEWSTATE_KEY] == null)ViewState [EXTENDED_FIELD_VIEWSTATE_KEY] = new ExtendedFieldDto();返回(ExtendedFieldDto)ViewState [EXTENDED_FIELD_VIEWSTATE_KEY]; }' – bflemi3

回答

4

這是ISupportInitialize界面創建時的一系列常見問題之一。

public abstract class NotifyPropertyChanged : ISupportInitialize { 
    ... 
    public void BeginInit() { } 
    public void EndInit() { PropertyChangedObserver(); } 
} 

並且你使用這樣的:

ExtendedFieldDto foo = new ExtendedFieldDto(); 
foo.BeginInit(); 
foo.id = "abc123"; 
foo.idLocation = 0; 
... 
foo.EndInit(); 

編輯:您也可能會考慮實施INotifyPropertyChanged,而你在它,因爲你已經大部分的方式存在。

+0

好的界面:ISupportInitialize。我不知道。不幸的是,XmlSerializer.Deserialize(.Net v4.0)似乎並沒有使用它。 – Knowleech

0

我有一次非常類似的問題。使用ctor的想法對我不起作用,因爲該對象是由XML反序列化創建和初始化的。

我使用的相當醜陋的解決方案是僞全局初始化bool變量(線程靜態變量,http://msdn.microsoft.com/library/system.threadstaticattribute%28v=vs.110%29.aspx)。在反序列化數據之前,我將該bool設置爲true,並在完成反序列化之後將其重置爲false(使用try-finally構造以保證安全)。在我的PropertyChanged處理程序中,我檢查了這個布爾。如果這是真的,我只是沒有開火我的事件。

這是一個非常醜陋的解決方案。我甚至不喜歡將它稱爲解決方案,因爲每次調用PropertyChanged處理程序時都檢查該bool變量。這不是一種乾淨的或保存的方法,因爲您必須確保在初始化期間僅設置該布爾值,並且必須確保事後重置該布爾值。但它爲我工作。

+0

我也曾考慮過這個,但不喜歡客戶不必擔心任何事情,但設置對象的想法。 – bflemi3

+0

也許可以將其修改爲屬性具有某些模糊初始值的位置,並且如果值從初始值更改爲「from」,則不會觸發set屬性。雖然這可能看起來很奇怪,我不確定初始值可以/應該是什麼。 – Vlad

相關問題