none
PasswordBox的“水印”功能实现方法 RRS feed

  • 问题

  • 我做一个密码框,要求没有内容时,显示“密码”,当输入密码之后,不要再显示“密码”,代码如下

                        <Grid Width="240" Name="PasswordGrid" VerticalAlignment="Top" Margin="16,142,16,0">
                            <Border CornerRadius="2" BorderThickness="1" BorderBrush="#ccc" Height="26">
                                <PasswordBox VerticalContentAlignment="Center" BorderThickness="0" Name="PasswordTextBox" Padding="4 0 0 0"></PasswordBox>
                            </Border>
                            <TextBlock IsHitTestVisible="False" Text="密码" VerticalAlignment="Center" Margin="6,0,0,0" Foreground="DarkGray">
                                <TextBlock.Style>
                                    <Style TargetType="{x:Type TextBlock}">
                                        <Setter Property="Visibility" Value="Collapsed"/>
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Password, ElementName=PasswordTextBox}" Value="">
                                                <Setter Property="Visibility" Value="Visible"/>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </TextBlock.Style>
                            </TextBlock>
                        </Grid>
    

    相同的代码如果是TextBox就完全OK,换成PasswordBox之后,不知道为何输入密码的时候,里面的那个TextBlock不会隐藏。

    想来想去搞不明白,求指点。。。


    da jia hao!

    2017年9月11日 8:23

全部回复

  • Hi,

    >> 相同的代码如果是TextBox就完全OK,换成PasswordBox之后,不知道为何输入密码的时候,里面的那个TextBlock不会隐藏。

    原因在于Password不是依赖属性,所以数据触发器将不起作用。

    你可以尝试下面的代码:

      public class PlaceHolderHelper : DependencyObject
        {
            #region PlaceHolderText
            public static bool GetPlaceHolderText(DependencyObject obj)
            {
                return (bool)obj.GetValue(PlaceHolderTextProperty);
            }
            public static void SetPlaceHolderText(DependencyObject obj, string value)
            {
                obj.SetValue(PlaceHolderTextProperty, value);
            }
            public static readonly DependencyProperty PlaceHolderTextProperty =
                DependencyProperty.RegisterAttached("PlaceHolderText", typeof(string),
                    typeof(PlaceHolderHelper),
                    new UIPropertyMetadata(string.Empty, PlaceHolderTextChanged));
            private static void PlaceHolderTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                if (!(d is PasswordBox)) return;
                ((PasswordBox)d).PasswordChanged +=
                    (sender, args) =>
                    {
                        var pb = sender as PasswordBox;
                        pb.SetValue(HasPasswordProperty, (pb.Password.Length > 0));
                    };
            }
            #endregion
            #region HasPassword
            public bool HasPassword
            {
                get { return (bool)GetValue(HasPasswordProperty); }
                set { SetValue(HasPasswordProperty, value); }
            }
            private static readonly DependencyProperty HasPasswordProperty =
                DependencyProperty.RegisterAttached("HasPassword",
                    typeof(bool), typeof(PlaceHolderHelper),
                    new FrameworkPropertyMetadata(false));
            #endregion
        }
     <Window.Resources>   
            <Style TargetType="{x:Type PasswordBox}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type PasswordBox}">
                            <Border Name="MainBorder" 
                                    Background="{TemplateBinding Background}"
                                    BorderBrush="{TemplateBinding BorderBrush}"
                                    BorderThickness="{TemplateBinding BorderThickness}">
                                <Grid>
                                    <ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" Margin="1" />
                                    <TextBlock x:Name="PlaceHolder"
                                               Text="{TemplateBinding local:PlaceHolderHelper.PlaceHolderText}"
                                               Foreground="LightGray" 
                                               IsHitTestVisible="False"
                                               HorizontalAlignment="Left" 
                                               VerticalAlignment="Center" 
                                               Margin="4,0,0,0"/>
                                </Grid>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="local:PlaceHolderHelper.HasPassword" Value="True">
                                    <Setter TargetName="PlaceHolder" Property="Opacity" Value="0" />
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Window.Resources>
        <Grid>
          <PasswordBox Width="140" Height="24" local:PlaceHolderHelper.PlaceHolderText="密码:"  Margin="5"/>
        </Grid>

    Watermark in PasswordBox 中提到的方法您也可以参考;

    Best Regards,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.



    2017年9月11日 8:50
    版主