用户控制运行时宽度和高度
本文关键字:高度 控制 运行时 用户 | 更新日期: 2023-09-27 18:32:09
我正在尝试在VS2008中创建一个简单的用户控件(不是WPF),它实际上是一个带有Panel1
按钮的SplitContainer
,按下该按钮时,切换Panel2Collapsed
属性并将控件大小调整为Panel1
的大小。
以下是控件的基本内容:
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
是控件在用户控件设计器中的值,而不是在主窗体设计器中的设计时设置的值。
任何帮助将不胜感激。
更新
继 Lucas 的解决方案之后,这种方式意味着_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;
}
您正在构造函数中读取控件的 Height 属性,这意味着它可能在窗体中显示之前。问题是,当控件需要在窗体中显示时,大小似乎会进行调整。在此之前,它是在控件的设计器中设置的值,您现在将获得该值。
解决此问题的最简单方法是在确定控件已经以表单绘制时读取Height
值,即您可以从控件的构造函数中获取open
参数,添加一个初始化Open
和_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;
}
这样,控件可以在每次更改其大小时自行调整。