如何绑定数组我mvvmcross [英] How to bind arrays i mvvmcross
问题描述
我需要一个按钮在视图中移动,当它被点击。
我以下列方式绑定按钮(Android)
set.Bind(_paramsButton).For pb => pb.LeftMargin).To(vm => vm.ButtonX).OneWay();
set.Bind(_paramsButton).For(pb => pb.TopMargin).To(vm => vm.ButtonY).OneWay();
set.Bind(_paramsButton).For(pb => pb.Height).To(vm => vm.ButtonHight).OneWay();
set.Bind(_paramsButton).For(pb => pb.Width).To(vm => vm.ButtonWidth).OneWay();
在viewModel中我有正常属性
private int _buttonX;
public int ButtonX
{
get {return _buttonX; }
set {_buttonX = value; RaisePropertyChanged(()=> ButtonX);
}
等。
这是正常的。
现在我有10个按钮,想要像
for(int i = 0; i< 10; i ++ ){
set.Bind(_paramsButton [i])。对于(pb => pb.LeftMargin).To(vm => vm.ButtonX [i])。OneWay();
set.Bind(_paramsButton [i])。对于(pb => pb.TopMargin).To(vm => vm.ButtonY [i])。OneWay();
set.Bind(_paramsButton [i])For(pb => pb.Height).To(vm => vm.ButtonHight [i])。OneWay();
set.Bind(_paramsButton [i])For(pb => pb.Width).To(vm => vm.ButtonWidth [i])。OneWay();
}
或
$ b $ (int i = 0; i <10; i ++){
set.Bind(_paramsButton [i])。对于(pb => pb.LeftMargin ).To(vm => vm.Button [i] .X).OneWay();
set.Bind(_paramsButton [i])。对于(pb => pb.TopMargin).To(vm => vm.Button [i] .Y).OneWay();
set.Bind(_paramsButton [i])For(pb => pb.Height).To(vm => vm.Button [i] .Height).OneWay();
set.Bind(_paramsButton [i])。对于(pb => pb.Width).To(vm => vm.Button [i] .Width).OneWay();
}
我的问题是在viewModel中,我不知道如何获得RaisePropertyChanged以数组列表中的各个项目触发。
有没有人有关于如何在modelView中声明整数数组的例子?
一般的答案是如果要为子视图模型启动 RaisePropertyChanged
,那么最简单的方法是使该子视图模型支持 INotifyPropertyChanged
所以,例如,你可以有一个ButtonViewModel子类,如:
public class ButtonViewModel:MvxNotifyPropertyChanged
{
private int _x;
public int X
{
get {return _x; }
set {_x = value; RaisePropertyChanged(()=> X); }
}
// etc
}
然后您的页面级ViewModel可以存储列表
或 ObservableCollection
:
public class MyViewModel:MvxViewModel
{
private readonly List&Button ButtonModel> _纽扣;
public List< ButtonViewModel> Buttons
{
get {return __buttons; }
}
// etc
}
一般来说,这是解决问题的方法 - 这应该允许绑定工作。
但是。 ..在您的具体代码的情况下,还有另一个问题需要考虑。
您的绑定语句包含绑定表达式中的for-loop变量:
(int i = 0; i< 10; i ++){set.Bind(_paramsButton [i])。 pb => pb.LeftMargin).To(vm => vm.Button [i] .X).OneWay();
}
我怕这只是将无法正常工作 - MvvmCross的表达式对于这些类型的局部变量表达式没有任何内置的评估。
您可以为绑定语句生成一个字符串,如:对于(int i = 0; i <10; i ++){
$按钮[{0}]。X,i);
set.Bind(_paramsButton [i])。对于(pb => pb.LeftMargin).To(to).OneWay();
}
- 您可以尝试使用某种收集类进行绑定。有关这方面的例子,请参阅N = 38的第二部分中绑定的僵尸集合映射注释 - http://slodge.blogspot.co.uk/2013/09/n38-more-maps-and-more-zombies.html
- 您可以尝试将按钮视图设置为
MvxView
对象 - 每个对象都有自己的内部绑定。有关这个想法的更多信息,请参阅中的N = 32 http://slodge.blogspot.co.uk/2013/06/n32-truth-about-viewmodels-starring.html
I need a button to move in the view, when it is clicked. I have bind the the button in the following way (Android)
set.Bind(_paramsButton).For(pb => pb.LeftMargin).To(vm => vm.ButtonX).OneWay();
set.Bind(_paramsButton).For(pb => pb.TopMargin).To(vm => vm.ButtonY).OneWay();
set.Bind(_paramsButton).For(pb => pb.Height).To(vm => vm.ButtonHight).OneWay();
set.Bind(_paramsButton).For(pb => pb.Width).To(vm => vm.ButtonWidth).OneWay();
In the viewModel i have the 'normal' properties
private int _buttonX;
public int ButtonX
{
get { return _buttonX; }
set { _buttonX = value; RaisePropertyChanged(() => ButtonX); }
}
etc.
This is working fine. Now i have 10 buttons and want to bind like
for(int i=0; i<10; i++){
set.Bind(_paramsButton[i]).For(pb => pb.LeftMargin).To(vm => vm.ButtonX[i]).OneWay();
set.Bind(_paramsButton[i]).For(pb => pb.TopMargin).To(vm => vm.ButtonY[i]).OneWay();
set.Bind(_paramsButton[i]).For(pb => pb.Height).To(vm => vm.ButtonHight[i]).OneWay();
set.Bind(_paramsButton[i]).For(pb => pb.Width).To(vm => vm.ButtonWidth[i]).OneWay();
}
or
for(int i=0; i<10; i++){
set.Bind(_paramsButton[i]).For(pb => pb.LeftMargin).To(vm => vm.Button[i].X).OneWay();
set.Bind(_paramsButton[i]).For(pb => pb.TopMargin).To(vm => vm.Button[i].Y).OneWay();
set.Bind(_paramsButton[i]).For(pb => pb.Height).To(vm => vm.Button[i].Height).OneWay();
set.Bind(_paramsButton[i]).For(pb => pb.Width).To(vm => vm.Button[i].Width).OneWay();
}
My problem is in the viewModel, I don't know how to get the RaisePropertyChanged to fire on the individual items in the array list. Does anybody have an example on how to declare the integer array in the modelView?
The general answer is that if you want to fire RaisePropertyChanged
for a sub-viewModel, then the easiest way is to make that sub-viewModel support INotifyPropertyChanged
So, for example, you could have a ButtonViewModel subclass like:
public class ButtonViewModel : MvxNotifyPropertyChanged
{
private int _x;
public int X
{
get { return _x; }
set { _x = value; RaisePropertyChanged(() => X); }
}
// etc
}
and your page-level ViewModel could then store a List
or ObservableCollection
of those:
public class MyViewModel : MvxViewModel
{
private readonly List<ButtonViewModel> _buttons;
public List<ButtonViewModel> Buttons
{
get { return __buttons; }
}
// etc
}
In general, this is the way to approach the problem - and this should allow the binding to work.
However... in the case of your specific code, there is another problem to consider.
Your binding statement includes a for-loop variable in the binding expression:
for(int i=0; i<10; i++){
set.Bind(_paramsButton[i]).For(pb => pb.LeftMargin).To(vm => vm.Button[i].X).OneWay();
}
I'm afraid this simply won't work - MvvmCross's expression walking doesn't have any built-in evaluation for these types of local-variable expressions.
You could instead generate a string for the binding statement like:
for(int i=0; i<10; i++){
var to = string.Format("Button[{0}].X", i);
set.Bind(_paramsButton[i]).For(pb => pb.LeftMargin).To(to).OneWay();
}
As some other alternatives:
- you could instead try using some kind of collection class for binding. For an example of this, see how the set of zombies is bound to map annotations in the second part of N=38 - http://slodge.blogspot.co.uk/2013/09/n38-more-maps-and-more-zombies.html
- you could instead try setting up your button views as
MvxView
objects - each with their own internal bindings. For more on this idea, see N=32 in http://slodge.blogspot.co.uk/2013/06/n32-truth-about-viewmodels-starring.html
这篇关于如何绑定数组我mvvmcross的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!