[RxUI] 16.1 – 扩展View支持
扩展IViewFor
有时候,需要将ReactiveUI视图类型的功能进行扩展。答案就在于扩展IViewFor
接口,以便ReactiveUI将其拾取并将其注册到ViewLocator
实例。一旦实现IViewFor<T>
,就可以在类上以扩展方法方式使用绑定。
下面是为各种平台提供的一些ReactiveUI基本实现,这不是详尽列表。
- ReactiveUserControl(Windows平台)
- ReactiveContentPage(Xamarin Forms)
注意:在撰写本文时,C#不支持多类继承
Xamarin Forms示例
对于此示例,将使用Rg.Plugins.Popup库,该库显示Xamarin.Forms的弹出样式模态页面。这种情况下,需要扩展基本的实现。另一个选择是从IViewFor<T>
显式扩展每个页面。请根据实际情况选择最合适的方式。
实现
需要做的第一件事是通过扩展IViewFor
来桥接PopupPage
,下面是具体实现。
public abstract class BasePopupPage<TViewModel> : PopupPage, IViewFor<TViewModel>
where TViewModel : class
{
protected readonly CompositeDisposable SubscriptionDisposables = new CompositeDisposable();
public static readonly BindableProperty ViewModelProperty =
BindableProperty.Create(nameof(ViewModel),
typeof(TViewModel),
typeof(IViewFor<TViewModel>),
(object) null,
BindingMode.OneWay,
(BindableProperty.ValidateValueDelegate) null,
new BindableProperty.BindingPropertyChangedDelegate(OnViewModelChanged),
(BindableProperty.BindingPropertyChangingDelegate) null,
(BindableProperty.CoerceValueDelegate) null,
(BindableProperty.CreateDefaultValueDelegate) null);
/// <summary>The ViewModel to display</summary>
public TViewModel ViewModel
{
get => (TViewModel) GetValue(ViewModelProperty);
set => SetValue(ViewModelProperty, (object) value);
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
ViewModel = BindingContext as TViewModel;
}
private static void OnViewModelChanged(BindableObject bindableObject, object oldValue, object newValue)
{
bindableObject.BindingContext = newValue;
}
object IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (TViewModel)value;
}
}
使用
在这里需要继承BasePopupPage
。
public partial class ExtendingPopupPage : BasePopupPage<ExtendingPopupViewModel>
{
public ExtendingPopupPage()
{
InitializeComponent();
}
}
XAML
在XAML中需要确保继承自同一页面,以便子类可以正确解析。看起来像下面这样。
<ui:BasePopupPage
x:TypeArguments="ui:ExtendingPopupViewModel"
xmlns="https://xamarin.com/schemas/2014/forms"
xmlns:x="https://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
xmlns:ui="clr-namespace:MyApplication;assembly=MyApplication"
x:Class="MyApplication.ExtendingPopupPage">
</ui:BasePopupPage>
现在,应该可以完全访问PopupPage
上的ViewModel
属性,并且可以使用响应式绑定和视图激活。
原文 https://www.reactiveui.net/docs/handbook/view-location/extending-iviewfor