ComboBox 中的 WPF 命令支持

发布于 2024-08-20 11:34:02 字数 1201 浏览 3 评论 0原文

我想让我的视图模型上的命令在我的组合框的选择更改上执行。显然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
}

I want to have a command on my viewmodel execute on the selectionchanged of my ComboBox. Obviously Combobox does not support executing commands.

I have created a new class that inherits from Combox and implements this interface.

When I try to view the control (in the designer or in debug) the control doesn't show. I don't get any exceptions - is my control missing a visual template or something?

Thanks.

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
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最终幸福 2024-08-27 11:34:02

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

编辑,我实际上测试了它,似乎这条线:

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

Not sure why its not displayed correctly. Maybe you need to execute the base constructor?

Edit, I actually tested it and it seems this line:

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

breaks it for me.

Here is my implementation and it works in the 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);
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文