2011-01-05 12 views
6

:WPF ComboBox with IsEditable = "Doğru" - Eşleşmenin bulunmadığını nasıl belirleyebilirim? Örnek olarak aşağıdaki basit metin kutusu kullanma

<ComboBox IsEditable="True" SelectedItem="{Binding}"> 
    <ComboBoxItem>Angus/ComboBoxItem> 
    <ComboBoxItem>Jane</ComboBoxItem> 
    <ComboBoxItem>Steve</ComboBoxItem> 
</ComboBox> 

Kullanıcı bir isim yazarak kendi seçimini bulmasını sağlamak istiyorum, bu yüzden gerçek eşittir IsEditable belirledik. SelectedItem'a bağlı özellik için kabul edilebilir değerler, listedeki seçeneklerden herhangi biri veya seçim yok (null). Sorun şu ki, listede olmayan bir ada sahip türünde varsayılan olarak bir hata göstergesi yoktur.

Örneğin: Bir kullanıcı SelectedItem mülkiyet boş olmasına neden "Bob" yazdığı ama Bob listesinde bulunmadığını fark edemedi. Bunun yerine ComboBox'ın Metin mülkiyet boş veya boş VE SelectedItem olduğunu boş değil en kısa sürede görsel bir gösterge sağlamak ister ve bir daha yazarak onları durdurmak ki?

İlk düşüncem özel bir doğrulama kuralıydı, ancak combobox'ın hem Text hem de SelectedItem özelliklerine nasıl erişeceğimi bilmiyorum.

+0

WPF öğretmenimin ders sırasında onlarca kez tekrarladığı bir ipucu: WPF'de SelectedItem'i ASLA kesinlikle kullanmamalısınız. Koleksiyon görünümleri budur. –

cevap

3

Başlangıç ​​olarak, kullanıcının mevcut seçeneklerden birinde yazıp yazmadığını görmesini isteyebilirsiniz.

1) "Otomatik tamamlama açılan kutuyu" ara.

2) bu göz atın:

http://weblogs.asp.net/okloeten/archive/2007/11/12/5088649.aspx

http://www.codeproject.com/KB/WPF/WPFCustomComboBox.aspx

3) Ayrıca şunu da deneyin:

<ComboBox IsEditable="true" TextSearch.TextPath="Content"> 
     <ComboBoxItem Content="Hello"/> 
     <ComboBoxItem Content="World"/> 
    </ComboBox> 

Yukarıdaki kod parçası görsel" olduğunu sağlamak için bir primite yoludur gösterge "sizin için arıyoruz. Kullanıcı 'h' olarak yazıyorsa, giriş metin kutusunda 'merhaba' görünecektir. Ancak, bu kendi başına, kullanıcının yasadışı bir karakter yazmasını engellemek için bir mekanizmaya sahip olmayacaktır.

4) Bu daha gelişmiş bir versiyonudur: Biz hiçbir combobox madde olduğunu tespit kez İşte

private void myComboBox_KeyUp(object sender, KeyEventArgs e) 
    { 
     // Get the textbox part of the combobox 
     TextBox textBox = myComboBox.Template.FindName("PART_EditableTextBox", myComboBox) as TextBox; 

     // holds the list of combobox items as strings 
     List<String> items = new List<String>(); 

     // indicates whether the new character added should be removed 
     bool shouldRemove = true; 

     for (int i = 0; i < myComboBox.Items.Count; i++) 
     { 
      items.Add(((ComboBoxItem)myComboBox.Items.GetItemAt(i)).Content.ToString()); 
     } 

     for (int i = 0; i < items.Count; i++) 
     { 
      // legal character input 
      if(textBox.Text != "" && items.ElementAt(i).StartsWith(textBox.Text)) 
      { 
       shouldRemove = false; 
       break; 
      } 
     } 

     // illegal character input 
     if (textBox.Text != "" && shouldRemove) 
     { 
      textBox.Text = textBox.Text.Remove(textBox.Text.Length - 1); 
      textBox.CaretIndex = textBox.Text.Length; 
     } 
    } 

biz kullanıcıyı izin vermeyin yazarak devam: Kod-arkasında

<ComboBox Name="myComboBox" IsEditable="true" KeyUp="myComboBox_KeyUp"> 
     <ComboBoxItem Content="Hello"/> 
     <ComboBoxItem Content="World"/> 
     <ComboBoxItem Content="WPF"/> 
     <ComboBoxItem Content="ComboBox"/> 
    </ComboBox> 

metin kutusundaki metinle başlar. Eklenen karakteri kaldırır ve başka bir karakter bekleriz.

+0

Bu kodda bir hata var - bir tuşun basılı tutulması mümkündür ve yazılan kod sadece son karakteri kaldıracaktır. (ör. kullanıcı 5 f girdisine kadar "f" tuşunu basılı tutarsa, 4 metine eklenir). Bununla ilgili henüz bir çözüm bulamadım. –

1

Bu, açılan kutuda çok fazla kayıt olana kadar iyi bir çözümdür.Ben daha verimli arama

2

Bu olduğunu düşünüyorum açılan kutu kayıtları eklemeye devam edilir bağlama sürece

List<String> items = new List<String>(); 

private void myComboBox_KeyUp(object sender, KeyEventArgs e) 
{ 
    TextBox textBox = myComboBox.Template.FindName("PART_EditableTextBox", myComboBox) as TextBox; 

    // indicates whether the new character added should be removed 
    bool shouldRemove = true; 

    // this way you don't fill the list for every char typed 
    if(items.Count <= 0) 
    { 
     for (int i = 0; i < myComboBox.Items.Count; i++) 
     { 
      items.Add(((ComboBoxItem)myComboBox.Items.GetItemAt(i)).Content.ToString()); 
     } 
    } 
    // then look in the list 
    for (int i = 0; i < items.Count; i++) 
    { 
     // legal character input 
     if(textBox.Text != "" && items.ElementAt(i).StartsWith(textBox.Text)) 
     { 
      shouldRemove = false; 
      break; 
     } 
    } 

    // illegal character input 
    if (textBox.Text != "" && shouldRemove) 
    { 
     textBox.Text = textBox.Text.Remove(textBox.Text.Length - 1); 
     textBox.CaretIndex = textBox.Text.Length; 
    } 
} 

, dosyanın üstündeki bu

beyan ederiz: ben bu şekilde yapacağını Çözüm, bir çift değişiklikle kullanıcı1234567'nin cevabına dayanır. Öğeler listesini aramak yerine, bir eşleşmenin bulunup bulunmadığını görmek için ComboBox'ın SelectedIndex değerini> = 0 olarak kontrol eder ve RB'nin bir karakteri birden fazla karakter eklemek için RB'nin endişesini giderir. Ayrıca karakterleri reddettiğinde sesli bir geri bildirim ekler.

private int _lastMatchLength = 0; 

private void myComboBox_GotFocus(object sender, RoutedEventArgs e) 
{ 
    _lastMatchLength = 0; 
} 

private void myComboBox_KeyUp(object sender, KeyEventArgs e) 
{ 
    ComboBox cBox = sender as ComboBox; 

    TextBox tb = cBox.Template.FindName("PART_EditableTextBox", cBox) as TextBox; 
    if (tb != null) 
    { 
     if (cBox.SelectedIndex >= 0) 
     { 
      _lastMatchLength = tb.SelectionStart; 
     } 
     else if (tb.Text.Length == 0) 
     { 
      _lastMatchLength = 0; 
     } 
     else 
     { 
      System.Media.SystemSounds.Beep.Play(); 
      tb.Text = tb.Text.Substring(0, _lastMatchLength); 
      tb.CaretIndex = tb.Text.Length; 
     } 
    } 
} 
İlgili konular