1

Je suis coincé essayer de réutiliser un modèle de contrôle pour une ContentPage indépendante ainsi qu'un ContentPage dans un CarouselPage ...Xamarin formes partagées ControlTemplate pour ContentPage et CarouselPage

Le principal problème est que le CarouselPage ne le fait pas soutenir la propriété ControlTemplate. Par conséquent, je suis obligé d'insérer un ContentPage dans le DataTemplate du CarouselPage. Ce ContentPage puis peut obtenir le ControlTemplate affecté mais je rencontre le problème que le BindingContext n'est pas la racine du ViewModel.

Je vais aussi essayer d'expliquer les problèmes avec le code:

J'AVONS créer le modèle comme indiqué ci-dessous.

<!-- 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> 

Le modèle est fonctionne correctement pour le ContentPage indiqué ci-dessous.

<ContentPage ... 
      ControlTemplate="{StaticResource LoaderViewTemplate}"> 

    <StackLayout HorizontalOptions="Center" VerticalOptions="Center"> 
     ... 
    </StackLayout> 

</ContentPage> 

Mais il ne fonctionne pas dans le CarouselPage comme indiqué ci-dessous.

<CarouselPage ... 
       ItemsSource="{Binding Tournament.Rounds}"> 

    <CarouselPage.ItemTemplate> 
     <DataTemplate> 
      <ContentPage ControlTemplate="{StaticResource LoaderViewTemplate}"> 
       ... 
      </ContentPage> 
     </DataTemplate> 
    </CarouselPage.ItemTemplate> 

</CarouselPage> 

Le BindingContext dans le CarouselPage devient un TournamentRoundModel de la collection Tournament.Rounds.

Est-ce que quelqu'un a une idée sur la façon dont je peux atteindre la racine du ViewModel dans le ContentPage indépendant et le CarouselPage imbriquée ContentPage?

Cordialement, Jop Middelkamp

Répondre

1

Tout d'abord, si vous avez besoin de ContentPage dans CarousalPage pour pouvoir vous référer au modèle de vue racine, tout en fournissant la même chose à la (aux) liaison (s) ControlTemplate.

La manière la plus simple de le faire serait d'étendre ContentPage pour prendre en charge une propriété pouvant être liée pour contenir cette référence (au modèle de vue racine).

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); } 
    } 
} 

Ensuite, vous pouvez mettre à jour votre modèle-contrôle partagé comme:

<!-- 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> 

Exemple d'utilisation ressemblerait à ceci:

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

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

et,

<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> 

De plus, si IsBusy est le o Propriété nly que vous devez faire référence dans ControlTemplate - vous pouvez créer une propriété de liaison IsBusy dans la page de contenu étendue; au lieu de RootViewModel.

+0

Cela a résolu mon problème! Merci G. Sharada! –

0

Si vous faites i carrousel de tout ce qui touche vous suggère d'utiliser ce paquet NuGet https://github.com/alexrainman/CarouselView au lieu de la page carrousel par défaut.

+0

Je viens de passer de CarouselView à CarouselPage parce que le CarouselView est en buggy. Lorsque vous appuyez sur une entrée sur n'importe quelle page, sauf la première, le contrôle CarouselView s'éloigne de la vue active ... Non réalisable et confirmant l'état NuGet avant impression. –