locked
DropDownList in EditItemTemplate in GridView using Model Binding (ItemType) RRS feed

  • Question

  • User-879727125 posted

    I have a web form in a web application. I have a field, WeekDay, that should show a weekday name but store the weekday id. So in the GridView for editing purposes I want to show a DropDownList instead of the weekday name. Very typical, except I realize it is inefficient to use a table just for weekday names. This is for educational purposes.

    I can create a separate DropDownList (outside of the GridView) using:

    <asp:DropDownList ID="DropDownList1" runat="server" ItemType="Web2017.WeekDay"
    	SelectMethod="GetWeedayItems"
    	DataTextField="Name"
    	DataValueField="Id" />

    I can use the following to get the weekday name shown in a TextBox but that only edits the name, that does not help.

    <EditItemTemplate>
    	<asp:TextBox ID="TextBoxDay" Text='<%# BindItem.WeekDay.Name %>' runat="server"/>
    </EditItemTemplate>
    

    Can I do something in the SelectMethod for the GridView so I can create the DropDownList without a separate SelectMethod or do I need to do something separate for the DropDownList? How do I get a DropDownList for editing an associated value using Model Binding (strongly typed data binding)?

    Monday, December 17, 2018 9:27 PM

Answers

  • User-879727125 posted

    One mistake I made was to provide the ItemType for the DropDownList. Doing that meant I could not use "Item" and "BindItem" for the data bound to the GridView.

    Without the ItemType in the DropDownList I can use "SelectedValue="<%# BindItem.KeyValueId %>"" to bind the DropDownList.

    For everything else we can use the existing tutorials and such.

    One concept I did not realize is that the SelectMethod can do all the retrieval without using the ItemType to specify what to retrieve. For the DropDownList we can just specify the relevant names for the DataTextField and DataValueField and if the SelectMethod retrieves values with those names then it works. I think we only need to understand that and the rest becomes obvious.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, December 23, 2018 11:35 PM

All replies

  • User-1174608757 posted

    Hi Sam Hobbs,
    According to your description ,I have made a sample here.

    Sam Hobbs

    Can I do something in the SelectMethod for the GridView so I can create the DropDownList without a separate SelectMethod or do I need to do something separate for the DropDownList?


    If you bind dropdownlist with modal ,you have to add SelectMethod so it could get the datasource.

    To avoid setting SelectMethod, you could just write the source code of dropdownlist in code behind or set in database .Here is my code.I hope it can help you .

    test.aspx:

    <body>
        <form id="form1" runat="server">
            <div>
                <asp:GridView ID="GridView1" runat="server" AutoGenerateEditButton="true" OnRowDataBound="GridView1_RowDataBound" AutoGenerateColumns="false"
                    DataKeyNames="id" OnRowEditing="GridView1_RowEditing" Height="195px" Width="314px" OnRowUpdating="GridView1_RowUpdating"  OnRowCancelingEdit="GridView1_RowCancelingEdit">
                    <Columns>
                        <asp:TemplateField>
                            <ItemTemplate>
                              <asp:Label runat="server" Text='<%#Eval("id") %>'></asp:Label>  
                            </ItemTemplate>                        
                        </asp:TemplateField>
                        <asp:TemplateField>
                             <ItemTemplate>
                                <asp:Label runat="server" Text='<%#Eval("Name") %>'></asp:Label>  
                            </ItemTemplate>
                        </asp:TemplateField>
    
                        <asp:TemplateField>
                            <ItemTemplate>
                                <asp:Label runat="server" Text='<%#Eval("project") %>'></asp:Label>  
                            </ItemTemplate>
                            <EditItemTemplate>
                                <asp:DropDownList ID="DropDownList1" AppendDataBoundItems="True" runat="server">
                                </asp:DropDownList>
                            </EditItemTemplate>
                        </asp:TemplateField>
                    </Columns>
                </asp:GridView>
            </div>
        </form>
    </body>

    test.aspx.cs:

     public partial class dropdownlist : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack)
                {
                    string sql = "select * from test";
                    this.GridView1.DataSource = SqlHelper.ExecuteDataTable(sql);
                    this.GridView1.DataBind();
                }
    
            }
    
            protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
            {
                if (e.Row.RowType == DataControlRowType.DataRow)
                {
                    if ((e.Row.RowState & DataControlRowState.Edit) > 0)
                    {
                        // this part is select the data from database
                        //DataRowView rowView = (DataRowView)e.Row.DataItem;
                        //int s =Convert.ToInt32( rowView["id"].ToString());
                        //DropDownList drop = (DropDownList)e.Row.FindControl("DropDownList1");
                        //string sql = "select * from test1";                 
                        //drop.DataSource = SqlHelper.ExecuteDataTable(sql);
                        //drop.DataValueField = "Id";
                        //drop.DataTextField = "Project";                                   
                        //drop.DataBind();
                        
    
                        //This part is directly gerneate the ddl's item
                        DropDownList drop = (DropDownList)e.Row.FindControl("DropDownList1");
                        DataTable dt = new DataTable();
                        dt.Columns.Add(new DataColumn("Id", typeof(Int32)));
                        DataRow row1 = dt.NewRow();
                        row1["Id"] = 1;
                        DataRow row2 = dt.NewRow();
                        row2["Id"] = 2;
                        dt.Columns.Add(new DataColumn("Project", typeof(string)));
                        row1["Project"] = "Java";
                        DataRow row4 = dt.NewRow();
                        row2["Project"] = "C#";
                        dt.Rows.Add(row1);
                        dt.Rows.Add(row2);
                                        
                        drop.DataSource = dt;
                        drop.DataValueField = "Id";
                        drop.DataTextField = "Project";
                        drop.DataBind();
                    }
    
                }
    
            }
    
            protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
            {
                GridView1.EditIndex = e.NewEditIndex;
                string sql = "select * from test";
                this.GridView1.DataSource = SqlHelper.ExecuteDataTable(sql);
                this.GridView1.DataBind();
    
            }
    
            protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
            {
                
                string id = GridView1.DataKeys[e.RowIndex].Value.ToString();
                DropDownList drop = (DropDownList)GridView1.Rows[e.RowIndex].FindControl("DropDownList1");
                string s = drop.SelectedItem.Text;
                string sql = "update test set project =@project where id =@id";
                SqlParameter[] prms = { new SqlParameter("@id", System.Data.DbType.Int32) { Value=id}, new SqlParameter("@project", s) };
                SqlHelper.ExecuteNonQuery(sql, prms);
                GridView1.EditIndex = -1;
                string sql1 = "select * from test";
                this.GridView1.DataSource = SqlHelper.ExecuteDataTable(sql1);
                this.GridView1.DataBind();
    
            }
    
            protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
            {
                GridView1.EditIndex = -1;
                string sql = "select * from test";
                this.GridView1.DataSource = SqlHelper.ExecuteDataTable(sql);
                this.GridView1.DataBind();
    
            }
        }

    Best Regards

    Wei Zhang

    Tuesday, December 18, 2018 10:03 AM
  • User-879727125 posted

    Thank you Wei Zhang but I think that won't work. You are setting the DataSource. That is incompatible with strongly typed data binding, right? When I set a DataSource for a control that has an ItemType attribute I get an error.

    Tuesday, December 18, 2018 6:45 PM
  • User-879727125 posted

    After thinking about it I decided to try using a DropDownList with an ItemType for the weekday items instead of the items that the (rest of the) GridView is showing. That seems to work except it gives the error that the database is read-only. I assume that is an unrelated problem and I will research that but the important thing is that the answer is probably to use a DropDownList with a different ItemType.

    Wednesday, December 19, 2018 5:52 AM
  • User-1174608757 posted

    Hi Sam Hobbs,

    According to your description, it seems better to use ItemType of dropdownlist if you don't want to use database. To solve the error that the database is read-only.

    I suggest you to send a new  case and we will solve it as soon as possible.

    Best Regards

    Wei Zhang 

    Wednesday, December 19, 2018 7:13 AM
  • User-879727125 posted

    I don't know what was causing the database to be read-only but I created a new project and proceeded from there. I almost have it working. I think I will figure it out tomorrow but this is where I am at currently.

    My EditItemTemplate for the week day is:

    <asp:DropDownList ID="DDLDay" runat="server"
    	ItemType="Web2017.WeekDay"
    	SelectMethod="GetWeedayItems"
    	DataTextField="Name"
    	DataValueField="Id" />
    

    GetWeedayItems is:

    public IQueryable<WeekDay> GetWeedayItems()
    {
        ShowsModel db = new ShowsModel();
        IOrderedQueryable<WeekDay> query;
        query = from item in db.WeekDays orderby item.Id select item;
        return query;
    }

    That gets the rows. But I need to have a way to initialize the value to the current week day id. And in my update, which is:

    public void UpdateShow(Show s)
    {
        ShowsModel db = new ShowsModel();
        var data = from item in db.Shows
                    where item.Id == s.Id
                    select item;
        Show obj = data.SingleOrDefault();
        obj.Name = s.Name;
        obj.WeekDayId = s.WeekDayId;
        db.SaveChanges();
    }
    

    I need to get the id value from the DropDownList. It is trying to do the update but then I get a SqlException: The UPDATE statement conflicted with the FOREIGN KEY constraint and that makes sense, I am not providing a valid value. And as I said, I am trying to use Model Binding.

    I assume this is a very common requirement; the ability to show a DropDownList for editing data using Model Binding. So I will do some searching and researching tomorrow, it is the end of the day for me.

    Thursday, December 20, 2018 7:35 AM
  • User-879727125 posted

    One mistake I made was to provide the ItemType for the DropDownList. Doing that meant I could not use "Item" and "BindItem" for the data bound to the GridView.

    Without the ItemType in the DropDownList I can use "SelectedValue="<%# BindItem.KeyValueId %>"" to bind the DropDownList.

    For everything else we can use the existing tutorials and such.

    One concept I did not realize is that the SelectMethod can do all the retrieval without using the ItemType to specify what to retrieve. For the DropDownList we can just specify the relevant names for the DataTextField and DataValueField and if the SelectMethod retrieves values with those names then it works. I think we only need to understand that and the rest becomes obvious.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, December 23, 2018 11:35 PM