Is it possible to check has item already been rendered (therefore visible to user) on screen? I am trying to create image control with automatic "image swapping animation" but when I have hundreds of images on page (for instance in GridView) performance is terrible. I'd like to know which controls are visible to user so I'd run animation only for them.
You can check the item's position by getting UIElement.TransformToVisual() and then using it to get the coordinates of the item relative to the clipping frame of the ScrollViewer in your GridView, but the performance of it might not be very good if you check it on each ScrollViewer view change event and could use some optimization, which would also be difficult if your GridView supports virtualization, which it needs to if you want to be able to scroll through hundreds of images.
Oleh's suggestion is your best best if you don't want to spend days or weeks figuring it out. Your GridView will be virtualized if you use a virtualizing panel for its ItemsPanel property, e.g. a WrapGrid (Windows 8.0 default) or ItemsWrapGrid (Windows 8.1 default). Note that VariableSizedWrapGrid is NOT virtualized.
Related
C# and wpf.
I have an ItemsControl that have many items(Images) and will load more if you scrolling down.
Is it possible to calculate location of an control in ItemsControl, when it's shown up?
Is there any existing event for this?
for example, ItemsControl has 200 items, and you seeing the first item.
is possible to know, when item 120 will be seen?
I want to create an smooth Image list control, so I can't show all items at once, so I thought this might be an good idea.
I have the following application:
I am developing a Windows Store app in which I need to show a big grid filled with buttons. The content of the buttons are some numbers and when I click any of them, I open a Popup with editor, where I edit those numbers. For that purpose I use a GridView, I put an ItemsWrapGrid as ItemsPanel. This makes the grid look exactly as I need it to look. I put the GridView inside a ScrollViewer, because I need to scroll the grid in both directions, since it has a lot of elements. Also I need to have the pinch-to-zoom effect that the ScrollViewer gives out of the box. I need to change the ItemsSource for that GridView when the user chooses different source in a ListView next to the GridView.
The problem:
Putting the GridView inside the ScrollViewer breaks the Virtualization inside and this has a major impact on my performance. When I switch the ItemsSource of the GridView, it takes more than 3-4 seconds for the rendering and during that time, the UI is frozen.
My question:
How can I keep the awesome stuff that the ScrollViewer gives me and also keep the virtualization? Because when I remove the ScrollViewer, changing between the ItemsSources happens almost instantly.
Any idea?
You'll be best off implementing virtualization yourself since you're trying to use the GridView far from the use cases it was designed for.
Put a Canvas in a ScrollViewer that does both pan and zoom and handle view change events on the ScrollViewer by laying out item containers inside and around the viewport. Avoid unnecessary changes too, so keep containers in place if they are to stay realized between view change events and recycle containers that are leaving the viewport neighborhood.
I am making an app for windows store; Like in c# we used Scroll bars to move down to the end of page and view all content, How can we do it for windows store? Like how to arrange data and use scroll bars to move to right and view all the data?
Typically you don't use ScrollBar controls directly and rather put your content in a Panel (usually Grid/StackPanel/Canvas) and put that panel inside of a ScrollViewer. Make sure to set Horizontal/Vertical-Scroll-Mode/BarVisibility and ZoomMode properties to match the direction of scrolling you want supported.
The benefit of using the ScrollViewer instead of ScrollBar is that you get smooth panning with touch that the platform handles for you with the Direct Manipulation layer that is not exposed to you in WinRT/XAML and also handles all the other inputs in a standard way.
Also if you are dealing with a list of items you want to scroll through, especially when the list is long - you would use some ItemsControl subclass - typically a vertical ListView for long, mostly text content lists or horizontal GridView for lists of richer media items. The benefit of using those is that they handle list virtualization for you - i.e. for lists of thousands of items you only get few item containers generated for the items currently visible in the control's view port and ones that are near the view port so they are ready when you scroll to them.
The templates of these list controls internally already have a ScrollViewer and the ScrollViewer's template has ScrollBars inside.
I have a ListBox that contains two columns - column one contains a Toggle Button, column two contains an Expander with multiple controls within it. If the expander is collapsed, the overall scrolling of the ListBox works fine. However, if the Expander is open and the expander contains a large quantity of items, the ListBox will scroll the entire row size, often not showing part of the expander list.
This would be similar to placing an image in the list box that is larger than the viewable area of the list box. In this case, if you click the scrollbar, you would want to "step" down the image, without it scrolling off the screen in one click.
Is there a setting for the ListBox that will allow the partial scrolling as I've described? My listBox is defined in a xaml, the controls are added via C# code.
Have you tried turning on smooth scrolling by setting ScrollViewer.CanContentScroll to false? This is what controls whether the ScrollViewer will scroll an item at a time, or smoothly with partial items available.
"ScrollViewer currently allows two scrolling modes: smooth
pixel-by-pixel scrolling (CanContentScroll = false) or discrete
item-by-item scrolling (CanContentScroll = true). Currently WPF
supports UI virtualization only when scrolling by item. Pixel-based
scrolling is also called 'physical scrolling' and item-based scrolling
is also called 'logical scrolling'."
(From this answer).
If you have a lot of items in your ListBox, this may not be an ideal solution, however, because it turns off Virtualization, and therefore may have a performance impact. Take a look at this answer to see more about smooth scrolling and virtualization. (One answer suggests a hack that allows for smooth scrolling and virtualization).
Basically, I have a SemanticZoom control with a GridView inside it, and the GridView has a custom control inside it, but for simplicity, let's assume it's a simple red Border. The problem is that I'm trying to handle the Border's manipulation when scaling (set ManipulationMode to Scale) so that I can know when the user does a pinch out gesture and "Zoom In" into the Border (which is really another page), but by handling the Manipulation, I lose the ability to (1) use the SemanticZoom and (2) Scrolling the grid.
If you have used the Windows 8 photo app, you'll notice that they implement this feature somehow. If you pinch in into an image, the Page will go into SemanticZoom, but if you pinch out it will go into full screen mode. I want similar functionality, but I don't know how to achieve it.
Any ideas?
Thanks in advance.
I will use 2 SemanticZoom controls to achieve Photo App Effect.