Search code examples
c#wpfxamlpasswordbox

Styling a WPF Passwordbox


I'm currently trying to do the following: If no password is entered a text "Password" should be shown.

But with my template no password is shown, and if i'm using a decorator or a scrollviewer i can't change the color of the text.

Do you have any ideas to achieve this?

Here's my styling code:

<Style TargetType="{x:Type PasswordBox}" x:Key="Password">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="PasswordBox">
                    <Grid>
                        <PasswordBox Background="{StaticResource BrushDark}" Foreground="{StaticResource BrushTextNormal}" BorderBrush="{StaticResource BrushBorderInput}" BorderThickness="1"/>
                        <TextBlock HorizontalAlignment="Left"
                            VerticalAlignment="Center"
                            Text="Password"
                            Margin="5,0,5,0"
                            Foreground="#ff808080"
                            IsHitTestVisible="False"
                            x:Name="UserMessage"
                            Visibility="Hidden"/>
                        <!--<ScrollViewer Foreground="{StaticResource BrushTextNormal}" Background="{StaticResource BrushTextNormal}" x:Name="PART_ContentHost"/>-->
                        <!--<Decorator TextBlock.Foreground="White" x:Name="PART_ContentHost"/>-->
                    </Grid>
                    <ControlTemplate.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="Tag" Value=""/>
                                <Condition Property="IsKeyboardFocusWithin" Value="False"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="Visibility" TargetName="UserMessage" Value="Visible"/>
                        </MultiTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Solution

  • If you create custom ControlTemplate for PasswordBox or TextBox you need to put ScrollViewer named x:Name="PART_ContentHost instead of inner PasswordBox

    From PasswordBox Syles and Templates

    PART_ContentHost - A visual element that can contain a FrameworkElement. The text of the PasswordBox is displayed in this element.

    And change Foreground as another Setter in you Style. Also, as a side node, I would do the same with Background and use TemplateBinding in your ControlTemplate. This will give more flexibility and allow you to change Background and/or Foreground manually without changing ControlTemplate

    <Style TargetType="{x:Type PasswordBox}" x:Key="Password">
       <Setter Property="Foreground" Value="{StaticResource BrushTextNormal}" />
       <Setter Property="Background" Value="{StaticResource BrushDark}"/>
       <Setter Property="Template">
          <Setter.Value>
             <ControlTemplate TargetType="{x:Type PasswordBox}">
                <Grid Background="{TemplateBinding Background}">
                   <ScrollViewer x:Name="PART_ContentHost" .../>
                   <TextBlock .../>               
                </Grid>
                <ControlTemplate.Triggers>
                   <!-- removed -->
                </ControlTemplate.Triggers>
             </ControlTemplate>
          </Setter.Value>
       </Setter>
    </Style>