gscraft
@gscraft
Программист, философ

Avalonia. Возможно ли маршрутизированное событие для класса в шаблонном типе?

У Avalonia есть интересная возможность: можно подписываться на события на уровне класса — https://docs.avaloniaui.net/docs/input/routed-even... Беда в том, что базовый интерфейс реактивных представлений/моделей предполагает реализацию IViewFor[TViewModel], имеющуюся в ReactiveUserControl[TViewModel]. А само реактивное событие — статическое свойство класса, работающее на уровне класса только для дочерних классов, но шаблонный (generic) тип не будет таковым. То есть, базовый класс A, реализующий реактивное событие, должен быть шаблонным, и никогда не передаст событие дочерним классам, с другим шаблонным типом, Base(T) не доведет событие до Concrete(ConcreteViewModel). Конечно, потребность в такой обработке событий можно обойти рядом способов, но тем не менее, местами хочется избежать лишнего кода, например, в цепочках передачи подписок и отписок, не усложняя менеджмент интерфейса, определяемого моделями (Content = SomeDataContext и т.д.). Так вот вопрос, изъян дизайна, так и задумано, что реактивные UserControl заставляют отказаться от ряда функций или есть решение?
  • Вопрос задан
  • 91 просмотр
Решения вопроса 1
@AAGR
Занимаюсь программированиям
Определите интерфейс, который содержит событие маршрутизации, и имплементировать этот интерфейс в каждом классе, где необходимо использовать это событие. Затем в каждом классе можно определить статический член, который будет хранить все подписки на событие в этом классе. Каждый раз, когда событие происходит, класс будет обновлять свои подписки и оповещать всех заинтересованных слушателей.

public interface IBase
{
    event EventHandler<RoutedEventArgs> MyRoutedEvent;
}

public class Base<T> : ReactiveUserControl<T>, IBase where T : class
{
    public static event EventHandler<RoutedEventArgs> MyRoutedEvent;

    event EventHandler<RoutedEventArgs> IBase.MyRoutedEvent
    {
        add { MyRoutedEvent += value; }
        remove { MyRoutedEvent -= value; }
    }

    protected static void OnMyRoutedEvent(object sender, RoutedEventArgs e)
    {
        MyRoutedEvent?.Invoke(sender, e);
    }
}


Concrete:

public class Concrete : Base<ConcreteViewModel>, IBase
{
    public static event EventHandler<RoutedEventArgs> MyRoutedEvent;

    event EventHandler<RoutedEventArgs> IBase.MyRoutedEvent
    {
        add { MyRoutedEvent += value; }
        remove { MyRoutedEvent -= value; }
    }

    protected override void OnInitialized()
    {
        base.OnInitialized();
        MyRoutedEvent += OnMyRoutedEvent;
    }

    protected override void OnDispose()
    {
        MyRoutedEvent -= OnMyRoutedEvent;
        base.OnDispose();
    }
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы