gpt4 book ai didi

wpf - 为什么不调用 OnActivate?

转载 作者:行者123 更新时间:2023-12-04 14:08:28 28 4
gpt4 key购买 nike

我在这里问这个是因为我试图弄清楚这一点而不知所措。我已经搜索过,所有出现的东西都是有意义的,但也不适用于我的情况。

我正在使用 WPFMVVMCaliburn.Micro .我有一个带有相应 View 模型的 shell 窗口,它是 Conductor<Screen>.Collection.OnceActive和一个继承自 Screen 的屏幕.我调用 ActivateItem在 Conductor 的构造函数中显示后续屏幕,它正确显示屏幕,但从不调用屏幕对 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; }
}

更新

我下载了 Caliburn Micro 源代码,这样我就可以进入 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在 Conductor 中为 false 是因为我的 Conductor 是使用 DisplayRootViewFor 创建的 Root View 并且看起来该函数没有设置 IsActive属性为真。

那么,知道这一点,我只是在执行这个错误,而指挥者不能/不应该是 Root View 吗?我是否需要有第二个 subview ,即指挥(这似乎有点多)?

最佳答案

我想通了,基本上是我没有想到。在导体/ Root View 的构造函数中激活 View 不能正常工作,因为它还没有被激活。 IsActive直到指挥者/ Root View 的 OnActivate 才设置为 true叫做。

这在某些时候可能会出现问题,因为即使在 OnInitialize 时导体也未激活。被调用,这意味着是一次性初始化函数和 OnActivate可以多次调用。就我而言,这会很好,因为我的指挥是 Root View ,所以 OnActivate只会被调用一次。

故事的寓意是,不要调用 ActivateItem当导体是 Root View 时,在导体的构造函数中。

关于wpf - 为什么不调用 OnActivate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38019227/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com