如何将命令处理程序移到另一个文件

时间:2019-04-17 07:57:07

标签: c# wpf xaml

我发现了一个Microsoft Examples形式的自定义路由命令示例,它运行良好。

<Window x:Class="CustomRoutedCommand.MainWindow"
        ...
        xmlns:local="clr-namespace:CustomRoutedCommand">
    <Window.CommandBindings>
        <CommandBinding Command="{x:Static local:MainWindow.ColorCmd}"
                    Executed="ColorCmdExecuted"
                    CanExecute="ColorCmdCanExecute"/>
    </Window.CommandBindings>

void ColorCmdExecuted(object sender, ExecutedRoutedEventArgs e)void ColorCmdCanExecute(object sender, CanExecuteRoutedEventArgs e) MainWindow.cs 中定义。

如果将这两个处理程序移动到 xxxx.cs ,如何更改XAML?

编辑,添加更多信息

命令处理程序在 MainWindow.cs 中定义,我将代码剪切并粘贴到另一个文件中,如下所示,然后编译出错。 错误CS1061'MainWindow'不包含'ColorCmdExecuted'的定义

// xxxx.cs
namespace CustomRoutedCommand
{
    public class xxxx
    {
        // ExecutedRoutedEventHandler for the custom color command.
        private void ColorCmdExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var target = e.Source as Panel;
            if (target != null)
            {
                target.Background = target.Background == Brushes.AliceBlue ? Brushes.LemonChiffon : Brushes.AliceBlue;
            }
        }

        // CanExecuteRoutedEventHandler for the custom color command.
        private void ColorCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (e.Source is Panel)
            {
                e.CanExecute = true;
            }
            else
            {
                e.CanExecute = false;
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

您不能将在XAML标记中关联的acual事件处理程序移动到另一个类,但是可以在另一个类中实现逻辑:

public partial class MainWindow : Window
{
    public static RoutedCommand ColorCmd = new RoutedCommand();

    public MainWindow()
    {
        InitializeComponent();
    }

    private void ColorCmdExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        xxxx.ColorCmdExecuted(e.Source);
    }

    private void ColorCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = xxxx.ColorCmdCanExecute(e.Source);
    }
}

public class xxxx
{
    public static void ColorCmdExecuted(object parameter)
    {
        var target = parameter as Panel;
        if (target != null)
        {
            target.Background = target.Background == Brushes.AliceBlue ? Brushes.LemonChiffon : Brushes.AliceBlue;
        }
    }

    public static bool ColorCmdCanExecute(object parameter)
    {
        return parameter is Panel;
    }
}

您可能希望将RoutedCommand替换为ICommand接口的自定义实现,该接口可以在直接执行命令时执行某些操作:

public class RelayCommand : ICommand
{
    private Action<object> _execute;
    private Predicate<object> _canExecute;

    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        _execute = execute;
        _canExecute = canExecute;
    }
    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        if (_canExecute == null)
            return true;
        return _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        if (_execute != null)
            _execute(parameter);
    }
}

public partial class MainWindow : Window
{
    public static RelayCommand ColorCmd = new RelayCommand(xxxx.ColorCmdExecuted, null);

    public MainWindow()
    {
        InitializeComponent();
    }
}

public class xxxx
{
    public static void ColorCmdExecuted(object parameter)
    {
        var target = parameter as Panel;
        if (target != null)
        {
            target.Background = target.Background == Brushes.AliceBlue ? Brushes.LemonChiffon : Brushes.AliceBlue;
        }
    }
}

XAML:

<Button Command="{x:Static local:MainWindow.ColorCmd}" Content="CommandTarget = FristStackPanel" />

有关该概念的更多信息,请参阅this博客文章。

答案 1 :(得分:0)

您可以继续使用static命令,但是看到ICommand的{​​{1}}实现被更普遍地使用。这使我们可以更轻松地利用MVVM,以便您的视图模型可以处理命令。这是RelayCommand的基本示例实现:

ICommand

然后,您将public class RelayCommand : ICommand { private Predicate<object> _canExecute; private Action<object> _execute; public RelayCommand(Predicate<object> canExecute, Action<object> execute) { _canExecute = canExecute; _execute = execute; } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public bool CanExecute(object parameter) { return _canExecute(parameter); } public void Execute(object parameter) { _execute(parameter); } } 作为属性添加到视图模型中,如下所示:

RelayCommand

有关MVVM和public class ViewModel : ViewModelBase { private RelayCommand colorCmd; public ICommand ColorCmd { get { colorCmd ?? colorCmd = new RelayCommand(p => ColorCmdCanExecute(), p => ColorCmdExectued()); return colorCmd; } } private bool ColorCmdCanExecute() { //CanExecute code here ... } private void ColorCmdExecuted() { //Command execute code here ... } } 实现的更多信息,有很多资源。对于WPF初学者来说,This one非常容易理解,应该使您对如何进行操作有更多了解。