Changing the watermark text in a DatePicker control


Someone recently asked about how to change the watermark text in a DatePicker control. Here’s a picture of the DatePicker control. I’ve drawn an arrow to the watermark text.


watermark


Unfortunately, changing the watermark text is not as easy to do as you might think, and I can only change it the first time it displays. 


The DatePicker control has a template part of type DatePickerTextBox that exposes a Watermark property. You’ll see this part declared in the class overview topic of the DatePicker control:


[TemplatePartAttribute(Name = “TextBox”, Type = typeof(DatePickerTextBox))]


There are multiple ways to tackle this problem, but one of the easiest ways I see to do it is to derive from DatePicker and override OnApplyTemplate. You can then retrieve the TextBox part and set the watermark.



using System.Windows.Controls.Primitives;


 


public class MyDatePicker : DatePicker
  
{
      
public override void OnApplyTemplate()
      
{
          
base.OnApplyTemplate();
          
DatePickerTextBox box = base.GetTemplateChild(“TextBox”) as DatePickerTextBox;
          
box.Watermark = “Type or select a date –> “;
      
}
  
}



If you go this route, keep in mind that the default implementation of the watermark text adjusts depending on the whether the selected date format is long or short. If you override the watermark you might want to take this in consideration as the user will lose an important hint about the expected format of the date.


One way to deal with this is to retrieve the selected date format and use it when you set the watermark.  (I have to point out that this example requires a very wide date picker, which is not ideal, but you get the idea):


 public class MyDatePicker : DatePicker
   
{
       
public override void OnApplyTemplate()
       
{
           
base.OnApplyTemplate();
           
DatePickerTextBox box = base.GetTemplateChild(“TextBox”) as DatePickerTextBox;
           
            
string formatString = “”;
           
if (this.SelectedDateFormat == DatePickerFormat.Short)
               
formatString = “mm/d/yy”;
           
if (this.SelectedDateFormat == DatePickerFormat.Long)
               
formatString = “dddd, MMMM, dd, yyyy”;
           
box.Watermark = “Type ( ” + formatString + “) or select a date –> “;
       
}
   
}

 

 


Here’s how my page XAML looks:

 


<UserControl x:Class=“DatePickerWatermark.MainPage”
   
xmlns=
“http://schemas.microsoft.com/winfx/2006/xaml/presentation”
   
xmlns:x=
“http://schemas.microsoft.com/winfx/2006/xaml”
   
xmlns:d=
“http://schemas.microsoft.com/expression/blend/2008”
   
xmlns:mc=
“http://schemas.openxmlformats.org/markup-compatibility/2006”
            
xmlns:local =
“clr-namespace:DatePickerWatermark”
   
mc:Ignorable=
“d”
   
d:DesignHeight=“300” d:DesignWidth=“400”>


   
<Grid x:Name=“LayoutRoot” Background=“White”>
       
<local:MyDatePicker Width=“240” Height=“40” />
   
</Grid>
</UserControl>

 

 



And here is how it looks how I run it:

watermarkCuston

 I hope this helps.


–Cheryl


Comments (6)

  1. tariolf says:

    Hello Cheryl,

    Your example is of great help but for me it works only half way. When my datebox displays, the custom watermark is displayed perfectly. But when I enter a value and delete it, the standard datepicker watermark is displayed, not the new one!

    Do you have any idea on what is causing this?

    Cheers.

  2. cherylws says:

    Unfortunately, I cannot not figure out a way to persist the watermark setting other than writing your own DatePicker, as this value is set in code, in a private method. I’ll check with the product team and post more info when I get it.

  3. razor24 says:

    Seriously, why on earth can't you change the format of the date in a datepicker control. That would be requirement #1 for any datepicker. SL4 added the stringFormat to the binding and this doesn't work either. How could you hardcode two date formats which almost no real application uses is beyond me.

  4. Matthew says:

    As a work around you can tap into the SelectedDateChanged event handler and handle the issue.  Here is sample code:

    public class CustomDatePicker : DatePicker

       {

           public CustomDatePicker()

           {

               SelectedDateChanged += DateChanged;

               Unloaded += CustomDatePickerUnloaded;

           }

           public override void OnApplyTemplate()

           {

               base.OnApplyTemplate();

               HandleWatermark();

           }

           private void DateChanged(object sender, SelectionChangedEventArgs e)

           {

               HandleWatermark();

           }

           private void CustomDatePickerUnloaded(object sender, RoutedEventArgs e)

           {

               SelectedDateChanged -= DateChanged;

           }

           public void HandleWatermark()

           {

               var box = GetTemplateChild("TextBox") as DatePickerTextBox;

               if (box == null) return;

               if (SelectedDateFormat == DatePickerFormat.Short)

                   box.Watermark = "mm/dd/yyyy";

           }

       }

    Hope that helps.

  5. a says:

    what a pointless and badly researched blog… and from a MS employee!!!

    Lucky that Matthew decided to comment with some information that is actually useful.

  6. Shivalika Jain says:

    There is away to persist the watermark in the DatePicker control. We can override the OnKeyUp method of the DatePIckerControl. Adding to Matthew's code, following provides the required solution:

    protected override void OnKeyUp(KeyEventArgs e)

    {

    base.OnKeyUp(e);

    HandleWatermark();

    }