开发者

Bind to a CheckBox and execute a command in a MVVM way

I have a question similar to this one, but in a more detailed situation. I am also trying to implement the solution using the Model View Viewmodel pattern.

In MainView, I have a button which calls a command (we'll call it Execute) stored in MainViewModel. I also want this command to be called when the left button of the mouse is clicked (actually, only on Up), but only when MouseUpCheckBox is checked.

When I had all the code in the view, I did static binding for Execute, but then used ElementName binding to the Window (named w_window) for IsChecked and checked the property value in the MouseLeftButtonUpEvent handler.

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>
///开发者_StackOverflow中文版 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

How can I port this code from my view into the viewmodel? Should I use an attached property? Is there a way to bind the checkbox value to a parameter in the Command, or maybe in the CanExecute handler? What's the idiomatic WPF/MVVM way of dealing with this kind of situation?


Check out this article. It shows you how to build an AttachedCommand which will let you accomplish what you are trying to do.


In my opinion your example looks a bit too complicated for such a simple task as binding to a Button or a CheckBox.

You might have a look at the ViewModel sample application of the WPF Application Framework (WAF). It shows how you can bind the IsChecked property to the ViewModel in a MVVM friendly way.


Rachel provided a very good solution above, but in sake of comprehension I'm providing below details of different approach she mentioned (thanks to @Rachel again).

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

I tried both and found some differences in handling routed events. But in general, both methods work like a charm.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜