Проблема понятна. Динамические ресурсы решаются путем разбора логического дерева. Динамический ресурс не найден, потому что ваш текстовый блок не находится в правильном логическом дереве, возможно, у него нет логического родителя, поэтому ресурс не найден.
Вы можете решить эту проблему, добавив ее в правильное логическое дерево, например, это может быть дочерний элемент текстового поля. Это не так тривиально и зависит также от использования, которое требуется, потому что настройка логического дерева не такая тривиальная.
Не так просто, как иметь общедоступный метод 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();
}
}
}
Помните, что это только временное решение, и таким образом будет работать только на пользовательском текстовых с динамическими ресурсами.
Также не правильное выполнение, потому что вы должны добавить водяные знаки на другие логические ребенок, не обращать внимания на другие логические ребенок и имеете только водяной знак, который даже не проверяется на нуль, как это:
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 и будет использоваться службой водяных знаков. Контролирует значение этого свойства. Таким образом, вы можете расширить функциональность для вашего TextBox и ComboBox, но все же это не расширяемое решение для любого элемента управления.
Из вашего описания это звучит скорее как проблема с кодом 'Watermark' ... вы можете это показать? – Sheridan
Thx. Как сказано в сообщении, код доступен по адресу http://stackoverflow.com/questions/833943/watermark-hint-text-textbox-in-wpf в сообщении John Myczek – saamorim