The Initially Selected Item when Binding to a Grouped ICollectionView

September 18, 2008

I found a bug in WPF today.  That doesn’t happen very often, but today was one of those days.  If you bind a ListBox to an ICollectionView that has one or more PropertyGroupDescriptions in its GroupDescriptions collection, the initially selected item’s IsSelected property is set to true.  This might not sound like a bug, but it turned out to be one of those issues that took an hour of my life away.  This blog post shows the workaround I came up with.

Suppose you have a collection of PersonViewModel instances, where the class is defined as:

Also suppose that you have these resources set up, and they are applied to the ListBox that displays the list of PersonViewModel objects:

The ListBox is declared as:

The UI also has another ListBox that is not bound to a grouped collection view, and also, beneath the ListBoxs, a TextBlock that shows the selected PersonViewModel’s Bio property. When you run the app, it looks like this:

If you select Steve Smith from the left ListBox, the UI updates accordingly:

However, if you then select Dave Brown again from the right ListBox (the one bound to grouped data), watch what happens:

Yikes!!  The left ListBox and Bio area did not update.  Why not?  Because it turns out that the initially selected item in a ListBox bound to a grouped ICollectionView has its IsSelected property set to true, as a local value.  According to rules of WPF, a local value takes precedence over the value provided by a binding.  So, the binding established on the ListBoxItem’s IsSelected property is overwritten by a local value.

Until Microsoft fixes the bug I reported about this we are stuck using a workaround.  Here’s what I came up with, as seen in the window’s code-behind file.

You can download the demo project here.  This application was compiled in Visual Studio 2008 against .NET 3.5 SP1.  You must change the file extension from .DOC to .ZIP and then decompress it.


XAML PowerToys v2 from Karl

September 16, 2008

Karl has just released v2 of his XAML PowerToys.  He has really outdone himself this time!  The main purpose of these Visual Studio Add-ins is to help make it easier and much faster to create business forms for classes.  He has done an outstanding job! I suggest you watch Karl’s brief introductory videos, on his blog, to quickly get up and running with his tools.

There are still a few rough spots, and certainly more features to be implemented, but what he has so far is definitely worth installing.  I am going to join his one man team and help build out some more features (it will be Mole Project all over again!).

Conserving screen real estate via the adorner layer

September 14, 2008

I spent the weekend building and expanding on my previous work adorning XamDataGrid with editor controls.  I made leaps and bounds of progress, and am very excited about the result.  As much of the functionality that can be abstracted away now lives as an attached behavior, called DisplayAdornerEditors.  I wrote a big post about it on my other blog, so if you’re interested, I highly recommend you check it out here!

WPF is amazing!

Editing metadata in the adorner layer

September 12, 2008

Today I created a solution to a problem involving where and how to edit metadata about a value in the XamDataGrid.  I  blogged about it on my work blog here.  The really cool part about the solution, in my opinion, is that I host an editor for the metadata in the adorner layer.  The metadata is an explanation for why the user modified the value of a cell in the grid.  To me, it just makes sense to put such extraneous information “outside of” the grid, so that it does not clutter up the UI and require the grid cells to be larger than necessary.

Here’s a screenshot of the metadata editor in action:

I think this sample really shows how powerful and flexible WPF is.

Using Attached Behaviors to Add Currency Support to XamDataGrid

September 9, 2008

I just found another great use for attached behaviors!  I used them to add to XamDataGrid the equivalent behavior of what WPF list controls get for free via the IsSynchronizedWithCurrentItem property.  You can check out how it works here.

Synchronizing the width of elements in an ItemsControl

September 6, 2008

When I use an ItemsControl (or subclass of ItemsControl, such as ListBox) to display a list of items, I often want the width of an element in each item to match the width of the equivalent elements displayed for all other items.  That is easy to achieve by setting the Width property of an element in the DataTemplate used by the ItemTemplate property, but using hard-coded width and height values is generally considered to be a bad practice.  It’s better to not specify a width, and let the element figure out how big it should be based on its content.  But, if the element created for each item in the ItemsControl is sizing to its own content, that means that the sizes of all elements created for items will usually not be equal to each other.

For example, the screenshot below displays an ItemsControl populated with some strings.  The ItemsControl has an ItemTemplate that contains a TextBlock with a light blue background color.  Notice how each item is just wide enough to display its content:

What I would like, however, is to have each item be equally wide, and that the width of all items is the width required by the widest item.   In other words, all of the TextBlocks should be as wide as the TextBlock that contains the word ‘Whatever’.  As I mentioned before, I could solve this problem by hard-coding a Width for the TextBlocks, but that is a very fragile solution.

It turns out that there is a very clean and simple solution to this problem.  The trick is to rely on a not-so-often used feature of the Grid panel.  Grid has an attached property called IsSharedSizeScope, which I will set to true on the ItemsControl.  I then wrap the TextBlock in the ItemControl’s ItemTemplate inside a Grid, and give that Grid a single ColumnDefinition whose SharedSizeGroup property is set to some arbitrary identifier.  Here is that XAML:

When I run the application now, the UI looks like this:

You can download the demo project here.  Be sure to change the file extension from .DOC to .ZIP and then decompress the file.

Using MVVM to work with CheckBoxes in XamDataGrid

September 4, 2008

On my other blog, I published a way to put CheckBoxes into the XamDataGrid.  The interesting aspect of the implementation, in my opinion, is how it uses the Model-View-ViewModel pattern to maintain the check state of each CheckBox.  Since I put a CheckBox into the header area above the CheckBoxes in each row, I used a ViewModel object to encapsulate the logic that figures out what state the header CheckBox should have, and how to update the state of each row’s CheckBox.  It’s just another example of how great MVVM is when working with WPF.

Here’s a screenshot of that demo app:

You can read that blog post here.