16

When my users select a date via the Calander control within the DatePicker, the value gets correctly bound to the underlying object. BUT, if the user types the date within the DatePicker, then clicks a button, the text is not set to the SelectedDate property.

The user has to remove the cursor from the TextBox within the DatePicker for the bound object to be updated.

 <toolkit:DatePicker Name="_dpField" Grid.Column="1" MinWidth="100"
               ToolTip="{Binding Path=ToolTipText}"
               TextInput="_dpField_TextInput"
               SelectedDate="{Binding Path=Value, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>

HELP! how do i make sure that this typed value is used within the buttons event code?

Thanks!

Nathan Tregillus
  • 6,006
  • 3
  • 52
  • 91

6 Answers6

19

I found a easier solution where I don't need the DateConverter.

I only bound to the Text Property and use TargetNullValue=''.

<DatePicker x:Name = "dpDisbursementDate" 
            Text = "{Binding NameOfMyProperty, Mode=TwoWay,    
            UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, 
            TargetNullValue=''}"/>
Blckknght
  • 100,903
  • 11
  • 120
  • 169
Slampen
  • 790
  • 9
  • 21
  • that is seriously sneaky! – Nathan Tregillus Jun 23 '14 at 15:45
  • That is absolutely brilliant! Works like a charm for me. – B.K. Jun 28 '14 at 03:29
  • 5
    This answer seems to fix the original problem but there is another dangerous problem which is not immediately apparent: different date formats are not parsed correctly. I'm from Finland and we use format dd.mm.yyyy. This implementation parsed current date December 9th, 2014 as September 11th, 2014. – Ville Salonen Dec 09 '14 at 06:27
  • I have tried this, but I found the same problem as Ville Salonen. So, does anyone find another solution? – Abdalwhab Bakheet Apr 11 '16 at 08:59
  • saved my day..... :) (I also seen the locale-influence, but in my actual usecase I don't have to bother....) – dba Aug 18 '16 at 06:22
  • It is not working if the `NameOfMyProperty` is nullable DateTime type. I guess that it works for string type only. We still need a converter. – Bigeyes Mar 02 '19 at 16:32
  • Wow that really is the best solution. I tried hours on binding to SelectedDate with converting the Text Binding. But always got others problem. Binding the DateTime? Property like this to the Text also solves the Problem that the Binding to SelectedDate only updates on LostFocus. Thanks a lot – Momo Nov 18 '19 at 13:26
8

You can use a converter for parsing your typed text to a valid datetime

Sample

 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string strValue = System.Convert.ToString(value);
        DateTime resultDateTime;
        if (DateTime.TryParse(strValue, out resultDateTime))
        {
            return resultDateTime;
        }
        return value;

    }

Xaml

     <Controls:DatePicker 
     Text="{Binding OrderDate,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
     SelectedDate="{Binding RelativeSource={RelativeSource Self},Path=Text,
     Converter={StaticResource DateConverter}}">
biju
  • 17,554
  • 10
  • 59
  • 95
  • Gotcha, I can do that. I am just curious why the binding for selected date only occurs when i purposefully blur the date picker's textbox. I think i need to ask another question about the click event with WPF, and why it doesn't cause the binding to push the value up to the bound object before the event is fired for the button click. thanks for the help – Nathan Tregillus Dec 28 '10 at 14:28
  • **Update** just implemented the converter, and it works. now to start a new question about binding mode and click events. – Nathan Tregillus Dec 28 '10 at 14:44
  • I use the method but it is not working because it needs ConvertBack method if I input the text on UI. – Bigeyes Mar 01 '19 at 02:48
  • Haven't worked for me always got ValidationErrors on Value "" when DatePicker Value is made Empty. Only solution that really worked was binding die DateTime? property to Text and Setting TargetNullValue='', like the answer below from @Slampen – Momo Nov 18 '19 at 13:28
2

Here a simple solution, that helped me even with the european/german date format "dd.MM.yyyy".

Add to your xaml root element

xml:lang="de-AT"

and the datepicker looks like this:

<DatePicker SelectedDate="{Binding PropertyName, StringFormat=dd.MM.yyyy}" Name="datePicker" />

hope it works for you!

1

The only solution that I could find is to disable entering of the date in the DatePicker by setting Focusable="False" and only allowing selection from the calendar. This way we can at least make sure that we get the correct date.

Abdalwhab Bakheet
  • 1,133
  • 2
  • 11
  • 17
0

In my particular case I had a Button that started an action in its ViewModel before the date was updated from text. However binding the function below to the buttons Click (both Click and Action are bound) overwrites the required date before the action starts.

private void UpdateDateBeforeAction(object sender, RoutedEventArgs e)
{
    bool parseSuccess = DateTime.TryParse(this.myDatePicker.Text, out DateTime parsedDate);
    if (parseSuccess && this.DataContext is MyParticularViewModel vm)
    {
        vm.targetDate = parsedDate;
    }
}

Edit: Actually you don't even need to touch the viewmodel

if(parseSuccess)
{
    this.myDatePicker.SelectedDate = parsedDate;
}
apoth
  • 13
  • 3
-2

This is probably a bit late, but I've been stuck on this for a while now.

If you have another WPF element you can change focus to that at the beginning of your button press event, this will make the datepicker process any text entered in it's textbox. I've only tried this with a combobox but it seems to work and it allows you to still have custom formatting on your dates (ie 26/04/2016 rather than 04/26/2016). I assume you would be able to use an invisible element as well if you don't have anything to change focus to.

    private void btnInbound_Complete_Click(object sender, RoutedEventArgs e)
    {
        if (Validation())
        {
            comboInbound_Result.Focus();//THIS IS SO THAT ANY MANUAL DATEPICKER ENTRY IS ACCEPTED BEFORE THE REST OF THE BUTTON CODE IS RUN
            SQLinbound_CompleteItem();
            ClearAll();
        }
    }
Il Vic
  • 5,576
  • 4
  • 26
  • 37
Rob
  • 1
  • 2