绘制点线面以及符号界面设计
实验名称
空间几何图形的绘制,点、线、面符号界面设计与实现
实验目的
理解 ArcGIS Rumtime 关于点线面的几何实体类,掌握地图视图中几何图形的绘制方法和技巧,点线面符号界面设计与实现
实验准备
ArcGIS Runtime 100.6
实验内容与步骤
一、程序界面的设计
1.创建新的基于 ArcGIS Runtime 的 WPF 程序,命名为 MainWindow
2.在MainWindow窗体上放置一个 stackpanel,然后在其中放置 8 个按钮,并分别命名和修改其 content
3.为项目添加新的 WPF 窗体,命名新的窗体为 OptionsWindows
按Ctrl + Shift + A 也可以
之后在 解决方案资源管理器 就会多出对应文件
4.在OptionsWindows窗体上放置一个 TabControl 控件,打开该控件的 Items 集合,添加三个页面,分别用来设置点、线、面的符号
5.在“点符号”页面上,添加六个 radiobutton,分别用来点符号样式的选择;再添加一个 Slider 控件,用来设置符号大小;然后添加一个 Label 作为符号颜色的设置;最后添加三个按钮.
6.在“线符号”页面上,添加一个 combobox 控件,用来设置线符号的样式;再添加一个 slider 控件用来表示线的宽度;然后再添加一个 Rectangle 空间用来设置线的颜色;最后添加三个按钮.
7.为 combobox 控件添加 items,分别修改各 comboboxitem 的 content 属性值
8.在“面符号”页面上,添加一个 Listbox,用来表示填充符号的样式;添加一个 checkbox 控件,用来控制填充符号边框的可见性;添加一个 border 控件,并在其中放置一个 combobox 控件,用来设置边框样式,一个 textbox,用来设置边框宽度,一个 Rectangle 空间,用来设置边框颜色;再添加一个 Canvas 控件,用来设置填充颜色;最后添加三个按钮.
9.为 Listbox 控件添加八个 ListboxItem,分别表示八种填充模式,设置其背景为相应的图片
其实就是 SimpleFillSymbolStyle
里的8种
10.为边框样式的 combobox 控件添加 item
对应 SimpleLineSymbolStyle
里的5种
☞代码查看☜
二、为 optionswindow 窗体各 tab 页面添加相应的事件处理代码
1. 为窗体类添加下列成员
private SimpleMarkerSymbol pointSymbol;
private System.Drawing.Color pointColor;
private SimpleMarkerSymbolStyle pointStyle;
private double pointSize;
private SimpleLineSymbol lineSymbol;
private System.Drawing.Color lineColor;
private SimpleLineSymbolStyle lineStyle;
private double lineSize;
private SimpleFillSymbol fillSymbol;
private SimpleLineSymbol outlineSymbol;
private System.Drawing.Color fillColor;
private SimpleFillSymbolStyle fillStyle;
private System.Drawing.Color outlineColor;
private SimpleLineSymbolStyle outlineStyle;
private double outlineSize;
2.为“pointSymbol”、“lineSymbol”、“fillSymbol”三个成员添加属性
public SimpleMarkerSymbol PointSymbol
{
get
{
return pointSymbol;
}
set
{
pointSymbol = value;
}
}
public SimpleLineSymbol LineSymbol
{
get
{
return lineSymbol;
}
set
{
lineSymbol = value;
}
}
public SimpleFillSymbol FillSymbol
{
get
{
return fillSymbol;
}
set
{
fillSymbol = value;
}
}
3.为窗体的 Loaded 事件添加代码
这里是窗体 OptionsWindows
加载时运行的函数,目的是为了获取主窗体 MainWindow
里的一些图形属性,然后显示,不然的话,你点击options
按钮时,弹出的窗体的属性显示怎么知道你画的图形所带的属性呢
下面来看看没有添加这个事件会怎样,
后面的几个 Loaded
是同样的解释,就不再解释了。
private void Window_Loaded(object sender, RoutedEventArgs e)
{
if (pointSymbol != null)
{
pointColor = pointSymbol.Color;
pointStyle = pointSymbol.Style;
pointSize = pointSymbol.Size;
}
if (lineSymbol != null)
{
lineColor = lineSymbol.Color;
lineStyle = lineSymbol.Style;
lineSize = lineSymbol.Width;
}
if (fillSymbol != null)
{
fillColor = fillSymbol.Color;
fillStyle = fillSymbol.Style;
if (fillSymbol.Outline != null)
{
outlineSymbol = (SimpleLineSymbol)fillSymbol.Outline;
outlineCheckBox.IsChecked = true;
outlineBorder.Visibility = Visibility.Visible;
}
else
{
outlineSymbol = null;
outlineCheckBox.IsChecked = false;
outlineBorder.Visibility = Visibility.Collapsed;
}
// 记得加这三行代码,不然后面初始化获取不了当前属性
outlineColor = outlineSymbol.Color;
outlineStyle = outlineSymbol.Style;
outlineSize = outlineSymbol.Width;
}
}
4.(Point)为“点符号” tab 页的 Loaded
事件添加代码
private void PointPropertyTab_Loaded(object sender, RoutedEventArgs e)
{
switch (pointStyle)
{
case SimpleMarkerSymbolStyle.Cross:
radioButton1.IsChecked = true;
break;
case SimpleMarkerSymbolStyle.Diamond:
radioButton2.IsChecked = true;
break;
case SimpleMarkerSymbolStyle.Square:
radioButton3.IsChecked = true;
break;
case SimpleMarkerSymbolStyle.X:
radioButton4.IsChecked = true;
break;
case SimpleMarkerSymbolStyle.Triangle:
radioButton5.IsChecked = true;
break;
case SimpleMarkerSymbolStyle.Circle:
radioButton6.IsChecked = true;
break;
}
sizeSlider.Value = pointSize/10; //pointSize/10 这里的除以10,是为了抵消MainWindow.xaml.cs里设置的初始点符号大小,不然的话, silder 控件一打开就是显示10了,不懂的话可以试试把v/10改回v
System.Windows.Media.Color c = System.Windows.Media.Color.FromArgb(pointColor.A, pointColor.R, pointColor.G, pointColor.B);
colorLabel.Background = new SolidColorBrush(c);
//int v = Convert.ToInt32(sizeSlider.Value);
//sizeLabel.Content = "大小:" + v.ToString();
}
5.(Point)为“点符号”tab 页中的 radiobutton 的 checked
事件添加代码
private void radioButton1_Checked(object sender, RoutedEventArgs e)
{
pointStyle = SimpleMarkerSymbolStyle.Circle;
}
private void radioButton2_Checked(object sender, RoutedEventArgs e)
{
pointStyle = SimpleMarkerSymbolStyle.Cross;
}
private void radioButton3_Checked(object sender, RoutedEventArgs e)
{
pointStyle = SimpleMarkerSymbolStyle.Diamond;
}
private void radioButton4_Checked(object sender, RoutedEventArgs e)
{
pointStyle = SimpleMarkerSymbolStyle.Square;
}
private void radioButton5_Checked(object sender, RoutedEventArgs e)
{
pointStyle = SimpleMarkerSymbolStyle.X;
}
private void radioButton6_Checked(object sender, RoutedEventArgs e)
{
pointStyle = SimpleMarkerSymbolStyle.Triangle;
}
6.(Point)为“点符号”tab 页的 silder 控件的 ValueChanged
事件添加代码
private void sizeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
// 注意这里,当你一点击options按钮时,程序会自动执行这一部分代码,所以可以发现ValueChanged事件,会在程序一启动就会先调用一次,有点类似Vue的Watch侦视了
// 所以我把老师给的PointPropertyTab_Loaded(object sender, RoutedEventArgs e)函数里最后的两行代码156、157注释了
double v = e.NewValue;
sizeLabel.Content = "大小:" + v.ToString();
pointSize = v * 10; // 自己加的,目的是把点符号扩大10倍,之前的感觉有点小了(#^.^#)
}
7.(Point)为“点符号”tab 页的颜色 label 控件的 MouseDoubleClick
事件添加代码,设置颜色
private void colorLabel_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
System.Windows.Forms.ColorDialog clrDlg = new System.Windows.Forms.ColorDialog(); // 新建颜色对话框,还未弹出
Console.WriteLine("111:"+clrDlg); // 初始化颜色,111:System.Windows.Forms.ColorDialog, Color: Color [Black]
SolidColorBrush s = (SolidColorBrush)colorLabel.Background;
Console.WriteLine("222:"+s); // 获取当前颜色 222:#FF0000FF
clrDlg.Color = System.Drawing.Color.FromArgb(s.Color.A, s.Color.R, s.Color.G, s.Color.B);// 转换颜色类型,就是将System.Windows.Media.Color转为System.Drawing.Color
if (clrDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) //弹出颜色对话框,等待用户选择并确定
{
pointColor = clrDlg.Color;// 读取用户选择的颜色
Console.WriteLine("333:"+pointColor); // 读取用户选择的颜色:333:Color [Yellow]
System.Windows.Media.Color c = System.Windows.Media.Color.FromArgb(pointColor.A, pointColor.R, pointColor.G, pointColor.B); // 转换颜色类型,就是将System.Drawing.Color转为System.Windows.Media.Color
colorLabel.Background = new SolidColorBrush(c);// 设置为父对话框Label的颜色背景
/*备注一下:
* System.Windows.Forms.ColorDialog clrDlg 就是双击Label时,弹出来的颜色对话框,它的颜色类型是System.Drawing.Color
* colorLabel.Background 也就是点击options按钮时显示的对话框里面的Label的颜色 它的颜色类型是System.Windows.Media.Color
* SolidColorBrush s = (SolidColorBrush)colorLabel.Background; 所以这行可以直接强制类型转换,因为一开始读取的是Label的背景,类型是System.Windows.Media.Color,后面两者通过FromArgb来相互转换
*/
}
}
8.(Point)为“点符号” tab 页中的三个 button 的点击事件添加代码
private void OKBtn_Click(object sender, RoutedEventArgs e)
{
pointSymbol.Color = pointColor;
pointSymbol.Style = pointStyle;
pointSymbol.Size = pointSize;
this.Close(); // 目前感觉this.Close()和this.DialogResult = true区别不是很大,this就是弹出来的窗体
//this.DialogResult = true; //老师代码只有这一行,但我觉得不是很好,如果只有这一行,那跟取消按钮没区别了呀,所以我加了上面的三行代码
}
private void CancelBtn_Click(object sender, RoutedEventArgs e)
{
this.Close();//同样这里也用this.Close()替代一下,若有Bugger我再提醒
//this.DialogResult = false;
}
private void ApplyBtn_Click(object sender, RoutedEventArgs e)
{
pointSymbol.Color = pointColor;
pointSymbol.Style = pointStyle;
pointSymbol.Size = pointSize;
}
9.(Line)为“线符号” tab 页的 Loaded
事件添加代码
private void linePropertyTab_Loaded(object sender, RoutedEventArgs e)
{
// lineStyle在窗体加载的时候就已经获取并设置了
switch (lineStyle)
{
case SimpleLineSymbolStyle.Solid:
lineStyleCombobox.SelectedIndex = 0;
break;
case SimpleLineSymbolStyle.Dash:
lineStyleCombobox.SelectedIndex = 1;
break;
case SimpleLineSymbolStyle.Dot:
lineStyleCombobox.SelectedIndex = 2;
break;
case SimpleLineSymbolStyle.DashDot:
lineStyleCombobox.SelectedIndex = 3;
break;
case SimpleLineSymbolStyle.DashDotDot:
lineStyleCombobox.SelectedIndex = 4;
break;
case SimpleLineSymbolStyle.Null:
lineStyleCombobox.SelectedIndex = -1;
break;
}
lineWidthSlider.Value = lineSize; // 设置对应控件的值
System.Windows.Media.Color curColor = System.Windows.Media.Color.FromArgb(lineColor.A, lineColor.R, lineColor.G, lineColor.B);
lineColorRectangle.Fill = new System.Windows.Media.SolidColorBrush(curColor); // 设置对应控件的填充颜色
}
10.(Line)为“线符号” tab 页中的 combobox 控件添加 SelectionChanged
事件添加代码
private void lineStyleCombobox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
int index = lineStyleCombobox.SelectedIndex;
switch (index)
{
case 0:
lineStyle = SimpleLineSymbolStyle.Solid;
break;
case 1:
lineStyle = SimpleLineSymbolStyle.Dash;
break;
case 2:
lineStyle = SimpleLineSymbolStyle.Dot;
break;
case 3:
lineStyle = SimpleLineSymbolStyle.DashDot;
break;
case 4:
lineStyle = SimpleLineSymbolStyle.DashDotDot;
break;
default:
lineStyle = SimpleLineSymbolStyle.Null;
break;
}
}
11.(Line)为“线符号” tab 页中的 slider 控件的 ValueChanged
事件添加代码
private void lineWidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
// 注意这里,当你一点击options按钮时,程序会自动执行这一部分代码
Console.WriteLine("lineSize旧值:" + lineSize);
lineSize = e.NewValue;
Console.WriteLine("lineSize新值:" + lineSize);
lineSizeLabel.Content = "宽度:" + lineSize.ToString();
}
12.(Line)为“线符号” tab 页中的 Rectangle 控件的 MouseDown
事件添加代码,设置填充颜色
/*这里你会不会跟我有同样的疑问,为什么老师不用MouseDoubleClick事件呢?
* 我自己尝试了一下,把上面的点符号的颜色这支代码copy过来,稍微改了一下,代码在下面的注释那里,然后在界面设计器添加事件时,我发现是什么原因了
* 原因就是 Rectangle 控件 没有 MouseDoubleClick 这个属性,所以老师用了 e.ClickCount == 2 来替代 MouseDoubleClick
*/
private void LineColorRectangle_MouseDown(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("e.ClickCount:" + e.ClickCount);
if (e.ClickCount == 2) // 判断是否鼠标连续双击
{
//这里的代码跟点符号那里的颜色设置的代码的解释是一样的,这里就不解释了,不懂的返回去看
System.Windows.Forms.ColorDialog clrDlg = new System.Windows.Forms.ColorDialog();
System.Windows.Media.SolidColorBrush br = (System.Windows.Media.SolidColorBrush)lineColorRectangle.Fill;
clrDlg.Color = System.Drawing.Color.FromArgb(br.Color.A, br.Color.R, br.Color.G, br.Color.B);
if (clrDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
System.Windows.Media.Color selColor = System.Windows.Media.Color.FromArgb(clrDlg.Color.A, clrDlg.Color.R, clrDlg.Color.G, clrDlg.Color.B);
lineColorRectangle.Fill = new System.Windows.Media.SolidColorBrush(selColor);
lineColor = clrDlg.Color;
}
}
}
/*
//为“线符号” tab 页的颜色 label 控件的 MouseDoubleClick 事件添加代码,设置颜色
private void colorRectangle_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
System.Windows.Forms.ColorDialog clrDlg = new System.Windows.Forms.ColorDialog(); // 新建颜色对话框,还未弹出
Console.WriteLine("111:" + clrDlg); // 初始化颜色,111:System.Windows.Forms.ColorDialog, Color: Color [Black]
SolidColorBrush s = (SolidColorBrush)lineColorRectangle.Fill;
Console.WriteLine("222:" + s); // 获取当前颜色 222:#FF0000FF
clrDlg.Color = System.Drawing.Color.FromArgb(s.Color.A, s.Color.R, s.Color.G, s.Color.B);// 转换颜色类型,就是将System.Windows.Media.Color转为System.Drawing.Color
if (clrDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) //弹出颜色对话框,等待用户选择并确定
{
pointColor = clrDlg.Color;// 读取用户选择的颜色
Console.WriteLine("333:" + pointColor); // 读取用户选择的颜色:333:Color [Yellow]
System.Windows.Media.Color c = System.Windows.Media.Color.FromArgb(pointColor.A, pointColor.R, pointColor.G, pointColor.B); // 转换颜色类型,就是将System.Drawing.Color转为System.Windows.Media.Color
lineColorRectangle.Fill = new SolidColorBrush(c);// 设置为父对话框Label的颜色背景
lineColor = clrDlg.Color;
//备注一下:
//System.Windows.Forms.ColorDialog clrDlg 就是双击Label时,弹出来的颜色对话框,它的颜色类型是System.Drawing.Color
//colorLabel.Background 也就是点击options按钮时显示的对话框里面的Label的颜色 它的颜色类型是System.Windows.Media.Color
//SolidColorBrush s = (SolidColorBrush)colorLabel.Background; 所以这行可以直接强制类型转换,因为一开始读取的是Label的背景,类型是System.Windows.Media.Color,后面两者通过FromArgb来相互转换
}
}
*/
所以不是不用,而是用不了haha
13.(Line)为“线符号” tab 页中的三个按钮添加点击事件处理代码
private void lineOKBtn_Click(object sender, RoutedEventArgs e)
{
LineSymbol.Style = lineStyle;
LineSymbol.Color = lineColor;
LineSymbol.Width = lineSize;
this.Close();
//this.DialogResult = true; // 这里的设置同样跟点符号的一样,老师只写了这一行代码,所以参照点符号那里的设置,不懂的返回去看
}
private void lineCancelBtn_Click(object sender, RoutedEventArgs e)
{
this.Close();
//this.DialogResult = false;
}
private void lineApplyBtn_Click(object sender, RoutedEventArgs e)
{
LineSymbol.Style = lineStyle;
LineSymbol.Color = lineColor;
LineSymbol.Width = lineSize;
}
14.(Polygon)为“面符号” tab 页的 Loaded
事件添加代码
private void fillPropertyTab_Loaded(object sender, RoutedEventArgs e)
{
// 读取当前图形的填充样式
switch (fillStyle)
{
case SimpleFillSymbolStyle.DiagonalCross:
fillStyleListBox.SelectedIndex = 0;
break;
case SimpleFillSymbolStyle.Horizontal:
fillStyleListBox.SelectedIndex = 1;
break;
case SimpleFillSymbolStyle.Null:
fillStyleListBox.SelectedIndex = 2;
break;
case SimpleFillSymbolStyle.Vertical:
fillStyleListBox.SelectedIndex = 3;
break;
case SimpleFillSymbolStyle.Solid:
fillStyleListBox.SelectedIndex = 4;
break;
case SimpleFillSymbolStyle.Cross:
fillStyleListBox.SelectedIndex = 5;
break;
case SimpleFillSymbolStyle.ForwardDiagonal:
fillStyleListBox.SelectedIndex = 6;
break;
case SimpleFillSymbolStyle.BackwardDiagonal:
fillStyleListBox.SelectedIndex = 7;
break;
}
Console.WriteLine("outlineCheckBox.IsChecked==true:" + outlineCheckBox.IsChecked);
// 先判断那个边界线的勾勾是否打上了,感觉这个判断应该可以不用了
if (outlineCheckBox.IsChecked == true)
{
Console.WriteLine("进来了!");
// 读取当前边框线的样式
switch (outlineStyle)
{
case SimpleLineSymbolStyle.Solid:
outlineStyleComboBox.SelectedIndex = 0;
break;
case SimpleLineSymbolStyle.Dash:
outlineStyleComboBox.SelectedIndex = 1;
break;
case SimpleLineSymbolStyle.Dot:
outlineStyleComboBox.SelectedIndex = 2;
break;
case SimpleLineSymbolStyle.DashDot:
outlineStyleComboBox.SelectedIndex = 3;
break;
case SimpleLineSymbolStyle.DashDotDot:
outlineStyleComboBox.SelectedIndex = 4;
break;
case SimpleLineSymbolStyle.Null:
outlineStyleComboBox.SelectedIndex = -1;
break;
}
Console.WriteLine("outlineStyle:"+outlineStyle);
// 读取当前边框线的大小
outlineTextBox.Text = outlineSize.ToString();
Console.WriteLine("outlineTextBox.Text:"+ outlineTextBox.Text);
// 读取当前边框线的颜色
System.Windows.Media.Color vr = System.Windows.Media.Color.FromArgb(outlineColor.A, outlineColor.R, outlineColor.G, outlineColor.B);
outlineColorRectangle.Fill = new System.Windows.Media.SolidColorBrush(vr);
Console.WriteLine("outlineColorRectangle.Fill:"+ outlineColorRectangle.Fill);
// 读取当前图形的填充颜色
System.Windows.Media.Color vc = System.Windows.Media.Color.FromArgb(fillColor.A, fillColor.R, fillColor.G, fillColor.B);
fillColorCanvas.Background = new System.Windows.Media.SolidColorBrush(vc);
}
}
15.(Polygon)为“面符号” tab 页中的 combobox 控件添加 SelectionChanged
事件添加代码,设置图形填充样式
private void fillStyleListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
int index = fillStyleListBox.SelectedIndex;
Console.WriteLine("outlineStyleComboBox.SelectedIndex:" + index);
// 对应八种填充样式
switch (index)
{
case 0:
fillStyle = SimpleFillSymbolStyle.DiagonalCross;
break;
case 1:
fillStyle = SimpleFillSymbolStyle.Horizontal;
break;
case 2:
fillStyle = SimpleFillSymbolStyle.Null;
break;
case 3:
fillStyle = SimpleFillSymbolStyle.Vertical;
break;
case 4:
fillStyle = SimpleFillSymbolStyle.Solid;
break;
case 5:
fillStyle = SimpleFillSymbolStyle.Cross;
break;
case 6:
fillStyle = SimpleFillSymbolStyle.ForwardDiagonal;
break;
case 7:
fillStyle = SimpleFillSymbolStyle.BackwardDiagonal;
break;
default:
fillStyle = SimpleFillSymbolStyle.Solid;
break;
}
}
16.(Polygon)为“面符号” tab 页中的 combobox 控件添加 SelectionChanged
事件添加代码,设置边框线样式
private void outlineStyleComoBoxBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
int index = outlineStyleComboBox.SelectedIndex;
Console.WriteLine("lineStyleCombobox.SelectedIndex:"+ index);
// 对应五种线样式
switch (index)
{
case 0:
outlineStyle = SimpleLineSymbolStyle.Solid;
break;
case 1:
outlineStyle = SimpleLineSymbolStyle.Dash;
break;
case 2:
outlineStyle = SimpleLineSymbolStyle.Dot;
break;
case 3:
outlineStyle = SimpleLineSymbolStyle.DashDot;
break;
case 4:
outlineStyle = SimpleLineSymbolStyle.DashDotDot;
break;
default:
outlineStyle = SimpleLineSymbolStyle.Null;
break;
}
}
17.(Polygon)为“面符号” tab 页中的 TextBox 控件的 TextChanged
事件添加代码,设置边框线大小
private void OutlineTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
outlineSize = Convert.ToInt32(outlineTextBox.Text);
Console.WriteLine("边框线大小:" + outlineSize);
}
18.(Polygon)为“面符号” tab 页中的 Rectangle 控件的 MouseDown
事件添加代码,设置边框线颜色
private void OutlineColorRectangle_MouseDown(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("e.ClickCount:" + e.ClickCount);
if (e.ClickCount == 2) // 判断是否鼠标连续双击
{
//这里的代码跟点符号那里的颜色设置的代码的解释是一样的,这里就不解释了,不懂的返回去看
System.Windows.Forms.ColorDialog clrDlg = new System.Windows.Forms.ColorDialog();
System.Windows.Media.SolidColorBrush br = (System.Windows.Media.SolidColorBrush)outlineColorRectangle.Fill;
clrDlg.Color = System.Drawing.Color.FromArgb(br.Color.A, br.Color.R, br.Color.G, br.Color.B);
if (clrDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
System.Windows.Media.Color selColor = System.Windows.Media.Color.FromArgb(clrDlg.Color.A, clrDlg.Color.R, clrDlg.Color.G, clrDlg.Color.B);
outlineColorRectangle.Fill = new System.Windows.Media.SolidColorBrush(selColor);
outlineColor = clrDlg.Color;
}
}
}
19.(Polygon)为“面符号” tab 页中的 Rectangle 控件的 MouseDown
事件添加代码,设置填充颜色
private void colorCanvas_MouseDown(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("e.ClickCount:" + e.ClickCount);
if (e.ClickCount == 2) // 判断是否鼠标连续双击
{
//这里的代码跟点符号那里的颜色设置的代码的解释是一样的,这里就不解释了,不懂的返回去看
System.Windows.Forms.ColorDialog clrDlg = new System.Windows.Forms.ColorDialog();
System.Windows.Media.SolidColorBrush br = (System.Windows.Media.SolidColorBrush)fillColorCanvas.Background;
clrDlg.Color = System.Drawing.Color.FromArgb(br.Color.A, br.Color.R, br.Color.G, br.Color.B);
if (clrDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
System.Windows.Media.Color selColor = System.Windows.Media.Color.FromArgb(clrDlg.Color.A, clrDlg.Color.R, clrDlg.Color.G, clrDlg.Color.B);
fillColorCanvas.Background = new System.Windows.Media.SolidColorBrush(selColor);
fillColor = clrDlg.Color;
}
}
}
20.(Polygon)为“面符号” tab 页中的三个按钮添加点击事件处理代码
private void fillOKBtn_Click(object sender, RoutedEventArgs e)
{
//判断语句,用于判断outlineCheckBox的勾勾有没有打上
if (outlineCheckBox.IsChecked == true)
{
outlineSymbol = new SimpleLineSymbol(outlineStyle, outlineColor, outlineSize);
Console.WriteLine("outlineSymbol:" + outlineSymbol.Style + "\n" + outlineSymbol.Color + "\n" + outlineSymbol.Width);
}
else
{
outlineSymbol = null;
}
FillSymbol.Style = fillStyle;
FillSymbol.Color = fillColor;
FillSymbol.Outline = outlineSymbol;
this.Close();
//this.DialogResult = true; // 这里的设置同样跟点符号的一样,所以参照点符号那里的设置,不懂的返回去看
}
private void fillCancelBtn_Click(object sender, RoutedEventArgs e)
{
this.Close();
//this.DialogResult = false;
}
private void fillApplyBtn_Click(object sender, RoutedEventArgs e)
{
//判断语句,用于判断outlineCheckBox的勾勾有没有打上
if (outlineCheckBox.IsChecked == true)
{
outlineSymbol = new SimpleLineSymbol(outlineStyle,outlineColor,outlineSize);
Console.WriteLine("outlineSymbol:" + outlineSymbol.Style + "\n" + outlineSymbol.Color + "\n" + outlineSymbol.Width);
}
else
{
outlineSymbol = null;
}
FillSymbol.Style = fillStyle;
FillSymbol.Color = fillColor;
FillSymbol.Outline = outlineSymbol;
}
三、绘制图形(MainWindow主窗体
)
1.在 MainWindow 所在命名空间中定义一个枚举类型
enum DrawType
{
None,
DrawPoint,
DrawLine,
DrawArea
};
**2.为 MainWindow 类添加成员变量**
```c#
private SimpleMarkerSymbol pointSymbol;
private SimpleLineSymbol lineSymbol;
private SimpleFillSymbol fillSymbol;
private DrawType drawingType;
private Esri.ArcGISRuntime.Geometry.PointCollection linePoints;
private List<Graphic> linesList;
private List<Graphic> polygonList;
3.在 MainWindow 类的构造函数中初始化成员变量
public MainWindow()
{
InitializeComponent();
// 赋值变量
pointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle.Diamond, System.Drawing.Color.Blue, 10.0); // 默认点符号,这里乘10,是想把初始的点符号设置打一点
lineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, System.Drawing.Color.Red, 1.0); // 默认线符号
fillSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle.DiagonalCross, System.Drawing.Color.Yellow, new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, System.Drawing.Color.YellowGreen, 1.0)); // 默认面符号 填充,填充颜色,边框
drawingType = DrawType.None; // 枚举变量
linePoints = new Esri.ArcGISRuntime.Geometry.PointCollection(new SpatialReference(3857)); // 点集合
linesList = new List<Graphic>(); // 线集合
polygonList = new List<Graphic>(); // 面集合
}
4.为 MainWindow 的 Loaded
事件处理添加代码
private void Window_Loaded(object sender, RoutedEventArgs e)
{
GraphicsOverlay graphicLayer = new GraphicsOverlay(); // 涂层是一张白纸,覆盖物就是这张白纸上所画出来的东东
myMapView.GraphicsOverlays.Add(graphicLayer); // GraphicsOverlays 覆盖物的集合
}
5.为“Add Layer”按钮点击事件处理添加代码
private async void AddLayerBtn_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog(); // 打开文件对话框
ofd.Title = "打开Shapefile文件";
ofd.Filter = "Shapefile文件(*.shp)|*.shp";
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
String filePath = ofd.FileName;
ShapefileFeatureTable shpFT = await ShapefileFeatureTable.OpenAsync(filePath);
FeatureLayer ftLayer = new FeatureLayer(shpFT);
myMapView.Map.OperationalLayers.Add(ftLayer);
await myMapView.SetViewpointGeometryAsync(ftLayer.FullExtent);
}
}
6.为“Draw Point”按钮点击事件处理添加代码
private void DrawPointBtn_Click(object sender, RoutedEventArgs e)
{
drawingType = DrawType.DrawPoint;
}
7.为“Draw Line”按钮点击事件处理添加代码
private void DrawLineBtn_Click(object sender, RoutedEventArgs e)
{
drawingType = DrawType.DrawLine;
linePoints.Clear();
}
8.为“Draw Polygon”按钮点击事件处理添加代码
private void DrawPolygonBtn_Click(object sender, RoutedEventArgs e)
{
drawingType = DrawType.DrawArea;
linePoints.Clear();
}
9.为“Return”按钮点击事件处理添加代码
这里就类似于我们软件上的撤销,但是我这里做了一些限制,不能一直撤销,后面有时间再完善了(⊙︿⊙)
private void Return_Click(object sender, RoutedEventArgs e)
{
// 线图层,返回上一步,点数必须大于2
if (drawingType == DrawType.DrawLine)//画线
{
if (linePoints.Count > 2)
{
linePoints.RemoveAt(linePoints.Count - 1);
Graphic curGraphic = linesList[linesList.Count - 1];
myMapView.GraphicsOverlays[0].Graphics.Remove(curGraphic);
linesList.Remove(curGraphic);
Esri.ArcGISRuntime.Geometry.Polyline line = new Esri.ArcGISRuntime.Geometry.Polyline(linePoints);
Graphic lineGraphic = new Graphic(line, lineSymbol);
myMapView.GraphicsOverlays[0].Graphics.Add(lineGraphic);
linesList.Add(lineGraphic);
}
}
// 面图层,返回上一步,点数必须大于3
else if (drawingType == DrawType.DrawArea)
{
if (linePoints.Count > 3)
{
linePoints.RemoveAt(linePoints.Count - 1);
Graphic curGraphic = polygonList[polygonList.Count - 1];
myMapView.GraphicsOverlays[0].Graphics.Remove(curGraphic);
polygonList.Remove(curGraphic);
Esri.ArcGISRuntime.Geometry.Polygon polygon = new Esri.ArcGISRuntime.Geometry.Polygon(linePoints);
Graphic polygonGraphic = new Graphic(polygon, fillSymbol);
myMapView.GraphicsOverlays[0].Graphics.Add(polygonGraphic);
polygonList.Add(polygonGraphic);
}
}
}
10.为“Clear”按钮点击事件处理添加代码
private void Clear_Click(object sender, RoutedEventArgs e)
{
int index = myMapView.GraphicsOverlays[0].Graphics.Count;
if(index > 0)
myMapView.GraphicsOverlays[0].Graphics.RemoveAt(index - 1);
linePoints.Clear();
}
11.为“Clear All”按钮点击事件处理添加代码
private void clearAllBtn_Click(object sender, RoutedEventArgs e)
{
MessageBoxResult vr = System.Windows.MessageBox.Show("确定清除全部图层?(●__●)", "操作提示", MessageBoxButton.OKCancel, MessageBoxImage.Question);
if(vr == MessageBoxResult.OK)
{
myMapView.GraphicsOverlays[0].Graphics.Clear(); // 因为只新建了一层,所以索引为0,清除该图层
linePoints.Clear();
}
}
12.绘制线图形和面图形
这里我直接把它们的代码提取出来了,需要的时候调用就可以了
//画线图形
private void draw_Line()
{
if (linePoints.Count >= 2)//如果点集中点数足够
{
if (linesList.Count > 0 && linePoints.Count > 2)//已有加入的线图形,则移除当前的图形,重新加入新的图形
{
Graphic curGraphic = linesList[linesList.Count - 1];//获取上一次的点击的点形成的线图形,为了后面删除,想想,如果不删除,如果点n下,那将会有n-1条线段
Console.WriteLine("myMapView_MouseLeftButtonDown3:" + curGraphic); // 输出:Esri.ArcGISRuntime.UI.Graphic
myMapView.GraphicsOverlays[0].Graphics.Remove(curGraphic);
Console.WriteLine("移除显示的线图层");
linesList.Remove(curGraphic);
Console.WriteLine("linesList个数:" + linesList.Count);
Console.WriteLine("linePoints点数:" + linePoints.Count);
Console.WriteLine("移除容器内的线图层");
}
Esri.ArcGISRuntime.Geometry.Polyline line = new Esri.ArcGISRuntime.Geometry.Polyline(linePoints);//由点集构造线
Graphic lineGraphic = new Graphic(line, lineSymbol);//由线创建图形
myMapView.GraphicsOverlays[0].Graphics.Add(lineGraphic);//加入该图形元素到覆盖层中
linesList.Add(lineGraphic);//同时,将该图形加入链表
Console.WriteLine("将该图形加入链表" + linesList[0]);
}
}
//画面图形
private void draw_Polygon()
{
if (linePoints.Count >= 3)//如果点集中点数足够
{
if (polygonList.Count > 0 && linePoints.Count > 3)//已有加入的面图形,则移除当前的图形,重新加入新的图形
{
Graphic curGraphic = polygonList[polygonList.Count - 1];//获取上一次的点击的点形成的面图形,为了后面删除,想想,如果不删除,如果点n下,那将会有n-2个面
Console.WriteLine("myMapView_MouseLeftButtonDown3:" + curGraphic); // 输出:Esri.ArcGISRuntime.UI.Graphic
myMapView.GraphicsOverlays[0].Graphics.Remove(curGraphic);
Console.WriteLine("移除显示的面图层");
polygonList.Remove(curGraphic);
Console.WriteLine("polygonList个数:" + polygonList.Count);
Console.WriteLine("linePoints点数:" + linePoints.Count);
Console.WriteLine("移除容器内的面图层");
}
Esri.ArcGISRuntime.Geometry.Polygon polygon = new Esri.ArcGISRuntime.Geometry.Polygon(linePoints);//由点集构造面
Graphic polygonGraphic = new Graphic(polygon, fillSymbol);//由面创建图形
myMapView.GraphicsOverlays[0].Graphics.Add(polygonGraphic);//加入该图形元素到覆盖层中
polygonList.Add(polygonGraphic);//同时,将该图形加入链表
Console.WriteLine("将该图形加入链表" + polygonList[0]);
}
}
13.为 MapView 的 MouseLeftButtonDown
事件处理添加代码
注意一下哈,线是由点来连接形成,面是由点连接来封闭形成,所以都用linePoints
这个点集合,懒得再定义一个新的点集合变量了O(∩_∩)O
private void myMapView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
IInputElement mv = (IInputElement)sender;
Console.WriteLine("myMapView_MouseLeftButtonDown1:" + mv); // 输出:Esri.ArcGISRuntime.UI.Controls.MapView
MapPoint location = myMapView.ScreenToLocation(e.GetPosition(mv));
Console.WriteLine("myMapView_MouseLeftButtonDown2:" + location); // 输出:MapPoint[X=-2980643.97532462, Y=7942640.88222337, Wkid=3857]
if (drawingType == DrawType.DrawPoint)//画点
{
Graphic gPT = new Graphic(location, pointSymbol);
myMapView.GraphicsOverlays[0].Graphics.Add(gPT);
}
else if (drawingType == DrawType.DrawLine)//画线
{
linePoints.Add(location);//将当前点加入点集
draw_Line();
}
else if (drawingType == DrawType.DrawArea)
{
linePoints.Add(location);//将当前点加入点集
draw_Polygon();
}
}
14.为 MapView 的 MouseRightButtonDown
事件处理添加代码
private void myMapView_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
drawingType = DrawType.None;//停止绘制
}
15.展示窗体
private void Options_Click(object sender, RoutedEventArgs e)
{
OptionsWindows sForm = new OptionsWindows();
sForm.PointSymbol = pointSymbol; // get set
sForm.LineSymbol = lineSymbol;
sForm.FillSymbol = fillSymbol;
sForm.ShowDialog(); // 这里用了ShowDialog,所以在另一个窗体里,老师用了this.DialogResult,感觉this.Close()也应该是可以的
}
四、代码查看
☞代码查看☜
花了大概一天半的时间,搞完了 O(∩_∩)O 哈哈~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!