Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF: Combobox with forced uppercase?

I'm not sure why, but none of the solutions are working properly for me from a similar question.

I realize that a TextBox has a property (CharacterCasing) which can be set to Upper to change any lowercase typing into uppercase. It works so great because the user is never interrupted while typing, caps lock and shift don't affect it negatively, and other non-alpha characters aren't affected negatively either.

The problem is that there is no option to use this property for a ComboBox. The solutions from that similar posting don't seem to work for me. I'm looking to duplicate the CharacterCasing property but for a ComboBox. I don't mind it being an attached property, in fact, that'd be great. I tried a couple of different events directly on the xaml object, with no success.

like image 594
myermian Avatar asked Dec 07 '22 01:12

myermian


1 Answers

The ComboBox template uses a TextBox when IsEditable is true. So you can either replace the template to set CharacterCasing on the TextBox, or create an attached property that will find the TextBox by its name ("PART_EditableTextBox") and set the CharacterCasing property on it.

Here's a simple implementation of the attached property solution:

public static class ComboBoxBehavior
{

    [AttachedPropertyBrowsableForType(typeof(ComboBox))]
    public static CharacterCasing GetCharacterCasing(ComboBox comboBox)
    {
        return (CharacterCasing)comboBox.GetValue(CharacterCasingProperty);
    }

    public static void SetCharacterCasing(ComboBox comboBox, CharacterCasing value)
    {
        comboBox.SetValue(CharacterCasingProperty, value);
    }

    // Using a DependencyProperty as the backing store for CharacterCasing.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CharacterCasingProperty =
        DependencyProperty.RegisterAttached(
            "CharacterCasing",
            typeof(CharacterCasing),
            typeof(ComboBoxBehavior),
            new UIPropertyMetadata(
                CharacterCasing.Normal,
                OnCharacterCasingChanged));

    private static void OnCharacterCasingChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        var comboBox = o as ComboBox;
        if (comboBox == null)
            return;

        if (comboBox.IsLoaded)
        {
            ApplyCharacterCasing(comboBox);
        }
        else
        {
            // To avoid multiple event subscription
            comboBox.Loaded -= new RoutedEventHandler(comboBox_Loaded);
            comboBox.Loaded += new RoutedEventHandler(comboBox_Loaded);
        }
    }

    private static void comboBox_Loaded(object sender, RoutedEventArgs e)
    {
        var comboBox = sender as ComboBox;
        if (comboBox == null)
            return;

        ApplyCharacterCasing(comboBox);
        comboBox.Loaded -= comboBox_Loaded;
    }

    private static void ApplyCharacterCasing(ComboBox comboBox)
    {
        var textBox = comboBox.Template.FindName("PART_EditableTextBox", comboBox) as TextBox;
        if (textBox != null)
        {
            textBox.CharacterCasing = GetCharacterCasing(comboBox);
        }
    }

}

And here's how to use it:

    <ComboBox ItemsSource="{Binding Items}"
              IsEditable="True"
              local:ComboBoxBehavior.CharacterCasing="Upper">
        ...
like image 180
Thomas Levesque Avatar answered Dec 11 '22 08:12

Thomas Levesque