Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 11 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
11
Dung lượng
395,36 KB
Nội dung
Lập trình với C# Gvhd: Nguyễn Tấn Trần Minh Khang
125
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íc 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á lặp sẽ kết thúc nếu nút hiện hành là 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 )
{
SetCheck(node, false);
}
}
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
Lập trình với C# Gvhd: Nguyễn Tấn Trần Minh Khang
126
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ất 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
{
foreach (TreeNode n in node.Nodes)
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)
Lập trình với C# Gvhd: Nguyễn Tấn Trần Minh Khang
127
{
FileInfo file = new File(fileName);
if (file.Exists)
fileList.Add(file);
}
13.1.2.4 Quản lý sự kiện nhấn chọn nút xóa ( Delete )
Trước tiên ta cần đảm bảo rằng người dùng chắc chắn muốn xóa bằng cách cho hiện
lên một hộp thoại xác nhận xóa. Để hiển thị hộp thoại ta dùng hàm tĩnh Show() của
đối tượng MessageBox.
protected void btnDelete_Click( object sender, System.EventArgs e)
{
System.Windows.Forms.DialogResult result =
MessageBox.Show( "Are you quite sure?",// Thông điệp
"Delete Files", // Tiêu đề cho hộp thoại
MessageBox.Buttons.OKCancel,// nút nhấn
MessageBox.Icon.Exclamation,// biểu tượng hộp thoại
MessageBox.DefaultButton.Button2); // nút mặc định
}
Khi người dùng nhấn nút OK hay Cancel, ta sẽ nhận được giá trị trả về từ đối
tượng DialogResult thuộc namespace Forms và tiến hành xử lý tương ứng :
if (result == System.Windows.Forms.DialogResult.OK)
{
Nếu người dùng chọn nút OK thì ta sẽ lấy về danh sách tên các tập tin fileNames,
sau đó duyệt qua từng tên và xóa chúng đi :
ArrayList fileNames = GetFileList( );
foreach (FileInfo file in fileNames)
{
try
{
lblStatus.Text = "Deleting " +
txtTargetDir.Text + "\\" +
file.Name + " ";
Application.DoEvents( );
file.Delete( );
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
lblStatus.Text = "Done.";
Application.DoEvents( );
Sau đây là mã của toàn bộ ứngdụng :
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
Lập trình với C# Gvhd: Nguyễn Tấn Trần Minh Khang
128
/// <remarks>
/// chép tập tin – ứngdụng minh họa cho Windows Form
/// </remarks>
namespace FileCopier
{
/// <summary>
/// Form minh họa cho ứngdụng Windows Form
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// lớp bên trong của lớp Form1, so sánh 2 tập tin
/// </summary>
public class FileComparer : IComparer
{
public int Compare (object f1, object f2)
{
FileInfo file1 = (FileInfo) f1;
FileInfo file2 = (FileInfo) f2;
if (file1.Length > file2.Length)
{
return -1;
}
if (file1.Length < file2.Length)
{
return 1;
}
return 0;
}
}
public Form1( )
{
InitializeComponent( );
// đẩy dữ liệu vào cây bên trái và bên phải
FillDirectoryTree(tvwSource, true);
FillDirectoryTree(tvwTargetDir, false);
}
/// <summary>
/// phương thức này dùng để đẩy dữ liệu vào cây
/// </summary>
private void FillDirectoryTree(TreeView tvw, bool isSource)
{
// trước khi đẩy dữ liệu vào cây, ta phải xóa bỏ các nút
// hiện đang tồn tại trên cây.
tvw.Nodes.Clear( );
// lấy về danh sách các ổ đĩa logic trên máy tính
// sau đó đẩy chúng vào làm nút gốc của cây
string[] strDrives = Environment.GetLogicalDrives( );
// Duyệt qua các ổ đĩa, dùng khối try/catch để bắt bất
// kỳ lỗi nào xảy ra trên đĩa, nếu đĩa hợp lệ thì ta
// thêm vào làm nút gốc cho cây.
// đĩa không hợp lệ sẽ không thêm vào cây : đĩa mềm hay
// CD trống
foreach (string rootDirectoryName in strDrives)
Lập trình với C# Gvhd: Nguyễn Tấn Trần Minh Khang
129
{
if (rootDirectoryName != @"C:\")
continue;
try
{
// nếu đĩa không hợp lệ ta sẽ quăng ra một lỗi.
DirectoryInfo dir =
new DirectoryInfo(rootDirectoryName);
dir.GetDirectories( );
TreeNode ndRoot = new TreeNode(rootDirectoryName);
// thêm nút gốc vào cây
tvw.Nodes.Add(ndRoot);
// thêm các nút con vào cây, nếu là cây bên trái
// thì thêm cả tập tin vào cây
if (isSource)
GetSubDirectoryNodes(ndRoot, ndRoot.Text, true);
else
GetSubDirectoryNodes(ndRoot, ndRoot.Text, false);
}
catch (Exception e)
{
// thông báo đĩa có lỗi
MessageBox.Show(e.Message);
}
}
} // kết thúc thao tác đẩy dữ liệu vào cây
/// <summary>
/// lấy về tất cả các thư mục con của nút cha truyền vào,
/// thêm các thư mục con tìm được vào cây
/// hàm này có 3 đối số : nút cha, tên đầy đủ của nút cha,
/// và biến cờ getFileNames xác định có lấy tập tin không
/// </summary>
private void GetSubDirectoryNodes( TreeNode parentNode,
string fullName, bool getFileNames)
{
DirectoryInfo dir = new DirectoryInfo(fullName);
DirectoryInfo[] dirSubs = dir.GetDirectories( );
// ứng với mỗi mục con ta thêm vào cây nếu nó không ở
// trạng thái ẩn.
foreach (DirectoryInfo dirSub in dirSubs)
{
// bỏ qua các thư mục ẩn
if ( (dirSub.Attributes & FileAttributes.Hidden) != 0 )
{
continue;
}
/// <summary>
/// ta chỉ cần tên nút để thêm vào cây, còn ta phải
/// truyền vào tên đường dẫn đầy đủ của nút trên cây
/// cho hàm lặp đệ qui GetSubDirectoryNodes()để nó có
/// thể tìm được các nút con cửa nút đó
/// </summary>
TreeNode subNode = new TreeNode(dirSub.Name);
Lập trình với C# Gvhd: Nguyễn Tấn Trần Minh Khang
130
parentNode.Nodes.Add(subNode);
// lặp đệ qui hàm GetSubDirectoryNodes().
GetSubDirectoryNodes(
subNode,dirSub.FullName,getFileNames);
}
if (getFileNames)
{
// lấy mọi tập tin thuộc nút
FileInfo[] files = dir.GetFiles( );
// thêm các tập tin và nút con
foreach (FileInfo file in files)
{
TreeNode fileNode = new TreeNode(file.Name);
parentNode.Nodes.Add(fileNode);
}
}
}
/// <summary>
/// điểm vào chính củaứng dụng.
/// </summary>
[STAThread]
static void Main( )
{
Application.Run(new Form1( ));
}
/// <summary>
/// tạo ra một danh sách có thứ tự các tập tin được chọn ,
/// chép chúng sang cây bên phải
/// </summary>
private void btnCopy_Click(object sender,
System.EventArgs e)
{
// lấy về danh sách tập tin
ArrayList fileList = GetFileList( );
// tiến hành chép tấp tin
foreach (FileInfo file in fileList)
{
try
{
lblStatus.Text = "Copying " + txtTargetDir.Text +
"\\" + file.Name + " ";
Application.DoEvents( );
file.CopyTo(txtTargetDir.Text + "\\" +
file.Name,chkOverwrite.Checked);
}
catch // (ta không làm gì ở đây cả)
{
}
}
lblStatus.Text = "Done.";
Application.DoEvents( );
}
/// <summary>
Lập trình với C# Gvhd: Nguyễn Tấn Trần Minh Khang
131
/// bắt sự kiện kết thúc ứngdụng
/// </summary>
private void btnCancel_Click(object sender, System.EventArgs e)
{
Application.Exit( );
}
/// <summary>
/// bắt sự kiện xóa bỏ các nút được chọn trên cây bên trái
/// </summary>
private void btnClear_Click( object sender, System.EventArgs e)
{
// lấy về nút gốc trên cây bên trái và
// tiến hành lặp đệ qui
foreach (TreeNode node in tvwSource.Nodes)
{
SetCheck(node, false);
}
}
/// <summary>
/// đảm bảo người dùng muốn xóa nút đó
/// </summary>
private void btnDelete_Click(object sender, System.EventArgs e)
{
// xác nhận xóa
System.Windows.Forms.DialogResult result = MessageBox.Show(
"Are you quite sure?", // thông điệp
"Delete Files", // tiêu đề
MessageBox.Buttons.OKCancel, // nút nhấn
MessageBox.Icon.Exclamation, // biểu tượng
MessageBoxDefaultButton.Button2); // nút mặc định
// nếu đồng ý xóa
if (result == System.Windows.Forms.DialogResult.OK)
{
// duyệt danh sách các tập tin và xoá các tập tin
/ được chọn
ArrayList fileNames = GetFileList( );
foreach (FileInfo file in fileNames)
{
try
{
// cập nhật nhãn
lblStatus.Text = "Deleting " +
txtTargetDir.Text + "\\" + file.Name + " ";
Application.DoEvents( );
file.Delete( );
}
catch (Exception ex)
{
// hộp thoại thông báo
MessageBox.Show(ex.Message);
}
}
lblStatus.Text = "Done.";
Application.DoEvents( );
Lập trình với C# Gvhd: Nguyễn Tấn Trần Minh Khang
132
}
}
/// <summary>
/// lấy đường dẫn đầy đủ của nút được chọn và gán vào
/// điều khiển TextBox txtTargetDir
/// </summary>
private void tvwTargetDir_AfterSelect( object sender,
System.Windows.Forms.TreeViewEventArgs e)
{
// lấy đường dẫn đầy đủ của nút
string theFullPath = GetParentString(e.Node);
// nếu nó không là nút lá, ta sẽ xóa 2 ký tự cuối cùng
// đi, vì đây là dấu //
if (theFullPath.EndsWith("\\"))
{
theFullPath =
theFullPath.Substring(0,theFullPath.Length-1);
}
// gán đường dẫn cho điều khiển TextBox
txtTargetDir.Text = theFullPath;
}
/// <summary>
/// đánh dấu chọn nút hiện hành và các nút con của nó
/// </summary>
private void tvwSource_AfterCheck(object sender,
System.Windows.Forms.TreeViewEventArgs e)
{
SetCheck(e.Node,e.Node.Checked);
}
/// <summary>
/// lập đệ qui việc đánh dấu chọn hay loại bỏ dấu chọn trên
/// nút truền vào dựa vào cờ check
/// </summary>
private void SetCheck(TreeNode node, bool check)
{
// set this node's check mark
node.Checked = check;
// tìm tất cả các nút con của nút
foreach (TreeNode n in node.Nodes)
{
// nếu là nút là thì ta đánh dấu chọn hoặc không chọn
if (node.Nodes.Count == 0)
node.Checked = check;
// nếu không là lá thì ta lặp đệ qui
else
SetCheck(n,check);
}
}
// lấy về tất cả các tập tin đã được đánh dấu chọn thuộc
// nút
private void GetCheckedFiles(TreeNode node,ArrayList fileNames)
{
Lập trình với C# Gvhd: Nguyễn Tấn Trần Minh Khang
133
// nếu là nút lá
if (node.Nodes.Count == 0)
{
// nếu nút là đánh dấu chọn
if (node.Checked)
{
// lấy đường dẫn đầy đủ của nút và thêm vào cây
string fullPath = GetParentString(node);
fileNames.Add(fullPath);
}
}
else // không là nút lá
{
// thực hiện trên tất cả nút con
foreach (TreeNode n in node.Nodes)
{
GetCheckedFiles(n,fileNames);
}
}
}
/// <summary>
/// lấy về đường dẫn đầy đủ của nút truyền vào
/// </summary>
private string GetParentString(TreeNode node)
{
// nếu là nút gốc thì trả về tên nút ( c:\ )
if(node.Parent == null)
return node.Text;
else
// nếu là nút cha thì thêm dấu // vào chuỗi trả về
// nếu nút lá ta không thêm gì cả
return GetParentString(node.Parent) + node.Text +
(node.Nodes.Count == 0 ? "" : "\\");
}
/// <summary>
/// trả về danh sách các tập tin được chọn theo thứ tự
/// </summary>
private ArrayList GetFileList( )
{
// danh sách tên tập tin đầy đủ không được sắp
ArrayList fileNames = new ArrayList( );
// duyệt từng nút của cây và lấy về danh sách các tập
// tin được chọn
foreach (TreeNode theNode in tvwSource.Nodes)
{
GetCheckedFiles(theNode, fileNames);
}
// danh sách các đối tượng FileInfo
ArrayList fileList = new ArrayList( );
// fileNames là tập tin thì ta thêm vào fileList
foreach (string fileName in fileNames)
{
// tạo ra FileInfo tương ứng với fileName
Lập trình với C# Gvhd: Nguyễn Tấn Trần Minh Khang
134
FileInfo file = new FileInfo(fileName);
if (file.Exists)
fileList.Add(file);
}
// tạo ra một thể hiện IComparer
IComparer comparer = (IComparer) new FileComparer( );
// sắp xếp danh sách tập tin
fileList.Sort(comparer);
return fileList;
}
}
}
13.1.3 Tạo sưu liệu XML bằng chú thích
Ngôn ngữ C# hỗ trợ kiểu chú thích mới, bằng ba dấu gạch chéo ( /// ). Trình biên
dịch C#dùng phần chú thích này để tạo thành sưu liệu XML.
Ta có thể tạo tập tin sưu liệu XML này bằng mã lệnh, ví dụ như để tạo sưu liệu cho
ứng dụng FileCopier ở trên ta gõ các lệnh sau :
csc filecopier.cs /r:System.Windows.Forms.dll /r:mscorlib.dll
/r:system.dll /r:system.configuration.dll /r:system.data.dll
/r:system.diagnostics.dll /r:system.drawing.dll
/r:microsoft.win32.interop.dll
/doc:XMLDoc.XML
Ta cũng có thể tạo sưu liệu XML trực tiếp ngay trong Visual Studio .NET, bằng
cách nhấn chuột phải lên biểu tượng của dự án và chọn ‘Properties’ để hiện lên hộp
thoại thuộc tính của dự án (Property Pages), sau đó chọn mục Configuration
Properties \ Build rồi gõ tên tập tin sưu liệu XML cần tạo ra vào dòng XML
Document File. Khi biên dịch dự án, tập tin sưu liệu XML sẽ tự động được tạo ra
trong thư mục chứa dự án. Dưới đây là một đoạn mã được trích ra từ tập tin sưu liệu
XML được tạo ra từ ứngdụng FileCopier trên :
<?xml version="1.0"?>
<doc>
<assembly>
<name>FileCopier</name>
</assembly>
<members>
<member name="T:FileCopier.Form1">
<summary>
Form demonstrating Windows Forms implementation
</summary>
</member>
<member name="F:FileCopier.Form1.components">
<summary>
Required designer variable.
</summary>
</member>
<member name="F:FileCopier.Form1.tvwTargetDir">
<summary>
Tree view of potential target directories
[...]...L p trình với C# Gvhd: Nguyễn Tấn Trần Minh Khang FileInfo file = new FileInfo(fileName); if (file.Exists) fileList.Add(file); } // tạo ra một thể hiện IComparer IComparer comparer = (IComparer) new FileComparer( ); } } // s p x p danh sách t p tin fileList.Sort(comparer); return fileList; } 134 . chọn ‘Properties’ để hiện lên h p
thoại thuộc tính của dự án (Property Pages), sau đó chọn mục Configuration
Properties Build rồi gõ tên t p tin sưu liệu. ra một thể hiện IComparer
IComparer comparer = (IComparer) new FileComparer( );
// s p x p danh sách t p tin
fileList.Sort(comparer);
return fileList;