views:

81

answers:

4

Hello there! Iam trying to use a method in class, from another class.

namespace Crystal.Utilities
{
   public class Logging
   {
      public static void Log()
      {
          //dostuff
          Crystal.MainForm.general_log_add_item("Hello World");
      }
   }
}

namespace Crystal
{
   public partial class MainForm : Form
   { 
      public void general_log_add_item(string msg)
      {
         listBox1.Items.Add(msg);
      }
   }
} 

I want to be able to call Crystal.Utilities.Logging.Log() from anywhere, and that to be able to call Crystal.MainForm.general_log_add_item() . But It doesnt let me, becuase if I put it as public, then I cant see it, if its static then It cant interract with my listbox :/

+1  A: 

You have to understand that the window is not static, there is one instance of him, thats why the method cant be static, you can use Application.Windows to reach this instance and call the add method.

or you can register the window in his constructor on another class that will mediate the Logging and the window.

If you don't understand tell me and I'll try to be more clear

Chen Kinnrot
The basic idea is to have my methods in different namespaces like "Crystal.Utilities" and in utilities namespace, there is a class Logging. Logging have Log method, that I want to be able to call anywhere from Crystal namespace. Log writes string to file, AND adds an item to a listBox in the mainform. AM I able to do this? Or this is a stupid idea at all? Thank you very much for helping!
Dominik
Yes this is a good idea, the problem is the coupling you create between your log util to the window, I recommend you to extract an interface from your window and add a method to your logger that will get this interface as a parameter, the interface will have a method called write to log, and will get a string parameter as the message, the window will implement this interface and in the constructor will register himself to the log util as a log reporter.
Chen Kinnrot
Could you give me some snippet please? Since Iam new to C# , I dont understand everything, that you said.
Dominik
Sure I'll put it in my blog, give me 10 minutes and go to http://kinnrot.blogspot.com/
Chen Kinnrot
WoW awesome, thank you.
Dominik
go here http://kinnrot.blogspot.com/2010/09/simple-abstraction-and-decoupling.html
Chen Kinnrot
implented it, thanks.
Dominik
+2  A: 

Instead of implementing it as a static method, try implementing as a singleton. It's a common trick to make an instance global in scope, and restrict to one instance, without making everything static (and thus unable to be used as an instance).

KeithS
thanks for the tip, but singleton looks a little complicated for me :OAnyways, thanks for heads up, I'll take a look at this thing later.
Dominik
+1  A: 

When you declare a method as "static" you're saying that it's not dependent upon a specific instance of the class it's in.
For example if you have a class named "chair" and you want to count how many chairs there are, you'll do that with a static field, and a static method to return that field's value.
The count of all chairs is not related to a specific chair.
In your case you want to add a static method to add an item to a specific instance of a Form. That's impossible and doesn't make sense.
If you want to add an item to a listBox, it must be through a public method.
So basically what I'm saying is - rethink what you're trying to do, there's a good explanation as to why you're not succeeding in doing that.

Oren A
thanks for the info, critic. Iam gonna thinkg this over again.
Dominik
Making you think must be a good thing (-:
Oren A
+2  A: 

This is a wrong approach. Your class should not call into the UI, as the UI could change. The class should not know nor care about the UI. Instead, the class could expose an event that the form could subscribe to, and update based upon the information contained within the event's arguments.

Here's a hastily thrown together example.

class Program
{
    static void Main()
    {
        Logger.OnLogging += Logger_OnLogging;
        Logger.Log();
        Logger.OnLogging -= Logger_OnLogging;
    }

    static void Logger_OnLogging(LoggingEventArgs e)
    {
        Trace.WriteLine(e.Message);
    }
}

public class Logger
{
    public delegate void LoggingEventHandler(LoggingEventArgs e);

    public static event LoggingEventHandler OnLogging;

    public static void Log()
    {
        // do stuff
        RaiseLoggingEvent("Data logged");
    }

    protected static void RaiseLoggingEvent(string message)
    {
        if (OnLogging != null)
            OnLogging(new LoggingEventArgs(message));
    }
}

public class LoggingEventArgs : EventArgs
{
    public LoggingEventArgs(string message)
    {
        this.Message = message;
    }

    public string Message { get; private set; }
}
Anthony Pegram
I think you miss understand me, I would liek to log something to a log file, and print it on my gui screen at the same time. The problem was that I couldnt add items to my listbox from my Logging class.If iam the one, who dont understands you, then Iam sorry.
Dominik
Thank you very much for the snippet, anyway!
Dominik
@Dominik, the logging class *should not be calling your UI*. That UI could go away tomorrow and completely be reimplemented using cotton balls and fingerpaint. Your logging class should be unaffected by any such change. That's what the event model is for. The logging class can provide a hook, saying "this might be important, subscribe if you care." Then the UI can say, "I care! I'm subscribing."
Anthony Pegram