Click here to Skip to main content
15,887,477 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Ok I have built a class that produces rectangles
30 of them in a 3 groups of 10.

What I am having issue with is ?
when I instantiate say a local copy

example:
VB
Dim betline1 As New TicketGroupNodeControl

           betline1.NewNumericUpAndDownXValue() = NumericUpDown1.Value
           betline1.NewNumericUpAndDownYValue() = NumericUpDown2.Value
           betline1.NewNumericUpAndDownXXValue() = NumericUpDown3.Value
           betline1.NewNumericUpAndDownYYValue() = NumericUpDown4.Value

           betline1.FibTrainerOhioPk3BetLineNodeGroup()

           For i = 0 To betline1.BetLineNodeGroup.Length - 1
               e.Graphics.DrawRectangle(Pens.Blue, betline1.BetLineNodeGroup(i))
               e.Graphics.FillRectangle(Brushes.Blue, betline1.BetLineNodeGroup(i))

           Next i


When i try to use mouse event args
it requires me to have to declare betline1 variable globally in order for it to work.
When trying to use mousedown and mousemove.

What I am trying to accomplish is being able to select the first rectangle in the group and drag it to location using the mouse.

What I have tried:

This actually worked but as i stated it requires me to make the variable global.
I need it to remain local so when its not being used it doesnt exist.

I will possibly have 100s of these copys for different setups .
but only say 10 setups will be active at any given time.


VB
Private Sub RadDiagram1_MouseMove(sender As Object, e As MouseEventArgs) Handles RadDiagram1.MouseMove
       Label1.Text = "X:" & e.X.ToString & "     " & "Y:" & e.Y.ToString

       'If e.Button = Windows.Forms.MouseButtons.Left AndAlso betConfig1.BetConfigNodeGroup(0).Contains(e.Location) Then
       '    NumericUpDown21.Value = e.X + x
       '    NumericUpDown22.Value = e.Y + y
       '    RadDiagram1.Invalidate()
       'End If



VB
Private Sub RadDiagram1_MouseDown(sender As Object, e As MouseEventArgs) Handles RadDiagram1.MouseDown
       'If e.Button = Windows.Forms.MouseButtons.Left AndAlso betConfig1.BetConfigNodeGroup(0).Contains(e.Location) Then
       '    x = NumericUpDown21.Value - e.X
       '    y = NumericUpDown21.Value - e.Y
       'End If
   End Sub


If I make betconfig1 a global this works.

How can i add it to a class or possibly add a handler of some sort .

Can some one give me an example of how i can still call the mouse argument from an instant of a class that I instantiate in the paint routine of picturebox1 or "raddiagram 1"

When I try to use this variable to fire the mousemove event . I cannot use this variable in that sub because it was local in the paint routine.

Any help would be appreciated.
I am completely self taught and just hung not for sure which way to head to read my way out of this problem.

Thanks Jeff
Posted
Updated 27-Jan-17 17:15pm
v2

1 solution

It depends on where you mouse event is being triggered - if it's part of the TicketGroupNodeControl, then the instance of the control that triggered the event is passed to you in the sender parameter of the event handler - all you have to do is cast it to the appropriate type and use it.
If it isn't, then the control that the mouse was over when the button was clicked will be supplied - so if your group control contains the controls you are searching in the comments, then it's already available via the sender parameter.

Use the debugger, and have a look at the parameter - it may help you work out what is going on.


am not sure what your talking about there ?
I am using a class and creating an instance of this class in side of the paint routine of picturebox1 say.

This is in paint
VB
Dim betline1 As New TicketGroupNodeControl


Then after I have drawn the 30 rectangles .

I am wanting to use the mousedown event and mousemove event
to check if the mouse pointer is in the first rectangle.contains(e.location) when the left mouse button is pressed .
If so drag the square then update the location when released.

But when I use the mouse event args.
betline1.variable or instance is not valid in this scope. because it was created in paint sub.

I guess my question is how do i pass this on to allow the mouse events to work .



OK...we're going to have to go back a couple of steps here, because what you are trying to do is not correct!

The first thing is that you should not create your objects in the Paint event handler, for two reasons:
1) It needs to be as short and "snappy" as it can or it will impact your UI badly.
2) Paint is a "frequent flyer" event - it gets triggered a lot: every single time the system needs to show the user a change.

Which means that your objects for display should not be created in the Paint event - they need to be ready when the Paint event is handled. Think about it: when you "drag" one of your squares, you need the paint event handled in order to show it moving! :laugh:

So start off by creating your squares in the container for your squares (probably your form, but I'd use a UserControl myself - don't worry about that, you'll come to them later).
Your squares need to be available inside the Paint event (so they can be drawn) and inside other events as well - MouseDown and MouseMove need them as well - otherwise they can't all work together to move and display your items.
So create your squares as part of the containing class - probably the form - and use them in the handlers. Look at adding the squares as part of the Form.Shown event and call Invalidate when you want to update the display.
Does that make sense?
 
Share this answer
 
v2
Comments
OriginalGriff 27-Jan-17 8:38am    
So you are after the rectangles that should be drawn on the PictureBox in the PB.Paint event?
If so, then I'd add a List of shapes, and set the PictureBox.Tag property to that list. Every Control has a Tag property which is there for you are "associate" information with that particular control instance. That way, you can have two PictureBox controls, each with separate Lists of the shapes they should draw in the paint event.
Does that make sense?
OriginalGriff 28-Jan-17 5:13am    
Answer updated - I needed the space! :laugh:
Jeffrey Watkins 28-Jan-17 7:28am    
Ok let me try and explain it better.

I have a class that has the properties and the method to draw the 30
rectangles all in a group that can be moved x & Y also can expand evenly away from each other x & Y

They are in an array of rectangles()0 through 29.

When I create an instance of this object from my rectangle class
"Dim betline1 As New TicketGroupNodeControl"

betline1.NewNumericUpAndDownXValue() = NumericUpDown1.Value
betline1.NewNumericUpAndDownYValue() = NumericUpDown2.Value
betline1.NewNumericUpAndDownXXValue() = NumericUpDown3.Value
betline1.NewNumericUpAndDownYYValue() = NumericUpDown4.Value

betline1.FibTrainerOhioPk3BetLineNodeGroup()

For i = 0 To betline1.BetLineNodeGroup.Length - 1
e.Graphics.DrawRectangle(Pens.Blue, betline1.BetLineNodeGroup(i))
e.Graphics.FillRectangle(Brushes.Blue, betline1.BetLineNodeGroup(i))

Next i
This all has to be in paint event
because its a local variable

the only option i have is to just create global variables for every instance which will force me to have 100s of instance variables already declared.
that depending on the user settings may or may not be selected.

Is there no way I can pass this off or created mouse arguments within the class to accommodate the behavior i need ?

After all rectangles are set in their proper place.
these locations will be recorded and saved .

I am just trying to add a little more functionality to enable the user to grab the top left rectangle in order to drag the entire group in place quicker then use the numeric keys to fine tune the group in to their proper place.

Also this is to design the layout of a ticket.
there is at least 7 groups of 30 per ticket.
depending on the ticket layout is which groups will be called to the designer..

so i created a class so i could have reusable code .
and only create the variable when needed?

does this make sense?
OriginalGriff 28-Jan-17 7:43am    
Right ... I think I see.
The way I would do it is to create a UserControl which contains and draws the rectangles. That has nothing to do with the form - this is your NewTicketGroupNodeControl and it draws the rectangles in it's Paint event, they aren't drawn in the containers Paint event.
When the properties you show get changed, that causes the control to Invalidate itself, which forces itself to redraw.
The instance of the UserControl is dropped on the Form (or other container) surface, not created in the Form.Paint, just as all other controls are. Otherwise, every time you move the main window, or drag another app over the top, Windows will call the Paint event handler and that will create new instances each time. You don't want that, any more than you want to create a new instance of a button or textbox every time Windows needs you to repaint your user interface!
The UserControl handles the MouseDown and MouseMove events to move itself within it's container - it doesn't need to worry about the rectangles because they are drawn automatically via it's Paint event when needed.

You don't have to have them as instance variables in you need more that one group of rectangles as you can just create them at run time (via the Load or Shown methods) and add them to the container's Controls collection - which will automatically generate the Paint events for each as necessary. Each individual instance will then process the Mouse events for itself, rather than the Form doing it for them.

I know that isn't what you've got at the moment, but that is the way you want to go.
Jeffrey Watkins 28-Jan-17 21:17pm    
oh Ok so if I understand your approach would be to say create a user control that is a picturebox and add the code for it inside of user control.
Because it would have its own paint event gotcha .
Its worth a try .
I will give this a shot.

Thanks for the Idea

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900