This is a quick demonstration that focuses on some of the geometric shape drawing features that are available in Silverlight and how to use those features in code.
Live Demo:
Drawing Dynamic Silverlight Shapes
The following code excerpts show the highlights of performing the primary shape drawing functions:
- Dynamic shape creation
- Sizing calculations
- Brushes
- Dynamic event handlers
- Shape re-sizing
- Shape movement
///
/// Draws the desired geometrical shape. This quick example app uses
/// ellipses and rectangles, but others would work here as well.
///
private void DrawShape(Shape shape, SolidColorBrush brush)
{
double x = 0.0, y = 0.0;
// These calcs are required to handle sizing in any direction
if (_ptStart.X > _mX)
{
shape.Width = _ptStart.X - _mX;
x = _mX;
}
else
{
shape.Width = _mX - _ptStart.X;
x = _ptStart.X; }
if (_ptStart.Y > _mY)
{
shape.Height = _ptStart.Y - _mY;
y = _mY;
}
else
{
shape.Height = _mY - _ptStart.Y;
y = _ptStart.Y;
}
// Set the brushes
shape.Fill = brush;
shape.StrokeThickness = 1;
shape.Stroke = _whiteBrush;
// Set the shape's coordinates
shape.SetValue(Canvas.LeftProperty, x);
shape.SetValue(Canvas.TopProperty, y);
if (_shapeLast != null )
{
LayoutRoot.Children.Remove(_shapeLast);
}
// Set the name, tooltip and add the event handlers
shape.Name = "DynamicShape" + _shapeCount.ToString();
ToolTipService.SetToolTip(shape, shape.Name + "\r\n" + shape.GetType().ToString());
shape.MouseEnter += new MouseEventHandler(shape_MouseEnter);
shape.MouseLeave += new MouseEventHandler(shape_MouseLeave);
shape.MouseLeftButtonDown += new MouseButtonEventHandler(shape_MouseLeftButtonDown);
shape.MouseLeftButtonUp += new MouseButtonEventHandler(shape_MouseLeftButtonUp);
// Add the shape to the canvas
_shapeLast = shape;
_shapeCount++;
LayoutRoot.Children.Add(shape);
} |
///
/// This is the method where the shapes are drawn, resized and moved.
///
private void LayoutRoot_MouseMove( object sender, System.Windows.Input.MouseEventArgs e)
{
// Update mouse coordinates
_mX = e.GetPosition(sender as UIElement).X;
_mY = e.GetPosition(sender as UIElement).Y;
ctlCoords.Text = "(" + _mX + " ," + _mY + ")" ;
// If enabled, add event info to the console
if (chkTrackMouse.IsChecked == true )
{
AddConsoleMsg( "LayoutRoot_MouseMove: X=" + _mX + ", Y=" + _mY);
}
// Perform a hittest to make sure we're operating within the bounds of our
// drawing surface
IEnumerable elements;
elements = VisualTreeHelper.FindElementsInHostCoordinates(
new Point(_mX, _mY), ctlBounds as UIElement);
if (elements.Any())
{
// If enabled, draw the gridlines
if (chkGridlines.IsChecked == true )
{
DrawGridlines();
}
// If enabled, draw an ellipse
if (_isLeftMouseButtonDown == true && _isDrawEllipse)
{
Ellipse ellipse = new Ellipse();
DrawShape(ellipse, _brushes[_randBrush.Next(0,_brushes.Count)]);
}
// If enabled, draw a rectangle
if (_isLeftMouseButtonDown == true && _isDrawRect)
{
Rectangle rect = new Rectangle();
DrawShape(rect, _brushes[_randBrush.Next(0, _brushes.Count)]);
}
// If enabled, draw a line
if (_isLeftMouseButtonDown == true && _isDrawLine)
{
Line line = new Line();
DrawLine(line);
}
// If a shape is moving
if (_isShapeMoving)
{
double x = _mX - _shapeMove.Width / 2;
double y = _mY - _shapeMove.Height / 2;
// Move the shape
_shapeMove.SetValue(Canvas.LeftProperty, x);
_shapeMove.SetValue(Canvas.TopProperty, y);
}
}
else
{
// We're outside of the bounds of our drawing surface so remove the gridlines
RemoveGridlines();
}
} |
You can download the full source here:
Drawing Dynamic Silverlight Shapes Demo. This requires Visual Studio 2008 and Silverlight 3 development tools (Expression Blend is notrequired but would be useful as well).
This is extremely helpful and a great introduction. Have you added any other paint-like functionality you can share?
ReplyDelete