开发者

WPF ListBoxItem Visibility and ScrollBar

开发者 https://www.devze.com 2023-03-19 06:35 出处:网络
I was hoping to collapse certain ListBoxItems based on a property of their data context. I came up with the following (trimmed for brevity)

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}">
      开发者_如何学JAVA      <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?


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


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

Why don't my listboxitems collapse?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号