3

This seems like a serious bug :

        private void LayoutRoot_Drop(object sender, DragEventArgs e)
        {
            if ((e.Data != null) && (e.Data.GetDataPresent(DataFormats.FileDrop)))
            {
                FileInfo[] files = (FileInfo[])e.Data.GetData(DataFormats.FileDrop);

                using (FileStream fileStream = files[0].OpenRead())
                {
                    //Code reaching this point.
                    BitmapImage bmpImg = new BitmapImage();
                    bmpImg.ImageOpened += new EventHandler<RoutedEventArgs>(bmpImg_ImageOpened);
                    bmpImg.ImageFailed += new EventHandler<ExceptionRoutedEventArgs>(bmpImg_ImageFailed);
                    try
                    {
                        bmpImg.SetSource(fileStream);                        
                    }
                    catch
                    {
                        //Code dosen't reach here.                        
                    }
                }
            }          
        }

        void bmpImg_ImageFailed(object sender, ExceptionRoutedEventArgs e)
        {
            //Code dosen't reach here. 
        }

        void bmpImg_ImageOpened(object sender, RoutedEventArgs e)
        {
            //Code dosen't reach here. 
        }

I am experiencing a very strange behivour. Running this code on my computer, it works - when you drag a JPG on the LayoutRoot I can break inside bmpImg_ImageOpened().

But on a different machine it won't work - when dragging a JPG, I can break in the drop event but after SetSource() nothing happens : no exceptions are thrown, and non of the callbacks are invoked.

I tried it on another machine and it also didn't work.

edit: On all of the machines, when adding an Image class and setting it's Source property to the bitmapImage, the image is shown fine. so I guess it's an issue with the callbacks. This is not enough because I still need those events.

I am banging my head here, what could it be ?

AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
Yaron Levi
  • 12,535
  • 16
  • 69
  • 118
  • Maybe it's a difference between the developer runtime and the end-user runtime? The other machines that you tried - which Silverlight runtime did they have installed? – RobSiklos Sep 15 '11 at 20:18
  • @RobSiklos Silverlight 4.0 , all of them. – Yaron Levi Sep 15 '11 at 21:57
  • Ok, Silverlight 4.0, but there are two different runtimes - developer and end-user. Maybe there's a difference. – RobSiklos Sep 16 '11 at 00:17
  • Another idea - maybe Silverlight behaves differently depending on whether you're accessing the web site using http://localhost vs. using the full hostname. – RobSiklos Sep 16 '11 at 00:17
  • This is from MSDN about ImageOpened : " Occurs when the image source is downloaded and decoded with no failure. ". And the FileStream I use is not downloaded, it's from local file. By the way, I also tried to put an Image and set it's Source property to the BitmapImage, and it works, on all machines. So I guess what's happening is that ImageOpened will be invoked only if at the moment of calling SetSource, the stream was not fully available (Usually happens when the stream is from an Uri, but probably can also happen when it's locally and the specific machine is slow - my case). – Yaron Levi Sep 16 '11 at 09:33

2 Answers2

1

You have to set

bitmapImage.CreateOptions = BitmapCreateOptions.None;

Then the ImageOpened event is fired. This is because the default Options are CreateDelayed

Greetings

Christian http://www.wpftutorial.net

Christian Moser
  • 1,871
  • 20
  • 10
1

This is simply how Silverlight has always behaved. ImageOpened only fires if the image is downloaded and decoded (i.e. using Source). It does not fire when using SetSource. If you need access to the dimensions after loading your image either use WriteableBitmap for the PixelWidth and PixelHeight properties (instead of BitmapImage) or do something like:

img.Source = bmpImg;
Dispatcher.BeginInvoke(() =>
{
   FakeImageOpened(); // Do logic in here
});
David
  • 1,052
  • 1
  • 8
  • 19
  • This worked for me. The FakeImageOpened I have an image in my root visual with opacity="0" and IsHitTestVisible="False" I then set the Image's source to the bitmap and call UpdateLayout on the Image. It works. – shane Jul 13 '13 at 00:31