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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章