Tôi đã thấy điều này được thực hiện trong môi trường Turbo C ++ của Borland , nhưng tôi không chắc chắn cách thực hiện đối với ứng dụng C # mà tôi đang làm việc. Có thực hành tốt nhất hoặc gotchas để tìm ra?
Tôi đã thấy điều này được thực hiện trong môi trường Turbo C ++ của Borland , nhưng tôi không chắc chắn cách thực hiện đối với ứng dụng C # mà tôi đang làm việc. Có thực hành tốt nhất hoặc gotchas để tìm ra?
Câu trả lời:
Một số mã mẫu:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.AllowDrop = true;
this.DragEnter += new DragEventHandler(Form1_DragEnter);
this.DragDrop += new DragEventHandler(Form1_DragDrop);
}
void Form1_DragEnter(object sender, DragEventArgs e) {
if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
}
void Form1_DragDrop(object sender, DragEventArgs e) {
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string file in files) Console.WriteLine(file);
}
}
io.File
(string[])
diễn viên an toàn cho bất kỳ FileDrop
thả định dạng? Đó là, có thể tạo ra một FileDrop
điều sẽ gây ra ngoại lệ bất hợp pháp string[]
không? Tôi gặp khó khăn khi tìm ra điều đó từ các tài liệu .
Lưu ý về quyền bảo mật của windows vista / windows 7 - nếu bạn đang chạy Visual Studio với tư cách quản trị viên, bạn sẽ không thể kéo các tệp từ cửa sổ thám hiểm không phải quản trị viên vào chương trình của bạn khi bạn chạy nó từ trong studio hình ảnh. Các sự kiện liên quan đến kéo thậm chí sẽ không bắn! Tôi hy vọng điều này sẽ giúp người khác ngoài kia không lãng phí hàng giờ trong cuộc sống của họ ...
Trong Windows Forms, đặt thuộc tính AllowDrop của điều khiển, sau đó lắng nghe sự kiện Drag Entry và sự kiện DragDrop.
Khi DragEnter
sự kiện kích hoạt, đặt đối số AllowedEffect
thành một cái gì đó không phải là không (ví dụ e.Effect = DragDropEffects.Move
).
Khi DragDrop
sự kiện diễn ra, bạn sẽ nhận được một danh sách các chuỗi. Mỗi chuỗi là đường dẫn đầy đủ đến tập tin bị loại bỏ.
Bạn cần phải nhận thức được một gotcha. Bất kỳ lớp nào bạn chuyển qua làm DataObject trong hoạt động kéo / thả phải được tuần tự hóa. Vì vậy, nếu bạn cố gắng vượt qua một đối tượng và nó không hoạt động, hãy đảm bảo rằng nó có thể được nối tiếp vì đó gần như chắc chắn là vấn đề. Điều này đã bắt tôi ra một vài lần!
Một Gotcha khác:
Mã khung gọi các sự kiện Kéo nuốt tất cả các ngoại lệ. Bạn có thể nghĩ rằng mã sự kiện của bạn đang chạy trơn tru, trong khi nó đang xuất hiện các ngoại lệ ở khắp mọi nơi. Bạn không thể nhìn thấy chúng vì khung đánh cắp chúng.
Đó là lý do tại sao tôi luôn đặt thử / bắt trong các trình xử lý sự kiện này, để tôi biết liệu họ có đưa ra bất kỳ ngoại lệ nào không. Tôi thường đặt một Debugger.Break (); trong phần bắt.
Trước khi phát hành, sau khi thử nghiệm, nếu mọi thứ dường như hoạt động, tôi loại bỏ hoặc thay thế chúng bằng xử lý ngoại lệ thực sự.
Một vấn đề phổ biến khác là nghĩ rằng bạn có thể bỏ qua các sự kiện Form DragOver (hoặc Drag Entry). Tôi thường sử dụng sự kiện DragOver của Form để đặt allowEffect và sau đó là sự kiện DragDrop của một điều khiển cụ thể để xử lý dữ liệu bị bỏ.
Đây là một cái gì đó tôi đã sử dụng để thả tập tin và / hoặc thư mục đầy tập tin. Trong trường hợp của tôi, tôi chỉ lọc *.dwg
các tệp và chọn bao gồm tất cả các thư mục con.
fileList
là một IEnumerable
hoặc tương tự Trong trường hợp của tôi bị ràng buộc với điều khiển WPF ...
var fileList = (IList)FileList.ItemsSource;
Xem https://stackoverflow.com/a/19954958/492 để biết chi tiết về thủ thuật đó.
Người xử lý thả ...
private void FileList_OnDrop(object sender, DragEventArgs e)
{
var dropped = ((string[])e.Data.GetData(DataFormats.FileDrop));
var files = dropped.ToList();
if (!files.Any())
return;
foreach (string drop in dropped)
if (Directory.Exists(drop))
files.AddRange(Directory.GetFiles(drop, "*.dwg", SearchOption.AllDirectories));
foreach (string file in files)
{
if (!fileList.Contains(file) && file.ToLower().EndsWith(".dwg"))
fileList.Add(file);
}
}
Bạn có thể triển khai Kéo và Thả trong WinForms và WPF.
Bạn nên thêm sự kiện mousemove:
private void YourElementControl_MouseMove(object sender, MouseEventArgs e)
{
...
if (e.Button == MouseButtons.Left)
{
DoDragDrop(new DataObject(DataFormats.FileDrop, new string[] { PathToFirstFile,PathToTheNextOne }), DragDropEffects.Move);
}
...
}
Bạn nên thêm sự kiện DragDrop:
private void YourEuityControl_DragDrop (người gửi đối tượng, DragEventArss e)
{
...
foreach (string path in (string[])e.Data.GetData(DataFormats.FileDrop))
{
File.Copy(path, DirPath + Path.GetFileName(path));
}
...
}