RectDrawingVisual.cs一个用于绘制ROI感兴趣区域矩形框的可视化组件using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Media;namespace ROIControl.Drawings{public class RectDrawingVisual:DrawingVisual{private readonly ROIBox _box;publicRectDrawingVisual(ROIBox box){this._boxbox;}public Rect Rect{get{return(Rect)GetValue(RectProperty);}set{SetValue(RectProperty,value);}}publicstaticreadonly DependencyProperty RectPropertyDependencyProperty.Register(Rect,typeof(Rect),typeof(RectDrawingVisual),newFrameworkPropertyMetadata(default(Rect),(d,e){RectDrawingVisual controld as RectDrawingVisual;if(controlnull)return;if(e.OldValue is Rect o){}if(e.NewValue is Rect n){}control.Draw();}));public Brush Stroke{get{return(Brush)GetValue(StrokeProperty);}set{SetValue(StrokeProperty,value);}}publicstaticreadonly DependencyProperty StrokePropertyDependencyProperty.Register(Stroke,typeof(Brush),typeof(RectDrawingVisual),newFrameworkPropertyMetadata(Brushes.Chartreuse,(d,e){RectDrawingVisual controld as RectDrawingVisual;if(controlnull)return;if(e.OldValue is Brush o){}if(e.NewValue is Brush n){}}));publicdoubleStrokeThickness{get{return(double)GetValue(StrokeThicknessProperty);}set{SetValue(StrokeThicknessProperty,value);}}publicstaticreadonly DependencyProperty StrokeThicknessPropertyDependencyProperty.Register(StrokeThickness,typeof(double),typeof(RectDrawingVisual),newFrameworkPropertyMetadata(1.0,(d,e){RectDrawingVisual controld as RectDrawingVisual;if(controlnull)return;if(e.OldValue isdoubleo){}if(e.NewValue isdoublen){}}));public Brush Fill{get{return(Brush)GetValue(FillProperty);}set{SetValue(FillProperty,value);}}publicstaticreadonly DependencyProperty FillPropertyDependencyProperty.Register(Fill,typeof(Brush),typeof(RectDrawingVisual),newFrameworkPropertyMetadata(newSolidColorBrush(Colors.Black){Opacity0.5},(d,e){RectDrawingVisual controld as RectDrawingVisual;if(controlnull)return;if(e.OldValue is Brush o){}if(e.NewValue is Brush n){}}));publicdoubleHandleLength{get{return(double)GetValue(HandleLengthProperty);}set{SetValue(HandleLengthProperty,value);}}publicstaticreadonly DependencyProperty HandleLengthPropertyDependencyProperty.Register(HandleLength,typeof(double),typeof(RectDrawingVisual),newFrameworkPropertyMetadata(6.0,(d,e){ROIBox controld as ROIBox;if(controlnull)return;if(e.OldValue isdoubleo){}if(e.NewValue isdoublen){}}));publicvoidDraw(){using var dcthis.RenderOpen();var combinenewCombinedGeometry(GeometryCombineMode.Exclude,newRectangleGeometry(this._box.BoundingBox),newRectangleGeometry(this.Rect));dc.PushClip(combine);dc.DrawRectangle(this.Fill,null,this._box.BoundingBox);dc.Pop();dc.DrawRectangle(Brushes.Transparent,newPen(this.Stroke,this.StrokeThickness),this.Rect);var centernewPoint(this.Rect.Leftthis.Rect.Width/2,this.Rect.Topthis.Rect.Height/2);DashStyle dashStylenewDashStyle();dashStyle.DashesnewDoubleCollection(newdouble[]{this.StrokeThickness*1,this.StrokeThickness*1});var dashpennewPen(this.Stroke,this.StrokeThickness/2){DashStyledashStyle};if(this._box.UseCross){//dc.DrawLine(dashpen, new Point(0, center.Y), new Point(this._box.BoundingBox.Right, center.Y));//dc.DrawLine(dashpen, new Point(center.X, 0), new Point(center.X, this._box.BoundingBox.Bottom));dc.DrawLine(dashpen,newPoint(0,center.Y),newPoint(this.Rect.Left,center.Y));dc.DrawLine(dashpen,newPoint(this.Rect.Right,center.Y),newPoint(this._box.BoundingBox.Right,center.Y));dc.DrawLine(dashpen,newPoint(center.X,0),newPoint(center.X,this.Rect.Top));dc.DrawLine(dashpen,newPoint(center.X,this.Rect.Bottom),newPoint(center.X,this._box.BoundingBox.Bottom));}doublehthicknessthis.HandleLength/3;dc.DrawHandle(this.Rect.TopLeft,this.Stroke,hthickness,this.HandleLength);dc.DrawHandle(this.Rect.BottomRight,this.Stroke,hthickness,this.HandleLength);dc.DrawHandle(this.Rect.TopRight,this.Stroke,hthickness,this.HandleLength);dc.DrawHandle(this.Rect.BottomLeft,this.Stroke,hthickness,this.HandleLength);dc.DrawHandle(newPoint(this.Rect.Left,center.Y),this.Stroke,hthickness,this.HandleLength);dc.DrawHandle(newPoint(this.Rect.Right,center.Y),this.Stroke,hthickness,this.HandleLength);dc.DrawHandle(newPoint(center.X,this.Rect.Top),this.Stroke,hthickness,this.HandleLength);dc.DrawHandle(newPoint(center.X,this.Rect.Bottom),this.Stroke,hthickness,this.HandleLength);FormattedText formattedTextnewFormattedText(${(int)this.Rect.Left},{(int)this.Rect.Top},{(int)this.Rect.Width},{(int)this.Rect.Height},System.Globalization.CultureInfo.CurrentCulture,FlowDirection.LeftToRight,newTypeface(Microsoft YaHei),10,Brushes.White,VisualTreeHelper.GetDpi(this).PixelsPerDip);dc.DrawText(formattedText,this.Rect.BottomLeft);}}publicstaticclass DrawingContextExtension{publicstaticvoidDrawHandle(this DrawingContext dc,Point point,Brush stroke,doublestrokeThickness1,doublelen6){doubleslen/2;dc.DrawRectangle(Brushes.White,newPen(stroke,strokeThickness),newRect(point.X-s,point.Y-s,len,len));}}}