WPF is tough. According to many sources it takes at least six month to a good developer to just go over the hump of learning curve. From that point on the things will become more natural and faster but before there's simply a lot to learn in WPF. I made stand-up desk and in order to occasionally sit at it I also have bar stool. The bar stool turned out to be little bit lower than I needed, and in order to get it up a few inches I put the thickest book I could find in my house. The book is (no disrespect to author, it's a nice book) Pro WPF in C# 2010. It has 1,181 pages.

Where I see people going off track is converting Windows Forms applications to WPF or applying Windows Forms techniques to WPF. Then the next developer comes along, sees Windows Form style code and keeps on going the same route.

Consider the simplest example. Say you have TextBlock on WFP form which displays payment type

<TextBlock x:Name="paymentType"  />  

and we need a few things:

  1. If payment type is Unknown, TextBlock should be empty.
  2. If payment type is Cash, TextBlock font size should be 14 and its color red.
  3. The same TextBlock is on five other WPF forms and we don't want clipboard inheritance (copy-paste the same code five times).

What Windows Form developer would do in this situation is put this code in code-behind:

paymentType.Text = (paymentType == PaymentType.Unknown) ? string.Empty : paymentType.ToString();  
if (paymentType == PaymentType.Cash)  
  paymentType.Foreground = Brushes.Red;
  paymentType.FontSize = 14;

Done. Problem solved. What about not copying-pasting the same code? Err.. There's already class with 2,000 lines in the project called Utilities. We'll just move this code into a static method in that class and call this method five times. Right?

Well, no WPF developer would ever write code like this. They would use ValueConverters and style triggers. First of all the only lines that would go to code-behind is to databind the control (assuming that nothing is databound on this form):

paymentType.DataContext = _account.PaymentType;  

Then we have one value converter:

public class PaymentTypeTextConverter : IValueConverter  
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        PaymentType paymentType;
        if (value != null && Enum.TryParse(value.ToString(), out paymentType))
            return paymentType == PaymentType.Unknown ? string.Empty : paymentType.ToString();     
            return string.Empty;
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        throw new NotImplementedException();

The next is to define style with trigger:

<Style x:Key="paymentType" TargetType="{x:Type TextBlock}">  
    <Trigger Property="Text" Value="Cash">
      <Setter Property="Foreground" Value="Red" />
      <Setter Property="FontSize" Value="14" />

Finally, the markup on the form becomes this:

<TextBlock  Style="{StaticResource paymentType}" Text="{Binding Path=., Converter={StaticResource PaymentTypeTextConverter}}" x:Name="paymentType"  />  

Nothing is earth shaking in these techniques that have been forever, but just to give a sense of how different it will look.