WPF中ListBox显示横向图片

3

我正在尝试在WPF/XAML中创建一个控件,用于显示水平图像列表。列表框的宽度是固定的(无滚动条)。当添加新项目时,现有项目会减少所显示的图像数量以容纳它(实际图像大小不变,只是显示的图像数量减少)。该功能类似于向具有相对宽度属性("*")的网格添加新列,并且该列包含固定宽度的图像。以下是我的代码:

<Window.Resources>
    <ItemsPanelTemplate x:Key="ListBox_HorizontalItems">
        <StackPanel Orientation="Horizontal" />
    </ItemsPanelTemplate>

    <DataTemplate x:Key="ListBox_DataTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="50" />
            </Grid.ColumnDefinitions>
            <Image Width="150" Source="{Binding ImageSource}" />
        </Grid>
    </DataTemplate>

    <Style x:Key="ListBox_Style_Horizontal" TargetType="ListBox">
        <Setter Property="Width" Value="150" />-->
        <Setter Property="ItemTemplate" Value="{StaticResource ListBox_DataTemplate}" />
        <Setter Property="ItemsPanel" Value="{StaticResource ListBox_HorizontalItems}" />
    </Style>
</Window.Resources>

<Grid>
    <ListBox Name="lbxImages" Style="{StaticResource ListBox_Style_Horizontal}" Width="250"  Height="100" />
</Grid>

非常接近我需要的内容!但是我不知道如何减少新项添加到列表时显示的图片数量。目前,当添加新项时,会出现滚动条。如果我没有表达清楚,这里有一些截图展示我需要的功能:
能否有人向我展示如何实现这个功能?谢谢任何帮助!
2个回答

9
使用以下UniformGrid作为ItemsPanel:
<ItemsPanelTemplate>
    <UniformGrid Columns="{Binding Path=Items.Count,RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"/>
</ItemsPanelTemplate>

禁用水平滚动:

<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled">

修改ItemTemplate:

<DataTemplate>
    <Image Source="{Binding ImageSource}"
           Stretch="None"
           HorizontalAlignment="Center"/>
</DataTemplate>

谢谢,这很好用!我以前从没用过 "UniformGrid",看起来非常实用... - qu1ckdry

0

我发现仅仅替换ItemsPanelTemplate并不能完全去除滚动条,因为该ItemsPanelTemplate嵌套在一个ScrollViewer中,而该ScrollViewer又嵌套在ListBox中的某个位置。你可能还需要移除该ScrollViewer。

我替换了整个ListBox的模板:

<Style  TargetType="ListBox">        
    <Setter Property="Height" Value="Auto"/>
    <Setter Property="Width" Value="Auto"/>        
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Border 
                    BorderBrush="Red" 
                    BorderThickness="1">
                    <UniformGrid  
                        IsItemsHost="True" 
                        Rows="1">                       
                    </UniformGrid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="ItemContainerStyle">
        <Setter.Value>
            <Style TargetType="ListBoxItem">                    
                <Setter Property="Width" Value="Auto"/>
                <Setter Property="VerticalAlignment" Value="Center"/>                    
                <Setter Property="VerticalContentAlignment" Value="Top"/>                    
                <Setter Property="Height" Value="25"/>
                <Setter Property="Padding" Value="5 0 5 0"/>
                <Setter Property="Background" Value="Transparent" />

                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <Border                                   
                                Background="{TemplateBinding Background}"
                                SnapsToDevicePixels="True">
                                 <!-- Presenter for the UniformGrid: -->
                                <ContentPresenter
                                    HorizontalAlignment="Center"
                                    VerticalAlignment="Center"/>
                            </Border>
                            <ControlTemplate.Triggers>
                        <!-- triggers to indicate selection -->

                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>
</Style>

此外,在UniformGrid中无需查找列数。系统只使用ListBoxItems的数量。 我认为IsItemsHost="True"会为您完成这项工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接