WP8中LongListSelector的scrollTo函数的性能滞后?

时间:2013-08-26 10:46:21

标签: c# windows-phone-8 scroll longlistselector

为了证明这里的问题是代码背后的代码

public partial class MainPage : PhoneApplicationPage
{
    ObservableCollection<ABC> listTest = new ObservableCollection<ABC>();
    // Constructor
    public MainPage()
    {
        InitializeComponent();

        for (int i = 0; i < 50; i++)
        {
            ABC conv = new ABC(string.Format("Test:{0}", i));
            listTest.Add(conv);
        }
        testLls.ItemsSource = listTest;
    }

    private void Button_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
    {
        testLls.ScrollTo(listTest[listTest.Count - 1]);
    }

    private void TitlePanel_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
    {
        Stopwatch st = Stopwatch.StartNew();

        testLls.ScrollTo(listTest[listTest.Count - 1]);
        st.Stop();
        Debug.WriteLine("tttt:", st.ElapsedMilliseconds);
    }

    class ABC
    {
        private string _name;

        public ABC(string aa)
        {
            this._name = aa;
        }

        public string Name
        {
            get
            {
                return _name;
            }
        }

        public Visibility GroupMemberVisibility
        {
            get
            {
                return Visibility.Collapsed;
            }
        }
    }
}

Xaml Code

     <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28" Tap="TitlePanel_Tap_1">
        <TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
        <TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>

    <!--ContentPanel - place additional content here-->
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <phone:LongListSelector Name="testLls" VirtualizingStackPanel.VirtualizationMode="Standard" >
            <phone:LongListSelector.ItemTemplate>
                <DataTemplate x:Name="dtRecievedBubbleText" >
                    <Grid x:Name="LayoutRoot" Background="Transparent" Margin="24 0 0 14"  HorizontalAlignment="Left">

                        <Grid.RowDefinitions>
                            <RowDefinition Height="14" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <Grid Grid.Row="1">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <Rectangle Grid.RowSpan="3" Fill="{Binding BubbleBackGroundColor}" />
                            <TextBlock Text="test" Visibility="{Binding GroupMemberVisibility}" FontSize="22" FontFamily="Segoe WP Semibold" Margin="12, 12, 0, 0"  />
                            <TextBlock Grid.Row="2" Text="{Binding Name}" HorizontalAlignment="Right" Margin="0,0,12,6" FontSize="18" />
                        </Grid>
                    </Grid>
                </DataTemplate>
            </phone:LongListSelector.ItemTemplate>
        </phone:LongListSelector>

    </Grid>

点击标题时,包含元素的长列表选择器会滚动到底部。当元素的值从30-50-100个元素变化时,观察到的时间是20ms,744ms,815ms。测试是使用诺基亚Lumia 620进行的。

在此示例中,项目模板非常简单,但在实际场景中我的项目templates are much more complex。因此,该场景所用的时间为1753ms for 100 elements

为什么这么大time differenceCan this be improved以任何方式?

还有其他人观察过这个吗?

1 个答案:

答案 0 :(得分:1)

有一种解决方法可以解决此问题。

从lls中提取视口,然后设置视口原点。

要提取视口,我们必须在xaml中添加样式

  <Style x:Name="llsMessagesStyle"  TargetType="phone:LongListSelector">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="phone:LongListSelector">
                    <Grid Background="{TemplateBinding Background}" d:DesignWidth="480" d:DesignHeight="800">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="ScrollStates">
                                <VisualStateGroup.Transitions>
                                    <VisualTransition GeneratedDuration="00:00:00.5"/>
                                </VisualStateGroup.Transitions>
                                <VisualState x:Name="Scrolling">
                                    <Storyboard>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VerticalScrollBar"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="NotScrolling"/>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Grid Margin="0">
                            <ViewportControl x:Name="ViewportControl" HorizontalContentAlignment="Stretch" VerticalAlignment="Bottom" Loaded="ViewPortLoaded"/>
                            <ScrollBar x:Name="VerticalScrollBar" Style="{StaticResource ChatThemeScrollBarStyle}" Opacity="0" Margin="2 0 2 0" Orientation="Vertical" HorizontalAlignment="Right" Width="5" ValueChanged="vScrollBar1_ValueChanged"  />
                        </Grid>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

在代码背后:

 ViewportControl llsViewPort;
    private void ViewPortLoaded(object sender, RoutedEventArgs e)
    {
        llsViewPort = sender as ViewportControl;
    }

 private void ScrollToBottom()
    {
        if (llsViewPort != null)
            llsViewPort.SetViewportOrigin(new System.Windows.Point(0, llsViewPort.Bounds.Height));
    }

通过这种方式,我们可以实现所需的功能。