2010-02-08 1 views
9

Desidero avere un comando sul mio viewmodel eseguito sulla selezione modificata del mio ComboBox. Ovviamente Combobox non supporta i comandi in esecuzione.Supporto comandi WPF in ComboBox

Ho creato una nuova classe che eredita da Combox e implementa questa interfaccia.

Quando si tenta di visualizzare il controllo (nella finestra di progettazione o nel debug) il controllo non viene visualizzato. Non ho eccezioni: il mio controllo manca un modello visivo o qualcosa del genere?

Grazie.

public class CommandSourceComboBox : ComboBox, ICommandSource 
{ 
    static CommandSourceComboBox() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(CommandSourceComboBox), new FrameworkPropertyMetadata(typeof(CommandSourceComboBox))); 
    } 

    #region ICommandSource Members 

    public ICommand Command 
    { 
     get; 
     set; 
    } 

    public object CommandParameter 
    { 
     get; 
     set; 
    } 

    public IInputElement CommandTarget 
    { 
     get; 
     set; 
    } 

    protected override void OnSelectionChanged(SelectionChangedEventArgs e) 
    { 
     base.OnSelectionChanged(e); 

     if (this.Command != null) 
     { 
      RoutedCommand command = Command as RoutedCommand; 

      if (command != null) 
      { 
       command.Execute(CommandParameter, CommandTarget); 
      } 
      else 
      { 
       ((ICommand)Command).Execute(CommandParameter); 
      } 
     } 
    } 

    #endregion 
} 

risposta

10

Non so perché non è visualizzato correttamente. Forse hai bisogno di eseguire il costruttore di base?

Edit, in realtà ho testato e sembra che questa linea:

DefaultStyleKeyProperty.OverrideMetadata(typeof(ComboBoxWithCommand), new FrameworkPropertyMetadata(typeof(ComboBoxWithCommand))); 

pause per me.

Qui è la mia implementazione e funziona nella finestra di progettazione:

public class ComboBoxWithCommand : ComboBox, ICommandSource 
{ 
    private static EventHandler canExecuteChangedHandler; 

    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", 
                          typeof(ICommand), 
                          typeof(ComboBoxWithCommand), 
                          new PropertyMetadata((ICommand)null, 
                          new PropertyChangedCallback(CommandChanged))); 

    public ICommand Command 
    { 
     get 
     { 
      return (ICommand)GetValue(CommandProperty); 
     } 
     set 
     { 
      SetValue(CommandProperty, value); 
     } 

    } 

    public static readonly DependencyProperty CommandTargetProperty = DependencyProperty.Register("CommandTarget", 
                            typeof(IInputElement), 
                            typeof(ComboBoxWithCommand), 
                            new PropertyMetadata((IInputElement)null)); 

    public IInputElement CommandTarget 
    { 
     get 
     { 
      return (IInputElement)GetValue(CommandTargetProperty); 
     } 
     set 
     { 
      SetValue(CommandTargetProperty, value); 
     } 
    } 

    public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", 
                            typeof(object), 
                            typeof(ComboBoxWithCommand), 
                            new PropertyMetadata((object)null)); 

    public object CommandParameter 
    { 
     get 
     { 
      return (object)GetValue(CommandParameterProperty); 
     } 
     set 
     { 
      SetValue(CommandParameterProperty, value); 
     } 
    } 

    public ComboBoxWithCommand() : base() { } 


    private static void CommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     ComboBoxWithCommand cb = (ComboBoxWithCommand)d; 
     cb.HookUpCommand((ICommand)e.OldValue, (ICommand)e.NewValue); 
    } 

    private void HookUpCommand(ICommand oldCommand, ICommand newCommand) 
    { 
     if (oldCommand != null) 
     { 
      RemoveCommand(oldCommand, newCommand); 
     } 
     AddCommand(oldCommand, newCommand); 
    } 

    private void RemoveCommand(ICommand oldCommand, ICommand newCommand) 
    { 
     EventHandler handler = CanExecuteChanged; 
     oldCommand.CanExecuteChanged -= handler; 
    } 

    private void AddCommand(ICommand oldCommand, ICommand newCommand) 
    { 
     EventHandler handler = new EventHandler(CanExecuteChanged); 
     canExecuteChangedHandler = handler; 
     if (newCommand != null) 
     { 
      newCommand.CanExecuteChanged += canExecuteChangedHandler; 
     } 
    } 
    private void CanExecuteChanged(object sender, EventArgs e) 
    { 

     if (this.Command != null) 
     { 
      RoutedCommand command = this.Command as RoutedCommand; 

      // If a RoutedCommand. 
      if (command != null) 
      { 
       if (command.CanExecute(this.CommandParameter, this.CommandTarget)) 
       { 
        this.IsEnabled = true; 
       } 
       else 
       { 
        this.IsEnabled = false; 
       } 
      } 
      // If a not RoutedCommand. 
      else 
      { 
       if (Command.CanExecute(CommandParameter)) 
       { 
        this.IsEnabled = true; 
       } 
       else 
       { 
        this.IsEnabled = false; 
       } 
      } 
     } 
    } 

    protected override void OnSelectionChanged(SelectionChangedEventArgs e) 
    { 
     base.OnSelectionChanged(e); 

     if (this.Command != null) 
     { 
      RoutedCommand command = this.Command as RoutedCommand; 

      if (command != null) 
      { 
       command.Execute(this.CommandParameter, this.CommandTarget); 
      } 
      else 
      { 
       ((ICommand)Command).Execute(CommandParameter); 
      } 
     } 
    } 
} 
+0

Questo è grande! Esattamente quello che voglio. Purtroppo ora tutti gli stili applicati a ComboBox non si applicano agli oggetti ComboBoxWithCommand. Conosci un modo semplice per far cadere gli stili? O devo duplicare lo stile e scegliere il tipo ComboBoxWithCommand? – KrisTrip

+1

Non importa, l'ho capito. Ho aggiunto quanto segue al mio modello di stile: KrisTrip

+0

Il codice ha funzionato anche per me, grazie per aver pubblicato! – dain