为什么对单个绑定项进行更改不会刷新ObservableCollection中的该项
本文关键字:ObservableCollection 刷新 单个 绑定 为什么 | 更新日期: 2023-09-27 18:22:28
我觉得有必要为这个问题道歉。我确信答案已经存在,但我很难理解这里发生了什么。我需要一些帮助来学习。
我的问题是让WPF对ObservableCollections
中对象的更改做出反应。在我的ViewModel中有一个名为ItemPrices
的,作为属性公开。ViewModel实现了INotifyPropertyChanged
。该集合是一个名为Price
的EF对象,但它不是。
集合绑定到ListView
。集合中的每个项目都有一个按钮-单击此按钮将更改绑定到该行的Price
对象的状态。这一切都很好。我想要的是,当用户点击按钮时,按钮上的图像会发生变化。
为此,我创建了一个Converter,它根据绑定的Price
对象的属性返回不同的源字符串。这也有效,但前提是你关闭窗口并重新打开它。我希望它在用户点击按钮时立即做出反应。
我知道ObservableCollection只响应添加和删除,我需要做一些其他事情来通知ViewModel集合中的对象已经更改。我没有在ListView
上使用SelectedItem
做任何其他事情,所以我想我会使用它。
因此,我向ViewModel添加了一个SelectedPrice
比例,并将其绑定到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在价格上,如下所示:
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));
}
}
}
您必须在Price
对象上实现INotifyPropertyChanged
。PropetyChanged
事件不冒泡,它只知道自己的对象。
假设按钮是DataTemplate的一部分,您基本上已经将图像的源绑定到"this"(到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属性的值。