【问题标题】:WPF command support in ComboBoxComboBox 中的 WPF 命令支持
【发布时间】:2010-02-08 15:02:33
【问题描述】:

我想让我的视图模型上的命令在我的 ComboBox 的 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
}

【问题讨论】:

    标签: wpf combobox command


    【解决方案1】:

    不知道为什么它没有正确显示。也许您需要执行基本构造函数?

    编辑,我实际测试过,似乎是这一行:

    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);
                }
            }
        }
    }
    

    【讨论】:

    • 这太棒了!完全符合我的要求。不幸的是,现在我应用于 ComboBox 的所有样式都不适用于 ComboBoxWithCommand 对象。你知道一种简单的方法来让风格逐渐流行吗?还是我需要复制样式并定位 ComboBoxWithCommand 类型?
    • 没关系,我想通了。我在样式模板中添加了以下内容:
    猜你喜欢
    • 2011-02-24
    • 1970-01-01
    • 2014-05-02
    • 2021-05-27
    • 2013-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多