Rogue PropertyChanged notifications from ViewModel
Posted
by
user1886323
on Stack Overflow
See other posts from Stack Overflow
or by user1886323
Published on 2012-12-07T19:34:03Z
Indexed on
2012/12/09
23:04 UTC
Read the original article
Hit count: 229
The following simple program is causing me a Databinding headache. I'm new to this which is why I suspect it has a simple answer. Basically, I have two text boxes bound to the same property myString. I have not set up the ViewModel (simply a class with one property, myString) to provide any notifications to the View for when myString is changed, so even although both text boxes operate a two way binding there should be no way that the text boxes update when myString is changed, am I right?
Except...
In most circumstances this is true - I use the 'change value' button at the bottom of the window to change the value of myString to whatever the user types into the adjacent text box, and the two text boxes at the top, even although they are bound to myString, do not change. Fine. However, if I edit the text in TextBox1, thus changing the value of myString (although only when the text box loses focus due to the default UpdateSourceTrigger property, see reference), TextBox2 should NOT update as it shouldn't receive any updates that myString has changed. However, as soon as TextBox1 loses focus (say click inside TextBox2) TextBox2 is updated with the new value of myString.
My best guess so far is that because the TextBoxes are bound to the same property, something to do with TextBox1 updating myString gives TextBox2 a notification that it has changed. Very confusing as I haven't used INotifyPropertyChanged or anything like that.
To clarify, I am not asking how to fix this. I know I could just change the binding mode to a oneway option. I am wondering if anyone can come up with an explanation for this strange behaviour?
ViewModel:
namespace WpfApplication1
{
class ViewModel
{
public ViewModel()
{
_myString = "initial message";
}
private string _myString;
public string myString
{
get
{
return _myString;
}
set
{
if (_myString != value)
{
_myString = value;
}
}
}
}
}
View:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
<Grid>
<!-- The culprit text boxes -->
<TextBox Height="23" HorizontalAlignment="Left" Margin="166,70,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" Text="{Binding Path=myString, Mode=TwoWay}" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="166,120,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" Text="{Binding Path=myString, Mode=TwoWay}"/>
<!--The buttons allowing manual change of myString-->
<Button Name="changevaluebutton" Content="change value" Click="ButtonUpdateArtist_Click" Margin="12,245,416,43" Width="75" />
<Button Content="Show value" Height="23" HorizontalAlignment="Left" Margin="12,216,0,0" Name="showvaluebutton" VerticalAlignment="Top" Width="75" Click="showvaluebutton_Click" />
<Label Content="" Height="23" HorizontalAlignment="Left" Margin="116,216,0,0" Name="showvaluebox" VerticalAlignment="Top" Width="128" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="116,245,0,0" Name="changevaluebox" VerticalAlignment="Top" Width="128" />
<!--simply some text-->
<Label Content="TexBox1" Height="23" HorizontalAlignment="Left" Margin="99,70,0,0" Name="label1" VerticalAlignment="Top" Width="61" />
<Label Content="TexBox2" Height="23" HorizontalAlignment="Left" Margin="99,118,0,0" Name="label2" VerticalAlignment="Top" Width="61" />
</Grid>
</Window>
Code behind for view:
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
ViewModel viewModel;
public MainWindow()
{
InitializeComponent();
viewModel = (ViewModel)this.DataContext;
}
private void showvaluebutton_Click(object sender, RoutedEventArgs e)
{
showvaluebox.Content = viewModel.myString;
}
private void ButtonUpdateArtist_Click(object sender, RoutedEventArgs e)
{
viewModel.myString = changevaluebox.Text;
}
}
}
© Stack Overflow or respective owner