2012-04-25 11 views
6

Estoy intentando crear un sencillo control de usuario (no WPF) en VS2008 lo que efectivamente es un SplitContainer con un botón en Panel1, que cuando se pulsa, alterna la propiedad Panel2Collapsed y cambia el tamaño de la de control para el tamaño de Panel1.Usercontrol anchura de tiempo de ejecución y la altura

Éstos son el esqueleto de control:

private int _openHeight; 
private int _closedHeight; 

public MyUserControl(bool open) 
{ 
    InitializeComponent(); 

    _openHeight = this.Height; 
    _closedHeight = splitContainer1.SplitterDistance; 
    Open = open; 
}  

private bool _open; 
private bool Open 
{ 
    get { return _open; } 
    set 
    { 
    _open = value; 
    splitContainer1.Panel2Collapsed = !_open; 
    this.Height = _open ? _openHeight : _closedHeight; 
    } 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    Open = !Open; 
} 

El problema es que this.Height en tiempo de ejecución es el valor, que el control está en el diseñador de control del usuario, en lugar de lo que se establece en tiempo de diseño en el diseñador de la forma principal

Cualquier ayuda sería muy apreciada.

ACTUALIZACIÓN

raíz de solución de Lucas, de esta manera significa que el _openHeight sólo se establece una vez, dando como resultado el efecto deseado:

private int? _openHeight; 
private int _closedHeight; 

public MyUserControl(bool open) 
{ 
    InitializeComponent(); 

    //the _closedHeight doesn't change so can be defined in the constructor 
    _closedHeight = splitContainer1.SplitterDistance; 

    //set value 
    Open = open; 

    this.SizeChanged += new EventHandler(MyUserControl_SizeChanged); 
    this.Load += new EventHandler(MyUserControl_Load); 
}  

void MyUserControl_SizeChanged(object sender, EventArgs e) 
{ 
    //this event is called BEFORE the _Load event so gets the height set in the designer 
    // and not any changes at run time (e.g. when you collapse the control) 

    if (_openHeight == null) 
    _openHeight = this.Height; 
} 

private bool _open; 
private bool Open 
{ 
    get { return _open; } 
    set 
    { 
    _open = value; 

    if (_open) 
    { 
     //sets height only if it has been initialized 
     if (_openHeight != null) 
     this.Height = (int)_openHeight; 
    } 
    else 
    { 
     this.Height = (int)_closedHeight; 
    } 
    } 
} 

void MyUserControl_Load(object sender, EventArgs e) 
{ 
    //now that control is loaded, set height 
    Open = Open; 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    Open = !Open; 
} 
+0

¿Te ha funcionado la solución que sugerí? –

+1

Acaba de probar su segunda solución y, con un poco de modificación, funciona. ¿Es una buena práctica actualizar tu respuesta con mi solución modificada? –

+0

Simplemente haga na ** Actualizar ** en su encabezado de pregunta y actualícelo con la respuesta que tiene y alguna descripción :). –

Respuesta

5

Estás leyendo propiedad Height del control de es constructor, lo que significa que probablemente ANTES de que se muestre en el formulario. El problema es que el tamaño parece ajustarse cuando el control debe mostrarse en el formulario. Antes de esto, es un valor establecido en el diseñador del control, que ahora está obteniendo.

La forma más fácil de resolver el problema es leer el valor Height cuando esté seguro de que el control ya se ha elaborado bajo la forma es decir, se puede obtener open parámetro de constructor del control, añadir un nuevo método que inicializa Open y _closedHeight y llámalo en el evento Load del formulario.

Algo como esto:

public MyUserControl() 
{ 
    InitializeComponent(); 
} 

public AdjustControlSize(bool open) 
{ 
    _openHeight = this.Height; 
    _closedHeight = splitContainer1.SplitterDistance; 
    Open = open; 
} 

//the rest of the control's code is unchanged 
... 

luego llamar a AdjustControlSize método del evento de forma Load.

solución con el mecanismo de concurso completo

También puede utilizar propios eventos de control para leer la Height cuando sea apropiado. De esta forma, no tiene que cambiar nada en el código Form.

Por lo tanto, en este caso, el código puede tener este aspecto (no he probado esto, sin embargo):

public MyUserControl(bool open) 
{ 
    InitializeComponent(); 

    _openHeight = this.Height; 
    _closedHeight = splitContainer1.SplitterDistance; 
    Open = open; 
    this.SizeChanged += new EventHandler(MyUserControl_SizeChanged); 
} 

void CustomPictureBox_SizeChanged(object sender, EventArgs e) 
{ 
    _openHeight = this.Height; 
    _closedHeight = splitContainer1.SplitterDistance; 
} 

De esta manera, el control puede auto ajustarse cada vez que se cambia su tamaño.

Cuestiones relacionadas