본문 바로가기

.NET/WPF

WPF 기초 Resource, Linear Gradient , Style

반응형




전체 소스

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>

        <LinearGradientBrush x:Key="ButtonGradient" StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="#FDB6CADF" Offset="0" />
            <GradientStop Color="#FCC3C5FF" Offset="0.1" />
            <GradientStop Color="#FCC4D0EF" Offset="0.3" />
            <GradientStop Color="#FDB7C2DF" Offset="0.6" />
            <GradientStop Color="#FE95B3CF" Offset="0.8" />
            <GradientStop Color="#FE96AACF" Offset="1" />
        </LinearGradientBrush>

        <LinearGradientBrush x:Key="ButtomUpGradient" StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="Transparent"
 Offset="0" />
            <GradientStop Color="#33000000" Offset="1" />
        </LinearGradientBrush>
        <LinearGradientBrush x:Key="ButtonDownGradient" StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="#10000000" Offset="0" />
            <GradientStop Color="#20000000" Offset="1" />
        </LinearGradientBrush>

        <LinearGradientBrush x:Key="ButtonDisabledGradient" StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="#10302A90" Offset="0" />
            <GradientStop Color="#10201040" Offset="1" />
        </LinearGradientBrush>
        <!--button Template-->
        <Style TargetType="{x:Type Button}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border x:Name="OuterBorder" CornerRadius="3" Background="{DynamicResource ButtonGradient}" >
                            <Border x:Name="InnerBorder" CornerRadius="3" Background="{DynamicResource ButtonUpGradient}" Padding="{TemplateBinding Padding}">
                                <ContentPresenter x:Name="ContentSite" HorizontalAlignment="Center" VerticalAlignment="Center" />
                            </Border>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsPressed" Value="true">
                                <Setter TargetName="InnerBorder" Property="Background" Value="{DynamicResource ButtonDownGradient}"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter TargetName="InnerBorder" Property="Background" Value="{DynamicResource ButtonDisableGradient}" />
                                <Setter Property="BorderBrush" Value="Silver" />
                                <Setter Property="Foreground" Value="SlateGray" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="Height" Value="18" />
            <Setter Property="Foreground" Value="MidnightBlue" />
        </Style>
    </Window.Resources>

    <StackPanel Height="200">
        <Button Width="200" Height="40" VerticalAlignment="Center">Press Me!</Button>
    </StackPanel>
</Window>






Resource

처음 도입부는 Windows 엘리먼트를 선언하고 네임스페이스를 추가한 후, Resources 섹션을 선언한다.
Resouces 섹션에 선언한 스타일이나 엘리먼트들은 프로그램을 구성하는 UI 어느곳에서나 공유할 수 있다.

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>



Linear Gradient 

리니어 그레이디언트는 선을 따러서 색상을 입힌다. 색상은 한 지점에서 다른 지점까지 선을 따라서 점진적으로 변한다 (새로운 색상을 적용하기 위해 GradientStop 오브젝트를 사용하면 점진적으로 변하던 값들이 변경된다)

리니어 그레인언트는 꼭 그렇지는 않지만 보통 대각선으로 적용된다. 이때 , 사용되는 가상의 선은 시작점과 종료점에 따라서 결정되며 지정할 경우 좌측 상단의 시작점에서 우측 하단의 종료점까지 (x,y)좌표에 다라서 점진적으로 색상이 적용된다.
(0,0)--------
     | 사각형  |
      ------- (1,1)

<LinearGradientBrush x:Key="ButtonGradient" StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="#FDB6CADF" Offset="0" />

시작점과 종료점을 선언한후 LinearGradientBrush와 한개 이상의 GradientStop 엘리먼트를 추가한다

이러한 작업은 LinearGradientBrush와 연동하는 GradientStop의 컬렉션을 추가하는 것과 같다
GradientStop 엘리먼트는 그레디언트 축의 색상과 오프셋을 설정하는 데 사용된다


정리해 보면, LinearGradientBrush는 그레이디언트의 변화율을 결정하고, GradientStop엘리먼트들은 그레이디언트가 진행되는 과정에 색상의 변화를 결정한다. 



Style

예제의 두 번째 섹션은 전역 스타일(Style)을 정의하고 이스타일을 Button에 적용하는 부분이다. 대상 엘리먼트는 http://schemas.microsoft.com/winfx/2006/xaml 네임스페이스에 정의된 Type 어트리뷰트로 식별하고 TargetType 프로퍼티로 설정한다 이때, 네임스페이스를 식별자를 사용하는데, 통상 'x' 접두어를 사용한다.

<Style TargetType="{x:Type Button}" 
이 밑 라인 밑으로 Setter 엘리먼트를 하나 추가한다. 일반적으로, 한개의 Setter 엘리먼트는 한개의 프로퍼티 값을 설정한다. 이번예제에서, Setter는 프로퍼티가 설정된 특정인스턴스를 식별하기 위해서 스타일의 대상을 설정하는 경우에 사용된다


<Setter Property="Template"> 프로퍼티의 이름을 설정할 Property 키워드가 필요하다. 여기서는 , 템플릿으로 사용할 스타일을 지칭할 것이다

<Setter.Value> 템플릿 값은 명시적인 프로퍼티로 설정하기 위해서 프로퍼티와 엘리먼트의 수만틈 열고 닫는 태그를 설정한다

<ControlTemplate TartgetType="x:Type Button}" > ControlTramplate 이 버튼의 생성을 단순화하기 위해서 사용된다. ControlTemplate은 TargetType 프로퍼티를 가지고 있는데, 이 프로퍼티는 ControlTemplate이 사용될 형식을 명시한다

<Border x:Name="OuterBorder" CornerRadius="3" Background="{DynamicResource ButtonGradient}" 이 템플릿에서, 버튼은 모서리의 곡면(radius)의 둥글기가 3인 테두리를 가진 OuterBorder란 이름으로 설정할 것이다 . 여기서는 DynamicResource를 사용해서 배경색을 설정한다. 주의할 점은 곡면 처리를 위해서 CornerRadius를 10으로 설정해서, 버튼을 좀더 블릿 형태로 보이게 만들 것이다.   

<Border x:Name = "InnerBorder" CornerRadius="3" Background="{DynamicResource ButtonUpgradient}" Padding="{TemplateBinding Padding}" > 
     <ContentPresenter x:Name="ContentSite" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border> 이후, 두번째 Border오브젝트를 정의하고 배경색을 할당하기 위해서 ButtonUpGradient를 사용한다. Padding은 컨텐트의 외곽의 공백을 만들기 위해 사용되고, ContentPresenter 버튼에 글자를 보여 주기 위해서 사용된다.

<ControlTemplate.Triggers> 트리거(Trigger)는 프로퍼티의 상태를 변경하고 이벤트에 따라서 애니메이션을 시작하기 위한 메커니즘이다. 이번 예제에서는 트리거를 호출하지는 않지만 일단 내용에 포함시킨다. 이 트리거는 뒤에서 다룰 때 효과를 적용 하기 위해서 사용한다.

<Trigger Property="IsPressed" Value="true">
    <Setter TargetName="InnerBorder" Property="Background" Value="{DynamicResource ButtonDownGradient}"/> 
</Trigger> 버튼을 누를 때, 트리거는 InnerBorder에 ButtonDownGradient 설정을 적용한다


<Trigger Property="IsEnabled" Value="false">
    <Setter TargetName="InnerBorder" Property="Background" Value="{DynamicResource ButtonDisableGradient}" />
    <Setter Property="BorderBrush" Value="Silver" />
    <Setter Property="Foreground" Value="SlateGray" />
</Trigger>
이 트리거는 IsEnabled 프로퍼티가 false로 설정 될때 InnerBorder 이름의 Border 컨트롤의 Background 프로퍼티에 적용되면, 실제 동작은 ButtonDisabledGradient란 리소스를 동적으로 참조한다. 이 리소소는 배경색이 은색이고 전경색은 진회색(SlateGray)로 설정된 것들이다.


</ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
      </Setter> Setter 태그를 닫고 이제까지 열린 태그를 모두 닫는다.


<Setter Property="Height" Value="18" />
<Setter Property="Foreground" Value="MidnightBlue" />
버튼의 프로퍼티에 적용할 두 개 이상의 평범한 Setter를 설정한다


        </Style>
    </Window.Resources>
    <StackPanel Height="200">
        <Button Width="200" Height="40" VerticalAlignment="Center">Press Me!</Button>
    </StackPanel>
</Window> 스타일 (Style)과 리소스(Resources)엘리먼트가 닫히고, 버튼을 포함한 StackPanel을 만든 후, Windows 엘리먼트가 끝난다.





- 출처  Programming .Net 3.5 by Jesse Liberty and Alex Horovitz. (소수 수정)