Silverlight - 将 ValueConverter 添加到自定义控件中的 Binding 对象

发布于 2024-10-18 21:06:31 字数 981 浏览 1 评论 0原文

我正在 Silverlight 中构建自定义控件,扩展 TextBox。该控件的目的是提供水印逻辑(默认文本,通常在搜索框中使用)。我设法做到了,当访问 Text 属性时,如果 Text == Watermark 它将返回 string.Empty。事实上,您不想将“在此处输入名称”之类的内容视为相关值。当涉及到 TwoWay 数据绑定时,事情会变得更加复杂。

我创建了一个 ValueConverter,它将水印作为参数并返回 string.Empty 如果 Text == Watermark,否则返回 Text。我希望该控件非常易于使用,因此如果客户端代码在绑定到 Text 属性时不必每次都指定该转换器,那就太好了。相反,转换器将插入自定义控件内部、与 Text 属性相关的绑定对象上。

我尝试了以下代码,但它崩溃了,因为绑定对象一旦分配就无法修改。我在 Load() 和 OnApplyTemplate() 事件中尝试了该代码。

var watermarkedTextBox = (WatermarkedTextBox)dependencyObject;
var textBindingExpression = watermarkedTextBox.GetBindingExpression(TextProperty);
if (textBindingExpression != null)
{
    var textBinding = textBindingExpression.ParentBinding;
    textBinding.Converter = new WatermarkConverter();
    textBinding.ConverterParameter = watermarkedTextBox.Watermark;
    watermarkedTextBox.SetBinding(TextProperty, textBinding);
}

所以我需要在正确的时间拦截绑定对象(仍然允许修改它)。有什么想法吗?

提前致谢,

蒂博

I'm building a custom control in Silverlight, extending TextBox. The purpose of the control is to provide a watermark logic (default text, typically used in search boxes). I managed that, when accessing the Text property, it will return string.Empty if Text == Watermark. Indeed, you don't want to consider something like "Enter name here" as a relevant value. When it comes to TwoWay databinding, things get more complicated.

I created a ValueConverter, that takes as parameter the watermark and returns string.Empty if Text == Watermark, Text otherwise. I want the control to be very ease to use, so it would be cool if the client code wouldn't have to specify each time that converter when binding to the Text property. Instead, the converter would be plugged inside the custom control, on the binding object related to the Text property.

I tried the following code, but it crashes because the binding object cannot be modified once it has been assigned. I tried that code in the Load() and OnApplyTemplate() events.

var watermarkedTextBox = (WatermarkedTextBox)dependencyObject;
var textBindingExpression = watermarkedTextBox.GetBindingExpression(TextProperty);
if (textBindingExpression != null)
{
    var textBinding = textBindingExpression.ParentBinding;
    textBinding.Converter = new WatermarkConverter();
    textBinding.ConverterParameter = watermarkedTextBox.Watermark;
    watermarkedTextBox.SetBinding(TextProperty, textBinding);
}

So I need to intercept the binding object at the right time (where it's still allowed to modify it). Any ideas ?

Thanks in advance,

Thibaut

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

乞讨 2024-10-25 21:06:31

好吧,和同事讨论了一下,找到了最优的解决方案。

水印在自定义控件的 ControlTemplate 中定义。它是添加在 TextBox 中的 TextBlock,在焦点上隐藏,如果文本为空则显示。代码要好得多:

  • 不需要使用 Text 属性并在某些条件下更改它以将其更改为水印,或将其更改为 string.Empty,因此永远不会返回水印文本(容易出错)
  • 水印文本样式可以直接模板绑定(TemplateBinding),所以这很棒,无需任何 C# 代码,客户端将能够自定义水印的外观:颜色、斜体等
  • 提供新的可能性(图像水印文本框几乎免费)

再见;)

All right, discussed this with colleagues, found the optimal solution.

The watermark is defined in the ControlTemplate of the custom control. It's a TextBlock added in the TextBox, hidden on focus, shown if text is empty. Code is much better like that :

  • No need to play with the Text property and change it under certain conditions to change it to watermark, or change it to string.Empty so the watermark text is never returned (was error prone)
  • Watermark text style can be directly template bound (TemplateBinding), so it's great, without any C# code, client will be able to customize the appearance of the watermark : color, italicize and more
  • Offers new possibilities (image watermark textbox almost for free)

See you ;)

留蓝 2024-10-25 21:06:31

我还没有尝试过,但 Silverlight 4 文本框有一个水印属性。

I haven't tried it yet but the Silverlight 4 Textbox has a Watermark property.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文