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