我对VirtualizingStackPanel
有一个奇怪的行为。我有一个列表,其中包含包含TextBlock
和TextWrap="Wrap"
的项目。这是代码:
<ListBox x:Name="messagesList" ItemsSource="{Binding Messages}" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
...
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<CheckBox Style="{Binding Own, Converter={StaticResource MsgTypeToStyle}}"
Tag="{Binding TimeString}"
IsEnabled="True">
<TextBlock Text="{Binding Content}" TextWrapping="Wrap"/>
</CheckBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
它的效果很好,但是如果我尝试快速滚动(在仿真器上使用鼠标,而不是过快地滚动),则滚动会有些滞后,可能
HorizontallOffset
有时会计算错误,并且最后以非常奇怪的结果结尾(请参见右图)图片显示正常行为)。经过研究,我发现结合使用
VirtualizingStackPanel
和TextBlock.TextWrap="Wrap"
时出现了这个问题,如果我从这对夫妇中删除一个元素,则它们都可以正常工作。但是我需要进行虚拟化,因为项目数量很大,并且需要
TextWrap
才能正确显示文本。因此,我考虑自己制作Virtualization Panel的实现,请您指导我,如何执行此操作或解决当前问题?
UPD:问题:
在前两个图像上,
ListBox
已经(!)滚动到底部(不能再向下滚动),但是元素放置不正确,正确的位置显示在右侧图像上。仅当您滚动得非常快时,才会发生这种情况。 UPD2:感谢Milan Aggarwal。他很好地说明了我的问题here。似乎确实是
ListBox
中的错误。提供的解决方法不适合我的情况,因为我需要与ListBox
项内的控件进行交互。现在,我正在 try catch
ManipulationCompleted
事件,并检查它是否为Inertial
,如果是,这意味着滚动,并将焦点设置到页面上: void messagesList_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
if (e.IsInertial)
this.Focus();
}
P.S.感谢您的好运;)
最佳答案
为了克服滚动时出现的黑色现象,您需要虚拟化滚动控件。为此,您应该继承IList
并创建自己的Collection
(类似于ObservableCollection
),在其中您将不得不根据缓存要求覆盖默认索引器,并同时维护项目的缓存。我觉得这可能是您要寻找的:http://blogs.msdn.com/b/ptorr/archive/2010/08/16/virtualizing-data-in-windows-phone-7-silverlight-applications.aspx
该页面上有一个示例项目。试试看。
我也觉得您正在面对http://blog.rsuter.com/?p=258这个问题。我想这将使用虚拟化本身解决。希望能帮助到你