'style'에 해당되는 글 3건

  1. 2009.06.16 ControlTemplate 정의하기
  2. 2009.06.16 Resource에서 Style을 범용적으로 사용
  3. 2009.06.16 Style 정의하기
Silverlight2009.06.16 17:14
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
ControlTemplate 정의하기  (0) 2009.06.16
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
Posted by Min-gu, Kim
Silverlight2009.06.16 15:58

Element 의 Style을 지정하는 방법을 알아 봤지만, 모든 Element에 Style을 지정 해 Element의 형태를 지정하는 것은 비효율적이며 손이 많이 가는게 사실입니다. 또한, 유지보수 차원에서도 여간 쉬운 일이 아닙니다. (일례로, Page내 TextBox 스타일이 일률적으로 변경 된다거 등의 작업을 처리하기 위해서는 Page내 TextBox의 Style을 수정해야 하기 때문이죠)

예를 들어, 다음과 같은 사용자 로그인 페이지를 구현한다고 하면,



<Grid x:Name="LayoutRoot" Background="White" ShowGridLines="True">
<Grid.RowDefinitions>
    <RowDefinition Height="50"/>
    <RowDefinition Height="50"/>
    <RowDefinition Height="50"/>
    <RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
    <ColumnDefinition Width="150"/>
    <ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="Login ID : " Grid.Column="0" Grid.Row="0"
           FontFamily="Comic Sans MS"
           FontSize="15"
           Foreground="Blue"
           HorizontalAlignment="Right"/>
<TextBox x:Name="TextBoxLogin" Grid.Column="1" Grid.Row="0"
         HorizontalAlignment="Left"
         VerticalAlignment="Top"
         FontFamily="Verdana"
         FontSize="12"
         Foreground="Black"
         Width="200" Height="30"/>
<TextBlock Text="E-Mail Address: " Grid.Column="0" Grid.Row="1"
           FontFamily="Comic Sans MS"
           FontSize="15"
           Foreground="Blue"
           HorizontalAlignment="Right"/>
<TextBox x:Name="TextBoxEMail" Grid.Column="1" Grid.Row="1"
         HorizontalAlignment="Left"
         VerticalAlignment="Top"
         FontFamily="Verdana"
         FontSize="12"
         Foreground="Black"
         Width="200" Height="30"/>
<TextBlock Text="Phone Number : " Grid.Column="0" Grid.Row="2"
           FontFamily="Comic Sans MS"
           FontSize="15"
           Foreground="Blue"
           HorizontalAlignment="Right"/>
<TextBox x:Name="TextBoxPhoneNum" Grid.Column="1" Grid.Row="2"
         HorizontalAlignment="Left"
         VerticalAlignment="Top"
         FontFamily="Verdana"
         FontSize="12"
         Foreground="Black"
         Width="200" Height="30"/>
<TextBlock Text="Memo : " Grid.Column="0" Grid.Row="3"
           FontFamily="Comic Sans MS"
           FontSize="15"
           Foreground="Blue"
           HorizontalAlignment="Right"/>
<TextBox x:Name="TextBoxMemo" Grid.Column="1" Grid.Row="3"
         HorizontalAlignment="Left"
         VerticalAlignment="Top"
         FontFamily="Verdana"
         FontSize="12"
         Foreground="Black"
         TextWrapping="Wrap" Width="200" Height="150"/>
</Grid>

위 코드에서 처럼, Login ID, E-Mail Address, Phone Number, Memo TextBlock이 Style이 모두 같기 때문에 4개의 TextBlock 모두 같은 코드를 반복해서 타이핑 할 수 밖에 없습니다. 마찬가지로, TextBox 입력 부분도, HorizontalAlignment, VerticalAlignment, FontSize, FontFamily등이 중복되서 타이핑 되 있죠.

만약 이 상황에서, 모든 TextBlock의 FontFamily를 바꿔야 한다거나, FontSize를 바꿔야 한다고 하면, 일일이 모든 TextBlock의 FontFamily와 FontSize property를 찾아서 Value 값을 변경 해 줘야 합니다. (혹은 Ctrl+C, Ctrl+V)
정말 비효율적이고 생산성이 떨어지겠죠.

그래서, Silverlight 에서는 Style을 Resource에 선언한 뒤에 선언 된 Style 을 필요로 하는 Element에서 공유 할 수 있도록 지원합니다. Resource에 선언 한 뒤 Style을 Element에서 사용하기 위해서는
Style="{StaticResource 스타일객체키}"
위와 같이 Resource에서 지정 된 Style의 Key(String)를 지정하면 됩니다.

처음 로그인 페이지를 Resource에서 추가 된 Style을 사용하여 구현한다면,
<Grid.Resources>
    <Style x:Key="TextBlockTitle" TargetType="TextBlock">
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="15"/>
        <Setter Property="Foreground" Value="Blue"/>
        <Setter Property="HorizontalAlignment" Value="Right"/>
    </Style>
    <Style x:Key="TextBoxContent" TargetType="TextBox">
        <Setter Property="FontFamily" Value="Verdana"/>
        <Setter Property="FontSize" Value="12"/>
        <Setter Property="Foreground" Value="Black"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Top"/>
        <Setter Property="Width" Value="200"/>
        <Setter Property="Height" Value="30"/>
    </Style>
</Grid.Resources>
<Grid.RowDefinitions> ...
</Grid.RowDefinitions>
<Grid.ColumnDefinitions> ...
</Grid.ColumnDefinitions>
<TextBlock Text="Login ID : " Grid.Column="0" Grid.Row="0"
           Style="{StaticResource TextBlockTitle}"/>
<TextBox x:Name="TextBoxLogin" Grid.Column="1" Grid.Row="0"
         Style="{StaticResource TextBoxContent}"/>
<TextBlock Text="E-Mail Address: " Grid.Column="0" Grid.Row="1"
           Style="{StaticResource TextBlockTitle}"/>
<TextBox x:Name="TextBoxEMail" Grid.Column="1" Grid.Row="1"
         Style="{StaticResource TextBoxContent}"/>
<TextBlock Text="Phone Number : " Grid.Column="0" Grid.Row="2"
           Style="{StaticResource TextBlockTitle}"/>
<TextBox x:Name="TextBoxPhoneNum" Grid.Column="1" Grid.Row="2"
         Style="{StaticResource TextBoxContent}"/>
<TextBlock Text="Memo : " Grid.Column="0" Grid.Row="3"
           Style="{StaticResource TextBlockTitle}"/>
<TextBox x:Name="TextBoxMemo" Grid.Column="1" Grid.Row="3"
         Style="{StaticResource TextBoxContent}"/>

중복 되는 Style을 Resouce에서 지정 하고, Style을 공유 할 Element에서 Style Resouce를 Binding 해서 쓰면 됩니다. 그런데, 위 코드를 실행하게 되면

Memo 의 입력 부분이, 다른 입력 부분과 동일한 Style이 적용 되 있는 것을 확인 할 수 있습니다.

이 땐, Memo의 입력 부분인 TextBox에서 Height라던가, TextWrapping 속성을 추가로 지정 해 주면 됩니다.
<TextBox x:Name="TextBoxMemo" Grid.Column="1" Grid.Row="3"
         TextWrapping="Wrap"
         Height="150"
         Style="{StaticResource TextBoxContent}"/>


UIElement의 Style을 지정하고, 디자인(XAML)에서 속성 값을 할당 하면, 중복되는 경우, 항상 디자인(XAML)에서 할당 된 속성값을 갖게 됩니다.

'Silverlight' 카테고리의 다른 글

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
ControlTemplate 정의하기  (0) 2009.06.16
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
Layout Panel #4 (DockPanel)  (0) 2009.06.12
Posted by Min-gu, Kim
Silverlight2009.06.16 14:10

UIElement 의 Style 정의
UIElement의 모양을 변경하기 위해 Style Class를 정의하여 UIElement의 Style속성에 설정합니다.
(FrameworkElement 를 상속 받은 모든 Element는 Style 속성을 가지고 있기 때문)

Style Class는 SetterBaseCollection 형의 Setter property를 가지고 있습니다.
SetterBaseCollection내 각각의 Setter class 는 Style의 속성에 값을 부여하는 Class로, 적용 될 Property를 지정하는 Property property와 지정된 property의 값을 설정하는 Value property가 있습니다.
Style Class 는 Property와 Value가 지정 된 Setter class를 배열로 가지고 있고, Style Class 의 TargetType property로 Style을 적용할 Element의 형식을 설정하여 각 Setter가 지정하고 있는 Element의 Property 에 Value 값을 설정 합니다.
- Rectangle 객체의 Style을 지정-

<Rectangle x:Name="myRectangle">
    <Rectangle.Style>
        <Style TargetType="Rectangle" x:Name="myStyle">
            <Setter Property="Width" Value="50"/>
            <Setter Property="Height" Value="50"/>
            <Setter Property="Fill">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="Blue" Offset="1"/>
                        <GradientStop Color="Red" Offset="0"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
        </Style>
    </Rectangle.Style>
</Rectangle>


Style객체를 생성해서 Rectangle 의 Style Property에 설정합니다.
(Rectangle 은 FrameworkElement를 상속 받아 Style property를 가지고 있어, Style 객체를 생성해서 설정할 수 있습니다.)
생성 된 Style 객체는 TargetType 으로 Rectangle 이 지정 되 있고 Style 객체 내 Setter에서는 Width 속성의 값을 50으로, Height 값을 50으로, Fill 값을 Setter.Value를 지정하여 여러 가지 속성을 가진 LinearGradientBrush를 값으로 사용하였습니다.



위 코드에서 처럼 Style 객체 내 Setter class 는 Value 값을 Int32나 String처럼 기본 자료형인 Property에 지정 할 수도 있지만, Rectangle 내 Fill property 에 여러 속성을 가지는 LinearGradientBrush를 값으로 지정 할 수도 있습니다.

'Silverlight' 카테고리의 다른 글

Behavior 만들기  (0) 2009.06.18
Element to Element Binding  (0) 2009.06.17
Data Binding  (0) 2009.06.17
ControlTemplate 정의하기  (0) 2009.06.16
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
Layout Panel #4 (DockPanel)  (0) 2009.06.12
Layout Panel #3 (StackPanel)  (0) 2009.06.12
Posted by Min-gu, Kim

티스토리 툴바