Grafiken laden lange, trotz in Resources enthalten

i123

Mitglied
Guten Tag,
habe mal wieder ein kleines Problem mit meinem neuem Projekt und da mir hier immer bestens geholfen wird, hoff ich mal das der Thread auch im richtigem Bereich ist.

Habe in meinem Projekt alle Knöpfe / Buttons mit MouseHover versehen, doch wenn man drübergeht, dann braucht er immer 1 sek, oder so bis er das geladen hat ? Stört zwar nicht so sehr, aber würde das trotzdem gerne weghaben...

Die Grafiken sind schon klein, um die 3-4 KB von Photoshop fürs Web konvertiert, und sie sind auch alle im Resources Ordner, also wieso muss er die Grafiken immer wieder neu laden?

Kann man das irgendwie verhindern?

mfg
 

i123

Mitglied
Code:
        private void einzelspieler_MouseHover(object sender, EventArgs e)
        {
            einzelspieler.BackgroundImage = Carcassonne.Properties.Resources.einzelspieler;
            this.Cursor = Cursors.Hand;
            erklaerung.Text = "Spiel gegen den Computer";
        }

        private void einzelspieler_MouseLeave(object sender, EventArgs e)
        {
            einzelspieler.BackgroundImage = Carcassonne.Properties.Resources.einzelspielerohne;
            this.Cursor = Cursors.Default;
            erklaerung.Text = "";
        }

So mache ich das, das mit dem Text ist nun nicht überall, aber die ersten beiden ansich schon...
 

Nico Graichen

Erfahrenes Mitglied
Hi

Das Code wird permanent bei jeder Bewegung der Maus über dem Control ausgeführt.
Probier mal, ob das Problem im MouseEnter-Event auch auftritt
 

Danielku15

Erfahrenes Mitglied
Hallo.
Ich kann Nico nur zustimmen. Das Problem wird daran liegen dass beim MouseHover Event das Control oft neu gezeichnet wird. Am besten auf das MouseEnter Event umändern oder eine zusätzliche Bedingung einbauen ob sich das Hintergrundbild ändern soll. Bspw einen Spezialwert im Tag-Property ablegen und auf diesen Prüfen
C#:
private void einzelspieler_MouseHover(object sender, EventArgs e)
{
    if(einzelspieler.Tag != "MouseOver")
    {    
        einzelspieler.BackgroundImage = Carcassonne.Properties.Resources.einzelspieler;
        this.Cursor = Cursors.Hand;
        erklaerung.Text = "Spiel gegen den Computer";
    }
}

private void einzelspieler_MouseLeave(object sender, EventArgs e)
{
    if(einzelspieler.Tag != "MouseLeave")
    {
        einzelspieler.BackgroundImage = Carcassonne.Properties.Resources.einzelspielerohne;
        this.Cursor = Cursors.Default;
        erklaerung.Text = "";
    }
}

Zum generellen Thema "Geschwindigkeit beim Laden von Resourcen":
Das Laden von Resourcen ist oft mal aufwändiger als gedacht. Ich hatte bei meinem aktuellen Projekt ein ähnliches Problem. (Visualisierung von Noten auf einem Griffbrett). Ich zeichne oft innerhalb von Bruchteilen von Sekunden das Control neu und hatte auch in der Zeichenroutine das Hintergrundbild über die Resources Klasse angegeben. ich musste feststellen dass die Resource oft neu geladen werden muss was enormen Ladeaufwand zur Folge hatte. Um dem Problem Abhilfe zu schaffen lade ich zu Beginn das Bild einmal in eine statische Variable (lazy-loaded-property). Das erhöht zwar den benötigten Speicher des Programms, verringert aber den Aufwand die Ressource jedes mal neu zu laden. Aussehen tut das Ganze ungefähr so:

C#:
private Image _backgroundImage = null;
private Image BackgroundImage {
    get {
        if(_backgroundImage == null) {
            _backgroundImage = Resouces.FretboardBackground;
        }
        return _backgroundImage;
    }   
}

private void PaintFretboard(Graphics g)
{
    g.DrawImage(_backgroundImage,...);
}
 

i123

Mitglied
Ok, vielen dank, das hat soweit geklappt... liegt also daran dass alles zu oft repaintet wird nehme ich an...
Jetzt hab ich allerdings noch das selbe problem bei meiner eigentlichen spielfläche:
Das spiel ist eine art puzzlespiel.
Jedes Puzzleteil wird durch eine Picturebox dargestellt.
Um dem Spieler zu zeigen wo er sein aktuelles Puzzleteil anlegen könnte werden PictureBoxen dorthingelegt wo ein teil sein könnte.
d.h. nach jedem spielzug werden diese temorären markierungen wieder gelöscht und neue erstellt -> massig repaints durch das löschen und hinzufügen von pictureboxen...

Jetzt meine Frage:
Kann ich unterdrücken dass meine form ständig repaintet wird und sie erst manuell repainten wenn alles fertig berechnet ist?
 

Spyke

Premium-User
Ich würde ohne Pictureboxen arbeiten und alles selbst zeichnen.
Die Koordinaten kannst du dir in einer eigenen Rectangle Auflistung merken und über das Graphics Objekt kannst du ja Bilder anzeigen lassen.
Bringt auch weniger Performance probleme (bei größerer Anzahl an Pictureboxen).

Zusatzinfo: Rectanlge besitzt eine Contains Methode mit der du Prüfen kannst ob ein Punkt innerhalb des Rectangles sich befindet.

Musst also nur in deinem Steuerelement welches für das Zeichnen zuständig ist OnPaint überschreiben und die jeweiligen Maus Ereignisse.
 

Neue Beiträge