Как вы можете пассивно реагировать на RoutedCommand? - PullRequest
0 голосов
/ 27 декабря 2018

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

Теперь в некоторых случаях элемент закрывается (или удаляется из стека)сначала нужно сделать некоторую очистку.И эта страница также прослушивала событие Close, что казалось правильным решением.

Теперь, поскольку эта страница фактически получит событие до того, как появится окно (команда Close реализована с помощью 'bubbling').event ') мы думали, что все, что нам нужно сделать, это установить привязку команды на странице, а затем в обработчике установить значение e.Handled в значение false, и оно будет продолжаться до окна.

Вот код встраница (InitializeCommands вызывается из конструктора) ...

private void InitializeCommands(){

    CommandBindings.Add(
        new CommandBinding(ApplicationCommands.Close, Close_Execute, Close_CanExecute)
    );
}

private void Close_CanExecute(object sender, CanExecuteRoutedEventArgs e){
    // True executes this handler, but blocks the one in the window
    // False executes the one in the window, but ignores this one
    e.CanExecute = true;

    // Doesn't seem to have any effect
    e.Handled = false;
}
private void Close_Execute(object sender, ExecutedRoutedEventArgs e){
    Console.WriteLine("I want to respond passively!");
    // Doesn't seem to have any effect
    e.Handled = false;
}

Однако, независимо от того, для чего мы установили это свойство, команда никогда не попадет в главное окно.Если мы удалим привязку команды на странице, она снова заработает, доказав, что страница глотает команду независимо от этого свойства.

Итак, что вам нужно сделать, чтобы страница прослушивала событие Closeпассивно?

Ответы [ 2 ]

0 голосов
/ 27 декабря 2018

Еще одна идея - взглянуть на метод AddHandler ().Это позволит вам добавить один обработчик событий для всех дочерних событий.Т.е. для моего элемента управления крошкой я могу сделать:

AddHandler (BreadcrumbSplitButton.ClickEvent, новый RoutedEventHandler (OnBreadcrumbSplitButtonClick));

В классе BreadCrumb для прослушивания ClickEvent для всех дочерних элементов Bb.

0 голосов
/ 27 декабря 2018

Да, CommandBinding ест команды.Вот выдержка из его реализации:

internal void OnExecuted(object sender, ExecutedRoutedEventArgs e)
{
    if (!e.Handled)
    {
        if (e.RoutedEvent == CommandManager.ExecutedEvent)
        {
            if (this.Executed != null && CheckCanExecute(sender, e))
            {
                this.Executed(sender, e);
                e.Handled = true;
            }
        }
        else if (this.PreviewExecuted != null && CheckCanExecute(sender, e))
        {
            this.PreviewExecuted(sender, e);
            e.Handled = true;
        }
    }
}

Как видите, если вы вернете true для CanExecute, команды будут съедены.

Возможно, вы захотите взглянуть на CompositeCommand.Это было бы больше в твоем переулке.Вы создаете глобальную CompositeCommand, которая привязана к фрейму, и затем к нему могут присоединяться различные виды.Разные реализации могут иметь разные интересные способы определения поведения нескольких подписчиков команд.Т.е. все должны возвращать canExecute, любые должны возвращаться, переходят только в активное представление и т. Д.

РЕДАКТИРОВАТЬ: CompositeCommand изначально был частью Prism, но вы можете либо найти отдельную реализацию, либо просто вытащить ее из самой Prism.:

https://github.com/PrismLibrary/Prism/blob/master/Source/Prism/Commands/CompositeCommand.cs

...