2012-04-25 140 views
6

我試圖在VS2008中創建一個簡單的用戶控件(不是WPF),它實際上是一個SplitContainer,它有一個按鈕Panel1,當它按下時,切換Panel2Collapsed屬性並將控件大小調整爲Panel1Usercontrol運行時寬度和高度

這裏有控制的梗概:

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

的問題是,this.Height在運行時是控制在用戶控件設計,而不是什麼被設置在設計時的值主窗體的設計師。

任何幫助將不勝感激。

UPDATE

從盧卡斯的解決方案繼,這種方式意味着,_openHeight只能設置一次,造成了預期的效果:

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

我建議的解決方案是否適合您? – 2012-04-25 18:01:25

+1

剛剛測試過您的第二個解決方案,並且稍作修改即可使用。使用我的修改後的解決方案更新您的答案是否正確? – 2012-04-26 09:17:26

+0

只需在您的問題標題中更新**,然後使用您的答案和一些說明對其進行更新:)。 – 2012-04-26 18:36:52

回答

5

您正在閱讀的控件的Height屬性它是構造函數,這意味着它可能在它在表單中顯示之前。事情是,當控件需要在窗體中顯示時,大小似乎會被調整。在此之前,這是控制器設計器中的一個值,您現在正在設置該值。

解決問題的最簡單的方法是,當你確保控制在形式已經繪製,即你可以得到open參數進行控制的構造函數,添加初始化Open一種新的方法來讀取Height值和_closedHeight並將其稱爲Load事件表單。

事情是這樣的:

public MyUserControl() 
{ 
    InitializeComponent(); 
} 

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

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

然後調用從窗體的Load事件AdjustControlSize方法。

與事件機制

解決方案還可以使用控制自己的事件,在適當的時候讀Height。這樣你就不需要改變Form的代碼。

因此,在這種情況下,代碼可以是這樣的(我沒有測試這個雖然):

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

通過這種方式,可以控制調整自各大小改變時本身。