c#设置/获取控件到/从另一个线程的属性

时间:2016-12-07 10:03:16

标签: multithreading get set controls

我有这个代码用于将controls参数设置为另一个线程:

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 || !@this.GetType().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 });
        }
    }

它的工作原理如下:

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

但是我还需要它来处理其他事情,例如:

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

哪个不起作用。

我需要的第二件事是获得控制值的相同功能。

非常感谢您的建议。

1 个答案:

答案 0 :(得分:1)

适合我的解决方案:

    /// <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);