Existe-t-il un moyen d'afficher / masquer dynamiquement l'en-tête d'un ListView en fonction d'une condition lors de l'exécution.

<ListView x:Name="ListViewChallenges" Header="{Binding .}">

    <ListView.FooterTemplate>
        <DataTemplate>
            <Label Text="No Elements found." IsVisible="{Binding FooterIsVisible}" />
        </DataTemplate>
    </ListView.FooterTemplate>

    <!-- ... -->

</ListView>

Dans le BindingContext, j'ai déclaré la propriété FooterIsVisible. Lorsqu'il est faux, le pied de page doit être invisible. Cependant, cela ne fonctionne pas, le pied de page consomme toujours un certain espace pour l'étiquette en bas de ListView.

Est-ce possible?

6
Florian 27 janv. 2017 à 16:28

7 réponses

Meilleure réponse

Vous devriez pouvoir masquer le pied de page et ne pas le laisser occuper de l'espace. Je pense que vous devrez définir le HeightRequest pour le libellé dans le FooterTemplate. Vous pouvez le faire en faisant quelque chose comme:

<Label Text="No Elements found." IsVisible="{Binding FooterIsVisible}">
    <Label.Triggers>
        <Trigger TargetType="Label" Property="IsVisible" Value="False">
            <Setter Property="HeightRequest" Value="0" />
        </Trigger>
    </Label.Triggers>
</Label>
7
Eugene Pawlik 27 janv. 2017 à 14:37

Vous pouvez envelopper votre modèle de pied de page dans un ViewCell, puis définir le ViewCell de Height sur 0 lorsque vous ne souhaitez pas qu'il s'affiche. Si vous faites cela, assurez-vous de définir la propriété ListView.HasUnevenRows sur True:

<ListView x:Name="ListViewChallenges" Header="{Binding .}" HasUnevenRows="True">

    <ListView.FooterTemplate>
        <DataTemplate>
            <ViewCell Height={Binding FooterHeight}>
                <Label Text="No Elements found." IsVisible="{Binding FooterIsVisible}" />  
            </ViewCell>
        </DataTemplate>
    </ListView.FooterTemplate>

<!-- ... -->

</ListView>
0
SuavePirate 27 janv. 2017 à 14:37

Voici la solution:

<ListView.FooterTemplate>
  <DataTemplate>

    <!--VIEW-->
    <ActivityIndicator IsRunning="true" IsVisible="{Binding IsLoadingOnDemand}" HorizontalOptions="CenterAndExpand" Margin="15">
      <ActivityIndicator.Triggers>
        <Trigger TargetType="ActivityIndicator" Property="IsVisible" Value="False">
          <Setter Property="HeightRequest" Value="0" />
        </Trigger>
      </ActivityIndicator.Triggers>
    </ActivityIndicator>

  </DataTemplate>
</ListView.FooterTemplate>
0
RaJesh RiJo 29 août 2017 à 16:02

Vous devez utiliser les propriétés de modèle de pied de page et de pied de page. Cela fonctionne comme ItemTemplate et ItemSsource:

<ListView Footer="{Binding IsFooterVisible}">
    <ListView.FooterTemplate>
        <DataTemplate>
            <!-- Footer content. Always visible -->
        </DataTemplate>
    <ListView.FooterTemplate>
</ListView>

Et liez à la propriété Footer quelque chose de nullable (objet par exemple). Ou vous pouvez utiliser un convertisseur pour convertir: true -> new object () et false -> null

Il est également possible de créer une sous-classe de ListView. Mon exemple (la propriété IsLoading est ce que vous recherchez):

Xaml:

<?xml version="1.0" encoding="UTF-8"?>
<ListView xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="Panor.Views.LoadableListView"
    x:Name="element"
    >
    <ListView.FooterTemplate>
        <DataTemplate>
            <ContentView>
                <ActivityIndicator IsRunning="true"
                    Margin="0, 5"
                    Color="{StaticResource mainColor}"
                    VerticalOptions="CenterAndExpand"
                    HorizontalOptions="CenterAndExpand"
                    >
                    <ActivityIndicator.Scale>
                        <OnPlatform x:TypeArguments="x:Double" iOS="2" Android="1" />
                    </ActivityIndicator.Scale>
                </ActivityIndicator>
            </ContentView>            
        </DataTemplate>
    </ListView.FooterTemplate>
</ListView>

Code-derrière:

public partial class LoadableListView : ListView
{
    public LoadableListView()
    {
        InitializeComponent();

        this.ItemAppearing += OnItemAppearing;
    }

    public static readonly BindableProperty IsLoadingProperty = BindableProperty.Create(
        nameof(IsLoading),
        typeof(bool),
        typeof(LoadableListView),
        false,
        propertyChanged: (bindable, oldValue, newValue) => 
        {
            var element = (LoadableListView)bindable;

            element.Footer = (bool)newValue ? new object() : null;
        }
    );
    public bool IsLoading
    {
        set => SetValue(IsLoadingProperty, value);
        get => (bool)GetValue(IsLoadingProperty);
    }

    public static readonly BindableProperty ScrolledDownCommandProperty = BindableProperty.Create(
        nameof(ScrolledDownCommand),
        typeof(ICommand),
        typeof(LoadableListView)
    );
    public ICommand ScrolledDownCommand
    {
        set => SetValue(ScrolledDownCommandProperty, value);
        get => (ICommand)GetValue(ScrolledDownCommandProperty);
    }

    void OnItemAppearing(object sender, ItemVisibilityEventArgs e)
    {
        if (ItemsSource == null) return;
        if (ScrolledDownCommand == null) return;

        object last = null;

        if (ItemsSource is IList)
        {
            var length = (ItemsSource as IList).Count;
            last = (ItemsSource as IList)[length - 1];
        }
        else 
        {
            foreach (var item in ItemsSource)
                last = item;
        }

        if (e.Item == last && ScrolledDownCommand.CanExecute(null))
            ScrolledDownCommand.Execute(null);

    }

Consommant:

 <views:LoadableListView ItemsSource="{Binding ItemSource}"
                RowHeight="120"
                SeparatorColor="#c7c8c9" 
                IsLoading="{Binding IsMoreLoading}"
                ScrolledDownCommand="{Binding ScrolledDownCommand}"
                IsPullToRefreshEnabled="true"
                IsRefreshing="{Binding IsRefreshing}"
                RefreshCommand="{Binding RefreshCommand}"
                >
                <views:LoadableListView.ItemTemplate>
                    <DataTemplate>
                        <cells:MagazinesListCell Name="{Binding Name}" 
                            Publisher="{Binding Publisher}"
                            Price="{Binding Price}"
                            Image="{Binding Converter={StaticResource UriToImageSourceConvertor}, Path=Image}"
                            Commands="{Binding Commands}"
                            />
                    </DataTemplate>
                </views:LoadableListView.ItemTemplate>
            </views:LoadableListView>
1
Artem 17 nov. 2017 à 11:17

J'ai essayé toutes les variantes avec:
1) Header liaison de propriété new object() ou null
2) Deux stacklayouts sans convertisseur (https://stackoverflow.com/a/53197844/7429947)
3) DataTrigger et Trigger lors du changement IsVisible définissent HeightRequest

Cela ne m'aide pas, puis j'ai remplacé MinimumHeightRequest sur 'HeightRequest' et la deuxième variante m'aide pour iOS et Android!

Version de Xamarin.Forms: 4.6.0.726

0
slav4ik51493 12 mai 2020 à 18:34

Cela fonctionne pour moi sans modèle (le modèle ne fonctionnera pas si vous avez besoin de faire référence à des éléments de l'en-tête dans le code .cs parent). Il faut donc avoir des conteneurs avec une hauteur de 0 et non 0 et changer leur visibilité.

  <ListView.Header>
<StackLayout Style="{StaticResource DefaultStackLayout}">
    <StackLayout x:Name="ZeroHeaderContainer"
                 HeightRequest="0"
                 IsVisible="{Binding SomeBooleanField}"/>


    <StackLayout  x:Name="NormalHeaderContainer"
             Style="{StaticResource DefaultStackLayout}"
             HorizontalOptions="Fill" 
             IsVisible="{Binding SomeBooleanField,Converter={StaticResource InverseBooleanConverter}}">
    </StackLayout>
</StackLayout>      
0
Alexander Zuban 7 nov. 2018 à 21:08

Si vous souhaitez masquer le pied de page car la liste est vide, définissez simplement

listview.footer = null
0
Book Of Zeus 3 mars 2019 à 00:47