Lon*_*aco 10 c# navigation wpf prism module
我有一个使用WPF和Prism的小应用程序.我有我的shell和两个模块.我可以在"正常时尚"(例如点击按钮)之间成功地在它们之间导航,因此我知道它们已正确连接导航.但是,如果我执行一些在完成时触发事件的异步操作,我无法从该事件处理程序内部导航.我尝试的最后一件事是使用Event Aggregation将事件发布回UI线程,但它仍然没有导航.事件的订阅者成功获取事件并触发RequestNavigate(...),但UI不会更新.
现在,一些代码:我的第一个模块的viewmodel LoginModule
:
public class LoginViewModel : ViewModelBase, ILoginViewModel, INavigationAware
{
...
[ImportingConstructor]
public LoginViewModel(IRegionManager regionManager, IUnityContainer container, IEventAggregator eventAggregator)
{
_regionManager = regionManager;
_container = container;
_eventAggregator = eventAggregator;
}
private DelegateCommand _Login;
public DelegateCommand Login
{
get
{
if (_Login == null)
_Login = new DelegateCommand(() => LoginHandler());
return _Login;
}
}
private void LoginHandler()
{
_client = new JabberClient();
_client.Server = "gmail.com";
_client.User = Username;
_client.Password = Password;
...
_client.OnAuthenticate += client_OnAuthenticate;
_client.Connect();
}
private void client_OnAuthenticate(object sender)
{
Console.WriteLine("Authenticated!");
_eventAggregator.GetEvent<UserAuthenticatedEvent>().Publish("");
}
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
}
...
}
Run Code Online (Sandbox Code Playgroud)
我的第二个模块的ViewModel RosterModule
:
public class RosterViewModel : IRosterViewModel, INavigationAware
{
private readonly IEventAggregator _eventAggregator;
private readonly IRegionManager _regionManager;
[ImportingConstructor]
public RosterViewModel(IRegionManager regionManager, IEventAggregator eventAggregator)
{
_regionManager = regionManager;
_eventAggregator = eventAggregator;
_eventAggregator.GetEvent<UserAuthenticatedEvent>().Subscribe(o =>
{
Console.WriteLine("Requesting navigation...");
_regionManager.RequestNavigate(RegionNames.ContentRegion, new Uri(WellKnownViewNames.RosterView, UriKind.Relative));
});
}
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
}
public void OnNavigatedFrom(NavigationContext navigationContext)
{
}
public void OnNavigatedTo(NavigationContext navigationContext)
{
Console.WriteLine("I'm here at the RosterViewModel");
}
}
Run Code Online (Sandbox Code Playgroud)
关于我可能做错的任何提示?
从OP,
好吧,发布后几分钟,我重读了昨天遇到的一篇文章,发现了一些我错过的东西......
http://neverindoubtnet.blogspot.com/2009/05/event-aggregator-in-prism-explorer.html
他们解释说 Subscribe 方法的重载之一包括 ThreadOption。
所以:
_eventAggregator.GetEvent<UserAuthenticatedEvent>()
.Subscribe(
o =>
{
Console.WriteLine("Requesting navigation...");
_regionManager.RequestNavigate(
RegionNames.ContentRegion,
new Uri(WellKnownViewNames.RosterView, UriKind.Relative));
});
Run Code Online (Sandbox Code Playgroud)
变成:
_eventAggregator.GetEvent<UserAuthenticatedEvent>()
.Subscribe(
o =>
{
Console.WriteLine("Requesting navigation...");
_regionManager.RequestNavigate(
RegionNames.ContentRegion,
new Uri(WellKnownViewNames.RosterView, UriKind.Relative));
},
ThreadOption.UIThread);
Run Code Online (Sandbox Code Playgroud)
现在可以了!
希望这能对其他人有所帮助。
享受!