如何附加命令以检查和取消选中CheckBox?

时间:2009-06-06 10:31:07

标签: wpf xaml data-binding mvvm

在我的ViewModel中,我有两个命令:

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

我希望将这些命令附加到CheckBox,并在检查时执行其中一个命令,而在取消选中时执行另一个命令。在没有使用代码隐藏的视图混乱的情况下实现这一目标的最佳方法是什么?

5 个答案:

答案 0 :(得分:14)

我使用“IsChecked”触发器来设置命令。

e.g。

<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>

答案 1 :(得分:3)

我发现这样做的最简单方法是借用一堆代码。我还认为您不希望为状态更改公开两个事件。命令CheckedChangedCommand而不是Checked和Unchecked。将CheckBox.IsChecked依赖项属性绑定到ViewModelClass上的属性。这样,当您的命令执行时,您只需在ViewModel中检查该值。

首先,从WPF ViewModel toolkit开始使用DelegateCommand。您的帖子中不清楚您是否在。

接下来,从此链接的“下载”标签下载.zip archive

存档有一个名为EventBehaviourFactory的类,可以更轻松地设置DependencyProperty。回到上面链接的Home选项卡,Samuel告诉您如何将XAML中的Command连接到ViewModel。这是:

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

我使用了三个类(DelegateCommand,EventBehaviourFactory和TextBoxBehaviour)行作为行,并且在大约五分钟内让TextChanged事件在我的项目中工作。

将其扩展到您需要做的其他控件的模式也很简单。我设法以相同的方式连接ListBox.SelectionChanged。创建一个新的ControlBehaviour类,并在所有实例中将“Control”替换为“TextBox”,并将DependencyProperty附加到新事件。

当你的代码背后是空的时候,这是一件很美妙的事情!

答案 2 :(得分:1)

另一个解决方案,类似于Eddie的:Marlon Grech的Attached Command Behaviours

你也可以使用CheckBox的Command属性只附加一个命令,你可以在其中测试是否选中了复选框......

或者您可以将IsChecked属性绑定到ViewModel的属性,并对该属性的setter中的更改做出反应。

答案 3 :(得分:1)

这与Eddie的回答有关。

我玩了一下它很棒我也创建了一个用于创建新命令的小模板。我将它与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

ote,这是重要的,你要确保为所有者选择正确的类名(在我的案例中是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

    }

通过使用上面的模板,每个命令只需要几秒钟。

答案 4 :(得分:0)

你可以从checkBox控件继承,将两个命令添加为属性(Dependency Propertiess),然后覆盖OnChecked和OnUnchecked方法并在适当的位置触发每个命令