Как привязать (Binding) команду (ICommand) к кнопке на FluentRibbon из UserControl (MVVM)

367
28 апреля 2017, 16:31

Здравствуйте!

В проекте имеется много разных сущностей, которые надо отображать и списком в таблице и подробно и иметь возможность каждую править. Для этого было принято решение использовать связку AvalonDock+FluentRibbon. Создавать и показывать сущности в AvalonDock я научился через UserControl. А как теперь привязать команды обработки к кнопкам на Ribbon? И как сделать возможным прятать/отображать эти кнопки по мере необходимости при работе пользователя с приложением? И по возможности всё это в рамках паттерна MVVM.

Есть ли возможность расширить ICommand, чтобы добавить в него дополнительные свойства, и эти свойства правильно интерпретировались и обрабатывались элементами управления в окне/UserControl? Например свойство видимости? Просто иногда бывает дешевле сделать редактирование (например справочник) прямо в таблице, и тогда надо спрятать кнопки работы со списком, и показать кнопки работы с записью (сохранить, отмена)

Спасибо

p.s. Я только начинаю изучать WPF и MVVM, перехожу с WinForms

Answer 1

Создайте во VM поле типа ICommand. Используйте одну из реализаций этого интерфейса, лично я пользуюсь DelegateCommand примерно такого содержания (есть много MVVM библиотек, во всех есть что-то подобное):

public class DelegateCommand : ICommand
{
    private readonly Predicate<object> _canExecute;
    private readonly Action<object> _execute;
    public event EventHandler CanExecuteChanged;
    public DelegateCommand(Action<object> execute) 
                   : this(execute, null)
    {
    }
    public DelegateCommand(Action<object> execute, 
                   Predicate<object> canExecute)
    {
        _execute = execute;
        _canExecute = canExecute;
    }
    public override bool CanExecute(object parameter)
    {
        if (_canExecute == null)
        {
            return true;
        }
        return _canExecute(parameter);
    }
    public override void Execute(object parameter)
    {
        _execute(parameter);
    }
    public void RaiseCanExecuteChanged()
    {
        if( CanExecuteChanged != null )
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }
    }
}

Пусть во VM у вас будет команда и два метода:

public DelegateCommand SaveCommand {get;} = new DelegateCommand(Save,CanSave);
private void Save(){...}
private bool CanSave(){
    return true; // Проверка, можно ли выполнить сохранение
}

Задайте привязку к этой команде:

<Button Content="Сохранить" Command="{Binding SaveCommand}" />

В зависимости от результата выполнения метода CanSave кнопка будет доступна или нет. Можно обновить статус кнопки вызовом SaveCommand.RaiseCanExecuteChanged().

Чтобы вообще скрыть кнопку, просто создайте привязку свойства Visibility к свойству во VM.

READ ALSO
Открыть с помощью

Открыть с помощью

VS2015, Win10, программа на C# WPF

232
Чем отличается iTextSharp от iText и что сейчас лучше использовать?

Чем отличается iTextSharp от iText и что сейчас лучше использовать?

В Nuget сейчас обе библиотеки имеют достаточно свежие версии

272
&ldquo;Частичная&rdquo; десериализация объекта

“Частичная” десериализация объекта

В ответ на запрос к API я получаю json следующей структуры:

248