While debugging a problem in a WPF application, I have noticed that the TwoWay data binding does not seem to be symmetrical. Here is an example:
<Window x:Class="ConverterTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ConverterTest"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:TextConverter x:Key="textConverter"/>
</Window.Resources>
<Grid>
<TextBox x:Name="txt1" Height="24" Margin="0" VerticalAlignment="Top"/>
<TextBox x:Name="txt2" Height="24" Margin="0,40,0,0" VerticalAlignment="Top"
Text="{Binding ElementName=txt1, Path=Text,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource textConverter}}"/>
</Grid>
</Window>
The converter looks like this:
public class TextConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, System.Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
return value.ToString().ToUpper();
}
public object ConvertBack(object value, System.Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
return value.ToString().ToLower();
}
#endregion
}
When editing inside txt1, only Convert() is called; but when editing inside txt2, first ConvertBack() and then Convert() is called.
In other words, TwoWay binding seems to work like this:
- When the source property is updated, the target property is updated.
- When the target property is updated, first the source property is updated, and then the target property is updated again.
The MSDN documentation merely says:
Causes changes to either the source property or the target property to automatically update the other.
From that sentence, I would have expected the following behavior:
- When the source property is updated, the target property is updated.
- When the target property is updated, the source property is updated.
Is there any way to achieve this symmetrical behavior (purely in XAML, without C# programming)?
EDIT: I just have discovered that in WPF 3.5, TwoWay bindings work symmetrical. In WPF 4.0, however, the behavior has changed (as described above).
Well, entirely symmetrical cannot be achieved because:
For example: validation.
When the source is updated, say, from code, it passed all validation (unless you forgot to check, but that’s another problem). The control just displays the new value.
When the target is updated, the value is first converted back in the converter to be manipulable, then coerced, validated and then at last, the source is set.
But as you see, the value could have been modified between the target and the source, so the value is converted again, and finally displayed.
Bonus: to understand where and in which order the value can change, see Dependency Property Value Precedence.