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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1286692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:51:09  来源:igfitidea点击:

WPF Standard Commands - Where's Exit?

wpfbinding

提问by Andrew Shepherd

I'm creating a standard menu in my WPF application.

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

I know that I can create custom commands, but I know there are also a bunch of standard commands to bind to.

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

For example, to open a file I should bind to ApplicationCommands.Open, to close a file I should bind to ApplicationCommands.Close. There's also a large number of EditCommands, ComponentCommandsor NavigationCommands.

例如,要打开一个文件,我应该绑定到ApplicationCommands.Open,要关闭一个文件,我应该绑定到ApplicationCommands.Close。还有大量的EditCommandsComponentCommandsNavigationCommands

There doesn't seem to be an "Exit" command. I would have expected there to be ApplicationCommands.Exit.

似乎没有“退出”命令。我原以为会有ApplicationCommands.Exit

What should I bind to the "Exit" menu item? To create a custom command for something this generic just seems wrong.

我应该将什么绑定到“退出”菜单项?为这种通用的东西创建自定义命令似乎是错误的。

采纳答案by Thomas Levesque

AFAIK there's no ApplicationCommands.Quit or ApplicationCommands.Exit, so I guess you're gonna have to create it yourself...

AFAIK 没有 ApplicationCommands.Quit 或 ApplicationCommands.Exit,所以我猜你必须自己创建它......

Anyway, if you're using the MVVM pattern, RoutedCommands are not exactly handy, so it's better to use a lightweight alternative like RelayCommandor DelegateCommand.

无论如何,如果您使用的是MVVM 模式,RoutedCommands 并不是很方便,所以最好使用轻量级替代品,如RelayCommandDelegateCommand

回答by dthrasher

Unfortunately, there is no predefined ApplicationCommands.Exit. Adding one to WPF was suggested on Microsoft Connect in 2008: http://connect.microsoft.com/VisualStudio/feedback/details/354300/add-predefined-wpf-command-applicationcommands-exit. The item has been marked closed/postponed, however.

不幸的是,没有预定义的 ApplicationCommands.Exit。2008 年在 Microsoft Connect 上建议向 WPF 添加一个:http: //connect.microsoft.com/VisualStudio/feedback/details/354300/add-predefined-wpf-command-applicationcommands-exit。然而,该项目已被标记为关闭/推迟。

Mike Taulty discussed how to create your own Exit commandin an article on his blog.

Mike Taulty在他博客上的一篇文章中讨论了如何创建自己的退出命令

回答by NoOne

Not that complex actually (but still, M$ sucks for not providing it). Here you go:

实际上并没有那么复杂(但 M$ 仍然很糟糕,因为没有提供它)。干得好:

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();
    }
}

And the body of the AplicationCloseCommand.CanExecuteChangedevent handler may not be even needed.

AplicationCloseCommand.CanExecuteChanged甚至可能不需要事件处理程序的主体。

You use it like so:

你像这样使用它:

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

Cheers!

干杯!

(You cannot imagine how long it took me to discover this Command stuff myself...)

(你无法想象我花了多长时间自己发现这个命令的东西......)

回答by Peter Duniho

Yes, it would've made a lot of sense for Microsoft to include an ApplicationCommands.Exitcommand in their collection of pre-defined commands. It disappoints me that they didn't. But as the answers to this question demonstrate, not all is lost.

是的,微软ApplicationCommands.Exit在他们的预定义命令集合中包含一个命令是很有意义的。令我失望的是他们没有。但正如这个问题的答案所表明的那样,并不是所有的都丢失了。

There are lots of workarounds possible for the lack of a proper ApplicationCommands.Exitobject. However, I feel most miss the point. Either they implement something in the view model, for something that really is strictly a view behavior (in some cases reaching into the view object graph with e.g. Application.Current.MainWindow!), or they write a bunch of code-behind to do what XAML does very well and much more conveniently.

由于缺少合适的ApplicationCommands.Exit对象,有很多可能的解决方法。但是,我觉得最没有抓住重点。他们要么在视图模型中实现一些东西,对于一些真正严格来说是视图行为的东西(在某些情况下,使用例如Application.Current.MainWindow!)方便多了。

IMHO, the simplest approach is just to declare a RoutedUICommandresource for the window, attach that to a command binding, and to a menu item, to hook all the parts up. For example:

恕我直言,最简单的方法是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>

The Executedevent handler for the command binding is trivial:

Executed命令绑定的事件处理程序很简单:

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

Assuming, of course, your program implementation follows the usual semantics of closing the main window to exit the program.

当然,假设您的程序实现遵循关闭主窗口以退出程序的常用语义。

In this way, all of the UI-specific elements go right into the RoutedUICommandobject, which can be configured correctly and conveniently right in the XAML rather than having to declare a new C# class to implement the command and/or mess around with the input bindings from code-behind. The MenuItemobject already knows what to do with a RoutedUICommandin terms of display, so going this route provides a nice decoupling of the command's properties from the rest of the UI. It also provides a convenient way to provide a secondary key gesture, in case you'd prefer something other than the default Alt+F4(e.g. Ctrl+W).

通过这种方式,所有特定于 UI 的元素都直接进入RoutedUICommand对象,可以在 XAML 中正确且方便地对其进行配置,而不必声明新的 C# 类来实现命令和/或处理输入绑定从代码隐藏。该MenuItem物体已经知道如何与做RoutedUICommand在显示器方面,所以去这条路线提供了一个很好的从UI的其他命令的属性去耦。它还提供了一种方便的方式来提供辅助键手势,以防您更喜欢默认值以外的其他内容Alt+F4(例如Ctrl+W)。

You can even put the RoutedUICommanddeclaration in the App.xaml file, for reuse among multiple windows in your program, should they exist. Again, decoupling the UI-specific aspects, which are declared in the resource, from the consumers that are found throughout the program.

您甚至可以将RoutedUICommand声明放在 App.xaml 文件中,以便在程序中的多个窗口之间重用,如果它们存在的话。同样,将资源中声明的特定于 UI 的方面与整个程序中发现的使用者分离。

I find this approach much more generalizable and easily implemented than the other options which I've seen presented (here and elsewhere).

我发现这种方法比我看到的其他选项(这里和其他地方)更易于推广和易于实现。

回答by Alex

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

回答by Maxence

Pretty simple to do:

做起来很简单:

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

Use it in your XAML like this:

在您的 XAML 中使用它,如下所示:

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

[..]

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

Code-behind:

代码隐藏:

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

回答by karl.r

You can modify the Text property of a command before you bind it in a window. This will change the text of the command everywhere it appears in your ui.

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

EDIT: Do this to Close in the Window or App ctor

编辑:执行此操作以在窗口或应用程序中关闭