2012-06-10 25 views
10

Tôi vừa mới bắt đầu phát triển cửa sổ mới của mình 8 ứng dụng tuần trước bằng cách sử dụng ánh sáng mvvm. Tôi quen với điều hướng mvvmlight WP7. Làm thế nào tôi có thể đạt được như nhau trong windows 8. Có thể bất kỳ một đề nghị một phương pháp tốt hơn để đạt được như nhau trong windows 8. Tôi tìm thấy một giải pháp, nơi chúng tôi ghi đè lên các sự kiện onnavigated trong vm và xử lý điều hướng đến trang khác. Nhưng tôi nghĩ rằng phương pháp đó đã lỗi thời. Bất kỳ ai xin vui lòng hướng dẫn tôi với việc thực hiện đúng. Cảm ơn trước.Điều hướng trang thông qua ViewModel sử dụng MVVMLight trong windows 8

+0

bạn có thể chia sẻ giải pháp của mình, cách bạn ghi đè OnNavigatedTo trong vm? –

Trả lời

15

Tôi hiểu đây không phải là câu trả lời chính xác mà bạn có thể đang tìm kiếm, nhưng điều này có thể cung cấp cho bạn một số ý tưởng để khám phá.

Trong trường hợp của tôi, tôi không sử dụng MVVMLight - nhưng thực thi MVVM đơn giản của riêng tôi. Tôi sử dụng lớp BindableBase (đi kèm với mẫu RC 2012 RC mặc định) cho thông báo thuộc tính. Tôi tưởng tượng, bạn có thể sử dụng MVVMLight để cung cấp cho bạn một số cơ sở hạ tầng, mà bạn có thể bổ sung với một cái gì đó như dưới đây.

Đối với chuyển hướng, tôi xác định một giao diện trông giống như:

Và thực hiện nó như sau:

using System; 
using System.Collections.Generic; 
using System.Threading.Tasks; 
using Windows.UI.Xaml.Controls; 

public class NavigationService : INavigationService 
{ 
    private readonly Frame _frame; 

    public NavigationService(Frame frame) 
    { 
     _frame = frame; 
     _frame.Navigated += OnFrameNavigated; 
    } 

    private void OnFrameNavigated(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e) 
    { 
     var view = e.Content as IView; 
     if (view == null) 
      return; 

     var navMsg = new NavigationMessage() 
     { 
      Sender = this, 
      NewView = view, 
      Parameter = e.Parameter, 
      NavigationMode = (int)e.NavigationMode 
     }; 

     EventManager.Current.Publish(navMsg); 

     //Anything that the parent needs to be notified should happen in of after this method 
     var viewModel = view.ViewModel; 
     if (viewModel != null) 
      viewModel.Initialise(e.Parameter); 
    } 

    public void Navigate(Type pageType) 
    { 
     DisposePreviousView(); 
     _frame.Navigate(pageType); 
    } 

    public void Navigate(Type pageType, object parameter) 
    { 
     DisposePreviousView(); 
     _frame.Navigate(pageType, parameter); 
    } 

    private void DisposePreviousView() 
    { 
     var currentView = this.CurrentView; 
     var currentViewDisposable = currentView as IDisposable; 
     if (currentViewDisposable != null) 
     { 
      currentViewDisposable.Dispose(); 
      currentViewDisposable = null; 
     } //view model is disposed in the view implementation 
    } 

    public void EnsureNavigated(Type pageType, object parameter) 
    { 
     var currentView = this.CurrentView; 
     if (currentView == null || currentView.GetType() != pageType) 
     { 
      Navigate(pageType, parameter); 
     } 
    } 

    public IView CurrentView 
    { 
     get { return _frame.Content as IView; } 
    } 


    public bool CanGoBack 
    { 
     get { return _frame != null && _frame.CanGoBack; } 
    } 

    public void GoBack() 
    { 
     // Use the navigation frame to return to the previous page 
     if (_frame != null && _frame.CanGoBack) _frame.GoBack(); 
    } 

    public bool CanGoForward 
    { 
     get { return _frame != null && _frame.CanGoForward; } 
    } 

    public void GoForward() 
    { 
     // Use the navigation frame to return to the previous page 
     if (_frame != null && _frame.CanGoForward) _frame.GoForward(); 
    } 

} 

IView:

public interface IView : IDisposable 
{ 
    IViewModel ViewModel { get; } 
    void Refresh(); 
} 

IViewModel:

public interface IViewModel : INotifyPropertyChanged, IDisposable 
{ 
    void Initialise(object parameter); 
    string ViewTitle { get; } 
    void Refresh(); 
} 

Cuối cùng, trong trang XAML, xác định một yếu tố Frame:

<Frame x:Name="ContentFrame" /> 

Và trong code-behind of the page: (điều này ở phần xấu xí chỉ trong quan điểm của tôi - nhưng nó hy vọng không phải là quá xấu):

var _navigationService = new NavigationService(this.ContentFrame); 

Bây giờ bạn có thể chuyển _navigationService sang chế độ xem. Trong trường hợp của tôi, tôi tạo chế độ xem trong mã phía sau của trang:

public HomePage() 
{ 
    this.InitializeComponent(); 

    var _navigationService = NavigationService.GetFor(this.ContentFrame); 

    DataContext = new HomePageViewModel(_navigationService); 

} 

Hy vọng điều này sẽ hữu ích.

+0

+1 - Tôi thích cách tiếp cận này. Đối với "phần xấu xí", bạn có thể sử dụng vùng chứa DI để bạn không phải chuyển dịch vụ tới viewmodel trong codebehind của khung nhìn. – EkoostikMartin

+0

Phiên bản mới nhất của MVVMLight có một SimpleIoc mà đặt này trong vở kịch ra khỏi hộp với một vài dòng mã. –

4

Đọc bài báo đăng trên Tạp chí MSDN chỉ thời gian gần đây bởi Laurent Bugnion mình vào làm việc với Toolkit MVVM Light và Windows 8.

Hướng tới cuối bài viết, ông giải thích chính xác cách thiết lập số NavigationService mà bạn cần.

http://msdn.microsoft.com/en-us/magazine/jj651572.aspx

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