|
| 1 | +--- |
| 2 | +title: Virtual |
| 3 | +page_title: Grid for Blazor | Virtual Columns |
| 4 | +description: How to add virtual columns to a scrollable Grid. |
| 5 | +slug: grid-columns-frozen |
| 6 | +tags: telerik,blazor,grid,column,virtual |
| 7 | +published: true |
| 8 | +position: 5 |
| 9 | +--- |
| 10 | + |
| 11 | +# Virtual Columns |
| 12 | + |
| 13 | +The Grid lets you add Virtual Columns. This means that columns will be rendered only for the currently visible viewport and data will be loaded just for them. |
| 14 | + |
| 15 | +## Requirements |
| 16 | +To enable Virtual Columns: |
| 17 | +* Set the `ColumnVirtualization` parameter of the Grid to `true`. |
| 18 | +* Set the `Width` parameter of all columns in `px` so that the total sum is greater than the `Width` of the Grid which will enable horizontal scrollbar. You can read more about the scrolling behavior of the grid in the [Grid Column Width Behavior]({%slug grid-columns-width%}) article. |
| 19 | +* Set the `RowHeight` parameter so that the content fits. For more information see the [Notes](#notes) section. |
| 20 | + |
| 21 | + |
| 22 | +This article will be separated in the following sections: |
| 23 | +* [Basics](#basics) |
| 24 | +* [Virtual Columns and Rows](#virtual-columns-and-rows) |
| 25 | +* [Virtual Autogenerated Columns](#virtual-autogenerated-columns) |
| 26 | +* [Notes](#notes) |
| 27 | + |
| 28 | + |
| 29 | +## Basics |
| 30 | + |
| 31 | +The targeted scenario is for Grid with big volume of columns, since the performance improvement will be most significant there. |
| 32 | + |
| 33 | +>caption Basic setup of the Virtual Columns |
| 34 | +
|
| 35 | + |
| 36 | +````CSHTML |
| 37 | +@*Observe the behavior of the Grid with enabled ColumnVirtualization*@ |
| 38 | +
|
| 39 | +<TelerikGrid Data="@MyData" |
| 40 | + Width="800px" |
| 41 | + RowHeight="65" |
| 42 | + ColumnVirtualization="true" |
| 43 | + Pageable="true" PageSize="5"> |
| 44 | + <GridColumns> |
| 45 | + <GridCheckboxColumn Title="Select" Width="70px" /> |
| 46 | + <GridColumn Field="@(nameof(User.Id))" Width="100px" /> |
| 47 | + <GridColumn Field="@(nameof(User.FirstName))" Title="First Name" Width="200px" /> |
| 48 | + <GridColumn Field="@(nameof(User.LastName))" Title="Last Name" Width="200px" /> |
| 49 | + <GridColumn Field="@(nameof(User.FullName))" Title="Full Name" Width="200px" /> |
| 50 | + <GridColumn Field="@(nameof(User.DateOfBirth))" Title="Date of Birth" Width="200px" /> |
| 51 | + <GridColumn Field="@(nameof(User.Age))" Title="Age" Width="100px" /> |
| 52 | + <GridColumn Field="@(nameof(User.EmailAddress))" Title="Email Address" Width="200px" /> |
| 53 | + <GridColumn Field="@(nameof(User.RegistrationDate))" Title="Registration Date" Width="200px" /> |
| 54 | + <GridColumn Field="@(nameof(User.LocalTime))" Title="Local Time" Width="200px" /> |
| 55 | + <GridColumn Field="@(nameof(User.UserNumber))" Title="User Number" Width="300px" /> |
| 56 | + <GridColumn Field="@(nameof(User.Gender))" Title="Gender" Width="200px" /> |
| 57 | + <GridCommandColumn Width="250px" Title="Command Column"> |
| 58 | + <GridCommandButton Command="Edit" Icon="edit">Edit</GridCommandButton> |
| 59 | + <GridCommandButton Command="Delete" Icon="delete">Delete</GridCommandButton> |
| 60 | + </GridCommandColumn> |
| 61 | + </GridColumns> |
| 62 | +</TelerikGrid> |
| 63 | +
|
| 64 | +@code { |
| 65 | + public IEnumerable<User> MyData = Enumerable.Range(1, 30).Select(x => new User |
| 66 | + { |
| 67 | + Id = x, |
| 68 | + FirstName = "App", |
| 69 | + LastName = $"User {x}", |
| 70 | + DateOfBirth = new DateTime(1970, 1, 1), |
| 71 | + EmailAddress = $"app-user{x}@mail.com", |
| 72 | + RegistrationDate = DateTime.Today.AddDays(-x), |
| 73 | + LocalTime = DateTime.Now, |
| 74 | + UserNumber = Guid.NewGuid(), |
| 75 | + Gender = x % 2 == 0 ? "Male" : "Female" |
| 76 | + }); |
| 77 | +
|
| 78 | + public class User |
| 79 | + { |
| 80 | + public int Id { get; set; } |
| 81 | + public string FirstName { get; set; } |
| 82 | + public string LastName { get; set; } |
| 83 | + public string FullName |
| 84 | + { |
| 85 | + get |
| 86 | + { |
| 87 | + string fullName = $"{FirstName} {LastName}"; |
| 88 | +
|
| 89 | + return fullName; |
| 90 | + } |
| 91 | + } |
| 92 | + public DateTime DateOfBirth { get; set; } |
| 93 | + public int Age |
| 94 | + { |
| 95 | + get |
| 96 | + { |
| 97 | + var timeSpan = DateTime.Today - DateOfBirth; |
| 98 | + var years = timeSpan.Days / 365; |
| 99 | +
|
| 100 | + return years; |
| 101 | + } |
| 102 | + } |
| 103 | + public string EmailAddress { get; set; } |
| 104 | + public Guid UserNumber { get; set; } |
| 105 | + public DateTime RegistrationDate { get; set; } |
| 106 | + public DateTime LocalTime { get; set; } |
| 107 | + public string Gender { get; set; } |
| 108 | + } |
| 109 | +} |
| 110 | +```` |
| 111 | +>caption The result from the code snippet above |
| 112 | + |
| 113 | + |
| 114 | +## Virtual Columns and Rows |
| 115 | + |
| 116 | +To use Virual Columns and Rows together you need to set `Height` parameter of the Grid. More information on Virtual Rows can be found in the [Virtual Scrolling]({%slug components/grid/virtual-scrolling%}) article. |
| 117 | + |
| 118 | +>caption Use Virtual Columns and Rows together |
| 119 | +
|
| 120 | +````CSHTML |
| 121 | +@*Observe the behavior of the Grid with Virtual Rows and Columns*@ |
| 122 | +
|
| 123 | +<TelerikGrid Data="@MyData" |
| 124 | + Width="800px" |
| 125 | + RowHeight="65" |
| 126 | + Height="400px" |
| 127 | + ScrollMode="GridScrollMode.Virtual" |
| 128 | + ColumnVirtualization="true"> |
| 129 | + <GridColumns> |
| 130 | + <GridCheckboxColumn Title="Select" Width="70px" /> |
| 131 | + <GridColumn Field="@(nameof(User.Id))" Width="100px" /> |
| 132 | + <GridColumn Field="@(nameof(User.FirstName))" Title="First Name" Width="200px" /> |
| 133 | + <GridColumn Field="@(nameof(User.LastName))" Title="Last Name" Width="200px" /> |
| 134 | + <GridColumn Field="@(nameof(User.FullName))" Title="Full Name" Width="200px" /> |
| 135 | + <GridColumn Field="@(nameof(User.DateOfBirth))" Title="Date of Birth" Width="200px" /> |
| 136 | + <GridColumn Field="@(nameof(User.Age))" Title="Age" Width="100px" /> |
| 137 | + <GridColumn Field="@(nameof(User.EmailAddress))" Title="Email Address" Width="200px" /> |
| 138 | + <GridColumn Field="@(nameof(User.RegistrationDate))" Title="Registration Date" Width="200px" /> |
| 139 | + <GridColumn Field="@(nameof(User.LocalTime))" Title="Local Time" Width="200px" /> |
| 140 | + <GridColumn Field="@(nameof(User.UserNumber))" Title="User Number" Width="300px" /> |
| 141 | + <GridColumn Field="@(nameof(User.Gender))" Title="Gender" Width="200px" /> |
| 142 | + <GridCommandColumn Width="250px" Title="Command Column"> |
| 143 | + <GridCommandButton Command="Edit" Icon="edit">Edit</GridCommandButton> |
| 144 | + <GridCommandButton Command="Delete" Icon="delete">Delete</GridCommandButton> |
| 145 | + </GridCommandColumn> |
| 146 | + </GridColumns> |
| 147 | +</TelerikGrid> |
| 148 | +
|
| 149 | +@code { |
| 150 | + public IEnumerable<User> MyData = Enumerable.Range(1, 50).Select(x => new User |
| 151 | + { |
| 152 | + Id = x, |
| 153 | + FirstName = "App", |
| 154 | + LastName = $"User {x}", |
| 155 | + DateOfBirth = new DateTime(1970, 1, 1), |
| 156 | + EmailAddress = $"app-user{x}@mail.com", |
| 157 | + RegistrationDate = DateTime.Today.AddDays(-x), |
| 158 | + LocalTime = DateTime.Now, |
| 159 | + UserNumber = Guid.NewGuid(), |
| 160 | + Gender = x % 2 == 0 ? "Male" : "Female" |
| 161 | + }); |
| 162 | +
|
| 163 | + public class User |
| 164 | + { |
| 165 | + public int Id { get; set; } |
| 166 | + public string FirstName { get; set; } |
| 167 | + public string LastName { get; set; } |
| 168 | + public string FullName |
| 169 | + { |
| 170 | + get |
| 171 | + { |
| 172 | + string fullName = $"{FirstName} {LastName}"; |
| 173 | +
|
| 174 | + return fullName; |
| 175 | + } |
| 176 | + } |
| 177 | + public DateTime DateOfBirth { get; set; } |
| 178 | + public int Age |
| 179 | + { |
| 180 | + get |
| 181 | + { |
| 182 | + var timeSpan = DateTime.Today - DateOfBirth; |
| 183 | + var years = timeSpan.Days / 365; |
| 184 | +
|
| 185 | + return years; |
| 186 | + } |
| 187 | + } |
| 188 | + public string EmailAddress { get; set; } |
| 189 | + public Guid UserNumber { get; set; } |
| 190 | + public DateTime RegistrationDate { get; set; } |
| 191 | + public DateTime LocalTime { get; set; } |
| 192 | + public string Gender { get; set; } |
| 193 | + } |
| 194 | +} |
| 195 | +```` |
| 196 | +>caption The result from the code snippet above |
| 197 | +
|
| 198 | + |
| 199 | + |
| 200 | +## Virtual Autogenerated Columns |
| 201 | + |
| 202 | +In order to add Virtual Autogenerated Columns, the `ColumnWidth` parameter must be set. For more information on Autogenerated columns you can read the [Automatically Generated Columns]({%slug grid-columns-automatically-generated%}) article. |
| 203 | + |
| 204 | +````CSHTML |
| 205 | +@*Grid with Virtual Autogenerated Columns*@ |
| 206 | +
|
| 207 | +<TelerikGrid Data="@MyData" |
| 208 | + Width="800px" |
| 209 | + RowHeight="65" |
| 210 | + Height="400px" |
| 211 | + ColumnVirtualization="true" |
| 212 | + AutoGenerateColumns="true"> |
| 213 | + <GridColumns> |
| 214 | + <GridCheckboxColumn Title="Select" Width="70px" /> |
| 215 | + <GridAutoGeneratedColumns ColumnWidth="200px" /> |
| 216 | + <GridCommandColumn Width="250px" Title="Command Column"> |
| 217 | + <GridCommandButton Command="Edit" Icon="edit">Edit</GridCommandButton> |
| 218 | + <GridCommandButton Command="Delete" Icon="delete">Delete</GridCommandButton> |
| 219 | + </GridCommandColumn> |
| 220 | + </GridColumns> |
| 221 | +</TelerikGrid> |
| 222 | +
|
| 223 | +@code { |
| 224 | + public IEnumerable<User> MyData = Enumerable.Range(1, 50).Select(x => new User |
| 225 | + { |
| 226 | + Id = x, |
| 227 | + FirstName = "App", |
| 228 | + LastName = $"User {x}", |
| 229 | + DateOfBirth = new DateTime(1970, 1, 1), |
| 230 | + EmailAddress = $"app-user{x}@mail.com", |
| 231 | + RegistrationDate = DateTime.Today.AddDays(-x), |
| 232 | + LocalTime = DateTime.Now, |
| 233 | + UserNumber = Guid.NewGuid(), |
| 234 | + Gender = x % 2 == 0 ? "Male" : "Female" |
| 235 | + }); |
| 236 | +
|
| 237 | + public class User |
| 238 | + { |
| 239 | + public int Id { get; set; } |
| 240 | +
|
| 241 | + [Display(Name = "First Name")] |
| 242 | + public string FirstName { get; set; } |
| 243 | +
|
| 244 | + [Display(Name = "Last Name")] |
| 245 | + public string LastName { get; set; } |
| 246 | +
|
| 247 | + [Display(Name = "Full Name")] |
| 248 | + public string FullName |
| 249 | + { |
| 250 | + get |
| 251 | + { |
| 252 | + string fullName = $"{FirstName} {LastName}"; |
| 253 | +
|
| 254 | + return fullName; |
| 255 | + } |
| 256 | + } |
| 257 | +
|
| 258 | + [Display(Name = "Date of Birth")] |
| 259 | + public DateTime DateOfBirth { get; set; } |
| 260 | +
|
| 261 | + [Display(Name = "Age")] |
| 262 | + public int Age |
| 263 | + { |
| 264 | + get |
| 265 | + { |
| 266 | + var timeSpan = DateTime.Today - DateOfBirth; |
| 267 | + var years = timeSpan.Days / 365; |
| 268 | +
|
| 269 | + return years; |
| 270 | + } |
| 271 | + } |
| 272 | +
|
| 273 | + [Display(Name = "Email Address")] |
| 274 | + public string EmailAddress { get; set; } |
| 275 | +
|
| 276 | + [Display(Name = "User Number")] |
| 277 | + public Guid UserNumber { get; set; } |
| 278 | +
|
| 279 | + [Display(Name = "Registration Date")] |
| 280 | + public DateTime RegistrationDate { get; set; } |
| 281 | +
|
| 282 | + [Display(Name = "Local Time")] |
| 283 | + public DateTime LocalTime { get; set; } |
| 284 | +
|
| 285 | + [Display(Name = "Gender")] |
| 286 | + public string Gender { get; set; } |
| 287 | + } |
| 288 | +} |
| 289 | +```` |
| 290 | +>caption The result from the code snippet above |
| 291 | +
|
| 292 | + |
| 293 | + |
| 294 | +## Notes |
| 295 | + * Rendering the Virtual Columns in Client-side Blazor Applications is slower due to the Framework rendering performance. In the Server-side Applications this issue is not present. |
| 296 | + * Setting `RowHeight` and `Height` is required because the grid could be dynamically resized during scrolling due to the way HTML handles with dynamic content. |
| 297 | + |
| 298 | + |
| 299 | +## See also |
| 300 | + * [Live demo: Virtual Columns](https://demos.telerik.com/blazor-ui/grid/virtual-columns) |
| 301 | + * [Virtual Scrolling]({%slug components/grid/virtual-scrolling%}) |
| 302 | + * [Grid Column Width Behavior]({%slug grid-columns-width%}) |
| 303 | + * [Automatically Generated Columns]({%slug grid-columns-automatically-generated%}) |
0 commit comments