Google+

Disabling WPF DataGrid Virtualization

Recently, Microsoft released a DataGrid for WPF (Windows Presentation Foundation). I've been getting my feet wet in WPF, because I think it's the long term direction that Microsoft is pushing UI design into.

The DataGrid they released is only a CTP, not an official release. However, I needed something that worked now, not later for the utility I'm writing. I created a list of data, and bound it to the grid, only to watch my bound ComboBoxes lose their mind as I scrolled up and down. After ripping out my hair, I found a simple solution (for the DataGrid issue, not the lost hair). I added this attribute to my DataGrid declaration:

VirtualizingStackPanel.VirtualizationMode="Standard"

By default, the DataGrid is configured to virtualize it's contained controls. That means that as you scroll, the rendered controls are reused, and avoids constantly generating containers.

I've seen this behavior in Adobe Flex, and it's a useful feature to have, especially when memory is a concern. A real world example is the Outlook message list. If you have 10,000 items sitting in your inbox (I've seen it!), you don't want to wait while your computer busily tries to display things you can't see.

Back to the issue I had. There is either a bug in the DataGrid with ComboBox items, or there I am doing something wrong in my XAML. Either scenario is certainly plausible. When new versions of the DataGrid are released, I'll have to give them a try. For now, this fix works great.

Like this post? Please share it!

See a mistake? Edit this post!

New Version of SimpleTracking.com

I recently released a new version of SimpleTracking.com. Here are the highlights:

  • Nearly a complete rewrite, making the code far more modular and manageable.
  • Nearly 100% unit tested code base.
  • Dedicated hosting instead of shared hosting. This means that the speed and reliability has increased quite a bit. The site used to go down a couple times a day for a minute or two at a time.
  • Automatic fail-over. If the site goes down, within a matter of minutes, a completely different hosting provider kicks in and takes over. This is done through a DNS fail-over service.

image

I also set up a feedback page (using UserVoice), that allows you to vote for the features that you would like to see on the site. This is really going to help me decide if and where to focus my time. Please head over there and get voting and suggesting!

Like this post? Please share it!

See a mistake? Edit this post!

Design your classes for their consumer

I'm going to describe a methodology that will help you save time by writing better classes, and will help simplify your life by allowing you to solve problems with a top-down approach.

Developers such as myself often have a tendency to just focus on the class we're currently working on. Of course I believe this is a good thing, because we all know the importance of focus. However, you should never forget the reason you're actually writing that class. It is because other code will be consuming it.

Consumer-Approach

There have been far too many instances where I would figure out which pieces I needed to build, and then build each one, from the bottom up. The problem is that I would write the class in the most short-sighted and easiest way possible, which is usually not the best way to use it.

Now, when there is a question of what a class interface should look like, I ask myself what it should look like to make the life of the consumer as easy as possible.

Sometimes we can even take code usability to an extreme. For example, Fluent interfaces, which allow you to chain together multiple calls. In many instances, this makes the code much easier to call, potentially at the expense of making the called code more complicated.

I've come up with a simple example to help illustrate. Suppose I need to process a list of x,y coordinates. Here are a couple of potential signatures:

  • ProcessData(double[] xData, double[] yData);
  • ProcessData(PointF[] points);
  • ProcessData(IDictionary points);

For now, just ignore the performance implications (they're going to be linear in this case, or close to it anyway). To choose the correct signature, we need to know who the caller is.

Of course there is a good chance that we'll have a slight intentional leaky abstraction. In the previous example, we may have been able to use the IEnumerable generic to be more flexible. That's a topic for another day.

Thankfully, this problem is minimized, although not always eliminated when you follow the single responsibility principle. The better you can follow that principle, the simpler each piece will be. That tends to minimize the potential for the consumer to need the interface to look different than it would naturally be.

Another way to look at your classes from the consumers point of view is to practice test-driven development. In fact, I see this as one of the strongest arguments for test driven design. For each layer in your code, you're creating code by consuming it before writing it. Every layer acts as an API to the layer above it.

In conclusion, I'm simply recommending that you don't lose sight of why you're writing that piece of code. You're not just writing code for the sake of writing code, you're writing it to be used!

Like this post? Please share it!

See a mistake? Edit this post!

Jason Young I'm Jason Young, software engineer. This blog contains my opinions, of which my employer - Microsoft - may not share.

@ytechieGitHubLinkedInStack OverflowPersonal VLOG