'ItemTemplate'에 해당되는 글 1건
- 2008.12.10 [강좌] 1. Listbox의 기본적인 사용.(2) Item Look 변경.
Item 의 스타일을 변경해주는 방법은 2가지가 있습니다.
바로 ItemContainerStyle 을 바꾸어 주는 방법과 ItemTemplate을 바꾸는 방법이지요.
ItemTemplate 을 바꾸는 방법은 스캇 구슬리 강좌 에 소개 되어있는데요. 기본적으로 Container 안에 내용물을 바꾸는 것으로 볼 수 있죠.
그럼 ItemContainerStyle부터 살펴 봅시다. ItemContainderStyle은 Style을 Value 값으로 받습니다. 아시는 분은 알겠지만 Style은 TargetType 이 필요하죠. 여기서 TargetType은 ListBoxItem 입니다. 결국 ItemContainerStyle은 ListBoxItem의 스타일을 정해주는 프로퍼티라는 것이지요.
그럼 ListBoxItem의 DefaultStyle을 볼까요?
너무 길죠?^^ 제가 알기 쉽게 Template부분만 간단히 정리해보죠.
간단하죠?^^ 간단히 말하면 ListBoxItem은 하나의 ContentPresenter를 가지고 있는
ContentControl 이죠. VisualStateManager는 Item 상태를 결정 해주는 것이고요.
사실 ContentPresenter이 없어도 됩니다. 다만 ItemTemplate이 무용지물이 되어버리죠.구지 ItemsTemplate을 쓰지 않고 Container로 모두 끝내도 된다면 상관없겠죠.
그리고 특히 Select나 MouseOver에 대해 특별한 애니메이션이 필요하다면 꼭 ItemContainerStyle을 다시 설정해주어야 하겠죠. 또 ItemTemplate은 위의 ListBoxItem Style 중에 <ContentPresenter /> 부분을 대체하는 부분이기 때문에 ListBoxItem의 전체적인 디자인을 바꾸지는 못하겠죠.
결국 간단히
ItemContainerStyle은 ListBoxItem의 Style을 바꾸는 것이고
ItemTemplate은 ListBoxItem의 ContentPresenter 부분을 바꾸는 것입니다.
(이렇게 간단한 걸.. 이렇게.. 길게 어렵게 설명한 것인가....--;;;)
아직 이해를 못하신 분들을 위해 두가지 예제를 보여드리죠.
다음의 경우를 살펴봅시다.
이 후 비하인드 코드에서 다음과 같이 셋팅해줍시다.
결과는 다음과 같죠.
ListBoxItem 안에들어가는 내용물 디자인이 바뀌긴 했지만 MouseOver나 Select시 State 변화는 똑같은 걸 알 수 있죠.
ItemsContainerStyle 을 바꾸어야 하는데 이것은 조금더 복잡하기 때문에 Blend를 사용하는 것이 좋을 것같습니다. Blend에서 ListBox를 선택한 후 ItemsContainerStyle을 바꿀려고 보니 아래 그림과 같이 메뉴가 없는 걸 알 수 있습니다.
ItemTemplate과 다음장에 배울 ItemsPanel은 수정할 수 있는데 ItemsContainerStyle은 찾아볼 수가 없죠. 오른쪽 프로퍼티 창에는 존재하지만 GUI로 작업할 방법이 없는 듯 싶은데요..그래서 여기선 한가지 우회 방법을 써야만 합니다.
바로 ListBoxItem을 하나 만들어서 그 Style을 만들고 ItemsContainerStyle에 적용하는 것입니다.
왼쪽 Control 메뉴를 클릭하면 선택할 수 있는 모든 컨트롤이 나옵니다.(아니 "Show All" 이 Check 되어있을 경우만요..)
ListBoxItem을 클릭한 후에 ListBoxItem을 적당한 크기로 생성을 합니다. 그리고 ListBoxItem 의 Style을 조정해 주면 됩니다.
Style을 변경하는 방법은 다른 강좌에서 설명하기로 하고 여기서는 간단히 제가 임의로 수정하도록 하겠습니다.
Style을 다 만들고 나면 오른쪽 Resource Tab메뉴에 다음과 같이 Style이 생겨 있음을 볼 수 있습니다.
그러면 이 등록된 Style을 ListBox의 ItemsContainerStyle에 적용하기만 하면 됩니다. 적용방법은 간단하죠. ListBox선택후 오른쪽 속성창에서 다음 그림에서 보이는 것처럼 설정해주시면 됩니다.
이제 적용된 결과를 테스트 해보시면 ListBox의 Item들이 전혀 다르게 Style이 적용된다는 것을 알 수 있을 겁니다.
그럼 다음에는 ItemsPanel 에 대해 설명하죠. 다음 장에는 좀더 자세히 설명을 해야겠다는 반성을.....--;;
- smile -
바로 ItemContainerStyle 을 바꾸어 주는 방법과 ItemTemplate을 바꾸는 방법이지요.
ItemTemplate 을 바꾸는 방법은 스캇 구슬리 강좌 에 소개 되어있는데요. 기본적으로 Container 안에 내용물을 바꾸는 것으로 볼 수 있죠.
그럼 ItemContainerStyle부터 살펴 봅시다. ItemContainderStyle은 Style을 Value 값으로 받습니다. 아시는 분은 알겠지만 Style은 TargetType 이 필요하죠. 여기서 TargetType은 ListBoxItem 입니다. 결국 ItemContainerStyle은 ListBoxItem의 스타일을 정해주는 프로퍼티라는 것이지요.
그럼 ListBoxItem의 DefaultStyle을 볼까요?
<Style TargetType="ListBoxItem" >
<Setter Property="Padding" Value="3" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="TabNavigation" Value="Local" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem" xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows">
<Grid Background="{TemplateBinding Background}">
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="CommonStates" >
<vsm:VisualState x:Name="Normal" />
<vsm:VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="fillColor" Storyboard.TargetProperty="Opacity" Duration="0" To=".35" />
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Opacity" Duration="0" To=".55" />
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
<vsm:VisualStateGroup x:Name="SelectionStates" >
<vsm:VisualState x:Name="Unselected" />
<vsm:VisualState x:Name="Selected">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="fillColor2" Storyboard.TargetProperty="Opacity" Duration="0" To=".75" />
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
<vsm:VisualStateGroup x:Name="FocusStates" >
<vsm:VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Visibility" Duration="0">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="Unfocused" />
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<Rectangle x:Name="fillColor" Opacity="0" Fill="#FFBADDE9" IsHitTestVisible="False" RadiusX="1" RadiusY="1" />
<Rectangle x:Name="fillColor2" Opacity="0" Fill="#FFBADDE9" IsHitTestVisible="False" RadiusX="1" RadiusY="1" />
<ContentPresenter x:Name="contentPresenter" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" />
<Rectangle x:Name="FocusVisualElement" Stroke="#FF6DBDD1" StrokeThickness="1" Visibility="Collapsed" RadiusX="1" RadiusY="1" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Setter Property="Padding" Value="3" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="TabNavigation" Value="Local" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem" xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows">
<Grid Background="{TemplateBinding Background}">
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="CommonStates" >
<vsm:VisualState x:Name="Normal" />
<vsm:VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="fillColor" Storyboard.TargetProperty="Opacity" Duration="0" To=".35" />
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Opacity" Duration="0" To=".55" />
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
<vsm:VisualStateGroup x:Name="SelectionStates" >
<vsm:VisualState x:Name="Unselected" />
<vsm:VisualState x:Name="Selected">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="fillColor2" Storyboard.TargetProperty="Opacity" Duration="0" To=".75" />
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
<vsm:VisualStateGroup x:Name="FocusStates" >
<vsm:VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Visibility" Duration="0">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="Unfocused" />
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<Rectangle x:Name="fillColor" Opacity="0" Fill="#FFBADDE9" IsHitTestVisible="False" RadiusX="1" RadiusY="1" />
<Rectangle x:Name="fillColor2" Opacity="0" Fill="#FFBADDE9" IsHitTestVisible="False" RadiusX="1" RadiusY="1" />
<ContentPresenter x:Name="contentPresenter" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" />
<Rectangle x:Name="FocusVisualElement" Stroke="#FF6DBDD1" StrokeThickness="1" Visibility="Collapsed" RadiusX="1" RadiusY="1" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
너무 길죠?^^ 제가 알기 쉽게 Template부분만 간단히 정리해보죠.
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<vsm:VisualStateManager.VisualStateGroups/>
<ContentPresenter />
</Grid>
</ControlTemplate>
<Grid>
<vsm:VisualStateManager.VisualStateGroups/>
<ContentPresenter />
</Grid>
</ControlTemplate>
간단하죠?^^ 간단히 말하면 ListBoxItem은 하나의 ContentPresenter를 가지고 있는
ContentControl 이죠. VisualStateManager는 Item 상태를 결정 해주는 것이고요.
사실 ContentPresenter이 없어도 됩니다. 다만 ItemTemplate이 무용지물이 되어버리죠.구지 ItemsTemplate을 쓰지 않고 Container로 모두 끝내도 된다면 상관없겠죠.
그리고 특히 Select나 MouseOver에 대해 특별한 애니메이션이 필요하다면 꼭 ItemContainerStyle을 다시 설정해주어야 하겠죠. 또 ItemTemplate은 위의 ListBoxItem Style 중에 <ContentPresenter /> 부분을 대체하는 부분이기 때문에 ListBoxItem의 전체적인 디자인을 바꾸지는 못하겠죠.
결국 간단히
ItemContainerStyle은 ListBoxItem의 Style을 바꾸는 것이고
ItemTemplate은 ListBoxItem의 ContentPresenter 부분을 바꾸는 것입니다.
(이렇게 간단한 걸.. 이렇게.. 길게 어렵게 설명한 것인가....--;;;)
아직 이해를 못하신 분들을 위해 두가지 예제를 보여드리죠.
다음의 경우를 살펴봅시다.
<ListBox Width="60" x:Name="ItemTemplateSettingListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse Width="5" Height="5" Margin="5" Fill="Black"/>
<TextBlock Text="{Binding }"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse Width="5" Height="5" Margin="5" Fill="Black"/>
<TextBlock Text="{Binding }"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
이 후 비하인드 코드에서 다음과 같이 셋팅해줍시다.
ItemTemplateSettingListBox.ItemsSource = new List<string>() { "하나", "둘", "셋", "넷" };
결과는 다음과 같죠.
ItemsContainerStyle 을 바꾸어야 하는데 이것은 조금더 복잡하기 때문에 Blend를 사용하는 것이 좋을 것같습니다. Blend에서 ListBox를 선택한 후 ItemsContainerStyle을 바꿀려고 보니 아래 그림과 같이 메뉴가 없는 걸 알 수 있습니다.
ItemTemplate과 다음장에 배울 ItemsPanel은 수정할 수 있는데 ItemsContainerStyle은 찾아볼 수가 없죠. 오른쪽 프로퍼티 창에는 존재하지만 GUI로 작업할 방법이 없는 듯 싶은데요..그래서 여기선 한가지 우회 방법을 써야만 합니다.
바로 ListBoxItem을 하나 만들어서 그 Style을 만들고 ItemsContainerStyle에 적용하는 것입니다.
왼쪽 Control 메뉴를 클릭하면 선택할 수 있는 모든 컨트롤이 나옵니다.(아니 "Show All" 이 Check 되어있을 경우만요..)
ListBoxItem을 클릭한 후에 ListBoxItem을 적당한 크기로 생성을 합니다. 그리고 ListBoxItem 의 Style을 조정해 주면 됩니다.
Style을 변경하는 방법은 다른 강좌에서 설명하기로 하고 여기서는 간단히 제가 임의로 수정하도록 하겠습니다.
Style을 다 만들고 나면 오른쪽 Resource Tab메뉴에 다음과 같이 Style이 생겨 있음을 볼 수 있습니다.
그럼 다음에는 ItemsPanel 에 대해 설명하죠. 다음 장에는 좀더 자세히 설명을 해야겠다는 반성을.....--;;
- smile -
p.s. 역시 샘플 프로젝트를 첨부합니다.