Jer*_*xon 6 data-binding wpf animation storyboard
这是我的问题.
ListBox A显示Observable Collection中的所有项目.
ListBox B仅显示在ListBox A中选择的项目.
<ListBox ItemsSource="{Binding MyView}" Name="ListBoxA">
<ListBox ItemsSource="{Binding Path=SelectedItems,
ElementName=ListBoxA}" Name="ListBoxB">
Run Code Online (Sandbox Code Playgroud)
在ListBox A中更改选择时,将运行StoryBoard.根据用户的选择,生成的UI是一个很酷且平滑的进出ListBox B的幻灯片.
问题是,我的ListBox A数据绑定只有Name属性,ListBox B数据绑定数十个,在某些情况下甚至数百个属性.
问题仍在继续,WPF中的数据绑定在渲染时会产生50-500毫秒的短暂UI延迟(特别是在它具有动态性时).用户界面冻结了.
这是可以忍受的.但我的StoryBoard似乎被这个DataBinding延迟阻止了.因此,用户界面"快照"到位,我看不到流畅的StoryBoard.
我通过附加到StoryBoard.Completed事件解决了这个问题.一旦StoryBoard完成,我就为ListBox B设置ItemsSource.
然而,这只有50%不错.用户看到StoryBoard执行,是的.但是,动画之后,ListBox B的结果UI仍然"捕捉"到视图中.
在我看来,正确的解决方案是以某种方式指示ListBox B内呈现的控件等待,或延迟实际的数据绑定.这将允许UI被渲染并参与StoryBoard - 但是数据将在以后"填充"(希望还能延迟DataBinding引起的延迟).
有人有过类似的问题吗?
这是完全演示问题的XAML(因为StackOverflow限制了问题的大小,您需要添加额外的TextBox才能真正看到延迟):
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<x:Array Type="{x:Type sys:String}" x:Key="MyData">
<sys:String>One</sys:String>
<sys:String>Two</sys:String>
<sys:String>Three</sys:String>
<sys:String>Four</sys:String>
<sys:String>Five</sys:String>
<sys:String>Six</sys:String>
</x:Array>
<Storyboard x:Key="MyGrowStoryboard">
<ParallelTimeline>
<DoubleAnimation To="1" DecelerationRatio="0.5"
Duration="00:00:00.500"
Storyboard.TargetName="MyTransform"
Storyboard.TargetProperty="ScaleX" />
<DoubleAnimation To="1" DecelerationRatio="0.5"
Duration="00:00:00.500"
Storyboard.TargetName="MyTransform"
Storyboard.TargetProperty="ScaleY" />
</ParallelTimeline>
</Storyboard>
<Storyboard x:Key="MyShrinkStoryboard">
<ParallelTimeline>
<DoubleAnimation To=".1" DecelerationRatio="0.5"
Duration="00:00:00.500"
Storyboard.TargetName="MyTransform"
Storyboard.TargetProperty="ScaleX" />
<DoubleAnimation To=".1" DecelerationRatio="0.5"
Duration="00:00:00.500"
Storyboard.TargetName="MyTransform"
Storyboard.TargetProperty="ScaleY" />
</ParallelTimeline>
</Storyboard>
</Page.Resources>
<StackPanel>
<ListBox ItemsSource="{Binding Source={StaticResource MyData}}"
Name="ListBoxA">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<DataTemplate.Triggers>
<!-- grow -->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Value="True"
Binding="{Binding Path=IsSelected,
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}}}" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard
Storyboard="{StaticResource MyGrowStoryboard}" />
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<BeginStoryboard
Storyboard="{StaticResource MyShrinkStoryboard}" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
<!-- shrink -->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Value="False"
Binding="{Binding Path=IsSelected,
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}}}" />
<Condition Value="1"
Binding="{Binding Path=SelectedItems.Count,
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type ListBox}}}" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard
Storyboard="{StaticResource MyShrinkStoryboard}" />
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<BeginStoryboard
Storyboard="{StaticResource MyGrowStoryboard}" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
</DataTemplate.Triggers>
<TextBlock Text="{Binding .}">
<TextBlock.LayoutTransform>
<ScaleTransform ScaleX="1" ScaleY="1"
x:Name="MyTransform"/>
</TextBlock.LayoutTransform>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox ItemsSource="{Binding Path=SelectedItems,
ElementName=ListBoxA}" Name="ListBoxB">
<ListBox.ItemTemplate>
<DataTemplate>
<UniformGrid Columns="10">
<!-- repeat this part MANY times (like 3000) ! -->
<TextBox Text="{Binding .}" />
<TextBox Text="{Binding .}" />
<TextBox Text="{Binding .}" />
<TextBox Text="{Binding .}" />
<TextBox Text="{Binding .}" />
</UniformGrid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Page>
Run Code Online (Sandbox Code Playgroud)
看起来像这样:
谢谢!
归档时间: |
|
查看次数: |
974 次 |
最近记录: |