Skip to content

Commit 72f8b66

Browse files
dimodiDimo Dimov
andauthored
Add Grid and TreeList interface binding docs (#494)
* Add interface binding docs * Add link to general data binding article * Fix page title and nullable int * Fix page title * Fix TreeList id-parent relationship Co-authored-by: Dimo Dimov <dimo@Dimos-MacBook-Pro.local>
1 parent 43ba81d commit 72f8b66

File tree

6 files changed

+285
-33
lines changed

6 files changed

+285
-33
lines changed

_contentTemplates/treelist/databinding.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44

55
* [Flat data]({%slug treelist-data-binding-flat-data%}) - a single collection of items with defined parent-child relationships. See the `Id` and `ParentId` settings.
66

7-
In either mode you can also do [Load on Demand]({%slug treelist-data-binding-load-on-demand%}) or lazy loading - that is, provide children to a node when it expands through an event. See the `HasChildren` setting and the `OnExpand` event.
8-
#end
7+
In either mode, you can implement [Load on Demand]({%slug treelist-data-binding-load-on-demand%}) or lazy loading - that is, provide children to a node when it expands through an event. See the `HasChildren` setting and the `OnExpand` event.
98

9+
Finally, you can also [bind the TreeList to an interface]({%slug treelist-data-binding-interface%}), no matter if you are using flat data or hierarchical data.
10+
#end
1011

1112

1213
#link-to-basics

components/grid/columns/bound.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
---
22
title: Data Binding
3-
page_title: Grid - DataBound Column
3+
page_title: Blazor Grid - Data Bound Columns | Telerik UI for Blazor
44
description: Data binding and bound column properties in Grid for Blazor.
55
slug: components/grid/columns/bound
66
tags: telerik,blazor,grid,bound,column
77
published: True
88
position: 0
99
---
1010

11-
# Grid Data Binding Overview
11+
# Grid Data Bound Columns
1212

1313
This article explains the basics of showing data in a grid and the features of its bound columns.
1414

15+
Important related information are the [Grid data binding fundamentals]({%slug grid-data-binding%}).
16+
1517
@[template](/_contentTemplates/common/general-info.md#valuebind-vs-databind-link)
1618

1719
Sections in this article:

components/grid/data-binding.md

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
---
2+
title: Data Binding
3+
page_title: Data Binding | Grid for Blazor
4+
description: Data bind the Blazor Grid to any of the supported data sources.
5+
slug: grid-data-binding
6+
tags: telerik,blazor,grid,data,binding,databind,databinding
7+
published: true
8+
position: 10
9+
---
10+
11+
# Grid Data Binding
12+
13+
Telerik Blazor Grid is data source agnostic - you can use any database and service according to your project. You only need to get the collection of data models to the Grid in the view-model of the component hosting it.
14+
15+
## Data Sources and Scenarios
16+
17+
The following list of resources provides examples for data binding a grid in various scenarios:
18+
19+
* Basic **example**, tutorial **video** and **notes** - [Grid Bound Columns Overview]({%slug components/grid/columns/bound%}). Also lists the features (parameters) of a bound column.
20+
21+
* **Optimizing the data source queries** - see the [Notes]({%slug components/grid/columns/bound%}#notes) section in the article above. In a server-side app, an `IQueriable` that ties to an appropriate context (such as EntityFramework) that can optimize the LINQ queries the grid generates is a quick option. For full control, use the [OnRead event]({%slug components/grid/manual-operations%}).
22+
23+
* **SQL** (or any other) **database** - you can find examples in our [online demos](https://demos.telerik.com/blazor-ui/grid/overview). You can see an offline version of the demos project in the `demos` folder of your installation ([automated]({%slug installation/msi%}) or [archive]({%slug installation/zip%})). They showcase an EntityFramework context using an SQL database that provides data to a grid through a service, which is a common architecture for decouping the front-end from the actual data source that you can apply to any database.
24+
25+
* The **CRUD sample project** our extensions for [Visual Studio]({%slug getting-started-vs-integration-new-project%}) and [Visual Studio Code]({%slug getting-started-vs-code-integration-overview%}) can generate for you showcases a similar architecture that you can use as a starting point.
26+
27+
* The [Blazing Coffee sample application](https://github.com/telerik/blazor-ui/tree/master/sample-applications/blazing-coffee) shows how to provide data from a SQL (uses SQLite) database to the Grid using Entity Framework Core services.
28+
29+
* **WebAPI** data source - you can see how to send an appropriate request for data and return an optimized query in the following sample projects: [Grid DataSourceRequest on the server](https://github.com/telerik/blazor-ui/tree/master/grid/datasourcerequest-on-server). This is a flexible approach that you can use for any type of service you have - serializing and deserializing the data according to the application logic and needs, and optimizing the database queries on the backend.
30+
31+
* **OData** data source - an extension method we provide lets you make OData v4 queries as shown in the following example: [Grid and OData](https://github.com/telerik/blazor-ui/tree/master/grid/odata).
32+
33+
* **DataTable**, **ExpandoObject** collection - If you don't have actual strongly typed models (yet) and you use `ExpandoObject`, or your backend comes from an older technology and still returns `DataTable`s, the grid can accommodate such dynamic data types. You can get started from our examples on how to bind the grid to a [ExpandoObject collection](https://github.com/telerik/blazor-ui/tree/master/grid/binding-to-expando-object) and to a [DataTable](https://demos.telerik.com/blazor-ui/grid/data-table) which also support [editing]({%slug components/grid/overview%}#editing).
34+
35+
* **gRPC** - the gRPC tooling supports .NET Core, and as of mid-June 2020, there is a package that brings it to WebAssembly. You can find a basic example and more resources to get you started with gRPC in Blazor in the [Grid Data from gRPC Sample Project](https://github.com/telerik/blazor-ui/tree/master/common/grpc-example).
36+
37+
* **Foreign Keys** - using foreign tables and keys is usually done through the grid templates. You can read more and find examples in the [Grid - Foreign Key]({%slug grids-foreign-key%}) KnowledgeBase article.
38+
39+
## Binding to Interface
40+
41+
Since version 2.27, the Grid supports binding to a collection of multiple model types that implement the same interface.
42+
43+
Note the usage of [`OnModelInit`]({%slug grid-events%}#onmodelinit) in the example below. The event handler sets the model type to be used for new items in the Grid. One-type model creation is supported out-of-the-box. If you need to support adding instances of different types:
44+
45+
* Use custom **Add** buttons in the [Grid Toolbar]({%slug components/grid/features/toolbar%}), one for each model type.
46+
* In each button click handler, define an `InsertedItem` of the correct type in the [Grid State]({%slug grid-state%}).
47+
* [Put the Grid in Insert mode]({%slug grid-state%}#initiate-editing-or-inserting-of-an-item) with the [SetState method]({%slug grid-state%}#methods).
48+
49+
>caption Data Binding the Grid to an Interface
50+
51+
````CSHTML
52+
<TelerikGrid Data="@GridData"
53+
FilterMode="GridFilterMode.FilterRow"
54+
EditMode="GridEditMode.Inline"
55+
OnUpdate="@UpdateHandler"
56+
OnDelete="@DeleteHandler"
57+
OnCreate="@CreateHandler"
58+
OnModelInit="@(() => new Model1())">
59+
<GridToolBar>
60+
<GridCommandButton Command="Add" Icon="add">Add</GridCommandButton>
61+
</GridToolBar>
62+
<GridColumns>
63+
<GridColumn Field="IntProperty" />
64+
<GridCommandColumn>
65+
<GridCommandButton Command="Edit">Edit</GridCommandButton>
66+
<GridCommandButton Command="Save" ShowInEdit="true">Save</GridCommandButton>
67+
<GridCommandButton Command="Cancel" ShowInEdit="true">Cancel</GridCommandButton>
68+
</GridCommandColumn>
69+
</GridColumns>
70+
</TelerikGrid>
71+
72+
@code {
73+
public interface IModel
74+
{
75+
public int Id { get; set; }
76+
public int IntProperty { get; set; }
77+
}
78+
79+
public class Model1 : IModel
80+
{
81+
public int Id { get; set; }
82+
public int IntProperty { get; set; }
83+
}
84+
85+
public class Model2 : IModel
86+
{
87+
public int Id { get; set; }
88+
public int IntProperty { get; set; }
89+
}
90+
91+
List<IModel> GridData { get; set; }
92+
93+
protected override void OnInitialized()
94+
{
95+
var data = new List<IModel>();
96+
97+
data.Add(new Model1()
98+
{
99+
Id = 1,
100+
IntProperty = 1
101+
});
102+
data.Add(new Model2()
103+
{
104+
Id = 2,
105+
IntProperty = 2
106+
});
107+
108+
GridData = data;
109+
}
110+
111+
public void UpdateHandler(GridCommandEventArgs args)
112+
{
113+
var model = (IModel)args.Item;
114+
115+
var matchingItem = GridData.FirstOrDefault(c => c.Id == model.Id);
116+
117+
if (matchingItem != null)
118+
{
119+
matchingItem.IntProperty = model.IntProperty;
120+
}
121+
}
122+
123+
public void DeleteHandler(GridCommandEventArgs args)
124+
{
125+
var model = (IModel)args.Item;
126+
127+
GridData.Remove(model);
128+
}
129+
130+
public void CreateHandler(GridCommandEventArgs args)
131+
{
132+
var model = (IModel)args.Item;
133+
134+
model.Id = GridData.Max(d => d.Id) + 1;
135+
136+
GridData.Insert(0, model);
137+
}
138+
}
139+
````
140+
141+
>note Up to version 2.26, the `Data` collection of the Grid must contain instances of only one model type.
142+
143+
## See Also
144+
145+
* [Live Demo: Bind Grid to Observable Data](https://demos.telerik.com/blazor-ui/grid/observable-data)
146+
* [Live Demo: Bind Grid to DataTable](https://demos.telerik.com/blazor-ui/grid/data-table)
147+
* [Live Demo: Manual Grid Data Operations](https://demos.telerik.com/blazor-ui/grid/manual-operations)

components/grid/overview.md

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -69,35 +69,9 @@ General grid with its most common features
6969

7070
## Data Binding
7171

72-
To show data in a grid, you need to define [GridColumn]({%slug components/grid/columns/bound%}) instances - they take a model `Field` and expose settings for [templates]({%slug components/grid/features/templates%}), [grouping](#grouping) and [reordering]({%slug components/grid/columns/reorder%}). To [edit](#editing) data or invoke custom logic, you define a [CommandColumn]({%slug components/grid/columns/command%}).
73-
74-
>tip The Telerik Blazor Grid is data source agnostic - you can use any database and service according to your project, you only need to get the collection of data models to the grid in the view-model of the component hosting it.
75-
76-
The following list of resources provides examples for data binding a grid in various scenarios:
77-
78-
* Basic **example**, tutorial **video** and **notes** - [Grid Data Binding Overview]({%slug components/grid/columns/bound%}). Also lists the features (parameters) of a bound column.
79-
80-
* **Optimizing the data source queries** - see the [Notes]({%slug components/grid/columns/bound%}#notes) section in the article above. In a server-side app, an `IQueriable` that ties to an appropriate context (such as EntityFramework) that can optimize the LINQ queries the grid generates is a quick option. For full control, use the [OnRead event]({%slug components/grid/manual-operations%}).
81-
82-
* **SQL** (or any other) **database** - you can find examples in our [online demos](https://demos.telerik.com/blazor-ui/grid/overview). You can see an offline version of the demos project in the `demos` folder of your installation ([automated]({%slug installation/msi%}) or [archive]({%slug installation/zip%})). They showcase an EntityFramework context using an SQL database that provides data to a grid through a service, which is a common architecture for decouping the front-end from the actual data source that you can apply to any database.
83-
84-
* The **CRUD sample project** our extensions for [Visual Studio]({%slug getting-started-vs-integration-new-project%}) and [Visual Studio Code]({%slug getting-started-vs-code-integration-overview%}) can generate for you showcases a similar architecture that you can use as a starting point.
85-
86-
* The [Blazing Coffee sample application](https://github.com/telerik/blazor-ui/tree/master/sample-applications/blazing-coffee) shows how to provide data from a SQL (uses SQLite) database to the Grid using Entity Framework Core services.
87-
88-
* **WebAPI** data source - you can see how to send an appropriate request for data and return an optimized query in the following sample projects: [Grid DataSourceRequest on the server](https://github.com/telerik/blazor-ui/tree/master/grid/datasourcerequest-on-server). This is a flexible approach that you can use for any type of service you have - serializing and deserializing the data according to the application logic and needs, and optimizing the database queries on the backend.
89-
90-
* **OData** data source - an extension method we provide lets you make OData v4 queries as shown in the following example: [Grid and OData](https://github.com/telerik/blazor-ui/tree/master/grid/odata).
91-
92-
* **DataTable**, **ExpandoObject** collection - If you don't have actual strongly typed models (yet) and you use `ExpandoObject`, or your backend comes from an older technology and still returns `DataTable`s, the grid can accommodate such dynamic data types. You can get started from our examples on how to bind the grid to a [ExpandoObject collection](https://github.com/telerik/blazor-ui/tree/master/grid/binding-to-expando-object) and to a [DataTable](https://demos.telerik.com/blazor-ui/grid/data-table) which also support [editing](#editing).
93-
94-
* **gRPC** - the gRPC tooling supports .NET Core, and as of mid-June 2020, there is a package that brings it to WebAssembly. You can find a basic example and more resources to get you started with gRPC in Blazor in the [Grid Data from gRPC Sample Project](https://github.com/telerik/blazor-ui/tree/master/common/grpc-example).
95-
96-
* **Foreign Keys** - using foreign tables and keys is usually done through the grid templates. You can read more and find examples in the [Grid - Foreign Key]({%slug grids-foreign-key%}) KnowledgeBase article.
97-
98-
99-
>note The `Data` collection of the grid must contain instances of only one model type.
72+
To show data in a Grid, you need to define [GridColumn]({%slug components/grid/columns/bound%}) instances or allow the Grid to [generate columns automatically]({%slug grid-columns-automatically-generated%}). Declared columns take a model `Field` and expose settings for [templates]({%slug components/grid/features/templates%}), [grouping](#grouping) and [reordering]({%slug components/grid/columns/reorder%}). To [edit](#editing) data or invoke custom logic, you define a [CommandColumn]({%slug components/grid/columns/command%}).
10073

74+
The [Grid Data Binding article]({%slug grid-data-binding%}) provides detailed information and examples about binding the Grid in different scenarios and to various data sources.
10175

10276
### Loading Animation
10377

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
title: Data Binding to Interface
3+
page_title: Blazor TreeList - Data Binding to Interface | Telerik UI for Blazor
4+
description: Data binding the Blazor TreeList to multiple model types with the same interface.
5+
slug: treelist-data-binding-interface
6+
tags: telerik,blazor,treelist,data,bind,databind,databinding,interface
7+
published: true
8+
position: 4
9+
---
10+
11+
# TreeList Data Binding to Interface
12+
13+
Since version 2.27, the TreeList supports binding to a collection of multiple model types that implement the same interface.
14+
15+
Note the usage of [`OnModelInit`]({%slug treelist-events%}#onmodelinit) in the example below. The event handler sets the model type to be used for new items in the TreeList. One-type model creation is supported out-of-the-box. If you need to support adding instances of different types:
16+
17+
* Use custom **Add** buttons in the [TreeList Toolbar]({%slug treelist-toolbar%}), one for each model type.
18+
* In each button click handler, define an `InsertedItem` of the correct type in the [TreeList State]({%slug treelist-state%}).
19+
* [Put the TreeList in Insert mode]({%slug treelist-state%}#initiate-editing-or-inserting-of-an-item) with the [SetState method]({%slug treelist-state%}#methods).
20+
21+
>caption Data Binding the TreeList to an Interface
22+
23+
````CSHTML
24+
<TelerikTreeList Data="@TreeListData"
25+
IdField="Id"
26+
ParentIdField="ParentId"
27+
EditMode="TreeListEditMode.Inline"
28+
OnUpdate="@UpdateHandler"
29+
OnDelete="@DeleteHandler"
30+
OnCreate="@CreateHandler"
31+
OnModelInit="@(() => new Model1())">
32+
<TreeListToolBar>
33+
<TreeListCommandButton Command="Add" Icon="add">Add</TreeListCommandButton>
34+
</TreeListToolBar>
35+
<TreeListColumns>
36+
<TreeListColumn Field="IntProperty" Expandable="true" />
37+
<TreeListCommandColumn>
38+
<TreeListCommandButton Command="Edit">Edit</TreeListCommandButton>
39+
<TreeListCommandButton Command="Save" ShowInEdit="true">Save</TreeListCommandButton>
40+
<TreeListCommandButton Command="Cancel" ShowInEdit="true">Cancel</TreeListCommandButton>
41+
</TreeListCommandColumn>
42+
</TreeListColumns>
43+
</TelerikTreeList>
44+
45+
@code {
46+
public interface IModel
47+
{
48+
public int? Id { get; set; }
49+
public int? ParentId { get; set; }
50+
public int IntProperty { get; set; }
51+
}
52+
53+
public class Model1 : IModel
54+
{
55+
public int? Id { get; set; }
56+
public int? ParentId { get; set; }
57+
public int IntProperty { get; set; }
58+
}
59+
60+
public class Model2 : IModel
61+
{
62+
public int? Id { get; set; }
63+
public int? ParentId { get; set; }
64+
public int IntProperty { get; set; }
65+
}
66+
67+
List<IModel> TreeListData { get; set; }
68+
69+
protected override void OnInitialized()
70+
{
71+
var data = new List<IModel>();
72+
73+
data.Add(new Model1()
74+
{
75+
Id = 1,
76+
ParentId = null,
77+
IntProperty = 1
78+
});
79+
data.Add(new Model2()
80+
{
81+
Id = 2,
82+
ParentId = 1,
83+
IntProperty = 2
84+
});
85+
86+
TreeListData = data;
87+
}
88+
89+
public void UpdateHandler(TreeListCommandEventArgs args)
90+
{
91+
var model = (IModel)args.Item;
92+
93+
var matchingItem = TreeListData.FirstOrDefault(c => c.Id == model.Id);
94+
95+
if (matchingItem != null)
96+
{
97+
matchingItem.IntProperty = model.IntProperty;
98+
}
99+
}
100+
101+
public void DeleteHandler(TreeListCommandEventArgs args)
102+
{
103+
var model = (IModel)args.Item;
104+
105+
TreeListData.Remove(model);
106+
}
107+
108+
public void CreateHandler(TreeListCommandEventArgs args)
109+
{
110+
var model = (IModel)args.Item;
111+
112+
model.Id = TreeListData.Max(d => d.Id) + 1;
113+
114+
TreeListData.Insert(0, model);
115+
}
116+
}
117+
````
118+
119+
>note Up to version 2.26, the `Data` collection of the TreeList must contain instances of only one model type.
120+
121+
122+
## See Also
123+
124+
* [Binding to Flat Data]({%slug treelist-data-binding-flat-data%})
125+
* [Binding to Hierarchical Data]({%slug treelist-data-binding-hierarchical-data%})
126+
* [Load on Demand]({%slug treelist-data-binding-load-on-demand%})
127+
* [Live Demo: TreeList Flat Data](https://demos.telerik.com/blazor-ui/treelist/flat-data)
128+
* [Live Demo: TreeList Hierarchical Data](https://demos.telerik.com/blazor-ui/treelist/hierarchical-data)
129+
* [Live Demo: TreeList Load on Demand](https://demos.telerik.com/blazor-ui/treelist/lazy-loading)

components/treelist/data-binding/overview.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ The properties of a treelist item match directly to a field of the model the tre
4444
* HasChildrenField => HasChildren
4545
* ItemsField => Items
4646

47-
4847
## Examples
4948

5049
For samples of using each data binding approach listed above, see its corresponding article:

0 commit comments

Comments
 (0)