Tuesday, March 2, 2010

Watermarked TextBox Part II

In the first post we created the visual elements for our WatermarkedTextbox user control. In this post we are going to add some code, create a few more states, and wire everything up.

Remember that you can grab the finished control from here.

You can view a working sample on the Expression Gallery here.

Before we add any code-behind, we'll create two state groups - one for showing or hiding the watermark, the other for showing or hiding the clear-text button.

Select the States tab and click the Add State Group button. Name the new state group "ClearFilterButtonStates", since this group is going to hold the states for the ClearFilterButton.

Before we add a state for the button, lets set the default appearance of the ClearFilterButton. Since the default text in the TextBox will be an empty string, we don't need to show the ClearFilterButton until there is some text to clear, so set the Opacity of the ClearFilterButton to 0. I want the button to animate as it appears; expanding from a dot until it reaches it's full size. To make the ClearFilterButton start out as a dot, go to the RenderTransform group on the Properties panel, click on the Scale tab and set the X and Y values to 0 as shown here:

Now click the Add State button on the ClearFilterButtonStates line and name the new state "ButtonVisible". Add another state named "ButtonHidden".

Select the "ButtonVisible" state (Blend will show the red border to indicate it is recording property changes for the selected state) and then select the ClearFilterButton. Set it's opacity to 100, and it's X and Y scale render transform values back to 1. We want the button to animate, rather than appear all at once, so let's change the transition time value for the whole ClearFilterButtonStates to 0.3:

Click on the "Turn on transition preview" button in the top right of the States panel, select the [UserControl] element in the Objects tree view and click back and forth between the ButtonVisible state and the ButtonHidden state.

Select the "Base" state group so any changes we make next are not just recorded for a state. The button is a little to close to the edges, so lets give it some room by setting it's Right, Top, and Bottom margin to 3.

Now we will create the states for the watermark in much the same way. Create a new state group called "WatermarkStates" and add two states called "WatermarkVisible" and "WatermarkHidden". We don't need to do anything for the WatermarkVisible state, so just select the WatermarkHidden state, select the WatermarkText control and set it's Opacity to 0. Also, expand the Common Properties group on the Properties panel and turn off "IsHitTestVisible" - we don't want it interfering with the text box interaction.

We want the watermark to disappear straight away when the user clicks in the text box, so we won't set a group level transition time for the Watermark States, but it would be nice to have it fade in when the text box becomes empty. Click the Add transition button on the WatermarkHidden state and select the "WatermarkHidden -> WatermarkVisible" option:

And set the transition time to 0.4:

Now we are ready to add some code to put make the whole control work.

This post has already gone longer than I thought it would, so I'm going to describe the code in Part III.


  1. The implementation is wrong for multiple reasons.

    1)It should be a control (not usercontrol) so it can be fully customizable.The user cant customize the watermark textblock, the clear button etc.
    Can i localize the button tooltip? no
    Can i change the watermark textblock style? no
    It could even be a TextBox.
    A watermark textbox IS a textbox!!
    2)Following the first every part and state should be documented in the class the way every silverlight control is designed.
    3)It should provide events for pretty much everything (textchanged ,watermarkchanged, clear clicked etc) alongside the MVVM ICommand aproach cause not everybody uses the pattern.
    4)The implementation does not respect bindings.
    The text is not bound to the textbox so it wont validate! if an exception is thrown from the source.No templatebindings also for various properties because its not a stylable control!

    All in all bad impl.I suggest u read more about silvelight and most importantly read good silverlight code from the sl toolkit source code.

  2. Anonymous - I have responded to your critique on the first post.