2013-10-16 10 views
9

Tôi có một ứng dụng nhỏ sử dụng WPF và Prism. Tôi có vỏ của tôi và hai mô-đun. Tôi có thể điều hướng thành công giữa chúng trong "thời trang bình thường" (ví dụ: từ nhấp chuột vào nút) để tôi biết chúng được kết nối để điều hướng chính xác. Tuy nhiên, nếu tôi thực hiện một số thao tác không đồng bộ kích hoạt sự kiện khi hoàn thành, tôi không thể điều hướng từ bên trong trình xử lý sự kiện đó. Điều cuối cùng tôi đã thử là sử dụng Event Aggregation để xuất bản một sự kiện trở lại chủ đề UI, nhưng nó vẫn chưa được điều hướng. Người đăng ký sự kiện nhận sự kiện thành công và kích hoạt RequestNavigate (...) nhưng giao diện người dùng không cập nhật.Không thể điều hướng từ bên trong phương thức gọi lại với Prism

Bây giờ, một số mã: ViewModel cho mô-đun đầu tiên của tôi 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; 
    } 
    ... 
} 

ViewModel cho mô-đun thứ hai của tôi 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"); 
    } 
} 

Bất cứ lời khuyên về những gì tôi có thể làm sai?

+0

tại sao bạn không đặt câu trả lời? – HichemSeeSharp

+5

Vui lòng sao chép các nhận xét đã giải quyết của bạn vào một câu trả lời và trả lời nó. Điều này có thể giúp người khác một ngày nào đó. –

+1

@ Jason: Vui lòng thêm giải pháp của bạn vào câu trả lời và đánh dấu câu trả lời.Nếu bạn không đánh dấu câu trả lời là câu trả lời, những người đang tìm kiếm giải pháp cùng một vấn đề sẽ không xem bài đăng này vì nó được hiển thị dưới dạng chưa được trả lời trong danh sách. Ngoài ra những người biết giải pháp và sẵn sàng trả lời nó sẽ bị thất vọng sau khi đầu tư thời gian của họ để đọc bài đăng này. –

Trả lời

1

Từ OP,

Ok, vì vậy chỉ cần một vài phút sau khi công bố, tôi đọc lại một bài báo tôi chạy vào ngày hôm qua và nhìn thấy một cái gì đó tôi đã bỏ lỡ ...

http://neverindoubtnet.blogspot.com/2009/05/event-aggregator-in-prism-explorer.html

Họ giải thích rằng một của quá tải của phương pháp đăng ký bao gồm một ThreadOption.

Vì vậy:

_eventAggregator.GetEvent<UserAuthenticatedEvent>() 
    .Subscribe(
    o => 
    { 
     Console.WriteLine("Requesting navigation..."); 
     _regionManager.RequestNavigate(
      RegionNames.ContentRegion, 
      new Uri(WellKnownViewNames.RosterView, UriKind.Relative)); 
    }); 

Trở thành:

_eventAggregator.GetEvent<UserAuthenticatedEvent>() 
    .Subscribe(
    o => 
    { 
     Console.WriteLine("Requesting navigation..."); 
     _regionManager.RequestNavigate(
      RegionNames.ContentRegion, 
      new Uri(WellKnownViewNames.RosterView, UriKind.Relative)); 
    }, 
    ThreadOption.UIThread); 

Và bây giờ nó hoạt động!

Hy vọng điều này sẽ giúp người khác xuống đường.

Tận hưởng!

Các vấn đề liên quan