首页 > 其他分享 >WPFUI报错 - page does not have a parameterless constructor

WPFUI报错 - page does not have a parameterless constructor

时间:2024-08-06 22:16:36浏览次数:8  
标签:TargetPageType containerProvider parameterless Controls does Ui viewItem 报错 Wpf

WPFUI报错

page does not have a parameterless constructor. If you are using Wpf.Ui.IPageService do not navigate initially and don't use Cache or Precache

问题原因

WPFUI中的NavigationView只支持导航页面的无参构造函数或含一个dataContext的有参构造函数。因为在View的构造函数中注入了一些服务,导致View创建失败,WPFUI报错。

问题处理

查看异常堆栈,找报错位置:

在 Wpf.Ui.Controls.NavigationViewActivator.CreateInstance(Type pageType, Object dataContext) 在 Wpf.Ui.Controls\NavigationViewActivator.cs 中: 第 37 行
在 Wpf.Ui.Controls.NavigationView.GetPageInstanceFromCache(Type targetPageType) 在 Wpf.Ui.Controls\NavigationView.cs 中: 第 1206 行
在 Wpf.Ui.Controls.NavigationCache.Remember(Type entryType, NavigationCacheMode cacheMode, Func`1 generate) 在 Wpf.Ui.Controls\NavigationCache.cs 中: 第 25 行
在 Wpf.Ui.Controls.NavigationView.GetNavigationItemInstance(INavigationViewItem viewItem) 在 Wpf.Ui.Controls\NavigationView.cs 中: 第 1185 行
在 Wpf.Ui.Controls.NavigationView.NavigateInternal(INavigationViewItem viewItem, Object dataContext, Boolean addToNavigationStack, Boolean isBackwardsNavigated) 在 Wpf.Ui.Controls\NavigationView.cs 中: 第 1131 行
在 Wpf.Ui.Controls.NavigationViewItem.OnClick() 在 Wpf.Ui.Controls\NavigationViewItem.cs 中: 第 314 行
...

看源码,找解决方案:

private object GetNavigationItemInstance(INavigationViewItem viewItem)
{
    if (viewItem.TargetPageType is null)
    {
        throw new InvalidOperationException(
            $"The {nameof(viewItem)}.{nameof(viewItem.TargetPageType)} property cannot be null."
        );
    }

    if (_serviceProvider is not null)
    {
        return _serviceProvider.GetService(viewItem.TargetPageType)
            ?? throw new InvalidOperationException(
                $"{nameof(_serviceProvider)}.{nameof(_serviceProvider.GetService)} returned null for type {viewItem.TargetPageType}."
            );
    }

    if (_pageService is not null)
    {
        return _pageService.GetPage(viewItem.TargetPageType)
            ?? throw new InvalidOperationException(
                $"{nameof(_pageService)}.{nameof(_pageService.GetPage)} returned null for type {viewItem.TargetPageType}."
            );
    }

    return _cache.Remember(
            viewItem.TargetPageType,
            viewItem.NavigationCacheMode,
            ComputeCachedNavigationInstance
        )
        ?? throw new InvalidOperationException(
            $"Unable to get or create instance of {viewItem.TargetPageType} from cache."
        );

    object? ComputeCachedNavigationInstance() => GetPageInstanceFromCache(viewItem.TargetPageType);
}

可以看到,如果提供了serviceProvider或者pageService,就可以通过容器获取View实例,不需要通过NavigationViewActivator.CreateInstance创建实例了。

提供ServiceProvider,例如使用Prism:

public class PrismServiceProvider : IServiceProvider
{
    private readonly IContainerProvider _containerProvider;

    public PrismServiceProvider(IContainerProvider containerProvider)
    {
        _containerProvider = containerProvider;
    }

    public object GetService(Type serviceType)
    {
        return _containerProvider.Resolve(serviceType);
    }
}

WPFUI中未提供默认的IPageService实现,但demo.mvvm中提供了基于IServiceProvider的实现,可以参考。本文基于Prism实现:

public class PageService : IPageService
{
    private readonly IContainerProvider _containerProvider;

    public PageService(IContainerProvider containerProvider)
    {
        _containerProvider = containerProvider;
    }

    public T GetPage<T>() where T : class
    {
        if (!typeof(FrameworkElement).IsAssignableFrom(typeof(T)))
            throw new InvalidOperationException("The page should be a WPF control.");

        return (T)_containerProvider.Resolve(typeof(T));
    }

    public FrameworkElement GetPage(Type pageType)
    {
        if (!typeof(FrameworkElement).IsAssignableFrom(pageType))
            throw new InvalidOperationException("The page should be a WPF control.");

        return _containerProvider.Resolve(pageType) as FrameworkElement;
    }
}

最后一步,将PrismServiceProvider、PageService注入容器,并通过INavigationService为NavigationView设置IServiceProvider和IPageService:

// App.xaml.cs
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    var serviceProvider = new PrismServiceProvider(Container);
    containerRegistry.RegisterInstance<IServiceProvider>(serviceProvider);
    containerRegistry.RegisterSingleton<IPageService, PageService>();
    containerRegistry.RegisterSingleton<INavigationService, NavigationService>();
}

// MainWindow.xaml.cs
public MainWindow(INavigationService navigationService,
    IPageService pageService,
    ISnackbarService snackbarService)
{
    InitializeComponent();

    navigationService.SetPageService(pageService);
    navigationService.SetNavigationControl(NavigationView);
}

标签:TargetPageType,containerProvider,parameterless,Controls,does,Ui,viewItem,报错,Wpf
From: https://www.cnblogs.com/louzixl/p/18346088

相关文章

  • 【linux】关于qemu-img创建虚拟机前端磁盘报错
    问题描述:使用qemu-imgcreate-fqcow2-bcirros.qcow2vmhost.img20G创建虚拟机磁盘出现以下报错,报错内容:qemu-img:vmhost.img:BackingfilespecifiedwithoutbackingformatDetectedformatofqcow2.[root@ecsimages]#qemu-imgcreate-fqcow2-bcirros.qcow2vmho......
  • 【Pyautogui自动准备jupyter】附上报错合集,已解决
    刚认识了pyautogui,浅浅写一段自动准备jupyter的程序importpyautogui#importpyperclipimporttimedefopen_jupyter():print('Openingjupyter...')time.sleep(1)try:location=pyautogui.locateOnScreen(r"D:\STEFANOS\python\t......
  • 解决torchaudio.load报错 (Couldn't find appropriate backend to handle uri )
    解决torchaudio.load报错(Couldn'tfindappropriatebackendtohandleuri)问题描述(报错信息):问题:Traceback(mostrecentcalllast): File"resample.py",line43,in<module>  resample_use_cuda() File"resample.py",line24,inres......
  • ADFS配置“声明提供方信任”时,读取url报错
    声明提供方信任,通过Haproxy2.8.5提供https服务,metadata通过url可以正常打开页面ADFS在配置“声明提供方信任”时,通过URL访问声明提供方的联合元数据,提示“SSL连接通道已关闭”或“基础连接已关闭”,查看haproxy日志发现保存日志““SSLhandshakefailure(error:14209102:SSLro......
  • (已解决)QT4 自定义信号函数调用报错 error: C2248: “Boss::DeadSignal”: 无法访问 pr
     (解决方法见文章末尾)报错语句如下 DeadSignal是自定义槽函数,是放在public下的,不知道为什么报错说是protected,不知道是不是版本问题Boss类和DeadSignal定义如下 mboss是在自定义类Widget中调用的Boss对象 调用位置是Widget的自定义槽函数 解决方法在Boss中定......
  • 【YashanDB数据库】大事务回滚导致其他操作无法执行,报错YAS-02016 no free undo block
    问题现象客户将一个100G的表的数据插入到另一个表中,使用insertintoselect插入数据。从第一天下午2点开始执行,到第二天上午10点,一直未执行完毕。由于需要实施下一步操作,客户kill重启了数据库,之后数据库一直回滚中,导致后续执行其他操作都报错YAS-02016nofreeundoblocks问题......
  • .netCore System.Drawing.Common 发布,在CentOS 运行报错
    centos下要运行 System.Drawing.Common,需要先安装mono的  libgdiplus插件才可以。安装后,还报以下错误的,才是下文的内容。 报错:System.PlatformNotSupportedException:System.Drawing.Commonisnotsupportedonnon-Windowsplatforms.Seehttps://aka.ms/systemdra......
  • 解决Maven Deploy时提示module java.base does not "opens java.util" to unnamed mod
    使用Maven向中央仓库推送项目时,遇到Unabletomakefieldprivatefinaljava.util.Comparatorjava.util.TreeMap.comparatoraccessible:modulejava.basedoesnot"opensjava.util"tounnamedmodule的错误提示。网上搜了下,大概是因为自Java9起,引入了模块系统(ProjectJig......
  • 后端MyBatis连接Mysql数据库时常见报错
     目录报错情况报错情况一:​编辑报错情况二:解决步骤一、解决命名问题1.mapper层的id是否和Dao层的方法名字相同2.检查namespace与Dao层的文件地址相同二、解决注解问题1.检查Controller层的注解是否正确和完整2.Dao层或者Mapper层的注解3.pojo层:实体类层Data注解(用......
  • 【报错提示】java.lang.RuntimeException: Can't create handler inside thread
    ​报错提示遇到一个报错: java.lang.RuntimeException:Can'tcreatehandlerinsidethreadThread[OkHttphttps://a.fxltsbl.com/...]thathasnotcalledLooper.prepare() 分析 1.这个报错提示是在一个没有调用Looper.prepare()的线程中尝试创建一个Handler对象......