WPF Datepicker returns previously selected Date us

2019-05-16 18:01发布

问题:

I am working on a WPF project where I have a Datepicker control on a Window. I am using MVVM pattern for data bindings. I have setup a command on SelectedDate changed event of the Datepicker. The problem is that for e.g., when first time I change the date I get NULL in the event handler of the command. And when I changed the date again, then I get the previously selected date in the event handler. This is a strange behaviour as this doesn't happens if I don't use WPF commands and work in code behind model.

Here is my xaml code snippet for DatePicker:

<DatePicker x:Name="dpEventDate" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Stretch" Margin="150,0,150,0" 
            VerticalAlignment="Center" SelectedDateFormat="Long" 
            SelectedDate="{Binding Path=., Source={x:Static sys:DateTime.Today},  StringFormat=Today is {0:dddd, MMMM dd}}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectedDateChanged">
            <i:InvokeCommandAction Command="{Binding SelectedDateChangedCommand}"
                                   CommandParameter="{Binding ElementName=dpEventDate, Path=SelectedDate}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <DatePicker.Background>
        <SolidColorBrush Color="LightYellow"></SolidColorBrush>
    </DatePicker.Background>
</DatePicker>

Command event handler in ViewModel class

get
{
    return new DelegateCommand((sdate) =>
    {
        selectedDate = Convert.ToDateTime(sdate);
        if (sdate != null)
        {
            //some logic here
        }
    }  
}
set
{
    SelectedDateChangedCommand = value;
    RaisePropertyChangedEvent("SelectedDateChangedCommand");
}

DelegateCommand class implements ICommand

So in above code "sdate" parameter always return a previously selected date. And if it is the first time I change the date it returns NULL.

Any idea what I might be doing wrong?

回答1:

I'm not sure what you are trying to achieve by binding the change to the event and command. Is there a reason why you don't bind the SelectedDate Property of your DatePicker (using TwoWay mode)? Currently you're binding it to a static DateTime.Today.

<DatePicker x:Name="dpEventDate" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Stretch" Margin="150,0,150,0" 
      VerticalAlignment="Center" SelectedDateFormat="Long" 
      SelectedDate="{Binding MyDateTimeProperty, Mode=TwoWay}">

and in your ViewModel having a

private Nullable<DateTime> myDateTimeProperty = null;
public Nullable<DateTime> MyDateTimeProperty {
    get {
        if(myDateTimeProperty == null) {
            myDateTimeProperty = DateTime.Today;
        }
        return myDateTimeProperty;
    }
    set {
        myDateTimeProperty = value;
        RaisePropertyChangedEvent("MyDateTimeProperty");
    }
}

This way your ViewModel will return the current date and set it in the DatePicker, if the date is null previously and if the DatePicker is changed, it will bind it's new way back to the property.