Come posso fare in modo che un pannello scorra a livello di codice per esporre la sua casella PictureSize
-
05-07-2019 - |
Domanda
Ho una casella immagine impostata su AutoSize in modo che l'immagine la costringa a crescere a dimensioni intere dell'immagine.
La finestra dell'immagine si trova in un pannello con autoScroll = true, in modo che le barre di scorrimento vengano visualizzate quando l'immagine è più grande del pannello.
Come posso scorrere programmaticamente il pannello mentre l'utente fa clic sui trascini sull'immagine, riposizionando così l'immagine.
Ho provato a utilizzare l'evento MouseMove, catturando le ultime posizioni X e Y del mouse, calcolando la quantità di movimento del mouse e regolato i valori di Scorrimento verticale e orizzontale del pannello.
Muove l'immagine in giro, ma salta dappertutto e scorre imprevedibilmente.
Come posso raggiungere questo obiettivo?
Ecco cosa ho nei miei eventi del mouse ...
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (dragging)
{
if (e.Button == MouseButtons.Left)
{
// move the image inverse to direction dragged
int horizontalChange = (e.X - startingX) * -1;
int newHorizontalPos = panel1.HorizontalScroll.Value + horizontalChange;
if (newHorizontalPos < panel1.HorizontalScroll.Minimum)
{
newHorizontalPos = panel1.HorizontalScroll.Minimum;
horizontalChange = 0;
}
if (newHorizontalPos > panel1.HorizontalScroll.Maximum)
{
newHorizontalPos = panel1.HorizontalScroll.Maximum;
horizontalChange = 0;
}
panel1.HorizontalScroll.Value = newHorizontalPos;
int verticalChange = (e.Y - startingY);
// move the image inverse to direction dragged
int newverticalPos = panel1.VerticalScroll.Value + verticalChange * -1;
if (newverticalPos < panel1.VerticalScroll.Minimum)
{
newverticalPos = panel1.VerticalScroll.Minimum;
verticalChange = 0;
}
if (newverticalPos > panel1.VerticalScroll.Maximum)
{
newverticalPos = panel1.VerticalScroll.Maximum;
verticalChange = 0;
}
panel1.VerticalScroll.Value = newverticalPos;
}
}
startingX = e.X;
startingY = e.Y;
}
La mia logica è sbagliata o la mia comprensione della funzionalità di scorrimento del pannello è sbagliata?
Soluzione
Credo che il tuo istinto sia corretto, ma l'errore è quello di tentare di regolare le barre di scorrimento anziché spostare PictureBox all'interno del pannello scorrevole.
Dovresti intercettare MouseMove e regolare la proprietà Location di PictureBox con il delta del movimento del mouse & # 8212; le barre di scorrimento dovrebbero aggiornarsi automaticamente per riflettere la nuova posizione dell'immagine al suo interno.
L'aggiornamento del codice sarebbe simile al seguente (non testato):
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (dragging)
{
if (e.Button == MouseButtons.Left)
{
int horizontalChange = (e.X - startingX) * -1; // move the image inverse to direction dragged
int verticalChange = (e.Y - startingY);
pictureBox1.Left += horizontalChange;
pictureBox1.Top += verticalChange;
}
}
startingX = e.X;
startingY = e.Y;
}
(Inoltre, sarei propenso a registrare il mouse iniziale e le posizioni PictureBox all'inizio del trascinamento e aggiornarli relativamente a questa posizione iniziale su ciascun evento MouseMove piuttosto che apportare modifiche incrementali come il codice sopra (e il codice originale ) La ragione di ciò è che se ci sono valori imprevisti, per qualsiasi motivo, ciò causerà solo un effetto transitorio & # 8212; il prossimo evento buono si correggerà da solo.)
Altri suggerimenti
Sta saltando perché l'atto di scorrere il pannello eliminerà la posizione del mouse per la quantità di scorrimento. Puoi ottenere " real " posizione del mouse (relativa dall'angolo in alto a sinistra del pannello) in questo modo:
Point realPos = new Point(e.X + panel1.AutoScrollPosition.X,
e.Y + panel1.AutoScrollPosition.Y);
presupponendo che la proprietà Posizione della finestra immagine sia (0, 0). Il modo migliore per scorrere il pannello è impostare la proprietà AutoScrollPosition.
È possibile impostare il AutoScrollPosition
del pannello nell'evento MouseMove. Testato e funziona bene.
panel1.AutoScrollPosition = new Point(-panel1.AutoScrollPosition.X - e.X + startPoint.X, -panel1.AutoScrollPosition.Y - e.Y + startPoint.Y);