C# 中的新手 MVVM 尝试使用 Esc 关闭应用程序(处理键命令)

Novice MVVM in C# trying to close application with Esc (handling key commands)

我是 learning/practicing C# 中的基本 MVVM 框架解决方案

我有一个与 ComboBox 一起玩的小程序,如果用户 select 来自盒子的东西,它会显示在 MsgBox 中。现在我希望它在 esc 键上关闭。我在这里发现了很多已解决的问题,例如:

Keyboard events in a WPF MVVM application? Press Escape key to call method

但我无法实现这些中的任何一个...我什至似乎无法将 KeyPreview 设置为 True(我现在可以只写入表单,但有趣的是,我可以让它发挥作用。)

我的问题是,我有一段时间没有使用 c#,我不确定到底要使用什么(KeyEventArg KeyEventHandler,我应该使用 e.Key、e.keyDown 吗?)而且我不确定在哪里把这段代码。我在 XAML 文件中阅读了一些关于如何处理它的内容,这将是最好的但无法做到。现在这是我在 App.xaml.cs 中的代码,我尝试在不同的地方实现它,但我在编码时再次询问并且不知道 do/what Mi 到底要做什么,所以在这里我。

我现在的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace WpfComboBoxStrinbgListMVVM
{



    public class MainViewModel
    {

        public MainViewModel()
        {
            ItemList = new List<string> { "item1", "item2", "item3" };
        }
        public List<string> ItemList { get; set; }

        private string seletedElement;
        public string SelectedElement
        {
            get { return seletedElement; }
            set
            {
                seletedElement = value;
                MessageBox.Show(seletedElement);
            }
        }

        private void EscKeyDown(object sender, KeyEventArgs e)
        {

            if (e.Key == Key.Escape)
            {
                MessageBox.Show("Escape key pressed");
                // mainWindow.Close();? MainWievModel.Close(); App.Close();

            }

        }

        //private void Form1_KeyDown(object sender, KeyEventArgs e)
        //{
        //    if (e.KeyCode == Keys.Escape)
        //    {
        //        MessageBox.Show("Escape key pressed");

        //        // prevent child controls from handling this event as well
        //        e.SuppressKeyPress = true;
        //    }
        //}

    }

}

您可以使用KeyBinding,示例代码如下:

<InputBindings>
   <KeyBinding Key="Esc" Command="{Binding CloseCommand}"/>
</InputBindings>

在window.xaml(恐怕你得在后面写点代码:( )

Window(){
  InitializeComponent();
  this.DataContextChanged += (sender,e){
    var vm = e.NewValue as WindowViewModel;
    if(vm != null){
       vm.CloseFunc = () => this.Close();
    }
 }

}

对于 WindowViewModel: public 动作 CloseFunc{get;set;}

private RelayCommand _closeCommand;
public RelayCommand CloseCommand =>
     _closeCommand??(_closeCommand = 
    new RelayCommand(() =>{
       CloseFunc?.Close();
   })));

在这种情况下,最简单的方法是使用预定义的 ApplicationCommands.Close 命令

这看起来像这样

<Window.InputBindings>
    <KeyBinding Key="Esc" Command="ApplicationCommands.Close" />
</Window.InputBindings>

然后在代码隐藏

this.CommandBindings.Add(
  new CommandBinding(
    ApplicationCommands.Close,
    (s,a)=>Application.Current.Shutdown() //or this.Close() depending on what you want to close
  )
);

其他选项包括实现使用 ICommand 接口的自定义 class 或使用提供此功能的数百个库之一,例如 prism's Delegate Command or the Relay command

编辑

由于你对匿名委托不熟悉后面的代码也可以这样写

this.CommandBindings.Add(
  new CommandBinding(
    ApplicationCommands.Close,
    PerformClose
  )
);

public void PerformClose(object sender, ExecutedRoutedEventArgs args)
{
    Application.Current.Shutdown();
}