How can i build an expandable and collapsible panel in VB.net? - vb.net

I am looking for a way to make a panel which can be expanded and collapsed with a little arrow or button. I tried to find some examples, nothing worked so far. I tried to resize a group to 0px but the problem was when i did that the panel below it stayed in a same place, and I wanted it to slide upside, to save screen real estate.
I have a bunch of labels and text boxes which provides me data, but takes up a lot of space, and i grouped them together.
All help would be appreciated.
David

Simple in window Form
Insert a button and write code
Simple Example:
Public Class Form1
Dim panelshow As Boolean = False
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
If panelshow = False Then
panelshow = True
Panel1.Show()
Else
Panel1.Hide()
panelshow = False
End If
End Sub
End Class
You can change name of variables, buttons and panels.
Set the panelshow to false if on application start your panel is collapsed otherwise to true if your panel is visible on startup and want to hide later by user.

Most people have answered the question about the collapse and expand, but to answer your question about "animation" so that it really has a good slide feel. For winforms i recommend this library on github DotNet Transitions
you can then write very simple code to give it animated transition.
using the transitions library, this code would collapse the panel in half a second:
Transitions.Transition.run(pnl, "Height",
initialValue:=pnl.Height,
destinationValue:=0,
transitionMethod:=New TransitionType_EaseInEaseOut(500)
)

If you want to use animation in win forms like when panel collapsed and the additional space should be covered with content then you can use
Control.Top() And Control.Left() Property ' control = your control name on which content is written like label, textbox etc.
Or second choice
To resize your content (like increasing the size etc).
Depend on your choice as I can't see your form presentation but advise you on the base of my imagination.
For example my panel height is 100 and when i collapsed I want my next control should move upward by 100 (Just suppose)
Suppose, my next control is RichTextBox
Then, you can do change here :
Public Class Form1
Dim panelshow As Boolean = True
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
If panelshow = False Then
panelshow = True
Panel1.Show()
RichTextBox1.Top = RichTextBox1.Top + 100
RichTextBox1.Height = RichTextBox1.Height - 100
Else
Panel1.Hide()
panelshow = False
RichTextBox1.Top = RichTextBox1.Top - 100
RichTextBox1.Height = RichTextBox1.Height + 100
End If
End Sub
End Class
Just add a method in addition to our previous code to do this thing.
Don't mind my grammar mistakes.
I am not perfect in English.
For more help comment or post your code (if you have any kind of problem)

Related

How to create any one dynamic controls with a for loop without using location property and the form should grow automatically

How to create multiple button controls with a for loop without getting the controls overlapped and without using location property in Vb.Net.
I have created 'n' number of vb controls dynamically but the created controls are getting overlapped to each other. When I use location property to each controls all the controls are getting displayed as per the location value.
The real problem is, I'm using a panel of width 300 and height 300, under that I need to display the dynamically created controls. I have figured it out which is tedious work and does take a lot of time. My idea is to find the panel width and height then need to check whether the new control which is getting created has ample of space to fit inside the panel.
I need to know few things,
1) How to display the controls dynamically using for loop without getting overlapped over each other and without using location property.
2) I need the container or the panel to grow as per the number of controls which gets created dynamically.
3) Accessing each controls which got displayed using an ID or educate or explain me any better idea.
I created a new WinForms project and added a Button to the top of the form. I added a FlowLayoutPanel under that and made it narrow enough to fit a single Button widthwise. I set the AutoSize property of the FLP to True and the FlowDirection to TopDown. I then added this code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Create the new Button.
Dim btn As New Button
'Add it to the FLP
FlowLayoutPanel1.Controls.Add(btn)
'Get the position of the bottom, left of the Button relative to the form.
Dim pt = PointToClient(btn.PointToScreen(New Point(0, btn.Height)))
'Resize the form to provide clearance below the new Button.
ClientSize = New Size(ClientSize.Width, pt.Y + 10)
End Sub
I then ran the project and started clicking the Button I added. As expected, each click added a new Button to the FLP in a vertical column and the form resized to fit. In order to access such controls in code, you can simply index the Controls collection of the FLP.
try this helps you.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
'Do Something
Else
'Do Something else
End If
Panel1.Controls.Clear()
For i As Integer = 0 To 10 Step 1
Dim b15 As New Button
b15.Text = "Test3"
b15.ID = "a" & i
AddHandler b15.Click, AddressOf updateFunc
Panel1.Controls.Add(b15)
Next
End Sub

How do I add a VScrollBar to a textbox?

I am using a theme from the web for my vb.net application and the textbox does not have scrollbars or a scrollbar property. The theme did come with a VScrollBar Control, but I don't know how to add code to it to make it scroll the textbox like normal. Can anyone help me?
These are Custom Controls.
It's a Windows Form. (WinForms)
Textbox and its Properties:
Vertical scroll bars can be added to TextBox form objects, but however they must be Multiline:
This can either be done by setting Multiline to True and ScrollBars to Vertical:
or it can be done via code, programmatically, as per se:
TextBox1.Multiline = True
TextBox1.ScrollBars = ScrollBars.Vertical
You can set ScrollBars to be only horizontal, vertical, both, or none (default):
Remember, you should:
Be sanitizing the user's input if you're sending the textbox's contents off to a database
Limit the amount of characters that the user can input (see below)
Be using proper programming technique by naming your objects properly, for example, try not to name your textbox TextBox1
As mentioned above, you may want to show the amount of characters the user can input, for example:
the code for this:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
text1.MaxLength = 140
charsLeft.Text = "0/" + CStr(text1.MaxLength)
End Sub
Private Sub textHasChanged() Handles text1.TextChanged
charsLeft.Text = CStr(text1.TextLength) + "/" + CStr(text1.MaxLength)
End Sub

Darken a .Net Form

I have a 1080p touchscreen application. When a modal pops up, i want to emphasize that by darkening the main form.
Right now i use a second form, the size of the main form, that is black and has 50% opacity. Whenever a modal needs to appear, i open the opaque form, and then open the desired modal.
I feel this is a bit devious for my purpose. Its also not asshole-proof that when the user alt tabs, the forms will glitch out of sequence.
Is there a better way to achieve the darkening effect. Perhaps by darkening the main form from within itself?
Solved it myself by doing the following:
Place a hidden picturebox with dock:fill on the main form,
Take a screenshot of the current screen and darken it
assign the image to the picturebox and make it visible
open the modal in a new win
when the modal is dismissed
hide the picturebox
It really stupid that VB.net doesn't have this function built into it. Here's what you do to get around it:
Make a new form and call it Shade. I'm going to assume your main form is called frmMain. For the sake of clarity, lets assume the form you're launching is called dlgX.
Add the following lines in the Load event of dlgX (that's the sub with dlgX.Load or Me.Load or MyBase.Load):
Shade.Opacity = 0.001
Shade.Show()
Shade.Location = frmMain.Location ' Form location will only update if the form is visible.
Shade.Hide()
Shade.FormBorderStyle = Windows.Forms.FormBorderStyle.None 'This gets rid of the windows Titlebar and window border.
Shade.Size = frmMain.Size
Shade.BackColor = Color.Black
Shade.Opacity = 0.5
Shade.Show() ' Form size will only update the next time you show it.
Shade.TopMost = True ' Puts Shade over main form
Me.TopMost = True ' Puts current form over shade
Under all events that dismiss the form dlgX (OK.click, Cancel.click, etc), add the following lines:
Shade.Close
Or you can even make your own sub that handles all events where the form is closed:
Private Sub DispelShades(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.FormClosed
Shade.Close()
End Sub
This is way simpler than the PictureBox scenario and you don't have to mess with layering issues and having to ensure that the PictureBox renders on top of everything (for example, tabs really do not like having things rendered above them and they will not let you render a picture box above them). Rendering a black semi transparent form above your main form gets around all these headaches.
If you have multiple forms to shade, just make a Shad1, Shade2, Shade3 etc.
This is pretty obvious but it's worth stating: if you're shading the main form, you'll also want to make it unclickable by opening dlgX via dlgX.ShowDialog and not dlgX.Show
Here is some code, very similar to the method in Thomas's answer. Note to use the Darkness property in a Try...Finally block, to make sure you never leave the form in the dark state.
Public Class Form1
Private _PB As PictureBox
Public WriteOnly Property Darkness
Set(value)
If value Then
Dim Bmp = New Bitmap(Bounds.Size.Width, Bounds.Size.Height)
Me.DrawToBitmap(Bmp, New Rectangle(Point.Empty, Bounds.Size))
Using g = Graphics.FromImage(Bmp)
Dim Brush As New SolidBrush(Color.FromArgb(125, Color.Black))
g.FillRectangle(Brush, New Rectangle(Point.Empty, Bmp.Size))
End Using
_PB = New PictureBox
Me.Controls.Add(_PB)
_PB.Size = Bounds.Size
_PB.Location = Bounds.Location - PointToScreen(Point.Empty)
_PB.Image = Bmp
_PB.BringToFront()
Else
If _PB IsNot Nothing Then
Me.Controls.Remove(_PB)
_PB.Dispose()
End If
End If
End Set
End Property
Private Sub btnDialog_Click(sender As Object, e As EventArgs) Handles btnDialog.Click
Try
Darkness = True
MsgBox("Modal dialog")
Finally
Darkness = False
End Try
End Sub
End Class

How can I place/drop an image evertime you click the mouse button using vb.net?

I looked at "How do I place an image with a mouse-click in Javascript?" but it had a small snippet of Java; immensely larger than my knowledge of Java. And that is the closest I've come to finding an answer in the past week.
Here's what I would like to do (don't know if its even possible):
I have a panel and a toolstrip with 3 buttons. Each button represents a different image. I want to click on a button (once) and then move into the panel and everytime I click the mouse button it drops the image where ever I clicked. This only ends when either I click back on the same button or one of the other buttons. I do not want to drag an image into the panel each time. In other words the button stays depressed and the event/action stays active.
Any help would be greatly appreciated.
Here is an example application. It's just a form with a ToolStrip on it, along with a couple of buttons with an image added to each button. The key property for each button is CheckOnClick=True, which will keep the button pressed down.
There isn't a radio button like feature for ToolStrips, so you have to "uncheck" the other ToolStripButtons yourself, which I have handled in the ItemClicked event.
Public Class Form1
Private _ActiveImage As Image = Nothing
Private Class ImagePoint
Public Location As Point
Public Image As Image
Public Sub New(ByVal image As Image, ByVal location As Point)
Me.Image = image
Me.Location = location
End Sub
End Class
Private _Images As New List(Of ImagePoint)
Public Sub New()
InitializeComponent()
Me.DoubleBuffered = True
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles MyBase.Paint
For Each imageItem As ImagePoint In _Images
e.Graphics.DrawImage(imageItem.Image, imageItem.Location)
Next
End Sub
Private Sub ToolStrip1_ItemClicked(ByVal sender As Object, ByVal e As ToolStripItemClickedEventArgs) Handles ToolStrip1.ItemClicked
For Each toolButton As ToolStripButton In ToolStrip1.Items.OfType(Of ToolStripButton)()
If toolButton.CheckOnClick Then
If e.ClickedItem.Equals(toolButton) Then
_ActiveImage = e.ClickedItem.Image
Else
toolButton.Checked = False
End If
End If
Next
End Sub
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseDown
If _ActiveImage IsNot Nothing AndAlso e.Button = MouseButtons.Left Then
_Images.Add(New ImagePoint(_ActiveImage, e.Location))
Me.Invalidate()
End If
End Sub
End Class
This example just uses a simple class to hold which image was placed at what location and the paint event just loops through the list and paints the image.
If deleting images is in your future, then you would have to call e.Graphics.Clear(Color.White) before painting any images.
For the button UI, check out the alternate style for radio buttons/check boxes. They have a "toggle button" mode which sounds like exactly what you need.
You could go through the motions of detecting mouse down events on the panel, getting the coordinates, creating an image control, and placing a copy of the image in it, but there's a better approach.
Fill the panel with a single image control (fill so that it handles resizes, the image control should always be the same size as the panel). Create a new Bitmap the same size as the image control and associate it with it (set the Image property). Obtain a Graphics object for the Bitmap (Graphics.FromImage() I think). Clear() it with the background color (Color.White?).
Preload your three images on startup and write the code to toggle between them, selecting the "active one" every time a different button is selected. On the mouse down event, you can get the coordinates of the click easily. Use myGraphics.DrawImage(...) to draw the active image at that location onto the Bitmap. You can then save the Bitmap to a file or do whatever you want with it. All of these concepts have lots of examples, Google them.
If you want to interact with the images after you "drop" them (like move them around again or something), then you will need to maintain a data structure that tracks what and where you've dropped. A simple class that has a Point and Image reference will be sufficient. Each drop should add an entry to a List(Of ...) these objects. You'll probably then need to write code such as "which image is under the current mouse location?". This can be accomplished by iterating through the list and doing point/rectangle intersection testing.
Private Sub ToolStripSound_Click(sender As Object, e As EventArgs) Handles ToolStripSound.Click
If ToolStripSound.Checked = False Then
ToolStripSound.Checked = True
Else
ToolStripSound.Checked = False
End If
End Sub
Private Sub ToolStripSound_CheckedChanged(sender As Object, e As EventArgs) Handles ToolStripSound.CheckedChanged
' ToolStripSound.Checked = True
If ToolStripSound.Checked = True Then
Me.ToolStripSound.Image = Global.Traffic_Lights.My.Resources.Resources.Oxygen_Icons_org_Oxygen_Status_audio_volume_high
Else
Me.ToolStripSound.Image = Global.Traffic_Lights.My.Resources.Resources.Oxygen_Icons_org_Oxygen_Status_audio_volume_muted
End If
End Sub

Setting Focus on a Tab

I have a tab in a windows form called Wafer Map that has three sub-tabs. The First sub-tab is the called Map and has a Load and Skip button. I am trying to set the focus on the Wafer sub-tab on the Load button click. This is the following code I have tried to use.
Private Sub Load_Wafer_Layout_Map_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Load_Wafer_Layout_Map.Click
Wafer_Info.Enabled = True
Wafer_Info.Show()
End Sub
The Wafer_Info.Enabled = True is used to enabled all of the controls on the Wafer tab and works properly when the button is clicked. I have tried using .Focus() and .Show() to bring focus to the next tab but I am not have any luck getting to switch. Anyone have any suggestions?
Just set it:
tabControl.SelectedTab = yourTab
On the Tab Controls Tab Pages, just ensure you name the tab you are attempting to reference. Additionally, see MSDN TabControl.SelectedTab
The code that worked for me is Tab_WaferMap.SelectTab(1). Tab_WaferMap is my main tab and the 1 is the index of the sub tab I wanted to show
I came across this thread as i was looking for a solution to my own focus issue. I have a TabControl with many TabPages. Each TabPage is set to auto scroll due to overflowing content. The problem I ran into was the mouse scroll wheel would not function if the TabPage did not have focus. Since there is not an event for each tab click it made setting focus to each TabPage a challenge. It was not hard, but a challenge none the less. So, here is my code (assuming auto scroll true).
On form load sets focus to main TabPage:
Private Sub frmParent_Load(sender As Object, e As System.EventArgs) Handles Me.Load
TabControl1.TabPages(0).Focus()
End Sub
Sets focus to current TabPage by getting the index then setting focus.
This is triggered by TabControl1.SelectedIndexChange event.
Private Sub TabControl1_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles TabControl1.SelectedIndexChanged
Dim intTabIndex As Integer = TabControl1.SelectedIndex
TabControl1.TabPages(intTabIndex).Focus()
End Sub
I hope someone find this useful. It was very useful for me.
Joshua
You can also set the Selected Index of the tab (and sub-tab) using a (zero based) numeric value:
TabParent.SelectedIndex = 3
TabSub.SelectedIndex=2