2

I am writing an app using Xamarin Forms XAML, and I need a way to redraw the view.

I have a layout containing multiple Labels and a ListView. I also have a button that when pressed calls an API to download a new set of data which needs to update the controls on the page.

All of my controls are bound correctly so when the data updates in the background, the data does update on the view but the controls are not redrawn and therefore messes up the look of the layout.

Sometimes the data in my ListView can be only 1 or 2 rows but usually will be a lot more. The 1st time the page is drawn, everything looks fine but my problem is when updating the view with data that has a different number of rows in the ListView as the controls do not resize.

Example:

When 1st entering the screen I download data and the ListView has 10 items and so draws 10 rows on the screen

When I press the "Reload Data" button, the data downloaded might now only contain 2 items. The data is updated correctly but the spacing on the screen is still the same size as when 1st drawn (with the 10 items), so I now have a large blank space.

If the opposite of this example is done (1st entry is 2 items, 2nd entry is 10 items), then the space for the ListView is still only 2 items high and therefore you can only see 2 of the 10 items.

What I want to be able to do, is to refresh the controls somehow when downloading new data so that the size of the ListView is redrawn and is always the correct size for the amount of items being displayed.

plingingo
  • 121
  • 2
  • 13
  • Are you making sure that these updates happen on the UI Thread? – Cheesebaron Aug 28 '18 at 09:56
  • @Cheesebaron How do I check that? All know is that if I put a break point in my ViewModel I see my bound controls get updated and then when I actually test the code the data displayed does reflect what has been downloaded. The problem is purely to do with the size of the controls. The 1st entry always works correct but whenever a new set of data with a different amount of items is downloaded then the controls don't resize. – plingingo Aug 28 '18 at 10:02
  • Check `Thread.CurrentThread.ManagedThreadId` if it is anything than 1 then it is not UI Thread usually. If you are doing stuff async, you can control the behavior with `ConfigureAwait` on the awaited task. You need to post a bit more code for us to better help you what to do here. – Cheesebaron Aug 28 '18 at 10:59
  • It'd be helpful to see your code and XAML, or at least a [mcve]. – Paul Kertscher Aug 28 '18 at 11:34
  • If you will not use HasUnEvenRows of ListView, that means you have Fixed size Row Height for all of the ListView ViewCells. You can manipulate the total height of the ListView in your ViewModel based on the Total Items you can multiply that Total height and bind the Height of the ListView. – N Subedi Aug 28 '18 at 14:16

1 Answers1

1

Had the same issue. I think you are approaching it wrong. ListView doesn't work the way you think it does. It's not designed to always fit just perfectly for it's content. If you want that, you need to calculate the height by yourself and set it to the ListView.

One approach is to change the height of your ListView. You can achieve that by binding a property to HeightRequest:

<ListView
  HeightRequest="{Binding ListViewHeight}">
</ListView>

This is my calculation for ListViewHeight. RowHeight is 72 for Android and 75 for iOS. It's a dirty solution because of hard coded values for height, but it's the best solution I found for the problem. Keep in mind that you need to adjust these values to fit your needs, otherwise your ListView might be too small/tall.

public double ListViewHeight
{
    get
    {
        if (MyItemsList!= null)
        {
            double listViewHeight = MyItemsList.Count * RowHeight;
            if (CanLoadMoreNotifications)
            {
                listViewHeight += RowHeight;
            }
            return listViewHeight;
        }
        return 0;
    }
}

Now every time you're making changes to you list, call RaisePropertyChanged("ListViewHeight");. This way, your ListView height is calculated and your UI updates.

Dennis Schröer
  • 2,392
  • 16
  • 46
  • Great "dirty" solution. The ListView, as a lot of things with Xamarin Forms, doesn't work perfectly and is not calculating the right height when you load the elements dynamically. Unbelievable! Thanks a lot for this! – juangalf May 21 '20 at 23:27
  • @juangalf I haven't looked into it a lot yet, but maybe Xamarin's new `CollectionView` solves those issues – Dennis Schröer May 26 '20 at 08:12