WPF应用程序的意外行为

Dav*_*igo 2 c# wpf xaml

我正在学习WPF,我编写了一个使用"Bindings"概念的小例子.但该程序的行为与我的预期不同.

我有Person类,它有两个属性:FirstName和LastName.这个类实现了INotifyPropertyChanged接口,因此我可以用它来绑定.

 class Person : INotifyPropertyChanged
{
    private string firstName;
    private string lastName;

    public string FirstName
    {
        get {  return firstName; }
        set { NotifyPropertyChanged("FirstName"); firstName = value; }
    }

    public string LastName
    {
        get { return lastName; }
        set { NotifyPropertyChanged("LastName"); lastName = value; }
    }

    private void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(info));
    }

    public event PropertyChangedEventHandler PropertyChanged;

}
Run Code Online (Sandbox Code Playgroud)

然后我有一些XAML代码.

<Window x:Class="BughouseClient.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <StackPanel Name="stackPanel">
        <TextBox Text="{Binding Path=FirstName, UpdateSourceTrigger=PropertyChanged}">
        </TextBox>
        <TextBox Text="{Binding Path=LastName, UpdateSourceTrigger=PropertyChanged}"></TextBox>
        <Button Click="Fill">
            Click
        </Button>
    </StackPanel>
</Grid>
Run Code Online (Sandbox Code Playgroud)

MainClass代码:

public partial class MainWindow : Window
{
    Person person;

    public MainWindow()
    {
        InitializeComponent();
        person = new Person();
        person.FirstName = "Bruce";
        person.LastName = "Lee";
        stackPanel.DataContext = person;
    }

    void Fill(object sender, RoutedEventArgs e)
    {
        person.FirstName = "John";
        person.LastName = "Jones";     
    }
}
Run Code Online (Sandbox Code Playgroud)

我期待当我点击Click按钮时,FirstName和LastName属性将会改变,我将立即在文本框中看到它们.但我必须单击TWICE才能看到文本框中的更改.请问有谁知道为什么?

..我发现,当我将MainClass代码更改为:

public partial class MainWindow : Window
{
    Person person;
    int i = 1;

    public MainWindow()
    {
        InitializeComponent();
        person = new Person();
        person.FirstName = "Bruce";
        person.LastName = "Lee";
        stackPanel.DataContext = person;
    }

    void Fill(object sender, RoutedEventArgs e)
    {
        if (i == 1)
        {
            person.FirstName = "John";
            person.LastName = "Jones";
            i++;
        }
        if (i == 2)
        {
            person.FirstName = "Jim";
            person.LastName = "Parker";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它"神奇地"起作用!我可以立即在文本框中看到John Jones.但我无法解释原因.任何帮助将非常感激.先感谢您.

loo*_*ode 7

更新后备字段后,需要进行通知.

这个:

set { NotifyPropertyChanged("FirstName"); firstName = value; }
Run Code Online (Sandbox Code Playgroud)

应该:

set { firstName = value; NotifyPropertyChanged("FirstName");  }
Run Code Online (Sandbox Code Playgroud)

当您调用NotifyPropertyChanged时会发生绑定触发器,如果​​您先调用它,那么当触发绑定时您的字段不会更新,并且您最终仍然显示旧值.