2

I have a ListView with custom-made cells (items).

This ListView represents a conversation between two persons exchanging messages with my application. Each time a message is added, the conversation auto-scrolls to the last item.

I am facing a few "strange" issues :

When a user writes a rather long message (say, 10 lines), it can then take up almost the whole screen (meaning the space allocated to the ListView) which is normal of course but then the scrolling is somewhat broken.

First, when the list auto-scrolls to this message, a big white space appears below the item all the way down to the bottom of my ListView. See picture : Example whith big message and big white space

And when messages are very short (single line) : Example with short messages

Second, and in all cases, the scroll speed is way to fast. A single mous-wheel "stroke" (the feeling in your finger as you scroll) will move the scroll bar too fast : up to 4 small messages are scrolled ! That's too much !

So question is : how to control the scroll speed ? How to slow it down ? Why is there this big white space ? Thanks for the help !

[UPDATE 1]

Requested by @CurtisHx my ListView XAML is as follow :

http://pastebin.com/FFZGhi6w

I hope it helps understanding my issue!

Mackovich
  • 3,319
  • 6
  • 35
  • 73

2 Answers2

1

One way to be to set ScrollViewer.CanContentScroll="False" on the ListView. https://social.msdn.microsoft.com/Forums/vstudio/en-US/47bd6a75-7791-4c0f-93ae-931e9a6540e7/smooth-scrolling-on-listbox?forum=wpf

You will loose virtualization on the ListView, so keep the number of elements in the ListView to something reasonable. That should fix the fast scroll speed.

Text Alignment

The text is being aligned correctly. Currently, the parent container limits the width of the TextBlocks. TextBlocks will fill all of the horizontal space it can before wrapping the text. So for long messages, the TextBlock will expand horizontally until it hits the limits of the parent container.

In order to get the staggered text, the width of the message needs to be less than width of the ListView. If you widen the window, you'll see the text become staggered. Below is a snippit of code, pointing out the TextBlock that needs to be width limited.

<ListView x:Name="ConversationList" ScrollViewer.IsDeferredScrollingEnabled="False" ScrollViewer.CanContentScroll="False" ScrollViewer.VerticalScrollBarVisibility="Auto"
            BorderBrush="Transparent" Grid.Row="0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,10,10">
     <!-- Big Snip /!-->
     <ListView.ItemTemplate>
        <DataTemplate>
           <!-- Snip /!-->
           <Border Padding="0, 15, 0, 15">
              <Grid x:Name="ConversationBubble">
                 <Grid.RenderTransform>
                    <TranslateTransform />
                 </Grid.RenderTransform>
                 <Border Margin="70, 5, 70, 5" HorizontalAlignment="{Binding Alignment}" BorderBrush="#ECECEC" Visibility="Visible" Background="#F1F1F2"  Padding="10">
                    <StackPanel>

CurtisHx
  • 746
  • 3
  • 11
  • 30
  • It worked, scroll speed is not quite slow '^^ but as you said I lost virtualization and therefore the application is too slow and taking a lot of RAM because my `ListView` is loading a big `ObservableCollection` (from hundreds of items over to more than a thousand items). Is there any other solution ? Thanks for you help ! – Mackovich Jun 12 '15 at 12:36
  • @Mackovic One thing you could do is keep a small subset of the total `ObservableCollection` in RAM (what the user is viewing plus 50-100 items off each end). As the user scrolls, load the items that they are about to view. – CurtisHx Jun 15 '15 at 11:47
  • I have thought about it, much like iOS SMS app with "load previous messages" but I thought virtualization was implemented to avoir such a pattern. But I can try. Do you have sample where such a pattern exists ? Thanks ! – Mackovich Jun 15 '15 at 12:33
  • @Mackovich I've updated my answer to address the alignment issue. Virtualization does avoid the performance hit when dealing with large data sets, but it disables smooth scrolling. Your looking at a fairly simple caching pattern. The cache is bound to the `ListView`. Scrolling the `ListView` triggers cache updates. – CurtisHx Jun 15 '15 at 12:49
  • Thank you @CurtisHx but why do you talk about width when my problem seems to be about height ? The huge block of whitespaces take place below big messages. So I don't quite understand your point :( – Mackovich Jun 15 '15 at 13:39
  • Because I misunderstood the question. Is the big white space still an issue with `ScrollViewer.CanContentScroll = "false"`? – CurtisHx Jun 15 '15 at 13:50
  • this is really strange. I did try your solution `ScrollViewer.CanContentScroll = "false"` before and it rendered my app very slow (because of loss of `Virtualization` coupled to huge `ObservableCollection` (some can reach over a 1000 messages / items !). But now, my app ain't that slow except for very long conversation. And now scroll speed is slow (perhaps a tiny bit too slow but I must have been used to the very fast scrolling) AND white space bug seems to have disappeared ! :D Now should I work on cached ListView ? Where can I find guide with proper and clean pattern ? Thanks ! :D – Mackovich Jun 15 '15 at 14:15
1

I know this is too late, but:

VirtualizingPanel.ScrollUnit="Pixel"

DarkDuck
  • 88
  • 1
  • 5