Drawing shapes, text and images with moving and scaling in WPF - wpf

I'm trying to draw simple map in WPF. I need to draw shapes, text and images. It also should be possible to use mouse to move around and zoom in and out.
Right now, I have combination of Canvas + Geometry + Transforms to draw shapes, but I don't know how to add text and images.
I already tried various combination of Canvas/Grid and Layout/Render transform. Biggest problem is adding text and images, because transformations are in geometries.

If i understand you right, you're currently putting Path objects (with transformed Geometries) into a Canvas. For adding text and images you could easily add TextBlock and Image objects to the same Canvas and apply your transformations to their RenderTransform property.
A completely different approach would be to use WPF low-level rendering, provided by the DrawingVisual class. You may start at WPF Graphics Rendering Overview.

Related

Is it technically possible to render a wpf Xaml element to a direct3d texture?

Lets say I have a simple WPF canvas where I draw a few buttons and shapes using xaml. I would like to render the canvas to a direct3d texture so I can have access to the pixels from within the GPU.
RenderTargetBitmap allows me to do software rendering. but this will be limiting in terms of performance as I will have to manually copy the pixels to where I want.
I also looked into using a custom shader effect on the canvas. but as far as I know it is impossible to write to a separate texture using direct3d 9.
So is it at all possible? if so how?

How to do Free hand Image Cropping in WPF?

all
I m developing on Medical Image Processing software, I wont crop image on mouse event, means when we drag mouse cursor and move over the image in any shape, the selected portion of image should be cropped. and that will paste in same image. is it Possible in WPF or Silverlight?
Check out the Clip property. You can specify a path in this property that is used to clip the parent object. Set Clip on your Image control to clip the image.
For design time clipping, your best bet is to use Blend (download a trial here if you don't have it) to draw a free hand path. Right click on the path and select Path->Make Clipping Path. In the next dialog, select the image that you want to clip.
EDIT: It sounds like you want to use runtime clipping/cropping, so you will want to generate the clip path using the points gathered from the mouse events. Create a collection of these points and then generate a path from them (linear lines probably... I don't know how you would generate appropriate curves unless you wrote a complex algorithm). Set this path to the Clip property after the fact.
/EDIT
You can add a transparent layer on top of the control and add an InkCanvas.
Then allow the user to draw a stroke (freehand) and turn the stroke into a Geometry by using GetGeometry use the geometry in the Clip property of the control to be clipped.

What is the best way in Silerlight to make areas of a large graphic clickable?

In a Silverlight application I have large images which have flow charts on them.
I need to handle the clicks on specific hotspots of the image where the flow chart boxes are.
Since the flow charts will always be different, the information of where the hotspots has to be dynamic, e.g. in a list of coordinates.
I've found article like this one but don't need the detail of e.g. the outline of countries but just simple rectangle and circle areas.
I've also found articles where they talk about overlaying an HTML image map over the silverlight application, but it has to be easier than this.
What is the best way to handle clicks on specific areas of an image in silverlight?
Place the Image and a Canvas in a Grid so that the Canvas overlays the Image.
Add shapes of appropriate sizes and placed as needed to the canvas. All shapes will a transparent fill and no border, hence the user only sees the Image. On the Canvas MouseDown (or Up events) use OriginalSource to determine which shape generated the click. Use the Tag property of each shape to associate it with some object that represents the flowchart element being mapped.
I found an easy way to do this without a canvas:
How to get the coordinates of an image mouse click in the event handler?

Erasing in a WPF program

How can I make a MS Paint clone in WPF?
I use Canvas and Shapes, but I don't know how to implement erasing. Should I use different controls, image control for example, or other drawing technology?
You can simply remove the object from the Canvas using canvas.Children.Remove() methods.

WPF: Creating snappable grid lines with variable spacing

I'm currently creating a MSPaint-like WPF-application and struggling with the implementation of a snappable grid.
The painting of the grid is no problem with a VisualBrush and a Rectangle but the problem is that these lines are then purely for looks and can't be easily changed (for example highlighted when the snapping to a specific line triggered).
My other idea was to have a 2 Canvas solution where 1 Canvas is used for the elements and one Canvas (who is positioned above the other) contains all the grid lines. However I have the feeling that this would mean quite a performance hit.
Are there any other possible ways to implement this kind of functionality?
Efficiency considerations of a two-panel approach vs DrawingContext
I have good news for you: You are wrong about the significant performance hit. Your two-canvas idea is nearly optimal, even if you use individual objects for the grid lines. This is because WPF uses retained-mode rendering: When you create the canvas, everything on it is serialized into a compact structure at native level. This only changes when you change the grid lines in some way, such as changing the grid spacing. At all other times the performance will be indistinguishable from the very fastest possible managed-code methods.
A slight performance increase could be had by using DrawingContext as Nicholas describes.
A simpler and more efficient solution
Perhaps a better way then drawing individual lines on the grid canvas is to use two tiled visual brushes (one horizontal, one vertical) to draw all unhilighted lines, then use Rectangle(s) added in code-behind to hilight the line(s) you are snapping to.
The main advantage of this technique is that your grid can be effectively infinite, so there is no need to calculate the right number of grid lines to draw and then update this every time the window resizes or the zoom changes. You also only have three UIElements involved, plus one more for each grid line that is currently hilighted. It also seems cleaner to me than tracking collections of grid lines.
The reason you want to use two visual brushes is that drawing is more efficient: The brush drawing the vertical lines is stretched to a huge distance (eg double.MaxValue/2) in the vertical direction so the GPU gets only one drawing call per vertical line, the same for the horizontal. Doing a two-way tiling is much less efficient.
Adorner layer
Since you asked about alternatives, another possibility is to use Adorner and AdornerLayer with any of the solutions above rather than stacking your canvas using eg a Grid or containing Canvas. For a Paint-like application this is nice because the adorner layer can be above your graphic layer(s) yet the adorners can still attach to individual items that are being displayed.
You might consider drawing your grid using the DrawingContext inside of OnRender. Drawing this way does not introduce new UIElements into the visual tree, which helps to keep performance up. In some ways, it is similar to what you are currently doing with the VisualBrush, which also does not create new UI elements per copy.
However, since you will actually be individually drawing each line instead of copying the look of a single line, you'll be able to highlight the grid line(s) that participate in snapping without changing the colors of those that do not.
If you are going to go down this route, make sure to have a look into GuidelineSets for positioning your guide lines (more details here), since you'll probably want to have your guide lines snap to the device's pixels so that they draw sharply.

Resources