3 votes

Xamarin Forms - Taille dynamique des ViewCell iOS dans une ListView

L'application XF suivante (code ci-dessous) crée un ListView simple avec 2 cellules personnalisées. En tapant sur une cellule, on utilise la propriété IsVisible pour afficher la deuxième étiquette.

Sur Android, cela fonctionne parfaitement, car la taille de la ViewCell est adaptée au contenu actuellement affiché. Lorsque l'élément Détail est rendu visible, la ViewCell s'agrandit pour afficher le détail.

Sur iOS, cela ne fonctionne pas.

Voici comment l'application apparaît au premier lancement...

enter image description here

Lorsque vous appuyez sur le premier ViewCell, la propriété IsVisible est déclenchée et l'élément Détail s'affiche. Cependant, la ViewCell reste à la même hauteur, ce qui la fait déborder, comme on peut le voir ci-dessous...

enter image description here

Comment cela peut-il être réalisé du côté de l'iOS ?

Voici le code...

XAML

  <ContentPage.Content>
    <ListView x:Name="___list" Margin="50" HasUnevenRows="True">
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <StackLayout>
              <StackLayout.GestureRecognizers>
                <TapGestureRecognizer Command="{Binding CellTap}" />
              </StackLayout.GestureRecognizers>
              <Label Text="{Binding Title}" />
              <Label Text="{Binding Detail}" FontSize="30" IsVisible="{Binding ShowDetails}" />
            </StackLayout>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
  </ContentPage.Content>

C#

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();

        ___list.ItemsSource = new List<Element>() {
                new Element() {
                    Title="First Element",
                    Detail = "First Element Details"
                },
                new Element() {
                    Title="Second Element",
                    Detail = "Second Element Details"
                }
            };
    }
}
public class Element : INotifyPropertyChanged
{
    public Element()
    {
        CellTap = new Command(() =>
        {
            ShowDetails = !ShowDetails;
        });
    }

    public ICommand CellTap { get; private set; }

    private string _title;
    public string Title
    {
        get { return _title; }
        set { if (_title != value) { _title = value; OnPropertyChanged("Title"); } }
    }
    private string _detail;
    public string Detail
    {
        get { return _detail; }
        set { if (_detail != value) { _detail = value; OnPropertyChanged("Detail"); } }
    }
    private bool _showDetails;
    public bool ShowDetails
    {
        get { return _showDetails; }
        set { if (_showDetails != value) { _showDetails = value; OnPropertyChanged("ShowDetails"); } }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

5voto

Krumelur Points 11160

ViewCell ne peut pas savoir automatiquement à quelle hauteur il est censé être. Vous devrez le soutenir en définissant son Height ou le forcer à se mettre à jour. Malheureusement, Height ne peut pas être lié.

Option 1 : Utilisez cette option si vous avez des hauteurs différentes par ligne et que la liste ne peut pas déterminer la hauteur correcte.

class CustomViewCell : ViewCell
{
  protected override void OnBindingContextChanged()
  {
    base.OnBindingContextChanged();
    // Do some calculation in here to get the height you need.
    // Here we are using an example that bases the size on the result of ToString()
    string text = BindingContext.ToString();
    Height = 10 + ((int)(text[0]) - 65);
  } 
}

Option 2 : changer la hauteur dynamiquement (probablement ce que vous voulez)

void SomeEventHandler(object sender, EventArgs args)
{
   // Let's assume an image was tapped...
   var image = sender as Image;
   // ...and the image is in a cell.
   var viewCell = image.Parent.Parent as ViewCell;

   // You would FIRST change the height of the content (in this case the image)
   if (image.HeightRequest < 250)
   {
       image.HeightRequest = image.Height + 100;
       // And THEN tell the cell to update (Note: you should not be required
       // to subclass the cell)
       viewCell.ForceUpdateSize();
   }
}

Assurez-vous que HasUnevenRows = true sinon le fait de forcer la mise à jour n'aura pas d'effet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X