When Armstrong landed on the moon more than 40 years ago, it was one small step for man but one big step for mankind.
Well it seems that I have achieved the opposite. One small step for a relatively experienced silverlight/wpf developer, but one giant step for Jeppe Vammen Kristensen.
I’ve created my first custom content control. “Pfff” you might add. But hey it has 3 dependency properties( A concept that it has taken me a long time to fully comprehend)
Tell me more
So what is this marvelous thing that I have created? It’s a fairly simple control where you can define content for when it is being edited or not edited.
You can go to this page for an example of it in action http://examples.jeppek.dk/TrueFalseExample/TrueFalseExampleTestPage.html. Checking the checkbox will enable and disable the IsEditing property.
Or you can download the sample code here: Source (it requires that you have Silverlight Tools installed)
The View
And here is the xaml for the example.
<UserControl x:Class="TrueFalseExample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Control="clr-namespace:TrueFalseExample.Control" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel>
<CheckBox Name="RandomCheckBox" Content="Enable Disable Editing" ></CheckBox>
<TextBlock FontSize="16" >Simple</TextBlock>
<Control:EditableContentControl
IsEditing="{Binding Path=IsChecked, ElementName=RandomCheckBox}"
TrueContent="Editing enabled"
FalseContent="Editing disabled" />
<TextBlock FontSize="16">Edit/Non Edit</TextBlock>
<Control:EditableContentControl
IsEditing="{Binding Path=IsChecked, ElementName=RandomCheckBox}">
<!-- The content for true -->
<Control:EditableContentControl.TrueContent>
<TextBox Text="{Binding Path=FullName,Mode=TwoWay}" />
</Control:EditableContentControl.TrueContent>
<!-- The content for false-->
<Control:EditableContentControl.FalseContent>
<TextBlock Text="{Binding Path=FullName}" />
</Control:EditableContentControl.FalseContent>
</Control:EditableContentControl>
</StackPanel>
</Grid>
</UserControl>
You can see that there are two examples of using the control. In the first one I simple add a text value to the TrueContent and FalseContent properties. On both controls I have bound the IsEditing property to the IsChecked value of the checkbox.
In the last control example I’m binding to a property directly in the view codebehind (just to keep the sample code as simple as possible).
public partial class MainPage : INotifyPropertyChanged
{
public MainPage()
{
InitializeComponent();
DataContext = this;
FullName = "Jeppe Vammen Kristensen";
}
private string _fullName;
public string FullName
{
get { return _fullName; }
set { _fullName = value; OnPropertyChanged("FullName"); }
}
public void OnPropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged = delegate {};
}
A short remark on dependency properties
The code for the control is as I mentioned earlier fairly simple in it’s nature. But I use Dependency Properties, and while they are smart, they also make the code a bit complicated to understand.
It’s also difficult to explain In few words what they do. So here are some characteristics:
- Dependency Properties are there so you can do among many things: DataBinding, Validation, Coercion , Change Notification. They are a key element when you do bind to properties. F.ex through “{Binding Path=SomeProperty}”
- It’s like having a static backing field for your properties, where the values are stored deep inside the belly of wpf. So in short it’s value is not stored on the control instance.
- Typically the control will wrap a property around the dependency property. For instance when you set the Text property in xaml :
<TextBox Text="SomeValue" />
-
You are basically calling this on instance:
public string Text
{
get { return GetValue(TextProperty);}
set { SetValue(TextProperty, value);}
}
-
In the previous example there is a call to GetValue and SetValue. Both take as input a Dependency Property. And the reason these methods are available is because the control is derived from a DependencyObject(which is the only place where you can set Dependency Properties)
I’ll stop here. Don’t be alarmed if you don’t get it 100 % (or at all). It has taken me a lot of time to grasp dependency properties, and to be honest I do not now if I have fully understood it.
The Code
But to get back to the control. If we strip away the insanity (the dependency properties) this is the control we have:

3 properties and a control derived from a ContentControl. Let’s try to strip down the code into chunks. In the start of the code we declare the dependency properties. It looks like this
Registering the Dependency Properties
public static DependencyProperty TrueContentProperty =
DependencyProperty.Register
(
name: "TrueContent",
propertyType: typeof (object),
ownerType: typeof (EditableContentControl),
typeMetadata: new PropertyMetadata(TrueDataTemplateChanged)
);
public static DependencyProperty FalseContentProperty =
DependencyProperty.Register
(
name: "FalseContent",
propertyType: typeof (object),
ownerType: typeof (EditableContentControl),
typeMetadata: new PropertyMetadata(FalseContentChanged)
);
public static DependencyProperty IsEditingProperty =
DependencyProperty.Register
(
name: "IsEditing",
propertyType: typeof (bool),
ownerType: typeof (EditableContentControl),
typeMetadata: new PropertyMetadata(IsEditingChanged)
);
We are registering the properties in the wpf motor. Defining the value of the property and other metadata. Be aware of the typeMetaData, here we are pointing towards a callback for when changes occur to the properties (We will get to that).
Wrapping the dependency properties in good old properties
/// <summary>
/// The content to display when IsEditing is true
/// </summary>
public object TrueContent
{
get { return GetValue(TrueContentProperty); }
set { SetValue(TrueContentProperty, value); }
}
/// <summary>
/// The content to display when IsEditing is false
/// </summary>
public object FalseContent
{
get { return GetValue(FalseContentProperty); }
set { SetValue(FalseContentProperty, value); }
}
public bool IsEditing
{
get { return (bool) GetValue(IsEditingProperty); }
set { SetValue(IsEditingProperty, value); }
}
These are the properties we use when we set values in xaml, and because this is done on all controls is also the reason why you generally don’t have to be concerned about Dependency Properties
Handling changes to the properties (the heart of the control)
/// <summary>
/// Changes the displayed content if isEditing is false and the passed
/// in FalseContent is different from the existing
/// </summary>
/// <param name="d"></param>
/// <param name="e"></param>
private static void FalseContentChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var isEditing = ExtractBool(d.GetValue(IsEditingProperty));
if (!isEditing && e.NewValue != e.OldValue)
d.SetValue(ContentProperty, e.NewValue);
}
/// <summary>
/// Changes the displayed content if isEditing is true and the passed
/// in FalseContent is different from the existing
/// </summary>
/// <param name="d"></param>
/// <param name="e"></param>
private static void TrueDataTemplateChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var isEditing = ExtractBool(d.GetValue(IsEditingProperty));
if (isEditing && e.NewValue != e.OldValue)
d.SetValue(ContentProperty, e.NewValue);
}
/// <summary>
/// Handles changes to the IsEditing property
/// </summary>
/// <param name="d"></param>
/// <param name="e"></param>
private static void IsEditingChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
if (e.NewValue == e.OldValue) return;
bool newBool = ExtractBool(e.NewValue);
UpdateContent(newBool,d);
}
I’m inspecting all property changes and based on different factors updates the Content of the control (the content is the part that will be displayed ).
- FalseContent. If the changed value for the FalseContent is different from the old (e.NewValue vs. e.OldValue) and the IsEditing property is false. We change overwrite the current Content being displayed
- TrueContent. The same as for FalseContent. Only we overwrite if IsEditing is true
- IsEditing. We determine if IsEditing has changed to a new value. And the call to the method UpdateContent will overwrite Content with the value of TrueContent or FalseContent based on what the new IsEditing value is.
The two static help methods
private static void UpdateContent(bool isEditing, DependencyObject d)
{
if (isEditing)
d.SetValue(ContentProperty, d.GetValue(TrueContentProperty));
else
d.SetValue(ContentProperty, d.GetValue(FalseContentProperty));
}
private static bool ExtractBool(object value)
{
if (value is bool?)
return ((bool?)value).GetValueOrDefault(false);
if (value is bool)
return (bool)value;
return false;
}
I hope the ExtractBool is pretty self explanatory. A short comment should be attached to the UpdateContent method. We pass in the DependencyObject and since we are in a static context we can’t use the property wrapper so we use SetValue and GetValue instead.
Wrapping up
The purpose of this blog post was to try to explain how to create a relatively simple custom control in a silverlight/wpf application. A certain property type that has been mentioned a lot in this post, is the key to doing that.