2012-04-17 86 views
7

在過去的幾周裏,我一直在使用MVVMCross框架開發跨平臺的應用程序(IOS/Android/WP7)。今天我遇到了一個我不知道如何解決的問題,所以希望你能把我推向正確的方向。將變量從ViewModel傳遞到另一個視圖(MVVMCross)

在IOS我有以下的建設導航到另一個頁面(下面的代碼坐落在一個視圖模型):

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

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

當這個IMvxCommand被觸發(按下按鈕)下一個視圖被加載,在這種情況下是BeckhoffActuatorViewModel。在BeckhoffActuatorView的代碼,我用的是keyvaluepair從上面:

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 
    } 
} 

這種結構在IOS工作正常,但我想用我的Android應用程序相同的結構。

ViewModel中的代碼沒有改變,因爲這是MVVM的整個想法。但BackhoffActuatorView的代碼爲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); 

    } 
} 

上面的代碼不工作時,MvxBindingActivityView似乎並沒有實現類似的ViewController我在IOS使用的東西。代碼只在標準構造函數中出現,當我完全離開它時,它不會編譯/運行。

有誰知道知道我可以訪問我使用RequestNavigate發送的keyvaluepair?謝謝!

回答

10

MVVMCross是非常基於約定 - 它的工作原理是儘可能在ViewModels之間傳遞消息。

如果您導航到一個視圖模型使用:

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

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

,那麼你應該能夠使用構造來挑選了在BeckhoffActuatorViewModel:

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

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

然後你的意見可以訪問ViewModel.ShortValue(對於iOS,這可以在base.ViewDidLoad()之後完成,OnCreate()之後的Android以及OnNavigatedTo之後的WP7)

這一點,看看在TwitterSearch例如:

這有利用它調用導航HomeViewModel:

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

和接收使用構造的SEARCHTERM一個TwitterViewModel:

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

請注意,此消息目前只允許使用 string - 但您始終可以使用JSON.Net序列化您自己的對象 - 或者您可以擴展該框架 - 它是開源的。

請注意,只有string S,int S,double S和bool s的允許通過目前該構造函數的參數 - 這是由於XAML的URL和Android的意圖系列化的要求。如果您想使用自己的自定義序列化對象進行導航實驗,請參閱http://slodge.blogspot.co.uk/2013/01/navigating-between-viewmodels-by-more.html

另請注意,如果你想使用匿名對象導航(RequestNavigate<TwitterViewModel>(new { searchTerm = SearchText });),那麼你就需要確保一個InternalsVisibleTo屬性設置 - 見https://github.com/slodge/MvvmCrossTwitterSearch/blob/master/TwitterSearch.Core/Properties/AssemblyInfo.cs

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

進一步.. 。不適合膽小的...這不是「好的mvvm代碼」......但是如果你真的想要/需要訪問Android活動中的MvxShowViewModelRequest數據,那麼你可以從傳入的Intent中提取它 - 有一個包含請求的額外字符串(請參閱CreateViewModelFromIntent中的反序列化https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Android/Views/MvxAndroidViewsContainer.cs

+4

謝謝Stuart,使用Twitter示例我設法解決了我的問題! – David 2012-04-18 08:03:27

+0

幹得好 - 如果你需要另一個參數傳遞的例子,那麼你可以嘗試CustomerManagement和書籍樣本:) – Stuart 2012-04-18 11:36:18

相關問題