views:

52

answers:

3

Hello Why I haven't access to my private control on form (e.g. ListBox) from a static method? How to update control in this case?

EDIT 1.

my code:

ThreadStart thrSt = new ThreadStart(GetConnected);
        Thread thr = new Thread(thrSt);
        thr.Start();

and

static void GetConnected()
    {
        //update my ListBox
    }

So it must be void, without param and be static, right?

EDIT 2.

If someone need solution in WPF then should try this:

private void GetConnected()
    {
        myListBox.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                    new Action(() =>
                    {
                        myListBox.Items.Add("something");
                    }
                               )
                 );
    }
A: 

You should, define them static because in static method you can't instantiate objects other than your related class and local variables in method. static objects will be create in heap and others will be create in stack.

When you working with controls it's not required to access them from method you just should update their related data sources.

SaeedAlg
+1  A: 

Static methods cannot access instance state (such as a non-static control). Either remove static from the method declaration, or pass a reference to the control as argument to the method:

private static void SomeMethod(ListBox listBox)
{
    listBox.Items.Add("Some element");
}

...and call it like so:

SomeMethod(MyListBox);

Update
There are different ways to do asynchronous things in the UI (now assuming winforms). I would recommend you to look into using BackgroundWorker (search here on SO; plenty of examples). If you really want to do it by creating threads on your own, here is one way to do that:

private void SomeMethod()
{
    string newElement = FetchNextElementToAdd():
    SafeUpdate(() => yourListBox.Items.Add(newElement));
}

private void SafeUpdate(Action action)
{
    if (this.InvokeRequired)
    {
        this.BeginInvoke(action);
    }
    else
    {
        action();
    }
}

...and to call it:

Thread thread = new Thread(SomeMethod);
thread.Start();

You can also use the thread pool (preferred over creating your own threads, given that you don't expect them to run for very long):

ThreadPool.QueueUserWorkItem(state => SomeMethod());
Fredrik Mörk
I must call this method in another Thread so AFAIK it must be static and must be without param and must return void, right?
Saint_pl
@Saint_pl: I assume that you mean that you want to launch call the method on a separate thread (as in `new Thread(YourMethod)`). If that is the case then no, it does not need to be static. Parameterless and returning void yes, but not necessarily static.
Fredrik Mörk
Hmm, that's right :) I don't know why earlier it didn't work :)
Saint_pl
good answer but i prefer to use task item:D
SaeedAlg
I'm wrong or sth but in wpf there's no sth like InvokeRequired? So it's problem because I have error: "The calling thread cannot access this object because a different thread owns it."
Saint_pl
O, there's sth better :) Sth called Dispatcher :)
Saint_pl
@Saint_pl: yes, I missed the wpf-controls tag. My bad. You should use Dispatcher.
Fredrik Mörk
+1  A: 

you need to pass a reference to the control to your static method, or something that contains them. static methods cant access non static fields/methods/etc. dont declare your control as static, i'm not even sure if its possible, but if it was, it would cause you problems you dont even want to know about.

jasper