Master WPF on your iPhone

February 16, 2012

After being obsessed with WPF for so many years, I can’t just forget about it. Even though my focus is now on iOS development, I still think that WPF is an awesome platform. That’s why I wrote an iPhone app named Master WPF. It contains 500 questions, spread across 28 topics, that I painstakingly wrote, organized, and proofread until my eyes bled. The questions will help any WPF developer sharpen their skills.

It’s for WPF noobs, gurus, and everyone in between.

Master WPF on your iPhone or iPod Touch

Master WPF on your iPhone or iPod Touch

You can download Master WPF for free on your iPhone or iPod Touch, running iOS 5 or greater. The app comes with 15 free questions so that you can try it out. If you decide that you want to master WPF with my app, you can make a small in-app purchase to unlock all 500 questions.

Think of it as a donation to a recovering WPF addict.

Screenshots of Master WPF

Screenshots of Master WPF

For more info about Master WPF, please check out http://masterwpf.com


Article about Service Locator, MVVM, and MessageBoxes

April 1, 2010

I just published an article titled ‘Using a Service Locator to Work with MessageBoxes in an MVVM Application‘ on CodeProject.  It’s one solution to the now canonical question of how to work with message boxes in an MVVM app, either WPF or Silverlight.  The article gives an introduction to the Service Locator pattern, in case you are not yet familiar with that concept, and then dives into an example of how to leverage it.  The end result is a simple, testable, extensible way to work with message boxes from ViewModel objects.

http://www.codeproject.com/KB/WPF/MessageBoxInMVVM.aspx

By the way, I found out today that I got the Microsoft MVP award again.  Four years in a row!  Woohoo!! 😀


Introducing ContentControl3D

February 23, 2009

A couple years ago, Ian Griffiths blogged about a way to create flippable list items in WPF.  His approach involves using a VisualBrush to display the 2D content in 3D space, because he implemented it before Viewport2DVisual3D was introduced in .NET 3.5.  Also, his approach was not very easy to reuse in many applications because the functionality was not placed into a custom control.  Tonight, I decided to remedy this by making use of Viewport2DVisual3D in a reusable control.

The code associated with this post is a working prototype.  I intend on turning this into something more complete, but want to share it with the world as soon as possible, hoping to get some feedback and feature requests early on.

I created a control that derives ContentControl, called ContentControl3D.  It allows you to assign the BackContent property to specify what should be shown after you first flip the control over.  The Content property, inherited from ContentControl, specifies what to display on the front side of the surface.  You can also assign the BackContentTemplate property a DataTemplate, if BackContent is set to a data object (instead of a visual element).

Here is a screenshot of the demo application when it first loads up:

front
After clicking the “Flip Over” button, the UI performs an animated rotation, leaving you with a view of the back side of the surface.  This is shown below…

back
Naturally, you can put whatever content you want on the front and back sides.

Here is the XAML which configures the ContentControl3D in the demo window:

xaml
If you would like to check this control out, you can download the source code here: ContentControl3D Source Code.  NOTE: Be sure to change the file extension from .DOC to .ZIP and then decompress the file.

Your feedback is welcome.  Thanks!


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.


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!


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.