【问题标题】:Novice MVVM in C# trying to close application with Esc (handling key commands)C# 中的新手 MVVM 尝试使用 Esc 关闭应用程序(处理键命令)
【发布时间】:2017-08-15 11:28:07
【问题描述】:

我正在学习/练习 C# 中的基本 MVVM 框架解决方案

我有一个使用 ComboBox 的小程序,如果用户从框中选择某些内容,它会显示在 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 中的代码,我尝试在各个地方实现它,但我再次询问我何时编码并且不知道该做什么/我到底在做什么,所以我在这里。

我现在的代码:

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;
        //    }
        //}

    }

}

【问题讨论】:

  • 我无法让按下 Esc 键的 MsgBox 出现,如果你想帮助我,请询问你需要的任何东西:)
  • “现在我希望它在 esc 键上关闭” - 什么是“它”?
  • 应用程序本身,程序,整个事情(我有另一个项目,在 Esc 上登录窗口消失但仍在任务管理器中运行,我希望能够正确关闭它)

标签: c# .net wpf mvvm keydown


【解决方案1】:

在这种情况下,最简单的方法是使用预定义的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 接口的自定义类或使用提供此功能的数百个库之一,例如 prism's Delegate CommandRelay command

编辑

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

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

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

【讨论】:

  • 谢谢...我尝试了很多类似这样的不同方法,尝试了 Application.Close 和 App.Close 以及 this.Close 等等...你能向我解释一下这条线是做什么的吗做? : (s,a)=>Application.Current.Shutdown() 为什么我们在 ApplicationCommands.Close 之后需要它? (s,a) 是什么?
  • (s,a)=&gt; 定义了一个匿名委托,在这种情况下接受 2 个参数 object s 和 eventAgs e,标准事件处理程序指纹,Application.Current 获取当前正在运行的应用程序,而 shuddown 方法是命令关闭选定的应用程序
  • 很抱歉打扰您,但程序如何知道 s 是对象类型? a 是 eventArgs 吗?它们在哪里指定?对我来说,它看起来像是某种 (s,a) => 部分的黑魔法(但我想理解的不仅仅是实现)
  • 这是因为CommandBinding 构造函数的定义指定委托是ExecutedRoutedEventHandler 类型,然后它定义了参数的类型
  • 我明白了,如果有人感兴趣,这里是文档:msdn.microsoft.com/en-us/library/…
【解决方案2】:

您可以使用 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: 公共动作 CloseFunc{get;set;}

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

【讨论】:

  • 嗨,感谢您的帮助,但我不能像任何其他 MVVM“命令”一样使用 Binding CloseCommand,如下所示:[code] private string seletedElement;公共字符串 SelectedElement { 获取 { 返回已选择元素; } 设置 { 选择元素 = 值; MessageBox.Show(seletedElement); } } [代码]
  • @BasicHumanBeing 命令绑定是您处理任何其他命令的方式,但是处理该绑定的方法可以以不同的方式完成
  • @Jake ,windiw.xaml 和 WindowViewModel 都出现错误。在 WVM 中:找不到 action 和 relaycommands 命名空间,并且在 window.xaml.cs 中(我假设那是你指示我写它的地方)在发件人 e)之后 IDE 除外“=>”并且它不识别 CloseFunc(也我以前从未见过这个,它是做什么的: = () => 不是一个简单的 this.close 应该这样做吗?)
  • @BasicHumanBeing 中继命令不是 .net 框架的一部分,您需要自己编写或获取已为您完成此操作的库,我认为 jake 正在使用 mvvmlight.net
猜你喜欢
  • 1970-01-01
  • 2010-10-16
  • 1970-01-01
  • 2011-06-28
  • 2016-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多