c# - mvvmcross Viewmodel.Initialize 在您可以挂接 InitializeTask.PropertyChanged 之前被触发

标签 c# android xamarin xamarin.android mvvmcross

在我的应用程序中,我想在 View 中知道初始化何时完成。问题是它在您可以挂接 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 是您在 View 中最快访问 ViewModel 的方法。如果我设置断点,Initialize 将在 OnViewModelSet 触发之前运行。这使得在您可以挂接事件之前初始化很可能已经完成。 View 中是否还有其他位置可以在初始化开始之前 Hook 事件,以便保证 Initialize.PropertyChanged 将在 View 中触发?

**** 更新****

我遵循@fmaccaroni的建议并实现了一个名为DataLoaded的MvxInteraction。我做的不同的一件事是创建一个单独的函数来加载数据。

    public void LoadData()
    {
        Task.Run(async () =>
        {
            ClientID = await IHSDataSource.GetClientID();
            _DataLoaded.Raise();
        });
    }

在连接交互事件之前,我担心异步任务是否完成。通过这种方式,我将其添加到 View 中。

    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 结束时在 View 中执行操作,只需执行 MvxInteraction并在 await 之后调用它,即:

View 模型:

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);
}

以及 View 中的绑定(bind):

var set = this.CreateBindingSet<MyView, MyViewModel>();
set.Bind(this).For(view => view.MyMvxInteraction).To(viewModel => viewModel.MyMvxInteraction).OneWay();
set.Apply();

关于c# - mvvmcross Viewmodel.Initialize 在您可以挂接 InitializeTask.PropertyChanged 之前被触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48586899/

相关文章:

c# - 检查非打字间隔

Android:收到电话时自动录制视频并将生成的电影文件发送到电子邮件地址

c# - "Address already in use"在停止后尝试启动 tcpListener

c# - 如何为搜索查询创建解析器

c# - 将 Attribute with AttributeTargets = Method 应用于类中的所有方法

C#:将字符串转换为 Sbyte*

java - 如何创建不可删除的通知?

java - 在按钮上显示 float

Xamarin Shiny 推送

android - 布局方向改变 RTL LTR