2012-04-25 12 views
6

Sto cercando di creare un semplice controllo utente (non WPF) in VS2008, che è effettivamente un SplitContainer con un pulsante in Panel1, che se premuto, commuta la proprietà Panel2Collapsed e ridimensiona il controllo delle dimensioni del Panel1.Usercontrol larghezza di runtime e l'altezza

Qui ci sono le ossa nude del controllo:

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; 
} 

Il problema è che this.Height in runtime è il valore che il controllo è nel controllo utente Designer, piuttosto che ciò che è impostato in fase di progettazione in il progettista della forma principale.

Qualsiasi aiuto sarebbe molto apprezzato.

UPDATE

Sulla scia soluzione Lucas', in questo modo significa che il _openHeight è impostata una sola volta, con conseguente effetto desiderato:

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

La soluzione che ho suggerito ha funzionato per voi? –

+1

Appena testato la tua seconda soluzione e, con un po 'di modifica, funziona. È una pratica corretta aggiornare la risposta con la mia soluzione modificata? –

+0

Basta fare ** Aggiornamento ** nella tua intestazione di domanda e aggiornarlo con la risposta che hai e qualche descrizione :). –

risposta

5

Stai leggendo proprietà Height del controllo in è costruttore, il che significa che probabilmente è PRIMA che si mostri nel modulo. Il fatto è che la dimensione sembra essere aggiustata quando il controllo deve essere mostrato nella forma. Prima di questo, è un valore impostato nel designer del controllo, che ora stai ricevendo.

Il modo più semplice per risolvere il problema è quello di leggere il valore Height quando si è sicuri che il controllo è stato già disegnato nella forma ad esempio è possibile ottenere open parametro fuori costruttore del controllo, aggiungere un nuovo metodo che inizializza Open e _closedHeight e chiamarlo nell'evento Load del modulo.

Qualcosa di simile a questo:

public MyUserControl() 
{ 
    InitializeComponent(); 
} 

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

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

quindi chiamare AdjustControlSize metodo dall'evento di forma Load.

Soluzione con meccanismo di gestione degli eventi

È inoltre possibile utilizzare propri eventi del controllo di leggere il Height quando opportuno. In questo modo non devi modificare nulla nel codice di Form.

Quindi, in questo caso, il codice può assomigliare a questo (non ho ancora testato questo però):

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; 
} 

In questo modo il controllo di sé può regolare se stesso ogni volta che la sua dimensione è cambiato.