처음으로 Caliburn을 사용하여이 프로젝트를 작성하려고합니다. 완전히 이해하지 못했던 MEF 구조도 작성했습니다.여러보기가있는 Caliburn 이벤트 집계 도구
지휘자와 EventAggregator를 모두 사용해야합니다. 나는 3 개의 다른보기 (AppView 내부의 UserControls)로 사용자를 이동시키는 3 개의 버튼을 "표시"하는 AppViewModel을 가지고 있기 때문에 도체가 있습니다.
그리고 이러한 3 개의보기 중 하나에 4 번째보기를로드해야하는 단추가 있기 때문에 EventAggregator가 필요합니다. 전체 화면이어야하기 때문에 UserControl이 아닌 생각하는 창이어야합니다. 그래서 나는 사용자가 3 개의 뷰 (AppView 내부의 UserControl)에서이 버튼을 클릭하면 메시지가 Listener (즉, AppViewModel이어야 함) 위로 전송 될 수 있다고 생각했습니다.이 메시지는 ActivateItem (4 번째 VM)이어야합니다.
왜 Caliburn 프로젝트의 예를 따르더라도 내 메시지가 AppViewModel에 도달하지 않습니다.
public class AppBootstrapper : Bootstrapper<AppViewModel>
{
private CompositionContainer container;
protected override void Configure()
{
container = new CompositionContainer(new AggregateCatalog(AssemblySource.Instance.Select(x =>
new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()));
CompositionBatch batch = new CompositionBatch();
batch.AddExportedValue<IWindowManager>(new WindowManager());
batch.AddExportedValue<IEventAggregator>(new EventAggregator());
batch.AddExportedValue(container);
container.Compose(batch);
}
protected override object GetInstance(Type serviceType, string key)
{
string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key;
var exports = container.GetExportedValues<object>(contract);
if (exports.Any())
return exports.First();
throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
}
protected override IEnumerable<object> GetAllInstances(Type serviceType)
{
return container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType));
}
protected override void BuildUp(object instance)
{
container.SatisfyImportsOnce(instance);
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<AppViewModel>();
}
}
이
는 AppViewModel입니다 :이
내 부트 스트 래퍼입니다[Export (typeof(AppViewModel))]
public class AppViewModel : Conductor<object>, IHandle<ChangeViewEvent>
{
[ImportingConstructor]
public AppViewModel(IEventAggregator events)
{
events.Subscribe(this);
ActivateItem(new MainViewModel());
}
public void GoToPatientsManager()
{
ActivateItem(new PatientsManagerViewModel(new WindowManager(), new EventAggregator()));
}
public void GoToTestManager()
{
ActivateItem(new TestManagerViewModel(new WindowManager()));
}
public void GoToResultsManager()
{
ActivateItem(new MainViewModel());
}
public void Handle(ChangeViewEvent message)
{
switch (message.ViewName)
{
case "TestManager" :
GoToTestManager();
break;
}
}
}
그리고 이것은 4 VM
[Export(typeof(PatientsManagerViewModel))]
public class PatientsManagerViewModel : Screen
{
private readonly IWindowManager _windowManager;
private readonly IEventAggregator eventAggregator;
[ImportingConstructor]
public PatientsManagerViewModel(IWindowManager windowManager, IEventAggregator eventAggregator)
{
_windowManager = windowManager;
this.eventAggregator = eventAggregator;
}
#region Methods
public void ShowFakeMessage()
{
dynamic settings = new ExpandoObject();
settings.Placement = PlacementMode.Center;
settings.PlacementTarget = GetView(null);
var res = _windowManager.ShowDialog(new DeletePersonViewModel(), null, settings);
if (res)
{
// The result of the dialog men. In this true case we'll use Linq to delete the entry from the database
// using the dbContext
}
}
public void GoToTestManager()
{
eventAggregator.Publish(new ChangeViewEvent("TestManager"));
}
#endregion
}
를로드하는 요청을 시작해야 뷰 모델
AppViewModel의 Handle 메서드에 도달하지 않습니다.
보기 모델의 인스턴스에 이러한 문제가 있습니까? 나는
편집
은 문제가 나는 새로운 EventAggregator 오브젝트 나는 새로운 PatientsManagerViewModel을 활성화 할 때마다 통과한다는 것을 수 있습니다 ... 여기에서 앞으로 이동할 수 없습니다? 어떤 팁?