mm_ezzo

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 dont 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

 



Re: Visual Basic Language problem of controls array in Visual Basic 2005

nogChoco

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.




Re: Visual Basic Language problem of controls array in Visual Basic 2005

Blair Allen Stark

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;
}
}






Re: Visual Basic Language problem of controls array in Visual Basic 2005

mm_ezzo

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





Re: Visual Basic Language problem of controls array in Visual Basic 2005

mm_ezzo

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





Re: Visual Basic Language problem of controls array in Visual Basic 2005

nogChoco

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.




Re: Visual Basic Language problem of controls array in Visual Basic 2005

ReneeC

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.






Re: Visual Basic Language problem of controls array in Visual Basic 2005

mm_ezzo

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

 





Re: Visual Basic Language problem of controls array in Visual Basic 2005

spotty

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.





Re: Visual Basic Language problem of controls array in Visual Basic 2005

nogChoco

Actually, Blair Allen Stark gave you a hint for linking the parent-checkbox to each child-combobox: by pointing the combobox's tag to the parent-checkbox, you don't have to mess with indexnumbers because the tag points to the whole parent-checkbox object. So you would get this code:
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.






Re: Visual Basic Language problem of controls array in Visual Basic 2005

mm_ezzo

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





Re: Visual Basic Language problem of controls array in Visual Basic 2005

mm_ezzo

Thanks nogchoco

hashtable is WonderFull Way to do what i want.....

thank u





Re: Visual Basic Language problem of controls array in Visual Basic 2005

Blair Allen Stark

mm_ezzo wrote:

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

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;} }
}







Re: Visual Basic Language problem of controls array in Visual Basic 2005

nogChoco

You're welcome, mm_ezzo




Re: Visual Basic Language problem of controls array in Visual Basic 2005

mm_ezzo

Thank u Blair