win8 metro 无限滚动加载数据,实现“更多”功能

1、metro前台

<common:LayoutAwarePage
    x:Name="pageRoot"
    x:Class="HTFinancial.GroupNewsPage"
    DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HTFinancial"
    xmlns:data="using:HTFinancial.Data"
    xmlns:common="using:HTFinancial.Common"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:c4fConverters="using:Coding4Fun.Toolkit.Controls.Converters"
    xmlns:c4fToolkit="using:Coding4Fun.Toolkit.Controls"
    >

    <Page.Resources>
        <!-- 此页所显示的项集合-->
        <CollectionViewSource
            x:Name="itemsViewSource"
            Source="{Binding Items}"
            d:Source="{Binding AllGroups[0].Items, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"/>
    </Page.Resources>

    <!--
        此网格用作定义以下两行的页的根面板:
        * 第 0 行包含后退按钮和页标题
        * 第 1 行包含页布局的其余部分
    -->
    <Grid Background="{StaticResource GridImageBrush}"
        Style="{StaticResource LayoutRootStyle}"
        DataContext="{Binding Group}"
        d:DataContext="{Binding AllGroups[0], Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}">

        <Grid.RowDefinitions>
            <RowDefinition Height="140"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ProgressBar x:Name="pb" IsIndeterminate="True" Foreground="Gray" Margin="0,-130,0,0" />
        <!-- 在大多数视图状态中使用的水平滚动网格-->
        <GridView
            x:Name="itemGridView"
            AutomationProperties.AutomationId="ItemGridView"
            AutomationProperties.Name="Items In Group"
            TabIndex="1"
            Grid.RowSpan="2"
            Padding="120,126,120,50"
            ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
            ItemTemplate="{StaticResource Standard300x100ItemTemplate}"
            SelectionMode="None"
            IsSwipeEnabled="false"
            IsItemClickEnabled="True"
            Margin="-100,0,0,0"   
            ScrollViewer.HorizontalScrollBarVisibility="Visible"
            PointerReleased="itemGridView_PointerReleased" 
            ItemClick="ItemView_ItemClick"  Loaded="itemGridView_Loaded" >


            <!--<GridView.Header>
                <StackPanel Visibility="Collapsed" Width="480" Margin="0,4,14,0">
                    <TextBlock Text="{Binding Subtitle}" Margin="0,0,18,20" Style="{StaticResource SubheaderTextStyle}" MaxHeight="60"/>
                    <Image Source="{Binding Image}" Height="420" Margin="0,0,18,20" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
                    <TextBlock Text="{Binding Description}" Margin="0,0,18,0" Style="{StaticResource BodyTextStyle}"/>
                </StackPanel>
            </GridView.Header>-->

            <GridView.ItemContainerStyle>
                <Style TargetType="FrameworkElement">
                    <Setter Property="Margin" Value="52,0,0,10"/>
                </Style>
            </GridView.ItemContainerStyle>

        </GridView>

        <!-- 垂直滚动列表仅在对齐后使用-->
        <ListView
            x:Name="itemListView"
            AutomationProperties.AutomationId="ItemListView"
            AutomationProperties.Name="Items In Group"
            TabIndex="1"
            Grid.Row="1"
            Visibility="Collapsed"
            Padding="10,0,0,60"
            ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
            ItemTemplate="{StaticResource Standard30ItemTemplate}"
            SelectionMode="None"
            IsSwipeEnabled="False"
            IsItemClickEnabled="True"
            Foreground="Transparent"
            ItemClick="ItemView_ItemClick"  >

            <ListView.Header>
                <StackPanel x:Name="sp" >
                    <TextBlock Text="{Binding Title}" Margin="10,0,18,20" Style="{StaticResource TitleTextStyle}" MaxHeight="60"/>
                    <TextBlock Margin="10,20,18,30" Text="{Binding PubDate}" Style="{StaticResource PubDateStyle}"/>
                </StackPanel>
            </ListView.Header>
        </ListView>

        <!-- 后退按钮和页标题-->
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="186"/>
            </Grid.ColumnDefinitions>
            <Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>
            <TextBlock x:Name="pageTitle" Text="{Binding Title}" Style="{StaticResource PageHeaderTextStyle}" Grid.Column="1" IsHitTestVisible="false"/>
            <StackPanel Grid.Column="2" >
                <Button  x:Name="btnGoLeft" FontSize="20"  Content="左端"  Width="137" Height="41" Margin="39,22,0,2" Click="btnGoLeft_Click"/>
                <Button  x:Name="btnGoRight" FontSize="20" Content="右端"  Width="137" Height="41" Margin="39,8,0,2" Click="btnGoRight_Click"/>
            </StackPanel>

            <!--   <c4fToolkit:Tile Click="openCalendarBtn_Click"  >
                <StackPanel Width="auto">
                    <TextBox HorizontalAlignment="Left" IsReadOnly="True" x:Name="datePicker"   TextWrapping="Wrap" Text="{Binding CurrentDateTime, Converter={StaticResource DebugConverter}}"
        	VerticalAlignment="Center" Height="57"  Width="448" Margin="0,20,30,0" />
                </StackPanel>
            </c4fToolkit:Tile>-->

        </Grid>

        <VisualStateManager.VisualStateGroups>

            <!-- 视觉状态反映应用程序的视图状态-->
            <VisualStateGroup x:Name="ApplicationViewStates">
                <VisualState x:Name="FullScreenLandscape"/>
                <VisualState x:Name="Filled"/>

                <!-- 整页采用较窄的 100 像素页边距约定(纵向)-->
                <VisualState x:Name="FullScreenPortrait">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PortraitBackButtonStyle}"/>
                        </ObjectAnimationUsingKeyFrames>

                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" Storyboard.TargetProperty="Padding">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="100,126,90,0"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>

                <!--
                    对齐后,后退按钮和标题的样式将有所不同,并且列表表示形式将被
                    所有视图状态中显示的网格所替代
                -->
                <VisualState x:Name="Snapped">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedBackButtonStyle}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/>
                        </ObjectAnimationUsingKeyFrames>

                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemListView" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</common:LayoutAwarePage>
2、metro后台

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Xml.Linq;
using HTFinancial.Common;
using HTFinancial.Data;
using Windows.ApplicationModel;
using Windows.Data.Xml.Dom;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.UI.Core;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// “基本页”项模板在 http://go.microsoft.com/fwlink/?LinkId=234237 上有介绍

namespace HTFinancial
{
    /// <summary>
    /// 显示单个组的概述的页,包括组内各项
    /// 的预览。
    /// </summary>
    public sealed partial class GroupNewsPage : HTFinancial.Common.LayoutAwarePage
    {
        //Point start = new Point();
        public List<NewsItem> olditem = new List<NewsItem>();
        //集合总数
        public int itemCount = 0;
        //进入页面时是否为相同参数
        bool isSameItem = false;
        public string navUrl;
        //更多时加载参数
        public int page = 2;
        //最右端
        public double maxNum; 

        public GroupNewsPage()
        {
            //启动缓存
            NavigationCacheMode = NavigationCacheMode.Enabled;
            this.InitializeComponent();
      }

        /// <summary>
        /// 在此页将要在 Frame 中显示时进行调用。
        /// </summary>
        /// <param name="e">描述如何访问此页的事件数据。Parameter
        /// 属性通常用于配置页。</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            if (e.NavigationMode != NavigationMode.Back)
            {
                // TODO: 创建适用于问题域的合适数据模型以替换示例数据
                var item = (String)e.Parameter as String;
                var group = SampleDataSource.GetItem(item);
                try
                {
                    if (DefaultViewModel["Group"] != null)
                    {
                        //上一次和本次页面加载的参数是否一致
                        isSameItem = this.DefaultViewModel["Group"].ToString() == group.ToString();
                        if (!isSameItem)
                        {
                            pb.Visibility = Visibility.Visible;
                            maxNum = 0;
                            itemGridView.ItemsSource = null;
                            page = 2;
                            olditem = new List<NewsItem>();
                        }
                    }
                }
                catch (Exception e1)
                {
                    isSameItem = false;
                    string e3 = e.ToString();
                }
                this.DefaultViewModel["Group"] = group;

                if (item.Split(new char[] { '|' }).Length > 1)
                {
                    navUrl = item.Split(new char[] { '|' })[1];
                    //相同参数时不加载数据
                    if (!isSameItem)
                    {
                        LoadHistoryData(navUrl);
                    }
                }
            }
        }

        /// <summary>
        /// 避免itemGridView未加载数据scroollBar.ValueChanged 不触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void itemGridView_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                //找到gridview中的 scrollViewer 、 scrollBar 注册值改变事件
                //Tip 获取该事件要在绑定数据后才去注册,不然获取不到scrollviewer 
                var scrollViewer = this.FindVisualChildByName<ScrollViewer>(this.itemGridView, "ScrollViewer");
                //找到水平的滚轴
                var scroollBar = this.FindVisualChildByName<ScrollBar>(scrollViewer, "HorizontalScrollBar");
                //同页面不同参数进入时滚动条在最左端
                if (itemCount == -1 && !isSameItem)
                {
                    //新页面 滚动条默认的初始位置是置顶
                    scrollViewer.ScrollToHorizontalOffset(0);
                }
                scroollBar.ValueChanged += scroollBar_ValueChanged;
            }
            catch (Exception e2)
            {
                string e3 = e2.ToString();
            }
        }

        /// <summary>
        /// 根据名称找到控件的内容控件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parent"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public T FindVisualChildByName<T>(DependencyObject parent, string name) where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);
                string controlName = child.GetValue(Control.NameProperty) as string;
                if (controlName == name)
                {
                    return child as T;
                }
                else
                {
                    T result = FindVisualChildByName<T>(child, name);
                    if (result != null)
                        return result;
                }
            }
            return null;
        }

        /// <summary>
        /// 滚动到最右边实现加载跟多功能,maxNum参数实现滑到底只触发一次
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void scroollBar_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
        {
            ScrollBar scrollbar = sender as ScrollBar;
            //当滚轴值为最大时 且 同值第一次加载数据   且  不为重新加载页面 或 第二次进入相同页面相同参数时
            if ((e.NewValue != maxNum && e.NewValue == scrollbar.Maximum) && (itemCount != -1 || isSameItem))
            {
                pb.Visibility = Visibility.Visible;
                //避免多次触发事件
                maxNum = e.NewValue;
                //异步加载数据
                if (Utility.IsConnectedToInternet())
                {
                    string url = navUrl.Replace("xml", "asp") + "?page=" + page;
                    isSameItem = true;
                    LoadHistoryData(url);
                    page++;
                }
                else
                {
                    MessageDialog dlg = new MessageDialog("当前网络不可用", "提示");
                    dlg.ShowAsync();
                }
            }
            if (e.NewValue == scrollbar.Minimum)
            {

            }
        }

        /// <summary>
        /// 在单击某个项时进行调用。
        /// </summary>
        /// <param name="sender">显示所单击项的 GridView (在应用程序处于对齐状态时
        /// 为 ListView)。</param>
        /// <param name="e">描述所单击项的事件数据。</param>
        void ItemView_ItemClick(object sender, ItemClickEventArgs e)
        {
            // 导航至相应的目标页,并
            // 通过将所需信息作为导航参数传入来配置新页
            var itemId = ((NewsItem)e.ClickedItem).Id;
            this.Frame.Navigate(typeof(NewsDetailPage), itemId);
        }

        /// <summary>
        /// 加载页面数据
        /// </summary>
        /// <param name="url"></param>
        void LoadHistoryData(string url)
        {
            WebRequest request = HttpWebRequest.Create(url);
            request.BeginGetResponse(ResponseCallBackLoad, request);
        }

        /// <summary>
        /// 异步加载数据
        /// </summary>
        /// <param name="result"></param>
        private void  ResponseCallBackLoad(IAsyncResult result)
        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)result.AsyncState;
                WebResponse response = request.EndGetResponse(result);

                using (Stream stream = response.GetResponseStream())
                using (StreamReader reader = new StreamReader(stream))
                {
                    XDocument Xdoc = XDocument.Parse(reader.ReadToEnd());
                    List<NewsItem> nis = null;

                    nis = (from item in Xdoc.Descendants("item")
                            select new NewsItem()
                            {
                                Title = item.Element("title").Value,
                                PubDate = Utility.ConvertRssToDateTime(item.Element("pubDate").Value).ToString("yyyy-MM-dd HH:mm:ss"),
                                Id = item.Element("ID").Value,
                            }).ToList();

                    //重新加载页面或不同参数时数据归零
                    if (itemCount == -1 && !isSameItem)
                    {
                        maxNum = 0;
                        olditem = new List<NewsItem>();
                        page = 2;
                    }

                    //通过操作olditem集合实现加载更多功能
                    int i = olditem.Count;
                    foreach (NewsItem ni in nis)
                    {
                        olditem.Insert(i, ni);
                        i++;
                    }
                    itemCount = olditem.Count;
                    ObservableCollection<NewsItem> items = new ObservableCollection<NewsItem>(olditem);

                    Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                    {
                        itemGridView.ItemsSource = items;
                        pb.Visibility = Visibility.Collapsed;//滚动条显示
                       // this.DefaultViewModel["Items"] = items;
                    });
                }
            }
            catch (Exception e)
            {
                string e1=e.ToString();
            }
        }

        /// <summary>
        /// 鼠标松键事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void itemGridView_PointerReleased(object sender, PointerRoutedEventArgs e)
        {
        //    Point end = e.GetCurrentPoint(itemGridView).Position;
        //    double angle = 0;
        //    //判断拖动鼠标角度
        //    if (Math.Abs(end.X - start.X) < 1 && Math.Abs(end.Y - start.Y) < 1)
        //    {
        //        angle = 0;
        //    }
        //    else if (end.X > start.X)
        //    {

        //        if (end.Y > start.Y)
        //        {
        //            angle = 360 - Math.Atan((end.Y - start.Y) * 1.0 / (end.X - start.X)) * 180 / Math.PI;
        //        }
        //        else
        //        {
        //            angle = Math.Atan((start.Y - end.Y) * 1.0 / (end.X - start.X)) * 180 / Math.PI;
        //        }
        //    }
        //    else if (end.X < start.X)
        //    {
        //        if (end.Y > start.Y)
        //        {
        //            angle = Math.Atan((end.Y - start.Y) * 1.0 / (start.X - end.X)) * 180 / Math.PI + 180;
        //        }
        //        else
        //        {
        //            angle = 180 - Math.Atan((start.Y - end.Y) * 1.0 / (start.X - end.X)) * 180 / Math.PI;
        //        }
        //    }
        //    if (angle == 0)
        //    {
        //        //this.tbLabel.Text = "点击了一次鼠标或者屏幕";
        //    }
        //    else if (angle >= 45 && angle < 135)
        //    {
        //        //this.tbLabelFore.Text = "从下往上";
        //    }
        //    else if (angle <= 45 || angle > 315)
        //    {
        //        if (itemGridView.SelectedIndex == itemCount - 1)
        //        {
        //            if (Utility.IsConnectedToInternet())
        //            {
        //                string url = navUrl.Replace("xml", "asp") + "?page=" + page;
        //                LoadHistoryData(url);
        //                page++;
        //            }
        //            else
        //            {
        //                MessageDialog dlg = new MessageDialog("当前网络不可用", "提示");
        //                dlg.ShowAsync();
        //            }
        //        }
        //        //this.tbLabelFore.Text = "从左向右滑";
        //    }
        //    else if (angle >= 135 && angle < 225)
        //    {
        //        //this.tbLabelFore.Text = "从右向左滑";
        //    }
        //    else if (angle >= 225 && angle < 315)
        //    {
        //        //this.tbLabelFore.Text = "从上往下";
        //    }
        }

        /// <summary>
        /// 离开本页面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected override void GoBack(object sender, RoutedEventArgs e)
        {
            //离开时标记itemCount=-1
            itemCount = -1;
            this.Frame.Navigate(typeof(GroupedItemsPage), "AllGroups");
        }

        /// <summary>
        /// 回到最左端
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGoLeft_Click(object sender, RoutedEventArgs e)
        {
            var scrollViewer = this.FindVisualChildByName<ScrollViewer>(this.itemGridView, "ScrollViewer");
            //新页面 滚动条默认的初始位置是置顶
            scrollViewer.ScrollToHorizontalOffset(0);
        }

        /// <summary>
        /// 来到最右端,可以相当于更多
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGoRight_Click(object sender, RoutedEventArgs e)
        {
            var scrollViewer = this.FindVisualChildByName<ScrollViewer>(this.itemGridView, "ScrollViewer");
            double toRight = scrollViewer.ScrollableWidth ;
            //新页面 滚动条默认的初始位置是置顶
            scrollViewer.ScrollToHorizontalOffset(toRight);
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值