WP7 ListBox使用总结

mac2022-06-30  81

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;    }  }}

 

转载于:https://www.cnblogs.com/IronSword/archive/2012/04/12/2444210.html

最新回复(0)