首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >来自Watermark TextBox的WPF水印PasswordBox

来自Watermark TextBox的WPF水印PasswordBox
EN

Stack Overflow用户
提问于 2009-10-22 21:08:44
回答 4查看 28.7K关注 0票数 6

我使用的是Watermark TextBox in WPF中的水印文本框

代码语言:javascript
复制
 <Grid Grid.Row="0" Background="{StaticResource brushWatermarkBackground}" Style="{StaticResource EntryFieldStyle}" >
        <TextBlock Margin="5,2" Text="This prompt dissappears as you type..." Foreground="{StaticResource brushWatermarkForeground}"
                   Visibility="{Binding ElementName=txtUserEntry, Path=Text.IsEmpty, Converter={StaticResource BooleanToVisibilityConverter}}" />
        <TextBox Name="txtUserEntry" Background="Transparent" BorderBrush="{StaticResource brushWatermarkBorder}" />
    </Grid>

如何将此应用于PasswordBox?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-10-23 08:16:59

一般的方法是相同的:编写一个自定义控件样式,并在密码框为空时显示水印。这里唯一的问题是PasswordBox.Password不是依赖属性,您不能在触发器中使用它。此外,PasswordBox是密封的,因此您不能覆盖此通知行为,但您可以在此处使用附加属性。

下面的代码演示了如何实现。

XAML:

代码语言:javascript
复制
<Window x:Class="WpfTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:WpfTest="clr-namespace:WpfTest"
    Title="Password Box Sample" Height="300" Width="300">
  <Window.Resources>
    <Style x:Key="{x:Type PasswordBox}"
        TargetType="{x:Type PasswordBox}">
      <Setter Property="WpfTest:PasswordBoxMonitor.IsMonitoring"
              Value="True"/>
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type PasswordBox}">
            <Border Name="Bd"
                    Background="{TemplateBinding Background}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    SnapsToDevicePixels="true">
              <Grid>
                <ScrollViewer x:Name="PART_ContentHost"
                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                <TextBlock Text="Please enter your password" 
                           Margin="4, 2, 0, 0"
                           Foreground="Gray" 
                           Visibility="Collapsed"
                           Name="txtPrompt" />
              </Grid>
            </Border>
            <ControlTemplate.Triggers>
              <Trigger Property="IsEnabled"
                                         Value="false">
                <Setter TargetName="Bd"
                                            Property="Background"
                                            Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                <Setter Property="Foreground"
                                            Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
              </Trigger>
              <Trigger Property="WpfTest:PasswordBoxMonitor.PasswordLength" Value="0">
                <Setter Property="Visibility" TargetName="txtPrompt" Value="Visible"/>
              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </Window.Resources>
  <Grid>
    <PasswordBox VerticalAlignment="Top"/>
  </Grid>
</Window>

C#:

代码语言:javascript
复制
using System.Windows;
using System.Windows.Controls;

namespace WpfTest {
    public partial class Window1 : Window {
        public Window1() {
            InitializeComponent();
        }
    }

  public class PasswordBoxMonitor : DependencyObject {
    public static bool GetIsMonitoring(DependencyObject obj) {
      return (bool)obj.GetValue(IsMonitoringProperty);
    }

    public static void SetIsMonitoring(DependencyObject obj, bool value) {
      obj.SetValue(IsMonitoringProperty, value);
    }

    public static readonly DependencyProperty IsMonitoringProperty =
        DependencyProperty.RegisterAttached("IsMonitoring", typeof(bool), typeof(PasswordBoxMonitor), new UIPropertyMetadata(false, OnIsMonitoringChanged));

    public static int GetPasswordLength(DependencyObject obj) {
      return (int)obj.GetValue(PasswordLengthProperty);
    }

    public static void SetPasswordLength(DependencyObject obj, int value) {
      obj.SetValue(PasswordLengthProperty, value);
    }

    public static readonly DependencyProperty PasswordLengthProperty =
        DependencyProperty.RegisterAttached("PasswordLength", typeof(int), typeof(PasswordBoxMonitor), new UIPropertyMetadata(0));

    private static void OnIsMonitoringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
      var pb = d as PasswordBox;
      if (pb == null) {
        return;
      }
      if ((bool) e.NewValue) {
        pb.PasswordChanged += PasswordChanged;
      } else {
        pb.PasswordChanged -= PasswordChanged;
      }
    }

    static void PasswordChanged(object sender, RoutedEventArgs e) {
      var pb = sender as PasswordBox;
      if (pb == null) {
        return;
      }
      SetPasswordLength(pb, pb.Password.Length);
    }
  }
}

请注意XAML代码中的PasswordBoxMonitor

票数 19
EN

Stack Overflow用户

发布于 2011-03-18 02:11:26

您可以自行显示/隐藏背景,而不使用触发器:

XAML:

代码语言:javascript
复制
<PasswordBox x:Name="passwordBox" PasswordChanged="passwordChanged" 
        Background="{StaticResource PasswordHint}" />

代码隐藏:

代码语言:javascript
复制
// helper to hide watermark hint in password field
private void passwordChanged(object sender, RoutedEventArgs e)
{           
    if (passwordBox.Password.Length == 0)
        passwordBox.Background.Opacity = 1;
    else
        passwordBox.Background.Opacity = 0;
}
票数 9
EN

Stack Overflow用户

发布于 2010-07-16 21:37:27

您可以使用我的方法来处理水印行为。您所要做的就是复制并粘贴TextBoxWatermarkBehavior,然后将Behavior<TextBox>更改为Behavior<PasswordBox>

你可以找到一个演示项目here

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1607066

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档