【问题标题】:How to make WPF ListView horizontal with contained image stretched to fit the height?如何使 WPF ListView 水平并拉伸包含的图像以适应高度?
【发布时间】:2014-07-16 11:52:07
【问题描述】:

我想要一个画廊,以水平显示带有标签的图像ListView

每个列表项只是一个带有标签的图像:

<DataTemplate x:Key="ImageItemTemplate">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="4*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Image Grid.Row="0" Source="{Binding Image}" Stretch="UniformToFill" />
        <Label Grid.Row="1" Content="{Binding Title}" />
    </Grid>
</DataTemplate>

为了使ListView 水平,我将ListView.ItemsPanel 替换为水平StackPanel

<ListView.ItemsPanel>
    <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal" />
    </ItemsPanelTemplate>
</ListView.ItemsPanel>

现在我得到了这样的东西:

但我希望每个图像都拉伸到ListView 的全部高度(减去标签的足够高度),同时保持纵横比,所以我替换了ListView.ItemContainerStyle

<ListView.ItemContainerStyle>
    <Style TargetType="ListViewItem">
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        <Setter Property="VerticalContentAlignment" Value="Stretch" />
    </Style>
</ListView.ItemContainerStyle>

但我不知道为什么每个项目的宽度没有被拉伸而是被切割:

请帮忙,谢谢!

编辑:

整个xaml如下所示:

<UserControl x:Class="Test.ImageGalleryControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        mc:Ignorable="d">
    <UserControl.Resources>
        <DataTemplate x:Key="ImageItemTemplate">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="4*" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Image Grid.Row="0" Source="{Binding Image}" Stretch="UniformToFill" />
                <Label Grid.Row="1" Content="{Binding Title}" />
            </Grid>
        </DataTemplate>
    </UserControl.Resources>

    <Grid>
        <ListView x:Name="MyImageList" ItemTemplate="{StaticResource ImageItemTemplate}">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                    <Setter Property="VerticalContentAlignment" Value="Stretch" />
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
        </ListView>
    </Grid>
</UserControl>

【问题讨论】:

    标签: c# wpf listview


    【解决方案1】:

    试试这个

    通过将 ListView 高度设置为 Itemtemplate(网格)。

    <ListView  x:Name="MyImageList">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                <Setter Property="VerticalContentAlignment" Value="Stretch" />
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid Height="{Binding ElementName=MyImageList,Path=ActualHeight}">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="4*" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <Image Grid.Row="0" Source="Screenshot_3.png" Stretch="UniformToFill" />
                    <Label Grid.Row="1" Content="fghfgh" />
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    

    更新

    通过设置 VerticalScrollBarVisibility="Hidden" 或禁用并添加边距可以解决此问题,但正确的解决方案如下

    这个垂直滚动条的出现是由于 Listview 和 ListviewItem 默认样式中的默认边距和填充..您可以通过编辑 listview 和 listviewItem 的样式来获得所需的结果

    工作示例(没有垂直滚动条)

    资源

    <Window.Resources>
        <Style TargetType="{x:Type ListView}">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="#FFABADB3"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
            <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
            <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
            <Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
            <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
            <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListView}">
                        <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" Height="{TemplateBinding Height}" BorderThickness="0" Background="{TemplateBinding Background}" Padding="0" SnapsToDevicePixels="True">
                            <ScrollViewer Focusable="False" Padding="0" >
                                <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                            </ScrollViewer>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter Property="Background" TargetName="Bd" Value="White"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="#FFD9D9D9"/>
                            </Trigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsGrouping" Value="True"/>
                                    <Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="False"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style TargetType="{x:Type ListViewItem}">
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="Padding" Value="0"/>
            <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ItemsControl}}}"/>
            <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ItemsControl}}}"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="FocusVisualStyle">
                <Setter.Value>
                    <Style>
                        <Setter Property="Control.Template">
                            <Setter.Value>
                                <ControlTemplate>
                                    <Rectangle Margin="2" SnapsToDevicePixels="True" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListViewItem}">
                        <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1"  Background="{TemplateBinding Background}" Margin="0,-1,5,-1" SnapsToDevicePixels="True">
                            <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="#1F26A0DA"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="#A826A0DA"/>
                            </MultiTrigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Selector.IsSelectionActive" Value="False"/>
                                    <Condition Property="IsSelected" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="#3DDADADA"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="#FFDADADA"/>
                            </MultiTrigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Selector.IsSelectionActive" Value="True"/>
                                    <Condition Property="IsSelected" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="#3D26A0DA"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="#FF26A0DA"/>
                            </MultiTrigger>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter Property="TextElement.Foreground" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    

    窗口

    <ListView  x:Name="MyImageList">
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
        <Grid Height="{Binding ElementName=MyImageList,Path=ActualHeight}">
            <Grid.RowDefinitions>
                <RowDefinition Height="4*" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Image Grid.Row="0" Source="Screenshot_3.png" Stretch="UniformToFill" />
            <Label Grid.Row="1" Content="fghfgh"/>
        </Grid>
        <Grid  Height="{Binding ElementName=MyImageList,Path=ActualHeight}">
            <Grid.RowDefinitions>
                <RowDefinition Height="4*" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Image Grid.Row="0" Source="Screenshot_3.png" Stretch="UniformToFill" />
            <Label Grid.Row="1" Content="fghfgh"/>
        </Grid>
    </ListView>
    

    【讨论】:

    • 这个答案很好,除了一个额外的垂直滚动条出现。我猜这是因为将 Grid.Height 设置为 MyImageList.ActualHeight 不会为水平滚动条留下垂直空间。一种解决方法是从 ActualHeight 中减去一些下降,但我们无法判断多少是合适的。
    • 我添加了一个绑定到 ActialHeight 的转换器,默认情况下减去 15 个像素...这为我解决了垂直滚动条问题。
    【解决方案2】:

    现在尝试更改拉伸属性。嗯,怎么加不了代码……

    尝试将 Stretch="Uniform" 设置为图像

    <Image Grid.Row="0" Source="{Binding Image}" Stretch="Uniform" />
    

    【讨论】:

    • 我试过了,但现在它就像问题中的第一张图片。
    • 请显示整个 ListView XAML,因为我已经创建了 CustomControl(未编辑的项目样式)并且一切正常
    【解决方案3】:
    <Image Grid.Row="0" Source="{Binding Image}" Stretch="Fill" />
    

    但是,它不会保持图像的纵横比,使用 Stretch="Uniform" 来保持纵横比,而不管图像控件的大小。 您可以静态指定图像控件的高度,并使用 Stretch="Uniform" 来调整图像控件的纵横比和大小。

    【讨论】:

    • 但这不是问题的答案。看起来他想创建类似图片库的东西,没有项目宽度限制
    【解决方案4】:

    使用 ItemsControl 的简单解决方案

    <Grid>
        <Grid.Resources>
            <DataTemplate x:Key="ImageItemTemplate">
                <Grid Height="{Binding ActualHeight,RelativeSource={RelativeSource FindAncestor,AncestorType=ItemsControl}}"
                      Margin="2,2,2,-25"
                      VerticalAlignment="Top">
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition Height="auto" />
                    </Grid.RowDefinitions>
                    <Image Grid.Row="0" Source="{Binding Image}" Stretch="UniformToFill" />
                    <Label Grid.Row="1" Content="{Binding Title}" />
                </Grid>
            </DataTemplate>
        </Grid.Resources>
        <ScrollViewer HorizontalScrollBarVisibility="Auto"
                      VerticalScrollBarVisibility="Hidden">
            <ItemsControl x:Name="MyImageList"
                          ItemTemplate="{StaticResource ImageItemTemplate}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </ScrollViewer>
    </Grid>
    

    【讨论】:

      【解决方案5】:

      @pushpraj 的“使用 ItemsControl 的简单解决方案”在长时间搜索类似功能后确实帮助了我。我是 WPF 新手,但仍然尝试使用 ListView 和带有 ItemsControl 模板的 Ribbon,但没有得到我想要的结果。为了满足我的要求,我做了一个小改动,我将图像拉伸为均匀,Stretch="Uniform"。谢谢你的博客。

      【讨论】:

        猜你喜欢
        • 2013-05-06
        • 1970-01-01
        • 2023-04-09
        • 1970-01-01
        • 1970-01-01
        • 2013-08-22
        • 1970-01-01
        • 2011-05-04
        • 1970-01-01
        相关资源
        最近更新 更多