윈폼(Winforms) 판넬(Panel) 안에서 컨트롤들을 수평으로 정렬하기

윈폼(Winforms) 판넬(Panel) 안에서 컨트롤들을 수평으로 정렬하기

이철우

최근에 윈폼에서 UI 작업할 기회가 생겼다. 간만에 윈폼을 보니 여러 컨테이너 컨트롤들, Dock 속성 등이 신기하게 느겨진다. VB 6.0 UI와 비교해서 그럴지도 모르겠다.

아무래도 UI는 이뻐야 하는 것, 그 중 먼저가 삐뚤빼뚤이 아닌 '정렬’이다. 그런데 판넬 안에서 TextBox, ComboBox를 Label과 함께 수평으로 맞추는 것이 잘 안되었다.

그래서 찾은 방법이 [참고 1] 에 있는 두 번째 답글(글쓴이 CodingYoshi)이다. [참고 1]의 [그림 1]을 하게 되면 '수평으로 맞추’게 된다.

그림 1 질문
[그림 1]

어셈블리 수준에서 재활용 할 수 있게, 또 여러 컨트롤에도 적용 할 수 있게 생성형(Generic)으로 라이브러리(dll)를 만들고 그것을 사용하는 실행(exe)을 만들자. 닷넷 8.0(.Net 8.0)으로 하겠다.

라이브러리(Windows Forms Control Library) 만들기

000 비어있는 솔루션을 만들고 프로젝트 Windows Forms Control Library 를 추가한다. 프로젝트 이름은 'L’이다.

001 [참고 1] 에 있는 두 번째 답글을 정적 클래스(Helper.cs)의 정적 메서드로 만들어 프로젝트 'L’에 추가한다.

    // Helper.cs

    internal static class Helper
    {
        internal static void SetControl2VeticallyCenterInTableLayoutPanel(this TableLayoutPanel tableLayoutPanel, Control control)
        {
            tableLayoutPanel.RowCount = 3;
            tableLayoutPanel.ColumnCount = 1;

            tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 50.0F));
            tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
            tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
            tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 50.0F));

            tableLayoutPanel.Controls.Clear();
            control.Dock = DockStyle.Fill;
            tableLayoutPanel.Controls.Add(control, 0, 1);

            //control.BackColorChanged += (s, e) => tableLayoutPanel.BackColor = control.BackColor;
        }
    }

002 사용자 컨트롤을 프로젝트 'L’에 추가한다. 이름은 VerticallyCenterUserControl.cs 이다.

003 VerticallyCenterUserControl.cs를 코드보기로 연다. 그리고 아래와 같이 코딩한다.

    // VerticallyCenterUserControl.cs

    public partial class VerticallyCenterUserControl<T> : UserControl where T : Control, new()
    {
        private readonly TableLayoutPanel _tableLayoutPanel;
        public T GenericControl { get; init; }

        public VerticallyCenterUserControl()
        {
            InitializeComponent();

            _tableLayoutPanel = new TableLayoutPanel();
            GenericControl = new T();

            InitComponent();
        }

        private void InitComponent()
        {
            _tableLayoutPanel.SuspendLayout();
            SuspendLayout();

            _tableLayoutPanel.SetControl2VeticallyCenterInTableLayoutPanel(GenericControl);
            _tableLayoutPanel.Dock = DockStyle.Fill;
            Controls.Add(_tableLayoutPanel);

            _tableLayoutPanel.ResumeLayout(false);
            _tableLayoutPanel.PerformLayout();
            ResumeLayout(false);
        }
    }

004 VerticallyCenterUserControl.Designer.cs의 클래스 선언에도 "<‘T’>"를 붙인다.

partial class VerticallyCenterUserControl<T>

005 빌드하여 에러가 없음을 확인한다.

006 사용자 컨트롤을 프로젝트 'L’에 추가한다. 이름은 VerticallyCenterTextBox.cs 이다.

007 VerticallyCenterTextBox.cs를 코드보기로 연다. 그리고 아래와 같이 코딩한다.

    VerticallyCenterTextBox.cs

    public partial class VerticallyCenterTextBox: VerticallyCenterUserControl<TextBox>
    {
        public VerticallyCenterTextBox()
        {
            InitializeComponent();
        }
    }

008 빌드하여 에러가 없음을 확인한다.

009 사용자 컨트롤을 프로젝트 'L’에 추가한다. 이름은 VerticallyCenterComboBox.cs 이다.

010 VerticallyCenterComboBox.cs를 코드보기로 연다. 그리고 아래와 같이 코딩한다.

    VerticallyCenterComboBox.cs

    public partial class VerticallyCenterComboBox : VerticallyCenterUserControl<ComboBox>
    {
        public VerticallyCenterComboBox()
        {
            InitializeComponent();
        }
    }

011 빌드하여 에러가 없음을 확인한다.

실행(Windows Forms App) 만들기

100 프로젝트 'L’이 있는 솔루션에 프로젝트 Windows Forms App 를 추가한다. 프로젝트 이름은 'E’이다.

101 프로젝트 'E’에서 프로젝트 'L’을 참조한다.

102 Toolbox 에 VerticallyCenterTextBox, VerticallyCenterComboBox이 보일 것이다.
보이지 않는다면 VisualStudio-Tools-Options-Windows Forms Designer-Toobox-Automatically Populate Toolbox를 'True’로 바꾼다.

103 자동으로 생성된 ‘Form1.cs’ 위에 판넬을 끌어넣는다. 판넬 이름은 'panel1’이다.

104 (수평 정렬을 보기 위해) panel1의 BackColor를 ActiveCaption으로 바꾼다.

104 panel1 위에 VerticallyCenterTextBox를 끌어 넣는다. VerticallyCenterTextBox의 Dock 속성을 'Left’로 바꾼다.

105 panel1 위에 VerticallyCenterComboBox를 끌어 넣는다. VerticallyCenterComboBox의 Dock 속성을 'Left’로 바꾼다.

106 디자인 모드에서 Form1은 아래와 같이 보일 것이다. 수평으로 가운데 정렬이 되었다.

그림 2 디자인 모드
[그림 2]

107 VerticallyCenterTextBox, VerticallyCenterComboBox의 가로를 디자인 모드에서 바꿔보기 바란다.

108 VerticallyCenterTextBox, VerticallyCenterComboBox 각각의 핵심 컨트롤인 TextBox, ComboBox는 속성창에서 GenericControl로 접근할 수 있다. 그러나 GenericControl(TextBox, ComboBox 등)의 속성 변경은 VerticallyCenterTextBox, VerticallyCenterComboBox 의 생성자 또는 Load 이벤트에서 해주어야 한다.

(퀴즈) DateTimePicker 컨트롤을 위의 VerticallyCenterUserControl을 활용하여 수평 정렬되는 콘트롤로 만들어 보아라.

[참고 1] Are there any ways to align a textbox vertically middle within a panel?

컨테이너(panel이나 groupbox…등)로 감싸고
dock.fill 설정 후 앵커 탑.바텀 풀어서 사용해요 저는

네~ 이쁘게 UI 만드시기 바랍니다^^

잘 읽었습니다.
저도 wpf만 사용하다보니 winform이 오랫만이긴하네요…

저도 예전엔 아래 이미지내 기능들을 사용했었었는데 감회가 새로워요~

1개의 좋아요