午後わてんのブログ

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

動的に作ったコントロールと あらかじめ配置されているコントロールの連携のテスト、クラス作成の練習

動的に作ったコントロール

あらかじめ配置されているコントロールの連携のテスト
連携とか関連付けとかをラクにしたくてテストしてみた

 
イメージ 2
機能は
TabControlにTabPageの追加と削除
TabPageにボタンの追加と削除
追加したボタンクリックで連携しているLabelにボタンの数字を表示
Labelクリックで連携しているボタンの色変更
追加したボタンはどのLabelと連携するのかの指定をして、その確認
 
エラー(例外)の処理は全くしていないので
タブがないのにタブ削除しようとするとエラーで止まる、ボタン削除も一緒
他にもタブがないのにボタンを追加しようとしたりとかも
 
 
 
イメージ 3
「タブ追加1」ボタンでタブ1、「タブ追加2」ボタンでタブ2というTabPageが追加される
追加するときに連携するLabelを指定している、それぞれLabel1とLabel2
 
 
イメージ 4
「ボタン追加」ボタンで表示しているタブにボタンが上から順番に追加される
タブ2に追加されたボタンはLabel2と連携する
 
イメージ 5
追加されたボタンを押すとLabel2の表示が押したボタンと同じ数字になる
連携していないLabel1は変化なし
 
イメージ 6
Label2をクリックすると連携しているタブにあるボタンの中で
同じ数字のボタンの色が変化する
 
イメージ 7
タブの表示をタブ1に切り替えてボタンを3つ追加したところ
 
イメージ 8
追加されたボタンを押すとLabel1の表示が変化する、Label2は変化なし
 
イメージ 9
Label1クリックでボタンの色を変更したところ
 
テストアプリの中身は
デザイン画面

f:id:gogowaten:20191024144149p:plain

ボタン5個、Label2個、TabControl1個
ボタン以外の名前は初期値
今回はTabPageを継承したExPageクラスを作成して使うので
TabControlを追加した時に自動で作成されるTabPage1とTabPage2は削除
 
Form1

f:id:gogowaten:20191024144159p:plain

Public Class Form1
    'ボタン追加:タブにボタンを追加、右に追加
    'ボタン削除:タブにあるボタンを削除、右端のボタンを削除
    'タブに追加したボタンを押すと対応したLabelに自身のtextを表示
    'Labelをクリックで対応したボタンの色が変化
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Label1.BorderStyle = BorderStyle.FixedSingle
        Label2.BorderStyle = BorderStyle.FixedSingle
    End Sub
    Private Sub Button1タブ追加1_Click(sender As Object, e As EventArgs) Handles Button1タブ追加1.Click
        Call AddPageタブ追加(Label1, "タブ1")
    End Sub
    Private Sub Button2タブ追加2_Click(sender As Object, e As EventArgs) Handles Button2タブ追加2.Click
        Call AddPageタブ追加(Label2, "タブ2")
    End Sub
    '表示しているタブページを削除
    Private Sub Button3タブ削除_Click(sender As Object, e As EventArgs) Handles Button3タブ削除.Click
        TabControl1.TabPages.Remove(TabControl1.SelectedTab)
    End Sub
    Private Sub Button4ボタン追加_Click(sender As Object, e As EventArgs) Handles Button4ボタン追加.Click
        Dim iPage As exPage = TabControl1.SelectedTab
        iPage.AddButtonボタン追加()
    End Sub
    '最後に作成されたボタンを削除
    Private Sub Button5ボタン削除_Click(sender As Object, e As EventArgs) Handles Button5ボタン削除.Click
        Dim iPage As exPage = TabControl1.SelectedTab

        'ボタンが1個でも在れば
        If iPage.Controls.Count > 0 Then
            iPage.RemoveButtonボタン削除()
        End If
    End Sub
    'Labelクリックで対応したボタンの色変更
    Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click, Label2.Click
        Dim l As Label = DirectCast(sender, Label)
        Dim tp As exPage = TabControl1.SelectedTab
        tp.ChangeColorボタンの色変更(l)
    End Sub
    Private Sub AddPageタブ追加(l As Label, tabName As String)
        Dim eP As New exPage(l)
        eP.Text = tabName
        TabControl1.TabPages.Add(eP)
        TabControl1.SelectedTab = eP '追加したタブを選択状態にする
    End Sub

End Class
 
 
 
 
 

ExPage

f:id:gogowaten:20191024144218p:plain

'TabPageを継承したexPage、
Public Class exPage
    Inherits TabPage
    Private BtList As New List(Of Button) '作ったボタンを入れておくリスト
    Private BtCount As Integer = 0 'ボタン数記録用
    Private BtHeight As Integer = 24 'ボタンの高さ、追加する時の位置決定に使う
    Private LastButton As Button '最後に追加されたボタン記録用
    Private WithEvents bt As Button 'イベント付き変数
    Private Form1Label As Label '連携するLabel記録
    Public Sub New(l As Label)
        Form1Label = l 'タブにあるボタンと連携するLabel指定する
    End Sub
    Public Sub AddButtonボタン追加()
        'ボタンの位置決め
        Dim nP As Point
        If BtCount = 0 Then
            nP = New Point(0, 0)
        Else
            nP = New Point(0, LastButton.Top + BtHeight)
        End If
        'ボタン作成
        bt = New Button
        With bt
            .Text = BtCount '& Me.Text
            .Location = nP
        End With
        'ボタン追加
        BtList.Add(bt)
        BtCount += 1
        LastButton = bt
        Controls.Add(bt)
        AddHandler bt.MouseClick, AddressOf DisplayLabelに表示 'クリックイベントに関連付け
    End Sub
    Public Sub RemoveButtonボタン削除()
        '表示ページの中で最後に追加されたボタンを削除する
        'Controls.RemoveAt(BtCount - 1)
        Controls.Remove(LastButton) '外す
        LastButton.Dispose() 'これ要る?
        BtList.RemoveAt(BtCount - 1) 'リストからも削除
        BtCount -= 1 'カウント1減らす
        If BtCount > 0 Then
            LastButton = BtList(BtCount - 1)
        End If
    End Sub
    Private Sub DisplayLabelに表示(sender As Object, e As MouseEventArgs) Handles bt.Click
        Dim ibt As Button = DirectCast(sender, Button)
        Form1Label.Text = ibt.Text
    End Sub
    Public Sub ChangeColorボタンの色変更(l As Label)
        If l.Equals(Form1Label) = False Then Return '対応Labelと違っていたらなにもしないで終了

        Dim bt As Button = BtList(l.Text)
        If bt.BackColor = Color.PeachPuff Then
            bt.BackColor = Color.PowderBlue
        Else
            bt.BackColor = Color.PeachPuff
        End If
    End Sub
End Class
 
 
 
 
タブ追加の処理は
Form1の
46:    Private Sub AddPageタブ追加(l As Label, tabName As String)
47:        Dim eP As New exPage(l)
47行目のNewでタブ作成の時に連携させるLabelを引数として渡して
ExPageの
09:    Private Form1Label As Label '連携するLabel記録
11:    Public Sub New(l As Label)
12:        Form1Label = l 'タブにあるボタンと連携するLabel指定する
11行目のsub NewでLabelを受け取って12行目で9行目の変数に記録している
これでLabelとタブが関連付けられた
9行目で宣言した変数はグローバル変数なのでExPageクラス全体で共有する変数になる、であってるかな
 

ボタン追加の処理
ボタンを実際に作成するのはExPageクラスの方で、呼び出すのはForm1
Form1のボタンクリックイベントでExPageのボタン作成メソッドを呼び出す
24:    Private Sub Button4ボタン追加_Click(sender As Object, e As EventArgs) Handles Button4ボタン追加.Click
25:        Dim iPage As exPage = TabControl1.SelectedTab
26:        iPage.AddButtonボタン追加()
27:    End Sub
25行目のSelectedTabは選択表示されているタブ
 
ExPageクラス
08:    Private WithEvents bt As Button 'イベント付き変数
24:        bt = New Button
34:        AddHandler bt.MouseClick, AddressOf DisplayLabelに表示 'クリックイベントに関連付け
24行目でボタン作成している、作成したボタンは8行目で宣言したイベント付き変数のbtに入れる
34行目でボタンのクリックイベントに関連付けしている
 

追加したボタンのクリックイベント
ExPageクラス
48:    Private Sub DisplayLabelに表示(sender As Object, e As MouseEventArgs) Handles bt.Click
49:        Dim ibt As Button = DirectCast(sender, Button)
50:        Form1Label.Text = ibt.Text
51:    End Sub
Form1LabelはExPageクラスのグローバル変数なのでExPageならどこからでも参照できる
ExPage(タブページ)作成ごとに連携するLabelを指定しているので、どのLabelと連携しているのか探さなくてもいいことになる

 
ダウンロード先
OneDrive
test33_コントロールの連携2.7z

 
メモ
クラスの追加方法

f:id:gogowaten:20191024144232p:plain

右のソリューションエクスプローラーをクリックして表示して
項目の上から2番めにあるアプリと同じ名前を右クリック
表示されたメニューから追加→クラス
 

f:id:gogowaten:20191024144242p:plain

クラスを選択して、名前をつける、追加ボタンクリックで
新しいクラスが追加作成される

f:id:gogowaten:20191024144252p:plain

 
 
 
 
今回のこのテストは前回の記事のアプリでラクがしたかったから
大量の画像ファイルから目的のものを選ぶアプリを作りなおしている途中その2 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ

f:id:gogowaten:20191024144303p:plain

SplitPanelを使って中央で左右に分けている
それぞれListViewとPictureBoxを置いて連携、関連させている
右のListViewはTabControlのTabPageそれぞれに置いてあって
どのTabPageのListViewもPictureBox2と連携している
 
連携の内容は
PictureBoxの上でマウスホイール回転で画像の切り替え
縮小画像クリックで拡大画像をPictureBoxに表示
 
追加したい機能がTabPageの追加と削除
特に追加した時にどのコントロールと連携させるのか処理をラクにしたかった
今のはタブページは2枚固定、これだけでもかなりめんどくさい処理になっていて
タブを増減できるようにしたらもっとめんどくさくなりそうなので、どうしたらいいかなあって今回のテストになった
テストではうまくできた感じだけどどうなるかなあ
クラスを作成するときに、どれをプロパティにするのかメソッドにするのかの判断がさっぱりわかっていない、作りながら、作ってからこれはメソッドじゃなくてプロパティでいいやとかなっている
最初はTabControlを継承したクラスで作っていて、途中でTabPageを継承したクラスが必要になって追加して、できた!と思って少ししてからTabControlを継承したクラスは必要ないことがわかって作りなおしたりとか