首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >附加属性与DynamicResource

附加属性与DynamicResource
EN

Stack Overflow用户
提问于 2013-09-09 11:27:19
回答 1查看 431关注 0票数 1

我正在尝试在附加属性的内容上设置一个DynamicResource,但这是行不通的。想弄明白为什么,但我搞不懂。

基本上,我正在使用John提供的代码:Watermark / hint text / placeholder TextBox in WPF在文本框上实现一个水印,并按如下方式使用:

代码语言:javascript
复制
<TextBox Text="{Binding SomeProperty}">
     <helper:WatermarkService.Watermark>
          <TextBlock FontStyle="Italic" Text="{DynamicResource SomeResource}" />
     </helper:WatermarkService.Watermark>
</TextBox>

如果内部TextBlock位于WatermarkService.Watermark附加属性之外,它就可以正常工作。由于某种原因,SomeResource是空的。

我的资源被加载为so this.Resources.MergedDictionaries.Add(lastDictionary);,因为应用程序是本地化的,数据是从一个中心位置检索的。

附加属性上的控件是否与其“父级”共享相同的资源?这里怎么了?谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-09 12:04:43

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

您可以通过将它添加到正确的逻辑树中来解决这个问题,例如,它可能是textbox的子节点。它并不是那么简单,也取决于所需的用法,因为对逻辑树的定制并不是那么简单。

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

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

代码语言:javascript
复制
public class WaterTextBox : TextBox
{        
    protected override IEnumerator LogicalChildren
    {
        get
        {
            ArrayList list = new ArrayList();
            list.Add(WatermarkService.GetWatermark(this));
            return (IEnumerator)list.GetEnumerator();
        }
    }
}

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

而且,它不是正确的实现,因为您应该将水印添加到其他逻辑子逻辑中,而不是忽略其他逻辑子节点,并且只有水印,而水印甚至没有像下面这样检查空值:

代码语言:javascript
复制
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扩展功能,但对于任何控件来说,它都不是可扩展的解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18697209

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档