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


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

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

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

    View Code 
     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

    其中参数第一个是你放入的控件,本文中就是LongListSelector或者ListBox,第二个参数是你希望找到的控件,本文中就是ScrollViewer。 

    找到之后就是计算偏移量了,对于ListBox来说是比较简单的。ListBox有一个Items属性,会获取它包含的所有的Item条目,因此只需要for循环Items,找到和TextBox值一样的Item就可以算出偏移量了,这个偏移量for中的那个自增值。对于LongListSelector会比较麻烦些,因为LongListSelector的ItemsSource是个两层的集合,下面的代码会展示如何获取LongListSelector中的偏移量,这个例子是一个国家代码展示的LongListSelector,Group的GroupItemTemplate的值显示的是a到z的26个字母,而ItemTemplate中显示的值是国家代码和国家名称,例如:+1 美国。代码中CountryCode是一个自定义类型,包含了国家代码中的ID(国家缩写,例如中国是CN)。CountryCodeInGroup也是一个自定义类型,它是一个List<CountryCode>类型,其中还有一个属性是Key,它代表着a到z的26个字母。LongListSelectorSource同样是自定义类型,它是一个List<CountryCodeInGroup>类型,这样就组成了如图所示的结构:

     

    View Code 
     1 double offset = -2.5;//2.5为修正量
     2             bool find = false;
     3 
     4             foreach (CountryCodeInGroup countryCodeInGroup in LongListSelectorSource)
     5             {
     6                 if (find == truebreak;
     7                 if (countryCodeInGroup.Key == inputCountryCode.ID.Substring(0,1).ToLower())
     8                 {
     9                     foreach (CountryCode countryCode in countryCodeInGroup)
    10                     {
    11                         if (countryCode.ID == inputCountryCode.ID)
    12                         {
    13                             find = true;
    14                             break;
    15                         }
    16                         else
    17                         {
    18                             offset += 1;
    19                         }
    20                     }
    21                 }
    22                 else
    23                 {
    24                     if (countryCodeInGroup.Count != 0)
    25                     {
    26                         offset += countryCodeInGroup.Count + 1;
    27                     }
    28                 }
    29

    最后一步:ScrollViewer.ScrollToVerticalOffset(offset);  

    这个时候可能会考虑一个问题,就是我们在工作日很多时候是在DataTemplate中做些文章,如果我的DataTemplate做的很复杂会影响这个偏移量嘛?答案是不会的,不论是ListBox还是LongListSelector,我们计算的offset实际上都是一个Item的index。

    最后说明几点:

    1、发现2.5这个修正值似乎在ListBox和LongListSelector都通用,这个值是我肉眼修正的。

    2、LongListSelector其实有个  LongListSelector.ScrollTo(object item)方法,但是因为在做的时候没有找到合适的item,理论上将这个item可以是第二段代码中所写的一个CountryCode。

    3、吐槽一下LongListSelector.GetItemsWithContainers方法。

     
  • 相关阅读:
    利用UncaughtExceptionHandler捕获未try...catch到的异常
    nodejs
    angularjs异步处理 $q.defer()
    springboot集成swagger
    面试相关
    springboot注解
    关于自动拆装箱
    sonar集成搭建
    Predicate 类
    idea快捷键
  • 原文地址:https://www.cnblogs.com/klkucan/p/2301320.html
Copyright © 2020-2023  润新知