WPF ListBoxItem Visibility and ScrollBar

不打扰是莪最后的温柔 提交于 2019-12-13 17:05:18

问题


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?


回答1:


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}}"/>



回答2:


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

Why don't my listboxitems collapse?



来源:https://stackoverflow.com/questions/6655968/wpf-listboxitem-visibility-and-scrollbar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!