Создание полосы прокрутки ScrollViewer всегда видимой с помощью переопределения или стиля

Я пытаюсь сделать ScrollBar для ScrollViewer всегда видимым, чтобы он не появлялся только тогда, когда я пытаюсь прокрутить текстовое представление, и чтобы пользователь знал, что есть что-то еще, что можно увидеть. Сначала по какой-то причине я думал, что мне просто нужно изменить цвет, который требует переопределения кисти, но на самом деле полоса прокрутки исчезает и исчезает, поэтому необходимо изменить шаблон ScrollViewer или ScrollBar.

Я нашел шаблон ScrollViewer, который я только что поместил в раздел App.Resources, но я не знаю, как его редактировать, поэтому ScrollBar все время виден:

<Style TargetType="ScrollViewer">
    <Setter Property="HorizontalScrollMode" Value="Enabled" />
    <Setter Property="VerticalScrollMode" Value="Enabled" />
    <Setter Property="IsHorizontalRailEnabled" Value="True" />
    <Setter Property="IsVerticalRailEnabled" Value="True" />
    <Setter Property="IsTabStop" Value="False" />
    <Setter Property="ZoomMode" Value="Enabled" />
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
    <Setter Property="VerticalContentAlignment" Value="Top"/>
    <Setter Property="VerticalScrollBarVisibility" Value="Visible"/>
    <Setter Property="Padding" Value="0"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ScrollViewer">
                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="ScrollingIndicatorStates">
                            <VisualStateGroup.Transitions>
                                <VisualTransition From="MouseIndicator" To="NoIndicator">
                                    <Storyboard>
                                        <FadeOutThemeAnimation TargetName="ScrollBarSeparator" BeginTime="0:0:3" />
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="VerticalScrollBar"
                                                                   Storyboard.TargetProperty="IndicatorMode">
                                            <DiscreteObjectKeyFrame KeyTime="0:0:3">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <ScrollingIndicatorMode>None</ScrollingIndicatorMode>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalScrollBar"
                                                                   Storyboard.TargetProperty="IndicatorMode">
                                            <DiscreteObjectKeyFrame KeyTime="0:0:3">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <ScrollingIndicatorMode>None</ScrollingIndicatorMode>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualTransition>
                                <VisualTransition From="TouchIndicator" To="NoIndicator">
                                    <Storyboard>
                                        <FadeOutThemeAnimation TargetName="ScrollBarSeparator" />
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="VerticalScrollBar"
                                                                   Storyboard.TargetProperty="IndicatorMode">
                                            <DiscreteObjectKeyFrame KeyTime="0:0:0.5">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <ScrollingIndicatorMode>None</ScrollingIndicatorMode>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalScrollBar"
                                                                   Storyboard.TargetProperty="IndicatorMode">
                                            <DiscreteObjectKeyFrame KeyTime="0:0:0.5">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <ScrollingIndicatorMode>None</ScrollingIndicatorMode>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualTransition>
                            </VisualStateGroup.Transitions>

                            <VisualState x:Name="NoIndicator">
                                <Storyboard>
                                    <FadeOutThemeAnimation TargetName="ScrollBarSeparator" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="TouchIndicator">
                                <Storyboard>
                                                                            <FadeInThemeAnimation TargetName="ScrollBarSeparator" />

                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="VerticalScrollBar"
                                                               Storyboard.TargetProperty="IndicatorMode"
                                                               Duration="0">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <ScrollingIndicatorMode>TouchIndicator</ScrollingIndicatorMode>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalScrollBar"
                                                               Storyboard.TargetProperty="IndicatorMode"
                                                               Duration="0">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <ScrollingIndicatorMode>TouchIndicator</ScrollingIndicatorMode>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="MouseIndicator">
                                <Storyboard>
                                    <FadeInThemeAnimation TargetName="ScrollBarSeparator" />
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="VerticalScrollBar"
                                                               Storyboard.TargetProperty="IndicatorMode"
                                                               Duration="0">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <ScrollingIndicatorMode>MouseIndicator</ScrollingIndicatorMode>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalScrollBar"
                                                               Storyboard.TargetProperty="IndicatorMode"
                                                               Duration="0">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <ScrollingIndicatorMode>MouseIndicator</ScrollingIndicatorMode>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Grid Background="{TemplateBinding Background}">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <ScrollContentPresenter x:Name="ScrollContentPresenter"
                                            Grid.RowSpan="2"
                                            Grid.ColumnSpan="2"
                                            ContentTemplate="{TemplateBinding ContentTemplate}"
                                            Margin="{TemplateBinding Padding}" />
                        <ScrollBar x:Name="VerticalScrollBar"
                               Grid.Column="1"
                               IsTabStop="False"
                               Maximum="{TemplateBinding ScrollableHeight}"
                               Orientation="Vertical"
                               Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
                               Value="{TemplateBinding VerticalOffset}"
                               ViewportSize="{TemplateBinding ViewportHeight}"
                               HorizontalAlignment="Right"/>
                        <ScrollBar x:Name="HorizontalScrollBar"
                               IsTabStop="False"
                               Maximum="{TemplateBinding ScrollableWidth}"
                               Orientation="Horizontal"
                               Grid.Row="1"
                               Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
                               Value="{TemplateBinding HorizontalOffset}"
                               ViewportSize="{TemplateBinding ViewportWidth}" />
                        <!-- Change the opacity below, to zero. otherwise, the right and bottom border end up showing up as a single pixel lit on the screen even if the scroll is disabled. -->
                        <Border x:Name="ScrollBarSeparator"
                            Grid.Row="1"
                            Grid.Column="1"
                            Opacity="0"
                            BorderThickness="0,0,1,1"
                            Background="{StaticResource ScrollBarTrackBackgroundThemeBrush}"
                            BorderBrush="{StaticResource ScrollBarTrackBorderThemeBrush}" />
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Я пробовал удалять разные части кода, но в результате полоса прокрутки просто исчезла.

Я хочу, чтобы полоса прокрутки появлялась постоянно, а не исчезала вот так.


person Druvis Cukurs    schedule 31.07.2014    source источник
comment
Пожалуйста, добавьте снимок для вашего вопроса.   -  person Heena Patil    schedule 31.07.2014
comment
Как и просили, я добавил изображение.   -  person Druvis Cukurs    schedule 31.07.2014


Ответы (2)


Для достижения ожидаемого результата вам необходимо изменить стиль полосы прокрутки, так как средство просмотра прокрутки состоит из полосы прокрутки.

Рабочая полоса прокрутки

 <x:Double x:Key="ScrollBarMinThemeWidth">7</x:Double>
    <x:Double x:Key="ScrollBarMinThemeHeight">7</x:Double>
    <x:Double x:Key="ScrollBarPanningThumbThemeHeight">2.4</x:Double>
    <x:Double x:Key="ScrollBarPanningThumbThemeWidth">2.4</x:Double>
    <Style  TargetType="ScrollBar">
        <Setter Property="MinWidth" Value="{ThemeResource ScrollBarMinThemeWidth}"/>
        <Setter Property="MinHeight" Value="{ThemeResource ScrollBarMinThemeHeight}"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Foreground" Value="Transparent"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="IsTabStop" Value="False"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ScrollBar">
                    <Grid x:Name="Root" Background="Red">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="PointerOver"/>
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <DoubleAnimation Duration="0" To="0.5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="ScrollingIndicatorStates">
                                <VisualState x:Name="TouchIndicator">
                                    <!--<Storyboard>
                                        <FadeInThemeAnimation Storyboard.TargetName="HorizontalPanningRoot"/>
                                        <FadeInThemeAnimation Storyboard.TargetName="VerticalPanningRoot"/>
                                    </Storyboard>-->
                                </VisualState>
                                <VisualState x:Name="MouseIndicator"/>
                                <VisualState x:Name="NoIndicator">
                                    <!--<Storyboard>
                                        <FadeOutThemeAnimation BeginTime="0" Storyboard.TargetName="HorizontalPanningRoot"/>
                                        <FadeOutThemeAnimation BeginTime="0" Storyboard.TargetName="VerticalPanningRoot"/>
                                    </Storyboard>-->
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Grid x:Name="HorizontalPanningRoot" MinWidth="53">
                            <Rectangle x:Name="HorizontalPanningThumb" AutomationProperties.AccessibilityView="Raw" Fill="{ThemeResource ScrollBarPanningBackgroundThemeBrush}" HorizontalAlignment="Left" Height="{ThemeResource ScrollBarPanningThumbThemeHeight}" MinWidth="{ThemeResource ScrollBarMinThemeWidth}"/>
                        </Grid>
                        <Grid x:Name="VerticalPanningRoot" MinHeight="53">
                            <Rectangle x:Name="VerticalPanningThumb" AutomationProperties.AccessibilityView="Raw" Fill="{ThemeResource ScrollBarPanningBackgroundThemeBrush}" MinHeight="{ThemeResource ScrollBarMinThemeHeight}" VerticalAlignment="Top" Width="{ThemeResource ScrollBarPanningThumbThemeWidth}"/>
                        </Grid>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

<ScrollViewer Height="300" Margin="30" ScrollViewer.VerticalScrollMode="Enabled"  ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Visible">
    <TextBlock FontSize="20" TextWrapping="Wrap" Text="Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum."/>      
</ScrollViewer>

Результат

введите здесь описание изображения

person Heena Patil    schedule 31.07.2014

Почему бы вам просто не установить VerticalScrollBarVisibility и/или HorizontalScrollBarVisibility вашего экземпляра ScrollViewer на Visible вместо того, чтобы удалить поведение затухания из стиля?

<ScrollViewer VerticalScrollBarVisibility="Visible">
     <!-- ScrollViewer Content -->
</ScrollViewer>

ИЗМЕНИТЬ ПОСЛЕ КОММЕНТАРИЯ:

Кажется, я нашел «решение». Я не уверен, что это лучший способ добиться этого, но, похоже, он дает желаемый результат.

Создайте собственный стиль для ScrollViewer, затем создайте его для самого вертикального/горизонтального ScrollBar (используя Blend, что, как я предполагал, вы делали раньше). Получив копию стиля по умолчанию, отредактируйте следующие строки:

<VisualState x:Name="NoIndicator">
    <Storyboard>
        <FadeOutThemeAnimation BeginTime="0" TargetName="HorizontalPanningRoot"/>
        <FadeOutThemeAnimation BeginTime="0" TargetName="VerticalPanningRoot"/>
        <Fade**In**ThemeAnimation BeginTime="0" TargetName="HorizontalRoot"/>
        <Fade**In**ThemeAnimation BeginTime="0" TargetName="VerticalRoot"/>
    </Storyboard>
</VisualState>

Я предполагаю, что это буквально заставляет ScrollBar исчезать, когда с ним не взаимодействуют, то есть он всегда будет виден.

Вот соответствующий ScrollViewer XAML (я не могу вместить все это в ответ). Обратите внимание, что ScrollViewer настроен на использование моего пользовательского стиля ScrollViewerStyle1, затем в этом стиле VerticalScrollBar устанавливается на мой ScrollBar пользовательский стиль ScrollBarCustomStyle1, где NoIndicator VisualState изменяется. Вы можете сделать то же самое с горизонтальной полосой прокрутки, если вам нужно.

Стиль ScrollViewer:

<ScrollContentPresenter x:Name="ScrollContentPresenter" Grid.ColumnSpan="2" ContentTemplate="{TemplateBinding ContentTemplate}" Margin="{TemplateBinding Padding}" Grid.RowSpan="2"/>
<ScrollBar x:Name="VerticalScrollBar" Grid.Column="1" HorizontalAlignment="Right" IsTabStop="False" Maximum="{TemplateBinding ScrollableHeight}" Orientation="Vertical" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{TemplateBinding VerticalOffset}" ViewportSize="{TemplateBinding ViewportHeight}" Style="{StaticResource ScrollBarStyle1}"/>
<ScrollBar x:Name="HorizontalScrollBar" IsTabStop="False" Maximum="{TemplateBinding ScrollableWidth}" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{TemplateBinding HorizontalOffset}" ViewportSize="{TemplateBinding ViewportWidth}"/>
<Border x:Name="ScrollBarSeparator" BorderBrush="{ThemeResource ScrollBarTrackBorderThemeBrush}" BorderThickness="0,0,1,1" Background="{ThemeResource ScrollBarTrackBackgroundThemeBrush}" Grid.Column="1" Grid.Row="1"/>
person J.B    schedule 31.07.2014
comment
Извините, что я забыл упомянуть, что уже пробовал/погуглил. Это не работает так: здесь есть немного дырявой абстракции, где Visible не совсем означает то же самое для ScrollViewer, что и для человека-читателя. Если для параметра VerticalScrollBarVisibility установлено значение Visible, полоса прокрутки всегда присутствует и видна, насколько это касается ScrollViewer. Однако в самой полосе прокрутки полоса прокрутки и большой палец отображаются только в том случае, если они находятся в режиме MouseIndicator: стили полосы прокрутки по умолчанию не отображаются, если пользователь не взаимодействует с ними с помощью мыши. tinyurl.com/och8xrz - person Druvis Cukurs; 31.07.2014
comment
Отредактированный ответ, см. выше - person J.B; 31.07.2014
comment
Используя стиль по умолчанию отсюда (msdn.microsoft. com/en-us/library/windows/apps/xaml/), я получаю 4 ошибки ThemeBrush и ThemeThickness (ресурс не может быть разрешен). Не могли бы вы предоставить стиль по умолчанию, который вы используете? Раньше я пытался разрешить появление и исчезновение через состояния Blend ScrollViewer, но, похоже, у меня ничего не установлено. - person Druvis Cukurs; 31.07.2014
comment
Обновлено. Я также немного изменил свои первоначальные инструкции, поэтому проверьте их еще раз. - person J.B; 31.07.2014
comment
Я думаю, что какая-то часть ответа отсутствует или вы забыли ссылку. :) - person Druvis Cukurs; 31.07.2014
comment
Я только что закомментировал строки VisualState NoIndicator, и теперь это работает. - person arame3333; 03.02.2017