2009-02-24 10 views
6

Je veux créer zone de liste déroulante modifiable avec les propriétés suivantes:ComboBox éditable

  1. Bind la propriété text à mon modèle de données.
  2. Le modèle de données peut remplacer les modifications dans l'interface graphique, même dans la sélection modifiée. Par exemple. Je peux choisir de 1, 2, 3 je choisis 2, mais certains composants vers le bas sous les modifications à 3.
  3. Mise à jour du modèle de données sur les événements suivants:

    1. Sélection Changé
    2. perdre le focus
    3. Entrée
    4. Entrée (doit se comporter de la même manière que la mise au point perdue).

Je suis en mesure de créer un tel contrôle, mais il est assez laid (en utilisant de nombreux hacks) et j'espérais qu'il ya un moyen plus simple ...

Merci à l'avance

Répondre

2

Ok, je voici ce que je l'ai fait, et son pas laid:

/// <summary> 
/// Editable combo box which updates the data model on the following: 
/// 1. Select## Heading ##ion changed 
/// 2. Lost focus 
/// 3. Enter or Return pressed 
/// 
/// In order for this to work, the EditableComboBox requires the follows, when binding: 
/// The data model value should be bounded to the Text property of the ComboBox 
/// The binding expression UpdateSourceTrigger property should be set to LostFocus 
/// e.g. in XAML: 
/// <PmsEditableComboBox Text="{Binding Path=MyValue, UpdateSourceTrigger=LostFocus}" 
/// ItemsSource="{Binding Path=MyMenu}"/> 
/// </summary> 
public class PmsEditableComboBox : ComboBox 
{ 
    /// <summary> 
    /// Initializes a new instance of the <see cref="PmsEditableComboBox"/> class. 
    /// </summary> 
    public PmsEditableComboBox() 
     : base() 
    { 
     // When TextSearch enabled we'll get some unwanted behaviour when typing 
     // (i.e. the content is taken from the DropDown instead from the text) 
     IsTextSearchEnabled = false; 
     IsEditable = true; 
    } 

    /// <summary> 
    /// Use KeyUp and not KeyDown because when the DropDown is opened and Enter is pressed 
    /// We'll get only KeyUp event 
    /// </summary> 
    protected override void OnKeyUp(KeyEventArgs e) 
    { 
     base.OnKeyUp(e); 

     // Update binding source on Enter 
     if (e.Key == Key.Return || e.Key == Key.Enter) 
     { 
      UpdateDataSource(); 
     } 
    } 

    /// <summary> 
    /// The Text property binding will be updated when selection changes 
    /// </summary> 
    protected override void OnSelectionChanged(SelectionChangedEventArgs e) 
    { 
     base.OnSelectionChanged(e); 
     UpdateDataSource(); 
    } 

    /// <summary> 
    /// Updates the data source. 
    /// </summary> 
    private void UpdateDataSource() 
    { 
     BindingExpression expression = GetBindingExpression(ComboBox.TextProperty); 
     if (expression != null) 
     { 
      expression.UpdateSource(); 
     } 
    } 

} 
0

la façon la plus simple de le faire est d'utiliser la propriété UpdateSourceTrigger sur la liaison. Vous ne pouvez pas être en mesure de correspondre exactement à votre comportement actuel, mais vous pouvez trouver qu'il est comparable.

La propriété UpdateSourceTrigger contrôle lorsque la cible de la liaison met à jour la source. Les différents contrôles WPF ont des valeurs par défaut différentes pour cette propriété lorsqu'ils sont liés.

Voici vos options:

UpdateSourceTrigger.Default = Permet le contrôle cible pour déterminer le mode UpdateSourceTrigger.

UpdateSourceTrigger.Explicit = Mettre à jour la source uniquement lorsque quelqu'un appelle BindingExpression.UpdateSource();

UpdateSourceTrigger.LostFocus = Mettre à jour automatiquement la source de liaison chaque fois que la cible perd le focus. De cette façon, une modification peut être effectuée, puis la liaison est mise à jour après le déplacement de l'utilisateur.

UpdateSourceTrigger.PropertyChanged = Chaque fois que DependencyProperty sur la cible change des valeurs, la source est mise à jour immédiatement. La plupart des UserControls ne définissent pas cette propriété par défaut car elle nécessite plus de mises à jour de liaison (peut être un problème de performances).