为什么在单个绑定项上提高更改不会刷新ObservableCollection中的该项?

时间:2015-11-19 10:09:54

标签: c# wpf mvvm

我觉得有必要为这个问题道歉。我确定答案已存在于某处,但我无法理解这里发生了什么。我可以使用一些帮助学习。

我的问题是让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));
        }
    }
}

1 个答案:

答案 0 :(得分:3)

您必须在INotifyPropertyChanged对象上实施PricePropetyChanged事件不会起泡,它只知道自己的对象。

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