Click event "through" a control
:wave:Good evening yall,
I have a simple question about a complex problem. Let me describe my scenario here. I have a picturebox control that graphically represents an eight by eight grid. Each tile/box on the grid is 60 x 60. So I am able to generate tile/box location on a mouse click event based off of X and Y because the entire grid is 480 x 480.
However, I create labels during runtime that populate .bringtofront on the grid. If the user clicks on the label that exists on top of the grid I end up storing the X and Y from the generated label, not the grid, which throws my two deminsional location array off. So my simple question is...
Is there a way to generate a control on top of a control but make it uninteractable? I want to grab the mouse cordinates from my picbox grid, not the labels.
Any suggestions? I can post code if need be but I didn't see any reason to, I need information on how, not instruction on what is wrong.
I've searched the codebank and previous posts and didn't find anything remotely close to what I am looking for.
Thanks guys.
Re: Click event "through" a control
That's not the way to approach it. If you want to get the current mouse pointer location relative to a specific control then that's exactly what you should do. If you already have the mouse pointer location relative to ControlA and you want it relative to ControlB then it's two method calls:
vb.net Code:
ptB = ControlB.PointToClient(ControlA.PointToScreen(ptA))
This assumes that both controls have the same parent. If that's not the case then you need to allow for that.
Re: Click event "through" a control
Ahhhh, .enabled. Now I just need to figure out if there is a way to disable a control and NOT grey it out. You know, I don't even know why I buy books for this. All you need is the reference, code bank, and expertise on this site to answer questions regarding syntax problems or breaking new ground! I love this site. Daniweb, DreaminCode, and all the others should just quiver from the shear awesomeness contained here.
Re: Click event "through" a control
Even better JM, thanks. I'll experiment with that.
Re: Click event "through" a control
Ok I'm attempting to use the .PointToClient but I think I'm screwing the implementation. Would I want to use it like so? This is what I have so far.
vb Code:
Dim locMousePos As Point
If e.Location = picBoard.Location Then
XAxis = e.X
YAxis = e.Y
Else
locMousePos = picBoard.PointToClient(Cursor.Position)
XAxis = locMousePos.X
YAxis = locMousePos.Y
End If
I pretty much want the mouse click event to be tested for which control it is clicked on. If it isn't clicked on my grid then I want those cords passed to the parent control (my grid) right?
Re: Click event "through" a control
Anyone have links to documentation instructing on the use of PointToClient. I just can't seem to implement it correctly.
Re: Click event "through" a control
I'm sure you can find it in MSDN, but it's hardly complicated. PointToClient converts a screen coordinate into any control's Clientarea coordinates. PointToScreen does the opposite.
Suppose you are on a Form that has Location = 100, 100. The ClientRectangle's location, the part inside the borders, might be 104, 130 (in screen coordinates, 0, 0 in Client coordinates).
vb.net Code:
Dim p1 As New Point(150, 150) 'a location in screen coordinates
p2 = Me.PointToClient(p) 'a location in Form coordinates
and the result for p2 is: x = 150 - 104 = 46, y = 150 - 130 = 20.
Every control has a PointToClient function and it gives you the location of a screen point relative to that particular control. For example PictureBox1.PointToClient gives the position relative to PictureBox1 (excluding border).
If you are coding the MouseDown or MouseMove sub for PictureBox1, e.Location also gives you the position in the picture box. Usually those are the coordinates you need in those subs.
MousePosition gives you the cursor position in screen coordinates. That's often useful too. Windows.Forms.Cursor.Position is the same.
Any more questions:)?
BB
Re: Click event "through" a control
It is exactly what jmc told you. The following example has 9 labels on top of a picture box.
Code:
Private Sub LabelClicks(ByVal sender As System.Object, _
ByVal e As System.EventArgs)
'sender is the label clicked
Dim PBpoint As Point = DirectCast(sender, Label).PointToScreen(PictureBox1.Location)
'at this point PBpoint has the coordinates to the location in the PictureBox
Debug.WriteLine(PBpoint.X.ToString & " " & PBpoint.Y.ToString)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
'add handler LabelClicks for all of the labels
For Each c In Me.Controls
If TypeOf c Is Label Then
AddHandler (DirectCast(c, Label).Click), AddressOf LabelClicks
End If
Next
End Sub
Re: Click event "through" a control
By the way, here's a tip for anyone who gets confused about mouse coordinates. Paste this into the MouseMove event of any panel, picture box or other control control:
Code:
Dim ctrl As Control = CType(sender, Control)
Me.Text = "MousePosition (screen) = " & MousePosition.ToString & _
" ; Form Position = " & Me.PointToClient(MousePosition).ToString & _
" ; e.Location (" & ctrl.Name.ToString & ") = " & e.Location.ToString
Me.Invalidate()
If you want it to work for several controls or for the whole form, just add them to the sub's Handles clause:
Code:
Handles Me.MouseMove, PictureBox1.MouseMove, Panel2.MouseMove
It helped me out quite a bit when I started VB.Net.
BB
Re: Click event "through" a control
Thank you for all your helps guys, here is my final first time implementation, it works perfectly for me. It may look funky but it yields the correct data!:
vb Code:
Dim chipPoint As Point
Dim boardPoint As Point
Dim testlabel As Windows.Forms.Label
testlabel = DirectCast(sender, Label)
Dim a As Point
a.X = e.X
a.Y = e.Y
chippoint = testlabel.PointToScreen(a)
boardPoint = testlabel.Parent.PointToClient(chipPoint)
frmBoard.XAxis = boardPoint.X
frmBoard.YAxis = boardPoint.Y
I learned quite a bit about the Z order while doing this and how to use what I think is the equiv to VB pointers "AddressOf" with the information you great guys helped me out with and MSDN help I was able to not only create the labels during runtime but also add a handler for mouseclick that provided the client cords. Thanks so much, here is my creation code for the labels also.
vb Code:
If checked = "Green" Then
For counter = 1 To 12
Dim x As Integer
Dim y As Integer
Dim gameTile As Integer
gameTile = LoadRedTop(counter - 1)
detTileCords(gameTile, x, y)
Dim testlabel As New Windows.Forms.Label
With testlabel
.Name = "testlabel" & counter
.Image = Image.FromFile("..\checkerGreentileRed.gif")
.AutoSize = False
.Size = New Size(40, 40)
.Parent = frmBoard.picBoard
.Visible = True
.BringToFront()
.Location = New Point(x, y)
End With
AddHandler testlabel.MouseClick, AddressOf getMouseCords
gameTile = 0
x = 0
y = 0
Next
End If
Thanks so much, everyone is rated great in my book!
Re: Click event "through" a control
Mark thread resolved and take your signatures advice.
Re: Click event "through" a control
Thank you for your concern dbasnett but I prefer to keep threads I start open until I know that I won't have any other questions regarding issues related... Much like this new issue.
As my first post states I have a checker board which is placed in a single picturebox and I use the X and Y to get position for the board. However, I create my checkers at runtime with the following code:
vb Code:
'Load the board with green chips on the red tiles
If color = "green" And tile = "red" Then
For counter = 1 To 12
Dim x As Integer
Dim y As Integer
Dim gameTile As Integer
gameTile = LoadRedBottom(counter - 1)
detTileCords(gameTile, x, y)
Dim testlabel As New Windows.Forms.Label
With testlabel
.Name = "testlabel" & counter
.Image = Image.FromFile("..\checkerGreentileRed1.gif")
.AutoSize = False
.Size = New Size(40, 40)
.Parent = frmBoard.picBoard
.Visible = True
.BringToFront()
.Location = New Point(x, y)
End With
AddHandler testlabel.MouseClick, AddressOf getMouseCords
gameTile = 0
x = 0
y = 0
Next
When these "checker pieces are created they are placed on the picturebox. When I started doing this I needed a lil help with the PointToClient/PointToScreen method so I could get the right X and Y for the board and everything has worked out great with that thus far. The code:
vb Code:
Public Sub getMouseCords(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Dim chipPoint As Point
Dim boardPoint As Point
Dim testlabel As Windows.Forms.Label
testlabel = DirectCast(sender, Label)
Dim a As Point
a.X = e.X
a.Y = e.Y
chipPoint = testlabel.PointToScreen(a)
boardPoint = testlabel.Parent.PointToClient(chipPoint)
frmBoard.XAxis = boardPoint.X
frmBoard.YAxis = boardPoint.Y
End Sub
Now that I have pieced the board together a little more and worked out kinks I have come to another problem that concerns getting BACK to the labels that are created for checker pieces. See there is a single control on the form that is clickable and that is the picturebox which houses the board image. When the board is loaded/initialized and checkers pop up my picturebox.Mouseclick event becomes useless as I click on the labels because it isn't the picturebox that is receiving the event. So in reality its working how it should hehe. I've looked around, read about simulated mouse clicks and other methodologies that I could use but somehow I think there is a method that I could use to click on any label (game piece) and make the board think it has been clicked. Any suggestions?
Re: Click event "through" a control
"When the board is loaded/initialized and checkers pop up my picturebox.Mouseclick event becomes useless as I click on the labels because it isn't the picturebox that is receiving the event. So in reality its working how it should hehe. I've looked around, read about simulated mouse clicks and other methodologies that I could use but somehow I think there is a method that I could use to click on any label (game piece) and make the board think it has been clicked. Any suggestions?"
Lets see if I understand:
1 - You have a picturebox for the board
2 - When an empty spot on the board is clicked you add a checker (label)
3 - When a checker is clicked you want it to receive the click and also have the picture box receive the click
Is that about right?
Re: Click event "through" a control
Close.
#1 is correct.
#2 The checkers are loaded when the color and side is selected. It is a button click event that loads all 24 game pieces onto the board. I have not gotten to the "jump" function yet. I'll hammer that out after all this is handled.
#3 is the problem. When the checker is clicked, which is a label, the game board (a picture box control) event which controls mouse.click isn't called. And by all rights it should not be. However, that is where I am managing the mouse clicks from. I don't know how to produce a condition inside an event that uses the object that the event is handled for. Let me throw this down in pseudo showing the actual event and what I am attempting to do, that may help.
vb Code:
Private Sub picBoard_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picBoard.MouseClick
If picBoard recieves Mouse.click Then
do stuff....
Else
do stuff....
End If
End Sub
I don't think I can do that, but alas I do not know. However, when I try to increase the scope of the mouseclick to form wide I can't do so by drop down. Do I need to create my own custom event that evaluates which control is clicked on the board? I read JM's blog about "making custom events and calls" but I don't know if that is what I need to do.
I hope this helps bro.
Re: Click event "through" a control
Building on post #8
Code:
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
'add handler LabelClicks for all of the labels
For Each c In Me.Controls
If TypeOf c Is Label Then
AddHandler (DirectCast(c, Label).Click), AddressOf LabelClicks
End If
Next
End Sub
Private Sub LabelClicks(ByVal sender As System.Object, _
ByVal e As System.EventArgs)
'sender is the label clicked
Debug.WriteLine(DirectCast(e, MouseEventArgs).X & " " & DirectCast(e, MouseEventArgs).Y)
Dim PBpoint As Point = DirectCast(sender, Label).PointToScreen(PictureBox1.Location)
'at this point PBpoint has the coordinates to the location in the PictureBox
Dim mea As MouseEventArgs = _
New MouseEventArgs(Windows.Forms.MouseButtons.Left, 1, PBpoint.X, PBpoint.Y, 1)
PictureBox1_Click(sender, mea)
End Sub
Private Sub PictureBox1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles PictureBox1.Click
Debug.WriteLine(DirectCast(e, MouseEventArgs).X & " " & DirectCast(e, MouseEventArgs).Y)
End Sub
Re: Click event "through" a control
ok give me a minute to absorb this and work it into my board init. I'll be back to ya.
Re: Click event "through" a control
Thanks for all of your help. We are good to go.