【问题标题】:Re-evaluating a MultiConverter when a parameter changes?参数更改时重新评估 MultiConverter?
【发布时间】:2011-05-06 17:52:00
【问题描述】:

我有一个表示 SQL WHERE 语句的列表框,其中的项目可以分组。

例如,用户的列表框中可以有以下项目

仅当 ListBox 项不是列表框或组中的第一项(如示例)时,我才想显示 AND/OR 值。我目前在 ListBox 的 ItemTemplate 上使用 MultiConverter,它接受 ListBox 的 ItemSource 和 Current Item 作为参数,但是当用户添加新项目或将现有项目拖到新项目时,现有项目不会更新它们的 AND/OR 可见性点在列表框中。

有没有办法告诉 MultiConverter 在其参数之一(ListBox 的 ItemSource)发生变化时重新评估?我正在使用 MVVM,并且 ListBox 绑定到项目的 ObservableCollection。

更新 亚当要求的代码......

<ListBox x:Name="WhereList" ItemsSource="{Binding Path=CurrentQuery.WhereList}">        
    <ListBox.Style>
        <Style TargetType="{x:Type ListBox}">
            <Setter Property="ItemTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch"
                                    Margin="{Binding Path=Depth, Converter={StaticResource QueryBuilder_DepthToMarginConverter}}">
                            <Label Content="{Binding Path=BooleanComparison}" Padding="0">
                                <Label.Visibility>
                                    <MultiBinding Converter="{StaticResource ShouldShowOperatorConverter}">
                                        <Binding ElementName="WhereList" Path="ItemsSource"/>
                                        <Binding />
                                    </MultiBinding>
                                </Label.Visibility>
                            </Label>

                            <Label Content="{Binding ConditionText}" Padding="0" HorizontalAlignment="Stretch" />
                        </StackPanel>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.Style>
</ListBox>

MultiConverter 接受项目列表和当前项目。它检查该项目是否是列表中的第一个项目,或者列表中的前一个项目是否是 GroupStart 项目。如果其中任何一个条件为真,则返回 Visibility.Collapsed,否则返回 Visibility.Visible。

它在第一次加载时工作正常,对单个项目所做的更改(将新项目拖到列表框中,或将现有项目拖到列表框中的新位置)将正确更新新项目的 AND/OR 可见性,但是它不会更改任何其他项目,而不是正在添加/移动的项目。因此,如果您将新项目拖到列表顶部,它将正确隐藏新项目的 AND/OR,但不会更新第二个项目(以前的第一个项目)以显示 AND/OR。这确实会影响列表中项目的可读性,并阻止用户查看他们当前是否使用 AND 或 OR 链接项目,这会对返回的结果产生很大影响。

我很确定这与我使用 MultiConverter 的事实有关,因为我的 DepthToMarginConverter 工作正常(例如,对项目进行分组会正确更新组内所有项目的边距)。

【问题讨论】:

    标签: wpf xaml observablecollection converter


    【解决方案1】:

    您需要在 ViewModel 中的 ListBox 的 ItemsSource 上引发 PropertyChanged 事件。如果您的 ViewModel 基类有一个 RaisePropertyChanged 方法或其他一些 INOtifyPropertyChanged 帮助器,请在您的集合上提出它 - 这应该会导致 ListBox 刷新它的数据,并再次通过转换器运行它。

    【讨论】:

    • ItemsSource 是一个 ObservableCollection,它在添加/删除新项目时已经引发 PropertyChanged 事件。以防万一,我手动调用了 PropertyChange 事件,但它仍然没有重新评估转换器。
    • ObservableCollection 确实会在集合本身发生更改时引发 PropertyChanged(如您所说 - 添加或删除项目),如果集合中的项目本身发生更改,它不会引发它。这就是为什么你必须自己提高它。本来以为会奏效的。你能提供一些代码吗?
    • 我添加了一些代码。我认为这与 MultiConverter 有关,因为在这种情况下,集合本身已更改 - 新项目被拖入其中,或者项目被删除并重新插入到新索引处。我知道 PropertyChanged 事件正在运行,因为 ListBox 显示了新的/删除的项目。当属性更改时,项目也会正确更新,例如它们的值、AND/OR 运算符、项目的分组/深度/边距等
    【解决方案2】:

    我想不出一种方法来让我的MultiConverter 在其中一个参数更改时刷新(是的,它实现了INotifyPropertyChange)所以我最终只是向我的 IsBooleanOperatorShown 项目添加了一个属性并使用常规BooleanToVisibility转换器

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 2014-11-10
      • 2016-03-02
      • 1970-01-01
      • 2011-10-22
      • 2016-10-15
      相关资源
      最近更新 更多