WPF ICommand CanExecute вызывается, даже если есть модальное окно

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

<UserControl>
<Grid>
    <Button x:Name="button" Content="Show Dialog" DataContext="{Binding m_btnShowDialog}" Style="{StaticResource ButtonVM}" Command="{Binding Cmd}" HorizontalAlignment="Left" Margin="29,56,0,0" VerticalAlignment="Top" Width="75" >
</Grid>
</UserControl>

Командный класс реализует интерфейс ICommand.
Когда фокус находится в приведенном выше диалоговом окне, иногда вызывается CanExecute.
Этого следовало ожидать.

Проблема в том, что когда я нажимаю кнопку, вызывается метод Execute и появляется новое модальное диалоговое окно.
Фокус должен быть на новом диалоговом окне, но по некоторым причинам CanExecute все еще вызывается, когда я взаимодействую с новым диалоговым окном.
Это нормальное поведение?
И как я могу изменить это поведение?
Я не хочу, чтобы метод команд CanExecute, прикрепленных к элементам управления родительского диалогового окна, вызывался при отображении дочернего модального диалогового окна.


person nammae    schedule 02.03.2018    source источник
comment
Вы должны установить владельца дочернего окна, то есть childWindow.Owner = parentWIndow   -  person Raviraj Palvankar    schedule 02.03.2018


Ответы (1)


Это ожидаемо. Цитата напрямую от эксперта WPF Джоша Смита:

WPF автоматически запросит у всех команд, используемых в вашем пользовательском интерфейсе, возможность их выполнения. Это происходит в разное время, например, когда фокус ввода смещается на другой элемент управления, элемент выбран в списке и т. Д. Вы также можете программно инициировать это, вызвав статический метод InvalidateRequerySuggested CommandManager. Все это кажется волшебным, мечтательным и слишком хорошим, чтобы быть правдой.

Вы можете получить более подробное и ясное объяснение здесь

Вы можете переопределить поведение, используя событие CanExecuteChanged в реализации вашей команды.

class MyCommand : ICommand
{
public bool CanExecute(object parameter)
{
return maybeTrueOrFalse;
}

public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}

public void Execute(object parameter)
{
// Do something awesome.
}
}
person rahulaga_dev    schedule 02.03.2018