2013-08-07 112 views
1

我有一個XML序列化列表,其類型爲ObservableCollection。我實現了一個事件,以便每當對此集合進行更改時,都應該對其進行序列化,然後反序列化。C# - 檢查ObservableCollection CollectionChanged事件是否已完成執行

有一個外部類(武器編輯器),可以添加,刪除和修改武器。只要按下刪除按鈕,它就來到這個WeaponsDB類來收集ObservableCollection。但是,在我的CollectionChanged事件執行之前,它會刷新ObservableCollection中的內容。

如何確保CollectionChanged事件已完全執行,並且在任何其他類獲取最新數據之前所有內容都是最新的?

public class WeaponDatabase 
{ 
    [XmlArray("Weapons"), XmlArrayItem(typeof(Weapon), ElementName = "Weapon")] 
    public ObservableCollection<Weapon> Weapons = new ObservableCollection<Weapon>(); 

    private string path = @"Inventory\WeaponsDB.xml"; 

    public WeaponDatabase() 
    { 
     DeserializeData(); 
     Weapons.CollectionChanged += Weapons_CollectionChanged; 
    } 

    void Weapons_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     SerializeData(); 
     DeserializeData(); 
    } 

    public void SerializeData() 
    { 
     XmlSerializer Serializer = new XmlSerializer(typeof(ObservableCollection<Weapon>)); 
     TextWriter textWriter = new StreamWriter(path); 
     Serializer.Serialize(textWriter, Weapons); 
     textWriter.Close(); 
    } 

    public void DeserializeData() 
    { 
     XmlSerializer Serializer = new XmlSerializer(typeof(ObservableCollection<Weapon>)); 
     StreamReader reader = new StreamReader(path); 
     Weapons = (ObservableCollection<Weapon>)Serializer.Deserialize(reader); 
     reader.Close(); 
    } 
} 

回答

3

我還沒有使用ObservableCollection,所以有可能我是一個接觸基地,但嘿。

可能,您的弱點是您正在查看此反向。 CollectionChanged是爲了讓你的訪問集合的外部對象知道集合已更新,而不是用來更新實際集合(通過將其轉儲到文件或從XML文件重新構建它)應該觸發的。

機智:

這種外部類應該有沿此線設置的東西:

public class WeaponsEditor 
    { 
     private WeaponsDatabase DB; 
     public WeaponsEditor() 
     { 
      DB = new WeaponsDatabase(); 
      DB.CollectionChanged += CollectionChanged; 
     } 

     private object CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
     { 
      // respond to the updated database 
     } 
    } 

基本上,CollectionChanged事件是其他對象到到更改後的集合反應,不是讓你的班級進行更新。如果武器編輯器對象直接操縱集合,那就是你的問題;你應該讓它在WeaponsDatabase中調用一個自定義方法,它將把請求轉發到集合,然後立即調用Serialize/Deserialize方法。

1

您需要添加INotifyPropertyChanged接口WeaponDatabase(我說使用該接口而不是一個自定義事件所以像BindingSources將自動只是使用它)

public class WeaponDatabase : INotifyPropertyChanged 
{ 
    [XmlArray("Weapons"), XmlArrayItem(typeof(Weapon), ElementName = "Weapon")] 
    public ObservableCollection<Weapon> Weapons {get; private set;} 

    private string path = @"Inventory\WeaponsDB.xml"; 

    public event PropertyChangedEventHandler PropertyChanged; 

    public WeaponDatabase() 
    { 
     Weapons = new ObservableCollection<Weapon>(); 
     DeserializeData(); 
     Weapons.CollectionChanged += Weapons_CollectionChanged; 
    } 

    private void RaiseWeaponsChanged() 
    { 
     var temp = this.PropertyChanged; 
     if(temp != null) 
      temp(this, new PropertyChangedEventArgs("Weapons")); 
    } 

    void Weapons_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     SerializeData(); 
     DeserializeData(); 
     RaiseWeaponsChanged() 
    } 

    //Snip 
} 

現在,其他類可以訂閱WeaponDatabase.PropertyChanged事件,並在收集發生變化並且反序列化完成時收到通知。

相關問題