|
They're still there because you're still holding on to a reference to the child form in your global class-scoped variables.
Normally, you'd just handle the item click in the TreeView, create a child form instance, set it up as an MdiChild, Show it and be done. But, your code is holding onto a reference that Mdi doesn't manage, so...
Either don't hold on to the reference or you'll have to subscribe to the child form's Closing event and handle it in there.
|
|
|
|
|
Dave,
Thanks for your reply.
Do you think it is necessary to create a class scope reference to child form? or just create a local referece when user click tree node, add set it as MDI child and show it? which way is better?
If we use local reference and user click tree node 1, the first child form is created and shown, how about if user click tree node 1 again? do we need to loop through all child form to check if the first child form in the collection or not, if yes, activate it, otherwise, create it, am I right?
|
|
|
|
|
Andraw Tang wrote: Do you think it is necessary to create a class scope reference to child form?
Generally, no. If your application, data model design, form code is written completely encapsulating what they are responsible for, then you normally wouldn't need a class-level variable holding a reference at all and the problem your looking at wouldn't exist at all.
Andraw Tang wrote: or just create a local referece when user click tree node, add set it as MDI child and show it? which way is better?
This is what i just told you in the last post.
Andraw Tang wrote: If we use local reference and user click tree node 1, the first child form is created and shown, how about if user click tree node 1 again?
I'd probably code it so that I'm searching the MdiChildren for the existance of a form that is working on the node in question. Of course, that would mean that the child forms are exposing a property that shows which node it's working on.
In all, I have no idea what your application is doing nor it's requirements, but you normally don't see an MDI environment hanging off a treeview. Normally, you'd only work on one item in the treeview at a time.
|
|
|
|
|
Dave,
Thanks for your detailed expaination.
My application will collect hundreds input data from user, these data is divided to several categories, each categroy has dozens of data, that's why I want to use tree view, and each node represent a category of data, and the reason I use MDI is because all these data are related together, so when user input data to a form, he can look at data in other form for reference.
After user input all the required data, we will prepare input files for a software to run calculation.
This project is now in design stage, so all the comments are very important to me.
If you have any suggestion for my case, please feel free to tell me, I am very appreciate your help.
|
|
|
|
|
Andraw Tang wrote: reason I use MDI is because all these data are related together, so when user input data to a form, he can look at data in other form for reference.
It seems very cumbersome to switch back ansd forth between two forms just so you can enter data in one of them. If the data was that important to the second form, I would probably look into including that data on the new form in some form of making it so you don't have to reference another form. This could also be a sing that your data model is a bit too ... unorganized and cumbersome. When I design a layout, the user should have everything they need on a form so that decisions can be made to other options on the form.
|
|
|
|
|
Dave,
That's a good idea that each time only on form displayed.
I am also think about that if multiple child form opened together, user input data to one form, doesn't save it then switch to other form, it will cause mess.
Do you think it is good to open the child form as moduless, then either cancel form or fill in all data in the form when click OK?
|
|
|
|
|
Sorry, child form cannot be opened as moduless.
In this case, how about if user just fill in some data in a form, he didn't save it, then click other tree node?
|
|
|
|
|
First, are you just showing the child form in the tree node click event?
Because if you set it to nothing and then call frmChild1.Show() you'll get a null reference error.
You really shouldn't initialize the forms when the form is loaded, but do it when the tree node is clicked.
Then, when you create the child node, you need to hook the form closed event.
Personally, I wouldn't define the children forms to begin with, but would use a Dictionary to store them as you create them.
But, the code would look like:
frmChild1 = New frmChildForm1
AddHandler frmChild1.FormClosed, AddressOf ChildFormClosed
End Sub
Private Sub ChildFormClosed(ByVal sender as System.Object, ByVal e as System.Windows.Forms.FormClosedEventArgs)
CType(sender, Form).Dispose
If TypeOf sender Is frmChildForm1 Then
frmChild1 = Nothing
End If
End Sub
Again, that's not the way I would do it, but that's the way it looks like you want to.
|
|
|
|
|
William,
Thanks, it works fine.
But if you have better way, would please share with us.
|
|
|
|
|
I think you'll say the following code is better solution of your problem:
Private Sub TreeView1_NodeMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseClick
Select Case e.Node.Text
Case "Node0"
Dim frm As New Form1
frm.Name = "Form1"
frm.MdiParent = Me
Dim OldForm = System.Windows.Forms.Application.OpenForms(frm.Name)
If IsNothing(OldForm) Then
OldForm = frm
End If
If Not OldForm.Visible Then
frm.Show()
Else
OldForm.Show()
OldForm.Focus()
End If
Case "Node1"
Dim frm As New Form2
frm.Name = "Form2"
frm.MdiParent = Me
frm.Show()
Case Else
MsgBox("None")
End Select
End Sub
Use <pre lang="vb"> Visual Basic Code Here.</pre>
|
|
|
|
|
In my company we use an instrument that connects to our laptops via a USB-to-Serial bridge (the instrument only communications via RS232). Now, I have figured out how to communication with the instrument from a laptop, however I am trying to figure out how to communicate with it from a PPC (most of the employees have the iPaq but some have newer PDAs that run Windows Mobile).
Below is the sample code of how my laptop software communications with the instrument. Any idea on how to do this from the PPC would be greatly appreciated.
Dim SerialPort As SerialPort = New SerialPort(COMPort, 9600, Parity.None, 8, StopBits.One)
Dim ACK(1) As Byte
Public ENQ() As Byte = {&H5}
Public BEGIN() As Byte = {&H54}
Public DataBuffer(4096) As Byte
Dim SerialPortOK As Boolean = False
SerialPort.Open()
SerialPort.Write(ENQ, 0, ENQ.Length)
Threading.Thread.Sleep(2000)
If SerialPort.BytesToRead Then
SerialPort.Read(ACK, 0, 1)
If ACK(0) = &H6 Then
SerialPortOK = True
Else
MsgBox("The instrument returned an unexpected result. Please check the instrument and try again.", MsgBoxStyle.Exclamation + MsgBoxStyle.OkOnly, "Invalid Response")
SerialPort.Close()
End If
Else
MsgBox("The instrument did not respond. Please check that it is connected and set to download mode.", MsgBoxStyle.Exclamation + MsgBoxStyle.OkOnly, "No Response")
SerialPort.Close()
End If
If SerialPortOK Then
Download = New clsDownloadInstrument(FolderName, txtDownload.Text.Trim, InstrumentNumber, SerialPort)
Me.Enabled = False
Download.BeginDownload()
End If
|
|
|
|
|
I can probably help you on this, do the ppc's? have a serial port, and which version of Visual Studio are using?
Phil
Software Developer
http://www.yorkshirehumberit.co.uk
|
|
|
|
|
I'm using visual studio 2008. The PDA has a USB (Not serial) port on the bottom. I'm connecting the USB cable for the PDA to a ATEN USB-to-Serial Bridge, which is then connected to the instrument.
|
|
|
|
|
does the pda recognise the USB Bridge as a serial port in its device manager?
Phil
Software Developer
http://www.yorkshirehumberit.co.uk
|
|
|
|
|
Hi all,
I wrote a COM add-in for Excel with VB2008 Express. While the main "Connect" class (holding all the Extensibility stuff) seems to start in the way it's supposed to, a second class seems to produce a runtime error while starting. I say "seems" because to first impression it works, but during startup it's "loadBehaviour" value in the registry is reset from 3 to 2, pointing out a runtime error during startup.
Obviously there's no way to debug the addin while Excel is starting it up... so what would be a way (the best way ) to find out which runtime error might cause that effect?
Thanks for any hints,
Michael
|
|
|
|
|
Logging[^] is one of my major development tools.
|
|
|
|
|
Thank you, Luc.
I do log the commands in my AddIn to a file, using a TextWriterTraceListener. Unfortunately that doesn't lead me anywhere - I call the AddIn class and get proper log results. But when I look at the respective Resistry values I see they have been reset (again and again).
The runtime error seems to occur during the loading process, and I guess it's an Excel activity to reset Registry values if it can't properly load an AddIn. I need to find out which statement or method in my AddIn makes the loading process fail... so I'd need a way to trace Excel's addin-loading activity, which seems to be even beyond workbook's VBA modules (guessing that from the fact that add-ins are present even without workbooks).
Do you have an idea how I could do that?
|
|
|
|
|
Did you put logging statements at the beginning of your suspected methods? All you have to do is log something like "Got to <some class:somemethod="">" at the top of your suspected methods. You don't have to put this on every method, just the top level ones.
Have you tried launching Excel (without your addin enabled), attaching the debugger to the Excel process, then loading the addin?
|
|
|
|
|
Thanks for your time, Dave.
I've added Trace statements to the relevant (likely errorous) class, starting in the New constructor. The lines are written, so it's got to be something else. But what do you mean with "...attaching the debugger to the Excel process..."? How would I do that / which debugger to use?
Looking forward,
Mick
|
|
|
|
|
Under the Tools menu in Visual Studio, Attach to Process... Oh, you may want to set a breakpoint in the constuctor of your suspect class.
|
|
|
|
|
Thank you for the hint. Unfortunately it seems like the Express version doesn't have any 'Attach to process' options - but I've just found it in SharpDevelop (which I had rarely used by now), so that I'll try to get forward with it and follow your approach.
|
|
|
|
|
Michael Schäuble wrote: the Express version doesn't have any 'Attach to process'
correct[^].
Without other debug facilities, you'd have to add more log statements to your code. Make sure you catch and log exceptions as much as possible.
|
|
|
|
|
Whoops. I didn't see you were using Express in your first post... Sorry!
|
|
|
|
|
Hi All,
I have a userform (BinSheetForm) which I bind to a datasource as per the code below.
Private Sub BinSheetForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
BsCountIdLabel.Text = iCountId.ToString
Dim Conn As New SqlConnection(CntString)
conn.Open()
adapter = New SqlDataAdapter("select * from zz_ST_Binsheets", Conn)
adapter.FillSchema(dtset, SchemaType.Source, "zz_ST_Binsheets")
adapter.Fill(dtset, "zz_ST_Binsheets")
Conn.Close()
bind.DataSource = dtset
bind.DataMember = "zz_ST_Binsheets"
End Sub
On this userform I have a datagridview that I fill with the follwing code.
Private Sub FillBinDataGrid()
With Me.BsDataGridView
.DataSource = bind
.EditMode = DataGridViewEditMode.EditOnEnter
End With
End Sub
Up to this point it works fine, but now I want to do 2 more things.
First:
The database table zz_ST_Binsheets contains columns "iCountId" and "iBinNr". I have a label on the from that contains the value of "iCountId" and a textbox where the user can enter a value for "iBinNr". The user will then press a button and the datagridview must only be filled with the selection where "iCountId" = the label value and "iBinNr" = the textbox value.
Second:
I want the changes that the user make to be saved back to the database. The changes would include editing current data, adding new rows and deleting current rows.
I am using VS2005.
Thanks in advance.
|
|
|
|
|
To remove the need to go back and refilter the data to the selected iCountId and iBinNr values, you can use client side filter capabilities of the BindingSource . The binding source has a Filter property which acts like an additional where clause of the query, but does not requery the database.
Set the BindingSource.Filter to "Where iCountId=" & textBoxiCountId.text & " AND iBinNr= " & textBoxiBinNr.text
You can then Edit the data and save changes as you would do normally. When you are finished with the filter, it can be removed by BindingSouce.RemoveFilter()
[obviously change the names of the controls to match yours]
|
|
|
|
|