كيف يمكنني تعيين سلوك "إغلاق على مفتاح الهروب" لجميع نوافذ WPF داخل المشروع؟

StackOverflow https://stackoverflow.com/questions/3863431

سؤال

هل هناك أي طريقة مباشرة لإخبار تطبيق 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(); }));

على WindowS مبين مع 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();
    }
  }

أتمنى أن يساعد ذلك ،

سيمون لوف نيا

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top