I am trying to make a find, find next function for my program, which I did manage to do with this code:
int findPos = 0;
private void button1_Click(object sender, EventArgs e)
{
try
{
string s = textBox1.Text;
richTextBox1.Focus();
findPos = richTextBox1.Find(s, findPos, RichTextBoxFinds.None);
richTextBox1.Select(findPos, s.Length);
findPos += textBox1.Text.Length;
//i = richTextBox1.Find(s, i + s.Length, RichTextBoxFinds.None);
}
catch
{
MessageBox.Show("No Occurences Found");
findPos = 0;
}
}
And it works great in form1 but if I use this code and try to call it from form2 It doesn't do anything:
//Form1
public void FindNext()
{
try
{
this.Focus();
Form2 frm2 = new Form2();
string s = frm2.textBox1.Text;
richTextBox1.Focus();
findPos = richTextBox1.Find(s, findPos, RichTextBoxFinds.None);
richTextBox1.Select(findPos + 1, s.Length);
findPos += textBox1.Text.Length;
}
catch
{
MessageBox.Show("No Occurences Found");
findPos = 0;
}
}
//Form2
private void button1_Click(object sender, EventArgs e)
{
Form1 frm1 = new Form1();
frm1.FindNext();
}
Does any one know why this is?
Thanks,Tanner.
string s = Interaction.InputBox("enter search text", "Notepad-search", "", 100, 100);
//The above syntax is from vb.net so add reference as microsoft.VisualBasic from references. The above code creates an alertbox. Then type the text which you want search and click on ok.
int f = richTextBox1.Find(s);
if (f >= 0)
{
MessageBox.Show("search Text is found");
}
else
{
MessageBox.Show("search Text is not found");
}
I think you may be confused in how you reference Form1 and Form2 from each other.
Calling new Form() and new Form2() create references to new instances of Form1 and Form2, they don't reference the forms that are already open. You need to get the references for the existing instances.
Assuming that Form1 is the main form for your application and it creates and shows Form2, you can either add a property to Form2 that represents the instance of Form1 that created it, or you can appropriate the Owner property for this purpose (I'd recommend that).
In your code on Form1 that shows Form2 initially (not in the code you have above), call frm2.Show(this) instead of just frm2.Show(). This will set the Owner property of your Form2 instance equal to thinstance of Form1 that opened it.
Then change your button code for Form2 to this:
private void button1_Click(object sender, EventArgs e)
{
Form1 frm1 = (Form1)Owner;
frm1.FindNext();
}
This will make you reference the existing form rather than a new one, which is what you want.
As far as the FindNext function goes, you have two choices: either you can hold on to the reference of Form2 (though you probably want to do this anyway) and access the text directly, or you can change FindNext to take a string (this is what I'd recommend).
public void FindNext(string searchText)
{
try
{
this.Focus();
richTextBox1.Focus();
findPos = richTextBox1.Find(searchText, findPos, RichTextBoxFinds.None);
richTextBox1.Select(findPos + 1, searchText.Length);
findPos += searchText.Length;
}
catch
{
MessageBox.Show("No Occurences Found");
findPos = 0;
}
}
Then change the call to frm1.FindNext() on Form2 to frm1.FindNext(textBox1.Text):
private void button1_Click(object sender, EventArgs e)
{
Form1 frm1 = (Form1)Owner;
frm1.FindNext(textBox1.Text);
}
Looks like you are referencing two different instances of Form2.
In your Form1.FindNext() you have a new instance of Form2 that you are creating and getting the text value from which is different to the instance where you are calling your FindNext() from.
What you might want to do is to pass in the instance of the form to FindNext(). So your function would be...
//Form1
public void FindNext(Form2 frm2)
{
try
{
this.Focus();
string s = frm2.textBox1.Text;
richTextBox1.Focus();
findPos = richTextBox1.Find(s, findPos, RichTextBoxFinds.None);
richTextBox1.Select(findPos + 1, s.Length);
findPos += textBox1.Text.Length;
}
catch
{
MessageBox.Show("No Occurences Found");
findPos = 0;
}
}
//Form2
private void button1_Click(object sender, EventArgs e)
{
Form1 frm1 = new Form1();
frm1.FindNext(this);
}
By writing Form1 frm1 = new Form1();, you're creating a brand-new instance of the Form1 form, which never gets any text and is never shown to the user.
You need to pass the original Form1 instance to Form2 in Form2's constructor.
Similarly, when you write Form2 frm2 = new Form2(); in FindNext, you're making a brand-new Form2 instance without any text.
Instead, you should pass the text as a parameter to the FindNext method.
For example:
public void FindNext(string searchText) {
...
findPos = richTextBox1.Find(searchText, findPos, RichTextBoxFinds.None);
...
}
originalForm.FindNext(textBox1.Text);
Your textbox on the new instance of frm1 will have no value surely? So there is nothing for the method to do...
Try stepping through the code and checking you actually have values to work with?
When you say:
Form1 frm1 = new Form1();
You are creating a fresh version so any extra information thats been added you dont have when accessing frm1
Try this and you will see what I mean
Form1 frm1 = new Form1();
frm1.Show();
When this code is excecuted you will see that you have actually made another instance of your form.
What you need to do is work with the original instance rather than create a new one, so that you still have all that information in your textboxes.
I'll leave you to work this one out, but there is you answer :)
Related
I want to display the position of form 2 according to my wishes in Form1, to be precise, placed on the right. I write this code in form1 :
public static int ParentX, ParentY;
private void BT_ShowForm2_Click(object sender, EventArgs e)
{
using (Form2 Frm = new Form2 ())
{
ParentX = Location.X;
ParentY = Location.Y;
Frm.ShowDialog();
}
and this code is in form2 :
private void Form2_Load(object sender, EventArgs e)
{
Location = new Point(Form1.ParentX + 385, Form1.ParentY + 120);
}
when form1 is in the normal position, the code works as I want, but when form1 is in Maximize position, Form2 is no longer in the position I want. I want form2 to appear in the same position when form1 is in Normal and Maximal positions. how to achieve that?
sorry if this question is wrong, I'm still in the learning stage, and not very good at English.
Does this Work?
if (Form1.WindowState == FormWindowState.Maximized)
{
//Place form
} else {
Location = new Point(Form1.ParentX + 385, Form1.ParentY + 120);
}
Note: Form2 is MDI Child Form and I set all Form1's modifiers to Public
my method is not working when i want to change color or text or etc...
For example: There is two forms, Form1 and Form2. In Form2: label1.Click event i did this:
In Form2:
private void label1_MouseClick(object sender, MouseEventArgs e)
{
Form1 f1 = new Form1();
Label name = ((Label)sender);
f1.getInfoLabel(name);
}
Okay, everythings working until here, but in there:
In Form1:
public void getInfoLabel(Label obj)
{
pictureBox1.BackColor = obj.Forecolor; //not working
TextBox1.Text = obj.Text; //not working
MessageBox.Show(obj.Forecolor.ToString()); //working
MessageBox.Show(obj.Text); //working
}
Any help? Please.
Instead of
Form1 f1 = new Form1();
use
Form1 f1 = this.MDIParent as Form1;
if (f1 != null)
{
f1.getinfolabel(sender as Label);
}
As has been pointed out, you are creating a new Form1 instance and interacting with that instead of interacting with the parent form. As long as you are correctly setting MDIParent of Form2 then the above should work.
An alternate is to use:
Form1 f1 = Appliction.OpenForms.OfType<Form1>().FirstOrDefault();
if (f1 != null)
{
f1.getinfolabel(sender as Label);
}
I have 2 win forms..Form A and B, form B is let's say child and A is parent...
Form B is sending some data to A, but i have duplicate process with form A when i close form B...a second form A opens up...
This is the code that I put in form B...but the problem is that the value from form B is not "going" to form A...with this code only form A opens up, there is no duplicate process and B closes up, but no data comes from B to A...
This is the code:
private void button1_Click(object sender, EventArgs e)
{
//Index of the row which is currently selected.
int myIndex = dataGridView1.CurrentRow.Index;
DataGridViewRow row = this.dataGridView1.Rows[myIndex];
brdok = row.Cells["Broj_dokumenta"].Value.ToString();
FormCollection fc = Application.OpenForms;
bool FormFound = false;
foreach (Form frm in fc)
{
if (frm.Name == "Main")
{
//Open form A
Main f = new Main();
f.textRadniNalog.AppendText(brdok);
f.Focus();
FormFound = true;
}
}
if (FormFound == false)
{
Main f = new Main();
f.Show();
}
//close form B
this.Close();
}
The other answer explains how you can keep your current basic architecture, except without the specific bug. That said, Marko's comment is a better answer. Here's what that would look like:
partial class Main : Form
{
private void button1_Click(object sender, EventArgs e)
{
// Add whatever other initialization is needed here, of course
new FormB(this).Show();
}
}
partial class FormB : Form
{
private Main _main;
public FormB(Main main)
{
_main = main;
}
private void button1_Click(object sender, EventArgs e)
{
//Index of the row which is currently selected.
int myIndex = dataGridView1.CurrentRow.Index;
DataGridViewRow row = this.dataGridView1.Rows[myIndex];
brdok = row.Cells["Broj_dokumenta"].Value.ToString();
_main.textRadniNalog.AppendText(brdok);
_main.Focus();
//close form B
this.Close();
}
}
If it's actually possible for the Main form to be closed while FormB is open (something you can prevent by showing FormB using the ShowDialog() method instead of the Show() method), then you can add logic to account for that:
partial class FormB : Form
{
private Main _main;
public FormB(Main main)
{
_main = main;
if (_main != null)
{
_main.FormClosed += (sender, e) => _main = null;
}
}
private void button1_Click(object sender, EventArgs e)
{
if (_main != null)
{
//Index of the row which is currently selected.
int myIndex = dataGridView1.CurrentRow.Index;
DataGridViewRow row = this.dataGridView1.Rows[myIndex];
brdok = row.Cells["Broj_dokumenta"].Value.ToString();
_main.textRadniNalog.AppendText(brdok);
_main.Focus();
}
else
{
new Main().Show();
}
//close form B
this.Close();
}
}
If needed, you can similarly handle the scenario where the Main form could be opened after FormB is shown; the code that does that would of course need to know about the FormB instance, and would pass the new Main form instance reference to it when it shows the form. In that case — where forms rely on each other but come and go on some arbitrary mechanism — it would be best, rather than having each individual form have to know what other form(s) have to react to them, for you to have some top-level controller object that deals with all of the interactions, including being the go-between for events and state changes in different windows.
looks like you are creating a new instance even when the form is found
if (frm.Name == "Main")
{
//Open form A
Main f = new Main();
please try changing it to
if (frm is Main)
{
Main f = frm as Main;
f.textRadniNalog.AppendText(brdok);
f.Focus();
or
var mainFrm=fc.OfType<Main>().FirstOrDefault();
if (mainFrm != null)
{
mainFrm.textRadniNalog.AppendText(brdok);
mainFrm.Focus();
}
else
{
Main f = new Main();
f.Show();
}
How do you change the text in the Titlebar in Windows Forms?
When I open a new form I want it to say "Bob, the next time i click new and open a form it should say "Bob1"
I tried to use TryParase() it to string and that wont work.
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
Form2 childform2 = new Form2();
decimal childcount;
childform2.MdiParent= this;
string menuname;
menuname = "untilted" + childcount.ToString();
childform2.Text = menuname;
childform2.Show();
childcount++;
}
You need to keep childcount around longer than just that method. Since you declare it inside the method, it will reset to 0 each time you run this code. Declare the variable outside of the method, so something like this:
int childcount=1;
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
Form2 childform2 = new Form2();
childform2.MdiParent= this;
string menuname;
menuname = "untilted" + childcount.ToString();
childform2.Text = menuname;
childform2.Show();
childcount++;
}
I have a DataGridView on my Form2 and textboxes on form1. When I click on one of the DataGridView rows, I want to show every cell of the DataGridView copy in texboxes of form1.
I tried to change type of textboxes to 'public' then I wrote this in form2:
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex < 0 || e.ColumnIndex < 0)
return;
Form1 fr1 = new Form1();
fr1.textBox1.Text = "123";
Form2.ActiveForm.Close();
}
but nothing copied in texbox1 of form1.
Please Help me.
IT's a common mistake:
the line
Form1 fr1 = new Form1();
creates a new instance of Form1 and the var fr1 doesn't refers to the original Form1 displayed.
To solve this kind of problem you need to pass the original instance of Form1 to the constructor of Form2, save the reference in a global instance var and use that reference inside form2. For example:
CALLING:
Form2 fr2 = new Form2(this)
FORM2 CONSTRUCTOR:
public class Form2 : Form
{
private Form1 _caller = null;
public Form2(Form1 f1)
{
_caller = f1;
}
}
DATAGRIDVIEW_CELLCLICK
private void dataGridView1_CellClick(....)
{
if (e.RowIndex < 0 || e.ColumnIndex < 0)
return;
_caller.textBox1.Text = "123";
this.Close();
}