我有一个页面(company.aspx),当您单击页面上的按钮时,按钮单击事件(btnShowDeptsUserControl_Click)会动态创建用户控件并添加到占位符。页面重新加载并显示用户控件。这很好。
我遇到的问题是,当我单击用户控件本身上的按钮时,不会触发btnEmailDepts_Click事件,但会重新加载主页面(company.aspx)。
我已经读过,解决此问题的一种方法是在Page_Init中创建动态用户控件,但我从主页按钮单击创建用户控件。另外,我没有像通常那样在主页面后面的代码中声明用户控件,但确实有一个放置用户控件的放置器。
我还读过你可以在主页面上添加一个委托给用户控制按钮点击,但是这个例子似乎有这么多必要的代码,我认为必须有更好的方法。< / p>
以下是相关的代码段:
company.aspx:
<asp:Button id="btnShowDeptsUserControl" runat="server" OnClick="btnShowDeptsUserControl_Click">Show Depts</asp:Button>
<asp:PlaceHolder ID="phUserControls" runat="server"></asp:PlaceHolder>
company.aspx.cs:
protected void btnShowDeptsUserControl_Click(object sender, EventArgs e)
{
CreateDeptsUserControl();
}
private void CreateDeptsUserControl()
{
phUserControls.Controls.Clear();
var uc = (UserControl)LoadControl("~/controls/ucDepartments.ascx");
phUserControls.Controls.Add(uc);
}
ucDepartments.ascx:
<asp:Button ID="btnEmailDepts" runat="server" Text="Send Email" OnClick="btnEmailDepts_Click" />
ucDepartments.ascx.cs:
protected void btnEmailDepts_Click(object sender, EventArgs e)
{
EmailDepts(); // breakpoint here is never hit
}
private void EmailDepts()
{
// do something
}
答案 0 :(得分:1)
如果您阅读MSDN,您会注意到:
但是,添加的控件无法跟上回发数据处理。对于参与回发数据处理(包括验证)的附加控件,必须在Init事件中而不是在Load事件中添加控件。
您正在click
事件中添加您的控件,该事件发生在init
和load
事件之后,因此回发将无效。
您可以在CreateDeptsUserControl
事件中调用ini
功能,但在那里您必须检测自己是否点击了btnShowDeptsUserControl
。这并不难,您需要检查提交的值集合,看看是否有btnShowDeptsUserControl
的项目。
答案 1 :(得分:1)
只是想发布我做的工作。 Racil Hilan的回答帮助我找到了这个解决方案。我取消了动态用户控件,并使用了aspx中更常见的声明用户控件,但将其设置为Visible =&#34; False&#34;默认情况下。
请注意,主页按钮事件为空。另请注意,用户控件Page_Load事件为空。所有检查都在用户控件OnInit事件中完成,该事件在每个主页面加载时执行。
在用户控件OnInit事件中,我有几个保护条件,检查EVENTTARGET(如果有)导致页面/用户控件加载。如果EVENTTARGET(控件ID)是主页按钮的那个,则执行将继续并将调用LoadSomeData()以及设置用户控件Visible = true。否则,如果任一保护条件的计算结果为false,则退出并且不会加载用户控件,因此不会浪费数据库/服务调用。
company.aspx:
<asp:Button id="btnShowDeptsUserControl" runat="server" OnClick="btnShowDeptsUserControl_Click">Show Depts</asp:Button>
<uc1:ucDepartments ID="ucDepartments" runat="server" Visible="False" />
company.aspx.cs:
protected void btnShowDeptsUserControl_Click(object sender, EventArgs e)
{
// empty, just need the event for inspection later in user control OnInit event.
}
ucDepartments.ascx:
<asp:Button ID="btnEmailDepts" runat="server" Text="Send Email" OnClick="btnEmailDepts_Click" />
ucDepartments.ascx.cs:
protected override void OnInit(EventArgs e)
{
if (string.IsNullOrWhiteSpace(Request.Params["__EVENTTARGET"]))
return;
var controlName = Request.Params["__EVENTTARGET"];
if (controlName != "btnShowDeptsUserControl")
return;
LoadSomeData(); // call method to load the user control
this.Visible = true;
}
protected void Page_Load(object sender, EventArgs e)
{
// empty
}
private void LoadSomeData()
{
// get data from database
// load table / gridview / etc
// make service call
}
protected void btnEmailDepts_Click(object sender, EventArgs e)
{
EmailDepts(); // this event is now executed when the button is clicked
}
private void EmailDepts()
{
// do something
}
包含在回发后滚动到用户控件的jquery的变体:
在主页面按钮单击事件中,您还可以执行类似以下操作:将隐藏的var设置为可在主页doc上检查的值,以便执行一些jquery操作,例如将用户控件滚动到视图中,如果它远在页面下方(我在当前任务中实际执行的操作)。
在单击主页面按钮后,这不仅会将现在加载的用户控件滚动到视图中,还会注意setupDepts()中的代码。我隐藏了执行回发的asp按钮来加载用户控件,并显示一个常规的html按钮。它们看起来都一样(都说Show Depts),但点击时常规的html按钮会触发jquery来切换包含用户控件的div关闭,再次点击,它会打开,再次点击它会关闭等等。
这样,您只需在单击主页按钮时加载一次用户控件(使db / service调用一次),然后可以在随后单击备用按钮时切换显示或隐藏它。这种方法可以与多个按钮或链接一起使用,只要它们都具有相同的类ID。例如,您可能在页面顶部有一个Show Depts按钮/链接,在页面底部有另一个按钮/链接,这是我当前任务中的情况。
company.aspx:
<asp:Button id="btnShowDeptsUserControl" runat="server" class="btnShowDepts" OnClick="btnShowDeptsUserControl_Click">Show Depts</asp:Button>
<button class="btnToggleDepts" style="display: none;">Show Depts</button>
<div id="divShowDepts" style="display: none;">
<asp:HiddenField runat="server" id="hdnShowDepts"/>
<uc1:ucDepartments ID="ucDepartments" runat="server" Visible="False" />
</div>
<script language="javascript" type="text/javascript">
$(function () {
toggleDeptsUserControl();
if ($('#<%=hdnShowDepts.ClientID%>').val() === "show")
setupDepts();
});
function setupDepts() {
$('.btnShowDeptsUserControl').hide();
$('.btnToggleDeptsUserControl').show();
scrollToDepts();
}
function scrollToDepts() {
$('#divShowDepts').toggle(700, function () {
if ($(this).is(":visible")) {
$('html, body').animate({ scrollTop: ($(this).offset().top) }, 'slow');
}
});
}
function toggleDeptsUserControl() {
$('.btnToggleDeptsUserControl').on('click', function (event) {
event.preventDefault();
scrollToDepts();
});
}
</script>
company.aspx.cs:
protected void btnShowDeptsUserControl_Click(object sender, EventArgs e)
{
hdnShowDepts.Value = "show";
}