Of course you could "invoke" location change from anywhere; but your question if not formulated correctly. Strictly speaking, calls are done not with classes, but with objects (class instances); in the context of your question this is important.
Now, what is called "invocation" in .NET as opposed to normal call have nothing to do with difference in classes or instances. There are at least two different notions:
1) Invoke a call based on method meta-data and some object (optionally null (method is static)) which is supposed to play the role of "this" on a non-static method (and also optional parameters) -- this is all about Reflection.
2) Invocation of some method to be called in a different thread then a thread causing the invocation; the invocation is not actually a call at all; this is just posting information on desired call and parameters in some queue; all the rest relies on the foreign thread -- this is all about threading and so called dispatching.
If you do something like
MyForm.Location =
new System.Drawing.Point(myForm.Location.X + 100, 0);
it works; you simply need an instance of your form
MyForm
passed to the point of the call.
If you want this effect from the other thread though, this is harder to do. Now you really need invocation:
MyForm.Invoke(
new Action<Form>(
(form) =>
{
form.Location =
new System.Drawing.Point(
form.Location.X + 200,
10);
}
),
MyForm);
Here,
form
if a formal parameter of the complite-time type Form, (run-time type will be the same as of
MyForm
),
MyForm
is the instance used twice: in first line it is used as
this
argument of
Invoke
needed to detect current UI thread and perform invocation; in last line, it is needed to pass the instance to the formal parameter
form
of the anonymous method, so the
form.Location
property knew what exactly to move.
Sometimes, you do not know if you really run this code from the same thread as UI or a different one. In this case, you can write more effective code which work faster (through immediate call) if the threads are the same. No need to examine and compare thread object. This is done through the predicate property
Control.InvokeRequired
. This is how:
if (MyForm.InvokeRequired)
MyForm.Invoke(
new Action<form>(
(form) => {
form.Location =
new System.Drawing.Point(
form.Location.X + 200,
10);
}
),
MyForm);
else
MyForm.Location =
new System.Drawing.Point(
MyForm.Location.X + 200,
10);
</form>
Looks tricky? Well, with experience and
IntelliSense you do it almost automatically; much harder to explain it.
Despite some common misconception such inter-thread invocation can only be done to UI thread. The misconception is based on
Dispatcher
which can be called for anuwhere, but... only formally, in default case the effect will be equivalent the the call on a current thead. For non-UI thread the only way is to create all similar functionality from scratch: your own queue, dispatcher and invoke methods.