2011-11-15 25 views
7

WinForms ile, ekrana göre kontrol değiştiren bir konuma uyarı verilmesinin bir yolu var mı?Bir Kontrolün ekran konumu değiştiğinde nasıl izlenecek?

Üzerinde bir düğme bulunan bir Formunuz olduğunu ve düğmenin ekrandaki mevcut piksel konumundan ne zaman taşındığını bilmek istediğinizi varsayalım. Düğme, ana Formunda farklı bir konuma taşınırsa, LocationChanged olayını açıkça kullanabilirsiniz, ancak Form kullanıcı tarafından taşındıysa, düğmenin görsel olarak taşındığını nasıl anlarsınız?

Bu basitleştirilmiş durumda, hızlı yanıt Formun LocationChanged ve SizeChanged olaylarını izlemek içindir, ancak rasgele bir sayıda yuvalama düzeyi olabilir, bu nedenle her üst öğe için zincirdeki ana form için bu olayları izlemek mümkün değildir. Konumun değişip değişmediğini kontrol etmek için bir zamanlayıcı kullanmak da hile gibi görünüyor (kötü bir şekilde).

Kısa versiyon: sadece keyfi bir denetim nesnesi göz önüne alındığında, ekranda zaman o denetimin konumu değişiklikleri bilmek için bir yol denetimin üst hiyerarşi bilgisi olmadan var mı?

isteği ile bir illüstrasyon, Bu "iğneleme" kavramı varolan yetenektir ancak şu anda ana formu ve nasıl çocuk kontrol boğulan bir bilgi gerektirdiğini

Illustration

Not; Bu çözmeye çalıştığım sorun değil. Bu kontrol izleme mantığını, formları "sabitleştirebilen" formların kalıtsal bir formunda kapsüllemek istiyorum. Karmaşık ebeveyn takibiyle uğraşmak zorunda kalmadan ekranda bir kontrolün ne zaman hareket ettiğini bilmek için girebileceğim bazı mesaj pompa sihirbazı var mı?

+0

Neden tüm veliler izlenmesi değil tüm yol mümkün değildir üst pencereye? –

+0

Tümü, Doldur'a yerleştirilmiş 20 yuvalama seviyeniz olduğunu varsayalım. Ana biçimi, kenarlığı sürükleyerek yeniden boyutlandırdığınızda, SizeChanged olayı, sürükleme sırasında birçok kez her bir düzeyde tetiklenecektir. Bu bir ton gereksiz olay. İkinci olarak, bu kontroller bir yerden diğerine geçebilir (tamamen farklı yuvalanmış hiyerarşileri), bu nedenle her ebeveyn için ParentChanged'i bağlasanız bile, değişiklik yaptıktan sonra, tüm ebeveyn kontrolünü saklamadan eski ebeveynlerden SizeChanged/LocationChanged'i kaldıramazsınız geçiş yaparken bilgi. Her şey çok kirli görünüyor. – roken

+1

Bu, soruyu gerektirenlerden biri gibi görünüyor: "Ne yapmaya çalışıyorsunuz?" –

cevap

3

Neden üst zincirin izlenmesinin neden uygun olmadığını söyleyemediğinizden emin değilim. Bu sadece uygun değil, doğru cevap ve kolay cevap.

bir çözüme Sadece hızlı kesmek:

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

Bu benim büyük yorumumda sorduğum olası çözümdür, ancak kirli olduğunu hissettim. Bunu yapmak için daha iyi bir yol görmem. – roken

İlgili konular