为什么对单个绑定项进行更改不会刷新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));
        }
    }
}

为什么对单个绑定项进行更改不会刷新ObservableCollection中的该项

您必须在Price对象上实现INotifyPropertyChangedPropetyChanged事件不冒泡,它只知道自己的对象。

假设按钮是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属性的值。