Как уже упоминалось в моем комментарии после того, как вы пройдете ControlProperty
к параметрам Control.Invoke()
он больше не передаются по ссылке.
Вот решение, использующее Reflection. Вы просто передаете имя свойства и значение, которое вы хотите передать его методу SetProperty
. Я объявил его как метод расширения, таким образом, он должен быть помещен в общественном модуле:
Imports System.Reflection
Imports System.Runtime.CompilerServices
Public Module Extensions
''' <summary>
''' Thread-safely sets the property of a control to the specified value. Be sure that the value is of the correct type.
''' </summary>
''' <param name="Control">The control which's property to set.</param>
''' <param name="PropertyName">The name of the property to set.</param>
''' <param name="Value">The value to give the property.</param>
<Extension()> _
Public Sub SetProperty(ByVal Control As Control, ByVal PropertyName As String, ByVal Value As Object)
If Control.InvokeRequired = True Then
Control.Invoke(Sub() Control.SetProperty(PropertyName, Value))
Else
Control.GetType().InvokeMember(PropertyName, _
BindingFlags.SetProperty _
Or BindingFlags.IgnoreCase _
Or BindingFlags.Public _
Or BindingFlags.Instance _
Or BindingFlags.Static, _
Nothing, Control, New Object() {Value})
End If
End Sub
End Module
Теперь вы можете использовать его как это:
For x = 1 To 256
Label1.SetProperty("Text", ((x * 100)/256) & "%")
ProgressBar1.SetProperty("Value", x)
Thread.Sleep(15)
Next
Важно: При использовании этого вам должен убедиться, что значение, которое вы даете свойству, имеет правильный тип, поскольку неявные преобразования не выполняются. Поэтому, если указанное вами свойство имеет тип String
, тогда попытка установить его на Integer
вызовет исключение.
Если вам не нужно ссылаться, вы напрямую изменяете ссылку 'ControlProperty'. Однако, когда вы вызываете 'Invoke()' параметры передаются как массив объектов, где каждый элемент массива передается по значению. Это стандартное поведение массивов и невозможно изменить. - Используйте решение @ MrGadget, которое вызывает метод напрямую и по-прежнему передает 'ControlProperty' по ссылке. –
К сожалению, кажется, что параметр ByRef не может использоваться в выражении лямбда @VisualVincent – Kyle
Но выражение лямбда должно вести себя как любой нормальный метод, а вызов другого метода с параметром ByRef не должен иметь значения. Я попробую, и если я не получу его на работу, у меня есть альтернативное решение, которое вы можете использовать. –