我在asp.net应用程序中使用ObservableCollection,通过使用“CollectionChanged”事件,我可以获得添加/删除的值。为此,我将对象存储在会话(InProc)中,每个工作正常。
现在问题是我将会话更改为outproc(DB),Collection_CollectionChanged停止触发(Button2_Click)。我认为必须要对序列化做些什么。对此有任何帮助。
示例的用法: 首先点击button1&然后按钮2,按钮1和按钮1
后面的aspx代码中有2个事件 [Serializable]
public class School
{
public School()
{
studentList = new ObservableCollection<Student>();
studentList.CollectionChanged += Collection_CollectionChanged;
}
public string SchoolName { get; set;}
public ObservableCollection<Student> studentList { get; set; }
public void Collection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
var result= "add";
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
var result= "del";
}
}
}
[Serializable]
public class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
//Code in .aspx.cs Page
protected void Button1_Click(object sender, EventArgs e)
{
School school = new School();
school.SchoolName = "Benie";
school.studentList.Add(new Student() { FirstName = "a", LastName = "a1" });
school.studentList.Add(new Student() { FirstName = "b", LastName = "b1" });
Session["school"] = school;
}
protected void Button2_Click(object sender, EventArgs e)
{
School school = Session["school"] as School;
//Not working in Out Proc session, Working in InProc session
school.studentList.RemoveAt(1);
}
答案 0 :(得分:2)
我怀疑CollectionChanged事件没有被挂钩,因为该对象是通过序列化创建的(奇怪但我认为可能)或者序列化后没有挂钩Button1_Click(更高的可能性因为你没有在构造函数中这样做,但是我另读了你的问题)
要解决此问题,您可以尝试为您的School类实现ISerializable(不要忘记构造函数)并将事件挂钩到序列化构造函数中。
答案 1 :(得分:1)
我同意问题肯定是序列化,特别是Student对象被ObservableCollection包装的事实。如果要继续使用该方法,可以自己实现自定义序列化。
Kent Bogart有一篇关于这个确切场景以及如何在ObservableCollections上实现自定义序列化的帖子。 Take a look at it here.
答案 2 :(得分:0)
问题是,CollectionChanged
事件未标记为“不可序列化”。因此,在反序列化后,CollectionChanged
为null
。解决方案here
[Serializable]
public class SObservableCollection<T> : ObservableCollection<T>,
INotifyPropertyChanged
{
[field:NonSerialized]
public override event NotifyCollectionChangedEventHandler CollectionChanged;
[field: NonSerialized]
private PropertyChangedEventHandler _propertyChangedEventHandler;
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
{
add
{
_propertyChangedEventHandler = Delegate.Combine(_propertyChangedEventHandler, value) as PropertyChangedEventHandler;
}
remove
{
_propertyChangedEventHandler = Delegate.Remove(_propertyChangedEventHandler, value) as PropertyChangedEventHandler;
}
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedEventHandler handler = CollectionChanged;
if (handler != null)
{
handler(this, e);
}
}
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = _propertyChangedEventHandler;
if (handler != null)
{
handler(this, e);
}
}
}