我试图通过数据绑定到viewmodel中的属性(视图的datacontext)来更新视图上的文本块。
在下面的代码中;当 SelectedItem 发生变化时,我希望使用 SelectedItem 上名称属性的值更新文本块文本。
为了实现这一目标,我将绑定源设置为正在更改的属性,将绑定路径设置为我想要更新文本块的数据。
即。我期待绑定引擎会在绑定Source(SelectedItem)上看到更改,并从绑定路径(SelectedItem.Name)中提取数据。
http://msdn.microsoft.com/en-us/library/ms746695.aspx
设置SelectedItem会引发INPC,但文本不会更新。
public class ViewModel
{
public IConfiguration Configuration { get; set;}
}
public class Configuration : IConfiguration, INotifyPropertyChanged
{
public Item SelectedItem
{
get { return _item;}
set
{
_item = value;
ItemName = _item.Name;
RaisePropertyChangedEvent("SelectedItem");
}
}
public string ItemName
{
get { return _itemName;}
set
{
_itemName= value;
RaisePropertyChangedEvent("ItemName");
}
}
}
public class Item
{
public string Name { get; set;}
}
我知道可以看到配置上的更改,因为它有效:
<TextBlock Text="{Binding Configuration.ItemName}"/>
但这不是:
<TextBlock Text="{Binding Path=Name, Source=Configuration.SelectedItem}"/>
这也不是:
<TextBlock Text="{Binding Path=Configuration.SelectedItem.Name, Source=Configuration.SelectedItem}"/>
我认为这应该是直截了当的 - 我错过了什么?
答案 0 :(得分:3)
我以前从未见过有人使用Binding.Source,所以我对此并不了解。但我的猜测是它不是动态的。当您创建绑定时,它会抓取对Source中指定的对象的引用,然后就是它:它在绑定的生命周期中使用相同的引用。
为什么要这么复杂?只需使用Path即可。这是进行绑定的常规方式,它一直是动态的 - 你所做的正是Path的目的。
<TextBlock Text="{Binding Path=Configuration.SelectedItem.Name}"/>
答案 1 :(得分:0)
这可能有效,你就是看不到它。尚未通知Binding引擎Item对象的Name属性已更改。
尝试在Item类上实现INotifyPropertyChanged接口(根据需要引发PropertyChanged事件)
这适用于您的第三种绑定情况,也适用于下面的类似定义
<TextBlock DataContext="{Binding Path=Configuration.SelectedItem}" Text="{Binding Path=Name}"/>
但是对于更简单的修复,这应该有效:
<TextBlock Text="{Binding Path=Configuration.SelectedItem.Name}" />
编辑:
public class Configuration : INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
private Item _SelectedItem = null;
public Item SelectedItem
{
get
{
return _SelectedItem;
}
set
{
_SelectedItem = value;
OnPropertyChanged("SelectedItem");
}
}
}
public class Item
{
public string Name { get; set; }
}
然后在某个地方的命令执行中我有这个:
Configuration.SelectedItem = new Item() { Name = "test" };
在View中正确更新TextBlock:
<TextBlock Text="{Binding Path=Configuration.SelectedItem.Name}" />