Skip to content
This repository has been archived by the owner on Aug 24, 2022. It is now read-only.

Wondering why some controls work in xamlapp sample and some do not #50

Closed
ericsink opened this issue Jun 29, 2022 · 12 comments
Closed

Wondering why some controls work in xamlapp sample and some do not #50

ericsink opened this issue Jun 29, 2022 · 12 comments
Labels
question Further information is requested

Comments

@ericsink
Copy link

(More of a question than an issue. If this repo had Discussions, this would belong there.)

So the xamlapp sample in this repo works nicely.

But if I replace the Button with, for example, a TextBox, it crashes.

Do we (by which I mean "you all") know why?

RatingControl and ColorPicker crash too.

CalendarDatePicker and DatePicker and Slider do not.

I know I'm probably in unsupported/uncharted territory here, but I'm just curious what's going on. Because, in the Swift projection I've been working on, I get exactly the same results: ericsink/SwiftWinRT#3

In fact, running each of these cases under a debugger, the Rust and Swift versions show the same debug messages before failing.

Any insights would be appreciated.

@riverar riverar added question Further information is requested labels Jun 30, 2022
@riverar
Copy link
Collaborator

riverar commented Jun 30, 2022

Hey @ericsink, yep. You're entering undocumented XAML territory I'm afraid. XAML is tightly coupled with the code generated by its compiler on the client side, code of which we're not currently generating. (There is no XAML compiler for Rust.)

The controls/types you're trying to use need a specialized IXamlMetadataProvider implementation, an instance of XamlControlsXamlMetaDataProvider, and probably a bunch of other things that I haven't even run into yet.

I'm very slowly deriving those requirements from reverse engineering efforts but it's going to take time. Ideally someone from the XAML team would pitch in.

You may want to consider using an alternative UI stack for Rust/Windows development.

Wish I had better words for you.

@ericsink
Copy link
Author

Wow. You mean I need one of those IXamlMetadataProvider things even when I'm not trying to use XAML?

There's a lot I don't know about XAML under the hood, but I think of it as an XML syntax that writes code for me, and if I prefer, I can just write that code myself. In other words, I think of the XML syntax stuff as a layer above, and the lower layer is complete and can be used by itself from C#. Maybe I'm wrong about that? Lots of Microsoft examples seem to show this alternative approach, creating UI from code instead of XML.

@kennykerr
Copy link
Collaborator

If only it were that simple. 🙃

@riverar
Copy link
Collaborator

riverar commented Jun 30, 2022

Wow. You mean I need one of those IXamlMetadataProvider things even when I'm not trying to use XAML?

Yep. These controls are not really designed to be used outside the very narrow context of a C#/C++ XAML app written in Visual Studio.

@ericsink
Copy link
Author

ericsink commented Jul 1, 2022

I've asked a follow-up question over in the Windows App SDK repo:

https://github.com/microsoft/WindowsAppSDK/discussions/2691

... wherein I am trying to explicitly confirm whether it is possible to use those controls from code instead of XAML, but so far it's just crickets.

I wonder if it's possible to create a sample with cppwinrt that uses WinUI3 without XAML syntax to create a TextBox?

are not really designed to be used outside the very narrow context of

Agreed, but... still. I'm just having a lot of trouble making sense of the idea that the layer below can't be used at all from code because it contains dependencies on the layer above. I mean... who does that?

For example: .NET MAUI uses WinUI3 for Windows, but I'm pretty sure it doesn't use WinUI3 XAML. Rather, it has its own dialect of XAML, on all its platforms (which includes iOS and Android, etc).

The MAUI dialect of XAML is implemented in code, and not (pretty sure) on top of WinUI3 XAML. So, MAUI's use of Windows App SDK suggests (perhaps even proves) that the Microsoft.UI.Xaml.* layer can be used from code instead of XAML. Doesn't it?

The MAUI code base does not contain the string "IXamlMetadataProvider".

The only uses of the word "island" in the MAUI code base are in english strings referring to an actual geographical feature.

If I'm being too annoying, let me know and I'll go pester somebody else in my quest for answers. :-)

@ericsink
Copy link
Author

ericsink commented Jul 1, 2022

Wow:

  1. Start with a blank C# WinUI project template. It has a simple window with one Button that says Click Me.
  2. Change it to be Unpackaged
  3. Rewrite the XAML in C# (exercise left for the reader, but fairly straightforward)
  4. Run it. Everything works.
  5. In the code, right after the button, add a TextBox
  6. Now it crashes.
  7. Change it to a DatePicker instead. Now it works fine.
  8. (The behavior is just like my experiments with Rust. Just like my Swift version.)

OTOH, do the same thing, but leave everything in XAML, and add a TextBox in the XAML, and it works fine.

and, deep inside the build output directory, there is a file called XamlTypeInfo.g.cs, which contains:

public partial class App : global::Microsoft.UI.Xaml.Markup.IXamlMetadataProvider

TLDR; I was struggling to make sense of what you said, and I still don't fully understand how all this works, but it looks like you were right.

@riverar
Copy link
Collaborator

riverar commented Jul 1, 2022

Agreed, but... still. I'm just having a lot of trouble making sense of the idea that the layer below can't be used at all from code because it contains dependencies on the layer above. I mean... who does that?

🙃

For example: .NET MAUI uses WinUI3 for Windows, but I'm pretty sure it doesn't use WinUI3 XAML. Rather, it has its own dialect of XAML, on all its platforms (which includes iOS and Android, etc).

When targeting Windows desktop, you're right .NET MAUI leans on WinUI 3. It makes use of XAML markup extensions to, well, extend the markup language without breaking compatibility (e.g. <OnPlatform ... />). This allows everyone to use the same XAML compiler.

If you drop a MAUI app into ildasm or another disassembler, you'll see the same compiler-generated XamlTypeInfo, XamlMetaDataProvider, etc. types.

@ericsink
Copy link
Author

ericsink commented Jul 1, 2022

Indeed.

Here's another data point which is consistent with what you've been saying:

The following project offers a way for people using various XAML-based UIs to avoid XAML and write their UIs in code.

https://github.com/VincentH-Net/CSharpForMarkup

Interestingly, the WinUI samples still have an App.xaml file. And yes, that compiler-generated XamlTypeInfo stuff is present down in the build directories. In other words, it seems to be saying, "yes, you can use WinUI from code, but not completely. You still need the Application object to be XAML so it can do its magic".

@kennykerr
Copy link
Collaborator

Anything's possible depending on how much effort you want to expend. 😉

Here's an attempt a few years back for C++ where you can see how I implement IXamlMetadataProvider to avoid the Xaml compiler, but this is just the tip of the iceberg and the Xaml team have long-since moved on to an even move C#-specific way of doing this.

https://github.com/kennykerr/binding/blob/master/Simpler/xaml.h

@ericsink
Copy link
Author

ericsink commented Jul 3, 2022

Another tidbit:

Yes, MAUI uses WinUI3 for Windows, but its bootstrap code for the Windows platform literally includes an App.xaml file of the WinUI variety (not MAUI XAML).

See dotnet/maui#8413

@riverar
Copy link
Collaborator

riverar commented Aug 16, 2022

Closing this as there's no way forward here; no internal interest in making this work.

@riverar riverar closed this as completed Aug 16, 2022
@ericsink
Copy link
Author

FWIW, I concur. This incarnation of XAML simply works differently than I was expecting.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants