2011-10-20 4 views
5

データバインディングが発生したときに、コントロールの変更を無視するにはどうすればよいですか?私はgotfocus、textchanged、leavefocusなどのさまざまなイベントをフックしようとしましたが、コントロールにすでにフォーカスがあり、ユーザーが変更をキャンセルすると、レコードをリロードしてデータバインディングを引き継ぐと、textchangedはユーザーがフォーカスはそのコントロールにあります。コールスタックは空です。データバインディングの開始やデータバインディングのようなグローバルなデータバインディングイベントはありますか?私はOnProperyChangedを発射する場所を見ますが、その呼び出しの中ではデータバインディングは発生しません。それは "キューに入れられている"ように見えるし、いくつかの他のポイントで実行されます。データバインディングによるテキスト/値の変更を無視する

私はビューモデルでプロパティー変更イベントをフックしようとしていましたが、これは検出されず、ユーザーがコントロールから離れるまでフォームが表示されていることを視覚的に表示できないことを意味します。私は知っている、私はすべての文字の変更ですぐにバインディングが発生するようにバインディングを変更することができますが、ユーザーが値を入力し終えていないので、いくつかの検証ケースが混乱する。

ユーザーがキー、クリップボード、マウスのクリップボードなどを使用しているかどうかにかかわらず、TextChangedByUserのようなイベントが大好きです。

ユーザーの変更とデータバインドの変更を区別する方法を理解できません。

答えて

6

私は本当に、そのユーザーがキー、クリップボード、マウス、クリップボード、ユーザーによってトリガ何 を使用するかどうか は火だろうTextChangedByUserのようなイベントのいくつかの種類が大好きです。

ユーザーの変更とデータバインディングの変更を区別する方法がわかりません。


ではなくBinding.SourceUpdatedイベントを使用し、ユーザ入力を検出するText.TextChangedイベントを使用しないでください。

以上一般: ビジュアルエレメントのDPを使用してユーザーの更新を検出しないでください。代わりにイベントを使用してください。

これはRoutedEventです。 バインド時にNotifyOnSourceUpdated = trueを設定する必要があります。 UpdateSourceTriggerの助けを借りて、通知を受けたいときにも微調整することができます。


あなたのXAMLは、このようなSTHのようになります。

<Grid x:Name="LayoutRoot" Binding.SourceUpdated="LayoutRoot_SourceUpdated"> 
    ... 
    <TextBox> 
     <TextBox.Text> 
      <Binding NotifyOnSourceUpdated="True" Path="path" UpdateSourceTrigger="PropertyChanged" > 
      </Binding> 
     </TextBox.Text> 
</Grid> 

あなたのイベントは、このようなことができます:

private void LayoutRoot_SourceUpdated(object sender, DataTransferEventArgs e) 
{ 
    // called every time s.th. changed by user 
} 

(によるコメントに編集した)
なぜこれがへの有効な方法です。入力がユーザによって何らかの形でトリガされたかどうかを検出しますか?
TextBoxのDataContextの 'path'プロパティはソースで、 'TextBox.Text'プロパティはのターゲットです。
[データバインディングの概要] http://msdn.microsoft.com/en-us/library/ms752347.aspx
バインディングが初期化され、ソース値が 'TextBox.Text'プロパティに書き込まれるときにTextBox.Textプロパティが初めて変更されます。バインドがいつ正確に行われるかわからないので、TextBox.Textプロパティまたはそのイベント(TextChangedなど)を使用してユーザー入力を検出することはできません。したがって: ユーザー入力を検出するのにText.TextChangedイベントを使用しないでください。より一般的な:ビジュアル要素のDPを使用してユーザーの更新を検出しないでください!何を意味し、一度「TextBox.Text」プロパティの変更(ごターゲット)その.After、バインディングアップデートソースがで定義されたことにより、ユーザーが視覚的テキストフィールドの内容を変更した場合

UpdateSourceTrigger。SourceUpdatedイベントが発生したときです。

私は、バインディングの外部からのバインディングソースの変更の影響を知りません。 しかし、私は完全なエディタのようなデスクトップ - アプリケーションがその方法でユーザーの変更を検出し、それは非常にうまく動作しています。

+0

はい、私はこれを既に見つけましたが、実際に私が直接望んでいたものではありません。私はバインディングオブジェクトのTargetUpdatedイベントのイベントハンドラを追加しています。私のカスタムコントロール内で処理されるこのイベントでは、ユーザーがフィールドを変更したかどうかを追跡するために使用するフラグをリセットします。私が本当に好きなのは、バインディングイベントであるかどうかを示す静的プロパティを照会することができるイベントハンドラ内です。 – happyfirst

+0

あなたは本当に間違った方法でこれを見ています。私が提案したやり方で、TargetUpdatedからSourceUpdatedへの再設計を考えるべきです。それはまさにあなたが探しているものであることに気付くでしょう。 "私が本当に好きなのは、バインディングイベントであるかどうかを知らせる静的プロパティを照会することができるイベントハンドラ内です" –

+0

何を取得しているのかを確認します。私は技術的に推測すると、sourceupdatedは常に最初に発射され、次にターゲットが更新されますか?私はあなたのコメントのために投稿を編集しました。SourceUpdated – happyfirst

0

{Binding Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} 

EDIT設定するために、あなたのバインディングコードを更新する必要があります。申し訳ありませんが、私はすでにこのことを知っているという事実を監督している...その場合は、私は助けることはできませんが。 (

0

あなたは、ユーザ入力を検出するUIElement.TextInput eventを使用することができます。

(注)UIElement.PreviewTextInput eventを使用する必要がある場合がありますので、イベントはおそらく既に入力コントロール自体によって処理されていること。

関連する問題