Panel mit Autoscroll
-
Sorry, meinte natürlich
pictureBox1.Location
.
-
pictureBox1.Location ist ebenfalls bei beiden Aufrufen (0,0)
-
Das sollte aber nur so sein, wenn beide Scrollbars ganz links bzw. oben sind.
Ansonsten sollten die Positionen der enthaltenen Child-Elemente immer relativ zur aktuellen ScrollBar-Position sein (also negativ, wenn sie links bzw. oben herausragen).Aber um es kurz zu machen, du mußt bei nachfolgenden Veränderungen von
AutoScrollPosition
immer die aktuelle Position miteinberechnen (quasi auf Null zurücksetzen):Point pos = panel.AutoScrollPosition; Point p = new Point(x, y); panel.AutoScrollPosition = new Point(-pos.X + p.X, -pos.Y + p.Y);
-
Die aktuelle Position mit einzurechnen hat leider auch nicht funktioniert. Aber ich habe jetzt einen Workaround gefunden: Ich schalte einfach bei jedem Aufruf den Autoscroll aus und wieder ein:
using System; using System.Drawing; using System.Windows.Forms; namespace test2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { panel1.AutoScroll = false; panel1.AutoScroll = true; pictureBox1.SizeMode = PictureBoxSizeMode.Normal; pictureBox1.Size = new Size(1280,1024); pictureBox1.Load("test.png"); Point p = new Point(); p.X = (pictureBox1.Size.Width - panel1.ClientRectangle.Width) / 2; p.Y = (pictureBox1.Size.Height - panel1.ClientRectangle.Height) / 2; panel1.AutoScrollPosition = p; } } }
-
Jetzt geht es auch unter Berücksichtigung der aktuellen Position. Man beachte das "+=" bei der Berechnung der Koordinaten.
Vielen Dank für deine Hilfe!
Michaelusing System; using System.Drawing; using System.Windows.Forms; namespace test2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { panel1.AutoScroll = true; pictureBox1.SizeMode = PictureBoxSizeMode.Normal; pictureBox1.Size = new Size(1280,1024); pictureBox1.Load("test.png"); Point p = new Point(); p.X += (pictureBox1.Size.Width - panel1.ClientRectangle.Width) / 2; p.Y += (pictureBox1.Size.Height - panel1.ClientRectangle.Height) / 2; panel1.AutoScrollPosition = p; } } }
-
Das
+=
hat doch gar keinen Effekt, denn derPoint()
-Konstruktor initialisiertX
undY
mit 0 (und0 + x
ist immerx
).PS: Unveränderliche Zuweisungen solltest du möglichst nur einmalig im Konstruktor vornehmen (also die ersten 3 Zeilen im
button1_Click
).
-
@Th69 Du hat Recht, das Beispiel funktioniert nicht. Also irgendie muss man die Ist-Position berücksichtigen. Aber wie das genau gehen soll, das habe ich immer noch nicht rausgefunden.
-
So funktioniert es immer, ausgenommen beim ersten Aufruf:
using System; using System.Drawing; using System.Windows.Forms; namespace test2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); pictureBox1.SizeMode = PictureBoxSizeMode.Normal; pictureBox1.Size = new Size(1280, 1024); pictureBox1.Load("test.png"); panel1.AutoScroll = true; } private void button1_Click(object sender, EventArgs e) { Point p = panel1.AutoScrollPosition; int x = (pictureBox1.Size.Width - panel1.ClientRectangle.Width) / 2; int y = (pictureBox1.Size.Height - panel1.ClientRectangle.Height) / 2; panel1.AutoScrollPosition = new Point(x, y); } } }
-
Und so stehen die Scrollbalken bei allen Aufrufen falsch, ausgenommen beim zweiten Aufruf:
using System; using System.Drawing; using System.Windows.Forms; namespace test2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); pictureBox1.SizeMode = PictureBoxSizeMode.Normal; pictureBox1.Size = new Size(1280, 1024); pictureBox1.Load("test.png"); panel1.AutoScroll = true; } private void button1_Click(object sender, EventArgs e) { Point p = panel1.AutoScrollPosition; int x = (pictureBox1.Size.Width - panel1.ClientRectangle.Width) / 2; int y = (pictureBox1.Size.Height - panel1.ClientRectangle.Height) / 2; panel1.AutoScrollPosition = new Point(-p.X + x, -p.Y + y); } } }
-
Jetzt geht es. Die Ist-Position muss nicht berücksichtigt werden. Wichtig ist dass die Zeile pictureBox1.Location = new Point(0, 0); nicht in button1_Click() drinsteht.
using System; using System.Drawing; using System.Windows.Forms; namespace test2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); pictureBox1.Location = new Point(0, 0); panel1.AutoScroll = true; pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize; } private void button1_Click(object sender, EventArgs e) { pictureBox1.Load("test.png"); Point p = new Point(); p.X = (pictureBox1.Size.Width - panel1.ClientRectangle.Width) / 2; p.Y = (pictureBox1.Size.Height - panel1.ClientRectangle.Height) / 2; panel1.AutoScrollPosition = p; } } }
-
Ich muss doch nochmal fragen, weil da immer noch der Wurm drin ist. Das Zentrieren der Scrollbalken habe ich jetzt in die Funktion center() ausgelagert. Wenn ich diese Funktion von button1_Click() aus aufrufe, dann tut sie jedesmal was sie soll, egal wie oft ich da draufklicke. Aber wenn ich sie vom Konstruktor von Form1() aus aufrufe, dann werden die Scrollbalken nicht zentriert, obwohl center() durchlaufen wird. Wie kann das sein? Hinter InitializeComponent() sollte doch eigentlich alles initialisiert sein.
using System; using System.Drawing; using System.Windows.Forms; namespace test2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); pictureBox1.Location = new Point(0, 0); panel1.AutoScroll = true; pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize; pictureBox1.Size = new Size(1280, 1024); panel1.AutoScrollMinSize = new Size(1280, 1024); center(); // Dieser Aufruf zentriert die Scrollbalken nicht! center(); // Dieser auch nicht! } public void center() { pictureBox1.Load("test.png"); Point p = new Point(); p.X = (pictureBox1.Size.Width - panel1.ClientRectangle.Width) / 2; p.Y = (pictureBox1.Size.Height - panel1.ClientRectangle.Height) / 2; panel1.AutoScrollPosition = p; } private void button1_Click(object sender, EventArgs e) { center(); // Dieser Aufruf zentriert die Scrollbalken } } }
-
Vor
center()
bitteShow()
aufrufen.
-
Danke, jetzt ist das Problem gelöst!
Michael