【问题标题】:WPF: Combobox with forced uppercase?WPF:强制大写的组合框?
【发布时间】:2010-10-15 18:57:37
【问题描述】:

我不知道为什么,但是similar question 的解决方案都没有为我正常工作。

我意识到 TextBox 有一个属性 (CharacterCasing),可以将其设置为 Upper 以将任何小写字母更改为大写字母。它之所以如此出色,是因为用户在输入时不会被打断,大写锁定和 shift 不会对其产生负面影响,并且其他非字母字符也不会受到负面影响。

问题是没有选项可以将此属性用于组合框。来自类似帖子的解决方案似乎对我不起作用。我正在寻找复制 CharacterCasing 属性但对于 ComboBox。我不介意它是一个附属财产,事实上,那会很棒。我直接在 xaml 对象上尝试了几个不同的事件,但没有成功。

【问题讨论】:

    标签: wpf combobox uppercase


    【解决方案1】:

    ComboBox 模板在IsEditable 为真时使用TextBox。因此,您可以替换模板以在TextBox 上设置CharacterCasing,或者创建一个附加属性,通过其名称(“PART_EditableTextBox”)找到TextBox,并在其上设置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">
            ...
    

    【讨论】:

    • 这似乎对我不起作用...它不能在用户控件中使用吗?特别是 var textBox = comboBox.Template.FindName("PART_EditableTextBox", comboBox) as TextBox; 行将 textBox 设置为 null,这就是为什么 CharacterCasing 永远不会被应用。
    • 这很奇怪......我测试了它,它对我来说效果很好。您是否将 IsEditable 设置为 true ?如果为 false,则 ComboBox 使用不同的模板,该模板不包含 TextBox
    • 我不知道为什么它也不起作用。我在该行上停止了调试并检查了组合框的属性。 IsEditable 设置为 true。
    • 您是否为 ComboBox 使用自定义 ControlTemplate?如果是,请检查它是否包含具有适当名称的元素 (PART_EditableTextBox)。可以使用不包含此类元素的 ControlTemplates,但是当然这种实现将不起作用。
    • 感谢您提供好的解决方案...我会在您添加处理程序之前添加comboBox.Loaded -= comboBox_Loaded;(在您的 else 块中)。在加载控件之前多次调用 PropertyChanged 的​​情况下,这只是一个轻微的优化(据我所知,这应该是可能的,它会导致重复调用 ApplyCharacterCasing,即使它可以正常工作)跨度>
    猜你喜欢
    • 2019-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    • 2011-09-02
    • 2011-01-02
    • 1970-01-01
    • 2010-12-14
    相关资源
    最近更新 更多