当参数更改时重新评估 MultiConverter?

发布于 2024-09-30 19:22:41 字数 2442 浏览 4 评论 0原文

我有一个代表 SQL WHERE 语句的列表框,并且可以对里面的项目进行分组。

例如,用户可以在其列表框中包含以下项目

alt text

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

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

更新 Adam 要求的代码...

<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 项目。如果其中一个条件为 true,则返回 Visibility.Collapsed,否则返回 Visibility.Visible。

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

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

I have a listbox representing a SQL WHERE statement and the items inside can be grouped.

For example, a user can have the following items in their ListBox

alt text

I would like to show the AND/OR value only if the ListBox item is not the first item in the listbox or a group (like example). I am currently using a MultiConverter on the ListBox's ItemTemplate that accepts the ListBox's ItemSource and the Current Item as parameters, however existing items do not get their AND/OR visibility updated when the user adds a new item, or drags an existing item to a new spot in the listbox.

Is there a way to tell the MultiConverter to reevaluate when one of its parameters, the ListBox's ItemSource, changes? I am using MVVM and the ListBox is bound to an ObservableCollection of items.

Update
Code as requested by Adam...

<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>

The MultiConverter accepts a list of items, and the current item. It checks to see if the item is the first item in the list, or if the previous item in the list is a GroupStart item. If either of these conditions are true, it returns Visibility.Collapsed, otherwise it returns Visibility.Visible.

It works fine for the first load, and changes made to a single item (dragging a new item into the listbox, or dragging an existing item to a new location in the listbox) will correctly update the new item's AND/OR visibility, however it does not change any other item then the one being added/moved. So if you drag a new item to the top of the list, it will correctly hide the AND/OR of the new item, however it will not update the 2nd item (former first item) to show the AND/OR. This really affects the readability of the items in the list and prevents the user from seeing if they are currently linking the item with an AND or an OR which makes a big difference in the results returned.

I'm fairly sure it has something to do with the fact I'm using a MultiConverter since my DepthToMarginConverter works fine (for example, grouping items correctly updates the margin of all items within the group).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱人如己 2024-10-07 19:22:41

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

You need to raise the PropertyChanged event on the ListBox's ItemsSource in the ViewModel. If your ViewModel base class has a RaisePropertyChanged method, or some other INOtifyPropertyChanged helper, raise that on your collection - this should cause the ListBox to refresh it's data, and run it through the converters again.

初相遇 2024-10-07 19:22:41

我无法找到一种方法让我的 MultiConverter 在其中一个参数更改时刷新(是的,它实现了 INotifyPropertyChange),所以我最终只是向我的IsBooleanOperatorShown 项并使用常规 BooleanToVisibility 转换器

I can't figure out a way to get my MultiConverter to refresh when one of the parameters change (yes it implements INotifyPropertyChange) so I ended up just adding a property to my item of IsBooleanOperatorShown and using a regular BooleanToVisibility converter

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文