我在這裏問這是因爲我在試圖弄清楚這一點是在虧本。我已經搜索過,所有出現的內容都是有意義的,但也不適用於我的情況。爲什麼OnActivate不被調用?
我使用WPF
與MVVM
和Caliburn.Micro
。我有一個相應的視圖模型的外殼窗口,它是一個Conductor<Screen>.Collection.OnceActive
和一個從Screen
繼承的屏幕。我在導體的構造函數中調用ActivateItem
來顯示後續屏幕,它正確顯示了屏幕,但從未調用屏幕覆蓋OnActivate
和屏幕的IsActive
屬性設置爲False
。
這隻發生在我第一次撥打指揮ActivateItem
,所有額外的電話將正確呼叫OnActivate
和OnDeactivate
。
這對我來說沒有意義,我也不知道發生了什麼。我清理解決方案,重建,甚至重新啓動,但仍然無法正常工作。下面是代碼:
父指揮
[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;
}
}
}
子屏幕
[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
我下載了卡利微源,所以我可以踏進ActivateItem
函數,看看發生了什麼。由於某種原因,當我第一次打電話給指揮ActivateItem
時,指揮的IsActive
屬性被設置爲false,導致Caliburn跳過呼叫OnActivate
覆蓋。我不知道爲什麼這個財產是錯誤的。
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);
}
它看起來像的原因IsActive
是在指揮錯誤是因爲我的指揮是使用DisplayRootViewFor
創建的根視圖,它看起來像這個功能並沒有設置IsActive
屬性爲true。
因此,知道這一點,我只是簡單地實施這個錯誤,一個導體不能/不應該是根視圖?我是否需要有第二個孩子的看法,那就是指揮(這看起來好像有點多)?
我也一直在努力,直到找到答案。那是上週。今天我正在研究別的東西,發現這種行爲在http://caliburnmicro.com/documentation/composition的文檔中有具體提及:如果你激活一個本身不活躍的售票員的物品,那麼這個物品不會實際上被激活直到導體被激活。 –