UserControl 中的 RoutedCommand 未按预期工作
RoutedCommand in UserControl is not working as expected
我正在尝试在我的 UserControls
中使用 RoutedCommands
,灵感来自 Josh Smith 的这篇文章。
https://joshsmithonwpf.wordpress.com/2008/03/18/understanding-routed-commands/
我做的和文章中的例子有点不同,在Usercontrol中定义了RoutedCommand和CommandBindings。
现在我正尝试在我的主窗口中使用它。这样通过点击Button,UserControl中的Command就被执行了。不幸的是,我得到的是一个禁用的按钮。
Foo_CanExecute()
方法从未执行。
<UserControl x:Class="RoutedCommandTest.ViewControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:RoutedCommandTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.CommandBindings>
<CommandBinding
Command="{x:Static local:ViewControl.Foo}"
PreviewCanExecute="Foo_CanExecute"
PreviewExecuted="Foo_Executed"
/>
</UserControl.CommandBindings>
<Grid>
</Grid>
</UserControl>
在ViewControl.xaml.cs
public static readonly RoutedCommand Foo = new RoutedCommand();
void Foo_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
void Foo_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("The Window is Fooing...");
}
public ViewControl()
{
InitializeComponent();
}
在MainWindow.xaml中:
<Window x:Class="RoutedCommandTest.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:local="clr-namespace:RoutedCommandTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:ViewControl/>
<Button Content="Foo" Margin="0 5" Command="{x:Static local:ViewControl.Foo}"/>
</Grid>
</Window>
您的命令在用户控件中,而按钮在主窗口中。
其中可能包含您的用户控件。
喜欢冒泡和路由事件(用于驱动它们)。
已执行查找将可视化树向上冒泡到绑定的命令。
PreviewExecuted 查找将可视化树向下传送到绑定的命令。
由于您的按钮位于用户控件的父级中,我不确定冒泡或隧道是否有效。
但是隧道将是 PreviewExecuted 和 PreviewCanExecute。
要正确执行路由命令可能非常棘手。
有时您需要做的一件事是绑定 commandtarget 以告诉它去哪里查看。
例如:
<Grid>
<local:UserControl1 x:Name="UC1" Height="60" Width="100"/>
<Button Content="Foo" TextElement.FontSize="30" Command="{x:Static local:UserControl1.Foo}"
CommandTarget="{Binding ElementName=UC1}"
/>
</Grid>
适合我。
我很少发现它们有用 - 这是使它们不如您最初想象的有用的方面之一。
编辑:
也许值得一提的是,与常规 icommand 相比,这些命令没有吸引力。您需要使用静态,这意味着它只适用于非常通用的命令,或者您需要将在代码后面的事件处理程序。
另一方面。
如果您要编写的内容必须与具有焦点的内容通用。就像说一个带有多个文本框的文本编辑器,你正在做文本操作。路由命令可能是合适的。不过,我在开发的应用程序中从未遇到过这样的要求。
我正在尝试在我的 UserControls
中使用 RoutedCommands
,灵感来自 Josh Smith 的这篇文章。
https://joshsmithonwpf.wordpress.com/2008/03/18/understanding-routed-commands/
我做的和文章中的例子有点不同,在Usercontrol中定义了RoutedCommand和CommandBindings。
现在我正尝试在我的主窗口中使用它。这样通过点击Button,UserControl中的Command就被执行了。不幸的是,我得到的是一个禁用的按钮。
Foo_CanExecute()
方法从未执行。
<UserControl x:Class="RoutedCommandTest.ViewControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:RoutedCommandTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.CommandBindings>
<CommandBinding
Command="{x:Static local:ViewControl.Foo}"
PreviewCanExecute="Foo_CanExecute"
PreviewExecuted="Foo_Executed"
/>
</UserControl.CommandBindings>
<Grid>
</Grid>
</UserControl>
在ViewControl.xaml.cs
public static readonly RoutedCommand Foo = new RoutedCommand();
void Foo_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
void Foo_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("The Window is Fooing...");
}
public ViewControl()
{
InitializeComponent();
}
在MainWindow.xaml中:
<Window x:Class="RoutedCommandTest.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:local="clr-namespace:RoutedCommandTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:ViewControl/>
<Button Content="Foo" Margin="0 5" Command="{x:Static local:ViewControl.Foo}"/>
</Grid>
</Window>
您的命令在用户控件中,而按钮在主窗口中。
其中可能包含您的用户控件。
喜欢冒泡和路由事件(用于驱动它们)。
已执行查找将可视化树向上冒泡到绑定的命令。
PreviewExecuted 查找将可视化树向下传送到绑定的命令。
由于您的按钮位于用户控件的父级中,我不确定冒泡或隧道是否有效。
但是隧道将是 PreviewExecuted 和 PreviewCanExecute。
要正确执行路由命令可能非常棘手。
有时您需要做的一件事是绑定 commandtarget 以告诉它去哪里查看。
例如:
<Grid>
<local:UserControl1 x:Name="UC1" Height="60" Width="100"/>
<Button Content="Foo" TextElement.FontSize="30" Command="{x:Static local:UserControl1.Foo}"
CommandTarget="{Binding ElementName=UC1}"
/>
</Grid>
适合我。
我很少发现它们有用 - 这是使它们不如您最初想象的有用的方面之一。
编辑:
也许值得一提的是,与常规 icommand 相比,这些命令没有吸引力。您需要使用静态,这意味着它只适用于非常通用的命令,或者您需要将在代码后面的事件处理程序。
另一方面。
如果您要编写的内容必须与具有焦点的内容通用。就像说一个带有多个文本框的文本编辑器,你正在做文本操作。路由命令可能是合适的。不过,我在开发的应用程序中从未遇到过这样的要求。