0

I have created an instance of a TextBox that implements ICommandSource, I would like to control the IsEnabled property via the DataContext. This portion of my code works, on top of this I would like to control the Text property via this same method or by extension the IsEnabled property.

Basically when the TextBox transitions from IsEnabled="False" to IsEnabled="True" I would like to reset the Text field to an empty string or preferably null.

I have attempted to do this in a handful of ways without success.

Attempt 1

<ctrl:CommandTextBox x:Name="txtSerialNumber"
                     Command="{Binding VMFactory.CreateViewModelCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
                     CommandParameter="{Binding Text, RelativeSource={RelativeSource Self}}" DecoderPrefix="S">
    <ctrl:CommandTextBox.Style>
        <Style TargetType="{x:Type ctrl:CommandTextBox}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding}" Value="{x:Null}">
                    <Setter Property="IsEnabled" Value="True" />
                    <Setter Property="Text" Value="{x:Null}" />
                </DataTrigger>
            </Style.Triggers>
            <Setter Property="IsEnabled" Value="False" />
            <Setter Property="Text" Value="{Binding SerialNumber, Mode=OneWay}" />
        </Style>
    </ctrl:CommandTextBox.Style>
</ctrl:CommandTextBox>

This does work but only when the CommandParameter does not need to be "Decoded". It seems as though when my text property is changed via the override it breaks the trigger until the application is restarted.

CommandTextBox.cs

public class CommandTextBox : DecoderTextBox, ICommandSource
{
    // Additional Fields, Properties, and Methods removed for the sake of brevity.

    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);

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

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

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

            e.Handled = true;
        }
    }
}

DecoderTextBox.cs

public class DecoderTextBox : TextBox
{
    public static DependencyProperty DecoderPrefixProperty = DependencyProperty.Register("DecoderPrefix", typeof(string), typeof(DecoderTextBox), new PropertyMetadata(String.Empty));

    public string DecoderPrefix
    {
        get { return (string)GetValue(DecoderPrefixProperty); }
        set { SetValue(DecoderPrefixProperty, value); }
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            string text = this.Text;

            // If the if statement returns true the trigger will break.
            if (text.Substring(0, Math.Min(DecoderPrefix.Length, text.Length)) == DecoderPrefix)
                this.Text = text.Remove(0, DecoderPrefix.Length);
        }

        base.OnKeyDown(e);
    }
}

Is there something specific to my implementation of OnKeyDown that is breaking this trigger?

Derrick Moeller
  • 4,808
  • 2
  • 22
  • 48
  • A question, is your `CommandTextBox` inside of a template by any chance? – XAMlMAX Jan 27 '15 at 17:53
  • @XAMlMAX No it is not, it is sitting inside of a grid that is part of a UserControl. – Derrick Moeller Jan 27 '15 at 18:03
  • ok, as long as any parts of the visual tree that this belong to is not a template then the style should be applied. What do you get in your Output Window? Can it not find the property? – XAMlMAX Jan 27 '15 at 18:08
  • @XAMlMAX I do not see anything in the Output Window that is unusual, I've done some additional troubleshooting and if I execute the same command via a button the Text does get updated as expected. Using the Command via the TextBox appears to break the style? I'm not sure where to go from here? – Derrick Moeller Jan 27 '15 at 18:57
  • It looks like your code might be causing the invalid results, have a look at the [behaviours](http://stackoverflow.com/a/21942689/2029607) instead, HTH – XAMlMAX Jan 27 '15 at 19:55
  • @XAMlMAX This TextBox is used in mulititude of projects and is the preferred method for executing a command by the group I work with. I would very much like to fix this behavior then to abandon the TextBox. I have learned some more details, it appears to be specific to the OnKeyDown override in DecoderTextBox. I would appreciate your feedback. – Derrick Moeller Jan 29 '15 at 12:58
  • this is just a guess but shouldn't you set the `e.Handled = true;` after you're done with handling the `KeyDown`? – XAMlMAX Jan 29 '15 at 14:51

1 Answers1

0

There is an issue related to setting the value of a DependencyProperty locally. It appears as though you have to use SetCurrentValue to maintain the binding.

DecoderTextBox.cs

protected override void OnPreviewKeyDown(KeyEventArgs e)
{
    if (e.Key == Key.Enter)
    {
        if (Text.StartsWith(DecoderPrefix))
            SetCurrentValue(TextProperty, Text.Remove(0, DecoderPrefix.Length));
    }

    base.OnPreviewKeyDown(e);
}
Derrick Moeller
  • 4,808
  • 2
  • 22
  • 48