我可以使绑定与WinForms控件同步工作吗?

时间:2019-03-25 14:55:25

标签: c# .net winforms data-binding

相关: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的说法是,控件是从不是在其上创建的线程的线程访问的。

我根据this answer更改了代码。该答案的评论也包含对我问题的描述。

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.TargetControl,但在我的情况下却是System.ComponentModel.ReflectPropertyDescriptor,这是我在调试期间观察到的某些运行时类型。该类型未实现ISynchronizeInvoke,这导致synchnull,无论如何都会引发异常,因为控制方法只是直接调用而不是同步调用。 >

我的问题是我是否可以使我的OnPropertyChanged处理程序使用控件的PropertyChangedEventHandler界面访问控件的ISynchronizeInvoker。我以.NET 4.6.2为目标,并且正在使用Visual Studio 2013。

0 个答案:

没有答案