C#覺得好玩的筆記(---將不斷更新哦---)

  1. 使用Console.Read( )方法讀輸入並不立即響應,而是要等到用戶按下enter鍵。如果要即時做出響 應,可以改用Console的ReadKey方法,這時的比較輸出代碼可換成:ConsolKeyInfok =Console.ReadKey();

  2. C#規定,一個類只能有一個基類

  3. IndexOfAny()和LastIndexOfAny()查找對象是指定字符串數組中的任意字符

  4. 數值轉換有一個原則:從低精度類型到高精度類型可進行隱式轉換,而
    從高精度類型到低精度類型 必須進行顯式轉換;從精度相同的無符號
    數值類型向有符號數值類型的轉換也只能顯式轉換。

  5. C#支持兩個預定義的引用類型object和string。
    在應用程序執行的過程中,引用類型使用new關鍵字創建對象實例,並存儲在堆中。堆是一種由系統 彈性配置的內存空間,沒有特定大小及存活時間,因此可以被彈性地運用於對象的訪問。
    所有被稱爲“類”的都是引用類型,例如
    Student student1= new Student();
    Student student2= student1;

  6. 裝箱是將值類型轉換爲引用類型;拆箱是將引用類型轉換爲值類型
    利用裝箱和拆箱功能,可通過允許值類型的任何值與Object 類型的值相互轉換,將值類型與引用類 型鏈接起來

  7. 計算器的動態編譯器:博客:http://www.cnblogs.com/youring2/archive/2012/12/17/2822104.html
    DateTime是C#的一種表示日期和時間的類型,如獲取當前的時間: DateTime.Now.ToString(“YYYY-MM-DD-HH-mm-ss”);

  8. 還有一種類型是:System.TimeSpan,可用於兩個DateTime類型的數運算,如: System.TimeSpan s = DateTimed1-DateTime d2;

9.  數組的類型轉換

 public static int StrToInt(string str)
{
    return int.Parse(str);
}

string[] arrs = new string[] { "100", "300", "200" };
int[] arri = Array.ConvertAll(arrs, new Converter<string, int>(StrToInt));
  1. 抽象類可以有抽象方法和實體方法,但接口都public,只能抽象方法,所有所有方法都不用加作用域public 必須要有class實現

  2. 結構體是值類型,class是引用類型

  3. 實例方法,能調用靜態方法,也能調用實例方法;但是靜態方法之只能調用靜態方法,不能調用實例方法,必須要new一個實例對象

  4. Array.Sort([] d):對各類型數組進行升序排序,Array.Reverse([] d)對各類型數組進行倒序

  5. int?:表示可空類型,就是一種特殊的值類型,它的值可以爲null.
    int a=null;(錯)
    int? a=null(正確)

  6. ArrayList.Capacity容量不斷改變,根據動態數組的個數進行分配容量。

  7. 輸出當前時間和主機名字
    Console.WriteLine(DateTime.Now.ToString()+’\t’+Environment.MachineName);

17. C#委託對象是真正的對象,C/C++函數指針只是函數入口地址:
http://www.cnblogs.com/weidagang2046/archive/2009/08/09/1542248.html
http://www.cnblogs.com/leslies2/archive/2012/03/22/2389318.html0
18. 當子類繼承有參構造函數的父類時候,必須用base關鍵字進行構造函數的派生。
19. MySql裏面 char是一種固定長度的類型,varchar則是一種可變長度的類型
  1. CRC算法實現
    public static string CRCCalc(string data)
    {
    string[] datas = data.Split(’ ‘);
    List bytedata = new List();

        foreach (string str in datas)
        {
            bytedata.Add(byte.Parse(str, System.Globalization.NumberStyles.AllowHexSpecifier));
        }
        byte[] crcbuf = bytedata.ToArray();
        //計算並填寫CRC校驗碼
        int crc = 0xffff;
        int len = crcbuf.Length;
        for (int n = 0; n < len; n++)
        {
            byte i;
            crc = crc ^ crcbuf[n];
            for (i = 0; i < 8; i++)
            {
                int TT;
                TT = crc & 1;
                crc = crc >> 1;
                crc = crc & 0x7fff;
                if (TT == 1)
                {
                    crc = crc ^ 0xa001;
                }
                crc = crc & 0xffff;
            }
        }
        string[] redata = new string[2];
        redata[1] = Convert.ToString((byte)((crc >> 8) & 0xff), 16);
        redata[0] = Convert.ToString((byte)((crc & 0xff)), 16);
    

    if (redata[1].Length < 2)
    redata[1] = “0” + redata[1];
    if (redata[0].Length < 2)
    redata[0] = “0” + redata[0];

        return redata[0] + " " + redata[1];
    }
    
```
21、C#中的ComboBox實現只能選擇不能輸入,且下拉框中有默認值。
     // 在Designer.cs添加並修改順序
this.comboBox1.Items.AddRange(new object[] {
            "4800",
            "9600",
            "19200",
            "38400",
            "57600",
            "115200"});
this.comboBox1.Text = this.comboBox1.Items[1].ToString();  //這個必須在Items定義下面才行,否則報錯
this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;

21、 另一種更方法
image.png

22、 當SerialPort已經開啟以後就使用SerialPort.Write 方法 (Byte[], Int32, Int32)將前面的Byte陣列送出去,這個方法的參數1是你所要傳送的資料、參數二是你要從這個陣列的哪個位置開始送,參數三則是你要送的資料有多長。comport.Write(buffer, 0, buffer.Length) 這個寫法就是代表要送的資料存在buffer這個陣列中;從陣列的第一個元素 (它的Index是0);整個buffer我都要送,所以直接用buffer.Length,要多長就多長這樣。

23、控件TextBox內容全選快捷鍵實現
 private void anyTextBox_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
  if (e.KeyChar == '\x1')
  {
    ((TextBox)sender).SelectAll();
    e.Handled = true;
  }
}

24、判斷光標焦點在是否在 textbox:textbox.Focused ; 設置光標焦點:textbox.Focus();

25、關於c#註冊表的問題,在Microsoft.Win32的命名空間裏,主要是Registry類、RegistryKey類。
一般機器上的軟件註冊表都在Registry.LocaMachine這個主鍵
註冊在當前用戶裏,如果使用管理員運行該軟件才能註冊在LocalMachine裏,所以本地用戶就隨便註冊在CurrentUser就可以了。

26、密碼的加密解密方法:https://www.cnblogs.com/guohu/p/5562759.html

RSA加密算法

在談RSA加密算法之前,我們需要先了解下兩個專業名詞,對稱加密和非對稱加密。

對稱加密即:含有一個稱爲密鑰的東西,在消息發送前使用密鑰對消息進行加密,在對方收到消息之後,使用相同的密鑰進行解密

非對稱加密即:加密和解密使用不同的密鑰的一類加密算法。這類加密算法通常有兩個密鑰A和B,使用密鑰A加密數據得到的密文,只有密鑰B可以進行解密操作(即使密鑰A也無法解密),相反,使用了密鑰B加密數據得到的密文,只有密鑰A可以解密。這兩個密鑰分別稱爲私鑰和公鑰,顧名思義,私鑰就是你個人保留,不能公開的密鑰,而公鑰則是公開給加解密操作的另一方的。根據不同用途,對數據進行加密所使用的密鑰也不相同(有時用公鑰加密,私鑰解密;有時相反用私鑰加密,公鑰解密)。非對稱加密的代表算法是RSA算法。

瞭解了這兩個名詞下面來講,RSA加密算法。RSA取名來自開發他們三者的名字。RSA是目前最有影響力的公鑰加密算法,多用於數據加密和數字簽名。雖然有這麼大的影響力,但是同時它也有一些弊端,它產生密鑰很麻煩,受到素數產生技術的限制,因而難以做到一次一密,分組長度太大等。

下面通過示例演示使用RSA加密、解密,引用名稱空間System.Security.Cryptography;

//加密
    private string Encryption(string express)
    {
        CspParameters param = new CspParameters();
        param.KeyContainerName = "oa_erp_dowork";//密匙容器的名稱,保持加密解密一致才能解密成功
        using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param))
        {
            byte[] plaindata = Encoding.Default.GetBytes(express);//將要加密的字符串轉換爲字節數組
            byte[] encryptdata = rsa.Encrypt(plaindata, false);//將加密後的字節數據轉換爲新的加密字節數組
            return Convert.ToBase64String(encryptdata);//將加密後的字節數組轉換爲字符串
        }
    }

    //解密
    private string Decrypt(string ciphertext)
    {
        CspParameters param = new CspParameters();
        param.KeyContainerName = "oa_erp_dowork";
        using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param))
        {
            byte[] encryptdata = Convert.FromBase64String(ciphertext);
            byte[] decryptdata = rsa.Decrypt(encryptdata, false);
            return Encoding.Default.GetString(decryptdata);
        }
    }
//通過使用RSA加密算法產出公匙和私匙
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
using (StreamWriter sw = new StreamWriter(Server.MapPath("PublicKey.xml")))//產生公匙
{
    sw.WriteLine(rsa.ToXmlString(false));
}
using (StreamWriter sw = new StreamWriter(Server.MapPath("PrivateKey.xml")))//產生私匙(也包含私匙)
{
    sw.WriteLine(rsa.ToXmlString(true));
}

27、關於路徑名,最好就是在路徑名前面加上@,如果不加@,那麼路徑名上的 ‘\’ 要換成 ‘\’ 才行 ,原因是 ‘\’ 會被當作字符串的一部分,而 ‘\’ 才被識別爲轉義字符:路徑

28、GDI:關於graphics、brush、bitmap、image的關係

29、關於BitMap,原始需要佔用很多字節,經過RLE壓縮算法得到了很好的解決辦法。
而RLE壓縮算法的經歷:
1、原始RLE方法(未壓縮前:A-A-A-A-A-B-B-C-D,壓縮後:5-A-2-B-1-C-1-D)
2、但是第一種方法最壞情況下就是所有的數據都不連續重複,則壓縮後的數據量會增大一倍。實現的辦法只能是,在數據壓縮的時候如果發現數據的高兩位是1只能再在該數據字節前面插入數據重數字節,置其值爲1(此時由於高兩位作爲標記位已經置爲1,故這裏實際存儲的是0XC1)。這樣這個改進的RLE算法就完成了,其平均壓縮率也比原始RLE算法更高,但是相對的壓縮速度就稍微慢了。同樣的與原始RLE算法一樣也有最大長度問題,處理方法與原始RLE一樣。(未壓縮前:A-A-A-A-A-B-B-C-D,壓縮後:5-A-2-B-C-D)
3、原始的RLE算法和改進後的RLE算法對於連續出現的不重複數據的處理方式都是一個一個處理的,沒有把不重複數據作爲一個整體進行處理。對於連續重複的數據,這個數字表示需要重複的次數,對於連續不重複數據,這個數字表示連續不重複數據塊的長度。需要注意的是,只有重複次數超過2的數據才被認爲是連續重複數據,因爲如果數據的重複次數是2,壓縮後加上標誌字節後總的長度沒有變化,因此沒有必要處理。(未壓縮前:A-A-A-A-A-B-B-C-D,壓縮後:5-A-4-B-B-C-D)

30、  C# 系統應用之窗體最小化至任務欄及常用操作
一.界面操作
1.創建"Windows窗體應用程序"項目,從"工具箱"中添加NotifyIcon(運行時期間在Windows任務欄右側的通知區域顯示圖標).鼠標右擊notifyIcon1屬性,爲控件屬性Icon添加圖標,Text屬性爲"CSDN".
2.添加ContextMenuStrip(當用戶右擊關聯控件時顯示快鍵菜單).鼠標右鍵contextMenuStrip1屬性,進入Items添加或右鍵"編輯項".添加3個toolStripMenuItem,設置其Text爲"顯示窗體""隱藏窗體""退出".如下圖所示:

3.關聯繫統托盤圖標與右鍵菜單.設置notifyIcon1的ContextMenuStrip屬性爲contextMenuStrip1關聯兩個控件.運行程序,右下角任務欄的系統托盤處圖標點擊右鍵顯示如下圖所示:

 
二.窗體設置
 窗體設置主要是當窗體點擊"退出"按鈕時,任務欄仍然顯示圖標且程序沒有退出.設置Form1的MaximizeBox(窗體是否能最大化)屬性設置爲False,讓其不能最大化.併爲Form1添加FormClosing(當用戶關閉窗體時,在窗體已關閉並制定關閉原因前發生)事件.如下圖所示.

添加代碼如下,主要實現的功能是當用戶點擊窗體"關閉"按鈕或通過Alt+F4快捷關閉時,取消關閉操作且窗體隱藏,任務欄圖標仍然顯示:

//窗體關閉前發生事件
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    //窗體關閉原因爲單擊"關閉"按鈕或Alt+F4
    if (e.CloseReason == CloseReason.UserClosing)
    {
        e.Cancel = true;           //取消關閉操作 表現爲不關閉窗體
        this.Hide();               //隱藏窗體
    }
}

其中:FormClosingEventArgs 類爲FormClosing事件提供數據,其屬性Cancel獲取或設置是否應取消事件的值,CloseReason獲取一個值,該值指示關閉窗體的原因.(詳見MSDN FormClosingEventArgs 類)
注意:添加的事件是Form_Closing-窗體關閉前發生,而不是Form_Closed窗體已關閉發生.它沒有e.Cancel屬性,會提示錯誤 "System.Windows.Forms.FormClosedEventArgs"不包含Cancel的定義.

三.系統托盤功能
常見的窗體最小化至任務欄(系統托盤)圖標的功能:
1.當鼠標左鍵點擊圖標時,顯示窗體.
2.當鼠標右鍵點擊圖標時,顯示"顯示窗體"\"隱藏窗體"\"退出"菜單欄,並有相對應的功能.
具體操作是:分別點擊"顯示窗體"\"隱藏窗體"\"退出"在其屬性欄中添加"Click"事件.添加代碼如下:

//"顯示窗體"單擊事件
private void toolStripMenuItem1_Click(object sender, EventArgs e)
{
    this.Show();                                //窗體顯示
    this.WindowState = FormWindowState.Normal;  //窗體狀態默認大小
    this.Activate();                            //激活窗體給予焦點
}

//"隱藏窗體"單擊事件
private void toolStripMenuItem2_Click(object sender, EventArgs e)
{
    this.Hide();                      //隱藏窗體
}

//"退出"單擊事件
private void toolStripMenuItem3_Click(object sender, EventArgs e)
{
    //點擊"是(YES)"退出程序
    if (MessageBox.Show("確定要退出程序?", "安全提示",
                System.Windows.Forms.MessageBoxButtons.YesNo,
                System.Windows.Forms.MessageBoxIcon.Warning)
        == System.Windows.Forms.DialogResult.Yes)
    {
        notifyIcon1.Visible = false;   //設置圖標不可見
        this.Close();                  //關閉窗體
        this.Dispose();                //釋放資源
        Application.Exit();            //關閉應用程序窗體
    }
}

其中,窗體的狀態FormWindowState有Minimized(最小化)、Maximized(最大化)、Normal(默認大小).有的程序設置sizechanged事件,當用戶點擊"最小化"按鈕窗體尺寸變化時才最小化至任務欄(系統托盤).但我認爲打開程序時就有最小化圖標更好,同時添加FormClosing事件更符合用戶使用.點擊"退出"運行結果如下圖所示: 

最後添加鼠標左鍵圖標顯示窗體功能.右鍵notifyIcon1屬性,添加MouseClick(鼠標單擊組件時發生)事件.添加代碼如下:
//鼠標左鍵圖標事件
private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
{
    //點擊鼠標"左鍵"發生
    if (e.Button == MouseButtons.Left)
    {
        this.Visible = true;                        //窗體可見
        this.WindowState = FormWindowState.Normal;  //窗體默認大小
        this.notifyIcon1.Visible = true;            //設置圖標可見
    }
}

四.完整代碼
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinFormMin
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //窗體關閉前發生事件
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //窗體關閉原因爲單擊"關閉"按鈕或Alt+F4
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;           //取消關閉操作 表現爲不關閉窗體
                this.Hide();               //隱藏窗體
            }
        }

        //"顯示窗體"單擊事件
        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            this.Show();                                //窗體顯示
            this.WindowState = FormWindowState.Normal;  //窗體狀態默認大小
            this.Activate();                            //激活窗體給予焦點
        }

        //"隱藏窗體"單擊事件
        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            this.Hide();                      //隱藏窗體
        }

        //"退出"單擊事件
        private void toolStripMenuItem3_Click(object sender, EventArgs e)
        {
            //點擊"是(YES)"退出程序
            if (MessageBox.Show("確定要退出程序?", "安全提示",
                        System.Windows.Forms.MessageBoxButtons.YesNo,
                        System.Windows.Forms.MessageBoxIcon.Warning)
                == System.Windows.Forms.DialogResult.Yes)
            {
                notifyIcon1.Visible = false;   //設置圖標不可見
                this.Close();                  //關閉窗體
                this.Dispose();                //釋放資源
                Application.Exit();            //關閉應用程序窗體
            }
        }

        //鼠標左鍵圖標事件
        private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
        {
            //點擊鼠標"左鍵"發生
            if (e.Button == MouseButtons.Left)
            {
                this.Visible = true;                        //窗體可見
                this.WindowState = FormWindowState.Normal;  //窗體默認大小
                this.notifyIcon1.Visible = true;            //設置圖標可見
            }
        }
    }
}
## 鼠標事件:
1、MouseMove:表示在控件的區域內鼠標任意移動都會觸發的事件,只要一移動就會觸發,所以會觸發很多次。
2、MouseEnter:表示鼠標經過該控件就會觸發一次,就是鼠標在該控件的區域範圍內就會觸發一次。
3、與MovseEnter相對的就是MovseLeave:也是隻會觸發一次,就是當鼠標從控件區域範圍離開就會觸發一次。
4、MovseHover:和MovseEnter類似,但是Hover的意思是:徘徊,意思就是需要鼠標在控件區域範圍內一段時間纔會觸發。很遺憾,MovseHoverTime字段只能get,不能set,所以只有400ms。
  通過System.Windows.Forms.SystemInformation.MouseHoverTime;便可get到。

1、Point類中:X和Y都是int型;PointF類中:X和Y都是float型
image.png

2、  畫橢圓: Graphics.FillEllipse(Brush, new Rectangle(0, 0, 200, 300));

public Rectangle(int x, int y, int width, int height)
    System.Drawing.Rectangle 的成員

摘要:
用指定的位置和大小初始化 System.Drawing.Rectangle 類的新實例。

參數:
x: 矩形左上角的 x 座標。
y: 矩形左上角的 y 座標。
width: 矩形的寬度。
height: 矩形的高度。

3、獲取鼠標位置
(1)Control.MousePosition:是整個屏幕鼠標的位置,左上角(0,0)
(2)Form.EventArgs e.Location:是控件裏面鼠標的位置,控件的左上角(0,0)

4、ArrayList<Integer>如何轉換爲數組
 ArrayList<Integer> intList = new ArrayList<Integer>();//泛型爲Integer
intList.add(123);
intList.add(234);
intList.add(345);
Integer[] b = new Integer[intList.size()];//當泛型爲Integer時,需要
 b = (Integer[])intList.toArray(b);      //以Integer類來作爲數組基本元素

5、返回上一層文件夾: ..\
private string pictureRoad = @”……\Tempature.jpg”; //已經返回了三層

6、 DataGirdView單元列內容居中顯示:dataGridView.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
7、GroupBox 去掉邊框線重寫paint事件:
private   void   groupBox1_Paint(object   sender,   System.Windows.Forms.PaintEventArgs   e)   
  {   
       e.Graphics.Clear(this.BackColor);   
  }
8、子控件在父控件居中,基於groupbox的父子居中
/// <summary>
/// 兩個groupBox的居中
/// </summary>
/// <param name="kidBox">子groupBox</param>
/// <param name="FatherBox">父groupBox</param>
public void GroupBoxReSize(GroupBox kidBox, GroupBox FatherBox)
{
    kidBox.Left = (FatherBox.Left - kidBox.Left) / 2;
    int x = (int)(FatherBox.Width - kidBox.Width) / 2;
    int y = kidBox.Location.Y;
    kidBox.Location = new Point(x, y);

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章