2012-08-15 49 views
10

我有一个奇怪的行为VirtualizingStackPanel。我有一个包含TextBlockTextWrap="Wrap"的项目列表。下面是代码:VirtualizingStackPanel和TextWrapping错误? Windows Phone

<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> 

它的工作原理相当不错,但如果我尝试滚动速度非常快(在模拟器使用鼠标,而不是prommatically)有一定的滞后在滚动,可能HorizontallOffset有时计算错误,并在底部有很奇怪的结果(见图像,右图显示了正常行为)。

scroll bug

研究后,我在组合VirtualizingStackPanelTextBlock.TextWrap="Wrap"想通了这个问题,如果我的这对夫妻都工作正常删除一个元素。

但我需要虚拟化,因为大项目计数,和TextWrap正确的文本显示。

所以我想自己制作虚拟化面板的实现,请问能否指导我,怎么做,或者如何解决当前的问题?

UPD:问题:(!)
第一个两个图像ListBox已滚动至底部(它不能被向下滚动任何更多),但元件放置不当,在右侧示出正确放置图片。只有在您滚动得非常快时才会发生这种情况。

UPD2:感谢米兰Aggarwal。他提供了我的问题here的一个很好的例子。看起来这真的是一个错误ListBox。解决方法,提供不符合我的方案,因为我需要与ListBox项目内的控件进行交互。 现在我想抓住ManipulationCompleted事件,并检查它是否是Inertial,如果这样就意味着滚动和我焦点设置到页面:

void messagesList_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) 
    { 
     if (e.IsInertial) 
      this.Focus(); 
    } 

附:谢谢你的好运祝福;)

+4

OFF_TOPIC:在VK比赛好运=) – 2012-08-17 08:42:17

回答

1

第二个屏幕有什么问题?你的意思是在最后一条消息之后有大的空白空间最后一条消息没有放在页面的底部?我是否正确?

其实我并没有试图去模仿你的代码和错误,但我的观点是,因为使用的是第三方库(Silverlight工具包)在你的应用,为什么不使用Coding4Fun Tools呢?

我写这个虚拟类:

public class Message 
{ 
    public string Time { get; private set; } 
    public string Content { get; private set; } 

    public Message(string time, string content) 
    { 
     Time = time; 
     Content = content; 
    } 
} 

然后我把这个假的代码在主要页面的构造函数:

var _messages = new ObservableCollection<Message>(); 

for (int i = 0; i < 50; i++) 
{ 
    _messages.Add(new Message("12:40", "Teh very long string which should be wrapped. Pavel Durov gives WP7 Contest winners less money than he did for Android/iOS winners. FFFUUUUUUUUUUUUUU ")); 
} 

this.ListBox.ItemsSource = _messages; 

而且在XAML我把一个列表框与工具的聊天泡泡控制:

<ListBox x:Name="ListBox"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <c4fToolkit:ChatBubble> 
       <Grid> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="Auto"/> 
         <RowDefinition Height="Auto"/> 
        </Grid.RowDefinitions> 
        <TextBlock Grid.Row="0" 
           Text="{Binding Content}" 
           TextWrapping="Wrap"/> 
        <TextBlock Grid.Row="1" 
           Text="{Binding Time}" 
           HorizontalAlignment="Right"/> 
       </Grid> 
      </c4fToolkit:ChatBubble> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

我跑了,看到没有奇怪的行为,也许有点滞后。 有结果:

dat pic is huge

希望我做了一些帮助。


乐趣的比赛,我会自己参加,但不相信,这将是能够做出像样的客户端1.5个月。

+0

谢谢,我会检查了这一点。很好的示例文本:) – Alexander 2012-08-17 09:59:50

+0

不,这个控件也有这个问题,只是让物品内部有不同的高度和位置按钮,例如点击任意按钮并滚动,这会重现bug – Alexander 2012-08-17 14:51:28

+0

我刚刚记得我遇到过这个问题在我上一个项目上,我毫不怀疑它存在于我目前的项目中。但是这个错误出现的条件(快速滚动)对我来说并不正常,所以我没有尝试修复它。 =) – Oleg 2012-08-17 15:07:37

9

中序来克服滚动,你需要虚拟化您的滚动控制黑色的发生。对于您应该继承IList并创建自己的类似的CollectionObservableCollection中,你将不得不重写取决于你的缓存需求的默认索引,同时保持你的项目的缓存。我觉得这可能是你在找什么: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。我想这将使用虚拟化本身来解决。希望它可以帮助

+0

谢谢你,你回答正确的方向我 – Alexander 2012-08-17 15:15:35

1

什么是在第二图像的问题?是不是该BlackArea出现了在所有的,或者是它的滚动型没有“反冲”滚动结束,以填补内容黑色区域后?

它是知道这一点是至关重要的,因为...这效果简直自然的WPF/WP7 .. BTW。滚动条应该“反冲”过滚动之后,但似乎有一个bug,有时甚至忘记去做。

我这么问是因为黑色/白色区域往往不仅对WP7,但和任何地方有一个XAMLish ScrollViewer中有惯性滚动。你看,滚动时比平台快可以提供新的项目,你只需滚动预先计算项目之外,一旦你“而不是”滚动很远,慢慢传入项目突然发现,有没有更多的项目,因此 - 回空区..

出现这种情况主要是当一些情况发生在一次:你快速滚动(耶),您的绑定缓慢(过于复杂的表达式),模板渲染速度很慢(复杂的非可重用的UI模板) ,绑定不知道有多少项目有(绑定到IEnumerableIList! - >没有.Count之间的信息),或渲染犯规知道多少高度保留一个项目(该项目不等高,但eveyr项目必须计算确定自己的确切高度)。

如果你要纠正它,你必须有这些原因争第一,或者您必须实现自己的滚动或侵入虚拟化堆栈面板和BindingSource的物品的供给与滚动,让滚轮猜总高度同步更好:比如,只显示一次一个小项目,听滚动事件,并添加/删除列表中的头/尾项目的下一组动态。这将不会允许快速滚动解决的问题:))) ))

我认为,制约了项目的高度是最简单的方法。你能不能做一些聪明,使项目实际上恒定大小?

+0

不,项目必须是不同的高度,他们必须显示他们的所有内容。米兰Aggarwal发布了一个伟大的链接与问题演示 – Alexander 2012-08-17 14:55:22

+0

我明白,我有相同的问题有很多应用程序。真的,你必须关注我指出的几件事情。然后,一些组合只是强制这种效果。另一件事,你可以尝试禁用“惯性滚动”并保持正常的平滑滚动,但这通常也是不利的,因为这会降低“感觉”。如果没有看到确切的情况,我不能帮助你。我只能指出常见的原因。它本身的问题全在于代码,绑定和呈现的性能。 – quetzalcoatl 2012-08-17 19:33:02

1

我建议你创建一个最简单的函数,计算该包裹正文块并绑定到一个高度。这样一来,你在列表框中可变高度项目的效益,但得到使用虚拟化堆栈面板保持。