c# - 如何同步两个 ScrollViewer?

标签 c# wpf windows-phone-8

我有四个区域。其中三个滚动。我必须同步他们的移动,所以如果用户移动 areaA(仅限水平),areaC 会模仿移动。如果用户移动 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,Horizo​​ntal]Offset 在适当的其他滚动条上。正如我所说,它以某种方式起作用,但他们相当有点结结巴巴。另外,我还没有找到一种方法来模仿“到达 ScrollView 的末尾,因此内容现在会向上/向下压缩一点”的效果。

//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 没有完全的经验,所以我很可能会忽略(或谷歌 foo 低)满足我需要的控件或功能。开放所有建议(虽然布局本身几乎是锁定的)。我看了here , herehere例如,但它们都和我试过的一样。

最佳答案

我使用了 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>

试试这个,希望对你有帮助。

关于c# - 如何同步两个 ScrollViewer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26628687/

相关文章:

c# - MarkupExtension.ProvideValue——是否实际使用了 IServiceProvider?

c# - 保留录制视频的最后 X 分钟

xaml - Windows Phone 8 - 中心全景 Item.Header

c# 在 windows phone 8.1 silverlight 项目中混合两个音频文件

c# - 折叠所有内容时隐藏扩展器

c# - 从后面的代码访问 css 文件中的 css 类?

c# - 为 WPF DateTimePicker 验证设置区域性

.net - 如何为WPF提出好的商业案例?

c# - 更快或并行地将数据加载到单个 Azure Blob 中

c# - 对数据表实现约束