Databound to an ObservableCollection
, I am filling an ItemsControl
with Buttons
. I am using UniformGrid
to help evenly spread things out whether there are 5 or 5000 objects in the ObservableCollection
.
Desire: After the user searches/filters the ObservableCollection
, I would like to update an IsVisible
property on items to show/hide them... while also consolidating the space.
Rationale: I figured, performance wise, updating a property would be better than doing a Clear()
and loop to re-add the filtered items back to the databound ObservableCollection
.
Problem: While the current implementation (code below) does visibly hide the buttons, the space they take up still is present regardless of which Visibility
property I try to use.
Disclaimer: I am open to more than just simply "fixing" my current code. For example, if a viable solution does not use UniformGrid
for example but still achieves a sustainable result, I can probably use it! The same is true on the ViewModel
side.
<ItemsControl Name="ItemsList"
Width="Auto"
HorizontalContentAlignment="Left"
ItemsSource="{Binding ItemsVM.WorkList}"
ScrollViewer.CanContentScroll="True" VirtualizingStackPanel.IsVirtualizing="true"
VirtualizingStackPanel.VirtualizationMode="Standard"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="5" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button
Width="250" Height="50"
FontSize="18" FontWeight="Bold"
Background="{Binding TextColor, Converter={StaticResource TextToColorConvert}, UpdateSourceTrigger=PropertyChanged}"
Margin="1,1,1,1" HorizontalAlignment="Center" VerticalAlignment="Center"
BorderBrush="WhiteSmoke" BorderThickness="0" Click="workNumSelect"
Content="{Binding Workload.WorkNum}"
Cursor="Hand" Opacity=".8"
Visibility="{Binding IsVisible, Converter={StaticResource BoolToCollapsedVisConvert}, UpdateSourceTrigger=PropertyChanged}"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer Width="Auto" VerticalScrollBarVisibility="Visible">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
Update: I did not simply copy and paste the entire answer.
Button
, inside of the DataTemplate
, I removed the Visibility
line.I only added the following code:
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Style.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</ItemsControl.ItemContainerStyle>
It has no effect to set the Visibility of the Button in the DataTemplate. You should instead set the Visibility of the item container, i.e. the ContentPresenter
that displays the individual items.
You would achieve that by setting the ItemContainerStyle
of the ItemsControl to a Style with a Setter that binds the Visibility property, or with a DataTrigger
instead of a Binding with Converter.
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer VerticalScrollBarVisibility="Visible">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="5" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button ... />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Style.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With