Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drag and drop: setting DragUIOverride.Caption after async code triggers a COM exception #9296

Closed
Arko109 opened this issue Jan 29, 2024 · 5 comments
Labels
bug Something isn't working

Comments

@Arko109
Copy link

Arko109 commented Jan 29, 2024

Describe the bug

Drag and drop: setting DragUIOverride.Caption after async code triggers a COM exception that has no message.

Exception thrown: 'System.Runtime.InteropServices.COMException' in WinRT.Runtime.dll
An exception of type 'System.Runtime.InteropServices.COMException' occurred in WinRT.Runtime.dll but was not handled in user code

Without the async call it works fine. Actually, if I catch the exception, the caption is set, however the drag and drop becomes broken and works only once. The subsequent times I try to drop a file, the DragOver is called, but setting values does nothing and the file is not accepted.

Tried with release and prerelease Nuget package.

Maybe I misunderstand how to filter the file type that can be dropped and there is a way of doing it without an async call?

Steps to reproduce the bug

  1. Create a new blank WinUI app
  2. In MainWindow add any element (StackPanel, RelativePanel...) with AllowDrop="True" and DragOver="DragOver"
  3. In the DragOver event handler paste the following code:
if (e.DataView.Contains(StandardDataFormats.StorageItems)
    && (await e.DataView.GetStorageItemsAsync()).FirstOrDefault() is StorageFile file 
    && (file.FileType == ".xlsx" || file.FileType == ".xls"))
{
    e.AcceptedOperation = DataPackageOperation.Copy;
    e.DragUIOverride.Caption = "TEST";
}
  1. Try dragging over an Excel file, the e.DragUIOverride.Caption = "TEST" statement will throw a COM exception

Expected behavior

The drag and drop should work without exceptions and multiple times.

Screenshots

No response

NuGet package version

WinUI 3 - Windows App SDK 1.4.4: 1.4.231219000

Windows version

Windows 10 (21H2): Build 19044

Additional context

Actual OS build: 19045.3930

@Arko109 Arko109 added the bug Something isn't working label Jan 29, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the needs-triage Issue needs to be triaged by the area owners label Jan 29, 2024
@kmgallahan
Copy link
Contributor

Use DragEnter instead of DragOver.

The DragOver event gets dispatched many times per second until the drag stops. You are starting many instances of the handler that are all awaiting e.DataView.GetStorageItemsAsync and setting the drag properties at the same time, which is resulting in a problem somewhere.

@Arko109
Copy link
Author

Arko109 commented Jan 30, 2024

I tried with DragEnter and setting the AcceptedOperation is not reliable, most of the time it doesn't work and the file drop isn't accepted. Also the COM exception still happens sometimes if you enter - exit - enter.

I also tried using DragOver with a semaphore to limit the number of instances of the handler to one and it didn't fix anything, the exception is still occurring.

@kmgallahan
Copy link
Contributor

kmgallahan commented Jan 30, 2024

This was interesting to play with.

After testing I came to the same conclusions as found here #8108, which describes the issue and what is happening at a lower level.

The final reply states this is "by design". I don't think that is a great way to word it, but rather this is just what happens due to how the event processing system interacts with the DataExchangeHost.

Using a synchronous handler with e.DataView.GetStorageItemsAsync().GetAwaiter().GetResult() makes the problem go away, and also results in DragEnter working reliably so you aren't processing extra events.


@JJBrychell Perhaps the GetStorageItemsAsync and/or DragEventArgs docs should include a warning about interacting with DragEventArgs in a continuation.

Better yet, DragEventArgs could track when it has become invalid and throw a useful error message as if one were trying to interact with a disposed object.

@Arko109
Copy link
Author

Arko109 commented Jan 30, 2024

.GetAwaiter().GetResult() fixes the exception for me. You can close this issue if you don't need it for following up.

@bpulliam
Copy link
Contributor

bpulliam commented Feb 6, 2024

Closing as dup of #8108

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants