Telerik RagGridView – Where Are My Cells Gone?

My latest application required a RadGridView having a dynamic number of columns. And therefor, the binding of the data an event handler needed to by managed during runtime as well.

Not really in issue: handle the RowLoaded event, iterate over the cells of the row passed by the event arguments, and everything is fine. That’s what I thought and implemented.

It was fine until the number of rows to be displayed exceeded the number of rows that could be displayed. When starting to scroll the grid in the UI, an exception occurred (in this case, the browser windows turned white and the status bar mentioned there was an error on the page – really helpful!)

So I had to start the debugger, and immediately I saw what caused the exception: the number of cells in the row passed to the event handler was smaller than the number of columns of the grid. Since I iterated over the number of columns of the grid, and then used the index to access the corresponding cell of the row, it has to fail.

Soon it was obvious that the number of cells in the row matched the number of columns displayed in the browser. But where have all the other cells gone? The answer to this question is UI Virtualization, explained in this article: http://www.telerik.com/help/wpf/radgridview-features-ui-virtualization.html.

After reading the article, the solution was quite easy: turn of the column virtualization of the grid, and the number of cells in the row passed to the handler was matching to the number of columns of the grid.

I think it’s worth to mention that during the initial loading of the grid, all rows had the matching number of cells in the RowLoaded-handler, even with UI virtualization turned on. The mismatch only occurred when the user started to scroll.

Silverlight, Telerik GridView, Dynamically Created Loaded Handler & Performance

I like Silverlight, Telerik’s GridView control and the ability to create the columns of a grid dynamically.

Recently, I had to build up a grid during runtime. The number of columns and the header text is unknown at design time (read it from the database), but nothing to worry about. The XAML file only contains the definition of the Telerik grid control itself, but no column definitions.

Almost every column should contain a checkbox. And I need to handle the load event of every dynamically created checkox. Since I had to use Silverlight 4, I needed to create the cell template by using the XamlReader loading a XAML fragment.

To verify that the creation of the grid columns works at all, I did not include the load event handling in the XAML fragment for the first try. The application started, the grid and its columns were built as expected. Everything was fine.

Then I added the event handler to the fragment . The result contains something like this: <CheckBox Loaded="MyCheckBoxLoadedHandlerMethod"/>.

Having this little change done, opening the view containing the grid hangs in that way, that after a while IE complained the localhost was not responding any more. CPU usage went up, and memory consumption too.

What I think what happened is, that for each checkbox in the grid (in my sample 17 lines by 14 checkbox columns), an event handler instance is created either by Silverlight or the Telerik control. This seems to be such resource intensive, that it brought down IE.

Now what I had to do is to create a single event handler instance and assign it to every newly created checkbox. But how can I do that in Silverlight 4? In Silverlight 4 you cannot assign an object to a DataTemplate, except using the XamlReader approach (Silverlight 5 offers this ability).

I added a RowLoaded event handler to the grid. The handler iterates thru the cells of the row and looks for the checkbox child element. If it finds one, the one-and-only handler is assigned to the Click event.

It still takes time to show up the view, but now it works. I can’t tell what the real reason for the slowdown of the first approach is. But I found a way to get it running πŸ™‚

Silverlight Printing and Inheritance of Language Settings

From what I learned, printing in Silverlight (4) is straight forward: Create a control and print it.

I used this pattern in a Silverlight application I built. Because I had to implement some multipage- and list handling, I created user controls that I added into a stack panel of the main print control during runtime (inside of the PrintDocument.PrintPage event handler).

To get the correct – current UI culture dependent – formatting of all of the date and numeric values when printed, I set the Language property in the ctor of the main print control to the current culture’s language. But when the child controls were printed, the culture-dependent output was formatted in en-US style, not in the current culture style. I had to set the Language property inside of each child control.

Of course, at the time the child control was created using new ChildControl, the Language property could not be set to the value of the parent, since at that time the child did not know it has one. But I expected Silverlight to change the Language property to the parent’s value as soon as the child as added to the Children collection.

Well, adding Language = XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.Name) ; into each child control’s ctor (or into the base class’ ctor), wasn’t that hard to do πŸ˜‰

Generic UserControl Base Class in Silverlight

Having generics in .NET is a great thing. I already loved template classes in C++, missed them in .NET 1.x, and was happy to get a (little bit restricted) kind of templates in .NET 2.0.

Building a Silverlight application, I felt the need to create a generic UserControl base class. But I was unable to use it until I found the following hint: “Known Issue – Controls Deriving From A Generic Base Class Must Be In Separate Assembly” (http://blogs.msdn.com/b/wpfsldesigner/archive/2010/01/22/known-issue-controls-deriving-from-a-generic-base-class-must-be-in-separate-assembly.aspx).

This article mainly describes generic UserControl classes for WPF, and at the end puts the focus on the issue in Silverlight. And it gives the crucial hint: One has to create a “middle” class. The only purpose of the middle class is to create a non-generic type based on the generic base class. The declaration looks like this:

MiddleClass : GenericBaseClass<TypeClass>

where GenericBaseClass<T> itself is derived from UserControl.

The base class can be abstract. The middle class of course have to override all abstract methods. I only put a throw (new NotImpementedException("NeedsToBeOverridden")) into the implementation of these methods to remind me not to forget to override them by the derived class (the user control itself).

The user control now can be derived from the middle class, which does not require type parameters. Silverligt’s XAML parser is happy, and I am too. The declaration looks like this:

DerivedClass : MiddleClass

Simple, isn’t it?!

The reason why Silverlight requires this workaround is a lack of the x:TypeArguments property in the XAML.

Silverlight’s DatePicker and Telerik’s RadWindow Dialog

In my current Silverlight project, I’m using the DatePicker control, which is part of the Silverlight SDK.

In one scenario, the DatePicker with TwoWay binding is embedded into a User Control, which itself is embedded into another User Control. The format is “dd.MM.yyyy”. Entering e.g. 23.11.2011 works fine, means the value of the bound property is set to the 23rd of November in 2011.

Then I needed a date input inside of a modal dialog. Shouldn’t be a problem, so I just copied and pasted the XAML from the User Control into the dialog’s XAML. But entering 23.11.2011 in the dialog, the bound property remains null. First I thought there was a binding issue at all, but after some playing around I noticed that entering 8.11.2011 worked fine. The bound property was set correctly to the 8th of November 2011. But as soon as the entered day was bigger than 12 – the maximum value of a month – the input was ignored.

Luckily, I already had a DateConverter created in that project. This converter parses the entered string in the ConvertBack method using the current culture. So I bound the DatePicker control to that converter too, set a breakpoint at the ConvertBack method, and stepped into it. And to my surprise, the entered values was interpreted and bound correctly now.

To me, the behavior does not make sense. Why does the Date Picker control act different in these two scenarios? One thing might be that the RadWindow as the parent somehow changes the culture. But from my understanding, this should lead to the 11th of August 2011 when entering 8.11.2011.

At least I’m happy that I found a workaround. I do not have to understand everything at all…

Refresh A Silverlight Control That Is Using A Converter

One of the great things of Silverlight – from my point of view – is the introduction of converters to format the content if a control, e.g. a text box. Well, the idea itself isn’t new, but it is the first time I saw it built in a Microsoft UI technology.

But I think MS should spend some time to optimize this feature. Here is the scenario:

I created a concatenation converter. This converter receives via the ConverterParameter attribute the names of the properties it should concatenate (simple string concat with blank separator). The properties are taken from the object the control is bound to. This converter is used e.g. for display-only text boxes.

Now I had the case that one of the properties, that is concatenated by the converter, was changed by the application during runtime (not by user input). But the control wasn’t updated, means it was still showing the old value.

After some web searching I understood why: In case a property of an object is changed – and the object implements the INotifyPropertyChanged – the control that is bound to that property receives the PropertyChanged event and updates itself. You doesn’t have to implement the event handler yourself. It is part of Silverlight’s magic. As soon as you use the binding, the event handler is there.

In my case, the TextBox wasn’t bound to a property, but directly to the DataContext. This is done by just declaring Text="{Binding}". And of course in my case it looks like this: Text="{Binding Converter={StaticResource ConcatConverter}, ConverterParameter=Property1,Property2}". So the control doesn’t have a property it can listen to (or not the right one). Silverlight does not know that the values of ConverterParameter are property names it should use to listen to PropertyChanged events.

And – of course – I hadn’t found a way how to ‘attach’ the properties to the control.

My first approach was to fire the PropertyChanged event by calling OnPropertyChanged of the control via reflection. The Silverlight security prevents this. An exception was thrown when I called the method via refection.

Then I implemented a kind of reset to the DataContext of the control the TextBox was embedded in. Reset is not just DataContext = DataContext. Siverlight recognizes that the context does not change. One has to set the DataContext to null first and then reassign the old value.

In theory, first all the controls are cleared and then the values are displayed. In fact, the graphic engine and / or the human eye (at least my eyes) are too slow to recognize an flickering.

Later on, I learned that the reset approach might lead to some confusion (as it did in my project). One of the users told me that, after she used the functionality where the DataContext is re-set, the control always shows the value that was set by the re-set.

It took some time to figure out what was going on. I did some debugging, but the context of the control’s parent was always set to the correct value. And this is the point: the context of the parent.

The control was nested in (was part of) another control. The nested control’s DataContext wasn’t set explicitly, so the control I have the focus on “derived” the context from its parent (one thing I really like about Silverlight: I don’t have to set the context for each child control).

As soon as the context of the child was re-set, something inside of Silverlight seems to cut the context connection between the parent and the child. And since the control is only created once during the lifetime of the application, from that moment on, it doesn’t point to the parent’s DataContext anymore. And therefor, the control does not reflect any changes. Even setting child.DataContext = parent.DataContext did not help. Odd thing!

The only workaround I found was to add a SetDataContext method by the nesting control, which has to be called every time a refresh is required. πŸ™

Silverlight TabStop and Copy&Paste

What a “feature” πŸ™

In one of the LOB apps I’m building, I set some of the text boxes to enabled, read-only and no tab stop. Then I needed top copy the content of one of these text boxes into the clipboard. It was not possible! Because you cannot mark the content of the box!

As soon as I removed the IsTabStop="false" property from the style, Copy&Paste was working again. For the price that I had to define the tab order manually. And in case the sequence of the controls changes, I have to take care to reset the TabIndex property of each control.

Using Styles From Different Class Library In Silverlight

For re-use purposes, it is helpful to put Silverlight styles into a separate class library; let’s call it ResourceLibrary in this example.

In the class library which is using the styles from ResourceLibrary, one should declare a Styles.xaml, which only contains a reference to ResourceLibrary:

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary 
      Source="/ResourceLibrary;component/Assets/Styles.xaml"/>
  </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

The using class library is called UsingLibrary here.
To be able to render the controls contained in UsingLibrary in Visual Studio’s designer, the xaml needs to contain the following declaration:

<UserControl.Resources>
  <ResourceDictionary 
    Source="/ResourceLibrary;component/Assets/Styles.xaml"/>
</UserControl.Resources>

For some kind of controls, this code is not valid, e.g. for controls based on Telerik's RadWindow class.
So I took the following approach:

<Control.Resources>
  <ResourceDictionary 
    Source="/ResourceLibrary;component/Assets/Styles.xaml"/>
</Control.Resources>

The designer was happy (styles were resolved in design mode), the compiler was happy too, but the runtime wasn't.

An exception occurred complaining that "Local values are not allowed in resource dictionary with Source set". Whatever that means…

The way out was to replace the resource dictionary declaration with the following code:

<Control.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary 
        Source="/ResourceLibrary;component/Assets/Styles.xaml"/>
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Control.Resources>

To me, a little bit unexpected. Why does the designer and the compiler like the short version, while the runtime doesn't?!

The environment was VS 2010 SP1 and Silverlight 4.

Why Silverlight Binding’s StringFormat Property Sometimes Isn’t Fully Working

In Silverlight 4, the new Binding property StringFormat was introduced. It’s a nice thing, e.g. if you want to display numeric values with digit grouping and a fix number of decimal places. The syntax is equal to the String.Format: {Binding DataContextProperty StringFormat=’#,##0.00′}. One can, of course, use it for other simple types like DateTime…

I was using this feature in a project in one control, and it worked as expected. Then I created a new UserControl, and the trouble began. When the control showed up, the value was display as set by the StringFormat expression set in the xaml file. But after entering a new value, the formatting was gone.

It took me some time to figure out what the difference was. And it was not found in the xaml!

What I noticed was that the control working correctly as long as it was bound against a property of a class that was generated from a WCF Service Reference. Means, this class was originally declared inside the WCF Service assembly, and because it was part of the operation contract declared by the WCF Service, VS generated that class (or kind of proxy) in the Silverlight project as well.

When I bound the newly created control to an instance of this operation contract class, without changing the xaml, everything worked as expected.

So what is the difference? First of all, I bound the new control to (a property of) an instance of a class that was declared inside the Silverlight project itself.

The class looked like this:

public SilverlightClass
{
public decimal Value { get; set; }
}

Comparing it to the operation contract class, first thing I noticed was that that class not only had properties, but it had also data members (fields) which are encapsulated by corresponding properties.

So I changed the Silverlight class to something like this:

public SilverlightClass
{
private decimal m_Value;

public decimal Value
{
get { return (m_Value; } set { m_Value = value; } }
}

But still, the formatting did not work. So I “copied” the other difference: the operation contract also implemented the INotifyPropertyChanged interface and raised a PropertyChanged event whenever a property was set to a new value. This lead to the final version of the Silverlight class:

public SilverlightClass : INotifyPropertyChanged
{
private decimal m_Value;

public decimal Value
{
get { return (m_Value; }
set
{
if (!m_Value.Equals(value))
{
m_Value = value;
RaisePropertyChanged("Value");
}
}
}

public event PropertyChangedEventHandler PropertyChanged;

private void RaisePropertyChanged
(
string propertyName
)
{
if ((PropertyChanged != null))
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
}

And that was it… Since my knowledge of Silverlight and its mechanisms is very little, I was a little bit surprised.

Having the Silverlight class changed like that, also the update of the bound controls worked when the code behind changed the bound property of the DataContext during runtime (e.g. by a LostFocusHandler).

Large Message Size And Bad Request on WCF Service

In an application I built, using Silverlight Client and WCF Service, the application threw an exception when the request data passed by the client to the server exceeded about 64K (might be a little bit less).

Using a TCP tracer, I saw that the client received a “bad request” error.

Looking around a little bit, the solution was quite easy.

When creating a service reference in the Silverlight project using Visual Studio, the ServiceClient.config already contains the maxBufferSize and maxReceivedMessageSize properties.

What is missing are the corresponding settings in the WCF Services’s web.config. So just put a

<bindings>
<basicHttpBinding>
<binding maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
</binding>
</basicHttpBinding>
</bindings>

section inside the system.serviceModel node, and you’re done πŸ™‚