C# ASP.NET CheckBox_OnCheckedChanged 未按预期触发
C# ASP.NET CheckBox_OnCheckedChanged not firing as expected
我有一个问题,Checkbox_OnCheckedChanged
和 Dropdownlist_OnSelectedIndexChanged
事件都没有触发我后面的代码中的相关函数。
两个控件都绑定到 GridView
中的值。在从 UI 引发的第一个 OnCheckedChanged
或 OnSelectedIndexChanged
事件中,代码中的函数会毫无错误地触发,但是如果我刷新 UpdatePanel
,例如通过更改日期GridView
内的数据范围并因此加载或多或少的记录,不再调用 OnCheckedChanged
和 OnSelectedIndexChanged
函数,但是会出现 PostBack
。
我认为这些函数没有被调用,因为调用了重新绑定 GridView
的函数:
private void report_DateChanged(object sender, EventArgs e)
{
// Bind GridView here..
}
但是我不明白为什么会这样。
我有一个主页:
namespace ReportingSystemV2.Reporting
{
public partial class Reporting : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
// Attach to DateChanged Event on DateChange UserControl to Function
DateRangeSelect.dateChanged += new DateRangeSelect.dateChangedEventHandler(dtRgSel_dateChanged);
}
// Declare an event for the content pages
public event EventHandler reportDateChanged;
// Called on a date change event
protected void dtRgSel_dateChanged(object sender, DateChangedEventArgs e)
{
// Raise the event for content pages
if (reportDateChanged != null)
reportDateChanged(this, EventArgs.Empty);
}
}
这个 MasterPage
有一个 Control
用于选择我的日期范围..
我的控件ascx
代码的主要部分是:
<%--UpdatePanel to trigger datechange--%>
<asp:UpdatePanel runat="server" ID="UpdatePanelDateChanged" OnLoad="UpdatePanelDateChanged_Load" >
</asp:UpdatePanel>
<%--When the date changes in javascript a postback is called in the updatepanel--%>
__doPostBack('<%=UpdatePanelDateChanged.ClientID %>', null);
此控件后面的主要代码部分是:
// Declare a delegate
public delegate void dateChangedEventHandler(object sender, DateChangedEventArgs e);
// Declare an event for any pages that have the control
public event dateChangedEventHandler dateChanged;
protected virtual void OnDateChanged(DateChangedEventArgs e)
{
dateChangedEventHandler handler = dateChanged;
// Raise the event
if (handler != null)
handler(this, e);
}
protected void UpdatePanelDateChanged_Load(object sender, EventArgs e)
{
// Trigger the controls public event
OnDateChanged(new DateChangedEventArgs(DateTime.Parse(dates[0]), DateTime.Parse(dates[1])));
}
在我的内容页面中,我的 aspx
代码是:
<%@ Page Title="Downtime" Language="C#" MasterPageFile="~/Reporting/Reporting.Master" AutoEventWireup="true" CodeBehind="GensetDowntime.aspx.cs" Inherits="ReportingSystemV2.Reporting.GensetDowntime" %>
<%@ MasterType VirtualPath="~/Reporting/Reporting.Master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ReportingSubContent" runat="server">
<div class="container-fluid">
<asp:UpdatePanel ID="updPanelDowntime" runat="server">
<ContentTemplate>
<div class="row">
<div id="downtimeDiv" runat="server">
<asp:GridView ID="gridDowntime" runat="server" AutoGenerateColumns="False" GridLines="None" CssClass="table table-striped table-condensed"
OnRowDataBound="gridDowntime_RowDataBound"
OnSelectedIndexChanged="gridDowntime_SelectedIndexChanged"
DataKeyNames="ID,ID_Location,iddown,idup,dtdown,dtup,isexempt" EmptyDataText="No exempts in the selected period.">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TemplateField HeaderText="Exempt?">
<ItemTemplate>
<asp:DropDownList ID="ddlDowntimeExempt" AutoPostBack="true" runat="server"
OnSelectedIndexChanged="ddlDowntimeExempt_SelectedIndexChanged">
<asp:ListItem Value="-1">Unverified</asp:ListItem>
<asp:ListItem Value="1">Yes</asp:ListItem>
<asp:ListItem Value="0">No</asp:ListItem>
</asp:DropDownList>
<asp:Label ID="lblDowntimeExempt" runat="server" Text='<%#DataBinder.Eval(Container.DataItem,"isexempt")%>' Visible="false"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Exclude?">
<ItemTemplate>
<asp:CheckBox ID="chkDowntimeExclude" runat="server" Checked='<%#Convert.ToBoolean(Eval("ISEXCLUDED")) %>' OnCheckedChanged="chkDowntimeExclude_CheckedChanged" AutoPostBack="true"/>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowSelectButton="True" SelectText="Details" />
</Columns>
</asp:GridView>
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</asp:Content>
最后,我的内容页面背后的代码是:
protected void Page_PreInit(object sender, EventArgs e)
{
// Attach to UserControl Event on the MasterPage
Master.reportDateChanged += new EventHandler(report_DateChanged);
}
// If the user changes the date lets update the table
private void report_DateChanged(object sender, EventArgs e)
{
// Bind the gridview
}
// Function to be called when the ddl selectedindex is changed, only called on initial page load
protected void ddlDowntimeExempt_SelectedIndexChanged(object sender, EventArgs e)
{
// Applies the values selected in the exempt DDL to the database value
}
// function to be called when the checkbox checked state is change, again only called on the initial page loading - not after a postback
protected void chkDowntimeExclude_CheckedChanged(object sender, EventArgs e)
{
// When the Exclude checkbox is changed, update the Db
}
上面的代码显示了 control
使用 javascript 到 trigger
PostBack
在 UpdatePanel
上 triggers
public 事件在 Control
中。 MasterPage
有一个附加到 Control
事件的函数,这个 MasterPage
函数更新了一些值并触发了我的 ContentPage
可以访问的新事件。 ContentPage
将函数附加到此 MasterPage
事件,当 DateRange
更改时,它将加载 GridView
的数据并绑定它。
母版页在 "child" 页中控件的开头附加了额外的名称。您很可能希望下拉菜单有一个名称,但它会有一个不同的较长名称,例如 ctrl1$something$dropdown。
首先使用 Chrome 中的 inspect 或开发工具检查 ida 以确认这是您的问题。
我认为您缺少异步回发触发器。当更新面板部分回发时,它会发回整个页面,进行处理,然后 returns 仅发回更改的部分。可能在那个过程中,ID 发生了轻微的变化,然后漏掉了注册。 report_DateChanged
被触发很可能是因为它是页面上第一个实现 IPostBackEventHandler
的控件(因为复选框和下拉列表上的回发不再起作用)
要解决这个问题,请明确添加每个应该执行异步回发的控件到更新面板的触发器。像这样:
protected void gridDowntime_RowDataBound(object sender, GridViewRowEventArgs e)
{
DropDownList ddl = e.Row.FindControl("ddlDowntimeExempt") as DropDownList;
CheckBox cb = e.Row.FindControl("chkDowntimeExclude") as CheckBox;
ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(ddl);
ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(cb);
}
问题已解决,通过修改我的 DateRangeControl
中的代码,UpdatePanel
不再在所有 PostBacks
上触发,仅在被 __doPostBack('<%=UpdatePanelDateChanged.ClientID %>', null);
调用的那些上触发在我的 Javascript
.
protected void UpdatePanelDateChanged_Load(object sender, EventArgs e)
{
if (Request["__EVENTTARGET"] == UpdatePanelDateChanged.ClientID)
{
//Trigger Event
OnDateChanged(new DateChangedEventArgs(DateTime.Parse(dates[0]), DateTime.Parse(dates[1])));
}
}
解决方案参考:http://encosia.com/are-you-making-these-3-common-aspnet-ajax-mistakes/
我有一个问题,Checkbox_OnCheckedChanged
和 Dropdownlist_OnSelectedIndexChanged
事件都没有触发我后面的代码中的相关函数。
两个控件都绑定到 GridView
中的值。在从 UI 引发的第一个 OnCheckedChanged
或 OnSelectedIndexChanged
事件中,代码中的函数会毫无错误地触发,但是如果我刷新 UpdatePanel
,例如通过更改日期GridView
内的数据范围并因此加载或多或少的记录,不再调用 OnCheckedChanged
和 OnSelectedIndexChanged
函数,但是会出现 PostBack
。
我认为这些函数没有被调用,因为调用了重新绑定 GridView
的函数:
private void report_DateChanged(object sender, EventArgs e)
{
// Bind GridView here..
}
但是我不明白为什么会这样。
我有一个主页:
namespace ReportingSystemV2.Reporting
{
public partial class Reporting : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
// Attach to DateChanged Event on DateChange UserControl to Function
DateRangeSelect.dateChanged += new DateRangeSelect.dateChangedEventHandler(dtRgSel_dateChanged);
}
// Declare an event for the content pages
public event EventHandler reportDateChanged;
// Called on a date change event
protected void dtRgSel_dateChanged(object sender, DateChangedEventArgs e)
{
// Raise the event for content pages
if (reportDateChanged != null)
reportDateChanged(this, EventArgs.Empty);
}
}
这个 MasterPage
有一个 Control
用于选择我的日期范围..
我的控件ascx
代码的主要部分是:
<%--UpdatePanel to trigger datechange--%>
<asp:UpdatePanel runat="server" ID="UpdatePanelDateChanged" OnLoad="UpdatePanelDateChanged_Load" >
</asp:UpdatePanel>
<%--When the date changes in javascript a postback is called in the updatepanel--%>
__doPostBack('<%=UpdatePanelDateChanged.ClientID %>', null);
此控件后面的主要代码部分是:
// Declare a delegate
public delegate void dateChangedEventHandler(object sender, DateChangedEventArgs e);
// Declare an event for any pages that have the control
public event dateChangedEventHandler dateChanged;
protected virtual void OnDateChanged(DateChangedEventArgs e)
{
dateChangedEventHandler handler = dateChanged;
// Raise the event
if (handler != null)
handler(this, e);
}
protected void UpdatePanelDateChanged_Load(object sender, EventArgs e)
{
// Trigger the controls public event
OnDateChanged(new DateChangedEventArgs(DateTime.Parse(dates[0]), DateTime.Parse(dates[1])));
}
在我的内容页面中,我的 aspx
代码是:
<%@ Page Title="Downtime" Language="C#" MasterPageFile="~/Reporting/Reporting.Master" AutoEventWireup="true" CodeBehind="GensetDowntime.aspx.cs" Inherits="ReportingSystemV2.Reporting.GensetDowntime" %>
<%@ MasterType VirtualPath="~/Reporting/Reporting.Master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ReportingSubContent" runat="server">
<div class="container-fluid">
<asp:UpdatePanel ID="updPanelDowntime" runat="server">
<ContentTemplate>
<div class="row">
<div id="downtimeDiv" runat="server">
<asp:GridView ID="gridDowntime" runat="server" AutoGenerateColumns="False" GridLines="None" CssClass="table table-striped table-condensed"
OnRowDataBound="gridDowntime_RowDataBound"
OnSelectedIndexChanged="gridDowntime_SelectedIndexChanged"
DataKeyNames="ID,ID_Location,iddown,idup,dtdown,dtup,isexempt" EmptyDataText="No exempts in the selected period.">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TemplateField HeaderText="Exempt?">
<ItemTemplate>
<asp:DropDownList ID="ddlDowntimeExempt" AutoPostBack="true" runat="server"
OnSelectedIndexChanged="ddlDowntimeExempt_SelectedIndexChanged">
<asp:ListItem Value="-1">Unverified</asp:ListItem>
<asp:ListItem Value="1">Yes</asp:ListItem>
<asp:ListItem Value="0">No</asp:ListItem>
</asp:DropDownList>
<asp:Label ID="lblDowntimeExempt" runat="server" Text='<%#DataBinder.Eval(Container.DataItem,"isexempt")%>' Visible="false"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Exclude?">
<ItemTemplate>
<asp:CheckBox ID="chkDowntimeExclude" runat="server" Checked='<%#Convert.ToBoolean(Eval("ISEXCLUDED")) %>' OnCheckedChanged="chkDowntimeExclude_CheckedChanged" AutoPostBack="true"/>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowSelectButton="True" SelectText="Details" />
</Columns>
</asp:GridView>
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</asp:Content>
最后,我的内容页面背后的代码是:
protected void Page_PreInit(object sender, EventArgs e)
{
// Attach to UserControl Event on the MasterPage
Master.reportDateChanged += new EventHandler(report_DateChanged);
}
// If the user changes the date lets update the table
private void report_DateChanged(object sender, EventArgs e)
{
// Bind the gridview
}
// Function to be called when the ddl selectedindex is changed, only called on initial page load
protected void ddlDowntimeExempt_SelectedIndexChanged(object sender, EventArgs e)
{
// Applies the values selected in the exempt DDL to the database value
}
// function to be called when the checkbox checked state is change, again only called on the initial page loading - not after a postback
protected void chkDowntimeExclude_CheckedChanged(object sender, EventArgs e)
{
// When the Exclude checkbox is changed, update the Db
}
上面的代码显示了 control
使用 javascript 到 trigger
PostBack
在 UpdatePanel
上 triggers
public 事件在 Control
中。 MasterPage
有一个附加到 Control
事件的函数,这个 MasterPage
函数更新了一些值并触发了我的 ContentPage
可以访问的新事件。 ContentPage
将函数附加到此 MasterPage
事件,当 DateRange
更改时,它将加载 GridView
的数据并绑定它。
母版页在 "child" 页中控件的开头附加了额外的名称。您很可能希望下拉菜单有一个名称,但它会有一个不同的较长名称,例如 ctrl1$something$dropdown。
首先使用 Chrome 中的 inspect 或开发工具检查 ida 以确认这是您的问题。
我认为您缺少异步回发触发器。当更新面板部分回发时,它会发回整个页面,进行处理,然后 returns 仅发回更改的部分。可能在那个过程中,ID 发生了轻微的变化,然后漏掉了注册。 report_DateChanged
被触发很可能是因为它是页面上第一个实现 IPostBackEventHandler
的控件(因为复选框和下拉列表上的回发不再起作用)
要解决这个问题,请明确添加每个应该执行异步回发的控件到更新面板的触发器。像这样:
protected void gridDowntime_RowDataBound(object sender, GridViewRowEventArgs e)
{
DropDownList ddl = e.Row.FindControl("ddlDowntimeExempt") as DropDownList;
CheckBox cb = e.Row.FindControl("chkDowntimeExclude") as CheckBox;
ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(ddl);
ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(cb);
}
问题已解决,通过修改我的 DateRangeControl
中的代码,UpdatePanel
不再在所有 PostBacks
上触发,仅在被 __doPostBack('<%=UpdatePanelDateChanged.ClientID %>', null);
调用的那些上触发在我的 Javascript
.
protected void UpdatePanelDateChanged_Load(object sender, EventArgs e)
{
if (Request["__EVENTTARGET"] == UpdatePanelDateChanged.ClientID)
{
//Trigger Event
OnDateChanged(new DateChangedEventArgs(DateTime.Parse(dates[0]), DateTime.Parse(dates[1])));
}
}
解决方案参考:http://encosia.com/are-you-making-these-3-common-aspnet-ajax-mistakes/