我正在构建一个与BLE设备通信的Xamarin应用。目前,我正在构建类似“文件资源管理器”的工具;我有一个页面,其中包含可从设备下载的3种“文件类型”的列表视图;当点击一个项目时,我想创建一个新页面(使用Navigation.PushAsync()
),其中包含从设备中提取的文件列表。我正在使用在其构造函数中创建并绑定到其viewmodel的页面来实现它,但是我无法在构造函数中调用异步方法来下载数据。
这是设计不良还是在创建ViewModel期间有办法开始下载信息?
答案 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块中。