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.