Laden...

Mouseover Effekt implementieren

Erstellt von tc5678 vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.677 Views
T
tc5678 Themenstarter:in
38 Beiträge seit 2009
vor 14 Jahren
Mouseover Effekt implementieren

Hallo,
ich wollte mittels des folgenden Codes einen Mouseover Effekt implementieren. Leider funktioniert dies nur mit starken flackern und bei mehreren Buttons erscheint die Fehlermeldung „Out of Memory Exception“. Ich denke, dass es daran liegt, das ich mit „Invalidate();“ alles neugezeichnet wird. Nun bin ich leider auch ein ziemlicher Anfänger und weiß net wie ich es schaffe nur eine bestimmte Region neu zeichnen zu lassen. Ebenso bin ich mir auch net sicher ob dies der richtige Weg ist mein Ziel zu erreichen. Für Hilfe wäre ich wirklich Dankbar!

Code:


static int width = 100;
static int height = 60;

        //bilder werden gezeichnet
        protected override void OnPaint(PaintEventArgs e)
        {
            SetStyle(ControlStyles.OptimizedDoubleBuffer
                   | ControlStyles.AllPaintingInWmPaint
                   | ControlStyles.UserPaint, true);
           
                Image pic = Image.FromFile(@"Pfad");
                
                Graphics g = e.Graphics;
                
                g.DrawImage(pic, 687, 150, width, height);      //Picture
                g.DrawRectangle(Pens.Black, 685, 148, width + 3, height + 3);   //Rahmen
 
                base.OnPaint(e);
           
        }

        private void 1_MouseEnter(object sender, EventArgs e)
        {
            int dx = 5, dy = 5;

            for (int i = 0; i < 5; i++) 
            {
                width4 += dx;
                height4 += dy;
                Invalidate();
                Thread.Sleep(30); 
                
            }
        }
        private void 2_MouseLeave(object sender, EventArgs e)
        {
            int dx = -5, dy = -5;

            for (int i = 0; i < 5; i++) 
            {
                width += dx;
                height += dy;
                Invalidate();
                Thread.Sleep(30); 
	    }
	}

82 Beiträge seit 2009
vor 14 Jahren

Also obs am Invalidate liegt weiß ich nicht, aber du könntest mittels sender.Invalidate() [auch da keine Ahnung, ob das ohne Konvertierung geht ^^] nur das entsprechende Control aktualisieren lassen.

Diskordianer schwimmen nicht gegen den Strom - sie klettern aus dem Fluss! Ein Mathematiker ist ein Mensch, der einen ihm vorgetragenen Gedanken nicht nur sofort versteht, sondern auch weiß auf welchem Denkfehler er beruht
T
tc5678 Themenstarter:in
38 Beiträge seit 2009
vor 14 Jahren

Glaub da brauch ich noch etwas mehr hilfe, dass funktioniert net....

B
67 Beiträge seit 2009
vor 14 Jahren

Reicht es nicht einmal das Bild aus der Datei zu laden ?
In jedem Aufruf von OnPaint erstellst du ein neues Bild.
Möglicherweise füllst du damit den Speicher und es kommt zur angesprochenen Exception.

T
tc5678 Themenstarter:in
38 Beiträge seit 2009
vor 14 Jahren

Hey, dass war eine sehr gute Idee! 😁 Funktioniert jetzt schon viel besser! Mein Problem ist eben, dass ich noch net so richtig verstanden habe, wie der Code überhaupt funktioniert! Der Tipp war aber schon sehr erleuchtend.... Das Flackern ist jetzt auch deutlich weniger! Wenn jemand noch ne Idee hat wie es ganz weggeht, dann wäre das echt super!

F
100 Beiträge seit 2009
vor 14 Jahren

versuchs doch mal mit nem Timer. in etwa so:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1 {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
            _mouseOverTimer = new Timer();
            _mouseOverTimer.Interval = 10;
            _mouseOverTimer.Tick += new EventHandler(_mouseOverTimer_Tick);

        }

        Timer _mouseOverTimer;
        int _deltaSize = 1;
        int _currentSize = 20;

        private void _mouseOverTimer_Tick(object sender, EventArgs e) {
            if ((_currentSize >= 30 && _deltaSize == 1) || (_currentSize <= 10 && _deltaSize == -1)) {
                _mouseOverTimer.Stop();
            }

            _currentSize += _deltaSize;
            this.pictureBox1.Invalidate();
        }

        private void pictureBox1_MouseLeave(object sender, EventArgs e) {
            _mouseOverTimer.Stop();
            _deltaSize = -1;
            _mouseOverTimer.Start();
        }

        private void pictureBox1_MouseEnter(object sender, EventArgs e) {
            _mouseOverTimer.Stop();
            _deltaSize = 1;
            _mouseOverTimer.Start();
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e) {
            e.Graphics.DrawEllipse(Pens.Red, new Rectangle(0, 0, _currentSize, _currentSize));
        }
    }
}
49.485 Beiträge seit 2005
vor 14 Jahren

Hallo tc5678,

Nun bin ich leider auch ein ziemlicher Anfänger und weiß net wie ich es schaffe nur eine bestimmte Region neu zeichnen zu lassen.

bei Invalidate kannst du doch eine Region angeben. Das bekommst man auch als Anfänger aus der :rtfm: Doku raus.

Das Flackern ist jetzt auch deutlich weniger! Wenn jemand noch ne Idee hat wie es ganz weggeht, dann wäre das echt super! [FAQ] Flackernde Controls vermeiden / Schnelles, flackerfreies Zeichnen

herbivore

T
tc5678 Themenstarter:in
38 Beiträge seit 2009
vor 14 Jahren

Hallo fagju,
habe dein Beispiel mal ausprobiert, leider passiert jedoch gar nix. Kann es sein, dass ich noch was zu beachten habe bei der Ausführung? Habe es mal so genommen und reinkopiert. Sind auch so keine Fehler aufgetreten. Es passiert jedoch nix… Im Debug-Modus wird zwar alles ordnungsgemäß durchlaufen und das wars dann…

Hallo herbivore,
habe mir deine links vorher schon mal angeschaut. Mein Problem ist, dass ich noch net ganz damit klar komme ein Bereich zu definieren und diesen anschließend zu übergeben. Allgemein müsste ich doch zuerst ein Rechteck zeichnen und dieses bei Aufruf von Invalidate(hier mein Rechteck); übergeben!? Könntest Du mir mal dies bitte an meinem Beispiel zeigen?? Wäre für den Lernfortschritt wirklich hilfreich…

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo tc5678,

ich verstehe dein Problem ehrlich gesagt nicht. Wie man ein Objekt erzeugt und per Parameter an eine Methode übergibt, setzen wir als bekannt voraus. Oder liegt dein Problem woanders?

Bitte beachte [Hinweis] Wie poste ich richtig? Punkt 1.1.1. und 4b.

herbivore

T
tc5678 Themenstarter:in
38 Beiträge seit 2009
vor 14 Jahren

Mein Problem ist, dass ich hier schon ne ganze Weile an den folgenden Code rumprobiere und immernoch net das Prinzip so richtig verstehe. Es geht weder so


RectangleF Bereich = new RectangleF(55,66,100,100);
                       
            int dx = 5, dy = 5;

            for (int i = 0; i < 5; i++) 
            {
                width4 += dx;
                height4 += dy;
                Invalidate(Bereich);
                Thread.Sleep(5); 
                
            }

noch so


RectangleF Bereich = new RectangleF(55,66,100,100);

            GraphicsPath myPath = new GraphicsPath();
            
            
            int dx = 5, dy = 5;

            for (int i = 0; i < 5; i++) 
            {
                width4 += dx;
                height4 += dy;
                Invalidate(myPath.GetBounds(Bereich));
                Thread.Sleep(5); 
               
            }

und mir fehlt eben das Wissen, welche Methoden ich welche Parameter übergeben kann und welche Schritte ich machen muss, um dann zum Ziel zu kommen. Grundlegend ist mir das schon klar. Jedoch kenne ich mich nicht genug mit den Methoden in dieser Klasse aus und somit ist es nur viel rumprobieren. Leider ist es auch net so einfach, dass was Ihr so gemacht habt hier einzubauen, wenn man die Kniffe net so kennt.
Eure Beispiele die ihr so gemacht habt sind zwar alle ganz schön, wobei sie zum Teil doch etwas komplex sind....

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo tc5678,

siehe [FAQ] Warum blockiert mein GUI?

herbivore

K
133 Beiträge seit 2009
vor 14 Jahren
  
RectangleF Bereich = new RectangleF(55,66,100,100);  
                         
            int dx = 5, dy = 5;  
  
            for (int i = 0; i < 5; i++)   
            {  
                width4 += dx;  
                height4 += dy;  
                Invalidate(Bereich);  
                Thread.Sleep(5);   
                  
            }  
  

Ich frag mich gerade was diese Statements überhaupt bewirken sollen? Für mich sieht das aus als fehlen dir Grundkenntnisse der Programmierung. Ohne dir nahe treten zu wollen würd ich sagen du solltest mal ganz von vorne anfangen und dir ein Handbuch oder ähnliches zulegen!

T
tc5678 Themenstarter:in
38 Beiträge seit 2009
vor 14 Jahren

Habs jetzt rausgefunden was mein Fehler war! Muss statt RectangelF einfach nur Rectangel verwenden und es funzt!! Das soll mal einer wissen....

Ich frag mich gerade was diese Statements überhaupt bewirken sollen? Für mich sieht das aus als fehlen dir Grundkenntnisse der Programmierung. Ohne dir nahe treten zu wollen würd ich sagen du solltest mal ganz von vorne anfangen und dir ein Handbuch oder ähnliches zulegen!

Sorry "Kein Plan" erst lesen und dann schreiben...