52 votes

Exécution d'une commande sur une case à cocher cochée ou non cochée.

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 ?

90voto

Arseny Points 4270
<CheckBox Content="CheckBox"
          Command="{Binding YourCommand}"
          CommandParameter="{Binding IsChecked, RelativeSource={RelativeSource Self}}" />

29voto

Igor S Points 586

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>

13voto

Rohit Vats Points 36234

Cela fonctionnera ce que vous exigez -

<CheckBox CommandParameter="{Binding}"
          Command="{Binding DataContext.AddRemovePresetAssignmentCommand,
          RelativeSource={RelativeSource FindAncestor,
                           AncestorType={x:Type UserControl}}}"
          Content="{Binding Path=Name}">

5voto

kub1x Points 36
  • 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.

0voto

Eric Ouellet Points 1370

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

    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X