ViewModel 不会处理事件聚合器事件



我似乎只能从ShellViewModel处理EventAggregator事件,但我想从LoginViewModel处理它。

ShellViewModelLoginViewModel构造为其活动项。我还将其设置为从IHandle<AuthenticatedMessage>继承,作为事件发布工作的测试。它能够处理该事件。为了简洁起见,我没有在代码中显示任何取消订阅事件。

public class ShellViewModel : Conductor<IScreen>.Collection.OneActive, IHandle<AuthenticatedMessage>    
{
public ShellViewModel(IEventAggregator eventAggregator, LoginViewModel loginViewModel)
{
_eventAggregator = eventAggregator;
_loginViewModel = loginViewModel;
}

protected override async Task OnActivateAsync(CancellationToken cancellationToken)
{
await base.OnActivateAsync(cancellationToken);
_eventAggregator.SubscribeOnPublishedThread(this);

await ActivateItemAsync(_loginViewModel);
}

public async Task HandleAsync(AuthenticatedMessage authCode, CancellationToken cancellationToken)
{
// this is reached! So the event is publishing successfully.
await Task.CompletedTask;
}
}

LoginViewModel也订阅了该事件,但它的Handle方法没有被调用。

Login方法负责创建发布事件的LoginWindowViewModel窗口(如下所示(。

public class LoginViewModel : Screen, IHandle<AuthenticatedMessage>
{
private IEventAggregator _eventAggregator;
private readonly IWindowManager _windowManager;
private readonly ILoginWindowViewModelFactory _LoginWindowViewModelFactory;
public LoginViewModel(IEventAggregator eventAggregator, 
IWindowManager windowManager, 
ILoginWindowViewModelFactory loginWindowViewModelFactory)
{
_eventAggregator = eventAggregator; 
_windowManager = windowManager;
_LoginWindowViewModelFactory = loginWindowViewModelFactory;
}

protected override async Task OnActivateAsync(CancellationToken cancellationToken)
{
await base.OnActivateAsync(cancellationToken);

_eventAggregator.SubscribeOnPublishedThread(this);
}

// This is bound to a button click event. It creates a window.
public async void Login()
{
Uri loginUri = new Uri(_api.BaseLoginUrl);
await _windowManager.ShowWindowAsync(
_ndLoginWindowViewModelFactory.Create(loginUri, _eventAggregator));
}       


public async Task HandleAsync(AuthenticatedMessage authCode, CancellationToken cancellationToken)
{
// why is this is never reached?
await Task.CompletedTask;
}
}

发布AuthenticatedMessage事件的LoginWindowViewModel

public class LoginWindowViewModel : Screen
{
private readonly IEventAggregator _eventAggregator;
private readonly Uri _initialUri;         
public NDLoginWindowViewModel(Uri initialUri, IEventAggregator eventAggregator)
{
_initialUri = initialUri;
_eventAggregator = eventAggregator;
}       

// bound to the WebView2 (browser control) event
public async void NavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs e)
{            
string authCode = HttpUtility.ParseQueryString(new Uri(e.Uri).Query).Get("code");

// Publish event here. LoginViewModel should handle this, but currently only ShellViewModel can.
await _eventAggregator.PublishOnUIThreadAsync(new AuthenticatedMessage(authCode));                              
}
}
}

我在将eventAggregator.SubscribeOnPublishedThread(this);移动到LoginViewModel构造函数而不是OnActivateAsync()方法后解决了这个问题。

从这里:

protected override async Task OnActivateAsync(CancellationToken cancellationToken)
{
await base.OnActivateAsync(cancellationToken);

_eventAggregator.SubscribeOnPublishedThread(this);
}

收件人:

public LoginViewModel(IEventAggregator eventAggregator, 
IWindowManager windowManager, 
ILoginWindowViewModelFactory loginWindowViewModelFactory)
{
_eventAggregator = eventAggregator; 
_windowManager = windowManager;
_LoginWindowViewModelFactory = loginWindowViewModelFactory;
_eventAggregator.SubscribeOnPublishedThread(this);
}

编辑:

当视图第一次在ShellViewModel中创建时,OnActivateAsync方法没有被调用,因为它是我的根Screen和Conductor。因此,认购从未发生。

public class ShellViewModel : Conductor<IScreen>.Collection.OneActive
{
...
protected override async Task OnActivateAsync(CancellationToken cancellationToken)
{
await base.OnActivateAsync(cancellationToken);            

await ActivateItemAsync(_loginViewModel);
// IsActive = false here, therefore the child Screen `_loginViewModel` 
// is also not active. Result is that OnActivateAsync 
// in this view model does not get called.
}
}

它直接关系到这个问题和答案。

这就解释了为什么把它移到构造函数中就解决了这个问题。

最终的解决方案是在Constructor和OnActivateAsync方法中都添加_eventAggregator.SubscribeOnPublishedThread(this);。这允许我在离开此视图模型并返回后重新订阅该活动。

相关内容

  • 没有找到相关文章

最新更新