2015-12-16 2 views
1

Я работаю над небольшим WPF MVVM. По сути, пользователь просматривает файл, затем нажимает «Выполнить», чтобы запустить некоторый код в файле.Сделать команду CanExecute зависеть от значения другого поля

В моем классе модели модели я связал два нажатия кнопки («Обзор» и «Выполнить») до ICommand.

internal class DelegateCommand : ICommand 
{ 
    private readonly Action _action; 

    public DelegateCommand(Action action) 
    { 
     _action = action; 
    } 

    public void Execute(object parameter) 
    { 
     _action(); 
    } 

    public bool CanExecute(object parameter) 
    { 
     return true; 
    } 

    public event EventHandler CanExecuteChanged; 
} 

internal class Presenter : INotifyPropertyChanged // VM class 
{ 
    private string filePath; 

    public string FilePath 
    { 
     get { return filePath; } 
     set 
     { 
      filePath = value; 
      RaisePropertyChangedEvent("FilePath"); 
     } 
    } 

    public ICommand ExecuteCommand 
    { 
     // returns a DelegateCommand 
    } 

    public ICommand BrowseCommand 
    { 
     // how to enable/disable button based on whether or not a file has been selected? 
    } 
} 

Здесь CanExecute всегда возвращает истину. Однако мне хотелось бы, чтобы для CanExecute была привязана к тому, был ли выбран файл (например, с FilePath.Length > 0), а затем связать с ним статус кнопки (включен/отключен). Каков наилучший способ сделать это без добавления IsFileSelected наблюдаемого свойства в Presenter?

ответ

3

Обычно у меня есть базовый класс для ICommand экземпляров, который принимает делегат для как его Execute и CanExecute методы. В этом случае вы можете захватывать вещи по объему через закрытие. например что-то в этих строках:

private readonly DelegateCommand _executeCommand; 
public DelegateCommand ExecuteCommand { /* get only */ } 

public Presenter() 
{ 
    _excuteCommand = new DelegateCommand 
    (
     () => /* execute code here */, 
     () => FilePath != null /* this is can-execute */ 
    ); 
} 

public string FilePath 
{ 
    get { return filePath; } 
    set 
    { 
     filePath = value; 
     RaisePropertyChangedEvent("FilePath"); 
     ExecuteCommand.OnCanExecuteChanged(); // So the bound control updates 
    } 
} 
+0

Что должно быть 'OnCanExecuteChanged()' be? И как выглядит привязка в xaml? – rookie

+0

Обнаружил, что xaml не нужно изменять и что я могу вызвать переоценку «CanExecute», добавив «RaisePropertyChangedEvent (« ExecuteCommand »)». – rookie

+1

@rookie См. Prism's [DelegateCommandBase] (https://github.com/PrismLibrary/Prism/blob/0615d57b3a27926c8806c25251f392321eb92a5d/Source/Prism/Commands/DelegateCommandBase.cs), у него есть реализация, включающая использование 'OnCanExecuteChanged', это просто базовый шаблон «поднять событие», чтобы поднять событие, входящее в состав ICommand. –

Смежные вопросы