在网格中显示图像

时间:2013-10-10 09:12:17

标签: wpf image data-binding listbox wrappanel

我有一个BitmapSources的ObservableCollection,我想在网格中显示它们并覆盖选定和未选择的样式。我一直在寻找很多不同的方法来做到这一点,但没有设法让它让我满意。我的最新尝试看起来像这样:

<ListBox ItemsSource={Binding Images}>
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel ItemsHost="True">
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="Black" BorderThickness="3">
                <Image Source={Binding}>
            </Border>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

这确实显示了图像,但WrapPanel总是只有一行...我不想要水平滚动,所以我希望它能单独进行换行或者能够告诉它它应该每行只有3个项目或类似的东西。没有WrapPanel,图像各占一行。另外,我真的不明白如何覆盖所选项目的样式,因为DataTemplate的DataType现在是BitmapSource,而不是ListBoxItem ......

我也尝试过一个类似结果的DataGrid(看起来更合适)。

我该怎么做?

3 个答案:

答案 0 :(得分:2)

UniformGrid定义为ItemsPanel,并将Columns值设置为您希望每行的项目数。

          <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Columns="3"/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>

您的样式将覆盖默认选择背景和边框画笔设置:

           <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Style.Resources>
                        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
                         Color="Transparent"/>
                    </Style.Resources>
                    <Setter Property="BorderThickness" Value="0.5"/>
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="BorderBrush" Value="blue"/>
                        </Trigger>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="BorderBrush" Value="Red"/>
                        </Trigger>
                    </Style.Triggers>

                </Style>

            </ListBox.ItemContainerStyle>

答案 1 :(得分:1)

CNC中
关于此答案中列表框宽度的部分不正确,请参阅clemens答案

- 原始后期 - 您需要通过设置宽度或使用其他一些父布局来限制列表框的宽度。否则,包装面板将声明所有可用宽度,以便将所有内容放在一行上。在使用滚动窗格时,例如

,这种情况很常见

一个提示是为元素设置不同的背景颜色,以查看实际抓住空间的人

您可以通过设置ItemsContainerStyle

来更改所选样式

答案 2 :(得分:1)

您可以简单地禁用水平滚动。这将使WrapPanel包裹它的孩子。

<ListBox ItemsSource="{Binding Images}"
         ScrollViewer.HorizontalScrollBarVisibility="Disabled">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="Black" BorderThickness="3">
                <Image Stretch="None" Source="{Binding}"/>
            </Border>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>