C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


■86986 / )  Re[7]: コントロールが全て削除されてしまう
□投稿者/ 魔界の仮面弁士 (1608回)-(2018/04/06(Fri) 16:52:12)
No86778 では VB2017 をお使いだったようなので、その前提で回答します。

No86983 (FRMC さん) に返信
> まず、頂点の追加をし、それから追加したモノ以外の頂点(ラベル)を動かすと動かす前のラベルが残ってしまい、それが無限に続いてしまいます。

どのタイミングで処理しているのか(Timer 処理? クリックした位置に移動? マウスドラッグに追従?)が
分かりませんが、とにかく「動かす」ということは、ラベルの座標を変更しているという事ですよね。
だとすれば、この移動処理の段階では、Add / Remove / Clear の出番は一切無いはず。

ということで、座標変更のために各ラベルの Location プロパティ、あるいは Left と Top プロパティを
編集するだけのコードを書いているのであろうかと想像します。(あるいは SetBounds メソッド)

たとえば
 Me.LabelA.Left += 10
のようにすれば、このコードが呼ばれるたびに、10 ドットずつ右にずれることになりますね。
もちろん実際には、親コントロールの領域内に収まるようなコードなのだとは思いますが。


…で、この座標変更においては、「どのラベルを動かすのか」が重要となるわけですが、
追加したばかりの頂点ラベルと、それ以前に追加してあった既存のラベルを、
どのようなコードで区別されているのでしょうか?
そこの手続きが間違っているので、おかしな動きをしているのではないかと想像しています。


また、「残ってしまう」としか説明されていませんが、具体的にはどのような残り方をするのでしょうか。
実際にはそこに存在しないのに残像として残ってしまうといるだけなのか、
それとも本当にラベルが増殖してしまっているのかも確認しておいた方が良いと思います。

子コントロールが増殖しているかどうかは、移動のたびに
 Debug.WriteLine( Me.PictureBox1.Controls.Count )
などを呼び出すようにすれば追跡できます。この値が予期せず増加するなら、
コントロールの管理方法に問題があるということになります。

Count 値が変化していないのに、残像が残ってしまっているのなら、
 Me.PictureBox1.Refresh()
で再描画することで解決できるかもしれません。



> そのためにclearをしていますが、

うまく移動させられないので、一旦すべてクリアして再配置してみた、ということでしょうか?


> 今回はclearをすると全コントロールが削除されるので、clear以外のremoveみたいな感じでできるものを探しています。

PictureBox1 に載っている Label をすべて削除するという意味であれば、
 For Each lbl In Me.PictureBox1.Controls.OfType(Of Label).ToArray()
  Me.PictureBox1.Controls.Remove(lbl)
  lbl.Dispose()
 Next
と書けます。


すべての Label ではなく、特定の Label だけを削除したいのであれば、たとえば
 Me.PictureBox1.Controls.Remove( 削除したいLabelインスタンスを格納した変数 )
 削除したいLabelインスタンスを格納した変数.Dispse()
 削除したいLabelインスタンスを格納した変数 = Nothing
というコードになります。


特定の Label 以外をすべて削除したいのであれば、
 For Each lbl In Me.PictureBox1.Controls.OfType(Of Label).ToArray()
  If lbl IsNot 残したいLabelのインスタンス Then
   Me.PictureBox1.Controls.Remove(lbl)
   lbl.Dispose()
  End If
 Next
などとなるでしょう。


このあたりの手続きは、それぞれの Label をどのように管理しているのかによっても
コーディングが変わってくるので、ご自身の実装に合わせて適宜調整してみてください。
(頂点数が可変個数の場合は、配列やコレクション等で管理されているのでしょうし)



>>いずれにせよ、現在のコーディング内容が間違っているのだと思いますが、
>>実際のコードが一切記述されていない以上、問題点を指摘することができません。
> clearとremoveです。

Clear や Remove で取り除いたラベルは、後で再利用しますか?
それとも再利用せずに破棄して、必要になったら、もういちど New しなおす感じですか?

前者だとしたら、どのラベルが使用中で、どれが利用されていない物なのか
インスタンス管理に気を使う必要があるでしょう。

後者だとしたら、Remove や Clear の後で Dispose を呼び出せねばなりませんし、
Dispose 済みのラベルが再利用されないよう注意せねばなりません。(再度作り直す必要がある)


>>エラーメッセージが出るのではなく、想定とは異なる動きをしている(論理エラー)という意味なら、
> そうです。全く異なる感じです。
では、どういう操作をした時に、どういう結果になるのか、再現手順を示してください。


> まとめると、以前出直した質問の代替案です。
まとまってはいないですよね。
返信 編集キー/


管理者用

- Child Tree -