前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WPF-实现TextBox和PasswordBox显示背景文字

WPF-实现TextBox和PasswordBox显示背景文字

作者头像
MaybeHC
发布2024-04-23 19:18:09
950
发布2024-04-23 19:18:09
举报
文章被收录于专栏:技术之路技术之路

TextBox实现

完成下面的效果

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
 <TextBox Name="userId" CaretBrush="White"  Foreground="#ffffff" FontSize="16" BorderBrush="Transparent" BorderThickness="0">
                    <TextBox.Resources>
                        <VisualBrush x:Key="HelpBrush" TileMode="None" Stretch="None" AlignmentX="Left">
                            <VisualBrush.Visual>
                                <Border Background="Black">
                                    <TextBlock  Opacity="0.4" Background="Transparent" FontSize="16"  Foreground="White" Text="请输入用户名"/>
                                </Border>
                            </VisualBrush.Visual>
                        </VisualBrush>
                    </TextBox.Resources>
                    <TextBox.Style>
                        <Style TargetType="TextBox">
                            <Setter Property="Background" Value="Transparent"></Setter>
                            <Style.Triggers>
                                <Trigger Property="Text" Value="{x:Null}">
                                    <Setter Property="Background" Value="{StaticResource HelpBrush}"/>
                                </Trigger>
                                <Trigger Property="Text" Value="">
                                    <Setter Property="Background" Value="{StaticResource HelpBrush}"/>
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </TextBox.Style>
</TextBox>

TextBox的代码实现很简单,就是通过画刷用TextBlock作背景,将TextBox背景设置为画刷构成的背景。 遇到的问题!!! 在TextBox 的代码中不能直接给Background赋值,如下面的代码。在这里赋值后,通过Style将不能修改背景,因为如下的赋值方法的优秀级较高,Style中将无法修改。建议将正常输入时的背景色设置在Style中,这样就可以避免因为优先级无法呈现效果。上面给出的代码已经将背景这只在Style中

代码语言:javascript
复制
<TextBox Background="Black"></TextBox >

PasswordBox实现

PasswordBoxHelper.cs

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;

namespace WpfApplication1
{
    public class PasswordBoxHelper
    {
        static bool isInistialised = false;

        public static string GetWatermark(DependencyObject obj)
        {
            return (string)obj.GetValue(WatermarkProperty);
        }

        public static void SetWatermark(DependencyObject obj, string value)
        {
            obj.SetValue(WatermarkProperty, value);
        }

        public static readonly DependencyProperty WatermarkProperty =
            DependencyProperty.RegisterAttached("Watermark", typeof(string), typeof(PasswordBoxHelper), new UIPropertyMetadata(null, WatermarkChanged));



        public static bool GetShowWatermark(DependencyObject obj)
        {
            return (bool)obj.GetValue(ShowWatermarkProperty);
        }

        public static void SetShowWatermark(DependencyObject obj, bool value)
        {
            obj.SetValue(ShowWatermarkProperty, value);
        }

        public static readonly DependencyProperty ShowWatermarkProperty =
            DependencyProperty.RegisterAttached("ShowWatermark", typeof(bool), typeof(PasswordBoxHelper), new UIPropertyMetadata(false));



        static void WatermarkChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var pwd = obj as PasswordBox;

            CheckShowWatermark(pwd);

            if (!isInistialised)
            {
                pwd.PasswordChanged += new RoutedEventHandler(pwd_PasswordChanged);
                pwd.Unloaded += new RoutedEventHandler(pwd_Unloaded);
                isInistialised = true;
            }
        }

        private static void CheckShowWatermark(PasswordBox pwd)
        {
            pwd.SetValue(PasswordBoxHelper.ShowWatermarkProperty, pwd.Password == string.Empty);
        }

        static void pwd_PasswordChanged(object sender, RoutedEventArgs e)
        {
            var pwd = sender as PasswordBox;
            CheckShowWatermark(pwd);
        }

        static void pwd_Unloaded(object sender, RoutedEventArgs e)
        {
            var pwd = sender as PasswordBox;
            pwd.PasswordChanged -= new RoutedEventHandler(pwd_PasswordChanged);
        }

    }
}

App.xaml

代码语言:javascript
复制
<Application x:Class="WpfApplication1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApplication1"
             xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
             StartupUri="Login.xaml">
    <Application.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
        <ControlTemplate x:Key="WatermarkedPasswordBoxTemplate" TargetType="{x:Type PasswordBox}">
            <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true">
                <Grid>
                    <TextBlock Margin="0 4.5 0 0" Background="Transparent" Text="{Binding Path=(local:PasswordBoxHelper.Watermark), RelativeSource={RelativeSource TemplatedParent}}" VerticalAlignment="Center" Foreground="White" Opacity="0.35" FontSize="16"  Visibility="{Binding (local:PasswordBoxHelper.ShowWatermark), Converter={StaticResource BooleanToVisibilityConverter}, RelativeSource={RelativeSource TemplatedParent}}" />
                    <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Grid>
            </Microsoft_Windows_Themes:ListBoxChrome>
            <ControlTemplate.Triggers>
                <Trigger Property="IsEnabled" Value="false">
                    <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Application.Resources>
    
</Application>

需要导入的命名空间

在这里插入图片描述
在这里插入图片描述

最后一步 xaml中使用

代码语言:javascript
复制
 <PasswordBox Template="{StaticResource   WatermarkedPasswordBoxTemplate}" local:PasswordBoxHelper.Watermark="请输入密码" />

PasswordBox的实现流程较复杂一些 ,大家按如上步骤便可以实现效果

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-04-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • TextBox实现
  • PasswordBox实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com