Comment gérer l'événement Drag and Drop sous WPF

Amyco 35 20 Reputation points
2023-09-26T12:25:37.6533333+00:00

Sous .Net Framework 4.8, dans un projet de bureau WPF en C# :

Je fais un Drag and Drop d’un fichier Excel sur un Grid afin d’importer ses données.

L’événement DragEnter doit fournir une réponse à l’acceptation du fichier en fonction de son contenu. Or, la vérification demande l’ouverture et la lecture du fichier qui sont deux opérations longues et en attendant le curseur apparait avec l’icône qui indique un refus.

Comment résoudre ce problème ?

1.      Afficher le curseur d’attente spécialisé en lieu et place du curseur de refus,

2.      Désynchroniser la tache de vérification en acceptant le curseur de refus mais afficher un message d’attente dans un champ dédié de l’application,

3.       ?

J’imagine que cette problématique n’est pas nouvelle et que des réponses ont déjà été apportées. Mais lesquelles ? Avez-vous un exemple de code qui m’aiderait beaucoup.

Merci de votre aide

Windows 10
Windows 10
A Microsoft operating system that runs on personal computers and tablets.
11,575 questions
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Limitless Technology 44,316 Reputation points
    2023-09-27T08:44:14.6733333+00:00
    Hello Amyco 35,
    
    In my experience, you can handle it through 2 options:
    
    1. Display a Specialized Waiting Cursor:
    
    Instead of immediately displaying a rejection cursor in the DragEnter event, you can set a specialized waiting cursor to indicate that the file is being analyzed. This provides a visual response to the user, signaling that the application is processing the file. Here's an example of how to load and apply a custom cursor in your DragEnter event handler:
    
    private void Grid_DragEnter(object sender, DragEventArgs e)
    {
        // Load the custom waiting cursor from the project resources
        Cursor customCursor = new Cursor(Application.GetResourceStream(
            new Uri("pack://application:,,,/YourProjectNamespace;component/YourCursor.cur")).Stream);
    
        // Set the cursor to the custom waiting cursor
        Mouse.OverrideCursor = customCursor;
    
        // Continue with your DragEnter logic...
    }
    
    NOTE: Please replace: "YourProjectNamespace" should be replaced with your project's actual namespace.
    "YourCursor.cur" should be replaced with the actual name and path of your custom cursor image file.
    
    2. Asynchronously Verify the File:
    
    In parallel, you can initiate the file content verification task in the background. During this verification, you can display a waiting message or progress bar in a dedicated area of the application to indicate that processing is ongoing.
    
    Once the verification is complete, you can update the user interface accordingly. If the file is accepted, you can change the cursor to an acceptance cursor. If the file is rejected, you can display an appropriate error message. Here's a simplified example of code to illustrate this approach:
    
    private async void Grid_DragEnter(object sender, DragEventArgs e)
    {
        // Set a specialized waiting cursor
        Mouse.OverrideCursor = Cursors.Wait;
    
        // Get the drag-and-drop data
        if (e.Data.GetDataPresent(DataFormats.FileDrop))
        {
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
    
            // Start the file verification in the background
            bool isFileAccepted = await VerifyFileAsync(files[0]);
    
            // Update the UI accordingly
            if (isFileAccepted)
            {
                // Set the acceptance cursor
                Mouse.OverrideCursor = Cursors.Hand;
            }
            else
            {
                // Display an error message to the user
                MessageBox.Show("The file is not accepted.", "Error");
                // Set the rejection cursor
                Mouse.OverrideCursor = Cursors.No;
            }
        }
    }
    
    private async Task<bool> VerifyFileAsync(string filePath)
    {
        // Perform the file content verification here (reading, parsing, etc.).
        // You can display a waiting message during this operation.
    
        // Simulate an asynchronous operation for a few seconds
        await Task.Delay(3000);
    
        // Return true if the file is accepted, otherwise return false
        return true; // or false based on the verification result
    }
    
    Note: Please remember to customize and adapt this code to your actual file verification logic. This approach enhances the user experience by making it appear that the application responds promptly while conducting lengthy verification operations in the background.
    
    --If the reply is helpful, please Upvote and Accept as answer--
    
    0 comments No comments

  2. Amyco 35 20 Reputation points
    2023-09-27T13:08:33.1066667+00:00

    Thank you for your reply.

    The logic of Drag and Drop:

    The user drags a source object (say a file) onto a destination object which may or may not accept it. The destination object receives the DragEnter event. At this moment the left mouse button is pressed and the mouse cursor takes the form of a forbidden direction (a refusal of the object by default).

    Processing this DragEnter event validates or not the acceptance of the object (via e.Effects). It is at the end of this processing that Windows processes e.Effects and displays the appropriate cursor (acceptance or refusal). During the entire duration of this validation, the cursor is not changed. In particular, under WPF, the Mouse.OverrideCursor = Cursors.Wait; only takes effect when processing of this event exits.

    In the usual operation of Drag and Drop, it is when the user releases the mouse button while the source object has been accepted (via previous e.Effects) that the application receives the DragDrop event which allows to introduce the source data into the destination object.

    With WPF:

    • Either the user holds the mouse button (on the underlying file) long enough for the synchronous or asynchronous validation to be completed, with the cursor refusing, which is counter-intuitive,

    • Either he immediately releases the mouse button (since the cursor indicates refusal) and sees the wait cursor appear then, later, the data loaded into the destination object.

    That's where my thoughts are. What do you think ?

    THANKS.

    0 comments No comments

  3. Amyco 35 20 Reputation points
    2023-09-30T22:24:42.09+00:00

    Finally I used a BackgroundWorker to import an Excel file. There it works correctly!

    Regards

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.