DependencyProperty's value is null when method in attached property's class is called

自闭症网瘾萝莉.ら 提交于 2019-12-24 14:22:29

问题


we have been working a complete day on this problem and have it all summed up to a small example. We are currently converting a project from Silverlight to WPF, in Silverlight both versions work, in WPF only one does.

We have a simple control with a string-type dependencyproperty like this:

public class MyControl : Control
{
  public String Text
  {
    get { return (String)GetValue(TextProperty); }
    set { SetValue(TextProperty, value); }
  }

  public static readonly DependencyProperty TextProperty =
    DependencyProperty.Register("Text", typeof(String), typeof(MyControl), new PropertyMetadata(null, TextChanged));

  private static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {

  }
}

Then we have a class with an attached property as follows:

public class MyAttachedProperty
{
  public static readonly DependencyProperty DescriptionProperty = DependencyProperty.RegisterAttached("Description", typeof(String), typeof(MyAttachedProperty), new PropertyMetadata(null, DescriptionPropertyChanged));

  public static String GetDescription(DependencyObject obj, String value)
  {
    return (String)obj.GetValue(DescriptionProperty);
  }

  public static void SetDescription(DependencyObject obj, String value)
  {
    obj.SetValue(DescriptionProperty, value);
  }

  private static void DescriptionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {
    var MySuperbControl = d as MyControl;
    Debug.WriteLine("The control's text is: " + MySuperbControl.Text);
  }

  public static void DoNothing()
  {

  }
}

We implement our control like this in MainWindow.xaml:

<ContentControl x:Name="MyContentControl">
  <ContentControl.ContentTemplate>
    <DataTemplate>
      <local:MyControl x:Name="MyCntrl" Text="DefaultText" att:MyAttachedProperty.Description="Test"/>
    </DataTemplate>
  </ContentControl.ContentTemplate>
</ContentControl>

and in the code-behind have this constructor:

public MainWindow()
{
  MyAttachedProperty.DoNothing();
  InitializeComponent();
}

If you start the project this way, the Debug-text will not contain any text. If you call DoNothing() after InitializeComponent(), it will show the text. Can anyone please explain, why? Note, in Silverlight both ways work. Also, if you do not use the control in a datatemplate both ways work.


回答1:


It's interesting side effect. It makes sense when you think that DependencyProperty registration adds it to some global collection. If you call static constructor on MyAttachedProperty first it is added to the collection first and set first for an object.

If you force static constructor to run first on MyControl by adding same empty static method DoNothing then you can do

    public MainWindow()
    {
        MyControl.DoNothing();
        MyAttachedProperty.DoNothing();
        InitializeComponent();
    }

and the text will be shown or in case

    public MainWindow()
    {
        MyAttachedProperty.DoNothing();
        MyControl.DoNothing();
        InitializeComponent();
    }

the empty text will be shown.



来源:https://stackoverflow.com/questions/24281898/dependencypropertys-value-is-null-when-method-in-attached-propertys-class-is-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!