Search code examples
c#winui-3savefiledialog

WinUI 3: Saving A File; "Specified cast not valid"


I have successfully did this in an app that had nothing but a rich edit box and a menu with a save button.

I am now trying to add it to my other project that has multiple pages. The menu is on page two of the app, and it is no longer working.

Here's my code:

private async void SaveButton_Click(object sender, RoutedEventArgs e)
{
    FileSavePicker savePicker = new FileSavePicker();

    var hWnd = WindowNative.GetWindowHandle(this);

    InitializeWithWindow.Initialize(savePicker, hWnd);

    savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
    savePicker.FileTypeChoices.Add("Plain Text", new List<string>() { ".txt", ".rtf" });
    var enteredFileName = "My Document";
    savePicker.SuggestedFileName = enteredFileName;

    StorageFile file = await savePicker.PickSaveFileAsync();
    if (file != null)
    {
        Windows.Storage.Streams.IRandomAccessStream randAccStream =
            await file.OpenAsync(FileAccessMode.ReadWrite);

        ScratchPad.Document.SaveToStream((TextGetOptions)Windows.UI.Text.TextGetOptions.None, randAccStream);
    }
}

The exception happens at:

var hWnd = WindowNative.GetWindowHandle(this);

I have tried a few different things such as referencing the main window and nothing has fixed it.


Solution

  • This is how to fix the problem I am having. It's almost embarrassingly simple:

    private async void SaveButton_Click(object sender, RoutedEventArgs e)
    {
        FileSavePicker savePicker = new FileSavePicker();
        //-----
        Window win = new();
        //-----
        var hWnd = WindowNative.GetWindowHandle(win);
    
        InitializeWithWindow.Initialize(savePicker, hWnd);
    
        savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
        savePicker.FileTypeChoices.Add("Plain Text", new List<string>() { ".txt", ".rtf" });
        var enteredFileName = "My Document";
        savePicker.SuggestedFileName = enteredFileName;
    
        StorageFile file = await savePicker.PickSaveFileAsync();
        if (file != null)
        {
            Windows.Storage.Streams.IRandomAccessStream randAccStream =
                await file.OpenAsync(FileAccessMode.ReadWrite);
    
            ScratchPad.Document.SaveToStream((TextGetOptions)Windows.UI.Text.TextGetOptions.None, randAccStream);
        }
    }
    

    A new window must be instantiated so:

    Window win = new();
    

    Then "win" can be passed as a parameter rather than "this":

    var hWnd = WindowNative.GetWindowHandle(win);