我自己写了个控件,定义了一个DataTable属性,但是非常奇怪的是,不管该属性在自定义的控件内部
如何改变,都不能够在提交后取回,该如何实现IStateManager呢?
public DataTable CheckboxSelectedInfo
{
get
{
m_dtCheckboxSelectedInfo = (DataTable)this.ViewState[CHECKBOX_KEYNAME];
return m_dtCheckboxSelectedInfo;
}
set
{
m_dtCheckboxSelectedInfo = value;
ViewState[CHECKBOX_KEYNAME] = m_dtCheckboxSelectedInfo;
ViewState.SetItemDirty(CHECKBOX_KEYNAME, true);
}
}
如何改变,都不能够在提交后取回,该如何实现IStateManager呢?
public DataTable CheckboxSelectedInfo
{
get
{
m_dtCheckboxSelectedInfo = (DataTable)this.ViewState[CHECKBOX_KEYNAME];
return m_dtCheckboxSelectedInfo;
}
set
{
m_dtCheckboxSelectedInfo = value;
ViewState[CHECKBOX_KEYNAME] = m_dtCheckboxSelectedInfo;
ViewState.SetItemDirty(CHECKBOX_KEYNAME, true);
}
}
而且断点也无法进入下面的几个方法,请各位大侠多多指教!public class CallBackControl : System.Web.UI.WebControls.WebControl,IStateManager
{
bool IStateManager.IsTrackingViewState
{
get
{
return ((IStateManager)this.ViewState).IsTrackingViewState;
}
}
/// <summary>
/// This method saves the state for a particular menuitem.</summary>
/// <res>This method returns a Triplet, where the first item is the result from the MenuItem's ViewState's
/// SaveViewState() method call. The second is the ViewState saved from the
/// subItems MenuItemCollection instance. The third item is the ViewState saved from the
/// RolesCollection.
/// </res>
/// <returns>A Triplet containing the ViewState and state of the subitems.</returns>
object IStateManager.SaveViewState()
{
if( (!((IDictionary)this.ViewState).Contains(CHECKBOX_KEYNAME)) || (this.ViewState.IsItemDirty(CHECKBOX_KEYNAME))) {
{
this.ViewState.Clear();
// Add the _message property to the StateBag.
this.ViewState.Add(CHECKBOX_KEYNAME, m_dtCheckboxSelectedInfo);
}
}
return ((IStateManager)this.ViewState).SaveViewState(); } /// <summary>
/// Loads the state upon postback back into the MenuItem.
/// </summary>
/// <param name="savedState">The state preserved from the SaveViewState() method in the
/// previous page invocation.</param>
void IStateManager.LoadViewState(object savedState)
{
m_dtCheckboxSelectedInfo = (DataTable)this.ViewState[CHECKBOX_KEYNAME];
if (savedState != null)
((IStateManager)this.ViewState).LoadViewState(savedState);
} /// <summary>
/// Starts tracking view state for the ViewState and subItems properties.
/// </summary>
void IStateManager.TrackViewState()
{
base.TrackViewState();
((IStateManager)this.ViewState).TrackViewState();
}
}
类的定义如上,去掉IStateManager也是一样的效果。
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;namespace MyControls
{
public class MyTableControl : WebControl
{
public DataTable MyData
{
get
{
object o = ViewState["MyData"];
return (DataTable)o;
}
set
{
ViewState["MyData"] = value;
}
}
}
}2. compile it into an assembly and copy it to the bin directory
E:\labs\>csc /t:library MyControls.cs3. TestDataControls.aspx:
<%@ Import Namespace="System.Data" %>
<%@ Register TagPrefix="cc" Assembly="MyControls" Namespace="MyControls" %>
<form runat="server">
<cc:MyTableControl id="mc" runat="server" />
<asp:Button id="btn" runat="server" Text="Click Me" OnClick="Button_Click" />
</form>
<script language="C#" runat="server">
void Page_Load(Object sender, EventArgs e)
{
DataTable dt = mc.MyData;
if (dt == null)
{
Response.Write("adding data<BR>");
dt = new DataTable();
dt.Columns.Add("Time", typeof(DateTime)); AddData(dt);
mc.MyData = dt;
} foreach (DataRow dr in dt.Rows)
{
Response.Write(dr["Time"] + "<BR>");
}
}void AddData(DataTable dt)
{
DataRow dr = dt.NewRow();
dr["Time"] = DateTime.Now;
dt.Rows.Add(dr);
}void Button_Click(Object sender, EventArgs e)
{
DataTable dt = mc.MyData;
AddData(dt);
}
</script>
现在有如下几个问题,很让人疑惑。
1)实现INamingContainer接口后,DataTable的属性值不再能够序列化??2)我上面的问题是在控件的Render方法中修改了DataTable中的记录行,但是修改部分不能够被viewstate记住,为什么??
在stateBag中我确信指定键值对应的DataTable已经发生了改变,可为什么修改的部分无法序列化呢?3)IStateManager的几个方法何时被调用,为什么我在DEBUG时跟踪不到呢?如IStateManager.TrackViewState()
public class MyTableControl : WebControl, INamingContainerstill works for me2. SaveViewState runs before Render, so it is too late to change state in Render3. you don't need to implement IStateManager if you derive from Control or WebControl
1)msdn关于StateBag的说明如下
“在控件处理生存期的任何阶段可以从此类读取,但是当控件正在呈现时不应该向此类写入。”2)WebControl中已经有了viewState属性,不需要再implement IStateManager
应该override IStateManager 的三个方法即可。有遇到相关问题的,可以发MAIL给我一起讨论。[email protected]