2012-10-12 64 views
4

我有一個基類,其中包括以下功能的BLL:IsDirty標記模式

public bool IsDirty { get; protected set; } 

    internal void SetField<TParam>(ref TParam field, TParam value) 
    { 
     if (EqualityComparer<TParam>.Default.Equals(field, value) == false) 
     { 
      field = value; 
      IsDirty = true; 
     } 
    } 

在繼承的基類我使用這個作爲圍繞SET對象的包裝的類,如:

public string UserName 
    { 
     get { return _userName; } 
     set { SetField(ref _userName, value); } 
    } 

我使用IsDirty屬性來測試以查看是否需要發出更新。如果至少有一個屬性發生更改,則保存到數據庫。這適用於大多數類型,但集合和列表可以在不使用set的情況下更改。我寫了一個包裝的收集到有可能變更進行測試列表中的IsDirty標誌:

public class CollectionChangeTracked<T> : Collection<T> 
    { 
     public bool IsDirty {get; set;} 

     public CollectionChangeTracked() 
     { 
      IsDirty = false; 
     } 

     protected override void InsertItem(int index, T newItem) 
     { 
      base.InsertItem(index, newItem); 
      IsDirty = true; 
     } 

     protected override void SetItem(int index, T newItem) 
     { 
      base.SetItem(index, newItem); 
      IsDirty = true; 
     } 

     protected override void RemoveItem(int index) 
     { 
      base.RemoveItem(index); 
      IsDirty = true; 
     } 

     protected override void ClearItems() 
     { 
      base.ClearItems(); 
      IsDirty = true; 
     } 
    } 
} 

的問題是,我現在來測試的CLASSE的IsDirty屬性和任何CollectionChangeTracked.IsDirty爲標誌更新。

public CollectionChangeTracked<ApplicationRole> RolesList 
    { 
     get { return _rolesList; } 
     set { SetField(ref _rolesList, value); } 
    } 

    public override bool IsDirty 
    { 
     get { return ResolveIsDirty(); } 
     protected set { _isDirty = value; } 

    private bool ResolveIsDirty() 
    { 
     bool returnValue; 

     if (_isDirty || RolesList.IsDirty) 
      returnValue = true; 
     else 
      returnValue = false; 

     return returnValue; 
    } 

但好像我應該能夠拿出一個更清潔的解決方案,將允許包含集合一類訂閱的改變:比如我可以創建在一個地方進行的測試方法CollectionChangeTracked對象的IsDirty,並基於該更改更新IsDirty。這是更好的方法,我將如何實施?

+5

我覺得很髒。 – jgauffin

+0

@jgauffin讓我解決這個問題:jgauffin =!jgauffin。 – LarsTech

回答

1

您可以使用ObservableCollection<T>寄存器來登記CollectionChanged事件,並在引發事件時標記IsDirty標誌。

... 

ObservableCollection<int> myCollection = new ObservableCollection<int>(); 
myCollection.CollectionChanged += OnCollectionChanged; 

... 

public void OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) 
{ 
    IsDirty = true; 
} 
+0

ObservableCollection的問題是它的所有消費者都必須支持INotifyPropertyChanged,所以它可以適用於這種情況,但我會限制Collection的用處,這就是爲什麼我創建了CollectionChangeTracked()。 – Josh

+0

消費者不必支持INotifyPropertyChanged,他們可以像使用其他任何集合一樣使用它。如果要對集合中的項目使用Binding或綁定到類中的集合屬性,則只需要INotifyPropertyChanged接口。 –

+0

所以如果我有一個人使用這個作爲源到GridView它仍然是安全的?如果是這樣,將工作。 – Josh