2012-08-15 73 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

我建議你創建一個最簡單的函數,計算該包裹正文塊並綁定到一個高度。這樣一來,你在列表框中可變高度項目的效益,但得到使用虛擬化堆棧面板保持。