是否可以让 Alt + F4 (以及X
关闭按钮+ <system menu> :: Close
)触发标记的按钮如IsCancel
?我希望它按照 Esc 键的相同方式运行。
注意:我正在使用Prism并且正在RegionBehavior
创建对话框,因此我无法直接访问按钮
答案 0 :(得分:0)
Alt + F4应该触发CloseCommand(RoutedUICommand,属性来自静态类ApplicationCommands)。 如果你为这个命令定义一个CommandBinding,你应该能够对它做出反应(即调用StopCommand或取消其他方式)并将其标记为已处理,否则Window将处理它并关闭。
如果无法做到这一点,您可以从CloseCommand中分离KeyGesture Alt + F4(在应用程序启动时)并将其映射到您取消的其他一些操作。
答案 1 :(得分:0)
我最终通过自定义行为支持此操作,其代码如下所示。我很乐意切换到一个更干净的实现(例如,一个不需要为按钮添加行为的实现),如果有人能想到一个。
关于实施的一些注释(基于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();
}
}