构造Xamarin页面时获取数据的最佳方法是什么?

时间:2019-05-12 17:34:06

标签: c# xamarin mvvm xamarin.forms

我正在构建一个与BLE设备通信的Xamarin应用。目前,我正在构建类似“文件资源管理器”的工具;我有一个页面,其中包含可从设备下载的3种“文件类型”的列表视图;当点击一个项目时,我想创建一个新页面(使用Navigation.PushAsync()),其中包含从设备中提取的文件列表。我正在使用在其构造函数中创建并绑定到其viewmodel的页面来实现它,但是我无法在构造函数中调用异步方法来下载数据。

这是设计不良还是在创建ViewModel期间有办法开始下载信息?

2 个答案:

答案 0 :(得分:1)

在下载数据ID的同时,您可以打开一个新页面,该页面的活动指示器绑定到YourViewModel的IsBusy属性。

然后,您可以像这样在新任务上开始下载:

public class YourViewModel
{
    private bool isBusy;
    public bool IsBusy
    {
        get => isBusy;
        set => SetProperty(isBusy, value);
    }

    public YourViewModel()
    {
        StartDownload();
    }

    private void StartDownload()
    {
        IsBusy = true;

        Task.Run(ExceptionHandler(async() => 
            {
              // Your download starts here
              // await it
              // and when it came finished:
              Device.BeginInvokeOnMainThread(() => IsBusy = false);
            }));
    }

    private void ExceptionHandler(Action action)
    {
        try
        {
            action?.Invoke();
        }
        catch(Exception ex)
        {
            // Handle exceptions here
        }
    }
}

您可以通过视图模型或类似事件通过事件添加页面组件。

希望对您有帮助。

答案 1 :(得分:0)

作为一种替代方法,您可以在ViewModel中定义一个LoadDataAsync方法,然后从视图的OnAppearing方法中调用它。您必须将其标记为异步:

public class MyView : ContenPage {

    private bool isDataLoaded = false;

    public void MyView {
        BindingContext = new MyViewModel();
    }

    protected async override void OnAppearing(){
        if (!isDataLoaded && BindingContext is MyViewModel vm){
            await vm.LoadDataAsync();
            isDataLoaded = true;
        }
    }
}

请注意isDataLoaded字段:在获取数据后,将其设置为true,以避免在从另一个页面导航时再次获取数据(根据您的应用程序逻辑,这可能有用也可能不会有用)。

然后在ViewModel的LoadDataAsync方法中,您可以将获取数据的代码插入到普通的try / catch块中。