I have some trouble with ListView where the ItemsSource can be very important (over 5'000 items).
My application is that of a Chat Application consisting of two ListViews.
One on the left, the thread ListView showing a list of active thread
(conversation)
One on the right, the conversation ListView showing all messages exchanged.
I am using the DataTemplatepattern so that each item of my conversation ListView is customized as follow :
A chat Bubble using Coding4Fun package : http://www.geekchamp.com/articles/getting-started-with-the-coding4fun-toolkit-windows-phone-chatbubble-control
Each Chat Bubble has two TextBlock (one for the message content, the other for the timestamp).
Later, I intend to add pictures to this messages.
When user clicks on a conversation from the left-panel ListView, the main conversation ListView is loaded with the corresponding conversation (observable) collection.
If that collection is particularly big (in one case, I have more than 10'000 messages), the conversation ListView does show the content, but as soon as a switch to another thread and back to the previous, the content does not show anymore, although it's here, it's loaded. Starting to scroll, makes the ListView flickering and the content, therefore, is visible but severly flickering. If I stop scrolling, no content is showed, showing an empty list.
Further tests showed that this problem occurs only with large collection in concordance of usage of ScrollIntoView() method: indeed, I whish to show the bottom of my conversation ListView each time a user clicks on a thread so that he can read the last messages instead of the oldes, therefore saving him to have to scroll all the way to the bottom, each time.
I confirmed this issue by commenting out the line where I make the ListView to scroll to the bottom. The flickering problem is gone.
Finally, as I wrote my question, I found a stackoverflow question that seems to be my case: Windows Store universal app - ListView oddity
Unfortunately, the solution is not very clear. How can I solve my issue ? How should I use VirtualizingStackPanel/>inside a ListView that uses alread <ListView.ItemContainerStyle>, ListView.ItemTemplate>and <DataTemplate> ?
The solution to my flickering problem and how to implement UI Virtualization (normaly introduced in Windows 8.1) as described here https://www.microsoftpressstore.com/articles/article.aspx?p=2216995&seqNum=4 is as follow :
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
To be placed within a ListView scope !
Orientation must be defined ( Vertical | Horizontal ) otherwise a Critial Failure occurs !
UI Virtualization enhance large GridViews and ListViews so that huge amount data can be effeciently loaded without slowing down the UI nore blocking it for too long.
Honnestly the answer to your problem would be to redesign your application.
Never should there be so many items in a listview. You need to filter out some results
Example : Sort the question names /types/ etc and only show the corresponding (such as tags in Stack Overflow)
Only show the last lines of the conversation when you load it and allow the user to load more (like facebook's messenger)
Take a look at this C# listview maximum number of rows
As the answer says. The amount of items in your listview should be limited by common sense. 5k items in one listview is an incredibly high amount for a user to scroll through.
I am assuming your bubbles are in some kind of list or array. You can use Linq to get what you want. Take a look at this LINQ query to select top five
Related
I have performance issue with my wpf application. I am displaying a form with many textboxes (like 130 or so). It is a software where user can configure many states in three stages of a distiller machine. The form consists of three sections (stages), each can have different number of states and some fixed amount of properties to setup. Each state gives user option to set 6 values(via textbox).
So if a stage consists of for example 7 states, then it has 7x6 + 5 (fixed amount) = 47 textboxes. So the 3 stages can show 141 textboxes (it will be less because only two stages can be visible rest can be scrolled down).
https://pasteboard.co/I8LiVxG.png
To display the states for each stage I am using ItemsControl with ObservableCollection binding. This is a bottleneck in VS performance profiler as the application spends too much time in layout (orange color).
When I swap the ItemsControl with StackPanel and fixed amount of states, the problem is gone.
https://pasteboard.co/I8Lhu37.png
Of course the UI is a bit more complex, there is a listbox with distiller processes and each process is displayed in detail with stages and states. I have also viewmodels and bindings, the states count can be changed runtime so there is ObservableCollection bound to the ItemsControl. None of this is causing the issue, i tried to turn off most of the mvvm code that resets the values or recreates collection of states.
<ItemsControl Grid.Row="2" ItemsSource="{Binding Cuts}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:RunConfigControl DataContext="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
In the code above RunConfigControl is just a Grid with 6 textboxes and labels. Cuts is the name of the ObservableCollection.
What is the difference when I use just a fixed amount of controls in StackPanel and when I use ItemsControl with collection. There is also StackPanel when i look at the visual tree.
Also I know that the controls are rendering when not visible (I am not using virtualization) but there are not many states (between 2-10) and the number of stages is always 3. Also all the states need to be visible I don't need to show 3 states and scroll for 7 others. Also I see two and half stage on the screen so the one half of last stage rendering despite not visible should not be the problem.
Thanks for any kind of help
I would use an editable DataGrid. This could be bound to your observable collection. The benefit is that a textbox is only create when editing, otherwise a textblock is used. You can style your grid to look like your picture. You can also set the cell to edit mode on mouse down so only a single click is needed to enter a textbox (cell).
Here is an example. You could get the look you want by hiding the headers, and adding some cell padding.
I'm new to Xamarin Forms, and am trying to create a page that has 4 sections of read-only data, one of which is a list of clickable items. In addition, the top section needs to be stationary (always on top).
My initial attempt was to use various StackLayouts, with a ScrollView to control this. There was much advice against putting a ListView in a ScrollView. After some struggles I got it to work, but then ran into an odd app crash on the ListView binding the second time a page is loaded (simple labels with the same binding are fine).
So my question is, should a ListView be used when many other elements are also on the page? If so, should the header and footer of the ListView contain the other controls, effectively making the ListView the root control? Is there an alternative suggestion to get a bound, clickable list on a page with other controls? Or maybe I'm running into difficulty simply due to the ListView needing to be in a ScrollView?
My app shows newsfeed from social network. Every feed has different attachments - images, video, audio, etc, - so every feed has different height. Newsfeed shows in listbox using template selector. I read MSDN and as i can see - i broked almost all rules how to use listbox (non fixed sized items, nested listboxes, and so on). As result - i have laggin listbox, which jumping from item to item when it wants. So, if MS couldn't make a listbox, which can normaly works with dynamic items, what sould i use to get smooth scrolling by items?
UPD: Why minuses? Can you explain? Its a bad question? I think not only for me its important.
You can try the ItemPresenter control with a ItemTemplate.
You could try stackpanel inside a scrollviewer.
Also you could make images and text load only when scrollviewer gets close to displaying that item, not load everything all the way at the start.
This reduces internet traffic, loading time and the lag while scrolling. Ofcourse it will take some of your coding time, but believe me - it will be well worth it! Most services use this thus cutting server load and traffic.
Check if that helps!
I have a scroll view that holds about 614 Grid Controls (it's used as a book index, with each grid points to certain place at the book), inside each grid about 4 textblocks showing information about that choice....
The content is static inside all the textblocks. The thing is, when loading all that content , the phone becomes quiet unresponsive for a while... it takes time to load that page and navigate to it from another pages.
I want another solution for all that items to be shown correctly and also each grid view of the 600 has it's own clicked event handler to be able to point it to the page in the book.
I read about some hard ways to do that, I was thinking maybe I can only load the index as a very "tall" image with the index written inside it and then detect where the user tapped and calculate the index page from that ? is that efficient? or maybe there's something else ?
What is happening is the scroll view is iterating through all 600 items to measure the height of each entry so that it knows how big to render the scrollbars.
It is better to use a ListBox in this case before WP7 will only render the visible items only. Even then, I've heard of performance issues when you hit 2000 rows.
If you are interested in how virtualization works, Samuel Jack has written one that scales well (albeit not for WP7), but he has detailed writeups on the decisions he made.
https://github.com/samueldjack/VirtualCollection/tree/master/VirtualCollection/VirtualCollection
See his write ups on:
Data Virtualization and Stealth Paging
Silverlights Virtual Collection
A Virtualizing Wrap Panel
Assume two observable collections A and B. Bind your collection A to your UI. Every time fill you collection B. Everytime whne UI is refreshed clear A. Once the UI is loaded, via an event trigger start filling of items from B -> A, as it is an Observable Collection and if you are using INotifyPropertyChanged correctly the items will start appearing on the UI one by one. (Lazy Loading). You may alter this approach according your implementation. I myself am following this approach. Hope it helps for you too.
In my WPF application, I've got a screen with a tab control. Five of these tabs contain datagrids which need to display a large number of rows (at least 5000). The tables are bound to ObservableCollections of Part objects. Each row displays around 20 points of part data. My problem is that, after the user enters the information they require and generate the data, clicking on a tab causes the application to hang for 30-60 seconds. After this the datagrid finally loads, and with the right virtualization settings, they perform at an acceptable rate (not exactly fast, but not too slow). If I disable virtualization, the program uses up way too much memory, and the loading time isn't really affected.
The most offensive tables consist of about half a dozen template columns. Each template contains controls inside a stackpanel or a grid; basically each row is split into two, like a double-row. This layout is a requirement, and paging is probably not something that the customer is willing to accept.
This is the most important screen in my application and I'm pretty much at a loss about making this work. Is there anything I can do to speed up this process? Perhaps ObservableCollection is the wrong choice?
Can you please provide more insights...
Can you check how much time is spent in "generating" the 5 collections of 5000 rows each? (this is what I assume you are saying)
With virtulaization "on" what is the UI loading time "after" we assign the collection to the items source?
What happen if you bind "ItemsSource" to the respective datagrid only when the tabItem is actually Visible \ Selected?
Do you datagrids have default sort member path? Grouping? Filter Paths?
These are a few things I would target to start on the issue.