|
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Xml;
namespace DiagramDesigner
{
public class DesignerCanvas : Canvas
{
// start point of the rubberband drag operation
private Point? rubberbandSelectionStartPoint = null;
// keep track of selected items
private List<ISelectable> selectedItems;
public List<ISelectable> SelectedItems
{
get
{
if (selectedItems == null)
selectedItems = new List<ISelectable>();
return selectedItems;
}
set
{
selectedItems = value;
}
}
public DesignerCanvas()
{
this.AllowDrop = true;
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
if (e.Source == this)
{
// in case that this click is the start for a
// drag operation we cache the start point
this.rubberbandSelectionStartPoint = new Point?(e.GetPosition(this));
// if you click directly on the canvas all
// selected items are 'de-selected'
foreach (ISelectable item in SelectedItems)
item.IsSelected = false;
selectedItems.Clear();
e.Handled = true;
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
// if mouse button is not pressed we have no drag operation, ...
if (e.LeftButton != MouseButtonState.Pressed)
this.rubberbandSelectionStartPoint = null;
// ... but if mouse button is pressed and start
// point value is set we do have one
if (this.rubberbandSelectionStartPoint.HasValue)
{
// create rubberband adorner
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
if (adornerLayer != null)
{
RubberbandAdorner adorner = new RubberbandAdorner(this, rubberbandSelectionStartPoint);
if (adorner != null)
{
adornerLayer.Add(adorner);
}
}
}
e.Handled = true;
}
protected override void OnDrop(DragEventArgs e)
{
base.OnDrop(e);
DragObject dragObject = e.Data.GetData(typeof(DragObject)) as DragObject;
if (dragObject != null && !String.IsNullOrEmpty(dragObject.Xaml))
{
DesignerItem newItem = null;
Object content = XamlReader.Load(XmlReader.Create(new StringReader(dragObject.Xaml)));
if (content != null)
{
newItem = new DesignerItem();
newItem.Content = content;
Point position = e.GetPosition(this);
if (dragObject.DesiredSize.HasValue)
{
Size desiredSize = dragObject.DesiredSize.Value;
newItem.Width = desiredSize.Width;
newItem.Height = desiredSize.Height;
DesignerCanvas.SetLeft(newItem, Math.Max(0, position.X - newItem.Width / 2));
DesignerCanvas.SetTop(newItem, Math.Max(0, position.Y - newItem.Height / 2));
}
else
{
DesignerCanvas.SetLeft(newItem, Math.Max(0, position.X));
DesignerCanvas.SetTop(newItem, Math.Max(0, position.Y));
}
this.Children.Add(newItem);
//update selection
foreach (ISelectable item in this.SelectedItems)
item.IsSelected = false;
SelectedItems.Clear();
newItem.IsSelected = true;
this.SelectedItems.Add(newItem);
}
e.Handled = true;
}
}
protected override Size MeasureOverride(Size constraint)
{
Size size = new Size();
foreach (UIElement element in base.Children)
{
double left = Canvas.GetLeft(element);
double top = Canvas.GetTop(element);
left = double.IsNaN(left) ? 0 : left;
top = double.IsNaN(top) ? 0 : top;
//measure desired size for each child
element.Measure(constraint);
Size desiredSize = element.DesiredSize;
if (!double.IsNaN(desiredSize.Width) && !double.IsNaN(desiredSize.Height))
{
size.Width = Math.Max(size.Width, left + desiredSize.Width);
size.Height = Math.Max(size.Height, top + desiredSize.Height);
}
}
// add margin
size.Width += 10;
size.Height += 10;
return size;
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.