简体   繁体   English

c#网格视图中的下拉列表

[英]c# drop down list in grid view

I am a grid view that I have that I can edit, update, delete from. 我是一个网格视图,我可以编辑,更新,删除。 I can manually add a drop down and have the selected value populate correctly, but I want to be able to populate the drop down from the database (and show the selected value correctly) when editing it. 我可以手动添加下拉列表并正确填充所选值,但我希望能够在编辑时填充数据库中的下拉列表(并正确显示所选值)。

I have tried a bunch of searches/options but can not find a way to make it work. 我尝试了一堆搜索/选项,但找不到让它工作的方法。

My code is below: 我的代码如下:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            PopulateData();
            lblMessage.Text = "";
        }

        string sSQL = "";

        // populate drop downs
        sSQL = @"SELECT ErrorTypeLookupID as Value, ErrorDescription as DisplayText
            FROM BabelFish.dbo.ErrorTypeLookup (NOLOCK)
            WHERE ErrorType = 'Category'
            ";
        //ORDER BY OrderBy, ErrorDescription";

        new DatabaseConnection().PopulateListBoxFromDB(sSQL, "", lstNewResolutionCategory);


        sSQL = @"SELECT ErrorTypeLookupID as Value, ErrorDescription as DisplayText
            FROM BabelFish.dbo.ErrorTypeLookup (NOLOCK)
            WHERE ErrorType = 'Severity'
            ";
        //ORDER BY OrderBy, ErrorDescription";

        new DatabaseConnection().PopulateListBoxFromDB(sSQL, "", lstNewResolutionSeverity);


    }//end page load


    protected void DeleteRow(object sender, GridViewDeleteEventArgs e)
    {

        var ResolutionsID = GridView1.DataKeys[e.RowIndex].Value;

        GridViewRow row = GridView1.Rows[e.RowIndex] as GridViewRow;

        string sSQL = "Delete from BabelFish.dbo.Resolutions where ResolutionsID = @ResolutionsID";

        SqlCommand sCommand = new SqlCommand(sSQL);

        sCommand.Parameters.AddWithValue("@ResolutionsID", ResolutionsID);

        // run delete
        new DatabaseConnection().RSExecute(sCommand);

        lblMessage.Text = "Record deleted successfully !";

        GridView1.EditIndex = -1;

        this.PopulateData();

    }




    protected void UpdateRow(object sender, GridViewUpdateEventArgs e)
    {

        var ResolutionsID = GridView1.DataKeys[e.RowIndex].Value;

        GridViewRow row = GridView1.Rows[e.RowIndex] as GridViewRow;

        TextBox txtResolutionDescription = row.FindControl("txtResolutionDescription") as TextBox;
        DropDownList drpErrorCategoryID = row.FindControl("ErrorCategory") as DropDownList;


        string sSQL = @"Update BabelFish.dbo.Resolutions set 
                    ResolutionDescription = @ResolutionDescription,
                    UserIDSolved = ISNULL(BabelFish.dbo.fn_GetUserIDFromTeamMemberTable(@UserIDSolved), BabelFish.dbo.fn_GetUserIDFromTeamMemberTable(REPLACE(@UserIDSolved, '-', ''))), 
                    DateTimeSolved = ISNULL(DateTimeSolved, GetDate())                        
                    where ResolutionsID = @ResolutionsID";

        SqlCommand sCommand = new SqlCommand(sSQL);

        sCommand.Parameters.AddWithValue("@ResolutionDescription", txtResolutionDescription.Text.Trim());
        sCommand.Parameters.AddWithValue("@ResolutionsID", ResolutionsID);
        sCommand.Parameters.AddWithValue("@UserIDSolved", UserID);

        // run update
        new DatabaseConnection().RSExecute(sCommand);


        lblMessage.Text = "Record updated successfully !";

        GridView1.EditIndex = -1;

        this.PopulateData();

    }




    private void PopulateData()
    {
        string sSQL = @"SELECT
                ResolutionsID, ErrorTableID, BabelFish.dbo.fn_GetUserNameFromTeamMemberTable(UserIDSolved) as UserIDSolved, 
                DateTimeSolved, ResolutionDescription, ResolutionCategory, ResolutionSeverity, IsActive
                FROM BabelFish.dbo.Resolutions (NOLOCK)
                Where ErrorTableID = '" + ErrorTableID + "'";

        DataTable dt = DatabaseAccessing.DatabaseConnection.GetDataTable(sSQL);

        // only do if more then 1 row exists
        if (dt.Rows.Count > 0)
        {
            GridView1.DataSource = dt;

            GridView1.DataBind();
        }
        else
        {
            lblMessage.Text = "No Rows Exist.";
        }




    }


    protected void AddRow(object sender, EventArgs e)
    {
        // get values to add to database
        string txtResolutionDescription = txtNewResolutionDescription.Text.ToString();

        string lstCategoryID = lstNewResolutionCategory.SelectedValue;
        string lstSeverityID = lstNewResolutionSeverity.SelectedValue;

        string sSQL = @"INSERT INTO BabelFish.dbo.Resolutions (
            ErrorTableID, UserIDSolved, DateTimeSolved, ResolutionDescription, 
            ResolutionCategory, ResolutionSeverity, IsActive
        )

        VALUES (
            @ErrorTableID, ISNULL(BabelFish.dbo.fn_GetUserIDFromTeamMemberTable(@UserIDSolved), BabelFish.dbo.fn_GetUserIDFromTeamMemberTable(REPLACE(@UserIDSolved, '-', ''))), 
            GetDate(), @ResolutionDescription,
            @ResolutionCategory, @ResolutionSeverity, 1
        )";


        SqlCommand sCommand = new SqlCommand(sSQL);

        sCommand.Parameters.AddWithValue("@ErrorTableID", ErrorTableID);
        sCommand.Parameters.AddWithValue("@UserIDSolved", UserID);
        sCommand.Parameters.AddWithValue("@ResolutionDescription", txtResolutionDescription);
        sCommand.Parameters.AddWithValue("@ResolutionCategory", lstCategoryID);
        sCommand.Parameters.AddWithValue("@ResolutionSeverity", lstSeverityID);


        // run update
        new DatabaseConnection().RSExecute(sCommand);


        lblMessage.Text = "Record successfully added!";

        GridView1.EditIndex = -1;

        this.PopulateData();
    }


    protected void EditRow(object sender, GridViewEditEventArgs e)
    {
        GridView1.EditIndex = e.NewEditIndex;

        this.PopulateData();

        /*
        //not working, ddl is NULL
        var ddl = (DropDownList)GridView1.FindControl("selResolutionSeverity");

        string sSQL = @"SELECT ErrorTypeLookupID as Value, ErrorDescription as DisplayText
            FROM BabelFish.dbo.ErrorTypeLookup (NOLOCK)
            WHERE ErrorType = 'Severity' ";


        DataSet DS = new DatabaseAccessing.DatabaseConnection().DS(sSQL);

        ddl.DataSource = DS;
        ddl.DataTextField = "DisplayText";
        ddl.DataValueField = "Value";
        ddl.DataBind();
        ddl.Items.Insert(0, new ListItem("-- Select --", "0"));
         * */
    }



    protected void CancelEditRow(object sender, GridViewCancelEditEventArgs e)
    {
        GridView1.EditIndex = -1;
        this.PopulateData();
    }


    protected void ChangePage(object sender, GridViewPageEventArgs e)
    {

        GridView1.PageIndex = e.NewPageIndex;
        this.PopulateData();

    }



    <asp:Label ID="lblMessage" runat="server" ForeColor="Green" EnableViewState="false" />

    <asp:GridView ID="GridView1" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None"
        AutoGenerateColumns="false" 
        Width="100%" 
        OnRowEditing="EditRow" 
        OnRowCancelingEdit="CancelEditRow"
        OnRowUpdating="UpdateRow" 
        DataKeyNames="ResolutionsID" 
        OnRowDeleting="DeleteRow" 
        AllowPaging="true"
        PageSize="50" 
        OnPageIndexChanging="ChangePage"            

        >

    <Columns>

        <asp:TemplateField HeaderText="Edit">

            <ItemTemplate>
                <asp:LinkButton ID="lnkEdit" runat="server" Text="Edit" CommandName="Edit" />
            </ItemTemplate>

            <EditItemTemplate>

                <asp:LinkButton ID="lnkUpdate" runat="server" Text="Update" CommandName="Update" />

                <asp:LinkButton ID="lnkCancel" runat="server" Text="Cancel" CommandName="Cancel" />

            </EditItemTemplate>

        </asp:TemplateField>


        <asp:BoundField HeaderText="ResolutionsID" DataField="ResolutionsID" ReadOnly="true" />

        <asp:TemplateField HeaderText="ResolutionDescription">
            <ItemTemplate><%# Eval("ResolutionDescription")%></ItemTemplate>

            <EditItemTemplate>
                <asp:TextBox ID="txtResolutionDescription" runat="server" Text='<%# Eval("ResolutionDescription") %>'/>
            </EditItemTemplate>
        </asp:TemplateField>

        <asp:BoundField HeaderText="UserIDSolved" DataField="UserIDSolved" ReadOnly="true" />

        <asp:TemplateField HeaderText="Category">
            <ItemTemplate>
                <%# Eval("ResolutionCategory")%>
            </ItemTemplate>

            <HeaderStyle HorizontalAlign="Left" />
                <EditItemTemplate>  
                    <asp:DropDownList ID="selResolutionCategory" runat="server" SelectedValue='<%# Eval("ResolutionCategory") %>'>         
                        <asp:ListItem Text="-- Select One --" Value="0" />
                        <asp:ListItem Text="cat1" Value="1" />
                        <asp:ListItem Text="cat2" Value="2" />        
                    </asp:DropDownList>
                </EditItemTemplate>
        </asp:TemplateField>


        <asp:TemplateField HeaderText="Severity">
            <ItemTemplate>
                <%# Eval("ResolutionSeverity")%>
            </ItemTemplate>

            <HeaderStyle HorizontalAlign="Left" />
                <EditItemTemplate>  
                    <asp:DropDownList ID="selResolutionSeverity" runat="server">                                     
                    </asp:DropDownList>
                </EditItemTemplate>
        </asp:TemplateField>


        <asp:TemplateField HeaderText="Delete?">
            <ItemTemplate>
                <span onclick="return confirm('Are you sure to delete?')">
                    <asp:LinkButton ID="lnkDelete" runat="server" Text="Delete" ForeColor="Red" CommandName="Delete" />
                </span>
            </ItemTemplate>

        </asp:TemplateField> 


    </Columns>

    <AlternatingRowStyle BackColor="White" />

    <EditRowStyle BackColor="#efefef" />

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

    <SortedAscendingCellStyle BackColor="#F5F7FB" />

    <SortedAscendingHeaderStyle BackColor="#6D95E1" />

    <SortedDescendingCellStyle BackColor="#E9EBEF" />

    <SortedDescendingHeaderStyle BackColor="#4870BE" />

    </asp:GridView>

You are going to want to use OnRowDataBound. 您将要使用OnRowDataBound。 Here is the example of how I populate one of my drop downs within my gridview. 以下是我在gridview中填充其中一个下拉列表的示例。

protected void gvVehicle_OnRowDataBound(object sender, GridViewRowEventArgs e)
    {
        foreach (GridViewRow gvr in gvVehicleTEMP.Rows)
        {
            DropDownList ddlLocation = ((DropDownList)gvr.FindControl("ddlLocation"));
            Label lblLocationLabel = ((Label)gvr.FindControl("lblLocationLabel"));

            conn.Close();
            conn.Open();

            SqlCommand cmdLocationNames = new SqlCommand("SELECT Name FROM Billers WHERE Store = '" + 1 + "' ORDER BY Name ASC", conn);
            List<string> internalLocationsList = new List<string>();

            using (SqlDataReader reader = cmdLocationNames.ExecuteReader())
            {
                while (reader.Read())
                {
                    string interlocations = reader.GetString(0);
                    internalLocationsList.Add(interlocations);
                }
                foreach (string locname in internalLocationsList)
                {
                    ddlLocation.Items.Add(new ListItem(locname));
                    conn.Close();
                }
                conn.Close();
            }

            conn.Close();

        }

  //EDIT: if (lblLocationLabel.Text.Length > 0)
            {
                 ddlLocation.SelectedValue = lblLocationLabel.Text;
            }
    }  

So, I used an SqlDataReader and then I add the "Billers" to the list. 所以,我使用了一个SqlDataReader然后将“Billers”添加到列表中。 Once that happens, I add the listItems to the Drop Down List. 一旦发生这种情况,我将listItems添加到下拉列表中。

What I had to do for it to select properly was Bind the text to a label, then say.. 我必须做的才能正确选择是将文本绑定到标签,然后说..

ddlLocation.SelectedValue = lblLabelLocation.Text; ddlLocation.SelectedValue = lblLabelLocation.Text;

Don't Forget to put the OnRowDataBound in your gridview properties as well. 不要忘记将OnRowDataBound也放在gridview属性中。 I hope this helps. 我希望这有帮助。

EDIT: 编辑:

This is how I did it. 这就是我做到的。 I used an if statement to check to see if that label's text length is not blank (I have a blank field in my drop down) and if it does have text, then select or show the value.. I made the edit above but here it is again. 我使用if语句检查该标签的文本长度是否为空(我的下拉列表中有一个空白字段),如果它有文本,则选择或显示值..我在上面进行了编辑但是这里它又来了。

protected void gvVehicle_OnRowDataBound(object sender, GridViewRowEventArgs e)
    {
        foreach (GridViewRow gvr in gvVehicleTEMP.Rows)
        {
            DropDownList ddlLocation = ((DropDownList)gvr.FindControl("ddlLocation"));
            Label lblLocationLabel = ((Label)gvr.FindControl("lblLocationLabel")); //add this line to find the label

            conn.Close();
            conn.Open();

            SqlCommand cmdLocationNames = new SqlCommand("SELECT Name FROM Billers WHERE Store = '" + 1 + "' ORDER BY Name ASC", conn);
            List<string> internalLocationsList = new List<string>();

            using (SqlDataReader reader = cmdLocationNames.ExecuteReader())
            {
                while (reader.Read())
                {
                    string interlocations = reader.GetString(0);
                    internalLocationsList.Add(interlocations);
                }
                foreach (string locname in internalLocationsList)
                {
                    ddlLocation.Items.Add(new ListItem(locname));
                    conn.Close();
                }
                conn.Close();
            }

            conn.Close();

        }

      if (lblLocationLabel.Text.Length > 0)//Added if statement
            {
                 ddlLocation.SelectedValue = lblLocationLabel.Text;
            }
    } 

I use a templatefield like so. 我使用像这样的模板字段。

<asp:TemplateField HeaderText="Location" SortExpression="Received">
           <ItemTemplate>
                  <asp:DropDownList ID="ddlLocation" runat="server" AutoPostBack="false">
                  </asp:DropDownList>
                  <asp:Label ID="lblLocationLabel" runat="server" Text='<%# Bind("Location") %>' Visible="false"></asp:Label>
                              <font size="2">Received On: </font>
           </ItemTemplate>
           <HeaderStyle Width="200px" />
</asp:TemplateField>

I hope this cleared it up a bit. 我希望这有点清除它。

There are a couple of issues here: 这里有几个问题:

  1. You don't appear to be populating the DropDownList with id selResolutionSeverity and 您似乎没有使用id selResolutionSeverity填充DropDownList
  2. Your FindControl() won't work at the parent control level (you need to first locate the row being updated) 您的FindControl()将无法在父控件级别工作(您需要首先找到正在更新的行)

I suggest you simplify the program by using data binding. 我建议你使用数据绑定来简化程序。 If you are able to create a DataSource (eg SqlDataSource) for the severities, then you won't need to put any specific logic in the code behind. 如果您能够为严重性创建一个DataSource(例如SqlDataSource),那么您将不需要在代码中放置任何特定的逻辑。 The following example assumes you have a SqlDataSource in your page called dsSeverities . 以下示例假定您的页面中有一个名为dsSeveritiesSqlDataSource If you don't wish to go down this route, then you could alternatively populate the DropDownList within a RowDataBound event handler. 如果您不希望沿着这条路线走下去,那么您也可以在RowDataBound事件处理程序中填充DropDownList。

<asp:TemplateField HeaderText="Severity">
 <HeaderStyle HorizontalAlign="Left" />
 <ItemTemplate>
   <%# Eval("ResolutionSeverity")%>
 </ItemTemplate>

 <EditItemTemplate>
   <asp:DropDownList  ID="selResolutionSeverity" runat="server"
     DataSourceID="dsSeverities"
     DataTextField="Description"
     DataValueField="ID"
     SelectedValue='<%# Bind("ResolutionSeverity") %>'  />
 </EditItemTemplate>
</asp:TemplateField>

You have to find the DropDownList in the GridViewRow which is in Edit mode on GridView 's OnRowDataBound event. 您必须在GridViewRow找到DropDownList ,它在GridViewOnRowDataBound事件上处于编辑模式

Here's how you can do this: 这是你如何做到这一点:

In markup add a method to GridView 's OnDtatBound. 在标记中为GridView的OnDtatBound添加一个方法。 :

<asp:GridView ID="GridView1" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None"
    ... ... ...
    OnRowDataBound="GridView1_RowDataBound" >

Now in the code write your GridView1_RowDataBound method write this code ( I would highly recommend replacing the query string with parameterized query to prevent possible sql injection) : 现在在代码中编写你的GridView1_RowDataBound方法编写这段代码(我强烈建议用参数化查询替换查询字符串以防止可能的sql注入):

protected void GridView1_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
    //Make sure the row is in edit mode to find controls in EditItemTemlates
    if ((e.Row.RowType == DataControlRowType.DataRow) && ((e.Row.RowState & DataControlRowState.Edit) > 0))
    {

        var ddl = GridView1.FindControl("selResolutionSeverity") as DropDownList;
        if (ddl != null)
        {

            // Consider using parameterized query to prevent possible sql injection
            string sSQL = @"SELECT ErrorTypeLookupID as Value, ErrorDescription as DisplayText
                            FROM BabelFish.dbo.ErrorTypeLookup (NOLOCK)
                            WHERE ErrorType = 'Severity' ";

            DataSet DS = new DatabaseAccessing.DatabaseConnection().DS(sSQL);
            ddl.DataSource = DS;
            ddl.DataTextField = "DisplayText";
            ddl.DataValueField = "Value";
            ddl.DataBind();
            ddl.Items.Insert(0, new ListItem("-- Select --", "0"));
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM