很长的道歉,因为试图获取尽可能多的信息。我正在使用WPF(.NET Framework 4.8),Prism 7,Prism.Unity和MahApps。我几乎所有的视图模型都需要参数化的构造函数(注入依赖项)。我正在使用内置的Prism ViewModelLocator.AutoWireViewModel来连接视图模型(即,棱镜:ViewModelLocator.AutoWireViewModel =“ True”)。一切工作正常,但这意味着创建了两个视图模型实例,一次是使用AutoWireViewModel,另一次是在后台调用参数化构造函数(请参见Brian Lagunas的评论Avoid Prism AutoWireViewModel Creating the ViewModel Twice)。因此,我将AutoWireViewModel的值设置为False,现在在每个视图后面的代码中创建视图模型。我能够将创建视图模型时所需的依赖项注入到视图构造函数中-这也可以正常工作。我遇到的问题是当我尝试使用Mahapps HamburgerMenu控件时。它包含每个子视图的菜单项。根据我的判断,每个子视图都需要一个无参数的构造函数,但是我需要一个参数化的视图构造函数(注入了创建/调用viewmodel构造函数所需的依赖项)。我收到的异常/内部异常是:
“在类型'MyCompany.Wpf.Modules.Admin.Views.AdminDataGrid'上找不到匹配的构造函数。可以使用Arguments或FactoryMethod指令构造此类型。”行号“ 236”和行位置“ 34”。”“找不到类型'MyCompany.Wpf.Modules.Admin.Views.AdminDataGrid'的默认构造函数。您可以使用Arguments或FactoryMethod指令构造此类型。”
如果我在AdminDataGrid视图中添加一个无参数的构造函数,那么我不会收到任何错误,但无法创建视图模型并传递依赖项。
我的代码如下:
包含HamburgerMenu的AdminMainView代码(问题子视图名为AdminDataGrid):
<Controls:HamburgerMenu x:Name="HamburgerMenuControl"
HamburgerWidth="48"
IsPaneOpen="True"
CanResizeOpenPane="True"
ItemInvoked="HamburgerMenuControl_OnItemInvoked"
ItemTemplate="{StaticResource MenuItemTemplate}"
OptionsItemTemplate="{StaticResource MenuItemTemplate}"
SelectedIndex="0"
Style="{StaticResource MahApps.Styles.HamburgerMenu.Ripple}"
VerticalScrollBarOnLeftSide="False">
<!-- Items -->
<Controls:HamburgerMenu.ItemsSource>
<Controls:HamburgerMenuItemCollection>
<Controls:HamburgerMenuIconItem Icon="{iconPacks:FontAwesome Kind=TableSolid}" Label="Data Grid">
<Controls:HamburgerMenuIconItem.Tag>
<views:AdminDataGrid />
</Controls:HamburgerMenuIconItem.Tag>
</Controls:HamburgerMenuIconItem>
</Controls:HamburgerMenuItemCollection>
</Controls:HamburgerMenu.ItemsSource>
后面的AdminDataGrid视图的代码。第二个构造函数是我想调用的: 公共局部类AdminDataGrid:UserControl,IAdminDataGrid { //我必须添加此代码才能构建/运行代码。 公共AdminDataGrid() { InitializeComponent(); }
// This is the constructor I would like to call
public AdminDataGrid(ICustomerService service)
{
InitializeComponent();
this.DataContext = new AdminDataGridViewModel(service);
}
}
AdminDataGridViewModel:
public class AdminDataGridViewModel : BindableBase, IAdminDataGridViewModel
{
private ObservableCollection<Customer> _customers;
public ObservableCollection<Customer> Customers
{
get => this._customers;
set => SetProperty(ref _customers, value);
}
public AdminDataGridViewModel(ICustomerService service)
{
Customers = new ObservableCollection<Customer>();
Customers.AddRange(service.GetAllCustomers().OrderBy(c => c.LastName));
}
}
我已经尝试为AdminDataGrid / AdminDataGridViewModel创建接口,并且类从它们继承,模块管理器代码为:
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<IAdminDataGrid, AdminDataGrid>();
containerRegistry.Register<IAdminDataGridViewModel, AdminDataGridViewModel>();
}
后面的AdminMainView代码。注意:我注入了IAdminDataGridViewModel对象,并将其作为AdminMainViewModel上的一个属性公开(想法是将View的DataContext设置为该属性:AdminDataGrid菜单项-但不确定如何操作或是否可行)。
public AdminMainView(IAdminDataGridViewModel adminDataGridViewModel)
{
this.InitializeComponent();
this.DataContext = new AdminMainViewModel(adminDataGridViewModel);
}
AdminMainViewModel构造函数:
public AdminMainViewModel(IAdminDataGridViewModel adminDataGridViewModel)
{
this.AdminDataGridViewModel = adminDataGridViewModel;
}
当呈现views:AdminDataGrid项时,如何获取HamburgerMenu控件以使用参数化构造函数?谢谢。
当渲染视图时,如何获取HamburgerMenu控件以使用参数化的构造方法:AdminDataGrid项目?
您不会。控件应该具有无参数的构造函数,这就是ViewModelLocator
发明的目的。
我只是用它来创建视图模型(with所有必需的依赖项作为构造函数参数,而不是手动创建和分配数据上下文。