XAML or HTML

019. 컨트롤템플릿(ControlTemplate) #2

XAML 뽀개기

이번 포스트에서는 템플릿 수정과 다양한 템플릿의 효율적인 사용방법에 대해 알아봅니다.

 

1
2
3
4
5
6
7
<HeaderedContentControl Header="재생" Grid.Column="1"
                        Style="{DynamicResource Style_HeaderedContentControl}">
    <StackPanel>
        <Button Content="시작"/>
        <Button Content="정지"/>
    </StackPanel>
</HeaderedContentControl>
cs


이전 포스트에서 Blend for VS [템플릿 편집 > 복사본 편집기능을 이용해 HeaderedContentControl의 기본 템플릿을 구했습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<Style x:Key="Style_HeaderedContentControl" TargetType="{x:Type HeaderedContentControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type HeaderedContentControl}">
                <Border Background="WhiteSmoke" 
                        BorderBrush="DarkGray" 
                        BorderThickness="1" 
                        Margin="5">
                    <StackPanel Background="WhiteSmoke" 
                                Margin="5">
                        <ContentPresenter ContentSource="Header" 
                                          TextBlock.FontWeight="Bold" 
                                          Margin="0,0,0,5"/>
                        <ContentPresenter />
                    </StackPanel>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
cs

 

이전 포스트에서 작성했던 스타일링 작업의 XAML 코드를 참고해 템플릿을 수정했습니다. HeaderedContentControl의 구조와 외형을 변경하는 작업입니다.

 

1
2
3
4
5
6
7
<HeaderedContentControl Header="재생"
                        Style="{DynamicResource Style_HeaderedContentControl}">
    <StackPanel>
        <Button Content="시작"/>
        <Button Content="정지"/>
    </StackPanel>
</HeaderedContentControl>
cs

           

HeaderedContentControl에 스타일을 각각 선언 수도 있지만 StackPanel 아래에 리소스로 스타일을 정의하면서 Key 이름을 생략하고 BasedOn 속성을 이용해 일괄적으로 하위 컨트롤에 영향을 미칠  있습니다

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<StackPanel Grid.Column="1">
    <StackPanel.Resources>
        <Style TargetType="HeaderedContentControl"
               BasedOn="{StaticResource Style_HeaderedContentControl}"/>
    </StackPanel.Resources>
            
    <HeaderedContentControl Header="재생">
        <StackPanel>
            <Button Content="시작"/>
            <Button Content="정지"/>
        </StackPanel>
    </HeaderedContentControl>
    <HeaderedContentControl Header="트랙">
        <StackPanel>
            <Button Content="이전"/>
            <Button Content="다음"/>
        </StackPanel>
    </HeaderedContentControl>
    <HeaderedContentControl Header="소리">
        <StackPanel>
            <Button Content="작게"/>
            <Button Content="크게"/>
        </StackPanel>
    </HeaderedContentControl>
</StackPanel>
cs



  절약하고 깔끔한 코드를 얻게 되었습니다. 이전 포스트에서도 다룬 적이 있으니 참고하세요.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<StackPanel.Resources>
    <ControlTemplate x:Key="Template_HeaderedContentControl" 
                     TargetType="{x:Type HeaderedContentControl}">
        <Border Background="WhiteSmoke" 
                BorderBrush="DarkGray" 
                BorderThickness="1" 
                Margin="5">
            <StackPanel Background="WhiteSmoke" 
                        Margin="5">
                <ContentPresenter ContentSource="Header" 
                                  TextBlock.FontWeight="Bold" 
                                  Margin="0,0,0,5"/>
                <ContentPresenter />
            </StackPanel>
        </Border>
    </ControlTemplate>
</StackPanel.Resources>
cs


1
2
3
4
5
6
7
<HeaderedContentControl Header="재생"
                        Template="{DynamicResource Template_HeaderedContentControl}">
    <StackPanel>
        <Button Content="시작"/>
        <Button Content="정지"/>
    </StackPanel>
</HeaderedContentControl>
cs


 

스타일이 아니더라도 템플릿을 변경할 있습니다. 말인 즉슨 스타일의 ControlTemplate을 단독으로도 사용할 있다는 것입니다. 리소스로 정의해 사용하는 방법 동일하기 때문에 Key 이름 선언이 필수입니다.

 

1
2
3
4
5
6
7
<!--HeaderedContentControl의 Content 템플릿-->
<DataTemplate x:Key="DataTemplate_Content">
    <StackPanel Orientation="Horizontal">
        <Button Content="이전" Width="50" Margin="0,0,5,0"/>
        <Button Content="다음" Width="50"/>
    </StackPanel>
</DataTemplate>
cs

 

1
2
3
4
5
6
7
8
<HeaderedContentControl Header="트랙"
                        Template="{DynamicResource Template_HeaderedContentControl}"
                        ContentTemplate="{DynamicResource DataTemplate_Content}">
    <!--<StackPanel>
        <Button Content="이전"/>    
        <Button Content="다음"/>        
    </StackPanel>-->
</HeaderedContentControl>
cs

 

 

Content만의 템플릿을 새로이 정의할 수도 있습니다. 이 템플릿은 DataTemplate이라고 합니다. DataTemplate은 이전 ControlTemplate의 하위 템플릿이라고 할  있습니다. DataTemplate 다른 포스트에서 다시 살펴보겠습니다.

 

1
2
3
4
5
6
7
<!--HeaderedContentControl의 Header 템플릿-->
<DataTemplate x:Key="DataTemplate_Header">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="※" Margin="0,0,5,0" Foreground="Red"/>
        <TextBlock Text="{Binding }" Foreground="Red"/>
    </StackPanel>
</DataTemplate>
cs

 

1
2
3
4
5
6
7
8
<HeaderedContentControl Header="소리" 
                        Template="{DynamicResource Template_HeaderedContentControl}"
                        HeaderTemplate="{DynamicResource DataTemplate_Header}">
    <StackPanel>
        <Button Content="작게"/>
        <Button Content="크게"/>
    </StackPanel>
</HeaderedContentControl>
cs

 

 

앞서 본 Content의 템플릿과 동일한 방법으로 Header만의 템플릿을 새로이 정의할 수도 있습니다.

 

Template, ContentTemplate, HeaderTemplate 모두 템플릿이라 있습니다. Template 기본 골격(외형)이라면 ContentTemplate, HeaderTemplate 아래 골격(외형)이라 있겠습니다. ContentPresenter의 Content 속성이 암시적 바인딩이 작용한 것과 같이 템플릿 속성도 암시적으로 바인딩됩니다.

 

지금까지 예로  템플릿 사용 방법들은 기본 골격은 같은데 특정 일부만 변경을 필요로 할  하위 템플릿을 새로이 정의해서 리소스(템플릿) 효율적으로 사용 가능케 합니다.


관련 목차


018. 컨트롤템플릿(ControlTemplate) #1

019. 컨트롤템플릿(ControlTemplate) #2