J'ai un contrôle de case à cocher dans une fenêtre. J'aimerais exécuter une commande qui appellera une méthode dans le modèle de vue associé. J'ai également besoin de la valeur de la case à cocher. Je n'arrive pas à trouver un moyen d'associer une commande à une case à cocher. Quelqu'un l'a-t-il fait ?
Réponses
Trop de publicités?Si vous utilisez MVVM, vous pouvez utiliser des déclencheurs d'événements comme celui-ci :
<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>
- Ajouter
System.Windows.Interactivity
à vos références de projet. -
Ajouter
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
à vos espaces de noms 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>
Je mets en œuvre INotifyPropertyChanged
sur mon ViewModel comme suit :
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
El SomeBoolProperty
de mon ViewModel ressemble alors à ceci :
private bool _SomeBoolProperty = false;
public bool SomeBoolProperty {
get => _SomeBoolProperty;
set {
_SomeBoolProperty = value;
OnPropertyChanged(nameof(SomeBoolProperty));
}
}
J'utilise RelayCommand comme implémentation de ma commande à partir d'ici https://stackoverflow.com/a/22286816/336753 .
Les commandes sur mon ViewModel ressemblent alors à ceci :
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;
});
Je suis arrivé à cette question en essayant de trouver un moyen de réutiliser deux commandes que j'avais déjà sur mon ViewModel. L'une est appelée quand elle est cochée et l'autre quand elle n'est pas cochée. Je les utilise également sur certains boutons et je ne voulais pas ajouter une commande paramétrée supplémentaire. Des personnes ont posé ici des questions sur l'implémentation de ViewModel, j'ai donc ajouté cette réponse pour compléter celle de Igor_S . J'espère que cela vous aidera.
Je suis en retard... J'ai utilisé la réponse de Rohit Vats et j'ai trouvé ce code.
L'exemple est un extrait de code fonctionnel et il n'est là que pour aider à comprendre tous les aspects. Il s'agit d'une punaise qui peut être active ou inactive et qui utilise un DelegateCommand. Vous pourriez probablement aussi utiliser une RelayCommand ou toute autre classe similaire pour faire le même travail.
Commandement :
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 :
<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>
Modèle :
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
}
}
- Réponses précédentes
- Plus de réponses