Reputation: 337
I have some code which has an unexpected behavior depending on how you use the DatePicker control. If you use the DatePicker by selecting the date via the mouse the event is fired once and the code works correctly. Though if you type in the date the event is triggered twice. Here is my xaml code.
<DatePicker Margin="0,-1,0,0" Height="23" VerticalAlignment="Top" HorizontalAlignment="Right" Width="190" SelectedDate="{Binding DaDate}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedDateChanged">
<i:InvokeCommandAction Command="{Binding SelectedDaDateChangedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</DatePicker>
And c# bits.
public ICommand SelectedDaDateChangedCommand { get; set; }
private DateTime? daDate;
public DateTime? DaDate
{
get { return daDate; }
set
{
daDate = value;
NotifyOfPropertyChange(() => DaDate);
}
}
public MisoConstraintsViewModel(IView v) : base(v)
{
//This is where DoStuff() gets called twice from the SelectedDateChanged
SelectedDaDateChangedCommand = new RelayCommand(p => DoStuff());
}
Any help is appreciated. Thanks.
Upvotes: 0
Views: 3476
Reputation: 191
This is a reactive approach, same concept can be used with events if you do not wish to use reactive. The DatePicker will fire twice when modifying it from the text box because it triggers the SelectedDateChanged when the edit is committed in the text box and again when the calendar sets the selected date. I extended the class to be able to subscribe to something that I have a bit more control over.
I know this is an old thread, hope this helps someone still looking for an answer.
class CustomDatePicker : DatePicker
{
private DateTime comparer;
private Subject<DateTime> dateChangedSubject = new Subject<DateTime>();
static CustomDatePicker()
{
// Override property changed callback for SelectedDate
DatePicker.SelectedDateProperty.OverrideMetadata(typeof(CustomDatePicker), new FrameworkPropertyMetadata(SelectedDate_PropertyChanged));
}
/// <summary>
/// Subscribe to this observable instead of SelectedDateChanged event
/// It will only fire once when the selected date changes
/// </summary>
public IObservable<DateTime> DateChanged
{
get { return this.dateChangedSubject.AsObservable(); }
}
/// <summary>
/// Checks if the comparer is equal to the new value
/// If it is not, store the new value and fire changed subject
/// </summary>
/// <param name="d"></param>
/// <param name="e"></param>
private static void SelectedDate_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
CustomDatePicker datePicker = d as CustomDatePicker;
if(datePicker.comparer != (DateTime)e.NewValue)
{
datePicker.comparer = (DateTime)e.NewValue;
datePicker.dateChangedSubject.OnNext((DateTime)e.NewValue);
}
}
}
Can be used like:
customDatePicker.DateChanged.Subscribe(_ =>
{
Console.WriteLine("DateChanged fired");
});
or
// use the passed DateTime value to do something
customDatePicker.DateChanged.Subscribe(dt =>
{
//... do something with dt
});
Upvotes: 1
Reputation: 242
if I got you right, DaDate
property is set two times in a row. I would advice to check for previous value
public DateTime? DaDate
{
get { return daDate; }
set
{
if(value != daDate)
{
daDate = value;
NotifyOfPropertyChange(() => DaDate);
}
}
}
this won't help to find out the cause, but possibly can solve your problem
Upvotes: 1