调用附加属性类中的方法时,DependencyProperty的值为null

时间:2014-06-18 09:28:42

标签: c# .net wpf xaml datatemplate

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

我们有一个简单的控件,其字符串类型依赖属性如下:

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

  }
}

然后我们有一个带有附加属性的类,如下所示:

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中实现我们的控件:

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

并且在代码隐藏中有这个构造函数:

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

如果以这种方式启动项目,则调试文本将不包含任何文本。如果在InitializeComponent()之后调用DoNothing(),它将显示文本。谁能解释一下,为什么?注意,在Silverlight中两种方式都有效。此外,如果您不在datatemplate中使用该控件,则两种方式都可以正常工作。

1 个答案:

答案 0 :(得分:1)

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

如果强制静态构造函数首先在MyControl上运行,方法是添加相同的空静态方法DoNothing,那么就可以了

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

将显示文字 或者以防万一

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

将显示空文本。