In my ViewModel I have two properties type of Datetime. They are bound in XAML with TwoWay mode. When I update each of them - OnPropertyChanged raises in set part of this Datetime property for the third property. So I want to update the third property only once when I update two Datetime properties at the same time, instead of updating third property twice. How it can be archieved?
Code applied:
//1
public DateTime StartDate
{
...
set
{
this.selectedEndDate = value;
this.OnPropertyChanged("StartDate");
this.OnPropertyChanged("MyList");
}
}
//2
public DateTime EndDate
{
...
set
{
this.selectedEndDate = value;
this.OnPropertyChanged("EndDate");
this.OnPropertyChanged("MyList");
}
}
//third property
public IEnumerable<MyObject> MyList
{
get
{
return _data.Where(kvp=> kvp.Key.Date >= Start && kvp.Value.Date <= End).Select(kvp => kvp.Value);
}
}
You may delay the MyList
property change notification by means of a timer that is started whenever one of the date properties changes. This would not only avoid double notifications when both properties change "at the same time", but would also protect against frequent notifications when one of the properties changes too frequently.
The timer would be reset on every property change by stopping and restarting it, hence you can have many subsequent property changes before actually notifying the MyList
property change.
The code example below uses a DispatcherTimer to perform this task. Of course you have to find a sensible value for the Interval
value.
private DispatcherTimer notifyTimer;
public ViewModel()
{
notifyTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(200) };
notifyTimer.Tick += OnNotifyTimerTick;
}
private void OnNotifyTimerTick(object sender, EventArgs e)
{
OnPropertyChanged("MyList");
notifyTimer.Stop();
}
public DateTime StartDate
{
...
set
{
selectedEndDate = value;
OnPropertyChanged("StartDate");
notifyTimer.Stop();
notifyTimer.Start();
}
}
public DateTime EndDate
{
...
set
{
selectedEndDate = value;
OnPropertyChanged("EndDate");
notifyTimer.Stop();
notifyTimer.Start();
}
}
As I see it user change startDate fist endDate second. ? or vice versa.
The below code has a chance ,
bool fistChanged,endChanged;
on Ctor (Constructor)
this.PropertyChanged+=(s,p)=>
{
if(p.PropertyName=="firstDate")
{
firstChanged=true;
}
if(p.PropertyName=="endDate")
{
endChanged=true;
}
if(firstChanged && endChanged)
{
this.OnPropertyChanged("MyList");
fistChaned=false;endChanged=false;
}
}