WPF:实现ICommandSource而不会中断IsEnabled

德里克·莫勒(Derrick Moeller)

我创建了一个实现ICommandSource的TextBox,在大多数情况下,我使用Slider遵循了Microsoft的示例按下“ Enter”键后,此文本框将执行绑定命令。行为的这一部分正常运行,我遇到的问题是不能再在XAML中设置IsEnabled?我不确定为什么会这样,您仍然可以在本机Microsoft类(如Button)上设置IsEnabled。

public class CommandTextBox : TextBox, ICommandSource
{
    // The DependencyProperty for the Command.
    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(CommandTextBox), new PropertyMetadata(OnCommandChanged));

    // The DependencyProperty for the CommandParameter.
    public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(CommandTextBox));

    // The DependencyProperty for the CommandTarget.
    public static readonly DependencyProperty CommandTargetProperty = DependencyProperty.Register("CommandTarget", typeof(IInputElement), typeof(CommandTextBox));

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    public object CommandParameter
    {
        get { return GetValue(CommandParameterProperty); }
        set { SetValue(CommandParameterProperty, value); }
    }

    public bool CommandResetsText { get; set; }

    public IInputElement CommandTarget
    {
        get { return (IInputElement)GetValue(CommandTargetProperty); }
        set { SetValue(CommandTargetProperty, value); }
    }

    // Command dependency property change callback. 
    private static void OnCommandChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
    {
        CommandTextBox ctb = (CommandTextBox)dp;
        ctb.HookUpCommand((ICommand)e.OldValue, (ICommand)e.NewValue);
    }

    // Add a new command to the Command Property. 
    private void HookUpCommand(ICommand oldCommand, ICommand newCommand)
    {
        // If oldCommand is not null, then we need to remove the handlers. 
        if (oldCommand != null)
            RemoveCommand(oldCommand);

        AddCommand(newCommand);
    }

    // Remove an old command from the Command Property. 
    private void RemoveCommand(ICommand command)
    {
        EventHandler handler = CanExecuteChanged;
        command.CanExecuteChanged -= handler;
    }

    // Add the command. 
    private void AddCommand(ICommand command)
    {
        var handler = new EventHandler(CanExecuteChanged);
        canExecuteChangedHandler = handler;
        if (command != null)
            command.CanExecuteChanged += canExecuteChangedHandler;
    }

    private void CanExecuteChanged(object sender, EventArgs e)
    {
        if (Command != null)
        {
            RoutedCommand command = Command as RoutedCommand;

            // If a RoutedCommand. 
            if (command != null)
            {
                if (command.CanExecute(CommandParameter, CommandTarget))
                    this.IsEnabled = true;
                else
                    this.IsEnabled = false;
            }
            // If a not RoutedCommand. 
            else
            {
                if (Command.CanExecute(CommandParameter))
                    this.IsEnabled = true;
                else
                    this.IsEnabled = false;
            }
        }
    }

    // If Command is defined, pressing the enter key will invoke the command; 
    // Otherwise, the textbox will behave normally. 
    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);

        if (e.Key == Key.Enter)
        {
            if (Command != null)
            {
                RoutedCommand command = Command as RoutedCommand;

                if (command != null)
                    command.Execute(CommandParameter, CommandTarget);
                else
                    Command.Execute(CommandParameter);

                if (CommandResetsText)
                    this.Text = String.Empty;
            }
        }
    }

    private EventHandler canExecuteChangedHandler;
}

XAML

<Button Command="{Binding GenericCommand}" IsEnabled="False" /> // This is disabled(desired).
<CommandTextBox Command="{Binding GenericCommand}" IsEnabled="False" /> // This is enabled?

对于任何反馈,我们都表示感谢。

埃尔达·多尔吉耶夫(Eldar Dordzhiev)

首先,您需要创建一个私有属性或将在命令可以执行的情况下设置的字段:

private bool _canExecute;

其次,您需要覆盖IsEnabledCore属性:

protected override bool IsEnabledCore
{
    get
    {
        return ( base.IsEnabledCore && _canExecute );
    }
}

最后,你刚刚杀青CanExecuteChanged通过替换法IsEnabled_canExecute和强迫IsEnabledCore毕竟:

private void CanExecuteChanged(object sender, EventArgs e)
{
    if (Command != null)
    {
        RoutedCommand command = Command as RoutedCommand;

        // If a RoutedCommand. 
        if (command != null)
        {
            _canExecute = command.CanExecute(CommandParameter, CommandTarget);
        }
        // If a not RoutedCommand. 
        else
        {
            _canExecute = Command.CanExecute(CommandParameter);
        }
    }

    CoerceValue(UIElement.IsEnabledProperty);
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Symfony:清除缓存而不会中断服务

来自分类Dev

以下哪项不会中断正在运行的进程?

来自分类Dev

Autopep8不会中断较长的注释行吗?

来自分类Dev

读取用户输入而不会中断bash

来自分类Dev

实现BeanNameAware会中断自动装配

来自分类Dev

在列中插入文本而不会中断间距

来自分类Dev

使用HttpPost批注?修复,使其不会中断页面

来自分类Dev

即使条件为true,Return语句也不会中断

来自分类Dev

Break语句不会中断循环

来自分类Dev

Break语句不会中断for循环

来自分类Dev

Python return语句不会中断循环

来自分类Dev

虽然循环不会中断?

来自分类Dev

Vue制定了计算属性,不会中断

来自分类Dev

为什么do while循环不会中断?

来自分类Dev

Symfony:清除缓存而不会中断服务

来自分类Dev

以下哪项不会中断正在运行的进程?

来自分类Dev

Java while循环不会中断

来自分类Dev

进入图形模式而不会中断汇编

来自分类Dev

打印多个作业而不会中断C#

来自分类Dev

使用HttpPost批注?修复,使其不会中断页面

来自分类Dev

即使条件为true,Return语句也不会中断

来自分类Dev

Powershell功能不会中断

来自分类Dev

Ruby-循环不会中断

来自分类Dev

在输入中插入图标而不会中断

来自分类Dev

ServerSocket同时不会中断图像数据输入流

来自分类Dev

循环不会中断。C程序

来自分类Dev

fgets()while循环不会中断

来自分类Dev

Java bufferedReader readline 循环不会中断

来自分类Dev

Python while 循环不会中断