午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

マウスドラッグでラベルコントロールの移動と直線の描画

マウスドラッグでラベルコントロールの移動と直線の描画

 
4つの点を通過する直線をPictureBoxに表示
点をマウスドラッグで移動して線もそれに合わせて描画しているところ
 
線を描画するにはPoint(点)が必要
そのPointの情報をPictureBoxに持たせたかったので
クラスの継承っていう機能を使ってexPictureBoxってのを新たに作った

f:id:gogowaten:20191016101002p:plain

クラスの追加
ソリューションエクスプローラーから右クリックメニューで
追加→クラス
↓が開いて

f:id:gogowaten:20191016101014p:plain

名前はexPictureBoxにしてみた
 

f:id:gogowaten:20191016101027p:plain

exPictureBoxに書いたのはこれだけ
 
Public Class exPictureBox
    Inherits PictureBox
    'Public PointN As New ArrayList
    Public PointN As New Generic.List(Of Point)

    Public Property exPoint() As Generic.List(Of Point)
        Get
            Return PointN
        End Get
        Set(value As Generic.List(Of Point))
            PointN = value
        End Set
    End Property

End Class
このクラスの目的はPictureBoxの機能+Pointを複数持たせること
Pointの情報は読み書きができること
解説サイトVB中学校を見ながら見よう見まねで書いてみた
よくわかっていないけど期待通りに動いている
 
2番目のPoint情報にPoint(1,1)を書き込む(書き換え)時は
Me.ExPictureBox1.PointN(2) = New Point(1, 1)
これでいいみたい、楽ちん
 
2番めのPoint情報を読み込む(取得する)時は
Dim pn As New Point(Me.ExPictureBox1.PointN(2))
 
 
作ったクラスはデザイン画面のツールボックスにも表示されるようになる

f:id:gogowaten:20191016101135p:plain

面白い
ここから追加できる
新しく作ったプロパティの名前はexPointにしてみた
これがデザイン画面のプロパティの画面でも表示されるみたいなのはさっき気づいた

f:id:gogowaten:20191016101200p:plain

なのでここからでも設定できるみたい
今回は気づかなかったので中に書いた
        With Me.ExPictureBox1.PointN
            .Add(New Point(0, 0))
            .Add(New Point(150, 40))
            .Add(New Point(80, 100))
            .Add(New Point(100, 150))
        End With
 
ここでデザイン画面全体図

f:id:gogowaten:20191016101433p:plain

今回使っているのは
exPictureBox1と点表示ボタンだけ
 
これでexPictureBoxには複数のPointを持たせることができたので
あとはこの情報を元に線を描画
Dim canvas As New Bitmap(Me.ExPictureBox1.Width, Me.ExPictureBox1.Height)
Dim g As Graphics = Graphics.FromImage(canvas)
Dim pss() As Point
pss = DirectCast(Me.ExPictureBox1.PointN.ToArray, Point())
g.DrawLines(Color.Aqua, pss)
Me.ExPictureBox1.Image = canvas
↑の中で見慣れないのが
pss = DirectCast(Me.ExPictureBox1.PointN.ToArray, Point())
これ
exPictureBoxのPoint(PointN)はCollectionのArrayListなんだけど
線を描画するときに使うPointは1次元配列なので変換する必要がある
もっとめんどくさい方法を想像していたけどこんな方法があった
今気づいたけどexPictureBoxって名前つけたんだけど
最初のeがEに変換されているなあExPictureBox1
最初の文字は大文字じゃないといけないのかしら
 
 
点表示ボタン設定部分
   Dim iLabel as Label
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim exp As Generic.List(Of Point)
    exp = Me.ExPictureBox1.PointN

    Me.iLabel = New Label()
    With Me.iLabel
        .Width = 5
        .Height = 5
        .BackColor = Color.Black
        .Location = exp(i)
       'Name = "exL" & i 'Withの中だとName、tag、textが空白になる
       'Tag = i
       'Text = i
    End With

    Me.iLabel.Name = i
    Me.iLabel.Tag = i
    iLabel.Text = i

    Me.ExPictureBox1.Controls.Add(iLabel)
    AddHandler iLabel.MouseDown, AddressOf マウスダウンドラッグ開始
    AddHandler iLabel.MouseMove, AddressOf マウスムーブドラッグ中
end sub
点の表示はLabelコントロールにしてみた
大きさは5x5、色は黒
マウスドラッグで移動するイベントに関連付け
うまくいかないのが名前とタグとテキストの指定
これは動かすときにどのラベルをクリックしたのか判別するのに使う用
目印だからどれでもいいんだけどWithを使ったなかだと空白になってしまう
 
マウスドラッグでラベルを移動して、線を描画する
Dim Pen2 As New Pen(Color.Aqua, 3)
Dim startP as Point

Private Sub マウスダウンドラッグ開始(ByVal sender As Object, ByVal e As MouseEventArgs)’マウスをおした時、MouseDown
    startP = New Point(e.Location)
End Sub
 
↓MouseMoveイベント
Private Sub マウスムーブドラッグ中(sender As Object, e As MouseEventArgs)
    If e.Button = Windows.Forms.MouseButtons.Left Then
        Dim newL As Point
        Dim oBj As Control
        oBj = DirectCast(sender, Label)
        newL = New Point(e.X - startP.X + oBj.Location.X, e.Y - startP.Y + oBj.Location.Y)
        oBj.Location = newL 'ラベルの表示場所決定

        '線の描画
        Dim canvas As New Bitmap(Me.ExPictureBox1.Width, Me.ExPictureBox1.Height)
        Dim g As Graphics = Graphics.FromImage(canvas)
        Dim i = oBj.Tag ' sender.tag
        Me.ExPictureBox1.PointN(i) = newL
        Dim pss() As Point
        pss = DirectCast(Me.ExPictureBox1.PointN.ToArray, Point())
        g.DrawLines(Pen2, pss)
        Me.ExPictureBox1.Image = canvas
    End If
End Sub
これもよくわかっていないけど動いている
Pixtack紫陽花でも折れ線や曲線をかけるようにしたいなあ
ダウンロード
 
参照したところ
VB コレクション - ArrayList, Hashtableなど
VB 中級講座 - 継承, Inherits, Overridable, Overrides
VB.NETで作る! | ドラッグで移動できるコントロールを作る
 
 
 
 
 
関連記事
次回2014/12/20は1日後
2019/08/23は5年後、継承を使わずに書いてみた
DrawLinesで直線の描画と、その頂点を表示してマウスドラッグ ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/16000619.html