본문 바로가기

프로그래밍언어/WPF

WPF 컨트롤 템플릿



컨트롤 클래스는 자신의 외관을 변경할 수 있도록 많은 프로퍼티를 가지고 있다. 예를들면 버튼은 백그라운드나 포어그라운드 프로퍼티를 이용해서 색상을 변경 가능하다.

반면에, 템플릿은 원하는 것들을 거의 다 반영해서 비주얼 트리를 완벽하게 변경할 수 있도록 허용해 준다. 물론 템플릿을 사용해도 기능상의 변화는 아무것도 없다.

WPF는 템플릿을 사용하여 디자인과 로직을 분리하기 때문에 코딩으로 외관을 설정하기 위한 별도의 프로퍼티들을 많이 노출하지 않는다.

컨트롤 템플릿(ControlTemplate) 클래스의 중요한 부분은 VisualTree 컨텐트 프로퍼티이다. 이 프로퍼티는 원하는 외관을 정의한 엘리먼트의 구조를 포함한다.

<Grid>
<Grid.Resources>
<ControlTemplate x:Key="buttonTemplate">
<Grid>
<Ellipse Width="100" Height="100">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="Blue" />
<GradientStop Offset="1" Color="Red" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse Width="80" Height="80">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="White" />
<GradientStop Offset="1" Color="Transparent" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
</ControlTemplate>
</Grid.Resources>
<Button Template="{StaticResource buttonTemplate}">OK</Button>
</Grid>


템플릿의 비주얼 트리는 하나의 셀을 가진 그리드 네부에 Ellipse 엘리먼트를 이용한 두 개의 원을 사용했다. 외관은 수정했지만, 결과물은 click 이벤트와 IsDefault 프로퍼티뿐만 아니라 예전에 일반 버튼에서 사용하던 모든 기능을 이용 가능 하다.
결과적으로, 모양만 다를 뿐 버튼의 인스턴스이다

트리거를 이용한 상호작용

스타일을 사용할 때, 템플릿은 Triggers 컬렉션에 있는 모든 타입의 트리거들을 포함한다
<Grid>
<Grid.Resources>
<ControlTemplate x:Key="buttonTemplate">
<Grid>
<Ellipse x:Name="outerCircle" Width="100" Height="100" >
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="Blue" />
<GradientStop Offset="1" Color="Red" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse Width="80" Height="80">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="White" />
<GradientStop Offset="1" Color="Transparent" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX=".9" ScaleY=".9" />
</Setter.Value>
</Setter>
<Setter Property="RenderTransformOrigin" Value=".5,.5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Grid.Resources>
<Button Template="{StaticResource buttonTemplate}">Ok</Button>
</Grid>


트리거를 가지고 템플릿의 하위 엘리먼트를 조절하는 기능은 복잡한 템플릿에서는 필수적이다

템플릿에 사용된 부모 컨트롤의 프로퍼티 사용하기

컨트롤 템플릿의 재사용성을 높이기 위해서라도, 적용하고자 하는 상위 컨트롤의 프로퍼티를 적절히 이용하는 작업을 추가적으로 해야한다

컨텐트 컨트롤의 컨텐트 프로퍼티 사용하기

컨트롤 템플릿 내부에서 대상 엘리먼트의 프로퍼티 값을 넣어 주는 역할을 하는 것은 데이터 바인딩이다

<Grid>
<Grid.Resources>
<ControlTemplate x:Key="buttonTemplate" TargetType="{x:Type Button}">
<Grid>
<Ellipse x:Name="outerCircle" Width="100" Height="100" >
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="Blue" />
<GradientStop Offset="1" Color="Red" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse Width="80" Height="80">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="White" />
<GradientStop Offset="1" Color="Transparent" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Viewbox>
<ContentControl Margin="20" Content="{TemplateBinding Content}" />
</Viewbox>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="outerCircle" Property="Fill" Value="Orange" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX=".9" ScaleY=".9" />
</Setter.Value>
</Setter>
<Setter Property="RenderTransformOrigin" Value=".5,.5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Grid.Resources>
<Button Template="{StaticResource buttonTemplate}">Ok</Button>
</Grid>


'프로그래밍언어 > WPF' 카테고리의 다른 글

WPF 동영상 재생  (0) 2011.07.12
컨트롤에 대해서[WPF 컨트롤]  (0) 2011.07.11
WPF 데이터 바인딩  (0) 2011.07.04
WPF 레이아웃  (0) 2011.06.29
WPF(기본적인 개념,아키텍쳐)[XAML이란 무었인가  (0) 2011.06.29