|
You can use delegates to communicate between forms.
Here[^] is a decent example.
|
|
|
|
|
Well there are multiple methods. Another approach can be
- make a static class and define its data/function members
- set values of data member of this class from Form2.
- access this static class in Form1.
- Before setting (or after getting) values, you can clear all the values of static class.
It all depends on situation. Once delegates did not work for me so had to use this method
|
|
|
|
|
thanks for your useful info....
|
|
|
|
|
A key piece of information here is how the Forms are created. If there is one primary Form that creates, and Shows, the other Forms, then, at the point where you create the secondary Forms, you have a reference to that newly created Form.
That means that if you do this in your main form:
Form2 F2 = new Form2(); And you define the variable 'F2 as being within the scope of the main form: you can always access the instance of Form2, 'F2, within the main form: once you have instantiated it ... most likely in the main Form Load EventHandler.
The question that you should be asking yourself now is: "wait a minute, 'F2 has a TextBox on it, and that TextBox is an access-as-private-only Control: it can't be seen using the reference to 'F2: this won't work:
Form2 F2;
TextBox TextBoxOnForm2;
private void Form1_Load(object sender, EventArgs e)
{
F2 = new Form2();
F2.Show();
TextBoxOnForm2 =
} And this is the point at which I encourage you to start thinking about the issue of "what is the bare essential content, or control, that one Form needs to access from another ?: does it need to only access content in the Control, or does it need access to the Control itself so that it can modify the content of the Control, and/or its settings, or visual appearance, or whatever."
In this case it appears you want access to either a TextBox itself implying you might want to both read from and write to the TextBox perhaps make changes to its structrure: probably, at least, access the contents of the TextBox.
Let's take the case where you want full access to the TextBox on the instance of Form2, 'F2:
1. first define a public property in Form2 of Type TextBox:
public TextBox F2TextBox
{
private set;
get { }
} 2. then in the Load or Shown events of Form2: set that public property to the instance of the TextBox: so your code in Form2 might look like this:
public TextBox F2TextBox;
private void Form2_Load(object sender, EventArgs e)
{
F2TextBox = textBox1;
} And now in your main form, you no longer need to keep a reference to the whole instance of Form2; you just need access to the TextBox on Form2:
public TextBox TextBoxOnForm2;
private void Form1_Load(object sender, EventArgs e)
{
Form2 F2 = new Form2();
F2.Show();
TextBoxOnForm2 = F2.F2TextBox;
} Now you have access to the TextBox itself: you can manipulate its Size, BackGroundColor, whatever, an access its Text by TextBoxOnForm2.Text
And if you want to get the current content (Text) in the TextBox on F2 "on demand," for example,, by a Button Click EventHandler on the main form:
private void button1_Click(object sender, EventArgs e)
{
SomeTextBoxOnForm1.Text = TextBoxOnForm2 .Text;
} What if you need to instantly synchronize any change in the Text on F2 with other Text somewhere on the main Form: then you are going to have to define a Public Event that accesses F2's TextBox, and Raises that Event with each change in the Text in the TextBox on the instance of Form2: the main form will then have to "subscribe" to that Event. The answer above by Abhinav points you to the use of Delegates to help you with that.
There are other ways, also, to approach "access to control and/or data" between Forms, like the use of Interfaces, and Static classes.
And we could re-write this example so the only thing you could get access to on Form2 was the actual Text content of the TextBox, not the TextBox itself, but we'll leave that for you to think about. But, here's a hint: the public Property defined on Form2 is now going to look something like this:
public string F2TextBoxText
{
set { textBox1.Text = value; }
get { return textBox1.Text; }
}
"The first principle is that you must not fool yourself, and you are the easiest person to fool." Richard Feynman
modified 8-Feb-12 9:36am.
|
|
|
|
|
hellog guys...plz excuse me for this basic question. I have these three comboboxes on the form. They are bound to a common DataTable. Now when I change value of one combobox, values of other two are also changed. So in essance, every time I make change to one of the combo boxes, all of them point to same value in datatable. What can be the reason? Ask me if you need code. thnx
|
|
|
|
|
If you copy pasted these dropdowns, most likely the datasource and the binding properties have been copied too.
Check the data sources and three properties you have bound to.
|
|
|
|
|
Actually I am setting values of all the dropdowns in the same functions, so I had to copy/paste the code. Here is the code
<pre lang="c#">
private void LoadStudents()
{
StringBuilder sb = new StringBuilder();
DataTable dt = GetStudentsList(); //get data from database
DataTable dt2 = MakeTable(); //to insert concatenated NAMEs with IDs
for (int i = 0; i < dt.Rows.Count; i++)
{
// concatinate id with name
sb.Append(dt.Rows[i][0].ToString().Trim());
sb.Append(" --- ");
sb.Append(dt.Rows[i][1].ToString().Trim());
string studentName = sb.ToString();
dt2.Rows.Add(studentName );
sb.Clear();
}
LoadAccountsIntoCombos(dt2);
}
private void LoadAccountsIntoCombos(DataTable dt2)
{
//Show Students
combo1.DataSource = dt2;
combo1.DisplayMember = "StudentName";
combo1.SelectedIndex = 0;
combo2.DataSource = dt2;
combo2.DisplayMember = "StudentName";
combo2.SelectedIndex = 0;
combo3.DataSource = dt2;
combo3.DisplayMember = "StudentName";
combo3.SelectedIndex = 0;
}
</pre>
|
|
|
|
|
I think (it has been a while since I used a datatable) you can use something like
combo2.DataSource = dt2.Copy();
Basically you need to make a copy of the datatable so you are not continiously interacting with the same data.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Mycroft Holmes wrote: combo2.DataSource = dt2.Copy();
That sounds perfect.
|
|
|
|
|
Thnx..it helped...hence voted
|
|
|
|
|
In short, you assigned the same 'reference' to the comboboxes. You need to have a 'deep copy' assigned to them. (I also used to make that same mistake )
V.
|
|
|
|
|
Bear in mind that this copies the entire data table, which is often vast overkill for a combo box. In this case the table appears to be just ID/value so this is probably a correct solution, but the questioner shouldn't take away that this is something that should be applied to all data binding scenarios.
|
|
|
|
|
Generally (I love generalisations) a combo table tends to be small. However one must expect some common sense to be applied to any solution. The OP was chasing the problem of using the same datasource, the size of the datasource was not part of the problem
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Indeed, the copying is fine for this problem. I just wanted to raise the issue so the next time this guy wants to do something similar he might be reminded to think about it.
|
|
|
|
|
You should not duplicate the data, instead you should use an explicit BindingSource (DataContainer -> BindingSource -> Control ), that way each binding would be distinct, and would hold its own state.
Luc Pattyn [My Articles] Nil Volentibus Arduum
Fed up by FireFox memory leaks I switched to Opera and now CP doesn't perform its paste magic, so links will not be offered. Sorry.
|
|
|
|
|
This is the best solution and follows DRY principle. to Luc Pattyn
|
|
|
|
|
how to get names and count of tables in a database from sqlserver and MSAccess?
could u tell me pls?
|
|
|
|
|
While some database systems provide that functionality in various ways, with any database system that provides an ADO.net provider, the Connection derives (or should derive*) from System.Data.Common.DbConnection , which has a GetSchema method which returns a DataTable with that information. So I have been using the following:
System.Data.Common.DbConnection con =
this.command.Connection as System.Data.Common.DbConnection ;
if ( con != null )
{
System.Data.DataTable temp = con.GetSchema
(
"TABLES"
) ;
temp.DefaultView.RowFilter = "TABLE_TYPE='TABLE' OR TABLE_TYPE='BASE TABLE'" ;
temp.DefaultView.Sort = "TABLE_NAME" ;
This is good enough for SQL Server, Access, and Excel. But this is old code; a week or so ago I started using Oracle and MySql (and FireBird, just because) again and found that the tables provided by them are more different than I expected so I had to adapt.
* I'm looking at you Cache.
|
|
|
|
|
PIEBALDconsult wrote: a week or so ago I started using Oracle and MySql
Poor bastard, you have my sincere sympathies.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Yes, thank you. Fortunately all I need to do is pull some data from them and make copies in SQL Server, but I still need to be sure that my data access library works with them.
|
|
|
|
|
|
Lets say I have an object o, o.Ref = o1. o1 references o2 and o2 references o3.
If I set o.Ref = null, is the GC going to dispose of o1, o2 and o3? Seems like there will be no reference to o1, so that'll be disposed resulting in no ref to o2 and so on??
What I'm getting at, if I have a binary tree structure and set the root to null, are all the nodes going to get disposed in cascade fashion?
|
|
|
|
|
SledgeHammer01 wrote: What I'm getting at, if I have a binary tree structure and set the root to null, are all the nodes going to get disposed in cascade fashion?
The garbage collector will move them as soon as your application can no longer reach the object from code. It's not guaranteed in which order they are moved.
Bastard Programmer from Hell
|
|
|
|
|
SledgeHammer01 wrote: are all the nodes going to get disposed in cascade fashion? No, and disposing has nothing to do with it, and there is absolutely no reference counting. What will happen is this:
The next time the garbage collection does a collection on the generation that these things are in (which may not be ever), it will find all of them to be unreachable, and they will not be promoted to the next generation (or an older part of the same generation, if it's generation 2) and not copied to the target memory segment.
|
|
|
|
|
There are two parts to that question:
1.
if o.Ref held the only remaining reference to o1 (and o1 the only reference to o2, etc), then setting it null will make o1 (and o2 and o3) eligible for garbage collection. It will not call Dispose(), and it will not force a garbage collection to occur. When you later need more memory than is currently free inside your process, the GC may or may not free those objects (depends on their generation); if they have finalizers, then those would be called. However, if your app came to a halt, no memory would be freed, no Dispose would be called.
2.
When the GC determines all of o1, o2, and o3 are no longer alive, they will all be scrapped, in no particular order. One pointing to the other does not influence that.
Luc Pattyn [My Articles] Nil Volentibus Arduum
Fed up by FireFox memory leaks I switched to Opera and now CP doesn't perform its paste magic, so links will not be offered. Sorry.
|
|
|
|