Сбой пользовательского элемента управления WPF с сообщением «Вызывающий поток должен быть STA»

Код WinForm дает сбой с The calling thread must be STA, because many UI components require this. при попытке создать пользовательский элемент управления WPF с использованием myWpfUserControl = new MyWpfUserControl();. Кажется, он падает в конструкторе базового пользовательского элемента управления.

Точка входа в мое приложение — ApplicationStartup в App.xaml.cs, на которой есть [STAThread]. Я вообще не использую многопоточность, и я вижу на панели «Потоки» в Visual Studio, когда происходит сбой, что он находится на Main Thread.

РЕДАКТИРОВАТЬ: Раньше это работало.

Вот скелет моего кода:

[STAThread]
private void ApplicationStartup(object sender, StartupEventArgs e)
{
    LogonFormEventListener listener = new LogonFormEventListener();
    Logon.LogonFormEvent += new Logon.ClassFormEventHandler(listener.TestEventRaised);
    Logon logon = new Logon();
    logon.ShowDialog();
}

public partial class Logon : Form
{
    private void OKbutton_Click(object sender, EventArgs e)
    {
        if(LogonFormEvent !=null) LogonFormEvent(this, null);
    }
}

public class LogonFormEventListener
{
    public void TestEventRaised(Logon o, EventArgs e)
    {
        MainForm mainForm = new MainForm();
        mainForm.ShowDialog();
    }
}

public partial class MainForm : Form
{
    MyWpfUserControl myWpfUserControl;

    private void mainMenu_ItemClick(object sender, MenuBar.ItemEventArgs e)
    {
        switch (e.Item.Key)
        {
            case "myAction":
                myWpfUserControl = new MyWpfUserControl(); //CRASH
                ...
                break;
        }
    }
}

Пользовательский элемент управления аварийно завершает работу в базовом конструкторе до того, как запустится какой-либо код в моем пользовательском элементе управления, поэтому нет смысла показывать код пользовательского элемента управления (я думаю).

Любые идеи были бы хорошы.


person wezten    schedule 08.10.2015    source источник
comment
вам нужно добавить код для диагностики.   -  person Nikita Shrivastava    schedule 08.10.2015
comment
Возможно, связано с этим вопросом.   -  person Codor    schedule 08.10.2015
comment
@Nikita Какой код будет полезен?   -  person wezten    schedule 08.10.2015
comment
добавьте свои классы/пользовательские элементы управления и основной метод.   -  person Nikita Shrivastava    schedule 08.10.2015
comment
Подождите, вы создаете UserControl WPF в коде WinForm, а запуск происходит в app.xaml.cs (WPF)? Я очень смущен тем, какую технологию вы используете и чего вы пытаетесь достичь.   -  person bic    schedule 08.10.2015
comment
@Nikita Это буквально тысячи строк.   -  person wezten    schedule 08.10.2015
comment
Покажите вызывающий код и опишите структуру проекта.   -  person bic    schedule 08.10.2015
comment
О.. нет нет.. так много и не нужно. Можете ли вы просто попробовать образец скелета приложения, а не логику, а только компоненты. Это может помочь.   -  person Nikita Shrivastava    schedule 08.10.2015
comment
@bic Simple — ApplicationStartup вызывает new MyWinForm().ShowDialog(), а программный код MyWinForm создает MyWpfUserControl.   -  person wezten    schedule 08.10.2015
comment
Причина, по которой вы получаете эту проблему, заключается в том, что событие запускается из потока, отличного от пользовательского интерфейса.   -  person Nikita Shrivastava    schedule 08.10.2015
comment
Итак, ваша реальная проблема заключается в попытке открыть окно WinForms в приложении WPF. Вам нужно разместить другую технологию пользовательского интерфейса в соответствующем ElementHost или использовать помощников InterOp. stackoverflow.com/questions/16577122/   -  person bic    schedule 08.10.2015
comment
@bic - нет - WinForm показывает нормально. Смотрите код, который я разместил.   -  person wezten    schedule 08.10.2015
comment
Размещен ли myWpfUserControl на ElementHost? msdn.microsoft.com/en-us /библиотека/vstudio/ms754008(v=vs.90).aspx   -  person bic    schedule 08.10.2015
comment
@bic - Да, но это не имеет значения - заранее происходит сбой в конструкторе.   -  person wezten    schedule 08.10.2015
comment
Не могли бы вы попробовать открыть свою WinForm с помощью WindowInteropHelper в примере, на который я ссылался ранее.   -  person bic    schedule 08.10.2015
comment
@bic Какая форма - Logon или MainForm или обе?   -  person wezten    schedule 08.10.2015
comment
@Nikita Итак, почему VS падает в основном потоке? (кстати, я добавил код)   -  person wezten    schedule 08.10.2015
comment
Атрибут [STAThread] ничего не делает, он может работать только с точкой входа Main() программы. И ваш обработчик событий ApplicationStartup определенно не является точкой входа. WPF запутывает его, автоматически генерируя Main(), вам нужно взглянуть на obj\Debug\App.g.cs, чтобы увидеть, что с ним могло пойти не так.   -  person Hans Passant    schedule 08.10.2015
comment
@HansPassant App.g.cs имеет атрибут STAThread.   -  person wezten    schedule 08.10.2015


Ответы (1)


Просто предположение, но это может быть ShowDialog() на вашем TestEventRaised?

        System.Windows.Application.Current.Dispatcher.Invoke((Action)(() => { mainForm.ShowDialog(); }));

Может стрелять по какой-то причине.

Если нет, вы можете попытаться обернуть его вокруг вызовов ShowDialog() других конструкторов за пределами функции [STAThread], если некоторые из них когда-либо это сделают.

person Tyress    schedule 08.10.2015
comment
Спасибо, но ваше предыдущее предложение не сработало. Я не понял, как сделать последнее. - person wezten; 08.10.2015
comment
В последней части я имею в виду, есть ли в вашем приложении какие-либо другие вызовы ShowDialog() помимо тех, которые вы указали в своем вопросе? Особенно в экземпляре класса, где происходит сбой. - person Tyress; 08.10.2015