Closed nlogozzo closed 2 years ago
@Austin-Lamb and @JesseCol FYI
Gentlemen, i witness the same error with the latest Uno framework even though the dialog's XamlRoot
is assigned to the Shell's one.
@StephenLPeters will you fix this ?
Hey folks, sorry for not noticing this issue earlier. The XamlRoot property only gets set when the element in question gets loaded into a visual tree - that's how we know what tree of XAML content it's associated with. For a UIElement this makes sense, as it could be added to any tree so we can't infer it until it really is in one.
We should consider exposing a Window.XamlRoot property which could be more eagerly available for scenarios like this (@marb2000 please consider that).
For now, what you should do is wait for Window.Content.Loaded to be raised, at which point Window.Content.XamlRoot will be valid - this is true of any UIElement, not just Window.Content, but that's your use case in the code sample above.
@nlogozzo - could you see if that works for your case?
@Austin-Lamb I carry out somethign like this but to no avail :
protected override UIElement CreateShell()
{
var shell = Container.Resolve<Shell>();
#if HAS_UNO_WINUI || NETCOREAPP
shell.Loaded += (s, e) =>
{
MainXamlRoot = (s as UIElement).XamlRoot;
};
#endif
return shell;
}
protected override void InitializeShell(UIElement shell)
{
#if WINDOWS
Window = new Window();
Window.Activate();
#else
Window = Window.Current;
#endif
Window.Content = shell;
}
Window.Content.Loaded
ain't existing inside Uno.
@sigmarsson - I feel like I'm getting lost. Uno is a separate codebase run by the Uno team/company at this github: https://github.com/unoplatform/uno
If this issue only repros in Uno, please report the issue there for their team to look at.
Does this issue repro for you in WinUI 3? And in your screenshot it looks like you're getting an instance of XamlRoot back, so can you clarify what isn't working? Do you happen to have a minimal repro you could share all the code for in case the snippets are not revealing enough about where the problem may be?
@Austin-Lamb , No Doubt !
I am just trying to open a dialog as the Prism's DialogService is harnessed here and this issue hopefully provides more details what is happening and going wrong .
Yes, it is compiled as Uno's WinUI 3 (aka ReUnion 0.8.1 ) Desktop Head, so I thought it is the same WinUI 3 lib. Please tell if I shall delegate this backlog to Uno or I shall ask the Prism engineers again.
And yes, the XamlRoot has value in the callback. Is it worth to use ContentDialog by the way ? I am unable to alter its dimensions, I read somewhere - it is because a legacy UWP architecture restricts it and puts a crimp on changing the width and height.
Should my previous comments not be sufficient to resolve this, I am offering screen sharing rather than git.
Setting here the dialog's XamlRoot
:
I believe this issue is related. I'm trying to show a custom ContentDialog on my Activated event on a C++ WinUI app. Here is the code:
IAsyncAction MainWindow::WindowActivated(const IInspectable& sender, const WindowActivatedEventArgs& args)
{
if (!m_opened)
{
Configuration configuration = Configuration::Load();
if (configuration.IsFirstTimeOpen())
{
WelcomeDialog welcomeDialog;
welcomeDialog.XamlRoot(Menu().XamlRoot());
co_await welcomeDialog.ShowAsync();
}
m_opened = true;
}
}
However, I'm now getting the following issues:
Exception thrown at 0x7666B512 (KernelBase.dll) in NickvisionApplication.exe: WinRT originate error - 0x80070490 : 'Windows.Graphics.Display: GetForCurrentView must be called on a thread that is associated with a CoreWindow.'.
Exception thrown at 0x7666B512 (KernelBase.dll) in NickvisionApplication.exe: WinRT originate error - 0x80070057 : 'This element is already associated with a XamlRoot, it cannot be associated with a different one until it is removed from the previous XamlRoot.'.
Exception thrown at 0x7666B512 (KernelBase.dll) in NickvisionApplication.exe: WinRT originate error - 0x80070490 : 'Windows.Graphics.Display: GetForCurrentView must be called on a thread that is associated with a CoreWindow.'.
Exception thrown at 0x7666B512 (KernelBase.dll) in NickvisionApplication.exe: WinRT originate error - 0x80000019 : 'Only a single ContentDialog can be open at any time.'.
Temporary Fix: Don't use Activated
event of Window
. Instead, create a Loaded
event for the Grid
(or whatever control you have` for the window.
@nlogozzo , I do not know . I do attach to the Shell's Loaded
event.
Your first issue is a threading one; "GetForCurrentView must be called on a thread that is associated with a CoreWindow."
Well I never call GetForCurrentView anywhere in the method nor do I switch threads in that method or in the WelcomeDialog code.
@sigmarsson - It appears you are setting the XamlRoot on your UserControl, but you need to set it on the ContentDialog itself so the dialog knows what tree of content you want it to show up in (what window, basically).
I'm not sure what's going on with the originate errors you're seeing about GetForCurrentView - can you have Visual Studio break on WinRT Originate Error (see the Exceptions window to do this) to get a callstack for when that is happening? You'll need to have a mixed mode debugger attached to get the native bits of the callstack.
@Austin-Lamb , okay i changed the UserControl
to ContentDialog
but to no avail. Same ex.
So the dialog xaml is as now :
<ContentDialog
x:Class="Weather.History.Mvvm.Views.SettingsDialog"
xmlns:prismmvvm="using:Prism.Mvvm"
prismmvvm:ViewModelLocator.AutowireViewModel="True"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:myctr="using:Weather.History.UI.Control"
xmlns:myux="using:Weather.History.Mvvm.Model"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Height="768"
Width="1024">
The XamlRoot magic is left everywhere the same.
I had a same problem with the initialization of a Pivot
. Merely including it in my XAML would crash because it would call GetForCurrentView
in its initialization. I tore my hair out trying to figure it out, copied the code to a new directory, and started adding things in one-by-one. In the end, diff -ur old/ new/
revealed zero differences (except minor differences in generated code) but "old" triggered the crash in Pivot init and "new" didn't. I just deleted "old" and started using "new" instead. Something weird is going on.
@mqudsi , every now an then kick back. we all build applications piece by piece. Sometimes by tiny pieces, hence these projects shall become a hobby rather than a duty at these stages.
I have a UWP app (just UWP, not Uno) that I'm trying to port to WinUI 3 [1.0.0-preview3]. The following code is present in click handler for a button in a XAML page:
var editDialog = new Views.Auth.EditProfileDialog(UserService.CurrentProfile);
if (await editDialog.ShowAsync() == ContentDialogResult.Primary)
{
// ...
}
The exception is thrown at the ShowAsync() call.
As per the docs, there is a need to manually set the XamlRoot on the dialog to the root of the XAML host.
contentDialog.XamlRoot = elementAlreadyInMyAppWindow.XamlRoot;
await contentDialog.ShowAsync();
As per the docs, there is a need to manually set the XamlRoot on the dialog to the root of the XAML host.
contentDialog.XamlRoot = elementAlreadyInMyAppWindow.XamlRoot; await contentDialog.ShowAsync();
Of course, that link is a 404 these days. It's been a whole seven months, I guess it's too much to expect for docs to be that long-lived.
I found this documentation link (updated 07/08/2022) useful. I tried and it works. As the docs said, just manually set the XamlRoot of the ContentDialog as the XamlRoot of one of the elements, or the content, of the windows itself. The reason is:
By default, content dialogs display modally relative to the root ApplicationView. When you use ContentDialog inside of either an AppWindow or a XAML Island, you need to manually set the XamlRoot on the dialog to the root of the XAML host.
The XamlRoot property only gets set when the element in question gets loaded into a visual tree - that's how we know what tree of XAML content it's associated with.
Thank you bro. Austin-Lamb. You saved my time.
The code below solved the problem for me -
var dialog = new ContentDialog { Title = "My Media Collection", Content = "Adding items to the collection is not yet supported.", CloseButtonText = "OK", XamlRoot = this.XamlRoot }; await dialog.ShowAsync();
Also, have a look at the code snippet for ContentDialog in the WinUI 3 Gallery app https://apps.microsoft.com/detail/9p3jfpwwdzrc?hl=en-US&gl=US
private async void ShowDialog_Click(object sender, RoutedEventArgs e) { ContentDialog dialog = new ContentDialog();
// XamlRoot must be set in the case of a ContentDialog running in a Desktop app
dialog.XamlRoot = this.XamlRoot;
dialog.Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style;
dialog.Title = "Save your work?";
dialog.PrimaryButtonText = "Save";
dialog.SecondaryButtonText = "Don't Save";
dialog.CloseButtonText = "Cancel";
dialog.DefaultButton = ContentDialogButton.Primary;
dialog.Content = new ContentDialogContent();
var result = await dialog.ShowAsync();
}
Describe the bug
I have a custom MVVM framework with a ContentDialogService for displaying ContentDialogs inside a ViewModel. However, the ContentDialog requires the XamlRoot property to be set, however the MainWindow's XamlRoot is always null when I debug. and I get this error:
Below is my code for the ContentDialogService, MainWindow XAML, and MainWindow Code-Behind.
Steps to reproduce the bug
Steps to reproduce the behavior:
Nickvision.WinUI
Nuget Package. (When you try to build you'll get an error. See Issue #4983 . You'll have to manually add these two files to the Nuget package (Steps on issue #4454) https://we.tl/t-RlUTQP9xrn)Expected behavior
The ContentDialog should be displayed correctly, without errors.
Version Info
WinUI 3 - Project Reunion 0.5.6 Windows 10 V20H2
NuGet package version: [WinUI 3 - Project Reunion 0.5: 0.5.6] [Nickvision.WinUI V2021.5.0.6-beta]