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

わんくま同盟

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

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

■103812 / 15階層)  Visual Basicで簡易CADを作成
□投稿者/ 魔界の仮面弁士 (3881回)-(2025/08/04(Mon) 19:43:28)
No103811 (shiro さん) に返信
> Private Sub PictureBox1_MouseDown(
>  ByVal sender As System.Object,
>  ByVal e As System.Windows.Forms.MouseEventArgs) _
>  Handles PictureBox1.MouseDown
>
>  Dim pillarList As New List(Of Pillar)

Sub や Function の内側で Dim 宣言された変数を「ローカル変数」と呼びます。

そのデータ型が Integer であれ List であれ String であれ、
上記のローカル変数は、MouseDown イベントが発生するたびに初期化され
MouseDown イベントを抜けるたびに破棄されてしまいます。

※変数の有効期間のことを、専門用語で「スコープ」と呼びます。


> Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
>  Dim pillarList As New List(Of Pillar)

Paint イベントで宣言された pillarList 変数と
MouseDown イベントで宣言された pillarList 変数は
名前が同じというだけで、それぞれ別物です。


描画オブジェクトの List は、各イベント間で共有されるべきものですから、
ローカル変数として「Dim pillarList As New List(Of Pillar)」などと宣言するのではなく、
フィールド変数として宣言するようにしてください。

つまり、従来の
 Private pointList As New List(Of Point)
 Private snappedRectangles As New List(Of Rectangle)
と同様に、Form1 の直下にて
 Private pillarList As New List(Of Pillar)
として宣言されるべきである、ということです。


これは、クラスを自作していなかったとしても同じことです。

スコープの概念は、Visual Basic の言語仕様として重要な所なので、
もしも御存知なかったのであれば
 Visual Basic 中学校の 初級講座 [改訂版]
 第9回 変数のスコープと寿命
 https://www.umayadia.com/VBStandard2/VBStandard2Toc.htm
などで学んでおきましょう。


> Dim pillarList As New List(Of Pillar)
> Dim newPillar As New Pillar With {
>  .Index = pillarList.Count + 1,
>  .X = SnapToGrid(e.Location).X,
>  .Y = SnapToGrid(e.Location).Y
> }
> pillarList.Add(newPillar)

これだと、Index 管理に問題があります。
No103805 で 柱B を削除した時のことを覚えていますか?

たとえば、柱が 3 本あった場合、それぞれの Index は
 柱A ⇒ pillarList(0).Index は 1
 柱B ⇒ pillarList(1).Index は 2
 柱C ⇒ pillarList(2).Index は 3
と追加されていくことを想定されているのかと思います。

ではここで、柱A を削除したとすると
 柱B ⇒ pillarList(0).Index は 2
 柱C ⇒ pillarList(1).Index は 3
に変わるわけですよね。

ではその後、さらに柱D を建てるときに
 .Index = pillarList.Count + 1
が実行されたらどうなるでしょう? pillarList には柱が 2 本しかないので
 柱B ⇒ pillarList(0).Index は 2
 柱C ⇒ pillarList(1).Index は 3
 柱D ⇒ pillarList(2).Index は 3
になってしまうわけです。


柱に固定的な番号を付けるのであれば、同じ Index 番号が再利用されることは防ぐべきなので、
例えばこのような書き方もしてみてください。

 Public Class Pillar
  Private Shared LastIndex As Integer = 0
  Public ReadOnly Property Index As Integer
  Public Property X As Integer
  Public Property Y As Integer

  Public Sub New(location As Point)
   LastIndex += 1
   Me.Index = LastIndex
   Me.X = location.x
   Me.Y = location.y
  End Sub
 End Class


そして、柱を建てる際には
  Dim newPillar As New Pillar(SnapToGrid(e.Location))
  pillarList.Add(newPillar)
のようにします。こうすれば Index も自動採番されますし、
pillarList から柱が削除された後も、Index の重複が発生することがありません。
編集キー/

前の記事(元になった記事) 次の記事(この記事の返信)
←Re[14]: Visual Basicで簡易CADを作成 /shiro →Re[16]: Visual Basicで簡易CADを作成 /shiro
 
上記関連ツリー

Visual Basicで簡易CADを作成 / shiro (25/07/25(Fri) 20:50) #103783
Re[1]: Visual Basicで簡易CADを作成 / KOZ (25/07/27(Sun) 14:35) #103784
  └ Re[2]: Visual Basicで簡易CADを作成 / shiro (25/07/28(Mon) 20:17) #103785
    ├ Re[3]: Visual Basicで簡易CADを作成 / kiku (25/07/29(Tue) 08:49) #103786
    └ Re[3]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/07/29(Tue) 14:06) #103791
      └ Re[4]: Visual Basicで簡易CADを作成 / shiro (25/07/30(Wed) 12:22) #103792
        └ Re[5]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/07/30(Wed) 15:46) #103794
          └ Re[6]: Visual Basicで簡易CADを作成 / shiro (25/07/31(Thu) 07:34) #103795
            └ Re[7]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/07/31(Thu) 10:48) #103796
              └ Re[8]: Visual Basicで簡易CADを作成 / shiro (25/08/01(Fri) 06:15) #103797
                ├ Re[9]: Visual Basicで簡易CADを作成 / kiku (25/08/01(Fri) 08:47) #103798
                │└ Re[10]: Visual Basicで簡易CADを作成 / shiro (25/08/02(Sat) 03:40) #103803
                └ Re[9]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/01(Fri) 10:46) #103800
                  ├ Re[10]: Visual Basicで簡易CADを作成 / kiku (25/08/01(Fri) 10:50) #103801
                  └ Re[10]: Visual Basicで簡易CADを作成 / shiro (25/08/02(Sat) 03:38) #103802
                    └ Re[11]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/03(Sun) 11:50) #103805
                      └ Re[12]: Visual Basicで簡易CADを作成 / shiro (25/08/04(Mon) 05:10) #103806
                        └ Re[13]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/04(Mon) 11:36) #103808
                          └ Re[14]: Visual Basicで簡易CADを作成 / shiro (25/08/04(Mon) 18:59) #103811
                            └ Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/04(Mon) 19:43) #103812 ←Now
                              └ Re[16]: Visual Basicで簡易CADを作成 / shiro (25/08/05(Tue) 12:42) #103814
                                └ Re[17]: Visual Basicで簡易CADを作成 / shiro (25/08/05(Tue) 12:44) #103815
                                  └ Re[18]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/05(Tue) 18:02) #103817
                                    └ Re[19]: Visual Basicで簡易CADを作成 / shiro (25/08/05(Tue) 19:28) #103819
                                      └ Re[20]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/05(Tue) 20:39) #103821
                                        └ Re[21]: Visual Basicで簡易CADを作成 / shiro (25/08/06(Wed) 12:22) #103822
                                          └ Re[22]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/06(Wed) 14:42) #103825
                                            ├ Re[23]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/06(Wed) 17:53) #103828
                                            │└ Re[24]: Visual Basicで簡易CADを作成 / shiro (25/08/06(Wed) 19:13) #103830
                                            │  ├ Re[25]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/06(Wed) 19:44) #103832
                                            │  │└ Re[26]: Visual Basicで簡易CADを作成 / shiro (25/08/07(Thu) 07:06) #103834
                                            │  │  └ Re[27]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/07(Thu) 12:18) #103835
                                            │  │    └ Re[28]: Visual Basicで簡易CADを作成 / shiro (25/08/07(Thu) 19:14) #103836
                                            │  │      └ Re[29]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/07(Thu) 20:25) #103837
                                            │  │        ├ Re[30]: Visual Basicで簡易CADを作成 / shiro (25/08/08(Fri) 03:34) #103838
                                            │  │        └ Re[30]: Visual Basicで簡易CADを作成 / shiro (25/08/08(Fri) 07:29) #103839
                                            │  │          └ Re[31]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/08(Fri) 09:40) #103841
                                            │  │            └ Re[32]: Visual Basicで簡易CADを作成 / shiro (25/08/09(Sat) 05:05) #103842
                                            │  │              └ Re[33]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/09(Sat) 14:24) #103843
                                            │  │                └ Re[34]: Visual Basicで簡易CADを作成 / shiro (25/08/09(Sat) 19:18) #103844
                                            │  └ Re[25]: Visual Basicで簡易CADを作成 / 魔界の仮面弁士 (25/08/06(Wed) 19:53) #103833
                                            └ Re[23]: Visual Basicで簡易CADを作成 / shiro (25/08/18(Mon) 12:41) #103847
                                              └ Re[24]: Visual Basicで簡易CADを作成 / kiku (25/08/20(Wed) 15:09) #103848
                                                └ Re[25]: Visual Basicで簡易CADを作成 / shiro (25/08/20(Wed) 18:35) #103849
                                                  └ Re[26]: Visual Basicで簡易CADを作成 / kiku (25/08/21(Thu) 09:03) #103850
                                                    └ Re[27]: Visual Basicで簡易CADを作成 / shiro (25/08/21(Thu) 22:01) #103851
                                                      └ Re[28]: Visual Basicで簡易CADを作成 / kiku (25/08/22(Fri) 08:45) #103852
                                                        └ Re[29]: Visual Basicで簡易CADを作成 / shiro (25/08/22(Fri) 13:20) #103853
                                                          └ Re[30]: Visual Basicで簡易CADを作成 / kiku (25/08/22(Fri) 16:45) #103854
                                                            └ Re[31]: Visual Basicで簡易CADを作成 / shiro (25/08/22(Fri) 20:33) #103855
                                                              └ Re[32]: Visual Basicで簡易CADを作成 / kiku (25/08/25(Mon) 08:42) #103857

上記ツリーを一括表示 / 上記ツリーをトピック表示
 
上記の記事へ返信