有没有做网站的随州,安阳区号是多少号码,上海设计网站方法,模板建网站价格本文经原作者授权以原创方式二次分享#xff0c;欢迎转载、分享。原文作者#xff1a;眾尋原文地址#xff1a; https://www.cnblogs.com/ZXdeveloper/p/8600785.html前言这个是百度地图上北京地铁的地址#xff0c;我们先看下百度上面的效果图#xff1b;我要实现的内容比… 本文经原作者授权以原创方式二次分享欢迎转载、分享。原文作者眾尋原文地址 https://www.cnblogs.com/ZXdeveloper/p/8600785.html前言这个是百度地图上北京地铁的地址我们先看下百度上面的效果图我要实现的内容比较简单就是绘制这些图和在地铁线上滑动时会有跟着走的地铁名的提示。以下是我实现的简陋的效果一、准备数据我不会爬虫所以这里是用Fiddler把数据给扒下来由于北京地铁官网最近在维护中所以进不去不知道他们是不是提供了相关的数据如果数据丰富的话可做的东西还是很多的。F12打开开发者工具用鼠标工具选择地铁图会定位到相应的代码部分;数据就在SVG的结点下面我们把数据复制粘贴出来这些数据上我们能发现是分离开的举个例子1号线上有很多个站点例如苹果园、古城等但是在数据上你看不出1号线和苹果园、古城的关系所在也就是说展示给我们的数据是相对独立的。数据上提供了Path的路径Textblock和Ellipse的坐标信息。那我们就用这些信息简单的画一下北京地铁图。二、读取XML文件将扒下来的数据放到XML中稍微修改下因为会报错命名空间的问题很好弄就不贴了观察数据以后建立一个实体DrawInfo包含几个字段;public class DrawInfo{private string type;//类型 path text ellipse image private string pathData;//path的路径数据private string forColor;//颜色private double x;//坐标private double y;//坐标private string tooltip;//ToolTipprivate string id;//ID private string fontWeight;public string Type{get{return type;}set{type value;}}public string PathData{get{return pathData;}set{pathData value;}}public string ForColor{get{return forColor;}set{forColor value;}}public double X{get{return x;}set{x value;}}public double Y{get{return y;}set{y value;}}public string Tooltip{get{return tooltip;}set{tooltip value;}}public string Id{get{return id;}set{id value;}}public string FontWeight{get{return fontWeight;}set{fontWeight value;}}}DrawInfo下面是读取的方法;private void ReadXML(){doc.Load(xmlPath);XmlNodeList xmlNodeList doc.DocumentElement.GetElementsByTagName(g);foreach (XmlNode xn in xmlNodeList){foreach (XmlNode item in xn.ChildNodes){DrawInfo drawInfo null;if (item.Name path){drawInfo new DrawInfo(){Type path,PathData item.Attributes[d].InnerText,ForColor item.Attributes[stroke].InnerText,Tooltip item.Attributes[lb].InnerText,};}if (item.Name text){drawInfo new DrawInfo(){Type text,ForColor item.Attributes[fill].InnerText,X double.Parse(item.Attributes[x].InnerText),Y double.Parse(item.Attributes[y].InnerText),Tooltip item.InnerText,FontWeight item.Attributes[font-weight].InnerText};}if (item.Name ellipse){drawInfo new DrawInfo(){Type ellipse,ForColor item.Attributes[stroke].InnerText,X double.Parse(item.Attributes[cx].InnerText) - 6.5,Y double.Parse(item.Attributes[cy].InnerText) - 6.5,Tooltipitem.Attributes[name].InnerText,};}if (item.Name image){drawInfo new DrawInfo(){Type image,X double.Parse(item.Attributes[x].InnerText),Y double.Parse(item.Attributes[y].InnerText),Id item.Attributes[id].InnerText,Tooltipitem.Attributes[name].InnerText};}if (drawInfo ! null)DrInList.Add(drawInfo);}}}ReadXML由于是一个小Demo所以代码上写的不是很规范例如DrawInfo里面的字段好多我在后期都公用了而且定义的类型也不是很规范用了string而没使用Brush、FontWeight等在取XML结点的Name的时候也应该定义一个枚举类型我都没有去弄就是为了写小例子的时候省事一点但是在实际的生产代码中建议大家是规范的利人利己。三、绘制效果图数据从XML中拿到以后绘制效果图就方便多了代码就很容搞定;private void ShowSubWay(){foreach (DrawInfo item in DrInList){if (item.Type path){Style style win.FindResource(pathStyle) as Style;Path path new Path(){Style style,Data Geometry.Parse(item.PathData),Stroke (Brush)brushConverter.ConvertFromString(item.ForColor),ToolTip item.Tooltip};path.MouseMove Path_MouseMove;path.MouseLeave Path_MouseLeave;grid.Children.Add(path);}if (item.Type text){Style style win.FindResource(textblockStyle) as Style;TextBlock textBlock new TextBlock(){Style style,Foreground (Brush)brushConverter.ConvertFromString(item.ForColor),Margin new Thickness() { Left item.X, Top item.Y },Text item.Tooltip,FontWeight (FontWeight)new FontWeightConverter().ConvertFromString(item.FontWeight),};grid.Children.Add(textBlock);}if (item.Type ellipse){Style style win.FindResource(ellipseStyle) as Style;Ellipse ellipse new Ellipse(){Style style,Stroke (Brush)brushConverter.ConvertFromString(item.ForColor),Margin new Thickness() { Left item.X, Top item.Y },ToolTipitem.Tooltip};ellipse.MouseMove Ellipse_MouseMove;ellipse.MouseLeave Ellipse_MouseLeave;grid.Children.Add(ellipse);}if (item.Type image){Style style null;if (item.Id svgjsImage12298 || item.Id svgjsImage12302)style win.FindResource(imgAir) as Style;elsestyle win.FindResource(imgTran) as Style;Image img new Image(){Style style,Margin new Thickness() { Left item.X, Top item.Y },ToolTipitem.Tooltip};img.MouseMove Img_MouseMove;img.MouseLeave Img_MouseLeave;grid.Children.Add(img);}}}代码很Low羽神说我把WPF写成了Winform不得不承认是这个样子的binding什么的都没用但是后来想了想不是我不想用而是地铁图的路线不规则没有规律我就不知道怎么重写一个控件来绑定一个List集合统一进行展示了思考了挺久但是依然没有好的想法因为我们在公司做的binding都是基于数据层面的说白了就是前台的XAML变动不大或者变动的比较有规律例如重写Listbox的Template来实现统一的效果绑定数据以后自动展示。就像上面这个图就可以重写Listbox然后实现效果但是我这次的小Demo里没有做因为XML的数据中没有提供相关的东西也就没有去搞了相信做过WPF的看了这个图基本也就知道怎么搞了如果有没有思路的朋友可以留言问我。四、类似于ToolTip的地铁名提示这个功能特别的感谢李伟哥普通的地球人不得不说李伟哥的WPF特别厉害轻松的搞定了我当时出现的困扰。最开始做跟着鼠标走的ToolTip的时候首先想到的是ToolTip但是发现不好用因为他会定位到一个位置不会跟着走后来也用了Popup但是根据网上的方法会闪烁因为Popup是需要先隐藏再显示的所以有闪烁的效果在群里问了以后李伟哥很快给了一个Demo解答了我厉害在此谢谢李伟哥。Popup Grid.Row1 x:NamepopPath AllowsTransparencyTrueBorder BorderBrushTransparent BorderThickness0 BackgroundTransparentGrid HorizontalAlignmentCenter VerticalAlignmentCenterPath StrokeBlack StrokeThickness1 FillWhite DataM 0,0 L 120,0 L 120,30 L 65,30 L 60,35 L 55,30 L 0,30 Z /Grid x:NamegrpopPath Margin5,5,5,10TextBlock x:NametbPath ForegroundWhite FontSize13 HorizontalAlignmentCenter VerticalAlignmentCenter Style{Binding Null} //Grid/Grid/Border
/Popupprivate void Path_MouseMove(object sender, MouseEventArgs e)
{Path path (Path)sender;grpopPath.Background path.Stroke;tbPath.Text path.ToolTip.ToString();Point p e.GetPosition(mainGrid);popPath.IsOpen true;popPath.HorizontalOffset p.X - 60;popPath.VerticalOffset p.Y - mainGrid.ActualHeight - 40;
}private void Path_MouseLeave(object sender, MouseEventArgs e)
{popPath.IsOpen false;
}效果如图五、扩展1Grid这个控件我一直使用也习惯了用Grid但是在做的过程中确确实实学习到了不少东西在此感谢羽神不知道羽神的博客园地址问题是这样的就是绘制Path和Textblock的时候都没有问题但是绘制Ellipse的时候却出现问题了定位的位置不对严重便宜到右下方但是也设置了Grid的HorizontalAlignmentLeft VerticalAlignmentTop但是都不起作用。羽神一语道破是因为Grid的内部控件都是默认全部填充的需要设置控件自身的HorizontalAlignment和VerticalAlignment当时设置完以后就搞定了这个问题感谢羽神的帮助。2Canvas群里有人问为什么不用Canvas而用Grid我当时确实没有考虑过用Canvas说白了我不太习惯除非必要我个人喜欢用Grid所以当时给出的回答是“没想那么多”但是当做完以后后来想想改成Canvas试下效果但是发现了原因此处还真不能用Canvas需要用Grid因为我的外层用了Viewbox因为百度地图上趴下了的数据Path的路径和定位都特别的大都是2000多3000多大的样子用了Canvas没法显示下。可能大家不太好理解我举个例子外层用Viewbox窗体的大小是300*300的Viewbox下我们测试Canvas和GridCanvas和Grid下放置一个3000*3000的Button。上面是Canvas的例子代码和效果明细可以看到展示不出来Button就是最大化也不行我的电脑屏幕比较小。上面是Grid的例子能够看出Button是可以显示出来的填充了整个Viewbox这和地铁图的原理是一样的。有人可能会问Canvas如果不给宽和高呢如果Canvas不给宽和高则会在左侧顶点上你可以试验下就知道了。六、总结这个例子用到的知识点XML的读取控件的拖拽缩放内容不多但是与我个人而言每次做个小Demo都有所收获和成长因为公司不忙所以不想手生了只能没事做个小Demo补充自己的不足提高自己就像做的时候遇到的两个问题李伟哥和羽神给了很好的回答我都学习到了谢谢。源码