Bizarre Errors When Using Telerik Controls

I’m in the process of developing a complete line-of-business application in Silverlight.  I have a Telerik Premium license and most of the controls I use are Telerik controls.

At one point in my development process, I innocently added an “Up/Down” control to a UserControl, using Blend 4.  Suddenly and for no apparent reason, I could no longer see the UserControl in Visual Studio 2010.  I would get a very odd looking blank page.  I could still edit it in Blend, however, and I’m under a time crunch so I carried on.

Today, Blend started crashing when trying to open the UserControl.  I now had no design surface and I’m struggling with other issues.  Among other strange issues, this error appeared in the VS designer:

An unhandled exception was encountered while trying to render the current silverlight project on the design surface. To diagnose this failure, please try to run the project in a regular browser using the silverlight developer runtime.

If I reloaded the designer I would go back to the blank page.  After much gnashing of teeth, I tried copying this control to another project in my solution.   After commenting out a few lines, Voila!  Design surface!

The Solution: When I used Blend to add the “up/down” control, it added a reference to a prior version of the Telerik.Windows.Controls.Input assembly to my project.  I had several other Telerik assemblies referenced, all Q3 2010 version.  The mismatched versions played hell with the designer and I was stuck.  I removed the offending prior versions and replaced them with the correct ones, and life was good.  Hope this saves you some time and gray hairs.

I Don’t Miss ViewState

I’ve been working with ASP.NET MVC for the last year and I don’t miss webforms.  The one thing about webforms I miss the least is ViewState.

It’s a Hack

Hidden HTML fields were never intended to hold so much data.  Persisting data in the page this way is Ugly, Expensive, Confusing, and Hard to Test.

It’s Ugly

ViewState is this ugly blob of Base-64 encoded data:

 <input type=”hidden” name=”__VIEWSTATE”
  value=”aHR0cDovL3d3dy5jb2Rlcm9zZXR0YS5jb20vYmFsbHB1enpsZQ==” />

It’s Expensive

ViewState is processed on every postback. This means it has to be sent, parsed, processed, updated, and re-sent with every request.  Not good for performance!

It’s Confusing

I can’t tell you how many StackOverflow and forums posts I’ve seen about dynamic controls and ViewState.  If you don’t add dynamic controls at just the right point in the page lifecycle, ViewState breaks.

It Uses Magic Strings (So It’s Hard to Test)

ViewState["MyMagicString"] is a typo-prone way to address data.  Strongly-typed Views in ASP.NET MVC are so much easier to work with and much more testable.

The MVC Way

MVC doesn’t even try to match ViewState as a feature.  ViewState is a stateful paradigm layered on top of a fundamentally stateless protocol: HTTP.  Rather than the hybridized hack of packing a huge encoded graph into a hidden field, MVC says:

“If you want to persist state, do it on the server using a Model.”

You can use Session state or TempData on the server and javascript or cookies at the client to store pointers, but actual data should be persisted by one thing- the Model.  The MVC rendering pipeline relies on Models (or ViewModels) to retain and provide the data that populate Views.  If you change the state of a control, the data is updated in and persisted through the Model, preferably by a loosely-coupled persistence implementation.  This is a much cleaner, architecturally sound method for dealing with state over a stateless delivery protocol.

LINQ Aggregate Queries: Multiple Group By Columns

I recently had the need to SUM a column grouped by two other columns. Here’s the view:

SELECT SolutionID, EventName, EventDuration
FROM Events

I needed this:

SELECT SolutionID, EventName, SUM(EventDuration) EventTotal
FROM Events
GROUP BY SolutionID, EventName

Here’s the LINQ:

var events = from e in summary
   group e by new { e.SolutionID, e.EventDetail } into g
   let TotalMinutes = g.Sum(x => x.EventDuration)
   orderby TotalMinutes descending
   select new EventSummary
     {
          SolutionID = g.Key.SolutionID,
          Name = g.Key.EventDetail,
          Seconds = TotalMinutes,
          Minutes = TotalMinutes / 60.0,
          Hours = (TotalMinutes / 60.0) / 60.0                           
     };

The magic is in line 2:

   group e by new { e.SolutionID, e.EventDetail } into g

You can group by as many columns as you need with that little nugget. Using the anonymous type feature in C# 3.0 you can group on as many columns as you need. Enjoy!

Follow

Get every new post delivered to your Inbox.