Search code examples
multithreadinggetsetcontrols

c# Setting / Getting properties of controls to / from another thread


I have this code for setting controls parameter to another thread:

private delegate void SetPropertySafeDelegate<TResult>(System.Windows.Forms.Control @this, Expression<Func<TResult>> property, TResult value);

    public static void SetProperty<TResult>(this System.Windows.Forms.Control @this, Expression<Func<TResult>> property, TResult value)
    {
        var propertyInfo = (property.Body as MemberExpression).Member as PropertyInfo;

        if (propertyInfo == null || [email protected]().IsSubclassOf(propertyInfo.ReflectedType) || @this.GetType().GetProperty(propertyInfo.Name, propertyInfo.PropertyType) == null)
        {
            throw new ArgumentException("The lambda expression 'property' must reference a valid property on this Control.");
        }

        if (@this.InvokeRequired)
        {
            @this.Invoke(new SetPropertySafeDelegate<TResult>(SetProperty), new object[] { @this, property, value });
        }
        else
        {
            @this.GetType().InvokeMember(propertyInfo.Name, BindingFlags.SetProperty, null, @this, new object[] { value });
        }
    }

it works like this:

 label1.SetProperty(() => label1.Text, "xxx");

but I need it to work also on other things, such as:

checkBox4.SetProperty(() => checkBox4.Checked, true);

which doesn't work.

The second thing I need is the same function for getting control value.

Thanks a lot for your advice.


Solution

  • The solution which works for me:

    /// <summary>
    /// Gets control property. Usage: label1.GetProperty2(() => label1.Text);
    /// </summary>
    public static object GetProperty2<TResult>(this Control @this, Expression<Func<TResult>> property)
    {
        var propertyInfo = (property.Body as MemberExpression).Member as PropertyInfo;
    
        return @this.GetType().GetProperty(propertyInfo.Name, propertyInfo.PropertyType).GetValue(@this, null);
    }
    
    /// <summary>
    /// Sets control property. Usage: label1.SetProperty2(() => label1.Text, "Zadej cestu k modelu.");
    /// </summary>
    public static void SetProperty2<TResult>(this Control @this, Expression<Func<TResult>> property, TResult value)
    {
        var propertyInfo = (property.Body as MemberExpression).Member as PropertyInfo;
    
        if (@this.InvokeRequired)
        {
            @this.Invoke(new SetPropertySafeDelegate<TResult>(SetProperty2), new object[] { @this, property, value });
        }
        else
        {
            @this.GetType().InvokeMember(propertyInfo.Name, BindingFlags.SetProperty, null, @this, new object[] { value });
        }
    }
    private delegate void SetPropertySafeDelegate<TResult>(Control @this, Expression<Func<TResult>> property, TResult value);