我觉得有必要为这个问题道歉。我确定答案已存在于某处,但我无法理解这里发生了什么。我可以使用一些帮助学习。
我的问题是让WPF对ObservableCollections
内的对象的更改做出反应。我的ViewModel中有一个名为ItemPrices
,作为属性公开。 ViewModel实现INotifyPropertyChanged
。该集合是名为Price
的EF对象,但不是。{/ p>
该集合绑定到ListView
。集合中的每个项目都有一个按钮 - 单击此按钮可更改绑定到该行的Price
对象的状态。一切正常。我想要发生的是当用户点击按钮时按钮上的图像会发生变化。
我通过创建一个转换器来实现此目的,该转换器根据绑定的Price
对象的属性返回不同的源字符串。这也有效 - 但只有关闭窗口并重新打开它。当用户点击按钮时,我希望它立即做出反应。
我知道ObservableCollection只响应添加和删除,我需要做一些其他事情来通知ViewModel集合中的对象已经改变。我没有使用SelectedItem
上的ListView
用于其他任何内容,所以我想我会使用它。
因此,我向ViewModel添加了SelectedPrice
propoerty,并将其绑定到ListView中的SelectedItem属性。然后,在用户单击按钮时执行的函数中,我添加了SelectedPrice = price
- 假设对OnPropertyChanged的调用会冒泡并导致项目在ViewModel中刷新。
它不起作用,我不完全确定原因。我尝试了很多其他的事情,例如在ObservableCollection
中包裹ICollectionView
并在其上调用Refresh()
,并在价格中添加INotifyPropertyChanged
- 但我没做什么将立即刷新该图像。
<Button Width="30" HorizontalAlignment="Right" Margin="5" CommandParameter="{Binding}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.DocumentCommand}" >
<Image HorizontalAlignment="Center" VerticalAlignment="Center" Source="{Binding Converter={StaticResource PriceDocumentImageConverter} }" />
</Button>
转换器:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Price price = (Price)value;
if(price.DocumentId != null)
{
return @"/Resources/Icons/Document-View.png";
}
return @"/Resources/Icons/Document-Add.png";
}
EDIT2 - INotifyPropertyChanged在Price上,如下所示:
public partial class Price : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
答案 0 :(得分:3)
您必须在INotifyPropertyChanged
对象上实施Price
。
PropetyChanged
事件不会起泡,它只知道自己的对象。
假设该按钮是DataTemplate的一部分,您基本上将图像的来源绑定到&#34;这个&#34; (对于Price对象本身),你实际上似乎想要将它绑定到单击按钮时更改的状态(可能是属性)。该属性是应该触发PropertyChanged事件的属性(将其名称作为属性名称传递),并且图像源应该绑定到该属性,即(假设它被称为State):
public partial class Price : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public int State
{
get { /*...*/ }
set
{
/*...*/
OnPropertyChanged("State");
}
}
}
XAML:
<Image Source="{Binding State, Converter={StaticResource PriceDocumentImageConverter} }" />
当然,您必须更新转换器,因为它现在将获取传入的State属性的值。