我有一个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实例 - 一个是视图)。 荧光笔有一个状态,这就是每个View必须使用自己的Decorator实例的原因。
为什么会有这样的行为? 任何想法如何解决它?
更新 D J问我“为什么你需要多个转换器实例”所以我将描述这个任务。
应用程序中有多个相同View的实例。每个视图都包含自己的文本过滤器,以过滤掉ListView中的元素。 ViewModel端有一个Highlighter,它有一个过滤器文本和字符串(在我们的例子中是ListView元素标题)作为输入,并返回标题的哪些部分与过滤器文本匹配的信息。 Decorator转换器具有从Highlighter返回的标题和信息作为输入,RichText作为输出。
我同意WPF提供的形式的ValueConverter不太适合这个问题。但我没有看到任何其他优雅的方式在View侧进行。
Ed.ward
答案 0 :(得分:0)
将x:Shared = False放在声明转换器资源的位置。在每一个电话上它都会给你新的对象。
<GUI:Decorator x:Shared=False x:Key="Decorator" **Highlighter="{Binding Highlighter}"** />