我使用棱镜6.1。我在ConfigureContainer
类的Bootstrapper
方法中设置了Unity配置。但是,当Prism框架尝试调用View模型时,它无法创建它,并抛出异常'没有为此对象定义的无参数构造函数。'。
Bootstrapper.cs
public class Bootstrapper: UnityBootstrapper
{
...
protected override void ConfigureContainer()
{
base.ConfigureContainer();
this.Container.RegisterType<IMyService, MyService>(new ContainerControlledLifetimeManager());
this.Container.RegisterType<MyFormViewModel>(new ContainerControlledLifetimeManager());
}
...
}
MyFormModule.cs
public class MyFormModule : IModule
{
private readonly IRegionViewRegistry regionViewRegistry;
public SkypeActionModule(IRegionViewRegistry registry)
{
this.regionViewRegistry = registry;
}
public void Initialize()
{
regionViewRegistry.RegisterViewWithRegion("MainRegion", typeof(Views.MyFormView));
}
}
MyFormViewModel.cs
public class MyFormViewModel : BindableBase
{
private readonly IMyService myService;
public SkypeActionViewModel(IMyService myService)
{
this.myService = myService;
}
...
}
在此行中抛出异常:
regionViewRegistry.RegisterViewWithRegion("MainRegion", typeof(Views.MyFormView));
在prism documentation中解释了如何配置统一,但这是在Module类中(在我的例子中是MyFormModule
)。我不明白,因为通过这种方式,我需要在每个模块中配置它,并且我的模块类中没有对象this.container.RegisterType
。
在其他链接中,我发现了一些类似于“MEF”配置的配置,其中“DI”配置在ConfigureContainer
方法中。但它对我的配置不起作用,或者我的配置中缺少的东西。
修改
我在我的模块类中包含了容器。但我有同样的问题。我认为这是正常的,因为问题在于Prism创建视图模型类MyFormViewModel
。
public class MyFormModule : IModule
{
private readonly IRegionViewRegistry regionViewRegistry;
private readonly IUnityContainer container;
public MyFormModule(IRegionViewRegistry registry, IUnityContainer container)
{
this.regionViewRegistry = registry;
this.container = container;
}
public void Initialize()
{
this.container.RegisterType<IMyService, MyService>(new ContainerControlledLifetimeManager());
this.container.RegisterType<MyFormViewModel>();
this.container.RegisterType<MyFormView>();
regionViewRegistry.RegisterViewWithRegion("MainRegion", typeof(MyFormView));
}
}
修改
解决方案:我在this question on stackoverflow
中找到了解决方案在BindViewModelToView
类:
Bootstrap
public void BindViewModelToView<TViewModel, TView>()
{
ViewModelLocationProvider.Register(typeof(TView).ToString(), () => Container.Resolve<TViewModel>());
}
然后,在ConfigureViewModelLocator
类的方法Bootstrap
中调用所有视图模型将其与视图绑定:
protected override void ConfigureViewModelLocator()
{
BindViewModelToView<ViewAVM, ViewA>();
BindViewModelToView<ViewAVM, ViewB>();
}
答案 0 :(得分:0)
你如何告诉棱镜创建视图模型?您使用的是from tkinter import *
import tkinter.font
import RPi.GPIO as GPIO
import time
GPIO Setup
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(16, GPIO.OUT) # Water Pump
GPIO.setup(18, GPIO.IN) # Tank Float Switch
GPIO.output(16, GPIO.LOW)
time_to_run = 60 # time to run the pump in seconds
time_running = time.time() - 1
#Window Setup
win = Tk()
win.title("Pump Test")
win.geometry("150x150+0+0")
#Label Setup
Label (win, text="Water System", fg="red", bg="black", font="24").grid(row=0, column=0)
#Functions
def off():
WTR.config(text="LOW WATER", bg="red")
GPIO.output(16, GPIO.LOW)
def wtr():
global time_running
time_running = time.time() + time_to_run
if GPIO.input(18) and not GPIO.input(16):
pump_on()
elif GPIO.input(16):
pump_off()
def pump_on():
WTR.config(text="Water", bg="green")
GPIO.output(16, GPIO.HIGH)
# added to turn the pump off manualy
def pump_off():
WTR.config(text="Water", bg="grey")
GPIO.output(16, GPIO.LOW)
def check_pump():
# if the water level goes low turn the pump off
# and show low water level
if not GPIO.input(18):
off()
# if a set time has passed then shut the pump off it it is running
if time_running <= time.time() and GPIO.input(16):
pump_off()
win.after(100, check_pump) # call this function every 100 miliseconds
#Buttons
WTR = Button(win, text="Water", bg="grey", command = wtr, height = 2, width = 8)
WTR.grid(row=1, column=0) #Water Pump Control
check_pump() # must be called once to start the after function
mainloop()
吗?
如果是这样,你想做类似
的事情ViewModelLocator.AutoWireViewModel="True"
在引导程序中,以确保您的容器用于解析视图模型...