2014-11-19 2 views
0

В vb.net у меня есть приложение winforms, которое периодически запускает форму для проверки нескольких операций в другом потоке основного потока. Я хотел бы показать эти формы «модальным» способом, поэтому поток доступа к основной форме должен быть заблокирован.Показать форму в качестве модальной в новой теме

Возможно ли это?

Есть ли другой способ запустить форму в новом потоке без использования Application.Run (new Form()) ...?

Код выглядит следующим образом:

Imports System 
Imports System.Windows.Forms 

Friend NotInheritable Class Program 

Private Sub New() 
End Sub 

<STAThread() _ 
Shared Sub Main() 
    Application.EnableVisualStyles() 
    Application.SetCompatibleTextRenderingDefault(false) 

    threadFormCheckOperations.Start() 

    Application.Run(New FormMain()) 

End Sub 

Public Shared threadFormCheckOperations As New Thread(AddressOf launchThreadFrmCheckOperations) 

Public Shared Sub launchThreadFrmCheckOperations() 
    While(True) 
     Dim threadForm As New Thread(AddressOf launchFrmCheckOperations) 
     threadForm.Start() 
     threadForm.Join() '---> Wait until thread is closed 
     Thread.Sleep(60000) 
    End While 
End Sub 

Public Shared Sub launchFrmCheckOperations() 
    'I guess, here is where the code have to change… or is in the FormCheckOperations properties? 
    Application.Run(New FormCheckOperations() 
End Sub 


End Class 

ответ

1

вы не можете показать модальное окно из другого потока, но вы можете показать окно и сделать его всегда поверх остальных окон. Это связано с тем, что модальное окно всегда требует окна владельца ... вы, вероятно, знаете, что в окне есть дескриптор, и такие ручки не могут быть разделены между потоками. Поскольку главный обработчик окна принадлежит основному потоку (обычно это поток пользовательского интерфейса), показ модального окна из отдельного потока запрещен и вызовет исключение.

использовать что-то вроде этого, чтобы показать новое окно ...

Dim window As New FormCheckOperations() 
window.Show() 

Установите TopMost -свойство в Form например к истине, чтобы сделать пребывание окна всегда поверх других ...

window.TopMost = True 

Вы также можете найти пример для этого в MSDN: http://msdn.microsoft.com/de-de/library/system.windows.forms.form.topmost(v=vs.110).aspx

Run метод класса Application - это неправильный способ отображения другой формы. Он должен начать цикл сообщения для приложения; см.: http://msdn.microsoft.com/de-de/library/ms157902(v=vs.110).aspx

+0

Спасибо за объяснения, но это не решает мою проблему, так как, если я открываю форму методом '.Show()', она автоматически закрывается. Использование свойства '.TopMost' может быть решением, неудобные всплывающие окна (например: messagebox) в дополнительной форме не могут быть показаны, поскольку дополнительная форма всегда была бы в верхней части .... Но решение кажется ближе. – mzurita

+0

Я думаю, что в вашем приложении есть какое-то заблуждение ... Я предполагаю, что в классе окон есть какая-то логика, которая выполняется, когда вы показываете окно? Возможно, было бы целесообразно разделить логику и пользовательский интерфейс и показать одно модальное окно, которое показывается, прежде чем начнется какой-либо рабочий поток ... каждый поток может показывать данные в модальном окне (для этого требуется определенная синхронизация, но, вероятно, приводят к более чистым и более стабильным приложениям). – Matze

0

Другим способом было бы отключить главное окно перед открытием «модального» -Window и снова включить его после закрытия модала.

+0

Как я могу сделать это в своем текущем решении?(Запуск форм из метода Application.Run() ... Спасибо! – mzurita

0

Вы можете открыть форму, используя ShowDialog, которая прекратит выполнение кода в потоке до тех пор, пока из него не будет закрыто, но оно не будет отображаться поверх любых других форм.

Я думаю, что для того, чтобы сделать то, что вы хотите, вам нужно будет указать форму владельца, чтобы ваша модальная форма была сверху. Проблема в том, что вы получите ошибку Cross-thread operation not valid, если вы попытаетесь сделать это в отдельном потоке:

frmModal.ShowDialog(frmMain) '< errors when run on a separate thread 

Таким образом, вы должны будете использовать Control.Invoke так:

Private Sub ShowModalForm() 
    If Me.InvokeRequired Then 
     Me.BeginInvoke(New Action(AddressOf ShowModalForm)) 
    Else 
     frmModal.ShowDialog(frmMain) 
    End If 
End Sub 
Смежные вопросы