WPF Adorner Clipping - wpf

I have an ItemsControl in a ScrollViewer. The items in the ItemsControl are expanded to a DataTemplate which basically consists of an Adorner.
Now the problem is, when scrolling, the Visual Children of the Adorner are visible outside the ScrollViewer. Lets say I scroll from the Horizontal Offset 0 to 100, the Visual Children of the Adorner move to the left and are visible next to the ScrollViewer, although they should be hidden. Setting ClipToBounds on the ItemsControl or the ScrollViewer does not work.
I understand, that Adorner are rendered above all elements z-order wise, but they really shouldn't be visible in such cases as with the ScrollViewer. The adorned Element by the way behaves like expected and is not visible through the ScrollViewer.
Is there any easy way to "clip" the Adorners, so that they are only visible in the visible scroll area?
Thanks,
Andrej

Setting ClipToBounds on the containing control is not enough. You must set the adorner's IsClipEnabled property too.

I've encountered the same problem when subclassing the WPFToolkit DataGrid to draw an adorner around the current cell.
The content of the ScrollViewer is rendered by a ScrollContentPresenter instance. ScrollContentPresenter has its own adorner layer, which is accessible through the ScrollContentPresenter.AdornerLayer property.
I found that my adorner correctly clips if I add it to that layer.

My solution was to push a clip region onto the drawing context, render whatever I needed, and pop the clipping at the end, like this:
drawingContext.PushClip(new RectangleGeometry(new Rect(0, 0, this.AdornedElement.RenderSize.Width, this.AdornedElement.RenderSize.Height)));
// continue drawing
drawingContext.Pop();
You can plug this in into any Adorner, the bounds are already available as part of the element.

Related

Include Adorner in ScrollViewer scrollable region

I currently have an Adorner inside a ScrollViewer. Objects at the bottom of the scrollviewer can sometimes display a large adorner below them. Unfortunately, that adorner is not included in the ExtentHeight of the scrollviewer, so the lower portion of the adorner is clipped by the bottom of the scrollviewer's viewport.
Is there a way to get the adorner layer's contents to be included in the scrollable region of the scrollviewer?
I'm afraid the consensus from other sources and hours of investigation seems to be that what I mentioned simply isn't possible. My solution has been simply to detect the last item in my ListBox and automatically add a margin to its bottom when my Adorner is being displayed. It's a bit of a hack, but it achieves the desired behavior mentioned above.

Panning contents of a Canvas in a ScrollViewer

I'm trying to implement panning within a Canvas within a scrollviewer like:
<ScrollViewer>
<Canvas>
<!-- some visual elements here -->
</Canvas>
</ScrollViewer>
I want a click and drag operation within the canvas to cause the contents of the canvas to move. I've tried handling the MouseDown, MouseMove, and MouseUp events to do a translation in the manner described here but it hasn't worked.
Any ideas?
You can't do that with your current setup. A Canvas will stretch beyond its parent container and the scrollviewer won't know the size of the Canvas (it will tell it it doesn't need to scroll) and therefore can't create the handles.
If you want to skip with that set up change the canvas to a grid and use the Vertical Scroll and Horizontal Scroll and associated set properties to move the visible section of the grid around.
Try giving your Canvas a set Width and Height and give it a background color (Transparent should be fine) and see if that helps you get your mouse events.

Silverlight scaletransform adjust scrollbars

I have the following UI element hierarchy: UserControl>ScrollViewer>Canvas. I am drawing lots of stuff on the canvas, and it becomes larger than the UserControl, at which point the ScrollViewer displays the scrollbars. So far, so good. Now I apply a ScaleTransform to the Canvas (say, 2.0, making everything twice as large). However, my scrollbars to not adjust, so I can now only scroll half-way across my enlarged canvas. How do I get my ScrollViewer scrollbars to adjust when I apply a scaletransform to the canvas being displayed within the ScrollViewer?
Your problem is that the ScaleTransform is a RenderTransform and not a LayoutTransform. The size it reports to the ScrollViewer is the same size regardless of what the scale is.
One solution I've used in the past to get around this is to nest the Canvas in another Canvas. You can then in code change the size of the outer Canvas to reflect the actual dimensions of the inner Canvas. The ScrollViewer will then update to reflect the correct dimensions. You don't actually change the size of the inner Canvas, you just change the scale.
This answer should answer your question:
XAML: make a ScrollViewer show scrollbars when the ScaleTransform of a child object gets big

The "visible area" of a control?

I have a Canvas within a ScrollViewer. The Canvas have a size of 600x600 and the ScrollViewer
400x400. If i scroll to the right side, i can't see 200pxl left side of the Canvas. Therefore my area of Canvas begins at x=200 but actually the visible area at x=0. Is there any way to get so "visile area" of a control by a property or something like that ?
Regards
Gepro
What are you looking for?
Choose the one from the list below:
ContentVerticalOffset
ContentHorizontalOffset
ViewportWidth
ViewportHeight

WPF Adorner Transforms

I am building a control, where the user can "draw" resizable rectangles that are laid over the content. To resize those rectangles, I use an Adorner on top of them which contains 4 Thumbs to change the size of the rectangle.
The problem is, that this control is is "zoomable", meaning a ScaleTransform is applied to the whole control depending on a zoom factor. The Thumbs in the Adorner are affected by this ScaleTransform as well.
But I need them to keep their size, independent of the zoom factor.
I tried putting the Adorners in a Layer of another non-transformed control instead of the rectangle-layer, but this didn't work.
How can I achieve this?
Thanks,
Andrej
Have you checked this post: Transformations on AdornedElement are also applied to Adorner?! ? Does it work?
I also find this question on MSDN: How to exclude scaleTransform from GeneralTransform in Adorner GetDesiredTransform method., this is good because also there is some example code.

Resources