[c#] 폼이 종료되었는지 확인하는 방법

폼이 종료되었는지 확인해야 할 때가 있다. 예를 들어 설정 창을 새로운 폼으로 만든 때 이 창은 하나만 떠야 한다. 설정 창을 두 개 이상 동시에 열리지 않게 하려면 이 창이 열려 있지 않을 때에만 창이 만들어지게 하면 된다. 근데 이게 약간 복잡하다.

아래와 같이 form이 visible한지 확인하려고 하면 오류로 멈춘다. 폼을 선언만 하고 인스턴스를 만들지는 않아서 null인 상태인데 널인 객체에 접근을 하려 해서 그렇다.

Form2 SecondForm;

private void button1_Click(object sender, EventArgs e)
{
if (!SecondForm.Visible)
{
SecondForm = new(this);

SecondForm.Visible = true;
}
}

그렇다고 아래와 같이 폼이 널인지를 확인하면 될 때도 있고 되지 않을 때도 있다. 폼을 만들기 전에는 되지만 일단 만들고 종료한 뒤 다시 해 보면 안 된다. 오류로 멈추지는 않지만 열리지도 않는다. 폼이 종료되었지만 여전히 메모리에 올려져 있고 널이 아니기 때문이다. 폼은 close되어도 널이 되지는 않는다. 따로 널로 만들어 줘야 한다.

private void button2_Click(object sender, EventArgs e)
{
if (SecondForm == null)
{
SecondForm = new(this);

SecondForm.Visible = true;
}
}

새로 열린 창이 close되거나 close된 때 아래와 같이 this 즉 자기 자신을 널로 만들게 하는 방법을 생각해 볼 수 있지만 역시 안 된다. this는 읽기 전용 객체이기 때문이다.

private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
this = null;
}

private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
this = null;
}

메인 폼 아닌 폼이 종료된 때 널로 만들려면 아래와 같이 메인 폼에서 종료된 폼을 널로 만들어야 한다. 새로 만들어진 폼의 종료 이벤트를 메인 폼에 만드는 거다.

private void button3_Click(object sender, EventArgs e)
{
SecondForm = new(this);

SecondForm.FormClosed += SecondForm_FormClosed;

SecondForm.Show();
}

private void SecondForm_FormClosed(object? sender, FormClosedEventArgs e)
{
SecondForm = null;
}