views:

154

answers:

1

Hello, I am loading an image to my silverlight application. This image will fit in a 3d model as a texture map. I need to fetch image attributes. For that I am using ImageOpened event, like this:

public MainPage()
    {

        BitmapImage img = new BitmapImage(new Uri("imagens/textura.jpg", UriKind.Relative));

        img.ImageOpened += new EventHandler<RoutedEventArgs>(img_ImageOpened);
        img.ImageFailed += new EventHandler<ExceptionRoutedEventArgs>(img_ImageFailed);
        imageBrush.ImageSource = img;

        InitializeComponent();

        this.Loaded += new RoutedEventHandler(MainPage_Loaded);

        this.MouseLeftButtonUp += new MouseButtonEventHandler(MainPage_MouseLeftButtonUp);

(...)

and then:

private void img_ImageOpened(object sender, RoutedEventArgs e)
    {
        BitmapImage i = sender as BitmapImage;
        ImgSize.Width  = i.PixelWidth;
        ImgSize.Height = i.PixelHeight;
        MessageBox.Show("LOADED IMAGE SIZE\n W:" + ImgSize.Width.ToString() + "  H:" + ImgSize.Height.ToString());

    }

The messagebox is showing the correct values for the loaded picture. But this is running after the scene is loaded, so the size is always default (0,0) ... I don't know how to fix this. I've runned the debugger, i've noticed that the scene and the model is rendered and the picture width and height is zero. After this, the event is fired ... I can't figure it out.

Thanks in advance,

Jose'

+1  A: 

First off this is a little confusing:-

    imageBrush.ImageSource = img;

    InitializeComponent();

Unless you have something quite unusual happening the imageBrush object will be null until after the InitializeComponent has run.

As to your question at a guess you load the 3D model in MainPage_Loaded. The problem then is that his happens asynchronously with the arrival of the bitmap. Hence you do not want to actually load the 3D Model until both Loaded and ImageOpened events have both occured. Note it would be dangerous to assume that ImageOpened would always happen last.

The simplest solution I can think of would be to move all your existing code in the MainPage_Loaded event to ImageOpened then move the code that fetches the image to the MainPage_Loaded. This serialises the sequence, when execution of ImageOpened you are guaranteed that the page has loaded.

Not the most sophisticated solution and doesn't make use of benefits of the asynchronous nature of SL. However it should get you going and you can assess whether there is any benefit in having Page loading and bitmap downloading operating in parallel.

AnthonyWJones
I can't do this, because I have many objects which depends from the PageLoaded .. I am using Kit3D plus silverlight.. i have viewports, meshes and stuff ... when i'm pointing imageBrush.ImageSource to img, because i think this does not depends on InitComponent (which is for the UI stuff)
jose
I guess I can't see enough of your code to tell, for example what `MainPage` derives from is unavailable in your current question. Whatever the case you will need to synchronise rendering with the availablity of image info. Its still unclear to me why you can't defer the code currently in PageLoaded to the ImageOpened event.
AnthonyWJones