2015-08-19 1 views
0

этот вопрос только для понимания. Я в порядке с моей IDE, рассказывающей мне об ошибках, которых там нет, до тех пор, пока приложение работает.Команды WPF - привязки не работают, прямые вызовы делают. Зачем?


Я разрабатываю приложение WPF с #, используя шаблон MVVM; данные и CommandBindings.

Однако я заметил, что когда я использую привязку для привязки к Command, команда не выполняется, однако я не получаю никаких ошибок, отображаемых в IDE или отладочном выходе.

Например:

Command="{Binding MyCommand}" 
<!-- Or --> 
Command="{Binding cmd:Commands.MyCommand}" 

Однако просто писать

Command="cmd:Command.MyCommand" 

работает просто отлично, хотя XAML-редактор показывает мне ошибку, сказав, что команда не может быть найден.

Почему это так?

+0

Можете ли вы показать свою реализацию MyCommand? – Sasha

+0

«Я разработчик веб-приложений, приложений и настольных компьютеров, моя работа в основном заключается в разработке программного обеспечения для компаний, которым требуется бэкэнд на стороне компании, серверная сторона и клиентский интерфейс». Повезло тебе. Как объявить MyCommand, о котором вы говорите? – VMaleev

+1

частный RelayCommand _myCommand, ///

/// Выполнить команду, которая делает это, это и это /// общественного RelayCommand МояКоманда { ПОЛУЧИТЬ { обратный _myCommand ?? (_myCommand = новый RelayCommand (новое действие (() => { DoSomething(); }), нового Func (() => { возвращающих; })); } } – SimonC

ответ

1

Вот RelayCommand, что я использую:

public sealed class RelayCommand : ICommand 
{ 
    #region Fields 

    readonly Action<object> _action; 
    readonly Action<object> _execute; 
    readonly Predicate<object> _canExecute; 

    #endregion Fields 

    #region Constructors 

    public RelayCommand(Action<object> action) 
    { 
     if (action != null) 
      _action = action; 
    } 

    public RelayCommand(Action<object> execute, Predicate<object> canExecute) 
    { 
     if (execute == null) 
      throw new ArgumentNullException("execute"); 

     _execute = execute; 
     _canExecute = canExecute; 
    } 

    #endregion Constructors 

    #region ICommand Members 

    public void Execute(object parameter) 
    { 
     if (_execute != null) 
      _execute(parameter); 
     else 
     { 
      _action(parameter ?? "Command parameter is null!"); 
     } 
    } 

    [DebuggerStepThrough] 
    public bool CanExecute(object parameter) 
    { 
     return _canExecute == null || _canExecute(parameter); 
    } 

    public event EventHandler CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove { CommandManager.RequerySuggested -= value; } 
    } 

    #endregion 
} 

Что вам нужно реализовать в команде ViewModel, и вы будете в состоянии связать это следующим образом:

Command="{Binding MyCommand}" 

Редактировать As для меня я предпочитаю использовать две библиотеки - взаимодействия и интерактивность. С их помощью легко привязать все события к viewModel. Например:

XAML:

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="Click"> 
      <ei:CallMethodAction TargetObject="{Binding}" MethodName="OnClick"/> 
    </i:EventTrigger>     
</i:Interaction.Triggers> 

и ViewModel:

public void OnClick(object sender, RoutedEventArgs e) 
{ 
    //your code 
} 
1

Вам нужно привязать к свойству типа ICommand. Эта функция будет использовать функцию RelayCommand с вашей функцией.

Реализация по умолчанию RelayCommand выглядит следующим образом:

public class RelayCommand : ICommand 
{ 
    public event EventHandler CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove { CommandManager.RequerySuggested -= value; } 
    } 
    private readonly Action methodToExecute; 
    private readonly Func<bool> canExecuteEvaluator; 
    public RelayCommand(Action methodToExecute, Func<bool> canExecuteEvaluator) 
    { 
     this.methodToExecute = methodToExecute; 
     this.canExecuteEvaluator = canExecuteEvaluator; 
    } 
    public RelayCommand(Action methodToExecute) 
     : this(methodToExecute, null) 
    { 
    } 
    public bool CanExecute(object parameter) 
    { 
     if (canExecuteEvaluator == null) 
     { 
      return true; 
     } 
     bool result = canExecuteEvaluator.Invoke(); 
     return result; 
    } 
    public void Execute(object parameter) 
    { 
     methodToExecute.Invoke(); 
    } 
} 

В ViewModel вам необходимо реализовать свойство типа ICommand с OnClick-функции:

public ICommand MyCommand 
{ 
    get 
    { 
     return new RelayCommand(() => 
     { 
      doSomething(); 
     }); 
    } 
} 

Теперь вы можете для динамической привязки Button-Command вашего вида к ICommand во время выполнения:

Command="{Binding MyCommand}" 

Кроме того, имейте в виду, что Command="cmd:Command.MyCommand" является статической реализацией.

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