2

可能重复:
为什么绑定更新而不实现 INotifyPropertyChanged?

下面的简单程序让我对数据绑定感到头疼。我是新手,这就是为什么我怀疑它有一个简单的答案。基本上,我有两个文本框绑定到同一个属性 myString。我还没有设置 ViewModel(只是一个具有一个属性 myString 的类)来向 View 提供任何通知以了解何时更改 myString,因此即使两个文本框都操作双向绑定,文本框也不应该更改 myString 时更新,对吗?

除了...

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

到目前为止,我最好的猜测是,因为 TextBoxes 绑定到同一个属性,所以与 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;
            }
        }
    }
4

0 回答 0