2009-05-26 10 views
0

フォーム上のPanelコントロールにいくつかのLabelコントロールがあります。実行時にパネルとラベルを非表示にし、他のテキストをフォーム上に直接描画できるように、フォームの起点に相対的なラベルの位置を取得したい。Control.PointToScreenは異なる結果を示します - なぜですか?

基本的に、私は次の計算をやってる:Control.PointToScreen(とラベルの絶対画面位置を取得)とControl.PointToClient()との相対位置に戻ってそれを変換するので、次のいずれか

Dim newloc As Point = Me.PointToClient(ctl.PointToScreen(Point.Empty)) 
負の値で表示領域の外に私の新しいポイントを置く -

または

Dim newloc As Point = Me.PointToClient(ctl.Parent.PointToScreen(ctl.Location)) 

は、私は2つの方法が、時々私に異なる結果を与えることを発見しました! - しかし、理由を特定できませんでした。私は彼らが同一でなければならないと思っていたでしょう(そして、彼らはほとんどの時間です)。

ドキュメントを読むのは初めてではありませんでしたが、多分何かをスキップしました...とにかく、私の髪を引き裂く前に、どんな助けでも感謝しています。

これに対して、これを行うより良い方法がありますか?

編集:サンプル結果

だから、ここでは実際の例です。

Panel1の{X = 4、Y = 6}のLabel1。同じ親Panel1上の{X = 163、Y = 6}のLabel2。明らかに私は異なるXポジションを期待していますが、Yは両方のポジションが同じでなければなりません。

ctl.PointToScreen(Point.Empty)
ctl.Parent.PointToScreen(ctl.Location)
は、{X = 959、Y = 119}のLabel1と同じ画面の場所を表示します(絶対値はフォーム自体の位置によって異なります)、Me.PointToClientが適用されている場合({X = 5、Y = 32}の場合)、フォームからの相対的な正しい位置です。

次の行は、Label2(親(6)内の同じY値)と同じ計算を行いますが、結果は完全にオフです。ctl.Parent.PointToScreen()は{X = 1114、Y = 63}。 Xはほぼ正しいです(959-4 + 163 = 1118)が、YはLabel1の119付近にはありません。そして、ctl.PointToScreen()は私に{X = 166、Y = 29}を与え、フォーム座標(Me.PointToClient){X = -784、Y = -2}に変換し直します。

これらの数値は、Madnessの周りを何も動かすことなく、相互に直接的に計算され、デバッグウィンドウに印刷されます。

これはかなり面倒ですが、誰かが簡単な説明をしてくれることを願っています。ありがとう!

+0

いつ違いがありますか?フォームまたはラベルが移動されたとき、または同じ呼び出しで異なる場合 –

+0

質問を編集し、実際の値を追加して問題を説明します。 –

+1

そして多分少しの睡眠を取って後でそれを後に戻っても助けてくれるでしょう... ;-) –

答えて

3

OK、解決策が見つかりました。

私はControl.PointToScreenをの前に呼び出していました。コントロールが作成される前に:Control.IsHandleCreated = False。

コントロールが最初に作成されていることを確認したら(Control.CreateControl)、両方のメソッドが同じように機能します。

私が後続の呼び出しで異なる結果を出したのは、Control.PointToScreenの最初の呼び出しによってコントロールが作成されるため(つまり、その親と他のコントロールが親に配置されているため)、

よく、私はこれで済むとうれしいです:-)

0

私はそれが睡眠だと思う。 :)の代わりに:

ctl.PointToScreen(Point.Empty)

ctl.Parent.PointToScreen(ctl.Location)

試してみてください。

ctl.PointToScreen (ポイント。空)

ctl.PointToScreen(ctl.Location)//注釈なし.Parent!

代わりに、x/y座標の違いが表示されます。

また、PointToScreen演算を実行するときにControl.TopLevelControlまたはControl.FindForm()を使用して一番外側のフォームを取得してみてください。

+0

ctl.PointToScreen(ctl.Location)//注釈なし.Parent!間違っているのは、ctl.locationをオフセットとして追加するためです。これは、私が望ましくないものです。私の方法は、少なくとも私に正しい座標を教えてくれます。 TopLevelControlまたはFindFormを使用することの他の提案は良いですが、この特殊なケースでは私は本当にトップレベルのコントロールを望ましくはありません。私は実際に別のコンテナ内のポジションを探しています。 –

関連する問題