Blog | Tag | Local | Guest | Login | Write |  RSS
Mouse Over Detail View

이번시간에는 XAML만을 사용하여 쇼핑몰 등에서 사용 가능한 Detail View를 구현해보도록 하겠습니다. (이번에도 역시 정확한 이름짖기가 애매해서 -_- Detail View라고 했습니다.) 아래는 시연 동영상 입니다.



제가 좋아하는 만화중에 하나인 드래곤볼입니다ㅎㅎ 기능에 대해서 설명하자면 화면 왼쪽에는 손오공이 오른쪽에는 베지터라는 메뉴가 있습니다. 해당 메뉴에 마우스를 오버 할 경우 해당 메뉴에서 더 보여주고 싶은 자세한 내용을 포함 할 수 있습니다. 소스코드를 본 뒤 더 자세히 이야기를 해보겠습니다.

  1. <WINDOW title="DragonBall - WPFKOREA(http://whatisthat.co.kr)" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="DragonBall.Window1" Width="600" Height="400">  
  2.     <WINDOW.RESOURCES>  
  3.         <IMAGEBRUSH x:Key="Background" ImageSource="Background.jpg" />  
  4.            
  5.         <STYLE TargetType="Button" x:Key="ProfileBox">  
  6.             <Style.Resources>  
  7.                 <Style TargetType="TextBlock">  
  8.                     <Setter Property="Foreground" Value="White"/>  
  9.                     <Setter Property="TextAlignment" Value="Center"/>  
  10.                     <Setter Property="FontSize" Value="11"/>  
  11.                     <Setter Property="FontFamily" Value="Trebuchet MS"/>  
  12.                     <Setter Property="VerticalAlignment" Value="Center"/>  
  13.                     <Setter Property="HorizontalAlignment" Value="Center"/>  
  14.                     <Setter Property="Cursor" Value="Hand"/>  
  15.                 </STYLE>  
  16.             </STYLE.RESOURCES>  
  17.                
  18.             <SETTER Value="Black" Property="Background" />  
  19.             <SETTER Value="55" Property="Width" />  
  20.             <SETTER Value="17.5" Property="Height" />  
  21.   
  22.             <SETTER Property="Template">  
  23.                 <SETTER.VALUE>  
  24.                     <CONTROLTEMPLATE>  
  25.                         <GRID Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Background="{TemplateBinding Background}">  
  26.                             <TEXTBLOCK Text="{TemplateBinding Tag}" />  
  27.                             <CONTENTPRESENTER x:Name="ContentBase" Opacity="0" Content="{TemplateBinding Button.Content}" />  
  28.                         </GRID>  
  29.                         <CONTROLTEMPLATE.TRIGGERS>  
  30.                             <TRIGGER Value="True" Property="Button.IsMouseOver">  
  31.                                 <TRIGGER.ENTERACTIONS>  
  32.                                     <BEGINSTORYBOARD>  
  33.                                         <STORYBOARD Storyboard.TargetName="ContentBase">  
  34.                                             <DOUBLEANIMATION Storyboard.TargetProperty="(Grid.Height)" Duration="0:0:0.5" To="175" />  
  35.                                             <DOUBLEANIMATION Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:0.5" To="142.5" />  
  36.                                             <DOUBLEANIMATION Storyboard.TargetProperty="Opacity" Duration="0:0:0.5" To="1" />  
  37.                                         </STORYBOARD>  
  38.                                     </BEGINSTORYBOARD>  
  39.                                 </TRIGGER.ENTERACTIONS>  
  40.                                 <TRIGGER.EXITACTIONS>  
  41.                                     <BEGINSTORYBOARD>  
  42.                                         <STORYBOARD Storyboard.TargetName="ContentBase">  
  43.                                             <DOUBLEANIMATION Storyboard.TargetProperty="(Grid.Height)" Duration="0:0:0.5" To="17.5" />  
  44.                                             <DOUBLEANIMATION Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:0.5" To="300" />  
  45.                                             <DOUBLEANIMATION Storyboard.TargetProperty="Opacity" Duration="0:0:0.5" To="0" />  
  46.                                         </STORYBOARD>  
  47.                                     </BEGINSTORYBOARD>  
  48.                                 </TRIGGER.EXITACTIONS>  
  49.                             </TRIGGER>  
  50.                         </CONTROLTEMPLATE.TRIGGERS>  
  51.                     </CONTROLTEMPLATE>  
  52.                 </SETTER.VALUE>  
  53.             </SETTER>  
  54.   
  55.                
  56.         </STYLE>  
  57.   
  58.         <STYLE TargetType="Button" x:Key="LeftProfileBox" BasedOn="{StaticResource ProfileBox}">  
  59.                
  60.             <Style.Triggers>  
  61.                 <Trigger Property="IsMouseOver" Value="True">  
  62.                     <Trigger.EnterActions>  
  63.                         <BeginStoryboard>  
  64.                             <Storyboard>  
  65.                                 <DoubleAnimation To="200" Duration="0:0:0.5" BeginTime="0:0:0.5" Storyboard.TargetProperty="(Grid.Width)"/>  
  66.                                 <DoubleAnimation To="30" Duration="0:0:0.5" BeginTime="0:0:0.5" Storyboard.TargetProperty="(Canvas.Left)"/>  
  67.                             </Storyboard>  
  68.                         </BeginStoryboard>  
  69.                     </Trigger.EnterActions>  
  70.                     <Trigger.ExitActions>  
  71.                         <BeginStoryboard>  
  72.                             <Storyboard>  
  73.                                 <DoubleAnimation To="55" Duration="0:0:0.5" BeginTime="0:0:0.5" Storyboard.TargetProperty="(Grid.Width)"/>  
  74.                                 <DoubleAnimation To="175" Duration="0:0:0.5" BeginTime="0:0:0.5" Storyboard.TargetProperty="(Canvas.Left)"/>  
  75.                             </Storyboard>  
  76.                         </BeginStoryboard>  
  77.                     </Trigger.ExitActions>  
  78.                 </Trigger>                   
  79.             </Style.Triggers>  
  80.                
  81.         </STYLE>  
  82.            
  83.         <STYLE TargetType="Button" x:Key="RightProfileBox" BasedOn="{StaticResource ProfileBox}">  
  84.             <Style.Triggers>  
  85.                 <Trigger Property="IsMouseOver" Value="True">  
  86.                     <Trigger.EnterActions>  
  87.                         <BeginStoryboard>  
  88.                             <Storyboard>  
  89.                                 <DoubleAnimation To="200" Duration="0:0:0.5" BeginTime="0:0:0.5" Storyboard.TargetProperty="(Grid.Width)"/>  
  90.                             </Storyboard>  
  91.                         </BeginStoryboard>  
  92.                     </Trigger.EnterActions>  
  93.                     <Trigger.ExitActions>  
  94.                         <BeginStoryboard>  
  95.                             <Storyboard>  
  96.                                 <DoubleAnimation To="55" Duration="0:0:0.5" BeginTime="0:0:0.5" Storyboard.TargetProperty="(Grid.Width)"/>  
  97.                             </Storyboard>  
  98.                         </BeginStoryboard>  
  99.                     </Trigger.ExitActions>  
  100.                 </Trigger>  
  101.             </Style.Triggers>  
  102.         </STYLE>  
  103.            
  104.     </WINDOW.RESOURCES>  
  105.     <GRID>  
  106.         <CANVAS Width="511" Height="328" Background="{StaticResource Background}">  
  107.             <BUTTON style="StaticResource: " Tag="Son Goku" Canvas.Top="300" Canvas.Left="175">  
  108.                 <IMG height=175 width=200 Source="Goku.jpg">  
  109.             </BUTTON>  
  110.             <BUTTON style="StaticResource: " Tag="Vegeta" Canvas.Top="300" Canvas.Left="275">  
  111.                 <IMG height=175 width=200 Source="Vegeta.jpg">  
  112.             </BUTTON>  
  113.         </CANVAS>  
  114.     </GRID>  
  115. </WINDOW>  



코드가 급하게 포스팅한 내용이라 코드가 상당히 지저분 하지만 전반적인 작동원리에 대해서 이해하시는데에는 크게 문제는 없을 것 같습니다. 메뉴는 기본적으로 Button을 사용하기 때문에 Button의 Style을 적용합니다. MouseOver상태에 따라서 보여줄 객체를 정하기 위해서 Trigger에 IsMouseOver Property를 적용했습니다. 두 매뉴가 확장댈때의 위치가 다르기 때문에 Left와 Right를 기존의 Style을 상속받아 확장될때의 크기를 다시 적용했습니다.

  1. <GRID Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Background="{TemplateBinding Background}">  
  2.     <TEXTBLOCK Text="{TemplateBinding Tag}" />  
  3.     <CONTENTPRESENTER x:Name="ContentBase" Opacity="0" Content="{TemplateBinding Button.Content}" />  
  4. </GRID>  



Button Style부분의 코드입니다. 작은 상태에서의 보여줄 텍스트는 Tag를 Template Binding하여 표현하고 확장됬을경우 보여줄 컨텐츠를 보여주기 위해 ContentPresenter를 사용했습니다. ContentPresenter의 경우 기본적으로 Opacity가 0이여서 출력되지 않으며 MouseOver시에 Opacity가 변경됩니다.

  1. <BUTTON style="StaticResource: " Tag="Son Goku" Canvas.Top="300" Canvas.Left="175">  
  2.     <IMG height=175 width=200 Source="Goku.jpg">  
  3. </BUTTON>  
  4. <BUTTON style="StaticResource: " Tag="Vegeta" Canvas.Top="300" Canvas.Left="275">  
  5.     <IMG height=175 width=200 Source="Vegeta.jpg">  
  6. </BUTTON>  



사용할 때는 위와 같이 Tag Property에 버튼의 이름을 정의하고 Content Property에 Detail View에서의 컨텐츠를 추가 하면됩니다. 급하게 포스팅하느라 내용이 약간 어수선 한 부분이 있지만 시간이 되면 다시 정리하도록 하겠습니다. 자세한 내용이나 질문은 댓글이나 메일로 보내주시기 바랍니다.