2013-04-12 29 views
9

Hôm nay tôi đã quyết định thử nghiệm TreeView ảo hóa. Để làm điều đó ràng buộc là bắt buộc. Vì vậy, tôi quyết định để có được 2 điều kiểm tra - HierarchicalDataTemplate dựa trên các loại + ảo hóa.Sự cố cuộn trong TreeView ảo hóa

Tôi đã tạo một lớp cơ sở cho một số dữ liệu. Đã tạo 2 lớp dẫn xuất từ ​​lớp cơ sở. Thực hiện 2 HierarchicalDataTemplate (1 cho mỗi lớp dẫn xuất) để có được định dạng khác nhau của các nút. Và chạy dân số của 10k nút của 2 loại.

Lớp học:

public class ListItem_Generic 
{ 
    public string Name { get; protected set; } 
    public ListItem_Generic(string Name = "") { this.Name = Name; } 
} 

public class ListItem_Single : ListItem_Generic 
{ 
    public ListItem_Single(string Name = "") : base(Name) { } 
} 

public class ListItem_Multi : ListItem_Generic 
{ 
    public List<ListItem_Generic> Items { get; protected set; } 
    public ListItem_Multi(string Name = "", List<ListItem_Generic> Items = null) 
     : base(Name) 
    { 
     if (Items == null) 
      this.Items = new List<ListItem_Generic>(); 
     else 
      this.Items = new List<ListItem_Generic>(Items); 
    } 
} 

Thế hệ của 10k hạch cấp 1 với một số trẻ em, ràng buộc:

public MainWindow() 
    { 
     InitializeComponent(); 

     // Create a list of sample items and populate them 
     var lst = new List<ListItem_Generic>(); 

     int MaxHeaders = 10000; 
     var rnd = new Random(); 
     // Now generate 10 000 records. First select random amount of headers 
     int HeadersCount = rnd.Next(MaxHeaders); 

     for (int i = 0; i < HeadersCount; i++) 
     { 
      var Childrencount = rnd.Next(100); 
      var children = new List<ListItem_Generic>(); 
      for (int j = 0; j < Childrencount; j++) 
       children.Add(new ListItem_Single("Child #"+j+" of parent #"+i)); 
      lst.Add(new ListItem_Multi("Header #" + i + " (" + Childrencount + ")", children)); 
     } 
     for (int i = 0; i < MaxHeaders - HeadersCount; i++) 
      lst.Add(new ListItem_Single("Line #" + i)); 

     // Bind lstView to lst 
     lstView.ItemsSource = lst; 
     lstView.UpdateLayout(); 
    } 

XAML với HierarchicalDataTemplates:

<Window x:Class="Test_DataTemplates.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:loc="clr-namespace:Test_DataTemplates" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <TreeView Name="lstView" VirtualizingPanel.IsVirtualizing="True"> 
      <TreeView.Resources> 
       <HierarchicalDataTemplate DataType="{x:Type loc:ListItem_Multi}" ItemsSource="{Binding Path=Items}"> 
        <Border Background="RosyBrown"> 
         <TextBlock Text="{Binding Path=Name}" Foreground="White" FontWeight="Bold"/> 
        </Border> 
       </HierarchicalDataTemplate> 
       <HierarchicalDataTemplate DataType="{x:Type loc:ListItem_Single}"> 
        <TextBlock Text="{Binding Path=Name}"/> 
       </HierarchicalDataTemplate> 
      </TreeView.Resources> 
     </TreeView> 
    </Grid> 
</Window> 

Mọi thứ hoạt động tinh:

  • treeview được ảo hóa (dễ nhận biết bởi bộ nhớ + thời gian tải)
  • Nodes có nguồn gốc từ các loại được định dạng chính xác

Tuy nhiên, khi di chuyển đến giả tiêu đề # 1000 và mở rộng nó - vị trí cuộn sẽ nhảy đến một số nơi khác làm cho nút mở rộng và các con của nó KHÔNG hiển thị.

Tôi đã làm gì sai? Có cách nào để sửa lỗi này không?

Cập nhật: Xóa ảo hóa cũng sẽ xóa lỗi cuộn.

+0

liên quan: http://stackoverflow.com/questions/4074475/scrolling-bug-in-wpf-virtualized- treeview –

+0

có vấn đề tương tự như ở đây – Laie

+0

@ Jee-heonOh imho, TreeView không phải là quá phù hợp cho ảo hóa. Tôi khuyên bạn nên sử dụng ListBox/ListView để thay thế. Thật dễ dàng để mô phỏng chế độ xem dạng cây thông qua các mẫu và mô phỏng việc mở rộng/thu hẹp cấp bằng cách thêm/xóa các phần tử vào/từ danh sách đồng bộ (có thể quan sát). Có nhiều ví dụ có sẵn của TreeListView. Nếu bạn có xu hướng sử dụng TreeView (lưu ý rằng nó có thể ảo hóa thứ bậc cấp bậc đầu tiên) - xem cách giải quyết trên trang web microsoft, được đăng bởi một trong những người đóng góp. Ông ghi đè một số sự kiện của treeviewitem để đưa nó vào xem theo yêu cầu, giải quyết vấn đề di chuyển. – user2274578

Trả lời

0

thử tắt (không phải trên) Tái chế bài viết

VirtualizingStackPanel.VirtualizationMode="Standard" 

Việc tối ưu hóa đề cập đến biến nó trên

How to: Improve the Performance of a TreeView

+0

Cả hai chế độ Standart và Recycling đều tạo ra lỗi tương tự khi cuộn, Blam. – user2274578

+0

Bắn Tôi sẽ để nó cho đến khi bạn nhận được câu trả lời chỉ để cho mọi người biết đó không phải là câu trả lời. – Paparazzi

0

Tôi đánh giá cao nếu some1 chỉ có thể kiểm tra điều này trong môi trường của họ và xác nhận vấn đề. Ngoài ra, chơi xung quanh một chút tìm thấy một hành vi kỳ lạ:

  • thay đổi chế độ để standart
  • thực hiện IsExpanded hai chiều ràng buộc (không chắc chắn nếu điều này là cần thiết ở tất cả)

chạy Tiếp theo chương trình:

  • Mở rộng tiêu đề với một số lớn, như 1000 - cuộn nhảy tới một số địa điểm khác

Chạy lại chương trình (đối với độ tinh khiết của thí nghiệm)

  • Mở rộng một trong những tiêu đề đầu tiên, giống như # 2.
  • Mở rộng tiêu đề với một số số lượng lớn, giống như 1000 - scroller vẫn ở vị trí thích hợp ...

Mở rộng một trong những nút đầu tiên tìm được một cách giải quyết.

1

Sau khi có nhiều vấn đề với ảo hóa cây trong C# WPF (bao gồm vấn đề chính, chỉ mức đầu tiên được ảo hóa) - tôi không thể tìm được bản sửa lỗi thích hợp. Microsoft đã chấp nhận một báo cáo lỗi và trả lời, vấn đề di chuyển đó sẽ được khắc phục trong một trong các bản phát hành sau này.

Đối với giải pháp cuối cùng cho điều này cho cá nhân tôi - tôi đã chuyển sang thực hiện riêng ListTreeView, tức là sử dụng Danh sách và mô phỏng cây. Điều này giải quyết tất cả các vấn đề với ảo hóa và với hành vi di chuyển. Vấn đề duy nhất là - loại bỏ nhiều mục sau khi thu hẹp nút cây. Tôi đã phải thực hiện kiểm tra xem việc tạo lại danh sách mới dễ dàng/nhanh hơn thay vì xóa các mục 1 theo 1.

0

Tôi đã tìm thấy giải pháp trên MSDN. Rõ ràng nó có một cái gì đó để làm với các mẫu TreeView mặc định. Sau đây sửa thanh cuộn nhấp nháy và dừng các nút ngẫu nhiên mở rộng khi cuộn nhanh.

<Style x:Key="{x:Type TreeView}" TargetType="{x:Type TreeView}"> 
    <Setter Property="TreeView.Background" Value="Transparent"/> 
    <Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/> 
    <Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/> 
    <Setter Property="TreeView.SnapsToDevicePixels" Value="True" /> 
    <Setter Property="TreeView.OverridesDefaultStyle" Value="True" /> 
    <Setter Property="ItemsControl.ItemsPanel"> 
     <Setter.Value> 
      <ItemsPanelTemplate> 
       <VirtualizingStackPanel IsItemsHost="True"/> 
      </ItemsPanelTemplate> 
     </Setter.Value> 
    </Setter> 
    <Setter Property="TreeView.Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="TreeView"> 
       <ScrollViewer Focusable="False" CanContentScroll="True" Padding="4"> 
        <ItemsPresenter HorizontalAlignment="Stretch"/> 
       </ScrollViewer> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Tôi đã thử di chuyển nhanh và dường như không nhận thấy sự cố nữa. Điều tuyệt vời là bạn thậm chí không phải làm đi với ảo hóa của bạn.

+0

Bạn có thể thêm một liên kết đến nơi bạn tìm thấy nó trên MSDN không? Tôi sẽ đặc biệt quan tâm đến các chi tiết cụ thể về nơi mẫu mặc định bị lỗi. –

Các vấn đề liên quan