dotNed

Welkom bij dotNed Inloggen | Aanmelden | Help
in Zoeken

Dennis' avonturen in .net

WPF: Images laden in code

Stom, stom, stom. Ik ben bezig met een stukje code waarin ik in WPF een image als brush wil gebruiken voor een 3D object. Normaal doe ik dat in de XAML code, maar aangezien het hier om de texture van een trackball gaat, wilde ik het in code zetten.

Normaal doe ik het dus als volgt:

<geo:DrawableGeometry3D GraphicType="Oiltank"                                       
                        Position="1 1 1"
                        Dimension="1.5 1.5 1.5" >
    <geo:DrawableGeometry3D.Material>
        <DiffuseMaterial>
            <DiffuseMaterial.Brush>
                <ImageBrush ImageSource="pack://application:,,,/Images/CheckerBoard.png"/>
            </DiffuseMaterial.Brush>
        </DiffuseMaterial>
    </geo:DrawableGeometry3D.Material>
</geo:DrawableGeometry3D>

Met dit als resultaat:

image

In code lukte het me maar niet. Hoe kon ik nou de material aanmaken met een image? Het antwoord is natuurlijk: op dezelfde manier als in XAML, met een klein verschil. Dit is de code:

    1 DrawableGeometry3D sphere = new DrawableGeometry3D()
    2 {
    3     GraphicType = GraphType3D.Sphere,
    4     Position = new Point3D(0, 0, 0),
    5     Dimension = new Vector3D(2, 2, 2)
    6 };
    7 
    8 _ViewportTrackball.Children.Add(sphere);
    9 _CheckerBoardMaterial = new DiffuseMaterial();
   10 
   11 BitmapImage bmpImage = new BitmapImage();
   12 bmpImage.BeginInit();
   13 bmpImage.UriSource = new Uri("pack://application:,,,/Images/CheckerBoard.png");
   14 bmpImage.EndInit();
   15 
   16 _CheckerBoardMaterial.Brush = new ImageBrush(bmpImage);
   17 
   18 sphere.Material = _CheckerBoardMaterial;

(Hier maak ik een bol, in de XAML code een afgeronde cylinder, maakt voor het verhaal niet uit). Het geheim zat hem in de regels 12 en 14. Je moet BeginInit() en EndInit() aanroepen, anders doet 'ie het niet.

Waarom, vraag je je wellicht af, begin ik deze post nou met "stom, stom, stom"? Het antwoord is simpel.

Ik had de BeginInit() en EndInit() niet staan. Dus ik kreeg exceptions. Dus ik ging debuggen. Dus ik ging zoeken. En niet vinden. Als ik echter 5 seconden de tijd had genomen om de Exception te bestuderen, dan had ik gezien dat er stond:

{"BitmapImage has not been initialized.  Call the BeginInit method, set the appropriate properties, and then call the EndInit method."}

Dat had me een hoop tijd gescheeld.. Zucht. Geleerde les? Lees de foutmelding! Er kan iets nuttigs in staan!

PS Even ter mijn verdediging: bij de meeste fouten in mijn applicatie krijg ik alleen een algemene melding over de XAML die niet geladen kan worden, pas na 5 levels diep in de inner exception te graven kom ik bij de echte exception terecht. Dus ik lees ze amper meer. Niet slim, maar ja..

Published Thursday, March 26, 2009 3:54 PM door dvroegop

Comments

No Comments
Anonymous comments are disabled

About dvroegop

Programmeert al sinds 1982. Is nu werkzaam als software architect bij Detrio Consultancy b.v.
Powered by Community Server, by Telligent Systems