2011-11-15 13 views
7

WinFormsでは、画面に対してコントロールを変更するコントロールに警告する方法はありますか?コントロールの画面の場所が変更されたときを監視する方法はありますか?

ボタンが付いたフォームがあり、ボタンが画面上の現在のピクセル位置から移動したときを知りたいとします。ボタンが親フォームの別の場所に移動された場合は、明らかにLocationChangedイベントを使用できますが、フォームがユーザーによって移動された場合、ボタンが視覚的に移動したことをどのように知ることができますか?

この単純なケースでは、フォームのLocationChangedイベントとSizeChangedイベントを監視するのがクイックアンサーですが、任意の数のネスティングレベルが存在する可能性があります。場所が変更されたかどうかを確認するためにタイマーを使用すると、悪い方法で不正行為のように思えます。

ショートバージョン: のみ、任意のコントロールオブジェクトを指定して、画面上のときのコントロールの位置の変化を知るための方法は、コントロールの親階層の知識がなくても、あるのでしょうか?

要求によってイラスト、この「ピン留め」という概念は、既存の機能があるが、それは現在、親フォームとどのように子コントロールの振る舞いの知識が必要であることを

Illustration

注意。これは私が解決しようとしている問題ではありません。私は、このコントロール追跡ロジックを抽象的なFormにカプセル化したいと思います。複雑な親トラッキングをすべて処理することなく、コントロールが画面上を移動するときを知るために利用できるメッセージポンプの魔法がありますか?

+0

はなぜすべての親に現実的ではない上のウィンドウにすべての方法を監視していませんか? –

+0

20レベルのネスティングがあり、すべてがFillにドッキングされているとします。ボーダーをドラッグしてメインフォームのサイズを変更すると、SizeChangedイベントはドラッグの途中で何度もトリガーされます。それは冗長なイベントのトンです。第2に、これらのコントロールは場所(完全に異なる入れ子構造の階層)に移動する可能性があるため、各親に対して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

関連する問題