Register for your free account! | Forgot your password?

Go Back   elitepvpers > Blogs > InvincibleNoOB
You last visited: Today at 10:02

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Rate this Entry

Accessing Form members from different threads(C#)

Posted 04/16/2009 at 23:32 by InvincibleNoOB

Hello,

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";
            }
        }
The contructor is namedTextValue,the form is,lets say - Form1.

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";
However,you may ask,"I cannot access the constructor in Form1 itself,it's missing".
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;
        }
See,it works!

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";
                }
            }
        }
Invoke is most likely always used and to be honest,that else statement is just useless,but it's good to stay there for a better view from intellectual point of view.

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");
can also be used with multiple lines.Example I use this to add the servers names in the combobox of my clientless
Code:
                    FormMain.PerformActionOnMainForm(form =>
                        {
                            form.comboServers.Items.Clear();
                            for (ii = 0; ii < num; ii++)
                            {
                                form.comboServers.Items.Insert(ii, Names[ii]);
                            };
                        });
End of my lesson.
Posted in Uncategorized
Views 2572 Comments 1 Email Blog Entry
« Prev     Main     Next »
Total Comments 1

Comments

  1. Old Comment
    what's mean var in :
    var form = Form.ActiveForm as Form1;

    thx
    permalink
    Posted 05/27/2009 at 06:41 by fahazzi fahazzi is offline
 

All times are GMT +2. The time now is 10:02.


Powered by vBulletin®
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2024 elitepvpers All Rights Reserved.