VMを子ページに割り当てる責任は、ホストページ(つまり、ReactiveTabbedPage
)にあります。それだけで、どのVMがどのビューに対応しているかが分かります。
一度に1ステップずつ進んでみましょう。まず第一に、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
のコードビハインドで行うこれらのビューにVMをフックする必要があります。
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
呼び出しを使用して、この最も安全な方法やりました。実際には、あなたの子供の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>
そしてビハインドコード:
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);
});
}
}
は、もう一度、私たちは、UIのコントロールを持つVMのプロパティを関連付けるために良さを結合通常のRxUIをやっています。もう一度、突然変異しないプロパティに対しても最適化することができます。
この例では、ChildView2
はChildView1
とほとんど同じですが、明らかに完全に異なる可能性があります。あなたが期待よう
最終的な結果は次のとおりです。
何のスクリーンショットからも明らかではないのですが、非常に重要なのは、あなたが離れてから切り替えたときの各タブが非アクティブ化されていることである(それに関連するだろうとして、モデルが実装されている場合はISupportsActivation
)。これは、タブが使用されていないときにそのタブのバインディングとサブスクリプションをクリーンアップすることができ、メモリの負荷を軽減し、パフォーマンスを向上させることを意味します。
これはすぐには分かりませんでしたが、問題を完全に解決しました。失効についての良いニュースも! –