调用附加属性类中的方法时,DependencyProperty的值为null [英] DependencyProperty's value is null when method in attached property's class is called

查看:153
本文介绍了调用附加属性类中的方法时,DependencyProperty的值为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们已经在这一问题上完成了一整天的工作,并将其总结为一个小例子。目前,我们正在将一个项目从Silverlight转换为WPF,在Silverlight中这两个版本都可以,而在WPF中只有一个。

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.

我们有一个简单的控件,带有字符串类型的依赖项this:

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()
  {

  }
}

我们在MainWindow.xaml中实现如下控件:

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();
}

如果以此方式启动项目,则调试文本将不包含任何内容文本。如果在InitializeComponent()之后调用DoNothing(),它将显示文本。谁能解释,为什么?请注意,在Silverlight中,两种方法都可以工作。另外,如果您不在数据模板中使用控件,则这两种方法都可以使用。

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.

推荐答案

这是一个有趣的副作用。当您认为DependencyProperty注册将其添加到某些全局集合时,这很有意义。如果首先在MyAttachedProperty上调用静态构造函数,则它将首先添加到集合中,并首先为一个对象设置。

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.

如果通过添加相同的方法强制静态构造函数首先在MyControl上运行空的静态方法DoNothing然后可以执行

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();
    }

将显示空白文本。

这篇关于调用附加属性类中的方法时,DependencyProperty的值为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆