Title: Let the user draw a polyline in WPF and C#
This example shows how you can let the user use the mouse to draw a polyline in and WPF application in C#. I often badmouth WPF by saying that it is "twice as flexible and only ten times as hard" as Windows Forms, but this example is actually somewhat simpler than a Windows Forms program that draws polylines. I'll say more about this at the end of the post.
To draw a shape in WPF, you create a shape object and then add it to the control that should hold it. In this example, the program creates a Polyline object and adds it as a child of a Canvas control.
The following code declares a Polyline object at the form level.
// The Polyline we are currently drawing.
// This is null when we are not drawing.
private Polyline NewPolyline = null;
This Polyline object is null when we are not drawing a new Polyline.
When the user presses the mouse button down over the program's Canvas control, the following event handler executes.
// The user clicked. Add a point,
// stop drawing, or start a new curve.
private void canDrawing_MouseDown(object sender, MouseButtonEventArgs e)
{
// See if we are currently drawing.
if (NewPolyline != null)
{
// See if this is the left or right mouse button.
if (e.ChangedButton == MouseButton.Left)
{
// Left button. Add a new point.
NewPolyline.Points.Add(e.GetPosition(canDrawing));
}
else
{
// Right button. Stop drawing.
NewPolyline = null;
}
}
else
{
// We are not drawing. Start a new Polyline.
NewPolyline = new Polyline();
NewPolyline.Stroke = Brushes.LightGreen;
NewPolyline.StrokeThickness = 5;
NewPolyline.Points.Add(e.GetPosition(canDrawing));
NewPolyline.Points.Add(e.GetPosition(canDrawing));
canDrawing.Children.Add(NewPolyline);
}
}
This code checks the NewPolyline variable to see if we are currently drawing a new polyline. If we are drawing a polyline, then the program checks which mouse button the user pressed. If the user pressed the left mouse button, the code adds the mouse's current location to the new polyline's Points collection. That's all it needs to do. The Polyline object automatically redraws itself.
If the user pressed the right mouse button, the code simply sets NewPolyline to null to indicate that we are done drawing this polyline. You'll see shortly that this means the most recent mouse position is added as the final point in the polyline. If you don't want to include the point where the user right-clicked, you can make this code remove the new polyline's final point.
If the user clicked the mouse while we were not drawing a polyline, then the event handler creates a new polyline and sets its drawing properties Stroke and StrokeThickness. It then adds the mouse's current position to the new object's Points collection. The MouseMove event handler described shortly will move the second of those points as the user moves the mouse. The code then adds the new polyline to the canDrawing Canvas control so it becomes visible.
The following code shows the Canvas control's MouseMove event handler.
// Update the new Polyline's most recent point.
private void canDrawing_MouseMove(object sender, MouseEventArgs e)
{
if (NewPolyline == null) return;
NewPolyline.Points[NewPolyline.Points.Count - 1] =
e.GetPosition(canDrawing);
}
This code checks the NewPolyline variable and returns if it is null.
If NewPolyline is not null, the program sets the new polyline's last point equal to the mouse's current position.
That's all there is to it!
In a Windows Forms program, we would use a Boolean variable to keep track of whether we were drawing a new polyline. We would also need a list of points to keep track of its points. Finally, we would need to write code to draw any previous polylines and to draw the new polyline separately so it looked different from older polylines.
The WPF version uses the single NewPolyline object to keep track of whether we are drawing and to store the new polyline's points. The Canvas control automatically draws the older polylines so we don't need to keep track of them.
There are plenty of other things you might like this program to do. For example, you might want to let the user draw with different colors and lines styles. You might also like to be able to move or delete polylines, adjust their points, or change their colors and drawing styles. All of that won't be trivial, but it should be slightly easier than it is in a Windows Forms program because the WPF version has the Polyline class to keep track of the polylines for you.
Download the example to experiment with it and to see additional details.
|