1

I currently have two different event handlers in C#, which perform two different functions. Although how could I combine the two methods together, so only 1 button could perform both actions? (Taking into account that button1_Click event must be performed first.)

    private void button2_Click(object sender, EventArgs e)
    {
        var file = File.AppendText(@"c:\output2.txt");

        foreach (string tmpLine in File.ReadAllLines(@"c:\output.txt"))
        {
            if (File.Exists(tmpLine))
            {
                file.WriteLine(tmpLine);
            }
        }

        file.Close();

    }

    private void button1_Click(object sender, EventArgs e)
    {
        using (StreamWriter sw = File.AppendText(@"c:\output.txt"))
        {
            StreamReader sr = new StreamReader(@"c:\filename.txt");

            string myString = "";
            while (!sr.EndOfStream)
            {

                myString = sr.ReadLine();
                int index = myString.LastIndexOf(":");
                if (index > 0)
                    myString = myString.Substring(0, index);

                sw.WriteLine(myString);
            }
            button2_Click(sender, e);

        }

    }
James
  • 101
  • 1
  • 1
  • 8
  • Can you please expain a bit more detailed? The obvious answer is to put the code in one method. But I guess that's not what you are looking for!? – Achim Jun 08 '11 at 20:05
  • @Achim Thats exactly what I am trying to do, I have had to call method one (button click 1), then call method 2 that takes method ones input and processes it, outputing output2.txt, if you see what I mean? – James Jun 08 '11 at 20:19
  • StreamReader is IDisposable, and should also go in a using block. File.AppendText is also returning a StreamWriter, which should go in a using block. (Yes, you're closing it, but what if the write throws an exception?) – TrueWill Jun 08 '11 at 20:20
  • Instead of button2_click(sender,e); ,you could say just button.PerformClick(); – Rosmarine Popcorn Jun 08 '11 at 21:55

5 Answers5

11

Instead of writing the code in the event handler, bring them out into two functions and then call those functions whichever way you want from the event handler.

Chris Walsh
  • 1,863
  • 17
  • 16
  • 1
    +1. "Code under buttons" is seldom a good idea. Better yet, move the I/O logic out to a separate class. – TrueWill Jun 08 '11 at 20:22
2

You could, if I'm understanding you correctly, have one event handler call another. An event handler is "just" a method after all, so:

private void button1_Click(object sender, EventArgs e)
{
    // All the code that's currently there
    button2_Click(sender, e);
}

Or, you could extract the code from the event handlers into separate methods:

private void button1_Click(object sender, EventArgs e)
{
    WriteToOutputDotTxt();
    OtherMethodThatWritesToOutputDotTxt();
}
private void button2_Click(object sender, EventArgs e)
{
    OtherMethodThatWritesToOutputDotTxt();
}

private void WriteToOutputDotTxt()
{
    // Code that's currently in button1_Click
}

private void OtherMethodThatWritesToOutputDotTxt()
{
    // Code that's currently in button2_Click
}

The code doesn't have to be contained within the event handlers, in fact you'll find it easier (if you're interested!) to test your code if you can separate it away from your UI. You could, for example, have a class called ProcessOutputFile and move the WriteToOutputDotTxt and OtherMethodThatWritesToOutputDotTxt methods onto that class. It's then a lot easier to write tests for that code as it's not "tied into" the UI code.

Rob
  • 45,296
  • 24
  • 122
  • 150
  • Hi, I have tried your method, although it states that output.txt is in use by other method, as I made button2 call output.txt and output it as output2.txt, I have updated my code to show the changes I made – James Jun 08 '11 at 20:15
2

I try to keep most logic out of event handlers and create functions with logical names that i call from the event handlers. Then they can be called from wherever.

jumpdart
  • 1,702
  • 16
  • 35
1

Just attach two event handlers to some button:

somebutton.Click += new EventHandler(button1_Click);
somebutton.Click += new EventHandler(button2_Click);
cichy
  • 10,464
  • 4
  • 26
  • 36
  • Ordering is not guaranteed: http://stackoverflow.com/questions/1645478/order-of-event-handler-execution – Achim Jun 08 '11 at 20:25
0
// given these two methods extracted from your events
void DoBar(object sender, EventArgs e)
{

    var file = File.AppendText(@"c:\output.txt");

    foreach (string tmpLine in File.ReadAllLines(@"c:\filename.txt"))
    {
        if (File.Exists(tmpLine))
        {
            file.WriteLine(tmpLine);
        }
    }

    file.Close();

}

void DoFoo(object sender, EventArgs e)
{
        using (StreamWriter sw = File.AppendText(@"c:\output.txt"))
        {
            StreamReader sr = new StreamReader(@"c:\filename.txt");

            string myString = "";
            while (!sr.EndOfStream)
            {

                myString = sr.ReadLine();
                int index = myString.LastIndexOf(":");
                if (index > 0)
                    myString = myString.Substring(0, index);

                sw.WriteLine(myString);
            }
        }

}

    // you can subscribe like this
button1.Click += DoFoo;
button1.Click += DoBar;
button2.Click += DoBar;  

EDIT forgot my sender and eventargs

IAbstract
  • 19,551
  • 15
  • 98
  • 146