Setting a Control Property Value from a Non-UI Thread

As most of you might know (I hope) it is unwise to call methods on a Control from a non-UI thread. This can cause all sorts of issues. Actually, I think in most cases .NET will throw and Exception. If you need to set a property on a Control this is how you would properly do it.

VB.NET

 Delegate Sub SetPropertyValueDelegate(ByVal obj As Object, ByVal val As Object, ByVal index As Object())

 

    Public Sub SetControlProperty(ByVal ctrl As Control, ByVal propName As String, ByVal val As Object)

        Dim propInfo As PropertyInfo = ctrl.[GetType]().GetProperty(propName)

        Dim propertyDelegate As [Delegate] = New SetPropertyValueDelegate(propInfo.SetValue)

        ‘index

        ctrl.Invoke(propertyDelegate, New Object(2) {ctrl, val, Nothing})

    End Sub

 

    Private Sub UpdateSent(ByVal item As String)

        _chat.AppendLine(item)

 

        If Me.SentTextBox.InvokeRequired Then

            ‘ This is a worker thread so delegate the task.

            SetControlProperty(SentTextBox, “Text”, _chat.ToString())

        Else

            ‘ This is the UI thread so perform the task.

            Me.SentTextBox.Text = _chat.ToString()

        End If

 

 

    End Sub

C#

        delegate void SetPropertyValueDelegate(Object obj, Object val, Object[] index);

 

        public void SetControlProperty(Control ctrl, String propName, Object val)

        {

            PropertyInfo propInfo = ctrl.GetType().GetProperty(propName);

            Delegate propertyDelegate = new SetPropertyValueDelegate(propInfo.SetValue);

            ctrl.Invoke(propertyDelegate, new Object[3] { ctrl, val, /*index*/null });

        }

 

        private void UpdateSent(string item)

        {

            _chat.AppendLine(item);

 

            if (this.SentTextBox.InvokeRequired)

            {   // This is a worker thread so delegate the task.

                SetControlProperty(SentTextBox, “Text”, _chat.ToString());

            }

            else

            {   // This is the UI thread so perform the task.      

                this.SentTextBox.Text = _chat.ToString();

            }

 

        }

UpdateSent is example code on how to use the code. Also, _chat is a StringBuilder object. This code is taken from a chat program I wrote at where I work.

Tip Submitted By: David McCarter

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s