c#如何正确使用Page_init,ViewState和Page_Load?

时间:2017-07-12 08:34:24

标签: c# asp.net viewstate pageload

我现在已经使用Web Forms了一段时间,我已经在谷歌上阅读了大部分关于此的内容。但是,我仍然不清楚如何正确使用它。我喜欢this answer中的图片,但发现它有点过于通用。关于如何处理这些事件,我没有找到一个体面的具体例子。

我目前正在Page_Load事件中的代码中动态创建多个控件:

foreach (Service service in Services)
{
    // service div
    HtmlGenericControl serviceDiv = new HtmlGenericControl("div");
    serviceDiv.ID = service.ID;
    serviceDiv.Style.Add(HtmlTextWriterStyle.TextAlign, "center");
    outerDiv.Controls.Add(serviceDiv); //outerDiv exists in the aspx page

    // service updatepanel
    UpdatePanel uPanel = new UpdatePanel()
    {
        ID = service.ID + "_uPanel",
        UpdateMode = UpdatePanelUpdateMode.Conditional
    };
    serviceDiv.Controls.Add(uPanel);

    // status span
    HtmlGenericControl statusSpan = new HtmlGenericControl("span");
    statusSpan.ID = service.ID + "_statusSpan";
    statusSpan.InnerHtml = service.Status;
    uPanel.ContentTemplateContainer.Controls.Add(statusSpan);

    // show specific content
    if (service.Status.Equals(ServiceControllerStatus.Running.ToString()))
    {
        // status color
        statusSpan.Attributes.Add("class", "status-run");

        // stop button
        HtmlButton stopButton = new HtmlButton();
        stopButton.ID = service.ID + "_btnStop";
        stopButton.InnerHtml = "<i class=\"fa fa-stop btn-red\"/></i>";
        stopButton.Attributes.Add("type", "button");
        stopButton.Attributes.Add("runat", "server");
        stopButton.Attributes.Add("class", "btn btn-link btn-xs");
        stopButton.Attributes.Add("title", "Stop");
        stopButton.ServerClick += new EventHandler(BtnStop_Click);
        ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(stopButton);
        uPanel.ContentTemplateContainer.Controls.Add(stopButton);

        // restart button
        HtmlButton restartButton = new HtmlButton();
        restartButton.ID = service.ID + "_btnRestart";
        restartButton.InnerHtml = "<i class=\"fa fa-refresh btn-blue\"/></i>";
        restartButton.Attributes.Add("type", "button");
        restartButton.Attributes.Add("runat", "server");
        restartButton.Attributes.Add("class", "btn btn-link btn-xs");
        restartButton.Attributes.Add("title", "Restart");
        restartButton.ServerClick += new EventHandler(BtnRestart_Click);
        ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(restartButton);
        uPanel.ContentTemplateContainer.Controls.Add(restartButton);
    }
    else
    {
        // status color
        statusSpan.Attributes.Add("class", "status-stop");

        // start button
        HtmlButton startButton = new HtmlButton();
        startButton.ID = service.ID + "_btnStart";
        startButton.InnerHtml = "<i class=\"fa fa-play btn-green\"/></i>";
        startButton.Attributes.Add("type", "button");
        startButton.Attributes.Add("runat", "server");
        startButton.Attributes.Add("class", "btn btn-link btn-xs");
        startButton.Attributes.Add("title", "Start");
        startButton.ServerClick += new EventHandler(BtnStart_Click);
        ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(startButton);
        uPanel.ContentTemplateContainer.Controls.Add(startButton);
    }

    // version span
    HtmlGenericControl versionSpan = new HtmlGenericControl("span");
    versionSpan.ID = service.ID + "_version";
    versionSpan.InnerHtml = service.Version;
    versionSpan.Attributes.Add("class", "version-text");
    serviceDiv.Controls.Add(versionSpan);

在Page_Init中创建这些内容我会得到什么?如果我在Page_Init中创建它们,我如何在Page_Load中访问它们? UpdatePanelHtmlButton的私人全球列表感觉非常不洁净。

我知道ViewState在Page_Init和Page_Load之间加载,但这究竟意味着什么?由于我不做完整的回发,而是使用RegisterAsyncPostBackControl仅在回发时更新UpdatePanel,我不需要在Page_Load中重新填充?

1 个答案:

答案 0 :(得分:2)

如果您不需要ViewState,则还可以在Page_Load中创建控件。 ViewState用于存储控件的值(取决于控件的值),并在PostBack发送到服务器时使用它们。

例如,如果您有一个文本框,则PostBack包含文本框的新值以及ViewState中的旧值。 ASP.NET框架现在比较这两个,并在必要时引发TextChanged事件。没有ViewState,这是不可能的。

对于ASP.NET WebForms中动态创建的控件,您可以提供的最佳建议是避免使用它们。它们非常快速地增加复杂性并且通常不是必需的(即使它最初看起来如此)。

在大多数情况下,有一种更简单的方法,例如通过使用中继器。在您的情况下,您有一个服务列表。您可以将此列表绑定到Repeater,并避免手动创建控件。有关如何使用Repeater的信息,请参阅此link

使用Repeater的另一个好处是,您可以在ASPX标记中而不是在代码隐藏文件中定义UI。在您的示例中,您可以根据服务的状态更改UI。在这种情况下,使用Repeater的ItemDataBound - 事件可能是一个不错的选择。