Harsha
Harsha

Reputation: 1879

WPF - Image Control Actual Size

I have a problem in getting ActualHeight and ActualWidth of image control in WPF. When user selects the image file, I want to resize the selected image based on the dimensions of the image control.

I tried to get the Image.ActualHeight and Image.ActualWidth when window initializes, but I found that both properties of Image control are '0'.

So how to get the dimensions of the image control.

Upvotes: 3

Views: 5798

Answers (4)

soren.enemaerke
soren.enemaerke

Reputation: 4830

Off the top of my head, I think you should subscribe to the Load event on the image control, the ActualHeight/Width are not updated until that event fires.

Upvotes: 2

osMike
osMike

Reputation: 107

The Best solution I have found is to wait until after the Image has loaded.

Private Sub Update_imgImage(tURI As Uri)
    imgImage.LayoutTransform = New ScaleTransform(scaleX:=1, scaleY:=1)
    Dim src As BitmapImage = New BitmapImage()
    src.BeginInit()
    src.UriSource = tURI
    src.CacheOption = BitmapCacheOption.OnLoad
    src.EndInit()
    imgImage.SetCurrentValue(Image.SourceProperty, src)
    AddHandler src.DownloadCompleted, AddressOf ImageDownloadCompleted
End Sub

Then for ImageDownloadCompleted i have the following:

Sub ImageDownloadCompleted(sender As Object, e As System.EventArgs)
    Dim src As BitmapImage
    src = DirectCast(sender, BitmapImage)
    Dim scaleXY As Double
    If sender.Width = 0 Then Exit Sub
    'default width is 600 for my item, if changed, then resize
    If sender.Width <> 600 Then
        scaleXY = 500 / sender.Width
        imgImage.LayoutTransform = New ScaleTransform(scaleX:=scaleXY, scaleY:=scaleXY)
    Else
        imgImage.LayoutTransform = New ScaleTransform(scaleX:=1, scaleY:=1)
    End If
    RemoveHandler src.DownloadCompleted, AddressOf ImageDownloadCompleted
End Sub

I hope this works for you.

Upvotes: 0

Ed Noepel
Ed Noepel

Reputation: 442

The control's ActualSize is set after the "Measure" layout pass (the "Arrange" layout pass sets its location). The other two answers are helpful; the "Arrange" layout pass of the container only happens after its children have been measured, and the load handler of your image control should be called after its first layout pass has completed.

Upvotes: 0

andyp
andyp

Reputation: 6269

the remarks for FrameworkElement.ActualHeight say that there might be some lag before the property has its real value.

This property is a calculated value based on other height inputs, and the layout system. The value is set by the layout system itself, based on an actual rendering pass, and may therefore lag slightly behind the set value of properties such as Height that are the basis of the input change.

The final size of your control is set by FrameworkElement.Arrange(-Override). You could override the method and just call the base class implementation. Its return value will be the actual size of your Image.

Upvotes: 2

Related Questions