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>

 

运行效果如下:

WPF 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