WPF: Implementing ICommandSource Without Interruption IsEnabled

I created a TextBox that implements ICommandSource, for the most part I have followed Microsoft's example using Slider . This TextBox will execute the associated command after pressing the Enter key. This part of the behavior is working correctly, the problem I am facing is that IsEnabled can no longer be installed in XAML? I'm not sure why this is so, you can still install IsEnabled on native Microsoft classes such as Button.

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?

Any feedback would be appreciated.

+4
source share
1 answer

, , :

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

All Articles