그리드 컨트롤

dotnet의 wpf 템플릿을 실행하면

xaml 에서 Window 의 자식 컨트롤이

Grid로 되어 있습니다.

버튼이나 텍스트 블록 등 wpf 의

UI 구성요소들을 배치하려면

레이아웃이 필요한데 wpf 에서는

패널(Panel) 개념을 사용합니다.

 

패널에는 Canvas, StackPanel, Grid

패널 등이 있습니다. 자바의 스윙GUI을

사용해본 적이 있다면 일종의 레이아웃객체,

레이아웃 매니저 같은 것 입니다.

 

xaml은 태그를 사용해서 좀 html 과

비슷하다는 느낌이 듭니다만,

데스크탑 앱인 xaml 이 더 엄격한 언어로

속성하나만 틀려도 컴파일이 안됩니다.

 

그래서 까다롭긴 한데 개념만 잡으면

직관적인 디자인이 가능하기 때문에

훨씬 수월한 부분이 있습니다.

전통적 방식으로는 사용자 UI 부분과

내부 로직을 같은 언어로 사용하기 때문에

같은 사람이 해야하는 한계가 있습니다.

반면 wpf는 xaml 은 UI디자이너가

비즈니스 로직은 프로그래머가

분업할 수 있는 구조가 되었습니다.

 

자바 스윙이나 AWT, 더 거슬러 올라가면

Win32 같은 것을 사용해보면 알겠지만

잘 만들기가 힘듭니다. 왜냐하면

프로그래머는 보통 UI디자인 같은 것은

익숙하지 않고 UI디자이너는 프로그램에

익숙하지 않기 때문입니다. 이 두가지를

다 잘하면 좋겠지만 그것을 비유하면

이과 대학을 졸업한 후 미술대학원을

다니는 것과 같습니다. 그러니까

둘중 하나가 좀 부족한 것 같다 -면 정상입니다.

 

 

PC사양이 발달하지 않았을 때는

괜찮았는데 점점 하드웨어가 발달하면서

소프트웨어의 품질도 올리는 방향으로

가다보니 이런 분업이 가능해진 역사가 있습니다.

 

mvvm 패턴들도 혼자서 작업을 많이하라고

만든 패턴은 아닐 겁니다.

분업이 필요한 회사에서 분업하라고

만든 패턴이겠지요.

 

어쨋든 wpf 가 뭔지 추상적인 이야기만

하다보면 잘 이해가 안되는데

xaml 을 사용해보면 좀 더 이해가 빠릅니다.

html 을 다뤄봤다면 더 쉬울 것 입니다.

 

예제

dotnet new wpf 로 생성한 템플릿에는

<Grid></Grid> 로 비워져 있는 부분이 있습니다.

 

여기다가 Button 등 콘트롤들을

그냥 넣으면 서로 겹쳐집니다.

 

그리드 콘트롤은 워드의 테이블처럼

행과 열을 만들어 줘야 합니다.

 

열을 두개로 나눠 보겠습니다.

 

    <Grid>

        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Button Grid.Column="0">Btn1</Button>
        <Button Grid.Column="1">Btn2</Button>

    </Grid>

<ColumnDefinition/> 이것 하나가 열 하나입니다.

두개를 넣었으니 열이 두개가 되었습니다.

버튼에는 Grid.Column 으로 인덱스를

지정해줍니다. 0부터 시작합니다.

 

 

칼럼(열)을 세개 넣으면 어떻게 될까요?

버튼은 2개

        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

 

이제 이원리를 터특했다면 다음은 쉽습니다.

 

Grid 콘트롤로 계산기 자판을 만들어 보겠습니다.

 

    <Grid>

        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Grid.Column="0" FontSize="20">1</Button>
        <Button Grid.Row="0" Grid.Column="1" FontSize="20">2</Button>
        <Button Grid.Row="0" Grid.Column="2" FontSize="20">3</Button>
        <Button Grid.Row="1" Grid.Column="0" FontSize="20">4</Button>
        <Button Grid.Row="1" Grid.Column="1" FontSize="20">5</Button>
        <Button Grid.Row="1" Grid.Column="2" FontSize="20">6</Button>
        <Button Grid.Row="2" Grid.Column="0" FontSize="20">7</Button>
        <Button Grid.Row="2" Grid.Column="1" FontSize="20">8</Button>
        <Button Grid.Row="2" Grid.Column="2" FontSize="20">9</Button>

        <Button Grid.Row="0" Grid.Column="3" FontSize="20">X</Button>
        <Button Grid.Row="1" Grid.Column="3" FontSize="20">-</Button>
        <Button Grid.Row="2" Grid.Column="3" FontSize="20">+</Button>
        
        <Button Grid.Row="3" Grid.Column="0" FontSize="20">/</Button>
        <Button Grid.Row="3" Grid.Column="1" FontSize="20">0</Button>
        <Button Grid.Row="3" Grid.Column="2" FontSize="20">.</Button>
        <Button Grid.Row="3" Grid.Column="3" FontSize="20">=</Button>
        
    </Grid>

 

결과는 아래와 같이 나옵니다.

아주 훌륭하지는 않지만 쓸만합니다.

윈도창의 크기 자체는 Window 태그에서

적당히 설정할 수 있습니다.

그럴 듯한 계산기 처럼 보이면 충분합니다.

이것을 C#의 문법으로 타이핑하면

복잡해 보이는데 마크업 언어의

트리형식으로 보면 명확합니다.

wpf 그리드 컨트롤 (Grid Control)

너비와 높이 조정하기

그리드 컨트롤에서는 각 그리드 너비와

높이를 상대적 비율로 조절이 가능합니다.

 

위의 계산기 자판 그리드 비율을 조정해보겠습니다.

 

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="2*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="3*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>

첫번째 열은 2배입니다. 2*는 2배라는 뜻입니다.

3번째 행은 3배입니다. 3*는 3배입니다.

ColumnDefinition 과 RowDefinition에서 조절이 가능합니다.

너비를 픽셀단위로 직접 조절할려면

Width="50" 처럼 수치를 지정해주면 되고

안의 텍스트에 따라 가변길이로 바꿀려면

"Auto" 로 지정합니다. 알아서 Grid가

그려주기 때문에 상당히 편리합니다.

 

스팬(Span)

스팬 속성은 그리드의 개수입니다.

1이면 하나 2이면 2개 입니다.

 

Grid.RowSpan과 Grid.ColumnSpan으로

스팬을 늘릴 수 있습니다. Button 콘트롤은

위에 쌓는 방식(위에 그려버리는)이니까

스팬 공간을 확보하도록 합니다.

 

    <Grid>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Grid.RowSpan="2" Grid.Column="0" FontSize="20">1</Button>
        <Button Grid.Row="0" Grid.Column="1" FontSize="20">2</Button>
        <Button Grid.Row="0" Grid.Column="2" FontSize="20">3</Button>

        <Button Grid.Row="1" Grid.Column="1" FontSize="20">5</Button>
        <Button Grid.Row="1" Grid.Column="2" FontSize="20">6</Button>
        <Button Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" FontSize="20">7</Button>

 

 

그리드 스플리터

그리드 스플리터 - GridSplitter는

사용자가 칸을 조절할 수 있게하는

컨트롤입니다. 너무 자잘한 조절보다는

큰 틀에서의 조절 기능에서 사용하는게 좋지요.

(패널의 크기 조절 등)

 

<Grid>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="5"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        
        <Button Grid.Row="0" Grid.Column="0" FontSize="20">1</Button>
        <GridSplitter HorizontalAlignment="Center" Grid.Column="1" Width="5"/>
        <Button Grid.Row="0" Grid.Column="2" FontSize="20">2</Button>

      </Grid>

 

 

그리드 패널 로그인 창

그리드 콘트롤을 사용한 로그인 창입니다.

높이가 250 너비가 300으로

디자이너를 사용하는 것도 좋지만

다 끝난 후에는 직접 타이핑을 하면서

문서의 구조를 정리하는 것이 좋습니다.

 

<Grid Margin="10">

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>

        <Label Grid.Row="0" Grid.ColumnSpan="2" FontSize="15" HorizontalAlignment="Center">User Login</Label>
        
        <Label Grid.Row="1" Margin="10,0,0,5">id:</Label>
        <TextBox Grid.Row="1" Grid.Column="1" Margin="5,0,20,5"/>
        <Label Grid.Row="2" Margin="10,0,0,5">password:</Label>
        <TextBox Grid.Row="2" Grid.Column="1" Margin="5,0,20,5"/>
        <Button Grid.Row="3" Grid.ColumnSpan="2" HorizontalAlignment="center" Width="50" Height="30">login</Button>

 </Grid>

많은 에너지를 쏟지 않아도

그렇저럭 쓸만하게 나오는게 장점입니다.

 

로그인창 WPF

 

*그리드 콘트롤을 다룰 수 있다면

다른 콘트롤 패널은 별로 어렵지 않을겁니다.

 

대부분 배치하고 정렬하고 마진 설정하는 것

순서 배치하는 것들이니까 한번 쯤 정리해두면

사용하는데 큰 문제가 없을 겁니다.

 

코딩 로직과 달리 레이아웃은

최대한 실습을 해보는게 좋습니다.

이건 정확한 로직보다는 감각의 영역이란게

있기 때문에 사람이 사용하기 편하게

배치할 줄을 알아야 합니다.

기능적인 문제가 해결되면 그 다음은

미적인 품질을 올릴 수 있을 겁니다.

(GUI니까 딱히 필요없긴 하지만 그래도...)

 

 

공유하기

facebook twitter kakaoTalk kakaostory naver band