WPF标准命令 - 退出在哪里?

25

我正在创建一个标准菜单在我的WPF应用程序中。

我知道我可以创建自定义命令,但也知道有一大堆标准命令可供绑定。

例如,要打开文件,我应该绑定到ApplicationCommands.Open,要关闭文件,我应该绑定到ApplicationCommands.Close。还有许多EditCommandsComponentCommandsNavigationCommands

似乎没有"Exit"命令。我本来希望有ApplicationCommands.Exit

那么我应该将"Exit"菜单项绑定到什么?为这个通用的东西创建一个自定义命令似乎不太对。

7个回答

9

6

实际上并不是很复杂(但微软太烂了,没有提供这个功能)。下面是方法:

public static class MyCommands
{
    private static readonly ICommand appCloseCmd = new ApplicationCloseCommand();
    public static ICommand ApplicationCloseCommand
    {
        get { return appCloseCmd; }
    }
}

//===================================================================================================
public class ApplicationCloseCommand : ICommand
{
    public event EventHandler CanExecuteChanged
    {
        // You may not need a body here at all...
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public bool CanExecute(object parameter)
    {
        return Application.Current != null && Application.Current.MainWindow != null;
    }

    public void Execute(object parameter)
    {
        Application.Current.MainWindow.Close();
    }
}

而且,AplicationCloseCommand.CanExecuteChanged事件处理程序的主体可能根本不需要。

你可以这样使用它:

<MenuItem Header="{DynamicResource MenuFileExit}" Command="MyNamespace:MyCommands.ApplicationCloseCommand"/>

干杯!

(你无法想象我自己发现这个命令需要多长时间...)


6
据我所知,没有ApplicationCommands.Quit或ApplicationCommands.Exit,因此我猜你得自己创建它...
无论如何,如果你正在使用MVVM模式,RoutedCommands并不是很方便,因此最好使用轻量级的替代方案,比如RelayCommand或DelegateCommand。

4

是的,如果微软在其预定义命令集合中包括了一个ApplicationCommands.Exit命令,那么这将会非常有意义。但令我失望的是,他们没有这样做。但正如本问题的答案所示,情况并非都是无解。

对于缺乏适当的ApplicationCommands.Exit对象,有很多可行的解决方案。然而,我认为大多数都没有抓住重点。要么他们在视图模型中实现了一些东西,而实际上这是一个严格的视图行为(在某些情况下,甚至触及视图对象图形,例如Application.Current.MainWindow!),或者他们编写了大量的代码来完成XAML可以很好地且更方便地完成的工作。

在我看来,最简单的方法就是声明一个用于窗口的RoutedUICommand资源,将其附加到命令绑定和菜单项上,以连接所有部分。例如:

<Window x:Class="ConwaysGameOfLife.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

  <Window.Resources>
    <RoutedUICommand x:Key="fileExitCommand" Text="File E_xit">
      <RoutedUICommand.InputGestures>
        <KeyGesture >Alt+F4</KeyGesture>
      </RoutedUICommand.InputGestures>
    </RoutedUICommand>
  </Window.Resources>

  <Window.CommandBindings>
    <CommandBinding Command="{StaticResource fileExitCommand}" Executed="fileExitCommand_Executed"/>
  </Window.CommandBindings>

  <DockPanel>
    <Menu DockPanel.Dock="Top">
      <MenuItem Header="_File">
        <!-- other menu items go here -->
        <Separator/>
        <MenuItem Command="{StaticResource fileExitCommand}"/>
      </MenuItem>
    </Menu>
    <!-- the main client area UI goes here -->
  </DockPanel>

</Window>
< p > 命令绑定的 Executed 事件处理程序很简单:

private void fileExitCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
    Close();
}

假设你的程序实现采用通常语义,通过关闭主窗口来退出程序。
这种方式,所有与用户界面相关的元素都直接进入 RoutedUICommand 对象,可以在 XAML 中正确方便地配置该对象,而无需声明新的 C# 类以实现命令并/或混乱地在代码后台中进行输入绑定。菜单项对象已经知道如何显示 RoutedUICommand,因此采用这种方法可将命令属性与其余用户界面分离开。它还提供了一种方便的方法来提供第二个键盘手势,以防您希望使用除默认的 Alt + F4 之外的其他内容(例如 Ctrl + W)。
您甚至可以将 RoutedUICommand 声明放在 App.xaml 文件中,以便在程序中的多个窗口中重复使用。再次将 UI 特定方面(在资源中声明)与程序中找到的使用者分离开。
我发现这种方法比其他我见过的方法更具普适性和易于实现(包括本文和其他地方)。

1
private void MenuItem_Click(object sender, RoutedEventArgs e)
    {
        Application.Current.Shutdown();
    }

1
相当简单:

using System.Windows.Input;

namespace YourApp
{
    static class ApplicationCommands
    {    
        public static RoutedCommand Quit { get; }    

        static ApplicationCommands()
        {
            var inputGestures = new InputGestureCollection();
            inputGestures.Add(new KeyGesture(Key.Q, ModifierKeys.Control));
            Quit = new RoutedUICommand("Quit", "Quit", typeof(ApplicationCommands),
                inputGestures);
        }
    }
}

在您的XAML中使用它:

<Window.CommandBindings>
    <CommandBinding Command="local:ApplicationCommands.Quit" 
                    Executed="QuitCommandOnExecuted"/>
</Window.CommandBindings>

[..]

<MenuItem Command="local:ApplicationCommands.Quit" />

后台代码:

void QuitCommandOnExecuted(object sender, ExecutedRoutedEventArgs e)
{
    Application.Current.Shutdown();
}

-1

在将命令绑定到窗口之前,您可以修改命令的Text属性。这将更改命令在UI中出现的所有位置的文本。

编辑:在窗口或App ctor中执行此操作以关闭。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接