长列表选择器可观察集合和可视化树 - 问题? [英] Long List Selector Observable Collection and Visual Tree - problems?

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

问题描述



我做了一个简短的例子来说明我在哪里遇到了一些问题.他们将 LongsListSelector 绑定到 ObservableCollection (无论项目是什么类型).我已经将长列表项模板设置为(例如)一个文本块,我还制作了三个按钮 - 将一个元素添加到集合中,删除最后一个元素,以及搜索可视化树.代码不是很长,所以我会在下面发布它(如果你想要完整的例子,它位于:http://sdrv.ms/163TYEG).

XAML(标头除外):



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>

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

问题出在哪里?

  1. 当我按下添加"按钮时,集合会放大一个元素.好的,我看到它是因为在 LLS 中添加了元素项.但是尝试更多地推动它.之后,一键按下几个元素出现?怎么了?集合扩大了一个元素,但 LLS 的填充速度要快得多.

  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.

与删除相同 - 它删除一个元素,但有时会从 LLS 中删除一组项目.

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

主要问题 - 在 showBtn_Click 的第二行切换断点.添加一些元素,尝试搜索可视化树(按下显示按钮).调试停止,在第二行之后,您会看到可视化树中元素的确切数量(与 collection.Count 不同).第二个大惊喜 - 当您删除 en 元素并再次搜索可视化树时,您会看到:集合被减少(这是正确的),一些元素从 LLS 中消失(应该是),并且!- 视觉树元素的数量没有改变(!).怎么了?

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?

推荐答案

我还做了一些进一步的研究——如果你用 LLS 重新进入页面,一切都会正确更新——Visual tree 有很多元素,比如集合.我修改了一个例子(http://sdrv.ms/169kRqI ):

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 ):

让我们将 Main_Page 设为 second_page:

Let's make Main_Page the second_page:

XML:

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

背后的代码:

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

和 Main_Page - 仅导航:

and Main_Page - only navigation:

XML:

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

背后的代码:

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. 例如添加 3 个元素,使用调试器在 showBtn_Click 的第二行切换断点并单击按钮 - 它将显示 6 个元素!除了回去别碰任何东西.

  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.

重新进入第二页 - 您将看到正确的 LLS - 当您单击带有断点的 showBtn 时,您将看到 3 个元素在可视化树中.

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.

有人试过吗?

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

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