WPF에서 그라데이션으로 색 칠하기
작성날짜 2025/01/01
LinearGradientBrush
LinearGradientBrush 태그를 이용해 그라데이션으로 색을 칠할 수 있다. 색이 바뀌는 구간은 GradientStrop태그로 지정한다.
<!-- This rectangle is painted with a diagonal linear gradient. -->
<Rectangle Width="200" Height="100">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Yellow" Offset="0.0" />
<GradientStop Color="Red" Offset="0.25" />
<GradientStop Color="Blue" Offset="0.75" />
<GradientStop Color="LimeGreen" Offset="1.0" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
200 넓이의 Rentagle이 1/4 , 1/2 , 3/4 지점 마다 색이 바뀌게 된다.
출력된 Rectangle을 보면, 색이 세로로 구분되는게 아니라 대각선으로 구분되는 것을 볼 수 있는데, 이는 StartPoint, EndPoint와 연관이 있다. 위의 코드에서 StartPoint는 (0, 0), EndPoint는 (1, 1)이므로 왼쪽 상단이 StartPoint, 오른쪽 하단이 EndPoint가 된다.
따라서, 대각선이 아니라 세로로 색을 구분하고 싶다면 y축의 값을 중간값인 0,5로 지정해 주면 된다.
<LinearGradientBrush StartPoint="0, 0.5" EndPoint="1, 0.5">
마찬가지로 색이 바뀌는 방향을 가로에서 세로로 바꾸고 싶다면 StartPoint, EndPoint를 바꿔주면 된다.
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5, 1">
응용
이번엔 마우스 커서를 올리면 색이 변하는 버튼을 만들어보자.
<LinearGradientBrush x:Key="btnDefualtBackground" StartPoint="0, 0.5" EndPoint="1, 0.5">
<GradientStop Color="MidnightBlue" Offset="0.0"/>
<GradientStop Color="OliveDrab" Offset="0.75"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="btnOverBackground" StartPoint="0, 0.5" EndPoint="1, 0.5">
<GradientStop Color="OliveDrab" Offset="0.0"/>
<GradientStop Color="Olive" Offset="0.75"/>
</LinearGradientBrush>
마우스를 안 올렸을 때랑 올렸을 때, 두가지 색을 Resources에 정의해주자.
<Button Width="200" Height="60" Background="{StaticResource btnDefualtBackground}">
<TextBlock Text="Over Mouse to Me!"/>
</Button>
그리고 배경색을 입혀주면...
그라데이션이 적용된다. 하지만 아무런 스타일이나 이벤트를 정의하지 않았으니 마우스를 올려도 반응이 없다.
애니메이션을 적용하는 방법은 많이 있지만 코드 비하인드에서 이벤트를 처리하지 않고 xaml만으로 작동시켜 보자.
<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border Background="{StaticResource btnBackground}" VerticalAlignment="Stretch" CornerRadius="15" HorizontalAlignment="Stretch"/>
<Border x:Name="OnOverBorder" Opacity="0" Background="{StaticResource btnOverBackground}" VerticalAlignment="Stretch" CornerRadius="15" HorizontalAlignment="Stretch"/>
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" x:Name="MainContent" />
</Grid>
</Setter.Value>
</Setter>
</Style>
버튼에 적용할 스타일을 정의했다.
버튼에 Border 2개를 정의하고 하나는 투명하게, 하나는 불투명하게 설정한다.
<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border Background="{StaticResource btnBackground}" VerticalAlignment="Stretch" CornerRadius="15" HorizontalAlignment="Stretch"/>
<Border x:Name="OnOverBorder" Opacity="0" Background="{StaticResource btnOverBackground}" VerticalAlignment="Stretch" CornerRadius="15" HorizontalAlignment="Stretch"/>
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" x:Name="MainContent" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="OnOverBorder" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="OnOverBorder" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
그리고 IsMouseOver Trigger에서 두 Border의 투명도를 바꾸는 DoubleAnimation을 정의해주고
<Button Width="200" Height="60" Style="{StaticResource MyButtonStyle}">
<TextBlock Text="Over Mouse to Me!"/>
</Button>
버튼에 스타일을 적용하면
마우스를 안 올렸을 때
마우스를 올렸을 때 색이 서서히 바뀌는 것을 볼 수 있다.