4

Windowデータエディターを表すWPFがあります。のDataContextは、Window(を実装する)監視可能なオブジェクトのものINotifyPropertyChangedです。

監視可能なオブジェクトの各プロパティは、WindowTextBox数値タイプのCheckBox場合bool、などの場合)の適切なウィジェットにバインドされます。

変更されたプロパティを保持するために[OK]ボタンと[キャンセル]ボタンは必要ありません。ウィジェットがフォーカスを失ったときに、基になるデータを監視可能なオブジェクトに保持したいと思います。

これを行うために、ウィジェットのイベントPreviewLostKeyboardFocusとイベントを処理しました。LostFocus私のundoフレームワークには、現在の状態を表す監視可能なオブジェクトのコピーと、新しい状態のコピーが必要です。イベントはオブジェクトのPreviewLostKeyboardFocusコピーを作成し、LostFocusイベントは実際にデータベースへの保存を実行します。

しかし、私の問題はこれです。フィールドのバインディングは、イベントが実行されるまで基になる監視可能なオブジェクトを実際には更新しません。LostFocus正味の効果は、aのテキストをTextBox「A」から「B」に変更すると、フィールドのデータが「A」として保持されることです。「A」から「B」、「C」に変更すると、「B」が持続します。

イベントハンドラーと基になるオブジェクトのセッターにブレークポイントを設定しました。案の定、PreviewLostKeyboardFocus最初に実行し、次に実行LostFocusし、最後に監視可能なオブジェクトのセッターを実行します。

これをできるだけ一般的にしたいので、オブザーバブルオブジェクトにKeyboardFocusChangedEventArgs、を使用して独自のプロパティを更新するように指示することはできますが、フィールドごとに個別のイベントハンドラーが必要であり、かなりの数になる可能性があります。

とイベントの間Bindingを実行する方法はありますか?PreviewLostKeyboardFocusLostFocus

XAML:

<TextBox Text="{Binding ObjectProperty, StringFormat='{}{0:F5}'}" LostFocus="PersistentTextBox_LostFocus" PreviewLostKeyboardFocus="PersistentTextBox_PreviewLostKeyboardFocus" />

コードビハインドのイベントハンドラー:

private void PersistentTextBox_LostFocus(object sender, RoutedEventArgs e) {
    this.ObservableObject.PersistChanges(this.tempObservableObject);
}

private void PersistentTextBox_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) {
    this.tempObservableObject = this.ObservableObject;
}

ObservableObjectクラス(セッター):

public class ObservableObject : INotifyPropertyChanged {
    ...
    public Single ObjectProperty {
        get {
            return this._objectProperty;
        }
        set {
            this._objectProperty = value;
            RaisePropertyChanged("ObjectProperty");
        }
    }
}

ありがとう!

4

1 に答える 1

5

私があなたの質問を正しく理解している場合、これはデフォルトでフォーカスが失われTextBoxたときに更新されるという事実が原因である可能性があります。Source

これを解決する1つの方法は、をに設定するTextBox UpdateSourceTriggerことです。PropertyChanged

<TextBox Text="{Binding ObjectProperty, UpdateSourceTrigger=PropertyChanged, StringFormat='{}{0:F5}'}" 

これにより、で変更が行われるとすぐに、基になる監視可能なオブジェクトを更新できるようになりますTextBox。その後、ウィジェットのロストフォーカスイベントで変更を永続化できます。

または、LostFocusハンドラーでソースをに設定して更新するUpdateSourceTriggerこともできます。Explicit

 <TextBox Text="{Binding ObjectProperty, UpdateSourceTrigger=Explicit, StringFormat='{}{0:F5}'}" 

    private void TextBox_LostFocus(object sender, RoutedEventArgs e)
    {
       (sender as TextBox).GetBindingExpression(TextBox.TextProperty).UpdateSource();
    }
于 2013-02-14T21:50:46.350 に答える