Как переместить обработчик команд в другой файл - PullRequest
1 голос
/ 17 апреля 2019

Я нашел пользовательский пример перенаправленной команды из Примеры Microsoft , он хорошо работает.

<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 .

Как изменить XAML, если я переместу эти два обработчика в xxxx.cs ?

Редактировать, добавить дополнительную информацию

Обработчики команд определены в 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 голосов
/ 17 апреля 2019

Нельзя переместить обработчики фактических событий, которые вы подключили в разметке XAML, в другой класс, но вы могли бы реализовать логику в другом классе:

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" />

Пожалуйста, обратитесь к этому сообщению в блоге для получения дополнительной информации о концепции.

0 голосов
/ 17 апреля 2019

Вы можете продолжать использовать static команды, но гораздо чаще можно увидеть реализацию ICommand, которая называется RelayCommand. Это позволяет нам легче использовать MVVM, чтобы ваша модель представления могла позаботиться о командах. Вот базовый пример реализации 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 как свойство к вашей модели вида, например, так:

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
        ...
    }
}

Для получения дополнительной информации о реализации MVVM и ICommand имеется множество ресурсов. Этот довольно прост для понимания новичком WPF и должен дать вам немного больше понимания того, как действовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...