Хотя невозможно создать форму в одном потоке и отобразить ее в другом потоке, , безусловно, позволяет создать форму в неосновном потоке графического интерфейса пользователя. Текущий принятый ответ, кажется, говорит, что это невозможно.
Windows Forms применяет модель однопоточных квартир. Таким образом, это означает, что в каждом потоке может быть только один цикл сообщений Windows и наоборот. Кроме того, если, например, threadA хочет взаимодействовать с циклом сообщений threadB, он должен перенаправить вызов с помощью таких механизмов, как BeginInvoke.
Однако, если вы создаете новый поток и предоставляете ему свой собственный цикл сообщений, этот поток будет счастливо обрабатывать события независимо, пока ему не будет сказано завершить цикл сообщений.
Для демонстрации ниже приведен код Windows Forms для создания и отображения формы в потоке без графического интерфейса пользователя:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
label1.Text = Thread.CurrentThread.ManagedThreadId.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
ThreadStart ts = new ThreadStart(OpenForm);
Thread t = new Thread(ts);
t.IsBackground=false;
t.Start();
}
private void OpenForm()
{
Form2 f2 = new Form2();
f2.ShowDialog();
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
label1.Text = Thread.CurrentThread.ManagedThreadId.ToString() ;
}
}
Метод OpenForm запускается в новом потоке и создает экземпляр Form2.
Form2 фактически получает свой собственный отдельный цикл сообщений, вызывая ShowDialog (). Если бы вместо этого вы вызывали Show (), цикл сообщений не предоставлялся бы, и Form2 немедленно закрывался бы.
Кроме того, если вы попытаетесь получить доступ к Form1 в OpenForm () (например, с помощью 'this'), вы получите сообщение об ошибке во время выполнения при попытке доступа к пользовательскому интерфейсу между потоками.
t.IsBackground=false
устанавливает нить как нить переднего плана. Нам нужен поток переднего плана, потому что фоновые потоки уничтожаются немедленно, когда основная форма закрывается без предварительного вызова событий FormClosing или FormClosed.
Помимо этих пунктов, Form2 теперь может использоваться как любая другая форма. Вы заметите, что Form1 все еще счастливо работает как обычно с собственным сообщением lopp. Это означает, что вы можете нажать на кнопку и создать несколько экземпляров Form2, каждый из которых имеет свой отдельный цикл и поток сообщений.
Вы должны быть осторожны с перекрестным доступом к форме, который теперь фактически является перекрестным. Вам также необходимо убедиться, что вы обрабатываете закрытие основной формы, чтобы гарантировать, что все неосновные формы потоков закрыты правильно.