.net中同步多个ScrollViewer滚动的四种方法

  在.net中,Wpf是有ScrollChanged事件的,而silverilght(pc/wp7)则没有,提供以下几种方案:

第一种:(简易,推荐,尤其SL)

        private void Test_Loaded(object sender, RoutedEventArgs e)
        {
            sv1 = VisualTreeHelper.GetChild(this.Listbox1, 0) as ScrollViewer;
            sv2 = VisualTreeHelper.GetChild(this.Listbox2, 0) as ScrollViewer;

            var binding = new Binding("VerticalOffset") { Source = sv1 };
            var offsetChangeListener = DependencyProperty.RegisterAttached("ListenerOffset",
   typeof(object), typeof(UserControl), new PropertyMetadata(OnScrollChanged));
            sv1.SetBinding(offsetChangeListener, binding);

            binding = new Binding("VerticalOffset") { Source = sv2 };
            offsetChangeListener = DependencyProperty.RegisterAttached("ListenerOffset",
   typeof(object), typeof(UserControl), new PropertyMetadata(OnScrollChanged2));
            sv2.SetBinding(offsetChangeListener, binding);
        }

        public void OnScrollChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            double a = (double)e.NewValue;
            sv2.ScrollToVerticalOffset(a);
        }

        public void OnScrollChanged2(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            double a = (double)e.NewValue;
            sv1.ScrollToVerticalOffset(a);
        }

 第二种:(推荐)

        ScrollBar bar1, bar2;
        ScrollViewer sv1, sv2;

        private void EnoTest_Loaded(object sender, RoutedEventArgs e)
        {
            sv1 = VisualTreeHelper.GetChild(this.enoListbox1, 0) as ScrollViewer;
            sv2 = VisualTreeHelper.GetChild(this.enoListbox2, 0) as ScrollViewer;

            bar1 = GetScrollBar(sv1, false);
            bar2 = GetScrollBar(sv2, false);

            //bar1.Scroll += delegate { Debug.WriteLine("bar1 Scroll..."); };//Scroll事件响应不了,原因不详
            //bar2.Scroll += delegate { Debug.WriteLine("bar2 Scroll..."); };

            bar1.ValueChanged += new RoutedPropertyChangedEventHandler<double>(bar1_ValueChanged);
            bar2.ValueChanged += new RoutedPropertyChangedEventHandler<double>(bar2_ValueChanged);

   }

        private void bar1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            sv2.ScrollToVerticalOffset(e.NewValue);
        }

        private void bar2_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            sv1.ScrollToVerticalOffset(e.NewValue);
        }

        private ScrollBar GetScrollBar(ScrollViewer viewer, bool isHor)
        {
            var a = VisualTreeHelper.GetChild(viewer, 0);
            var b = VisualTreeHelper.GetChild(a, 0);
            var c = VisualTreeHelper.GetChild(b, 0);

            if (isHor)
                return VisualTreeHelper.GetChild(b, 2) as ScrollBar;//水平
            else
                return VisualTreeHelper.GetChild(b, 1) as ScrollBar;//垂直          
        }

 第三种:

        public Test()
        {

            this.Listbox1.ManipulationStarted += new EventHandler<ManipulationStartedEventArgs>(Listbox1_ManipulationStarted);
            this.Listbox2.ManipulationStarted += new EventHandler<ManipulationStartedEventArgs>(Listbox2_ManipulationStarted);

            this.Loaded += new RoutedEventHandler(Test_Loaded);

            timer.Interval = new System.TimeSpan(0, 0, 0, 0, 120);
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();

   }

        private void Test_Loaded(object sender, RoutedEventArgs e)
        {
            sv1 = VisualTreeHelper.GetChild(this.Listbox1, 0) as ScrollViewer;
            sv2 = VisualTreeHelper.GetChild(this.Listbox2, 0) as ScrollViewer;
   }

        private void timer_Tick(object sender, EventArgs e)
        {
            if (num == 1)
                sv2.ScrollToVerticalOffset(sv1.VerticalOffset);

            if (num == 2)
                sv1.ScrollToVerticalOffset(sv2.VerticalOffset);
        }

        private void Listbox1_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
            num = 1;
        }

        private void Listbox2_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
            num = 2;
        }

 第四种:(对SL PC&Wp7,wpf均支持)

   搜索一下,SynchronizedScrollViewers,提供了wpf/silverlight的一个封装类库,wp7用的话,使用上略有一点不同而已。

 

第五种:(仅支持wpf,原因是其有事件ScrollChanged

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            sv1 = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(this.listbox1, 0), 0) as ScrollViewer;
            sv2 = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(this.listbox2, 0), 0) as ScrollViewer;

            sv1.ScrollChanged += new ScrollChangedEventHandler(sv1_ScrollChanged);
            sv2.ScrollChanged += new ScrollChangedEventHandler(sv2_ScrollChanged);
        }

        void sv1_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            sv2.ScrollToVerticalOffset(sv1.VerticalOffset);
        }

        void sv2_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            sv1.ScrollToVerticalOffset(sv2.VerticalOffset);
        }

 

posted on 2011-10-08 15:26  chuncn  阅读(4860)  评论(1编辑  收藏  举报

导航