MvvmCross 视图模型初始化完成
MvvmCross View Model Initialize Complete
在 MvvmCross 的第 5 版中,添加了一个异步初始化覆盖,您可以在其中加载大量数据。
public override async Task Initialize()
{
MyObject = await GetObject();
}
有没有办法在View中判断Initialize已经完成?在视图中说我想将工具栏标题设置为在 MyObject
中显示一个字段
MyViewModel vm;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
this.SetContentView(Resource.Layout.MyView);
var toolbar = (Toolbar)FindViewById(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
vm = (MyViewModel)this.ViewModel;
SupportActionBar.Title = vm.MyObject.Name;
}
在设置 SupportActionBar.Title 的那一行,有没有办法确定 Initialize 任务是否已经完成,如果没有,在完成时得到通知?
更新:
我尝试设置两个正确答案,因为@nmilcoff 回答了我的实际问题,@Trevor Balcom 向我展示了一种更好的方法来做我想做的事情。
是的,您可以订阅 InitializeTask 的 属性 更改。
像这样的东西会起作用:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// your code
ViewModel.PropertyChanged += MyViewModel_PropertyChanged;
}
private void MyViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if(e.PropertyName == nameof(ViewModel.InitializeTask) && ViewModel.InitializeTask != null)
{
ViewModel.InitializeTask.PropertyChanged += ViewModel_InitializeTask_PropertyChanged;
}
}
private void ViewModel_InitializeTask_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if(e.PropertyName == nameof(ViewModel.InitializeTask.IsSuccessfullyCompleted))
SupportActionBar.Title = ViewModel.MyObject.Name;
}
当然,也可能只听 ViewModel.MyObject.Name
属性 变化会更容易。但以上是监听 InitializeTask 属性 变化的通用方式。
您可以在 official documentation 中了解有关 InitializeTask
和 MvxNotifyTask
的更多信息。
工具栏还支持 Title
属性 的数据绑定,如下所示:
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:MvxBind="Title MyObject.Name" />
在 Xamarin 表单上:
我想添加 属性 更改虚拟机中的事件登录以便能够对其进行测试,因此:
View.xaml.cs
protected override void OnViewModelSet()
{
base.OnViewModelSet();
var vm = this.DataContext as SearchMovieViewModel;
if (vm is null)
{
return;
}
vm.OnViewModelSet();
}
在您的 ViewModel 上:
/// <summary>
/// This method should be called in every View Code Behind when you
/// need to subscribe to InitializeTask changes.
/// </summary>
public void OnViewModelSet()
{
if (this.InitializeTask is null)
{
return;
}
this.InitializeTask.PropertyChanged += this.InitializeTask_PropertyChanged;
}
最后在你的视图模型上实现你需要为 MvvmCross InitializeTask 做的任何检查,在我的例子中我使用了 IsCompleted 属性,但你可以使用任何你需要的:
private void InitializeTask_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(this.InitializeTask.IsCompleted))
{
// do something
}
}
不要忘记取消订阅,例如当视图被销毁时。您可以在视图模型中覆盖此方法:
public override void ViewDestroy(bool viewFinishing = true)
{
base.ViewDestroy(viewFinishing);
this.InitializeTask.PropertyChanged -= this.InitializeTask_PropertyChanged;
}
在 MvvmCross 的第 5 版中,添加了一个异步初始化覆盖,您可以在其中加载大量数据。
public override async Task Initialize()
{
MyObject = await GetObject();
}
有没有办法在View中判断Initialize已经完成?在视图中说我想将工具栏标题设置为在 MyObject
中显示一个字段 MyViewModel vm;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
this.SetContentView(Resource.Layout.MyView);
var toolbar = (Toolbar)FindViewById(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
vm = (MyViewModel)this.ViewModel;
SupportActionBar.Title = vm.MyObject.Name;
}
在设置 SupportActionBar.Title 的那一行,有没有办法确定 Initialize 任务是否已经完成,如果没有,在完成时得到通知?
更新: 我尝试设置两个正确答案,因为@nmilcoff 回答了我的实际问题,@Trevor Balcom 向我展示了一种更好的方法来做我想做的事情。
是的,您可以订阅 InitializeTask 的 属性 更改。
像这样的东西会起作用:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// your code
ViewModel.PropertyChanged += MyViewModel_PropertyChanged;
}
private void MyViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if(e.PropertyName == nameof(ViewModel.InitializeTask) && ViewModel.InitializeTask != null)
{
ViewModel.InitializeTask.PropertyChanged += ViewModel_InitializeTask_PropertyChanged;
}
}
private void ViewModel_InitializeTask_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if(e.PropertyName == nameof(ViewModel.InitializeTask.IsSuccessfullyCompleted))
SupportActionBar.Title = ViewModel.MyObject.Name;
}
当然,也可能只听 ViewModel.MyObject.Name
属性 变化会更容易。但以上是监听 InitializeTask 属性 变化的通用方式。
您可以在 official documentation 中了解有关 InitializeTask
和 MvxNotifyTask
的更多信息。
工具栏还支持 Title
属性 的数据绑定,如下所示:
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:MvxBind="Title MyObject.Name" />
在 Xamarin 表单上: 我想添加 属性 更改虚拟机中的事件登录以便能够对其进行测试,因此:
View.xaml.cs
protected override void OnViewModelSet()
{
base.OnViewModelSet();
var vm = this.DataContext as SearchMovieViewModel;
if (vm is null)
{
return;
}
vm.OnViewModelSet();
}
在您的 ViewModel 上:
/// <summary>
/// This method should be called in every View Code Behind when you
/// need to subscribe to InitializeTask changes.
/// </summary>
public void OnViewModelSet()
{
if (this.InitializeTask is null)
{
return;
}
this.InitializeTask.PropertyChanged += this.InitializeTask_PropertyChanged;
}
最后在你的视图模型上实现你需要为 MvvmCross InitializeTask 做的任何检查,在我的例子中我使用了 IsCompleted 属性,但你可以使用任何你需要的:
private void InitializeTask_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(this.InitializeTask.IsCompleted))
{
// do something
}
}
不要忘记取消订阅,例如当视图被销毁时。您可以在视图模型中覆盖此方法:
public override void ViewDestroy(bool viewFinishing = true)
{
base.ViewDestroy(viewFinishing);
this.InitializeTask.PropertyChanged -= this.InitializeTask_PropertyChanged;
}