【问题标题】:Bind/tie scroll position of two LongListSelectors绑定/绑定两个 LongListSelector 的滚动位置
【发布时间】:2014-01-08 15:18:14
【问题描述】:

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

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

谁能指出我如何做到这一点的正确方向?如果无法通过绑定完成,我愿意在代码隐藏或其他任何方式中完成。

【问题讨论】:

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


    【解决方案1】:

    您可以通过挂钩到 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}"/>
    

    【讨论】:

    • 很好的实现!
    • @Shawn Kendrot - 非常感谢这个实现。我使用它并让它工作了大约 95%。这可能已经足够好了,但我有一个跟进 - 有没有办法让它们之间的“反弹”和“拉伸”同步?如果您一直滑动到一个顶部,它会比它应该向下移动一点,但另一个不会。您可以在最后的 Youtube 剪辑中看到它。这不是世界上最大的问题,但既然你的答案很准确,我想我会看看你是否也能解决这个问题。
    • 给老鼠一块饼干,嗯?哎呀! (开玩笑)。我会看看有没有办法解决这个问题,也许在周末。
    • 哈哈。如果它不是您的头顶上的东西或您没有兴趣研究的东​​西,请不要担心。
    【解决方案2】:

    虽然我从未为 Windows Phone 开发过,但我对 WPF 中的 XAML 非常熟悉,并且遇到过类似的问题,我需要在多个条形图中同步条形的宽度。我提出的解决方案使用 Dependency Properties 允许您在 XAML 中绑定 ListSelectors,就像在 Grids 中使用 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-dictionary 留给读者作为执行,这应该很容易。如果您不熟悉制作自己的控件,请尝试 this 初学者资源。

    要使用您准备好的控件,只需将其添加到 XAML 中,如下所示:&lt;yourNamespace:SyncedLongListSelector GroupName="MySyncedGroup" /&gt;

    【讨论】:

    • 谢谢@Zache - 我今晚会试一试这条路线,让你知道我的结果。非常感谢!
    • 希望我能给你一部分赏金,因为你的解决方案非常接近我所需要的,Shawn 的只是更完整一点。不过肯定给了你一个赞成票!再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多