2013年12月25日 星期三

C# 動態建立事件、刪除事件




public Form1()
{
    InitializeComponent();
}

// 動態建立事件及刪除事件。
// 建立三個 Button,分別取名 btnAdd, btnDel, btnShow
// 按下 btnAdd 可動態建立事件。
// 按下 btnDel 可動態刪除事件。
// 在事件建立後,按下 btnShow 會秀出 "Hello world!"
// btnAdd 按幾次,就會建立相應次數的 btnShow_Click 事件。
//
private void btnAdd_Click(object sender, EventArgs e)
{
    // 動態建立事件。
    // 輸入到 += 時,可以按兩下 Tab鍵 會自動建立 btnShow_Click 事件。
    btnShow.Click += new EventHandler(btnShow_Click); 


    // Visual Studio 2005 才有 EventHandler(btnShow_Click)
    // Visual Studio 2005 只剩下 btnShow_Click
}

void btnShow_Click(object sender, EventArgs e)
{
    MessageBox.Show("Hello world!");
}

private void btnDel_Click(object sender, EventArgs e)
{
    // 動態刪除事件。
    btnShow.Click -= new EventHandler(btnShow_Click);
}

C# 動態建立事件




筆記:C# 動態建立事件。
1.建立一個 Window 應用程式。
2.拉一個 groupBox ,並且放入幾個 TextBox 及 ComboBox 排成一直行。
3.接下來完成下面的 code ,就可以用上下鍵在各個 TextBox 間移動。


        private void Form1_Load(object sender, EventArgs e)
        {
            // 跑回圈。
            // groupBox1.Controls Controls 代表 groupBox 中所有物件。
            foreach (Control ctl in groupBox1.Controls)
            {
                // 針對不同的物件,各自動態建立事件。
                if (ctl is TextBox)
                {
                    // Form Load 時動態建立 txt_KeyDown 事件。
                    //        打到 += 之後(↓這裡),按下 Tab鍵,便會自動產生事件。
                    ((TextBox)ctl).KeyDown += new KeyEventHandler(txt_KeyDown);
                    // Form Load 時動態建立 txt_GotFocus 事件。
                    ((TextBox)ctl).GotFocus += new EventHandler(txt_GotFocus); 
                }
                else if (ctl is ComboBox)
                {
                    // Form Load 時動態建立 txt_KeyDown 事件。
                    ((ComboBox)ctl).KeyDown += new KeyEventHandler(txt_KeyDown);
                    // Form Load 時動態建立 txt_GotFocus 事件。
                    ((ComboBox)ctl).GotFocus += new EventHandler(txt_GotFocus);

                }

            }
        }

        void txt_GotFocus(object sender, EventArgs e)
        {
            // 宣告 txt,將 sender 轉型成 TextBox 後,用 txt 承接
            // 這種轉型的方法,看很多次,還是不懂啊....
            TextBox txt = (TextBox)sender;
            txt.SelectAll();
        }

        private void txt_KeyDown(object sender, KeyEventArgs e)
        {
            // C# select case
            switch (e.KeyCode)
            {

                case Keys.Down:
                case Keys.Return:
                    // 送出 Tab 鍵的訊號
                    SendKeys.Send("{Tab}");
                    break;
                case Keys.Up:
                    // 送出 Shift + Tab 鍵的訊號
                    // +」號代表 Shift
                    SendKeys.Send("+{Tab}");
                    break;
                default:
                    break;
            }
        }

2012年12月9日 星期日

String 斷行方式

VB的斷行方式,是
Dim S as string ="SELECT [Date] " & _
                 "      ,[Unit]
" & _ 
                 "      ,[UID] " & _
                 "      ,[MDate] " & _
                 "  FROM [FOD11] "

C#的斷行方式,是
string S =  @"SELECT [Date]
                    ,[Unit]
                    ,[UID]
                    ,[MDate]
                FROM [FOD11] ";

2012年9月20日 星期四

Crystal Reports 指定子報表接收DataTable資料


建立Crystal Reports報表,使用XML Schema File,使用Crystal Reports中資料庫 > 設定資料來源位置 > 建立新連結 > ADO.NET(XML)來設定報表欄位的方式,這些步驟就先略過了。直接跳回VB端,紀錄塞資料給指定子報表的方式。


REM 宣告 Table
Dim print_Main As New DataTable
Dim print_TermsOfPayment As New DataTable
Dim print_Building As New DataTable
Dim print_Agreement As New DataTable

REM 取得報表資料:
print_Main = Wer_Service_Name( Mode=2, "參數", ServerVer)
print_TermsOfPayment = Wer_Service_Name( Mode=3, "參數", ServerVer)
print_Building = Wer_Service_Name( Mode=4, "參數", ServerVer)
print_Agreement = Wer_Service_Name( Mode=5, "參數", ServerVer)

REM 載入資料至主報表:
rptDoc_R001.SetDataSource(print_Main)

REM 載入資料至子報表:
REM 方法一,直接指定子報表名稱並匯入資料。
rptDoc_R001.Subreports.Item("R001_TermsOfPayment.rpt").SetDataSource(print_TermsOfPayment)
rptDoc_R001.Subreports.Item("R001_building.rpt").SetDataSource(print_Building)
rptDoc_R001.Subreports.Item("R001_agreement.rpt").SetDataSource(print_Agreement)
REM 方法二,以順序指定子報表並匯入資料。
rptDoc_R001.Subreports.Item(0).SetDataSource(print_TermsOfPayment)
rptDoc_R001.Subreports.Item(1).SetDataSource(print_Building)
rptDoc_R001.Subreports.Item(2).SetDataSource(print_Agreement)

備註:
使用方法二,要注意子報表名稱的排序,需跟子報表放置順序一樣,否則很容易出錯。也就是最好把子報表的名稱R001_TermsOfPayment.rptR001_building.rptR001_agreement.rpt,改成R001_0.rpt""R001_1.rpt""R001_2.rpt"這樣的名稱,這樣給資料到子報表時才不會出錯。 


傳值到子報表需在報表端設定。

子報表端設定:
對子報表點選右鍵 > 變更子報表連結... > 設定要連結的欄位。

























除了可以連結欄位之外,也可以用來傳值到子報表。

先分別設定好母報表端的「參數欄位」以及子報表的「參數欄位」,接著設定子報表連結。
當母報表接收到傳入值時,就可以透過子報表連結傳遞到子報表端。

2012年9月11日 星期二

C# 的命名空間


開始C#人生了。

然後我發現我的基本觀念都很差,而且應該會繼續差下去吧。因為像「命名空間」、「類別空間」、...這種東西,在我工作的場合,會變動到它們的機會不多。很少用的東西,對我來說,也是容易遺忘的東西,不容易在人腦記憶體裡面佔一席之地。

但不知道,也說不過去,所以還是要記錄一下這些基礎的東西。



// 引用相關的命名空間
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1  // 命名空間。ConsoleApplication1 同時也是專案名稱。
{
    class Program              // 類別空間
    {
        static void Main(string[] args)  // Main() 方法為程式進入點
        {
        }
    }
}





2012年9月3日 星期一

CASE 函數


/* case 函數*/

--對欄位作CASE的判斷。
SELECT s.[std_name] + CASE p.[addr] when '新竹市' then '市民' else '訪客' end
      ,p.[addr]
  from [personal] p,[score] s
 where p.[std_num]=s.[std_num]


--對欄位下條件作CASE的判斷。
SELECT s.[std_name] + CASE when p.[addr] like '新竹%' then '在地人' else '觀光客' end
      ,p.[addr]
  from [personal] p,[score] s
 where p.[std_num]=s.[std_num]


SELECT [std_num]
      ,[std_name]
      ,[CO]
      ,[DB]
      ,[SP]
      ,[TD]
      ,[judgment]
      ,總成績=co+db+sp+td
      ,本次考試表現=case 
                    when co+db+sp+td>=360 then '非常好!'
                    when co+db+sp+td>=320 then '再加油!'
                    else '太混了!' end
  FROM [CSIE98].[dbo].[score]



--對排序作CASE的判斷。
SELECT [員工編號]
      ,[姓名]
      ,[職稱]
      ,[性別]
      ,[主管]
      ,[出生日期]
      ,[任用日期]
      ,[區域號碼]
      ,[地址]
      ,[分機號碼]
  FROM [CH11範例資料庫].[dbo].[員工]
 ORDER BY CASE [性別] when '' then [出生日期] else [任用日期] end




話說,
CASE 函數可以使用在排序條件上,這點有令我意外。
因為我還真不知道可以這樣子用呢!