8

In my project I have a Settings form and a Main form. I'm trying to call the Main form's MasterReset function from the Setting form, but nothing happens.
The Master form's Masterreset function looks like this.

public void MasterReset()
    {
        DialogResult dialogResult = MessageBox.Show("Are you sure you want to perform master reset? All settings will be set to default.", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
        if (dialogResult == DialogResult.Yes)
        {
            string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            string phonebook_path = path + "\\Phonebook\\Contacts.xml";
            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(phonebook_path);
            XmlNode xNode = xDoc.SelectSingleNode("People");
            xNode.InnerXml = "";
            xDoc.Save(phonebook_path);
            listView1.Clear();
            people.Clear();
        }
        else if (dialogResult == DialogResult.No)
        {
            return;
        }
    }

And I'm accessing it from the Settings form like this

private void btn_MasterReset_Click(object sender, EventArgs e)
{
    Main f1 = new Main();
    f1.MasterReset();
}

Why am I not seeing any results?

Boris Callens
  • 90,659
  • 85
  • 207
  • 305
Exinta Enea
  • 235
  • 3
  • 5
  • 16
  • 2
    What _issue_? What happens? Does it get in? Do you get an exception? – Andrei V Nov 29 '13 at 12:46
  • Do you mean 'method' or 'function' when you say 'void'? And never, ever say 'with no success' on StackOverflow without providing more detail about the lack of success. – Will Dean Nov 29 '13 at 12:47
  • Void is used when the function or method returns nothing and just do some stuff but you have a return in your `else if`? – J2D8T Nov 29 '13 at 12:51
  • `return` can be used to exit a method, pointless in this instance anyway as removing the `else if` would have the same result. – Lotok Nov 29 '13 at 12:53
  • Is your methd `MasterReset` inside the same class as `btn_MasterReset_Click` ??? – marsze Nov 29 '13 at 12:54
  • 2
    I would suspect that your problem is that you are creating a new instance of your Main class and calling MasterReset on that instance instead of using a existing instance. – PhoenixReborn Nov 29 '13 at 12:55
  • please see my answer as clarify the question – BRAHIM Kamel Nov 29 '13 at 12:55
  • I edited my Answer now is more clear – BRAHIM Kamel Nov 29 '13 at 12:59
  • Wow, easy. Void MasterReset() is in **public partial class Main : Form**, and btn_MasterReset_Click is in **public partial class Settings : Form**. Excuse me, when I say no success I mean nothing happens - no error occured though. – Exinta Enea Nov 29 '13 at 13:03
  • What duplicate are you talking about!? There is clearly no connection between the two of these! – Exinta Enea Nov 30 '13 at 06:31

5 Answers5

14

Do you know what composition over inheritance is?

In the form where you have MasterReset you should do something like this:

Llet's suppose that in your second form you have something like this, and let's suppose your "mainform" will be called "MasterForm".

public partial class Form1 : Form
{
    private MasterForm _masterForm;  

    public Form1(MasterForm masterForm )
    {
        InitializeComponent();
        _masterForm = masterForm;  

    }
}

Here's the code in your masterForm Class:

 private void button2_Click(object sender, EventArgs e)
 {
     Form1  form1 = new Form1(this);

 } 

Here's in your form1:

private void btn_MasterReset_Click(object sender, EventArgs e)
{
    _masterForm.MasterReset();
} 

Hope this helps!

aliteralmind
  • 19,847
  • 17
  • 77
  • 108
BRAHIM Kamel
  • 13,492
  • 1
  • 36
  • 47
9

This worked for me: In your Program class, declare a static instance of Main (The class, that is) called Form. Then, at the beginning of the Main method, use Form = new Main(); So now, when starting your app, use Application.Run(Form);

public static Main Form;

static void Main() {
    Form = new Main();
    Application.Run(Form)
}

Now, calling a function from another form is simple.

Program.Form.MasterReset();  //Make sure MasterReset is a public void
Devrok
  • 27
  • 1
  • 8
Blue0500
  • 715
  • 8
  • 16
8
namespace F1
{
    // Method defined in this class
    public partial class Form1 : Form
    {
        
        public Form1()
        {
            InitializeComponent();
           
        }

        //This method I would like to call in other form
        public void function()
        {
            MessageBox.Show("Invoked");
        }
        
        // opening the new form using button click
        private void OpenNewForm_Click(object sender, EventArgs e)
        {
            Form2 f2 = new Form2();
            f2.ShowDialog();
        }
    } 

    // This is second form
    public partial class Form2: Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        // on button click Form1 method will be called
        private void button1_Click(object sender, EventArgs e)
        {
            var mainForm = Application.OpenForms.OfType<Form1>().Single();
            mainForm.function();
        }
     }
}
Peter Bruins
  • 807
  • 9
  • 25
Sandeep
  • 83
  • 1
  • 3
3

There are multiple solutions possible. But the problem itself arise from the bad design. If you need something to be accessed by many, then why should it belong to someone? If, however, you want to inform something about anything, then use events.

Your mistake is what you are creating another instance of form1, thus MasterReset is operating with form, which is not even shown.

What you can do:

  1. Make (as Ravshanjon suggest) a separate class to handle that MasterReset (and maybe something else). But also add to it an event. form1 and form2 can both subscribe to it and whenever either of them call MasterReset - both will react.

  2. Create form dependency (as BRAHIM Kamel suggested): when you create form2, then pass to it form1 instance (as constructor parameter or by setting public property), to be able to call public non-static methods of form1.

  3. As a quick, but relatively legimate solution, make this method static:


private static Form1 _instance;

public Form1()
{
    InitializeComponents();
    _instance = this;
}

public static void MasterReset()
{
    // alot of code
    _instance.listView1.Clear();
    // alot of code
}

this way you can call MasterReset from any other form like this Form1.MasterReset(). Disadvantage of this method is what you can not have more than one instance of form2 (which is more likely anyway).

Sinatr
  • 20,892
  • 15
  • 90
  • 319
  • Thanks for your answer. Anyway, I am stuck now. Can you please take a look at discussion between Ravshanjon and me, so you can have a clear vision what did I actually modify. Or, I can undo those changes and accept your suggestions, it would probably be better. – Exinta Enea Nov 29 '13 at 14:00
1

I understand your problem, you can declare your function as public static void(also listView1 and people should be static too). Then when you want to call to like this:

private void btn_MasterReset_Click(object sender, EventArgs e)
{
    Main.MasterReset();
}
r.mirzojonov
  • 1,209
  • 10
  • 18
  • I suppose `MasterReset` resides in the same class as the handler, since it uses `listview1` etc. – marsze Nov 29 '13 at 12:55
  • @marsze I know and because of this I said to make listView1 and people static. – r.mirzojonov Nov 29 '13 at 12:57
  • Uhh... I don't like that idea. `listview1` a control on the form. – marsze Nov 29 '13 at 13:00
  • @marsze If I don't like to make an extra work I do like that ))) – r.mirzojonov Nov 29 '13 at 13:02
  • 1
    Thank you my friend, unlike the rest of the guys you understood the problem. Anyway, I made MasterReset() public static void, but how can I make listView1 and people, because they turned red (the code is not correct)? **people** is **List people = new List();** and is located beyond all voids. – Exinta Enea Nov 29 '13 at 13:08
  • @ExintaEnea make it static, like this: public static List = new List(); and go to MainDesigner.cs and change listView1 from private to public static ListView listView1; – r.mirzojonov Nov 29 '13 at 13:18
  • Changed List as well, but when it comes to the listview, having no success. I went to Form1.Designer.cs and changed the following: http://s30.postimg.org/9631kuxip/screenshot_90.png, but many parts of the code turned red, like this: http://s30.postimg.org/lyr5ks94h/screenshot_90.png – Exinta Enea Nov 29 '13 at 13:28
  • @ExintaEnea remove the word "this." before each listView1 – r.mirzojonov Nov 29 '13 at 13:31
  • I did that. Anyway, when I tried to run the program, the error occured: http://s30.postimg.org/3kl7ujm7l/screenshot_90.png I just hope that I didn't ruin the app. – Exinta Enea Nov 29 '13 at 13:41
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/42203/discussion-between-ravshanjon-and-exinta-enea) – r.mirzojonov Nov 29 '13 at 13:43