簡體   English   中英

ALT + F4和IsCancel按鈕

[英]ALT+F4 and the IsCancel button

是否可以讓Alt + F4 (以及X關閉按鈕+ <system menu> :: Close )觸發標記為IsCancel的按鈕? 我希望它的行為與按Esc鍵的行為相同。

注意:我使用的是Prism,並且該對話框是在RegionBehavior中創建的,因此無法直接訪問該按鈕

Alt + F4應該觸發CloseCommand(RoutedUICommand,靜態類ApplicationCommands中的Property)。 如果為此命令定義了CommandBinding,則應該能夠對此做出反應(即調用StopCommand或取消其他方式)並將其標記為已處理,否則Window將對其進行處理並關閉。

如果無法做到這一點,則可以將KeyGesture Alt + F4與CloseCommand分離(在應用程序啟動時),並將其映射到其他要取消的動作。

我最終通過一個自定義行為來支持此操作,其代碼如下。 如果有人可以想到一個更干凈的實現(例如,不需要向按鈕添加行為的實現),我將非常高興。

有關實現的一些說明(基於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(); 
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM