mvvmcross Viewmodel.Initialize 在你挂钩 InitializeTask.PropertyChanged 之前被触发
mvvmcross Viewmodel.Initialize is fired before you can hook InitializeTask.PropertyChanged
在我的应用程序中,我想在视图中知道初始化何时完成。问题是它在您挂钩 InitializeTask.PropertyChanged 之前就已启动。这是我的 ViewModel 代码:
public override async Task Initialize()
{
ClientID = await MyDataSource.GetClientID();
}
在我看来,我正在做以下事情:
protected override void OnViewModelSet()
{
var vm = this.DataContext as MyViewModel;
vm.InitializeTask.PropertyChanged += InitializeTask_PropertyChanged;
base.OnViewModelSet();
}
private void InitializeTask_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsSuccessfullyCompleted")
{
vm.InitializeTask.PropertyChanged -= InitializeTask_PropertyChanged;
if (vm.ClientID != "")
posClient = new PosClient(this, vm.ClientID);
}
}
据我所知,OnViewModelSet 是您访问视图中的 ViewModel 最快的方法。如果我放置断点,Initialize 在 OnViewModelSet 被触发之前运行。这使得 Initialize 很可能在您挂钩事件之前就已经完成。 View 中是否还有其他地方可以在 Initialize 开始之前挂接事件,以便保证 Initialize.PropertyChanged 会在 View 中触发?
**** 更新 ****
我听从了@fmaccaroni 的建议并实现了一个名为 DataLoaded 的 MvxInteraction。我做的不同的一件事是创建一个单独的函数来加载数据。
public void LoadData()
{
Task.Run(async () =>
{
ClientID = await IHSDataSource.GetClientID();
_DataLoaded.Raise();
});
}
我担心在连接交互事件之前完成异步任务。这样做,我在视图中添加了它。
protected override void OnViewModelSet()
{
vm = this.DataContext as InvoiceViewModel;
var set = this.CreateBindingSet<InvoiceView, InvoiceViewModel>();
set.Bind(this).For(view => view.DataLoaded).To(viewModel => viewModel.DataLoaded).OneWay();
set.Apply();
vm.LoadData();
base.OnViewModelSet();
}
这样,在我确定结果会触发交互并且我保证得到结果之前,LoadData 不会启动。这是我第一次听说 MvxInteraction,现在我一直在使用它。
我不确定你想要实现什么,但是如果你想在 Initialize
结束时在你的视图中采取行动,只需执行 MvxInteraction 并在你的 [= 之后调用它14=],即:
视图模型:
private MvxInteraction _interaction = new MvxInteraction();
public IMvxInteraction MyMvxInteraction => _interaction;
public override async Task Initialize()
{
ClientID = await MyDataSource.GetClientID();
this._interaction.Raise();
}
查看:
private IMvxInteraction _interaction;
public IMvxInteraction MyMvxInteraction
{
get => this._interaction;
set
{
if (this._interaction != null)
this._interaction.Requested -= this.OnInteractionRequested;
this._interaction = value;
this._interaction.Requested += this.OnInteractionRequested;
}
}
private void OnInteractionRequested(object sender, EventArgs e)
{
var vm = this.DataContext as MyViewModel;
if (vm.ClientID != "")
posClient = new PosClient(this, vm.ClientID);
}
和视图中的绑定:
var set = this.CreateBindingSet<MyView, MyViewModel>();
set.Bind(this).For(view => view.MyMvxInteraction).To(viewModel => viewModel.MyMvxInteraction).OneWay();
set.Apply();
在我的应用程序中,我想在视图中知道初始化何时完成。问题是它在您挂钩 InitializeTask.PropertyChanged 之前就已启动。这是我的 ViewModel 代码:
public override async Task Initialize()
{
ClientID = await MyDataSource.GetClientID();
}
在我看来,我正在做以下事情:
protected override void OnViewModelSet()
{
var vm = this.DataContext as MyViewModel;
vm.InitializeTask.PropertyChanged += InitializeTask_PropertyChanged;
base.OnViewModelSet();
}
private void InitializeTask_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsSuccessfullyCompleted")
{
vm.InitializeTask.PropertyChanged -= InitializeTask_PropertyChanged;
if (vm.ClientID != "")
posClient = new PosClient(this, vm.ClientID);
}
}
据我所知,OnViewModelSet 是您访问视图中的 ViewModel 最快的方法。如果我放置断点,Initialize 在 OnViewModelSet 被触发之前运行。这使得 Initialize 很可能在您挂钩事件之前就已经完成。 View 中是否还有其他地方可以在 Initialize 开始之前挂接事件,以便保证 Initialize.PropertyChanged 会在 View 中触发?
**** 更新 ****
我听从了@fmaccaroni 的建议并实现了一个名为 DataLoaded 的 MvxInteraction。我做的不同的一件事是创建一个单独的函数来加载数据。
public void LoadData()
{
Task.Run(async () =>
{
ClientID = await IHSDataSource.GetClientID();
_DataLoaded.Raise();
});
}
我担心在连接交互事件之前完成异步任务。这样做,我在视图中添加了它。
protected override void OnViewModelSet()
{
vm = this.DataContext as InvoiceViewModel;
var set = this.CreateBindingSet<InvoiceView, InvoiceViewModel>();
set.Bind(this).For(view => view.DataLoaded).To(viewModel => viewModel.DataLoaded).OneWay();
set.Apply();
vm.LoadData();
base.OnViewModelSet();
}
这样,在我确定结果会触发交互并且我保证得到结果之前,LoadData 不会启动。这是我第一次听说 MvxInteraction,现在我一直在使用它。
我不确定你想要实现什么,但是如果你想在 Initialize
结束时在你的视图中采取行动,只需执行 MvxInteraction 并在你的 [= 之后调用它14=],即:
视图模型:
private MvxInteraction _interaction = new MvxInteraction();
public IMvxInteraction MyMvxInteraction => _interaction;
public override async Task Initialize()
{
ClientID = await MyDataSource.GetClientID();
this._interaction.Raise();
}
查看:
private IMvxInteraction _interaction;
public IMvxInteraction MyMvxInteraction
{
get => this._interaction;
set
{
if (this._interaction != null)
this._interaction.Requested -= this.OnInteractionRequested;
this._interaction = value;
this._interaction.Requested += this.OnInteractionRequested;
}
}
private void OnInteractionRequested(object sender, EventArgs e)
{
var vm = this.DataContext as MyViewModel;
if (vm.ClientID != "")
posClient = new PosClient(this, vm.ClientID);
}
和视图中的绑定:
var set = this.CreateBindingSet<MyView, MyViewModel>();
set.Bind(this).For(view => view.MyMvxInteraction).To(viewModel => viewModel.MyMvxInteraction).OneWay();
set.Apply();