Gar*_*cis 5 reactiveui xamarin.forms
我一直在使用ReamaUI与Xamarin Forms一段时间,但在尝试使用ReactiveTabbedPage时,我遇到了一堵砖墙.我无法弄清楚ViewModel将如何绑定到ReactiveTabbedPage的子级ReactiveContentPage.
因此,作为一个例子,我可能有以下XAML:
<ReactiveTabbedPage x:Name="TabbedPage">
<local:Page1View x:Name="Page1" />
<local:Page2View x:Name="Page2" />
</ReactiveTabbedPage>
Run Code Online (Sandbox Code Playgroud)
其中Page1View和Page2View都是ReactiveContentPage类型,T是关联的ViewModel.
我期望发生的是,当ReactiveTabbedPage被导航到时,将显示Page1View,并且将加载ViewModel(就像我直接导航到Page1View时那样).但是,ViewModel永远不会被调用(构造函数永远不会被触发,也不会发生数据绑定).
但是,Page1View和Page2View都会渲染,我可以看到在这些视图中创建的初始数据(例如标签的默认文本等).
我知道ViewModel的工作正常,因为如果我直接导航到Page1View(例如不在ReactiveTabbedPage中),所有内容都会按照我的预期显示.
我错过了什么,或者我错误地做了什么?或者这在当前版本的RxUI中是否不受支持?
任何意见是极大的赞赏!
将VM绑定到子页面的责任在于主页(即ReactiveTabbedPage
).它只知道哪个VM对应哪个视图.
让我们一步一步迈出这一步.首先,MainViewModel
:
public class MainViewModel : ReactiveObject
{
public ChildViewModel1 Child1 => new ChildViewModel1();
public ChildViewModel2 Child2 => new ChildViewModel2();
}
Run Code Online (Sandbox Code Playgroud)
这段代码显然不太现实,因为您不希望在每次访问属性时重新创建子VM.它更像是与此相关的API.
ChildViewModel1
看起来像这样:
public class ChildViewModel1 : ReactiveObject
{
public string Test => "Hello";
}
Run Code Online (Sandbox Code Playgroud)
而且ChildViewModel2
看起来大同小异.
现在我们可以开始设置视图了.我们MainView.xaml
看起来像这样:
<?xml version="1.0" encoding="utf-8" ?>
<rxui:ReactiveTabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:TypeArguments="vms:MainViewModel"
xmlns:local="clr-namespace:ReactiveTabbedPageTest"
xmlns:rxui="clr-namespace:ReactiveUI.XamForms;assembly=ReactiveUI.XamForms"
xmlns:vms="clr-namespace:ReactiveTabbedPageTest.VMs"
x:Class="ReactiveTabbedPageTest.MainView">
<local:Child1View x:Name="child1View" Title="Child 1"/>
<local:Child2View x:Name="child2View" Title="Child 2"/>
</rxui:ReactiveTabbedPage>
Run Code Online (Sandbox Code Playgroud)
请注意,它声明了每个子视图.我们需要将VM连接到那些视图,我们在代码隐藏中执行以下操作MainView
:
public partial class MainView : ReactiveTabbedPage<VMs.MainViewModel>
{
public MainView()
{
InitializeComponent();
this.ViewModel = new VMs.MainViewModel();
this.WhenActivated(
disposables =>
{
this
.OneWayBind(this.ViewModel, x => x.Child1, x => x.child1View.ViewModel)
.DisposeWith(disposables);
this
.OneWayBind(this.ViewModel, x => x.Child2, x => x.child2View.ViewModel)
.DisposeWith(disposables);
});
}
}
Run Code Online (Sandbox Code Playgroud)
我通过使用WhenActivated
和OneWayBind
调用这是最安全的方式.实际上,你的子VM不太可能会改变,所以直接分配它们而不是绑定是完全没问题的.
现在我们的孩子视图可以被抛在一起了.这是ChildView1.xaml
:
<?xml version="1.0" encoding="utf-8" ?>
<rxui:ReactiveContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ReactiveTabbedPageTest.Child1View"
x:TypeArguments="vms:ChildViewModel1"
xmlns:rxui="clr-namespace:ReactiveUI.XamForms;assembly=ReactiveUI.XamForms"
xmlns:vms="clr-namespace:ReactiveTabbedPageTest.VMs">
<Label x:Name="label" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
</rxui:ReactiveContentPage>
Run Code Online (Sandbox Code Playgroud)
代码隐藏:
public partial class Child1View : ReactiveContentPage<ChildViewModel1>
{
public Child1View()
{
InitializeComponent();
this.WhenActivated(
disposables =>
{
this
.OneWayBind(this.ViewModel, x => x.Test, x => x.label.Text)
.DisposeWith(disposables);
});
}
}
Run Code Online (Sandbox Code Playgroud)
我们再次使用通常的RxUI绑定优势来将VM中的属性与UI中的控件相关联.再次,您可以针对不变异的属性进行优化.
出于这个例子的目的,它们ChildView2
大致相同ChildView1
,但显然它可能完全不同.
最终结果如你所料:
屏幕截图中没有明显的内容,但非常重要的是当您切换它时,每个选项卡都会停用(如果它实现的话,它的关联视图模型也是如此ISupportsActivation
).这意味着您可以在不使用时清除该选项卡的任何绑定和订阅,从而减少内存压力并提高性能.
归档时间: |
|
查看次数: |
543 次 |
最近记录: |