C# 调用状态更改后,不会重新呈现组件

C# 调用状态更改后,不会重新呈现组件,c#,asp.net-core,.net-core,blazor,C#,Asp.net Core,.net Core,Blazor,我读过“”这篇文章,并尝试着这样做。 我在@body下有消息组件,根据@body组件中的用户操作,消息必须更改 @inject ClientMessage clientMessage @inherits LayoutComponentBase @using Site.Shared.Components <div class="sidebar"> <AdminMenu /> </div> <div class="main"> <di

我读过“”这篇文章,并尝试着这样做。 我在@body下有消息组件,根据@body组件中的用户操作,消息必须更改

@inject ClientMessage clientMessage
@inherits LayoutComponentBase
@using Site.Shared.Components

<div class="sidebar">
<AdminMenu />
</div>

<div class="main">
    <div class="content px-4">
        @Body
    </div>
   <Message/>
</div>

@code
{
    protected async Task ChangeState()
    {
        await InvokeAsync(StateHasChanged);
    }

    protected override void OnInitialized()
    {
        clientMessage.MsgChange += ChangeState;
    }
 }
@inject ClientMessage ClientMessage
@继承LayoutComponentBase
@使用Site.Shared.Components
@身体
@代码
{
受保护的异步任务ChangeState()
{
等待调用同步(StateHasChanged);
}
受保护的覆盖无效OnInitialized()
{
clientMessage.MsgChange+=ChangeState;
}
}
消息组件:

@inject ClientMessage clientMessage
<div style="@(IsVisble ? "display:block" : "display:none")" class="@MsgClass" role="alert">
    @if (clientMessage != null)
    {
        @clientMessage.Message
    }
</div>

@code {

    public bool IsVisble
    {
        get
        {
            if (string.IsNullOrEmpty(@clientMessage.Message))
            {
                return false;
            }

            return true;
        }
    }

    public string MsgClass
    {
        get
        {
            if (clientMessage == null)
            {
                return string.Empty;
            }

            string msgClass;

            switch (clientMessage.MsgType)
            {
                case EMsgType.Info:
                    msgClass = "alert alert-info";
                    break;
                case EMsgType.Success:
                    msgClass = "alert alert-success";
                    break;
                case EMsgType.Warning:
                    msgClass = "alert alert-warning";
                    break;
                case EMsgType.Error:
                    msgClass = "alert alert-danger";
                    break;
                case EMsgType.NoMsg:
                default:
                    msgClass = string.Empty;
                    break;
            }

            return msgClass;
        }
    }
}
@inject ClientMessage ClientMessage
@if(clientMessage!=null)
{
@clientMessage.Message
}
@代码{
公众视野
{
得到
{
if(string.IsNullOrEmpty(@clientMessage.Message))
{
返回false;
}
返回true;
}
}
公共字符串MsgClass
{
得到
{
if(clientMessage==null)
{
返回字符串。空;
}
字符串msgClass;
开关(clientMessage.MsgType)
{
案例EMsgType.Info:
msgClass=“警报信息”;
打破
案例EMsgType.成功:
msgClass=“警报成功”;
打破
案例EMsgType.警告:
msgClass=“警报”;
打破
案例EMsgType。错误:
msgClass=“警惕危险”;
打破
案例EMsgType.NoMsg:
违约:
msgClass=string.Empty;
打破
}
返回msgClass;
}
}
}
消息类

public class ClientMessage
{
    public event Func<Task> MsgChange;

    public ClientMessage(string msg, EMsgType msgType)
    {
        this.Message = msg;
        this.MsgType = msgType;
        NotifyStateChanged();
    }

    public void SetMsg(string msg, EMsgType msgType)
    {
        this.Message = msg;
        this.MsgType = msgType;
        NotifyStateChanged();
    }

    public string Message { get; set; }

    public EMsgType MsgType { get; set; }

    private void NotifyStateChanged()
    {
        if (MsgChange != null)
        {
            MsgChange.Invoke();
        }
    }
}
公共类ClientMessage
{
公共活动职能变更;
公共客户端消息(字符串消息,EMsgType msgType)
{
this.Message=msg;
this.MsgType=MsgType;
NotifyStateChanged();
}
public void SetMsg(字符串msg,EMsgType msgType)
{
this.Message=msg;
this.MsgType=MsgType;
NotifyStateChanged();
}
公共字符串消息{get;set;}
公共EMsgType MsgType{get;set;}
私有void NotifyStateChanged()
{
if(MsgChange!=null)
{
MsgChange.Invoke();
}
}
}
ClientMessage类由DI作为单例注入。如果我在@body components中调用SetMsg(newMsgm,msgType),那么会调用ChangeState()方法,但什么都没有发生,我的意思是组件不会重新呈现。如果我改为“InvokeAsync”使用“Invoke”我有一个错误“当前线程与调度程序不关联。在触发呈现或组件状态时,使用InvokeAsync()将执行切换到调度程序。”。如果我重新加载页面,我可以看到消息


我做错了什么?如何强制重新呈现消息组件?

我解决了这个问题。也许它会帮助别人

我本地化了问题-当在NavigationManager.NavigateTo(“某些页面”)被调用后@body被更改时,StateHasChanged()不会重新呈现消息组件。我尝试了不同的地方,在那里我可以启动StateHasChanged(),如果我将它移动到Message.razor,它将按预期工作


它比articles:)

您的消息组件没有参数,因此Blazor将假定它是静态的。如果将主布局的
code
部分移动到消息组件,则每当消息更改时,它都会重新呈现自身。您还应该实现IDisposable,这样您就可以取消订阅MsgChange事件,以确保完整性。文档是值得的。