FlexGrid ASP.NET MVC TreeView 컨트롤로 계층적 그룹화 추가

FlexGrid는 CRUD 작업을 수행하는 데 유용한 구성 요소입니다. 계층적 데이터를 표시하는 것은 FlexGrid의 고유하고 널리 사용되는 기능 중 하나입니다. FlexGrid는 그룹 행을 사용하여 계층적 데이터를 표시합니다.

Flexgrid의 계층적 데이터에 대한 이러한 행의 동작은 여러 열을 사용하는 추가 정보가 있는 TreeView와 유사합니다. 토글 아이콘은 하위 항목이 있는 행에 대해 표시되며, 이 아이콘을 클릭하면 TreeView와 유사하게 확장/축소로 전환됩니다.

TreeGrid에는 노드의 계층 구조를 나타내는 '레벨' 속성도 포함되어 있습니다. 하위 수준 노드는 상위 수준 노드를 유지합니다.

이 블로그에서는 FlexGrid에서 계층 구조 데이터를 표시하는 다양한 방법에 대해 설명합니다.
  • Grouping
  • Hierarchal Data Binding and Editing
  • Displaying Hierarchal Data Using Unbound Mode
  • XML Data Binding
  • Lazy Loading

  • 그룹화

    FlexGrid, by default, supports binding to a Database. The data would be displayed in the same order as it was in the Database. However, if we want the aggregate for columns, we need to calculate them explicitly.  

    To overcome this issue, FlexGrid has the grouping feature to set the aggregate for the columns.  

    Here is the code to set FlexGrid’s DataSource from the Model.

      

        <c1-flex-grid group-header-format="{value}" auto-generate-columns="false" style="height:300px"> 
                <c1-flex-grid-column binding="ID" header="ID"></c1-flex-grid-column> 
                <c1-flex-grid-column binding="First" header="First"></c1-flex-grid-column> 
                <c1-flex-grid-column binding="Last" header="Last"></c1-flex-grid-column> 
                <c1-flex-grid-column binding="Hired" header="Hired"></c1-flex-grid-column> 
                <c1-flex-grid-column binding="Sales" header="Sales"></c1-flex-grid-column> 
                <c1-flex-grid-column binding="Downloads" header="Downloads"></c1-flex-grid-column> 
                <c1-flex-grid-column binding="Active" header="Active"></c1-flex-grid-column> 
    
                <c1-items-source source-collection="Model" ></c1-items-source> 
            </c1-flex-grid> 
    

    To add the grouping in the FlexGrid, the PropertyGroupDescription instance should be added to the groupDescriptions property.  

    Here is the code for applying grouping and adding aggregates:

     

        <c1-flex-grid group-header-format="{value}" auto-generate-columns=false style="height:300px"> 
                <c1-flex-grid-column binding="ID" header="ID"></c1-flex-grid-column> 
                <c1-flex-grid-column binding="First" header="First"></c1-flex-grid-column> 
                <c1-flex-grid-column binding="Last" header="Last"></c1-flex-grid-column> 
                <c1-flex-grid-column binding="Hired" header="Hired" ></c1-flex-grid-column> 
                <c1-flex-grid-column binding="Sales" header="Sales" aggregate="Sum"></c1-flex-grid-column> 
                <c1-flex-grid-column binding="Downloads" header="Downloads" aggregate="Sum"></c1-flex-grid-column> 
                <c1-flex-grid-column binding="Active" header="Active"></c1-flex-grid-column> 
    
                  <c1-items-source source-collection="Model" group-by="Country"></c1-items-source> 
            </c1-flex-grid> 
    

    Here’s how FlexGrid would look after applying the grouping to FlexGrid:



    이미지에서 회색으로 강조 표시된 그룹 행에서 국가별로 그룹화된 판매 및 다운로드를 관찰할 수 있습니다.

    계층적 데이터 바인딩 및 편집

    In some instances, the data objects could be hierarchical instead of Flat recordsets. To display this data in FlexGrid, we can use the child-items-path property. This property value would be the property in items having the child items.  

    Here is the code to show the hierarchical data:

     

         <c1-flex-grid auto-generate-columns=false child-items-path="Children" height="500px"> 
            <c1-flex-grid-column binding="Header" width="*"> </c1-flex-grid-column> 
            <c1-flex-grid-column binding="DateModified"></c1-flex-grid-column> 
            <c1-flex-grid-column binding="Size"></c1-flex-grid-column>  
    
            <c1-items-source source-collection="Model"></c1-items-source> 
        </c1-flex-grid>
    

    The FlexGrid looks as follows: 



    기본적으로 FlexGrid 노드는 편집을 허용하지 않습니다. 사용자가 편집할 수 있도록 하려면 loaded-rows 이벤트를 처리하고 행에 대해 isReadOnly 속성을 false로 설정해야 합니다.

    동일한 코드는 다음과 같습니다.


        <script> 
            function loadedRows(s,e){ 
                for (let i = 0;i<s.rows.length;i++){ 
                    s.rows[i].isReadOnly = false; 
                } 
            } 
        </script>
        <c1-flex-grid auto-generate-columns=false child-items-path="Children" height="500px" loaded-rows="loadedRows"></c1-flex-grid> 
    


    언바운드 모드를 사용하여 계층 데이터 표시

    The unbound mode allows you to create data items at the client-side and add them to the existing FlexGrid; in this case, the itemsSource would be null, and the rows would be added using the JS code by pushing the row and setting the cell data using the FlexGrid’s setCellData() method.  

    Here is the code to show the TreeGrid from the hierarchy data using the JS Code.

     
     

        // Controller Code 
        [HttpGet,Route("Home/GetData")] 
                public string GetResult() 
                { 
                    var list = Folder.Create(Directory.GetCurrentDirectory()).Children; 
                    return JsonConvert.SerializeObject(list); 
                } 
        //View Code 
        <c1-flex-grid id="ubgrid" auto-generate-columns="false" > 
            <c1-flex-grid-column header="Header"  width="*"></c1-flex-grid-column> 
            <c1-flex-grid-column header="Modified Date"></c1-flex-grid-column> 
            <c1-flex-grid-column header="Size" align="right" ></c1-flex-grid-column> 
    
        </c1-flex-grid> 
        <script> 
            c1.documentReady(function () { 
                let grid = wijmo.Control.getControl("#ubgrid"); 
                // set FlexGrid data 
                $.get("/Home/GetData").then(function(d) {  
                    setGridData(grid, JSON.parse(d));     
                }) 
            }); 
            function setGridData(grid,data) { 
                for (let r = 0; r < data.length; r++) { 
                    // add header 
                    var header = data[r]; 
                    var row = new wijmo.grid.GroupRow(); 
                    row.dataItem = header; 
                    row.isReadOnly = false; 
                    row.level = 0; 
                    grid.rows.push(row); 
                    grid.setCellData(row.index, 0, header.Header); 
                    if (header.Children) { 
                        addChild(grid, header, 1); 
                    } 
                } 
            } 
    
            function addChild(grid, parent, level){ 
                for (var c = 0; c < parent.Children.length; c++) { 
                    // add children 
                    var child = parent.Children[c]; 
                    row = new wijmo.grid.GroupRow(); 
                    row.dataItem = child; 
                    row.isReadOnly = false; 
                    row.level = level; 
                    grid.rows.push(row); 
                    grid.setCellData(row.index, 0, child.Header); 
                    if (child.DateModified) { 
                        grid.setCellData(row.index, 1, new Date(child.DateModified)); 
                    } 
                    grid.setCellData(row.index, 2, child.Size); 
                    if (child.Children) { 
                        addChild(grid, child, level+1); 
                    } 
                } 
            } 
    
        </script> 
    

    XML 데이터 바인딩

    This feature is useful for the users who already have the data in XML format from the existing application or the API returns the XML data.  

    To display the data from an XML file, we need to read the XML data and convert it to the IEnumerable data. Later, we will bind it to the FlexGrid.  

    Here is the code for the same: 

    XML 데이터를 목록으로 변환




        public class TProduct 
            { 
                public int Id { get; set; } 
                public string Name { get; set; } 
                public List<TEditions> Products { get; set; } 
            } 
    
            public class TEditions 
            { 
                public string Name { get; set; } 
                public double Price { get; set; } 
                public double Discount { get; set; } 
                public string? PromoCode { get; set; } 
            } 
    
            public class ProductInfo 
            { 
                public static List<TProduct> GetProducts(string path) 
                { 
                    var _items = new List<TProduct>(); 
                    var _xml = XElement.Load(path); 
                    var _products = _xml.Elements("Product"); 
                    foreach (var item in _products) 
                    { 
                        _items.Add(new TProduct() 
                        { 
                            Id = Convert.ToInt32(item.Attribute("id").Value), 
                            Name = item.Attribute("name").Value, 
                            Products = new List<TEditions>() 
                        }); 
                       var _editions = item.Elements("Edition"); 
                        foreach (var _edition in _editions) 
                        { 
                            _items[_items.Count - 1].Products.Add(new TEditions() 
                            { 
                                Name = _edition.Attribute("name").Value, 
                                Discount = Convert.ToDouble(_edition.Attribute("discount")?.Value), 
                                Price = Convert.ToDouble(_edition.Attribute("price").Value), 
                                PromoCode = _edition.Attribute("promocode")?.Value 
                            }); 
                        } 
                    } 
    
                    return _items; 
                } 
            } 
    


    데이터를 FlexGrid에 바인딩





        // Controller 
        public IActionResult XMLBinding() 
                { 
                    var _path = Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\Content\ProductsInfo.xml"); 
                    return View(ProductInfo.GetProducts(_path)); 
                } 
    
        //View 
    
        @model List<TProduct> 
    
        <c1-flex-grid auto-generate-columns="false" child-items-path="Products" headers-visibility="Column"> 
            <c1-flex-grid-column binding="Name" header="Name" width="*"></c1-flex-grid-column> 
            <c1-flex-grid-column binding="Price" header="Price" format="c0" align="right"></c1-flex-grid-column> 
            <c1-flex-grid-column binding="Discount" header="Discount" format="p2" align="right"></c1-flex-grid-column> 
            <c1-flex-grid-column binding="PromoCode" header="Promo Code" ></c1-flex-grid-column> 
    
            <c1-items-source source-collection="Model"></c1-items-source> 
        </c1-flex-grid> 
    




    지연 로딩

    Lazy loading is a novel concept when working with large datasets, as it reduces the time to fetch as the data is loaded on demand. This is also useful to reduce the load time for the hierarchical view, as instead of loading the complete data for all nodes, the data can be loaded on demand once the Node is expanded. 

    This can be achieved with the help of the OnClientGroupCollapsedChanged event to detect the node expand/collapse. To implement this, we would bind FlexGrid with the Model. Later, we would expand the node by clicking on the expand icon, making an ajax call, and pushing the fetched data to the target item Children property.  

    Demo: FlexGrid - Lazy Loading - C1 ASP.NET MVC

    좋은 웹페이지 즐겨찾기