내용 보기

작성자

관리자 (IP : 172.17.0.1)

날짜

2020-07-09 04:06

제목

[WPF] Storyboard Value 바인딩 처리 하기


● Storyboard Value 바인딩 처리 하기


Storyboard의 DoubleAnimationUsingKeyFramesEasingDoubleKeyFrame등 애니메이션 설정시 Value을 바인딩해서 사용할때 다음과 같이 처리해야 한다.

다음은 엄청 간단한 애니메이션인 Storyboard 예시다.

MainWindow.xaml

<Window.Resources>
        <Storyboard x:Key="xGoBike" Completed="GoBikeEndStoryboard_Completed">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
                                           Storyboard.TargetName="xBikeLeft">
                <EasingDoubleKeyFrame KeyTime="0:0:0:0" Value="-0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0:3" Value="{Binding BikeEndPoint}"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
 
        <Storyboard x:Key="xGoBikeAfter">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
                                           Storyboard.TargetName="xBikeLeft">
                <EasingDoubleKeyFrame KeyTime="0:0:0:3" Value="0"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
</Window.Resources>
cs

단순히 xBikeLeft이름인 버튼을 화면의 width사이즈 만큼 오른쪽으로 이동시키고 다시 왼쪽으로 돌아오는 애니메이션인데
화면의 width는 동적인 값이기에 바인딩을 통해서 처리해야 한다.

다음과 같이 Value설정 부분에 Binding 처리를 하고 View가 로드되면서 바로 Storyboard가 로드 되도록 처리를 해보면

MainWindow.xaml
<Button x:Name="xBikeLeft"
                Width="200"
                Height="50"
                Background="Black"
                HorizontalAlignment="Left"
                Margin="0, 0, 0, 0">
            <TextBlock Text="this is Bike"
                       Foreground="White"/>
            <Button.RenderTransform>
                <TranslateTransform/>
            </Button.RenderTransform>
 
            <Button.Style>
                <Style TargetType="Button">
                    <Style.Triggers>
                        <EventTrigger RoutedEvent="Click">
                            <EventTrigger.Actions>
                                <BeginStoryboard Storyboard="{StaticResource xGoBike}"/>
                            </EventTrigger.Actions>
                        </EventTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
</Button>
cs

대충 이런식으로 Storyboard를 실행할 수 있다. (버튼 클릭시 Storyboard를 실행하는 트리거 적용)
하지만 이대로 실행해 보면?!


요런 예외가 딱! 하고 발생된다.

대충 왜 오류가 발생되는지 추측해보면..
View가 로드 되고 각 컨트롤의 스타일 이 로드 되면서 트리거 설정의
BeginStoryboard호출시 Storyboard가 먼저 실행(로드)된 후 바인딩 처리가 되므로 정상적으로 Value설정이 되지않아 예외가 발생된 것 같다.

이런 상황에서는 Storyboard 호출 처리를 View의 로드 동시에 처리 할 순 없고 Code상에서 비동기적으로 처리해야 한다.

MainWindow.cs
 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
public partial class MainWindow : Window
{
        public MainWindow()
        {
            InitializeComponent();

            this.DataContext = this;
        }

        public double BikeEndPoint
        {
            get; set;
        }

        private void GoBikeEndStoryboard_Completed(object sender, EventArgs e)
        {
            Storyboard goBikeSB = this.Resources["xGoBikeAfter"] as Storyboard;
            this.BeginStoryboard(goBikeSB);
        }

        private void xBikeLeft_Click(object sender, RoutedEventArgs e)
        {
            Storyboard goBikeSB = this.Resources["xGoBike"] as Storyboard;
            Action action = () => { this.BeginStoryboard(goBikeSB); };
            Dispatcher.BeginInvoke(action, DispatcherPriority.Render);
        }
}

24Line 부분이 Storyboard를 비동기 적으로 호출하는 부분이다.

출처1

출처2