65.9K
CodeProject 正在变化。 阅读更多。
Home

异步 Xamarin Forms MVVM 模型

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.84/5 (8投票s)

2016 年 6 月 29 日

CPOL

1分钟阅读

viewsIcon

25272

Xamarin Forms 的异步 MVVM 模型模板

引言

本文介绍 Xamarin Forms 的异步 MVVM 模型。

背景

在使用 Xamarin Forms 时,我遇到的问题是在首次页面加载时进行异步操作。我们不能正确地在构造函数中使用 async,所以我需要的是页面加载后的异步调用。我想到了一个方法,它运行良好,我想分享一下。希望你喜欢。

我会从头开始编写所有内容。以下是我使用的当前版本:

  • Visual Studio 2015 Community Edition
  • Xamarin for Visual Studio (4.1.1)

Using the Code

让我们创建一个项目并添加我们的基础模型并使用它。这只需要三个步骤。

你可以在 GitHub 上查看源代码。

1. 创建一个新的 Xamarin Forms 项目 (Xaml App)

现在我们准备好了。

2. 创建基础模型

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace AsyncTest.Models
{
    internal abstract class BaseModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

对于异步操作,这个基础模型需要知道它绑定到哪个页面。所以让我们添加它

protected Page CurrentPage { get; private set; }

现在,我们需要一个初始化器

public void Initialize(Page page)
{
    CurrentPage = page;

    CurrentPage.Appearing += CurrentPageOnAppearing;
    CurrentPage.Disappearing += CurrentPageOnDisappearing;
}

完整的代码如下:

using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Xamarin.Forms;

namespace AsyncTest.Models
{
    internal abstract class BaseModel : INotifyPropertyChanged
    {
        protected Page CurrentPage { get; private set; }

        public event PropertyChangedEventHandler PropertyChanged;

        public void Initialize(Page page)
        {
            CurrentPage = page;

            CurrentPage.Appearing += CurrentPageOnAppearing;
            CurrentPage.Disappearing += CurrentPageOnDisappearing;
        }

        protected virtual void CurrentPageOnAppearing(object sender, EventArgs eventArgs) {}

        protected virtual void CurrentPageOnDisappearing(object sender, EventArgs eventArgs) {}

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

如你所见,基础模型将页面作为属性,并为 "Appearing" 和 "Disappearing" 事件创建虚拟方法。如果你需要其他事件,只需将它们作为 virtual 方法添加即可。

3. 创建页面并使用它

我们已经有 "MainPage.xaml",所以让我们使用它。

首先,我们需要一个页面的模型。

namespace AsyncTest.Models
{
    internal class MainModel : BaseModel {}
}

我将使用 http://jsonplaceholder.typicode.com/ 进行测试。

using System;
using System.Net.Http;

namespace AsyncTest.Models
{
    internal class MainModel : BaseModel
    {
        private string _responseText;

        public string ResponseText
        {
            get { return _responseText; }
            set
            {
                _responseText = value;
                OnPropertyChanged();
            }
        }

        protected override async void CurrentPageOnAppearing(object sender, EventArgs eventArgs)
        {
            ResponseText = "Loading, please wait...";
            
            try
            {
                // Wait for testing...
                await Task.Delay(TimeSpan.FromSeconds(3));
                
                using (var client = new HttpClient())
                {
                    var responseMessage = await client.GetAsync
                                          ("http://jsonplaceholder.typicode.com/posts/1");

                    if (responseMessage.IsSuccessStatusCode)
                        ResponseText = await responseMessage.Content.ReadAsStringAsync();
                    else
                        ResponseText = $"StatusCode: {responseMessage.StatusCode}";
                }
            }
            catch (Exception exception)
            {
                ResponseText = exception.ToString();
            }
        }
    }
}

我喜欢设计器中的智能感知,所以我将模型添加到设计器中。

<?xml version="1.0" encoding="utf-8"?>

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:models="clr-namespace:AsyncTest.Models;assembly=AsyncTest"
             x:Class="AsyncTest.MainPage">

    <ContentPage.BindingContext>
        <models:MainModel />
    </ContentPage.BindingContext>

    <ContentPage.Content>
        <Label Text="{Binding ResponseText}" />
    </ContentPage.Content>

</ContentPage>

现在我们必须告诉模型这个页面,以便它初始化事件。

using AsyncTest.Models;

namespace AsyncTest
{
    public partial class MainPage
    {
        public MainPage()
        {
            InitializeComponent();
            ((BaseModel) BindingContext).Initialize(this);
        }
    }
}

完成了。按下 F5 并享受吧!

© . All rights reserved.