【问题标题】:Windows Phone 7 ScrollViewer.HorizontalOffset not updatingWindows Phone 7 ScrollViewer.Horizo​​ntalOffset 未更新
【发布时间】:2011-10-17 20:13:37
【问题描述】:

我创建了一个快速示例,将图像放入 ScrollViewer,启动 DispatcherTimer,然后每 200 毫秒打印一次 ScrollViewer.Horizo​​ntalOffset。从示例中我注意到一些奇怪的行为 - 如果我抓取图像并滚动少量,例如 60 像素左右,Horizo​​ntalOffset 值永远不会改变。 ScrollViewer 没有正确报告其位置是否有原因?

编辑:我还尝试在 ScrollViewer 中抓取 ScrollBar(名为“Horizo​​ntalScrollBar”)并检查其 Value 属性,但得到相同的结果。

EDIT2:这个错误似乎只发生在 Mango build 7712 上(即使应用程序是为 7.0 构建的)。我会关闭它并希望它在最终版本中得到修复。

示例代码。在我的机器上,我可以在很大程度上拖动图像而无需更新。我似乎只能获得 120 次左右的价值增量的更新。我希望至少每 10-20 像素更新一次。

<Grid x:Name="LayoutRoot" Background="Transparent">
        <ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" x:Name="Scroll">
            <Image Source="Jellyfish.jpg" Stretch="None"/>
        </ScrollViewer>
    </Grid>

MainPage.xaml.cs:

// Constructor
        public MainPage()
        {
            InitializeComponent();

            this.Loaded += (s, e) =>
                {
                    var scrollBar = Scroll.FindVisualChild("HorizontalScrollBar") as ScrollBar;
                    scrollBar.ValueChanged += (s1, e1) => Debug.WriteLine(DateTime.Now + " " + scrollBar.Value);
                };
        }

ExtensionMethods.cs:

public static class ExtensionMethods
    {
        public static FrameworkElement FindVisualChild(this FrameworkElement root, string name)
        {
            FrameworkElement temp = root.FindName(name) as FrameworkElement;
            if (temp != null)
                return temp;

            foreach (FrameworkElement element in root.GetVisualDescendents())
            {
                temp = element.FindName(name) as FrameworkElement;
                if (temp != null)
                    return temp;
            }

            return null;
        }

        public static IEnumerable<FrameworkElement> GetVisualDescendents(this FrameworkElement root)
        {
            Queue<IEnumerable<FrameworkElement>> toDo = new Queue<IEnumerable<FrameworkElement>>();

            toDo.Enqueue(root.GetVisualChildren());
            while (toDo.Count > 0)
            {
                IEnumerable<FrameworkElement> children = toDo.Dequeue();
                foreach (FrameworkElement child in children)
                {
                    yield return child;
                    toDo.Enqueue(child.GetVisualChildren());
                }
            }
        }

        public static IEnumerable<FrameworkElement> GetVisualChildren(this FrameworkElement root)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++)
                yield return VisualTreeHelper.GetChild(root, i) as FrameworkElement;
        }
    }

【问题讨论】:

  • 介意展示您如何获得偏移量(代码)?我刚刚建立了一个简单的示例,它似乎工作正常。
  • 我刚刚测试了你的代码,它对我来说很好用。延迟可能是由您拍摄快照的方式引起的。介意分享一下吗?
  • 嗨丹尼斯 - 快照代码是上面的“Debug.WriteLine()”。当您运行该示例时,您是说它几乎在每个像素处都更新了吗?我只会每 80-120 像素获得一次更新。
  • 我在一个独立的应用程序中测试了你的代码,它工作得很好。申请中还有其他处理吗?

标签: c# windows-phone-7 scrollviewer horizontal-scrolling


【解决方案1】:

不频繁的滚动事件更新是 Mango 性能改进的一部分:

http://blogs.msdn.com/b/slmperf/archive/2011/06/02/listbox-scrollviewer-performance-improvement-for-mango-and-how-it-impacts-your-existing-application.aspx

修复方法是改变 ScrollViewer 的 ManipulationMode 如下:

<ListBox ItemsSource="{Binding Items}" ScrollViewer.ManipulationMode ="Control" Height="652" Canvas.Top="80">

【讨论】:

    【解决方案2】:

    我使用过 scrollviewer 和 Horizo​​ntalOffset,您可以将您的开发工具更新到 beta2 以使其正常工作(在我的情况下,scrollviewer 是 beta 中的一个已知错误)。如果还是不行,试试我的代码(为我工作):

        public MainPage()
        {
            InitializeComponent();
            if (someVariable == 0)
            {
                myPopup = new Popup() { IsOpen = true, Child = new AnimatedSplashScreen() };
                backroungWorker = new BackgroundWorker();
                RunBackgroundWorker();
    
                timer = new DispatcherTimer();
                timer.Interval = TimeSpan.FromMilliseconds(10);
    
                timer.Tick += new EventHandler(timer_Tick);
                timer.Start();
    
                someVariable = 1;
            }
    
    
        }
    
        #region timer
        void timer_Tick(object sender, EventArgs e)
        {
    
            if (imagesScrollview.HorizontalOffset == (listBox.ActualWidth - 483))
                imagesScrollview.ScrollToHorizontalOffset(10);
           imagesScrollview.ScrollToHorizontalOffset(imagesScrollview.HorizontalOffset +1);
            current = imagesScrollview.HorizontalOffset + 1;
    

    【讨论】:

    • 啊,感谢您指出它在第一个测试版中存在错误。我会看看 beta 2 是否能解决这个问题。
    • 不幸的是,这似乎不是解决方案。最新的测试版问题仍然存在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多