2008-09-18 5 views
3

Что лучшие практики для общения события от UserControl для родительского контроля/страницы я хочу сделать что-то похожее на это:Eventhandling в ASCX UserControls

MyPage.aspx: 
<asp:Content ID="Content1" ContentPlaceHolderID="MainContentPlaceholder" runat="server"> 
    <uc1:MyUserControl ID="MyUserControl1" runat="server" 
    OnSomeEvent="MyUserControl_OnSomeEvent" /> 

MyUserControl.ascx.cs: 
public partial class MyUserControl: UserControl 
{ 
    public event EventHandler SomeEvent; 
.... 
    private void OnSomething() 
    { 
     if (SomeEvent!= null) 
      SomeEvent(this, EventArgs.Empty); 
    } 

Вопрос в том, что лучше практика?

ответ

6

Вам нужно создать событие в элементе управления, на котором подписывается родительский. См. Пример OdeToCode.

Вот статья ради долголетия:

Некоторых пользовательских элементов управления является полностью самодостаточным, например, пользовательским элемент управления отображением текущих котировок акций не должен взаимодействовать с любым другим контентом на странице. Другие элементы управления пользователя будут содержать кнопки для отправки назад. Хотя можно подписаться на событие нажатия кнопки с содержащейся страницы, это приведет к нарушению некоторых объектно-ориентированных правил инкапсуляции. Лучшая идея - опубликовать событие в пользовательском элементе управления, чтобы позволить любым заинтересованным сторонам обрабатывать событие.

Этот метод обычно называют «пузырьковым событием», поскольку событие может продолжать проходить через уровни, начиная с нижнего (пользовательское управление) и, возможно, достигая верхнего уровня (страницы), как пузырь, поднимающийся вверх шампанское.

Для начала давайте создадим пользовательский элемент управления с присоединенной кнопкой.

<%@ Control Language="c#" AutoEventWireup="false" 
    Codebehind="WebUserControl1.ascx.cs" 
    Inherits="aspnet.eventbubble.WebUserControl1" 
    TargetSchema="http://schemas.microsoft.com/intellisense/ie5" 
%> 
<asp:Panel id="Panel1" runat="server" Width="128px" Height="96px"> 
    WebUserControl1 
    <asp:Button id="Button1" Text="Button" runat="server"/> 
</asp:Panel> 

Код для пользовательского элемента управления выглядит следующим образом.

public class WebUserControl1 : System.Web.UI.UserControl 
{ 
    protected System.Web.UI.WebControls.Button Button1; 
    protected System.Web.UI.WebControls.Panel Panel1; 

    private void Page_Load(object sender, System.EventArgs e) 
    { 
     Response.Write("WebUserControl1 :: Page_Load <BR>"); 
    } 

    private void Button1_Click(object sender, System.EventArgs e) 
    { 
     Response.Write("WebUserControl1 :: Begin Button1_Click <BR>"); 
     OnBubbleClick(e); 
     Response.Write("WebUserControl1 :: End Button1_Click <BR>"); 
    } 

    public event EventHandler BubbleClick; 

    protected void OnBubbleClick(EventArgs e) 
    { 
     if(BubbleClick != null) 
     { 
     BubbleClick(this, e); 
     } 
    }   

    #region Web Form Designer generated code 
    override protected void OnInit(EventArgs e) 
    { 
     InitializeComponent(); 
     base.OnInit(e); 
    } 

    private void InitializeComponent() 
    { 
     this.Button1.Click += new System.EventHandler(this.Button1_Click); 
     this.Load += new System.EventHandler(this.Page_Load); 

    } 
    #endregion 

} 

Пользовательский элемент управления указывает публичное событие (BubbleClick), которое объявляет делегат. Любой, кто интересуется событием BubbleClick, может добавить метод EventHandler для выполнения при возникновении события - точно так же, как пользовательский элемент управления добавляет EventHandler, когда кнопка запускает событие Click.

В событии OnBubbleClick мы сначала проверяем, не привязаны ли какие-либо события к событию (BubbleClick! = Null), затем мы можем вызвать все методы обработки событий, вызвав BubbleClick, пройдя через параметр EventArgs и установив пользователя control (this) в качестве отправителя события. Обратите внимание, что мы также используем Response.Write, чтобы следить за потоком исполнения.

Теперь страница ASPX теперь может использовать пользовательский элемент управления.

<%@ Register TagPrefix="ksa" 
    TagName="BubbleControl" 
    Src="WebUserControl1.ascx" 
%> 
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" 
    AutoEventWireup="false" Inherits="aspnet.eventbubble.WebForm1" 
%> 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > 
<HTML> 
    <HEAD> 
     <title>WebForm1</title> 
    </HEAD> 
    <body MS_POSITIONING="GridLayout"> 
     <form id="Form1" method="post" runat="server"> 
      <ksa:BubbleControl id="BubbleControl" runat="server" /> 
     </form> 
    </body> 
</HTML> 

В коде для страницы.

public class WebForm1 : System.Web.UI.Page 
{ 
    protected WebUserControl1 BubbleControl; 

    private void Page_Load(object sender, System.EventArgs e) 
    { 
     Response.Write("WebForm1 :: Page_Load <BR>"); 
    } 

    #region Web Form Designer generated code 
    override protected void OnInit(EventArgs e) 
    { 
     InitializeComponent(); 
     base.OnInit(e); 
    } 

    private void InitializeComponent() 
    {  
     this.Load += new System.EventHandler(this.Page_Load); 
     BubbleControl.BubbleClick += new EventHandler(WebForm1_BubbleClick); 
    } 
    #endregion 

    private void WebForm1_BubbleClick(object sender, EventArgs e) 
    { 
     Response.Write("WebForm1 :: WebForm1_BubbleClick from " + 
        sender.GetType().ToString() + "<BR>");   
    } 
} 

Обратите внимание, что родительская страница просто должна добавить обработчик события во время метода InitializeComponent. Когда мы получим событие, мы снова будем использовать Reponse.Write, чтобы следить за потоком исполнения.

Одно предупреждение: если в любое время события таинственно прекратили работу, проверьте метод InitializeComponent, чтобы убедиться, что дизайнер не удалил какой-либо из кодов, добавляющих обработчики событий.

2

1) Объявляет Открытое событие в элементе управления пользователя

2) выдать RaiseEvent, где соответствующий внутри пользовательского элемента управления

3) В случае инициализации родительской страницы, используйте AddHandler, чтобы назначить контроль .весь на процедуру обработки, которую вы хотите использовать

Простой как это!

0

Я нашел такое же решение на OdeToCode, что и @lordscarlet, связанное с его принятым решением. Проблема в том, что мне нужно решение в VB, а не в C#. Это не переводилось отлично. В частности, проверка того, что обработчик события имеет значение null в OnBubbleClick, не работал в VB, потому что компилятор думал, что я пытаюсь вызвать событие, и выдавал ошибку, в которой говорилось: «... нельзя вызывать напрямую. Используйте« RaiseEvent », чтобы поднять мероприятие ». Итак, вот перевод VB для решения OdeToCode с помощью элемента управления CountryDropDownList.

Для начала создадим пользовательский элемент управления с выпадающим списком.

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="CountryDropDownList.ascx.vb" Inherits="CountryDropDownList" %> 
<asp:DropDownList runat="server" ID="ddlCountryList" OnSelectedIndexChanged="ddlCountryList_SelectedIndexChanged" AutoPostBack="true"> 
    <asp:ListItem Value=""></asp:ListItem> 
    <asp:ListItem value="US">United States</asp:ListItem> 
    <asp:ListItem value="AF">Afghanistan</asp:ListItem> 
    <asp:ListItem value="AL">Albania</asp:ListItem> 
</asp:DropDownList> 

Код для пользовательского элемента управления выглядит следующим образом.

Public Class CountryDropDownList 
    Inherits System.Web.UI.UserControl 
    Public Event SelectedCountryChanged As EventHandler 

    Protected Sub ddlCountryList_SelectedIndexChanged(sender As Object, e As EventArgs) 
     ' bubble the event up to the parent 
     RaiseEvent SelectedCountryChanged(Me, e) 
    End Sub 
End Class 

Теперь страница ASPX теперь позволяет пользователю управлять пользователем.

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="UpdateProfile.aspx.vb" Inherits="UpdateProfile" MaintainScrollPositionOnPostback="true" %> 
<%@ Register Src="~/UserControls/CountryDropDownList.ascx" TagPrefix="SO" TagName="ucCountryDropDownList" %> 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > 
<HTML> 
    <HEAD> 
     <title>WebForm1</title> 
    </HEAD> 
    <body> 
     <form id="Form1" method="post" runat="server"> 
      <SO:ucCountryDropDownList id="ddlCountry" runat="server" /> 
     </form> 
    </body> 
</HTML> 

В коде позади на странице:

Protected Sub OnSelectedCountryChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ddlCountry.SelectedCountryChanged 
    ' add your code here 
End Sub 
Смежные вопросы