diff --git a/src/PerfView/EventViewer/EventWindow.xaml b/src/PerfView/EventViewer/EventWindow.xaml index 600d963f8..74526fd49 100644 --- a/src/PerfView/EventViewer/EventWindow.xaml +++ b/src/PerfView/EventViewer/EventWindow.xaml @@ -249,6 +249,7 @@ ToolTip="Click on Update button to update." SelectionMode="Extended" SelectionUnit="CellOrRowHeader" SelectedCellsChanged="SelectedCellsChanged" + PreviewMouseWheel="Grid_PreviewMouseWheel" AlternatingRowBackground="{DynamicResource AlternateRowBackground}" AutomationProperties.Name="Events Table" ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}"> diff --git a/src/PerfView/EventViewer/EventWindow.xaml.cs b/src/PerfView/EventViewer/EventWindow.xaml.cs index eb75b16ec..d75ff1a86 100644 --- a/src/PerfView/EventViewer/EventWindow.xaml.cs +++ b/src/PerfView/EventViewer/EventWindow.xaml.cs @@ -1915,6 +1915,7 @@ private void Add(ObservableCollection events, EventRecord event_) private List m_userDefinedColumns; private float[] m_buckets; // Keep track of the counts of events. private double m_bucketTimeMSec; // Size for each bucket + private ScrollViewer m_gridScrollViewer; // Cached ScrollViewer for horizontal scrolling #endregion private void DoUseLocalTime(object sender, RoutedEventArgs e) @@ -2001,5 +2002,46 @@ private void DoHideTimeStampColumns(object sender, RoutedEventArgs e) // Save preference App.UserConfigData["EventWindowShowTimeStampColumns"] = "false"; } + + /// + /// When Shift is held, redirect mouse wheel events to horizontal scrolling. + /// + private void Grid_PreviewMouseWheel(object sender, MouseWheelEventArgs e) + { + if (Keyboard.Modifiers == ModifierKeys.Shift) + { + // Cache the ScrollViewer on first use + if (m_gridScrollViewer == null) + { + m_gridScrollViewer = FindVisualChild((DependencyObject)sender); + if (m_gridScrollViewer == null) + { + return; + } + } + + m_gridScrollViewer.ScrollToHorizontalOffset(m_gridScrollViewer.HorizontalOffset - e.Delta); + e.Handled = true; + } + } + + private static T FindVisualChild(DependencyObject parent) where T : DependencyObject + { + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) + { + DependencyObject child = VisualTreeHelper.GetChild(parent, i); + if (child is T found) + { + return found; + } + + T result = FindVisualChild(child); + if (result != null) + { + return result; + } + } + return null; + } } }