views:

98

answers:

1

Some background: I get the following exception in my code below.

ThreadStateException : ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment.

The Main() method is marked with the [STAThread] attribute. The app is supposed to start up without a window and listen for an event from a third party data context-sharing library. When the eventhandler is triggered, I would like it to create and show the form, if it isn't already. The form simply houses a webbrowser control.

So, my question is how do I delay instantiation of the main form (w/ webbrowser control) of an application until an event handler is triggered?

In this instance, I suppose I could just create the form from the beginning by passing it to the ApplicationContext constructor and then just hide it, but I'm really curious as to why this doesn't work.

[STAThread]
static void Main() {
     ListenerAppContext context = new ListenerAppContext();
     Application.Run(context);
}

...

public class ListenerAppContext : ApplicationContext {
  ThirdPartyDataContextAdapter adapter;
  string UrlFormat = "http://ViewDataHere/?{0}";

  public ListenerAppContext()  {
     adapter = new ThirdPartyDataContextAdapter();
     adapter.OnSomeEvent += new OnSomeEventHandler(adapter_OnSomeEvent);
  }

  void adapter_OnSomeEvent(string data) {
      ShowData(data);
  }

  void ShowData(string data) {
      string url = String.Format(UrlFormat, data);
      if (this.MainForm == null) {

          this.MainForm = new ReportViewer(url);  // Exception thrown here
      } else {
          ((IReportView)this.MainForm).Url = url;
      }
  }

 ...
}
+2  A: 

You may find it much easier to go ahead and instantiate the main form right away, but hide it so the users don't see it. Then, you just make it visible when you want to see what's in there.

John Fisher