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
Binding commands to ToggleButton Checked and Unchecked events
提问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 PortIsOpen
property :
You can put the logic to handle checked/unchecked event in the setter of PortIsOpen
property :
private bool _portIsOpen;
public bool PortIsOpen
{
get { return _portIsOpen; }
set
{
if(value) HandleCheckedEvent();
else HandleUnCheckedEvent();
....
}
}
Or you can use Ineraction.Triggers
extension to bind event to commmand :
WPF Binding UI events to commands in ViewModel
Or you can use Ineraction.Triggers
extension 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.