为什么在按钮和菜单项中禁用了WPF ApplicationCommands.Close命令? 问题代码研究

问题

为什么在按钮和菜单项中禁用了WPF ApplicationCommands.Close命令?

代码

<Window x:Class="ApplicationCloseCommand.Views.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"
        xmlns:viewModels="clr-namespace:ApplicationCloseCommand.ViewModels"
        mc:Ignorable="d"
        Title="MainWindow" Height="169.493" Width="319.273">
    <Window.DataContext>
        <viewModels:MainWindowViewModel />
    </Window.DataContext>
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_File">
                <MenuItem Header="_Exit" Command="Close"/>
            </MenuItem>
        </Menu>
        <Canvas>
            <Button Content="Close" Command="Close" Height="23" VerticalAlignment="Top" Canvas.Left="142" Canvas.Top="31"/>
        </Canvas>
    </DockPanel>
</Window>

研究

Some sources说自己实现ICommand并在命令处理程序中执行this.Close()。但是然后,我根本不理解为什么ApplicationCommands.Close存在。

Some sources说,需要实现一种CanExecute方法来返回true。但是同样,如果我必须自己做(包括链接的示例中的CloseCommandHandler),那么ApplicationCommands.Close有什么好处?

Some sources提到CommandTarget。这不起作用:

<MenuItem Header="_Exit" Command="Close" CommandTarget="{Binding ElementName=MyMainWindow}"/>

我只是用CommandTarget做错了吗?

yingjianfeng09 回答:为什么在按钮和菜单项中禁用了WPF ApplicationCommands.Close命令? 问题代码研究

ApplicationCommandsNavigationCommands一样,

ComponentCommands公开了一组预定义的通用UI命令。它们都是RoutedCommand的实现。 RoutedCommandRoutedUICommand实现ICommand

RoutedCommand未实现ExecuteCanExecute方法。它只引发相应的RoutedEvent

此事件将遍历视觉树,直到由CommandBinding处理。定义或执行CommandBindingCanExecute方法或特殊事件处理程序的是Execute。这意味着可以在引发RoutedCommand的树上的某处定义实际的命令实现。

有一些控件可以实现默认的CommandBinding(或命令实现)。 TextBox可以处理ApplicationCommands.Copy RoutedCommand。或者DocumentViewer可以处理NavigationCommands.NextPage RoutedCommand。 ApplicationCommands.Close没有任何控件提供的支持者或默认实现。

RoutedCommand设计用于UI上下文,例如执行控件的行为。这种逻辑永远不能在视图模型中处理。因此,ApplicationCommands.Close必须通过与可视树挂钩的控件或附加行为来实现。
对于与数据相关的行为或逻辑,必须提供自己的ICommand实现,该实现具有在视图模型中定义的处理程序。

如果您将RoutedCommand例如ApplicationCommands.Close分配给命令源,例如Button,但没有为此RoutedCommand提供处理程序,因此没有CanExecute处理程序存在于命令源中,例如Button假设CanExecute为假并禁用自身。

这意味着您必须提供CommandBinding

MainWindow.xaml

<Window>
  <Window.CommandBindings>
    <CommandBinding Command="{x:Static ApplicationCommands.Close}"
                    Executed="ExecutedCloseCommand"
                    CanExecute="CanExecuteCloseCommand" />
  </Window.CommandBindings>

  <Button Command="{x:Static ApplicationCommands.Close}"
          Content="Close Window"/>
</Window>

MainWindow.xaml.cs

private void CanExecuteCloseCommand(object sender,CanExecuteRoutedEventArgs e)
{
   e.CanExecute = true;
}

private void ExecutedCloseCommand(object sender,ExecutedRoutedEventArgs e)
{
  this.Close();
}
本文链接:https://www.f2er.com/2362228.html

大家都在问