Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid UserControl to catch mouse wheel scrolling

We have a UserControl showing all possible values of an enum represented as RadioButton in a ListBox to choose one of them. When this control is inside a ScrollViewer with other controls like textboxes or whatever and you try to scroll by mouse wheel it won't scroll the form's ScrollViewer when the mouse cursor is over the EnumBox.

This is how it looks like in an UI:

EnumBox in UI

For demonstration the RadioButtons have yellow background, the WrapPanel's background is green. When the mouse cursor is within the colored area (say within the WrapPanel) scrolling by mouse wheel has no effect.

The Template for the EnumBox looks like this:

  <UserControl.Template>
    <ControlTemplate TargetType="{x:Type clientsWpf:EnumBox}">
      <StackPanel>
        <GroupBox Header="{Binding Header, RelativeSource={RelativeSource AncestorType={x:Type clientsWpf:EnumBox}}}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource AncestorType={x:Type clientsWpf:EnumBox}}}">
          <Border x:Name="InvalidBorder"  BorderBrush="Red" BorderThickness="0" >
            <ListBox x:Name="PART_ListBox" HorizontalAlignment="Left" KeyboardNavigation.DirectionalNavigation="Cycle" Background="Transparent" BorderThickness="0" SelectedValuePath="." SelectedValue="{Binding Path=SelectedValue, RelativeSource={RelativeSource AncestorType={x:Type clientsWpf:EnumBox}}}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
              <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                  <WrapPanel Orientation="Horizontal" Background="Green"/>
                </ItemsPanelTemplate>
              </ListBox.ItemsPanel>
              <ListBox.Resources>
                <Style x:Key="{x:Type ListBoxItem}" TargetType="{x:Type ListBoxItem}" >
                  <Setter Property="Template">
                    <Setter.Value>
                      <ControlTemplate>
                        <Border Background="Transparent" Background="Yellow">
                          <RadioButton Margin="3" Focusable="False" Content="{TemplateBinding ContentControl.Content,Converter={StaticResource enumValueDescriptionConverter}}" 
                                     IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}},Path=IsSelected}" />
                        </Border>
                      </ControlTemplate>
                    </Setter.Value>
                  </Setter>
                </Style>
              </ListBox.Resources>
            </ListBox>
          </Border>
        </GroupBox>
      </StackPanel>
    </ControlTemplate>
  </UserControl.Template>

I tried to set ScrollViewer.VerticalScrollBarVisibility="Disabled" and ScrollViewer.CanContentScroll="False" on the ListBox, WrapPanel, RadioButton and its Border with no effect.

I tried to catch the ScrollBar.Scroll="WrapPanel_Scroll" event on all four controls but none of them got hit.

I tried to set SelectiveScrollingGrid.SelectiveScrollingOrientation="None" on the RadioButton with no effect.

Does anyone have a clue on what prevents the scrolling in the UI?

To make it clear: It is not about scrolling within the EnumBox but to scroll the whole form.

like image 697
gumo Avatar asked Dec 12 '25 16:12

gumo


1 Answers

The problem is the ListBox has its own ScrollViewer. Copy the template for the ListBox and remove the embedded ScrollViewer.

Here's a complete example with the embedded ScrollViewer commented out:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <SolidColorBrush x:Key="ListBorder" Color="#828790"/>
        <Style x:Key="ListBoxStyleNoScrollViewer" TargetType="{x:Type ListBox}">
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
            <Setter Property="BorderBrush" Value="{StaticResource ListBorder}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
            <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
            <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
            <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
            <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
            <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBox}">
                        <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="1" SnapsToDevicePixels="true">
                            <!--<ScrollViewer Focusable="false" Padding="{TemplateBinding Padding}">-->
                                <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                            <!--</ScrollViewer>-->
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                            </Trigger>
                            <Trigger Property="IsGrouping" Value="true">
                                <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <ScrollViewer>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="200"/>
                <RowDefinition Height="100"/>
                <RowDefinition Height="200"/>
            </Grid.RowDefinitions>

            <ListBox Grid.Row="1" Style="{StaticResource ListBoxStyleNoScrollViewer}" >
                <ListBox.Items>
                    <ListBoxItem>One</ListBoxItem>
                    <ListBoxItem>Two</ListBoxItem>
                    <ListBoxItem>Three</ListBoxItem>
                    <ListBoxItem>Four</ListBoxItem>
                </ListBox.Items>
            </ListBox>
        </Grid>
    </ScrollViewer>
</Window>

If the list box has Style="{StaticResource ListBoxStyleNoScrollViewer}" then the scroll wheel works when over the list box. If not then the sample exhibits the problem you mention.

like image 140
Phil Avatar answered Dec 15 '25 06:12

Phil