I originally wrote this tutorial for Stealthex ,but I will post it here aswell.
The purpose of the tutorial is to teach you how to access form members from threads other than the main thread.
I hope you like it.
//
In the beggining of my C# development I encounted much problems when I wanted to access the properties on my Form.
Same goes for Delphi,but I don't have a solution for Delphi.
This is the C# way.
To access a property on your form,you can create a method or class contructor:
Code:
public string TextValue
{
set
{
this.Memo.Text += value + "\n";
}
}
To access that type of functions,you have to assign a value to them,in our case a string.
So to call that function you should use:
Code:
Form1.TextValue = "Test Text";
This is because you didn't create a instance of Form1,you can also use this
Code:
public static void addtxt(string txt)
{
var form = Form.ActiveForm as Form1;
if(form != null)
form.TextValue = txt;
}
End of part I
Part II
In part 1 we discussed how to use form properties from different classes without making the properties's modifiers public.
However,an exception will be thrown if you try to access that thread from another thread(lets say you're making a TCP client with async callback).
To prevent that,we've got to use Invoke.
This is how our constructor would look like if we use Invoke
Code:
public string TextValue
{
set
{
if (this.Memo.InvokeRequired)
{ //if invoke IS required
this.Invoke((MethodInvoker)delegate
{
this.Memo.Text += value + "\n";
});
}
else //if invoke is not required
{
this.Memo.Text += value + "\n";
}
}
}
Now comes the handy part.(aka part 3 - the last one)
You may now wonder "So I have to create those two functions with so much code for every property on my form?".
Of course you don't have to.That's why there are "actions" since C# v2.0 went out. (:
This is the latest function I use,however it requires to change form properties's modifiers from private to Internal(protected internal is recommended).
And here comes the ultra-handy code that I use in my clientless:
//Note i made the class "partial" ,so it dont have to mess the form.cs file with it.
Code:
namespace Invincible_s_Clientless
{
public partial class FormMain
{
int Ticks = 0;
EndianBitConverter converter = EndianBitConverter.Little;
[DllImport("kernel32")]
public extern static int LoadLibrary(string librayName);
public static void PerformActionOnMainForm(Action<FormMain> action)
{
var form = Form.ActiveForm as FormMain;
if (form != null)
form.PerformAction(action);
}
public void PerformAction(Action<FormMain> action)
{
if (InvokeRequired)
Invoke(action, this);
else
action(this);
}
}
}
usage:
Code:
form1.PerformActionOnMainForm(form => form.memo.text += "My newest invoke method :)\n");
Code:
FormMain.PerformActionOnMainForm(form =>
{
form.comboServers.Items.Clear();
for (ii = 0; ii < num; ii++)
{
form.comboServers.Items.Insert(ii, Names[ii]);
};
});






