2013-05-07 2 views
2

J'ai créé un nouveau UserContol avec un bouton à l'intérieur. Je voulais lier la commande de bouton à une propriété de dépendance du nouveau contrôle utilisateur comme ceci.La liaison de commande de bouton ne fonctionne pas

<Grid> 
<Button Name="Button1" Command="{Binding Button1Command}" /> 
</Grid> 

c'est le DP sur le UserControl contenant:

public ICommand Button1Command 
{ 
    get { return (ICommand)GetValue(Button1CommandProperty); } 
    set { SetValue(Button1CommandProperty, value); } 
} 

public static readonly DependencyProperty Button1CommandProperty = 
    DependencyProperty.Register("Button1Command", typeof(ICommand), typeof(BptCellTemplate), new FrameworkPropertyMetadata(null)); 

lorsque je tente d'utiliser rien ne se passe quand je presse le bouton. Il ne reconnaît pas la commande. Si j'ajoute un événement cela fonctionne. Comme ceci:

public static readonly DependencyProperty Button1CommandProperty = 
    DependencyProperty.Register("Button1Command", typeof(ICommand), typeof(BptCellTemplate), new FrameworkPropertyMetadata(null, OnButton1CommandChanged)); 

private static void OnButton1CommandChanged(DependencyObject dependencyObject, 
               DependencyPropertyChangedEventArgs args) 
{ 
    var bptCellTemplate = dependencyObject as BptCellTemplate; 
    if (bptCellTemplate == null || !(args.NewValue is ICommand)) 
    { 
    return; 
    } 
    (bptCellTemplate.DataContext as BptCellTemplateViewModel).Button1Command = (ICommand)args.NewValue; 

} 

Y at-il un moyen de lier sans événement? car il fonctionne avec d'autres propriétés du bouton que je ne la même manière (Visibility par exemple)

+1

Où avez-vous défini la valeur de Button1Command? – jure

Répondre

1
  1. Vous avez besoin classe implémente l'interface ICommand.

    public class RelayCommand : ICommand 
    { 
        #region Fields 
    
        readonly Action<object> _execute; 
        readonly Predicate<object> _canExecute; 
    
        #endregion // Fields 
    
        #region Constructors 
    
        /// <summary> 
        /// Creates a new command that can always execute. 
        /// </summary> 
        /// <param name="execute">The execution logic.</param> 
        public RelayCommand(Action<object> execute) 
         : this(execute, null) 
        { 
        } 
    
        /// <summary> 
        /// Creates a new command. 
        /// </summary> 
        /// <param name="execute">The execution logic.</param> 
        /// <param name="canExecute">The execution status logic.</param> 
        public RelayCommand(Action<object> execute, Predicate<object> canExecute) 
        { 
         if (execute == null) 
          throw new ArgumentNullException("execute"); 
    
         _execute = execute; 
         _canExecute = canExecute; 
        } 
    
        #endregion // Constructors 
    
        #region ICommand Members 
    
        [DebuggerStepThrough] 
        public bool CanExecute(object parameter) 
        { 
         return _canExecute == null ? true : _canExecute(parameter); 
        } 
    
        public event EventHandler CanExecuteChanged 
        { 
         add { CommandManager.RequerySuggested += value; } 
         remove { CommandManager.RequerySuggested -= value; } 
        } 
    
        public void Execute(object parameter) 
        { 
         _execute(parameter); 
        } 
    
        #endregion // ICommand Members 
    } 
    
  2. Maintenant, il y a une liaison très simple. Définir la commande dans votre DataContext (MVVM ... ect.) Ne pas se souvenir de la configuration de DataContext ... par exemple DataContext = this; (Ceci est votre fenêtre)

    RelayCommand _btnCommand; 
    public ICommand Button1Command 
    { 
        get 
        { 
         if (_btnCommand == null) 
         { 
          _btnCommand = new RelayCommand(param => this.ExecuteButton1(), 
           param => this.CanButton1()); 
         } 
         return _btnCommand; 
        } 
    } 
    
    public void ExecuteButton1() 
    { 
    } 
    
    public bool CanButton1() 
    { 
        return true; 
    } 
    

Ca y est ...

+0

Darkzaleus: Merci pour l'édition :) – misak

+2

Il est intéressant de noter que vous pouvez simplement utiliser 'RoutedCommand' dans la plupart des cas: vous n'avez pas besoin de créer votre propre classe' ICommand'. –

2

Il est possible que votre fixation ne fonctionne pas parce qu'il n'y a rien qui dit que la propriété est Button1Command un membre de votre UserControl.

Vous pouvez vérifier que c'est le problème en consultant la fenêtre de sortie lors du débogage de votre programme dans Visual Studio. Vous verrez probablement des erreurs de liaison que le membre Button1Command n'a pas été trouvé. Le correctif typique consiste à ajouter un attribut de nom à l'élément racine de votre UserControl, tel que x:Name="root" (vous pouvez choisir votre propre nom ou en utiliser un existant si vous l'avez). Ensuite, modifiez votre liaison à la commande pour référencer le nouveau nom:

<Button Name="Button1" Command="{Binding Button1Command, ElementName=root}" /> 
Questions connexes