青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 17,  comments - 2,  trackbacks - 0

利用C#制作一個仿IE地址欄的文本框

利用IE上網時,只要在地址欄中輸入幾個字母,與這幾個字母模糊匹配的地址就會自動顯示出來供用戶選擇(如下圖),用戶通過按鍵盤上的上、下箭頭在已有選項中遍歷,找到自己需要的選項后,按回車鍵進行選擇,也可以直接用鼠標進行操作,非常方便,我們在程序中也可以利用這一功能,實現自動提示,方便用戶輸入,下面就以一個實際例子介紹我在工作中是如何實現的。


從上圖中可以看出,最佳的辦法似乎就是繼承
ComboBox寫一個控件,在TextChanged事件中,根據內容變化決定是否應拉下提示框,以及該提示什么內容,在實際工作中我們發現,ComboBox非常難以控制,如修改了SelectedIndex屬性后,會自動產生TextChanged事件,造成死循環等等,雖然可以添加其他一些變量來標記該文本改變是用戶引起的還是由程序引起的以進行區別對待處理,但效果始終不理想,經過反復試驗,最后選擇了文本框+列表框的方式,并做成控件庫供其他程序調用,效果很理想,其中,文本框接收用戶輸入,列表框提供選項讓用戶選擇。

新建一個普通的windows應用程序用來測試,不妨取名為Test吧,然后單擊菜單“文件”→“添加項目”→“新建項目(N)”,從彈出來的對話框選擇“windows控件庫”,將該項目和Test項目放在同一個文件夾中,不妨取名為“TextBoxExt”,該項目是本文的重點。

在“解決方案資源管理器” 中,右鍵單擊“TextBoxExt”項目,從彈出的菜單中選擇“屬性”,會彈出屬性配置對話框,在左上角的“配置(C)”中選擇“所有配置”,設置輸出路徑為“..\output”,注意,該輸入有點特殊,兩個小數點+反斜杠+output,意思是當前文件夾上一層的ouput文件夾(從VC過來的朋友可能比較熟悉這種方式),如下圖:


編譯一下,在“我的電腦”或“資源管理器”中我們可以就可以看到與
TextBoxExt文件夾同一級自動創建了一個output文件夾,輸出的TextboxExt.dll乖乖地躺在這里:


再來配置一下依賴性,點菜單“項目”→“設置依賴性(
D)”,設置項目Test取決于“TextBoxExt”,至此,開發環境配置完畢。

在“解決方案資源管理器” 中雙擊“UserControl1.cs”文件,再切換到代碼窗口中。為便于引用,我們將命名空間“namespace TextBoxExt”改為“namespace Tools”,由于本控件繼承于文本框,因此,將代碼

     public class UserControl1 : System.Windows.Forms.UserControl

     {

         public UserControl1()

         {

              InitializeComponent();

         }

修改為:

     public class TextBoxExt : System.Windows.Forms.TextBox

     {

         private System.ComponentModel.Container components = null;

         public TextBoxExt()

         {

    }

也就是說將命名空間改為Tools,將類名改為TextBoxExt,讓該類繼承于System.Windows.Forms.TextBox,并修改相應的構造函數。編譯成功后,在“解決方案資源管理器中”雙擊項目“Test”的“Form1.cs”來切換到窗體設計,在“工具箱”窗口中切換到“我的用戶控件”選項中,在空白處單擊右鍵,從彈出的菜單中選擇“添加/移出項”,接下來會彈出一個對話框,點“瀏覽”按鈕,找到剛才生成的控件庫,如下圖:


最后點“確定”按鈕,在“工具箱”的“我的控件庫”中就多了一個“
TextBoxExt”控件,同操作普通文本框控件一樣,在窗體上添加幾個該自定義控件??梢钥闯觯撐谋究蚝推綍r使用的文本框目前完全一樣。

切換到UserControl1.cs代碼設計窗口中,添加一個列表框變量,用于顯示提示:

         private System.Windows.Forms.ListBox m_lstShowChoice=null;

添加一段代碼,用于響應列表框鼠標的MouseUp事件,也就是用戶通過單擊列表框進行選擇:

     private void lstBox_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)

         {

              ListBox box=(ListBox)sender;

              if((box.SelectedIndex>-1) && !this.ReadOnly)

              {

                   this.Text=box.SelectedItem.ToString();

                   //選擇后文本框失去了焦點,這里移回來

                   this.Focus();

              }

         }

添加鼠標在列表框中移動的事件,當用戶在列表框中移動鼠標時,根據鼠標位置,自動設置列表框當前項。

         private void lstBox_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)

         {

              ListBox box=(ListBox)sender;

              Point pt = new Point(e.X,e.Y);

              int n=box.IndexFromPoint(pt);

              if(n>=0)

                   box.SelectedIndex=n;

    }

為了美觀,可以設置列表框的前景、背景、邊框風格等,按常規,我們可以設置一個public變量來供程序調用,但在程序設計時無法通過屬性窗口直接修改,不方便,通過“性質”來引用可以解決,下面的代碼是設置列表框的背景,比較好理解:

         #region 設置提示框的背景

         private Color m_lstForColor=System.Drawing.SystemColors.InfoText;

         /// <summary>

         /// 設置/獲取提示的背景色

         /// </summary>

         public Color PromptBackColor

         {

              get

              {

                   return m_lstBackColor;

              }

              set

              {

                   m_lstBackColor=value;

                   //lstPrompt的創建見下面的代碼

                   ListBox box=this.lstPrompt;

                   if(box!=null)

                       box.BackColor=m_lstBackColor;

              }

         }

         #endregion

設置前景、邊框的方法完全一樣,不再贅述,經過這樣處理,我們在程序設計時就可以直接在“屬性”窗口中指定了,如下圖:

 

接下來,也是通過“性質”來返回當前列表框,如果沒有則創建:

         private System.Windows.Forms.ListBox lstPrompt

         {

              get

              {

                   //如果沒有列表用于顯示提示的列表框,則創建一個

                   if((m_lstShowChoice==null) && this.Parent!=null)

                   {

                       m_lstShowChoice=new ListBox();

                       m_lstShowChoice.Visible=false;

                       m_lstShowChoice.Left=this.Left;

                       m_lstShowChoice.Top=this.Bottom;

                       m_lstShowChoice.Width=this.Width;

                       m_lstShowChoice.TabStop=false;

                       m_lstShowChoice.Sorted=true;

                       m_lstShowChoice.ForeColor=this.m_lstForColor; //前景

                       m_lstShowChoice.BackColor=this.m_lstBackColor; //背景(參見m_lstForColor的創建

                       m_lstShowChoice.BorderStyle=this.m_lstBordrStyle; //邊框,背景(參見m_lstForColor的創建

 

                       //如果提示框過低,則顯示到上面

                       if(m_lstShowChoice.Bottom>this.Parent.Height)

                            m_lstShowChoice.Top=this.Top-m_lstShowChoice.Height+8;

                       m_lstShowChoice.MouseUp += new System.Windows.Forms.MouseEventHandler(this.lstBox_MouseUp);

                       m_lstShowChoice.MouseMove+= new System.Windows.Forms.MouseEventHandler(this.lstBox_MouseMove);

                       this.Parent.Controls.Add(m_lstShowChoice);

                       this.Parent.ResumeLayout(false);

                       m_lstShowChoice.BringToFront();

                   }

                   return m_lstShowChoice;

              }

         }

 

創建一個ArrayList用于存放全部可供選擇的項目:

         private ArrayList m_ForChoice=new ArrayList();

         public ArrayList ChoiceArray

         {

              get

              {

                   return m_ForChoice;

              }

              set

              {

                   m_ForChoice=(ArrayList)(value.Clone());

                   ListBox box=this.lstPrompt;

                   if(box!=null )

                   {

                       box.Items.Clear();

                       box.Items.AddRange(m_ForChoice.ToArray());

                   }

              }

         }

用戶在輸入時,經常喜歡加空格,如兩個字的姓名“張三”,用戶喜歡輸成“張  三”,雖然可以和三個字的姓名對齊,比較美觀,但對程序中姓名檢索等非常不便,因為你還要判斷中間是否有空格,有多少空格等,為此,我們設置一個“性質”來決定是否允許用戶輸入空格。

         private bool m_AllowSpace=false;

         public bool AllowSpace

         {

              get

              {

                   return m_AllowSpace;

              }

              set

              {

                   m_AllowSpace=value;

              }

         }

在輸入過程中,有些內容是只能選擇不能輸入的,就象我們將ComboBoxDropDownStyle設置為DropDownList一樣,但為了方便用戶,我們允許用戶輸入,光標離開本文本框時,進行檢查,判斷用戶輸入的內容是否在可選項內,如果不在,則清空用戶輸入,因此,添加下面變量:

         private bool m_bChoiceOnly=false;

         public bool ChoicOnly

         {

              get

              {

                   return this.m_bChoiceOnly;

              }

              set

              {

                   this.m_bChoiceOnly=value;

              }

         }

按常理,我們應該在響應文本框的TextChange事件中根據文本變化來決定是否顯示列表框,以及列表框中該出現哪些可選項,但同ComboBox一樣,文本改變事件可能有多種事件連帶引發(如程序使用了TextBox1.Text=”abc”之類),難以控制,我們這里響應KeyUp事件,在通過KeyUpKeyDown的配合來完成,就避開了上述問題。本文開始處我們說過,可以通過鍵盤上的“↑”和“↓”在可選項中遍歷,而文本框默認上下箭頭也用來移動當前鍵盤光標,因此,我們在KeyDown中記下當前光標位置,在KeyUp中恢復,故聲明一個變量m_nOldPos來記錄按鍵前鍵盤光標位置,在實際工作中我們發現,部分輸入法存在BUG,用戶鍵入一個鍵后,產生了一個KeyDown后產生兩個KeyUp事件,為此,通過一個變量bKeyDown來記錄鍵是否按下,供KeyUp正確判斷,文本改變發生在KeyDownKeyUp之間,因此,在KeyDown中必須記錄當前文本,在KeyUp中判斷文本是否改變,根據上述分析,我們添加文本框的KeyDown事件響應代碼:

         private int m_nOldPos=0;

         private bool bKeyDown=false;

         private string m_strOldText="";

         private void TextBoxExt_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)

         {

              m_nOldPos=this.SelectionStart;

              bKeyDown=true;

              m_strOldText=this.Text;

    }

創建一個函數,用來根據文本框當前內容,從可供選擇的m_ForChoice數組中篩選出模糊匹配的選項,添加到列表框中:

         private void FillPrompt(string p_strText)

         {

              ListBox box=this.lstPrompt;

              if(box!=null)

              {

                   box.Items.Clear();

                   if(p_strText.Length==0)//沒有內容,顯示全部

                       box.Items.AddRange(this.m_ForChoice.ToArray());

                   else

                   {

                       foreach(string s in this.m_ForChoice)

                       {

                            if(s.ToLower().IndexOf(p_strText.ToLower())>=0)

                                 box.Items.Add(s);

                       }

                   }

              }

         }

 

添加文本框的KeyUp事件響應代碼:

                   private void TextBoxExt_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)

         {

              if(!bKeyDown)//忽略掉多余的KeyUp事件

                   return;

              bKeyDown=false;

              ListBox box=this.lstPrompt;

              switch(e.KeyCode)

              {

                       //通過上下箭頭在待選框中移動

                   case System.Windows.Forms.Keys.Up:

                   case System.Windows.Forms.Keys.Down:

                       if((box!=null) && !this.Multiline)//多行文本通過上下箭頭在兩行之間移動

                       {

                                 if((e.KeyCode==System.Windows.Forms.Keys.Up) && (box.SelectedIndex>-1))//↑

                                     box.SelectedIndex--;

                                 else if((e.KeyCode==System.Windows.Forms.Keys.Down) && (box.SelectedIndex<box.Items.Count-1))//↑

                                     box.SelectedIndex++;

                            //上下箭頭不能移動當前光標,因此,還原原來位置

                            this.SelectionStart=m_nOldPos;

                            //顯示提示框

                            if(!box.Visible)           

                            {

                                 if(box.Width!=this.Width)

                                     box.Width=this.Width;

                                 box.Visible=true;     

                            }

                       }

                       break;

                   case System.Windows.Forms.Keys.Escape://ESC隱藏提示

                       if((box!=null) && box.Visible)

                            box.Hide();

                       break;

                   case System.Windows.Forms.Keys.Return://回車選擇一個或跳到下一控件

 

                       if((box==null) || this.Multiline)

                            break;

                       //沒有顯示提示框時,移動到下一控件

                       if( !box.Visible)

                       {

                            SendKeys.Send("{TAB}");

                       }

                       else //有提示,關閉提示

                       {

                            if(box.SelectedIndex>-1)//有選擇,使用當前選擇的內容

                                 this.Text=box.SelectedItem.ToString();

                            this.SelectionStart=this.Text.Length;

                            this.SelectAll();

                            box.Hide();

                       }

                       break;

                   default://判斷文本是否改變

                       string strText=this.Text;

                        //不允許產生空格,去掉文本中的空格

                       if(!m_AllowSpace)

                            strText=this.Text.Replace(" ","");

 

                       int nStart=this.SelectionStart;

                       if(strText!=m_strOldText)//文本有改變

                       {

                            //設置當前文本和鍵盤光標位置

                            this.Text=strText;

                            if(nStart>this.Text.Length)

                                 nStart=this.Text.Length;

                            this.SelectionStart=nStart;

                            //修改可供選擇的內容,并顯示供選擇的列表框

                            if(box!=null)

                            {

                                 this.FillPrompt(strText);

                                 if(!box.Visible)

                                 {

                                     if(box.Width!=this.Width)

                                          box.Width=this.Width;

                                     box.Visible=true;     

                                 }                          

                            }

                       }

 

                       break;

              }

         }

當文本框失去鍵盤光標后,必須隱藏提示,對于只選型文本框,還要判斷用戶輸入是否在可選項中:

         private void TextBoxExt_Leave(object sender, System.EventArgs e)

         {

              //對于只選字段,必須輸入同待選相匹配的值

              if(this.m_bChoiceOnly)

              {

                   int nIndex=this.ChoiceArray.IndexOf(this.Text);

                   if(nIndex<0)

                       this.Text="";

              }

              //失去焦點后,必須隱藏提示

              ListBox box=this.lstPrompt;

              if(box!=null)

                   box.Visible=false;

         }

IE地址欄中,右邊有一個“↓”,我們可以點該箭頭來打開提示框,本例中沒有增加該功能不能不說是一個缺陷,這里,我們用雙擊文本框的辦法來代替(也可以通過在右邊加一個按鈕模擬下拉箭頭,制作方法見筆者另一篇文章《在C#中制作組合控件》):

         private void TextBoxExt_DoubleClick(object sender, System.EventArgs e)

         {

              if(this.ReadOnly)

                   return;

              ListBox box=this.lstPrompt;

              if((box!=null) && (!box.Visible))

              {

                   if(box.Width!=this.Width)

                       box.Width=this.Width;

                   box.Visible=true;     

              }

         }

切換到Test項目Form1的代碼窗口中,在前面添加一個引用:using Tools;并添加Form1的Load事件響應代碼:

         private void Form1_Load(object sender, System.EventArgs e)

         {

              //創建一個數組,用于填充本控件的可選項

              ArrayList arr=new ArrayList();

              arr.Add("aaabbbcccddd");

              arr.Add("bbbcccdddeee");

              arr.Add("cccdddeeefff");

              arr.Add("dddeeefffggg");

              //遍歷所有控件,篩選出增強型文本框控件進行可選項賦值

              foreach(Control ctl in this.Controls)

              {

                   TextBoxExt txtbox=ctl as TextBoxExt;

                   if(txtbox==null)

                       continue;

                   txtbox.ChoiceArray=arr;

              }

    }

運行一下,當在文本框中輸入一些字母后,文本框會自動匹配,去掉不符合要求的文本,同時,通過按上下箭頭、回車鍵、ESC鍵、雙擊等可以檢驗效果,運行結果如下圖所示:


至此,類似
IE地址欄的控件就開發完成了,在工作中可以擴充該控件,如在控件中增加一個“代表字段”的性質,程序設計時在屬性窗口中指定其所代表的字段(如“姓名”),在上面Form1Load事件的“foreach(Control ctl in this.Controls)”中,根據該字段自動從數據庫中搜索所有姓名,并填充到文本框的可選項中供用戶選擇,這一樣一來,就沒有必要在代碼中人為指定某文本框同什么字段綁定,大大減化了工作,連文本框的name屬性都可不指定了,且通用性強,以上只是一個思路和骨干代碼,實際使用的控件要強大的多,你可以根據自己工作情況不斷完善和補充,本例所有代碼請到我的ftp://202.107.251.26的“茍安廷”文件夾中下載,文件名為“文本框擴展.rar”。

posted on 2008-10-30 14:41 BeyondCN 閱讀(551) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美二区乱c少妇| 欧美 日韩 国产在线| 久久久久国产精品午夜一区| 亚洲永久网站| 亚洲视频综合| 美日韩免费视频| 免费不卡在线视频| 国产精品午夜在线观看| 一本色道久久88综合日韩精品| 亚洲二区在线| 欧美在线播放视频| 久久久青草婷婷精品综合日韩| 久久精品视频在线| 国产女主播一区二区三区| 中文一区二区在线观看| 亚洲一级在线| 国产精品私房写真福利视频| 怡红院精品视频| 欧美在线视频观看| 久久99在线观看| 在线播放日韩专区| 欧美精品在线观看91| 亚洲人成在线观看| 亚洲精品日韩在线观看| 欧美日韩成人一区| 亚洲午夜免费福利视频| 久久日韩粉嫩一区二区三区| 国产伊人精品| 欧美激情在线有限公司| 欧美一区二区三区视频在线 | 日韩视频在线免费| 欧美日本中文| 欧美一级淫片aaaaaaa视频| 欧美激情一区二区三区在线视频观看| 激情综合久久| 国产一区二区成人| 欧美人牲a欧美精品| 久久夜色精品国产欧美乱| 亚洲欧美不卡| 亚洲乱码国产乱码精品精天堂| 久久天堂av综合合色| 性久久久久久久久久久久| 亚洲国产精品久久久久| 狠狠色噜噜狠狠狠狠色吗综合| 国产精品美腿一区在线看| 久久久噜噜噜久噜久久| 中文国产亚洲喷潮| 亚洲毛片一区二区| 1000部精品久久久久久久久 | 欧美11—12娇小xxxx| 久久久人成影片一区二区三区| 中日韩高清电影网| 欧美一区永久视频免费观看| 亚洲免费在线看| 久久精品在线| 亚洲片在线资源| 亚洲天堂成人| 亚洲国产cao| 这里只有精品电影| 欧美在线综合视频| 久久亚洲影音av资源网| 91久久精品国产91久久性色| 最新国产拍偷乱拍精品| 亚洲伊人伊色伊影伊综合网| 久久精品亚洲精品国产欧美kt∨| 久久女同互慰一区二区三区| 免费国产自线拍一欧美视频| 欧美日韩午夜在线| 伊人狠狠色丁香综合尤物| 亚洲激情综合| 免费日韩成人| 欧美一区二区日韩一区二区| 久久精品国产欧美激情| 国产精品久久二区二区| 亚洲日本电影| 亚洲男人第一av网站| 91久久午夜| 蜜桃久久av| 一本色道久久综合狠狠躁的推荐| 在线视频你懂得一区二区三区| 久久久女女女女999久久| 国产精品美女一区二区| 亚洲女人av| 亚洲欧美日韩精品一区二区| 免费成人高清| 亚洲久久成人| 亚洲国产日韩美| 久久一区二区三区av| 伊人久久av导航| 久久乐国产精品| 亚洲午夜高清视频| 欧美午夜片在线免费观看| 一级成人国产| 亚洲一区激情| 国产精品乱看| 久久夜色精品亚洲噜噜国产mv| 欧美一区二区在线免费观看| 国产一区二区精品久久99| 免费亚洲一区二区| 欧美三区在线| 亚洲欧美日韩视频一区| 久久久国产午夜精品| 日韩视频免费| 久久国产精品毛片| 亚洲精品国久久99热| 亚洲欧美日韩国产另类专区| 亚洲第一精品在线| 亚洲天堂男人| 亚洲国产婷婷| 久久精品久久99精品久久| 一区二区三区精品视频| 欧美亚洲自偷自偷| 一区二区三区色| 午夜亚洲激情| 久久久久免费| 欧美亚洲视频在线观看| 蜜臀a∨国产成人精品| 欧美一区二区免费视频| 欧美精品一区二区三区四区 | 国产精品久久久久久久久久久久 | 欧美一区二区视频在线| 亚洲男人av电影| 国产精品一卡| 欧美亚洲综合久久| 久久国产精品色婷婷| 国产亚洲综合性久久久影院| 日韩午夜中文字幕| 在线日韩中文| 欧美va亚洲va国产综合| 免费成人在线视频网站| 国产一区亚洲| 久久免费黄色| 亚洲国产mv| 日韩小视频在线观看专区| 欧美凹凸一区二区三区视频| 欧美.日韩.国产.一区.二区| 日韩小视频在线观看| 国产精品视频久久一区| 亚洲欧美综合国产精品一区| 久久综合导航| 一区二区三区欧美在线| 国产精品久久久久天堂| 久久久蜜桃精品| 亚洲午夜在线| 亚洲精品视频免费| 性欧美精品高清| 亚洲国产欧美一区二区三区久久 | 在线观看国产欧美| 欧美视频二区36p| 久久久久高清| 亚洲一区免费观看| 亚洲激情另类| 欧美超级免费视 在线| 亚洲免费视频观看| 一区二区三区四区国产精品| 国一区二区在线观看| 国产精品亚洲一区| 欧美日韩在线视频一区| 麻豆精品视频在线| 快she精品国产999| 久久嫩草精品久久久精品一| 性欧美激情精品| 久久久久成人精品免费播放动漫| 欧美在线亚洲综合一区| 亚洲午夜精品久久久久久浪潮| 亚洲高清在线视频| 亚洲国产精品欧美一二99| 最新高清无码专区| 亚洲伦理久久| 亚洲午夜久久久| 欧美呦呦网站| 麻豆精品传媒视频| 欧美日韩极品在线观看一区| 欧美午夜一区二区福利视频| 国产日韩欧美二区| 亚洲精品欧美激情| 性做久久久久久| 久久久www成人免费毛片麻豆| 欧美黄色aaaa| 午夜精品久久久久| 欧美成人黑人xx视频免费观看| 欧美.www| 国产精品手机在线| 亚洲激情专区| 久久精品人人做人人综合| 欧美成黄导航| 91久久精品视频| 国语对白精品一区二区| 亚洲精品久久久久久一区二区| 亚洲男人的天堂在线aⅴ视频| 亚洲欧美一区二区三区极速播放 | 欧美日韩大片| 亚洲国产日韩在线一区模特| 午夜精彩国产免费不卡不顿大片| 一区二区三区免费在线观看| 亚洲高清免费视频| 美女精品国产| 亚洲电影欧美电影有声小说| 久久精品国产2020观看福利| 亚洲影视综合|