Share via

FrameworkElement.SizeChanged Event


Occurs when either the ActualHeight or the ActualWidth property changes value on a FrameworkElement.

 virtual event SizeChangedEventHandler ^ SizeChanged;
// Register
event_token SizeChanged(SizeChangedEventHandler const& handler) const;

// Revoke with event_token
void SizeChanged(event_token const* cookie) const;

// Revoke with event_revoker
FrameworkElement::SizeChanged_revoker SizeChanged(auto_revoke_t, SizeChangedEventHandler const& handler) const;
public event SizeChangedEventHandler SizeChanged;
function onSizeChanged(eventArgs) { /* Your code */ }
frameworkElement.addEventListener("sizechanged", onSizeChanged);
frameworkElement.removeEventListener("sizechanged", onSizeChanged);
- or -
frameworkElement.onsizechanged = onSizeChanged;
Public Custom Event SizeChanged As SizeChangedEventHandler 
<frameworkElement SizeChanged="eventhandler"/>

Event Type


SizeChanged fires whenever the size (either ActualHeight or ActualWidth) has changed on the object, which is after the Measure and Arrange passes are complete.

The SizeChangedEventArgs event data for the SizeChanged event provides two properties: the PreviousSize value, representing the size of the element before the layout change happened, and the NewSize value, representing the current size. To get the height and width info use the Height and Width values of the Size structure value for these SizeChangedEventArgs properties within your event handler.

One reason to handle the SizeChanged event is to see whether the ratio of an element's ActualHeight versus ActualWidth have changed, because of a new layout. For example, this might happen if the user has resized the app window and the overall app view is now a narrow view.

SizeChanged occurs during initial layout of elements on a page, when the app first is activated, because the ActualHeight and ActualWidth values for UI elements are undefined before layout happens. They only get values during the initial layout pass and thus the SizeChanged event occurs. Thereafter, during an app's lifetime, the SizeChanged event can fire from an element again if the ActualHeight and ActualWidth values change for other reasons. These include:

  • Code that adjusts the Height and Width of that element specifically.
  • Code that changes the constraint properties (like MinHeight or MaxHeight affecting the ActualHeight).
  • Databinding values refreshed or new styles applied that affect any of the layout-related properties of FrameworkElement.
  • Code that adjusts the dimensions of a container like a Panel or ListBox that is the parent of an element. This often triggers a layout pass. Due to the new layout conditions, a contained child element might now have more or less space available, and that could result in a new ActualHeight and ActualWidth for an element within.
  • Other changes that happen at run-time that change layout space even if they're not directly changing FrameworkElement layout properties. For example, a list that's based on databinding to items might refresh or update, and that could cause size changes in items, items controls, list views, and so on. Or a list view that supports incremental loading might fetch more items and expand the list view.
  • The user changes the app Window size (Window.SizeChanged occurs), which in turn affects the size of the top-level Page and perhaps the adaptive layout-derived sizes of elements within that page that use "Auto" layout or Stretch alignment and didn't specify dimensions.
  • ApplicationView changes or DisplayInformation changes that ultimately affect the window and page dimensions, and potentially all the UI elements within.

It is not strictly necessary to avoid calling other API that influence layout of the current object from within a SizeChanged handler. For example: setting Height or Width; calling InvalidateMeasure or UpdateLayout; calling ApplyTemplate; any operation that might resize child elements and thus invalidate the parent layout. The layout engine has internal logic that stabilizes the values before an object fires the event again, so the logic is usually robust enough to avoid looping conditions. However, it is still possible to inadvertently define sizing or rendering loops that can hang your app, which generally throws exceptions like LayoutCycleException rather than actually hanging. This happens if your handler logic combined with surrounding layout is not capable of reaching an end result for the size of the relevant object.

If the position of the object within a parent container changes, but not the size, SizeChanged won't occur.

LayoutUpdated is a similar event, but LayoutUpdated is also fired for position changes. Also, LayoutUpdated occurrence is not scoped to a specific object's layout properties, it's reporting on the entire visual tree that an object is contained in. LayoutUpdated informs you that something within the overall visual tree that contains the object has changed, but the layout specifics (size, position) of the object where the handler is attached might not have changed.

Although this event uses a RoutedEventHandler-related delegate and a RoutedEventArgs-derived class as event data, the event is not truly a routed event. It doesn't bubble through an object tree. It can be handled only on the element that originates the event (in other words, the sender). OriginalSource in event data for this event is always null, so don't try to use the OriginalSource.

Applies to

See also