Skip to content

Instantly share code, notes, and snippets.

@weitzhandler
Last active August 10, 2020 03:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save weitzhandler/96f2cf939e73acb82d3fd676e306fb33 to your computer and use it in GitHub Desktop.
Save weitzhandler/96f2cf939e73acb82d3fd676e306fb33 to your computer and use it in GitHub Desktop.
namespace Xamarin.Forms
{
public class AutoSizeBehavior : Behavior<ListView>
{
ListView _ListView;
protected override void OnAttachedTo(ListView bindable)
{
_ListView = bindable;
bindable.HeightRequest = 0;
bindable.ItemAppearing += AppearanceChanged;
bindable.ItemDisappearing += AppearanceChanged;
}
protected override void OnDetachingFrom(ListView bindable)
{
bindable.ItemAppearing -= AppearanceChanged;
bindable.ItemDisappearing -= AppearanceChanged;
_ListView = null;
}
private void AppearanceChanged(object sender, ItemVisibilityEventArgs e) =>
UpdateHeight(e.Item);
void UpdateHeight(object item)
{
double height;
if (_ListView.HasUnevenRows)
{
if ((height = _ListView.HeightRequest) == (double)VisualElement.HeightRequestProperty.DefaultValue)
height = 0;
height += MeasureRowHeight(item);
}
else
{
height = _ListView.RowHeight;
if (height == (int)ListView.RowHeightProperty.DefaultValue)
_ListView.RowHeight = (int)(height = MeasureRowHeight(item));
}
SetHeight(height);
}
double MeasureRowHeight(object item)
{
var template = _ListView.ItemTemplate;
var cell = (Cell)template.CreateContent();
cell.BindingContext = item;
// TODO: redundant
cell.ForceUpdateSize();
var height = cell.RenderHeight;
var mod = height % 1;
if (mod > 0)
height = height - mod + 1;
return height;
}
void SetHeight(double rowHeight)
{
var height = 0d;
// TODO if header or footer is string etc.
if (_ListView.Header is VisualElement header)
height += header.Height;
if (_ListView.Footer is VisualElement footer)
height += footer.Height;
var tiv = (ITemplatedItemsView<Cell>)_ListView;
height += tiv.TemplatedItems.Count * rowHeight;
_ListView.HeightRequest = height;
}
}
}
@tirathpal
Copy link

why to check for _ListView.HasUnevenRows just do this
void UpdateHeight(object item)
{
double height;
if ((height = _ListView.HeightRequest) == (double)VisualElement.HeightRequestProperty.DefaultValue)
height = 0;
height += MeasureRowHeight(item);
SetHeight(height);
}
it will work fine with number of rows with height set for viewcell

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment