在我的Prism 6 WPF MVVM模块化应用程序(使用Unity DI)中,我希望使用松耦合事件在模块之间进行通信 - 一个模块是发布者,另一个模块是订阅者。在AuthorizationViewModel类的发布者方面,我特别具有以下方法:
public class AuthorizationViewModel : BindableBase
{
. . . . .
// This method is called from the command method when user clicks button in the view.
private void authenticateUser(string userName, string userPassword, Action<UserAuthorizationLevel> successCallback, Action<string> failureCallback)
{
Task task = Task.Run(() =>
this.getUsers((users) =>
{
// Get authenticated user information.
var userAuthenticated = GetUserByNameAndPassword(userName, userPassword, users);
// Call method publishing loosely coupled event if the user exists. Else display the error message.
if (userAuthenticated != null)
successCallback(userAuthenticated.AuthorizationLevel);
else
failureCallback("Authentification failed.");
}));
}
. . . . .
}
以下是AuthorizationViewModel类中的successCalback定义:
private void successCalback(UserAuthorizationLevel authorizationLevel)
{
// Publish loosely coupled event.
this._eventAggregator.GetEvent<UserAuthorizationLevelDeterminedEvent>().Publish(authorizationLevel);
}
UserAuthorizationLevel这里是在我的应用程序解决方案的公共位置定义的枚举类型,我不在这里显示它。 UserAuthorizationLevelDeterminedEvent是在我的应用程序解决方案的公共位置定义的事件类型。下面我展示它:
public class UserAuthorizationLevelDeterminedEvent : PubSubEvent<UserAuthorizationLevel>
{
}
successCalback方法在必要时及其代码行
运行this._eventAggregator.GetEvent<UserAuthorizationLevelDeterminedEvent>().Publish(authorizationLevel);
执行正常以便发布事件但订阅者根本不对事件作出反应!订户方面的活动没有回复!下面我在用户端显示代码:
public class CalibrationNavigationItemViewModel : BindableBase
{
. . . . .
private IEventAggregator _eventAggregator;
. . . . .
// The constructor; creates instance of CalibrationNavigationItemViewModel.
public CalibrationNavigationItemViewModel(IRegionManager regionManager, IEventAggregator eventAggregator)
{
. . . . .
this._eventAggregator = eventAggregator;
this._eventAggregator.GetEvent<UserAuthorizationLevelDeterminedEvent>().Subscribe(this.setRadiobuttonVisualStatus, ThreadOption.BackgroundThread);
. . . . .
}
. . . . .
// Changes visual status of Radiobutton in the View.
private void setRadiobuttonVisualStatus(UserAuthorizationLevel userAuthorizationLevel)
{
if (userAuthorizationLevel == UserAuthorizationLevel.Manufacturer)
this.IsVisible = Visibility.Visible;
else
this.IsVisible = Visibility.Collapsed;
}
// Controls visual status of Radiobutton in the View; the Visibility property
// of Radiobutton in the View is bound to this property.
public Visibility IsVisible
{
get { return this._isVisible; }
set { this.SetProperty(ref this._isVisible, value); }
}
}
(我请原谅我在这里做了一个不好的决定:我在模块中控制Radiobutton的可见性状态,而不是动态加载模块本身,因为我的应用程序必须提供更改用户的机会在同一个会话中。棱镜模块在初始化后无法卸载。)现在,回到我们的羊群;我在订阅者端设置了ThreadOption.BackgroundThread,因为发布者在TPL任务中发布事件但在UI线程中没有。我想知道:为什么订阅者根本不对已发布的活动做出反应?我做错了什么?请帮帮我。
答案 0 :(得分:0)
尚未对此进行测试,但您似乎是在单独的线程上发布该事件。因此,该事件不会自动冒泡到订阅者正在收听的UI线程。
您可以尝试等待任务,然后在任务完成时发布事件,或者您可以尝试在后台线程上订阅事件。
编辑: 我看到了问题。您正在使用共享项目。这不行。 SharedProject不会生成程序集,而是表现为类在引用的程序集中定义并在其中编译。你必须使用PCL。
答案 1 :(得分:0)
此处的问题是在共享项目中定义的事件,而不在类库中定义。
这样,事件被复制到引用项目,实际上存在两个不同的事件(具有相同的名称),一个被订阅,另一个被发布。