标签归档:C#

【C#】List排序的方法List.Sort的使用

最近准备做一个回合制战斗的游戏,在游戏设计时,考虑到需要将所有可操作角色按照他们的速度进行排序,以来确定攻击顺序,用到了List.Sort方法,经过查看MSDN文档搞明白了怎么用,进行记录并分享。

List.Sort在默认不带参数的情况下,可以对String和Int等进行排序,而我的List中是一个类,我需要将List按照类中的Speed属性进行排序,具体方法是我们用到List.Sort 方法 (IComparer)来进行排序。

首先我们需要写一个继承自ICompare的排序函数:

/// <summary>
/// 一个针对IActItem的排序,按照Speed从大到小排序。
/// </summary>
public class SortBySpeed : IComparer<IActItem>
{
    /// <summary>
    /// 对比函数,名字不需要进行修改
    /// </summary>
    /// <param name="a">进行对比的左项</param>
    /// <param name="b">进行对比的右项</param>
    /// <returns>返回一个整形,这个整形代表左项需要移动的位置,列表顺序从左向右,-1为向左移(排在前面),1为向右移(排在后面),0为不移动</returns>
    public int Compare(IActItem a, IActItem b)
    {
        if (a == null)
        {
            if (b == null)
            {
                //如果两个都为null,则不进行排序
                return 0;
            }
            else
            {
                //a为null,b不是null,则b>a,将a向右移动1个位置
                return 1;
            }
        }
        else
        {
            if (b == null)
            {
                //b为null,a不是null,则a>b,将a向左移动1个位置
                return -1;
            }
            else
            {
                //如果a和b都不为null,则进行Speed属性对比
                if (a.Speed > b.Speed)
                {
                    //a的速度更快,排在b前面
                    return -1;
                }
                else
                {
                    //a的速度慢,则排在b后面
                    return 1;
                }
            }
        }
    }
}

之后我们只需要进行Sort调用即可:

SortBySpeed sbs = new SortBySpeed();
actList.Sort(sbs);

这样我们就完成对actList的排序,速度越大的排在越前面,按照顺序进行攻击。

更详细的使用方法可以查看MSDN文档

【C#】使用Split将字符串分割为数组

在编码中,我们经常会将数组组成字符串保存。而将字符串在分割为数组,同样常用。

今天正好用到了Split方法来分割字符串,于是记录下来。

1. 单个字符分割字符串

string text = "abc,def,ghi";

,分割这个字符串,使用String.Split 方法 (Char[])即可,代码如下:

string[] result = text.Split(new Char[] { ',' });

2. 使用字符串分割字符串

string text = "abcrndefrnghi";

我们需要使用rn分割此字符串,而rn本身就是字符串,并非单个字符,所以就要用到String.Split 方法 (String[], StringSplitOptions)

第二个参数StringSplitOptions拥有两个值,分别为RemoveEmptyEntriesNone

RemoveEmptyEntries代表分割后,删除空元素;None代表不删除空元素。

我们并不删除空元素,所以使用如下代码进行分割:

string[] result = text.Split(new string[] { "rn" }, StringSplitOptions.None);

两种方法都很简单易懂、易于使用。

【C#】获取网页内容及HTML解析器HtmlAgilityPack的使用

最近经常需要下载一些东西,而这个下载地址又会经过层层跳转,每个页面上都有很多广告,烦不胜烦,所以做了一个一键获得最终下载地址的小工具。使用C#,来获取网页内容,然后通过HtmlAgilityPack获取某a标签的href,不断循环,层层跳转,最后获得最终下载地址。

下面,介绍HtmlAgilityPack的使用方法,这个方法也是从网上很多篇文章中拼凑摸索出来的,因为找了一大圈根本找不到HtmlAgilityPack的文档……

首先,using HtmlAgilityPack;

代码片段:

string url = "http://www.baidu.com/";
HtmlWeb htmlweb = new HtmlWeb();
HtmlDocument htmldoc = htmlweb.Load(url);
HtmlNodeCollection hnc = htmldoc.DocumentNode.SelectNodes("//div[@class='s_btn_wr']//input[@class='s_btn']");
string text = hnc[hnc.Count - 1].Attributes["value"].Value;

要点:

htmlweb.Load:参数为url地址,功能是加载url页面内容到htmldoc这个对象中。

HtmlNodeCollection:是一个集合,包含多个节点,它有count属性,可以获取数量,获取最后一个节点使用hnc[hnc.Count – 1]。

htmldoc.DocumentNode.SelectNodes:选择所有匹配的节点,参数为XPath语法,可以搜索W3CShool的语法说明,我这里的意思是获取包含class等于s_btn_wr的div下面的class等于s_btn的input节点。

hnc[hnc.Count – 1].Attributes["value"].Value:获取最后一个节点的value的属性值。

基本了解了上面的内容之后,我想你已经基本能够完成你想做的功能了。

【C#】判断目录下文件是否存在

下面代码中,新建了一个 DirectoryInfo 对象,然后使用遍历来判断文件是否存在。这种方法很笨,但是我还没想到、也没有机会上网查好方法,所以暂时先这样。

//窗体加载时检测是否安装有本程序所需调用的文件,若有则加入下拉列表
         private void Form_Zhu_Load(object sender, EventArgs e)
         {
             string path = "C:\Program Files\Common Files\microsoft shared\DevServer\10.0\";
             DirectoryInfo netdir = new DirectoryInfo(path);
             FileInfo[] fl = netdir.GetFiles();
             foreach (FileInfo netfl in fl)
             {
                 if (netfl.Name == "WebDev.WebServer20.EXE")
                 {
                     CB_BanBen.Items.Add(".NET Framework 2.0");
                 }
                 if (netfl.Name == "WebDev.WebServer40.EXE")
                 {
                     CB_BanBen.Items.Add(".NET Framework 4");
                 }
             }
             if (CB_BanBen.Items.Count < 1)
             {
                 MessageBox.Show("没有在您的电脑上找到能够启用本程序的文件,程序退出。");
                 Application.Exit();
             }
              
         }

【C#】通过正则表达式对TextBox进行校验

以下代码使用了 .NET Framework 正则表达式,使用正则表达式来对TextBox框内的内容进行判断与校验。

//检测虚拟路径的正确性
 private void TB_XNLJ_Leave(object sender, EventArgs e)
 {
     if (System.Text.RegularExpressions.Regex.IsMatch(TB_XNLJ.Text, "^/[^\:*?"<>|]*$"))
     {
         string dizhi = "http://localhost";
         linkLabel_dizhi.Text = dizhi + TB_XNLJ.Text;
     }
     else
     {
         MessageBox.Show("虚拟目录格式不正确,已重置。nn文件夹名称中不能包含:  \ : * ? " < > | 这些字符。");
         TB_XNLJ.Text = "/";
     }
 }

【C#】关于生成快捷方式的技术问题

做ASP.NET迷你服务器时,最后突然想到如果能够增加一个保存快捷方式的功能的话,以后直接打开服务器,并且设定好一切都会很方便,于是就在MSDN上寻找相关技术文章与教程,最后一无所获,无奈下只能上网找资料了。

最后成功的找到了相关的文章,通过代码了解了生成快捷方式这个技术需要使用Win32API,最后又通过反复试验,最终搞定。

下面是生成快捷方式的代码:

private void label_sckjfs_Click(object sender, EventArgs e)
         {
             JiaoYan();
             if (tingzhi == "true")
             {
                 tingzhi = "";
                 return;
             }
             string path_zhuomian = "";
             RegistryKey key = Registry.CurrentUser;
             //打开对应的注册表项,并获取Desktop键的值,这个是用来寻找桌面路径。
             path_zhuomian = key.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders").GetValue("Desktop").ToString();
             path_zhuomian = path_zhuomian + "\";
             try
             {
                 //生成WshShell的实例
                 WshShell shell = new WshShell();
                 //CreatShortcut中的参数是生成快捷方式的目录及文件名
                 IWshShortcut kjfs = (IWshShortcut)shell.CreateShortcut(path_zhuomian + TB_KJFS.Text + ".lnk");
                 //快捷方式的目标路径:生成哪个文件的快捷方式,就是哪个文件的目录加文件名
                 kjfs.TargetPath = lujing + banben;
                 //快捷方式的启动参数
                 kjfs.Arguments = canshu;
                 //快捷方式的备注(描述)
                 kjfs.Description = "";
                 //快捷方式的工作目录,就是源程序的目录,和目标路径的目录一样
                 kjfs.WorkingDirectory = @"C:Program FilesCommon Filesmicrosoft sharedDevServer10.0";
                 //快捷方式的图标,我还不知道怎样能直接使用ico图标,以及使用当前程序的图标
                 kjfs.IconLocation = "iscsicli.exe,0";
                 //快捷方式的快捷键
                 kjfs.Hotkey = "";
                 //快捷方式的样式
                 kjfs.WindowStyle = 1;
                 //保存快捷方式
                 kjfs.Save();
                 MessageBox.Show("快捷方式生成成功。");
             }
             catch
             {
                 MessageBox.Show("未知错误!");
             }
         }

以上就是生成快捷方式的方法,需要引用一个COM组件,Interop.IWshRuntimeLibrary.dll

引用之后就可以使用上面的代码来生成快捷方式了。

【C#】通过Process来对系统进程进行操作

今天想自己写一个程序,来获取当前某项进程的命令行参数,以后也就不用打开任务管理器,然后一个字母的敲了,可是到最后都没有找到办法。

关于系统进程的获取、启动和停止,都已经搞定了。

本来可以很简单的,但是我弄复杂了点,顺带把多维数组温习了一遍。

下面是获取进程列表的代码:

using System.Diagnostics;
  
         private void button1_Click(object sender, EventArgs e)
         {
             listBox1.Items.Clear();
             listBox2.Items.Clear();
             Process[] liebiao = Process.GetProcesses();
             string[,] shuzu_jincheng = new string[liebiao.Length,2];
             int i = 0;
             foreach (Process jincheng in liebiao)
             {
                 shuzu_jincheng[i, 0] = jincheng.Id.ToString();
                 shuzu_jincheng[i, 1] = jincheng.ProcessName;
                 i++;
             }
             for (i = 0; i < liebiao.Length - 1; i++)
             {
                 listBox1.Items.Add(shuzu_jincheng[i, 0]);
                 listBox2.Items.Add(shuzu_jincheng[i, 1]);
             }
         }

这个也需要一个引用,代码第一行就是需要进行引用的类。

关于进程的操作,MSDN上都有(除了获取命令行参数,能获取的只有通过Process.start()启动的进程)。又关结束进程等的操作,可以直接去MSDN学习,我也就不贴代码了。

【C#】在WinForm中关于注册表的操作

昨天完善了以下ASP.NET迷你服务器的程序,增加了保存快捷方式的功能,其中把快捷方式保存到桌面时很费了一番脑筋(其实我就是个小白)。

在MSDN中差了一半天资料,最后找到了关于注册表的操作方法。MSDN中也只是简单的介绍一下,然后通过自己的摸索,最终搞定了。

生成快捷方式也有些难度,MSDN中没找到相关资料,从网上看了看别人的博文,最后加上自己的研究,也搞定了,我的下一篇博文对生成快捷方式进行说明。

下面的代码就是用来获取注册表键值的一个控制台程序:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
  
 namespace Consolezhucebiao
 {
     class Program
     {
         static void Main(string[] args)
         {
             RegistryKey rk = Registry.CurrentUser;
  
             // Print out the keys.
             PrintKeys(rk);
         }
  
         static void PrintKeys(RegistryKey rkey)
         {
  
             // Retrieve all the subkeys for the specified key.
             String names = rkey.OpenSubKey("SoftwareMicrosoftWindowsCurrentVersionExplorerUser Shell Folders").GetValue("Desktop").ToString();
             String a = System.Environment.SystemDirectory;
             Console.WriteLine("Subkeys of " + rkey.Name);
             Console.WriteLine("-----------------------------------------------");
             Console.WriteLine(names);
             Console.WriteLine(a);
             Console.ReadKey();
         }
  
     }
 }