Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keep the code decoupled from the GUI in C#?

Tags:

c#

winforms

I have developed a C# script that opens an XLS file, parses it and creates a list of XML files validating them.
Every main steps of the program is logged with something like this:

Console.WriteLine("Step Creating Xml 1... DONE!)
Console.WriteLine("Step Validating Xml 1... DONE!)

The XLS file path is currently hard-coded and I'm creating a tiny GUI with Windows Forms to allow the user to select the XLS file and read the steps made by the program in a TextBox.

I had no problem in creating the button to open the file dialog to select the XSL file but then, once selected, I'm puzzled on how to code the part to show the program's steps information to the user.

Which is the most common method to accomplish this task keeping the core program GUI agnostic?

like image 958
systempuntoout Avatar asked Feb 14 '11 16:02

systempuntoout


1 Answers

As said in other answers, raise an event that your GUI handles showing your log text. This is a complete examples:

1) first of all think about what informations carry with the event and extend EventArgs class for define you argument event class. I suppose to expose a string that is your log text:

public class LogEventArgs : EventArgs
{
    public string messageEvent {get;set;}
}        

2) For semplicity suppose to have your MyApplication class that expose a business method you want log. We will define and raise an event from here. Logging will be the private method who raise our log event.

public class MyApplication
{
    public void BusinessMethod(){
        this.Logging("first");
        System.Threading.Thread.Sleep(1000);
        this.Logging("second");
        System.Threading.Thread.Sleep(3000);
        this.Logging("third");
     }
}

3) Implement the event raise. For handle an event we use a delegate, that is both a description of what method declaration must be implemented in the receiver (your GUI) to consume the event and the pointer to the receiver method. We declare the event OnLogging. Inside Logging method we raise the event setting the argument with log message. We have to check the not null event handler because if there are no listener for the event, the handle will be null (null pointer to receiver event consumer method).

    public delegate void OnLoggingEventHandler(object sender, LogEventArgs e);
    public event OnLoggingEventHandler OnLogging;

    private void Logging(string message)
    {
        LogEventArgs logMessage = new LogEventArgs();
        logMessage.messageEvent = message;
        if (OnLogging != null)
        {
            OnLogging(this, logMessage);
        }
    }

4) Now we have to implement a listener of the event and a method that consume it. Suppose to have a windows form with a button that launch your application business method and a textbox where show log messages. This is our form without event listener and consumer.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        MyApplication myApp = new MyApplication();
        myApp.BusinessMethod();
    }
}

5) We define a consumer method that handle the event writing on our textbox the log messages received by the event raised. Of course the method has the same signature of the delegate.

private void MyApplication_OnLogging(object sender, LogEventArgs e)
{
    this.textBox1.AppendText(e.messageEvent + "\n");
}

6) With C# native operator we bind our OnLogging event to the event consumer.

private void button1_Click(object sender, EventArgs e)
    {
        MyApplication myApp = new MyApplication();

        myApp.OnLogging += new MyApplication.OnLoggingEventHandler(MyApplication_OnLogging);
        myApp.BusinessMethod();
    }
like image 184
palbo79 Avatar answered Sep 28 '22 03:09

palbo79