Я хочу иметь команду на своем viewmodel, выполняются на selectionchanged моего ComboBox. Очевидно Поле комбинированного списка не поддерживает выполняющиеся команды.
Я создал новый класс, который наследовался Combox и реализует этот интерфейс.
Когда я пытаюсь просмотреть управление (в разработчике или в отладке), управление не показывает. Я не получаю исключений - мое управление пропускает визуальный шаблон или что-то?
Спасибо.
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
}
Не уверен, почему он отображается неправильно. Может нужно выполнить базовый конструктор?
Редактировать, я действительно тестировал его, и мне кажется, что эта строка:
DefaultStyleKeyProperty.OverrideMetadata(typeof(ComboBoxWithCommand), new FrameworkPropertyMetadata(typeof(ComboBoxWithCommand)));
ломает меня.
Вот моя реализация, и она работает в дизайнере:
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);
}
}
}
}