拖放期间的c#确认消息框冻结文件资源管理器

时间:2016-10-25 23:42:19

标签: c# wpf

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

1 个答案:

答案 0 :(得分:0)

问题是它在同一个线程中运行,因此暂停其他所有内容。解决方案是让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
}