来自ViewModel的Rogue PropertyChanged通知

时间:2012-12-07 19:34:03

标签: wpf data-binding mvvm inotifypropertychanged

  

可能重复:
  Why does the binding update without implementing INotifyPropertyChanged?

以下简单的程序导致我数据绑定头痛。我是新手,这就是为什么我怀疑它有一个简单的答案。基本上,我有两个文本框绑定到相同的属性myString。我没有设置ViewModel(只是一个具有一个属性的类,myString),以便在myString更改时向View提供任何通知,因此即使两个文本框都运行双向绑定,也不应该有文本框当myString发生变化时更新,我是对的吗?

...除

在大多数情况下都是如此 - 我使用窗口底部的“更改值”按钮将myString的值更改为用户在相邻文本框中键入的内容,以及顶部的两个文本框,即使它们绑定到myString,也不要改变。精细。但是,如果我在TextBox1中编辑文本,从而更改myString的值(虽然只有当文本框由于默认的UpdateSourceTrigger属性而失去焦点时,请参阅参考资料),TextBox2不应该更新,因为它不应该接收myString的任何更新已经改变。但是,只要TextBox1失去焦点(比如在TextBox2中单击),TextBox2就会使用myString的新值进行更新。

到目前为止,我最好的猜测是因为TextBox绑定到同一个属性,与TextBox1更新myString有关,给TextBox2一个通知,它已经改变了。非常困惑,因为我没有使用过INotifyPropertyChanged或类似的东西。

澄清一下,我不是在问如何解决这个问题。我知道我可以将绑定模式更改为单向选项。我想知道是否有人能对这种奇怪的行为做出解释?

视图模型:

    namespace WpfApplication1
    {
        class ViewModel
        {
            public ViewModel()
            {
                _myString = "initial message";
            }

            private string _myString;

            public string myString
            {
                get
                {
                    return _myString;
                }
                set
                {
                    if (_myString != value)
                    {
                        _myString = value;

                    }
                }
            }
        }
    }

查看:

    <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>

视图后面的代码:

    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;
            }
        }
    }

0 个答案:

没有答案