代码创建继承NavigationView的自定义控件加载时抛出异常
问题场景
通过代码动态创建继承自NavigationView的自定义控件SubControl,并将其设置为Window的Content时出现异常;但通过XAML声明该控件,或让控件继承Button、TextBox等其他控件时,均可正常运行。
相关代码
MainWindow.xaml
<!--MainWindow.xaml--> <Window x:Class="TestApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />
MainWindow.xaml.cs
// MainWindow.xaml.cs namespace TestApp { internal sealed partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } } }
App.xaml.cs
// App.xaml.cs namespace TestApp { public partial class App : Application { public App() { InitializeComponent(); } protected override void OnLaunched(LaunchActivatedEventArgs args) { var mainWindow = new MainWindow(); mainWindow.Content = new SubControl(); mainWindow.Activate(); } } }
SubControl.cs
// SubControl.cs namespace TestApp.Controls { internal class SubControl : NavigationView { } }
异常信息
- 断点调试时抛出COM异常:
e.Exception: {"未检测到已安装的组件。(0x800F1000)"}, System.Exception {System.Runtime.InteropServices.COMException}
- 核心错误提示:
e.Message: "无法将TargetType为'Microsoft.UI.Xaml.Controls.NavigationView'的样式应用于类型为'Microsoft.UI.Xaml.Controls.ContentControl'的对象。"
异常现象
- 在
mainWindow.Content = new SubControl();处设置断点时,会触发上述异常; - 不设置断点时无异常提示,但
SubControl无法正常显示; - 切换为XAML声明
SubControl,或让其继承Button等基础控件时,功能完全正常。
原因分析
NavigationView属于需要显式关联默认样式资源的复杂控件,当仅通过纯C#代码子类化该控件时,XAML框架无法正确识别控件类型,错误地将其当作ContentControl来匹配样式,最终导致类型不匹配的异常。
解决方法
为自定义控件添加对应的XAML文件,显式指定控件类型并绑定默认样式:
1. 添加SubControl.xaml文件
<!--SubControl.xaml--> <NavigationView x:Class="TestApp.Controls.SubControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Style="{StaticResource NavigationViewStyle}"> </NavigationView>
2. 修改SubControl.cs代码
将控件改为partial类,并添加构造函数初始化XAML组件:
// SubControl.cs namespace TestApp.Controls { internal sealed partial class SubControl : NavigationView { public SubControl() { InitializeComponent(); } } }
3. 确认项目配置
检查项目文件中SubControl.xaml的生成操作是否设置为Page,确保编译时能正确关联代码与XAML资源。
完成以上修改后,动态创建SubControl并设置为Window.Content时,框架会正确识别控件类型并应用对应的NavigationView样式,异常和控件不显示的问题即可解决。
内容的提问来源于stack exchange,提问作者appletree5641

