therealchriswoodward
therealchriswoodward

Reputation: 49

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.

Upvotes: 0

Views: 316

Answers (2)

Andrew KeepCoding
Andrew KeepCoding

Reputation: 13356

You need to pass a Window instead of a Page.

Usually, you make the MainWindow accessible:

App.xaml.cs

public partial class App : Application
{
    public App()
    {
        this.InitializeComponent();
    }

    public static Window Window { get; } = new MainWindow();

    protected override void OnLaunched(LaunchActivatedEventArgs args)
    {
        Window.Activate();
    }
}

Then in your page:

var hWnd = WindowNative.GetWindowHandle(App.Window);

Upvotes: 1

therealchriswoodward
therealchriswoodward

Reputation: 49

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);

Upvotes: -1

Related Questions