.net - formularios - resize controls windows forms c#
¿Cómo se puede evitar que un Panel de Winforms se desplace? (5)
Si coloca un DataGridView de 400 píxeles de alto en un panel de 300 píxeles de alto, de modo que haya una barra de desplazamiento en el panel, desplácese hacia abajo para mostrar la mitad inferior de la cuadrícula y luego haga clic en un control fuera del panel , luego haga clic en una línea en la cuadrícula, el panel se desplaza hacia arriba y se selecciona la fila incorrecta en la cuadrícula.
No es solo una DataGridView; sucede con cualquier control que sea más alto que el panel, por ejemplo, Infragistics UltraWinGrid, Rich Text Box. Lo planteé como un error con Infragistics, pero dicen que es un problema de Microsoft.
Intenté usar todos los eventos relevantes para los controles, pero el desplazamiento del Panel ocurre antes de que los eventos se disparen.
¿Alguna sugerencia?
Entiendo tu dolor, esto me ha atrapado más de una vez.
Si su DataGridView es lo único en el panel, simplemente configure el Dock to Fill y deje que el DGV maneje el desplazamiento por sí mismo. No creo que vaya a saltar más. De lo contrario, supongo que podrías simplemente dimensionarlo para que sea menor que el panel y dejarlo hacer el desplazamiento por sí mismo.
Supongo que está configurando la propiedad AutoScroll del panel como verdadera. Cuando lo haga, el cambio de aplicaciones restablece la posición de desplazamiento a cero y el panel restablece su posición.
Si desactivas AutoScroll y añades tu propia barra de desplazamiento, puedes establecer el máximo y el mínimo de la barra de desplazamiento para que coincidan con los requisitos del panel, luego configura los valores de desplazamiento del panel en el evento Scroll de la barra de desplazamiento. Esto no se restablece cuando se cambia de Windows.
Algo como:
private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
{
panel1.VerticalScroll.Value = vScrollBar1.Value;
}
Este fue uno nuevo para mí y tuve que recrearlo. Debería agregar un artículo a mi sitio al respecto :-)
Esto es causado por el evento ScrollToControl que se dispara automáticamente por la clase ScrollableControl, y el controlador de eventos se desplaza para mostrar la parte superior izquierda del control que obtuvo el foco. Este comportamiento no es útil cuando el control de contenedor desplazable solo contiene un control. Estaba muy frustrado por este comportamiento hasta que descubrí cómo detenerlo.
La forma de detener este comportamiento es anular el controlador de eventos ScrollToControl, así:
class PanelNoScrollOnFocus : Panel
{
protected override System.Drawing.Point ScrollToControl(Control activeControl)
{
return DisplayRectangle.Location;
}
}
Reemplace su panel de control con este control de panel. Hecho.
Gracias skypecakes, que funcionó maravillosamente :) Aquí hay una versión editada de tu control que también realiza un seguimiento de dónde están las barras de desplazamiento:
class AutoScrollPanel : Panel
{
public AutoScrollPanel()
{
Enter += PanelNoScrollOnFocus_Enter;
Leave += PanelNoScrollOnFocus_Leave;
}
private System.Drawing.Point scrollLocation;
void PanelNoScrollOnFocus_Enter(object sender, System.EventArgs e)
{
// Set the scroll location back when the control regains focus.
HorizontalScroll.Value = scrollLocation.X;
VerticalScroll.Value = scrollLocation.Y;
}
void PanelNoScrollOnFocus_Leave(object sender, System.EventArgs e)
{
// Remember the scroll location when the control loses focus.
scrollLocation.X = HorizontalScroll.Value;
scrollLocation.Y = VerticalScroll.Value;
}
protected override System.Drawing.Point ScrollToControl(Control activeControl)
{
// When there''s only 1 control in the panel and the user clicks
// on it, .NET tries to scroll to the control. This invariably
// forces the panel to scroll up. This little hack prevents that.
return DisplayRectangle.Location;
}
}
Esto funciona solo si hay un solo control en el panel (aunque no lo he probado con más de un control).
Sí, descubrí que crear la nueva clase de Dock to Fill en el panel detuvo los saltos, por lo que afortunadamente no es necesario recordar y restaurar ScrollLocation al ingresar y abandonar eventos.