How can I determine which items in a GridView that are visible in the current scroll window? - windows-runtime

I have a GridView in my main app page and I want to do some background processing for the items that are currently in view for the user (high priority), and then of course do the other items too (low priority).
I can access the ScrollBar and the ScrollViewer, but none of them appear to tell me which of my items are in the current scroll window. I could try to hack this in, but it gets tricky because the number of row/columns change based on the size of the scroll region.
http://msdn.microsoft.com/en-us/library/windows/apps/br209745.aspx
http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.scrollviewer.aspx
Any help much appreciated!
thanks

There are two general ways you can do this. The first is to get the GridViewItem's AutomationPeer, which actually has a direct method to call. Class information here. I've had problems getting this to actually be usable though. Luckily, there's a second answer. It will require some math to be done, but it's doable.
Get the item container, in this case a GridViewItem, using the GridView's ItemContainerGenerator.
Get the GridView's ScrollViewer. You can search for FindVisualChild<T> methods, there are plenty around.
Do MyGridViewItem.TransformToVisual(MyGridViewScrollViewer).TransformPoint(new Point(0, 0)); This will get you the top left corner of the item, relative to the entire scrollable panel (known as its Extent) of the ScrollViewer (this will be important later).
This will return to you a Point object.
Next, we'll need to find out the range of X values that are currently being displayed in the ScrollViewer.
Note: If you're using a Vertical scrolling ScrollViewer, use the Heights. Horizontal, use the Widths. Both, use both. I am going to do my example using the Horizontal/Width.
Take the HorizontalOffset. This is your current 'lower bound' for the current viewable region.
Take the HorizontalOffset plus the ViewportWidth. This is the upper bound of the current viewable region.
If your Point.X is greater than your lower bound and less than your upper bound, then the item is visible.
If you further need to find out if the whole item is visible, do
this same calculation for Point.X + GridViewItem.Width.
Hope this helps, and happy coding!

You can use VisualTreeHelper to scan the visual tree as Nate suggests, but this is usually not recommended at runtime, especially for tight loops (e.g. checking lots of GridViewItem objects) or complex visual trees. You could do a minor improvement and only calculate the position of these items once and then do a simplified check based on the ScrollViewer.ViewChanged event and offset values, but that still seems a bit too complicated.
If your GridView uses an ItemsPanel that supports virtualization (e.g. the default WrapGrid) - most of the items that are actually loaded into GridView items are actually visible or not far off the screen, so if you bind your GridView to a collection of view models using ItemsSource - you can figure out when these items are accessed by binding to their properties or handling Loaded/Unloaded events on the ItemTemplate and call back to the view models to know when they are getting accessed. That way you can start loading these items when they first start showing up on screen and leave the logic to determine whether they should be loaded to the list control virtualization implementation in the platform.

Related

Hiding all columns while grid is loading in ExtJS

I am working with ExtJS 5 and am trying to hide the columns of an internally defined grid that extends Ext.Component. I will first explain the motivation behind this.
The thing is, while the grid is loading, the columns show up but then disappear after the loading. This leads to some inconsistency in the UI after the loading is done and the grid is finally rendered (a kind of glitch where columns disappear).
NOTE that by columns, I mean empty columns' titles while the grid is loading (the columns are only filled after the loading). Also, by grid loading, I mean the phase in which the grid data is not rendered, and only a spinner is shown on the grid content space.
The logic to show or hide two of the columns is included in the beforerender of a listeners:
beforerender: async function() {
// some async call to determine a global boolean flag for whether the two columns will be hidden or not; by default the two columns are showing
},
And for some reason, the rendering of the columns themselves, which depends on the global boolean flag set by the async call within the beforerender, does not fulfill the expected behavior of waiting for the async call to FINISH to have the proper global boolean flag in order to show or not.
Hence the inconsistency: the columns would show up at first while loading (and that's because the rendering of the columns does not wait for the boolean flag obtained asynchronously) but then the columns would be hidden (which is the intended behavior after determining the boolean flag).
After some digging around, I figured that a potential solution would be to hide the grid column titles themselves during the loading, so that the inconsistency is invisible (the user cannot see two columns that initially appear then disappear if they simply do not see the initial columns in the first place while loading).
Any suggestions or clues as to how to hide the columns while the grid is loading? I've looked around and saw that loadMask might be a potential path, but am not too sure as to how to implement this.
I believe this can be done pretty easily with through binding.
If the store is defined in your viewmodel, you can bind the loading property of the store to the hidden property of the grid column.
Here a fiddle that shows how to hide one column. The framework version is 6.5 but it shouldn't be too different on 5.X. If{gridStore.loading} bind does not work you can set a custom flag on your VM before and after store load. And bind the hidden property to that.
https://fiddle.sencha.com/#view/editor&fiddle/3f2j

How to find same logos, UI elements using sikulix

I am new to sikuli.
I am using it for functional test automation of my java spring standalone application. I am having the same set of images(logos) at multiple locations on the screen. and they are generated dynamically as per the application data. In that case how can I find and click on certain buttons/elements in the UI.
Example: like, share, comment text/image will be there several times in facebook page. in that how to we click on particular buttons out of all.(facebook is just an example) i want the similar solution for my application.
I think what you're asking is- given a case where the same image or UI element is present multiple times on the same page, how can I specify one of these elements in one location versus the same element in another?
The quick and easy way to do this would be to capture a larger picture, like as much of the window as you can, and click the image in parentheses after the click action; this opens a window reading file, matching preview, and target offset. Click target offset, use the mouse wheel to zoom in, and click on the exact point of the picture that you'd like to click.
It's possible to click in multiple places on a captured image, provided you use different click() commands, and you can set the target offset for each click() command without needing a new picture.
With just this one image, you can potentially click every square on the board provided you take the time to set the offset for each of the 64 click() commands it'd take to do so. http://files.chesscomfiles.com/images_users/tiny_mce/cigoL/Chessboard.png
The more difficult solution would be setting up regions, and searching those regions for the matching pictures, but for what you're looking for this should- for more about regions and setting it up check links below. Cheers!
http://sikulix-2014.readthedocs.io/en/latest/index.html
Based on your FB example you could use setROI() to focus on the top post on the page (imagine a rectangle that covers a complete post on the news feed) from there I would loop:
if exists(profile pic):
click(like button)
elif exists(profile pic 2): # If you are testing more than one user
click(like button)
else : type(Key.DOWN) #repeat as needed
Getting the next post into the ROI may be tricky but using WHEEL_DOWN may help if you can adjust your lines traveled with each wheel click on your system.

Easiest way to keep SSRS child elements in the same relative position when the parent is re-positioned?

I am trying to revise the layout of an SSRS report where I have several textboxes that are child elements of a rectangle.
When I reposition the parent rectangle down by x, all of the child textboxes maintain the same absolute position. Their "Location" (defined relative to the parent) decreases by x. I then need to reposition the child textboxes. Additionally, if any of these ever has a negative "Location" then the parent rectangle is then repositioned back up by x.
What is the easiest way to move everything in unison? I can Control-click everything and then drag them or use the arrow keys, but I want to position everything with precision and the "Location" field in the Properties window disappears when selecting more than one item. Is there a way I can avoid individually computing and typing in every "Location" value every time I have a small layout change?
I am using SSRS (11.0.3360.12) within the Visual Studio 2012 Shell. Thanks!
I'm having the exact same issue as you. I'd swear this used to work properly in earlier versions of Visual Studio.
The only thing I've seen that works is to edit the report file's xml directly in a text editor. e.g. look for the rectangle's element, then hand edit the value of "Top". Back in visual studio, let the report reload. Things should be ok, as long as you picked a reasonable value for "Top".
The only other available option to track position is by enabling ruler. Report -> View -> Ruler

Identify Visual event for a control

Is there any event to handle then element is visual to user?
Example: There are some UI elements in the listbox but all the items are not visual, when user scrolls the listbox then element is visual. I want to identify that visual to handle read operation.
If you use the LongListSelector, rather than a ListBox you can use the ItemRealized event to know when a virtualized item has been realized (loaded).
If you really want to know when items are visible you'll have to measure the size of the items (if they're not all the same and known in advance), the size of the area that the ListBox (or LongListSelector) takes up (it'll vary for WVGA/WXGA & 720P screens) and the ScrollOffset of the internal (to the control template) ScrollViewer to calculate which items are currently visible.

Complex Itemrenderer ( List within a List), Struggling with scrolling behaviour ins second list

I'm struggling for a while with a scrolling problem now.
I'm developing a flex application with some complex views. On of the views is like a word document view. It pulls data from the database and represents requirement specification. You can also edit the data within this "word" view. It should basically work like microsoft word. That view works fine but I have one issue with it: Scrolling!
To realize that view I have created a complex ItemRendererClass that contains another complex ItemRenderClass. Imagine it like that>
-List of chapters (itemrenderer)
- Chapternumber + ChapterTitle
- ChapterText
- Chapterpicture
- List of data (itemrenderer)
- Requirementnumber
- RequirmeentText
- Pictures
- lots and lots of attributes
-...
All in all I'm really happy how the "word" view&editor works but if I'm scrolling down and I'm over the second lists which represents the list of requirements I can't scroll anymore, when the mouse is out of the list item I can scroll again. What I have done is I use virtual layout on both lists for performance reasons and the second lists height is a 100%, so the second scroller never appears. I have tried to disable the second scroller of the second lists with "this.scroller.setStyle('verticalScrollPolicy', 'off')". But nothing happens. What i want is a normal scrolling behaviour, means that it shouldn't matter where in the "wordview" the mouse is I want to scroll like it is one list and not 2 lists.
Ok, solved it. Was really easy actually. I just created a skin for the second list where i deleted the scroller component. In addition to that i had to sign the scroller from the second list to the parent List. Works like a charm so far