简体   繁体   中英

Implementing both DependencyObject and INotifyPropertyChanged

I've got a dependency object that defines a single depedendency property named "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;
  }
}

In XAML I'm declaring it like this:

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

And further down I bind to it as such:

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

The above control template is used as the display template for cells of a grid. I want to use dependency objects/properties here for performance reason, given that they do have a performance and memory resource edge over implementing INotifyPropertyChanged as I understand it.

The problem I'm having is getting an update to trigger for the cells when data for Renderer object is changed. In code I'm attempting to get around the fact that Dependency properties will not trigger updates if the value is the same by first setting to setting to null, then setting back to the original property value. This does not work.

The only thing I have been able to get to work is to also have the object implement INotifyPropertyChanged and firing the PropertyChanged event in CellInfo.Renderer setter.

My guess is having to implement INotifyPropertyChange negates the performance benefit of using only DependencyObjects , is that correct? At this point, if I'm forced to implement INotifyPropertyChanged , I might as well not even extend DependencyObject , correct?

Thanks for any input.

Either swap out an instance of Renderer instead of modifying the existing instance (thus you may as well make it immutable), or have it extend DependencyObject and expose dependency properties.

The reason setting the property to null and back again isn't working is because WPF never gets a chance to "see" the property as null. Your code is running in a dispatcher message and binding updates will occur in a separate message. Since, that message doesn't run until after yours, it never sees the change. There is a workaround here, which is to update to null in one message, and then set it back again in another. But then you're throwing all performance gains well and truly out the window. Not to mention that doing it the "right" way turns out to be much easier anyway.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM