2016-08-03 17 views
12

Mam problem z zmienianiem rozmiaru wierszy dla formularzy Xamarin, jeśli chodzi o iOS. Mój kod działa jednak doskonale na Androidzie. Gdy zmieniam rozmiar wiersza w systemie iOS, zwiększając rozmiar, wówczas pokrywa się on z poniższym wierszem. Googling to daje mi takie wyniki: http://forums.xamarin.com/discussion/comment/67627/#Comment_67627Automatycznie zmień rozmiar wiersza listy dla iOS w Xamarin Forms

Wyniki twierdzą, że Xamarin Forms nie wdrożyło tego ze względu na problemy z wydajnością. Znajduję tylko wyniki, które mają ponad 1 rok, więc nie wiem, czy to nadal jest powód.

Znajduję wiele różnych sposobów rozwiązania tego problemu w różnych wątkach, które odkryłem, ale wszystkie są dość skomplikowane.

Dla mnie bardzo często w aplikacjach element jest rozszerzany po wyborze. Zastanawiam się, czy ktoś tutaj może zaproponować rozwiązanie, które rozwiąże ten problem? Jeśli to możliwe, bardzo chciałbym uniknąć wielokrotnego przeliczania dokładnych wysokości. Czy powinienem wstrzyknąć niestandardową listę przy użyciu Xamarin.iOS i wtyczki zależności?

Zamieść tutaj mój XAML, ale XAML prawdopodobnie nie jest problemem, ponieważ działa dobrze na Androidzie.

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

Moi pakiety dla projektu formy:

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

Oto mój ViewModel.

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

} 

kodzie:

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

urządzenia:

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

wyślę dwa zdjęcia poniżej z widoku listy. Pierwsze zdjęcie jest bez kliknięcia. Drugie zdjęcie jest po kliknięciu "Two". W komórce pojawia się przycisk, ale komórka zachodzi na komórkę poniżej ("Trzy").

Unclicked

Clicked

+0

W zależności od wersji, której używasz, w komórce znajduje się 'ForceUpdateSize'. Funkcja nie robi nic w mojej wersji, ale inni ludzie mówią, że to działa. – Taekahn

+0

Chciałbym spróbować, ale pozywam XAML całkowicie oddzielony od mojego ViewModel i chciałbym uniknąć bezpośredniego manipulowania GUI. Czy można to uruchomić bez odwoływania się do rzeczywistej listy w C#? –

Odpowiedz

8

Nie jestem pewien, dlaczego SushiHangover nie ma ten sam problem, ale mogę uzyskać te same rezultaty, które możesz zrobić. Domyślnie moje nie zmieniają rozmiaru.

Bez względu na to, czy chcesz skorzystać z jego sugestii na temat aktualizacji produktu, czy też w sposób, w jaki to zrobił, powinno to zmusić komórki do zaktualizowania ich do właściwego rozmiaru.

Zmień swój ViewCell, aby obsługiwać kran.

<ViewCell Tapped="Handle_Tapped"> 

następnie w opóźnieniem kodu dla strony xaml

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

documentation dla ForceUpdateSize() mówi uważać z nim, bo to może być kosztowne, ale czy to na pewno będzie to najmniej ilość wysiłku, aby zrobić to, czego szukasz.

+0

Dzięki! Od pewnego czasu zaczynam kwestionować moje zdrowie psychiczne. To działa idealnie. –

+0

Jak nazwałbyś ForceUpdateSize() z modelu widoku? – Csharpest