2011-11-15 69 views
7

使用WinForms,有沒有辦法提醒控件相對於屏幕的位置變化?假設你有一個帶有按鈕的窗體,並且你想知道按鈕從當前像素位置移動到屏幕上的時間。如果將按鈕移動到其父窗體上的其他位置,您顯然可以使用LocationChanged事件,但如果窗體被用戶移動,您如何知道該按鈕已被視覺移動?監視控件的屏幕位置更改的方法?

在這種簡化的情況下,快速回答是監視表單的LocationChanged和SizeChanged事件,但可以有任意數量的嵌套級別,因此監視這些事件對於鏈上的每個父級到主表單是不可行的。使用計時器來檢查位置是否改變也看起來像是作弊(壞的方式)。

短版: 僅給出一個任意控制對象,有沒有辦法知道在屏幕上時,該控件的位置變化,而控制的父層次的知識呢?

說明,按要求:

Illustration

注意,這個「釘住」的概念是現有的能力,但它目前需要父窗體以及如何控制孩子的行爲的知識;這不是我想要解決的問題。我想將這個控件跟蹤邏輯封裝在一個抽象的Form中,這個「Pin-able」的Forms可以繼承它。是否有一些消息泵的魔力,我可以利用它來了解控件何時在屏幕上移動,而不必處理所有複雜的父級跟蹤?

+0

爲什麼不監控所有的家長一路? –

+0

假設你有20層嵌套,所有對接填充。當您通過拖動邊框來調整主窗體的大小時,SizeChanged事件將在每個級別上觸發,並在拖動過程中多次觸發。這是一大堆冗餘事件。其次,這些控件可能會從一個地方移動到另一個地方(完全不同的嵌套層次結構),因此即使您爲每個父母連接了ParentChanged,在它更改之後,您仍然無法從前父級中解除SizeChanged/LocationChanged,而無需存儲所有父控件信息當你穿越。這一切似乎都很骯髒。 – roken

+1

這似乎是需要問題的人之一:「你想做什麼?」 –

回答

3

我不知道爲什麼你會說跟蹤母鏈「不可行」。這不僅是可行的,這是正確的答案簡單的答案。

就在溶液中的快速劈:頂端窗口不可行

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

這是在我對這個問題的大量評論中我忽略的可能解決方案,但是覺得它很髒。我不希望任何更好的方式來做到這一點。 – roken