实现DependencyObject和INotifyPropertyChanged

时间:2012-07-19 17:08:29

标签: c# .net wpf xaml

我有一个依赖项对象,它定义了一个名为“Renderer”的依赖属性。

public class Renderer {
  public string ResourceKey{get; set;}
  public string[] Params{get; set;}
}

public class CellInfo : DependencyObject {
  public static readonly DependencyProperty RendererProperty=
  DependencyProperty.Register("Renderer", typeof(Renderer), typeof(CellInfo), null);

  public Renderer Renderer {
    get { return (Renderer)GetValue(RendererProperty); }
    set { SetValue(RendererProperty, value); }
  }

  public void UpdateRenderer(string resourceKey, params string[] parameters) {
    this.Renderer.ResourceKey = resourceKey;
    this.Renderer.Params = parameters;
    //force refresh - this does not work
    Renderer tmp = this.Renderer;
    this.Renderer = null;
    this.Renderer = tmp;
  }
}

在XAML中,我宣布这样:

<local: CellInfo x:key="cellInfo" />

进一步下来,我这样绑定它:

 <ControlTemplate x:Key="MyDisplayTemplate" >
    <TextBlock VerticalAlignment="Center" HorizontalAlignment="Stretch"  >
  <TextBlock.Text>
    <MultiBinding Converter="{StaticResource MyConverter}" >
      <Binding Path="Value" />
      <Binding Source="{StaticResource cellInfo}" Path="Renderer"/>
    </MultiBinding>
  </TextBlock.Text>
    </TextBlock>
</ControlTemplate>

上述控制模板用作网格单元格的显示模板。我想在这里使用依赖对象/属性是出于性能原因,因为它们在实现INotifyPropertyChanged方面确实具有性能和内存资源优势 据我所知。

我遇到的问题是在更改Renderer对象的数据时获取更新以触发单元格。在代码中,我试图解决这样一个事实,即如果值相同,则首先将设置设置为null,然后设置回原始属性值,则依赖项属性不会触发更新。这不起作用。

我唯一能够开始工作的还有对象实现INotifyPropertyChanged并在PropertyChanged setter中触发CellInfo.Renderer事件。

我的猜测是必须实施INotifyPropertyChange否定仅使用DependencyObjects的性能优势,这是正确的吗?此时,如果我被迫实施INotifyPropertyChanged,我甚至可能不会延伸DependencyObject,对吗?

感谢您的任何意见。

1 个答案:

答案 0 :(得分:1)

交换Renderer的实例而不是修改现有实例(因此你也可以使它不可变),或者让它扩展DependencyObject并公开依赖属性。

将属性设置为null并再次返回的原因是因为WPF永远不会有机会将该属性“看到”为null。您的代码在调度程序消息中运行,绑定更新将在单独的消息中进行。因为,该消息直到您的消息之后才会运行,它永远不会看到更改。这里有一个解决方法,即在一条消息中更新为null,然后在另一条消息中再次设置它。但是,那么你将把所有的性能提升放在窗外。更不用说无论如何,以“正确”的方式做到这一点变得更加容易。