C# 我正在尝试使用自定义 类 创建 Web 用户控件,但我得到一个对象未​​设置为对象错误的实例

C# I'm trying to create a web user control with custom classes, and I am getting a Object not set to an instance of an Object Error

我希望你能帮我解决这个问题。我正在创建一个内部网络表单 asp.net 网站来显示不同类别的内部使用文档列表。

我决定创建一个自定义文档 class 以放入一个列表来保存文档,然后创建一个自定义 Web 用户控件以将文档显示在网站上他们想要的任何位置。

文档 class 在我的 App_Code 文件夹中的一般 class 文件中。

cabinet.cs

public class Document
{
    private string _Url;
    private string _Title;
    public Document(string URL, string Title)
    {
        _Url = URL;
        _Title = Title;
    }

    public string URL
    {
        get { return _Url; }
        set { _Url = value; }
    }

    public string Title
    {
        get { return _Title; }
        set { _Title = value; }
    }
}

这段代码工作得很好。然后在我的用户控件中创建一个文档类型列表并在 Page_Load() 中启动它。然后我创建了一个 public 方法来将新文档添加到列表中。

DocDisplay.ascx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class DocDisplay : System.Web.UI.UserControl
{
    private List<Document> _DocList;

    protected void Page_Load(object sender, EventArgs e)
    {
        _DocList = new List<Document>();
    }

    public void Add(string URL, string Title)
    {
        _DocList.Add(new Document(URL, Title));
    }

    public void WriteDocuments()
    {
        foreach (Document doc in _DocList)
        {
            Response.Write($"<span class='document'><a href='{doc.URL}'>{doc.Title}</a></span>");
        }
    }
}

我在添加方法中遇到错误。它说我的对象不是对象的实例。但我在 Page_Load.

中这样做

index.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
    pageDocs.Add("index.aspx", "Hello World!");
    pageDocs.Add("index.aspx", "Red Rum");
    pageDocs.Add("index.aspx", "Lorum Ipsum");
}

我已经在我的索引页中注册了我的用户控件。

<%@ Register Src="~/DocDisplay.ascx" TagPrefix="uc" TagName="DocDisplay" %>

<uc:DocDisplay ID="pageDocs" runat="server" />

所以我不太确定为什么会出现该错误。据我所知,我的代码没有任何问题。如果您能提供帮助,我将不胜感激。

事件从控制层次结构的根部开始,到叶节点结束。 Index.Page_LoadDocDisplay.Page_Load 有机会实例化列表之前被调用。

_DocList 字段需要一个值才能被任何东西使用,因此初始化需要尽早进行。使用字段初始化器可以很容易地完成此操作。一次声明并分配它:

private List<Document> _DocList = new List<Document>();

Index class 在页面生命周期的早期实例化其子控件时,_DocList 将立即拥有一个对象引用。

很想说,“Page_Init 很快就会被叫到;我会在那里做。”起初这可能有效,但如果您执行 any 动态控件加载,您很快就会发现这是一种平衡行为。动态加载的控件必须进行事件追赶,因此可以在静态加载的控件开始触发 Load 事件后触发其 Init 事件。重要的是将每个事件用于其目的,而不是时间,并使用构造函数(和字段初始化器)来初始化非控制 class 状态。