[英]Why is loosely coupled event generated with Prism EventAggregator not received by its subscriber?
在我的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); }
}
}
( 我請您包涵,在這里我會做個不好的休息:我正在控制模塊中單選按鈕的可見性狀態,而不是動態地加載模塊本身,因為我的應用程序必須提供機會在同一會話中更改用戶。Prism模塊可以初始化后將其卸載。 )現在,回到我們的羊; 我將ThreadOption.BackgroundThread設置在訂閱者端,因為發布者是在TPL Task中發布事件,而不是在UI線程中發布事件。 我想知道: 為什么訂戶根本不對已發布事件做出反應? 我做錯了什么? 請幫我。
尚未對此進行測試,但似乎您是在另一個線程上發布事件。 因此,該事件不會自動上升到訂戶正在監聽的UI線程。
您可以嘗試等待任務,然后在任務完成后發布事件,也可以嘗試在后台線程上訂閱事件。
編輯:我看到了問題。 您正在使用共享項目。 這不行。 SharedProject不產生程序集,而是像在引用的程序集中定義該類並在其中對其進行編譯一樣起作用。 您必須使用PCL。
這里的問題是事件是在共享項目中定義的,而不是在類庫中定義的 。
這樣,事件被復制到引用項目,實際上存在兩個不同的事件(具有相同的名稱),一個被訂閱,而另一個被發布。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.