Связано: https://stackoverflow.com/a/17451872/3485263
У меня есть класс, который реализует INotifyPropertyCHanged
.Существует несколько экземпляров System.Windows.Forms.Binding
, которые связывают его свойства со свойствами некоторых элементов управления в приложении Windows Forms.
public class Device : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string property_name)
{
if (PropertyChanged != null) // if there are any subscribers
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(property_name));
}
public bool connected {get; set;}
...
Связывание происходит в классе формы следующим образом:
button_Reboot.DataBindings.Add("Enabled", _device, "connected", false,
DataSourceUpdateMode.Never);
Проблема с этим кодом заключается в том, что обработчик OnPropertyChanged
и код формы работают в разных потоках.Это связано с тем, что _device
подписан на события инкапсулированного экземпляра SerialPort
и обновляет свои свойства для событий, инициируемых последовательным портом, что, по-видимому, происходит в другом потоке.Таким образом, я получаю InvalidOperationException
о том, что элемент управления доступен из потока, отличного от потока, в котором он был создан .
Я изменил свой код в соответствии с этим ответом .Комментарии к этому ответу также содержат описание моей проблемы.
void OnPropertyChanged(string property_name)
{
var handler = PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(property_name);
foreach (PropertyChangedEventHandler h in handler.GetInvocationList())
{
var synch = h.Target as ISynchronizeInvoke;
if (synch != null && synch.InvokeRequired)
synch.Invoke(h, new object[] { this, e });
else
h(this, e);
}
}
}
Автор этого ответа ожидал, что h.Target
будет Control
, но в моем случае это окажется System.ComponentModel.ReflectPropertyDescriptor
, некоторый тип Runtime, который я наблюдал во время отладки.Этот тип не реализует ISynchronizeInvoke
, поэтому synch
равен null
, что в любом случае приводит к исключению, потому что метод управления вызывается напрямую, а не вызывается синхронно.
Мой вопросмогу ли я сделать, чтобы мой обработчик OnPropertyChanged
получил доступ к элементу управления PropertyChangedEventHandler
, используя интерфейс элемента управления ISynchronizeInvoker
.Я нацеливаюсь на .NET 4.6.2 и использую Visual Studio 2013.