3

Just can't get it with datepicker validation. I have datepicker From and datepicker To, so I want to prevent the user from doing some kung fu and seting datepicker From to be bigger than datepicker To, I've bumped across some questions but couldn't find the answer, so I've tried doing the easiest way I could think of:

Set MaxDate property for datepicker from in form_load event

private void Form1_Load(object sender, EventArgs e)
{
     datepickerFrom.MaxDate = datepickerFrom.Value;
}

Then do the same for value_changed event

private void datepickerFrom_ValueChanged(object sender, EventArgs e)
{
    datepickerFrom.MaxDate = datepickerFrom.Value;
}

This was easy and fine, only few lines of code, and I've only needed datepickerFrom_ValueChanged event, but recently I've tried typing date into datepicker insted of selecting it, and then all hell broke loose. So I came to some solution for validation, instead of setting MaxDate property, I've tried this.

private void dtFrom_ValueChanged(object sender, EventArgs e)
{        
    DateTime from = datepickerFrom.Value;
    DateTime to = datepickerTo.Value;
    int year= from.Year > to.Year ? to.Year : from.Year;
    int month = from.Month > to.Month ? to.Month : from.Month;
    int day = from.Day > to.Day ? to.Day : from.Day;
    int hour = from.Hour > to.Hour ? to.Hour : from.Hour;
    int minute = from.Minute > to.Minute ? to.Minute : from.Minute;
    int second = from.Second > to.Second ? to.Second : from.Second;
    //setting datepicker value
    datepickerFrom.Value = new DateTime(year, month, day, hour, minute, second);

}

This works fine, but feels like bit of headache, and I have to do this for datepickerTO_ValueChanged event also, sure I could make one method and call it two times, but still feels like there is a batter way for this, so any suggestions?

Thank you for your time

Jonas W
  • 3,200
  • 1
  • 31
  • 44
Djordje
  • 437
  • 1
  • 12
  • 24
  • 2
    Am I missing something? Can't you just check if From greater than To? – Crowcoder Jan 10 '18 at 11:25
  • 1
    So your actual problem description, derived from your description "all hell broke loose", is something like _"When typing a date into a WinForms DatePicker it ignores the MaxDate property"_? – CodeCaster Jan 10 '18 at 11:29

2 Answers2

3

Solution 1:

You can handle datePickerTo close event and do something like:

private void dateTimePickerTo_CloseUp(object sender, EventArgs e)
{
    DateTime fromdate = Convert.ToDateTime(dateTimePickerFrom.Value);
    DateTime todate1 = Convert.ToDateTime(dateTimePickerTo.Value);
    if (fromdate > todate1)
        //Error
}

You can also use DateTime.Compare whcih get two date like

int result = DateTime.Compar(dateTimePickerFrom.Value ,dateTimePickerTo.Value);

if result is 1 means From date is earlier, see this link.

Note1:

but as you said if user type in From or To textboxes then closeup event never fire so you need compare them in where you want to process such as button click.

Note2:

As @Sinatr comment if Value is DateTime then don't need to convert it so the code would be like:

 if (dateTimePickerFrom.Value >dateTimePickerTo.Value)
        //Error
Aria
  • 3,724
  • 1
  • 20
  • 51
  • 1
    Why not use [Value](https://msdn.microsoft.com/en-us/library/system.windows.forms.datetimepicker.value(v=vs.110).aspx) property? Then you don't need to use `Convert`. – Sinatr Jan 10 '18 at 11:27
  • @Sinatr, Edited before seeing your comment, Thank you. – Aria Jan 10 '18 at 11:28
  • nice suggestion, but where do you suggest to put this line of code? should i put it in `datepickerTo_ValueChanged` event? that wou'd maybe cause some problem when trying to type in date instead of selecting, let me try it – Djordje Jan 10 '18 at 11:42
  • 1
    @Yollo As I mentioned put my suggested code in `CloseUp` event of `To` datepicker, or in a method and call it when user type date completely not `change` event. – Aria Jan 10 '18 at 11:45
  • @Yollo , Focus on Note1 , why you are insisting to check date in texboxes event ? isn't it better to check them in a separate method and call that method everywhere you want, such as button click (main process) . – Aria Jan 10 '18 at 12:09
2

Your proposal would lead to a horrible interface. Suppose the following case:

From = 1 jan 2000
To = 1 feb 2000

User wants to change both values to 2010. He starts with the from value:

From = 1 jan 2010

Now he wants to change the TO value to 1 feb 2010. Alas, he can't.

Proper usage would be: add some button with which the operator can affirm he has changed all data, start checking it and update. In windows this button is usually named Apply Now or OK. Why deviate from this windows standard.

private void OnFormLoading(object sender, ...)
{
    this.FromDate.MinValue = ... // use the real absolute min value you want ever to allow
    this.FromDate.MaxValue = ...;
    this.ToDate.MinValue = ...;
    this.ToDate.MaxValue = ...;
}

Don't do any checking as long as the operator is making changes. Strat checking the input values when he indicates that he finished making changes:

private void OnButtonApplyNow_Clicked(object sender, ...)
{
    bool InputOk = CheckInput();
    if (!inputOk)
    {
         ShowIncorrectInput(); // for instance using a MessageBox
    }
}
Harald Coppoolse
  • 28,834
  • 7
  • 67
  • 116
  • thank you for pointing and suggestions, It's just i am implementing this in large forms, so I've wanted to cut the validation in `value_changed event`, , would `_close` or `_leave` event be the same as apply now button? – Djordje Jan 10 '18 at 11:49
  • 1
    So add an apply-now in a group box with the two dates. If name is confusing, use something like "accept" – Harald Coppoolse Jan 10 '18 at 11:58