绑定/绑定两个LongListSelectors的滚动位置

时间:2014-01-08 15:18:15

标签: c# xaml windows-phone-7 windows-phone-8 windows-phone

在我的Windows Phone应用中,我在页面上有两个LongListSelectors并排。我想这样做,当用户滚动其中一个时,另一个滚动相同的数量。

两个LongListSelectors的ItemTemplates总是具有相同的高度。您可以将此视为模仿Excel中的冻结列(左LongListSelector仅垂直滚动,右侧水平和垂直滚动。

有人能指出我正确的方向如何做到这一点?我愿意在代码隐藏中做这件事,或者如果不能用绑定做的话。

2 个答案:

答案 0 :(得分:3)

虽然我从未为Windows Phone开发过,但我对WPF中的XAML非常熟悉并且遇到了类似的问题,我需要在几个条形图中同步条形宽度。我建议的解决方案使用依赖属性允许您在XAML中绑定ListSelectors,就像在网格中绑定SharedSizeGroup一样。如果您不熟悉依赖属性,请先查看here。由于我没有访问Windows Phone的必需程序集,因此尚未经过测试,但它确实可以在非常类似的场景中运行。

public class SyncedLongListSelector : LongListSelector
{
    private ScrollBar scrollBar;

    private static readonly Dictionary<string, List<SyncedLongListSelector>> Groupings = new Dictionary<string, List<SyncedLongListSelector>>();

    public static readonly DependencyProperty GroupNameProperty =
        DependencyProperty.Register("GroupName", typeof(string), typeof(SyncedLongListSelector), new PropertyMetadata(default(string)));

    public string GroupName
    {
        get
        {
            return (string)GetValue(GroupNameProperty);
        }
        set
        {
            SetValue(GroupNameProperty, value);
        }
    }

    public override void OnApplyTemplate()
    {
        scrollBar = GetTemplateChild("VerticalScrollBar") as ScrollBar; // See my comments

        if (scrollBar != null)
            scrollBar.Scroll += OnScroll;

        base.OnApplyTemplate();
    }

    private void UpdateScrolPosition(double scrollBarValue)
    {
        scrollBar.Value = scrollBarValue;
    }

    private void OnScroll(object sender, ScrollEventArgs args)
    {
        foreach (var otherList in Groupings[GroupName].Where(l => !Equals(l, this)))
            otherList.UpdateScrolPosition(scrollBar.Value);
    }
}

scrollBar = GetTemplateChild("VerticalScrollBar") as ScrollBar;我在您提供的link中找到了要使用的字符串。

如果设置scrollBar.Value引发OnScroll - 事件,您可能需要添加一些内容,这样就不会出现堆栈溢出:)

同样将控件添加到Grouping - 词典中作为执行者留给读者,应该很容易。如果您自己创建自己的控件是新手,请为初学者尝试this资源。

要使用您的就绪控件,只需将其添加到XAML中,如下所示:<yourNamespace:SyncedLongListSelector GroupName="MySyncedGroup" />

答案 1 :(得分:3)

您可以通过挂钩到LongListSelector的ViewportControl来完成此操作。当一个LLS的视口发生更改时,请更改其他LLS的视口。我猜你只需要两个LLS,所以一个DependencyProperty就可以了。我写了a blog,其中包含了如何实现这一目标的所有细节。

缺点是需要DependencyProperty

public double ScrollPosition
{
    get { return (double)GetValue(ViewPortProperty); }
    set { SetValue(ViewPortProperty, value); }
}

public static readonly DependencyProperty ViewPortProperty = DependencyProperty.Register(
    "ScrollPosition", 
    typeof(double), 
    typeof(MyLongListSelector), 
    new PropertyMetadata(0d, OnViewPortChanged));

并在视口更改时设置属性。

private void OnViewportChanged(object sender, ViewportChangedEventArgs args)
{
    ScrollPosition = _viewport.Viewport.Top;
}

然后将属性绑定到xaml中的每个LLS

<dataBoundApp1:MyLongListSelector x:Name="MainLongListSelector" ItemsSource="{Binding Items}"
                                    ScrollPosition="{Binding ScrollPosition, ElementName=MainLongListSelector2, Mode=TwoWay}"/>
<dataBoundApp1:MyLongListSelector x:Name="MainLongListSelector2" ItemsSource="{Binding Items}" Grid.Column="1" 
                                    ScrollPosition="{Binding ScrollPosition, ElementName=MainLongListSelector, Mode=TwoWay}"/>