#c# #wpf #command #commandbinding
#c# #wpf #команда #привязка команд
Вопрос:
В принципе, у меня есть привязка команды для самой команды, назначенной Window.Привязки команд:
<CommandBinding Command="local:TimerViewModel.AddTimer"
CanExecute="local:TimerViewModel.AddTimer_CanExecute"
Executed="local:TimerViewModel.AddTimer_Executed" />
local — это пространство имен, генерируемое по умолчанию, указывающее на пространство имен приложения. Чего я пытаюсь достичь здесь, так это иметь обработку команды внутри TimerViewModel, но я продолжаю получать следующую ошибку:
CanExecute=»local:TimerViewModel.»AddTimer_CanExecute» недопустимо. ‘local:TimerViewModel.’ AddTimer_CanExecute’ не является допустимым именем метода обработчика событий. Допустимы только методы экземпляра в сгенерированном или написанном в коде классе.
TimerViewModel довольно прост, но я считаю, что мне чего-то не хватает:
public class TimerViewModel : ViewModelBase
{
public TimerViewModel()
{
_timers = new ObservableCollection<TimerModel>();
_addTimer = new RoutedUICommand("Add Timer", "AddTimer", GetType());
}
private ObservableCollection<TimerModel> _timers;
public ObservableCollection<TimerModel> Timers
{
get { return _timers; }
}
private static RoutedUICommand _addTimer;
public static RoutedUICommand AddTimer
{
get { return _addTimer; }
}
public void AddTimer_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
public void AddTimer_Executed(object sender, ExecutedRoutedEventArgs e)
{
_timers.Add(new TimerModel(TimeSpan.FromSeconds((new Random()).Next())));
}
}
Кто-нибудь может указать на ошибки, которые я совершаю?
Ответ №1:
Также взгляните на RelayCommand Джоша Смита. Использование этого позволило бы вам написать вышеуказанное следующим образом:
public class TimerViewModel : ViewModelBase {
public TimerViewModel() {
Timers = new ObservableCollection<TimerModel>();
AddTimerCommand = new RelayCommand(() => AddTimer());
}
public ObservableCollection<TimerModel> Timers {
get;
private set;
}
public ICommand AddTimerCommand {
get;
private set;
}
private void AddTimer() {
Timers.Add(new TimerModel(TimeSpan.FromSeconds((new Random()).Next())));
}
}
Комментарии:
1. Это… Действительно приятно! Я еще не до конца понимаю, как это работает, и мне не терпится выяснить, прежде чем внедрять это, но это слишком аккуратно, чтобы не реализовывать! Спасибо!
2. Как я и предполагал, похоже, требуется некоторый дополнительный код… По-видимому, ‘new RelayCommand(AddTimer);’ не выполняет трюк, поскольку предупреждает меня, что: Аргумент 1: не удается преобразовать из ‘method group’ в ‘System. Действие<объект>’
3. Извините, я виноват. Вместо этого запишите это как
() => AddTimer()
; Я обновлю приведенный выше код.4. Разобрался, хотя для того, который я нашел, правильным использованием было бы (object x) => AddTimer (x) Тем не менее, мне удалось это сделать, но прямо сейчас я изо всех сил пытаюсь привязать его к кнопке. Command=»AddTimerCommand» было бы правильным подходом или? Потому что при этом говорится «не удается преобразовать AddTimerCommand»… РЕДАКТИРОВАТЬ: Я виноват. Следовало бы написать Command=»{Привязка AddTimerCommand}». Спасибо за вашу помощь!
Ответ №2:
Взгляните на http://www.wpftutorial.net/DelegateCommand.html для примера того, как реализовать команду делегирования для WPF. Это позволяет вам подключать Execute и CanExecute в качестве обработчиков событий. Если вы используете RoutedUICommand напрямую, вам нужно вывести из нее пользовательскую команду и переопределить Execute и CanExecute своими функциями.
Комментарии:
1. Я готов создать пользовательскую команду, но я немного запутался в том, как это сделать. Есть какие-либо советы / ссылки?