none
Error: the calling thread must be STA, because many UI components require this.

    Question

  • Hi, somehow I get this error but don't know how to handle it. In the following snippet I try to create two windows. namespace Generator.exe { public class Communication ... public Communication() { aboutW = new AboutWindow(); mainW = new MainWindow(); } ... public partial class AboutWindow : Window { ... public AboutWindow() //<--- ERROR { InitializeComponent(); LostFocus += new RoutedEventHandler(AboutWindow_LostFocus); } ... I already found something about "Dispatcher"". I think this might be the solution for my problem, but I do not understand the connection between my problem here and the use of a dispatcher nor what it does in general.
    Tuesday, May 31, 2011 5:42 PM

Answers

  • Okay,

     

    After implementing your code I received the same error. Basically i don't know why but calling your class App you are causing all sorts of problems. As I mentioned before WPF applications when created have a App.xaml which is the starting point for the application.

    By calling your class App the application starts in that class but its missing "stuff" that the application needs.

    You are definetly going to need an App.Xaml file in your application and you have 2 choices here -

     

    1) Rename your App class to something else and in the App.Xaml instsntiate it -

     

    public partial class App : Application
      {
    
        protected override void OnStartup(StartupEventArgs e)
        {
          base.OnStartup(e);
          Apps a = new Apps();
        }
      }
    

     I renamed your class to Apps and everything works fine and 2 windows appeared for me.

     

    (2) You can remove you App class and take all its logic and place it in the App.xaml.cs file. Thats what its there for so i would recommend doing this. But its your project and your call.

    • Proposed as answer by Pritesh3 Tuesday, May 31, 2011 7:23 PM
    • Marked as answer by The-Forgotten Tuesday, May 31, 2011 8:35 PM
    Tuesday, May 31, 2011 7:22 PM

All replies

  • hi,

     

    Your Generator.exe is probably running on a new thread (or creating a new thread somewhere) which is causing the issue. You cannot update UI elements of a WPF application (or a winform app) from a secondary thread (which is where Dipatcher comes into play).

     

    WPF applications all have 1 UI thread. Heres an article that will explain the role of the dispatcher -

    http://www.switchonthecode.com/tutorials/working-with-the-wpf-dispatcher

     

    Basically everyytime you want to pass values from a different thread (not the UI) you call the dispatcher object to marshall those changes to the UI thread.

    I've probably explained this really badly so I would strongly recommend reading the article (LOL) 

    • Proposed as answer by Pritesh3 Tuesday, May 31, 2011 5:59 PM
    Tuesday, May 31, 2011 5:59 PM
  • Ok ... so the dispatcher "manages" the UI Elements? Somehow my problem occures before I try to "change" my UI Elements. In your example the "CheckBox" is created like any other object. But I cannot create my windows like the checkBox was created. If I try to "move" the "creating part" into the thread using the dispatcher I get a NULL - reference error ... of course AboutWindow does not exist at this moment. If I try to create an object of this partitial class earlier I get the STA-Thread error System.Threading.Thread thread = new System.Threading.Thread( new System.Threading.ThreadStart( delegate() { AboutWindow.Dispatcher.Invoke( System.Windows.Threading.DispatcherPriority.Normal, new Action( delegate() { MARK <--- INSERTED HERE } )); } )); BTW: Somehow all my line breaks and spaces are deleted :S
    Tuesday, May 31, 2011 6:17 PM
  • Can you post a mre complete sample of your code. What you have posted shouldn't be causing this kind of error. Can you post the code that instantiates your Communication class. 

    Tuesday, May 31, 2011 6:28 PM
  • Sure...

    namespace Generator.exe
    {
    class App
    {
    static void Main()
    {
    Communication comm = new Communication();
    }
    }
    }


    namespace Generator.exe
    {
    public class Communication
    {
    MainWindow mainW;
    AboutWindow aboutW;

    public Communication()
    {
    //Doesnt work
    aboutW = new AboutWindow();
    mainW = new MainWindow();
    //Doesnt work (atm only the upper is implemented)
    Thread thread = new Thread(new ThreadStart(
    delegate()
    {
    aboutW = new AboutWindow();
    mainW = new MainWindow();
    }
    ));
    thread.Start();
    }
    }
    }

    namespace Generator.exe
    {
    /// <summary>
    /// Interaction logic for AboutWindow.xaml
    /// </summary>
    public partial class AboutWindow : Window
    {
    public AboutWindow()
    {
    InitializeComponent();
    LostFocus += new RoutedEventHandler(AboutWindow_LostFocus);
    }
    }
    }
    BTW: Caused line breaks with "html line break" ... hope this increases readability
    Tuesday, May 31, 2011 6:35 PM
  • Hi,

     

    I want to understand a little about what you are doing. Your app class. What is it purpose? How is it called?

    Normally my WPF application's start in App.Xaml and I "tell" it to show a window I want to open but you have this App classs which is doing this for you instead.

     

    Also how is your App class instantiated?

     

    Tuesday, May 31, 2011 6:43 PM
  • The basic idea was to have two or more windows communicating with each other.

    So I thought the best way to do this, is to create a "Master" class, this "master" is communication.

    communication is created to manage its childs, the main window, the popups, like aboutWindow etc.
    Tuesday, May 31, 2011 6:46 PM
  • Okay I see what your trying to do but what is the App class?

     

    Tuesday, May 31, 2011 6:48 PM
  • The App class is the basic startup class. I'm planning to implement other classes when the current phase of the project is finished. In the next phase the App Class will be quite useful.
    Tuesday, May 31, 2011 6:54 PM
  • Okay so can you post the code that instantiates the app class please?

    I know its a pain but your issue is a real pain (LOL) to figure out.

    Tuesday, May 31, 2011 6:59 PM
  • using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace Generator.exe
    {
    class App
    {
    static void Main()
    {
    Communication comm = new Communication();
    }
    }
    }
    Tuesday, May 31, 2011 7:00 PM
  • Okay,

     

    After implementing your code I received the same error. Basically i don't know why but calling your class App you are causing all sorts of problems. As I mentioned before WPF applications when created have a App.xaml which is the starting point for the application.

    By calling your class App the application starts in that class but its missing "stuff" that the application needs.

    You are definetly going to need an App.Xaml file in your application and you have 2 choices here -

     

    1) Rename your App class to something else and in the App.Xaml instsntiate it -

     

    public partial class App : Application
      {
    
        protected override void OnStartup(StartupEventArgs e)
        {
          base.OnStartup(e);
          Apps a = new Apps();
        }
      }
    

     I renamed your class to Apps and everything works fine and 2 windows appeared for me.

     

    (2) You can remove you App class and take all its logic and place it in the App.xaml.cs file. Thats what its there for so i would recommend doing this. But its your project and your call.

    • Proposed as answer by Pritesh3 Tuesday, May 31, 2011 7:23 PM
    • Marked as answer by The-Forgotten Tuesday, May 31, 2011 8:35 PM
    Tuesday, May 31, 2011 7:22 PM
  • by the way the debugger is going to go nuts when you create an App.xaml file.I#m sure these issues can be resolved but you might be better of creating a new project.

    Tuesday, May 31, 2011 7:30 PM
  • This is strange... this causes the same error :S

    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Data;
    using System.Linq;
    using System.Windows;

    namespace Generator.exe
    {
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
    protected override void OnStartup(StartupEventArgs e)
    {
    base.OnStartup(e);
    Apps a = new Apps();
    }
    }
    }


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;

    namespace Generator.exe
    {
    class Apps
    {
    Communication comm = new Communication();
    }
    }
    Tuesday, May 31, 2011 7:47 PM
  • The same error occures for(even after "excluding" the apps.cs file):

    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Data;
    using System.Linq;
    using System.Windows;

    namespace Generator.exe
    {
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
    protected override void OnStartup(StartupEventArgs e)
    {
    base.OnStartup(e);
    Communication a = new Communication();
    }
    }
    }
    Tuesday, May 31, 2011 7:50 PM
  • Hi,

    Yes I did.

    But when I tried to use StartUpUri = "Apps.cs" it didnt work. 

    Remove the StartUri.

    Then put in the method I gave you above (in the Apps.xaml.cs)-

     

    protected override void OnStartup(StartupEventArgs e)
      {
       base.OnStartup(e);
       Apps a = new Apps();
      }
    
    
    

     

    and then my sample works again.

     

    What about you?

    Tuesday, May 31, 2011 7:52 PM
  • I think StartUpUri can only open windows.
    Tuesday, May 31, 2011 7:52 PM
  • Like that?

    App.xaml
    <Application x:Class="Generator.exe.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>

    </Application.Resources>
    </Application>

    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Data;
    using System.Linq;
    using System.Windows;

    App.xaml.cs
    namespace Generator.exe
    {
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
    protected override void OnStartup(StartupEventArgs e)
    {
    base.OnStartup(e);
    Communication a = new Communication();
    }
    }
    }


    Causes the old STA - Thread error
    Tuesday, May 31, 2011 8:03 PM
  • I got it ... had still the Thread lines
    So your solution worked :D
    Thanks a lot for your help :D
    Tuesday, May 31, 2011 8:15 PM
  • No worries
    Tuesday, May 31, 2011 8:16 PM