WPF: Tips - the Mystery of the Lost Binding
This is more a horror story than a whodunnit.
There you are working on your application and suddenly you notice it's behaving strangely.
A dark shadow falls across the monitor, a door suddenly slams shut and dogs can be heard howling in the distance.
Your binding is gone.
Oh no.
What strange force is at work?
It was right there a moment ago.
Who or what stole your binding?
The Problem
If you set a value on a bound property then that effectively over-writes any binding that property had on it.
Even when you know this and don't write code behind, it's still entirely possible to set a value on a bound property and bang your binding is gone.
One easy way to lose your binding is an animation.
The sample provides a simple way to see this happening.
Rectangle
There's a Blue rectangle which has it's opacity bound to a property in the ViewModel called Opacity.
<Rectangle Name="BlueRectangle" Height="40" Fill="Blue" VerticalAlignment="Top"
Opacity="{Binding Opacity, Mode=TwoWay}"/>
That's the only property in the ViewModel ( this is a particularly focussed sample ).
public class MainWindowViewModel : ViewModelBase
{
private double opacity = 1;
public double Opacity
{
get
{
return opacity;
}
set
{
opacity = value;
RaisePropertyChanged();
}
}
}
Slider
That Opacity is also bound to a slider. Laziness kicked in during the layout design and the control is just vertically centred rather than using margins and a stackpanel or another grid. This meant using just one control but it's also a mildly interesting way to label a control using a HeaderedContentControl presenting the labelled TextBlock as content.
<HeaderedContentControl VerticalAlignment="Center">
<HeaderedContentControl.Header>
<TextBlock Text="Opacity for Rectangle 0 - 1"/>
</HeaderedContentControl.Header>
<Slider Minimum="0" Maximum="1" Value="{Binding Opacity, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</HeaderedContentControl>
As you can see the binding is twoway to guarantee as the property in the ViewModel changes, the thumb will move up and down the track of the Slider to match.
Similarly, UpdateSourceTrigger=Propertychanged makes the ViewModel property update immediately the user moves that thumb.
It's perhaps worth explaining the pointer thing on the Slider is called a Thumb, just in case you are unfamiliar with these controls.
Button
In order to illustrate this issue we need something to over-write that binding. That's where a xaml only button comes in.
<Button Grid.Column="1" Height="30" Margin="20">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard >
<Storyboard >
<DoubleAnimation
From="1"
To="0.1"
Storyboard.TargetName="BlueRectangle"
Storyboard.TargetProperty="(Rectangle.Opacity)"
Duration="0:0:3"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
Animate Opacity on Rectangle
</Button>
When you click on that button it animates the opacity of the blue rectangle from 1 to 0.1 over a period of 3 seconds. That fades it to almost nothing.
Experimenting
If you download and spin the app up, it will look like this:
( The elegance stems from It's a minimalist design. )
As you can see, the Slider starts off with its thumb over on the right. That's the starting opacity of 1 and the rectangle is a fairly deep blue.
Drag the slider over to the left and the rectangle totally disappears - Opacity of zero leaves you nothing to see.
Drag the thumb back over to 1.
Next, click on the "Animate Opacity on Rectangle" button.
The rectangle fades to almost nothing over a few seconds.
Notice how the thumb stays over there on the right.
Drag the thumb backwards and forwards on it's track and nothing happens.
In fact the animation takes a few seconds so you can click on the button and then drag the thumb whilst the animation is still running.
What Happened?
The animation has overwritten the binding.
The way round this is to animate a property that is bound to rather than the one which is the target. This can be tricky but if it was easy then anyone'd be writing WPF,
See Also
This article is part of the WPF Tips Series, if WPF is your area of interest then you will probably find other useful articles there.