一种监视控件的屏幕位置何时更改的方法?

使用WinForms,有没有办法提醒控件相对于屏幕的位置变化?

假设你有一个带有按钮的表单,并且你想知道该按钮何时从其当前像素位置移动到屏幕上。 如果将按钮移动到其父窗体上的其他位置,您显然可以使用LocationChanged事件,但如果窗体被用户移动,您如何知道该按钮已被视觉移动?

在这种简化的情况下,快速回答是监视表单的LocationChanged和SizeChanged事件,但是可以有任意数量的嵌套级别,因此监视链上的每个父级到主表单的这些事件是不可行的。 使用计时器来检查位置是否改变也看起来像是作弊(坏的方式)。

短版本:只给出一个任意的控制对象,是否有办法知道控件的位置在屏幕上何时发生变化,而不知道控件的父层次结构?

应要求说明:

请注意,这种“固定”概念是现有的功能,但它目前需要了解父表单以及子控件的行为方式; 这不是我想要解决的问题。 我想将这个控件跟踪逻辑封装在一个抽象的Form中,这个“Pin-able”的Forms可以继承它。 是否有一些消息泵的魔力,我可以利用它来了解控件何时在屏幕上移动,而不必处理所有复杂的父级跟踪?


我不知道为什么你会说跟踪母链“不可行”。 这不仅是可行的,而且是正确的答案和简单的答案。

只需简单地解决一个问题即可:

private Control         _anchorControl;
private List<Control>   _parentChain = new List<Control>();
private void BuildChain()
{
    foreach(var item in _parentChain)
    {
        item.LocationChanged -= ControlLocationChanged;
        item.ParentChanged -= ControlParentChanged;
    }

    var current = _anchorControl;

    while( current != null )
    {
        _parentChain.Add(current);
        current = current.Parent;
    }

    foreach(var item in _parentChain)
    {
        item.LocationChanged += ControlLocationChanged;
        item.ParentChanged += ControlParentChanged;
    }
}

void ControlParentChanged(object sender, EventArgs e)
{
    BuildChain();
    ControlLocationChanged(sender, e);
}

void ControlLocationChanged(object sender, EventArgs e)
{
    // Update Location of Form
    if( _anchorControl.Parent != null )
    {
        var screenLoc = _anchorControl.Parent.PointToScreen(_anchorControl.Location);
        UpdateFormLocation(screenLoc);
    }
}
链接地址: http://www.djcxy.com/p/10009.html

上一篇: A way to monitor when a Control's screen location changes?

下一篇: UIViewController reported as responding to addChildViewController: on iOS 4