我有以下xaml;
<DataTemplate DataType="{x:Type NameSpace:Node}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Item.Value}"/>
<ContentControl Content="{Binding Item}"/>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type NameSpace:Item}">
<TextBlock Text="{Binding Value}" />
</DataTemplate>
当我使用Node模板显示Node对象时,我得到两个TextBlocks,它们都显示相同的值。到现在为止还挺好。项目更改时会发生此问题。当Node类触发INotifyPropertyChanged事件时,Node DataTemplate中的TextBlock会按预期更新,但Item DataTemplate中的TextBlock不会更新。
当Node类触发IPropertyChanged事件时,如何让Item DataTemplate更新其绑定?
更新 事实证明,上述方法适用于以下简单方案;
的Xaml
<DataTemplate DataType="{x:Type DataTemplateExample:Node}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Item.Value}"/>
<ContentControl Content="{Binding Item}"/>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type DataTemplateExample:Item}">
<TextBlock Text="{Binding Value}" />
</DataTemplate>
</Window.Resources>
<Grid>
<StackPanel Orientation="Vertical">
<ContentControl Content="{Binding MyNode}"/>
<Button Command="{Binding ChangeMyNodeItem}">Change Item</Button>
</StackPanel>
</Grid>
</Window>
C#
public class MainViewModel
{
private readonly Node myNode;
private readonly DelegateCommand changeMyNodeItemCmd;
public MainViewModel()
{
myNode = new Node {Item = new Item("a")};
changeMyNodeItemCmd = new DelegateCommand(()=>
myNode.Item = new Item("b"));
}
public Node MyNode { get { return myNode; } }
public ICommand ChangeMyNodeItem
{
get { return changeMyNodeItemCmd; }
}
}
public class Node : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Item item;
public Item Item
{
set
{
item = value;
if (PropertyChanged != null)
PropertyChanged(this,new PropertyChangedEventArgs("Item"));
}
get { return item; }
}
}
public class Item
{
private readonly string value;
public Item(string value)
{
this.value = value;
}
public string Value
{
get { return value; }
}
}
在我的真实场景中,我使用代理,我认为这是让WPF感到困惑的原因。物品实际上并没有改变 - 它被重新映射。
最终,我使用类似于ShadeOfGray提出的解决方案解决了这个问题。但我应该指出,除非你使用代理,否则没有必要这样做。
答案 0 :(得分:2)
根据您发布的内容,我认为您正在错误的类中触发NotifyPropertyChanged。这样的事情应该在你的场景中正常工作。
根据评论更新:
public class Node : INotifyPropertyChanged
{
private Item item;
public event PropertyChangedEventHandler PropertyChanged;
public Item Item
{
get
{
return item;
}
set
{
item = value;
this.NotifyPropertyChanged("Item");
if (item != null)
{
item.ForcePropertyChanged("Value");
}
}
}
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class Item : INotifyPropertyChanged
{
private string itemValue;
public Item()
{
this.Value = string.Empty;
}
public event PropertyChangedEventHandler PropertyChanged;
public string Value
{
get
{
return itemValue;
}
set
{
itemValue = value;
NotifyPropertyChanged("Value");
}
}
public void ForcePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}