Pregunta

Se incluye un pequeño proyecto que demuestra mi problema.tengo un TPageControl alineado con el formulario principal.En cada una de las dos hojas de pestañas tengo paneles alineados por el cliente.En cada uno de esos paneles tengo 2 subpaneles y un divisor.El panel izquierdo y el divisor están alineados a la izquierda, el panel derecho alineado con el cliente.

Básicamente el problema es la interacción entre las 2 pestañas.Demostrar:

  • ejecuta el programa
  • estire la forma principal horizontalmente.El panel 3 crecerá
  • mueva el divisor lo más hacia la derecha posible.El Panel 2 crecerá, el Panel 3 se reducirá hasta su restricción de ancho mínimo de 10 píxeles.
  • seleccione la pestaña 2.El panel 5 es tal como se diseñó, el panel 6 creció cuando se estiró la forma principal
  • reduzca el ancho del formulario principal a su ancho original.El panel 6 se encoge demasiado (indeseable)
  • haga clic en la pestaña 1.La forma principal vuelve a aumentar de ancho (indeseable)

Bien, el comportamiento probablemente se pueda explicar en términos de las reglas de los paneles alineados, pero ¿alguien puede sugerir mejoras en el funcionamiento?

unit Unit17;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, ComCtrls;

type
  TForm17 = class(TForm)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    Panel1: TPanel;
    Panel2: TPanel;
    Splitter1: TSplitter;
    Panel3: TPanel;
    Panel4: TPanel;
    Splitter2: TSplitter;
    Panel5: TPanel;
    Panel6: TPanel;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form17: TForm17;

implementation

{$R *.dfm}

end.


object Form17: TForm17
  Left = 0
  Top = 0
  Caption = 'Form17'
  ClientHeight = 254
  ClientWidth = 314
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object PageControl1: TPageControl
    Left = 0
    Top = 0
    Width = 314
    Height = 254
    ActivePage = TabSheet1
    Align = alClient
    Constraints.MinWidth = 30
    TabOrder = 0
    ExplicitWidth = 480
    object TabSheet1: TTabSheet
      Caption = 'TabSheet1'
      ExplicitWidth = 281
      ExplicitHeight = 165
      object Panel1: TPanel
        Left = 0
        Top = 0
        Width = 306
        Height = 226
        Align = alClient
        Caption = 'Panel1'
        TabOrder = 0
        ExplicitWidth = 109
        ExplicitHeight = 165
        object Splitter1: TSplitter
          Left = 151
          Top = 1
          Width = 12
          Height = 224
          ExplicitLeft = 145
        end
        object Panel2: TPanel
          Left = 1
          Top = 1
          Width = 150
          Height = 224
          Align = alLeft
          Caption = 'Panel2'
          Constraints.MinWidth = 10
          TabOrder = 0
        end
        object Panel3: TPanel
          Left = 163
          Top = 1
          Width = 142
          Height = 224
          Align = alClient
          Caption = 'Panel3'
          Constraints.MinWidth = 10
          TabOrder = 1
          ExplicitLeft = 141
          ExplicitWidth = 330
        end
      end
    end
    object TabSheet2: TTabSheet
      Caption = 'TabSheet2'
      ImageIndex = 1
      ExplicitWidth = 281
      ExplicitHeight = 165
      object Panel4: TPanel
        Left = 0
        Top = 0
        Width = 306
        Height = 226
        Align = alClient
        Caption = 'Panel4'
        TabOrder = 0
        ExplicitWidth = 109
        ExplicitHeight = 165
        object Splitter2: TSplitter
          Left = 149
          Top = 1
          Width = 11
          Height = 224
          ExplicitLeft = 141
        end
        object Panel5: TPanel
          Left = 1
          Top = 1
          Width = 148
          Height = 224
          Align = alLeft
          Caption = 'Panel5'
          Constraints.MinWidth = 10
          TabOrder = 0
        end
        object Panel6: TPanel
          Left = 160
          Top = 1
          Width = 145
          Height = 224
          Align = alClient
          Caption = 'Panel6'
          Constraints.MinWidth = 10
          TabOrder = 1
          ExplicitLeft = 141
          ExplicitWidth = 139
          ExplicitHeight = 163
        end
      end
    end
  end
end 
¿Fue útil?

Solución

Para obtener el comportamiento esperado, elimine las restricciones (MinWidth) de sus paneles.Estas configuraciones están actualmente ineficaz de todos modos, dado que sus divisores tienen un MinSize de '30' (el valor predeterminado, no almacenado).

editar (respuesta al comentario):No se puede esperar que la restricción 'MinWidth' de un control que está en el lado derecho de un divisor ajuste el tamaño del control del lado izquierdo.Eso es lógico, la restricción es una propiedad del control que usted establece.Todo lo que logrará es que el formulario negará la reducción si su control ya está en su 'MinWidth', de ahí el indeseable comportamiento que observa que el formulario se hace más grande cuando cambia de pestaña.Lo que deseas tiene que ver con el código, como dijo Marjan en su respuesta.Debería haber más de una manera de lograr esto, por ejemplo, coloque lo siguiente en el evento 'OnCanResize' del Panel3:

procedure TForm1.Panel3CanResize(Sender: TObject; var NewWidth,
  NewHeight: Integer; var Resize: Boolean);
begin
  if NewWidth < Splitter1.MinSize then
    Panel2.Width := Panel2.Width - Splitter1.MinSize + NewWidth;
end;

Otros consejos

No necesariamente una respuesta real, pero sí un par de comentarios:

  • MinSize para un Splitter alineado a la izquierda pertenece al control a la izquierda y a la derecha del Splitter.De hecho, su Panel 6 cambia de tamaño a (un poco más que) su propio minWidth (10) en lugar del MinSize (30) del divisor.Puede demostrar esto más fácilmente agregando dos paneles alineados a la izquierda en cada uno de sus paneles 2, 3, 5 y 6 y dándoles un ancho de 10 y 20 y un color diferente.

  • Al seleccionar la hoja de pestañas uno nuevamente después de reducir el ancho del formulario principal, el formulario principal crece (¡ay!) Y muestra que ahora Panel3 también se ha reducido a su ancho mínimo en lugar del tamaño mínimo del divisor.

¿La solución al cambio de tamaño del formulario principal?No sé, pero asegurarse de que el ancho mínimo de sus paneles esté sincronizado con el tamaño mínimo de los divisores debería eliminar la contracción.Y como dice Sertac, sospecho que simplemente hay que optar por uno u otro, pero no por ambos...

Actualizar:

  • Establecer el tamaño mínimo de los divisores en 30 y establecer el ancho mínimo de los paneles en 0.Elimina el cambio de tamaño del formulario principal, pero reduce los paneles de la derecha a 0 de ancho.

  • Establecer el tamaño mínimo de los divisores en 30 y el ancho mínimo de los paneles en 30 elimina los problemas de ancho mínimo, pero aún así cambia el tamaño del formulario principal.

  • Configurar el minWidth de los paneles en 30 y establecer el minSize de los divisores en 1 (el mínimo) le permite mover el divisor completamente hacia la derecha y cambiar el tamaño del formulario principal según el minWidth de los paneles cuando suelta el divisor.Evita que Panel6 se reduzca a menos de 30, pero nuevamente el formulario principal cambia de tamaño cuando vuelve a seleccionar la pestaña 1.

Parecería que su mejor opción es confiar en el tamaño mínimo de los divisores y evitar "manualmente" que los paneles del lado derecho se reduzcan demasiado restringiendo el movimiento de los divisores cuando llega al extremo derecho.Puedes hacer esto en el evento OnCanResize de los divisores.

Por cierto, usando D2009

void __fastcall TFMain::SplitterCanResize(TObject *Sender, int &NewSize, bool &Accept)
{
  TSplitter *S = (TSplitter *)Sender;
  for (int i = 0; Accept && i < S->Parent->ControlCount; i++) if (S->Parent->Controls[i]->Constraints->MaxHeight && S->Parent->Controls[i]->Align == S->Align && NewSize >= S->Parent->Controls[i]->Constraints->MaxHeight * 2) Accept = false;
}

Si mientras el formulario era más ancho movió el divisor mucho hacia la derecha y luego redujo el ancho del formulario para que se volviera más estrecho que el panel de la izquierda (y por lo tanto el divisor se encontró "fuera" del formulario), ¿cuál debería ser el comportamiento de su formulario? ser en este caso?Se le ha preguntado sobre sus criterios de comportamiento deseable y todo lo que puedo ver en su respuesta hasta ahora es su comprensión de Naciones Unidascomportamiento deseable.

Ahora me han preocupado un par de veces los posibles efectos secundarios de cambiar el tamaño de un formulario que tiene paneles y divisores.No investigué mucho al respecto y, en particular, nunca antes supe sobre el efecto de cambio de tamaño automático como en sus situaciones.De todos modos, para evitar la mayoría (si no alguno) de los posibles artefactos de comportamiento que consideré usar TScrollBox como control principal para paneles y divisores en lugar de TPanel.

Creo que esto cambiaría el tamaño del formulario para cambiar el tamaño del área de cliente del cuadro de desplazamiento, lo que funcionaría bien para mí en algunos de mis pequeños proyectos en los que usé divisores, si empleara hojas de pestañas como usted.Sin embargo no puedo conocer su caso.Y entiendo que esto es más una solución alternativa a su problema.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top