c# - 何时以及如何在 Windows Phone wp8 中的 ViewModel 中调用异步方法

标签 c# mvvm windows-phone-8 async-await

我有一个使用 MVVM 模式的 windows phone (wp8) 应用程序,它包含一个带有枢轴控件的 View 并绑定(bind)到一个 ViewModel (PivotMainViewModel)。

每个数据透视项目包含不同的 View (数据模板)并绑定(bind)到自己的 View 模型(PivotItemViewModel1、Pivo​​tItemViewModel1 等),所有这些都运行良好。

我的 PivotMainViewModel 是通过 xaml 绑定(bind)初始化的,但由于它需要一个参数,因此它也通过 View 的 OnNavigatedTo 事件“初始化”。

PivotItemViewModel4 pivotItemViewModel4 = Resources["PivotItemViewModel4"] as PivotItemViewModel4;
if (selectedRow.Id > 0)
{
    pivotItemViewModel4.InitializeDocumentDetails(selectedRow);

}

但我不确定如何处理我想要异步发出的 Web 服务请求。我需要为每个单独的数据透视项“ View ”发出 Web 服务请求,并在数据返回的那一刻加载数据,但我需要在数据透视初始化后立即执行此操作,但我不确定以下内容:
  • 我需要在每个枢轴项“ View ”中填充数据,因此需要在它们的相关 View 模型中填充数据,但我不确定是应该从 PivotMainViewModel 还是从为每个枢轴项定义的每个单独的 View 模型中进行所有异步调用。
  • 无论我是从 PivotMainViewModel 调用它还是从每个数据透视项 View 模型调用它,我应该什么时候调用它?

  • 我应该从构造函数中调用它吗:
    public PivotItemViewModel1
    {
      this.Document = GetDocument();
    }
    

    或者当其内部变量为空时,我的属性(property)的获取部分? IE。
    public Document Document
    {
        get { return this._document ?? GetDocument(); }
    }
    

    或其他?

    如果我应该从单个 View 模型的构造函数中调用它,我该怎么做?我不能在构造函数上使用异步,也不能在属性上设置异步。

    在处理 MVVM 时,对 Web 服务进行异步调用的最佳方法是什么。
  • 同样,我不确定哪个是最好的:
  • 4.1 显示某种进度条,请求所有4个请求并等待它们全部完成然后隐藏进度条
  • 4.2 在每个单独的 View 中显示某种进度条,并在每个请求完成时相应地隐藏它们
  • 最后一个问题……挂了。我已经准备了很多关于异步和挂起的文章,但它们总是描述处理点击事件时的问题,但是当你没有点击事件但当你想调用时,我不明白如何处理这个问题这是在初始化 View 模型时。如果您知道如何,请您解释并提供一个简单的示例。
  • 最佳答案

    有不同的问题需要牢记:

  • 代码结构。通常,您希望限制 View 和 View 模型的范围,以获得模块化结构。 (这也称为封装。)
  • 用户体验响应能力。您不想让用户等待,如果他们必须等待,则向他们显示进度条/状态指示器。
  • 数据使用。用户可能正在使用数据连接,因此您希望对数据使用保持谨慎。

  • 所以,问题是:
  • 立即加载所有数据,或
  • 仅当用户滑动到给定 View 时才加载

  • 提出了#2 和#3 之间的权衡。这真的是一个判断电话,取决于您希望应用程序具有什么样的感觉。

    I'm not sure whether I should make all the asynchronous call from PivotMainViewModel or from each individual viewmodel defined for each of the pivot item



    我确实认为上面的#1 暗示了后者——为了封装,如果可能,每个 View 模型都应该拥有自己的数据。

    编辑 要在属性上使用异步,您必须使用 setter,而不是 getter。 Hook 到 View 模型的“初始化”事件(或类似事件):
    public Document Document
    {
        get { return this._document; }
        set
        {
            if (this._document == value)
                return;
            this._document = value;
            RaisePropertyChanged("Document");
        }
    }
    
    public async Task<Document> GetDocument
    {
        // ...
    }
    
    private async Task LoadData()
    {
        Document = GetDocument();
    }
    
    public void Initialize() 
    {
        LoadData();
    }
    

    关于c# - 何时以及如何在 Windows Phone wp8 中的 ViewModel 中调用异步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22129698/

    相关文章:

    c# - 为什么 MS 在新的 Windows 应用商店应用模板中去掉了 BindableBase?

    c# - 如何在启动时更改起始页?

    silverlight - 如何使用ScrollViewer.ScrollToVerticalOffset?

    android - android数据绑定(bind)的优缺点是什么?

    macos - 是否可以直接在 OS X 中运行 Windows Phone 8 模拟器?

    c# - 如何在DataContext类中公开DataContext?

    c# - 如何在OnRemoteFailure属性上传递相关ID

    c# - 为什么迭代器 (.Net) 在此代码中不可靠

    java - 在屏幕中的不同 Fragment 之间共享一个 ViewModel 实例

    c# - Xamarin Forms 观看来自 .xaml.cs 类的 ViewModel 属性