2009-02-24 4 views
6

Я хочу создать редактируемый выпадающий со следующими свойствами:редактируемые ComboBox

  1. Bind текст свойство моей модели данных.
  2. Модель данных может переопределять изменения в графическом интерфейсе, даже в разделе «Выбор». Например. Я могу выбрать из 1, 2, 3 я выбираю 2, но некоторые компоненты вниз при изменении его 3.
  3. Обновить модель данных о следующих событиях:

    1. Изменено Выбор
    2. Lose фокус
    3. Введите нажатие (должно вести себя так же, как потерянный фокус).

Я был в состоянии создать такой контроль, но это довольно уродливое (используя много хаков), и я надеялся, что есть более простой способ ...

Заранее спасибо

ответ

2

Хорошо, я вот что я сделал, и его не так некрасиво:

/// <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

Простейший способ сделать это, чтобы использовать свойство UpdateSourceTrigger на связывание. Возможно, вы не сможете точно сравнить свое текущее поведение, но вы можете обнаружить, что оно сопоставимо.

Свойство UpdateSourceTrigger контролирует, когда объект привязки обновляет источник. Различные элементы управления WPF имеют разные значения по умолчанию для этого свойства при привязке.

Вот варианты:

UpdateSourceTrigger.Default = Разрешить цель управления для определения режима UpdateSourceTrigger.

UpdateSourceTrigger.Explicit = Только источник обновлений, когда кто-то вызывает BindingExpression.UpdateSource();

UpdateSourceTrigger.LostFocus = Автоматическое обновление источника привязки всякий раз, когда цель теряет фокус. Таким образом, изменение может быть завершено, а затем привязка обновляется после того, как пользователь перейдет.

UpdateSourceTrigger.PropertyChanged = Всякий раз, когда DependencyProperty на цели изменяет значения, источник обновляется немедленно. Большинство UserControls не используют это свойство по умолчанию, потому что для этого требуется больше обновлений привязки (может быть проблема с производительностью).