将变量从ViewModel传递到另一个视图(MVVMCross)

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的代码中,我使用了上述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似乎没有实现与我在IOS中使用的ViewController类似的东西。 代码仅在标准构造函数中出现,并且当我完全省略它时,它无法编译/运行。

有人知道我如何访问使用RequestNavigate发送的键值对吗?谢谢!

1个回答

11

MVVMCross非常遵循惯例,并且基于在可能的情况下在ViewModels之间传递消息的思想进行工作。

如果您使用以下导航到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,它使用 navigate 进行调用:

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

还有一个 TwitterViewModel,它使用构造函数接收搜索词:

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

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

另外,请注意,目前在此构造函数参数传递中只允许使用 stringintdoublebool 类型 - 这是由于 Xaml Url 和 Android Intents 的序列化要求。如果您想尝试使用自定义序列化对象进行导航,则请参见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中提取它-有一个包含请求的Extras字符串(请参见https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Android/Views/MvxAndroidViewsContainer.cs中的CreateViewModelFromIntent的反序列化)。


4
谢谢,Stuart。使用 Twitter 的例子,我成功解决了我的问题! - David
干得好!如果你需要参数传递的另一个例子,那么你也可以尝试一下CustomerManagement和Books这两个示例 :) - Stuart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接