1

我正在尝试在附加属性的内容上设置 DynamicResource 但这不起作用。试图理解为什么,但我无法弄清楚。

基本上,我正在使用以下代码在文本框上实现水印: John Myczek 提供的WPF 中的 Watermark / hint text / placeholder TextBox并使用它:

<TextBox Text="{Binding SomeProperty}">
     <helper:WatermarkService.Watermark>
          <TextBlock FontStyle="Italic" Text="{DynamicResource SomeResource}" />
     </helper:WatermarkService.Watermark>
</TextBox>

如果内部在附加属性之外,则内部TextBlock工作正常。出于某种原因是空的WatermarkService.WatermarkSomeResource

this.Resources.MergedDictionaries.Add(lastDictionary);由于应用程序已本地化并且正在从中心位置检索数据,因此我的资源正在加载。

附加属性上的控件是否与其“父级”共享相同的资源集?这里有什么问题?谢谢

4

1 回答 1

1

问题很清楚。通过向上解析逻辑树来解析动态资源。找不到动态资源,因为您的文本块不在正确的逻辑树中,可能他没有逻辑父级,这就是找不到资源的原因。

您可以通过将其添加到正确的逻辑树来解决它,例如它可能是文本框的子级。它不是那么微不足道,并且还取决于所需的用法,因为逻辑树的定制并不是那么微不足道。

没有像拥有一个公共方法 AddLogicalChild 这样简单,因为那样你会搞砸整个系统。现在的问题是谁有责任这样做。一般的解决方案可能是有一个自定义 TextBox 覆盖逻辑子相关方法并返回水印文本块。

这不是全局解决方案,但在您的情况下,您可以有一个自定义文本框来覆盖 LogicalChildren 属性,如下所示:

public class WaterTextBox : TextBox
{        
    protected override IEnumerator LogicalChildren
    {
        get
        {
            ArrayList list = new ArrayList();
            list.Add(WatermarkService.GetWatermark(this));
            return (IEnumerator)list.GetEnumerator();
        }
    }
}

请记住,这只是一种解决方法,这种方法仅适用于具有动态资源的自定义文本框。

这也不是正确的实现,因为您应该将水印添加到其他逻辑子代,而不是忽略其他逻辑子代,并且只有水印甚至没有像这样检查 null:

public class WaterTextBox : TextBox
{        
    protected override IEnumerator LogicalChildren
    {
        get
        {
            ArrayList list = new ArrayList();
            IEnumerator enumerator = base.LogicalChildren;
            while (enumerator.MoveNext())
            {
                list.Add(enumerator.Current);
            }
            object watermark = WatermarkService.GetWatermark(this);
            if (watermark != null && !list.Contains(watermark))
            {
                list.Add(WatermarkService.GetWatermark(this));
            }
            return (IEnumerator)list.GetEnumerator();
        }
    }
}

为了使其更通用,您应该定义一个类似 IWatermark 的接口,定义一个类似 IsWaterMarkAdded 的属性,该属性将由您的自定义 TextBox 和 ComboBox 实现,并将由水印服务使用。LogicalChildren 覆盖将检查此属性的值。这样,您可以扩展 TextBox 和 ComboBox 的功能,但它仍然不是任何控件的可扩展解决方案。

于 2013-09-09T12:04:43.097 回答