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

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”控件,同操作普通文本框控件一樣,在窗體上添加幾個該自定義控件??梢钥闯?,該文本框和平時使用的文本框目前完全一樣。

切換到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>
            欧美视频三区在线播放| 亚洲免费在线观看| 欧美精品在线免费播放| 欧美一区永久视频免费观看| 一区二区三区欧美在线| 99av国产精品欲麻豆| 欧美成人免费观看| 久久久久久久性| 欧美xxx成人| 免费视频久久| 亚洲福利在线看| 亚洲国产日韩在线| 亚洲精品日韩精品| 日韩视频在线播放| 亚洲在线视频网站| 国产精品久久999| 欧美不卡福利| 99精品国产福利在线观看免费| 夜夜嗨av一区二区三区免费区| 亚洲欧美在线一区二区| 久久久免费精品| 欧美国产在线电影| 国产麻豆91精品| 欧美日韩一二三区| 在线观看国产精品网站| 日韩视频永久免费| 亚洲一区精品视频| 久久精品国产精品亚洲综合| 蜜臀91精品一区二区三区| 日韩写真在线| 久久综合九色欧美综合狠狠| 欧美视频一区二区三区四区| 亚洲黄色在线看| 久久婷婷亚洲| 香蕉久久精品日日躁夜夜躁| 欧美另类在线观看| 在线播放日韩欧美| 欧美影院视频| 一区二区电影免费在线观看| 久久天天躁狠狠躁夜夜av| 国产精品一区二区女厕厕| 亚洲免费观看视频| 美女视频黄a大片欧美| 午夜电影亚洲| 国产精品一区二区久久| 亚洲一级黄色片| 日韩视频久久| 欧美日韩国产综合一区二区 | 久久久人成影片一区二区三区| 欧美日韩免费一区二区三区| 亚洲精品一区中文| 美女爽到呻吟久久久久| 欧美一区网站| 国产亚洲亚洲| 久久嫩草精品久久久精品一| 性欧美1819性猛交| 国产一二精品视频| 国产一区二区三区高清| 亚洲一区在线观看视频| 日韩小视频在线观看专区| 欧美日韩国产一中文字不卡| 亚洲三级影片| 91久久精品国产91性色| 老司机亚洲精品| 亚洲国产天堂久久综合| 欧美华人在线视频| 欧美高清自拍一区| 亚洲色图制服丝袜| 99精品热6080yy久久| 欧美日韩不卡一区| 亚洲精品欧美一区二区三区| 欧美黄色片免费观看| 免费一级欧美片在线播放| 亚洲欧洲一区二区在线播放| 亚洲欧洲一区| 欧美日韩国产美| 亚洲在线观看| 久久精品视频在线观看| **欧美日韩vr在线| 亚洲看片免费| 国产欧美日韩亚洲| 欧美成人中文字幕| 一区二区三区欧美亚洲| 欧美主播一区二区三区美女 久久精品人 | 欧美在线视频全部完| 久久精品国产一区二区电影| 亚洲激情视频在线| aa亚洲婷婷| 国产日韩欧美电影在线观看| 欧美国产日韩一二三区| 国产精品久久久久久模特| 麻豆精品在线视频| 欧美视频1区| 嫩草国产精品入口| 国产精品第13页| 亚洲成色www8888| 国产精品中文在线| 欧美成人黑人xx视频免费观看| 欧美日韩视频在线| 欧美一二三视频| 午夜激情一区| 亚洲精品色婷婷福利天堂| 亚洲永久视频| 在线综合欧美| 欧美国产日韩在线观看| 欧美影院久久久| 欧美日韩一区综合| 欧美激情一区二区三区不卡| 国产精品素人视频| 亚洲成在线观看| 国内精品视频一区| 亚洲影院高清在线| 亚洲午夜精品一区二区| 欧美韩国日本综合| 男人天堂欧美日韩| 一区二区三区在线视频观看| 亚洲综合视频网| 亚洲字幕一区二区| 欧美日韩成人一区| 亚洲精品国产精品乱码不99 | 亚洲二区在线观看| 国产午夜精品美女毛片视频| 亚洲激情午夜| 亚洲精品国产欧美| 久久理论片午夜琪琪电影网| 午夜精品一区二区三区在线播放| 欧美国产日本高清在线| 噜噜噜久久亚洲精品国产品小说| 国产精品高潮呻吟久久av无限 | 另类尿喷潮videofree | 国内成+人亚洲+欧美+综合在线| 亚洲人成网站精品片在线观看| 在线免费观看日韩欧美| 亚洲国产精品va在线看黑人| 欧美在线免费观看| 欧美一区二区三区四区在线| 国产精品v亚洲精品v日韩精品| 亚洲黄色一区二区三区| 亚洲国产清纯| 欧美激情视频网站| 蜜桃av久久久亚洲精品| 国产亚洲a∨片在线观看| 亚洲免费视频一区二区| 亚洲欧美资源在线| 国产亚洲一区精品| 久久精品欧美| 蜜臀久久久99精品久久久久久| 狠狠色伊人亚洲综合成人| 久久青草欧美一区二区三区| 免费国产一区二区| 亚洲三级毛片| 欧美视频日韩视频| 亚洲欧美精品伊人久久| 久久色中文字幕| 亚洲国产婷婷| 欧美日韩一区二区国产| 亚洲一级高清| 欧美成人午夜激情视频| 99伊人成综合| 国产日韩欧美在线观看| 久久夜色精品国产| 日韩一本二本av| 久久久久在线| 日韩亚洲在线| 国产欧美日韩免费| 美日韩免费视频| 亚洲伊人伊色伊影伊综合网| 男人插女人欧美| 亚洲欧美国产不卡| 亚洲大胆视频| 国产精品久久久久久超碰 | 欧美丰满高潮xxxx喷水动漫| 亚洲精品乱码久久久久久黑人 | 国产欧美一区二区精品秋霞影院| 久久九九热re6这里有精品| 玖玖视频精品| 亚洲女人小视频在线观看| 一区免费观看视频| 国产精品成人一区| 葵司免费一区二区三区四区五区| 亚洲免费av网站| 久久午夜电影网| 午夜伦欧美伦电影理论片| 国产深夜精品| 欧美日韩国内自拍| 久久综合精品一区| 欧美一区二区三区另类| 99精品欧美一区二区蜜桃免费| 美女视频黄 久久| 性做久久久久久| 亚洲精品永久免费精品| 狠狠操狠狠色综合网| 亚洲精品免费网站| 先锋影音一区二区三区| 99亚洲一区二区| 亚洲精选久久| 亚洲美女中文字幕| 亚洲国产三级网| 欧美二区不卡| 欧美不卡视频一区发布|