위 그림처럼 메뉴 선택시 밑줄이 움직이는 애니메이션을 주고 싶었다.
저걸 어떻게 구현할까 고민 하던 중 Grid. Column 으로 나누고 Border 를 만들어서 선택된 RadioButton 에 따라서
Border 의 Grid.Column 을 이동시키면 되겠구나 라고 생각했다.
NO Animation Code
<Style TargetType="Border" x:Key="AnimatedBorderStyle">
<Setter Property="Grid.Column" Value="0"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=RightRadioButton}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<Int32Animation Storyboard.TargetProperty="(Grid.Column)"
To="1" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<Int32Animation Storyboard.TargetProperty="(Grid.Column)"
To="0" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
Border 스타일을 만들어서 적용을 해 보았더니, Border 표시가 되긴하지만 애니메이션 효과는 볼 수 없었다.
찾아보니 Grid.Column 으로는 애니메이션을 줄 수 없다는 의견들을 찾아서 포기했다.
xaml 상에서 여러가지를 시도해보았지만
' 스레드에서 사용하기 위해 이 Storyboard 시간 표시 막대 트리를 고정할 수 없습니다.'
오류가 자꾸 발생하였고
돌고 돌아 Behind code 에서 수정하기로 했다.
// Animation Border
<Border x:Name="AnimatedBorder"
Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3"
HorizontalAlignment="Left"
BorderThickness="0 2 0 0"
BorderBrush="#343D4C">
<Border.RenderTransform>
<TranslateTransform/>
</Border.RenderTransform>
</Border>
// Grid Column 개수는 3개
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" x:Name="GridColumn0"/>
<ColumnDefinition Width="Auto" x:Name="GridColumn1"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
우선 Border 에 RenderTransform, TranslateTransform 을 주어야만 애니메이션 효과를 기대할 수 있다.
// ActualWidth 저장 변수
private double GridColumn0ActualWidth;
private double GridColumn1ActualWidth;
// Loaded 에서 ActualWidth 를 가져온다.
this.Dispatcher.BeginInvoke(new Action(() =>
{
GridColumn0ActualWidth = GridColumn0.ActualWidth;
GridColumn1ActualWidth = GridColumn1.ActualWidth;
if (IsCheckedBefore == true)
{
AnimatedBorder.Width = GridColumn0ActualWidth;
AnimatedBorder.RenderTransform = new TranslateTransform(0, 0);
}
else
{
AnimatedBorder.Width = GridColumn1ActualWidth;
AnimatedBorder.RenderTransform = new TranslateTransform(GridColumn0ActualWidth, 0);
}
}), System.Windows.Threading.DispatcherPriority.Loaded);
// 좌측 라디오버튼
private void ExecuteCheckBefore()
{
if (IsCheckedBefore == true)
{
SlideAnimation(AnimatedBorder, GridColumn0.ActualWidth, 0, GridColumn0ActualWidth);
}
}
// 우측 라디오버튼
private void ExecuteCheckAfter()
{
if (IsCheckedAfter == true)
{
SlideAnimation(AnimatedBorder, 0, GridColumn0.ActualWidth, GridColumn1ActualWidth);
}
}
RadioButton 에 Command 를 주어 내가 원하는 이벤트가 발생할때마다 SlidAnimation 함수가 실행되도록 하였다.
private void SlideAnimation(UIElement element, double from, double to, double borderWidth)
{
// DoubleAnimation 생성
DoubleAnimation animation = new DoubleAnimation
{
From = from,
To = to,
Duration = new Duration(TimeSpan.FromSeconds(0.2))
};
// 애니메이션 적용할 속성 설정
Storyboard.SetTarget(animation, element);
Storyboard.SetTargetProperty(animation, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.X)"));
// Storyboard 생성 및 애니메이션 추가
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(animation);
// 애니메이션 시작
storyboard.Begin();
AnimatedBorder.Width = borderWidth;
}
Behind Code 에서 즉석으로 from, to 를 변경하였다.
'WPF' 카테고리의 다른 글
[WPF] Binding Error - HorizontalContentAlignment, VerticalContentAlignment (2) | 2024.09.11 |
---|---|
[WPF] Delay 이후 UI 작업을 진행할 때 (0) | 2024.09.11 |
[C#] 파일 읽고 쓰는 중 한글, 특수 문자가 깨지면 UTF8 을 사용하자 (0) | 2024.08.28 |
[WPF] Loading 창 Nuget Package 추천 (0) | 2024.08.07 |
[WPF] Popup 에서 TextBox 사용시 한글 분리 현상 (1) | 2024.08.05 |