Brent Stewart

Software, Invention, Art

Add PlaceHolder text to a PasswordBox

February 18
February 18, 2013 14:07 Posted in Tips 'n Tricks

Place holder text is UI candy that makes your app feel more polished and helps users better understand what needs to be entered into fields.  I had wanted to add place holder text to my WPF app’s login screen for quite a while, but never seem to find the time.

So today I decided to figure out what needed to be done to make this happen. After some searching and reading, I discovered that there are quite a few examples on how to add PlaceHolder text to TextBox controls, but that adding PlaceHolder text to PasswordBox controls is a little more difficult.  Most  of the examples of adding PlaceHolder text to TextBox controls relied on control triggers that checked the Text property to determine the visibility of the place holder text.  The problem with using this technique on a PasswordBox control is that the PasswordBox does not expose a dependency property for the password value, so there is no simple way to wire a trigger up to the value of a PasswordBox.  After some head scratching and a little more research, I decided that using an Attached Property would allow me to accomplish what I wanted.  First, I created a PlaceHolderHelper class that contains an Attached Property PlaceHolderText and a Dependency Property, HasPassword

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
}

This let me bind up a listener to the PasswordChanged event of the PasswordBox so I could track whether a password had been entered or not.  It also gave me the needed Dependency Property to use in my Control Trigger.  Next, I needed to create a Style that overlaid my place holder text over the PasswordBox.

<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 ctrls:PlaceHolderHelper.PlaceHolderText}" 
                                Foreground="LightGray" IsHitTestVisible="False" 
                                HorizontalAlignment="Left" VerticalAlignment="Center" Margin="4,0,0,0"/>
                    </Grid>
                </Border>                        
                <ControlTemplate.Triggers>
                    <Trigger Property="ctrls:PlaceHolderHelper.HasPassword" Value="True">
                        <Setter TargetName="PlaceHolder" Property="Opacity" Value="0" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

This is a very simplified style, but I wanted to boil this all down to the simplest example I could so you could see how this technique works.  Now all I had to do was declare a PasswordBox and set the PlaceHolderText.

<StackPanel VerticalAlignment="Top" Orientation="Horizontal" Margin="5">
  <PasswordBox Width="120" Height="24" ctrls:PlaceHolderHelper.PlaceHolderText="Enter your password" />
  <PasswordBox Width="140" Height="24" ctrls:PlaceHolderHelper.PlaceHolderText="Enter your secret phrase"  Margin="5"/>
  <Button Content="Submit" Width="50" Height="24" />
</StackPanel>
Here are the results, first with no text entered

 PlaceHolder Sample

and finally when entering text

PlaceHolder Sample #2

Tags: ,

Teaching my daughter to type

February 09
February 9, 2013 11:21 Posted in Misc

My 10 year old daughter loves to write and is a creative and imaginative story teller.  I want her to be able to share her stories with others and luckily we live in a time and age where that is a simple matter.  Her typing skills are the main thing that is keeping her from being able to share her stories, so I have decided that I would try to teach her to type.  I have found that there are quite a few free websites dedicated to learning to type and they seem to wok well.  The only issue that I have found is that most of the sites use Flash for the training, so learning on my Surface RT is out.  I guess it is time to either find a good typing program for Windows RT, or maybe this is an opportunity for making an app.  Let me know if you have any suggestions for good typing programs for kids.

Tags:

Surface Pro…Does it pass the WAF?

February 04
February 4, 2013 10:48 Posted in Toys

I stopped by the local Microsoft store today at lunch and tried out the Surface Pro and I must say that it was quite a nice piece of hardware.  I already have the Surface RT and have been happy with the purchase overall.  My wife on the other hand has been less impressed because she keeps running into things that the Surface either can’t do, or doesn’t do well.  One, she keeps finding websites that don’t play nice with touch screen only interactions, (hover menus, sliders, etc.), and two, she uses sites that need to be able to run flash.  She had all these complaints on her previous iPad, but I was hoping the Surface RT would fix some of this. But alas, there are still too many sites that don’t play nice with tablets.  My wife keeps insisting that a laptop is what she needs because it is a real computer and won’t have the same limitations, and while I agree that it should fix those issues, it feels like a poor fit for someone who mostly consumes information.  So the $64,000 question is, does a Surface Pro tablet fix the issues, or will she still see it as just a tablet?

Tags:

New website!

February 01
February 1, 2013 10:31 Posted in Blog

I finally decided on a domain name and moving everything to the new place.  Stay tuned for updates and check back often to see what I am up to.

Tags:

Use the Snipping Tool to make life easier

January 05
January 5, 2012 14:50 Posted in Tips 'n Tricks

I knew about the Snipping Tool in Windows, but for some reason I never thought much about it until recently when a friend reminded me when he heard all the steps I was going though to get a screen capture.  I was answering a question from StackOverflow, and I was trying to show some XAML output, so here is what I did to capture the output:

  1. Take a screen shot by pressing Alt+Print Screen (captures the active window to the clipboard)
  2. Open a graphics application (Paint.NET or Photoshop)
  3. Paste the clipboard contents into a new document
  4. Crop to the section of the screen I want to capture
  5. Save results to a file
  6. Insert file into my response

The same process using the Snipping Tool in Windows goes like this:

  1. Open Snipping Tool
  2. Select screen area I want to capture (the selection is inserted into the clipboard automatically if that is all you need)
  3. Save results to file
  4. Insert file into my response

Ah, much better.  This may not sound like a lot of savings, but it takes away the feeling of having to work to get what I want.  There is a much better chance of me taking time to grab a capture when I know that it is this simple, and that increases the quality of my communications and gives me a greater chance of being understood.  The next time you need to capture something from your screen, don’t forget the Snipping Tool.

Tags:

About Brent

Brent Stewart is a software developer, inventor, entrepreneur, photographer, comic, father, husband, and a fan of all things geek.