[英]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.