WPF中加载的事件和数据绑定

时间:2017-06-13 12:37:37

标签: c# wpf data-binding

假设我们有一个带依赖属性的控件:

 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绑定到某些ViewModel的某个属性Val。

我的问题是,在Loaded事件被触发时,MyControl.Value的值是否已经设置为它具有或不具有的Val值?那么,我能够在加载MyControl时执行的DoSomething方法中使用Val吗?

提前感谢您的任何答案。

2 个答案:

答案 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)));
    }

}

答案 1 :(得分:1)

  

我的问题是,在Loaded事件被触发的那一刻,MyControl.Value的值是否已经设置为它具有或不具有的Val值?

你不能依赖于此。 Loaded事件不是'数据绑定已完成'事件。此外,依赖项属性的值可以随时更改,并且处理Value属性的任何更改的位置都在OnValueChanged回调中。如果要执行以下操作,可以检查控件是否已加载回调:

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

关键是你应该执行任何依赖于回调中依赖属性值而不是Loaded事件处理程序中的值的操作。