How to open a form in a determined tab? vb .net - vb.net

I have a form with a tabcontrol and 4 tabs. I want to open a form with showdialog in a predetermined tab.
I've tried
OptionsForm.OPTS_TabControl1.SelectTab(1)
OptionsForm.OPTS_TabControl1.ShowDialog()
but it didn't work.
Any help? thanks

First Kudos for using Stackoverflow. It shows you paid attention to class =D
regarding your question, that piece of code you showed should be working. You should provide the actual error so we can try to figure out.
Does OptionsForm refer to the class or an object of a class you created?
Anyways, try to create an object of the form and then set the starting tab, like this:
Dim OptionsObject As New OptionsForm
OptionsObject.OPTS_TabControl1.SelectTab(1)
OptionsObject.OPTS_TabControl1.ShowDialog()
Another solution might be Overloading the Showdialog method, although it seems kind of an overshot.
Here's how:
Inside your OptionsForm Code:
Public Overloads Sub Showdialog(ByRef TabNumber As Integer)
OPTS_TabControl1.SelectTab(TabNumber)
Return MyBase.ShowDialog()
then call the form using
optionsform.showdialog(1)
Note: Overloading is basically creating another instance of a subrotine that accepts different arguments. read the pages 342-358 of the manual if you wish to know more.

Since you are getting a NullReferenceException, you should separate out the call to see where the null object is. Is the tab control null?.

Imports System.Drawing
Imports System.Windows.Forms
Public Class Form1
Inherits Form
Private tabControl1 As TabControl
Private tabPage1 As TabPage
Private tabPage2 As TabPage
Private Sub MyTabs()
Me.tabControl1 = New TabControl()
Me.tabPage1 = New TabPage()
Me.tabPage2 = New TabPage()
Me.tabControl1.Controls.AddRange(New Control() {Me.tabPage1, Me.tabPage2})
Me.tabControl1.Padding = New Point(15, 10)
Me.tabControl1.Location = New Point(35, 25)
Me.tabControl1.Size = New Size(220, 220)
' Selects tabPage2 using SelectedTab.
Me.tabControl1.SelectedTab = tabPage2
Me.tabPage1.Text = "tabPage1"
Me.tabPage2.Text = "tabPage2"
Me.Size = New Size(300, 300)
Me.Controls.AddRange(New Control() {Me.tabControl1})
End Sub
Public Sub New()
MyTabs()
End Sub
Shared Sub Main()
Application.Run(New Form1())
End Sub
End Class

Related

Remove Line Under ToolStrip VB.Net

I have added a ToolStrip to a form which is going to be used to add menus and set the background colour to match the forms background colour but it always displays a horizontal line under the ToolStrip which I find distracting.
My workaround so far is to use the StatusStrip and add dropdown buttons but ideally I would have liked to have used the ToolStrip as I believe this is the preferred tool for adding menus
Having researched this, I think it has something to do with the Render Property and I have read where it's been mentioned about creating an override.
Can anyone show me an example on how to achieve this in VB.Net please.
This is simply the VB.Net version of the code provided in this previous SO question.
Obviously, the line will be there at design-time on your form, but would be gone at run-time:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ToolStrip1.Renderer = New ToolStripRenderer
End Sub
Public Class ToolStripRenderer
Inherits ToolStripProfessionalRenderer
Public Sub New()
MyBase.New()
End Sub
Protected Overrides Sub OnRenderToolStripBorder(e As ToolStripRenderEventArgs)
If Not (TypeOf e.ToolStrip Is ToolStrip) Then
MyBase.OnRenderToolStripBorder(e)
End If
End Sub
End Class
End Class
An alternative would be to create a whole new class that inherits from ToolStrip and creates the renderer for you. Then the line would be gone at design-time as well. The new control would appear at the top of your ToolBox after you compile. Unfortunately, this means you'd have to delete the old ToolStrip and drag a new one (your version) onto the form and reconfigure it:
Public Class MyToolStrip
Inherits ToolStrip
Public Sub New()
MyBase.New
Me.Renderer = New ToolStripRenderer
End Sub
Public Class ToolStripRenderer
Inherits ToolStripProfessionalRenderer
Public Sub New()
MyBase.New()
End Sub
Protected Overrides Sub OnRenderToolStripBorder(e As ToolStripRenderEventArgs)
If Not (TypeOf e.ToolStrip Is ToolStrip) Then
MyBase.OnRenderToolStripBorder(e)
End If
End Sub
End Class
End Class
Thank you for explaining how to do that. I went with the second option as this seemed more convenient for what I wanted and I presume I can save that Class and reuse it on further projects.
I still need to learn the Class and explore what and how they can be used.
Public Class MyToolStrip
Inherits ToolStrip
Public Sub New()
MyBase.New
Me.Renderer = New ToolStripRenderer
End Sub
Public Class ToolStripRenderer
Inherits ToolStripProfessionalRenderer
Public Sub New()
MyBase.New()
End Sub
Protected Overrides Sub OnRenderToolStripBorder(e As ToolStripRenderEventArgs)
If Not (TypeOf e.ToolStrip Is ToolStrip) Then
MyBase.OnRenderToolStripBorder(e)
End If
End Sub
End Class
End Class
Here is a screenshot of what I am referring to
I have made the Toolstrip the same colour as the Panel I have put it into.
Underneath the Toolstrip is a white line which I find distracting and would like to be able to remove it.

Visual Basic: Write to StreamWriter from different Forms

I have tried looking for a similar problem but I haven't found any for VB.
I have multiple forms, all of which with their own design and function. Form1 creates a StreamWriter file and will launch the other forms. Form2 and so on need to be able add to the same file, however I cannot access the file from the other forms.
I have tried declaring the file as Public in Form1, and also I have tried using:
Form1:
Dim newForm As New Form2(myFile)
newForm.show()
Form2:
Public Sub New(ByVal myFile As StreamWriter)
Me.myFile = myFile
End Sub
but this will load Form2 without any of the controls I put on it in design mode.
You are missing the InitializeComponent() method
Public Sub New(ByVal myFile As StreamWriter)
InitializeComponent()
Me.myFile = myFile
End Sub
For more info read Very Simple definition of InitializeComponent(); Method

showing a new Form Using a public function in vb.net

In my application I have to show lot of forms when particular button/panels are clicked. so instead of writing
Frm = New formname
Frm.MdiParent = MDIParent
Frm.Show()
i want to have public function through which i can pass the form name.
for that i have written a function
Public Sub showForm(ByVal formname As Form)
Frm = New formname
Frm.MdiParent = MDIParent1
Frm.Show()
End Sub
Call showForm(myformname)
but problem with this is, it says formname is not defined
EDIT:
I updated my answer to reflect your comment that a form should only be opened once.
I want to have public function through which i can pass the form name.
for that i have written a function
Public Sub showForm(ByVal formname As Form)
You don´t pass the name of a form to your function but an object of type Form instead.
Here is one possible solution with a generic version of showForm:
Public Class FormManager
Private _formByName As New Dictionary(Of String, Form)
Public Sub showForm(Of T As {Form, New})(name As String, parent As Form)
Dim frm As Form = Nothing
If Not _formByName.TryGetValue(name, frm) OrElse _formByName(name).IsDisposed Then
frm = New T()
_formByName(name) = frm
End If
frm.MdiParent = parent
frm.Show()
End Sub
End Class
The FormManager holds a dictionary cache for all opened forms with Key=form name. This is to make sure that a form is only opened once. The check form.IsDisposed makes sure that you can close the form and reopen it.
Usage from the parent form:
Public Class Form1
Private fm = New FormManager()
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
fm.showForm(Of MyForm)("MyForm", Me)
End Sub
End Class
The first parameter is to identify the form name. The real magic is in the Type T which we made sure it is 1) of type or subtype Form and 2) it has a parameterless constructor (MyForm is just a placeholder for this example put in the type of your real form you want to show).
The parent parameter will bring you additional flexibility if it is not always MDIParent1. Remove it if you don´t neet the extra flexibility.
For sure you can also drop the FormManager class and put the showForm to another place.

Multiple forms, instances and using them in a class. VB.net

I have an MDI Parentform and it has multiple forms which are declared as :
Partial Public Class Giriş
Private clients As thirdperson
Private suppliers As thirdperson
Private activecontrol As thirdperson
Private proposals As transactions
Private addproposal As addtransaction
private sales as transactions
private addsales as addtransation
Private products As products
...
...
I also have a dataworks sub which works as a class but i code it in form and also for each form as below :
'for example for pressing add new button
If ActiveControl Is **clients** Or ActiveControl Is **suppliers** Then
activeform.dataworks (counter, "add new")
ElseIf ActiveControl Is products Then
products.dataworks (counter, "add new")
ElseIf ActiveControl Is addproposal Then
addproposal.dataworks (counter, "add new")
End If
i need a way to figure out how to use a vairble name for instance name. (I don't want to define each instance name everytime i just want to know if there is a way to use like below :
'for example
dim formvariable as form
formvariable.dataworks(counter,"add new") --> just want to use this and assign the value for products, proposals vs to this variable.
is this possible?
Thanks for your help in advance.
Sertac.
The proper way would be to develop an Interface that all of your Child Forms Implement. That interface would have a dataworks() method. Then you can cast the current mdichild to the interface type and run the method. This would result in strongly typed coded that makes sense.
If you just want to hack your way through it, though, then attempt grab the dataworks() sub from the current mdichild using reflection and execute it like below:
Dim frm As Form = Me.ActiveMdiChild
If Not IsNothing(frm) Then
Dim MI As Reflection.MethodInfo = frm.GetType.GetMethod("dataworks", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.IgnoreCase)
If Not IsNothing(MI) Then
MI.Invoke(frm, New Object() {counter, "add new"})
End If
End If
Here's a quick example of the Interface approach:
Public Interface Data
Sub DataWorks(ByVal counter As Integer, ByVal msg As String)
End Interface
This is what thirdperson looks like implementing the interface:
Public Class thirdperson
Implements Data
Public Sub DataWorks(counter As Integer, msg As String) Implements Data.DataWorks
Debug.Print(counter & ", " & msg)
End Sub
End Class
All of your mdichild forms would have to be modified in a similar approach.
Then the code in the MdiParent would change to:
Dim frm As Form = Me.ActiveMdiChild
If TypeOf frm Is Data Then
Dim D As Data = DirectCast(frm, Data)
D.DataWorks(counter, "add new")
End If

Create and loop through collection subset of controls

Im making a small vb.net windows form application in which I have 4 ComboBoxes. I would like to add the ComboBoxes to a collection and be able to loop through that collection to refer to each one.
There are other ComboBoxes on the form so I cannot just use the collection for the entire form (the form layout cannot be changed, e.g. to add a container, etc).
I was thinking something like the following:
Public Class Form1
Dim IoTypeCombos As New ControlCollection(Me) From {Me.IO1_ComboBox, Me.IO2_ComboBox, Me.IO3_ComboBox, Me.IO4_ComboBox}
Dim IoTypes As New Collection() From {"Out 0", "Out 1", "Input", "Analog"}
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
For Each cb As combobox In Me.IoTypeCombos
FillComboBox(cb, Types)
Next
End Sub
Function FillComboBox(cb As Control, cc As Collection) As Boolean
Dim cbc As ComboBox = CType(cb, ComboBox)
If cc.Count = 0 Then
Return False
End If
For Each cn In cc
cbc.Items.Add(cn)
Next
Return True
End Function
This doesn't raise any exception, BUT it doesn't populate the ComboBoxes either :(
The FillComboBox() works perfectly if I pass a single control to it.
What am I doing wrong? Thanks
This line is illegal:
Public Class Form1
Dim IoTypeCombos As New ControlCollection(Me) From {Me.IO1_ComboBox,
Me.IO2_ComboBox, Me.IO3_ComboBox, Me.IO4_ComboBox }
That code will run before the constructor, before Me or ION_ComboBox exist. In this case, the resulting collection contains nothing since there is nothing to put in it yet.
In other cases, referencing controls before they exist can result in a NullReference being thrown, but due to an odd bug it may not be reported. When that happens, the rest of the code is skipped and the form simply shown.
In either case, the solution is to declare your collection at the form level, but populate it in the form load event once the controls do exist. I would also use a Collection(Of T) instead (an array or List(Of T) will also work, the OP uses/asks about a collection though):
Imports System.Collections.ObjectModel
Public Class Form1
Dim IoTypeCombos As Collection(Of ComboBox) ' form and controls Do No Exist yet
Public Sub New
'...
InitializeComponent()
' NOW they exist
End Sub
Sub Form_Load
IoTypeCombos = New Collection(Of ComboBox)
IoTypeCombos.Add(IO1_ComboBox)
IoTypeCombos.Add(IO2_ComboBox)
...
If you use a List(Of ComboBox), you can populate it different ways:
' in the ctor:
IoTypeCombos = New List(Of ComboBox)({IO1_ComboBox, IO2_ComboBox...})
' using AddRange:
IoTypeCombos.AddRange({IO1_ComboBox, IO2_ComboBox...})
Not sure if you need the where clause, but if you have other comboboxes that do not have names like this and do not want them in the collection then you do need it.
Dim IoTypeComboboxes =
Me.Controls.OfType(Of Combobox)().Where(Function(cb) cb.Name.StartsWith("IO")).ToList()
'on yourFormName
'added :
'45 PictureBox:("PicBarNum1_NotLastOdig" to "PicBarNum45_NotLastOdig")
'added:
'45 PictureBox:("PicBarNum1_UkOdig" to "PicBarNum45_UkOdig")
Public Class yourFormName
Private picbarlistNum1to45_UkOdig As New List(Of PictureBox)
Private picbarlistNum1to45_UkLastNotOdig As New List(Of PictureBox)
Private sub yourFormName_Load
Call AddPicBoxesInList_OdigNoOdig()
End sub
Private Sub AddPicBoxesInList_OdigNoOdig()
picbarlistNum1to45_UkOdig.Clear()
picbarlistNum1to45_UkLastNotOdig.Clear()
picbarlistNum1to45_UkOdig = Me.Controls(0).Controls.OfType(Of PictureBox)()
.Where(Function(pb) pb.Name.StartsWith("PicBarNum") And
pb.Name.EndsWith("_UkOdig")).ToList()
picbarlistNum1to45_UkLastNotOdig = Me.Controls(0).Controls.OfType(Of
PictureBox)().Where(Function(pb) pb.Name.StartsWith("PicBarNum") And
pb.Name.EndsWith("_NotLastOdig")).ToList()
End Sub
End Class