0
votes

To reproduce this, simply add this style to any wpf project that has a RichTextBox:

https://pastebin.com/dJAqFC3d

And a full minimal project can be located here: https://drive.google.com/file/d/1a7e-vwKpt1Emg7fhMhVRLccwrjOlhWk1/view?usp=sharing

Also an example of the two styles:

<!--

    This style does NOT break RichTextBox Scrolling

-->

<Style TargetType="{x:Type ScrollViewer}">
    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
    </Style.Resources>
</Style>


<!--

    The Style below breaks Rich Text Box

-->

<!--<Style TargetType="{x:Type ScrollViewer}">
    <Setter Property="CanContentScroll" Value="True"></Setter>
    <Setter Property="PanningMode" Value="Both"></Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ScrollViewer}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <ScrollContentPresenter Grid.Column="0" />
                    <ScrollBar
                        x:Name="PART_VerticalScrollBar"
                        Grid.Row="0"
                        Grid.Column="1"
                        Maximum="{TemplateBinding ScrollableHeight}"
                        ViewportSize="{TemplateBinding ViewportHeight}"
                        Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
                        Value="{TemplateBinding VerticalOffset}" />
                    <ScrollBar
                        x:Name="PART_HorizontalScrollBar"
                        Grid.Row="1"
                        Grid.Column="0"
                        Maximum="{TemplateBinding ScrollableWidth}"
                        Orientation="Horizontal"
                        ViewportSize="{TemplateBinding ViewportWidth}"
                        Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
                        Value="{TemplateBinding HorizontalOffset}" />
                    --><!--<Rectangle Grid.Row="1" Grid.Column="1" Fill="Red"/>--><!--
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>-->

Then at the bottom of the style, comment out either of the ScrollViewer styles to swap between them. One simply overrides the bottom right rectangle color. The other does the same, but also defines the scrollbars. The style that defines the scrollbars breaks vertical scrolling.

This can also be reproduced using the official Microsoft provided styles, located here:

https://docs.microsoft.com/en-us/dotnet/desktop/wpf/controls/scrollbar-styles-and-templates?view=netframeworkdesktop-4.8

and here

https://docs.microsoft.com/en-us/dotnet/desktop/wpf/controls/scrollviewer-styles-and-templates?view=netframeworkdesktop-4.8

UPDATE: (The above links will soon be an invalid example, because this issue has been submitted, and it is apparently going to be addressed and fixed)

Does anyone know why declaring a custom style for ScrollViewers breaks RichTextBox mouse wheel scrolling?

Edit: It should also be noted that the above example does not hinder or break the vertical mouse wheel scrolling of any other control (that I've noticed). RichTextBox seems to be an edge case.

1

1 Answers

0
votes

Found the solution, and it's actually stupid easy.

You have to add CanContentScroll="True" to the ScrollContentPresenter within the ScrollViewer control template. Here is an example:

<Style TargetType="{x:Type ScrollViewer}">
        <Setter Property="CanContentScroll" Value="True"></Setter>
        <Setter Property="PanningMode" Value="Both"></Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ScrollViewer}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <ScrollContentPresenter CanContentScroll="True" Grid.Column="0" />
                        <ScrollBar
                            x:Name="PART_VerticalScrollBar"
                            Grid.Row="0"
                            Grid.Column="1"
                            Maximum="{TemplateBinding ScrollableHeight}"
                            ViewportSize="{TemplateBinding ViewportHeight}"
                            Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
                            Value="{TemplateBinding VerticalOffset}" />
                        <ScrollBar
                            x:Name="PART_HorizontalScrollBar"
                            Grid.Row="1"
                            Grid.Column="0"
                            Maximum="{TemplateBinding ScrollableWidth}"
                            Orientation="Horizontal"
                            ViewportSize="{TemplateBinding ViewportWidth}"
                            Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
                            Value="{TemplateBinding HorizontalOffset}" />
                        <Rectangle Grid.Row="1" Grid.Column="1" Fill="Red"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

This is not mentioned anywhere within the microsoft style example, and they also ommit it from their suggested style template.