WPF-隐藏ItemControl-> UniformGrid中的项目,使其不占用基于数据绑定的UI空间

Ste*_*awg 3 c# wpf datatemplate observablecollection mvvm

数据绑定到ObservableCollection,我正在ItemsControlButtons。我正在UniformGrid用来帮助均匀分布对象,无论对象中有5个还是5000个对象ObservableCollection

需求:用户搜索/过滤之后ObservableCollection,我想更新商品的IsVisible属性以显示/隐藏它们...同时还要巩固空间。

原理:我认为,从性能角度考虑,更新属性要比执行Clear()and循环将过滤后的项目重新添加回databound 更好ObservableCollection

问题:尽管当前的实现(下面的代码)确实隐藏了按钮,但无论Visibility我尝试使用哪个属性,它们仍然占据着空间。

免责声明:我不仅仅只是简单地“修复”当前代码。例如,如果一个可行的解决方案没有使用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>
Run Code Online (Sandbox Code Playgroud)

更新: 我并没有简单地复制并粘贴整个答案。

  1. 在上面的代码中Button,在中的DataTemplate,我删除了该Visibility行。
  2. 我只添加了以下代码:

            <ItemsControl.ItemContainerStyle>
                <Style TargetType="ContentPresenter">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsVisible}" Value="False">
                            <Setter Property="Visibility" Value="Collapsed" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ItemsControl.ItemContainerStyle>
    
    Run Code Online (Sandbox Code Playgroud)

Cle*_*ens 5

在DataTemplate中设置按钮的可见性无效。您应该改为设置项目容器的可见性,即ContentPresenter显示单个项目的。

您可以通过ItemContainerStyle使用将可见性属性绑定到的Setter或通过DataTrigger而不是Converter绑定来将ItemsControl的Style 设置为Style 来实现。

<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>
Run Code Online (Sandbox Code Playgroud)

  • @AvinashReddy 这就像给你 10 张纸,有人告诉你将每张纸折叠成什么......除了那个人故意告诉你不要对其中 6 张纸做任何事情。你还有10张纸!克莱门斯:很好的解释,也是很好的解决方案,我认为可以应用于很多事情。我不知道 ItemContainerStyle 可以这样使用!谢谢你! (2认同)