Results 1 to 26 of 26

Thread: Removing tab pages at runtime

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Nov 2003
    Location
    Chicagoland
    Posts
    92

    Removing tab pages at runtime

    If you've read any of my previous posts, you may know that I am working on a project that reads in lines from an input file and parses each line as it is read. I've got that working great, thanks to the your help. But I've run into another problem.

    As the program reads each line from the input file, it creates a tab page and lists of labels and textboxes. Some of these files have hundreds of lines and I end up with hundreds of tab pages.

    I want to make it so that when another file is opened, it deletes all of the previous tab pages and other controls. Is there a way to easily clear the form of all controls and start over again?

  2. #2
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780
    This is completly off the top of my head, so expect to change it a bit. It just runs through removing the first tab until the tab control is empty of pages. For general usage, just use the MyTabThing.TabPages namespace to remove/add things.


    Code:
     Do Until MyTabThing.TabPages.Count = 0
             MyTabThing.TabPages.RemoveAt(0)
      Loop

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Nov 2003
    Location
    Chicagoland
    Posts
    92
    Alright. So now I have:

    Code:
    Do Until Me.TabControl1.TabPages.Count = 0
       Me.TabControl1.TabPages.Remove(???)
    Loop
    I'm stuck on the arguement of the Remove method. It wants to know which TabPage to remove. How would I specify that?

  4. #4

    Thread Starter
    Lively Member
    Join Date
    Nov 2003
    Location
    Chicagoland
    Posts
    92
    Sorry for the double posting, but I think I found a solution.

    Code:
    Do Until Me.TabControl1.TabPages.Count = 0
        Me.TabControl1.TabPages.Remove(Me.TabControl1.SelectedTab)
    Loop
    But it freaked me out as I saw hundreds of tabpages go flashing by. Is there someway to get rid of them all in one fell swoop?

  5. #5
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780
    Im not at work (.net) but if you just use your namespace help thing (just put the . ) then you should get a list of all the possible functions. You may have one that looks like this:

    Me.TabControl1.TabPages.Clear

    See if you can work it out from the descriptions that are given, thats what I do.

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Nov 2003
    Location
    Chicagoland
    Posts
    92
    Well the Clear method seems to do the same as the Remove. I have a large file that translates into about 360 tab pages. Either way, the program crashes when it tries to clear this many tab pages. I get the error

    ---------------------------
    An unhandled exception of type 'System.ComponentModel.Win32Exception' occurred in system.windows.forms.dll

    Additional information: Error creating window handle.
    ---------------------------

    What does this mean?

  7. #7

    Thread Starter
    Lively Member
    Join Date
    Nov 2003
    Location
    Chicagoland
    Posts
    92
    I did a little more investigation. I put my code back to

    Code:
    Do Until Me.TabControl1.TabPages.Count = 0
         Me.TabControl1.TabPages.Remove(Me.TabControl1.SelectedTab)
    Loop
    It always crashes when Me.TabControl1.TabPages.Count = 260. Is there something magical about 260?

  8. #8
    Frenzied Member dynamic_sysop's Avatar
    Join Date
    Jun 2003
    Location
    Ashby, Leicestershire.
    Posts
    1,142
    why not just do this....
    VB Code:
    1. [Color=Blue]Dim[/color] tab [Color=Blue]As[/color] TabPage
    2.         [Color=Blue]For[/color] [Color=Blue]Each[/color] tab [Color=Blue]In[/color] TabControl1.TabPages
    3.             TabControl1.TabPages.Remove(tab)
    4.         [Color=Blue]Next[/color]
    ~
    if a post is resolved, please mark it as [Resolved]
    protected string get_Signature(){return Censored;}
    [vbcode][php] please use code tags when posting any code [/php][/vbcode]

  9. #9
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    VB Code:
    1. Dim r As New TabControl()
    2.  
    3.         Dim i As Integer
    4.         For i = 0 To 1000 'add 1000 tabpages
    5.             Dim g As New TabPage()
    6.             Dim j As Integer
    7.             For j = 0 To 20 'add 20 textboxes per page
    8.                 g.Controls.Add(New TextBox())
    9.             Next
    10.             r.TabPages.Add(g)
    11.         Next
    12.         MessageBox.Show("removing")
    13.         r.TabPages.Clear()
    14.         MessageBox.Show("Cleared")

    This worked and didn't break. You must be doing something else that is affecting it.

  10. #10

    Thread Starter
    Lively Member
    Join Date
    Nov 2003
    Location
    Chicagoland
    Posts
    92
    You must be doing something else that is affecting it.
    I don't know what. Basically, this part just checks if an input file has been previously opened, and if so, remove the tab pages so the next file can be parsed and displayed.

    Here is a cut and paste of that area of the program:

    Code:
    If Me.TabControl1.TabPages.Count > 0 Then
                For Each Tab In TabControl1.TabPages
                    TabControl1.TabPages.Clear()
                Next
    End If
    Line by line:

    Code:
    If Me.TabControl1.TabPages.Count > 0 Then
    If Me.TabControl1.TabPages.Count > 0 then I know that a file has been opened previously and I need to get rid of all the old tab pages.

    If Me.TabControl1.TabPages.Count = 0 then I know that I can skip this and pop up an OpenFileDialog box to open a window. All of that works fine.

    Code:
    For Each Tab In TabControl1.TabPages
        TabControl1.TabPages.Clear()
    Go through each tab page and clear it from TabControl1

    I've tried some other files with this and if they are any larger than 100 lines (tabpages) then it crashes. In fact, the program crashes after removing about 100 tab pages. Then I always get the error that I've shown in a previous reply, that "window handle" error.

  11. #11

    Thread Starter
    Lively Member
    Join Date
    Nov 2003
    Location
    Chicagoland
    Posts
    92
    I thought I figured out the problem. I had the clear() method in a loop. From the example given below, I saw I didn't need to do that, so I changed it to:

    Code:
    If Me.TabControl1.TabPages.Count > 0 Then
                Me.TabControl1.TabPages.Clear()
    End If
    Still, I am always getting this error.

    An unhandled exception of type 'System.ComponentModel.Win32Exception' occurred in system.windows.forms.dll

    Additional information: Error creating window handle.
    What is a window handle and why is WinXP having problems creating it?

    Sorry if I'm sounding rude. I'm just very frustrated.

  12. #12
    Your Ad Here! Edneeis's Avatar
    Join Date
    Feb 2000
    Location
    Moreno Valley, CA (SoCal)
    Posts
    7,339
    Why do you want/need SO many tabpages? Can't you load them in groups of twenty or something of that nature? Is a user going to actually work with 300 tabs at a time?

    A window handle is sort of an identifier to the OS that allows a 'window' (could be a form or control) to receive messages. Its like the location in memory to send the messages to. Thats not the best description but should give you the idea.

    I don't think the problem is just simply a product of adding or removing too many tabs though. This runs fine for me and doesn't even take more than a second:
    VB Code:
    1. For cnt As Integer = 1 To 360
    2.             TabControl1.TabPages.Add(New TabPage)
    3.         Next
    4.         MsgBox(TabControl1.TabPages.Count)
    5.         TabControl1.TabPages.Clear()
    Which means the problem has to be some smaller detail. Try posting more of your code and maybe the problem will be visible.
    Last edited by Edneeis; Nov 25th, 2003 at 03:21 PM.

  13. #13

    Thread Starter
    Lively Member
    Join Date
    Nov 2003
    Location
    Chicagoland
    Posts
    92
    What my program is doing is taking a batch file that an insurance company would transmit to an agency branch. It may have 7 to 10 transactions in each file (a transaction might be an insurance application, or a claim, etc). If you've ever filled out an insurance application, you may remember that there are a lot of little checkboxes and fields to fill out. The standards group these into, on average, groups of 20 or so and assigns each group a header. There are ususally about 30-50 groups per transaction. This file is transmitted as one long text string.

    My program takes this string and chops it up into its individual fields and displays them with a label telling the user what each field is. We mainly use it to find errors in the file so we need to display everything so that we don't miss anything. I've got everything working great except this clear function.

    My users want to say, "Alright, there is a problem in this file. Let's see if the same problem exists in this other file." At this point, they want to open another file and see its contents. Without the clear function, my program just appends the new file to the end of the old file (starts creating tab pages where it left off).

    I have attached all of my code from my main form. I have a File menu with Open as the only option. All of this runs when Open is clicked.

    BTW, if anyone knows of a better way to sort through the headers, please let me know.
    Attached Files Attached Files

  14. #14
    Your Ad Here! Edneeis's Avatar
    Join Date
    Feb 2000
    Location
    Moreno Valley, CA (SoCal)
    Posts
    7,339
    Why don't you try zipping the project to debug with? Or at least the offending part. A sample dat file would be helpful as well.

    Also that has to be the longest select case every. Try this instead:
    VB Code:
    1. 'Get the header and decide which datafile to open
    2.                 Header = InputStr.Substring(1, 4).ToLower 'Mid(InputStr, 1, 4)
    3.                 'if you really need else then add the strings to an array and check contains
    4.                 Dim available As String = "1mhc,2aci,2tag,2tcg..." 'add all of them here
    5.                 If available.IndexOf(Header) = -1 Then
    6.                     DataFile = File.OpenText("c:\al3parser\data\else.dat")
    7.                 Else
    8.                     DataFile = File.OpenText("c:\al3parser\data\" & Header & ".dat")
    9.                 End If
    10.                 'if you don't really need else use the line below instead
    11.                 'DataFile = File.OpenText("c:\al3parser\data\" & Header & ".dat")

    As for the clear:
    VB Code:
    1. PaddbFlag = 0
    2.         'If a file has been opened previously, this will clear the form
    3.         TabControl1.TabPages.Clear()'no loop just clear
    4.  
    5.         'Paddb popup box goes here
    6.         Dim frmPaddbDialog As New paddb
    7.         frmPaddbDialog.ShowDialog()
    Last edited by Edneeis; Nov 25th, 2003 at 06:26 PM.

  15. #15
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780
    You may have to have at least 1 tab in the tab control at the least (this is a theory). And yes, sorry, you dont use the .clear method in that loop, just call it the once.

  16. #16

    Thread Starter
    Lively Member
    Join Date
    Nov 2003
    Location
    Chicagoland
    Posts
    92
    I did have the loop commented out around the clear method. It was in an if statement though I've since taken that out as well. I'm still having the same problem.

    That was a god awfully long select statement. Even though I wrote it, it still scared me.

    So I've made some changes, such as getting rid of the if statement and letting the clear method run the first time a file is opened. I also followed Edneeis's suggestion to put that select case into an array. I wanted to do that originally, but I couldn't figure out how to get the correct .dat file. Edneeis showed me just how obvious it was.

    So anyway, attached is the zip file of my project along with all 208 .dat files and a sample input file, ROBIN.FIX. The program expects the .dat files to be in c:\al3parser\dat, so you will need to make sure they are there if you go to run it. The way to reproduce the problem is to open ROBIN.FIX then, once it is fully loaded, click File->Open again. It should crash on the clear method (at least it does for me).
    Attached Files Attached Files

  17. #17
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780
    It also crashes here (its not just you). Ive tried various things, it appears to be the number of controls in total, not just the tabs.
    Ive added 1000 empty tabs, and removed them, it worked fine.

    Ive got a few suggestions (not this issue) to make things a bit quicker.
    When I get home Ill do a little update for you and re-attach here.

  18. #18
    Your Ad Here! Edneeis's Avatar
    Join Date
    Feb 2000
    Location
    Moreno Valley, CA (SoCal)
    Posts
    7,339
    I believe the problem stems from the tabpages being removed but not disposing properly of all of the dynamica controls on the tabs. I fixed the problem by looping through and removing then disposing of the controls on the tabs then the tabs themselves. This worked and I also changed a couple other things; Made the list of data files and their location dynamic by using an ap.config file, using Suspend/ResumeLayout which holds off on painting controls and speeds up the adding and removing, added a spalsh type screen that tells the user to wait. Refer to the comments in code for anything else especially the clean up on form_closing.

    The file was too large to attach, at first, so I didn't include the dat files in the zip.

  19. #19
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    (not using the authror's code but mine i posted in the thread earlier)... I added 1000 tab pages with 20 textboxes on each. So that's 20,000 controls. (on a machine with only 512mb)

    So I imagine, there's something about his code.

  20. #20
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    Originally posted by Edneeis
    I believe the problem stems from the tabpages being removed but not disposing properly of all of the dynamica controls on the tabs.
    So, you're thinking the Tabpage Components dispose is not removing all the controls, or all the TabControls' compent container dispose?

    perhaps its an issue with the GC?

  21. #21
    Your Ad Here! Edneeis's Avatar
    Join Date
    Feb 2000
    Location
    Moreno Valley, CA (SoCal)
    Posts
    7,339
    Yes I believe it is a problem with the GC or a matter of timing really. Since the error is related to the a Windows Handle I think that it may be something along the lines of it trying to move on to the next line of code but being kind of hung still disposing objects. The error happens if you loop and remove but if you loop, remove and dispose it doesn't. Its very odd. I couldn't reproduce the error in a sample project by just looping and testing but I didn't really see anything untoward in his code.

    I'm not sure why it happens but it happens on the removal of the 101st tabpage. Maybe its related to that specific page? Nevermind it must be related to the amount of memory used. If you dispose the tabs but not the controls then it crashes around 200.

    Also he has about 60 controls on each tab and 359 tabs, which is 21,540 controls about the same range you used.
    Last edited by Edneeis; Nov 26th, 2003 at 01:40 PM.

  22. #22

    Thread Starter
    Lively Member
    Join Date
    Nov 2003
    Location
    Chicagoland
    Posts
    92
    Wow! That's awesome. It just goes to show that I have a lot to learn.

    I'm wondering though, might it just be quicker to quit the program and/or start another one. The sample input file I gave took just about 20 secs to clear. And that was only 100K. Some of the input files we'll be dealing with are upwards of 3Meg. They didn't want to have to close the first one and then start the program again, but if I show them that this is the best that can be done, I'm sure they'll go for it.

    This has been very educational for me, even if we end up not using the stuff you guys added. I really appreciate the help and the quickness.

  23. #23
    Your Ad Here! Edneeis's Avatar
    Join Date
    Feb 2000
    Location
    Moreno Valley, CA (SoCal)
    Posts
    7,339
    Well I think you'll definately want to clean up the previous file, if you want to cut down the waiting then you could start a new instance of the form (probably convert it to an mdi format) and let the other close in the background. The thing I fear, which goes along the lines of the code I added to the form_closing event is that the gc is not going to properly clean up for you and thus you will develop a memory leak. Which especially if you are opening 3meg files will be a very bad thing.

  24. #24

    Thread Starter
    Lively Member
    Join Date
    Nov 2003
    Location
    Chicagoland
    Posts
    92
    Sorry for the double post, but I have some questions, Edneeis.

    A couple of times you added:
    VB Code:
    1. Me.Cursor = Cursors.WaitCursor
    and also:
    VB Code:
    1. Me.Cursor = Cursors.Default
    What does this mean/do?

    You moved the header array to app.config. This is an xml file, correct? It will be a seperate file when compiled? Does it have to be co-located in the same directory?

    To access the .dat files you use:
    VB Code:
    1. IO.Path.Combine(datpath, Header & ".dat")
    Is there someway to use this if the user decides to install it in another directory when they run Setup.exe?

    Finally, the way you have the Form1_closing routine written (not seeminly tied with any event), when and how is it executed?

  25. #25
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780
    Well done on the replies people, youve alll added the stuff that I was going to do . Saved me the time anyway. I added a counter in the loop and it actually loaded about 8000 controls in total, + the tabs. I dunno if this has been fixed, but there was a line of code that said

    TabControl.Controls.Add(newtab) (or something liek that)

    it would read better as

    TabControl.Tabs.AddTab(newtab)

    I have no idea if it has any difference on performance, other then saves casting it later.

    Im intrested in the result of what causes the error, I got it on a 1.8 with 512 mem. If I have time, Ill try it on my 2.8 at home, that shouldnt have any issues with memory

    I dont think its a timing issue. I created a function that removed 10 tabs at a time. then I ran that manually from a button, when it got down to 280 ish tabs left, it crashed.

  26. #26
    Your Ad Here! Edneeis's Avatar
    Join Date
    Feb 2000
    Location
    Moreno Valley, CA (SoCal)
    Posts
    7,339
    Originally posted by shadowfyre
    Sorry for the double post, but I have some questions, Edneeis.

    A couple of times you added:
    VB Code:
    1. Me.Cursor = Cursors.WaitCursor
    and also:
    VB Code:
    1. Me.Cursor = Cursors.Default
    What does this mean/do?
    This changes the cursor to the hourglass and back to notify the user that it is working.


    You moved the header array to app.config. This is an xml file, correct? It will be a seperate file when compiled? Does it have to be co-located in the same directory?
    It is a config file which has the same name as the exe and must be in the same folder as the exe but yes it is an xml file. Yes it stays seperate when compiled which is the main reason I put those things there. That way if you move the dat files or edit the list of data file names you don't have to recompile, just change it in the config file.


    To access the .dat files you use:
    VB Code:
    1. IO.Path.Combine(datpath, Header & ".dat")
    Is there someway to use this if the user decides to install it in another directory when they run Setup.exe?
    Yes since it pulls the path from the config file it can be changed on install or at any point thereafter.


    Finally, the way you have the Form1_closing routine written (not seeminly tied with any event), when and how is it executed?
    Actually it is an event, the closing event which fires during the closing of the form but before it is done closing.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width