我有一个需要外部有状态模块才能工作的 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 实例将实体转换为 RichText(而实际上创建了几个 Decorator 实例 - 一个按视图)。Highlighter 有一个状态,这就是为什么每个 View 都必须使用自己的 Decorator 实例的原因。
任何评论为什么会有这种行为?任何想法如何解决它?
更新: DJ 问我“为什么需要多个转换器实例”,所以我将描述该任务。
应用程序中有多个相同视图的实例。每个视图都包含自己的文本过滤器,用于从 ListView 中过滤掉元素。ViewModel 端有一个 Highlighter,它有一个过滤器文本和字符串(在我们的例子中是 ListView 元素标题)作为输入,并返回标题的哪些部分与过滤器文本匹配的信息。Decorator converts 具有从 Highlighter 返回的标题和信息作为输入,RichText 作为输出。
我同意 WPF 提供的表单中的 ValueConverter 不是很适合这个问题。但我在 View 方面看不到任何其他优雅的方式。
爱德华