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

Мне очень трудно подписываться на события в динамически загруженном пользовательском элементе управления. Вероятно, проще всего просто посмотреть на код, с которым у меня проблемы. Любая помощь с благодарностью.

На родительской странице я использую этот метод для динамической загрузки пользовательских элементов управления.

 private void LoadMyUserControl(string controlName)
 {
      parent.Controls.Clear();

      // Load the user Control
      UserControl MyControl = (UserControl)LoadControl(ControlName);

      string userControlID = controlName.Split('.')[0];
      MyControl.ID = userControlID.Replace("/","").Replace("~", "");
      Type ucType = MyControl.GetType();

      // Set misc parameters
      PropertyInfo myProp = ucType.GetProperty("MyProp");
      myProp.SetValue(MyControl, "MyVal", null);

      //Dynamically subscribe to user control event
      Type objectType = MyControl.GetType();
      EventInfo objectEventInfo = objectType.GetEvent("updateParent");
      Type objectEventHandlerType = objectEventInfo.EventHandlerType;            
      MethodInfo mi = this.GetType().GetMethod("HandledEvent");
      Delegate del = Delegate.CreateDelegate(objectEventHandlerType, this, mi);
      objectEventInfo.AddEventHandler(this, del);

  }

  public void HandledEvent (Object sender, EventArgs e)
  {

  }

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

  public partial class MyUserControl1 : System.Web.UI.UserControl
  {
         public int MyProp { get; set; }
         public event EventHandler updateParent;
  }

Я получаю сообщение об ошибке в строке ObjectEventInfo.AddEventHandler, в которой указано, что «объект не соответствует типу цели».

Еще раз спасибо за вашу помощь.

Ответы [ 2 ]

1 голос
/ 12 июля 2011

Решение № 1: Создание общего интерфейса.

// IParentControlUpdater.cs
namespace AspNetUserControlDynamicEvent {
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    interface IParentControlUpdater {
        event EventHandler<EventArgs> UpdateParent;
    }
}

// DynamicUserControl.ascx.cs
namespace AspNetUserControlDynamicEvent {
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    public partial class DynamicUserControl : System.Web.UI.UserControl, IParentControlUpdater {
        protected void Page_Load(object sender, EventArgs e) { }

        #region IParentControlUpdater Members

        public event EventHandler<EventArgs> UpdateParent;

        #endregion
    }
}

// Default.aspx.cs
namespace AspNetUserControlDynamicEvent {
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    public partial class _Default : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) { }

        private void LoadMyUserControl(string controlName) {
            UserControl control = (UserControl)LoadControl(controlName);

            // Do some stuff 

            ((IParentControlUpdater)control).UpdateParent += new EventHandler<EventArgs>(control_UpdateParent);
        }

        private void control_UpdateParent(object sender, EventArgs e) {
            throw new NotImplementedException();
        }
    }
}

Решение № 2: Создание базового класса.Создайте базовый класс пользовательского элемента управления (например, DynamicUserControlBase).

// DynamicUserControlBase.ascx.cs
namespace AspNetUserControlDynamicEvent {
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    public partial class DynamicUserControlBase : System.Web.UI.UserControl {
        protected void Page_Load(object sender, EventArgs e) { }

        // Base event
        public event System.EventHandler<System.EventArgs> UpdateParent;
    }
}

Затем в своем пользовательском элементе управления вы хотите динамически создать и подписать событие updateParent:

// DynamicUserControl.ascx.cs
namespace AspNetUserControlDynamicEvent {
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    public partial class DynamicUserControl : DynamicUserControlBase {
        protected void Page_Load(object sender, EventArgs e) { }
    }
}

Обратите внимание, какон наследуется от DynamicUserControlBase.Теперь для вашего метода LoadMyUserControl:

private void LoadMyUserControl(string controlName) {
    DynamicUserControlBase control = (DynamicUserControlBase)LoadControl(controlName);

    // Do some stuff     

    control.UpdateParent += new EventHandler<EventArgs>(HandledEvent);
}

private void HandledEvent(object sender, EventArgs e) {
    throw new NotImplementedException();
}

Однако, если вы работаете только с одним типом элемента управления, вы можете так же легко изменить бокс на LoadControl на:

WebUserControl1 control = (WebUserControl1)LoadControl(controlName); // example

Нокажется, что вы, возможно, смотрите на загрузку множества различных типов пользовательских элементов управления, поэтому первое решение должно работать нормально.

Что касается вашей озабоченности с помощью Reflection, попробуйте следующее:

Type type = MyControl.GetType();
EventInfo eventInfo = type.GetEvent("UpdateParent");
EventHandler handler = new EventHandler(HandledEvent);
eventInfo.AddEventHandler(MyControl, handler);
1 голос
/ 12 июля 2011

Если вы хотите получить общее решение, вы можете создать абстрактный класс пользовательского элемента управления с вашим свойством и вашим событием. Тогда MyUserControl1 может наследовать от этого абстрактного пользовательского элемента управления. В вашем методе загрузки вы можете привести к абстрактному пользовательскому элементу управления и использовать его более простым способом. Таким образом, вы можете создать некоторые другие пользовательские элементы управления.

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