【问题标题】:c# Counter requires 2 button clicks to updatec# Counter 需要点击 2 次按钮才能更新
【发布时间】:2010-05-22 00:12:57
【问题描述】:

我有一个问题困扰了我一整天。

在我的代码中,我有以下内容:

private int rowCount
    {
        get { return (int)ViewState["rowCount"]; }
        set { ViewState["rowCount"] = value; }
    }

还有一个按钮事件

protected void addRow_Click(object sender, EventArgs e)
    {
        rowCount = rowCount + 1;
    }

然后在 Page_Load 我读取该值并相应地创建控件。

我了解按钮事件在 Page_Load 触发后触发,因此在下一次回发之前不会更新该值。真正的噩梦。

这是完整的代码:

protected void Page_Load(object sender, EventArgs e)
    {
        string xmlValue = ""; //To read a value from a database
        if (xmlValue.Length > 0)
        {
            if (!Page.IsPostBack)
            {
                DataSet ds = XMLToDataSet(xmlValue);
                Table dimensionsTable = DataSetToTable(ds);
                tablePanel.Controls.Add(dimensionsTable);

                DataTable dt = ds.Tables["Dimensions"];
                rowCount = dt.Rows.Count;
                colCount = dt.Columns.Count;
            }
            else
            {
                tablePanel.Controls.Add(DataSetToTable(DefaultDataSet(rowCount, colCount)));
            }
        }
        else
        {
            if (!Page.IsPostBack)
            {
                rowCount = 2;
                colCount = 4;
            }
            tablePanel.Controls.Add(DataSetToTable(DefaultDataSet(rowCount, colCount)));
        }
    }

    protected void submit_Click(object sender, EventArgs e)
    {
        resultsLabel.Text = Server.HtmlEncode(DataSetToStringXML(TableToDataSet((Table)tablePanel.Controls[0])));
    }
    protected void addColumn_Click(object sender, EventArgs e)
    {
        colCount = colCount + 1;
    }

    protected void addRow_Click(object sender, EventArgs e)
    {
        rowCount = rowCount + 1;
    }

    public DataSet TableToDataSet(Table table)
    {
        DataSet ds = new DataSet();

        DataTable dt = new DataTable("Dimensions");
        ds.Tables.Add(dt);

        //Add headers
        for (int i = 0; i < table.Rows[0].Cells.Count; i++)
        {
            DataColumn col = new DataColumn();
            TextBox headerTxtBox = (TextBox)table.Rows[0].Cells[i].Controls[0];

            col.ColumnName = headerTxtBox.Text;
            col.Caption = headerTxtBox.Text;
            dt.Columns.Add(col);
        }


        for (int i = 0; i < table.Rows.Count; i++)
        {
            DataRow valueRow = dt.NewRow();
            for (int x = 0; x < table.Rows[i].Cells.Count; x++)
            {
                TextBox valueTextBox = (TextBox)table.Rows[i].Cells[x].Controls[0];
                valueRow[x] = valueTextBox.Text;
            }
            dt.Rows.Add(valueRow);
        }

        return ds;
    }

    public Table DataSetToTable(DataSet ds)
    {
        DataTable dt = ds.Tables["Dimensions"];
        Table newTable = new Table();

        //Add headers
        TableRow headerRow = new TableRow();
        for (int i = 0; i < dt.Columns.Count; i++)
        {
            TableCell headerCell = new TableCell();
            TextBox headerTxtBox = new TextBox();
            headerTxtBox.ID = "HeadersTxtBox" + i.ToString();
            headerTxtBox.Font.Bold = true;
            headerTxtBox.Text = dt.Columns[i].ColumnName;

            headerCell.Controls.Add(headerTxtBox);
            headerRow.Cells.Add(headerCell);
        }
        newTable.Rows.Add(headerRow);

        //Add value rows
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            TableRow valueRow = new TableRow();
            for (int x = 0; x < dt.Columns.Count; x++)
            {
                TableCell valueCell = new TableCell();
                TextBox valueTxtBox = new TextBox();
                valueTxtBox.ID = "ValueTxtBox" + i.ToString() + i + x + x.ToString();
                valueTxtBox.Text = dt.Rows[i][x].ToString();

                valueCell.Controls.Add(valueTxtBox);
                valueRow.Cells.Add(valueCell);
            }
            newTable.Rows.Add(valueRow);
        }

        return newTable;
    }

    public DataSet DefaultDataSet(int rows, int cols)
    {
        DataSet ds = new DataSet();
        DataTable dt = new DataTable("Dimensions");
        ds.Tables.Add(dt);


        DataColumn nameCol = new DataColumn();
        nameCol.Caption = "Name";
        nameCol.ColumnName = "Name";
        nameCol.DataType = System.Type.GetType("System.String");
        dt.Columns.Add(nameCol);

        DataColumn widthCol = new DataColumn();
        widthCol.Caption = "Width";
        widthCol.ColumnName = "Width";
        widthCol.DataType = System.Type.GetType("System.String");
        dt.Columns.Add(widthCol);

        if (cols > 2)
        {
            DataColumn heightCol = new DataColumn();
            heightCol.Caption = "Height";
            heightCol.ColumnName = "Height";
            heightCol.DataType = System.Type.GetType("System.String");
            dt.Columns.Add(heightCol);
        }
        if (cols > 3)
        {
            DataColumn depthCol = new DataColumn();
            depthCol.Caption = "Depth";
            depthCol.ColumnName = "Depth";
            depthCol.DataType = System.Type.GetType("System.String");
            dt.Columns.Add(depthCol);
        }
        if (cols > 4)
        {
            int newColCount = cols - 4;
            for (int i = 0; i < newColCount; i++)
            {
                DataColumn newCol = new DataColumn();
                newCol.Caption = "New " + i.ToString();
                newCol.ColumnName = "New " + i.ToString();
                newCol.DataType = System.Type.GetType("System.String");
                dt.Columns.Add(newCol);
            }
        }

        for (int i = 0; i < rows; i++)
        {
            DataRow newRow = dt.NewRow();
            newRow["Name"] = "Name " + i.ToString();
            newRow["Width"] = "Width " + i.ToString();
            if (cols > 2)
            {
                newRow["Height"] = "Height " + i.ToString();
            }
            if (cols > 3)
            {
                newRow["Depth"] = "Depth " + i.ToString();
            }
            dt.Rows.Add(newRow);
        }
        return ds;
    }

    public DataSet XMLToDataSet(string xml)
    {
        StringReader sr = new StringReader(xml);
        DataSet ds = new DataSet();
        ds.ReadXml(sr);

        return ds;
    }

    public string DataSetToStringXML(DataSet ds)
    {
        XmlDocument _XMLDoc = new XmlDocument();
        _XMLDoc.LoadXml(ds.GetXml());

        StringWriter sw = new StringWriter();
        XmlTextWriter xw = new XmlTextWriter(sw);

        XmlDocument xml = _XMLDoc;
        xml.WriteTo(xw);
        return sw.ToString();
    }

    private int rowCount
    {
        get { return (int)ViewState["rowCount"]; }
        set { ViewState["rowCount"] = value; }
    }
    private int colCount
    {
        get { return (int)ViewState["colCount"]; }
        set { ViewState["colCount"] = value; }
    }

编辑:这也是我的 .aspx,以防你想在 VS 中试用。

    <asp:Panel ID="tablePanel" runat="server" CssClass="table-panel" />
    <asp:Label ID="resultsLabel" runat="server" />
    <asp:LinkButton ID="submit" Text="submit" runat="server" onclick="submit_Click" />
    <asp:LinkButton ID="addColumn" Text="Add Column" runat="server" 
        onclick="addColumn_Click" />
    <asp:LinkButton ID="addRow" Text="Add Row" runat="server" onclick="addRow_Click" />

提前致谢,

马尔科

【问题讨论】:

    标签: c# .net events dataset


    【解决方案1】:

    正如我在this other question 中推荐的那样,如果您希望在按钮的Click 事件之后执行某些页面逻辑,请将该代码放入Page_PreRender

    您可以在此处阅读更多信息:ASP.NET page life cycle

    编辑:

    在仔细检查您的代码后,我发现您添加了一些东西并创建了新控件,这在 PreRender 事件中不是一个好主意。 相反,将代码放入单独的方法中。在 Page_Load 中,检查是否是回发,如果不是则处理。 在按钮的单击事件中,还添加对该新方法的调用。 (从而处理 IsPostback == true 的情况)

    【讨论】:

    • 是的,但是在我的 submitButton_click 事件中,tablePanel 是空的,因此会引发索引超出范围错误。
    • 这是一个真正的问题 22. 我将创建控件的方法移到了 rowCount = rowCount + 1; 之后。和 colCount = colCount + 1;代码,但在尝试提交值时遇到了同样的问题。
    • 编辑了我的答案,给了你一个新的想法。
    • 抱歉,我不确定我是否关注。我已经在检查它是否是回发,如果不是,我只是将默认值设置为 2 和 4。在所有其他情况下,页面应该使用更新的值(分别为 rowCount 和 ColCount)重新创建控件.将其放入方法中有何帮助?
    • 关键是从按钮的点击事件中调用方法。
    【解决方案2】:

    好的,我已经按照this 帖子中的说明解决了这个问题。

    这是我的最终代码 - 如果您需要基于计数器创建动态控件,请随时使用它。

    此外,我不介意对整体编码风格的反馈,我总是感谢其他人的意见。

    protected void Page_Load(object sender, EventArgs e)
        {
            string xmlValue = ""; //To read a value from a database
            if (xmlValue.Length > 0)
            {
                if (!Page.IsPostBack)
                {
                    DataSet ds = XMLToDataSet(xmlValue);
                    Table dimensionsTable = DataSetToTable(ds);
                    tablePanel.Controls.Add(dimensionsTable);
    
                    DataTable dt = ds.Tables["Dimensions"];
                    rowCount = dt.Rows.Count;
                    colCount = dt.Columns.Count;
                }
                else
                {
                    tablePanel.Controls.Add(DataSetToTable(DefaultDataSet(rowCount, colCount)));
                }
            }
            else
            {
                if (!Page.IsPostBack)
                {
                    rowCount = 2;
                    colCount = 4;
                }
                else
                {
                    if (GetPostBackControl(this.Page).ID == "addRow")
                    {
                        rowCount = rowCount + 1;
                    }
                    else if (GetPostBackControl(this.Page).ID == "addColumn")
                    {
                        colCount = colCount + 1;
                    }
                }
                tablePanel.Controls.Add(DataSetToTable(DefaultDataSet(rowCount, colCount)));
            }
        }
    
        protected void submit_Click(object sender, EventArgs e)
        {
            resultsLabel.Text = Server.HtmlEncode(DataSetToStringXML(TableToDataSet((Table)tablePanel.Controls[0])));
        }
        protected void addColumn_Click(object sender, EventArgs e)
        {
    
        }
    
        protected void addRow_Click(object sender, EventArgs e)
        {
    
        }
    
        public DataSet TableToDataSet(Table table)
        {
            DataSet ds = new DataSet();
    
            DataTable dt = new DataTable("Dimensions");
            ds.Tables.Add(dt);
    
            //Add headers
            for (int i = 0; i < table.Rows[0].Cells.Count; i++)
            {
                DataColumn col = new DataColumn();
                TextBox headerTxtBox = (TextBox)table.Rows[0].Cells[i].Controls[0];
    
                col.ColumnName = headerTxtBox.Text;
                col.Caption = headerTxtBox.Text;
                dt.Columns.Add(col);
            }
    
    
            for (int i = 0; i < table.Rows.Count; i++)
            {
                DataRow valueRow = dt.NewRow();
                for (int x = 0; x < table.Rows[i].Cells.Count; x++)
                {
                    TextBox valueTextBox = (TextBox)table.Rows[i].Cells[x].Controls[0];
                    valueRow[x] = valueTextBox.Text;
                }
                dt.Rows.Add(valueRow);
            }
    
            return ds;
        }
    
        public Table DataSetToTable(DataSet ds)
        {
            DataTable dt = ds.Tables["Dimensions"];
            Table newTable = new Table();
    
            //Add headers
            TableRow headerRow = new TableRow();
            for (int i = 0; i < dt.Columns.Count; i++)
            {
                TableCell headerCell = new TableCell();
                TextBox headerTxtBox = new TextBox();
                headerTxtBox.ID = "HeadersTxtBox" + i.ToString();
                headerTxtBox.Font.Bold = true;
                headerTxtBox.Text = dt.Columns[i].ColumnName;
    
                headerCell.Controls.Add(headerTxtBox);
                headerRow.Cells.Add(headerCell);
            }
            newTable.Rows.Add(headerRow);
    
            //Add value rows
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                TableRow valueRow = new TableRow();
                for (int x = 0; x < dt.Columns.Count; x++)
                {
                    TableCell valueCell = new TableCell();
                    TextBox valueTxtBox = new TextBox();
                    valueTxtBox.ID = "ValueTxtBox" + i.ToString() + i + x + x.ToString();
                    valueTxtBox.Text = dt.Rows[i][x].ToString();
    
                    valueCell.Controls.Add(valueTxtBox);
                    valueRow.Cells.Add(valueCell);
                }
                newTable.Rows.Add(valueRow);
            }
    
            return newTable;
        }
    
        public DataSet DefaultDataSet(int rows, int cols)
        {
            DataSet ds = new DataSet();
            DataTable dt = new DataTable("Dimensions");
            ds.Tables.Add(dt);
    
    
            DataColumn nameCol = new DataColumn();
            nameCol.Caption = "Name";
            nameCol.ColumnName = "Name";
            nameCol.DataType = System.Type.GetType("System.String");
            dt.Columns.Add(nameCol);
    
            DataColumn widthCol = new DataColumn();
            widthCol.Caption = "Width";
            widthCol.ColumnName = "Width";
            widthCol.DataType = System.Type.GetType("System.String");
            dt.Columns.Add(widthCol);
    
            if (cols > 2)
            {
                DataColumn heightCol = new DataColumn();
                heightCol.Caption = "Height";
                heightCol.ColumnName = "Height";
                heightCol.DataType = System.Type.GetType("System.String");
                dt.Columns.Add(heightCol);
            }
            if (cols > 3)
            {
                DataColumn depthCol = new DataColumn();
                depthCol.Caption = "Depth";
                depthCol.ColumnName = "Depth";
                depthCol.DataType = System.Type.GetType("System.String");
                dt.Columns.Add(depthCol);
            }
            if (cols > 4)
            {
                int newColCount = cols - 4;
                for (int i = 0; i < newColCount; i++)
                {
                    DataColumn newCol = new DataColumn();
                    newCol.Caption = "New " + i.ToString();
                    newCol.ColumnName = "New " + i.ToString();
                    newCol.DataType = System.Type.GetType("System.String");
                    dt.Columns.Add(newCol);
                }
            }
    
            for (int i = 0; i < rows; i++)
            {
                DataRow newRow = dt.NewRow();
                newRow["Name"] = "Name " + i.ToString();
                newRow["Width"] = "Width " + i.ToString();
                if (cols > 2)
                {
                    newRow["Height"] = "Height " + i.ToString();
                }
                if (cols > 3)
                {
                    newRow["Depth"] = "Depth " + i.ToString();
                }
                dt.Rows.Add(newRow);
            }
            return ds;
        }
    
        public DataSet XMLToDataSet(string xml)
        {
            StringReader sr = new StringReader(xml);
            DataSet ds = new DataSet();
            ds.ReadXml(sr);
    
            return ds;
        }
    
        public string DataSetToStringXML(DataSet ds)
        {
            XmlDocument _XMLDoc = new XmlDocument();
            _XMLDoc.LoadXml(ds.GetXml());
    
            StringWriter sw = new StringWriter();
            XmlTextWriter xw = new XmlTextWriter(sw);
    
            XmlDocument xml = _XMLDoc;
            xml.WriteTo(xw);
            return sw.ToString();
        }
    
        private int rowCount
        {
            get { return (int)ViewState["rowCount"]; }
            set { ViewState["rowCount"] = value; }
        }
        private int colCount
        {
            get { return (int)ViewState["colCount"]; }
            set { ViewState["colCount"] = value; }
        }
        public static Control GetPostBackControl(Page page)
        {
            Control control = null;
    
            string ctrlname = page.Request.Params.Get("__EVENTTARGET");
            if (ctrlname != null && ctrlname != string.Empty)
            {
                control = page.FindControl(ctrlname);
            }
            else
            {
                foreach (string ctl in page.Request.Form)
                {
                    Control c = page.FindControl(ctl);
                    if (c is System.Web.UI.WebControls.Button)
                    {
                        control = c;
                        break;
                    }
                }
            }
            return control;
        }
    

    【讨论】:

    • 这个 GetPostBackControl 是一个聪明的主意。
    • 旁注:在此上下文中,this 实例等于 this.Page 实例。因此,您可以编写“if (!IsPostBack)”或“GetPostBackControl(this)”。 (您的页面继承自 Page 类);)
    • 是的,感谢上帝,我发现它解决了我所有的问题!感谢您的帮助,我已为您的努力 +1。马尔科
    【解决方案3】:

    移动此代码:

    tablePanel.Controls.Add(DataSetToTable(DefaultDataSet(rowCount, colC....
    

    到预渲染事件以在按钮单击触发后使表格绑定到其数据。

    【讨论】:

    • 正如您在上面看到的,我在执行该代码之前进行了一组检查。我已将整个代码块移至 Page_PreRender 事件,但在 submit_click 上 tablePanel 为空。错误是:指定的参数超出了有效值的范围。 resultsLabel.Text = Server.HtmlEncode(DataSetToStringXML(TableToDataSet((Table)tablePanel.Controls[0])));
    • 知道为什么在 PreRender 而不是 Page_Load 中创建控件时提交时没有值吗?
    猜你喜欢
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多