2

外部ステートフル モジュールが動作する必要がある ValueConverter があります。だから私は Freezable からそれを継承し、依存関係のプロパティを宣言しました。

public class Decorator : Freezable, IValueConverter
{
  public static readonly DependencyProperty HighlighterProperty =
      DependencyProperty.Register("Highlighter", typeof (IHighlighter), typeof (Decorator), new PropertyMetadata(null));

  public ITypeNameHighlighter TypeNameHighlighter
  {
    get { return (ITypeNameHighlighter)GetValue(TypeNameHighlighterProperty); }
    set { SetValue(TypeNameHighlighterProperty, value); }
  }
  //...
}

次に、DataTemplate と DataTemplateSelector を使用してビューを表示します。リソースで Decorator のインスタンスを作成し、バインディングで使用する

<DataTemplate x:Key="ViewTemplate">
...

<ListView ...>
  <Control.Resources>
    <GUI:Decorator x:Key="Decorator" **Highlighter="{Binding Highlighter}"** />
  </Control.Resources>
...

<GridViewColumn>
  <GridViewColumnHeader  ... />

    <GridViewColumn.CellTemplate>
      <DataTemplate>
        <GUI:RichTextBlock RichText="{Binding Path=Title, Converter={**StaticResource Decorator**}}" />
      </DataTemplate>
  </GridViewColumn.CellTemplate>
</GridViewColumn>
</ListView>
...
</DataTemplate>

問題は、View の複数のインスタンスが作成されるときに、すべてが Decorator の 1 つの (最初の) インスタンスを使用してエンティティを RichText に変換することです (実際には、Decorator の複数のインスタンスがビューごとに作成されます)。Highlighter には状態があるため、各 View は独自の Decorator インスタンスを使用する必要があります。

なぜそのような振る舞いがあるのか​​ コメントはありますか?それを修正する方法はありますか?

更新: DJ から「コンバーターの複数のインスタンスが必要な理由」と尋ねられたので、そのタスクについて説明します。

アプリケーション内に同じビューのインスタンスがいくつかあります。各ビューには、ListView から要素を除外するための独自のテキスト フィルターが含まれています。入力としてフィルター テキストと文字列 (この場合は ListView 要素のタイトル) を持ち、タイトルのどの部分がフィルター テキストと一致するかという情報を返す ViewModel 側の Highlighter があります。Decorator convert には、Highlighter から入力として返されたタイトルと情報があり、RichText が出力として返されます。

WPF が提供する形式の ValueConverter は、問題にはあまり適していないことに同意します。しかし、ビュー側でそれを行うための他のエレガントな方法は見当たりません。

エドワード

4

1 に答える 1

0

コンバーターのリソースを宣言する場所に x:Shared=False を配置します。すべての呼び出しで、新しいオブジェクトが提供されます。

<GUI:Decorator x:Shared=False x:Key="Decorator" **Highlighter="{Binding Highlighter}"** /> 
于 2012-09-17T09:10:47.270 に答える