I have been play around for quite some time with a custom Drawing canvas that could do some simple but yet useful stuff, a program that had some of the functionality of normal drawing program, and could be used to generate some XAML content.
For writing code that looks interesting and useful to others, we often want to use "real world" data as input. As always, the first thing I did was some searching on the CodeProject site and elsewhere, and I did find a WPF drawing tool here on this very site.
I had some different ideas for implementing some stuff, like zooming and panning, loading images and other things, that would require quite a lot of redesigning of the program, and I needed a challenge, so I decided to write my own drawing program. As I looked around the web for interesting ideas, I came upon a couple of articles on this site that gave me some ideas; there were especially two that really stood out:.
The way he designed the resize using an Adorner was brilliant, and I used his code nearly without making any changes. The control I would describe here would inherit two custom controls and a control form the framework itself. The only control that is fully custom is my Drawing canvas, that inherits the Canvas control with some simple modifications. I have, at my previous work places, done quite a lot of editing digital maps, and have witnessed how vital a real good editing tool for digital drawing program is.
I have also had some experience in how difficult it can be if you lack those tools, they can litterally mean the difference between swearing and not.
Line in WPF
Unfortunately, a real good all purpose drawing program, are huge, and normally requires a whole programming team to be implemented in an easy to use way. So this program will eventually have short comings, but I hope its a good start. Based on the other programs I could find the easiest thing seem to be to create a custom user control that inherited the Canvas. This canvas would hold all the drawn elements, and it would also be necessary to override some of the default properties.
The standard canvas also has some problem, in that it is not intended, as it is, to have any scrolling or limits.
This would have to be solved by using some additional outer controls that could remedy the situation. This was perhaps the easiest thing, as I implemented the WPF Diagram Designer items, tweaked the design slightly and voila.
Last I would also need to create a customized control that inherits the Scroll View control. This control would be responsible for panning and zooming the unity urp parallax drawing area, it would also have to be the outer most control, meaning that it would house the Adorner resize and the custom canvas. A drawing program like this would have to handle quite a lot of very complex events. Events would have to be stopped, tunneled, and routed, based on the actions that are going to be performed.
I will start with the Zoom and panning event. After some thinking I eventually came to the conclusion that the panning would have to be handled by the scroll control, and the zooming would have to be initiated from the same control as well, as both the two lower controls would depend on this. I would also have to in part, exclude the resize control from the zooming event, as it would become invisible if I zoomed out far enough.
Its size, meaning height and width, would have to change according to the changes in the height and width of the canvas though. However, dragging and resizing of the actual drawings on the canvas, would have to take place on the canvas control itself, as it would have all the necessary information of the custom framework elements that I would create my own custom classes in. This meant that my main custom control would consist of three distinct parts:. This would also, however mean that I would have to design tall the controls that did the actual drawing, to also be able to find out whether or not you clicked a point or the line, meaning they would have to be implemented inheriting a FrameworkElement and using DrawingContext to hold the visual objects shown on the Canvas control.
I call all of these controls Basic Controls, as they form the underlying for the elements to be drawn, while the outer controls just are housing blocks and organizers of the content inside them. The program has in all 5 different controls that implement some drawing capabilities. This is by far the most complex control in the program, as it handles most of the drawing functions, and stops and initiates nearly all the functions.
Unlike bitmap images, which can be displayed using the Image control, vectors can be scaled and transformed without distortion or pixellation. In this article, and those that follow, we'll look at six drawing classes that can be added to windows using pure XAML. We'll see how they can be formatted to change the style of lines and fills. We'll also see how the same formatting, defined using pens and brushescan be applied to other WPF controls.
Later in the tutorial we'll use two-dimensional shapes when replacing control templatesallowing advanced customisation of the standard controls. The first of the drawing classes that we'll consider is Line. This draws a simple, straight line between two points.
The two points are defined using two pairs of X and Y co-ordinates. Both co-ordinate pairs are defined relative to the top-left corner of the invisible bounding box that surrounds the line.
Let's demonstrate with a simple example. Once loaded, replace the XAML of the main window with the following code:.
How to: Draw a Line
In this example code, a Line is defined within a StackPanel. The co-ordinates for the start point of the line are defined in the X1 and X2 properties. X1 and Y1 are both set to 10, so the start point is ten device independent units from the left of the control's bounding box and ten units from the top. This means that the line will not start in the top corner of the window. The X2 and Y2 attributes define the end point for the line, again relative to the bounding box.
Stroke sets the pen used to draw the line. In this case the value, "Black", means that the line will use a solid black colour. The StrokeThickness property defines the width of the line.
This defaults to zero, so if you do not explicitly provide a value, the line will not be visible. Drawing objects follow the same layout rules as other controls.
The nature of the drawing classes means that they are commonly used within a Canvasso are positioned using co-ordinates. However, they can equally be used within any other layout control. As described earlier, a line is defined using two pairs of co-ordinates within an imaginary bounding box. When lines are positioned within a container control, the rules are applied to this invisible box.
The dark mode beta is finally here. Change your preferences any time. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. I have a problem with handling mouse events on canvas. I want to draw on it using mouse and I've come up with these event handlers, but they don't do anything when I start drawing. I'm willing to bet that your canvas isn't receiving mouse events because it's background property is set to transparent.
So I tried PolyLine and works fine. Learn more. Asked 6 years, 11 months ago. Active 6 days ago. Viewed 56k times. WindowFrameBrush; line. X; line. Y; line. GetPosition this. GetPosition this ; paintSurface. Dawid B Dawid B 1 1 gold badge 2 2 silver badges 4 4 bronze badges.
Active Oldest Votes. I'm willing to bet that your canvas isn't receiving mouse events because it's background property is set to transparent This works fine for me. Threading; using System. Tasks; using System.
Windows; using System. Input; using System. Andy Andy 5, 1 1 gold badge 28 28 silver badges 33 33 bronze badges. That's exactly what I did. Thank you. How can I update the click capturing to account for offsets caused by menus? Andreas Andreas 2, 2 2 gold badges 31 31 silver badges 48 48 bronze badges.This topic provides an overview of the features of the FormattedText object. The FormattedText object allows you to draw multi-line text, in which each character in the text can be individually formatted.
The following example shows text that has several formats applied to it. WPF includes multiple controls for drawing text to the screen. Each control is targeted to a different scenario and has its own list of features and limitations.
In general, the TextBlock element should be used when limited text support is required, such as a brief sentence in a user interface UI. Label can be used when minimal text support is required. For more information, see Documents in WPF. The FormattedText object provides greater text formatting features than Windows Presentation Foundation WPF text controls, and can be useful in cases where you want to use text as a decorative element.
For more information, see the following section Converting Formatted Text to a Geometry.
In addition, the FormattedText object is useful for creating text-oriented DrawingVisual -derived objects. DrawingVisual is a lightweight drawing class that is used to render shapes, images, or text. To create formatted text, call the FormattedText constructor to create a FormattedText object. Once you have created the initial formatted text string, you can apply a range of formatting styles.
Use the MaxTextWidth property to constrain the text to a specific width. The text will automatically wrap to avoid exceeding the specified width. Use the MaxTextHeight property to constrain the text to a specific height.
The text will display an ellipsis, "…" for the text that exceeds the specified height. You can apply multiple formatting styles to one or more characters. For example, you could call both the SetFontSize and SetForegroundBrush methods to change the formatting of the first five characters in the text. The following code example creates a FormattedText object and then applies several formatting styles to the text. As with other text objects in Windows Presentation Foundation WPF applications, the FormattedText object uses device-independent pixels as the unit of measure.
However, most Win32 applications use points as the unit of measure. The following code example shows how to perform this conversion.
You can convert formatted text into Geometry objects, allowing you to create other types of visually interesting text. For example, you could create a Geometry object based on the outline of a text string. The following examples illustrate several ways of creating interesting visual effects by modifying the stroke, fill, and highlight of converted text.
When text is converted to a Geometry object, it is no longer a collection of characters—you cannot modify the characters in the text string. However, you can affect the appearance of the converted text by modifying its stroke and fill properties.
The stroke refers to the outline of the converted text; the fill refers to the area inside the outline of the converted text.
For more information, see Create Outlined Text. You can also convert formatted text to a PathGeometry object, and use the object for highlighting the text. For example, you could apply an animation to the PathGeometry object so that the animation follows the outline of the formatted text.A Canvas panel is used to position child elements by using coordinates that are relative to the canvas area.
Here are some of the properties of Canvas panels. The default values of Height and Width properties of a Canvas are 0. If you do not set these values, you will not see a canvas unless child elements are automatically resizable.
Child elements on a Canvas are never resized. The vertical and horizontal alignments on child elements do not work. Margin does work partially. If Left property of Canvas is set, Right property does not work. If Top property of Canvas is set, Bottom property does not work.
How to: Draw a Polyline by Using the Polyline Element
The Left property represents the distance between the left side of a control and its parent container Canvas. The Top property represents the distance between the top of a control and its parent container Canvas. The code in Listing 1 creates a Canvas and adds three Rectangle controls and position them using Canvas control properties. The code listed in Listing creates a Canvas Panel dynamically, add three Rectangle controls to it, and sets their left and top positions using Canvas.
SetLeft and Canvas. SetTop methods. The output of Listing generates Figure 1. The default z-order of controls is the order controls are created in. The ZIndex property of Canvas represents the z-order of a control.
The maximum value of ZIndex is In Figure 1, the z-order of red, blue, and green rectangles is 1, 2, and 3 respectively. Now, the code in Listing 2 changes the z-order of these rectangles using the ZIndex property of the Canvas.
The code snippet in Listing 2 sets the position of the Canvas control in the left top corner of the page. Figure 2. View All.This example shows how to draw a polyline, which is a series of connected lines, by using the Polyline element.
To draw a polyline, create a Polyline element and use its Points property to specify the shape vertices. Finally, use the Stroke and StrokeThickness properties to describe the polyline outline because a line without a stroke is invisible. Because the Polyline element is not a closed shape, the Fill property has no effect, even if you deliberately close the shape outline. To create a closed shape with a Filluse a Polygon element.
The following example draws two Polyline elements inside a Canvas. Although this example uses a Canvas to contain the polylines, you can use polyline elements and all the other shape elements with any Panel or Control that supports non-text content.
Shapes and Basic Drawing in WPF Overview
The dark mode beta is finally here. Change your preferences any time. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. How do I draw a line that is truly 1 pixel thick? Apart from what has been suggested, it might also be possible that your screen resolution is more than 96 DPI. I found that this answer wasn't sufficient, that it doesn't work for vertical lines on a Canvass: which sometimes displayed as 2 pixels wide.
To fix that I find I need to constrain the X-position of the line. Constraining the x value to an integer made it reliable -- i. Learn more. Asked 9 years, 10 months ago. Active 1 year, 11 months ago. Viewed 33k times. Black; myLine. Add myLine. Active Oldest Votes.
Two things: myLine. SetValue RenderOptions. EdgeModeProperty, EdgeMode. Aliased. Rusty Rusty 3, 14 14 silver badges 23 23 bronze badges. Try adding this: myLine. Matt Hamilton Matt Hamilton k 57 57 gold badges silver badges bronze badges.
If this is the case, you will have to explicitly specify the units.