2010-01-19 2 views
4

У меня есть 2 формы. Из одной формы я создал и показал другую форму. Он отлично работает. Но когда я пытаюсь закрыть или Dispose эту форму из формы, создавшего его я получаю следующее исключение:Форма Dispose() или Close()

 
Exception : 
    Value Dispose() cannot be called while doing CreateHandle(). 

Stack Trace : 
======================== 
    at System.Windows.Forms.Control.Dispose(Boolean disposing) 
    at System.Windows.Forms.Label.Dispose(Boolean disposing) 
    at System.ComponentModel.Component.Dispose() 
    at System.Windows.Forms.Control.Dispose(Boolean disposing) 
    at System.Windows.Forms.ContainerControl.Dispose(Boolean disposing) 
    at System.Windows.Forms.Form.Dispose(Boolean disposing) 
    at Speedometer_Application.frmSpeedometer.Dispose(Boolean disposing) 

Любая идея ????

+0

Это зависит от того, какой код использовался для отображения другой формы. – geekonweb

ответ

0

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

if (frmMain.objfrm== null) 
{ 
    frmMain.objfrm = frmMyForm.Instance;  
    frmMain.objfrm.ShowInTaskbar = false;  
} 
frmMain.objfrm.Show(); 
frmMain.objfrm.BringToFront(); 

frmMain является основной формой, которая имеет статическую переменную frmMyForm. чем в моем коде, если я хочу использовать это, я просто проверяю, не является ли это чем-то недействительным, чем создавать его с помощью статического экземпляра, а не давать peoperty.

при закрытии формы У меня есть следующий код:

frmMain.objfrm.Close_this(); 

Close_this вызывает Закрывать метод() или Dispose().

Но когда я вызываю эту функцию, я получаю исключение выше.

1

трудно сказать, в чем проблема с кодом, который вы опубликовали.

Код, который вы опубликовали, должен работать (форма, показанная с помощью Show(), должна быть закрыта с помощью метода Dispose()).

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

Мое предложение - прокомментировать весь ваш код в форме objfrm (или создать новую EMPTY-форму) и посмотреть, произошла ли ошибка. Это не должно произойти. Затем добавьте комментарий и посмотрите, когда произойдет ошибка. Уверен, что это будет в коде, который вызывается как следствие метода Dispose.

+0

У меня проблема. У меня есть отметка таймера, и событие делегата вызывается каждые 100 миллисекунд. поэтому, когда он пытается избавиться от формы, в которой работает событие в потоке рабочего, и я получаю исключение !!! Но мне нужно, чтобы это событие запускалось каждые 100 миллисекунд. так что теперь может быть решением ??? – Jankhana

0

Вам необходимо использовать ShowDialog вместо Показать вот и проблема. Показать не блокировать приложение, и код продолжает работать.

Вы избавляетесь объект, когда графический интерфейс, создавая его (то, что сказал исключение)

Попробуйте с этим:

if (frmMain.objfrm== null) 
{ 
    frmMain.objfrm = frmMyForm.Instance;  
    frmMain.objfrm.ShowInTaskbar = false;  
} 
frmMain.objfrm.ShowDialog(); 

Обратите внимание на ShowDialog()

+0

ShowDialog() не работает. все-таки такое же исключение приходит !!! – Jankhana

+0

И почему вы используете .Instance? вы можете попробовать: frmMain.objfrm = new frmMyForm(); Cheers – MarcosMeli

13

Погрешность Value Close() cannot be called while doing CreateHandle() обычно происходит, когда мы пытаемся закрыть форму в конструкторе или событии Load.

Например, следующий код выдает ошибку:

private void frmCustomer_Load(object sender, EventArgs e) 
{ 
if (!Valid()) 
    this.Close; 
} 

Решение:

private void frmCustomer_Load(object sender, EventArgs e) 
{ 
if (!Valid()) 
    this.BeginInvoke(new MethodInvoker(Close)); 
} 

Вы можете использовать это в вашем коде.

+2

Это альтернатива VB: «Me.BeginInvoke (новый методInvoker (AddressOf Close))' – TechyGypo

0

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

Invoke((Action) (() => labelOnlineStatus.Text = "changed")); 

Проверить это answer для более подробной информации.

Смежные вопросы