Возникла проблема с вызовом модального диалога после события, вызванного, например, из callback. Метод ShowDialog показывает форму, но она не модальная!
Поясню на примере. У меня есть форма Form1 с одной кнопкой "Fire Event".
У меня есть также форма Form2, которую надо показать как модальный диалог.
Еще есть класс Class1 с таймером внутри, который по истечении одной секунды бросит событие "А показать модальный диалог":
//- Class1 -----------------public class Class1
{
public event EventHandler openDialog = null;
private Timer timer;
public Class1()
{
timer = new Timer( 1000 );
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
}
public void callDialog()
{
timer.Start();
}
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
timer.Stop();
if( openDialog != null )
openDialog( this, null );
}
}
//- endOfClass1 ------------
Класс Class1 инициализирован на главной форме Form1. Нажатие кнопки "Fire Event" вызывает метод Class1.callDialog(). Через секунду вызовется обработчик события таймера, зарегистрированный в Form1, и должно открыться модальное окно Form2.
Вот часть кода Form1:
//- Form1 -------------------private Class1 cls = null;
private System.Windows.Forms.Button btnFire;
:
cls = new Class1();
cls.openDialog += new EventHandler( onOpenDialog );
:
private void btnFire_Click(object sender, System.EventArgs e)
{
cls.callDialog();
}
public void onOpenDialog( object sender, EventArgs e )
{
Form2 frm = new Form2();
frm.ShowDialog( this );
}
//- endOfForm1 --------------
Так вот, Form2 открывается как НЕМОДАЛЬНОЕ. Хотя оно всегда наверху, но юзер может легко понажимать на кнопочки родительской формы Form1, а это не хорошо. Form2 не капчурит все mouse events.
Это, конечно, тест. Реальное приложение работает с тредами и колбэками (клиент, работающий с web-services). Ситуация возникла при перехвате WebExceptions и показе сообщения об ошибке. А юзер, оказывается, после этого может еще чего-нибудь нажать.
Подскажите, пожалуйста, как побороть ситуацию.
P.S. Смотрел на System.Windows.Forms.Form.ShowDialog() — он вызывает UnsafeNativeMethods.GetCapture(). (net framework 1.1).
Евгений
20.07.04 14:38: Перенесено модератором из '.NET' — TK
Здравствуйте, Jevgenij, Вы писали:
J>Возникла проблема с вызовом модального диалога после события, вызванного, например, из callback. Метод ShowDialog показывает форму, но она не модальная!
Проблеммы подобного рода обычно вызваны тем, что вызов ShowDialog производится из другого потока нежели чем родительская форма.
Для того чтобы диалог был модальным, необходимо, чтобы он октрывался в ТОМ ЖЕ потоке что и родительская форма.
Здравствуйте, syrompe, Вы писали:
S>Проблеммы подобного рода обычно вызваны тем, что вызов ShowDialog производится из другого потока нежели чем родительская форма. S>Для того чтобы диалог был модальным, необходимо, чтобы он октрывался в ТОМ ЖЕ потоке что и родительская форма.
Согласен. Может быть подскажете как модифицировать вызов в этом примере?
Здравствуйте, Jevgenij, Вы писали:
J>Здравствуйте, syrompe, Вы писали:
S>>Проблеммы подобного рода обычно вызваны тем, что вызов ShowDialog производится из другого потока нежели чем родительская форма. S>>Для того чтобы диалог был модальным, необходимо, чтобы он октрывался в ТОМ ЖЕ потоке что и родительская форма.
Даже не знаю.
Попробуй отлавливать сообщения таймера в классе формы.
J>Согласен. Может быть подскажете как модифицировать вызов в этом примере?
J>Eugene
Hello, TK
TK>Какой таймер используется? Возможно, что стоит перейти на использование таймера из пространства имен System.Windows.Forms
Да, если заменить на таймер из пространства System.Windows.Forms, то пример работает как надо.
Беда в том, что я пытался с помощью таймера съимитировать проблему, возникающую при перехвате exception в callback функции, выполняемой, естественно в своем треде. Таймер из System.Timers это неплохо эмулировал.
Так что пример заменой таймера починить можно, но это исказит тест. А реальному приложению это не помогает.
Hello, "Jevgenij"
> > Да, если заменить на таймер из пространства System.Windows.Forms, то пример работает как надо. > Беда в том, что я пытался с помощью таймера съимитировать проблему, возникающую при перехвате exception в callback функции, выполняемой, естественно в своем треде. Таймер из System.Timers это неплохо эмулировал. > Так что пример заменой таймера починить можно, но это исказит тест. А реальному приложению это не помогает. >
Для отображения диалога переходи в GUI поток с помощью Control.Invoke
Posted via RSDN NNTP Server 1.9 alpha
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.