2

我被困在尝试将控制模板重用于独立的ContentPage以及...ContentPageCarouselPage

主要问题是CarouselPage不支持该ControlTemplate属性。因此,我被迫ContentPageDataTemplate. CarouselPageContentPage然后可以得到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中的变成CarouselPageTournamentRoundModelTournament.Rounds集合中。

有没有人知道我如何才能达到ViewModel独立ContentPageCarouselPage嵌套的根源ContentPage

亲切的问候,乔普·米德尔坎普

4

2 回答 2

1

首先,如果您需要每个ContentPageinCarousalPage能够引用根视图模型,同时为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.

于 2017-10-16T17:55:22.123 回答
0

如果你正在做任何与轮播相关的事情,我建议你使用这个 nuget 包https://github.com/alexrainman/CarouselView而不是默认的轮播页面。

于 2017-10-16T14:08:33.363 回答