2008-09-24 13 views
10

Estoy escribiendo una aplicación de WinForms y una de las pestañas en mi TabControl tiene un SplitContainer. Estoy guardando SplitterDistance en la configuración de la aplicación del usuario, pero la restauración es inconsistente. Si la página de pestañas con el divisor está visible, entonces la restauración funciona y la distancia del divisor es la que yo dejé. Si se selecciona alguna otra pestaña, entonces la distancia del divisor es incorrecta.Restauración de SplitterDistance dentro de TabControl no es consistente

Respuesta

7

Encontré el problema. No se cambia el tamaño de cada página de pestañas para que coincida con el control de pestañas hasta que se selecciona. Por ejemplo, si el control de pestañas tiene 100 píxeles de ancho en el diseñador y acaba de establecerlo en 500 píxeles durante la carga, la configuración de la distancia del divisor a 50 en una pestaña oculta se redimensionará a una distancia de 250 divisores cuando selecciona esa página de pestañas.

Trabajé alrededor registrando las propiedades SplitterDistance y Width del SplitContainer en la configuración de mi aplicación. Luego, al restaurar, configuré SplitterDistance a recordedSplitterDistance * Width/recordedWidth.

16

Hay una solución más fácil. Si Panel1 se establece como el panel fijo en la propiedad SplitContainer.FixedPanel, todo se comporta como se esperaba.

+0

interesante. Tendré que experimentar con eso. –

+0

+1 Gracias. Establecer FixedPanel fue la solución. –

4

Para el manejo de todos los casos de FixedPanel y orientación, algo como lo siguiente debería funcionar:

 var fullDistance = 
      new Func<SplitContainer, int>(
       c => c.Orientation == 
        Orientation.Horizontal ? c.Size.Height : c.Size.Width); 

     // Store as percentage if FixedPanel.None 
     int distanceToStore = 
      spl.FixedPanel == FixedPanel.Panel1 ? spl.SplitterDistance : 
      spl.FixedPanel == FixedPanel.Panel2 ? fullDistance(spl) - spl.SplitterDistance : 
      (int)(((double)spl.SplitterDistance)/((double)fullDistance(spl))) * 100; 

luego hacer lo mismo cuando se restaura

 // calculate splitter distance with regard to current control size 
     int distanceToRestore = 
      spl.FixedPanel == FixedPanel.Panel1 ? storedDistance: 
      spl.FixedPanel == FixedPanel.Panel2 ? fullDistance(spl) - storedDistance : 
      storedDistance * fullDistance(spl)/100; 
0

Traté de cambiar todo lo que fuera haciendo mi Panel1 la panel estático. SplitContainer.FixedPanel no funcionó para mí. Aunque el panel izquierdo era el Fixed, Panel2 todavía tenía problemas en el lado derecho. Acabé tratando el siguiente ...

El uso de un cuadro de imagen dentro de PANEL2 y haciéndolo Muelle a la matriz (es decir, hice el muelle cuadro de imagen a los padres PANEL2), que parecía ser mi salvación.

Parece que hay un error en el SplitContainer y en la vista de diseño simplemente no pude conseguir que se pegue en el extremo derecho. Cada vez que coloco algo cerca del lado derecho del Panel2, se acercaría mucho al borde o, peor aún, pasaría el área mostrada del Panel2.

0

Restaurar las distancias del divisor también me ha causado mucha pena. He encontrado que restaurarlos desde mi configuración de usuario en el evento de carga de formulario (o control de usuario) dio resultados mucho mejores que usar el constructor. Tratar de hacerlo en el constructor me dio todo tipo de comportamiento extraño.

3

Tuve el mismo problema. En mi caso particular, estaba usando formularios, que transformé en tabulaciones y agregué al control de pestañas. La solución que encontré fue establecer las distancias del divisor en el evento Form_Shown, no en el evento load.

0

La respuesta es sincronizaciones de tiempo. Debe configurar SplitterDistance cuando la ventana finalice con el cambio de tamaño. A continuación, debe marcar para el cambio de tamaño final y luego establecer SplitterDistance. En este caso, está bien

5

Como se mencionó, el control con SplitContainer no cambia de tamaño para que coincida con el control de pestañas hasta que se selecciona. Si maneja la restauración configurando SplitterDistance en porcentaje (storedDistance * fullDistance/100) en el caso de FixedPanel.None, verá que el divisor se está moviendo en algún momento debido a la precisión de los cálculos.

Encontré otra solución para este problema.Me suscribo a uno de los eventos, por ejemplo, Paint event. Este evento viene después del cambio de tamaño del control, por lo que el SplitContainer tendrá el valor correcto. Después de la primera restauración que debe darse de baja de este evento con el fin de restaurar sólo una vez:

private void MainForm_Load(object sender, EventArgs e) 
{ 
    splitContainerControl.Paint += new PaintEventHandler(splitContainerControl_Paint); 
} 

void splitContainerControl_Paint(object sender, PaintEventArgs e) 
{ 
    splitContainerControl.Paint -= splitContainerControl_Paint; 
    // Handle restoration here 
} 
0

Ajuste el que contiene TabPage.Width = TabControl.Width - 8 antes de ajustar el SplitContainer.SplitDistance

2

Guardar la distancia divisor como un porcentaje de la altura del contenedor dividido. Luego restaure el porcentaje de distancia del divisor utilizando la altura actual del contenedor dividido.

/// <summary> 
    /// Gets or sets the relative size of the top and bottom split window panes. 
    /// </summary> 
    [Browsable(false)] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    [UserScopedSetting] 
    [DefaultSettingValue(".5")] 
    public double SplitterDistancePercent 
    { 
    get { return (double)toplevelSplitContainer.SplitterDistance/toplevelSplitContainer.Size.Height; } 
    set { toplevelSplitContainer.SplitterDistance = (int)((double)toplevelSplitContainer.Size.Height * value); } 
    } 
Cuestiones relacionadas