2010-02-08 4 views
9

Ich möchte einen Befehl auf meinem Viewmodel ausführen auf der Auswahl geändert von meiner ComboBox. Offensichtlich unterstützt Combobox das Ausführen von Befehlen nicht.WPF-Befehl unterstützt in ComboBox

Ich habe eine neue Klasse erstellt, die von Combox erbt und diese Schnittstelle implementiert.

Wenn ich versuche, das Steuerelement anzuzeigen (im Designer oder im Debug) wird das Steuerelement nicht angezeigt. Ich bekomme keine Ausnahmen - ist meine Kontrolle fehlt eine visuelle Vorlage oder etwas?

Danke.

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 
} 

Antwort

10

Nicht sicher, warum es nicht richtig angezeigt wird. Vielleicht müssen Sie den Basiskonstruktor ausführen?

bearbeiten, ich habe es tatsächlich getestet und es scheint, diese Zeile:

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

bricht es für mich. meine Implementierung

Hier ist und es funktioniert im Designer:

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

Das ist großartig! Ist genau was ich will. Leider gelten jetzt alle Styles, die ich auf ComboBox angewendet habe, nicht für die ComboBoxWithCommand-Objekte. Kennen Sie einen einfachen Weg, um die Stile zu tröpfeln? Oder muss ich den Stil duplizieren und den ComboBoxWithCommand-Typ als Ziel festlegen? – KrisTrip

+1

Vergiss es, ich habe es herausgefunden. Ich habe meiner Stilvorlage Folgendes hinzugefügt: KrisTrip

+0

Code funktionierte auch für mich, danke für die Veröffentlichung! – dain