2010-05-10 111 views
2

我有一個問題,一直在困擾着我整天。c#計數器需要2個按鈕點擊才能更新

在我的代碼,我有以下:

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" /> 

由於提前,

馬爾科

回答

1

好的我按照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; 
    } 
+0

這GetPostBackControl是一個聰明的主意。 – Venemo 2010-05-11 08:19:46

+0

注意:在這種情況下,這個實例等於this.Page實例。因此,你可以寫「if(!IsPostBack)」或「GetPostBackControl(this)」。 (你的頁面從頁面類繼承);) – Venemo 2010-05-11 08:21:31

+0

是啊,感謝上帝,我發現它解決了我所有的問題!感謝您的幫助,我爲您付出了努力+1。馬爾科 – Marko 2010-05-11 20:48:15

0

舉動驗證碼:

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

要預渲染事件使表綁定到其數據按鈕點擊後發射。

+0

正如你所看到的,我在執行代碼之前做了一系列檢查。我已將整個代碼塊移至Page_PreRender事件,但tablePanel在submit_click上爲空。 錯誤是: 指定的參數超出了有效值的範圍。 resultsLabel.Text = Server.HtmlEncode(DataSetToStringXML(TableToDataSet((Table)tablePanel)。控制[0]))); – Marko 2010-05-10 05:42:29

+0

任何想法爲什麼在PreRender中創建控件而不是Page_Load時提交的值不存在? – Marko 2010-05-10 05:53:01

1

正如我在this other question中推薦的那樣,如果您希望在按鈕「Click」事件後執行一些頁面邏輯,請將代碼放入Page_PreRender

您可以在這裏閱讀更多關於它的信息:ASP.NET page life cycle

編輯:

更加緊密地檢查你的代碼後,我看到你添加的東西,創造新的控制,這是不是在PreRender事件是一個好主意。 而是將代碼放入單獨的方法中。在Page_Load中,檢查它是否是回傳,如果不是,則處理該情況。 在按鈕的單擊evnt中,還要添加對該新方法的調用。 (因此處理IsPostback ==真實案例)

+0

是的,但後來在我的submitButton_click事件中tablePanel是空的,因此拋出索引超出範圍錯誤。 – Marko 2010-05-10 05:45:09

+0

這是一個真正的捕獲22.我移動了在rowCount = rowCount + 1之後創建我的控件的方法;和colCount = colCount + 1;代碼,但在嘗試提交值時遇到了同樣的問題。 – Marko 2010-05-10 05:51:53

+0

編輯我的答案,給你一個新的想法。 – Venemo 2010-05-10 06:19:59

相關問題