用户控件的“ResizeEnd”等效事件是什么?

10

我正在编写一个用户控件,希望在调整大小完成后绘制该用户控件。但我找不到与 Windows 窗体中的 "ResizeEnd" 相当的事件。

是否有等效于用户控件的事件?

请注意,在这种情况下,用户控件的父控件本身也是一个用户控件,因此我无法将其(父用户控件)转换为窗体。由于我正在使用框架,因此无法访问将显示该用户控件的窗体。


你解决了你的问题吗?如果是肯定的,你是如何解决的?我也遇到了同样的麻烦,并在这里发布了一个可能的解决方案。 - Marco
2个回答

8

没有相应的功能。一个表单有一个模态大小调整循环,当用户点击表单的边缘或角落时启动。子控件不能以这种方式调整大小,它只能看到其Size属性的更改。

通过为您的用户控件添加Sizing属性来解决此问题。表单可以轻松地从其OnResizeBegin/End()重写中分配它。在UC的Load事件中跟随Parent属性直到找到Form也是可能的:

public bool Resizing { get; set; }

private void UserControl1_Load(object sender, EventArgs e) {
  if (!this.DesignMode) {
    var parent = this.Parent;
    while (!(parent is Form)) parent = parent.Parent;
    var form = parent as Form;
    form.ResizeBegin += (s, ea) => this.Resizing = true;
    form.ResizeEnd += (s, ea) => this.Resizing = false;
  }
}

在我的情况下,父窗体也是一个用户控件。因此,我无法将父控件强制转换为窗体。 - Ram
@Ram:这就是为什么要用while循环的原因。你试过了吗? - Hans Passant
@Hans Passant:这篇文章是在我的帖子这里之后给我的。问题是(使用你的答案)父级在循环期间变为null,导致一切都失败了。即使使用this.FindForm()也会返回null。你有另一个想法吗? - Marco
@Marco - 不要跳过DesignMode测试。在这个Load事件处理程序上设置断点并查看调用堆栈。用户控件可能因对其Handle属性的意外引用而过早创建。 - Hans Passant
@Hans:也许我明白这个问题的原因了。在运行时,当控件被创建时,用户控件(内部控件)会被分配到其父控件(外部用户控件),但此时外部控件的父级尚未设置!!!你觉得我说的对吗? - Marco
显示剩余2条评论

1
汉斯的解决方案可行(看起来这是唯一的方法),但需要在每个使用您的控件的表单中使用这些处理程序(这并不总是可接受的)。
因此,您可以使用简单的解决方法,在调整大小发生时启动计时器。每次更改大小时,计时器都会重新启动。只有当一段时间内没有大小更改(_timer.Interval),它才会调用ResizeFinished()方法。
    private Timer _timer;

    public MyControl() 
    {
        _timer = new Timer();
        _timer.Interval = 500;
        _timer.Tick += (sender, e) => ResizeFinished();
    }

    protected override void OnSizeChanged(EventArgs e)
    {
        base.OnSizeChanged(e);
        _timer.Start();
    }

    private void ResizeFinished()
    {
        _timer.Stop();
        // Your code
    }

正如您所看到的,只有在最后一次大小更改调用之后500毫秒才会调用您的代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接