Hi:
I wrote a project in vb6.
That project contains controls array and I want to upgrade this project to vb2005 but I have some problems.
In vb6:
I have array of checkbox
When the user check the checkbox It's index = I as integer then
Create 3 elements in 3 arrays of combobox
All this elements have the same index
When I want to determine any combobox by the index of checkbox
I will write code like this:
For i = 0 To Check1.UBound
If Check1(i).Value = vbChecked Then
Rs1.Field1 = Combo1(i).Text
Rs1.Field2 = Combo2(i).Text
Rs1.Field3 = Combo3(i).Text
End If
Next i
In VB2005:
No problem when I create the controls in container like groupbox
But I used the tag property instead of index property
If Chk.CheckState = CheckState.Checked Then
Dim CB1 As New ComboBox
Dim Cb2 As New ComboBox
Dim Cb3 As New ComboBox
CB1.Size = New Size(93, 21)
CB1.Location = New Point(176, Chk.Top)
CB1.Tag = Chk.Tag
CB1.Name = "cb1" & Chk.Tag
Grl.Controls.Add(CB1)
Cb2.Size = New Size(100, 21)
Cb2.Location = New Point(292, Chk.Top)
Cb2.Tag = Chk.Tag
Cb2.Name = "Cb2" & Chk.Tag
Grl.Controls.Add(Cb2)
Cb3.Size = New Size(38, 21)
Cb3.Location = New Point(418, Chk.Top)
Cb3.Tag = Chk.Tag
Cb3.Name = "Cb3" & Chk.Tag
Grl.Controls.Add(Cb3)
But when I want to remove row of comboboxes
By this code:
ElseIf Chk.CheckState = CheckState.Unchecked Then
For Each Cnl As Control In Grl.Controls
If Cnl.Tag = Chk.Tag Then
If TypeOf Cnl Is ComboBox Then
Grl.Controls.Remove(Cnl)
End If
End If
Next
Only Two comboboxes removed ,
Becouse more than one control of controls in groupbox have the same index !!!
I don’t know why
And I don't know how i can make the groupbox generate the unique index to it's controls
And the big problem is:
To determine the combobox in groupbox :
For Each Cnl As Control In GrL.Controls
If TypeOf Cnl Is CheckBox Then
Chk = CType(Cnl, CheckBox)
If Chk.CheckState = CheckState.Checked Then
Dim Cb As ComboBox
For Each CNL1 As Control In Grl1.Controls
If TypeOf CNL1 Is ComboBox Then
Cb = CType(CNL1, ComboBox)
If Cb.Tag = Chk.Tag Then
' do somthing
End If
End If
Next
End If
End If
Next
or :
fix the lenth of string of name property of check boxes and comboboxes.
For Each Cnl As Control In GrL.Controls
If TypeOf Cnl Is CheckBox Then
Chk = CType(Cnl, CheckBox)
If Chk.CheckState = CheckState.Checked Then
Dim Cb As ComboBox
For Each CNL1 As Control In Grl1.Controls
If TypeOf CNL1 Is ComboBox Then
Cb = CType(CNL1, ComboBox)
If Cb.Name.Substring(3) = _
Chk.Name.Substring(3) Then
' do something
End if
End If
End If
Next
End If
End If
Next
when the controls count not less than 500 elements
the program performance will be very weak
there's any other way to do that
Thanks for Read

problem of controls array in Visual Basic 2005
Jim Perry
For Each Cnl As Control In Grl.Controls
If Cnl.Tag = Chk.Tag Then
If TypeOf Cnl Is ComboBox Then
Grl.Controls.Remove(Cnl)
End If
End If
Next
The ForEach loop goes through the index from 0 to 2, so the first loop = item with index0, the second loop = item with index1, the third loop = item with index2
But if you remove itemA during the first loop, then itemB becomes the item at index0 and itemC=index1, so when the foreach loop goes to the second loop, it's looking for item with index1 which is itemC at that time.
In other words, don't use a ForEach loop if you're removing items - use a For..To.. loop instead.
lali.b
Combobox1.Tag = CheckBox1
------
I don't quite understand what you mean by 'determine if the control is numerical or not , required or not'.
-----
If you only want to save comboboxes that have numerical values (at the start of the text), then use the IsNumeric function: zTrueOrFalse = IsNumeric(combobox1.text)
Note that the IsNumeric function still returns True if there are words in the text after a number at the start. http://msdn2.microsoft.com/en-us/library/6cd3f6w1.aspx
-----
If you want a way to link the parent-CheckBox to its children-comboboxes, then you could use some type of Collection object to store the comboboxes, and make that collection object the Tag of the Checkbox. For Example:
Dim zHashTable As Hashtable
Dim zComboBox As ComboBox
zHashTable = New Hashtable ' This hashtable collection will store the Child-ComboBoxes
CheckBox1.Tag = zHashTable ' Attach the hashtable-collection to the checkbox' Tag
zComboBox = New ComboBox ' This adds a new child-combobox
zComboBox.Tag = CheckBox1 ' Point the new combobox' .Tag to the parent-checkbox
' Add the combobox to the GroupBox
GroupBox1.Controls.Add(zComboBox)
' Put the child-combobox into the parent-checkbox's hashtable-collection of children
' the zComboBox object is used as both key and value
zHashTable.Add(zComboBox, zComboBox)
' Now removing the Combobox again
GroupBox1.Controls.Remove(zComboBox)
zHashTable.Remove(zComboBox)
Now you have linked each combobox to its parent-checkbox, and each parent-checkbox carries a collection of its child-comboboxes in its own Tag property.
alihht
Blair,
If you claim "VBsux's" so much. Why do you hang around VB fora to criticize it
I don't like C languages but I don't go into C fora to criticize the language. It's a lot like going to christian fora to criticize christians. Your role becomes that of a troll. Even with all of your talents, your role in VB fora is often that of a troll.
Kenneth Gillen
easy. . .
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
checkBox1.Tag = new ControlWrapper(textBox1);
checkBox2.Tag = new ControlWrapper(textBox2);
checkBox3.Tag = new ControlWrapper(textBox3);
textBox1.Tag = new ControlWrapper(comboBox1);
textBox2.Tag = new ControlWrapper(comboBox2);
textBox3.Tag = new ControlWrapper(comboBox3);
checkBox1.CheckedChanged += checkBox1_CheckedChanged;
checkBox2.CheckedChanged += checkBox1_CheckedChanged;
checkBox3.CheckedChanged += checkBox1_CheckedChanged;
}
void checkBox1_CheckedChanged(object sender, EventArgs e)
{
CheckBox cb = sender as CheckBox;
if (cb == null) return;
ControlWrapper wrapper = cb.Tag as ControlWrapper;
if (wrapper == null) return;
TextBox tb = wrapper.Control as TextBox;
if (tb == null) return;
wrapper = tb.Tag as ControlWrapper;
if (wrapper == null) return;
ComboBox cbo = wrapper.Control as ComboBox;
if (cbo == null) return;
tb.Text = cb.Checked cbo.Text : string.Empty;
}
}
public class ControlWrapper
{
bool _isRequired = true;
Control _ctrl;
public ControlWrapper(Control ctrl, bool isRequired)
{
_ctrl = ctrl
_isRequired = isRequired;
}
public ControlWrapper(Control ctrl):base(ctrl, true){};
public Control Control { get { return _ctrl; }}
public bool IsRequired { get { return _isRequired;} {set { _isRequired = value;} }
}
maverick_majnoo
Thanks nogchoco
i mean by 'determine if the control is numerical or not , required or not'
actualy i useing module it's contain procedures and functions and use it from the forms :
like :
public sub ValidTheForm(ByVal F as Form)
'for each control in form F do validthecontrol procedure
end sub
private sub ValidTheControl( ByVal C as Control)
if c.tag="m" then ' it's required so show messagebox to user to must fill it.
if c.tag="i" then ' it numerical and user must insert only numbers
' ....................etc
end sub
and in the form i write code like this :
sub save
validtheform(me)
end sub
actualy i have no idea about the the hashtable but i will work with it and i will feedback to u
Thank You again
Blkbird
The indexproblem is as I described it: removing an item from a collection makes the index of the other items decrease by 1 and so the ForEach loop skips an item because it doesn't take the reordering of the items into account.
Here's a working example for you. It's a Form1 with 2 checkboxes: Chk (with Tag=1) and Chk2(with Tag=2) and a Groupbox (named Grl). Note that I don't have your complete code, so I had to adapt it slightly to make it work. The eventsub handles checkstatechanges for both checkboxes so I've used "sender" (which is one of the checkboxes) as the object. Just start a new WindowsApplication, add two checkboxes and a groupbox, name and tag them as mentioned, and paste the code below as the code for Form1.
Lixin wang
Tom_Liu
thans blair for yuor replay
but i have some problem with tag property that's cause me don't use it any more to determine the control
Actualy i use it to determine if this control is required or not when i validates the controls before saving the data
i need any other way to detemine the control in array of controls in container
but first i need the way to set the index to control before i create it and before set the name prperty to it !!
note: i'm trying to learn C# but i have no time for that .... maybe later
thanks again
Donald E. King
Thanks nogchoco
hashtable is WonderFull Way to do what i want.....
thank u
stallion_alpa
actually. . . control arrays were VbSux's way of gettng around some of its major deficiencies.
the proper way to do this would be to assign the associated textbox to the checkbox.tag and assign the associated combobox to the text box tag
in a checkedchanged handler cast the sender to a checkbox and cast tthat's tag to a text box and cast thats's tag to a combo box. then set the casted textbox text to the casted combobnoxes tag
because I can't stand coding in VB, this is in c# but the idea is the same. . . NOTE when you see the code in vb and compare to c# you will see why I dont care for vb.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
checkBox1.Tag = textBox1;
checkBox2.Tag = textBox2;
checkBox3.Tag = textBox3;
textBox1.Tag = comboBox1;
textBox2.Tag = comboBox2;
textBox3.Tag = comboBox3;
checkBox1.CheckedChanged += checkBox1_CheckedChanged;
checkBox2.CheckedChanged += checkBox1_CheckedChanged;
checkBox3.CheckedChanged += checkBox1_CheckedChanged;
}
void checkBox1_CheckedChanged(object sender, EventArgs e)
{
CheckBox cb = sender as CheckBox;
if (cb == null) return;
TextBox tb = cb.Tag as TextBox;
if (tb == null) return;
ComboBox cbo = tb.Tag as ComboBox;
if (cbo == null) return;
tb.Text = cb.Checked cbo.Text : string.Empty;
}
}
djchapin
Vivek Uppal
Thanks nogchoco : for your replay..
actualy : i tryed to do as u sayed but the problem still persist .
the problem is : more than one control of controls in groupbox have the same index
and some indexes missed :
example : in groupbox it have 50 control but there's no element have index 16 !
i don't know why
And your way here will cause error !!
any way to set the index to elements in container when creates the elements before i set the name to it
thanks again
Simon.Chan
Hear Hear.....
Everyone has a personal opinion but I wholeheartedly agree with Renee comment. Expressing your own personal opinions like this in a forum dedicated to the product - only serves to start arguments/flames.
Whilst you entitled to your opinion I would respectfully request that you dont express them in such a public manner in these forums. It just isnt needed and doesnt add anything to your comments.
jeff1024
Thanks nogchoco
it's works
thank you very much
but could i ask you something else
i use the tag property for determine if the control is numerical or not , required or not .
as a validation method before saving the data
there's any way else instead of tag property to derermine the control in the container .
but befor determination i need to set th index to the control before or when i create it.
Thank you again