2010-02-08 9 views
9

Chcę mieć polecenie w moim wykonaniu viewmodel w wyborze zmiany mojego ComboBox. Oczywiście Combobox nie obsługuje wykonywania poleceń.Obsługa komend WPF w ComboBox

Utworzyłem nową klasę dziedziczącą po Combox i implementującą ten interfejs.

Gdy próbuję wyświetlić kontrolkę (w projektancie lub debugowaniu) kontrolka nie jest wyświetlana. Nie dostaję żadnych wyjątków - czy moja kontrola nie ma szablonu wizualnego czy coś takiego?

Dzięki.

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 
} 

Odpowiedz

10

Nie wiem, dlaczego nie jest wyświetlany poprawnie. Może musisz wykonać podstawowy konstruktor?

Edycja I rzeczywiście przetestowane i wydaje się ten wiersz:

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

przerwy to dla mnie.

Oto moja realizacja i działa w projektancie:

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

To jest świetne! Dokładnie to chcę. Niestety obecnie wszystkie style zastosowane do ComboBox nie mają zastosowania do obiektów ComboBoxWithCommand. Czy wiesz, w jaki sposób można łatwo zmoczyć style? Czy muszę zduplikować styl i wybrać typ ComboBoxWithCommand? – KrisTrip

+1

Nieważne, rozgryzłem to. Dodałem do mojego szablonu stylu następujące elementy: KrisTrip

+0

Kod pracował również dla mnie, dzięki za wysyłkę! – dain