2016-06-24 3 views
3

나는 이것을 알아 내려고 애쓰며 잃어 버렸기 때문에 여기에 묻습니다. 나는 수색했는데 그 모든 것은 의미가 있지만 내 상황에는 적용되지 않는 것들이다.OnActivate가 호출되지 않는 이유는 무엇입니까?

나는 MVVMCaliburn.Micro과 함께 WPF을 사용하고 있습니다. 나는 Conductor<Screen>.Collection.OnceActive 인 해당 뷰 모델과 Screen에서 상속하는 화면이있는 쉘 창이 있습니다. 후속 화면을 표시하기 위해 도체 생성자 내에서 ActivateItem을 호출 중이면 화면을 올바르게 표시하지만 화면의 OnActivate에 대한 화면 오버라이드를 호출하지 않고 화면의 IsActive 속성을 False으로 설정합니다. 이 내용은 내가 컨덕터에서 ActivateItem를 호출 처음으로 일어나는

, 모든 추가 호출이 제대로 OnActivateOnDeactivate를 호출합니다.

이것은 내게 의미가 없으며 나는 무슨 일이 일어나는지 전혀 모른다. 내가 솔루션을 청소하고, 재건하고, 심지어 재부팅했지만 여전히 제대로 작동하지 않습니다. 나는 Caliburn 마이크로 소스를 다운로드

부모 지휘자

[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

나는 그것을 알아 냈다. 그리고 그것은 근본적으로 내가 생각하지 않고 있었다. 도체/루트보기의 생성자에서보기 활성화가 아직 활성화되지 않았기 때문에 제대로 작동하지 않습니다. 도체의/루트보기 OnActivate이 호출 될 때까지 IsActive이 참으로 설정되지 않습니다.

도체가 OnInitialize이 호출 되어도 활성 상태가 아니며 한 번 초기화 함수이고 OnActivate을 여러 번 호출 할 수 있기 때문에 문제가 될 수 있습니다. 나의 지휘자가 루트보기이기 때문에 내 경우에는 OnActivate이 한번만 호출 될 것이므로 괜찮을 것이다.

도덕적 인 이야기는 도체가 루트보기 인 경우 지휘자의 생성자에 을 호출하지 마십시오.

+0

나는이 답변도 찾을 때까지 어려움을 겪었습니다. 그게 지난 주 였어. 오늘 내가 뭔가 다른 것을 연구하고 있었고이 동작이 http://caliburnmicro.com/documentation/components : 의 문서에서 특별히 언급 된 것을 발견했습니다. 자체가 활성화되지 않은 지휘자의 항목을 활성화하면 해당 항목은 도체가 활성화 될 때까지 실제로 작동해야합니다. –