[C#] [WPF] [MVVM] Grid에 관하여

Jaemoon Lee·2023년 8월 24일
0

[C샾]

목록 보기
13/13

C# WPF를 활용한 SW를 개발할 때,
프로그램의 디자인은 XAML 코딩을 통해 형성할 수 있다.

이 중 Window, Page, UserControl과 같은 가장 큰 개념을 제외하면
우리가 생성할 "창"을 원하는 구역으로 분할 할 수 있는 큰 개념이 Grid라고 생각한다.

(백문이 불여일견...)

우선 난 HomeView라는 메인뷰(메인 인터페이스)에 종속되는 UserControl을 생성하였다.

이때 코드적 관점에서

<UserControl x:Class="IPLProject.Views.HomeView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:IPLProject.Views"
             xmlns:fa="http://schemas.awesome.incremented/wpf/xaml/fontawesome.sharp"
             mc:Ignorable="d"
             d:DesignHeight="600"
             d:DesignWidth="1000">

위와 같이 UserControl의 기본 속성을 정의하게 되는데,
저 UserControl의 영역에 커서를 갖다댄 뒤 클릭하면

위 사진과 같이 생성한 UserControl 전체 영역이 선택된 선을 확인할 수 있게된다.


그리고 우리는 가장 먼저 (상황에 따라 다르지만 일반적으로) 저 선택된 전체 영역의
'좌측 상단엔 그룹 박스를 할당해야지'
'좌측 하단 남은 공간은 로그 뷰어를 생성해야지'
'우측은 옵션이나 PreView 인터페이스를..'
...

등등 생성된 UserControl에 어떤 컨트롤들을 배치할 지 간략적인 그림을 그려나가게 된다.

그리고 그에 대한 설계가 완료되면 위 사진과 같이 각 구역에 컨트롤을 배치할 Grid를 나눌 수 있게 되는 것이다.

우선 그리드는 어떤 한 공간을 어떤 방식의 Row와 Column으로 나눌 것인지를 정의하는 기능을 뜻하는데,

위 사진의 가장 큰 개념의 Grid는

        <!--유저컨트롤 전체 나누기 (2*3)-->
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="120*" />
            <RowDefinition Height="120*" />
            <RowDefinition Height="210*" />
        </Grid.RowDefinitions>

를 통해 정의한 것이다.

<Grid.ColumnDefinitions> : 그리드를 열로 나눔
ColumnDefinition Width="*" : 열로 나눈 그리드가 차지하는 영역비율. 저기서 star point로 2개의 칼럼 데피니션을 지정했다는 것은 1:1 비율로 열을 나누겠다는 의미이다.

<Grid.RowDefinitions> : 그리드를 행으로 나눔
RowDefinition Height="120*" : 행으로 나눈 그리드가 차지하는 영역비율 - 위 코드는 120:120:210 의 비율로 행을 나누겠다는 의미이다.


전체 그리드를 나누고 나서 프로그래밍을 진행하다보니 한가지 에러 사항이 생겼다.
Text Block이 예쁘게 수직+수평 정렬이 되지 않는 것이다.
(가정한 상황)
그렇다면 우리는 위의 Item ID, Production ID, 2개의 TextBox가
저 Label Data라는 그룹 박스 안에
4 공간을 차지함과 동시에
수직 수평 정렬이 되도록 디자인 해야되는데...

= 전체영역을 나눈 그리드 안에 또 그리드를 지정해야 되는 것이다.

당연하겠지만 안될리가 없다.

<Grid>
        <!--유저컨트롤 전체 나누기 (2*3)-->
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="120*" />
            <RowDefinition Height="120*" />
            <RowDefinition Height="210*" />
        </Grid.RowDefinitions>

        <!--라벨 데이터 입력부 그리드-->
        <Grid Grid.Row="0"
              Name="labelDataGrid">
            <!--라벨 데이터 그룹박스 설정-->
            <GroupBox Header="Label Data"
                      Foreground="White"
                      FontWeight="Medium"
                      FontFamily="Montserrat">
                <!--그룹박스 TextBlock|TextBox 나누기(2*2)-->
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <!--TextBlock1 위치 (1,0,0,0)-->
                    <Grid Grid.Column="0"
                          Grid.Row="0"
                          Name="labelDataTextBlock1Grid">
                        <TextBlock Text="Item ID"
                                   Foreground="White"
                                   FontSize="25"
                                   FontWeight="Medium"
                                   FontFamily="Montserrat"
                                   TextAlignment="Center"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Center"
                                   Margin="1,1,1,1" />
                    </Grid>
                    <!--TextBlock1 위치 (0,0,1,0)-->
                    <Grid Grid.Column="0"
                          Grid.Row="1"
                          Name="labelDataTextBlock2Grid">
                        <TextBlock Text="Production Date"
                                   Foreground="White"
                                   FontSize="25"
                                   FontWeight="Medium"
                                   FontFamily="Montserrat"
                                   TextAlignment="Center"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Center"
                                   Margin="1,1,1,1" />
                    </Grid>
                    <!--TextBlock1 위치 (0,1,0,0)-->
                    <Grid Grid.Column="2"
                          Grid.Row="0"
                          Name="labelDataTextBox1Grid">
                        <TextBox x:Name="textBoxID"
                                 FontSize="25"
                                 FontWeight="Medium"
                                 FontFamily="Montserrat"
                                 Background="Transparent"
                                 Foreground="White"
                                 CaretBrush="{StaticResource plainTextColor3}"
                                 BorderBrush="{StaticResource plainTextColor3}"
                                 BorderThickness="0,0,0,2"
                                 Margin="1,1,1,1"
                                 TextWrapping="Wrap"
                                 Text="1111111111"
                                 HorizontalContentAlignment="Center"
                                 VerticalContentAlignment="Center"
                                 HorizontalAlignment="Center"
                                 VerticalAlignment="Center"
                                 Width="225"
                                 Height="40" />
                    </Grid>
                    <!--TextBlock1 위치 (0,0,0,1)-->
                    <Grid Grid.Column="2"
                          Grid.Row="1"
                          Name="labelDataTextBox2Grid">
                        <TextBox x:Name="textBoxWeek"
                                 FontSize="25"
                                 FontWeight="Medium"
                                 FontFamily="Montserrat"
                                 Background="Transparent"
                                 Foreground="White"
                                 CaretBrush="{StaticResource plainTextColor3}"
                                 BorderBrush="{StaticResource plainTextColor3}"
                                 BorderThickness="0,0,0,2"
                                 Margin="1,1,1,1"
                                 TextWrapping="Wrap"
                                 Text="20230810"
                                 HorizontalContentAlignment="Center"
                                 VerticalContentAlignment="Center"
                                 HorizontalAlignment="Center"
                                 VerticalAlignment="Center"
                                 Width="225"
                                 Height="40" />
                    </Grid>
                </Grid>
            </GroupBox>
        </Grid>

Grid Grid.Row="0"
: 그리드 행의 0번째(배열과 같이 0부터 시작이다.) 영역에 대한 정의. 즉, 위에서 2*3으로 나눈 메인 Grid (라고 칭하겠다.)의 0번째 행을 의미함.

Grid Grid.Column="0"
그리드 열의 0번째 영역에 대한 정의. 즉, 위에서 2*3으로 나눈 메인 Grid (라고 칭하겠다.)의 0번째 열을 의미함.

※ Grid.Column="0" Grid.Row="1" 과 같이 복합 적용이 가능함.

위 코드와 같이 가장 큰 범위의 메인 Grid
안에 다시 그룹박스를 2*2 범위의 그리드로 설정함으로써

(당연히 코드는 상당히 비효율적일 수 있다. 하지만 심미적 만족도를 위해 이정도는 감수할 필요가 있지않나...
마우스로 그냥 대충 설정할 수도 있지만, 개인적으로 Margin을 통해 지정한 것은 추후에 윈도우 크기를 변경하거나, 각 사용자의 화면 해상도 등의 변수로 인해 언제든 대참사가 일어날 수 있음을 명심하자. )

그룹 박스 안의 컨트롤들을 디자인적으로 아주 편-안하게 수직수평 중앙 정렬하도록 하였다.

추가적으로 위 코드엔 나오지 않지만

       <!--라벨 미리보기 창 그리드, 그리드 분할-->
       <Grid Grid.Column="0"
             Grid.Row="1"
             Grid.RowSpan="2"
             Name="logViewGrid">
       </Grid>

Grid.(Column)RowSpan 기능이 마지막으로 존재하는데,
Span이란 상위 Grid에서 지정한 영역을 포함(초과)하여 설정하고 싶을 때 사용한다.

위 Log Box처럼 나는 메인 Grid를 120:120:210로 나눴지만, 120:330으로 좌측 하단에 LogBox를 사용하고 싶다!
라고 한다면
0번째 열 + 1번째 행 + RowSpan=2
를 적용한 logViewGrid를 정의하면 되는 것이다.

(Margin은 Grid에만 적용되는 기능은 아니니 따로 설명하겠다. - 0,0,0,0 좌상우하 순서로 영역을 얼마나 들여쓸 것인가에 대해 정의함.)

profile
초보개발세발자

0개의 댓글