WPF 之 自定义Shape

AMindMap需要一个Line,用以连接父ANode和子ANode,

简单说,就是一头大一头小的线,Wpf自带的Line是没这个功能。

Path可以画,不过,我的想法仍旧是绑定。那只能自己做咯。

图例

image

正文

既然Line,Rectangle等都是继承自Shape的,直接新建一个类继承自Sharp.

 
  
1 Public Class ALine 2 Inherits Shape 3 4 Protected Overrides ReadOnly Property DefiningGeometry As System.Windows.Media.Geometry 5 Get 6 7 End Get 8 End Property 9 End Class 10

继承完Shape,ALine中自动添加了一个需要重写的只读属性,从字面上就可以理解

为自定义shape的内容了。返回一个Geometry,那岂不是嗯嗯嗯?

ALine的属性

一头大一头小的Line也是Line,那就要有两个端点,并且,端点的数值是需要被

绑定的,大声一起说,“DependencyProperty”

 
  
1 2 #Region " X1 DependencyProperty " 3 ''' <summary> 4 ''' PropertyComment 5 ''' </summary> 6 ''' <remarks></remarks> 7 Public Shared ReadOnly X1Property As DependencyProperty = _ 8 DependencyProperty.Register( 9 " X1 " , GetType ( Double ), GetType (ALine), New FrameworkPropertyMetadata( _ 10 0.0 , FrameworkPropertyMetadataOptions.AffectsMeasure)) 11 12 Public Property X1() As Double 13 Get 14 Return GetValue(X1Property) 15 End Get 16 Set ( ByVal Value As Double ) 17 SetValue(X1Property, Value) 18 End Set 19 End Property 20 #End Region 21 22 #Region " Y1 DependencyProperty " 23 ''' <summary> 24 ''' PropertyComment 25 ''' </summary> 26 ''' <remarks></remarks> 27 Public Shared ReadOnly Y1Property As DependencyProperty = _ 28 DependencyProperty.Register( 29 " Y1 " , GetType ( Double ), GetType (ALine), New FrameworkPropertyMetadata( _ 30 0.0 , FrameworkPropertyMetadataOptions.AffectsMeasure)) 31 32 Public Property Y1() As Double 33 Get 34 Return GetValue(Y1Property) 35 End Get 36 Set ( ByVal Value As Double ) 37 SetValue(Y1Property, Value) 38 End Set 39 End Property 40 41 #End Region 42 43 #Region " X2 DependencyProperty " 44 ''' <summary> 45 ''' PropertyComment 46 ''' </summary> 47 ''' <remarks></remarks> 48 Public Shared ReadOnly X2Property As DependencyProperty = _ 49 DependencyProperty.Register( 50 " X2 " , GetType ( Double ), GetType (ALine), New FrameworkPropertyMetadata( _ 51 0.0 , FrameworkPropertyMetadataOptions.AffectsMeasure)) 52 53 Public Property X2() As Double 54 Get 55 Return GetValue(X2Property) 56 End Get 57 Set ( ByVal Value As Double ) 58 SetValue(X2Property, Value) 59 End Set 60 End Property 61 62 #End Region 63 64 #Region " Y2 DependencyProperty " 65 ''' <summary> 66 ''' PropertyComment 67 ''' </summary> 68 ''' <remarks></remarks> 69 Public Shared ReadOnly Y2Property As DependencyProperty = _ 70 DependencyProperty.Register( 71 " Y2 " , GetType ( Double ), GetType (ALine), New FrameworkPropertyMetadata( _ 72 0.0 , FrameworkPropertyMetadataOptions.AffectsMeasure)) 73 74 Public Property Y2() As Double 75 Get 76 Return GetValue(Y2Property) 77 End Get 78 Set ( ByVal Value As Double ) 79 SetValue(Y2Property, Value) 80 End Set 81 End Property 82 83 #End Region 84 85 #Region " TailWidth DependencyProperty " 86 ''' <summary> 87 ''' PropertyComment 88 ''' </summary> 89 ''' <remarks></remarks> 90 Public Shared ReadOnly TailWidthProperty As DependencyProperty = _ 91 DependencyProperty.Register( 92 " TailWidth " , GetType ( Double ), GetType (ALine), New FrameworkPropertyMetadata( _ 93 3.0 , FrameworkPropertyMetadataOptions.AffectsMeasure)) 94 Public Property TailWidth() As Double 95 Get 96 Return GetValue(TailWidthProperty) 97 End Get 98 Set ( ByVal Value As Double ) 99 SetValue(TailWidthProperty, Value) 100 End Set 101 End Property 102 103 #End Region

这里定义了X1,Y1,X2,Y2,TailWidth,这些属性足够说明,线的位置和尾部粗细。

ALine的内容

一个楔形是怎么画的呢?这只是一个几何问题,还是画一张图说明吧。

image

Sorry哈,反正就是Atan,sin,cos一通算,画图太费劲了,我就歇了哈。

代码 强制重载的DefiningGeometry
 
  
1 2 Protected Overrides ReadOnly Property DefiningGeometry As System.Windows.Media.Geometry 3 Get 4 Dim mGeometry As New StreamGeometry 5 mGeometry.FillRule = FillRule.EvenOdd 6 7 Using context As StreamGeometryContext = mGeometry.Open 8 DrawLineGeometry(context) 9 End Using 10 mGeometry.Freeze() 11 Return mGeometry 12 End Get 13 End Property 14 15 Private Sub DrawLineGeometry( ByVal context As StreamGeometryContext) 16 Dim theta As Double = Math.Atan2(Y1 - Y2, X1 - X2) 17 Dim sint As Double = Math.Sin(theta) 18 Dim cost As Double = Math.Cos(theta) 19 Dim pt1 As Point = New Point(X2, Y2) 20 Dim pt2 As Point = New Point(X1 - TailWidth * sint, Y1 + TailWidth * cost) 21 Dim pt3 As Point = New Point(X1 + TailWidth * sint, Y1 - TailWidth * cost) 22 context.BeginFigure(pt1, True , True ) 23 context.LineTo(pt2, True , True ) 24 context.LineTo(pt3, True , True ) 25 End Sub
实例

在一个空白窗口中,像使用Line一样。

 
  
1 < local:ALine X1 ="10" Y1 ="10" X2 ="100" Y2 ="100" TailWidth ="10" 2 Fill ="LightBlue" 3 Canvas.Left ="93" Canvas.Top ="76" 4 > 5 </ local:ALine >

就这个效果

image

 

我不得不说,这个思路是在网上找到的,既然找到了,给大家分享一下,是一件好事儿。

转载于:https://www.cnblogs.com/allofalan/archive/2012/04/20/2459813.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值