0

I've seen this posted a few times but I cannot seem to get it to apply for me.

I want to add items to a listbox which is in my home class from my ServerController class.

Not entirely sure on how to go about this so any help would be grateful.

Home Class:

public partial class frmHome : Form
{

    serviceController sc = new serviceController();
    public ListBox lb = new ListBox();

    public frmHome()
    {
        lb = new ListBox();
        InitializeComponent();
        serviceController sc = new serviceController();
    }

    //ListBox Add
    public void addItem(string item)
    {
        lb_msg.Items.Add(item);
        lb_msg.Items.Add(item);
        lb_msg.Items.Add("");
    }
}

Service Class:

public class serviceController
    {

        ServiceController[] scServices;

        //Start the service
        public void startServices()
        {
            scServices = ServiceController.GetServices();
            try
            {
                foreach (ServiceController scTemp in scServices)
                {
                    if (scTemp.ServiceName == "MSSQL$SQLSERVER" || scTemp.ServiceName == "SQLBrowser")
                    {
                        if (scTemp.Status == ServiceControllerStatus.Stopped)
                        {
                            //Check to see if service is disabled

                            home.addItem("Attempting to start " + scTemp.ServiceName);
                            scTemp.Start();
                            scTemp.WaitForStatus(ServiceControllerStatus.Running);
                        }
                        if (scTemp.Status == ServiceControllerStatus.Running)
                        {
                            home.addItem(scTemp.ServiceName + " is running");
                        }

                    }
                    else if (scTemp.Status == ServiceControllerStatus.Running)
                    {
                        home.addItem(scTemp.ServiceName + " is already running");
                    }
                }
                serverStatus();
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

On the Service Class I want to use home.addItem

Am I write in thinking I need to make a public listbox in my home class and link it with the one in my design?

What I want to achieve is this:

I want it to check x amount of services to see the status of it. If it is stopped, then check if it is disabled and report back - if it is disabled attempt to set as automatic, else attempt to start it. I want to write a log as it does this.

Hope this gives a bit more clarification.

Thanks!!!

2
  • I'm little confused, why do you have public ListBox lb but use lb_msg to actually add something? Commented Mar 28, 2017 at 10:28
  • @JohnnyAW I was experimenting at the time. Forgot to take it out. Commented Mar 28, 2017 at 10:30

3 Answers 3

3

You could pass it through the constructor

public class serviceController
{
    private ListBox home;
    public serviceController(ListBox lb)
    {
       home = lb;
    }

    public void foo()
    {
        home.Items.Add("")
    }
}

Now, when you create a new object of serviceController, you need to pass a listbox.

serviceController sv = new serviceController(lb_msg);

Then, when you are in the serviceController, you can use the variable lb like you could in the main class

another way of accessing other form controls is

frmHome form = new frmHome();
ListBox lb = (ListBox)form.Controls["nameOfControl"];
lb.Items.Add("");

also: serviceController should start with an uppercase, ServiceController

Sign up to request clarification or add additional context in comments.

6 Comments

That instantly violates SRP from SOLID. serviceController should not, under any circumstances, be responsible for binding GUI form. It's sole purpose is to track ServiceController objects. Your home form could subscribe to events defined in serviceController and get those messages back from it. If you're interested, I will show how.
Thanks @Stefan - It works now thanks to the home.Items.Add
Yes please @NikhilVartak that'd be fantastic. I wanted to use a Subscriber but was unsure how to apply it in this situation.
@SCramphorn check my answer.
@NikhilVartak I'm not aware of how the ServiceController works or what it is, I was just answering in general programming. You can apply the constructor from other class method with lists or any other object, aswell as the second solution
|
1

I have written a sample code to demonstrate what I suggested. You have to match it with the actual types (classes e.g.) you're using. Added code comments, so I'm not going to write much here again. If you want to play with this code, here's a fiddle: https://dotnetfiddle.net/t0MyNk

public class Program // Consider this your home form
{
    public void Main()
    {
        var serviceController = new ServiceController();
        serviceController.ServiceStateChange += ServiceController_ServiceStateChanged;
        serviceController.StartServices();
    }

    private void ServiceController_ServiceStateChanged(object sender, ServiceControllerEventArgs e)
    {
        // Add to listbox or do whatever you want. I am just printing.
        Console.WriteLine(e.Message);
    }
}

public class ServiceController
{
    public event EventHandler<ServiceControllerEventArgs> ServiceStateChange;

    public void StartServices()
    {
        Service[] services = new Service[] // Sample services data
        { 
            new Service { Name = "MSMQ", Status = "Stopped" },
            new Service { Name = "W3SVC", Status = "Running" }
        };

        string message = null;

        foreach(Service s in services) 
        {
            if(s.Status == "Stopped") 
            {
                s.Start();
                // Assuming it starts almost immediately. If not, you could follow same pattern for 
                // Service class where an event will be raised once service is "actually" started.
                if(s.Status == "Running") {
                    message = string.Format("Service {0} is {1}", s.Name, s.Status);
                }
            }
            else if(s.Status == "Running") {
                message = string.Format("Service {0} is already {1}", s.Name, s.Status);
            }

            // Now tell subscriber (home form) about this.
            OnServiceStateChange(message);
        }
    }

    private void OnServiceStateChange(string message)
    {
        var serviceStateChangeHandler = ServiceStateChange;
        if(serviceStateChangeHandler != null)
        {
            serviceStateChangeHandler(this, new ServiceControllerEventArgs { Message = message });
        }
    }
}

// You could have custome delegate type for event to return string message.
// But IMO this is much cleaner, and as per MSFT guidelines.
public class ServiceControllerEventArgs : EventArgs
{
    // You can also return Service instance
    // Just including Message for now 
    public string Message { get; set; }
}

// for demo purpose, represents individual service.
public class Service
{
    public string Name { get; set; }
    public string Status { get; set; }

    public void Start() {
        Status = "Running";
    }
}

Output:

Service MSMQ is Running   
Service W3SVC is already Running

1 Comment

Thanks Nikhil, i'll take a look at this and learn from it. Many Thanks!
0

I would strongly recommend you adopt binding instead of manipulating the controls on your forms directly, with the goal of keeping data and UI separate. You could for instance have a list (it would have to be a BindingList<> if memory serves) of strings in your class, and the list control would bind to it; that way the contents of the list are reflected in the UI and you can freely update the list from somewhere else as just data, without having to think about the intricacies of how the data is presented.

In the end you could come up with something similar to MVVM (model-view-viewmodel) or MVC, which in my opinion are superior solutions to manipulating controls manually.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.