Как мне прикрепить команды к проверке и снятию отметки с CheckBox? - PullRequest
7 голосов
/ 06 июня 2009

В моей ViewModel у меня есть две команды:

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

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

Ответы [ 5 ]

14 голосов
/ 23 апреля 2010

Я сделал это с помощью триггера «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>
3 голосов
/ 06 июня 2009

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

Сначала начните использовать DelegateCommand из WPF ViewModel toolkit . Из вашего поста не ясно, есть вы или нет.

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

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

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

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

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

Это прекрасно, когда ваш код пуст!

1 голос
/ 26 июля 2009

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

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

#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 

Затем выполните поиск и замените «$ name» на имя события / команды, например. MouseEnter

Примечание: важно убедиться, что вы выбрали правильное имя класса для владельца (в моем случае 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

    }

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

1 голос
/ 06 июня 2009

Другое решение, похожее на решение Эдди: Прикрепленное поведение команд от Марлона Греча

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

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

0 голосов
/ 06 июня 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...