WPF - 根据数据绑定隐藏 ItemControl -> UniformGrid 中的项目占用 UI space
WPF - Hide items in ItemControl -> UniformGrid from taking up UI space based on databinding
数据绑定到 ObservableCollection
,我正在用 Buttons
填充 ItemsControl
。无论 ObservableCollection
中有 5 个还是 5000 个对象,我都使用 UniformGrid
来帮助均匀分布。
愿望:在用户 searches/filters ObservableCollection
之后,我想将项目上的 IsVisible
属性 更新为 show/hide 他们...同时还巩固了 space.
基本原理:我认为,从性能角度来看,更新 属性 比执行 Clear()
和循环以将过滤的项目重新添加回数据绑定 ObservableCollection
更好。
问题:虽然当前的实现(下面的代码)确实隐藏了按钮,但无论我尝试使用哪个 Visibility
属性,它们占用的 space 仍然存在.
免责声明:我不仅对 "fixing" 我当前的代码持开放态度。例如,如果一个可行的解决方案没有使用 UniformGrid
但仍然取得了可持续的结果,我可能会使用它! ViewModel
这边也是一样。
<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>
更新:
我没有简单地复制和粘贴整个答案。
- 在上面的代码中,在
DataTemplate
的 Button
处,我删除了 Visibility
行。
我只添加了以下代码:
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Style.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</ItemsControl.ItemContainerStyle>
在DataTemplate 中设置Button 的Visibility 无效。您应该改为设置项目容器的可见性,即显示单个项目的 ContentPresenter
。
您可以通过将 ItemsControl 的 ItemContainerStyle
设置为具有绑定可见性 属性 的 Setter 样式或使用 DataTrigger
而不是与转换器的绑定。
<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>
数据绑定到 ObservableCollection
,我正在用 Buttons
填充 ItemsControl
。无论 ObservableCollection
中有 5 个还是 5000 个对象,我都使用 UniformGrid
来帮助均匀分布。
愿望:在用户 searches/filters ObservableCollection
之后,我想将项目上的 IsVisible
属性 更新为 show/hide 他们...同时还巩固了 space.
基本原理:我认为,从性能角度来看,更新 属性 比执行 Clear()
和循环以将过滤的项目重新添加回数据绑定 ObservableCollection
更好。
问题:虽然当前的实现(下面的代码)确实隐藏了按钮,但无论我尝试使用哪个 Visibility
属性,它们占用的 space 仍然存在.
免责声明:我不仅对 "fixing" 我当前的代码持开放态度。例如,如果一个可行的解决方案没有使用 UniformGrid
但仍然取得了可持续的结果,我可能会使用它! ViewModel
这边也是一样。
<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>
更新: 我没有简单地复制和粘贴整个答案。
- 在上面的代码中,在
DataTemplate
的Button
处,我删除了Visibility
行。 我只添加了以下代码:
<ItemsControl.ItemContainerStyle> <Style TargetType="ContentPresenter"> <Style.Triggers> <DataTrigger Binding="{Binding IsVisible}" Value="False"> <Setter Property="Visibility" Value="Collapsed" /> </DataTrigger> </Style.Triggers> </Style> </ItemsControl.ItemContainerStyle>
在DataTemplate 中设置Button 的Visibility 无效。您应该改为设置项目容器的可见性,即显示单个项目的 ContentPresenter
。
您可以通过将 ItemsControl 的 ItemContainerStyle
设置为具有绑定可见性 属性 的 Setter 样式或使用 DataTrigger
而不是与转换器的绑定。
<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>