将变量从 ViewModel 传递到另一个视图 (MVVMCross)
本文关键字:视图 另一个 MVVMCross 变量 ViewModel | 更新日期: 2023-09-27 18:31:34
在过去的几周里,我一直在使用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));
}
}
当此IMvx命令被触发(按下按钮)时,将加载下一个视图,在本例中为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 的全部思想。但是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的东西。代码只出现在标准构造函数中,当我完全省略那个时,它不会编译/运行。
有谁知道我可以访问我通过请求导航发送的键值对?谢谢!
MVVMCross 非常基于约定 - 它的工作原理是尽可能在 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(),适用于 OnCreate() 之后的 Android 和 OnNavigatedTo 之后的 WP7)
有关这方面的示例,请查看TwitterSearch示例:
- https://github.com/slodge/MvvmCrossTwitterSearch
这有一个家庭视图模型,它使用以下方式调用导航:
private void DoSearch()
{
RequestNavigate<TwitterViewModel>(new { searchTerm = SearchText });
}
以及使用构造函数接收搜索词的 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 中提取它 - 有一个包含请求的 Extras 字符串(请参阅 https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Android/Views/MvxAndroidViewsContainer.cs 中 CreateViewModelFromIntent
中的反序列化)