我需要向面板添加多个用户控件,以便进一步编辑包含的数据。我的用户控件包含一些面板,下拉列表和输入元素,这些面板填充在用户控件的Page_Load事件中。
protected void Page_Load(object sender, EventArgs e)
{
// populate comparer ddl from enum
string[] enumNames = Enum.GetNames(typeof (SearchComparision));
var al = new ArrayList();
for (int i = 0; i < enumNames.Length; i++)
al.Add(new {Value = i, Name = enumNames[i]});
scOperatorSelection.DataValueField = "Value";
scOperatorSelection.DataTextField = "Name";
...
要显示的数据作为字段添加到用户控件,在Page_Load上面定义。事件的签名如下:
public delegate void ControlStateChanged(object sender, SearchCriteriaEventArgs eventArgs);
public event ControlStateChanged ItemUpdated;
public event ControlStateChanged ItemRemoved;
public event ControlStateChanged ItemAdded;
用户控件上的更新按钮会触发以下方法:
protected void UpdateCriteria(object sender, EventArgs e)
{
var searchCritCtl = (SearchCriteria) sender;
var scEArgs = new SearchCriteriaEventArgs
{
TargetCriteria = searchCritCtl.CurrentCriteria.CriteriaId,
SearchComparision = ParseCurrentComparer(searchCritCtl.scOperatorSelection.SelectedValue),
SearchField = searchCritCtl.scFieldSelection.SelectedValue,
SearchValue = searchCritCtl.scFilterValue.Text,
ClickTarget = SearchCriteriaClickTarget.Update
};
if (ItemUpdated != null)
ItemUpdated(this, scEArgs);
}
呈现页面从存储后端获取数据对象,并将其显示在其Page_Load事件中。这是它开始变得棘手的一点:我连接到自定义事件!
int idIt = 0;
foreach (var item in _currentSearch.Items)
{
SearchCriteria sc = (SearchCriteria)LoadControl("~/content/controls/SearchCriteria.ascx");
sc.ID = "scDispCtl_" + idIt;
sc.ControlMode = SearchCriteriaMode.Display;
sc.CurrentCriteria = item;
sc.ItemUpdated += CriteriaUpdated;
sc.ItemRemoved += CriteriaRemoved;
pnlDisplayCrit.Controls.Add(sc);
idIt++;
}
首次渲染页面时,一切都显示正常,我得到了所有数据。当我触发更新事件时,用户控件事件被正确触发,但用户控件的所有字段和控件都是 NULL 。经过一些研究后,我不得不得出结论,在控件初始化之前事件被触发了......
有什么方法可以防止这种行为/以某种方式覆盖页面生命周期?我无法在页面的Init-event中初始化用户控件,因为我必须访问Session-Store(未在Page_Init中初始化)。
欢迎任何建议......
修改
由于我们在存储后端保存所有标准信息(包括条件计数),并且该商店使用会话中的用户ID,因此我们无法使用Page_Init ...仅用于说明
编辑#2:
我设法解决了一些问题。由于我现在使用简单类型,我能够以声明方式绑定所有数据(使用带有简单ItemTemplate的转发器)。它受控制,它们以正确的方式呈现。在Postback上,所有数据都会反弹到用户控件,数据在OnDataBinding和OnLoad事件中可用,一切看起来都很好。
但是一旦它进入真实事件(绑定到用户控件的按钮控件),所有字段值都会以某种方式丢失...
有人知道,在数据绑定/加载后页面生命周期如何继续处理请求?我对这个问题发疯了......
答案 0 :(得分:0)
动态控制可能是一场噩梦。诀窍是确保重新绑定回发上的所有内容。
答案 1 :(得分:0)
我想出了一个解决方案;)
如果我在usercontrol内的按钮上使用OnCommand事件,我可以传递一个CommandArgument。现在我将集合标识符绑定到按钮的CommandArgument参数,这使我能够处理usercontrol中的所有回发。
<asp:Button ID="scUpdate"
runat="server"
Text="Update"
OnCommand="HandleCommand"
CommandName="update"
CommandArgument='<%# CriteriaId %>' />
此声明在整个回发中保留CriteriaId(一个Guid),并使我能够识别底层集合上的修改条目(在页面上管理)。以下代码段显示了如何触发订阅页面的事件。
scEArgs = new SearchCriteriaEventArgs
{
TargetCriteria = new Guid(e.CommandArgument.ToString()),
SearchComparision = ParseCurrentComparer(),
SearchField = scFieldSelection.SelectedValue,
SearchValue = scFilterValue.Text,
ClickTarget = SearchCriteriaClickTarget.Update
};
if (ItemUpdated != null)
ItemUpdated(this, scEArgs);
也许这个答案可以帮助某人,所以我会发布它;)