'Tag in PasswordBox is not displayed as placeholder

I made a style that shows the tag of the password box as a placeholder by binding it.
However, I used the Attached Property in the style, but the tag does not show as placeholder.

It consists of PasswordBoxProperties.cs, LoginPage.xaml, and Texts.xaml.
I used this code

<Style x:Key="Test1" TargetType="{x:Type PasswordBox}" BasedOn="{StaticResource BaseStyle}" >
    ...
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type PasswordBox}">
                <Grid>
                    <Border x:Name="border" 
                            Background="{TemplateBinding Background}" 
                            BorderBrush="{TemplateBinding BorderBrush}" 
                            BorderThickness="{TemplateBinding BorderThickness}" 
                            SnapsToDevicePixels="True">
                        <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                    </Border>

                    <PasswordBox.Style >
                        
                    </PasswordBox.Style>
                    <TextBlock IsHitTestVisible="False"
                               Text="{TemplateBinding Tag}"
                               x:Name="placeholder"
                               FontFamily="{StaticResource LatoThin}"
                               Padding="{TemplateBinding Padding}"
                               VerticalAlignment="Center"
                               HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                               Foreground="{StaticResource ForegroundVeryDarkBrush}" >

                        <TextBlock.Style>
                            <Style TargetType="{x:Type TextBlock}">
                                <Setter Property="Visibility" Value="Collapsed" />
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding (local:PasswordBoxProperties.HasText), RelativeSource={RelativeSource TemplatedParent}}" Value="False">
                                        <Setter Property="Visibility" Value="Visible" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBlock.Style>
                    </TextBlock>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Set the Texts.xaml about PasswordBox Style

public class PasswordBoxProperties
{
    public static readonly DependencyProperty MonitorPasswordProperty =
       DependencyProperty.RegisterAttached("MonitorPassword",
           typeof(bool),
           typeof(PasswordBoxProperties),
           new PropertyMetadata(false, OnMonitorPasswordChanged));

    private static void OnMonitorPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var passwordBox = (d as PasswordBox);

        if (passwordBox == null) 
            return;

        passwordBox.PasswordChanged -= PasswordBox_PasswordChanged;

        if ((bool)e.NewValue)
        {
            SetHasText(passwordBox);

            passwordBox.PasswordChanged += PasswordBox_PasswordChanged;
        }
    }

    private static void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
    {
        SetHasText((PasswordBox)sender);
    }

    public static void SetMonitorPassword(PasswordBox element, bool value)
    {
        element.SetValue(MonitorPasswordProperty, value);
    }

    public static bool GetMonitorPassword(PasswordBox element)
    {
        return (bool)element.GetValue(MonitorPasswordProperty);
    }



    public static readonly DependencyProperty HasTextProperty = 
        DependencyProperty.RegisterAttached("HasText",
            typeof(bool),
            typeof(PasswordBoxProperties),
            new PropertyMetadata(false));

    private static void SetHasText(PasswordBox element)
    {
        element.SetValue(HasTextProperty, element.SecurePassword.Length > 0);
    }

    public static bool GetHasText(PasswordBox element)
    {
        return (bool)element.GetValue(HasTextProperty);
    }
}

This PasswordBoxProperties.cs about Envent and somthing else

<!-- Email -->
<TextBox Style="{StaticResource TextBoxIDPwd}" Tag="Email" />
<!-- Password -->
<PasswordBox Style="{StaticResource Test1}" Tag="Password" Margin="0 0 0 30"/>

This is LoginPage.xaml


We solved placeholder

<!-- I add this code in Texts.xaml -->
<Setter Property="local:PasswordBoxProperties.MonitorPassword" Value="True" />

<!-- Edit this part -->
<DataTrigger Binding="{Binding (local:PasswordBoxProperties.HasText), RelativeSource={RelativeSource TemplatedParent}}" Value="False">
=>
<DataTrigger Binding="{Binding Path=(local:PasswordBoxProperties.HasText), RelativeSource={RelativeSource TemplatedParent}}" Value="False">

Add "Path="(local:Pass...)

then placeholder working with PasswordBox
Thank you guys



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source