2016-08-03 14 views
12

Ich habe ein Problem mit der Größenänderung von Zeilen für Xamarin Forms, wenn es um iOS geht. Mein Code funktioniert jedoch perfekt auf Android. Wenn ich die Größe einer Zeile für iOS durch Vergrößerung der Größe ändere, überlappt sie die darunter liegende Zeile. Googling das gibt mir Ergebnisse wie folgt: http://forums.xamarin.com/discussion/comment/67627/#Comment_67627Größe der Listenzeile für iOS in Xamarin-Formularen automatisch ändern

Die Ergebnisse behaupten, dass Xamarin Forms dies aufgrund von Leistungsproblemen nicht implementiert hat. Ich finde nur Ergebnisse, die 1+ Jahre alt sind, also weiß ich nicht, ob das immer noch der Grund ist.

Ich finde eine Reihe von verschiedenen Möglichkeiten, dies in den verschiedenen Threads zu lösen, die ich entdeckt habe, aber alle sind ziemlich kompliziert.

Für mich ist es sehr häufig in Apps, dass ein Element bei der Auswahl erweitert wird. Ich habe mich gefragt, ob hier jemand eine Lösung vorschlagen kann, die das löst? Wenn möglich, möchte ich wirklich vermeiden, exakte Höhen immer wieder neu zu berechnen. Sollte ich eine benutzerdefinierte Liste mit Xamarin.iOS und Abhängigkeitsinjektion injizieren?

Ich poste meine XAML hier, aber die XAML ist wahrscheinlich nicht das Problem, da es auf Android gut funktioniert.

<?xml version="1.0" encoding="UTF-8"?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="simpletest.PlayGroundPage"> 
    <ContentPage.Content> 
     <StackLayout> 
      <ListView VerticalOptions="FillAndExpand" HasUnevenRows="True" SeparatorVisibility="None" ItemsSource="{Binding AllItems}" SelectedItem="{Binding MySelectedItem}"> 
       <ListView.ItemTemplate> 
        <DataTemplate> 
         <ViewCell> 
          <StackLayout VerticalOptions="FillAndExpand"> 
           <Label Text="{Binding MyText}" /> 
           <Button Text="button1" IsVisible="{Binding IsExtraControlsVisible}" /> 
          </StackLayout> 
         </ViewCell> 
        </DataTemplate> 
       </ListView.ItemTemplate> 
      </ListView> 
     </StackLayout> 
    </ContentPage.Content> 
</ContentPage> 

Meine Pakete für das Formen Projekt:

<?xml version="1.0" encoding="utf-8"?> 
<packages> 
    <package id="FreshEssentials" version="2.0.1" targetFramework="portable-net45+win+wp80+MonoTouch10+MonoAndroid10+xamarinmac20+xamarintvos10+xamarinwatchos10+xamarinios10" /> 
    <package id="Xamarin.Forms" version="2.3.1.114" targetFramework="portable-net45+win+wp80+MonoTouch10+MonoAndroid10+xamarinmac20+xamarintvos10+xamarinwatchos10+xamarinios10" /> 
</packages> 

Hier mein Viewmodel ist.

public class PlayGroundViewModel : INotifyPropertyChanged 
{ 

    private Item _mySelectedItem; 
    private ObservableCollection<Item> _allItems; 

    public PlayGroundViewModel(ObservableCollection<Item> allItems) 
    { 
     AllItems = allItems; 
     MySelectedItem = allItems.First(); 

     ItemClicked = (obj) => { ExpandRow(obj); }; 

    } 

    public ObservableCollection<Item> AllItems { get { return _allItems; } set { _allItems = value; SetChangedProperty("AllItems"); } } 

    public Action<Item> ItemClicked { get; private set; } 

    public Item MySelectedItem 
    { 
     get { return _mySelectedItem; } 
     set { _mySelectedItem = value; SetChangedProperty("MySelectedItem"); } 
    } 

    private void ExpandRow(Item item) 
    { 
     foreach (Item x in AllItems) 
     { 
      x.IsExtraControlsVisible = false; 
     } 

     if (item != null) 
     { 
      item.IsExtraControlsVisible = true; 
     } 

     SetChangedProperty("MySelectedItem"); 
     SetChangedProperty("AllItems"); 
    } 

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

} 

Codebehind:

public PlayGroundPage() 
    { 
     InitializeComponent(); 
     ObservableCollection<Item> items = new ObservableCollection<Item>(); 
     items.Add(new Item("One")); 
     items.Add(new Item("Two")); 
     items.Add(new Item("Three")); 

     PlayGroundViewModel viewModel = new PlayGroundViewModel(items); 
     BindingContext = viewModel; 
     Action<Item> itemClickedAction = viewModel.ItemClicked; 
     ItemList.ItemTapped += (object sender, ItemTappedEventArgs e) => 
      { 
       Item item = (Item)e.Item; 
       itemClickedAction.Invoke(item); 
      }; 
    } 
} 

Das Item:

public class Item : INotifyPropertyChanged 
{ 


    public Item(string text) 
    { 
     _myText = text; 
     _isExtraControlsVisible = false; 
    } 

    private string _myText; 
    private bool _isExtraControlsVisible; 

    public event PropertyChangedEventHandler PropertyChanged; 


    public string MyText 
    { 
     get { return _myText; } 
     set { _myText = value; OnPropertyChanged("MyText"); } 
    } 

    public bool IsExtraControlsVisible 
    { 
     get { return _isExtraControlsVisible; } 
     set { _isExtraControlsVisible = value; OnPropertyChanged("IsExtraControlsVisible"); } 
    } 

    private void OnPropertyChanged(string property) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(property)); 
     } 
    } 
} 

ich zwei Bilder unten von einer Listenansicht veröffentlichen werde. Das erste Bild ist ohne zu klicken. Das zweite Bild ist nach dem Klicken auf "Zwei". Eine Schaltfläche erscheint in der Zelle, aber die Zelle überlappt die darunter liegende Zelle ("Drei").

Unclicked

Clicked

+0

Je nachdem, welche Version Sie verwenden, gibt es eine 'ForceUpdateSize' in der Zelle. Die Funktion tut nichts für meine Version, aber andere Leute haben gesagt, dass es funktioniert. – Taekahn

+0

Ich möchte das versuchen, aber ich verklagt XAML vollständig getrennt von meinem ViewModel und möchte vermeiden, die GUI direkt zu manipulieren. Kann dies ausgelöst werden, ohne auf die aktuelle Liste in C# zu verweisen? –

Antwort

8

Ich bin mir nicht sicher, warum SushiHangover nicht das gleiche Problem hat, aber ich bekomme genau die gleichen Ergebnisse, die Sie tun. In der Standardeinstellung ändert sich auch meine Größe nicht.

Unabhängig davon, ob Sie seinen Vorschlag zur Aktualisierung des Elements verwenden oder wie ursprünglich ausgeführt werden, sollte dies Ihre Zellen zwingen, auf die richtige Größe zu aktualisieren.

Ändern Sie Ihre ViewCell, um eine Berührung zu behandeln.

<ViewCell Tapped="Handle_Tapped"> 

dann in der Code-Behind für Ihre XAML-Seite

void Handle_Tapped(object sender, System.EventArgs e) 
{ 
    (sender as ViewCell).ForceUpdateSize(); 
} 

Die documentation für ForceUpdateSize() sagt damit vorsichtig sein, denn es kann teuer sein, aber wenn es wird sicherlich die am wenigsten sein Aufwand, um es zu tun, was Sie suchen.

+0

Vielen Dank !!! Ich habe angefangen, meinen Verstand für eine Weile in Frage zu stellen. Das funktioniert perfekt. –

+0

Wie würden Sie ForceUpdateSize() vom Ansichtsmodell aufrufen? – Csharpest

Verwandte Themen