Ich frage das hier, weil ich ratlos bin, weil ich versucht habe, das herauszufinden. Ich habe gesucht und alles, was auftaucht, sind Dinge, die Sinn machen, aber auch nicht auf meine Situation zutreffen.Warum wird OnActivate nicht aufgerufen?
Ich verwende WPF
mit MVVM
und Caliburn.Micro
. Ich habe ein Shell-Fenster mit einem entsprechenden View-Modell, das ist ein Conductor<Screen>.Collection.OnceActive
und ein Bildschirm, der von Screen
erbt. Ich rufe ActivateItem
innerhalb des Konstruktors des Dirigenten an, um den folgenden Bildschirm anzuzeigen, es zeigt den Bildschirm korrekt aber ruft die Bildschirmüberschreibung für OnActivate
nie auf und die IsActive
Eigenschaft des Bildschirms wird auf False
festgelegt.
Dies geschieht nur das erste Mal, dass ich ActivateItem
vom Conductor nennen, alle weiteren Anrufe rufen richtig OnActivate
und OnDeactivate
.
Das macht keinen Sinn für mich und ich habe keine Ahnung, was vor sich geht. Ich habe die Lösung gereinigt, neu aufgebaut und sogar neu gestartet, aber es funktioniert immer noch nicht richtig. Unten ist der Code:
Eltern Conductor
[Export]
public sealed class ShellViewModel : Conductor<Screen>.Collection.OneActive, IHandle<SimpleMessage>
{
private readonly DashboardViewModel m_Dash;
private readonly LoginViewModel m_Login;
private readonly IEventAggregator m_MsgBus;
[ImportingConstructor]
public ShellViewModel(DashboardViewModel dash, LoginViewModel login, IEventAggregator msgBus)
{
this.m_MsgBus = msgBus;
this.m_Dash = dash;
this.m_Login = login;
this.ActivateItem(this.m_Login);
}
protected override void OnActivate()
{
this.m_MsgBus.Subscribe(this); //called correctly
}
protected override void OnDeactivate(bool close)
{
this.m_MsgBus.Unsubscribe(this); //called correctly
}
public void Handle(SimpleMessage message)
{
switch (message)
{
case SimpleMessage.LoginSuccess:
this.ActivateItem(this.m_Dash);
break;
case SimpleMessage.Logout:
this.ActivateItem(this.m_Login);
break;
}
}
}
Kinder Bildschirm
[Export]
public sealed class LoginViewModel : Screen
{
private readonly IEventAggregator m_MsgBus;
[ImportingConstructor]
public LoginViewModel(IEventAggregator msgBus)
{
this.m_MsgBus = msgBus;
}
protected override void OnActivate()
{
//NOT called the first time, but is called every other time
MessageBox.Show("ACTIVATE TEST");
}
protected override void OnDeactivate(bool close)
{
//NOT called the first time, but is called every other time
MessageBox.Show("DEACTIVATE TEST");
}
public void CmdLogin(string password)
{
this.m_MsgBus.PublishOnUIThread(SimpleMessage.LoginSuccess);
}
public string Username { get; set; }
public string Password { get; set; }
}
UPDATE
ich die Caliburn Micro Quelle heruntergeladen, so konnte ich in den Schritt ActivateItem
Funktion und sehen, was vor sich geht. Aus irgendeinem Grund, wenn ich zum ersten Mal ActivateItem
vom Dirigenten anrufen, wird die IsActive
Eigenschaft des Dirigenten auf false gesetzt, was bewirkt, dass Caliburn den Aufruf der OnActivate
Überschreibung überspringt. Ich habe keine Ahnung, warum die Immobilie falsch wäre.
ConductorBaseWithActiveItem.cs
protected virtual void ChangeActiveItem(T newItem, bool closePrevious) {
ScreenExtensions.TryDeactivate(activeItem, closePrevious);
newItem = EnsureItem(newItem);
//Problem is here, IsActive is false the first time around in the conductor
if(IsActive)
ScreenExtensions.TryActivate(newItem);
activeItem = newItem;
NotifyOfPropertyChange("ActiveItem");
OnActivationProcessed(activeItem, true);
}
Es sieht aus wie der Grund IsActive
im Conductor falsch ist, weil mein Dirigent der Stammansicht ist, die DisplayRootViewFor
erstellt wird und es sieht so aus, dass Funktion die nicht gesetzt ist IsActive
Eigenschaft zu wahr.
Also, ich weiß, dass ich das einfach falsch implementiere und ein Conductor nicht die Root View sein kann/sollte? Muss ich ein zweites Kind sehen, welches der Dirigent ist (das scheint ein bisschen viel zu sein)?
Ich hatte auch damit zu kämpfen, bis ich Ihre Antwort fand. Das war letzte Woche. Heute habe ich etwas anderes recherchiert und festgestellt, dass dieses Verhalten in der Dokumentation unter http://caliburnmicro.com/documentation/composition erwähnt wird: > Wenn Sie einen Gegenstand in einem Leiter aktivieren, der selbst nicht aktiv ist, wird dieser Gegenstand nicht tatsächlich aktiviert werden, bis der Leiter aktiviert wird. –