【问题标题】:Bind to a CheckBox and execute a command in a MVVM way绑定到 CheckBox 并以 MVVM 方式执行命令
【发布时间】:2011-04-23 00:21:46
【问题描述】:

我有一个类似于this one 的问题,但情况更详细。我也在尝试使用模型视图视图模型模式来实现解决方案。

MainView 中,我有一个按钮,它调用存储在MainViewModel 中的命令(我们称之为Execute)。我还希望在单击鼠标左键时调用此命令(实际上,仅在 Up 上),但仅在选中 MouseUpCheckBox 时调用。

当我拥有视图中的所有代码时,我为Execute 进行了静态绑定,但随后使用ElementName 绑定到Window(名为w_window)的IsChecked 并检查了属性值MouseLeftButtonUpEvent 处理程序。

XAML

<Button Command="{x:Static local:MainView.Execute}">
    Execute
</Button>
<CheckBox IsChecked="{Binding ElementName=w_window, Path=ExecuteOnMouseUp}">
    Execute on Mouse Up
</CheckBox>

C#

public MainView()
{
    InitializeComponent();
    this.CommandBindings.Add(new CommandBinding(Execute, ExecuteExecuted));
    MyDesigner.AddHandler(UIElement.MouseLeftButtonUpEvent, new RoutedEventHandler((o, eventArgs) =>
    {
        if (ExecuteOnMouseUp)
        {
            Execute.Execute(null, this);
        }
    }), true);
}

#region ExecuteOnMouseUp
/// <summary>
/// ExecuteOnMouseUp Dependency Property
/// </summary>
public static readonly DependencyProperty ExecuteOnMouseUpProperty =
    DependencyProperty.Register("ExecuteOnMouseUp", typeof(bool), typeof(MainView),
        new FrameworkPropertyMetadata((bool)false));

/// <summary>
/// Gets or sets the ExecuteOnMouseUp property. This dependency property 
/// indicates ....
/// </summary>
public bool ExecuteOnMouseUp
{
    get { return (bool)GetValue(ExecuteOnMouseUpProperty); }
    set { SetValue(ExecuteOnMouseUpProperty, value); }
}
#endregion

#region Execute
/// <summary>
/// The Execute command ....
/// </summary>
public static RoutedUICommand Execute
    = new RoutedUICommand("Execute", "Execute", typeof(MainView));

private void ExecuteExecuted(object sender, ExecutedRoutedEventArgs e)
{
    ...
}
#endregion

如何将此代码从我的视图移植到视图模型中?我应该使用附加属性吗?有没有办法将复选框值绑定到CommandCanExecute 处理程序中的参数?处理这种情况的惯用 WPF/MVVM 方式是什么?

【问题讨论】:

标签: c# wpf mvvm binding


【解决方案1】:

Rachel 在上面提供了一个非常好的解决方案,但为了便于理解,我在下面提供了她提到的不同方法的详细信息(再次感谢@Rachel)。

<...
 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
...>
<i:Interaction.Triggers>
    <i:EventTrigger EventName="ExecuteOnMouseUp">
        <i:InvokeCommandAction Command="{Binding Execute}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

我尝试了两种方法,发现在处理路由事件方面存在一些差异。但总的来说,这两种方法都很有效。

【讨论】:

    【解决方案2】:

    在我看来,对于绑定到 Button 或 CheckBox 这样简单的任务,您的示例看起来有点过于复杂。

    您可以查看 WPF Application Framework (WAF)ViewModel 示例应用程序。它展示了如何以 MVVM 友好的方式将 IsChecked 属性绑定到 ViewModel。

    【讨论】:

      【解决方案3】:

      查看this 文章。它向您展示了如何构建一个 AttachedCommand,它可以让您完成您正在尝试做的事情。

      【讨论】:

      • 像魅力一样工作!但已经是5年前了。现在有标准(或 PRISM)解决方案吗?
      • @Klaus 你可以使用Interaction.Triggers,但我通常只使用AttachedCommandBehavior
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-23
      • 2014-06-27
      • 2011-04-04
      • 1970-01-01
      相关资源
      最近更新 更多