前面说了一下Activity控件
现在说一下ArrowLine画线控件
ArrowLine可以分为三部分:箭头、线、箭尾组成。
当点击Activity里面圆时,线就出来了,然后拖动,将箭头指向目标Activity控件里去
然后松开鼠标,这样一根线就画出来了。
如图所示:
当拖动开始节点Activity控件时,线的尾部坐标也得修改相应的坐标,同里当拖动结束节点Activity的时候,箭头的坐标也得及时更新位置
当不想要线的时候,可以点击线的右键,然后将线删除。
ArrowLine控件的xaml描述如下:
<Canvas x:Name="LayoutRoot" Background="White">
<Line x:Name="Cap">
<Line.RenderTransform>
<RotateTransform x:Name="CapRotateTransform" />
</Line.RenderTransform>
</Line>
<Line x:Name="Connector" />
<Line x:Name="Foot">
<Line.RenderTransform>
<RotateTransform x:Name="FootRotateTransform" />
</Line.RenderTransform>
</Line>
<TextBox Name="txtComment" Visibility="Collapsed" Text="请输入说明..." TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" />
</Canvas >
ArrowLine控件的cs代码如下:
下面里的代码有从网上摘出来的,修改了一下。
public partial class ArrowLine : UserControl, IArrowLine
{
/// <summary>
/// 删除箭头
/// </summary>
public event RoutedEventHandler DeleteLine;
Point startPoint;
Point endPoint;
/// <summary>
/// 右键菜单
/// </summary>
ContextMenu _Cmenu = new ContextMenu();
string _LineGuid;
/// <summary>
/// 线的GUID值
/// </summary>
public string LineGuid { get { return _LineGuid; } set { _LineGuid = value; } }
/// <summary>
/// 箭头尾部所在的控件
/// </summary>
public UIElement ArrowFootControl { get; set; }
/// <summary>
/// 箭头头部所在的控件
/// </summary>
public UIElement ArrowCapControl { get; set; }
/// <summary>
/// 开始坐标
/// </summary>
public Point StartPoint
{
get { return startPoint; }
set
{
startPoint = value;
Update();
}
}
/// <summary>
/// 结束坐标
/// </summary>
public Point EndPoint
{
get { return endPoint; }
set
{
endPoint = value;
Update();
}
}
public ArrowLine()
{
InitializeComponent();
MenuItem mi = new MenuItem();
mi.Click += new RoutedEventHandler(mi_Click);
mi.Header = "删除";
mi.Tag = "delete";
_Cmenu.Items.Add(mi);
_Cmenu.Visibility = System.Windows.Visibility.Collapsed;
mi = new MenuItem();
mi.Click += new RoutedEventHandler(mi_Click);
mi.Header = "说明";
mi.Tag = "Comment";
_Cmenu.Items.Add(mi);
this.MouseRightButtonDown += new MouseButtonEventHandler(ArrowLine_MouseRightButtonDown);
this.txtComment.LostFocus += new RoutedEventHandler(txtComment_LostFocus);
this.LayoutRoot.Children.Add(_Cmenu);
}
void txtComment_LostFocus(object sender, RoutedEventArgs e)
{
if (txtComment.Text.IsNullOrEmpty() || txtComment.Text.Equals("请输入说明..."))
{
txtComment.Visibility = System.Windows.Visibility.Collapsed;
}
else
{
txtComment.IsEnabled = false;
}
}
void ArrowLine_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
var p = e.GetPosition(sender as UIElement);
Canvas.SetLeft(_Cmenu, p.X);
Canvas.SetTop(_Cmenu, p.Y);
_Cmenu.Visibility = System.Windows.Visibility.Visible;
}
void mi_Click(object sender, RoutedEventArgs e)
{
MenuItem mi = sender as MenuItem;
string state = mi.Tag.ToString();
switch (state)
{
case "delete":
if (null != DeleteLine)
{
DeleteLine(this, e);
}
break;
case "Comment":
txtComment.IsEnabled = true;
txtComment.Visibility = System.Windows.Visibility.Visible;
break;
}
_Cmenu.Visibility = System.Windows.Visibility.Collapsed;
}
/// <summary>
/// 结构函数
/// </summary>
/// <param name="startPoint">开始坐标</param>
/// <param name="endPoint">结束坐标</param>
public ArrowLine(Point startPoint, Point endPoint)
: this()
{
this.startPoint = startPoint;
this.endPoint = endPoint;
Update();
}
/// <summary>
/// 更新
/// </summary>
private void Update()
{
double angleOfLine = Math.Atan2((endPoint.Y - startPoint.Y), (endPoint.X - startPoint.X)) * 180 / Math.PI;
Connector.X1 = startPoint.X;
Connector.Y1 = startPoint.Y;
Connector.X2 = endPoint.X;
Connector.Y2 = endPoint.Y;
Connector.StrokeThickness = 1;
Connector.Stroke = new SolidColorBrush(Colors.Black);
Cap.X1 = (startPoint.X + endPoint.X) / 2;
Cap.Y1 = (startPoint.Y + endPoint.Y) / 2;
Cap.X2 = (startPoint.X + endPoint.X) / 2;
Cap.Y2 = (startPoint.Y + endPoint.Y) / 2;
Cap.StrokeEndLineCap = PenLineCap.Triangle;
Cap.StrokeThickness = 20;
Cap.Stroke = new SolidColorBrush(Colors.Black);
CapRotateTransform.Angle = angleOfLine;
CapRotateTransform.CenterX = (this.StartPoint.X + this.endPoint.X) / 2;
CapRotateTransform.CenterY = (this.StartPoint.Y + this.endPoint.Y) / 2;
Foot.X1 = endPoint.X;
Foot.Y1 = endPoint.Y;
Foot.X2 = endPoint.X;
Foot.Y2 = endPoint.Y;
Foot.StrokeEndLineCap = PenLineCap.Triangle;
Foot.StrokeThickness = 20;
Foot.Stroke = new SolidColorBrush(Colors.Black);
FootRotateTransform.Angle = angleOfLine;
FootRotateTransform.CenterX = this.EndPoint.X;
FootRotateTransform.CenterY = this.EndPoint.Y;
Canvas.SetLeft(txtComment, (this.endPoint.X + this.startPoint.X) / 2);
Canvas.SetTop(txtComment, (this.endPoint.Y + this.startPoint.Y) / 2);
}
/// <summary>
/// 释放内存
/// </summary>
public void Dispose()
{
try
{
foreach (var v in _Cmenu.Items)
{
MenuItem mi = v as MenuItem;
if (null == mi)
{
continue;
}
mi.Click -= mi_Click;
}
this.MouseRightButtonDown -= ArrowLine_MouseRightButtonDown;
this.txtComment.LostFocus -= txtComment_LostFocus;
}
catch { }
}
/// <summary>
/// 导出描述线信息
/// </summary>
/// <returns></returns>
public string ExportLocation()
{
ArrowLineInfo ail = new ArrowLineInfo();
ail.Type = this.GetType().Name;
ail.Name = this.Name;
ail.Guid = this.LineGuid;
ail.StartX = StartPoint.X;
ail.StartY = StartPoint.Y;
ail.EndX = EndPoint.X;
ail.EndY = EndPoint.Y;
var aa = ail.ToXElement("ArrowLine");
return aa.ToString();
}
}