ValueConverter的行为类似于singleton



我有一个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有一个状态,这就是为什么每个视图都必须使用自己的Decorator实例。

有什么评论为什么会有这样的行为吗?有什么办法吗?

更新:D J问我"为什么需要多个转换器实例",所以我将描述这项任务。

应用程序中存在多个相同视图的实例。每个视图都包含自己的文本过滤器,用于过滤ListView中的元素。ViewModel端有一个Highlighter,它有一个过滤器文本和字符串(在我们的例子中是ListView元素标题)作为输入,并返回标题的哪些部分与过滤器文本匹配的信息。Decorator converters有一个标题和从Highlighter返回的信息作为输入,RichText作为输出。

我同意WPF提供的形式的ValueConverter不太适合这个问题。但在View方面,我看不到任何其他优雅的方式。

爱德华·

Put x:Shared=False,用于声明转换器的资源。每次通话时,它都会给你新的对象。

<GUI:Decorator x:Shared=False x:Key="Decorator" **Highlighter="{Binding Highlighter}"** /> 

最新更新