【问题标题】:Usercontrol runtime width and height用户控件运行时宽度和高度
【发布时间】:2012-05-06 09:14:13
【问题描述】:

我正在尝试在 VS2008 中创建一个简单的用户控件(不是 WPF),它实际上是一个 SplitContainer,在 Panel1 中有一个按钮,当按下该按钮时,会切换 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;
}

【问题讨论】:

  • 我建议的解决方案对您有用吗?
  • 刚刚测试了您的第二个解决方案,稍作修改,它就可以工作了。用我修改后的解决方案更新您的答案是否正确?
  • 只需在您的问题标题中进行 Update 并使用您的答案和一些描述进行更新:)。
  • 我看到你编辑了我的答案,但如果你愿意,我可以放弃它,让你更新问题并根据我的答案描述你自己的版本:)。
  • 好的,拒绝,我会更新这个问题。 :-)

标签: c# visual-studio-2008 .net-3.5 user-controls


【解决方案1】:

您正在它的构造函数中读取控件的 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;
}

这样,控件可以在每次更改大小时自行调整。

【讨论】:

    猜你喜欢
    • 2012-08-11
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    相关资源
    最近更新 更多