Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

The Simplest WPF Diagram Designer - Part 2

0.00/5 (No votes)
12 Oct 2014 1  
Added text, resize operation and a color picker to a designer

Introduction

In the previous part, I've shown how to build the simplest designer - drag and drop shapes on canvas. Now it is time to make it a little more complex. I will add the option to resize shapes, add the text to shapes and change their color.

Resize

That is the biggest change. Previously, I had a simple Shape class to represent shapes in MyBase but now to implement resizing (and add resize thumbs at corners), we need to create a user control for it. It is called ShapeContainer and consists of a Grid 3x3, with a ResizeThumbs at the corners and the main shape in the centre. Everything is quite straightforward and accessible from the code. However, there are few points of interest.

The main one is that with resizing to the left or top, we have to not only change the shape's size but as well move the shape itself accordingly. And in that case, we have to recalculate the attached connector`s coordinates as well. To do it, the ShapeContainer has to implement INotifyPropertyChanged and override its Width and Height properties. Relevant code can be found at MyShape.container_PropertyChanged.

Another point is that for drag operation, now we have to check the original source of the event. If it is a ResizeThumb control, then the drag operation is invalid as it is possible to resize the shape in a wrong manner.

And as an icing on the cake, we can now change the behaviour of the IsSelected property. It will change the color of the connector as before, but for actual shapes, it will show or hide the corresponding thumbs.

Text

As we have changed the control of the MyShape class, it is really simple. We need to add 2 controls to the grid: label to show the text and textbox to edit it.

public void EditText()
{
    Label.Visibility = Visibility.Hidden;
    EditableText.Visibility = Visibility.Visible;
    EditableText.Text = Text;

    EditableText.Focus();
}

This public method is called to start the editing - just show the textbox while hiding the label. The last point here is to publish a TextChanged event...

public event Action TextChanged;

...in order to save the changes from the control back to the model.

Color

In my blog, I have described how I`ve done elliptic menu (here). But in this project, I've decided to use the Microsoft.Expression.Drawing assembly and the Arc control from it to draw the ring. To create a whole pallet, I've used 7 arc segments with linear gradients: Red -> Orange -> Yellow -> Green -> Cyan -> Blue -> Magenta -> Red. And to find out what is the color under the mouse pointer, I have to render my control to the RenderTargetBitmap and if the mouse is over the ring - copy pixel information.

Probably, the only tricky part here is to remember the circle formula and to get the mouse position before the rearrangement of the control (you have to do it or it is possible to get the black rectangle as a result):

var point = Mouse.GetPosition(element);

element.Measure(new Size(element.Width, element.Height));
element.Arrange(new Rect(new Size(element.Width, element.Height)));
element.UpdateLayout();

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here