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);
}
}
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.
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.
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!
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));
}
}
}
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
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…
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
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....
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!
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...