본문 바로가기

silverlight

ControlTemplate 정의하기

Control의 Style을 바꾸기 위해선 Style을 Resource로 정의하고 공유하면 되지만, Style을 바꾸는 것 이상으로 Control의 모양을 사용자가 원하는 모양으로 바꾸고 싶을 때, ControlTemplate을 사용합니다.

실버라이트의 모든 Control 은 Template속성에 ControlTemplate을 적용할 수 있습니다.

ControlTemplate 정의
Button control을 추가하면,
<Button x:Name="myButton" Content="Unchanged Shape" Width="120" Height="50"/>

그림과 같은 형태의 버튼이 삽입 됩니다.

버튼의 모양을 둥글게 변형하거나, 별모양을 만들고 싶다거나 하는 경우, Button.Template 속성에 ControlTemplate를 정의하면 됩니다.
<Button x:Name="myButton" Content="Changed Shape" Width="120" Height="50">
    <Button.Template>
        <ControlTemplate>
            <Border Height="50" Width="120" BorderThickness="1" BorderBrush="Blue">
            </Border>
        </ControlTemplate>
    </Button.Template>
</Button>

코드에서 Button.Template 속성에 ControlTemplate를 지정하면 Button의 모양이 ControlTemplate 속성에 정의 된 Ellipse 모양으로 변경 된 것을 확인 할 수 있습니다.

Content 표시
그런데, 위 코드와 같이 ControlTemplate을 사용자가 재 정의하게 되는 경우 Button의 Content 속성에 정의 된 "Changed Shape"가 표시 되지 않습니다. 이것은, Content property를 보여주던 기존의 방식이 동작하지 않기 때문입니다.
Content property 를 보여주기 위해서 ContentPresenter와 ItemsPresenter 두 가지 엘리먼트를 제공합니다.
Control의 Content 위치를 지정하기 위해서는 ContentPresenter를 사용하고, ItemsControl에서 Content 위치를 지정하기 위해서는 ItemsPresenter를 사용해야 합니다.
<Border Height="50" Width="120" BorderThickness="1" BorderBrush="Blue">
    <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>


ControlTemplate 에서 Control의 Property 값 Binding
ControlTemplate에서 Border의 Height와 Width property를 직접 할당 하였는데, 이런 경우 Button의 Height나 Width가 변경 시에도 Border의 Height와 Width는 변경 되지 않기 때문에, 버튼이 작아지면 Border가 표시 되는 부분이 잘리거나, 버튼이 작아지면 Border는 버튼의 크기와 상관없이 그대로 존재하게 됩니다.
이런 경우를 고려하여, Button 즉, Control의 Property를 ControlTemplate에서 Binding 한다면 Control의 Property의 변화에 고려된 ControlTemplate를 구성 할 수 있습니다.
Control의 Property를 ControlTemlplate에 Binding 하는 방법은
Height = {TemplateBinding Height}"
TemplateBinding 키워드를 사용하여 Binding 될 Control의 Property를 지정하면 됩니다.
<Button x:Name="myButton" Content="Changed Shape" Width="120" Height="50">
    <Button.Template>
        <ControlTemplate>
            <Border Height="{TemplateBinding Height}" Width="{TemplateBinding Width}"
                    BorderThickness="1" BorderBrush="Blue">
                <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
            </Border>
        </ControlTemplate>
    </Button.Template>
</Button>

Button의 Height를 30 으로 변경시
고정 된 Border의 Width, Height를 사용 한 경우

Control(Button)의 Property를 TemplateBinding 하여 사용 한 경우


ItemsControl의 Item 정렬하기
ItemsControl의 Items 를 정렬하기 위해서는 ItemsPanel property에 ItemsPanelTemplate를 지정하면, ItemsPanelTemplate에 정의 된 Layout Panel 방식으로 Items가 정렬 됩니다. (기본적으로 다른 Layout Panel 들은 Item 배치를 위한 추가적인 코드를 필요로 하기 때문에 StackPanel을 많이 사용합니다.)
<ListBox  Width="100" Height="100">
    <ListBox.Template>
        <ControlTemplate>
            <Border BorderBrush="Blue" BorderThickness="1">
                <ItemsPresenter/>
            </Border>
        </ControlTemplate>
    </ListBox.Template>
   
    <ListBox.Items>
        <ListBoxItem>
            <TextBlock Text="1"/>
        </ListBoxItem>
        <ListBoxItem>
            <TextBlock Text="2"/>
        </ListBoxItem>
        <ListBoxItem>
            <TextBlock Text="3"/>
        </ListBoxItem>
        <ListBoxItem>
            <TextBlock Text="4"/>
        </ListBoxItem>
    </ListBox.Items>
</ListBox>

ListBox의 Template를 재정의 후, <ItemsPresenter/> 를 사용하여 ItemsControl의 Content 위치를 지정.
Item은 Default로 Vertical 정렬 됩니다.

<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"/>
    </ItemsPanelTemplate>
</ListBox.ItemsPanel><SPAN id=tx_marker_caret></SPAN>

ListBox에 ItemsPanel property에 ItemsPanelTemplate를 지정(StackPanel을 Orientation을 Horizontal로)하면, Item이 Horizontal로 정렬 됩니다.

'silverlight' 카테고리의 다른 글

MultiScaleImage의 SubImages 배치변경  (0) 2009.06.23
Make a Deepzoom Solution  (0) 2009.06.22
Behavior 만들기  (0) 2009.06.18
Element to Element Binding  (0) 2009.06.17
Data Binding  (0) 2009.06.17
Resource에서 Style을 범용적으로 사용  (0) 2009.06.16
Style 정의하기  (0) 2009.06.16
VisualStateManager  (0) 2009.06.15
Storyboard (Animation in Silverlight)  (0) 2009.06.15
Layout Panel #5 (WrapPanel)  (0) 2009.06.12