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
Related
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
I Intended to display an PictureBox in my form when the mouse hovered over another control. I then wanted to use a separate event for when the mouse left the control. This event would remove the displayed PictureBox from controls. However, because my events are private subs, I can't directly access the name of the control in the latter event. A solution to this would be a method that removes the most recently added control. If no such method exists, or there is an alternative way of approaching this problem, any help would be appreciated.
I tried simply using Controls.Remove(), but this requires a parameter. The name of the control as a string did not work either, as the parameter must be a control itself.
Private Sub Tile_MouseEnter(Sender As Object, e As EventArgs)
Dim CloseUpPic As New PictureBox With {Properties}
CloseUpPic.Image = Sender.Image
Controls.Add(CloseUpPic)
Refresh()
End Sub
Private Sub Tile_MouseLeave(Sender As Object, e As EventArgs)
Me.Controls.Remove()
End Sub
The program won't compile due to .Remove() needing a parameter
I expected for the Control to be created and displayed when the mouse entered the tile, and to cease to exist when the mouse left the tile.
For future reference, controls have Tag property which allows you to store whatever you like. In this case, you can store a reference to the newly created PictureBox. Furthermore, the "Sender" parameter tells you which control was the source of the event. You can cast sender to a control, then store the reference. Then, in the leave event, you can cast sender to a control, cast the .Tag to a control, and finally remove it:
Private Sub Tile_MouseEnter(Sender As Object, e As EventArgs)
Dim ctl As Control = DirectCast(Sender, Control)
Dim CloseUpPic As New PictureBox With {Properties}
CloseUpPic.Image = Sender.Image
Controls.Add(CloseUpPic)
ctl.Tag = CloseUpPic
Refresh()
End Sub
Private Sub Tile_MouseLeave(Sender As Object, e As EventArgs)
Dim ctl As Control = DirectCast(Sender, Control)
Dim ctlToRemove As Control = DirectCast(ctl.Tag, Control)
Me.Controls.Remove(ctlToRemove)
End Sub
I ended up using the following code to solve my issue:
For Each Closeup In Controls.OfType(Of CloseUp)
Controls.Remove(Closeup)
Next
I created a new class of my own called Closeup, that inherits PictureBox. I then looped through each Closeup in controls (There was only one but this code works for multiple controls), and removed them.
In my program (Winforms), i use usercontrols as pages. I do this in the following way:
I have a panel on my Form1 in which i load usercontrols, on these usercontrols are my actual controls (buttons, labels, checkboxes etc). So actually i'm using the user controls as "sub" pages in my form.
The usercontrols are declared at the start of runtime, so they are "live" when i load them into the panel. This has allways worked fine, untill i ran into a problem yesterday.
Yesterday I used a datagridview on one of those usercontrols and during the ParentChanged of this control i call a Sub which changes the backcollor of this data grid view. (The sub itself is a public sub which is located in a module)
Like this:
Private Sub Init_ParentChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.ParentChanged
GetRecipe(RecipeDGV, "Bla")
End Sub
Public Sub GetRecipe(ByVal Data As DataGridView, ByVal RecipeID As String)
For r As Integer = 0 To Recipe_Mem.Rows.Count - 1
For c As Integer = 0 To Recipe_Mem.Columns.Count - 1
Data(c, r).Style.BackColor = getPresetColorByID(CInt(Data(c, r).Value))
Data(c, r).ToolTipText = getPresetNameByID(CInt(Data(c, r).Value))
NEXT
NEXT
End Sub
When i run my program, i can see that my dgv gets the data from the database (which happens in the same Sub). But there is no color change in the cells.
Now, something i've noticed is that when i add a button to the user control, and use the click event of this button to call the same sub for the coloring, it does work).
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
GetRecipe(RecipeDGV, "Bla")
End Sub
Any idea why this works on a button click event, but it doesn't in the usercontrol parent changed event? it looks like during the parent changed event there is some kind of repaint event of the dgv. how do i solve this?
Have you tried wrapping the gridview in an ajax control ( with triggers on the ParentChanged event?
I'm a little puzzled by the "RecipeID" argument being passed as it isn't used.
Currently in my windows form, I have a few WinForms to work with. One WinForm acts as a main menu and is supposed to call another form as a secondary window on its own.
Private Sub btnMainGame_Click(sender As Object, e As EventArgs) Handles btnMainGame.Click
' This is the button to call up the main game controller. So simply hide this form aned then open the new form.
Dim frmController As New frmControllerScreen
frmController.Show()
Me.Hide() ' Happens on .Close as well
End Sub
The above code invokes another WinForm which is used to handle more options. When the user clicks on a particular button, a sub form is created again.
Dim OpenNewGameWindow As New frmGameConfig
OpenNewGameWindow.ShowDialog(Me)
Me.DialogResult = DialogResult.None ' Used to prevent the subform from closing the main form when it catches a dialog result.
Now in the frmGameConfig, the program is supposed to take data and pass it back to the form that called it.
Private Sub btnNewGameStartGame_Click(sender As Object, e As EventArgs) Handles btnNewGameStartGame.Click
' ... Skipped code...
frmControllerScreen.MasterQuestionList = QuestionList
frmControllerScreen.blnBankedTime = cbBankedTime.Checked
' ... Skipped code...
End Sub
However, when the frmController tries to reference MasterQuestionList... it returns a nullreference error as if it was not set.
Here's where things get funny...
When I made this code, frmControllerScreen was actually the startup form. Now when I change this form back to frmMainMenu, I get NullReference errors constantly.
My question: How am I supposed to pass information from one form to the next form if it was instantiated from a parent form. (Note I even moved the declartion to Public as a "module-wide" variable... and nothing happens but the same result.) The same error happens even if I go ahead and declare frmController.MasterQuestionList as well.
Instead of trying to pass data back from the called form to the caller, you can reference the called form's controls from the calling code after .ShowDialog.
Dim OpenNewGameWindow As New frmGameConfig
If OpenNewGameWindow.ShowDialog() Then
MasterQuestionList = OpenNewGameWindow.QuestionList
blnBankedTime = OpenNewGameWindow.cbBankedTime.Checked
End If
In OpenGameWindow button click:
Private Sub btnNewGameStartGame_Click(sender As Object, e As EventArgs) Handles btnNewGameStartGame.Click
Me.DialogResult = True
End Sub
I am writing a program using a database for customers and technicians. The main form (CustomerIncidents) has a toolstripbutton that opens a different form to (SearchByState) where the user inputs a state code and looks for any incidents.
If the user clicks into one of the datagrid cells I want that customers information to be stored in the TAG so that when the form is closed using the OK button that it will show back up in the main form (CustomerIncidents).
Edited 03/11/14 12:21pm
The problem is in the Main Form. When I click the OK button in the Second Form it tries to convert the DialogResult Button to a String. I can't figure out how to fix it.
Customer Form (Main Form) Opens to Secondary Form
Private Sub btnOpenState_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnOpenState.Click
Dim frmSearchState As New FindCustomer
----->>Dim selectedButton As DialogResult = frmSearchState.ShowDialog()
If selectedButton = Windows.Forms.DialogResult.OK Then
CustomerIDToolStripTextBox.Text = frmSearchState.Tag.ToString
End If'
Search By State Form (Secondary Form) Or "Child Form"
Private Sub btnOk_Click(message As String, ByVal e As DataGridViewCellEventArgs) Handles btnOk.Click
message = CustomersDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex).Value.ToString
Me.Tag = message
Me.DialogResult = DialogResult.OK
End Sub
The click event for a button does not have a DataGridViewCellEventArgs parameter, and will throw an exception when you try to use it.
You don't need to use the Tag property since you can just create your own property.
In your child form, create a property called GridValue:
Private Sub btnOk_Click(sender As Object, e As EventArgs) Handles btnOk.Click
If dgv.CurrentCell Is Nothing OrElse dgv.CurrentCell.Value Is Nothing Then
MessageBox.Show("A cell needs to be selected.")
Else
Me.DialogResult = DialogResult.OK
End If
End Sub
Public ReadOnly Property GridValue As String
Get
Return dgv.CurrentCell.Value.ToString
End Get
End Property
In your parent form, you can now access your information:
Using frmSearchState As New FindCustomer
If frmSearchState.ShowDialog(Me) = DialogResult.Ok Then
CustomerIDToolStripTextBox.Text = frmSearchState.GridValue
End If
End Using
My personal approach for doing this kind of stuff is to create a public property in the child form, having the same type as the DATA you want to take back to your main form. So instead of storing DataGridView's reference in Tag property, you should really be storing the actual value that was there in the cell that the user clicked on.
For example, if your DGV cell has a string value in it, you could do something like:
Public Readonly Property StateName As String
Get
If YourDGV.SelectedCell IsNot Nothing Then
Return YourDGV.SelectedCell.Value
Else
Return ""
End If
End Get
End Property
(I have written that code by hand, so there may be some syntax problems, but you should be able to get the idea.)
You can now use ShowDialog() in the main form to bring up this child form and upon OK or Cancel, you could check the value of StateName property of your child form to get this value. The thing to remember here is that closing a form doesn't dispose off all its constituent controls and properties and therefore you can access them even after the form has finished ShowDialog() call.