Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Child elements of scrollviewer preventing scrolling with mouse wheel?

I'm having a problem getting mouse wheel scrolling to work in the following XAML, which I have simplified for clarity:

<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" CanContentScroll="False" >     <Grid     MouseDown="Editor_MouseDown"     MouseUp="Editor_MouseUp"     MouseMove="Editor_MouseMove"     Focusable="False"     >         <Grid.Resources>             <DataTemplate             DataType="{x:Type local:DataFieldModel}"             >                 <Grid                 Margin="0,2,2,2"                 >                     <TextBox                     Cursor="IBeam"                     MouseDown="TextBox_MouseDown"                     MouseUp="TextBox_MouseUp"                     MouseMove="TextBox_MouseMove"                     />                 </Grid>             </DataTemplate>         </Grid.Resources>         <ListBox         x:Name="DataFieldListBox"         ItemsSource="{Binding GetDataFields}"         SelectionMode="Extended"         Background="Transparent"         Focusable="False"         >             <ListBox.ItemsPanel>                 <ItemsPanelTemplate>                     <Canvas />                 </ItemsPanelTemplate>             </ListBox.ItemsPanel>             <ListBox.ItemContainerStyle>                 <Style                 TargetType="ListBoxItem"                 >                     <Setter                     Property="Canvas.Left"                     Value="{Binding dfX}"                     />                     <Setter                     Property="Canvas.Top"                     Value="{Binding dfY}"                     />                 </Style>             </ListBox.ItemContainerStyle>         </ListBox>     </Grid> </ScrollViewer> 

Visually, the result is an area of some known size where DataFields read from a collection can be represented with TextBoxes which have arbitrary position, size, et cetera. In cases where the ListBox's styled "area" is too large to display all at once, horizontal and vertical scrolling is possible, but only with the scroll bars.

For better ergonomics and sanity, mouse wheel scrolling should be possible, and normally ScrollViewer would handle it automatically, but the ListBox appears to be handing those events such that the parent ScrollViewer never sees them. So far I have only been able to get wheel scrolling working be setting IsHitTestVisible=False for either the ListBox or the parent Grid, but of course none of the child element's mouse events work after that.

What can I do to ensure the ScrollViewer sees mouse wheel events while preserving others for child elements?

Edit: I just learned that ListBox has a built-in ScrollViewer which is probably stealing wheel events from the parent ScrollViewer and that specifying a control template can disable it. I'll update this question if that resolves the problem.

like image 978
Tom Avatar asked Jan 15 '13 22:01

Tom


People also ask

Which device used for scrolling?

A scroll wheel is a wheel used for scrolling. The term usually refers to such wheels found on computer mice (where they can also be called a mouse wheel).

Which part of mouse helps in scrolling?

The scroll wheel that is located in the middle of the mouse is used to scroll up and down on any page without using the vertical scroll bar on the right hand side of a document or webpage. The scroll wheel can also be used as a third button on the mouse.

How do you lock a scroll wheel?

Navigate to HKEY_CURRENT_USER\Control Panel\Desktop and set WheelScrollChars and WheelScrollLines to 0. A reboot is necessary for this to take affect. This will disable scrolling, not the button itself. PS: If you open the Mouse setting in the Control Panel, it will reset those settings back to 3.

What is a ScrollViewer c#?

The ScrollViewer control encapsulates horizontal and vertical ScrollBar elements and a content container (such as a Panel element) in order to display other visible elements in a scrollable area. You must build a custom object in order to use the ScrollBar element for content scrolling.


1 Answers

You can also create a behavior and attach it to the parent control (in which the scroll events should bubble through).

// Used on sub-controls of an expander to bubble the mouse wheel scroll event up  public sealed class BubbleScrollEvent : Behavior<UIElement> {     protected override void OnAttached()     {         base.OnAttached();         AssociatedObject.PreviewMouseWheel += AssociatedObject_PreviewMouseWheel;     }      protected override void OnDetaching()     {         AssociatedObject.PreviewMouseWheel -= AssociatedObject_PreviewMouseWheel;         base.OnDetaching();     }      void AssociatedObject_PreviewMouseWheel(object sender, MouseWheelEventArgs e)     {         e.Handled = true;         var e2 = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);         e2.RoutedEvent = UIElement.MouseWheelEvent;         AssociatedObject.RaiseEvent(e2);     } }  <SomePanel>             <i:Interaction.Behaviors>                 <viewsCommon:BubbleScrollEvent />             </i:Interaction.Behaviors> </SomePanel> 
like image 91
JoeB Avatar answered Oct 22 '22 00:10

JoeB