ItemsControl设置WrapPanel作为ItemsPanel时如何为条目添加不重叠边框
解决方案
导致边框重叠的核心原因是相邻条目的相邻边框各自为1px,叠加后总厚度变成2px,你可以用以下几种更稳定的方案实现目标:
方案1:负Margin + 外层边框补边(最推荐,无性能损耗,适配WrapPanel自动换行逻辑)
这个方案的逻辑是让所有条目只保留右下边框,通过负Margin让相邻边框重叠,再在外层补充左上整体边框,最终所有位置的边框厚度都为1px:
修改后的代码如下:
<!-- 外层补左上边框 --> <Border BorderBrush="Green" BorderThickness="1 1 0 0"> <ItemsControl ItemsSource="{Binding}" SnapsToDevicePixels="True" UseLayoutRounding="True"> <ItemsControl.ItemTemplate> <DataTemplate> <!-- 仅保留右下边框,负Margin让相邻边框重叠 --> <Border x:Name="myBorder" BorderBrush="Green" BorderThickness="0 0 1 1" Margin="0 0 -1 -1"> <StackPanel Margin="10" Orientation="Horizontal"> <TextBlock Width="20" Text="{Binding Name}"/> <TextBox Width="100" Text="{Binding Value}"/> </StackPanel> </Border> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Vertical"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </Border>
同时给控件加上SnapsToDevicePixels和UseLayoutRounding属性,避免WPF子像素渲染导致的边框发虚、厚度异常问题。
方案2:自定义条目容器逻辑
如果需要避免在外层套边框,可以给ItemsControl.ItemContainerStyle添加样式,配合转换器判断当前条目是否为第一行/第一列,仅给非首列条目设置左Margin为-1、非首行条目设置上Margin为-1,也能实现同样效果,缺点是需要额外写转换器适配WrapPanel的布局逻辑。
效果示例
原重叠效果

调整后正常效果

内容的提问来源于stack exchange,提问作者Vincent
相关产品推荐
相关产品推荐

