Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 91519

ListView (iOS not Android) scrolls after item is replaced with another

$
0
0

Trying to work around the problem I fought all last week, I am attempting to make the Forms.ListView be able to handle the replacement of a cell on both iOS and Android. Again, Android works great but iOS doesn't. I've included sample source code (below) and a video to demonstrate the issue.

Description of the program:

Environment:

  • iOS 8.x and 9.x (device or simulator)
  • Xamarin.Forms 1.5.1.6471

Actions:

  • start program on device or simulator
  • scroll down so the header of the second section is at the top of the screen
  • make a selection in the bottom of the second section

Expected behavior:

App will replace the contents of the selected cell with the word "pizza"

Observed behavior:

  • Android: App behaves as expected
  • iOS: App scrolls ListView so that second section's header is in the middle of the screen.
    image

Source code:

using System;
using Xamarin.Forms;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace CellDelete
{
    public class App : Application
    {
        public class Item : BindableObject {
        }

        public class Item<T> : Item {
            public static BindableProperty ValueProperty = BindableProperty.Create ("Value", typeof(T), typeof(Item<T>), default(T));
            public T Value {
                get { return (T)GetValue (ValueProperty); }
                set { SetValue (ValueProperty, value); }
            }
        }

        public class ItemGroup : ObservableCollection<Item> {
            public string Title;
        }

        ObservableCollection<ItemGroup> groups;
        ItemGroup strings, booleans;
        ListView listView;

        public App()
        {
            groups = new ObservableCollection<ItemGroup> ();

            strings = new ItemGroup () { Title = "Strings" };
            for (int i = 0; i < 10; i++)
                strings.Add (new Item<string> () { Value = "strings[" + i + "]"} );
            groups.Add (strings); 


            booleans = new ItemGroup () { Title = "Booleans" };
            for (int i = 0; i < 10; i++)
                booleans.Add (new Item<bool> () { Value = i%2==1 });
            groups.Add (booleans);

            listView = new ListView () {
                ItemsSource = groups,
                ItemTemplate = new DataTemplate (typeof(MyCell)),
                IsGroupingEnabled = true,
                HasUnevenRows = true,
            };
            listView.ItemSelected += OnItemSelected;

            MainPage = new ContentPage () {
                Content = listView,
                Padding = new Thickness(0,20,0,0),
            };
        }

        Item lastItem = new Item<string>() { Value = "pizza" };
        public void OnItemSelected(object sender, SelectedItemChangedEventArgs e) {
            listView.SelectedItem = null;
            var item = e.SelectedItem as Item;
            foreach (ItemGroup group in groups) {
                if (group.Contains (item)) {
                    int index = group.IndexOf (item);
                    var tmpItem = item;
                    group.Remove (item);
                    group.Insert (index, lastItem);
                    System.Diagnostics.Debug.WriteLine ("removed:" + item + " for:" + lastItem);
                    lastItem = tmpItem;
                    return;
                }
            }
        }

        public class HeaderCell : ViewCell {
            public HeaderCell() {
                View = new Label { TextColor = Color.White, BackgroundColor = Color.Blue, HeightRequest=25 };
            }
            protected override void OnBindingContextChanged() {
                base.OnBindingContextChanged ();
                ((Label)View).Text = ((ItemGroup)BindingContext).Title;
            }
        }

        public class MyCell : ViewCell {

            Label _label;
            Switch _switch;
            public MyCell() {
                _label = new Label();
                _label.SetBinding(Label.TextProperty,"Value");
                _switch = new Switch();
                _switch.SetBinding(Switch.IsToggledProperty,"Value");
                View = new StackLayout() {
                    Children = { _label, _switch },
                    Orientation = StackOrientation.Vertical,
                    HeightRequest = 56,
                };
            }

            protected override void OnBindingContextChanged() {
                base.OnBindingContextChanged ();

                View.BindingContext = BindingContext;
                Type type = BindingContext?.GetType ();
                _label.IsVisible = false;
                _switch.IsVisible = false;
                if (type == typeof(Item<string>) )
                    _label.IsVisible = true;
                else if (type == typeof(Item<bool>))
                    _switch.IsVisible = true;
            }
        }
    }
}

Viewing all articles
Browse latest Browse all 91519

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>