In this article, we will create a dynamic tree view menu fetched
from the database, using ASP.NET MVC 5, C#, Razor and SQL Server 2014 (using Visual
Studio 2013). This article will guide you on how to display parent child tree view dynamically from the database. This is the best, easiest, and fastest way to
make tree view. Let's try to populate it.
Step 1
Create a table and insert the records, as per your requirement. The table structure is given below.
Create table query
- CREATE TABLE [dbo].[Categories](
- [CategoryId] [int] primary key identity(1,1),
- [CategoryName] [varchar](40),
- [ParentCategoryId] [int],
- [Remarks] [nvarchar](max),
- )
Step 2
I have attached sample SQL query file named “categoryDb.sql” to create table and insert the records. Just run the query to make database and insert the records. You can insert records manually also.
Create a new project and take Empty ASP.NET MVC Application. Here, I have used MVC 5 project.
Step 4
Add new Class Library Project. The solution is named Business Layer which contains an actual logic and an interaction with the database.
Step 5
Add new class named SqlAccess in BusinessLayer project. The class has a constructor to initialize SqlConnection and a method, which will take query in the string format and return rows in DataTable.
- #region Declaration
- SqlConnection con;
- DataTable dt;
- #endregion
-
- #region Constructor
- public SqlAccess()
- {
- con = new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["ConStr"]);
- }
- #endregion
-
- #region KeyMethods
- public DataTable GetDataTableFromDb(string query)
- {
- SqlDataAdapter Adpt = new SqlDataAdapter(query, con);
- dt = new DataTable();
- try
- {
- Adpt.Fill(dt);
- }
- catch (SqlException ex)
- {
- dt = null;
- if (con.State == ConnectionState.Open)
- con.Close();
- }
- finally
- {
- if (con != null)
- if (con.State == ConnectionState.Open) con.Close();
- Adpt.Dispose();
- }
- return dt;
- }
- #endregion
Step 6
Add another class named HomeBAL in BusinessLayer. This class contains a method that passes query to SqlAccess and returns the DataTable.
- public DataTable GetAllCategories()
- {
- return new SqlAccess().GetDataTableFromDb("SELECT CategoryId, CategoryName, ParentCategoryId FROM Categories");
- }
Step 7
Now, we need to access BusinessLayer members from our PresentationLayer (MVC Project). So, give the referenc of BusinessLayer to PresentationLayer.
Make sure that the BusinessLayer is referenced inside "References" of PresentationLayer.
Step 8
Add a new class named Category in PresentationLayer, which contains database structure properties.
- public class Category
- {
- public int CategoryId { get; set; }
- public string CategoryName { get; set; }
- public System.Nullable<int> ParentCategoryId { get; set; }
- }
Step 9
Add a new class named TreeNode in “PresentationLayer” which contains database properties, and add one more List<> type of property which will hold all the children of the particular category.
- public class TreeNode
- {
- public int CategoryId { get; set; }
- public string CategoryName { get; set; }
-
- public TreeNode ParentCategory { get; set; }
- public List<TreeNode> Children { get; set; }
- }
Step 10
Add a new Controller named “HomeController” which has one action method (Index) and two other methods.
Index Action Method
- public ActionResult Index()
- {
- ViewBag.Tree = GetAllCategoriesForTree();
- return View();
- }
Recursive method
- private static List<TreeNode> FillRecursive(List<Category> flatObjects, int? parentId = null)
- {
- return flatObjects.Where(x => x.ParentCategoryId.Equals(parentId)).Select(item => new TreeNode
- {
- CategoryName = item.CategoryName,
- CategoryId = item.CategoryId,
- Children = FillRecursive(flatObjects, item.CategoryId)
- }).ToList();
- }
Get all categories from database and generate html string,
- public string GetAllCategoriesForTree()
- {
- List<Category> categories = new List<Category>();
- DataTable dt = new HomeBAL().GetAllCategories();
-
- if (dt != null && dt.Rows.Count > 0)
- {
- foreach (DataRow row in dt.Rows)
- {
- categories.Add(
- new Category
- {
- CategoryId = Convert.ToInt32(row["CategoryId"]),
- CategoryName = row["CategoryName"].ToString(),
- ParentCategoryId = (Convert.ToInt32(row["ParentCategoryId"]) != 0) ? Convert.ToInt32(row["ParentCategoryId"]) : (int?) null
- });
- }
-
- List<TreeNode> headerTree = FillRecursive(categories, null);
-
- #region BindingHeaderMenus
-
- string root_li = string.Empty;
- string down1_names = string.Empty;
- string down2_names = string.Empty;
-
- foreach (var item in headerTree)
- {
- root_li += "<li class=\"dropdown mega-menu-fullwidth\">"
- + "<a href=\"/Product/ListProduct?cat=" + item.CategoryId + "\" class=\"dropdown-toggle\" data-hover=\"dropdown\" data-toggle=\"dropdown\">" + item.CategoryName + "</a>";
-
- down1_names = "";
- foreach (var down1 in item.Children)
- {
- down2_names = "";
- foreach (var down2 in down1.Children)
- {
- down2_names += "<li><a href=\"/Product/ListProduct?cat=" + down2.CategoryId + "\">" + down2.CategoryName + "</a></li>";
- }
- down1_names += "<div class=\"col-md-2 col-sm-6\">"
- + "<h3 class=\"mega-menu-heading\"><a href=\"/Product/ListProduct?cat=" + down1.CategoryId + "\">" + down1.CategoryName + "</a></h3>"
- + "<ul class=\"list-unstyled style-list\">"
- + down2_names
- + "</ul>"
- + "</div>";
- }
- root_li += "<ul class=\"dropdown-menu\">"
- + "<li>"
- + "<div class=\"mega-menu-content\">"
- + "<div class=\"container\">"
- + "<div class=\"row\">"
- + down1_names
- + "</div>"
- + "</div>"
- + "<div>"
- + "</li>"
- + "</ul>"
- + "</li>";
- }
- #endregion
-
- return "<ul class=\"nav navbar-nav\">" + root_li + "</ul>";
- }
- return "Record Not Found!!";
- }
Step 11
Add new View named “Index.cshtml” which contains our webpage's body and displays the viewbag return from Controller.
- <!DOCTYPE html>
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- <title>Dynamic Tree</title>
- </head>
- <body>
- <div class="header-v5 header-static">
-
-
- <div class="navbar navbar-default mega-menu" role="navigation">
- <div class="container">
- <div class="collapse navbar-collapse navbar-responsive-collapse">
- @Html.Raw(ViewBag.Tree);
- </div>
- </div>
- </div>
-
- </div>
- </body>
- </html>
Step 12
If you run this action, your tree is ready but without design, as shown below.
Step 13
Put the CSS content inside project and include it in page. You can see successfully generated TreeView like below.
Final Output
Thank you developers… I have attached the full project with this article. Please comment if you encounter any issues here.
Note
Here, I am showing you two queries which are getting all categories from db.
Simple Parent Child
- SELECT
- CategoryId,
- CategoryName,
- ParentCategoryId
- FROM
- Categories
If you want TreeView from SQL query,
- SELECT
- CASE
- WHEN
- down1.CategoryName is null
- THEN
- root.CategoryId
- WHEN
- down2.CategoryName is null
- THEN
- down1.CategoryId
- WHEN
- down3.CategoryName is null
- THEN
- down2.CategoryId
- ELSE
- 0
- END AS CategoryId
- ,root.CategoryName as root_name
- ,ISNULL(down1.CategoryName,'') as down1_name
- ,ISNULL(down2.CategoryName,'') as down2_name
- ,ISNULL(down3.CategoryName,'') as down3_name
- FROM Categories as root
- LEFT OUTER
- JOIN Categories AS down1
- ON down1.ParentCategoryId = root.CategoryId
- LEFT OUTER
- JOIN Categories AS down2
- ON down2.ParentCategoryId = down1.CategoryId
- LEFT OUTER
- JOIN Categories AS down3
- ON down3.ParentCategoryId = down2.CategoryId
- WHERE root.ParentCategoryId = 0
- ORDER
- BY root_name
- , down1_name
- , down2_name
- , down3_name
Hope you like it. Thank you for reading. Like and share, and keep learning.