Wpf ALT+;F4和IsCancel按钮
是否可以让Alt+F4(以及Wpf ALT+;F4和IsCancel按钮,wpf,prism,Wpf,Prism,是否可以让Alt+F4(以及Xclose按钮+::close)触发标记为IsCancel的按钮?我想让它的行为方式与按Esc键相同 注意:我使用的是Prism,对话框是在区域行为中创建的,因此我无法直接访问按钮Alt+F4应触发CloseCommand(RouteDuicCommand,来自静态类ApplicationCommand的属性)。 如果为此命令定义CommandBinding,则应该能够对其作出反应(即调用StopCommand或以其他方式取消),并将其标记为已处理,否则窗口将处理并
X
close按钮+::close
)触发标记为IsCancel
的按钮?我想让它的行为方式与按Esc键相同
注意:我使用的是Prism,对话框是在
区域行为中创建的,因此我无法直接访问按钮Alt+F4应触发CloseCommand(RouteDuicCommand,来自静态类ApplicationCommand的属性)。
如果为此命令定义CommandBinding,则应该能够对其作出反应(即调用StopCommand或以其他方式取消),并将其标记为已处理,否则窗口将处理并关闭
如果这是不可能的,您可以从CloseCommand(在应用程序启动时)中分离按键手势Alt+F4,并将其映射到执行取消操作的其他操作。我最终通过自定义行为支持此操作,代码如下所示。如果有人能想到的话,我非常乐意切换到更干净的实现(例如,不需要向按钮添加行为的实现)
关于实施的一些注意事项(基于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();
}
}
公共类对话框CancelButtonBehavior:行为
{
受保护的覆盖无效附加()
{
base.onatached();
按钮=关联的对象;
GetWindowAsync(按钮)
.SelectMany(窗口=>GetWindowClosed(窗口))
.Where(=>button.IsCancel)
.TakeUntil(GetButtonClicked(按钮))
.TakeUntil(GetButton未加载(按钮))
.订阅(=>ClickButton(按钮));
}
私有IObservable GetWindowAsync(按钮)
{
var buttonLoaded=可观测的FromEvent(
h=>新的路由EventHandler(h),
h=>button.Loaded+=h,
h=>button.Loaded-=h);
返回按钮。已加载
?可观察。返回(窗口。获取窗口(按钮))
:buttonLoaded.Take(1)。选择(=>Window.GetWindow(按钮));
}
私有IObservable GetWindowClosed(窗口窗口)
{
返回可观察的.FromEvent(
h=>新事件处理程序(h),
h=>window.Closed+=h,
h=>window.Closed-=h);
}
私有IObservable GetButtonClicked(按钮)
{
返回可观察的.FromEvent(
h=>新的路由EventHandler(h),
h=>按钮。单击+=h,
h=>按钮。单击-=h);
}
私有IObservable GetButton未加载(按钮)
{
返回可观察的.FromEvent(
h=>新的路由EventHandler(h),
h=>按钮。卸载+=h,
h=>button.unload-=h);
}
私有作废点击按钮(按钮)
{
按钮自动对等=
(ButtonAutomationPeer)UIElementAutomationPeer.CreatePeerForElement(按钮);
IInvokeProvider invokeProv=
作为IInvokeProvider的peer.GetPattern(PatternInterface.Invoke);
invokeProv.Invoke();
}
}
问题在于,创建窗口的代码完全不知道按钮,因此无法将它们链接起来。