ALT + F4 и кнопка IsCancel - PullRequest
       9

ALT + F4 и кнопка IsCancel

1 голос
/ 25 ноября 2010

Возможно ли, чтобы Alt + F4 (а также X кнопка закрытия + <system menu> :: Close) активировали кнопку, отмеченную как IsCancel? Я бы хотел, чтобы он вел себя так же, как при нажатии клавиши Esc .

Примечание: я использую Prism, и диалог создается в RegionBehavior, поэтому я не могу напрямую получить доступ к кнопке

Ответы [ 2 ]

0 голосов
/ 25 ноября 2010

В итоге я поддержал это с помощью пользовательского поведения, код которого приведен ниже. Я более чем рад переключиться на более чистую реализацию (например, такую, которая не требует добавления поведения к кнопке), если кто-то может подумать о ней.

Несколько замечаний по реализации (основанной на Rx):

  • Предполагается, что нажатие кнопки отмены всегда приведет к закрытию окна. Если ваша кнопка отмены может быть отменена (так сказать), это приведет к тому, что кнопка не будет нажата при закрытии окна.
  • Если кнопка каким-то образом удалена из окна (в нашем случае другой контент переместится в область), это приведет к отключению поведения.
  • Все обработчики событий удаляются в конце последовательности, независимо от того, было ли окно закрыто, была ли нажата кнопка или была удалена кнопка.

А вот и код:

public class DialogCancelButtonBehavior : Behavior<Button>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        Button button = AssociatedObject;

        GetWindowAsync(button)
            .SelectMany(window => GetWindowClosed(window))
            .Where(_ => button.IsCancel)
            .TakeUntil(GetButtonClicked(button))
            .TakeUntil(GetButtonUnloaded(button))
            .Subscribe(_ => ClickButton(button));
    }

    private IObservable<Window> GetWindowAsync(Button button)
    {
        var buttonLoaded = Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>(
            h => new RoutedEventHandler(h),
            h => button.Loaded += h,
            h => button.Loaded -= h);

        return button.IsLoaded
            ? Observable.Return(Window.GetWindow(button))
            : buttonLoaded.Take(1).Select(_ => Window.GetWindow(button));
    }

    private IObservable<IEvent<EventArgs>> GetWindowClosed(Window window)
    {
        return Observable.FromEvent<EventHandler, EventArgs>(
            h => new EventHandler(h),
            h => window.Closed += h,
            h => window.Closed -= h);
    }

    private IObservable<IEvent<RoutedEventArgs>> GetButtonClicked(Button button)
    {
        return Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>(
            h => new RoutedEventHandler(h),
            h => button.Click += h,
            h => button.Click -= h);
    }

    private IObservable<IEvent<RoutedEventArgs>> GetButtonUnloaded(Button button)
    {
        return Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>(
            h => new RoutedEventHandler(h),
            h => button.Unloaded += h,
            h => button.Unloaded -= h);
    }

    private void ClickButton(Button button)
    {
        ButtonAutomationPeer peer = 
            (ButtonAutomationPeer)UIElementAutomationPeer.CreatePeerForElement(button);

        IInvokeProvider invokeProv = 
            peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;

        invokeProv.Invoke(); 
    }
}
0 голосов
/ 25 ноября 2010

Alt + F4 должен вызывать CloseCommand (RoutedUICommand, свойство из статического класса ApplicationCommands).Если вы определите CommandBinding для этой команды, вы должны иметь возможность реагировать на нее (т.е. вызывать StopCommand или отменять каким-либо другим способом) и помечать ее как обработанную, в противном случае окно будет обрабатывать ее и закрывать.

Еслиэто невозможно, вы можете просто отсоединить KeyGesture Alt + F4 от команды CloseCommand (при запуске приложения) и сопоставить ее с другим действием, которое отменяет действие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...