2010-07-30 24 views
36

Tengo una propiedad ComboBox y ComboBox.IsEditable se establece en True para que ComboBox actúe como un cuadro de texto y una lista desplegable simultáneamente. Pero cuando el ComboBox está vinculado a datos, al ingresar texto personalizado no se agregará un nuevo elemento a la colección enlazada a datos.WPF Editable ComboBox

Por ejemplo, si ingreso 'Joe' en un ComboBox que está vinculado a una lista de personas, que no contiene el valor 'Joe', entonces el valor 'Joe' no se va a agregar al lista desplegable automáticamente.

¿Cuál es la mejor manera de manejar esto?

Respuesta

3

Lo manejaría en el evento LostFocus.

Aquí puede verificar si SelectedItem es nulo. Si es así, agregue el valor de Texto a la lista encuadernada y establezca SelectedItem en el nuevo elemento.

En XAML:

<ComboBox Name="_list" LostFocus="LostFocus" IsEditable="True"/> 

En código subyacente:

Espero que esto ayude :)

+0

Es posible que también desee hacerlo en el evento DropDownOpened. – Taudris

3

Mi sugerencia sería utilizar un MVVM-enfoque y vincular a su ComboBox.text a algún TextProperty de su ViewModel. (Lo mismo se puede lograr simplemente agregando una propiedad de cadena a su vista) Luego puede tratar la entrada en el colocador de esta propiedad y agregar ese nuevo elemento a la lista, sin importar en qué forma se "comprometió" en la vista. AFAIK no hay un mecanismo listo para usar para agregar nuevos elementos a su fuente de datos, de todos modos tendrá que hacer la generación de artículos.

Alternativamente, puede enlazar ambos elementos, SelectedItem y Text de su ComboBox, para evitar búsquedas en caso de que el usuario haya ingresado un elemento conocido. Pero esa parte puede ser menos importante para responder su pregunta.

68

Aquí está una manera básica MVVM compatible de conseguir el comportamiento que desea:

MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
     <ComboBox Margin="30,5,30,5" 
        IsEditable="True" 
        ItemsSource="{Binding Items}" 
        SelectedItem="{Binding SelectedItem}" 
        Text="{Binding NewItem, UpdateSourceTrigger=LostFocus}"/> 
     <TextBox Margin="30,5,30,5" /> 
    </StackPanel> 
</Window> 

MainWindow.cs

public partial class MainWindow : Window, INotifyPropertyChanged 
{ 
    private string _selectedItem; 

    private ObservableCollection<string> _items = new ObservableCollection<string>() 
    { 
     "One", 
     "Two", 
     "Three", 
     "Four", 
     "Five", 
    }; 

    public MainWindow() 
    { 
     InitializeComponent(); 
     this.DataContext = this; 
    } 

    public IEnumerable Items 
    { 
     get { return _items; } 
    } 

    public string SelectedItem 
    { 
     get { return _selectedItem; } 
     set 
     { 
      _selectedItem = value; 
      OnPropertyChanged("SelectedItem"); 
     } 
    } 

    public string NewItem 
    { 
     set 
     { 
      if (SelectedItem != null) 
      { 
       return; 
      } 
      if (!string.IsNullOrEmpty(value)) 
      { 
       _items.Add(value); 
       SelectedItem = value; 
      } 
     } 
    } 

    protected void OnPropertyChanged(string propertyName) 
    { 
     var handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

que tenía que colocar otro control en la ventana como he establecido la propiedad UpdateSourceTrigger del enlace Text a LostFocus. Si no hay otros controles en la ventana, el Combobox nunca perderá el foco.

Cambié el modo de actualización porque el modo de actualización predeterminado es Propertychanged, que agregará un nuevo elemento para cada pulsación de tecla.

E.G. si ingresó el texto "Ventana", se agregará lo siguiente a su colección:

W 
Wi 
Win 
Wind 
Windo 
Window 
+4

Tuve que agregar un get {return SelectedItem; } a la propiedad NewItem para que funcione. –

+0

¡Esto es maravilloso! Funciona perfectamente. :) – Kokos