自制水印文本框

本文关键字:文本 | 更新日期: 2023-09-27 18:20:35

我用下面的xaml制作了一个自己的WatermarkTextBox。

<Grid>
    <TextBlock Margin="5 0 5 0"
               VerticalAlignment="Center"
               Foreground="{Binding WatermarkForeground, FallbackValue=#DBDBDB}"
               Text="{Binding Watermark, FallbackValue=This prompt dissappears as you type...}"
               Visibility="{Binding ElementName=txtUserEntry, Path=Text.IsEmpty, Converter={StaticResource BooleanToVisibilityConverter}}" />
    <TextBox Name="txtUserEntry"
             Background="Transparent"
             BorderThickness="0"
             Foreground="{Binding TextForeground, FallbackValue=Black}"
             VerticalAlignment="Center"
             Text="{Binding Text}" />
</Grid>

以下代码是据我所知不需要INotifyPropertyChanged的代码。这些DependencyProperty应该足够了。

public String Watermark
{
    get { return (String)GetValue(WatermarkProperty); }
    set { SetValue(WatermarkProperty, value); }
}
public String Text
{
    get { return (String)GetValue(TextProperty); }
    set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty WatermarkProperty = 
    DependencyProperty.Register("Watermark", typeof(string), 
    typeof(WatermarkTextBox), new PropertyMetadata(""));
public static readonly DependencyProperty TextProperty = 
    DependencyProperty.Register("Text", typeof(string), 
    typeof(WatermarkTextBox), new PropertyMetadata(""));

然后,在我的应用程序中,我这样使用它。

<c:WatermarkTextBox Watermark="[Design] Name *"
                    Text="{Binding Name, FallbackValue='Name'}" />

当我运行应用程序时,我确实看到"[Design]Name*"作为文本块中的水印。现在,在上面的示例中,我将DP Text绑定到ViewModel中的属性Name,如下所示。

public string Name { get; set; }

ViewModel确实实现了INotifyPropertyChanged

public class MainWindowViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

在我的ViewModel中,如果我按下按钮,我会执行以下代码

Name = "Test";

单词Test从不希望出现在WatermarkTextBox中。即使我在运行时在其中键入一些内容并请求属性Name,它仍然会返回null

这会让事情更清楚吗?


我用常规的TextBox测试了结合。在这里,绑定看起来像它应该的那样工作,并且确实显示了它必须做什么。我认为问题在我的WatermarkTextBox内部,但我不知道在哪里。

<TextBox Text="{Binding Name, FallbackValue='Name'}" />

自制水印文本框

问题出现在WatermarkTextBox绑定中。为网格分配一个名称,并将其DataContext设置为UserControl本身,因为您正在绑定到Control 中的属性

        <Grid x:Name="grid">
        <TextBlock Margin="5 0 5 0"

xaml.cs

public partial class WatermarkTextBox  : UserControl
{
    public WatermarkTextBox()
    {
        InitializeComponent();
        grid.DataContext = this;
    }

我希望这会有所帮助。

更新:

        <c:WatermarkTextBox Watermark="[Design] Name *"
                Text="{Binding Name,  Mode=TwoWay, FallbackValue='Name'}" />