6

次のプロパティを持つ編集可能なコンボ ボックスを作成したい:

  1. テキスト プロパティをデータ モデルにバインドします。
  2. データ モデルは、選択が変更された場合でも、GUI の変更を上書きする場合があります。たとえば、1、2、3 から選択できます。私は 2 を選択しますが、下にあるコンポーネントによって 3 に変更されます。
  3. 次のイベントでデータ モデルを更新します。

    1. 選択が変更されました
    2. フォーカスを失う
    3. Enter キーを押します (フォーカスを失った場合と同じように動作する必要があります)。

私はそのようなコントロールを作成することができましたが、(多くのハックを使用して) かなり見苦しく、もっと簡単な方法があることを願っていました...</p>

前もって感謝します

4

2 に答える 2

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();
        }
    }

}
于 2009-03-08T09:00:41.263 に答える
0

これを行う最も簡単な方法は、バインディングで UpdateSourceTrigger プロパティを使用することです。現在の行動と正確に一致することはできないかもしれませんが、同等であることがわかるかもしれません。

UpdateSourceTrigger プロパティは、バインディングのターゲットがソースを更新するタイミングを制御します。異なる WPF コントロールは、バインドされたときのこのプロパティの既定値が異なります。

オプションは次のとおりです。

UpdateSourceTrigger.Default = ターゲット コントロールが UpdateSourceTrigger モードを決定できるようにします。

UpdateSourceTrigger.Explicit = 誰かが BindingExpression.UpdateSource() を呼び出したときにのみソースを更新します。

UpdateSourceTrigger.LostFocus = ターゲットがフォーカスを失うたびにバインディング ソースを自動的に更新します。このようにして変更を完了し、ユーザーが次に移動した後にバインディングを更新できます。

UpdateSourceTrigger.PropertyChanged = ターゲットの DependencyProperty の値が変更されるたびに、ソースはただちに更新されます。ほとんどの UserControls は、より多くのバインディングの更新を必要とするため (パフォーマンスの問題になる可能性があります)、このプロパティをデフォルトに設定しません。

于 2009-03-11T12:14:00.773 に答える