这是关于 ASP.NET、ViewState、UserControls 和丢失我的属性值的问题。我知道,这是一个经典的问题,尽管我已经在这里和谷歌上搜索了这个问题的解决方案,但我还没有成功。相反,我测试不同的东西越多,我对它的理解似乎就越少。
除此之外,我正在使用 ext.net 和他们所谓的 DirectMethod,但我认为这与这个问题没有太大关系。我有很多问题。
用户控件
我有一个用户控件 Customers.ascx,其中包含一些属性。 “最”重要的是_CustomerId。 _CustomerId 在 ext.net 的“DirectMethod”中的代码隐藏中设置,如下所示(下面的代码来自页面 Customers.aspx):
[DirectMethod]
public void SetCustomer()
{
RowSelectionModel sm = GridPanel2.SelectionModel.Primary as RowSelectionModel;
if (sm.SelectedRow != null)
{
uint customerId = uint.Parse(sm.SelectedRow.RecordID);
customer_modify._CustomerId = customerId;
}
}
“customer_modify”是 Customers.aspx 中定义的 UserControl 的实例(页面,而不是 UserControl):
<asp:Content ID="Content2" ContentPlaceHolderID="CPH_center" runat="server">
<CP:Customer ID="customer_modify" runat="server" _IsCreateMode="false" ViewStateMode="Enabled" />
</asp:Content>
在该页面 Customers.aspx 中,我有 ext.net GridPanel,它列出了客户,当我单击 GridPanel 中的行时,将执行(直接)方法 SetCustomer。
正如您在 SetCustomer 方法中看到的,属性“_CustomerId”已使用 uint 进行更新,因此让我们看一下 UserControl 中的属性:
public uint _CustomerId
{
get
{
object o = ViewState["_CustomerId"];
if (o == null)
return 0;
return (uint)o;
}
set
{
object o = ViewState["_CustomerId"];
ViewState["_CustomerId"] = value;
SetCustomer();
}
}
如您所见,我正在使用 ViewState-thingie,我希望状态(即属性的值)能够被记住。他们不是。
当我第一次单击 GridPanel 中的行时,我可以看到(通过破坏)
ViewState["_CustomerId"] == null
没问题。此后我看到 _CustomerId 的 setter 被执行,并且 ViewState["_CustomerId"]
被分配了 RecordID(uint)。
我现在单击 GridPanel 中的另一行,然后再次执行 SetCustomer 方法。我闯入 _CustomerId 的 setter 并在分配它之前查看
ViewState["_CustomerId"]
是什么。 它是 0,但我希望它是上一个单击行的值。
为什么是0?我错过了什么?
还有:
我实际上在页面上有两个用户控件,另一个名为“customer_create”:
<ext:Window
ID="Window_CreateNewCustomer"
runat="server"
Icon="New"
Title="Skapa ny kund"
Hidden="true"
Width="480"
Height="370"
Modal="true">
<Content>
<CP:Customer ID="customer_create" runat="server" Title="Skapa ny kund" _IsCreateMode="true" />
</Content>
</ext:Window>
令我不安的是,每次我单击 GridPanel 中的一行时,UserControl 中的 Page_Load 都会执行两次,即使我只在 SetCustomer() 方法中更新其中一个。
这是为什么?
ViewState
被序列化、加密并作为隐藏表单字段发送到客户端,以便在触发表单提交时可以重新构建它。 [DirectMethod]
不进行表单提交(它作为 AJAX 调用进行处理),因此它既不能读取也不能写入 ViewState
数据,除非使用 ViewStateMode.Enabled
特别请求此数据的往返。
对于任何指向表单的给定请求,
Load
事件将从页面触发,从而由页面上在页面处理生命周期的预期阶段订阅该事件的每个用户控件接收 -无论是一个 UserControl
的两个实例还是两个不同的 UserControl
,它都是两个订阅者,因此有两个调用(每个实例一个)。