1

「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

私が抱えている問題は、レンダラーオブジェクトのデータが変更されたときにセルに対してトリガーする更新を取得することです。コードでは、最初にnullに設定してから元のプロパティ値に戻すことで、値が同じ場合に依存関係プロパティが更新をトリガーしないという事実を回避しようとしています。これは動作しません。

私が仕事に取り掛かることができた唯一のことは、オブジェクトに実装さINotifyPropertyChangedせ、セッターでPropertyChangedイベントを発生させることです。CellInfo.Renderer

私の推測では、実装する必要があると、INotifyPropertyChangeのみを使用することによるパフォーマンス上の利点が無効になりますDependencyObjectsが、それは正しいですか?この時点で、私が実装を余儀なくされた場合INotifyPropertyChanged、私は拡張すらしないかもしれませんDependencyObject、正しいですか?

ご入力いただきありがとうございます。

4

1 に答える 1

1

既存のインスタンスを変更する代わりに のインスタンスを交換するかRenderer(したがって、インスタンスを不変にすることもできます)、拡張DependencyObjectして依存関係プロパティを公開します。

プロパティを null に設定してから戻すことが機能しない理由は、WPF がプロパティを null として「見る」機会を得られないためです。コードはディスパッチャー メッセージで実行され、バインディングの更新は別のメッセージで行われます。そのメッセージはあなたのメッセージの後まで実行されないため、変更が表示されることはありません。ここには回避策があります。これは、あるメッセージで null に更新し、別のメッセージで再度設定することです。しかし、そうすると、すべてのパフォーマンスの向上を適切に、そして真に窓の外に投げ出すことになります。とにかく、「正しい」方法でそれを行う方がずっと簡単であることが判明したことは言うまでもありません。

于 2012-07-19T17:15:10.173 に答える