Tôi muốn xác minh rằng các mục trong số ListBox
của tôi được hiển thị chính xác trong giao diện người dùng. Tôi đã tìm ra một cách để làm điều này là đi qua tất cả các con của số ListBox
trong cây thị giác, lấy văn bản của chúng, và sau đó so sánh nó với những gì tôi mong đợi văn bản được.Buộc WPF tạo các mục trong một ItemsControl
Vấn đề với cách tiếp cận này là nội bộ ListBox
sử dụng VirtualizingStackPanel
để hiển thị các mục của nó, vì vậy chỉ các mục hiển thị mới được tạo. Cuối cùng tôi đã đi qua lớp ItemContainerGenerator
, có vẻ như nó sẽ buộc WPF tạo các điều khiển trong cây trực quan cho mục được chỉ định. Thật không may, đó là gây ra một số tác dụng phụ lạ đối với tôi. Đây là mã của tôi để tạo ra tất cả các mục trong ListBox
:.
List<string> generatedItems = new List<string>();
IItemContainerGenerator generator = this.ItemsListBox.ItemContainerGenerator;
GeneratorPosition pos = generator.GeneratorPositionFromIndex(-1);
using(generator.StartAt(pos, GeneratorDirection.Forward))
{
bool isNewlyRealized;
for(int i = 0; i < this.ItemsListBox.Items.Count; i++)
{
isNewlyRealized = false;
DependencyObject cntr = generator.GenerateNext(out isNewlyRealized);
if(isNewlyRealized)
{
generator.PrepareItemContainer(cntr);
}
string itemText = GetControlText(cntr);
generatedItems.Add(itemText);
}
}
(tôi có thể cung cấp mã cho GetItemText()
nếu bạn muốn, nhưng nó chỉ đi qua cây thị giác cho đến khi một TextBlock
được tìm thấy tôi nhận ra đó là những cách khác để có văn bản trong một mục, nhưng tôi sẽ sửa chữa điều đó một khi tôi nhận được thế hệ mục hoạt động đúng.)
Trong ứng dụng của tôi, ItemsListBox
chứa 20 mục, với 12 mục đầu tiên nhìn thấy được. Văn bản cho 14 mục đầu tiên là chính xác (có thể do các điều khiển của chúng đã được tạo). Tuy nhiên, đối với các hạng mục 15-20, tôi không nhận được bất kỳ văn bản nào cả. Ngoài ra, nếu tôi cuộn xuống cuối của ItemsListBox
, văn bản của các mục 15-20 cũng trống. Vì vậy, có vẻ như tôi đang can thiệp vào cơ chế bình thường của WPF để tạo ra một số điều khiển như thế nào.
Tôi đang làm gì sai? Có cách nào khác tốt hơn để buộc các mục trong một số ItemsControl
được thêm vào cây trực quan không?
Cập nhật: Tôi nghĩ rằng tôi đã tìm thấy lý do tại sao điều này xảy ra, mặc dù tôi không biết cách khắc phục. Giả định rằng cuộc gọi đến PrepareItemContainer()
sẽ tạo bất kỳ điều khiển cần thiết nào để hiển thị mục và sau đó thêm vùng chứa vào cây trực quan ở vị trí chính xác. Nó chỉ ra rằng nó không phải là làm một trong những điều này. Vùng chứa không được thêm vào ItemsControl
cho đến khi tôi cuộn xuống để xem nó và tại thời điểm đó chỉ có chính vùng chứa (tức là ListBoxItem
) được tạo ra - con của nó không được tạo (có một vài điều khiển được thêm vào đây, một trong số đó phải là TextBlock
sẽ hiển thị văn bản của mục).
Nếu tôi duyệt cây thị giác của điều khiển mà tôi đã chuyển đến PrepareItemContainer()
kết quả giống nhau. Trong cả hai trường hợp, chỉ có ListBoxItem
được tạo và không có con nào được tạo.
Tôi không thể tìm thấy cách tốt để thêm ListBoxItem
vào cây trực quan. Tôi tìm thấy số VirtualizingStackPanel
trong cây trực quan, nhưng gọi số Children.Add()
kết quả là InvalidOperationException
(không thể thêm các mục trực tiếp vào ItemPanel
vì nó tạo mục cho số ItemsControl
). Cũng giống như một bài kiểm tra, tôi đã thử gọi số AddVisualChild()
bằng cách sử dụng Reflection (vì nó được bảo vệ), nhưng điều đó cũng không hoạt động. tìm
Tôi không hiểu. Tại sao bạn muốn làm điều này? Thử nghiệm? –
Có - chỉ dành cho mục đích thử nghiệm. – Andy
Bạn có thể đặt ['VirtualizingStackPanel.IsVirtualizing'] (http://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingstackpanel.isvirtualizing.aspx) đính kèm thuộc tính thành' false' trên 'ItemsListBox 'trước khi thêm các mục. Khi bạn đặt nó thành 'true' một lần nữa mọi thứ sẽ bắt đầu ảo hóa khi bạn cuộn. –