user3386180
user3386180

Reputation:

Getting ActualWidth in Windows Phone8.1

I'd like to get the actual width of an image in my WP8.1 app. The width cannot be determined (i.e. is zero) until the page has been rendered, and other solutions suggest handling this in the page loaded event as in the basic example below. But even here, img.ActualWidth is zero.

How can I retrieve img.ActualWidth once as soon as the page is rendered?

public sealed partial class MainPage : Page {

    public MainPage() {
        this.InitializeComponent();
        this.NavigationCacheMode = NavigationCacheMode.Required;
        this.Loaded += MainPage_Loaded;
    }

    private void MainPage_Loaded(object sender, RoutedEventArgs e) {
        Debug.WriteLine(img.ActualWidth);
    }
}

and

<Page
    x:Class="Page_Loaded.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Page_Loaded"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <Image x:Name="img" Source="/image.jpg" />
    </Grid>
</Page>

Upvotes: 0

Views: 136

Answers (1)

Utsav Dawn
Utsav Dawn

Reputation: 8256

Use SizeChanged event handler. It occurs when either the ActualHeight or the ActualWidth property changes value on a FrameworkElement.

ActualWidth is a calculated property. The calculations are a result of a layout pass, where the object is sized in layout according to the logic of its successive layout parents.

The default of ActualWidth is 0. The default might be encountered if the object has not been loaded and hasn't yet been involved in a layout pass that renders the UI. (This is happening in your case)

ActualWidth can have multiple or incremental reported changes to the value because of operations by the layout system. If you get the value while layout is still iterating, the layout system might still be calculating the required measure of space for child objects, constraints by the parent object, and so on. Because the value is based on an actual rendering pass, it may lag slightly behind the set value of properties like Width, which can be the basis of the input change.

For purposes of ElementName binding, ActualWidth does not post updates when it changes (due to its asynchronous and run-time calculated nature). Do not attempt to use ActualWidth as a binding source for an ElementName binding. If you have a scenario that requires updates based on ActualWidth, use a SizeChanged handler.

SizeChanged fires whenever the size (either ActualHeight or ActualWidth) has changed on the object, which is after the Measure and Arrange passes are complete. 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.

Upvotes: 1

Related Questions