[Summary]
I have an Invoice form
with several private TextBoxes
in my C# program. When the user changes the text of those textboxes, the search form
appears. I would like to transfer some values from my dataGridView(which is linked to my database) in the search form
to those TextBoxes in the Invoice form
(when I press Enter for example).
[Description] In my Invoice form I have merchendise code textbox and merchandise name text box. When the user changes the text of those textboxes, the search form appears and the entered text will be transfered to the textbox of searchform. The searchform only has a textbox and a datagridview. When something is entered in the text box of search form the datagridview will search and show the results in the datagridview. The datagridview has reletive columns as Invoice form's textboxs . Now I want to manage to do this: when I enter on searchform, the information of the current row of the datagridview be transfered to the reletive textboxes in the Invoice form. merchandise code column to merchandise code textbox and merchandise name column to merchandise name textbox.
I could illustrate this in the following code: (I know how to get the values of selected row in datagridview my question is just the title...)
if (e.KeyCode == Keys.Enter)
{
SqlCommand sqlcmd = new SqlCommand("SELECT ID FROM X WHERE ID=" +
dataGridView1.CurrentRow.Cells[0].Value + "", sqlcon);
SqlDataReader sqldr = sqlcmd.ExecuteReader();
while (sqldr.Read())
{
InvoiceForm.CodeTextBox = sqldr[codecolumn].Tostring
InvoiceForm.NameTextBox = sqldr[Namecolumn].Tostring
InvoiceForm.BlahTextBox = sqldr[Blahcolumn].Tostring
}
}
I have tried the above code but its sais:
codeTextBox is private... not able to do so because of protection level...
Lets assume I dont want to change the protection level of those textboxes to public.
Effectively, you should avoid direct access to properties of a control in a form as it make caller code directly dependant on the UI of the form. For example, if you want to change the text box for a combo box or maybe a third party text box, you might have to make change at multiple locations.
In simple cases when the property are essentially independant, I would generally add properties to the class that would hide implementation details from the caller.
If the controls are related, then using a function might be preferable
If you do that, you might keep the properties but make then read-only so that the function is used when desired.
But if you reload the data from the database, then you might consider moving the code to the InvoiceForm and have a function similar to:
By the way, notice that I have replace the
while
loop with anif
condition. Obviously the query should return a single item as otherwise it would mean that the database contains duplicate values. If the data is bogus, why prefer last returned item to first one?I have also added the missing
();
afterToString
calls.Without implementing an Interface, there are two simple methods to reference an existing Form class from another class.
Passing the reference of the caller class (
this
) in the constructor of the callee:Using the Owner property of the callee (
Form2
). The Owner is set using the Show(Owner) or ShowDialog(Owner) methods.this
is the instance of the caller:You could also have a public Property in the callee (
Form2
), used to set the current caller (this
):Pretty much useless since the two former methods already achieve the same result using the standard features. There are other means, of course, but pretty much overkill in this context.
Here, I'm using the
Owner
property to access the instance of theForm
class that instantiated yourSearch
Form class. The example uses a public method of the caller class (yourInvoiceForm
), which the callee (yourSearch
Form) uses to pass back the values a user selected.Using
Form.Show(this)
also implies that the Form shown will be parented (not to be confused with theParent
property, though) with the Form that showed it and will stay on top of it.You could also use the
ShowDialog(this)
method, if it's preferrable in your case. The Form will be shown as modal dialog in this case.I'm making two examples using this public method:
InvoiceForm
controls. This is probably the preferred method to pass these values, because it can be more easily extended and re-used in different contexts.Public method with a class parameter:
Note that
this.Owner is InvoiceForm frm
is used to identify the currentOwner
.The
UpdateMyControls
class is the container used to transfer specific values. TheSearchForm
could act differently if the Owner was a different one.This is somewhat simplified, but you can use this selection to re-use the
SearchForm
with different callers, having different results for eachOwner
.Note: The class used to transfer the values/references, could be passed in the contructor of
SearchForm
, possibly using a well-known contract (an Interface), which defines the values and their types. Too broad to describe here, but you should consider exploring this possibility.Public method with multiple parameters: