2017-01-27 1 views
1

Gibt es eine Möglichkeit, die Kopfzeile eines ListView auf der Grundlage einer Bedingung zur Laufzeit dynamisch ein-/auszublenden.Kopf- oder Fußzeile von Xamarin.Forms.ListView dynamisch ein-/ausblenden

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

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

    <!-- ... --> 

</ListView> 

Im BindingContext habe ich die FooterIsVisible-Eigenschaft deklariert. Wenn es falsch ist, sollte die Fußzeile unsichtbar sein. Dies funktioniert jedoch nicht, da die Fußzeile immer einen bestimmten Platz für das Label am unteren Ende des ListViews verbraucht.

Ist das irgendwie möglich?

Antwort

5

Sie können die Fußzeile verstecken und es keinen Platz verbrauchen. Ich glaube, Sie müssen die HeightRequest für das Etikett in der FooterTemplate setzen. Sie können das tun, indem Sie etwas zu tun, wie:

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

Ich habe HeightRequest zuvor versucht, aber es tut es nicht Arbeit. Die Fußzeile ignoriert sie und verbraucht immer noch diesen Speicherplatz, selbst wenn ForceLayout auf dem übergeordneten ContentView ausgelöst wird. – Florian

+0

Arbeiten Sie mit iOS, Android oder etwas anderem? Ich habe gerade einen kurzen Test mit diesem Code auf Android durchgeführt, der die 'FooterIsVisible' ein- und ausschaltet und es scheint so weit zu funktionieren, wie ich das Problem verstehe. Ich habe im Moment keinen Zugriff auf meinen Mac, also kann ich es nicht auf iOS anschauen. –

+0

Vielen Dank für die Überprüfung. Ich habe es erneut auf iOS und Android versucht und du bist richtig für Android. Da funktioniert es, das Problem besteht also nur auf iOS. Sobald die Fußzeile sichtbar ist, bleibt sie übrig, um den gleichen Platz zu verbrauchen, selbst wenn sie unsichtbar ist. Das könnte ein Fehler sein. Ich habe den Eindruck, dass Xamarin nicht wirklich auf "kleinere" Probleme reagiert - also muss ich wohl damit leben. – Florian

0

Sie können Ihre Fußzeilenvorlage in eine und dann die ViewCellHeight auf 0, wenn Sie nicht möchten, dass es angezeigt wird. Wenn Sie dies tun, stellen Sie sicher, dass die ListView.HasUnevenRows Eigenschaft auf True einzustellen: sollte

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

Wenn ein ViewCell ich mit bekommen System.ArgumentException: Wert war ein ungültiger Wert für FooterTemplate – Florian

0

Hier ist die Lösung:

<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

Sie sollten FooterTemplate und Footer-Eigenschaften verwenden. Es funktioniert als ItemTemplate und ItemSource:

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

Und binden an Footer-Eigenschaft etwas Nullable (Objekt zum Beispiel). Oder Sie konvertieren Converter: true -> new object() und false -> null

Es ist auch möglich, eine Unterklasse von ListView zu erstellen. Mein Beispiel (IsLoading Eigenschaft ist das, was Sie suchen):

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

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

    } 

Konsumieren:

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