从资源加载任务栏图标并使用 Prism 注入视图模型

Posted

技术标签:

【中文标题】从资源加载任务栏图标并使用 Prism 注入视图模型【英文标题】:Loading a Taskbar Icon from resources and using Prism to inject view model 【发布时间】:2021-07-09 16:23:42 【问题描述】:

背景

我正在尝试编写一个主要位于系统托盘上的应用程序,它将来会有一个窗口,所以右键单击它打开窗口的图标。

代码

我目前没有在 Prism 启动时定义 shell,即:

protected override Window CreateShell()

    return null;

通知图标(使用 Hardcodet.NotifyIcon 是否有任何区别?)在资源字典中定义,因为我没有启动 View xaml 来将图标添加到:

<!-- the application's NotifyIcon - started from App.xaml.cs. Declares its own view model. -->
    <tb:TaskbarIcon x:Key="NotifyIcon"
                    IconSource="Binding UserStatus, Converter=StaticResource UserStatusToImageSourceConverter"
                    ToolTipText="Double-click for window, right-click for menu"
                    DoubleClickCommand="Binding ShowWindowCommand"
                    ContextMenu="StaticResource SysTrayMenu">

         <!--self-assign a data context (could also be done programmatically)--> 
        <tb:TaskbarIcon.DataContext>
            <viewModels:NotifyIconViewModel />
        </tb:TaskbarIcon.DataContext>
    </tb:TaskbarIcon>

视图模型,正如您在 sn-p 的后面部分看到的那样,采用 NotifyIconViewModel,它有一个构造函数参数,因此我可以使用 IEventAggregator 在视图的不同部分之间进行通信(例如右键单击托盘图标时显示的上下文菜单中的视图)。

视图模型的签名如下所示:

public NotifyIconViewModel(IEventAggregator eventAggregator)

    _eventAggregator = eventAggregator;
    ...

服务已注册:

protected override void RegisterTypes(IContainerRegistry containerRegistry)

    ...
    containerRegistry.Register<NotifyIconViewModel>();

并且通知图标本身是在OnInitialized方法中实例化的:

protected override void OnInitialized()

    base.OnInitialized();
    notifyIcon = (TaskbarIcon)FindResource("NotifyIcon");

问题

但是,启动时抛出的异常是找不到视图模型的默认构造函数(正确,没有)。但我的解读是,prism 架构应该能够在需要时注入视图模型(及其 deps)?

我只能假设我错误地初始化了通知图标并且 FindResource 不会导致触发 prism 库构造函数注入/DI 部分,但是执行此行为的正确方法是什么?

【问题讨论】:

&lt;viewModels:NotifyIconViewModel /&gt; 是你的构造函数调用...我这里没有看到任何参数 好的,有趣且有效的观点,那么如何正确/正确地做到这一点,因为我这里没有 IEventAggregator 的参数?我应该如何将视图模型绑定到视图组件/图标以启用此自动注入? 【参考方案1】:

如果您使用容器来构造(也称为解析)对象,则会注入依赖项。

当一个普通的 Prism 应用程序解析 shell 时会发生这种情况,它(通过使用 ViewModelLocator)解析 shell 的视图模型,它解析了 shell 视图模型的所有依赖关系以及这些依赖关系的依赖关系等等。

如果您使用容器(即直接在 xaml 中构造对象),它不会为您解决任何依赖关系。

您可以创建图标并使用容器来解析NotifyIconViewModel并将其设置为DataContext

protected override void OnInitialized()

    base.OnInitialized();
    notifyIcon = (TaskbarIcon)FindResource("NotifyIcon");
    notifyIcon.DataContext = Container.Resolve<NotifyIconViewModel>();

【讨论】:

好热的小伙子!那行得通!当您在上面的 cmets 中指出该调用没有 args 时,解决方法非常好,并且完全有意义!现在去体验地区的乐趣..

以上是关于从资源加载任务栏图标并使用 Prism 注入视图模型的主要内容,如果未能解决你的问题,请参考以下文章

Prism:如何在区域中注入视图模型实例?

WPF 应用程序的 Windows 任务栏中显示的大小错误的图标

一招彻底解决win10开机桌面及任务栏卡死问题

最小化后不在任务栏显示图标怎么办

Xamarin Master Detail prism 导航栏后退按钮

在 Prism 导航页面的工具栏中添加搜索栏