2013年5月31日 星期五

字母與ASCII的轉換

前文參考

在本文將介紹 如何將A的字元 轉成 ASCII

大概複習一下!
ASCII(美國信息互換標準代碼)是一套電腦編碼系統

UNICODE 是萬國碼,使電腦得以呈現世界上數十種文字的系統

再來須注意的是ASCII碼有多種編碼方式 UTF8 表示8bit與
UTF16表示16bit
在 C# 中,所有記憶體內的字串編碼都是 Unicode (UTF-16)

OK觀念清楚後 來開始看如何轉換吧!

首先來個字串A好了
string F="A";
我們的目標是要把A的ASCII碼SHOW出
再來宣告物件 變數Q是Encodeng物件
GetEnocding設定取的Unicode UTF16
Encoding Q= encoding.GetEncoding("Unicode")

用byte[]存取8位元為一個陣列 Q.GeyByte(取F的Unicode-UTF16)
byte[] x=Q.GeyBytes(F);

這邊順便解釋一下 陣列中的數值
注意 我門的容器是Byte[]代表 8bit一個陣列
但是 GetByte是一個UTF16的 16bit
這代表著甚麼事情呢
代表著 byte[]陣列中
A=65 轉二進為 10000010 00000000 前8bit都用不完了
那後面的8bit           00000000 =10進致的0
GetByte取的是16bit
所以 byte[]陣列中
後面8bit 將等於0
X[0]= 65    X[1]=0

再來只需要把 陣列 show出 即可

來看一下程式碼如下

private void button1_Click(object sender, EventArgs e)
        {
            string r = "z";
            //在 C# 中,所有記憶體內的字串編碼都是 Unicode(UTF-16)16bit。
            //當您將資料從儲存區帶入 string 物件時,資料會自動轉換成 UTF-16
            Encoding Q = Encoding.GetEncoding("UTF-16");//設定取UTF16
            byte[] p = Q.GetBytes(r);//Q取r字串中的UTF16以每8bit放進byte[]陣列
            string f = p[0].ToString();//p[0]=122再轉成字串輸出
           
        }

再來我們看
更進階的寫法 在書看到的
類是匿名方式 剛接觸有點混亂 所以紀錄一下
來看一下 Encoding 的合併宣告+判斷

首先來個題目
String A="zA" //等等要解析z與A
//先來個位元組容器 並在W後面直接建立物件
byte[] W = Encoding.GetEncoding("Unicode").GetBytes(A);
//再來做輸出動作 並指定陣列W[0] 代表z
MessageBox.Show(W[0].ToString());

再來另一個做法
以字串當容器 缺點是會長一點
不同的是 要在GetBytes中建立char 並指定A字串中哪一個字[0]=z [1]=A
之後再以位元組的角度去思考[0] 輸入字串
注意 前者陣列是字串 後者 指位元組
string RRT = Encoding.GetEncoding("unicode").GetBytes(new char[] {A[1]})[0].ToString();
之後直接輸出 即可

再來我們看看如何將Unicode轉回字元吧
我們都知道A=65

//先用整數型態存取65
int E=65;
//再來需要char的幫忙 char
//存放不帶正負號的 16 位元 (2 位元組) 字碼指標,範圍從 0 到 65535。
//每一個「字碼指標」或字元碼代表單一 Unicode 字元。
char G=(char)A;
G裡面會存放一個65
如果要存放2個以上呢
只好用陣列了!
char[] yt = { 'H', 'I' };
yt[0]=72  yt[1]=73
現在明白char是存取數值
再來往下探討

int E=65; //設定整數E=65
string y=((char)E).ToString();
MessageBox.Show(y);
用一個字串String 當容器
((char)E)將E轉成char
再將char值轉對等的字串表示
剛好放進string容器中
在show出來65即可轉回 A


明白這原理後 可以來看正是題目了
例題如下

2個BUTTON! 4個textbox
每一組 1個BUTTON 2個Textbox 來做字元與ASCII的轉換
第一組 字元轉ASCII
第二組 ASCII轉字元

第一組程式碼如下


private void btn_ToASCII_Click(object sender, EventArgs e)
        {                                     //你的radioButton
            if (txt_char.Text != string.Empty)//如果txt_char不等於空直
            {                                  //注意判斷式中[1]表示位元組指的是 第二位元組
                                               //數字不超過8bit! 所以剩下8bit=0通常是字母
                if (Encoding.GetEncoding("unicode").GetBytes(new char[] { txt_char.Text[0] })[1] == 0)
                {    //得到字符的ASCII碼值 直接輸出textbox!
                    txt_ASCII.Text = Encoding.GetEncoding("unicode").GetBytes(txt_char.Text)[0].ToString();
                }
                else
                {
                    txt_ASCII.Text = string.Empty;//輸入不是字母
                    MessageBox.Show("請輸入字母!", "提示!");//提示用戶訊息
                }
            }
        }





第二組如下

private void btn_ToChar_Click(object sender, EventArgs e)
        {
            if (txt_ASCII2.Text != string.Empty)//如果不等於空直 空的
            {
                int P_int_Num;//定義整型局部變數
                //將使用者在textbox輸入的數字轉成 P_int_Num
                if (int.TryParse(txt_ASCII2.Text, out P_int_Num))
                {
                    //將P_int_Num int 轉char.Tostring()=A
                    //在輸出Text屬性
                    txt_Char2.Text =((char)P_int_Num).ToString();//將ASCII碼轉換為字符
                }
                else
                {    //告訴使用者輸入已超過int整數數值範圍
                    MessageBox.Show(//如果輸入不符合要求彈出提示框
                        "請輸入正確ASCII碼值。", "錯誤!");
                }
            }
           
        }

2013年5月27日 星期一

ToUpper與ToLower 字串的大小寫轉換

如果  String 轉換大寫 或寫小呢?
string 變數 ="abc".ToUpper;
會等於     變數"=ABC"
string 變數="ABC".ToLower;
會等於     變數"=abc"
來看一下範例

public partial class Frm_Main : Form
    {
        public Frm_Main()
        {
            InitializeComponent();
        }
        private void btn_change_Click(object sender, EventArgs e)
        {
            if (rbtn_upper.Checked)//判斷radioButton 是不是選rbtn_upper
            {
                txt_changed.Text = txt_string.Text.ToUpper();
            }
            else//判斷radioButton 是不是選rbtn_lower
            {
                txt_changed.Text = txt_string.Text.ToLower();
            }
        }
        private void txt_string_MouseClick(object sender, MouseEventArgs e)
        {   //假如字串中的名與"          請輸入字串"一樣TURE
            if (txt_string.Text == "          請輸入字串")
            {
                txt_string.Text = //清空TextBox控制元件中的文字訊息
                    string.Empty;
            }
        }
    }



上面TextBox字串用了一個小技巧
讓使用者 點選TextBox時 "請輸入字串" 消失
利用MouseClick觸發事件即可

2013年5月24日 星期五

goto搜尋listbox中的item與AddRange的方法

將標題放入字串陣列中
然後可以使用 System.Array 的IndexOf 指定搜尋範圍
也可以使用 for迴圈下去搜尋

這裡將介紹如何使用goto來達到循環搜尋的效果
來看下面 範例

namespace Goto
{
    public partial class Frm_Main : Form
    {
        public Frm_Main()
        {
            InitializeComponent();
        }
        string[] G_str_array = new string[] //定義陣列並初始化
        { //首先 建立字串陣列
        "C#範例寶典",
        "C#編程寶典",
        "C#視頻學",
        "C#項目開發全程實錄",
        "C#項目開發實例自學手冊",
        "C#編程詞典",
        "C#實戰寶典",
        "C#經驗技巧寶典",
        "C#入門模式",
        };
        private void Frm_Main_Load(object sender, EventArgs e)
        {//在程式執行瞬間 利用AddRange 把G_str_array全部加入item中
            lbox_str.Items.AddRange(G_str_array);
        }
        private void btn_query_Click(object sender, EventArgs e)
        {
            int i = 0;//定義計數器
            label1://定義標籤 這標籤 是給goto的跳回指標
            //Contains指出指定的(String)物件是否會出現在這個字串內
            //回傳布林 ture false
            if (G_str_array[i].Contains(txt_query.Text))//判斷是否找到圖書
            {
                lbox_str.SelectedIndex = i;//選中搜尋到的結果
                MessageBox.Show(txt_query.Text + " 已經找到!", "提示!");//提示找到訊息
                return;
            }
            i++;//累加i
            if (i < G_str_array.Length) goto label1;//i 小於 陣列數 跳轉到 標籤
            MessageBox.Show(txt_query.Text + " 沒有找到!", "提示!");//提示未找到訊息
        }
    }
}



再來介紹一個 好用的方法AddRange
語法如下
public virtual void AddRange
(
  Control[] controls
)
我們可以如上列子
把定義好的陣列整批加到Item中

2013年5月23日 星期四

在Windows Form 中加入事件與事件解析

本文參考於http://www.dotblogs.com.tw/hung-chin/archive/2011/10/01/38490.aspx
我們在程式執行時會先去執行Program.cs 裡面 Main這一段{}
去呼叫第一個啟動的form

這範例的啟動表單就叫BaseForm

static void Main()
 {
     Application.EnableVisualStyles();
     Application.SetCompatibleTextRenderingDefault(false);
     Application.Run(new BaseForm());
 }

接著會執行表單內的這一段 public 加上表單名稱,從InitializeComponent();初始化動作新增我們要的事件 我們加入Form的FormClosing事件
這事件用於 視窗關閉時 觸發!  請看在BaseForm.Designer.cs檔案中的
private void InitializeComponent(){加入事件} 範例如下
       

 private void InitializeComponent()
  {
        //在InitializeComponent()中還有許多要初始化的原件
        //直接添入下面那一行即可
        FormClosing += new System.Windows.Forms.FormClosingEventHandler
                                                                         (this.Frm_Main_FormClosing);
  }


再來解說 註冊FormClosing他的驅動原理
首先第一句FormClosing 他是一個發生於表單關閉之前會觸發的事件。
而需要注意的是他的語法中public event FormClosingEventHandler FormClosing
FormClosingEventHandler剛好是我們接下來要解釋的委派
如果忘記委派請往前翻 趕快看看如何使用吧
委派到哪裡去呢? Forms.FormClosingEventHandler (this.Frm_Main_FormClosing);
委派到Form.cs檔案中的 Frm_Main_FormClosing程式區塊中
長這樣 如下
 private void Frm_Main_FormClosing(object sender, FormClosingEventArgs e)
        {

         }

再回到委派FormClosingEventHandler中的語法來解析
public delegate void FormClosingEventHandler
(
  Object sender,
  FormClosingEventArgs e
)

當按下關閉時會觸發裡面有兩個參數
       sender = {WindowsFormsApplication5.Form1, Text: Form1}
而            e = {System.Windows.Forms.FormClosingEventArgs}


看到FormClosingEventArgs 類別 順便一提 等等要解釋的屬性
FormClosingEventArgs.Cancel取得或設定值,這個值表示是否應該取消事件。
如果應該要取消事件則為 true,否則為 false

再來我們看一下Form.cs檔案中的 Frm_Main_FormClosing程式區塊中
的實際應用吧!
private void Frm_Main_FormClosing(object sender, FormClosingEventArgs e)
{
/*
if (e.CloseReason != CloseReason.WindowsShutDown)
{
if (MessageBox.Show("是否確定要關閉程式", "關閉程式", MessageBoxButtons.YesNo) == DialogResult.No)
{
e.Cancel = true;
}
}
*/


if (MessageBox.Show("你剛按關閉對吧!", "關閉程式", MessageBoxButtons.YesNo) == DialogResult.No)
{
e.Cancel = true;//如果選擇no取消這事件 不關閉視窗
//e=FormClosingEventArgs.Cancel=true

}
//Environment.Exit(0);//強行關閉視窗
}







在這之後 還有許多Form的事件可以用
可以參考msdn中的
Windows Form 中事件的順序

2013年5月17日 星期五

猜數字遊戲關鍵技術紀錄

光要寫一個猜數字遊戲 就花了不少時間try啊!
終於完成並融會貫通全部的函式~有些書上根本不會說
來記錄一下之前思緒的集合吧

關於猜數字遊戲的 玩法
首先建立 100個button 
在建立完後同事 分配一個Thtead計時用
並調用控制項 SHOW出時間!

再利用Randon 亂數取直1~100其中之1
再由共同事件觸發邏輯判斷
Button 名稱是否大於 Random的值
如果大於R值 更改Button.text值為大
如果小於R值                                   小
如果 等於R值SHOW出多少秒?猜幾次? 才猜中

關於猜幾次的函式裡利用深度搜尋控制項目是否
為ebable 如果是 累加Count 計算值
之後需要時 取Count值

在按下BUTTON 瞬間
需同時加入 清除BUTTON函式
用於清除 玩完的BUTTON
好讓程序 重新建立100個BUTTON!

來看程式碼吧 比較好懂

首先 建立  全域的 thread 與 random 存放random值得 int整數型態

        Thread G_th;//定義多執行序物件叫G_th,稍後實體化G_TH物件
        Random G_random = new Random();//宣告 與實體化 亂數物件
        int G_int_num;//定義變數用於存放存機數





再來建立一個Button來讓遊戲開始
而Button處方的事件可多了 CODE如下
計時工作Thread並使用匿名方式 因為只叫用一次

private void btn_begin_Click(object sender, EventArgs e)//按下按鈕後
        {
            RemoveControl();//呼叫副程式,清空所有無用對像,玩完要清除玩過的畫面
            int p_int_x = 10;//X坐標預設值為10
            int p_int_y = 60;//Y坐標預設值為60
            for (int i = 0; i < 100; i++)//新增100個按鈕
            {
                Button bt = new Button();//宣告與實體化button按鈕
                bt.Text = (i + 1).ToString();//設定button按鈕的文字值
                bt.Name = (i + 1).ToString();//設定button按鈕的Name屬性
                bt.Width = 35;//設定button按鈕的寬
                bt.Height = 35;//設定button按鈕的高
                bt.Location = new Point(p_int_x, p_int_y);//設定button按鈕的位置
                bt.Click += new EventHandler(bt_Click);//定義button按鈕的事件
                p_int_x += 36;//設定下一個按鈕的位置,右移36
                if ((i + 1) % 10 == 0)//設定換行10/10=於0換下一行
                {
                    p_int_x = 10;//換行後重新設定X坐標,左移回到10
                    p_int_y += 36;//換行後重新設定Y坐標,下移36
                }
                Controls.Add(bt);//button設定好後放入Controls中
            }
            G_th = new System.Threading.Thread
                //實體化G_TH 並且
                //利用多執行續 來執行委派,這裡委派使用匿名方式
                (delegate()
                {
                    //http://www.dotblogs.com.tw/yc421206/archive/2009/02/16/7206.aspx
                    int P_int_count = 0;//初始化計數器
                    while (true)//開始無限循環
                    {//計數累加1之後做判斷,三元判斷
                        P_int_count = ++P_int_count > 100000000 ? 0 : P_int_count;
                        this.Invoke(//將程式碼交給主線程執行
                            (MethodInvoker)delegate//使用匿名方法
                            {
                                label6.Text += 1;
                                lb_time.Text = //視窗中顯示計數
                                    P_int_count.ToString();
                            }
                            );
                        System.Threading.Thread.Sleep(1000);//線程睡眠1秒
                    }
                }
                );
            G_th.IsBackground = true;//設定線程為後台線程
            G_th.Start();//開始執行線程
            G_int_num = G_random.Next(1, 100);//產生隨機數1~到100
            btn_begin.Enabled = false;//停用開始按鈕
        }



再來是一個 RESET BUTTON的工作 來清楚之前玩過的按鈕
在上面BUTTON中被呼叫的RemoveControl() CODE如下
將會開始搜尋 控制項KEY索引直 在羅技判斷 名子是否為1~100如果是 刪除!
void RemoveControl()
        {
            for (int i = 0; i < 100; i++)//開始深度搜尋100個按鈕
            {
                //如果ContainsKey索引 會搜尋controls中text叫1~100的按鈕
                if (Controls.ContainsKey((i + 1).ToString()))//如果找到k值繼續執行
                {
                    for (int j = 0; j < Controls.Count; j++)//j<控制項的種集合數量;j++
                    {   ////搜尋索引值1~100的text是否有叫1的
                        if (Controls[j].Name ==(i + 1).ToString())
                        {//刪除指定控制向的索引值 RemoveAt(索引值)
                            Controls.RemoveAt(j);//刪除指定按鈕
                            break;//終止j迴圈
                        }
                    }
                }
            }
        }

再來是一個事件觸發的動作
這100個BUTTON中 雖然觸發同一個事件叫bt_Click
但是每一個BUTTON的名子不一樣
然而sender 傳來的是一個Text=1~100的屬性值
利用它來做按了哪一個按鈕做判斷

void bt_Click(object sender, EventArgs e)
        {
            Control P_control = sender as Control;//將sender轉換為control類型對像
            if (int.Parse(P_control.Name) > G_int_num)
            {
                P_control.BackColor = Color.Red;//設定按鈕背景為紅色
                P_control.Enabled = false;//設定按鈕停用
                P_control.Text = "大";//更改按鈕文字
            }
            if (int.Parse(P_control.Name) < G_int_num)
            {
                P_control.BackColor = Color.Red;//設定按鈕背景為紅色
                P_control.Enabled = false;//設定按鈕停用
                P_control.Text = "小";//更改按鈕文字
            }
            if (int.Parse(P_control.Name) == G_int_num)
            {
                G_th.Abort();//終止計數線程
                MessageBox.Show(string.Format(//顯示遊戲訊息
                    "恭喜你猜對了!共猜了{0}次 用時{1}秒",
                    GetCount(), lb_time.Text), "恭喜!");
                btn_begin.Enabled = true;//啟用開始按鈕
            }
        }


再來最後一個則是紀錄 按了幾次的副程式
用於搜尋視窗中Enable屬性為False控制元件的數量
用於計算玩家有多少次沒有猜中
返回沒有猜中數量
CODE如下

string GetCount()
        {
            int P_int_temp = 0;//初始化計數器
            foreach (Control c in Controls)//深度搜尋控制元件集合
            {
                if (!c.Enabled)
                {
                    P_int_temp++;//計數器累加
                }
            }
            return P_int_temp.ToString();//返回計數器訊息
        }




完整程式碼如下

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace NumGame
{
    public partial class Frm_Main : Form
    {
        public Frm_Main()
        {
            InitializeComponent();
        }
        Thread G_th;//定義多執行序物件叫G_th,稍後實體化G_TH物件
        Random G_random = new Random();//宣告 與實體化 亂數物件
        int G_int_num;//定義變數用於存放存機數
        private void btn_begin_Click(object sender, EventArgs e)//按下按鈕後
        {
            RemoveControl();//呼叫副程式,清空所有無用對像,玩完要清除玩過的畫面
            int p_int_x = 10;//X坐標預設值為10
            int p_int_y = 60;//Y坐標預設值為60
            for (int i = 0; i < 100; i++)//新增100個按鈕
            {
                Button bt = new Button();//宣告與實體化button按鈕
                bt.Text = (i + 1).ToString();//設定button按鈕的文字值
                bt.Name = (i + 1).ToString();//設定button按鈕的Name屬性
                bt.Width = 35;//設定button按鈕的寬
                bt.Height = 35;//設定button按鈕的高
                bt.Location = new Point(p_int_x, p_int_y);//設定button按鈕的位置
                bt.Click += new EventHandler(bt_Click);//定義button按鈕的事件
                p_int_x += 36;//設定下一個按鈕的位置,右移36
                if ((i + 1) % 10 == 0)//設定換行10/10=於0換下一行
                {
                    p_int_x = 10;//換行後重新設定X坐標,左移回到10
                    p_int_y += 36;//換行後重新設定Y坐標,下移36
                }
                Controls.Add(bt);//button設定好後放入Controls中
            }
            G_th = new System.Threading.Thread
                //實體化G_TH 並且
                //利用多執行續 來執行委派,這裡委派使用匿名方式
                (delegate()
                {
                    int P_int_count = 0;//初始化計數器
                    while (true)//開始無限循環
                    {//計數累加1之後做判斷,三元判斷
                        P_int_count = ++P_int_count > 100000000 ? 0 : P_int_count;
                        this.Invoke(//將程式碼交給主線程執行
                            (MethodInvoker)delegate//使用匿名方法
                            {
                                label6.Text += 1;
                                lb_time.Text = //視窗中顯示計數
                                    P_int_count.ToString();
                            }
                            );
                        System.Threading.Thread.Sleep(1000);//線程睡眠1秒
                    }
                }
                );
            G_th.IsBackground = true;//設定線程為後台線程
            G_th.Start();//開始執行線程
            G_int_num = G_random.Next(1, 100);//產生隨機數1~到100
            btn_begin.Enabled = false;//停用開始按鈕
        }
        void bt_Click(object sender, EventArgs e)
        {
            Control P_control = sender as Control;//將sender轉換為control類型對像
            if (int.Parse(P_control.Name) > G_int_num)
            {
                P_control.BackColor = Color.Red;//設定按鈕背景為紅色
                P_control.Enabled = false;//設定按鈕停用
                P_control.Text = "大";//更改按鈕文字
            }
            if (int.Parse(P_control.Name) < G_int_num)
            {
                P_control.BackColor = Color.Red;//設定按鈕背景為紅色
                P_control.Enabled = false;//設定按鈕停用
                P_control.Text = "小";//更改按鈕文字
            }
            if (int.Parse(P_control.Name) == G_int_num)
            {
                G_th.Abort();//終止計數線程
                MessageBox.Show(string.Format(//顯示遊戲訊息
                    "恭喜你猜對了!共猜了{0}次 用時{1}秒",
                    GetCount(), lb_time.Text), "恭喜!");
                btn_begin.Enabled = true;//啟用開始按鈕
            }
        }
        /// <summary>
        /// 用於搜尋視窗中Enable屬性為False控制元件的數量
        /// 用於計算玩家有多少次沒有猜中
        /// </summary>
        /// <returns>返回沒有猜中數量</returns>
        string GetCount()
        {
            int P_int_temp = 0;//初始化計數器
            foreach (Control c in Controls)//深度搜尋控制元件集合
            {
                if (!c.Enabled)
                {
                    P_int_temp++;//計數器累加
                }
            }
            return P_int_temp.ToString();//返回計數器訊息
        }
        /// <summary>
        /// 用於清空視窗中動態產生的按鈕
        /// </summary>
        void RemoveControl()
        {
            for (int i = 0; i < 100; i++)//開始深度搜尋100個按鈕
            {
                //如果ContainsKey索引 會搜尋controls中text叫1~100的按鈕
                if (Controls.ContainsKey((i + 1).ToString()))//如果找到k值繼續執行
                {
                    for (int j = 0; j < Controls.Count; j++)//j<控制項的種集合數量;j++
                    {   ////搜尋索引值1~100的text是否有叫1的
                        if (Controls[j].Name ==(i + 1).ToString())
                        {//刪除指定控制向的索引值 RemoveAt(索引值)
                            Controls.RemoveAt(j);//刪除指定按鈕
                            break;//終止j迴圈
                        }
                    }
                }
            }
        }
        private void Frm_Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            Environment.Exit(0);//強行關閉視窗
        }
    }
}

(object sender, EventArgs e) 關於事件的觸發

下面簡單的code可以看出 sender 與 e 裡面裝了啥東西

private void button16_Click(object sender, EventArgs e)
        {
            MessageBox.Show(sender.ToString());
            MessageBox.Show(e.ToString());
        }


第一次sender會show出
System.Winsows.Forms,Buttom,Text:Button16
SHOW一個TEXT屬直為Button16

第二次e會show出
System.Windows.Forms.MouseEventArgs
代表我使用滑鼠觸發事件
如果我使用ENTER 結果又不一樣了
結果為
System.EventArgs

用處違和呢?
關於共同事件 可用於sender取 TEXT屬性值

e值在使用滑鼠 可以取座標值

更多相關技術日後補充

2013年5月16日 星期四

Thread.IsBackground 背景執行緒解析

關於IsBackground 背景執行緒 用於
當主程序 宣告另一個 線程時 而這線程裡有個計時器 1~10
主程序裡 也設一個計時器 1~4 之後 可按任何鍵 離開程式!

在沒有設定IsBackground 預設是False
在按下任意見時 是無法離開程式的

除非把Thread.IsBackground 設定成true
把線程成訂為 背景執行續
當主程序結束時~~ 線程如同終止程序

以下範例參考

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("啟動第二程序");
            Thread t=new Thread(new ThreadStart(work));
            t.IsBackground = false;
            t.Start();
            for (int i = 0; i <= 4; i++)
            {
                Console.WriteLine("計時4次主程序");
                Thread.Sleep(1000);
            }
            Console.WriteLine("主程序已跑完 按enter鍵可以離開");
            Console.ReadLine();
        }
        private static void work()
        {
            for (int i = 0; i <= 10; i++)
            {
                Console.WriteLine("線程執行中{0},{1}",i, Thread.CurrentThread.ThreadState);
                Thread.Sleep(1000);
            }
        }
    }
   
}<\code>

2013年5月13日 星期一

關於Control與Controls的不同

每次遇到關於搜尋控制項的問題 百思不得奇解的
理解Controls之後 心想不會忘記!
結果經過時間的力量讓我再次遇見Controls
想通之後已經是2.3天過後了
還是為了這寫一篇吧XD

關於Control 與 Controls差別 先重 命名空間看起吧
他的命名空間 叫做System.Windows.Forms
基本上這個命名空間 專門在定義 控制項目 與功能表等等..
介紹先要用的就好


而底下的類別中 待會要介紹的有

Control類別 與 Control.ControlCollection類別

在這裡先來解釋Control類別
msnd中說!
定義控制項的基底類別,它們屬於具視覺表示的元件?

話說不知道是 翻譯不好還是我國文程度差
在大概觀看一下 屬性功能後 才大概明白何謂基底類別?
指 背景顏色 或 高度和寬度 等等的 介紹起來要一本書這麼多XD
關鍵來了
在Control類別中有一個叫Controls的屬性
msdn解釋說  : 取得控制項中包含的控制項集合。
在備註中 說到了重點 如下
Control 可以當做是控制項集合的父代。例如,將數個控制項加入 Form 時,每一個控制項都是指派給表單之 Controls 屬性的 Control.ControlCollection 成員 (衍生自 Control 類別)。

也就是說 Controls是    衍生自Control中的ControlCollection類別!!

ControlCollection 也就是 Controls

您可以使用 Control.ControlCollection 類別中的可用方法,管理指派給 Controls 屬性之 Control.ControlCollection 中的控制項。


再來證明 Controls等於Control.ControlCollection
我們用Controls來使用Control.ControlCollection 中的方法!

假如我要搜尋system.Windows.Forms中控制項的索引key值
利用textBox讓使用者 輸入要 搜尋屬性的text名稱 按下button之後
show出訊息!!
來看下列範例
如果視窗中 放了許多 Button1~~N 我們要搜尋其中之一 然後 刪除!
假如我要找BUTTON1 好了

 private void button12_Click(object sender, EventArgs e)
        {
            //輸入控制項的Text屬性名稱 假如E="Button1"
            string E = textBox1.Text;
            //利用ContainsKey(E)搜尋Controls裡面有沒有Text=Button1
            if (Controls.ContainsKey(E))//找到if會等於 TRUE
            {
                MessageBox.Show("準備刪除"+Controls[E]);
                Controls.Remove(Controls[E]);//刪除!
            }
            else//不然就FALSE
                MessageBox.Show("NO"+Controls[E]);
        }



 關於Controls中的動作 可參考Control.ControlCollection類別
比如 刪除Remove 或 show出name 之類的

2013年5月6日 星期一

Invoke((MethodInvoker))關於調用外部控制項

假如 今天程式呼叫委派的執行過程中
在委派中 同時又要控制 外部控制項
首先 基礎的初學者通常語法大概長這樣如下

private void button9_Click(object sender, EventArgs e)
        {//建立無傳入參數的委派物件GO
            MethodInvoker GO = new MethodInvoker(sshh);
            Invoke(GO);//開始執行GO委派物件
        }

        public void sshh()
        {//將外部控制向屬性,打入已執行
            label6.Text = "已執行";
        }

進階的話 有人會使用匿名法  一時難以理解   CODE如下


private void button9_Click(object sender, EventArgs e)
        {
            Invoke((MethodInvoker)delegate{label5.Text="已執行";});
        }

再來如果今天 觸發INVOK不是 BUTTON的話而是
方法或委派或多程序
我們就要..
範例如下

private void button11_Click(object sender, EventArgs e)
        {
            Thread po = new Thread(new ThreadStart(Dooo));
            po.Start();
        }
        public void Dooo()
        {
            MethodInvoker ee = new MethodInvoker(delegate { label6.Text = "SSSSS"; });
            Invoke(ee);
        }
也可以在縮寫如下

Invoke((MethodInvoker)delegate { label6.Text = "WWW"; });
再來更進階一點的範例
比如說 方塊又戲中的  時鐘 或 計時器
計時一分鐘
我們用多程序來執行時鐘 並SHOW到LABLE上
計時器範例如下

private void button10_Click(object sender, EventArgs e)
        {//建立多程序 G,多程序啟動委派匿名方式
            Thread G = new System.Threading.Thread(delegate()
                {
                    int P_int_count = 0;//宣告整數當作秒數累加計時器用
                    while (true)//開始無限循環
                    {//計數累加1之後做判斷,三元判斷
                        //++P_int_count 先+1才做判斷喔~
                        //如果P_int_count沒超過100000000的話 判斷為P_int_count自己
                        P_int_count = ++P_int_count > 100000000 ? 0 : P_int_count;
                        //再利用INVOKE啟動,匿名委派中的方法 而方法再去控制外部LABLE
                        Invoke((MethodInvoker)delegate { label7.Text = P_int_count.ToString(); });
                        System.Threading.Thread.Sleep(1000);//睡眠1秒在重複執行
                    }
                }
                );
            G.Start();//開始執行多程序
        }

2013年5月1日 星期三

MethodInvoker簡易委派不帶參數

這項委派可執行 Managed 程式碼中任何宣告為 void 且不採用任何參數的方法。

MethodInvoker提供簡單的委派,用來叫用該方法具有虛值的參數清單。進行呼叫的控制項時,就可以使用這個委派Invoke方法,或者當您需要簡單的委派,但不是想要自行定義。


private void button9_Click(object sender, EventArgs e)
        {
            MethodInvoker GO = new MethodInvoker(sshh);
            Invoke(GO);
        }

        public void sshh()//建立VOID物件
        {
            label6.Text = "已執行";
        }