如何在Silverlight ViewModel类中推迟数据查询?

MCS*_*MCS 5 c# silverlight mvvm viewmodel

我有一个Silverlight应用程序,顶部有几个图表和一个日期控件,允许用户设置日期范围(例如7月1日 - 9月30日).

基本上,当用户修改日期范围时,会执行一个命令,将ViewModel的DateRange属性设置为新值.该DateRangesetter调用一个RunQueries查询新数据的方法,Data1Data2使用这些查询的结果设置和属性.相应绑定Data1Data2更新的图形.请参阅下面的基本ViewModel代码; 记下setter 中的RunQueries方法调用DateRange.

现在实际上,已经有两个以上的数据集合,并且随着应用程序的扩展而不断添加.此外,并非所有图表都可以同时显示; 有时只能看到一个图表.但是,当用户更改日期范围时,将使用新的开始日期和结束日期重新运行获取任何图表所需的所有数据的所有查询.这对我来说似乎效率很低 - 也许只需要运行一个查询!

所以我的问题是 - 如何在我的ViewModel类中实现延迟数据查询?

以下是我一直在考虑的两个想法:

  • 跟踪哪些数据集合是最新的,然后检查数据getter方法是否需要运行查询.
  • 将ViewModel分解为几个子类,每个子图对应一个子类,并让每个ViewModel管理自己的数据,基类跟踪DateRange.

这两个想法实现起来都很复杂,我一直在想 - 有没有一种标准的方法呢?我是否遗漏了解决此问题的MVVM设计模式?


这是我的ViewModel类的非常简化版本:

public class MyViewModel: INotifyPropertyChanged
{
    private ObservableCollection<MyData> _Data1;
    private ObservableCollection<MyData> _Data2;
    private MyDateRange _DateRange;

    public ObservableCollection<MyData> Data1
    {
        get 
        { 
            return _Data1; 
        }
        set
        { 
            if (_Data1 != value) 
            {
                _Data1 = value;
                NotifyPropertyChanged("Data1");
            }
        }
    }

    // getter and setter for Data2 go here

    public MyDateRange DateRange
    {
        get
        {
             return _DateRange;
        }
        set
        {
             if (_DateRange != value)
             {
                 _DateRange = value;
                 NotifyPropertyChanged("DateRange");

                 // if date range changed, need to query for stats again
                 RunQueries();
             }
         }
     }

     private void RunQueries()
     {
          GetData1();
          GetData2();
     }

     private void GetData1()
     {
          // call wcf service to get the data
     }

     private void GetData1Completed(object s, EventArgs e)
     {
          // update Data1 property with results of service call
     }

     // etc
}
Run Code Online (Sandbox Code Playgroud)

vor*_*olf 1

我将尝试总结一下您的情况:

  • 如果数据范围发生变化,则仅应更新可见图表。
  • 如果任何图表变得可见 - 它应该立即更新自身。

因此,显然需要可见性属性。

第一点的解决方案:在 RunQueries 方法中检查命令执行的可能性。

第二点的解决方案:在 Visibility 属性的 setter 中执行命令。

这是示例:

private DelegateCommand UpdateData1Command { get; set; }

    public MyViewModel()
    {
        this.UpdateData1Command = new DelegateCommand(_ => this.GetData1(), _ => this.IsGraph1Visible);
    }

    private bool isGraph1Visible;

    public bool IsGraph1Visible
    {
        get { return isGraph1Visible; }
        set
        {
            isGraph1Visible = value;
            OnPropertyChanged("IsGraph1Visible");

            if(UpdateData1Command.CanExecute(null))
                UpdateData1Command.Execute(null);
        }
    }

    private void RunQueries()
    {
        if (UpdateData1Command.CanExecute(null))
            UpdateData1Command.Execute(null);
    }

    private void GetData1()
    {
        // call wcf service to get the data
    }
Run Code Online (Sandbox Code Playgroud)

每个图表现在都有属性 Data、IsVisible、UpdateDataCommand 和方法 GetData。我建议将它们移至单独的视图模型中。