描述了一個例子here。但作者顯然忘記了包含下載的代碼。如何創建一個通用StateManagedCollection?
另一示例顯示爲here。但是,這個不太合適(如評論中所述)。
你如何正確地做到這一點?
描述了一個例子here。但作者顯然忘記了包含下載的代碼。如何創建一個通用StateManagedCollection?
另一示例顯示爲here。但是,這個不太合適(如評論中所述)。
你如何正確地做到這一點?
DanHerbert明白了。該死,我也在這上面花了幾個小時!在試圖回答這個問題的過程中,我想出了一個簡化的通用StateManagedCollection,它從Framework的內置StateManagedCollection繼承,基於版本here。也許你會發現它很有用。我的示例項目的完整源代碼可用here。
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Security.Permissions;
using System.Web;
using System.Collections.Generic;
using System.Web.UI;
namespace Web
{
public abstract class StateManagedCollection<T> : StateManagedCollection, IList<T>, ICollection<T>, IEnumerable<T>
where T : class, IStateManagedItem, new()
{
protected override object CreateKnownType(int index)
{
return Activator.CreateInstance<T>();
}
protected override Type[] GetKnownTypes()
{
return new Type[] { typeof(T) };
}
protected override void SetDirtyObject(object o)
{
((IStateManagedItem)o).SetDirty();
}
#region IList<T> Members
public int IndexOf(T item)
{
return ((IList)this).IndexOf(item);
}
public void Insert(int index, T item)
{
((IList)this).Insert(index, item);
if (((IStateManager)this).IsTrackingViewState)
{
this.SetDirty();
}
}
public void RemoveAt(int index)
{
((IList)this).RemoveAt(index);
if (((IStateManager)this).IsTrackingViewState)
{
this.SetDirty();
}
}
public T this[int index]
{
get { return (T)this[index]; }
set { this[index] = value; }
}
#endregion
#region ICollection<T> Members
public void Add(T item)
{
((IList)this).Add(item);
this.SetDirty();
}
public bool Contains(T item)
{
return ((IList)this).Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
((IList)this).CopyTo(array, arrayIndex);
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(T item)
{
if (((IList)this).Contains(item))
{
((IList)this).Remove(item);
return true;
}
return false;
}
#endregion
#region IEnumerable<T> Members
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
throw new NotImplementedException();
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
return ((IList)this).GetEnumerator();
}
#endregion
}
}
該second example you found幾乎可行,它只是缺少一點點。所有需要的是主控制中的2種方法。
將此代碼添加到AppointmentControl.cs
文件,它將工作。
protected override object SaveViewState()
{
if (appointments != null)
return appointments.SaveViewState();
return null;
}
protected override void LoadViewState(object savedState)
{
appointments = new AppointmentCollection();
appointments.LoadViewState(savedState);
}
示例站點中的代碼相當不錯。它實現了它應該擁有的所有接口,並且做得非常好。儘管在抽象代碼中包含了所有需要的代碼,但它們分開的地方並不重要,因爲在需要的地方沒有引用這些接口。
正在使用的集合類對它們沒有任何「特殊」,除了實現一些接口。框架不會自動調用這些方法。框架將然而調用我上面寫的重寫的方法,你需要實現,以便您的控件保存集合中的元素。只要你給他們打電話,一切都會奏效。
我已經使用所提供的解決方案上面的代碼是確定,但我是越來越例外 - 「StackOverflow的」酷:)問題是在aspx頁面添加幾個子項目重複性,並切換到設計視圖Visual Studio的設計視圖(Visual Studio只是重新啓動,沒人知道發生了什麼......)。
IEnumerator IEnumerable.GetEnumerator()
{
return ((IList)this).GetEnumerator();
}
所以,我想我理解了它只是改變了上述方法的這樣實施:
IEnumerator IEnumerable.GetEnumerator()
{
// return ((IList)this).GetEnumerator();
return this.GetEnumerator();
}
希望這會幫助別人像我一樣:)只是不丟失幾個小時得到它與設計師的工作VS
這是一個[更新的鏈接到第二個例子](http://blog.spontaneouspublicity.com/child-collections-in-asp-net-custom-controls) – 2012-07-05 18:13:47
謝謝你更新。 – Larsenal 2012-07-05 19:09:55