9

在过去的几周里,我一直在使用 MVVMCross 框架开发一个跨平台应用程序(IOS/Android/WP7)。今天我遇到了一个我真的不知道如何解决的问题,所以希望你能把我推向正确的方向。

在 IOS 中,我有以下结构用于导航到另一个页面(下面的代码位于 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));
    }
}

当这个 IMvxCommand 被触发(按下按钮)时,下一个视图被加载,在本例中是 BeckhoffActuatorViewModel。在 BeckhoffActuatorView 的代码中,我使用了上面的键值对:

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 的全部理念。但是对于 Android,BackhoffActuatorView 的代码是不同的:

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 似乎没有实现类似于我在 IOS 中使用的 ViewController 的东西。代码只出现在标准构造函数中,当我完全离开那个构造函数时,它不会编译/运行。

有谁知道我可以访问我使用 RequestNavigate 发送的键值对?谢谢!

4

1 回答 1

11

MVVMCross 非常基于约定 - 它的工作原理是尽可能在 ViewModel 之间传递消息。

如果您使用以下方法导航到 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));
    }
}

那么您应该能够使用构造函数在 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() 之后完成,对于 Android 在 OnCreate() 之后以及对于 WP7 在 OnNavigatedTo 之后完成)

有关这方面的示例,请查看 TwitterSearch 示例:

这有一个 HomeViewModel 调用导航使用:

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

和一个使用构造函数接收 searchTerm 的 TwitterViewModel:

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

请注意,string目前在此消息传递中只允许 s - 但您始终可以使用 JSON.Net 序列化您自己的对象 - 或者您可以扩展框架 - 它是开源的。

请注意,目前在此构造函数参数中只允许传递strings、ints、doubles 和bools - 这是由于 Xaml Urls 和 Android Intents 的序列化要求。如果您想使用自己的自定义序列化对象来试验导航,请参阅http://slodge.blogspot.co.uk/2013/01/navigating-between-viewmodels-by-more.html

RequestNavigate<TwitterViewModel>(new { searchTerm = SearchText });另外,请注意,如果您想使用匿名对象InternalsVisibleTo导航( /AssemblyInfo.cs

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

此外...不适合胆小的人...这不是“好的 mvvm 代码”...但是如果您真的想要/需要访问 Android 活动中的 MvxShowViewModelRequest 数据,那么您可以从传入 Intent - 有一个包含请求的 Extras 字符串(请参阅https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Android/Views/MvxAndroidViewsContainer.csCreateViewModelFromIntent 中的反序列化)

于 2012-04-17T14:12:29.493 回答