如何同步两个ScrollViewers?

时间:2014-10-29 11:03:48

标签: c# wpf windows-phone-8

我有四个方面。其中三个滚动。我必须同步它们的运动,所以如果用户移动区域A(仅水平)区域C模仿运动。如果用户移动areaC areaA模仿水平,areaB模仿垂直移动。

由于某些区域可以“移动”在其他区域之下,我看不到使用单个ScrollView的方法:

  • C在'A
  • 下垂直移动
  • C在'B
  • 下水平移动
  • B在固定区域
  • 下垂直移动
  • A在固定区域
  • 下水平移动

The 4 areas

请注意我正在开发一个针对WinRT运行时的Windows Phone 8.1应用程序(如果这是它的当前名称?它不是Silverlight。)。

关于维度:

  • areaA和areaC具有相同的宽度
  • areaB和areaC具有相同的高度

我目前管理的是通过订阅ViewChanging事件让他们同步,从事件arg中读取NextView偏移值并在相应的其他滚动条上调用ScrollTo[Vertical,Horizontal]Offset 。正如我所说,它以某种方式起作用,但它们的口感相当于相当。另外,我还没有找到一种模仿'滚动视图结束的方法,所以内容现在被压缩了一点上/下'的效果。

//adding event handler
areaCScroller.ViewChanging += HandleAreaCScrolls;

//handler
void HandleAreaCScrolls(object sender, ScrollViewerViewChangingEventArgs e)
{
    areaAScroller.ScrollToHorizontalOffset(e.NewView.HorizontalOffset);
    areaBScroller.ScrollToVerticalOffset(e.NewView.VerticalOffset);
}

我还尝试了FinalView值(导致StackOverFlowExceptions)并在滚动条上禁用惯性(这没有帮助,但让它们感觉不那么“酷”)。

所以我的问题是:我怎样才能以更好的方式做到这一点?

我对WPF / XAML并不完全熟悉,所以我可能会很好地忽略(或者谷歌的低谷歌)一个控制或功能,它可以满足我的需要。打开所有建议(布局本身几乎被锁定)。我查看了hereherehere,但他们都做了与我尝试过的相同的事情。

1 个答案:

答案 0 :(得分:4)

我使用了ScrollViewer中的ViewChanged。一切都对我很好。以下是MainPage.xaml.cs的代码:

protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        var list = new List<int>();
        for (int i = 0; i < 100; ++i)
        {
            list.Add(i);
        }

        ItemsControl1.ItemsSource = list;
        ItemsControl2.ItemsSource = list;
    }

    private void ScrollViewer1_OnViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
    {
        if (ScrollViewer1.VerticalOffset != ScrollViewer2.VerticalOffset)
        {
            ScrollViewer2.ScrollToVerticalOffset(ScrollViewer1.VerticalOffset);
        }
    }

    private void ScrollViewer2_OnViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
    {
        if (ScrollViewer1.VerticalOffset != ScrollViewer2.VerticalOffset)
        {
            ScrollViewer1.ScrollToVerticalOffset(ScrollViewer2.VerticalOffset);
        }
    }

来自MainPage.xaml的XAML代码

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="50"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <ScrollViewer Grid.Column="0"
                  x:Name="ScrollViewer1"
                  ViewChanged="ScrollViewer1_OnViewChanged">
        <ItemsControl x:Name="ItemsControl1">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>
    <ScrollViewer Grid.Column="2"
                  x:Name="ScrollViewer2"
                  ViewChanged="ScrollViewer2_OnViewChanged">
        <ItemsControl x:Name="ItemsControl2">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>
</Grid>

试试这个,希望它有所帮助。