WP7 - Create DatePicker control programmatically

If you need use DatePicker in your windows phone application you must create control field in xaml file. Or no...
Let's create DatePicker control programmatically without any code in xaml file.


  1. Install Silverlight Toolkit last version.
  2. Create new "Windows Phone Application" named "DatePickerControlProgrammatically".
  3. Adding new reference to Microsoft.Phone.Controls.Toolkit
    • Main Menu -> Project -> Add Reference -> Tab ".NET" -> choose Microsoft.Phone.Controls.Toolkit.
    • If you no find Microsoft.Phone.Controls.Toolkit in ".NET" tab go to "Browse" tab and navigate to this dll in you computer (for me "C:\Program Files\Microsoft SDKs\Windows Phone\v7.0\Toolkit\Sep10\Bin\Microsoft.Phone.Controls.Toolkit.dll").
  4. Create new folder in project "Toolkit.Content" and put inside two images for cancel and check control (you can get them in Silverlight Toolkit project or create you own icons):
  5. Don't forget change "Build Action" property for each image to "Content" from "Resource".
  6. Override DatePicker class with our custom DatePickerCustom class. Create new class "DatePickerCustom.cs":
    using System.Windows.Automation.Peers;
    using System.Windows.Automation.Provider;
    using System.Windows.Controls;
    using Microsoft.Phone.Controls;  
    
    namespace DatePickerControlProgrammatically
    {
        public class DatePickerCustom : DatePicker
        {
            public void ClickTemplateButton()
            {
                Button btn = (GetTemplateChild("DateTimeButton") as Button);
                ButtonAutomationPeer peer = new ButtonAutomationPeer(btn);
                IInvokeProvider provider = (peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider);
    
                provider.Invoke();
            }
        }
    }
    
  7. MainPage.xaml.cs - create new DatePickerCustom on Loaded event:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    namespace DatePickerControlProgrammatically
    {
        public partial class MainPage : PhoneApplicationPage
        {
            private DatePickerCustom datePicker;
    
            // Constructor
            public MainPage()
            {
                InitializeComponent();
    
                Loaded += new RoutedEventHandler(MainPage_Loaded);
            }
    
            void MainPage_Loaded(object sender, RoutedEventArgs e)
            {
                // create datePicker programmatically
                if (this.datePicker == null)
                {
                    this.datePicker = new DatePickerCustom();
                    this.datePicker.IsTabStop = false;
                    this.datePicker.MaxHeight = 0;
    
                    this.datePicker.ValueChanged += new EventHandler<DateTimeValueChangedEventArgs>(datePicker_ValueChanged);
    
                    LayoutRoot.Children.Add(this.datePicker);
    
                }
            }
    
            void datePicker_ValueChanged(object sender, DateTimeValueChangedEventArgs e)
            {
                // now we may use got value from datePicker
                PageTitle.Text = this.datePicker.ValueString;
            }
        }
    }
  8. For test add to MainPage.xaml two buttons - "Get Date" and "Clear Date":
    <Button Content="Get Date" Height="72" HorizontalAlignment="Left" 
        Name="button1" VerticalAlignment="Top" 
        Width="160" Click="button1_Click"/>
    <Button Content="Clear Date" Height="72" HorizontalAlignment="Right" 
        Name="button2" VerticalAlignment="Top" 
        Width="160" Click="button2_Click"/>
    

  9. And to MainPage.xaml.cs add control for our buttons:
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        this.datePicker.ClickTemplateButton();
    }
    
    private void button2_Click(object sender, RoutedEventArgs e)
    {
        PageTitle.Text = "Page Title";
        clearDatePicker();
    }
    
    void clearDatePicker()
    {
        this.datePicker.ValueChanged -= new EventHandler<DateTimeValueChangedEventArgs>(datePicker_ValueChanged);
    
        //this.datePicker.Value = "8/16/2011";
        this.datePicker.Value = null;
    
        this.datePicker.ValueChanged += new EventHandler<DateTimeValueChangedEventArgs>(datePicker_ValueChanged);
    }
    
  10. Run

6 comments:

  1. Does this approach still work with Windows Phone 8?
    I get a ArgumentNullException on ButtonAutomationPeer peer = new ButtonAutomationPeer(btn);
    And btn is null, so it does not find it

    ReplyDelete
    Replies
    1. nevermind. It works when I call ApplyTemplate() before

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Several years later, but I just found this. Works great! Thanks so much for posting this!

    ReplyDelete
  4. My button is always null and I am not sure why

    Button btn = (GetTemplateChild("DateTimeButton") as Button);

    ReplyDelete