一次更新依赖属性而不是两次

时间:2013-02-23 11:20:31

标签: silverlight data-binding mvvm viewmodel inotifypropertychanged

在我的ViewModel中,我有两种属性类型的Datetime。它们在XAML中以TwoWay模式绑定。当我更新它们时 - OnPropertyChanged在第三个属性的Datetime属性的set部分中引发。因此,当我同时更新两个Datetime属性时,我只想更新第三个属性,而不是两次更新第三个属性。它如何成功? 适用代码:

//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);
    }
}

2 个答案:

答案 0 :(得分:2)

您可以通过每当其中一个日期属性更改时启动的计时器来延迟MyList属性更改通知。当两个属性“同时”更改时,这不仅可以避免双重通知,还可以防止在其中一个属性更改频​​繁时频繁发出通知。

通过停止并重新启动计时器,可以在每次更改属性时重置计时器,因此在实际通知MyList属性更改之前,您可以进行许多后续属性更改。

下面的代码示例使用DispatcherTimer来执行此任务。当然,您必须为Interval值找到合理的值。

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();
    }
}

答案 1 :(得分:0)

正如我看到的那样,用户更改startDate的拳头结束日期。 ?反之亦然。

以下代码有机会,

        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;
                }
         }