WPF UserControl DependencyProperty Binding

On the weekend I was messing around creating a simple WPF card game application and wanted to just quickly knock together a UserControl with a dependency property (actually there were several controls and several dependency properties) which allows the hosting Window or UserControl to change the property.

Ofcourse we should probably look at implementing this as a lookless control but I was just trying to do the bare minimum to get this working as a proof of concept.

So what I want is UserControl which displays playing card, so let’s call it CardView and it looks like this (excluding the UserControl element for brevity)

<Grid>
   <Border Background="White" Padding="8" CornerRadius="8">
      <Image Source="{Binding CardImage, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
      <Border.Effect>
         <DropShadowEffect />
      </Border.Effect>
    </Border>
</Grid>

and the code behind looks like this

public partial class CardView : UserControl
{
   public static readonly DependencyProperty CardImageProperty = DependencyProperty.Register(
      nameof(CardImage), typeof(Uri), typeof(CardView), new PropertyMetadata(default(Uri)));

   public Uri CardImage
   {
      get => (Uri)GetValue(CardImageProperty);
      set => SetValue(CardImageProperty, value);
   }

   public CardView()
   {
      InitializeComponent();
   }
}

The key thing here is that we have this code-behind dependency property CardImage, and in the XAML we want to show the image of the card that was set through the dependency property.

If this was a lookless control we’d have set this binding up like this

RelativeSource={RelativeSource TemplatedParent}

but there’s no separation here of style and code, instead everything’s in the UserControl, so we have to use

RelativeSource={RelativeSource AncestorType=UserControl}

This will then bind the UserControl Image to the dependency property in code-behind and allow our host Window or UserControl to simply do the following

<local:CardView Width="140" Height="200" 
   CardImage="../Resources/HQ.png"/>

For this example, the png’s will be stored in a Resources folder with their Build Action set to Resource.