I used 3 days on this problem, so i ask here.
I have a listbox which contains some receipt items. when i add first couple of items everything works fine :
but as soon as an item is added to listbox which "overflow" scrollviewer, random margin suddenly appears and i cant figure out how to get rid of it:
I tried different versions of .NET framework and in 4.5 this doesnt happen, but unfortunatly i am bound to .NET 3.5
Here is a link to "sandbox" application with same behavior : link
Does anybody have any ideas?
Here is requirements:
.NET 3.5
listbox must be virtualized because it can get very large.
You have set CanContentScroll="True" on ScrollContentPresenter which means you want item by item scrolling. If you set CanContentScroll="False" you won't see any empty space at bottom. Reason being now listBox will use pixel by pixel scrolling.
With item scrolling, listbox reserve some space to make sure next item comes perfectly in viewport. Hence, you see empty space at bottom.
However, setting it to false will disable UI virtualization. So, it's a kind of trade off between empty space and virtualization.
That being said, you mentioned that it's working fine in .Net4.5 which is not the case. I tried in your sample with 4.5 also and still the same result.
Related
I have a DataGrid which has a DataTable set as its ItemsSource.
The DataTable holds 24 columns and ~1600 rows (actually I will have to load alot more rows later on, but for now this is troublesome enough).
Despite setting virtualization for columns and rows active, the DataGrid takes around 30 seconds to display those 1600 rows.
After that, scrolling vertically works fine, horizontally is laggy, though you'd expect it the other way around.
If I run a memory profiler, I can verify that most of the memory used by the application comes from DataGridCells, Borders, ContentPresenters and Textblocks. To me, this indicates that the grid does not virtualize its rows properly.
Can anyone confirm that there's an issues with DataGrid's virtualization? Or is there some sort of infamous trap in the implementation of this control?
Looking forward to any kind of input/suggestions. Thanks :)
I've solved the issue.
My DataGrid was sitting inside a ScrollViewer, in which it would stretch infinitely. So it was fooled into thinking everything was visible, that's why it wouldn't virtualize its items.
I removed the ScrollViewer (DataGrid has scrollbars on its own anyway) and it works flawlessly now.
Hmm, ok I don't know why but obviously I've to add some glue text to post an answer here. Maybe, this SO answer will help you.
Edit
As additional advice I'd like to recommend you to think about your approach. Is it really necessary to add 1.6k+ items to a DataGrid? Perhaps you should think about deferred loading.
I am making a search app in wp7. Every record's data is bound to a user control. I have introduced an infinite loading instead giving page numbers. So when the number of instances of the UserControl is increased in the screen the transition from one page to another page (like the preview or settings pages) or coming back from that page to the current page is getting slower. I cannot change the design (infinite loading concept).
What are the ways to handle this scenario? How about changing the visibility of the controls? And reference or suggestion will be highly appreciated.
Note I tagged WPF and Silverlight because the binding happens the same way in them, expected those to have dealt with scenarios like these.
EDIT Check this question, which is asked by me. Because of having UserControl's in the listbox the vertical offset is not being maintained. So I had no option other than using ItemsControl with scrollViewer around it. ItemsControl contains a list of 5 - 6 usercontrols which intern have itemsControls inside them, I thought virtualization may not happen in such cases. Am I right?
In WPF, this is done by Virtualization
Using Virtualization, only one copy (or a few copies) of the UserControl actually gets created, and switching to another user control actually just swaps out the DataContext that the control is bound to. It doesn't actually create a new UserControl.
For example, if you have an VirtualizingStackPanel with 100,000 items, and only 10 are visible at a time, it will only render about 14 items (extra items for a scroll buffer). When you scroll, the DataContext behind those 14 controls gets changed, but the actual controls themselves will never get replaced. In contrast, a regular StackPanel would actually render 100,000 items when it gets loaded, which would dramatically decrease the performance of your application.
This question about Virtualizing an ItemsControl can probably get you going in the right direction.
Take a look at this post, I believe the solution provided by Rico is what you are looking for. :)
I have a ListBox that contains a number of User items that are DataTemplated to appear as UserControls in the ListBox. Each UserControl can be expanded in size. To start with, the ListBox is big enough to display them all in their unexpanded state. The problem that I have is that when a number of these UserControls are expanded together, they extend out of the ListBox's visible area. The ListBox does not recognise this fact and no ScrollBars appear, even when they are set to Visible.
I am using DoubleAnimations to alter the UserControl heights when the user clicks on a button in each one. Is there something that I have to do, or some setting on the ListBox that must be set to get it to register the size changes of the UserControls that represent its items and display ScrollBars when needed?
Edit>>>
I have tracked down the problem to a custom WrapPanel that I am using in the ListBox.ItemsPanel. When I remove it, or replace it with a standard WrapPanel, ScrollBars appear when required. I got the code for the Panel from a good article about creating custom WPF panels. Can anyone see what's missing from the code given in the article and why it might stop the ScrollBars from displaying?
I wonder whether ListBoxes normally do what you are expecting? You might try calling InvalidateMeasure/Layout on the ListBox if you know when the item sizes change, just to see?
I decided to write the custom WrapPanel code again completely and this time it worked correctly! When comparing the new version with the previous version, I could see that a + was missing from a += in a measuring calculation and so the Panel thought that the items were much smaller than they really were... hence no ScrollBars.
So, if you have this problem, check your measuring code carefully.
I'm having a problem with combobox popup (not sure if it's a problem of combobox). First when i click it, dropdown popup opens correct - upwards(there are about 50 items in it, and combobox is located in the bottom of the page, if it goes downwards, there would be only 5 items visible). But then if i select any item, and them open it again - it will open downwards and put items in a scroll. So how can I fix this and force popup open in the desired direction?
Are you setting the "MaxDropDownHeight" at some point? By default it is infinity but maybe setting to hard # greater than # in combo box might help.
Also I just tested this in SL4/Firefox and the combo box pops up each time (with or without a selected item). What version of SL are you using?
Well, what I've done - I subscribed to SizeChanged event of the Border element which is a child of Popup.Child canvas. In that method, I'm calculating space below and above the combo box and then setting Top offset using Canvas.SetTop method to that border and it's MaxHeight. Maybe I will post some code later.
I was having this exact same issue (actually with Silverlight 5, but the same behavior nonetheless). I tried various things with MaxDropDownHeight but that did not correct the problem.
#Walker the approach you mentioned in your answer sounded promising but I was not able to tell from your description how you actually implemented that.
In any case, I found a rather unlikely solution. I discovered that if I populated my ComboBox with ComboBoxItems instead of a collection of custom objects, then the dropdown/selection/direction issue does not occur. I've posted an answer here that goes into a little more detail.
If i create a datagrid on a silverlight page and bind it to a domaindatasource / ria services then i automatically get features like sorting/resizing/reordering of columns.
When i copy the exact same code into a usercontrol then the column headers lose these features. Is there something obvious im missing here?
Edit: I noticed that when i remove the associated pager beneath my grid, sorting gets enabled. The only question is why..
Alright.. the problem was that the pager was positioned on top of the grid (even though it looks like its positioned below the grid, its boundaries actually stretch across the whole grid), hence stealing all mouse and keyboard input. To resolve this one could set the z index of the pager to 0 and the z index of the grid to 1 (or perhaps use a stackpanel?)