I'm getting closer to releasing my next app (tentatively called "Simple Exporter for Bing Maps Collections"), I'm running into more silly issues with both Visual Studio 2022 and with the WinUI3 toolkit.
Error box fit-and-finish
Let's start with terrible fit-and-finish. This is the "Error" list that Visual Studio 2022 shows to help consolidate all errors. Take a look in particular at the column spacing, but also look at the vertical alignment.
The most important information is probably the description; it's squeezed into a narrow column. The project name (arguably the least important information) is given a super wide column by default. And because the description is so narrow, the critical code, file, and line number data isn't even visible.
But wait, the fit and finish is actually worse than it appears. The actual error is that while removing some code, I removed the backing code from my .CS file but I haven't removed it from my .XAML UX file. As a reminder, XAML is the go-to for Windows UX work, and has been ever since the Windows Presentation Foundation (WPF) was created for Vista. It's the foundation (albeit with forks) for the Silverlight web plugin, it was the UX for Windows Phone 7 (and was redone for Windows Phone 8), it was the UX for the "Metro" apps in the giant Windows 8 update.
After all this time, Visual Studio can't figure out that the code as written is in the XAML file, not the generated .g.cs file. And that with the .g.cs file having a comment saying exactly where the code is from.
Continuing issues with the Windows model: XamlRoot
Fixing the This element does not have a XamlRoot. Either set the XamlRoot property or add the element to a tree.' exception.
Looking at the documentation, the C# sample code doesn't include setting the XamlRoot until very far down in the documentation. You have to set the XamlRoot is your app uses an "AppWindow" instead of an "ApplicationView". Note that the app framework is 100% boilerplate. This is the entire description of a WinUI3 project from Visual Studio 2022:
Note that "uses AppWindow" isn't mentioned. There's essentially no useful documentation on why there's this switch, or why in one framework the topmost thing is a "ApplicationView" but into another the work Application is shorter and now it's a "View". Nor does the winUI3 docs say anything about this, and in any event, AFAICT the AppWindow is marked as being preview for the last 5 years.
And let's keep on the HWND issue with Pickers
Micro-gripe: the URL https://aka.ms/cswinrt/interop#windows-sdk in fact takes me to the GitHub repo for the docs, not the actual learn.microsoft.com page.
Let's unpack the terrible, terrible usability of this. For a Picker to work, it needs to know the HWND that it should be attached to. If you don't set this, you get the exception. But there's no good way (AFAICT) for a control to even know the HWND they are part off.
My eventual solution: the MainWindow.xaml.cs, in the constructor, will set a public AppWindowHandleHwnd public property that I added to my user control. Why do a push, and not have the control pull the value? Because the user control is intended to be generic: it doesn't know much at all about the environment that it's in, and certainly doesn't know anything about the application it's in. So there's no way for the control to "know" what the MainWindow is. On the other hand, the MainWindow.xaml.cs file is the program, and it certainly knows all about the underlying controls that are used by the application and knows all the requirements that the control exposes.
Utter failures suggested by Microsoft:
Using "WinRT.Interop.WindowNative.GetWindowHandle(this)" as suggested by Retrieve a window handle (HWND) - Windows apps | Microsoft Learn . But that only works for an object of type Window and not for just any ordinary FrameworkElement-derived object like a UserControl. IMHO, "calling from a UserControl" is going to be like 99% of the time.
The error you get, BTW, is a runtime error, not a compile time error, and looks like this:
System.InvalidCastException: 'Failed to create a CCW for object of type 'SimpleExportBingMapsCollection.BingMapsExtractorControl' for interface with IID 'EECDBF0E-BAE9-4CB6-A68E-9598E1CB57BB': the specified cast is not valid.'
And WTF is up with "Failed to create a CCW for object of type...". It's most likely a COM Callable Wrapper - .NET | Microsoft Learn. But's it's an incredibly wonky phrase to add to the exception.
As an alternative, a Microsoft person also suggested using the VisualTree.GetParent() method, which is ridiculous. That method only returns XAML UIElement parents, and the Window isn't one of those.
No comments:
Post a Comment