將VM綁定到子頁面的責任在於主頁(即ReactiveTabbedPage
)。只有它知道哪個VM對應於哪個視圖。
讓我們一步一個腳印吧。首先,在MainViewModel
:
public class MainViewModel : ReactiveObject
{
public ChildViewModel1 Child1 => new ChildViewModel1();
public ChildViewModel2 Child2 => new ChildViewModel2();
}
這顯然代碼是不現實的,因爲你不會希望在每次屬性訪問重新孩子的VM。它更適合這裏的API。
ChildViewModel1
看起來是這樣的:
public class ChildViewModel1 : ReactiveObject
{
public string Test => "Hello";
}
而且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>
注意它聲明瞭每個子視圖。我們需要虛擬機掛接到這些意見,這是我們在代碼隱藏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);
});
}
}
我用WhenActivated
和OneWayBind
調用來完成這個最安全的方式。實際上,你的子虛擬機不太可能會改變,所以直接分配而不是綁定是完全沒問題的。
現在我們的孩子的意見可以扔在一起。下面是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>
和代碼隱藏:
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);
});
}
}
再次我們正在做平常RxUI結合善良的VM屬性與UI控件相關聯。再一次,你可以優化這個不變異的屬性。
就本例而言,ChildView2
與ChildView1
大致相同,但顯然它可能完全不同。
最終的結果是你所期望的:
![animation of reactive tabbed control](https://i.stack.imgur.com/lKUjv.gif)
什麼也不明顯從截圖,但很重要的是,每個選項卡被取消當你從它切換出來(如將其相關的查看模型,如果它實施了ISupportsActivation
)。這意味着您可以清除該選項卡未使用時的任何綁定和訂閱,從而減少內存壓力並提高性能。
這並不明顯,但完美地解決了這個問題!關於停用的好消息呢! –