I have a OneWayToSource binding that is not behaving as I expected when I set the DataContext of the target control. The property of the source is being set to default instead of the value of the target control's property.
I've created a very simple program in a standard WPF window that illustrates my problem:
XAML
<StackPanel>
<TextBox x:Name="tb"
Text="{Binding Path=Text,Mode=OneWayToSource,UpdateSourceTrigger=PropertyChanged}"
TextChanged="TextBox_TextChanged"/>
<Button Content="Set DataContext" Click="Button1_Click"/>
</StackPanel>
MainWindow.cs
public partial class MainWindow : Window
{
private ViewModel _vm = new ViewModel();
private void Button1_Click(object sender, RoutedEventArgs e)
{
Debug.Print("'Set DataContext' button clicked");
tb.DataContext = _vm;
}
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
Debug.Print("TextBox changed to " + tb.Text);
}
}
ViewModel.cs
public class ViewModel
{
private string _Text;
public string Text
{
get { return _Text; }
set
{
Debug.Print(
"ViewModel.Text (old value=" + (_Text ?? "<null>") +
", new value=" + (value ?? "<null>") + ")");
_Text = value;
}
}
}
The TextBox tb
starts out with a null DataContext and therefore the binding is not expected to do anything. So if I type something in the text box, say "X", the ViewModel.Text property remains null.
If I then click the Set DataContext button I would have expected the ViewModel.Text
property to be set to the "X" of the TextBox.Text
property. Instead it is set to "". Certainly the binding is working because if I then type "Y" in the text box, after the "X", it sets the ViewModel.Text
property to "XY".
Here is an example of the output (the last two lines are counter-intuitive because of the order of evaluation, but they definitely both occur immediately after typing the "Y"):
TextBox changed to X
'Set DataContext' button clicked
ViewModel.Text (old value=<null>, new value=)
ViewModel.Text (old value=, new value=XY)
TextBox changed to XY
Why is the ViewModel.Text
property being set to "" instead of "X" when the DataContext is set?
What am I doing wrong? Am I missing something? Have I misunderstood something about binding?
Edit: I would have expected the output to be:
TextBox changed to X
'Set DataContext' button clicked
ViewModel.Text (old value=<null>, new value=X)
ViewModel.Text (old value=X, new value=XY)
TextBox changed to XY