Context: We have recently ported an old Xamarin.Forms project into .NET MAUI. We now have the app opening and a working login. The Main Page after logging in is a page where users can log their actions. Currently, if I have a log from the previous day and click an arrow on the page to go see it, I recieved the No Installed Components Detected issue on my SETMODELBINDING method, which is the last method listed below. The following is redacted code:
public DailyLogPage(int dailylogid = 0)
{
dlog = new DailyLogControl();
myid = Guid.NewGuid();
loadingControl = new LoadingControl();
this.Title = "Daily Log";
IconImageSource = "Navigation_Add.png";
this.Disappearing += MainViewPage_Disappearing;
BasePage.InitPage(this);
SetDataRepository();
InitializeCriteria();
CreateDailyLogUI();
CreatePageActions();
SetMessagingCenterSubscriptions();
SetHomeOpco();
AutoSaveAndSync();
}
#region UICode
private void CreateDailyLogUI()
{
CreateTxtDevice();
CreateGrid();
CreateMainScrollView();
stackBody.SetBinding(StackLayout.BackgroundColorProperty, "PageColor.BodyBackground");
this.SetBinding(ContentPage.BackgroundColorProperty, "PageColor.PageBackground");
SetModelBinding(dailylogCriteria.DailyLog);
}
private void CreateTxtDevice()
{
txtDevice = new AutoCompleteView
{
Placeholder = "Enter text",
ShowSearchButton = false,
SuggestionsHeightRequest = 120,
SelectedCommand = new Command(() => { }),
};
txtDevice.EntText.IsVisible = false;
}
private void CreateGrid()
{
AddButton = new Button
{
HeightRequest = 45,
ImageSource = "add_data.png",
BackgroundColor = Colors.Transparent
};
AddButton.Clicked += AddButton_Clicked;
sideStack = new StackLayout();
grid = new Grid
{
ColumnDefinitions =
{
new ColumnDefinition { Width = new GridLength(.05, GridUnitType.Star) },
new ColumnDefinition { Width = new GridLength(.5, GridUnitType.Star) },
new ColumnDefinition { Width = new GridLength(9.45, GridUnitType.Star) },
}
};
grid.Children.Add(sideStack);
Grid.SetColumn(sideStack, 0);
sideStack.Children.Add(AddButton);
grid.Children.Add(sideStack);
Grid.SetColumn(sideStack, 1);
}
private void CreateMainScrollView()
{
dailyLogHeader = new DailyLogStepControlHeader() { IsClippedToBounds = true };
stack = new StackLayout { };
var scrollView = new StackLayout { Children = { stack } };
dailyLogSyncControl = new DailyLogSyncControl { VerticalOptions = LayoutOptions.End, IsClippedToBounds = true };
//Create StackBody
stackBody = new StackLayout
{
Padding = new Thickness(5, 5, 5, 30),
Children =
{
dailyLogHeader,
scrollView
}
};
//Create StackMain
stackmain = new StackLayout
{
Padding = new Thickness(7),
Children =
{
dlog,
stackBody,
dailyLogSyncControl
}
};
//Create MainScrollView
mainScrollView = new ScrollView { Content = stackmain };
Content = mainScrollView;
}
private void CreatePageActions()
{
#region actions
//wire up the next & previous page action button commands here
Action NextPage = async () =>
{
if (!model.DailyLog.ValidData)
{
await DisplayAlert(UIConstants.TITLE, "Location & Purpose are required.", "Ok");
return;
}
await model.SaveData(true);
if (dailylogCriteria.HasNext)
{
dailylogCriteria = _data.GetNextDailyLog(model.DailyLog.DailyLogId);
}
else
{
var newDlog = CreateDailyLog(false);
await _data.SaveDailyLog(newDlog);
dailylogCriteria = _data.GetLastDailyLog();
}
SetModelBinding(dailylogCriteria.DailyLog);
};
Action PreviousPage = async () =>
{
await model.SaveData(true);
if (dailylogCriteria.HasPrevious)
{
dailylogCriteria = _data.GetPreviousDailyLog(model.DailyLog.DailyLogId);
}
else
{
return;
}
SetModelBinding(dailylogCriteria.DailyLog);
};
Action<int> GotoPage = (pageid) =>
{
//CAN THIS FUNCTION EVER BE RUN?
//await model.SaveData(true);
//if (pageid > 0 && pageid <= dailylogCriteria.TotalDailyLogs)
//{
// SetModelBinding(model.DailyLog);
//}
};
#endregion
dlog.SetNextPage(NextPage);
dlog.SetPreviousPage(PreviousPage);
dlog.SetGotoPage(GotoPage);
dlog.IsClippedToBounds = true;
}
private DailyLog CreateDailyLog(bool isLogin)
{
var newDlog = new DailyLog();
//This is redacted data. just setting DailyLog properties to user data(ie, username, opco, etc)
return newDlog;
}
private void SetModelBinding(DailyLog dailyLog)
{
stackmain.Children.Remove(dlog);
model = new DailyLogViewModel(dailyLog)
{
IsFetching = true,
PageCount = dailylogCriteria.TotalDailyLogs,
PageNo = dailylogCriteria.CurrentPage
};
BindingContext = model;
stackmain.Children.Insert(0, dlog); <---- THIS IS WHERE THE ERROR OCCURS
stack.Children.Clear();
ToggleLoading();
//remove old controls
Task.Delay(300).ContinueWith((t) =>
{
this.Dispatcher.Dispatch(async () =>
{
try
{
await FetchData();
}
catch
{ //try one more attempt from sql lite
await ReFetchData();
}
});
});
System.Runtime.InteropServices.COMException: 'No installed components were >detected
stackmain.Children.Insert(0, dlog); <---- THIS IS WHERE THE ERROR OCCURS
About this, I find an issue on MAUI GitHub: [Windows] Faced no installed components were detected exception #8997, you can try the solution mattleibow provided:
I think it may be because you are adding a child during a layout cycle? >Maybe you can avoid this by adding via a dispatch. This should cause the >child to be added after the layout is complete:
this.Owner.Dispatcher.Dispatch(() => this.Owner.Children.Add(myLabel));
Hope it can help you.