为什么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
?
ApplicationCommands
譬如 NavigationCommands
和 ComponentCommands
暴露了一组预定义的通用UI命令。它们都是 RoutedCommand
. RoutedCommand
或 RoutedUICommand
实施 ICommand
.
RoutedCommand
没有实现 Execute
或 CanExecute
方法。它只是引发了相应的 RoutedEvent
.
该事件将遍历视觉树,直到它被某个 CommandBinding
. 这是 CommandBinding
定义或执行 CanExecute
和 Execute
方法或特殊事件处理程序。这意味着实际的命令实现可以在树上的某个地方被定义,而在这个树上的 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();
}