gpt4 book ai didi

wpf - 嵌套对象更改时更新绑定(bind)

转载 作者:行者123 更新时间:2023-12-01 12:59:31 25 4
gpt4 key购买 nike

我有一些 XAML 如下(一个简单的标签和按钮):

<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Test="clr-namespace:WpfApplication2">
<StackPanel DataContext="{Binding Path=TestPerson}">
<Label Content="{Binding Path=Name}"></Label>
<Button Content="Button" Click="button1_Click" />
</StackPanel>
</Window>

在我后面的代码中:

public partial class MainWindow : Window, INotifyPropertyChanged
{
private Person _person = new Person();
public Person TestPerson { get { return _person; } }

public MainWindow()
{
DataContext = this;
InitializeComponent();
}

private void button1_Click(object sender, RoutedEventArgs e)
{
_person.Name = "Bill";
//_person = new Person() { Name = "Bill" };
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("TestPerson"));
}
}

public event PropertyChangedEventHandler PropertyChanged;
}

类 Person 是:

public class Person
{
string _name = "Bob";

public string Name
{
get { return _name; }
set { _name = value; }
}
}

实际上,触发 Propertychanged 事件不会导致 Label 的内容更改为 Bill。

我发现我可以通过以下任一方法克服这个问题:

  • 将新对象分配给 _person(如注释掉的那一行)
  • 从 StackPanel 中删除 DataContext 并将 Label 绑定(bind)到 Path=TestPerson.Name

我不明白为什么我必须实际分配一个新对象给 _person 来更新标签,或者在绑定(bind)中使用完整路径。

有没有办法在提供完整路径(依赖于 DataContext)并且将新对象分配给 _person 的情况下更新标签?

最佳答案

您为 Person 实例 TestPerson 引发了 PropertyChanged。但是,TestPerson 没有改变,改变的是 TestPersonName 属性,也就是 Label< 的属性 绑定(bind)到。

编辑:回答为什么你的前两个版本有效

Assigning a new object to _person (as in the commented out line)

这里您实际上是在更改 TestPerson 的值,因为 DataContext 由子级继承,所以 Label 得到一个新的 DataContext 以及 Binding 更新的原因。

Removing the DataContext from the StackPanel and have Label bind to Path=TestPerson.Name

这是我从未见过的。相同的绑定(bind)为 Person 中的 TestPersonName 订阅 PropertyChanged,因此引发 PropertyChanged 对于这些属性中的任何一个都可以。

如果您想在不为 Person 实现 INotifyPropertyChanged 的情况下解决这个问题,您可以将 set UpdateSourceTrigger 更改为 Explicit

<Label Name="label"
Content="{Binding Path=Name, UpdateSourceTrigger=Explicit}"/>

并在 Name 更改时手动更新 Binding

private void button1_Click(object sender, RoutedEventArgs e)
{
_person.Name = "Bill";
BindingExpression be = label.GetBindingExpression(Label.ContentProperty);
be.UpdateTarget();
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("TestPerson"));
}
}

否则,只需为 Person 实现 INotifyPropertyChanged,它就会起作用

public class Person : INotifyPropertyChanged
{
string _name = "Bob";

public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}

public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

关于wpf - 嵌套对象更改时更新绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7381445/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com