wpf Binding commands to ToggleButton Checked and Unchecked events

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25778802/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 11:21:09  来源:igfitidea点击:

Binding commands to ToggleButton Checked and Unchecked events

wpfxamlcommandtogglebutton

提问by ck84vi

I have a ToggleButton in my C# WPF application where I would like to bind one Command to the Checked event and one Command to the Unchecked event.

I have a ToggleButton in my C# WPF application where I would like to bind one Command to the Checked event and one Command to the Unchecked event.

What I have currently is the following:

What I have currently is the following:

<ToggleButton Name="btnOpenPort" Style="{StaticResource myOnOffBtnStyle}" Content="Open Port"
              Checked="btnOpenPort_Checked" Unchecked="btnOpenPort_Unchecked"
              IsChecked="{Binding Path=PortViewModel.PortIsOpen, Mode=OneWay}"
              Canvas.Left="75" Canvas.Top="80" Height="25" Width="100"/>

But this is not what I aim to do. Because in this case, I would have to set properties in the code behind for the Checked and Unchecked event. Instead, I would like to call a Command (ICommand) in my ViewModel once the Checked or Unchecked event gets fired so that I don't need any code-behind for my toggle button.

But this is not what I aim to do. Because in this case, I would have to set properties in the code behind for the Checked and Unchecked event. Instead, I would like to call a Command (ICommand) in my ViewModel once the Checked or Unchecked event gets fired so that I don't need any code-behind for my toggle button.

Is there a way to bind a command directly for these two events in XAML? Similar to the command property of the "standard" button control in WPF?

Is there a way to bind a command directly for these two events in XAML? Similar to the command property of the "standard" button control in WPF?

EDITThis is how it works with regards to @har07 hint:

EDITThis is how it works with regards to @har07 hint:

1: Added references if you dont have it yet:

1: Added references if you dont have it yet:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"

2: Implemented Interaction.Triggers for Checked and Unchecked events:

2: Implemented Interaction.Triggers for Checked and Unchecked events:

<ToggleButton 
        Name="btnOpenPort" Style="{StaticResource myOnOffBtnStyle}" Content="Open Port"
        IsChecked="{Binding Path=PortViewModel.PortIsOpen, Mode=OneWay}"
        Canvas.Left="75" Canvas.Top="80" Height="25" Width="100">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Checked">
                <i:InvokeCommandAction Command="{Binding Path=PortViewModel.OpenPort}"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="Unchecked">
                <i:InvokeCommandAction Command="{Binding Path=PortViewModel.ClosePort}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
</ToggleButton>

With this solution, I don't have to change a single line of code in my ViewModel or my code behind. I can just call my ICommand as I would do it with a standard button following MVVM pattern.

With this solution, I don't have to change a single line of code in my ViewModel or my code behind. I can just call my ICommand as I would do it with a standard button following MVVM pattern.

采纳答案by har07

You can put the logic to handle checked/unchecked event in the setter of PortIsOpenproperty :

You can put the logic to handle checked/unchecked event in the setter of PortIsOpenproperty :

private bool _portIsOpen;
public bool PortIsOpen
{
    get { return _portIsOpen; }
    set
    {
        if(value) HandleCheckedEvent();
        else HandleUnCheckedEvent();
        ....
    }
}

Or you can use Ineraction.Triggersextension to bind event to commmand : WPF Binding UI events to commands in ViewModel

Or you can use Ineraction.Triggersextension to bind event to commmand : WPF Binding UI events to commands in ViewModel

回答by pushpraj

you may not be able to bind two commands for each checked and unchecked directly however you can still bind a command, which will be invoked for both. you also have option for attached behaviors if you need different command for both events.

you may not be able to bind two commands for each checked and unchecked directly however you can still bind a command, which will be invoked for both. you also have option for attached behaviors if you need different command for both events.

<ToggleButton Command="{Binding MyCommand}"/>

in the vm

in the vm

public ICommand MyCommand { get; private set; }

you will need to initialize it accordingly

you will need to initialize it accordingly

and to determine the current state you may have a condition on the bonded property PortIsOpen

and to determine the current state you may have a condition on the bonded property PortIsOpen

void Execute(object state)
{
    if(PortIsOpen)
    {
        //checked
    }
    else
    {
        //unchecked
    }
}

or perhaps you may pass it as a parameter too

or perhaps you may pass it as a parameter too

eg

eg

<ToggleButton Command="{Binding MyCommand}" 
              CommandParameter="{Binding IsChecked,RelativeSource={RelativeSource Self}}"/>

and use it as

and use it as

void Execute(object state)
{
    if((bool)state)
    {
        //checked
    }
    else
    {
        //unchecked
    }
}

回答by user3473830

Maybe we can use EventTriggers

Maybe we can use EventTriggers

    <ToggleButton>
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Checked">
                <i:InvokeCommandAction Command="{Binding Path=CheckedCommand}"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="Unchecked">
                <i:InvokeCommandAction Command="{Binding Path=UncheckedCommand}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </ToggleButton>

to use Triggers we have to reference System.Windows.Interactivity

to use Triggers we have to reference System.Windows.Interactivity

 xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

回答by Nitin Goel

 <ToggleButton Name="btnOpenPort" Style="{StaticResource myOnOffBtnStyle}" Content="Open Port"
              Checked="{Binding ICommand}"  Unchecked="{Binding ICommand}"
              IsChecked="{Binding Path=PortViewModel.PortIsOpen, Mode=OneWay}"
              Canvas.Left="75" Canvas.Top="80" Height="25" Width="100"/>

Replace ICommand with your ICommand property name.

Replace ICommand with your ICommand property name.