Как предотвратить InvokeCommandAction от распространения события на родительские элементы? - PullRequest
14 голосов
/ 04 октября 2011

Я понял, что при использовании InvokeCommandAcction, связанной с EventTrigger, исходное событие все еще направлялось до родительских элементов, пока оно не было обработано.Ну, я думаю, это ожидаемое поведение.Но мой вопрос заключается в том, как я могу пометить событие как Обработанное, чтобы оно не распространялось вверх по всему дереву пользовательского интерфейса?

На самом деле, когда вы обрабатываете это событие в команде, все будет обрабатываться в этой команде, поэтомуэто не должно распространяться.И в одном случае, который я обнаружил, это вызывает нежелательное поведение.Например, я открываю новое окно, когда пользователь дважды щелкает элемент (событие MouseDoubleClick).Проблема в том, что новые окна открываются, а затем главное окно возвращается перед новым, потому что событие MouseDoubleClick только что достигло верхнего элемента в дереве пользовательского интерфейса.Требуемое поведение состояло бы в том, чтобы сохранить новое окно впереди, но поскольку InvokeCommandAction позволяет событию распространяться вверх, главное окно возвращает фокус ...

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

<UserControl x:Class="..."
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseDoubleClick">
            <i:InvokeCommandAction Command="{Binding Path=DisplayReportCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    ...
</UserControl>

Ответы [ 3 ]

21 голосов
/ 07 октября 2011

Вы можете реализовать свой собственный EventTrigger, который помечает события как обработанные.

public class HandlingEventTrigger : System.Windows.Interactivity.EventTrigger
{
    protected override void OnEvent(System.EventArgs eventArgs)
    {
        var routedEventArgs = eventArgs as RoutedEventArgs;
        if (routedEventArgs != null)
            routedEventArgs.Handled = true;

        base.OnEvent(eventArgs);
    }
}

Затем замените <i:EventTrigger EventName="MouseDoubleClick"> на <local:HandlingEventTrigger EventName="MouseDoubleClick"> и добавьте

xmlns:local="clr-namespace:HandlingEventTrigger's namespace here"

к атрибутам вашего usercontrol.

1 голос
/ 08 октября 2011

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

              CommandManager.PreviewCanExecute="PreviewCanExecute" 

и в обработчике событий

               e.ContinueRouting = false;

Надеюсь, это поможет !

0 голосов
/ 08 октября 2011

Событие MouseDoubleClick на самом деле не пузырьковое перенаправленное событие, а прямое перенаправленное событие.

Однако это событие возникает вдоль дерева элементов, которое может бытьпроверено с помощью инструмента Snoop .Более того, даже если для параметра Handled for MouseDoubleClick установлено значение true, это событие будет происходить вдоль дерева элементов.

Хотя это перенаправленное событие (MouseDoubleClick Event), по-видимому, следует по пузырчатому маршруту через дерево элементов, онона самом деле это событие прямой маршрутизации, которое вызывается в дереве элементов каждым элементом UIElement.

Если для свойства Handled установлено значение true в обработчике события MouseDoubleClick, последующие события MouseDoubleClick вдоль маршрута будут происходить, а для параметра Handled установлено значение false,Это событие более высокого уровня для потребителей элементов управления, которые хотят получать уведомления, когда пользователь дважды щелкает элемент управления и обрабатывает событие в приложении.(От MSDN )

Как указано выше, ваша проблема может быть не вызвана распространением, как вы упоминали.Есть свойство Window.ShowActivation, которое определяет, активируется ли окно при первом его отображении.Вы можете установить свойство в подокне (xaml), как показано ниже, но имейте в виду, что хотя ShowActivation может фокусироваться на главном окне, оно не может позволить главному окну визуально находиться перед подокном.Я пытался найти решение, но до сих пор не знаю.

<Window ShowActivated="False" ....>
....
</Window>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...