"LoadFromXaml" inherited from a component does not find the converters used in a ControlTemplate located in another assembly.
See original GitHub issueDescription
Hi Maui Team !
I have created a simple solution to reproduce my issue
-
MainApplication
Contains nothing special exepted DI and application starting.
#define NO_SUCCESS
using CustomerProjet;
using SharedComponent;
namespace MainApplication;
public partial class App : Application
{
public App()
{
InitializeComponent();
#if SUCCESS
// Converter Works when this page is used
MainPage = new SharedPage();
#else
// LoadFromXaml Fails to find Converter when this page is used
MainPage = new CustomerPage();
#endif
}
}
-
SharedComponent
Contains a Shared ControlTemplate with key AppMobileTemplate named MainPage.xaml That template define a bindable property ValueConverted that can be filled by inerited components. This Value is used with a Converter SimpleConverter defined in the template. It converts the given value between 0 and 100 to a color from Red,Orange, Yellow, Green. The converter class is SimpleColorConverter and is defined as public.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:control="clr-namespace:SharedComponent"
x:Class="SharedComponent.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<control:SimpleColorConverter x:Key="SimpleConverter"></control:SimpleColorConverter>
</ResourceDictionary>
<ControlTemplate x:Key="AppMobileTemplate" >
<ScrollView>
<VerticalStackLayout Spacing="25" Padding="30,0" VerticalOptions="Center">
<Label Text="{TemplateBinding TitleText,StringFormat='Templated {0}'}"></Label>
<Label Text="{TemplateBinding ValueConverted,StringFormat='Raw Value {0}'}"></Label>
<Label Text="{TemplateBinding ValueConverted,StringFormat='Converted Value {0}'}"
TextColor="{TemplateBinding ValueConverted, Converter={StaticResource SimpleConverter}}"></Label>
<Label Text="Label From Template" SemanticProperties.HeadingLevel="Level1" FontSize="32" HorizontalOptions="Center" />
<ContentPresenter></ContentPresenter>
</VerticalStackLayout>
</ScrollView>
</ControlTemplate>
</ContentPage.Resources>
</ContentPage>
That project contains also one page SharedPage that use the template and changes randomly the ConvertedValue every 2 secondes.
-
CustomerProject
That project has a reference on the SharedComponent project. It contains a component named CustomerPage that does exactly the same things than SharedPage
When SharedPage is called not problem.
The probleme occurs when CustomerPage is called.
The following exception is thrown
Position 9:14. Type control:SimpleColorConverter not found in xmlns clr-namespace:SharedComponent
Thank you.
Best Regards
Steps to Reproduce
Thing that works
- Open the linked projet.
- In MainApplication => App.xaml.cs => SUCCESS must be defined.
- Run the application on Windows or Android and you should see this :
Thing that fails
- Change SUCCESS to NO_SUCCESS
- Run the solution again on Windows or Android and you should have this now
There’s a subtile nuance on android : If the debugger is attached, the converter is ignored and the label stays black with changing value. Is the application is launched from Android, it simply crashes and stops.
Link to public reproduction project repository
https://github.com/CyrilleMancini/TestBugLoadFromXamlConverter
Version with bug
Unknown/Other
Last version that worked well
Unknown/Other
Affected platforms
Android, Windows
Affected platform versions
Android 11, Windows 11
Did you find any workaround?
I found this workaround :
When I copy the SimpleColorConverter from SharedComponent to CustomerProjet
The application starts and the converter is found.
Relevant log output
_à Microsoft.Maui.Controls.Xaml.CreateValuesVisitor.Visit(ElementNode node, INode parentNode)
à Microsoft.Maui.Controls.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
à Microsoft.Maui.Controls.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
à Microsoft.Maui.Controls.Xaml.ListNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
à Microsoft.Maui.Controls.Xaml.RootNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
à Microsoft.Maui.Controls.Xaml.XamlLoader.Visit(RootNode rootnode, HydrationContext visitorContext, Boolean useDesignProperties)
à Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, String xaml, Assembly rootAssembly, Boolean useDesignProperties)
à Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, String xaml, Boolean useDesignProperties)
à Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, Type callingType)
à Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml[TXaml](TXaml view, Type callingType)
à SharedComponent.MainPage.InitializeComponent() dans C:\Users\cylma\Documents\Projets\TestBugLoadFromXamlConverter\SharedComponent\Microsoft.Maui.Controls.SourceGen\Microsoft.Maui.Controls.SourceGen.CodeBehindGenerator\MainPage.xaml.sg.cs :ligne 22
à SharedComponent.MainPage..ctor() dans C:\Users\cylma\Documents\Projets\TestBugLoadFromXamlConverter\SharedComponent\MainPage.xaml.cs :ligne 26
à CustomerProjet.CustomerPage..ctor() dans C:\Users\cylma\Documents\Projets\TestBugLoadFromXamlConverter\CustomerProjet\CustomerPage.xaml.cs :ligne 10
à MainApplication.App..ctor() dans C:\Users\cylma\Documents\Projets\TestBugLoadFromXamlConverter\MainApplication\App.xaml.cs :ligne 22
à System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
à System.Reflection.ConstructorInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr) dans /_/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs :ligne 103
à System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) dans /_/src/libraries/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs :ligne 290
à Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context) dans /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteRuntimeResolver.cs :ligne 69
à Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) dans /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs :ligne 48
à Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context) dans /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteRuntimeResolver.cs :ligne 92
à Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) dans /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteVisitor.cs :ligne 27
à Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) dans /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteRuntimeResolver.cs :ligne 30
à Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType) dans /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs :ligne 172
à System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
à Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) dans /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs :ligne 131
à Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) dans /_/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs :ligne 90
à Microsoft.Maui.MauiContext.WrappedServiceProvider.GetService(Type serviceType)
à Microsoft.Maui.MauiContext.WrappedServiceProvider.GetService(Type serviceType)
à Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) dans /_/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceProviderServiceExtensions.cs :ligne 45
à Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) dans /_/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceProviderServiceExtensions.cs :ligne 65
à Microsoft.Maui.MauiWinUIApplication.OnLaunched(LaunchActivatedEventArgs args)
à Microsoft.UI.Xaml.Application.Microsoft.UI.Xaml.IApplicationOverrides.OnLaunched(LaunchActivatedEventArgs args)
à ABI.Microsoft.UI.Xaml.IApplicationOverrides.Do_Abi_OnLaunched_0(IntPtr thisPtr, IntPtr args)_
Issue Analytics
- State:
- Created 2 months ago
- Comments:5
Yes… you got it! 👍 Here is a link to what MS says…
XAML namespaces
Well known issue as suggested earlier comment you need to fully qualify it