2009-06-06 3 views
7

В моей ViewModel У меня есть две команды:Как присоединить команды к проверке и снятию флажка CheckBox?

ICommand ExecuteMeOnCheck { get; } 
ICommand ExecuteMeOnUncheck { get; } 

я желаю, чтобы присоединить эти команды к CheckBox и имеют один из них выполнить, когда проверяется, а другой выполнить, когда он снят. Каков наилучший способ добиться этого, не загромождая представление с помощью кода?

+0

Что не так с загромождением кода с этим? Это самое простое решение для понимания, и оно по-прежнему сохраняет разделение View-ViewModel. –

ответ

3

Самый простой способ я нашел это связано с заимствованием кучи кода. Я также думаю, что вы не хотите выставлять два события для изменения состояния. Сделайте команду CheckedChangedCommand вместо Проверено и Не отмечено. Привяжите свойство CheckBox.IsChecked зависимости к свойству ViewModelClass. Таким образом, когда ваша команда будет выполнена, вы просто проверите это значение в своей ViewModel.

Сначала начните использовать DelegateCommand с WPF ViewModel toolkit. Вы не знаете, есть ли у вас или нет.

Затем загрузите .zip archive с вкладки «Загрузки» по этой ссылке.

В архиве есть класс EventBehaviourFactory, который упрощает настройку DependencyProperty. Вернувшись на вкладку «Главная» в приведенной выше ссылке, Самуил расскажет вам, как подключить команду в вашем XAML к ViewModel. Вот оно:

<TextBox ff:TextBoxBehaviour.TextChangedCommand="{Binding TextChanged}"/> 

я использовал три класса (DelegateCommand, EventBehaviourFactory и TextBoxBehaviour) линию для линии и имел событие TextChanged работает в моем проекте в течение примерно пяти минут.

Образец для распространения его на другие элементы управления, как вам нужно, тоже легко. Мне удалось связать ListBox.SelectionChanged таким же образом. Создайте новый класс ControlBehaviour и замените «Control» для «TextBox» во всех экземплярах и присоедините DependencyProperty к новому событию.

Это замечательная вещь, когда ваш код позади пуст!

+0

Большое спасибо за этот намек. Я столкнулся с описанной выше проблемой около 3 часов назад и, наконец, нашел это, и это именно то, что мне нужно. Я уже боялся, что мне придется расстаться с прекрасной чистотой вставить всю логику в модель. Единственное решение, о котором я мог думать, - это направить события на модель из представления, но это было бы не так приятно, как делать это так. –

0

хорошо вы можете наследовать от управления CheckBox, добавьте две команды в качестве свойств (Dependency Propertiess), а затем переопределить OnChecked и OnUnchecked методы и вызвать каждую команду в соответствующем месте

1

Другое решение, похоже на Эдди: Attached Command Behaviours Марлоном Греч

Вы можете также использовать свойство Command в CheckBox, чтобы присоединить только одну команду, в которой вы проверить, отмечен ли флажок ...

Или вы можете привязать свойство IsChecked к свойству ViewModel и отреагировать на изменение в настройке этого свойства.

+0

Использование одной команды не кажется хорошей идеей, поскольку она вводит зависимость между командой и CheckBox. Binding IsChecked будет отличным решением в тех случаях, когда команды не нужны. – GraemeF

1

Это относится к ответу Эдди.

Я немного поиграл с ним, и это здорово. Я также создал небольшой шаблон для создания новых команд. Я использую его с Sharpdevelop в качестве фрагмента кода. Просто вставьте следующий код в код (e.g.via фрагмент):

#region $nameCommand 

    public static readonly DependencyProperty $nameCommand = 
     EventBehaviourFactory.CreateCommandExecutionEventBehaviour(
      Control.$nameEvent, "$nameCommand", typeof (ControlBehavior)); 

    public static void Set$nameCommand(DependencyObject o, ICommand value) 
    { 
     o.SetValue($nameCommand, value); 
    } 

    public static ICommand Get$nameCommand(DependencyObject o) 
    { 
     return o.GetValue($nameCommand) as ICommand; 
    } 

    #endregion 

Затем сделайте поиск заменить на «$» имя с именем Event/Command, например,MouseEnter

ОТЕ, это Importand, что вы убедитесь, что вы правильно выбрать имя класса для владельца (в моем случае ControlBehavior.

Я прилагаю класс, который я создал для общей Маус команды в надежде, что другие люди и мы не просто реализуем одно и то же снова и снова, где мы могли бы сэкономить много времени, поделившись. Здесь мой полный класс ControlBehavior (я только реализовал события, которые мне нужны до сих пор):

public static class ControlBehavior 
    { 
     #region MouseEnterCommand 

     public static readonly DependencyProperty MouseEnterCommand = 
      EventBehaviourFactory.CreateCommandExecutionEventBehaviour(
       Control.MouseEnterEvent, "MouseEnterCommand", typeof (ControlBehavior)); 

     public static void SetMouseEnterCommand(DependencyObject o, ICommand value) 
     { 
      o.SetValue(MouseEnterCommand, value); 
     } 

     public static ICommand GetMouseEnterCommand(DependencyObject o) 
     { 
      return o.GetValue(MouseEnterCommand) as ICommand; 
     } 

     #endregion 

     #region MouseLeaveCommand 

     public static readonly DependencyProperty MouseLeaveCommand = 
      EventBehaviourFactory.CreateCommandExecutionEventBehaviour(
       Control.MouseLeaveEvent, "MouseLeaveCommand", typeof (ControlBehavior)); 

     public static void SetMouseLeaveCommand(DependencyObject o, ICommand value) 
     { 
      o.SetValue(MouseLeaveCommand, value); 
     } 

     public static ICommand GetMouseLeaveCommand(DependencyObject o) 
     { 
      return o.GetValue(MouseLeaveCommand) as ICommand; 
     } 

     #endregion 


     #region MouseDoubleClickCommand 

     public static readonly DependencyProperty MouseDoubleClickCommand = 
      EventBehaviourFactory.CreateCommandExecutionEventBehaviour(
      Control.MouseDoubleClickEvent, "MouseDoubleClickCommand", typeof (ControlBehavior)); 

     public static void SetMouseDoubleClickCommand(Control o, ICommand command) 
     { 
      o.SetValue(MouseDoubleClickCommand, command); 
     } 

     public static void GetMouseDoubleClickCommand(Control o) 
     { 
      o.GetValue(MouseDoubleClickCommand); 
     } 

     #endregion 

     #region MouseLeftButtonDownCommand 

     public static readonly DependencyProperty MouseLeftButtonDownCommand = 
      EventBehaviourFactory.CreateCommandExecutionEventBehaviour(
       Control.MouseLeftButtonDownEvent, "MouseLeftButtonDownCommand", typeof (ControlBehavior)); 

     public static void SetMouseLeftButtonDownCommand(DependencyObject o, ICommand value) 
     { 
      o.SetValue(MouseLeftButtonDownCommand, value); 
     } 

     public static ICommand GetMouseLeftButtonDownCommand(DependencyObject o) 
     { 
      return o.GetValue(MouseLeftButtonDownCommand) as ICommand; 
     } 

     #endregion 

    } 

При использовании вышеуказанного шаблона для каждой команды потребовалось всего несколько секунд.

13

Я сделал это с помощью триггера на «IsChecked», который устанавливает команду.

например.

<Style x:Key="checkBoxStyle" TargetType="{x:Type CheckBox}"> 
     <Style.Triggers> 
     <Trigger Property="IsChecked" Value="True"> 
      <Setter Property="Command" 
        Value="{Binding AddThingCommand}" /> 
     </Trigger> 
     <Trigger Property="IsChecked" Value="False"> 
      <Setter Property="Command" 
        Value="{Binding RemoveThingCommand}" /> 
     </Trigger> 
     </Style.Triggers> 
    </Style>