[C#/WPF] Window의 크기를 테두리가 아닌 내부 영역 기준으로 설정하는 방법 (사이즈에 맞추는 방법과 동일)

  WPF를 가지고 놀다 보면 불편한 점이 하나 있습니다. WinForm으로 코딩할 땐 그냥 디자이너나 InitializeComponent() 이후 ClientSize를 설정하면 윈도우 버전/테마마다 다른 테두리 두께와 상관없이 렌더링 영역의 크기를 설정할 수 있었는데, WPF에서는 그렇다 할 프로퍼티가 보이지 않고, 있더라도 불편하게 많은 줄의 코드를 추가해야 한다는 것이죠.

  하지만, 약간의 꼼수만 있다면 언제나 그렇든 매우 간편하게 해결할 수 있습니다.

렌더링 영역이 16:9인 가로 120의 윈도우를 만들고 싶다

  16:9 = 120:67.5 이므로 세로를 68로 설정해야 합니다. 우선, 항상 하듯 WindowWidthHeight를 120과 68로 설정해볼까요?



  보시다시피 창 자체의 크기가 120x68로 설정되었고, 렌더링되는 내부의 크기는 그보다 작게 설정되었습니다.

  뭐, 스택오버플로우나 이곳저곳 돌아다니다 보면 제가 쓰려는 이 방법 말고도 코드 도입부에 4줄정도 추가해 내부 사이즈를 조정하는 방법이 있긴 합니다만, 너무 길고 귀찮으므로 간단하게 XAML 선에서 해결을 봅시다.


  1. Window의 Width, Height 속성을 제거한다.
  2. Window의 SizeToContent 속성을 SizeToContent.WidthAndHeight로 설정한다.
  3. Window의 첫 번째 자식 요소의 WidthHeight를 고정으로 설정한다. (여기선 120, 68)
  위와 같이 하면 일단 시작 시 클라이언트의 영역은 원한 대로 설정됩니다. (120*68)

  그러나, 치명적인 문제가 하나 생기는데요, 윈도우의 크기가 변해야 할 상황이 생기는 경우(리사이즈 등), 내부 엘리먼트가 고정 크기이기 때문에 변하지 않고 그대로 유지됩니다.

  다이얼로그나 기타 고정된 사이즈의 윈도우에는 위 3단계로 충분하지만, 그게 아니라면 아래와 같은 코드를 Window.Loaded 이벤트 핸들러에 등록해야 합니다.

public void Window_Loaded(object sender, RoutedEventArgs e)
{
    ClearValue(SizeToContentProperty);
    _firstChild.ClearValue(WidthProperty);
    _firstChild.ClearValue(HeightProperty);
}


  여기서 _firstChild는 Window의 첫 번째 자식 요소입니다. 보통 Grid이죠. 이렇게 처리하면

  1. 윈도우가 로드되며 SizeToContent 속성을 통해 첫 번째 엘리먼트의 크기로 맞춰지고,
  2. 윈도우가 로드된 후 Window.Loaded 이벤트가 발생해 윈도우의 SizeToContent 프로퍼티를 지우고, 첫 번째 자식 요소의 Width, Height 프로퍼티를 지워
  3. 윈도우 리사이즈시 정상적으로 내부 엘리먼트도 리사이즈되게 됩니다.

댓글

이 블로그의 인기 게시물

C# 남아도는 메모리에도 불구하고 OutOfMemoryException이 발생한다면?

USB를 뒤는 괜찮은데 앞에 꽂으면 인식이 힘들다?

MySQL 데이터 타입과 Java 데이터 타입 비교/매칭