Search code examples
mauimaui-windows

.Net Maui FilePicker doesn't respond after clicking File (Async vs Result)


I'm new to Maui and am using the FilePicker but am running into a strange issue. Using the standard Maui Project template is Visual Studio 2022.. I have cloned the "Click Me" button and mapped it to second version of an event.

Button 1 calls this function (which works)

    private async void OnCounterClicked1(object sender, EventArgs e)
    {
        FileResult myFileResult = await FilePicker.PickAsync();
        await DisplayAlert("File Picker Result", myFileResult.FullPath, "OK");
    }

Button 2 calls this function (Once I select the file, the dialog closes but the code never returns and just hangs)

private void OnCounterClicked2(object sender, EventArgs e)
{
    FileResult myFileResult = FilePicker.PickAsync().Result;
    DisplayAlert("File Picker Result", myFileResult.FullPath, "OK");
}

I will admit I'm not the greatest at dealing with Async, but normally, for all other Async calls I've used in .NET, using the ".Result" works in place of the Async, but here it hangs.

  • NOTE * This is a simple example to reproduce the issue. My actual program is layers deep by the time I use the FilePicker.

**** UPDATE ****

Well I thought I got it working using this. Turns out it works for Windows, but not Android....

    private void OnCounterClicked3(object sender, EventArgs e)
    {
        FileResult myFileResult = null;

        Task.Run(async () =>
        {
            myFileResult = await FilePicker.PickAsync();
        }).Wait();

        if (myFileResult != null)
        {
            DisplayAlert("File Picker Result", myFileResult.FullPath, "OK");
        }
    }

Solution

  • After my 3rd variation did not work on Android, I had no choice but to go up the call stack and turn everything into Async and deal with Task Returns. Seems like it requires the actual Click event to be Async which in turn trickles down.

    So in my actual program, it now has to look more like this, starting with the initial Click Event ...

    private async void buttonClicked(object sender, EventArgs e)
    {
      Button myButton = (Button)sender;
      switch (Convert.ToString(myButton.CommandParameter))
      {
        case "LOCAL":
            if (await GetFileLocal() == true)
            {
               await Navigation.PopAsync(true);
            }
            break;
    
        case "SMB":
            if (GetFileSMB() == true)  //This one is Sync
            {
               await Navigation.PopAsync(true);
            }
            break;
    
        default:
            break;
      }
    
    }
    

    and then the problem function has to be defined as...

    private async Task<bool> GetFileLocal()
    {
        FileResult myFileResult = await FilePicker.PickAsync();
        //...Do File Copy Logic ...   
        await DisplayAlert("Success", "File Copied", "OK");
        return true;
    }        
    

    where the other function(s) can be used like normal...

    private bool GetFileSMB()
    {
        //...Do File Copy Logic ...   
        DisplayAlert("Success", "File Copied", "OK");
        return true
    }