Search code examples
c#winformsobserver-pattern

A Control is an observer of an object and I it fails to register because window handle has not been created


I have a windows forms control MyControl which is an observer of an object. The object has some images. The control has System.Windows.Forms.ProgressBar progressBar. On registering the object notifies the control of the images and the control increments the value of the progress bar, which throws "Invoke or BeginInvoke cannot be called on a control until the window handle has been created". This control is inside another control which is inside a window and all of this is happening in a chain of constructors.

My understanding is that registering should happen after the window is created, but I don't think I can do it with the current architecture. I used to just ask the object of images count in the constructor, but the images are added asynchronously, so I don't want to rely on counters anymore.

interface IImagesObserver
{
  void onImageAdded();
}
class MyControl : IImagesObserver
{
  public MyControl(MyObject object)
  {
    InitializeComponent();
    ...
    object.register(this);
  }

  void IObjectOnserver.onImageAdded()
  {
    Invoke((MethodInvoker)delegate
    {
      progressBar.Value++;
      Invalidate();
    });
  }
}
class MyObject
{
  public void register(IImagesObserver observer)
  {
    foreach( var img in images)
      observer.onImageAdded();
  }
}

Solution

  • You could override OnHandleCreated and call the register method from there. Or you can force the creation of the control handle in the constructor with CreateControl. You should also unregister your observer before it gets disposed. An override of the Control.Dispose method would be a good place for this (before you call base.Dispose).