Reputation: 99
I have a button in my Xaml code like this:
<Button x:Name="PickFolderButton" Click="PickFolderButton_Click"/>
and the code behind is this:
private async void PickFolderButton_Click(object sender, RoutedEventArgs e)
{
BackupDestinationText.Text = "";
FolderPicker openPicker = new FolderPicker();
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
WinRT.Interop.InitializeWithWindow.Initialize(openPicker, hWnd);
openPicker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
openPicker.FileTypeFilter.Add("*");
StorageFolder folder = await openPicker.PickSingleFolderAsync();
if (folder != null)
{
StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolderToken", folder);
BackupDestinationText.Text = folder.Path;
}
else
{
BackupDestinationText.Text = "Operation cancelled";
}
}
Yet, if I run this code (press the button), then I get a general break, it points to the file App.g.i.cs
, line 68, global::System.Diagnostics.Debugger.Break();
, which is not helpful at all (see image for an inline image).
After @Simon Mourier's suggestion, I tried using the debugger to get more info on the error, with it, I got this error in the DispatcherQueueSynchronizationContext.cs
file, which is read only:
System.InvalidCastException
HResult=0x80004002
Message=Specified cast is not valid.
Source=WinRT.Runtime
StackTrace:
at WinRT.ComWrappersSupport.CreateCCWForObjectForABI(Object obj, Guid iid) in WinRT\ComWrappersSupport.cs:line 888
at WinRT.MarshalInspectable`1.CreateMarshaler2(T o, Guid iid, Boolean unwrapObject) in WinRT\MarshalInspectable.cs:line 53
at WinRT.Interop.IWindowNativeMethods.get_WindowHandle(Object _obj) in WinRT.Interop\IWindowNativeMethods.cs:line 11
at WinRT.Interop.WindowNative.GetWindowHandle(Object target) in WinRT.Interop\WindowNative.cs:line 9
at BackupTool.Views.NewProfilePage.<PickFolderButton_Click>d__10.MoveNext() in C:\Users\user\source\repos-private\BackupTool\Views\NewProfilePage.xaml.cs:line 126
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state) in System.Threading.Tasks\Task.cs:line 1851
at Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.<>c__DisplayClass2_0.<Post>b__0() in Microsoft.UI.Dispatching\DispatcherQueueSynchronizationContext.cs:line 29
This exception was originally thrown at this call stack:
WinRT.ComWrappersSupport.CreateCCWForObjectForABI(object, System.Guid) in ComWrappersSupport.cs
WinRT.MarshalInspectable<T>.CreateMarshaler2(T, System.Guid, bool) in MarshalInspectable.cs
WinRT.Interop.IWindowNativeMethods.get_WindowHandle(object) in IWindowNativeMethods.cs
WinRT.Interop.WindowNative.GetWindowHandle(object) in WindowNative.cs
BackupTool.Views.NewProfilePage.PickFolderButton_Click(object, Microsoft.UI.Xaml.RoutedEventArgs) in NewProfilePage.xaml.cs
System.Threading.Tasks.Task.ThrowAsync.AnonymousMethod__128_0(object) in Task.cs
Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.Post.AnonymousMethod__0() in DispatcherQueueSynchronizationContext.cs```
After some trial and error, it seems that following line in by button code is the culprit:
```cs
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
It seems like the same issue as this post, on which the working answer was this from @mm8. It goes as follows:
Change the modifier for the m_window field in App.xaml.cs:
internal Window m_window;
...or better yet expose it through a property:
public Window Window => m_window;
Then you can access the window from the page like this:
var window = (Application.Current as App)?.m_window as MainWindow;
or
var window = (Application.Current as App)?.Window as MainWindow;
I've tried adding both proposed solutions to my App.xaml.cs
file, of which only the first one did not get an error (second one said: CS0103 The name 'm_window' does not exist in the current context
), yet it didn't work (probably because m_Window
was never in App.xaml.cs
to begin with).
How can I use var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
?
Upvotes: 0
Views: 41