2012-04-17 50 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

相关问题