绑定到 ViewController 中嵌套 CustomView 的属性
Binding to Properties of Nested CustomViews in a ViewController
鉴于我有以下设置(简化版本、删除逻辑以添加到父视图和约束等)。
public class TestViewModel : MvxViewModel
{
string _text;
public string Text
{
get => _text;
set
{
_text = value;
RaisePropertyChanged(() => Text);
}
}
}
public class TestViewController : MvxViewController<TestViewModel>
{
CustomViewA customViewA;
public TestViewController()
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
var bindingSet = this.CreateBindingSet<TestViewController, TestViewModel>();
bindingSet
.Bind(customViewA)
.For(v => v.Text)
.To(vm => vm.Text);
bindingSet.Apply();
}
}
public class CustomViewA : UIView
{
CustomViewB customViewB;
public string Text
{
get => customViewB.Text;
set => customViewB.Text = value;
}
}
public class CustomViewB : UIView
{
UITextField textField;
public string Text
{
get => textField.Text;
set => textField.Text = value;
}
}
为什么绑定不起作用?仅当我在 CustomViewB public 中创建 UITextField 并在 ViewController 中直接绑定到它而不是指向文本 属性 的 public 属性似乎工作。像这样:
bindingSet
.Bind(customViewA.customViewB.textField)
.For(v => v.Text)
.To(vm => vm.Text);
我在这里错过了什么?
这取决于你的要求。
一个方向的绑定应该有效(查看模型到视图),我已经测试了你的代码,当 ViewModel
属性 发生变化时,变化会传播到 CustomViewA
从那里到 CusomViewB
最后到 UITextField
.
但是,问题出在相反的方向(view-to-view 模型)。当用户更新文本字段时,它的 Text
属性 会发生变化。但是,没有关于此更改的通知。
虽然 属性 Text
指向文本字段,但它不是 "bound",所以当 TextField
的 Text
改变时, 属性 本身并不知道它,MvvmCross 绑定也不知道。
事实上,控制到视图模型方向的MvvmCross绑定是基于观察一个事件的能力,该事件告诉绑定检查绑定源的新值。这已经为 UITextField
的 Text
实现,它连接了 EditingChanged
事件(参见 source code)。
您仍然可以通过手动实现自定义绑定,使其在视图到视图模型方向上工作。这是 described in the documentation.
鉴于我有以下设置(简化版本、删除逻辑以添加到父视图和约束等)。
public class TestViewModel : MvxViewModel
{
string _text;
public string Text
{
get => _text;
set
{
_text = value;
RaisePropertyChanged(() => Text);
}
}
}
public class TestViewController : MvxViewController<TestViewModel>
{
CustomViewA customViewA;
public TestViewController()
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
var bindingSet = this.CreateBindingSet<TestViewController, TestViewModel>();
bindingSet
.Bind(customViewA)
.For(v => v.Text)
.To(vm => vm.Text);
bindingSet.Apply();
}
}
public class CustomViewA : UIView
{
CustomViewB customViewB;
public string Text
{
get => customViewB.Text;
set => customViewB.Text = value;
}
}
public class CustomViewB : UIView
{
UITextField textField;
public string Text
{
get => textField.Text;
set => textField.Text = value;
}
}
为什么绑定不起作用?仅当我在 CustomViewB public 中创建 UITextField 并在 ViewController 中直接绑定到它而不是指向文本 属性 的 public 属性似乎工作。像这样:
bindingSet
.Bind(customViewA.customViewB.textField)
.For(v => v.Text)
.To(vm => vm.Text);
我在这里错过了什么?
这取决于你的要求。
一个方向的绑定应该有效(查看模型到视图),我已经测试了你的代码,当 ViewModel
属性 发生变化时,变化会传播到 CustomViewA
从那里到 CusomViewB
最后到 UITextField
.
但是,问题出在相反的方向(view-to-view 模型)。当用户更新文本字段时,它的 Text
属性 会发生变化。但是,没有关于此更改的通知。
虽然 属性 Text
指向文本字段,但它不是 "bound",所以当 TextField
的 Text
改变时, 属性 本身并不知道它,MvvmCross 绑定也不知道。
事实上,控制到视图模型方向的MvvmCross绑定是基于观察一个事件的能力,该事件告诉绑定检查绑定源的新值。这已经为 UITextField
的 Text
实现,它连接了 EditingChanged
事件(参见 source code)。
您仍然可以通过手动实现自定义绑定,使其在视图到视图模型方向上工作。这是 described in the documentation.