oco*_*odo 16 wpf routed-commands
我有兴趣创建可在我的WPF应用程序中的任何位置使用的命令.
我希望他们能够在相同的方式工作Cut,Copy,Paste和其他应用程序级别的命令,即:
<Button Command="Paste" />
我假设我可以为Application实例设置CommandBindings,但该属性不可用.
这是怎么做到的?
到目前为止我所管理的最好的是在顶级窗口上创建一套命令,然后像这样访问它们......:
<Button Command="{x:Static namespace::MainWindow.CommandName}" />
哪个有效,但当然紧密耦合,非常脆弱.
小智 34
您可以为WPF应用程序的"所有Windows"设置CommandBindings,并在Application类中实现命令处理程序.
首先,创建一个静态命令容器类.例如,
namespace WpfApplication1 
{
    public static class MyCommands
    {
        private static readonly RoutedUICommand doSomethingCommand = new RoutedUICommand("description", "DoSomethingCommand", typeof(MyCommands));
        public static RoutedUICommand DoSomethingCommand
        {
            get
            {
                return doSomethingCommand;
            }
        }
    }
}
接下来,将自定义命令设置为Button.Command.
<Window x:Class="WpfApplication1.MainWindow"
        ...
        xmlns:local="clr-namespace:WpfApplication1">
    <Grid>
        ...
        <Button Command="local:MyCommands.DoSomethingCommand">Execute</Button>
    </Grid>
</Window>
最后,在Application类中实现自定义命令的命令处理程序.
namespace WpfApplication1 
{
    public partial class App : Application
    {
        public App()
        {
            var binding = new CommandBinding(MyCommands.DoSomethingCommand, DoSomething, CanDoSomething);
            // Register CommandBinding for all windows.
            CommandManager.RegisterClassCommandBinding(typeof(Window), binding);
        }
        private void DoSomething(object sender, ExecutedRoutedEventArgs e)
        {
            ...
        }
        private void CanDoSomething(object sender, CanExecuteRoutedEventArgs e)
        {
            ...
            e.CanExecute = true;
        }
    }
}
StackOverflow成员帮助我这么多时间,我现在决定贡献和分享;-)
根据Shou Takenaka的回答,这是我的实施.
我的兴趣是只生成一个可重用的文件.
首先,创建一个命令容器类
namespace Helpers
{
    public class SpecificHelper
    {
        private static RoutedUICommand _myCommand = new RoutedUICommand("myCmd","myCmd", typeof(SpecificHelper));
        public static RoutedUICommand MyCommand { get { return _myCommand; } }
        static SpecificHelper()
        {
            // Register CommandBinding for all windows.
            CommandManager.RegisterClassCommandBinding(typeof(Window), new CommandBinding(MyCommand, MyCommand_Executed, MyCommand_CanExecute));
        }
        // TODO: replace UIElement type by type of parameter's binded object
        #region MyCommand
        internal static void MyCommand_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            if (!verifType<UIElement>(e.Parameter)) return;
            e.Handled = true;
            // TODO : complete the execution code ...
        }
        internal static void SelectAll_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (!verifType<UIElement>(e.Parameter)) return;
            e.CanExecute = true;
            var item = (e.Parameter as UIElement);
            // TODO : complete the execution code ...
        }
        #endregion
        private static bool verifType<T>(object o)
        {
            if (o == null) return false;
            if (!o.GetType().Equals(typeof(T))) return false;
            return true;
        }
    }
}
接下来,在App.xaml中声明一个资源:
<Application x:Class="Helper.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:h="clr-namespace:Helpers"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d" 
             StartupUri="MainWindow.xaml" >
    <Application.Resources>
        <h:SpecificHelper x:Key="sh" />
    </Application.Resources>
</Application>
最后,将任何命令属性绑定到应用程序资源的属性:
<Button Content="Click to execute my command"
        Command="{Binding Source={StaticResource sh}, Path=MyCommand}"
        CommandParameter="{Binding ElementName=myElement}" />
这是所有人:-)
我不喜欢其他解决方案的复杂性,但是经过几个小时的研究,我发现它确实很简单。
首先,像平常一样设置命令,但是为WPF添加静态属性,以便它可以获取命令的实例。
class MyCommand : ICommand
{
    // Singleton for the simple cases, may be replaced with your own factory     
    public static ICommand Instance { get; } = new MyCommand();
    public bool CanExecute(object parameter)
    {
        return true; // TODO: Implement
    }
    public event EventHandler CanExecuteChanged;
    public void Execute(object parameter)
    {
        // TODO: Implement       
    }   
}
在XAML(最后一行)中添加对命令名称空间的引用,如下所示:
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:commands="clr-namespace:MyProject.Commands">     
然后像这样在XAML中引用您的静态属性:
<Button Content="Button" Command="commands:MyCommand.Instance" />