How to let ListBox scroll smoothly
There is a listbox with the following ItemContainerStyle, it's binding to the ViewModel class but when scroll the listbox its performance not smooth. I check this on the web, and I replaced the visualstackpanel with normal stackpanel in the listbox. Yes, it scrolls smoothly, but it freezes when the data is loading. Is there anything I can do?
<Style TargetType="ListBoxItem" x:Key="ListBoxItem">
<Setter Property="Background" Value="Transparent"/>
&l开发者_运维知识库t;Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Padding" Value="0" />
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="LayoutBorder" BorderThickness="0.3,0.3,0.3,0.3" BorderBrush="LightCoral" CornerRadius="10" Margin="0,0.2,0,0.2">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition To="MouseOver" GeneratedDuration="0:0:0.1" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutBorder" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="#1BA1E2"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="Gray"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Opacity" Duration="0" To=".5" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected"/>
<VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutBorder" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="#1BA1E2"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutBorder" Storyboard.TargetProperty="BorderThickness">
<DiscreteObjectKeyFrame KeyTime="0" Value="0.6"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="NameTextBlock" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="#E09728"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RepostTextBlock" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="#1BA1E2"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CommentTextBlock" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="#1BA1E2"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FriendBorder" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="#1BA1E2"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="64" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="130" />
<ColumnDefinition Width="170" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="37" />
<RowDefinition Height="37" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" x:Name="FriendBorder" BorderThickness="2" Margin="10,10,0,10" CornerRadius="5">
<Image Height="50" Width="50" HorizontalAlignment="Center" VerticalAlignment="Top" Source="{Binding ImageUrl, Mode=OneWay}" >
<Image.Clip>
<RectangleGeometry RadiusX="5" RadiusY="5" Rect="0, 0, 50, 50" />
</Image.Clip>
</Image>
</Border>
<TextBlock x:Name="NameTextBlock" Grid.ColumnSpan="2" Grid.Row="0" Grid.Column="1" Margin="10,6,0,0" Text="{Binding ScreenName, Mode=OneWay}" Style="{StaticResource NameTextBlockStyle}" />
<TextBlock x:Name="DateTextBlock" Grid.Row="0" Grid.Column="3" Margin="0,6,0,0" Text="{Binding Date, Mode=OneWay}" Style="{StaticResource MidelTextBlock}" />
<TextBlock x:Name="RepostTextBlock" Grid.Row="1" Grid.Column="1" Margin="10,6,0,0" Text="{Binding RepostNumb, Mode=OneWay}" Style="{StaticResource SmallTextBlock}"/>
<TextBlock x:Name="CommentTextBlock" Grid.Row="1" Grid.Column="2" Margin="10,6,0,0" Text="{Binding CommentNumb, Mode=OneWay}" Style="{StaticResource SmallTextBlock}" />
<TextBlock x:Name="SourceTextBlock" Grid.Row="1" Grid.Column="3" Margin="0,3,0,0" Text="{Binding Source, Mode=OneWay}" Style="{StaticResource MidelTextBlock}" />
<TextBlock Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="2" Width="440" Text="{Binding Content, Mode=OneWay}" TextWrapping="Wrap" Margin="0,5,0,2" Style="{StaticResource PhoneTextSubtleStyle}" />
<Border Visibility="{Binding IsBusy}" Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="3" Background="Gray" Width="420" Padding="5" CornerRadius="15,18,30,10" BorderThickness="2, 3, 1, 0.5" BorderBrush="Chocolate">
<TextBlock x:Name="OriginalTextBlock" Width="400" Margin="0,2,0,5" Text="{Binding Original, Mode=OneWay}" TextWrapping="Wrap" Style="{StaticResource PhoneTextSubtleStyle}" />
</Border>
<Image Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="4" Stretch="None" Margin="0,2,0,2" HorizontalAlignment="Center" VerticalAlignment="Center" Source="{Binding ImageUrl}" >
</Image>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Think about pushing some of the work off into a thread, use Observable collections and try using Virtualized Lists in the UI to aid in the some of the speed issues.
This helped me a little. http://blog.landdolphin.net/?p=78
Sometimes I watch Silverlight TV and found a good tip.
Never let any image downloads happening while scrolling : Image downloading on long Listboxes should be controlled by the ScrollViewer state and position to optimize the network activity and also it would be effective to download the images in a queue based background thread system. This will ensure scrolling performance by downloading only the visible set of images, that too only when the scrolling activity stops.
Check this blog post.
Loading images off the UI thread will aid performance. An easy way to do this is with the LowProfileImageLoader from David Anson.
Peter Torr has created a LazyListBox which among other things uses a simplified template while scrolling. Definitely check this post out.
In looking at your template it seems massively complicated for a ListBoxItem. I'd strongly recommend reconsidering whether you could use a simpler template (maybe combining some of the text off the UI so that multiple fields can be bound at once) and/or reducing the amount of information you show for each item. Maybe moving some of the details to another page.
精彩评论