我一直试图在ContentPage
...
ContentPage
和CarouselPage
重用控制模板
主要问题是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.Rounds
和ViewModel
嵌套ContentPage
内找到CarouselPage
的根?
亲切的问候, Jop Middelkamp
答案 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而不是默认的轮播页面。