Adding dynamic columns to an ASP.NET Gridview

前端 未结 9 1352
不思量自难忘°
不思量自难忘° 2020-12-28 18:54

I\'m having a problem dynamically adding columns to a GridView. I need to change the layout -- i.e. the included columns -- based on the value in a DropDownList. When the

相关标签:
9条回答
  • 2020-12-28 19:14

    I recently conquered silmilar issues with dynamic columns in gridviews, perhaps this will help.

    First turn the viewstate off
    Second add the columns programatically in a function fired in the oninit event
    Lastly I used the following helper class to cause the checkboxes to instantiate when the RowDataBound event kicked off. Yes some of it is hard coded.

    Heck here is all the code. Have at it :) Warrenty as is, blah blah blah...

    Finally since I am just getting my feet wet DotNet any tips would be appreciated [IE don't rip me too much :) ]. And yes 'borrowed' the initial code from the web somewhere, sorry I cant remember off the top of my head :(

    -- Fire this off in protected override void OnInit

        private void GridViewProject_AddColumns()
        {
            DataSet dsDataSet = new DataSet();
            TemplateField templateField = null;
    
            try
            {
                StoredProcedure sp = new StoredProcedure("ExpenseReportItemType_GetList", "INTRANETWEBDB", Context.User.Identity.Name);
                dsDataSet = sp.GetDataSet();
    
                if (sp.RC != 0 && sp.RC != 3000)
                {
                    labelMessage.Text = sp.ErrorMessage;
                }
    
                int iIndex = 0;
                int iCount = dsDataSet.Tables[0].Rows.Count;
                string strCategoryID = "";
                string strCategoryName = "";
                iStaticColumnCount = GridViewProject.Columns.Count;
    
                // Insert all columns immediatly to the left of the LAST column
                while (iIndex < iCount)
                {
                    strCategoryName = dsDataSet.Tables[0].Rows[iIndex]["CategoryName"].ToString();
                    strCategoryID = dsDataSet.Tables[0].Rows[iIndex]["CategoryID"].ToString();
    
                    templateField = new TemplateField();
                    templateField.HeaderTemplate = new GridViewTemplateExternal(DataControlRowType.Header, strCategoryName, strCategoryID);
                    templateField.ItemTemplate = new GridViewTemplateExternal(DataControlRowType.DataRow, strCategoryName, strCategoryID);
                    templateField.FooterTemplate = new GridViewTemplateExternal(DataControlRowType.Footer, strCategoryName, strCategoryID);
    
                    // Have to decriment iStaticColumnCount to insert dynamic columns BEFORE the edit row
                    GridViewProject.Columns.Insert((iIndex + (iStaticColumnCount-1)), templateField);
                    iIndex++;
                }
                iFinalColumnCount = GridViewProject.Columns.Count;
                iERPEditColumnIndex = (iFinalColumnCount - 1); // iIndex is zero based, Count is not
            }
            catch (Exception exception)
            {
                labelMessage.Text = exception.Message;
            }
        }
    

    -- Helper Class

    public class GridViewTemplateExternal : System.Web.UI.ITemplate
    {
        #region Fields
        public DataControlRowType DataRowType;
        private string strCategoryID;
        private string strColumnName;
        #endregion
    
        #region Constructor
        public GridViewTemplateExternal(DataControlRowType type, string ColumnName, string CategoryID)
        {
            DataRowType = type; // Header, DataRow,
            strColumnName = ColumnName; // Header name
            strCategoryID = CategoryID;
        }
        #endregion
    
        #region Methods
        public void InstantiateIn(System.Web.UI.Control container)
        {
            switch (DataRowType)
            {
                case DataControlRowType.Header:
                    // build the header for this column
                    Label labelHeader = new Label();
                    labelHeader.Text = "<b>" + strColumnName + "</b>";
                    // All CheckBoxes "Look Up" to the header row for this information
                    labelHeader.Attributes["ERICategoryID"] = strCategoryID;
                    labelHeader.Style["writing-mode"] = "tb-rl";
                    labelHeader.Style["filter"] = "flipv fliph";
                    container.Controls.Add(labelHeader);
                    break;
                case DataControlRowType.DataRow:
                    CheckBox checkboxAllowedRow = new CheckBox();
                    checkboxAllowedRow.Enabled = false;
                    checkboxAllowedRow.DataBinding += new EventHandler(this.CheckBox_DataBinding);
                    container.Controls.Add(checkboxAllowedRow);
                    break;
                case DataControlRowType.Footer:
                    // No data handling for the footer addition row
                    CheckBox checkboxAllowedFooter = new CheckBox();
                    container.Controls.Add(checkboxAllowedFooter);
                    break;
                default:
                    break;
            }
        }
        public void CheckBox_DataBinding(Object sender, EventArgs e)
        {
            CheckBox checkboxAllowed = (CheckBox)sender;// get the control that raised this event
            GridViewRow row = (GridViewRow)checkboxAllowed.NamingContainer;// get the containing row
            string RawValue = DataBinder.Eval(row.DataItem, strColumnName).ToString();
            if (RawValue.ToUpper() == "TRUE")
            {
                checkboxAllowed.Checked = true;
            }
            else
            {
                checkboxAllowed.Checked = false;
            }
        }
        #endregion
    }
    
    0 讨论(0)
  • 2020-12-28 19:14

    Instead of dynamically adding columns, could you define them at the outset and hide/show them as needed (either with Visible="false" or setting the CssClass of the control/header/footer to a class with "display: none;")? I use this method in some of my code, including template columns, with no issues.

    0 讨论(0)
  • 2020-12-28 19:19

    diningphilanderer.myopenid.com has a similar approach to what I would recommend.

    The problem is that you have to rebind the grid each time a postback occurs and consequently you have to rebuild the columns. I like to have a method called BindGrid() that first clears the Columns GridView1.Columns.Clear(); then adds them programatically, then sets the datasource and calls databind. Make sure you have viewstate disabled for the grid and you have autogeneratecolumns = false;

    0 讨论(0)
提交回复
热议问题