C#Silverlight - 延迟子窗口加载?

时间:2009-09-30 11:07:18

标签: c# silverlight

情景

目前我有一个C#Silverlight应用程序,它使用域服务类和ADO.Net实体框架与我的数据库进行通信。我想在点击一个按钮时加载子窗口,该按钮包含我从服务器端查询到数据库的一些数据。

过程

此过程的第一部分涉及两个加载操作,以从两个表中加载单独的数据。该过程的下一部分涉及组合这些数据列表以在列表框中显示。

问题

这个问题是前两个异步加载操作在到达组合这些数据列表的代码段时没有返回数据,因此导致空值异常..... < / p>

获取数据的初始加载操作:

public void LoadAudits(Guid jobID)
        {
            var context = new InmZenDomainContext();

            var imageLoadOperation = context.Load(context.GetImageByIDQuery(jobID));
            imageLoadOperation.Completed += (sender3, e3) =>
            {
                imageList = ((LoadOperation<InmZen.Web.Image>)sender3).Entities.ToList();
            };

            var auditLoadOperation = context.Load(context.GetAuditByJobIDQuery(jobID));
            auditLoadOperation.Completed += (sender2, e2) =>
            {
                auditList = ((LoadOperation<Audit>)sender2).Entities.ToList();
            };
        }

我想立即执行此操作:

IEnumerable<JobImageAudit> jobImageAuditList
                = from a in auditList
                  join ai in imageList
                  on a.ImageID equals ai.ImageID
                  select new JobImageAudit
                  {
                      JobID = a.JobID,
                      ImageID = a.ImageID.Value,
                      CreatedBy = a.CreatedBy,
                      CreatedDate = a.CreatedDate,
                      Comment = a.Comment,
                      LowResUrl = ai.LowResUrl,

                  };

            auditTrailList.ItemsSource = jobImageAuditList;

但是我不能,因为异步调用还没有返回数据......

因此我必须这样做(执行加载操作,然后按子窗口上的按钮执行列表连接和绑定):

private void LoadAuditsButton_Click(object sender, RoutedEventArgs e)
        {

            IEnumerable<JobImageAudit> jobImageAuditList
                = from a in auditList
                  join ai in imageList
                  on a.ImageID equals ai.ImageID
                  select new JobImageAudit
                  {
                      JobID = a.JobID,
                      ImageID = a.ImageID.Value,
                      CreatedBy = a.CreatedBy,
                      CreatedDate = a.CreatedDate,
                      Comment = a.Comment,
                      LowResUrl = ai.LowResUrl,

                  };

            auditTrailList.ItemsSource = jobImageAuditList;
        }

解决方案的潜在想法:

以某种方式延迟显示子窗口? 可能使用DomainDataSource和Activity Load控件?!

任何想法,帮助,解决方案,样本评论等都非常感谢。

1 个答案:

答案 0 :(得分:1)

首先,延迟窗口的显示是没有意义的。相反,您应该设计代码以便能够处理数据的异步更新。在这种情况下,您有一个有趣的情况,即您正在执行两个异步加载操作,并且您只能在两个操作完成时创建显示数据。

此问题的一个解决方案是移动查询,将数据组合到服务器端。然后,您可以在两个单独的操作中从服务器检索Image和Audit对象,而不是检索JobImageAudit对象。

另一种解决方案是为您检索的数据创建类似于视图模型的内容。这是一个粗略的草图,可以帮助您入门:

public class JobImageAuditViewModel : INotifyPropertyChanged {

  IEnumerable<Image> images;

  IEnumerable<Audit> audits;

  IEnumerable<JobImageAudit> jobImageAudits;

  public void GetData() {
     this.images = null;
     this.audits = null;
     this.jobImageAudits = null;
     OnPropertyChanged("JobImageAuditList");
     // Load images by using GetImageByIDQuery()
     // Load audits by using GetAuditByJobIDQuery()
  }

  void LoadImageCompleted(Object sender, EventArgs e) {
    // Store result of query.
    this.images = ...
    UpdateJobImageAuditList();
  }

  void LoadAuditCompleted(Object sender, EventArgs e) {
    // Store result of query.
    this.audits = ...
    UpdateJobImageAudits();
  }

  void UpdateJobImageAudits() {
    if (this.images != null && this.jobs != null) {
      // Combine images and audits.
      this.jobImageAudits = ...
      OnPropertyChanged("JobImageAudits");
    }
  }

  public IEnumerable<JobImageAudit> JobImageAudits {
    get {
      return this.jobImageAudits; 
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;

  protected virtual void OnPropertyChanged(String propertyName) {
    var handler = PropertyChanged;
    if (handler != null)
      handler(this, new PropertyChangedEventArgs(propertyName));
  }

}

然后您必须将auditTrailList.ItemsSource数据绑定到JobImageAuditViewModel.JobImageAudits。您可以通过将包含DataContext的{​​{1}}或ChildWindow的{​​{1}}设置为UserControl的实例并将此属性添加到{{1}来执行此操作XAML:

auditTrailList

实际上,.NET RIA框架旨在让客户端生成的权利类承担MVVM应用程序中视图模型的角色。它们可以在客户端进行扩展,并且支持JobImageAuditViewModel。但是,在您的情况下,您在客户端使用服务器端不存在的实体。将我的第一个建议与数据绑定相结合可能是解决问题的最终方法。