Привязка к событиям в динамически загружаемых пользовательских элементах управления - PullRequest
4 голосов
/ 21 июля 2011

Я создаю тестовый проект, чтобы продемонстрировать (для меня), как динамически загружать пользовательские элементы управления.Все работает, кроме проводки управления, чтобы уведомить родителя, что что-то случилось.Проблема связана со строкой, которая пытается соединить событие в пользовательском элементе управления с обработчиком событий на родительской странице.Событие «NotifyParentEvent» не отображается, и компилятор блокирует его (событие не определено в System.Web.UI.Control).Я пытался использовать UserControl вместо Control, но безрезультатно.

Control control = Page.LoadControl(SavedControlVirtualPath);
if (control != null)
{
    control.ID = control.GetType().Name;
>>>>>    control.NotifyParentEvent += new EventHandler(UserControlNotificationHandler);
    controlPlaceholder.Controls.Add(control);
}

Код для управления пользователем:

public partial class UserControls_WebUserControl1 : System.Web.UI.UserControl
{
    public event CommandEventHandler NotifyParentEvent;

    private void NotifyParent(string message)
    {
        if (NotifyParentEvent != null)
        {
            CommandEventArgs e = new CommandEventArgs("Control1 Action", message);
            NotifyParentEvent(this, e);
        }
    }
}

Страница родителей:

public partial class _Default : System.Web.UI.Page
{
    private string SavedControlVirtualPath
    {
        get {return (ViewState["savedControlPath"] == null || (string)ViewState["savedControlPath"] == string.Empty) 
                ? null : (string)ViewState["savedControlPath"]; }
        set { ViewState["savedControlPath"] = value; }
    }

    private void ReloadControl()
    {
        controlPlaceholder.Controls.Clear();
        if (SavedControlVirtualPath != null)
        {
            Control control = Page.LoadControl(SavedControlVirtualPath);
            if (control != null)
            {
                // Gives the control a unique ID. It is important to ensure
                // the page working properly. Here we use control.GetType().Name
                // as the ID.
                control.ID = control.GetType().Name;
                control.NotifyParentEvent += new EventHandler(UserControlNotificationHandler); <== THIS LINE WON'T COMPILE
                controlPlaceholder.Controls.Add(control);
            }
        }
    }

    private void UserControlNotificationHandler(object sender, CommandEventArgs e)
    {
        //  ???
    }

    protected void Page_Init(object sender, EventArgs e)
    {
        lblLastEvent.Text += "Page_Init<br />";
        LoadUserControls();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        lblLastEvent.Text += string.Format("{0} on main page<br />", (this.IsPostBack) ? "Postback" : "Page_Load");
        ReloadControl();
    }

    protected void rblControlSelector_Changed(object sender, EventArgs e)
    {
        lblLastEvent.Text += "rblControlSelector_Changed<br />";
        LoadUserControls();
    }

    private void LoadUserControls()
    {
        Label lbl = new Label();
        controlPlaceholder.Controls.Clear();
        switch (rblControlSelector.SelectedValue)
        {
            case "0":
                lblLastEvent.Text = "Unload/Clear<br />";
                SavedControlVirtualPath = "";
                break;

            case "1":
                lblLastEvent.Text += "Adding control #1<br />";
                SavedControlVirtualPath = "~/UserControls/WebUserControl1.ascx";
                break;

            case "2":
                lblLastEvent.Text += "Adding control #2<br />";
                SavedControlVirtualPath = "~/UserControls/WebUserControl2.ascx";
                break;

            case "3":
                lblLastEvent.Text += "Adding control #3<br />";
                SavedControlVirtualPath = "~/UserControls/WebUserControl3.ascx";
                break;

        }
        if (!string.IsNullOrEmpty(SavedControlVirtualPath))
        {
            ReloadControl();
        }
    }
}

Ответы [ 2 ]

4 голосов
/ 21 июля 2011

Опция 1

Вам необходимо привести ваш элемент управления к типу, который реализует событие NotifyParentEvent, чтобы присоединить обработчик события.В основном, в вашем методе ReloadControl замените эту строку кода:

control.NotifyParentEvent += new EventHandler(UserControlNotificationHandler);

следующим:

if(control is UserControls_WebUserControl1) 
{
    (control as UserControls_WebUserControl1).NotifyParentEvent += new EventHandler(UserControlNotificationHandler);
}

Опция 2

Более общий подход заключается в создании интерфейса и проверке того, реализует ли динамический элемент управления этот интерфейс.

Создание интерфейса:

interface INotifyParent
{
    event CommandEventHandler NotifyParentEvent;
}

Реализация интерфейса:

public partial class UserControls_WebUserControl1 : System.Web.UI.UserControl, INotifyParent
{
    public event CommandEventHandler NotifyParentEvent;

    private void NotifyParent(string message)
    {
        if (NotifyParentEvent != null)
        {
            CommandEventArgs e = new CommandEventArgs("Control1 Action", message);
            NotifyParentEvent(this, e);
        }
    }
}

Проверьте, реализует ли интерфейс динамическое управление:

if(control is INotifyParent) 
{
    (control as INotifyParent).NotifyParentEvent += new EventHandler(UserControlNotificationHandler);
}
0 голосов
/ 21 июля 2011

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

Я не уверен, что это сработает, но попробуйте использовать приведение с использованием динамического типа, а не Control.

ака

dynamic control = Page.LoadControl(SavedControlVirtualPath);

В этом коде предполагается, что вы используете .NET 4.0

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...