Beyond the Grid
The grid gets the glory, but day-to-day you'll wire just as many input widgets: dropdowns, date pickers, uploads. The same mental model applies β C# wrapper, jQuery widget underneath β plus a few patterns worth knowing cold.
Dropdowns and cascading
DropDownList (pick from a list) and ComboBox (pick or type) both bind to a
value/text pair, usually loaded via AJAX so lookup tables stay in the database. The
public-sector classic is the cascade: County β City β District, each list filtered by its
parent. Kendo makes this declarative with CascadeFrom:
@(Html.Kendo().DropDownList().Name("CityId")
.DataTextField("Name").DataValueField("Id")
.DataSource(s => s.Read(r => r.Action("Cities", "Lookup")
.Data("cityFilter")))
.CascadeFrom("CountyId"))
The child disables itself until the parent has a value, then re-reads with the parent's value
in the request (the small cityFilter JS function supplies it). No hand-written
change-handlers, no race conditions. Set .OptionLabel("Selectβ¦") so [Required] validation
has an empty state to catch.
Dates, uploads, and templates
DatePicker gives you culture-aware parsing and a Min/Max range β always validate the
range server-side too, since the widget is just UX. Upload in async mode posts files to a
controller action as IFormFile (or IEnumerable<IFormFile> for multiples); enforce
size and extension limits on the server, never trust the client checks.
Client templates (#= fieldName # syntax) let grid columns and dropdown items render links,
badges, or composed text. They execute as JavaScript in the browser β so HTML-encode with
#: field # when displaying user-entered data, and keep logic minimal. If a template grows past
a couple of expressions, move it into a named <script type="text/x-kendo-template"> block or
compute the display value server-side in the view model.
Keeping Kendo maintainable
Kendo pages rot when configuration, templates, and event handlers smear across Razor, inline scripts, and shared JS files. House rules that keep a large codebase sane:
- One naming convention for widget
Name()s β it's the JavaScript lookup key ($("#StartDate").data("kendoDatePicker")), so make it predictable. - Client events (
.Events(e => e.Change("onStatusChange"))) point at named functions in a per-feature JS file, never anonymous inline script blobs in the view. - View models feed widgets β compute display strings and flags in C#, keep templates dumb.
- Pin and document the Kendo version; wrapper APIs and themes shift between releases, and upgrades deserve their own testing pass.
Follow those and Kendo stays what it should be: a fast way to build consistent, accessible line-of-business UI β not a haunted layer nobody dares touch.