You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI中ControlTemplate含CollectionView+ContentPresenter引发异常

问题:使用ControlTemplate实现列表视图时,导航返回抛出"No installed components were detected"异常

我们有多个展示Model列表的View,点击列表项会显示操作菜单,原本功能正常。为保证视图一致性,尝试用ControlTemplate重构。首次测试时ItemsSource仅含单个项,功能看似正常;但当ItemsSource包含多个项时,导航离开再返回视图会抛出No installed components were detected异常,不过首个项仍能正常渲染和响应点击。


涉及代码文件

ListViewsTemplate.xaml(控件模板)

<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="MauiIssues.Controls.ListViewsTemplate"
         ControlTemplate="{DynamicResource ContainerTemplate}"
         x:Name="this">
<ContentView.Resources>
    <ResourceDictionary>
        <ControlTemplate x:Key="ContainerTemplate">
            <Frame BindingContext="{x:Reference this}" Padding="10, 0, 10, 0">
                <CollectionView ItemsSource="{TemplateBinding ItemsSource}">
                    <CollectionView.ItemsLayout><LinearItemsLayout Orientation="Vertical" /></CollectionView.ItemsLayout>
                    <CollectionView.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Frame>
                                    <Frame.GestureRecognizers>
                                        <TapGestureRecognizer 
                                            Command="{TemplateBinding ItemTapped}"
                                            CommandParameter="{Binding .}" />
                                    </Frame.GestureRecognizers>
                                    <ContentPresenter />
                                </Frame>
                                <Rectangle IsVisible="{OnPlatform false, Android=True}" HeightRequest="2" Fill="Black"/>
                            </Grid>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>
            </Frame>
        </ControlTemplate>
    </ResourceDictionary>
</ContentView.Resources>
</ContentView>

ListViewsTemplate.xaml.cs(控件模板代码后置)

using System.Collections;
using System.Windows.Command;

namespace MauiIssues.Controls
{
    public partial class ListViewsTemplate : ContentView
    {
        public IEnumerable ItemsSource
        {
            get => (IEnumerable)GetValue(ItemsSourceProperty);
            set => SetValue(ItemsSourceProperty, value);
        }
        public static readonly BindableProperty ItemsSourceProperty =
            BindableProperty.Create(nameof(ItemsSource), typeof(IEnumerable), typeof(ListViewsTemplate), defaultBindingMode: BindingMode.TwoWay);
        
        public ICommand ItemTapped
        {
            get => (ICommand)GetValue(ItemTappedProperty);
            set => SetValue(ItemTappedProperty, value);
        }
        public static readonly BindableProperty ItemTappedProperty =
            BindableProperty.Create(nameof(ItemTapped), typeof(ICommand), typeof(ListViewsTemplate), defaultBindingMode: BindingMode.TwoWay);

        public ListViewsTemplate() { InitializeComponent(); }

    }
}

ListViewsTemplate.xaml(内容页)

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:model="clr-namespace:MauiIssues.Models"
             xmlns:uc="clr-namespace:MauiIssues.Controls"
             xmlns:viewmodel="clr-namespace:MauiIssues.ViewModels"
             x:Class="MauiIssues.Views.ListViewsTemplate"
             x:DataType="viewmodel:ListViewsTemplateViewModel">
    <uc:ListViewsTemplate ItemsSource="{Binding Items}" ItemTapped="{Binding ItemTappedCommand}" VerticalOptions="StartAndExpand" >
        <Label BindingContext="{Binding Source={RelativeSource AncestorType={x:Type model:ListViewsTemplateModel}}}" 
               x:DataType="{x:Type model:ListViewsTemplateModel}" 
               Text="{Binding Name}" />
    </uc:ListViewsTemplate>
</ContentPage>

ListViewsTemplate.xaml.cs(内容页代码后置)

using MauiIssues.ViewModels;

namespace MauiIssues.Views
{
    public partial class ListViewsTemplate : ContentPage
    {
        public ListViewsTemplateViewModel ViewModel { get; }

        public ListViewsTemplate()
        {
            base.BindingContext = this.ViewModel = new ListViewsTemplateViewModel();
            InitializeComponent();
        }

        protected override async void OnAppearing()
        {
            await this.ViewModel.OnAppearing();
            base.OnAppearing();
        }
    }
}

ListViewsTemplateViewModel.cs(视图模型)

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MauiIssues.Models;
using System.Collections.ObjectModel;

namespace MauiIssues.ViewModels
{
    public partial class ListViewsTemplateViewModel : ObservableObject
    {
        public ObservableCollection<ListViewsTemplateModel> Items { get; } = new ();

        [RelayCommand]
        async Task ItemTapped(ListViewsTemplateModel item)
        {
            await App.Current.MainPage.DisplayAlert("tapped item", item.Name, "OK");
        }

        public async Task OnAppearing() 
        {
            this.Items.Add(new ListViewsTemplateModel() { Name = $"Item {this.Items.Count + 1}" });
            await Task.CompletedTask;
        }
    }
}

异常堆栈信息

首次导航到视图时一切正常,但导航离开并返回时抛出以下异常:

No installed components were detected.

at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode)
at WinRT.DelegateExtensions.DynamicInvokeAbi(Delegate del, Object[] invoke_params)
at ABI.System.Collections.Generic.IVectorMethods`1.Append(IObjectReference obj, T value) at ABI.System.Collections.Generic.IListMethods`1.Add(IObjectReference obj, T item)
at Microsoft.UI.Xaml.Controls.UIElementCollection.Add(UIElement item)
at Microsoft.Maui.Handlers.ContentViewHandler.UpdateContent(IContentViewHandler handler)
at Microsoft.Maui.Handlers.ContentViewHandler.MapContent(IContentViewHandler handler, IContentView page)
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.BindingExpression.ApplyCore(Object sourceObject, BindableObject target, BindableProperty property, Boolean fromTarget)
at Microsoft.Maui.Controls.BindingExpression.Apply(Object sourceObject, BindableObject target, BindableProperty property)
at Microsoft.Maui.Controls.Binding.d__27.MoveNext()
at System.Threading.Tasks.Task.<>c.b__128_0(Object state)
at Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.<>c__DisplayClass2_0.b__0()
--- End of stack trace from previous location ---
at WinRT.ExceptionHelpers.g__Throw|20_0(Int32 hr)
at ABI.Windows.ApplicationModel.Core.IUnhandledErrorMethods.Propagate(IObjectReference _obj)
at Windows.ApplicationModel.Core.UnhandledError.Propagate()
at Microsoft.AppCenter.Utils.ApplicationLifecycleHelperWinUI.<.ctor>b__0_3(Object sender, UnhandledErrorDetectedEventArgs eventArgs)
--- End of stack trace from previous location ---
at Microsoft.AppCenter.Utils.ApplicationLifecycleHelperWinUI.<.ctor>b__0_3(Object sender, UnhandledErrorDetectedEventArgs eventArgs)
at WinRT.EventSource__EventHandler`1.EventState.<GetEventInvoke>b__1_0(Object obj, T e) at ABI.System.EventHandler`1.Do_Abi_Invoke[TAbi](Void* thisPtr, IntPtr sender, TAbi args)

更新说明

为更清晰说明需求,我们想要实现类似ASP.NET母版页的功能:每个Web页面使用母版页,并在ContentPlaceHolder中放置自定义控件,我们理解这正是ContentPresenter的用途。

ASP.NET母版页示例(Page.Master)

<body>
   <div class="main">
       <asp:ContentPlaceHolder ID="FilterContent" runat="server" />
       <asp:Button ID="btnSearch" runat="server" Text="Search" />
       <div class="filterseparator" />
       <asp:ContentPlaceHolder ID="GridContent" runat="server" />
       <div class="gridseparator" />
       <asp:ContentPlaceHolder ID="MainContent" runat="server" />
   </div>
</body>

内容的提问来源于stack exchange,提问作者dpTech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 21:45:55