سؤال

I have several ScrollViews with hidden vertical and horizontal scrollbars. I want a scrollbar on the screen which doesn't belong to any ScrollViews and it should be able to control (synchronize) the scrolling of all the ScrollViews. In other words, when I scroll the "master" scrollbar I can have all the ScrollViews scroll with the same offset. Is it possible? If yes, how can I achieve that? Thanks in advance.

هل كانت مفيدة؟

المحلول

Here is an example of solution.

Code behind

public MainWindow()
{
    InitializeComponent();

    Loaded += new RoutedEventHandler(MainWindow_Loaded);
}

void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    ((FrameworkElement)svContainer1.Content).SizeChanged += new SizeChangedEventHandler(content_SizeChanged);

    sbScroller.Minimum = 0;
    sbScroller.Maximum = svContainer1.ExtentHeight - svContainer1.ViewportHeight;
}

void content_SizeChanged(object sender, SizeChangedEventArgs e)
{
    sbScroller.Minimum = 0;
    sbScroller.Maximum = svContainer1.ExtentHeight - svContainer1.ViewportHeight;
}

//ScrollBar event handler
private void ScrollBar_Scroll(object sender, System.Windows.Controls.Primitives.ScrollEventArgs e)
{
    UpdateScrollOffset(sbScroller.Value);
}

//Updates the offset of both ScrollViewer
public void UpdateScrollOffset(double newOffset)
{
    svContainer1.ScrollToVerticalOffset(newOffset);
    svContainer2.ScrollToVerticalOffset(newOffset);
}

//Event handler for all ScrollViewers
private void Grid_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
    UpdateScrollOffset(e.VerticalOffset);
}

Xaml code:

<Grid ScrollViewer.ScrollChanged="Grid_ScrollChanged">

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="0.5*"/>
        <ColumnDefinition Width="0.5*"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>


    <ScrollViewer x:Name="svContainer1"  VerticalScrollBarVisibility="Hidden" Grid.Column="0">
        <Grid Height="1000">
            <Grid.RowDefinitions>
                <RowDefinition Height=".25*"/>
                <RowDefinition Height=".25*"/>
                <RowDefinition Height=".25*"/>
                <RowDefinition Height=".25*"/>
            </Grid.RowDefinitions>

            <Rectangle Fill="Red" Grid.Row="0"/>
            <Rectangle Fill="Green" Grid.Row="1"/>
            <Rectangle Fill="Violet" Grid.Row="2"/>
            <Rectangle Fill="Blue" Grid.Row="3"/>

        </Grid>
    </ScrollViewer>

    <ScrollViewer x:Name="svContainer2" VerticalScrollBarVisibility="Hidden" Grid.Column="1">
        <Grid Height="1000">
            <Grid.RowDefinitions>
                <RowDefinition Height=".25*"/>
                <RowDefinition Height=".25*"/>
                <RowDefinition Height=".25*"/>
                <RowDefinition Height=".25*"/>
            </Grid.RowDefinitions>

            <Rectangle Fill="Red" Grid.Row="0"/>
            <Rectangle Fill="Green" Grid.Row="1"/>
            <Rectangle Fill="Violet" Grid.Row="2"/>
            <Rectangle Fill="Blue" Grid.Row="3"/>

        </Grid>
    </ScrollViewer>

    <ScrollBar x:Name="sbScroller" Grid.Column="3" Minimum="0" Scroll="ScrollBar_Scroll"  Maximum="100"/>
</Grid>

Actually there is no simple way. You have to listen to ScrollBar events and update ScrollViewers' offsets. You also have to listen to ScrollViewer's content size changes too so you can update scroll bounds of the ScrollBar.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top