外部ステートフル モジュールが動作する必要がある 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 は、問題にはあまり適していないことに同意します。しかし、ビュー側でそれを行うための他のエレガントな方法は見当たりません。
エドワード