2016-10-25 24 views
2

Documentのオブジェクトを格納するDataGridのウィンドウがあります。ファイルエクスプローラからファイルをドラッグ&ドロップすると、DataGridに追加されます。ただし、DataGridに既に同じ名前のオブジェクトが含まれている場合は、Documentを置き換えるかどうかを尋ねるMessageBoxが表示されます。ドラッグアンドドロップ中の確認メッセージボックスでファイルエクスプローラがフリーズ

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(); 
} 
+0

設計によって完全です。 D + D通知は、ディスパッチャスレッド上のドラッグソースによって生成されます。この場合はエクスプローラです。 MessageBox.Show()呼び出しがブロックされているため、エクスプローラはディスパッチャを再開できません。それは凍って見えます、それはもはや入力に反応することはできません。独自のDispatcher.BeginInvoke()メソッドを使用して、イベント処理が完了した後にコードを実行させることができます。 –

答えて

0

問題は、それが同じスレッドで実行されるため、他のすべてが一時停止していることです。解決策は、別のタスク内MessageBoxの実行をさせることになります。

実装:

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 
} 
関連する問題