Lyall
Lyall

Reputation: 945

Horizontal auto-scroll of text in a TextBlock

I want to have a fixed-width TextBlock that has long, unbroken, horizontal text, and am looking for a good approach to allow all the text to be read by the user. I want something more sophisticated than just putting the control inside a ScrollViewer.

First (ideal) option is to be able to hover the mouse over the TextBlock and if the mouse is right of center for example, it would scroll to the right (with increasing speed the further you move from the center). I guess this is do-able, by handling MouseEnter / MouseOver events on the TextBlock, figuring out where the cursor is within the TextBlock, and enabling some marquee/animation as appropriate. I'm looking for approaches on how to do this, particularly as I have little experience with animation in WPF. Would like to figure out the detail myself but struggling to get started.

Second option would be to have a RepeatButton on either side of the text, and when you hover over that, it scrolls the text.

An initial attempt:

<RepeatButton ClickMode="Hover"
              Command="{x:Static ComponentCommands.MoveLeft}"
              CommandTarget="{Binding ElementName=TextAutoScroller}"
              Content="Go left" />

<ScrollViewer x:Name="TextAutoScroller" Grid.Column="1"
              VerticalScrollBarVisibility="Disabled"
              HorizontalScrollBarVisibility="Hidden">
    <TextBlock VerticalAlignment="Center"
               Text="The quick brown fox jumps over the lazy dog.&#x0d;&#x0a;The quick brown fox jumps over the lazy dog.&#x0d;&#x0a;The quick brown fox jumps over the lazy dog." />
</ScrollViewer>

<RepeatButton Grid.Column="2"
              ClickMode="Hover"
              Command="{x:Static ComponentCommands.ScrollPageRight}"
              CommandTarget="{Binding ElementName=TextAutoScroller}"
              Content="Go right" />

The problem with this is that both RepeatButton controls are disabled - seems that neither MoveLeft or ScrollPageRight are supported, but ScollPageDown (no good for my horizontal scenario) works ok?

Any tips or suggestions on either option would be greatly appreciated!

Upvotes: 2

Views: 2179

Answers (1)

Chronicide
Chronicide

Reputation: 1152

A good solution for the repeatable button version would be to just scroll the scrollviewer incrementally.

private void scrollLeft_Click(object sender, RoutedEventArgs e)
{
    sv.ScrollToHorizontalOffset(sv.HorizontalOffset - 10);
}

private void scrollRight_Click(object sender, RoutedEventArgs e)
{
    sv.ScrollToHorizontalOffset(sv.HorizontalOffset + 10);
}

The above assumes your text is wrapped in a scrollviewer named sv, with two repeatbuttons.

If you want to speed up the longer you've held it in:

    private int offset = 1;
    private int maxOffset = 50;

    private void scrollLeft_Click(object sender, RoutedEventArgs e)
    {
        sv.ScrollToHorizontalOffset(sv.HorizontalOffset - offset);
        offset += offset < maxOffset ? 1 : 0;
    }

    private void scrollRight_Click(object sender, RoutedEventArgs e)
    {
        sv.ScrollToHorizontalOffset(sv.HorizontalOffset + offset);
        offset += offset < maxOffset ? 1 : 0;
    }

    private void scrollRight_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        offset = 1;
    }

I would also weigh in and suggest not using the ClickMode="Hover"... Users are more accustomed to clicking buttons. Just my two cents.

Upvotes: 1

Related Questions