WPF ListBox水平显示并支持滚动
ItemsPanel属性
在WPF中,ListBox提供了一个ItemPanel属性,它可以指定用于控制元素呈现的模板。
对于ListBox,默认使用的是VirtualizingStackPanel.
水平显示
我们可以使用ItemsPanel属性来自定义元素显示所使用的面板,继续使用VirtualizingStackPanel,但是将方向控制为水平,并启用水平滚动条,禁用垂直滚动条。
1 <ListBox ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled" > 3 <ListBox.ItemsPanel> 4 <ItemsPanelTemplate> 5 <VirtualizingStackPanel Orientation="Horizontal" IsItemsHost="True" /> 6 </ItemsPanelTemplate> 7 </ListBox.ItemsPanel> 8 9 <ListBoxItem> 10 2343243242 11 </ListBoxItem> 12 <ListBoxItem> 13 2343243242 14 </ListBoxItem> 15 <ListBoxItem> 16 2343243242 17 </ListBoxItem> 18 <ListBoxItem> 19 2343243242 20 </ListBoxItem> 21 </ListBox>
运行效果如下:

支持滚动
我们可以处理PreviewMouseWheel事件,在事件中,对滚轮的方向和偏移量进行判断,并手动控制滚动
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled" PreviewMouseWheel="list_PreviewMouseWheel" >
事件处理函数
1 private void list_PreviewMouseWheel(object sender, MouseWheelEventArgs e) 2 { 3 if (sender is ListBox listBox) 4 { 5 var scrollViewer = TreeHelper.FindVisualChild<ScrollViewer>(listBox); 6 if (scrollViewer != null) 7 { 8 scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset - e.Delta); 9 e.Handled = true; 10 } 11 } 12 }
这里我们需要查找子元素ScrollViewer,使用了VisualTreeHelper类提供的功能,封装了一个FindVisualChild函数,代码如下
TreeHelper.cs
1 public class TreeHelper 2 { 3 public static T FindVisualChild<T>(DependencyObject dependencyObject) where T : DependencyObject 4 { 5 var childrenCount = VisualTreeHelper.GetChildrenCount(dependencyObject); 6 for (int i = 0; i < childrenCount; i++) 7 { 8 DependencyObject child = VisualTreeHelper.GetChild(dependencyObject, i); 9 if (child is T t) 10 { 11 return t; 12 } 13 else 14 { 15 T childOfChild = FindVisualChild<T>(child); 16 if (childOfChild != null) 17 return childOfChild; 18 } 19 } 20 return null; 21 } 22 }

浙公网安备 33010602011771号