Refer to a determinate created button - vb.net

So In my program I’ve putted a flowlayourpanel and with a button I add to the layout infinite new buttons
(button.name = “button” + i.tostring) [i = i + 1]
With another button I want to hide the button with the i=3 so button3.hide(), but it doesn’t work beacause it doesn’t exist yet so How can I refer to the button created when the i was 3?

Name is a property of the Control class so every control has that property. That doesn't mean that it needs to be set though, so some controls don't have a name. When you add a control to your form in the designer, what happens is that the Name property is set AND a field is declared with that name. That's why, if you name a Button control Button1, you are able to use the field Button1 to refer to it.
When you create controls at run time, of course there is no field dedicated to that control so of course you can use such a dedicated field to refer to it. It's up to you to get a reference to that control from wherever you put it when you created it. Where that is is up to you but, if you added it to the Controls collection of a container, that is one option for getting it back. If you set the Name property, you can index the Controls collection with that name to get it, e.g.
Dim myButton = DirectCast(myFlowLayoutPanel.Controls("Button" & i), Button)
There may be other ways of getting that reference too. For instance, if you created your own List(Of Button) and set the Tag of each Button to the number, you could do this:
Dim myButton = myButtonList.Single(Function(btn) CInt(btn.Tag) = i)

When adding your buttons to the FlowLayoutPanel you have correctly assinged a name. You can use this name to refer to the button as shown in Button2.Click.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For i = 1 To 5
Dim b As New Button
b.Name = "btn" & i
b.Text = "btn" & i
FlowLayoutPanel1.Controls.Add(b)
Next
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
FlowLayoutPanel1.Controls("btn3").Visible = False
End Sub

Related

How do you set a dynamically created panel to false in VB.net?

I have on my screen design Panel1(left half), and panel2 through 10(right half), the panels on the right half are named based on data from a database.
I need to be able to click on a button in panel1 and when I do so, I need to set visibility to false for the current panel on the right half and set visibility to true that is referenced from the button click. I know that I can do the following but I think this is just way too much overhead and there has to be a better solution than this:
For Each control In Me.Controls.OfType(Of Panel)
If control.visible = true Then
control.visible = false
exit
Next
Panel that the visibility that needs to be set to false was dynamically created so it can not just be accessed by just name, otherwise that would solve my issue easily.
I seen this bit of code elsewhere and it would make my life easier, however not sure how to implement it dynamically when the panels are created, since the name of the panels are unknown at creation.
This bit of code to be able to reference the panels directly.
Dim machinePanel As Panel = DirectCast(Me.Controls.Item("pnl" & strMTB & strMachineID), Panel)
I'm not sure what you mean but "is referenced from the button click", so I'll assume that the text of the button refers to the panel name.
Create a method that handles the visibility
Private Sub SetPanelVisibility(button As Button)
'panel that the button is in
Dim leftPanel = CType(button.Parent, Panel)
'get right panels and ignore left
Dim rightpanels = Me.Controls.OfType(Of Panel).Where(Function(x) x.Name <> leftPanel.Name)
'set visibility of each panel.
For Each panel In rightpanels
panel.Visible = panel.Name = button.Text
Next
End Sub
To call the method just pass the button in on the click event. e.g.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
SetPanelVisibility(sender)
End Sub

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

Determine an object's runtime X-location

This might be a stupid question, but I'm attempting to move a button to the left by roughly 160 pixels each time the button is pressed. However, I need to know what the x-location is of the object at runtime so I can dynamically add those 160 pixels to it. A real world example of this would be right above (if you happen to be using chrome/firefox-which who isn't?) when the new tab button moves every time a new tab is opened (additionally subtracting those pixels too which is harder because I have to figure out how to handle the tab close event within a QTab control in the QIOS devsuite).
You could do this:
Button1.Location = New Point(Button1.Location.X - 160, Button1.Location.Y)
or this:
Dim pt As Point = Button1.Location
Button1.Location = New Point(pt.X - 160, pt.Y)
or maybe this:
Dim pt As Point = Button1.Location
pt.Offset(-160, 0)
Button1.Location = pt
When you use the WinForm designer, each control on your form is assigned a unique name. When you place a control on the form, the designer automatically assigns a unique name (e.g. Button1), but you can change it to whatever you want. The designer automatically creates a class-level variable (i.e. field) for each control. The name of the variable matches the name of the control. So, for instance, if you call your control Button1, then you can access the X-location of that button via the Button1 variable, like this:
Dim x As Integer = Button1.Left
If you are writing code that is intended to handle events from multiple controls, so you wouldn't know which variable to use, you can use the event handler's sender parameter. Every event handler has a sender As Object parameter which points to the control that is raising the event.
So, for instance, in a the click event, you could do something like this:
Private Sub ClickHandler(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click, Button3.Click
Dim clickedButton As Button = DirectCast(sender, Button)
Dim x As Integer = clickedButton.Left
End Sub

Edit Update DatagridView VB.Net (No Database)

Good day everyone.
I need your help in this project I am into (a Visual Basic program with no database.) It just contains a Datagridview, a Textbox, and three buttons (an "Add" Button, a "Edit" and an "Update" Button).
1 . Is there any way (like using "for loop") to automatically assign DataGridView1.Item("item location") to the one edited and be updated?
2 . Or is it possible to just click an item in the Datagridview then it will be edited at that without passing it to a Textbox, and to be updated at that.
The DataGridViewCellEventArgs variable (e in the method stub the designer will generate for you) of the double click event of the cell has RowIndex and ColumnIndex properties which refer to the position of the cell you clicked.
Save those (in a class variable possibly or a local one if that's all you need) and then refer to them when you update the cell in your DataGridView, possibly like this MyDataGridView.Item(e.ColumnIndex, e.RowIndex) or MyDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex) where e is the variable from the double click event handler.
For you cell double click event you could have something like this:
Private Sub DataGridView1_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellDoubleClick
Using myEditor As New frmCellEditor(Me.DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value)
If myEditor.ShowDialog() = DialogResult.OK Then
Me.DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value = myEditor.NewCellValue
End If
End Using
End Sub
This will call a new instance of your editor and get a value from you. For the purpose of this demo I have made a form like this:
Public Class frmCellEditor
Public NewCellValue As Integer
Public Sub New(ByVal CurrentCellValue As Object)
InitializeComponent()
Me.TextBox1.Text = CStr(CurrentCellValue)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.NewCellValue = CInt(Me.TextBox1.Text)
Me.DialogResult = DialogResult.OK
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Call Me.Close()
End Sub
End Class
Which just has two buttons (Button1 = OK, Button2 = Cancel). When you click OK, it just returns the value 1 which then gets set as the value of the cell.
This is a VERY simplistic example, but it should provide you the basics of what you are trying to do.
UPDATE:
I updated the code for the editor interface so it will include handling for passing the value back and forth from the form with your datagridview.
In your project, make a new form called frmCellEditor. This forms has to have two buttons and a textbox (Make sure that the programmatic names match!). Replace the code with the code listed above. You will have to add Imports System.Windows.Forms above the class as well.
Amend the event handler for the cell double click event of your datagrid to pass the cell value when frmCellEditor is constructed (the line going ... New frmCellEditor(...).
How many columns does your DataGridView has?
Based on how you populate your DataGridView, I'll assume only 1.
Declare this on top of your form
Dim i as Integer
On your btnUpdate_Click Event (Just combine your Edit and Update button into One)
SELECT CASE btnUpdate.Text
Case "Update"
With DataGridView1
'Check if there is a selected row
If .SelectedRows.Count = 0 Then
Msgbox "No Row Selected for Update"
Exit Sub
End If
i = .CurrentRow.Index 'Remember the Row Position
Textbox1.Text = .item(0 ,i).value 'Pass the Value to the textbox
.Enabled = False 'Disable DataGridView to prevent users from clicking other row while updating.
btnUpdate.Text = "Save"
End With
Case Else 'Save
DatagridView1.Item(0,i).Value = Textbox1.Text
btnUpdate.Text = "Update"
END SELECT
Thanks for those who contributed to finding answers for this thread. I have not used your solutions for now (maybe some other time). After some research, I've found an answer for problem 2 (more user friendly at that):
2 . Or is it possible to just click an item in the Datagridview then
it will be edited at that without passing it to a Textbox, and to be
updated at that.
Here's what i did:
in Private Sub Form1_Load, just add:
yourDataGridView.EditMode = DataGridViewEditMode.EditOnEnter
in Private Sub yourDataGridView_(whatever event here: DoubleCellClick, CellContentClick, etc.) add:
DataGridView1(e.ColumnIndex, e.RowIndex).[ReadOnly] = False
DataGridView1.BeginEdit(False)

On Postback placeholder controls disappearing

Within my webpage I am loading usercontrols within a placeholder. Each of these user controls triggers a postback when an ajaxcontroltoolkit rating is changed. The problem I am having is that if I use
If (Not IsPostBack is Nothing)
the controls within the placeholder disappear on post.
My Page_Load looks like this currently
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Session("ProId") = Nothing
Session("FolId") = Nothing
Dim ProId As Integer
If (Not Request.QueryString("ProjectID") Is Nothing) Then
ProId = Convert.ToInt32(Request.QueryString("ProjectID").ToString())
Session("ProId") = Request.QueryString("ProjectID").ToString()
End If
Dim FolId As Integer
If (Not Request.QueryString("FolderID") Is Nothing) Then
FolId = Convert.ToInt32(Request.QueryString("FolderID").ToString())
Session("FolId") = Request.QueryString("FolderID").ToString()
End If
objUser = New BSSiteUser(CInt(Page.User.SiteUser.intID))
objProject = New BSProject(ProId)
objFolder = New BSFolder(objUser.SiteUserID, FolId)
objOrganization = New BSOrganization(objProject.intOrganizationID, objUser.SiteUserID)
Me.Load_SubcontractorList()
Me.Load_EvaluationList(1)
Me.Load_EvaluationList(2)
Me.lblorganization.Text = objOrganization.CompanyName
Me.lblprojectname.Text = objProject.strProjectName
Me.lblprojectnumber.Text = objProject.strProjectNumber
Me.lbldatecreated.Text = Date.Now.Date.ToString()
End Sub
The Load_EvaluationList is what loads the user controls, if I place the IsPostBack check around those two, the controls disappear, what could be the problem
Dynamically added controls disappear on postback as you are working with a brand new instance of your page. In order for you to keep them you are going to have to recreate them for any postback that occurs.
It is also important to note that if you want your ViewState to be retained you should create your user controls on Page Init and not Page Load as loading of ViewState data back to the controls happens before the Load event.
If you are dynamically adding controls then on every postback you have to add control again.
try using if(Not IsPostBack) or (IsPostBack) instead of comparing it with Nothing.
Here I am simply adding a textbox dynamically on postback and it will stay in every postback.
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If (IsPostBack) Then
Dim t As TextBox = New TextBox()
form1.Controls.Add(t)
End If
End Sub
End Class
You can put the controls you are trying to add dynamically in one function/method/subroutine and just call inside of Load.
Update
If you want your data to stay in the controls you have to save the data in the viewstate. You will have to create control again no matter what but before control is sent back to user get their data from the view state. It is described with example here.
http://forums.asp.net/t/1186195.aspx/1
I am abandoning this question as a decision was made to go a different route