2011-11-20 33 views
36

Tôi đang cố gắng để ràng buộc một bộ sưu tập lớn để một ComboBox và tôi phải đối mặt với vấn đề hiệu suất khi mở popup của ComboBox. Tôi đã tìm kiếm trên internet và thấy rằng việc sử dụng VirtualizingStackPanel như một mẫu bảng điều khiển các mục có thể hữu ích, nhưng nó chỉ giúp một phần. Nếu tôi liên kết một bộ sưu tập lớn với một ComboBox, tôi có thể mở popup rất nhanh, đó là ok, nhưng nếu sau đó tôi ràng buộc một bộ sưu tập khác vào một ComboBox và cố gắng mở popup một lần nữa, nó trở nên rất chậm. Tương tự đang xảy ra nếu bạn mở popup cho một ComboBox rỗng, sau đó ràng buộc bộ sưu tập lớn và cố gắng để mở popup một lần nữa - phải mất một vài giây trước khi popup mở ra.WPF ComboBox vấn đề hiệu suất bằng cách ràng buộc một bộ sưu tập lớn

Đây là XAML:

<ComboBox Name="cbBlah"> 
    <ComboBox.ItemsPanel> 
     <ItemsPanelTemplate> 
      <VirtualizingStackPanel /> 
     </ItemsPanelTemplate> 
    </ComboBox.ItemsPanel> 
</ComboBox> 

và mã mẫu cho ràng buộc để tạo lại vấn đề:

var list = new List<string>(); 
for (var i = 0; i < new Random().Next(9000, 10000); i++) 
    list.Add(i.ToString()); 
cbBlah.ItemsSource = list; 

tôi đã cố gắng để làm cho việc ảo hóa ngăn xếp bảng trông như thế này:

<VirtualizingStackPanel VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" /> 

nhưng không hiệu quả, có vẻ như VirtualizationMode bị bỏ qua vì vậy cửa sổ bật lên mở nhanh rất nhanh lần đầu tiên và sau đó, mỗi lần sau khi thay đổi ràng buộc, nó rất chậm.

CẬP NHẬT: Tôi đã nghĩ về việc không ràng buộc bộ sưu tập mới mỗi lần, nhưng liên kết một ObservableCollection một lần và sau đó chỉ thay đổi nội dung của nó. Cùng một điều, càng sớm càng nội dung thay đổi bộ sưu tập, mở một popup vẫn phải mất vài giây :(

+0

hãy nhìn vào những câu hỏi mà tôi đã trả lời http://stackoverflow.com/a/8555403/920384 – punker76

Trả lời

79

Theo blog này: http://vbcity.com/blogs/xtab/archive/2009/12/15/wpf-using-a-virtualizingstackpanel-to-improve-combobox-performance.aspx

Tôi đã thử nghiệm nó với mã này:

<ComboBox Name="cbBlah" ItemsSource="{Binding}"> 
    <ComboBox.ItemsPanel> 
     <ItemsPanelTemplate> 
      <VirtualizingStackPanel /> 
     </ItemsPanelTemplate> 
    </ComboBox.ItemsPanel> 
</ComboBox> 

nó hoạt động tốt cho lần đầu tiên và lần tiếp theo nó không phải là cần thiết để mã hóa những dòng này:..

<VirtualizingStackPanel VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" /> 

tôi hy vọng điều này sẽ giúp bạn

+0

đang Vậy ít và hoạt động giống như một nét duyên dáng! – Tafari

+0

Bạn, thưa bạn, là một thiên tài! Điều này tạo ra sự khác biệt về hiệu suất rất lớn đối với tôi, và việc sửa chữa rất thanh lịch và đơn giản. Cảm ơn! :) – dbeachy1

+1

Có thể thực hiện điều này bằng mã C# không? Tôi đang triển khai một lớp có nguồn gốc từ Combobox, và tôi muốn thiết lập nó ở đây. – jonas

0

Tôi cũng gặp sự cố này. Tôi đang sử dụng mã này trong một hộp combo tùy chỉnh với một mẫu kiểu. Khi tôi chạy mã của tôi trong chế độ gỡ lỗi VS, ảo hóa không hoạt động đúng cách. Khi tôi chạy nó bên ngoài gỡ lỗi, tôi có thể chuyển nội dung của ObservableCollection mà không khóa giao diện người dùng. Nó cũng có thể hữu ích nếu bạn đặt chiều cao tối đa và chiều rộng tối đa.

<Setter Property="ScrollViewer.CanContentScroll" Value="True"/> 
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/> 
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/> 
<Popup> 
    <Border/> 
    <ScrollViewer> 
     <VirtualizingStackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained"/> 
    </ScrollViewer> 
    </Grid> 
</Popup> 
8

tôi đã có vấn đề với hiệu suất chậm là tốt. Nhưng tôi đã tạo ra một lớp mà kế thừa hình thức Combobox, do đó tôi muốn làm điều này lập trình. Vì vậy, đây là giải pháp cho các googlers khác ra khỏi đó.

ItemsPanel = new ItemsPanelTemplate(); 
var stackPanelTemplate = new FrameworkElementFactory(typeof (VirtualizingStackPanel)); 
ItemsPanel.VisualTree = stackPanelTemplate; 
+0

Đập mã đó vào trong hàm tạo, làm việc rất đẹp. Chúc mừng! – Kris

+0

giải pháp đẹp :) cảm ơn – HuyNA

+0

Tôi biết rằng đây là một bài đăng cũ, nhưng đối với các đồng nghiệp, đây là giải pháp thanh lịch. Tốc độ mọi thứ lên _tremendously_. – Chris

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