I updated the version of the Telerik controls from 5.0.1 to 6.0.0 and some popups have started to throw errors. The odd thing is that not all popups throw this exception...
In my formatted log (using NLog) I see this when I try to open a certain popup. This popup worked just minutes prior to the upgrade as I added some functionality to it. As soon as I upgraded to 6.0, it bombs...
----------------------------------
2023-07-23 10:15:41.4515 ERROR
Call site: MauiProgram.FirstChanceException
Method name: MobyClient.MauiProgram.FirstChanceException
Line: 0
Exception Type: System.Runtime.InteropServices.COMException
Exception Message: No installed components were detected.
Stack Trace: at WinRT.DelegateExtensions.DynamicInvokeAbi(Delegate del, Object[] invoke_params)
at WinRT.DelegateExtensions.DynamicInvokeAbi(Delegate del, Object[] invoke_params)
at ABI.System.Collections.Generic.IVectorMethods`1.Append(IObjectReference obj, T value)
at Microsoft.Maui.Handlers.ViewHandler`2.SetupContainer()
at Microsoft.Maui.Handlers.LabelHandler.SetupContainer()
at Microsoft.Maui.Handlers.LabelHandler.MapBackground(ILabelHandler handler, ILabel label)
at Microsoft.Maui.Controls.Element.OnPropertyChanged(String propertyName)
at Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, Boolean silent)
at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes)
at Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value, Boolean fromStyle, Boolean checkAccess)
at Microsoft.Maui.Controls.Setter.Apply(BindableObject target, Boolean fromStyle)
at Microsoft.Maui.Controls.Style.ApplyCore(BindableObject bindable, Style basedOn)
at Microsoft.Maui.Controls.Style.Microsoft.Maui.Controls.IStyle.Apply(BindableObject bindable)
at Microsoft.Maui.Controls.MergedStyle.SetStyle(IStyle implicitStyle, IList`1 classStyles, IStyle style)
at Microsoft.Maui.Controls.MergedStyle.OnImplicitStyleChanged()
at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes)
at Microsoft.Maui.Controls.Element.OnResourcesChanged(IEnumerable`1 values)
at Microsoft.Maui.Controls.VisualElement.OnParentResourcesChanged(IEnumerable`1 values)
at Microsoft.Maui.Controls.Element.OnResourcesChanged(IEnumerable`1 values)
at Microsoft.Maui.Controls.VisualElement.OnParentResourcesChanged(IEnumerable`1 values)
at Microsoft.Maui.Controls.Element.OnResourcesChanged(IEnumerable`1 values)
at Microsoft.Maui.Controls.VisualElement.OnParentResourcesChanged(IEnumerable`1 values)
at Microsoft.Maui.Controls.Element.OnResourcesChanged(IEnumerable`1 values)
at Microsoft.Maui.Controls.VisualElement.OnParentResourcesChanged(IEnumerable`1 values)
at Microsoft.Maui.Controls.Element.OnResourcesChanged(IEnumerable`1 values)
at Microsoft.Maui.Controls.VisualElement.OnParentResourcesChanged(IEnumerable`1 values)
at Microsoft.Maui.Controls.Element.set_Parent(Element value)
at Telerik.Maui.Controls.PopupBase.IsOpenPropertyChanged(Boolean oldValue, Boolean newValue)
at Telerik.Maui.Controls.PopupBase.<>c.<.cctor>b__124_0(BindableObject b, Object o, Object n)
at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes)
at Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value, Boolean fromStyle, Boolean checkAccess)
at Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value)
at Telerik.Maui.Controls.PopupBase.set_IsOpen(Boolean value)
at MobyClient.ViewModels.InvitationsViewModel.FindSomeone() in C:\Development\MobyNet\Dev\MobyClient\MobyClient\ViewModels\InvitationsViewModel.cs:line 121
at CommunityToolkit.Mvvm.Input.RelayCommand.Execute(Object parameter)
at Telerik.Maui.Controls.ButtonToolbarItemView.ExecuteCommand()
at Telerik.Maui.Controls.ButtonToolbarItemView.OnClicked()
at Telerik.Maui.Controls.ButtonToolbarItemView.Telerik.Maui.Controls.IToolStripClickableView.OnClicked()
at Telerik.Maui.Controls.RadToolbar.OnContentTapped(Point touchLocation)
at Telerik.Maui.Controls.RadToolbar.OnContentTapped(Object sender, ITouchLocation eventArgs)
at Telerik.Maui.NativeGestureRecognizer.NativeView_Tapped(Object sender, TappedRoutedEventArgs e)
at WinRT._EventSource_global__Microsoft_UI_Xaml_Input_TappedEventHandler.EventState.<GetEventInvoke>b__1_0(Object sender, TappedRoutedEventArgs e)
at ABI.Microsoft.UI.Xaml.Input.TappedEventHandler.Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e)
Additional Info: System.Runtime.InteropServices.COMException: No installed components were detected.
----------------------------------
The error message is horrible as it provides no additional context, so I have no idea what is missing!
Up until this morning, I had my NuGet package manager looking here https://api.nuget.org/v3/index.json and selected the new version. This is when the errors started. It was working just minutes prior when I was using 5.0.1. So, I downloaded the msi and installed it. That didn't fix it so I pointed my NuGet Telerik source to the local packages C:\Program Files\Telerik\Telerik_UI_for_Maui_600\Packages, found the 6.0 package and still no success. When I downgrade to 5.1 (not 5.0.1) it works...
I have a popup service that defines the popup that doesn't work as follows:
public void InitializePopups () { if (_isInitialized) return; // Find someone popup. FindContactsViewModel = new FindContactsViewModel (_logger, _mobyConfigurationManager, this); var popupContent = (View) Application.Current.Resources["FindContactsPopup"]; popupContent.BindingContext = FindContactsViewModel; FindSomeonePopup = new RadPopup { Content = popupContent, Placement = PlacementMode.Center }; // Find someone results popup. FindContactsResultsViewModel = new FindContactsResultsViewModel (_logger, this); popupContent = (View) Application.Current.Resources["FindContactsResultsPopup"]; popupContent.BindingContext = FindContactsResultsViewModel; FindSomeoneResultsPopup = new RadPopup { Content = popupContent, Placement = PlacementMode.Center }; _logger.Debug ($"{GetType ().Name} is initialized."); _isInitialized = true; }
The xaml that I use for these two popups is:
<!--
Common Popups
-->
<!-- Find Contacts Popup -->
<telerik:RadBorder
x:DataType="viewModels:FindContactsViewModel"
x:Key="FindContactsPopup"
BackgroundColor="{StaticResource Background_Dark}"
BorderColor="Lime"
BorderThickness="1"
CornerRadius="8"
HorizontalOptions="Center"
Padding="10"
VerticalOptions="Start"
WidthRequest="400">
<Grid
RowDefinitions="*, Auto"
Margin="3">
<telerik:RadBorder
Grid.Row="0"
BackgroundColor="{StaticResource Background_Dark}"
BorderColor="White"
BorderThickness="1"
CornerRadius="8"
Padding="5"
VerticalOptions="Start">
<Grid
RowDefinitions="Auto, *"
Margin="3">
<Label
Grid.Row="0"
FontSize="16"
FontAttributes="Bold"
HorizontalOptions="Center"
Text="{x:Static strings:LabelResources.LabelFindContactsHeader}"
TextColor="White"
VerticalOptions="Start" />
<Editor
Grid.Row="1"
AutoSize="TextChanges"
BackgroundColor="White"
Margin="1,11,1,1"
Placeholder="{x:Static strings:LabelResources.PlaceholderEnterAddressesToFind}"
PlaceholderColor="Gray"
Text="{Binding FindSomeoneList}"
TextColor="Black"
VerticalOptions="Start" />
</Grid>
</telerik:RadBorder>
<HorizontalStackLayout
Grid.Row="1"
HorizontalOptions="End"
Margin="0,10,0,0"
VerticalOptions="End">
<telerik:RadButton
Command="{Binding ShowFindSomeoneResultsCommand}"
FontSize="14"
HeightRequest="40"
Text="{x:Static strings:LabelResources.LabelFind}"
WidthRequest="90" />
<telerik:RadButton
Command="{Binding CancelFindContactsCommand}"
FontSize="14"
HeightRequest="40"
Margin="8,0,0,0"
Text="{x:Static strings:LabelResources.LabelCancel}"
WidthRequest="90" />
</HorizontalStackLayout>
</Grid>
</telerik:RadBorder>
<!-- Find Contacts Results Popup -->
<telerik:RadBorder
x:DataType="viewModels:FindContactsResultsViewModel"
x:Key="FindContactsResultsPopup"
BackgroundColor="{StaticResource Background_Dark}"
BorderColor="Lime"
BorderThickness="1"
CornerRadius="8"
HorizontalOptions="Center"
Padding="10"
VerticalOptions="Start"
WidthRequest="400">
<Grid
RowDefinitions="*, Auto"
Margin="3">
<telerik:RadBorder
Grid.Row="0"
BackgroundColor="{StaticResource Background_Dark}"
BorderColor="White"
BorderThickness="1"
CornerRadius="8"
Padding="5"
VerticalOptions="Start">
<Grid
RowDefinitions="Auto, *"
Margin="3">
<Label
Grid.Row="0"
FontSize="16"
FontAttributes="Bold"
HorizontalOptions="Center"
Text="{x:Static strings:LabelResources.LabelFindContactsResultsHeader}"
TextColor="White"
VerticalOptions="Start" />
<telerik:RadDataGrid
x:DataType="viewModels:FindContactsViewModel"
x:FieldModifier="Public"
x:Name="FindContactsDataGrid"
Grid.Row="1"
AutoGenerateColumns="False"
BackgroundColor="White"
CanUserReorderColumns="False"
CanUserResizeColumns="True"
CurrentCellStyle="{StaticResource CurrentCellStyle}"
GridLinesColor="LightGray"
GridLinesThickness="1"
GridLinesVisibility="Both"
GroupHeaderStyle="{StaticResource GroupHeaderStyle}"
HeightRequest="400"
ItemsSource="{Binding Contacts}"
Margin="1,11,1,1"
MouseHoverStyle="{StaticResource MouseHoverStyle}"
RowBackgroundStyle="{StaticResource RowBackgroundStyle}"
RowHeight="30"
SelectionMode="None"
SelectionStyle="{StaticResource SelectionStyle}"
SelectionUnit="Row"
ShowColumnFooters="False"
ShowGroupFooters="False"
ShowGroupHeaderAggregates="False"
UserEditMode="None"
UserFilterMode="Disabled"
UserGroupMode="Disabled"
UserSortMode="Multiple">
<telerik:RadDataGrid.Columns>
<telerik:DataGridTextColumn
CellContentStyle="{StaticResource CellContentStyle}"
HeaderStyle="{StaticResource ColumHeaderStyle}"
HeaderText="{x:Static strings:LabelResources.LabelContactId}"
PropertyName="ContactId"
SizeMode="Stretch" />
<telerik:DataGridTextColumn
CellContentStyle="{StaticResource CellContentStyle}"
HeaderStyle="{StaticResource ColumHeaderStyle}"
HeaderText="{x:Static strings:LabelResources.LabelMobyUser}"
SizeMode="Auto">
<telerik:DataGridTextColumn.CellContentTemplate>
<DataTemplate>
<Label
HorizontalOptions="Center"
Margin="0"
Padding="8,0,0,0"
Text="{Binding IsMobyUser, Converter={StaticResource BoolToString}, ConverterParameter='YesNo'}"
TextColor="Black"
VerticalOptions="Center" />
</DataTemplate>
</telerik:DataGridTextColumn.CellContentTemplate>
</telerik:DataGridTextColumn>
</telerik:RadDataGrid.Columns>
</telerik:RadDataGrid>
</Grid>
</telerik:RadBorder>
<HorizontalStackLayout
Grid.Row="1"
HorizontalOptions="End"
Margin="0,10,0,0"
VerticalOptions="End">
<telerik:RadButton
Command="{Binding CloseFindContactsResultsCommand}"
FontSize="14"
HeightRequest="40"
Text="{x:Static strings:LabelResources.LabelClose}"
WidthRequest="90" />
</HorizontalStackLayout>
</Grid>
</telerik:RadBorder>
I have attached two screenshots showing that they do work...
Like I said, when I downgraded to 5.1 it works. The popups worked just minutes prior to the upgrade to 6.0.0. Other popups do work which makes this even more mystifying... These two above do not work and I cannot put my finger on why. I NEED the rich text editor that is in the new package so I need to upgrade pronto!
Looking forward to your response!
Steve
Hi Steve, can you please confirm that you did a complete Clean and Rebuild after updating? This is critical because Visual Studio is intentionally efficient when you compile code... it will not replace DLLs that were cached from the last build. The error here looks a lot like when the project was not built fully after updating.
So let me take you through a set of steps to follow.
This will force VS2022 to actually pull a fresh copy of the DLLs from the NuGet packages instead of using the old ones form the last build. so this time, when you deploy the project, it should be up to date.
Hi Lance,
I never do just a build... I always do a rebuild as it does an implicit clean and build.
I found out what the issue was. I still think there is some work you guys need to do to get this straightened out, but...
I have a common popup that I have on several of my pages. Instead of duplicating the code that controls these popups, I refactored the code into a popup service. I initialize the service very early in my application's startup and found that the placement target on the popup is the culprit. I was assigning the target to be Application.Current?.MainPage which at that point in the startup, MainPage is null. So, the service has an invalid placement target.
Coming back to the error that is thrown by the Telerik popup code says:
which is nowhere near describing the actual exception. This code WORKED in v5.1 so something changed. Again, poor messages in the exceptions wasted hours of my time having to figure out what broke.
So, "No installed components were detected" was a red herring and did nothing to help debug the situation. What I did was back out of the refactored approach and having duplicated code throughout my app which I absolutely detest.
The bottom line is I have moved beyond getting 6.0 installed and "working" but your code has some new bug that someone needs to look into.
Regards, Steve
Hi Stephen, are you using MAUI's new DependencyService system? You didn't mention this was in a service through .NET 6/7's DI, this changes everything.
Such problems are known in .NET MAUI. It is because when .NET MAUI registers services that try to create concrete instances much too early... hence why your App.Current.MainPage was still null... the MAUI layer still wasn't ready yet, so you can't expect other controls that rely on the Maui application object to be ready either. So if you have a service that is expecting a view, it will not work and throw a not-so-clear exception like "no components installed",
The easiest way to handle this to do it is to trying using AddSingleton<MyServiceWhichDependsOnViewHandlerReadiness>, I can't explain exactly why this works yet as I haven't compiled it against the .NET MAUI source code.
This is particularly important when using 3rd party controls that require handlers, because our code cannot run until the platform is ready. so if your service gets instantiated by the DI system, the views are null and our handler's platform-specific elements are still null.
To add an extra layer of importance, the RadPopup is not a .NET MAUI construct. It is a custom native platform implementation that provides more feature capability that anything in the .NET MAUI layer can provide (e.g., attaching to the native visual tree root to allow for special popups). This again requires that the handlers have finished loading and there are concrete native views available.
Moving Forward
I will pass this on to the MAUI dev team. What I do know is they actually fixed issues when using AddSingleton, between 5.1.0 and 6.0.0, so you should be fine moving forward with the suggested AddSingleton approach.
If using AddSingleton doesn't work, then I strongly request that you prepare a standalone project that only has your PopupService in it (it only needs a MainPage and throws the exception). Then, open a Bug Report with it attached here => https://feedback.telerik.com/maui.
The repro project is critical in this situation, rather than partial snippets, because it will allow the developers to directly investigate that project against our source code and identify the exact lifecycle issue involved. With it, we can prepare a directly relevant solution for you.
Hi Stephen, don't worry, I'm not reading any of your replies with a negative tone or via combative lens, and I sincerely hope I am not coming across that way for you!
First, I should maybe clear up that the RadPopup does not throw that exception message. It comes from .NET MAUI DI inflation, which appears to swallowing our initial exception, this is outside of our control. According to this GitHub issue, the WinUI team is working on making these exception messages more useful => [Windows] Faced no installed components were detected exception · Issue #8997 · dotnet/maui (in that case, you can see it's a different 3rd party control).
In fact, I emphasize with you because I have personally been here with the same exact problem when registering a view. This is something in .NET MAUI that is very hard to debug unless you were already aware of the DI lifecycle that is very specific to .NET MAUI.
What's Next?
I am familiar with exactly where the code is in the RadPopup that checks for the Application.Current.MainPage, this is what I went looking for after your last update. It was modified between 5.1.0 and 6.0.0, to fix an earlier problem with the app instance not being ready yet. This appears to be intentionally designed to prevent problems when the app is null, because we absolutely require the Maui application object to be ready for the handlers to work. I did inform the developer who is responsible and we are currently awaiting for your reply with repro-able code.
Repro
This is why I am humbly asking you to share your exact service code with us. I cannot open a bug report and escalate to the developers without having code to reproduce it, even if I can point to the exact line in the source code.
To help you along those lines, I have built a compete test app, with view, view model and service registrations. find it attached. Please update with your service code and invocation, so that it causes the exception.
My hope is that we have two options:
Ultimately, without any actionable material to go on, we might be forced to say that RadPopup is not supported in transient DI registrations. There are some controls you cannot get past this fact because the app object is absolutely required due to handler requirements (i.e. native ChartView). For those things that do not support pre-Maui application instantiation, there is a solution using the HandlerChanged event to know when it's ready, but I don't think that's needed here because of what I show in my demo with the dynamic replacement of the target.
If you can reply to me with an updated version of the project that reproduces the exception, I will be happy to escalate it to the developers for direct review against the recent changes.