2014-11-13 3 views
3

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> 

답변

0

문제는 당신의 ContentControl을 한 번에 한 가지를 결합 할 수 있다는 것입니다. 뷰 모델을 변경하자마자 이전 모델에 대한 바인딩이 더 이상 존재하지 않으므로 사라지지 않을 것입니다.이 문제를 해결하려면 두 개의 겹치는 UserControls를 설정하고 개별적으로 페이드 인/페이드 아웃하거나 a helper class을 사용하여 처리해야합니다.