본문 바로가기

XAML 뽀개기

015. 두개의 콘텐츠 버튼(Two Contents Button) #1


위와 같이 2개의 Content가 사용되는 버튼 컨트롤은 실제 프로젝트에서 흔히 사용됩니다. 기본으로 제공되는 버튼 컨트롤은 Content 속성이 하나 밖에 제공되지 않지만 Object 타입이기 때문에 아래와 같은 방법으로 흔히 표현할 수 있습니다.


1
2
3
4
5
6
7
8
<Button>
    <Button.Content>
        <StackPanel Margin="5">
            <TextBlock Text="Menu01" FontWeight="Bold"/>
            <TextBlock Text="Lorem Ipsum is simply" TextWrapping="Wrap"/>
        </StackPanel>
    </Button.Content>
</Button>
cs


1
2
3
4
5
6
<Button>
    <StackPanel Margin="5">
        <TextBlock Text="Menu01" FontWeight="Bold"/>
        <TextBlock Text="Lorem Ipsum is simply" TextWrapping="Wrap"/>
    </StackPanel>
</Button>
cs


가장 간단한 방법은 위와 같지 않을까 생각됩니다. 하지만 버튼 컨트롤 자체의 Style과 Template에 영향을 받을 수 없는 한계가 있습니다. 물론 TextBlock 자체에 Style를 입힐 수는 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<Button Content="Menu01">
    <Button.Template>
        <ControlTemplate TargetType="Button">
            <Border BorderBrush="{TemplateBinding BorderBrush}" 
                    BorderThickness="{TemplateBinding BorderThickness}" 
                    Background="{TemplateBinding Background}" 
                    SnapsToDevicePixels="True">
                <ContentPresenter x:Name="contentPresenter" 
                    ContentTemplate="{TemplateBinding ContentTemplate}" 
                    Content="{TemplateBinding Content}" 
                    ContentStringFormat="{TemplateBinding ContentStringFormat}" 
                    Focusable="False" 
                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                    Margin="{TemplateBinding Padding}" 
                    RecognizesAccessKey="True" 
                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
            </Border>
        </ControlTemplate>
    </Button.Template>
</Button>
cs


기본으로 제공되는 버튼의 템플릿은 위와 같습니다. 약간 복잡해 보입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Button Content="Menu02" Grid.Column="1">
    <Button.Template>
        <ControlTemplate TargetType="Button">
            <Border BorderBrush="{TemplateBinding BorderBrush}" 
                    BorderThickness="{TemplateBinding BorderThickness}" 
                    Background="{TemplateBinding Background}">
                <StackPanel HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                            Margin="5">
                    <ContentPresenter Content="{TemplateBinding Content}"/>
                </StackPanel>
            </Border>
        </ControlTemplate>
    </Button.Template>
</Button>
cs


이번 포스트 주제에만 집중할 수 있도록 예제 코드를 간략히 수정했습니다. 2개의 콘텐츠를 세로로 정렬하기 위해 StackPanel로 ContentPresenter를 감싸주었습니다.


Content="{TemplateBinding Content}" 코드도 생략할 수있습니다. ContentPresenter의 Content는 암시적으로 바인딩되기 때문에 가능합니다. 이 예제에서는 일부러 생락하지 않습니다. ContentTemplate과 ContentPresenter는 다른 포스트에서 다룰 예정입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<Button Content="Menu02" Tag="Lorem Ipsum is simply" Grid.Column="1">
    <Button.Template>
        <ControlTemplate TargetType="Button">
            <Border BorderBrush="{TemplateBinding BorderBrush}" 
                    BorderThickness="{TemplateBinding BorderThickness}" 
                    Background="{TemplateBinding Background}">
                <StackPanel HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                            Margin="5">
                    <ContentPresenter Content="{TemplateBinding Content}"/>
                    <TextBlock Text="{TemplateBinding Tag}" TextWrapping="Wrap"/>
                </StackPanel>
            </Border>
        </ControlTemplate>
    </Button.Template>
</Button>
cs


위 코드는 FrameworkElement를 상속 받은 모든 컨트롤들이 공통적으로 가지고 있는 Tag 속성을 이용하는 예제 코드입니다. 두번째 Content를 추가하기 위해 ContentPresenter를 하나 더 추가해도 되지만 TextWrapping 속성을 이용해 줄내림 효과를 바로 얻기 위해 TextBlock 컨트롤을 추가했습니다. 그런 후 Tag 속성과 TextBlock 컨트롤의 Text 속성을 TemplateBinding 문법을 이용해 결합했습니다.



이런 간단한 방법으로도 2개의 컨텐츠를 표현할 수 있습니다. 하지만 Tag 속성은 의미적(Semantic)으로 적합하지 않고 일부 개발하는 과정에서 다른 용도로 사용될 수 있는 가능성이 있으므로 이렇게 사용하는 것은 프로토타입니나 샘플 코드에서나 적합할 것입니다.


샘플 코드 : https://github.com/CharlesKwon/XamlSimplified


관련 목차


015. 두개의 컨텐츠 버튼(Two contents button) #1

016. 두개의 컨텐츠 버튼(Two contents button) #2

017. 두개의 컨텐츠 버튼(Two contents button) #3