Chương 8 Ứng dụng Windows với WindowsForm
8.2.3. Quản lý sự kiện trên điều khiển cây
Trong ứng dụng này, chúng ta sẽ phải quản lý một số sự kiện. Đầu tiên là sự
kiện người dùng nhấn lên ô CheckBox để chọn các tập tin hay thư mục ở cây bên phải hay nhấn các nút ở cây bên phải. Tiếp theo là các sự kiện nhấn vào Button ‘Cancel’, ‘Copy’, = ‘Delete’ hay ‘Clear’.
Ta sẽ khảo sát sự kiện trên điều khiển cây trước.
Sự kiện chọn một nút trên điều khiển cây bên trái
Khi người dùng muốn chọn một tập tin hay thư mục để chép hay xóa. Ứng với mỗi lần chọn sẽ phát sinh ra một số sự kiện tương ứng. Ta sẽ bắt sự kiện AfterCheck của điều khiển cây. Ta gõ vào các đoạn mã sau :
tvwSource.AfterCheck +=
new TreeViewEventHandler (this.tvwSource_AfterCheck );
Ta viết lệnh thực thi cho hàm bắt sự kiện AfterCheck có tên là tvwSource_AfterCheck, hàm này có hai tham số: đầu tiên là biến Sender chứa thông tin về đối tượng phát sinh ra sự kiện, thứ hai là đối tượng TreeViewEventArgs chứa thông tin về sự kiện phát ra. Ta sẽ đánh dấu là chọn cho thư mục được chọn và tất cả các tập tin hay thư mục con của thư mục đó thông qua hàm SetCheck():
protected void tvwSource_AfterCheck (object sender, System.Windows.Forms.TreeViewEventArgs e) {
SetCheck(e.node,e.node.Checked); }
Hàm SetCheck() sẽ tiến hành thực hiện đệ qui trên nút hiện hành, hàm gồm hai tham số: nút cần đánh dấu và cờ xác định là đánh dấu hay bỏ đánh dấu chọn, nếu thuộc tính Count bằng không (nghĩa là nút này là nút lá) thì ta sẽ đánh dấu chọn cho nút đó. Nếu không ta gọi đệ qui lại hàm SetCheck():
private void SetCheck(TreeNode node, bool check) {
node.Checked = check;
foreach (TreeNode n in node.Nodes) { if (node.Nodes.Count == 0) { node.Checked = check; } else { SetCheck(n,check); }
} }
Sự kiện chọn một nút trên điều khiển cây bên phải
Khi người dùng chọn một nút ở cây bên phải, ta sẽ phải cho hiện đường dẫn
đầy đủ của nút đó lên TextBox ở góc phía trên bên phải. Ta sẽ bắt sự kiện AfterSelect của cây. Sự kiện này sẽ được gọi sau khi người dùng nhấn một nút nào
đó trên cây, hàm bắt sự kiện này như sau :
protected void tvwTargetDir_AfterSelect( object sender, System.Windows.Forms.TreeViewEventArgs e)
{
string theFullPath = GetParentString(e.node);
Sau khi ta có được đường dẫn đầy đủ của nút chọn, ta sẽ bỏ đi dấu \\ (Backslash) nếu có. Rồi cho hiển thị lên hộp thoại TextBox.
if (theFullPath.EndsWith("\\")) { theFullPath =theFullPath.Substring(0,theFullPath.Length-1); } txtTargetDir.Text = theFullPath; }
Hàm GetParentString() trả về đường dẫn đầy đủ của nút được truyền vào làm thông số. Hàm này cũng tiến hành lặp đệ qui trên nút truyền vào nếu nút này không là nút lá và thêm dấu \\ vào nó. Quá trình lặp sẽ kết thúc nếu nút hiện hành không là nút cha.
private string GetParentString(TreeNode node) { if(node.Parent == null) { return node.Text; } else {
return GetParentString(node.Parent) + node.Text + (node.Nodes.Count == 0 ? "" : "\\");
} }
Quản lý sự kiện nhấn nút bỏ chọn (Clear)
Ta tiến hành bổ sung mã lệnh sau cho hàm bắt sự kiện nhấn vào nút ‘Clear’: protected void btnClear_Click(object sender, System.EventArgs e)
{
foreach ( TreeNode node in tvwSource.Nodes ) {
} }
Hàm này chỉđơn giản là duyệt qua tất cả các nút thuộc cây bên trái, sau đó gọi lại hàm SetCheck() với biến cờ là false, nghĩa là bỏ chọn tất cả các nút hiện đang
được chọn trên điều khiển cây.
Quản lý sự kiện nhấn nút chép tập tin (Copy)
Cái ta cần để hoàn chỉnh thao tác này là danh sách các đối tượng FileInfo. Để
có thể quản lý linh hoạt trên danh sách này ta sẽ dùng đối tượng ArrayList, nó cho phép ta thực hiện hầu hết mọi thao tác trên danh sách một các dễ dàng. Để lấy về
danh sách các đối tượng FileInfo, ta sẽ gọi hàm GetFileList() của ta: protected void btnCopy_Click( object sender, System.EventArgs e) {
ArrayList fileList = GetFileList( );
Lấy về danh sách các tập tin
Đầu tiên ta sẽ khởi tạo một đối tượng ArrayList để lưu trữ danh sách tên các tập tin được chọn, có tên là fileNames:
private ArrayList GetFileList( ) {
ArrayList fileNames = new ArrayList( );
Ta lấy về danh sách tên các tập tin được chọn bằng cách duyệt toàn bộ các nút trong điều khiển cây bên phải:
foreach (TreeNode theNode in tvwSource.Nodes) GetCheckedFiles(theNode, fileNames);
}
Hàm GetCheckedFiles() thêm danh sách tên các tập tin được đánh dấu của nút hiện hành theNode vào đối tượng fileNames. Nếu nút truyền vào là nút lá và được
đánh dấu chọn, ta sẽ lấy đường dẫn đầy đủ của nút và thêm vào đối tượng fileNames:
private void GetCheckedFiles(TreeNode node, ArrayList fileNames) {
if (node.Nodes.Count == 0) {
if (node.Checked) {
string fullPath = GetParentString(node); fileNames.Add(fullPath); } } Nếu không là nút lá, ta sẽ lập đệ qui để tìm nút lá : else {
GetCheckedFiles(n,fileNames); }
}
Sau khi thực hiện hết hàm này (nghĩa là duyệt hết cây tvwSource), đối tượng fileNames sẽ chứa toàn bộ các tập tin được đánh dấu chọn của cây. Quay trở lại khảo sát tiếp tục hàm GetFileList(), ta tạo thêm một đối tượng ArrayList nữa, tên fileList. Mảng này sẽ chứa danh sách các đối tượng FileInfo ứng với các tên tập tin tìm được trong mảng fileNames. Thuộc tính Exists của đối tượng FileInfo dùng để
kiểm tra là tập tin hay thư mục. Thuộc tính Exists là True thì đối tượng FileInfo đó là tập tin và ta sẽ thêm vào mảng fileList, ngược lại là thư mục thì không thêm.
foreach (string fileName in fileNames) {
FileInfo file = new File(fileName); if (file.Exists)
fileList.Add(file); }