Зарегистрируйте и отмените регистрацию события с отражением в WinRT

Для моего проекта с открытым исходным кодом http://mytoolkit.codeplex.com Я пытаюсь реализовать улучшенный класс страниц для WinRT и WinPRT (8.1). Класс находится в библиотеке PCL. Вот почему я должен регистрировать обратное нажатие события путем отражения. Код без отражения выглядит следующим образом:

using Windows.Phone.UI.Input;

namespace SampleUniversalPhoneApp
{
 public class MyClass
 {
 public void Start()
 {
 HardwareButtons.BackPressed += OnBackPressed;
 }

 public void Stop()
 {
 HardwareButtons.BackPressed -= OnBackPressed;
 }

 private void OnBackPressed(object sender, BackPressedEventArgs e)
 {
 // TODO: Add more code
 e.Handled = true;
 }
}

}

Теперь мне нужна такая же логика, но с отражением, потому что классы HardwareButtons и BackPressedEventArgs недоступны в моей библиотеке PCL.

Как я могу это сделать?

2 ответа

Вот решение для этого вопроса:

public class MyClass
{
 private object _backPressedToken;
 private static readonly Type _hardwareButtonsType;
 private static readonly EventInfo _backPressedEvent;

 static MyClass()
 {
 _hardwareButtonsType = Type.GetType(
 "Windows.Phone.UI.Input.HardwareButtons, " +
 "Windows, Version=255.255.255.255, Culture=neutral, " +
 "PublicKeyToken=null, ContentType=WindowsRuntime");

 if (_hardwareButtonsType != null)
 _backPressedEvent = _hardwareButtonsType.GetRuntimeEvent("BackPressed");
 }

 public void Start()
 {
 // Register event
 Action<object, object=""> callback = OnBackKeyPressed;
 var callbackMethodInfo = callback.GetMethodInfo();
 var backPressedDelegate = callbackMethodInfo.CreateDelegate(_backPressedEvent.EventHandlerType, this);
 _backPressedToken = _backPressedEvent.AddMethod.Invoke(null, new object[] { backPressedDelegate });
 }

 public void Stop()
 {
 // Unregister event
 _backPressedEvent.RemoveMethod.Invoke(null, new [] { _backPressedToken });
 _backPressedToken = null; 
 }

 private void OnBackKeyPressed(object sender, dynamic args)
 {
 // Handle event
 if (!args.Handled)
 args.Handled = DoIt(args.Handled);
 }
}
</object,>

Наконец, используется в этом классе:

https://github.com/MyToolkit/MyToolkit/blob/master/src/MyToolkit.Extended/Paging/Handlers/BackKeyPressedHandler.cs


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

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

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

ИМХО, вы должны изменить свою архитектуру, предоставляя больше возможностей клиенту библиотеки.

В качестве дополнительной заметки Microsoft вскоре выпустит новое обновление VS2013 (уже доступное как бета-версия), что позволит вам разработать уникальное приложение для всех устройств на базе Microsoft.

licensed under cc by-sa 3.0 with attribution.