【问题标题】:Multibinding not updating when collection updates集合更新时多重绑定不更新
【发布时间】:2019-11-16 06:48:05
【问题描述】:

我有一个列表框,其中包含消息,它们是简单的(typeEnum,字符串)对象,并使用数据模板显示:

<ListBox ItemsSource="{Binding Messages}"
                Background="DimGray" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" >
                        <TextBlock Text="{Binding MessageText}" >
                            <TextBlock.Foreground>
                                <MultiBinding Converter="{StaticResource TypeEnumToBrushConverter}" >
                                    <Binding Path="TypeEnum" />
                                    <Binding Path="MessageColours" RelativeSource="{RelativeSource AncestorType={x:Type Window}}" />
                                </MultiBinding>
                            </TextBlock.Foreground>
                        </TextBlock>
                        <Button Click="ButtonBase_OnClick1" >T</Button>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

我正在尝试将消息的前景设置为 MessageColours (TypeEnum - Brush 对的集合),我将其传递给转换器。

这适用于我手动添加到 MessageColours 的初始画笔。

我正在另一个窗口中更改它们,并且该集合已成功更新,但是 ListBox 消息颜色不会更新。 MessageColours 最初是一个 ObservableCollection MessageColourSettings (TypeEnum, Brush) 但我将其更改为实现 INotifyPropertyChanged 的​​实现,因此它也会在集合项中的属性发生更改时发出通知,但它没有帮助。

MessageColourSettings 实现了 INotifyPropertyChanged,当另一个窗口的颜色发生变化时它会被触发,并且 MessageColours 集合会触发它的项目属性发生变化。

当我单击该按钮时,它会将 typeEnum 从 A 切换到 B 再切换回 A,然后显示消息 现在有更新的颜色,所以我认为多重绑定有问题。

转换器:

public class TypeEnumToBrushConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            TypeEnum typeEnum = (TypeEnum) values[0];
            var settings = values[1] as FullyObservableCollection<MessageColourSetting>;
            return settings.Single(setting => setting.TypeEnum == typeEnum).Brush;
        }
    }

任何见解将不胜感激

【问题讨论】:

    标签: wpf data-binding


    【解决方案1】:

    我让它工作了,但我仍然不确定为什么它是必要的,或者它是如何工作的。

    我用于 MessageColours 的实现基本上是一个 ObservableDictionary ,它还会在 Message 的属性发生更改时发出通知 我从https://stackoverflow.com/a/32013610/211186得到的

    它工作正常,但 MultiBinding 没有响应通知。

    所以我最终不得不手动完成。

    MessageColours.ItemPropertyChanged += (sender, args) => Update(sender, args);
    
     private void Update(object sender, ItemPropertyChangedEventArgs args)
            {
    
                TypeEnum typeEnum = (sender as FullyObservableCollection<MessageColourSetting>)[args.CollectionIndex].TypeEnum;
    
                IEnumerable<Message> messages =
                    Box.ItemContainerGenerator.Items.Select(m => m as Message).Where(m => m.TypeEnum == typeEnum);
    
                List<ListBoxItem> ListBoxItems = messages
                                                .Select(message => (ListBoxItem) Box.ItemContainerGenerator.ContainerFromItem(message))
                                                .ToList();
    
                foreach (ListBoxItem listBoxItem in ListBoxItems)
                {
                    ContentPresenter presenter = FindVisualChildrenUtils.FindVisualChild<ContentPresenter>(listBoxItem);
                    DataTemplate template = presenter.ContentTemplate;
                    TextBlock textBlock = (TextBlock) template.FindName("messageText", presenter);
                    MultiBindingExpression bindingExpression =
                        BindingOperations.GetMultiBindingExpression(textBlock, ForegroundProperty);
                    bindingExpression.UpdateTarget();
                }
            }
    

    这对我来说似乎很 hackish,但这只是实验性代码。

    有没有更简单的方法来更新多重绑定?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-30
      • 2013-04-17
      相关资源
      最近更新 更多