长长的名单选择观察的集合和Visual树 - 问题? [英] Long List Selector Observable Collection and Visual Tree - problems?

查看:136
本文介绍了长长的名单选择观察的集合和Visual树 - 问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




   我做了一个简单的例子来说明,我已经encoutered一些问题。他们concers LongsListSelector必然的ObservableCollection(不管项目是什么类型)。我设置了一长串的项目模板(比如)一个文本块,我也做了三个按钮 - 一个元素添加到收藏,除去最后一个,并通过visuall树进行搜索。在code是没有这么长,所以我会后在这里下面(如果你想整个例如它在:的http:/ /sdrv.ms/163TYEG )。


XAML(除了头):

 <电话:PhoneApplicationPage.Resources>
    <的DataTemplate X:键=ElementStyle>
        < TextBlock的X:名称=elemBlck文本=元素/>
    < / DataTemplate中>
< /电话:PhoneApplicationPage.Resources>
<电网X:NAME =LayoutRoot背景=透明>
    < Grid.RowDefinitions>
        < RowDefinition HEIGHT =30 */>
        < RowDefinition HEIGHT =30 */>
        < RowDefinition HEIGHT =30 */>
    < /Grid.RowDefinitions>
    < Grid.ColumnDefinitions>
        < ColumnDefinition WIDTH =70 */>
        < ColumnDefinition WIDTH =30 */>
    < /Grid.ColumnDefinitions>    &所述;按钮X:名称=addBtn内容=添加Grid.Row =0Grid.Column =1/>
    <按钮X:NAME =delBtnCONTENT =删除Grid.Row =1Grid.Column =1/>
    <按钮X:NAME =showBtnCONTENT =显示Grid.Row =2Grid.Column =1/>
    <电话:LongListSelector X:NAME =phoneLLS的Horizo​​ntalAlignment =左HEIGHT =700保证金=0Grid.Row =0
                            VerticalAlignment =评出的Grid.RowSpan =3Grid.Column =0WIDTH =300
                            LayoutMode =网格GridCellSize =300100IsGroupingEnabled =FALSE
                            的ItemTemplate ={StaticResource的ElementStyle}/>
< /网格和GT;

和C#:

 公共部分类的MainPage:的PhoneApplicationPage
 {
  私人的ObservableCollection<串GT;收集=新的ObservableCollection<串GT;();  公众的MainPage()
  {
     的InitializeComponent();
     phoneLLS.ItemsSource =收集;
     addBtn.Click + = addBtn_Click;
     delBtn.Click + = delBtn_Click;
     showBtn.Click + = showBtn_Click;
  }  私人无效addBtn_Click(对象发件人,RoutedEventArgs E)
  {
     collection.Add(元素);
  }  私人无效delBtn_Click(对象发件人,RoutedEventArgs E)
  {
     collection.RemoveAt(collection.Count - 1);
  }  私人无效showBtn_Click(对象发件人,RoutedEventArgs E)
  {
     清单<&的TextBlock GT; controlList =新的List<&的TextBlock GT;();
     SearchForControls<&的TextBlock GT;(phoneLLS,楼盘controlList);
  }  私有静态无效SearchForControls< T>(DependencyObject的父母,裁判名单< T> controlList)其中T:DependencyObject的
  {
     INT numberOfChildreen = VisualTreeHelper.GetChildrenCount(父);
     的for(int i = 0; I< numberOfChildreen;我++)
     {
        VAR孩子= VisualTreeHelper.GetChild(父母,我);        如果(孩子T)
           controlList.Add((T)的孩子);
        否则SearchForControls< T>(儿童,REF controlList);
     }
  }
}

在哪里问题?


  1. 当我按下按钮添加,收集由一个元素放大。好吧,我看到它becouse元素项中加入LLS。但是,试图将更多。之后,一键之内将一些元素出现?怎么了?收藏是一个元素,但扩大LLS快得多填充。


  2. 与删除一样 - 它删除一个元素,但是从LLS一组项目有时dissapear


  3. 和存在的主要问题 - 在切换的showBtn_Click第二行断点。添加一定元素,尝试搜索可视化树(按显示按钮)。调试停止,第二行之后你看到的可视化树(从collection.Count不同)内的元素的确切NUMER。第二大的惊喜 - 当你删除的连接元素,并再次搜索可视化树,然后你会看到:收集是decresed(这是正确的),由LLS dissapeard一些元素(如果有一个),以及! - 视觉树中的元素的数量并没有改变(!)。怎么了?

    这些是某种错误的?或者,也许我不明白的地方?



解决方案

我也做了一些进一步的研究 - 如果你重新输入LLS一切的页面更新正确的 - 视觉树有很多元素,比如集合。我修改一个例子( http://sdrv.ms/169kRqI ):

让我们Main_Page的second_page:

XAML中:

 <电话:PhoneApplicationPage.Resources>
    <的DataTemplate X:键=ElementStyle>
        < TextBlock的X:名称=elemBlck文本=元素/>
    < / DataTemplate中>
< /电话:PhoneApplicationPage.Resources>
<电网X:NAME =LayoutRoot背景=透明>
    < Grid.RowDefinitions>
        < RowDefinition HEIGHT =30 */>
        < RowDefinition HEIGHT =30 */>
        < RowDefinition HEIGHT =30 */>
    < /Grid.RowDefinitions>
    < Grid.ColumnDefinitions>
        < ColumnDefinition WIDTH =70 */>
        < ColumnDefinition WIDTH =30 */>
    < /Grid.ColumnDefinitions>    &所述;按钮X:名称=addBtn内容=添加Grid.Row =0Grid.Column =1/>
    <按钮X:NAME =delBtnCONTENT =删除Grid.Row =1Grid.Column =1/>
    <按钮X:NAME =showBtnCONTENT =显示Grid.Row =2Grid.Column =1/>
    <电话:LongListSelector X:NAME =phoneLLS的Horizo​​ntalAlignment =左HEIGHT =700保证金=0Grid.Row =0
                            VerticalAlignment =评出的Grid.RowSpan =3Grid.Column =0WIDTH =300
                            LayoutMode =网格GridCellSize =300100IsGroupingEnabled =FALSE
                            的ItemTemplate ={StaticResource的ElementStyle}的ItemsSource ={结合}/>< /网格和GT;

背后code:

 公共部分类second_page:的PhoneApplicationPage
{
  公共second_page()
  {
     的InitializeComponent();
     phoneLLS.DataContext = MainPage.collection;
     addBtn.Click + = addBtn_Click;
     delBtn.Click + = delBtn_Click;
     showBtn.Click + = showBtn_Click;
  }  私人无效addBtn_Click(对象发件人,RoutedEventArgs E)
  {
     MainPage.collection.Add(元素);
  }  私人无效delBtn_Click(对象发件人,RoutedEventArgs E)
  {
     MainPage.collection.RemoveAt(MainPage.collection.Count - 1);
  }  私人无效showBtn_Click(对象发件人,RoutedEventArgs E)
  {
     清单<&的TextBlock GT; controlList =新的List<&的TextBlock GT;();
     SearchForControls<&的TextBlock GT;(phoneLLS,楼盘controlList);
  }  私有静态无效SearchForControls< T>(DependencyObject的父母,裁判名单< T> controlList)其中T:DependencyObject的
  {
     INT numberOfChildreen = VisualTreeHelper.GetChildrenCount(父);
     的for(int i = 0; I< numberOfChildreen;我++)
     {
        VAR孩子= VisualTreeHelper.GetChild(父母,我);        如果(孩子T)
           controlList.Add((T)的孩子);
        否则SearchForControls< T>(儿童,REF controlList);
     }
  }
}

和Main_Page - 只有导航:

XAML中:

 <电网X:NAME =LayoutRoot背景=透明>
    <按钮X:NAME =GotoPage记述CONTENT =SecondPageWIDTH =自动HEIGHT =自动
            的Horizo​​ntalAlignment =中心VerticalAlignment =中心/>
< /网格和GT;

背后code:

 公共部分类的MainPage:的PhoneApplicationPage
{
  公共静态的ObservableCollection<串GT;收集=新的ObservableCollection<串GT;();  公众的MainPage()
  {
     的InitializeComponent();
     goToPage.Click + = goToPage_Click;
  }  私人无效goToPage_Click(对象发件人,RoutedEventArgs E)
  {
     NavigationService.Navigate(新的URI(/ second_page.xaml,UriKind.Relative));
  }
}

刚刚尝试做相同的,并无需重新输入页面:


  1. 添加例如3元素,在调试的showBtn_Click第二行切换断点并点击布敦 - 它会显示6元!不要触摸除回去什么。


  2. 重新输入的第二页 - 你本身正确的LLS - 3元素单击showBtn与断点,你会看到3个元素在可视化树

    有人试过吗?




I've made a short example to show where I've encoutered some problems. They concers LongsListSelector bound to ObservableCollection (no matter what type items are). I've set long list item template as (for example) a textblock, I've also made three buttons - to add one element to collection, to remove one last, and to search through visuall tree. The code is not so long so I'll post it here below (if you want whole example it's at: http://sdrv.ms/163TYEG ).

XAML (except headers):

    <phone:PhoneApplicationPage.Resources>
    <DataTemplate x:Key="ElementStyle">
        <TextBlock x:Name="elemBlck" Text="Element"/>
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>
<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="30*"/>
        <RowDefinition Height="30*"/>
        <RowDefinition Height="30*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="70*"/>
        <ColumnDefinition Width="30*"/>
    </Grid.ColumnDefinitions>

    <Button x:Name="addBtn" Content="Add" Grid.Row="0" Grid.Column="1"/>
    <Button x:Name="delBtn" Content="Del" Grid.Row="1" Grid.Column="1"/>
    <Button x:Name="showBtn" Content="Show" Grid.Row="2" Grid.Column="1"/>       
    <phone:LongListSelector x:Name="phoneLLS" HorizontalAlignment="Left" Height="700" Margin="0" Grid.Row="0" 
                            VerticalAlignment="Top" Grid.RowSpan="3" Grid.Column="0" Width="300"
                            LayoutMode="Grid" GridCellSize="300,100" IsGroupingEnabled="False"
                            ItemTemplate="{StaticResource ElementStyle}" />
</Grid>

and C#:

 public partial class MainPage : PhoneApplicationPage
 {
  private ObservableCollection<string> collection = new ObservableCollection<string>();

  public MainPage()
  {
     InitializeComponent();
     phoneLLS.ItemsSource = collection;
     addBtn.Click += addBtn_Click;
     delBtn.Click += delBtn_Click;
     showBtn.Click += showBtn_Click;
  }

  private void addBtn_Click(object sender, RoutedEventArgs e)
  {
     collection.Add("element");
  }

  private void delBtn_Click(object sender, RoutedEventArgs e)
  {
     collection.RemoveAt(collection.Count - 1);
  }

  private void showBtn_Click(object sender, RoutedEventArgs e)
  {
     List<TextBlock> controlList = new List<TextBlock>();
     SearchForControls<TextBlock>(phoneLLS, ref controlList);
  }

  private static void SearchForControls<T>(DependencyObject parent, ref List<T> controlList) where T : DependencyObject
  {
     int numberOfChildreen = VisualTreeHelper.GetChildrenCount(parent);
     for (int i = 0; i < numberOfChildreen; i++)
     {
        var child = VisualTreeHelper.GetChild(parent, i);

        if (child is T)
           controlList.Add((T)child);
        else SearchForControls<T>(child, ref controlList);
     }
  }
}

Where are problems?

  1. When I push button 'add', the collection is enlarged by one element. Ok, I see it becouse element item is added in LLS. But try to push it more. After that within one button push few elements appear? What's wrong? Collection is enlarged by one element but LLS is populated much faster.

  2. The same with delete - it deletes one element but from LLS a group of items sometimes dissapear.

  3. And the main problem - toggle a breakpoint at second line of showBtn_Click. Add some elements, try to search visual tree (push show button). The debug stops and after the second line you see the exact numer of elements within the visual tree (which differs from collection.Count). And the second big surprise - when you delete en element, and search once again visual tree, then you'll see that: collection was decresed (which is right), some elements dissapeard from LLS (should one), and! - the number of Visual tree elements didn't changed (!). What's wrong?

    Are these some kind of a bug? Or maybe I don't understand something?

解决方案

I've also made some further research - that if you reenter the page with LLS everything is updated correct - Visual tree has that many elements like collection. I've modified an example (http://sdrv.ms/169kRqI ):

Let's make Main_Page the second_page:

Xaml:

<phone:PhoneApplicationPage.Resources>
    <DataTemplate x:Key="ElementStyle">
        <TextBlock x:Name="elemBlck" Text="Element"/>
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>
<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="30*"/>
        <RowDefinition Height="30*"/>
        <RowDefinition Height="30*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="70*"/>
        <ColumnDefinition Width="30*"/>
    </Grid.ColumnDefinitions>

    <Button x:Name="addBtn" Content="Add" Grid.Row="0" Grid.Column="1"/>
    <Button x:Name="delBtn" Content="Del" Grid.Row="1" Grid.Column="1"/>
    <Button x:Name="showBtn" Content="Show" Grid.Row="2" Grid.Column="1"/>
    <phone:LongListSelector x:Name="phoneLLS" HorizontalAlignment="Left" Height="700" Margin="0" Grid.Row="0" 
                            VerticalAlignment="Top" Grid.RowSpan="3" Grid.Column="0" Width="300"
                            LayoutMode="Grid" GridCellSize="300,100" IsGroupingEnabled="False"
                            ItemTemplate="{StaticResource ElementStyle}" ItemsSource="{Binding}"/>

</Grid>

code behind:

public partial class second_page : PhoneApplicationPage
{
  public second_page()
  {
     InitializeComponent();
     phoneLLS.DataContext = MainPage.collection;
     addBtn.Click += addBtn_Click;
     delBtn.Click += delBtn_Click;
     showBtn.Click += showBtn_Click;
  }

  private void addBtn_Click(object sender, RoutedEventArgs e)
  {
     MainPage.collection.Add("element");
  }

  private void delBtn_Click(object sender, RoutedEventArgs e)
  {
     MainPage.collection.RemoveAt(MainPage.collection.Count - 1);
  }

  private void showBtn_Click(object sender, RoutedEventArgs e)
  {
     List<TextBlock> controlList = new List<TextBlock>();
     SearchForControls<TextBlock>(phoneLLS, ref controlList);
  }

  private static void SearchForControls<T>(DependencyObject parent, ref List<T> controlList) where T : DependencyObject
  {
     int numberOfChildreen = VisualTreeHelper.GetChildrenCount(parent);
     for (int i = 0; i < numberOfChildreen; i++)
     {
        var child = VisualTreeHelper.GetChild(parent, i);

        if (child is T)
           controlList.Add((T)child);
        else SearchForControls<T>(child, ref controlList);
     }
  }
}

and Main_Page - only navigation:

Xaml:

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Button x:Name="goToPage" Content="SecondPage" Width="Auto" Height="Auto"
            HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>

Code behind:

public partial class MainPage : PhoneApplicationPage
{
  public static ObservableCollection<string> collection = new ObservableCollection<string>();

  public MainPage()
  {
     InitializeComponent();
     goToPage.Click+=goToPage_Click;
  }

  private void goToPage_Click(object sender, RoutedEventArgs e)
  {
     NavigationService.Navigate(new Uri("/second_page.xaml", UriKind.Relative));
  }
}

Just try to do the same with and without reentering the page:

  1. add for example 3 elements, with debugger toggle a breakpoint at second line of showBtn_Click and Click the buton - it will show 6 elements! Do not touch anything except go back.

  2. Reenter the second page - you will se the correct LLS - with 3 elements as you click showBtn with breakpoint you will see 3 elements in the Visual Tree.

    Anybody tried this?

这篇关于长长的名单选择观察的集合和Visual树 - 问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆