2012年10月29日 星期一

指定動態組合頁面名稱的頁面顯示(C#)

最近有需求是需要動態組合頁面名稱,
指定頁面顯示。
程式碼如下:
string FormName = "NameSpaceName." + indexrow[0]["FrameItem"].ToString();
Form frm = ((Form)Assembly.GetExecutingAssembly().CreateInstance(FormName));
frm.Show();
FormName是NameSpaceName+"."+FormName,
須為一個完整的名稱,
利用Assembly.GetExecutingAssembly().CreateInstance,
找出剛湊出來的FormName,
轉成Form形式。
最後將此Form顯示即可。

2012年10月28日 星期日

計算機程式數字鍵盤設計(C#)

POS系統設計必須採用大圖形介面設計,輸入數量也需設計數字鍵盤讓使用者輸入,因此這個需求便產生。

但我又不想要一個button一個button去寫事件,這樣太累了。

若想要數字鍵盤,甚至是英文字母鍵盤,我想要將他們的click事件寫成通用的click事件要怎麼辦到呢?請繼續看下去。

首先必須從控制項Name命名下手,將那些要寫成同一個事件的控制項命名規則一致。

我下面將採用btnKey+數字(例:數字鍵盤1的Button.Name為btnKey1),接下來在Form_Load事件上定義那幾個Button的Click事件指向自己撰寫的Click事件。

   1: foreach (Control crl in this.Controls)            
   2: {                
   3:     if (crl.Name.Contains("btnKey"))                
   4:     {                    
   5:         crl.Click += new EventHandler(btnKey_Click);                
   6:     }            
   7: }

原理就是搜尋頁面中的Controls,若Control.Name包含btnKey則加入自寫的Click事件─btnKey_Click。下面是btnKey_Click事件:




   1: private void btnKey_Click(object sender, EventArgs e)        
   2: {                        
   3:     Button btn = (Button)sender;            
   4:     int start = txtInsert.SelectionStart;            
   5:     this.txtInsert.Text = txtInsert.Text.Insert(start, btn.Text);
   6:     txtInsert.SelectionStart = start + 1;       
   7:     txtInsert.Focus();        
   8: }


這裡面也有些需的技巧,此範例中接受輸入的文字方塊Textbox名稱為txtInsert。


因為文字方塊會有游標焦點位置,總不可能預設都判斷游標焦點位置在最後方,而直接寫txtInsert.Text += btn.Text吧。


因此需要動一點手腳,我將目前游標焦點位置用SelectionStart存至start變數,利用Textbox.Text.Insert的方式於指定位置內加入字串,最後將游標焦點位置調為start變數後一格。如此一來就可以達到數字鍵盤或者英文字母鍵盤了。


在這提供給大家一個不一樣的選擇,下回見。

2012年10月22日 星期一

條碼輸入與手動輸入判別─WinCE為例(C#)

使用PDA作業都需要使用條碼輸入
但有時沒有標籤可讀取亦可能人員手動輸入
此時判斷讀取條碼或手動輸入這個需求出現了
我們都知道讀取條碼採用模擬鍵盤事件輸入
表示只要將焦點(Focus)在文字方塊上
按下PDA上的[Scan]鍵就會讀取到的條碼會自動輸入到文字方塊中
然而最後它會輸入[Enter]鍵
因此只要在文字方塊的keypress事件中
在判斷式if(e.keychar == 13)底下寫你想要做的事情就可以了
寫到這,看不出來為何要判別讀取條碼或手動輸入

以下就是關鍵所在了
若你要第二次輸入時,將焦點放回文字方塊中
按下[Scan]鍵,會發現第二次讀取條碼會輸在原本已輸入的第一個條碼後面
它不會自動清除第一次輸入的條碼
總不可能教育訓練時,跟客戶講說要輸第二次時,須將第一次輸的條碼文字清除
因此你要判斷若是條碼輸入,必須將文字方塊中的文字清除

目前遇到的PDA讀取條碼API有兩種處理方式:
1.一個字一個字輸入進去
2.會存在自己的內存後,按下[Ctrl+V]
以上兩種最後都會按下[Enter]鍵

因應兩種處理方式,各有不同方法去處理:
1.針對第一種方法,一個字一個字輸進去的
需要以時間間隔去判斷條碼或手動輸入
以下為代碼:
//GetTickCountFunc
        [DllImport("Coredll.dll", EntryPoint = "GetTickCount")]
        private static extern int GetTickCount();
//條碼與手動輸入判斷變數
        private int i = 0;
        private string tmp = "";  //暫存字串                
        private bool ManualInput = false;
        private bool AutoInput = false;
        private int dstart = GetTickCount(); 

private void txtMTL_ID_KeyPress(object sender, KeyPressEventArgs e)
        {
int dend = GetTickCount();//結束時間
                string strtime = (dend - dstart).ToString();//"毫秒"

                if (Convert.ToInt32(strtime) < 100)//判斷時間間隔,間隔小於50豪秒,TextBox清空
                {
                    txtMTL_ID.Text = "";
                    AutoInput = true;
                    ManualInput = false;
                }
                else
                {
                    tmp = "";
                    ManualInput = true;
                    AutoInput = false;
                }
                dstart = dend;

                if (e.KeyChar > 32 && e.KeyChar <= 126)
                {
                    i++;
                    tmp += e.KeyChar.ToString();
                }

if (e.KeyChar == 13)
{
 i = 0;
 if (AutoInput == true)
 {
  txtMTL_ID.Text = tmp;
 }
 if (ManualInput == true)
 {
  txtMTL_ID.Text = txtMTL_ID.Text;
 }

 //這裡寫想要做的事情
 //這裡寫想要做的事情

//清除存放資訊
 AutoInput = false;
 ManualInput = false;
 tmp = "";

         }
}
判斷原理是因為條碼輸入比人快且平均
因此以每個字輸入的時間間隔(毫秒)去判別
GetTickCount()Func是因WinCE的關係才需要
一般winform只需用DateTime.Now後用TotalMilliSeconds去判斷就可以了
ManualInput=true即手動輸入,AutoInput=true則是條碼輸入
範例中的[<100]也因每一台PDA而不同,需要自己去抓準那個時間

2.第二種會按下[Ctrl+V]的方式解方法更為簡單且準確
以下為代碼:
if (e.KeyChar == 22)
   txtMTL_ID.Text = "";

if (e.KeyChar == 13)
{
  //這裡寫想要做的事情
  //這裡寫想要做的事情
}
非常之簡單,判斷有按下[Ctrl+V]鍵將文字方塊內的文字清除
基本上PDA上面的按鍵,人員不可能會去按到這種Ctrl+V這種案件組合
因此這個方法應該是滿準確的

以上解決方式或許會有些瑕疵
但已經是可以解決我目前手邊出現的問題
當然你也可以仿照微軟的設計風格
根本不用判斷是條碼或手動輸入
只要一按到文字方塊將文字全選
這樣條碼輸入亦可蓋掉之前的
再點一下亦可將游標移至想要的位置進行輸入
這個方法最常在Excel當中見到
將selectall()方法寫在Textbox的MouseClick事件中即可
因為WinCE的Textbox中無MouseClick事件
暫時無想到其他方式
因此才會選擇使用上面兩種方式
下回見



2012年10月11日 星期四

動態新增之button.text換行(C#)

最近著手開發TouchPanel系統
系統上的每個介面的流程控制均設置於Server上
為畫面美觀,有些按鈕之顯示文字須兩行顯示
查了一下網路C#之換行必須用(Char)13及(Char)10去實現
因此Server之config上顯示文字內容欄位須訂定一個符號表示換行
欄位內容:出勤#登入
名詞解釋:
1.drbuttonlist為Datarow,button設置資料
2.drbuttonlist[i]["Name"]為顯示文字內容欄位
3.特殊符號使用"#"
4.cntr為Form上之Control
if (drbuttonlist[i]["Name"].ToString().Contains("#"))
{                            
 string[] textarr = drbuttonlist[i]["Name"].ToString().Split('#');
 for (int j = 0; j < textarr.Length; j++)
 {
  //利用(Char)13及(Char)10換行
  cntr.Text += textarr[j] + Convert.ToChar(13) + Convert.ToChar(10);
 }
}
else
{
 cntr.Text = drbuttonlist[i]["Name"].ToString();//指定其text
}
參考網址:http://www.dotblogs.com.tw/a-law/archive/2009/11/10/11508.aspx