wpf 在 Checkbox.Checked 或 Unchecked 上执行命令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5566050/
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
Executing a command on Checkbox.Checked or Unchecked
提问by Hosea146
I have a checkbox control on a window. I'd like to execute a command that will call a method in the associated view model. I'll also need the value of the checkbox as well. I cannot seem to find a way to associate a command with a checkbox. Has anyone done this?
我在窗口上有一个复选框控件。我想执行一个命令,该命令将调用关联视图模型中的一个方法。我还需要复选框的值。我似乎找不到将命令与复选框关联的方法。有没有人做过这个?
回答by Arseny
<CheckBox Content="CheckBox"
Command="{Binding YourCommand}"
CommandParameter="{Binding IsChecked, RelativeSource={RelativeSource Self}}" />
回答by Igor S
If you use MVVM, you can use event triggers like this:
如果您使用 MVVM,您可以使用这样的事件触发器:
<CheckBox IsChecked="{Binding ServiceOrderItemTask.IsCompleted, Mode=TwoWay}" Content="{Binding ServiceOption.Name}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding DataContext.IsCompletedCheckedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type t:RadGridView}}}" CommandParameter="{Binding}"/>
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding DataContext.IsCompletedUncheckedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type t:RadGridView}}}" CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
回答by Rohit Vats
This will work what you requires -
这将按照您的要求工作-
<CheckBox CommandParameter="{Binding}"
Command="{Binding DataContext.AddRemovePresetAssignmentCommand,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type UserControl}}}"
Content="{Binding Path=Name}">
回答by kub1x
- Add
System.Windows.Interactivity
to your project references. - Add
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
to your XAML namespaces.
- 添加
System.Windows.Interactivity
到您的项目参考。 - 添加
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
到 XAML 命名空间。
<CheckBox IsChecked="{Binding SomeBoolProperty, Mode=OneWay}" Content="Check Meee!">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding MyOnCheckedCommand}"/>
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding MyOnUncheckedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
I implement INotifyPropertyChanged
on my ViewModel as follows:
我INotifyPropertyChanged
在我的 ViewModel 上实现如下:
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
The SomeBoolProperty
of my ViewModel then looks like this:
在SomeBoolProperty
我的视图模型的则是这样的:
private bool _SomeBoolProperty = false;
public bool SomeBoolProperty {
get => _SomeBoolProperty;
set {
_SomeBoolProperty = value;
OnPropertyChanged(nameof(SomeBoolProperty));
}
}
I use RelayCommand as my command implementation from here https://stackoverflow.com/a/22286816/336753.
我从这里使用 RelayCommand 作为我的命令实现 https://stackoverflow.com/a/22286816/336753。
The commands on my ViewModel then look like this:
我的 ViewModel 上的命令如下所示:
public ICommand MyOnCheckedCommand { get; } = new RelayCommand(o => {
// Do something here.
SomeBoolProperty = true;
});
public ICommand MyOnUncheckedCommand { get; } = new RelayCommand(o => {
// Do something else here.
SomeBoolProperty = false;
});
I got to this question trying to find a way to reusetwo commands I already had on my ViewModel. One called when checked and one when unchecked. I use them on some buttons too so did not want to add an extra parametrized command. People were asking here about ViewModel implementation so adding this answer to complete the one from Igor_S. Hope it helps.
我遇到了这个问题,试图找到一种方法来重用我在 ViewModel 上已有的两个命令。一种在选中时调用,一种在未选中时调用。我也在一些按钮上使用它们,所以不想添加额外的参数化命令。人们在这里询问 ViewModel 实现,因此添加此答案以完成来自Igor_S 的答案。希望能帮助到你。
回答by Eric Ouellet
I'm late... I used Rohit Vats answer and came up with this code.
我迟到了......我使用了 Rohit Vats 答案并想出了这个代码。
The example is a working code extract and it is only here to help to understand every aspects. It is a pushpin that could be either active or inactive and it use a DelegateCommand. You could probably also use a RelayCommand or any other similar class to do the same job.
该示例是一个工作代码摘录,仅用于帮助理解各个方面。它是一个可以处于活动状态或非活动状态的图钉,它使用一个 DelegateCommand。您也可以使用 RelayCommand 或任何其他类似的类来完成相同的工作。
Command:
命令:
using System.Windows.Input;
namespace HQ.Wpf.Util.Command
{
public class StandardCommand
{
public static RoutedUICommand PinPropertyGrid = new RoutedUICommand("Pin property grid", "PinPropertyGrid", typeof(StandardCommand));
Xaml:
Xml:
<CheckBox HorizontalAlignment="Right"
VerticalAlignment="Top"
Margin="2,0,3,0"
Command="{Binding CommandPinPropertyGrid}"
CommandParameter="{Binding IsChecked, RelativeSource={RelativeSource Self}}">
<CheckBox.Template>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Image x:Name="ImagePushpin" Width="16" Height="16" Source="pack://application:,,,/WpfUtil;component/Images/PushpinUnpinned16x16.png" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="ImagePushpin" Property="Source" Value="pack://application:,,,/WpfUtil;component/Images/PushpinPinned16x16.png" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</CheckBox.Template>
</CheckBox>
Model:
模型:
public MainWindowViewModel()
{
CommandPinPropertyGrid = new DelegateCommand<bool>(PinPropertyGrid);
...
...
// ******************************************************************
public DelegateCommand<bool> CommandPinPropertyGrid { get; private set; }
public void PinPropertyGrid(bool pinned)
{
this.IsPropertyGridPinned = pinned;
}
DelegateCommand:
委托命令:
using System;
using System.Windows.Input;
namespace HQ.Wpf.Util.Command
{
/// <summary>
/// Represents a command that forwards the <c>Execute</c> and <c>CanExecute</c> calls to specified delegates.
/// </summary>
public class DelegateCommand<T> : ICommand
{
private readonly Action<T> _executeCallback;
private readonly Predicate<T> _canExecuteCallback;
/////////////////////////////////////////////////////////////////////////////////////////////////////
// OBJECT
/////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// Initializes a new instance of the <see cref="DelegateCommand<T>"/> class.
/// </summary>
/// <param name="executeCallback">The execute callback delegate.</param>
public DelegateCommand(Action<T> executeCallback)
: this(executeCallback, null)
{
// No-op
}
/// <summary>
/// Initializes a new instance of the <see cref="DelegateCommand<T>"/> class.
/// </summary>
/// <param name="executeCallback">The execute callback delegate.</param>
/// <param name="canExecuteCallback">The can execute callback delegate.</param>
public DelegateCommand(Action<T> executeCallback, Predicate<T> canExecuteCallback)
{
if (executeCallback == null)
throw new ArgumentNullException("executeCallback");
this._executeCallback = executeCallback;
this._canExecuteCallback = canExecuteCallback;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
// INTERFACE IMPLEMENTATION
/////////////////////////////////////////////////////////////////////////////////////////////////////
#region ICommand Members
/// <summary>
/// Defines the method that determines whether the command can execute in its current state.
/// </summary>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to <see langword="null"/>.</param>
/// <returns>
/// <c>true</c> if this command can be executed; otherwise, <c>false</c>.
/// </returns>
public bool CanExecute(object parameter)
{
return (this._canExecuteCallback == null) ? true : this._canExecuteCallback((T)parameter);
}
/// <summary>
/// Occurs when changes occur that affect whether or not the command should execute.
/// </summary>
public event EventHandler CanExecuteChanged
{
add
{
if (this._canExecuteCallback != null)
CommandManager.RequerySuggested += value;
}
remove
{
if (this._canExecuteCallback != null)
CommandManager.RequerySuggested -= value;
}
}
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to <see langword="null"/>.</param>
public void Execute(object parameter)
{
this._executeCallback((T)parameter);
}
#endregion // ICommand Members
}
}
回答by Dennis Heldt
When you need only the Status of the CheckBox (Checked or Unchecked), then you don't need a Parameter. You can detect the Status of the Checkbox when you use this code:
当您只需要 CheckBox 的状态(已选中或未选中)时,则不需要参数。使用此代码时,您可以检测复选框的状态:
CheckBox box = e.OriginalSource as CheckBox;
if(box.IsChecked.Value)
DoThis();
else
DoAnotherMethod();
"e" is the ExecutedRoutedEventArgs-Parameter in the Command. You Need box.IsChecked.Value, because box.IsChecked is from Type bool?.
“e”是命令中的 ExecutedRoutedEventArgs-Parameter。您需要 box.IsChecked.Value,因为 box.IsChecked 来自类型 bool?。