【发布时间】:2016-10-25 23:42:18
【问题描述】:
我有一个带有DataGrid 的窗口,用于存储Document 的对象。当我从文件资源管理器拖放文件时,我将其添加到DataGrid。但是,如果DataGrid 已经包含同名对象,则会显示MessageBox,询问用户是否要替换现有的Document。
问题是当显示MessageBox 时,它会冻结文件资源管理器。我无法关闭、最小化等。如果文件资源管理器显示在MessageBox 前面,我必须从任务栏中选择它。我不知道为什么它会冻结文件资源管理器,以及如何修复它。任何帮助都会很棒!
代码:
private void MainWindow_DragEnter(object sender, DragEventArgs e)
{
gridDragDropVisual.Visibility = Visibility.Visible;
}
private void MainWindow_DragLeave(object sender, DragEventArgs e)
{
gridDragDropVisual.Visibility = Visibility.Collapsed;
}
private void MainWindow_Drop(object sender, DragEventArgs e)
{
gridDragDropVisual.Visibility = Visibility.Collapsed;
// Get dropped data
if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
{
List<string> files = new List<string>();
foreach (string obj in (string[])e.Data.GetData(DataFormats.FileDrop))
{
// If data is a directory
if (Directory.Exists(obj))
{
// Get files in directory
string[] detectedFiles = Directory.GetFiles(obj, "*.*", SearchOption.AllDirectories);
// Add files to list
files.AddRange(detectedFiles);
}
else // If data is files
{
// Add files to list
files.Add(obj);
}
}
// Add files as documents
AddItems(files.ToArray());
// Populate datagrid
dataGrid.ItemsSource = documentList = Documents.Get();
}
}
private void AddItems(string[] items)
{
foreach (string file in items)
{
string fileName = file.Substring(file.LastIndexOf('\\')+1);
// Create new document
Document newDocument = new Document(file);
// Get any existing document with the same name
Document existingDocument = documentList.FirstOrDefault(objDocument => objDocument.fldName == fileName);
if (existingDocument != null)
{
switch (MessageBox.Show(Application.Current.MainWindow, string.Format("There is already a document that exists with the name '{0}'.\n\nWould you like to replace it?",fileName), "", MessageBoxButton.YesNo, MessageBoxImage.Question))
{
case MessageBoxResult.Yes:
{
// Remove existing document
Document.Remove(existingDocument.pkDocumentID);
// Add document to database
newDocument.Add();
break;
}
}
}
else
{
// Add document to database
newDocument.Add();
}
}
// Populate datagrid
dataGrid.ItemsSource = documentList = Documents.Get();
}
【问题讨论】:
-
这完全是设计使然。 D+D 通知由拖动源在其调度程序线程上生成。探险家在这种情况下。您的 MessageBox.Show() 调用被阻塞,因此资源管理器无法恢复其调度程序。它看起来会被冻结,不再响应输入。您可以使用自己的 Dispatcher.BeginInvoke() 方法让您的代码在事件处理完成后运行。