多:1のイベント処理 への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2020/11/4 13:06:53
>> m.Map.Map_Move(Direction:=sender.Tag)
> これはTagの内容を直接渡しているので、Tagの内容を
> Map.Dir.UpやMap.Dir.Downなどにすれば動作するとすぐ解りました。
Map_Move の引数が Direction As Object の場合には、
m.Map.Map_Move(Direction:=sender.Tag)
のままで構いませんが、恐らくは Direction As Map.Dir なのですよね。
sender 引数の型は As Object ですし、
Tag プロパティの型も As Object です。
初期設定では Option Strict Off モードでビルドされているので問題になりませんが、
Option Strict On モードでビルドされていた場合、
Map.Dir 型の仮引数に渡す値は、Object 側の値を実引数として渡すのではなく、
Map.Dir 型の実引数を渡す必要があります。そのため、 DirectCast を使って
データ型を揃えてやる必要があるというわけです。
なお、このパターンを実行する場合には、Form の Load イベントにおいて、
lblMovingUp.Tag = Map.Dir.Up
などのように、「Tag プロパティに Map.Dir 列挙型の値をセットしておく」必要があります。
>> m.Map.Map_Move(Direction:=DirectCast(sender, Control).Tag)
> これもLabelはControlなので、上記を丁寧に書いたやり方だと理解出来ます。
下記いずれも、同じ結果が得られます。
Tag プロパティを実装しているのは Label ではなく、その親クラスである Control なので、
今回はあえて Control 型にキャストしてありますが、Label にキャストしても問題ありません。
(Label クラスは Control の Tag プロパティをそのまま受け継いでいます)
>> m.Map.Map_Move(Direction:=DirectCast(DirectCast(sender, Control).Tag, Map.Dir))
> これ!
> (Label)コントロールのタグをMap.Dirにキャストする???
sender 引数同様、Tag プロパティも As Object なデータ型なので、DirectCast あるいは CType が必要になります。
もしも sender に Label 以外が渡される可能性がある場合には、TryCast を使うこともできます。
> これはTagの内容を直接渡しているので、Tagの内容を
> Map.Dir.UpやMap.Dir.Downなどにすれば動作するとすぐ解りました。
Map_Move の引数が Direction As Object の場合には、
m.Map.Map_Move(Direction:=sender.Tag)
のままで構いませんが、恐らくは Direction As Map.Dir なのですよね。
sender 引数の型は As Object ですし、
Tag プロパティの型も As Object です。
初期設定では Option Strict Off モードでビルドされているので問題になりませんが、
Option Strict On モードでビルドされていた場合、
Map.Dir 型の仮引数に渡す値は、Object 側の値を実引数として渡すのではなく、
Map.Dir 型の実引数を渡す必要があります。そのため、 DirectCast を使って
データ型を揃えてやる必要があるというわけです。
なお、このパターンを実行する場合には、Form の Load イベントにおいて、
lblMovingUp.Tag = Map.Dir.Up
などのように、「Tag プロパティに Map.Dir 列挙型の値をセットしておく」必要があります。
>> m.Map.Map_Move(Direction:=DirectCast(sender, Control).Tag)
> これもLabelはControlなので、上記を丁寧に書いたやり方だと理解出来ます。
下記いずれも、同じ結果が得られます。
m.Map.Map_Move(Direction:=DirectCast(sender, Control).Tag)
m.Map.Map_Move(Direction:=DirectCast(sender, Label).Tag)
Tag プロパティを実装しているのは Label ではなく、その親クラスである Control なので、
今回はあえて Control 型にキャストしてありますが、Label にキャストしても問題ありません。
(Label クラスは Control の Tag プロパティをそのまま受け継いでいます)
>> m.Map.Map_Move(Direction:=DirectCast(DirectCast(sender, Control).Tag, Map.Dir))
> これ!
> (Label)コントロールのタグをMap.Dirにキャストする???
sender 引数同様、Tag プロパティも As Object なデータ型なので、DirectCast あるいは CType が必要になります。
もしも sender に Label 以外が渡される可能性がある場合には、TryCast を使うこともできます。
Dim lbl As Label = TryCast(sender, Label)
If lbl IsNot Nothing Then
Dim direction As Map.Dir = CType(lbl.Tag, Map.Dir)
m.Map.Map_Move(Direction:=direction)
End If
投稿者 (削除されました)  ()
投稿日時
2020/11/4 12:43:14
(削除されました)
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2020/11/4 12:35:32
> プログラム的には
> DirectCast(Sender,Label).BackColor
> …とした方がスマートなのかも知れませんが…
あるいは
Sub lblMoving_MouseEnter(sender As Object, e As EventArgs)
を
Sub lblMoving_MouseEnter(sender As Label, e As EventArgs)
に変更するという手もあります。
※ Option Strict Off の場合のみ有効
> DirectCast(Sender,Label).BackColor
> …とした方がスマートなのかも知れませんが…
あるいは
Sub lblMoving_MouseEnter(sender As Object, e As EventArgs)
を
Sub lblMoving_MouseEnter(sender As Label, e As EventArgs)
に変更するという手もあります。
※ Option Strict Off の場合のみ有効
投稿者 あせたけ  (社会人)
投稿日時
2020/11/4 11:41:30
オブジェクト指向…
奥が深い…
魔界の仮面弁士様のコードを参考にして…
------------------------------------------------------------------------------
Private Sub lblMoving_MouseEnter(sender As Object, e As EventArgs) Handles lblMovingUp.MouseEnter, lblMovingDown.MouseEnter, lblMovingLeft.MouseEnter, lblMovingRight.MouseEnter
Select Case sender.Tag
Case "UP"
lblMovingUp.BackColor = Color.LightPink
Case "DOWN"
lblMovingDown.BackColor = Color.LightPink
Case "LEFT"
lblMovingLeft.BackColor = Color.LightPink
Case "RIGHT"
lblMovingRight.BackColor = Color.LightPink
End Select
End Sub
------------------------------------------------------------------------------
これも…
↓
------------------------------------------------------------------------------
Private Sub lblMoving_MouseEnter(sender As Object, e As EventArgs) Handles lblMovingUp.MouseEnter, lblMovingDown.MouseEnter, lblMovingLeft.MouseEnter, lblMovingRight.MouseEnter
sender.BackColor = Color.LightPink
End Sub
------------------------------------------------------------------------------
こうなりましたw
プログラム的には
DirectCast(Sender,Label).BackColor
…とした方がスマートなのかも知れませんが…
奥が深い…
魔界の仮面弁士様のコードを参考にして…
------------------------------------------------------------------------------
Private Sub lblMoving_MouseEnter(sender As Object, e As EventArgs) Handles lblMovingUp.MouseEnter, lblMovingDown.MouseEnter, lblMovingLeft.MouseEnter, lblMovingRight.MouseEnter
Select Case sender.Tag
Case "UP"
lblMovingUp.BackColor = Color.LightPink
Case "DOWN"
lblMovingDown.BackColor = Color.LightPink
Case "LEFT"
lblMovingLeft.BackColor = Color.LightPink
Case "RIGHT"
lblMovingRight.BackColor = Color.LightPink
End Select
End Sub
------------------------------------------------------------------------------
これも…
↓
------------------------------------------------------------------------------
Private Sub lblMoving_MouseEnter(sender As Object, e As EventArgs) Handles lblMovingUp.MouseEnter, lblMovingDown.MouseEnter, lblMovingLeft.MouseEnter, lblMovingRight.MouseEnter
sender.BackColor = Color.LightPink
End Sub
------------------------------------------------------------------------------
こうなりましたw
プログラム的には
DirectCast(Sender,Label).BackColor
…とした方がスマートなのかも知れませんが…
投稿者 あせたけ  (社会人)
投稿日時
2020/11/4 11:27:28
>書き漏らしたので追記。
頭が混乱してきましたw
>m.Map.Map_Move(Direction:=sender.Tag)
これはTagの内容を直接渡しているので、Tagの内容を
Map.Dir.UpやMap.Dir.Downなどにすれば動作するとすぐ解りました。
>m.Map.Map_Move(Direction:=DirectCast(sender, Control).Tag)
これもLabelはControlなので、上記を丁寧に書いたやり方だと理解出来ます。
>m.Map.Map_Move(Direction:=DirectCast(DirectCast(sender, Control).Tag, Map.Dir))
これ!
(Label)コントロールのタグをMap.Dirにキャストする???
…とどうなるか今の私には想像が出来ません…
Public Enum Dir
None
Up
Down
Left
Right
End Enum
こうなっておりまして…
Enumにキャストする…
?????
勉強不足で理解不能です^^;
頭が混乱してきましたw
>m.Map.Map_Move(Direction:=sender.Tag)
これはTagの内容を直接渡しているので、Tagの内容を
Map.Dir.UpやMap.Dir.Downなどにすれば動作するとすぐ解りました。
>m.Map.Map_Move(Direction:=DirectCast(sender, Control).Tag)
これもLabelはControlなので、上記を丁寧に書いたやり方だと理解出来ます。
>m.Map.Map_Move(Direction:=DirectCast(DirectCast(sender, Control).Tag, Map.Dir))
これ!
(Label)コントロールのタグをMap.Dirにキャストする???
…とどうなるか今の私には想像が出来ません…
Public Enum Dir
None
Up
Down
Left
Right
End Enum
こうなっておりまして…
Enumにキャストする…
?????
勉強不足で理解不能です^^;
投稿者 あせたけ  (社会人)
投稿日時
2020/11/4 11:16:55
魔界の仮面弁士様
いつもお世話になります。
>VB には「Dir 関数」が標準で組み込まれているので、別の変数名にした方が良いかと思います。
良い変数名が思い浮かばずつい…^^:
>また、lblMovingUp と lblMovingUp が混在している点も気になりますし、
>If/ElseIf 句が lblMovingLeftthen / lblMovingRightthen なのに、
>Handles 句が lblMovingLeft / lblMovingRight なのも不自然ですね。
直接手打ちした為の入力ミスです^^;
ご容赦ください^^;;;
辞書を使って書く方法が一番スマートそうです。
Select Case Trueと言う書き方があると言う事も知る事が出来ました。
最近はオブジェクト指向のプログラムがある程度は書ける様にはなりましたが、
VB.NETが出来てからもしばらくはVB6.0で組んでいたもので、
オブジェクトについてはまだまだ勉強が足りないなと痛感しています^^;
このコードを見た時、目から鱗でした…w
ありがとうございました。
いつもお世話になります。
>VB には「Dir 関数」が標準で組み込まれているので、別の変数名にした方が良いかと思います。
良い変数名が思い浮かばずつい…^^:
>また、lblMovingUp と lblMovingUp が混在している点も気になりますし、
>If/ElseIf 句が lblMovingLeftthen / lblMovingRightthen なのに、
>Handles 句が lblMovingLeft / lblMovingRight なのも不自然ですね。
直接手打ちした為の入力ミスです^^;
ご容赦ください^^;;;
辞書を使って書く方法が一番スマートそうです。
Select Case Trueと言う書き方があると言う事も知る事が出来ました。
最近はオブジェクト指向のプログラムがある程度は書ける様にはなりましたが、
VB.NETが出来てからもしばらくはVB6.0で組んでいたもので、
オブジェクトについてはまだまだ勉強が足りないなと痛感しています^^;
このコードを見た時、目から鱗でした…w
ありがとうございました。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2020/11/4 11:11:35
書き漏らしたので追記。
m.Map.Map_Move(Direction:=sender.Tag)
'あるいは
m.Map.Map_Move(Direction:=DirectCast(sender, Control).Tag)
'あるいは
m.Map.Map_Move(Direction:=DirectCast(DirectCast(sender, Control).Tag, Map.Dir))
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2020/11/4 10:40:13
> Dim dir As Map.Dir
VB には「Dir 関数」が標準で組み込まれているので、別の変数名にした方が良いかと思います。
> 多:1のイベント処理で、通常は…
自分ならこう書きます。
> …と言う感じには書けないものでしょうか…
強いて言えば次のような書き方がありますが、参照の一致を見るのであれば、
Dictionary 等を使うか、If 判定した方が素直だと思います。
> タグネームを付けて処理させて例(これはエラーは出ず、期待通りに処理する)
Tag プロパティは Object 型のプロパティです。
デザイン時には文字列しかセットできませんが、実際には任意のデータを格納できますから、
Load イベントなどで最初から Map.Dir 型の値を Tag にセットしておけば、下記のように書けますよ。
VB には「Dir 関数」が標準で組み込まれているので、別の変数名にした方が良いかと思います。
また、lblMovingUp と lblMovingUp が混在している点も気になりますし、
If/ElseIf 句が lblMovingLeftthen / lblMovingRightthen なのに、
Handles 句が lblMovingLeft / lblMovingRight なのも不自然ですね。
If/ElseIf 句が lblMovingLeftthen / lblMovingRightthen なのに、
Handles 句が lblMovingLeft / lblMovingRight なのも不自然ですね。
> 多:1のイベント処理で、通常は…
自分ならこう書きます。
Private Direction As New Dictionary(Of Object, Map.Dir)()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Direction.Add(lblMovingUp, Map.Dir.Up)
Direction.Add(lblMovingDown, Map.Dir.Down)
Direction.Add(lblMovingLeft, Map.Dir.Left)
Direction.Add(lblMovingRight, Map.Dir.Right)
End Sub
Private Sub lblMoving_Click(sender As Object, e As EventArgs) Handles lblMovingUp.Click, lblMovingDown.Click, lblMovingLeft.Click, lblMovingRight.Click
m.Map.Map_Move(Direction:=Direction(sender))
End Sub
> …と言う感じには書けないものでしょうか…
強いて言えば次のような書き方がありますが、参照の一致を見るのであれば、
Dictionary 等を使うか、If 判定した方が素直だと思います。
Select Case True
Case sender Is lblMovingUp
dir = Map.Dir.Up
Case sender Is lblMovingDown
dir = Map.Dir.Down
End Select
' https://github.com/dotnet/vblang/issues/568
> タグネームを付けて処理させて例(これはエラーは出ず、期待通りに処理する)
Tag プロパティは Object 型のプロパティです。
デザイン時には文字列しかセットできませんが、実際には任意のデータを格納できますから、
Load イベントなどで最初から Map.Dir 型の値を Tag にセットしておけば、下記のように書けますよ。
m.Map.Map_Move(Direction:=sender.Tag)
'あるいは
m.Map.Map_Move(Direction:=DirectCast(sender, Control).Tag)
投稿者 (削除されました)  ()
投稿日時
2020/11/4 10:32:44
(削除されました)
投稿者 (削除されました)  ()
投稿日時
2020/11/4 10:31:28
(削除されました)
投稿者 あせたけ  (社会人)
投稿日時
2020/11/3 16:23:19
雑談的と言うか…技術的と言うか…な話題になりますが…^^;
多:1のイベント処理で、通常は…
Private Sub lblMoving_Click(sender As Object, e As EventArgs) Handles lblMovingUp.Click, lblMovingDown.Click, lblMovingLeft.Click, lblMovingRight.Click
Dim dir As Map.Dir
If sender Is lblMovingUp Then
dir = Map.Dir.Up
ElseIf sender Is lblMovingDown then
dir = Map.Dir.Down
ElseIf sender Is lblMovingLeftthen
dir = Map.Dir.Left
ElseIf sender Is lblMovingRightthen
dir = Map.Dir.Right
End If
m.Map.Map_Move(Direction:=dir)
End Sub
…とするところを…
Private Sub lblMoving_Click(sender As Object, e As EventArgs) Handles lblMovingUp.Click, lblMovingDown.Click, lblMovingLeft.Click, lblMovingRight.Click
Dim dir As Map.Dir
Select Case sender
Case lblMovingUp
dir = Map.Dir.Up
Case lblMovingDown
dir = Map.Dir.Down
Case lblMovingLeft
dir = Map.Dir.Left
Case lblMovingRight
dir = Map.Dir.Right
End Select
m.Map.Map_Move(Direction:=dir)
End Sub
…と言う感じには書けないものでしょうか…
(ちなみにこのままではSystem.InvalidCastExeptionが出ます)
Select Case CType(sender,Label) …としてみましたが、今度は「演算子 '=' は、型 'Label' に対して定義されていません…と出ます。
素直にタグネームを入れてやれよと言う話もあるとは思いましたが、
気になりましたので、投稿させて頂きました^^;
<参考>タグネームを付けて処理させて例(これはエラーは出ず、期待通りに処理する)
Private Sub lblMoving_Click(sender As Object, e As EventArgs) Handles lblMovingUp.Click, lblMovingDown.Click, lblMovingLeft.Click, lblMovingRight.Click
Dim dir As Map.Dir
Select Case sender.Tag
Case "UP"
dir = Map.Dir.Up
Case "DOWN"
dir = Map.Dir.Down
Case "LEFT"
dir = Map.Dir.Left
Case "RIGHT"
dir = Map.Dir.Right
End Select
m.Map.Map_Move(Direction:=dir)
End Sub
多:1のイベント処理で、通常は…
Private Sub lblMoving_Click(sender As Object, e As EventArgs) Handles lblMovingUp.Click, lblMovingDown.Click, lblMovingLeft.Click, lblMovingRight.Click
Dim dir As Map.Dir
If sender Is lblMovingUp Then
dir = Map.Dir.Up
ElseIf sender Is lblMovingDown then
dir = Map.Dir.Down
ElseIf sender Is lblMovingLeftthen
dir = Map.Dir.Left
ElseIf sender Is lblMovingRightthen
dir = Map.Dir.Right
End If
m.Map.Map_Move(Direction:=dir)
End Sub
…とするところを…
Private Sub lblMoving_Click(sender As Object, e As EventArgs) Handles lblMovingUp.Click, lblMovingDown.Click, lblMovingLeft.Click, lblMovingRight.Click
Dim dir As Map.Dir
Select Case sender
Case lblMovingUp
dir = Map.Dir.Up
Case lblMovingDown
dir = Map.Dir.Down
Case lblMovingLeft
dir = Map.Dir.Left
Case lblMovingRight
dir = Map.Dir.Right
End Select
m.Map.Map_Move(Direction:=dir)
End Sub
…と言う感じには書けないものでしょうか…
(ちなみにこのままではSystem.InvalidCastExeptionが出ます)
Select Case CType(sender,Label) …としてみましたが、今度は「演算子 '=' は、型 'Label' に対して定義されていません…と出ます。
素直にタグネームを入れてやれよと言う話もあるとは思いましたが、
気になりましたので、投稿させて頂きました^^;
<参考>タグネームを付けて処理させて例(これはエラーは出ず、期待通りに処理する)
Private Sub lblMoving_Click(sender As Object, e As EventArgs) Handles lblMovingUp.Click, lblMovingDown.Click, lblMovingLeft.Click, lblMovingRight.Click
Dim dir As Map.Dir
Select Case sender.Tag
Case "UP"
dir = Map.Dir.Up
Case "DOWN"
dir = Map.Dir.Down
Case "LEFT"
dir = Map.Dir.Left
Case "RIGHT"
dir = Map.Dir.Right
End Select
m.Map.Map_Move(Direction:=dir)
End Sub
>Sub lblMoving_MouseEnter(sender As Label, e As EventArgs)
こう言う書き方も出来るのですね!
>恐らくは Direction As Map.Dir なのですよね。
はい、そうです。
>Tag プロパティを実装しているのは Label ではなく、その親クラスである Control なので、
>今回はあえて Control 型にキャストしてありますが、Label にキャストしても問題ありません。
>(Label クラスは Control の Tag プロパティをそのまま受け継いでいます)
どこからの派生クラスかと言うのも知っていた方が良いみたいですね^^;;;;
>> (Label)コントロールのタグをMap.Dirにキャストする???
------------------------------------------------------------------------------
Dim lbl As Label = TryCast(sender, Label)
If lbl IsNot Nothing Then
Dim direction As Map.Dir = CType(lbl.Tag, Map.Dir)
m.Map.Map_Move(Direction:=direction)
End If
------------------------------------------------------------------------------
Control←Labelの説明と、上記のソースコードで何となく理解できました。