Suggestion for a time grid? - vb.net

In VB.NET I'm looking to build a "Time" grid very similar to the Time Restriction grid of the Parental Section of Windows: http://www.thinkbroadband.com/images/guides/time-restrictions.png
It needs to toggle between 2 colors on cell-click
I've played around with One-Cell = One-Label and it kinda works but, like the Windows Time Restriction grid, I'd like to have the labels change colors if I move over the label whilst having the left button pressed (and not only on label click).
Here is what I currently have:
Private Sub ColorToggle(sender As Object, e As MouseEventArgs) Handles Label1.Click, Label2.Click, Label3.Click 'etc..
If e.Button = Windows.Forms.MouseButtons.Left Then
sender.backcolor = If(sender.backcolor = SystemColors.Control, Color.LightGreen, SystemColors.Control)
End If
End Sub
Since the sender stays the same when I hover the labels (sender = label I've originally clicked on), this code doesn't work for my purpose.
I'm looking for suggestions!
Thanks :)

When you click on a control and you hold the mouse button down, this control captures the following mouse events, so that you won't get events from the other lables when moving the mouse over them.
The trick is to set label.Capture = False.
Lets define colors:
Private ReadOnly selectedColor As Color = Color.Blue
Private ReadOnly unselectedColor As Color = Color.White
And Booleans storing the current state of our operations
Private isSelecting As Boolean = False
Private isUnselecting As Boolean = False
(All four as fields of the form class)
Now lets write these three event handlers:
Private Sub Label_MouseDown(sender As Object, e As EventArgs)
'This event starts selecting/unselecting
Dim label = DirectCast(sender, Label)
label.Capture = False '<=== THIS IS IMPORTANT!
If label.BackColor = selectedColor Then
isUnselecting = True
Else
isSelecting = True
End If
SelectLabel(label)
End Sub
Private Sub Label_MouseUp(sender As Object, e As EventArgs)
'This event stops selecting/unselecting
isSelecting = False
isUnselecting = False
End Sub
Private Sub Label_MouseEnter(sender As Object, e As EventArgs)
SelectLabel(DirectCast(sender, Label))
End Sub
And we need this procedure that selects or unselects the labels:
Private Sub SelectLabel(label As Label)
If isSelecting Then
label.BackColor = selectedColor
ElseIf isUnselecting Then
label.BackColor = unselectedColor
End If
End Sub
That's it!
Footnote: I have created the lables like this:
Private Sub Form_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Const w As Integer = 50, h As Integer = 50
For x = 1 To 10
For y = 1 To 10
Dim lbl As New Label() With {
.Location = New Point(x * w, y * h),
.Size = New Size(w, h),
.BorderStyle = BorderStyle.FixedSingle,
.BackColor = unselectedColor
}
AddHandler lbl.MouseDown, AddressOf Label_MouseDown
AddHandler lbl.MouseUp, AddressOf Label_MouseUp
AddHandler lbl.MouseEnter, AddressOf Label_MouseEnter
Controls.Add(lbl)
Next
Next
End Sub

I hope this isn't homework...
Private Sub Button8_Click(sender As Object, e As EventArgs) Handles Button8.Click
Dim i As Integer
With dgv
.ColumnCount = 0
.DataSource = Nothing
.Columns.Add("Day", "Day")
For i = 0 To 23
.Columns.Add(i, i)
.Columns(.Columns.Count - 1).Width = 30
Next
For i = 1 To 7
.Rows.Add({i})
Next
End With
End Sub
Private Sub dgv_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgv.CellClick
dgv.CurrentCell.Style.BackColor = Color.Blue
End Sub
Here is a drag version:
Private Sub dgv_MouseUp(sender As Object, e As MouseEventArgs) Handles dgv.MouseUp
For Each cell As DataGridViewCell In dgv.SelectedCells
If cell.Style.BackColor = Color.Blue Then
cell.Style.BackColor = Color.White
Else
cell.Style.BackColor = Color.Blue
End If
Next
dgv.ClearSelection()
End Sub

Related

Get variable for two clicks on form

I am trying to assign two clicks to two variables on my Mouse_Down event on my form. Here is the starting code I am working with on Mouse_Down event. What I am trying to do is click two points on a form, get the X & Y location (these will then give me my button size). Example: First Click get X & Y, Second Click get X & Y then perform click of a button.... repeat this until I quit.
Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles MyBase.MouseDown
Dim XYClickOne, XYClickTwo
Dim count As Integer
count = 0
Do
XYClickOne = e.X & "," & e.Y
XYClickTwo = e.X & "," & e.Y
count = count + 1
Loop Until count = 2
Button1.PerformClick() 'After 2nd click, create button.
End Sub
Move those variables out to Form level so they are accessible by other methods, and will persist across clicks. Here's a quick example:
Public Class Form1
Private points(2) As Point
Private count As Integer = 0
Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
If e.Button = MouseButtons.Left Then
points(count) = New Point(e.X, e.Y)
count = count + 1
If count = 2 Then
count = 0
CreateButton(points(0), points(1))
End If
End If
End Sub
Private Sub CreateButton(ByVal ptA As Point, ByVal ptB As Point)
Dim pt As New Point(Math.Min(ptA.X, ptB.X), Math.Min(ptA.Y, ptB.Y))
Dim sz As New Size(Math.Abs(ptA.X - ptB.X) + 1, Math.Abs(ptA.Y - ptB.Y) + 1)
Dim btn As New Button
btn.Bounds = New Rectangle(pt, sz)
btn.Text = "X"
Me.Controls.Add(btn)
End Sub
End Class
Thought you might like a quick example of making a "rubber band selection". Click and DRAG on your form with the left mouse button:
The artifacts are from my screen recorder, in reality it drew smoothly with out leaving lines behind:
Code:
Public Class Form1
Private ptA, ptB As Point
Private count As Integer = 0
Private firstBoxDrawn As Boolean = False
Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
If e.Button = MouseButtons.Left Then
ptA = Me.PointToScreen(New Point(e.X, e.Y))
ptB = ptA
firstBoxDrawn = False
End If
End Sub
Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
If e.Button = MouseButtons.Left Then
If firstBoxDrawn Then
' erase the previous box by drawing it again
ControlPaint.DrawReversibleFrame(RectangleFromPoints(ptA, ptB), Color.Black, FrameStyle.Dashed)
End If
ptB = Me.PointToScreen(New Point(e.X, e.Y))
' draw the new box
ControlPaint.DrawReversibleFrame(RectangleFromPoints(ptA, ptB), Color.Black, FrameStyle.Dashed)
firstBoxDrawn = True
End If
End Sub
Private Sub Form1_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
If e.Button = MouseButtons.Left Then
' erase the box
ControlPaint.DrawReversibleFrame(RectangleFromPoints(ptA, ptB), Color.Black, FrameStyle.Dashed)
CreateButton(Me.PointToClient(ptA), Me.PointToClient(ptB))
End If
End Sub
Private Sub CreateButton(ByVal ptA As Point, ByVal ptB As Point)
Dim btn As New Button
btn.Text = "X"
btn.Bounds = RectangleFromPoints(ptA, ptB)
Me.Controls.Add(btn)
End Sub
Private Function RectangleFromPoints(ByVal ptA As Point, ByVal ptB As Point) As Rectangle
Dim pt As New Point(Math.Min(ptA.X, ptB.X), Math.Min(ptA.Y, ptB.Y))
Dim sz As New Size(Math.Abs(ptA.X - ptB.X) + 1, Math.Abs(ptA.Y - ptB.Y) + 1)
Return New Rectangle(pt, sz)
End Function
End Class

Change size of brush in a menustrip to draw different sizes in Visual Basic

Okay, I am currently have an app where I can draw on it. I use radio buttons to select the color and drawing size of the "Pen" for the drawing. I would like to get rid of these radio buttons and use a MenuStrip on a MDI form to affect the color and size of the pen on a new child form within the MDI form.
Currently, this is what I have for the form that I can draw on that includes the radio buttons.
Public Class Form1
Private shouldPaint As Boolean = False
Dim paintColor As Color
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.MdiParent = ParentMdiForm
'Color Radio Buttons
Me.redRadio.Tag = Color.Red
Me.blueRadio.Tag = Color.Blue
Me.greenRadio.Tag = Color.Green
Me.blackRadio.Tag = Color.Black
Me.blackRadio.Checked = True
'Size Radio Buttons
Me.smallRadio.Checked = True
End Sub
'Draw while mouse button is pressed
Private Sub Painter_MouseDown(sender As Object, e As MouseEventArgs) Handles MyBase.MouseDown
shouldPaint = True
End Sub
'Stop drawing when mouse button is not pressed
Private Sub Painter_MouseUp(Sender As Object, e As MouseEventArgs) Handles MyBase.MouseUp
shouldPaint = False
End Sub
'Change the size of the pen
Private Sub Painter_MouseMove(sender As Object, e As MouseEventArgs) Handles MyBase.MouseMove
If (shouldPaint) Then
If smallRadio.Checked = True Then
Using g As Graphics = CreateGraphics()
g.FillEllipse(New SolidBrush(paintColor), e.X, e.Y, 4, 4)
End Using
ElseIf mediumRadio.Checked = True Then
Using g As Graphics = CreateGraphics()
g.FillEllipse(New SolidBrush(paintColor), e.X, e.Y, 8, 8)
End Using
ElseIf largeRadio.Checked = True Then
Using g As Graphics = CreateGraphics()
g.FillEllipse(New SolidBrush(paintColor), e.X, e.Y, 12, 12)
End Using
End If
End If
End Sub
Private Sub RadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles redRadio.CheckedChanged, blueRadio.CheckedChanged, greenRadio.CheckedChanged, blackRadio.CheckedChanged
If CType(sender, RadioButton).Checked = True Then
paintColor = CType(CType(sender, RadioButton).Tag, Color)
End If
End Sub
Private Sub SizeRadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles smallRadio.CheckedChanged, mediumRadio.CheckedChanged, largeRadio.CheckedChanged
If CType(sender, RadioButton).Checked = True Then
End If
End Sub
End Class
My question is, how do I use the menustrip to select the size for my drawings? I figured out how to do it with the color but I cannot figure out the size. I am just not understanding how to code this.

Smart Phone Like Scrolling Solution issue (vb.net)

This solution seems to be the best one out there and the most commonly accepted one - however, if you scroll to the bottom and touch a the actual flowcontrol behind the buttons (I tried to make this so that there would be empty space to make this sample test easier), you then have to double tap-and-hold the button for the scrolling to resume. Restarting the application restores the phone-like scrolling functionality. I am wondering if anyone else has seen this or figured it out - try it with your apps and see if it is the case as well. I modified the snippet above so that you can start a new project, copy and paste this into form1's code, and hit run.
Public Class Form1
Dim FlowPanel As New FlowLayoutPanel
Private Function GenerateButton(ByVal pName As String) As Button
Dim mResult As New Button
With mResult
.Name = pName
.Text = pName
.Width = 128
.Height = 128
.Margin = New Padding(0)
.Padding = New Padding(0)
.BackColor = Color.CornflowerBlue
AddHandler .MouseDown, AddressOf Button_MouseDown
AddHandler .MouseMove, AddressOf Button_MouseMove
End With
Return mResult
End Function
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
Me.Width = 806
Me.Height = 480
FlowPanel.Padding = New Padding(0)
FlowPanel.Margin = New Padding(0)
' FlowPanel.ColumnCount = Me.Width / (128 + 6)
FlowPanel.Dock = DockStyle.Fill
FlowPanel.AutoScroll = True
Me.Controls.Add(FlowPanel)
Dim i As Integer
For i = 1 To 98
FlowPanel.Controls.Add(GenerateButton("btn" & i.ToString))
Next
End Sub
Dim myMouseDownPoint As Point
Dim myCurrAutoSMouseDown As Point
Private Sub Button_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
myMouseDownPoint = PointToClient(Cursor.Position)
myCurrAutoSMouseDown = FlowPanel.AutoScrollPosition
End Sub
Private Sub Button_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
Dim mLocation As Point = PointToClient(Cursor.Position)
If myMouseDownPoint <> mLocation Then
Dim mCurrAutoS As Point
Dim mDeslocation As Point = myMouseDownPoint - mLocation
mCurrAutoS.X = Math.Abs(myCurrAutoSMouseDown.X) + mDeslocation.X
mCurrAutoS.Y = Math.Abs(myCurrAutoSMouseDown.Y) + mDeslocation.Y
FlowPanel.AutoScrollPosition = mCurrAutoS
End If
End If
End Sub
End Class
Thanks for the code , I made ​​some changes to improve behavior . I hope it can be useful to someone .
Dim myMouseDownPoint As Point
Dim myCurrAutoSMouseDown As Point
'Add boolean variable a true.
Private _ValidateClickEvent As Boolean = True
Private Sub MyMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
myMouseDownPoint = PointToClient(Cursor.Position)
myCurrAutoSMouseDown = Panel1.AutoScrollPosition
End Sub
' Add MouseUp event for return the boolean variable a true.
Private Sub MyMouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
_ValidateClickEvent = True
End Sub
'Set boolean variable a false when change mlocation.
Private Sub MyMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
Dim mLocation As Point = PointToClient(Cursor.Position)
If myMouseDownPoint <> mLocation Then
Dim mCurrAutoS As Point
Dim mDeslocation As Point = CType(myMouseDownPoint - mLocation, Size)
mCurrAutoS.X = Math.Abs(myCurrAutoSMouseDown.X) + mDeslocation.X
mCurrAutoS.Y = Math.Abs(myCurrAutoSMouseDown.Y) + mDeslocation.Y
Panel1.AutoScrollPosition = mCurrAutoS
_ValidateClickEvent = False
End If
End If
End Sub
' Test boolean variable to perform click event.
Private Sub MyClick(sender As System.Object, e As System.EventArgs)
If _ValidateClickEvent Then
........................
Else
_ValidateClickEvent = True
End If
End Sub

doing multiple labels in Visual studio

This is what I have for clicking on one label so it could change color, but I would like to know how to make it so the next labels will also turn red only if clicked.
In
In total, I have 48 labels If Seat1.BackColor = Color.White Then
Seat1.BackColor = Color.Red
Else
Seat1.BackColor = Color.White
End If
You can have the same sub routine handle all of the seat label click events by casting the sender parameter as a Label:
Private Sub HandleSeatClick(sender As Object, e As EventArgs) Handles Seat1.Click, Seat2.Click, Seat3.Click
Dim lblTarget As Label = CType(sender, Label)
If lblTarget.BackColor = Color.White Then
lblTarget.BackColor = Color.Red
Else
lblTarget.BackColor = Color.White
End If
End Sub
If all of your seat labels are named in the same way (example = Seat5, Seat6, Seat7, ... , Seat48) then you can leverage AddHandler so you don't have to wire up the 48 labels with the Handles in the HandleSeatClick routine definition:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim intCursor As Integer = 1
Do Until intCursor = 48
Dim lblTarget As Label = CType(Me.Controls.Find("Seat" & intCursor.ToString(), False).First(), Label)
AddHandler lblTarget.Click, AddressOf HandleSeatClick
intCursor += 1
Loop
End Sub

Creating Dynamic Controls in VB and having them pre-programmed in different events

I have a project that can create a picturebox control but I want every picturebox the user creates to have events already set in place such as the mouse down and mouse up events. But since the control hasnt been created yet, I can't refer to it in the code without getting an error and the form not being able to load because of it. In other words, after the user creates a picturebox, they can move the picturebox around the screen and draw on it. Then they can create another picturebox and move it around and draw on it as well and arrange the pictureboxes as they please. Any ideas? Thanks.
here is my code:
Private Sub AddCanvasToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddCanvasToolStripMenuItem.Click
Dim canvas As New PictureBox
Dim i As Integer = 0
i = i + 1
canvas.Name = "canvas"
canvas.BackColor = Color.White
canvas.BorderStyle = BorderStyle.FixedSingle
canvas.Image = Nothing
canvas.Height = 200
canvas.Width = 200
AddHandler canvas.MouseDown, AddressOf PictureBox1_MouseDown
AddHandler canvas.MouseMove, AddressOf PictureBox1_MouseMove
canvas.Top = Panel2.Bottom
canvas.Left = Panel1.Right
Controls.Add(canvas)
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
If RadioButton1.Checked = True Then
xpos = Cursor.Position.X - PictureBox1.Location.X
ypos = Cursor.Position.Y - PictureBox1.Location.Y
End If
If RadioButton2.Checked = True Then
down = True
If down = True Then
PictureBox1.CreateGraphics.FillEllipse(mybrush, e.X, e.Y, 2, 2)
End If
End If
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If RadioButton1.Checked = True Then
If e.Button = Windows.Forms.MouseButtons.Left Then
pos = MousePosition
pos.X = pos.X - xpos
pos.Y = pos.Y - ypos
PictureBox1.Location = pos
End If
End If
If down = True Then
PictureBox1.CreateGraphics.FillEllipse(mybrush, e.X, e.Y, 2, 2)
End If
End Sub
But this only makes what I want to happen to canvas happen to picturebox1.
I dont even want picturebox1 to exist in the first place. I want them to create a new picturebox out of nowhere with events already programmed into it. So the user can create a new picturebox and then move it and draw on it.
Create events dynamically too, Like this:
Private Sub AddCanvasToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddCanvasToolStripMenuItem.Click
Dim canvas As New PictureBox
Dim i As Integer = 0
i = i + 1
canvas.Name = "canvas"
canvas.BackColor = Color.White
canvas.BorderStyle = BorderStyle.FixedSingle
canvas.Image = Nothing
canvas.Height = 200
canvas.Width = 200
AddHandler canvas.MouseDown, AddressOf pic_MouseDown
canvas.Top = Panel2.Bottom
canvas.Left = Panel1.Right
Controls.Add(canvas)
End Sub
Private Sub pic_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
'Do Something
End Sub
The above is perfect, but just to expand a little bit more:
Private Sub btnAddPictureBox_Click(sender As Object, e As EventArgs) Handles btnAddPictureBox.Click
Dim newPicBox As New PictureBox
Me.Controls.Add(newPicBox)
newPicBox.Location = New Point(50, 50)
newPicBox.Height = 100
newPicBox.Width = 100
newPicBox.BackColor = Color.White
newPicBox.BorderStyle = BorderStyle.FixedSingle
AddHandler newPicBox.MouseClick, AddressOf PictureBoxMouseClick
End Sub
Private Sub PictureBoxMouseClick(sender As Object, e As MouseEventArgs)
'Access the control the raised the event
'In this case we are changing the background colour to red
DirectCast(sender, PictureBox).BackColor = Color.Red
End Sub