2015年11月

20个C#热点问题解答(二)

.NET中加密和解密

如何获取foreach当前循环迭代的索引

  • 第一种方式

    int counter = 0
    //diction 是个字典集合
    foreach(object obj in diction)
    {

       Console.WriteLine(counter);
       counter++;

    }

  • 第二种方式

int curIndex = 0
//创建一个string类型的list集合
foreach(string str in stringList)
{
    curIndex = stringList.IndexOf(str);
    Console.WriteLine(curIndex.Tostring());
}
  • 第三种方式

int curIndex = 0
//创建一个string类型的Arraylist集合
foreach(string str in arrList)
{
    curIndex = stringList.IndexOf(str);
    Console.WriteLine(curIndex.Tostring());
}

如何在C#中获取自己的IP地址

using System.Net.NetWorkInformation;
using System.Net.Sockets;

foreach(var interfaces in NetWorkInterface.GetAllNetworkInterfaces())
{
    foreach(var address in interfaces.GetIPPrpperties().UnicastAddresses)
    {
        if(address.Address.AddressFamily == AddressFamily.InterNetwork)
        {
            Console.WriteLine("IP Address: "+ address.Address.Tostring());
        }
    }
}

//另一个方式

string publicip = GetPublicIP();
Console.WriteLine("public ip: " + publicip);

static string GetPublicIP()
{
    string address = "";
    WebRequest request = WebRequest.Create("Http://checkip.dydns.org/");
    using(WebResponse response = request.GetResponse())
    using(StringReader stream = new StreamReader(response.GetResponseStream()))
    {
        address = string.ReadToEnd;
    }
    //Search for the ip in the html
    int first = address.IndexOf("Address: ") + 9;
    int lase = address.LastIndex("</Body>");
    address = address.Substring(first,last - first);

    return address;
}

如何在C#中获取人的年龄

这里主要使用了DataTime

CalcAge(DateTime.Parse("10/13/1992"));

static void CalAge(DateTime birthday)
{
    DateTime curDate = DateTime.Today;
    if(birthday > curDate)
    {
        Console.WriteLine("Birthady must be equal to or before today")
    }
    else
    {
        int age = curDate.Year - birthday.Year;
        if(birthday.Month > curDate.Month)
        {
            age --;
        }
        Console.WriteLine("The person's age is :{0}",age);
    }
}

如何获取一个枚举的字符串值

public enum AuthMethod
{
    FORMS = 1;
    WINDOWAUTHENICATION = 2;    
    SINGLESIGNON = 3;
}
static void StringEnums()
{
    AuthMethod auth = AuthMethod.FORMS;
    string str = Enum.GetName(typeof(AuthMethod),auth);
    Console.WriteLine(str);
    
    str = AuthMethod.FORMS.ToString();
    Console.WriteLine(str);
}

未完...

没有写完

20个C#热点问题解答(一)

结构和类分别应在什么时候使用

  • struct是值类型,他可以包含数据和函数

  • struct是值类型,不需要的分配

  • struct直接将数据存储在结构中,而类存储的是对一个动态分配的对象的引用

  • struct适用于较小的数据结构

  • struct可能会影响性能(因为来回操作的话都是操作的单独的副本,而类操作的是原始对象,存储的是引用

  • 构造函数可以通过new操作符调用,但这不会在堆上分配内存

  • struct构造函数只返回struct值本身(通常是堆栈中的临时位置),而且在必要时这个值被复制。

以上是官方的解答。我认为最终要的是要认识到,struct是值类型,类是引用类型,然后清楚值类型和引用类型的区别才可以。比如存储的位置的区别了,存储的内容(一个是副本,一个是引用),多次操作对性能的影响了等等,了解了这些就清楚了何时使用值类型,何时使用引用类型.

如何解析XML文件

static void parseXML(string xmlString)
{
    StringBuilder sb = new StringBuilder();
    using(XmlReader reader = XmlReader.Create(new StringReader(xmlString)))
    {
        reader.ReadToFollowing("book");
        reader.MoveToFirstAttribute();
        string genre = reader.Value;
        sb.AppendLine("The genre value:" + genre);
        
        reader.ReadToFollowing("title");
        sb.AppendLine("Content of fitle element" + reader.ReadelementContentAsString());
    }

    Console.WriteLine(sb);
}

以上就是基本代码,比较简单。关于XmlReader类详见MSDN文档
现在好像用Linq也可以解析XML文件,还更加方便。

String和string的区别

•string 类型是一个封装的类(class)类型,它直接从对象继承。string 类的实例表示Unicode 字符串。
•string 类型的值可以被写为字符串。.
•string 关键字只是预定义的类System.String的别名,因此可以使用string name = “Fred”; 或String name = “Fred”;
•类似地,我们可以使用string.Concat() 或String.Concat()
•string 用于变量名称
•String 用于类方法和引用
以上是MVA中给出的解释,这里我更喜欢CLR via C#中提到的,string属于C#基元类型,而String属于FCL Framework类库类型,两者从本质上讲没有区别,string可以看成是String的别名,它们的区别可以看成是int和System.Int32的区别

如何在C#程序中输出程序所在路径

这里面使用到了反射,其实从代码来说是非常简单的。

string path = System.Reflection.Assembly.GetExecutingAssembly().Location;
Console.WriteLine(System.IO.Path.GetDirectioryName(path));

关于反射明天回从CLR via C#中讲一些

在 C# 中调用基类构造函数

在C#中调用父类基本的构造函数是很简单的

public BaseClass()
{
    public string _name = "" ;
    public BaseClass(string name)
    {
        _name = name;
    }

    public 
}


//子类
public InheritTest : BaseClass
{    
    //应该很好理解,这样就调用了父类的构造函数
    public InheritTest(string name):base(name)
    {

    }
}

但如果想在调用父类的构造函数之前,更改这个值该怎么办

//Microsoft给出的方法是:在子类中重写虚方法,并按如下方式调用

public InheritTest : BaseClass
{    
    
    public InheritTest(string name):base(ModifyBase(name))
    {

    }
    private static string ModifyBase(string newName)
    {
        return newName.Toupper();
    }
}

虚拟方法是在基类中创建的方法,并且可以在子类中重写,这也是面向对象编程中多态性概念的由来。

如何在一个字符串中统计另一个字符串的字数

这里演示了两种方法,一种使用正则表达式Regex,另一种使用了Foreach循环

foreach(Match m in Regex.Matches(test,"you"))
{
    wordCount++;
}

foreach(char value in test)
{
    if(value == 'y')
    {
        charCount ++ ;
    }
}

使用foreach统计字符的话还是比较简单的,统计字符串的话还是使用*Regex*更加简单,并且高效。


如何检测一个数是否是2的幂

static bool CheckPowerOfTwo(ulong number)
{
    return (number != 0) && ((number & (number - 1 )) == 0);
}

number - 1number&运算,如果number是2的幂,那么这个值总是为0,这就是关键点

breakcontinue的区别,中继循环和继续执行循环的区别

static void breakVSContinue()
{
    for(int i = 0;i < 10 ;i++)
    {
        if(i ==0) break;
        DoSomeThingWith(i);
    }
}

abstractvirtual函数的区别

  • 抽象函数没有任何实现,并且必须被重写

  • 虚函数可能有一个实现,这不是必须的。并且接下来能够被重写

  • 对于抽象函数你不能调用base.method(),但对于虚函数你可以这么做

refhe out区别

一个简单的回答说两者在visual stuido 中工作基本没有区别。,区别就是:你需要初始化ref,而无须初始化out

乱七八糟的Mavlink学习(二)

学习一中,最后提到了writeKML方法,在一开始的时候并没有对这个方法进行太多的注意,后期发现,这个方法是在是很重要。拿到这里来分析一下

KML是啥

KML 是一种文件格式,用于在地球浏览器(例如 Google 地球、Google 地图和 Google 地图移动版)中显示地理数据。KML 使用包含嵌套的元素和属性的结构(基于标记),并符合 XML 标准。所有标记都区分大小写,并且必须与 KML 参考中列出的完全一样。该参考指出了哪些标记是可选的。在给定元素内,标记必须按照参考中列出的顺序显示。来自googleDevelopers--KML教程

总结一下,就是KML就是一种存放地图数据的格式,这种格式可以用Google地球读取,类似于Html可以用浏览器解析。

WriteKML都干了啥

writeKML总体来说都做了什么呢?WriteKML就是将表格中的数据进行处理,一方面将点在地图上进行标注;另一方面完善表格的内容(设置坡度、距离、角度等等)
这里有两个list数组,一个是pointList、一个是fullpointlist,我理解的不同点就是pointlist中包含的是所有点的信息,即表格中的所有点位置信息,而fullpointlist中包含的是添加到地图上的点的信息,即去掉无意义的点后pointlist剩下的点

pointlist.Add(new PointLatLngAlt(double.Parse(TXT_homelat.Text), double.Parse(TXT_homelng.Text), (int)double.Parse(TXT_homealt.Text), "H"));
//这里的意思就是把最新的点添加到fullpointlist中,pointlist[pointlist.Count - 1] 就是最后一个点
fullpointlist.Add(pointlist[pointlist.Count - 1]);

在下面的设置兴趣点时if (command == (byte)MAVLink.MAV_CMD.DO_SET_ROI)中,就只有pointlist.Add(new PointLatLngAlt(double.Parse(cell3), double.Parse(cell4), (int)double.Parse(cell2) + homealt, "ROI" + (a + 1)) { color = Color.Red });,而没有fullpointList.Add

计算到Home点的距离

homedist = MainMap.MapProvider.Projection.GetDistance(fullpointlist[fullpointlist.Count - 1], fullpointlist[0]);

计算总的距离

for (int a = 1; a < fullpointlist.Count; a++)
                {
                    if (fullpointlist[a - 1] == null)
                        continue;

                    if (fullpointlist[a] == null)
                        continue;

                    dist += MainMap.MapProvider.Projection.GetDistance(fullpointlist[a - 1], fullpointlist[a]);
                }

设置坡度、距离、方位

//GetDistance中计算得到的是距离Home点的距离。
//设置坡度
Commands.Rows[int.Parse(lla.Tag) - 1].Cells[Grad.Index].Value = (((lla.Alt - last.Alt) / (lla.GetDistance(last) * CurrentState.multiplierdist)) * 100).ToString("0.0");
//设置距离
Commands.Rows[int.Parse(lla.Tag) - 1].Cells[Dist.Index].Value = (lla.GetDistance(last) * CurrentState.multiplierdist).ToString("0.0");
//设置角度
Commands.Rows[int.Parse(lla.Tag) - 1].Cells[AZ.Index].Value = ((lla.GetBearing(last) + 180) % 360).ToString("0");

分析地图加载的事件

  • 配置缓存目录

    MainMap.CacheLocation = Path.GetDirectoryName(Application.ExecutablePath) + Path.DirectorySeparatorChar + "gmapcache" + Path.DirectorySeparatorChar;

  • 地图提供者

    MainMap.MapProvider = GoogleSatelliteMapProvider.Instance;

  • OnCurrentPositionChanged

GMapMarker center = new GMarkerGoogle(new PointLatLng(0.0, 0.0), GMarkerGoogleType.none);

void MainMap_OnCurrentPositionChanged(PointLatLng point)
    {
        if (point.Lat > 90) { point.Lat = 90; }
        if (point.Lat < -90) { point.Lat = -90; }
        if (point.Lng > 180) { point.Lng = 180; }
        if (point.Lng < -180) { point.Lng = -180; }
        center.Position = point;
        coords1.Lat = point.Lat;
        coords1.Lng = point.Lng;
    }
  • OnTitleLoadStart,地图开始加载事件

        MethodInvoker m = delegate {
            lbl_status.Text = "Status: loading tiles...";
        };
        try
        {
            BeginInvoke(m);
        }
        catch
        {
        }
  • OnTitleLoadComplete

MethodInvoker m = delegate
        {
            lbl_status.Text = "Status: loaded tiles";

            //panelMenu.Text = "Menu, last load in " + MainMap.ElapsedMilliseconds + "ms";

            //textBoxMemory.Text = string.Format(CultureInfo.InvariantCulture, "{0:0.00}MB of {1:0.00}MB", MainMap.Manager.MemoryCacheSize, MainMap.Manager.MemoryCacheCapacity);
        };
        try
        {
            if (!IsDisposed)
                BeginInvoke(m);
        }
        catch
        {
        }
  • OnMarkerClick,点击坐标

int answer;
try
{
    if(item.Tag == null)
        return;
    if(int.TryParse(item.Tag.ToString(), out answer))
    {
        Command.CurrentCell = Commands[0,answer - 1];
    }
} 
catch{}
  • OnMapZoomChanged()

    trackBar是类似进度条一类的东西,引用后添加到界面即可
    if(MainMap.Zoom > 0 )
    {

       try
       {
           trackBar1.Value = (int)(MainMap.Zoom);
       }
       catch{}
       center.Position = MainMap.Position;

    }

  • OnMouseMove

    //下面的代码包含三部分:1、如果(MouseDownStart == point),返回2、鼠标抬起了,设置显示3、更新位置坐标
    PointLatLng point = MainMap.FromLocalToLatLng(e.x,e.Y);

    if(MouseDownStart == point)

       return;

    currentMarker.Position = point;

    if(!isMouseDown)
    {

       SetMouseDisplay(point.Lat,point.Lng,0);

    }
    if (e.Button == MouseButtons.Left && isMouseDown)
    {

       isMouseDraging = true;
       if(CurrentRectMarker != null)
       {
           try
                   {
                       // check if this is a grid point
                       if (CurentRectMarker.InnerMarker.Tag.ToString().Contains("grid"))
                       {
                           drawnpolygon.Points[int.Parse(CurentRectMarker.InnerMarker.Tag.ToString().Replace("grid", "")) - 1] = new PointLatLng(point.Lat, point.Lng);
                           MainMap.UpdatePolygonLocalPosition(drawnpolygon);
                           MainMap.Invalidate();
                       }
                   }
                   catch { }
    
                   PointLatLng pnew = MainMap.FromLocalToLatLng(e.X, e.Y);
    
                   // adjust polyline point while we drag
                   try
                   {
                       if (CurrentGMapMarker != null && CurrentGMapMarker.Tag is int)
                       {
    
                           int? pIndex = (int?)CurentRectMarker.Tag;
                           if (pIndex.HasValue)
                           {
                               if (pIndex < wppolygon.Points.Count)
                               {
                                   wppolygon.Points[pIndex.Value] = pnew;
                                   lock (thisLock)
                                   {
                                       MainMap.UpdatePolygonLocalPosition(wppolygon);
                                   }
                               }
                           }
                       }
                   }
                   catch { }
    
                   // update rect and marker pos.
                   if (currentMarker.IsVisible)
                   {
                       currentMarker.Position = pnew;
                   }
                   CurentRectMarker.Position = pnew;
    
                   if (CurentRectMarker.InnerMarker != null)
                   {
                       CurentRectMarker.InnerMarker.Position = pnew;
                   }
       }

    else if (CurrentGMapMarker != null)

               {
                   PointLatLng pnew = MainMap.FromLocalToLatLng(e.X, e.Y);
    
                   CurrentGMapMarker.Position = pnew;
               }

    else // left click pan

               {
                   double latdif = MouseDownStart.Lat - point.Lat;
                   double lngdif = MouseDownStart.Lng - point.Lng;
    
                   try
                   {
                       lock (thisLock)
                       {
                           MainMap.Position = new PointLatLng(center.Position.Lat + latdif, center.Position.Lng + lngdif);
                       }
                   }
                   catch { }
               }

    }

  • MouseDown

    //这里就最终放下这个坐标
    MouseDownStart = MainMap.FromLocalToLatLng(e.X, e.Y);
    if (e.Button == MouseButtons.Left && ModifierKeys != Keys.Alt && ModifierKeys != Keys.Control)

           {
               isMouseDown = true;
               isMouseDraging = false;
               //Console.WriteLine("是鼠标左键,不是ALT也不是CTRL");
               Debug.Print("是鼠标左键,不是ALT也不是CTRL");
    
               if (currentMarker.IsVisible)
               {
                   currentMarker.Position = MainMap.FromLocalToLatLng(e.X, e.Y);
                   Console.WriteLine("currentMarker.Position:"+CurentRectMarker.Position);
               }
           }
    
  • MouseUP

    MouseDownEnd = MainMap.FromLocalToLatLng(e.X, e.Y);
    if (isMouseDown) // mouse down on some other object and dragged to here.

           {
               if (e.Button == MouseButtons.Left)
               {
                   isMouseDown = false;
               }
      if (!isMouseDraging)
               {
                   if (CurentRectMarker != null)
                   {
                       // cant add WP in existing rect
                   }
                   else
                   {
                       AddWPToMap(currentMarker.Position.Lat, currentMarker.Position.Lng, 0);
                   }
               }
       if (CurentRectMarker != null)
                   {
                       if (CurentRectMarker.InnerMarker.Tag.ToString().Contains("grid"))
                       {
                           try
                           {
                               drawnpolygon.Points[int.Parse(CurentRectMarker.InnerMarker.Tag.ToString().Replace("grid", "")) - 1] = new PointLatLng(MouseDownEnd.Lat, MouseDownEnd.Lng);
                               MainMap.UpdatePolygonLocalPosition(drawnpolygon);
                               MainMap.Invalidate();
                           }
                           catch { }
                       }
                       else
                       {
                               callMeDrag(CurentRectMarker.InnerMarker.Tag.ToString(), currentMarker.Position.Lat, currentMarker.Position.Lng, -1);
                       }
                       CurentRectMarker = null;
                   } 

    }

  • MouseEnter

    if (!isMouseDown)

           {
               if (item is GMapMarkerRect)
               {
                   GMapMarkerRect rc = item as GMapMarkerRect;
                   rc.Pen.Color = Color.Red;
                   MainMap.Invalidate(false);
    
                   int answer;
                   if (item.Tag != null && rc.InnerMarker != null && int.TryParse(rc.InnerMarker.Tag.ToString(), out answer))
                   {
                       try
                       {
                           Commands.CurrentCell = Commands[0, answer - 1];
                           item.ToolTipText = "Alt: " + Commands[Alt.Index, answer - 1].Value;
                           item.ToolTipMode = MarkerTooltipMode.OnMouseOver;
                       }
                       catch { }
                   }
    
                   CurentRectMarker = rc;
               }
               if (item is GMapMarker)
               {
                   CurrentGMapMarker = item;
               }
           }
    
  • OnMarkerLeave

if (!isMouseDown)
        {
            if (item is GMapMarkerRect)
            {
                CurentRectMarker = null;
                GMapMarkerRect rc = item as GMapMarkerRect;
                rc.ResetColor();
                MainMap.Invalidate(false);
            }
            if (item is GMapMarkerRallyPt)
            {
                CurrentRallyPt = null;
            }
            if (item is GMapMarker)
            {
                // when you click the context menu this triggers and causes problems
                CurrentGMapMarker = null;
            }

        }

---
以上是对乱七八糟的代码的整理,都是可能需要到的。在接下来的工作中就是对其中的某些内容进行修改

Linux--用户及文件权限管理

## 实验内容

  1. 查看用户

who am i 或者 who mom likes

  1. 创建用户

sudo adduser lilei
su su- sudo的区别

su可以切换到用户user,执行时需要输入目标用户的密码,sudo<cmd>可以以特权命令运行cmd命令,需要当前用户属于sudo组,且需要输入当前用户密码。su-<user>命令也是切换用户,同时环境变量也会跟着变成目标用户的环境变量。

  1. 切换用户

su -l lilei
退出使用exit或使用快捷键CTRL + D

  1. 用户组

查看用户组
groups shiyanlou ,默认在sudo用户组的用户可以使用root权限
或者通过查看etc/group文件,使用cat /etc/group | sort。也可以使用 cat /etc/group |grep -E "shiyanlou|sudo"

  1. 把新添加的用户加入到sudo组

su shiyanlou
groups lilei
sudo usermod -G sudo lilei 
groups lilei
  1. 删除用户

sudo deluser lilei --remove-home
  1. 查看文件权限

通过ls来查看,如 ls -a ls -dl<目录名> ls - al等等
权限说明

  1. 变更所有者

  1. 修改文件权限

乱七八糟Mavlink学习(一)

写WPS思路

  1. 如果用户的高度设置为绝对高度,给予提示
    默认为相对高度 altmode.Relative

  2. 检查命令表格中的数据是否合法

利用的是double.TryParse(将String类型转换为等效双精度浮点数,一个指示转换是否成功的返回值)

  1. 警告AltWarn默认为0

指令是否包含Unknown,是continue,不是继续执行

  1. 将表格的第一列转换为cmd,利用Enum.parse(枚举类型,包含要转换的字符串,是否区分大小写)

如果cmd < mavcmd.last && 飞行高度的值小于警戒高度,并且cmd类型不是起飞、降落、返回出发点模式,就提示用户,这个高度小于警戒高度,需要改。我想应该是有一个最低的境界高度,如果低于这个高度,会有碰撞的危险

  1. 现在开始搞一个进度条,saveWPS

  2. saveWPS做什么呢?首先用个Try异常处理语句,包含代码。。。

  3. 检查端口是否正常链接;设置give-Comporttrue,防止其他代码对端口进行读写吧;接下来设置LocationWP-Home,这是一个自定义的类,包含了经纬度、高度、还有命令那些信息,这里对home有个异常处理,判断填入的经纬度信息是否是合法的。

  4. //这里出现了一个WPS,起这么个乱七八糟的名字我也是醉了。其实就是一个字典,键是一个int类型,值是Mission_item.检查表格中的数据,看看能不能只发送变化的部分。怎么检查呢

    {
    对WPF.Values进行遍历
    {
        if( a == -1)
        {
            a++;
            continue; //跳过Home
        }
        mission_item temp= DataViewToLocationWP //听名字也知道这是干啥的。就是将表格中的命令转换为Mission_item
        if(所有的数据都相等,比较的是循环的item和temp项)
        {
        }
        else
        {
            不匹配呢,加入到WPFUPload,其实也是一个字典,用来存储新的变化的部分
        }
    a++;
    } 
}
```
  1. 更新进度条,提示SetTotalWPS,发送航点,发送的是Mission_Count,返回的是Mission_result,对结果值进行判断,处理

  2. 更新进度条状态,变为SetHomeSetWp(home,0,Mav_mavFrame_global,0)

  3. 判断返回值是不是Accepted,接收了吗?

  4. 定义默认的Frame,默认就是mavFrame.Global.Relative.ALT

    if(不是最后一个命令或Do_setHome)
    {

       var mode = 现在选择的模式
       if(terriain)
           frame = Global_terriain_act;
       if(absolute)
           frame = Global;
       else
           frame = relative_alt

    }

  5. 尝试发送,MissionItem,对missionResult进行判断。处理

a++;

  1. 全部都发完了,发送一个ACK包,

  2. 设置半径啥的,全部完成之后,ok,显式Down


这都是些啥


读WPS思路

  1. 首先判断命令表格中的行数是否 > 0;如果是,代表你可能现在已经规划了一个任务,提示你现有操作将会清除你已经存在的任务,是否继续

  2. new一个进度条,显示getwps

  3. getwps做什么呢?这里面做了两件事,1、取得所有航点数量,2、然后循环所有航电添加到表格中

怎么实现的呢?

      List<Locationwp> cmds = new List<Locationwp>(); //
        try
        {
            MAVLinkInterface port = MainV2.comPort;

            if (!port.BaseStream.IsOpen)
            {
                throw new Exception("Please Connect First!");
            }

            MainV2.comPort.giveComport = true;

            param = port.MAV.param;

            ((ProgressReporterDialogue)sender).UpdateProgressAndStatus(0, "Getting WP count");
            //getWPCount返回航点的数量
            int cmdcount = port.getWPCount();

            //循环所有点,发送Request命令,调用getWP(a)返回对应的Item,Cmd.Add命令把Item加入到集合
            for (ushort a = 0; a < cmdcount; a++)
            {
                if (((ProgressReporterDialogue)sender).doWorkArgs.CancelRequested)
                {
                    ((ProgressReporterDialogue)sender).doWorkArgs.CancelAcknowledged = true;
                    throw new Exception("Cancel Requested");
                }

                log.Info("Getting WP" + a);
                ((ProgressReporterDialogue)sender).UpdateProgressAndStatus(a * 100 / cmdcount, "Getting WP " + a);
                //发送MissionRequest命令,取得MissionItem包
                cmds.Add(port.getWP(a));
            }
            //都搞完了,然后发一个ACK确认
            port.setWPACK();

            ((ProgressReporterDialogue)sender).UpdateProgressAndStatus(100, "Done");

            log.Info("Done");
        }
        catch { throw; }
        //这里把所有的item添加到屏幕上,包括地图中和表格中
        WPtoScreen(cmds);
    1. WPtoScreen做什么呢
      这里面调用了三个方法: 1、 processToScreen(cmds);2、getRallyPointsToolStripMenuItem_Click(null, null);3.、 writeKML();

    2. processToscreen(cmds)做什么?
      判断现有表格是否有数据,有的话先进行清理工作。判断cmd.count == 0,是的话return

          //把Home从Cmd中减去,Commdands就是表格,现在是-1
          int i = Commands.Rows.Count - 1;
          foreach (Locationwp temp in cmds)
          {
              i++;
              //Console.WriteLine("FP processToScreen " + i);
              if (temp.id == 0 && i != 0) // 0 and not home
                  break;
              if (temp.id == 255 && i != 0) // bad record - never loaded any WP's - but have started the board up.
                  break;
              //现有表格行数不够了
              if (i + 1 >= Commands.Rows.Count)
              {
                  selectedrow = Commands.Rows.Add();
              }
              //if (i == 0 && temp.alt == 0) // skip 0 home
              //  continue;
              DataGridViewTextBoxCell cell; 
              DataGridViewComboBoxCell cellcmd; //命令,是下拉框,可选择的
              cellcmd = Commands.Rows[i].Cells[Command.Index] as DataGridViewComboBoxCell;
              cellcmd.Value = "UNKNOWN";
              cellcmd.Tag = temp.id;
      
              foreach (object value in Enum.GetValues(typeof(MAVLink.MAV_CMD)))
              {
                  if ((int)value == temp.id)
                  {
                      //命令是missionitem中的命令,先把第一列都搞好了
                      cellcmd.Value = value.ToString();
                      break;
                  }
              }
      
              // from ap_common.h,对altmode进行设置,不大懂
              if (temp.id < (byte)MAVLink.MAV_CMD.LAST || temp.id == (byte)MAVLink.MAV_CMD.DO_SET_HOME)
              {
                  // check ralatice and terrain flags
                  if ((temp.options & 0x9) == 0 && i != 0)
                  {
                      CMB_altmode.SelectedValue = (int)altmode.Absolute;
                  }// check terrain flag
                  else if ((temp.options & 0x8) != 0 && i != 0)
                  {
                      CMB_altmode.SelectedValue = (int)altmode.Terrain;
                  }// check relative flag
                  else if ((temp.options & 0x1) != 0 && i != 0)
                  {
                      CMB_altmode.SelectedValue = (int)altmode.Relative;
                  }
              }
              //对高度进行赋值 。。 
              cell = Commands.Rows[i].Cells[Alt.Index] as DataGridViewTextBoxCell;
              cell.Value = Math.Round((temp.alt * CurrentState.multiplierdist), 0);
              。。。省略其他的
              //这个过会讲
              setWPParams();
          //设置Home相关比较简单,设置完成后还要把home在表格中移除
          try
          {
      
              DataGridViewTextBoxCell cellhome;
              cellhome = Commands.Rows[0].Cells[Lat.Index] as DataGridViewTextBoxCell;
              if (cellhome.Value != null)
              {
                  if (cellhome.Value.ToString() != TXT_homelat.Text && cellhome.Value.ToString() != "0")
                  {
                      DialogResult dr = CustomMessageBox.Show("Reset Home to loaded coords", "Reset Home Coords", MessageBoxButtons.YesNo);
      
                      if (dr == DialogResult.Yes)
                      {
                          TXT_homelat.Text = (double.Parse(cellhome.Value.ToString())).ToString();
                          cellhome = Commands.Rows[0].Cells[Lon.Index] as DataGridViewTextBoxCell;
                          TXT_homelng.Text = (double.Parse(cellhome.Value.ToString())).ToString();
                          cellhome = Commands.Rows[0].Cells[Alt.Index] as DataGridViewTextBoxCell;
                          TXT_homealt.Text = (double.Parse(cellhome.Value.ToString()) * CurrentState.multiplierdist).ToString();
                      }
                  }
              }
          }
      
    1. setWPParam就是设置一些半径啥的参数。对我现在来说没大有用。

    以上就是读的步骤