Im having a textfield set up with the text "Hello" and a button
When i change the text and press i'd like to have a msgbox replying the changed text
Public Class TestText
Dim Text As String = Textbox.text
Private Sub BtnchangeTXT_Click(sender As Object, e As EventArgs) Handles BtnchangeTXT.Click
Text = Textbox.Text
Msgbox(Text)
Msgbox(TextField.Fieldtext)
End Sub
End Class
Public Class TextField
Public Shared FieldText As String = TestText.Textbox.Text
End Class
All works well untill i request for the "TextField.FieldText" msgBox this will always return the defaulttext ("hello")
where do i go wrong?
Ive tried to set a different text "On Load" but still the default "Hello" is being returned.
In this line:
Public Shared FieldText As String = TestText.Textbox.Text
The value of "FieldText" only gets set ONCE, when that variable is created (and that occurs even before the form with the textbox is shown). It does not get updated whenever the TextBox changes.
If you want that variable to always have the current value of that TextBox, then use the TextChanged() event of that TextBox to update the variable.
Private Sub Textbox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Textbox.TextChanged
TextField.Fieldtext = Textbox.Text
End Sub
There are two problems with your code. Firstly, because this code:
Public Class TextField
Public Shared FieldText As String = TestText.Textbox.Text
End Class
uses the name of the TestText class to refer to an instance of that class, it is referring to the default instance. If you don't know what default instances are, I suggest that you do some reading on the subject. You can find my own writeup here.
That means that that code will always get the Text of the TextBox on the default instance of that type. If you display the default instance then that's fine but if you explicitly create an instance and display that, then modify the contents of the TextBox on that instance, that will have exactly zero effect on the default instance.
The second issue is the fact that you are using a field. You seem to be under the impression that that FieldText field should change dynamically as you change the contents of the TextBox. Why would you think that? The code you have DOES NOT get the current contents of the TextBox every time you get the field value. What is does is get the current contents of the TextBox and assign it to the field on the first occasion you get that field and then NEVER changes the field value again. If what you actually want is the current contents of the TextBox then you would need a property rather than a field:
Public Class TextField
Public Shared ReadOnly Property FieldText As String
Get
Return TestText.Textbox.Text
End Get
End Property
End Class
The whole point of properties is that they act like fields on the outside, so your code to get that property value won't change, but they act like methods on the inside, so the code to get the current contents of the TextBox will be executed every time you get the property value.
Related
I currently have 2 forms. 1 holds user data and is modifiable. The other is a display/read only form.
I am trying to pull data (tbUSI.text) from ReportSettings and pass it to Form1 and display it on my UserData.text control.
I have tried using public properties but to no avail. I would rather use public properties, since its cleaner. Here is the code im using to set the property:
Public Property UserSignedInto As String
Get
Return tbUSI.Text
End Get
Set(value As String)
End Set
End Property
Here is my code attempting to call that property on the main form (form1)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
UserData.text = UserSignedInto
End Sub
It doesn't pull anything, the textbox on my main form is blank.
Take a look here:
SCCMReports = New ReportSettings
UserData.text = SCCMReports.UserSignedInto
When was the SCCMReports form ever displayed to the user? Since it was never displayed, its tbUSI.Text value will of course be empty because the user never had an opportunity to enter text.
It sounds like you need a reference to an existing instance of ReportSettings, rather than creating a new instance. Where do you have that existing instance?
If Form1 created the instance in another block of code, store it in a class-level member on Form1 (perhaps called SCCMReportsInstance or something of that nature). When the instance is created, set it to the value of that property and reference that property in your code:
UserData.text = Me.SCCMReportsInstance.UserSignedInto
If the ReportSettings form is instead creating the instance of Form1 then it can pass a reference to itself. You'd still have a property on Form1, it would just be set in the constructor. Something like this:
Sub New(ByVal sccmReportsInstance As ReportSettings)
Me.SCCMReportsInstance = sccmReportsInstance
End Sub
So when initializing the Form1 instance, you'd pass the reference:
Dim form1 As Form1
form1 = New Form1(Me)
form1.Show()
Any way you go about it, you need to access the existing instance of the displayed form in order to access its properties. A new instance would have new versions of those properties and wouldn't have the same values.
I was wondering how you would grab some text from a textbox in a selected form. I have a MDI form which contains X number of child forms. Each child form has a textbox in it with some text. When I hit the save button how do I know which form is selected and how do I grab the text from that textbox.
Private Sub Forms_Clicked(sender As Object, e As EventArgs) Handles Forms.clicked
globalVar = sender
End Sub
I was thinking to make an event that just detects when ever a form is clicked and save it's form/form ID in a global variable. Any thoughts?
You have to determine the active child from first and from there, you can check which text box you want to read its content.
Like bodjo said, you have the [YourMDIForm].ActiveMDIChild property.
What is unclear, like Plutonix said is where is your Save "Button". Did you meant :
a Save MenuItem from a MenuStrip on your MDI Parent Form ?
or a Save Button inside an MDI Child Form (or either another Form that is not part of the MDI Parent/Child system)
The first case is pretty straightforward : Use the .ActiveMDIChild of your MDIParent Form.
The secund may need some valid way to point to an actual active child form (similar to the one you tried with your globalVar... there are better ways to do it.
By the way, when you get your targeted MDIChild through .ActiveMDIChild, you must access the textbox with a Public, Friend or Protected variable. Usually, controls in forms are private. So you may have to :
Public Class [YourMDIChildClassName]
' ...
' create a Public Property
Public ReadOnly Property ContentToSave() As String
Get
Return [YourTextBox].Text
End Get
End Property
' or make your textbox public in the Form design
Public [YourTextBox] As TextBox
' ... the one or the other, not both.
' ...
End Class
Another way to access the "active" MDIChild, assuming all of your MDIChild are instances of the same class is to create a static (shared) property in your Child class :
Public Class [YourMDIChildClassName]
' ...
Private Shared _CurrentMDIChild As [YourMDIChildClassName] = Nothing
Public Shared ReadOnly Property CurrentMDIChild() As [YourMDIChildClassName]
Get
Return _CurrentMDIChild
End Get
End Property
' ...
End Class
And using the same thing you tried, but using .Activated instead of .Clicked
Public Class [YourMDIChildClassName]
' ...
Private Sub MyChildForm_Activated() Handles Me.Activated
_CurrenMDIChild = Me
End Sub
' And that's ALL this method SHOULD contain.
' If you try to add other activation tricks, like activating another Form,
' or firing up a DialogBox (worst case),
' everything will go WRONG and your application will hang in an endless loop !!!
' Be carefull when using .Activated.
' ...
End Class
Then you could access the currently active MDIChild using the static Property :
[YourMDIChildClassName].CurrentMDIChild
' => Gives you directly a VALID instance of your MDI Child (or Nothing !)
' Then you can use in your MDI Parent :
If [YourMDIChildClassName].CurrentMDIChild IsNot Nothing Then
Dim TextToSave As String = [YourMDIChildClassName].CurrentMDIChild.ContentToSave
' ... save your text...
End If
HOWEVER, because you've created a static (shared) pointer to the last active MDIChild (sort of, I know it's not a pointer like in C) you must update this pointer whenever you close an MDIChild Form !
Public Class [YourMDIChildClassName]
' ...
Private Sub [YourMDIChildClassName]_FormClosing( _
sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
If _CurrentMDIChild Is Me Then ' And "Me" is closing right now...
_CurrentMDIChild = Nothing
' We don't want memory leak or pointer to a Form that has been closed !
End If
End Sub
' ...
End Class
We are not supposed to create custom way of handling Child Form activation. MDIParent.ActiveMDIChild is there for that. However, once we want to access extended/custom/specific Properties of the Child Form that doesn't initially exists in System.Windows.Forms.Form, we need to cast the MDIParent.ActiveMDIChild to the real Form derived Type of our MDIChild. That's one other way to do it, but it's just me : I don't like castings much. Always set IDE to :
Option Explicit On
Option Strict On
Option Infer Off
Forms.Clicked ... does this event (Clicked) really exist ? I'm aware of .Click but not "Clicked". Anyway :
Public Class [YourMDIChildClassName]
' ...
Private Sub MyChildForm_Clicked() Handles Me.Click
' This part is executed when you click INSIDE the Form,
' at a location where there is NO Control.
' If you click on a control, like a Textbox, a Picturebox, a Panel, etc
' this block IS NOT EXECUTED as you've clicked on a control,
' not on the Form !
End Sub
' ...
End Class
I'm anand. I have a problem about how to get text value in textbox in user control. I make a small application. I use Form1 as main form, and in the form I put one panel. In panel I will put custom user control that contain textbox. Now, I want to get the text on the textbox in user control and show it in the msgbox. Can anyone help me to fix this problem please?
As André Leal said in the comments. If you define a public property in your user control you will be able to access the value.
Public Property textboxValue as String
Get
Return MyTextBox.text
End Get
Set(value as String)
MyTextBox.text = value
End Set
End Property
Then you can access it using code like this.
YourUserControl.textboxValue
If you don't need to edit the value of the textbox you can make the property readonly as follows.
Public ReadOnly Property textboxValue as String
Get
Return MyTextBox.text
End Get
End Property
I know that you can refer to a form "indirectly" by simply including "me" instead of "form1," for example.
Is there a way to do the same thing for form elements like text boxes or radio buttons?
Example:
If me.checked = true then
count += 1
Else
count -=1
End If
The only way to do that is to create a property named checked that wraps a check box control which is a member of your form class. Something like:
Public Property checked() As Boolean
Get
return myCheckbox.Checked
End Get
Set(ByVal Value As Integer)
myCheckbox.Checked = value
End Set
End Property
Doing this doesn't get you much though. It would actually lead to code obfuscation rather than clarity and brevity.
In VB the keyword me is a reference to an instance of the class which contains the scope of code (as a function of that class) which contains the me reference. I don't know if this is clear enough, but basically me can't be used from inside the Form class to refer to a member of the class (such as a CheckBox or RadioButton control) - only to the class itself.
The CheckBox and RadioButton controls that you place on a Form are created as private objects inside of the Form class which contains them. They are called members of the class. From within the class which contains the CheckBox and RadioButton member instances you can refer to the class itself (the Form) as me. So, assuming that you have a checkbox called "checkbox1" as a control on that form, that CheckBox control would be created as a private member inside of the Form like this:
Private checkbox1 as CheckBox
After that, from that form you could refer to that CheckBox like so:
Me.checkbox1
VB.net uses a sender variable that indicates who's action is being sent to the procedure. By adding multiple elements to the procedure's "handles" property you can use the sender to identify the element being active.
The situation:
I have a datagridview with one column (col1).
In the datagrid definition (design view), i have created this row, and set the formatting to C2 (or C0, or C - I tried them all).
then, I load my datagrid view programmatically :
dbl_myValue as double
dbl_myValue = 6.99
datagridview1.item(0,0) = dbl_myValue
The datagridView shows the data correcly : 6.99$
When I "spy" on the datagridview.item(0,0), the "Value" property is a Double.
the problem :
It doesn't work if the user manually enter a value : click in the cell, enter a numeric value (let's say 100, without decimal to avoid complexity) and then leave the cell (so no more in edit mode).
The formating just dont applies.
When I "spy" on the datagridview.item(0,0), the "value" property is a STRING.
So I guess this is the problem, but what can I do?
I've tried to go in CellValidating and stuffing it with code like:
Private Sub DataGridView1_CellValidating(....)
Dim c As Control = DataGridView_WorkOrderAddition.EditingControl
c.text = formatNumeric(c.text)
c.text = convert.toDouble(c.text)
But it still doesn't work.
Yes, when the DGV is not bound then cells default to storing strings. Setting the column's CellType property can solve that, Decimal is most appropriate for handling money values. You'll also need to implement the DataError event so you can warn the user that the string cannot be converted. Thus:
Public Class Form1
Public Sub New()
InitializeComponent()
DataGridView1.Columns(0).ValueType = GetType(Decimal)
End Sub
Private Sub DataGridView1_DataError(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles DataGridView1.DataError
MessageBox.Show(e.Exception.Message)
End Sub
End Class