描述了一个例子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