为什么 IMultiValueConverter 没有将更新的 ObservableCollection 作为参数获取?

Why IMultiValueConverter doesn't get updated ObservableCollection as a parameter?

我有一个 ItemsControl 是这样设置的:

<ItemsControl ItemsSource="{Binding GameObjects}" 
                          AlternationCount="{Binding GameObjects.Count}" 
                          Grid.RowSpan="10"
                          Grid.ColumnSpan="10">
<DataTemplate>
    <Grid>
        <Grid.DataContext>
            <vm:MainWindowViewModel/>
        </Grid.DataContext>
        <TextBlock Text="{Binding Path=(ItemsControl.AlternationIndex), 
                         RelativeSource={RelativeSource TemplatedParent}}"/>
        <Image>
            <Image.Source>
                <MultiBinding Converter="{StaticResource 
                    ObservableCollectionItemByAlternationIndex}">
                    <Binding Path="Textures"/>
                    <Binding Path="GameObjects"/>
                    <Binding Path="(ItemsControl.AlternationIndex)"
                        RelativeSource="{RelativeSource TemplatedParent}"/>
                </MultiBinding>
            </Image.Source>
        </Image>
    </Grid>
</DataTemplate>

转换器如下所示:

public override object Convert(object[] v, Type t, object p, CultureInfo c)
    {
        var value1 = (ObservableCollection<string>)v[0];
        var value2 = (ObservableCollection<GameObject>)v[1];
        var value3 = (int)v[2];

        foreach(var tex in value1)
        {
            if ("/Maelstrom;component//Data/Resources/Textures/" + value2[value3].GetType().Name + ".png" == tex)
            {
                return new BitmapImage(new Uri("pack://application:,,," + tex));
            }
        }

        return new BitmapImage(new Uri("pack://application:,,," + value1[0]));
    }

这里的问题是,当我更新 GameObjects 时,转换器不会获取 GameObjects 的更新版本,value1 将包含 value1 中的所有元素=14=] 程序启动时。 ItemsControl 更新正常(从 GameObjects 中删除的项目也从 UI 中删除)。

问题是您混淆了 INotifyPropertyChangedINotifyCollectionChanged

A multi-binding 仅在其中一个绑定中的属性之一发出 INotifyPropertyChanged.PropertyChanged 事件时才会更新。换句话说,如果 整个集合 底层 TexturesGameObjects 被完全替换为 ObservableCollection

的全新实例

但是,当您 add/remove 项 to/from 和 ObservableCollection 时,情况并非如此。那样的话,属性那个returns那个集合对象根本就不会变;完全相同的 ObservableCollection 对象仍然存在。但是集合 本身 引发了 INotifyCollectionChanged.CollectionChanged 事件。

WPF 对此做出反应的唯一方法是,如果某个对象正在监视 INotifyCollectionChanged 的特定 ObservableCollection 对象。当您在 MultiBinding 中使用它时,这不可能发生,因为 ObservableCollection 在转换中丢失了。 MultiBinding returns 一个单独的值,无论该值是什么,它都不是实现 INotifyCollectionChanged.

的任何对象

您可能想查看 CompositeCollection class。这可能是更好的方法