我正在开发基于MVVM Light工具包的第一个WPF项目。主视图在数据绑定ContentControl
中包含任意ViewModel,如下所示:
<ContentControl x:Name="ViewModelContent" Content="{Binding CurrentViewModel}" ... />
我想做的是,每当此ViewModel更改时,淡出旧的ViewModel(即ContentControl
),然后淡入新的。这在WPF世界中并不是一个新想法,我花了相当多的时间研究如何完成它(在这里和其他网站上)。我试图保持这个相对简单,我收集的是我可以使用VisualStateManager
在视图DataTemplate
上定义两个状态:
然后,使用GoToStateAction
,我可以根据需要设置动画到适当的状态。就我而言,“根据需要”是通过我的ViewModel上定义的CurrentViewModelChanging
属性来完成的(记住,我正在使用MVVM Light):
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;
....
};
}
当它运行时会发生什么事情:ViewModel瞬间切换而没有任何动画。我的印象是,更改CurrentViewModelChanging
会导致动画运行并停止执行任何剩余代码,直到动画结束。情况似乎并非如此,所以有人可以告诉我发生了什么(以及如何解决)?我最好的猜测是,动画在与执行逻辑不同的线程中运行,并且所述逻辑执行得如此之快,以至于动画没有时间实际执行任何操作。但是,如果我在Thread.Sleep()
切换中放置一个CurrentViewModelChanging
调用,那么我仍然无法获得动画:程序只是暂停了很长时间我告诉它,然后立即更改ViewModel。
另外,如果不明显,这都是基于DataTemplate
,所以要求我使用UserControls
的解决方案并不理想。如果这就是它所需要的,那么我肯定会这样做。如果有帮助,这里的DataTemplate
更完整的XAML。请注意,我已经省略了动画的细节,以保持简洁:
<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 :(得分:0)
问题是你的ContentControl一次只能绑定一件事。一旦更改了视图模型,就不再存在与旧视图模型的绑定,因此没有任何内容可以消失。要解决此问题,您必须设置两个重叠的UserControl并分别淡入/淡出,或使用a helper class为您处理。