当嵌套对象更改时更新绑定
我有一些 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 事件不会导致标签的内容更改为 Bill。
我发现我可以通过以下任一方法来克服这个问题:
- 将一个新对象分配给 _person (如注释掉的行中所示)
- 从 StackPanel 中删除 DataContext 并将 Label 绑定到 Path=TestPerson.Name
我不明白为什么我必须实际为 _person 分配一个新对象才能更新标签,或者在绑定中使用完整路径。
有没有一种方法可以在不提供完整路径(依赖于 DataContext)并且不向 _person 分配新对象的情况下更新标签?
I have a some XAML as follows (a simple Label and Button):
<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>
in the code behind I have:
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;
}
and the class Person is:
public class Person
{
string _name = "Bob";
public string Name
{
get { return _name; }
set { _name = value; }
}
}
As it is, firing the Propertychanged event does not cause the Label's contents to change to Bill.
I've found I am able to overcome this by either:
- Assigning a new object to _person (as in the commented out line)
- Removing the DataContext from the StackPanel and have Label bind to Path=TestPerson.Name
I don't understand why I have to actually assign a NEW object to _person for the Label to update, or use the FULL path in the binding.
Is there a way to update the Label without supplying the full path (relying on the DataContext), and without assigning a new object to _person?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您为
Person
实例TestPerson
引发PropertyChanged
。但是,TestPerson
没有改变,改变的是TestPerson
的Name
属性,即Label< 的属性。 /code> 绑定到。
编辑:回答为什么前两个版本有效
这里您实际上正在更改
TestPerson
的值,并且因为DataContext
是由子级继承的,所以Label
也会获得一个新的DataContext
,因此这就是更新Binding
的原因。这是我从未见过的。相同的绑定为
Person
中的TestPerson
和Name
订阅PropertyChanged
,因此引发PropertyChanged
> 对于任何这些属性都可以。如果您想在不为
Person
实现INotifyPropertyChanged
的情况下解决此问题,您可以将UpdateSourceTrigger
设置为Explicit
并更新每当
Name
更改时手动Bining
否则,只需为
Person
实现INotifyPropertyChanged
即可。You raise
PropertyChanged
for thePerson
instanceTestPerson
. However,TestPerson
hasn't changed, it is theName
property ofTestPerson
that has changed and that is the property theLabel
is binding to.Edit: To answer why your first two versions work
Here you are actually changing the value of
TestPerson
and becauseDataContext
is inherited by the children, theLabel
gets a newDataContext
as well so that's why theBinding
is updated.This is something I've never seen. The same binding subscribes to
PropertyChanged
for bothTestPerson
andName
inPerson
so raisingPropertyChanged
for any of these properties will work.If you want to overcome this without implementing
INotifyPropertyChanged
forPerson
, you can change setUpdateSourceTrigger
toExplicit
And update the
Binding
manually wheneverName
changesOtherwise, just implement
INotifyPropertyChanged
forPerson
as well and it will work您需要对 XAML 进行一些更改...
在后面的代码中,不要将
DataContext
设置为this
,而是通过 Binding 在 XAML 中设置它...代码中删除
从您的 代码后面。
让我知道这是否有帮助。
You need a little change in your XAML...
In your code behind, instead of setting
DataContext
asthis
, set it in XAML via Binding...Remove the
from your code behind.
Let me know if this helps.