2016-06-24 15 views
3

私はこれを理解しようとして失っているので、ここにお尋ねします。私は検索しましたが、それはすべて意味があるものですが、私の状況にも当てはまらないものです。OnActivateが呼び出されないのはなぜですか?

MVVMCaliburn.MicroWPFを使用しています。私は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の呼び出しをスキップします。なぜ私の財産が偽であるのか分かりません。私の指揮はDisplayRootViewForを使用して作成され、その機能が設定されていないように見えるされたルートビューなのでIsActiveは、導体で偽の理由があるように見えます

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プロパティをtrueに設定します。

これを知っているだけで、私はこれを間違って実装していて、導体はルートビューではい​​けません。私は指揮者(それは少しのように思える)の2番目の子供のビューを持っている必要がありますか?

答えて

3

私はそれを理解しました。基本的に私は考えていませんでした。導体/ルートビューのコンストラクタでビューを有効にすると、まだアクティブ化されていないため、正しく動作しません。導体の/ルートビューのOnActivateが呼び出されるまでIsActiveはtrueに設定されません。

OnInitializeが呼び出されても導体がアクティブでなく、1度の初期化機能であり、OnActivateが複数回呼び出される可能性があるため、これはある時点で問題となる可能性があります。私の場合、指揮官はルートビューなのでOnActivateは一度しか呼び出されないので、それは問題ありません。

導体のルートは、指揮者のコンストラクタでと呼ぶことはありません。

+0

私はあなたの答えを見つけるまで、これも苦労しました。それは先週だった。今日私は何か他のものを研究していましたが、この動作がhttp://caliburnmicro.com/documentation/composition: の文書に具体的に記載されていることが判明しました>それ自体がアクティブでない導体のアイテムをアクティブにすると、実際には導体が活性化されるまで活性化される。 –

関連する問題