在本教程中,您将创建一个用户定义的结束样式,它是交叉结束的x形格式。然后将其与注释框架渲染集成。最后,以XML格式保存并加载它。
从中创建的项目开始在图像上绘制和编辑注释.
为main form的代码添加以下声明:
使用System.Xml;
向项目中添加一个新的c#类并命名AnnCrossLineEnding.设置要继承的新类AnnLineEnding.然后,重写一些成员,并通过向新类中添加以下代码来实现自定义结束样式的新功能:
//我们想要实现的自定义结束样式
公共类AnnCrossLineEnding: AnnLineEnding
{
公共AnnCrossLineEnding ()
{
}
受保护的覆盖AnnLineEnding Create ()
{
返回新AnnCrossLineEnding ();
}
公共覆盖AnnLineEnding克隆()
{
arrowLineEnding =基地.Clone ()作为AnnCrossLineEnding;
arrowLineEnding。关闭了=_closed;
返回arrowLineEnding;
}
公共覆盖intId
{
//注意,当创建自定义结束样式时,您添加了以前没有使用过的唯一Id
//对于现有的结束样式,id都是负的,所以我们将为自定义结束样式设置id = 1
得到{返回1;}
}
//这是一个属性,控制我们是否要关闭结束样式的十字形状
私人保龄球_closed =假;
公共保龄球关闭
{
得到{返回_closed;}
集{_closed = value;}
}
//返回组成样式形状的点数组,这将在呈现样式时使用,也在命中测试时使用
公共覆盖LeadPointD[] GetStylePoints(LeadPointD lineStart, LeadPointD lineEnd)
{
双长度=这. length。值/ 2;
//第一个交叉线开始
双lineStartX = lineStart.X;
双lineStartY = lineStart.Y;
LeadPointD pt0 = LeadPointD。创建(lineStartX - length, lineStartY - length);
LeadPointD pt1 = LeadPointD。创建(lineStartX + length, lineStartY + length);
LeadPointD pt2 = LeadPointD。创建(lineStartX - length, lineStartY + length);
LeadPointD pt3 = LeadPointD。创建(lineStartX + length, lineStartY - length);
返回新LeadPointD[] {pt0, pt1, pt2, pt3};
}
//在这里你可以指定你是否想要样式是可测试的,你可以通过拖动它来移动对象
公共覆盖保龄球HitTest (LeadPointD点,双hitTestBuffer, LeadPointD lineStart, LeadPointD lineEnd
{
返回假;
}
//保存自定义样式到xml文档
公共覆盖XmlNode serializeoptions选项,XmlNode parentNode, XmlDocument文档,字符串elementName)
{
XmlNode styleNode =基地.Serialize(选项,parentNode,文档,elementName);
XmlNode元素=文档。CreateElement (“StyleClosed”);
元素。在nerText = _closed.ToString();
styleNode.AppendChild(元素);
返回styleNode;
}
//从xml文档加载自定义样式
公共覆盖无效反序列化(AnnDeserializeOptions选项,XmlNode元素,XmlDocument文档)
{
基地.Deserialize(选项,元素,文档);
XmlNode childNode = element。SelectSingleNode (“StyleClosed”);
如果(childNode ! =零)
{
_closed =保龄球.Parse (childNode.FirstChild.Value);
}
}
在AnnPolyLineObjectRenderer覆盖方法AnnPolyLineObjectRenderer。RenderEndingStyles通过将下面的类添加到主表单代码:
//处理自定义结束样式的自定义折线渲染器
公共类AnnCustomPolylineObjectRenderer: AnnPolylineObjectRenderer
{
公共覆盖无效渲染(AnnContainerMapper映射器,AnnObject)
{
基地.Render (mapper annObject);
}
公共覆盖无效RenderEndingStyles(AnnContainerMapper, AnnPolylineObject)
{
//调用base来绘制原始的结尾样式
基地.RenderEndingStyles (mapper annPolyLineObject);
//现在我们将绘制结束样式
AnnCrossLineEnding startStyle = annPolyLineObject。StartStyle作为AnnCrossLineEnding;
AnnCrossLineEnding endStyle = annPolyLineObject。EndStyle作为AnnCrossLineEnding;
AnnWinFormsRenderingEngine =这.RenderingEngine作为AnnWinFormsRenderingEngine;
LeadPointCollection objectPoints = annPolyLineObject.Points;
intcount = objectPoints.Count;
如果(计数< 2)
返回;
如果(annPolyLineObject.SupportsLineEndings)
{
LeadPointD firstPoint = objectPoints[0];
如果(startStyle ! =零)
渲染crosslineending (startStyle,引擎,mapper, annPolyLineObject。FixedStateOperations, firstPoint, objectPoints[1]);
如果(endStyle ! =零)
RenderCrossLineEnding(endStyle, engine, mapper, annPolyLineObject。FixedStateOperations, objectPoints[count - 1], objectPoints[count - 2]);
}
}
私人无效RenderCrossLineEnding(AnnCrossLineEnding, AnnWinFormsRenderingEngine引擎,AnnContainerMapper映射器,AnnFixedStateOperations操作,LeadPointD lineStart, LeadPointD lineEnd)
{
AnnStroke stroke = mapper.StrokeFromContainerCoordinates(crossLineEnding。中风、操作);
如果(中风! =零)
{
LeadPointD[] endingStylePoints = mapper.PointsFromContainerCoordinates(crossLineEnding. pointfromcontainercoordinates)GetStylePoints(lineStart, lineEnd),操作);
如果(endingStylePoints ! =零& & endingStylePoints。长度== 4)
{
使用(钢笔钢笔= AnnWinFormsRenderingEngine.ToPen(笔画))
{
engine.Context。DrawLine(钢笔,AnnWinFormsRenderingEngine.ToPoint(endingStylePoints[0]), AnnWinFormsRenderingEngine.ToPoint(endingStylePoints[1]));
engine.Context。DrawLine(钢笔,AnnWinFormsRenderingEngine.ToPoint(endingStylePoints[2]), AnnWinFormsRenderingEngine.ToPoint(endingStylePoints[3]));
如果(crossLineEnding.Closed)
{
engine.Context。DrawLine(钢笔,AnnWinFormsRenderingEngine.ToPoint(endingStylePoints[0]), AnnWinFormsRenderingEngine.ToPoint(endingStylePoints[3]));
engine.Context。DrawLine(钢笔,AnnWinFormsRenderingEngine.ToPoint(endingStylePoints[2]), AnnWinFormsRenderingEngine.ToPoint(endingStylePoints[1]));
}
}
}
}
}
}
将新的自定义折线对象呈现器集成到注释框架中。将下面的代码添加到OnLoad(EventArgs e)
行后方法_annotations = new AutomationManagerHelper(automationManager);
:
//将自定义折线渲染器连接到现有渲染器
AnnPolylineObjectRenderer polyLineRenderer = automationManager.RenderingEngine.Renderers[AnnObject.LineObjectId]作为AnnPolylineObjectRenderer;
AnnCustomPolylineObjectRenderer customerrenderer =新AnnCustomPolylineObjectRenderer ();
cutomerRenderer。LocationsThumbStyle = polylinerender .LocationsThumbStyle;
cutomerRenderer。RotateCenterThumbStyle = polylinerender .RotateCenterThumbStyle;
cutomerRenderer。RotateGripperThumbStyle = polylinerender .RotateGripperThumbStyle;
automationManager.RenderingEngine.Renderers [AnnObject。LineObjectId] = customerrenderer;
将自定义结束样式设置为行对象。在主窗体的合适位置添加一个新按钮。将按钮的文本字段设置为添加自定义行尾和它的点击处理程序如下代码:
私人无效_btnAddCustomLineEnding_Click (对象发送者,EventArgs
{
AnnAutomation automation = _annotations.AutomationManager.Automations[0];
AnnCrossLineEnding startStyle =新AnnCrossLineEnding ();
startStyle。Length = automatic . container . map . lengthtocontainercoordinates (20);
AnnCrossLineEnding endStyle =新AnnCrossLineEnding ();
endStyle。Length = automatic . container . map . lengthtocontainercoordinates (20);
endStyle。关闭了=真正的;
如果(automation.Container.Children。计数> 0)
{
AnnPolylineObject = automation.Container.Children[0]作为AnnPolylineObject;
如果(annPolylineObject ! =零)
{
annPolylineObject。StartStyle =startStyle;
annPolylineObject。EndStyle =endStyle;
automation.Invalidate (LeadRectD.Empty);
}
}
}
要保存和加载自定义结束样式,请在主窗体的合适位置添加一个新按钮,并将其文本字段设置为保存/加载自定义样式.在按钮的点击处理程序中添加以下代码:
私人无效_btnSaveLoadCustomStyle_Click (对象发送者,EventArgs
{
AnnAutomation automation = _annotations.AutomationManager.Automations[0];
AnnContainer容器= automation.Container;
AnnCodecs =新AnnCodecs ();
AnnDeserializeOptions选项=新AnnDeserializeOptions ();
annCodecs。DeserializeOptions = options;
//当从xml加载时,钩子到DeserializeObject事件以创建自定义结尾样式实例
选项。DeserializeObject + =委托(对象sender2, AnnSerializeObjectEventArgs
{
AnnPolylineObject polyLine = args。AnnObject作为AnnPolylineObject;
如果(折线! =零& &折线。Id== AnnObject.LineObjectId)
{
如果(折线。StartStyle==零)
{
如果(arg游戏。TypeName = =“1”)//我们的自定义结束样式id是1
{
多段线。StartStyle =新AnnCrossLineEnding ();
}
}
其他的如果(折线。EndStyle ==零)
{
如果(arg游戏。TypeName = =“1”)//我们的自定义结束样式id是1
{
多段线。EndStyle=新AnnCrossLineEnding ();
}
}
}
};
annCodecs。保存(@“C: \ LEADTOOLS21 \资源\ \ temp.xml图像”,容器,AnnFormat。注释1);
//删除所有子容器,我们想从xml文件中加载它们。
container.Children.Clear ();
//加载保存的子容器,这包括自定义结束样式的行对象
AnnContainer tempContainer = annCodecs。负载(@“C: \ LEADTOOLS21 \资源\ \ temp.xml图像”1);
foreach(AnnObject AnnObject在tempContainer.Children)
container.Children.Add (annObject);
automation.Invalidate (LeadRectD.Empty);
}
构建并运行演示。在演示工具栏中,选择直线对象并绘制一条直线。下一步,单击添加自定义行尾按钮,您应该看到您的自定义结束样式。
现在点击保存/加载自定义样式按钮。注意,您的自定义结束样式正确地从XML文件加载。