代码之家  ›  专栏  ›  技术社区  ›  Richard Szalay

ALT+F4和IsCancel按钮

  •  1
  • Richard Szalay  · 技术社区  · 14 年前

    有没有可能 中高音 + 四层 (以及 X 关闭按钮+ <system menu> :: Close )触发标记为的按钮 IsCancel ? 我想让它以同样的方式按下 电子稳定控制系统 钥匙。

    注意:我使用的是Prism,对话框是在 RegionBehavior 所以我不能直接进入按钮

    2 回复  |  直到 12 年前
        1
  •  0
  •   Simon D.    14 年前

    Alt+F4应该触发CloseCommand(RoutedUICommand,来自静态类ApplicationCommands的属性)。 如果为此命令定义CommandBinding,则应该能够对此命令作出反应(即调用StopCommand或以其他方式取消),并将其标记为已处理,否则窗口将处理并关闭它。

    如果这是不可能的,您可以从CloseCommand(在应用程序启动时)中分离keyphense Alt+F4并将其映射到执行取消操作的其他操作。

        2
  •  0
  •   Richard Szalay    14 年前

    我最终通过一个自定义行为来支持这一点,代码如下。如果有人能想到的话,我非常乐意切换到更干净的实现(例如,不需要向按钮添加行为的实现)。

    关于实现(基于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(); 
        }
    }