VirtualMode là một phương pháp để bạn tự quản lý dữ liệu trong ListView (hoặc DataGridView) với mục đích chính là tăng tốc độ hiển thị trong những trường hợp phải nạp quá nhiều dữ liệu lên ListView. Với phương pháp này, dữ liệu sẽ không được thêm trực tiếp vào ListView mà chúng sẽ được tạo động khi cần thiết để hiển thị. Trong bài viết này tôi sẽ làm một ví dụ để nạp và tìm kiếm tập tin trong một thư mục trên ListView.
Download ListView VirtualMode Example (VC# 2010) Giới thiệuĐể sử dụng được phương pháp này, đầu tiên bạn cần đặt property VirtualMode bằng true. Sau đó bạn cần gán property VirtualListSize bằng số phần tử mà ListView chứa. Một vài điểm cần lưu ý là các property của ListView như Items, CheckedItems, SelectedItems sẽ không được sử dụng nữa. Thay vào đó, bạn hãy sử dụng CheckedIndices và SelectedIndices để thay thế. Ngoài ra khi để chế độ View là Tile, nó sẽ được tự động chuyển sang chế độ LargeIcon. Trong ví dụ này tôi tạo một lớp Y2ListView thừa kế từ ListView để thực hiện các công việc cần thiết. Lớp này có property FolderPath, mỗi khi gán giá trị mới cho property này, ListView sẽ được cập nhật lại để lấy và hiển thị danh sách tập tin trong thư mục đó. Sự kiện RetrieveVirtualItemTrong chế độ VirtualMode, sự kiện RetrieveVirtualItem sẽ được gọi khi ListView cần lấy một phần tử nào đó. Bạn cần khởi tạo phần tử và gán cho property Item của tham số RetrieveVirtualItemEventArgs. Dựa vào property ItemIndex của tham số này, bạn có thể lấy được giá trị cần thiết từ dữ liệu nguồn để tạo ra phần tử. public class Y2ListView:ListView { string[] _files; // data private string _folderPath; public string FolderPath { get {return _folderPath;} set { if(String.IsNullOrEmpty(value)) return; _folderPath=value; _files=Directory.GetFiles(_folderPath); Array.Sort(_files); this.VirtualListSize=_files.Length; } } public Y2ListView() { this.VirtualMode=true; } protected override void OnRetrieveVirtualItem(RetrieveVirtualItemEventArgs e) { string filePath=_files[e.ItemIndex]; string fileName=Path.GetFileName(filePath); FileInfo finfo=new FileInfo(filePath); ListViewItem item=new ListViewItem(fileName,e.ItemIndex-_startIndex); double size=Math.Ceiling(finfo.Length/1024f); item.SubItems.Add(size.ToString("#,0 KB")); item.SubItems.Add(finfo.LastWriteTime.ToString()); e.Item=item; base.OnRetrieveVirtualItem(e); } } } Bởi vì ListView mà tôi tạo ra sẽ có ba cột Name, Size, DateModified nên trong sự kiện RetrieveVirtualItem, bạn cũng cần phải tạo item có đủ ba giá trị (sub item). Sự kiện CacheVirtualItemsBạn có thể xử lý sự kiện này để tăng tốc độ cho ListView trong chế độ VirtualMode. Bằng cách tạo ra và lưu trữ sẵn các dữ liệu cần thiết sắp được sử dụng, việc truy xuất và hiển thị các phần tử sẽ nhanh hơn. Ví dụ tôi thêm một ImageList để hiển thị icon cho các tập tin. Thay vì viết trực tiếp trong sự kiện RetrieveVirtualItem, tôi sẽ lưu trữ sẵn các icon cần thiết vào ImageList trong sự kiện CacheVirtualItems: protected override void OnCacheVirtualItems(CacheVirtualItemsEventArgs e) { _imageList.Images.Clear(); for (int i = e.StartIndex; i < e.EndIndex; i++) { Icon icon=Icon.ExtractAssociatedIcon(_files[i]); _imageList.Images.Add(icon); } base.OnCacheVirtualItems(e); } Dựa vào property StartIndex và EndIndex, tôi chỉ lấy icon của các tập tin trong khoảng này và lưu vào ImageList. Như vậy ImageList sẽ có EndIndex-StartIndex phần tử tính từ 0, như vậy ta cần một biến để lưu giá trị StartIndex lại nếu muốn gán ảnh cho ListViewItem thông qua ImageIndex. Sự kiện SearchForVirtualItemSự kiện này cần được xử lý nếu bạn muốn sử dụng được hai phương thức FindItemWithText và FindNearestItem của ListView. Tham số SearchForVirtualItemEventArgs chứa property Text là giá trị của chuỗi tìm kiếm (trong ví dụ này là tên tập tin bao gồm phần mở rộng), và Index là giá trị mà bạn cần gán cho nó để xác định phần tử nào tìm được trong danh sách. Bởi vì danh sách file của ta đã được sắp xếp, tôi sử dụng BinarySearch để hiện thực sự kiện này đơn giản như sau: protected override void OnSearchForVirtualItem(SearchForVirtualItemEventArgs e) { string filePath=Path.Combine(_folderPath,e.Text); int index=Array.BinarySearch(_files,filePath); if(index>-1) e.Index=index; base.OnSearchForVirtualItem(e); } Mã nguồn hoàn chỉnh lớp Y2ListViewusing System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Windows.Forms; namespace Win1 { public class Y2ListView:ListView { private ImageList _imageList; int _startIndex; string[] _files; private string _folderPath; public string FolderPath { get {return _folderPath;} set { if(String.IsNullOrEmpty(value)) return; if(_imageList!=null) _imageList.Images.Clear(); _startIndex=-1; _folderPath=value; _files=Directory.GetFiles(_folderPath); Array.Sort(_files); this.VirtualListSize=_files.Length; } } public Y2ListView() { _imageList=new ImageList(); _imageList.ImageSize = new System.Drawing.Size(16, 16); this.VirtualMode=true; this.DoubleBuffered=true; this.SmallImageList=_imageList; this.LargeImageList=_imageList; } protected override void OnSearchForVirtualItem(SearchForVirtualItemEventArgs e) { string filePath=Path.Combine(_folderPath,e.Text); int index=Array.BinarySearch(_files,filePath); if(index>-1) e.Index=index; base.OnSearchForVirtualItem(e); } protected override void OnCacheVirtualItems(CacheVirtualItemsEventArgs e) { if(_startIndex==e.StartIndex) return; _startIndex=e.StartIndex; _imageList.Images.Clear(); for (int i = e.StartIndex; i < e.EndIndex; i++) { Icon icon=Icon.ExtractAssociatedIcon(_files[i]); _imageList.Images.Add(icon); } base.OnCacheVirtualItems(e); } protected override void OnRetrieveVirtualItem(RetrieveVirtualItemEventArgs e) { string filePath=_files[e.ItemIndex]; string fileName=Path.GetFileName(filePath); FileInfo finfo=new FileInfo(filePath); ListViewItem item=new ListViewItem(fileName,e.ItemIndex-_startIndex); double size=Math.Ceiling(finfo.Length/1024f); item.SubItems.Add(size.ToString("#,0 KB")); item.SubItems.Add(finfo.LastWriteTime.ToString()); e.Item=item; base.OnRetrieveVirtualItem(e); } } } |
C# – Ví dụ về VirtualMode trong ListView: Nạp danh sách tập tin trong thư mục
Ý kiến bạn đọc
Tin tức khác
C# – Thread Signaling: Auto và Manual Reset Event
- 22/2/2013
C# – Giao tiếp giữa các process bằng Pipe Stream (Inter-process communication)
- 19/2/2013
.NET – Tạo instance và chuyển đổi kiểu dữ liệu bất kì
- 10/4/2012
OOP – Interface vs Abstract class
- 4/4/2012
Codecademy – “Cách đơn giản nhất để học lập trình”
- 30/3/2012
.NET 4 – System.Tuple vs Anonymous Type
- 30/3/2012
Viết Extension cho Google Chrome – Đơn giản ... và phức tạp
- 30/3/2012
Thiết kế Entity Data Model – Part 3: Code First
- 28/3/2012
Thiết kế Entity Data Model – Part 2: Model First
- 28/3/2012
Thiết kế Entity Data Model – Part 1: Database First
- 28/3/2012
Tin tiêu điểm
-
Đọc và ghi tập tin bằng C# – read and write file with C# .net (61,450)
-
Định dạng kiểu DateTime C# (48,639)
-
Đọc và ghi XML với C# – Read and Write XML with C# (33,471)
-
Sử dụng control ListView trong C# – Using ListView control in C# (28,778)
-
C# hướng đối tượng - ĐỐI TƯỢNG VÀ LỚP_1 (27,996)
-
Sử dụng control TreeView trong C# – Using TreeView control in C# (25,312)
-
C# - Sử Dụng Delegate Để Truyền Giá Trị Giữa Các Form (24,223)
-
Định dạng hiển thị cho kiểu dữ liệu Double, Float trong C# (23,768)
-
C# hướng đối tượng - ĐỐI TƯỢNG VÀ LỚP_2 (21,689)
-
Thiết kế Entity Data Model – Part 3: Code First (16,591)
Gallery
Text Links
Thiết kế logo chuyên nghiệp Insky
DAFABET
W88 w88b.com/dang-ky-tai-khoan-w88
W88
ca do bong da online
DAFABET
W88 w88b.com/dang-ky-tai-khoan-w88
W88
ca do bong da online
Tags
asp.net
JavaScript
Lập trình
Cơ sở dữ liệu
jquery
Csharp
Ajax
Thủ thuật
JavaScript
menu
Sql Server
Lập trình C#
WebService
stty
Sql
Phân trang
Rewrite
Mã hoá
Backup
Thủ thuật lập trình
Store procedure
Accordion
Validation
Store
Upload
Slide
jQueryPlugin
StoreProcedure
Regular Expression
Regex
android
Quick and snow
HTML5
WPF
WCF
Copyright © 2011 - 2012 vietshare.vn
by
phamkhuong102@gmail.com doanhkisi2315@gmail.com. All rights reserved.