XamlAnimatedGif / WpfAnimatedGif

A simple library to display animated GIF images in WPF, usable in XAML or in code.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Content ActualWidth & Height zero

ChuckSavage opened this issue · comments

I'm using a control called, ZoomAndPanControl - http://www.codeproject.com/Articles/85603/A-WPF-custom-control-for-zooming-and-panning - I added my branch of his work here at GibHub - https://github.com/ChuckSavage/ZoomAndPanControl

The xaml looks like this
ScrollViewer
ZoomAndPanControl
Grid
Image

When I use the Image's Source, ZoomAndPanControl can use its content.ActualWidth & content.ActualHeight

But when I use gif:ImageBehavoir.AnimatedSource content.ActualWidth & content.ActualHeight (https://github.com/ChuckSavage/ZoomAndPanControl/blob/master/ZoomAndPanControl.cs#L522) are zero. Any idea what could be causing this?

Otherwise, this is a really cool libary - thanks for the hard work

It's zero initially, before the animation is loaded; it should change as soon as the control starts showing the images. When are you calling ScaleToFit?

On Image_Loaded

private void imgLarge_Loaded(object sender, RoutedEventArgs e)
{
        Image image = sender as Image;
        ZoomAndPanControl zoom = image.FindVisualParent<ZoomAndPanControl>();
        zoom.ScaleToFit();
        zoom.MinContentScale = zoom.ContentScaleNormal;
}

The problem is that when the Image control's Loaded event is triggered, the image itself might not be loaded yet (depending on various things, e.g. where the image is loaded from). I had added an AnimationLoaded attached event for a similar purpose, but it was on a branch that I eventually abandoned because of too many regressions. I'll see if I can salvage that part and reintroduce it.

@ChuckSavage, I added the event mentioned above; please let me know if it solves your problem

Thank you - yes it works. It doesn't fire on a normal image, but I could still use my old Image_Loaded method.

It doesn't fire on a normal image

It's an oversight; for consistency, it would probably be better to fire it for a non-animated image too. I'll fix it.

Thanks for reporting the issue!

Actually, there seems to be a problem. I had by accident left in my Image.Source binding, when I said it worked. When I removed it, the ActualWidth & ActualHeight in the ScaleToFit method were zero again.

You'd think, this is all I would need:

<Image x:Name="imgLarge"
        RenderOptions.BitmapScalingMode="HighQuality"
        Stretch="None"
        gif:ImageBehavior.AnimatedSource="{Binding Converter={c:ImageConverter}, Path=FullName}"
        Loaded="imgLarge_Loaded"
        gif:ImageBehavior.AnimationLoaded="ImgLarge_AnimationLoaded"
    />

But it turns out I still need the Source=

Source="{Binding Converter={c:ImageConverter}, Path=FullName}"

Oh, I see... that's because the layout of the Image control hasn't been updated yet. Actually, the easiest solution is probably to handle the LayoutUpdated event (which occurs after the layout pass); at this point the ActualWidth and ActualHeight will be set.

So the AnimationLoaded won't help you there eventually... no matter, it will still be useful ;)

Can't use LayoutUpdated because the content hasn't been set for the Zoom control yet.

There has to be something going on, with the Image.Source being set with ImageBehavoir.AnimatedSource being set as well. I don't know WPF well enough to debug it, thanks for your attempts.

I have a hack, and it is working - though I have to call my converter twice, and load the bitmap twice.

OK, another option (that was actually my first idea) is to force the layout pass when the AnimationLoaded event is fired. You can do that by calling Measure and Arrange on the Image control. After that the actual size should be set.

At this point, it is too low level WPF code for me. I'll stick with my hack, and try to figure out a way to use the same BitmapImage for both sources.