Search code examples
c#asp.nett-sqldrop-down-menuhierarchy

Display Hierarchy in a DropDown List


I have a data hierarchy that I currently display in a treeview. I was wondering what would be the easiest way to convert this hierarchy into a dropdown list as well. In a treeview I can find a specific node and add an item under that node. I'm not sure how to do that with a drop down list. Below is the code I have for the dropdown so far:

DropDown Hierarchy
**Solved

    public void DropDownTree(DropDownList ddl)
    {
        ddl.Items.Clear(); 
        using (SqlConnection connection = new SqlConnection())
        {
            // Data Connection
            connection.ConnectionString = (ConfigurationManager.ConnectionStrings["AssetWhereConnectionString"].ConnectionString);
            connection.Open();
            string getLocations = @"
                With hierarchy (id, [location id], name, depth, [path])
                As (

                    Select ID, [LocationID], Name, 1 As depth,
                        Cast(Null as varChar(max)) As [path]
                    From dbo.Locations
                    Where ID = [LocationID]

                    Union All

                    Select child.id, child.[LocationID], child.name,
                        parent.depth + 1 As depth,
                        IsNull(
                            Cast(parent.id As varChar(max)),
                            Cast(parent.id As varChar(max))
                        ) As [path]
                    From dbo.Locations As child
                    Inner Join hierarchy As parent
                        On child.[LocationID] = parent.ID
                    Where child.ID != parent.[Location ID])

                Select *
                From hierarchy
                Order By [depth] Asc";

            using (SqlCommand cmd = new SqlCommand(getLocations, connection))
            {
                cmd.CommandType = CommandType.Text;
                using (SqlDataReader rs = cmd.ExecuteReader())
                {
                    while (rs.Read())
                    {
                        string id = rs.GetGuid(0).ToString();
                        int depth = rs.GetInt32(3);
                        string text = rs.GetString(2);
                        string locationID = rs.GetGuid(1).ToString();
                        string padding = String.Concat(Enumerable.Repeat("- ", 2 * depth));


                        if (id == locationID)
                        {
                            ddl.Items.Add(new ListItem(padding + text, id));
                        }
                        else
                        {
                            int index = ddl.Items.IndexOf(ddl.Items.FindByValue(rs.GetString(4).ToString().ToLower()));

                            // Fix the location where the item is inserted. 
                            index = index + 1;

                            ddl.Items.Insert(index, new ListItem(padding + text, id));

                        }
                    }
                }
            }
        }
    }

Solution

  • Your code looks fine but from your comment under your question, it sounds like you are getting a negative value for the index on this line:

    int index =  ddl.Items.IndexOf(ddl.Items.FindByValue(rs.GetString(4).ToString().ToLower()));
    

    A negative value indicates that the dropdownlist item that you were searching for was not found. This would certainly be the case if the dropdownlist is empty. You would be searching for an item that doesn't exist.

    Below is an update to your code that will produce the following (which I believe is what you're looking for): enter image description here

    Try changing your code to the following:

    if (id == locationID)
    {
        ddl.Items.Add(new ListItem(padding + text, id));
    }
    else
    {
        int index =  ddl.Items.IndexOf(ddl.Items.FindByValue(rs.GetString(4).ToString().ToLower()));
    
        //Check to see if this item exists before trying to insert
        if (index == -1) 
        {
            //Add the item if it doesn't exist
            ddl.Items.Add(new ListItem(padding + text, id));
        }
        else
        {
            ddl.Items.Insert(index, new ListItem(padding + text, id));
        }
    }