美高梅官方网站3045-mgm6608美高梅app下载
WP7中代码设置ListBox和LongListSelector条目项的显示位置

WP7中代码设置ListBox和LongListSelector条目项的显示位置

作者:美高梅官方网站    来源:未知    发布时间:2020-02-03 12:55    浏览量:

在LongListSelector的Item上面绑定了数据,也添加了contextmenu,长按一个item就可以在contextmenu里面删除,数据确实是删掉了,但是LongListSelector并没有变,当我退出那个页面再进去的时候就会刷新,请问有什么办法当我删除item的时候就刷新Longlistselector?或者是如何手动刷新整个页面?

最近开始接触WP7的开发,遇到一个需求,简要的概述如下:

 LongListSelector是一个加强版的列表控件,它可以实现分组的列表,如系统人脉列表的交互效果就可以利用LongListSelector控件去实现,同时LongListSelector也一样可以实现和ListBox一样的列表效果。在使用LongListSelector控件的时候可以使用IsGroupingEnabled属性来控制你要实现的是分组的效果,还是非分组的列表效果。

有两个画面,第一个画面中有一个用于输入的TextBox;第二个画面是一个 LongListSelector控件。当第一个画面输入内容后,跳转到第二个画面,如果第二个画面中LongListSelector的数据中有和TextBox输入内容相同的条目,那么选中这个条目,并且使得条目处于屏幕的中间。

    下面我们用LongListSelector来实现一个非分组的列表效果,同时还要实现的功能是列表下拉自动刷新的效果。LongListSelector实现非分组列表效果和ListBox控件是类似的,通过对ItemTemplate模板进行设置,然后绑定集合的相关属性就可以了。在前面的章节由介绍过一个使用ListBox控件判断列表滚动到底的例子,实现的原理是通过可视化树获取ListBox的ScrollViewer控件,然后根据ScrollViewer控件的垂直位移属性来判断ListBox控件什么时候滚动到底。但是LongListSelector内部没有采用ScrollViewer控件,所以我们不能采用这种方式来实现下拉自动刷新的功能。那么我们这个例子是通过LongListSelector控件的ItemRealized事件去控制自动刷新的逻辑,因为LongListSelector控件是对数据进行虚拟化处理的,当列表向下滚动的时候下面的数据就会不断地被实例化,当数据实例化的时候就会触发ItemRealized事件,所以我只需要监控到当列表最后一个数据实例化的时候就可以出发数据刷新的逻辑就可以了。代码如下所示:

 

    <phone:LongListSelector x:Name="lls" ItemsSource="{Binding Items}" IsGroupingEnabled="False">
        <phone:LongListSelector.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding FirstName}" FontSize="30"></TextBlock>
                    <TextBlock Text="{Binding LastName}" FontSize="30" Margin="30,0,0,0"></TextBlock>
                </StackPanel>
            </DataTemplate>
        </phone:LongListSelector.ItemTemplate>
    </phone:LongListSelector>

对于LongListSelector和ListBox来说,其视图结构中都包含一个ScrollViewer,区别只在于ScrollViewer所处于的层次会有所不同。对于LongListSelector来说,它内在的第一层是一个TemplatedListBox,第二层才是ScrollViewer,而对于ListBox第一层就是ScrollViewer。我解决这个问题的关键就在于找到控件中的ScrollViewer,并使用它的ScrollToVerticalOffset方法。怎么找这个控件呢,办法是调用 VisualTreeHelper.GetChild(DependencyObject reference, int childIndex)方法。可以使用递归来完成这个步骤:

 

 

    public partial class MainPage : PhoneApplicationPage
    {
        // 绑定的数据集合
        public ObservableCollection<Item> Items { get; set; }
        // 数据加载的标识
        public bool IsLoading = false;
        // 线程锁的对象
        private object o = new object();
        // 构造函数
        public MainPage()
        {
            InitializeComponent();
            // 列表初始化加载100个数据项
            Items = new ObservableCollection<Item>();
            for (int i = 0; i < 100; i++)
            {
                Items.Add(new Item { FirstName = "Li" + i, LastName = "Lei" + i });
            }
            this.DataContext = this;
        }
        // 页面加载完成,订阅列表的ItemRealized事件
        private void PhoneApplicationPage_Loaded_1(object sender, RoutedEventArgs e)
        {
            lls.ItemRealized += lls_ItemRealized;
        }
        // ItemRealized事件处理程序,在这里判断刷新的时机
        void lls_ItemRealized(object sender, ItemRealizationEventArgs e)
        {
            // 因为该事件会被多个线程进入,所以添加线程锁,控制下面的代码只能单个线程去执行
            lock (o)
            {
                if (!IsLoading)
                {
                    if (e.ItemKind == LongListSelectorItemKind.Item)
                    {
                        if ((e.Container.Content as Item).Equals(lls.ItemsSource[lls.ItemsSource.Count - 1]))
                        {
                            // 设置IsLoading为true,在加载数据的过程中,禁止多次进入
                            IsLoading = true;
                            // 显示系统托盘的进度条
                            Microsoft.Phone.Shell.ProgressIndicator progressIndicator = new Microsoft.Phone.Shell.ProgressIndicator();
                            Microsoft.Phone.Shell.SystemTray.ProgressIndicator = progressIndicator;
                            progressIndicator.Text = "加载中...";
                            progressIndicator.IsIndeterminate = true;
                            progressIndicator.IsVisible = true;
                            // 模拟后台耗时任务拉取数据的场景
                            Task.Factory.StartNew(async () =>
                            {
                                await Task.Delay(3000);
                                // 调用UI线程添加数据
                                this.Dispatcher.BeginInvoke(() =>
                                {
                                    int count = Items.Count;
                                    for (int i = count; i < count + 50; i++)
                                    {
                                        Items.Add(new Item { FirstName = "Li" + i, LastName = "Lei" + i });
                                    }
                                    // 关闭进度条
                                    progressIndicator.IsVisible = false;
                                    // 修改加载的状态
                                    IsLoading = false;
                                });
                            });
                        }
                    }
                }
            }
        }
    }

图片 1图片 2View Code 

图片 3

 1 public static UIElement FindElementRecursive(FrameworkElement parent, Type targetType)
 2         {
 3             int childCount = VisualTreeHelper.GetChildrenCount(parent);
 4             UIElement returnElement = null;
 5             if (childCount > 0)
 6             {
 7                 for (int i = 0; i < childCount; i++)
 8                 {
 9                     Object element = VisualTreeHelper.GetChild(parent, i);
10                     if (element.GetType() == targetType)
11                     {
12                         return element as UIElement;
13                     }
14                     else
15                     {
16                         returnElement = FindElementRecursive(VisualTreeHelper.GetChild(parent, i) as FrameworkElement, targetType);
17                     }
18                 }
19             }
20             return returnElement;
21

 

下一篇:没有了
友情链接: 网站地图
Copyright © 2015-2019 http://www.zen-40.com. mgm美高梅有限公司 版权所有