zoukankan      html  css  js  c++  java
  • WP7 listbox 总结

    1、XAML文件中配置好ListBox,在CS文件中为相应的ListBox添加ListBoxItem,如果ListBoxItem的数目较多(超过一屏显示),当拖动ListBox到底端,然后跳转到新页面并返回时ListBox会显示空白。

      XAML文件:  

    <Grid>
        <ListBox x:Name="MyListBox"  />
    </Grid>

      CS文件:

    复制代码
    private void AddItems()
    {
        for (int i = 0; i < 50; i++)
        {
            ListBoxItem item = new ListBoxItem();
            TextBlock textBlock = new TextBlock();
            textBlock.Text = i.ToString();
            item.Content = textBlock;
            MyListBox.Items.Add(item);
        }
    }
    复制代码

      原因分析:返回原页面后,ListBox的VerticalOffset与ScrollableHeight值都增加了(超过屏幕高度),所以当用户回到原页面不向上拖动ListBox是无法查看到数据内容的。

      目前解决方法:修改XAML文件,自定义ListBox的Template。 

    复制代码
    <Grid>
        <ListBox x:Name="MyListBox"  >
            <ListBox.Template>
                <ControlTemplate TargetType="ListBox">
                    <ScrollViewer BorderBrush="{TemplateBinding BorderBrush}"  BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"  Foreground="{TemplateBinding Foreground}" Padding="{TemplateBinding Padding}" >
                        <Grid>
                            <ItemsPresenter/>
                        </Grid>
                    </ScrollViewer>
                </ControlTemplate>
            </ListBox.Template>
        </ListBox>
    </Grid>
    复制代码

    2、在ListBox中添加拖动到ListBox底部进行加载数据操作(分页加载):

      常用方法:

      1)通过遍历ListBox的子控件,找到ListBox中自带的ScrollViewer;

        //获取子类型
    public static T FindChildOfType<T>(DependencyObject root) where T : class
    {
    var queue = new Queue<DependencyObject>();
    queue.Enqueue(root);
    while (queue.Count > 0)
    {
    DependencyObject current = queue.Dequeue();
    for (int i = VisualTreeHelper.GetChildrenCount(current) - 1; 0 <= i; i--)
    {
    var child = VisualTreeHelper.GetChild(current, i);
    var typedChild = child as T;
    if (typedChild != null)
    {
    return typedChild;
    }
    queue.Enqueue(child);
    }
    }
    return null;
    }

      2)如果ScrollViewer.VerticalOffset >= ScrollViewer.ScrollableHeight,则已经拖动到ListBox底部;

      为了简单,不用去遍历ListBox获取ScrollViewer,直接在XAML文件修改Template并添加ScrollViewer的拖动方法。

      XAML 文件:

    复制代码
    <Grid>
        <ListBox x:Name="MyListBox"  >
            <ListBox.Template>
                <ControlTemplate TargetType="ListBox">
                    <ScrollViewer BorderBrush="{TemplateBinding BorderBrush}"  
                      BorderThickness="{TemplateBinding BorderThickness}"
                      Background="{TemplateBinding Background}"
                      Foreground="{TemplateBinding Foreground}"
                      Padding="{TemplateBinding Padding}"
                      ManipulationCompleted="ListBox_ManipulationCompleted"> <Grid> <ItemsPresenter/> </Grid> </ScrollViewer> </ControlTemplate> </ListBox.Template> </ListBox> </Grid>
    复制代码

      CS文件:

    复制代码
    private void ListBox_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
    {
      ScrollViewer scrollViewer
    = sender as ScrollViewer;
      
    if (scrollViewer == null)
      {
        return;
      }

      // 如果是向下拖动并且已经在ListBox底端
      if (e.TotalManipulation.Translation.Y < 0 && scrollViewer.VerticalOffset >= scrollViewer.ScrollableHeight)   {   // do something   } }
    复制代码

    3、ListBox分页加载显示最新数据:

      基本思路:对ListBox中ScrollViewer的VerticalOffset进行修改, 在分页加载前先记录VerticalOffset,然后加载完成后根据需要调整VerticalOffset值。

      实际操作中发现分页加载完成后,ListBox中的ScrollViewer的ScrollableHeight并没有及时发生变化,因此调整VerticalOffset值并不起作用,用户仍然需要拖动屏幕才能看到最新加载的数据。

    由于对ListBox与ScrollViewer内部机制了解不够,最后只能采用在LayoutUpdated中监控ScrollViewer的ScrollableHeight是否发生变化,如果发生变化则立即调整ScrollViewer的VerticalOffset值。

      XAML文件 :

    复制代码
    <Grid>
        <ListBox x:Name="MyListBox"  >
            <ListBox.Template>
                <ControlTemplate TargetType="ListBox">
                    <ScrollViewer BorderBrush="{TemplateBinding BorderBrush}"  
                      BorderThickness="{TemplateBinding BorderThickness}" 
                      Background="{TemplateBinding Background}"  
                      Foreground="{TemplateBinding Foreground}" 
                      Padding="{TemplateBinding Padding}" 
                      LayoutUpdated="ListBox_LayoutUpdated"                   ManipulationCompleted
    ="ListBox_ManipulationCompleted"> <Grid> <ItemsPresenter/> </Grid> </ScrollViewer> </ControlTemplate> </ListBox.Template> </ListBox> </Grid>
    复制代码

      CS文件:

    复制代码
    private double currentVerticalOffset = 0.0d;
    private ScrollViewer myScrollViewer = null;
    private
    double scrollableHeight = 0.0d;

    private
    void ListBox_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) {   ScrollViewer scrollViewer = sender as ScrollViewer;   if (scrollViewer == null)   {     return;   }

      if (myScrollViewer == null)
      {
        myScrollViewer = scrollViewer;
      }   
    // 如果是向下拖动并且已经在ListBox底端   if (e.TotalManipulation.Translation.Y < 0 && scrollViewer.VerticalOffset >= scrollViewer.ScrollableHeight)   {
        // 记录当前偏移值
        currentVerticalOffset = scrollViewer.VerticalOffset;   
    // do something   } }

    private void ListBox_LayoutUpdated(object sender, EventArgs e)
    {
      
    if (myScrollViewer != null)
      {
        if (myScrollViewer.ScrollableHeight > scrollableHeight)
        {
          if (scrollableHeight > 0)
          {
            // 设置纵向位置,此处向下拖曳ListBox的实际高度
            myScrollViewer.ScrollToVerticalOffset(currentVerticalOffset + this.MyListBox.ActualHeight);
          }

          scrollableHeight = myScrollViewer.ScrollableHeight;
        }
      }
    }
    复制代码
    http://www.cnblogs.com/IronSword/archive/2012/04/12/2444210.html
  • 相关阅读:
    京东二面面经(07.17 11:30)
    招银三面手撕代码题(字符串连续子串)
    shein二面(31min)
    京东提前批一面
    两个链表的第一个公共结点
    Java并发机制的底层实现原理
    招银网络(二面07.09)
    黑盒测试与白盒测试
    求1+2+...+n(剑指offer-47)
    第一个只出现一次的字符(剑指offer-34)
  • 原文地址:https://www.cnblogs.com/zziss/p/2735884.html
Copyright © 2011-2022 走看看