我有一个正在运行的 Prism WPF 应用程序,其主要目标是工厂操作员的 UI 以及与工厂机器的通信。
主 UI 视图 (
MachineDashboard
) 绑定到其视图模型 (MachineDashboardViewModel
),其中基于属性 MachineId
完成与机器和 BL 的所有通信。
此属性现在从应用程序设置中初始化。
现在我需要升级应用程序,因此它将显示不同机器(最多 4 台)的 UI。 基本上,我需要显示最多 4 个不同的视图(MachineDashboards)。
我向 UserControl 添加了依赖属性
MachineDashboard
MachineId_DP
,通过它我可以在 ViewModel 中设置属性 MachineId
MachineDashboardViewModel
<UserControl.Resources>
<ResourceDictionary>
<Style TargetType="local:MachineDashboard">
<Setter Property="MachineId_DP" Value="{Binding MachineId, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
</Style>
</ResourceDictionary>
</UserControl.Resources>
如果我想在 HomeView 中显示不同机器的 UserCotrols,我现在可以添加用户控件并定义机器的 Id
<WrapPanel Grid.Row="0">
<local:MachineDashboard MachineId_DP="1" Margin="10"/>
<local:MachineDashboard MachineId_DP="2" Margin="10"/>
<local:MachineDashboard MachineId_DP="3" Margin="10"/>
<local:MachineDashboard MachineId_DP="4" Margin="10"/>
</WrapPanel>
这完全按照我想要的方式工作。
但是,如果我尝试通过 ItemsControl 执行相同的操作(因为确切的计算机列表是从数据库加载的),则
MachineId
的绑定不起作用。加载了正确数量的用户控件,但 MachineIds
未传递到 MachineDashboardViewModel
<ItemsControl Grid.Row="1" ItemsSource="{Binding Machines}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate >
<local:MachineDashboard MachineId_DP="{Binding MachineId}" Margin="10"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
事实上,即使我尝试添加固定MachineId_DP参数的datatemplate,结果也是一样的。
<DataTemplate >
<local:MachineDashboard MachineId_DP="3" Margin="10"/>
</DataTemplate>
我检查了每个 stackoverflow 的条目,都有类似的问题,但没有适当的答案,通常争论是围绕着为什么要为用户控件使用视图模型这一事实。 该用户控件 (MachineDashoard) 实际上由大约 50 个控件组成,例如标签、数据网格、按钮等,并带有指向其他输入对话框的链接。因此,这里必须为每台机器提供单独的视图模型实例。
此外,依赖注入是在 MachineDashboardViewModel 中实现的
public MachineDashboardViewModel(IDialogService dialogservice, ILogger logger)
所以我要问的主要问题是如何动态加载用户控件
MachineDashboard
并在其视图模型中设置适当的MachineId
属性?
我创建了非常简化的示例应用程序 这里
最直接的选项是在创建
MachineId
时设置 MachineDashboardViewModel
并将它们放入 Machines
属性中。
当子视图模型从一开始就位于父视图模型的属性中时,从父视图模型绕道到数据模板,再到用户控件,再到子视图模型是绝对没有意义的。