[英]Cancel all events from Page_Load
編輯:對於那些來這里遇到類似問題的人,現在我知道這是一個糟糕的想法。
嗨,我有這樣的事情:
bool preventEvents;
protected void Page_Load(object sender, eventargs e)
{
preventEvents = doSomeValidation();
}
protected void Button1_Click(object sender, EventArgs e)
{
if (preventEvents) return;
// ...
}
protected void Repeater1_DataBound(object sender, EventArgs e)
{
if (preventEvents) return;
// ...
}
問題是頁面上有很多事件。
是否可以取消所有其他事件而無需在每個方法上添加“ if”行?
編輯:
得到了一些有趣的答案(感謝大家),但不是我想要的東西,也許我應該更具體:
給定某些條件,是否可以跳過Page_Load之后的所有事件並僅跳轉到呈現,而無需手動刪除/映射每個事件?
問題是頁面上有很多事件。
是的,這是一個問題。 同一頁面中的許多事件都會降低性能(這意味着您要存儲大量狀態並執行許多http請求)。 它們不利於可維護性(同一類中有很多代碼混雜在一起)。 它們不利於可測試性(眾所周知,asp.net事件很難進行單元測試)。 而且它們不利於可用性(無法添加書簽,不能與“后退”按鈕一起使用,可能導致重復發布)。
解決方案是使用Post / Redirect / Get模式 。 不利之處在於,這將意味着重新考慮應用程序設計的各個部分,但最終,您將擁有一個性能更好,更快且易於維護的應用程序。
請小心選擇跳過事件處理,這是您的計划。 奇數是您當前的頁面狀態是多個事件的結果,不處理事件可能會破壞頁面的預期狀態。
我有同樣的問題。 我當前的方法是覆蓋RaisePostBackEvent方法並檢查“ cancelEvents”標志。 RaisePostBackEvent負責將回發路由到其發起者。
我仍在測試它的不良副作用-如果有人有這個想法的經驗,我將不勝感激。
使用自定義驗證器,然后它就屬於您的標准無效支票。
您可以使用以下內容,但費用幾乎相同
Protected void Page_Load() {
if (preventEvents) {
textbox1.TextChanged -= textbox1_TextChanged;
dropdownlist1.SelectedIndexChanged -= dropdownlist1_SelectedIndexChanged;
// and so on
}
}
您可以在事件處理程序上創建包裝委托,如下所示:
private EventHandler CreateCancelableEventHandler(EventHandler handler)
{
return (sender, e) =>
{
if (!preventEvents)
{
handler.Invoke(sender, e);
}
};
}
該解決方案的缺點是您將需要在代碼隱藏中而不是在標記中預訂所有事件。 訂閱的用法如下:
button1.OnClick += CreateCancelableEventHandler(Button1_OnClick);
如何在頁面指令中將AutoEventWireup設置為False? 即。
<%@ Page Language="C#" AutoEventWireup="false" Inherits="MyWebApp.EventWireUpFalse" %>
這樣,只有在OnInit中顯式“連接”的事件才會被調用。 這將使您更好地控制頁面生命周期中引發的事件。
您不能“跳到”渲染,因為ProcessRequestMain
中沒有任何條件允許它。 唯一的選擇是破解相關控件的事件處理程序。
protected void Page_Load(object sender, EventArgs e) {
// DON'T DO THIS!! Years from now, some poor soul tasked with
// debugging your code will tear their hair out, until they
// discover the unholy magic you have conjured herein. Keep in mind
// this is the 21st century and this person knows where you live.
//
// Seriously, just use the validation built in to ASP.NET.
if ("true".Equals(Request.QueryString["disable_events"], StringComparison.OrdinalIgnoreCase)) {
// disable *all* event handlers on button controls
foreach (var b in this.GetControlDescendants().OfType<Button>()) {
var eventList = (EventHandlerList) typeof (Control)
.GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(b, null);
typeof (EventHandlerList)
.GetField("head", BindingFlags.Instance | BindingFlags.NonPublic)
.SetValue(eventList, null);
}
}
}
實用程序擴展方法的完整性:
/// <summary>
/// Performs a breadth-first traversal of a control's control tree. Unlike
/// FindControl, this method does not descend into controls that have not
/// called EnsureChildControls yet.
/// </summary>
/// <returns>Enumerable of the visited controls.</returns>
public static IEnumerable<Control> GetControlDescendants(this Control parent) {
// Don't force execution of EnsureChildControls
if (!parent.HasControls()) yield break;
foreach (Control child in parent.Controls) {
yield return child;
}
foreach (Control child in parent.Controls) {
foreach (var descendant in child.GetControlDescendants()) {
yield return descendant;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.