views:

284

answers:

3

I'm building a Notepad. I have a Find and Replace form. When I click a button that form opens, user gives two input in two textboxes and press a button. Then the RichTextBoxes from the main form is supposed to get modified.

Here's the form of the FindAndReplace form :

private void btnReplaceAll_Click(object sender, EventArgs e)
        {
            string findMe = txtFind.Text;
            string replaceMe = txtReplace.Text;
            Form1 f1 = new Form1();
            f1.MainText.Replace(findMe, replaceMe);
            //this.Hide();
        }

The problem is its not working.. I'm getting a NullReferenceException in the line f1.MainText.Replace(findMe, replaceMe); Any idea?

+2  A: 

Here you create a new instance of the form:

Form1 f1 = new Form1();

All properties are initialized to their default values (i.e. strings to null). Next you try to call the Replace method on the MainText property which is null and you get the exception:

f1.MainText.Replace(findMe, replaceMe);

You need to first initialize this property:

f1.MainText = "blablabla";
f1.MainText = f1.MainText.Replace(findMe, replaceMe);

UPDATE:

When you create the FindAndReplace form you could pass to its constructor the current value of the text:

public class Form1 : Form
{
    protected void FindAndReplace_Click(object sender, EventArgs e) 
    {
        var findAndReplaceForm = new FindAndReplaceForm(MainText.Text);
        findAndReplaceForm.ShowDialog();
        MainText.Text = findAndReplaceForm.NewText;
    }
}

public class FindAndReplaceForm : Form
{
    private readonly string _originalText;

    public FindAndReplaceForm(string originalText)
    {
        _originalText = originalText;
    }

    public string NewText 
    { 
        get 
        {
            return (_originalText ?? string.Empty).Replace(findMe, replaceMe);
        }
    }
}
Darin Dimitrov
It should also be noted that calling `f1.MainText.Replace` won't do anything. `Replace` returns a new string with the requested replacement; it doesn't perform an in-place modification (strings are immutable).
Adam Robinson
I need to initialize `f1` with the current value of `MainText`.. any way?
Bibhas
@Bibhas, what do you mean by `current` value? Where it is stored?
Darin Dimitrov
See the scenario. I write something on the MainText(RichTextBox) on form1.. then press a button to open the FindNReplace form which has two textboxes. I press the replace button on the later form. the value of MainText shud get altered..
Bibhas
Ok, now it's more clear, see my update.
Darin Dimitrov
Worked.. Thanx!!
Bibhas
A: 

Your find and replace form must know about your main form. The way you are doing it, you are creating a completely new main form, which will have no text in the main text area. When you create the Find and Replace form, you should pass your parent form, or even just the main text, to the Find and replace form, then search the main form text from the form just passed in.

You want something like the following:

public class FindAndReplaceForm
{
    private Form1 MainForm;

    public FindAndReplaceForm(Form1 parentForm)
    {
        this.MainForm = parentForm;
        //The rest of you constructor here
    }

    private void btnReplaceAll_Click(object sender, EventArgs e)
    {
        string findMe = txtFind.Text;
        string replaceMe = txtReplace.Text;

        //The following line will search the parent form
        this.MainForm.MainText.Replace(findMe, replaceMe);
        //this.Hide();
    }
}
phsr
Hierarchy can get very troublesome with multiple forms.
Lazlo
`this.ParentForm = parentForm;` this line is invalid. `this.parentform` Gets an instance of the parent form..
Bibhas
@Bibhas, you are incorrect. Its an instance variable, and it has no restrictions on getting or setting.
phsr
I saw it in the tooltip and msdn : ContainerControl.ParentForm Property: Gets the form that the container control is assigned to.
Bibhas
I forgot that parent form is defined for Forms, you just need to change the name of the instance variable then. Updating code now. If you create the application to us MDI, then you use ParentForm to tell the form which window that it belongs in
phsr
A: 

You could add static form references to your Program class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        public static Form1 F1 { get; set; }
        public static Form2 F2 { get; set; }

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            Form1 = new Form1();
            Form2 = new Form2();

            Application.Run(Form1);
        }
    }
}

Then, from any form in your application, you'll be able to use Program.Form1 or Program.Form2 as an already instantiated reference.

Lazlo
Why do we need `F1` and `F2` if we need to use Form1 to access it??
Bibhas
This does not really answer the question.
Charlie Salts