WPF ListView行扩展需求:将最后一列内容移至对应行下方显示
几种替代模板选择器的实现方案
嘿,这个需求其实有几种更直接的实现方式,不用非得搞模板选择器,我给你分享几个实用的思路:
方案一:让图片列表在单元格内自动换行(改动最小)
你现在的问题是最后一列的ListBox用了横向StackPanel,导致内容过长溢出。最简单的办法就是把横向布局改成自动换行的WrapPanel,这样图片多了就会在单元格内换行,ListView的行高会自动适配内容高度。
只需要修改最后一列的ItemsPanelTemplate:
<GridViewColumn Width="Auto" Header="Rotation" > <GridViewColumn.CellTemplate> <DataTemplate> <!-- 换成ItemsControl更轻量,不需要选择功能的话更合适 --> <ItemsControl ItemsSource="{Binding Images}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <!-- 把StackPanel换成WrapPanel,自动换行 --> <WrapPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemContainerStyle> <Style TargetType="ContentPresenter"> <Setter Property="Margin" Value="0 0 2 0"/> <!-- 给图片加个小间距 --> </Style> </ItemsControl.ItemContainerStyle> <ItemsControl.ItemTemplate> <DataTemplate DataType="CraftingActionContainer"> <Grid Height="25"> <Image Width="25" Height="25" Source ="{Binding BitmapSource}" VerticalAlignment="Top" /> </Grid> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn>
这里把ListBox换成了ItemsControl,因为不需要列表项的选择功能,ItemsControl更轻量。WrapPanel会自动把超出宽度的图片换到下一行,对应的ListView行也会自动增高,刚好把所有图片都显示出来。
方案二:自定义ListView行模板,让图片列表单独占一行
如果希望图片列表完全占据整行的宽度(而不是局限在最后一列),可以放弃GridView的默认行结构,自定义ListView的ItemTemplate,把行分成上下两部分:上半部分显示原来的各项属性,下半部分显示图片列表。
示例代码:
<ListView x:Name="ListViewRotations" FontFamily="Consolas" MouseDoubleClick="ListViewRotations_MouseDoubleClick"> <ListView.ContextMenu> <ContextMenu> <MenuItem Header="Remove" Click="ContextMenuItemRemoveClicked" /> </ContextMenu> </ListView.ContextMenu> <!-- 自定义ItemTemplate,替换原来的GridView --> <ListView.ItemTemplate> <DataTemplate> <Border BorderThickness="0 0 0 1" BorderBrush="#EEEEEE"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <!-- 第一行:显示各项属性,用Grid模拟列 --> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="120"/> <ColumnDefinition Width="120"/> <ColumnDefinition Width="80"/> <ColumnDefinition Width="50"/> <ColumnDefinition Width="130"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBlock Grid.Column="0" Text="Max Craftsmanship:" FontWeight="Bold"/> <TextBlock Grid.Column="0" Margin="100 0 0 0" Text="{Binding RotationInfo.MaxCraftsmanship}"/> <TextBlock Grid.Column="1" Text="Min Craftsmanship:" FontWeight="Bold"/> <TextBlock Grid.Column="1" Margin="100 0 0 0" Text="{Binding RotationInfo.MinCraftsmanship}"/> <TextBlock Grid.Column="2" Text="Min Control:" FontWeight="Bold"/> <TextBlock Grid.Column="2" Margin="60 0 0 0" Text="{Binding RotationInfo.MinControl}"/> <TextBlock Grid.Column="3" Text="CP:" FontWeight="Bold"/> <TextBlock Grid.Column="3" Margin="30 0 0 0" Text="{Binding RotationInfo.CP}"/> <TextBlock Grid.Column="4" Text="Score:" FontWeight="Bold"/> <TextBlock Grid.Column="4" Margin="90 0 0 0" Text="{Binding RotationInfo.Score}"/> <TextBlock Grid.Column="5" Text="Rotation Time:" FontWeight="Bold"/> <TextBlock Grid.Column="5" Margin="110 0 0 0" Text="{Binding RotationInfo.RotationTime}"/> </Grid> <!-- 第二行:图片列表,跨所有列 --> <ItemsControl Grid.Row="1" ItemsSource="{Binding Images}" Margin="0 5 0 5"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate DataType="CraftingActionContainer"> <Image Width="25" Height="25" Source="{Binding BitmapSource}" Margin="0 0 2 0"/> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </Grid> </Border> </DataTemplate> </ListView.ItemTemplate> </ListView>
这个方案的好处是图片列表可以利用整行宽度,显示更舒展,布局结构也更清晰;缺点是需要手动模拟原来的GridView列布局,不能直接用GridView的列宽调整功能了。
方案三:用Expander实现折叠/展开(节省空间)
如果不想让ListView的行太高,可以把图片列表放在Expander里,默认展开(或者默认折叠,用户点击展开查看),这样平时行高正常,需要看完整序列时再展开。
示例代码(基于原来的GridView修改):
<GridViewColumn Width="Auto" Header="Rotation" > <GridViewColumn.CellTemplate> <DataTemplate> <Expander IsExpanded="True" Header="View Rotation"> <ItemsControl ItemsSource="{Binding Images}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate DataType="CraftingActionContainer"> <Image Width="25" Height="25" Source="{Binding BitmapSource}" Margin="0 0 2 0"/> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </Expander> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn>
这个方案适合图片列表很长的场景,既节省了默认的行高,又能完整展示内容,交互性也不错。
内容的提问来源于stack exchange,提问作者Igie
相关产品推荐
相关产品推荐

