How can I make the changes of a transformation stick? - wpf

So I have a FrameworkElement to which I apply a template that has a thumb. I calculate the angle and then I set the RenderTransfrom property equal to a RotationTranform. Once I do the rotation and want to do another rotation, the changes don't stick, that it the element returns to its initial position. How can I make the changes stick after a transformation has been applied. Any help would be appreciated. Thank you.
Do transformations affect the actual element or are they only a rendering thing? Also do they affect the bounding box of the element? I tried a layout transformation and still the same result.

You can only have one tranform at a time, but if you need multiple transfomations you can use a TransformGroup to add whatever transforms you need.
Alternatively you can use a MatrixTransform whose Matrix you can manipulate (those changes will not be reversible but as there is only one transformation in total it should have a higher performance).

Related

object not rotating properly after translate transform in wpf?

I have canvas with several cutom controls inherited from panel class, dynamically added to it at runtime with rendertransform=(.5,.5). But when apply translate transform (50,50) and rotate it by 100 degrees, it does not rotate on its place, it rotates in radius of 50, why?
Am I doing wrong something ?
Transformations are not commutative, you should apply the rotation before applying the translation.
Often you have a TransformGroup, then you can just change the order of its children, if this is somehow not an option because some transform is "inherited" from a parent you can nullify prior transforms using their inverse (in the case of a translation that should move the target back to the origin), then you can rotate it in place, and apply the original transform again.
The documentation is your friend, here is what can be found for TransformGroups:
In a composite transformation, the order of individual transformations is important. For example, if you first rotate, then scale, then translate, you get a different result than if you first translate, then rotate, then scale. One reason order is significant is that transformations like rotation and scaling are done with respect to the origin of the coordinate system. Scaling an object that is centered at the origin produces a different result than scaling an object that has been moved away from the origin. Similarly, rotating an object that is centered at the origin produces a different result than rotating an object that has been moved away from the origin.
If it rotates with a radius of 50, it's because your origin is wrong.
You just need to change the origin of your RotateTransform by setting the CenterX and CenterY properties both to 50 in this case.

Getting the true visual bounding box of a WPF element?

For a simplified version of my problem, I would like to calculate the bounding box of a layout-transformed (possibly even render-transformed) shape, so that I can always fit a rectangle perfectly around the shape, no matter what its rotation or scale may be. If you can solve this, I will be happy.
The more complex problem is that of calculating the visual bounding box of any framework element. By 'visual bounding box' I mean the top-most visible pixel within the framework element determines the top-bound, the right-most visible pixel determines the right-bound, etc. If you can solve this, I will be even more happy.
I have tried playing with LayoutInformation.GetLayoutSlot(), but this did not work in the expected manner. The 'layout slot' was actually MUCH larger than the actual bounds. I also tried using VisualTreeHelper.GetDescendantBounds(), but because of the VisualParent of my test shape being protected I could not manage to access this property, and decided to check here before I go any further into it.
I hope that somebody can provide an easy way of getting the true visual bounding box of an element in WPF, that is calculated AFTER all transforms. If I have not made something clear in my question, please let me know.
private Rect GetRectOfObject(FrameworkElement _element)
{
Rect rectangleBounds = _element.RenderTransform.TransformBounds(
new Rect(_element.RenderSize);
return rectangleBounds;
}
Maybe this will help out.
You will get good results with VisualTreeHelper.GetDescendantBounds() and you can use VisualTreeHelper.GetParent() to gain access to the otherwise protected VisualParent property. However what you probably want to do is call GetDescendantBounds on the shape itself, not its parent, because in spite of its name, the method returns the bounds of the parent and all of its decendants.
The problem is not easy, as a control may draw outside its bounds.
But if you assume this doesn't happen you can solve the problem by using parent.TranslatePoint(point_in_child_coord_system, child) to transform (0,0), (child.ActualWidth,0), (child.ActualWidth, child.ActualHeight) and (0,child.ActualHeight) to the parent coord system. Then sort the x and y coordinates of all points and use minimum and maximum values to find the bounding box.
Note: sorting is necessary because of possible child rotation.

Check for overlapping shapes in WPF

I have a set of shapes which need to be drawn on top of each other. I need to re-order them such that the smallest shape gets drawn last (i.e. it will be closest to the user). Is there any way to check whether a shape overlappes (encloses and/or intersects) another shape. I know there is a method in Rect structure called Contains which checks whether there is an object within it. Is there a similar method or a way to simulate it on Shapes in WPF? Thanks in advance for any help.
Cheers,
Nilu
You could probably use the Geometry.FillContainsWithDetail method. Its name is ill-chosen IMHO, but the description is clear :
Returns a value that describes the intersection between the current geometry and the specified geometry.
I have successfully used it for collision testing before, so it should work for you too...

Best way to write a custom gauge control in WPF?

I need to write a gauge control in WPF for a project at work. By gauge control, I mean something akin to a traditional car speedometer: a circular face with numbers and ticks around the circumference, and a needle pointing to the current value. Although I could get my employer to purchase a third-party control, or even find a free one somewhere, I’d still like to write it myself, for curiosity’s sake more than anything else.
My first thought was to ‘skin’ an existing control using a template, something like a ProgressBar for example as it has Minimum, Maximum and Value properties. However, I don’t think this will offer me the flexibility that I need.
I’d like to animate the needle that points to the current value, so that when the gauge’s value changes the needle moves from the old value to the new value. I figured the easiest way to do this would be to have some kind of shape or geometry representing the needle, and then apply a RotateTransform of the relevant number of degrees to get the needle to point to the correct value. The animation’s To property would be set to the ‘value degrees’ property via binding.
It seems to me that there are three basic approaches I could take:
Use one custom FrameworkElement to represent the entire gauge
I could derive from FrameworkElement, override its OnRender method, then use the DrawingContext to draw both the gauge face and the needle. This would mean that I could no longer animate the needle directly using a RotateTransform, but would instead have to redraw the entire gauge every time the value changes. This seems inefficient to me, as the gauge face represents the bulk of the drawing code but would change very rarely. However, this approach is the most lightweight in terms of the number of elements used.
Use two custom FrameworkElements, one for the face and one for the needle
I’m currently leaning towards this approach. One element would represent the face, the other the needle. This would allow me to target the needle element with the RotateTransform. The gauge control would then consist of three elements: the face, the needle, and a Panel container to hold both of them (ie. Canvas, Grid, whatever). So three elements instead of one, hence not as lightweight as the first approach.
Use DrawingVisuals to draw the face and needle
I’ve also read about the DrawingVisual class, but I’m a bit confused as to why anyone would use this as opposed to deriving from FrameworkElement and overriding OnRender, given that DrawingVisual must be hosted in a custom FrameworkElement anyway. It would seem that this approach doesn’t offer any advantages over the second approach, and would require more code, but maybe I’m missing something.
Any thoughts or advice regarding which approach people think is best and why would be most welcome!
Personally I'd recommend making a CustomControl using the second approach. Unless you are going to be showing more than 1000 of the gauges in view at the same time you aren't going to notice the extra element in your visual tree and I think you'll find it's much easier to make and maintain.
You could just style a slider control and feed values into it. You should be able to make a slider look like any kind of gauge you need.

How can i check if 2 controls overlap eachother on a canvas in WPF?

I am writing a designer that enables the user to drag controls around the screen.
What would be the best way of detecting if a control is overlapping another control while i am dragging the one control around?
Should i just get the dimensions of the FrameworkElement and keep on checking the dimensions of the other elements?
Thanks.
Eli
You can use the Rect.IntersectsWith method
The dimension (FrameworkElement.ActualWidth FrameworkElement.ActualHeight) and postion (Canvas.Top, Canvas.Bottom,Canvas.Left, Canvas.Right) of your elements would suffice if they are always rectangular. In that case you can easily calculate if two rectangles overlap. If you elements can be of more complex shapes it gets hairy. I have no idea if I can test for intersection of two Visual instances in WPF.
Maybe we can use hittesting? With this approach you could at least test if a certain point or geometry intersect with a certian visual. So you would have to define a geometry or a list of points that more or less closely match the bounds of your 2nd visual.

Resources