스토리 보드에 첨부 된 동작에 바인딩하십시오
-
22-07-2019 - |
문제
스토리 보드에서 이벤트가 발사 될 때 내 뷰 모델에서 메소드를 호출 할 수 있도록 스토리 보드에 첨부 된 종속성 속성을 만들었습니다.
public static class StoryboardExtensions
{
public static ICommand GetCompletedCommand(DependencyObject target)
{
return (ICommand)target.GetValue(CompletedCommandProperty);
}
public static void SetCompletedCommand(DependencyObject target, ICommand value)
{
target.SetValue(CompletedCommandProperty, value);
}
public static readonly DependencyProperty CompletedCommandProperty =
DependencyProperty.RegisterAttached(
"CompletedCommand",
typeof(ICommand),
typeof(StoryboardExtensions),
new FrameworkPropertyMetadata(null, OnCompletedCommandChanged));
static void OnCompletedCommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
Storyboard storyboard = target as Storyboard;
if (storyboard == null) throw new InvalidOperationException("This behavior can be attached to Storyboard item only.");
storyboard.Completed += new EventHandler(OnStoryboardCompleted);
}
static void OnStoryboardCompleted(object sender, EventArgs e)
{
Storyboard item = ... // snip
ICommand command = GetCompletedCommand(item);
command.Execute(null);
}
}
그런 다음 바인딩 구문과 함께 XAML에서 사용하려고합니다.
<Grid>
<Grid.Resources>
<Storyboard x:Key="myStoryboard" my:StoryboardExtensions.CompletedCommand="{Binding AnimationCompleted}">
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="0:0:5" />
</Storyboard>
<Style x:Key="myStyle" TargetType="{x:Type Label}">
<Style.Triggers>
<DataTrigger
Binding="{Binding Path=QuestionState}" Value="Correct">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource myStoryboard}" />
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Label x:Name="labelHello" Grid.Row="0" Style="{StaticResource myStyle}">Hello</Label>
</Grid>
다음과 같은 예외로 실패합니다.
system.windows.markup.xamlparseexception이 발생한 메시지 = "속성의 값을 'system.windows.style'유형의 객체로 속성 '스타일'으로 변환 할 수 없습니다.이 스토리 보드 타임 라인 트리를 스레드에서 사용하기 위해 정지 할 수 없습니다. 마크 업 파일 'testwpfapp; component/window1.xaml'
스토리 보드에 첨부 된 ICOMMAND 속성으로 바인딩 구문을 작동시키는 방법이 있습니까?
해결책 3
이 문제를 해결하기 위해 스토리 보드 헬퍼 (Storyboard Helpers)라는 첨부 된 속성을 만들었습니다.여기서 소스 코드). 스토리 보드 자체에 첨부하려고 시도했고 이제 스토리 보드가 완료되면 내 뷰 모델에서 ICOMMAND를 호출하고 스토리 보드에서 특정 이벤트에 바인딩하기 위해 내 뷰 모델에서 ICOMMAND를 호출하기 위해 (임의의) 프레임 워크 요소에 첨부하는 것을 포기했습니다. . 세 번째 첨부 된 속성은 다음과 같은 스토리 보드를 지정합니다.
<FrameworkElement
my:StoryboardHelpers.Storyboard="{StaticResource rightAnswerAnimation}"
my:StoryboardHelpers.Completed="{Binding CompletedCommand}"
my:StoryboardHelpers.BeginEvent="{Binding StartCorrectAnswer}" />
다른 팁
이것은 디자인으로 무언가입니다. 스타일에 맞는 얼어 붙을 수있는 객체가있는 경우, 크로스 스레드에 액세스 할 수 있도록 스타일이 얼어 붙습니다. 그러나 바인딩은 본질적으로 데이터 바인딩이 단일 스레드이므로 동결 될 수 없다는 것을 의미합니다.
이 작업을 수행 해야하는 경우 스타일이 아닌 프레임 워크 요소 아래에서 트리거를 스타일 외부로 넣으십시오. Grid.Triggers 섹션 에서이 작업을 수행 할 수 있습니다. 스타일이 더 이상 완료되지 않아 트리거를 복제해야하지만 WPF의 "디자인"기능입니다.
MSDN 소셜 포럼에 대한 전체 답변은 다음과 같습니다 여기.
스토리 보드를 심으로 시작하기 위해 새로운 동결 유래 클래스를 만들 수 있습니다. 해당 shim 객체의 속성을 스토리 보드 이름에 바인딩하십시오. 그렇게하면 트리거를 복제하거나 스타일 외부에 저장할 필요가 없습니다.