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 TreeHelper2 {3 public static T FindVisualChild<T>(DependencyObject dependencyObject) where T : DependencyObject4 {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 }
参考资料:
https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.itemscontrol.itemspanel?view=windowsdesktop-9.0