WPF: Combobox с принудительной заглавной буквы? - PullRequest
4 голосов
/ 15 октября 2010

Я не уверен, почему, но ни одно из решений не работает для меня должным образом из подобного вопроса .

Я понимаю, что TextBox имеет свойство (CharacterCasing), которое можно установить на Upper, чтобы изменить ввод любой строчной буквы в верхнюю. Он работает так здорово, потому что пользователь никогда не прерывается во время набора текста, заглавные буквы и сдвиги не влияют на него отрицательно, а другие символы, не являющиеся альфа-символами, также не влияют отрицательно.

Проблема в том, что нет возможности использовать это свойство для ComboBox. Решения из той же публикации, похоже, не работают для меня. Я ищу дубликат свойства CharacterCasing, но для ComboBox. Я не возражаю против того, чтобы это была собственность, это было бы здорово. Я попробовал несколько различных событий непосредственно на объекте xaml, но безуспешно.

1 Ответ

13 голосов
/ 15 октября 2010

В шаблоне ComboBox используется TextBox, когда IsEditable имеет значение true.Таким образом, вы можете либо заменить шаблон на CharacterCasing для TextBox, либо создать присоединенное свойство, которое найдет TextBox по его имени ("PART_EditableTextBox"), и установить для него свойство CharacterCasing.*

Вот простая реализация решения с присоединенным свойством:

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

}

А вот как его использовать:

    <ComboBox ItemsSource="{Binding Items}"
              IsEditable="True"
              local:ComboBoxBehavior.CharacterCasing="Upper">
        ...
...