Partilhar via


Determining the Visibility of Elements inside Scrollviewer

A ScrollViewer is a very handy control. One of the problems, however, is bringing a control to Focus or scrolling to the item. If this is done manually, that’s not an issue. But programmatically hmm.. You can hit some issues. The simplest way is to call the scrollviewer’s ScrollToVerticalOffset() with the offset being the Y co-ordinate. But what if the element is partially visible and you do not want it to scroll. This would require determining if the element is in the ScrollViewers viewport. The way to achieve this is simple.

Suppose ContainedObject is the element inside the Scrollviewer (ScrollViewerObj)

 

// position of your visual inside the scrollviewer   

GeneralTransform childTransform = ContainedObject.TransformToAncestor(ScrollViewerObj);

Rect rectangle = childTransform.TransformBounds(new Rect(new Point(0,0),ContainedObject.RenderSize));

//Check if the elements Rect intersects with that of the scrollviewer's
Rect result = Rect.Intersect(new Rect(new Point(0, 0), ScrollViewerObj.RenderSize),rectangle);

//if result is Empty then the element is not in view

if (result == Rect.Empty)

{

//....

}

else

{

//obj is partially Or completely visible

//skip or bring obj in view.

}

 

 

 

Share this post

Comments

  • Anonymous
    January 19, 2007
    If the element is a FrameworkElement, couldn't you use the BringIntoView method?

  • Anonymous
    January 19, 2007
    that would not work if you do not want to bring the partially visible object completely into view.

  • Anonymous
    January 20, 2007
    Could you explain why it would not work? I mean, yes if you wanted to only scroll vertically then you need to do as you listed but if you just want to ensure that an element is in view, that is what the BringIntoView method is designed to do. It allows an element to request to be brought into view without having to worry about what type of container its in and allow the container to perform the action necessary to bring it into view. The ScrollViewer hooks the RequestBringIntoView and brings the element into view if its a descendant of the scroll viewer.

  • Anonymous
    January 20, 2007
    If its just trying to bring the object into view you are right. BringIntoView always tries to being the whole onject into view. But if the objective is to only bring the object into view if it is not visible then you cannot do this by BringIntoView. A simple scenario could be you are viewing a list of thumbnails and in the view you have 3 images with the image at the bottom being of interest. Now if you call BringIntoView it will try to scroll so that this image is at the top  completely in view.

  • Anonymous
    January 20, 2007
    BringIntoView does not force the item to be displayed at the top (unless the object is so large that even when at the top it would not be fully in view). It just scrolls enough so that the item is in view. If the item is below the visible area, it would scroll it such that the bottom of the element in question is at the bottom of the visible area. I'm not sure what you're point is about being "visible"; I assume you mean in view in which case if the item were already in view, it would do nothing. Also, if the goal is to bring a certain portion of the element into view, you can use the overload that takes a Rect which indicates the portion within element on which BringIntoView is called that should be brought into view.

  • Anonymous
    January 20, 2007
    Hi Andrew, the point of the post is to show how someone could decide if the object is visible (partially/completely) in the viewport. If its partially visible, a call to bringtoview tries to bring the complete object in view - this may or may not be the objective. There might be several ways of acheving the result - the post documents one approach on  how the user could decide whether the obj is in view or not... Scrolling or calling bringintoview depends on the scenario. :)