Xamarin Forms为ContentPage和CarouselPage共享ControlTemplate

时间:2017-10-13 22:15:20

标签: xamarin xamarin.forms controltemplate controltemplates control-template

我一直试图在ContentPage ...

中为独立的ContentPageCarouselPage重用控制模板

主要问题是CarouselPage不支持ControlTemplate属性。因此,我被迫在ContentPage的{​​{1}}中插入DataTemplate。然后,此CarouselPage可以分配ContentPage,但我遇到的问题是ControlTemplate不是BindingContext的根。

我还会尝试用代码解释问题:

我已经创建了如下所示的模板。

ViewModel

下面显示的<!-- Loader view template --> <ControlTemplate x:Key="LoaderViewTemplate"> <AbsoluteLayout Padding="0" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"> <!-- Content --> <ContentPresenter AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All" /> <!-- Loader --> <BoxView IsVisible="{TemplateBinding BindingContext.IsBusy}" BackgroundColor="Green" Opacity="0.5" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All" /> <StackLayout IsVisible="{TemplateBinding BindingContext.IsBusy}" Padding="6" BackgroundColor="Gray" Orientation="Horizontal" AbsoluteLayout.LayoutBounds="0.5, 0.5, -1, -1" AbsoluteLayout.LayoutFlags="PositionProportional"> <ActivityIndicator Color="White" IsRunning="{TemplateBinding BindingContext.IsBusy}" VerticalOptions="Center" WidthRequest="20" HeightRequest="20" /> <Label TextColor="White" Text="Loading..." VerticalOptions="Center" /> </StackLayout> </AbsoluteLayout> </ControlTemplate> 模板正常

ContentPage

<ContentPage ... ControlTemplate="{StaticResource LoaderViewTemplate}"> <StackLayout HorizontalOptions="Center" VerticalOptions="Center"> ... </StackLayout> </ContentPage> 中的无效,如下所示。

CarouselPage

<CarouselPage ... ItemsSource="{Binding Tournament.Rounds}"> <CarouselPage.ItemTemplate> <DataTemplate> <ContentPage ControlTemplate="{StaticResource LoaderViewTemplate}"> ... </ContentPage> </DataTemplate> </CarouselPage.ItemTemplate> </CarouselPage> 中的BindingContext成为CarouselPage集合中的TournamentRoundModel

是否有人知道如何在独立Tournament.RoundsViewModel嵌套ContentPage内找到CarouselPage的根?

亲切的问候, Jop Middelkamp

2 个答案:

答案 0 :(得分:1)

首先,如果您需要ContentPage中的每个CarousalPage能够引用根视图模型,同时为ControlTemplate的绑定提供相同的内容(一个或多个)。

最简单的方法是扩展ContentPage以支持可绑定属性来保存此引用(到根视图模型)。

public class ExContentPage : ContentPage
{
    public static readonly BindableProperty RootViewModelProperty =
        BindableProperty.Create(
            "RootViewModel", typeof(object), typeof(ExContentPage),
            defaultValue: default(object));

    public object RootViewModel
    {
        get { return (object)GetValue(RootViewModelProperty); }
        set { SetValue(RootViewModelProperty, value); }
    }
}

然后,您可以将共享控制模板更新为:

<!-- Loader view template -->
<ControlTemplate x:Key="LoaderViewTemplate">
    <AbsoluteLayout Padding = "0" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">

        <!-- Content -->
        <ContentPresenter .. />

        < !--Loader-- >
        <BoxView IsVisible= "{TemplateBinding RootViewModel.IsBusy}" BackgroundColor= "Green" .. />

        <StackLayout IsVisible= "{TemplateBinding RootViewModel.IsBusy}" .. >
            <ActivityIndicator Color= "White" IsRunning= "{TemplateBinding RootViewModel.IsBusy}"  />
            <Label TextColor= "White" Text= "Loading..." VerticalOptions= "Center" />
        </StackLayout>
    </AbsoluteLayout>
</ControlTemplate>

示例用法如下:

<local:ExContentPage ...
        xmlns:local="clr-namespace:CustomNamespace"     
        RootViewModel="{Binding}"
         ControlTemplate="{StaticResource LoaderViewTemplate}">

    <StackLayout HorizontalOptions = "Center" VerticalOptions="Center">
        ...
    </StackLayout>
</local:ExContentPage>

<CarouselPage...
             x:Name="Parent" 
             ItemsSource="{Binding Tournament.Rounds}">
    <CarouselPage.ItemTemplate>
        <DataTemplate>
            <local:ExContentPage
                ControlTemplate = "{StaticResource LoaderViewTemplate}"
                RootViewModel="{Binding BindingContext, Source={x:Reference Parent}}">
                ...
            </ContentPage>
        </DataTemplate>
    </CarouselPage.ItemTemplate>
</CarouselPage>

此外,如果IsBusy是您需要在ControlTemplate中引用的唯一属性 - 您可以在扩展内容页面中创建IsBusy可绑定属性;而不是RootViewModel

答案 1 :(得分:0)

如果您正在做任何相关的旋转木马,我建议您使用此nuget包https://github.com/alexrainman/CarouselView而不是默认的轮播页面。