반응형
토글 스위치가 필요하여 구글링으로 알게 된 내용과 구현하고자 하는 방식에 차이가 있어 일부 내용을 수정하여 만들게 되었다. 수정하던 중 이상한 현상이 있어 내용을 기록해 본다.
1. Animation 사용
위 이미지의 토글 스위치에서 IsChecked = True일 경우, Border 배경 색상이 변경된다.
이 코드를 Storyboard에서 Animation으로 설정했는데, 토글 버튼인 Ellipse를 이동시키는 Animation과 함께 사용된다.
아래 코드를 보면 ColorAnimation과 ThicknessAnimation이 함께 사용됨을 확인할 수 있다.
이렇게 사용하면 IsChecked 속성 변경 시 배경색이 변경되며 토글 버튼이 이동하는데, 이상한 점은 xaml에서 IsChecked 속성을 변경해도 빌드해 보면 적용이 되지 않는다는 것이다. 자세히 설명하자면 아래와 같다.
- 토글 버튼의 기본 위치는 IsChecked = False의 위치
- xaml에서 IsChecked = True로 설정하면 토글 버튼의 위치가 변경됨
- 빌드하여 폼에서 확인하면 IsChecked = False 상태로 표시됨
- 하지만 해당 토글 버튼의 IsChecked 속성을 확인해 보면 True
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Checked">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="GreenYellow"
Duration="0:0:0.5" />
<ThicknessAnimation Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="Margin"
To="20 1 2 1"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Unchecked">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#FFF5F5F5"
Duration="0:0:0.2" />
<ThicknessAnimation Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="Margin"
To="2 1 2 1"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="0.35" />
</Trigger>
</ControlTemplate.Triggers>
|
cs |
다른 토글 스위치를 만들어 테스트를 해보았으나 해답은 Animation 사용에 있었다.
Storyboard에 Animation을 2개 사용하면 위 설명된 내용처럼 IsChecked 상태가 꼬이게(?) 된다. 정확한 이유는 잘 모르겠으나, Animation을 1개만 사용하면 위 현상이 발생하지 않았다.
2. 토글 스위치 최종 결과
결국 Animation은 하나만 사용하고, Trigger에서 배경색을 변경하는 것으로 코드를 작성했다. 코드는 아래와 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
<Style TargetType="{x:Type local:ToggleSwitch}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ToggleSwitch}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Viewbox Grid.Column="0">
<Border x:Name="Border" CornerRadius="10" Background="#FFF5F5F5"
Width="40" Height="20" BorderThickness="1" BorderBrush="Black" >
<Border.Effect>
<DropShadowEffect ShadowDepth="0" Direction="0" Opacity="0" />
</Border.Effect>
<Ellipse x:Name="Ellipse" Fill="Magenta" Stretch="Uniform"
Margin="2 1 2 1" Stroke="Lime" StrokeThickness="1"
HorizontalAlignment="Stretch">
</Ellipse>
</Border>
</Viewbox>
<ContentPresenter Grid.Column="1" Content="{TemplateBinding Content}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Visibility="{TemplateBinding IsReadOnly}" />
</Grid>
<ControlTemplate.Resources>
<Storyboard x:Key="right">
<ThicknessAnimation Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="Margin" Duration="0:0:0.2" To="20 1 2 1">
<ThicknessAnimation.EasingFunction>
<CircleEase EasingMode="EaseOut"/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
<Storyboard x:Key="left">
<ThicknessAnimation Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="Margin" Duration="0:0:0.2" To="2 1 2 1">
<ThicknessAnimation.EasingFunction>
<CircleEase EasingMode="EaseOut"/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource right}" x:Name="rightt"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource left}" x:Name="leftt"/>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.35"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True"/>
<Condition Property="IsEnabled" Value="True"/>
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Border.Background" Value="GreenYellow"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
|
cs |
반응형
'프로그래밍 언어 > WPF' 카테고리의 다른 글
[C#] WPF - 사용자 정의 컨트롤(User Control) / 사용자 지정 컨트롤(Custom Control) (0) | 2024.01.09 |
---|---|
[C#] WPF - UI의 모든 컨트롤 가져오기 (0) | 2024.01.05 |
[C#] WPF - 특정 프로세스 Focus 여부 판단 방법 (0) | 2023.01.09 |
[C#] WPF - DataGrid의 ForeColor 변경 시 에러 방지 (2) | 2022.10.26 |
[C#] Form에서 다른 Form으로 데이터 전송하는 방법 (0) | 2022.10.25 |
댓글