كيف يمكنني تعيين سلوك "إغلاق على مفتاح الهروب" لجميع نوافذ WPF داخل المشروع؟
-
27-09-2019 - |
سؤال
هل هناك أي طريقة مباشرة لإخبار تطبيق WPF بأكمله للرد على هروب مكابس المفاتيح من خلال محاولة إغلاق الأرملة المركزة حاليًا؟ إنه ليس منزعجًا جدًا إعداد روابط الأوامر والإدخال يدويًا ، لكنني أتساءل عما إذا كان تكرار هذا XAML في جميع النوافذ هو النهج الأكثر أناقة؟
<Window.CommandBindings>
<CommandBinding Command="Close" Executed="CommandBinding_Executed" />
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Key="Escape" Command="Close" />
</Window.InputBindings>
أي اقتراحات بناءة مرحب بها!
المحلول
كل ما يمكنني اقتراحه لتحسين ذلك هو إزالة الحاجة إلى معالج الحدث عن طريق الارتباط بمثال أمر ثابت.
ملاحظة: لن يعمل هذا فقط في .NET 4 فصاعدًا لأنه يتطلب القدرة على ربط KeyBinding
الخصائص.
أولاً ، قم بإنشاء أمر يأخذ نافذة كمعلمة ومكالمات Close
في حدود Execute
طريقة:
public class CloseThisWindowCommand : ICommand
{
#region ICommand Members
public bool CanExecute(object parameter)
{
//we can only close Windows
return (parameter is Window);
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
if (this.CanExecute(parameter))
{
((Window)parameter).Close();
}
}
#endregion
private CloseThisWindowCommand()
{
}
public static readonly ICommand Instance = new CloseThisWindowCommand();
}
ثم يمكنك ربط الخاص بك KeyBinding
إلى ثابت Instance
منشأه:
<Window.InputBindings>
<KeyBinding Key="Escape" Command="{x:Static local:CloseThisWindowCommand.Instance}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" />
</Window.InputBindings>
لا أعرف أن هذا بالضرورة أفضل من نهجك ، ولكن هذا يعني أقل هامشيًا في الجزء العلوي من كل Window
وأنك لا تحتاج إلى تضمين معالج الأحداث في كل منهما
نصائح أخرى
أو يمكنك فقط إضافة زر مع إلغاء النص والتعيين IsCancel = True
. ثم سيعمل Escape كأمر افتراضي لإغلاقه.
خلق RoutedUICommand
مثل أدناه
private static RoutedUICommand EscUICommand = new RoutedUICommand("EscBtnCommand"
, "EscBtnCommand"
, typeof(WindowName)
, new InputGestureCollection(new InputGesture[]
{ new KeyGesture(Key.Escape, ModifierKeys.None, "Close") }));
وأضفه الربط في مُنشئ
CommandBindings.Add(new CommandBinding(EscUICommand, (sender, e) => { this.Hide(); }));
على Window
S مبين مع ShowDialog()
يمكنك استخدام:
<!-- Button to close on Esc -->
<Button IsCancel="True" Width="0" Height="0"/>
يمكنك أيضًا استخدام حدث PreviewKeydown
PreviewKeyDown="UserControl_PreviewKeyDown"
الكود وراء Call You Close Command
private void UserControl_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
_vm.OnCloseCommand(sender);
}
}
طريقة أخرى ممكنة هي استخدام الخصائص المرفقة
Bellow هو رمز جوهر:
<script src="https://gist.github.com/meziantou/1e98d7d7aa6aa859d916.js"></script>
لم يعمل أي من أعلاه بالنسبة لي ، باستثناء كاي. لقد قمت بتعديل إجابته: لقد أضفت "btn_close.iscancel = true ؛ ' إلى مُنشئ. SettingSwindow هي نافذتي الثانية ، والنافذة الرئيسية هي (افتراضية) mainwindow.
public partial class SettingsWindow : Window {
public SettingsWindow() {
InitializeComponent();
btn_close.IsCancel = true;
}
private void btn_close_Click(object sender, RoutedEventArgs e) {
this.Close();
}
}
أتمنى أن يساعد ذلك ،
سيمون لوف نيا