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

时间:2010-12-07 17:42:30

标签: c# silverlight mvvm viewmodel

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

基本上,当用户修改日期范围时,会执行一个命令,将ViewModel的DateRange属性设置为新值。 DateRange的setter调用RunQueries方法查询新数据,并使用这些查询的结果设置Data1Data2属性。绑定到Data1Data2的图表会相应更新。请参阅下面的基本ViewModel代码;请注意RunQueries setter中的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
}

1 个答案:

答案 0 :(得分: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
    }

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