OnPropertyChanged 在 Blazor(MAUI 混合)中无法正常工作

问题描述 投票:0回答:1

我已在 MauiProgram.cs 中注册了一项服务:

builder.Services.AddSingleton<NetworkStatusService>();

服务等级:

public class NetworkStatusService : INotifyPropertyChanged
{
    private NetwStatus _netwStat;
    public NetwStatus NetwStat
    {
        get => _netwStat;
        set
        {
            if (_netwStat != value)
            {
                _netwStat = value;
                OnPropertyChanged(nameof(NetwStat));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public async Task CheckNetw()
    {
        NetwStat = NetwStatus.Loading;

        await Task.Delay(1000);

        if (await SomeClass.CheckDBConnection())
            NetwStat = NetwStatus.Success;
        else
            NetwStat = NetwStatus.Fail;
    }
}

我的简化 blazor 页面如下:

@page "/LoginComponent"
<div class="Grid">
    @switch (NetworkStatusService.NetwStat)
    {
        case NetwStatus.Loading:
            <h6 style="font-size:0.8rem; margin-bottom:-12px; color:coral">Trying to connect...</h6>
            break;
        case NetwStatus.Success:
            <h6 style="font-size:0.8rem; margin-bottom:-12px; color:green">Connected uccessfully.</h6>
            break;
        case NetwStatus.Fail:
            <h6 style="font-size:0.8rem; margin-bottom:-12px; color:red">Connection failed.</h6>
            break;
        default:
            break;
    }    ‌ ‌
    <i @onclick="ViewModel.btnNetwOkCommand.ExecuteAsync">refresh</i>
</div>

该命令显然会运行 NetworkStatusService.CheckNetw()

但它永远不会更改为“尝试连接...”模式。它只是等待并改变成功或失败。这太令人沮丧了,我开始讨厌我的职业。

c# blazor maui inotifypropertychanged propertychanged
1个回答
0
投票

这正是 INotifyPropertyChanged 与 Blazor 配合不佳的原因。此行相当于

async void
:

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

由于您不(不能)等待它,因此渲染与程序流断开连接。

在 OnPropertyChanged() 中,您必须调用 StateHasChanged() 但这是页面的受保护方法。这意味着您将需要一些丑陋的 IView 耦合来交给 ViewModel。以及用于设置它的管道。

© www.soinside.com 2019 - 2024. All rights reserved.