2009/12/23

取出Resources中的Excel/Word檔來使用


這裡以Excel為例
如果我們需要一個Excel檔做範本
可以先把它拉到Resources中

image

然後在需要的時候才把它從Resources取出來使用
不過因為它沒辦法像圖檔可以直接操作
所以需要點小技巧
看程式碼

private void button1_Click(object sender, EventArgs e)
{
    byte[] sampleXls = Properties.Resources.sample; //取出Resources中的sample.xls檔
    FileStream outputExcelFile = new FileStream("C:\\sample.xls", FileMode.Create, FileAccess.Write); //存到C槽
    outputExcelFile.Write(sampleXls, 0, sampleXls.Length);
    outputExcelFile.Close();
}

 

把它存成一般的Excel檔案後
就可以對它做一般Excel的讀寫操作了

如果不喜歡固定存到某個位置讓別人知道
可以搭配Path類別幫你產生不重複的暫存檔

private void button2_Click(object sender, EventArgs e)
{
    string tmpFile = Path.GetTempFileName(); //取一個不重複的暫存檔名 (副檔名.tmp)
 
    byte[] sampleXls = Properties.Resources.sample;
    FileStream outputExcelFile = new FileStream(tmpFile, FileMode.Create, FileAccess.Write); //存到temp檔
    outputExcelFile.Write(sampleXls, 0, sampleXls.Length);
    outputExcelFile.Close();
 
    string xlsFile = Path.ChangeExtension(tmpFile, "xls"); //變更副檔名為.xls
    File.Move(tmpFile, xlsFile);
 
    MessageBox.Show("存到[" + xlsFile + "]成功");
}

 

[Code下載]

 

 

by sam319

2009/12/22

TextBox點三下全選


如果TextBox有開啟Multiline屬性或是TextBox內容是中英混打
此時點兩下是不會全選的
那麼可以考慮用上這個小技巧

利用一個TimeSpan變數
在Click事件中判斷200毫秒內是否連點過兩下滑鼠即可

以下是程式碼

DateTime doubleClickTimer = DateTime.Now; 
 
private void textBox1_DoubleClick(object sender, EventArgs e) 
{ 
    doubleClickTimer = DateTime.Now; //記下DoubleClick的時間 
} 
 
private void textBox1_Click(object sender, EventArgs e) 
{ 
    TimeSpan t = (TimeSpan)(DateTime.Now - doubleClickTimer); //DoubleClick後又點了一下, 計算時間差 
 
    if (t.Minutes == 0 && t.Seconds == 0 && t.Milliseconds <= 200) //如果小於200豪秒就全選 
        textBox1.SelectAll(); 
}

 

 

by sam319

模擬MSN的震動視窗


在一小段迴圈內亂數改變視窗左上角的位置就可以了
看程式碼

private void button1_Click(object sender, EventArgs e)
{
    Point now_p = this.Location;
    Random r = new Random();
    
    for (int i = 0; i < 50; i++)
    {
        Point new_p = new Point(now_p.X + r.Next(-10, 10), now_p.Y + r.Next(-10, 10)); //新的位置
        this.Location = new_p;
        System.Threading.Thread.Sleep(20);
        this.Location = now_p; //還原位置
    }
}

 

[Code下載]

 

 

by sam319

讓中文字長度等於2


由於客戶需要相容舊系統資料的關係
必須把中文字的長度算2
但在Unicode的架構下中文字的長度都是1

不過在C#下其實蠻簡單的
稍微轉個型就好
看程式碼

private void button1_Click(object sender, EventArgs e)
{
    //byte[] byteStr = Encoding.Default.GetBytes(textBox1.Text); //使用Default方法在非中文系統下可能會有問題
    byte[] byteStr = Encoding.GetEncoding("big5").GetBytes(textBox1.Text); //把string轉為byte 
    label1.Text = byteStr.Length.ToString(); //取byte的長度, 中文字就會算2碼了
}

 


[Code下載]

 

 

by sam319

用Path類別來處理目錄&檔案名稱


原來.Net有提供Path類別給我們處理目錄&檔案名稱
不要再傻傻的拿字串函數來處理了Tongue out

using System.IO;
 
private void Form1_Load(object sender, EventArgs e)
{
    string strPath = @"D:\Downloads\test.jpg";
 
    Path.GetFullPath(strPath); //取得完整路徑: "D:\Downloads\test.jpg"
    Path.GetPathRoot(strPath); //取得根目錄: "D:\"
    Path.GetDirectoryName(strPath); //取得目錄名: "D:\Downloads"
 
    Path.GetFileName(strPath); //取得檔名: "test.jpg"
    Path.GetFileNameWithoutExtension(strPath); //取得檔名(不含副檔名): "test"
    Path.GetExtension(strPath); //取得副檔名: ".jpg"
 
    Path.ChangeExtension(strPath, "txt"); //變更副檔名: "D:\Downloads\test.txt"
    Path.Combine(strPath, @"path1\path2"); //結合路徑: "D:\Downloads\test.jpg\path1\path2"
 
    Path.GetTempPath(); //取得系統暫存資料夾: "C:\Users\Sam\AppData\Local\Temp\"
    Path.GetTempFileName(); //建立並取得唯一的暫存檔完整路徑
    Path.GetRandomFileName(); //隨機傳回一個資料夾或檔案名稱
 
    char a = Path.DirectorySeparatorChar; //目錄分隔字元: "\"
    char b = Path.VolumeSeparatorChar; //磁碟分隔字元: ":"
    char c = Path.PathSeparator; //路徑分隔字元: ";"
 
    char[] d = Path.GetInvalidPathChars(); //取得系統不合法的目錄字元
    char[] e = Path.GetInvalidFileNameChars(); //取得系統不合法的檔案字元
}

 

 

by sam319

MaskedTextBox.SelectAll()無作用!?


當文字方塊取得焦點時
user都會要求文字方塊可以自動把文字全選起來

private void textBox1_Enter(object sender, EventArgs e)
{
    textBox1.SelectAll();
}

 

但遮罩文字方塊在設定遮罩後
上面的方法就沒有作用了


解決方法很簡單
只要再呼叫一次Focus方法
問題就解決了

private void maskedTextBox1_Enter(object sender, EventArgs e)
{
    maskedTextBox1.Focus();
    maskedTextBox1.SelectAll();
}

 

 

by sam319

使用DbParameter傳遞參數撈SQL Server資料速度異常的慢


這問題困擾了我很久
終於找到解決方法

註:以下測試所使用的查詢SQL Command與傳遞的參數是一致的, 測試資料只有100筆

使用DbParameter傳遞參數 (查詢耗費時間: 10分鐘Confused)

DbCommand p_cmd = DbConnection.CreateCommand();
p_cmd.CommandText = strSQL;
p_cmd.CommandType = CommandType.Text;
 
DbParameter p_dbParameter = new DbParameter();
p_dbParameter.DbType = DbType.String;
p_dbParameter.ParameterName = "@value";
p_dbParameter.Value = strValue;
p_dbParameter.Direction = ParameterDirection.Input;
p_cmd.Parameters.Add(p_dbParameter);

 

使用SqlParameter傳遞參數 (查詢耗費時間: 不到1秒)

DbCommand p_cmd = DbConnection.CreateCommand();
p_cmd.CommandText = strSQL;
p_cmd.CommandType = CommandType.Text;
 
SqlParameter p_dbParameter = new SqlParameter();
p_dbParameter.SqlDbType = SqlDbType.VarChar;
p_dbParameter.ParameterName = "@value";
p_dbParameter.Value = strValue;
p_dbParameter.Direction = ParameterDirection.Input;
p_cmd.Parameters.Add(p_dbParameter);

 

另外好奇心驅使下
又多試了DbParameter傳遞參數一次
不過稍微改變一下DbType的值 (查詢耗費時間: 不到1秒)

DbCommand p_cmd = DbConnection.CreateCommand();
p_cmd.CommandText = strSQL;
p_cmd.CommandType = CommandType.Text;
 
DbParameter p_dbParameter = new DbParameter();
p_dbParameter.DbType = DbType.AnsiString;
p_dbParameter.ParameterName = "@value";
p_dbParameter.Value = strValue;
p_dbParameter.Direction = ParameterDirection.Input;
p_cmd.Parameters.Add(p_dbParameter);

 

猜測是因為C#中使用Unicode值無法對應SQL Server中的Varchar值所造成的查詢緩慢(?)


另外這兩篇也可以參考一下

 

 

by sam319

2009/11/05

Windows Live Sync遠端同步不同電腦間的資料

系統環境:Windows 7, Windows Xp

我自己會寫一些小工具
有時候在公司寫一點
下班後就把Code Email給自己
回到家再繼續寫

但說實在這樣真的很不方便
要重複做著壓縮>寄信>收信>解壓縮的動作
有時候一兩個星期沒寫
就忘了哪邊才是最新的版本

Windows Live Sync剛好可以解決我的困擾
以下是個人覺得還不錯的幾個點:

  • 整合MSN帳號
  • 可以同步多台電腦間的資料
  • 資料放在微軟的Live空間
  • 可以加朋友的帳號, 一起同步資料
  • 可以設定同步的權限, 不怕資料外流

下載位置:https://sync.live.com/clientdownload.aspx
(要先登入MSN帳號才能下載)

安裝好後
到[開始功能表]>[所有程式]>[Windows Live]執行[Windows Live Sync]



登入MSN帳號



設定完成



假設我有一個資料夾[D:\_Work]要同步
先在公司電腦裝好Windows Live Sync並登入後
滑鼠點右下角小圖示選[Sync 網站]



開啟視窗後, 點[建立個人資料夾]



選擇要同步的電腦, 這裡我選公司的電腦[Sam]
(ps. 你的帳號有登入過的電腦, 這裡會全部列出來)



選擇要同步的資料夾, 這裡我選[D:\_Work]



再點選[在此同步處理資料夾]



點選[略過此步驟並完成], 公司電腦就設定好了
(ps. 如果你的帳號有加入其他電腦, 可以在此設定其他電腦要如何同步處理)



回到家後
也是先裝好Windows Live Sync並登入
點右下角小圖示會發現多了一個[_Work]的項目
這是在公司電腦設定要同步的資料夾
點它一下



然後會跳出一個設定視窗, 選擇要同步家裡電腦的哪一個資料夾
這邊我選擇[桌面\_WorkHome]



再點選[在此同步處理資料夾]



這邊我選[自動同步處理], 你可以視自己的需求來做調整
再按[完成], 這樣家裡的電腦也設定好同步資料了



我們來試試看比對一下
原本公司電腦的[_Work]裡只有一個[測試]文字檔
家裡電腦設定好同步後
[_WorkHome]也出現一樣的[測試]文字檔



然後我在公司電腦增加一個[測試2]文字檔
家裡電腦也同步下載了這個檔案



這次換在家裡電腦新增[測試3]文字檔
公司電腦也正確同步了



另外如果你同時在兩邊電腦編輯同一個檔案
他會幫你分開儲存



小巧方便
希望以後可以加上[版本控管]的功能

2009/11/03

讓軟體像服務一樣執行

系統環境:Windows 7

[執行]>[gpedit.msc]


[電腦設定]>[Windows設定]>[指令碼(啟動/關機)]>[啟動]


[新增]>[瀏覽], 選擇要執行的軟體即可


這樣軟體就可以像服務一樣
不需要登入系統就已經在背景執行了