ListView GroupHeader is getting the same height as the ListView rows

xandertanxandertan USMember ✭✭

Is there a way to achieve the ff: list view cache strategy set to recycle (better performance when dealing w a large number of rows), while listview.HasUnevenRows = true and GroupHeaders with heights set to a smaller value than the list view rows ?

The problem appears when I implement a search function on the list view. Once the search function starts filtering the list view item source, the resulting list view row height doesn't follow its original render height.

Extra info:
- I'm using a custom rendered view cell as my list view's data template
- the search-filtered list view rows follow the proper height if I set the list view HasUnevenRows property to false, but for some reason the group header height gets the list view rows' height, which should not happen
- everything works fine if i use ListViewCacheStrategy.RetainElement, but its way too laggy

Creating the list view:
void CreateListView(ListViewCachingStrategy cachestrat = ListViewCachingStrategy.RecycleElement){ listView = new ListView (cachestrat) { VerticalOptions = LayoutOptions.FillAndExpand, BackgroundColor = Color.Transparent, ItemsSource = PreLoadedGroupedList, SeparatorColor = Color.Transparent, ItemTemplate = new DataTemplate(() => { return new ContactViewCell (this); }), IsGroupingEnabled = true, GroupDisplayBinding = new Binding("Key"), HasUnevenRows = true, GroupShortNameBinding = new Binding ("Key"), GroupHeaderTemplate = new DataTemplate (() => { return new HeaderCell (); }), Header = contactsCount, HeaderTemplate = new DataTemplate(() => { return new StackLayout{ Children = { lblContactsCount } }; }), }; if (cachestrat == ListViewCachingStrategy.RecycleElement) { //when HasUnevenRows = false, search-filtered list view rows have correct render heights, but group headers end up the same height as the list view content rows //listView.HasUnevenRows = false; //listView.RowHeight = 70; } ...etc }

ContactViewCell's OnBindingContextChanged method (custom rendered data template) :
`protected override void OnBindingContextChanged ()
{
base.OnBindingContextChanged ();
Debug.WriteLine ("OnBindingContextChanged");

    var item = BindingContext as ContactData;
    if (item != null) {
        nameLabel.Text = item.Name;
        playlistLabel.Text = item.Playlist;
        circleImage.Source = item.PicStringBase64;
        initials.Text = item.Initials;
    }
}`

GroupHeaderTemplate:
public HeaderCell() { this.Height = 20; //works when listview.HasUnevenRows = true, but otherwise it gets the same height as the list view rows during runtime var title = new Label { BackgroundColor = Color.Transparent, FontSize = Device.GetNamedSize (NamedSize.Medium, typeof(Label)), FontAttributes = FontAttributes.Bold, TextColor = Color.Black, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.FillAndExpand, }; title.SetBinding(Label.TextProperty, "Key"); View = new StackLayout { BackgroundColor = Color.FromHex("E9E9E9"), HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.Center, Padding = new Thickness(5, 0), Orientation = StackOrientation.Horizontal, Children = { title } }; this.View.BackgroundColor = Color.White; this.View.Opacity = 0.5; }

Anyone here have the same problem?

Sorry if its confusing. If you need clarification, feel free to comment.

Thanks!

Answers

  • xandertanxandertan USMember ✭✭

    I also came across this thread previously https://forums.xamarin.com/discussion/19573/listview-group-header-issue
    and it does work, but the search-filtered list view rows still have the wrong height.

    Here's my search function if it helps:
    `if (string.IsNullOrWhiteSpace(filter))
    {
    // need to recreate the list view as a simple list rather than a grouped list before searching, so user can search for a specific contact instead of a group of contacts

        ReBuildGroupedSearchableListView(playlist, PreLoadedGroupedList, 
            ListViewCachingStrategy.RecycleElement); 
    
            }
            else {
                listView.BeginRefresh();
    
        //crashes if I don't put these 3 lines
                listView.IsGroupingEnabled = false;
                listView.GroupDisplayBinding = new Binding(".");
                listView.GroupShortNameBinding = new Binding(".");
                listView.GroupHeaderTemplate = null;
    
        listView.ItemsSource = Util.FilterNameNumberOrg(PreloadedList, filter);
    
                listView.EndRefresh();
           }`
    

    And some attachments for visual reference

  • xandertanxandertan USMember ✭✭

    I think the main problem here is that ListView.HasUnevenRows affects the group header heights. After not using a custom renderer for my view cell list view data template, i still get the same result. I found that if I set HasUnevenRows to false when searching the list view, the rows and group header all follow the expected heights. However, the performance takes a hit

    Perhaps this is a bug in Forms?

Sign In or Register to comment.