2012-04-17 25 views
7

Trong vài tuần qua, tôi đã nghiên cứu phát triển ứng dụng nền tảng chéo (IOS/Android/WP7) bằng cách sử dụng khung MVVMCross. Hôm nay tôi gặp phải một vấn đề tôi không thực sự biết làm thế nào để giải quyết, vì vậy hy vọng bạn có thể đẩy tôi đi đúng hướng.Chuyển các biến từ ViewModel sang Chế độ xem khác (MVVMCross)

Trong IOS Tôi đã xây dựng sau đây để điều hướng đến một trang khác (mã dưới đây nằm trong một ViewModel):

KeyValuePair<string,string> kvpAct1 = new KeyValuePair<string, string>("short", ".countertest5"); 

public IMvxCommand BeckhoffActuator1 
{ 
    get 
    {   
     return new MvxRelayCommand<Type>((type) => this.RequestNavigate<Beckhoff.BeckhoffActuatorViewModel>(kvpAct1)); 
    } 
} 

Khi IMvxCommand này là bắn (nút bấm) View tiếp theo được nạp, trong trường hợp này là BeckhoffActuatorViewModel. Trong đoạn mã của BeckhoffActuatorView tôi sử dụng KeyValuePair với phần trên:

public class BeckhoffActuatorView : MvxTouchDialogViewController<BeckhoffActuatorViewModel> 
{ 

    ICollection<string> icol; 

    public BeckhoffActuatorView(MvxShowViewModelRequest request) : base(request, UITableViewStyle.Grouped, null, true) 
    { 

     icol = request.ParameterValues.Values; 

    } 

    public override void ViewDidLoad() 
    { 
     //Code 
    } 
} 

xây dựng này đang làm việc tốt trong IOS, nhưng tôi muốn sử dụng việc xây dựng tương tự trong ứng dụng Android của tôi.

Mã trong ViewModel không thay đổi vì đó là toàn bộ ý tưởng của MVVM. Nhưng mã của BackhoffActuatorView là khác nhau dành cho Android:

public class BeckhoffActuatorView : MvxBindingActivityView<BeckhoffSensorViewModel> 
{ 
    public ICollection<string> icol; 

    public BeckhoffActuatorView() 
    { 
     Debug.WriteLine("Standard"); 
    } 

    public BeckhoffActuatorView(MvxShowViewModelRequest request) 
    { 
     Debug.WriteLine("Custom"); 

     icol = request.ParameterValues.Values; 
    } 

    protected override void OnViewModelSet() 
    { 

     SetContentView(Resource.Layout.BeckhoffActuatorView); 

    } 
} 

Đoạn mã trên không hoạt động, các MvxBindingActivityView dường như không thực hiện một cái gì đó tương tự như ViewController tôi sử dụng trong IOS. Mã chỉ đến trong hàm tạo tiêu chuẩn, và khi tôi bỏ nó ra hoàn toàn, nó sẽ không biên dịch/chạy.

Có ai biết tôi có thể truy cập keyvaluepair mà tôi gửi bằng RequestNavigate không? Cảm ơn bạn!

Trả lời

10

MVVMCross rất dựa trên quy ước - và nó hoạt động trên ý tưởng truyền thông điệp giữa ViewModels bất cứ khi nào có thể.

Nếu bạn điều hướng đến một ViewModel sử dụng:

KeyValuePair<string,string> kvpAct1 = new KeyValuePair<string, string>("short", ".countertest5"); 

public IMvxCommand BeckhoffActuator1 
{ 
    get 
    {   
     return new MvxRelayCommand<Type>((type) => this.RequestNavigate<Beckhoff.BeckhoffActuatorViewModel>(kvpAct1)); 
    } 
} 

sau đó bạn sẽ có thể chọn mà lên trong BeckhoffActuatorViewModel sử dụng constructor:

public class BeckhoffActuatorViewModel : MvxViewModel 
{ 
    public BeckhoffActuatorViewModel(string short) 
    { 
     ShortValue = short; 
    } 

    private string _shortValue; 
    public string ShortValue 
    { 
     get 
     { 
      return _shortValue; 
     } 
     set 
     { 
      _shortValue = value; 
      FirePropertyChanged("ShortValue"); 
     } 
    } 
} 

Và sau đó quan điểm của bạn có thể truy cập ViewModel.ShortValue (cho iOS này có thể được thực hiện sau khi base.ViewDidLoad(), cho Android sau khi OnCreate() và cho WP7 sau OnNavigatedTo)

Ví dụ về này, hãy nhìn vào ví dụ TwitterSearch:

này có HomeViewModel trong đó kêu gọi điều hướng sử dụng:

private void DoSearch() 
    { 
     RequestNavigate<TwitterViewModel>(new { searchTerm = SearchText }); 
    } 

và TwitterViewModel mà nhận được searchterm sử dụng các nhà xây dựng:

public TwitterViewModel(string searchTerm) 
    { 
     StartSearch(searchTerm); 
    } 

Xin lưu ý rằng chỉ có string s được phép trong thư này đi qua hiện tại - nhưng bạn luôn có thể tuần tự hóa các đối tượng của riêng mình bằng cách sử dụng JSON.Net - hoặc bạn có thể mở rộng khung công tác - đó là nguồn mở.

Xin lưu ý rằng chỉ string s, int s, double s và bool s được phép trong tham số constructor này đi qua hiện nay - điều này là do yêu cầu serialization cho XAML url và dành cho Android Intents. Nếu bạn muốn thử nghiệm với điều hướng bằng cách sử dụng các đối tượng được tuần tự tùy chỉnh của riêng mình, vui lòng xem http://slodge.blogspot.co.uk/2013/01/navigating-between-viewmodels-by-more.html.

Ngoài ra, lưu ý rằng nếu bạn muốn sử dụng điều hướng đối tượng ẩn danh (RequestNavigate<TwitterViewModel>(new { searchTerm = SearchText });) sau đó bạn sẽ cần phải chắc chắn rằng một thuộc tính được thiết lập InternalsVisibleTo - xem https://github.com/slodge/MvvmCrossTwitterSearch/blob/master/TwitterSearch.Core/Properties/AssemblyInfo.cs:

[assembly: InternalsVisibleTo("Cirrious.MvvmCross")] 

Tiếp tục .. Không phải cho những người yếu tim ... và đây không phải là "mã mvvm tốt" ... nhưng nếu bạn thực sự muốn/cần truy cập dữ liệu MvxShowViewModelRequest bên trong một hoạt động Android, thì bạn có thể giải nén nó khỏi Intent - có một chuỗi Extras có chứa yêu cầu (xem deserialisation trong CreateViewModelFromIntent trong https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Android/Views/MvxAndroidViewsContainer.cs)

+4

Cảm ơn Stuart, sử dụng ví dụ Twitter mà tôi đã cố gắng khắc phục sự cố của mình! – David

+0

Công việc tốt - nếu bạn cần một ví dụ khác về truyền tham số, thì bạn có thể thử CustomerManagement và các mẫu Sách quá :) – Stuart

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