动态加载用户控件并在其视图模型中设置属性(Prism WPF)

问题描述 投票:0回答:1

我有一个正在运行的 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
属性?

我创建了非常简化的示例应用程序 这里

c# mvvm prism
1个回答
1
投票

最直接的选项是在创建

MachineId
时设置
MachineDashboardViewModel
并将它们放入
Machines
属性中。

当子视图模型从一开始就位于父视图模型的属性中时,从父视图模型绕道到数据模板,再到用户控件,再到子视图模型是绝对没有意义的。

© www.soinside.com 2019 - 2024. All rights reserved.