2012-04-25 81 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; 
} 

通过这种方式,可以控制调整自各大小改变时本身。