access values from dynamic generated textbox (or dropdownlist) in a gridview

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • sasha3
    New Member
    • Aug 2010
    • 6

    access values from dynamic generated textbox (or dropdownlist) in a gridview

    In my asp page when press a button, a gridview will be populated with data from db, but beside the columns from database i need a new dynamic column in gridview, to contain only dropdownlist with items number from 0-n.


    This far i managed to do it, with some research on internet (i used an intemerdiet datatable to apply ItemTemplate from GridViewTemplat e class, and than merged it to datatable containg the result from query, so the gridview's datasource si the merge of this 2 datatables).


    The issue is that i don't now how can i access the values selected by user in the dinamically dropdownlists, 'cause i have to save them in DB.


    Attach is my GridViewTemplat e class code, and .cs and .aspx code.

    GridViewTemplat e class
    Code:
    public class GridViewTemplate : ITemplate
    {
        //A variable to hold the type of ListItemType.
        ListItemType _templateType;
    
        //A variable to hold the column name.
        string _columnName;
    
        //Constructor where we define the template type and column name.
        public GridViewTemplate(ListItemType type, string colname)
        {
            //Stores the template type.
            _templateType = type;
    
            //Stores the column name.
            _columnName = colname;
        }
    
        void ITemplate.InstantiateIn(System.Web.UI.Control container)
        {
            switch (_templateType)
            {
                case ListItemType.Header:
                    //Creates a new label control and add it to the container.
                    Label lbl = new Label();            //Allocates the new label object.
                    lbl.Text = _columnName;             //Assigns the name of the column in the lable.
                    container.Controls.Add(lbl);        //Adds the newly created label control to the container.
                    break;
    
                case ListItemType.Item:
                    //Creates a new dro down list control and add it to the container.
                    DropDownList ddl = new DropDownList();                     //Allocates the new text box object.
                    ddl.DataBinding += new EventHandler(ddl_DataBinding);      //Attaches the data binding event.
                    ddl.Width = 35;                                            //Creates a column with size 4.
                    ddl.Items.Add("0");                                        //Fill in the dropdownlist with values from 0-4
                    ddl.Items.Add("1");
                    ddl.Items.Add("2");
                    ddl.Items.Add("3");
                    ddl.Items.Add("4");
                    //ddl.ID = "dropdownlist1";                                 // the ddl name will end with dropdownlist1, all of them, can use findcontrol method...but..
                    container.Controls.Add(ddl);                              //Adds the newly created textbox to the container.
                    break;
    
                case ListItemType.EditItem:
                    //As, I am not using any EditItem, I didnot added any code here.
                    break;
    
                case ListItemType.Footer:
                    CheckBox chkColumn = new CheckBox();
                    chkColumn.ID = "Chk" + _columnName;
                    container.Controls.Add(chkColumn);
                    break;
            }
        }
    
        void ddl_DataBinding(object sender, EventArgs e)
        {
            DropDownList ddd = (DropDownList)sender;
            GridViewRow container = (GridViewRow)ddd.NamingContainer;
            object dataValue = DataBinder.Eval(container.DataItem, _columnName);
            if (dataValue != DBNull.Value)
            {
                ddd.Text = dataValue.ToString();
            }
        }
    }

    .cs code


    Code:
    public void btn_Matrix_Click(object sender, EventArgs e)
            {
                SqlConnection conn = null;
                SqlDataAdapter myDataAdapter = null;
                grdMatrix.Visible = true;
    
                try
                {
                    string connStr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
                    conn = new SqlConnection(connStr);
    
                    DataSet myDataSet = new DataSet();
    
                    myDataAdapter = new SqlDataAdapter("", conn);
                    myDataAdapter.SelectCommand.CommandText = "select employee_id as 'Employee No',lastname as 'Employee Name' from employee";
    
    
                    myDataAdapter.Fill(myDataSet, "Temp");
    
                    DataTable dtquery = myDataSet.Tables[0];
    
                    DataTable dtcolumns = new DataTable();
    
                    dtcolumns.Columns.Add("Level");
                
                   foreach (DataColumn col in dtcolumns.Columns)
                    {
                        //Declare the bound field and allocate memory for the bound field.
                        TemplateField bfield = new TemplateField();
    
                        //Initalize the DataField value.
                        bfield.HeaderTemplate = new GridViewTemplate(ListItemType.Header, col.ColumnName);
    
                        //Initialize the HeaderText field value.
                        bfield.ItemTemplate = new GridViewTemplate(ListItemType.Item, col.ColumnName);
    
                        //Add the newly created bound field to the GridView.
                        grdMatrix.Columns.Add(bfield);
                    }
    
                dtcolumns.Merge(dtquery);
                //Initialize the DataSource
                grdMatrix.DataSource = dtcolumns;
    
                //Bind the datatable with the GridView.
                grdMatrix.DataBind();
                conn.Close();   
                }
                catch (Exception ex)
                {
                    WebMsgBox.Show(ex.Message);
                }
                finally
                {
                    if (conn != null)
                        conn.Close();
                }
            }

    .aspx code
    Code:
        <br/><asp:Panel ID="Panel1" runat="server">
        <asp:GridView ID="grdMatrix" runat="server" AutoGenerateColumns = "False"
            CellPadding="4" EnableModelValidation="True" ForeColor="#333333"
            GridLines="None" >
            <AlternatingRowStyle BackColor="White" />
        <Columns>
        <asp:BoundField DataField="Employee No" Visible="true" HeaderText="Employee No" />
        <asp:BoundField DataField="Employee Name" Visible="true" HeaderText="Employee Name" />
        </Columns>
            <EditRowStyle BackColor="#2461BF" />
            <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
            <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
            <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
            <RowStyle BackColor="#EFF3FB" />
            <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
        </asp:GridView>
        </asp:Panel>
    Thank you in advance.
    Last edited by Frinavale; Aug 31 '10, 02:12 PM. Reason: Added code tags. Please post code in [code] ... [/code] tags in the future.
  • Frinavale
    Recognized Expert Expert
    • Oct 2006
    • 9749

    #2
    In your InstantiateIn method...when you create the DropDownList, give the DropDownList and ID. That way you can use the GridViewRow's FindControl() method to retrieve the DropDownList in the button click event.


    -Frinny

    Comment

    • sasha3
      New Member
      • Aug 2010
      • 6

      #3
      I have considered this, but i commented the
      //ddl.ID = "dropdownlist1" ; from the InstantiateIn method because i could not use it.

      If i go for something like:
      (DropDownList) txt1 = (DropDownList)) grdMatrix.Rows[1].Cells[1].FindControl("d ropdownlist1");
      (DropDownList)) grdMatrix.Rows[1].Cells[2].FindControl("d ropdownlist2"); .....and so on ...but i don't know how many dropdownlist i will have until the user makes his selections and the gridview is generated.

      Comment

      • Frinavale
        Recognized Expert Expert
        • Oct 2006
        • 9749

        #4
        You need to give the DropDownList an ID. Either pass the column number into the constructor for the ITemplate and use that to create the ID for the DropDownList... or in the method that handles the DropDownList binding event use the NamingContainer to retrieve the GridView.Rows.C ount value and use that to create an ID for the DropDownList.

        I think the first one is a bit easier to understand...bu t they will both accomplish the same thing.

        For example, you would change the constructor to take the "colnum" value and use that to set the ID of the DropDownList in the InstantiateIn method.

        Like this:
        Code:
        public class GridViewTemplate : ITemplate
        {
            //A variable to hold the type of ListItemType.
            ListItemType _templateType;
         
            //A variable to hold the column name.
            string _columnName;
        
            //A variable to hold the column number.
            string columnNum;
         
            //Constructor where we define the template type and column name.
            public GridViewTemplate(ListItemType type, string colname, int colNum)
            {
                //Stores the template type.
                _templateType = type;
         
                //Stores the column name.
                _columnName = colname;
        
                //Stores the column number.
                columnNum = colNum;
            }
         
            void ITemplate.InstantiateIn(System.Web.UI.Control container)
            {
                switch (_templateType)
                {
                   //...........
        
                        case ListItemType.Item:
                        //Creates a new drop down list control and add it to the container.
                          DropDownList ddl = new DropDownList();                     //Allocates the new text box object.
                          ddl.DataBinding += new EventHandler(ddl_DataBinding);      //Attaches the data binding event.
                          ddl.Width = 35;                                            //Creates a column with size 4.
                          ddl.Items.Add("0");                                          //Fill in the dropdownlist with values from 0-4
                          ddl.Items.Add("1");
                          ddl.Items.Add("2");
                          ddl.Items.Add("3");
                          ddl.Items.Add("4");
                          ddl.ID = "dropdownlist" & columnNum.ToString();                                 
                          container.Controls.Add(ddl);
                          //Adds the newly created textbox to the container.
                        break;

        Or, you try using the NamingContainer to retrieve a reference to the GridView when the DropDownList is being bound. That way you can figure out the number of columns already in the GridView to create the ID for the DropDownList. In this case you don't have to change the consturctor.

        I don't really have a way to test this...but your code would look something like:
        Code:
            void ddl_DataBinding(object sender, EventArgs e)
            {
                DropDownList ddd = (DropDownList)sender;
                GridViewRow container = (GridViewRow)ddd.NamingContainer;
              
             GridView gv = (GridView)container.NamingContainer;
             int rowCount = gv.Rows.Count;
             ddd.ID = "dropdownlist" & rowCount.ToString();
        
                object dataValue = DataBinder.Eval(container.DataItem, _columnName);
                if (dataValue != DBNull.Value)
                {
                    ddd.Text = dataValue.ToString();
                }
            }
        In your button click event you need to retrieve the GridViewRow that you want to use and call the FindControl method for each DropDownList on it like this:
        Code:
        List<DropDownList> ddlListsForRow1;
        ddlListsForRow1= new List<DropDownList>();
        
        int dropDownListIteration;
        
        for(dropDownListIteration=0; dropDownListIteration<numOfDropDownLists; i++)
        {
          DropDownList ddl = (DropDownList))grdMatrix.Rows[1].FindControl("dropdownlist" & dropDownListIteration);
          ddlListsForRow1.Add(ddl);
        }
        -Frinny

        Comment

        • sasha3
          New Member
          • Aug 2010
          • 6

          #5
          Thank you very much for your detailed answer, i try now to implement this. Also found a nice, article,

          Comment

          Working...