Diskuze: .FormClosed event v hlavním okně a v a okně close na exception... vyhodi exception: K uvolněnému objektu nelze přistupovat.
Člen
Zobrazeno 9 zpráv z 9.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
To na to nemá vliv... Může tam být jen metoda...
Zjistil jsem, že na to nemá vůbec vliv ten event, ale samotné close v tom
exceptionu v konstruktoru...
//konstruktor
public A()
{
InitializeComponent();
try
{
using (StreamReader reader = new StreamReader(@"settings.grh"))
{
string[] file = File.ReadAllLines(@"settings.grh");
List<string> list = new List<string>();
list.AddRange(file);
foreach (string line in list)
{
if (line.Contains("[GROUP="))
{
string[] temp = line.Split('=');
listGroups.Items.Add(temp[1].Replace("]", ""));
}
}
}
}
catch
{
MessageBox.Show("There is missing file settings.grh,\nGRH will not work correctly.", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
Close(); //TOHLE ZPUSOBUJE CHYBU
}
foreach (Control objekt in Controls)
{
if (objekt is ComboBox)
((ComboBox)objekt).SelectedIndexChanged += new EventHandler(EventComboChanged);
}
textAddGroup.Text = "Group Name";
textAddGroup.ForeColor = Color.Gray;
textAddPlayer.Text = "Player Name";
textAddPlayer.ForeColor = Color.Gray;
}
Chyba:
Neošetřená výjimka typu System.ObjectDisposedException vznikla v System.Windows.Forms.dll.
Další informace: K uvolněnému objektu nelze přistupovat.
Zavírat form hned v konstruktoru je poměrně "nestandartní" postup. A ani to nepotřebuješ -
když ti konstruktor form nevytvoří, tak ho ani nemusíš zavírat.
Navíc se pokoušíš přistupovat k objektu, který jsi vlastně ani
nevytvořil.
Co se týče neošetřené vyjímky - ty ji musíš poslat dál a někde zpracovat.
Něco si o vyjímkách nastuduj - třeba tady
mělo by to vypadat zhruba takto:
public A()
{
InitializeComponent();
try
{
using (StreamReader reader = new StreamReader(@"settings.grh"))
{
string[] file = File.ReadAllLines(@"settings.grh");
List<string> list = new List<string>();
list.AddRange(file);
foreach (string line in list)
{
if (line.Contains("[GROUP="))
{
string[] temp = line.Split('=');
listGroups.Items.Add(temp[1].Replace("]", ""));
}
}
}
}
catch
{
if (MessageBox.Show("There is missing file settings.grh,\nGRH will not work correctly.", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1) == DialogResult.OK)
throw new Exception("nejaky problem :(");
}
foreach (Control objekt in Controls)
{
if (objekt is ComboBox)
((ComboBox)objekt).SelectedIndexChanged += new EventHandler(EventComboChanged);
}
textAddGroup.Text = "Group Name";
textAddGroup.ForeColor = Color.Gray;
textAddPlayer.Text = "Player Name";
textAddPlayer.ForeColor = Color.Gray;
}
private void btnGroupClick(object sender, EventArgs e)
{
if (!isOpenedEditGroups)
{
try
{
A a = new A();
a.Show();
isOpenedEditGroups = true;
a.FormClosed += GroupEditClosedEvent;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "pozor", MessageBoxButtons.OK);
}
;
}
}
K a.FormClosed musíš přiřadit event handler FormClosedEventHandler a ne jenom metodu:
to bylo dřív - ve VS2015 (možná i VS2013, nevím) už to být nemusí
Problém bude zřejmě v tom, že se pokoušíš form zavřít už v konstruktoru, kde ale ještě není úplně vytvořený. V konstruktoru bys měl maximálně nastavovat nějaké property které si vytvoříš, ale ne sahat na UI nebo form zavírat.
Místo kde to můžeš bezpečně udělat, protože už je všechno vytvořeno, je při vyvolání eventu Loaded (týká se jenom WPF) nebo Shown (týká se winformů). U winformů je ještě event Load, ale tam bych byl taky opatrný, nejsem si úplně jistý co všechno je při jeho zavolání už vytvořeno a co ještě ne.
Myslím, že když dojde k vyjímce v konstruktoru,tak to Garbage Collector všechno uklidí.(ale jistě to nevím)
ale to že má v konstruktoru věci, které by tam být neměly je pravda
Já vím, samozřejmě bych to mohl vyřešit takhle:
try
{
Options options = new Options();
options.Show();
isOpenedEditGroups = true;
options.FormClosed += new FormClosedEventHandler(GroupEditClosedEvent);
}
catch
{
MessageBox.Show("////", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
}
Ale zajímalo mě, jak to vyřešit takhle Díky
Honza má pravdu - dej to radši do obsluhy události Load, nebo Shown
private void A_Load(object sender, EventArgs e)
{
try
{
using (StreamReader reader = new StreamReader(@"settings.grh"))
{
string[] file = File.ReadAllLines(@"settings.grh");
List<string> list = new List<string>();
list.AddRange(file);
foreach (string line in list)
{
if (line.Contains("[GROUP="))
{
string[] temp = line.Split('=');
listGroups.Items.Add(temp[1].Replace("]", ""));
}
}
}
}
catch (Exception ex)
{
if (MessageBox.Show(ex.Message, "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1) == DialogResult.OK)
{
Close();
}
throw new Exception(ex.Message);
}
}
tohle ti přímo hodí hlášku do MessageBoxu, že "soubor settings.grh nebyl nalezen"
Zobrazeno 9 zpráv z 9.