从资源加载任务栏图标并使用 Prism 注入视图模型
Loading a Taskbar Icon from resources and using Prism to inject view model
背景
我正在尝试编写一个主要位于系统托盘上的应用程序,它将来会有一个 window 所以右键单击该图标会打开 window.
代码
我目前没有在 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>
视图模型,正如您在该片段的后面部分看到的,采用 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");
}
问题
但是,启动时抛出的异常是没有为视图模型找到默认构造函数(正确,没有)。但我的解读是棱镜架构应该能够在需要时注入视图模型(及其依赖)?
我只能假设我错误地初始化了通知图标并且 FindResource 不会导致触发棱镜库构造函数 injection/DI 部分,但是执行此行为的正确方法是什么?
如果您使用容器构造(又名解析)对象,则会注入依赖项。
当普通的 Prism 应用程序解析 shell 时会发生这种情况,它(通过使用 ViewModelLocator
)解析 shell 的视图模型,后者解析 shell 的所有依赖项=24=]的view model以及那些依赖的依赖等等。
如果您不使用容器(即直接在xaml中构造对象),它不会为您解决任何依赖关系。
您可以创建图标并使用容器来解析 NotifyIconViewModel
并将其设置为 DataContext
:
protected override void OnInitialized()
{
base.OnInitialized();
notifyIcon = (TaskbarIcon)FindResource("NotifyIcon");
notifyIcon.DataContext = Container.Resolve<NotifyIconViewModel>();
}
背景
我正在尝试编写一个主要位于系统托盘上的应用程序,它将来会有一个 window 所以右键单击该图标会打开 window.
代码
我目前没有在 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>
视图模型,正如您在该片段的后面部分看到的,采用 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");
}
问题
但是,启动时抛出的异常是没有为视图模型找到默认构造函数(正确,没有)。但我的解读是棱镜架构应该能够在需要时注入视图模型(及其依赖)?
我只能假设我错误地初始化了通知图标并且 FindResource 不会导致触发棱镜库构造函数 injection/DI 部分,但是执行此行为的正确方法是什么?
如果您使用容器构造(又名解析)对象,则会注入依赖项。
当普通的 Prism 应用程序解析 shell 时会发生这种情况,它(通过使用 ViewModelLocator
)解析 shell 的视图模型,后者解析 shell 的所有依赖项=24=]的view model以及那些依赖的依赖等等。
如果您不使用容器(即直接在xaml中构造对象),它不会为您解决任何依赖关系。
您可以创建图标并使用容器来解析 NotifyIconViewModel
并将其设置为 DataContext
:
protected override void OnInitialized()
{
base.OnInitialized();
notifyIcon = (TaskbarIcon)FindResource("NotifyIcon");
notifyIcon.DataContext = Container.Resolve<NotifyIconViewModel>();
}