[RxUI] 16.1 – 扩展View支持

[RxUI] 16.1 – 扩展View支持

扩展IViewFor

有时候,需要将ReactiveUI视图类型的功能进行扩展。答案就在于扩展IViewFor接口,以便ReactiveUI将其拾取并将其注册到ViewLocator实例。一旦实现IViewFor<T>,就可以在类上以扩展方法方式使用绑定。

下面是为各种平台提供的一些ReactiveUI基本实现,这不是详尽列表。

注意:在撰写本文时,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

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注