XamarinCommunityToolkit icon indicating copy to clipboard operation
XamarinCommunityToolkit copied to clipboard

[Bug] [Expander] Invoke method ForceUpdateSize on Content MeasureInvalidated

Open FrozDark opened this issue 2 years ago • 7 comments

Seems like expander is caching the last size of content and expanding to that size. But there is no change when content size changed if add some views to layouts like StackLayout, Grid inside an expander

Description

Need to clear cache of last content holder size and force measure of the content on it's measure change

Steps to Reproduce

  1. Create expander with content like grid
  2. Expand the expander
  3. Add views to grid

Expected Behavior

Change the size of expander on content size change

Actual Behavior

Size of expander remains the same as last expansion

Basic Information

  • Version with issue: 1.3.1
  • Last known good version: None

Workaround

Invoke ForceUpdateSize on expander when its content size change

FrozDark avatar Dec 29 '21 22:12 FrozDark

@FrozDark Could you attach a small repro?

pictos avatar Dec 30 '21 01:12 pictos

@pictos Yep ExpanderSizeIssueRepro.zip

FrozDark avatar Dec 30 '21 10:12 FrozDark

@FrozDark hi Yes, this is the limitation of Expander

You should call ForceUpdateSize or ForceUpdateSizeCommand on your own after any content changes.

AndreiMisiukevich avatar Mar 16 '22 04:03 AndreiMisiukevich

For others still experiencing this, the easiest way to do this through MVVM is via the MessagingCenter.

In your View Model:

void EnqueueForceResizeExpanders() => MessagingCenter.Send(this, "ExpanderForceResize");

In your View code-behind (.xaml.cs):

private void ForceResizeExpanders<T>(T _)
{
	foreach (View childView in MyLayoutOfExpanders.Children)
	{
		if (childView is Expander expander && expander.IsExpanded)
		{
			expander.ForceUpdateSize();
		}
	}
}

The method is generic and the sender parameter is discarded because it is irrelevant for this messaging scenario.

In OnAppearing():

MessagingCenter.Subscribe<MyViewModel>(this, "ExpanderForceResize", ForceResizeExpanders);

In OnDisappearing() (clean up to prevent leaking memory through orphaned event subscriptions):

MessagingCenter.Unsubscribe<MyViewModel>(this, "ExpanderForceResize");

If you have only a few Expanders and they are static (not templated as part of a collection) then you can simplify the foreach loop and reference them each directly but the principle remains.

ahoke-cr avatar Apr 19 '22 00:04 ahoke-cr

MyLayoutOfExpanders

What does MyLayoutOfExpanders represents in a CollectionView with an ItemTemplate @ahoke-cr ?

gsgou avatar Aug 12 '22 14:08 gsgou

@gsgou it is any layout view (like a CollectionView) that has children of type Expander (which could come from a DataTemplate).

ahoke-cr avatar Aug 12 '22 14:08 ahoke-cr

@ahoke-cr tks for the quick response. While a Layout has a Children property a CollectionView does not. It does have though ChildAdded() so could be used with a behaviour.

gsgou avatar Aug 12 '22 15:08 gsgou