首页 > 解决方案 > 如何更好地在 WPF 中对图像列表框进行样式化?

问题描述

我已经将一个 List 从我的代码隐藏绑定到一个 ListBox,但我很难对外观进行样式化以获得我想要的。我想一次显示最多 8 张图片,但不向下滚动就不会超过这个。当窗口调整大小时,我希望图像大小随之缩放,但仍然显示不超过 8 个。这是我当前的 XAML:

<ListBox ItemsSource="{Binding PictureImagesList}">
    <ListBox.Template>
        <ControlTemplate TargetType="ListBox">
            <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
                <ItemsPresenter/>
            </ScrollViewer>
        </ControlTemplate>
    </ListBox.Template>
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="4" HorizontalAlignment="Center" VerticalAlignment="Top" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}" >
                        <Grid Background="{TemplateBinding Background}">
                            <Border HorizontalAlignment="Center" VerticalAlignment="Center"
                        BorderBrush="{TemplateBinding BorderBrush}">
                                <ContentPresenter />
                            </Border>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="BorderBrush" Value="Yellow" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

这是此 XAML 生成的图片。如您所见,图像太大了,我们只看到第二行的上半部分。如果我弄乱了 ListBoxItem 边距,我可以让它们变小,但这并不是很理想,因为它只有在屏幕分辨率保持不变的情况下才有效。

我得到这个

标签: c#wpfxaml

解决方案


您可以使用 UniformGrid 作为 ItemsPanel 与适当的HorizontalAlignmentVerticalAlignment。还要从 DataTemplate 中删除多余的 Border 元素。

<ListBox ItemsSource="{Binding PictureImagesList}">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="4" HorizontalAlignment="Left" VerticalAlignment="Top"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Image Width="200" Height="200" Margin="5" Source="{Binding}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

更新:为了使黄色选择边框直接围绕图像,请使用如下所示的 ListBoxItem 样式。要将图像缩放到完整 ListBox 宽度的(一小部分),请添加适当的 ControlTemplate。

<ListBox ItemsSource="{Binding PictureImagesList}">
    <ListBox.Template>
        <ControlTemplate TargetType="ListBox">
            <ScrollViewer HorizontalScrollBarVisibility="Disabled"
                          VerticalScrollBarVisibility="Auto">
                <ItemsPresenter/>
            </ScrollViewer>
        </ControlTemplate>
    </ListBox.Template>
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="4" HorizontalAlignment="Left" VerticalAlignment="Top"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Background" Value="LightGray" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}" >
                        <Grid Background="{TemplateBinding Background}">
                            <Border HorizontalAlignment="Center" VerticalAlignment="Center"
                                    BorderThickness="5"
                                    BorderBrush="{TemplateBinding BorderBrush}">
                                <ContentPresenter />
                            </Border>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="BorderBrush" Value="Yellow" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

推荐阅读