WTF Moment: Data Binding Errors in ListBoxes

Posted January 30, 2008 by Jerry Lin
Categories: WPF

Tags: , ,

Let’s say you have a ListBox that is data-bound to an ObservableCollection and set up similar to this:

listboxexample.png

Also, assume you’ve implemented sorting on your collection using the CollectionView representing your data bound items.

Can you guess what’s wrong?

When you sort the items (you’re really sorting UI elements representing your data), a data binding error occurs for every item in the collection. From what I can ascertain from the cryptic error messages, the runtime can’t find the instance of the ItemContainerStyle associated with each item.

As you probably already know, data binding errors are really exceptions. Remember, there is overhead involved when exceptions get thrown not only because an object is being constructed, but because the callstack is getting unwound somewhere.

This is an actual error that was happening in Jing’s History bin. Although I don’t have hard data to validate my claims, these data binding errors were causing a perceivable hit to performance when sorting. When you sort the UI elements representing your items in a collection view, all the UI elements are being destroyed and regenerated (if you don’t believe me, set break points in the debugger to see for yourself). And with a data binding error being thrown for each item, sorting becomes proportionally worse as you add more items to the collection.

The work-around for this is simple, but in all honesty I have no idea why it works. All you have to do is set the ListBox’s GroupStyle. That’s it, no more data binding errors when sorting your collection. If you don’t need grouping, just make the GroupStyle hidden.

Someday I’ll get off my lazy butt and ask Microsoft why this works. Until then, this quirk with the ListBox still makes me think, “WTF?”.

WTF Moment: Data Binding Error

Posted January 8, 2008 by Jerry Lin
Categories: WPF

Tags: , , ,

A few weeks ago, I was updating Jing’s splash screen because of some underyling classes that I refactored when I encountered an exception thrown in a MultiBindingConverter for trying to read DependencyProperty.UnsetValue as an enum.

The MultiBindingConverter was blowing up in XAML that looked similar to:

multibindingsnippet.png

After a few hours of gnashing my teeth, and cursing under my breath, I fixed this error. The culprit was with the declaration of one of the properties:

internal AnEnum SomeProperty2

When I declared the property as public, everything worked. To be absolutely honest, I have no clue why this fixed it, as I’ve never seen anything in the MSDN docs stating you could only do MultiBinding on public properties. This is a slight annoyance, as that property really should have been internal, and making it public to make MultiBinding work broke some encapsulation.

Maybe I’ll use Reflector one day to poke around the WPF classes and see if there’s a clue as to why this is.

A “WTF” moment, indeed.

Favorite WPF Utilities

Posted January 4, 2008 by Jerry Lin
Categories: WPF

Tags: , , ,

I’ve compiled this list of WPF utilities that have helped me save time while debugging, profiling, and as a result make development under WPF much more productive and enjoyable:

Snoop

I can’t recommend this enough. Snoop let’s you view a window’s visual tree, glance at an element’s property values, check if there are any data binding errors, and look at a RoutedEvent’s execution path. Indispensable.

Mole

Although I only started using it a few weeks ago, I use it quite a bit. It’s similar to Snoop in that it let’s you view a window’s visual tree and property values, but actually runs inside the Visual Studio debugger as a Visualizer tool. Additionally, it shows you the window’s logical tree and even the XAML where an element was instantiated. Very cool.

WPF Perf

This is actually a collection of profiling tools that Microsoft ships with the .NET 3.0 SDK. Perforator has helped me a number of times to discover where rendering performance bottlenecks were occurring on Jing.

Reflector

An oldie but goodie. Reflector will dissasemble the source for any non-obfuscated assemblies, allowing you to look at an almost 1:1 mapping of 3rd party source code. Not only can you look at the source for classes in an assembly, Reflector will also show all the locations the class was used and its documentation. This has to be my all-time favorite WPF/.NET tool as I’ve used it countless times to look at Microsoft’s code to learn how they implemented certain panels, DependencyProperties, etc.

 Pistachio

EDIT 1/7/2008: I started using Pistachio today after the lead developer, Mike Malinak, recommended it last week. Pistachio shows you the XAML resources that are available in a WPF project, where they’re declared, if they’re used, and where they’re used. To be honest, I think the UI could be improved (such as a tree-view of all the XAML resources instead pressing buttons to manually scroll through each file), but it’s a decent first start. Plus, god knows Visual Studio 2005 desperately needs functionality like this. Kudos to Grant Hinkson for writing this, I look forward to its continued improvement.

So there you have it, these are the utilities that I swear by for my WPF development. What are some of your favorite WPF utilities?

Lightweight Drawing with DrawingVisuals: Part 2 of 2

Posted December 19, 2007 by Jerry Lin
Categories: WPF

Tags: , , , ,

I apologize for writing this entry almost a month after the first part of this series. I was busy making the Sun Launcher draggable in the Windows version of Jing (which was pushed yesterday). Yay!

Anyhow, in this entry I will teach you how to do lightweight drawing with DrawingVisuals. Most visuals in WPF derive from FrameworkElement, which contains overhead that affects rendering performance that we can avoid with DrawingVisuals.

However, you can’t simply use DrawingVisuals in XAML. DrawingVisuals don’t contain support for layout, so the runtime won’t be able to position them and ultimately have them rendered. To use DrawingVisuals, you have to host them in a class that does provide layout, such as a FrameworkElement.

Ok, so let’s learn how to host DrawingVisuals! To help distill the concepts for you, we’ll just draw a black square.

Step 1: Create a class that will host your visual(s)

step-1.png

SquareVisual is our host, and will have support for layout because it derives from FrameworkElement. _square will be the square that we will draw.

Step 2: Register your visual(s) with the host

step-2.png
Note how there are calls to AddVisualChild() and AddLogicalChild(). These calls are required, or the visual that you are hosting will not be rendered. This is because they tell the host (SquareVisual) of the existence of _square, which will force it to participate in its layout.

Step 3: Maintain bookkeeping of our visuals

step-3.png

We need to implement these two overrides so the rendering system can maintain proper bookkeeping. Since we only have 1 visual, _square, implementing them is trivial. However, if you have multiple visuals to maintain, it can get ugly. Luckily, Microsoft provides a class called VisualCollection which you could use in place of _square. Then implementing these two overrides becomes simple again.

Step 4: Draw the visual

In Step 2, there was this function:

step-4.png

This function is what draws the square. To render a drawing visual, we describe its properties by calling RenderOpen() to get access to an instance of DrawingContext, which provides functions for drawing various shapes and geometries. It’s somewhat reminiscent of a DeviceContext. If you’ve done custom drawing with GDI, you may be wondering why we only called DrawRectangle once, and why aren’t we drawing inside OnRender()? Those are very good questions, and we need to understand how rendering works in WPF.

WPF rendering is entirely different from Win32. In Win32/MFC apps, the app was responsible for updating the visual state of a window every time a part of the client area was invalidated. If you’ve done custom drawing with GDI, you know how time consuming it could be to write complex drawing routines to make sure visuals got updated properly on every call to OnRender(), prevent flickering and tearing, etc. WPF however, utilizes what is called a Retained Mode system. In WPF apps, the runtime is responsible for maintaining the visual state of elements in a window.

The implications of this are profound. What this means is anytime you draw a visual (ie DrawRectangle()), what you are really doing is describing the properties of your visual to the rendering system with rendering instructions that are serialized for later use in the graphics pipeline. This is beneficial because the rendering system can optimize rendering performance by minimizing the number of redraws that are required, prevent flickering, etc. Best of all, any changes to your visuals are converted to serialized rendering instructions that the rendering system is responsible for maintaining.

All that’s left to do is to add SquareVisual in your window’s XAML file and you now have a custom visual.

Now you know how to do lightweight drawing with DrawingVisuals. While this technique is not hard, the performance you gain comes at the cost of flexibility with describing your visuals in XAML, losing the ability to do binding on your visuals, creating dependency properties etc.

If you only have a few visuals, say < 10, go ahead and use the visuals that WPF already provides as it’s not worth spending the time to host custom visuals.

The complete source code is below. It was made with Visual Studio 2005 and the WPF extensions installed.

DrawingVisualSample.zip

DIUs, Not DUIs

Posted November 28, 2007 by Jerry Lin
Categories: WPF

Tags: , , , ,

In a previous post, I included a sample project to demonstrate how to make non-rectangular windows in WPF with Interop. You may or may not have noticed something like this in the code: ScaleUI.UpScaleX( someValue ), or ScaleUI.UpScaleY( someValue ). Admittedly, I stated in the comments to not worry about it, but in this post I will explain why that static class exists.

If you’re like most of the WinJing devs, you’ve come from the Win32/MFC world where you’ve been conditioned to think in terms of pixels. Coming to WPF, you (by “you” I really mean “myself”) probably would assume setting a window’s size and location would also be in pixel units.

And you’d be right. Sort of. In some cases.

What we, and I’m actually talking about myself, found out the hard way was that WPF does not perform sizing and placement in terms of pixels. Instead, WPF was designed to recognize placement and sizing in terms of what Microsoft engineers dubbed Device Independent Units.

Besides being a typical verbose Microsoft acronym, DIUs are actually not that complicated. To the WPF runtime, 1 DIU = 1/96 of an inch, or 96 dpi. So for example, if you sized a window to be 288 x 288, what you’re really saying is the window should be 3 in. x 3 in (96 x 3 = 288). The WPF architects did this so that applications written in WPF would be sized “correctly” on different monitors with different dimensions and resolutions. The implications of this are:

If your monitor is set to 96 dpi, the window’s width and height would map directly to pixel units.

A window should be relatively the same size on two monitors with different resolution settings.

WPF will scale your windows and elements automatically as best it can in terms of inches regardless of your dpi.

But beware, you can’t just use DIUs and forget about dpi totally. As well designed as WPF is, it is missing some functionality that WinForms, and even MFC/Win32 provides. For example, Jing’s Sun Launcher’s position is stored internally as a percentage of a screen’s width and height to avoid resolution issues. To get the current monitor’s size, we had to use the WinForms Screens API because WPF does not have the equivalent set of classes. However, the Screens classes work in terms of pixel sizes, but assumes the resolution is set to 96 dpi. For example, if a desktop’s size was set to 1280 x 1024 at 120 dpi, it should really be 1024 x 819, but the Screens API would report the monitor’s dimensions as 1280 x 1024 @ 96 dpi (120 / 96 = 120%, so everything is scaled up by 20%). Plus, if you have to use Interop (and chances are you will) like we did, you need to take the horizontal and vertical dpi into account when translating from DIUs to pixels.

One way to get the system’s dpi settings is with this line of code:

PresentationSource.FromVisual( Application.Current.MainWindow ).CompositionTarget.TransformToDevice;

However, because you need a window that’s already been loaded, we used Interop on Jing to call the GetDeviceCaps function to avoid that. This is what forms the basis of the ScaleUI class, which was used to take a monitor’s resolution into account.

Finally, don’t let the DIU acronym fool you. If you took a ruler to measure your WPF window, chances are it won’t be the exact size that you specified. The reason is because your monitor’s real, physical dpi is probably different from the resolution that is set in your Display Settings. In other words, WPF doesn’t know this real dpi, so it scales everything as best it can in terms of the dpi that you set in the Control Panel. Interestingly, if you set your dpi to match your monitor’s physical resolution, everything will be sized exactly as you specified.

In other words, what DIU really means is this: if you had two monitors, and each one had its dpi set to match its physical resolution, a window in WPF will be exactly the same size on both.

For more information on the implications of DIUs, read this excellent post by WPF Learning Experience. And if I had taken the two minutes to ask our lead developer about DIUs in the first place, all of this confusion would have been avoided..

Lightweight Drawing with DrawingVisuals: Part 1 of 2

Posted November 21, 2007 by Jerry Lin
Categories: WPF

Tags: , , , , , ,

Because of WPF’s layout system, designing User Interfaces has become a much more creative, organic and powerful process. However, all this power comes at a price: it is easy to adversely affect rendering performance by making complex layouts. In this post I will explain why, and how using DrawingVisuals are one way to prevent such performance bottlenecks.

Let’s take a step back and learn how layout and rendering works in WPF. In WPF there is the concept of Logical and Visual Trees. A Logical Tree can be thought of as representing the encapsulated elements contained within the Window. So for example, if you had this Window described with XAML:

<Window>
<Grid>
<Button />
<Label />
</Grid>
</Window>

The window’s Logical Tree would basically be the Grid, with the Button and Label as its children. Visual Trees are usually more complicated though. A Visual Tree can be thought of as all the visual elements that compose an element. So looking at the previous example, the Button could actually be composed as a Border that contains a Grid which contains a TextBlock, which in turn is composed of more visual elements. And the Label could be composed of one or more visual elements. What this means is WPF separates an element’s behavior from its appearance, and allows developers to easily style controls.

Developers should be mindful of the number of elements in the Visual Tree. In WPF, every object that has rendering derives from the Visual abstract class, which contains all the low-level infrastructure for said rendering. Although objects like Buttons, Rectangles, Labels etc. ultimately derive from Visual, they also derive from FrameworkElement. FrameworkElement contains support for layout, input, data binding, routed events, dependency properties, and animations. Because of this, there is overhead when creating objects that derive from FrameworkElement. Now, if you had a large and complex visual tree with each element being an instance of that class, the overhead in creating and rendering these elements becomes noticeable.

For example, I was working on a window that contained a ListBox that was bound to a collection of objects. Each ListBoxItem was rendered with a custom style that ended up being over 30 elements! Needless to say, that window had a complex Visual Tree. Using Perforator, I discovered that the Window’s Dirty Rect Addition rate (or the rate at which each UI element was being generated) was in the single digits, which is very low.

To tap-dance around this, I performed custom drawing with DrawingVisuals. DrawingVisuals derive directly from Visuals and contain support to add lightweight visuals without the overhead that FrameworkElements carry. They also have support for simple input in the form of Visual Hit Testing. Since DrawingVisuals do not contain the overhead that FrameworkElements carry, you could theoretically have hundreds of Visuals in a WPF app without significantly impacting performance, assuming your hardware is relatively current.

wpf-class-hierarchy.png
By using DrawingVisuals to style each capture in the History bin, we were able to increase the rate that each capture was generated by a factor of ~4-5. In the next part, I will show you how to make custom visuals with DrawingVisuals.

The History of Improving the History Bin

Posted November 20, 2007 by Jerry Lin
Categories: WPF

Tags: , , , , , , , ,

During the sprint for Jing 1.2.7, one of my tasks was to add sorting and filtering to the History bin. While adding that functionality was trivial, it was immediately noticeable that it was painfully slow. It was so slow that the sorting in History was almost pointless. Up until that point, the History always had been sluggish, or at least seemed sluggish, and with sorting and filtering being so slow, something had to be done. [In]conveniently, profiling the History for performance gains was also one of my tasks for that sprint.

After about a week of profiling and testing, I found three major bottlenecks to the History’s performance. Unfortunately, they were all interrelated, non-trivial fixes. Two of the fixes were not completed until 1.3.

In order to understand the first, and arguably largest, bottleneck, you have to realize that the History is essentially this XAML snippet:

historyxaml.png

Yup, the History is basically nothing more than a WPF ListBox data-bound to a collection of objects that we use to encapsulate each capture. To achieve the tabular look, we overrode its ItemsPanelTemplate to use a WrapPanel. This gave us the benefit of having rows re-arrange themselves whenever the History window was resized. However, it also caused a huge hit in rendering performance.

By default, ListBoxes use what’s called a VirtualizingStackPanel as its ItemsPanelTemplate. A virtualized panel does lazy-loading of UI elements. Specifically, virtualized panels will only generate (realize) the UIs for elements that are actually visible on the screen, and destroying them when they become non-visible (unrealized). Since the History was using a WrapPanel, whenever the History was sorted, the UI for each capture was being destroyed and regenerated, regardless if it was on-screen or not. In other words, it wasn’t the actual sorting that was slow – it was the rendering of each capture’s UI that was.

Unfortunately as of this writing, Microsoft does not provide a VirtualizingWrapPanel, so if you want one, you will have to write one yourself. To warn you though, writing a custom virtualizing panel is time consuming and NOT trivial. Luckily, Dan Crevier has a series of blog posts on how to write one. Although I was working on an implementation, I was not able to finish it in time for the 1.3 release.

Another major bottleneck with the History was that it was a layered window. As I’ve discussed in other posts, layered windows in WPF are basically evil. Because of the per-pixel alpha blending, each pixel in the History was being rendered twice. The effect of this was if the History was sorted, each item was realized (because of the WrapPanel), and then rendered again. To prove this, I invalidated the client area of History by resizing and scrolling it, and saw its framerate drop to as low as 5 fps under Perforator. By making the History non-layered, resizing and scrolling became much more performant, with framerates on my Vista box getting as high as 60 fps. Sorting now was also improved since each capture was only being rendered once. However, there was still one bottleneck that made sorting noticeably sluggish.

Each capture had over 30 elements in its Visual Tree, according to Snoop. To confirm my suspicions, I ripped the History out into a test harness, invalidated the client area by sorting to force it to regenerate the UI for every capture. Using Perforator, the rate at which it was generating each UI was under 10. When I used DrawingVisuals to custom render each capture, the UI regeneration rate (Perforator calls this the Dirty Rectangle region rate) jumped to over 100! NOTE: I will discuss custom drawing in WPF and Visual Trees in more detail in a future post.

With those two fixes in place, the History has come a long way in terms of rendering performance and has been a major area in which the team has learned some best practices in WPF. As a FYI to other devs that may be getting started with WPF, I cannot stress these points enough:

  1. Avoid the tempation of using layered windows to make non-rectangular regions. Instead, use the GDI CreateRgn functions.
  2. Avoid complicated layouts. That is, be aware of the number of elements you use to compose your layouts, using Snoop and Perforator to make sure they do not adversely impact the UI generation rate. If you really need to, use custom drawing with DrawingVisuals to cut down on overhead.
  3. If you are displaying a collection of objects that could potentially become numerous, write a virtualizing panel to render only the objects that will actually be visible on the screen.

Now all I have to do is write a virtualizing WrapPanel to get some peace of mind..

Creating Non-Rectangular Windows With Interop

Posted November 13, 2007 by Jerry Lin
Categories: WPF

Tags: , , , ,

In a previous post, I discussed why using layered windows in WPF incurred huge performance hits when rendered, and recommended developers to stay away with them if they could. As a rule of thumb, using transparency to make non-rectangular windows that will NOT be resizable, small, and contain only a few UI elements are actually OK.

However, today’s post is for developers who absolutely need resizable, non-rectangular windows in WPF. The key to achieving this is realizing that Win32 supports non-rectangular windows via the CreateRectRgn functions. Rather than write a lengthy explanation, I wrote a sample app with lengthy comments that hopefully makes the process relatively easy to understand.

Be aware that this solution was written for VS 2005 with the WPF extensions installed.

NonRectWindow.zip

The Evils of Layered Windows

Posted November 5, 2007 by Jerry Lin
Categories: WPF

Tags: , , ,

EDIT 1/8/2009: Microsoft improved layered windows performance with .NET 3.5 SP1 + Vista SP1 and XP SP1, rendering this post outdated.

One feature of WPF is the ability to have transparent/layered windows by setting a window’s AllowsTransparency property to “True”. Setting this property makes it possible to easily create non-rectangular and/or semi-transparent windows. Without it, irregularly shaped windows would be difficult to create. However, there is a hidden cost when setting AllowsTransparency=”True”.

To put it bluntly, performance is crappy. In WPF, there are two aspects to rendering. First, the scene is composed, then presented. On Vista, layered windows are composed in the hardware pipeline via DirectX, but because DirectX cannot present that surface and retain its alpha channel information, it acquires a surface with IDirect3DSurface9::GetDC and presents to the screen via GDI. On Windows XP, DirectX does not support IDirect3DSurface9::GetDC of a surface with alpha channels. GDI is not hardware accelerated on Vista.

So what the hell am I babbling about? Basically, WPF layered windows in XP are composed and presented entirely in software. On Vista, although layered windows are composed in hardware, they are presented in software. Translation: layered windows in WPF are slow.

But things get more complicated. On Vista, because the scene is composed in the hardware pipeline but presented in software via GDI, rendering a layered window will result in a chain of bit-blits from the video card, to system memory, back to video memory. What this means is rendering layered windows on Vista with a grahics card that has dedicated memory can actually be much slower than on machines with shared memory.

To see for yourself, invalidate the client area of a layered window by resizing or scrolling and watch the frame rate dip below 10 fps using Perforator. One caveat: Visual Profiler will report that a layered window is being rendered in hardware. On Vista this technically true, but the surface is still presented in software via GDI.

Bottom line, layered windows in WPF incur a big rendering performance hit, so try to avoid them if you can. Here are some rough guidelines to help you decide if layered windows are absolutely necessary:

Is the window relatively small?
Does your window have only a few UIElements?
Does your window have to be non-rectangular? If so, use the Win32 CreateRgn functions (I’ll talk more about this in a future post)