How can we improve the Windows dev platform?

Can you bring back cppwinrt's xaml programmatic support

Earlier this year (but with cppwinrt still new!) I created a complete complex UI using cppwinrt's programmatic support for xaml: e.g. StackPanel(), Grid(), RowDefinitions, Column Definitions, Children().append(), etc. Quite a lot of work but it easy to read and ran great. Is all of that gone? Or is there still a way to use those cppwinrt features?

2 votes
Sign in
Check!
(thinking…)
Reset
or sign in with
  • facebook
  • google
    Password icon
    Signed in as (Sign out)

    We’ll send you updates on this idea

    Jeff Evans shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →

    15 comments

    Sign in
    Check!
    (thinking…)
    Reset
    or sign in with
    • facebook
    • google
      Password icon
      Signed in as (Sign out)
      Submitting...
      • Jeff Evans commented  ·   ·  Flag as inappropriate

        Bingo. That did the job. Much obliged, Brent and Daniel. I needed to rebuild the project to begin with; it had finally gotten too messed up during experiments. But here is what I believe was the original problem (aside from the missing declaration, which really ought to be included in BlankApp, I should think). In my previous functional version of the app I was beginning in MainPage by creating a Grid, then getting the current Window and then setting Window.content(theGrid). In the code Brent provided he set the content of MainPage instead, e.g.
        this->Content(theGrid). For some reason the method I used before no longer works, but assigning to MainPage that way does work. Just what I needed. C++/Winrt is the only way to fly.

      • Jeff Evans commented  ·   ·  Flag as inappropriate

        Daniel, that does work. I added using namespace Windows::UI::Xaml::Controls to get the Button. I uncommented InitializeComponent() and uncommented /*this->*/ - I think you're using a convention there I'm not familiar with. The button appeared in the view. Maybe it's nothing more than the manner of assigning content. In my other project it was Window.Content(theGrid), not this->Content(theElement). I will work with that and see what happens. Really appreciate your responding; I'll confirm the results either way.

      • Jeff Evans commented  ·   ·  Flag as inappropriate

        [Update] I created BlankApp again, this time not even renaming it. When I got the error message about XamlTypeInfo this time I pasted the recommended declaration into App.idl instead of MainPage.idl. I was asked to change the target OS minimum, and changed it to the target 10.0.17666.0. This builds and runs - Now I will try the xaml commands, but I wanted to post this quickly.

      • Jeff Evans commented  ·   ·  Flag as inappropriate

        OK - First I created BlankApp, called it TestApp, and tried running it with no changes at all. That produces two errors like this one: "C1083 Cannot open include file: 'XamlMetaDataProvider.g.h: No such source file or directory (compiling source file App.cpp)" The same error appears for Generated Files\XamlTypeInfo.impl.app. Clicking on the error gives me the advice that I need a declaration in my IDL for the XamlMetaDataProvider runtime class. I paste the recommended declaration into MainPage.idl, and then I get different errors that I didn't see last time: "Cannot open include file: 'XamlMetaDataProvider.g.h...(compiling source file module.g.cpp)" "Cannot open TestApp.XamlMetaDataProvider.g.h...(compiling App.cpp), and the same for compiling \XamlTypeInfo.Impl.g.cpp - So far I'm not able to get far enough this time to test your suggestion below. This is VS 15.9.0 Preview 3, target and minimum set to 10.0.17666.0. Running on Home Insider Preview 1809, build 18252.1000.

      • Brent Rector commented  ·   ·  Flag as inappropriate

        Can you create a new BlankApp, and change it to the following. That should verify whether the basics are working.

        ...
        using namespace Windows::UI::Xaml::Controls;
        ...
        MainPage::MainPage()
        {
        // InitializeComponent();
        Button button;
        button.Content(winrt::box_value(L"Hello"));
        /*this->*/Content(button);
        }

      • Jeff Evans commented  ·   ·  Flag as inappropriate

        If you need it I can put up an archive and give you a link. But it's just the BlankApp with xaml designer disabled in tools/options/xaml, and the window.Content() set to a Grid with some other elements added.

      • Jeff Evans commented  ·   ·  Flag as inappropriate

        Daniel, thanks very much. I think you'd get the same results just by starting a BlankApp for cpwinrt using the new VS Preview, but I can create a package of my own effort and send that if it will help. Not sure how to to attach that in this comment section, though.

      • Daniel commented  ·   ·  Flag as inappropriate

        I'm on the Xaml team and we did not remove any functionality for C++\WinRT projects. I could help you figure out what's going on if you could share a sample project that exhibits the behavior you described. Thanks!

      • Jeff Evans commented  ·   ·  Flag as inappropriate

        If someone involved in the cppwinrt project is reading, perhaps they could use the current VS preview to create its default BlankApp for for cppwinrt and then try modifying the xaml programmatically, using StackPanel(), Grid(), etc. to add elements. I think they will see what I saw (i.e. nothing), but they will know better than I what needs to be changed in the BlankApp.

      • Jeff Evans commented  ·   ·  Flag as inappropriate

        (p.s. the BlankApp originally had a sample button inside the default Page, which appeared and worked. I removed the button in the xaml for that Page, and now see just the blank page). But this Page is the window content, when what I want is for my own content to appear, beginning with that Grid. My assignment of content to the current window simply has no effect. Yet it did in my previous version of this app, which was built on one of Kenny's sample projects called xamlbutton. I switched to the new BlankApp as a starting point in order to more easily use Win2D.

      • Jeff Evans commented  ·   ·  Flag as inappropriate

        Leaving out the rowdefinitions, etc. the essence of that crucial first step is
        Grid mainView = Grid();
        Window theWindow = Window::Current();
        Window.Content(mainView);
        There's nothing to step into in that assignment of the grid as the window content; it's just that the grid and its contents never appear. But the blankapp is creating - has created - a xaml file of its own that consists of a <Page>. This blank page is what is seen. But if I remove that xaml file the app will not build and the errors are obscure. It is expecting me to add the interface to that file as xaml code. Seems to me there must be a configuration issue in the default blank app. My guess is that it has to do with mainpage.g.h, which references that initial <Page>, and the large list of generated files that weren't there in my other app. What would be really great would be a default blankapp already configured to use cppwinrt's programmatic xaml features.

      • Brent Rector commented  ·   ·  Flag as inappropriate

        Fortunately, there is one huge advantage with C++/WinRT. You have all the source so can debug into it. :)

        I'm not a XAML guy. I say that up front so I don't appear to have experience that I do not. :) But it sounds like you're doing all the correct things to create the tree of UI elements. That should be unchanged and work as it did before.

        I suspect, but this is speculation, that setting the tree as the content of the current window is failing for some reason. I suspect it because that's where you are handing off your programmatically created tree to the XAML markup created element. There may be some subtly there.

        Can you debug into that call and see if anything jumps out?

      • Jeff Evans commented  ·   ·  Flag as inappropriate

        Brent, thanks, this is hopeful. I had been told by someone at Stackpanel that programmatic xaml was not possible. I have been folding my previous code into the new blank app created by VS as a starting place for cppwinrt apps. I get no errors when, for example, that code creates a Grid with Grid() and sets that as the content of the current window, as it did before. Nor are there any errors when I set rows and columns as before, and when I use StackPanel() and add the resulting stackpanel to the Grid with theGrid.Children().append(theStackpanel), and so on. But none of this appears in the window content. I see that the generated file directory is now full of generated files, whereas in my previous app there was nothing in there except winrt. Probably there is some kind of change I need to make to the configuration of the blankapp.

      • Brent Rector commented  ·   ·  Flag as inappropriate

        There's no need to "bring it back". It never left. :)

        Anything you did programmatically with XAML using C++/WinRT continues to work as it did before.

        At //Build, when we released the XAML support, it *added* the ability to use XAML markup, invoke the XAML compiler, automatically integrate all that tooling into your project build.

        Programmatically using XAML types via C++/WinRT is no different than programmatically using any other Windows Runtime type using C++/WinRT. Instantiate the type and call methods on it.

        winrt::Windows::UI::Xaml::Controls::Button myButton;
        myButton.SomeProperty (newValue);

        No special settings are required. It sounds like this didn't work for you. What was the specific error?

      • Jeff Evans commented  ·   ·  Flag as inappropriate

        I am told by someone involved with cppwinrt that the programmatic support is still functional! Good news, so maybe this suggestion really needs to be changed to a request for documentation of how to make that work in the BlankApp created by Visual Studio when beginning a new cppwinrt project. Apparently those features are not supported in the default configuration.

      Feedback and Knowledge Base