在win8中如何实现下拉刷新的功能

 

现在我以listview为例来讲述下拉刷新的功能!

   在xaml中设置listview一定要设置一个这样的属性,IsSwipeEnabled=false,然后再listview控件的前面要布局下拉刷新的图标及提示,在listview控件的后面也要布局上拉时的提示信息。

   现在我将个人的布局展现出来,仅供大家参考!

 <Grid Name="layoutCtlRoot" MinWidth="240">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>
            <Border Name="recRefresh" Height="0" Margin="0" MaxHeight="800" VerticalAlignment="Bottom">
                <Grid>
                    <Grid Margin="10" VerticalAlignment="Bottom">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="64"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Center">
                            <Image Name="imgArrow" Style="{StaticResource ProgressArrowStyle}">
                                <Image.RenderTransform>
                                    <RotateTransform x:Name="imageRotateTransform" Angle="0"/>
                                </Image.RenderTransform>
                            </Image>
                            <ProgressRing Name="prgRefresh" Style="{StaticResource ProgressRingStyle}"/>
                        </StackPanel>
                        <StackPanel VerticalAlignment="Bottom" Grid.Column="1">
                            <TextBlock Name="txtOperationTip" Style="{StaticResource TipsContentStyle}"/>
                            <TextBlock Name="txtOperationTime" Style="{StaticResource TipsContentStyle}"/>
                        </StackPanel>
                    </Grid>
                    <Border Background="#99999999" VerticalAlignment="Bottom" Height="1"/>
                </Grid>
            </Border>
            <ListView Name="ForumList" Grid.Row="1" IsSwipeEnabled="False" ItemContainerStyle="{StaticResource ListItemBaseStyle}"/>
            <Border Name="recLoad" Height="0" Grid.Row="2" MaxHeight="800">
                <Grid VerticalAlignment="Top" Margin="0,10">
                    <Border Background="#99999999" VerticalAlignment="Top" Height="1"/>
                    <StackPanel Name="splNextPageLoading" HorizontalAlignment="Center" Orientation="Horizontal" Visibility="Collapsed">
                        <ProgressRing Style="{StaticResource ProgressRingStyle}" Visibility="Visible"/>
                        <TextBlock Text="正在加载…" Margin="13" Style="{StaticResource TipsContentStyle}"/>
                    </StackPanel>
                </Grid>
            </Border>
        </Grid>

 

 

然后在后台就要实现下拉刷新的正真效果呢!

 这里特别要指出的要注册这样一个事件,  this.LayoutUpdated += ForumList_LayoutUpdated;不然就实现不了!

 也要注册listview的触摸事件,例如:

            this.ForumList.ManipulationStarted+=ForumList_ManipulationStarted;
            this.ForumList.ManipulationDelta+=ForumList_ManipulationDelta;
            this.ForumList.ManipulationCompleted+=ForumList_ManipulationCompleted;

 

 思路就是这样的,现在我就讲后台的逻辑也给大家参考!

  DispatcherTimer toptimer = new DispatcherTimer();
        DispatcherTimer timer = new DispatcherTimer();
        private ScrollViewer listViewScrollViewer;

        private double listviewItemHeight = -1;
        private int optLimitHeight = 96;
        private bool isInPrpcessing = false;

        private Point eventStartPoint;

        private double lastDeltaHandledY = 0;

        private ObservableCollection<dynamic> listDataItems = new ObservableCollection<dynamic>();

        //移动开始位置
        private Point moveStartPoint;
        //是否可以移动
        private bool canMove = false;

        public ListPage()
        {
            this.InitializeComponent();
          
              this.imgArrow.Source = new BitmapImage(new Uri(@"ms-appx:///Assets/pullrefresh_arrow.png",UriKind.RelativeOrAbsolute));
            this.LayoutUpdated += ForumList_LayoutUpdated;
            this.recRefresh.SizeChanged+=recRefresh_SizeChanged;
            this.ForumList.ManipulationStarted+=ForumList_ManipulationStarted;
            this.ForumList.ManipulationDelta+=ForumList_ManipulationDelta;
            this.ForumList.ManipulationCompleted+=ForumList_ManipulationCompleted;
            //this.ForumList.SelectionChanged+=ForumList_SelectionChanged;
        }


 

  private void ForumList_LayoutUpdated(object sender, object e)
        {
            if (this.Height.Equals(double.NaN) && this.Parent != null)
            {
                this.Height = ((Windows.UI.Xaml.FrameworkElement)(this.Parent)).ActualHeight;
            }

            if (listViewScrollViewer == null)
            {
                listViewScrollViewer = FindVisualElement<ScrollViewer>(VisualTreeHelper.GetParent(this));
                listViewScrollViewer.ManipulationMode = ManipulationModes.All;
            }

            for (int i = 0; i < this.ForumList.Items.Count; i++)
            {
                ListViewItem item = this.ForumList.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;

                if (item != null && item.ManipulationMode != ManipulationModes.All)
                {
                    item.ManipulationMode = ManipulationModes.All;

                    if (listviewItemHeight < 0)
                    {
                        listviewItemHeight = ((Windows.UI.Xaml.FrameworkElement)(item)).ActualHeight;
                    }
                }
            }
        }

        private static T FindVisualElement<T>(DependencyObject container) where T : DependencyObject
        {
            Queue<DependencyObject> childQueue = new Queue<DependencyObject>();
            childQueue.Enqueue(container);

            while (childQueue.Count > 0)
            {
                DependencyObject current = childQueue.Dequeue();

                T result = current as T;
                if (result != null && result != container)
                {
                    return result;
                }

                int childCount = VisualTreeHelper.GetChildrenCount(current);
                for (int childIndex = 0; childIndex < childCount; childIndex++)
                {
                    childQueue.Enqueue(VisualTreeHelper.GetChild(current, childIndex));
                }
            }

            return null;
        }

 

 private void recRefresh_SizeChanged( object sender,SizeChangedEventArgs e)
        {
            if (e.NewSize.Height > this.optLimitHeight && !isInPrpcessing)
            {
                if (!this.txtOperationTip.Text.Equals("松开刷新…"))
                {
                    this.txtOperationTip.Text = "松开刷新…";
                    this.ImgStoryBoard.Begin();
                }
            }
        }

        private void ForumList_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
        {
            eventStartPoint = e.Position;
            lastDeltaHandledY = 0;
            if (!isInPrpcessing)
            {
                this.txtOperationTip.Text = "下拉刷新列表…";
            }
            e.Handled = true;
        }
        private void ForumList_ManipulationDelta(object sender,ManipulationDeltaRoutedEventArgs e)
        {
            double offset = e.Cumulative.Translation.Y - lastDeltaHandledY;
            if (listViewScrollViewer.VerticalOffset < 3)
            {
                double height = recRefresh.Height + offset;
                recRefresh.Height = height > 0 ? height : 0;
                if (offset < 0 && recRefresh.Height <= 0)
                {
                    //向上滑动且刷新Panel未显示时滚动条下移
                    listViewScrollViewer.ScrollToVerticalOffset(listViewScrollViewer.VerticalOffset-offset/listviewItemHeight);
                }
            }
            else if (listViewScrollViewer.VerticalOffset >= listViewScrollViewer.ScrollableHeight - 1)
            {
                double height = recLoad.Height - offset;
                recLoad.Height = height > 0 ? height : 0;
                if (offset > 0 && recLoad.Height <= 0)
                {
                    listViewScrollViewer.ScrollToVerticalOffset(listViewScrollViewer.VerticalOffset - offset / listviewItemHeight);
                }
            }
            else
            {
                listViewScrollViewer.ScrollToVerticalOffset(listViewScrollViewer.VerticalOffset-offset/listviewItemHeight);
            }
            lastDeltaHandledY = e.Cumulative.Translation.Y;
            e.Handled = true;
        }

        private void ForumList_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
        {
            if (listViewScrollViewer != null)
            {
                double offset = listViewScrollViewer.VerticalOffset;
                double total = listViewScrollViewer.ScrollableHeight;
                if (offset <= 3 || offset > total - 2)
                {
                    DoListItemsSwipe();
                }
            }
        }
        /// <summary>
        /// 数据加载后是否可下拉刷新
        /// </summary>
        public static readonly DependencyProperty RefreshableProperty = DependencyProperty.Register("Refreshable", typeof(bool), typeof(ListPage), new PropertyMetadata(true));
        public bool Refreshable
        {
            get
            {
                return (bool)base.GetValue(RefreshableProperty);
            }
            set
            {
                base.SetValue(RefreshableProperty, value);

                if (!value)
                {
                    this.imgArrow.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                    this.prgRefresh.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                    this.txtOperationTip.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                    this.txtOperationTime.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                }
            }
        }
        private void DoListItemsSwipe()
        {
            if (recRefresh.Height > 0)
            {
                if (recRefresh.Height > optLimitHeight && this.Refreshable)
                {
                    recRefresh.Height = 96;
                    imgArrow.Visibility = Visibility.Collapsed;
                    prgRefresh.Visibility = Visibility.Visible;
                    if (!this.isInPrpcessing)
                    {
                        System.Diagnostics.Debug.WriteLine(this.isInPrpcessing);
                        DoListDataSourceRefresh();
                    }
                }
                else
                {
                    recRefresh.Height = 0;
                }
                listViewScrollViewer.ScrollToVerticalOffset(2.05);
            }
            if (recLoad.Height > 0)
            {
                if (recLoad.Height > optLimitHeight)
                {
                    recLoad.Height = 68;
                    splNextPageLoading.Visibility = Visibility.Visible;
                    if (!this.isInPrpcessing)
                    {
                        DoListDataLoadNextPage();
                    }
                }
                else
                {
                    recLoad.Height = 0;
                }
            }
        }
        private  void DoListDataSourceRefresh()
        {
           
            this.isInPrpcessing = true;
            this.txtOperationTip.Text = "加载数据中";
            this.isInPrpcessing = false;
            this.recRefresh.Height = 0;
            this.imgArrow.Visibility = Windows.UI.Xaml.Visibility.Visible;
            this.prgRefresh.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
            this.ImgStoryBoard.Begin(); //箭头复位
        }
        private  void DoListDataLoadNextPage()
        {
            this.recLoad.Height = 0;
            splNextPageLoading.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
        }
        public event SelectionChangedEventHandler SelectionChanged;
        private void ForumList_SelectionChanged( object sender,SelectionChangedEventArgs e)
        {
            SelectionChanged(sender,e);
        }

 

 

posted @ 2013-07-10 14:52  深山居士  阅读(1224)  评论(0编辑  收藏  举报