0

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);
    }
}
Phil
  • 42,255
  • 9
  • 100
  • 100
Buddy
  • 89
  • 6

2 Answers2

2

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();
    }
}
Clemens
  • 123,504
  • 12
  • 155
  • 268
0

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;
                }
         }
Davut Gürbüz
  • 5,526
  • 4
  • 47
  • 83
  • Actually, these StartDate and EndDate are bound to SelectedStartDate and SelectedEndDate of RadTimeBar telerik's control. So it's possible to change one of these dates, for example I change only SelectedStartDate and third property needs to be changed to. _BUT_ when I drag over subcontrol of RadTimeBar so both SelectedStartDate and SelectedEndDate change in very small period I guess. And after change of _BOTH_ Dates I want to update my third property. – Buddy Feb 23 '13 at 14:31
  • I also use RadTimeBar,RadTimeLine also. My code should help you. (I just code down Stackoverflow's editor). You may also use events if exist for drag operation.(such as drag completed ? ) – Davut Gürbüz Feb 23 '13 at 14:38
  • I've added _UpdateDates_ method for my ViewModel and call it in _SelectionChanged_ event handler of RadTimeBar. This solution not so good, but thank you for ideas. If anyone could suggest better idea, it would be great. – Buddy Feb 23 '13 at 15:28