Можно ли заставить Binding работать синхронно с элементом управления WinForms? - PullRequest
0 голосов
/ 25 марта 2019

Связано: 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...