web-dev-qa-db-fra.com

Comment lier le bouton WPF à une commande dans ViewModelBase?

J'ai une vue AttributeView qui contient toutes sortes d'attributs. Il y a aussi un bouton qui, lorsqu'il est pressé, devrait définir les valeurs par défaut pour les attributs. J'ai aussi une classe ViewModelBase qui est une classe de base pour tous les ViewModels que j'ai. Le problème est que je n'arrive pas à obtenir le bouton lié à la commande avec WPF.

J'ai essayé ça, mais ça ne fait rien:

<Button Command="{Binding DataInitialization}" Content="{x:Static localProperties:Resources.BtnReinitializeData}"></Button>

La commande est définie (dans le ViewModelBase) comme ceci:

public CommandBase DataInitialization { get; protected set; }

et au démarrage de l'application, une nouvelle instance est créée pour la commande:

DataInitialization = new DataInitializationCommand()

Cependant, la liaison WPF ne semble pas "trouver" la commande (appuyer sur le bouton ne fait rien). Le ViewModel utilisé dans la vue actuelle est dérivé de ViewModelBase. Qu'est-ce que je peux essayer d'autre (je suis assez nouveau pour WPF, donc la question peut être très simple)?

44
kor_
 <Grid >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Button Command="{Binding ClickCommand}" Width="100" Height="100" Content="wefwfwef"/>
</Grid>

le code derrière la fenêtre:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModelBase();
    }
}

Le ViewModel:

public class ViewModelBase
{
    private ICommand _clickCommand;
    public ICommand ClickCommand
    {
        get
        {
            return _clickCommand ?? (_clickCommand = new CommandHandler(() => MyAction(), ()=> CanExecute));
        }
    }
     public bool CanExecute
     {
        get
        {
            // check if executing is allowed, i.e., validate, check if a process is running, etc. 
            return true/false;
        }
     }

    public void MyAction()
    {

    }
}

Gestionnaire de commandes:

 public class CommandHandler : ICommand
{
    private Action _action;
    private Func<bool> _canExecute;

    /// <summary>
    /// Creates instance of the command handler
    /// </summary>
    /// <param name="action">Action to be executed by the command</param>
    /// <param name="canExecute">A bolean property to containing current permissions to execute the command</param>
    public CommandHandler(Action action, Func<bool> canExecute)
    {
        _action = action;
        _canExecute = canExecute;
    }

    /// <summary>
    /// Wires CanExecuteChanged event 
    /// </summary>
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    /// <summary>
    /// Forcess checking if execute is allowed
    /// </summary>
    /// <param name="parameter"></param>
    /// <returns></returns>
    public bool CanExecute(object parameter)
    {
        return _canExecute.Invoke();
    }

    public void Execute(object parameter)
    {
        _action();
    }
}

J'espère que cela vous donnera l'idée.

109
yo chauhan

La solution proposée par ethicallogics fonctionne à merveille. Juste une remarque - au lieu d'implémenter votre propre CommandHandler, envisagez d'utiliser Microsoft.Practices.Prism.Commands.DelegateCommand (qui est pratiquement identique, sauf pour un ctor supplémentaire si votre bouton est toujours activé).

0
erezmk