WPF实现支持Command绑定的ComboBox控件

由于ComboBox,ListBox等控件没有实现ICommandSource接口,所以不支持在XAML中进行Command绑定,下面的一段代码就是,对ComboBox实现对ICommandSource接口的实现:

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

            }

        }

    }

}

如此,便可以在XAML中对Command进行绑定,处理ComboBox的SelectedChanged事件!

你可能感兴趣的:(combobox)