2016-06-24 99 views
3

我在這裏問這是因爲我在試圖弄清楚這一點是在虧本。我已經搜索過,所有出現的內容都是有意義的,但也不適用於我的情況。爲什麼OnActivate不被調用?

我使用WPFMVVMCaliburn.Micro。我有一個相應的視圖模型的外殼窗口,它是一個Conductor<Screen>.Collection.OnceActive和一個從Screen繼承的屏幕。我在導體的構造函數中調用ActivateItem來顯示後續屏幕,它正確顯示了屏幕,但從未調用屏幕覆蓋OnActivate和屏幕的IsActive屬性設置爲False

這隻發生在我第一次撥打指揮ActivateItem,所有額外的電話將正確呼叫OnActivateOnDeactivate

這對我來說沒有意義,我也不知道發生了什麼。我清理解決方案,重建,甚至重新啓動,但仍然無法正常工作。下面是代碼:

父指揮

[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。

因此,知道這一點,我只是簡單地實施這個錯誤,一個導體不能/不應該是根視圖?我是否需要有第二個孩子的看法,那就是指揮(這看起來好像有點多)?

回答

3

我想通了,基本上我沒在想。激活導體/根視圖構造函數中的視圖無法正常工作,因爲它尚未激活。 IsActive在調用指揮/根視圖的OnActivate之前未設置爲true。

這在某些時候可能會有問題,因爲即使調用了OnInitialize,導體仍處於非活動狀態,這意味着一次init函數和OnActivate可能被多次調用。在我的情況下,這將是罰款,因爲我的售票員是根視圖,所以OnActivate將只被調用一次。

故事的道德是,當導體是根視圖時,不要在指揮員的構造函數中調用ActivateItem

+0

我也一直在努力,直到找到答案。那是上週。今天我正在研究別的東西,發現這種行爲在http://caliburnmicro.com/documentation/composition的文檔中有具體提及:如果你激活一個本身不活躍的售票員的物品,那麼這個物品不會實際上被激活直到導體被激活。 –

相關問題