WPF ListBoxItem 可见性和滚动条

发布于 2024-11-19 21:51:05 字数 979 浏览 3 评论 0原文

我希望根据数据上下文的属性折叠某些 ListBoxItems。

我想出了以下内容(为了简洁而进行了修剪)

<ListBox ItemsSource="{Binding SourceColumns}">
     <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Style.Triggers>
              <DataTrigger Binding="{Binding IsDeleted}" Value="True">
                 <Setter Property="Visibility" Value="Collapsed"/>
              </DataTrigger>
            </Style.Triggers>
         </Style>
      </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
       <DataTemplate>
         <TextBlock VerticalAlignment="Center" Margin="5,0" Text="{Binding ColumnName}"/>
       </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

这个“有效”,因为它确实折叠了标记为“IsDeleted”的列表框项目,但是垂直滚动条不会针对“丢失”项目进行调整。当我滚动时,栏突然变得越来越大(没有移动),直到我滚动经过隐藏项目的点,然后最终开始移动。

我还尝试在数据触发器中明确将高度和宽度设置为 0,但无济于事。

有谁知道这个问题是否有解决方法?

I was hoping to collapse certain ListBoxItems based on a property of their data context.

I came up with the following (trimmed for brevity)

<ListBox ItemsSource="{Binding SourceColumns}">
     <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Style.Triggers>
              <DataTrigger Binding="{Binding IsDeleted}" Value="True">
                 <Setter Property="Visibility" Value="Collapsed"/>
              </DataTrigger>
            </Style.Triggers>
         </Style>
      </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
       <DataTemplate>
         <TextBlock VerticalAlignment="Center" Margin="5,0" Text="{Binding ColumnName}"/>
       </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

This "works" in that it does collapse the listboxitems that are marked as "IsDeleted", however the vertical scrollbar does not adjust for the "missing" items. As I'm scrolling, all of a sudden the bar gets bigger and bigger (without moving) until I scroll past the point of the hidden items, and then finally starts to move.

I also tried explicitly setting the height and width to 0 as well in the data trigger, to no avail.

Does anyone know if there's a workaround for this?

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

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

发布评论

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

评论(2

指尖上的星空 2024-11-26 21:51:06

输入 CollectinViewSource

您可以做的一件事是通过 CollectionViewSource 将 ListBox 连接到您的项目。

您要做的就是在 XAML 中创建 collectionViewSource:

<Window.Resources>
    <CollectionViewSource x:Key="cvsItems"/>
</Window.Resources>

在 CodeBehind 或 ViewModel 中连接到它

Dim cvsItems as CollectionViewSource
cvsItems = MyWindow.FindResource("cvsItems")

,并将其源属性设置为您的项目集合。

cvsItems.Source = MyItemCollection

然后你就可以对其进行过滤。 collectionViewSource 维护集合中的所有项目,但根据您告诉它的内容更改这些项目的视图。

过滤

要进行过滤,请使用 CollectionViewSource 创建一个 CollectionView:

Dim MyCollectionView as CollectionView = cvsItems.View

接下来编写一个过滤函数:

Private Function FilterDeleted(ByVal item As Object) As Boolean
    Dim MyObj = CType(item, MyObjectType)
    If MyObj.Deleted = True Then Return False Else Return True End If
End Function

最后,编写一些使奇迹发生的东西:

MyCollectionView .Filter = New Predicate(Of Object)(AddressOf FilterDeleted)

我通常在可隐藏的扩展器中使用复选框或单选按钮,让我可以来回更改过滤选项。这些绑定到属性,每个属性都运行过滤器函数,该函数评估所有过滤器,然后返回该项目是否应该出现。

让我知道这是否适合您。

编辑:

我差点忘了:

<ListBox ItemsSource="{Binding Source={StaticResource cvsItems}}"/>

Enter CollectinViewSource

One thing you can do is connect your ListBox to your items through a CollectionViewSource.

What you do is create the collectionViewSource in XAML:

<Window.Resources>
    <CollectionViewSource x:Key="cvsItems"/>
</Window.Resources>

Connect to it in your CodeBehind or ViewModel

Dim cvsItems as CollectionViewSource
cvsItems = MyWindow.FindResource("cvsItems")

and set it's source property to your collection of items.

cvsItems.Source = MyItemCollection

Then you can do filtering on it. The collectionViewSource maintains all of the items in the collection, but alters the View of those items based on what you tell it.

Filtering

To filter, create a CollectionView using your CollectionViewSource:

Dim MyCollectionView as CollectionView = cvsItems.View

Next write a filtering function:

Private Function FilterDeleted(ByVal item As Object) As Boolean
    Dim MyObj = CType(item, MyObjectType)
    If MyObj.Deleted = True Then Return False Else Return True End If
End Function

Finally, write something that makes the magic happen:

MyCollectionView .Filter = New Predicate(Of Object)(AddressOf FilterDeleted)

I usually have checkboxes or Radiobuttons in a hideable expander that lets me change my filtering options back and forth. Those are bound to properties each of which runs the filter function which evaluates all the filters and then returns whether the item should appear or not.

Let me know if this works for you.

Edit:

I almost forgot:

<ListBox ItemsSource="{Binding Source={StaticResource cvsItems}}"/>
江南月 2024-11-26 21:51:06

答案是在列表框中设置 VirtualizingStackPanel.IsVirtual="False"。

为什么我的列表框项目不折叠?

The answer is to set the VirtualizingStackPanel.IsVirtual="False" in your listbox.

Why don't my listboxitems collapse?

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