使用.NET7和Blazor服务器,我正在try 使用消息组件和List<Message>作为类库来构建消息查看器,以便在我的环境中的所有应用程序中重复使用.除了可以从列表中删除消息组件之外,一切都运行得很好.Message Razor类如下所示

@namespace TestApp.Components

@if(MessageText!=null){
    <div class="mt-3 @MessageClass">
        @MessageText
        <button class="btn-close" @onclick="CloseMessage">Close</button>
    </div>
}

代码后面的相关部分如下所示:

using Microsoft.AspNetCore.Components;

namespace TestApp.Components;
public partial class Message : ComponentBase
{
    public string MessageText {get;set;} = string.Empty;
    public string MessageClass {get;set;} = string.Empty;
    public Guid MessageId {get;set;} = new Guid();
    [Parameter] public Message Origin {set{
        MessageText=value.MessageText;
        MessageClass=value.MessageClass;
        MessageId=value.MessageId;
    }}
    public Message(){

    }
    public Message(string message){
        MessageText=message;
    }
    public event EventHandler CloseRequested=default!;

    private void CloseMessage()
    {
        CloseRequested(this,EventArgs.Empty);
    }
}

然后在保存每个用户的消息列表的应用程序状态类中引用所有这些消息,直到它们被清除.该代码看起来像

using TestApp.Components;

public class ApplicationState
{
    public List<Message> Messages {get;set;} = new();
    public event EventHandler OnMessagesChange = default!;

    public void AddMessage(string messageText)
    {
        var message = new Message(messageText);
        Messages.Add(message);
        EventHandler handler = OnMessagesChange;
        if(handler!=null)
            handler.Invoke(this,EventArgs.Empty);
        message.CloseRequested+=RemoveMessage;
    }

    private void RemoveMessage(object sender, EventArgs e)
    {
        var message = (Message?)sender;
        if(message!=null)
            Messages.Remove(message);
    }
}

当我单击按钮删除消息时,我得到错误System.NullReferenceException: Object reference not set to an instance of an object.,我认为这意味着EventHandler已初始化,但我不能确定why并非如此,因为ApplicationState类订阅了该事件,因此它应该是可调用的.

我try 在CloseMessage方法中判断事件处理程序为空,并将事件处理程序设置为=default!;,但没有成功.任何帮助都将不胜感激.

推荐答案

你有

  var message = new Message(messageText); // new() of a Component
  ...
  message.CloseRequested+=RemoveMessage;

...剃刀页面中的Foreach循环.在该循环中,它使用带有Origin属性的组件来设置值.

This means that you have 2 Components for each message: 1 in the list, with the event set 和 1 created by the foreach loop. You copy the properties but not the event.

The instance from the foreach loop will be the one shown, 和 that has eventCloseRequested == null

The solution is to split this in a MessageComponent : ComponentBase 和 a MessageViewModel. Then it is at least clearer what is going on.

I leave the event h和ling open, there are many ways to do that. But you'll also want to update the parent page when you remove a message. So I would add an EventCallback param to the component 和 assign an update method on that page.

Csharp相关问答推荐

如果没有中间变量,可空引用类型将无法工作

O(N)测试失败

在Linq中调用需要limit和offset的方法''''

如何从泛型方法返回一个可为空的T,其中T:notnull?

如何使用XmlSerializer反序列化字符串数组?

实现List T,为什么LINQ之后它不会返回MyList?<>(无法强制转换WhereListIterator `1类型的对象)'

HttpConext.Request.Path和HttpConext.GetEndpoint()之间的差异

为具有实体框架后端的Reaction项目 Select 正确的Visual Studio模板

C#和ASP.NET核心标识:提高GetUserAsync调用的性能

TeamsBot SendActivityActivityTypes与ActivityTypes同步.键入不再起作用

当我没有此令牌时,为什么语法报告EOF错误?

该函数不能检测两条曲线的交点

C#自定义验证属性未触发IsValid方法

异步任务调用程序集

如何更改新创建的实例的变量?

未在Windows上运行的Maui项目

如何在特定环境中运行dotnet测试?

我是否应该注销全局异常处理程序

在C#中删除多个不同名称的会话

身份验证中间件如何处理多个方案