c#拖放过程中的确认消息框会冻结文件资源管理器



我有一个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}'.nnWould 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();
}

问题是它在同一个线程中运行,因此暂停了其他所有内容。解决方案是让MessageBox在另一个任务中运行:

/// <summary>
/// Represents a wrapper for using task based messageboxes.
/// </summary>
public static class AdvancedMessageBox
{
    /// <summary>
    /// Does show a messagebox inside another task, so it has rather no impact to the main thread.
    /// </summary>
    public static void TaskBasedShow(
        string message,
        string caption,
        MessageBoxButton buttons,
        MessageBoxImage image)
    {
        Task.Run(() =>
        {
            OnRes?.Invoke(MessageBox.Show(message, caption, buttons, image));
        });
    }
    public delegate void OnResult(MessageBoxResult res);
    /// <summary>
    /// Will get triggered, when the user pressed a button on a messagebox (after calling TaskBasedShow).
    /// </summary>
    public static event OnResult OnRes;
}

实现:

public MainWindow()
{
    InitializeComponent();
    AdvancedMessageBox.OnRes += MessageBox_OnRes;
    AdvancedMessageBox.TaskBasedShow(
        "My message",
        "My caption",
        MessageBoxButton.YesNo,
        MessageBoxImage.Question);
}
/// <summary>
///     Is getting triggered after the user pressed a button.
/// </summary>
/// <param name="res">The pressed button.</param>
private void MessageBox_OnRes(MessageBoxResult res)
{
    // Implement you logic here
}

最新更新