microsoft / WindowsAppSDK

The Windows App SDK empowers all Windows desktop apps with modern Windows UI, APIs, and platform features, including back-compat support, shipped via NuGet.
https://docs.microsoft.com/windows/apps/windows-app-sdk/
MIT License
3.85k stars 328 forks source link

Migrating UWP app to WindowsAppSDK. Can't navigate to page from Windows Runtime Component #1769

Open timmarriott opened 3 years ago

timmarriott commented 3 years ago

Describe the bug

Internal bug https://task.ms/36925415

App.xaml.cpp is just activates the MainWindow which is exactly what it does out of the box. I attempted to put the page navigation code in there as documented but didn't work. Now MainWindow.xaml had a named <Frame x:Name="rootFrame Loaded="Loaded"/>

In the Loaded Event for the Frame I am calling rootFrame().Navigate(xaml_typename(), *this);

In either case I get an exception thrown: Exception thrown at 0x00007FFB4621466C (KernelBase.dll) in CloudView.exe: WinRT originate error - 0x80004005 : 'Cannot locate resource from 'ms-appx:///BlankPage.xaml'.'.

This is a project added as a WinUI3 Runtime Component inside the Solution. My production code is in a Separate solution and has the same problem.

I tried the same thing using the Windowing Sample cpp-winui from the WindowsAppSDK-Samples.git repo. It works there. The difference is that this uses a separate Packaging Project. The current SDK integrates the packaging into the App.

Steps to reproduce the bug

1) Create a new Solution/Project using the "Blank App, Packaged (WinUI 3 in Desktop), Default names are fine. Don't check Solution in same folder

2) Add a New Project to the Solution using the "Windows Runtime Component (WinUI 3)" template. Default names are fine.

3) Add a New Item to the RuntimeComponent1 Project, using the "Blank Page (WinUI 3)" template. Default names are fine.

4) Build the RuntimeComponent1. Debug, x64 is what I used.

5) Add a Reference in App1 to RuntimeComponent1. Right click>Add>Reference...

6) Edit MainWindow.xaml and make it look like this: <Window x:Class="App1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App1" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">

    </Window>

7) Edit MainWindow.xaml.h. Add the following #includes above #include "MainWindow.g.h"

include <winrt/RuntimeComponent1.h>

        #include <winrt/Windows.UI.Xaml.Interop.h>
   Add the following Loaded Method
        void MainWindow::Loaded(Windows::Foundation::IInspectable sender, Microsoft::UI::Xaml::RoutedEventArgs const& e)
        {
            rootFrame().Navigate(xaml_typename < RuntimeComponent1::BlankPage>(), *this);
        }

8) Edit MainWindow.xaml.cpp and remove the reference to myButton() in the myButton_Click Event.

9) Build and run App1. You will get the exception.

Expected behavior

No response

Screenshots

No response

NuGet package version

1.0.0-preview3

Packaging type

Packaged (MSIX)

Windows version

Windows 11 (22000)

IDE

Visual Studio 2022

Additional context

No response

andrewleader commented 3 years ago

@evelynwu-msft is this the known issue with Component Libraries exposing controls (or in this case Pages) not working with single-project MSIX (issue #1691)?

evelynwu-msft commented 3 years ago

@andrewleader This is a duplicate of internal bug https://task.ms/36925415.

evelynwu-msft commented 3 years ago

@timmarriott Unfortunately this is a known issue for 1.0, but you can work around it by adding the following target to the end (after all imports of .targets files) of your Windows Runtime Component's .vcxproj:

  <Target Name="GetPriIndexName">
    <PropertyGroup>
       <!-- Winmd library targets use the default root namespace of the project for the App package name -->
       <PriIndexName Condition="'$(RootNamespace)' != ''">$(RootNamespace)</PriIndexName>
       <!-- If RootNamespace is empty fall back to TargetName -->
       <PriIndexName Condition="$(PriIndexName) == ''">$(TargetName)</PriIndexName>
     </PropertyGroup>
  </Target>
timmarriott commented 3 years ago

I found that the work around does enable things to work, but not quite right using a Project with integrated MSIX. One issue is that WebView2 does not show the webpage. Also, some bindings don't seem to be working.

If I use the WAP template everything works fine. The work around is needed so Resources work correctly.