【问题标题】:A way to monitor when a Control's screen location changes?一种监视控件的屏幕位置何时更改的方法?
【发布时间】:2011-12-29 20:17:17
【问题描述】:

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

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

在这个简化的情况下,快速的答案是监控表单的 LocationChanged 和 SizeChanged 事件,但是可以有任意数量的嵌套级别,因此监控这些事件对于链上到主表单的每个父级是不可行的。使用计时器检查位置是否发生变化也似乎是作弊(以一种糟糕的方式)。

短版: 仅给定一个任意 Control 对象,有没有办法知道该 Control 在屏幕上的位置何时发生变化,而不需要知道该控件的父层次结构?

插图,应要求提供:

请注意,这种“固定”概念是现有功能,但目前需要了解父窗体以及子控件的行为方式;这不是我要解决的问题。我想将此控制跟踪逻辑封装在“可固定”表单可以继承的抽象表单中。是否有一些消息泵魔法可以让我知道控件何时在屏幕上移动,而无需处理所有复杂的父跟踪?

【问题讨论】:

  • 为什么不能一直监控所有的父母到顶部窗口不可行?
  • 假设您有 20 层嵌套,全部停靠到 Fill。当您通过拖动边框调整主窗体的大小时,SizeChanged 事件将在每个级别上触发,在拖动过程中多次触发。这是一大堆多余的事件。其次,这些控件可能会从一个地方移动到另一个地方(完全不同的嵌套层次结构),因此即使您为每个父级连接 ParentChanged,在它更改后,您也无法在不存储所有父级控件的情况下从以前的父级取消挂钩 SizeChanged/LocationChanged遍历时的信息。这一切似乎都很肮脏。
  • 这似乎是需要问题的人之一:“你想做什么?”
  • 我想将表单“固定”到任意控件,因此当控件移动时,表单的位置将保持在相对于控件的相同位置。
  • 也许您可以提供一些您正在尝试完成的屏幕截图。

标签: c# winforms controls location screen


【解决方案1】:

我不确定您为什么会说跟踪父链“不可行”。它不仅可行,而且是正确的答案简单的答案。

快速解决方案:

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);
    }
}

【讨论】:

  • 这是我在对该问题的大量评论中回避的可能解决方案,但觉得它很脏。不过,我认为没有更好的方法来做到这一点。
猜你喜欢
  • 1970-01-01
  • 2014-05-18
  • 2016-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多