You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF TextBox水印问题:初始化赋值与输入时水印未自动隐藏

WPF TextBox水印问题解决

问题描述

  1. 构造函数中设置searchBox.Text = "aaa"后,运行时文本不显示,水印仍存在
  2. 用户输入内容时,输入文本与水印“Hello World”同时显示

核心原因

  • 自定义ControlTemplate中的水印TextBlock固定显示,未根据TextBox的Text内容动态控制可见性
  • TextBox的Text属性绑定了SearchText,直接设置控件的Text会被绑定逻辑覆盖,导致赋值无效

解决方案

1. 修改XAML:动态控制水印可见性

在ControlTemplate中添加触发器,默认隐藏水印,仅当TextBox的Text为空或null时显示水印:

<!-- 在Window/UserControl根元素添加系统命名空间(用于空字符串判断) -->
xmlns:sys="clr-namespace:System;assembly=mscorlib"

<!-- 修改后的TextBox完整XAML -->
<TextBox x:Name="searchBox" HorizontalAlignment="Center" VerticalAlignment="Top" Width="1100" Height="30" Margin="10,70,0,0" FontSize="16" TextChanged="searchBox_TextChanged">
    <TextBox.Style>
        <Style TargetType="TextBox">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="MaxLength" Value="50" />
            <Setter Property="Foreground" Value="DarkGray" />
            <Style.Triggers>
                <Trigger Property="IsFocused" Value="True">
                    <Setter Property="Foreground" Value="Black" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
    <TextBox.Text>
        <Binding Path="SearchText" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"/>
    </TextBox.Text>
    <TextBox.Template>
        <ControlTemplate TargetType="TextBox">
            <Grid>
                <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"/>
                <!-- 默认隐藏水印 -->
                <TextBlock x:Name="Watermark" Text="Hello World" Foreground="LightGray" Margin="5,0,0,0" Visibility="Collapsed"/>
                <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
            </Grid>
            <ControlTemplate.Triggers>
                <!-- 当Text为空或null时显示水印 -->
                <Trigger Property="Text" Value="">
                    <Setter TargetName="Watermark" Property="Visibility" Value="Visible"/>
                </Trigger>
                <Trigger Property="Text" Value="{x:Null}">
                    <Setter TargetName="Watermark" Property="Visibility" Value="Visible"/>
                </Trigger>
                <Trigger Property="Text" Value="{x:Static sys:String.Empty}">
                    <Setter TargetName="Watermark" Property="Visibility" Value="Visible"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </TextBox.Template>
</TextBox>

2. 修改C#代码:通过绑定属性赋值

由于TextBox的Text已绑定到SearchText,需通过绑定属性赋值而非直接操作控件,同时实现INotifyPropertyChanged确保UI更新:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Collections.Generic;
using System.Linq;

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private string _searchText;
    public string SearchText
    {
        get => _searchText;
        set
        {
            _searchText = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    // 示例:假设已定义的进程字典
    private Dictionary<int, ProcessInfo> processDictionary = new Dictionary<int, ProcessInfo>();

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this; // 设置数据上下文关联绑定属性
        SearchText = "aaa"; // 通过绑定属性赋值,确保UI同步
    }

    private void searchBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        string searchText = searchBox.Text.ToLower();
        var filteredProcesses = processDictionary.Values.Where(p => p.Name.ToLower().Contains(searchText)).ToList();
        lstvw.ItemsSource = filteredProcesses;
    }
}

// 示例:自定义进程信息实体类
public class ProcessInfo
{
    public string Name { get; set; }
}

效果验证

  • 构造函数赋值SearchText = "aaa"后,TextBox显示"aaa",水印自动隐藏
  • 用户输入内容时,水印立即隐藏,仅显示输入文本
  • 清空文本后,水印重新显示

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 20:05:54