我有一个XML Serializable List,它的类型是ObservableCollection。我已经实现了一个事件,以便每次对此集合进行更改时,都应该对其进行序列化,然后进行反序列化。
有一个可以添加,删除和修改武器的外部类(武器编辑器)。按下删除按钮后,它将立即进入此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();
}
}
答案 0 :(得分: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事件用于其他对象以响应已更改的集合,而不是您的类进行更新。如果Weapons Editor对象直接操作集合,那就是你的问题;你应该让它在WeaponsDatabase中调用一个自定义方法,它会将请求转发给集合,然后立即调用Serialize / Deserialize方法。
答案 1 :(得分: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
事件,并在收集更改并且反序列化完成时收到通知。