winform中使用SVG矢量图,动态创建加载简单矢量图形
SVG文件加载
在winform中使用webbrowers控件加载外部html静态页面,在页面中使用SVG图形,在使用script可做到动态更新svg图形。在实际使用中发现在html中直接使用svg后,在webbrowers中无法显示svg图形,在web中使用svg可参考以下链接,示例中的方式都无法满足winform中使用。最后尝试直接在webbrowers中加载svg文件,发现可正常使用,后面只需要解决动态创建和刷新问题即可。
1 string pathSvgScript = AppDomain.CurrentDomain.BaseDirectory + @"images\deviceView\svgScript.svg"; 2 string pathSvgLine = AppDomain.CurrentDomain.BaseDirectory + @"images\deviceView\svgLine.svg"; 3 4 5 string a = "<?xml version=\"" + "1.0" + "\"" + " encoding=\"" + "utf-8\"?>" + "\r\n";//gbk 6 7 XDocument docSvgLine = XDocument.Load(pathSvgLine); 8 docSvgLine = SetLine(docSvgLine); 9 10 11 XElement eleSvgLine = XElement.Parse(docSvgLine.ToString()); 12 XDocument docSvgScript = XDocument.Load(pathSvgScript); 13 docSvgScript.Root.Add(eleSvgLine); 14 15 string asa = a + docSvgScript.ToString();
先将script和纯svg图形文件分开,使用setline方法动态生成svg图形,然后将svg图形插入到完整文件中,即可在界面正常显示。
xml文件操作
插入节点(可实现SVG动态创建)
1、获取文件 XDocument docSvgLine = XDocument.Load(pathSvgLine);
2、插入节点
若xml中上级存在命令空间,则插入下级节点时会自动添加 xmlns="" 属性,添加后导致新插入的节点无法正常显示
需要在新建此节点时加入命名空间
声明命名空间 XNamespace aw = "http://www.w3.org/2000/svg";(根据实际情况声明需要的命名空间)
1 XElement tdcSlave = new XElement(aw + "text"); 2 tdcSlave.Add(new XAttribute("x", x - 100)); 3 tdcSlave.Add(new XAttribute("y", yTdc)); 4 tdcSlave.Add(new XAttribute("style", "fill:rgb(255,255,255); text-anchor:middle;font-weight:normal")); 5 tdcSlave.Add(new XAttribute("font-family", "SimSun")); 6 tdcSlave.Add(new XAttribute("text-anchor", "middle")); 7 tdcSlave.Add(new XAttribute("font-size", "22")); 8 tdcSlave.Add(new XElement(aw + "tspan", "测试")); 9 docSvgLine.Root.Add(tdcSlave);
以上代码展示 新建一个节点,此节点加入了上级命名空间、节点中加入必要的属性和元素,最后将节点插入到xml文件中。
获取节点(可实现svg图形实时刷新)
若节点有id属性,可根据节点id获取 ,(picLine为webbrowers控件)
foreach (HtmlElement he in picLine.Document.All) { if (he.GetAttribute("id") != null) { string id = he.GetAttribute("id"); if (nameId.ContainsKey(id)) { he.InnerText = nameId[id]; } if (id.ToLower().Contains("status")) { if (nameId[id] == "1") { he.SetAttribute("style", "fill:rgb(0,255,0);stroke-width:1;stroke:rgb(0,0,0)"); he.Style = "fill:rgb(0,255,0);stroke-width:1;stroke:rgb(0,0,0"; } else if (nameId[id] == "4") { he.SetAttribute("style", "fill:rgb(255,0,0);stroke-width:1;stroke:rgb(0,0,0)"); he.Style = "fill:rgb(255,0,0);stroke-width:1;stroke:rgb(0,0,0"; } else { he.SetAttribute("style", "fill:rgb(255,255,255);stroke-width:1;stroke:rgb(0,0,0)"); he.Style = "fill:rgb(255,255,255);stroke-width:1;stroke:rgb(0,0,0"; } } } }
svgLine.svg文件
<?xml version="1.0" encoding="gbk"?> <g id="testdrag" xmlns="http://www.w3.org/2000/svg"> </g>
svgScript.svg文件
<?xml version="1.0" encoding="gbk"?> <svg onmousedown="Grab(evt)" xmlns:cge="http://www.cim.com" width="1366" onmousemove="Drag(evt)" xmlns:xlink="http://www.w3.org/1999/xlink" onload="Init(evt)" xmlns="http://www.w3.org/2000/svg" height="850px" version="1.1" onmouseup="Drop(evt)" > <rect width="110%" x="-10%" pointer-events="all" y="-10%" fill="none" height="110%" id="BackDrop" /> <g id="0" > <rect width="1366" height="850" style="fill:rgb(0,0,0)" /> </g> <script type="text/javascript" defer="true" ><![CDATA[ var SVGDocument = null; var SVGRoot = null; var TrueCoords = null; var GrabPoint = null; var BackDrop = null; var DragTarget = null; var width = 800; var height = 400; var gridLength = 20; var scale = 1; var svgPanel = null; function Init(evt){ SVGDocument = evt.target.ownerDocument; SVGRoot = SVGDocument.documentElement; TrueCoords = SVGRoot.createSVGPoint(); GrabPoint = SVGRoot.createSVGPoint(); BackDrop = SVGDocument.getElementById("BackDrop"); svgPanel = SVGDocument.getElementById("testdrag"); if(document.addEventListener){ document.addEventListener('DOMMouseScroll',scrollZoom,false); } window.onmousewheel=document.onmousewheel=scrollZoom; document.documentElement.style.overflowY = 'hidden'; //??????? } function scrollZoom(e){ e=e || window.event; if(isFirefox=navigator.userAgent.indexOf("Firefox")>0){ e.wheelDelta>0 || e.detail >0?zoom(0.9,e):zoom(1.1,e); }else{ e.wheelDelta>0 || e.detail >0?zoom(1.1,e):zoom(0.9,e); } } function zoom(num,e){ scale *= num; var sb = getMousePos(e); var sbx = sb.x; var sby = sb.y; svgPanel.setAttribute("transform-origin","0 0"); svgPanel.setAttribute("transform","scale("+scale+"),translate(-"+sbx+",-"+sby+")"); } function Grab(evt){ var targetElement = svgPanel; if (BackDrop != targetElement){ DragTarget = targetElement; DragTarget.parentNode.appendChild(DragTarget); DragTarget.setAttributeNS(null, "pointer-events", "none"); var transMatrix = DragTarget.getCTM(); GrabPoint.x = TrueCoords.x - Number(transMatrix.e); GrabPoint.y = TrueCoords.y - Number(transMatrix.f); } }; function getMousePos(event) { var e = event || window.event; return {'x':e.clientX,'y':e.clientY} } function Drag(evt){ GetTrueCoords(evt); if (DragTarget){ var newX = TrueCoords.x - GrabPoint.x; var newY = TrueCoords.y - GrabPoint.y; DragTarget.setAttributeNS(null, "transform", "translate(" + newX + "," + newY + "),scale("+scale+")"); } }; function Drop(evt){ if (DragTarget){ var targetElement = svgPanel; DragTarget.setAttributeNS(null, "pointer-events", "all"); if ("Folder" == targetElement.parentNode.id){ targetElement.parentNode.appendChild( DragTarget ); } else{} DragTarget = null; } }; function GetTrueCoords(evt){ var newScale = SVGRoot.currentScale; var translation = SVGRoot.currentTranslate; TrueCoords.x = (evt.clientX - translation.x)/newScale; TrueCoords.y = (evt.clientY - translation.y)/newScale; }; ]]></script> </svg>