WPF

2017-06-13 12 views
0
でのLoadedイベントとデータバインディング

は、私たちが依存関係プロパティを持つコントロールがあるとします。WPF

public class MyControl : ContentControl 
{ 

    static MyControl() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl))); 
    } 


    void DoSomething(object sender, RoutedEventArgs e) 
    { 
     //... 

    } 

    public MyControl() 
    {   
     this.Loaded += DoSomething; 
    } 

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
     "Value", typeof(string), typeof(MyControl), 
     new FrameworkPropertyMetadata(default(string), 
      FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal, OnValueChanged)); 


    private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     //some actions    
    } 

    public string Value 
    { 
     get { return (string)GetValue(MyControl.ValueProperty); } 
     set { SetValue(MyControl.ValueProperty, value); } 
    }} 

そしてどこかにXAMLで我々はいくつかのビューモデルのいくつかのプロパティヴァルにValuePropertyをバインドします。

私の質問は、Loadedイベントが発生した瞬間、MyControl.Valueの値はValの値に既に設定されているかどうかです。だから、MyControlがロードされたときに実行されるDoSomethingメソッドでValを使うことができますか?

ありがとうございました。

+3

それを試してみるのは簡単でしょうか? ;) –

+0

私は試してみましたが、何が間違っているのではなく、場合によっては機能しています(値が設定されています)、そうでないもの、依存しているものを理解できない、私は定義された振る舞いがあるかどうか、それがどのようなものなのかを尋ねることにしました。 –

+0

私はちょうど尋ねています、私は一日をこのことを理解してデバッグすることを試みました。 –

答えて

1
public class MyControl : ContentControl 
{ 
    public MyControl() 
    {   
     this.Loaded += (s,e) => DoSomething(); 
    } 

    private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var c = (MyControl)d; 
     if (c.IsLoaded) 
      c.DoSomething();    
    } 

    // this will be called only if the control is loaded 
    private void DoSomething() 
    { 
     var value = Value; 
     if (value == null) 
     { 
      ... 
     } else if (value == string.Empty) 
     { 
      ... 
     } else 
     { 
     } 
    } 

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
     "Value", typeof(string), typeof(MyControl), 
     new FrameworkPropertyMetadata(default(string), 
      FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal, OnValueChanged)); 

    public string Value 
    { 
     get { return (string)GetValue(MyControl.ValueProperty); } 
     set { SetValue(MyControl.ValueProperty, value); } 
    } 

    static MyControl() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl))); 
    } 

} 
+0

あなたの答えをありがとう、コントロールがロードされるときにユーザーに何を表示するかを決める前に、特定のアクションを実行するためにデータ検証を実行する必要がありました。すべてのプロパティは既に設定されています...私はそれがLoadedイベントの後になる可能性があると思いました。 –

1

私の質問は、Loadedイベントが発生した瞬間に、MyControl.Valueの値はすでにそれが持っているか、いないのValの値に設定されますか?

これに頼ることはできません。 Loadedイベントは、 'データバインディング済みイベント'ではありません。また、依存関係プロパティの値はいつでも変更でき、Valueプロパティの変更を処理する場所はOnValueChangedコールバックにあります。ポイントは、あなたがコールバックではなくLoadedであなたの依存関係プロパティの値に依存して任意のアクションを実行すべきであるということである

private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    MyControl ctrl = d as MyControl; 
    if (ctrl.IsLoaded) 
    { 
     //... 
    } 
} 

:あなたは、あなたがしたい場合は、コントロールがコールバックでロードされているかどうかをチェックすることができますイベントハンドラ。

+0

はい、あなたの意見を理解しています。私の状況では、データはViewModelからロードされ、有効性がチェックされます。データが有効でない場合は、追加のアクションを実行する必要があります。だから私はコントロールをロードするときにプロパティが既に設定されていると思っていました。すべてのバインドは完了です(しかし、何も設定されていないと言われています)...だから今はロードできます;私はこれを他の方法で実装しています –

+1

各依存関係にブール値フラグを設定できますプロパティコールバックを呼び出し、すべてのフラグが設定されたら "Complete"メソッドなどを呼び出します。 – mm8

+0

はい、ありがとう、私はそのようなことを実際に考えています... –