Jump to content

Recommended Posts

Posted

I have a dynamic array of textboxes (lets say 3 for this example though). I want to iterate through each and set the backColor property. I'm trying:

 

Dim value as TextBox
For Each value In txtMain 'txtMain is the array of TextBoxes
value.BackColor = My.Settings.frmMainBackColour
Next

 

I have checked my settings and a default BackColour value exists so this is the cause of the following error at run-time:

 

Object reference not set to an instance of an object

 

I think I've done this before (like yesterday haha) but my mind is on a go slow and I can't remember how I might have overcome it.

 

Any ideas?

Posted (edited)

Shouldn't you use one of the containers in VB for that rather than an array? I believe arrays are fixed length in VB so if all of the values aren't populated you will see that error

 

Generic Lists in VB.NET - ForEach, FindAll, and Sort Generic Methods

 

That way you can grow and shrink the list as required.

 

Dim listOfTextboxes As List(Of Textbox)

 

listOfTextboxes.Add(textbox1);

listOfTextboxes.Add(textbox2);

listOfTextboxes.Add(textbox3);

listOfTextboxes.Add(textbox4);

 

Dim value As Textbox

 

For Each value In listOfTextboxes

 

value.etc etc

 

Next

Edited by Jamo
Posted

It might be that you haven't specified 'Next value'

 

Alternatively, try:

 

Dim x as long
For x=LBound(txtMain) to UBound(txtMain)
txtMain(x).BackColor = My.Settings.frmMainBackColour
Next x

Posted
It might be that you haven't specified 'Next value'

 

Alternatively, try:

 

Dim x as long
For x=LBound(txtMain) to UBound(txtMain)
txtMain(x).BackColor = My.Settings.frmMainBackColour
Next x

 

It wasn't the value bit. Trying the other now...

Posted
It wasn't the value bit. Trying the other now...

 

Same error :(

 

Hmmm I like a challenge, I'm gonna try and recreate this myself and see if I can solve it, I'll let you know if I come up with a solution...

  • Thanks 1
Posted
How are you creating this dynamic array? As far as I know VB doesn't have the ability to have dynamic arrays with out using containers such as the one I suggested without keeping track of array bounds etc which gets very messy.
Posted

Dim txtMain(1) as TextBox
Dim iNumTxt as Integer = 3
ReDim txtMain(iNumTxt)

iNumTxt = 5
ReDim txtMain(iNumTxt)

 

Then to create each text box I need:

 

iNumTxt += 1
ReDim txtMain(iNumTxt)

txtMain(variableHoldingNumberOfLatestAddedBox).Name = "GIVE IT A NAME"
txtMain(...).Text = "GIVE IT SOME TEXT"
txtMain(...).Properties = "ADD WHATEVER PROPERTIES YOU WANT HERE"
Me.Controls.Add(txtMain)

 

This method works great so far, with the exception being this little stop sign I've come across. Will be some way around it though.

Posted (edited)

The List example I gave just now does what you want just wrapped up in an STL container style format without the extra vars.

 

 

Forget that last bit i just deleted I am thinking of C++ vectors! You need to use the List.Item(0) etc to access the items.

Edited by Jamo
VB is not C++..... :p
Posted
Dim txtMain(1) as TextBox
Dim iNumTxt as Integer = 3
ReDim txtMain(iNumTxt)

iNumTxt = 5
ReDim txtMain(iNumTxt)

 

Then to create each text box I need:

 

iNumTxt += 1
ReDim txtMain(iNumTxt)

txtMain(variableHoldingNumberOfLatestAddedBox).Name = "GIVE IT A NAME"
txtMain(...).Text = "GIVE IT SOME TEXT"
txtMain(...).Properties = "ADD WHATEVER PROPERTIES YOU WANT HERE"
Me.Controls.Add(txtMain)

 

This method works great so far, with the exception being this little stop sign I've come across. Will be some way around it though.

 

 

why not,

 


for x as integer = 0 to inumtxt 'or your maximum number
dim t as new textbox

with t
.name = "name"
.text = "text"
.properties = "etc"
end with

me.controls.add(t)
next

 

i'm sure i have done it like that before :confused:

 

Mark

Posted (edited)

I've just tested your code and I think the problem is with the line:

 

value.BackColor = My.Settings.frmMainBackColour

 

If you set it to a system constant color (e.g. 'Color.AliceBlue') then it works, so something seems to be wrong with the way you're accessing settings. If you're just setting their background colour to that of the main form, couldn't you just use this instead:

 

If this routine is outside of the code for frmMain, it would be:
value.BackColor = frmMain.BackColour

If it's within the code for frmMain, you use instead:
value.BackColor = Me.BackColour

 

EDIT:

Just tried adding a setting named the same as yours myself and using that worked fine, is the setting you're using set to type "System.Drawing.Color"?

 

EDIT 2:

Also noticed you're not creating new instances of TextBox when you're creating them, just before the line:

txtMain(variableHoldingNumberOfLatestAddedBox).Name = "GIVE IT A NAME"

try adding:

txtMain(variableHoldingNumberOfLatestAddedBox) = New TextBox

Edited by LosOjos
Posted
I've just tested your code and I think the problem is with the line:

 

value.BackColor = My.Settings.frmMainBackColour

If you set it to a system constant color (e.g. 'Color.AliceBlue') then it works, so something seems to be wrong with the way you're accessing settings. If you're just setting their background colour to that of the main form, couldn't you just use this instead:

 

Just tried this: Doesn't even work for me using a system colour such as value.BackColour = Color.Red

 

However, I can do txtMain(0).BackColor = My.Settings.frmMainBackColour which sets the colour fine, so the problem seems to be lying with the value For Each loop. :confused:

 

Just tried adding a setting named the same as yours myself and using that worked fine, is the setting you're using set to type "System.Drawing.Color"?

 

Yes - System.Drawing.Color in the User scope with a default value of White.

 

Also noticed you're not creating new instances of TextBox when you're creating them, just before the line:

txtMain(variableHoldingNumberOfLatestAddedBox).Name = "GIVE IT A NAME"

try adding:

txtMain(variableHoldingNumberOfLatestAddedBox) = New TextBox

 

I was already doing that - just forgot to put that line in the example above.

 

I can set the background colour when I create the textbox i.e.

 

txtMain(...).BackColor = My.Settings.frmMainBackColour

 

Which works perfectly when the application loads or a new textbox is created, but I need to be able to iterate through the currently in use textboxes and changes their colours so the user doesn't have to restart the application for changes to take effect.

Posted
why not,

 


for x as integer = 0 to inumtxt 'or your maximum number
dim t as new textbox

with t
.name = "name"
.text = "text"
.properties = "etc"
end with

me.controls.add(t)
next

i'm sure i have done it like that before :confused:

 

Mark

 

That's just a shorthand way of doing what I posted up - and that's not the part I'm having trouble with. I just posted that part up because someone asked how I was created my TextBox array.

 

Doing it that way has no advantages apart from it's a little easier on the eye.

Posted
The List example I gave just now does what you want just wrapped up in an STL container style format without the extra vars.

 

Looking into that now pal.... :)

Posted (edited)

This should work the way you're doing it, only other thing I can see that could be causing the error is the way you are 'Redim'-ing the txtMain array, when it comes to adding new text boxes, are you using 'Redim Preserve'? If you're not, this may well be causing the problem as you're erasing the pointers to all previous text boxes each time you create a new one in the array...

 

EDIT:

Just to prove my point (lol), this code works and seems to be doing exactly what you intend to do (it's all within the code for 'Form1'):

Public Class Form1

   Dim txtMain() As TextBox



   Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
       Dim x As Long

       For x = 0 To 5
           ReDim Preserve txtMain(0 To x)
           txtMain(x) = New TextBox
           txtMain(x).Name = "txtDyn" & x.ToString
           txtMain(x).Location = New Point(5, x * 25)
           Me.Controls.Add(txtMain(x))
       Next

   End Sub

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       Dim x As TextBox
       For Each x In txtMain
           x.BackColor = My.Settings.frmMainBackColor
       Next
   End Sub
End Class

Edited by LosOjos
Posted

Here's my code (with all the irrelevant bits taken out). Can you try it on yours to see if it works, as the stuff you said works for you isn't working for me - so I wonder if my environment is setup differently:

 

Imports System.IO
Imports System.Drawing

Public Class frmMain
   Dim iNumTabs As Integer = 0 ' Used to keep count of the number of tabs open
   Dim WithEvents TabControl1 As New TabControl ' This is the tab control that is defined at runtime
   Dim TabNo(iNumTabs) As TabPage ' And this is an array of tab pages which is redefined as and when needed
   Dim txtMain(iNumTabs) As TextBox ' One text box sits on one tab, so this is similar to the above array for tab pages
   Dim iIndex As Integer ' This keeps track of the current selected tab

   Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
       ' Set the tab control properties and stick it on the form
       TabControl1.Anchor = AnchorStyles.Bottom Or AnchorStyles.Left Or AnchorStyles.Right Or AnchorStyles.Top
       TabControl1.Size = New Size(590, 321)
       TabControl1.Location = New Point(0, 25)
       Me.Controls.Add(TabControl1)
       ' Add a right-click menu to the tab control (used for closing tabs etc)
       TabControl1.ContextMenuStrip = ContextMenuTabs
       ' Need at least one tabbed page so load this now
       createTabPage()
       ' Update the variable to hold the index of the last selected tab (or only tab in this case)
       iIndex = TabControl1.SelectedIndex
   End Sub

   Public Sub createTabPage()
       ' Additional tab so increase variable to keep track of this
       iNumTabs += 1
       'ReDim the tab page array and textbox array to make room for the new tab page (preserving current tab pages & textboxes
       ReDim Preserve TabNo(0 To iNumTabs)
       ReDim Preserve txtMain(0 To iNumTabs)

       ' Create the new tab page and stick it on the form (into the only tab control)
       TabNo(iNumTabs - 1) = New TabPage
       TabNo(iNumTabs - 1).Name = "TabPage" & iNumTabs
       TabNo(iNumTabs - 1).Text = "Blank File"
       TabControl1.Controls.Add(TabNo(iNumTabs - 1))

       ' Create the new textbox and add this to the tab page that we just added
       txtMain(iNumTabs - 1) = New TextBox
       txtMain(iNumTabs - 1).Name = "txtMain"
       txtMain(iNumTabs - 1).Dock = DockStyle.Fill
       txtMain(iNumTabs - 1).Multiline = True
       txtMain(iNumTabs - 1).ScrollBars = ScrollBars.Vertical
       txtMain(iNumTabs - 1).Font = New Font("Courier New", 10, FontStyle.Regular)
       txtMain(iNumTabs - 1).ForeColor = My.Settings.frmMainForeColour
       txtMain(iNumTabs - 1).BackColor = My.Settings.frmMainBackColour
       TabNo(iNumTabs - 1).Controls.Add(txtMain(iNumTabs - 1))
   End Sub
   
   Private Sub SettingsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SettingsToolStripMenuItem.Click
       ' Open the settings form, and if colour is returned as set...
       If frmSettings.ShowDialog() = DialogResult.OK Then
           Dim value As New TextBox
           ' Iterate through all currently opened tabs and update the colour
           For Each value In txtMain
               value.BackColor = My.Settings.frmMainBackColour
           Next
       End If
   End Sub
End Class

Posted
Here's my code (with all the irrelevant bits taken out). Can you try it on yours to see if it works, as the stuff you said works for you isn't working for me - so I wonder if my environment is setup differently:

 

What is 'frmSettings' made up of?

 

Where is 'ContextMenuTabs' decalred?

 

I'll have to re-create those two to get it to work.

 

At the moment, these are the errors I'm getting (should be solved once you answer my questions though):

 

Error	1	Name 'ContextMenuTabs' is not declared.
Error	2	Handles clause requires a WithEvents variable defined in the containing type or one of its base types.
Error	3	Name 'frmSettings' is not declared.

Posted (edited)

You know what, going through your code, you seem to be making the txtMain & TabNo arrays one bigger than they need to be, thus leaving a 'Null' object at the end, that might explain your error. Try replacing the 'createTabPage' sub with this code to see if it solves it:

 

    Public Sub createTabPage()

       ' Additional tab so increase variable to keep track of this
       iNumTabs += 1

       'ReDim the tab page array and textbox array to make room for the new tab page (preserving current tab pages & textboxes
       ReDim Preserve TabNo(0 To iNumTabs)
       ReDim Preserve txtMain(0 To iNumTabs)

       ' Create the new tab page and stick it on the form (into the only tab control)
       TabNo(iNumTabs) = New TabPage
       TabNo(iNumTabs).Name = "TabPage" & iNumTabs
       TabNo(iNumTabs).Text = "Blank File"
       TabControl1.Controls.Add(TabNo(iNumTabs))

       ' Create the new textbox and add this to the tab page that we just added
       txtMain(iNumTabs) = New TextBox
       txtMain(iNumTabs).Name = "txtMain"
       txtMain(iNumTabs).Dock = DockStyle.Fill
       txtMain(iNumTabs).Multiline = True
       txtMain(iNumTabs).ScrollBars = ScrollBars.Vertical
       txtMain(iNumTabs).Font = New Font("Courier New", 10, FontStyle.Regular)
       txtMain(iNumTabs).ForeColor = My.Settings.frmMainForeColour
       txtMain(iNumTabs).BackColor = My.Settings.frmMainBackColour
       TabNo(iNumTabs).Controls.Add(txtMain(iNumTabs))

   End Sub

 

And when you intialise iNumTabs, set it to -1

Edited by LosOjos
  • Thanks 1
Posted (edited)

could you not use the controls collection to loop through each one and change the colour something similiar to

 

[color=blue][font=Courier New]Sub[/font][/color][font=Courier New] [color=black]Form1_Load[/color]([color=blue]ByVal[/color]  [color=black]sender[/color] [color=blue]As[/color]  Object, [color=blue]ByVal[/color] [color=black]e[/color] [color=blue]As[/color] [color=black]EventArgs[/color]) _[/font]
[font=Courier New]  [color=blue]Handles[/color] [color=blue]MyBase[/color].[color=black]Load[/color][/font]
[b][font=Courier New]  [color=blue]Dim[/color] [color=black]control[/color]  [color=blue]As[/color] [color=black]Control[/color][/font][/b]
[b][font=Courier New]  [color=blue]For[/color] [color=blue]Each[/color] [color=black]control[/color] [color=blue]In[/color]  [color=blue]Me[/color].[color=black]Controls[/color][/font][/b]
    If control="TextBox" Then
[b][font=Courier New]    [color=black]MessageBox[/color].[color=black]Show[/color]([color=black]control[/color].[color=black]Name[/color])[/font][/b]
   End If
[b][font=Courier New]  [color=blue]Next[/color][/font][/b]
[color=blue][font=Courier New]End[/font][/color][font=Courier New] [color=blue]Sub[/color][/font]

How do you use control collection on VB.NET?

 

Obviously you would have to change MessageBox.Show(Control.Name) to control.BackColour = vbRed or whatever. Also not sure about the control name but you would need to find out the control name so that the if statement works

Edited by mac_shinobi
Posted
What is 'frmSettings' made up of?

 

Where is 'ContextMenuTabs' decalred?

 

I'll have to re-create those two to get it to work.

 

At the moment, these are the errors I'm getting (should be solved once you answer my questions though):

 

Error    1    Name 'ContextMenuTabs' is not declared.
Error    2    Handles clause requires a WithEvents variable defined in the containing type or one of its base types.
Error    3    Name 'frmSettings' is not declared.

 

1) ContextMenuTabs is a simple context menu giving the tab pages right-click functionality. Should have taken that out as we don't need it for what I'm trying to achieve here - just delete it's references from your copy of the code ;)

 

2) frmSettings it a very basic Windows form that has a colorDialog on it so the user can dynamically select the BackColor.

 

:)

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...