본문 바로가기

프로그램 경험/.Net

[VisualStudio] 디자이너를 로드하기 전에 데이터가 손실되지 않게 하려면 다음 오류를 해결해야 합니다.


이런 오류를 만나면 참 황당하기 그지 없다.
디자이너 화면은 수정한 적도 없는데 이런 화면이 뜨면 더더욱 황당한 노릇이다.

이 오류가 어째서 발생하였는지를 설명해 보겠다.

팝업 화면을 하나 생성하는 과정에서 부모창의 위치를 참조해서 팝업의 위치를 결정 하고 싶었다.
그래서 아래와 같은 로직을 폼 로드 이벤트에 삽입 하였다.
이 폼을 생성한 부모폼(Owner)을 참조하는 로직이다. 

private void Form1_Load(object sender, EventArgs e)
{
    Point owner_location = this.Owner.Location;
    int owner_width = this.Owner.Size.Width;

    int x = owner_location.X + owner_width + 5;
    this.Location = new Point(x, owner_location.Y + 3);
}

이때 까지는 별 문제가 없었으나 이런 팝업폼이 몇개 더 필요 하게 되었다.
중복을 피하기 위해 상위 클래스에 해당 로직을 넣고 상속받게 하였다.
이렇게 하니까 캡쳐와 같은 오류가 생기는 것이다.

이 오류를 찾는 과정에서 재미있는 사실을 발견 하였다.
Visual Studio는 디자이너 타임에서 상속받은 부모 클래스를 인스턴스화 한다는 것이다.

그래서 아래와 같이 상위 클래스의 폼 로드 이벤트에 메시지 박스를 삽입하고 하위 클래스 디자이너 화면을 
열면 메시지 박스를 볼것이다...ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 잼나지 않나? ㅋㅋㅋ

private void Base_Load(object sender, EventArgs e) 
{
   MessageBox.Show("상위 클래스 생성 됐어요~");
}

여튼 문제 해결은 아래와 같이 부모창에서 호출되지 않은 경우의 예외처리를 해주면 화면이 정상적으로 표시될 것이다.

private void Base_Load(object sender, EventArgs e)
{
    if (this.Owner == null)  
       return;

//2014.11.5 수정
//찾아보니 디자인 모드 처리하는 프로퍼티가 아예 따로 있다.
 if (this.DesignMode)
       return;

 
    Point owner_location = this.Owner.Location;
    int owner_width = this.Owner.Size.Width;

    int x = owner_location.X + owner_width + 5;
    this.Location = new Point(x, owner_location.Y + 3);
}