Wpf Xbap TreeView VirtualizingStackPanel 错误?
我有一个带有 VirtualizingStackPanel 的 TreeView。 TreeView 有一个“Level 1”TreeViewItem,我将此 TreeViewItem 绑定到一个 10k 项目列表。每个子项也是另一个 TreeViewItem。
虚拟化效果很好,性能也很棒,但有一个大问题。假设我位于页面顶部并按 Ctrl-End 到达底部,浏览器变为空白。如果我稍微滚动鼠标或调整浏览器大小,它就会重新出现。
另一个大问题是:当我快速滚动到树的中间或底部时。假设我停在项目编号 5000 处。然后我无法展开子树视图项目,浏览器只是 在我滚动或调整大小之前什么也不显示。
非常感谢任何帮助。下面是示例 xaml 和代码:
<Page x:Class="WpfBrowserApplication3.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:s="clr-namespace:WpfBrowserApplication3"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="Page1" DataContext="{StaticResource _mainViewModel}">
<Page.Resources>
<s:SingleToCollectionConverter x:Key="_collectionConverter"></s:SingleToCollectionConverter>
<DataTemplate x:Key="_level2Template">
<TreeViewItem Header="{Binding Order}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Order: "></TextBlock>
<TextBox Text="{Binding Order}"></TextBox>
</StackPanel>
</TreeViewItem>
</DataTemplate>
</Page.Resources>
<TreeView VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Standard">
<TreeViewItem Header="Level 1" ItemsSource="{Binding Level2List}" ItemTemplate="{StaticResource _level2Template}"></TreeViewItem>
</TreeView>
</Page>
public class MainViewModel
{
public MainViewModel()
{
Level2List = new List<Level2>();
for (int i = 0; i < 10000; i++)
{
Level2List.Add(new Level2(i));
}
}
public List<Level2> Level2List { get; set; }
}
public class Level2
{
public Level2(int order)
{
Order = order;
}
public int Order { get; set; }
}
我将 Visual Studio 2010 与 .Net 4 一起使用。另外,我确实注意到如果我设置高度和高度, _level2Template 下 TreeViewItem 的宽度,问题消失了。但在我的情况下,设置高度不是一个选项,因为高度在实际应用程序中会有所不同。
更新:对我来说,发生这个问题似乎很明显,因为子树视图项的高度可能会有所不同。也许这就是为什么 VirtualizingStackPanel 在 TreeView 中默认不打开,但在 DataGrid & 中默认打开的原因。列表框。不用说,数据网格或列表框项目的高度通常是不变的。
更新:我下载了 telerik RadTreeView 的免费试用版并测试了虚拟化。在telerik radtreeview中根本不会出现这个问题。可能会再测试一下 Telerik,然后就可以使用它了。
I have a TreeView with VirtualizingStackPanel on. The TreeView has a "Level 1" TreeViewItem, and I bind this TreeViewItem to a 10k items list. Each children is also another TreeViewItem.
Virtualization works well, and the performance is great, but there is a big issue. Let's say I am at the top of the page and press Ctrl-End to get to the bottom, browser goes blank. It will reappear if I scroll the mouse a bit or resize the browser.
Another big issue is: when i scroll very fast to the middle or the bottom of the tree. let's say I stop at item number 5000. Then I can't expand the child treeviewitem, the browser just
shows nothing until I scroll or resize a bit.
Any help is very much appreciated. Below is the sample xaml & code:
<Page x:Class="WpfBrowserApplication3.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:s="clr-namespace:WpfBrowserApplication3"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="Page1" DataContext="{StaticResource _mainViewModel}">
<Page.Resources>
<s:SingleToCollectionConverter x:Key="_collectionConverter"></s:SingleToCollectionConverter>
<DataTemplate x:Key="_level2Template">
<TreeViewItem Header="{Binding Order}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Order: "></TextBlock>
<TextBox Text="{Binding Order}"></TextBox>
</StackPanel>
</TreeViewItem>
</DataTemplate>
</Page.Resources>
<TreeView VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Standard">
<TreeViewItem Header="Level 1" ItemsSource="{Binding Level2List}" ItemTemplate="{StaticResource _level2Template}"></TreeViewItem>
</TreeView>
</Page>
public class MainViewModel
{
public MainViewModel()
{
Level2List = new List<Level2>();
for (int i = 0; i < 10000; i++)
{
Level2List.Add(new Level2(i));
}
}
public List<Level2> Level2List { get; set; }
}
public class Level2
{
public Level2(int order)
{
Order = order;
}
public int Order { get; set; }
}
I use Visual Studio 2010 with .Net 4. Plus I did notice if I set the Height & Width for the TreeViewItem under _level2Template, the issue is gone. But setting the Height is not an option in my case, cause the Height varies in the real Application.
Updated: It seems quite obvious to me that this issue happened because the height of the child treeviewitem may vary. Perhaps that's the reason why VirtualizingStackPanel is not turned on by default in TreeView, but it is turned on by default in DataGrid & ListBox. Needless to say the Height of a datagrid or listbox item is usually unchanged.
Updated: I downloaded a free trial of telerik RadTreeView and tested the virtualization. This problem does not appear at all in telerik radtreeview. May test the telerik one a little more then probably go with it then.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
发现这个:TreeView 虚拟化
同样的问题,TreeView 没有解决方案。唯一的方法是按照 http://www.beacosta 中的建议使用 ListBox 而不是 TreeView .com/blog/?p=45
很确定这是 TreeView 错误。我尝试过 Telerik RadTreeView,它在打开虚拟化时也有自己的错误。我将改为使用 ListBox。
Found this: TreeView Virtualization
Same issue, and no solution for TreeView. Only way around is to use the ListBox instead of TreeView as suggested in http://www.beacosta.com/blog/?p=45
Pretty sure this is TreeView bug. I have tried Telerik RadTreeView and it also has its own bug when turn on Virtulization. I will change to use ListBox instead.