VB.NET - Handle many textboxes with less code - vb.net

I got many textboxes (about 10) in a form. I want the text in the textbox to be higlighted whenever it gets foucs. The code for that looks like:
Private Sub txtBillNo_GotFocus(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtBillNo.GotFocus
HoverText(txtBillNo)
End Sub
Private Sub HoverText(ByRef ctrl as TextBox)
ctrl.SelectAll()
End Sub
It works perfectly, but I though I could do some code optimization here. Since, I have about 10 textboxes (and many other forms containing several textboxes), I have to HoverText(TextBox) in every Private Sub.. Handles TextBox.GotFocus for every textbox in each form.
I look for any form event (or any other way) that is trigerred when focus is given to another control (textbox) within the form, either by MouseClick or TAB so that HoverText(TextBox) is needed to be written only once for a form.

You can list all your textboxes in the Handles clause:
Private Sub atextbox_GotFocus(ByVal sender As System.Object, ByVal e As _
System.EventArgs) _
Handles txt1.GotFocus, _
txt2.GotFocus, _
txt3.GotFocus, _
(...remaining text boxes..)
txt9.GotFocus, _
txt10.GotFocus
Or you can add handlers to all textboxes when loading the form:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For Each t In Me.Controls.OfType(Of TextBox)()
AddHandler t.GotFocus, AddressOf HoverText
Next
End Sub
Private Sub HoverText(ByVal sender As System.Object, ByVal e As System.EventArgs)
DirectCast(sender, TextBox).SelectAll()
End Sub

The .NET way to alter the behavior of a class is to derive a new one. That's well supported by VB.NET and Winforms as well. For any class derived from Control, you can intercept an event by overriding the protected OnXxx event where Xxx is the event name. You should be using the Enter event btw. Use Project + Add Class and make the code look like this:
Public Class MyTextBox
Inherits TextBox
Protected Overrides Sub OnEnter(ByVal e As System.EventArgs)
Me.Select(0, Me.Text.Length)
MyBase.OnEnter(e)
End Sub
End Class
Compile. Go back to your form and note that you now have a new control on the top of the toolbox. Drag it on the form and note how it now behaves the way you want it, without writing any code or event handler in your form at all.

Related

How to access DataGridView properties on an already designed Windows Form

I had already designed a windows form (Form1) with a DataGridView on it, I also have a ribbon with a button on it in which I want when I click on it, it run a code like bellow:
Private Sub Button2_Click(sender As Object, e As RibbonControlEventArgs) Handles
Button2.Click
Dim f As Form1
f = New Form1
f.Show()
'(Room for my question)
end sub
I want to be able to access my datagridview user control to add columns and rows programmatically.
How should I do that?
You can create a Public Sub on form one which where you will put the changes that you want make on the the Datagridview then call it on the Button2_Click event of your Form2.
Example:
Form 1:
Public Sub AddToDGV()
With DataGridView1
.Rows.Add(Form2.TextBox1.Text, Form2.TextBox2.Text, Form2.TextBox3.Text)
End With
End Sub
Form2:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Call Form1.AddToDGV()
End Sub

How to enable parent form using ShowDialog in Vb.Net

Hi I've migrated VB6 code to VB.Net where in VB6 one of the functionality uses modal dialogue which allows user to copy few text from parent form. But in Vb.Net ShowDialog doesn't allow user to copy anything as you guys know it just disables the parent form.
My question is, Is there a way I can enable parent form or else minimize child form to copy few text from parent form?
please don't suggest to use show instead of ShowDialog because I want to achieve this only using ShowDialog.
This VB6 Code.
Form.Show vbModal, objParent
migration wizard has below code
Form.ShowDialog
The answer may be one of design, instead of a technical workaround to .ShowDialog(). Let's take your parent form, for example, with text that may be copied for pasting within a popup modal form. I don't know the data in your parent form, so let's call it a Widget.
Public Class Widget
Public Property ID As Integer = 0
Public Property TextThatMayBeCopied As String = String.Emtpy
End Class
In your parent form's code, you would load this data into a Widget object from a database, a file, whatever.
Private _widget As Widget = Nothing
Public Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
' Assume we want the Widget with ID of 123
_widget = MyFunction.WhichLoadsWidgetDataAndReturnsWidgetObject(123)
DisplayData()
End Sub
Private Sub DisplayData()
txtID.Text = _widget.ID
txtTextThatMayBeCopied.Text = _widget.TextThatMayBeCopied
End Sub
Private Sub btnShowDialog_Click(sender As Object, e As EventArgs) Handles btnShowDialog.Click
_widget.TextThatMayBeCopied = txtTextThatMayBeCopied.Text.Trim
Dim f As New MyShowDialogForm(_widget)
f.ShowDialog
End Sub
Your target form MyShowDialogForm would take in it's own constructor an object of type Widget:
Private _widget As Widget = Nothing
Public Sub New(widget As Widget)
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
_widget = widget
End Sub
You can now access the data passed to form MyShowDialogForm via the _widget object, for example, in a button click event for btnCopyText, or however you need.
The key takeaway here is to use a method of exchanging data within different forms. Typically it becomes very messy code to use the Form classes themselves as the encapsulation for data. Instead, use classes for encapsulating data and moving it around your app.
'For example we have 2 form, form1 (main) and form2 (child)
'This Form as Main
Public Class Form1
Private Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
'if you don't have timer in child form, you must click again this button
'after you form back awhile to this form as main form
Form2.ShowDialog()
End Sub
Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
Me.Close()
Me.Dispose()
End Sub
End Class
'This Form as Child
Public Class Form2
Private Sub btnToMainAWhile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnToMainAWhile.Click
'you hide this current form to caller form, you must back here again,
'if not this form always active in background
'or if you have timer1 here with enabled property =false here, you can add this:
'Timer1.Interval = 10000
'Timer1.Enabled = True
Me.Hide()
End Sub
Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
Me.Close()
Me.Dispose()
End Sub
'if you have timer1 and you will wait for many seconds back to main form, add this:
'Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
' Timer1.Enabled = False
' Me.ShowDialog()
'End Sub
End Class

Vb.NET Windows Forms Focus Event

I am working with .Net Windows Forms application (vb.net),
I have Two Forms,
Form A = Main form
Form B = Which is being called by clicking a button on Form A
The Issue is, I want to update certain Controls(List,Grids) when ever my Form A gets Activated,
At Form_A_Load it will load controls one must, but when I open Form B and upon Exit of Exit of Form B, I want to reload Form A's controls(List,Grids).
I have tried many events
Activated,Deactivated,Enter,Leave,Enabled,Visibility changed , but could not trap any,
If I am using Activated/Deactivated with some flag to check which was triggered, then a continues loop occurs. Kindly some body suggest , the workable method
Here is the Edit code:
Public Class Form1
Private Sub Form1_Activated(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Activated
MessageBox.Show("Activated")
End Sub
Private Sub Form1_Deactivate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Deactivate
' MessageBox.Show("Deactivated")
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.Text = "Activated/Deactivated"
MessageBox.Show("This will set focus lost")
End Sub
End Class
--If a once click on Button1_Click .. "MessageBox.Show("Activated")" appears again and again.
Basically, It was something multiple forms opened, and what I did is that at the FormClosing of last Form where my code Returns to Forma A, I have checked through Loop the Opened Forms and from there I selected my Form A and Triggered the Function Which Reloads the List.
Try this:
[UPDATED]
Public Class FormA
Friend WithEvents objectFormB As FormB
Private Sub objectFormB_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles objectFormB.FormClosed
'do whatever...
End Sub
End Class

Project level conception of modal and nonmodal forms

I have project which consist of several forms and want to open it in certain modality rules which I can't achieve.
First, here is main form "Form1", then "Form11" and "Form111", "Form12" and "form121"
From main form "Form1" I can start only forms "Form11" and "Form12" like this:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Form11.Show()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Form12.Show()
End Sub
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Me.Close()
End Sub
End Class
In this situation, when "Form11" and "Form12" are showed I can easily exit application by pressing Button4 on "Form1" what will close all forms.
Now, here is another form, "Form111" which I open modally by clicking a button on "Form11"...
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim f As New Form111
f.ShowDialog(Me)
f = Nothing
End Sub
And here I have some misunderstanding or misconception of my project.
When "Form111" is opened I like it to block "Form11" but not "Form1" where I would like to (say) open "Form2" or exit application where modal form "Form111" on nonmodal form "Form11" is opened.
Is it possible to achieve such functionality with described project configuration and how?
First, the code for the button clicks in the first block may not be right. If the forms are named Form11 and Form12 that is their class name. They should be instanced as you do with Form111.
The reason the application closes is because that form (Me) is set as the startup form. If/when that closes, the app ends. You can change the app to exit when the last form closes in project properties.
As for your question, to have a dialog "block" "Form11" but not "Form1", the answer is no. Forms are either Modal (what you are calling "blocking") or Modeless. You could tell Form111 to stay on top, but it would not be "blocking" any other form.
What you are trying to do suggests that the operations on these forms may not be as well organized or planned as they need to be.

Setting focus to a textbox control

If I want to set the focus on a textbox when the form is first opened, then at design time, I can set it's tabOrder property to 0 and make sure no other form control has a tabOrder of 0.
If I want to achieve the same result at run-time, using code, how should I proceed?
Are there alternatives to using tabOrder?
I assume any run-time code will be in the form's constructor or its onload event handler?
EDIT
In other words I'd like to be able to type straight into the textbox as soon as the form appears without having to manually tab to it, or manually select it.
Because you want to set it when the form loads, you have to first .Show() the form before you can call the .Focus() method. The form cannot take focus in the Load event until you show the form
Private Sub RibbonForm1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.Show()
TextBox1.Select()
End Sub
I think what you're looking for is:
textBox1.Select();
in the constructor. (This is in C#. Maybe in VB that would be the same but without the semicolon.)
From http://msdn.microsoft.com/en-us/library/system.windows.forms.control.focus.aspx :
Focus is a low-level method intended primarily for custom control
authors. Instead, application programmers should use the Select method
or the ActiveControl property for child controls, or the Activate
method for forms.
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
TextBox1.Select()
End Sub
Using Focus method
Private Sub frmTest_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
yourControl.Focus()
End Sub
To set focus,
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
TextBox1.Focus()
End Sub
Set the TabIndex by
Me.TextBox1.TabIndex = 0
Quite simple :
For the tab control, you need to handle the _SelectedIndexChanged event:
Private Sub TabControl1_SelectedIndexChanged(sender As Object, e As System.EventArgs) _
Handles TabControl1.SelectedIndexChanged
If TabControl1.SelectedTab.Name = "TabPage1" Then
TextBox2.Focus()
End If
If TabControl1.SelectedTab.Name = "TabPage2" Then
TextBox4.Focus()
End If
I think the appropriate event handler to use is "Shown".
And you only need to focus the appropriate text box.
Private Sub Me_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
myTextbox.Focus()
End Sub
create a textbox:
<TextBox Name="tb">
..hello..
</TextBox>
focus() ---> it is used to set input focus to the textbox control
tb.focus()