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

问题描述 投票:0回答:1

疑问

为什么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>

科研

一些来源 说要实行 ICommand 自己动手 this.Close() 在命令处理程序中。但是,我不明白为什么 ApplicationCommands.Close 根本不存在。

一些资料来源 说要实现 CanExecute 阴极返回 true. 但是,再次,如果我必须做,自己包括 CloseCommandHandler (从链接的例子中),有什么好处呢?ApplicationCommands.Close?

一些来源 提及 CommandTarget. 这没有用。

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

难道我刚才做错了 CommandTarget?

wpf xaml icommand
1个回答
0
投票

ApplicationCommands譬如 NavigationCommandsComponentCommands 暴露了一组预定义的通用UI命令。它们都是 RoutedCommand. RoutedCommandRoutedUICommand实施 ICommand.

RoutedCommand 没有实现 ExecuteCanExecute 方法。它只是引发了相应的 RoutedEvent.

该事件将遍历视觉树,直到它被某个 CommandBinding. 这是 CommandBinding 定义或执行 CanExecuteExecute 方法或特殊事件处理程序。这意味着实际的命令实现可以在树上的某个地方被定义,而在这个树上的 RoutedCommand 被提出。

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

RoutedCommand 被设计为在UI上下文中使用,例如执行一个控件的行为。这种逻辑绝不应该在视图模型中处理。因此,在视图模型中不应该处理这类逻辑。ApplicationCommands.Close 必须由一个控件或附加的行为来实现,该行为必须挂到可视化树中。对于数据相关的行为或逻辑,你必须提供你自己的 ICommand 实现,它的处理程序定义在视图模型中。

如果您在视图模型中定义了一个 RoutedCommand 例如:, ApplicationCommands.Close 到一个命令源,如a 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();
}
© www.soinside.com 2019 - 2024. All rights reserved.