MVVM Light 툴킷을 기반으로 한 첫 번째 WPF 프로젝트에서 작업하고 있습니다. 주요보기과 같이, 데이터 바인딩 ContentControl
에 임의의 뷰 모델을 보유 : 내가하고 싶은 무엇VisualStateManager를 사용하여 MVVM ViewModel 전환 애니메이션 - 실행중인 애니메이션이 없습니다.
<ContentControl x:Name="ViewModelContent" Content="{Binding CurrentViewModel}" ... />
가, 때마다이 뷰 모델 변경 후 이전 뷰 모델 (즉, ContentControl
이다)과 페이드 아웃 새 것으로 사라지다. 이것은 WPF 세계에서 새로운 아이디어는 아니며,이를 수행하는 방법을 연구하는 데 상당한 시간을 투자했습니다 (여기와 다른 사이트 모두에서). 나는이 비교적 간단한 유지하려고하고, 제가 수집 한 것은 내가보기의 DataTemplate
에 두 가지 상태를 정의 할 수 VisualStateManager
를 사용할 수 있다는 것입니다 해요 :
- 이을 ContentChanging 다음 페이드 아웃 상태
- 에게 는을 ContentChanged 다음 퇴색 된 상태
을 다음, GoToStateAction
를 사용하여 필요에 따라 나는 적절한 상태로 애니메이션 효과를 적용 할 수 있습니다. "필요에 따라"내 경우에는, (내가 MVVM 라이트 사용하고 기억) 내 뷰 모델에 정의 된 CurrentViewModelChanging
속성에 의해 이루어집니다
private bool _vmChanging;
public bool CurrentViewModelChanging
{
get
{
return _vmChanging;
}
private set
{
Set(() => CurrentViewModelChanging, ref _vmChanging, value);
}
}
내가이 프로퍼티에 바인딩하는 DataTrigger
을 활용하고 변경할 수 있습니다 그에 따라 상태. DataTemplate
에 대한 XAML에서 그것은 다음과 같습니다
<i:Interaction.Triggers>
<ei:DataTrigger Binding="{Binding CurrentViewModelChanging, Mode=OneWay}" Value="True">
<ei:GoToStateAction StateName="ContentChanging"/>
</ei:DataTrigger>
<ei:DataTrigger Binding="{Binding CurrentViewModelChanging, Mode=OneWay}" Value="False">
<ei:GoToStateAction StateName="ContentChanged"/>
</ei:DataTrigger>
</i:Interaction.Triggers>
지금까지 너무 좋아.
CurrentViewModelChanging
을 토글하지 않고 (그리고 상태를 변경하는 것) 다른 목적을 수행하지 않는 버튼을 폼에 넣었습니다. 예상했던대로 정확하게 수행합니다. 한 번 클릭하면 페이드 아웃되고 다시 클릭하면 페이드 인합니다. 문제는 ViewModel을 실제로 변경할 때 페이드 아웃/인을 수행하려고 할 때 발생합니다. 여기에 내가 이것을 시도 코드 조각은 다음과 같습니다
이 실행될 때 발생하는 기본적으로 아무것도 무엇
public Standards.StandardsViewModel CurrentViewModel
{
....
private set
{
....
CurrentViewModelChanging = true;
Set(() => CurrentViewModel, ref _viewModel, value);
CurrentViewModelChanging = false;
....
};
}
: 뷰 모델은 어떤 애니메이션없이 즉시 전환됩니다. CurrentViewModelChanging
을 변경하면 애니메이션이 실행되고 애니메이션이 끝날 때까지 나머지 코드가 실행되는 것을 중지한다는 인상 아래에있었습니다. 그렇게 보이지는 않습니다. 그래서 누군가가 내게 무슨 일이 일어나는지 (어떻게 고쳐야하는지) 궁금해 할 수 있습니까? 내 생각 엔 애니메이션은 실행중인 논리와 다른 스레드에서 실행되며 논리는 너무 빨리 실행되므로 애니메이션이 실제로 아무것도 할 시간이 없다는 것입니다. 그러나 Thread.Sleep()
호출을 CurrentViewModelChanging
토글에 넣으면 애니메이션이 생기지 않습니다. 프로그램에서 ViewModel을 변경하고 즉시 변경합니다.
또한 분명하지 않은 경우이 내용은 모두 DataTemplate
을 기반으로하므로 UserControls
을 사용해야하는 솔루션은 이상적이지 않습니다. 그것이 그 때 가지고가는 무슨 인 경우에, 나는 확실히 그것을, 그러나 할 것이다. XAML에 대한 자세한 내용은 DataTemplate
을 참조하십시오. 내가 간결하게 유지하기 위해 애니메이션의 세부 사항을 남겨 두었다 참고 :
<DataTemplate DataType="{x:Type localVMS:StandardsModuleViewModel}">
<DockPanel x:Name="ModLayout" LastChildFill="True" Margin="0" Grid.Column="1">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ContentPresentationStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.1" To="ContentChanging"/>
<VisualTransition GeneratedDuration="0:0:0.1" To="ContentChanged"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="ContentChanging" ... />
<VisualState x:Name="ContentChanged" .... />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="MainMenuGrid" VerticalAlignment="Top" Background="Black" DockPanel.Dock="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ItemsControl x:Name="MainMenu" HorizontalAlignment="Left" VerticalAlignment="Bottom" ItemsSource="{Binding MainMenu}" ItemTemplate="{DynamicResource TopMenuItem}" ItemsPanel="{DynamicResource HorizontalMenuTemplate}" FontFamily="Calibri" FontSize="16" MinHeight="20" Background="Transparent" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>
</Grid>
<ItemsControl x:Name="SubMenu" ItemsSource="{Binding SubMenu}" ItemsPanel="{DynamicResource HorizontalMenuTemplate}" ItemTemplate="{StaticResource SubMenuItem}" DockPanel.Dock="Top" Height="25" VerticalContentAlignment="Center" Background="White" FontFamily="Calibri" FontSize="13.333"/>
<Grid x:Name="ViewModelLayout" DockPanel.Dock="Bottom">
<i:Interaction.Triggers>
<ei:DataTrigger Binding="{Binding CurrentViewModelChanging, Mode=OneWay}" Value="True">
<ei:GoToStateAction StateName="ContentChanging"/>
</ei:DataTrigger>
<ei:DataTrigger Binding="{Binding CurrentViewModelChanging, Mode=OneWay}" Value="False">
<ei:GoToStateAction StateName="ContentChanged"/>
</ei:DataTrigger>
</i:Interaction.Triggers>
<ContentControl x:Name="ViewModelContent" Content="{Binding CurrentViewModel}" ContentTemplateSelector="{StaticResource GenericTemplateSelector}" HorizontalAlignment="Center" VerticalAlignment="Top" Padding="10" HorizontalContentAlignment="Center" Margin="10" RenderTransformOrigin="0.5,0.5" ... />
</Grid>
</DockPanel>
</DataTemplate>