2010-10-15 35 views
4

我不知道爲什麼,但是沒有一個解決方案可以從similar question正常工作。WPF:與強制大寫的組合框?

我知道一個TextBox有一個屬性(CharacterCasing)可以設置爲Upper來將任何小寫字母改成大寫。它的工作原理非常好,因爲用戶在打字時絕不會中斷,大寫鎖定和移位不會對其造成負面影響,其他非字母字符也不會受到負面影響。

問題是沒有選項可以將此屬性用於ComboBox。來自類似帖子的解決方案似乎不適合我。我正在尋找複製CharacterCasing屬性,但爲一個組合框。我不介意它是一個附屬的財產,事實上,這將是偉大的。我直接在xaml對象上嘗試了幾個不同的事件,但沒有成功。

回答

13

IsEditable爲真時,ComboBox模板使用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"> 
     ... 
+0

這似乎並不爲我工作...是不是在用戶控制中可用?特別是'var textBox = comboBox.Template.FindName(「PART_EditableTextBox」,comboBox)作爲TextBox;'將textBox設置爲null,這就是'CharacterCasing'永遠不會被應用的原因。 – 2010-10-15 20:46:30

+0

這很奇怪......我測試了它,它對我來說工作得很好。你是否將IsEditable設置爲true?如果它是錯誤的,ComboBox使用不同的模板,它不包含TextBox – 2010-10-15 22:45:24

+0

我不知道它爲什麼不起作用。我在該行放置了一個調試停止並檢查了comboBox的屬性。 IsEditable被設置爲true。 – 2010-10-16 23:07:16