控制生命周期中的什么时候Control.Visible停止渲染?

The*_*beg 7 c# asp.net

我正在尝试编写一个简单的实用程序webcontrol来显示网页内的单行消息 - 状态更新,错误消息等.通过调用webcontrol上的方法,消息将来自页面上的其他控件.如果控件在预渲染时没有任何消息,我不希望它在页面上呈现 - 我希望它设置Control.Visible = false.这似乎只适用于非回发渲染.这是我正在使用的代码:

public class MessageList : WebControl
{

#region inner classes

    private struct MessageItem
    {
        string Content, CssClass;

        public MessageItem(string content, string cssClass)
        {
            Content = content;
            CssClass = cssClass;
        }

        public override string ToString()
        { return "<li" + (String.IsNullOrEmpty(CssClass) ? String.Empty : " class='" + CssClass + "'") + ">" + Content + "</li>"; }
    }

    private class MessageQueue : Queue<MessageItem> { }

#endregion

#region fields, constructors, and events

    MessageQueue queue;

    public MessageList() : base(HtmlTextWriterTag.Ul)
    {
        queue = new MessageQueue();
    }

    protected override void OnLoad(EventArgs e)
    {
        this.Controls.Clear();
        base.OnLoad(e);
    }

    protected override void OnPreRender(EventArgs e)
    {
        this.Visible = (queue.Count > 0);

        if (this.Visible)
        {
            while (queue.Count > 0)
            {
                MessageItem message = queue.Dequeue();
                this.Controls.Add(new LiteralControl(message.ToString()));
            }
        }

        base.OnPreRender(e);
    }

#endregion

#region properties and methods

    public void AddMessage(string content, string cssClass)
    { queue.Enqueue(new MessageItem(content, cssClass)); }

    public void AddMessage(string content)
    { AddMessage(content, String.Empty); }

#endregion

}
Run Code Online (Sandbox Code Playgroud)

我也尝试将检查放在CreateChildControls中,结果相同.

The*_*beg 5

我实际上是自己想出来的,我认为答案对社区有用.

看起来像Control.Visible设置为false的控件实际上在Page_Load事件之后的某个时间停止.这里的技巧是将Control.Visible属性加载到ViewState中.因此,如果第一页命中没有消息,则控件将自身设置为Visible = false,并且永远不会再次到达CreateChildControls或OnPreRender.

解决方案是重置控件在未跳过的早期事件之一中的可见性.以下更改解决了我的问题:

protected override void OnLoad(EventArgs e)
{
--> this.Visible = true;
    this.Controls.Clear();
    base.OnLoad(e);
}
Run Code Online (Sandbox Code Playgroud)

  • 我使用OnPreRender进行了测试,并且事件没有像你所说的那样被调用,我从未想过它,但我想如果控件设置为Visible = False则没有任何东西可以渲染. (2认同)

Man*_*dra 3

不要修改“Visible”属性,而是尝试以下操作:

    protected override void Render(HtmlTextWriter writer)
    {
        if (queue.Count > 0)
            base.Render(writer);
    }
Run Code Online (Sandbox Code Playgroud)