hallo ihr lieben 😉
ich hab mal wieder ein kleines Problem, welches ich unter der suche nicht gefunden habe.
Und zwar ist es so, dass ich eine Art Karte von Webseiten erstellen möchte, wobei die aktuelle Webseite immer in der Mitte der Form angezeigt werden soll. So weit kein Problem. Da Problem kommt jedoch, wenn Webseiten links der aktuellen gezeichnet werden. Dabei gehen diese über die Form hinaus (in den negativen Bereich jenseits von 0 😄) und ich konnte noch keine Möglichkeit finden, welche es mir erlaubt in diesen Bereich zu scrollen. AutoScroll ist natürlich auf true 😉
Ich hab mir schon gedanken darüber gemacht, dann "einfach" alle Pictureboxen entsprechend nach rechts zu verschieben, so dass es passt, nur leider weiß ich nicht, wie ich die aktuelle dann in der Mitte halten soll...
Hier noch ein bisschen Code, wie die Pictureboxen erstellt werden:
for(i = 0; i < brlist.Count; i++)
{
pb.Add(new PictureBox());
map.Controls.Add(pb[i]);
pb[i].Size = new Size(aufx / 7, aufy / 7);
pb[i].SizeMode = PictureBoxSizeMode.StretchImage;
pb[i].Image = image;
if (i < weblist.IndexOf(aktweb))
pb[i].Location = new Point(map.ClientSize.Width / 2 - pb[i].Width / 2 - (weblist.IndexOf(aktbr) - i) * aufx / 6, map.ClientSize.Height / 2 - pb[i].Height / 2);
else if (i > weblist.IndexOf(aktweb))
pb[i].Location = new Point(map.ClientSize.Width / 2 - pb[i].Width / 2 + (i - weblist.IndexOf(aktbr)) * aufx / 6, map.ClientSize.Height / 2 - pb[i].Height / 2);
else
pb[i].Location = new Point(map.ClientSize.Width / 2 - pb[i].Width / 2, map.ClientSize.Height / 2 - pb[i].Height / 2);
}
weblist ist eine Liste mit allen Webseiten,
pb ist eine Liste mit entsprechender Anzahln an Pictureboxen,
map ist meine Form,
aufx ist die Bildschrimauflösung in x Richtung (dementsprechend werden die Pictureboxen proportional angepasst)
aufy ist die Bildschirmauflösung in y Richtung
Bei Fragen einfach melden 😉
Mfg
Gumba
Ach so hier noch ein Bild, welches die Situation beschreibt
Hallo Gumba,
mit Pictureboxen kommst du da nicht weit - zeichne lieber wie in [Tutorial] Zeichnen in Windows-Programmen (Paint/OnPaint, PictureBox) beschrieben in OnPaint (nebenbei geht das so auch deutlich performanter).
Dann kannst du mittels einer TranslateTransform einfach alles verschieben.
Hallo Gumba,
ermittle die kleinste vorkommende Koordinate (also die negative Koordinate, mit dem größten Absolutwert). Addiere diesen Absolutwert auf alle vorkommenden Koordinaten. Anschließend ist die kleinste vorkommende Koordinate 0 und damit sollte wieder alles passen. Wenn sich dadurch die Scrollposition verschiebt, kannst du ja AutoScrollPosition anschließend so setzen, dass wieder alles stimmt.
Das beschreibt nur das Prinzip. Die praktische Umsetzung von winSharp ist vermutlich einfacher.
herbivore
@winSharp93 ich weiß auch nicht warum ich pictureboxen genommen hab, wo ich den rahmen ja schon via graphics zeichne 🤔
@herbivore danke für die herleitung 🙂 damit konnte ich winsharps ansatz optimal umsetzen. 👍
hier noch mal der finale code:
private void map_Paint(object sender, PaintEventArgs e)
{
if (weblist.IndexOf(aktweb) * aufx / 6 + aufx / 14 >= map.ClientSize.Width / 2)
{
int add = weblist.IndexOf(aktweb) * aufx / 6 + aufx / 14 - map.ClientSize.Width / 2;
e.Graphics.TranslateTransform(add, 0);
}
for (i = 0; i < weblist.Count; i++)
{
if (i < weblist.IndexOf(aktweb))
e.Graphics.DrawImage(GenerateScreenshot(weblist[i]),
map.ClientSize.Width / 2 - aufx / 14 - (weblist.IndexOf(aktweb) - i) * aufx / 6,
map.ClientSize.Height / 2 - aufy / 14,
aufx / 7, aufy / 7);
else if (i > weblist.IndexOf(aktweb))
e.Graphics.DrawImage(GenerateScreenshot(weblist[i]),
map.ClientSize.Width / 2 - aufx / 14 + (i - weblist.IndexOf(aktweb)) * aufx / 6,
map.ClientSize.Height / 2 - aufy / 14,
aufx / 7, aufy / 7);
else
e.Graphics.DrawImage(GenerateScreenshot(weblist[i]),
map.ClientSize.Width / 2 - aufx / 14,
map.ClientSize.Height / 2 - aufy / 14,
aufx / 7, aufy / 7);
Pen pen = new Pen(Color.Lime, 5);
e.Graphics.DrawRectangle(pen,
map.ClientSize.Width / 2 - aufx / 14 - 5,
map.ClientSize.Height / 2 - aufy / 14 - 5,
aufx / 7 + 9,
aufy / 7 + 9);
}
}
EDIT.: Nachdem gescrollt wurde sind die Bilder verschwunden.. Sollte es aber nicht so sein, dass per Scroll die Paint-Methode aufgerufen wird? Es passiert auch, dass der Clientbereich plötzlich ein rotes X auf weißem grund zeigt. Ich kann dazu leider kein bild hochladen, dass ein screenshot daon nicht möglich ist. Außerdem kommt es mit teilweise so vor, dass er mit dem Zeichnen beim Scrollen nicht hinterher kommt 🙁
Vielen Dank für eure Hilfe 👍
Mfg
Gumba
Hallo Gumba,
Sollte es aber nicht so sein, dass per Scroll die Paint-Methode aufgerufen wird?
beim Scrollen wird Paint normalerweise nur für den Bereich aufgerufen, der durch das Scrollen neu sichtbar geworden ist. Das ist üblicherweise ausreichend.
Es passiert auch, dass der Clientbereich plötzlich ein rotes X auf weißem grund zeigt.
Das ist normalerweise ein Anzeichen, dass der Paint-EventHandler eine Exception geworfen hat.
herbivore
der code ist vmtl. sehr unperformant, weil alle Bilder in jedem Paint scheinbar neu generiert werden, bevor sie gezeichnet werden.
Dass alle Bilder gezeichnet werden, ist i.O. Denn da das Graphics geclipt ist, nehmen die Zeichnungen von Bereichen ausserhalb des Clips fast keine Zeit in Anspruch.
Aber wie gesagt: dass jedes Bild neu generiert wird...
Der frühe Apfel fängt den Wurm.
ok ich hab jetzt testweise nur ein rechteck zeichnen lassen. das rote X kommt nicht mehr, aber der rahmen ist beim langsamen hin und wieder zurück scrollen nicht zu sehen, beim schnellen scrollen entstehen grafikfehler 🙁
private void map_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(pen, 100, 100, 200, 200);
}
mfg
Gumba
EDIT.: Wenn ich die Form Resize wird das rechteck wie gewünscht gezeichnet. Es scheint also nur beim scrollen probleme zu geben...
EDIT2.: Also manchmal könnt ich mich echt Ohrfeigen 😜 Wenn man die AutoscrollPosition weglässt is klar warums nich gescheit gezeichnet wird 😁
Also mit
e.Graphics.DrawRectangle(Pens.Red, 100 + map.AutoScrollPosition.X, 100 + map.AutoScrollPosition.Y, 200, 200);
klappts jez 👍
Das mit dem Generieren der Screenshots hab ich auf den Aufruf der Form gelegt. Wird also nur noch 1x zu Beginn ausgeführt 😉
Vielen Dank noch mal für eure Hilfe 😁
Mfg
Gumba
Also manchmal könnt ich mich echt Ohrfeigen 😛 Wenn man die AutoscrollPosition weglässt is klar warums nich gescheit gezeichnet wird
Wie gesagt: Wenn du transformierst, brauchst du das nicht explizit einzurechnen.
Kürzlich habe ich ein fremdes Projekt genau um eine solche Autoscroll- (und sogar Zoom-) Funktionalität erweitert.
Der Code findet sich in der ScrollableZoomableControl.cs - man muss nur von dieser ableiten und Measure sowie PaintContent überschreiben und kriegt Scrolling und Zooming ohne weiteren Aufwand (bis, auf dass man in Eventhandlern ClientPointToContent verwenden muss).
Wie gesagt: Wenn du transformierst, brauchst du das nicht explizit einzurechnen.
Tu ich auch nicht und ich benutze ja dein transformieren 😉 Transformiert wird halt lediglich die AutoScrollPosition 😁
Dein Code ist sehr interessant! Der wird mit bestimmt bei etwaigen Zusatzfunktionen hilfreich sein 😁 Sollten Fragen dazu auftauchen, werd ich mich auf jeden Fall noch mal bei dir melden 😉
mfg
Gumba