2014-01-19 3 views
1

WinFormWinForm против WPF .close() событие

public Form1() 
{ 
    Form2 obj = new Form2(); 
    obj.show(); //shows form2 
    this.Close(); //exception crash: bcoz constructor have not yet called `new Form1.show()` 
} 

В Winform

  1. 'this.close()' будет через исключение и аварии (не может отчуждать объект не инициализирован)
  2. если я не звоню .close в Form1, а i close (X) Form1, Form2 также будет получить закрытым bcoz является экземпляром в Form1

в WPF, тот же код:

  1. 'this.close()' не через исключение
  2. Если Form1 закрыт, Form2 будет оставаться открытым в MainWindow.

Why is the Difference?

* (Edit) * Я знаю, что в Winform я не могу закрыть ту же форму в конструкторе bcoz его еще не создан, но how is WPF differ with it in constructor call?.

И что, если я хочу, чтобы все окна детей закрывались, если родители закрылись, WinForm?

+0

В WinForms, рекомендуется использовать InitializeControls/FormLoaded вместо создания элементов управления (и особенно пытается закрыть ту же форму) в конструкторе. – user2864740

+0

В WPF вы закрываете Window или UserControl? –

+0

Вы видели http://stackoverflow.com/questions/3067901/c-sharp-closing-a-form-during-a-constructor – grantnz

ответ

3

Разница заключается в том, как реализуется метод Close для каждого класса. Несмотря на сходство функций и внешнего вида, System.Windows.Forms.Form и System.Windows.Window представляют собой два совершенно разных класса, построенных на основе двух разных архитектур.

System.Windows.Forms.Form существует с .NET 1.0 и в основном представляет собой просто тонкую, удобную в использовании оболочку вокруг собственной предварительной (то есть, не объектно-ориентированной) библиотеки Windows UI.

System.Windows.Window является частью WPF, который был представлен в .NET 3.0, был попыткой создать современную инфраструктуру пользовательского интерфейса поверх CLI (а не просто обертывать старую библиотеку Windows UI). Таким образом, реализация System.Windows.Window может быть совершенно иной, чем реализация System.Windows.Forms.Form. Кроме того, хотя операции, доступные в этих классах, могут быть внешне похожими, они не могут быть семантически идентичными. В этом смысле Form.Close и Window.Close не обязательно имеют точно такой же смысл.

Теперь, в этом конкретном случае, согласно документации (http://msdn.microsoft.com/en-us/library/system.windows.forms.form.close(v=vs.110).aspx), вы получаете это исключение, потому что «Форма была закрыта при создании дескриптора». Если вы немного распакуете этот оператор, это значит, что вы сделали вызов метода Close до того, как дескриптор окна (HWND) был создан. Это фактически не имеет ничего общего с тем фактом, что вы закрываете окно в конструкторе: конструктор класса Form уже завершен на этом этапе. Объект Form в .NET представляет собой собственное окно в ОС Windows, которое идентифицируется дескриптором окна (или HWND, который является именем типа, используемым в C/C++). Однако, поскольку создание дескриптора окна является дорогостоящим процессом, объект Form фактически не создает дескриптор, пока он ему не понадобится. Таким образом, дескриптор окна для объекта формы не существует, пока вы не вызываете Form.Show, Form.HWND или какой-либо другой метод, который заставляет его создавать. Если вы вызвали this.Show() прямо перед этим.Close(), исключение не будет выбрано.

Почему это не так в System.Windows.Window? Я предполагаю, что метод Close в System.Windows.Окно немного «умнее» и просто пропускает шаг распоряжения дескриптором, если он еще не существует. Или, возможно, дескриптор окна создается с нетерпением, в отличие от реализации Форм.

Невозможно ли это различие полностью преднамеренно. Не совсем ясно, имеет ли смысл «закрывать» Окно, которое никогда не было показано в первую очередь, и если попытка сделать это должна вызвать исключение. Его выбор дизайна. Возможно, что программисты Microsoft теперь предпочитают семантику System.Windows.Window.Close над менее прощающим System.Windows.Forms.Close, но такое внесение такого изменения не будет обратно совместимым. Или, его возможности никто не замечал и не думал о разнице.

+0

+1 Благодарим за подробную информацию. Я понял. Я был смущен, исходя из фона WinForm, но реальная проблема остается. В WPF. Если я закрываю Form1, не закрываем Form2, а bcoz его экземпляр находится внутри Form1. для 'Window' нет .Dispose(). – ADi

+0

Я действительно не был уверен, что вы пытались выполнить, на самом деле. Но короткий ответ - нет. Просто потому, что Form2 был создан внутри конструктора Form1, это не означает, что Form2 является «внутри» Form1. Form2 - это собственный автономный экземпляр Window. Вы можете сохранить ссылку на Form2, а затем переопределить метод Close Form1 для vall Form2.Close явно. Или, если вы пытаетесь выключить программу, вы можете вызвать Application.Current.Shutdown. Было бы лучше, если бы вы опубликовали новый вопрос и объяснили, что вы на самом деле пытаетесь сделать. – Nimrand

+0

Спасибо за ответ ур, на самом деле из урской информации и ответа Бсиенна я понял, в чем проблема. на самом деле, когда я закрываю Window1, я надеялся, что он закроет Window2 и выйдет из программы. Но в WPF это не так. – ADi

1

В WPF вы не вручную удаляете объекты WPF, они получают сборку мусора, когда больше нет ссылок на них.

Как ваша форма 1 имеет ссылку на форму 2, ур Form1 останется в живых в фоновом режиме, скрывая форму на .close(), пока вы не закроете Form2.

Вы можете уничтожить все объекты при закрытии события Form1, или вы можете заставить приложение закрыть, что не является хорошей идеей, если вы не обрабатываете несохраненные данные.

это очень через информацию делать это How to exit a WPF app programmatically?

+0

+1 спасибо за ответ ур, я понял проблему сейчас. как ур правильный, но извините, не могу принять ur anser bcoz, я могу только 1. Моя ошибка для того, чтобы задать 2 вопроса в одной теме. – ADi

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