绘制点线面以及符号界面设计

实验名称

空间几何图形的绘制,点、线、面符号界面设计与实现

实验目的

理解 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 哈哈~

posted @ 2021-10-23 21:05  槑孒  阅读(673)  评论(0编辑  收藏  举报