|
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
namespace DiagramDesigner
{
public class Connector : Control, INotifyPropertyChanged
{
// drag start point, relative to the DesignerCanvas
private Point? dragStartPoint = null;
public ConnectorOrientation Orientation { get; set; }
// center position of this Connector relative to the DesignerCanvas
private Point position;
public Point Position
{
get { return position; }
set
{
if (position != value)
{
position = value;
OnPropertyChanged("Position");
}
}
}
// the DesignerItem this Connector belongs to;
// retrieved from DataContext, which is set in the
// DesignerItem template
private DesignerItem parentDesignerItem;
public DesignerItem ParentDesignerItem
{
get
{
if (parentDesignerItem == null)
parentDesignerItem = this.DataContext as DesignerItem;
return parentDesignerItem;
}
}
// keep track of connections that link to this connector
private List<Connection> connections;
public List<Connection> Connections
{
get
{
if (connections == null)
connections = new List<Connection>();
return connections;
}
}
public Connector()
{
// fired when layout changes
base.LayoutUpdated += new EventHandler(Connector_LayoutUpdated);
}
// when the layout changes we update the position property
void Connector_LayoutUpdated(object sender, EventArgs e)
{
DesignerCanvas designer = GetDesignerCanvas(this);
if (designer != null)
{
//get centre position of this Connector relative to the DesignerCanvas
this.Position = this.TransformToAncestor(designer).Transform(new Point(this.Width / 2, this.Height / 2));
}
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
DesignerCanvas canvas = GetDesignerCanvas(this);
if (canvas != null)
{
// position relative to DesignerCanvas
this.dragStartPoint = new Point?(e.GetPosition(canvas));
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.dragStartPoint = null;
// but if mouse button is pressed and start point value is set we do have one
if (this.dragStartPoint.HasValue)
{
// create connection adorner
DesignerCanvas canvas = GetDesignerCanvas(this);
if (canvas != null)
{
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(canvas);
if (adornerLayer != null)
{
ConnectorAdorner adorner = new ConnectorAdorner(canvas, this);
if (adorner != null)
{
adornerLayer.Add(adorner);
e.Handled = true;
}
}
}
}
}
internal ConnectorInfo GetInfo()
{
ConnectorInfo info = new ConnectorInfo();
info.DesignerItemLeft = DesignerCanvas.GetLeft(this.ParentDesignerItem);
info.DesignerItemTop = DesignerCanvas.GetTop(this.ParentDesignerItem);
info.DesignerItemSize = new Size(this.ParentDesignerItem.ActualWidth, this.ParentDesignerItem.ActualHeight);
info.Orientation = this.Orientation;
info.Position = this.Position;
return info;
}
// iterate through visual tree to get parent DesignerCanvas
private DesignerCanvas GetDesignerCanvas(DependencyObject element)
{
while (element != null && !(element is DesignerCanvas))
element = VisualTreeHelper.GetParent(element);
return element as DesignerCanvas;
}
#region INotifyPropertyChanged Members
// we could use DependencyProperties as well to inform others of property changes
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
// provides compact info about a connector; used for the
// routing algorithm, instead of hand over a full fledged Connector
internal struct ConnectorInfo
{
public double DesignerItemLeft { get; set; }
public double DesignerItemTop { get; set; }
public Size DesignerItemSize { get; set; }
public Point Position { get; set; }
public ConnectorOrientation Orientation { get; set; }
}
public enum ConnectorOrientation
{
None,
Left,
Top,
Right,
Bottom
}
}
|
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.