Minimal Text Entry of Date

8 posts, 0 answers
  1. Andrew Powrie
    Andrew Powrie avatar
    17 posts
    Member since:
    Apr 2007

    Posted 14 Feb 2012 Link to this post

    Have recently upgraded to 2011 Q3 SP1 and have noticed a change in the behaviour of the DateTimePicker when entering a date manually (using the format "dd/MM/yyyy"). Previously when you entered "1/1/1" into a blank DateTimePicker the result would be "01/01/2001" as the initial key press in each section would overwrite the whole section. The behaviour has now changed so the initial keypress only adds to the right of each section, so "1/1/1" results in "11/11/9001" (as it edits the null date instead of overwriting it).

    Is there anything I can do so it goes back to the old behaviour?  It is essential for our users to enter dates in with as minimal keystrokes as possible.
  2. Peter
    Admin
    Peter avatar
    1148 posts

    Posted 17 Feb 2012 Link to this post

    Hi Andrew,

    Thank you for writing.

    We have changed the input behavior in Q2 2011, because we want to have a strictly validated date in every moment in which the user types.

    When you start typing, the DateTimePicker will append the typed number to the initial value of the year- in your case 0001. So if you want to enter 0015, you should press 5 and this will concatenate 1 and 5, the result will be 0015.

    As a workaround for your case, you can set the initial value for the year to 200 - in this case when user types 1, the result will be 2001.

    Please refer to the code below:
    this.radDateTimePicker1.NullableValue = new DateTime(200,12,29);//this will set the base date for the editor – user typing will be appended to these numbers
    this.radDateTimePicker1.NullableValue = null; //this line will clear the text from the editor

    Let me know if this is this an applicable solution in your case - if not, I will try to find another solution based on KeyPress or Validate event.

    Regards,
    Peter
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Andrew Powrie
    Andrew Powrie avatar
    17 posts
    Member since:
    Apr 2007

    Posted 19 Feb 2012 Link to this post

    I'm sorry but that is not a solution at all.  What if the user wants to enter 11 for 2011? It doesn’t even address the issue of the end user trying to enter a single digit day or month.

    Your comment that "We have changed the input behaviour in Q2 2011, because we want to have a strictly validated date in every moment in which the user types" does not make sense. The new behaviour is more likely to lead to invalid dates being entered (as 0015 is not valid as opposed to the original behaviour interpreting this as 2015). 

    The new behaviour also leads to a lot more end user confusion, as your date control does not behave like a standard date control. Date controls are expected to handle partial date entry. This control used to work perfectly fine. Why did it have to change?




  5. Peter
    Admin
    Peter avatar
    1148 posts

    Posted 21 Feb 2012 Link to this post

    Hi Andrew,

    Thank you for your feedback.

    For Q2 2011 we had completely rewritten our RadMaskedEditBox in order to fix a few shortcomings.
    In this version we do not allow incomplete input of the date - e.g. value is always equal with user input.
    I would like to propose a workaround for your case. Check the year OnValidate event to and if it smaller than 2000, then add 2000 to year:
    this.radDateTimePicker1.NullableValue = new DateTime(20, 1, 1);        
    this.radDateTimePicker1.NullableValue = null;          
    this.radDateTimePicker1.Validated += new EventHandler(radDateTimePicker1_Validated);
     
     
    void radDateTimePicker1_Validated(object sender, EventArgs e)
    {
              if (this.radDateTimePicker1.Value.Year < 2000)
                {
                    int lastDigits = int.Parse(this.radDateTimePicker1.Value.ToString("yy"));
                    this.radDateTimePicker1.Value = new DateTime(lastDigits + 2000, this.radDateTimePicker1.Value.Month, this.radDateTimePicker1.Value.Day);           
                }
    }

    I hope this helps. Do not hesitate to contact us if you have other questions.

    Greetings,
    Peter
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  6. Andrew Powrie
    Andrew Powrie avatar
    17 posts
    Member since:
    Apr 2007

    Posted 21 Feb 2012 Link to this post

    I'm sorry but that is still not a solution.  It still doesn’t address the issue of the end user trying to enter a single digit day or month. Tab onto an empty date control and enter 2/2/76 for 02/02/1976 and you will get and invalid date or with your fix 12/12/2076. It also doesn't address editing of dates. When trying to change 01/01/1999 to 01/01/2001, previously you initially pressed 1 on the year section and it worked, now you get 01/01/9991. They only way to use this control when editing to to fully type out all 8 digits, which is not the natual way to do things when you only want to change a single date part.

    Shouldn't the date control behave in the same way as Microsoft's date control? What has been your experience setting and editing dates with your control on a day to day basis?

    The only way I can think of working around this is to handle the keypress event. If it is determined that this is the first keypress in a date part (either from giving the control focus or changing from another date part within the same control), then padleft the required number of 0's and then add the keypress (is there an easy way to determine which dart part is being changed?). On validation if the year is >= 50 and <= 99 then add 1900, else if the year is >= 500 and <= 999 then add 1000, else if the year is < 50 or if the year is > 99 and < 500 then add 2000.


  7. Peter
    Admin
    Peter avatar
    1148 posts

    Posted 24 Feb 2012 Link to this post

    Hi Andrew,

    Thank you for your suggestions.

    We plan to implement such functionality in one of our future releases. Please refer to the code below which demonstrates how you can handle the key-press event and how to detect if the key-press is in the year part:

    public Form1()
        {
            InitializeComponent();
     
            this.radDateTimePicker1.Value = DateTime.MinValue.AddDays(1);  
            this.radDateTimePicker1.KeyPress += new KeyPressEventHandler(radDateTimePicker1_KeyPress);
              
        }
     
        void radDateTimePicker1_KeyPress(object sender, KeyPressEventArgs e)
        {
            MaskDateTimeProvider provider = (MaskDateTimeProvider)this.radDateTimePicker1.DateTimePickerElement.TextBoxElement.Provider;
            if (provider.List[provider.SelectedItemIndex].type == PartTypes.Year)
            {
                MaskPart part = provider.List[provider.SelectedItemIndex];
                int len = part.value.ToString().Length;
                if (len >= 2)
                {
                    part.value = int.Parse(part.value.ToString().Substring(len - 2, 2));
                }
                if (part.value >= 50 && part.value <= 99)
                {
                    part.value += 1900;
                }
                else if (part.value >= 500 && part.value <= 999)
                {
                    part.value += 1000;
                }
                else if (part.value < 50 || (part.value > 99 && part.value < 500))
                {
                    part.value += 2000;
                }
     
                radDateTimePicker1.Value = new DateTime(part.value, radDateTimePicker1.Value.Month, radDateTimePicker1.Value.Day, radDateTimePicker1.Value.Hour, radDateTimePicker1.Value.Minute, radDateTimePicker1.Value.Second);
            }
        }

    I hope you find this information helpful.

    Greetings,
    Peter
    the Telerik team
    RadControls for WinForms Q1'12 release is now live! Check out what's new or download a free trial >>
  8. Andrew Powrie
    Andrew Powrie avatar
    17 posts
    Member since:
    Apr 2007

    Posted 05 Mar 2012 Link to this post

    public class MyRadDateTimePicker : RadDateTimePicker
    {
        private PartTypes lastPart = PartTypes.ReadOnly;
        public MyRadDateTimePicker()
            : base()
        {
            this.CustomFormat = "dd/MM/yyyy";
            this.Format = DateTimePickerFormat.Custom;
            this.NullText = "Select Date";
            this.KeyPress += new KeyPressEventHandler(_KeyPress);
        }
        public override string ThemeClassName
        {
            get
            {
                return typeof(RadDateTimePicker).FullName;
            }
        }
        private void _KeyPress(object sender, KeyPressEventArgs e)
        {
            MaskDateTimeProvider provider = (MaskDateTimeProvider)this.DateTimePickerElement.TextBoxElement.Provider;
            PartTypes currPart = provider.List[provider.SelectedItemIndex].type;
            if (Char.IsDigit(e.KeyChar) && currPart != this.lastPart && Int32.Parse("" + e.KeyChar) != 0 && (currPart == PartTypes.Year || currPart == PartTypes.Month || currPart == PartTypes.Day))
            {
                if (provider.List[provider.SelectedItemIndex].type == PartTypes.Year)
                {
                    this.Value = new DateTime(2000 + Int32.Parse("" + e.KeyChar), this.Value.Month, this.Value.Day, this.Value.Hour, this.Value.Minute, this.Value.Second);
                }
                else if (provider.List[provider.SelectedItemIndex].type == PartTypes.Month)
                {
                    this.Value = new DateTime(this.Value.Year, Int32.Parse("" + e.KeyChar), this.Value.Day, this.Value.Hour, this.Value.Minute, this.Value.Second);
                    if (this.Value == this.NullDate)
                    {
                        this.Value = new DateTime(DateTime.Now.Year, this.Value.Month, this.Value.Day, this.Value.Hour, this.Value.Minute, this.Value.Second);
                    }
                }
                else if (provider.List[provider.SelectedItemIndex].type == PartTypes.Day)
                {
                    this.Value = new DateTime(this.Value.Year, this.Value.Month, Int32.Parse("" + e.KeyChar), this.Value.Hour, this.Value.Minute, this.Value.Second);
                    if (this.Value == this.NullDate)
                    {
                        this.Value = new DateTime(DateTime.Now.Year, this.Value.Month, this.Value.Day, this.Value.Hour, this.Value.Minute, this.Value.Second);
                    }
                }
                this.lastPart = currPart;
            }
            else if (Char.IsDigit(e.KeyChar) && currPart == this.lastPart && currPart == PartTypes.Year && this.Value.Year < 1000)
            {
                if (this.Value.Year >= 50 && this.Value.Year <= 99)
                {
                    this.Value = new DateTime(1900 + this.Value.Year, this.Value.Month, this.Value.Day, this.Value.Hour, this.Value.Minute, this.Value.Second);
                }
                else if (this.Value.Year >= 900 && this.Value.Year <= 999) // anything less than 1900 generates an invalid date
                {
                    this.Value = new DateTime(1000 + this.Value.Year, this.Value.Month, this.Value.Day, this.Value.Hour, this.Value.Minute, this.Value.Second);
                }
                else
                {
                    this.Value = new DateTime(2000 + this.Value.Year, this.Value.Month, this.Value.Day, this.Value.Hour, this.Value.Minute, this.Value.Second);
                }
            }
        }
    }
    This is what I have implemented so far to get the behaviour I am looking for.
  9. Peter
    Admin
    Peter avatar
    1148 posts

    Posted 08 Mar 2012 Link to this post

    Hello Andrew,

    Thank you for sharing your solution with the community. 

    We plan to implement similar functionality in our next release.

    I have updated your Telerik points accordingly. 

    Greetings,
    Peter
    the Telerik team
    RadControls for WinForms Q1'12 release is now live! Check out what's new or download a free trial >>
Back to Top
UI for WinForms is Visual Studio 2017 Ready