ﺑﺴﻢ اﷲ اﻟﺮﺣﻤﻦ اﻟﺮﺣﻴﻢ
آﻣﻮزش وﻳﮋوال 2005 C# ﮔﺮدآوري: ﺳﻴﺪ ﻣﺤﻤﺪ ﻫﺎﺷﻤﻴﺎن
١
اﻳﻦ ﻛﺘﺎب آﻣﻮزﺷﻲ ﻳﻚ ﻛﺘﺎب راﻳﮕﺎن اﺳﺖ و ﻣﻲ ﺗﻮان ﻣﻄﺎﻟﺐ ﻣﻮﺟﻮد در آن را ﺑﺎ/ﺑﺪون اﺟﺎزه ﮔﺮدآورﻧﺪه ﺗﻮزﻳﻊ ﻛﺮده و ﻳﺎ ﺗﻐﻴﻴﺮ داد .اﻳﻦ ﻛﺘﺎب ﺑﻪ اﻳﻦ اﻣﻴﺪ ﮔﺮدآوري ﺷﺪه اﺳﺖ ﻛﻪ ﺑﺘﻮاﻧﺪ در ارﺗﻘﺎي ﺳﻄﺢ ﻋﻠﻤﻲ دوﺳﺘﺎن ﻣﻮﺛﺮ واﻗﻊ ﺷﻮد ،اﻣﺎ ﻫﻴﭻ ﺗﻀﻤﻴﻨﻲ در ﻣﻮرد آن و ﻳﺎ در ﻣﻮرد ﻣﻨﺎﺳﺐ ﺑﺪون ﻣﻄﺎﻟﺐ ﻣﻮﺟﻮد ﺑﺮاي اﻫﺪاف ﺧﺎص وﺟﻮد ﻧﺪارد. از ﺧﻮاﻧﻨﺪه ﻣﺤﺘﺮم ﺗﻘﺎﺿﺎ ﻣﻲ ﺷﻮد ﺑﺎ ارﺳﺎل ﻧﻈﺮات و ﭘﻴﺸﻨﻬﺎدات ﺧﻮد در ﻣﻮرد اﻳﻦ ﻛﺘﺎب و ﻳﺎ اﺷﻜﺎﻻت ﻣﻮﺟﻮد در ﻣﺤﺘﻮي ﻳﺎ ﻣﺘﻦ آن ﺑﻪ آدرس
[email protected]در ﺑﻬﺒﻮد اﻳﻦ ﻛﺘﺎب ﺳﻬﻴﻢ ﺷﻮد. ﺑﺎ ﺗﺸﻜﺮ، ﺳﻴﺪ ﻣﺤﻤﺪ ﻫﺎﺷﻤﻴﺎن ﺗﺎﺑﺴﺘﺎن 1385
٢
ﻓﺼﻞ اول :ﺑﻪ وﻳﮋوال 2005 C#ﺧﻮش آﻣﺪﻳﺪ
18
ﻧﺼﺐ وﻳﮋوال 18 ............................................................................................................ :2005 C# ﻣﺤﻴﻂ ﺗﻮﺳﻌﻪ وﻳﮋوال 23 .................................................................................................... :2005 C# ﺻﻔﺤﻪ 23 ...................................................................................................... :Profile Setup ﻣﻨﻮ24 ............................................................................................................................... : ﻧﻮار اﺑﺰارﻫﺎ26 ........................................................................................................................ : اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺳﺎده27 ............................................................................................................... : ﭘﻨﺠﺮه ﻫﺎ در IDEوﻳﮋوال اﺳﺘﻮدﻳﻮ 28 ...................................................................................... :2005 اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺳﺎﺧﺘﻦ ﭘﺮوژه 29 .................................................................................... Hello User ﺟﻌﺒﻪ اﺑﺰار31 ........................................................................................................................ : ﻧﺸﺎﻧﻪ ﮔﺬاري ﻣﺠﺎرﺳﺘﺎﻧﻲ ﺗﻐﻴﻴﺮ ﻳﺎﻓﺘﻪ35 ................................................................................................ : وﻳﺮاﻳﺸﮕﺮ ﻛﺪ36 ..................................................................................................................... : اﺳﺘﻔﺎده از ﺳﻴﺴﺘﻢ راﻫﻨﻤﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ41 ......................................................................................... : ﺧﻼﺻﻪ43 ............................................................................................................................... : ﺗﻤﺮﻳﻦ43 ................................................................................................................................ :
ﻓﺼﻞ دوم :ﭼﺎرﭼﻮب .NETو ارﺗﺒﺎط آن ﺑﺎ 44 .................................................... C# ﭼﺎرﭼﻮب .NETﭼﻴﺴﺖ؟ 44 ........................................................................................................... ﭼﺎرﭼﻮب .NETاز ﭼﻪ اﺟﺰاﻳﻲ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ؟45 ................................................................................. ﭼﮕﻮﻧﻪ ﺑﺎ اﺳﺘﻔﺎده از ﭼﺎرﭼﻮب .NETﺑﺮﻧﺎﻣﻪ ﺑﻨﻮﻳﺴﻴﻢ؟ 46 ............................................................................. MSILو 46 ................................................................................................................. :JIT اﺳﻤﺒﻠﻲ ﻫﺎ47 ........................................................................................................................ : ﻛﺪﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه48 ............................................................................................................ : ﻣﺪﻳﺮﻳﺖ ﺣﺎﻓﻈﻪ در 48 ......................................................................................................:.NET ﻣﺮاﺣﻞ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ در 48 ..................................................................................................... .NET ﻟﻴﻨﻚ دادن50 ....................................................................................................................... : C#ﭼﻴﺴﺖ؟ 50 ......................................................................................................................... ﭼﻪ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ را ﻣﻴﺘﻮان ﺑﺎ اﺳﺘﻔﺎده از C#اﻧﺠﺎم داد؟ 51 ......................................................................... وﻳﮋوال اﺳﺘﻮدﻳﻮ 52 ............................................................................................................... :2005 راه ﺣﻠﻬﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ53 ...........................................................................................................: ﻧﺘﻴﺠﻪ53 ................................................................................................................................. :
ﻓﺼﻞ ﺳﻮم :ﻧﻮﺷﺘﻦ ﻧﺮم اﻓﺰار 54 .......................................................................... داده ﻫﺎ و اﻃﻼﻋﺎت54 ................................................................................................................... : اﻟﮕﻮرﻳﺘﻢ ﻫﺎ54 .......................................................................................................................: ﻳﻚ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﭼﻴﺴﺖ؟ 56 ................................................................................................. ﻣﺘﻐﻴﻴﺮ ﻫﺎ56 ............................................................................................................................. : ﻛﺎر ﺑﺎ ﻣﺘﻐﻴﻴﺮ ﻫﺎ56 .................................................................................................................. : ﺗﻮﺿﻴﺤﺎت و ﻓﻀﺎﻫﺎي ﺧﺎﻟﻲ60 ..........................................................................................................:
٣
ﺗﻮﺿﻴﺤﺎت60 ........................................................................................................................ : ﻓﻀﺎﻫﺎي ﺧﺎﻟﻲ62 ................................................................................................................... : ﻧﻮع ﻫﺎي داده اي62 .................................................................................................................... : ﻛﺎرﻛﺮدن ﺑﺎ اﻋﺪاد62 ................................................................................................................. : ﻋﻤﻠﻴﺎت رﻳﺎﺿﻲ ﻣﻌﻤﻮل روي اﻋﺪاد ﺻﺤﻴﺢ63 .................................................................................. : ﺗﻨﺪ ﻧﻮﻳﺴﻲ در ﻋﻤﻠﻴﺎت رﻳﺎﺿﻲ66 ............................................................................................... : ﻣﺤﺪودﻳﺖ ﻛﺎر ﺑﺎ اﻋﺪاد ﺻﺤﻴﺢ67 ............................................................................................... : اﻋﺪاد اﻋﺸﺎري68 ................................................................................................................ : ﺣﺎﻟﺘﻬﺎي دﻳﮕﺮ70 ................................................................................................................ : اﻋﺪاد اﻋﺸﺎري ﺑﺎ دﻗﺖ ﻣﻌﻤﻮﻟﻲ70 ............................................................................................... : ﻛﺎر ﺑﺎ رﺷﺘﻪ ﻫﺎ71 ....................................................................................................................: اﺗﺼﺎل رﺷﺘﻪ ﻫﺎ73 ...............................................................................................................: اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ اﺗﺼﺎل رﺷﺘﻪ در درون ﺑﺮﻧﺎﻣﻪ74 .............................................................................. : ﻋﻤﻠﻴﺎت ﺑﻴﺸﺘﺮ روي رﺷﺘﻪ ﻫﺎ75 .................................................................................................: زﻳﺮ رﺷﺘﻪ ﻫﺎ77 .................................................................................................................. : ﻗﺎﻟﺐ ﺑﻨﺪي رﺷﺘﻪ ﻫﺎ79 .......................................................................................................... : ﻗﺎﻟﺐ ﺑﻨﺪي ﺑﻮﻣﻲ80 ............................................................................................................. : ﺟﺎﻳﮕﺰﻳﻨﻲ زﻳﺮرﺷﺘﻪ ﻫﺎ81 ....................................................................................................... : ﺗﺒﺪﻳﻞ ﻧﻮع ﻫﺎي داده اي82 ..................................................................................................... : اﺳﺘﻔﺎده از ﺗﺎرﻳﺨﻬﺎ85 ................................................................................................................ : ﻗﺎﻟﺐ ﺑﻨﺪي ﺗﺎرﻳﺨﻬﺎ86 .......................................................................................................... : اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺘﻬﺎي 88 ....................................................................................... :DateTime ﻛﺎر ﺑﺎ ﺗﺎرﻳﺨﻬﺎ89 ................................................................................................................ : ﺑﻮﻟﻴﻦ90 ............................................................................................................................. : ﻧﮕﻬﺪاري ﻣﺘﻐﻴﻴﺮ ﻫﺎ91 .................................................................................................................. : دودوﻳﻲ91 ........................................................................................................................... : ﺑﻴﺘﻬﺎ و ﺑﺎﻳﺖ ﻫﺎ92 ...................................................................................................................: ﻧﻤﺎﻳﺶ ﻣﻘﺎدﻳﺮ92 .................................................................................................................... : ﻣﺘﺪﻫﺎ94 ................................................................................................................................. : ﭼﺮا از ﻣﺘﺪﻫﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ؟ 95 .................................................................................................. ﻣﺘﺪﻫﺎﻳﻲ ﻛﻪ ﺗﺎﻛﻨﻮن دﻳﺪه اﻳﺪ95 ................................................................................................ : اﻳﺠﺎد ﻳﻚ ﻣﺘﺪ100................................................................................................................... : اﻧﺘﺨﺎب ﻧﺎم ﺑﺮاي ﻣﺘﺪ103............................................................................................................ : ﻣﺤﺪوده ﻫﺎ104...................................................................................................................... : ﻧﺘﻴﺠﻪ106................................................................................................................................ : ﺗﻤﺮﻳﻦ107............................................................................................................................... : ﺗﻤﺮﻳﻦ 107.........................................................................................................................:1 ﺗﻤﺮﻳﻦ 107.........................................................................................................................:2
٤
ﻓﺼﻞ ﭼﻬﺎرم :ﻛﻨﺘﺮل روﻧﺪ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ 108 ............................................................. ﺗﺼﻤﻴﻢ ﮔﻴﺮي در ﺑﺮﻧﺎﻣﻪ108............................................................................................................. : دﺳﺘﻮر 108............................................................................................................................ :if دﺳﺘﻮر 111....................................................................................................................:Else ﺑﺮرﺳﻲ ﭼﻨﺪ ﺷﺮط ﺑﺎ 112.................................................................................................. :else if دﺳﺘﻮرات ifﺗﻮدرﺗﻮ114............................................................................................................. : ﻋﻤﻠﮕﺮﻫﺎي ﻣﻘﺎﻳﺴﻪ اي115..........................................................................................................: اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ ﻣﺨﺎﻟﻒ115................................................................................................... : اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ ﻫﺎي ﻣﻘﺎﻳﺴﻪ اي117......................................................................................... : ﻋﻤﻠﮕﺮ ﻫﺎي Andو Orﻣﻨﻄﻘﻲ 121......................................................................................... : اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ Andﻣﻨﻄﻘﻲ123............................................................................................: ﻣﻄﺎﻟﺐ ﺑﻴﺸﺘﺮ در راﺑﻄﻪ ﺑﺎ ﻋﻤﻠﮕﺮ ﻫﺎي Andو Orﻣﻨﻄﻘﻲ125.............................................................. : ﻣﻘﺎﻳﺴﻪ رﺷﺘﻪ ﻫﺎ126................................................................................................................. : اﻧﺘﺨﺎب ﺑﻴﻦ ﺣﺎﻟﺘﻬﺎ ﺑﺎ اﺳﺘﻔﺎده از 128......................................................................................... :switch اﺳﺘﻔﺎده از switchﺑﺎ و ﺑﺪون ﺣﺴﺎﺳﻴﺖ ﺑﻪ ﻧﻮع ﺣﺮوف132....................................................................... : اﻧﺘﺨﺎﺑﻬﺎي ﭼﻨﺪ ﮔﺎﻧﻪ136............................................................................................................. : دﺳﺘﻮر 138............................................................................................................... :default اﺳﺘﻔﺎده از ﻧﻮع ﻫﺎي داده اي ﮔﻮﻧﺎﮔﻮن در دﺳﺘﻮر 139.................................................................... :switch ﺣﻠﻘﻪ ﻫﺎ139............................................................................................................................. : ﺣﻠﻘﻪ 140....................................................................................................................... :for ﺷﻤﺎرش ﻣﻌﻜﻮس در ﺣﻠﻘﻪ145.................................................................................................. : ﺣﻠﻘﻪ ﻫﺎي 146.......................................................................................................... :foreach ﺣﻠﻘﻪ ﻫﺎي 148.................................................................................................................. :do ﺣﻠﻘﻪ 150................................................................................................................... :while ﺷﺮﻃﻬﺎي ﻗﺎﺑﻞ ﻗﺒﻮل ﺑﺮاي ﺣﻠﻘﻪ ﻫﺎي doو 152..................................................................... :while ﺣﻠﻘﻪ ﻫﺎي ﺗﻮدرﺗﻮ153............................................................................................................... : ﺧﺮوج زودﻫﻨﮕﺎم از ﺣﻠﻘﻪ155........................................................................................................ : دﺳﺘﻮر 157......................................................................................................... :continue ﺣﻠﻘﻪ ﻫﺎي ﺑﻲ ﻧﻬﺎﻳﺖ158............................................................................................................ : ﻧﺘﻴﺠﻪ159................................................................................................................................ : ﺗﻤﺮﻳﻦ160............................................................................................................................... : ﺗﻤﺮﻳﻦ 160.........................................................................................................................:1 ﺗﻤﺮﻳﻦ 160.........................................................................................................................:2
ﻓﺼﻞ ﭘﻨﺠﻢ :ﻛﺎرﻛﺮدن ﺑﺎ ﺳﺎﺧﺘﺎرﻫﺎي داده اي 161 ....................................................... ﻣﻔﻬﻮم آراﻳﻪ161......................................................................................................................... : ﺗﻌﺮﻳﻒ و اﺳﺘﻔﺎده از آراﻳﻪ ﻫﺎ161.....................................................................................................: اﺳﺘﻔﺎده از 164........................................................................................................... :foreach
٥
اﻧﺘﻘﺎل آراﻳﻪ ﻫﺎ ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ167................................................................................................. : ﻣﺮﺗﺐ ﺳﺎزي آراﻳﻪ ﻫﺎ170............................................................................................................: ﺣﺮﻛﺖ ﺑﻪ ﻋﻘﺐ در آراﻳﻪ ﻫﺎ171..................................................................................................... : ﻣﻘﺪار دﻫﻲ اوﻟﻴﻪ ﺑﻪ آراﻳﻪ ﻫﺎ173.................................................................................................... : ﻣﻔﻬﻮم ﺷﻤﺎرﻧﺪه ﻫﺎ174.................................................................................................................. : اﺳﺘﻔﺎده از ﺷﻤﺎرﻧﺪه ﻫﺎ175........................................................................................................... : ﺗﻌﻴﻴﻦ ﻣﻮﻗﻴﺖ180.................................................................................................................... : ﻣﻔﻬﻮم ﺛﺎﺑﺖ ﻫﺎ182...................................................................................................................... : اﺳﺘﻔﺎده از ﺛﺎﺑﺖ ﻫﺎ182.............................................................................................................. : ﺛﺎﺑﺘﻬﺎ ﺑﺎ ﻧﻮﻋﻬﺎي داده اي ﮔﻮﻧﺎﮔﻮن185.............................................................................................. : ﺳﺎﺧﺘﺎرﻫﺎ186............................................................................................................................ : اﻳﺠﺎد ﺳﺎﺧﺘﺎرﻫﺎ186.................................................................................................................. : اﺿﺎﻓﻪ ﻛﺮدن ﺧﺎﺻﻴﺖ ﺑﻪ ﺳﺎﺧﺘﺎرﻫﺎ190.............................................................................................. : ﻛﺎر ﺑﺎ ﻟﻴﺴﺖ ﻫﺎي ﭘﻴﻮﻧﺪي191.......................................................................................................... : اﺳﺘﻔﺎده از ﻟﻴﺴﺖ ﻫﺎي ﭘﻴﻮﻧﺪي192.................................................................................................. : ﺣﺬف ﻳﻚ ﻋﻨﺼﺮ از ﻟﻴﺴﺖ ﻫﺎي ﭘﻴﻮﻧﺪي197........................................................................................ : ﻧﻤﺎﻳﺶ ﻋﻨﺎﺻﺮ ﻣﻮﺟﻮد در ﻟﻴﺴﺖ ﭘﻴﻮﻧﺪي200........................................................................................ : اﻳﺠﺎد ﺟﺪاول ﻗﺎﺑﻞ ﺟﺴﺘﺠﻮ ﺑﺎ Hashtableﻫﺎ202.................................................................................... : اﺳﺘﻔﺎده از 203....................................................................................................... :Hashtable ﺟﻠﻮﮔﻴﺮي از وارد ﺷﺪن ﻋﻨﺎﺻﺮ ﺗﻜﺮاري208......................................................................................... : ﻧﺘﻴﺠﻪ210................................................................................................................................ : ﺗﻤﺮﻳﻦ210............................................................................................................................... : ﺗﻤﺮﻳﻦ 211.........................................................................................................................:1
ﻓﺼﻞ ﺷﺸﻢ :اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي 212 ............................................................ ﭘﺎﺳﺦ ﺑﻪ روﻳﺪادﻫﺎ212................................................................................................................... : ﺗﻨﻈﻴﻢ ﻳﻚ روﻳﺪاد ﺑﺮاي ﻛﻨﺘﺮل 212..................................................................................... :Button اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺳﺎده218.............................................................................................................. : اﻳﺠﺎد ﻓﺮم218....................................................................................................................... : ﺷﻤﺎرش ﻛﺎراﻛﺘﺮ ﻫﺎ220............................................................................................................. : ﺷﻤﺎرش ﻛﻠﻤﺎت222................................................................................................................. : اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﭘﻴﭽﻴﺪه ﺗﺮ227........................................................................................................ : ﺑﺮﻧﺎﻣﻪ وﻳﺮاﻳﺸﮕﺮ ﻣﺘﻦ227........................................................................................................... : اﻳﺠﺎد ﻧﻮار اﺑﺰار228.................................................................................................................. : اﻳﺠﺎد ﻧﻮار وﺿﻌﻴﺖ232.............................................................................................................. : اﻳﺠﺎد ﻗﺴﻤﺖ وﻳﺮاﻳﺶ ﻣﺘﻦ234..................................................................................................... : ﭘﺎك ﻛﺮدن ﺑﺨﺶ وﻳﺮاﻳﺸﮕﺮ ﻣﺘﻦ235............................................................................................... : ﭘﺎﺳﺦ ﺑﻪ روﻳﺪادﻫﺎي ﻧﻮار اﺑﺰار237................................................................................................... : ﻣﻔﻬﻮم ﻓﻮﻛﻮس242.................................................................................................................. :
٦
اﺳﺘﻔﺎده از ﭼﻨﺪﻳﻦ ﻓﺮم در ﺑﺮﻧﺎﻣﻪ244.................................................................................................... : ﻓﺮم 245................................................................................................................... :About ﻧﺘﻴﺠﻪ248................................................................................................................................ : ﺗﻤﺮﻳﻦ249............................................................................................................................... : ﺗﻤﺮﻳﻦ 249.........................................................................................................................:1 ﺗﻤﺮﻳﻦ 249.........................................................................................................................:2
ﻓﺼﻞ ﻫﻔﺘﻢ :ﻧﻤﺎﻳﺶ ﻛﺎدرﻫﺎي ﻣﺤﺎوره اي 250 ........................................................... ﻛﺎدر ﻣﺤﺎوره اي 250............................................................................................... :MessageBox آﻳﻜﻮﻧﻬﺎي ﻗﺎﺑﻞ اﺳﺘﻔﺎده در ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم251..................................................................................... : دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد ﺑﺮاي ﻛﺎدر ﭘﻴﻐﺎم251............................................................................................. : ﺗﻨﻈﻴﻢ دﻛﻤﻪ ي ﭘﻴﺶ ﻓﺮض252.................................................................................................... : ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﺨﺘﻠﻒ ﻛﺎدر ﭘﻴﻐﺎم252.................................................................................................. : ﺣﺎﻟﺘﻬﺎي ﻣﺨﺘﻠﻒ اﺳﺘﻔﺎده از ﻣﺘﺪ 253.......................................................................................:Show ﻛﺎدرﻫﺎي ﭘﻴﻐﺎم ﻧﻤﻮﻧﻪ255............................................................................................................ : ﻛﻨﺘﺮل 259.................................................................................................... :OpenFileDialog ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل 260.................................................................................... :OpenFileDialog ﻣﺘﺪﻫﺎي 262...............................................................................................:OpenFileDialog اﺳﺘﻔﺎده از ﻛﻨﺘﺮل 262..................................................................................... :OpenFileDialog ﻛﻨﺘﺮل 268..................................................................................................... :SaveFileDialog ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل 268..................................................................................... :SaveFileDialog ﻣﺘﺪﻫﺎي ﻛﻨﺘﺮل 269........................................................................................ :SaveFileDialog اﺳﺘﻔﺎده از ﻛﻨﺘﺮل 269...................................................................................... :SaveFileDialog ﻛﻨﺘﺮل 273............................................................................................................ :FontDialog ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل 273............................................................................................ :FontDialog ﻣﺘﺪﻫﺎي ﻛﻨﺘﺮل 274...............................................................................................:FontDialog اﺳﺘﻔﺎده از ﻛﻨﺘﺮل 274............................................................................................. :FontDialog ﻛﻨﺘﺮل 278.......................................................................................................... :ColorDialog ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل 279.......................................................................................... :ColorDialog اﺳﺘﻔﺎده از ﻛﻨﺘﺮل 280........................................................................................... :ColorDialog ﻛﻨﺘﺮل 282............................................................................................................ :PrintDialog ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل 283........................................................................................... :PrintDialog اﺳﺘﻔﺎده از ﻛﻨﺘﺮل 283............................................................................................ :PrintDialog ﻛﻼس 283................................................................................................. :PrintDocument ﺧﺼﻮﺻﻴﺎت ﻛﻼس 284................................................................................ :PrintDocument ﭼﺎپ ﻳﻚ ﺳﻨﺪ284...................................................................................................................: ﻛﻨﺘﺮل 293........................................................................................... :FolderBrowserDialog ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل 294...................................................................................... :FolderBrowser اﺳﺘﻔﺎده از ﻛﻨﺘﺮل 295....................................................................................... :FolderBrowser
٧
ﻧﺘﻴﺠﻪ298................................................................................................................................ : ﺗﻤﺮﻳﻦ299............................................................................................................................... : ﺗﻤﺮﻳﻦ 299.........................................................................................................................:1 ﺗﻤﺮﻳﻦ 299.........................................................................................................................:2
ﻓﺼﻞ ﻫﺸﺘﻢ :ﻣﻨﻮ ﻫﺎ 301 .................................................................................. درك وﻳﮋﮔﻴﻬﺎي ﻳﻚ ﻣﻨﻮ301........................................................................................................... : ﺗﺼﺎوﻳﺮ301.......................................................................................................................... : ﻛﻠﻴﺪﻫﺎي دﺳﺘﺮﺳﻲ302.............................................................................................................. : ﺷﻮرت ﻛﺎت ﻫﺎ302.................................................................................................................. : ﻋﻼﻣﺖ ﺗﻴﻚ302.................................................................................................................... : ﭘﻨﺠﺮه 303.......................................................................................................... :Properties اﻳﺠﺎد ﻣﻨﻮ ﻫﺎ304.........................................................................................................................: ﻃﺮاﺣﻲ ﻣﻨﻮ ﻫﺎ304...................................................................................................................: اﺿﺎﻓﻪ ﻛﺮدن ﻧﻮار اﺑﺰارﻫﺎ و ﻛﻨﺘﺮل ﻫﺎ307........................................................................................... : ﻧﻮﺷﺘﻦ ﻛﺪ ﺑﺮاي ﻣﻨﻮ ﻫﺎ309......................................................................................................... : ﻛﺪ ﻧﻮﻳﺴﻲ ﻣﻨﻮي Viewو ﻧﻮار اﺑﺰارﻫﺎ315........................................................................................ : اﻣﺘﺤﺎن ﺑﺮﻧﺎﻣﻪ317................................................................................................................... : ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ320..................................................................................................................... : اﻳﺠﺎد ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ321........................................................................................................... : ﻓﻌﺎل و ﻏﻴﺮ ﻓﻌﺎل ﻛﺮدن ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻨﻮ و دﻛﻤﻪ ﻫﺎي ﻧﻮار اﺑﺰار324................................................................ : ﻧﺘﻴﺠﻪ330................................................................................................................................ : ﺗﻤﺮﻳﻦ330............................................................................................................................... :
ﻓﺼﻞ ﻧﻬﻢ :ﺳﺎﺧﺘﻦ اﺷﻴﺎ 331 .............................................................................. ﻣﻔﻬﻮم اﺷﻴﺎ331.......................................................................................................................... : ﻛﭙﺴﻮﻟﻲ ﺑﻮدن333................................................................................................................... : ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎ333............................................................................................................ : روﻳﺪادﻫﺎ334......................................................................................................................... : ﻗﺎﺑﻞ روﻳﺖ ﺑﻮدن334................................................................................................................ : ﻳﻚ ﻛﻼس ﭼﻴﺴﺖ؟ 335............................................................................................................. اﻳﺠﺎد ﻛﻼﺳﻬﺎ336....................................................................................................................... : ﻗﺎﺑﻠﻴﺖ اﺳﺘﻔﺎده ﻣﺠﺪد337............................................................................................................... : ﻃﺮاﺣﻲ ﻳﻚ ﺷﻴﺊ338................................................................................................................... : ﺣﺎﻟﺖ339............................................................................................................................ : رﻓﺘﺎر339............................................................................................................................. : ﻧﮕﻬﺪاري ﺣﺎﻟﺖ340................................................................................................................. : ﺧﺎﺻﻴﺖ ﻫﺎي ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ343.................................................................................................... : ﺧﺎﺻﻴﺘﻬﺎي ﺧﻮاﻧﺪﻧﻲ-ﻧﻮﺷﺘﻨﻲ348................................................................................................... : ﻣﺘﺪ 351.............................................................................................................. :IsMoving ٨
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪ 352............................................................................. IsMoving ﻣﺘﺪﻫﺎي ﺳﺎزﻧﺪه354..................................................................................................................... : اﻳﺠﺎد ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه354...........................................................................................................: وراﺛﺖ356............................................................................................................................... : اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي ﺟﺪﻳﺪ357...................................................................................... : اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪ 361...................................................................... :GetPowerToWeightRatio ﺗﻐﻴﻴﺮ دادن ﭘﻴﺶ ﻓﺮض ﻫﺎ362...................................................................................................... : ﭼﻨﺪ ﺷﻜﻠﻲ ﺑﻮدن :ﻛﻠﻤﻪ اي ﺗﺮﺳﻨﺎك ،ﻣﻔﻬﻮﻣﻲ ﺳﺎده 364............................................................................ Overrideﻛﺮدن ﻣﺘﺪﻫﺎي ﺑﻴﺸﺘﺮ365............................................................................................ : ﺑﻪ ارث ﺑﺮدن از ﻛﻼس 369.............................................................................................. :Object اﺷﻴﺎ و ﺳﺎﺧﺘﺎرﻫﺎ369..................................................................................................................... : ﻛﻼﺳﻬﺎي ﭼﺎرﭼﻮب 370........................................................................................................:.NET ﻓﻀﺎي ﻧﺎم370....................................................................................................................... : راﻫﻨﻤﺎي 372............................................................................................................... :using وراﺛﺖ در ﭼﺎرﭼﻮب 373.................................................................................................... :.NET ﻧﺘﻴﺠﻪ373................................................................................................................................ :
ﻓﺼﻞ دﻫﻢ :ﻣﺒﺎﺣﺚ ﭘﻴﺸﺮﻓﺘﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا 375 ................................................ ﺳﺮﺑﺎر ﮔﺬاري ﻣﺘﺪ ﻫﺎ375................................................................................................................ : اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي 378......................................................................................... :Static اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ﻫﺎي 379.............................................................................................. :Static اﺳﺘﻔﺎده از ﻣﺘﺪﻫﺎي 385.................................................................................................... :Static ﺳﺮﺑﺎر ﮔﺬاري ﻋﻤﻠﮕﺮ ﻫﺎ386............................................................................................................. : درك ﻋﻤﻠﮕﺮ ﻫﺎ387................................................................................................................. : ﭼﮕﻮﻧﮕﻲ ﺳﺮﺑﺎر ﮔﺬاري ﻋﻤﻠﮕﺮ ﻫﺎ388............................................................................................... : ﻛﻼﺳﻬﺎي 394............................................................................................................. :Abstract ﻛﻼﺳﻬﺎي 401................................................................................................................ :sealed Interfaceﻫﺎ401..................................................................................................................... : اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻛﺎرﺑﺮدي414.......................................................................................................: ﺷﻮرت ﻛﺎت ﻫﺎي اﻳﻨﺘﺮﻧﺘﻲ و Favoritesﻫﺎ414.................................................................................. : اﺳﺘﻔﺎده از ﻛﻼﺳﻬﺎ416............................................................................................................... : ﭘﻴﺪا ﻛﺮدن ﮔﺰﻳﻨﻪ ﻫﺎي 423.......................................................................................... :Favorites ﻣﺸﺎﻫﺪه ي ﻟﻴﻨﻚ ﻫﺎ428............................................................................................................ : اﻳﺠﺎد ﻧﻤﻮﻧﻪ اي دﻳﮕﺮ از ﺑﺮﻧﺎﻣﻪ ي 431....................................................................... :Favorite Viewer اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي 431......................................................................................... :Favorites Tray ﻧﻤﺎﻳﺶ ﮔﺰﻳﻨﻪ ﻫﺎي 434.............................................................................................. :Favorites ﻧﺘﻴﺠﻪ439................................................................................................................................ :
ﻓﺼﻞ ﻳﺎزدﻫﻢ :اﺷﻜﺎل زداﻳﻲ و ﻛﻨﺘﺮل ﺧﻄﺎ در ﺑﺮﻧﺎﻣﻪ 441 ................................................
٩
اﻧﻮاع ﻣﺨﺘﻠﻒ ﺧﻄﺎﻫﺎ441................................................................................................................. : ﺧﻄﺎﻫﺎي دﺳﺘﻮري441............................................................................................................... : ﺧﻄﺎﻫﺎي اﺟﺮاﻳﻲ444................................................................................................................ : ﺧﻄﺎﻫﺎي ﻣﻨﻄﻘﻲ444................................................................................................................ : اﺷﻜﺎل زداﻳﻲ446........................................................................................................................ : اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻤﻮﻧﻪ446......................................................................................................... : ﻛﻨﺘﺮل اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از Breakpointﻫﺎ451.......................................................................... : ﮔﺰﻳﻨﻪ ﻫﺎي ﭘﺮ ﻛﺎرﺑﺮد در ﻧﻮار اﺑﺰار 452.................................................................................. :Debug ﭘﻨﺠﺮه ي 454.................................................................................................... :Breakpoints ﻛﻨﺘﺮل اﺳﺘﺜﻨﺎ ﻫﺎ در ﺑﺮﻧﺎﻣﻪ456...........................................................................................................: ﭼﮕﻮﻧﮕﻲ ﻳﺎﻓﺘﻦ ﺑﻼك Catchﺑﺮاي ﻳﻚ اﺳﺘﺜﻨﺎ457.............................................................................. : ﻛﻼس 458..........................................................................................................:Exception دﺳﺘﻮر 459................................................................................................................. :throw دﺳﺘﻮرات tryو 462....................................................................................................... :catch اﻳﺠﺎد ﺑﻼك ﻫﺎي catchاﺧﺘﺼﺎﺻﻲ465.......................................................................................... : ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي ﻛﻼس 468................................................................................. :Exception ﻧﺘﻴﺠﻪ471................................................................................................................................ :
ﻓﺼﻞ دوازدﻫﻢ :اﻳﺠﺎد ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس473 ......................................................... ﻣﻔﻬﻮم ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس474....................................................................................................... : اﻳﺠﺎد ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس474.................................................................................................. : اﻳﺠﺎد ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺑﺮاي 476............................................................... :Favorites Viewer ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﭼﻨﺪ ﻻﻳﻪ480........................................................................................................... : اﺳﺘﻔﺎده از ﻧﺎﻣﮕﺬاري ﻗﻮي 482........................................................................................................... اﻣﻀﺎ ﻛﺮدن اﺳﻤﺒﻠﻲ ﻫﺎ483.......................................................................................................... : ﻧﺴﺨﻪ ﻫﺎي ﻳﻚ اﺳﻤﺒﻠﻲ486........................................................................................................ : ﺛﺒﺖ ﻛﺮدن ﻳﻚ اﺳﻤﺒﻠﻲ487............................................................................................................ : اﺑﺰار 487................................................................................................................ :GacUtil ﻃﺮاﺣﻲ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس490...................................................................................................... : اﺳﺘﻔﺎده از ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺷﺨﺺ ﺛﺎﻟﺚ491................................................................................... : اﺳﺘﻔﺎده از ﻓﺎﻳﻞ 491................................................................................ :InetrnetFavorites.dll اﺳﺘﻔﺎده از 492................................................................................................. :Object Browser ﻧﺘﻴﺠﻪ494................................................................................................................................ : ﺗﻤﺮﻳﻦ494............................................................................................................................... :
ﻓﺼﻞ ﺳﻴﺰدﻫﻢ :اﻳﺠﺎد ﻛﻨﺘﺮﻟﻬﺎي ﺳﻔﺎرﺷﻲ 495 ........................................................... ﻛﻨﺘﺮﻟﻬﺎي وﻳﻨﺪوزي495................................................................................................................. : اﻳﺠﺎد و ﺗﺴﺖ ﻛﺮدن ﻛﻨﺘﺮل ﻫﺎي ﺳﻔﺎرﺷﻲ496..................................................................................... : اﻳﺠﺎد ﻛﺮدن ﺧﺎﺻﻴﺖ ﺑﺮاي ﻛﻨﺘﺮل ﻫﺎي ﺳﻔﺎرﺷﻲ500...................................................................................:
١٠
اﺿﺎﻓﻪ ﻛﺮدن ﺧﺎﺻﻴﺖ ﻫﺎ501........................................................................................................ : اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪ ﺑﻪ ﻛﻨﺘﺮل ﻫﺎي ﺳﻔﺎرﺷﻲ503...................................................................................... : اﺿﺎﻓﻪ ﻛﺮدن روﻳﺪاد ﺑﻪ ﻛﻨﺘﺮل504.................................................................................................. : زﻣﺎن اﺟﺮا ﻳﺎ زﻣﺎن ﻃﺮاﺣﻲ509.......................................................................................................... : اﻳﺠﺎد ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻓﺮم512......................................................................................................... : اﻳﺠﺎد ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻓﺮم ﺣﺎوي ﻓﺮم ورود512................................................................................... : اﺳﺘﻔﺎده از ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻓﺮم اﻳﺠﺎد ﺷﺪه523.......................................................................................... : اﺳﺘﻔﺎده از روﻳﺪاد ﻫﺎي ﻣﻮﺟﻮد در ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻓﺮم526............................................................................. : ﻧﺘﻴﺠﻪ530................................................................................................................................ : ﺗﻤﺮﻳﻦ531............................................................................................................................... :
ﻓﺼﻞ ﭼﻬﺎردﻫﻢ :اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﮔﺮاﻓﻴﻜﻲ 532 ........................................................ اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي Paintﺳﺎده532................................................................................................. : اﻳﺠﺎد ﻳﻚ ﭘﺮوژه ﻫﻤﺮاه ﺑﺎ ﻛﻨﺘﺮل ﻫﺎي ﺳﻔﺎرﺷﻲ532................................................................................ : ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﮔﺮاﻓﻴﻜﻲ ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ؟ 533..................................................................................... ﺗﺮﺳﻴﻢ ﺑﻴﺖ ﻣﭙﻲ534............................................................................................................. : ﺗﺮﺳﻴﻢ ﺑﺮداري535............................................................................................................... : اﻳﺠﺎد ﻛﻼس 535............................................................................................. :GraphicsItem ﻣﺨﺘﺼﺎت ﺻﻔﺤﻪ و ﻣﺨﺘﺼﺎت ﺑﺮﻧﺎﻣﻪ538............................................................................................: ﺑﺮرﺳﻲ ﺣﺮﻛﺎت ﻣﺎوس و رﺳﻢ اﺷﻴﺎي 540.................................................................. :GraphicsCircle ﻧﺎ ﻣﻌﺘﺒﺮ ﺳﺎزي547................................................................................................................... : ﺑﻬﻴﻨﻪ ﺳﺎزي ﻛﺮدن رﺳﻢ548........................................................................................................ : اﻧﺘﺨﺎب رﻧﮓ549.................................................................................................................... : اﻳﺠﺎد ﻛﻨﺘﺮل 549............................................................................................ :ColorPalette ﭘﺎﺳﺦ دادن ﺑﻪ ﻛﻠﻴﻚ ﻫﺎ556......................................................................................................... : اﺳﺘﻔﺎده از دو رﻧﮓ در ﺑﺮﻧﺎﻣﻪ560........................................................................................................ : ﻣﺸﺨﺺ ﻛﺮدن رﻧﮕﻬﺎي ﻣﻮرد اﺳﺘﻔﺎده563.......................................................................................... : اﺳﺘﻔﺎده از رﻧﮕﻬﺎي ﺑﻴﺸﺘﺮ در ﺑﺮﻧﺎﻣﻪ572............................................................................................. : اﺳﺘﻔﺎده از ﻛﺎدر 574.................................................................................................... :Color اﺳﺘﻔﺎده از رﻧﮕﻬﺎي ﺳﻴﺴﺘﻤﻲ576................................................................................................ : اﺳﺘﻔﺎده از اﺑﺰارﻫﺎي ﻣﺘﻔﺎوت577..................................................................................................... : اﺳﺘﻔﺎده از داﻳﺮه ﻫﺎي ﺗﻮﺧﺎﻟﻲ578................................................................................................... : ﻛﺎر ﺑﺎ ﻋﻜﺴﻬﺎ584........................................................................................................................: ﻧﻤﺎﻳﺶ ﺗﺼﺎوﻳﺮ585.................................................................................................................. : ﺗﻐﻴﻴﺮ اﻧﺪازه ي ﺗﺼﺎوﻳﺮ587.......................................................................................................... : ﻣﺘﺪ ﻫﺎي دﻳﮕﺮ ﻛﻼس 590............................................................................................... :Graphics ﻧﺘﻴﺠﻪ591................................................................................................................................ :
ﻓﺼﻞ ﭘﺎﻧﺰدﻫﻢ :اﺳﺘﻔﺎده از ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ 592 ....................................................... ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﭼﻴﺴﺖ؟ 592............................................................................................................. ١١
اﺷﻴﺎي ﻣﻮﺟﻮد در 593.................................................................................................... :Access ﺟﺪوﻟﻬﺎ593.......................................................................................................................... : ﭘﺮس وﺟﻮ ﻫﺎ594.................................................................................................................... : دﺳﺘﻮر SELECTدر زﺑﺎن 595.............................................................................................. :SQL ﭘﺮس وﺟﻮ ﻫﺎ در 597........................................................................................................ :Access اﻳﺠﺎد ﻳﻚ ﭘﺮس وﺟﻮ598............................................................................................................ : ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي دﺳﺘﺮﺳﻲ اﻃﻼﻋﺎت603................................................................................................. : 603..................................................................................................................... :DataSet 604.......................................................................................................... :DataGridView 604.......................................................................................................... :BindingSource 605..................................................................................................... :BindingNavigator 605............................................................................................................ :TableAdapter اﺗﺼﺎل داده ﻫﺎ605....................................................................................................................... : ﻧﺘﻴﺠﻪ613................................................................................................................................ : ﺗﻤﺮﻳﻦ614............................................................................................................................... : ﺗﻤﺮﻳﻦ 614.........................................................................................................................:1 ﺗﻤﺮﻳﻦ 615.........................................................................................................................:2
ﻓﺼﻞ ﺷﺎﻧﺰدﻫﻢ :ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺎ SQL Serverو 616 .......... ADO.NET 617..................................................................................................................... ADO.NET ﻓﻀﺎي ﻧﺎم 617............................................................................................................... :Data ﻛﻼس 619.................................................................................................. :SqlConnection اﻳﺠﺎد ﺑﺨﺸﻬﺎي ﻣﺨﺘﻠﻒ 619........................................................................ :ConnectionString ﻣﺘﺼﻞ ﺷﺪن و ﻗﻄﻊ ﻛﺮدن اﺗﺼﺎل ﺑﻪ ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ621................................................................. : ﻛﻼس 621.................................................................................................... :SqlCommand ﺧﺎﺻﻴﺖ 622.................................................................................................. :Connection ﺧﺎﺻﻴﺖ 622.............................................................................................:CommandText ﺧﺎﺻﻴﺖ 623................................................................................................... :Parameters ﻣﺘﺪ 624........................................................................................... :ExecuteNonQuery ﻛﻼس 625................................................................................................ :SqlDataAdapter ﺧﺎﺻﻴﺖ 626.......................................................................................... :SelectCommand اﺳﺘﻔﺎده از Command Builderﺑﺮاي اﻳﺠﺎد دﺳﺘﻮرات SQLدﻳﮕﺮ628............................................... : ﻣﺘﺪ 628.................................................................................................................... :Fill ﻛﻼس 630............................................................................................................. :DataSet ﻛﻼس 631..........................................................................................................:DataView ﺧﺎﺻﻴﺖ 632.............................................................................................................. :Sort ﺧﺎﺻﻴﺖ 632.................................................................................................... :RowFilter ﻣﺘﺪ 633.................................................................................................................. :Find اﺳﺘﻔﺎده از ﻛﻼﺳﻬﺎي ADO.NETدر ﻋﻤﻞ634.................................................................................... :
١٢
ﻛﺎرﺑﺮد DataSetدر ﺑﺮﻧﺎﻣﻪ635................................................................................................... : اﺗﺼﺎل داده ﻫﺎ646....................................................................................................................... : BindingContextو 647........................................................................ :CurrencyManager اﺗﺼﺎل ﻛﻨﺘﺮل ﻫﺎ648................................................................................................................ : ﻣﺜﺎل اﻳﺠﺎد اﺗﺼﺎل649........................................................................................................... : ﻧﺘﻴﺠﻪ689................................................................................................................................ : ﺗﻤﺮﻳﻦ690............................................................................................................................... : ﺗﻤﺮﻳﻦ 690.........................................................................................................................:1
ﻓﺼﻞ ﻫﻔﺪﻫﻢ :ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب 691 ............................................................ ﻣﻌﻤﺎري ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب691..................................................................................................... : ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب در ﻣﻘﺎﻳﺴﻪ ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز693..................................................................... : ﻣﺰاﻳﺎي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز693............................................................................................... : ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب694...........................................................................................................: اﺟﺰاي اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب694................................................................................................ : ﺳﺮور وب695........................................................................................................................ : ﻣﺮورﮔﺮ695.......................................................................................................................... : 695...................................................................................................................... :HTML VBScriptو 696............................................................................................... :JavaScript 696........................................................................................................................... :CSS 696.............................................................................................................................. :ASP ﻣﺰاﻳﺎ697............................................................................................................................. : ﻓﺎﻳﻠﻬﺎي ﺧﺎص در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب697.................................................................................... : ﻓﺎﻳﻞ 697..................................................................................................... :Global.asax ﻓﺎﻳﻞ 698...................................................................................................... :web.config اﺳﺘﻔﺎده از ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ698............................................................................................... : ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﺟﻌﺒﻪ اﺑﺰار698................................................................................................. : اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺗﺤﺖ وب699...........................................................................................................: اﻳﺠﺎد ﻳﻚ ﻓﺮم وب ﺑﺮاي ﭘﺮدازش ﺳﻤﺖ ﺳﺮور و ﺳﻤﺖ ﻛﻼﻳﻨﺖ700............................................................... : درﻳﺎﻓﺖ اﻃﻼﻋﺎت و اﻋﺘﺒﺎر ﺳﻨﺠﻲ آﻧﻬﺎ707.......................................................................................... : ﻃﺮاﺣﻲ ﻇﺎﻫﺮ ﺳﺎﻳﺖ713............................................................................................................. : اﺳﺘﻔﺎده از ﻛﻨﺘﺮل GridViewﺑﺮاي ﻧﻤﺎﻳﺶ داده ﻫﺎ در ﻓﺮم وب727............................................................ : ﻣﺤﻞ ﻗﺮارﮔﻴﺮي ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب در وﻳﮋوال اﺳﺘﻮدﻳﻮ735.................................................................. : ﻧﺘﻴﺠﻪ738................................................................................................................................ : ﺗﻤﺮﻳﻦ738............................................................................................................................... :
ﻓﺼﻞ ﻫﺠﺪﻫﻢ :ﺗﺸﺨﻴﺺ ﻫﻮﻳﺖ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب 740 ......................................... ﺗﺸﺨﻴﺺ ﻫﻮﻳﺖ در ﻳﻚ ﺳﺎﻳﺖ وب740................................................................................................ : ﺗﺸﺨﻴﺺ ﻫﻮﻳﺖ ﺑﺎ اﺳﺘﻔﺎده از وﻳﻨﺪوز740........................................................................................... : ﺗﺸﺨﻴﺺ ﻫﻮﻳﺖ ﺑﺎ اﺳﺘﻔﺎده از ﻓﺮﻣﻬﺎي وب741..................................................................................... : ١٣
اﺑﺰار ﻣﺪﻳﺮﻳﺖ ﺳﺎﻳﺖ وب )741.............................................................................................:(WAT ﻛﻨﺘﺮﻟﻬﺎي 752............................................................................................................. :Login ﻧﺘﻴﺠﻪ765............................................................................................................................ : ﺗﻤﺮﻳﻦ766............................................................................................................................... : ﺗﻤﺮﻳﻦ 766.........................................................................................................................:1
ﻓﺼﻞ ﻧﻮزدﻫﻢ XML :و وﻳﮋوال 767 ....................................................... 2005 C# درك 767....................................................................................................................... :XML XMLﺷﺒﻴﻪ ﺑﻪ ﭼﻴﺴﺖ؟ 768....................................................................................................... XMLﺑﺮاي اﻓﺮاد ﻣﺒﺘﺪي771..................................................................................................... : ﭘﺮوژه ي دﻓﺘﺮ ﺗﻠﻔﻦ771................................................................................................................. : اﻳﺠﺎد ﭘﺮوژه771...................................................................................................................... : ﻛﻼس 773............................................................................................... :SerializableData درﻳﺎﻓﺖ داده ﻫﺎ از ﻳﻚ ﻓﺎﻳﻞ 780.......................................................................................... :XML ﺗﻐﻴﻴﺮ در داده ﻫﺎ784................................................................................................................. : ﻓﺮﺳﺘﺎدن اﻳﻤﻴﻞ785..................................................................................................................: اﻳﺠﺎد ﻟﻴﺴﺘﻲ از آدرﺳﻬﺎ786.......................................................................................................... : در ﻧﻈﺮ ﻧﮕﺮﻓﺘﻦ اﻋﻀﺎ792............................................................................................................ : اﺳﺘﺨﺮاج رﻛﻮرد ﻫﺎ از ﻓﺎﻳﻞ 795............................................................................................ :XML اﺿﺎﻓﻪ ﻛﺮدن رﻛﻮرد ﻫﺎي ﺟﺪﻳﺪ796................................................................................................. : ﺣﺮﻛﺖ در ﺑﻴﻦ داده ﻫﺎ798.......................................................................................................... : ﺣﺬف ﻛﺮدن داده ﻫﺎ از ﺑﺮﻧﺎﻣﻪ800................................................................................................... : ﺑﺮرﺳﻲ ﻟﺒﻪ ﻫﺎ802................................................................................................................... : اﻳﺠﺎد ﻳﻜﭙﺎرﭼﮕﻲ ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ي دﻓﺘﺮ ﺗﻠﻔﻦ و دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ803................................................................... : ﺗﻮﺿﻴﺢ اﺻﻮل ﻳﻜﭙﺎرﭼﻪ ﺳﺎزي803...................................................................................................: ﺧﻮاﻧﺪن اﻃﻼﻋﺎت ﺑﺮﻧﺎﻣﻪ ي دﻓﺘﺮ ﺗﻠﻔﻦ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي دﻳﮕﺮ805.................................................................: ﻧﺘﻴﺠﻪ811................................................................................................................................ : ﺗﻤﺮﻳﻦ811............................................................................................................................... : ﺗﻤﺮﻳﻦ 812.........................................................................................................................:1 ﺗﻤﺮﻳﻦ 812.........................................................................................................................:2
ﻓﺼﻞ ﺑﻴﺴﺘﻢ :وب ﺳﺮوﻳﺲ ﻫﺎ و 813 ........................................... .NET Remoting وب ﺳﺮوﻳﺲ ﭼﻴﺴﺖ؟813................................................................................................................ ﻧﺤﻮه ي ﻋﻤﻠﻜﺮد وب ﺳﺮوﻳﺲ ﻫﺎ814.............................................................................................. : 815........................................................................................................................ :SOAP اﻳﺠﺎد ﻳﻚ وب ﺳﺮوﻳﺲ816............................................................................................................. : اﻳﺠﺎد ﻳﻚ وب ﺳﺮوﻳﺲ ﺳﺎده817................................................................................................... : اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪﻫﺎي دﻳﮕﺮ820..................................................................................................... : اﻳﺠﺎد ﺳﺮور ﭘﺮوژه ي 822...................................................................................... :Picture Service
١٤
اﻳﺠﺎد ﭘﺮوژه822...................................................................................................................... : ﺑﺮﮔﺮداﻧﺪن آراﻳﻪ ﻫﺎ ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ي ﻣﺘﺪ825..................................................................................... : ﺑﺮﮔﺮداﻧﺪن ﻳﻚ ﺳﺎﺧﺘﺎر ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ي ﻳﻚ ﻣﺘﺪ در وب ﺳﺮوﻳﺲ830.......................................................... : اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ835............................................................................................................ : 835...................................................................................................................... :WSDL اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ835........................................................................................................ : اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ وب ﺳﺮوﻳﺲ ﺑﻪ ﺑﺮﻧﺎﻣﻪ837....................................................................................... : ﻧﻤﺎﻳﺶ ﻟﻴﺴﺖ ﻓﻮﻟﺪر ﻫﺎ در ﺑﺮﻧﺎﻣﻪ839............................................................................................... : ﻧﻤﺎﻳﺶ ﻟﻴﺴﺖ ﻓﺎﻳﻠﻬﺎي ﻣﻮﺟﻮد و اﻧﺘﺨﺎب آﻧﻬﺎ843................................................................................... : 848............................................................................................................ :.NET Remoting اﻳﺠﺎد ﭘﺮوﻛﺴﻲ852.................................................................................................................. : ﻧﺘﻴﺠﻪ856................................................................................................................................ : ﺗﻤﺮﻳﻦ856............................................................................................................................... : ﺗﻤﺮﻳﻦ 856.........................................................................................................................:1 ﺗﻤﺮﻳﻦ 857.........................................................................................................................:2
ﻓﺼﻞ ﺑﻴﺴﺖ و ﻳﻜﻢ :ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﺎرﺑﺮدي 858 .................................................... ﻣﻨﻈﻮر از ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﭼﻴﺴﺖ؟ 858...................................................................................................... ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از روش 859............................................................................... :ClickOnce ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از روش 865.................................................................................. :XCOPY اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ 865.................................................................... :2005 اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه866............................................................................................... : وﻳﺮاﻳﺸﮕﺮ راﺑﻂ ﻛﺎرﺑﺮي ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ870............................................................................................ : ﺗﻮزﻳﻊ راه ﺣﻠﻬﺎي ﮔﻮﻧﺎﮔﻮن874.......................................................................................................... : اﺳﻤﺒﻠﻲ ﻫﺎي ﺧﺼﻮﺻﻲ874......................................................................................................... : اﺳﻤﺒﻠﻲ ﻫﺎي ﻋﻤﻮﻣﻲ875........................................................................................................... : ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي876..................................................................................................... : ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب876................................................................................................ : ﺗﻮزﻳﻊ وب ﺳﺮوﻳﺲ ﻫﺎ876.......................................................................................................... : اﺑﺰارﻫﺎي ﻣﻔﻴﺪ876................................................................................................................... : ﻧﺘﻴﺠﻪ877................................................................................................................................ : ﺗﻤﺮﻳﻦ878............................................................................................................................... : ﺗﻤﺮﻳﻦ 878.........................................................................................................................:1 ﺗﻤﺮﻳﻦ 878.........................................................................................................................:2
ﻓﺼﻞ ﺑﻴﺴﺖ و دوم :اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﻮﺑﺎﻳﻞ 879 ....................................................... درك ﻣﺤﻴﻂ879......................................................................................................................... : 880....................................................................................... :Common Language Runtime 880............................................................................................................... :ActiveSync ﻧﻮع ﻫﺎي داده اي در 881...................................................................................................... :CF ١٥
ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در 882..........................................................................:Compact Framework اﻳﺠﺎد ﻳﻚ ﺑﺎزي ﺑﺮاي 885............................................................................................. :Pocket PC ﻧﺘﻴﺠﻪ897................................................................................................................................ : ﺗﻤﺮﻳﻦ898............................................................................................................................... :
ﺿﻤﻴﻤﻪ ي :1اداﻣﻪ ي ﻣﺴﻴﺮ 899 ......................................................................... ﻣﻨﺎﺑﻊ آﻧﻼﻳﻦ900......................................................................................................................... : ﻣﻨﺎﺑﻊ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ900.............................................................................................................. : ﻣﻨﺎﺑﻊ دﻳﮕﺮ901...................................................................................................................... :
ﺿﻤﻴﻤﻪ :2ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺗﺠﺎري و ﭼﻨﺪ ﻻﻳﻪ در 902 ........................................... .NET ﭼﺮا .NET؟ 902....................................................................................................................... ﻣﺸﻜﻼت ﺗﺠﺎري رﻓﻊ ﺷﺪه ﺗﻮﺳﻂ 902..................................................................................... .NET ﻛﺎراﻳﻲ و ﻣﻘﻴﺎس ﭘﺬﻳﺮي904........................................................................................................ : ﻣﺰاﻳﺎي 904................................................................................................................ : .NET ﭘﺬﻳﺮش اﺳﺘﺎﻧﺪاردﻫﺎي ﻫﻤﮕﺎﻧﻲ905................................................................................................. : ﺳﺮوﻳﺲ ﻫﺎي وب906...............................................................................................................: وﻳﮋﮔﻲ ﻫﺎي ﻣﺤﻴﻂ ﺗﻮﺳﻌﻪ 906.......................................................................... : Visual Stadio.NET 906....................................................................................... :Common Language Runtime زﺑﺎن ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ 906.............................................................................................. :.NET 907............................................................................................. :Intermediate Language ﺗﻜﺎﻣﻞ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻻﻳﻪ اي907...................................................................................................... : ﺗﻌﺮﻳﻒ907........................................................................................................................... : ﻣﺪﻳﺮﻳﺖ ﻣﺘﻤﺮﻛﺰ907................................................................................................................. : ﻣﺤﺎﺳﺒﺎت ﺗﻮزﻳﻊ ﺷﺪه908........................................................................................................... : ﻛﺎراﻳﻲ908........................................................................................................................... : ﻣﻘﻴﺎس ﭘﺬﻳﺮي908.................................................................................................................. : ﻗﻮاﻋﺪ و دﺳﺘﻮرات ﺗﺠﺎري908....................................................................................................... : راﺣﺘﻲ ﻛﺎرﺑﺮ909..................................................................................................................... : ﺑﺮﻧﺎﻣﻪ ﻫﺎي دو ﻻﻳﻪ909................................................................................................................. : ﻣﺪﻳﺮﻳﺖ ﻛﺪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي دو ﻻﻳﻪ909.............................................................................................: ﻛﺎراﻳﻲ910........................................................................................................................... : دﺳﺘﺮﺳﻲ داده ﻫﺎ910................................................................................................................ : ﻗﻮاﻋﺪ ﺗﺠﺎري911.................................................................................................................... : ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﻪ ﻻﻳﻪ911................................................................................................................ : ﺳﺮوﻳﺲ ﻫﺎي ﻛﺎرﺑﺮان911.......................................................................................................... : ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري912........................................................................................................... : ﺳﺮوﻳﺲ ﻫﺎي اﻃﻼﻋﺎﺗﻲ912........................................................................................................ : ﻣﺪﻳﺮﻳﺖ ﻛﺪ913..................................................................................................................... : ﻣﻘﻴﺎس ﭘﺬﻳﺮي913.................................................................................................................. : ١٦
ﻗﻮاﻋﺪ ﺗﺠﺎري913.................................................................................................................... : ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﭼﻨﺪ ﻻﻳﻪ914............................................................................................................. : ﻛﻼس ﺧﺎرﺟﻲ914.................................................................................................................. : ﻛﻼس اﺻﻠﻲ ﺗﺠﺎري915............................................................................................................: ﻛﻼﺳﻬﺎي دﺳﺘﺮﺳﻲ اﻃﻼﻋﺎت916.................................................................................................. : ﺳﺮوﻳﺲ ﻫﺎي وب916...............................................................................................................: ﻣﺪل ﻻﻳﻪ وب ﺳﺮوﻳﺲ ﻫﺎ917...................................................................................................... : ﭼﺮا وب ﺳﺮوﻳﺲ ﻫﺎ؟ 917............................................................................................................
ﺿﻤﻴﻤﻪ ي :3ﻣﻌﻤﺎري ﭘﻠﺖ ﻓﺮم 919 ........................................ .NET Framework ﻛﺎﻣﭙﺎﻳﻞ ﺳﻮرس ﻛﺪ ﺑﻪ ﻣﺎژول ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه919.................................................................................. : ﺗﺮﻛﻴﺐ ﻣﺎژول ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه در اﺳﻤﺒﻠﻲ ﻫﺎ922................................................................................... : ﺑﺎرﮔﺬاري 924............................................................................. :Common Language Runtime اﺟﺮاي ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه925....................................................................................................... : ﻣﺠﻤﻮﻋﻪ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻛﻼس 929.............................................................................. :.NET Framework ﺳﻴﺴﺘﻢ ﻧﻮع داده اي ﻋﻤﻮﻣﻲ931........................................................................................................ : ﺧﺼﻮﺻﻴﺎت ﻋﻤﻮﻣﻲ زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ933......................................................................................... :
ﺿﻤﻴﻤﻪ :4ﻣﺪﻳﺮﻳﺖ ﺣﺎﻓﻈﻪ در 935 .............................................................. .NET درك ﻣﺒﺎﻧﻲ ﻛﺎر 935....................................................................................... :Garbage Collector اﻟﮕﻮرﻳﺘﻢ 938............................................................................................. :Garbage Collection ارﺟﺎع ﻫﺎي ﺿﻌﻴﻒ942.................................................................................................................. : ﻧﺴﻠﻬﺎ944................................................................................................................................ : دﻳﮕﺮ ﻧﺘﺎﻳﺞ ﻛﺎراﻳﻲ 948.................................................................................... :Garbage Collector اﺷﻴﺎي ﺑﺰرگ950........................................................................................................................ :
١٧
ﻓﺼﻞ اول :ﺑﻪ وﻳﮋوال 2005 C#ﺧﻮش آﻣﺪﻳﺪ ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺮاي ﻳﻚ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﻤﺎﻧﻨﺪ ﻳﺎد دادن ﮔﺮه زدن ﺑﻨﺪ ﻛﻔﺶ ﺑﻪ ﻳﻚ ﻛﻮدك اﺳﺖ .ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﺷﻤﺎ ﻧﺘﻮاﻧﻴﺪ درﺳﺖ ﻣﺮاﺣﻞ ﻛـﺎر را ﺑﻴﺎن ﻛﻨﻴﺪ ،ﻫﻴﭻ ﻛﺎري اﻧﺠﺎم ﻧﻤﻲ ﺷﻮد .وﻳﮋوال 2005 C#ﻳﻚ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آن ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻛـﺎﻣﭙﻴﻮﺗﺮ ﺧﻮد ﺑﮕﻮﻳﻴﺪ ﭼﻪ ﻛﺎرﻫﺎﻳﻲ را اﻧﺠﺎم دﻫﺪ .اﻣﺎ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻧﻴﺰ ﻣﺎﻧﻨﺪ ﻳﻚ ﻛﻮدك اﺳﺖ و ﻓﻘﻂ ﻛﺎرﻫﺎﻳﻲ را ﻣﻲ ﺗﻮاﻧﺪ اﻧﺠﺎم دﻫﺪ ﻛﻪ ﻣﺮاﺣﻞ آن ﺑﻪ وﺿﻮح ﻣﺸﺨﺺ ﺷﻮﻧﺪ .اﮔﺮ ﺗﺎ ﻛﻨﻮن ﻫﻴﭻ ﺑﺮﻧﺎﻣﻪ اي ﻧﻨﻮﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻣﻤﻜﻦ اﺳﺖ اﻳﻦ ﻛﺎر ﺑﺴﻴﺎر ﻣﺸﻜﻞ ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ ،اﻟﺒﺘﻪ در ﺑﻌﻀﻲ ﻣﻮاﻗﻊ ﻧﻴﺰ ﺑﻪ ﻫﻤﻴﻦ ﺻﻮرت اﺳﺖ .اﻣﺎ ﺧﻮﺷﺒﺨﺘﺎﻧﻪ ،وﻳﮋوال 2005 C#زﺑﺎﻧﻲ اﺳﺖ ﻛﻪ ﺳﻌﻲ ﻛﺮده اﺳﺖ اﻳﻦ ﻣﻮﺿﻮع را ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﺳﺎده ﻛﻨﺪ و ﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣﻲ دﻫﺪ ﺗﺎ ﻛﺎرﻫﺎي ﺑﺴﻴﺎر ﻣﺸﻜﻞ را ﺑﻪ ﺳﺎدﮔﻲ اﻧﺠﺎم دﻫﻴﺪ .درك اﺗﻔﺎﻗﺎﺗﻲ ﻛﻪ در ﺳﻄﻮح ﭘﺎﻳﻴﻦ ﺑﺮاي اﺟﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ رخ ﻣﻲ دﻫﺪ ﻫﻴﭻ وﻗﺖ ﺿﺮري ﻧﺪاﺷﺘﻪ اﺳﺖ ،اﻣﺎ در وﻳﮋوال 2005 C#ﺑﺮاي ﻧﻮﺷﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺎزي ﺑﻪ درﮔﻴﺮي ﺑﺎ ﻣﺴﺎﺋﻠﻲ از اﻳـﻦ ﻗﺒﻴـﻞ ﻧﺪارﻳﺪ و ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ راﺣﺘﻲ ﺑﺮ اﻟﮕﻮرﻳﺘﻢ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﻨﻮﻳﺴﻴﺪ ﺗﻤﺮﻛﺰ ﻛﻨﻴﺪ. ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي وﻳﮋوال 2005 C#ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮﻧﺪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﺮ روي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ وﻳﻨﺪوز اﺟﺮا ﺷﻮﻧﺪ .ﺣﺘﻲ اﮔﺮ ﺗـﺎﻛﻨﻮن ﻫﻴﭻ ﺑﺮﻧﺎﻣﻪ اي ﺑﺮاي ﻛﺎﻣﭙﻴﻮﺗﺮ ﻧﻨﻮﺷﺘﻪ ﺑﺎﺷﻴﺪ ،در ﻃﻮل ﻛﺘﺎب و اﺟﺮاي ﺗﻤﺮﻳﻨﺎت ﺑﺨﺶ "اﻣﺘﺤﺎن ﻛﻨﻴﺪ" ،ﺑﻴﺸﺘﺮ ﺑﺎ ﺟﻨﺒﻪ ﻫﺎي ﻣﺨﺘﻠﻒ اﻳﻦ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ و ﻫﻤﭽﻨﻴﻦ .NET Frameworkآﺷﻨﺎ ﻣﻲ ﺷﻮﻳﺪ .ﺑﻪ زودي ﻣﺘﻮﺟﻪ ﺧﻮاﻫﻴﺪ ﺷﺪ ﻛـﻪ ﺑﺮﻧﺎﻣـﻪ ﻧﻮﻳـﺴﻲ ﺑـﺮاي ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﻪ اﻳﻦ اﻧﺪازه ﻛﻪ ﺗﺼﻮر ﻣﻲ ﻛﻨﻴﺪ ،ﻣﺸﻜﻞ ﻧﻴﺴﺖ .ﺑﻌﺪ از ﻣﺪت ﻛﻤﻲ ﻛﻪ ﺑﺎ آن آﺷﻨﺎ ﺷﺪﻳﺪ ،ﺑﻪ راﺣﺘـﻲ ﻣـﻲ ﺗﻮاﻧﻴـﺪ اﻧـﻮاع ﻣﺨﺘﻠـﻒ ﺑﺮﻧﺎﻣﻪ ﻫﺎ را ﺑﺎ وﻳﮋوال 2005 C#اﻳﺠﺎد ﻛﻨﻴﺪ .وﻳﮋوال ) 2005 C#ﻫﻤﺎﻧﻄﻮر ﻛﻪ از اﺳﻢ .NETﻣﺸﺨﺺ اﺳﺖ( ﻣﻴﺘﻮاﻧﺪ ﺑـﺮاي اﻳﺠـﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺎﺑﻞ اﺳﺘﻔﺎده در اﻳﻨﺘﺮﻧﺖ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد .ﺷﻤﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﻳﻦ زﺑﺎن ﺑﻪ راﺣﺘـﻲ ﺑـﺮاي دﺳـﺘﮕﺎه ﻫـﺎي ﻣﻮﺑﺎﻳـﻞ و ﻳـﺎ PocketPCﻫﺎ ﺑﺮﻧﺎﻣﻪ ﺑﻨﻮﻳﺴﻴﺪ .ﻧﻮﺷﺘﻦ اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ آﻧﻘﺪر ﺳﺎده اﺳﺖ ﻛﻪ در ﭘﺎﻳﺎن اﻳﻦ ﻛﺘﺎب ،ﺑﺮاي ﻧﻤﻮﻧﻪ ﻳﻚ ﺑﺮﻧﺎﻣـﻪ ﺑـﺮاي اﻳﻦ دﺳﺘﮕﺎه ﻫﺎ ﺧﻮاﻫﻴﻢ ﻧﻮﺷﺖ .اﻣﺎ اﺣﺘﻤﺎﻻً ﺑﺎ اﻳﻦ ﻧﻜﺘﻪ ﻣﻮاﻓﻘﻴﺪ ﻛﻪ ﻗﺒﻞ از ﻳﺎدﮔﻴﺮي دوﻳﺪن ،ﺑﺎﻳﺪ راه رﻓﺘﻦ را آﻣﻮﺧـﺖ .ﺑﻨـﺎﺑﺮاﻳﻦ در اﻳـﻦ ﻗﺴﻤﺖ از ﻛﺘﺎب در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ وﻳﻨﺪوز ﺗﻤﺮﻛﺰ ﻣﻲ ﻛﻨﻴﻢ. در اﻳﻦ ﻓﺼﻞ:
ﻧﺼﺐ وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005 ﮔﺸﺘﻲ در ﻣﺤﻴﻂ ﺗﻮﺳﻌﻪ ﻣﺘﻤﺮﻛﺰ ) (IDEوﻳﮋوال 2005 C# ﭼﮕﻮﻧﮕﻲ اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺳﺎده ﺗﺤﺖ وﻳﻨﺪوز ﭼﮕﻮﻧﮕﻲ اﺳﺘﻔﺎده از ﺳﻴﺴﺘﻢ راﻫﻨﻤﺎي ﺟﺎﻣﻊ وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005
ﻧﺼﺐ وﻳﮋوال :2005 C# ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ و وﻳﮋوال C#را ﺷﺮوع ﻛﻨﻴﻢ ،ﺑﺎﻳﺪ آن را در ﻛﺎﻣﭙﻴﻮﺗﺮ ﺧﻮدئ ﻧﺼﺐ ﻛﻨـﻴﻢ .وﻳـﮋوال C# ﺑﻪ گ.ﻧﻪ ﻫﺎي ﻣﺨﺘﻠﻔﻲ ﺑﻪ وﺳﻴﻠﻪ ي ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ اراﺋﻪ ﺷﺪه اﺳﺖ .ﻧﺴﺨﻪ ي وﻳﮋوال C#اي ﻛﻪ ﺷﻤﺎ از آن اﺳﺘﻔﺎده ﻣـﻲ ﻛﻨﻴـﺪ ،ﻣﻤﻜـﻦ اﺳﺖ ﺑﻪ ﻳﻜﻲ از ﺣﺎﻟﺘﻬﺎي زﻳﺮ ﺑﺎﺷﺪ:
ﺑﻪ ﻋﻨﻮان ﺑﺨﺸﻲ از وﻳﮋوال اﺳﺘﻮدﻳﻮ ،2005ﻛﻪ ﻳﻚ ﻣﺠﻤﻮﻋﻪ ﺷﺎﻣﻞ اﺑﺰارﻫﺎ و زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳـﺴﻲ اﺳـﺖ :اﻳـﻦ ﻣﺠﻤﻮﻋـﻪ ﻫﻤﭽﻨــﻴﻦ ﺷــﺎﻣﻞ وﻳــﮋوال ﺑﻴــﺴﻴﻚ J# ،و ﻧﻴــﺰ Visual C++ﻣﻴــﺸﻮد .وﻳــﮋوال اﺳــﺘﻮدﻳﻮ در ﻧــﺴﺨﻪ ﻫــﺎي Tools For Office، Professional ،Standardو وﻳـﮋوال اﺳـﺘﻮدﻳﻮ Team
١٨
Systemﻣﻨﺘﺸﺮ ﺷﺪه اﺳﺖ .ﻫﺮ ﻛﺪام از اﻳﻦ ﻧﺴﺨﻪ ﻫﺎ ﻧﺴﺒﺖ ﺑﻪ ﻧﺴﺨﻪ ﻗﺒﻠﻲ از اﻣﻜﺎﻧﺎت و اﺑﺰارﻫﺎي ﺑﻴﺸﺘﺮي ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻬﺮه ﻣﻨﺪ ﻫﺴﺘﻨﺪ. ﺑﻪ ﻋﻨﻮان ﻧﮕﺎرش :Expressاﻳﻦ ﻧﮕﺎرش ﻧﺴﺨﻪ اي از وﻳﮋوال C#اﺳﺖ ﻛﻪ ﺷﺎﻣﻞ ﻳﻚ ﺳﺮي اﻣﻜﺎﻧـﺎت و وﻳﮋﮔﻴﻬـﺎي ﻣﺤﺪود ﻣﻮﺟﻮد در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻣﻴﺸﻮد.
ﻫﺮ دوي اﻳﻦ ﻧﺴﺨﻪ ﻫﺎ از C#ﺑﻪ ﺷﻤﺎ اﻳﻦ اﻣﻜﺎن را ﻣﻲ دﻫﺪ ﺗﺎ ﺑﺮاي وﻳﻨﺪوز ﺑﺮﻧﺎﻣﻪ ﺑﻨﻮﻳﺴﻴﺪ .ﻣﺮاﺣﻞ ﻧـﺼﺐ ﻫـﺮ دوي آﻧﻬـﺎ ﻧﻴـﺰ ﻛـﺎﻣ ً ﻼ واﺿﺢ اﺳﺖ .در ﺣﻘﻴﻘﺖ ،ﺑﺎﻳﺪ ﮔﻔﺖ ﻛﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ آﻧﻘﺪر ﺑﺎﻫﻮش اﺳﺖ ﻛﻪ ﺑﻔﻬﻤـﺪ ﺑـﺮاي اﺟـﺮا ﺷـﺪن روي ﻛـﺎﻣﭙﻴﻮﺗﺮ ﺷـﻤﺎ ﺑـﻪ ﭼـﻪ ﭼﻴﺰﻫﺎﻳﻲ ﻧﻴﺎز دارد. ﺗﻮﺿﻴﺤﺎﺗﻲ ﻛﻪ در ﺑﺨﺶ "اﻣﺘﺤﺎن ﻛﻨﻴﺪ" زﻳﺮ آﻣﺪه اﺳﺖ ،ﺑﺮاي ﻧﺼﺐ وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﻧﺴﺨﻪ ي Team Systemاﺳـﺖ. ﺑﻴﺸﺘﺮ ﻗﺴﻤﺘﻬﺎي ﻧﺼﺐ ﻛﺎﻣﻼً واﺿﺢ ﻫﺴﺘﻨﺪ و ﻓﻘﻂ ﺑﺎﻳﺪ ﮔﺰﻳﻨﻪ ﻫﺎي ﭘﻴﺶ ﻓـﺮض را اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ .ﺑﻨـﺎﺑﺮاﻳﻦ ﺻـﺮف ﻧﻈـﺮ از اﻳﻨﻜـﻪ از ﻛﺪاﻣﻴﻚ از ﻧﮕﺎرش ﻫﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ،اﮔﺮ ﻫﻨﮕﺎم ﻧﺼﺐ ﮔﺰﻳﻨﻪ ﻫﺎي ﭘﻴﺶ ﻓﺮض را اﻧﺘﺨﺎب ﻛﻨﻴﺪ ،در ﻧـﺼﺐ ﺑﺮﻧﺎﻣـﻪ ﻧﺒﺎﻳﺪ ﻣﺸﻜﻠﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻧﺼﺐ وﻳﮋوال 2005 C# (1
(2
(3 (4
ﺑﺎ ﻗﺮار دادن CDوﻳﮋوال اﺳﺘﻮدﻳﻮ 2005در دراﻳﻮ ،ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﺟﺮا ﻣﻲ ﺷـﻮد .اﻣـﺎ اﮔـﺮ اﺟـﺮا ﻧـﺸﺪ ﻣﻴﺘﻮاﻧﻴﺪ ﻓﺎﻳﻞ setup.exeرا از درون دراﻳﻮ اﺟﺮا ﻛﻨﻴﺪ .ﺑﺮاي اﻳـﻦ ﻛـﺎر ﺑـﻪ ﻣﻨـﻮي Startﺑﺮوﻳـﺪ و روي ﮔﺰﻳﻨـﻪ Runﻛﻠﻴﻚ ﻛﻨﻴﺪ .در ﭘﻨﺠﺮه اي ﻛﻪ ﺑﺎز ﻣﻴﺸﻮد D:\setup.exe ،را ﺗﺎﻳﭗ ﻛﻨﻴﺪ ) Dﻧﺎم دراﻳﻮ ي اﺳﺖ ﻛﻪ CDﻳﺎ DVDوﻳﮋوال اﺳﺘﻮدﻳﻮ در آن ﻗﺮار دارد( .ﺑﻌﺪ از اﺟﺮاي ﺑﺮﻧﺎﻣﻪ Setupﺑﺎﻳﺪ ﺻﻔﺤﻪ اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 1-1ﺑﺒﻴﻨﻴﺪ. اﻳﻦ ﭘﻨﺠﺮه ﻣﺮاﺣﻠﻲ را ﻛﻪ ﺑﺮاي ﻧﺼﺐ ﺑﺎﻳﺪ ﻃﻲ ﻛﻨﻴﺪ ﻧﺸﺎن ﻣﻲ دﻫﺪ .ﺑﺮاي اﺟﺮاي درﺳﺖ ﻓﺮآﻳﻨﺪ ﻧﺼﺐ ،وﻳﮋوال اﺳـﺘﻮدﻳﻮ ﻧﻴـﺎز دارد ﻛﻪ ﻳﻚ ﺳﺮي از ﺑﺮﻧﺎﻣﻪ ﻫﺎي روي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ را ﺑﻪ روز رﺳﺎﻧﻲ ﻛﻨﺪ ﻣﺜﻞ ﺳﺮوﻳﺲ ﭘﻚ 1ﺑﺮاي وﻳﻨﺪوز .XPﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ،ﻟﻴﺴﺘﻲ از ﻣﻮاردي را ﻛﻪ ﺑﺎﻳﺪ در ﺳﻴﺴﺘﻢ ﺑﻪ روز رﺳﺎﻧﺪه ﺷﻮﻧﺪ را ﺑﻪ ﺷﻤﺎ ﻧﺸﺎن ﻣﻲ دﻫﺪ و ﺷـﻤﺎ ﺑﺎﻳـﺪ ﻗﺒـﻞ از اداﻣـﻪ ي ﻧﺼﺐ وﻳﮋوال اﺳﺘﻮدﻳﻮ ،اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ را ﻧﺼﺐ ﻛﻨﻴﺪ .ﺑﻌﺪ از اﻳﻨﻜﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺗﻐﻴﻴﺮات ﻻزم در ﺳﻴﺴﺘﻢ را اﻧﺠـﺎم داد ،وارد ﻧﺼﺐ ﺧﻮد ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺷﻮﻳﻢ .ﺑﺮاي اﻳﻦ ﻣﺮﺣﻠﻪ روي ﻟﻴﻨﻚ Install Visual Studioﻛﻠﻴﻚ ﻛﻨﻴﺪ. ﺑﻌﺪ از ﻗﺒﻮل ﻛﺮدن ﻗﺮارداد ﻧﻮﺷﺘﻪ ﺷﺪه ﺗﻮﺳﻂ ﺷﺮﻛﺖ ،روي Continueﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑﻪ ﻣﺮﺣﻠﻪ ﺑﻌﺪ ﺑﺮوﻳﺪ. در اﻳﻦ ﻣﺮﺣﻠﻪ ﻧﻮع ﻫﺎي ﻣﺨﺘﻠﻔﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ وﻳﮋوال اﺳﺘﻮدﻳﻮ را ﺑﻪ آن ﺻﻮرت ﻧﺼﺐ ﻛﻨﻴﺪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺳﻪ ﮔﺰﻳﻨﻪ ي ﻣﺨﺘﻠﻒ را در اﻳﻦ ﻗﺴﻤﺖ در اﺧﺘﺎر ﺷﻤﺎ ﻗﺮار ﻣﻲ دﻫﺪ ﻛﻪ ﻋﺒﺎرﺗﻨﺪ از: :Defaultاﻳﻦ ﮔﺰﻳﻨﻪ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺎ اﺑﺰارﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ﺻـﻮرت ﭘـﻴﺶ ﻓـﺮض اﻧﺘﺨـﺎب ﺷـﺪه اﻧـﺪ در ﺳﻴﺴﺘﻢ ﻧﺼﺐ ﺷﻮﻧﺪ. :Fullﺑﺎ اﻧﺘﺨﺎب اﻳﻦ ﮔﺰﻳﻨﻪ ،وﻳﮋوال اﺳﺘﻮدﻳﻮ و ﺗﻤﺎم اﺑﺰارﻫﺎي ﺟﺎﻧﺒﻲ آن ﺑﻪ ﺻﻮرت ﻛﺎﻣـﻞ در ﺳﻴـﺴﺘﻢ ﺷـﻤﺎ ﻧـﺼﺐ ﻣـﻲ ﺷﻮﻧﺪ .اﮔﺮ از ﻧﻈﺮ ﻓﻀﺎﻳﻲ ﻛﻪ ﺑﺎ اﻧﺘﺨﺎب اﻳﻦ ﮔﺰﻳﻨﻪ در ﺳﻴﺴﺘﻢ ﺷﻤﺎ اﺷﻐﺎل ﻣﻲ ﺷﻮد ﻣﺸﻜﻠﻲ ﻧﺪارﻳـﺪ ،ﺑﻬﺘـﺮ اﺳـﺖ ﻛـﻪ ﻫﻨﮕـﺎم ﻧﺼﺐ اﻳﻦ ﮔﺰﻳﻨﻪ را اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﻪ ﺻﻮرت ﻛﺎﻣﻞ ﻧﺼﺐ ﺷﻮد. :Customﺑﺎ اﻧﺘﺨﺎب اﻳﻦ ﮔﺰﻳﻨﻪ ،ﻟﻴﺴﺘﻲ از ﺗﻤﺎم ﻗﺴﻤﺘﻬﺎي ﻣﻮﺟﻮد در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ و ﻣﻲ ﺗﻮاﻧﻴـﺪ اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﻛﻪ ﻛﺪام ﻗﺴﻤﺘﻬﺎ ﺑﺎﻳﺪ ﻧﺼﺐ ﺷﻮﻧﺪ و ﻛﺪاﻣﻴﻚ ﻧﺒﺎﻳﺪ ﻧﺼﺐ ﺷﻮﻧﺪ.
١٩
در اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﺮاي اﻳﻨﻜﻪ ﺑﺎ ﻗﺴﻤﺘﻬﺎي ﻣﻮﺟﻮد در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﻴﺰ آﺷﻨﺎ ﺷﻮﻳﻢ ،ﮔﺰﻳﻨﻪ ي Customرا اﻧﺘﺨﺎب ﻛـﺮده و دﻛﻤﻪ ي Nextرا ﻓﺸﺎر دﻫﻴﺪ. (5ﺑﺎ وارد ﺷﺪن ﺑﻪ اﻳﻦ ﻗﺴﻤﺖ ،ﻟﻴﺴﺖ اﺟﺰاي وﻳﮋوال اﺳﺘﻮدﻳﻮ را ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻧﺼﺐ ﻛﻨﻴﺪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛـﺮد .ﺑـﺪﻳﻦ ﺗﺮﺗﻴـﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻓﻘﻂ ﻗﺴﻤﺘﻬﺎﻳﻲ را ﻛﻪ ﺑﻪ آﻧﻬﺎ ﻧﻴﺎز دارﻳﺪ ﻧﺼﺐ ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻓﻀﺎي دﻳـﺴﻚ ﺷـﻤﺎ ﻛـﻢ اﺳـﺖ و از وﻳـﮋوال 2005 C++اﺳﺘﻔﺎده ﻧﻤﻲ ﻛﻨﻴﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ آن را ﻧﺼﺐ ﻧﻜﻨﻴﺪ .در اﻳﻦ ﻗﺴﻤﺖ ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﻜﺎن ﻧﺼﺐ ﺑﺮﻧﺎﻣﻪ را ﻧﻴـﺰ ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ )ﻣﻌﻤﻮﻻ ﻣﻜﺎن اوﻟﻴﻪ ﻣﻨﺎﺳﺐ اﺳﺖ ،ﻣﮕﺮ آﻧﻜﻪ ﺑﻪ دﻟﻴﻞ ﺧﺎﺻﻲ ﺑﺨﻮاﻫﻴﺪ آن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ( .ﺗﻤﺎم ﻗﺴﻤﺘﻬﺎﻳﻲ را ﻛـﻪ در اﻳﻦ ﻣﺮﺣﻠﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﺑﻌﺪاً ﻧﻴﺰ ﻣﻴﺘﻮاﻧﻨﺪ ﻧﺼﺐ ﺷﺪه و ﻳﺎ از ﺣﺎﻟﺖ ﻧﺼﺐ ﺧﺎرج ﺷﻮﻧﺪ .اﻟﺒﺘﻪ اﮔـﺮ ﻣـﻲ ﺧﻮاﻫﻴـﺪ ﺑﺮﻧﺎﻣـﻪ ﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﻨﻮﻳﺴﻴﺪ ،ﻫﻤﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ در ﻓﺼﻞ 16ﺗﻮﺿﻴﺢ داده ﺷﺪه اﻧـﺪ ،در اﻳـﻦ ﻗـﺴﻤﺖ ﺑﺎﻳـﺪ SQL Server 2005 Expressﻛﻪ آﺧﺮﻳﻦ ﮔﺰﻳﻨﻪ ي ﻟﻴﺴﺖ اﺳﺖ را ﻧﻴﺰ اﻧﺘﺨﺎب ﻛﻨﻴﺪ.
ﺷﻜﻞ 1-1 ﺑﺮاي ﻫﺮ ﮔﺰﻳﻨﻪ از ﻟﻴﺴﺖ ﺳﻪ ﻗﺴﻤﺖ وﺟﻮد دارﻧﺪ ﻛﻪ اﻃﻼﻋﺎت آن را ﻧﻤﺎﻳﺶ ﻣﻴﺪﻫﻨﺪ:
ﻗﺴﻤﺖ Feature Descriptionﻳﻚ ﻃﺮح ﻛﻠﻲ و ﻛﺎراﻳﻲ ﻗﺴﻤﺖ اﻧﺘﺨﺎب ﺷﺪه را ﺷﺮح ﻣﻴﺪﻫﺪ. ﻗﺴﻤﺖ Feature Install Pathﻣﻜﺎﻧﻲ ﻛـﻪ ﻓﺎﻳﻠﻬـﺎي ﺑﺨـﺶ اﻧﺘﺨـﺎب ﺷـﺪه در آن ﻧـﺼﺐ ﻣﻴﺸﻮﻧﺪ را ﻧﻤﺎﻳﺶ ﻣﻴﺪﻫﺪ. در ﻧﻬﺎﻳﺖ ،ﻗﺴﻤﺖ Disk Space Requirementsﺑﻪ ﺷﻤﺎ ﻧﺸﺎن ﻣﻴﺪﻫﺪ ﻛﻪ ﺑﺎ ﻧـﺼﺐ ﺑﺨـﺶ اﻧﺘﺨﺎب ﺷﺪه ،ﻓﻀﺎي دﻳﺴﻚ ﺷﻤﺎ ﭼﮕﻮﻧﻪ ﺗﻐﻴﻴﺮ ﻣﻲ ﻛﻨﺪ.
٢٠
ﺑﻌﺪ از اﻳﻨﻜﻪ ﻧﺼﺐ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﻪ ﭘﺎﻳﺎن رﺳﻴﺪ ،زﻣﺎﻧﻲ ﻛﻪ وﻳﮋوال 2005 C#را اﺟﺮا ﻣﻲ ﻛﻨﻴﺪ اﻃﻼﻋﺎت زﻳﺎدي از دﻳﺴﻚ ﺑﻪ ﺣﺎﻓﻈﻪ و ﺑﺮﻋﻜﺲ ﻣﻨﺘﻘﻞ ﻣﻲ ﺷﻮﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ داﺷﺘﻦ ﻣﻘﺪاري ﻓﻀﺎي ﺧﺎﻟﻲ در دﻳﺴﻚ ﺑﺮاي ﻛﺎر ﺿﺮوري اﺳﺖ .ﺗﻌﻴﻴﻦ ﻣﻘﺪار دﻗﻴﻖ ﻓﻀﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺮاي اﻳﻦ ﻣﻮرد ،اﻣﻜﺎن ﭘﺬﻳﺮ ﻧﻴﺴﺖ .اﻣﺎ اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ از اﻳﻦ ﺳﻴﺴﺘﻢ ﺑـﺮاي ﺑﺮﻧﺎﻣـﻪ ﻧﻮﻳـﺴﻲ اﺳـﺘﻔﺎده ﻛﻨﻴﺪ ،ﺣﺪاﻗﻞ ﺑﻪ 100ﻣﮕﺎ ﺑﺎﻳﺖ ﻓﻀﺎي ﺧﺎﻟﻲ ﻧﻴﺎز دارﻳﺪ.
ﺷﻜﻞ 2-1 (6ﺑﻌﺪ از اﻧﺘﺨﺎب ﻗﺴﻤﺘﻬﺎﻳﻲ ﻛﻪ ﻣﻴﺨﻮاﻫﻴﺪ ﻧﺼﺐ ﻛﻨﻴﺪ ،روي ﮔﺰﻳﻨﻪ Installﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺣـﺎﻻ ﺷـﻤﺎ ﻣﻴﺘﻮاﻧﻴـﺪ ﻣﻘـﺪاري اﺳﺘﺮاﺣﺖ ﻛﻨﻴﺪ ،ﺗﺎ ﺑﺮﻧﺎﻣﻪ ﺑﺮ روي ﺳﻴﺴﺘﻢ ﻧﺼﺐ ﺷﻮد .زﻣﺎن ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﻧﺼﺐ ﺑﺮﻧﺎﻣﻪ ﺑﺴﺘﻪ ﺑﻪ ﻗﺴﻤﺘﻬﺎﻳﻲ ﻛﻪ ﺑـﺮاي ﻧـﺼﺐ اﻧﺘﺨﺎب ﻛﺮده اﻳﺪ ﻣﺘﻔﺎوت اﺳﺖ .وﻟﻲ ﻧﺼﺐ ﺑﺮﻧﺎﻣﻪ در ﻳﻚ ﺳﻴﺴﺘﻢ ﺑﺎ ﭘﺮدازﻧﺪه ي 2,4ﮔﻴﮕﺎ ﻫﺮﺗﺰ و 512ﻣﮕﺎ ﺑﺎﻳﺖ ﺣﺎﻓﻈـﻪ ﺑـﺎ وﻳﻨﺪوز XPﻧﺴﺨﻪ Professionalﺣﺪود 20دﻗﻴﻘﻪ ﻃﻮل ﻣﻴﻜﺸﺪ. (7ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻧﺼﺐ ﺑﺮﻧﺎﻣﻪ ﺗﻤﺎم ﺷﺪ ،ﺻﻔﺤﻪ اي را ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﭘﺎﻳﺎن ﻧﺼﺐ را اﻃﻼع ﻣﻴﺪﻫﺪ .در اﻳﻦ ﻣﺮﺣﻠـﻪ ،ﺑﺮﻧﺎﻣـﻪ ي ﻧﺼﺐ ﻫﺮ ﻣﺸﻜﻠﻲ ﻛﻪ ﺑﺎ آن روﺑﺮو ﺷﺪه ﺑﺎﺷﺪ را ﮔﺰارش ﻣﻲ دﻫﺪ .ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﻣﺮﺣﻠﻪ ﻣﻴﺘﻮاﻧﻴﺪ ﮔﺰارش ﻋﻤﻠﻜﺮد ﻧـﺼﺐ را ﻧﻴﺰ ﺑﺮرﺳﻲ ﻛﻨﻴﺪ .در اﻳﻦ ﮔﺰارش ﺗﻤﺎم ﻛﺎرﻫﺎﻳﻲ ﻛﻪ در ﻃﻮل ﻧﺼﺐ ﺑﺮﻧﺎﻣﻪ اﻧﺠﺎم ﺷﺪه ،ﻧﻮﺷﺘﻪ ﺷـﺪه اﺳـﺖ .اﻳـﻦ ﮔـﺰارش در ﻣﻮاﻗﻌﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻧﺼﺐ ﺑﺎ ﻣﺸﻜﻞ روﺑﺮو ﻣﻲ ﺷﻮد ،ﻣﻲ ﺗﻮاﻧﺪ ﻣﻔﻴﺪ ﺑﺎﺷﺪ .ﺧﻮب ،ﺑﺪﻳﻦ ﺗﺮﺗﻴـﺐ ﻧـﺼﺐ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ 2005 ﺗﻤﺎم ﺷﺪ .روي ﮔﺰﻳﻨﻪ Doneﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ وارد ﺑﺨﺶ ﻧﺼﺐ ﻣﺴﺘﻨﺪات ﻳﺎ راﻫﻨﻤﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺷﻮﻳﻢ. (8ﻧﺼﺐ MSDN Libraryﻛﺎﻣﻼً ﺳﺎده و واﺿﺢ اﺳﺖ و در اﻳﻦ ﺑﺨﺶ ﻓﻘﻂ ﻗﺴﻤﺘﻬﺎي ﻣﻬﻢ آن را ذﻛﺮ ﻣﻲ ﻛﻨﻴﻢ .اوﻟﻴﻦ ﺻﻔﺤﻪ اي ﻛﻪ در اﻳﻦ ﻣﺮﺣﻠﻪ ﻣﻴﺒﻴﻨﻴﺪ ،ﺻﻔﺤﻪ ﺧﻮش آﻣﺪ ﮔﻮﻳﻲ اﺳﺖ .ﺑﺮاي اداﻣﻪ ﻛﺎر روي Nextﻛﻠﻴﻚ ﻛﻨﻴﺪ.
٢١
(9ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ 3-1ﻧﺸﺎن داده ﺷﺪه اﺳﺖ ،ﺑﻪ ﺷﻤﺎ اﺟﺎزه داده ﻣﻲ ﺷﻮد ﻛﻪ ﻣﻘﺪار ﻣﺴﺘﻨﺪاﺗﻲ ﻛـﻪ ﻣـﻲ ﺧﻮاﻫﻴـﺪ ﻧـﺼﺐ ﻛﻨﻴﺪ را ﻣﺸﺨﺺ ﻛﻨﻴﺪ .ﺑﺮاي ﺷﺮوع ﻧﺼﺐ روي ﮔﺰﻳﻨﻪ Nextﻛﻠﻴﻚ ﻛﻨﻴﺪ. اﮔﺮ دﻳﺴﻚ ﺷﻤﺎ ﻓﻀﺎي ﻛﺎﻓﻲ دارد ،ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ MSDNرا ﺑﻪ ﺻﻮرت ﻛﺎﻣﻞ ﻧﺼﺐ ﻛﻨﻴﺪ .ﺑﺪﻳﻦ ﺗﺮﺗﻴﺐ ﺑﻪ ﺗﻤـﺎم اﻃﻼﻋـﺎت اﻳﻦ ﻛﺘﺎﺑﺨﺎﻧﻪ دﺳﺘﺮﺳﻲ ﺧﻮاﻫﻴﺪ داﺷﺖ .اﻳﻦ ﻣﻮرد ﺑﻪ ﺧﺼﻮص در ﻣﻮاﻗﻌﻲ ﻛﻪ ﻓﻘﻂ ﻗﺴﻤﺘﻲ از وﻳﮋوال اﺳﺘﻮدﻳﻮ را ﻧـﺼﺐ ﻛـﺮده اﻳﺪ و ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﻌﺪا ﻗﺴﻤﺘﻬﺎي دﻳﮕﺮي را ﻧﻴﺰ ﻧﺼﺐ ﻛﻨﻴﺪ ،ﺑﺴﻴﺎر ﻣﻔﻴﺪ ﺧﻮاﻫﺪ ﺑﻮد. (10ﺑﻌﺪ از اﻳﻨﻜﻪ ﻧﺼﺐ MSDNﺑﻪ ﭘﺎﻳﺎن رﺳﻴﺪ ،ﺑﻪ ﺻﻔﺤﻪ اول ﺑـﺎز ﺧﻮاﻫﻴـﺪ ﮔـﺸﺖ .در اﻳـﻦ ﻣﺮﺣﻠـﻪ ﮔﺰﻳﻨـﻪ Service Releasesﻧﻴﺰ ﻓﻌﺎل ﺧﻮاﻫﺪ ﺑﻮد.
ﺷﻜﻞ 3-1 ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻦ ﮔﺰﻳﻨﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻧﺴﺨﻪ ﻫﺎي Updateاﻳﻦ ﺑﺮﻧﺎﻣﻪ را ﺑﺎ اﺳﺘﻔﺎده از اﻳﻨﺘﺮﻧﺖ درﻳﺎﻓﺖ ﻛﻨﻴﺪ .اﻳﻦ ﻧﺴﺨﻪ ﻫﺎ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺷﺎﻣﻞ ﻫﺮ ﭼﻴﺰي ،از ﻣﺴﺘﻨﺪات اﺿﺎﻓﻲ ﺗﺎ ﺗﻌﻤﻴﺮ ﺧﻄﺎﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ ﺑﺎﺷﻨﺪ .ﺑﺮاي درﻳﺎﻓﺖ آﻧﻬﺎ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ از اﻳﻨﺘﺮﻧﺖ و ﻳﺎ از ﺑﺴﺘﻪ ﻫﺎي Service Packاﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻟﺒﺘﻪ ﻣﺸﺨﺺ اﺳﺖ ﻛﻪ ﺑﺮاي ﻧﺼﺐ اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎ از ﻃﺮﻳﻖ اﻳﻨﺘﺮﻧﺖ ،ﺑﺎﻳﺪ ﻳﻚ اﺗﺼﺎل ﻓﻌﺎل ﺑﻪ اﻳﻨﺘﺮﻧﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ و ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ اﻳﻦ اﺗﺼﺎل ﺳﺮﻳﻊ ﺑﺎﺷﺪ ،ﭼﻮن ﺣﺠﻢ اﻳﻦ ﺑـﺴﺘﻪ ﻫﺎ ﻣﻌﻤﻮﻻ زﻳﺎد اﺳﺖ. ﺑﻌﺪ از ﻃﻲ ﻛﺮدن ﻣﺮاﺣﻞ ﺑﺎﻻ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﺼﺐ ﺷﺪه و آﻣﺎده اﺳﺘﻔﺎده اﺳﺖ .از اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺑﻌﺪ ﺗﻔﺮﻳﺢ واﻗﻌﻲ ﺷـﺮوع ﻣﻴـﺸﻮد! ﭘـﺲ اﺟﺎزه ﺑﺪﻫﻴﺪ وارد دﻧﻴﺎي وﻳﮋوال 2005 C#ﺑﺸﻮﻳﻢ.
٢٢
ﻣﺤﻴﻂ ﺗﻮﺳﻌﻪ 1وﻳﮋوال :2005 C# در اﺑﺘﺪا ﺟﺎﻟﺐ اﺳﺖ ﺑﺪاﻧﻴﺪ ﻛﻪ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻪ زﺑﺎن ،C#ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي وﻳﮋوال 2005 C#ﻧﻴﺎزي ﻧﺪارﻳﺪ! ﺷﻤﺎ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑﺮﻧﺎﻣـﻪ ﻫﺎي ﺧﻮد را ﺑﺎ ﻳﻚ وﻳﺮاﻳﺸﮕﺮ ﻣﺘﻨﻲ ﻣﺎﻧﻨﺪ Notepadﻧﻴﺰ ﺑﻨﻮﻳﺴﻴﺪ .اﻣﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﮋوال C#ﻣﻌﻤﻮﻻ ﻃـﻮﻻﻧﻲ ﻫـﺴﺘﻨﺪ و ﻧﻮﺷـﺘﻦ آﻧﻬﺎ ﺑﺎ notepadزﻣﺎن زﻳﺎدي را ﺻﺮف ﻣﻲ ﻛﻨﺪ .اه ﺑﻬﺘﺮ ﺑﺮاي اﻧﺠﺎم اﻳﻦ ﻛﺎر اﺳﺘﻔﺎده از ﻣﺤﻴﻂ ﺗﻮﺳﻌﻪ ﻣﺠﺘﻤﻊ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻛـﻪ ﺑﻪ ﻋﻨﻮان IDEﻧﻴﺰ ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮد IDE .وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻣﻜﺎﻧﺎت ﺑﺴﻴﺎر زﻳﺎدي را در اﺧﺘﻴﺎر ﺷﻤﺎ ﻗﺮار ﻣﻲ دﻫﺪ ﻛﻪ ﻣﺴﻠﻤﺎً ﺑﺎ اﺳﺘﻔﺎده از وﻳﺮاﻳﺸﮕﺮ ﻫﺎي ﻣﺘﻨﻲ ﺑﻪ آﻧﻬﺎ دﺳﺘﺮﺳﻲ ﻧﺨﻮاﻫﻴﺪ داﺷﺖ .ﺑﺮاي ﻣﺜﺎل اﻳﻦ ﻣﺤﻴﻂ ﻣﻲ ﺗﻮاﻧﺪ درﺳﺘﻲ ﻛﺪﻫﺎي ﻧﻮﺷﺘﻪ ﺷـﺪه را ﺑﺮرﺳـﻲ ﻛﻨـﺪ، ﻗﺴﻤﺘﻬﺎي ﺗﻤﺎم ﺷﺪه از ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﺻﻮرت ﺑﺼﺮي ﻧﻤﺎﻳﺶ دﻫﺪ ،ﺧﻄﺎﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ را ﺗﺸﺨﻴﺺ دﻫﺪ و ….
ﺻﻔﺤﻪ :Profile Setup ﻳﻚ ،IDEﻣﺤﻴﻄﻲ اﺳﺖ ﺷﺎﻣﻞ ﻳﻚ ﺳﺮي اﺑﺰار ﻛﻪ ﻣﻮﺟﺐ ﺳﻬﻮﻟﺖ ﻛﺎر ﺗﻮﺳﻌﻪ و ﻃﺮاﺣﻲ ﻧﺮم اﻓﺰار ﻣﻲ ﺷﻮد .وﻳﮋوال اﺳـﺘﻮدﻳﻮ 2005را اﺟﺮا ﻛﻨﻴﺪ ﺗﺎ ﺑﺒﻴﻨﻴﺪ ﺑﺎ ﭼﻪ ﭼﻴﺰي روﺑﺮو ﻣﻲ ﺷﻮﻳﺪ .اﮔﺮ ﺷﻤﺎ ﻣﺮاﺣﻞ ﭘﻴﺶ ﻓﺮض ﻧﺼﺐ را اﻧﺘﺨﺎب ﻛﺮده اﻳـﺪ ،ﺑـﻪ ﻣﻨـﻮي اﺳـﺘﺎرت ﺑﺮوﻳـﺪ و Allدر وﻳﻨــﺪوز XPﻳــﺎ وﻳﻨــﺪوز (2003ﺳــﭙﺲ از زﻳــﺮ ﻣﻨــﻮي Programsرا اﻧﺘﺨــﺎب ﻛﻨﻴــﺪ )Programs Microsoft Visual Studio 2005ﮔﺰﻳﻨـﻪ ي Microsoft Visual Studio 2005را اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺻﻔﺤﻪ آﻏﺎزﻳﻦ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ ﺑـﻪ ﺳـﺮﻋﺖ ﻧﻤـﺎﻳﺶ داده ﻣـﻲ ﺷـﻮد و ﺑﻌـﺪ از آن ﭘﻨﺠـﺮه Choose Default Environment Settingsرا ﺧﻮاﻫﻴـﺪ دﻳـﺪ .از ﻟﻴـﺴﺖ ﻇـﺎﻫﺮ ﺷـﺪه ﮔﺰﻳﻨـﻪ Visual C# Development Settingsرا اﻧﺘﺨﺎب ﻛﺮده و روي Start Visual Studioﻛﻠﻴﻚ ﻛﻨﻴـﺪ .ﻣﺤـﻴﻂ ﺗﻮﺳﻌﻪ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 4-1ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
)Integrated Development Environment (IDE
1
٢٣
ﺷﻜﻞ 4-1
ﻣﻨﻮ: اﺣﺘﻤﺎﻻ اﺷﺘﻴﺎق زﻳﺎدي ﺑﺮاي ﺷﺮوع ﻛﺪ ﻧﻮﻳﺴﻲ دارﻳﺪ .اﻣﺎ در اﺑﺘﺪا ﺑﻬﺘﺮ اﺳﺖ ﻛﻤﻲ IDEرا ﺑﺮرﺳﻲ ﻛﻨﻴﻢ .ﮔﺮدش ﺧﻮدﻣـﺎن را در IDE از ﻣﻨﻮ ﻫﺎ و ﻧﻮارﻫﺎي اﺑﺰار ﺷﺮوع ﻣﻲ ﻛﻨﻴﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻴﺒﻴﻨﻴﺪ ،ﻣﻨﻮ ﻫﺎ و ﻧﻮار اﺑﺰارﻫﺎ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﺗﻔﺎوت ﭼﻨـﺪاﻧﻲ ﺑـﺎ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي دﻳﮕﺮ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ از ﻗﺒﻴﻞ Wordو ﻳﺎ Excelﻧﺪارد. ﻧﻮار ﻣﻨﻮي Visual Studio 2005ﺑﻪ ﺻﻮرت دﻳﻨﺎﻣﻴﻚ اﺳﺖ ،ﻳﻌﻨﻲ ﺑﺮ ﺣﺴﺐ ﻛﺎري ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ اﻧﺠﺎم دﻫﻴـﺪ ﻳـﻚ ﺳﺮي از ﮔﺰﻳﻨﻪ ﻫﺎ ﺑﻪ ﻣﻨﻮ اﺿﺎﻓﻪ ﺷﺪه و ﻳﺎ از آن ﺣﺬف ﻣﻲ ﺷﻮﻧﺪ .وﻗﺘﻲ ﻓﻘﻂ ﻣﺤﻴﻂ IDEﺧﺎﻟﻲ را در ﻣﻘﺎﺑﻞ ﺧﻮد دارﻳﺪ ،ﻣﻨـﻮي وﻳـﮋوال اﺳــﺘﻮدﻳﻮ ﺷــﺎﻣﻞ ﮔﺰﻳﻨــﻪ ﻫــﺎي Community ،Window ،Test ،Tools ،Data ،View ،Edit ،Fileو ﻣﻨﻮي Helpاﺳﺖ .اﻣﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎر ﺑﺮ روي ﻳﻚ ﭘﺮوژه را ﺷﺮوع ﻛﻨﻴﺪ ﻣﻨﻮي ﻛﺎﻣﻞ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ 2005ﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ 5-1 ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
ﺷﻜﻞ 5-1 در اﻳﻨﺠﺎ ﺑﻪ ﺗﻮﺿﻴﺢ ﻛﺎﻣﻞ در ﻣﻮرد ﻫﻤﻪ ي ﻣﻨﻮ ﻫﺎ ﻧﻴﺎزي ﻧﺪارﻳﻢ .در ﻃﻮل اﻳﻦ ﻛﺘﺎب ﺑﻪ ﻣﺮور ﺑﺎ ﺗﻤﺎﻣﻲ آﻧﻬﺎ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ .اﻣـﺎ در زﻳـﺮ ﺑﺮاي آﺷﻨﺎﻳﻲ اوﻟﻴﻪ ،ﺷﺮح ﻣﺨﺘﺼﺮي از ﻋﻤﻠﻜﺮد ﻫﺮ ﻳﻚ از ﻣﻨﻮ ﻫﺎ آورده ﺷﺪه اﺳﺖ:
٢٤
:Fileﺑﻪ ﻧﻈﺮ ﻣﻴﺮﺳﺪ ﻛﻪ ﻫﻤﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي ﻳﻚ ﻣﻨﻮي ﻓﺎﻳﻞ دارﻧﺪ .در اﻳﻦ ﻣﻨﻮ ﺣﺪاﻗﻞ ﭼﻴﺰي ﻛـﻪ ﭘﻴـﺪا ﻣﻴـﺸﻮد، راﻫﻲ ﺑﺮاي ﺧﺎرج ﺷﺪن از ﺑﺮﻧﺎﻣﻪ اﺳﺖ .اﻟﺒﺘﻪ در ﻣﻨﻮي Fileاﻳﻦ ﺑﺮﻧﺎﻣﻪ ،ﮔﺰﻳﻨﻪ ﻫﺎي ﺑﻴﺸﺘﺮي ﻣﺜﻞ ﺑـﺎز ﻛـﺮدن ،ﺑـﺴﺘﻦ ﻳـﺎ ذﺧﻴﺮه ﻛﺮدن ﻳﻚ ﻓﺎﻳﻞ ﺧﺎص و ﻳﺎ ﺗﻤﺎم ﭘﺮوژه ﻫﻢ وﺟﻮد دارد. :Editاﻳﻦ ﻣﻨﻮ ﻫﻢ ﻣﺜﻞ ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕﺮ ﺷﺎﻣﻞ ﮔﺰﻳﻨﻪ ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ اﻧﺘﻈﺎر آن را دارﻳـﺪCut ،Redo ، Undo: Paste، Copy،و .Delete :Viewﻣﻨﻮي Viewﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣﻲ دﻫﺪ ﺗﺎ ﺑﻪ ﺳﺮﻋﺖ ﺑﻪ ﭘﻨﺠﺮه ﻫﺎي ﻣﻮﺟﻮد در IDEﻣﺜـﻞ Solution ،Explorerﭘﻨﺠﺮه ،Propertiesﭘﻨﺠﺮه Toolbar ،Outputﻫﺎ و ...دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ. :Projectاﻳﻦ ﻣﻨﻮ ﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣﻴﺪﻫﺪ ﺗﺎ ﻓﺎﻳﻠﻬﺎي ﻣﺨﺘﻠﻒ از ﻗﺒﻴﻞ ﻓﺮﻣﻬﺎي ﺟﺪﻳﺪ و ﻳﺎ ﻛﻼﺳﻬﺎ را ﺑﻪ ﺑﺮﻧﺎﻣـﻪ ي ﺧـﻮد اﺿﺎﻓﻪ ﻛﻨﻴﺪ. :Buildاﻳﻦ ﻣﻨﻮ زﻣﺎﻧﻲ ﻣﻔﻴﺪ ﺧﻮاﻫﺪ ﺑﻮد ﻛﻪ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد را ﺗﻤﺎم ﻛﻨﻴﺪ و ﺑﺨﻮاﻫﻴﺪ ﻛـﻪ آن را ﺑـﺪون اﺳـﺘﻔﺎده از ﻣﺤـﻴﻂ Visual C#اﺟﺮا ﻛﻨﻴﺪ )اﺣﺘﻤﺎﻻ از ﻃﺮﻳﻖ ﻣﻨﻮي اﺳﺘﺎرت ،ﻣﺜﻞ ﻫﻤﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي دﻳﮕﺮ از ﻗﺒﻴﻞ Wordو ﻳﺎ (Excel :Debugاﻳﻦ ﻣﻨﻮ ﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣﻴﺪﻫﺪ ﺗﺎ ﺑﺮﻧﺎﻣﻪ ﺧﻮدﺗﺎن را در داﺧﻞ ﻣﺤﻴﻂ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ ﺧـﻂ ﺑـﻪ ﺧـﻂ اﺟـﺮا ﻛﻨﻴـﺪ. ﻫﻤﭽﻨﻴﻦ از ﻃﺮﻳﻖ اﻳﻦ ﻣﻨﻮ ﺷﻤﺎ ﺑﻪ دﻳﺒﺎﮔﺮ وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﻧﻴﺰ دﺳﺘﺮﺳﻲ ﺧﻮاﻫﻴﺪ داﺷﺖ .ﺑﻪ وﺳﻴﻠﻪ دﻳﺒـﺎﮔﺮ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﻋﻤﻠﻜﺮد ﻛﺪ ﺧﻮد را در ﻫﻨﮕﺎم اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺧﻂ ﺑﻪ ﺧﻂ ﺑﺮرﺳﻲ ﻛﺮده و ﻣﺸﻜﻼت آن را ﻣﺘﻮﺟﻪ ﺷﻮﻳﺪ. :Dataاﻳﻦ ﻣﻨﻮ ﺑﻪ ﺷﻤﺎ ﻛﻤﻚ ﻣﻲ ﻛﻨﺪ ﺗﺎ از اﻃﻼﻋﺎت ﺑﺪﺳﺖ آﻣﺪه از ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺘﻔﺎده ﻛﻨﻴـﺪ .اﻟﺒﺘـﻪ اﻳـﻦ ﻣﻨـﻮ زﻣﺎﻧﻲ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﻛﻪ در ﺣﺎل ﻛﺎر ﺑﺮ روي ﻗﺴﻤﺘﻬﺎي ﺑﺼﺮي ﺑﺮﻧﺎﻣﻪ ﺧﻮد ﺑﺎﺷﻴﺪ ) در ﭘﻨﺠﺮه اﺻﻠﻲ وﻳﮋوال اﺳـﺘﻮدﻳﻮ، ﻗﺴﻤﺖ ] [Designﻓﻌﺎل ﺑﺎﺷﺪ( ،ﻧﻪ زﻣﺎﻧﻲ ﻛﻪ در ﺣﺎل ﻧﻮﺷﺘﻦ ﻛﺪ ﻫﺴﺘﻴﺪ .در ﻓﺼﻮل 15و 16ﻛﺘﺎب ،ﻛﺎر ﺑـﺎ ﺑﺎﻧﻜﻬـﺎي اﻃﻼﻋﺎﺗﻲ را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد. :Formatاﻳﻦ ﻣﻨﻮ ﻧﻴﺰ ﻓﻘﻂ زﻣﺎﻧﻲ ﻛﻪ در ﺣﺎل ﻛﺎر ﺑﺎ ﻗﺴﻤﺖ ﻫﺎي ﺑﺼﺮي ﺑﺮﻧﺎﻣﻪ ﺑﺎﺷﻴﺪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﺑـﻪ وﺳـﻴﻠﻪ ﮔﺰﻳﻨﻪ ﻫﺎي اﻳﻦ ﻣﻨﻮ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻃﺮﻳﻘﻪ ﻗﺮار ﮔﺮﻓﺘﻦ اﺷﻴﺎي ﻣﻮﺟﻮد در ﻓﺮم ﺑﺮﻧﺎﻣﻪ )از ﻗﺒﻴﻞ TextBoxﻫﺎ ،دﻛﻤﻪ ﻫﺎ و (...را ﻛﻨﺘﺮل ﻛﻨﻴﺪ. :Toolsدر اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﺤﻴﻂ IDEوﻳﮋوال اﺳﺘﻮدﻳﻮ 2005را ﻛﻨﺘﺮل و ﻳﺎ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ .ﻫﻤﭽﻨﻴﻦ ﻟﻴﻨﻜـﻲ ﺑـﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي اﺿﺎﻓﻲ ﻧﺼﺐ ﺷﺪه در ﻛﻨﺎر وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﻴﺰ ،در اﻳﻦ ﻗﺴﻤﺖ وﺟﻮد دارد. :Testﻣﻨﻮي Testﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣﻲ دﻫﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ اﻳﺠﺎد ﻛﻨﻴﺪ ﺗﺎ ﺑﻪ وﺳﻴﻠﻪ آن ﺑﺘﻮاﻧﻴﺪ ﺑﻌﺪ از اﺗﻤـﺎم ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ، ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ آن را از ﻧﻈﺮ ﻛﺎراﻳﻲ و ﻳﺎ ﻋﻤﻠﻜﺮد ﺑﺮرﺳﻲ ﻛﻨﻴﺪ. :Windowاﻳﻦ ﻣﻨﻮ در ﻫﻤﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ اﻣﻜﺎن ﺑﺎز ﻛﺮدن ﺑﻴﺶ از ﻳﻚ ﭘﻨﺠﺮه در ﻫﺮ ﻟﺤﻈﻪ را ﺑﻪ ﻛﺎرﺑﺮ ﻣﻲ دﻫﻨﺪ ،ﻣﺜﻞ Wordو ﻳﺎ ،Excelﻧﻴﺰ وﺟﻮد دارد .ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻣﻨﻮ ﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣﻲ دﻫﻨﺪ ﻛـﻪ در ﺑـﻴﻦ ﭘﻨﺠـﺮه ﻫـﺎي ﻣﻮﺟﻮد در IDEﺟﺎ ﺑﻪ ﺟﺎ ﺷﻮﻳﺪ .ﻧﺎم ﭘﻨﺠﺮه ﻫﺎﻳﻲ ﻛﻪ در ﻫﺮ ﻟﺤﻈﻪ در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺎز ﻫﺴﺘﻨﺪ ،در ﭘﺎﻳﻴﻦ ﻧﻮار اﺑـﺰار ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي ﻫﺮ ﻛﺪام از آﻧﻬﺎ ،ﭘﻨﺠﺮه ﻣﺮﺑﻮﻃﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد. :Communityاﻳﻦ ﻣﻨﻮ ،دﺳﺘﺮﺳﻲ ﺑﻪ ﻣﻨﺎﺑﻊ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ،ﻣﻜﺎن ﻫﺎﻳﻲ ﺑﺮاي ﭘﺮﺳﻴﺪن ﺳﻮاﻻت و ﻧﻴﺰ ﺟﺴﺘﺠﻮ ﺑﻴﻦ ﻧﻤﻮﻧﻪ ﻛﺪﻫﺎ را در اﻳﻨﺘﺮﻧﺖ ﻓﺮاﻫﻢ ﻣﻲ ﻛﻨﺪ. :Helpﻣﻨﻮي Helpﺑﻪ ﺷﻤﺎ اﺟﺎزه دﺳﺘﺮﺳﻲ ﺑﻪ ﻣﺴﺘﻨﺪات وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005را ﻣﻲ دﻫـﺪ .راه ﻫـﺎي زﻳـﺎدي ﺑـﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻳﻦ اﻃﻼﻋﺎت وﺟﻮد دارﻧﺪ )ﺑﺮاي ﻣﺜﺎل از ﻃﺮﻳﻖ ﻣﺤﺘﻮﻳﺎت ،اﻧﺪﻳﺲ و ﻳﺎ ﺟﺴﺘﺠﻮ( .اﻳﻦ ﻣﻨﻮ ﻫﻤﭽﻨﻴﻦ داراي ﮔﺰﻳﻨـﻪ ﻫﺎﻳﻲ ﺑﺮاي وﺻﻞ ﺷﺪن ﺑﻪ وب ﺳﺎﻳﺖ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ،درﻳﺎﻓﺖ آﺧﺮﻳﻦ ﻧﺴﺨﻪ ﻫﺎي ﺑـﻪ روز رﺳـﺎﻧﻲ و ﻫﻤﭽﻨـﻴﻦ ﮔـﺰارش دادن ﻣﺸﻜﻼت ﺑﺮﻧﺎﻣﻪ اﺳﺖ.
٢٥
ﻧﻮار اﺑﺰارﻫﺎ: ﻧﻮار اﺑﺰارﻫﺎي زﻳﺎدي در IDEوﻳﮋوال اﺳﺘﻮدﻳﻮ وﺟﻮد دارﻧﺪ ،ﻣﺎﻧﻨﺪ Image Editor ،Formattingو ﻳـﺎ Text .Editorﺑﺮاي ﺣﺬف و ﻳﺎ اﺿﺎﻓﻪ اﻳﻦ ﻧﻮار اﺑﺰارﻫﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﮔﺰﻳﻨﻪ Toolbarsدر ﻣﻨﻮي Viewاﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﻫﺮ ﻛـﺪام از اﻳﻦ ﻧﻮار اﺑﺰارﻫﺎ ،دﺳﺘﺮﺳﻲ ﺳﺮﻳﻊ ﺷﻤﺎ را ﺑﻪ ﻳﻚ دﺳﺘﻮر ﭘﺮﻛﺎرﺑﺮد ﻓﺮاﻫﻢ ﻣﻲ ﻛﻨﺪ .ﺑﺪﻳﻦ ﺻﻮرت ﻣﺠﺒﻮر ﻧﺨﻮاﻫﻴﺪ ﺑﻮد ﻛـﻪ ﻫـﺮ ﺑـﺎر ﺑـﺮاي اﺟﺮاي آن دﺳﺘﻮر ﻣﻨﻮ ﻫﺎ را زﻳﺮ و رو ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜـﺎل ،ﮔﺰﻳﻨـﻪ ي … File New Projectاز ﻧـﻮار ﻣﻨـﻮ ،ﺑـﻪ وﺳﻴﻠﻪ ي ﺳﻤﺖ ﭼﭗ ﺗﺮﻳﻦ آﻳﻜﻮن در ﻧﻮار اﺑﺰار ﭘﻴﺶ ﻓﺮض ﻛﻪ ﻧﻮار اﺑﺰار اﺳﺘﺎﻧﺪارد ﻧﻴﺰ ﻧﺎﻣﻴﺪه ﻣﻴﺸﻮد )ﺷـﻜﻞ (1-6ﻧﻴـﺰ ﻗﺎﺑـﻞ دﺳﺘﺮﺳـﻲ اﺳﺖ.
ﺷﻜﻞ 6-1 ﻧﻮار اﺑﺰار اﺳﺘﺎﻧﺪارد ﺑﻪ ﭼﻨﺪ ﺑﺨﺶ ﻛﻪ ﺷﺎﻣﻞ ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﺮﺗﺒﻂ ﺑﻪ ﻫﻢ ﻫﺴﺘﻨﺪ ﺗﻘﺴﻴﻢ ﺷﺪه اﺳﺖ .ﻫﺮ ﺑﺨﺶ ﺑﻪ وﺳﻴﻠﻪ ﻳﻚ ﺧﻂ ﻋﻤﻮدي از ﺑﺨﺸﻬﺎي دﻳﮕﺮ ﺗﻔﻜﻴﻚ ﺷﺪه اﺳﺖ .ﭘﻨﺞ آﻳﻜﻮن اول ،ﺷﺎﻣﻞ ﻛﺎرﻫﺎي ﻋﻤﻮﻣﻲ ﺑـﺮ روي ﻓﺎﻳـﻞ و ﻳـﺎ ﭘـﺮوژه ﻫـﺴﺘﻨﺪ ﻛـﻪ از ﻃﺮﻳـﻖ ﻣﻨـﻮي Fileو ﻳﺎ ﻣﻨﻮي Projectﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ اﻧﺪ ،ﻣﺎﻧﻨﺪ ﺑﺎز ﻛﺮدن و ﻳﺎ ذﺧﻴﺮه ﻛﺮدن ﻓﺎﻳﻠﻬﺎ. ﮔﺮوه ﺑﻌﺪي آﻳﻜﻮن ﻫﺎ ،ﺑﺮاي وﻳﺮاﻳﺶ اﺳﺘﻔﺎده ﻣﻴﺸﻮد ) Copy ،Cutو .(Pasteﮔﺮوه ﺑﻌﺪي ﻧﻴﺰ ﺑﺮاي ﻟﻐﻮ ﻛـﺮدن آﺧـﺮﻳﻦ ﻋﻤـﻞ اﻧﺠﺎم ﺷﺪه ،دوﺑﺎره اﻧﺠﺎم دادن آن و ﻳﺎ ﺟﺎ ﺑﻪ ﺟﺎ ﺷﺪن ﺑﻴﻦ ﻛﺪﻫﺎ اﺳﺖ. ﮔﺮوه ﭼﻬﺎرم از آﻳﻜﻮن ﻫﺎ ﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣﻲ دﻫﺪ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺧﻮد را ﺷﺮوع ﻛﻨﻴﺪ ) ﺑﻪ وﺳﻴﻠﻪ ﻣﺜﻠﺚ ﺳﺒﺰ رﻧﮓ( .در اﻳﻦ ﻗﺴﻤﺖ ﻫﻤﭽﻨﻴﻦ ﻣﻴﺘﻮاﻧﻴﺪ ﭘﻴﻜﺮ ﺑﻨﺪي ﺑﺮﻧﺎﻣﻪ ﺗﺎن را ﻣﺸﺨﺺ ﻛﺮده و ﻳﺎ ﻧﺤﻮه اﺟﺮاي آن را ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ. در ﺑﺨﺶ ﺑﻌﺪي ﻣﻴﺘﻮاﻧﻴﺪ ﻣﺘﻦ ﺧﺎﺻﻲ را در ﺑﻴﻦ ﻛﺪﻫﺎي ﻓﺎﻳﻠﻲ ﻛﻪ ﻫﻢ اﻛﻨﻮن ﺑﺎز اﺳﺖ ،در ﺑﻴﻦ ﻣﺴﺘﻨﺪات ﺑﺮﻧﺎﻣﻪ و ﻳﺎ در ﺑـﻴﻦ ﻛـﻞ ﭘـﺮوژه ﺟﺴﺘﺠﻮ ﻛﻨﻴﺪ. ﮔﺮوه آﺧﺮ از آﻳﻜﻮن ﻫﺎ دﺳﺘﺮﺳﻲ ﺳﺮﻳﻊ ﺷﻤﺎ را ﺑـﻪ ﻗـﺴﻤﺘﻬﺎي ﻣﺨﺘﻠـﻒ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ ﻣﺎﻧﻨـﺪ ،Solution Explorer ﭘﻨﺠﺮه Start Page ،Object Browser ،Toolbox ،Propertiesو ﻳﺎ ﺻﻔﺤﺎت دﻳﮕﺮ ﻓﺮاﻫﻢ ﻣﻲ ﻛﻨﺪ )در ﻗﺴﻤﺘﻬﺎي ﺑﻌﺪي ﺑﺎ اﻳﻦ ﭘﻨﺠﺮه ﻫﺎ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ( .اﮔﺮ ﻫﺮ ﻛﺪام از اﻳﻦ ﭘﻨﺠﺮه ﻫﺎ ﺑﺴﺘﻪ ﺷﺪه ﺑﺎﺷـﺪ ،ﺑـﺎ ﻛﻠﻴـﻚ ﺑـﺮ روي آﻳﻜﻮن آن در اﻳﻦ ﻗﺴﻤﺖ ،ﭘﻨﺠﺮه ﻣﻮرد ﻧﻈﺮ ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ. ﻧﻜﺘﻪ :اﮔﺮ ﻓﺮاﻣﻮش ﻛﺮدﻳﺪ ﻛﻪ ﻫﺮ آﻳﻜﻮن ﭼﻪ ﻛﺎري اﻧﺠﺎم ﻣﻴﺪﻫﺪ ،اﺷﺎره ﮔﺮ ﻣﺎوس ﺧﻮد را ﺑﺮاي ﭼﻨﺪ ﻟﺤﻈﻪ ﺑﺮ روي آن ﻧﮕﻪ دارﻳﺪ .ﺑﺪﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎدري ﻇﺎﻫﺮ ﻣﻴﺸﻮد ﻛﻪ ﻧﺎم آﻳﻜﻮن ﻣﻮرد ﻧﻈﺮ را ﻧﻤﺎﻳﺶ ﻣﻴﺪﻫﺪ. ﺑﺮاي دﻳﺪن ﺑﻘﻴﻪ ﭘﻨﺠﺮه ﻫﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻣﻨﻮي ،Viewﭘﻨﺠﺮه ﻣﻮرد ﻧﻈﺮﺗـﺎن را اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ .اﻣـﺎ ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ ﻣﻴﺒﻴﻨﻴﺪ ،ﺑﻴﺸﺘﺮ آﻧﻬﺎ در ﺣﺎل ﺣﺎﻇﺮ ﺧﺎﻟﻲ ﻫﺴﺘﻨﺪ و ﻧﻤﻴﺘﻮان ﻋﻤﻠﻜﺮد آﻧﻬﺎ را ﻓﻬﻤﻴﺪ .ﺑﻬﺘﺮﻳﻦ راه ﻓﻬﻤﻴﺪن ﻛﺎرﺑﺮد اﻳﻦ ﻗﺴﻤﺘﻬﺎ ،ﻛﺎر ﻛـﺮدن ﺑـﺎ IDEو اﺳﺘﻔﺎده از اﻳﻦ ﻗﺴﻤﺘﻬﺎ در ﻃﻮل ﻧﻮﺷﺘﻦ ﻛﺪ ﺑﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ اﺳﺖ.
٢٦
اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺳﺎده: ﺑﺮاي اﺗﻤﺎم ﮔﺮدش در IDEوﻳﮋوال اﺳﺘﻮدﻳﻮ ،ﺑﻬﺘﺮ اﺳﺖ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺳﺎده ﺑـﺴﺎزﻳﻢ .ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ،در ﭘﻨﺠـﺮه ﻫـﺎي ﻗﺒﻠـﻲ ﻣﻘـﺪاري اﻃﻼﻋﺎت واﻗﻌﻲ و ﺟﺎﻟﺐ ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ آﻧﻬﺎ را ﺑﺮرﺳﻲ ﻛﻨﻴﺪ .در ﺑﺨﺶ "اﻣﺘﺤﺎن ﻛﻨﻴﺪ" زﻳﺮ ،ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻛﺎﻣﻼً ﺳﺎده ﺑﻪ ﻧﺎم HelloUserﺧﻮاﻫﻴﺪ ﺳﺎﺧﺖ ﻛﻪ در آن ﻛﺎرﺑﺮ ﻣﻴﺘﻮاﻧﺪ ﻧﺎم ﺧﻮد را در ﻳﻚ ﻛﺎدر ﻣﺘﻨﻲ وارد ﻛﻨﺪ .ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ ﻳﻚ ﭘﻴﻐﺎم ﺧﻮش آﻣـﺪ ﮔﻮﻳﻲ ﺑﻪ ﻛﺎرﺑﺮ ،ﺑﺎ ﻧﺎم او ،ﻧﻤﺎﻳﺶ ﺧﻮاﻫﺪ داد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻳﻚ ﭘﺮوژه HelloUser (1ﺑﺮ روي دﻛﻤﻪ ي New Projectدر ﻧﻮار اﺑﺰار ﻛﻠﻴﻚ ﻛﻨﻴﺪ. (2ﭘﻨﺠﺮه New Projectﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ .ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ ﻛﻪ در ﻗﺴﻤﺖ Project Typeدر ﺳـﻤﺖ ﭼـﭗ ،ﮔﺰﻳﻨـﻪ Visual C#اﻧﺘﺨـﺎب ﺷـﺪه ﺑﺎﺷـﺪ .ﺳـﭙﺲ در ﺑﺨـﺶ Templatesدر ﺳـﻤﺖ راﺳـﺖ ،ﮔﺰﻳﻨـﻪ Windows Applicationsرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .در ﻛﺎدر Nameﻛﻠﻤﻪ Hello Userرا ﺗﺎﻳﭗ ﻛـﺮده و در اﻧﺘﻬﺎ روي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﭘﻨﺠﺮه New Projectﺷﻤﺎ ﺑﺎﻳﺪ ﭼﻴﺰي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 7-1ﺑﺎﺷﺪ.
ﺷﻜﻞ 7-1
٢٧
(3ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي IDE ،OKوﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ وﻳﻨﺪوزي ﺧﺎﻟﻲ ﺑﺮاي ﺷﻤﺎ اﻳﺠﺎد ﻣﻴﻜﻨﺪ .در ﺣﺎل ﺣﺎﻇﺮ ،ﺑﺮﻧﺎﻣﻪ ي Hello Userﻓﻘﻂ داراي ﻳﻚ ﭘﻨﺠﺮه وﻳﻨﺪوزي ﺧﺎﻟﻲ اﺳﺖ ﻛﻪ ﻳﻚ ﻓﺮم وﻳﻨﺪوزي) 1ﻳﺎ ﺑﻪ اﺧﺘﺼﺎر ﻳﻚ ﻓﺮم( ﻧﺎﻣﻴﺪه ﻣﻲ ﺷﻮد .ﻧﺎم ﭘﻴﺶ ﻓﺮض اﻳﻦ ﻓﺮم ،ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ 8-1ﻧﺸﺎن داده ﺷﺪه اﺳﺖ Form1.cs ،اﺳﺖ. ﻧﻜﺘﻪ :ﻫﺮ زﻣﺎﻧﻲ ﻛﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺨﻮاﻫﺪ ﻳﻚ ﻓﺎﻳﻞ ﺟﺪﻳﺪ را اﻳﺠﺎد ﻛﻨﺪ ،ﭼﻪ اﻳﻦ ﻓﺎﻳﻞ در ﻫﻨﮕﺎم ﺳﺎﺧﺘﻦ ﭘﺮوژه اﻳﺠﺎد ﺷﻮد و ﭼﻪ ﺑﻌـﺪاً ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﻮد ،ﻧﺎﻣﻲ ﺑﻪ آن ﻓﺎﻳﻞ اﺧﺘﺼﺎص ﻣﻲ دﻫﺪ ﻛﻪ از دو ﻗﺴﻤﺖ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ .ﻗﺴﻤﺖ اول ﻧﻮع ﻓﺎﻳـﻞ را ﺗﻮﺻـﻴﻒ ﻣـﻲ ﻛﻨﺪ و ﻗﺴﻤﺖ دوم ﻧﻴﺰ ﻳﻚ ﻋﺪد اﺳﺖ ﻛﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ اﻳﻦ ﻓﺎﻳﻞ ،ﭼﻨﺪﻣﻴﻦ ﻓﺎﻳﻞ از اﻳﻦ ﻧﻮع اﺳﺖ.
ﭘﻨﺠﺮه ﻫﺎ در IDEوﻳﮋوال اﺳﺘﻮدﻳﻮ :2005 در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﭘﻨﺠﺮه ﻫﺎي زﻳﺎدي را ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻫﺮ ﻛﺪام ﻛﺎرﺑﺮد ﺧﺎﺻﻲ دارﻧﺪ .ﺑﻬﺘﺮ اﺳﺖ ﻗﺒﻞ از اداﻣـﻪ ي ﺑﺨـﺶ "اﻣﺘﺤﺎن ﻛﻨﻴﺪ" ،ﺗﻌﺪادي از آﻧﻬﺎ را ﺑﻪ اﺧﺘﺼﺎر ﺑﺮرﺳﻲ ﻛﻨﻴﻢ .ﻳﺎدآوري ﻣﻲ ﻛﻨﻢ ﻛﻪ اﮔﺮ ﻫﺮ ﻳﻚ از اﻳﻦ ﭘﻨﺠﺮه ﻫﺎ در ﻛﺎﻣﭙﻴﻮﺗﺮ ﺷﻤﺎ ﻧﻤـﺎﻳﺶ داده ﻧﻤﻲ ﺷﻮﻧﺪ ،از ﻣﻨﻮي Viewﮔﺰﻳﻨﻪ ﻣﺮﺑﻮط ﺑﻪ آن را اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ آن ﭘﻨﺠﺮه دﻳﺪه ﺷﻮد .ﻫﻤﭽﻨﻴﻦ اﮔﺮ از ﻣﻜـﺎن ﻗﺮارﮔﻴـﺮي ﻳـﻚ ﭘﻨﺠﺮه ﺧﺎص راﺿﻲ ﻧﻴﺴﺘﻴﺪ ،ﺑﺎ ﻛﻠﻴﻚ ﺑﺮ روي ﻧﻮار ﻋﻨﻮان ﭘﻨﺠﺮه )ﻧﻮار آﺑﻲ رﻧﮓ ﺑﺎﻻي ﭘﻨﺠﺮه ﻣﻮرد ﻧﻈﺮ( و ﻛﺸﻴﺪن آن ﺑﻪ ﻣﻜـﺎن ﺟﺪﻳـﺪ، ﺟﺎي آن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﭘﻨﺠﺮه ﻫﺎ ﻣﻴﺘﻮاﻧﻨﺪ درون IDEﺷﻨﺎور ﺑﺎﺷﻨﺪ و ﻳﺎ ﺑﻪ ﻳﻜﻲ از ﻟﺒﻪ ﻫﺎ وﺻﻞ ﺷﻮﻧﺪ)ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ .(8-1ﻟﻴﺴﺖ زﻳـﺮ ﻋﻤﻮﻣﻲ ﺗﺮﻳﻦ ﭘﻨﺠﺮه ﻫﺎ را ﻣﻌﺮﻓﻲ ﻣﻴﻜﻨﺪ.
:Server Explorerاﻳﻦ ﭘﻨﺠﺮه دﺳﺘﺮﺳﻲ ﺷﻤﺎ را ﺑﻪ ﺳﺮورﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﺗﻌﺮﻳـﻒ ﻛـﺮده اﻳﺪ ﻓﺮاﻫﻢ ﻣﻲ ﻛﻨﺪ .در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ اﺗﺼﺎﻻت ﺟﺪﻳﺪي را ﺑﻪ اﻳـﻦ ﺳـﺮورﻫﺎ اﻳﺠـﺎد ﻛﻨﻴـﺪ و ﻳـﺎ اﻃﻼﻋـﺎت ﻣﻮﺟـﻮد در ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ ﻛﻨﻮﻧﻲ را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ .در ﺗﺼﻮﻳﺮ ،8-1ﭘﻨﺠﺮه ،Server Explorerﺗﺐ 2ﻣﻮﺟـﻮد در زﻳـﺮ ﭘﻨﺠﺮه Toolboxاﺳﺖ. :Toolboxاﻳﻦ ﭘﻨﺠﺮه ﺷﺎﻣﻞ ﻛﻨﺘﺮل ﻫﺎ و ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﺧﻮد اﺿﺎﻓﻪ ﻛﺮده و ﺑﺎ اﺳﺘﻔﺎده از آن ﭘﻨﺠﺮه ي ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد را ﻃﺮاﺣﻲ ﻛﻨﻴﺪ .اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﺷﺎﻣﻞ ﻛﻨﺘﺮﻟﻬﺎي ﻋﻤﻮﻣﻲ ﻣﺎﻧﻨﺪ دﻛﻤﻪ ﻫﺎ ﻳﺎ اﺗـﺼﺎل دﻫﻨـﺪه ﻫـﺎي داده اي ،ﻛﻨﺘﺮﻟﻬﺎي ﺧﺮﻳﺪاري ﺷﺪه و ﻳﺎ ﻛﻨﺘﺮل ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﺧﻮدﺗﺎن ﻃﺮاﺣﻲ ﻛﺮده اﻳﺪ. :Design Windowاﻳﻦ ﻗﺴﻤﺖ ،ﺑﺨﺸﻲ اﺳﺖ ﻛﻪ ﺑﻴﺸﺘﺮﻳﻦ ﻓﻌﺎﻟﻴﺘﻬﺎ در آن ﺻﻮرت ﻣﻴﮕﻴﺮد .در اﻳﻦ ﺑﺨﺶ ﺷﻤﺎ راﺑﻂ ﻛﺎرﺑﺮي ﺑﺮﻧﺎﻣﻪ ﺗﺎن را ﺑﺮ روي ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻃﺮاﺣﻲ ﻣﻲ ﻛﻨﻴﺪ .اﻳﻦ ﭘﻨﺠﺮه در ﺑﻌﻀﻲ ﻣﻮاﻗﻊ Designerﻫـﻢ ﻧﺎﻣﻴـﺪه ﻣـﻲ ﺷﻮد. 3 :Solution Explorerاﻳﻦ ﭘﻨﺠﺮه ﻳﻚ ﻧﻤﺎي درﺧﺘﻲ از راه ﺣﻞ ﺷﻤﺎ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .ﻳﻚ راه ﺣﻞ ﻣﻲ ﺗﻮاﻧﺪ ﺷﺎﻣﻞ ﭼﻨﺪﻳﻦ ﭘﺮوژه ﺑﺎﺷﺪ ،ﻛﻪ ﻫﺮ ﻳﻚ از اﻳﻦ ﭘﺮوژه ﻫﺎ ﺧﻮد ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺷﺎﻣﻞ ﻓـﺮم ﻫـﺎ ،ﻛﻼﺳـﻬﺎ ،ﻣـﺎژول ﻫـﺎ ،و ﻳـﺎ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎﻳﻲ ﺑﺎﺷﻨﺪ ﻛﻪ ﻳﻚ ﻣﺴﺌﻠﻪ ﺧﺎص را ﺣﻞ ﻣﻲ ﻛﻨﺪ .در ﻓﺼﻞ دوم ﺑﻴﺸﺘﺮ در ﻣﻮرد ﻳﻚ راه ﺣﻞ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد. :Propertiesﭘﻨﺠﺮه Propertiesﺧﺎﺻﻴﺘﻬﺎي ﻗﺎﺑﻞ ﺗﻐﻴﻴﺮ ﺷﻴﺊ اﻧﺘﺨﺎب ﺷﺪه را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫـﺪ .اﮔﺮﭼـﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ ﺧﺎﺻﻴﺖ ﻫﺎ را از ﻃﺮﻳﻖ ﻛﺪ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ،اﻣﺎ در ﺑﻌﻀﻲ از ﻣﻮاﻗﻊ ﺗﻨﻈﻴﻢ ﻛﺮدن آﻧﻬﺎ در زﻣﺎن ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ راﺣﺖ ﺗﺮ اﺳﺖ )ﺑﺮاي ﻣﺜﺎل ،ﻣﻮﻗـﻊ ﻗـﺮار دادن ﻛﻨﺘـﺮل ﻫـﺎ در ﻓـﺮم( .دﻗـﺖ ﻛﻨﻴـﺪ ﻛـﻪ ﺧﺎﺻـﻴﺖ File Nameداراي ﻣﻘـﺪار Form1.csاﺳﺖ .اﻳﻦ ﻧﺎم ،ﻧﺎم ﻓﻴﺰﻳﻜﻲ ﻓﺎﻳﻞ ﺣﺎوي ﻛﺪﻫﺎي ﻓﺮم و اﻃﻼﻋﺎت ﻇﺎﻫﺮي آن اﺳﺖ. 1
Windows Form - WinForm Tab 3 Solution 2
٢٨
ﺷﻜﻞ 8-1
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺳﺎﺧﺘﻦ ﭘﺮوژه Hello User (1اﺑﺘﺪا ﻧﺎم ﻓﺮم ﺧﻮد را ﺑﻪ ﭼﻴﺰي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ ﺑﻴﺸﺘﺮ ﻣﻌـﺮف ﺑﺮﻧﺎﻣـﻪ ﺷـﻤﺎ ﺑﺎﺷـﺪ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر روي Form1.csدر Solution Explorerﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺳﭙﺲ ،در ﭘﻨﺠﺮه Propertiesﺧﺎﺻـﻴﺖ File Name را از Form1.csﺑﻪ HelloUser.csﺗﻐﻴﻴﺮ داده )ﺷﻜﻞ (9-1و Enterرا ﻓﺸﺎر دﻫﻴﺪ .ﺑﻌﺪ از ﺗﻐﻴﻴـﺮ ﻫـﺮ ﺧﺎﺻﻴﺖ در ﭘﻨﺠﺮه ،Propertiesﺑﺮاي اﻋﻤﺎل آن ﺑﺎﻳﺪ ﻛﻠﻴﺪ Enterرا ﻓﺸﺎر دﻫﻴﺪ و ﻳﺎ در ﺟﺎﻳﻲ ﺧﺎرج از ﭘﻨﺠـﺮه ﻛﻠﻴﻚ ﻛﻨﻴﺪ. (2ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ اﺳﻢ ﻓﺎﻳﻞ در ﭘﻨﺠﺮه Solution Explorerﻫﻢ ﺑﻪ HelloUser.csﺗﻐﻴﻴﺮ ﻣﻲ ﻛﻨﺪ. (3ﺣﺎﻻ روي ﻓﺮﻣﻲ ﻛﻪ در ﭘﻨﺠﺮه ي Designﻧﻤﺎﻳﺶ داده ﺷﺪه اﺳﺖ ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .ﭘﻨﺠـﺮه Propertiesﺗﻐﻴﻴـﺮ ﻛﺮده و ﺧﺎﺻﻴﺘﻬﺎي Formاﻧﺘﺨﺎب ﺷﺪه را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ )ﺑﻪ ﺟﺎي ﺧﺎﺻﻴﺘﻬﺎي ﻓﺎﻳﻞ HelloUser.csﻛـﻪ در ﻗﺴﻤﺖ ﻗﺒﻠﻲ در ﺣﺎل ﻧﻤﺎﻳﺶ آن ﺑﻮد( .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﺧﺎﺻﻴﺘﻬﺎي اﻳﻦ ﻗﺴﻤﺖ ﻛﺎﻣﻼً ﻣﺘﻔﺎوت ﺑـﺎ ﻗـﺴﻤﺖ ﻗﺒﻠـﻲ اﺳـﺖ. ﺗﻔﺎوﺗﻲ ﻛﻪ در اﻳﻦ ﺟﺎ وﺟﻮد دارد ﺑﻪ ﻋﻠﺖ دو ﻧﮕﺎه ﻣﺘﻔﺎوت ﺑﻪ ﻳﻚ ﻓﺎﻳﻞ اﺳﺖ .زﻣـﺎﻧﻲ ﻛـﻪ ﻧـﺎم ﻓـﺮم در Solution Explorerاﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ،ﺧﺎﺻﻴﺘﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﻓﺎﻳﻞ ﻓﻴﺰﻳﻜﻲ ﻓﺮم ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷـﻮد .اﻣـﺎ زﻣـﺎﻧﻲ ﻛـﻪ ﻓـﺮم ﻣﻮﺟﻮد در ﺑﺨﺶ Designerاﻧﺘﺨﺎب ﺷﻮد ،ﺧﺎﺻﻴﺘﻬﺎي ﻣﻨﻄﻘﻲ و ﺑﺼﺮي ﻓﺮم ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
٢٩
ﺷﻜﻞ 9-1 ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه Propertiesﻣﻴﺘﻮاﻧﻴﺪ ﺧﺎﺻﻴﺘﻬﺎي ﻳﻚ ﻛﻨﺘـﺮل را ﺑـﻪ راﺣﺘـﻲ ﺗﻐﻴﻴـﺮ دﻫﻴـﺪ .ﺧﺎﺻـﻴﺖ ﻫـﺎ ﻳـﻚ ﻣﺠﻤﻮﻋﻪ ي وﻳﮋه ،داﺧﻞ اﺷﻴﺎ ﻫﺴﺘﻨﺪ .آﻧﻬﺎ ﻣﻌﻤﻮﻻ رﻓﺘﺎر ﻳﺎ ﻇﺎﻫﺮ ﻳﻚ ﺷﻴﺊ را ﺗﻮﺻﻴﻒ ﻣﻲ ﻛﻨﻨﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ 10-1 ﻣﻲ ﺑﻴﻨﻴﺪ ﺧﺎﺻﻴﺖ ﻫﺎ در ﮔﺮوه ﻫﺎي ﻣﺨﺘﻠﻒ ﻗﺮار ﻣﻴﮕﻴﺮﻧﺪ ﻛﻪ ﻋﺒﺎرﺗﻨـﺪ از)Accessibility :ﻧﻤـﺎﻳﺶ داده ﻧـﺸﺪه اﺳﺖ()Appearance ،ﻧﺎم اﻳﻦ ﮔﺮوه ﻧﻴﺰ در ﺷﻜﻞ ﻣـﺸﺨﺺ ﻧﻴـﺴﺖ(،Design ،Data ،Behavior ، )Focusﻧﻤــﺎﻳﺶ داده ﻧــﺸﺪه اﺳــﺖ()Layout ،ﻧﻤــﺎﻳﺶ داده ﻧــﺸﺪه اﺳــﺖ()Misc ،ﻧﻤــﺎﻳﺶ داده ﻧــﺸﺪه اﺳــﺖ( و )Window-Styleﻧﻤﺎﻳﺶ داده ﻧﺸﺪه اﺳﺖ(. ﻧﻜﺘﻪ :ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ ﻣﺸﺨﺺ اﺳﺖ ،ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﺧﺎﺻﻴﺖ ﻧﺎم ﻓﺎﻳﻞ ﻣﺮﺑﻮط ﺑﻪ ﻓﺮم را ﺑﻪ Hello Userﺗﻐﻴﻴﺮ داده اﻳﻢ، اﻣﺎ ﻋﻨﻮان ﻓﺮم ﻫﻤﭽﻨﺎن Form1اﺳﺖ. (4در ﺣﺎل ﺣﺎﻇﺮ ،ﻋﻨﻮان اﻳﻦ ﻓﺮم Form1اﺳﺖ .اﻳﻦ ﻋﻨﻮان ﻛﺎرﺑﺮد ﺑﺮﻧﺎﻣﻪ را ﻣﺸﺨﺺ ﻧﻤﻲ ﻛﻨﺪ .ﭘﺲ آن را ﺗﻐﻴﻴﺮ ﻣﻲ دﻫـﻴﻢ ﺗﺎ ﺑﻴﺸﺘﺮ ﻣﻌﺮف ﺑﺮﻧﺎﻣﻪ ﺑﺎﺷﺪ .ﺧﺎﺻﻴﺖ Textرا در ﺑﺨﺶ Appearanceدر ﭘﻨﺠﺮه Propertiesاﻧﺘﺨﺎب ﻛﺮده و ﻣﻘﺪار آن را ﺑﻪ Hello From Visual C# 2005ﺗﻐﻴﻴﺮ داده ،ﺳﭙﺲ Enterرا ﻓﺸﺎر دﻫﻴﺪ. ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﻋﻨﻮان ﻓﺮم در ﺑﺨﺶ Designerﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺪاري ﻣﻲ ﺷﻮد ﻛﻪ در ﻛﺎدر ﻣﺮﺑﻮﻃﻪ وارد ﻛﺮده اﻳﺪ. اﮔﺮ ﭘﻴﺪا ﻛﺮدن ﺧﺎﺻﻴﺖ ﻣﻮرد ﻧﻈﺮﺗﺎن از ﻟﻴﺴﺖ در ﺣﺎﻟﺖ ﮔﺮوه ﺑﻨﺪي ﺷﺪه ﻣﺸﻜﻞ اﺳـﺖ ،ﺑـﺮ روي ﮔﺰﻳﻨـﻪ AZدر ﻧـﻮار اﺑـﺰار ﺑﺎﻻي ﭘﻨﺠﺮه Propertiesﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﺪﻳﻦ ﺗﺮﺗﻴﺐ ﻟﻴﺴﺖ ﺧﺎﺻﻴﺖ ﻫﺎ ﺑﻪ ﺻﻮرت اﻟﻔﺒﺎﻳﻲ ﻣﺮﺗﺐ ﻣﻲ ﺷﻮﻧﺪ. (5ﺑﺮ روي دﻛﻤﻪ Startدر ﻧﻮار اﺑﺰار وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻛﻠﻴﻚ ﻛﻨﻴﺪ )ﻣﺜﻠﺚ ﺳﺒﺰ رﻧﮓ( ﺗﺎ ﺑﺮﻧﺎﻣﻪ اﺟﺮا ﺷﻮد .در ﻃﻮل اﻳﻦ ﻛﺘﺎب ﻫﺮ ﺟﺎ ﻋﺒﺎرﺗﻬﺎي "ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ" و ﻳﺎ "ﺑﺮﻧﺎﻣﻪ را ﺷﺮوع ﻛﻨﻴﺪ" دﻳﺪﻳﺪ ،روي ﻛﻠﻴﺪ Startﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻌﺪ از ﻛﻠﻴﻚ روي اﻳﻦ دﻛﻤﻪ ،ﻳﻚ ﭘﻨﺠﺮه ﺧﺎﻟﻲ ﺑﺎ ﻋﻨﻮان Hello From Visual C# 2005ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
٣٠
ﺷﻜﻞ 10-1 ﺧﻴﻠﻲ راﺣﺖ ﺑﻮد ،اﻣﺎ ﺑﺮﻧﺎﻣﻪ ﻛﻮﭼﻚ ﺷﻤﺎ ﻛﺎري اﻧﺠﺎم ﻧﻤﻲ دﻫﺪ .اﺟﺎزه ﺑﺪﻫﻴﺪ ﻣﻘﺪاري ﺑﺮﻧﺎﻣﻪ را ﻣﺤﺎوره اي ﺗﺮ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛـﺎر، ﺑﺎﻳﺪ ﺗﻌﺪادي ﻛﻨﺘﺮل ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﻢ ،دو دﻛﻤﻪ ،ﻳﻚ ﻟﻴﺒﻞ و ﻳﻚ ﻛﺎدر ﻣﺘﻨﻲ .ﺑﻪ زودي ﺧﻮاﻫﻴﺪ دﻳﺪ ﻛـﻪ اﺿـﺎﻓﻪ ﻛـﺮدن اﻳﻨﻬـﺎ ﺑـﺎ اﺳﺘﻔﺎده از Toolboxﭼﻪ ﻗﺪر راﺣﺖ اﺳﺖ .ﻳﻜﻲ از ﻣﺰﻳﺖ ﻫﺎي Visual C#اﻳﻦ اﺳﺖ ﻛﻪ ﺷﻤﺎ ﻣﻴﺘﻮاﻧﻴﺪ ﻣﻘﺪار زﻳـﺎدي از ﺑﺮﻧﺎﻣﻪ ﺧﻮدﺗﺎن را ﻃﺮاﺣﻲ ﻛﻨﻴﺪ ﺑﺪون اﻳﻨﻜﻪ ﻛﺪي ﺑﻨﻮﻳﺴﻴﺪ .اﻟﺒﺘﻪ ﺑﺮاي آﻧﻬﺎ ﻛﺪ ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد ،اﻣﺎ اﻳﻦ ﻛﺪ دور از دﻳﺪ ﺷﻤﺎ اﺳﺖ و وﻳﮋوال C#آﻧﻬﺎ را ﺑﺮاي ﺷﻤﺎ ﻣﻲ ﻧﻮﻳﺴﺪ.
ﺟﻌﺒﻪ اﺑﺰار: ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﺟﻌﺒﻪ اﺑﺰار ﺳﻪ راه وﺟﻮد دارد: .1از ﻣﻨﻮي Viewﮔﺰﻳﻨﻪ Toolboxرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. .2از ﻧﻮار اﺑﺰار اﺳﺘﺎﻧﺪارد آﻳﻜﻮن ﻣﺮﺑﻮط ﺑﻪ آن را اﻧﺘﺨﺎب ﻛﻨﻴﺪ. .3ﻛﻠﻴﺪﻫﺎي Ctrl+Alt+Xرا ﻓﺸﺎر دﻫﻴﺪ.
٣١
ﺑﺪﻳﻦ ﺗﺮﺗﻴﺐ ﺟﻌﺒﻪ اﺑﺰار در ﻗﺴﻤﺖ ﭼﭗ IDEﻧﻤﺎﻳﺶ داده ﻣﻴﺸﻮد .ﺟﻌﺒﻪ اﺑﺰار ﺷﺎﻣﻞ ﻛﻨﺘﺮل ﻫﺎ و ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫـﺎﻳﻲ ﻣـﻲ ﺷـﻮد ﻛـﻪ ﻣـﻲ ﺗﻮاﻧﻴﺪ ﺑﺮ روي ﻓﺮم ﺧﻮد ﻗﺮار دﻫﻴﺪ .ﻛﻨﺘﺮل ﻫﺎ ﻣﺎﻧﻨﺪ دﻛﻤﻪ ﻫﺎ ،ﻛﺎدر ﻫﺎي ﻣﺘﻨﻲ ،دﻛﻤﻪ ﻫﺎي رادﻳﻮﻳﻲ و ﻳﺎ ﻟﻴﺴﺖ ﻫﺎي ﺗﺮﻛﻴﺒﻲ ﻣﻲ ﺗﻮاﻧﻨﺪ از ﺟﻌﺒﻪ اﺑﺰار اﻧﺘﺨﺎب ﺷﻮﻧﺪ و روي ﻓﺮم ﻗﺮار ﮔﻴﺮﻧـﺪ .ﺑـﺮاي ﺑﺮﻧﺎﻣـﻪ HelloUserﺷـﻤﺎ ﻓﻘـﻂ از ﻛﻨﺘﺮﻟﻬـﺎي ﻗـﺴﻤﺖ Common Controlsدر ﺟﻌﺒﻪ اﺑﺰار اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ .در ﺷﻜﻞ 11-1ﻣﻲ ﺗﻮاﻧﻴﺪ ﻟﻴﺴﺘﻲ از ﻛﻨﺘﺮﻟﻬﺎي ﻋﻤﻮﻣﻲ ﺑـﺮاي ﻓﺮﻣﻬـﺎي وﻳﻨـﺪوزي را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ. ﻛﻨﺘﺮل ﻫﺎ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ ﻫﺮ ﺗﺮﺗﻴﺒﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﺷﻮﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ اﻳﻦ ﻣﻮرد ﻛﻪ ﺷﻤﺎ دﻛﻤﻪ ﻫﺎ را ﻗﺒﻞ از ﻛﺎدرﻫـﺎي ﻣﺘﻨـﻲ ﺑـﺮ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ و ﻳﺎ ﻟﻴﺒﻞ ﻫﺎ را ﻗﺒﻞ از دﻛﻤﻪ ﻫﺎ رﺳﻢ ﻛﻨﻴﺪ اﻫﻤﻴﺘﻲ ﻧﺪارد .در "اﻣﺘﺤﺎن ﻛﻨﻴﺪ" ﺑﻌﺪي ،ﻗﺮار دادن ﻛﻨﺘـﺮل ﻫـﺎ ﺑـﺮ روي ﻓﺮم را ﺷﺮوع ﻣﻲ ﻛﻨﻴﻢ.
ﺷﻜﻞ 11-1
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﻛﻨﺘﺮل ﻫﺎ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي HelloUser (1اﮔﺮ ﺑﺮﻧﺎﻣﻪ ﻫﻢ اﻛﻨﻮن در ﺣﺎل اﺟﺮا اﺳﺖ آن را ﻣﺘﻮﻗﻒ ﻛﻨﻴﺪ ،زﻳﺮا ﺑﺎﻳﺪ ﺗﻌﺪادي ﻛﻨﺘﺮل ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴـﺪ .ﺑﻬﺘـﺮﻳﻦ راه ﺑـﺮاي ﺑﺴﺘﻦ ﺑﺮﻧﺎﻣﻪ ﻛﻠﻴﻚ ﻛﺮدن روي دﻛﻤﻪ ي Xدر ﺳﻤﺖ راﺳﺖ ﻧﻮار ﻋﻨﻮان اﺳﺖ.ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮ روي ﻣﺮﺑﻊ آﺑﻲ رﻧﮓ در IDEﻛﻠﻴﻚ ﻛﻨﻴﺪ )اﮔﺮ اﺷﺎره ﮔﺮ ﻣﺎوس ﺧﻮد را ﺑﺮ روي آن ﻧﮕﻪ دارﻳﺪ ﻋﺒـﺎرت " "Stop Debuggingدر ﻛـﺎدر زرد ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد(. (2ﻳﻚ ﻛﻨﺘﺮل ﻟﻴﺒﻞ ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ،در ﺟﻌﺒﻪ اﺑﺰار روي ﻛﻨﺘﺮل Labelﻛﻠﻴﻚ ﻛﻨﻴﺪ و آن را ﺗﺎ ﻣﺤﻞ ﻣﻮرد ﻧﻈﺮﺗﺎن ﺑﺮ روي ﻓﺮم ﺑﻜﺸﻴﺪ و ﺳﭙﺲ آن را رﻫﺎ ﻛﻨﻴﺪ .ﻫﻤﭽﻨﻴﻦ ﺑﺮاي ﻗﺮار دادن ﻳﻚ ﻛﻨﺘﺮل روي ﻓﺮم ﻣﻴﺘﻮاﻧﻴﺪ ﺑﺮ روي آﻳﻜﻮن آن در ﺟﻌﺒﻪ اﺑﺰار دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ.
٣٢
(3اﮔﺮ ﻛﻨﺘﺮل ﻟﻴﺒﻠﻲ ﻛﻪ ﺑﺮ روي ﻓﺮم ﻗﺮار داده اﻳﺪ در ﻣﻜﺎن ﻣﻨﺎﺳﺒﻲ ﻗﺮار ﻧﮕﺮﻓﺘﻪ اﺳﺖ ،ﻣﺸﻜﻠﻲ ﻧﻴﺴﺖ .ﻫﻨﮕﺎﻣﻲ ﻛـﻪ ﻛﻨﺘﺮﻟـﻲ ﺑـﺮ روي ﻓﺮم ﻗﺮار ﻣﻲ ﮔﻴﺮد ،ﻣﻴﺘﻮاﻧﻴﺪ آن را ﺟﺎ ﺑﻪ ﺟﺎ ﻛﻨﻴﺪ و ﻳﺎ اﻧﺪازه آن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺷﻜﻞ 12-1ﻓـﺮم ﺑﺮﻧﺎﻣـﻪ را ﺑﻌـﺪ از ﻗـﺮار دادن ﻛﻨﺘﺮل ﺑﺮ روي آن ﻧﺸﺎن ﻣﻴﺪﻫﺪ .ﺑﺮاي ﺣﺮﻛﺖ دادن ﻛﻨﺘﺮل روي ﻓﺮم ،ﺑﺮ روي ﻧﺎﺣﻴﻪ ﻧﻘﻄﻪ ﭼﻴﻦ در ﻓﺮم ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ و آن را ﺑﻪ ﻣﻜﺎن ﻣﻮرد ﻧﻈﺮﺗﺎن ﺑﻜﺸﻴﺪ .از ﻧﻈﺮ اﻧﺪازه ﻫﻢ ،ﻛﻨﺘﺮل ﻟﻴﺒﻞ ﺧﻮد را ﺑﺎ ﻣﺘﻨﻲ ﻛﻪ درون آن وارد ﻣـﻲ ﻛﻨﻴـﺪ ﻫـﻢ اﻧـﺪازه ﻣﻴﻜﻨﺪ .ﭘﺲ ﺧﻴﺎﻟﺘﺎن ﻣﻲ ﺗﻮاﻧﺪ از اﻳﻦ ﻧﻈﺮ راﺣﺖ ﺑﺎﺷﺪ. (4ﺑﻌﺪ از رﺳﻢ ﻳﻚ ﻛﻨﺘﺮل ﺑﺮ روي ﻓﺮم ،ﺣﺪاﻗﻞ ﺑﺎﻳﺪ ﻧﺎم و ﻣﺘﻨﻲ ﻛـﻪ ﻧﻤـﺎﻳﺶ ﻣـﻲ دﻫـﺪ را اﺻـﻼح ﻛﻨﻴـﺪ .ﺑـﺎ اﻧﺘﺨـﺎب ﻛﻨﺘـﺮل Labelﺑـﺮ روي ﻓــﺮم ،ﻣــﺸﺎﻫﺪه ﺧﻮاﻫﻴــﺪ ﻛــﺮد ﻛــﻪ ﭘﻨﺠــﺮه Propertiesدر ﺳــﻤﺖ ﭼــﭗ ،Designer ﺧﺎﺻــﻴﺘﻬﺎي Label1را ﻧﻤــﺎﻳﺶ ﻣــﻲ دﻫــﺪ .در ﭘﻨﺠــﺮه Propertiesﺧﺎﺻــﻴﺖ Textاﻳــﻦ ﻛﻨﺘــﺮل را ﺑــﻪ Enter Your Nameﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﺑﺎ ﻓﺸﺎر ﻛﻠﻴﺪ Enterو ﻳﺎ ﻛﻠﻴﻚ در ﺧﺎرج از ﺧﺎﺻﻴﺖ ﻣﻮرد ﻧﻈﺮ ،اﻧﺪازه ﻟﻴﺒﻞ ﺑﻪ ﺻـﻮرﺗﻲ ﺗﻐﻴﻴـﺮ ﻣﻴﻜﻨـﺪ ﺗـﺎ ﻣـﺘﻦ ﺷـﻤﺎ را در ﺧـﻮد ﺟـﺎي دﻫـﺪ .ﺣـﺎﻻ ،ﺧﺎﺻـﻴﺖ Nameﻛﻨﺘـﺮل را ﺑـﻪ lblNameﺗﻐﻴﻴﺮ دﻫﻴﺪ.
ﺷﻜﻞ 12-1 (5ﺣﺎﻻ ،دﻗﻴﻘﺎ زﻳﺮ ﻛﻨﺘﺮل ،Labelﻳﻚ ﻛﻨﺘﺮل TextBoxﻗﺮار دﻫﻴﺪ ﺗﺎ در آن ﺑﺘﻮاﻧﻴﺪ ﻧـﺎم را وارد ﻛﻨﻴـﺪ .ﺑـﺮاي اﺿـﺎﻓﻪ ﻛﺮدن ﻳﻚ TextBoxﺑﻪ ﻓﺮم ﻫﻤﺎﻧﻨﺪ ﻟﻴﺒﻞ ﻋﻤﻞ ﻛﻨﻴﺪ ،اﻣﺎ در اﻳﻦ ﺑﺎر ﺑﻪ ﺟﺎي ﻟﻴﺒﻞ ،ﻛﻨﺘـﺮل TextBoxرا از ﺟﻌﺒـﻪ اﺑﺰار اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺑﻌﺪ از اﻳﻨﻜﻪ TextBoxرا در ﺟﺎي ﺧﻮد ﺑﺮ روي ﻓﺮم ﻗﺮار دادﻳﺪ )ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ (13-1ﺑـﺎ اﺳـﺘﻔﺎده از ﭘﻨﺠﺮه Propertiesﺧﺎﺻﻴﺖ Nameآن را ﺑﻪ txtNameﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺑﻪ دﺳﺘﮕﻴﺮه ﻫﺎي ﺗﻨﻈﻴﻢ اﻧﺪازه در ﺳﻤﺖ ﭼﭗ و راﺳﺖ ﻛﻨﺘﺮل ﺗﻮﺟﻪ ﻛﻨﻴﺪ .ﺑﻪ وﺳﻴﻠﻪ آﻧﻬﺎ ،ﻣﻴﺘﻮاﻧﻴﺪ اﻧﺪازه اﻓﻘﻲ ﻛﻨﺘﺮل را ﺗﻐﻴﻴـﺮ دﻫﻴﺪ.
٣٣
ﺷﻜﻞ 13-1 (6در ﺳﻤﺖ ﭼﭗ ﭘﺎﻳﻴﻦ ﻓﺮم ،ﺑﻪ ﻫﻤﺎن ﺻﻮرت ﻛﻪ Labelو ﻳﺎ TextBoxرا ﺑـﺮ روي ﻓـﺮم ﻗـﺮار دادﻳـﺪ ،ﻳـﻚ ﻛﻨﺘـﺮل Buttonﻫﻢ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺳﭙﺲ ﺧﺎﺻﻴﺖ Nameآن را ﺑـﻪ btnOKو ﺧﺎﺻـﻴﺖ Textآن را ﺑـﻪ &OKﺗﻐﻴﻴـﺮ ﻫﻴﺪ .ﻓﺮم ﺷﻤﺎ ﻫﻢ اﻛﻨﻮن ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 14-1ﺑﺎﺷﺪ. ﻛﺎراﻛﺘﺮ & ﻛﻪ در ﺧﺎﺻﻴﺖ Textدﻛﻤﻪ ﻫﺎي ﻓﺮﻣﺎن اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد ،ﺑﺮاي اﻳﺠﺎد ﺷـﻮرت ﻛـﺎت ﺑـﺮاي آن دﻛﻤـﻪ اﺳـﺖ. ﺣﺮﻓﻲ ﻛﻪ ﻛﺎراﻛﺘﺮ & ﻗﺒﻞ از آن ﻗﺮار ﻣﻲ ﮔﻴﺮد ،ﺑﻪ ﺻﻮرت زﻳﺮ ﺧـﻂ دار ﻧﻤـﺎﻳﺶ داده ﻣﻴـﺸﻮد)ﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ .(14-1ﺑـﺪﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎرﺑﺮ ﻣﻴﺘﻮاﻧﺪ ﺑﻪ ﺟﺎي ﻛﻠﻴﻚ ﻛﺮدن ﺑﺎ ﻣﺎوس ﺑﺮ روي دﻛﻤﻪ ،ﺑﺎ ﻓﺸﺎر ﻛﻠﻴﺪ Altو ﺣﺮف ﻣﺸﺨﺺ ﺷـﺪه ﻛﻠﻴـﺪ ﻣـﻮرد ﻧﻈﺮ را اﻧﺘﺨﺎب ﻛﻨﺪ )در ﺑﻌﻀﻲ ﻣﻮاﻗﻊ ،ﺗﺎ ﻛﺎرﺑﺮ ﻛﻠﻴﺪ Altرا ﻓﺸﺎر ﻧﺪﻫﺪ ،ﺣﺮوف ﻣﻮرد ﻧﻈﺮ زﻳﺮ ﺧﻂ دار ﻧﻤـﻲ ﺷـﻮﻧﺪ( .ﺑـﺮاي ﻣﺜﺎل ،در اﻳﻦ ﺟﺎ ﻓﺸﺎر دادن ﻛﻠﻴﺪ Alt + Oﻫﻤﺎﻧﻨﺪ ﻛﻠﻴﻚ ﻛﺮدن ﺑﺮ روي دﻛﻤﻪ OKاﺳﺖ .ﺑﺮاي اﻧﺠﺎم دادن اﻳﻦ ﻛـﺎر ﻻزم ﻧﻴﺴﺖ ﻛﻪ ﺷﻤﺎ ﻛﺪي را وارد ﻛﻨﻴﺪ. (7ﺣﺎﻻ دﻛﻤﻪ دوم را ﻫﻤﺎﻧﻨﺪ دﻛﻤﻪ اول ،ﺑﺎ ﻛﺸﻴﺪن از ﺟﻌﺒﻪ اﺑﺰار و رﻫﺎ ﻛﺮدن ﺑﺮ روي ﻓﺮم ،در ﮔﻮﺷﻪ ﺳـﻤﺖ راﺳـﺖ ﭘـﺎﻳﻴﻦ ﻓـﺮم ﻗﺮار دﻫﻴﺪ .دﻗﺖ ﻛﻨﻴﺪ ،ﺑﻪ ﻣﺤﺾ اﻳﻨﻜﻪ دﻛﻤﻪ ﻣﻮرد ﻧﻈﺮ را ﺑﻪ ﮔﻮﺷﻪ ﺳﻤﺖ راﺳﺖ ﻓﺮم ﺑﺒﺮﻳﺪ ،ﻳﻚ ﺧﻂ اﻓﻘﻲ آﺑﻲ رﻧﮓ ،ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ،15-1ﻇﺎﻫﺮ ﻣﻴﺸﻮد .اﻳﻦ ﺧﻂ ﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣﻲ ﻫﺪ ﻛﻪ ﻣﻜﺎن ﻛﻨﺘﺮل ﺟﺪﻳﺪ را ،ﺑﺎ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻓﺮم ﺗـﺮاز ﻛﻨﻴـﺪ. ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ ﺧﻂ ﻣﻲ واﻧﻴﺪ ﻛﻨﺘﺮﻟﻬﺎي ﺟﺪﻳﺪ را دﻗﻴﻘﺎً در ﺳﻤﺖ ﭼﭗ ،راﺳﺖ ،ﺑﺎﻻ و ﻳﺎ ﭘﺎﻳﻴﻦ ﻳﻚ ﻛﻨﺘﺮل ﺧﺎص ﻗﺮار دﻫﻴﺪ .ﺑـﻪ وﺳﻴﻠﻪ ﺧﻂ آﺑﻲ ﻛﻤﺮﻧﮓ ﻛﻨﺎر ﻛﻨﺘﺮل ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﻓﺎﺻﻠﻪ ﺧﺎص را ﻫﻤﻮاره ﺑﻴﻦ ﻟﺒﻪ ﻓﺮم ﺧﻮد و ﻟﺒﻪ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻓﺮم رﻋﺎﻳﺖ ﻛﻨﻴﺪ .ﺧﺎﺻﻴﺖ Nameﻛﻨﺘﺮل ﺟﺪﻳﺪ را ﺑﻪ btnExitو ﺧﺎﺻﻴﺖ Textآن را ﺑـﻪ E&xitﺗﻐﻴﻴـﺮ دﻫﻴـﺪ. ﻓﺮم ﺷﻤﺎ ﻫﻢ اﻛﻨﻮن ﺑﺎﻳﺪ ﭼﻴﺰي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 15-1ﺑﺎﺷﺪ.
٣٤
ﺷﻜﻞ 14-1
ﺷﻜﻞ 15-1 ﺧﻮب ،ﻗﺒﻞ از اﻳﻨﻜﻪ اوﻟﻴﻦ ﺑﺮﻧﺎﻣﻪ را ﺗﻤﺎم ﻛﻨﻴﺪ ،ﺑﻬﺘﺮ اﺳﺖ ﻣﻘﺪاري ﻛﺪ ﻛﻪ ﺑﺎﻳﺪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ را ﺑﻪ اﺧﺘﺼﺎر ﺗﻮﺿﻴﺢ دﻫﻴﻢ.
ﻧﺸﺎﻧﻪ ﮔﺬاري ﻣﺠﺎرﺳﺘﺎﻧﻲ ﺗﻐﻴﻴﺮ ﻳﺎﻓﺘﻪ: اﺣﺘﻤﺎﻻ ﻣﺘﻮﺟﻪ ﺷﺪه اﻳﺪ ﻛﻪ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ ﺗﺎ ﻛﻨﻮن اﻳﺠﺎد ﻛﺮده اﻳﻢ ،ﺳﺎﺧﺘﺎر ﻧﺎم ﺟﺎﻟﺒﻲ دارﻧﺪ .ﺗﻤﺎﻣﻲ آﻧﻬﺎ داراي ﻳﻚ ﭘﻴﺸﻮﻧﺪ ﻫﺴﺘﻨﺪ ﻛـﻪ ﻧﻮع ﻛﻨﺘﺮل را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ .اﻳﻦ ﻛﺎر ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﻫﻨﮕﺎم ﻛﺪ ﻧﻮﻳﺴﻲ ﺑﻪ راﺣﺘﻲ ﻧﻮع ﻛﻨﺘﺮﻟﻲ ﻛﻪ ﺑﺎ آن ﻛﺎر ﻣﻲ ﻛﻨﻴﺪ را ﺗﺸﺨﻴﺺ
٣٥
دﻫﻴﺪ .ﻣﺜﻼً ﻓﺮض ﻛﻨﻴﺪ در ﺑﺮﻧﺎﻣﻪ ﺧﻮد ﻳﻚ ﻛﻨﺘﺮل دارﻳﺪ ﻛﻪ ﻧﺎم آن Nameاﺳﺖ ،ﺑـﺪون ﻫـﻴﭻ ﭘﻴـﺸﻮﻧﺪي از ﻗﺒﻴـﻞ lblﻳـﺎ .txt ﭼﻄﻮر ﻣﻲ ﺧﻮاﻫﻴﺪ ﺗﺸﺨﻴﺺ دﻫﻴﺪ ﻛﻪ اﻳﻦ ﻛﻨﺘﺮل ،ﻳﻚ ﻛﺎدر ﻣﺘﻨﻲ ) (TextBoxاﺳﺖ ﻛﻪ ﻧﺎم را از ﻛﺎرﺑﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨـﺪ ﻳـﺎ ﻳـﻚ ﻟﻴﺒﻞ ﻛﻪ ﻳﻚ ﻋﺒﺎرت ﻣﺮﺑﻮط ﺑﻪ ﻧﺎم را در ﻓﺮم ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ؟ ﻓـﺮض ﻛﻨﻴـﺪ ﻛـﻪ در ﺑﺨـﺶ "اﻣﺘﺤـﺎن ﻛﻨﻴـﺪ" ﻗﺒﻠـﻲ ،ﻛﻨﺘـﺮل ﻟﻴﺒـﻞ را Name1و ﻛﻨﺘﺮل TextBoxرا Name2ﻧﺎم ﮔﺬاري ﻣﻲ ﻛﺮدﻳﻢ ،ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺴﻠﻤﺎً ﮔﻴﺞ ﻣﻲ ﺷﺪﻳﺪ .اﮔﺮ ﺑﻌﺪ از ﭼﻨﺪ ﻣﺎه ﻣﻲ ﺧﻮاﺳﺘﻴﺪ ﻛﺪ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ ،ﭼﻄﻮر ﻣﻴﺘﻮاﻧﺴﺘﻴﺪ ﻛﻨﺘﺮل ﻫﺎ را از ﻫﻢ ﺗﺸﺨﻴﺺ دﻫﻴﺪ؟ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺎ ﭼﻨﺪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﺑﻪ ﺻﻮرت ﮔﺮوﻫﻲ ﻛﺎر ﻣﻲ ﻛﻨﻴﺪ ،اﻳﻦ ﻣﻮرد ﻛﻪ ،اﺳﺘﻴﻞ و ﻗﺎﻟﺐ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﺻـﻮرت ﺛﺎﺑـﺖ و ﻣﺸﺨـﺼﻲ ﻧﮕﻪ دارﻳﺪ ﻣﻬﻢ ﺧﻮاﻫﺪ ﺷﺪ .ﻳﻜﻲ از ﻋﻤﻮﻣﻲ ﺗﺮﻳﻦ ﺳﺎﺧﺘﺎرﻫﺎي ﻧﺎم ﺑﺮاي ﻛﻨﺘﺮل ﻫﺎ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻪ ﻫـﺮ زﺑـﺎﻧﻲ ،ﺗﻮﺳـﻂ دﻛﺘـﺮ ﭼـﺎرﻟﺰ ﺳﻴﻤﻮﻧﻲ ﺑﻪ وﺟﻮد آﻣﺪ ﻛﻪ ﻗﺒﻞ از ﭘﻴﻮﺳﺘﻨﺶ ﺑﻪ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﺑﺮاي ﺷﺮﻛﺖ 1XPARCﻛﺎر ﻣﻴﻜﺮد .او ﭘﻴﺸﻮﻧﺪ ﻫﺎي ﻛﻮﺗﺎﻫﻲ را ﺑـﻪ وﺟـﻮد آورده ﺑﻮد ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﺑﺎ اﺳﺘﻔﺎده از آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﺴﺘﻨﺪ ﺑﻪ راﺣﺘﻲ ﺗﺸﺨﻴﺺ دﻫﻨﺪ ﻛﻪ ﻫﺮ ﻣﺘﻐﻴﻴﺮ ﭼـﻪ ﻧـﻮع داده اي را ﻧﮕﻬـﺪاري ﻣـﻲ ﻛﻨﺪ .ﺑﻪ دﻟﻴﻞ اﻳﻨﻜﻪ دﻛﺘﺮ ﺳﻴﻤﻮﻧﻲ اﻫﻞ ﻣﺠﺎرﺳﺘﺎن ﺑﻮد و اﻳﻦ ﭘﻴﺸﻮﻧﺪ ﻫﺎ ﻫﻢ ﻣﻘﺪاري ﻣﺎﻧﻨﺪ ﻳﻚ زﺑﺎن ﺧـﺎرﺟﻲ ﻣـﻲ ﻣﺎﻧﺪﻧـﺪ ،ﻧـﺎم "ﻧـﺸﺎﻧﻪ ﮔﺬاري ﻣﺠﺎرﺳﺘﺎﻧﻲ" ﺑﺮ روي اﻳﻦ ﺳﻴﺴﺘﻢ ﻣﺎﻧﺪ .ﻫﻤﭽﻨﻴﻦ ﺑﻪ اﻳﻦ دﻟﻴﻞ ﻛﻪ ﺳﻴﺴﺘﻢ ﻣﻌﺮﻓﻲ ﺷﺪه ﺑﺮاي زﺑﺎﻧﻬﺎي Cو C++ﺑﻪ ﻛﺎر ﻣﻴﺮﻓﺖ، ﻣﺎ اﻳﻦ ﺳﻴﺴﺘﻢ را در وﻳﮋوال " 2005 C#ﻧﺸﺎﻧﻪ ﮔﺬاري ﻣﺠﺎرﺳﺘﺎﻧﻲ ﺗﻐﻴﻴﺮ ﻳﺎﻓﺘﻪ" ﻣﻲ ﻧﺎﻣﻴﻢ .ﺟﺪول زﻳﺮ ﻟﻴﺴﺘﻲ از ﭘﻴﺸﻮﻧﺪﻫﺎﻳﻲ اﺳـﺖ ﻛـﻪ ﺑﻪ ﺷﻤﺎ ﭘﻴﺸﻨﻬﺎد ﻣﻲ ﻛﻨﻢ در اﻳﻦ ﻛﺘﺎب از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﻧﺸﺎﻧﻪ ﮔﺬاري ﻣﺠﺎرﺳﺘﺎﻧﻲ زﻣﺎﻧﻲ ﻛﻪ در ﺣﺎل ﺑﺮرﺳﻲ ﻛﺪ ﻓﺮد دﻳﮕﺮي ﻫﺴﺘﻴﺪ و ﻳﺎ ﻛﺪي ﻛﻪ ﺧﻮدﺗﺎن ﭼﻨﺪ ﻣﺎه ﭘﻴﺶ ﻧﻮﺷﺘﻪ اﻳﺪ را ﻣﻄﺎﻟﻌﻪ ﻣﻲ ﻛﻨﻴﺪ ،ﺑﺴﻴﺎر ﻛﺎر را ﺳﺮﻳﻊ ﻣﻲ ﻛﻨﻨﺪ .اﻣﺎ ﮔﺬﺷﺘﻪ از اﻳﻦ ﻣﻮرد ،ﺑﻬﺘﺮﻳﻦ ﻓﺎﻳﺪه اﺳﺘﻔﺎده از اﻳﻦ ﺳﻴﺴﺘﻢ ،اﻳﺠﺎد ﻳﻜﭙﺎرﭼﮕﻲ در ﻛﺪ اﺳﺖ .ﭘﻴـﺸﻨﻬﺎد ﻣﻲ ﻛﻨﻢ از ﭘﻴﺶ ﻓﺮض ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ﺻﻮرت ﻏﻴﺮ رﺳﻤﻲ در وﻳﮋوال 2005 C#ﺑﻪ ﺻﻮرت اﺳﺘﺎﻧﺪارد در آﻣﺪه اﻧﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،اﻣﺎ اﻳﻦ ﻛﺎر واﺟﺐ ﻧﻴﺴﺖ .ﻣﻬﻢ اﻳﻦ اﺳﺖ ﻛﻪ در ﻃﻮل ﺑﺮﻧﺎﻣﻪ ﺧﻮد از ﻳﻚ ﻗﺎﻋﺪه ﺧﺎص ﺑﺮاي ﻧﺎﻣﮕﺬاري ﭘﻴﺮوي ﻛﻨﻴﺪ .ﺗﻌﺪادي از اﻳﻦ ﭘﻴﺶ ﻓﺮض ﻫﺎ ﺑﻪ ﻫﻤﺮاه ﻧﺎم ﻛﻨﺘﺮل ﻣﺮﺑﻮط ﺑﻪ آن در ﺟﺪول زﻳﺮ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﻧﺪ. ﻛﻨﺘﺮل
ﭘﻴﺸﻮﻧﺪ
دﻛﻤﻪ ﻓﺮﻣﺎن )(Button
Btn
ﺟﻌﺒﻪ ﺗﺮﻛﻴﺒﻲ )(ComboBox
Cbo
ﺟﻌﺒﻪ اﻧﺘﺨﺎب )(CheckBox
Chk
ﻟﻴﺒﻞ )(Label
lbl
ﺟﻌﺒﻪ ﻟﻴﺴﺖ )(ListBox
lst
ﻣﻨﻮي اﺻﻠﻲ )(Menu
mnu
دﻛﻤﻪ رادﻳﻮﻳﻲ )(RadioButton
rdb
ﺟﻌﺒﻪ ﺗﺼﻮﻳﺮ )(PictureBox
pic
ﺟﻌﺒﻪ ﻣﺘﻨﻲ )(TextBox
txt
وﻳﺮاﻳﺸﮕﺮ ﻛﺪ:
Xerox Palo Alto Research Center
1
٣٦
ﺣﺎﻻ ﻛﻪ ﻓﺮم HelloUserرا اﻳﺠﺎد ﻛﺮده اﻳﺪ ،ﺑﺎﻳﺪ ﻣﻘﺪاري ﻛﺪ ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ ﻛﺎرﻫﺎي ﻣﻮرد ﻧﻈﺮ را ﺑﺮاﻳﺘﺎن اﻧﺠﺎم دﻫـﺪ .ﺗـﺎ ﻛﻨﻮن دﻳﺪه اﻳﺪ ﻛﻪ اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻛﻨﺘﺮل ﺑﻪ ﻓﺮم ﺗﺎ ﭼﻪ ﺣﺪ ﺳﺎده اﺳﺖ .ﻓﺮاﻫﻢ ﻛﺮدن ﻳﻚ ﻛﺎراﻳﻲ ﺧﺎص ﺑﺮاي اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﺑﻪ وﺳﻴﻠﻪ ﻛﺪ ﻧﻴﺰ ،زﻳﺎد ﺳﺨﺖ ﺗﺮ از اﺿﺎﻓﻪ ﻛﺮدن ﻛﻨﺘﺮل ﺑﻪ ﻓﺮم ﻧﻴﺴﺖ .ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﻛﺪ ﺑﻪ ﻛﻨﺘﺮل ﻣﻮرد ﺑﺤﺚ ،ﻓﻘﻂ ﻛﺎﻓﻲ اﺳﺖ ﻛـﻪ روي آن دوﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﺎ اﻳﻦ ﻛﺎر ،ﺻﻔﺤﻪ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ 16-1ﻧﺸﺎن داده ﺷﺪه اﺳﺖ ﺑﺎز ﻣﻲ ﺷﻮد.
ﺷﻜﻞ 16-1 دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻳﻚ ﻟﺒﻪ دﻳﮕﺮ ﺑﻪ ﻟﺒﻪ ﻫﺎي ﺑﺎﻻي ﺻﻔﺤﻪ اﺻﻠﻲ در وﻳﮋوال اﺳﺘﻮدﻳﻮ اﺿﺎﻓﻪ ﺷﺪ .ﺣﺎﻻ در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﻪ دو ﭘﻨﺠﺮه Designو Codeدﺳﺘﺮﺳﻲ دارﻳﺪ .ﺑﺮاي ﻃﺮاﺣﻲ ﻇﺎﻫﺮ و راﺑﻂ ﻛﺎرﺑﺮي ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ از ﻗﺴﻤﺖ ،Designو ﺑـﺮاي ﻧﻮﺷـﺘﻦ ﻛـﺪ ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ از ﻗﺴﻤﺖ Codeاﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﺑﺮاي ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﻓﺮم ،ﻳﻚ ﻓﺎﻳﻞ ﻣﺠﺰا اﻳﺠـﺎد ﻣﻲ ﻛﻨﺪ .ﻗﺴﻤﺘﻬﺎي ﺑﺼﺮي و ﻗﺴﻤﺘﻬﺎﻳﻲ ﻛﻪ ﺑﻪ ﻇﺎﻫﺮ ﻓﺮم ﻣﺮﺑﻮط ﻫﺴﺘﻨﺪ در ﻓﺎﻳﻠﻲ ﺑﻪ ﻧﺎم HelloUser.Designer.cs و ﻛﺪﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﭼﮕﻮﻧﮕﻲ ﻋﻤﻠﻜﺮد ﻓﺮم در HelloUser.csﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ .اﻳﻦ ﻣـﻮرد ﺧـﻮد ﻳﻜـﻲ از دﻻﻳﻠـﻲ اﺳـﺖ ﻛـﻪ ﻣﻮﺟﺐ راﺣﺘﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺎ وﻳﮋوال 2005 C#ﻣﻲ ﺷﻮد .ﺑﺎ اﺳﺘﻔﺎده از ﻗﺴﻤﺖ Designﻣﻲ ﺗﻮاﻧﻴﺪ ﻇﺎﻫﺮ ﺑﺮﻧﺎﻣﻪ ﺧـﻮد را ﻃﺮاﺣـﻲ ﻛﻨﻴﺪ ،ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻗﺴﻤﺖ Codeﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻓﺮم را ﺑﻨﻮﻳﺴﻴﺪ. ﻗﺴﻤﺖ ﻣﻬﻢ دﻳﮕﺮ در ﭘﻨﺠﺮه ﻣﺮﺑﻮط ﺑﻪ ﻛﺪ ،دو ﺟﻌﺒﻪ ﺗﺮﻛﻴﺒﻲ ﻣﻮﺟﻮد در ﺑﺎﻻي ﺻﻔﺤﻪ اﺳﺖ .ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ دو ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑـﻪ ﺳـﺮﻋﺖ ﺑـﻪ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﻓﺮم ﺧﻮد دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ .اﺷﺎره ﮔﺮ ﻣﺎوس ﺧﻮد را ﺑﺮ روي ﺟﻌﺒﻪ ﺗﺮﻛﻴﺒﻲ ﺳﻤﺖ ﭼﭗ ﺑﺒﺮﻳﺪ و ﻣﻘـﺪاري ﺑـﺮ روي آن ﻧﮕﻪ دارﻳﺪ .راﻫﻨﻤﺎﻳﻲ ﻇﺎﻫﺮ ﺷﺪه و ﻣﻴﮕﻮﻳﺪ ﻛﻪ اﻳﻦ ﻛﺎدر ،ﻣﺮﺑﻮط ﺑﻪ Typesاﺳﺖ .اﮔﺮ اﻳﻦ ﻟﻴﺴﺖ را ﺑـﺎز ﻛﻨﻴـﺪ ،ﻟﻴـﺴﺘﻲ از ﺗﻤـﺎﻣﻲ ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﻓﺮم ﺧﻮد ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد .اﮔﺮ اﺷﺎره ﮔﺮ ﻣﺎوس ﺧﻮد را ﺑﺮ روي ﺟﻌﺒﻪ ﺗﺮﻛﻴﺒﻲ ﺳـﻤﺖ راﺳـﺖ ﺑﺒﺮﻳـﺪ ،راﻫﻨﻤـﺎي ﻇﺎﻫﺮ ﺷﺪه ﺑﻪ ﺷﻤﺎ ﻣﻲ ﮔﻮﻳﺪ ﻛﻪ اﻳﻦ ﻗﺴﻤﺖ ﻣﺮﺑﻮط ﺑﻪ Membersاﺳﺖ .اﮔﺮ اﻳﻦ ﻟﻴﺴﺖ را ﺑﺎز ﻛﻨﻴـﺪ ،ﻧـﺎم ﺗﻤـﺎم ﺗﻮاﺑـﻊ و زﻳﺮﺑﺮﻧﺎﻣـﻪ ﻫﺎﻳﻲ ﻛﻪ در ﻛﻼس اﻧﺘﺨﺎب ﺷﺪه در ﺳﻤﺖ ﭼﭗ ﻗﺮار دارﻧﺪ را ﺧﻮاﻫﻴﺪ دﻳﺪ .اﮔﺮ ﻓﺮم ﺟﺎري ﻣﺤﺘﻮي ﻣﻘﺪار زﻳﺎدي ﻛﺪ اﺳﺖ ،ﺑﻪ وﺳﻴﻠﻪ اﻳـﻦ ﻗﺴﻤﺖ ﻣﻴﺘﻮاﻧﻴﺪ ﺑﻪ راﺣﺘﻲ ﺑﻴﻦ ﺗﻮاﺑﻊ آن ﺟﺎ ﺑﻪ ﺟﺎ ﺷﻮﻳﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﻛﺪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ HelloUser (1ﺑﺮاي ﺷﺮوع اﺿﺎﻓﻪ ﻛﺮدن ﻛﺪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ،ﺑﺮ روي ﻗﺴﻤﺖ Designدر ﭘﻨﺠﺮه اﺻﻠﻲ ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﺑـﺎر دﻳﮕـﺮ ﻗـﺴﻤﺖ ﻃﺮاﺣﻲ را ﺑﺒﻴﻨﻴﺪ .ﺳﭙﺲ روي دﻛﻤﻪ ي OKدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﭘﻨﺠﺮه ي ﻛﺪ ﺑﺎ ﻛﺪي ﻛﻪ در زﻳﺮ ﻧﻮﺷﺘﻪ ﺷﺪه اﺳـﺖ ﺑـﺎز ﻣـﻲ
٣٧
ﺷﻮد .اﻳﻦ ﻛﺪ ﻛﻪ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ ،ﭘﻮﺳﺘﻪ ﻳﺎ ﻗﺎﻟﺐ روﻳﺪاد Clickﺑﺮاي ﻛﻨﺘﺮل Buttonاﺳـﺖ. در اﻳﻦ ﻗﺴﻤﺖ ﻣﻴﺘﻮاﻧﻴﺪ ﻛﺪي را وارد ﻛﻨﻴﺪ ﻛﻪ ﺑﺎ ﻫﺮ ﺑﺎر ﻛﻠﻴﻚ ﻛﺮدن روي اﻳﻦ ﻛﻨﺘﺮل اﺟﺮا ﺷﻮد .اﻳﻦ ﻛﺪ ﺑﻪ ﻋﻨـﻮان ﻛﻨﺘـﺮل ﻛﻨﻨﺪه ي روﻳﺪاد 1و ﻳﺎ زﻳﺮ ﺑﺮﻧﺎﻣﻪ روﻳﺪاد 2ﻧﺎﻣﻴﺪه ﻣﻲ ﺷﻮد .در ﻓﺼﻠﻬﺎي ﺑﻌﺪ ﺑﺎ اﻳﻦ ﻣﻮارد ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ: )private void btnOK_Click(object sender, EventArgs e { } در ﻛﺪ ﺑﺎﻻ ﻛﻠﻤﺎت voidو ﻳﺎ privateﻧﻤﻮﻧﻪ اي از ﻛﻠﻤﺎت ﻛﻠﻴﺪي در C#ﻫﺴﺘﻨﺪ .در اﺻﻄﻼﺣﺎت ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ، ﻛﻠﻤﺎت ﻛﻠﻴﺪي 3ﻛﻠﻤﺎﺗﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﻪ وﻳﮋوال C#ﻣﻴﮕﻮﻳﻨﺪ ﻛﺎرﻫﺎي ﺧﺎﺻﻲ را اﻧﺠﺎم دﻫﺪ .ﻣﺜﻼً در اﻳﻦ ﺟﺎ ،ﻛﻠﻤﻪ void ﺑﻪ وﻳﮋوال C#ﻣﻲ ﮔﻮﻳﺪ ﻛﻪ ﺗﺎﺑﻊ ﺗﻌﺮﻳﻒ ﺷﺪه ﻫﻴﭻ ﻣﻘﺪاري را ﺑﺮﻧﻤﻲ ﮔﺮداﻧﺪ .ﻫﻤـﻪ ي ﻛـﺪﻫﺎﻳﻲ ﻛـﻪ ﺷـﻤﺎ در ﺑـﻴﻦ ﺧﻄـﻮط ﻣﺮﺑﻮط ﺑﻪ ﺑﺎز ﺷﺪن آﻛﻮﻻد ){( و ﺑﺴﺘﻪ ﺷﺪن آن )}( ﺑﻨﻮﻳﺴﻴﺪ ،ﺗﺎﺑﻊ روﻳﺪاد ﻣﺮﺑﻮط ﺑﻪ دﻛﻤـﻪ OKرا ﺗـﺸﻜﻴﻞ ﻣـﻲ دﻫﻨـﺪ .در ﻓﺼﻞ ﺳﻮم ﺑﻴﺸﺘﺮ در ﻣﻮرد اﻳﻦ ﻣﺒﺎﺣﺚ ﮔﻔﺘﮕﻮ ﺧﻮاﻫﻴﻢ ﻛﺮد. (2ﺣﺎﻻ ﻛﺪﻫﺎي ﻣﺸﺨﺺ ﺷﺪه در اﻳﻦ ﻗﺴﻤﺖ را در ﺗﺎﺑﻊ وارد ﻛﻨﻴﺪ )در ﺑﻴﻦ آﻛﻮﻻدﻫﺎ ﺑﻨﻮﻳﺴﻴﺪ(: )private void btnOK_Click(object sender, EventArgs e { //Display a message box greeting the user MessageBox.Show("Hello " + txtName.Text + "! Welcome to Visual C# 2005.", ;)""Hello User Message } ﻧﻜﺘﻪ :ﺑﻪ ﻋﻠﺖ ﻛﻤﺒﻮد ﺟﺎ در اﻳﻦ ﺻﻔﺤﻪ ﻧﻤﻲ ﺗﻮاﻧﻴﻢ ﺗﻤﺎم ﻳﻚ دﺳﺘﻮر را ﭘﺸﺖ ﺳﺮ ﻫﻢ ﺑﻨﻮﻳﺴﻴﻢ ،اﻣﺎ در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ،ﺷﻤﺎ ﻣـﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ ﻛﺪﻫﺎ را ﭘﺸﺖ ﺳﺮ ﻫﻢ ﺑﻨﻮﻳﺴﻴﺪ .در وﻳﮋوال C#ﻳﻚ ﺧﻂ ﻛﺪ ،زﻣﺎﻧﻲ ﺗﻤﺎم ﻣﻴﺸﻮد ﻛﻪ ﻋﻼﻣﺖ ﻧﻘﻄﻪ وﻳﺮﮔﻮل );( ﺑﻌﺪ از آن ﺑﻴﺎﻳﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻴﺘﻮاﻧﻴﺪ ﻳﻚ دﺳﺘﻮر را در ﭼﻨﺪ ﺧﻂ ﺑﻨﻮﻳﺴﻴﺪ و ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻛﺎراﻛﺘﺮ ; را وارد ﻧﻜﺮده اﻳﺪ ﻧﻴﺰ دﺳـﺘﻮر را اداﻣـﻪ دﻫﻴﺪ. ﻧﻜﺘﻪ :در ﻃﻮل ﻛﺘﺎب ،ﺑﺎ ﻗﺴﻤﺘﻬﺎﻳﻲ روﺑﺮو ﻣﻲ ﺷﻮﻳﺪ ﻛﻪ ﺑﺎﻳﺪ ﻛﺪﻫﺎﻳﻲ را در ﺑﺮﻧﺎﻣﻪ ﺧﻮد وارد ﻛﻨﻴﺪ .ﻣﻌﻤﻮﻻ ﻫﺮ ﺟﺎ ﻛﻪ ﭼﻨﻴﻦ ﻣﻮردي ﭘﻴﺶ ﺑﻴﺎﻳﺪ ،ﻣﻜﺎن دﻗﻴﻖ وارد ﻛﺮدن ﻛﺪ را ﺑﺮاي ﺷﻤﺎ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻢ .ﻛﺪﻫﺎﻳﻲ ﻛﻪ ﺑﺎ رﻧﮓ ﭘـﻴﺶ زﻣﻴﻨـﻪ ﺧﺎﻛـﺴﺘﺮي ﻣـﺸﺨﺺ ﻣـﻲ ﺷـﻮﻧﺪ، ﻛﺪﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﺎﻳﺪ در ﺑﺮﻧﺎﻣﻪ وارد ﻛﻨﻴﺪ. (3ﺑﻌﺪ از اﻳﻨﻜﻪ ﻛﺪ ﻗﺴﻤﺖ ﻗﺒﻠﻲ را وارد ﻛﺮدﻳﺪ ،ﻣﺠﺪدا ﺑﻪ ﻗﺴﻤﺖ Designﺑﺮﮔﺮدﻳﺪ و روي دﻛﻤـﻪ Exitدوﺑـﺎر ﻛﻠﻴـﻚ ﻛﻨﻴﺪ .ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﺗﺎﺑﻊ btnExit_Clickوارد ﻛﻨﻴﺪ. )private void btnExit_Click(object sender, EventArgs e { 1
Event Handler Event Procedure 3 Keywords 2
٣٨
//End the program and close the form ;)(this.Close } اﺣﺘﻤﺎﻻ ﻛﻠﻤﻪ thisﺑﺮاﻳﺘﺎن ﺟﺪﻳﺪ اﺳﺖ this .ﻳﻚ ﻛﻠﻤﻪ ﻛﻠﻴـﺪي در C#اﺳـﺖ ﻛـﻪ ﺑـﻪ ﺷـﻴﺊ ﻛـﻪ در آن ،در ﺣـﺎل ﻛﺪﻧﻮﻳﺴﻲ ﻫﺴﺘﻴﻢ ،اﺷﺎره ﻣﻲ ﻛﻨﺪ .در اﻳﻦ ﺟﺎ ﭼﻮن ﻛﺪﻫﺎي ﻧﻮﺷﺘﻪ ﺷـﺪه ﻣﺮﺑـﻮط ﺑـﻪ ﻓـﺮم HelloUserاﺳـﺖ ،ﻛﻠﻤـﻪ thisﺑﻪ ﻓﺮم HelloUserاﺷﺎره ﻣﻲ ﻛﻨﺪ. (4ﺣﺎﻻ ﻛﻪ ﻛﺪﻧﻮﻳﺴﻲ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﭘﺎﻳﺎن رﺳﻴﺪ ،زﻣﺎن ﺗﺴﺖ ﻛﺮدن آن ﺷﺪه اﺳﺖ و ﻣﻲ ﺗﻮاﻧﻴﺪ ﺳﺎﺧﺘﻪ ﺧﻮدﺗﺎن را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ .اﺑﺘـﺪا ﺑﺮﻧﺎﻣﻪ را از ﻃﺮﻳﻖ ﻣﻨﻮي File Save HelloUser.csو ﻳﺎ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻠﻴﺪ Saveروي ﻧـﻮار اﺑﺰار ،ذﺧﻴﺮه ﻛﻨﻴﺪ. (5روي دﻛﻤﻪ Startﺑﺮ روي ﻧﻮار اﺑﺰار )ﻣﺜﻠﺚ ﺳﺒﺰ رﻧـﮓ( ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .ﭘﻨﺠـﺮه Outputدر ﭘـﺎﻳﻴﻦ ﺻـﻔﺤﻪ ،اﻧﺠـﺎم ﻓﻌﺎﻟﻴﺘﻬﺎي زﻳﺎدي را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .اﮔﺮ در وارد ﻛﺮدن ﻛﺪﻫﺎي ﺑﺮﻧﺎﻣﻪ ﻫﻴﭻ ﺧﻄﺎﻳﻲ ﺑﻪ وﺟﻮد ﻧﻴﺎﻳﺪ ،اﻃﻼﻋﺎت اﻳﻦ ﭘﻨﺠﺮه ﻓﻘﻂ ﺷﺎﻣﻞ اﺳﻢ ﻓﺎﻳﻠﻬﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﺮاي اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﺎرﮔﺬاري ﻣﻲ ﺷﻮﻧﺪ. در اﻳﻦ ﻣﺮﺣﻠﻪ ،ﺑﻪ اﺻﻄﻼح ،وﻳﮋوال اﺳﺘﻮدﻳﻮ در ﺣﺎل ﻛﺎﻣﭙﺎﻳﻞ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ اﺳﺖ .ﻛﺎﻣﭙﺎﻳﻞ ﻛﺮدن ﺑﻪ ﻣﺮﺣﻠﻪ اي ﮔﻔﺘﻪ ﻣﻲ ﺷـﻮد ﻛﻪ در آن ،از ﻛﺪ وﻳﮋوال 2005 C#ﻛﻪ ﺗﻮﺳﻂ ﺷﻤﺎ ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ ،ﻛﺪي ﺳﺎﺧﺘﻪ ﻣﻴﺸﻮد ﻛﻪ ﺗﻮﺳـﻂ ﻛـﺎﻣﭙﻴﻮﺗﺮ ﻗﺎﺑـﻞ ﻓﻬـﻢ ﺑﺎﺷﺪ .1ﺑﻌﺪ از اﻳﻨﻜﻪ ﻛﺎﻣﭙﺎﻳﻞ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺑﺎ ﻣﻮﻓﻘﻴﺖ ﺑﻪ ﭘﺎﻳﺎن رﺳﻴﺪ ،وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005آن را اﺟﺮا ﻣﻲ ﻛﻨـﺪ و ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﻧﺘﻴﺠﻪ ﻛﺎر ﺧﻮد را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ. اﮔﺮ در ﻣﺮﺣﻠﻪ ﻛﺎﻣﭙﺎﻳﻞ ﻛﺮدن ،وﻳﮋوال 2005 C#ﺑﺎ ﻫﺮ ﺧﻄﺎﻳﻲ در ﻛﺪ ﻣﻮاﺟﻪ ﺷﻮد ،آن را ﺑﻪ ﻋﻨﻮان ﻳﻚ وﻇﻴﻔﻪ در ﭘﻨﺠـﺮه ي Task Listﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .ﺑﺎ دوﺑﺎر ﻛﻠﻴﻚ ﻛﺮدن روي وﻇﻴﻔﻪ ﻣﻮرد ﻧﻈﺮ در ﺑﺨﺶ Task Listﺑﻪ ﻗﺴﻤﺘﻲ از ﻛﺪ ﻛﻪ ﺑﻪ آن ﻣﺮﺗﺒﻂ اﺳﺖ ،ﻣﻨﺘﻘﻞ ﻣﻲ ﺷﻮﻳﺪ .در ﻓﺼﻞ 11در ﻣﻮرد ﺧﻄﺎ ﻳﺎﺑﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ و اﺻﻼح آﻧﻬﺎ ﺑﻴـﺸﺘﺮ ﻳـﺎد ﺧـﻮاﻫﻴﻢ ﮔﺮﻓﺖ. (6ﺑﻌﺪ از اﻳﻨﻜﻪ ﺑﺮﻧﺎﻣﻪ اﺟﺮا ﺷﺪ ،ﺻﻔﺤﻪ اﺻﻠﻲ آن ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﻳﻚ ﻧﺎم را وارد ﻛﺮده و روي ﻛﻠﻴﺪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ )ﻳـﺎ ﻛﻠﻴﺪﻫﺎي Alt + Oرا ﻓﺸﺎر دﻫﻴﺪ() .ﺷﻜﻞ (17-1
– Compile 1در اﻳﻦ ﻣﻮرد در ﻓﺼﻞ دوم ﺑﻴﺸﺘﺮ ﺗﻮﺿﻴﺢ ﺧﻮاﻫﻴﻢ داد.
٣٩
ﺷﻜﻞ 17-1 (7ﭘﻨﺠﺮه اي ﻛﻪ ﺑﻪ ﻛﺎدر ﭘﻴﻐﺎم 1ﻣﻌﺮوف اﺳﺖ ،ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ و ﺑﻪ ﺷﺨﺼﻲ ﻛﻪ ﻧـﺎم او در TextBoxداﺧـﻞ ﻓـﺮم آﻣﺪه اﺳﺖ ﺧﻮش آﻣﺪ ﻣﻲ ﮔﻮﻳﺪ) .ﺷﻜﻞ (18-1
ﺷﻜﻞ 18-1 (8ﺑﻌﺪ از اﻳﻨﻜﻪ ﻛﺎدر ﭘﻴﻐﺎم را ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي دﻛﻤﻪ OKﺑﺴﺘﻴﺪ ،روي دﻛﻤﻪ Exitﺑﺮ روي ﻓـﺮم ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .ﺑﺮﻧﺎﻣـﻪ ﺑﺴﺘﻪ ﺧﻮاﻫﺪ ﺷﺪ و ﺷﻤﺎ ﺑﻪ ﻣﺤﻴﻂ وﻳﮋوال 2005 C#ﺑﺮﺧﻮاﻫﻴﺪ ﮔﺸﺖ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻛﺪي ﻛﻪ در روﻳﺪاد Clickﺑﺮاي دﻛﻤﻪ OKوارد ﻛﺮده اﻳﺪ ﻧﺎم ﻛﺎرﺑﺮي را ﻛﻪ در TextBoxﻓﺮم وارد ﺷﺪه اﺳﺖ درﻳﺎﻓﺖ ﻛـﺮده و آن را ﺑﻪ ﻋﻨﻮان ﺑﺨﺸﻲ از ﭘﻴﻐﺎم ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 18-1ﻧﺸﺎن ﻣﻲ دﻫﺪ. ﺧﻂ اوﻟﻲ ﻛﻪ در ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ ،ﻓﻘﻂ ﻳﻚ ﺗﻮﺿﻴﺢ اﺳﺖ .اﻳﻦ ﺗﻮﺿﻴﺢ ﺑﺮاي راﻫﻨﻤﺎﻳﻲ ﻛﺮدن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻛﻪ روي ﭘﺮوژه ﻛﺎر ﻣﻲ ﻛﻨﺪ و ﻳﺎ ﻛﺴﻲ ﻛﻪ ﺑﻌﺪﻫﺎ ﻣﻲ ﺧﻮاﻫﺪ ﻛﺪ ﺑﺮﻧﺎﻣﻪ را ﺑﺨﻮاﻧﺪ ﻧﻮﺷﺘﻪ ﻣـﻲ ﺷـﻮد و ﺗﻮﺳـﻂ ﻛـﺎﻣﭙﻴﻮﺗﺮ ﺧﻮاﻧـﺪه ﻧﻤـﻲ ﺷـﻮد. ﺗﻮﺿﻴﺤﺎت در وﻳﮋوال C#ﺑﺎ ) (//ﻣﺸﺨﺺ ﻣﻲ ﺷﻮﻧﺪ و ﻫﺮ ﻣﺘﻨﻲ ﻛﻪ ﺑﻌﺪ از اﻳﻦ دو ﻛﺎراﻛﺘﺮ وارد ﺷﻮد ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ ﻧﺎدﻳﺪه ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮد .در راﺑﻄﻪ ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ﺗﻮﺿﻴﺤﺎت در ﻓﺼﻞ ﺳﻮم ﺑﺤﺚ ﺷﺪه اﺳﺖ. ﺗﺎﺑﻊ MessageBox.Showﻳﻚ ﭘﻴﻐﺎم را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .اﻳﻦ ﺗﺎﺑﻊ ﭘﺎراﻣﺘﺮﻫﺎي ﻣﺨﺘﻠﻔﻲ را درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ .ﻣـﺜﻼ در ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ ،ﻳﻚ رﺷﺘﻪ ﻣﺘﻨﻲ را ﺑﻪ اﻳﻦ ﺗﺎﺑﻊ ﻓﺮﺳﺘﺎدﻳﺪ ﺗﺎ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﺪ .رﺷﺘﻪ ﻣﺘﻨﻲ ﺷﻤﺎ از اﺗﺼﺎل دو ﻣﻘﺪار ﺛﺎﺑﺖ ﻣﺘﻨﻲ ﻛﻪ در ﻋﻼﻣﺖ ﻧﻘﻞ ﻗﻮل )"( ﻗﺮار ﮔﺮﻓﺘﻪ ﺑﻮد ﺗﺸﻜﻴﻞ ﻣﻲ ﺷﺪ .ﺑﺮاي اﺗﺼﺎل ﭼﻨﺪ رﺷﺘﻪ ﻣﺘﻨﻲ ﺑﻪ ﻳﻜﺪﻳﮕﺮ و اﻳﺠﺎد ﻳﻚ رﺷﺘﻪ ﻃﻮﻻﻧﻲ در C#ﻣـﻲ ﺗﻮاﻧﻴﺪ ﻫﻤﺎﻧﻨﺪ ﻛﺎري ﻛﻪ ﺑﺮاي ﺟﻤﻊ ﻛﺮدن اﻋﺪاد اﻧﺠﺎم ﻣﻲ دﻫﻴﺪ ،از ﻋﻼﻣﺖ +اﺳﺘﻔﺎده ﻛﻨﻴﺪ. در ﺣﻘﻴﻘﺖ ﻛﺪي ﻛﻪ ﺑﻌﺪ از ﺧﻂ ﺗﻮﺿﻴﺤﺎت در ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ آﻣﺪه اﺳﺖ ،ﺛﺎﺑﺖ رﺷﺘﻪ اي " "Helloرا ﺑﺎ ﻣﻘـﺪار ﺧﺎﺻـﻴﺖ Text ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل txtNameﺟﻤﻊ ﻛﺮده و ﻋﺒـﺎرت " "! Welcome to Visual C# 2005را ﺑـﻪ رﺷـﺘﻪ ﺣﺎﺻﻞ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ .ﭘﺎراﻣﺘﺮ دوﻣﻲ ﻛﻪ ﺑﻪ ﻣﺘﺪ MessageBox.Showﻓﺮﺳﺘﺎده ﺷﺪه اﺳﺖ ،ﺗﻮﺳﻂ ﺗﺎﺑﻊ ﺑﻪ ﻋﻨﻮان ﻣﺘﻨﻲ ﻛـﻪ ﺑﺎﻳﺪ در ﻧﻮار ﻋﻨﻮان ﭘﻨﺠﺮه ﻧﻤﺎﻳﺶ داده ﺷﻮد اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد. ﻧﻜﺘﻪ دﻳﮕﺮي ﻛﻪ در اﻳﻦ ﻛﺪ ﻣﻬﻢ اﺳﺖ اﻳﻦ اﺳﺖ ﻛﻪ ﻳﻚ دﺳﺘﻮر را در ﭼﻨﺪ ﺧﻂ ﻧﻮﺷﺘﻪ اﻳﻢ .اﻳﻦ ﻛﺎر ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻳﻚ دﺳﺘﻮر ﻃﻮﻻﻧﻲ را وارد ﻛﻨﻴﻢ ﺑﺴﻴﺎر ﻣﻔﻴﺪ اﺳﺖ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ذﻛﺮ ﺷﺪ ،در C#ﻳﻚ دﺳﺘﻮر زﻣﺎﻧﻲ ﺗﻤﺎم ﻣﻴﺸﻮد ﻛﻪ ﻛﺎراﻛﺘﺮ ; ﺑﻌﺪ از آن ﻗﺮار ﮔﻴﺮد. ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﺑﻪ اﻳﻦ ﻛﺎراﻛﺘﺮ ﺑﺮﺧﻮرد ﻧﻜﺮده ﺑﺎﺷﺪ ،ﺗﻤﺎم ﻣﺘﻦ را ﺑﻪ ﻋﻨﻮان ﻳﻚ دﺳﺘﻮر در ﻧﻈﺮ ﻣﻲ ﮔﻴﺮد.
MessageBox
1
٤٠
)private void btnOK_Click(object sender, EventArgs e { //Display a message box greeting the user MessageBox.Show("Hello " + txtName.Text + "! Welcome to Visual C# 2005.", ;)""Hello User Message } ﻛﺪ ﺑﻌﺪي ﻛﻪ وارد ﻛﺮدﻳﺪ ،ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickﺑـﺮاي دﻛﻤـﻪ Exitﺑـﻮد .در آﻧﺠـﺎ ﺑـﺮاي ﺧـﺮوج از ﺑﺮﻧﺎﻣـﻪ ،ﺑـﻪ راﺣﺘـﻲ ﻛـﺪ )( this.Closeرا ﻧﻮﺷﺘﻴﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻗﺒﻼ ﻫﻢ ﺗﻮﺿﻴﺢ داده ﺷﺪ ،ﻛﻠﻤﻪ ﻛﻠﻴﺪي ،thisﺑﻪ ﻓﺮﻣﻲ ﻛـﻪ ﻫـﻢ اﻛﻨـﻮن در آن ﻫﺴﺘﻴﻢ اﺷﺎره ﻣﻲ ﻛﻨﺪ .ﻣﺘﺪ Closeاز ﻓﺮم ﺟﺎري ،ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﻓﺮم ﺑﺴﺘﻪ ﺷﺪه و ﺗﻤﺎم ﻣﻨﺎﺑﻌﻲ ﻛـﻪ ﺳﻴـﺴﺘﻢ در اﺧﺘﻴـﺎر آن ﻗـﺮار داده اﺳﺖ آزاد ﺷﻮﻧﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ ﻓﺮم )و در ﻧﺘﻴﺠﻪ ﺑﺮﻧﺎﻣﻪ( ﺑﺴﺘﻪ ﻣﻲ ﺷﻮد. )private void btnExit_Click(object sender, EventArgs e { //End the program and close the form ;)(this.Close } اﺣﺘﻤﺎﻻً ﻗﺴﻤﺘﻬﺎي زﻳﺎدي از ﻧﻮﺷﺘﻪ ﻫﺎي ﺑﺎﻻ را ﻣﺘﻮﺟﻪ ﻧﺸﺪه اﻳﺪ و ﻳﺎ ﺑﺮاﻳﺘﺎن ﻧﺎﻣﻔﻬﻮم اﺳﺖ .اﻣﺎ اﺻﻼً ﺟﺎي ﻧﮕﺮاﻧـﻲ ﻧﻴـﺴﺖ ،در ﻓـﺼﻠﻬﺎي ﺑﻌﺪي ﺗﻤﺎم اﻳﻦ ﻣﻮارد ﺑﻪ ﺗﻔﺼﻴﻞ ﺗﻮﺿﻴﺢ داده ﺧﻮاﻫﻨﺪ ﺷﺪ.
اﺳﺘﻔﺎده از ﺳﻴﺴﺘﻢ راﻫﻨﻤﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ: ﺳﻴﺴﺘﻢ راﻫﻨﻤﺎﻳﻲ ﻛﻪ در وﻳﮋوال 2005 C#ﺑﻪ ﻛﺎر رﻓﺘﻪ اﺳﺖ ،ﻧﺴﺨﻪ ي ارﺗﻘﺎ ﻳﺎﻓﺘﻪ ي ﻧﺴﺨﻪ ﻫﺎي ﻗﺒﻠﻲ اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﺳﺖ .ﺑﻪ ﺗﺪرﻳﺞ ﻛﻪ ﺷﺮوع ﺑﻪ ﻳﺎدﮔﻴﺮي وﻳﮋوال 2005 C#ﻛﻨﻴﺪ ،ﺑﺎ اﻳﻦ ﺳﻴﺴﺘﻢ راﻫﻨﻤﺎ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ .اﻣﺎ ﺧﻮب اﺳﺖ در اﻳﻨﺠﺎ ﺑﻪ ﻃﻮر ﻣﺨﺘﺼﺮ اﻳـﻦ ﺳﻴﺴﺘﻢ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﺪ ﺳﺮﻳﻌﺘﺮ اﻃﻼﻋﺎت ﻣﻮرد ﻧﻴﺎز ﺧﻮد را در آن ﭘﻴﺪا ﻛﻨﻴﺪ. ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻨﻮي Helpدر ﺷﻜﻞ 19-1ﻧﻤﺎﻳﺶ داده ﺷﺪه اﻧﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ ﺑﻴﻨﻴﺪ ،اﻳﻦ ﻣﻨﻮ ﻧﺴﺒﺖ ﺑﻪ ﻣﻨﻮي Helpدﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي ﮔﺰﻳﻨﻪ ﻫﺎي ﺑﻴﺸﺘﺮي دارد .دﻟﻴﻞ اﻳﻦ ﻣﻮﺿـﻮع ﻫـﻢ ﺣﺠﻢ زﻳﺎد ﻣﺴﺘﻨﺪاﺗﻲ اﺳﺖ ﻛﻪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ وﺟﻮد دارد .اﻓﺮاد ﻛﻤﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﻴﺸﺘﺮ ﻣﻮارد ﻣﻮرد ﻧﻴﺎز ﺧﻮد را در .NETاز ﺣﻔﻆ ﺑﺎﺷﻨﺪ. اﻣﺎ ﺧﻮﺷﺒﺨﺘﺎﻧﻪ ﻧﻴﺎزي ﺑﻪ ﺣﻔﻆ ﺑﻮدن آﻧﻬﺎ ﻧﻴﺴﺖ ،ﭼﻮن ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ راﺣﺘﻲ و ﺑﻪ ﺳﺮﻋﺖ ﺑﻪ ﺳﻴﺴﺘﻢ راﻫﻨﻤـﺎي وﻳـﮋوال اﺳـﺘﻮدﻳﻮ ﻣﺮاﺟﻌـﻪ ﻛﻨﻴﺪ. ﻳﻜﻲ از اﻣﻜﺎﻧﺎت ﺟﺎﻟﺐ راﻫﻨﻤﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ ،ﺳﻴﺴﺘﻢ راﻫﻨﻤﺎي دﻳﻨﺎﻣﻴﻚ آن اﺳﺖ .وﻗﺘﻲ ﺷﻤﺎ ﮔﺰﻳﻨﻪ Dynamic Helpرا از ﻣﻨﻮي Helpاﻧﺘﺨﺎب ﻣﻲ ﻛﻨﻴﺪ ،ﭘﻨﺠﺮه ﻣﺮﺑﻮط ﺑﻪ راﻫﻨﻤﺎي دﻳﻨﺎﻣﻴﻚ ﺑﺎز ﻣﻲ ﺷﻮد و ﻟﻴﺴﺘﻲ از ﻣﻮﺿﻮﻋﺎت ﻣﺮﺗﺒﻂ ﺑﺎ ﻛﺎري ﻛـﻪ در ﺣـﺎل اﻧﺠﺎم آن ﻫﺴﺘﻴﺪ را ﺑﻪ ﺷﻤﺎ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .ﭘﻨﺠﺮه راﻫﻨﻤﺎي دﻳﻨﺎﻣﻴﻚ از ﻃﺮﻳـﻖ اﻧﺘﺨـﺎب Help Dynamic Help در ﻧﻮار ﻣﻨﻮ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ اﺳﺖ .ﺑﺎ اﻧﺘﺨﺎب آن ﭘﻨﺠﺮه Dynamic Helpدر ﻛﻨﺎر ﭘﻨﺠـﺮه ي Propertiesدر ﻣﺤـﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
٤١
ﺷﻜﻞ 19-1 ﻣﺜﻼً ،ﻓﺮض ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﺷﻤﺎ در ﺣﺎل ﻛﺎر ﺑﺎ ﻳﻚ ﻛﻨﺘـﺮل TextBoxﻫـﺴﺘﻴﺪ )ﺑـﺮاي ﻣﺜـﺎل TextBoxاي ﻛـﻪ در ﺑﺮﻧﺎﻣـﻪ ي Hello Userﻗﺮار دادﻳﻢ( و ﻣﻲ ﺧﻮاﻫﻴﺪ ﻣﻘﺪاري اﻃﻼﻋﺎت راﺟﻊ ﺑﻪ آن ﻛﺴﺐ ﻛﻨﻴﺪ .ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ در ﻓﺮم و ﻳﺎ در ﻗﺴﻤﺖ ﻛـﺪ، TextBoxرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ ﺗﻤﺎم ﻣﻮﺿﻮﻋﺎت ﻣﺮﺗﺒﻂ ﺑﺎ آن را در ﭘﻨﺠﺮه راﻫﻨﻤﺎي دﻳﻨﺎﻣﻴﻚ ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ) .ﺷﻜﻞ (20-1 ﮔﺰﻳﻨﻪ ﻫﺎي دﻳﮕﺮ ﻣﻮﺟﻮد در ﻣﻨﻮي Content ،Serach) Helpو (Indexﻫﻤﺎﻧﻨﺪ دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨـﺪوزي ﻋﻤـﻞ ﻣﻴﻜﻨﻨﺪ .ﮔﺰﻳﻨﻪ How Do Iدر اﻳﻦ ﻣﻨﻮ ،ﻟﻴﺴﺘﻲ از ﻣﻮارد ﻣﻮﺟﻮد در راﻫﻨﻤﺎي وﻳﮋوال اﺳـﺘﻮدﻳﻮ ﻛـﻪ در آن ﻛﺎرﻫـﺎي ﻋﻤـﻮﻣﻲ دﺳـﺘﻪ ﺑﻨﺪي ﺷﺪه اﻧﺪ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
ﺷﻜﻞ 21-1
٤٢
ﺧﻼﺻﻪ: ﺧﻮﺷﺒﺨﺘﺎﻧﻪ ﺗﺎ ﻛﻨﻮن ﻣﺘﻮﺟﻪ ﺷﺪه اﻳﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺎ وﻳﮋوال 2005 C#ﺳﺨﺖ ﻧﻴﺴﺖ .ﻣﻘﺪاري ﻣﺤﻴﻂ وﻳﮋوال اﺳـﺘﻮدﻳﻮ را ﺑﺮرﺳـﻲ ﻛﺮده اﻳﺪ و دﻳﺪه اﻳﺪ ﻛﻪ اﻳﻦ ﻣﺤﻴﻂ ﭼﮕﻮﻧﻪ ﺑﻪ ﺷﻤﺎ ﻛﻤﻚ ﻣﻲ ﻛﻨﺪ ﺗﺎ ﺑﻪ ﺳﺮﻋﺖ ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﻃﺮاﺣﻲ ﻛﻨﻴﺪ .دﻳﺪﻳﺪ ﻛـﻪ ﺟﻌﺒـﻪ اﺑـﺰار ﻣـﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺷﻤﺎ در ﻃﺮاﺣﻲ راﺣﺖ و ﺳﺮﻳﻊ راﺑﻄﻬﺎي ﻛﺎرﺑﺮي ﻛﻤﻚ ﺑﺴﻴﺎري ﻛﻨﺪ .ﺑﻪ ﻛﻤﻚ ﭘﻨﺠﺮه Propertiesﻣﻲ ﺗﻮاﻧﻴﺪ ﺧﺎﺻﻴﺖ ﻫﺎي ﻛﻨﺘﺮل ﻫـﺎي ﻓـﺮم ﺧـﻮد را ﺑـﻪ راﺣﺘـﻲ ﺗﻐﻴﻴـﺮ داده و ﺑـﻪ ﺻـﻮرت دﻟﺨـﻮاه ﺗﻨﻈـﻴﻢ ﻛﻨﻴـﺪ .ﺑـﻪ ﻛﻤـﻚ ﭘﻨﺠـﺮه Solution Explorerﺗﻮاﻧﺴﺘﻴﺪ ﻧﻤﺎي درﺧﺘﻲ ﺗﻤﺎم ﻓﺎﻳﻠﻬﺎي ﺗﺸﻜﻴﻞ دﻫﻨﺪه ي ﭘﺮوژه را ﻣﺸﺎﻫﺪه ﻛﻨﻴـﺪ .ﺣﺘـﻲ در اﻳـﻦ ﺑﺨـﺶ ﻣﻘـﺪاري ﻛـﺪ ﻧﻮﺷﺘﻴﺪ. در ﻓﺼﻠﻬﺎي ﺑﻌﺪي ﺑﺎ ﺟﺰﻳﻴﺎت ﺑﻴﺸﺘﺮي درﮔﻴﺮ ﻣﻲ ﺷﻮﻳﺪ و ﺑﻴﺸﺘﺮ ﺑﻪ ﻛﺪ ﻧﻮﻳﺴﻲ ﻋﺎدت ﻣﻲ ﻛﻨﻴـﺪ .ﻗﺒـﻞ از اﻳﻨﻜـﻪ زﻳـﺎد وارد وﻳـﮋوال C# 2005ﺑﺸﻮﻳﻢ ،در ﻓﺼﻞ ﺑﻌﺪ ﭼﺎرﭼﻮب .NETرا ﻣﻌﺮﻓﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد. در ﭘﺎﻳﺎن ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ:
ﻣﺤﻴﻂ ﺗﻮﺳﻌﻪ ﻣﺠﺘﻤﻊ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﺎ IDE اﺿﺎﻓﻪ ﻛﺮدن ﻛﻨﺘﺮل ﺑﻪ ﻓﺮم در ﺣﺎﻟﺖ ﻃﺮاﺣﻲ ﺗﻨﻈﻴﻢ ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل ﻫﺎي روي ﻓﺮم اﺿﺎﻓﻪ ﻛﺮدن ﻛﺪ ﺑﻪ ﻛﻨﺘﺮل ﻫﺎ در ﭘﻨﺠﺮه ي ﻛﺪ
ﺗﻤﺮﻳﻦ: ﺑﺮﻧﺎﻣﻪ اي ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ ﺷﺎﻣﻞ ﻳﻚ ﻛﻨﺘﺮل TextBoxو ﻳﻚ Buttonﺑﺎﺷﺪ .ﺑﺎ ﻓﺸﺎر داده ﺷﺪن دﻛﻤﻪ ﺗﻮﺳﻂ ﻛﺎرﺑﺮ ،ﻣﺘﻨﻲ ﻛﻪ در TextBoxﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ در ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﺷﻮد. ﻧﻜﺘﻪ :ﭘﺎﺳﺦ اﻳﻦ ﺗﻤﺮﻳﻦ و دﻳﮕﺮ ﺗﻤﺮﻳﻦ ﻫﺎ ،در اﻧﺘﻬﺎي ﻛﺘﺎب در ﺿﻤﻴﻤﻪ ي 5آورده ﺷﺪه اﺳﺖ.
٤٣
ﻓﺼﻞ دوم :ﭼﺎرﭼﻮب .NETو ارﺗﺒﺎط آن ﺑﺎ C# در ﻓﺼﻞ ﻗﺒﻞ ﻣﻘﺪاري ﺑﺎ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ C#و ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ آﺷﻨﺎ ﺷﺪﻳﻢ .اﻣﺎ ﺑﻬﺘﺮ اﺳﺖ ﻗﺒﻞ از اﻳﻨﻜﻪ درﮔﻴﺮ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺎ اﻳﻦ زﺑﺎن و ﻛﺎر ﺑﺎ اﻳﻦ ﻣﺤﻴﻂ ﺷﻮﻳﻢ ،ﻣﻘﺪاري در راﺑﻄﻪ ﺑﺎ ﭼﺎرﭼﻮب 1.NETو ارﺗﺒﺎط آن ﺑﺎ وﻳﮋوال اﺳﺘﻮدﻳﻮ و C#ﺻﺤﺒﺖ ﻛﻨﻴﻢ. در اﻳﻦ ﻓﺼﻞ اﺑﺘﺪا ﻧﮕﺎﻫﻲ ﻛﻠﻲ ﺑﻪ ﺗﻜﻨﻮﻟﻮژي .NETﺧﻮاﻫﻴﻢ داﺷﺖ و ﺑﻌﺪ از ﻣﻌﺮﻓﻲ اﺟﺰاي آن ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ارﺗﺒﺎط آﻧﻬﺎ را ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﺷﺮح دﻫﻴﻢ .NET .ﻫﻨﻮز ﻳﻚ ﺗﻜﻨﻮﻟﻮژي ﺟﺪﻳﺪ ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد و داراي ﻣﺒﺎﺣﺚ ﻓﻨﻲ زﻳﺎدي اﺳﺖ ﻛﻪ ﻓﺮاﮔﻴﺮي آﻧﻬـﺎ در اﺑﺘـﺪا ﻛﻤـﻲ ﻣﺸﻜﻞ ﺑﻪ ﻧﻈﺮ ﻣﻲ رﺳﺪ .ﻣﺸﻜﻞ ﺑﻮدن آن ﻧﻴﺰ ﺑﻪ اﻳﻦ ﻋﻠﺖ اﺳﺖ ﻛﻪ .NETﻳﻚ ﭼﺎرﭼﻮب ﻳﺎ ﻓﺮﻳﻢ ورك اﺳﺖ و ﻳﻚ ﻓﺮﻳﻢ ورك ،راه و روش ﺟﺪﻳﺪي را ﺑﺮاي ﻃﺮاﺣﻲ و ﺗﻮﺳﻌﻪ ﻧﺮم اﻓﺰار اراﺋﻪ ﻣﻲ دﻫﺪ .در ﻃﻮل اﻳﻦ ﻓﺼﻞ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﻣﻔﺎﻫﻴﻢ ﺟﺪﻳﺪ اراﺋﻪ ﺷﺪه در .NET را ﺑﻪ ﻃﻮر ﺧﻼﺻﻪ و اﺟﻤﺎﻟﻲ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ. در اﻳﻦ ﻓﺼﻞ:
ﭼﺎرﭼﻮب .NETﭼﻴﺴﺖ؟ ﭼﺎرﭼﻮب .NETﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ و ﭼﻪ ﭼﻴﺰي ﺑﺎﻋﺚ ﺷﺪه اﺳﺖ ﻛﻪ ﺑﻪ ﻳﻚ ﻓﺮﻳﻢ ورك ﭘﺮﻃﺮﻓﺪار ﺗﺒﺪﻳﻞ ﺷﻮد؟ ﺑﺎ زﺑﺎن C#ﭼﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ را ﻣﻲ ﺗﻮان ﻧﻮﺷﺖ؟
ﭼﺎرﭼﻮب .NETﭼﻴﺴﺖ؟ ﻗﺒﻞ از ﻫﺮ ﭼﻴﺰ ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﺗﻌﺮﻳﻒ دﻗﻴﻘﻲ از ﻛﻠﻤﺎت ﻓﺮﻳﻢ ورك ﻳﺎ ﭼﺎرﭼﻮب و ﻫﻤﭽﻨﻴﻦ ﭘﻠﺘﻔﺮم اراﺋﻪ دﻫﻴﻢ. در ﺗﻌﺮﻳﻒ .NETﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ ﻛﻪ" :ﭼﺎرﭼﻮب .NETﻳﻚ ﭘﻠﺘﻔﺮم ﺟﺪﻳﺪ اﺳﺖ ﻛﻪ ﺗﻮﺳﻂ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﺑﺮاي ﻃﺮاﺣﻲ و ﺗﻮﺳـﻌﻪ ﻧﺮم اﻓﺰار اﻳﺠﺎد ﺷﺪه اﺳﺖ". ﻧﻜﺘﻪ ﺟﺎﻟﺒﻲ ﻛﻪ در اﻳﻦ ﺗﻌﺮﻳﻒ وﺟﻮد دارد اﺑﻬﺎم زﻳﺎدي اﺳﺖ ﻛﻪ در اﻳﻦ ﺗﻌﺮﻳﻒ ﺑﻪ ﻛﺎر ﺑﺮده ام ،اﻣﺎ ﺑﺮاي اﻳﻦ ﻛﺎر دﻟﻴﻞ ﺧـﻮﺑﻲ وﺟـﻮد دارد. ﺑﺮاي ﺷﺮوع ،ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﺗﻌﺮﻳﻒ ﻧﮕﻔﺘﻪ ام "ﻃﺮاﺣﻲ و ﺗﻮﺳﻌﻪ ﻧﺮم اﻓﺰار ﺑـﺮاي ﺳﻴـﺴﺘﻢ ﻋﺎﻣـﻞ وﻳﻨـﺪوز ".اﮔﺮﭼـﻪ ﻣﺎﻳﻜﺮوﺳـﺎﻓﺖ ﭼﺎرﭼﻮب .NETرا ﺑﺮاي اﺟﺮا ﺑﺮ روي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ وﻳﻨﺪوز ﻣﻨﺘﺸﺮ ﻛﺮده اﺳﺖ ،ﺑـﻪ زودي ﻧـﺴﺨﻪ ﻫـﺎي دﻳﮕـﺮي از اﻳـﻦ ﭼـﺎرﭼﻮب را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺑﺮ روي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻫﺎي دﻳﮕﺮ ﻣﺎﻧﻨﺪ ﻟﻴﻨﻮﻛﺲ ﻧﻴﺰ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ .ﻳﻜﻲ از اﻳﻦ ﻧﺴﺨﻪ ﻫـﺎ ﻣﻮﻧـﻮ 2اﺳـﺖ .ﻣﻮﻧـﻮ ﻳﻚ ﻧﺴﺨﻪ ﻣﺘﻦ ﺑﺎز از ﭼﺎرﭼﻮب .NETاﺳﺖ )ﻛﻪ ﺷﺎﻣﻞ ﻳﻚ ﻛﺎﻣﭙﺎﻳﻠﺮ C#ﻧﻴﺰ ﻫﺴﺖ( ﻛﻪ ﺑﺮاي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻫﺎي ﮔﻮﻧـﺎﮔﻮﻧﻲ ﻣﺎﻧﻨـﺪ ﻧﺴﺨﻪ ﻫﺎي ﻣﺨﺘﻠﻒ ﻟﻴﻨﻮﻛﺲ و ﻣﻜﻴﻨﺘﺎش ﻣﻨﺘﺸﺮ ﺷﺪه اﺳﺖ .ﭘﺮوژه ﻫﺎي ﺑﺴﻴﺎر دﻳﮕﺮي ﻣﺸﺎﺑﻪ ﻣﻮﻧﻮ در ﺣﺎل اﺟﺮا ﻫﺴﺘﻨﺪ ﻛﻪ ﻣﻤﻜﻦ اﺳـﺖ ﻫﻨﮕﺎم اﻧﺘﺸﺎر اﻳﻦ ﻛﺘﺎب در اﺧﺘﻴﺎر ﺷﻤﺎ ﻗﺮار ﮔﺮﻓﺘﻪ ﺑﺎﺷﻨﺪ .ﺑﻪ ﻋـﻼوه ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﺎ اﺳـﺘﻔﺎده از ﻧـﺴﺨﻪ ﻓـﺸﺮده اﻳـﻦ ﭼـﺎرﭼﻮب ﺑـﻪ ﻧـﺎم Microsoft .NET Compact Frameworkﻛﻪ زﻳﺮ ﻣﺠﻤﻮﻋﻪ اي از ﭼﺎرﭼﻮب .NETاﺳﺖ ﺑﺮاي وﺳـﺎﻳﻞ ﻫﻮﺷﻤﻨﺪ ﻣﺎﻧﻨﺪ دﺳﺘﻴﺎر دﻳﺠﻴﺘﺎل ﺷﺨﺼﻲ 3و ﻳﺎ ﻣﻮﺑﺎﻳﻞ ﻫﺎ ﻧﻴﺰ ﺑﺮﻧﺎﻣﻪ ﺑﻨﻮﻳﺴﻴﺪ )ﺑﺎ اﻳﻦ ﭼﺎرﭼﻮب در ﻓﺼﻞ ﺑﻴﺴﺖ و دوم ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧـﻮاﻫﻴﻢ ﺷﺪ(. اﮔﺮ ﺑﻪ ﺗﻌﺮﻳﻔﻲ ﻛﻪ در ﺑﺎﻻ ﺑﺮاي ﭼﺎرﭼﻮب .NETآورده ﺷﺪه اﺳﺖ دﻗﺖ ﻛﻨﻴﺪ ،ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ ﺗﻌﺮﻳﻒ ﻣﺤﺪود ﺑﻪ ﻧﻮع ﺧﺎﺻـﻲ از ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻧﻴﺴﺖ .در ﺣﻘﻴﻘﺖ در ﻣﻮرد ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺗﻮان ﺑﺎ .NETﻧﻮﺷﺖ ﻫﻴﭻ ﻣﺤﺪودﻳﺘﻲ وﺟﻮد ﻧﺪارد ﻛﻪ ﺑﺨﻮاﻫﻴﻢ آن را 1
.NET Framework Mono 3 )Personal Digital Assistant (PDA 2
٤٤
ذﻛﺮ ﻛﻨﻴﻢ .از ﭼﺎرﭼﻮب .NETﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮاي ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز ،ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ،ﺳﺮوﻳﺴﻬﺎي ﻣﺒﺘﻨﻲ ﺑـﺮ وب و ...اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﭼﺎرﭼﻮب .NETﻳﻚ ﭼﺎرﭼﻮب ﻛﻠﻲ اﺳﺖ و ﻣﺤﺪود ﺑﻪ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺧﺎﺻﻲ ﻧﻴﺴﺖ .ﺷﻤﺎ ﻣﻲ ﺗﻮاﻧﻴـﺪ ﺑﺮﻧﺎﻣـﻪ ﺧﻮدﺗـﺎن را ﺑـﻪ ﻫـﺮ زﺑﺎﻧﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺑﻨﻮﻳﺴﻴﺪ .در اﻳﻦ ﻛﺘﺎب ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻪ زﺑﺎن C#را ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ ،اﻣﺎ ﻋﻼوه ﺑﺮ اﻳﻦ زﺑﺎن ﻣﻲ ﺗﻮاﻧﻴﺪ از زﺑﺎﻧﻬـﺎﻳﻲ ﻣﺎﻧﻨﺪ ،C++وﻳﮋوال ﺑﻴﺴﻴﻚ ،ﺟﺎوا و ﺣﺘﻲ زﺑﺎﻧﻬﺎي ﻗﺪﻳﻤﻲ ﻣﺎﻧﻨﺪ COBOLﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻴـﺪ .ﺑـﺮاي ﻫـﺮ ﻛـﺪام از اﻳـﻦ زﺑﺎﻧﻬـﺎ ﻳـﻚ ﻛﺎﻣﭙﺎﻳﻠﺮ ﺧﺎص .NETاراﺋﻪ ﻣﻲ ﺷﻮد .ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ ﻛﺎﻣﭙﺎﻳﻠﺮ ،ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻧﻮﺷﺘﻪ ﺷﺪه ﺑﻪ اﻳﻦ زﺑﺎﻧﻬﺎ ﻧﻪ ﺗﻨﻬـﺎ ﻣـﻲ ﺗﻮاﻧﻨـﺪ ﺑـﺎ ﭼـﺎرﭼﻮب .NETارﺗﺒﺎط داﺷﺘﻪ ﺑﺎﺷﻨﺪ ،ﺑﻠﻜﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي زﺑﺎﻧﻬﺎي دﻳﮕﺮ ﻛﻪ ﺗﺤﺖ .NETﻧﻮﺷﺘﻪ ﺷﺪه اﻧﺪ ﻧﻴﺰ ارﺗﺒﺎط داﺷـﺘﻪ ﺑﺎﺷـﻨﺪ. ﺑﺮاي ﻣﺜﺎل ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻛﻪ ﺑﻪ زﺑﺎن C#ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ ﺑﻪ راﺣﺘﻲ ﻣﻲ ﺗﻮاﻧﺪ از ﻛﺪي اﺳﺘﻔﺎده ﻛﻨﺪ ﻛﻪ ﺑﻪ زﺑﺎن وﻳـﮋوال ﺑﻴـﺴﻴﻚ ﻧﻮﺷـﺘﻪ ﺷﺪه اﺳﺖ و ﻳﺎ ﺑﺮﻋﻜﺲ. ﻣﻮاردي ﻛﻪ ﺗﺎ ﻛﻨﻮن ﮔﻔﺘﻴﻢ ﺳﻄﺢ ﺑﺎﻻي ﺗﻨﻮع در .NETرا ﻧﺸﺎن ﻣﻲ دﻫﻨﺪ .اﻳﻦ ﺗﻨـﻮع ﻳﻜـﻲ از دﻻﻳﻠـﻲ اﺳـﺖ ﻛـﻪ ﺑﺎﻋـﺚ ﻣـﻲ ﺷـﻮد ﭼﺎرﭼﻮب .NETﭼﻨﻴﻦ دورﻧﻤﺎي ﺟﺬاﺑﻲ داﺷﺘﻪ ﺑﺎﺷﺪ. ﭘﺲ دﻗﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ .NETﻳﻚ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ،ﻳﻚ ﻣﺪل ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺗﺤﺖ وﻳﻨﺪوز ،ﻳﻚ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺮاي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻠﻲ ﺧﺎص ﻣﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺗﺤﺖ وﻳﻨﺪوز و ﻳﺎ ﻣﻮاردي از اﻳﻦ ﻗﺒﻴﻞ ﻧﻴﺴﺖ .ﺑﻠﻜﻪ .NETﻳـﻚ روش ﺑـﺮاي ﻃﺮاﺣﻲ و ﺗﻮﺳﻌﻪ ي ﻧﺮم اﻓﺰار اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﻣﻌﺮﻓﻲ ﺷﺪه اﺳﺖ و ﻣﻲ ﺗﻮاﻧﺪ در ﺗﻤﺎﻣﻲ ﻣﻮاردي ﻛﻪ در ﺑﺎﻻ ذﻛـﺮ ﺷـﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد.
ﭼﺎرﭼﻮب .NETاز ﭼﻪ اﺟﺰاﻳﻲ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ؟ ﻳﻜﻲ از اﺟﺮاي اﺻﻠﻲ ﭼﺎرﭼﻮب .NETﻛﺘﺎﺑﺨﺎﻧﻪ ﻛﻼس ﻋﻈﻴﻢ آن اﺳﺖ ﻛﻪ ﻣـﻲ ﺗﻮاﻧﻴـﺪ از آن در ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي ﺧـﻮد اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ. ﻛﺘﺎﺑﺨﺎﻧﻪ ﻛﻼس 1ﻳﻚ ﻣﺠﻤﻮﻋﻪ از ﺗﻮاﺑﻊ و ﻛﻼﺳﻬﺎ اﺳﺖ ﻛﻪ ﺑﺮاي اﻧﺠﺎم اﻣﻮر ﻣﺨﺘﻠﻒ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد .ﺑـﺮاي ﻣﺜـﺎل ﻳـﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻛﻼس ،ﺷﺎﻣﻞ ﺗﻮاﺑﻌﻲ ﺑﺮاي ﻛﻨﺘﺮل ورودي و ﺧﺮوﺟﻲ ،اﺳﺘﻔﺎده از اﻣﻜﺎﻧﺎت ﭼﺎپ ،ﻛﺎر ﺑﺎ اﻧﻮاع ﻣﺨﺘﻠﻒ ﺷﺒﻜﻪ ﻫﺎ و ...اﺳـﺖ .اﻳـﻦ ﺗﻮاﺑﻊ و ﻛﻼﺳﻬﺎ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﺗﻜﻨﻴﻜﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا ﻧﻮﺷﺘﻪ ﺷﺪه اﻧﺪ ،2در .NETﺑـﻪ ﮔـﺮوه ﻫـﺎ و ﻳـﺎ ﻓـﻀﺎي ﻧﺎﻣﻬـﺎي ﻣﺨﺘﻠﻔﻲ دﺳﺘﻪ ﺑﻨﺪي ﻣﻲ ﺷﻮﻧﺪ .ﺑﺎ ﻣﻔﻬﻮم ﻓﻀﺎي ﻧﺎم در ﻓﺼﻞ 9ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ. در ﻧﻮﺷﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﻫﺮ ﻛﺪام از ﻓﻀﺎي ﻧﺎﻣﻬﺎ را ﻛﻪ ﻧﻴﺎز داﺷﺘﻴﺪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻳﻜﻲ از اﻳﻦ ﻓـﻀﺎي ﻧﺎﻣﻬـﺎ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺗﺤﺖ وﻳﻨﺪوز ﺑﻪ ﻛﺎر ﻣﻲ رود ،ﻳﻜﻲ دﻳﮕﺮ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﺒﻜﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد ،ﻓﻀﺎي ﻧﺎم دﻳﮕـﺮي ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺗﺤﺖ وب ﺑﻪ ﻛﺎر ﻣﻲ رود .ﺑﻌﻀﻲ از اﻳﻦ ﻓﻀﺎي ﻧﺎﻣﻬﺎ ﺧﻮد ﺑﻪ ﻓﻀﺎي ﻧﺎﻣﻬﺎي ﻛﻮﭼﻜﺘﺮي ﺗﻘﺴﻴﻢ ﻣﻲ ﺷﻮﻧﺪ ﻛـﻪ ﺑـﺮاي ﻛﺎرﺑﺮد ﺧﺎﺻﻲ در آن ﻗﺴﻤﺖ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮﻧﺪ .ﺑﺮاي ﻣﺜﺎل ﻓﻀﺎي ﻧﺎم ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺗﺤﺖ وب ﺷﺎﻣﻞ ﻳﻚ ﻓﻀﺎي ﻧﺎم ﻛﻮﭼﻜﺘﺮ اﺳﺖ ﻛـﻪ ﺑﺮاي ﻧﻮﺷﺘﻦ ﺳﺮوﻳﺴﻬﺎي ﺗﺤﺖ وب ﺑﻪ ﻛﺎر ﻣﻲ رود. ﺑﺎﻳﺪ ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﺗﻤﺎم ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻫﺎ ،ﻫﻤﻪ ﺗﻮاﺑﻊ ﻣﻮﺟﻮد در اﻳﻦ ﻓﻀﺎي ﻧﺎﻣﻬﺎ را ﭘﺸﺘﻴﺒﺎﻧﻲ ﻧﻤﻲ ﻛﻨﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻳﻚ دﺳـﺘﻴﺎر دﻳﺠﻴﺘﺎل ﺷﺨﺼﻲ از ﺗﻮاﺑﻊ اﺻﻠﻲ ﭼﺎرﭼﻮب .NETﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ ﻛﻨﺪ ،اﻣﺎ ﻳﻚ ﺳﺮي از ﺗﻮاﺑﻊ ﻛﻪ در اﻳـﻦ وﺳـﺎﻳﻞ ﻛـﺎرﺑﺮدي ﻧـﺪارد ﺑـﻪ وﺳﻴﻠﻪ آﻧﻬﺎ ﭘﺸﺘﻴﺒﺎﻧﻲ ﻧﻤﻲ ﺷﻮد. ﺑﺨﺶ دﻳﮕﺮي از ﭼﺎرﭼﻮب ،.NETﻳﻚ ﺳﺮي ﻧﻮع ﻫﺎي داده اي اﺑﺘـﺪاﻳﻲ را ﺗﻌﺮﻳـﻒ ﻣـﻲ ﻛﻨـﺪ .ﻧـﻮع ﻫـﺎي داده اي ﺑـﺮاي ﻧﮕﻬـﺪاري اﻃﻼﻋﺎت ﻳﻚ ﺑﺮﻧﺎﻣﻪ در ﻃﻮل اﺟﺮاي آن ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ .ﻧﻮع ﻫﺎي داده اي ﻛﻪ در اﻳـﻦ ﻗـﺴﻤﺖ از .NETﺗﻌﺮﻳـﻒ ﻣـﻲ ﺷﻮﻧﺪ ﺑﻪ ﺻﻮرت ﺑﺴﻴﺎر ﭘﺎﻳﻪ اي ﻫﺴﺘﻨﺪ )ﻣﺎﻧﻨﺪ "ﻋﺪد ﺻﺤﻴﺢ ﻋﻼﻣﺖ دار 32ﺑﻴﺘﻲ"( .ﻧﻮع ﻫﺎي داده اي ﭘﻴـﺸﺮﻓﺘﻪ ﺗـﺮي ﻛـﻪ در زﺑﺎﻧﻬـﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺒﺘﻨﻲ ﺑﺮ .NETﻣﺎﻧﻨﺪ C#و ﻳﺎ وﻳﮋوال ﺑﻴﺴﻴﻚ وﺟﻮد دارﻧﺪ ﺑﺎﻳﺪ ﺑﺮ اﺳﺎس ﻳﻜﻲ از اﻳﻦ ﻧﻮع ﻫﺎي داده اي ﺗﻌﺮﻳﻒ ﺷـﺪه Class Library
1
2ﺑﺎ اﻳﻦ ﺗﻜﻨﻴﻚ ﻫﺎ در ﻓﺼﻮل 9و 10آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ.
٤٥
در اﻳﻦ ﻗﺴﻤﺖ از ﭼﺎرﭼﻮب .NETﺑﺎﺷﻨﺪ .اﻳﻦ ﻣﻮرد ﺑﺎﻋﺚ ﻫﻤﺎﻫﻨﮕﻲ ﺑﻴﻦ زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﻲ ﺷـﻮد ﻛـﻪ از ﭼـﺎرﭼﻮب .NET اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ .اﻳﻦ ﻗﺴﻤﺖ از ﭼﺎرﭼﻮب ،.NETﺳﻴﺴﺘﻢ ﻧﻮع داده اي ﻋﻤﻮﻣﻲ و ﻳﺎ ﺑﻪ اﺧﺘﺼﺎر 1CTSﻧﺎﻣﻴﺪه ﻣﻲ ﺷﻮد .ﺑﺎ ﻧﻮع ﻫـﺎي داده اي در ﻓﺼﻞ ﺑﻌﺪ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ. 2 ﻋﻼوه ﺑﺮ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻛﻼﺳﻲ ﻛﻪ ذﻛﺮ ﺷﺪ ،ﭼﺎرﭼﻮب .NETﺷﺎﻣﻞ ﺑﺨﺸﻲ ﺑﻪ ﻧﺎم زﺑﺎن ﻋﻤﻮﻣﻲ زﻣﺎن اﺟﺮا و ﻳﺎ ﺑﻪ اﺧﺘﺼﺎر CLRاﺳـﺖ. اﻳﻦ ﺑﺨﺶ از ﭼﺎرﭼﻮب ) .NETﻛﻪ ﻣﻬﻤﺘﺮﻳﻦ ﺑﺨﺶ آن ﻧﻴﺰ ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد( ﻣﺴﺌﻮل ﻛﻨﺘﺮل و ﻣﺪﻳﺮﻳﺖ اﺟﺮاي ﺗﻤـﺎم ﺑﺮﻧﺎﻣـﻪ ﻫـﺎﻳﻲ اﺳﺖ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﺘﺎﺑﺨﺎﻧﻪ ﻛﻼس .NETﻧﻮﺷﺘﻪ ﺷﺪه اﻧﺪ.3
ﭼﮕﻮﻧﻪ ﺑﺎ اﺳﺘﻔﺎده از ﭼﺎرﭼﻮب .NETﺑﺮﻧﺎﻣﻪ ﺑﻨﻮﻳﺴﻴﻢ؟ ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از ﭼﺎرﭼﻮب .NETﺑﻪ ﻣﻌﻨﻲ ﻧﻮﺷﺘﻦ ﻛﺪ ﺑﻪ ﻫﺮ ﻛﺪام از زﺑﺎﻧﻬﺎﻳﻲ ﻛﻪ ﺗﻮﺳﻂ .NETﭘﺸﺘﻴﺒﺎﻧﻲ ﻣـﻲ ﺷـﻮﻧﺪ ،ﺑـﺎ اﺳﺘﻔﺎده از ﻛﺘﺎﺑﺨﺎﻧﻪ ﻛﻼس .NETاﺳﺖ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ در ﻃﻮل اﻳﻦ ﻛﺘﺎب از ﻣﺤﻴﻂ ﻃﺮاﺣﻲ ﻣﺠﺘﻤـﻊ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ )(IDE ﺑﺮاي ﻃﺮاﺣﻲ و ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .ﻣﺰﻳﺖ اﺳﺘﻔﺎده از اﻳﻦ ﻣﺤﻴﻂ اﻳﻦ اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑـﻪ راﺣﺘـﻲ از وﻳﮋﮔﻴﻬـﺎﻳﻲ ﻛـﻪ در ﺑﺨﺸﻬﺎي ﻗﺒﻠﻲ از ﭼﺎرﭼﻮب .NETﻣﻌﺮﻓﻲ ﻛﺮدﻳﻢ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﻛﺪي ﻛﻪ ﺷﻤﺎ ﺑﺮاي ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ در ﻃﻮل اﻳﻦ ﻛﺘﺎب اﺳﺘﻔﺎده ﻣـﻲ ﻛﻨﻴﺪ ﻛﻼً ﺑﻪ زﺑﺎن C#اﺳﺖ ،اﻣﺎ در ﻃﻮل ﺑﺮﻧﺎﻣﻪ ﻫﺎ از ﭼﺎرﭼﻮب .NETو ﻫﻤﭽﻨﻴﻦ از ﻳﻚ ﺳﺮي وﻳﮋﮔﻲ ﻫـﺎ و اﺑﺰارﻫـﺎﻳﻲ ﻛـﻪ ﻣﺤـﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ در اﺧﺘﻴﺎر ﻣﺎ ﻗﺮار ﻣﻲ دﻫﺪ اﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد. ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻛﻪ ﺑﻪ زﺑﺎن C#ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ ﻗﺒﻞ از اﺟﺮا ﺑﺎﻳﺪ ﺑﻪ ﻛﺪي ﺗﺒﺪﻳﻞ ﺷﻮد ﻛﻪ ﺑﺮاي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻗﺎﺑﻞ ﻓﻬﻢ ﺑﺎﺷﺪ .ﺑﻪ اﻳﻦ ﻛـﺪ، ﻛﺪ ﻣﺤﻠﻲ 4ﻣﻲ ﮔﻮﻳﻨﺪ .ﺗﺒﺪﻳﻞ ﻳﻚ ﻛﺪ از ﻫﺮ زﺑﺎﻧﻲ ﺑﻪ ﻛﺪ ﻣﺤﻠﻲ ﻛﻪ ﺑﺮاي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻗﺎﺑﻞ ﻓﻬﻢ ﺑﺎﺷﺪ را ﻛﺎﻣﭙﺎﻳﻞ ﻛﺮدن ﻣﻲ ﮔﻮﻳﻨـﺪ و ﻋﻤﻠﻲ اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ اﻧﺠﺎم ﻣﻲ ﺷﻮد .در ﭼﺎرﭼﻮب .NETاﻳﻦ ﺑﺨﺶ از دو ﻣﺮﺣﻠﻪ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ.
MSILو :JIT ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در آن از ﺗﻮاﺑﻊ ﻣﻮﺟﻮد در ﻛﺘﺎﺑﺨﺎﻧﻪ ﻛﻼس .NETاﺳﺘﻔﺎده ﺷﺪه اﺳﺖ را ﻛﺎﻣﭙﺎﻳﻞ ﻣـﻲ ﻛﻨﻴـﺪ ،ﺑﻼﻓﺎﺻـﻠﻪ ﻛـﺪ ﻗﺎﺑﻞ ﻓﻬﻢ ﺑﺮاي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ و ﻳﺎ ﻛﺪ ﻣﺤﻠﻲ ﺗﻮﻟﻴﺪ ﻧﻤﻲ ﺷﻮد .در ﻋﻮض ﻛﺪ ﺷﻤﺎ ﺑﻪ زﺑﺎﻧﻲ ﺑﻪ ﻧﺎم زﺑﺎن ﺳﻄﺢ ﻣﻴﺎﻧﻲ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ و ﻳﺎ ﺑـﻪ اﺧﺘﺼﺎر 5MSILﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮد .اﻳﻦ ﻛﺪ ﺑﺮاي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﺧﺎﺻﻲ ﻧﻴﺴﺖ و ﻫﻤﭽﻨﻴﻦ ﻣﻨﺤﺼﺮ ﺑﻪ زﺑﺎن C#ﻧﻴﺰ ﻧﻴـﺴﺖ .ﺑـﻪ ﻋﺒـﺎرت دﻳﮕﺮ ﻛﺪ زﺑﺎﻧﻬﺎي دﻳﮕﺮ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ MSILﺗﺒﺪﻳﻞ ﺷﻮد )و اﻟﺒﺘﻪ ﺑﺎﻳﺪ ﺗﺒﺪﻳﻞ ﺷـﻮﻧﺪ( .ﻛـﺪﻫﺎي زﺑﺎﻧﻬـﺎي دﻳﮕـﺮي ﻛـﻪ از ﭼـﺎرﭼﻮب .NETاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﻧﻴﺰ )ﻣﺎﻧﻨﺪ وﻳﮋوال ﺑﻴﺴﻴﻚ( ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ اﺑﺘﺪا ﺑﻪ زﺑﺎن MSILﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮﻧﺪ .ﻫﻨﮕﺎم اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮاي ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ،اﻳﻦ ﻣﺮﺣﻠﻪ از ﻛﺎﻣﭙﺎﻳﻞ ﺗﻮﺳﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻧﺠﺎم ﻣﻲ ﺷﻮد. اﻣﺎ ﺑﺮاي اﺟﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﻮﺳﻂ ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻳﻚ ﻣﺮﺣﻠﻪ دﻳﮕﺮ ﻧﻴﺰ ﻣﻮرد ﻧﻴﺎز اﺳﺖ .اﻳﻦ ﻣﺮﺣﻠﻪ وﻇﻴﻔﻪ ي ﻛﺎﻣﭙـﺎﻳﻠﺮ Just-In- Timeو ﻳﺎ ﺑﻪ اﺧﺘﺼﺎر JITﻛﺎﻣﭙﺎﻳﻠﺮ اﺳﺖ .اﻳﻦ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻛﺪ MSILﻳﻚ ﺑﺮﻧﺎﻣﻪ را درﻳﺎﻓﺖ ﻛﺮده و آن را ﺑﻪ ﻛﺪي ﺗﺒﺪﻳﻞ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻗﺎﺑﻞ اﺟﺮا ﺑﺎﺷﺪ .ﺑﻌﺪ از اﻳﻨﻜﻪ اﻳﻦ ﺗﺒﺪﻳﻞ ﺗﻮﺳﻂ JITاﻧﺠﺎم ﺷﺪ ،ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨـﺪ.
1
Common Type System Common Language Runtime 3اﻳﻦ ﻣﻔﺎﻫﻴﻢ ﺑﻪ ﺗﻔﺼﻴﻞ و ﺑﺎ ذﻛﺮ ﺟﺰﺋﻴﺎت ،در ﺿﻤﻴﻤﻪ ي 2ﻣﻮرد ﺑﺮرﺳﻲ ﻗﺮار ﮔﺮﻓﺘﻪ اﻧﺪ .اﻟﺒﺘﻪ ﻣﻄﺎﻟﻌﻪ ي ﻣﻄﺎﻟﺐ آن ﺿﻤﻴﻤﻪ ﻣﻤﻜـﻦ اﺳـﺖ ﺑـﺮاي ﺑـﺎر اول ﻣﻘـﺪاري ﻣﺸﻜﻞ ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ. 4 Native Code 5 Microsoft Intermediate Language 2
٤٦
ﻫﻤﺎﻧﻄﻮر ﻛﻪ از اﺳﻢ اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﻣﺸﺨﺺ اﺳﺖ ) (Just-In-Timeﻛﺪﻫﺎي زﺑﺎن MSILﻓﻘﻂ ﻫﻨﮕﺎﻣﻲ ﺑﻪ زﺑﺎن ﻣﺤﻠﻲ ﻗﺎﺑﻞ ﻓﻬﻢ ﺑﺮاي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮﻧﺪ ،ﻛﻪ ﺑﺨﻮاﻫﻨﺪ اﺟﺮا ﺷﻮﻧﺪ. در ﮔﺬﺷﺘﻪ ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﺪ ﺑﺮﻧﺎﻣﻪ ﺧﻮد را ﺑﺮ روي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻫﺎي ﻣﺨﺘﻠﻒ اﺟﺮا ﻛﻨﻴﺪ ﻧﻴﺎز داﺷﺘﻴﺪ ﻛﻪ ﺑـﺮاي ﻫـﺮ ﻧـﺴﺨﻪ از ﺳﻴـﺴﺘﻢ ﻋﺎﻣﻞ ،آن ﻛﺪ را ﻳﻚ ﻣﺮﺗﺒﻪ ﺑﻪ ﻃﻮر ﻛﺎﻣﻞ ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﻴﺪ .اﻣﺎ در ﭼﺎرﭼﻮب .NETﻧﻴﺎزي ﺑﻪ اﻳﻦ ﻛﺎر ﻧﻴﺴﺖ .زﻳﺮا ﺑﺮاي ﻫﺮ ﻧﻮع ﭘﺮدازﻧﺪه و ﻧﻴﺰ ﻫﺮ ﻧﻮع ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻳﻚ ﻧﺴﺨﻪ از JITوﺟﻮد دارد .ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ در ﻫﺮ ﺳﻴﺴﺘﻢ ﻋﺎﻣﻠﻲ ﻛﻪ اﺟﺮا ﺷﻮد ،ﻛﺎﻣﭙﺎﻳﻠﺮ JITﻣﻮﺟﻮد در آن ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ،ﻛﺪ MSILﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ را ﻛﻪ ﻣﺴﺘﻘﻞ از ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ و ﻧﻮع ﭘﺮدازﻧﺪه اﺳﺖ درﻳﺎﻓﺖ ﻛﺮده و ﻛﺪ ﻣﺤﻠﻲ ﻣﻨﺎﺳﺒﻲ ﺗﻮﻟﻴـﺪ ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ ﺑﺮاي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻗﺎﺑﻞ ﻓﻬﻢ ﺑﺎﺷﺪ. ﻓﺎﻳﺪه اﺳﺘﻔﺎده از اﻳﻦ روش در اﻳﻦ اﺳﺖ ﻛﻪ وﻇﻴﻔﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ را ﺑﻪ ﺷﺪت ﻛﺎﻫﺶ ﻣﻲ دﻫﺪ .در ﺣﻘﻴﻘﺖ ﻣﻲ ﺗﻮان ﮔﻔﺖ ﻛﻪ ﺑـﻪ ﻋﻨـﻮان ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ،ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﻛﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺳﻴﺴﺘﻢ ﻋﺎﻣﻠﻲ ﻛﻪ ﻗﺮار اﺳﺖ ﺑﺮﻧﺎﻣﻪ روي آن اﺟﺮا ﺷﻮد را ﻓﺮاﻣﻮش ﻛـﺮده و ﻓﻜـﺮ ﺧـﻮد را ﺑـﺮ روي ﻛﺪ و ﻣﻨﻄﻖ ﺑﺮﻧﺎﻣﻪ ﻣﺘﻤﺮﻛﺰ ﻛﻨﻴﺪ.
اﺳﻤﺒﻠﻲ ﻫﺎ: ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﻛﺎﻣﭙﺎﻳﻞ ﻣﻲ ﻛﻨﻴﺪ ،ﻛﺪ MSILﺗﻮﻟﻴﺪ ﺷﺪه در ﻓﺎﻳﻠﻬﺎﻳﻲ ﺑﻪ ﻧﺎم اﺳﻤﺒﻠﻲ 1ذﺧﻴﺮه ﻣﻲ ﺷﻮﻧﺪ .ﻓﺎﻳﻠﻬﺎي اﺳـﻤﺒﻠﻲ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺷﺎﻣﻞ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﺑﺎﺷﻨﺪ ﻛﻪ ﺑﺪون ﻧﻴﺎز ﺑﻪ ﺑﺮﻧﺎﻣﻪ اي دﻳﮕﺮ ﺑﺘﻮاﻧﻨﺪ ﺑﺮ روي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ اﺟﺮا ﺷﻮﻧﺪ )اﻳـﻦ ﮔﻮﻧـﻪ ﻓﺎﻳﻠﻬـﺎ داراي ﭘﺴﻮﻧﺪ .exeﻫﺴﺘﻨﺪ( و ﻳﺎ ﺷﺎﻣﻞ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎﻳﻲ از ﻛﻼﺳﻬﺎ و ﺗﻮاﺑﻊ ﺑﺮاي اﺳﺘﻔﺎده در دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﺎﺷﻨﺪ )اﻳـﻦ ﮔﻮﻧـﻪ ﻓﺎﻳﻠﻬـﺎ داراي ﭘﺴﻮﻧﺪ .dllﻫﺴﺘﻨﺪ(. 2 ﻓﺎﻳﻠﻬﺎي اﺳﻤﺒﻠﻲ ﻋﻼوه ﺑﺮ ﻛﺪﻫﺎي ،MSILﺷﺎﻣﻞ اﻃﻼﻋﺎت ﻣﺘﺎ )اﻃﻼﻋﺎﺗﻲ راﺟﻊ ﺑﻪ اﻃﻼﻋـﺎت ذﺧﻴـﺮه ﺷـﺪه در ﻓﺎﻳـﻞ اﺳـﻤﺒﻠﻲ( و ﻫﻤﭽﻨﻴﻦ ﻣﻨﺎﺑﻊ اﺧﺘﻴﺎري )اﻃﻼﻋﺎت اﺿﺎﻓﻲ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻛﺪﻫﺎي MSILاﺳﺘﻔﺎده ﻣﻲ ﺷـﻮﻧﺪ ،ﻫﻤﺎﻧﻨـﺪ ﻓﺎﻳﻠﻬـﺎي ﺻـﻮﺗﻲ و ﻳـﺎ ﻓﺎﻳﻠﻬـﺎي ﺗﺼﻮﻳﺮي( ﻧﻴﺰ ﻫﺴﺘﻨﺪ .اﻃﻼﻋﺎت ﻣﺘﺎ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﻳﻚ ﻓﺎﻳﻞ اﺳﻤﺒﻠﻲ ﺑﺘﻮاﻧﺪ اﻃﻼﻋﺎت داﺧﻞ ﺧﻮد را ﺑﻪ ﻃﻮر ﻛﺎﻣﻞ ﺗﻮﺻﻴﻒ ﻛﻨﺪ .ﺑـﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﺮاي اﺳﺘﻔﺎده از ﻳﻚ اﺳﻤﺒﻠﻲ ﺑﻪ ﻫﻴﭻ اﻃﻼﻋﺎت و ﻳﺎ ﻛﺎرﻫﺎي اﺿﺎﻓﻲ ﻣﺎﻧﻨﺪ ﺛﺒﺖ آن در رﺟﻴﺴﺘﺮي ﺳﻴﺴﺘﻢ ﻧﻴﺎزي ﻧﺪارﻳـﺪ .ﺑـﻪ اﻳﻦ ﺗﺮﺗﻴﺐ از ﻣﺸﻜﻼﺗﻲ ﻛﻪ ﻋﻤﻮﻣﺎً ﻫﻨﮕﺎم ﻛﺎر ﺑﺎ اﻳﻦ ﻧﻮع ﻓﺎﻳﻠﻬﺎ در ﻣﺤﻴﻄﻬﺎي دﻳﮕﺮ ﺑﻪ وﺟﻮد ﻣﻲ آﻣﺪ ﻧﻴﺰ ﺟﻠﻮﮔﻴﺮي ﻣﻲ ﺷﻮد. ﻳﻜﻲ دﻳﮕﺮ از ﺧﺎﺻﻴﺘﻬﺎي اﻳﻦ ﻣﻮرد در اﻳﻦ اﺳﺖ ﻛﻪ ﺗﻮزﻳﻊ ﻳﻚ ﻧﺮم اﻓﺰار ﺑﻪ ﺳﺎدﮔﻲ ﻛﭙﻲ ﻛﺮدن ﺗﻤﺎم ﻓﺎﻳﻠﻬﺎي آن ﺑﺮ روي ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﻘﺼﺪ اﺳﺖ .ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﺑﺮاي اﺟﺮاي ﻳﻚ ﻓﺎﻳﻞ اﺳﻤﺒﻠﻲ ﺑﻪ ﻫﻴﭻ ﻣﻮرد دﻳﮕﺮي ﻧﻴﺎز ﻧﻴﺴﺖ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺳﺎدﮔﻲ ﻓﻮﻟـﺪر ﺣـﺎوي ﺑﺮﻧﺎﻣـﻪ را ﺑـﺮ روي ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﻘﺼﺪ ﻛﭙﻲ ﻛﻨﻴﺪ و ﺳﭙﺲ ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن ﺑﺮ روي ﻓﺎﻳﻞ اﺟﺮاﻳﻲ آن ،ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و از آن اﺳﺘﻔﺎده ﻛﻨﻴـﺪ )ﺑـﺎ ﻓـﺮض اﻳﻨﻜﻪ CLRﻛﻪ ﻣﻬﻤﺘﺮﻳﻦ ﺑﺨﺶ .NETاﺳﺖ ،ﻗﺒﻼ در آن ﻛﺎﻣﭙﻴﻮﺗﺮ ﻧﺼﺐ ﺷﺪه ﺑﺎﺷﺪ( .در ﻣﻮرد ﭼﮕﻮﻧﮕﻲ ﺗﻮزﻳـﻊ ﻳـﻚ ﻧـﺮم اﻓـﺰار در ﻓﺼﻞ ﺑﻴﺴﺖ و ﻳﻜﻢ ﺑﻴﺸﺘﺮ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد. اﻟﺒﺘﻪ ﻣﻤﻜﻦ اﺳﺖ در ﺑﻌﻀﻲ ﻣﻮاﻗﻊ ﺑﺨﻮاﻫﻴﺪ از ﺗﻮاﺑﻊ ﻣﻮﺟﻮد در ﻳﻚ ﻓﺎﻳﻞ ،DLLدر ﭼﻨﺪ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻻزم ﻧﻴـﺴﺖ ﻓﺎﻳﻞ ﻣﺬﻛﻮر را در ﻓﻮﻟﺪر ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﻗﺮار دﻫﻴﺪ .ﺑﻠﻜﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ آن را ﻳﻚ ﺑﺎر در ﻳﻚ ﻣﻜـﺎن ﻣـﺸﺨﺺ ﻗﺮار دﻫﻴﺪ و ﺳﭙﺲ ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﻪ ﺑﻪ آن ﻧﻴﺎز دارﻧﺪ ،از آن اﺳﺘﻔﺎده ﻛﻨﻨﺪ .در ﭼﺎرﭼﻮب .NETاﻳﻦ ﻣﻜﺎن ﻣﺸﺨﺺ ﻛﻪ ﺑـﺮاي ﻗـﺮار ﮔﺮﻓﺘﻦ ﻓﺎﻳﻠﻬﺎي اﺳﻤﺒﻠﻲ ﻋﻤﻮﻣﻲ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ Global Assembly Cache ،و ﻳﺎ GACﻧـﺎم دارد .ﺑـﺮاي اﻳﻨﻜﻪ ﻳﻚ ﻓﺎﻳﻞ اﺳﻤﺒﻠﻲ را در اﻳﻦ ﻗﺴﻤﺖ ﻗﺮار دﻫﻴﺪ ،ﻛﺎﻓﻲ اﺳﺖ ﺑﻪ ﺳﺎدﮔﻲ ﻓﺎﻳﻞ ﻣﻮرد ﻧﻈﺮ را در ﻓﻮﻟﺪر ﻣﺸﺨﺺ ﺷﺪه ﺑﺮاي GACﻛﭙﻲ ﻛﻨﻴﺪ ،زﻳﺮا ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻲ ﺗﻮاﻧﻨﺪ ﻋﻼوه ﺑﺮ اﺳﻤﺒﻠﻲ ﻫﺎي ﺧﻮد ﺑﻪ ﻫﻤﻪ اﺳﻤﺒﻠﻲ ﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻓﻮﻟﺪر ﻧﻴﺰ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ.
1ﻣﻔﻬﻮم اﺳﻤﺒﻠﻲ در اﻳﻦ ﻛﺘﺎب ﻛﺎﻣﻼ ﺑﺎ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﺳﻤﺒﻠﻲ ﺗﻔﺎوت دارد. Metadata
2
٤٧
ﻛﺪﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه: ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ اﺑﺘﺪا ﺑﻪ ﻛﺪ MSILﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮد ،ﺳﭙﺲ اﻳﻦ ﻛﺪ ﻗﺒﻞ از اﺟﺮا ﺑﻪ وﺳـﻴﻠﻪ JITﺑـﻪ ﻛﺪ ﻣﺤﻠﻲ ﺗﺒﺪﻳﻞ ﺷﺪه و ﻛﺪ ﻣﺤﻠﻲ ﺑﻪ وﺳﻴﻠﻪ ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ اﺟﺮا ﻣﻲ ﺷﻮد .ﺗﻤﺎم اﻳﻦ ﻗﺴﻤﺘﻬﺎ ﺑﺨﺸﻲ از وﻇﺎﻳﻒ CLRاﺳﺖ ،اﻣـﺎ وﻇـﺎﻳﻒ CLRﺑﻪ اﻳﻦ ﻣﻮارد ﺧﺘﻢ ﻧﻤﻲ ﺷﻮد .ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ .NETﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ در ﻃﻮل زﻣﺎن اﺟﺮا ﺗﻮﺳﻂ CLRﻣﺪﻳﺮﻳﺖ ﻣـﻲ ﺷﻮد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ در ﻃﻮل اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻧﻮﺷﺘﻪ ﺷﺪه ﺑﺎ CLR ،.NETﻣﺴﺌﻮل ﻛﻨﺘﺮل اﻣﻨﻴﺖ آﻧﻬﺎ ،ﻣﺪﻳﺮﻳﺖ ﺣﺎﻓﻈﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎ، ﻛﻨﺘﺮل ﺑﺨﺸﻬﺎي ﺧﻄﺎ ﻳﺎﺑﻲ در ﺑﺮﻧﺎﻣﻪ ﻫﺎ و ...اﺳﺖ .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﺎ .NETﻧﻮﺷﺘﻪ ﺷﺪه اﻧﺪ ،ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣـﺪﻳﺮﻳﺖ ﺷﺪه ﻣﻲ ﮔﻮﻳﻨﺪ .در ﻣﻘﺎﺑﻞ ،ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺗﺤﺖ ﻛﻨﺘﺮل CLRاﺟﺮا ﻧﻤﻲ ﺷﻮﻧﺪ ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي ﻣـﺪﻳﺮﻳﺖ ﻧـﺸﺪه 1ﻣﻌـﺮوف ﻫـﺴﺘﻨﺪ و زﺑﺎﻧﻬﺎي ﻣﺸﺨﺼﻲ ﻣﺎﻧﻨﺪ C++ﻣﻲ ﺗﻮاﻧﻨﺪ ﭼﻨﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ را ﺗﻮﻟﻴﺪ ﻛﻨﻨﺪ .از ﻛﺪﻫﺎي ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه ﺑﻴﺸﺘﺮ در ﻣﻮاﻗﻌﻲ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد ﻛﻪ ﻗﺎﺑﻠﻴﺖ اﺳﺘﻔﺎده از ﻛﺪﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﻧﺒﺎﺷﺪ ،ﻫﻤﺎﻧﻨﺪ ﻓﺮاﺧﻮاﻧﻲ ﺗﻮاﺑﻊ ﺳﻄﺢ ﭘﺎﻳﻴﻦ ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ .اﻟﺒﺘﻪ ﺑﺎ اﺳﺘﻔﺎده از زﺑﺎن C#ﻧﻤـﻲ ﺗﻮان ﻛﺪﻫﺎي ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه ﺗﻮﻟﻴﺪ ﻛﺮد و ﺗﻤﺎم ﻛﺪﻫﺎي ﺗﻮﻟﻴﺪ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ C#ﺗﺤﺖ ﻛﻨﺘﺮل CLRاﺟﺮا ﻣﻲ ﺷﻮﻧﺪ.
ﻣﺪﻳﺮﻳﺖ ﺣﺎﻓﻈﻪ در :.NET ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ وﻳﮋﮔﻴﻬﺎي ﻛﺪﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه ،ﺑﺨﺶ ﻣﺪﻳﺮﻳﺖ ﺣﺎﻓﻈﻪ در اﻳﻦ ﻧﻮع ﻛـﺪﻫﺎ اﺳـﺖ ﻛـﻪ ﺑـﻪ وﺳـﻴﻠﻪ ﺳﻴـﺴﺘﻤﻲ ﺑـﻪ ﻧـﺎم Garbage Collectionو ﻳﺎ ﺑﻪ اﺧﺘﺼﺎر GCاﻧﺠﺎم ﻣﻲ ﺷﻮد .ﭼﺎرﭼﻮب .NETﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﺳﻴـﺴﺘﻢ ﻣـﻲ ﺗﻮاﻧـﺪ اﻃﻤﻴﻨﺎن ﺣﺎﺻﻞ ﻛﻨﺪ ﻛﻪ ﺣﺎﻓﻈﻪ اي ﻛﻪ ﺑﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ اﺧﺘﺼﺎص داده ﻣﻲ ﺷﻮد ،ﺑﺎ ﭘﺎﻳﺎن ﺑﺮﻧﺎﻣـﻪ ﺑـﻪ ﻃـﻮر ﻛﺎﻣـﻞ ﺑﺎزﻳـﺎﺑﻲ ﻣـﻲ ﺷـﻮد .در زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻗﺒﻞ از ،.NETاﻳﻦ ﻣﻮرد ﺑﻪ وﺳﻴﻠﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻛﻨﺘﺮل ﻣﻲ ﺷﺪ و اﻣﻜﺎن داﺷﺖ ﻛﻪ ﺑﺎ ﻳﻚ اﺷـﺘﺒﺎه ﻛﻮﭼـﻚ در ﻛﺪ ﺑﺮﻧﺎﻣﻪ ،ﻣﻘﺪار زﻳﺎدي از ﻓﻀﺎي ﺣﺎﻓﻈﻪ ﻏﻴﺮ ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﺑﻤﺎﻧﺪ و ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﻛﻤﺒﻮد ﺣﺎﻓﻈﻪ ﻣﻮاﺟﻪ ﺷﻮد .اﻳﻦ ﮔﻮﻧﻪ ﻣﺸﻜﻼت ﺑﺎﻋﺚ ﻛﺎﻫﺶ ﺳﺮﻋﺖ ﺑﺮﻧﺎﻣﻪ ﻫﺎ و ﺣﺘﻲ در ﺑﻌﻀﻲ ﺷﺮاﻳﻂ ﺑﺎﻋﺚ ﺗﻮﻗﻒ ﺳﻴﺴﺘﻢ ﻣﻲ ﺷﺪ. ﻧﺤﻮه ﻛﺎر GCدر .NETﺑﻪ اﻳﻦ ﺻﻮرت اﺳﺖ ﻛﻪ در زﻣﺎﻧﻬﺎي ﻣﺸﺨﺼﻲ ﺑﻪ ﺑﺮرﺳـﻲ ﺣﺎﻓﻈـﻪ ﻣـﻲ ﭘـﺮدازد و داده ﻫـﺎﻳﻲ را ﻛـﻪ دﻳﮕـﺮ اﺳﺘﻔﺎده ﻧﻤﻲ ﺷﻮﻧﺪ از ﺣﺎﻓﻈﻪ ﭘﺎك ﻣﻲ ﻛﻨﺪ .اﻟﺒﺘﻪ ﺑﺮرﺳﻲ ﺣﺎﻓﻈﻪ ﺗﻮﺳﻂ GCدر ﻓﺎﺻﻠﻪ ﻫﺎي زﻣﺎﻧﻲ ﺛﺎﺑﺖ ﺻﻮرت ﻧﻤﻲ ﮔﻴﺮد ﺑﻠﻜـﻪ ﻣﻤﻜـﻦ اﺳﺖ در ﺷﺮاﻳﻄﻲ در ﻫﺮ ﺛﺎﻧﻴﻪ ﭼﻨﺪﻳﻦ ﻫﺰار ﺑﺎر اﺟﺮا ﺷﻮد و در ﺷﺮاﻳﻂ دﻳﮕﺮ در ﻫﺮ ﭼﻨﺪ ﺛﺎﻧﻴﻪ ﻳﻚ ﺑﺎر اﺟﺮا ﺷﻮد.2
ﻣﺮاﺣﻞ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ در .NET ﻗﺒﻞ از اداﻣﻪ ،ﻣﺮاﺣﻞ ﻻزم ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎ .NETرا ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﺗﻮﺿﻴﺢ داده ﺷﺪ ﺟﻤﻊ ﺑﻨﺪي ﻣﻲ ﻛﻨﻴﻢ: (1ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﺑﻪ وﺳﻴﻠﻪ ﻳﻜﻲ از زﺑﺎﻧﻬﺎي ﺳﺎزﮔﺎر ﺑﺎ .NETﻣﺎﻧﻨﺪ C#ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد )ﺷﻜﻞ :(1-2
Unmanaged Code
1
2ﺑﺮاي آﺷﻨﺎﻳﻲ ﺑﻴﺸﺘﺮ ﺑﺎ ﺳﻴﺴﺘﻢ ﻣﺪﻳﺮﻳﺖ ﺣﺎﻓﻈﻪ در .NETﺑﻪ ﺿﻤﻴﻤﻪ ي 4ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ.
٤٨
ﺷﻜﻞ 1-1 (2اﻳﻦ ﻛﺪ ﺑﻪ زﺑﺎن MSILﻛﺎﻣﭙﺎﻳﻞ ﻣﻲ ﺷﻮد و ﺳﭙﺲ در ﻳﻚ ﻓﺎﻳﻞ اﺳﻤﺒﻠﻲ ذﺧﻴﺮه ﻣﻲ ﺷﻮد )ﺷﻜﻞ :(2-2
ﺷﻜﻞ 2-2 (3ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺪ ﺑﺨﻮاﻫﺪ اﺟﺮا ﺷﻮد )ﭼﻪ ﺧﻮد ﻓﺎﻳﻞ اﺟﺮاﻳﻲ ﺑﺎﺷﺪ و ﺑﻪ ﺗﻨﻬﺎﻳﻲ اﺟﺮا ﺷﻮد ،ﭼﻪ ﻳﻚ ﻓﺎﻳﻞ ﺣﺎوي ﺗﻮاﺑﻊ ﻣﻮرد اﺳﺘﻔﺎده ﺑﺎﺷﺪ و ﺑﻪ وﺳﻴﻠﻪ دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﺣﻀﺎر ﺷﻮد( اﺑﺘﺪا ﺑﺎﻳﺪ ﺑﻪ وﺳﻴﻠﻪ ﻳﻚ ﻛﺎﻣﭙﺎﻳﻠﺮ دﻳﮕﺮ ﺑﻪ ﻛﺪ ﻣﺤﻠﻲ ﺗﺒﺪﻳﻞ ﺷﻮد .اﻳـﻦ ﻛﺎﻣﭙـﺎﻳﻠﺮ JITﻧﺎم دارد )ﺷﻜﻞ :(3-2
ﺷﻜﻞ 3-2
٤٩
(4ﻛﺪ ﻣﺤﻠﻲ ﺗﻮﻟﻴﺪ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ JITﺑﻪ ﻫﻤﺮاه دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎي در ﺣﺎل اﺟﺮا ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ .NETﻧﻮﺷﺘﻪ ﺷﺪه اﻧﺪ ،ﺗﺤﺖ ﻛﻨﺘﺮل CLRﺑﻪ اﺟﺮا در ﻣﻲ آﻳﺪ )ﺷﻜﻞ :(4-2
ﺷﻜﻞ 4-2
ﻟﻴﻨﻚ دادن: در ﺗﻜﻤﻴﻞ ﮔﻔﺘﻪ ﻫﺎي ﻗﺒﻠﻲ ،ﻓﻘﻂ ﻳﻚ ﺑﺨﺶ دﻳﮕﺮ ﺑﺎﻗﻲ ﻣﺎﻧﺪه اﺳﺖ .ﻛﺪ C#ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻛﻪ در اوﻟﻴﻦ ﻣﺮﺣﻠﻪ ﺑﻪ زﺑـﺎن MSILﺗﺒـﺪﻳﻞ ﻣﻲ ﺷﻮد ﺣﺘﻤﺎً ﻧﺒﺎﻳﺪ در ﻳﻚ ﻓﺎﻳﻞ ﺑﺎﺷﺪ ،ﺑﻠﻜﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺮﻧﺎﻣﻪ را در ﭼﻨﺪﻳﻦ ﻓﺎﻳﻞ ﺳﻮرس ﻛﺪ ﻗﺮار دﻫﻴﻢ و ﺳﭙﺲ آﻧﻬـﺎ را در ﻳـﻚ ﻓﺎﻳـﻞ اﺳﻤﺒﻠﻲ ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﻴﻢ .ﺑﻪ اﻳﻦ ﻋﻤﻞ ﻟﻴﻨﻚ ﻛﺮدن ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻛﺎرﺑﺮد زﻳﺎدي دارد .ﻓﺎﻳﺪه اﻳﻦ روش در اﻳـﻦ اﺳـﺖ ﻛـﻪ ﻣﻌﻤﻮﻻ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻛﺎر ﺑﺎ ﭼﻨﺪ ﻓﺎﻳﻞ ﻛﻮﭼﻚ راﺣﺖ ﺗﺮ از ﻛﺎر ﺑﺎ ﻳﻚ ﻓﺎﻳﻞ ﺑﺰرگ اﺳﺖ .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﺳﻮرس ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﭼﻨﺪﻳﻦ ﻓﺎﻳﻞ ﻣﺠﺰا ﺗﻘﺴﻴﻢ ﻛﻨﻴﺪ و ﺳﭙﺲ ﺑﻪ ﻃﻮر ﺟﺪاﮔﺎﻧﻪ ﺑﺮ روي ﻫﺮ ﻳﻚ از آﻧﻬﺎ ﻛﺎر ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ در ﻣﻮاﻗـﻊ ﻣـﻮرد ﻧﻴـﺎز ،ﭘﻴـﺪا ﻛﺮدن ﻗﺴﻤﺖ ﺧﺎﺻﻲ از ﻛﺪ ﻧﻴﺰ ﺑﺴﻴﺎر راﺣﺖ ﺗﺮ ﺧﻮاﻫﺪ ﺷﺪ. ﻳﻜﻲ دﻳﮕﺮ از ﻗﺎﺑﻠﻴﺘﻬﺎي اﻳﻦ روش در اﻳﻦ اﺳﺖ ﻛﻪ ﮔﺮوﻫﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﻲ ﺗﻮاﻧﻨﺪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﭼﻨﺪ ﻗﺴﻤﺖ ﺗﻘﺴﻴﻢ ﻛﻨﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﺮ ﻛﺪام از ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﺮ روي ﻳﻚ ﻗﺴﻤﺖ ﺧﺎص ﻛﺎر ﻛﻨﺪ ﺑﺪون اﻳﻨﻜﻪ در ﻣﻮرد ﻧﺤﻮه ﭘﻴـﺸﺮﻓﺖ ﻗـﺴﻤﺘﻬﺎي دﻳﮕـﺮ ﻧﮕﺮان ﺑﺎﺷﻨﺪ.
C#ﭼﻴﺴﺖ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﻧﻴﺰ ذﻛﺮ ﺷﺪ C#ﻳﻜﻲ از زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ آن ﻣﻲ ﺗﻮان ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﺑﺎ ﻗﺎﺑﻠﻴـﺖ اﺟﺮا در .NET CLRﺗﻮﻟﻴﺪ ﻛﺮد .زﺑﺎن C#در ﺣﻘﻴﻘﺖ ﻧﺴﺨﻪ ﻛﺎﻣﻞ ﺷﺪه ي زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ Cو C++اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﺑﺮاي ﻛﺎر ﺑﺎ ﭼﺎرﭼﻮب .NETﺑﻪ وﺟﻮد آﻣﺪه اﺳﺖ .ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﺟﺪﻳﺪ ﺑﻮدن اﻳﻦ زﺑﺎن ﺑﺮﻧﺎﻣـﻪ ﻧﻮﻳـﺴﻲ ،در اﻳﺠـﺎد آن ﺳـﻌﻲ ﺷﺪه اﺳﺖ ﻛﻪ از وﻳﮋﮔﻴﻬﺎي ﺧﻮب زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ دﻳﮕﺮ اﻟﻬﺎم ﮔﺮﻓﺘﻪ ﺷﻮد و ﻧﻴﺰ ﻛﺎﺳﺘﻲ ﻫﺎي آن زﺑﺎﻧﻬﺎ ﺑﺮﻃﺮف ﺷﻮد.
٥٠
اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ در ﻣﺤﻴﻂ C#ﺑﺴﻴﺎر راﺣﺖ ﺗﺮ از اﻳﺠﺎد ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ در ﻣﺤـﻴﻂ C++اﺳـﺖ .ﻋـﻼوه ﺑـﺮ اﻳـﻦ ﺳـﺎدﮔﻲ C# ،زﺑـﺎن ﻗﺪرﺗﻤﻨﺪي ﻧﻴﺰ ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد ﺑﻪ ﻧﺤﻮي ﻛﻪ اﻏﻠﺐ ﻛﺎرﻫﺎﻳﻲ ﻛﻪ در C++اﻣﻜﺎن ﭘﺬﻳﺮ اﺳﺖ در C#ﻫﻢ ﻣﻲ ﺗﻮان اﻧﺠﺎم داد .ﺑﻌﻀﻲ از وﻳﮋﮔﻴﻬﺎي C#ﻛﻪ ﻫﻢ ﺳﻄﺢ ﺑﺎ وﻳﮋﮔﻴﻬﺎي ﭘﻴﺸﺮﻓﺘﻪ در C++ﻫﺴﺘﻨﺪ ،ﻫﻤﺎﻧﻨﺪ ﻗﺎﺑﻠﻴﺖ دﺳﺘﺮﺳﻲ ﻣﺴﺘﻘﻴﻢ ﺑﻪ ﺣﺎﻓﻈﻪ و ﻧﻴﺰ ﺗﻐﻴﻴﺮ آن ،ﺑﺎﻋﺚ ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﻛﺪﻫﺎي ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻋﻨﻮان ﻛﺪ ﻧﺎ اﻣﻦ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﻮد .اﺳﺘﻔﺎده از اﻳﻦ ﺗﻜﻨﻴﻚ ﻫﺎي ﭘﻴﺸﺮﻓﺘﻪ ي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ،ﻋﻤﻮﻣﺎً ﺧﻄﺮﻧﺎك ﻫﺴﺘﻨﺪ زﻳﺮا ﻣﻤﻜﻦ اﺳﺖ ﺑﺎﻋﺚ ﺷﻮﻧﺪ ﻗﺴﻤﺘﻬﺎي ﻣﻬﻢ ﺣﺎﻓﻈﻪ ﻛﻪ اﻃﻼﻋﺎت ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ در آن ﻗﺮار دارد ﺑـﻪ ﻃـﻮر ﻧـﺎ ﺧﻮاﺳـﺘﻪ ﺗﻐﻴﻴﺮ ﻛﻨﺪ و ﺳﻴﺴﺘﻢ ﻣﺘﻮﻗﻒ ﺷﻮد .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ اﻳﻦ ﻣﺒﺎﺣﺚ در اﻳﻦ ﻛﺘﺎب ﻣﻮرد ﺑﺮرﺳﻲ ﻗﺮار ﻧﻤﻲ ﮔﻴﺮﻧﺪ. ﺑﻌﻀﻲ ﻣﻮاﻗﻊ ﻛﺪﻫﺎي زﺑﺎن C#ﻃﻮﻻﻧﻲ ﺗﺮ از ﻛﺪﻫﺎي زﺑﺎن C++ﻫﺴﺘﻨﺪ .ﻋﻠﺖ اﻳﻦ ﻃﻮﻻﻧﻲ ﺗﺮ ﺑﻮدن ﻛﺪﻫﺎ ﺑﻪ ﺧﺎﻃﺮ اﻳﻦ اﺳﺖ ﻛﻪ C# ﺑﺮ ﺧﻼف C++ﻳﻚ زﺑﺎن ﻧﻮع-اﻣﻦ 1اﺳﺖ .در اﺻﻄﻼح اﻳﻦ ﻟﻐﺖ ﺑﻪ ﻣﻌﻨﻲ اﻳﻦ اﺳـﺖ ﻛـﻪ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻧـﻮع داده اي ﻳـﻚ ﻣﺘﻐﻴﻴـﺮ ﻣﺸﺨﺺ ﺷﺪ ،آن ﻣﺘﻐﻴﻴﺮ ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻪ ﻳﻚ ﻧﻮع داده اي دﻳﮕﺮ ﻛﻪ ﺑﻪ آن ﻣﺮﺗﺒﻂ ﻧﻴﺴﺖ ﺗﺒﺪﻳﻞ ﺷﻮد .2ﻋـﻼوه ﺑـﺮ اﻳـﻦ ﻣـﻮرد ﻳـﻚ ﺳـﺮي ﻣﺤﺪودﻳﺘﻬﺎي دﻳﮕﺮ ﻧﻴﺰ ﻫﻨﮕﺎم ﺗﺒﺪﻳﻞ ﻳﻚ ﻧﻮع داده اي ﺑﻪ ﻧﻮع داده اي دﻳﮕﺮ ﻧﻴﺰ وﺟﻮد دارد ﻛﻪ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﺪﻫﺎي C#ﻃﻮﻻﻧﻲ ﺗـﺮ از ﻛﺪﻫﺎي C++ﺷﻮﻧﺪ ،اﻣﺎ در ﻣﻘﺎﺑﻞ ﻛﺪﻫﺎي C#از ﭘﺎﻳﺪاري ﺑﻴﺸﺘﺮي ﺑﺮﺧﻮردارﻧﺪ و ﻧﻴﺰ ﺧﻄﺎ ﻳﺎﺑﻲ در آﻧﻬﺎ ﺳﺎده ﺗﺮ اﺳﺖ. اﻟﺒﺘﻪ C#ﻓﻘﻂ ﻳﻜﻲ از زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﺳﺖ ﻛﻪ ﺑﺮاي ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﺗﺤﺖ .NETاﻳﺠﺎد ﺷﺪه اﺳﺖ ،اﻣﺎ ﺑﻪ ﻧﻈـﺮ ﻣـﻦ ﻣﻄﻤﺌﻨـﺎً ﺑﻬﺘﺮﻳﻦ زﺑﺎن ﺑﺮاي اﻳﻦ ﻛﺎر اﺳﺖ .ﻳﻜﻲ از دﻻﻳﻞ اﻳﻦ اﻣﺮ اﻳﻦ اﺳﺖ ﻛﻪ زﺑﺎن C#از ﭘﺎﻳﻪ ﺑﺮاي اﺳﺘﻔﺎده در ﻣﺤـﻴﻂ .NETاﻳﺠـﺎد ﺷـﺪه اﺳﺖ و ﻣﻌﻤﻮﻻً در ﭘﺮوژه ﻫﺎﻳﻲ ﻛﻪ در راﺑﻄﻪ ﺑﺎ اﻧﺘﻘﺎل .NETﺑﻪ ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻫﺎي دﻳﮕﺮ اﺳﺖ ،ﻣﺎﻧﻨﺪ Monoاز اﻳﻦ زﺑﺎن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ .در زﺑﺎﻧﻬﺎي دﻳﮕﺮ ،ﻣﺎﻧﻨﺪ ﻧﺴﺨﻪ .NETزﺑﺎن وﻳﮋوال ﺑﻴﺴﻴﻚ ،ﺑﺮاي اﻳﻨﻜﻪ ﺷﺒﺎﻫﺖ ﺑﺎ ﻧﺴﻠﻬﺎي ﻗﺒﻠﻲ ﺧﻮد را ﺣﻔﻆ ﻛﻨﻨﺪ ،ﻳﻜـﺴﺮي از ﻗﺴﻤﺘﻬﺎي CLRﭘﺸﺘﻴﺒﺎﻧﻲ ﻧﻤﻲ ﺷﻮد .در ﻣﻘﺎﺑﻞ ﺑﺎ اﺳﺘﻔﺎده از زﺑﺎن C#ﻣﻲ ﺗﻮان از ﺗﻤﺎم وﻳﮋﮔﻴﻬﺎي اراﺋﻪ ﺷـﺪه ﺑـﻪ وﺳـﻴﻠﻪ .NETدر ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﺮد.
ﭼﻪ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ را ﻣﻴﺘﻮان ﺑﺎ اﺳﺘﻔﺎده از C#اﻧﺠﺎم داد؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ،در .NETﻫﻴﭻ ﻣﺤﺪودﻳﺘﻲ ﺑﺮاي ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺎﺑﻞ اﺟـﺮا وﺟـﻮد ﻧـﺪارد .زﺑـﺎن C#ﻧﻴـﺰ از ﭼـﺎرﭼﻮب .NET اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻴﭻ ﻣﺤﺪودﻳﺘﻲ در ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺗﻮان ﺑﺎ اﻳﻦ زﺑﺎن اﻧﺠﺎم داد وﺟﻮد ﻧﺪارد .اﻣﺎ ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﺎ C#ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮﻧﺪ ﺟﺰء ﻳﻜﻲ از دﺳﺘﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي زﻳﺮ ﻫﺴﺘﻨﺪ:
ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وﻳﻨﺪوز :اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻫﻤﺎﻧﻨﺪ Officeﺑﺮﻧﺎﻣﻪ ﻫـﺎﻳﻲ ﻫـﺴﺘﻨﺪ ﻛـﻪ داراي ﻇـﺎﻫﺮ آﺷـﻨﺎي ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي ﻫﺴﺘﻨﺪ .اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﻪ وﺳﻴﻠﻪ ﻓﻀﺎي ﻧﺎم ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي در ﭼـﺎرﭼﻮب .NET ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮﻧﺪ .اﻳﻦ ﻓﻀﺎي ﻧﺎم ﺷﺎﻣﻞ ﻛﻨﺘﺮل ﻫﺎﻳﻲ از ﻗﺒﻴﻞ دﻛﻤﻪ ﻫﺎي ﻓﺮﻣﺎن ،ﻧﻮار اﺑﺰارﻫﺎ ،ﻣﻨﻮ ﻫﺎ و ...اﺳﺖ ﻛﻪ ﺑـﻪ وﺳـﻴﻠﻪ آﻧﻬﺎ ﻣﻲ ﺗﻮان راﺑﻂ ﮔﺮاﻓﻴﻜﻲ ﺑﺮﻧﺎﻣﻪ را ﻃﺮاﺣﻲ ﻛﺮد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب :اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺷﺎﻣﻞ ﻳﻚ ﺳﺮي ﺻﻔﺤﺎت وب ﻫﺴﺘﻨﺪ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺗﺎﻛﻨﻮن ﺑﻪ وﺳـﻴﻠﻪ ﻣﺮورﮔﺮ ﻫﺎي ﻣﺨﺘﻠﻒ اﻳﻨﺘﺮﻧﺖ آﻧﻬﺎ را ﻣﺸﺎﻫﺪه ﻛﺮده ﺑﺎﺷﻴﺪ .ﭼﺎرﭼﻮب .NETداراي ﻳﻚ ﺳﻴﺴﺘﻢ ﻗﻮي ﺑﺮاي اﻳﺠﺎد اﺗﻮﻣﺎﺗﻴﻚ ﺻﻔﺤﺎت وب و ﺗﺎﻣﻴﻦ اﻣﻨﻴﺖ آﻧﻬﺎ و ...اﺳﺖ .اﻳﻦ ﺳﻴﺴﺘﻢ 3ASP.NETﻧﺎﻣﻴﺪه ﻣﻲ ﺷﻮد و ﺷﻤﺎ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﺎ اﺳـﺘﻔﺎده از زﺑﺎن C#و ﺳﻴﺴﺘﻢ ASP.NETﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻣﺒﺘﻨﻲ ﺑﺮ وب اﻳﺠﺎد ﻛﻨﻴﺪ. ﺳﺮوﻳﺴﻬﺎي وب :وب ﺳﺮوﻳﺲ ﻫﺎ ﻳﻚ روش ﺟﺪﻳﺪ و ﺟﺎﻟﺐ ﺑﺮاي اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﻮزﻳﻊ ﺷﺪﻧﻲ ﻣﺒﺘﻨﻲ ﺑﺮ وب ﻫﺴﺘﻨﺪ .ﺑﺎ اﺳﺘﻔﺎده از وب ﺳﺮوﻳﺲ ﻫﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻫﺮ ﻧﻮع اﻃﻼﻋﺎﺗﻲ را از ﻃﺮﻳﻖ اﻳﻨﺘﺮﻧﺖ ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻨﺘﻘﻞ ﻛﻨﻴﺪ .در اﻳـﻦ ﻣـﻮرد زﺑـﺎن Type-Safe
1
2در ﻣﻮرد ﻧﻮع ﻫﺎي داده اي و ﺗﺒﺪﻳﻞ آﻧﻬﺎ ﺑﻪ ﻳﻜﺪﻳﮕﺮ در ﻓﺼﻞ ﺑﻌﺪ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد. Active Server Pages .NET
3
٥١
ﻣﻮرد اﺳﺘﻔﺎده در ﺑﺮﻧﺎﻣﻪ و ﻳﺎ ﺳﻴﺴﺘﻢ ﻋﺎﻣﻠﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ در آن اﺟﺮا ﻣﻲ ﺷﻮد اﻫﻤﻴﺘﻲ ﻧﺪارد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ي ﺷـﻤﺎ ﻛـﻪ ﺗﺤﺖ .NETو ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ وﻳﻨﺪوز ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕﺮ ﻛﻪ ﺗﺤﺖ ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻫـﺎي دﻳﮕـﺮ ﻋﻤﻞ ﻣﻲ ﻛﻨﺪ ﺗﺒﺎدل اﻃﻼﻋﺎت داﺷﺘﻪ ﺑﺎﺷﺪ. در ﻫﺮ ﻛﺪام از اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ در ﺑﺎﻻ ذﻛﺮ ﺷﺪ ﻣﻤﻜﻦ اﺳﺖ ﺑﻪ دﺳﺘﺮﺳﻲ ﺑﻪ ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻧﻴﺎز ﭘﻴﺪا ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻣﻨﻈﻮر در .NETﺑﺎﻳﺪ از ﺳﻴﺴﺘﻤﻲ ﺑﻪ ﻧﺎم 1ADO.NETاﺳﺘﻔﺎده ﻛﻨﻴﺪ.
وﻳﮋوال اﺳﺘﻮدﻳﻮ :2005 در ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي .NETاﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻣﻮردي ﺿﺮوري ﻧﻴﺴﺖ .اﻣﺎ ﺑـﺎ اﺳـﺘﻔﺎده از آن ﺳـﺮﻋﺖ ﻃﺮاﺣـﻲ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎ اﻓﺰاﻳﺶ ﺷﺪﻳﺪي ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ .ﺑﺮاي ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از C#ﺗﺤﺖ .NETﻣﻲ ﺗﻮاﻧﻴﺪ ﺣﺘﻲ از ﻳـﻚ وﻳﺮاﻳـﺸﮕﺮ ﺳـﺎده ي ﻣـﺘﻦ ﻣﺎﻧﻨﺪ Notepadﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻴﺪ و ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻛﺎﻣﭙﺎﻳﻠﺮ ﺧﻂ-ﻓﺮﻣﺎن .NET 2ﺑﺮاي ،C#آن را ﺑﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻗﺎﺑﻞ اﺟـﺮا ﺗﺒﺪﻳﻞ ﻛﻨﻴﺪ. در زﻳﺮ وﻳﮋﮔﻴﻬﺎﻳﻲ از وﻳﮋوال اﺳﺘﻮدﻳﻮ .NETﻛﻪ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد اﻳﻦ ﻣﺤﻴﻂ اﻧﺘﺨـﺎﺑﻲ ﻣﻨﺎﺳـﺐ ﺑـﺮاي ﺑﺮﻧﺎﻣـﻪ ﻧﻮﻳـﺴﻲ ﺗﺤـﺖ .NET ﻣﺤﺴﻮب ﺷﻮد را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد:
وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺗﻤﺎم ﻣﺮاﺣﻞ ﻛﺎﻣﭙﺎﻳﻞ ﻳﻚ ﺳﻮرس ﻛﺪ ﺑﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻗﺎﺑﻞ اﺟﺮا را ﺑﻪ ﺻـﻮرت اﺗﻮﻣﺎﺗﻴـﻚ اﻧﺠـﺎم ﻣـﻲ دﻫـﺪ و ﻫﻤﭽﻨﻴﻦ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ اﺟﺎزه ﻣﻲ دﻫﺪ ﻫﺮ ﻗﺴﻤﺘﻲ را ﻛﻪ ﺑﺨﻮاﻫﺪ ﺗﻐﻴﻴﺮ داده و ﺗﻨﻈﻴﻢ ﻛﻨﺪ. وﻳﺮاﻳﺸﮕﺮ ﻛﺪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮاي ﻛﺪ ﻧﻮﻳﺴﻲ زﺑﺎن ﻫﺎي ﭘﺸﺘﻴﺒﺎﻧﻲ ﺷﺪه در .NETﺑﺴﻴﺎر ﻫﻮﺷﻤﻨﺪ اﺳﺖ و ﻣﻲ ﺗﻮاﻧﺪ ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ اﻳﻦ ﻛﺪﻫﺎ ﺧﻄﺎﻫﺎي آﻧﻬﺎ را ﺗﺸﺨﻴﺺ داده و در ﺗﺼﺤﻴﺢ آﻧﻬﺎ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻛﻤﻚ ﻛﻨﺪ. وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺷﺎﻣﻞ ﻣﺤﻴﻄﻬﺎﻳﻲ ﺑﺮاي ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي و ﻧﻴﺰ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب اﺳﺖ ﻛـﻪ ﺑـﻪ ﻛﻤـﻚ آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺳﺎدﮔﻲ ﻣﺤﻴﻂ ﺑﺮﻧﺎﻣﻪ ﺧﻮد را ﻃﺮاﺣﻲ ﻛﻨﻴﺪ. ﺑﺮاي اﻳﻨﻜﻪ در .NETﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﺤﺖ وﻳﻨﺪوز اﻳﺠﺎد ﻛﻨﻴﺪ ﺑﺎﻳﺪ ﻣﻘﺪار زﻳﺎدي ﻛﺪ را ﻛـﻪ در اﻏﻠـﺐ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎ ﺑـﻪ ﺻـﻮرت ﺗﻜﺮاري ﻫﺴﺘﻨﺪ ﺑﻨﻮﻳﺴﻴﺪ .اﻳﻦ ﻣﻮرد در اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ از ﻧﻮع ﻫﺎي دﻳﮕﺮ ﻣﺎﻧﻨﺪ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي ﺗﺤـﺖ وب ﻧﻴـﺰ وﺟـﻮد دارد. وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺎ ﻧﻮﺷﺘﻦ اﺗﻮﻣﺎﺗﻴﻚ اﻳﻦ ﻛﺪﻫﺎ در ﺳﺮﻋﺖ ﺑﺨﺸﻴﺪن ﺑﻪ ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻛﻤﻚ ﻗﺎﺑﻞ ﺗﻮﺟﻬﻲ ﻣﻲ ﻛﻨﺪ. وﻳﮋوال اﺳﺘﻮدﻳﻮ داراي وﻳﺰارد ﻫﺎي زﻳﺎدي اﺳﺖ ﻛﻪ ﺑﺴﻴﺎري از ﻛﺎرﻫﺎي ﻋﻤﻮﻣﻲ را ﺑﺮاي ﺷﻤﺎ اﻧﺠﺎم داده و ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ آﻧﻬـﺎ را در ﺑﺮﻧﺎﻣﻪ ﻗﺮار ﻣﻲ دﻫﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ دﻳﮕﺮ ﻧﻴﺎزي ﻧﻴﺴﺖ در ﻣﻮرد ﻧﺤﻮه ﻧﻮﺷﺘﻦ ﻛﺪ آﻧﻬﺎ ﻧﮕﺮان ﺑﺎﺷﻴﺪ. وﻳﮋوال اﺳﺘﻮدﻳﻮ داراي اﺑﺰارﻫﺎي ﻗﺪرﺗﻤﻨﺪي ﺑﺮاي ﻛﻨﺘﺮل ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﻳﻚ ﭘﺮوژه از ﻗﺒﻴـﻞ ﺳـﻮرس ﻛـﺪﻫﺎي C#و ﻳـﺎ ﻓﺎﻳﻠﻬﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺮﻧﺎﻣﻪ از ﻗﺒﻴﻞ ﻓﺎﻳﻠﻬﺎي ﺻﻮﺗﻲ و ﺗﺼﻮﻳﺮي اﺳﺖ. ﻋﻼوه ﺑﺮ ﺳﺎدﮔﻲ ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ در ،.NETﺗﻮزﻳﻊ آﻧﻬﺎ ﻧﻴﺰ ﺑـﺴﻴﺎر ﺳـﺎده اﺳـﺖ و ﺑـﻪ راﺣﺘـﻲ ﻣـﻲ ﺗـﻮان آن را ﺑـﺮ روي ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎي ﻣﻘﺼﺪ اﺟﺮا ﻛﺮد و ﻳﺎ ﺑﻪ روز رﺳﺎﻧﺪ. وﻳﮋوال اﺳﺘﻮدﻳﻮ داراي اﺑﺰارﻫﺎي ﻗﻮي ﺧﻄﺎ ﻳﺎﺑﻲ در ﺑﺮﻧﺎﻣﻪ اﺳﺖ .ﺑﺮاي ﻣﺜﺎل ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ اﺑﺰارﻫﺎ ﻣﻲ ﺗﻮان ﺑﺮﻧﺎﻣـﻪ را ﺧـﻂ ﺑﻪ ﺧﻂ اﺟﺮا ﻛﺮد و در اﺟﺮاي ﻫﺮ ﺧﻂ ﻣﻮﻗﻌﻴﺖ ﺑﺮﻧﺎﻣﻪ را ﺑﺮرﺳﻲ ﻛﺮد.
Active Data Objects .NET Command-Line Compiler
1 2
٥٢
وﻳﮋﮔﻴﻬﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺴﻴﺎر ﺑﻴﺸﺘﺮ از ﻣﻮارد ذﻛﺮ ﺷﺪه اﺳﺖ اﻣﺎ ﻫﻤﻴﻦ ﻣﻘﺪار ﺑﺮاي ﻧﻤﺎﻳﺶ ﻣﺰاﻳﺎي اﺳﺘﻔﺎده از آن ﻛﺎﻓﻲ ﺑـﻪ ﻧﻈـﺮ ﻣـﻲ رﺳﺪ.
راه ﺣﻠﻬﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ: ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﺑﺎ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﻨﻮﻳﺴﻴﺪ اﺑﺘﺪا ﺑﺎﻳﺪ ﻳﻚ راه ﺣﻞ 1اﻳﺠﺎد ﻛﻨﻴﺪ .ﻳﻚ راه ﺣـﻞ در اﺻـﻄﻼح وﻳـﮋوال اﺳﺘﻮدﻳﻮ ،از ﺑﻴﺶ از ﻳﻚ ﭘﺮوژه ﺗﺸﻜﻴﻞ ﻣﻲ ﺷﻮد .راه ﺣﻞ ﻫﺎ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺷﺎﻣﻞ ﭼﻨﺪﻳﻦ ﭘﺮوژه از اﻧﻮاع ﻣﺨﺘﻠﻒ ﺑﺎﺷـﻨﺪ .ﺑـﺮاي ﻣﺜـﺎل ﺗـﺼﻮر ﻛﻨﻴﺪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﺮﻧﺎﻣﻪ اي ﺑﺮاي ﻳﻚ ﺷﺮﻛﺖ ﺗﺠﺎري ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ از دو ﻗﺴﻤﺖ ﺗﺸﻜﻴﻞ ﻣﻲ ﺷﻮد :در ﻗﺴﻤﺖ اول ﺑﺎﻳﺪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﺤـﺖ وﻳﻨﺪوز اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ اﻣﻮر ﻣﺨﺘﻠﻒ آن ﺷﺮﻛﺖ را ﻛﻨﺘﺮل ﻛﻨﺪ ،در ﻗﺴﻤﺖ دوم ﻧﻴﺰ ﺑﺎﻳﺪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب اﻳﺠﺎد ﻛﻨﻴﺪ ﺗـﺎ اﻃﻼﻋـﺎت ﻣﺮﺑﻮط ﺑﻪ آن ﺷﺮﻛﺖ را در ﻳﻚ وب ﺳﺎﻳﺖ ﻧﻤﺎﻳﺶ دﻫﺪ .ﺑﺮاي ﻫﺮ ﻛﺪام از اﻳﻦ ﻗﺴﻤﺘﻬﺎ ﺑﻪ ﻳﻚ ﭘﺮوژه ي ﻣﺠﺰا ﻧﻴﺎز دارﻳﺪ .ﺑﻨﺎﺑﺮاﻳﻦ در ﻛﻞ ﺑﺎﻳﺪ دو ﭘﺮوژه اﻳﺠﺎد ﻛﻨﻴﺪ .ﺑﺮاي در ﻳﻚ ﮔﺮوه ﻗﺮار دادن اﻳﻦ دو ﭘﺮوژه ﻣﻲ ﺗﻮاﻧﻴﺪ از راه ﺣﻞ ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴـﺐ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﻛﺪﻫﺎي ﻣﺮﺗﺒﻂ ﺑﻪ ﻫﻢ را در ﻳﻚ ﺟﺎ ﮔﺮوه ﺑﻨﺪي ﻛﻨﻴﺪ ،ﺣﺘﻲ اﮔﺮ ﭘﺮوژه ﻫﺎي آﻧﻬﺎ در ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠـﻒ ﻫـﺎرد دﻳـﺴﻚ ﺑﺎﺷـﻨﺪ و ﻫﻨﮕـﺎم ﻛﺎﻣﭙﺎﻳﻞ ﭼﻨﺪﻳﻦ ﻓﺎﻳﻞ اﺳﻤﺒﻠﻲ ﻣﺨﺘﻠﻒ در ﻗﺴﻤﺘﻬﺎي ﻣﺘﻔﺎوت ﻫﺎرد دﻳﺴﻚ اﻳﺠﺎد ﺷﻮد. ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ وﻳﮋﮔﻲ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻫﻤﺰﻣﺎن ﺑﺮ روي ﻛﺪﻫﺎﻳﻲ ﻛﻪ ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﺸﺘﺮك اﺳﺖ ) ﺑـﺮاي ﻣﺜـﺎل اﺳـﻤﺒﻠﻲ ﻫـﺎي ﻣﻮﺟـﻮد در (GACو ﻧﻴﺰ ﺑﺮﻧﺎﻣﻪ اﺻﻠﻲ ﻛﺎر ﻛﻨﻴﺪ .ﻫﻤﭽﻨﻴﻦ ﺑﻪ ﻋﻠﺖ اﻳﻦ ﻛﻪ ﺑﺮاي ﻛﺎر ﺑﺮ روي اﻳﻦ ﭘﺮوژه ﻫﺎ از ﻳﻚ ﻣﺤﻴﻂ ﻃﺮاﺣﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ، ﺧﻄﺎ ﻳﺎﺑﻲ آﻧﻬﺎ ﻧﻴﺰ ﺑﺴﻴﺎر ﺳﺎده ﺗﺮ ﺧﻮاﻫﺪ ﺷﺪ.
ﻧﺘﻴﺠﻪ: در اﻳﻦ ﻓﺼﻞ ﺑﻪ ﻣﻌﺮﻓﻲ .NETﭘﺮداﺧﺘﻴﻢ و دﻳﺪﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗـﻮان ﺑـﺎ اﺳـﺘﻔﺎده از .NETﺑـﻪ ﺳـﺎدﮔﻲ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي ﻣﺘﻨـﻮع و ﻗﺪرﺗﻤﻨﺪي را ﻧﻮﺷﺖ .ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﺑﺮاي اﺟﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻮﺷﺘﻪ ﺷﺪه ﺑﻪ زﺑﺎن C#در .NETﭼﻪ ﻣﺮاﺣﻠﻲ ﺑﺎﻳﺪ ﻃﻲ ﺷﻮﻧﺪ و ﻧﻴﺰ ﻣﺰﻳﺖ ﻫﺎي اﺳﺘﻔﺎده از ﻛﺪﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه در .NET CLRﻧﺴﺒﺖ ﺑﻪ ﻛﺪﻫﺎي ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه ﭼﻴﺴﺖ. در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ:
ﭼﺎرﭼﻮب .NETﭼﻴﺴﺖ ،ﭼﺮا ﺑﻪ وﺟﻮد آﻣﺪ و ﭼﻪ ﻣﻮاردي ﺑﺎﻋﺚ ﻗﺪرت و ﺟﺬاﺑﻴﺖ آن ﻣﻲ ﺷﻮد؟ زﺑﺎن C#ﭼﻴﺴﺖ و ﭼﻪ ﭼﻴﺰ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﺑﻪ ﻳﻚ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﻨﺎﺳﺐ ﺗﺤﺖ .NETﺗﺒﺪﻳﻞ ﺷﻮد؟ وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﭼﻴﺴﺖ و ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﺪ در ﺗﺴﺮﻳﻊ ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ در .NETﻣﻮﺛﺮ واﻗﻊ ﺷﻮد؟
Solution
1
٥٣
ﻓﺼﻞ ﺳﻮم :ﻧﻮﺷﺘﻦ ﻧﺮم اﻓﺰار ﺣﺎﻻ ﻛﻪ ﺗﻮاﻧﺴﺘﻴﺪ وﻳﮋوال 2005 C#را اﺟﺮا ﻛﺮده و ﺣﺘﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻛﻮﭼﻚ وﻟﻲ ﻗﺎﺑﻞ اﺟﺮا ﺑﺎ آن ﺑﻨﻮﻳﺴﻴﺪ ،ﺑﻬﺘـﺮ اﺳـﺖ در اﻳـﻦ ﻓـﺼﻞ ﻣﺒﺎﻧﻲ ﻓﺮآﻳﻨﺪ ﻧﻮﺷﺘﻦ ﻳﻚ ﻧﺮم اﻓﺰار را ﻳﺎد ﺑﮕﻴﺮﻳﺪ و ﻛﺪﻫﺎي ﺧﻮدﺗﺎن را در ﻛﻨﺎر ﻫﻢ ﻗﺮار دﻫﻴﺪ و ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺟﺬاﺑﻲ ﻃﺮاﺣﻲ ﻛﻨﻴﺪ. در اﻳﻦ درس:
در راﺑﻄﻪ ﺑﺎ اﻟﮕﻮرﻳﺘﻢ ﻫﺎ ﻣﻄﺎﻟﺒﻲ را ﺧﻮاﻫﻴﺪ آﻣﻮﺧﺖ. ﭼﮕﻮﻧﮕﻲ اﺳﺘﻔﺎده از ﻣﺘﻐﻴﻴﺮ ﻫﺎ را ﺧﻮاﻫﻴﺪ دﻳﺪ. ﺑﺎ اﻧﻮاع ﻣﺨﺘﻠﻒ داده ﻫﺎ از ﻗﺒﻴﻞ اﻋﺪاد ﺻﺤﻴﺢ ،اﻋﺸﺎري ،رﺷﺘﻪ ﻫﺎ و ﺗﺎرﻳﺦ ﻫﺎ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. ﺑﺎ داﻣﻨﻪ ﻓﻌﺎﻟﻴﺖ ﻣﺘﻐﻴﻴﺮ ﻫﺎ آﺷﻨﺎ ﻣﻲ ﺷﻮﻳﺪ. ﺑﺎ ﺧﻄﺎ ﻳﺎﺑﻲ در ﺑﺮﻧﺎﻣﻪ ﻫﺎ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. ﭼﮕﻮﻧﮕﻲ ذﺧﻴﺮه ﺷﺪن داده ﻫﺎ در ﺣﺎﻓﻈﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
داده ﻫﺎ و اﻃﻼﻋﺎت: اﻃﻼﻋﺎت ﺑﻪ ﺗﻮﺿﻴﺤﺎﺗﻲ ﮔﻔﺘﻪ ﻣﻴﺸﻮد ﻛﻪ راﺟﻊ ﺑﻪ واﻗﻌﻴﺘﻲ ﺑﻴﺎن ﻣﻲ ﺷﻮد .اﻳﻦ اﻃﻼﻋﺎت ﻣﻴﺘﻮاﻧﻨﺪ در ﻫﺮ ﻗﺎﻟﺒﻲ ﺟﻤﻊ آوري و ﻳﺎ اراﺋﻪ ﺷﻮﻧﺪ، ﺑﻪ ﮔﻮﻧﻪ اي ﻛﻪ ﺑﺮاي درك ﺗﻮﺳﻂ ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎ و ﻳﺎ اﻧﺴﺎﻧﻬﺎ ﻣﻨﺎﺳﺐ ﺑﺎﺷﺪ .ﻣﺜﻼ اﮔﺮ ﺷﻤﺎ ﭼﻨﺪ ﻧﻔـﺮ را ﺑـﺮاي ﺑﺮرﺳـﻲ وﺿـﻌﻴﺖ ﺗﺮاﻓﻴـﻚ ﺑـﻪ ﭼﻨﺪﻳﻦ ﭼﻬﺎرراه ﻣﺨﺘﻠﻒ ﺑﻔﺮﺳﺘﻴﺪ ،در ﭘﺎﻳﺎن ﻛﺎر ﺑﺎ ﭼﻨﺪ ﮔﺰارش دﺳﺖ ﻧﻮﻳﺲ ﻛﻪ وﺿﻌﻴﺖ ﻋﺒﻮر ﻣﺎﺷﻴﻨﻬﺎ را در ﭼﻬﺎرراه ﻫﺎي ﻣﺨﺘﻠـﻒ ﺑﻴـﺎن ﻣﻲ ﻛﻨﺪ روﺑﺮو ﻣﻲ ﺷﻮﻳﺪ .اﻳﻦ ﮔﺰارﺷﺎت را ﻣﻴﺘﻮان اﻃﻼﻋﺎﺗﻲ در ﻧﻈﺮ ﮔﺮﻓﺖ ﻛﻪ ﺑﺮاي اﻧﺴﺎن ﻗﺎﺑﻞ ﻓﻬﻢ ﻫﺴﺘﻨﺪ. ﺑﻪ اﻃﻼﻋﺎت ﺟﻤﻊ آوري ﺷﺪه ،ﻣﺮﺗﺐ ﺷﺪه و ﻗﺎﻟﺐ ﺑﻨﺪي ﺷﺪه ،ﺑﻪ ﻧﺤﻮي ﻛﻪ ﺗﻮﺳﻂ ﻗﺴﻤﺘﻲ از ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﺎﻣﭙﻴﻮﺗﺮي ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﺑﺎﺷﺪ، داده ﻣﻲ ﮔﻮﻳﻨﺪ .اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﺷﻤﺎ دارﻳﺪ )ﭼﻨﺪﻳﻦ دﻓﺘﺮ ﭘﺮ از ﻣﺘﻨﻬﺎي دﺳﺖ ﻧﻮﻳﺲ( ﺑﻪ وﺳﻴﻠﻪ ﻧـﺮم اﻓﺰارﻫـﺎي ﻛـﺎﻣﭙﻴﻮﺗﺮي ﻗﺎﺑـﻞ اﺳـﺘﻔﺎده ﻧﻴﺴﺘﻨﺪ .ﺑﺮاي ﺗﺒﺪﻳﻞ آﻧﻬﺎ ﺑﻪ داده ﻫﺎي ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﺗﻮﺳﻂ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﺎﻳﺪ ﭼﻨﺪﻳﻦ ﻧﻔﺮ روي آﻧﻬﺎ ﻛﺎر ﻛﻨﻨﺪ و ﻗﺎﻟﺐ آن را ﺗﻐﻴﻴﺮ دﻫﻨﺪ.
اﻟﮕﻮرﻳﺘﻢ ﻫﺎ: ﺻﻨﻌﺖ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﻪ اﻳﻦ ﻣﻌﺮوف اﺳﺖ ﻛﻪ ﺑﺎ ﺳﺮﻋﺘﻲ ﺑﺎورﻧﻜﺮدﻧﻲ در ﺣﺎل ﺗﻐﻴﻴﺮ اﺳﺖ .ﺑﻴﺸﺘﺮ ﻣﺘﺨﺼﺼﺎن اﻳﻦ رﺷﺘﻪ در ﺗﻤﺎم دوران ﻓﻌﺎﻟﻴـﺖ ﺧﻮد ،داﺋﻤﺎ در ﺣﺎل آﻣﻮزش و ﻳﺎدﮔﻴﺮي ﻫﺴﺘﻨﺪ ﺗﺎ اﻃﻼﻋﺎت ﺧﻮد را ﺑﻪ روز ﻧﮕﻪ دارﻧﺪ .اﻣﺎ ﺑﻌﻀﻲ از ﻗﺴﻤﺘﻬﺎي ﻛﺎﻣﭙﻴﻮﺗﺮ ،از زﻣـﺎﻧﻲ ﻛـﻪ ﺑـﻪ وﺟﻮد آﻣﺪه اﻧﺪ ﺗﺎ ﻛﻨﻮن ﺗﻐﻴﻴﺮي ﻧﻜﺮده اﻧﺪ و اﺣﺘﻤﺎﻻ در ﻃﻮل ﻋﻤﺮ ﻣﺎ ﻫﻢ ﺗﻐﻴﻴﺮي ﻧﺨﻮاﻫﻨﺪ ﻛﺮد .ﻓﺮآﻳﻨﺪ و ﺗﺮﺗﻴﺐ ﻣﻮﺟـﻮد در ﺗﻮﺳـﻌﻪ ﻧـﺮم اﻓﺰار ﻧﻤﻮﻧﻪ اي از ﺟﻨﺒﻪ ﻫﺎي ﺗﻜﻨﻮﻟﻮژي ﻛﺎﻣﭙﻴﻮﺗﺮ اﺳﺖ ﻛﻪ ﻣﺎﻫﻴﺖ اﺻﻠﻲ آن از اﺑﺘﺪا ﺗﺎﻛﻨﻮن دﭼﺎر ﺗﻐﻴﻴﺮ ﻧﺸﺪه اﺳﺖ. ﺑﺮاي ﻛﺎر ﻛﺮدن ﻳﻚ ﻧﺮم اﻓﺰار ،ﻳﻚ ﺳﺮي داده ﻧﻴﺎز اﺳﺖ ﻛﻪ روي آﻧﻬﺎ ﭘﺮدازش اﻧﺠﺎم ﺷﻮد .ﻧﺮم اﻓﺰار اﻳﻦ داده ﻫﺎ را درﻳﺎﻓﺖ ﻣﻴﻜﻨﺪ و ﺑـﻪ ﻓﺮﻣﻲ دﻳﮕﺮ ﺗﺒﺪﻳﻞ ﻣﻴﻜﻨﺪ و اراﺋﻪ ﻣﻲ دﻫﺪ .ﺑﺮاي ﻣﺜﺎل ،ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ،اﻃﻼﻋﺎت ﻣﺸﺘﺮﻳﺎن ﺷﻤﺎ را ﻛﻪ ﺑﻪ ﺻﻮرت ﺻﻔﺮ و ﻳﻚ ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ و آﻧﻬﺎ را ﺑﺮاي ﺷﻤﺎ در ﻣﺎﻧﻴﺘﻮر ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .ﻳﺎ ﺳﺮوﻳﺲ ﺗﻠﻔﻦ ﺷﻤﺎ ،ﻣﺪت زﻣﺎن ﺗﻤﺎﺳـﻬﺎي ﺷـﻤﺎ را ذﺧﻴﺮه ﻛﺮده و ﺻﻮرت ﺣﺴﺎب ﻫﺎ را ﺑﺮ اﺳﺎس اﻳﻦ اﻃﻼﻋﺎت ﺗﻮﻟﻴﺪ ﻣﻲ ﻛﻨﺪ. اﻣﺎ اﺳﺎس ﻓﻌﺎﻟﻴﺖ ﻫﻤﻪ اﻳﻦ ﻧﺮم اﻓﺰارﻫﺎ ،اﻟﮕﻮرﻳﺘﻢ آﻧﻬﺎ اﺳﺖ .ﻗﺒﻞ از اﻳﻨﻜﻪ ﺷﻤﺎ ﺑﺘﻮاﻧﻴﺪ ﺑﺮﻧﺎﻣﻪ اي ﺑﻨﻮﻳﺴﻴﺪ ﺗﺎ ﻣﺴﺌﻠﻪ اي را ﺣﻞ ﻛﻨﺪ ،اﺑﺘـﺪا ﺑﺎﻳﺪ آن را ﺑﻪ ﭼﻨﺪ ﻣﺴﺌﻠﻪ ﻛﻮﭼﻜﺘﺮ ﺗﻘﺴﻴﻢ ﻛﻨﻴﺪ ،و ﭼﮕﻮﻧﮕﻲ ﺣﻞ اﻳﻦ ﻣﺴﺎﻳﻞ را ﻗﺪم ﺑﻪ ﻗﺪم ﺗﻮﺿـﻴﺢ دﻫﻴـﺪ .اﻟﮕـﻮرﻳﺘﻢ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎ ﻛـﺎﻣﻼ
٥٤
ﻣﺴﺘﻘﻞ از زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﺳﺖ ﻛﻪ ﺑﺮاي ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ از آن اﺳﺘﻔﺎده ﻣﻴﻜﻨﻴﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺷﻤﺎ ﻣﻴﺘﻮاﻧﻴﺪ اﻟﮕﻮرﻳﺘﻢ ﻳﻚ ﺑﺮﻧﺎﻣـﻪ را ﺑـﻪ ﻫـﺮ ﻧﺤﻮي ﻛﻪ ﺑﻪ ﺷﻤﺎ ﻛﻤﻚ ﻣﻴﻜﻨﺪ ﺗﺎ ﻣﺴﺌﻠﻪ را درك ﻛﻨﻴﺪ ﺑﺎزﮔﻮ ﻛﻨﻴﺪ .ﻣﺜﻼ ﻣﻴﺘﻮاﻧﻴﺪ آن را ﺑﻪ زﺑﺎﻧﻲ ﻛﻪ ﺑﺎ آن ﺻﺤﺒﺖ ﻣﻴﻜﻨﻴﺪ ﺑﺮاي ﺧﻮدﺗـﺎن ﺗﻮﺿﻴﺢ ﺑﺪﻫﻴﺪ و ﻳﺎ آن را ﺑﻪ وﺳﻴﻠﻪ ﺷﻜﻠﻬﺎ و ﻧﻤﻮدارﻫﺎ رﺳﻢ ﻛﻨﻴﺪ. ﻓﺮض ﻛﻨﻴﺪ ﺷﻤﺎ ﺑﺮاي ﻳﻚ ﺷﺮﻛﺖ ﺧﺪﻣﺎت ﺗﻠﻔﻨﻲ ﻛﺎر ﻣﻴﻜﻨﻴﺪ و ﻣﻴﺨﻮاﻫﻴﺪ ﺻﻮرت ﺣﺴﺎب ﻣﺸﺘﺮﻛﻴﻦ را ﺑﺮ اﺳﺎس ﺗﻤﺎﺳﻬﺎﻳﻲ ﻛﻪ ﮔﺮﻓﺘﻪ اﻧﺪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ .اﻟﮕﻮرﻳﺘﻤﻲ ﻛﻪ ﺑﺮاي ﺣﻞ ﻣﺴﺌﻠﻪ ﺑﺎﻻ ﻣﻴﺘﻮاﻧﻴﺪ ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ ،ﻣﻴﺘﻮاﻧﺪ ﻣﺸﺎﺑﻪ اﻟﮕﻮرﻳﺘﻢ زﻳﺮ ﺑﺎﺷﺪ: (1 (2 (3 (4 (5 (6
در اﺑﺘﺪاي ﻫﺮ ﻣﺎه ﺷﻤﺎ ﺑﺎﻳﺪ ﺻﻮرت ﺣﺴﺎب ﻫﺮ ﻳﻚ از ﻣﺸﺘﺮﻛﻴﻦ ﺧﻮد را ﻣﺤﺎﺳﺒﻪ ﻛﻨﻴﺪ. ﺑﺮاي ﻫﺮ ﻣﺸﺘﺮك ،ﺷﻤﺎ ﻟﻴﺴﺖ ﺗﻤﺎﺳﻬﺎﻳﻲ ﻛﻪ آن ﻣﺸﺘﺮك در ﻣﺎه ﻗﺒﻞ ﮔﺮﻓﺘﻪ اﺳﺖ را دارﻳﺪ. ﺷﻤﺎ ﻣﺪت ﻫﺮ ﺗﻤﺎس و ﺳﺎﻋﺘﻲ ﻛﻪ آن ﺗﻤﺎس ﮔﺮﻓﺘﻪ ﺷﺪه ﺑﻮد را ﻣﻴﺪاﻧﻴﺪ و ﺑﺮ اﺳﺎس اﻳﻦ اﻃﻼﻋﺎت ﻣﻴﺘﻮاﻧﻴﺪ ﻫﺰﻳﻨﻪ ﻫﺮ ﺗﻤﺎس را ﻣﺸﺨﺺ ﻛﻨﻴﺪ. ﺑﺮاي ﻫﺮ ﻣﺸﺘﺮك ،ﺻﻮرت ﺣﺴﺎب او ﺑﺮاﺑﺮ اﺳﺖ ﺑﺎ ﻣﺠﻤﻮع ﻫﺰﻳﻨﻪ ﺗﻤﺎم ﺗﻤﺎﺳﻬﺎﻳﻲ ﻛﻪ داﺷﺘﻪ اﺳﺖ. ﻣﺎﻟﻴﺎت ﻫﺮ ﺻﻮرت ﺣﺴﺎب را ﻣﺤﺎﺳﺒﻪ ﻣﻲ ﻛﻨﻴﺪ. ﺑﻌﺪ از اﻳﻦ ﻛﻪ ﺻﻮرت ﺣﺴﺎب ﻧﻬﺎﻳﻲ ﻣﺤﺎﺳﺒﻪ ﺷﺪ ،ﺑﺎﻳﺪ آن را ﭼﺎپ ﻛﻨﻴﺪ.
اﻳﻦ ﺷﺶ ﻣﺮﺣﻠﻪ ،اﻟﮕﻮرﻳﺘﻢ ﻗﺴﻤﺘﻲ از ﻧﺮم اﻓﺰاري اﺳﺖ ﻛﻪ ﻫﺰﻳﻨﻪ ﻣﺎﻫﻴﺎﻧﻪ ﻣﺸﺘﺮﻛﻴﻦ ﻳﻚ ﻣﺮﻛﺰ ﺧﺪﻣﺎت ﺗﻠﻔﻨﻲ را ﻣﺤﺎﺳﺒﻪ ﻣﻴﻜﻨﺪ .ﺗﻔـﺎوﺗﻲ ﻧﺪارد ﺷﻤﺎ اﻳﻦ ﻧﺮم اﻓﺰار را ﺑﺎ ﭼﻪ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﻲ ﻧﻮﻳﺴﻴﺪ ،C# ،C++ ،وﻳﮋوال ﺑﻴـﺴﻴﻚ ،J# ،ﺟـﺎوا و ﻳـﺎ ﻫـﺮ زﺑـﺎن دﻳﮕـﺮي، اﻟﮕﻮرﻳﺘﻢ ﻛﻠﻲ ﺑﺮﻧﺎﻣﻪ ﺗﻐﻴﻴﺮي ﻧﻤﻴﻜﻨﺪ) .اﻟﺒﺘﻪ اﻳﻦ ﻫﻔﺖ ﻣﺮﺣﻠﻪ ﻫﻢ ﺧﻴﻠﻲ ﻛﻠﻲ ﻫﺴﺘﻨﺪ و ﺑﺎﻳﺪ ﻗﺒﻞ از اﻳﻦ ﻛﻪ ﺑﻪ وﺳـﻴﻠﻪ ﻳـﻚ زﺑـﺎن ﺑﺮﻧﺎﻣـﻪ ﻧﻮﻳﺴﻲ ﻧﻮﺷﺘﻪ ﺷﻮﻧﺪ ﺑﻪ ﻣﺮاﺣﻞ ﻛﻮﭼﻜﺘﺮي ﺷﻜﺴﺘﻪ ﺷﻮﻧﺪ و ﺟﺰﺋﻴﺎت ﺑﻴﺸﺘﺮي از آن ﺷﺮح داده ﺷﻮد( ﺣﺎﻻ ﺑﺮاي اﻓﺮادي ﻛﻪ ﺗﺎزه وارد ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﺪه اﻧﺪ ،ﻳﻚ ﺧﺒﺮ ﺧﻮب و ﻳﻚ ﺧﺒﺮ ﺑﺪ دارم .ﺧﺒﺮ ﺧﻮب اﻳﻦ اﺳﺖ ﻛﻪ ﻣﻌﻤـﻮﻻ اﻳﺠـﺎد ﻳـﻚ اﻟﮕﻮرﻳﺘﻢ ﺑﺴﻴﺎر ﺳﺎده اﺳﺖ .ﻣﺜﻼ در اﻟﮕﻮرﻳﺘﻢ ﻗﺒﻠﻲ ،ﻓﻜﺮ ﻧﻜﻨﻢ ﻗﺴﻤﺘﻲ ﺑﻪ ﻧﻈﺮ ﺷﻤﺎ ﮔﻨﮓ ﺑﺎﺷﺪ و واﺿﺢ ﺑﻪ ﻧﻈﺮ ﻧﺮﺳﺪ .ﻣﻌﻤﻮﻻ اﻟﮕﻮرﻳﺘﻢ ﻫﺎ از ﻳﻚ ﺳﺮي اﺳﺘﺪﻻل ﻫﺎﻳﻲ ﭘﻴﺮوي ﻣﻴﻜﻨﻨﺪ ﻛﻪ از ﻧﻈﺮ ﻣﺮدم ﻋﺎدي درﺳﺖ اﺳﺖ .اﻟﺒﺘﻪ ﻣﻤﻜﻦ اﺳﺖ ﻛﻪ ﺷﻤﺎ ﺑﺎ اﻟﮕـﻮرﻳﺘﻢ ﻫـﺎﻳﻲ ﺑﺮﺧـﻮرد ﻛﻨﻴﺪ ﻛﻪ داراي ﻓﺮﻣﻮﻟﻬﺎي ﭘﻴﭽﻴﺪه رﻳﺎﺿﻲ و ﻳﺎ ﻓﺮﻣﻮﻟﻬﺎي دﻳﮕﺮ ﻋﻠﻮم ﺑﺎﺷﻨﺪ و ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ ﻓﺮﻣﻮل ﻫﺎ ﺑﺎ اﺳﺘﺪﻻل ﻫﺎي ﺷﻤﺎ درﺳﺖ ﺑﻪ ﻧﻈﺮ ﻧﻤﻲ رﺳﻨﺪ ،اﻣﺎ ﺧﻮب اﻳﻦ ﻓﺮﻣﻮل ﻫﺎ ﻫﻢ از ﻧﻈﺮ اﻓﺮاد دﻳﮕﺮي ﻛﻪ آﻧﻬﺎ را ﻣﻴﺪاﻧﻨﺪ درﺳﺖ ﺑﻪ ﻧﻈﺮ ﻣﻴﺮﺳﺪ .اﻣﺎ ﺧﺒﺮ ﺑﺪ اﻳـﻦ اﺳـﺖ ﻛـﻪ ﻣﻌﻤﻮﻻ ﺗﺒﺪﻳﻞ ﻳﻚ اﻟﮕﻮرﻳﺘﻢ ﺑﻪ ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﻛﺎر ﻣﺸﻜﻠﻲ اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻪ ﻋﻨﻮان ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ اﻳﻦ ﻛﻪ ﺑﺪاﻧﻴﺪ ﭼﮕﻮﻧﻪ ﻳﻚ اﻟﮕـﻮرﻳﺘﻢ را ﺗﻮﺳﻂ ﻳﻚ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﭘﻴﺎده ﻛﻨﻴﺪ ﻣﻬﻢ اﺳﺖ. ﻫﻤﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﺣﺮﻓﻪ اي ﺑﺮ اﻳﻦ اﺻﻞ ﻋﻘﻴﺪه دارﻧﺪ ﻛﻪ ﺗﻘﺪم ﻳﻚ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺮ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ دﻳﮕﺮ ،ﻛـﺎﻣﻼ ﺑـﻲ رﺑـﻂ اﺳﺖ .زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺘﻔﺎوت ﻣﻴﺘﻮاﻧﻨﺪ ﻛﺎرﻫﺎي ﻣﺨﺘﻠﻔﻲ را راﺣﺖ ﺗﺮ و ﺳﺮﻳﻌﺘﺮ اﻧﺠﺎم دﻫﻨﺪ .ﻣﺜﻼ C++ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﻗـﺪرت زﻳﺎدي در ﻛﻨﺘﺮل ﻧﺤﻮه اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﻴﺪﻫﺪ و ﻫﻤﭽﻨﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎي آن ﻧﻴﺰ از ﺳﺮﻋﺖ اﺟﺮاي ﺑﺎﻻﻳﻲ ﺑﺮﺧﻮردار ﻫﺴﺘﻨﺪ ،اﻣﺎ ﺑـﺪي آن اﻳـﻦ اﺳﺖ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻪ اﻳﻦ زﺑﺎن ﺑﺴﻴﺎر ﻣﺸﻜﻞ اﺳﺖ و ﻳﺎدﮔﻴﺮي آن ﺑﺮاي ﻣﺒﺘﺪﻳﺎن ﻣﻌﻤﻮﻻ ﺑﺴﻴﺎر ﺳﺨﺖ اﺳﺖ .در ﻣﻘﺎﺑﻞ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ و ﻳﺎدﮔﻴﺮي زﺑﺎن وﻳﮋوال ﺑﻴﺴﻴﻚ ﺑﺴﻴﺎر راﺣﺖ ﺗﺮ اﺳﺖ ،اﻣﺎ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ در اﻳﻦ زﺑﺎن ﻛﻨﺘـﺮل ﻛـﺎﻓﻲ ﺑـﺮ روي ﺑﺮﻧﺎﻣـﻪ ﻧـﺪارد )زﺑـﺎن C# ﻫﻤﺎﻧﻄﻮر ﻛﻪ ادﻋﺎ ﺷﺪه اﺳﺖ ،زﺑﺎﻧﻲ اﺳﺖ ﻛﻪ از ﺳﺎدﮔﻲ زﺑﺎﻧﻲ ﻣﺎﻧﻨﺪ وﻳﮋوال ﺑﻴﺴﻴﻚ و ﻗﺪرت زﺑﺎﻧﻲ ﻣﺎﻧﻨﺪ C++ﺑﺮﺧﻮردار اﺳـﺖ( .ﭼﻴـﺰي ﻛﻪ ﺷﻤﺎ ﺑﺎﻳﺪ ﺑﻪ ﻋﻨﻮان ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻳﺎد ﺑﮕﻴﺮﻳﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺘﻮاﻧﻴﺪ ﺑﺮاي ﺣﻞ ﻳﻚ ﻣﺴﺌﻠﻪ ،زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺨﺘﻠﻒ را ﺑﺮرﺳﻲ ﻛﻨﻴﺪ .اﻟﺒﺘﻪ زﻣﺎﻧﻲ ﻛﻪ ﺷﺮوع ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ اوﻟﻴﻦ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ را ﻳﺎد ﺑﮕﻴﺮﻳﺪ ،در آن ﭘﻴﺸﺮﻓﺖ ﻛﻨـﺪي ﺧﻮاﻫﻴـﺪ داﺷـﺖ ،اﻣـﺎ ﻣﻌﻤـﻮﻻ زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ در ﻧﺤﻮه اﺟﺮا و ﭘﻴﺎده ﻛﺮدن اﻟﮕﻮرﻳﺘﻢ ﻫﺎ ﺗﻔﺎوﺗﻲ ﻧﺪارﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ را ﻳﺎد ﮔﺮﻓﺘﻴـﺪ، ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺗﺠﺮﺑﻪ ﺧﻮد در اﻟﮕﻮرﻳﺘﻢ ﻫﺎ و ﻳﺎ ﺣﺘﻲ ﻛﺪ زﺑﺎن ﻗﺒﻠﻲ در زﺑﺎن ﺟﺪﻳﺪ ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﺮده و ﭼﻨﺪﻳﻦ زﺑﺎن دﻳﮕﺮ را ﻧﻴﺰ ﺑـﻪ ﺳـﺮﻋﺖ ﻳﺎد ﺑﮕﻴﺮﻳﺪ.
٥٥
ﻳﻚ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﭼﻴﺴﺖ؟ از ﻳﻚ ﻧﮕﺎه ،ﻣﻴﺘﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ ﻛﻪ ﻳﻚ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻪ ﭼﻴﺰي ﮔﻔﺘﻪ ﻣﻴﺸﻮد ﻛﻪ ﺗﻮاﻧﺎﻳﻲ ﺗـﺼﻤﻴﻢ ﮔﻴـﺮي داﺷـﺘﻪ ﺑﺎﺷـﺪ .ﻛﺎﻣﭙﻴﻮﺗﺮﻫـﺎ ﻣﻌﻤﻮﻻ ﺧﻴﻠﻲ ﺳﺮﻳﻊ و ﺑﺎ دﻗﺖ ﻣﻴﺘﻮاﻧﻨﺪ ﺗﺼﻤﻴﻢ ﮔﻴﺮي ﻛﻨﻨﺪ اﻣﺎ ﻣﺘﺎﺳﻔﺎﻧﻪ ،ﻓﻘﻂ در زﻣﻴﻨﻪ ﻫﺎي ﺑﺴﻴﺎر ﺳﺎده ﻣﻴﺘﻮاﻧﻨﺪ اﻳﻦ ﻛﺎر را اﻧﺠﺎم ﺑﺪﻫﻨﺪ. ﻣﺜﻼ "آﻳﺎ اﻳﻦ ﻋﺪد ﺑﺰرﮔﺘﺮ از ﺳﻪ اﺳﺖ؟" و ﻳﺎ "آﻳﺎ اﻳﻦ ﻣﺎﺷﻴﻦ آﺑﻲ اﺳﺖ؟". اﮔﺮ ﺷﻤﺎ ﺑﺨﻮاﻫﻴﺪ ﻳﻚ ﺗﺼﻤﻴﻢ ﮔﻴﺮي ﭘﻴﭽﻴﺪه را ﺑﻪ وﺳﻴﻠﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ اﻧﺠﺎم دﻫﻴﺪ ،اﺑﺘﺪا ﺑﺎﻳـﺪ آن را ﺑـﻪ ﻗـﺴﻤﺘﻬﺎي ﻛـﻮﭼﻜﺘﺮي ﻛـﻪ ﺗﻮﺳـﻂ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻗﺎﺑﻞ ﻓﻬﻢ ﺑﺎﺷﺪ ﺗﻘﺴﻴﻢ ﻛﻨﻴﺪ .ﻣﻌﻤﻮﻻ ﺑﺮاي ﻓﻬﻤﻴﺪن اﻳﻦ ﻛﻪ ﭼﮕﻮﻧﻪ ﻳﻚ ﺗﺼﻤﻴﻢ ﮔﻴﺮي ﭘﻴﭽﻴﺪه را ﺑﻪ ﭼﻨﺪ ﻗﺴﻤﺖ ﺳـﺎده ﺗﻘـﺴﻴﻢ ﻛﻨﻴﺪ ﻣﻴﺘﻮاﻧﻴﺪ از اﻟﮕﻮرﻳﺘﻢ ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﺑﺮاي ﻧﻤﻮﻧﻪ ﻳﻚ ﻣﺴﺌﻠﻪ ﻛﻪ ﺣﻞ آن ﺑﺮاي ﻛﺎﻣﭙﻴﻮﺗﺮ ﺧﻴﻠﻲ ﺳﺨﺖ اﺳﺖ ،ﺗﺸﺨﻴﺺ ﭼﻬﺮه اﻧﺴﺎﻧﻬﺎ اﺳﺖ .ﺷـﻤﺎ ﻧﻤﻴﺘﻮاﻧﻴـﺪ ﺑـﻪ ﻳـﻚ ﻛـﺎﻣﭙﻴﻮﺗﺮ ﺑﮕﻮﻳﻴﺪ ﻛﻪ "آﻳﺎ اﻳﻦ ﻋﻜﺲ ﺗﺼﻮﻳﺮي از ﻣﺎري اﺳﺖ؟" ،ﺑﻠﻜﻪ ﺑﺎﻳﺪ اﻳﻦ ﻣﺴﺌﻠﻪ را ﺑﻪ ﭼﻨﺪ ﻣﺴﺌﻠﻪ ﻛﻮﭼﻜﺘﺮ ﻛﻪ ﺗﻮﺳـﻂ ﻛـﺎﻣﭙﻴﻮﺗﺮ ﻗﺎﺑـﻞ ﻓﻬـﻢ ﺑﺎﺷﺪ ﺗﻘﺴﻴﻢ ﻛﻨﻴﺪ ﺗﺎ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﺘﻮاﻧﺪ ﺑﻪ آﻧﻬﺎ ﭘﺎﺳﺦ ﺻﺤﻴﺢ ﺑﺪﻫﺪ. ﺳﻮاﻻﺗﻲ ﻛﻪ ﺷﻤﺎ ﻣﻴﺘﻮاﻧﻴﺪ از ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎ ﺑﭙﺮﺳﻴﺪ و ﺑﺮ اﺳﺎس آﻧﻬﺎ ﺗﺼﻤﻴﻢ ﮔﻴﺮي ﻛﻨﻴﺪ ﻣﻌﻤﻮﻻ داراي ﺟﻮاب ﺑﻠﻪ و ﻳﺎ ﺧﻴـﺮ ﻫـﺴﺘﻨﺪ .اﻳـﻦ دو ﺟﻮاب ﻣﻌﻤﻮﻻ ﺑﺎ ﻋﻨﻮان درﺳﺖ و ﻏﻠﻂ و ﻳﺎ 1و 0ﻧﻴﺰ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮﻧﺪ .در زﻣﺎن ﻧﻮﺷﺘﻦ ﻧﺮم اﻓﺰار ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﺑﺮ اﺳﺎس ﭘﺎﺳـﺦ ﺑـﻪ ﺳﻮال " 10در ﻣﻘﺎﻳﺴﻪ ﺑﺎ 4ﭼﻪ ﻗﺪر ﺑﺰرﮔﺘﺮ اﺳﺖ؟" ﺗﺼﻤﻴﻢ ﮔﻴﺮي ﻛﻨﻴﺪ .ﺑﻠﻜﻪ ﺑﺎﻳﺪ اﻳﻦ ﺳﻮال را ﺑﻪ ﺻﻮرت "آﻳﺎ 10از 4ﺑﺰرﮔﺘـﺮ اﺳـﺖ؟" ﺑﭙﺮﺳﻴﺪ .ﺗﻔﺎوت اﻳﻦ دو ﺳﻮال ﺑﺴﻴﺎر رﻳﺰ و در ﻋﻴﻦ ﺣﺎل ﻣﻬﻢ اﺳﺖ .ﺟﻮاب ﺳﻮال اول ﺑﻪ ﺻﻮرت ﺑﻠﻪ و ﻳﺎ ﺧﻴﺮ ﻧﻴﺴﺖ اﻣﺎ ﺟﻮاب ﺳـﻮال دوم ﺑﻪ اﻳﻦ ﺻﻮرت اﺳﺖ .اﻟﺒﺘﻪ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻴﺪاﻧﻴﺪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻗﺎدر اﺳﺖ ﺑﻪ ﺳﻮال اول ﻫﻢ ﭘﺎﺳﺦ ﺑﺪﻫﺪ ،اﻣـﺎ ﺑـﺮ اﺳـﺎس اﻳـﻦ ﭘﺎﺳـﺦ ﻧﻤﻴﺘـﻮان ﺗﺼﻤﻴﻢ ﮔﻴﺮي ﻛﺮد .ﺑﺮاي ﭘﺎﺳﺦ ﺳﻮال اول ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﻘﺪار 4را از 10ﻛﻢ ﻣﻴﻜﻨﺪ و ﺣﺎﺻﻞ را ﻧﮕﻬﺪاري ﻣﻴﻜﻨـﺪ ﺗـﺎ ﺷـﻤﺎ ﺑﺘﻮاﻧﻴـﺪ از آن در ﻗﺴﻤﺘﻬﺎي دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﻣﻤﻜﻦ اﺳﺖ ﻛﻪ ﻓﻜﺮ ﻛﻨﻴﺪ ﺗﺼﻤﻴﻢ ﮔﻴﺮي ﻓﻘﻂ ﺑﺮ اﺳﺎس ﺑﻠﻪ و ﻳﺎ ﺧﻴﺮ ﻳﻚ ﻣﺤﺪودﻳﺖ اﺳﺖ ،اﻣﺎ واﻗﻌﺎً اﻳﻦ ﻃﻮر ﻧﻴـﺴﺖ .ﺣﺘـﻲ در زﻧـﺪﮔﻲ روزﻣﺮه ﻧﻴﺰ ﺗﺼﻤﻴﻢ ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﮔﻴﺮﻳﻢ ﻧﻮﻋﻲ از ﺑﻠﻪ و ﺧﻴﺮ اﺳﺖ .وﻗﺘﻲ ﺷﻤﺎ ﻣﻴﺨﻮاﻫﻴﺪ راﺟﻊ ﺑﻪ ﻣﻮردي ﺗﺼﻤﻴﻢ ﺑﮕﻴﺮﻳـﺪ ،ﻳـﺎ آن را ﻗﺒـﻮل ﻣﻴﻜﻨﻴﺪ )ﺑﻠﻪ ،درﺳﺖ و ﻳﺎ (1ﻳﺎ آن را رد ﻣﻴﻜﻨﻴﺪ )ﻧﻪ ،ﻏﻠﻂ ﻳﺎ .(0 در اﻳﻦ ﻛﺘﺎب ﺷﻤﺎ از C#ﺑﻪ ﻋﻨﻮان زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺧﻮد اﺳﺘﻔﺎده ﻣﻴﻜﻨﻴﺪ ،اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻴﺪاﻧﻴﺪ ﺟﻨﺒﻪ ﻣﻬﻢ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﻳﻦ اﺳﺖ ﻛﻪ زﺑﺎن ﻣﻮرد اﺳﺘﻔﺎده در آن ﻣﻬﻢ ﻧﻴﺴﺖ .در ﺣﻘﻴﻘﺖ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺴﺘﻘﻞ از زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﺳـﺖ .ﻫـﺮ ﺑﺮﻧﺎﻣـﻪ اي ،ﺑﺎ ﻫﺮ ﺷﻜﻞ و ﻇﺎﻫﺮي ﻛﻪ ﺑﺎﺷﺪ و ﻫﺮ زﺑﺎﻧﻲ ﻛﻪ ﻧﻮﺷﺘﻪ ﺷﺪه ﺑﺎﺷﺪ ،از ﻣﺘﺪﻫﺎ )ﺗﻮاﺑﻊ و زﻳﺮﺑﺮﻧﺎﻣﻪ ﻫﺎ :ﭼﻨﺪﻳﻦ ﺧﻂ ﻛﺪ ﻛﻪ ﻳـﻚ اﻟﮕـﻮرﻳﺘﻢ ﺧﺎص را اﺟﺮا ﻣﻴﻜﻨﻨﺪ( و ﻣﺘﻐﻴﻴﺮ ﻫﺎ )ﻣﻜﺎﻧﻲ ﺑﺮاي ﻧﮕﻬﺪاري و ﺗﻐﻴﻴﺮ داده ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﻫﺎ ( ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ.
ﻣﺘﻐﻴﻴﺮ ﻫﺎ: ﻣﺘﻐﻴﻴﺮ ﻣﻜﺎﻧﻲ اﺳﺖ ﻛﻪ ﺷﻤﺎ در ﻃﻮل ﻛﺎر اﻟﮕﻮرﻳﺘﻢ ﺧﻮد ﻣﻘﺪاري را در آن ذﺧﻴﺮه ﻣﻲ ﻛﻨﻴﺪ .ﺑﻌﺪﻫﺎ ﺷﻤﺎ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﺮ اﺳـﺎس ﻣﻘـﺪار آن ﻣﺘﻐﻴﻴﺮ ﺗﺼﻤﻴﻢ ﮔﻴﺮي ﻛﻨﻴﺪ )ﺑﺮاي ﻣﺜﺎل "آﻳﺎ اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﺑﺮاﺑﺮ 79اﺳﺖ؟" و ﻳﺎ "آﻳﺎ اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﺑﻴﺸﺘﺮ از 4اﺳﺖ؟"( ﻳﺎ ﻋﻤﻠﻴـﺎت رﻳﺎﺿـﻲ و ﻣﺤﺎﺳﺒﺎﺗﻲ ﺑﺮ روي آن اﻧﺠﺎم دﻫﻴﺪ ) ﻣﺜﻼ "ﻣﺘﻐﻴﻴﺮ را ﺑﺎ 2ﺟﻤﻊ ﻛﻦ ".و ﻳﺎ "ﻣﺘﻐﻴﻴﺮ را در 6ﺿﺮب ﻛﻦ"( ﻳﺎ ﭼﻴﺰﻫﺎي دﻳﮕﺮ.
ﻛﺎر ﺑﺎ ﻣﺘﻐﻴﻴﺮ ﻫﺎ:
٥٦
ﻗﺒﻞ از اﻳﻨﻜﻪ درﮔﻴﺮ ﻣﺘﻐﻴﻴﺮ ﻫﺎ در ﻛﺪ ﺷﻮﻳﻢ ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﺑﻪ اﻟﮕﻮرﻳﺘﻢ زﻳﺮ ﺗﻮﺟﻪ ﻛﻨﻴﺪ: (1ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﻧﺎم nاﻳﺠﺎد ﻛﻨﻴﺪ و ﻣﻘﺪار 27را در آن ذﺧﻴﺮه ﻛﻨﻴﺪ. (2ﻣﺘﻐﻴﻴﺮ nرا ﺑﺎ ﻋﺪد 1ﺟﻤﻊ ﻛﻨﻴﺪ و ﺣﺎﺻﻞ را ﻣﺠﺪداً در nﻗﺮار دﻫﻴﺪ. (3ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ nرا ﺑﻪ ﻛﺎرﺑﺮ ﻧﺸﺎن دﻫﻴﺪ. در اﻳﻦ اﻟﮕﻮرﻳﺘﻢ ﺷﻤﺎ ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﻧﺎم nاﻳﺠﺎد ﻛﺮده و ﻣﻘﺪار 27را در آن ﻗﺮار ﻣﻲ دﻫﻴﺪ .اﻳﻦ ﻣـﻮرد ﺑـﻪ اﻳـﻦ ﻣﻌﻨـﻲ اﺳـﺖ ﻛـﻪ ﺷـﻤﺎ ﻣﻘﺪاري از ﺣﺎﻓﻈﻪ ي ﻛﺎﻣﭙﻴﻮﺗﺮ را ﻛﻪ ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ اﺳﺖ ﮔﺮﻓﺘﻪ اﻳﺪ و ﻣﻘﺪار 27را در آن ﻗـﺮار داده اﻳـﺪ .اﻳـﻦ ﻗـﺴﻤﺖ از ﺣﺎﻓﻈـﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﻘﺪار 27را ﺑﺮاي ﺷﻤﺎ ﻧﮕﻪ ﺧﻮاﻫﺪ داﺷﺖ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ آن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ و ﻳﺎ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﺑﮕﻮﻳﻴﺪ ﻛﻪ دﻳﮕﺮ ﺑﻪ آن ﻧﻴﺎزي ﻧﺪارﻳﺪ. در ﻣﺮﺣﻠﻪ دوم ﺷﻤﺎ ﻳﻚ ﻋﻤﻠﻴﺎت ﺟﻤﻊ اﻧﺠﺎم ﻣﻲ دﻫﻴﺪ .در اﻳﻦ ﻣﺮﺣﻠﻪ ،ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ nرا از ﮔﺮﻓﺘﻪ و آن را ﺑـﺎ ﻋـﺪد 1ﺟﻤـﻊ ﻣـﻲ ﻛﻨﻴـﺪ. ﺳﭙﺲ آن را ﻣﺠﺪداً در nﻗﺮار ﻣﻲ دﻫﻴﺪ .ﺑﻌﺪ از ﭘﺎﻳﺎن اﻳﻦ ﻋﻤﻠﻴﺎت ﻗﺴﻤﺘﻲ از ﺣﺎﻓﻈﻪ ﻛﻪ ﻣﺘﻐﻴﻴﺮ nرا ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ ،ﺣﺎوي ﻣﻘﺪار 28 ﺧﻮاﻫﺪ ﺑﻮد. در ﻣﺮﺣﻠﻪ آﺧﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﻪ ﻛﺎرﺑﺮ ﻣﻘﺪار nرا ﻧﺸﺎن دﻫﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ nرا از ﺣﺎﻓﻈـﻪ ﻛـﺎﻣﭙﻴﻮﺗﺮ ﺧﻮاﻧـﺪه و آن را ﺑـﺮاي ﻛﺎرﺑﺮ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻧﺸﺎن ﻣﻲ دﻫﻴﺪ. ﻓﻜﺮ ﻧﻜﻨﻢ ﭼﻴﺰي در اﻳﻦ اﻟﮕﻮرﻳﺘﻢ ﻧﺎﻣﻔﻬﻮم ﺑﺎﺷﺪ ﻛﻪ ﻣﺘﻮﺟﻪ آن ﻧﺸﺪه ﺑﺎﺷﻴﺪ .ﻫﻤﻪ ﭼﻴﺰ واﺿﺢ اﺳﺖ! اﻟﺒﺘﻪ ،ﻛـﺪ اﻳـﻦ ﻛـﺎر در وﻳـﮋوال C# 2005ﻣﻘﺪاري رﻣﺰي ﺗﺮ ﺑﻪ ﻧﻈﺮ ﻣﻲ رﺳﺪ .در ﺑﺨﺶ "اﻣﺘﺤﺎن ﻛﻨﻴﺪ" زﻳﺮ ،ﺑﻴﺸﺘﺮ در راﺑﻄﻪ ﺑﺎ ﻛﺎر ﺑﺎ ﻣﺘﻐﻴﻴﺮ ﻫﺎ در C#آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻛﺎر ﺑﺎ ﻣﺘﻐﻴﻴﺮ ﻫﺎ (1ﺑﺎ اﻧﺘﺨﺎب ﮔﺰﻳﻨﻪ File New Projectاز ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ ،ﻳﻚ ﭘﺮوژه ﺟﺪﻳﺪ را اﻳﺠﺎد ﻛﻨﻴـﺪ. در ﭘﻨﺠﺮه New Projectاز ﻗﺴﻤﺖ ﺳﻤﺖ راﺳﺖ Windows Applicationرا اﻧﺘﺨﺎب ﻛﻨﻴـﺪ و در ﻗﺴﻤﺖ ﻧﺎم ﭘﺮوژه Variablesرا وارد ﻛﻨﻴﺪ .ﺳﭙﺲ روي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ) .ﺷﻜﻞ (1-3 (2ﭘﻨﺠﺮه Form1را ﻣﻘﺪاري ﻛﻮﭼﻜﺘﺮ ﻛﻨﻴﺪ و ﺳﭙﺲ از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل Buttonروي آن ﻗـﺮار دﻫﻴـﺪ .ﺧﺎﺻـﻴﺖ Textآن را ﺑﻪ Add 1 to intNumberو ﺧﺎﺻﻴﺖ Nameآن را ﺑﻪ btnAddﺗﻐﻴﻴـﺮ دﻫﻴـﺪ .ﻓـﺮم ﺷﻤﺎ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 2-3ﺷﻮد. (3روي دﻛﻤﻪ ﻓﺮﻣﺎن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺗﺎﺑﻊ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickدﻛﻤﻪ ﻓﺮﻣﺎن ﺑﺎ ﻧـﺎم btnAdd_Click ﺑﺎز ﺷﻮد .ﻛﺪﻫﺎي ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ. )private void btnAdd_Click(object sender, EventArgs e { ;int intNumber ;intNumber = 27 ;intNumber = intNumber + 1 (MessageBox.Show "Value of intNumber + 1 = " + intNumber, ;)""Variables }
٥٧
ﺷﻜﻞ 1-3
ﺷﻜﻞ 2-3 (4ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﺮ روي دﻛﻤﻪ Add 1 to intNumberﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ 3-3 ﻧﻤﺎﻳﺶ داده ﻣﻴﺸﻮد.
ﺷﻜﻞ 3-3
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟
٥٨
ﺑﺮﻧﺎﻣﻪ از ﺑﺎﻻﺗﺮﻳﻦ ﺧﻂ ﺷﺮوع ﻣﻲ ﺷﻮد ،ﻳﻜﻲ ﻳﻜﻲ ﺧﻄﻬﺎ را اﺟﺮا ﻣﻴﻜﻨﺪ و ﺑﻪ ﺳﻤﺖ ﭘﺎﻳﻴﻦ ﻣﻲ آﻳﺪ .ﺧﻂ اول ﻳﻚ ﻣﺘﻐﻴﻴـﺮ ﺟﺪﻳـﺪ ﺑـﻪ ﻧـﺎم intNumberاﻳﺠﺎد ﻣﻴﻜﻨﺪ. ;int intNumber intدر C#ﻳﻚ ﻛﻠﻤﻪ ﻛﻠﻴﺪي اﺳﺖ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻓﺼﻞ ﻳﻚ ﮔﻔﺘﻢ ﻛﻠﻤﻪ ﻛﻠﻴﺪي ،ﺑﻪ ﻛﻠﻤﻪ اي ﮔﻔﺘﻪ ﻣﻴﺸﻮد ﻛﻪ ﺑﺮاي وﻳـﮋوال C# 2005ﻣﻌﻨﻲ ﺧﺎﺻﻲ دارد .ﻣﺎﻧﻨﺪ دﺳﺘﻮرات .ﻛﻠﻤﻪ ﻛﻠﻴﺪي ،intﻛﻪ ﻣﺨﻔﻒ ﻛﻠﻤﻪ integerﺑﻪ ﻣﻌﻨـﺎي ﻋـﺪد ﺻـﺤﻴﺢ اﺳـﺖ ،ﻧـﻮع ﻣﻘﺪاري ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ در اﻳﻦ ﻣﺘﻐﻴﻴﺮ ذﺧﻴﺮه ﻛﻨﻴﻢ را ﺑﻪ وﻳﮋوال 2005 C#ﻣﻴﮕﻮﻳﺪ .اﻳﻦ ﻛﻠﻤﺎت ﻛﻪ ﺑـﺮاي ﻣـﺸﺨﺺ ﻛـﺮدن ﻧـﻮع داده ﻣﻮرد ﻧﻈﺮ اﺳﺘﻔﺎده ﻣﻴﺸﻮﻧﺪ ،ﺑﻪ "ﻧﻮع داده اي" ﻣﻌﺮوف ﻫﺴﺘﻨﺪ .ﻓﻌﻼ ﻫﻤﻴﻦ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﺑﺪاﻧﻴﺪ ،اﻳـﻦ ﻧـﻮع داده اي ﺑـﻪ وﻳـﮋوال C# 2005ﻣﻴﮕﻮﻳﺪ ﻛﻪ ﺷﻤﺎ ﻣﻴﺨﻮاﻫﻴﺪ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ را در اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻗﺮار دﻫﻴﺪ. ﻧﻜﺘﻪ :ﻛﻠﻤﻪ intﺑﺮاي ﺗﻌﺮﻳﻒ ﻧﻮع داده اي ﻋﺪد ﺻﺤﻴﺢ در C#از زﺑﺎن C++ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ .در C#ﺑﻌﻀﻲ از ﻛﻠﻤـﺎت ﻛﻠﻴـﺪي ﻛﻪ ﻣﺮﺑﻮط ﺑﻪ ﻛﺎر ﺑﺎ اﻋﺪاد ﻫﺴﺘﻨﺪ ،از زﺑﺎن C++ﮔﺮﻓﺘﻪ ﺷﺪه اﻧﺪ ،ﻣﺎﻧﻨﺪ ﻛﻠﻤﺎت ﻛﻠﻴﺪي ﻣﺮﺑﻮط ﺑﻪ ﺗﻌﺮﻳﻒ اﻋﺪاد ﺻﺤﻴﺢ ،اﻋـﺪاد اﻋـﺸﺎري، اﻋﺪاد ﺻﺤﻴﺢ ﺑﺰرگ و .. ﺑﻌﺪ از اﻳﻦ ﻛﻪ ﻧﻮع داده اي ﻣﺘﻐﻴﻴﺮ ﺧﻮد را ﻣﺸﺨﺺ ﻛﺮدﻳﻢ ،ﺑﺎﻳﺪ ﻧﺎﻣﻲ را ﺑﻪ آن اﺧﺘﺼﺎص دﻫﻴﻢ ﺗﺎ در ﻃﻮل ﺑﺮﻧﺎﻣﻪ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑـﻪ آن، از آن ﻧﺎم اﺳﺘﻔﺎده ﻛﻨﻴﻢ .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﺎم intNumberرا ﺑﺮاي ﻣﺘﻐﻴﻴﺮ اﻧﺘﺨﺎب ﻛﺮده اﻳﻢ .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در ﻧﺎﻣﮕﺬاري اﻳﻦ ﻣﺘﻐﻴﻴﺮ از ﻧﻤﺎد ﮔﺬاري ﻣﺠﺎرﺳﺘﺎﻧﻲ ﻛﻪ در ﻓﺼﻞ ﻳﻚ ﺗﻮﺿﻴﺢ دادم اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ .در اﻳﻨﺠﺎ ﻛﻠﻤﻪ intﻣﺨﻔﻒ ﻋﺒﺎرت Integerاﺳﺖ و ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ را در ﺧﻮد ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ .ﻛﻠﻤﻪ Numberﻫﻢ ﻧـﺎم ﺧـﻮد ﻣﺘﻐﻴﻴـﺮ اﺳـﺖ .در ﻃﻮل ﺑﺮﻧﺎﻣﻪ دﻳﺪﻳﺪ ﻛﻪ اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ را در ﺧﻮد ﻧﮕﻬﺪاري ﻣﻴﻜﻨﺪ ،ﭘﺲ اﻳﻦ ﻧﺎم ﺑﺮاي آن ﻣﻨﺎﺳﺐ اﺳﺖ. دﺳﺘﻮر ﻧﻮﺷﺘﻪ ﺷﺪه در ﺧﻂ ﺑﻌﺪي ،ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ intNumberرا در آن ﻗﺮار ﻣﻲ دﻫﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ در اﻳـﻦ ﺧـﻂ ﻣﻘـﺪار 27در intNumberﻗﺮار ﻣﻲ ﮔﻴﺮد. ﻧﻜﺘﻪ :ﻣﻲ ﺗﻮاﻧﻴﻢ ﻣﻘﺪار ﻳﻚ ﻣﺘﻐﻴﻴﺮ را ﻫﻨﮕﺎم ﺗﻌﺮﻳﻒ ﻧﻴﺰ ﺑﻪ آن ﺑﺪﻫﻴﻢ .ﻣﺜﻼً در ﺑﺮﻧﺎﻣﻪ ي ﺑﺎﻻ ﺑﻪ ﺟﺎي اﻳﻨﻜﻪ در ﻳﻚ ﺧﻂ ﻣﺘﻐﻴﻴﺮ را ﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ و در ﺧﻂ ﺑﻌﺪ ﻣﻘﺪار 27را ﺑﻪ آن اﺧﺘﺼﺎص دﻫﻴﻢ ،ﻣﻲ ﺗﻮاﻧﺴﺘﻴﻢ ﺑﻪ ﺻﻮرت زﻳﺮ در ﻳﻚ ﺧﻂ ﻫﻢ ﻣﺘﻐﻴﻴﺮ را ﺗﻌﺮﻳﻒ ﻛﺮده و ﻫﻢ ﺑـﻪ آن ﻣﻘﺪار ﺑﺪﻫﻴﻢ: ;int intNumber = 27 دﺳﺘﻮر ﺧﻂ ﺑﻌﺪي ،ﻋﺪد ﻳﻚ را ﺑﺎ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ intNumberﺟﻤﻊ ﻣﻴﻜﻨﺪ: ;intNumber = intNumber + 1 اﮔﺮ از دﻳﺪ رﻳﺎﺿﻲ ﺑﻪ اﻳﻦ دﺳﺘﻮر ﻧﮕﺎه ﻛﻨﻴﺪ ﻣﻤﻜﻦ اﺳﺖ اﺷﺘﺒﺎه ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ .اﻣﺎ در ﺣﻘﻴﻘﺖ ﻛﺎري ﻛﻪ اﻳﻦ دﺳﺘﻮر اﻧﺠﺎم ﻣﻴﺪﻫﺪ ،اﻳﻦ اﺳﺖ ﻛﻪ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ intNumberرا ﺑﺎ ﻋﺪد 1ﺟﻤﻊ ﻣﻴﻜﻨﺪ و ﺣﺎﺻﻞ را ﻣﺠﺪدا در intNumberذﺧﻴﺮه ﻣﻴﻜﻨﺪ. ﺧﻂ آﺧﺮ ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ ﻣﻴﺪﻫﺪ ﻛﻪ در آن ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ intNumber + 1ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ .ﻋﺒـﺎرﺗﻲ ﻛـﻪ اﻳﻦ ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ ﻣﻴﺪﻫﺪ ﺑﻪ ﺻﻮرت ﻣﺠﻤﻮع رﺷﺘﻪ ي "= "Value of intNumber + 1و ﻣﻘـﺪار ﻛﻨـﻮﻧﻲ intNumberاﺳﺖ .ﻫﻤﭽﻨﻴﻦ ﻋﻨﻮان اﻳﻦ ﭘﻨﺠﺮه را ﻧﻴﺰ " "Variablesﻗﺮار ﻣﻴﺪﻫﻴﻢ ﺗﺎ ﺑﺎ ﻧﺎم ﺑﺮﻧﺎﻣﻪ ﻫﻤﺎﻫﻨﮓ ﺷﻮد:
٥٩
(MessageBox.Show "Value of intNumber + 1 = " + intNumber, ;)""Variables
ﺗﻮﺿﻴﺤﺎت و ﻓﻀﺎﻫﺎي ﺧﺎﻟﻲ: ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺪ ﻳﻚ ﻧﺮم اﻓﺰار را ﻣﻲ ﻧﻮﻳﺴﻴﺪ ،ﺑﺎﻳﺪ ﺑﺪاﻧﻴﺪ ﻛﻪ ﺷﻤﺎ ﻳﺎ ﺷﺨﺺ دﻳﮕﺮي در آﻳﻨﺪه ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﺪ اﻳﻦ ﻛﺪ را ﺗﻐﻴﻴﺮ دﻫـﺪ. ﺑﻨﺎﺑﺮاﻳﻦ وﻇﻴﻔﻪ ﺷﻤﺎﺳﺖ ﻛﻪ ﺗﺎ ﺟﺎﻳﻲ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﻛﺪ را ﻗﺎﺑﻞ ﻓﻬﻢ ﻛﻨﻴﺪ.
ﺗﻮﺿﻴﺤﺎت: ﺗﻮﺿﻴﺤﺎت ﺑﺨﺸﻲ از ﺑﺮﻧﺎﻣﻪ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ وﻳﮋوال 2005 C#ﻧﺎدﻳﺪه ﮔﺮﻓﺘﻪ ﻣﻲ ﺷـﻮﻧﺪ .ﻳﻌﻨـﻲ ﺷـﻤﺎ ﻣـﻲ ﺗﻮاﻧﻴـﺪ در اﻳـﻦ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ ،ﻫﺮ ﭼﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ و ﺑﻪ ﻫﺮ زﺑﺎﻧﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﻨﻮﻳﺴﻴﺪ و ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛـﻪ ﻗﻮاﻋـﺪ ﺧﺎﺻـﻲ را رﻋﺎﻳـﺖ ﻛﻨﻴـﺪ .اﻳـﻦ ﻗﺴﻤﺖ ﻓﻘﻂ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻛﻪ در ﺣﺎل ﻣﻄﺎﻟﻌﻪ ﻛﺪ ﺑﺮﻧﺎﻣﻪ اﺳﺖ ﻛﻤﻚ ﻣﻲ ﻛﻨﺪ ﺗﺎ راﺣﺖ ﺗﺮ ﺑﻔﻬﻤﺪ آن ﻗـﺴﻤﺖ از ﺑﺮﻧﺎﻣـﻪ در ﺣـﺎل ﭼـﻪ ﻛﺎري اﺳﺖ. ﻧﻜﺘﻪ :ﻫﻤﻪ زﺑﺎﻧﻬﺎ ﻗﺎﺑﻠﻴﺖ ﻧﻮﺷﺘﻦ ﺗﻮﺿﻴﺤﺎت را دارﻧﺪ ،اﻣﺎ ﻧﻮع ﻣﺸﺨﺺ ﻛﺮدن ﺗﻮﺿﻴﺤﺎت در زﺑﺎﻧﻬﺎي ﻣﺨﺘﻠﻒ ﻣﺘﻔﺎوت اﺳﺖ. اﻣﺎ ﺳﻮال اﻳﻨﺠﺎﺳﺖ ﻛﻪ ﺷﻤﺎ ﭼﻪ ﻣﻮﻗﻊ ﺑﻪ ﻧﻮﺷﺘﻦ ﺗﻮﺿﻴﺤﺎت ﻧﻴﺎز دارﻳﺪ؟ﺧﻮب ،اﻳﻦ ﻣﻮرد ﺑﺮ ﺣﺴﺐ ﻣﻮﻗﻌﻴﺘﻬﺎي ﻣﺨﺘﻠﻒ ﻓﺮق ﻣﻲ ﻛﻨﺪ ،اﻣﺎ ﺑﻪ ﻋﻨﻮان ﻳﻚ ﻗﺎﻧﻮن ﻛﻠﻲ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ ﻛﻪ ﺑﻬﺘﺮ اﺳﺖ ﺑﻪ اﻟﮕﻮرﻳﺘﻢ ﺧﻮدﺗﺎن دﻗﺖ ﻛﻨﻴﺪ .ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در "اﻣﺘﺤﺎن ﻛﻨﻴﺪ" ﻗﺴﻤﺖ ﻗﺒـﻞ ﻧﻮﺷﺘﻴﻢ داراي اﻟﮕﻮرﻳﺘﻢ زﻳﺮ ﺑﻮد: (1ﻳﻚ ﻣﻘﺪار را ﺑﺮاي intNumberﺗﻌﺮﻳﻒ ﻛﻦ. (2ﻣﻘﺪار 1را ﺑﻪ intNumberاﺿﺎﻓﻪ ﻛﻦ. (3ﻣﻘﺪار ﺟﺪﻳﺪ intNumberرا ﺑﻪ ﻛﺎرﺑﺮ ﻧﺸﺎن ﺑﺪه. ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﻮﺿﻴﺤﺎﺗﻲ را ﺑﻪ ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ ﺑﺎ ﻗﺴﻤﺘﻬﺎي اﻟﮕﻮرﻳﺘﻢ ﻫﻤﺎﻫﻨﮓ ﺷﻮد: // Define a variable for intNumber ;int intNumber // Set the initial value ;intNumber = 27 // Add 1 to the value of intNumber ;intNumber = intNumber + 1 // Display the new value of intNumber (MessageBox.Show "Value of intNumber + 1 = " + intNumber, ;)""Variables
٦٠
در وﻳﮋوال 2005 C#ﺗﻮﺿﻴﺤﺎت ﺧﻮد را ﺑﺎ دو ﻛﺎراﻛﺘﺮ اﺳﻠﺶ ) (//ﺷﺮوع ﻣﻲ ﻛﻨﻴﺪ .ﻫﺮ ﻣﺘﻨﻲ ﻛﻪ ﺑﻌﺪ از اﻳﻦ دو ﻛﺎراﻛﺘﺮ ﺗﺎ اﻧﺘﻬـﺎي آن ﺧﻂ ،ﻗﺮار ﺑﮕﻴﺮد ﺑﻪ ﻋﻨﻮان ﺗﻮﺿﻴﺢ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺧﻮاﻫﺪ ﺷﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ،ﺣﺘﻲ اﮔﺮ در ﻳﻚ ﺧﻂ ﻛﺪي وﺟﻮد داﺷـﺘﻪ ﺑﺎﺷـﺪ و ﺷـﻤﺎ در اواﺳـﻂ ﺧﻂ از //اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﻣﺘﻦ ﺑﻌﺪ از آن ﺑﻪ ﻋﻨﻮان ﺗﻮﺿﻴﺢ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻴﺸﻮد .ﻣﺎﻧﻨﺪ: intNumber = intNumber + 1; // Add 1 to value of intNumber اﻳﻦ ﻣﻮرد ﻣﻨﻄﻘﻲ ﻫﻢ ﻫﺴﺖ ،زﻳﺮا ﻓﻘﻂ ﺗﻮﺿﻴﺤﺎت ﺑﻌﺪ از ﻋﻼﻣﺖ //ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﺗﻮﺿﻴﺤﺎت ﻛﺪ ﻗﺒﻠﻲ ،ﻛـﻢ و ﺑـﻴﺶ ﻣﺸﺎﺑﻪ اﻟﮕﻮرﻳﺘﻢ ﺑﺮﻧﺎﻣﻪ ﻫﺴﺘﻨﺪ .ﻳﻚ ﺗﻜﻨﻴﻚ ﺧﻮب ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﺗﻮﺿﻴﺢ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﻳﻦ اﺳﺖ ﻛﻪ آن ﻗﺴﻤﺖ از اﻟﮕﻮرﻳﺘﻢ ﺑﺮﻧﺎﻣﻪ ﻛﻪ در ﺣﺎل ﻧﻮﺷﺘﻦ ﻛﺪ آن ﻫﺴﺘﻴﺪ را در ﭼﻨﺪ ﻛﻠﻤﻪ ﺗﻮﺿﻴﺢ دﻫﻴﺪ. اﮔﺮ در ﻗﺴﻤﺘﻲ از ﺑﺮﻧﺎﻣﻪ ﻧﻴﺎز داﺷﺘﻴﺪ ﻛﻪ از ﺑﻴﺶ از ﻳﻚ ﺧﻂ ﺗﻮﺿﻴﺢ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺟﺎي اﻳﻨﻜﻪ در اﺑﺘـﺪاي ﻫـﺮ ﺧـﻂ از // اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،در ﺟﺎﻳﻲ ﻛﻪ ﺗﻮﺿﻴﺤﺎت ﺷﺮوع ﻣﻲ ﺷﻮﻧﺪ از ﻋﻼﻣﺖ * /اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ وﻳﮋوال C#ﺗﻤﺎم ﻣـﺘﻦ ﺑﻌـﺪ از اﻳـﻦ ﻋﻼﻣﺖ را ﺗﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﻪ ﻋﻼﻣﺖ */ﺑﺮﺳﺪ ﺑﻪ ﻋﻨﻮان ﺗﻮﺿﻴﺢ در ﻧﻈﺮ ﻣﻲ ﮔﻴﺮد .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﺴﺘﻴﻢ ﺗﻤﺎم ﺗﻮﺿﻴﺤﺎت ﻧﻮﺷﺘﻪ ﺷﺪه در ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ را در ﻳﻚ ﻗﺴﻤﺖ ﺑﻪ ﺻﻮرت زﻳﺮ وارد ﻛﻨﻴﻢ: /* 1) Define a variable for intNumber 2) Set the initial value 3) Add 1 to the value of intNumber 4) Display the new value of intNumber */ ;int intNumber ﻳﻜﻲ دﻳﮕﺮ از روﺷﻬﺎي ﺗﻮﻟﻴـﺪ ﺑﻼﻛﻬـﺎي ﺗﻮﺿـﻴﺤﺎت ﺑـﺮاي ﻣﺘـﺪﻫﺎي ﺑﺮﻧﺎﻣـﻪ ،اﺳـﺘﻔﺎده از وﻳﮋﮔـﻲ دروﻧـﻲ XML Document Commentدر وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005اﺳﺖ .ﺑﺮاي اﺳﺘﻔﺎده از اﻳﻦ وﻳﮋﮔﻲ ،ﻣﻜﺎن ﻧﻤﺎ را در ﺧﻂ ﺧﺎﻟﻲ ﺑﺎﻻي ﻣﺘﺪ ﻣـﻮرد ﻧﻈﺮﺗـﺎن ﻗـﺮار دﻫﻴﺪ و ﺳﻪ ﻛﺎراﻛﺘﺮ اﺳﻠﺶ ) (///ﺗﺎﻳﭗ ﻛﻨﻴﺪ .ﻳﻚ ﺑﻼك ﺗﻮﺿﻴﺤﺎت ،ﻫﻤﺎﻧﻨﺪ ﻛﺪ زﻳﺮ ،ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﻧﻤﺎﻳﺶ داده ﻣﻴﺸﻮد. >/// <summary /// >/// /// <param name="sender">/// <param name="e"> <paramاز اﻳـﻦ ﺑﻼك ﺗﻮﺿﻴﺤﺎت ﺣﺬف ﻣﻲ ﺷﻮد. ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻳﻦ ﺑﻼك ﺗﻮﺿﻴﺤﺎت را اﻳﺠﺎد ﻛﺮدﻳﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﺧﻼﺻﻪ از ﻋﻤﻠﻜﺮد ﻣﺘﺪ را در ﻗﺴﻤﺖ summaryوارد ﻛﻨﻴـﺪ و ﻳـﺎ ﻫﺮ ﺗﻮﺿﻴﺢ اﺿﺎﻓﻲ ﻛﻪ ﻗﺒﻞ از ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ﺑﺎﻳﺪ در ﻧﻈﺮ داﺷﺖ را ﻧﻴﺰ در اﻳﻦ ﺑﻼك ﺑﻨﻮﻳﺴﻴﺪ .اﮔﺮ ﻣﺘﺪ ﺷـﻤﺎ ﻣﻘـﺪاري را ﺑﺮﮔﺮداﻧـﺪ ﺑﺨـﺶ >
٦١
ﻧﻜﺎﺗﻲ راﺟﻊ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺷﺎره ﻣﻴﻜﻨﻨﺪ ﻛﻪ در ﻧﮕﺎه اول ﺑﻪ ﻛﺪ ﻣﺸﺨﺺ ﻧﻴﺴﺘﻨﺪ و ﻳﺎ در ﻣﻮرد ﻋﻤﻠﻜﺮد ﻛﺪ ﺧﻼﺻﻪ اي را ﺑﻴـﺎن ﻣـﻲ ﻛﻨﻨـﺪ ﺗـﺎ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﺑﺘﻮاﻧﺪ ﺑﺪون دﻧﺒﺎل ﻛﺮدن ﺧﻂ ﺑﻪ ﺧﻂ ﻛﺪ از ﻋﻤﻠﻜﺮد آن ﻗﺴﻤﺖ ﻣﻄﻠﻊ ﺷﻮد. ﺑﻪ زودي ﻣﺘﻮﺟﻪ ﺧﻮاﻫﻴﺪ ﺷﺪ ﻛﻪ ﻫﺮ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ روﺷﻬﺎي ﺧﺎص ﺧﻮدش را ﺑﺮاي ﺗﻮﺿﻴﺢ ﻧﻮﺷﺘﻦ دارد .اﮔﺮ ﺷﻤﺎ ﺑﺮاي ﻳﻚ ﺷﺮﻛﺖ ﺑﺰرگ ﻛﺎر ﻣﻲ ﻛﻨﻴﺪ ،ﻳﺎ ﻣﺪﻳﺮ ﺷﻤﺎ ﺑﺮ ﻛﺪ ﻧﻮﻳﺴﻲ اﺳﺘﺎﻧﺪارد ﺗﺎﻛﻴﺪ داﺷﺘﻪ ﺑﺎﺷﺪ ،ﺑﻪ ﺷﻤﺎ ﮔﻔﺘﻪ ﻣﻴﺸﻮد ﻛﻪ ﺗﻮﺿﻴﺤﺎت ﺧﻮد را در ﭼﻪ ﻗﺎﻟﺒﻬﺎﻳﻲ ﺑﻨﻮﻳﺴﻴﺪ و ﻳﺎ اﻳﻨﻜﻪ در ﻛﺪام ﻗﺴﻤﺖ از ﻛﺪ ﺗﻮﺿﻴﺢ ﺑﻨﻮﻳﺴﻴﺪ و در ﻛﺪام ﻗﺴﻤﺖ ﻧﻨﻮﻳﺴﻴﺪ.
ﻓﻀﺎﻫﺎي ﺧﺎﻟﻲ: ﻳﻜﻲ دﻳﮕﺮ از ﻣﻮاردي ﻛﻪ ﻣﻮﺟﺐ ﺧﻮاﻧﺎﻳﻲ ﺑﻴﺸﺘﺮ ﻛﺪ ﻣﻴﺸﻮد اﺳﺘﻔﺎده زﻳﺎد از ﻓﻀﺎﻫﺎي ﺧﺎﻟﻲ ﺑﻴﻦ ﻛﺪﻫﺎ اﺳـﺖ .ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ ﻓـﻀﺎي ﺑـﻴﻦ ﻛﻠﻤﺎت در اﻧﮕﻠﻴﺴﻲ ﻣﻮﺟﺐ ﺑﻬﺘﺮ ﺧﻮاﻧﺪه ﺷﺪن ﻣﺘﻦ ﻣﻲ ﺷﻮد ،ﻓﻀﺎﻫﺎي ﺧﺎﻟﻲ در ﺑﺮﻧﺎﻣﻪ )ﻓﻀﺎ ﻫﺎﻳﻲ ﺑﺮ روي ﺻﻔﺤﻪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻛـﺎراﻛﺘﺮ ﻫﺎ اﺷﻐﺎل ﻧﻤﻲ ﺷﻮﻧﺪ( ﻣﻮﺟﺐ ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﻛﺪﻫﺎ راﺣﺖ ﺗﺮ ﺧﻮاﻧﺪه ﺷﻮﻧﺪ .ﻣﺜﻼ اﮔﺮ در ﻣﺜﺎل ﻗﺒﻠﻲ در ﻫﺮ ﺧﻂ ،ﻗﺒـﻞ از ﺗﻮﺿـﻴﺤﺎت از ﻳـﻚ ﺧﻂ ﺧﺎﻟﻲ اﺳﺘﻔﺎده ﻛﻨﻴﻢ ،ﻣﻮﺟﺐ ﻣﻲ ﺷﻮد ﻛﺴﻲ ﻛﻪ ﻛﺪ را ﻣﻲ ﺧﻮاﻧﺪ ﻣﺘﻮﺟﻪ ﺷﻮد ﻛﻪ ﻫﺮ ﻛﺪام از اﻳﻦ ﺑﺨﺸﻬﺎ ﻳﻚ ﻛﺎر ﺧﺎص را اﻧﺠﺎم ﻣـﻲ دﻫﻨﺪ. در ﻓﺼﻞ ﺑﻌﺪي ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﻢ ﻛﻨﺘﺮل اﺟﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ وﺳﻴﻠﻪ ﺑﻼﻛﻬﺎي ﺗﻜﺮار ) (forو ﻳﺎ ﺗﺼﻤﻴﻢ ﮔﻴﺮي ) (ifﺗﻮﺿـﻴﺢ ﺑﺪﻫﻴﻢ ،ﺑﺎ دﻟﻴﻞ اﺳﺘﻔﺎده از ﻓﻀﺎﻫﺎي ﺧﺎﻟﻲ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ .ﻫﻤﻴﻦ ﻃﻮر ﻣﺘﻮﺟﻪ ﻣﻲ ﺷﻮﻳﺪ ﻛﻪ ﻣﻘﺪار و ﭼﮕﻮﻧﮕﻲ اﺳﺘﻔﺎده از ﻓﻀﺎﻫﺎي ﺧﺎﻟﻲ در ﺑﺮﻧﺎﻣﻪ ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﻣﺘﻔﺎوت اﺳﺖ .ﻓﻌﻼ از زﻳﺎد ﻓﺎﺻﻠﻪ ﻗﺮار دادن ﺑﻴﻦ ﻛﺪﻫﺎ ﻧﺘﺮﺳﻴﺪ ،اﻳﻦ ﻣﻮرد ﺧﻮاﻧﺎﻳﻲ ﻛﺪ ﺷﻤﺎ را ﺑﻪ ﻣﻘﺪار زﻳﺎدي اﻓﺰاﻳﺶ ﻣﻲ دﻫﺪ ،ﻣﺨﺼﻮﺻﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺣﺠﻢ زﻳﺎدي از ﻛﺪ را در ﺑﺮﻧﺎﻣﻪ ﺑﻨﻮﻳﺴﻴﺪ. ﻧﻜﺘﻪ :ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎ ،ﻓﻀﺎﻫﺎي ﺧﺎﻟﻲ ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ و ﻫﻤﭽﻨﻴﻦ ﺗﻮﺿﻴﺤﺎت ﺑﺮﻧﺎﻣﻪ را ﻧﺎدﻳﺪه ﻣﻴﮕﻴﺮﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻴﻦ اﺟﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﻓـﻀﺎي ﺧﺎﻟﻲ و ﺗﻮﺿﻴﺤﺎت زﻳﺎد و ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺪون اﻳﻦ ﻣﻮارد ،از ﻟﺤﺎظ ﺳﺮﻋﺖ و ﻛﺎراﻳﻲ ﻫﻴﭻ ﺗﻔﺎوﺗﻲ ﻧﻴﺴﺖ.
ﻧﻮع ﻫﺎي داده اي: ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﻴﺨﻮاﻫﻴﺪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ را ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﺑﺪاﻧﻴﺪ ﺗﻘﺮﻳﺒﺎ ﭼﻪ ﻧﻮع اﻃﻼﻋﺎﺗﻲ را ﻣﻴﺨﻮاﻫﻴﺪ در آن ذﺧﻴﺮه ﻛﻨﻴﺪ .ﺗﺎ اﻳﻨﺠﺎ در ﻣﺜﺎل ﻗﺒﻞ ،ﻣﺘﻐﻴﻴﺮي را دﻳﺪﻳﺪ ﻛﻪ ﻣﻘﺎدﻳﺮ ﺻﺤﻴﺢ را در ﺧﻮد ﻧﮕﻪ ﻣﻴﺪاﺷﺖ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﻴﺨﻮاﻫﻴﺪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ را در وﻳﮋوال 2005 C#ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ ﺑﻪ آن ﺑﮕﻮﻳﻴﺪ ﻛﻪ ﭼﻪ ﻧﻮع اﻃﻼﻋـﺎﺗﻲ را ﻣﻴﺨﻮاﻫﻴـﺪ در آن ذﺧﻴﺮه ﻛﻨﻴﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﺣﺪس زده اﻳﺪ ،اﻳﻦ ﻣﻮارد ﺑﻪ ﻋﻨﻮان ﻧﻮع ﻫﺎي داده اي ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮﻧﺪ و ﺗﻤﺎم زﺑﺎﻧﻬﺎي ﻣﻬـﻢ ،ﺗﻌـﺪاد زﻳـﺎدي ﻧﻮع داده اي دارﻧﺪ ﻛﻪ ﺷﻤﺎ ﻣﻴﺘﻮاﻧﻴﺪ ﻧﻮع اﻃﻼﻋﺎت داﺧﻞ ﻣﺘﻐﻴﻴﺮ ﺧﻮد را از ﺑﻴﻦ آﻧﻬﺎ اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﻧﻮع داده اي ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺗﺎﺛﻴﺮ زﻳﺎدي ﺑـﺮ اﻳﻦ ﻛﻪ ﭼﮕﻮﻧﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ را اﺟﺮا ﻛﻨﺪ دارد .در اﻳﻦ ﺑﺨﺶ ﻧﮕﺎه دﻗﻴﻘﺘﺮي ﺑﺮ ﭼﮕﻮﻧﮕﻲ ﻛﺎر ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﺧﻮاﻫﻴﻢ داﺷـﺖ .ﻫﻤﭽﻨـﻴﻦ ﭼﮕﻮﻧﮕﻲ ﺗﺎﺛﻴﺮ ﻧﻮع ﻳﻚ ﻣﺘﻐﻴﻴﺮ را در ﻛﺎراﻳﻲ ﺑﺮﻧﺎﻣﻪ ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد.
ﻛﺎرﻛﺮدن ﺑﺎ اﻋﺪاد:
٦٢
زﻣﺎﻧﻲ ﻛﻪ ﺷﻤﺎ ﺑﺎ اﻋﺪاد در وﻳﮋوال 2005 C#ﻛﺎر ﻣﻲ ﻛﻨﻴﺪ ،ﻣﻴﺘﻮاﻧﻴﺪ دو ﻧﻮع ﻋﺪد داﺷﺘﻪ ﺑﺎﺷﻴﺪ :اﻋﺪاد ﺻﺤﻴﺢ و اﻋﺪاد اﻋﺸﺎري .ﻫﺮ ﻛﺪام از اﻳﻦ اﻋﺪاد ﻛﺎرﺑﺮد ﺧﺎص ﺧﻮدﺷﺎن را دارﻧﺪ .ﻣﺜﻼ اﻋﺪاد ﺻﺤﻴﺢ ﺗﻮاﻧﺎﻳﻲ ﻧﮕﻬﺪاري ﺑﺨﺶ اﻋﺸﺎري را ﻧﺪارﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي ﻣﺤﺎﺳﺒﺎﺗﻲ ﻛـﻪ ﻣﻤﻜﻦ اﺳﺖ ﻧﺘﻴﺠﻪ ﺷﺎﻣﻞ اﻋﺸﺎر ﻫﻢ ﺑﺎﺷﺪ ﻧﺒﺎﻳﺪ از ﻣﺘﻐﻴﻴﺮ ﻫﺎي ﺻﺤﻴﺢ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. در ﻧﻮﺷﺘﻦ ﻧﺮم اﻓﺰارﻫﺎ ،ﺑﻴﺸﺘﺮ از اﻋﺪاد ﺻﺤﻴﺢ ﺑﺮاي ﺷﻤﺮدن ﻣﺮاﺗﺒﻲ ﻛﻪ ﻳﻚ اﺗﻔﺎق رخ ﻣﻴﺪﻫﺪ اﺳﺘﻔﺎده ﻣﻴﺸﻮد ﺗﺎ ﺑـﺮاي اﻧﺠـﺎم ﻣﺤﺎﺳـﺒﺎت. ﺑﺮاي ﻣﺤﺎﺳﺒﺎت ﺑﻴﺸﺘﺮ از اﻋﺪاد اﻋﺸﺎري اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ. ﻣﺜﻼ ،ﻓﺮض ﻛﻨﻴﺪ در ﺣﺎل ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ اي ﻫﺴﺘﻴﺪ ﻛﻪ اﻃﻼﻋﺎت ﻣﺸﺘﺮﻛﻴﻦ را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﺪ .ﻫﻤﭽﻨﻴﻦ ﻓﺮض ﻣﻴﻜﻨﻴﻢ ﻛـﻪ ﺷـﻤﺎ اﻃﻼﻋﺎت 100ﻣﺸﺘﺮك را در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺧﻮد دارﻳﺪ .زﻣﺎﻧﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺷﺮوع ﺑـﻪ ﻛـﺎر ﻛـﺮد ،اﻃﻼﻋـﺎت ﻣـﺸﺘﺮك اول را در ﺻـﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﺪ .در اﻳﻨﺠﺎ ﺷﻤﺎ ﺑﺎﻳﺪ ﺑﺪاﻧﻴﺪ ﻛﻪ اﻃﻼﻋﺎت ﻛﺪام ﻣﺸﺘﺮك در ﺻﻔﺤﻪ ﭼﺎپ ﺷﺪه ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻛﺎرﺑﺮ درﺧﻮاﺳﺖ ﻛﺮد اﻃﻼﻋﺎت ﻣﺸﺘﺮك ﺑﻌﺪي را ﻣﺸﺎﻫﺪه ﻛﻨﺪ ،ﺑﺪاﻧﻴﺪ ﻛﺪام اﻃﻼﻋﺎت را ﺑﺎﻳﺪ ﻧﻤﺎﻳﺶ دﻫﻴﺪ. ﻣﻌﻤﻮﻻ اﮔﺮ ﻫﺮ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را ﻛﻪ ﺣﺎوي اﻃﻼﻋﺎت ﻣﺸﺘﺮﻛﻴﻦ ﺑﺎﺷﻨﺪ ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ ،ﺧﻮاﻫﻴﺪ دﻳﺪ ﻛـﻪ در آن ﻫـﺮ ﻣـﺸﺘﺮك داراي ﻳـﻚ ﺷﻤﺎره ﻣﺨﺼﻮص ﺑﻪ ﺧﻮد اﺳﺖ .اﻳﻦ ﺑﻪ اﻳﻦ ﺧﺎﻃﺮ اﺳﺖ ﻛﻪ ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎ راﺣﺖ ﺗﺮ ﻣﻴﺘﻮاﻧﻨﺪ ﺑﺎ اﻋﺪاد ﻛﺎر ﻛﻨﻨﺪ ﺗـﺎ ﺑـﺎ اﺳـﺎﻣﻲ .ﻣﻌﻤـﻮﻻ اﻳـﻦ ﺷﻤﺎره ﻫﺎي ﻣﺨﺼﻮص ﻛﻪ ﺑﻪ ﻣﺸﺘﺮﻛﻴﻦ داده ﻣﻴﺸﻮد ،ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ اﺳﺖ ﻛﻪ ﺑﻪ آن ﺷﻨﺎﺳﻪ 1ﻳﺎ IDﮔﻔﺘﻪ ﻣﻴـﺸﻮد .ﺑﻨـﺎﺑﺮاﻳﻦ در ﻣﺜـﺎل ﻗﺒﻠﻲ ﻫﻢ ﻛﻪ ﻣﺎ ﻟﻴﺴﺘﻲ از 100ﻣﺸﺘﺮك را در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺧﻮد داﺷﺘﻴﻢ ،ﻫﺮ ﻣﺸﺘﺮك داراي ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ ﻣﺨﺼﻮص ﺑﻪ ﺧـﻮد از 1 ﺗﺎ 100اﺳﺖ .ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺑﺮاي ﭼﺎپ اﻃﻼﻋﺎت ﻣﺸﺘﺮﻛﻴﻦ ،ﻣﻴﺘﻮاﻧﺪ ﺷﻤﺎره آﺧﺮﻳﻦ ﻣﺸﺘﺮﻛﻲ ﻛﻪ اﻃﻼﻋﺎت او ﭼـﺎپ ﺷـﺪه اﺳـﺖ را در ﻳـﻚ ﻣﺘﻐﻴﻴﺮ ﻧﮕﻪ دارد .زﻣﺎﻧﻲ ﻛﻪ ﻛﺎرﺑﺮ درﺧﻮاﺳﺖ ﻛﺮد ﺗﺎ اﻃﻼﻋﺎت ﻣﺸﺘﺮك ﺑﻌﺪي را ﺑﺒﻴﻨﺪ ،ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﺷﻤﺎ ﻳﻚ واﺣﺪ ﺑـﻪ ﺷﻨﺎﺳـﻪ آﺧـﺮﻳﻦ ﻛﺎرﺑﺮي ﻛﻪ اﻃﻼﻋﺎت او ﭼﺎپ ﺷﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ و اﻃﻼﻋﺎت ﻣﺸﺘﺮك ﺟﺪﻳﺪ را ﭼﺎپ ﻛﻨﻴﺪ. اﻳﻦ ﮔﻮﻧﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎ را زﻣﺎﻧﻲ ﻛﻪ در ﻣﻮرد ﻣﺒﺎﺣﺚ ﭘﻴﺸﺮﻓﺘﻪ ﺗﺮي ﻣﺜﻞ ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ ﺻﺤﺒﺖ ﻛﺮدﻳﻢ ،ﺗﻤﺮﻳﻦ ﺧﻮاﻫﻴﻢ ﻛـﺮد .اﻣـﺎ ﻓﻌـﻼً ﺑﺪاﻧﻴﺪ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻌﻤﻮﻻ از اﻋﺪاد ﺻﺤﻴﺢ ﺑﻴﺸﺘﺮ از اﻋﺪاد اﻋﺸﺎري اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد.
ﻋﻤﻠﻴﺎت رﻳﺎﺿﻲ ﻣﻌﻤﻮل روي اﻋﺪاد ﺻﺤﻴﺢ: در اﻳﻦ ﻗﺴﻤﺖ ﺷﻤﺎ ﭘﺮوژه ﺟﺪﻳﺪي ﺑﺮاي اﻧﺠﺎم ﻋﻤﻠﻴﺎت رﻳﺎﺿﻲ ﺧﻮاﻫﻴﺪ ﻧﻮﺷﺖ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻛﺎر ﺑﺎ اﻋﺪاد ﺻﺤﻴﺢ (1ﺑﺎ اﻧﺘﺨﺎب ﻣﻨﻮي File New Projectﻳﻚ ﭘﺮوژه ﺟﺪﻳﺪ در وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005اﻳﺠﺎد ﻛﻨﻴﺪ .در ﭘﻨﺠﺮه New Projectﮔﺰﻳﻨﻪ Windows Applicationرا از ﻗﺴﻤﺖ ﺳﻤﺖ راﺳﺖ اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ )ﺑﻪ ﻋﻜﺲ 1-3رﺟﻮع ﻛﻨﻴﺪ( .ﻧﺎم ﭘﺮوژه را IntegerMathوارد ﻛﻨﻴﺪ و روي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ. (2ﻗﺒﻞ از ﻫﺮ ﭼﻴﺰ ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ،ﻳﻚ ﻛﻨﺘﺮل Buttonﺑﻪ ﻓـﺮم ﺧـﻮد اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ .ﺧﺎﺻـﻴﺖ Nameآن را ﺑـﻪ btnIntMathو ﺧﺎﺻﻴﺖ Textآن را ﺑﻪ Math Testﺗﻐﻴﻴﺮ دﻫﻴﺪ .روي ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ و در ﻣﺘﺪ اﻳﺠﺎد ﺷﺪه ﺑﺮاي روﻳﺪاد Clickﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺗﺎﻳﭗ ﻛﻨﻴﺪ: )private void btnIntMath_Click(object sender, EventArgs e { // Declare variable Identifier
1
٦٣
int intNumber; // Set number, add numbers, and display results intNumber = 16; intNumber = intNumber + 8; MessageBox.Show("Addition test... " + intNumber, "Integer Math"); // Set number, subtract numbers, and display results intNumber = 24; intNumber = intNumber - 2; MessageBox.Show("Subtraction test... " + intNumber, "Integer Math"); // Set number, multiply numbers, and display results intNumber = 6; intNumber = intNumber * 10; MessageBox.Show("Multiplication test... " + intNumber,"Integer Math"); // Set number, divide numbers, and display results intNumber = 12; intNumber = intNumber / 6; MessageBox.Show("Division test... " + intNumber, "Integer Math"); } ﻧﻤـﺎﻳﺶ داده3-4 ﭼﻬﺎر ﻛﺎدر ﭘﻴﻐﺎم ﻣﺘﻮاﻟﻲ ﻫﻤﺎﻧﻨﺪ ﺷـﻜﻞ. ﻛﻠﻴﻚ ﻛﻨﻴﺪMath Test ( ﭘﺮوژه را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ3 . در ﻫﺮ ﻛﺪام ﻛﻠﻴﻚ ﻛﻨﻴﺪOK ﻣﻴﺸﻮﻧﺪ و ﺷﻤﺎ ﺑﺎﻳﺪ روي
4-3 ﺷﻜﻞ
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻴﻜﻨﺪ؟ در، ﺷﻤﺎ ﻗﺒﻼ ﻛـﺎرﺑﺮد ﻋﻤﻠﮕـﺮ ﺟﻤـﻊ را دﻳـﺪه اﻳـﺪ. ﺧﻴﻠﻲ ﮔﻴﺞ ﻛﻨﻨﺪه ﻧﻴﺴﺘﻨﺪ، ﻫﻴﭻ ﻛﺪام از ﻛﺪﻫﺎﻳﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﺑﺎﻻ ﻧﻮﺷﺘﻴﺪ،ﺧﻮﺷﺒﺨﺘﺎﻧﻪ .اﻳﻨﺠﺎ ﻫﻢ از آن دوﺑﺎره اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ
٦٤
// Set number, add numbers, and display results ;intNumber = 16 ;intNumber = intNumber + 8 MessageBox.Show("Addition test... " + intNumber, ;)""Integer Math ﭼﻴﺰي ﻛﻪ در اﻳﻦ ﻛﺪ ﺷﻤﺎ ﺑﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻣﻴﮕﻮﻳﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ: (1ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ intNumberرا ﺑﺮاﺑﺮ 16ﻗﺮار ﺑﺪه. (2ﺳﭙﺲ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ intNumberرا ﺑﺮاﺑﺮ ﻣﻘﺪار ﻛﻨﻮﻧﻲ اﻳﻦ ﻣﺘﻐﻴﻴﺮ )ﻋﺪد (16ﺑﻪ اﺿﺎﻓﻪ 8ﻗﺮار ﺑﺪه. ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻛﺎدر ﭘﻴﻐﺎم ﺷﻜﻞ 3-4ﻣﻲ ﺑﻴﻨﻴﺪ ،ﻣﻘﺪار 24ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ ﻛﻪ درﺳﺖ اﺳﺖ. ﻋﻤﻠﮕﺮ ﺗﻔﺮﻳﻖ در اﻳﻨﺠﺎ ﻋﻼﻣﺖ ) (-اﺳﺖ ﻛﻪ ﻋﻤﻠﻜﺮد آن را در ﻛﺪ زﻳﺮ ﻣﻲ ﺑﻴﻨﻴﺪ: // Set number, subtract numbers, and display results ;intNumber = 24 ;intNumber = intNumber - 2 MessageBox.Show("Subtraction test... " + intNumber, ;)""Integer Math دوﺑﺎره ،ﻫﻤﺎﻧﻨﺪ ﻗﺴﻤﺖ ﺟﻤﻊ ﺑﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻣﻲ ﮔﻮﻳﻴﺪ ﻛﻪ: (1ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ intNumberرا ﺑﺮاﺑﺮ 24ﻗﺮار ﺑﺪه. (2ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ intNumberرا ﺑﺮاﺑﺮ ﻣﻘﺪار ﻛﻨﻮﻧﻲ اﻳﻦ ﻣﺘﻐﻴﻴﺮ ) (24ﻣﻨﻬﺎي 2ﻗﺮار ﺑﺪه. ﻋﻤﻠﮕﺮ ﺿﺮب ،ﻋﻼﻣﺖ ﺳﺘﺎره اﺳﺖ )*( ﻛﻪ ﻛﺎرﺑﺮد آن در ﻛﺪ زﻳﺮ ﻣﺸﺨﺺ اﺳﺖ: // Set number, multiply numbers, and display results ;intNumber = 6 ;intNumber = intNumber * 10 MessageBox.Show("Multiplication test... " + ;)"intNumber,"Integer Math اﻟﮕﻮرﻳﺘﻢ اﻳﻦ ﻛﺪ ﺑﻪ ﺻﻮرت زﻳﺮ اﺳﺖ: (1ﻣﻘﺪار intNumberرا ﺑﺮاﺑﺮ 6ﻗﺮار ﺑﺪه. (2ﻣﻘﺪار intNumberرا ﺑﺮاﺑﺮ ﻣﻘﺪار ﻛﻨﻮﻧﻲ اﻳﻦ ﻣﺘﻐﻴﻴﺮ ) (6ﺿﺮب در 10ﻗﺮار ﺑﺪه. در آﺧﺮ ،ﻋﻤﻠﮕﺮ ﺗﻘﺴﻴﻢ ﻳﻚ ﻋﻼﻣﺖ /اﺳﺖ ﻛﻪ در زﻳﺮ ﻧﺸﺎن داده ﺷﺪه اﺳﺖ: // Set number, divide numbers, and display results ٦٥
intNumber = 12; intNumber = intNumber / 6; MessageBox.Show("Division test... " + intNumber, "Integer Math"); :و اﻟﮕﻮرﻳﺘﻢ آن ﻣﻄﺎﺑﻖ زﻳﺮ اﺳﺖ . ﻗﺮار ﺑﺪه12 را ﺑﺮاﺑﺮintNumber ( ﻣﻘﺪار1 . ﻗﺮار ﺑﺪه6 ( ﺗﻘﺴﻴﻢ ﺑﺮ12 را ﺑﺮاﺑﺮ ﻣﻘﺪار ﻛﻨﻮﻧﻲ اﻳﻦ ﻣﺘﻐﻴﻴﺮ )ﻳﻌﻨﻲintNumber ( ﻣﻘﺪار2
:ﺗﻨﺪ ﻧﻮﻳﺴﻲ در ﻋﻤﻠﻴﺎت رﻳﺎﺿﻲ اﻟﺒﺘﻪ ﻣﺴﻠﻤﺎ در اﺑﺘﺪا اﻳﻦ ﻧﻮع ﻧﻮﺷـﺘﻦ. ﺷﻤﺎ ﻛﺪﻫﺎي ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ را ﺑﻪ ﻧﺤﻮي ﺑﺴﻴﺎر ﻛﻮﺗﺎﻫﺘﺮ ﺧﻮاﻫﻴﺪ ﻧﻮﺷﺖ،در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي . از آﻧﻬﺎ ﺑﻴﺸﺘﺮ اﺳﺘﻔﺎده ﺧﻮاﻫﻴﺪ ﻛﺮد، ﺑﻌﺪ از ﻣﻘﺪاري ﻛﺎر، اﻣﺎ ﺑﻪ زودي،ﻧﺴﺒﺖ ﺑﻪ ﻧﻮع ﻃﻮﻻﻧﻲ آﻧﻬﺎ ﻏﻴﺮ ﻣﻨﻄﻘﻲ ﺑﻪ ﻧﻈﺮ ﻣﻲ رﺳﺪ
اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ ﻫﺎي ﻣﺨﺘﺼﺮ ﺷﺪه:اﻣﺘﺤﺎن ﻛﻨﻴﺪ : ﺧﻄﻬﺎي ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ. را ﻣﺠﺪدا ﺑﺎز ﻛﻨﻴﺪForm1.cs ﺑﺮوﻳﺪ و ﻓﺎﻳﻞ2005 ( ﺑﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ1 private void btnIntMath_Click(object sender, EventArgs e) { // Declare variable int intNumber; // Set number, add numbers, and display results intNumber = 16; intNumber += 8; MessageBox.Show("Addition test... " + intNumber, "Integer Math"); // Set number, subtract numbers, and display results intNumber = 24; intNumber -= 2; MessageBox.Show("Subtraction test... " + intNumber, "Integer Math"); // Set number, multiply numbers, and display results intNumber = 6; intNumber *= 10; MessageBox.Show("Multiplication test... " + intNumber,"Integer Math"); // Set number, divide numbers, and display results intNumber = 12; intNumber /= 6;
٦٦
MessageBox.Show("Division test... " + intNumber, ;)""Integer Math } (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ Math Testﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻧﺘﻴﺠـﻪ اي ﻣـﺸﺎﺑﻪ ﺑﺮﻧﺎﻣـﻪ ﻗﺒﻠـﻲ را درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﻴﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺮاي اﺳﺘﻔﺎده از ﺣﺎﻟﺖ ﻣﺨﺘﺼﺮ ﺷﺪه ﻋﻤﻠﮕﺮ ﻫﺎ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﻧﺎم ﻣﺘﻐﻴﻴﺮ را ﻛﻪ ﺑﺮاي ﺑﺎر دوم ﺗﻜﺮار ﺷـﺪه اﺳـﺖ ﺣـﺬف ﻛﻨﻴـﺪ و ﻋﻼﻣـﺖ رﻳﺎﺿﻲ ﻣﺮﺗﺒﻂ ﺑﺎ آن را ﻧﻴﺰ ﺑﻪ ﻗﺒﻞ از ﻣﺴﺎوي اﻧﺘﻘﺎل دﻫﻴﺪ .ﻣﺜﻼ در ﺣﺎﻟﺖ: ;intNumber = intNumber + 8 ﻋﺒﺎرت ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮد: ;intNumber += 8
ﻣﺤﺪودﻳﺖ ﻛﺎر ﺑﺎ اﻋﺪاد ﺻﺤﻴﺢ: ﻣﺤﺪودﻳﺖ اﺻﻠﻲ ﻛﻪ در ﻛﺎر ﺑﺎ اﻋﺪاد ﺻﺤﻴﺢ وﺟﻮد دارد اﻳﻦ اﺳﺖ ﻛﻪ ﺷﻤﺎ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﻋﺪدي داﺷﺘﻪ ﺑﺎﺷـﻴﺪ ﻛـﻪ داراي ﻗـﺴﻤﺖ اﻋـﺸﺎري ﺑﺎﺷﺪ .ﺑﺮاي ﻣﺜﺎل اﺳﺘﻔﺎده از ﻛﺪ زﻳﺮ ﻣﻮﺟﺐ اﻳﺠﺎد ﺧﻄﺎ در زﻣﺎن ﻛﺎﻣﭙﺎﻳﻞ ﺑﺮﻧﺎﻣﻪ ﻣﻴﺸﻮد: // Try multiplying numbers ;int intNumber = 34 ;intNumber *= 10.234 اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﺎﻻ ﺑﻪ ﻋﻠﺖ ﺧﻄﺎﻳﻲ ﻛﻪ در ﻗﺴﻤﺖ ﻛﺎﻣﭙﺎﻳﻞ ﺑﻪ وﺟﻮد ﻣﻲ آﻳﺪ ﻣﺘﻮﻗﻒ ﻣﻲ ﺷﻮد .زﻳﺮا ﻣﺘﻐﻴﻴﺮ intNumberاز ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ اﺳﺖ و ﺷﻤﺎ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ آن را در ﺣﺎﻟﺖ ﻋﺎدي در ﻳﻚ ﻋﺪد اﻋﺸﺎري ﺿﺮب ﻛﻨﻴﺪ. در ﺗﻘﺴﻴﻢ دو ﻋﺪد ﻫﻢ اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ را ﺑﺮ ﻳﻚ ﻋﺪد اﻋﺸﺎري ﺗﻘﺴﻴﻢ ﻛﻨﻴﺪ ،ﺑﺎ ﺧﻄﺎﻳﻲ ﻣﺸﺎﺑﻪ ﺣﺎﻟﺖ ﺟﻤﻊ روﺑـﺮو ﻣﻴـﺸﻮﻳﺪ. اﻣﺎ ﻛﺪ زﻳﺮ را در ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ: …// Try deviding numbers ;int intNumber = 12 ;intNumber /= 7 در اﻳﻦ ﻛﺪ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ intNumberرا ) (12ﻛﻪ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ اﺳﺖ ﺑﺮ 7ﻛﻪ آن ﻧﻴﺰ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ اﺳﺖ ﺗﻘﺴﻴﻢ ﻛﺮده اﻳﻢ و ﺟﻮاب ﺑﺮاﺑﺮ 1,71اﺳﺖ .در اﻳﻦ ﻣﻮاﻗﻊ ﻛﺎﻣﭙﺎﻳﻠﺮ ﺧﻄﺎﻳﻲ ﺗﻮﻟﻴﺪ ﻧﻤﻴﻜﻨﺪ ،اﻣﺎ ﻣﻘﺪار ﻛﻪ در ﻣﺘﻐﻴﻴﺮ intNumberذﺧﻴـﺮه ﻣﻴـﺸﻮد ﺑـﺎ ﺟﻮاﺑﻲ ﻛﻪ ﺷﻤﺎ اﻧﺘﻈﺎر دارﻳﺪ ﺗﻔﺎوت دارد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ،ﺑﻌﺪ از اﺟﺮاي ﻛﺪ ﺑﺎﻻ ،ﺟﻮاب 1,71در intNumberﻧﺨﻮاﻫﺪ ﺑـﻮد ،ﺑﻠﻜـﻪ
٦٧
ﻗﺴﻤﺖ اﻋﺸﺎر اﻳﻦ ﻋﺪد ﺣﺬف ﻣﻴﺸﻮد و ﻣﻘﺪار 1در ﻣﺘﻐﻴﻴﺮ intNumberﻗﺮار ﻣﻴﮕﻴﺮد .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺗﺼﻮر ﻛﻨﻴـﺪ ،اﮔـﺮ ﺑﺮﻧﺎﻣﻪ اي ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ ﺑﺨﻮاﻫﺪ ﺑﺎ اﻧﻮاع ﻣﺨﺘﻠﻒ داده ﻫﺎ ﻛﺎر ﻛﻨﺪ و از اﻋﺪاد ﺻﺤﻴﺢ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ﺑﺎ ﻣﺸﻜﻞ ﻣﻮاﺟﻪ ﺧﻮاﻫﻴﺪ ﺷﺪ. در ﻗﺴﻤﺖ ﺑﻌﺪي ﺧﻮاﻫﻴﺪ دﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از اﻋﺪاد اﻋﺸﺎري ،از ﺑﺮوز ﻣﺸﻜﻼﺗﻲ ﻣﺎﻧﻨﺪ ﻗﺒﻞ ﺟﻠﻮﮔﻴﺮي ﻛﻨﻴﺪ.
اﻋﺪاد اﻋﺸﺎري: در ﻗﺴﻤﺖ ﻗﺒﻞ ﻣﺘﻮﺟﻪ ﺷﺪﻳﺪ ﻛﻪ اﻋﺪاد ﺻﺤﻴﺢ ﺑﺮاي اﻧﺠﺎم ﻣﺤﺎﺳﺒﺎت رﻳﺎﺿﻲ ﻣﻨﺎﺳﺐ ﻧﻴﺴﺘﻨﺪ .زﻳﺮا ﻧﺘﻴﺠـﻪ ﺑﻴـﺸﺘﺮ اﻳـﻦ ﻣﺤﺎﺳـﺒﺎت داراي ﻗﺴﻤﺖ اﻋﺸﺎري اﺳﺖ و اﻋﺪاد ﺻﺤﻴﺢ ﻫﻢ ﻧﻤﻲ ﺗﻮاﻧﻨﺪ ﻗـﺴﻤﺖ اﻋـﺸﺎري را در ﺧـﻮد ﻧﮕﻬـﺪاري ﻛﻨﻨـﺪ .در اﻳـﻦ ﺑﺨـﺶ ﭼﮕـﻮﻧﮕﻲ اﻧﺠـﺎم ﻣﺤﺎﺳﺒﺎت رﻳﺎﺿﻲ ﺑﺎ اﻋﺪاد اﻋﺸﺎري را در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺨﺘﻠﻒ ﻣﺎﻧﻨﺪ ﻣﺤﺎﺳﺒﻪ ﻣﺴﺎﺣﺖ و ﻣﺤﻴﻂ داﻳﺮه ﺗﻤﺮﻳﻦ ﺧﻮاﻫﻴﻢ ﻛـﺮد ،اﻣـﺎ ﻓﻌـﻼ ،در آزﻣﺎﻳﺶ ﻛﻨﻴﺪ زﻳﺮ ،ﻓﻘﻂ ﻣﻔﺎﻫﻴﻢ ﻛﻠﻲ را ﻣﻌﺮﻓﻲ ﻣﻲ ﻛﻨﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻋﺪاد اﻋﺸﺎري (1ﻳﻚ ﭘﺮوژه ﺟﺪﻳﺪ در وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﺑﻪ ﻧﺎم Floating-Pt Mathاﻳﺠﺎد ﻛﻨﻴﺪ .ﻗﺒـﻞ از ﻫـﺮ ﭼﻴـﺰ ،ﻳـﻚ ﻛﻨﺘﺮل Buttonروي ﻓﺮم ﻗﺮار دﻫﻴﺪ و ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑـﺮ btnFloatMathو ﺧﺎﺻـﻴﺖ Text آن را ﺑﺮاﺑﺮ Double Testﻗﺮار دﻫﻴﺪ. (2روي دﻛﻤﻪ btnFloatMathدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن ﻛﺪي را ﻛﻪ در زﻳﺮ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ وارد ﻛﻨﻴﺪ. Private void btnFloatMath_Click(object sender, )EventArgs e { // Declare variable ;double dblNumber // Set number, multiply numbers, and display results ;dblNumber = 45.34 ;dblNumber *= 4.333 MessageBox.Show("Multiplication test... " + ;)"dblNumber, "Floating Points // Set number, divide numbers, and display results ;dblNumber = 12 ;dblNumber /= 7 MessageBox.Show("Division test... " + dblNumber, ;)""Floating Points } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي ﻛﻠﻴﺪ Double Testﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻧﺘﻴﺠﻪ اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 5-3را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
٦٨
ﺷﻜﻞ 5-3
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺘﻮﺟﻪ ﺷﺪﻳﺪ ﻣﻬﻤﺘﺮﻳﻦ ﺗﻐﻴﻴﺮ در ﺑﺮﻧﺎﻣﻪ ﺑﺎﻻ ،ﺗﻐﻴﻴﺮ ﻧﻮع ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴﺮ اﺳﺖ: // Declare variable ;double dblNumber ﺑﻪ ﺟﺎي اﻳﻨﻜﻪ ﺑﺮاي ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴﺮ از ﻛﻠﻤﻪ ﻛﻠﻴﺪي intاﺳﺘﻔﺎده ﻛﻨﻴﻢ ،از ﻛﻠﻤﻪ doubleاﺳﺘﻔﺎده ﻛﺮده اﻳﻢ .اﻳﻦ ﻛﻠﻤﻪ ﺑـﻪ وﻳـﮋوال 2005 C#ﻣﻴﮕﻮﻳﺪ ﻛﻪ ﺷﻤﺎ ﻣﻲ ﺧﻮاﻫﻴﺪ در اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﺟﺎي اﻋﺪاد ﺻﺤﻴﺢ ،اﻋﺪاد ﺑﺎ ﻗﺴﻤﺖ اﻋﺸﺎر ﻗﺮار دﻫﻴﺪ .در ﻧﺘﻴﺠﻪ ،ﻫﺮ ﻋﻤﻠﻴـﺎﺗﻲ ﻛﻪ ﺑﺮ روي ﻣﺘﻐﻴﻴﺮ dblNumberاﻧﺠﺎم دﻫﻴﺪ از ﻧﻮع اﻋﺸﺎري ﺧﻮاﻫﺪ ﺑﻮد و ﻣﻴﺘﻮاﻧﺪ ﻗﺴﻤﺖ اﻋﺸﺎري را ﻧﻴـﺰ ﻧﮕﻬـﺪاري ﻛﻨـﺪ .ﻧﻜﺘـﻪ ﻣﻬﻢ دﻳﮕﺮ در ﻛﺪ ﺑﺎﻻ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از ﭘﻴﺸﻮﻧﺪ intاز ﭘﻴﺸﻮﻧﺪ dblاﺳﺘﻔﺎده ﻛﺮده اﻳﻢ ﺗﺎ ﻣﺸﺨﺺ ﺑﺎﺷـﺪ ﻛـﻪ ﻣﺘﻐﻴﻴـﺮ ﺑﺎﻻ اﻋﺪاد اﻋﺸﺎري از ﻧﻮع Doubleرا در ﺧﻮد ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﻨﺪ. اﻟﺒﺘﻪ ﺑﺎ اﻳﻦ ﻛﻪ ﻋﻤﻠﻴﺎت روي ﻣﺘﻐﻴﻴﺮ dblNumberﻗﺴﻤﺖ اﻋﺸﺎري را ﻧﻴﺰ ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﻨﺪ اﻣﺎ روش اﻧﺠﺎم ﻋﻤﻠﻴـﺎت ،ﻫﻤـﺎﻧﻄﻮر ﻛﻪ در ﻛﺪ زﻳﺮ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،ﺑﺎ ﻋﻤﻠﻴﺎت روي اﻋﺪاد ﺻﺤﻴﺢ ﺗﻔﺎوﺗﻲ ﻧﺪارد. // Set number, multiply numbers, and display results ;dblNumber = 45.34 ;dblNumber *= 4.333 MessageBox.Show("Multiplication test... " + dblNumber, ;)""Floating Points اﮔﺮ ﻛﺪ ﺑﺎﻻ را اﺟﺮا ﻛﻨﻴﺪ ،ﻧﺘﻴﺠﻪ 196,45822را ﻣﺸﺎﻫﺪه ﻣﻴﻜﻨﻴﺪ ﻛﻪ ﻫﻤﺎﻧﻨﺪ دو ﻋﺪدي ﻛﻪ در ﻫﻢ ﺿﺮب ﺷﺪﻧﺪ داراي ﻗﺴﻤﺖ اﻋﺸﺎري ﻧﻴﺰ ﻫﺴﺖ .اﻟﺒﺘﻪ اﻋﺪادي ﻛﻪ در اﻳﻦ ﻣﺤﺎﺳﺒﺎت ﺑﻪ ﻛﺎر ﻣﻴﺮوﻧﺪ ﺣﺘﻤﺎ ﻧﺒﺎﻳﺪ داراي ﺑﺨﺶ ﺻﺤﻴﺢ ﺑﺎﺷﻨﺪ ،ﺑﻠﻜﻪ ﻣﺎﻧﻨﺪ ﻗﺴﻤﺖ ﺗﻘـﺴﻴﻢ ﺑﺮﻧﺎﻣـﻪ ﻗﺒـﻞ ﻣﻲ ﺗﻮاﻧﻨﺪ از دو ﻋﺪد ﺻﺤﻴﺢ ﺗﺸﻜﻴﻞ ﺷﺪه ﺑﺎﺷﻨﺪ ﻛﻪ در ﺻﻮرت ﻧﻴﺎز ﺣﺎﺻﻞ ﻋﺒﺎرت ﺑﺎ ﻗﺴﻤﺖ اﻋﺸﺎري ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ .ﺑﺮاي ﻣﺜﺎل ﺑﻪ ﻛﺪ زﻳﺮ ﺗﻮﺟﻪ ﻛﻨﻴﺪ: // Set number, divide numbers, and display results ;dblNumber = 12 ;dblNumber /= 7 MessageBox.Show("Division test... " + dblNumber, ;)""Floating Points
٦٩
ﻧﺘﻴﺠﻪ اﻳﻦ ﺗﻘﺴﻴﻢ داراي ﻗﺴﻤﺖ اﻋﺸﺎري ﻧﻴﺰ ﺧﻮاﻫﺪ ﺑﻮد زﻳﺮا ﻣﺘﻐﻴﻴﺮ dblNumberﺑﻪ ﮔﻮﻧﻪ اي ﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ ﻛـﻪ در ﺻـﻮرت ﻧﻴﺎز ﺑﺘﻮاﻧﺪ ﻗﺴﻤﺖ اﻋﺸﺎري اﻋﺪاد را ﻧﻴﺰ ﻧﮕﻬﺪاري ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﺑﺮﻧﺎﻣﻪ ﺑﺎﻻ را اﺟﺮا ﻛﻨﻴـﺪ ،ﻋـﺪد 1,71428571428571را ﺑـﻪ ﻋﻨـﻮان ﻧﺘﻴﺠﻪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد. ﻧﻜﺘﻪ :ﺑﻪ اﻋﺪاد اﻋﺸﺎري ،اﻋﺪاد ﺑﺎ ﻣﻤﻴﺰ ﺷﻨﺎور ﻧﻴﺰ ﮔﻔﺘﻪ ﻣﻴﺸﻮد .اﻳﻦ ﻧﺎﻣﮕﺬاري ﺑﻪ اﻳﻦ دﻟﻴﻞ اﺳﺖ ﻛﻪ اﻳﻦ اﻋﺪاد ﺑـﻪ ﺻـﻮرت ﻋـﺪد ﻋﻠﻤـﻲ ذﺧﻴﺮه ﻣﻲ ﺷﻮﻧﺪ .در ﻧﻤﺎد ﮔﺬاري ﻋﻠﻤﻲ ﺑﺮاي اﻋﺪاد ،ﻳﻚ ﻋﺪد ﺑﻪ ﺻﻮرت ﺗﻮاﻧﻲ از 10و ﻋـﺪدي دﻳﮕـﺮ ﺑـﻴﻦ 1ﺗـﺎ 10وﺟـﻮد دارد .ﺑـﺮاي ﻣﺤﺎﺳﺒﻪ ﻣﻘﺪار واﻗﻌﻲ ﻋﺪد 10 ،ﺑﻪ ﺗﻮان ﻋﺪد اول ﻣﻲ رﺳﺪ و ﺳﭙﺲ در ﻋﺪد دوم ﺿﺮب ﻣﻲ ﺷﻮد .ﺑﺮاي ﻣﺜـﺎل ،ﻋـﺪد 10001ﺑـﻪ ﺻـﻮرت 1,0001*104و ﻋﺪد 0,0010001ﺑﻪ ﺻﻮرت 1,0001*10 -3ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد .در اﻳﻦ ﮔﻮﻧﻪ اﻋﺪاد ،ﻣﻤﻴـﺰ ﺑـﻴﻦ اﻋـﺪاد ﺑﻌـﺪ از رﻗـﻢ اول ﺷﻨﺎور اﺳﺖ .اﻋﺪاد اﻋﺸﺎري در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻧﻴﺰ ﺑﺎ ﻫﻤﻴﻦ روش ﻧﮕﻬﺪاري ﻣﻲ ﺷﻮﻧﺪ ﺑﺎ اﻳﻦ ﺗﻔﺎوت ﻛﻪ اﻳﻦ اﻋﺪاد در ﻣﺒﻨﺎي 10ﺑﻮدﻧﺪ اﻣﺎ اﻋـﺪاد در ﻛﺎﻣﭙﻴﻮﺗﺮ در ﻣﺒﻨﺎي 2ذﺧﻴﺮه ﻣﻲ ﺷﻮﻧﺪ.
ﺣﺎﻟﺘﻬﺎي دﻳﮕﺮ: اﻋﺪاد اﻋﺸﺎري ﻋﻼوه ﺑﺮ ﻣﻘﺎدﻳﺮ ﻋﺪدي ،ﻣﻴﺘﻮاﻧﻨﺪ ﺣﺎﻟﺘﻬﺎي ﺧﺎص دﻳﮕﺮي را ﻧﻴﺰ ﻧﮕﻬﺪاري ﻛﻨﻨﺪ .ﺑﻌﻀﻲ از اﻳﻦ ﺣﺎﻟﺘﻬﺎ ﻋﺒﺎرﺗﻨﺪ از:
– NaNﻛﻪ ﺑﻪ ﻣﻌﻨﻲ " "Not a Numberﻳﺎ "ﻋﺪد ﻧﻴﺴﺖ" اﺳﺖ. ﺑﻲ ﻧﻬﺎﻳﺖ ﻣﻨﻔﻲ ﺑﻲ ﻧﻬﺎﻳﺖ ﻣﺜﺒﺖ
ﻣﺎ در اﻳﻦ ﻛﺘﺎب در ﻣﻮرد اﻳﻦ ﺣﺎﻟﺘﻬﺎ ﺻﺤﺒﺖ ﻧﺨﻮاﻫﻴﻢ ﻛﺮد ،اﻣﺎ در ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺤﺎﺳﺒﺎﺗﻲ و رﻳﺎﺿـﻲ ﻣﻴﺘـﻮان از اﻳـﻦ ﺣﺎﻟﺘﻬـﺎ ﻧﻴـﺰ اﺳﺘﻔﺎده ﻛﺮد.
اﻋﺪاد اﻋﺸﺎري ﺑﺎ دﻗﺖ ﻣﻌﻤﻮﻟﻲ: در ﻗﺴﻤﺖ ﻗﺒﻠﻲ از اﻋﺪاد اﻋﺸﺎري ﺑﺎ دﻗﺖ ﻣﻀﺎﻋﻒ اﺳﺘﻔﺎده ﻛﺮدﻳﻢ ،اﻣﺎ در .NETﺷﻤﺎ ﺑﺮاي ﻧﮕﻬﺪاري اﻋﺪاد اﻋﺸﺎري ﺧـﻮد ﻣﻴﺘﻮاﻧﻴـﺪ از دو ﻧﻮع ﻋﺪد اﻋﺸﺎري اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در ﺑﻌﻀﻲ از ﻣﻮاﻗﻊ ،ﺑﺨﺶ اﻋﺸﺎري ﻳﻚ ﻋﺪد ﻣﻤﻜﻦ اﺳﺖ ﺗﺎ ﺑﻲ ﻧﻬﺎﻳﺖ اداﻣﻪ ﭘﻴـﺪا ﻛﻨـﺪ )ﻣﺎﻧﻨـﺪ ﻋـﺪد ﭘﻲ( ،اﻣﺎ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﻲ ﻧﻬﺎﻳﺖ ﻓﻀﺎ ﺑﺮاي ﻧﮕﻬﺪاري اﻳﻦ اﻋﺪاد ﻧﺪارد ،ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻤﻴـﺸﻪ ﺑـﺮاي ﻧﮕﻬـﺪاري ﺗﻌـﺪاد ارﻗـﺎم اﻋـﺸﺎري ﻳـﻚ ﻋـﺪد ﻣﺤﺪودﻳﺘﻬﺎﻳﻲ وﺟﻮد دارد .اﻳﻦ ﻣﺤﺪودﻳﺖ ﺑﻪ اﻧﺪازه ﻳﺎ ﻓﻀﺎﻳﻲ ﺑﺴﺘﮕﻲ دارد ﻛﻪ ﻣﺘﻐﻴﻴﺮ ﺑﺮاي ﻧﮕﻬﺪاري ﻋﺪد از آن اﺳﺘﻔﺎده ﻣﻴﻜﻨﺪ. اﻋﺪاد اﻋﺸﺎري ﺑﺎ دﻗﺖ ﻣﻀﺎﻋﻒ ﻣﻴﺘﻮاﻧﻨﺪ اﻋﺪاد از – 1,7 * 10308ﺗﺎ + 1,7 * 10308را ﺑﺎ دﻗﺘﻲ ﺑﺴﻴﺎر ﺑﺎﻻ ﻧﮕﻬﺪاري ﻛﻨﺪ )ﺑـﺎ دﻗـﺖ ﻳـﻚ ﭘﻨﻲ در 45ﺗﺮﻳﻠﻴﻮن دﻻر( .اﻋﺪاد ﺻﺤﻴﺢ ﺑﺎ دﻗﺖ ﻣﻌﻤﻮﻟﻲ ﻣﻴﺘﻮاﻧﻨﺪ اﻋﺪاد از – 3,4 * 1038ﺗﺎ + 3,4 * 1038را ﻧﮕﻬﺪاري ﻛﻨﻨﺪ .اﻟﺒﺘﻪ اﻳـﻦ ﻋﺪد ﻫﻢ ﻋﺪد ﺑﺴﻴﺎر ﺑﺰرﮔﻲ اﺳﺖ اﻣﺎ ﻣﻴﺰان دﻗﺖ اﻳﻦ اﻋﺪاد ﺧﻴﻠﻲ ﻛﻤﺘﺮ از اﻋﺪاد ﺑﺎ دﻗـﺖ ﻣـﻀﺎﻋﻒ اﺳـﺖ )ﻳـﻚ ﭘﻨـﻲ در 330000دﻻر(. ﻣﺰﻳﺘﻲ ﻛﻪ اﻋﺪاد ﺑﺎ دﻗﺖ ﻣﻌﻤﻮﻟﻲ دارﻧﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻧﺴﺒﺖ ﺑﻪ اﻋﺪاد ﺑﺎ دﻗﺖ ﻣﻀﺎﻋﻒ ﻓﻀﺎي ﻛﻤﺘﺮي در ﺣﺎﻓﻈﻪ اﺷﻐﺎل ﻣﻲ ﻛﻨﻨﺪ و ﺳﺮﻋﺖ ﻣﺤﺎﺳﺒﻪ ﺑﺎﻻﺗﺮي دارﻧﺪ.
٧٠
ﻧﻜﺘﻪ :ﺑﻪ ﺟﺰ در ﻣﻮاردي ﻛﻪ ﺑﻪ دﻗﺖ ﺑﺴﻴﺎر ﺑﺎﻻﻳﻲ ﻧﻴﺎز دارﻳﺪ ،از اﻋﺪاد ﺑﺎ دﻗﺖ ﻣﻀﺎﻋﻒ اﺳـﺘﻔﺎده ﻧﻜﻨﻴـﺪ و ﺑـﻪ ﺟـﺎي آن اﻋـﺪاد ﺑـﺎ دﻗـﺖ ﻣﻌﻤﻮﻟﻲ را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ .اﺳﺘﻔﺎده از اﻋﺪاد ﺑﺎ دﻗﺖ ﻣﻀﺎﻋﻒ ﺑﻪ ﺟﺎي اﻋﺪاد ﺑﺎ دﻗﺖ ﻣﻌﻤﻮﻟﻲ ،ﻣﺨﺼﻮﺻﺎ در ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي ﺑـﺰرگ ﻣﻴﺘﻮاﻧـﺪ در ﺳﺮﻋﺖ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺑﻪ ﺷﺪت ﺗﺎﺛﻴﺮﮔﺬار ﺑﺎﺷﺪ. ﺑﺮاي اﻧﺘﺨﺎب اﻳﻨﻜﻪ از ﭼﻪ ﻧﻮع ﻋﺪدي اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ ﺑﻪ ﻣﺤﺎﺳﺒﺎﺗﻲ ﻛﻪ ﻣﻴﺨﻮاﻫﻴﺪ اﻧﺠﺎم دﻫﻴﺪ ﺗﻮﺟﻪ ﻛﻨﻴﺪ .ﺑﺮاي ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴـﺮ ﻫـﺎي ﻋﺪدي ﺑﺎ دﻗﺖ ﻣﻀﺎﻋﻒ از ﻛﻠﻤﻪ ﻛﻠﻴﺪي doubleو ﺑﺮاي ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴﺮ ﻫﺎي ﻋﺪدي ﺑﺎ دﻗﺖ ﻣﻌﻤﻮﻟﻲ از ﻛﻠﻤـﻪ ﻛﻠﻴـﺪي float اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
ﻛﺎر ﺑﺎ رﺷﺘﻪ ﻫﺎ: رﺷﺘﻪ ﻣﺠﻤﻮﻋﻪ اي از ﻛﺎراﻛﺘﺮ اﺳﺖ ﻛﻪ اﺑﺘﺪا و اﻧﺘﻬﺎي آن ﺑﻪ وﺳﻴﻠﻪ ﻋﻼﻣﺖ ﻧﻘﻞ ﻗﻮل )"( ﻣﺸﺨﺺ ﻣﻲ ﺷﻮد .روش اﺳﺘﻔﺎده از رﺷـﺘﻪ ﻫـﺎ را در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺒﻠﻲ ﺑﺮاي ﻧﻤﺎﻳﺶ ﻧﺘﻴﺠﻪ ﺑﺮﻧﺎﻣﻪ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻳﺪه اﻳﺪ .رﺷﺘﻪ ﻫﺎ ﻋﻤﻮﻣﺎ ﺑﺮاي اﻳﻦ ﻣﻨﻈﻮر اﺳﺘﻔﺎده ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﺑﻪ ﻛﺎرﺑﺮ اﻃﻼع داده ﺷﻮد در ﺑﺮﻧﺎﻣﻪ ﭼﻪ اﺗﻔﺎﻗﻲ اﻓﺘﺎده اﺳﺖ و ﭼﻪ اﺗﻔﺎﻗﻲ ﻣﻴﺨﻮاﻫﺪ رخ دﻫﺪ .ﻳﻚ اﺳﺘﻔﺎده دﻳﮕﺮ از رﺷﺘﻪ ﻫﺎ ،ذﺧﻴﺮه ﻗـﺴﻤﺘﻲ از ﻳﻚ ﻣﺘﻦ ﺑﺮاي اﺳﺘﻔﺎده از آن در ﻳﻚ اﻟﮕﻮرﻳﺘﻢ اﺳﺖ .در ﻃﻮل اﻳﻦ ﻛﺘﺎب ﺑﺎ رﺷﺘﻪ ﻫﺎي زﻳﺎدي ﻣﻮاﺟﻪ ﻣﻲ ﺷﻮﻳﺪ ،ﻫﻤﺎﻧﻄﻮر ﻛـﻪ ﺗـﺎﻛﻨﻮن از رﺷﺘﻪ زﻳﺮ اﺳﺘﻔﺎده ﻛﺮده اﻳﺪ: MessageBox.Show("Multiplication test... " + dblNumber, ;)""Floating Points "… "Multiplication testو " "Floating Pointsﻧﻤﻮﻧﻪ ﻫـﺎﻳﻲ از رﺷـﺘﻪ ﻫـﺴﺘﻨﺪ ،زﻳـﺮا داراي ﻋﻼﻣﺖ )"( در اﺑﺘﺪا و اﻧﺘﻬﺎي ﺧﻮد ﻫﺴﺘﻨﺪ .اﻣﺎ ﻋﺒﺎرت dblNumberﭼﻲ؟ در ﻋﺒﺎرت ﺑﺎﻻ ،ﻣﻘﺪار ﻣﺘﻐﻴﻴـﺮ dblNumberﺑـﻪ رﺷﺘﻪ ﺗﺒﺪﻳﻞ ﺷﺪه و ﭘﺲ از ﺗﺮﻛﻴﺐ ﺑﺎ دو رﺷﺘﻪ دﻳﮕﺮ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ )ﭼﮕﻮﻧﮕﻲ ﺗﺒﺪﻳﻞ اﻳﻦ ﻣﺘﻐﻴﻴـﺮ ﻋـﺪدي ﺑـﻪ رﺷـﺘﻪ، ﺑﺤﺜﻲ اﺳﺖ ﻛﻪ ﺟﻠﻮﺗﺮ راﺟﻊ ﺑﻪ آن ﺻﺤﺒﺖ ﺷﺪه اﺳﺖ .اﻣﺎ ﻓﻌﻼ اﻳﻦ را ﺑﺪاﻧﻴﺪ ﻛﻪ در اﻳﻦ ﺟﺎ ﻳﻚ ﺗﺒﺪﻳﻞ ﺻﻮرت ﮔﺮﻓﺘﻪ اﺳﺖ( .ﺑـﺮاي ﻣﺜـﺎل اﮔﺮ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ dblNumberﺑﺮاﺑﺮ ﺑﺎ 27ﺑﺎﺷﺪ ،اﻳﻦ ﻣﻘﺪار ﺑﻪ ﻳﻚ ﻋﺒﺎرت رﺷﺘﻪ اي ﻛﻪ دو ﻛـﺎراﻛﺘﺮ ﻃـﻮل دارد ﺗﺒـﺪﻳﻞ ﻣﻴـﺸﻮد و ﺳﭙﺲ روي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ،ﺑﺎ ﻳﻚ ﺳﺮي از ﻛﺎرﻫﺎﻳﻲ ﻛﻪ ﻣﻴﺘﻮاﻧﻴﺪ ﺑﺎ رﺷـﺘﻪ ﻫـﺎ اﻧﺠـﺎم دﻫﻴـﺪ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از رﺷﺘﻪ ﻫﺎ (1ﺑﺎ اﺳﺘﻔﺎده از ﮔﺰﻳﻨﻪ File New Projectﻳﻚ ﭘﺮوژه ﺟﺪﻳﺪ در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ و ﻧـﺎم آن را Stringsﻗﺮار دﻫﻴﺪ. (2ﺑــﺎ اﺳــﺘﻔﺎده از ﺟﻌﺒــﻪ اﺑــﺰار ،ﻳــﻚ ﻛﻨﺘــﺮل Buttonروي ﻓــﺮم ﻗــﺮار دﻫﻴــﺪ .ﺧﺎﺻــﻴﺖ Nameاﻳــﻦ دﻛﻤــﻪ را ﺑﺮاﺑــﺮ btnStringsو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ Using Stringsﻗﺮار دﻫﻴﺪ .روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و در ﻣﺘﺪ اﻳﺠﺎد ﺷﺪه ،ﻛﺪ زﻳﺮ را وارد ﻛﻨﻴﺪ: )private void btnStrings_Click(object sender, EventArgs e {
٧١
// Declare variable ;string strData // Set the string value ;"!strData = "Hello, world // Display the result ;)"MessageBox.Show(strData, "Strings } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ Using Stringsﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛﺎدر ﭘﻴﻐـﺎﻣﻲ ﻣـﺸﺎﺑﻪ ﺷـﻜﻞ 6-3ﻧﻤـﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
ﺷﻜﻞ 6-3
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺮاي ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴﺮي ﻛﻪ ﺑﺘﻮاﻧﺪ رﺷﺘﻪ ﻫﺎ را در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﺸﺎﺑﻪ ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴﺮ ﻫﺎي ﻋـﺪدي ﻋﻤـﻞ ﻛﻨﻴـﺪ .اﻣـﺎ اﻳـﻦ ﻣﺮﺗﺒﻪ از ﻛﻠﻤﻪ ﻛﻠﻴﺪي stringاﺳﺘﻔﺎده ﻛﻨﻴﺪ: // Declare variable ;string strData ﻫﻤﺎﻧﻨﺪ ﻗﺒﻞ ،ﻳﻚ ﻣﻘﺪار را ﺑﻪ ﻣﺘﻐﻴﻴﺮ ﺟﺪﻳﺪ اﺧﺘﺼﺎص ﻣﻲ دﻫﻴﺪ: // Set the string value ;"!strData = "Hello, world ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن اﻳﻦ ﻛﻪ رﺷﺘﻪ ﺷﻤﺎ از ﻛﺠﺎ ﺷﺮوع ﺷﺪه و ﺗﺎ ﻛﺠﺎ اداﻣﻪ ﭘﻴﺪا ﻣﻴﻜﻨﺪ ﺑﺎﻳﺪ از ﻋﻼﻣﺖ ﻧﻘﻞ ﻗﻮل )"( اﺳﺘﻔﺎده ﻛﻨﻴـﺪ .اﻳـﻦ ﻣﻮرد اﻫﻤﻴﺖ زﻳﺎدي دارد ،زﻳﺮا اﻳﻦ ﻋﻼﻣﺖ ﺑﻪ وﻳﮋوال 2005 C#ﻣﻴﮕﻮﻳﺪ ﻛﻪ ﻛﺪام ﻋﺒﺎرات را ﺑﺎﻳﺪ ﺑﻪ ﻋﻨﻮان رﺷﺘﻪ در ﻧﻈﺮ ﺑﮕﻴﺮد و آﻧﻬﺎ را ﻛﺎﻣﭙﺎﻳﻞ ﻧﻜﻨﺪ .اﮔﺮ از ﻋﻼﻣﺖ ﻧﻘﻞ ﻗﻮل اﺳﺘﻔﺎده ﻧﻜﻨﻴﺪ ،وﻳﮋوال 2005 C#ﺑﺎ اﻳﻦ ﻣﺘﻦ ﻫﺎ ﺑﻪ ﻋﻨﻮان ﻛﺪ رﻓﺘﺎر ﻛﺮده ،ﺳﻌﻲ ﻣﻴﻜﻨـﺪ آﻧﻬـﺎ را ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﺪ و ﻧﻤﻴﺘﻮاﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻛﺎﻣﭙﺎﻳﻞ ﻛﻞ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﺧﻄﺎ روﺑﺮو ﺧﻮاﻫﺪ ﺷﺪ. وﻗﺘﻲ ﻣﻘﺪار "! "Hello, worldرا در ﻣﺘﻐﻴﻴﺮ strDataذﺧﻴﺮه ﻛﺮدﻳﺪ ﻣﻴﺘﻮاﻧﻴﺪ آن را در ﺑﻪ ﻋﻨـﻮان ﻳـﻚ ﭘـﺎراﻣﺘﺮ ﺑـﻪ ﺗﺎﺑﻊ MessageBox.Showﺑﻔﺮﺳﺘﻴﺪ ﺗﺎ روي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﭼﺎپ ﻛﻨﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ دﻳﺪﻳﺪ ﻧﺤﻮه ﺗﻌﺮﻳﻒ و اﺳﺘﻔﺎده از رﺷﺘﻪ ﻫﺎ ﻧﻴﺰ ﻣﺸﺎﺑﻪ اﻋﺪاد اﺳﺖ .در ﻗﺴﻤﺖ ﺑﻌﺪي در ﻣﻮرد ﭼﮕﻮﻧﮕﻲ اﻧﺠﺎم ﻋﻤﻠﻴﺎت ﻣﺨﺘﻠـﻒ روي رﺷﺘﻪ ﻫﺎ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد.
٧٢
اﺗﺼﺎل رﺷﺘﻪ ﻫﺎ: اﺗﺼﺎل رﺷﺘﻪ ﻫﺎ ﺑﻪ ﻣﻌﻨﻲ ﺑﻪ ﻫﻢ ﻣﺘﺼﻞ ﻛﺮدن ﻳﻚ ﺳﺮي از رﺷﺘﻪ ﻫﺎ در اﻣﺘﺪاد ﻳﻜﺪﻳﮕﺮ و اﻳﺠﺎد ﻳﻚ رﺷﺘﻪ ﺟﺪﻳﺪ اﺳﺖ .اﺗﺼﺎل ﺑﺮاي رﺷﺘﻪ ﻫﺎ ﻫﻤﺎﻧﻨﺪ ﻋﻤﻞ ﺟﻤﻊ ﻛﺮدن در اﻋﺪاد اﺳﺖ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ،ﺑﺎ ﭼﮕﻮﻧﮕﻲ اﻳﻦ ﻋﻤﻞ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺗﺼﺎل رﺷﺘﻪ ﻫﺎ (1در ﭘﺮوژه اي ﻛﻪ در ﺑﺨﺶ ﻗﺒﻠﻲ اﻳﺠﺎد ﻛﺮدﻳﺪ ،ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ Form1ﺑﺮوﻳﺪ و ﻳﻚ ﻛﻨﺘﺮل Buttonﺟﺪﻳﺪ اﺿـﺎﻓﻪ ﻛﻨﻴــــﺪ .ﺧﺎﺻــــﻴﺖ Nameآن را ﺑﺮاﺑــــﺮ btnConcatenationو ﺧﺎﺻــــﻴﺖ Textآن را ﺑﺮاﺑــــﺮ Concatenationﻗﺮار دﻫﻴﺪ .روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در ﻣﺘﺪ اﻳﺠﺎد ﺷﺪه وارد ﻛﻨﻴﺪ: private void btnConcatenation_Click(object sender, )EventArgs e { // Declare variables ;string strOne ;string strTwo ;string strResults // Set the string values ;" strOne = "Hello, ;"!strTwo = "World // Concatenate the strings ;strResults = strOne + strTwo // Display the results ;)"MessageBox.Show(strResults, "Strings } (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ Concatenationﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 6-3ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛﺮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﻳﻦ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ،اﺑﺘﺪا ﺳﻪ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع رﺷﺘﻪ ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﺪ: // Declare variables ;string strOne ;string strTwo ٧٣
;string strResults ﺳﭙﺲ ﺑﻪ دو ﻣﺘﻐﻴﻴﺮ اول ﻣﻘﺪار ﻣﻲ دﻫﻴﺪ: // Set the string values ;" strOne = "Hello, ;"!strTwo = "World ﺑﻌﺪ از اﻳﻦ ﻛﻪ ﺑﻪ دو ﻣﺘﻐﻴﻴﺮ اول ﻣﻘﺪار دادﻳﺪ ،دو رﺷﺘﻪ را ﺑﺎ اﺳﺘﻔﺎده از ﻋﻼﻣﺖ ﺟﻤﻊ ) (+ﺑﺎ ﻫﻢ ﺟﻤﻊ ﻣﻲ ﻛﻨﻴﺪ و ﻋﺒﺎرت ﺟﺪﻳﺪ را در ﻣﺘﻐﻴﻴﺮ ﺳﻮم ﺑﻪ ﻧﺎم strResultsﻗﺮار ﻣﻲ دﻫﻴﺪ: // Concatenate the strings ;strResults = strOne + strTwo در واﻗﻊ در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻣﻲ ﮔﻮﻳﻴﺪ" :ﻣﻘـﺪار ﻣﺘﻐﻴﻴـﺮ strResultsرا ﺑﺮاﺑـﺮ ﻣﻘـﺪار strOneﺑـﻪ ﻋـﻼوه ﻣﻘـﺪار strTwoﻗﺮار ﺑﺪه" .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺗﺎﺑﻊ MessageBox.Showرا ﻓﺮاﺧـﻮاﻧﻲ ﻛﺮدﻳـﺪ ،ﻣﻘـﺪار strResultsﺑﺮاﺑـﺮ "! "Hello, Worldﺧﻮاﻫﺪ ﺑﻮد ،ﺑﻨﺎﺑﺮاﻳﻦ ﻧﺘﻴﺠﻪ اي ﻣﺸﺎﺑﻪ ﻗﺒﻞ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﻴﺪ. // Display the results ;)"MessageBox.Show(strResults, "Strings
اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ اﺗﺼﺎل رﺷﺘﻪ در درون ﺑﺮﻧﺎﻣﻪ: ﺑﺮاي اﺗﺼﺎل دو رﺷﺘﻪ ﺑﻪ ﻳﻜﺪﻳﮕﺮ ﺣﺘﻤﺎ ﻧﺒﺎﻳﺪ ﻣﺘﻐﻴﻴﺮي ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ و رﺷﺘﻪ ﻫﺎ را درون آن ﻗﺮار دﻫﻴﺪ .ﺑﻠﻜﻪ ﻣـﻲ ﺗﻮاﻧﻴـﺪ درون ﻛـﺪ و ﺑـﻪ ﺳﺮﻋﺖ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻳﻦ روش در اﻣﺘﺤﺎن ﻛﻨﻴﺪ اﻳﻦ ﺑﺨﺶ ﺷﺮح داده ﺷﺪه اﺳﺖ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺗﺼﺎل رﺷﺘﻪ ﻫﺎ درون ﺑﺮﻧﺎﻣﻪ (1ﻣﺠﺪدا ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ Form1ﺑﺮﮔﺮدﻳﺪ و ﻳﻚ دﻛﻤﻪ ﻓﺮﻣﺎن ﺟﺪﻳﺪ ﺑﻪ ﺻـﻔﺤﻪ اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ .ﺧﺎﺻـﻴﺖ Nameآن را Inline ﺑﺮاﺑــــﺮ btnInlineConcatenationو ﺧﺎﺻــــﻴﺖ Textآن را ﺑﺮاﺑــــﺮ Concatenationﻗﺮار دﻫﻴﺪ .روي دﻛﻤﻪ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در آن وارد ﻛﻨﻴﺪ: private void btnInlineConcatenation_Click(object sender, )EventArgs e { // Declare variable ;int intNumber // Set the value ;intNumber = 26 ٧٤
// Display the results MessageBox.Show("The value of intNumber is: " + ;)"intNumber, "Strings } (2ﻛﺪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ Inline Concatenationﻛﻠﻴﻚ ﻛﻨﻴـﺪ .ﻧﺘﻴﺠـﻪ اي ﻣـﺸﺎﺑﻪ ﺷـﻜﻞ 7-3را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 7-3
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ اﺗﺼﺎل رﺷﺘﻪ ﻣﺎﻧﻨﺪ ﻛﺪ ﺑﺎﻻ را ﻗﺒﻼ در ﻣﺜﺎل ﻫﺎي ﭘﻴﺶ دﻳﺪه ﺑﻮدﻳﺪ .ﭼﻴﺰي ﻛﻪ در ﺣﻘﻴﻘﺖ اﻳﻦ ﻛﺪ اﻧﺠﺎم ﻣﻲ دﻫﺪ ﺗﺒﺪﻳﻞ ﻣﻘﺪار ذﺧﻴﺮه ﺷﺪه در ﻣﺘﻐﻴﻴﺮ intNumberﺑﻪ رﺷﺘﻪ اﺳﺖ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﻳﻦ ﻣﻘﺪار ﻣﻴﺘﻮاﻧﺪ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﭼﺎپ ﺷﻮد .ﺑـﻪ اﻳـﻦ ﻛﺪ ﻧﮕﺎه ﻛﻨﻴﺪ: // Display the results MessageBox.Show("The value of intNumber is: " + ;)"intNumber, "Strings ﺑﺨﺶ " "The value of intNumber is:در ﺣﻘﻴﻘﺖ ﻳﻚ رﺷﺘﻪ اﺳﺖ ،اﻣﺎ ﺷﻤﺎ ﻣﺠﺒﻮر ﻧﻴـﺴﺘﻴﺪ ﻛـﻪ آن را ﺑﻪ ﻋﻨﻮان ﻳﻚ ﻣﺘﻐﻴﻴﺮ رﺷﺘﻪ اي ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ .در وﻳﮋوال 2005 C#اﻳﻦ ﻧﻮع رﺷﺘﻪ ﻫﺎ را ﻳﻚ ﺛﺎﺑﺖ رﺷﺘﻪ اي ﻣﻲ ﻧﺎﻣﻨﺪ ،زﻳﺮا از ﻫﻨﮕﺎم ﺗﻌﺮﻳﻒ ﺗﺎ ﻣﻮﻗﻊ اﺳﺘﻔﺎده ،ﻣﻘﺪار آﻧﻬﺎ ﺛﺎﺑﺖ اﺳﺖ و ﺗﻐﻴﻴﺮ ﻧﻤﻲ ﻛﻨﺪ .زﻣﺎﻧﻲ ﻛﻪ ﺷﻤﺎ از ﻋﻤﻠﮕﺮ اﺗـﺼﺎل رﺷـﺘﻪ ﻫـﺎ روي اﻳـﻦ رﺷـﺘﻪ و ﻣﺘﻐﻴﻴـﺮ intNumberاﺳﺘﻔﺎده ﻛﺮدﻳﺪ ،ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ intNumberﺑﻪ رﺷﺘﻪ ﺗﺒﺪﻳﻞ ﺧﻮاﻫﺪ ﺷﺪ و در اﻧﺘﻬﺎي "The value " of intNumber is:ﻗﺮار ﺧﻮاﻫﺪ ﮔﺮﻓﺖ .ﻧﺘﻴﺠﻪ اﻳﻦ ﻋﻤﻞ ﻳﻚ رﺷﺘﻪ ﺟﺪﻳﺪ ﺷﺎﻣﻞ ﻫﺮ دو ﻋﺒﺎرت رﺷﺘﻪ و ﻋﺪد ﺧﻮاﻫـﺪ ﺑﻮد ﻛﻪ ﺑﻪ ﺗﺎﺑﻊ MessageBox.Showﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد.
ﻋﻤﻠﻴﺎت ﺑﻴﺸﺘﺮ روي رﺷﺘﻪ ﻫﺎ: در ﻫﺮ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ از ﺟﻤﻠﻪ C#ﺗﻮاﺑﻊ زﻳﺎدي ﺑﺮاي ﻛﺎر ﺑﺮ روي ﻳﻚ رﺷﺘﻪ وﺟﻮد دارﻧﺪ .ﺑﻌﻀﻲ از اﻳﻦ ﺗﻮاﺑﻊ در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ﺗﻮﺿﻴﺢ داده ﺷﺪه اﻧﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻴﺘﻮاﻧﻴﺪ ﻃﻮل ﻳﻚ رﺷﺘﻪ را ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﺗﻮاﺑﻊ ﺑﺪﺳﺖ آورﻳﺪ.
٧٥
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺑﺪﺳﺖ آوردن ﻃﻮل ﻳﻚ رﺷﺘﻪ (1ﺑﺎ اﺳﺘﻔﺎده از ﻗﺴﻤﺖ ﻃﺮاﺣﻲ Form1ﻳﻚ ﻛﻨﺘﺮل TextBoxﺑﻪ ﻓﺮم ﺧﻮد اﺿﺎﻓﻪ ﻛﻨﻴﺪ .و ﺧﺎﺻﻴﺖ Nameآن را ﺑـﻪ txtStringﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﻛﻨﺘﺮل Buttonدﻳﮕـﺮي ﺑـﻪ ﺻـﻔﺤﻪ اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ و ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑـﺮ btnLengthو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ Lengthﻗﺮار دﻫﻴﺪ .ﻛﻨﺘﺮﻟﻬﺎي روي ﻓﺮم را ﺑﻪ ﻧﺤـﻮي ﻗـﺮار دﻫﻴـﺪ ﻛﻪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 8-3ﺑﺎﺷﻨﺪ:
ﺷﻜﻞ 8-3 (2روي دﻛﻤﻪ Lengthدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را ﻣﺘﺪ اﻳﺠﺎد ﺷﺪه اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )private void btnLength_Click(object sender, EventArgs e { // Declare variable ;string strData // Get the text from the TextBox ;strData = txtString.Text // Display the length of the string MessageBox.Show(strData.Length + " Character(s)", ;)""Strings } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﻣﺘﻦ دﻟﺨﻮاﻫﻲ را در TextBoxوارد ﻛﻨﻴﺪ. (4روي دﻛﻤﻪ Lengthﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻧﺘﻴﺠﻪ اي ﻣﺸﺎﺑﻪ آﻧﭽﻪ در ﺷﻜﻞ 9-3ﻧﺸﺎن داده ﺷﺪه اﺳﺖ را ﺧﻮاﻫﻴﺪ دﻳﺪ.
ﺷﻜﻞ 9-3
٧٦
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اوﻟﻴﻦ ﻛﺎري ﻛﻪ اﻧﺠﺎم ﻣﻲ دﻫﻴﺪ ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴﺮي اﺳﺖ ﻛﻪ اﻃﻼﻋﺎت را در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ .ﺳﭙﺲ ﻣﺘﻦ وارد ﺷـﺪه در TextBox را درﻳﺎﻓﺖ ﻛﺮده و در ﻣﺘﻐﻴﻴﺮ ﻣﺘﻨﻲ ﺧﻮد ﻛﻪ strDataﻧﺎﻣﻴﺪه ﻣﻲ ﺷﻮد ذﺧﻴﺮه ﻣﻲ ﻛﻨﻴﺪ. // Declare variable ;string strData // Get the text from the TextBox ;strData = txtString.Text زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﻣﺘﻨﻲ دارﻳﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺧﺎﺻﻴﺖ Lengthآن ﺑﺮاي درﻳﺎﻓﺖ ﺗﻌﺪاد ﺣﺮوف رﺷﺘﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻳـﻦ ﺧﺎﺻـﻴﺖ ﻣﻘﺪاري را از ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ ﺑﻪ ﻋﻨﻮان ﻃﻮل رﺷﺘﻪ ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .ﺑﻪ ﻳﺎد داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﺮ ﻛﺎراﻛﺘﺮي از ﻗﺒﻴﻞ ﻓﻀﺎﻫﺎي ﺧـﺎﻟﻲ و ﻋﻼﻣﺘﻬﺎ را ﻧﻴﺰ در ﻣﺤﺎﺳﺒﻪ ﻃﻮل رﺷﺘﻪ ﺑﻪ ﺷﻤﺎر ﻣﻲ آورد. // Display the length of the string MessageBox.Show(strData.Length + " Character(s)", ;)""Strings
زﻳﺮ رﺷﺘﻪ ﻫﺎ: در ﺑﻴﺸﺘﺮ ﻣﻮاﻗﻊ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ در ﺑﺮﻧﺎﻣﻪ ﺧﻮد ﺑﻪ ﺟﺎي ﻛﺎر ﺑﺎ ﺗﻤﺎم رﺷﺘﻪ ،ﺑﺎ ﻗﺴﻤﺘﻲ از آن ﻛﺎر ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺧﻮاﻫﻴﺪ از ﻳﻚ ﻣﺠﻤﻮﻋﻪ از ﻛﺎراﻛﺘﺮ ﻫﺎ ﻛﻪ در اول رﺷﺘﻪ و ﻳﺎ در آﺧﺮ آن آﻣﺪه اﻧﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻳﻦ ﻣﺠﻤﻮﻋﻪ ﻛﺎراﻛﺘﺮ ﻫﺎ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ از ﻫﺮ ﺟـﺎﻳﻲ از رﺷﺘﻪ ﺷﺮوع ﺷﻮﻧﺪ و ﺑﻪ ﻫﺮ ﺟﺎﻳﻲ در رﺷﺘﻪ ﺧﺘﻢ ﺷﻮﻧﺪ را زﻳﺮ رﺷﺘﻪ ﻣﻲ ﻧﺎﻣﻴﻢ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻴﻢ ﻛﻪ ﺳﻪ ﻛﺎراﻛﺘﺮ اﺑﺘﺪا ،وﺳﻂ و اﻧﺘﻬﺎي رﺷﺘﻪ را ﻧﻴﺰ ﻧﻤﺎﻳﺶ دﻫﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻛﺎر ﺑﺎ زﻳﺮ رﺷﺘﻪ ﻫﺎ (1اﮔﺮ ﺑﺮﻧﺎﻣﻪ Stringsدر ﺣﺎل اﺟﺮا اﺳﺖ ،آن را ﺑﺒﻨﺪﻳﺪ. (2دﻛﻤﻪ ﻓﺮﻣﺎن دﻳﮕﺮي ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﺪ و ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ btnSplitو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑـﺮ Splitﻗﺮار دﻫﻴﺪ .روي دﻛﻤﻪ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را وارد ﻛﻨﻴﺪ: )private void btnSplit_Click(object sender, EventArgs e { // Declare variable ;string strData
٧٧
// Get the text from thew TextBox ;strData = txtString.Text // Display the first three characters ;)"MessageBox.Show(strData.Substring(0, 3), "Strings // Display the middle three characters ;)"MessageBox.Show(strData.Substring(3, 3), "Strings // Display the last three characters (MessageBox.Show ;)"strData.Substring(strData.Length - 3), "Strings } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﻛﻠﻤﻪ Cranberryرا در ﺟﻌﺒﻪ ﻣﺘﻨﻲ وارد ﻛﻨﻴﺪ. (4روي دﻛﻤﻪ Splitﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺳﻪ ﻛﺎدر ﭘﻴﻐﺎم ﻣﺘﻮاﻟﻲ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 10-3ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 10-3
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻣﺘﺪ Substringﺑﻪ ﺷﻤﺎ اﻳﻦ اﻣﻜﺎن را ﻣﻲ دﻫﺪ ﺗﺎ از ﻫﺮ ﻗﺴﻤﺘﻲ از رﺷﺘﻪ ،ﻳﻚ ﻣﺠﻤﻮﻋﻪ از ﻛﺎراﻛﺘﺮ ﻫﺎ را ﺟﺪا ﻛﻨﻴﺪ .اﻳﻦ ﻣﺘـﺪ ﺑـﻪ دو روش ﻣﻲ ﺗﻮاﻧﺪ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮد .روش اول اﻳﻦ اﺳﺖ ﻛﻪ ﺷﻤﺎره ﻛﺎراﻛﺘﺮ اول و ﺗﻌﺪاد ﻛﺎراﻛﺘﺮ ﻫﺎﻳﻲ را ﻛﻪ ﻧﻴﺎز دارﻳﺪ ﺑﻪ ﺗﺎﺑﻊ ﺑﺪﻫﻴﺪ .ﺑﺮاي ﻣﺜﺎل در اوﻟﻴﻦ ﺑﺎر اﺟﺮاي ﺗﺎﺑﻊ در ﺑﺮﻧﺎﻣﻪ ﺑﺎﻻ ﺑﻪ وﻳﮋوال 2005 C#ﻣﻲ ﮔﻮﻳﻴﻢ ﻛﻪ از ﻛﺎراﻛﺘﺮ ﺻﻔﺮم )از اﺑﺘﺪاي رﺷﺘﻪ( ﺷـﺮوع ﻛـﻦ و ﺳـﻪ ﻛﺎراﻛﺘﺮ را ﺟﺪا ﻛﻦ: // Display the first three characters ;)"MessageBox.Show(strData.Substring(0, 3), "Strings در ﻣﺮﺗﺒﻪ دوم ﻓﺮاﺧﻮاﻧﻲ ،ﺑﻪ ﺗﺎﺑﻊ ﻣﻲ ﮔﻮﻳﻴﺪ ﻛﻪ از ﻛﺎراﻛﺘﺮ ﺳﻮم ،ﺳﻪ ﻛﺎراﻛﺘﺮ را ﺟﺪا ﻛﻨﺪ و ﺑﺮﮔﺮداﻧﺪ. // Display the middle three characters ;)"MessageBox.Show(strData.Substring(3, 3), "Strings در ﻣﺮﺗﺒﻪ آﺧﺮي ﻛﻪ ﺗﺎﺑﻊ را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﺪ ،ﻓﻘﻂ ﻳﻚ ﭘﺎراﻣﺘﺮ را ﺑﺮاي آن ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﺪ .اﻳﻦ ﭘﺎراﻣﺘﺮ ﺑﻪ ﺗﺎﺑﻊ ﻣﻲ ﮔﻮﻳﺪ ﻛﻪ از ﻣﻜﺎن ﻣﺸﺨﺺ ﺷﺪه ﺷﺮوع ﻛﻨﺪ و ﺗﻤﺎم ﻛﺎراﻛﺘﺮ ﻫﺎي ﺳﻤﺖ راﺳﺖ آن را ﺟﺪا ﻛﻨﺪ .در اﻳـﻦ ﻗـﺴﻤﺖ ﻣـﻲ ﺧـﻮاﻫﻴﻢ ﺳـﻪ ﻛـﺎراﻛﺘﺮ آﺧـﺮ رﺷـﺘﻪ را ٧٨
ﺑﺮﮔﺮداﻧﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ Lengthﺑﻪ ﺗﺎﺑﻊ Substringﻣﻲ ﮔﻮﻳﻴﻢ ﻛﻪ از ﺳﻪ ﻛﺎراﻛﺘﺮ ﻣﺎﻧﺪه ﺑﻪ اﻧﺘﻬﺎي رﺷـﺘﻪ ﺷﺮوع ﻛﻦ و ﺗﻤﺎم ﻛﺎراﻛﺘﺮ ﻫﺎي ﺑﺎﻗﻲ ﻣﺎﻧﺪه را ﺑﺮﮔﺮدان. // Display the last three characters MessageBox.Show(strData.Substring(strData.Length - 3), ;)""Strings
ﻗﺎﻟﺐ ﺑﻨﺪي رﺷﺘﻪ ﻫﺎ: ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﺎ رﺷﺘﻪ ﻫﺎ ﻛﺎر ﻛﻨﻴﺪ ،ﻣﻤﻜﻦ اﺳﺖ ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻧﺤﻮه ﻧﻤﺎﻳﺶ ﻛﺎراﻛﺘﺮ ﻫـﺎ ﺑـﺮ ﺻـﻔﺤﻪ ﻧﻤـﺎﻳﺶ را ﺗﻐﻴﻴـﺮ دﻫﻴﺪ .ﻣﺜﻼ در ﺷﻜﻞ ،5-3ﻛﺎدر ﭘﻴﻐﺎم ﻧﺘﻴﺠﻪ ﺗﻘﺴﻴﻢ را ﻧﻤﺎﻳﺶ ﻣﻴﺪﻫﺪ ،اﻣﺎ اﺣﺘﻤﺎﻻ ﺷﻤﺎ ﺑﻪ ﻫﺮ 14رﻗﻢ اﻋﺸﺎر ﻧﻴﺎز ﻧﺪارﻳـﺪ و 2ﻳـﺎ 3رﻗـﻢ ﻛﻔﺎﻳﺖ ﻣﻴﻜﻨﺪ! ﭼﻴﺰي ﻛﻪ ﺷﻤﺎ در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺎز دارﻳﺪ اﻳﻦ اﺳﺖ ﻛﻪ رﺷﺘﻪ را ﺑﻪ ﮔﻮﻧﻪ اي ﻗﺎﻟﺐ ﺑﻨﺪي ﻛﻨﻴﺪ ﻛﻪ ﺗﻤﺎم ﻛﺎراﻛﺘﺮ ﻫﺎي ﺳﻤﺖ ﭼﭗ ﻣﻤﻴﺰ و ﻓﻘﻂ 2ﻳﺎ 3رﻗﻢ اﻋﺸﺎر را ﻧﺸﺎن دﻫﺪ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي اﻳﻦ ﻛﺎر را اﻧﺠﺎم ﺧﻮاﻫﻴﻢ داد:
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻗﺎﻟﺐ ﺑﻨﺪي رﺷﺘﻪ ﻫﺎ (1ﺑﺮﻧﺎﻣﻪ Floating-Pt Mathرا ﻛﻪ ﻗﺒﻼ در اﻳﻦ ﻓﺼﻞ اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﺪ ﺑﺎز ﻛﻨﻴﺪ. (2وﻳﺮاﻳﺸﮕﺮ ﻛﺪ را ﺑﺮاي Form1ﺑﺎز ﻛﻨﻴﺪ و ﺗﻐﻴﺮات زﻳﺮ را در ﻛﺪ اﻳﺠﺎد ﻛﻨﻴﺪ: // Set number, divide numbers, and display results ;dblNumber = 13 ;dblNumber /= 7 // Display the results without formatting MessageBox.Show("Without formatting: " + dblNumber, ;)""Floating Points //Display the results with formatting MessageBox.Show("With formatting: " + String.Format("{0:n3}", dblNumber), ;)""Floating Points (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﺑﻌﺪ از اﻳﻨﻜﻪ ﻛﺎدر ﭘﻴﻐـﺎم ﻣﺮﺑـﻮط ﺑـﻪ ﺗـﺴﺖ ﻋﻤـﻞ ﺿـﺮب ﻧﻤـﺎﻳﺶ داده ﺷـﺪ ،ﻛـﺎدر ﭘﻴﻐـﺎم ﺑﻌـﺪي ﻋـﺪد 1,71428571428571را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. (4ﻫﻨﮕﺎﻣﻲ ﻛﻪ روي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ،ﻛﺎدر ﺑﻌﺪي ﻧﺘﻴﺠﻪ 1,714را ﻧﻤﺎﻳﺶ ﺧﻮاﻫﺪ داد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟
٧٩
ﺗﻨﻬﺎ ﭼﻴﺰي ﻛﻪ در اﻳﻦ ﻛﺪ ﻣﻤﻜﻦ اﺳﺖ ﻋﺠﻴﺐ ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ ،اﺳﺘﻔﺎده از ﺗﺎﺑﻊ String.Formatاﺳﺖ .اﻳﻦ ﺗﺎﺑﻊ ﻗﻮي ،ﺑﻪ ﺷـﻤﺎ اﺟﺎزه ﻣﻴﺪﻫﺪ ﻣﺘﻦ و ﻳﺎ اﻋﺪاد ﺧﻮد را ﻗﺎﻟﺐ ﺑﻨﺪي ﻛﻨﻴﺪ .ﺗﻨﻬﺎ ﻧﻜﺘﻪ ﻣﻬﻤﻲ ﻛﻪ اﻳﻦ ﺗﺎﺑﻊ دارد ،ﭘﺎراﻣﺘﺮ اول آن اﺳﺖ ﻛـﻪ ﻣـﺸﺨﺺ ﻣـﻲ ﻛﻨـﺪ ﺧﺮوﺟﻲ ﺗﺎﺑﻊ ﺑﺎﻳﺪ در ﭼﻪ ﻗﺎﻟﺒﻲ ﺑﺎﺷﺪ. //Display the results with formatting MessageBox.Show("With formatting: " + String.Format("{0:n3}", dblNumber), ;)""Floating Points ﺑﺮاي ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ String.Formatﺑﺎﻳﺪ دو ﭘﺎراﻣﺘﺮ را ﺑﻪ آن ﺑﻔﺮﺳﺘﻴﺪ .ﭘﺎراﻣﺘﺮ اول ،"{0:n3}" ،ﻗﺎﻟﺐ رﺷﺘﻪ اي اﺳﺖ ﻛﻪ ﺷﻤﺎ ﻣﻴﺨﻮاﻫﻴﺪ از ﻣﺘﺪ درﻳﺎﻓﺖ ﻛﻨﻴﺪ .ﭘﺎراﻣﺘﺮ دوم ،dblNumber ،ﻣﻘﺪاري اﺳﺖ ﻛﻪ ﻣﻴﺨﻮاﻫﻴﺪ ﻗﺎﻟﺐ ﺑﻨﺪي ﻛﻨﻴﺪ. ﻋـﺪد ﺻـﻔﺮ در ﭘــﺎراﻣﺘﺮ اول ﻣـﺸﺨﺺ ﻣﻴﻜﻨــﺪ ﻛـﻪ در ﺣـﺎل ﻣــﺸﺨﺺ ﻛـﺮدن ﻗﺎﻟــﺐ اوﻟـﻴﻦ ﭘـﺎراﻣﺘﺮ ﺑﻌــﺪ از ﭘـﺎراﻣﺘﺮ ﺣﺎﺿــﺮ ﻳـﺎ ﻫﻤــﺎن dblNumberﻫﺴﺘﻴﺪ .ﻗﺴﻤﺘﻲ ﻛﻪ ﺑﻌﺪ از " ":آﻣﺪه اﺳﺖ ﻣﺸﺨﺺ ﻣﻴﻜﻨﺪ ﻛﻪ ﺑﻪ ﭼﻪ ﺻﻮرت ﻣﻲ ﺧﻮاﻫﻴﺪ رﺷﺘﻪ را ﻗﺎﻟﺐ ﺑﻨﺪي ﻛﻨﻴﺪ. در اﻳﻦ ﺟﺎ از n3اﺳﺘﻔﺎده ﻛﺮده اﻳﺪ ﻛﻪ ﺑﻪ ﻣﻌﻨﺎي "ﻳﻚ ﻋﺪد ﺑﺎ ﻣﻤﻴﺰ ﺷﻨﺎور و ﺳﻪ رﻗﻢ اﻋﺸﺎر" اﺳﺖ .ﺑﺮاي اﻳـﻦ ﻛـﻪ ﻋـﺪد را ﺑـﺎ دو رﻗـﻢ اﻋﺸﺎر داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،ﺑﻪ راﺣﺘﻲ ﻣﻴﺘﻮاﻧﻴﺪ از ﻋﺒﺎرت n2اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
ﻗﺎﻟﺐ ﺑﻨﺪي ﺑﻮﻣﻲ: زﻣﺎﻧﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ اي را ﺑﺎ .NETﻣﻲ ﻧﻮﻳﺴﻴﺪ ،ﺑﺎﻳﺪ ﺑﺪاﻧﻴﺪ ﻛﻪ ﻛﺎرﺑﺮ ﺷﻤﺎ ﻣﻤﻜﻦ اﺳﺖ از ﻗﻮاﻋﺪ ﻋﻼﻣﺖ ﮔﺬاري در زﺑﺎن ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﺪ ﻛﻪ ﺑﺮاي ﺷﻤﺎ ﻧﺎ آﺷﻨﺎ ﺑﺎﺷﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ در اﻳﺎﻻت ﻣﺘﺤﺪه زﻧﺪﮔﻲ ﻣﻲ ﻛﻨﻴﺪ ،از ﻋﻼﻣﺖ ﻧﻘﻄـﻪ ) (.ﺑـﺮاي ﻣﻤﻴـﺰ ﺑـﻴﻦ ﻗـﺴﻤﺖ اﻋـﺸﺎر و ﻗﺴﻤﺖ ﺻﺤﻴﺢ ﻋﺪد اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ .اﻣﺎ ﺑﺮاي ﻛﺎرﺑﺮاﻧﻲ ﻛﻪ در ﻓﺮاﻧﺴﻪ ﻫﺴﺘﻨﺪ اﻳﻦ ﻋﻼﻣﺖ ﻳﻚ وﻳﺮﮔﻮل ) (،اﺳﺖ .ﻫﻤﻴﻨﻄﻮر ﻣﻤﻜﻦ اﺳﺖ ﺑﺮاي ﻛﺎرﺑﺮان ﻛﺸﻮرﻫﺎي دﻳﮕﺮ اﻳﻦ ﻋﻼﻣﺖ ﺗﻔﺎوت داﺷﺘﻪ ﺑﺎﺷﺪ. وﻳﻨﺪوز ﻣﻴﺘﻮاﻧﺪ ﺑﺮ اﺳﺎس ﺗﻨﻈﻴﻤﺎت ﻣﺤﻠﻲ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻛﺎرﺑﺮ ،اﻳﻦ ﻋﻼﻣﺘﻬﺎ را ﺑﺮاي ﺷﻤﺎ اﻧﺘﺨﺎب ﻛﻨﺪ .اﮔﺮ ﺷﻤﺎ از ﭼـﺎرﭼﻮب .NETدرﺳـﺖ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﻋﻤﻮﻣﺎ ﻧﻴﺎزي ﻧﻴﺴﺖ در ﻣﻮرد اﻳﻦ ﻋﻼﻣﺖ ﮔﺬاري ﻫﺎ ﻧﮕﺮان ﺑﺎﺷﻴﺪ .ﺑﺮاي ﻣﺜﺎل در ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠـﻲ ﻣـﺎ ﺑـﺎ اﺳـﺘﻔﺎده از ،n3ﺑـﻪ .NETﮔﻔﺘﻴﻢ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻋﺪد ﺧﻮد را ﺑﺎ ﺟﺪا ﻛﻨﻨﺪه ﻫﺰارﮔﺎن و ﻫﻤﭽﻨﻴﻦ ﺑﺎ ﺳﻪ رﻗﻢ اﻋﺸﺎر در ﺳﻤﺖ راﺳـﺖ ﻧﻤـﺎﻳﺶ دﻫـﻴﻢ .اﻟﺒﺘـﻪ ﺗﻘﺴﻴﻢ ﻗﺴﻤﺖ ﻗﺒﻠﻲ ﺑﻪ ﺟﺪاﻛﻨﻨﺪه ﻫﺰارﮔﺎن ﻧﻴﺎزي ﻧﺪارد اﻣﺎ اﮔﺮ ﺗﻘﺴﻴﻢ را ﺑﻪ 12000 / 7ﺗﻐﻴﻴﺮ دﻫﻴﻢ ،ﻋـﺪد 1،742 .286را درﻳﺎﻓـﺖ ﻣـﻲ ﻛﻨﻴﻢ ﻛﻪ در ﺻﻮرت داﺷﺘﻦ ﺟﺪاﻛﻨﻨﺪه ﻫﺰارﮔﺎن ،راﺣﺖ ﺗﺮ ﺧﻮاﻧﺪه ﻣﻲ ﺷﻮد. ﺣﺎل اﮔﺮ ﻛﺎرﺑﺮ ﺗﻨﻈﻴﻤﺎت ﻣﺤﻠﻲ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺧﻮد را ﺑﺮاﺑﺮ ﺗﻨﻈﻴﻤﺎت ﻓﺮاﻧﺴﻮي ﻗﺮار دﻫﺪ و ﻛﺪ ﻗﺒﻠﻲ را اﺟﺮا ﻛﻨﺪ )ﺑﺪون اﻳﻨﻜﻪ ﻫﻴﭻ ﺗﻐﻴﺮي را در ﻛﺪ ﺑﻪ وﺟﻮد آورﻳﺪ( ،ﻧﺘﻴﺠﻪ 1 714،286را درﻳﺎﻓﺖ ﺧﻮاﻫﺪ ﻛﺮد. ﻧﻜﺘﻪ :ﺑﺮاي ﺗﻐﻴﻴﺮ ﺗﻨﻈﻴﻤﺎت ﻣﺤﻠﻲ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺧﻮد ﻣﻴﺘﻮاﻧﻴﺪ ﺑـﻪ Control Panelﺑﺮوﻳـﺪ و روي آﻳﻜـﻮن Regional and Language Optionsﻛﻠﻴﻚ ﻛﻨﻴﺪ و زﺑﺎن ﺧﻮد را ﺑﻪ زﺑﺎﻧﻲ ﻛﻪ ﺗﻤﺎﻳﻞ دارﻳﺪ ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺑﻪ اﻳﻦ ﺻـﻮرت ﻋﻼﻣـﺖ ﮔﺬاري زﺑﺎﻧﻲ ﻛﻪ اﻧﺘﺨﺎب ﻛﺮده اﻳﺪ در ﻛﺎﻣﭙﻴﻮﺗﺮ ﺷﻤﺎ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد. در زﺑﺎن ﻓﺮاﻧﺴﻪ ،ﺟﺪاﻛﻨﻨﺪه ﻫﺰارﮔﺎن ﻳﻚ ﻓﻀﺎي ﺧﺎﻟﻲ اﺳﺖ ﻧﻪ ﻳﻚ وﻳﺮﮔﻮل .ﻫﻤﭽﻨﻴﻦ ﺑﺮاي ﻣﻤﻴﺰ اﻋﺸﺎري ﻧﻴﺰ از وﻳﺮﮔﻮل اﺳﺘﻔﺎده ﻣﻴﻜﻨﻨﺪ ﻧﻪ از ﻧﻘﻄﻪ .ﺑﺎ اﺳﺘﻔﺎده درﺳﺖ از ﻣﺘﺪ String.Formatﻣﻴﺘﻮاﻧﻴﺪ ﺑﺮﻧﺎﻣﻪ اي ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ ﺑـﺮ اﺳـﺎس ﺗﻨﻈﻴﻤـﺎت ﻣﺤﻠـﻲ ﻛـﺎرﺑﺮ، اﻃﻼﻋﺎت را ﺑﻪ ﻧﺤﻮي ﺻﺤﻴﺢ ﻧﻤﺎﻳﺶ دﻫﺪ.
٨٠
ﺟﺎﻳﮕﺰﻳﻨﻲ زﻳﺮرﺷﺘﻪ ﻫﺎ: ﻳﻜﻲ از ﻛﺎرﻫﺎي ﻋﻤﻮﻣﻲ دﻳﮕﺮي ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﻫﻨﮕﺎم ﻛﺎر ﺑﺎ رﺷﺘﻪ ﻫﺎ ﺑﻪ آن ﻧﻴﺎز ﭘﻴﺪا ﻛﻨﻴﺪ ،ﺟـﺎﻳﮕﺰﻳﻨﻲ ﻳـﻚ رﺷـﺘﻪ ﺧـﺎص ﺑـﺎ رﺷـﺘﻪ دﻳﮕﺮي در ﻳﻚ ﻣﺘﻦ اﺳﺖ .ﺑﺮاي ﺗﻮﺿﻴﺢ ﭼﮕﻮﻧﮕﻲ اﻳﻦ ﻛﺎر ،در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ،ﺑﺮﻧﺎﻣﻪ Stringsﺧـﻮد را ﺑـﻪ ﮔﻮﻧـﻪ اي ﺗﻐﻴﻴﺮ ﻣﻴﺪﻫﻴﻢ ﻛﻪ رﺷﺘﻪ " "Helloرا ﺑﺎ رﺷﺘﻪ " "Goodbyeﺟﺎﻳﮕﺰﻳﻦ ﻛﻨﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺟﺎﻳﮕﺰﻳﻨﻲ زﻳﺮرﺷﺘﻪ ﻫﺎ (1ﺑﺮﻧﺎﻣﻪ Stringsرا ﻛﻪ ﻗﺒﻼ اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﺪ ،ﺑﺎز ﻛﻨﻴﺪ. (2ﻛﻨﺘﺮل Buttonدﻳﮕﺮي را ﺑﻪ Form1اﺿﺎﻓﻪ ﻛﻨﻴﺪ ،ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ btnReplaceو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ Replaceﻗﺮار دﻫﻴﺪ .روي دﻛﻤﻪ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ ﻣﺘﺪ ﻣﺮﺑـﻮط ﺑﻪ روﻳﺪاد Clickآن اﺿﺎﻓﻪ ﻛﻨﻴﺪ. )private void btnReplace_Click(object sender, EventArgs e { // Declare variables ;string strData ;string strNewData // Get the text from the TextBox ;strData = txtString.Text // Replace the string occurance ;)"strNewData = strData.Replace("Hello", "Goodbye // Display the new string ;)"MessageBox.Show(strNewData, "Strings } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺟﻤﻠﻪ ! Hello Worldرا در ﺟﻌﺒﻪ ﻣﺘﻨﻲ وارد ﻛﻨﻴﺪ. (4روي دﻛﻤﻪ Replaceﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛﺎدر ﭘﻴﻐﺎﻣﻲ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻋﺒـﺎرت ! Goodbye Worldرا ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻣﺘﺪ Replaceدو رﺷﺘﻪ را درﻳﺎﻓﺖ ﻣﻴﻜﻨﺪ و در ﻣﺘﻦ ﺑﻪ دﻧﺒﺎل رﺷﺘﻪ اول ﻣﻲ ﮔﺮدد .ﺳﭙﺲ در ﻫﺮ ﻗﺴﻤﺘﻲ از ﻣـﺘﻦ ﻛـﻪ رﺷـﺘﻪ اول را ﭘﻴﺪا ﻛﺮد آن را ﺑﺎ رﺷﺘﻪ دوم ﺟﺎﻳﮕﺰﻳﻦ ﻣﻲ ﻛﻨﺪ .ﺑﻌﺪ از اﻳﻦ ﻛﻪ رﺷﺘﻪ اول در ﺗﻤﺎم ﻣﺘﻦ ﺑﺎ رﺷﺘﻪ دوم ﺟﺎﻳﮕﺰﻳﻦ ﺷﺪ ،ﻋﺒﺎرت ﺟﺪﻳﺪ ﺑـﻪ ﺷـﻤﺎ ﺑﺮﮔﺮداﻧﺪه ﻣﻲ ﺷﻮد و ﻣﻲ ﺗﻮاﻧﻴﺪ آن را ﻧﻤﺎﻳﺶ دﻫﻴﺪ.
٨١
// Replace the string occurance ;)"strNewData = strData.Replace("Hello", "Goodbye ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﺪ ،ﻓﻘﻂ Helloاول ﺑﺎ Goodbyeﺟﺎﻳﮕﺰﻳﻦ ﻧﻤﻴﺸﻮد ،ﺑﻠﻜﻪ ﻣﻴﺘﻮاﻧﻴﺪ در ﺟﻌﺒﻪ ﻣﺘﻨﻲ ،ﻋﺒﺎرﺗﻲ را وارد ﻛﻨﻴـﺪ ﻛـﻪ ﭼﻨﺪﻳﻦ Helloداﺷﺘﻪ ﺑﺎﺷﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺗﻤﺎم Helloﻫﺎي ﻣﺘﻦ ﺑﺎ Goodbyeﺟﺎﻳﮕﺰﻳﻦ ﻣﻴﺸﻮﻧﺪ .اﻣﺎ ﺑﻪ ﺧﺎﻃﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻛﺪ ﺑﺎﻻ ،ﻛﻠﻤﻪ Helloرا ﺑﺎ Goodbyeﺟﺎﻳﮕﺰﻳﻦ ﻣﻴﻜﻨﺪ ﻧﻪ ﻛﻠﻤﻪ helloرا )ﻳﺎ ﻫﺮ ﺣﺎﻟﺖ دﻳﮕﺮي( .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ اﻳـﻦ ﺗﺎﺑﻊ ﻧﺴﺒﺖ ﺑﻪ ﻛﻮﭼﻜﻲ ﻳﺎ ﺑﺰرﮔﻲ ﺣﺮوف ﺣﺴﺎس اﺳﺖ.
ﺗﺒﺪﻳﻞ ﻧﻮع ﻫﺎي داده اي: در اﻧﺠﺎم ﻣﺤﺎﺳﺒﺎت ﺑﺮ روي ﻣﺘﻐﻴﻴﺮ ﻫﺎ و ﻳﺎ ذﺧﻴﺮه ﻣﻘﺪار ﻳﻚ ﻣﺘﻐﻴﻴﺮ در ﻣﺘﻐﻴﻴﺮي دﻳﮕﺮ ،ﻧﻮع داده اي آﻧﻬﺎ ﻫﻤﻮاره ﺑﺎﻳﺪ ﻳﻜﺴﺎن ﺑﺎﺷﺪ .ﺑـﺮاي ﻣﺜﺎل ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ را ﻓﻘﻂ ﻣﻲ ﺗﻮان ﺑﺮ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ دﻳﮕﺮ ﺗﻘﺴﻴﻢ ﻛﺮد و ﻳﺎ ﻣﻘﺪار ﻳﻚ ﻣﺘﻐﻴﻴﺮ اﻋـﺸﺎري را ﻧﻤـﻲ ﺗـﻮان ﺑـﻪ ﻳـﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ ﻧﺴﺒﺖ داد .1در ﻫﻨﮕﺎم ﻣﺤﺎﺳﺒﺎت اﮔﺮ ﻧﻮع ﻫﺎي ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﺑﺎ ﻫﻢ ﺗﻔﺎوت داﺷﺘﻪ ﺑﺎﺷﺪ ،ﻳﻜﻲ از ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﺑـﻪ ﻧـﻮع داده اي ﻣﺘﻐﻴﻴﺮ دﻳﮕﺮ ﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮد .ﺗﺒﺪﻳﻞ ﻧﻮع داده اي ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﺑﻪ دو روش ﻣﻲ ﺗﻮاﻧﺪ اﻧﺠﺎم ﺷﻮد :ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ و ﺑﻪ ﺻـﻮرت ﺻﺮﻳﺢ .در ﺑﻴﺸﺘﺮ ﻣﻮاﻗﻊ اﻳﻦ ﺗﺒﺪﻳﻞ ﻧﻮع ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺗﻮﺳﻂ ﻛﺎﻣﭙﺎﻳﻠﺮ اﻧﺠﺎم ﻣﻲ ﺷﻮد .اﻣﺎ در ﻣﻮاﻗﻌﻲ ﻛﻪ اﻳـﻦ ﺗﺒـﺪﻳﻞ ﻧـﻮع ﻣﻤﻜـﻦ اﺳﺖ ﻣﻨﺠﺮ ﺑﻪ از دﺳﺖ رﻓﺘﻦ اﻃﻼﻋﺎت ﺷﻮد ،ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﺑﺎﻳﺪ آن را ﺑﻪ ﺻﻮرت ﺻﺮﻳﺢ اﻧﺠﺎم دﻫﺪ. ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻣﻘﺪار ﻳﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع اﻋﺸﺎري را در ﻳﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع ﺻﺤﻴﺢ ﻗـﺮار دﻫﻴـﺪ .در اﻳـﻦ ﺣﺎﻟـﺖ ﻧﻤـﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺻﻮرت ﻣﻌﻤﻮﻟﻲ از ﻋﻤﻠﮕﺮ ﺗﺴﺎوي اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،زﻳﺮا ﺑﺎ اﻳﻦ ﻛﺎر ﻗﺴﻤﺖ اﻋﺸﺎر ﻋﺪد از ﺑﻴﻦ ﻣﻴﺮود .ﺑﻪ ﻫﻤﻴﻦ ﻋﻠﺖ ﻛﺎﻣﭙـﺎﻳﻠﺮ اﻳـﻦ ﺗﺒﺪﻳﻞ را ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻧﺠﺎم ﻧﻤﻲ دﻫﺪ .اﻣﺎ اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ را در ﻳﻚ ﻣﺘﻐﻴﻴـﺮ از ﻧـﻮع اﻋـﺸﺎري ﻗـﺮار دﻫﻴﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻋﻤﻠﮕﺮ ﺗﺴﺎوي اﺳﺘﻔﺎده ﻛﻨﻴﺪ .زﻳﺮا ﺑﺎ ﺗﻐﻴﻴﺮ ﻧﻮع از ﻋﺪد ﺻﺤﻴﺢ ﺑﻪ ﻋﺪد اﻋﺸﺎري اﻣﻜﺎن از دﺳﺖ رﻓﺘﻦ اﻃﻼﻋـﺎت وﺟـﻮد ﻧﺪارد و اﻳﻦ ﺗﺒﺪﻳﻞ ﻧﻮع ﺑﻪ ﺻﻮرت ﺧﻮدﻛﺎر ﺗﻮﺳﻂ ﻛﺎﻣﭙﺎﻳﻠﺮ اﻧﺠﺎم ﻣﻲ ﺷﻮد. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﭼﮕﻮﻧﮕﻲ ﺗﺒﺪﻳﻞ ﻧﻮع داده اي ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﻃﻮر ﺻﺮﻳﺢ را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد .
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺗﺒﺪﻳﻞ ﻧﻮع ﻫﺎي داده اي (1در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005روي ﻣﻨﻮي Fileﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﺳﭙﺲ New Projectرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. در ﭘﻨﺠﺮه New Projectﻳﻚ ﺑﺮﻧﺎﻣﻪ وﻳﻨﺪوزي ﺑﻪ ﻧﺎم Casting Demoاﻳﺠﺎد ﻛﻨﻴﺪ. (2در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ Form1ﻳﻚ ﻛﻨﺘﺮل Buttonﻗﺮار داده ،ﺧﺎﺻﻴﺖ Nameآن را ﺑـﻪ btnCastو Text آن را ﺑﻪ Castﺗﻐﻴﻴﺮ دﻫﻴﺪ. (3ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳـﺮ را در آن وارد ﻛﻨﻴﺪ. )private void btnCast_Click(object sender, EventArgs e { 1ﺣﺘﻲ اﮔﺮ ﻣﻘﺪار آن ﻣﺘﻐﻴﻴﺮ ﻓﺎﻗﺪ ﻗﺴﻤﺖ اﻋﺸﺎر ﺑﺎﺷﺪ ،ﺑﺎز ﻫﻢ ﻧﻤﻲ ﺗﻮان ﻣﻘﺪار آن را در ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ ﻗﺮار داد.
٨٢
int intNumber = 2; double dblNumber = 3.4; intNumber = dblNumber; MessageBox.Show("The value of intNumber is: " + intNumber); } . ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ در ﺧﻂ ﺳﻮم ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟﻪ ﻣﻲ ﺷﻮد.( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ4 : را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪbtCast_Click ( ﻛﺪ ﻣﺘﺪ5 private void btnCast_Click(object sender, EventArgs e) { int intNumber = 2; double dblNumber = 3.4; dblNumber = intNumber; MessageBox.Show("The value of dblNumber is: " + dblNumber); } 2 ﺑﻪ ﻋﺪدdblNumber ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ.( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن ﻛﻠﻴﻚ ﻛﻨﻴﺪ6 .ﺗﻐﻴﻴﺮ ﻛﺮده اﺳﺖ :( ﻛﺪ ﻣﻮﺟﻮد در ﻣﺘﺪ را ﻣﺠﺪداً ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ ﺑﻪ ﺻﻮرت زﻳﺮ درآﻳﺪ7 private void btnCast_Click(object sender, EventArgs e) { int intNumber = 2; double dblNumber = 3.4; intNumber = (int)dblNumber; MessageBox.Show("The value of intNumebr is: " + intNumber); } ﺗﻐﻴـﺮintNumber ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛـﻪ ﻣﻘـﺪار ﻣﺘﻐﻴﻴـﺮ.( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن ﻛﻠﻴﻚ ﻛﻨﻴﺪ8 . ﺷﺪه اﺳﺖdblNumber ﻛﺮده و ﺑﺮاﺑﺮ ﺑﺎ ﻗﺴﻤﺖ ﺻﺤﻴﺢ ﻋﺪد
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟
٨٣
در اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﺑﺘﺪا ﺳﻌﻲ ﻛﺮده اﻳﻢ ﻣﻘﺪار ﻳﻚ ﻣﺘﻐﻴﻴﺮ اﻋﺸﺎري را در ﻳﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع ﺻﺤﻴﺢ ﻗﺮار دﻫﻴﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﺑـﺎ اﻳـﻦ ﻛﺎر ﺑﺨﺶ اﻋﺸﺎر ﻋﺪد از ﺑﻴﻦ ﻣﻲ رود .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ ﻛﺎﻣﭙﺎﻳﻠﺮ اﻳﻦ ﺗﺒﺪﻳﻞ را ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻧﺠﺎم ﻧﻤﻲ دﻫﺪ و ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟـﻪ ﻣﻲ ﺷﻮد. ;intNumber = dblNumber MessageBox.Show("The value of intNumber is: " + ;)intNumber در ﺑﺨﺶ ﺑﻌﺪ ﺳﻌﻲ ﻛﺮده اﻳﻢ ﻣﻘﺪار ﻳﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع ﺻﺤﻴﺢ را در ﻳﻚ ﻣﺘﻐﻴﻴﺮ اﻋﺸﺎري ﻗﺮار دﻫﻴﻢ .ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ در اﻳﻦ ﺣﺎﻟﺖ اﺣﺘﻤـﺎل از دﺳﺖ رﻓﺘﻦ اﻃﻼﻋﺎت وﺟﻮد ﻧﺪارد و ﻣﻘﺪار ﻣﻮﺟﻮد در ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﺻﻮرت ﻛﺎﻣﻞ در ﻣﺘﻐﻴﻴﺮ اﻋﺸﺎري ذﺧﻴﺮه ﻣﻲ ﺷﻮد ،اﻳﻦ ﺗﺒﺪﻳﻞ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺗﻮﺳﻂ ﻛﺎﻣﭙﺎﻳﻠﺮ اﻧﺠﺎم ﻣﻲ ﺷﻮد. ;dblNumber = intNumber MessageBox.Show("The value of dblNumber is: " + ;)dblNumber ﺑﺎ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ و ﻛﻠﻴﻚ ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛـﺮد ﻛـﻪ ﻣﻘـﺪار ﻣﺘﻐﻴﻴـﺮ intNumberﻳﻌﻨـﻲ ﻋـﺪد 2در ﻣﺘﻐﻴﻴـﺮ dblNumberﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ. ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﻣﻘﺪار ﻳﻚ ﻣﺘﻐﻴﻴﺮ اﻋﺸﺎري را در ﻳﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ ﻧﮕﻬﺪاري ﻛﻨﻴﻢ ﺑﺎﻳﺪ ﺑﻪ ﻃـﻮر ﺻـﺮﻳﺢ آن را ﺑـﻪ ﻋـﺪد ﺻﺤﻴﺢ ﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ .در زﺑﺎن C#اﻳﻦ ﻛﺎر ﺑﻪ وﺳﻴﻠﻪ ﻋﻤﻠﮕﺮ ﭘﺮاﻧﺘﺰ )( اﻧﺠﺎم ﻣﻲ ﺷﻮد .ﺑﺮاي ﺗﺒﺪﻳﻞ ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑـﻪ ﻳـﻚ ﻧـﻮع داده اي ﺧﺎص و ذﺧﻴﺮه آن ،ﺑﺎﻳﺪ ﻗﺒﻞ از ﻧﺎم ﻣﺘﻐﻴﻴﺮ ﻳﻚ ﭘﺮاﻧﺘﺰ ﻗﺮار دﻫﻴﺪ و ﺳﭙﺲ داﺧﻞ ﭘﺮاﻧﺘﺰ ﻧﺎم ﻧﻮع داده اي ﻣﻘﺼﺪ را وارد ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل: ;intNumber = (int)dblNumber MessageBox.Show("The value of intNumebr is: " + ;)intNumber در اﻳﻦ ﻛﺪ ﻣﺘﻐﻴﻴﺮ dblNumberﻛﻪ از ﻧﻮع doubleاﺳﺖ ﺑﺎ اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ ﭘﺮاﻧﺘﺰ ﺑـﻪ ﻧـﻮع داده اي intﺗﺒـﺪﻳﻞ ﺷـﺪه اﺳﺖ و ﺳﭙﺲ در ﻣﺘﻐﻴﻴﺮي از اﻳﻦ ﻧﻮع ذﺧﻴﺮه ﺷﺪه اﺳﺖ. اﻟﺒﺘﻪ دﻗﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ از اﻳﻦ روش ﺑﺮاي ﺗﺒﺪﻳﻞ ﻣﺘﻐﻴﻴﺮ ﻫﺎي رﺷﺘﻪ اي ﺑﻪ ﻋﺪدي و ﺑﺮ ﻋﻜﺲ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﮔﺮ رﺷﺘﻪ اي ﻛﻪ ﺷﺎﻣﻞ ﻳﻚ ﻋﺪد اﺳﺖ )ﻣﺎﻧﻨﺪ " ("234.14را ﺑﺨﻮاﻫﻴﺪ ﺑﻪ ﻋﺪد ﺗﺒﺪﻳﻞ ﻛﻨﻴﺪ ﺑﺎﻳﺪ از ﺗﺎﺑﻊ Parseدر ﻧﻮع داده اي ﻋﺪد اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ ﻣﺘﻐﻴﻴﺮ ،str1رﺷﺘﻪ اي ﺣﺎوي ﻳﻚ ﻋﺪد اﻋﺸﺎري اﺳﺖ و ﻣﻲ ﺧﻮاﻫﻴـﺪ آن را در ﻣﺘﻐﻴﻴـﺮ dblNum1 ﻛﻪ از ﻧﻮع اﻋﺸﺎري اﺳﺖ ذﺧﻴﺮه ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ از ﺗﺎﺑﻊ )( double.Parseﺑﻪ ﺻﻮرت زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ;)dblNum1 = double.Parse(str1 ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴﺐ ﺑﺮاي ﺗﺒﺪﻳﻞ ﻳﻚ رﺷﺘﻪ ﺷﺎﻣﻞ ﻋﺪد ﺻﺤﻴﺢ ﺑﻪ ﻋﺪد ﺻﺤﻴﺢ ﺑﺎﻳﺪ از ﺗﺎﺑﻊ int.Parseاﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﺑﺮاي ﺗﺒﺪﻳﻞ ﻳﻚ ﻋﺪد ﺑﻪ رﺷﺘﻪ ﻫﻢ ﺑﺎﻳﺪ از ﺗﺎﺑﻊ )( ToStringﻣﺮﺑﻮط ﺑﻪ ﻣﺘﻐﻴﻴﺮ ﻋﺪدي اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜـﺎل اﮔـﺮ ﺑﺨﻮاﻫﻴـﺪ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ dblNumberرا در ﻳﻚ ﻣﺘﻐﻴﻴﺮ رﺷـﺘﻪ اي ذﺧﻴـﺮه ﻛﻨﻴـﺪ ﺑﺎﻳـﺪ از ﺗـﺎﺑﻊ )(dblNumber.ToString اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
٨٤
اﺳﺘﻔﺎده از ﺗﺎرﻳﺨﻬﺎ: ﻳﻜﻲ دﻳﮕﺮ از اﻧﻮاع داده اي ﻛﻪ ﻛﺎرﺑﺮد زﻳﺎدي دارد و اﺣﺘﻤﺎﻻً از آن زﻳﺎد اﺳﺘﻔﺎده ﺧﻮاﻫﻴﺪ ﻛﺮد ﺗﺎرﻳﺨﻬﺎ ﻫﺴﺘﻨﺪ .اﻳﻦ ﻧـﻮع ﻣﺘﻐﻴﻴـﺮ ﻫـﺎ ﻳـﻚ ﺗﺎرﻳﺦ را در ﺧﻮد ﻧﮕﻪ ﻣﻲ دارﻧﺪ .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ،ﺑﺎ ﻣﺘﻐﻴﻴﺮ ﻫﺎﻳﻲ ﻛﻪ ﺗﺎرﻳﺦ را ﻧﮕﻬﺪاري ﻣﻴﻜﻨﻨﺪ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﻣﻴﺸﻮﻳﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻧﻤﺎﻳﺶ ﺗﺎرﻳﺦ روز (1ﻳﻚ ﭘﺮوژه وﻳﻨﺪوزي ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم Date Demoاﻳﺠﺎد ﻛﻨﻴﺪ. (2ﺑﺎ اﺳـﺘﻔﺎده از ﺟﻌﺒـﻪ اﺑـﺰار ﻳـﻚ ﻛﻨﺘـﺮل Buttonﺑـﻪ ﻓـﺮم ﺟﺪﻳـﺪ ﺧـﻮد اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ .ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑـﺮ btnDateو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ Show Dateﻗﺮار دﻫﻴﺪ. (3روي دﻛﻤﻪ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را ﺑﻪ ﻣﺘﺪ اﻳﺠﺎد ﺷﺪه اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )private void btnDate_Click(object sender, EventArgs e { // Declare variable ;DateTime dteDate // Get the current date and time ;dteDate = DateTime.Now // Display the results ;)"MessageBox.Show(dteDate.ToString(), "Date Demo } (4ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ Show Dateﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻇﺎﻫﺮ ﺷﺪه و ﺗﺎرﻳﺦ و ﺳـﺎﻋﺖ ﺟـﺎري را )ﺑـﺮ اﺳﺎس ﺗﻨﻈﻴﻤﺎت ﻣﺤﻠﻲ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺷﻤﺎ( ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 11-3ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
ﺷﻜﻞ 11-3
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟
٨٥
ﻧﻮع داده اي DateTimeﻣﻴﺘﻮاﻧﺪ ﻳﻚ ﻣﻘﺪار را ﻛﻪ ﻣﻌﺮف ﻳﻚ ﺗﺎرﻳﺦ و زﻣﺎن ﺧﺎص اﺳﺖ ،در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ .ﺑﻌـﺪ از اﻳـﻦ ﻛـﻪ ﻣﺘﻐﻴﻴﺮي از اﻳﻦ ﻧﻮع را اﻳﺠﺎد ﻛﺮدﻳﺪ ،ﺑﺮاي اﻳﻦ ﻛﻪ ﺑﻪ آن ﻣﻘﺪار اوﻟﻴﻪ ﺑﺪﻫﻴﺪ ﻣﻴﺘﻮاﻧﻴﺪ از ﺧﺎﺻﻴﺖ Nowدر اﻳﻦ ﻧﻮع داده اي اﺳﺘﻔﺎده ﻛﻨﻴﺪ. اﻳﻦ ﺧﺎﺻﻴﺖ ﻣﻘﺪار ﺗﺎرﻳﺦ و زﻣﺎن ﻛﻨﻮﻧﻲ ﺳﻴﺴﺘﻢ را ﺑﺮﻣﻴﮕﺮداﻧﺪ: // Declare variable ;DateTime dteDate // Get the current date and time ;dteDate = DateTime.Now ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﺑﺮ اي اﻳﻦ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻣﺘﺪ MessageBox.Showﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ ،ﺑﺎﻳﺪ ﺑﻪ رﺷﺘﻪ ﺗﺒﺪﻳﻞ ﺷﻮﻧﺪ .در .NETﻫﺮ ﻣﺘﻐﻴﻴﺮي ﺗﺎﺑﻌﻲ ﺑﻪ ﻧﺎم ToStringدارد ﻛـﻪ ﻣﺘﻐﻴﻴـﺮ را ﺑـﻪ رﺷـﺘﻪ ﺗﺒـﺪﻳﻞ ﻣﻴﻜﻨـﺪ .1در اﻳـﻦ ﺟـﺎ ﺑـﺮاي اﻳـﻦ ﻛـﻪ ﺑﺘـﻮاﻧﻴﻢ ﻣﺘﻐﻴﻴـﺮ dteDateرا ﻧﻤﺎﻳﺶ دﻫﻴﻢ اﺑﺘﺪا ﺑﺎﻳﺪ آن را ﺑﻪ رﺷﺘﻪ ﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ ﻛﻪ ﺑﺮاي اﻳﻦ ﻛﺎر از ﺗﺎﺑﻊ ToStringاﻳـﻦ ﻣﺘﻐﻴﻴـﺮ اﺳـﺘﻔﺎده ﻛﺮده اﻳﻢ: // Display the results ;)"MessageBox.Show(dteDate.ToString(), "Date Demo ﻣﺘﻐﻴﻴﺮ ﻫﺎي ﺗﺎرﻳﺦ و زﻣﺎن ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ دﻳﮕﺮ ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﻫﺴﺘﻨﺪ ،ﺑﺎ اﻳﻦ ﺗﻔﺎوت ﻛﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺗـﺎرﻳﺦ و زﻣـﺎن را در ﺧـﻮد ﻧﮕﻬـﺪاري ﻛﻨﻨـﺪ و ﻋﻤﻠﻴﺎت ﺟﻤﻊ و ﺗﻔﺮﻳﻖ ﻣﺮﺑﻮط ﺑﻪ آن را ﻧﻴﺰ اﻧﺠﺎم دﻫﻨﺪ .در ﺑﺨﺸﻬﺎي ﺑﻌﺪي ﺑﺎ ﻧﺤﻮه ﻛﺎر ﺑﺎ اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻫﺎ و ﻧﻤﺎﻳﺶ آﻧﻬﺎ ﺑـﺮ روي ﺻـﻔﺤﻪ ﻧﻤﺎﻳﺶ ﺑﻪ روﺷﻬﺎي ﮔﻮﻧﺎﮔﻮن ،ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ.
ﻗﺎﻟﺐ ﺑﻨﺪي ﺗﺎرﻳﺨﻬﺎ: در ﻗﺴﻤﺖ ﻗﺒﻠﻲ ﻳﻜﻲ از ﺣﺎﻟﺘﻬﺎي ﻗﺎﻟﺐ ﺑﻨﺪي ﺗﺎرﻳﺦ را دﻳﺪﻳﻢ .اﮔﺮ ﻣﺘﻐﻴﻴﺮي از ﻧﻮع ﺗﺎرﻳﺦ را ﺑﺎ اﺳﺘﻔﺎده از ﺗﺎﺑﻊ ToStringﺑﻪ رﺷـﺘﻪ ﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ ،ﺗﺎرﻳﺦ و زﻣﺎن ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 11-3ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﻨﺪ ﺷﺪ.ﺑﻪ دﻟﻴﻞ اﻳﻨﻜﻪ ﺗﻨﻈﻴﻤﺎت ﻣﺤﻠﻲ اﻳﻦ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑـﺮ اﺳـﺎس اﻳـﺮان اﺳﺖ ،ﺗﺎرﻳﺦ ﺑﻪ ﺻﻮرت YYYY/MM/DDو زﻣﺎن ﻧﻴﺰ ﺑﻪ ﺻﻮرت 12ﺳﺎﻋﺘﻪ ﻧﻤﺎﻳﺶ داده ﻣﻴﺸﻮد .اﻳـﻦ ﻧﻴـﺰ ﻧﻤﻮﻧـﻪ دﻳﮕـﺮي از ﺗـﺎﺛﻴﺮ ﺗﻨﻈﻴﻤﺎت ﻣﺤﻠﻲ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﺮ ﻧﺤﻮه ﻧﻤﺎﻳﺶ ﻣﺘﻐﻴﻴﺮ ﻫﺎ اﺳﺖ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﺗﻨﻈﻴﻤﺎت ﻣﺤﻠﻲ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺧﻮد را ﺑﺮاﺑـﺮ اﻧﮕﻠـﻴﺲ ﻗـﺮار دﻫﻴـﺪ، ﺗﺎرﻳﺦ در ﻗﺎﻟﺐ DD/MM/YYYYو زﻣﺎن ﻧﻴﺰ ﺑﻪ ﺻﻮرت 24ﺳﺎﻋﺘﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد. اﻟﺒﺘﻪ ﻣﻴﺘﻮاﻧﻴﺪ ﻧﺤﻮه ﻧﻤﺎﻳﺶ ﺗﺎرﻳﺦ را در ﺑﺮﻧﺎﻣﻪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﺗﺎ در ﻫﺮ ﺳﻴﺴﺘﻢ ﺑﺎ ﻫﺮ ﺗﻨﻈﻴﻤﺎت ﻣﺤﻠﻲ ﺑﻪ ﻳﻚ ﺻﻮرت ﻧﻤـﺎﻳﺶ داده ﺷـﻮد، اﻣﺎ ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ اﺟﺎزه دﻫﻴﺪ .NETﻧﺤﻮه ﻧﻤﺎﻳﺶ را ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻧﺘﺨﺎب ﻛﻨﺪ ،ﺗﺎ ﻫﺮ ﻛﺎرﺑﺮ ﺑﻪ ﻫﺮ ﻧﺤـﻮي ﻛـﻪ ﺑﺨﻮاﻫـﺪ آن را ﻣﺸﺎﻫﺪه ﻛﻨﺪ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺎ ﭼﻬﺎر روش ﻣﻔﻴﺪ ﺑﺮاي ﻗﺎﻟﺐ ﺑﻨﺪي ﺗﺎرﻳﺨﻬﺎ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻗﺎﻟﺐ ﺑﻨﺪي ﺗﺎرﻳﺨﻬﺎ 1اﻳﻦ در ﺣﺎﻟﺘﻲ اﺳﺖ ﻛﻪ ﻣﺘﻐﻴﻴﺮ ﺑﺘﻮاﻧﺪ ﺑﻪ رﺷﺘﻪ ﺗﺒﺪﻳﻞ ﺷﻮد .ﺑﻌﻀﻲ از ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﻛﻪ در ﻓﺼﻠﻬﺎي ﺑﻌﺪي ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﻣﻴﺸﻮﻳﻢ ﻧﻤﻴﺘﻮاﻧﻨﺪ ﺑﻪ رﺷﺘﻪ ﺗﺒـﺪﻳﻞ ﺷـﻮﻧﺪ .در اﻳـﻦ ﺻﻮرت ،اﻳﻦ ﺗﺎﺑﻊ رﺷﺘﻪ اي را ﺑﺮﻣﻴﮕﺮداﻧﺪ ﻛﻪ ﻣﻌﺮف ﻣﺘﻐﻴﻴﺮ ﻣﻮرد ﻧﻈﺮ اﺳﺖ.
٨٦
(1اﮔﺮ ﺑﺮﻧﺎﻣﻪ Date Demoدر ﺣﺎل اﺟﺮا اﺳﺖ آن را ﺑﺒﻨﺪﻳﺪ. (2ﺑﺎ اﺳﺘﻔﺎده از وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﺑﺮاي ،Form1ﺗﺎﺑﻊ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickدﻛﻤﻪ ﻓﺮﻣﺎن را ﭘﻴﺪا ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ: // Display the results MessageBox.Show("Current Date is: " + dteDate, ;)""Date Demo // Display dates MessageBox.Show(dteDate.ToLongDateString(), ;)""Date Demo MessageBox.Show(dteDate.ToShortDateString(), ;)""Date Demo // Display times MessageBox.Show(dteDate.ToLongTimeString(), ;)""Date Demo MessageBox.Show(dteDate.ToShortTimeString(), ;)""Date Demo } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﺑﺎ ﻛﻠﻴﻚ ﺑﺮ روي دﻛﻤﻪ ،Show Dateﭘﻨﺞ ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﻣﻴﺸﻮﻧﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣـﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،ﻛﺎدر ﭘﻴﻐﺎم اول ﺗﺎرﻳﺦ و زﻣﺎن را ﺑﺮ اﺳﺎس ﺗﻨﻈﻴﻤﺎت ﻣﺤﻠﻲ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺷﻤﺎ ﻧﻤـﺎﻳﺶ ﻣﻴﺪﻫـﺪ .ﻛـﺎدر دوم ﺗـﺎرﻳﺦ را ﺑـﻪ ﺻﻮرت ﻛﺎﻣﻞ و ﻛﺎدر ﺳﻮم ﺗﺎرﻳﺦ را ﺑﻪ ﺻﻮرت ﺧﻼﺻﻪ ﺷﺪه ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .ﻛﺎدر ﭼﻬﺎرم زﻣﺎن را ﺑﻪ ﺻـﻮرت ﻛﺎﻣـﻞ و ﻛـﺎدر آﺧﺮ زﻣﺎن ﺑﻪ ﺻﻮرت ﻣﺨﺘﺼﺮ ﻧﻤﺎﻳﺶ ﻣﻴﺪﻫﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ ﻫﻴﭻ ﻧﻘﻄﻪ ﻣﺒﻬﻤﻲ وﺟﻮد ﻧﺪارد و ﻧﺎم ﺗﻮاﺑﻊ ﺑﻪ اﻧﺪازه ﻛﺎﻓﻲ واﺿﺢ ﻫﺴﺘﻨﺪ و ﻣﺸﺨﺺ ﻣﻴﻜﻨﻨﺪ ﻛﻪ ﻫﺮ ﺗﺎﺑﻊ ﭼﻪ ﻛـﺎري اﻧﺠـﺎم ﻣﻴﺪﻫﺪ: // Display dates ;)"MessageBox.Show(dteDate.ToLongDateString(), "Date Demo ;)"MessageBox.Show(dteDate.ToShortDateString(),"Date Demo // Display times ;)"MessageBox.Show(dteDate.ToLongTimeString(), "Date Demo ;)"MessageBox.Show(dteDate.ToShortTimeString(),"Date Demo
٨٧
:DateTime اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺘﻬﺎي در. ﻣﻴﺘﻮاﻧﻴﺪ از ﺧﺎﺻﻴﺘﻬﺎي ﮔﻮﻧﺎﮔﻮﻧﻲ ﻛﻪ اراﺋـﻪ ﻣـﻲ دﻫـﺪ اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ، داﺷﺘﻪ ﺑﺎﺷﻴﺪDateTime ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع . ﺑﺎ ﻗﺴﻤﺘﻲ از آﻧﻬﺎ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ،اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ
DateTime اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺘﻬﺎي:اﻣﺘﺤﺎن ﻛﻨﻴﺪ . آن را ﺑﺒﻨﺪﻳﺪ، در ﺣﺎل اﺟﺮا اﺳﺖDate Demo ( اﮔﺮ ﺑﺮﻧﺎﻣﻪ1 آن را ﺑﺮاﺑـــــﺮName ﺧﺎﺻـــــﻴﺖ، اﺿـــــﺎﻓﻪ ﻛﻨﻴـــــﺪForm1 دﻳﮕـــــﺮي ﺑـــــﻪButton ( ﻛﻨﺘـــــﺮل2 روي. ﻗـﺮار دﻫﻴـﺪDate Properties آن را ﺑﺮاﺑﺮText و ﺧﺎﺻﻴﺖbtnDateProperties :دﻛﻤﻪ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ اﻳﺠﺎد ﺷﺪه وارد ﻛﻨﻴﺪ private void btnDateProperties_Click(object sender, EventArgs e) { // Declare variable DateTime dteDate; // Get the current date and time dteDate = DateTime.Now; // Display the various properties MessageBox.Show("Month: " + dteDate.Month, "Date Demo"); MessageBox.Show("Day: " + dteDate.Day, "Date Demo"); MessageBox.Show("Year: " + dteDate.Year, "Date Demo"); MessageBox.Show("Hour: " + dteDate.Hour, "Date Demo"); MessageBox.Show("Minute: " + dteDate.Minute, "Date Demo"); MessageBox.Show("Second: " + dteDate.Second, "Date Demo"); MessageBox.Show("Day of week: " + dteDate.DayOfWeek, "Date Demo"); MessageBox.Show("Day of year: " + dteDate.DayOfYear, "Date Demo"); } ﻳﻚ ﺳﺮي ﻛﺎدرﻫﺎي ﭘﻴﻐﺎم ﻣﺘﻮاﻟﻲ را ﺧﻮاﻫﻴﺪ دﻳﺪ ﻛﻪ ﭘﻴﻐـﺎم ﻫـﺎي.( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ ﻓﺮﻣﺎن ﺟﺪﻳﺪ ﻛﻠﻴﻚ ﻛﻨﻴﺪ3 .واﺿﺤﻲ را ﻧﻤﺎﻳﺶ ﻣﻴﺪﻫﻨﺪ
٨٨
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻨﺪ ﻗﺴﻤﺖ ﻗﺒﻞ ،در اﻳﻦ ﻣﺜﺎل ﻫﻢ ﻧﻜﺘﻪ ﻣﺒﻬﻤﻲ وﺟﻮد ﻧﺪارد ﻛﻪ ﻧﻴﺎز ﺑﻪ ﺗﻮﺿﻴﺢ داﺷﺘﻪ ﺑﺎﺷﺪ .ﺧﻮد ﺗﻮاﺑﻊ ﺑﻪ اﻧﺪازه ﻛﺎﻓﻲ واﺿـﺢ ﻫـﺴﺘﻨﺪ. ﺑﺮاي اﺳﺘﻔﺎده از ﺳﺎﻋﺖ ،از ﺧﺎﺻﻴﺖ ،Hourﺑﺮاي اﺳﺘﻔﺎده از ﺳﺎل از ﺧﺎﺻﻴﺖ Yearو ...اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
ﻛﺎر ﺑﺎ ﺗﺎرﻳﺨﻬﺎ: ﻳﻜﻲ از ﻣﻮاردي ﻛﻪ ﻛﻨﺘﺮل آن ﻫﻤﻴﺸﻪ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﻣﺸﻜﻞ ﺑﻮده اﺳﺖ ،ﻛﺎر ﺑﺎ ﺗﺎرﻳﺨﻬﺎ اﺳﺖ .ﻳﻜﻲ از اﻳـﻦ ﻧﻤﻮﻧـﻪ ﻣـﺸﻜﻼت ﻛـﻪ ﻣﻤﻜﻦ اﺳﺖ ﻫﻨﮕﺎم ﻛﺎر ﺑﺎ ﺗﺎرﻳﺦ در ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﻳﺠﺎد ﺷﻮد ،ﻣﺸﻜﻞ ﺳﺎل 2000ﺑﻮد ﻛﻪ در آن ﻫﻤﻪ ﻣﺮدم ﻣﻨﺘﻈﺮ ﺑﻮدﻧﺪ ﺗﺎ ﺑﺒﻴﻨﻨﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﺎﻣﭙﻴﻮﺗﺮي ﭼﮕﻮﻧﻪ ﺑﺎ اﻳﻦ ﻣﺸﻜﻞ روﺑﺮو ﻣﻲ ﺷﻮﻧﺪ .ﻳﺎ ﻣﺜﻼ ،ﻛﺎر ﺑﺎ ﺳﺎﻟﻬﺎي ﻛﺒﻴﺴﻪ ﻫﻤﻮاره ﻣﺸﻜﻼت زﻳﺎدي را در ﺑﺮﻧﺎﻣﻪ ﻫـﺎ اﻳﺠـﺎد ﻛـﺮده اﺳﺖ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺗﻌﺪادي از ﺗﻮاﺑﻊ و ﻣﺘﺪﻫﺎي ﻧﻮع داده اي Dateﻛﻪ ﻣﻮﺟﺐ ﺳﺎده ﺗﺮ ﺷﺪن ﻛﺎر ﺑﺎ ﺳﺎﻟﻬﺎي ﻛﺒﻴﺴﻪ در ﺑﺮﻧﺎﻣـﻪ ﻣﻲ ﺷﻮد را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻛﺎر ﺑﺎ ﺗﺎرﻳﺨﻬﺎي ﺧﺎص (1اﮔﺮ ﺑﺮﻧﺎﻣﻪ Date Demoدر ﺣﺎل اﺟﺮا اﺳﺖ آن را ﺑﺒﻨﺪﻳﺪ. (2دﻛﻤﻪ ﻓﺮﻣﺎن دﻳﮕﺮي ﺑﻪ ﻓﺮم ﺧﻮد اﺿﺎﻓﻪ ﻛﻨﻴﺪ ،ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑـﺮ btnDateManipulationو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ Date Manipulationﻗﺮار دﻫﻴﺪ .روي دﻛﻤﻪ ﻓﺮﻣﺎن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛـﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ اﻳﺠﺎد ﺷﺪه وارد ﻛﻨﻴﺪ: private void btnDateManipulation _Click(object sender, )EventArgs e { // Declare variables ;DateTime dteStartDate ;DateTime dteChangedDate // Start off in 2400 ;)dteStartDate = new DateTime(2400, 2, 28 // Add a day and display the results ;)dteChangedDate = dteStartDate.AddDays(1 MessageBox.Show(dteChangedDate.ToLongDateString(), ;)""Date Demo // Add some months and display the results
٨٩
dteChangedDate = dteStartDate.AddMonths(6); MessageBox.Show(dteChangedDate.ToLongDateString(), "Date Demo"); // Subtract a year and display the results dteChangedDate = dteStartDate.AddYears(-1); MessageBox.Show(dteChangedDate.ToLongDateString(), "Date Demo"); } ﻛـﺎدر ﭘﻴﻐـﺎم اوﻟـﻲ ﺗـﺎرﻳﺦ. ﺳﻪ ﻛـﺎدر ﭘﻴﻐـﺎم را ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛـﺮد.( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ ﻓﺮﻣﺎن ﻛﻠﻴﻚ ﻛﻨﻴﺪ3 . را ﻧﻤﺎﻳﺶ ﺧﻮاﻫﺪ داد2399/2/28 و ﻛﺎدر ﭘﻴﻐﺎم ﺳﻮم،2400/8/28 ﻛﺎدر ﭘﻴﻐﺎم دوﻣﻲ ﺗﺎرﻳﺦ،2400/2/29
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ : در زﻳﺮ ﺳﻪ ﻧﻤﻮﻧﻪ از آﻧﻬﺎ آﻣﺪه اﺳﺖ. ﻣﺘﺪﻫﺎي زﻳﺎدي ﺑﺮاي ﻛﺎر ﺑﺮ روي ﺗﺎرﻳﺦ داردDateTime ﻧﻮع داده اي // Add a day and display the results dteChangedDate = dteStartDate.AddDays(1); MessageBox.Show(dteChangedDate.ToLongDateString(), "Date Demo"); // Add some months and display the results dteChangedDate = dteStartDate.AddMonths(6); MessageBox.Show(dteChangedDate.ToLongDateString(), "Date Demo"); // Subtract a year and display the results dteChangedDate = dteStartDate.AddYears(-1); MessageBox.Show(dteChangedDate.ToLongDateString(), "Date Demo"); ﺑﺮاي ﻛﻢ ﻛﺮدن از اﻳـﻦ ﻣﻘـﺎدﻳﺮ، ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻴﻜﻨﻴﺪ. ﻣﺎه و ﻳﺎ ﺳﺎل ﺑﻪ ﺗﺎرﻳﺦ ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ،اﻳﻦ ﺗﻮاﺑﻊ ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن روز ،AddHours : ﻣﺘــﺪﻫﺎي ﻣﻬــﻢ دﻳﮕــﺮ در اﻳــﻦ ﻧــﻮع داده اي ﻋﺒﺎرﺗﻨــﺪ از.ﻳــﻚ ﻋــﺪد ﻣﻨﻔــﻲ را ﺑــﻪ اﻳــﻦ ﺗﻮاﺑــﻊ ارﺳــﺎل ﻛــﺮده اﻳــﻢ .AddMiliseconds وAddSeconds ،AddMinutes
:ﺑﻮﻟﻴﻦ
٩٠
ﺗﺎﻛﻨﻮن ﺑﺎ ﻧﻮع ﻫـﺎي داده اي String ،Double ،float ،intو DateTimeآﺷـﻨﺎ ﺷـﺪﻳﺪ .ﻧـﻮع داده اي ﻣﻬـﻢ دﻳﮕﺮي ﻛﻪ ﺑﺎﻳﺪ ﻧﺤﻮه ﻛﺎر ﺑﺎ آن را ﺑﺪاﻧﻴﺪ Boolean ،اﺳﺖ .ﺑﻌﺪ از اﺗﻤﺎم اﻳﻦ ﻧﻮع داده اي،ﺑﺎ ﭘﺮﻛﺎرﺑﺮد ﺗـﺮﻳﻦ ﻧـﻮع ﻫـﺎي داده اي در .NETآﺷﻨﺎ ﺷﺪه اﻳﺪ. ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑﻮﻟﻴﻦ ﻣﻲ ﺗﻮاﻧﺪ ﻣﻘﺎدﻳﺮ ) Trueدرﺳﺖ( و ﻳـﺎ ) Falseﻏﻠـﻂ( را داﺷـﺘﻪ ﺑﺎﺷـﺪ .ﻣﺘﻐﻴﻴـﺮ ﻫـﺎي Booleanﺑﻴـﺸﺘﺮ ﻫﻨﮕﺎﻣﻲ اﻫﻤﻴﺖ ﺧﻮد را ﻧﺸﺎن ﻣﻲ دﻫﻨﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺑﺨﻮاﻫﺪ ﺻﺤﺖ ﻳﻚ ﺷﺮط را ﺑﺮرﺳﻲ ﻛﻨﺪ )ﺑﺎ ﺑﺮرﺳﻲ ﺷﺮط ﻫﺎ در ﻓـﺼﻞ 4ﺑﻴـﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ(.
ﻧﮕﻬﺪاري ﻣﺘﻐﻴﻴﺮ ﻫﺎ: ﻋﻤﻮﻣﺎ ﻣﺤﺪود ﺗﺮﻳﻦ ﻗﺴﻤﺖ ﻳﻚ ﺳﻴﺴﺘﻢ ،ﺣﺎﻓﻈﻪ آن اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺑﺎﻳﺪ ﺑـﻪ ﺑﻬﺘـﺮﻳﻦ و ﻛﺎرآﻣـﺪ ﺗـﺮﻳﻦ ﻧﺤـﻮ از اﻳـﻦ ﻗـﺴﻤﺖ اﺳﺘﻔﺎده ﻛﻨﺪ .زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ )از ﻫﺮ ﻧﻮﻋﻲ( ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ،ﻗﺴﻤﺘﻲ از ﺣﺎﻓﻈﻪ را اﺷﻐﺎل ﻛﺮده اﻳﺪ .ﺑﻨﺎﺑﺮاﻳﻦ در ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴﺮ ﻫـﺎ ﺑﺎﻳـﺪ دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻫﻢ ﻛﻤﺘﺮﻳﻦ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ ﻣﻤﻜﻦ را ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ و ﻫﻢ ﺑﻪ ﺑﻬﺘﺮﻳﻦ ﻧﺤﻮ از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ. اﻣﺮوزه ،ﺑﻪ دو دﻟﻴﻞ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﺷﻤﺎ از ﺟﺰﺋﻴﺎت ﻛﺎﻣﻞ ﺑﻬﻴﻨﻪ ﺳﺎزي ﻣﺘﻐﻴﻴﺮ ﻫﺎ آﮔﺎه ﺑﺎﺷﻴﺪ .دﻟﻴـﻞ اول اﻳـﻦ اﺳـﺖ ﻛـﻪ ﻛﺎﻣﭙﻴﻮﺗﺮﻫـﺎي اﻣﺮوزي ﻣﻘﺪار زﻳﺎدي ﺣﺎﻓﻈﻪ دارﻧﺪ .از زﻣﺎﻧﻲ ﻛﻪ ﻻزم ﺑﻮد ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ،ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد را در 32ﻛﻴﻠﻮ ﺑﺎﻳـﺖ از ﺣﺎﻓﻈـﻪ ﻛـﺎﻣﭙﻴﻮﺗﺮ ﺟـﺎ ﺑﺪﻫﻨﺪ ﺧﻴﻠﻲ ﮔﺬﺷﺘﻪ اﺳﺖ .دﻟﻴﻞ دﻳﮕﺮ اﻳﻦ اﺳﺖ ﻛﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎي اﻣﺮوزي ﺑﻪ ﺻﻮرت دروﻧﻲ ،ﺑﻪ اﻧﺪازه ﻛﺎﻓﻲ در اﻳﻦ زﻣﻴﻨﻪ ﻫﻮﺷﻤﻨﺪ ﻋﻤﻞ ﻣﻴﻜﻨﻨﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ،ﻛﺪﻫﺎي ﺗﻮﻟﻴﺪ ﺷﺪه ﺗﻮﺳﻂ آﻧﻬﺎ ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﺑﻬﻴﻨﻪ ﻣﻴﺸﻮد ﺗﺎ ﺑﻬﺘﺮﻳﻦ ﻛﺎراﻳﻲ را داﺷﺘﻪ ﺑﺎﺷﻨﺪ.
دودوﻳﻲ: ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎ ﺑﺮاي ﻧﮕﻬﺪاري ﻫﺮ اﻃﻼﻋﺎﺗﻲ از ﺳﻴﺴﺘﻢ دودوﻳﻲ اﺳﺘﻔﺎده ﻣﻴﻜﻨﻨﺪ .در ﺣﻘﻴﻘﺖ ﻫﺮ داده اي را ﻛﻪ ﺷـﻤﺎ در ﻛـﺎﻣﭙﻴﻮﺗﺮ ﻧﮕﻬـﺪاري ﻣﻴﻜﻨﻴﺪ ﺑﺎﻳﺪ در ﻗﺎﻟﺐ ﺻﻔﺮ و ﻳﻚ ذﺧﻴﺮه ﺷﻮﻧﺪ .ﺑﺮاي ﻧﻤﻮﻧﻪ ﻋﺪد ﺻﺤﻴﺢ 27را در ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ .در ﺳﻴﺴﺘﻢ ﺑﺎﻳﻨﺮي ﻳﺎ دودوﻳﻲ اﻳﻦ ﻋﺪد ﺑـﻪ ﺻﻮرت 11011ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ،ﻛﻪ ﻫﺮ ﻛﺪام از اﻳﻦ اﻋﺪاد در ﺗﻮاﻧﻲ از دو ﺿﺮب ﻣﻴﺸﻮﻧﺪ .ﻧﻤﻮدار ﺷﻜﻞ 12-3ﺑﻪ ﺷﻤﺎ ﻛﻤﻚ ﻣﻴﻜﻨﺪ ﺗﺎ ﻋﺪد 27را ﺑﻬﺘﺮ در ﺳﻴﺴﺘﻢ ده دﻫﻲ و در ﺳﻴﺴﺘﻢ دودوﻳﻲ ﻳﺎ ﺑﺎﻳﻨﺮي ﻧﻤﺎﻳﺶ دﻫﻴﺪ. ﻣﻤﻜﻦ اﺳﺖ در اﺑﺘﺪا اﻳﻦ ﻣﻮرد ﻣﻘﺪاري ﻧﺎﻣﻔﻬﻮم ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ .در ﻣﺒﻨﺎي 10ﻳﺎ ﻫﻤﺎن ﺳﻴﺴﺘﻢ ده دﻫﻲ ﻛﻪ ﺑﺎ آن آﺷﻨﺎ ﻫﺴﺘﻴﺪ ،ﺑﺮاي ﺗﻌﻴﻴﻦ ارزش ﻫﺮ ﻋﺪد ،ﻫﺮ رﻗﻢ از آن در ﺗﻮاﻧﻲ از ده ﺿﺮب ﻣﻴﺸﻮد .اوﻟﻴﻦ رﻗﻢ ﻋﺪد از ﺳﻤﺖ راﺳﺖ در ده ﺑﻪ ﺗﻮان ﺻﻔﺮ ﺿﺮب ﻣﻴﺸﻮد ،ﻋـﺪد دوم در ده ﺑﻪ ﺗﻮان ﻳﻚ ﺿﺮب ﻣﻴﺸﻮد ،ﻋﺪد ﺳﻮم در ده ﺑﻪ ﺗﻮان دو ﺿﺮب ﻣﻴﺸﻮد و ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴﺐ اداﻣﻪ ﭘﻴﺪا ﻣﻴﻜﻨﺪ. ﻫﻤﻴﻦ روش در ﺳﻴﺴﺘﻢ ﺑﺎﻳﻨﺮي ﻫﻢ وﺟﻮد دارد .ﺑﺮاي ﺗﺒﺪﻳﻞ ﻳﻚ ﻋﺪد در ﻣﺒﻨﺎي دو ﺑﻪ ﻳﻚ ﻋﺪد در ﻣﺒﻨـﺎي ده ،ﺑﺎﻳـﺪ رﻗﻤﻬـﺎ را از ﺳـﻤﺖ راﺳﺖ ﻳﻜﻲ ﻳﻜﻲ ﺟﺪا ﻛﻨﻴﺪ و در دو ﺑﻪ ﺗﻮان ﺷﻤﺎره ﻣﻜﺎن ﻋﺪد ﺿﺮب ﻛﻨﻴﺪ )ﻋﺪد اول از ﺳﻤﺖ راﺳﺖ در ﻣﻜﺎن ﺻﻔﺮم ،ﻋﺪد دوم در ﻣﻜﺎن ﻳﻜﻢ و ...ﻗﺮار دارد( .ﺳﭙﺲ ﺗﻤﺎم اﻋﺪاد ﺑﻪ دﺳﺖ آﻣﺪه را ﺑﺎ ﻫﻢ ﺟﻤﻊ ﻛﻨﻴﺪ .ﻋﺪدي ﻛﻪ ﺑﻪ دﺳﺖ ﻣﻲ آﻳـﺪ ،ﻧﻤـﺎﻳﺶ دﻫﻨـﺪه ﻫﻤـﺎن ﻋـﺪد در ﻣﺒﻨﺎي ده اﺳﺖ.
٩١
در ﻣﺒﻨﺎي 10ﻫﺮ رﻗﻢ ﺿﺮﻳﺒﻲ از ﻳﻜﻲ از ﺗﻮاﻧﻬﺎي 10اﺳﺖ .ﺑﺮاي اﻳﻨﻜﻪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻳﻚ رﺷﺘﻪ از ارﻗﺎم ﻛﻪ در ﻣﺒﻨﺎي 10ﻧﻮﺷـﺘﻪ ﺷـﺪه اﻧﺪ ﭼﻪ ﻋﺪدي را ﻧﺸﺎن ﻣﻲ دﻫﻨﺪ ،ﻛﺎﻓﻲ اﺳﺖ رﻗﻢ اول را در 10ﺑﻪ ﺗﻮان ،0رﻗﻢ دوم را در 10ﺑﻪ ﺗﻮان 1و ...ﺿﺮب ﻛﺮده و ﺣﺎﺻﻞ را ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﺟﻤﻊ ﻛﻨﻴﺪ.
در ﻣﺒﻨﺎي 2ﻳﺎ اﻋﺪاد ﺑﺎﻳﻨﺮي ،ﻫﺮ رﻗﻢ ﺿﺮﻳﺒﻲ از ﻳﻜﻲ از ﺗﻮاﻧﻬﺎي 2اﺳﺖ .ﺑﺮاي ﺗﺸﺨﻴﺺ اﻳﻨﻜﻪ ﻳﻚ رﺷﺘﻪ ارﻗﺎم در ﻣﺒﻨﺎي 2ﭼﻪ ﻋـﺪدي را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻨﺪ ،ﺑﺎﻳﺪ رﻗﻢ اول را در 2ﺑﻪ ﺗﻮان ،0رﻗﻢ دوم را در 2ﺑﻪ ﺗﻮان 1و ...ﺿﺮب ﻛﺮده و ﺣﺎﺻﻞ را ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﺟﻤﻊ ﻛﺮد. ﺷﻜﻞ 12-3
ﺑﻴﺘﻬﺎ و ﺑﺎﻳﺖ ﻫﺎ: در اﺻﻄﻼﺣﺎت ﻛﺎﻣﭙﻴﻮﺗﺮي ،ﺑﻪ ﻳﻚ رﻗﻢ ﺑﺎﻳﻨﺮي ،ﻳﻚ ﺑﻴﺖ ﻣﻴﮕﻮﻳﻨﺪ .ﻳﻚ ﺑﻴﺖ ﻛﻮﭼﻜﺘﺮﻳﻦ ﺑﺨﺶ ﻣﻤﻜﻦ ﺑﺮاي ﻧﻤﺎﻳﺶ داده اﺳـﺖ و ﻓﻘـﻂ ﻣﻴﺘﻮاﻧﺪ داراي ﻣﻘﺪار درﺳﺖ و ﻳﺎ ﻏﻠﻂ ﺑﺎﺷﺪ .اﻳﻦ ﻣﻘﺪار در ﻣﺪارﻫﺎي ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﻪ وﺳﻴﻠﻪ وﺟﻮد داﺷﺘﻦ و ﻳﺎ وﺟﻮد ﻧﺪاﺷﺘﻦ ﺟﺮﻳـﺎن ﻣـﺸﺨﺺ ﻣﻲ ﺷﻮد .دﻟﻴﻞ اﻳﻨﻜﻪ در ﻫﺮ ﻗﺴﻤﺖ از ﺷﻜﻞ 12-3ﻫﺸﺖ ﺑﻴﺖ در ﻛﻨﺎر ﻫﻢ ﻧﺸﺎن داده ﺷﺪه اﻧﺪ ،اﻳﻦ اﺳﺖ ﻛﻪ ﻫﺮ ﻫـﺸﺖ ﺑﻴـﺖ در ﻛﻨـﺎر ﻫﻢ ﻳﻚ ﺑﺎﻳﺖ را ﺗﺸﻜﻴﻞ ﻣﻲ دﻫﻨﺪ .ﺑﺎﻳﺖ واﺣﺪ اﻧﺪازه ﮔﻴﺮي ﺣﺎﻓﻈﻪ ﻫﺎي ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﻪ ﺷﻤﺎر ﻣﻴﺮود. ﻳﻚ ﻛﻴﻠﻮ ﺑﺎﻳﺖ ﻳﺎ KBاز 1024ﺑﺎﻳﺖ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ .دﻟﻴﻞ اﻳﻨﻜﻪ ﺑﻪ ﺟﺎي 1000از 1024ﺑﺎﻳﺖ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ ،اﻳـﻦ اﺳـﺖ ﻛـﻪ 1024ﺗﻮاﻧﻲ از دو اﺳﺖ ) دو ﺑﻪ ﺗﻮان ده( .ﺑﻪ دﻟﻴﻞ اﻳﻨﻜﻪ اﻋﺪاد در ﻛﺎﻣﭙﻴﻮﺗﺮ در ﻣﺒﻨﺎي دو ذﺧﻴﺮه ﻣﻴﺸﻮﻧﺪ ،ﻧﮕﻬـﺪاري 1024راﺣـﺖ ﺗـﺮ از ﻧﮕﻬﺪاري 1000اﺳﺖ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻧﮕﻬﺪاري 1000ﺑﺮاي ﺷﻤﺎ ﻛﻪ از ﺳﻴﺴﺘﻢ ده دﻫﻲ اﺳﺘﻔﺎده ﻣﻴﻜﻨﻴﺪ راﺣﺖ ﺗﺮ از 1024اﺳﺖ. ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴﺐ ﻳﻚ ﻣﮕﺎ ﺑﺎﻳﺖ ﻳﺎ MBﺑﺮاﺑﺮ 1024ﻛﻴﻠﻮ ﺑﺎﻳﺖ ﻳﺎ 1048576ﺑﺎﻳﺖ ،ﻳﻚ ﮔﻴﮕﺎ ﺑﺎﻳﺖ 1024ﻣﮕﺎ ﺑﺎﻳـﺖ ﻳـﺎ 1073741824 ﺑﺎﻳﺖ اﺳﺖ )دو ﺑﻪ ﺗﻮان ﺳﻲ( .ﻫﻤﭽﻨﻴﻦ ﺗﺮا ﺑﺎﻳﺖ ﺑﺮاﺑﺮ دو ﺑﻪ ﺗﻮان ﭼﻬﻞ و ﭘﺘﺎ ﺑﺎﻳﺖ ﺑﺮاﺑﺮ دو ﺑﻪ ﺗﻮان ﭘﻨﺠﺎه اﺳﺖ. ﻫﻤﻪ اﻳﻦ ﻣﻄﺎﻟﺐ ﺑﻪ ﭼﻪ ﻛﺎر ﻣﻲ آﻳﺪ؟ ﺧﻮب ،داﻧﺴﺘﻦ اﻳﻦ ﻛﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﭼﮕﻮﻧﻪ اﻃﻼﻋﺎت را ذﺧﻴﺮه ﻣﻴﻜﻨﺪ ﻣﻤﻜﻦ اﺳﺖ ﺑﻪ ﺷﻤﺎ ﻛﻤـﻚ ﻛﻨـﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد را ﺑﻬﺘﺮ ﻃﺮاﺣﻲ ﻛﻨﻴﺪ .ﻓﺮض ﻛﻨﻴﺪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺷﻤﺎ 256ﻣﮕﺎ ﺑﺎﻳﺖ ﺣﺎﻓﻈﻪ دارد .اﻳﻦ ﻣﻘﺪار ﺣﺎﻓﻈﻪ ﺑﺮاﺑـﺮ 2147483648 ﺑﺎﻳﺖ اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺣﺎل ﻧﻮﺷﺘﻦ ﻧﺮم اﻓﺰار ﻫﺴﺘﻴﺪ ﺑﺎﻳﺪ ﺳﻌﻲ ﻛﻨﻴﺪ ﻛﻪ از ﺣﺎﻓﻈﻪ ﺑﻪ ﺑﻬﺘﺮﻳﻦ ﻧﺤﻮ ﻣﻤﻜﻦ اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
ﻧﻤﺎﻳﺶ ﻣﻘﺎدﻳﺮ:
٩٢
ﺑﻴﺸﺘﺮ ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎي اﻣﺮوزي 32ﺑﻴﺘﻲ ﻫﺴﺘﻨﺪ ،ﻳﻌﻨﻲ در ﻫﺮ ﻟﺤﻈﻪ ﻣﻴﺘﻮاﻧﻨﺪ ﺑﺎ داده ﻫﺎﻳﻲ ﺑﻪ ﻃﻮل 32ﺑﻴﺖ ﻛﺎر ﻛﻨﻨﺪ .اﻋﺪادي ﻛﻪ در ﺑﺨﺶ ﻗﺒﻠﻲ دﻳﺪﻳﺪ ﻫﻤﮕﻲ اﻋﺪاد ﻫﺸﺖ ﺑﻴﺘﻲ ﺑﻮدﻧﺪ .در ﻳﻚ ﻋﺪد ﻫﺸﺖ ﺑﻴﺘﻲ ﺣﺪاﻛﺜﺮ ﻣﻘﺪاري را ﻛﻪ ﻣﻲ ﺗﻮان ﻧﮕﻬـﺪاري ﻛـﺮد ﺑـﻪ ﺻـﻮرت زﻳـﺮ اﺳﺖ: 1*128 + 1*64 + 1*32 + 1*16 + 1*8 + 1*4 + 1*2 + 1*1 = 256 ﻫﺮ ﻋﺪد 32ﺑﻴﺘﻲ ﻣﻲ ﺗﻮاﻧﺪ ﻣﻘﺎدﻳﺮي در ﻣﺤﺪوده -2147483647ﺗﺎ 2147483647را ﻧﮕﻬﺪاري ﻛﻨـﺪ .ﺣـﺎل اﮔـﺮ ﺑﺨﻮاﻫﻴـﺪ ﻳـﻚ ﻋـﺪد ﺻﺤﻴﺢ را ﻧﮕﻬﺪاري ﻛﻨﻴﺪ ﻣﺘﻐﻴﻴﺮي را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻌﺮﻳﻒ ﻣﻴﻜﻨﻴﺪ: ;int intNumber در اﻳﻨﺠﺎ 32 .NET ،ﺑﻴﺖ از ﺣﺎﻓﻈﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ را ﺑﺮاي اﻳﻦ ﻣﺘﻐﻴﻴﺮ اﺧﺘﺼﺎص ﻣﻴﺪﻫﺪ ﻛﻪ ﺷﻤﺎ ﻣﻴﺘﻮاﻧﻴﺪ اﻋﺪاد در ﺑﺎزه اي ﻛﻪ ﮔﻔﺘـﻪ ﺷـﺪ را در آن ذﺧﻴﺮه ﻛﻨﻴﺪ .اﻣﺎ ﺑﻪ ﺧﺎﻃﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻣﻘﺪار ﺣﺎﻓﻈﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺷﻤﺎ ﻣﺤﺪود اﺳﺖ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ 256ﻣﮕﺎﺑﺎﻳـﺖ ﺣﺎﻓﻈـﻪ داﺷـﺘﻪ ﺑﺎﺷﺪ ،ﻣﻴﺘﻮاﻧﻴﺪ 67108864ﻋﺪد ﺻﺤﻴﺢ را در آن ﻧﮕﻬﺪاري ﻛﻨﻴﺪ .ﻣﻤﻜﻦ اﺳﺖ زﻳﺎد ﺑﻪ ﻧﻈﺮ ﺑﺮﺳـﺪ .اﻣـﺎ ﺑﺎﻳـﺪ دو ﻧﻜﺘـﻪ را در ﻧﻈـﺮ داﺷـﺘﻪ ﺑﺎﺷﻴﺪ .اول اﻳﻨﻜﻪ ﺑﻌﻀﻲ از ﻣﺘﻐﻴﻴﺮﻫﺎ ﻛﻪ در ﻓﺼﻠﻬﺎي ﺑﻌﺪي ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﻣﻴﺸﻮﻳﻢ ﺑﺴﻴﺎر ﺑﻴﺸﺘﺮ از ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ ﻓﻀﺎ اﺷـﻐﺎل ﻣـﻲ ﻛﻨﻨـﺪ. دوم اﻳﻨﻜﻪ ﺑﻪ ﺧﺎﻃﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﺣﺎﻓﻈﻪ ﺑﻴﻦ ﻫﻤﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﺸﺘﺮك اﺳﺖ و ﻧﺒﺎﻳﺪ آن را ﻫﺪر ﺑﺪﻫﻴﺪ. ﻫﻤﭽﻨﻴﻦ ﺑﺮاي ﻧﮕﻬﺪاري ﻳﻚ ﻋﺪد اﻋﺸﺎري ﺑﺎ دﻗﺖ ﻣﻀﺎﻋﻒ ،ﻣﺘﻐﻴﻴﺮي ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻌﺮﻳﻒ ﻣﻴﻜﺮدﻳﺪ: ;double dblNumber ﺑﺮاي ﻧﮕﻬﺪاري ﻳﻚ ﻋﺪد اﻋﺸﺎري ﺑﺎ دﻗﺖ ﻣﻀﺎﻋﻒ ﺑﻪ 64ﺑﻴﺖ از ﺣﺎﻓﻈﻪ ﻧﻴﺎز دارﻳﺪ .ﻳﻌﻨﻲ ﻣﻴﺘﻮاﻧﻴﺪ ﺣﺪاﻛﺜﺮ 33554432ﻋﺪد اﻋـﺸﺎري ﺑـﺎ دﻗﺖ ﻣﻀﺎﻋﻒ در ﺣﺎﻓﻈﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺧﻮد داﺷﺘﻪ ﺑﺎﺷﻴﺪ. ﻧﻜﺘﻪ :اﻋﺪاد اﻋﺸﺎري ﺑﺎ دﻗﺖ ﻣﻌﻤﻮﻟﻲ 32ﺑﻴﺖ از ﺣﺎﻓﻈﻪ را اﺷﻐﺎل ﻣﻲ ﻛﻨﻨﺪ ،ﻳﻌﻨﻲ اﻳﻦ اﻋﺪاد ﻧﺼﻒ اﻋﺪاد اﻋﺸﺎري ﺑﺎ دﻗﺖ ﻣﻀﺎﻋﻒ و ﺑـﻪ اﻧﺪازه ي اﻋﺪاد ﺻﺤﻴﺢ ﻓﻀﺎ ﻣﻴﮕﻴﺮﻧﺪ. اﮔﺮ ﻳﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع ﺻﺤﻴﺢ ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ،ﭼﻪ در آن 1را ذﺧﻴﺮه ﻛﻨﻴﺪ ،ﭼﻪ 249و ﻳﺎ ،2147483647دﻗﻴﻘﺎ 32ﺑﻴﺖ از ﻓﻀﺎي ﺣﺎﻓﻈﻪ را اﺷﻐﺎل ﻛﺮده اﻳﺪ .اﻧﺪازه ﻋﺪد ﻫﻴﭻ ﺗﺎﺛﻴﺮي در اﻧﺪازه ﻓﻀﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ذﺧﻴﺮه آن ﻧﺪارد .اﻳﻦ ﻣﻮرد ﻣﻤﻜﻦ اﺳﺖ ﻫﺪر رﻓـﺘﻦ ﺣﺎﻓﻈـﻪ ﺑـﻪ ﻧﻈﺮ رﺳﺪ .اﻣﺎ دﻗﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺗﺼﻮر ﻣﻴﻜﻨﺪ اﻋﺪاد از ﻧﻮع ﻳﻜﺴﺎن ﻓﻀﺎي ﻳﻜﺴﺎﻧﻲ ﺑﺮاي ﻧﮕﻬﺪاري ﻧﻴـﺎز دارﻧـﺪ .در ﻏﻴـﺮ اﻳـﻦ ﺻﻮرت ،ﻧﻤﻴﺘﻮاﻧﺪ ﺑﺎ ﺳﺮﻋﺖ ﻗﺎﺑﻞ ﻗﺒﻮﻟﻲ ﻛﺎر ﻛﻨﺪ. ﺣﺎﻻ ﺑﻪ ﭼﮕﻮﻧﮕﻲ ﺗﻌﺮﻳﻒ ﻳﻚ رﺷﺘﻪ ﻧﮕﺎه ﻛﻨﻴﺪ: ;"!string strData = "Hello, World ﺑﺮ ﺧﻼف اﻋﺪاد ﺻﺤﻴﺢ و اﻋﺸﺎري ،رﺷﺘﻪ ﻫﺎ داراي ﻃﻮل ﺛﺎﺑﺘﻲ ﻧﻴﺴﺘﻨﺪ .در رﺷﺘﻪ ﻫﺎ ،ﻫﺮ ﻛﺎراﻛﺘﺮ دو ﺑﺎﻳﺖ ﻳﺎ 16ﺑﻴﺖ از ﻓﻀﺎي ﺣﺎﻓﻈـﻪ را اﺷﻐﺎل ﻣﻴﻜﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي ﻧﻤﺎﻳﺶ اﻳﻦ رﺷﺘﻪ ي 13ﻛﺎراﻛﺘﺮي ،ﺑﻪ 26ﺑﺎﻳﺖ ﻳﺎ 208ﺑﻴﺖ ﻓﻀﺎ در ﺣﺎﻓﻈﻪ ﻧﻴﺎز دارﻳﺪ .ﺣﺎﻓﻈﻪ ﻛـﺎﻣﭙﻴﻮﺗﺮي ﻛﻪ ﭘﻴﺸﺘﺮ ﻣﺜﺎل زدﻳﻢ ﺣﺪود دو ﻣﻴﻠﻴﻮن ﻛﺎراﻛﺘﺮ را ﻣﻴﺘﻮاﻧﺪ ﻧﮕﻬﺪاري ﻛﻨﺪ ﻛﻪ ﻧﺴﺒﺖ ﺑﻪ اﻋﺪاد ﺻﺤﻴﺢ و ﻳﺎ اﻋﺪاد اﻋﺸﺎري ﺑﺴﻴﺎر ﻛﻤﺘﺮ اﺳﺖ. اﺷﺘﺒﺎﻫﻲ ﻛﻪ ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﺗﺎزه ﻛﺎر اﻧﺠﺎم ﻣﻴﺪﻫﻨﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻛﻤﺘﺮ ﺑﻪ ﺗﺎﺛﻴﺮ ﻧﻮع ذﺧﻴﺮه داده ﻫﺎ در ﺻﺮﻓﻪ ﺟﻮﻳﻲ ﺣﺎﻓﻈﻪ ﻓﻜﺮ ﻣﻲ ﻛﻨﻨﺪ .ﺑﺮاي ﻧﻤﻮﻧﻪ اﮔﺮ ﺷﻤﺎ ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑﺮاي ﻧﮕﻬﺪاري رﺷﺘﻪ ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ و ﺳﭙﺲ ﻋﺪد ﺻﺤﻴﺢ در آن ﻧﮕﻬﺪاري ﻛﻨﻴﺪ ،ﻣﺎﻧﻨﺪ زﻳﺮ:
٩٣
;"string strData = "65536 در اﻳﻨﺠﺎ ﺑﺮاي ﻧﮕﻬﺪاري اﻳﻦ ﻋﺪد ﺻﺤﻴﺢ در ﻗﺎﻟﺐ رﺷﺘﻪ ،از 10ﺑﺎﻳﺖ ﻳﺎ 80ﺑﻴﺖ اﺳﺘﻔﺎده ﻛﺮده اﻳﺪ .در ﺻﻮرﺗﻲ ﻛﻪ ﻣﻴﺘﻮاﻧﺴﺘﻴﺪ ﺑـﺎ ﺗﻌﺮﻳـﻒ اﻳﻦ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ ﺣﺎﻓﻈﻪ ﻛﻤﺘﺮي اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي ﻧﮕﻬﺪاري اﻳﻦ رﺷﺘﻪ ﻋﺪدي در ﺣﺎﻓﻈﻪ ﻫﺮ ﻛﺪام از اﻳﻦ ﻛﺎراﻛﺘﺮﻫﺎ ﺑﺎﻳـﺪ ﺑﻪ ﻳﻚ ﻋﺪد ﺧﺎص ﺗﺒﺪﻳﻞ ﺷﻮﻧﺪ و ﺳﭙﺲ در ﺣﺎﻓﻈﻪ ذﺧﻴﺮه ﺷﻮﻧﺪ .ﺑﺮاي ذﺧﻴﺮه ﻣﺘﻦ در ﺣﺎﻓﻈﻪ ،ﺑﺮ اﺳﺎس اﺳﺘﺎﻧﺪاردي ﺑﻪ ﻧﺎم ﻳﻮﻧﻴﻜﺪ 1ﺑﻪ ﻫﺮ ﻛﺎراﻛﺘﺮ ﻳﻚ ﻛﺪ ﺧﺎص داده ﻣﻴﺸﻮد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻫﺮ ﻛﺎراﻛﺘﺮ ﻳﻚ ﻛﺪ از 0ﺗﺎ 65535دارد و ﺑﺮاي ذﺧﻴﺮه آن ﻛـﺎراﻛﺘﺮ در ﺣﺎﻓﻈـﻪ ،ﻛـﺪ ﻣﻌﺎدل آن ذﺧﻴﺮه ﻣﻲ ﺷﻮد. در زﻳﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻫﺮ ﻛﺎراﻛﺘﺮ را در رﺷﺘﻪ ﺑﺎﻻ آورده اﻳﻢ:
" "6ﻳﻮﻧﻴﻜﺪ 54ﻛﻪ ﻛﺪ ﺑﺎﻳﻨﺮي ﻣﻌﺎدل آن ﺑﺮاﺑﺮ 0000000000110110اﺳﺖ. " "5ﻳﻮﻧﻴﻜﺪ 53ﻛﻪ ﻛﺪ ﺑﺎﻳﻨﺮي ﻣﻌﺎدل آن ﺑﺮاﺑﺮ 0000000000110101اﺳﺖ. " "5ﻳﻮﻧﻴﻜﺪ 53ﻛﻪ ﻛﺪ ﺑﺎﻳﻨﺮي ﻣﻌﺎدل آن ﺑﺮاﺑﺮ 0000000000110101اﺳﺖ. " "3ﻳﻮﻧﻴﻜﺪ 51ﻛﻪ ﻛﺪ ﺑﺎﻳﻨﺮي ﻣﻌﺎدل آن ﺑﺮاﺑﺮ 0000000000110011اﺳﺖ. " "6ﻳﻮﻧﻴﻜﺪ 54ﻛﻪ ﻛﺪ ﺑﺎﻳﻨﺮي ﻣﻌﺎدل آن ﺑﺮاﺑﺮ 0000000000110110اﺳﺖ.
ﻫﺮ ﻛﺪام از اﻳﻦ ﻛﺪﻫﺎ ﺑﺮاي ذﺧﻴﺮه ﺷﺪن ﺑﻪ دو ﺑﺎﻳﺖ ﻓﻀﺎ ﻧﻴﺎز دارﻧﺪ .ﭘﺲ ﺑﺮاي ذﺧﻴﺮه 5رﻗﻢ در ﻗﺎﻟﺐ رﺷﺘﻪ ﺑﻪ 80ﺑﻴﺖ ﻓﻀﺎ ﻧﻴـﺎز دارﻳـﻢ. ﺑﺮاي ذﺧﻴﺮه ﻋﺪد ﺑﺎﻻ ﺑﺎﻳﺪ ﻣﺘﻐﻴﻴﺮ را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ: ;int intNumber = 65536 ﻣﻘﺪار اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﺻﻮرت ﻳﻚ ﻋﺪد در ﻗﺎﻟﺐ ﺑﺎﻳﻨﺮي در ﺣﺎﻓﻈﻪ ذﺧﻴﺮه ﻣﻴﺸﻮد و از آﻧﺠﺎ ﻛﻪ ﻫﺮ ﻋﺪد ﺻﺤﻴﺢ 32ﺑﻴﺖ ﻓﻀﺎ را اﺷﻐﺎل ﻣـﻲ ﻛﻨﺪ ،اﻳﻦ ﻋﺪد ﻫﻢ 32ﺑﻴﺖ ﻓﻀﺎ در ﺣﺎﻓﻈﻪ اﺷﻐﺎل ﻣﻴﻜﻨﺪ ﻛﻪ ﺑﺴﻴﺎر ﻛﻤﺘﺮ از 80ﺑﻴﺖ اﺷﻐﺎل ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ رﺷﺘﻪ اﺳﺖ.
ﻣﺘﺪﻫﺎ: ﻳﻚ ﻣﺘﺪ ،ﻳﻚ ﺗﻜﻪ ﻛﺪ اﺳﺖ ﻛﻪ وﻇﻴﻔﻪ ﺧﺎﺻﻲ را اﻧﺠﺎم ﻣﻲ دﻫﺪ .ﻣﺘﺪﻫﺎ ﻛﻪ ﭘﺮوﺳﻴﺠﺮ ﻫﻢ ﻧﺎﻣﻴﺪه ﻣﻴـﺸﻮﻧﺪ ﺑـﻪ دو دﻟﻴـﻞ اﻫﻤﻴـﺖ زﻳـﺎدي دارﻧﺪ .دﻟﻴﻞ اول اﻳﻦ اﺳﺖ ﻛﻪ آﻧﻬﺎ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﻗﺴﻤﺘﻬﺎي ﻛﻮﭼﻜﺘﺮ ﺗﻘﺴﻴﻢ ﻣﻲ ﻛﻨﻨﺪ و ﻣﻮﺟﺐ ﻣﻴﺸﻮﻧﺪ ﻛـﻪ ﺑﺮﻧﺎﻣـﻪ ﺑﻬﺘـﺮ درك ﺷـﻮد .دوم اﻳﻨﻜﻪ آﻧﻬﺎ ﻗﺎﺑﻠﻴﺖ اﺳﺘﻔﺎده ﻣﺠﺪد از ﻛﺪﻫﺎ را اﻓﺰاﻳﺶ ﻣﻲ دﻫﻨﺪ .اﺳﺘﻔﺎده ﻣﺠﺪد از ﻛﺪﻫﺎ ﺑﻪ اﻧﺪازه اي ﻣﻬﻢ اﺳﺖ ﻛﻪ ﺗﺎ آﺧﺮ اﻳﻦ ﻛﺘﺎب ﺑﻴﺸﺘﺮ وﻗﺖ ﺧﻮد را ﺻﺮف آن ﻣﻲ ﻛﻨﻴﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻴﺪاﻧﻴﺪ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺷﺮوع ﺑﻪ ﻧﻮﺷﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﻴﻜﻨﻴﺪ ،اﺑﺘﺪا ﺑﺎﻳﺪ اﻟﮕﻮرﻳﺘﻢ ﻛﻠﻲ آن را ﺗﻬﻴﻪ ﻛـﺮده و ﺳـﭙﺲ ﺟﺰﺋﻴـﺎت ﻫـﺮ ﻗﺴﻤﺖ از اﻟﮕﻮرﻳﺘﻢ را ﺑﻪ ﻛﺪ ﺗﺒﺪﻳﻞ ﻛﻨﻴﺪ ﺗﺎ ﻛﻞ ﺑﺨﺸﻬﺎي اﻟﮕﻮرﻳﺘﻢ را ﺑﻪ ﺻﻮرت ﻛﺪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،ﺳﭙﺲ ﺑﺎ ﻛﻨﺎر ﻫﻢ ﻗﺮار دادن اﻳﻦ ﻛـﺪﻫﺎ ﺑﻪ اﻟﮕﻮرﻳﺘﻢ ﻛﻠﻲ ﻣﻴﺮﺳﻴﺪ .ﻳﻚ ﻣﺘﺪ ،ﻳﻜﻲ از ﺧﻄﻬﺎي اﻳﻦ اﻟﮕﻮرﻳﺘﻢ ﻛﻠﻲ را اﺟﺮا ﻣﻲ ﻛﻨﺪ ،ﺑﺮاي ﻣﺜﺎل "ﻳﻚ ﻓﺎﻳﻞ را ﺑﺎز ﻛﻦ"" ،ﻳﻚ ﻣـﺘﻦ را روي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﺑﺪه"" ،ﻳﻚ ﺻﻔﺤﻪ را ﭼﺎپ ﻛﻦ" و ﻳﺎ ﻣﻮاردي از اﻳﻦ ﻗﺒﻴﻞ. داﻧﺴﺘﻦ اﻳﻦ ﻛﻪ ﭼﮕﻮﻧﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﭼﻨﺪ ﻗﺴﻤﺖ ﻛﻮﭼﻜﺘﺮ ﺗﻘﺴﻴﻢ ﻛﻨﻴﺪ ﻣﻮردي اﺳﺖ ﻛﻪ ﺑﻪ ﺗﺠﺮﺑﻪ ﺑﺴﺘﮕﻲ دارد .اﻫﻤﻴﺖ ﺗﻘﺴﻴﻢ ﻛﺮدن ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﭼﻨﺪ ﻗﺴﻤﺖ ﻛﻮﭼﻚ و ﺗﺎﺛﻴﺮ آن در ﺳﺎدﮔﻲ ﺑﺮﻧﺎﻣﻪ را زﻣﺎﻧﻲ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺑﺴﻴﺎر ﭘﻴﭽﻴﺪه ﺗﺮي ﻧﺴﺒﺖ Unicode
1
٩٤
ﺑﻪ آﻧﻬﺎﻳﻲ ﻛﻪ ﺗﺎﻛﻨﻮن ﻧﻮﺷﺘﻪ اﻳﺪ ،ﺑﻨﻮﻳﺴﻴﺪ .در اداﻣﻪ ي اﻳﻦ ﺑﺨﺶ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﺑﻪ ﺷﻤﺎ ﺑﮕﻮﻳﻴﻢ ﭼﺮا و ﭼﮕﻮﻧـﻪ ﺑﺎﻳـﺪ از ﻣﺘـﺪﻫﺎ اﺳـﺘﻔﺎده ﻛﻨﻴﻢ.
ﭼﺮا از ﻣﺘﺪﻫﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ؟ در اﺳﺘﻔﺎده از ﻣﺘﺪﻫﺎ ،ﺷﻤﺎ ﺑﺎﻳﺪ اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﻳﻚ ﻣﺘﺪ ﺑﺮاي اﺟﺮا ﺑﻪ آﻧﻬﺎ ﻧﻴﺎز دارد را ﻓﺮاﻫﻢ ﻛﻨﻴﺪ ﺗﺎ ﻧﺘﻴﺠﻪ ي ﻣﻄﻠﻮﺑﻲ درﻳﺎﻓﺖ ﻛﻨﻴـﺪ .اﻳـﻦ اﻃﻼﻋﺎت ﻣﻤﻜﻦ اﺳﺖ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ ،ﻳﻚ رﺷﺘﻪ ﻣﺘﻨﻲ و ﻳﺎ ﺗﺮﻛﻴﺒﻲ از ﻫﺮ دو ﺑﺎﺷﺪ .اﻳﻦ اﻃﻼﻋﺎت ﺑﻪ ﻋﻨﻮان ﻣﻘﺎدﻳﺮ ورودي ﺷـﻨﺎﺧﺘﻪ ﻣﻴﺸﻮﻧﺪ .اﻟﺒﺘﻪ ﺑﻌﻀﻲ از ﻣﺘﺪﻫﺎ ورودي درﻳﺎﻓﺖ ﻧﻤﻲ ﻛﻨﻨﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ داﺷﺘﻦ ﻣﻘﺪار ورودي ﺑﺮاي ﻳﻚ ﻣﺘﺪ ﻻزم ﻧﻴﺴﺖ .ﻳﻚ ﻣﺘﺪ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ اﻃﻼﻋﺎت ورودي و ﻧﻴﺰ ﻳﻚ ﺳﺮي اﻃﻼﻋﺎت دروﻧﻲ )ﺑﺮاي ﻣﺜﺎل داﻧﺴﺘﻦ اﻃﻼﻋﺎﺗﻲ در راﺑﻄﻪ ﺑﺎ وﺿﻌﻴﺖ ﻛﻨﻮﻧﻲ ﺑﺮﻧﺎﻣﻪ( ﺳﻌﻲ ﻣﻴﻜﻨﺪ ﺗﺎ وﻇﻴﻔﻪ ﺧﻮد را اﻧﺠﺎم دﻫﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻳﻦ اﻃﻼﻋﺎت را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﻓﺮﺳﺘﻴﺪ ،در اﺻﻄﻼح داده ﺑﻪ ﺗﺎﺑﻊ ﻓﺮﺳﺘﺎده اﻳﺪ .ﺑﻪ اﻳﻦ داده ﻫﺎ ﭘﺎراﻣﺘﺮ ﻫﻢ ﮔﻔﺘﻪ ﻣﻴـﺸﻮد .در ﻧﻬﺎﻳﺖ ﺑﺮاي اﺳﺘﻔﺎده از ﻳﻚ ﺗﺎﺑﻊ ﺷﻤﺎ ﺑﺎﻳﺪ آن را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ .ﺧﻼﺻﻪ ،ﺷﻤﺎ ﻳﻚ ﻣﺘﺪ را ﻓﺮاﺧﻮاﻧﻲ ﻣﻴﻜﻨﻴﺪ و داده ﻫﺎي ﻣـﻮرد ﻧﻴـﺎز آن را ﺑﻪ وﺳﻴﻠﻪ ﭘﺎراﻣﺘﺮ ﻫﺎ ﺑﻪ آن ﻣﻴﻔﺮﺳﺘﻴﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺒﻞ ﻫﻢ ذﻛﺮ ﺷﺪ ،دﻟﻴﻞ اﺳﺘﻔﺎده از ﻳﻚ ﺗﺎﺑﻊ اﻳﻦ اﺳﺖ ﻛﻪ از ﻳﻚ ﻗﻄﻌﻪ ﻛﺪ ﭼﻨﺪﻳﻦ ﺑﺎر اﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر اﺑﺘـﺪا ﺑﺎﻳﺪ ﺑﺘﻮاﻧﻴﻢ اﻟﮕﻮرﻳﺘﻢ ﺑﺮﻧﺎﻣﻪ را در ﺣﺎﻟﺖ ﻛﻠﻲ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ و ﺳﭙﺲ ﻗﺴﻤﺘﻬﺎﻳﻲ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﭼﻨﺪ ﺑﺎر ﺑﻪ آﻧﻬﺎ ﻧﻴﺎز ﭘﻴﺪا ﻛﻨﻴﻢ را ﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﺑﻌﺪ از ﻣﺸﺨﺺ ﻛﺮدن اﻳﻦ ﻗﺴﻤﺘﻬﺎ ،ﻣﻴﺘﻮاﻧﻴﻢ آﻧﻬﺎ را ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪﻫﺎ ﺑﻨﻮﻳﺴﻴﻢ و ﺳﭙﺲ ﻣﺘﺪﻫﺎ را ﭼﻨﺪﻳﻦ ﺑـﺎر در ﺑﺮﻧﺎﻣـﻪ اﺳـﺘﻔﺎده ﻛﻨﻴﻢ. ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ از اﻟﮕﻮرﻳﺘﻢ ﻫﺎي زﻳﺎدي ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ .ﺑﻌﻀﻲ از اﻳﻦ اﻟﮕﻮرﻳﺘﻢ ﻫﺎ ﺑﺮاي ﻣﺤﺎﺳـﺒﺎت ﺧـﻮد ﻧﻴـﺎز دارﻧﺪ ﻛﻪ ﺑﺘﻮاﻧﻨﺪ ﻣﺤﻴﻂ داﻳﺮه را ﻣﺤﺎﺳﺒﻪ ﻛﻨﻨﺪ .ﭼﻮن ﺑﻌﻀﻲ از ﻗﺴﻤﺘﻬﺎي اﻟﮕﻮرﻳﺘﻢ ﻣﺎ ﻧﻴﺎز دارﻧﺪ ﻛﻪ ﻧﺤﻮه ﻣﺤﺎﺳﺒﻪ ﻣﺤﻴﻂ داﻳـﺮه را ﺑﺪاﻧﻨـﺪ، اﺳﺘﻔﺎده از ﻳﻚ ﻣﺘﺪ در اﻳﻦ ﻣﻮرد ﻣﻴﺘﻮاﻧﺪ ﻣﻨﺎﺳﺐ ﺑﺎﺷﺪ .ﺷﻤﺎ ﻣﻴﺘﻮاﻧﻴﺪ ﻣﺘﺪي ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ ﺑﺘﻮاﻧﺪ ﻣﺤﻴﻂ ﻳﻚ داﻳﺮه را ﺑـﺎ داﻧـﺴﺘﻦ ﺷـﻌﺎع آن ﻣﺤﺎﺳﺒﻪ ﻛﻨﺪ ،ﺳﭙﺲ در ﻫﺮ ﻗﺴﻤﺖ از اﻟﮕﻮرﻳﺘﻢ ﻛﻪ ﺑﻪ ﻣﺤﺎﺳﺒﻪ ﻣﺤﻴﻂ ﻧﻴﺎز ﺑﻮد ﻣﻴﺘﻮاﻧﻴﺪ اﻳﻦ ﻣﺘﺪ را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ .ﺑﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﻧﻴـﺎزي ﻧﻴﺴﺖ ﻛﺪي ﻛﻪ ﻳﻚ ﻛﺎر ﻣﺸﺨﺺ را اﻧﺠﺎم ﻣﻴﺪﻫﺪ ﭼﻨﺪ ﺑﺎر ﻧﻮﺷﺘﻪ ﺷﻮد .ﺷﻤﺎ ﻓﻘﻂ ﻳﻚ ﺑﺎر ﻛﺪ را ﻣﻲ ﻧﻮﻳـﺴﻴﺪ و ﭼﻨـﺪ ﺑـﺎر از آن اﺳـﺘﻔﺎده ﻣﻴﻜﻨﻴﺪ. ﻫﻤﭽﻨﻴﻦ ﻣﻤﻜﻦ اﺳﺖ ﻳﻚ ﻗﺴﻤﺖ از اﻟﮕﻮرﻳﺘﻢ ﺑﺨﻮاﻫﺪ ﻣﺤﻴﻂ ﻳﻚ داﻳﺮه ﺑﻪ ﺷﻌﺎع 100را ﺑﺪاﻧﺪ و ﻗﺴﻤﺘﻲ دﻳﮕﺮ ﻣﺤـﻴﻂ ﻳـﻚ داﻳـﺮه ﺑـﻪ ﺷﻌﺎع .200ﺑﻨﺎﺑﺮاﻳﻦ ﻣﺘﺪ ﺷﻤﺎ ﻣﻴﺘﻮاﻧﺪ ﺷﻌﺎع داﻳﺮه را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ از ورودي ﺑﮕﻴﺮد و ﺳﭙﺲ ﻣﺤﻴﻂ را ﻣﺤﺎﺳﺒﻪ ﻛﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﻳﻦ ﻣﺘﺪ در ﻫﺮ ﺷﺮاﻳﻄﻲ ﻣﻴﺘﻮاﻧﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد. ﻧﻜﺘﻪ :در وﻳﮋوال 2005 C#ﻳﻚ ﻣﺘﺪ ﻳﺎ ﻣﻴﺘﻮاﻧﺪ ﻣﻘﺪاري را ﺑﺮﮔﺮداﻧﺪ و ﻳـﺎ ﻫـﻴﭻ ﻣﻘـﺪاري را ﺑﺮﻧﮕﺮداﻧـﺪ .ﺑـﻪ ﻣﺘـﺪﻫﺎﻳﻲ ﻛـﻪ ﻣﻘـﺪاري را ﺑﺮﻣﻴﮕﺮداﻧﻨﺪ ﻳﻚ ﺗﺎﺑﻊ 1و ﺑﻪ ﻣﺘﺪﻫﺎﻳﻲ ﻛﻪ ﻫﻴﭻ ﻣﻘﺪاري را ﺑﺮﻧﻤﻴﮕﺮداﻧﻨﺪ ﻳﻚ زﻳﺮﺑﺮﻧﺎﻣﻪ 2ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد.
ﻣﺘﺪﻫﺎﻳﻲ ﻛﻪ ﺗﺎﻛﻨﻮن دﻳﺪه اﻳﺪ:
Function Subroutine
1 2
٩٥
ﺑﻬﺘﺮ اﺳﺖ ﺑﺪاﻧﻴﺪ ﻛﻪ ﺗﺎﻛﻨﻮن در ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﻧﻮﺷﺘﻪ اﻳﻢ ،از ﻣﺘﺪﻫﺎي زﻳﺎدي اﺳﺘﻔﺎده ﻛﺮده اﻳﺪ .ﺑﻪ ﻋﻨﻮان ﻣﺜـﺎل ﻛـﺪ زﻳﺮ را ﻛﻪ در اﺑﺘﺪاي ﻓﺼﻞ ﻧﻮﺷﺘﻴﺪ ﻣﻼﺣﻈﻪ ﻛﻨﻴﺪ: )private void btnAdd_Click(object sender, EventArgs e { // Define a variable for intNumber ;int intNumber // Set the initial value ;intNumber = 27 // Add 1 to the value of intNumber ;intNumber = intNumber + 1 // Display the new value of intNumber MessageBox.Show("The value of intNumber + 1 = " + ;)"intNumber, "Variables } اﻳﻦ ﻛﺪ ﻳﻚ ﻣﺘﺪ اﺳﺖ زﻳﺮا ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺗﻌﺮﻳﻒ ﻣﺘﺪ ﮔﻔﺘﻴﻢ ،ﻗﻄﻌﻪ ﻛﺪي ﻣﺠﺰا اﺳﺖ ﻛﻪ ﻛﺎر ﺧﺎﺻﻲ را اﻧﺠﺎم ﻣﻲ دﻫـﺪ .در اﻳﻨﺠـﺎ اﻳـﻦ ﻗﻄﻌﻪ ﻛﺪ ﻋﺪد ﻳﻚ را ﺑﻪ ﻣﺘﻐﻴﻴﺮ intNumberاﺿﺎﻓﻪ ﻣﻴﻜﻨﺪ و ﻧﺘﻴﺠﻪ را ﻧﻤﺎﻳﺶ ﻣﻴﺪﻫﺪ. اﻳﻦ ﻣﺘﺪ ﻫﻴﭻ ﻣﻘﺪاري را ﺑﺮ ﻧﻤﻲ ﮔﺮداﻧﺪ ﺑﻨﺎﺑﺮاﻳﻦ ﻧﻮع ﻣﻘﺪار ﺑﺎزﮔﺸﺘﻲ voidﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ .ﻛﻠﻤﻪ voidﺑﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻣـﻲ ﮔﻮﻳـﺪ ﻛﻪ اﻳﻦ ﻣﺘﺪ ﻫﻴﭻ ﻣﻘﺪاري را ﺑﺮ ﻧﻤﻲ ﮔﺮداﻧﺪ .اﮔﺮ ﻣﺘﺪي ﻣﻘﺪاري را ﺑﺮﮔﺮداﻧﺪ ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از voidﺑﺎﻳﺪ ﻧﻮع ﻣﻘـﺪاري ﻛـﻪ ﺑﺮﮔـﺸﺖ داده ﻣﻲ ﺷﻮد را ﺑﻨﻮﻳﺴﻴﺪ )ﺑﺮاي ﻣﺜﺎل intﻳﺎ doubleﻳﺎ .(...ﻫﺮ دﺳﺘﻮري ﻛﻪ ﺑﻴﻦ دو ﻋﻼﻣﺖ آﻛﻮﻻد ﻧﻮﺷﺘﻪ ﺷﻮد ﺟﺰﺋـﻲ از ﺑﺪﻧـﻪ ي ﻣﺘﺪ ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد .ﻳﻚ ﻣﺘﺪ ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻌﺮﻳﻒ ﻣﻲ ﺷﻮد )اﻟﺒﺘﻪ اﻳﻦ ﻣﺘﺪ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺗﻮﺳﻂ وﻳﮋوال 2005 C#اﻳﺠﺎد ﺷﺪه اﺳﺖ(: )private void btnAdd_Click(object sender, EventArgs e (1
(2 (3 (4
ﻗﺒﻞ از ﻫﺮ ﭼﻴﺰ ،ﻛﻠﻤﻪ privateرا در ﺗﻌﺮﻳﻒ ﺗﺎﺑﻊ ﻣﺸﺎﻫﺪه ﻣﻴﻜﻨﻴﺪ .درﺑﺎره اﻳﻦ ﻛﻠﻤـﻪ در ﻓـﺼﻠﻬﺎي ﺑﻌـﺪي ﺑـﻪ ﺗﻔـﺼﻴﻞ ﺑﺤﺚ ﺷﺪه اﺳﺖ .ﻓﻌﻼ ،ﻓﻘﻂ ﺑﺪاﻧﻴﺪ ﻛﻪ اﻳﻦ ﻛﻠﻤﻪ ﻣﻮﺟﺐ ﻣﻴﺸﻮد اﻳﻦ ﻣﺘﺪ ﻓﻘﻂ ﺗﻮﺳﻂ ﺗﻮاﺑﻊ و ﻳﺎ ﻣﺘﺪﻫﺎي دﻳﮕـﺮ داﺧـﻞ ﻫﻤـﺎن ﺑﺨﺶ اﺳﺘﻔﺎده ﺷﻮد. ﻛﻠﻤﻪ ﺑﻌﺪي ،ﻛﻠﻤﻪ voidاﺳﺖ ﻛﻪ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻴﻢ ﺑﻪ وﻳﮋوال C#ﻣﻲ ﮔﻮﻳﺪ اﻳﻦ ﻣﺘﺪ ﻫﻴﭻ ﻣﻘﺪاري را ﺑﺮﻧﻤﻲ ﮔﺮداﻧﺪ. ﺑﻌﺪ از voidﺑﺎ ﻛﻠﻤﻪ btnAdd_Clickروﺑﺮو ﻣﻴﺸﻮﻳﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺣﺪس زده ﺑﺎﺷﻴﺪ ،اﻳﻦ ﻛﻠﻤﻪ ﻧﺎم ﻣﺘﺪي اﺳﺖ ﻛﻪ ﺗﻌﺮﻳﻒ ﻛﺮده اﻳﻢ. ﭼﻬﺎرﻣﻴﻦ ﻣﻮرد در ﺗﻌﺮﻳﻒ اﻳﻦ ﺗﺎﺑﻊ ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﺑﻪ آن ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻴﻜﻨﻴﺪ اﻳـﻦ ﺗـﺎﺑﻊ دو ﭘﺎراﻣﺘﺮ را درﻳﺎﻓﺖ ﻣﻴﻜﻨﺪ .ﭘﺎراﻣﺘﺮ اول sender ،از ﻧﻮع objectاﺳﺖ و ﭘﺎراﻣﺘﺮ دوم eاز ﻧـﻮع EventArgs اﺳﺖ .در ﻣﻮرد اﻳﻦ ﭘﺎراﻣﺘﺮ ﻫﺎ در ﺑﺨﺸﻬﺎي ﺑﻌﺪي ﺑﻴﺸﺘﺮ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد.
در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ،ﻳﻚ ﻣﺘﺪ اﻳﺠﺎد ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻳﻚ ﻋﺒﺎرت را ﺑﺎ اﺳﺘﻔﺎده از ﻛﺎدر ﭘﻴﻐﺎم در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﺪ و ﺳﭙﺲ اﻳﻦ ﻣﺘﺪ را ﺑﻪ وﺳﻴﻠﻪ ﺳﻪ دﻛﻤﻪ ﻓﺮﻣﺎن ﻣﺘﻔﺎوت ﻓﺮاﺧﻮاﻧﻲ ﺧﻮاﻫﻴﺪ ﻛﺮد.
٩٦
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﻣﺘﺪﻫﺎ (1ﻳﻚ ﭘﺮوژه وﻳﻨﺪوزي ﺑﺎ وﻳﮋوال 2005 C#اﻳﺠﺎد ﻛﻨﻴﺪ و ﻧﺎم آن را ﺑﺮاﺑﺮ Three Buttonsﻗﺮار دﻫﻴﺪ. (2ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﺳﻪ دﻛﻤﻪ ﻓﺮﻣﺎن ﺑﺮ روي ﻓﺮم ﺧﻮد ﻗﺮار دﻫﻴﺪ. (3روي دﻛﻤﻪ ﻓﺮﻣﺎن اول دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )private void button1_Click(object sender, EventArgs e { // Call your method ;)(SayHello } )(private void SayHello { // Display a message box ;)"MessageBox.Show("Hello, World!", "Three Buttons } (4ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻓﺮﻣﻲ را ﺑﺎ ﺳﻪ دﻛﻤﻪ ﻓﺮﻣﺎن ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد .ﺑﺮ روي ﺑـﺎﻻﺗﺮﻳﻦ دﻛﻤـﻪ ﻓﺮﻣـﺎن ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .ﻛـﺎدر ﭘﻴﻐﺎﻣﻲ ﺑﺎ ﻋﺒﺎرت ! Hello, Worldرا ﺧﻮاﻫﻴﺪ دﻳﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﻣﺤﻴﻂ ﻃﺮاﺣﻲ ﺑﺮ روي ﻳﻚ دﻛﻤﻪ ﻓﺮﻣﺎن دو ﺑﺎر ﻛﻠﻴﻚ ﻣﻲ ﻛﻨﻴﺪ ،وﻳﮋوال 2005 C#ﺗﺎﺑﻌﻲ ﻣﺎﻧﻨﺪ زﻳﺮ را ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ: )private void button1_Click(object sender, EventArgs e { } ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي اﻳﻦ دﻛﻤﻪ در ﺑﺮﻧﺎﻣﻪ ﻛﻠﻴﻚ ﻛﻨﺪ ،اﺻﻄﻼﺣﺎ ﻳﻚ روﻳﺪاد 1در ﺑﺮﻧﺎﻣﻪ رخ داده اﺳـﺖ .وﻳـﮋوال 2005 C#ﻫﻨﮕـﺎم ﻛﺎﻣﭙﺎﻳﻞ اﻳﻦ ﻣﺘﺪ ،ﻛﺪي را ﺑﻪ آن اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ ﺗﺎ اﻳﻦ ﻣﺘﺪ ﻫﻨﮕﺎم رخ دادن روﻳﺪاد ﻛﻠﻴﻚ اﻳﻦ دﻛﻤﻪ اﺟﺮا ﺷﻮد .ﺑﻪ ﻋﺒﺎرت دﻳﮕـﺮ وﻳـﮋوال C#زﻣﺎﻧﻲ ﻛﻪ ﻛﺎرﺑﺮ روي اﻳﻦ دﻛﻤﻪ ﻓﺮﻣﺎن در ﺑﺮﻧﺎﻣﻪ ﻛﻠﻴﻚ ﻛﺮد ،اﻳﻦ ﻣﺘﺪ را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ .اﻳﻦ ﻣﺘﺪ دو ﭘﺎراﻣﺘﺮ را ﺑﻪ ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ ،ﻛﻪ ﻓﻌﻼ در ﻣﻮرد آﻧﻬﺎ ﺻﺤﺒﺘﻲ ﻧﻤﻲ ﻛﻨﻴﻢ .در ﻓﺼﻠﻬﺎي ﺑﻌﺪ ﺑﻴﺸﺘﺮ ﺑﺎ روﻳﺪادﻫﺎ و ﻧﺤﻮه اﺳـﺘﻔﺎده از آﻧﻬـﺎ در ﺑﺮﻧﺎﻣـﻪ آﺷـﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ.
Event
1
٩٧
در ﺑﻴﺮون از اﻳﻦ ﻣﺘﺪ ،ﻣﺘﺪ دﻳﮕﺮي را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﺪ: )(private void SayHello { // Display a message box ;)"MessageBox.Show("Hello, World!", "Three Buttons } اﻳﻦ ﻣﺘﺪ ﺟﺪﻳﺪ SayHello ،ﻧﺎﻣﻴﺪه ﻣﻴﺸﻮد .ﻫﺮ ﭼﻴﺰي ﻛﻪ در ﺑﻴﻦ دو آﻛﻮﻻد ﻣﺘﺪ ﻗﺮار ﺑﮕﻴﺮد ،ﺟﺰﺋﻲ از ﻛﺪ اﻳﻦ ﻣﺘﺪ ﻣﺤﺴﻮب ﻣﻴـﺸﻮد و ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺘﺪ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮد ،اﺟﺮا ﺧﻮاﻫﺪ ﺷﺪ .در اﻳﻦ ﺣﺎﻟﺖ ،ﻛﺪ ﻧﻮﺷﺘﻪ ﺷﺪه در اﻳﻦ ﻣﺘﺪ ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻴﺪاﻧﻴﺪ ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن ،وﻳﮋوال 2005 C#ﻣﺘﺪ button1_Clickرا اﺟﺮا ﻣﻴﻜﻨـﺪ و اﻳـﻦ ﻣﺘﺪ ﻧﻴﺰ SayHelloرا اﺣﻀﺎر ﻣﻴﻜﻨﺪ .ﻧﺘﻴﺠﻪ اﻳﻦ ﻛﻪ ﺑﺎ ﻛﻠﻴﻚ ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن ،ﻛﺪ داﺧﻞ ﻣﺘﺪ SayHelloاﺟﺮا ﻣﻴـﺸﻮد و ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻧﻤﺎﻳﺶ داده ﻣﻴﺸﻮد. )private void button1_Click(object sender, EventArgs e { // Call your method ;)(SayHello } ﺗﺎ اﻳﻨﺠﺎ ﻣﻘﺪاري ﺑﺎ ﺗﻌﺮﻳﻒ ﺗﺎﺑﻊ و ﻧﻴﺰ اﺳﺘﻔﺎده از آن آﺷﻨﺎ ﺷﺪﻳﺪ ،اﻣﺎ ﺳﻮاﻟﻲ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺑﻪ وﺟﻮد آﻳﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﭼﺮا ﻧﻴﺎز دارﻳﺪ ﻣﺘﺪي ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ ﻛﺎدر ﭘﻴﻐﺎﻣﻲ را ﻧﻤﺎﻳﺶ دﻫﺪ؟ در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ دﻟﻴﻞ اﻳﻦ ﻛﺎر را ﺑﻴﺸﺘﺮ ﻣﺘﻮﺟﻪ ﺧﻮاﻫﻴﺪ ﺷﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده ﻣﺠﺪد از ﻣﺘﺪﻫﺎ (1اﮔﺮ ﭘﺮوژه ﻗﺒﻠﻲ در ﺣﺎل اﺟﺮا اﺳﺖ ،آن را ﺑﺒﻨﺪﻳﺪ. (2روي دﻛﻤﻪ ﻓﺮﻣﺎن دوم دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در ﻣﺘﺪ اﻳﺠﺎد ﺷﺪه وارد ﻛﻨﻴﺪ: )private void button2_Click(object sender, EventArgs e { // Call your method ;)(SayHello } (3ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﺑﺮﮔﺮدﻳﺪ و روي دﻛﻤﻪ ﻓﺮﻣﺎن ﺳﻮم دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ .در ﻣﺘﺪ اﻳﺠﺎد ﺷﺪه ﻛﺪ زﻳﺮ را وارد ﻛﻨﻴﺪ: )private void button3_Click(object sender, EventArgs e { // Call your method ;)(SayHello }
٩٨
(4ﺣﺎﻻ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ ﻫﺎي ﻓﺮﻣﺎن ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻫﻤﻪ دﻛﻤﻪ ﻫﺎ ﻛﺎدر ﭘﻴﻐـﺎم ﻳﻜـﺴﺎﻧﻲ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻨﺪ. (5اﺟﺮاي ﺑﺮﻧﺎﻣﻪ را ﻣﺘﻮﻗﻒ ﻛﻨﻴﺪ و ﻣﺘﺪ SayHelloرا در ﺑﺨﺶ ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﭘﻴﺪا ﻛﻨﻴﺪ .ﻣﺘﻨﻲ ﻛﻪ در ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤـﺎﻳﺶ داده ﻣﻴﺸﻮد را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ: )(private void SayHello { // Display a message box ;)"MessageBox.Show("I have changed!", "Three Buttons } (6ﺑﺮﻧﺎﻣﻪ را ﻣﺠﺪدا اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ ﻫﺎي ﻓﺮﻣﺎن ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﻣﺘﻦ ﻣﻮرد ﻧﻤﺎﻳﺶ در ﻛﺎدر ﭘﻴﻐﺎم ﺗﻐﻴﻴﺮ ﻛـﺮده اﺳﺖ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﺮ ﻛﺪام از ﻣﺘﺪﻫﺎي ﻣﺨﺼﻮص ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ دﻛﻤﻪ ﻫﺎي ﻓﺮﻣﺎن ،1ﻣﺘﺪ SayHelloرا ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻨﺪ: )private void button1_Click(object sender, EventArgs e { // Call your method ;)(SayHello } )private void button2_Click(object sender, EventArgs e { // Call your method ;)(SayHello }
)private void button3_Click(object sender, EventArgs e { // Call your method ;)(SayHello } ﻫﻤﺎﻧﻄﻮر ﻛﻪ از اﺳﻢ اﻳﻦ ﻣﺘﺪﻫﺎ ﻧﻴﺰ ﻣﺸﺨﺺ اﺳﺖ ،ﻫﺮ ﻛﺪام از آﻧﻬﺎ ﺑﺮاي ﻛﻨﺘﺮل روﻳﺪاد ﻳﻜﻲ از دﻛﻤﻪ ﻓﺮﻣﺎﻧﻬﺎي روي ﻓﺮم ﻫﺴﺘﻨﺪ.
1ﺑﻪ اﻳﻦ ﻣﺘﺪﻫﺎ ﻛﻪ ﺑﺮاي ﻛﻨﺘﺮل ﻳﻚ روﻳﺪاد ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ Event Handler ،ﻧﻴﺰ ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد.
٩٩
ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺷﻤﺎ ﻧﺤﻮه ﻛﺎرﻛﺮد ﻣﺘﺪ SayHelloرا ﻛﻪ ﻫﺮ ﺳﻪ ﻣﺘﺪ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﺗﻐﻴﻴﺮ دﻫﻴﺪ ،ﺗﻐﻴﻴﺮات ﺑـﻪ ﻫـﺮ ﺳﻪ دﻛﻤﻪ ﻓﺮﻣﺎن اﻋﻤﺎل ﻣﻴﺸﻮد .اﻳﻦ ﻣﻮرد در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﻮﺿﻮع ﺑﺴﻴﺎر ﻣﻬﻤﻲ اﺳﺖ .اﮔﺮ ﺷﻤﺎ ﻣﺘﺪﻫﺎي ﻛﺪ ﺧﻮد را ﺑﻪ ﻧﺤـﻮي ﻣﻨﻄﻘـﻲ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ،ﻣﻴﺘﻮاﻧﻴﺪ ﺑﺎ ﺗﻐﻴﻴﺮ ﻳﻚ ﻣﺘﺪ در ﻗﺴﻤﺘﻲ از ﺑﺮﻧﺎﻣﻪ ،ﺑﺮ روي ﺗﻤﺎم ﻗﺴﻤﺘﻬﺎي ﺑﺮﻧﺎﻣﻪ ﺗﺎﺛﻴﺮ ﺑﮕﺬارﻳﺪ .ﻫﻤﭽﻨﻴﻦ اﻳﻦ ﻣـﻮرد ﺷـﻤﺎ را از وارد ﻛﺮدن ﻛﺪﻫﺎي ﻳﻜﺴﺎن و ﻣﺸﺎﺑﻪ ﺑﻪ ﺻﻮرت ﺗﻜﺮاري ﻧﻴﺰ ﻧﺠﺎت ﻣﻴﺪﻫﺪ.
اﻳﺠﺎد ﻳﻚ ﻣﺘﺪ: در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻣﺘﺪي ﺧﻮاﻫﻴﺪ ﺳﺎﺧﺖ ﻛﻪ ﻳﻚ ﻣﻘﺪار را ﺑﺮﮔﺮداﻧﺪ .ﺗﺎﺑﻌﻲ ﻛﻪ در اﻳﻦ ﺑﺨﺶ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ ﻣﻴﺘﻮاﻧﺪ ﻣﺴﺎﺣﺖ ﻳﻚ داﻳﺮه را ﺑﺮ اﺳﺎس ﺷﻌﺎع آن ﻣﺤﺎﺳﺒﻪ ﻛﻨﺪ .اﻟﮕﻮرﻳﺘﻤﻲ ﻛﻪ ﺑﺮاي اﻳﻦ ﻛﺎر اﺳﺘﻔﺎده ﻣﻴﻜﻨﻴﺪ ﺑﻪ ﺻﻮرت زﻳﺮ اﺳﺖ: (1ﺷﻌﺎع را ﺑﻪ ﺗﻮان دو ﺑﺮﺳﺎن. (2ﻧﺘﻴﺠﻪ را در ﻋﺪد ﭘﻲ ﺿﺮب ﻛﻦ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻳﻚ ﻣﺘﺪ (1ﺑﺮاي ﻧﻮﺷﺘﻦ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﻴﺘﻮاﻧﻴﺪ از ﺑﺮﻧﺎﻣﻪ Three Buttonsﻛﻪ در ﻣﺮﺣﻠﻪ ﻗﺒﻞ ﺳﺎﺧﺘﻴﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. (2ﻛﺪ زﻳﺮ را ﺑﺮاي ﺗﻌﺮﻳﻒ ﻳﻚ ﺗﺎﺑﻊ ﺟﺪﻳﺪ در ﻗﺴﻤﺖ ﻛـﺪ ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ )اﻳـﻦ ﻣﺘـﺪ ﻣﻘـﺪاري را ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ ي ﻓﺮاﺧـﻮان ﺑﺮﻣﻴﮕﺮداﻧﺪ ،ﭘﺲ ﻳﻚ ﺗﺎﺑﻊ ﺑﻪ ﺷﻤﺎر ﻣﻲ رود(. // CalculateAreaFromRadius - find the area of a circle )private double CalculateAreaFromRadius(double radius { // Declare variables ;double dblRadiusSquared ;double dblResult // Square the radius ;dblRadiusSquared = radius * radius // Multiply it by pi ;dblResult = dblRadiusSquared * Math.PI // Return the result ;return dblResult } (3ﺳﭙﺲ ﻛﺪ ﻧﻮﺷﺘﻪ ﺷﺪ در ﻣﺘﺪ button1_Clickرا ﺣﺬف ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را ﺑﻪ ﺟﺎي آن وارد ﻛﻨﻴﺪ: )private void button1_Click(object sender, EventArgs e
١٠٠
{ // Declare variable ;double dblArea // Calculate the area of a circle with radius 100 ;)dblArea = CalculateAreaFromRadius(100 // Print the results ;)"MessageBox.Show(dblArea, "Area } (4ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ ﻓﺮﻣﺎن Button1ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻧﺘﻴﺠﻪ اي را ﻣﺸﺎﺑﻪ ﺷﻜﻞ 13-3ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد:
ﺷﻜﻞ 13-3
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻗﺒﻞ از ﻫﺮ ﭼﻴﺰ ،ﻳﻚ ﻣﺘﺪ ﻣﺠﺰا ﺑﻪ ﻧﺎم CalculateAreaFromRadiusﻣﺎﻧﻨﺪ زﻳﺮ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ: )private double CalculateAreaFromRadius(double radius { } ﻫﺮ ﻛﺪي ﻛﻪ ﺑﻴﻦ دو آﻛﻮﻻد ﻗﺮار ﺑﮕﻴﺮد ﺑﻪ ﻋﻨﻮان ﺑﺪﻧﻪ ﺗﺎﺑﻊ ﺑﻪ ﺷﻤﺎر ﻣﻲ رود و ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﺗﺎﺑﻊ اﺟﺮا ﻣﻴﺸﻮد. ﻗﺴﻤﺖ double radiusﻳﻚ ﭘﺎراﻣﺘﺮ از ﻧﻮع doubleرا ﺑﺮاي اﻳﻦ ﻣﺘﺪ ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻣﺘﺪ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد .NET ،ﻗﺴﻤﺘﻲ از ﺣﺎﻓﻈﻪ را در اﺧﺘﻴﺎر آن ﻗﺮار ﻣﻲ دﻫﺪ ﺗﺎ ﻣﺘﺪ ﺑﺘﻮاﻧﺪ از آن در اﻧﺠﺎم دﺳﺘﻮرات ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﺪ .ﭘﺎراﻣﺘﺮﻫـﺎﻳﻲ ﻛﻪ ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ در ﺑﺪﻧﻪ ﻣﺘﺪ ﺗﻌﺮﻳﻒ ﺷﻮد ،ﻫﻨﮕﺎم ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ در اﻳﻦ ﻓﻀﺎ ﻛﭙﻲ ﻣﻲ ﺷﻮﻧﺪ ﺗﺎ ﻣﺘﺪ ﺑﺘﻮاﻧﺪ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﺪ .اﻳﻦ ﻋﻤـﻞ ﻣﻮﺟﺐ ﻣﻲ ﺷﻮد ﻫﺮ ﺗﻐﻴﺮي ﻛﻪ ﻣﺘﺪ در ﻣﻘﺪار ﭘﺎراﻣﺘﺮ اﻳﺠﺎد ﻛﻨﺪ ،در ﻣﺘﻐﻴﻴﺮ اﺻﻠﻲ ﺗﺎﺛﻴﺮي ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ. ﻣﺜﻼ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ،ﻫﻨﮕﺎم اﺣﻀﺎر ﻣﺘﺪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﻧﺎم radiusدر ﺣﺎﻓﻈﻪ ي ﻣﺨﺼﻮص ﻣﺘﺪ ﺗﻌﺮﻳﻒ ﻣﻲ ﺷﻮد و ﻣﻘﺪار ارﺳﺎﻟﻲ ﺑـﻪ ﻣﺘﺪ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ در آن ﻗﺮار ﻣﻲ ﮔﻴﺮد .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﻣﻘﺪار 200ﺑﻪ ﻣﺘﺪ ارﺳﺎل ﺷﻮد ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ ﺗﻌﺮﻳﻒ ﺷـﺪه ﺑﺮاﺑـﺮ 200ﺧﻮاﻫـﺪ ﺑﻮد .اﻳﻦ ﻣﻮرد ﻫﻤﺎﻧﻨﺪ اﻳﻦ اﺳﺖ ﻛﻪ در اﺑﺘﺪاي ﻣﺘﺪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﻧﺎم radiusﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ و ﻣﻘﺪار آن را ﺑﺮاﺑﺮ 200ﻗﺮار دﻫﻴﺪ: ;double radius = 200 ﻧﻜﺘﻪ :ﻳﻜﻲ از ﻣﺸﻜﻼت اﻳﻦ روش اﻳﻦ اﺳﺖ ﻛﻪ اﮔﺮ اﻧﺪازه ﻣﺘﻐﻴﻴـﺮ ﺑـﺰرگ ﺑﺎﺷـﺪ ،ﻛﭙـﻲ ﻛـﺮدن آن در از ﺑﺮﻧﺎﻣـﻪ اﺻـﻠﻲ در ﺣﺎﻓﻈـﻪ ي ﻣﺨﺼﻮص ﺑﻪ ﻣﺘﺪ زﻣﺎن زﻳﺎدي را ﻣﻲ ﮔﻴﺮد و ﻫﻤﭽﻨﻴﻦ ﻣﻮﺟﺐ ﻣﻲ ﺷﻮد ﺣﺎﻓﻈﻪ ي زﻳﺎدي اﺷﻐﺎل ﺷﻮد .ﺑﺮاي رﻓﻊ اﻳﻦ ﻣﺸﻜﻞ ﻣـﻲ ﺗـﻮان
١٠١
ﻣﺘﻐﻴﻴﺮ ﻫﺎي ﺑﺰرگ را ﺑﻪ روش دﻳﮕﺮي ﺑﻪ ﻧﺎم ارﺟﺎع 1ﺑﻪ ﻣﺘﺪﻫﺎ ﻓﺮﺳﺘﺎد .ﺑﺮاي اﻳﻨﻜﻪ ﻳﻚ ﭘﺎراﻣﺘﺮ ﺑﺎ اﺳﺘﻔﺎده از ارﺟﺎع ﺑﻪ ﻣﺘﺪ ﻓﺮﺳﺘﺎده ﺷﻮد ﺑﺎﻳﺪ ﻗﺒﻞ از ﺗﻌﺮﻳﻒ ﭘﺎراﻣﺘﺮ از ﻛﻠﻤﻪ ﻛﻠﻴﺪي refاﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﭘﺎراﻣﺘﺮ ﺑﺎ اﺳﺘﻔﺎده از ارﺟﺎع ﺑﻪ ﻳـﻚ ﻣﺘـﺪ ارﺳـﺎل ﺷـﻮد، دﻳﮕﺮ ﻣﻘﺪار ﭘﺎراﻣﺘﺮ در ﺣﺎﻓﻈﻪ ي ﻣﺘﺪ ﻛﭙﻲ ﻧﻤﻲ ﺷﻮد ﺑﻠﻜﻪ آدرس ﻣﺘﻐﻴﻴﺮ اﺻﻠﻲ در ﺣﺎﻓﻈﻪ ،ﺑﻪ ﻣﺘـﺪ ﻓﺮﺳـﺘﺎده ﺧﻮاﻫـﺪ ﺷـﺪ .ﺑﻨـﺎﺑﺮاﻳﻦ ﻫـﺮ ﺗﻐﻴﻴﺮي ﻛﻪ ﻣﺘﺪ در ﻣﻘﺪار ﭘﺎراﻣﺘﺮ اﻳﺠﺎد ﻛﻨﺪ ،ﺑﻼﻓﺎﺻﻠﻪ در ﻣﺘﻐﻴﻴﺮ اﺻﻠﻲ ﻧﻴﺰ ﺗﺎﺛﻴﺮ ﺧﻮاﻫﺪ ﮔﺬاﺷﺖ و ﻣﻘﺪار آن ﻧﻴﺰ ﺗﻐﻴﻴﺮ ﺧﻮاﻫﺪ ﻛﺮد. ﻛﻠﻤﻪ doubleﻛﻪ ﻗﺒﻞ از ﻧﺎم ﻣﺘﺪ آﻣﺪه اﺳﺖ ،ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ اﻳﻦ ﻣﺘﺪ ﻣﻘﺪاري را از ﻧﻮع ﻋﺪد اﻋﺸﺎري ﺑﺎ دﻗـﺖ ﻣـﻀﺎﻋﻒ ﺑـﻪ ﺟﺎﻳﻲ ﻛﻪ آن اﺣﻀﺎر ﺷﺪه اﺳﺖ ﺑﺮﻣﻲ ﮔﺮداﻧﺪ: )private double CalculateAreaFromRadius(double radius ﺣﺎﻻ ﺑﻬﺘﺮ اﺳﺖ ﺑﻪ ﺑﺪﻧﻪ ﺧﻮد ﻣﺘﺪ ﻧﮕﺎه دﻗﻴﻘﺘﺮي ﺑﻲ اﻧﺪازﻳﺪ .ﻗﺒﻞ از ﻫﺮ ﭼﻴﺰ ،ﻣﻴﺪاﻧﻴﺪ ﻛﻪ ﺑﺮاي ﻣﺤﺎﺳﺒﻪ ﻣﺴﺎﺣﺖ ﻳﻚ داﻳﺮه ﺑﺎﻳﺪ از اﻟﮕﻮرﻳﺘﻢ زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ: (1ﻋﺪدي ﻛﻪ ﺑﻴﺎﻧﮕﺮ ﺷﻌﺎع داﻳﺮه اﺳﺖ را درﻳﺎﻓﺖ ﻛﻨﻴﺪ. (2ﻋﺪد را ﺑﻪ ﺗﻮان دو ﺑﺮﺳﺎﻧﻴﺪ. (3ﺣﺎﺻﻞ را در ﻋﺪد ﭘﻲ ﺿﺮب ﻛﻨﻴﺪ. و ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ ﺑﻴﻨﻴﺪ ،اﻳﻦ ﻫﻤﺎن ﻛﺎري اﺳﺖ ﻛﻪ در ﺑﺪﻧﻪ ﻣﺘﺪ اﻧﺠﺎم داده اﻳﺪ: // Declare variables ;double dblRadiusSquared ;double dblResult // Square the radius ;dblRadiusSquared = radius * radius // Multiply it by pi ;dblResult = dblRadiusSquared * Math.PI ﻋﺒﺎرت Math.PIدر ﻛﺪ ﻗﺒﻠﻲ ﻣﻘﺪار ﺛﺎﺑﺘﻲ اﺳﺖ ﻛﻪ در وﻳﮋوال 2005 C#ﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ و ﻣﻘﺪار ﻋﺪد ﭘﻲ را در ﺧﻮد ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ .در ﺧﻂ آﺧﺮ ﺑﺎﻳﺪ ﻧﺘﻴﺠﻪ ﻣﺤﺎﺳﺒﺎت را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻓﺮاﺧﻮان ﺑﺎزﮔﺮداﻧﻴﺪ .اﻳﻦ ﻛﺎر ﺑﺎ ﻛﺪ زﻳﺮ اﻧﺠﺎم ﻣﻲ ﺷﻮد: // Return the result ;return dblResult ﻛﺪي ﻛﻪ در ﻣﺘﺪ button1_Clickاﺿﺎﻓﻪ ﻛﺮده اﻳﺪ ،ﺗﺎﺑﻊ ﻗﺒﻠﻲ را اﺣﻀﺎر ﻣﻲ ﻛﻨﺪ و ﻧﺘﻴﺠﻪ ﺑﺮﮔﺮداﻧﺪه ﺷﺪه ﺗﻮﺳـﻂ ﺗـﺎﺑﻊ را ﺑـﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ: // Declare variable Reference
1
١٠٢
;double dblArea // Calculate the area of a circle with radius 100 ;)dblArea = CalculateAreaFromRadius(100 // Print the results ;)"MessageBox.Show(dblArea, "Area اوﻟﻴﻦ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﻧﺎم dblAreaﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ﻛﻪ ﻣﺴﺎﺣﺖ داﻳﺮه را در ﺧﻮد ﻧﮕﻪ دارد .ﺑﻌﺪ از ﻓﺮاﺧﻮاﻧﻲ ﺗﺎﺑﻊ ،ﻣﻘﺪار ﺑﺮﮔﺸﺘﻲ از آن را ﻣﻲ ﺗﻮاﻧﻴﺪ در اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻧﮕﻬﺪاري ﻛﻨﻴﺪ .ﺑﺎ اﺳﺘﻔﺎده از ﭘﺮاﻧﺘﺰ ﻫﺎﻳﻲ ﻛﻪ در آﺧﺮ ﻧﺎم ﺗﺎﺑﻊ آﻣﺪه اﻧـﺪ، ﻣﻴﺘﻮاﻧﻴﺪ ﭘﺎراﻣﺘﺮﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺗﺎﺑﻊ را ﺑﻪ آن ارﺳﺎل ﻛﻨﻴﺪ .در اﻳﻦ ﺟﺎ ﻓﻘﻂ ﺑﺎﻳﺪ ﻳﻚ ﭘﺎراﻣﺘﺮ را ﺑﻪ ﺗﺎﺑﻊ ارﺳﺎل ﻛﻨﻴﺪ و آن ﻫـﻢ ﺷـﻌﺎع داﻳـﺮه ﺧﻮاﻫﺪ ﺑﻮد. ﺑﻌﺪ از اﻳﻨﻜﻪ ﻣﺘﺪ را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮدﻳﺪ ،ﺑﺎﻳﺪ ﺻﺒﺮ ﻛﻨﻴﺪ ﺗﺎ ﻣﺤﺎﺳﺒﺎت آن ﺗﻤﺎم ﺷﻮد .ﭘﺲ از اﺗﻤﺎم ﻣﺤﺎﺳﺒﺎت ﺗﺎﺑﻊ ،ﻧﺘﻴﺠﻪ ﻛـﻪ ﻣـﺴﺎﺣﺖ داﻳـﺮه اﺳﺖ ﺑﺮﮔﺮداﻧﺪه ﻣﻲ ﺷﻮد و در ﻣﺘﻐﻴﻴﺮ dblAreaﻗﺮار ﻣﻴﮕﻴﺮد .اﻛﻨﻮن ﻣﻴﺘﻮاﻧﻴﺪ ﻧﺘﻴﺠﻪ را ﺑﻪ روش ﻫﻤﻴﺸﮕﻲ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﻴﺪ.
اﻧﺘﺨﺎب ﻧﺎم ﺑﺮاي ﻣﺘﺪ: در ﭼﺎرﭼﻮب .NETﻳﻚ ﺳﺮي اﺳﺘﺎﻧﺪارد ﺑﺮاي ﻧﺎﻣﮕﺬاري ﺗﻮاﺑﻊ و ﻣﺘﺪﻫﺎ ﺗﻌﺮﻳﻒ ﺷﺪه اﻧﺪ ﻛﻪ ﺑﻬﺘﺮ اﺳﺖ ﻫﻨﮕﺎم اﻧﺘﺨـﺎب ﻧـﺎم ﺑـﺮاي ﻣﺘـﺪ آﻧﻬﺎ را رﻋﺎﻳﺖ ﻛﻨﻴﺪ .اﻳﻦ ﻣﻮرد ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن راﺣﺖ ﺗﺮ ﺑﺘﻮاﻧﻨﺪ ﻛﺪﻫﺎي ﻧﻮﺷﺘﻪ ﺷﺪه ﺗﻮﺳﻂ ﺧﻮد را ﺑﻪ زﺑﺎن دﻳﮕﺮي ﻣﻨﺘﻘـﻞ ﻛﻨﻨﺪ .ﺗﻮﺻﻴﻪ ﻣﻴﻜﻨﻴﻢ ﻛﻪ ﻫﻨﮕﺎم ﻧﺎﻣﮕﺬاري ﻣﺘﺪﻫﺎ از روش ﻧﺎﻣﮕﺬاري ﭘﺎﺳﻜﺎل اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﻳﻌﻨﻲ ﻓﻘﻂ اوﻟﻴﻦ ﺣـﺮف ﻧـﺎم ﻫـﺮ ﻣﺘـﺪ را ﺑـﻪ ﺻﻮرت ﺑﺰرگ ﺑﻨﻮﻳﺴﻴﺪ .اﻟﺒﺘﻪ اﻳﻦ ﻣﻮرد ﻓﻘﻂ ﻳﻚ ﺗﻮﺻﻴﻪ ﺑﺮاي ﺧﻮاﻧﺎ ﺗﺮ ﺷﺪن ﻛﺪﻫﺎ در وﻳﮋوال 2005 C#اﺳـﺖ و ﻫـﻴﭻ اﺟﺒـﺎري در آن ﻧﻴﺴﺖ .ﺑﻪ ﻣﺜﺎل ﻫﺎي زﻳﺮ ﺗﻮﺟﻪ ﻛﻨﻴﺪ:
CalculateAreaFromRadius OpenXmlFile GetEnvironmentValue
ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در ﻣﺜﺎل ﻫﺎي ﺑﺎﻻ ﺣﺘﻲ در ﻣﻮاردي ﻛﻪ از ﺣﺮوف ﻣﺨﻔﻒ ﻫﻢ اﺳﺘﻔﺎده ﺷﺪه اﺳﺖ ) XMLدر ﻣﺜﺎل دوم( ﺗﻤﺎم ﺣﺮوف ﺑﻪ ﺟﺰ ﺣﺮف اول ﺑﻪ ﺻﻮرت ﻛﻮﭼﻚ ﻧﻮﺷﺘﻪ ﺷﺪه اﻧﺪ .رﻋﺎﻳﺖ اﻳﻦ ﻧﻜﺘﻪ ﺑﻪ ﺧﺼﻮص در زﺑﺎﻧﻬﺎﻳﻲ ﻣﺜـﻞ C#ﻛـﻪ ﺑـﻪ ﻛـﻮﭼﻜﻲ و ﺑﺰرﮔـﻲ ﺣـﺮوف ﺣﺴﺎس ﻫﺴﺘﻨﺪ ،ﻣﻴﺘﻮاﻧﺪ از ﮔﻴﺞ ﺷﺪن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ در ﺑﺮاﺑﺮ ﻧﺎم ﺗﺎﺑﻊ ﺟﻠﻮﮔﻴﺮي ﻛﻨﺪ. ﻗﺎﻋﺪه دﻳﮕﺮ در ﻣﻮرد ﻧﺎﻣﮕﺬاري ﭘﺎراﻣﺘﺮ ﻫﺎ اﺳﺖ .در ﻧﺎﻣﮕﺬاري ﭘﺎراﻣﺘﺮ ﻫﺎ ﺑﻬﺘﺮ اﺳﺖ ﻫﻤﺎﻧﻨﺪ ﻧﺎﻣﮕﺬاري ﺗﻮاﺑﻊ و ﻣﺘﺪﻫﺎ ﻋﻤﻞ ﻛﻨﻴﺪ اﻣﺎ ﺣﺮوف اول ﻫﺮ ﭘﺎراﻣﺘﺮ را ﻧﻴﺰ ﻛﻮﭼﻚ ﻗﺮار دﻫﻴﺪ .ﺑﻪ ﻣﺜﺎل ﻫﺎي زﻳﺮ در اﻳﻦ ﻣﻮرد ﺗﻮﺟﻪ ﻛﻨﻴﺪ:
myAccount customerDetails updatedDnsRecords
در اﻳﻨﺠﺎ ﻧﻴﺰ ،ﻫﻤﻪ ﭼﻴﺰ ﺣﺘﻲ ﻛﻠﻤﺎت اﺧﺘﺼﺎري ﻫﻢ ﺑﺎﻳﺪ از ﻗﻮاﻋﺪ ﻧﺎﻣﮕﺬاري ﭘﻴﺮوي ﻛﻨﻨﺪ )ﻫﻤﺎﻧﻨﺪ DNSدر ﻣﺜﺎل ﺑﺎﻻ(. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻴﺪاﻧﻴﺪ در .NETﻛﺪﻫﺎ ﺑﻪ زﺑﺎن ﺧﺎﺻﻲ واﺑﺴﺘﻪ ﻧﻴﺴﺘﻨﺪ و ﻛﺪﻫﺎي ﻣﻮﺟﻮد در ﻳﻚ زﺑﺎن ﻣﻴﺘﻮاﻧﻨﺪ در زﻳﺎﻧﻬـﺎي دﻳﮕـﺮ ﻣـﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻬﺘﺮ اﺳﺖ از اﻳﻦ ﻗﻮاﻋﺪ ﭘﻴﺮوي ﻛﻨﻴﺪ ﺗﺎ ﻫﻢ در زﺑﺎﻧﻬﺎﻳﻲ ﻛﻪ ﺑﻪ ﻧﻮع ﺣﺮوف ﺣﺴﺎس ﻫﺴﺘﻨﺪ و ﻫﻢ در زﺑﺎﻧﻬﺎﻳﻲ ﻛﻪ ﻧﺴﺒﺖ ﺑﻪ اﻳﻦ ﻣﻮرد ﺣﺴﺎس ﻧﻴﺴﺘﻨﺪ ﺑﺎ ﻣﺸﻜﻠﻲ ﻣﻮاﺟﻪ ﻧﺸﻮﻳﺪ.
١٠٣
ﻧﻜﺘﻪ :زﺑﺎﻧﻬﺎﻳﻲ ﻣﺎﻧﻨﺪ Visual Basicﺑﻪ ﺑﺰرﮔﻲ و ﻛﻮﭼﻜﻲ ﺣﺮوف ﺣﺴﺎس ﻧﻴﺴﺘﻨﺪ اﻣﺎ زﺑﺎﻧﻬﺎي J# ،C#و C++ﺣـﺴﺎس ﺑﻪ ﺣﺮوف ﻫﺴﺘﻨﺪ .ﺑﺮاي ﻣﺜﺎل در اﻳﻦ زﺑﺎﻧﻬﺎ ﻣﺘﻐﻴﻴﺮ intNumberﺑﺎ ﻣﺘﻐﻴﻴﺮ INTNUMBERو ﻳﺎ intnumberﻣﺘﻔﺎوت اﺳﺖ.
ﻣﺤﺪوده ﻫﺎ: ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﻔﺎﻫﻴﻢ ﻣﺘﺪﻫﺎ را ﺑﻴﺎن ﻣﻲ ﻛﺮدﻳﻢ ،ﮔﻔﺘﻴﻢ ﻛﻪ ﻣﺘﺪﻫﺎ ﺟﺎﻣﻊ ﻫﺴﺘﻨﺪ .اﻳﻦ ﻣﻮرد ﺗﺎﺛﻴﺮ ﻣﻬﻤﻲ در ﻧﻮع ﺗﻌﺮﻳﻒ و اﺳـﺘﻔﺎده از ﻣﺘﻐﻴﻴـﺮ ﻫﺎ در ﻣﺘﺪ دارد .ﻓﺮض ﻛﻨﻴﺪ ﻛﻪ دو ﻣﺘﺪ ﺑﻪ ﺻﻮرت زﻳﺮ دارﻳﺪ ﻛﻪ در ﻫﺮ ﻛﺪام ﻣﺘﻐﻴﻴﺮي رﺷﺘﻪ اي ﺑﻪ ﻧﺎم strNameﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ: )(private void DisplaySebastiansName { // Declare variable and set value ;"string strName = "Sebastian Blackwood // Display results ;)"MessageBox.Show(strName, "Scope Demo } )(private void DisplayBalthazarsName { // Declare variable and set value ;"string strName = "Balthazar Keech //Display results ;)"MessageBox.Show(strName, "Scope Demo } ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻫﺮ دوي اﻳﻦ ﻣﺘﻐﻴﻴﺮﻫﺎ از ﻣﺘﻐﻴﻴﺮي ﺑﺎ ﻧﺎم ﻳﻜﺴﺎن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ،اﻣﺎ ﻫﺮ ﻛﺪام از اﻳـﻦ ﻣﺘﻐﻴﻴﺮﻫـﺎ در ﻣﺤـﺪوده ﻣﺘـﺪ ﺧـﻮد ﺗﻌﺮﻳﻒ ﺷﺪه اﻧﺪ .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي اﻳﻦ ﻣﻮرد را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻣﺤﺪوده ﻫﺎ (1ﻳﻚ ﭘﺮوژه وﻳﻨﺪوزي ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم Scope Demoدر وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻳﺠﺎد ﻛﻨﻴﺪ. (2ﻳﻚ ﻛﻨﺘﺮل Buttonﺟﺪﻳﺪ ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑـﺮ btnScopeو ﺧﺎﺻـﻴﺖ Text آن را ﺑﺮاﺑﺮ Scopeدﻫﻴﺪ .روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و در ﻣﺘﺪ اﻳﺠﺎد ﺷﺪه ،ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )private void btnScope_Click(object sender, EventArgs e { // Call a method
١٠٤
DisplayBalthazarsName(); } private void DisplaySebastiansName() { // Declare variable and set value string strName; strName = "Sebastian Blackwood"; // Display results MessageBox.Show(strName, "Scope Demo"); } private void DisplayBalthazarsName() { // Declare variable and set value string strName; strName = "Balthazar Keech"; // Display results MessageBox.Show(strName, "Scope Demo"); } ﻛــﺎدر ﭘﻴﻐــﺎﻣﻲ را ﻣــﺸﺎﻫﺪه ﺧﻮاﻫﻴــﺪ ﻛــﺮد ﻛــﻪ ﻧــﺎم. ﻛﻠﻴــﻚ ﻛﻨﻴــﺪScope ( ﺑﺮﻧﺎﻣــﻪ را اﺟــﺮا ﻛﻨﻴــﺪ و ﺑــﺮ روي دﻛﻤــﻪ3 . را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪBalthazar Keech
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺮﻧﺎﻣﻪ ﺑﻪ درﺳﺘﻲ ﻛﺎر، در اﻳﻦ ﺗﻤﺮﻳﻦ ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ دو ﻣﺘﻐﻴﻴﺮ ﺑﺎ ﻧﺎم ﻳﻜﺴﺎن وﻟﻲ در ﻣﻜﺎﻧﻬﺎي ﻣﺘﻔﺎوت دارﻳﻢ،ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ .ﻣﻲ ﻛﻨﺪ private void DisplaySebastiansName() { // Declare variable and set value string strName; strName = "Sebastian Blackwood"; // Display results MessageBox.Show(strName, "Scope Demo"); } private void DisplayBalthazarsName() { // Declare variable and set value string strName; strName = "Balthazar Keech";
١٠٥
// Display results ;)"MessageBox.Show(strName, "Scope Demo } ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻣﺘﺪ ﺷﺮوع ﺑﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ ،ﻣﺘﻐﻴﻴﺮ ﻫﺎﻳﻲ ﻛﻪ در آن ﺗﻌﺮﻳﻒ ﺷﺪه اﻧﺪ )در ﻣﺤﺪوده ﺑﺎز ﺷـﺪن آﻛـﻮﻻد و ﺑـﺴﺘﻪ ﺷـﺪن آن( ﻣﺤﺪوده ﻓﻌﺎﻟﻴﺖ ﻣﺤﻠﻲ 1ﻣﻲ ﮔﻴﺮﻧﺪ .ﻣﺤﺪوده ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻛﺪام ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ ﻣﻴﺘﻮاﻧﺪ ﺑﻪ آن دﺳﺘﺮﺳﻲ ﭘﻴـﺪا ﻛﻨـﺪ. ﻣﺤﺪوده ﻓﻌﺎﻟﻴﺖ ﻣﺤﻠﻲ ﻳﻌﻨﻲ ﻣﺘﻐﻴﻴﺮ ﻓﻘﻂ در ﻣﺤﺪوده ي ﻣﺘﺪ ﺟﺎري ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ اﺳﺖ. در ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ ،ﻣﺘﻐﻴﻴﺮ strNameﺗﺎ ﻫﻨﮕﺎم ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ وﺟﻮد ﻧﺪارد .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺘﺪ ﺷـﺮوع ﺑـﻪ ﻛـﺎر ﻛـﺮد .NET ،و وﻳﻨـﺪوز ﺣﺎﻓﻈﻪ ﻣﻮرد ﻧﻴﺎز را در اﺧﺘﻴﺎر اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻗﺮار ﻣﻲ دﻫﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻣﻲ ﺗﻮاﻧﺪ در ﻛﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد .در اﻳﻦ ﺗﻮاﺑﻊ اﺑﺘﺪا ﻣﻘـﺪار ﻣﺘﻐﻴﻴــﺮ را ﺑﺮاﺑــﺮ ﻳــﻚ ﻧــﺎم ﺧــﺎص ﻗــﺮار داده و ﺳــﭙﺲ ﻛــﺎدر ﭘﻴﻐــﺎم را ﻧﻤــﺎﻳﺶ ﻣﻴﺪﻫﻴــﺪ .ﺑﻨــﺎﺑﺮاﻳﻦ در اﻳــﻦ ﻣﺜــﺎل ﻫﻨﮕــﺎﻣﻲ ﺷــﻤﺎ ﻣﺘــﺪ DisplayBathazarNameرا ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﺪ ،ﻣﺘﻐﻴﻴﺮ ﻫﺎي ﺗﻌﺮﻳﻒ ﺷﺪه در آن ﻣﺘﺪ ﺑﻼﻓﺎﺻﻠﻪ اﻳﺠﺎد ﻣـﻲ ﺷـﻮﻧﺪ ،ﻣﺘـﺪ وﻇﺎﻳﻒ ﺧﻮد را اﻧﺠﺎم ﻣﻲ دﻫﺪ و ﺑﺎ ﭘﺎﻳﺎن ﻳﺎﻓﺘﻦ ﻣﺘﺪ ،ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﻧﻴﺰ از ﺣﺎﻓﻈﻪ ﺣﺬف ﻣﻲ ﺷﻮﻧﺪ. ﻧﻜﺘﻪ :در ﺑﺨﺶ ﺑﻌﺪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣﺤﺪوده ﻓﻌﺎﻟﻴﺖ ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺣﺘﻲ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ داﺧﻞ ﻳﻚ ﺣﻠﻘﻪ در داﺧﻞ ﻣﺘﺪ ﻣﺤﺪود ﺷﻮد.
ﻧﺘﻴﺠﻪ: در اﻳﻦ ﻓﺼﻞ ﻣﺒﺎﺣﺚ و اﺻﻮل ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﻧﻮﺷﺘﻦ ﻧﺮم اﻓﺰار را ﺑﻴﺎن ﻛﺮدﻳﻢ .ﺑﻴﺸﺘﺮ اﻳﻦ اﺻـﻮل ﻓﻘـﻂ ﻣﺤـﺪود ﺑـﻪ زﺑـﺎن وﻳـﮋوال C# ﻧﻴﺴﺘﻨﺪ ،ﺑﻠﻜﻪ در ﻫﺮ زﺑﺎﻧﻲ ﺻﺪق ﻣﻴﻜﻨﻨﺪ .ﻓﺼﻞ را ﺑﺎ ﻣﻌﺮﻓﻲ اﻟﮕﻮرﻳﺘﻢ ﻫﺎ آﻏﺎز ﻛﺮدﻳﻢ ﻛﻪ ﭘﺎﻳﻪ و اﺳﺎس ﺗﻤﺎم ﻧﺮم اﻓﺰارﻫـﺎ ﻫـﺴﺘﻨﺪ .ﺳـﭙﺲ ﻣﻔﺎﻫﻴﻢ اوﻟﻴﻪ ﻣﺘﻐﻴﻴﺮ ﻫﺎ را ﻣﻌﺮﻓﻲ ﻛﺮدﻳﻢ و از ﻧﺰدﻳﻚ ﭘﺮﻛﺎرﺑﺮد ﺗﺮﻳﻦ ﻧﻮع ﻫﺎي داده اي را از ﻗﺒﻴـﻞ ،string ،double ،int DateTimeو Booleanﺑﺮرﺳﻲ ﻛﺮدﻳﻢ .ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻛﺎرﻫﺎي ﮔﻮﻧﺎﮔﻮﻧﻲ روي اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻫـﺎ اﻧﺠـﺎم داد .ﻣﺜﻼ اﻧﺠﺎم ﻋﻤﻠﻴﺎت رﻳﺎﺿﻲ روي ﻣﺘﻐﻴﻴﺮ ﻫﺎي ﻋﺪدي ،اﺗﺼﺎل رﺷﺘﻪ ﻫﺎي ﻣﺨﺘﻠﻒ ﺑﻪ ﻫﻢ و اﻳﺠﺎد رﺷﺘﻪ ﺟﺪﻳـﺪ ،ﺑﺪﺳـﺖ آوردن ﻃـﻮل ﻳﻚ رﺷﺘﻪ ،ﺗﻘﺴﻴﻢ ﻳﻚ ﻣﺘﻦ ﺑﻪ ﭼﻨﺪ زﻳﺮرﺷﺘﻪ ،ﺑﺪﺳﺖ آوردن ﺗﺎرﻳﺦ ﺟﺎري ﺳﻴﺴﺘﻢ و ﻳﺎ دﺳﺘﺮﺳﻲ ﺑﻪ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﺗﺎرﻳﺦ از ﻗﺒﻴﻞ ﻣﺎه، ﺳﺎل و ...ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺘﻬﺎي آن .ﺳﭙﺲ ﻧﺤﻮه ذﺧﻴﺮه ﺷﺪن ﻣﺘﻐﻴﻴﺮ ﻫﺎ در ﺣﺎﻓﻈﻪ ﻳﻚ ﺳﻴﺴﺘﻢ را ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ. ﺑﻌﺪ از اﻳﻦ ﻣﻮارد ﻧﮕﺎﻫﻲ ﺑﻪ ﻣﺘﺪﻫﺎ اﻧﺪاﺧﺘﻴﻢ .اﻳﻦ ﻛﻪ ﻣﺘﺪﻫﺎ ﭼﻴﺴﺘﻨﺪ ،ﭼﺮا ﺑﻪ آﻧﻬﺎ ﻧﻴﺎز ﭘﻴﺪا ﻣﻴﻜﻨﻴﻢ ،ﭼﮕﻮﻧﻪ آﻧﻬـﺎ را اﻳﺠـﺎد ﻛﻨـﻴﻢ و ﺑـﻪ آﻧﻬـﺎ ﭘﺎراﻣﺘﺮ ﺑﻔﺮﺳﺘﻴﻢ .ﻫﻤﭽﻨﻴﻦ ﻣﺤﺪوده ﻓﻌﺎﻟﻴﺖ ﻣﺘﻐﻴﻴﺮ ﻫﺎ را در ﻳﻚ ﻣﺘﺪ را ﻧﻴﺰ ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ. در ﭘﺎﻳﺎن ﺑﺎﻳﺪ ﺑﺪاﻧﻴﺪ:
اﻟﮕﻮرﻳﺘﻢ ﻫﺎ ﭼﻴﺴﺘﻨﺪ و ﭼﮕﻮﻧﻪ در ﺗﻮﺳﻌﻪ ﻧﺮم اﻓﺰار ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ. ﭼﮕﻮﻧﻪ ﻣﺘﻐﻴﻴﺮ ﻫﺎﻳﻲ از ﻧﻮع ﻫﺎي داده اي ﻣﺨﺘﻠﻒ را اﻳﺠﺎد و اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﭼﮕﻮﻧﻪ از ﭘﺮﻛﺎرﺑﺮد ﺗﺮﻳﻦ ﺗﻮاﺑﻊ ﻛﺎر ﺑﺎ رﺷﺘﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺘﻐﻴﻴﺮي از ﻧﻮع stringدارﻳﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﭼﮕﻮﻧﻪ از ﻧﻮع داده اي DateTimeﺑﺮاي ﻧﮕﻬﺪاري زﻣﺎن و ﺗﺎرﻳﺦ اﺳﺘﻔﺎده ﻛﻨﻴﺪ و آﻧﻬﺎ را ﺑـﺮ اﺳـﺎس ﺗﻨﻈﻴﻤـﺎت ﻣﺤﻠـﻲ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻛﺎرﺑﺮ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﻴﺪ. ﭼﮕﻮﻧﻪ ﻣﺘﺪﻫﺎي ﺳﺎده را ﺗﻌﺮﻳﻒ و اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
Local Scope
1
١٠٦
ﺗﻤﺮﻳﻦ:
ﺗﻤﺮﻳﻦ :1 ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﺤﺖ وﻳﻨﺪوز ﺑﺎ دو ﻛﻨﺘﺮل Buttonاﻳﺠﺎد ﻛﻨﻴﺪ .در روﻳﺪاد Clickدﻛﻤﻪ اول دو ﻣﺘﻐﻴﻴﺮ از ﻧﻮع ﻋـﺪد ﺻـﺤﻴﺢ اﻳﺠـﺎد ﻛﻨﻴﺪ و ﻣﻘﺪار اوﻟﻴﻪ آﻧﻬﺎ را ﺑﺮاﺑﺮ ﻋﺪدي دﻟﺨﻮاه ﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ ﺗﻌﺪادي از ﻋﻤﻠﻴﺎت رﻳﺎﺿﻲ ﻣﺨﺘﻠﻒ را روي اﻳﻦ اﻋﺪاد اﻧﺠﺎم داده و ﻧﺘﻴﺠﻪ را در ﺧﺮوﺟﻲ ﻧﻤﺎﻳﺶ دﻫﻴﺪ. در روﻳﺪاد Clickدﻛﻤﻪ ﻓﺮﻣﺎن دوم دو ﻣﺘﻐﻴﻴﺮ از ﻧﻮع رﺷﺘﻪ ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ و ﻣﻘﺪار آﻧﻬﺎ را ﺑﺮاﺑﺮ رﺷﺘﻪ دﻟﺨﻮاه ﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ دو رﺷﺘﻪ را ﺑﻪ ﻫﻢ ﻣﺘﺼﻞ ﻛﺮده و ﻧﺘﻴﺠﻪ را ﻧﻤﺎﻳﺶ دﻫﻴﺪ.
ﺗﻤﺮﻳﻦ :2 ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﺤﺖ وﻳﻨﺪوز ﺑﺎ ﻳﻚ ﻛﻨﺘﺮل TextBoxو ﻳﻚ ﻛﻨﺘﺮل Buttonاﻳﺠﺎد ﻛﻨﻴﺪ .در روﻳﺪاد Clickدﻛﻤﻪ ﻓﺮﻣﺎن ،ﺳﻪ ﻛﺎدر ﭘﻴﻐﺎم را ﻧﻤﺎﻳﺶ دﻫﻴﺪ .ﻛﺎدر ﭘﻴﻐﺎم اول ﺑﺎﻳﺪ ﻃﻮل رﺷﺘﻪ ي درون TextBoxرا ﻧﻤﺎﻳﺶ دﻫـﺪ .ﻛـﺎدر ﭘﻴﻐـﺎم دوم ﺑﺎﻳـﺪ ﻧﻴﻤـﻪ اول رﺷﺘﻪ و ﻛﺎدر ﭘﻴﻐﺎم ﺳﻮم ﻧﻴﻤﻪ دوم رﺷﺘﻪ را ﻧﻤﺎﻳﺶ دﻫﺪ.
١٠٧
ﻓﺼﻞ ﭼﻬﺎرم :ﻛﻨﺘﺮل روﻧﺪ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ در ﻓﺼﻞ ﺳﻮم در ﻣﻮرد اﻟﮕﻮرﻳﺘﻢ ﻫﺎ و ﻛﺎرﺑﺮد آﻧﻬﺎ در ﻧﺮم اﻓﺰار ﻣﻄﺎﻟﺒﻲ را آﻣﻮﺧﺘﻴﺪ .در اﻳﻦ ﻓﺼﻞ ﻧﺤـﻮه ﻛﻨﺘـﺮل روﻧـﺪ اﺟـﺮاي ﺑﺮﻧﺎﻣـﻪ در ﻃﻮل اﻳﻦ اﻟﮕﻮرﻳﺘﻢ ﻫﺎ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد .ﺑﺮاي ﻣﺜﺎل ﺧﻮاﻫﻴﺪ دﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﺼﻤﻴﻤﺎﺗﻲ از ﻗﺒﻴﻞ "اﮔﺮ Xﺑـﻪ اﻳـﻦ ﺣﺎﻟـﺖ ﺑﻮد A ،را اﻧﺠﺎم ﺑﺪه در ﻏﻴﺮ اﻳﻦ ﺻﻮرت Bرا اﻧﺠﺎم ﺑﺪه" را در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد ﭘﻴﺎده ﻛﻨﻴﺪ .اﻳﻦ ﻗﺎﺑﻠﻴﺖ در اﻟﮕﻮرﻳﺘﻢ ﺑﺮﻧﺎﻣﻪ ﻫـﺎ ﺑـﻪ ﻋﻨـﻮان اﻧﺸﻌﺎب ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮد .ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﻓﺼﻞ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﻗﻄﻌﻪ ﻛﺪ را ﺑﻪ ﺗﻌﺪاد ﻣﺮﺗﺒﻪ ﻣﺸﺨﺺ و ﻳـﺎ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﺷﺮط درﺳﺖ اﺳﺖ اﺟﺮا ﻛﻨﻴﺪ. ﺧﺼﻮﺻﺎ در اﻳﻦ ﻓﺼﻞ در ﻣﻮرد ﻣﻮارد زﻳﺮ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد:
دﺳﺘﻮر if switch ﺣﻠﻘﻪ ﻫﺎي forو foreach ﺣﻠﻘﻪ ﻫﺎي do … whileو do … until
ﺗﺼﻤﻴﻢ ﮔﻴﺮي در ﺑﺮﻧﺎﻣﻪ: اﻟﮕﻮرﻳﺘﻢ ﻫﺎ ﻫﻤﻮاره داراي ﺗﺼﻤﻴﻤﺎﺗﻲ ﻫﺴﺘﻨﺪ .در واﻗﻊ ،اﻳﻦ ﺗﺼﻤﻴﻤﺎت اﺳﺖ ﻛﻪ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﺘﻮاﻧﺪ وﻇﻴﻔﻪ ﺧﻮد را ﺑـﻪ ﺧـﻮﺑﻲ اﻧﺠﺎم دﻫﺪ .ﻫﻨﮕﺎم ﻛﺪ ﻧﻮﻳﺴﻲ ﺑﺎ ﺗﺼﻤﻴﻢ ﮔﻴﺮي ﻫﺎي زﻳﺎدي ﻣﻮاﺟﻪ ﻣﻲ ﺷﻮﻳﺪ .ﻣﺜﻼ ﻓﺮض ﻛﻨﻴﺪ ﻛﻪ ﻟﻴﺴﺘﻲ ﺷﺎﻣﻞ ده ﻧـﺎم در اﺧﺘﻴـﺎر ﺷـﻤﺎ ﻗﺮار داده اﻧﺪ و ﺑﺎﻳﺪ ﻛﺪي ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ ﺑﻪ اﻋﻀﺎي اﻳﻦ ﻟﻴﺴﺖ ﻧﺎﻣﻪ اي را ﺑﻔﺮﺳﺘﺪ .در ﻫﺮ ﻗﺴﻤﺖ از اﻳﻦ ﻛﺪ ﻣﻲ ﭘﺮﺳـﻴﺪ "آﻳـﺎ ﻟﻴـﺴﺖ ﺗﻤـﺎم ﺷﺪه اﺳﺖ؟" اﮔﺮ ﭼﻨﻴﻦ ﺑﻮد اﻟﮕﻮرﻳﺘﻢ ﺗﻤﺎم ﻣﻲ ﺷﻮد .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻧﺎم ﻧﻔﺮ ﺑﻌﺪي از ﻟﻴﺴﺖ اﺳﺘﺨﺮاج ﻣﻴﺸﻮد و ﻣﺮاﺣـﻞ ارﺳـﺎل ﻧﺎﻣـﻪ ﺑﺮاي او اﻧﺠﺎم ﻣﻴﺸﻮد .ﺑﻪ ﻋﻨﻮان ﻣﺜﺎﻟﻲ دﻳﮕﺮ ﻣﻤﻜﻦ اﺳﺖ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﻓﺎﻳﻠﻲ را ﺑﺎز ﻛﻨﻴﺪ .در اﻳﻦ ﺣﺎﻟﺖ اﺑﺘﺪا ﻣﻲ ﭘﺮﺳﻴﺪ "آﻳـﺎ ﻓﺎﻳـﻞ ﻣـﻮرد ﻧﻈﺮ وﺟﻮد دارد؟" .در ﺻﻮرت وﺟﻮد ﻓﺎﻳﻞ را ﺑﺎز ﻣﻲ ﻛﻨﻴﺪ و در ﻏﻴﺮ اﻳﻦ ﺻﻮرت اﻟﮕﻮرﻳﺘﻢ را ﺑﻪ اﺗﻤﺎم ﻣﻴﺮﺳﺎﻧﻴﺪ. ﺗﻤﺎم اﻳﻦ ﺗﺼﻤﻴﻢ ﮔﻴﺮﻳﻬﺎ ﺑﻪ ﻳﻚ ﻧﺤﻮ در ﺑﺮﻧﺎﻣﻪ ﭘﻴﺎده ﺳﺎزي ﻣﻲ ﺷﻮﻧﺪ .در اﺑﺘﺪا ﺑﻪ ﺑﺮرﺳﻲ دﺳﺘﻮر ifﺑﺮاي ﻛﻨﺘﺮل روﻧـﺪ اﺟـﺮاي ﺑﺮﻧﺎﻣـﻪ ﻣﻲ ﭘﺮدازﻳﻢ.
دﺳﺘﻮر :if راﺣﺖ ﺗﺮﻳﻦ راه ﺑﺮاي ﺗﺼﻤﻴﻢ ﮔﻴﺮي در وﻳﮋوال 2005 C#اﺳﺘﻔﺎده از دﺳﺘﻮر ifاﺳﺖ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ﺑﺎ ﻧﺤﻮه ﻛﺎرﺑﺮد اﻳـﻦ دﺳﺘﻮر آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ:
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻳﻚ دﺳﺘﻮر ifﺳﺎده
١٠٨
(1ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﺤﺖ وﻳﻨﺪوز ﺑﻪ ﻧﺎم Simple Ifاﻳﺠﺎد ﻛﻨﻴﺪ .ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل Buttonﺑـﺮ روي ﻓﺮم ﻗﺮار داده ،ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ btnIfو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑـﺮ Ifﻗـﺮار دﻫﻴـﺪ .روي اﻳـﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در آن وارد ﻛﻨﻴﺪ: )private void btnIf_Click(object sender, EventArgs e { // Declare and set a variable ;int intNumber = 27 // Here's where you make a desicion // and tell the user what happend )if (intNumber == 27 { MessageBox.Show("'intNumber' is, indeed, 27!", ;)""Simple If } }
(2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن Ifﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛﺎدر ﭘﻴﻐﺎﻣﻲ را ﻣﺸﺎﺑﻪ ﺷﻜﻞ 1-4ﺧﻮاﻫﻴﺪ دﻳﺪ.
ﺷﻜﻞ 1-4
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﺑﺘﺪا ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﻧﺎم intNumberاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ و ﻣﻘﺪار آن را ﺑﺮاﺑﺮ 27ﻗﺮار ﻣﻲ دﻫﻴﺪ )ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ ﺑﻴﻨﻴﺪ ﻫﻢ ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴﺮ و ﻫﻢ ﻣﻘﺪار دﻫﻲ اوﻟﻴﻪ ﺑﻪ آن در ﻳﻚ ﺧﻂ اﻧﺠﺎم ﺷﺪه اﺳﺖ(: ;int intNumber = 27 ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر ifﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﺑﺎﻳﺪ ﭼﻪ ﻛﺎري اﻧﺠﺎم دﻫﻴﺪ .در اﻳﻨﺠﺎ ﺷﻤﺎ ﻣﻴﮕﻮﻳﻴﺪ "اﮔﺮ intNumberﺑﺮاﺑﺮ ﺑﺎ 27ﺑﻮد."... // Here's where you make a desicion // and tell the user what happend )if (intNumber == 27
١٠٩
{ MessageBox.Show("'intNumber' is, indeed, 27!", ;)""Simple If } ﻗﻄﻌﻪ ﻛﺪي ﻛﻪ درون آﻛﻮﻻد ﭘﺎﻳﻴﻦ دﺳﺘﻮر ifﻗﺮار دارد ﻓﻘﻂ ﻫﻨﮕﺎﻣﻲ اﺟﺮا ﻣﻴﺸﻮد ﻛﻪ intNumberﺑﺮاﺑﺮ ﺑﺎ 27ﺑﺎﺷﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺷﺮط داﺧﻞ ﭘﺮاﻧﺘﺰ ﺑﺮاﺑﺮ trueو ﻳﺎ درﺳﺖ ﺑﺎﺷﺪ ،ﻛﺪ داﺧﻞ ﺑﻼك ifاﺟﺮا ﻣﻲ ﺷﻮد. ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻨﺠﺎ ،اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺷﺮوع ﻣﻴﺸﻮد و ﺑﻪ دﺳﺘﻮر ifﻣﻴﺮﺳﺪ .ﺑﻌﺪ از ارزﻳـﺎﺑﻲ ﻋﺒـﺎرت داﺧـﻞ ﭘﺮاﻧﺘـﺰ ﭼـﻮن ﻣﻘـﺪار آن ﺑﺮاﺑـﺮ ﺑـﺎ trueاﺳﺖ ،دﺳﺘﻮرات درون ﺑﻼك ifاﺟﺮا ﻣﻲ ﺷﻮﻧﺪ و ﺳﭙﺲ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ از ﺧﻂ ﺑﻌﺪ از ﺑﻼك ifاداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ. ﻧﻜﺘﻪ :دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻛﺪﻫﺎي درون ﺑﻼك ifﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺑﺎ ﻣﻘﺪاري ﺗﻮرﻓﺘﮕﻲ 1ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮﻧﺪ .اﻳـﻦ ﻣـﻮرد ﺑﺎﻋـﺚ اﻓـﺰاﻳﺶ ﺧﻮاﻧﺎﻳﻲ ﻛﺪ ﻣﻲ ﺷﻮد ،زﻳﺮا ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ ﻧﮕﺎﻫﻲ ﺳﺮﻳﻊ ﺑﮕﻮﻳﻴﺪ ﻛﻪ ﻛﺪام ﻗﺴﻤﺖ از ﻛﺪ در ﺻﻮرت ﺻﺤﻴﺢ ﺑﻮدن دﺳﺘﻮر ifاﺟﺮا ﻣﻲ ﺷـﻮد. ﻫﻤﭽﻨﻴﻦ ﺑﺮاي ﺧﻮاﻧﺎﻳﻲ ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﺑﻬﺘﺮ اﺳﺖ ﻗﺒﻞ و ﺑﻌﺪ از ﺑﻼك ifﻣﻘﺪاري ﻓﻀﺎي ﺧﺎﻟﻲ ﻗﺮار دﻫﻴﺪ. ﻳﻚ دﺳﺘﻮر ifﺳﺎده ﻫﻤﺎﻧﻨﺪ ﻗﺴﻤﺖ ﻗﺒﻞ ﻣﻴﺘﻮاﻧﺪ ﺑﻮدن ﻫﻴﭻ آﻛﻮﻻدي ﻧﻮﺷﺘﻪ ﺷﻮد .اﻟﺒﺘﻪ اﻳﻦ ﻛﺎر ﻫﻨﮕﺎﻣﻲ اﻣﻜﺎﻧﭙـﺬﻳﺮ اﺳـﺖ ﻛـﻪ ﺑـﻼك ifﻓﻘﻂ ﺷﺎﻣﻞ ﻳﻚ دﺳﺘﻮر ﺑﺎﺷﺪ .ﺑﻪ ﻛﺪ زﻳﺮ ﻧﮕﺎه ﻛﻨﻴﺪ: )if (intNumber == 27 MessageBox.Show("'intNumber' is, indeed, 27!", ;)""Simple If اﻳﻦ دﺳﺘﻮر ﻫﻢ ﻣﺎﻧﻨﺪ دﺳﺘﻮر ifدر ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ ﻛﺎر ﻣﻲ ﻛﻨﺪ و ﻣﺰﻳﺖ آن ﻓﻘﻂ اﻳﻦ اﺳﺖ ﻛﻪ ﻛﺪ را ﻛﻮﺗﺎﻫﺘﺮ ﻣﻲ ﻛﻨﺪ. اﻣﺎ اﮔﺮ ﻧﺘﻴﺠﻪ ﻳﻚ ﺷﺮط ﻧﺎدرﺳﺖ ﺑﺎﺷﺪ ،ﭼﻪ اﺗﻔﺎﻗﻲ ﻣﻲ اﻓﺘﺪ؟ در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي اﻳﻦ ﺣﺎﻟﺖ را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻧﺎدرﺳﺖ ﺑﻮدن ﺷﺮط (1اﮔﺮ ﺑﺮﻧﺎﻣﻪ Simple Ifدر ﺣﺎل اﺟﺮا اﺳﺖ آن را ﺑﺒﻨﺪﻳﺪ .ﻛﻨﺘﺮل Buttonدﻳﮕﺮي ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴـﺪ ،ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑﺮ btnAnotherIfو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑـﺮ Another Ifﻗـﺮار دﻫﻴـﺪ .روي دﻛﻤﻪ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن وارد ﻛﻨﻴﺪ: private void btnAnotherIf_Click(object sender, )EventArgs e { // Declare and set a variable ;int intNumber = 27 // Here’s where you make a decision, // and tell the user what happened )if (intNumber == 1000 Indention
1
١١٠
{ MessageBox.Show("‘intNumber’ is, indeed, " + ;)""1000!", "Simple If } } (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﻳﻦ ﺣﺎﻟﺖ ،ﺟﻮاب ﺳﻮال "آﻳﺎ intNumberﺑﺮاﺑﺮ ﺑﺎ 1000اﺳﺖ؟" ﺧﻴﺮ اﺳﺖ .ﺑﻼك دﺳﺘﻮرات ﻫﻢ ﻓﻘﻂ در ﺣﺎﻟﺘﻲ اﺟﺮا ﻣﻲ ﺷﻮد ﻛﻪ ﻧﺘﻴﺠﻪ ﺷﺮط ﺑﺮاﺑﺮ trueﺑﺎﺷﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ ﻛﺪﻫﺎي اﻳﻦ ﺑﻼك اﺟﺮا ﻧﺨﻮاﻫﻨﺪ ﺷﺪ .در ﭼﻨﻴﻦ ﺷﺮاﻳﻄﻲ ﻛﻨﺘﺮل ﺑﺮﻧﺎﻣﻪ ﺑﻼﻓﺎﺻـﻠﻪ ﺑـﻪ ﺧـﻂ ﺑﻌﺪ از ifﻣﻨﺘﻘﻞ ﻣﻲ ﺷﻮد و ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ آن را اﺟﺮا ﻣﻲ ﻛﻨﺪ.
دﺳﺘﻮر :Else اﮔﺮ ﺑﺨﻮاﻫﻴﺪ در ﺻﻮرت درﺳﺖ ﺑﻮدن ﺷﺮط ﻗﺴﻤﺘﻲ از ﺑﺮﻧﺎﻣﻪ و در ﺻﻮرت ﻏﻠﻂ ﺑﻮدن آن ﻗﺴﻤﺘﻲ دﻳﮕﺮ اﺟﺮا ﺷـﻮد ،ﻣـﻲ ﺗﻮاﻧﻴـﺪ از دﺳـﺘﻮر elseاﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻧﺤﻮه ﻛﺎرﺑﺮد اﻳﻦ دﺳﺘﻮر را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :دﺳﺘﻮر else (1ﻛﺪ درون روﻳﺪاد Clickﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل btnAnotherIfرا ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ: private void btnAnotherIf_Click(object sender, )EventArgs e { // Declare and set a variable ;int intNumber = 27 // Here’s where you make a decision, // and tell the user what happened )if (intNumber == 1000 { MessageBox.Show("‘intNumber’ is, indeed, " + ;)""1000!", "Simple If } else {
١١١
MessageBox.Show("‘intNumber’ is not 1000!", ;)""Simple If } } (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ Another Ifﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 2-4را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 2-4
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻛﺪي ﻛﻪ در ﺑﻼك elseوارد ﺷﺪه اﺳﺖ ،ﻓﻘﻂ در ﺻﻮرﺗﻲ اﺟﺮا ﻣﻲ ﺷﻮد ﻛﻪ ﻋﺒﺎرت درون ﭘﺮاﻧﺘﺰ ifﻧﺎدرﺳﺖ ﺑﺎﺷﺪ .در اﻳـﻦ ﺣﺎﻟـﺖ، ﻣﻘﺪار intNumberﺑﺮاﺑﺮ ﺑﺎ 27اﺳﺖ ،اﻣﺎ ﭼﻮن در ﺷﺮط ﺑﺎ ﻋﺪد 1000ﻣﻘﺎﻳﺴﻪ ﺷﺪه اﺳﺖ ﺑﻨﺎﺑﺮاﻳﻦ ﺷﺮط ﻏﻠﻂ اﺳـﺖ و ﻛـﺪ ﻧﻮﺷـﺘﻪ ﺷﺪه در ﺑﺨﺶ elseاﺟﺮا ﺧﻮاﻫﺪ ﺷﺪ: else { MessageBox.Show("‘intNumber’ is not 1000!", ;)""Simple If }
ﺑﺮرﺳﻲ ﭼﻨﺪ ﺷﺮط ﺑﺎ :else if اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﻴﺶ از ﻳﻚ ﺣﺎﻟﺖ را ﺗﺴﺖ ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ از ﺗﺮﻛﻴﺐ دﺳﺘﻮر elseو ifاﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻣﺘﺤﺎن ﻛﻨﻴـﺪ ﺑﻌـﺪي ،ﺑﺮﻧﺎﻣـﻪ Simple Ifرا ﺑﻪ ﻧﺤﻮي ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻴﻢ ﻛﻪ ﺑﺮاﺑﺮي intNumberرا ﺑﺎ ﭼﻨﺪ ﻋﺪد ﻣﺨﺘﻠﻒ ﺑﺮرﺳﻲ ﻛﻨﺪ و ﻧﺘﻴﺠﻪ را ﻧﻤﺎﻳﺶ دﻫﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :دﺳﺘﻮر else if (1ﻛﺪ درون ﻣﺘﺪ btnAnotherIf_Clickرا ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ: private void btnAnotherIf_Click(object sender,
١١٢
)EventArgs e { // Declare and set a variable ;int intNumber = 27 // Here’s where you make a decision, // and tell the user what happened )if (intNumber == 1000 { MessageBox.Show("‘intNumber’ is, indeed, " + ;)""1000!", "Simple If } )else if (intNumber == 27 { MessageBox.Show("‘intNumber’ is 27!", ;)""Simple If } else { MessageBox.Show("‘intNumber’ is neither 1000" + ;)"" nor 27!", "Simple If } } (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ ﻓﺮﻣﺎن Another Ifﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 3-4را ﺧﻮاﻫﻴﺪ دﻳﺪ.
ﺷﻜﻞ 3-4
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ دﺳﺘﻮرات ﺑﺨﺶ else ifاﺟﺮا ﻣﻲ ﺷﻮﻧﺪ ،زﻳﺮا intNumberﺑﺮاﺑﺮ ﺑﺎ ﻋﺪد 27اﺳﺖ و ﺑﻨﺎﺑﺮاﻳﻦ ﻋﺒﺎرت داﺧـﻞ else ifدرﺳﺖ ﺧﻮاﻫﺪ ﺑﻮد .ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ اﮔﺮ ﺷﺮط داﺧﻞ else ifﻧﻴﺰ ﻏﻠﻂ ﺑﻮد ،ﻛﺪﻫﺎي ﺑﺨـﺶ elseاﺟـﺮا ﻣﻲ ﺷﺪﻧﺪ. در ﻳﻚ ﺳﺮي دﺳﺘﻮرات ifو else ifﻣﺘﻮاﻟﻲ ،ﺷﺮاﻳﻂ از ﺑﺎﻻﺗﺮﻳﻦ ifﺑﻪ ﺳﻤﺖ ﭘﺎﻳﻴﻦ ﺑﺮرﺳﻲ ﻣﻲ ﺷﻮﻧﺪ و اوﻟﻴﻦ ﻋﺒـﺎرﺗﻲ ﻛـﻪ درﺳﺖ ارزﻳﺎﺑﻲ ﺷﺪ ،دﺳﺘﻮرات ﻣﺮﺑﻮط ﺑﻪ آن اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ .ﭘﺲ در ﺑﺮﻧﺎﻣﻪ ﻗﺒﻞ اﮔﺮ ﺷﺮط اول را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ ﻛﻪ درﺳﺖ ﺑﺎﺷﺪ )ﺑﺮاي ﻣﺜﺎل داﺧﻞ ﭘﺮاﻧﺘﺰ ﻋﺒﺎرت intNumber > 10را ﻗﺮار دﻫﻴﻢ ﻛﻪ ﺑﻪ ﻋﻠﺖ ﺑﺰرﮔﺘﺮ ﺑﻮدن intNumberاز 10ﺑﺮاﺑـﺮ
١١٣
ﺑﺎ trueاﺳﺖ( ،ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﺷﺮط دوم ﻫﻢ درﺳﺖ اﺳﺖ دﺳﺘﻮرات ﺷﺮط اول اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ و ﻛﻨﺘﺮل ﺑﺮﻧﺎﻣﻪ ﺑـﻪ اوﻟـﻴﻦ ﺧـﻂ ﺑﻌـﺪ از ﺳﺮي دﺳﺘﻮرات ifﻣﻲ رود. )else if (intNumber == 27 { MessageBox.Show("‘intNumber’ is 27!", ;)""Simple If } else { MessageBox.Show("‘intNumber’ is neither 1000" + ;)"" nor 27!", "Simple If } ﺷﻤﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻫﺮ ﺗﻌﺪاد ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﻗﺴﻤﺘﻬﺎي else ifرا ﺑﻪ ﻳﻚ دﺳﺘﻮر ifﺑﺮاي ﺑﺮرﺳﻲ ﺣﺎﻟﺘﻬﺎي ﻣﺨﺘﻠﻒ اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ. اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ذﻛﺮ ﺷﺪ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ وﻳﮋوال C#ﺑﻪ اوﻟﻴﻦ دﺳﺘﻮر ifرﺳﻴﺪ ﺷﺮط داﺧﻞ آن را ﺑﺮرﺳﻲ ﻣﻴﻜﻨﺪ .اﮔﺮ ﻋﺒﺎرت داﺧﻞ ﭘﺮاﻧﺘـﺰ درﺳﺖ ارزﻳﺎﺑﻲ ﺷﻮد ،دﺳﺘﻮرات داﺧﻞ ﺑﻼك ifاﺟﺮا ﻣﻲ ﺷﻮﻧﺪ و ﻛﻨﺘﺮل ﺑﺮﻧﺎﻣﻪ ﺑﻪ اوﻟﻴﻦ ﺧﻂ ﺑﻌـﺪ از ﺳـﺮي دﺳـﺘﻮرات ifو else ﻣﻴﺮود .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ،ﻋﺒﺎرت ﻣﺮﺑﻮط ﺑﻪ اوﻟﻴﻦ else ifارزﻳﺎﺑﻲ ﻣﻲ ﺷﻮد .اﻳﻦ روﻧﺪ اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ ﺗﺎ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺑﻼﻛـﻲ از دﺳﺘﻮرات ﺑﺮﺳﺪ ﻛﻪ ﺣﺎﺻﻞ آن درﺳﺖ ﺑﺎﺷﺪ .در اﻳﻦ ﺣﺎﻟﺖ دﺳﺘﻮرات اﻳﻦ ﺑﻼك اﺟﺮا ﺷﺪه و ﻛﻨﺘﺮل ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺑﻌـﺪ از ﻣﺠﻤﻮﻋـﻪ دﺳـﺘﻮرات ifو elseﻣﻲ رود. ﻧﻜﺘﻪ :ﻫﻨﮕﺎم ﺑﺮرﺳﻲ ﻳﻚ ﺳﺮي از ﺣﺎﻟﺘﻬﺎ ،ﺑﻬﺘﺮ اﺳﺖ آﻧﻬﺎﻳﻲ را ﻛﻪ اﺣﺘﻤﺎل درﺳﺖ ﺑﻮدﻧﺸﺎن ﺑﻴﺸﺘﺮ اﺳﺖ ،اﺑﺘﺪا ﺑﺮرﺳﻲ ﻛﻨﻴـﺪ .اﻳـﻦ ﻣـﻮرد ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﻨﮕﺎم اﺟﺮا ،ﺷﺮاﻳﻂ اﺿﺎﻓﻪ را ﺑﺮرﺳﻲ ﻧﻜﻨﺪ و ﻛﺪ ﺳﺮﻳﻌﺘﺮ اﺟﺮا ﺷﻮد. ﻧﻜﺘﻪ :در ﻣﻮاردي ﻛﻪ ﺗﻌﺪاد ﻗﺴﻤﺘﻬﺎي else ifدر ﺑﺮﻧﺎﻣﻪ زﻳﺎد ﺑﺎﺷﺪ و ﺣﺎﻟﺘﻬﺎي زﻳﺎدي را ﺑﺎﻳﺪ ﺑﺮرﺳﻲ ﻛﻨﻴﺪ ،ﺑﻪ ﺟـﺎي اﺳـﺘﻔﺎده از ifو else ifﻣﻴﺘﻮاﻧﻴﺪ از switchاﺳﺘﻔﺎده ﻛﻨﻴﺪ ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﺑﻌﺪي ﺗﻮﺿﻴﺢ داده ﻣﻲ ﺷﻮﻧﺪ.
دﺳﺘﻮرات ifﺗﻮدرﺗﻮ: ﻋﻼوه ﺑﺮ اﺳﺘﻔﺎده ﻣﺘﻮاﻟﻲ از دﺳﺘﻮرات ،ifﻣﻲ ﺗﻮاﻧﻴﺪ در داﺧﻞ ﻳﻚ ifاز دﺳﺘﻮرات ifدﻳﮕﺮي اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑـﻪ ﻣﺜـﺎل زﻳـﺮ ﺗﻮﺟـﻪ ﻛﻨﻴﺪ: )if (intX > 3 { MessageBox.Show("intX is greater that 3", ;)""Sample If )if (intX == 6 ;)"MessageBox.Show("intX is 6!", "Sample If }
١١٤
در اﺳﺘﻔﺎده از دﺳﺘﻮرات ifﺗﻮدرﺗﻮ ﻫﻴﭻ ﻣﺤﺪودﻳﺘﻲ ﻧﻴﺴﺖ .اﻟﺒﺘﻪ ﺑﺎﻳﺪ دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻫﺮ ﭼﻪ ﺗﻌـﺪاد ifﻫـﺎي ﺗﻮدرﺗـﻮ در ﺑﺮﻧﺎﻣـﻪ ﺑﻴـﺸﺘﺮ ﺑﺎﺷﺪ ،درك آن ﻣﺸﻜﻠﺘﺮ ﻣﻲ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﺳﻌﻲ ﻛﻨﻴﺪ ﺗﺎ ﺟﺎﻳﻲ ﻛﻪ ﻣﻴﺘﻮاﻧﻴﺪ ﺗﻌﺪاد ifﻫﺎي ﺗﻮدرﺗﻮ را در ﺑﺮﻧﺎﻣﻪ ﻛﻢ ﻛﻨﻴﺪ.
ﻋﻤﻠﮕﺮﻫﺎي ﻣﻘﺎﻳﺴﻪ اي: در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ،ﻧﺤﻮه ﺑﺮرﺳﻲ ﺑﺮاﺑﺮ ﺑﻮدن ﻳﻚ ﻣﺘﻐﻴﻴﺮ را ﺑﺎ ﻣﻘﺎدﻳﺮ ﻣﺨﺘﻠﻒ ﺑﺮاي اﺳﺘﻔﺎده در ﺷﺮط ﻳﻚ دﺳﺘﻮر ifدﻳﺪﻳﻢ .اﻣـﺎ دﺳـﺘﻮر ifﺑﺴﻴﺎر اﻧﻌﻄﺎف ﭘﺬﻳﺮ ﺗﺮ اﺳﺖ .ﺷﻤﺎ ﻣﻴﺘﻮاﻧﻴﺪ ﺑﺮاي ﺷﺮط اﻳﻦ دﺳﺘﻮر از ﺳﻮاﻟﻬﺎﻳﻲ ﻣﺜﻞ ﻣﻮارد زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ﻛﻪ ﭘﺎﺳﺦ ﻫﻤﻪ آﻧﻬﺎ ﺑﻠﻪ ﻳﺎ ﺧﻴﺮ اﺳﺖ:
آﻳﺎ intNumberﺑﺰرﮔﺘﺮ از 49اﺳﺖ؟ آﻳﺎ intNumberﻛﻮﭼﻜﺘﺮ از 49اﺳﺖ؟ آﻳﺎ intNumberﺑﺰرﮔﺘﺮ ﻳﺎ ﻣﺴﺎوي 49اﺳﺖ؟ آﻳﺎ intNumberﻛﻮﭼﻜﺘﺮ ﻳﺎ ﻣﺴﺎوي 49اﺳﺖ؟ آﻳﺎ strNameﺑﺮاﺑﺮ ﺑﺎ Benاﺳﺖ؟
ﻫﻨﮕﺎم ﻛﺎر ﺑﺎ ﻣﺘﻐﻴﻴﺮ ﻫﺎي رﺷﺘﻪ اي ،ﻣﻌﻤﻮﻻ از ﺷﺮﻃﻬﺎي ﺑﺮاﺑﺮ ﺑﻮدن ﻳﺎ ﻣﺨﺎﻟﻒ ﺑﻮدن اﺳﺘﻔﺎده ﻣﻴﻜﻨﻴﺪ .اﻣﺎ ﻫﻨﮕﺎم ﻛﺎر ﺑﺎ ﻣﺘﻐﻴﻴﺮ ﻫﺎي ﻋﺪدي )ﭼﻪ اﻋﺪاد ﺻﺤﻴﺢ و ﭼﻪ اﻋﺪاد اﻋﺸﺎري( ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺗﻤﺎم ﻋﻤﻠﮕﺮ ﻫﺎي رﻳﺎﺿﻲ ﻛﻪ در ﺑﺎﻻ ذﻛﺮ ﺷﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ ﻣﺨﺎﻟﻒ: ﺗﺎﻛﻨﻮن از ﻋﻤﻠﮕﺮ ﻣﺨﺎﻟﻒ اﺳﺘﻔﺎده ﻧﻜﺮده اﻳﻢ .ﺑﻨﺎﺑﺮاﻳﻦ در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﻧﺤﻮه اﺳـﺘﻔﺎده از اﻳـﻦ ﻋﻤﻠﮕـﺮ را ﺑـﺎ ﻣﺘﻐﻴﻴـﺮ ﻫـﺎي رﺷـﺘﻪ اي ﺧﻮاﻫﻴﻢ دﻳﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ ﻣﺨﺎﻟﻒ (1ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﺤﺖ وﻳﻨﺪوز ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم If Demoاﻳﺠﺎد ﻛﻨﻴﺪ. (2ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺤﻴﻂ ﻃﺮاﺣﻲ Form1را ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﻳﻚ ﻛﻨﺘـﺮل TextBoxو ﻳـﻚ ﻛﻨﺘـﺮل Buttonرا ﺑـﻪ وﺳﻴﻠﻪ ﺟﻌﺒﻪ اﺑﺰار ﺑﺮ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ .ﺧﺎﺻﻴﺖ Nameﻛﻨﺘﺮل TextBoxرا ﺑﺮاﺑـﺮ ﺑـﺎ txtNameو ﺧﺎﺻـﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Robbinﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ ﺧﺎﺻﻴﺖ Nameﻛﻨﺘﺮل Buttonرا ﺑﺮاﺑﺮ btnCheckو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ Checkﻗﺮار دﻫﻴﺪ. (3روي Buttonدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در ﺑﺨﺶ روﻳﺪاد Clickﻣﺮﺑﻮط ﺑﻪ آن ﻗﺮار دﻫﻴﺪ: )private void btnCheck_Click(object sender, EventArgs e { // Declare a variable and // get the name from the text box ١١٥
;string strName ;strName = txtName.Text ?// Is the name Gretchen )"if (strName != "Gretchen MessageBox.Show("The name is *not* Gretchen.", ;)""If Demo } (4ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ Checkﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛﺎدر ﭘﻴﻐﺎﻣﻲ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣﻴﮕﻮﻳﺪ ﻧـﺎم داﺧـﻞ ﺟﻌﺒـﻪ ﻣﺘﻨﻲ ﺑﺮاﺑﺮ ﺑﺎ Gretchenﻧﻴﺴﺖ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻋﻤﻠﮕﺮ ﻣﺨـﺎﻟﻒ در زﺑـﺎن C#ﺑـﻪ ﺻـﻮرت =! اﺳـﺖ .ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻛـﺎرﺑﺮ روي دﻛﻤـﻪ ﻓﺮﻣـﺎن ﻛﻠﻴـﻚ ﻣـﻲ ﻛﻨـﺪ ،اول ﻣـﺘﻦ درون TextBoxﺑﻪ وﺳﻴﻠﻪ ﺧﺎﺻﻴﺖ Textآن ﺑﺪﺳﺖ آورده ﻣﻲ ﺷﻮد و درون ﻳﻚ ﻣﺘﻐﻴﻴﺮ رﺷﺘﻪ اي ﻗﺮار ﻣﻲ ﮔﻴﺮد. // Declare a variable and // get the name from the text box ;string strName ;strName = txtName.Text ﺑﻌﺪ از اﻳﻨﻜﻪ ﻧﺎم وارد ﺷﺪه در ﻣﺘﻐﻴﻴﺮ ﻗﺮار ﮔﺮﻓﺖ ،ﺑﺎ اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ ﻣﺨﺎﻟﻒ ﻣﻘﺪار درون ﻣﺘﻐﻴﻴﺮ رﺷﺘﻪ اي ﺑﺎ ﻳﻚ ﻋﺒﺎرت رﺷﺘﻪ اي دﻳﮕـﺮ ﻣﻘﺎﻳﺴﻪ ﺷﺪه و ﻧﺘﻴﺠﻪ اﻳﻦ ﻣﻘﺎﻳﺴﻪ ﺑﺮاي اﺟﺮاي دﺳﺘﻮرات ifاﺳﺘﻔﺎده ﻣﻲ ﺷﻮد. ?// Is the name Gretchen )"if (strName != "Gretchen MessageBox.Show("The name is *not* Gretchen.", ;)""If Demo ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻴﻢ ،دﺳﺘﻮرات درون ﺑﻼك ifﻓﻘﻂ در ﺻﻮرﺗﻲ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﻧﺘﻴﺠﻪ داﺧﻞ ﭘﺮاﻧﺘﺰ ﺑﺮاﺑﺮ ﺑـﺎ trueﺑﺎﺷـﺪ .ﻣﻤﻜـﻦ اﺳﺖ ﻋﻤﻠﮕﺮ ﻣﺨﺎﻟﻒ در اﺑﺘﺪا ﻣﻘﺪاري ﮔﻴﺞ ﻛﻨﻨﺪه ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ ،اﻣﺎ ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﺳﻮاﻟﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﭘﺮﺳﻴﺪه ﻣﻴﺸﻮد اﻳﻦ اﺳﺖ ﻛﻪ "آﻳﺎ ﻣﻘﺪار strNameﻣﺨﺎﻟﻒ Gretchenاﺳﺖ؟" .در اﻳﻦ ﺣﺎﻟﺖ ﭘﺎﺳـﺦ ﺑـﻪ ﺻـﻮرت "ﺑﻠـﻪ ،ﻣﻘـﺪار strNameﻣﺨـﺎﻟﻒ ﺑـﺎ Gretchenاﺳﺖ" ﺧﻮاﻫﺪ ﺑﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﭘﺎﺳﺦ اﻳﻦ ﺳﻮال ﺑﻪ ﺻﻮرت ﺑﻠﻪ اﺳﺖ ﻛﻪ trueارزﻳﺎﺑﻲ ﻣﻴـﺸﻮد .دﻗـﺖ ﻛﻨﻴـﺪ ﻛـﻪ اﮔـﺮ ﻣﻘﺪار Gretchenرا در TextBoxوارد ﻛﻨﻴﺪ ،ﻣﻘﺪار ﺷﺮط ﺑﺮاﺑﺮ ﺑﺎ ﻏﻠﻂ ﺧﻮاﻫﺪ ﺑﻮد و دﺳﺘﻮرات ﺑﻼك ifاﺟﺮا ﻧﺨﻮاﻫﻨﺪ ﺷﺪ. ﻧﻜﺘﻪ :اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻣﺘﻦ Gretchenرا در TextBoxوارد ﻛﻨﻴﺪ ،ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﺣﺘﻤﺎ اﻳﻦ ﻣﺘﻦ ﺑﻪ ﻫﻤﺎن ﺻـﻮرت ﻛـﻪ در ﻛﺪ ﺑﺮرﺳﻲ ﻣﻲ ﺷﻮد ﻧﻮﺷﺘﻪ ﺷﻮد )در اﻳﻨﺠﺎ ﺑﺎ Gﺑﺰرگ( .زﻳﺮا ﺑﺮرﺳﻲ ﺷﺮط در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺻﻮرت ﺣﺴﺎس ﺑﻪ ﺣﺮوف اﻧﺠﺎم ﻣﻲ ﺷـﻮد و اﮔﺮ ﻓﺮﺿﺎً ﻋﺒﺎرت gretchenرا وارد ﻛﻨﻴﺪ ،دو ﻣﻘﺪار ﺑﺮاﺑﺮ ﻧﺨﻮاﻫﺪ ﺑﻮد و ﻣﺠﺪدا ﻛﺎدر ﻣﺘﻨﻲ ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
١١٦
ﻧﻜﺘﻪ :ﻋﻼﻣﺖ ! در C#ﺑﺮاي ﻣﻌﻜﻮس ﻛﺮدن ﻣﻘﺪار ﻳﻚ ﺷﺮط ﺑﻪ ﻛﺎر ﻣﻲ رود .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﺣﺎﺻﻞ ﺷﺮﻃﻲ ﺑﺮاﺑﺮ ﺑـﺎ trueﺑﺎﺷـﺪ و ﻗﺒﻞ از آن از ﻋﻤﻠﮕﺮ ! اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﻧﺘﻴﺠﻪ ﺑﺮاﺑﺮ falseارزﻳﺎﺑﻲ ﻣﻲ ﺷﻮد .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻣﻘـﺪار ﻣﺘﻐﻴﻴـﺮ strNameﺑﺮاﺑـﺮ ﺑـﺎ Robbinﺑﺎﺷﺪ ،ﺣﺎﺻﻞ ﻋﺒﺎرت زﻳﺮ falseﺧﻮاﻫﺪ ﺑﻮد: ))"if (!(strName == "Robbin ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻋﻤﻠﮕﺮ ﻣﺨﺎﻟﻒ در ﺑﺮﻧﺎﻣﻪ ﺑﺎﻻ را ﻣﻲ ﺗﻮان ﺑﻪ ﺻﻮرت زﻳﺮ ﻧﻮﺷﺖ: ))"if (!(strName == "Gretchen
اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ ﻫﺎي ﻣﻘﺎﻳﺴﻪ اي: در اﻳﻦ ﺑﺨﺶ ﭼﻬﺎر ﻋﻤﻠﮕﺮ ﻣﻘﺎﻳﺴﻪ اي دﻳﮕﺮ را ﻣﻌﺮﻓﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﻫﺎي ﺑﻌﺪي ﺑﺎ اﻳﻦ ﻋﻤﻠﮕﺮ ﻫﺎ آﺷﻨﺎ ﻣﻲ ﺷﻮﻳﺪ:
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ ﻛﻮﭼﻜﺘﺮ (1اﮔﺮ ﺑﺮﻧﺎﻣﻪ If Demoدر ﺣﺎل اﺟﺮا اﺳـﺖ ،آن را ﺑﺒﻨﺪﻳـﺪ .ﻗـﺴﻤﺖ ﻃﺮاﺣـﻲ ﻓـﺮم را ﺑـﺮاي Form1ﺑـﺎز ﻛﻨﻴـﺪ ،ﻳـﻚ TextBoxﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﺪ و ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ txtValueﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ ﻳـﻚ Button دﻳﮕﺮ ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮده ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑـﺮ btnCheckNumberو ﺧﺎﺻـﻴﺖ Textآن را ﺑﺮاﺑـﺮ Check Numbersﻗﺮار دﻫﻴﺪ. (2روي ﻛﻨﺘﺮل Buttonدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در روﻳﺪاد Clickآن وارد ﻛﻨﻴﺪ: private void btnCheckNumber_Click(object sender, )EventArgs e { // Declare variable ;int intNumber = 0 try { // Get the number from the text box ;)intNumber = Int32.Parse(txtValue.Text } catch { } ?// Is intNumber less than 27 )if (intNumber < 27 MessageBox.Show("Is ‘intNumber’ less than 27? " + ;)""Yes!", "If Demo ١١٧
else MessageBox.Show("Is ‘intNumber’ less than 27? " + ;)""No!", "If Demo } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻋﺪدي را در TextBoxوارد ﻛﺮده و روي دﻛﻤﻪ Check Numbersﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .ﻛـﺎدر ﭘﻴﻐﺎﻣﻲ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺑﻪ ﺷﻤﺎ ﻣﻴﮕﻮﻳﺪ ﻋﺪد وارد ﺷﺪه در TextBoxﺑﺰرﮔﺘﺮ از 27اﺳﺖ ﻳﺎ ﻧﻪ؟ )ﺷﻜﻞ (4-4
ﺷﻜﻞ 4-4
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﺑﺘﺪا ﺑﺎﻳﺪ ﻣﻘﺪار ﻋﺪدي وارد ﺷﺪه در TextBoxرا ﺑﺪﺳﺖ آورد .ﺑﺮاي اﻳﻦ ﻛﺎر اﺑﺘﺪا ﺑﺎﻳـﺪ ﻣﻄﻤـﺌﻦ ﺷـﻮﻳﻢ ﻣـﺘﻦ داﺧـﻞ TextBoxﺷﺎﻣﻞ ﻋﺪد اﺳﺖ .زﻳﺮا ﻛﺎرﺑﺮ ﺑﺮﻧﺎﻣﻪ آزاد اﺳﺖ ﻛﻪ ﻫﺮ ﻣﺘﻨﻲ را در اﻳﻨﺠﺎ وارد ﻛﻨﺪ ،و ﻣﻤﻜﻦ اﺳﺖ ﻣـﺘﻦ وارد ﺷـﺪه ﺷـﺎﻣﻞ ﻫﻴﭻ ﻋﺪدي ﻧﺒﺎﺷﺪ ﻛﻪ در اﻳﻦ ﺣﺎﻟﺖ ﺑﺮﻧﺎﻣﻪ در ﺗﺒﺪﻳﻞ آن ﺑﻪ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ ﺑﺎ ﺷﻜﺴﺖ ﻣﻮاﺟﻪ ﻣﻲ ﺷـﻮد و ﺑﻘﻴـﻪ ﻛـﺪ اﺟـﺮا ﻧﻤـﻲ ﺷـﻮد. ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ ﻛﺪي را ﺑﺮاي ﻣﺪﻳﺮﻳﺖ اﻳﻦ اﺳﺘﺜﻨﺎ ﻫﺎ وارد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ اﮔـﺮ ﻛـﺎرﺑﺮ ﻣﻘـﺪاري ﻏﻴـﺮ از ﻋـﺪد وارد ﻛـﺮد ﻣﺘﻐﻴﻴـﺮ intNumberﺑﺮاﺑﺮ ﺑﺎ ﺻﻔﺮ ﺷﻮد ،در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻋﺪد وارد ﺷﺪه ﺗﻮﺳﻂ ﻛﺎرﺑﺮ در آن ﻗﺮار ﮔﻴﺮد. // Declare variable ;int intNumber = 0 try { // Get the number from the text box ;)intNumber = Int32.Parse(txtValue.Text } catch { } ﻧﻜﺘﻪ :دﺳﺘﻮر try…catchدر ﻓﺼﻞ 11ﺑﻪ ﺻﻮرت ﻛﺎﻣﻞ ﺑﺮرﺳﻲ ﻣﻲ ﺷﻮد ،ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻦ ﻗﺴﻤﺖ ﻣﻴﺘﻮاﻧﻴـﺪ از آن ﺻـﺮف ﻧﻈـﺮ ﻛﻨﻴﺪ. ﺑﺮاي ﺗﺒﺪﻳﻞ ﻳﻚ رﺷﺘﻪ ﻛﻪ ﺷﺎﻣﻞ ﻋﺪد اﺳﺖ ﺑﻪ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ ﺑﺎﻳﺪ از ﺗﺎﺑﻊ Parseدر Int32اﺳﺘﻔﺎده ﻛﻨﻴـﺪ .اﻳـﻦ ﺗـﺎﺑﻊ ﻳـﻚ رﺷﺘﻪ را ﻛﻪ ﺷﺎﻣﻞ ﻳﻚ ﻋﺪد اﺳﺖ درﻳﺎﻓﺖ ﻛﺮده و ﻋﺪد ﻣﻌﺎدل آن را ﺑﺮﻣﻴﮕﺮداﻧﺪ .اﮔﺮ رﺷﺘﻪ اي ﻛﻪ ﺑﻪ اﻳﻦ ﺗﺎﺑﻊ ﻓﺮﺳﺘﺎده ﻣـﻲ ﺷـﻮد ﺷـﺎﻣﻞ ﻋﺪد ﻧﺒﺎﺷﺪ ،ﻳﺎ ﺣﺘﻲ داراي ﻛﺎراﻛﺘﺮي ﻏﻴﺮ ﻋﺪدي ﺑﺎﺷﺪ ،ﺗﺎﺑﻊ ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟﻪ ﺷﺪه و اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﺘﻮﻗﻒ ﻣﻲ ﺷﻮد.
١١٨
در ﺑﺨﺶ ﺑﻌﺪي ،ﺑﻪ وﺳﻴﻠﻪ دﺳﺘﻮر ifﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻋﺪد وارد ﺷﺪه در TextBoxﺑﺰرﮔﺘﺮ از 27اﺳﺖ ﻳﺎ ﻧﻪ و ﺑـﺮ اﺳـﺎس آن ﭘﻴﻐﺎم ﻣﻨﺎﺳﺒﻲ را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﺪ. ?// Is intNumber less than 27 )if (intNumber < 27 MessageBox.Show("Is ‘intNumber’ less than 27? " + ;)""Yes!", "If Demo else MessageBox.Show("Is ‘intNumber’ less than 27? " + ;)""No!", "If Demo ﻧﻜﺘﻪ :ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻼﺣﻈﻪ ﻣﻲ ﻛﻨﻴﺪ ،در اﻳﻦ ﻗﺴﻤﺖ ﭼﻮن ﻫﻢ در ﺑﺨﺶ ifو ﻫﻢ در ﺑﺨﺶ elseﻓﻘـﻂ ﻳـﻚ دﺳـﺘﻮر وارد ﺷـﺪه اﺳﺖ ﻧﻴﺎزي ﺑﻪ اﺳﺘﻔﺎده از آﻛﻮﻻد در اﺑﺘﺪا و اﻧﺘﻬﺎي دﺳﺘﻮر ﻧﻴﺴﺖ. ﺟﺎﻟﺐ اﻳﻨﺠﺎﺳﺖ ﻛﻪ اﮔﺮ دﻗﻴﻘﺎ ﻣﻘﺪار 27را در TextBoxوارد ﻛﻨﻴﺪ ،ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد ﻛﻪ ﻋـﺪد ﻛـﻮﭼﻜﺘﺮ از 27ﻧﻴـﺴﺖ .زﻳـﺮا ﻋﻤﻠﮕـﺮ ﻛﻮﭼﻜﺘﺮ ﻓﻘﻂ در ﺻﻮرﺗﻲ ﻣﻘﺪار trueرا ﺑﺮﻣﻲ ﮔﺮداﻧﺪ ﻛﻪ ﻋﺪد ﻛﻮﭼﻜﺘﺮ ﺑﺎﺷﺪ ،ﻧﻪ ﺑﺰرﮔﺘﺮ ﻳﺎ ﻣﺴﺎوي .ﺑﺮاي اﻳﻨﻜﻪ ﺷﺮط ﺑﺎﻻ ﺧـﻮد ﻋـﺪد 27را ﻧﻴﺰ ﺷﺎﻣﻞ ﺷﻮد ﺑﺎﻳﺪ از ﻋﻤﻠﮕﺮ ﻛﻮﭼﻜﺘﺮ ﻣﺴﺎوي اﺳﺘﻔﺎده ﻛﻨﻴﺪ ﻛﻪ در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ﺷﺮح داده ﺷﺪه اﺳﺖ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ ﻛﻮﭼﻜﺘﺮ ﻳﺎ ﻣﺴﺎوي (1ﻛﺪ ﻣﻮﺟﻮد در روﻳﺪاد Clickﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل Buttonدر ﻗﺴﻤﺖ ﻗﺒﻠﻲ را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ: // Declare variable ;int intNumber try { // Get the number from the text box ;)intNumber = Int32.Parse(txtValue.Text } catch { } ?// Is intNumber less than or equal to 27 )if (intNumber <= 27 MessageBox.Show("Is ‘intNumber’ less than or " + ;)""equal to 27? Yes!", "If Demo else MessageBox.Show("Is ‘intNumber’ less than or " + ;)""equal to 27? No!", "If Demo
١١٩
(2ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﻋﺪد 27را در TextBoxوارد ﻛﻨﻴﺪ .روي دﻛﻤﻪ Check Numbersﻛﻠﻴـﻚ ﻛﻨﻴـﺪ. ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 5-4ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
ﺷﻜﻞ 5-4
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺗﻨﻬﺎ ﺗﻔﺎوﺗﻲ ﻛﻪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﺴﺒﺖ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ دارد اﻳﻦ اﺳﺖ ﻛﻪ ﺷﺮط دﺳﺘﻮر ifﺧﻮد ﻋﺪد 27را ﻧﻴﺰ ﺷﺎﻣﻞ ﻣﻲ ﺷﻮد .ﻳﻌﻨـﻲ اﮔـﺮ در ﺟﻌﺒﻪ ﻣﺘﻨﻲ ﻋﺪد 27وارد ﻛﻨﻴﺪ ،ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 4-5را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد. دو ﻋﻤﻠﮕﺮ دﻳﮕﺮ ﻣﺸﺎﺑﻪ ﻋﻤﻠﮕﺮ ﻫﺎي ﻗﺒﻠﻲ ﻣﻲ ﺑﺎﺷﺪ ﻛﻪ در ﺑﺨﺶ ﺑﻌﺪي آﻧﻬﺎ را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ ﺑﺰرﮔﺘﺮ و ﺑﺰرﮔﺘﺮ ﻣﺴﺎوي (1روﻳﺪاد Clickﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل Buttonرا ﺑﺎز ﻛﺮده و ﻛﺪ زﻳﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ: ?// Is intNumber less than or equal to 27 )if (intNumber <= 27 MessageBox.Show("Is ‘intNumber’ less than or" + ;)""equal to 27? Yes!", "If Demo else MessageBox.Show("Is ‘intNumber’ less than or" + ;)""equal to 27? No!", "If Demo ?// Is intNumber greater than 27 ) if (intNumber > 27 MessageBox.Show("Is ‘intNumber’ greater than" + ;)""27? Yes!", "If Demo else MessageBox.Show("Is ‘intNumber’ greater than" + ;)""27? No!", "If Demo ?// Is intNumber greater than or equal to 27 )if( intNumber >= 27
١٢٠
MessageBox.Show("Is ‘intNumber’ greater than" + "or equal to 27? Yes!", "If ;)"Demo else MessageBox.Show("Is ‘intNumber’ greater than" + ;)""or equal to 27? No!", "If Demo (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﻣﻘﺪار 99را در ﺟﻌﺒﻪ ﻣﺘﻨﻲ وارد ﻛﻨﻴﺪ .ﺳﭙﺲ روي دﻛﻤﻪ Check Numbersﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺳﻪ ﻛﺎدر ﭘﻴﻐﺎم ﻣﺘﻮاﻟﻲ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد .در ﻛﺎدر ﭘﻴﻐﺎم اول ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد ﻛﻪ ﻋﺪد ﻛﻮﭼﻜﺘﺮ ﻳﺎ ﻣﺴﺎوي 27ﻧﻴﺴﺖ .در ﻛـﺎدر ﭘﻴﻐﺎم دوم و ﺳﻮم ﺑﻪ ﺗﺮﺗﻴﺐ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻋﺪد ﺑﺰرﮔﺘﺮ و ﻫﻤﭽﻨﻴﻦ ﺑﺰرﮔﺘﺮ ﻣﺴﺎوي 27اﺳﺖ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻋﻤﻠﮕﺮ ﻫﺎي ﺑﺰرﮔﺘﺮ و ﺑﺰرﮔﺘﺮ ﻣﺴﺎوي دﻗﻴﻘﺎ ﺑﺮ ﻋﻜﺲ ﻋﻤﻠﮕﺮ ﻛﻮﭼﻜﺘﺮ و ﻛﻮﭼﻜﺘﺮ ﻣﺴﺎوي ﻋﻤﻞ ﻣﻲ ﻛﻨﺪ .ﺳـﻮاﻻﺗﻲ ﻛـﻪ در اﻳـﻦ ﻗـﺴﻤﺖ ﺑﺮاي ﺷﺮط ifﻣﻲ ﭘﺮﺳﻴﺪ ﺑﻪ ﺻﻮرت "آﻳﺎ intNumberﺑﺰرﮔﺘﺮ از 27اﺳﺖ؟" و " آﻳﺎ intNumberﺑﺰرﮔﺘﺮ ﻳـﺎ ﻣـﺴﺎوي 27اﺳﺖ؟" ﺧﻮاﻫﺪ ﺑﻮد ﻛﻪ ﺑﺮ اﺳﺎس ﭘﺎﺳﺦ آﻧﻬﺎ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﺷﺮط ifاﺟﺮا ﻣﻲ ﺷﻮد.
ﻋﻤﻠﮕﺮ ﻫﺎي Andو Orﻣﻨﻄﻘﻲ: 1 در ﺑﻌﻀﻲ از ﺷﺮاﻳﻂ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ ﺑﻪ ﺟﺎي ﻳﻚ ﺷﺮط ،ﭼﻨﺪ ﺷﺮط را در دﺳﺘﻮر ifﺑﺮرﺳﻲ ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺧﻮاﻫﻴـﺪ ﺑﺪاﻧﻴـﺪ آﻳﺎ intNumberﺑﺰرﮔﺘﺮ از 27و ﻛﻮﭼﻜﺘﺮ از 10اﺳﺖ ﻳﺎ ﻧﻪ و ﻳﺎ ﻣﻴﺨﻮاﻫﻴﺪ ﺑﺪاﻧﻴﺪ آﻳﺎ strNameﺑﺮاﺑﺮ " "Sydneyو ﻳﺎ " "Stephanieاﺳﺖ ﻳﺎ ﻧﻪ .در اﻳﻦ ﻣﻮارد ﻣﻴﺘﻮاﻧﻴﺪ ﺷﺮﻃﻬﺎي درون دﺳﺘﻮر ifرا ﺑﻪ وﺳﻴﻠﻪ ﻋﻤﻠﮕﺮ ﻫﺎي Andو Orﻣﻨﻄﻘﻲ ﺗﺮﻛﻴﺐ ﻛﻨﻴﺪ .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،روش اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ Orرا ﺧﻮاﻫﻴﻢ دﻳﺪ .ﻧﺘﻴﺠﻪ ﺗﺮﻛﻴﺐ ﭼﻨﺪ ﺷﺮط ﺑﻪ وﺳـﻴﻠﻪ اﻳـﻦ ﻋﻤﻠﮕـﺮ ﻓﻘـﻂ ﻫﻨﮕﺎﻣﻲ درﺳﺖ ﻛﻪ ﺣﺪاﻗﻞ ﻳﻜﻲ از ﺷﺮوط ﺑﺮاﺑﺮ ﺑﺎ درﺳﺖ ﺑﺎﺷﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ ﻫﺎي Andو Or (1ﺑﺮﻧﺎﻣﻪ وﻳﻨﺪوزي ﺟﺪﻳﺪي ﺑﻪ ﻧﺎم And Or Demoاﻳﺠﺎد ﻛﻨﻴﺪ. (2در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ Form1دو ﻛﻨﺘﺮل TextBoxو ﻳﻚ ﻛﻨﺘﺮل Buttonاﺿﺎﻓﻪ ﻛﻨﻴـﺪ .ﺧﺎﺻـﻴﺖ Nameﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮﻟﻬﺎي TextBoxرا ﺑﺮاﺑﺮ txtName1و txtName2و ﺧﺎﺻـﻴﺖ Nameﻛﻨﺘـﺮل Buttonرا ﺑﺮاﺑﺮ btnOrCheckﻗﺮار دﻫﻴﺪ. (3ﺧﺎﺻﻴﺖ Textﻣﺮﺑﻮط ﺑﻪ TextBoxاول را ﺑﺮاﺑﺮ Sydneyو TextBoxدوم را ﺑﺮاﺑـﺮ Stephanie ﻗﺮار دﻫﻴﺪ .در آﺧﺮ ﺧﺎﺻﻴﺖ Textﻛﻨﺘﺮل Buttonرا ﺑﺮاﺑﺮ Or Checkﻗﺮار دﻫﻴﺪ .ﺑﻌﺪ از اﻳـﻦ ﺗﻨﻈﻴﻤـﺎت ﻓـﺮم ﺷﻤﺎ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 6-4ﺑﺎﺷﺪ.
1در ﻣﻘﺎﺑﻞ ﻋﻤﻠﮕﺮ ﻫﺎي Andو Orﻣﻨﻄﻘﻲ ،ﻋﻤﻠﮕﺮ ﻫﺎي Andو Orﺑﻴﺘﻲ ﻧﻴﺰ وﺟﻮد دارﻧﺪ ﻛﻪ ﺑﺮاي اﻳﺠﺎد ﺗﻐﻴﻴﺮات روي ﺑﻴﺘﻬﺎ ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ.
١٢١
6-4 ﺷﻜﻞ
. آن وارد ﻛﻨﻴﺪClick دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در روﻳﺪادOr Check ( روي دﻛﻤﻪ4 private void btnOrCheck_Click(object sender, EventArgs e) { // Declare variables string strName1 , strName2; // Get the names strName1 = txtName1.Text; strName2 = txtName2.Text; // Is one of the names Sydney? if (strName1 == "Sydney" || strName2 == "Sydney") MessageBox.Show("One of the names is Sydney.", "And Or Demo"); else MessageBox.Show("Neither of the names is Sydney.", "And Or Demo"); } . ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد7-4 ﻛﺎدر ﭘﻴﻐﺎﻣﻲ را ﻣﺸﺎﺑﻪ ﺷﻜﻞ. ﻛﻠﻴﻚ ﻛﻨﻴﺪOr Check ( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ5
7-4 ﺷﻜﻞ
١٢٢
(6روي دﻛﻤﻪ OKﺑﺮ روي ﻛﺎدر ﭘﻴﻐﺎم ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑﻪ ﻓـﺮم اﺻـﻠﻲ ﺑﺮﮔﺮدﻳـﺪ .ﺣـﺎل ﻣـﺘﻦ داﺧـﻞ TextBoxاول را ﺑـﻪ Stephanieو ﻣﺘﻦ ﺟﻌﺒﻪ ﻣﺘﻨﻲ دوم را ﺑﻪ Sydneyﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﻣﺠـﺪدا روي دﻛﻤـﻪ Or Checkﻛﻠﻴـﻚ ﻛﻨﻴﺪ .ﻛﺎدر ﭘﻴﻐﺎﻣﻲ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣﻲ ﮔﻮﻳﺪ ﻳﻜﻲ از TextBoxﻫﺎ ﺷﺎﻣﻞ Sydneyاﺳﺖ. (7ﻣﺠﺪدا روي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ و در ﺻﻔﺤﻪ اﺻﻠﻲ ﻣﺘﻦ ﻫﺎي داﺧﻞ ﺻﻔﺤﻪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛـﻪ ﻫـﻴﭻ ﻳـﻚ از آﻧﻬـﺎ ﺷﺎﻣﻞ Sydneyﻧﺒﺎﺷﺪ و روي دﻛﻤﻪ Or Checkﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛﺎدر ﭘﻴﻐﺎﻣﻲ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣـﻲ ﮔﻮﻳـﺪ ﻫﻴﭻ ﻳﻚ از آﻧﻬﺎ ﺷﺎﻣﻞ Sydneyﻧﻴﺴﺖ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻋﻤﻠﮕﺮ || در C#ﺑﻪ ﻋﻨﻮان "ﻳﺎ" ﻣﻨﻄﻘﻲ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد و ﻣﻌﻤﻮﻻً در ﺑﺮرﺳﻲ ﺷﺮط ﻫﺎ ،ﺑﺮاي ﺗﺮﻛﻴﺐ دو ﺷﺮط ﻣﺘﻔﺎوت از ﻫﻢ ﺑﻪ ﻛﺎر ﻣﻲ رود .در روﻳﺪاد ،Clickاﺑﺘﺪا دو ﻣﺘﻐﻴﻴﺮ ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ و ﺳﭙﺲ ﻣﻘﺎدﻳﺮي ﻛﻪ ﻛﺎرﺑﺮ در TextBoxﻫﺎ وارد ﻛـﺮده اﺳـﺖ را آﻧﻬﺎ ﻗﺮار ﻣﻲ دﻫﻴﻢ. // Declare variables ;string strName1 , strName2 // Get the names ;strName1 = txtName1.Text ;strName2 = txtName2.Text ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻴﺒﻴﻨﻴﺪ در اﻳﻦ ﻗﺴﻤﺖ ﻫﺮ دوي ﻣﺘﻐﻴﻴﺮ ﻫﺎ در ﻳﻚ ﺧﻂ ﺗﻌﺮﻳﻒ ﺷﺪه اﻧﺪ .در C#اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﭼﻨﺪ ﻣﺘﻐﻴﻴﺮ از ﻳﻚ ﻧﻮع داﺷـﺘﻪ ﺑﺎﺷﻴﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﻫﻤﻪ آﻧﻬﺎ را ﻫﻤﺎﻧﻨﺪ ﻛﺪ ﺑﺎﻻ در ﻳﻚ ﺧﻂ ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ و ﻓﻘﻂ ﺑﺎﻳﺪ ﻧﺎم آﻧﻬﺎ را ﺑﺎ وﻳﺮﮔﻮل از ﻫﻢ ﺟﺪا ﻛﻨﻴﺪ .اﻳﻦ ﻣﻮرد ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﻓﺸﺮده ﺗﺮ ﺷﻮد و ﺗﻔﺎوﺗﻲ ﺑﺎ ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴﺮ ﻫﺎ در ﺧﻄﻬﺎي ﺟﺪاﮔﺎﻧﻪ ﻧﺪارد. ﺣﺎل ﻛﻪ ﻫﺮ دو ﻧﺎم را از داﺧﻞ TextBoxﻫﺎ ﺑﻪ دﺳﺖ آوردﻳﺪ ،ﻣﻴﺘﻮاﻧﻴﺪ آﻧﻬﺎ را در ﻳﻚ ﺷﺮط ifﺑﺎ اﺳﺘﻔﺎده از ﻋﻤﻠﮕـﺮ || ﺗﺮﻛﻴـﺐ ﻛﻨﻴﺪ .در اﻳﻦ ﺣﺎﻟﺖ ﺳﻮاﻟﻲ ﻛﻪ ﺷﻤﺎ در ﺑﺨﺶ ﺷﺮط ifاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ ﺑﻪ ﺻﻮرت "آﻳﺎ ﻣﻘﺪار strName1ﺑﺮاﺑـﺮ ﺑـﺎ Sydney اﺳﺖ و ﻳﺎ ﻣﻘﺪار strName2ﺑﺮاﺑﺮ ﺑﺎ Sydneyاﺳﺖ؟" ﺧﻮاﻫﺪ ﺑﻮد .در اﻳﻦ ﺣﺎﻟﺖ ﻣﻘﺪار ﻫﺮ ﻳﻚ از اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﻛـﻪ ﺑﺮاﺑـﺮ ﺑـﺎ Sydneyﺑﺎﺷﺪ ﻣﻮﺟﺐ ﻣﻴﺸﻮد ﻛﻪ ﭘﺎﺳﺦ ﺳﻮال ﺑﺮاﺑﺮ ﺑﺎ trueو ﻳﺎ درﺳﺖ ﺑﺎﺷﺪ. ?// Is one of the names Sydney )"if (strName1 == "Sydney" || strName2 == "Sydney MessageBox.Show("One of the names is Sydney.", ;)""And Or Demo else MessageBox.Show("Neither of the names is Sydney.", ;)""And Or Demo
اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ Andﻣﻨﻄﻘﻲ:
١٢٣
اﻳﻦ ﻋﻤﻠﮕﺮ ﻫﻢ ﻣﺎﻧﻨﺪ ﻋﻤﻠﮕﺮ Orﻣﻨﻄﻘﻲ اﺳﺖ ﺑﻪ ﺟﺰ اﻳﻨﻜﻪ ﺑﺮاي درﺳﺖ ﺑﻮدن ﺷﺮط آن ،ﺑﺎﻳﺪ ﺗﻚ ﺗﻚ ﺷﺮط ﻫﺎ درﺳﺖ ارزﻳـﺎﺑﻲ ﺷـﻮﻧﺪ. ﻋﻼﻣﺖ اﻳﻦ ﻋﻤﻠﮕﺮ در C#ﺑﻪ ﺻﻮرت && اﺳﺖ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ Andﻣﻨﻄﻘﻲ (1ﻛﻨﺘﺮل Buttonدﻳﮕـﺮي ﺑـﻪ ﻓـﺮم اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ ،ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑـﺮ btnAndCheckو ﺧﺎﺻـﻴﺖ Textآن را ﺑﺮاﺑﺮ And Checkﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ ﺑﺮ روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﺮده و ﻛﺪ ﻣـﺸﺨﺺ ﺷـﺪه در زﻳﺮ را در آن وارد ﻛﻨﻴﺪ: )private void btnAndCheck_Click(object sender, EventArgs e { // Declare variables ;string strName1, strName2 // Get the names ;strName1 = txtName1.Text ;strName2 = txtName2.Text ?// Are both names Sydney )"if( strName1 =="Sydney" && strName2 =="Sydney MessageBox.Show("Both names are Sydney.", ;)""And Or Demo else MessageBox.Show("One of the names is not" + ;)""Sydney.","And Or Demo } (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ And Checkﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛـﺎدر ﭘﻴﻐـﺎﻣﻲ را ﺧﻮاﻫﻴـﺪ دﻳـﺪ ﻛـﻪ ﻣـﻲ ﮔﻮﻳـﺪ ﻳﻜـﻲ از TextBoxﻫﺎ ﺷﺎﻣﻞ Sydneyﻧﻴﺴﺖ. (3اﻟﺒﺘﻪ اﮔﺮ ﻣﺘﻦ داﺧﻞ ﻫﺮ دو TextBoxرا ﺑﻪ Sydneyﺗﻐﻴﻴﺮ دﻫﻴﺪ ،ﻧﺘﻴﺠﻪ اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 8-4را ﺧﻮاﻫﻴﺪ دﻳﺪ.
ﺷﻜﻞ 8-4
١٢٤
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﻳﻨﺠﺎ ﺑﺎ اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ && ﻣﻲ. آﻧﻬﺎ را ﺑﺎ ﻫﻢ ﻣﻘﺎﻳﺴﻪ ﻣﻲ ﻛﻨﻴﺪ، را ﺑﺪﺳﺖ آوردﻳﺪTextBox ﺑﻌﺪ از اﻳﻨﻜﻪ ﻧﺎﻣﻬﺎي ﻣﻮﺟﻮد در واﺿﺢ اﺳﺖ ﺟـﻮاب اﻳـﻦ ﺳـﻮال."اﺳﺖ؟Sydney ﺑﺮاﺑﺮ ﺑﺎstrName2 وSydney ﺑﺮاﺑﺮ ﺑﺎstrName1 ﭘﺮﺳﻴﺪ "آﻳﺎ . ﺑﺎﺷﻨﺪSydney ﻣﺤﺘﻮي ﻛﻠﻤﻪTextBox ﻫﻨﮕﺎﻣﻲ درﺳﺖ اﺳﺖ ﻛﻪ ﻫﺮ دو // Are both names Sydney? if( strName1 =="Sydney" && strName2 =="Sydney") MessageBox.Show("Both names are Sydney.", "And Or Demo"); else MessageBox.Show("One of the names is not" + "Sydney.","And Or Demo");
: ﻣﻨﻄﻘﻲOr وAnd ﻣﻄﺎﻟﺐ ﺑﻴﺸﺘﺮ در راﺑﻄﻪ ﺑﺎ ﻋﻤﻠﮕﺮ ﻫﺎي اﻣﺎ ﻣﻴﺘﻮاﻧﻴﺪ اﻳﻦ ﻋﻤﻠﮕﺮ ﻫﺎ را ﺑﺎ اﻋﺪاد ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ زﻳﺮ ﺑﻪ، در رﺷﺘﻪ ﻫﺎ آﺷﻨﺎ ﺷﺪه اﻳﺪOr وAnd ﺗﺎﻛﻨﻮن ﺑﺎ ﻧﺤﻮه اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ ﻫﺎي :ﻛﺎر ﺑﺒﺮﻳﺪ
+
if( intX == 2 && dblY == 2.3) MessageBox.Show("Hello, the conditions has been" "satisfied!"); :ﻳﺎ if( intX == 2 || dblY == 2.3) MessageBox.Show("Hello, the conditions have been" + "satisfied!");
ﻣﻴﺘﻮاﻧﻴﺪ در ﺑﺮﻧﺎﻣﻪ ﺧـﻮد، ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ. ﻫﻴﭻ ﻣﺤﺪودﻳﺘﻲ ﻧﻴﺴﺖif در ﻳﻚ دﺳﺘﻮرOr وAnd ﻫﻤﭽﻨﻴﻦ در اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ ﻫﺎي :دﺳﺘﻮري ﻣﺸﺎﺑﻪ زﻳﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ if( intA == 1 && intB == 2 && intC intE == 5 && intF == 6 && intG intI == 2 && intJ == 3 && intK intM == 6 && intN == 7 && intO intQ == 3 && intR == 4 && intS intU == 7 && intV == 1 && intW intY == 4 && intZ == 5) MessageBox.Show("That’s quite
١٢٥
== == == == == ==
3 7 4 1 5 2
&& && && && && &&
intD intH intL intP intT intX
== == == == == ==
4 1 5 2 6 3
&& && && && && &&
an If statement!");
اﻟﺒﺘﻪ ﺑﺎﻳﺪ ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ اﺳﺘﻔﺎده زﻳﺎد از اﻳﻦ ﻋﻤﻠﮕﺮ ﻫﺎ از ﺧﻮاﻧﺎﻳﻲ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﻛﺎﻫﺪ و درك آن را ﻣﺸﻜﻞ ﺗﺮ ﻣﻲ ﻛﻨﺪ .ﭘﺲ ﺗﺎ ﺣـﺪ اﻣﻜﺎن ﺑﺎﻳﺪ از ﺷﺮﻃﻬﺎي ﻛﻤﺘﺮ در دﺳﺘﻮر ifﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﻫﻤﭽﻨﻴﻦ ﻣﻴﺘﻮاﻧﻴﺪ از ﭼﻨﺪ ﻋﻤﻠﮕﺮ Andو Orدر ﺷﺮط ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻳﻦ ﻣﻮاﻗﻊ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ﭘﺮاﻧﺘﺰﻫﺎ اﻳﻦ ﻋﻤﻠﮕﺮ ﻫﺎ را دﺳﺘﻪ ﺑﻨﺪي ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺧﻮاﻫﻴﺪ اﮔﺮ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮي ﺑﻴﻦ 10ﺗﺎ 20و ﻳﺎ ﺑﻴﻦ 25ﺗﺎ 30ﺑﺎﺷﺪ ،دﺳﺘﻮرات داﺧﻞ ﺷﺮط اﺟﺮا ﺷﻮﻧﺪ. در اﻳﻦ ﺻﻮرت ﻣﻲ ﺗﻮاﻧﻴﺪ از دﺳﺘﻮر ifزﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ: ))if( (intX > 10 && intX < 20) || (intX > 25 && intX < 30 ﺣﺎﻟﺘﻬﺎي ﻣﺨﺘﻠﻔﻲ ﺑﺮاي ﺗﺮﻛﻴﺐ ﻋﻤﻠﮕﺮﻫﺎ در ﻫﺮ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ وﺟﻮد دارد و ﺗﻌﺪاد آﻧﻬﺎ ﺑﻴﺸﺘﺮ از آن اﺳﺖ ﻛﻪ ﺑﺘﻮاﻧﻴﻢ آﻧﻬـﺎ را در اﻳـﻦ ﻛﺘﺎب ﻋﻨﻮان ﻛﻨﻴﻢ .اﻣﺎ ﺑﺪاﻧﻴﺪ ﻛﻪ ﻫﺮ ﺷﺮﻃﻲ را ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺑﺮرﺳﻲ ﻛﻨﻴﺪ ﻳﻚ ﺗﺮﻛﻴﺐ از اﻳﻦ ﻋﻤﮕﺮﻫﺎ وﺟﻮد دارد ﻛﻪ ﻧﻴﺎز ﺷـﻤﺎ را ﺑﺮﻃـﺮف ﻛﻨﺪ.
ﻣﻘﺎﻳﺴﻪ رﺷﺘﻪ ﻫﺎ: ﻣﻌﻤﻮﻻ ﻫﻨﮕﺎﻣﻲ ﻛﻪ در دﺳﺘﻮرات ifرﺷﺘﻪ ﻫﺎ را ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﻣﻘﺎﻳﺴﻪ ﻣﻲ ﻛﻨﻴﺪ ،ﺑﻪ ﻋﻠﺖ ﺣﺴﺎﺳﻴﺖ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺣﺮوف ﻛﻮﭼﻚ و ﺑـﺰرگ ﺑـﺎ ﻣﺸﻜﻞ ﻣﻮاﺟﻪ ﻣﻲ ﺷﻮﻳﺪ .ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻫﺮ دو ﻛﺎراﻛﺘﺮ " "aو " "Aﺑﺮاي اﻧﺴﺎﻧﻬﺎ ﻳﻚ ﻣﻌﻨﻲ را دارﻧﺪ و ﻳﻜﺴﺎن ﺗﻠﻘﻲ ﻣﻲ ﺷـﻮﻧﺪ ،اﻣـﺎ در ﻛﺎﻣﭙﻴﻮﺗﺮ دو ﻛﺎراﻛﺘﺮ ﻣﺠﺰا از ﻳﻜﺪﻳﮕﺮ ﻫﺴﺘﻨﺪ .اﻳﻦ ﻣﻮرد ﺑﻪ ﻋﻨﻮان ﺣﺴﺎﺳﻴﺖ ﺑﻪ ﻧﻮع ﺣﺮوف ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮد .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻛﺪ زﻳﺮ را در ﺑﺮﻧﺎﻣﻪ ﺧﻮد اﺟﺮا ﻛﻨﻴﺪ ،ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﻧﺨﻮاﻫﺪ ﺷﺪ: ;"string strName = "winston )"if (strName == "WINSTON ;)"!MessageBox.Show("Aha! you are Winston ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺣﺪس زده ﺑﺎﺷﻴﺪ ،ﻛﻠﻤﻪ WINSTONﻛﻪ ﺑﺎ ﺣﺮوف ﺑﺰرگ اﺳـﺖ ﺑـﺎ ﻣﻘـﺪار ﻣﺘﻐﻴﻴـﺮ strNameﻛـﻪ ﺑـﺎ ﺣﺮوف ﻛﻮﭼﻚ اﺳﺖ ﺗﻔﺎوت دارد و ﺷﺮط اﺟﺮا ﻧﺨﻮاﻫﺪ ﺷﺪ .اﻣﺎ در ﺑﻴﺸﺘﺮ ﻣﻮاﻗﻊ ﺷﻤﺎ ﻧﻤﻲ ﺧﻮاﻫﻴﺪ رﺷﺘﻪ ﻫﺎ را ﺑﻪ اﻳﻦ ﺻﻮرت ﺑﺮرﺳﻲ ﻛﻨﻴـﺪ، ﭘﺲ ﺑﺎﻳﺪ راﻫﻲ را ﭘﻴﺪا ﻛﻨﻴﺪ ﻛﻪ آﻧﻬﺎ را ﺑﻪ ﺣﺎﻟﺖ ﻋﺎدي و ﺑﺪون در ﻧﻈﺮ ﮔﺮﻓﺘﻦ ﻧﻮع ﺣﺮوف ﻣﻘﺎﻳﺴﻪ ﻛﻨﻴﺪ .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ،روﺷﻲ را ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد:
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻣﻘﺎﻳﺴﻪ رﺷﺘﻪ ﻫﺎ ﺑﺪون در ﻧﻈﺮ ﮔﺮﻓﺘﻦ ﻧﻮع ﺣﺮوف (1ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم را ﺑﺮاي Form1ﺑﺎز ﻛﻨﻴﺪ و ﻛﻨﺘﺮل Buttonدﻳﮕﺮي را ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴـﺪ .ﺧﺎﺻـﻴﺖ Name دﻛﻤﻪ ﻓﺮﻣﺎن را ﺑﺮاﺑﺮ btnStringCompareو ﺧﺎﺻـﻴﺖ Textآن را ﺑﺮاﺑـﺮ Compare String ﻗﺮار دﻫﻴﺪ. (2روي ﻛﻨﺘﺮل Buttonدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن وارد ﻛﻨﻴﺪ: private void btnStringCompare_Click(object sender, )EventArgs e
١٢٦
{ // Declare variable ;string strName // Get the name ;strName = txtName2.Text // Compare the name )if (String.Compare(strName, "STEPHANIE", True) == 0 MessageBox.Show("Hello, Stephanie!", ;)""And Or Demo } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ اي ﻛﻪ ﺟﺪﻳﺪا اﺿﺎﻓﻪ ﻛﺮدﻳﺪ ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻧﺘﻴﺠﻪ اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 9-4را ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛﺮد.
ﺷﻜﻞ 9-4 (4روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ و در TextBoxﻋﺒﺎرﺗﻲ را ﻣﺎﻧﻨﺪ STePHaniEﻳﺎ ﻫـﺮ ﺗﺮﻛﻴـﺐ دﻳﮕـﺮي از آن وارد ﻛﻨﻴﺪ .ﺳﭙﺲ روي دﻛﻤﻪ String Compareﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻴﻜﻨﻴﺪ ﻛﻪ ﻛﺎدر ﭘﻴﻐـﺎم ﻗـﺴﻤﺖ ﻗﺒـﻞ ﻣﺠـﺪدا ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻛﺪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﺑﻌﺪ از اﻳﻨﻜﻪ اﺳﻢ ﻧﻮﺷﺘﻪ ﺷﺪه در TextBoxرا در ﻣﺘﻐﻴﻴـﺮ ﻗـﺮار دادﻳـﻢ ،ﺑـﻪ ﺟـﺎي اﺳـﺘﻔﺎده از ﻋﻤﻠﮕﺮ == ﺑﺮاي ﻣﻘﺎﻳﺴﻪ آﻧﻬﺎ ،از ﺗﺎﺑﻊ Compareدر System.Stringاﺳﺘﻔﺎده ﻣﻴﻜﻨﻴﻢ .اﻳﻦ ﺗﺎﺑﻊ ﺳﻪ ﭘﺎراﻣﺘﺮ را ﺑﻪ ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ .ﭘﺎراﻣﺘﺮ اول و دوم رﺷﺘﻪ ﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﺎﻳﺪ ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﻣﻘﺎﻳﺴﻪ ﺷﻮﻧﺪ .در اﻳﻦ ﻣﺜﺎل ﺑـﺮاي ﭘـﺎراﻣﺘﺮ اول ﻣﻘـﺪار درون ﻣﺘﻐﻴﻴﺮ strNameو ﺑﺮاي ﭘﺎراﻣﺘﺮ دوم ﺛﺎﺑﺖ رﺷﺘﻪ اي " "STEPHANIEرا ﻓﺮﺳﺘﺎده اﻳﻢ .ﭘﺎراﻣﺘﺮ ﺳﻮم ﻫـﻢ ﺑـﺮاي ﺗـﺎﺑﻊ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ در ﻫﻨﮕﺎم ﻣﻘﺎﻳﺴﻪ ،ﻧﻮع ﺣﺮوف را ﻧﺎدﻳﺪه ﺑﮕﻴﺮد ﻳﺎ ﻧﻪ .در اﻳﻨﺠﺎ ﻣﻘﺪار trueﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛـﻪ ﺑﺰرﮔـﻲ و ﻳـﺎ
١٢٧
ﻛﻮﭼﻜﻲ ﺣﺮوف ﺑﻪ وﺳﻴﻠﻪ ﺗﺎﺑﻊ ﻧﺎدﻳﺪه ﮔﺮﻓﺘﻪ ﺷﻮﻧﺪ .اﮔﺮ ﻣﻘﺪار اﻳﻦ ﭘﺎراﻣﺘﺮ را ﺑﺮاﺑﺮ ﺑﺎ falseﻗﺮار دﻫﻴﺪ ،ﻋﻤﻠﻜﺮد اﻳﻦ ﺗﺎﺑﻊ دﻗﻴﻘﺎ ﻣـﺸﺎﺑﻪ اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ == ﺧﻮاﻫﺪ ﺑﻮد. // Compare the name )if (String.Compare(strName, "STEPHANIE", True) == 0 MessageBox.Show("Hello, Stephanie!", ;)""And Or Demo
ﻧﺘﻴﺠﻪ اي ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ ﺗﺎﺑﻊ ﺑﺮﮔﺮداﻧﺪه ﻣﻲ ﺷﻮد ﻣﻘﺪاري ﻋﺠﻴﺐ اﺳﺖ .اﻳﻦ ﺗﺎﺑﻊ ﺑﻪ ﺟﺎي ﻣﻘﺪار trueو ﻳﺎ ،falseﻳﻚ ﻋـﺪد ﺻﺤﻴﺢ را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .در ﺣﻘﻴﻘﺖ اﻳﻦ ﺗﺎﺑﻊ ﻋﻼوه ﺑﺮ ﻣﺸﺨﺺ ﻛﺮدن ﺑﺮاﺑﺮي و ﻳﺎ ﻧﺎﺑﺮاﺑﺮي دو رﺷﺘﻪ ،ﻣﻲ ﺗﻮاﻧﺪ ﻣﺸﺨﺺ ﻛﻨﺪ ﻛﻪ در ﺻﻮرت ﻧﺎﺑﺮاﺑﺮي آﻧﻬﺎ ﻛﺪاﻣﻴﻚ ﺑﺰرﮔﺘﺮ ﻣﻲ ﺑﺎﺷﻨﺪ .اﮔﺮ ﻣﻘﺪار ﺻﻔﺮ ﺗﻮﺳﻂ ﺗﺎﺑﻊ ﺑﺮﮔﺮداﻧﺪه ﺷﺪ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ دو رﺷﺘﻪ ﺑـﺎ ﻫﻢ ﺑﺮاﺑﺮﻧﺪ ،اﮔﺮ ﻋﺪد ﻣﻨﻔﻲ ﺑﺮﮔﺮداﻧﺪه ﺷﻮد ﻳﻌﻨﻲ رﺷﺘﻪ اول ﻛﻮﭼﻜﺘﺮ از رﺷﺘﻪ دوم اﺳﺖ و ﻋﺪد ﻣﺜﺒﺖ ﻧﻴﺰ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ رﺷـﺘﻪ اول ﺑﺰرﮔﺘﺮ از رﺷﺘﻪ دوم اﺳﺖ .از اﻳﻦ اﻋﺪاد ﻣﻴﺘﻮان ﺑﺮاي ﻧﻮﺷﺘﻦ اﻟﮕﻮرﻳﺘﻢ ﻫﺎي ﻣﺮﺗﺐ ﺳﺎزي و ﻳﺎ ﺟﺴﺘﺠﻮ اﺳﺘﻔﺎده ﻛﺮد.
اﻧﺘﺨﺎب ﺑﻴﻦ ﺣﺎﻟﺘﻬﺎ ﺑﺎ اﺳﺘﻔﺎده از :switch در ﺑﻌﻀﻲ از ﻣﻮاﻗﻊ ﺑﺎﻳﺪ ﺷﺮط ﻫﺎﻳﻲ را ﻣﺸﺎﺑﻪ زﻳﺮ ﺑﺮرﺳﻲ ﻛﻨﻴﺪ:
آﻳﺎ ﻧﺎم ﻣﺸﺘﺮي ﺑﺮاﺑﺮ ﺑﺎ Bryanاﺳﺖ؟ در اﻳﻦ ﺻﻮرت ﻋﻤﻞ Aرا اﻧﺠﺎم ﺑﺪه. آﻳﺎ ﻧﺎم ﻣﺸﺘﺮي ﺑﺮاﺑﺮ ﺑﺎ Stephanieاﺳﺖ؟ در اﻳﻦ ﺻﻮرت ﻋﻤﻞ Bرا اﻧﺠﺎم ﺑﺪه. آﻳﺎ ﻧﺎم ﻣﺸﺘﺮي ﺑﺮاﺑﺮ ﺑﺎ Cathyاﺳﺖ؟ در اﻳﻦ ﺻﻮرت ﻋﻤﻞ Cرا اﻧﺠﺎم ﺑﺪه. آﻳﺎ ﻧﺎم ﻣﺸﺘﺮي ﺑﺮاﺑﺮ ﺑﺎ Bettyاﺳﺖ؟ در اﻳﻦ ﺻﻮرت ﻋﻤﻞ Dرا اﻧﺠﺎم ﺑﺪه. آﻳﺎ ﻧﺎم ﻣﺸﺘﺮي ﺑﺮاﺑﺮ ﺑﺎ Edwardاﺳﺖ؟ در اﻳﻦ ﺻﻮرت ﻋﻤﻞ Eرا اﻧﺠﺎم ﺑﺪه.
اﮔﺮ ﺑﺨﻮاﻫﻴﺪ اﻳﻦ ﻛﺎر را ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر ifاﻧﺠﺎم دﻫﻴﺪ ،ﺑﺎﻳﺪ از ﻛﺪي ﻣﺸﺎﺑﻪ زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ: )"if (Customer.Name == "Bryan // Do A )"else if(Customer.Name == "Stephanie // Do B )"else if(Customer.Name == "Cathy // Do C )"else if(Customer.Name == "Betty // Do D )"else if(Customer.Name == "Edward // Do E در اﻳﻦ ﺣﺎات اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﺑﻌﺪ از ﻣﺪﺗﻲ ﻛﺪ را ﺑﻪ ﺻﻮرﺗﻲ ﺗﻐﻴﺮ دﻫﻴﺪ ﻛﻪ ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از ﻧﺎم ﻣﺸﺘﺮي از ﻧﺎم ﻛﻮﭼﻚ او اﺳﺘﻔﺎده ﻛﻨﺪ ،ﭼﻪ ﻛــــﺎري ﺑﺎﻳــــﺪ ﺑﻜﻨﻴــــﺪ؟ در اﻳــــﻦ ﺣﺎﻟــــﺖ ﺑﺎﻳــــﺪ ﻋﺒــــﺎرت Customer.Nameرا در ﺗﻤــــﺎم دﺳــــﺘﻮرات ifﺑــــﻪ
١٢٨
Customer.FirstNameﺗﻐﻴﺮ دﻫﻴﺪ ﻛﻪ ﻛﺎر ﺑﺴﻴﺎر وﻗﺖ ﮔﻴﺮي اﺳﺖ .ﻫﻤﭽﻨﻴﻦ اﺳﺘﻔﺎده از اﻳﻦ روش ﺧﻮاﻧﺎﻳﻲ ﺑﺮﻧﺎﻣﻪ را ﻧﻴﺰ ﻛﻢ ﻣﻲ ﻛﻨﺪ .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﺑﺎ روﺷﻲ آﺷﻨﺎ ﻣﻴﺸﻮﻳﻢ ﻛﻪ ﺑﺘﻮاﻧﻴﻢ ﺑﻬﺘﺮ اﻳﻦ ﺷﺮط ﻫﺎ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از دﺳﺘﻮر switch (1ﻳﻚ ﭘﺮوژه وﻳﻨﺪوزي ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم Switch Demoاﻳﺠﺎد ﻛﻨﻴﺪ .ﺳﭙﺲ ﺧﺎﺻـﻴﺖ Nameﻣﺮﺑـﻮط ﺑـﻪ ﻓـﺮم را ﺑﺮاﺑـﺮ Switchﻗﺮار دﻫﻴﺪ. (2ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ListBoxﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ،lstDataﺧﺎﺻـﻴﺖ Dockرا ﺑﻪ Fillو ﺧﺎﺻﻴﺖ IntegralHeightرا ﺑﻪ Falseﺗﻐﻴﻴﺮ دﻫﻴﺪ. (3ﻫﻨﮕﺎﻣﻲ ﻛـﻪ ﻛﻨﺘـﺮل ListBoxدر ﻓـﺮم اﻧﺘﺨـﺎب ﺷـﺪه اﺳـﺖ ،ﺑـﻪ ﭘﻨﺠـﺮه Propertiesﺑﺮوﻳـﺪ و ﺧﺎﺻـﻴﺖ String Itemsرا اﻧﺘﺨــﺎب ﻛﻨﻴــﺪ و ﺑــﺮ روي دﻛﻤــﻪ ﺳــﻤﺖ راﺳــﺖ آن ﻛﻠﻴــﻚ ﻛﻨﻴــﺪ .ﭘﻨﺠــﺮه اي ﺑــﻪ ﻧــﺎم Collection Editorﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ .ﻣﻄﺎﺑﻖ ﺷﻜﻞ ،10-4ﭘﻨﺞ ﻧﺎم ﻣﺨﺘﻠﻒ را در آن وارد ﻛﻨﻴﺪ.
ﺷﻜﻞ 10-4 (4ﺑﺮ روي ﻛﻠﻴﺪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻧﺎﻣﻬﺎ ﺑﻪ ListBoxاﺿﺎﻓﻪ ﺷﻮﻧﺪ .ﺳﭙﺲ ﺑﺮ روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑـﻮط ﺑﻪ روﻳﺪاد SelectedIndexChangedاﻳﺠﺎد ﺷﻮد .ﻛﺪ زﻳﺮ را در آن وارد ﻛﻨﻴﺪ: private void lstData_SelectedIndexChanged(object sender, )EventArgs e { // Declare variables ;string strName ;"" = string strFavoriteColor // Get the selected name = strName ;)(lstData.Items[lstData.SelectedIndex].ToString // Use a Switch to get the favorite color // of the selected name ١٢٩
switch(strName) { case "Bryan": strFavoriteColor = "Madras Yellow"; break; case "Stephanie": strFavoriteColor = "Sea Blue"; break; case "Cathy": strFavoriteColor = "Morning Mist"; break; case "Betty": strFavoriteColor = "Passionate Purple"; break; case "Edward": strFavoriteColor = "Battleship Gray"; break; } // Display the favorite color of the selected name MessageBox.Show(strName + "‘s favorite color is " + strFavoriteColor, "Select Demo"); } ﻧﻤـﺎﻳﺶ داده11-4 ﻛـﺎدر ﭘﻴﻐـﺎﻣﻲ ﻣـﺸﺎﺑﻪ ﺷـﻜﻞ، ﻛﻠﻴﻚ ﻛﻨﻴﺪListBox ﻫﺮ ﺑﺎر ﻛﻪ روي ﻧﺎﻣﻲ در.( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ5 .ﺧﻮاﻫﺪ ﺷﺪ
11-4 ﺷﻜﻞ
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻣﺘﻐﻴﻴﺮ ﻫﺎي ﻣﻮرد ﻧﻴـﺎز را ﺗﻌﺮﻳـﻒSelectedIndexChanged اوﻟﻴﻦ ﻛﺎري ﻛﻪ در روﻳﺪاد ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ آﻳﺘﻤـﻲ ﻛـﻪ ﺷـﻤﺎره آن ﺑﺮاﺑـﺮ ﺑـﺎ. اﻧﺘﺨﺎب ﺷﺪه اﺳﺖListBox ﺳﭙﺲ ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻛﻪ ﻛﺪام ﻧﺎم در.ﻛﻨﻴﺪ
١٣٠
ﺧﺎﺻﻴﺖ SelectedIndexاﺳﺖ را ﭘﻴﺪا ﻛﻨﻴﺪ و ﻣﺘﻦ داﺧﻞ آن آﻳﺘﻢ را در ﻣﺘﻐﻴﻴﺮ ﻗﺮار دﻫﻴﺪ .اﻳﻦ ﻛﺎر ﺑﻪ وﺳﻴﻠﻪ ﻛﺪ زﻳﺮ ﺻﻮرت ﻣﻲ ﮔﻴﺮد: // Declare variables ;string strName ;"" = string strFavoriteColor // Get the selected name = strName ;)(lstData.Items[lstData.SelectedIndex].ToString در اﻳــﻦ ﻗــﺴﻤﺖ از ﻛــﺪ ﺑــﻪ ﭼﻨــﺪ ﻧﻜﺘــﻪ ﺗﻮﺟــﻪ ﻛﻨﻴــﺪ .اول اﻳﻨﻜــﻪ ﻫﻤــﺎﻧﻄﻮر ﻛــﻪ ﻣــﺸﺎﻫﺪه ﻣــﻲ ﻛﻨﻴــﺪ ،ﻫﻨﮕــﺎم ﺗﻌﺮﻳــﻒ ﻣﺘﻐﻴﻴــﺮ strFavoriteColorﺑﻪ آن ﻣﻘﺪار اوﻟﻴﻪ داده اﻳﻢ .اﮔﺮ اﻳﻦ ﻣﻘﺪار اوﻟﻴﻪ را از ﻛﺪ ﺣﺬف ﻛﻨﻴﺪ ،ﺑﺮﻧﺎﻣﻪ ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ ﺑﺎ ﺧﻄـﺎ ﻣﻮاﺟﻪ ﻣﻲ ﺷﻮد. در C#ﻫﺮ ﻣﺘﻐﻴﻴﺮي ﻗﺒﻞ از اﺳﺘﻔﺎده ﺑﺎﻳﺪ داراي ﻣﻘﺪار اوﻟﻴﻪ ﺑﺎﺷﺪ و رﻋﺎﻳﺖ اﻳﻦ ﻣﻮرد در ﻛﺪ ،ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ ﺗﻮﺳﻂ ﻛﺎﻣﭙﺎﻳﻠﺮ ﺑﺮرﺳـﻲ ﻣـﻲ ﺷﻮد .ﻣﻘﺪار دﻫﻲ اوﻟﻴﻪ ﺑﻪ ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﺣﺘﻤﺎ ﺑﺎﻳﺪ ﻗﺒﻞ از اﺳﺘﻔﺎده از آﻧﻬﺎ و ﻫﻤﭽﻨﻴﻦ در ﺧﺎرج از ﺑﺨﺸﻬﺎﻳﻲ از ﻛﺪ ﻛﻪ ﻓﻘﻂ در ﺷـﺮاﻳﻂ ﺧـﺎص اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ )ﻫﻤﺎﻧﻨﺪ ﺑﻼك دﺳﺘﻮر ،(ifاﻧﺠﺎم ﺷﻮد. در اﻳﻦ ﻗﺴﻤﺖ ﻗﺒﻞ از اﺳﺘﻔﺎده از اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﺑﻪ آن ﻣﻘﺪار اوﻟﻴﻪ داده اﻳﻢ ،وﻟﻲ اﻳﻦ ﻛﺎر را در ﺑﻼك دﺳﺘﻮرات switchﻗﺮار داده اﻳـﻢ. ﻓﺮض ﻛﻨﻴﺪ ﻛﻪ ﻫﻴﭻ ﻳﻚ از ﺣﺎﻟﺘﻬﺎي دﺳﺘﻮر switchاﺟﺮا ﻧﺸﻮﻧﺪ .در اﻳـﻦ ﺣﺎﻟـﺖ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻛﺎﻣﭙـﺎﻳﻠﺮ ﺑـﻪ ﺧـﻂ ﺑﻌـﺪ از دﺳـﺘﻮر switchﺑﺮﺳﺪ و ﺑﺨﻮاﻫﺪ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ strFavoriteColotرا ﭼﺎپ ﻛﻨـﺪ ،اﻳـﻦ ﻣﺘﻐﻴﻴـﺮ ﻣﻘـﺪاري ﻧﺨﻮاﻫـﺪ داﺷـﺖ. ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟﻪ ﺧﻮاﻫﺪ ﺷﺪ .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ در ﻫﻨﮕﺎم ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴﺮ ﺑﻪ آن ﻣﻘﺪار اوﻟﻴﻪ داده اﻳﻢ ﺗﺎ در اﻳﻦ ﻣﻮارد ﻫـﻢ ﻣﺘﻐﻴﻴـﺮ داراي ﻣﻘﺪار ﺑﺎﺷﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻧﺎم اﻧﺘﺨﺎب ﺷﺪه در ﻟﻴﺴﺖ را ﺑﺪﺳﺖ آوردﻳﺪ ،ﻣﻴﺘﻮاﻧﻴﺪ ﺣﺎﻟﺘﻬﺎي ﻣﺨﺘﻠﻒ آن را ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر switchﺑﺮرﺳﻲ ﻛﻨﻴﺪ. ﺑﺮاي اﺳﺘﻔﺎده از اﻳﻦ دﺳﺘﻮر ،ﻧﺎم ﻣﺘﻐﻴﻴﺮي ﻛﻪ ﻣﻴﺨﻮاﻫﻴﺪ ﺑﺮرﺳﻲ ﻛﻨﻴﺪ را ﺑﺎﻳﺪ در داﺧﻞ ﭘﺮاﻧﺘﺰ ﻣﻘﺎﺑﻞ دﺳﺘﻮر وارد ﻛﻨﻴﺪ. درون ﺑﻼك دﺳﺘﻮر switchﺑﺎﻳﺪ ﺑﺮاي ﻫﺮ ﺣﺎﻟﺖ ﻛﻪ ﻣﻴﺨﻮاﻫﻴﺪ ﺑﺮرﺳﻲ ﻛﻨﻴﺪ ﻳﻚ دﺳﺘﻮر caseﻣﺠﺰا ﻗﺮار دﻫﻴﺪ .در اﻳـﻦ ﻣﺜـﺎل، ﭘﻨﭻ دﺳﺘﻮر caseدارﻳﺪ ﻛﻪ ﻫﺮ ﻛﺪام ﺑﻪ ﻳﻚ ﻧﺎم ﻣﺮﺑﻮط ﻫﺴﺘﻨﺪ .ﻫﻨﮕﺎم اﺟﺮاي اﻳﻦ ﻛﺪ ،اﮔﺮ وﻳﮋوال C#ﺑﻪ ﻳﻜﻲ از اﻳﻦ ﺣﺎﻟﺘﻬﺎ ﺑﺮﺧﻮرد ﻛﻨﺪ ،ﻛﺪ آن را اﺟﺮا ﻣﻲ ﻛﻨﺪ. در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﺑﺮاي اﻳﻨﻜﻪ ﺑﻌﺪ از اﺟﺮاي ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﺑﻼك ،اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺧﻂ ﺑﻌﺪ از دﺳـﺘﻮر switchﻣﻨﺘﻘـﻞ ﺷـﻮد، ﺑﺎﻳﺪ در اﻧﺘﻬﺎي دﺳﺘﻮرات آن ﺑﻼك از دﺳﺘﻮر breakﺑﻪ ﻧﺤﻮي ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻧﺸﺎن داده ﺷﺪه اﺳﺖ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. favorite color
;"= "Madras Yellow
;"= "Sea Blue
;"= "Morning Mist
// Use a Switch to get the // of the selected name )switch(strName { case "Bryan": strFavoriteColor ;break case "Stephanie": strFavoriteColor ;break case "Cathy": strFavoriteColor
١٣١
;break case "Betty": ;"strFavoriteColor = "Passionate Purple ;break case "Edward": ;"strFavoriteColor = "Battleship Gray ;break } // Display the favorite color of the selected name MessageBox.Show(strName + "‘s favorite color is " + ;)"strFavoriteColor, "Select Demo در زﻳﺮ ﻣﺮاﺣﻠﻲ ﻛﻪ ﺑﺎ اﻧﺘﺨﺎب ﻳﻚ ﻧﺎم از ﻟﻴﺴﺖ ﺑﺎﻛﺲ ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ ﻃﻲ ﻣﻲ ﺷﻮﻧﺪ ،را ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ:
ﻓﺮض ﻛﻨﻴﺪ ﻛﺎرﺑﺮ در ﻟﻴﺴﺖ روي ﻧـﺎم Bettyﻛﻠﻴـﻚ ﻣـﻲ ﻛﻨـﺪ .روﻳـﺪاد SelectedIndexChanged ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد و ﻣﻘﺪار " "Bettyدر ﻣﺘﻐﻴﻴﺮ strNameذﺧﻴﺮه ﻣﻲ ﺷﻮد. ﺑﺮﻧﺎﻣﻪ ﺑﻪ دﺳﺘﻮر switchﻣﻲ رﺳﺪ و ﻣﻘﺪار درون ﻣﺘﻐﻴﻴـﺮ strNameرا ﺑـﺎ ﺗـﻚ ﺗـﻚ ﻣﻘـﺎدﻳﺮي ﻛـﻪ ﺑـﻪ ﻋﻨـﻮان ﺣﺎﻟﺘﻬﺎي ﻣﺨﺘﻠﻒ اﻳﻦ دﺳﺘﻮر وارد ﺷﺪه اﻧﺪ ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﺪ. ﺑﻌﺪ از ﺑﺮرﺳﻲ ﺣﺎﻟﺘﻬﺎي وارد ﺷﺪه در دﺳﺘﻮر ،switchﺑﺮﻧﺎﻣﻪ ﻣﺘﻮﺟﻪ ﻣﻲ ﺷﻮد ﻛﻪ ﺣﺎﻟﺖ ﭼﻬـﺎرم ﺑـﺎ ﻣﻘـﺪار ﻣﺘﻐﻴﻴـﺮ ﺑﺮاﺑـﺮ اﺳــﺖ .ﺑﻨــﺎﺑﺮاﻳﻦ دﺳــﺘﻮرات اﻳــﻦ ﺣﺎﻟــﺖ را اﺟــﺮا ﻣــﻲ ﻛﻨــﺪ )ﻳﻌﻨــﻲ ﻣﻘــﺪار strFavoriteColorرا ﺑﺮاﺑــﺮ " "Passionate Purpleﻗﺮار ﻣﻲ دﻫﺪ(. ﺑﺮﻧﺎﻣﻪ از ﺑﻼك دﺳﺘﻮرات switchﺧﺎرج ﺷﺪه و اوﻟﻴﻦ ﺧﻂ ﺑﻌﺪ از آن را اﺟﺮا ﻣﻲ ﻛﻨﺪ و ﻛﺎدر ﭘﻴﻐﺎم ﻣﻨﺎﺳﺒﻲ را ﺑـﻪ ﻛـﺎرﺑﺮ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
اﺳﺘﻔﺎده از switchﺑﺎ و ﺑﺪون ﺣﺴﺎﺳﻴﺖ ﺑﻪ ﻧﻮع ﺣﺮوف: ﻫﻤﺎﻧﻨﺪ دﺳﺘﻮر ،ifدﺳﺘﻮر switchﻫﻢ ﺑﻪ ﺑﺰرﮔﻲ و ﻛﻮﭼﻜﻲ ﺣﺮوف ﺣﺴﺎس اﺳﺖ .ﺑﻪ ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ﺗﻮﺟﻪ ﻛﻨﻴﺪ:
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از switchﺑﺎ ﺣﺴﺎﺳﻴﺖ ﺑﻪ ﻧﻮع ﺣﺮوف (1ﻗﺴﻤﺖ ﻃﺮاﺣـﻲ ﻓـﺮم ﻣﺮﺑـﻮط ﺑـﻪ Form1را ﺑـﺎز ﻛـﺮده و ﻛﻨﺘـﺮل ListBoxرا در ﻓـﺮم اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ .از ﭘﻨﺠـﺮه Propertiesﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل ،ListBoxﮔﺰﻳﻨﻪ Itemsرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ و ﺳﭙﺲ روي دﻛﻤﻪ ﺟﻠﻮي اﻳﻦ ﺧﺎﺻﻴﺖ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﭘﻨﺠﺮه String Collection Editorﺑﺎز ﺷﻮد. (2اﺳﺎﻣﻲ ﻣﻮﺟﻮد در اﻳﻦ ﭘﻨﺠﺮه را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 12-4ﻫﻤﻪ ﺑﺎ ﺣﺮوف ﺑﺰرگ ﻧﻮﺷﺘﻪ ﺷﻮﻧﺪ.
١٣٢
ﺷﻜﻞ 12-4 (3روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺗﻐﻴﺮات اﻳﻦ ﭘﻨﺠﺮه ذﺧﻴﺮه ﺷﻮﻧﺪ و ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛـﺮد ﻛـﻪ ﺑـﺎ ﻛﻠﻴﻚ ﺑﺮ روي ﻫﺮ ﻳﻚ از ﻧﺎﻣﻬﺎي داﺧﻞ ،ListBoxﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻛﻪ ﻇﺎﻫﺮ ﻣﻲ ﺷﻮد ﻧﺎم رﻧﮓ ﻣﻮرد ﻧﻈﺮ را ﻧﻤﺎﻳﺶ ﻧﻤـﻲ دﻫﺪ) .ﺷﻜﻞ (13-4
ﺷﻜﻞ 13-4
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ دﺳﺘﻮر switchﻫﻢ ﻫﻤﺎﻧﻨﺪ دﺳﺘﻮر ifﻧﺴﺒﺖ ﺑﻪ ﻧﻮع ﺣﺮوف ﺣﺴﺎس اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ در ﺷﺮط دﺳﺘﻮر switchاز ﻧﺎﻣﻬـﺎي BETTYو ﻳﺎ CATHYاﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﻫﻴﭻ ﺣﺎﻟﺖ ﻣﻨﺎﺳﺒﻲ ﻳﺎﻓﺘﻪ ﻧﺨﻮاﻫﺪ ﺷﺪ .اﻳﻦ ﻣﻮرد ﻣﺎﻧﻨﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﻪ ﺻﻮرت زﻳﺮ از دﺳـﺘﻮر ifاﺳﺘﻔﺎده ﻛﻨﻴﺪ: )"if ("BETTY" == "Betty ﻳﺎ: )"if ("CATHY" == "Cathy
١٣٣
String.Compare در ﺑﺨﺸﻬﺎي ﻗﺒﻠﻲ دﻳﺪﻳﺪ ﻛﻪ ﺑﺮاي ﻣﻘﺎﻳﺴﻪ دو رﺷﺘﻪ ﺑﺪون در ﻧﻈﺮ ﮔﺮﻓﺘﻦ ﻧﻮع ﺣﺮوف ﻣﻲ ﺗـﻮان از ﺗـﺎﺑﻊ روﺷﻲ را ﺧﻮاﻫﻴﻢ دﻳﺪ ﻛﻪ ﺑﻪ، در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ. ﻧﻤﻲ ﺗﻮاﻧﻴﺪ از اﻳﻦ روش اﺳﺘﻔﺎده ﻛﻨﻴﺪswitch اﻣﺎ در دﺳﺘﻮر.اﺳﺘﻔﺎده ﻛﺮد . را ﻫﻢ ﺑﺪون ﺣﺴﺎﺳﻴﺖ ﺑﻪ ﻧﻮع ﺣﺮوف اﻧﺠﺎم دﻫﻴﺪswitch وﺳﻴﻠﻪ آن ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﻘﺎﻳﺴﻪ ﻫﺎي دﺳﺘﻮر
ﺑﺪون ﺣﺴﺎﺳﻴﺖ ﺑﻪ ﻧﻮع ﺣﺮوفswitch اﺳﺘﻔﺎده از:اﻣﺘﺤﺎن ﻛﻨﻴﺪ SelectedIndexChanged ﺑﺎز ﻛﻨﻴﺪ و در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑـﻪ روﻳـﺪادForm1 ( ﺑﺨﺶ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ را ﺑﺮاي1 ﻗﺮار ﻣﻴﺪﻫﻴﺪ ﺣﺘﻤـﺎcase دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﺣﺘﻤﺎ رﺷﺘﻪ ﻫﺎﻳﻲ را ﻛﻪ ﺑﺮاي ﺑﺮرﺳﻲ در ﺟﻠﻮي دﺳﺘﻮر.ﺗﻐﻴﺮات زﻳﺮ را اﻧﺠﺎم دﻫﻴﺪ .ﺑﺎ ﺣﺮوف ﻛﻮﭼﻚ ﻧﻮﺷﺘﻪ ﺷﻮﻧﺪ private void lstData_SelectedIndexChanged(object sender, EventArgs e) { // Declare variables string strName; string strFavoriteColor = ""; // Get the selected name strName = lstData.Items[lstData.SelectedIndex].ToString(); // Use a Switch to get the favorite color // of the selected name switch(strName.ToLower()) { case "bryan": strFavoriteColor = "Madras Yellow"; break ; case "stephanie": strFavoriteColor = "Sea Blue"; break; case "cathy": strFavoriteColor = "Morning Mist"; break; case "betty": strFavoriteColor = "Passionate Purple"; break; case "edward": strFavoriteColor = "Battleship Gray"; break; } // Display the favorite color of the selected name MessageBox.Show(strName + "‘s favorite color is " + strFavoriteColor, "Select Demo"); ١٣٤
} (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﻣﺠﺪدا ﺑﺮ روي ﻳﻜﻲ از اﺳﺎﻣﻲ درون ListBoxﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 14-4ﻛﺎدر ﭘﻴﻐـﺎﻣﻲ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻧﺎم ﻓﺮد اﻧﺘﺨﺎب ﺷﺪه و رﻧﮓ ﻣﻮرد ﻧﻈﺮ او را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
ﺷﻜﻞ 14-4
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺮاي اﻳﻦ ﻛﻪ رﺷﺘﻪ ي داﺧﻞ ﻣﺘﻐﻴﻴﺮ strNameﺑﺪون ﺣﺴﺎﺳﻴﺖ ﺑـﻪ ﻧـﻮع ﺣـﺮوف ﺑﺮرﺳـﻲ ﺷـﻮﻧﺪ ،ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﺎ اﺳـﺘﻔﺎده از ﺗـﺎﺑﻊ ToLowerﺗﻤﺎم ﺣﺮوف آن را ﺑﻪ ﺣﺮوف ﻛﻮﭼﻚ ﺗﺒﺪﻳﻞ ﻛﻨﻴﺪ و ﺳﭙﺲ آن را ﺑﺎ ﻣﻘﺎدﻳﺮ ﻣﺨﺘﻠﻒ ﻣﻘﺎﻳﺴﻪ ﻛﻨﻴﺪ. ))(switch(strName.ToLower اﻳﻦ دﺳﺘﻮر ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ strNameرا اﺑﺘﺪا ﺑﻪ ﺣﺮوف ﻛﻮﭼﻚ ﺗﺒﺪﻳﻞ ﻣﻲ ﻛﻨﺪ و ﺳﭙﺲ آن را ﺑﺎ ﻣﻘﺎدﻳﺮ ﻣﻮﺟـﻮد در دﺳـﺘﻮر case ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﺪ .در اﺳﺘﻔﺎده از اﻳﻦ روش ﺑﺎﻳﺪ دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﺗﻤﺎم ﻋﺒﺎرﺗﻬﺎي ﻣﻘﺎﺑﻞ دﺳﺘﻮر caseرا ﺑﺎ ﺣﺮوف ﻛﻮﭼﻚ ﺑﻨﻮﻳﺴﻴﺪ .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ،ﺣﺎﻟﺖ ﻣﻮرد ﻧﻈﺮ اﺟﺮا ﻧﺨﻮاﻫﺪ ﺷﺪ .ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ ﻋﺒﺎرت ﺟﻠﻮي دﺳﺘﻮر caseﺑﺮاﺑـﺮ ﺑـﺎ " "Bettyﺑﺎﺷـﺪ و ﻛﺎرﺑﺮ ﻧﻴﺰ ﻧﺎم BETTYرا از ﻟﻴﺴﺖ ﺑﺎﻛﺲ اﻧﺘﺨﺎب ﻣﻲ ﻛﻨﺪ .در اﻳﻦ ﺣﺎﻟﺖ ،اﻳﻦ ﻧﺎم ﺑﺎ اﺳـﺘﻔﺎده از ﺗـﺎﺑﻊ ToLowerﺑـﻪ betty ﺗﺒﺪﻳﻞ ﻣﻴﺸﻮد و ﺳﭙﺲ ﻣﻘﺪار " "Bettyﺑﺎ " "bettyﻣﻘﺎﻳﺴﻪ ﻣﻲ ﺷﻮد ﻛﻪ ﺑﻪ ﻋﻠﺖ ﺑﺮاﺑﺮ ﻧﺒﻮدن اﻳﻦ دو ﻣﻘﺪار ،ﻛﺪ ﻣﺮﺑـﻮط ﺑـﻪ اﻳﻦ ﺑﺨﺶ اﺟﺮا ﻧﺨﻮاﻫﺪ ﺷﺪ.
;"= "Madras Yellow
;"= "Sea Blue
;"= "Morning Mist
;"= "Passionate Purple
case "bryan": strFavoriteColor ; break case "stephanie": strFavoriteColor ;break case "cathy": strFavoriteColor ;break case "betty": strFavoriteColor ١٣٥
;break case "edward": ;"strFavoriteColor = "Battleship Gray ;break } در اﻧﺘﻬﺎ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻧﺎم رﻧﮓ ﻣﻮرد ﻧﻈﺮ را ﺑﺪﺳﺖ آوردﻳﺪ ،آن را ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﺪ. ﻧﻜﺘﻪ :ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از ﺣﺮوف ﻛﻮﭼﻚ ،ﻣﻴﺘﻮاﻧﻴﺪ ﺗﻤﺎم ﻋﺒﺎرﺗﻬﺎي ﻣﻘﺎﺑﻞ دﺳﺘﻮرات caseرا ﺑﺎ ﺣـﺮوف ﺑـﺰرگ ﺑﻨﻮﻳـﺴﻴﺪ و ﺳـﭙﺲ ﺑـﺎ اﺳﺘﻔﺎده از ﺗﺎﺑﻊ ،ToUpperرﺷﺘﻪ ﻣﻮرد ﻧﻈﺮ ﺧﻮدﺗﺎن را ﺑﻪ ﺣﺮوف ﺑﺰرگ ﺗﺒﺪﻳﻞ ﻛﻨﻴﺪ.
اﻧﺘﺨﺎﺑﻬﺎي ﭼﻨﺪ ﮔﺎﻧﻪ: در ﺑﺮرﺳﻲ ﺣﺎﻟﺘﻬﺎي ﻣﺨﺘﻠﻒ در ﺷﺮط ﻣﻘﺎﺑﻞ دﺳﺘﻮر caseاﺟﺒﺎري ﻧﻴﺴﺖ ﻛﻪ ﻓﻘﻂ ﻳﻚ ﺣﺎﻟﺖ را ﺑﺮرﺳﻲ ﻛﻨﻴﺪ ،ﺑﻠﻜﻪ ﻣﻴﺘﻮاﻧﻴﺪ ﭼﻨﺪ ﺣﺎﻟﺖ را در ﻣﻘﺎﺑﻞ ﻳﻚ caseﺑﺮرﺳﻲ ﻛﻨﻴﺪ ،ﺗﺎ در ﺻﻮرﺗﻲ ﻛﻪ ﻫﺮ ﻛﺪام از آﻧﻬﺎ رخ داد ،ﻛﺪ ﻣﻮرد ﻧﻈﺮ اﺟﺮا ﺷﻮد .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳـﺮ، ﺑﺮﻧﺎﻣﻪ ﺑﺎﻻ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻴﻢ ﻛﻪ ﺑﺎ اﻧﺘﺨﺎب ﻧﺎم از ،ListBoxﺟﻨﺴﻴﺖ ﻓﺮد اﻧﺘﺨﺎب ﺷﺪه را ﻧﻤﺎﻳﺶ دﻫﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻧﺘﺨﺎﺑﻬﺎي ﭼﻨﺪ ﮔﺎﻧﻪ (1ﻣﺤــﻴﻂ وﻳﺮاﻳــﺸﮕﺮ ﻛــﺪ را ﺑــﺮاي Form1ﺑــﺎز ﻛﻨﻴــﺪ و ﺗﻐﻴــﺮات ﻣــﺸﺨﺺ ﺷــﺪه در زﻳــﺮ را در ﻣﺘــﺪ ﻣﺮﺑــﻮط ﺑــﻪ روﻳــﺪاد SelectedIndexChangedاﻋﻤﺎل ﻛﻨﻴﺪ: private void lstData_SelectedIndexChanged(object sender, )EventArgs e { // Declare variables ;string strName // Get the selected name = strName ;)(lstData.Items[lstData.SelectedIndex].ToString // Use a Switch to display a person's gender ))(switch (strName.ToLower { case "bryan": case "edward": ;)"MessageBox.Show("Male", "Switch Demo ;break case "stephanie":
١٣٦
case "cathy": case "betty": ;)"MessageBox.Show("Female", "Switch Demo ;break } } (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي ﻳﻜﻲ از اﺳﺎﻣﻲ داﺧﻞ ListBoxﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و ﺟﻨﺴﻴﺖ ﻓﺮد اﻧﺘﺨﺎب ﺷﺪه را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ ) ﺷﻜﻞ .(15-4
ﺷﻜﻞ 15-4
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ درﻳﺎﻓﺖ ﻧﺎم و ﻣﻘﺪار دﻫﻲ اوﻟﻴﻪ ﺑﻪ ﻣﺘﻐﻴﻴﺮ ﺑﺮاي اﺳﺘﻔﺎده در ،switchﻫﻤﺎﻧﻨﺪ ﻗﺒﻞ اﺳﺖ و ﺗﻔﺎوﺗﻲ ﻧﺪارد .اﮔـﺮ ﺑﺨـﻮاﻫﻴﻢ ﺑﺮاي ﭼﻨﺪ ﺷﺮط ﻣﺨﺘﻠﻒ ﻳﻚ ﻛﺪ اﺟﺮا ﺷﻮد ،ﺑﺎﻳﺪ ﺑﺮاي ﻫﺮ ﺷﺮط ﻳﻚ ﺑﺎر دﺳﺘﻮر caseرا ﺑﻨﻮﻳﺴﻴﻢ ،ﺑﺎ اﻳﻦ ﺗﻔﺎوت ﻛﻪ ﻓﻘﻂ ﺑـﺮاي ﻣـﻮرد آﺧﺮ ،ﻛﺪ و دﺳﺘﻮر breakرا ﻣﻲ ﻧﻮﻳﺴﻴﻢ .در ﺑﻘﻴﻪ دﺳﺘﻮرات ،caseﻓﻘﻂ ﺷﺮط ﻣﻮرد ﻧﻈﺮ را وارد ﻣﻲ ﻛﻨﻴﻢ .اﻳﻦ ﻣﻮرد ﻣﻮﺟـﺐ ﻣـﻲ ﺷﻮد ﻛﻪ اﻳﻦ ﺷﺮط ﻫﺎ ﻫﻤﺎﻧﻨﺪ اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ Orدر دﺳﺘﻮر ifﺑﺎ ﻳﻜﺪﻳﮕﺮ ﺗﺮﻛﻴﺐ ﺷﻮﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﺮ ﻛﺪام از آﻧﻬﺎ ﻛﻪ درﺳﺖ ﺑﺎﺷـﺪ، ﻛﺪي ﻛﻪ ﺑﻌﺪ از آﺧﺮﻳﻦ دﺳﺘﻮر caseآﻣﺪه اﺳﺖ اﺟﺮا ﻣﻲ ﺷﻮد .ﺑﺮاي ﻣﺜﺎل در ﻣـﻮرد اول ،اﮔـﺮ اﺳـﻢ اﻧﺘﺨـﺎب ﺷـﺪه bryanو ﻳـﺎ edwardﺑﺎﺷﺪ ،ﻛﺪﻫﺎي ﺑﻌﺪ از دو دﺳﺘﻮر caseاﺟﺮا ﻣﻲ ﺷﻮﻧﺪ. case "bryan": case "edward": ;"strFavoriteColor = "Madras Yellow ; break دﻗﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﺑﺎ اﻳﻦ روش ،در ﺣﻘﻴﻘﺖ در ﺣﺎل ﺗﺮﻛﻴﺐ اﻳﻦ ﺷﺮﻃﻬﺎ ﺑﺎ ﻋﻤﻠﮕﺮ "ﻳﺎ" ﻫﺴﺘﻴﺪ و ﻣﻲ ﮔﻮﻳﻴﺪ "ﻳﺎ اﻳﻦ ﻣﻮرد ﻳﺎ آن ﻣﻮرد" ﻧﻪ اﻳﻨﻜﻪ "اﻳﻦ ﻣﻮرد و آن ﻣﻮرد".
١٣٧
دﺳﺘﻮر :default ﺗﺎﻛﻨﻮن ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﺷﺮﻃﻬﺎي ﻣﺨﺘﻠﻒ را در دﺳﺘﻮر switchﺑﺮرﺳﻲ ﻛﻨﻴﻢ .اﻣﺎ ﺳﻮال اﻳﻦ اﺳﺖ ﻛﻪ اﮔـﺮ ﻫـﻴﭻ ﻳـﻚ از اﻳﻦ ﺷﺮط ﻫﺎ اﺟﺮا ﻧﺸﺪﻧﺪ ﭼﻪ ﻣﻲ ﺷﻮد؟ اﻳﻦ ﻣﻮرد ﻛﻪ ﻫﻴﭻ ﻳﻚ از ﺷﺮط ﻫﺎ اﺟﺮا ﻧﺸﻮﻧﺪ را در ﺑﺨﺶ ﻗﺒﻠﻲ ،ﻫﻨﮕﺎﻣﻲ ﻛـﻪ در ﺣـﺎل ﺑﺮرﺳـﻲ ﻣﻘﺎﻳﺴﻪ ﺑﺎ ﺣﺴﺎﺳﻴﺖ ﺑﻪ ﻧﻮع ﺣﺮوف ﺑﻮدﻳﻢ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ .اﻣﺎ ﭼﮕﻮﻧﻪ ﻣﻲ ﺷﻮد ﻛﺪي را ﺑﻪ ﻧﺤﻮي ﻣﺸﺨﺺ ﻛﺮد ﻛﻪ ﻫﺮ ﮔﺎه ﻫـﻴﭻ ﻳـﻚ از ﺷﺮط ﻫﺎ ﺑﺮﻗﺮار ﻧﺒﻮدﻧﺪ اﺟﺮا ﺷﻮد؟ در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،اﻳﻦ ﻣﻮرد را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از دﺳﺘﻮر default (1ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم را ﺑﺮاي Form1ﺑﺎز ﻛﻨﻴﺪ و ﻛﻨﺘﺮل ListBoxرا از روي ﻓﺮم اﻧﺘﺨﺎب ﻛﻨﻴـﺪ .ﺳـﭙﺲ ﺑـﻪ ﭘﻨﺠـﺮه Propertiesﺑﺮوﻳــﺪ و ﺑــﺎ اﺳــﺘﻔﺎده از ﺧﺎﺻــﻴﺖ ،Itemsﭘﻨﺠــﺮه String Collection Editorرا ﻣﺠﺪدا ﺑﺎز ﻛﻨﻴﺪ .ﻧﺎم دﻳﮕﺮي ﺑﻪ ﻟﻴﺴﺖ اﺿﺎﻓﻪ ﻛﻨﻴﺪ و روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ. (2در ﻣﺘﺪ lstData_SelectedIndexChangedﺑﺨﺶ ﻣﺮﺑﻮط ﺑﻪ دﺳﺘﻮر switchرا ﺑـﻪ ﺻـﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ: ))(switch(strName.ToLower { case "bryan": case "edward": ;)"MessageBox.Show("Male", "Switch Demo ;break case "stephanie": case "cathy": case "betty": ;)"MessageBox.Show("Female", "Switch Demo ;break default: MessageBox.Show("I don’t know this person’s ;)"+ "gender.", "Select Demo ;break }
"
(3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و از ListBoxﻧﺎﻣﻲ ﻛﻪ ﺟﺪﻳﺪاً ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻟﻴﺴﺖ اﺿﺎﻓﻪ ﺷﺪه اﺳﺖ را اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﻧﺘﻴﺠﻪ اي ﻣـﺸﺎﺑﻪ ﺷﻜﻞ 16-4ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
١٣٨
ﺷﻜﻞ 16-4
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ دﺳﺘﻮراﺗﻲ ﻛﻪ ﺑﻌﺪ از ﺑﺨﺶ defaultوارد ﻣﻲ ﺷﻮﻧﺪ ،ﻫﻨﮕﺎﻣﻲ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﻫﻴﭻ ﻳﻚ از ﺷﺮاﻳﻄﻲ ﻛﻪ در ﺑﺨﺶ caseﻗﻴـﺪ ﺷﺪه اﺳﺖ ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ ﻧﺒﺎﺷﺪ .ﺑﺮاي ﻣﺜﺎل در ﺑﺮﻧﺎﻣﻪ ﺑﺎﻻ ﻫﻴﭻ دﺳﺘﻮر caseﺑﺮاي ﻋﺒﺎرت " "Sydneyوارد ﻧـﺸﺪه اﺳـﺖ، ﺑﻨﺎﺑﺮاﻳﻦ دﺳﺘﻮرات ﺑﺨﺶ defaultاﺟﺮا ﻣﻲ ﺷﻮﻧﺪ و ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﻛﻪ ﻣﻲ ﮔﻮﻳﻴﺪ ﺟﻨﺴﻴﺖ ﻓﺮد اﻧﺘﺨـﺎب ﺷـﺪه ﻣﺸﺨﺺ ﻧﻴﺴﺖ. ﻧﻜﺘﻪ :دﻗﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻫﻤﻮاره در اﻧﺘﻬﺎي دﺳﺘﻮرات ﺑﺨﺶ caseو ﻳـﺎ ﺑﺨـﺶ defaultاز دﺳـﺘﻮر breakاﺳـﺘﻔﺎده ﻛﻨﻴﺪ ﺗﺎ ﺑﻌﺪ از اﺟﺮاي ﻛﺪ ﻛﻨﺘﺮل ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺧﻂ ﺑﻌﺪ از دﺳﺘﻮر switchﺑﺮﮔﺮدد .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﺑﺎ ﺧﻄﺎي زﻣـﺎن ﻛﺎﻣﭙﺎﻳـﻞ ﻣﻮاﺟـﻪ ﺧﻮاﻫﻴﺪ ﺷﺪ.
اﺳﺘﻔﺎده از ﻧﻮع ﻫﺎي داده اي ﮔﻮﻧﺎﮔﻮن در دﺳﺘﻮر :switch در اﻳﻦ درس ،ﻓﻘﻂ از ﻣﺘﻐﻴﻴﺮ ﻫﺎي رﺷﺘﻪ اي در دﺳﺘﻮر switchاﺳﺘﻔﺎده ﻛﺮدﻳﺪ .اﻣﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ دﺳﺘﻮر را ﺑـﺎ اﻧـﻮاع ﻣﺘﻐﻴﻴـﺮ ﻫـﺎي ﻣﻮﺟﻮد در C#ﻫﻤﺎﻧﻨﺪ اﻋﺪاد ﺻﺤﻴﺢ ) ،(intاﻋـﺪاد اﻋـﺸﺎري ) doubleو (floatو ﻳـﺎ ﻣﺘﻐﻴﻴـﺮ ﻫـﺎي Booleanﻫـﻢ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﻫﺮ ﻧﻮع ﻣﺘﻐﻴﻴﺮي ﻛﻪ ﺑﺘﻮاﻧﺪ در دﺳﺘﻮر ifﺑﺎ اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ == ﺑﺮرﺳﻲ ﺷﻮد ،ﻣﻴﺘﻮاﻧﺪ در دﺳﺘﻮر switchﻧﻴـﺰ ﺑـﻪ ﻛـﺎر رود .اﻣـﺎ ﻣﻌﻤﻮﻻ از ﻣﺘﻐﻴﻴﺮ ﻫﺎﻳﻲ ﻛﻪ داراي ﻣﻘﺎدﻳﺮ ﭘﻴﻮﺳﺘﻪ ﻫﺴﺘﻨﺪ ﻣﺎﻧﻨﺪ ﻣﺘﻐﻴﻴﺮ ﻫـﺎي رﺷـﺘﻪ اي و ﻳـﺎ اﻋـﺪاد ﺻـﺤﻴﺢ ﺑـﺮاي دﺳـﺘﻮر switch اﺳﺘﻔﺎده ﻣﻴﻜﻨﻨﺪ .زﻳﺮا اﻋﺪاد اﻋﺸﺎري ﻣﻲ ﺗﻮاﻧﻨﺪ ﻣﻘﺪارﻫﺎي ﻛﺴﺮي ﻣﺎﻧﻨﺪ 2,221 ،2,21 ،2,2و … را داﺷﺘﻪ ﺑﺎﺷﺪ و اﺳﺘﻔﺎده از آﻧﻬﺎ در دﺳﺘﻮر switchﻣﻨﻄﻘﻲ ﻧﻴﺴﺖ.
ﺣﻠﻘﻪ ﻫﺎ:
١٣٩
ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺣﺎل ﻧﻮﺷﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻛﺎﻣﭙﻴﻮﺗﺮي ﻫﺴﺘﻴﺪ ،ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ ﻳﻚ ﻋﻤﻞ ﻣﺸﺨﺺ را ﭼﻨﺪﻳﻦ ﺑﺎر ﻣﺘﻮاﻟﻲ اﻧﺠﺎم دﻫﻴﺪ ﺗﺎ ﻧﺘﻴﺠﻪ ﻣﻄﻠﻮب ﺧﻮد را درﻳﺎﻓﺖ ﻛﻨﻴﺪ .ﻣﺜﻼ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ ﺻﻮرت ﺣﺴﺎب ﺗﻠﻔﻦ را ﺑﺮاي ﺗﻤﺎم ﻣﺸﺘﺮﻛﻴﻦ ﺑﺪﺳﺖ آورﻳﺪ و ﻳﺎ 10ﻓﺎﻳـﻞ را از روي ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﺨﻮاﻧﻴﺪ. در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ،ﺑﺮاي اﻧﺠﺎم اﻳﻦ اﻣﻮر ﻣﻌﻤﻮﻻ از ﺣﻠﻘﻪ ﻫﺎ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد .در اﻳﻦ ﺑﺨﺶ ﺑﺎ ﺳﻪ دﺳـﺘﻪ ﻛﻠـﻲ از ﺣﻠﻘـﻪ ﻫـﺎ ﻛـﻪ در C# وﺟﻮد دارﻧﺪ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ.
ﺣﻠﻘﻪ ﻫﺎي – forاﻳﻦ ﺣﻠﻘﻪ ﻫﺎ ﻣﻌﻤﻮﻻ ﺑﻪ ﺗﻌﺪاد ﻣﺮﺗﺒﻪ ﻣﺸﺨﺼﻲ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ )ﺑﺮاي ﻣﺜﺎل ،دﻗﻴﻘﺎ 10ﺑﺎر(. ﺣﻠﻘﻪ ﻫﺎي – whileاﻳﻦ ﺣﻠﻘﻪ ﻫﺎ ﻣﻌﻤﻮﻻ ﺗﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻧﺘﻴﺠﻪ ﻳﻚ ﺷﺮط درﺳﺖ ﺷﻮد اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﻨﺪ. ﺣﻠﻘﻪ ﻫﺎي – doﻋﻤﻠﻜﺮد اﻳﻦ ﺣﻠﻘﻪ ﻫﺎ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﺣﻠﻘﻪ ﻫﺎي whileاﺳﺖ ،ﺑﺎ اﻳﻦ ﺗﻔـﺎوت ﻛـﻪ ﺷـﺮط در ﺣﻠﻘـﻪ ﻫـﺎي whileدر اﺑﺘﺪا ﺑﺮرﺳﻲ ﻣﻲ ﺷﻮد وﻟﻲ در اﻳﻦ ﺣﻠﻘﻪ ﻫﺎ ،ﺷﺮط در اﻧﺘﻬﺎ ﺑﺮرﺳﻲ ﻣﻴﺸﻮد.
ﺣﻠﻘﻪ :for ﺣﻠﻘﻪ forﺣﻠﻘﻪ اي اﺳﺖ ﻛﻪ درك ﻧﺤﻮه ﻛﺎرﻛﺮد آن ﺑﺴﻴﺎر راﺣﺖ اﺳﺖ .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺎ اﻳﻦ دﺳﺘﻮر آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻳﻚ ﺣﻠﻘﻪ for (1 (2 (3 (4
ﻳﻚ ﭘﺮوژه وﻳﻨﺪوزي ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم Loopsاﻳﺠﺎد ﻛﻨﻴﺪ. در ﻓﺮﻣﻲ ﻛﻪ ﻇﺎﻫﺮ ﻣﻲ ﺷﻮد ﻳﻚ ListBoxو ﻳﻚ ﻛﻨﺘﺮل Buttonاﺿﺎﻓﻪ ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ Nameﻣﺮﺑﻮط ﺑﻪ ListBoxرا ﺑﺮاﺑﺮ lstDataو ﺧﺎﺻﻴﺖ IntegralHeightآن را ﺑﺮاﺑﺮ falseﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Nameﻣﺮﺑﻮط ﺑﻪ دﻛﻤـﻪ ﻓﺮﻣـﺎن Buttonرا ﺑﺮاﺑـﺮ btnForLoopو ﺧﺎﺻـﻴﺖ Textآن را ﺑﺮاﺑـﺮ For Loopﻗﺮار دﻫﻴﺪ .ﺗﺎﻛﻨﻮن ﻓﺮم ﺷﻤﺎ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 17-4ﺷﺪه ﺑﺎﺷﺪ.
١٤٠
ﺷﻜﻞ 17-4 (5ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن اﻳﺠﺎد ﺷـﻮد .ﺳـﭙﺲ ﻛـﺪ زﻳـﺮ را در آن وارد ﻛﻨﻴﺪ: )private void btnForLoop_Click(object sender, EventArgs e { // Declare variable ;int intCount // Perform a loop )for(intCount = 1;intCount <= 5;intCount += 1 { // Add the item to the list lstData.Items.Add("I’m item " + intCount + ;)"!" in the list } } (6ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﺮ روي دﻛﻤﻪ for Loopﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻧﺘﻴﺠﻪ اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 18-4ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﺑﺘﺪاي ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ ،ﻣﺘﻐﻴﻴﺮي را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ: // Declare variable ;int intCount
١٤١
ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﺣﻠﻘﻪ ﺑﺎﻳﺪ از ﻛﻠﻤﻪ ﻛﻠﻴﺪي forاﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻳﻦ ﻛﻠﻤﻪ ﺑﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ وﻳﮋوال C#ﻣﻴﮕﻮﻳﺪ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻳﻚ ﺣﻠﻘﻪ ﺑﺎ ﺗﻌﺪاد دﻓﻌﺎت ﺗﻜﺮار ﻣﺸﺨﺺ اﻳﺠﺎد ﻛﻨﻴﺪ .ﺗﻤﺎم ﻛﻠﻤﺎت و ﻋﻼﻣﺘﻬﺎﻳﻲ ﻛﻪ ﺑﻌﺪ از اﻳﻦ ﻛﻠﻤﻪ ﻣﻲ آﻳﻨﺪ ،ﺑﺮاي ﻣﺸﺨﺺ ﻛـﺮدن ﻧﺤـﻮه ﻋﻤﻠﻜـﺮد اﻳﻦ ﺣﻠﻘﻪ ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ .ﺑﺮاي ﺗﻌﻴﻴﻦ ﻧﺤﻮه ﻛﺎرﻛﺮد ﻳﻚ ﺣﻠﻘﻪ ،ﺳﻪ ﻣﻮرد را ﺑﺎﻳﺪ در ﺟﻠﻮي آن ﻣﺸﺨﺺ ﻛﻨﻴﺪ .اﻳﻦ ﺳـﻪ ﻣـﻮرد ،ﻫﻤـﺎﻧﻄﻮر ﻛﻪ در ﻛﺪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﺑﺎ ﻛﺎراﻛﺘﺮ ";" از ﻳﻜﺪﻳﮕﺮ ﺟﺪا ﻣﻲ ﺷﻮﻧﺪ.
ﺷﻜﻞ 18-4 در ﻗﺴﻤﺖ اول ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻛﻪ از ﭼﻪ ﻣﺘﻐﻴﻴﺮي ﻣﻴﺨﻮاﻫﻴﺪ ﺑﺮاي ﺷﻤﺎرش دﻓﻌﺎت ﺗﻜﺮار در اﻳﻦ ﺣﻠﻘﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﺑﺨﺶ ﻣﻘﺪار اوﻟﻴﻪ ﻣﺘﻐﻴﻴﺮ را ﻧﻴﺰ ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻛﻪ ﻣﻴﺨﻮاﻫﻴﺪ ﺷـﻤﺎرش در ﺣﻠﻘـﻪ از ﭼـﻪ ﻋﺪدي ﺷﺮوع ﺷﻮد .در اﻳﻦ ﻣﺜﺎل ﺑﺮاي ﺷﻤﺎرش ﺣﻠﻘﻪ از ﻣﺘﻐﻴﻴﺮ intCountﻛﻪ در ﺧﻂ ﻗﺒﻞ ﺗﻌﺮﻳﻒ ﻛﺮدﻳﻢ ،اﺳـﺘﻔﺎده ﻣـﻲ ﻛﻨـﻴﻢ و ﻣﻘﺪار اوﻟﻴﻪ آن را ﻧﻴﺰ 1ﺗﻌﻴﻴﻦ ﻣﻴﻜﻨﻴﻢ ﺗﺎ ﺷﻤﺎرش ﺣﻠﻘﻪ از ﻋﺪد ﻳﻚ ﺷﺮوع ﺷﻮد. در ﻗﺴﻤﺖ دوم ﺑﺎﻳﺪ ﺗﻌﻴﻴﻦ ﻛﻨﻴﻢ ﻛﻪ ﺣﻠﻘﻪ ،ﺷﻤﺎرش را ﺗﺎ ﭼﻪ ﻋﺪدي اداﻣﻪ دﻫﺪ .در اﻳـﻦ ﻣﺜـﺎل ﺗـﺎ زﻣـﺎﻧﻲ ﻛـﻪ ﻣﺘﻐﻴﻴـﺮ intCount ﻛﻮﭼﻜﺘﺮ و ﻳﺎ ﻣﺴﺎوي 5اﺳﺖ ﺷﻤﺎرش اداﻣﻪ ﭘﻴﺪا ﻣﻴﻜﻨﺪ .ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﺑﺮاي ﺷﺮط اﻳﻦ ﻗﺴﻤﺖ از ﻫﺮ ﻳﻚ از ﻋﻤﻠﮕﺮﻫﺎﻳﻲ ﻛـﻪ در ﺑﺨﺶ ﻗﺒﻞ ﻣﻌﺮﻓﻲ ﻛﺮدﻳﻢ ﻫﻤﺎﻧﻨﺪ ﻋﻤﻠﮕﺮ ﺑﺰرﮔﺘﺮ ﻣﺴﺎوي و ﻳﺎ ﻋﻤﻠﮕﺮ ﻛﻮﭼﻜﺘﺮ و ...ﻣﻴﺘﻮاﻧﻴﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. در ﻗﺴﻤﺖ آﺧﺮ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻛﻪ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ در ﻫﺮ ﻣﺮﺣﻠﻪ ﺑﺎﻳﺪ ﭼﻪ ﺗﻐﻴﻴﺮي ﻛﻨﺪ .در اﻳﻦ ﻣﺜﺎل ﻣﻴﺨﻮاﻫﻴﻢ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ را در ﻫﺮ ﻣﺮﺣﻠـﻪ از اﺟﺮاي ﺣﻠﻘﻪ ﻳﻚ واﺣﺪ اﻓﺰاﻳﺶ ﻳﺎﺑﺪ .ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻦ ﻗﺴﻤﺖ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ را ﺑﺎ ﻋﺪد ﻳﻚ ﺟﻤﻊ ﻣﻲ ﻛﻨﻴﻢ. از ﺗﻮﺿﻴﺤﺎت ﻗﺒﻠﻲ ﻣﺸﺨﺺ اﺳﺖ ﻛﻪ اﻳﻦ ﺣﻠﻘﻪ از ﻋﺪد ﻳﻚ ﺷﺮوع ﺑﻪ ﺷﻤﺎرش ﻣﻲ ﻛﻨﺪ و ﺗﺎ ﻋﺪد 5ﺷﻤﺎرش را اداﻣﻪ ﻣﻲ دﻫـﺪ و در ﻫـﺮ ﻣﺮﺣﻠﻪ ﻧﻴﺰ ﻳﻚ واﺣﺪ ﺑﻪ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ دﺳﺘﻮرات داﺧﻞ ﺣﻠﻘﻪ ﭘﻨﺞ ﺑﺎر اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ. ﻣﺮاﺣﻠﻲ ﻛﻪ ﺑﺮاي اﺟﺮاي اﻳﻦ ﺣﻠﻘﻪ ﺑﻪ وﺳﻴﻠﻪ وﻳﮋوال C#ﺑﺮرﺳﻲ ﻣﻲ ﺷﻮد ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﺳﺖ ﻛﻪ اﺑﺘﺪا ﻣﺘﻐﻴﻴﺮ intCountﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺪار ﻣﺸﺨﺺ ﺷﺪه در ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺷﻮد .ﺳﭙﺲ ﺷﺮط وارد ﺷﺪه در ﻗﺴﻤﺖ دوم ﺣﻠﻘﻪ ﺑﺮرﺳﻲ ﻣﻴﺸﻮد .در ﺻﻮرﺗﻲ ﻛـﻪ اﻳـﻦ ﺷـﺮط ﺑﺮﻗـﺮار ﻧﺒﺎﺷﺪ دﺳﺘﻮرات ﺣﻠﻘﻪ اﺟﺮا ﻧﻤﻲ ﺷﻮﻧﺪ و ﺑﺮﻧﺎﻣﻪ از ﺧﻂ ﺑﻌﺪ از ﺣﻠﻘﻪ اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ .در ﺻﻮرﺗﻲ ﻛﻪ ﺷﺮط ﺣﻠﻘﻪ ﺑﺮﻗـﺮار ﺑﺎﺷـﺪ )ﻳﻌﻨـﻲ در اﻳﻦ ﻣﺜﺎل ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ intCountﻛﻮﭼﻜﺘﺮ ﻳﺎ ﻣﺴﺎوي ﻋﺪد 5ﺑﺎﺷﺪ( دﺳﺘﻮرات داﺧﻞ ﺣﻠﻘﻪ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ .ﺑﻌﺪ از اﻳﻨﻜـﻪ دﺳـﺘﻮرات ﺣﻠﻘﻪ ﺑﺮاي ﻣﺮﺗﺒﻪ اول اﺟﺮا ﺷﺪﻧﺪ ،وﻳﮋوال C#ﺗﻐﻴﻴﺮاﺗﻲ را ﻛﻪ در ﻗﺴﻤﺖ ﺳﻮم ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﺑﺮ روي ﻣﺘﻐﻴﻴﺮ اﻋﻤﺎل ﻣﻲ ﻛﻨﺪ )ﺑـﺮاي ﻣﺜﺎل در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ،ﻳﻚ واﺣﺪ ﺑﻪ ﻣﺘﻐﻴﻴﺮ intCountاﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ( و ﺳﭙﺲ ﺷـﺮط وارد ﺷـﺪه در ﻗـﺴﻤﺖ دوم ﺣﻠﻘـﻪ forرا
١٤٢
ﻣﺠﺪدا ﺑﺮرﺳﻲ ﻣﻴﻜﻨﺪ و در ﺻﻮرت درﺳﺖ ﺑﻮدن اﻳﻦ ﺷﺮط دﺳﺘﻮرات داﺧﻞ ﺣﻠﻘﻪ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ .اﻳﻦ ﺷﺮاﻳﻂ اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﻨﺪ ﺗﺎ زﻣـﺎﻧﻲ ﻛﻪ ﺷﺮط ﻗﺴﻤﺖ دوم ﺣﻠﻘﻪ forﻧﺎدرﺳﺖ ﺑﺎﺷﺪ .در اﻳﻦ ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻠﺮ وﻳﮋوال C#از ﺣﻠﻘﻪ ﺧﺎرج ﻣﻲ ﺷﻮد و ﺑـﻪ اوﻟـﻴﻦ ﺧـﻂ ﺑﻌـﺪ از ﺣﻠﻘﻪ ﻣﻲ رود. // Perform a loop )for(intCount = 1;intCount <= 5;intCount += 1 { // Add the item to the list lstData1.Items.Add("I’m item " + intCount + ;)"!" in the list } ﻧﻜﺘﻪ :در ﻗﺴﻤﺖ ﺳﻮم ﺣﻠﻘﻪ ي ﺑﺎﻻ ،ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از ﻋﺒﺎرت intCount+=1ﻣﻲ ﺗﻮاﻧﺴﺘﻴﻢ از دﺳﺘﻮر intCount++ ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻳﻦ دﺳﺘﻮر ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﻳﻚ واﺣﺪ ﺑﻪ ﻣﺘﻐﻴﻴﺮ intCountاﺿـﺎﻓﻪ ﺷـﻮد و ﺣﺎﺻـﻞ در ﻫﻤـﺎن ﻣﺘﻐﻴﻴـﺮ ﻗـﺮار ﺑﮕﻴﺮد. )for(intCount = 1;intCount <= 5;intCount++ ﻋﻼوه ﺑﺮ ﻋﻤﻠﮕﺮ ++ﻛﻪ ﻳﻚ واﺣﺪ ﺑﻪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ اﺿﺎﻓﻪ ﻣﻴﻜﻨﺪ ،ﻋﻤﻠﮕﺮ --ﻧﻴﺰ وﺟﻮد دارد ﻛﻪ ﻳﻚ واﺣـﺪ از ﻣﻘـﺪار ﻳـﻚ ﻣﺘﻐﻴﻴـﺮ ﻣـﻲ ﻛﺎﻫﺪ.ﻛﺎرﺑﺮد اﻳﻦ ﻋﻤﻠﮕﺮ ﻫﻤﺎﻧﻨﺪ ﻋﻤﻠﮕﺮ ++اﺳﺖ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﺗﺎﻛﻨﻮن ﻣﺘﻮﺟﻪ ﺷﺪه اﻳﺪ ،در ﺣﻠﻘﻪ forاﺟﺒﺎري ﻧﻴﺴﺖ ﻛﻪ ﻣﻘﺪار ﺷﺮوع ﺣﻠﻘﻪ را ﻋﺪد ﻳﻚ در ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ و ﻳﺎ ﺷـﻤﺎرﻧﺪه در ﻫﺮ ﻣﺮﺣﻠﻪ ﻣﺘﻐﻴﻴﺮ را ﻓﻘﻂ ﻳﻚ واﺣﺪ اﻓﺰاﻳﺶ دﻫﺪ .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ﺣﻠﻘﻪ forﺟﺪﻳﺪي ﺧﻮاﻫﻴﻢ ﺳﺎﺧﺖ ﻛـﻪ از اﻳـﻦ ﻣـﻮارد اﺳـﺘﻔﺎده ﻛﻨﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻧﻌﻄﺎف ﭘﺬﻳﺮي ﺣﻠﻘﻪ for (1اﮔﺮ ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ ﻫﻤﭽﻨﺎن در ﺣﺎل اﺟﺮا اﺳﺖ آن را ﺑﺒﻨﺪﻳﺪ و ﺳـﭙﺲ ﻛﻨﺘـﺮل Buttonدﻳﮕـﺮي روي ﻓـﺮم اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ. ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ btnNewForLoopو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ New For Loopﻗﺮار دﻫﻴﺪ. (2روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن وارد ﻛﻨﻴﺪ. private void btnNewForLoop_Click(object sender, EventArgs )e { // Perform a loop )for (int intCount = 4; intCount < 62; intCount += 7 { // add the item to the list ;)lstData.Items.Add(intCount
١٤٣
} } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ New For Loopﺟﺪﻳﺪ ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻧﺘﻴﺠﻪ اي ﻣـﺸﺎﺑﻪ ﺷـﻜﻞ 19-4را درﻳﺎﻓـﺖ ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 19-4
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﻪ ﺗﻌﺮﻳﻒ ﺣﻠﻘﻪ forدر اﻳﻦ ﻣﺜﺎل ﺗﻮﺟﻪ ﻛﻨﻴﺪ: // Perform a loop )for (int intCount = 4; intCount < 62; intCount += 7 ﻧﻜﺘﻪ اوﻟﻲ ﻛﻪ در اﻳﻦ ﺣﻠﻘﻪ وﺟﻮد دارد ،ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴﺮ intCountدر ﺧﻮد ﺣﻠﻘﻪ اﺳﺖ .اﻳﻦ ﻣﻮرد ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﺑﺮﻧﺎﻣﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﻪ ﺣﻠﻘﻪ رﺳﻴﺪ ﻣﺘﻐﻴﻴﺮي را ﺑﻪ ﻧﺎم intCountﺗﻌﺮﻳﻒ ﻛﻨﺪ و ﺑﺮاي ﺷﻤﺎرش درون ﺣﻠﻘﻪ از آن اﺳﺘﻔﺎده ﻛﻨﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎر ﺣﻠﻘﻪ ﺑﻪ ﭘﺎﻳﺎن رﺳﻴﺪ ،ﻣﺘﻐﻴﻴﺮ ﻧﻴﺰ از ﺑﻴﻦ ﺧﻮاﻫﺪ رﻓﺖ و ﻓﻀﺎي اﺷﻐﺎل ﺷﺪه ﺗﻮﺳﻂ آن آزاد ﻣﻲ ﺷﻮد .در ﻣﺮﺣﻠﻪ ﺑﻌﺪ ،ﺑﻪ ﺟﺎي اﺳـﺘﻔﺎده از ﻋـﺪد 1ﺑـﻪ ﻋﻨﻮان ﻣﻘﺪار ﺷﺮوع ،از ﻋﺪد 4اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ .در ﺣﻘﻴﻘﺖ در اوﻟﻴﻦ دوره اﺟﺮاي ﺣﻠﻘﻪ ﻣﻘﺪار intCountﺑﺮاﺑﺮ ﺑﺎ ﻋـﺪد 4اﺳـﺖ و ﺑﻨﺎﺑﺮاﻳﻦ اوﻟﻴﻦ ﻣﻮرد اﺿﺎﻓﻪ ﺷﺪه ﺑﻪ ﻟﻴﺴﺖ ﻋﺪد 4ﺧﻮاﻫﺪ ﺑﻮد .ﻫﻤﭽﻨﻴﻦ در ﻫﺮ ﻣﺮﺣﻠﻪ از اﺟﺮاي ﺣﻠﻘﻪ 7 ،واﺣﺪ ﺑﻪ ﻣﻘـﺪار intCount اﻓﺰوده ﻣﻲ ﺷﻮد .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ ،دوﻣﻴﻦ ﻣﻮردي ﻛﻪ ﺑﻪ ﻟﻴﺴﺖ اﺿﺎﻓﻪ ﻣﻲ ﺷﻮد ﻋﺪد 11اﺳﺖ ،ﻧﻪ ﻋﺪد .5 ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﺣﻠﻘﻪ ﺑﺎﻳﺪ در ﻋﺪد 62ﺑﻪ ﭘﺎﻳﺎن ﺑﺮﺳﺪ ،اﻣﺎ ﻣﺸﺎﻫﺪه ﻣﻴﻜﻨﻴﺪ ﻛﻪ ﺣﻠﻘﻪ در ﻋﺪد 60ﺑﻪ ﭘﺎﻳﺎن ﻣﻲ رﺳﺪ .زﻳﺮا ﻋﺪد ﺑﻌـﺪ از آن67 ، ﺧﻮاﻫﺪ ﺑﻮد ﻛﻪ از 62ﺑﺰرﮔﺘﺮ اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﺣﻠﻘﻪ ﺑﺮاي ﻣﺮﺗﺒﻪ ﻧﻬﻢ اﺟﺮا ﻧﺨﻮاﻫﺪ ﺷﺪ.
١٤٤
ﺷﻤﺎرش ﻣﻌﻜﻮس در ﺣﻠﻘﻪ: اﮔﺮ در ﻫﺮ ﻣﺮﺣﻠﻪ از اﺟﺮاي ﺣﻠﻘﻪ ﻋﺪدي را از ﺷﻤﺎرﻧﺪه ي آن ﻛﻢ ﻛﻨﻴﺪ ،ﺣﻠﻘﻪ ﺑﻪ ﺻﻮرت ﻣﻌﻜﻮس ﺣﺮﻛﺖ ﺧﻮاﻫﺪ ﻛـﺮد .در اﻣﺘﺤـﺎن ﻛﻨﻴـﺪ ﺑﺨﺶ ﺑﻌﺪ ،اﻳﻦ ﻣﻮرد را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺷﻤﺎرش ﻣﻌﻜﻮس ﺣﻠﻘﻪ (1اﮔﺮ ﻫﻨﻮز ﺑﺮﻧﺎﻣﻪ ﻗﺴﻤﺖ ﻗﺒﻞ در ﺣﺎل اﺟﺮا اﺳﺖ آن را ﺑﺒﻨﺪﻳﺪ و ﺳﭙﺲ ﻛﻨﺘـﺮل Buttonدﻳﮕـﺮي ﺑـﻪ ﻓـﺮم اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ. ﺧﺎﺻـــــﻴﺖ Nameآن را ﺑﺮاﺑـــــﺮ btnBackwardsForLoopو ﺧﺎﺻـــــﻴﺖ Textآن را ﺑﺮاﺑـــــﺮ Backwards For Loopﻗﺮار دﻫﻴﺪ. (2روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن وارد ﻛﻨﻴﺪ: private void btnBackwardsForLoop_Click(object sender, )EventArgs e { // Perform a loop )for (int intCount = 10; intCount >= 1; intCount-- { // Add the item to the list ;)lstData.Items.Add(intCount } } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ Backwards For Loopﻛﻠﻴﻚ ﻛﻨﻴـﺪ .ﻧﺘﻴﺠـﻪ اي را ﻣـﺸﺎﺑﻪ ﺷـﻜﻞ 20-4 ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺖ ﺳﻮم ﺗﻌﺮﻳﻒ ﺣﻠﻘﻪ forﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،در ﻫﺮ ﻣﺮﺗﺒﻪ اﺟﺮاي ﺣﻠﻘﻪ ،اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ --ﻣﻮﺟﺐ ﻣﻲ ﺷـﻮد ﻳﻚ واﺣﺪ از ﻣﻘﺪار intCountﻛﻢ ﺷﻮد .ﭼﻮن ﻣﻘﺪار اوﻟﻴﻪ اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﺑﺮاﺑﺮ 10در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ ،ﺣﻠﻘـﻪ 10ﺑـﺎر اﺟـﺮا ﻣـﻲ ﺷﻮد و از ﻋﺪد 10ﺑﻪ ﺻﻮرت ﻣﻌﻜﻮس ﺑﻪ ﻋﺪد 1ﻣﻲ رﺳﺪ و اﺟﺮاي ﺣﻠﻘﻪ ﺗﻤﺎم ﻣﻲ ﺷﻮد.
١٤٥
ﺷﻜﻞ 20-4
ﺣﻠﻘﻪ ﻫﺎي :foreach در اﺳﺘﻔﺎده روزﻣﺮه از ﺣﻠﻘﻪ forدر ﺑﺮﻧﺎﻣﻪ ﻫﺎ ،ﻛﻤﺘﺮ از اﻳﻦ ﺣﻠﻘﻪ ﺑﻪ ﻧﺤﻮي ﻛـﻪ ﺷـﺮح داده ﺷـﺪ اﺳـﺘﻔﺎده ﻣـﻲ ﺷـﻮد .ﺑـﻪ ﻋﻠـﺖ ﻧﺤـﻮه ﻛﺎرﻛﺮدي ﻛﻪ ﭼﺎرﭼﻮب .NETدارد ،ﻣﻌﻤﻮﻻ در ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﺎ ﻧﻮع ﺧﺎﺻﻲ از اﻳﻦ ﺣﻠﻘﻪ ﻛﻪ foreachﻧﺎﻣﻴﺪه ﻣﻲ ﺷـﻮد ﺑﻴـﺸﺘﺮ ﻛـﺎر ﺧﻮاﻫﻴﻢ ﻛﺮد. در اﻟﮕﻮرﻳﺘﻢ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻋﻤﻮﻣﺎ ﻫﻨﮕﺎﻣﻲ از ﻳﻚ ﺣﻠﻘﻪ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻣﺠﻤﻮﻋﻪ اي از اﺷﻴﺎ را در اﺧﺘﻴﺎر داﺷﺘﻪ ﺑﺎﺷـﻴﺪ و ﺑﺨﻮاﻫﻴـﺪ ﺑـﻴﻦ اﻋﻀﺎي آن ﺟﺎ ﺑﻪ ﺟﺎ ﺷﻮﻳﺪ ،ﻛﻪ اﻳﻦ ﻣﺠﻤﻮﻋﻪ ﻫﻢ اﻏﻠﺐ ﺑﻪ ﺻﻮرت ﻳﻚ آراﻳﻪ اﺳﺖ .ﺑﺮاي ﻣﺜﺎل ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ ﺑﻴﻦ ﺗﻤـﺎم ﻓﺎﻳﻠﻬـﺎي درون ﻳﻚ ﻓﻮﻟﺪر ﺑﮕﺮدﻳﺪ و ﻓﺎﻳﻠﻲ را ﭘﻴﺪا ﻛﻨﻴﺪ ﻛﻪ اﻧﺪازه آن ﺑﻴﺶ از ﺣﺪ ﻣﺠﺎز اﺳﺖ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ از ﭼﺎرﭼﻮب .NETﺑﺨﻮاﻫﻴﺪ ﻛﻪ ﻟﻴﺴﺖ ﺗﻤﺎم ﻓﺎﻳﻠﻬﺎ را ﺑﻪ ﺷﻤﺎ ﺑﺮﮔﺮداﻧﺪ ،ﻳﻚ آراﻳﻪ از اﺷﻴﺎ را درﻳﺎﻓﺖ ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻫﺮ ﻛﺪام از اﻋﻀﺎي آن ﻧﺸﺎن دﻫﻨﺪه ي ﻳﻚ ﻓﺎﻳﻞ اﺳـﺖ .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺣﻠﻘﻪ داﺧﻞ ﺑﺮﻧﺎﻣﻪ ﺧﻮد را ﺑﻪ ﻧﺤﻮي ﺗﻐﻴﻴﺮ ﺧﻮاﻫﻴﺪ داد ﻛﻪ ﻧﺎم ﺗﻤﺎم ﻓﻮﻟﺪرﻫﺎي داﺧﻞ دراﻳﻮ Cﺷﻤﺎ را ﺑﺮﮔﺮداﻧﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺣﻠﻘﻪ foreach (1ﻛﻨﺘﺮل Buttonﺟﺪﻳـﺪي ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ ،ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑـﺮ btnForEachLoopو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ForEach Loopﻗﺮار دﻫﻴﺪ. (2روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن وارد ﻛﻨﻴﺪ: private void btnForEachLoop_Click(object sender, )EventArgs e { // List each folder at the root of your C Drive foreach (string strFolder
١٤٦
))"\\in System.IO.Directory.GetDirectories("C: { // Add the item to the list ;)lstData.Items.Add(strFolder } } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤـﻪ ي ForEach Loopﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .در ListBoxﻧـﺎم ﺗﻤـﺎﻣﻲ ﻓﻮﻟـﺪرﻫﺎي ﻣﻮﺟﻮد در دراﻳﻮ Cﺧﻮد را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺮاي ﺑﺪﺳﺖ آوردن ﻟﻴﺴﺖ ﺗﻤﺎم داﻳﺮﻛﺘﻮري ﻫﺎي ﻣﻮﺟﻮد در ﻳﻚ ﻣـﺴﻴﺮ ﺧـﺎص در ﺑﺮﻧﺎﻣـﻪ ﺑﺎﻳـﺪ از ﺗـﺎﺑﻊ GetFirectories ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس Directoryدر ﻓﻀﺎي ﻧﺎم System.IO 1اﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻳﻦ ﺗـﺎﺑﻊ ﻳـﻚ آراﻳـﻪ رﺷـﺘﻪ اي از ﻧـﺎم ﺗﻤـﺎم داﻳﺮﻛﺘﻮري ﻫﺎي ﻣﻮﺟﻮد در ﻣﺴﻴﺮي ﻛﻪ ﺑﺮاي آن ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ از اﻳﻦ ﺗﺎﺑﻊ ﺑﺮاي درﻳﺎﻓﺖ ﻧﺎم ﺗﻤـﺎﻣﻲ داﻳﺮﻛﺘﻮري ﻫﺎي ﻣﻮﺟﻮد در دراﻳﻮ Cاﺳﺘﻔﺎده ﻛﺮده اﻳﻢ. اﺻﻞ ﻛﺎر ﺣﻠﻘﻪ foreachﺑﻪ اﻳﻦ ﺻﻮرت اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آن ﺷﻤﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ در ﺑﻴﻦ ﺗﻤـﺎﻣﻲ اﺷـﻴﺎي ﻣﻮﺟـﻮد در ﻳـﻚ آراﻳـﻪ ﺧﺎص )ﻛﻪ ﺗﻌﺪاد آن را ﻧﻴﺰ ﻧﻤﻲ داﻧﻴﺪ( ﺣﺮﻛﺖ ﻛﻨﻴﺪ .ﺑﺮاي اﻳﺠﺎد اﻳﻦ ﺣﻠﻘﻪ ﺑﻪ ﻣﻨﺒﻌﻲ از اﺷﻴﺎ ﻧﻴﺎز دارﻳﺪ )در اﻳﻦ ﻣﺜﺎل ﻳﻚ آراﻳﻪ از رﺷﺘﻪ ﻫﺎ( و ﻳــﻚ ﻣﺘﻐﻴﻴــﺮ ﻛﻨﺘــﺮل ﻛﻨﻨــﺪه ﻛــﻪ در ﻫــﺮ ﻣﺮﺣﻠــﻪ ،ﺷــﻴﺊ ﻣــﻮرد ﺑﺮرﺳــﻲ در آن ﻗــﺮار ﺧﻮاﻫــﺪ ﮔﺮﻓــﺖ .در اﻳــﻦ ﻣﺜــﺎل ﺗــﺎﺑﻊ ،GetDirectoriesآراﻳــﻪ اي از اﺷــﻴﺎ را ﺑــﻪ ﻋﻨــﻮان ﻣﻨﺒــﻊ ﺑــﺮاي ﺣﻠﻘــﻪ foreachﻓــﺮاﻫﻢ ﻣــﻲ ﻛﻨــﺪ و ﻣﺘﻐﻴﻴــﺮ strFolderﺑﻪ ﻋﻨﻮان ﻣﺘﻐﻴﻴﺮ ﻛﻨﺘﺮل ﻛﻨﻨﺪه ﺑﻪ ﻛﺎر ﻣﻲ رود: foreach (string strFolder ))"\\in System.IO.Directory.GetDirectories("C: { // Add the item to the list ;)lstData.Items.Add(strFolder } اﻳﻦ ﻋﺒﺎرت ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ در ﻣﺮﺣﻠﻪ اول strFolder ،ﺑﺮاﺑﺮ ﺑﺎ اوﻟﻴﻦ آﻳﺘﻢ در آراﻳﻪ رﺷﺘﻪ اي اﺳﺖ )در اﻳـﻦ ﺟـﺎ ﺑﺮاﺑـﺮ ﺑـﺎ ﻓﻮﻟـﺪر " . ("C:\Documents and Settingsﺷـﻤﺎ ﻣﻴﺘﻮاﻧﻴـﺪ اﻳـﻦ ﻓﻮﻟـﺪر را ﺑـﺎ اﺳـﺘﻔﺎده از دﺳـﺘﻮر زﻳـﺮ ﺑـﻪ ListBoxاﺿﺎﻓﻪ ﻛﻨﻴﺪ. // Add the item to the list ;)lstData.Items.Add(strFolder ﻫﻤﺎﻧﻨﺪ ﺣﻠﻘﻪ ﻫﺎي forﻋﺎدي در ﻫﺮ ﻣﺮﺣﻠﻪ ،ﻳﻜﻲ از ﻋﻨﺎﺻﺮ اﻳﻦ آراﻳﻪ در ﻣﺘﻐﻴﻴﺮ strFolderﻗﺮار ﻣﻴﮕﻴﺮد و ﺳﭙﺲ ﻣﻘـﺪار آن ﺑﻪ ListBoxاﺿﺎﻓﻪ ﻣﻲ ﺷﻮد.
1ﺑﺎ ﻣﻔﻬﻮم ﻓﻀﺎي ﻧﺎم در ﻓﺼﻞ 9آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ.
١٤٧
ﻧﻜﺘﻪ :ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از رﺷﺘﻪ "\ "C:ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﺮاي ﺗﺎﺑﻊ ،GetDirectories از رﺷﺘﻪ "\\ "C:اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ .در زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺧﺎﻧﻮاده Cاز ﺟﻤﻠﻪ ،C#ﻛﺎراﻛﺘﺮ \ ﺑﻪ ﻋﻨﻮان ﻳﻚ ﻛـﺎراﻛﺘﺮ ﻛﻨﺘﺮﻟـﻲ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮد .ﻓﺮض ﻛﻨﻴﺪ ﻣﻴﺨﻮاﻫﻴﺪ رﺷﺘﻪ A " Signرا در ﻳﻚ ﻣﺘﻐﻴﻴﺮ رﺷﺘﻪ اي ذﺧﻴﺮه ﻛﻨﻴﺪ .اﻳﻦ رﺷﺘﻪ ﺷﺎﻣﻞ ﻛﺎراﻛﺘﺮ " اﺳﺖ ﻛﻪ ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن اﻧﺘﻬﺎي رﺷﺘﻪ ﺑﻪ ﻛﺎر ﻣﻲ رود .ﭘﺲ ﻧﻤﻴﺘﻮان ﺑﻪ ﺣﺎﻟﺖ ﻋﺎدي اﻳﻦ رﺷﺘﻪ را در ﻳﻚ ﻣﺘﻐﻴﻴﺮ رﺷﺘﻪ اي ﻗـﺮار داد .ﺑﺮاي اﻳﻨﻜﻪ ﺑﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﺑﮕﻮﻳﻴﻢ ﻛﺎراﻛﺘﺮ " ﺟﺰﺋﻲ از رﺷﺘﻪ اﺳﺖ ،ﺑﺎﻳﺪ از ﻛﺎراﻛﺘﺮ \ ﻗﺒﻞ از آن اﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺑﻪ ﻫﻤـﻴﻦ ﺗﺮﺗﻴـﺐ ﺑـﺮاي اﻳﻦ ﻛﻪ ﺑﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﺑﮕﻮﻳﻴﻢ در رﺷﺘﻪ "\ "C:ﻛﺎراﻛﺘﺮ \ ﺟﺰﺋﻲ از رﺷﺘﻪ اﺳﺖ ،ﺑﺎﻳﺪ از دو \ ﺑﻪ ﺻﻮرت ﻣﺘﻮاﻟﻲ اﺳﺘﻔﺎده ﻛﻨﻴﻢ و رﺷﺘﻪ را ﺑﻪ ﺻﻮرت "\\ "C:ﺑﻨﻮﻳﺴﻴﻢ .اﮔﺮ اﻳﻦ ﻋﺒﺎرت را ﺑﻪ ﺻﻮرت "\ "C:ﺑﻨﻮﻳﺴﻴﻢ ﻛﺎﻣﭙﺎﻳﻠﺮ ﺗﺼﻮر ﻣﻴﻜﻨـﺪ ﻛـﻪ ﺷـﻤﺎ اﻧﺘﻬـﺎي رﺷـﺘﻪ را ﻣﺸﺨﺺ ﻧﻜﺮده اﻳﺪ و ﺧﻄﺎ اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ ،زﻳﺮا " را در اﻧﺘﻬﺎي رﺷﺘﻪ ،ﺑﻪ ﻋﻨﻮان ﺑﺨﺸﻲ از ﻋﺒﺎرت ﻣﺤﺴﻮب ﻣﻲ ﻛﻨﺪ.
ﺣﻠﻘﻪ ﻫﺎي :do ﻧﻮع دﻳﮕﺮي از ﺣﻠﻘﻪ ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﺣﻠﻘﻪ ﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺗﺎ زﻣﺎن ﺑﺮﻗﺮاري ﻳﻚ ﺷﺮط ﻣـﺸﺨﺺ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ .ﻳﻜﻲ از اﻳﻦ ﺣﻠﻘﻪ ﻫﺎ ،ﺣﻠﻘﻪ ﻫﺎي doﻫﺴﺘﻨﺪ. در اﻳﻦ ﺣﻠﻘﻪ ﻫﺎ ،اﺑﺘﺪا دﺳﺘﻮرات داﺧﻞ ﺣﻠﻘﻪ اﺟﺮا ﺷﺪه ،ﺳﭙﺲ ﺷﺮط ﺣﻠﻘﻪ ﺑﺮرﺳﻲ ﻣﻲ ﺷﻮد .در ﺻﻮرت درﺳﺖ ﺑﻮدن ﺷﺮط ﺣﻠﻘﻪ ،دﺳﺘﻮرات ﻣﺮﺑﻮط ﺑﻪ ﺣﻠﻘﻪ ﺑﺎر دﻳﮕﺮ ﻧﻴﺰ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ،دﺳﺘﻮرات اﺟﺮا ﻧﺨﻮاﻫﻨﺪ ﺷﺪ و اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺧﻂ ﺑﻌﺪ از ﺣﻠﻘـﻪ ﻣﻨﺘﻘـﻞ ﻣﻲ ﺷﻮد .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ﺑﺮﻧﺎﻣﻪ اي را اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﺗﻌﺪادي ﻋﺪد ﺗﺼﺎدﻓﻲ ﺗﻮﻟﻴﺪ ﻛﻨﺪ .ﺗﻮﻟﻴﺪ اﻳﻦ اﻋﺪاد ﺗﺼﺎدﻓﻲ ﺑـﻪ وﺳـﻴﻠﻪ ﺗﻮاﺑﻊ دروﻧﻲ .NETاﻧﺠﺎم ﻣﻲ ﺷﻮد و ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻋﺪد 10ﺗﻮﻟﻴﺪ ﻧﺸﺪه اﺳﺖ اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﺣﻠﻘﻪ do (1در ﻗــﺴﻤﺖ ﻃﺮاﺣــﻲ ﻓــﺮم ،ﻛﻨﺘــﺮل Buttonدﻳﮕــﺮي ﺑــﻪ ﻓــﺮم اﺿــﺎﻓﻪ ﻛﻨﻴــﺪ .ﺧﺎﺻــﻴﺖ Nameآن را ﺑﺮاﺑــﺮ ﺑــﺎ btnDoLoopو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ Do Loopﻗﺮار دﻫﻴﺪ. (2روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪﻫﺎي ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickدﻛﻤﻪ ﻓﺮﻣﺎن ﻗﺮار دﻫﻴﺪ: )private void btnDoLoop_Click(object sender, EventArgs e { // Declare variable ;)(Random objRandom = new Random ;int intRandomNumber = 0 // Clear the list ;)(lstData.Items.Clear // Process the loop until intRandomNumber = 10 do { // Get a random number between 0 and 24 ;)intRandomNumber = objRandom.Next(25 ١٤٨
// Add the number to the list ;)lstData.Items.Add(intRandomNumber ;)} while (intRandomNumber != 10 } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ Do Loopﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻧﺘﻴﺠﻪ اي را ﻣﺸﺎﺑﻪ ﺷﻜﻞ 21-4ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛـﺮد .ﺑـﺎر دﻳﮕﺮ روي اﻳﻦ دﻛﻤﻪ ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ اﻋﺪاد داﺧﻞ ListBoxﺑﺎ اﻋﺪاد دﻳﮕﺮي ﻋﻮض ﻣﻲ ﺷـﻮﻧﺪ و ﺑـﺎ ﻫﺮ ﺑﺎر ﻛﻠﻴﻚ ﻛﺮدن ﺗﻌﺪادي ﻋﺪد ﺟﺪﻳﺪ در ListBoxﻗﺮار ﻣﻲ ﮔﻴﺮد.
ﺷﻜﻞ 21-4
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻳﻚ ﺣﻠﻘﻪ doﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﺷﺮط ﺧﺎص ﺑﺮﻗﺮار ﻧﺸﺪه اﺳﺖ اﺟﺮا ﻣـﻲ ﺷـﻮد .در اﻳـﻦ ﺣﻠﻘـﻪ ﻫـﺎ ،ﻫـﻴﭻ ﻣﺘﻐﻴﻴـﺮ ﻛﻨﺘـﺮل ﻛﻨﻨـﺪه و ﻳـﺎ ﺷﻤﺎرﺷﮕﺮي وﺟﻮد ﻧﺪارد ،ﺑﻠﻜﻪ ﺑﺎﻳﺪ ﺧﻮدﺗﺎن ﻣﻜﺎن ﻛﻨﻮﻧﻲ ﺣﻠﻘﻪ را ﻧﮕﻬﺪاري ﻛﻨﻴﺪ .در اﻳﻦ ﻣﺜﺎل اﺑﺘﺪا ﻳﻚ ﻣﺘﻐﻴﻴﺮ )ﺑـﻪ ﻋﺒـﺎرت دﻳﮕـﺮ ﻳـﻚ ﺷﻴﺊ( از ﻛﻼس Randomاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ .اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﺗﻮاﺑﻊ ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﺗﻮﻟﻴﺪ ﻋﺪد ﺗﺼﺎدﻓﻲ را در اﺧﺘﻴﺎر ﺷﻤﺎ ﻗﺮار ﻣﻲ دﻫﺪ. ﻧﻜﺘﻪ :ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻴﺪاﻧﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ اﻳﺠﺎد ﺷﺪ ،ﺑﺎﻳﺪ ﻣﻘﺪار اوﻟﻴﻪ آن را ﻣﺸﺨﺺ ﻛﺮد و ﺳﭙﺲ از آن اﺳـﺘﻔﺎده ﻛـﺮد .ﺑـﺮاي ﺑﻌﻀﻲ از ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﻫﻤﺎﻧﻨﺪ اﻋﺪاد ﺻﺤﻴﺢ ،ﺑﻪ راﺣﺘﻲ ﻣﻲ ﺗﻮان ﻣﻘﺪار اوﻟﻴﻪ ﻣﺸﺨﺺ ﻛﺮد .اﻣﺎ ﺑﺴﻴﺎري از ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻼﺳﻬﺎ اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ را ﻧﻤﻲ ﺗﻮان ﻫﻤﺎﻧﻨﺪ اﻋﺪاد ﺻﺤﻴﺢ ﻣﻘﺪار اوﻟﻴﻪ داد .ﺑﺮاي ﻣﻘﺪار دﻫﻲ ﺑﻪ اﻳﻦ اﺷﻴﺎ )ﻫﻤﺎﻧﻨـﺪ ﺷـﻴﺊ objRandomدر ﻣﺜﺎل ﻗﺒﻞ( از ﻛﻠﻤﻪ ﻛﻠﻴﺪي newاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .در اﻳﻦ ﺣﺎﻟﺖ ﺧﻮد ﻛﻼس ،ﺑﺮاي ﺷﻴﺊ ﻳﻚ ﻣﻘﺪار اوﻟﻴﻪ اﻳﺠﺎد ﻛﺮده و آن را ﺑﻪ ﺷﻴﺊ ﻧﺴﺒﺖ ﻣﻲ دﻫﺪ.
١٤٩
اﻳﻦ ﺷﻴﺊ ﺑﺎ ﭘﻴﺸﻮﻧﺪ objﻧﺎﻣﮕﺬاري ﺷﺪه اﺳﺖ ﺗﺎ ﻣﺸﺨﺺ ﺷﻮد ﻛﻪ ﻳﻚ ﺷﻴﺊ اﺳﺖ ﻛﻪ از ﻳﻚ ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه اﺳﺖ .ﻣﺘﻐﻴﻴﺮ ﺑﻌـﺪي ﻛﻪ ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﺪ ،ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ ﺑﻪ ﻧﺎم intRandomNumberﺧﻮاﻫﺪ ﺑﻮد ﻛﻪ وﻇﻴﻔﻪ ﻧﮕﻬﺪاري ﻋﺪد ﺗﺼﺎدﻓﻲ ﺗﻮﻟﻴﺪ ﺷﺪه ﺗﻮﺳﻂ objRandomرا ﺑﺮ ﻋﻬﺪه دارد: // Declare variable ;)(Random objRandom = new Random ;int intRandomNumber = 0 در ﻣﺮﺣﻠﻪ ﺑﻌﺪ ،ﻫﺮ ﻣﻮردي را ﻛﻪ ﻗﺒﻼ ﺑﻪ ﻟﻴﺴﺖ اﺿﺎﻓﻪ ﺷﺪه ﺑﻮد از آن ﭘﺎك ﻣﻲ ﻛﻨﻴﺪ: // Clear the list ;)(lstData.Items.Clear ﺳﭙﺲ ﺣﻠﻘﻪ doرا ﺑﻪ ﻧﺤﻮي اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﺗﺎ ﺗﻮﻟﻴﺪ ﻋﺪد 10ﺑﻪ اﺟﺮاي ﺧـﻮد اداﻣـﻪ دﻫـﺪ .در اﻳـﻦ ﺣﻠﻘـﻪ ،اﺑﺘـﺪا ﺑـﺮاي ﻣﺮﺗﺒـﻪ اول دﺳﺘﻮرات اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ و ﺳﭙﺲ ﺷﺮط ﺑﺮرﺳﻲ ﻣﻲ ﺷﻮد .ﺑـﺎ ﻫـﺮ ﺑـﺎر اﺟـﺮاي ﺣﻠﻘـﻪ ﻋـﺪد ﺗـﺼﺎدﻓﻲ ﺟﺪﻳـﺪي ﺗﻮﻟﻴـﺪ و آن را در ﻣﺘﻐﻴﻴـﺮ intRandomNumberذﺧﻴﺮه ﻣﻲ ﻛﻨﻴﺪ .ﺑﺮاي ﺗﻮﻟﻴﺪ ﻋﺪد ﺗﺼﺎدﻓﻲ از ﺗﺎﺑﻊ Nextدر ﺷﻴﺊ objRandomاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻳﻚ ﭘﺎراﻣﺘﺮ ﻣﻲ ﮔﻴﺮد .اﻳﻦ ﭘﺎراﻣﺘﺮ ﺑﺰرﮔﺘﺮﻳﻦ ﻋﺪدي ﻛﻪ اﻳﻦ ﺗﺎﺑﻊ ﻣﻲ ﺗﻮاﻧﺪ ﺗﻮﻟﻴﺪ ﻛﻨﺪ را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ .در اﻳﻨﺠﺎ ﻋﺪد 25ﺑـﻪ ﺗﺎﺑﻊ ﻓﺮﺳﺘﺎده ﺷﺪه اﺳﺖ و ﻣﺸﺨﺺ ﻣﻴﻜﻨﺪ ﻛﻪ ﺗﺎﺑﻊ ﺑﺎﻳﺪ ﻋﺪد ﺗﺼﺎدﻓﻲ در ﺑﺎزه 0ﺗﺎ 24ﺗﻮﻟﻴﺪ ﻛﻨﺪ .ﺑﻌﺪ از ﺗﻮﻟﻴـﺪ ﻋـﺪد ﺗـﺼﺎدﻓﻲ ،آن را ﺑـﻪ ﻟﻴﺴﺖ ﺧﻮد اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﺪ: // Get a random number between 0 and 24 ;)intRandomNumber = objRandom.Next(25 // Add the number to the list ;)lstData.Items.Add(intRandomNumber در اﻧﺘﻬﺎ ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ آﻳﺎ ﻋﺪد ﺗﻮﻟﻴﺪ ﺷﺪه ﺑﺮاﺑﺮ ﺑﺎ 10ﺑﻮده اﺳﺖ ﻳﺎ ﻧﻪ؟ اﮔﺮ ﻋﺪد ﺗﻮﻟﻴﺪ ﺷﺪه ﻣﺨـﺎﻟﻒ 10ﺑﺎﺷـﺪ ،ﺑﺮﻧﺎﻣـﻪ ﺑـﻪ اﺑﺘـﺪاي دﺳﺘﻮرات ﺣﻠﻘﻪ doﺑﺮﻣﻴﮕﺮدد و ﺑﺎر دﻳﮕﺮ ﺣﻠﻘﻪ را اﺟﺮا ﻣﻲ ﻛﻨﺪ .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت از ﺣﻠﻘﻪ ﺧﺎرج ﺷﺪه و ﺑﻪ اوﻟﻴﻦ ﺧﻂ ﺑﻌﺪ از ﺣﻠﻘﻪ ﻣـﻲ رود. ﻧﻜﺘﻪ :ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ دﺳﺘﻮرات در اﻳﻦ ﺣﻠﻘﻪ ﻗﺒﻞ از ﺑﺮرﺳـﻲ ﺷـﺮط ﺣﺘﻤـﺎ ﻳـﻚ ﺑـﺎر اﺟـﺮا ﻣـﻲ ﺷـﻮﻧﺪ ،ﻧﻴـﺎزي ﻧﻴـﺴﺖ ﻛـﻪ ﺑـﻪ ﻣﺘﻐﻴﻴـﺮ intRandomNumberﻣﻘﺪار اوﻟﻴﻪ اﺧﺘﺼﺎص دﻫﻴﺪ .زﻳﺮا اﻳﻦ ﻣﺘﻐﻴﻴﺮ در ﻣﺮﺣﻠﻪ اوﻟﻲ ﻛﻪ دﺳﺘﻮرات ﺣﻠﻘﻪ اﺟﺮا ﻣﻲ ﺷـﻮﻧﺪ ﻣﻘـﺪار ﻣﻲ ﮔﻴﺮد.
ﺣﻠﻘﻪ :while ﻋﻤﻠﻜﺮد اﻳﻦ ﺣﻠﻘﻪ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﺣﻠﻘﻪ doاﺳﺖ ﺑﺎ اﻳﻦ ﺗﻔﺎوت ﻛﻪ ﺷﺮط اﻳﻦ ﺣﻠﻘﻪ در اﺑﺘﺪا ﺑﺮرﺳﻲ ﻣﻲ ﺷـﻮد و ﺳـﭙﺲ ،در ﺻـﻮرت درﺳـﺖ ﺑﻮدن آن دﺳﺘﻮرات داﺧﻞ ﺣﻠﻘﻪ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ .در ﺑﺨﺶ ﺑﻌﺪ ﻛﺎرﺑﺮد اﻳﻦ ﺣﻠﻘﻪ ﻫﺎ را در ﺑﺮﻧﺎﻣﻪ ﺧﻮاﻫﻴﻢ دﻳﺪ.
١٥٠
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﺣﻠﻘﻪ ﻫﺎي while (1ﻛﻨﺘﺮل Buttonدﻳﮕﺮي ﺑﻪ ﻓﺮم ﺧـﻮد اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ ،ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑـﺮ btnDoWhileLoopو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ Do While Loopﻗﺮار دﻫﻴﺪ. (2روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن ﻗﺮار دﻫﻴﺪ: private void btnDoWhileLoop_Click(object sender, )EventArgs e { // Declare variables ;)(Random objRandom = new Random ;int intRandomNumber = 0 // Clear the list ;)(lstData.Items.Clear // Process the loop while intRandomNumber < 15 )while (intRandomNumber < 15 { // Get a random number between 0 and 24 ;)intRandomNumber = objRandom.Next(25 // Add the number to the list ;)lstData.Items.Add(intRandomNumber } } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ ي Do While Loopﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻧﺘﻴﺠﻪ اي را ﻣـﺸﺎﺑﻪ ﺷـﻜﻞ 22-4ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد. (4ﻫﺮ ﺑﺎر ﻛﻪ روي دﻛﻤﻪ ﻓﺮﻣﺎن ﻛﻠﻴﻚ ﻛﻨﻴﺪ اﻋﺪاد ﺟﺪﻳﺪي درون ﻟﻴﺴﺖ ﺑﺎﻛﺲ ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ .ﺗﻮﻟﻴﺪ اﻳﻦ اﻋـﺪاد ﺗـﺎ زﻣـﺎﻧﻲ ﻛـﻪ ﻋﺪدي ﺑﺰرﮔﺘﺮ از 15ﺗﻮﻟﻴﺪ ﺷﻮد ،اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻴﻢ ،ﻋﻤﻠﻜﺮد ﺣﻠﻘﻪ whileﻫﻤﺎﻧﻨﺪ ﺣﻠﻘﻪ doاﺳﺖ ﺑﺎ اﻳﻦ ﺗﻔﺎوت ﻛﻪ در اﻳﻦ ﻧﻮع ﺣﻠﻘﻪ ،ﺷـﺮط در اﺑﺘـﺪا ﺑﺮرﺳـﻲ ﻣـﻲ ﺷﻮد و در ﺻﻮرت درﺳﺖ ﺑﻮدن آن ،دﺳﺘﻮرات ﺣﻠﻘﻪ اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﺑﺮﻧﺎﻣﻪ اوﻟﻴﻦ ﺧﻂ ﺑﻌﺪ از ﺣﻠﻘﻪ را اﺟﺮا ﻣﻲ ﻛﻨﺪ. در اﻳﻦ ﻣﺜﺎل ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺣﻠﻘﻪ ﺷﺮوع ﺑﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ ،در اﺑﺘﺪا ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﺪ ﻛـﻪ آﻳـﺎ ﻣﻘـﺪار intRandomNumberاز 15 ﻛﻮﭼﻜﺘﺮ اﺳﺖ ﻳﺎ ﻧﻪ؟ در ﺻﻮرﺗﻲ ﻛﻪ ﺷﺮط درﺳﺖ ﺑﺎﺷﺪ ،دﺳﺘﻮرات داﺧﻞ ﺣﻠﻘﻪ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ. // Process the loop while intRandomNumber < 15 )while (intRandomNumber < 15 {
١٥١
// Get a random number between 0 and 24 ;)intRandomNumber = objRandom.Next(25 // Add the number to the list ;)lstData.Items.Add(intRandomNumber } ﺑﻌﺪ از اﻳﻨﻜﻪ ﺣﻠﻘﻪ ﺑﺮاي ﻣﺮﺗﺒﻪ اول اﺟﺮا ﺷﺪ ،ﻋﺪد ﺗﺼﺎدﻓﻲ ﺟﺪﻳﺪ در ﻣﺘﻐﻴﻴﺮ intRandomNumberﻗﺮار ﻣﻲ ﮔﻴﺮد و ﺷﺮط ﺣﻠﻘﻪ ﻣﺠﺪدا ﺑﺮرﺳﻲ ﻣﻲ ﺷﻮد .اﮔﺮ ﻋﺪد ﺗﻮﻟﻴﺪ ﺷﺪه از 15ﻛﻮﭼﻜﺘﺮ ﺑﺎﺷﺪ دﺳﺘﻮرات ﺣﻠﻘﻪ دوﺑﺎره اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ .در ﻏﻴﺮ اﻳـﻦ ﺻـﻮرت ،ﺑﺮﻧﺎﻣـﻪ ﺑـﻪ اوﻟﻴﻦ ﺧﻂ ﺑﻌﺪ از ﺣﻠﻘﻪ ﻣﻲ ﺷﻮد و دﺳﺘﻮرات آن را اﺟﺮا ﻣﻴﻜﻨﺪ.
ﺷﻜﻞ 22-4
ﺷﺮﻃﻬﺎي ﻗﺎﺑﻞ ﻗﺒﻮل ﺑﺮاي ﺣﻠﻘﻪ ﻫﺎي doو :while ﻣﻤﻜﻦ اﺳﺖ از ﻋﺒﺎرﺗﻬﺎي ﺷﺮﻃﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ در اﻳﻦ ﺣﻠﻘﻪ ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ﺗﻌﺠﺐ ﻛﻨﻴﺪ .وﻟﻲ ﻫﺮ ﻋﺒﺎرﺗﻲ را ﻛﻪ ﺑﺘﻮاﻧﻴﺪ در دﺳـﺘﻮر if اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ آن را ﺑﻪ ﻋﻨﻮان ﺷﺮط ﺣﻠﻘﻪ doو whileﻧﻴﺰ ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ .ﺑﺮاي ﻣﺜﺎل ﺑﻪ ﺷﺮط ﻫﺎي زﻳﺮ ﺗﻮﺟﻪ ﻛﻨﻴﺪ: )while (intX > 10 && intX < 100 ﻳﺎ: do { ;)} while ((intX > 10 && intX < 100) || intY == true ﻳﺎ:
١٥٢
)while (String.Compare(strA, strB) > 0 ﺧﻼﺻﻪ ،اﻳﻦ ﺣﻠﻘﻪ ﻫﺎ ﻗﺪرت و اﻧﻌﻄﺎف ﭘﺬﻳﺮي ﺑﺴﻴﺎر زﻳﺎدي دارﻧﺪ.
ﺣﻠﻘﻪ ﻫﺎي ﺗﻮدرﺗﻮ: در ﺑﻌﻀﻲ از ﺷﺮاﻳﻂ ﻣﻤﻜﻦ اﺳﺖ ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﻴﺪ در ﺣﻴﻦ اﻳﻦ ﻛﻪ درون ﻳﻚ ﺣﻠﻘﻪ ﻫﺴﺘﻴﺪ ،ﺣﻠﻘﻪ ﺟﺪﻳﺪي را ﺷﺮوع ﻛﻨﻴـﺪ .ﺑـﻪ اﻳـﻦ ﻧـﻮع ﺣﻠﻘﻪ ﻫﺎ ،ﺣﻠﻘﻪ ﻫﺎي ﺗﻮدرﺗﻮ ﻣﻲ ﮔﻮﻳﻨﺪ و در اﺻﻞ ﻫﻤﺎﻧﻨﺪ دﺳﺘﻮرات ifﺗﻮدرﺗﻮ ﻫﺴﺘﻨﺪ .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛـﺮد ﻛـﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ از اﻳﻦ ﻧﻮع ﺣﻠﻘﻪ ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﺣﻠﻘﻪ ﻫﺎي ﺗﻮدرﺗﻮ (1در ﻗــﺴﻤﺖ ﻃﺮاﺣــﻲ ﻓــﺮم ،ﻛﻨﺘــﺮل Buttonدﻳﮕــﺮي ﺑــﻪ ﻓــﺮم اﺿــﺎﻓﻪ ﻛﻨﻴــﺪ ،ﺧﺎﺻــﻴﺖ Nameآن را ﺑﺮاﺑــﺮ ﺑــﺎ btnNestedLoopو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Nested Loopﻗﺮار دﻫﻴﺪ. (2ﺑﺮ روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickوارد ﻛﻨﻴﺪ. private void btnNestedLoops_Click(object sender, )EventArgs e { // Process an outer loop )for (int intLoop1 = 1; intLoop1 <= 2; intLoop1++ { // Process a nested (inner) loop )for (int intLoop2 = 1; intLoop2 <= 3; intLoop2++ { " lstData.Items.Add(intLoop1 + ", ;)+ intLoop2 } } } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ Nested Loopﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻧﺘﻴﺠﻪ اي ﻣﺸﺎﺑﻪ ﺷـﻜﻞ 23-4را ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛﺮد.
١٥٣
ﺷﻜﻞ 23-4
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻛﺪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻛﺎﻣﻼ ﻣﺸﺨﺺ اﺳﺖ و ﺟﺎي اﺑﻬﺎﻣﻲ ﻧﺪارد .ﺣﻠﻘﻪ اول )ﺣﻠﻘﻪ ﺑﻴﺮوﻧﻲ( ﺑﺎ اﺳﺘﻔﺎده از ﺷﻤﺎرﺷﮕﺮ intLoop1از ﻋـﺪد 1 ﺗﺎ 2و ﺣﻠﻘﻪ دوم ﻳﺎ ﺣﻠﻘﻪ دروﻧﻲ ﺑﺎ اﺳﺘﻔﺎده از ﺷﻤﺎرﺷﮕﺮ intLoop2از 1ﺗﺎ 3ﺣﺮﻛﺖ ﻣﻲ ﻛﻨﺪ .در ﺣﻠﻘﻪ دروﻧﻲ ﻛﺪي ﺑﺮاي ﻧﻤﺎﻳﺶ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ ﻫﺎي intLoop1و intLoop2وﺟﻮد دارد: // Process an outer loop )for (int intLoop1 = 1; intLoop1 <= 2; intLoop1++ { // Process a nested (inner) loop )for (int intLoop2 = 1; intLoop2 <= 3; intLoop2++ { " lstData.Items.Add(intLoop1 + ", ;)+ intLoop2 } } در ﺣﻠﻘﻪ ﻫﺎي ﺗﻮ در ﺗﻮ ﺑﺎﻳﺪ ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،ﺣﻠﻘﻪ اي ﻛﻪ در درون ﻳﻚ ﺣﻠﻘﻪ دﻳﮕﺮ ﺷﺮوع ﻣﻲ ﺷﻮد ،در ﻫﻤﺎن ﺣﻠﻘﻪ ﻧﻴﺰ ﺗﻤﺎم ﻣﻲ ﺷﻮد. ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻛﺪﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﺣﻠﻘﻪ دروﻧﻲ ﻧﻤﻲ ﺗﻮاﻧﻨﺪ در ﺧﺎرج از ﺣﻠﻘﻪ ﺑﻴﺮوﻧﻲ ﻗﺮار ﺑﮕﻴﺮﻧﺪ .در اﻳﻨﺠﺎ اوﻟﻴﻦ آﻛﻮﻻدي ﻛﻪ ﺑﺴﺘﻪ ﺷـﺪه اﺳﺖ ﻣﺮﺑﻮط ﺑﻪ ﺣﻠﻘﻪ داﺧﻠﻲ اﺳﺖ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﺮاي اوﻟﻴﻦ ﺑﺎر وارد ﺣﻠﻘﻪ intLoop1ﻣﻲ ﺷﻮد ،ﺣﻠﻘـﻪ intLoop2را ﺳﻪ ﺑﺎر اﺟﺮا ﻣﻲ ﻛﻨﺪ .ﺳﭙﺲ ﻳﻚ واﺣﺪ ﺑﻪ ﺷﻤﺎرﻧﺪه ﺣﻠﻘﻪ intLoop1اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ و ﺑﺎر دﻳﮕﺮ ﺳـﻪ ﺑـﺎر دﺳـﺘﻮرات داﺧـﻞ ﺣﻠﻘـﻪ intLoop2را اﺟﺮا ﻣﻲ ﻛﻨﺪ .اﻳﻦ ﺗﻜﺮار اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ ﺗﺎ دﻓﻌﺎت ﺗﻜﺮار ﺣﻠﻘﻪ اول ﺑﻪ ﭘﺎﻳﺎن ﺑﺮﺳﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺮﻧﺎﻣﻪ از ﻫﺮ دو ﺣﻠﻘﻪ ﺧﺎرج ﻣﻲ ﺷﻮد و ﺑﻪ اوﻟﻴﻦ ﺧﻂ ﺑﻌﺪ از آﻧﻬﺎ ﻣﻲ رود.
١٥٤
ﺧﺮوج زودﻫﻨﮕﺎم از ﺣﻠﻘﻪ: ﺑﻌﻀﻲ ﻣﻮاﻗﻊ در ﺑﺮﻧﺎﻣﻪ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﻳﻚ ﺣﻠﻘﻪ forﺗﺎ اﻧﺘﻬﺎ اﺟﺮا ﺷﻮد .ﻣﺜﻼ در ﻳﻚ ﻟﻴﺴﺖ ﺑـﻪ دﻧﺒـﺎل ﻣـﻮردي ﺧـﺎص ﻣﻴﮕﺮدﻳـﺪ و ﻣﻴﺨﻮاﻫﻴﺪ ﺑﺎ ﭘﻴﺪا ﺷﺪن آن ﻣﻮرد از ﺣﻠﻘﻪ ﺧﺎرج ﺷﻮﻳﺪ ،زﻳﺮا ﮔﺸﺘﻦ ﺑﻘﻴﻪ ﻋﻨﺎﺻﺮ ﻟﻴﺴﺖ ﻻزم ﻧﻴﺴﺖ. در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ ﺗﻤﺎم ﻓﻮﻟﺪرﻫﺎي دراﻳـﻮ Cرا ﻧﻤـﺎﻳﺶ ﻣﻴـﺪاد ﺑـﻪ ﻧﺤـﻮي ﺗﻐﻴﻴـﺮ ﻣﻴﺪﻫﻴـﺪ ﻛـﻪ ﺑـﺎ رﺳـﻴﺪن ﺑـﻪ ﻓﻮﻟـﺪر C:\Program Filesﭘﻴﻐﺎﻣﻲ را ﻧﺸﺎن دﻫﺪ و از ﺑﺮﻧﺎﻣﻪ ﺧﺎرج ﺷﻮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺧﺮوج زودﻫﻨﮕﺎم از ﺣﻠﻘﻪ (1ﻛﻨﺘﺮل Buttonﺟﺪﻳﺪي ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﺪ ،ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑـﺮ btnQuittingAForLoop و ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ Quitting a For Loopﻗﺮار دﻫﻴﺪ. (2روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن ﻗﺮار دﻫﻴﺪ: private void btnQuittingAForLoop_Click(object sender, )EventArgs e { // List each folder at the root of your C Drive foreach (string strFolder in ))"\\System.IO.Directory.GetDirectories("C: { // Add the item to the list ;)lstData.Items.Add(strFolder ?// Do you have the folder C:\Program Files if(String.Compare(strFolder, )"c:\\program files",true) == 0 { // Tell the user "MessageBox.Show("Found it, exiting the loop ;)"+ " now.","Loops // Quit the loop early ;break } } } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ ي Quitting A For Loopﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻧﺘﻴﺠﻪ اي ﻣﺸﺎﺑﻪ ﺷـﻜﻞ 24-4 را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
١٥٥
ﺷﻜﻞ 24-4
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﺮ ﺑﺎر ﻛﻪ ﺣﻠﻘﻪ اﺟﺮا ﻣﻲ ﺷﻮد ،ﺑﺎ اﺳﺘﻔﺎده از ﺗﺎﺑﻊ String.Compareﻛﻪ ﻧﺤﻮه ﻛﺎر آن ﻗﺒﻼ ﺗﻮﺿﻴﺢ داده ﺷﺪ ،ﺑﺮرﺳﻲ ﻣﻴﻜﻨﻴـﺪ ﻛﻪ آﻳﺎ ﻧﺎم ﻓﻮﻟﺪر ﺑﺮاﺑﺮ ﺑﺎ C:\Program Filesاﺳﺖ ﻳﺎ ﻧﻪ؟ ?// Do you have the folder C:\Program Files )if(String.Compare(strFolder,"c:\\program files",true) == 0 در ﺻﻮرﺗﻲ ﻛﻪ ﻧﺎم ﻓﻮﻟﺪر ﺑﺮاﺑﺮ ﺑﺎ " "C:\Program Filesﺑﻮد اﺑﺘﺪا ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ ﻣﻴﺪﻫﻴﺪ. // Tell the user ;)"MessageBox.Show("Found it, exiting the loop now.","Loops ﺑﻌﺪ از آن ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر breakاز ﺣﻠﻘﻪ ﺧﺎرج ﻣﻲ ﺷﻮﻳﺪ .در اﻳﻦ ﺣﺎﻟﺖ ﻫﻨﮕﺎﻣﻲ ﻛﻪ وﻳﮋوال C#ﺑﻪ اﻳﻦ دﺳﺘﻮر ﺑﺮﺳﺪ ،ﺑﻪ اوﻟﻴﻦ ﺧﻂ ﺑﻌﺪ از ﺣﻠﻘﻪ ﻣﻲ رود و آن را اﺟﺮا ﻣﻲ ﻛﻨﺪ .در اﻳﻦ ﻣﺜﺎل از دﺳﺘﻮر breakﺑﺮاي ﺧﺮوج از ﺣﻠﻘﻪ forاﺳﺘﻔﺎده ﻛﺮدﻳﻢ اﻣﺎ از اﻳـﻦ دﺳﺘﻮر ﺑﺮاي ﺧﺮوج زودﻫﻨﮕﺎم از ﻫﺮ ﻧﻮع ﺣﻠﻘﻪ اي در C#ﻣﻴﺘﻮاﻧﻴﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. // Quit the loop early ;break
١٥٦
اﻟﺒﺘﻪ اﮔﺮ ﻧﺎم ﻓﻮﻟﺪر ﺑﺮاﺑﺮ ﺑﺎ ﻧﺎﻣﻲ ﻛﻪ ﺑﻪ دﻧﺒﺎل آن ﻫﺴﺘﻴﺪ ﻧﺒﺎﺷﺪ ،ﺟﺴﺘﺠﻮ ﺗﺎ اﻧﺘﻬﺎي ﻟﻴﺴﺖ اداﻣﻪ ﭘﻴﺪا ﻣﻴﻜﻨﺪ .در ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑـﺮاي ﺟـﺴﺘﺠﻮي ﻳﻚ ﻣﻮرد ﺧﺎص ﻣﻌﻤﻮﻻ از ﺣﻠﻘﻪ ﻫﺎي forاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ .اﺳﺘﻔﺎده از دﺳﺘﻮر breakﺑﺮاي ﺧﺮوج از ﺣﻠﻘﻪ ﻫﻨﮕﺎم ﭘﻴﺪا ﺷﺪن آﻳﺘﻢ ﻣﻮرد ﻧﻈﺮ ﺑﺎﻋﺚ اﻓﺰاﻳﺶ ﺳﺮﻋﺖ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺷﻮد. ﺗﺼﻮر ﻛﻨﻴﺪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻟﻴﺴﺘﻲ ﺷﺎﻣﻞ 1000آﻳﺘﻢ را ﺟﺴﺘﺠﻮ ﻛﻨﻴﺪ و آﻳﺘﻢ ﻣﻮرد ﻧﻈﺮ ﺷﻤﺎ در ﻣﻜﺎن دﻫﻢ ﻗﺮار دارد .اﮔﺮ ﺑﻌﺪ از ﭘﻴـﺪا ﻛـﺮدن آن از ﺣﻠﻘﻪ ﺧﺎرج ﻧﺸﻮﻳﺪ ،از ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻛﻪ 990آﻳﺘﻢ را ﺑﻲ دﻟﻴﻞ ﺟﺴﺘﺠﻮ ﻛﻨﺪ ﻛﻪ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﺳﺮﻋﺖ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺷـﺪت ﻛـﻢ ﺷﻮد. ﻧﻜﺘﻪ :ﺑﻪ ﻧﺤﻮه ﻧﻮﺷﺘﻦ آدرﺳﻬﺎ در ﻋﺒﺎرﺗﻬﺎي رﺷﺘﻪ اي اﻳﻦ ﺑﺮﻧﺎﻣﻪ دﻗﺖ ﻛﻨﻴﺪ .ﻛﺎراﻛﺘﺮ \ در ﺗﻤﺎم آﻧﻬﺎ ﺑﻪ ﺻﻮرت \\ ﻧﻮﺷﺘﻪ ﺷﺪه اﺳـﺖ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺑﺨﺶ ﻗﺒﻠﻲ ﺷﺮح داده ﺷﺪ ،ﺑﺮاي ﻗﺮار دادن ﻛﺎراﻛﺘﺮ \ در رﺷﺘﻪ ﺑﺎﻳﺪ از \\ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ در ﺑﺮﻧﺎﻣﻪ ﺑـﺎﻻ ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از رﺷﺘﻪ " "c:\\program filesاز " "c:\program filesاﺳﺘﻔﺎده ﻛﻨﻴﺪ ﺑﺎ ﺧﻄﺎي " "Unrecognized scape sequenceروﺑﺮو ﺧﻮاﻫﻴﺪ ﺷﺪ ،زﻳﺮا ﺑﻌﺪ از ﻛﺎراﻛﺘﺮ \ در ﻳـﻚ رﺷـﺘﻪ ،ﺑﺎﻳـﺪ ﻳـﻚ ﻛﺎراﻛﺘﺮ ﻛﻨﺘﺮﻟﻲ ﺑﺎ ﻣﻌﻨﻲ ﺑﺮاي ﻛﺎﻣﭙﺎﻳﻠﺮ ﻗﺮار ﺑﮕﻴﺮد و ﻛﺎراﻛﺘﺮ pﺟﺰ اﻳﻦ ﻛﺎراﻛﺘﺮﻫﺎ ﻧﻴﺴﺖ. ﻧﻜﺘﻪ :ﺑﻪ ﻛﺪ زﻳﺮ ﺑﺮاي ﺗﻌﺮﻳﻒ ﻳﻚ ﺛﺎﺑﺖ رﺷﺘﻪ اي دﻗﺖ ﻛﻨﻴﺪ: ;"string FileName = @"C:\Test\Temp.txt در اﻳﻦ ﻛﺪ ﺑﺮ ﺧﻼف ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ از دو ﻛﺎراﻛﺘﺮ \ اﺳﺘﻔﺎده ﻧﻜﺮده اﻳﻢ .ﺑﻠﻜﻪ ﻓﻘﻂ ﻳﻚ \ ﺑﻪ ﻛـﺎر ﺑـﺮده اﻳـﻢ و ﻗﺒـﻞ از رﺷـﺘﻪ ﻫـﻢ از ﻋﻼﻣﺖ @ اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ .در وﻳﮋوال C#اﮔﺮ ﻗﺒﻞ از ﺷﺮوع ﻳﻚ رﺷﺘﻪ از ﻋﻼﻣﺖ @ اﺳـﺘﻔﺎده ﺷـﻮد ،ﺗﻤـﺎم ﻛﺎراﻛﺘﺮﻫـﺎي ﻛﻨﺘﺮﻟـﻲ در رﺷﺘﻪ ﺑﻪ ﺻﻮرت ﻛﺎراﻛﺘﺮﻫﺎي ﻋﺎدي در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮﻧﺪ و رﺷﺘﻪ ﺗﺎ ﻋﻼﻣﺖ ﻧﻘﻞ ﻗﻮل ﺑﻌﺪي اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ .در اﻳﻦ رﺷﺘﻪ ﻫﻢ ﻗﺒﻞ از ﺷﺮوع از ﻋﻼﻣﺖ @ اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻤﺎم ﻛﺎراﻛﺘﺮ ﻫﺎ )ﺣﺘﻲ \( ﺗﺎ ﻛﺎراﻛﺘﺮ ﻧﻘﻞ ﻗﻮل ﭘﺎﻳﺎﻧﻲ ﺟﺰﺋﻲ از رﺷﺘﻪ ﺑﻪ ﺷﻤﺎر ﻣﻲ روﻧﺪ.
دﺳﺘﻮر :continue در ﺑﻌﻀﻲ از ﻣﻮاﻗﻊ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ دﺳﺘﻮرات ﺣﻠﻘﻪ در ﺷﺮاﻳﻄﻲ ﺧﺎص اﺟﺮا ﻧﺸﻮﻧﺪ .ﻓـﺮض ﻛﻨﻴـﺪ ﻣﻴﺨﻮاﻫﻴـﺪ اﻋـﺪاد 1ﺗـﺎ 15را ﻛـﻪ ﻣﻀﺮﺑﻲ از 3ﻧﻴﺴﺘﻨﺪ در ListBoxﻗﺮار دﻫﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ از ﻳﻚ ﺣﻠﻘﻪ forاﺳـﺘﻔﺎده ﻛﻨﻴـﺪ ﻛـﻪ ﺷـﻤﺎرﻧﺪه آن از ﻳـﻚ ﺗـﺎ ﭘﺎﻧﺰده ،ﻳﻚ واﺣﺪ ﻳﻚ واﺣﺪ اﻓﺰاﻳﺶ ﻳﺎﺑﺪ ،اﻣﺎ در ﺻﻮرﺗﻲ ﻛﻪ ﻋﺪد ﺑﺮ ﺳﻪ ﺑﺨﺶ ﭘﺬﻳﺮ ﺑﻮد ﻧﺒﺎﻳﺪ آن را در ListBoxﻗﺮار دﻫﻴـﺪ و ﺑـﻪ ﻋﺪد ﺑﻌﺪي ﺑﺮوﻳﺪ. در اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ﻧﺤﻮه ﻧﻮﺷﺘﻦ ﭼﻨﻴﻦ ﺑﺮﻧﺎﻣﻪ اي را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد:
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :دﺳﺘﻮر continue (1ﻛﻨﺘﺮل Buttonدﻳﮕﺮي ﺑﻪ ﻓﺮم اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ ،ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑـﺮ ﺑـﺎ btnContinueو ﺧﺎﺻـﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Continueﻗﺮار دﻫﻴﺪ. (2روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن وارد ﻛﻨﻴﺪ:
١٥٧
)private void btnContinue_Click(object sender, EventArgs e { // Perform a loop )for (int intCount = 1; intCount <= 15; intCount++ { // If the item is dividable by 3, // go to next number )if ((intCount % 3) == 0 ;continue // Add the item to the list ;)lstData.Items.Add(intCount } } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ ي Continueﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛـﻪ ﺗﻤـﺎم اﻋـﺪاد از 1ﺗـﺎ 15ﺑـﻪ ﺟـﺰ ﻣﻀﺎرب ﺳﻪ در ﻟﻴﺴﺖ ﺑﺎﻛﺲ ﻗﺮار ﮔﺮﻓﺘﻪ اﻧﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ دﺳﺘﻮر continueﺑﺎﻋﺚ ﺧﺮوج ﻛﺎﻣﻞ از ﺣﻠﻘﻪ ﻧﻤﻲ ﺷﻮد ،ﺑﻠﻜﻪ در ﻫﺮ ﻗﺴﻤﺘﻲ ﻛﻪ اﺳﺘﻔﺎده ﺷﻮد ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﺑﻘﻴﻪ دﺳﺘﻮرات ﺣﻠﻘﻪ ﻛﻪ ﺑﻌﺪ از اﻳﻦ دﺳﺘﻮر ﻗﺮار ﮔﺮﻓﺘﻪ اﻧﺪ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻧﺸﻮﻧﺪ و ﺣﻠﻘﻪ ﻣﺠﺪدا اﺟﺮا ﺷﻮد .در اﻳﻦ ﻣﺜﺎل ﺑـﺮاي اﻋـﺪاد 1و ،2ﺣﻠﻘـﻪ ﺑـﻪ ﺻـﻮرت ﻋﺎدي ﻛﺎر ﻣﻲ ﻛﻨﺪ .ﺑﺎ رﺳﻴﺪن ﺑﻪ ﻋﺪد ﺳﻪ ،ﺑـﻪ ﻋﻠـﺖ اﻳﻨﻜـﻪ ﺑﺎﻗﻴﻤﺎﻧـﺪه اﻳـﻦ ﻋـﺪد ﺑـﺮ ﺳـﻪ ﺑﺮاﺑـﺮ ﺑـﺎ ﺻـﻔﺮ اﺳـﺖ ،ﻛﺎﻣﭙـﺎﻳﻠﺮ ﺑـﻪ دﺳـﺘﻮر continueﻣﻲ رﺳﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ وﻳﮋوال C#ﺑﻪ اﻳﻦ دﺳﺘﻮر رﺳﻴﺪ ،ﺑﻘﻴﻪ دﺳﺘﻮرات ﺣﻠﻘﻪ را اﺟﺮا ﻧﻤﻲ ﻛﻨﺪ ،ﺑﻠﻜﻪ ﺷﻤﺎرﻧﺪه ﺣﻠﻘـﻪ را ﻳﻚ واﺣﺪ اﻓﺰاﻳﺶ ﻣﻴﺪﻫﺪ و ﺣﻠﻘﻪ را ﺑﺮاي ﻋﺪد 4اﺟﺮا ﻣﻲ ﻛﻨﺪ .اﻳﻦ ﻣﺮﺗﺒﻪ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ اﻋﺪاد ﻗﺒﻞ از ،3ﭼﻮن ﻋﺪد 4ﻣـﻀﺮﺑﻲ از 3ﻧﻴـﺴﺖ ﭘﺲ ﺑﺎﻗﻴﻤﺎﻧﺪه ﺑﺮاﺑﺮ ﺑﺎ ﺻﻔﺮ ﻧﻤﻲ ﺷﻮد و ﻋﺒﺎرت داﺧﻞ ifدرﺳﺖ ﻧﻴﺴﺖ .ﭘﺲ دﺳﺘﻮر continueاﺟﺮا ﻧﻤﻲ ﺷﻮد و ﺑﻘﻴﻪ دﺳـﺘﻮرات ﺣﻠﻘﻪ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ. ﻧﻜﺘﻪ :ﻋﻤﻠﮕﺮ %ﺑﺮاي ﻣﺤﺎﺳﺒﻪ ﺑﺎﻗﻴﻤﺎﻧﺪه ﺗﻘﺴﻴﻢ دو ﻋﺪد ﺑﻪ ﻛﺎر ﻣﻴﺮود .در اﻳﻦ ﻣﺜﺎل اﺳﺘﻔﺎده از اﻳﻦ ﻋﻤﻠﮕﺮ ﻣﻮﺟﺐ ﻣﻲ ﺷﻮد در ﻫﺮ ﻣﺮﺣﻠﻪ ﺑﺎﻗﻴﻤﺎﻧﺪه ﺗﻘﺴﻴﻢ intCountﺑﺮ ﺳﻪ ﻣﺤﺎﺳﺒﻪ ﺷﻮد و در ﺷﺮط ifﺑﺮرﺳﻲ ﺷﻮد.
ﺣﻠﻘﻪ ﻫﺎي ﺑﻲ ﻧﻬﺎﻳﺖ: ﻫﻨﮕﺎم اﻳﺠﺎد ﺣﻠﻘﻪ ﻫﺎ ،ﻣﻴﺘﻮاﻧﻴﺪ ﺣﻠﻘﻪ ﻫﺎﻳﻲ اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ ﺑﻴﻨﻬﺎﻳﺖ ﺑﺎر اﺟﺮا ﺷﻮﻧﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺷﺮوع ﺷﻮﻧﺪ ،ﻫـﻴﭻ وﻗـﺖ ﺗﻤﺎم ﻧﺸﻮﻧﺪ .ﺑﻪ ﺣﻠﻘﻪ اﻳﺠﺎد ﺷﺪه در ﻛﺪ زﻳﺮ ﻧﮕﺎه ﻛﻨﻴﺪ: )for (int intCount = 1; intCount > 0; intCount++ {
١٥٨
;)lstData.Items.Add(intCount } ﺑﺎ ﺷﺮوع ﺣﻠﻘﻪ ﻣﻘﺪار ﺷﻤﺎرﻧﺪه ﺑﺮاﺑﺮ ﺑﺎ ﻋﺪد 1اﺳﺖ و ﭼﻮن از ﺻﻔﺮ ﺑﺰرﮔﺘﺮ اﺳﺖ ﺣﻠﻘﻪ ﺑﺮاي ﺑﺎر اول اﺟﺮا ﻣﻲ ﺷﻮد .ﺑﻌﺪ از اﺟﺮاي دﺳـﺘﻮرات ﺣﻠﻘﻪ ،ﺷﻤﺎرﻧﺪه ﺗﻐﻴﻴﺮ ﻣﻲ ﻛﻨﺪ و ﺑﺮاﺑﺮ ﺑﺎ دو ﻣﻲ ﺷﻮد .در اﻳﻦ ﻣﺮﺣﻠﻪ ﻧﻴﺰ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﻋﺪد 2از ﺻﻔﺮ ﺑﺰرﮔﺘﺮ اﺳﺖ ،ﺣﻠﻘﻪ ﻣﺠﺪدا اﺟﺮا ﻣـﻲ ﺷﻮد .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،ﺷﻤﺎرﻧﺪه ي اﻳﻦ ﺣﻠﻘﻪ ﻫﻴﭽﮕﺎه ﺑﻪ ﻋﺪدي ﻛﻮﭼﻜﺘﺮ از ﺻﻔﺮ ﻧﻤﻲ رﺳـﺪ ،ﭘـﺲ ﺷـﺮط ﺣﻠﻘـﻪ ﻫﻤـﻮاره درﺳﺖ اﺳﺖ .اﻳﻦ ﺣﻠﻘﻪ ﺑﻴﻨﻬﺎﻳﺖ ﺑﺎر اﺟﺮا ﻣﻲ ﺷﻮد .ﻣﻤﻜﻦ اﺳﺖ ﺑﺮﻧﺎﻣﻪ ﺗﻮﻗﻒ ﻧﻜﻨﺪ اﻣﺎ ﺑﻪ ﻛﻠﻴﻚ ﻫﺎي ﺑﻌﺪي ﭘﺎﺳﺨﻲ ﻧﺨﻮاﻫـﺪ داد و داﺋﻤـﺎ دﺳﺘﻮرات ﺣﻠﻘﻪ را اﺟﺮا ﻣﻲ ﻛﻨﺪ. اﮔﺮ ﺣﺲ ﻛﺮدﻳﺪ ﻛﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ درون ﻳﻚ ﺣﻠﻘﻪ ﺑﻲ ﻧﻬﺎﻳﺖ ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ ،ﺑﺎﻳـﺴﺘﻲ آن را ﺑﺒﻨﺪﻳـﺪ .اﮔـﺮ ﺑﺮﻧﺎﻣـﻪ را در ﻣﺤـﻴﻂ وﻳـﮋوال اﺳﺘﻮدﻳﻮ اﺟﺮا ﻛﺮده اﻳﺪ ،ﺑﻪ ﻣﺤﻴﻂ وﻳﮋوال اﺳـﺘﻮدﻳﻮ ﺑﺮﮔﺮدﻳـﺪ و از ﻣﻨـﻮي Debugﮔﺰﻳﻨـﻪ Stop Debuggingرا اﻧﺘﺨـﺎب ﻛﻨﻴﺪ .اﻳﻦ ﮔﺰﻳﻨﻪ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ را ﻓﻮرا ﻣﺘﻮﻗﻒ ﻣﻲ ﻛﻨﺪ .اﮔﺮ ﺑﺮﻧﺎﻣﻪ ﻛﺎﻣﭙﺎﻳﻞ ﺷﺪه را در ﻣﺤﻴﻂ وﻳﻨﺪوز اﺟﺮا ﻛـﺮده اﻳـﺪ و درون ﻳـﻚ ﺣﻠﻘـﻪ ﺑﻴﻨﻬﺎﻳﺖ ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ ،ﺑﺮاي ﺑﺴﺘﻦ آن ﺑﺎﻳـﺪ از Task Managerاﺳـﺘﻔﺎده ﻛﻨﻴـﺪ .ﻛﻠﻴـﺪﻫﺎي Ctrl + Alt + Delرا ﻓﺸﺎر دﻫﻴﺪ ،ﺑﺮﻧﺎﻣﻪ Task Managerﺑﺎز ﺧﻮاﻫﺪ ﺷﺪ .ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در ﺣﻠﻘﻪ ي ﺑﻴﻨﻬﺎﻳﺖ ﻗﺮار دارد ﺑﻪ ﻋﻨﻮان Not Respondingﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﺑﺮﻧﺎﻣﻪ را اﻧﺘﺨﺎب ﻛﻨﻴﺪ و ﺑﺮ روي End Taskﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﭘﻨﺠﺮه اي ﺑﺎز ﺧﻮاﻫﺪ ﺷﺪ و ﻣﻲ ﮔﻮﻳﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻣﻮرد ﻧﻈﺮ ﭘﺎﺳﺨﻲ ﻧﻤﻲ دﻫﺪ ،آﻳﺎ ﻣﻲ ﺧﻮاﻫﻴﺪ آن را ﺑﻪ اﺟﺒﺎر ﺑﺒﻨﺪﻳﺪ .در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﺑـﺮ روي End Task ﻛﻠﻴﻚ ﻛﻨﻴﺪ. در ﺑﻌﻀﻲ از ﻣﻮاﻗﻊ ﻣﻤﻜﻦ اﺳﺖ ﺣﻠﻘﻪ آﻧﻘﺪر ﺣﺎﻓﻈﻪ ﺳﻴﺴﺘﻢ را ﻣﺼﺮف ﻛﻨﺪ ﻛﻪ ﻧﺘﻮاﻧﻴﺪ ﭘﻨﺠﺮه Task Managerرا ﺑﺎز ﻛﻨﻴﺪ و ﻳـﺎ ﺑﻪ ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮﮔﺮدﻳﺪ .در اﻳﻦ ﻣﻮاﻗﻊ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﻘﺪاري ﺻﺒﺮ ﻛﻨﻴﺪ و ﻣﺠﺪدا اﻳﻦ روﺷﻬﺎ را اﻣﺘﺤﺎن ﻛﻨﻴﺪ و ﻳﺎ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺧﻮد را ﻣﺠﺪدا راه اﻧﺪازي ﻛﻨﻴﺪ. ﻫﺮ ﺑﺎر ﻛﻪ در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻣﻲ ﻛﻨﻴﺪ ،اﺑﺘﺪا ﺑﺮﻧﺎﻣﻪ ﺗﻮﺳﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ در دﻳﺴﻚ ذﺧﻴﺮه ﻣﻲ ﺷﻮد و ﺳﭙﺲ اﺟﺮا ﻣﻲ ﺷﻮد ،ﺗﺎ اﮔﺮ ﺑﻪ ﻋﻠﺘﻲ ﻣﺠﺒﻮر ﺑﻪ راه اﻧﺪازي ﻣﺠﺪد ﻛﺎﻣﭙﻴﻮﺗﺮ ﺷﺪﻳﺪ ﻛﺪﻫﺎي ﺧﻮد را از دﺳﺖ ﻧﺪﻫﻴﺪ.
ﻧﺘﻴﺠﻪ: در اﻳﻦ ﻓﺼﻞ روﺷﻬﺎي ﮔﻮﻧﺎﮔﻮﻧﻲ ﻛﻪ ﻣﻴﺘﻮان ﺑﻪ وﺳﻴﻠﻪ آﻧﻬﺎ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﺼﻤﻴﻢ ﮔﻴﺮي ﻛﺮده و ﻳﺎ ﻗﺴﻤﺘﻲ از ﻛﺪ را ﭼﻨﺪ ﺑﺎر اﺟﺮا ﻛـﺮد را ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ .اﺑﺘﺪا ﻋﻤﻠﮕﺮ ﻫﺎﻳﻲ را ﻛﻪ ﻣﻴﺘﻮاﻧﻴﻢ در دﺳﺘﻮر ifاﺳﺘﻔﺎده ﻛﻨﻴﻢ ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ ،ﺳﭙﺲ دﻳﺪﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻴﺘﻮان ﺑﺎ اﺳـﺘﻔﺎده از ﻋﻤﻠﮕﺮ || ) (ORو ﻳﺎ && ) (ANDﻣﻴﺘﻮان ﭼﻨﺪ ﻋﻤﻠﮕﺮ را ﺗﺮﻛﻴﺐ ﻛﺮد .ﻫﻤﭽﻨﻴﻦ ﭼﮕﻮﻧﮕﻲ ﻣﻘﺎﻳﺴﻪ رﺷﺘﻪ ﻫﺎ ﺑﺪون در ﻧﻈـﺮ ﮔـﺮﻓﺘﻦ ﻧﻮع ﺣﺮوف را ﻧﻴﺰ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ. ﺳﭙﺲ ﺑﺎ دﺳﺘﻮر switchآﺷﻨﺎ ﺷﺪﻳﻢ و دﻳﺪﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻳﻚ ﺣﺎﻟﺖ ﺧﺎص را از ﺑﻴﻦ ﺗﻌﺪاد زﻳﺎدي ﺣﺎﻟﺖ اﻧﺘﺨﺎب ﻛﺮد .ﺑـﺎ ﻣﻔﻬﻮم ﻛﻠﻲ ﺣﻠﻘﻪ ﻫﺎ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ آﺷﻨﺎ ﺷﺪﻳﻢ و ﺳﻪ ﺣﻠﻘﻪ do ،forو whileرا ﺑﺮرﺳﻲ ﻛـﺮدﻳﻢ .ﺣﻠﻘـﻪ ﻫـﺎي forﺑـﺮاي ﺗﻜﺮار ﻳﻚ ﺳﺮي از دﺳﺘﻮرات ﺑﻪ ﺗﻌﺪاد ﻣﻌﻴﻦ ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ و ﺣﻠﻘﻪ foreachﻧﻴﺰ ﻛﻪ از اﻳﻦ ﺣﻠﻘﻪ ﻣﺸﺘﻖ ﻣﻲ ﺷﻮد ،ﺑﺮاي ﺣﺮﻛـﺖ در ﺑﻴﻦ ﻋﻨﺎﺻﺮ ﻳﻚ ﻣﺠﻤﻮﻋﻪ ﺑﺪون داﻧﺴﺘﻦ ﺗﻌﺪاد آن اﺳﺘﻔﺎده ﻣﻲ ﺷﻮﻧﺪ .ﺣﻠﻘﻪ ﻫﺎي whileﺗﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﺷﺮط ﺧـﺎص ﺑﺮﻗـﺮار اﺳﺖ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ .ﺣﻠﻘﻪ ﻫﺎي doﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﺣﻠﻘﻪ ﻫﺎي whileﻫﺴﺘﻨﺪ ﺑﺎ اﻳﻦ ﺗﻔﺎوت ﻛﻪ ﺷﺮط ﺣﻠﻘﻪ ﻫﺎي whileدر اﺑﺘﺪاي ﺣﻠﻘﻪ ﺑﺮرﺳﻲ ﻣﻲ ﺷﻮد وﻟﻲ ﺷﺮط ﺣﻠﻘﻪ ﻫﺎي doدر اﻧﺘﻬﺎي آن. ﺑﻌﺪ از ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﻧﺤﻮه اﺳﺘﻔﺎده از ﻣﻮارد زﻳﺮ را در ﺑﺮﻧﺎﻣﻪ ﺑﺪاﻧﻴﺪ:
١٥٩
دﺳﺘﻮرات else if ،ifو elseﺑﺮاي ﺗﺴﺖ ﺣﺎﻟﺘﻬﺎي ﻣﺨﺘﻠﻒ. دﺳﺘﻮرات ifﺗﻮدرﺗﻮ. ﻋﻤﻠﮕﺮ ﻫﺎي ﻣﻘﺎﻳﺴﻪ اي و ﺗﺎﺑﻊ .Sring.Compare دﺳﺘﻮر switchﺑﺮاي اﻧﺘﺨﺎب ﻳﻚ ﺣﺎﻟﺖ ﺑﻴﻦ ﺣﺎﻟﺘﻬﺎي ﻣﻮﺟﻮد. ﺣﻠﻘﻪ ﻫﺎي forو foreach ﺣﻠﻘﻪ ﻫﺎي do ﺣﻠﻘﻪ ﻫﺎي while
ﺗﻤﺮﻳﻦ:
ﺗﻤﺮﻳﻦ :1 ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﺤﺖ وﻳﻨﺪوز ﺑﺎ ﻳﻚ TextBoxو ﻳﻚ Buttonاﻳﺠﺎد ﻛﻨﻴﺪ .در روﻳﺪاد Clickﻣﺮﺑﻮط ﺑﻪ ،Buttonﻋﺪد داﺧﻞ TextBoxرا ﺑﺪﺳﺖ آورﻳﺪ و ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر switchاﮔﺮ ﻋﺪد ﻳﻜﻲ از اﻋﺪاد ﻳﻚ ﺗﺎ ﭘﻨﺞ ﺑﻮد آن را ﺑﻪ وﺳـﻴﻠﻪ ﻳـﻚ ﻛﺎدر ﭘﻴﻐﺎم در ﺧﺮوﺟﻲ ﻧﻤﺎﻳﺶ دﻫﻴﺪ .در ﺻﻮرﺗﻲ ﻛﻪ ﻋﺪد وارد ﺷﺪه در TextBoxدر ﺑﺎزه ﻳﻚ ﺗﺎ ﭘﻨﺞ ﻧﺒﻮد ،ﭘﻴﻐﺎم ﻣﻨﺎﺳﺒﻲ را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ دﻫﻴﺪ.
ﺗﻤﺮﻳﻦ :2 ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﺤﺖ وﻳﻨﺪوز ﻛﻪ ﺷﺎﻣﻞ ﻳﻚ ﻛﻨﺘﺮل ListBoxو ﻳﻚ ﻛﻨﺘﺮل Buttonﺑﺎﺷﺪ اﻳﺠـﺎد ﻛﻨﻴـﺪ .در روﻳـﺪاد Click ﻣﺮﺑﻮط ﺑﻪ ،Buttonﻳﻚ ﺣﻠﻘﻪ forاﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ اﻋﺪاد 1ﺗﺎ 10را در ListBoxﻗﺮار دﻫﺪ .ﺳـﭙﺲ ﺣﻠﻘـﻪ دﻳﮕـﺮي اﻳﺠـﺎد ﻛﻨﻴﺪ ﻛﻪ اﻋﺪاد 10ﺗﺎ 1را در ListBoxﻧﻤﺎﻳﺶ دﻫﺪ.
١٦٠
ﻓﺼﻞ ﭘﻨﺠﻢ :ﻛﺎرﻛﺮدن ﺑﺎ ﺳﺎﺧﺘﺎرﻫﺎي داده اي در ﻓﺼﻠﻬﺎي ﻗﺒﻠﻲ ﻧﺤﻮه اﺳﺘﻔﺎده از ﻣﺘﻐﻴﺮﻫﺎي ﺳﺎده اي ﻣﺎﻧﻨﺪ ﻣﺘﻐﻴﺮﻫﺎي integerﺑﺮاي اﻋـﺪاد ﺻـﺤﻴﺢ و ﻳـﺎ stringﺑـﺮاي رﺷﺘﻪ ﻫﺎ را ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ .ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ اﻳﻦ ﻧﻮع ﻫﺎي داده اي ﺑﺴﻴﺎر ﭘﺮ ﻛﺎرﺑﺮد ﻫﺴﺘﻨﺪ ،اﻣﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﭘﻴﭽﻴﺪه ﺗـﺮ ﻧﻴـﺎز دارﻧـﺪ ﻛـﻪ ﺑـﺎ ﺳﺎﺧﺘﺎرﻫﺎي داده اي ﻛﺎر ﻛﻨﻨﺪ .ﺳﺎﺧﺘﺎرﻫﺎي داده اي ﺑﻪ ﻳﻚ ﮔﺮوه از اﻃﻼﻋﺎت ﻣﺮﺗﺒﻂ ﺑﻪ ﻫﻢ ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد ﻛﻪ در ﻳﻚ واﺣـﺪ ﻣﺠـﺰا ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ.در اﻳﻦ ﻓﺼﻞ ﺑﺎ اﻧﻮاع ﺳﺎﺧﺘﺎرﻫﺎي داده اي ﻣﻮﺟﻮد در C#و ﻧﺤﻮه اﺳﺘﻔﺎده از آﻧﻬﺎ ﺑﺮاي ﻧﮕﻬﺪاري ﻣﺠﻤﻮﻋﻪ ﻫـﺎي داده اي ﭘﻴﭽﻴﺪه آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. در اﻳﻦ ﻓﺼﻞ ﻣﻄﺎﻟﺐ زﻳﺮ را ﺧﻮاﻫﻴﺪ آﻣﻮﺧﺖ:
آراﻳﻪ ﻫﺎ ﺷﻤﺎرﻧﺪه ﻫﺎ ﺛﺎﺑﺖ ﻫﺎ ﺳﺎﺧﺘﺎرﻫﺎ
ﻣﻔﻬﻮم آراﻳﻪ: ﻳﻜﻲ از ﻋﻤﻮﻣﻲ ﺗﺮﻳﻦ ﻧﻴﺎزﻫﺎ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻗﺎﺑﻠﻴﺖ ﻧﮕﻬﺪاري ﻟﻴﺴﺘﻲ از اﻃﻼﻋﺎت ﻣﺸﺎﺑﻪ و ﻳﺎ ﻣﺮﺗﺒﻂ ﺑـﻪ ﻫـﻢ اﺳـﺖ .ﺑـﺮاي اﻳـﻦ ﻣـﻮرد ﺑﺎﻳﺴﺘﻲ از آراﻳﻪ ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .آراﻳﻪ ﻫﺎ ،ﻟﻴﺴﺘﻲ از ﻣﺘﻐﻴﺮ ﻫﺎ ﻣﻲ ﺑﺎﺷﻨﺪ ﻛﻪ ﻫﻤﻪ از ﻳﻚ ﻧﻮع ﻫﺴﺘﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻤﻜﻦ اﺳـﺖ ﺑﺨﻮاﻫﻴـﺪ ﺳﻦ ﺗﻤﺎﻣﻲ دوﺳﺘﺎن ﺧﻮد را در ﻳﻚ آراﻳﻪ از اﻋﺪاد ﺻﺤﻴﺢ و ﻳﺎ ﻧﺎم ﺗﻤﺎﻣﻲ آﻧﻬﺎ را در ﻳﻚ آراﻳﻪ از رﺷﺘﻪ ﻫﺎ ﻗﺮار دﻫﻴﺪ. در اﻳﻦ ﺑﺨﺶ ﺑﺎ ﻧﺤﻮه اﻳﺠﺎد ،ﭘﺮ ﻛﺮدن و اﺳﺘﻔﺎده از آراﻳﻪ ﻫﺎ در ﺑﺮﻧﺎﻣﻪ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ.
ﺗﻌﺮﻳﻒ و اﺳﺘﻔﺎده از آراﻳﻪ ﻫﺎ: ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻳﻚ آراﻳﻪ ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﺪ ،در ﺣﻘﻴﻘﺖ ﻣﺘﻐﻴﺮي اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﺑﻴﺶ از ﻳﻚ ﻋﻨﺼﺮ را ﺑﺘﻮاﻧﺪ در ﺧﻮد ﻧﮕﻬـﺪاري ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻳﻚ ﻣﺘﻐﻴﺮ رﺷﺘﻪ اي را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ﻓﻘﻂ ﻳﻚ رﺷﺘﻪ را ﻣﻴﺘﻮاﻧﻴﺪ در آن ﻧﮕﻬﺪاري ﻛﻨﻴﺪ: ;string strName اﻣﺎ آراﻳﻪ ﻫﺎ ﺑﺎﻋﺚ اﻳﺠﺎد ﻧﻮﻋﻲ ﺣﺎﻟﺖ اﻓﺰاﻳﺸﻲ در ﻣﺘﻐﻴﺮ ﻣﻲ ﺷﻮﻧﺪ ،ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﻴﺶ از ﻳﻚ ﻣﻘﺪار را ﻣﻲ ﺗﻮاﻧﻴﺪ در ﻳـﻚ ﻣﺘﻐﻴـﺮ ذﺧﻴـﺮه ﻛﻨﻴﺪ .اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻳﻚ ﻣﺘﻐﻴﺮ را ﺑﻪ ﺻﻮرت آراﻳﻪ ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ﺑﺎﻳﺪ در ﻣﻘﺎﺑﻞ ﻧﻮع ﻣﺘﻐﻴﺮ از ﻋﻼﻣﺖ ][ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻛﺪ زﻳـﺮ ﻣﺘﻐﻴﺮي اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ ﻛﻪ ﺑﺘﻮاﻧﺪ 10ﻋﻨﺼﺮ را در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ: ;]string[] strName = new string[10
١٦١
ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ آراﻳﻪ را اﻳﺠﺎد ﻛﺮدﻳﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺗﻚ ﺗﻚ ﻋﻨﺎﺻﺮ آن ﺑﺎ اﺳﺘﻔﺎده از اﻧﺪﻳﺲ آن ﻋﻨـﺼﺮ دﺳﺘﺮﺳـﻲ ﭘﻴـﺪا ﻛﻨﻴـﺪ .اﻧـﺪﻳﺲ ﻋﻨﺎﺻﺮ ﻳﻚ آراﻳﻪ ﻫﻤﻮاره ﻋﺪدي ﺑﻴﻦ ﺻﻔﺮ و ﺷﻤﺎره ي آﺧﺮﻳﻦ ﻋﻨﺼﺮ آراﻳﻪ اﺳﺖ .ﺷﻤﺎره ي آﺧﺮﻳﻦ ﻋﻨﺼﺮ ﻫﺮ آراﻳﻪ ﻫﻢ ﺑﺮاﺑﺮ ﺑﺎ ﻳﻚ واﺣﺪ ﻛﻤﺘﺮ از ﻃﻮل آراﻳﻪ اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ اﻧﺪﻳﺲ ﻫﺮ آراﻳﻪ ﻋﺪدي ﺑﻴﻦ ﺻﻔﺮ ﺗﺎ ﻳﻚ واﺣﺪ ﻛﻤﺘﺮ از آﺧﺮﻳﻦ ﻋﻨﺼﺮ آراﻳﻪ اﺳﺖ. ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻣﻘﺪار ﻋﻨﺼﺮ ﺳﻮم آراﻳﻪ ﻗﺒﻠﻲ را ﺑﺮاﺑﺮ ﺑﺎ رﺷﺘﻪ ي " "Katieﻗﺮار دﻫﻴﺪ ﺑﺎﻳﺪ از ﻛﺪ زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ: ;"strName[2] = "Katie ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻣﻘﺪار ﻳﻚ ﻋﻨﺼﺮ از آراﻳﻪ ﻫﻢ ﻣﻴﺘﻮاﻧﻴﺪ از ﻫﻤﻴﻦ روش اﺳﺘﻔﺎده ﻛﻨﻴﺪ: ;)]MessageBox.Show(strName[2 ﻧﻜﺘﻪ ي ﻣﻬﻢ در اﻳﻨﺠﺎ اﻳﻦ اﺳﺖ ﻛﻪ اﮔﺮ ﻳﻜﻲ از ﻋﻨﺎﺻﺮ آراﻳﻪ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ ،ﻣﻘﺪار ﺑﻘﻴﻪ ﻋﻨﺎﺻﺮ ﺗﻐﻴﺮي ﻧﺨﻮاﻫﺪ ﻛﺮد .ﺑﺮاي ﻣﺜـﺎل اﮔـﺮ ﻛـﺪ زﻳﺮ را در ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ: ;"strName[3] = "Betty ﻣﻘﺪار ] strName[2ﻫﻤﭽﻨﺎن ﺑﺮاﺑﺮ ﺑﺎ " "Katieﺧﻮاﻫﺪ ﻣﺎﻧﺪ. اﺣﺘﻤﺎﻻ ﺑﻬﺘﺮﻳﻦ روش ﺑﺮاي ﻓﻬﻤﻴﺪن اﻳﻦ ﻛﻪ آراﻳﻪ ﻫﺎ ﭼﻴﺴﺘﻨﺪ و ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ اي ﺑﺎ اﺳﺘﻔﺎده از آﻧﻬﺎ اﺳﺖ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺗﻌﺮﻳﻒ و اﺳﺘﻔﺎده از ﻳﻚ آراﻳﻪ ﺳﺎده (1 (2 (3 (4
ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005روي ﻣﻨﻮي Fileﻛﻠﻴﻚ ﻛـﺮده و ﺳـﭙﺲ New Projectرا اﻧﺘﺨـﺎب ﻛﻨﻴﺪ .در ﭘﻨﺠﺮه New Projectﻳﻚ ﭘﺮوژه وﻳﻨﺪوزي ﺑﻪ ﻧﺎم Array Demoاﻳﺠﺎد ﻛﻨﻴﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ Form1ﻧﻤﺎﻳﺶ داده ﺷﺪ ،ﻳﻚ ﻛﻨﺘﺮل ListBoxﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺧﺎﺻﻴﺖ Name اﻳﻦ ﻛﻨﺘﺮل را ﺑﺮاﺑﺮ ﺑﺎ lstFriendsو ﺧﺎﺻﻴﺖ IntegralHeightآن را ﺑﺮاﺑﺮ ﺑﺎ Falseﻗﺮار دﻫﻴﺪ. اﻛﻨﻮن ﻳﻚ ﻛﻨﺘﺮل Buttonﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮده ،ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑﺎ btnArrayElementsو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Array Elementsﻗﺮار دﻫﻴﺪ .ﻓﺮم ﺷﻤﺎ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 1-5ﺷﺪه ﺑﺎﺷﺪ. روي ﻛﻨﺘﺮل Buttonدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن وارد ﻛﻨﻴﺪ: private void btnArrayElements_Click(object sender, )EventArgs e { // Declare an array ;]string[] strFriends = new string[5 array ;""Robbin ;""Bryan ;""Stephanie ;""Sydney
// Populate the = ]strFriends[0 = ]strFriends[1 = ]strFriends[2 = ]strFriends[3
١٦٢
;"strFriends[4] = "Katie // Add the first array item to the list ;)]lstFriends.Items.Add(strFriends[0 }
ﺷﻜﻞ 1-5 (5ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ ي Array Elementsﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛﻨﺘﺮل ListBoxروي ﻓـﺮم ﺑـﺎ ﻧـﺎم Robbinﭘﺮ ﻣﻲ ﺷﻮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻳﻚ آراﻳﻪ را ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ،اﺑﺘﺪا ﺑﺎﻳﺪ ﻧﻮع داده اي و اﻧﺪازه آن را ﻣﺸﺨﺺ ﻛﻨﻴﺪ .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺧـﻮاﻫﻴﻢ ﻳـﻚ آراﻳﻪ از ﻧﻮع رﺷﺘﻪ اي و ﺑﻪ ﻃﻮل 5ﻋﻨﺼﺮ اﻳﺠﺎد ﻛﻨﻴﻢ .ﭘﺲ از ﻛﺪ زﻳﺮ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ: // Declare an array ;]string[] strFriends = new string[5 ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ آراﻳﻪ اي ﺑﻪ ﻃﻮل 5اﻳﺠﺎد ﻛﺮده اﻳﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﻴﺘﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ آراﻳﻪ اي دارﻳـﻢ ﻛـﻪ ﺷـﺎﻣﻞ 5ﻋﻨـﺼﺮ اﺳﺖ. ﺑﻌﺪ از اﻳﺠﺎد آراﻳﻪ ،ﻳﻚ آراﻳﻪ ﺑﺎ ﭘﻨﺞ ﻋﻨﺼﺮ ﺧﻮاﻫﻴﺪ داﺷﺖ ﻛﻪ ﻣﻴﺘﻮاﻧﻴﺪ ﺑﻪ ﻫﺮ ﻳﻚ از ﻋﻨﺎﺻﺮ آن ﺑﺎ اﺳـﺘﻔﺎده از اﻧـﺪﻳﺲ آن دﺳﺘﺮﺳـﻲ ﭘﻴـﺪا ﻛﻨﻴﺪ.ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻳﻚ ﻋﻨﺼﺮ ﺧﺎص ﺑﺎﻳﺪ اﻧﺪﻳﺲ آن ﻋﻨﺼﺮ را در داﺧﻞ ﻛﺮوﺷﻪ ﺑﻌﺪ از ﻧﺎم آراﻳﻪ ﺑﻴﺎورﻳﺪ .اﻧﺪﻳﺲ ﻫـﺎ از ﺷـﻤﺎره ﺻـﻔﺮ ﺷﺮوع ﻣﻲ ﺷﻮﻧﺪ و ﺗﺎ ﻳﻚ واﺣﺪ ﻛﻤﺘﺮ از ﻃﻮل آراﻳﻪ اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻋﻨﺼﺮ اول آراﻳﻪ داراي اﻧﺪﻳﺲ ﺻـﻔﺮ ،ﻋﻨـﺼﺮ دوم آراﻳـﻪ
١٦٣
داراي اﻧﺪﻳﺲ ﻳﻚ و ...اﺳﺖ .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ اﺳﺖ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ آراﻳﻪ را ﺑﻪ ﻃﻮل 5ﺗﻌﺮﻳﻒ ﻛﺮده ،وﻟﻲ ﺑﺮاي ﭘﺮ ﻛﺮدن آن از اﻋﺪاد 0ﺗﺎ 4 اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ. array ;""Robbin ;""Bryan ;""Stephanie ;""Sydney ;""Katie
// Populate the = ]strFriends[0 = ]strFriends[1 = ]strFriends[2 = ]strFriends[3 = ]strFriends[4
ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﺑﺮاي ﻣﻘﺪار دﻫﻲ ﺑﻪ ﻳﻚ ﻋﻨﺼﺮ ﺧﺎص ﺑﺎﻳﺪ از اﻧﺪﻳﺲ آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻣﻘﺪار آن ﻋﻨﺼﺮ از آراﻳﻪ ﻧﻴـﺰ ﻣـﻲ ﺗﻮاﻧﻴﺪ از اﻧﺪﻳﺲ آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ،ﻣﻘﺪار ﻣﻮﺟﻮد در ﺧﺎﻧﻪ ﺻﻔﺮم آراﻳﻪ ﻛﻪ ﺑﺮاﺑﺮ ﺑـﺎ اوﻟـﻴﻦ ﻣﻘـﺪار آراﻳـﻪ )"("Robbin اﺳﺖ را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﺪ: // Add the first array item to the list ;)]lstFriends.Items.Add(strFriends[0 ﻋﻠﺖ اﻳﻦ ﻛﻪ اﻧﺪﻳﺲ ﻋﻨﺎﺻﺮ ﻣﻮﺟﻮد در آراﻳﻪ و ﻃﻮل آن آراﻳﻪ ﻣﻘﺪاري ﮔﻴﺞ ﻛﻨﻨﺪه ﺑﻪ ﻧﻈﺮ ﻣﻲ رﺳﺪ اﻳﻦ اﺳﺖ ﻛﻪ اﻧﺪﻳﺴﻬﺎ در ﻳﻚ آراﻳـﻪ از ﺻﻔﺮ ﺷﺮوع ﻣﻲ ﺷﻮﻧﺪ ،اﻣﺎ ﻣﻌﻤﻮﻻ اﻧﺴﺎﻧﻬﺎ اوﻟﻴﻦ ﻋﻨﺼﺮ ﻫﺮ ﻣﺠﻤﻮﻋﻪ اي را ﺑﺎ ﻳﻚ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻨﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴـﺪ ﻣﻘـﺪاري را در آراﻳﻪ ﻗﺮار دﻫﻴﺪ و ﻳﺎ ﻣﻘﺪار ﻳﻚ ﻋﻨﺼﺮ از آراﻳﻪ را ﺑﺪﺳﺖ آورﻳﺪ ،ﺑﺎﻳﺪ ﻳﻚ واﺣﺪ از ﻣﻜﺎن ﻋﻨﺼﺮ ﻣﻮرد ﻧﻈﺮﺗﺎن ﻛﻢ ﻛﻨﻴﺪ ﺗﺎ اﻧـﺪﻳﺲ آن را ﺑﺪﺳﺖ آورﻳﺪ .ﺑﺮاي ﻣﺜﺎل ﻋﻨﺼﺮ ﭘﻨﺠﻢ در آراﻳﻪ ﺑﺮاﺑﺮ ﺑﺎ اﻧﺪﻳﺲ 4و اوﻟﻴﻦ ﻋﻨﺼﺮ در آراﻳﻪ ﺑﺮاﺑﺮ ﺑﺎ اﻧﺪﻳﺲ 0اﺳﺖ. ﻧﻜﺘﻪ :ﺳﻮاﻟﻲ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ در اﻳﻦ ﻗﺴﻤﺖ اﻳﺠﺎد ﺷﻮد اﻳﻦ اﺳﺖ ﻛﻪ ﭼﺮا اﻧﺪﻳﺴﻬﺎ از ﺻﻔﺮ ﺷﺮوع ﻣﻴﺸﻮﻧﺪ؟ ﺑـﻪ ﺧـﺎﻃﺮ دارﻳـﺪ ﻛـﻪ ﺑـﺮاي ﻛﺎﻣﭙﻴﻮﺗﺮ ،ﻳﻚ ﻣﺘﻐﻴﺮ آدرس ﻣﻜﺎﻧﻲ از ﺣﺎﻓﻈﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ اﺳﺖ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻳﻚ ﻋﻨﺼﺮ از آراﻳﻪ اﻧـﺪﻳﺲ آن را ﻣـﺸﺨﺺ ﻣﻲ ﻛﻨﻴﺪ ،وﻳﮋوال C#اﻳﻦ اﻧﺪﻳﺲ را در اﻧﺪازه ي ﻳﻜﻲ از ﻋﻨﺎﺻﺮ آراﻳﻪ ﺿﺮب ﻣﻲ ﻛﻨﺪ 1و ﺣﺎﺻﻞ را ﺑﺎ آدرس آراﻳﻪ ﺟﻤﻊ ﻣﻲ ﻛﻨـﺪ ﺗـﺎ ﺑـﻪ آدرس ﻋﻨﺼﺮ ﻣﺸﺨﺺ ﺷﺪه ﺑﺮﺳﺪ .آدرس ﺷﺮوع ﻳﻚ آراﻳﻪ ﻫﻢ در ﺣﻘﻴﻘﺖ آدرس اوﻟﻴﻦ ﻋﻨﺼﺮ آن آراﻳﻪ اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ اوﻟﻴﻦ ﻋﻨﺼﺮ آراﻳﻪ ﺑﻪ اﻧﺪازه ﺻﻔﺮ ﺿﺮﺑﺪر اﻧﺪازه ﻋﻨﺼﺮ ،از ﻧﻘﻄﻪ ﺷﺮوع آراﻳﻪ ﻓﺎﺻﻠﻪ دارد ،دوﻣﻴﻦ ﻋﻨﺼﺮ ﺑﻪ اﻧﺪازه ﻳﻚ ﺿـﺮﺑﺪر اﻧـﺪازه ﻋﻨـﺼﺮ از ﺷـﺮوع آراﻳـﻪ ﻓﺎﺻﻠﻪ دارد و ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴﺐ اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ.
اﺳﺘﻔﺎده از :foreach ﻳﻜﻲ از ﻋﻤﻮﻣﻲ ﺗﺮﻳﻦ روﺷﻬﺎي اﺳﺘﻔﺎده از آراﻳﻪ ﻫﺎ ،ﺑﻪ وﺳﻴﻠﻪ ﺣﻠﻘﻪ ﻫﺎي foreachاﺳﺖ.اﻳﻦ ﻧﻮع ﺣﻠﻘﻪ ﻫﺎ در ﻓﺼﻞ ،4ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺎ آراﻳﻪ رﺷﺘﻪ اي ﺑﺮﮔﺮداﻧﺪه ﺷﺪه ﺗﻮﺳﻂ ﺗﺎﺑﻊ GetDirectoriesﻛﺎر ﻣﻲ ﻛﺮدﻳﺪ ،ﻣﻌﺮﻓﻲ ﺷﺪﻧﺪ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴـﺪ ﺑﻌـﺪ، ﻣﻼﺣﻈﻪ ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ از اﻳﻦ ﺣﻠﻘﻪ ﻫﺎ در آراﻳﻪ ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﻢ.
1اﻳﻦ ﻣﻮرد ﻛﻪ اﻧﺪازه ﻛﺪام ﻋﻨﺼﺮ را در ﻧﻈﺮ ﺑﮕﻴﺮد اﻫﻤﻴﺘﻲ ﻧﺪارد ،زﻳﺮا ﻫﻤﻪ ﻋﻨﺎﺻﺮ ﻳﻚ آراﻳﻪ از ﻳﻚ ﻧﻮع ﻫﺴﺘﻨﺪ و اﻧﺪازه آﻧﻬﺎ ﺑﺎ ﻫﻢ ﺑﺮاﺑﺮ اﺳﺖ .ﺑﺮاي ﻣﺜﺎل اﻧـﺪازه ﻫـﺮ ﻳﻚ از ﻋﻨﺎﺻﺮ ﻳﻚ آراﻳﻪ از ﻧﻮع ،intﺑﺮاﺑﺮ ﺑﺎ 4ﺑﺎﻳﺖ اﺳﺖ.
١٦٤
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﺣﻠﻘﻪ ﻫﺎي foreachﺑﺎ آراﻳﻪ ﻫﺎ (1اﮔﺮ ﺑﺮﻧﺎﻣﻪ ي Arrays Demoدر ﺣﺎل اﺟﺮا اﺳﺖ آن را ﺑﺒﻨﺪﻳﺪ .ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ را ﺑﺮاي Form1ﺑﺎز ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در ﺑﺎﻻﺗﺮﻳﻦ ﻗﺴﻤﺖ در ﺑﺪﻧﻪ ﻛﻼس ﺧﻮد وارد ﻛﻨﻴﺪ: public partial class Form1 : Form { // Declare a form level array ;]private string[] strFriends = new string[5 (2ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ Form1ﺑﺮﮔﺮدﻳﺪ و ﺑﺮ روي ﻗﺴﻤﺖ ﺧﺎﻟﻲ ﻓﺮم دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳـﺪاد Loadﻓﺮم ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﻣﻲ ﺷﻮد .ﺣﺎل ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: )private void Form1_Load(object sender, EventArgs e { // Populate the array ;"strFriends[0] = "Robbin ;"strFriends[1] = "Bryan ;"strFriends[2] = "Stephanie ;"strFriends[3] = "Sydney ;"strFriends[4] = "Katie } (3ﻣﺠﺪدا ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ و ﻳﻚ ﻛﻨﺘﺮل Buttonﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺧﺎﺻﻴﺖ Nameاﻳﻦ ﻛﻨﺘﺮل را ﺑﺮاﺑﺮ ﺑﺎ btnEnumerateArrayو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Enumerate Arrayﻗﺮار دﻫﻴﺪ. (4روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن وارد ﻛﻨﻴﺪ: private void btnEnumerateArray_Click(object sender, )EventArgs e { // Enumerate the array )foreach (string strName in strFriends { // Add the array item to the list ;)lstFriends.Items.Add(strName } } (5ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺑﺮ روي دﻛﻤـﻪ ي Enumerate Arrayﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .ﻧﺘﻴﺠـﻪ اي را ﻣـﺸﺎﺑﻪ ﺷـﻜﻞ 2-5 ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
١٦٥
ﺷﻜﻞ 2-5
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اﻳﻦ ﺗﻤﺮﻳﻦ را ﺑﺎ ﺗﻌﺮﻳﻒ ﻳﻚ ﻣﺘﻐﻴﺮ ﻛﻪ در ﺗﻤﺎم ﻓﺮم ﻗﺎﺑﻞ اﺳﺘﻔﺎده اﺳﺖ ﺷﺮوع ﻣﻲ ﻛﻨﻴﻢ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ اﻳﻦ آراﻳﻪ ﺑـﺮاي ﺗﻤـﺎم ﻣﺘـﺪﻫﺎي ﻣﻮﺟﻮد در ﻛﻼس Form1ﻗﺎﺑﻞ اﺳﺘﻔﺎده اﺳﺖ .ﻫﺮ ﮔﺎه ﻣﺘﻐﻴﺮي در ﺧﺎرج از ﻣﺘﺪﻫﺎ درون ﻳﻚ ﻛﻼس ﺗﻌﺮﻳﻒ ﺷﻮد ،در ﺗﻤﺎﻣﻲ ﻣﺘـﺪﻫﺎي آن ﻛﻼس ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﺧﻮاﻫﺪ ﺑﻮد. // Declare a form level array ;]private string[] strFriends = new string[5 ﺳﭙﺲ ﻣﺘﺪي را ﺑﺮاي روﻳﺪاد Loadﻣﺮﺑﻮط ﺑﻪ Form1اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﭘﺮ ﻛﺮدن آراﻳﻪ را در آن ﻗﺮار ﻣﻲ دﻫﻴﺪ .اﻳﻦ ﻣﺘﺪ ﻫﻨﮕﺎﻣﻲ اﺟﺮا ﻣﻲ ﺷﻮد ﻛﻪ اﻳﻦ ﻓﺮم از ﺑﺮﻧﺎﻣﻪ ﺑﺨﻮاﻫﺪ در ﺣﺎﻓﻈﻪ ﺑﺎر ﮔﺬاري ﺷﺪه و ﻧﻤﺎﻳﺶ داده ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻄﻤﺌﻦ ﻣﻲ ﺷﻮﻳﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﺮم ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد آراﻳﻪ ﺷﻤﺎ ﭘﺮ ﺷﺪه اﺳﺖ. )private void Form1_Load(object sender, EventArgs e { // Populate the array ;"strFriends[0] = "Robbin ;"strFriends[1] = "Bryan ;"strFriends[2] = "Stephanie ;"strFriends[3] = "Sydney ;"strFriends[4] = "Katie }
١٦٦
در ﻓﺼﻞ ﭼﻬﺎر ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻳﻚ ﺣﻠﻘﻪ foreachدر ﺑﻴﻦ ﻋﻨﺎﺻﺮ ﻳﻚ آراﻳﻪ از رﺷﺘﻪ ﻫﺎ ﺣﺮﻛﺖ ﻣﻲ ﻛﻨﺪ .در اﻳﻦ ﻣﺜـﺎل ﻫﻢ ﻫﻤﺎن ﻣﺮاﺣﻞ را ﺗﻜﺮار ﻣﻲ ﻛﻨﻴﻢ .ﻳﻚ ﻣﺘﻐﻴﺮ ﻛﻨﺘﺮل ﻛﻨﻨﺪه ،ﻫﻢ ﻧﻮع ﺑﺎ ﻋﻨﺎﺻﺮ آراﻳﻪ ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ و آن را ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑـﻪ ﺗـﻚ ﺗﻚ ﻋﻨﺎﺻﺮ آراﻳﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ دﻫﻴﻢ. ﺣﻠﻘﻪ foreachاز ﻋﻨﺼﺮ ﺻﻔﺮم آراﻳﻪ ﺷﺮوع ﻣﻲ ﻛﻨﺪ و ﺗﺎ رﺳﻴﺪن ﺑﻪ آﺧﺮﻳﻦ ﻋﻨﺼﺮ در آراﻳﻪ ،ﺑﻴﻦ ﺗﻤﺎم ﻋﻨﺎﺻﺮ ﺟﺎ ﺑﻪ ﺟﺎ ﻣﻲ ﺷﻮد .در ﻫﺮ ﺑﺎر ﺗﻜﺮار ﺣﻠﻘﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻋﻨﺼﺮي ﻛﻪ در ﻣﺘﻐﻴﺮ ﻛﻨﺘﺮل ﻛﻨﻨﺪه ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻳﻦ ﻣﺜﺎل اﻳﻦ ﻣﻘﺪار را ﺑـﻪ ﻟﻴـﺴﺖ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ. // Enumerate the array )foreach (string strName in strFriends { // Add the array item to the list ;)lstFriends.Items.Add(strName } ﻫﻤﭽﻨﻴﻦ ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﻋﻨﺎﺻﺮ ﺑﻪ ﻫﻤﺎن ﺗﺮﺗﻴﺒﻲ ﻛﻪ در آراﻳﻪ وارد ﺷﺪه اﻧﺪ داﺧﻞ ﻟﻴﺴﺖ ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ .اﻳﻦ ﻣﻮرد ﺑﻪ اﻳﻦ دﻟﻴﻞ اﺳﺖ ﻛـﻪ ﺣﻠﻘﻪ foreachاز ﻋﻨﺼﺮ ﺻﻔﺮم ﺗﺎ آﺧﺮﻳﻦ ﻋﻨﺼﺮ آراﻳﻪ را ﺑﻪ ﻫﻤﺎن ﺗﺮﺗﻴﺒﻲ ﻛﻪ ﺗﻌﺮﻳﻒ ﺷﺪه اﻧﺪ ﻃﻲ ﻣﻲ ﻛﻨﺪ.
اﻧﺘﻘﺎل آراﻳﻪ ﻫﺎ ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ: در ﺑﺴﻴﺎري از ﻣﻮارد ﻣﻤﻜﻦ اﺳﺖ ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻳﻚ آراﻳﻪ را ﻛﻪ ﻣﺤﺘﻮي ﭼﻨﺪﻳﻦ ﻋﻨﺼﺮ اﺳﺖ ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ ﻳﻚ ﻣﺘﺪ ﺑﻔﺮﺳﺘﻴﺪ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻧﺤﻮه اﻧﺠﺎم اﻳﻦ ﻋﻤﻞ را ﺧﻮاﻫﻴﻢ دﻳﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻧﺘﻘﺎل آراﻳﻪ ﻫﺎ ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ (1ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ و ﻛﻨﺘﺮل Buttonدﻳﮕﺮي را ﺑﻪ Form1اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺧﺎﺻﻴﺖ Nameاﻳﻦ ﻛﻨﺘـﺮل را ﺑﺮاﺑـﺮ ﺑـﺎ btnArraysAsParametersو ﺧﺎﺻـﻴﺖ Textآن را ﺑﺮاﺑـﺮ ﺑـﺎ Arrays as Parametersﻗﺮار دﻫﻴﺪ. (2روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑـﻮط ﺑـﻪ روﻳـﺪاد Clickآن وارد ﻛﻨﻴـﺪ .ﭘﻴﻐـﺎﻣﻲ را ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣﻲ ﮔﻮﻳﺪ زﻳﺮﺑﺮﻧﺎﻣﻪ AddItemsToListﺗﻌﺮﻳﻒ ﻧﺸﺪه اﺳﺖ .ﺑﺎ ﻛﻠﻴﻚ ﺑﺮ روي اﻳﻦ ﭘﻴﻐﺎم ،وﻳـﮋوال اﺳﺘﻮدﻳﻮ ﻣﺘﺪ را ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ .ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ ﭘﻴﻐﺎم را ﻧﺎدﻳﺪه ﺑﮕﻴﺮﻳﺪ ،زﻳﺮا اﻳﻦ ﻣﺘﺪ را در ﻣﺮﺣﻠﻪ ﺑﻌﺪي ﺗﻌﺮﻳﻒ ﺧﻮاﻫﻴﻢ ﻛﺮد: private void btnArraysAsParameters_Click(object sender, )EventArgs e { // List your friends ;)AddItemsToList(strFriends }
١٦٧
(3ﻫﻢ اﻛﻨﻮن ﻣﺘﺪ AddItemsToListرا ﺑﻪ ﺻﻮرت زﻳﺮ در ﻛﻼس ﺧﻮد ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ: )private void AddItemsToList(string[] arrayList { // Enumerate the array )foreach (string strName in arrayList { // Add the array item to the list ;)lstFriends.Items.Add(strName } } (4ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و روي دﻛﻤﻪ ي Arrays as Parametersﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻧﺘﻴﺠـﻪ اي را ﻣـﺸﺎﺑﻪ ﺷـﻜﻞ 2-5ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻧﻜﺘﻪ اي ﻛﻪ در ﻣﺘﺪ AddItemsToListوﺟﻮد دارد اﻳﻦ اﺳﺖ ﻛﻪ ﭘﺎراﻣﺘﺮ ﻣﻮرد ﻧﻴﺎز اﻳﻦ ﻣﺘﺪ ،آراﻳـﻪ اي از ﻧـﻮع رﺷـﺘﻪ اﺳـﺖ. ﺑﺮاي اﻳﻦ ﻛﻪ ﭘﺎراﻣﺘﺮ ﻳﻚ ﻣﺘﺪ را از ﻧﻮع آراﻳﻪ ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ در ﻣﻘﺎﺑﻞ ﻧﻮع داده اي آن ،از ﻳﻚ ﻛﺮوﺷﻪ ﺧﺎﻟﻲ )][( اﺳﺘﻔﺎده ﻛﻨﻴﺪ: )private void AddItemsToList(string[] arrayList ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺗﻌﺮﻳﻒ ﭘﺎراﻣﺘﺮﻫﺎي ﻳﻚ ﻣﺘﺪ ،آراﻳﻪ اي را ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﺪ اﻣﺎ ﻃﻮل آن را ﻣﺸﺨﺺ ﻧﻤﻲ ﻛﻨﻴـﺪ ،در ﺣﻘﻴﻘـﺖ ﺑـﻪ ﻛﺎﻣﭙـﺎﻳﻠﺮ وﻳﮋوال C#ﻣﻲ ﮔﻮﻳﻴﺪ ﻛﻪ ﻫﺮ آراﻳﻪ اي از اﻳﻦ ﻧﻮع ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻓﺮﺳﺘﺎده ﺷﻮد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ اﻧﺪازه آراﻳﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮﻧﺪ ﻣﻬﻢ ﻧﻴﺴﺖ و ﻓﻘﻂ ﻧﻮع آراﻳﻪ ﻣﻬﻢ اﺳﺖ .در زﻳﺮﺑﺮﻧﺎﻣﻪ btnArraysAsParametersﻣﻲ ﺗﻮاﻧﻴﺪ آراﻳﻪ اﺻﻠﻲ ﺧﻮد را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ اﻳﻦ ﺗﺎﺑﻊ ﻣﻨﺘﻘﻞ ﻛﻨﻴﺪ: // List your friends ;)AddItemsToList(strFriends در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،آراﻳﻪ اي ﺑﺎ ﻃﻮل ﻣﺘﻔﺎوﺗﻲ را ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ و ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن آن ﺑﻪ ﻟﻴﺴﺖ از ﻣﺘﺪ ﻗﺒﻠـﻲ اﺳـﺘﻔﺎده ﻣـﻲ ﻛﻨﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن دوﺳﺘﺎن ﺑﻴﺸﺘﺮ
١٦٨
(1اﮔﺮ ﺑﺮﻧﺎﻣﻪ در ﺣﺎل اﺟﺮا اﺳﺖ آن را ﺑﺒﻨﺪﻳﺪ و ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑـﻮط ﺑـﻪ Form1ﺑﺮﮔﺮدﻳـﺪ .ﻛﻨﺘـﺮل Button دﻳﮕﺮي ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮده ،ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑـﺎ btnMoreArrayParametersو ﺧﺎﺻـﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ More Array Parametersﻗﺮار دﻫﻴﺪ. (2ﺑﺮ روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickوارد ﻛﻨﻴﺪ: private void btnMoreArrayParameters_Click(object sender, )EventArgs e { // Declare an array ;]string[] strMoreFriends = new string[2 // Populate the array ;"strMoreFriends[0] = "Matt ;"strMoreFriends[1] = "Margie // List your friends ;)AddItemsToList(strFriends ;)AddItemsToList(strMoreFriends } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﺮ روي دﻛﻤﻪ اي ﻛﻪ ﺟﺪﻳﺪاً اﺿﺎﻓﻪ ﻛﺮده اﻳﺪ ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .ﻧﺘﻴﺠـﻪ اي ﻣـﺸﺎﺑﻪ ﺷـﻜﻞ 3-5را ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 3-5
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟
١٦٩
در اﻳﻦ ﻣﺜﺎل آراﻳﻪ اي را ﺑﻪ ﻃﻮل دو اﻳﺠﺎد ﻛﺮدﻳﻢ و آن را ﺑﻪ ﻣﺘﺪ AddItemsToListﻓﺮﺳﺘﺎدﻳﻢ ﺗﺎ آن را ﺑـﻪ ﻟﻴـﺴﺖ اﺿـﺎﻓﻪ ﻛﻨﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﻃﻮل آراﻳﻪ اي ﻛﻪ ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ اﻳﻦ ﻣﺘﺪ ارﺳﺎل ﻣﻲ ﻛﻨﻴﺪ ،اﻫﻤﻴﺘﻲ ﻧﺪارد. ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺣﺎل ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺴﺘﻴﺪ ،اﮔﺮ ﻳﻚ ﻣﺘﺪ ،ﭘﺎراﻣﺘﺮ ﺧﻮد را ﺑﻪ ﺻﻮرت آراﻳﻪ درﻳﺎﻓﺖ ﻛﻨﺪ ،در ﭘﻨﺠـﺮه اي ﻛـﻪ ﺑـﺮاي ﺗﻜﻤﻴـﻞ ﻫﻮﺷﻤﻨﺪاﻧﻪ ي ﻧﺎم ﻣﺘﺪ ﺗﻮﺳﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺎز ﻣﻲ ﺷﻮد ،در ﻣﻘﺎﺑﻞ ﻧﻮع داده اي آراﻳﻪ ﻳﻚ ﻛﺮوﺷﻪ ﺧﺎﻟﻲ ﻗﺮار دارد) .ﺷﻜﻞ (4-5
ﺷﻜﻞ 4-5 ﻧﻜﺘﻪ :در ﭘﻨﺠﺮه ﺑﺎز ﺷﺪه ﻧﻪ ﺗﻨﻬﺎ آراﻳﻪ اي ﺑﻮدن ﻳﻚ ﭘﺎراﻣﺘﺮ ﻗﺎﺑﻞ ﺗﺸﺨﻴﺺ اﺳﺖ ،ﺑﻠﻜﻪ ﻧﻮع اﻳﻦ ﭘﺎراﻣﺘﺮ ﻧﻴﺰ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
ﻣﺮﺗﺐ ﺳﺎزي آراﻳﻪ ﻫﺎ: ﻳﻜﻲ از ﻣﻮاردي ﻛﻪ ﻫﻤﻮاره ﻫﻨﮕﺎم ﻛﺎر ﺑﺎ آراﻳﻪ ﻫﺎ ﻣﻮرد ﻧﻴﺎز ﺑﻮده اﺳﺖ ،ﻣﺮﺗﺐ ﻛﺮدن آراﻳﻪ اﺳﺖ .در ﺑﺨﺶ اﻣﺘﺤـﺎن ﻛﻨﻴـﺪ ﺑﻌـﺪ ،ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان آراﻳﻪ ﻫﺎ را ﻣﺮﺗﺐ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻣﺮﺗﺐ ﺳﺎزي آراﻳﻪ ﻫﺎ (1در ﺑﺨﺶ ﻃﺮاﺣﻲ ﻓﺮم ﻛﻨﺘﺮل Buttonدﻳﮕﺮي ﺑﻪ Form1اﺿﺎﻓﻪ ﻛـﺮده ،ﺳـﭙﺲ ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑـﺮ ﺑـﺎ btnSortingArraysو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ Sorting Arraysﻗﺮار دﻫﻴﺪ. (2روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void btnSortingArrays_Click(object sender, )EventArgs e { // Sort the array ;)Array.Sort(strFriends // List your friends ;)AddItemsToList(strFriends } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي اﻳﻦ دﻛﻤﻪ ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻟﻴﺴﺖ ،اﺳﺎﻣﻲ ﻣﻮﺟﻮد در آراﻳﻪ را ﻛﻪ ﺑـﻪ ﺻـﻮرت اﻟﻔﺒﺎﻳﻲ ﻣﺮﺗﺐ ﺷﺪه اﻧﺪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
١٧٠
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺗﻤﺎم آراﻳﻪ ﻫﺎ ﺑﻪ ﺻﻮرت دروﻧﻲ از ﻛﻼﺳﻲ ﺑﻪ ﻧﺎم System.Arrayﻣﺸﺘﻖ ﻣﻲ ﺷﻮﻧﺪ .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ از ﻳﻜـﻲ از ﻣﺘـﺪﻫﺎي اﻳـﻦ ﻛﻼس ﺑﻪ ﻧﺎم Sortاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ ﻓﻘﻂ ﻳﻚ ﭘﺎراﻣﺘﺮ ﻣﻲ ﮔﻴﺮد و آن ﭘﺎراﻣﺘﺮ ﻧﻴﺰ ﻧﺎم آراﻳﻪ اي اﺳﺖ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴـﺪ آن را ﻣﺮﺗﺐ ﻛﻨﻴﺪ .ﺳﭙﺲ اﻳﻦ ﻣﺘﺪ ﻫﻤﺎﻧﻄﻮر ﻛﻪ از ﻧﺎم آن ﻣﺸﺨﺺ اﺳﺖ ،آراﻳﻪ را ﺑﺮ اﺳﺎس ﻧﻮع داده اي ﻋﻨﺎﺻﺮ آن ،ﻣﺮﺗﺐ ﻣﻲ ﻛﻨـﺪ و ﺑـﺎز ﻣـﻲ ﮔﺮداﻧﺪ.در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻋﻠﺖ اﻳﻦ ﻛﻪ ﻧﻮع ﻋﻨﺎﺻﺮ رﺷﺘﻪ اي اﺳﺖ ،آراﻳﻪ ﺑﻪ ﺻﻮرت اﻟﻔﺒﺎﻳﻲ ﻣﺮﺗﺐ ﻣﻲ ﺷﻮد .اﮔﺮ از اﻳﻦ ﻣﺘـﺪ ﺑـﺮاي ﻣﺮﺗـﺐ ﺳﺎزي ﻳﻚ آراﻳﻪ از اﻋﺪاد ﺻﺤﻴﺢ و ﻳﺎ اﻋﺪاد اﻋﺸﺎري اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،آراﻳﻪ ﺑﻪ ﺻﻮرت ﻋﺪدي ﻣﺮﺗﺐ ﺧﻮاﻫﺪ ﺷﺪ. // Sort the array ;)Array.Sort(strFriends اي ﻗﺎﺑﻠﻴﺖ ﻛﻪ ﻳﻚ ﻣﺘﺪ ﻣﻲ ﺗﻮاﻧﺪ ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ از ﻧﻮع ﻫﺎي داده اي ﻣﺨﺘﻠﻒ را درﻳﺎﻓﺖ ﻛﻨﺪ ،ﺳﭙﺲ ﺑﺮ اﺳﺎس ﻧﻮع ﭘﺎراﻣﺘﺮ ﻋﻤﻠﻴﺎت ﻣﻨﺎﺳﺒﻲ را ﺑﺮ روي آن اﻧﺠﺎم دﻫﺪ ،ﺳﺮﺑﺎر ﮔﺬاري 1ﻣﺘﺪﻫﺎ ﻣﻲ ﻧﺎﻣﻨﺪ .در اﻳﻨﺠﺎ ﻣﻲ ﮔﻮﻳﻴﻢ ﻛﻪ ﺗﺎﺑﻊ Sortﻳﻚ ﺗﺎﺑﻊ ﺳﺮﺑﺎر ﮔﺬاري ﺷـﺪه اﺳـﺖ .در ﻓﺼﻞ دﻫﻢ ﺑﻴﺸﺘﺮ در ﻣﻮرد ﺳﺮﺑﺎر ﮔﺬاري ﻣﺘﺪﻫﺎ و ﻧﺤﻮه اﻳﺠﺎد ﭼﻨﻴﻦ ﻣﺘﺪﻫﺎﻳﻲ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد.
ﺣﺮﻛﺖ ﺑﻪ ﻋﻘﺐ در آراﻳﻪ ﻫﺎ: ﺣﻠﻘﻪ ﻫﺎي foreachﻓﻘﻂ در ﻳﻚ ﺟﻬﺖ در ﺑﻴﻦ ﻋﻨﺎﺻﺮ ﻳﻚ آراﻳﻪ ﺣﺮﻛﺖ ﻣﻲ ﻛﻨﻨﺪ .آﻧﻬﺎ از ﻋﻨﺼﺮ ﺻﻔﺮم ﻳﻚ آراﻳﻪ ﺷﺮوع ﻣﻲ ﻛﻨﻨﺪ و ﺗﺎ آﺧﺮﻳﻦ ﻋﻨﺼﺮ آراﻳﻪ ﭘﻴﺶ ﻣﻲ روﻧﺪ .اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﺑﻴﻦ ﻋﻨﺎﺻﺮ ﻳﻚ آراﻳﻪ ﺑﻪ ﺻﻮرت ﺑﺮﻋﻜﺲ ﺣﺮﻛﺖ ﻛﻨﻴـﺪ )ﻳﻌﻨـﻲ از ﻋﻨـﺼﺮ آﺧـﺮ ﺑـﻪ ﻋﻨﺼﺮ اول ﺑﺮﮔﺮدﻳﺪ( دو راه در اﺧﺘﻴﺎر دارﻳﺪ. راه اول اﻳﻦ اﺳﺖ ﻛﻪ از ﺣﻠﻘﻪ ﻫﺎي forﻣﻌﻤﻮﻟﻲ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻳﻦ ﺻﻮرت ﺑﺎﻳﺪ ﻣﻘﺪار اوﻟﻴﻪ ﺷﻤﺎرﻧﺪه ﺣﻠﻘـﻪ را ﻳـﻚ واﺣـﺪ ﻛﻤﺘـﺮ از ﻃﻮل آراﻳﻪ ﻗﺮار دﻫﻴﺪ 2و ﺳﭙﺲ ﺣﻠﻘﻪ را ﻃﻮري ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ﻛﻪ ﺗﺎ ﻋﺪد ﻳﻚ ﺑﺮﮔﺮدد .در ﻗﺴﻤﺖ زﻳﺮ اﻳﻦ روش را ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ: ;)for (int intIndex = strFriends.GetUpperBound(0 )intIndex >= 0; intIndex-- { // Add the array item to the list ;)]lstFriends.Items.Add(strFriends[intIndex } روش دوم اﻳﻦ اﺳﺖ ﻛﻪ از ﻣﺘﺪ Reverseدر ﻛﻼس Arrayاﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻳﻦ ﻣﺘﺪ ﻋﻨﺎﺻﺮ ﻳﻚ آراﻳﻪ را ﺑﻪ ﺻﻮرت ﻣﻌﻜﻮس در آراﻳﻪ ﻗﺮار ﻣﻲ دﻫﺪ .ﺑﻌﺪ از اﺳﺘﻔﺎده از اﻳﻦ ﻣﺘﺪ ،ﻣﻴﺘﻮاﻧﻴﺪ از ﺣﻠﻘﻪ ﻫﺎي foreachﻣﻌﻤـﻮﻟﻲ ﺑـﺮاي ﻧﻤـﺎﻳﺶ آراﻳـﻪ اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،اﻳﻦ روش را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
1
Overloading 2ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﺑﻪ ﺧﺎﻃﺮ دارﻳﺪ ،اﻧﺪﻳﺲ آﺧﺮﻳﻦ ﻋﻨﺼﺮ ﻫﺮ آراﻳﻪ ﻳﻚ واﺣﺪ ﻛﻤﺘﺮ از ﻃﻮل آن آراﻳﻪ اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي ﺑﺎزﮔﺸﺘﻦ از آﺧﺮﻳﻦ ﻋﻨﺼﺮ آراﻳﻪ ﺑﺎﻳﺪ از ﻳـﻚ واﺣـﺪ ﻛﻤﺘﺮ از ﻃﻮل ﺑﻪ ﻋﻨﻮان ﻋﺪد ﺷﺮوع اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
١٧١
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻣﻌﻜﻮس ﻛﺮدن ﻳﻚ آراﻳﻪ (1ﻛﻨﺘـــﺮل Buttonدﻳﮕـــﺮي ﺑـــﻪ ﻗـــﺴﻤﺖ ﻃﺮاﺣـــﻲ ﻓـــﺮم اﺿـــﺎﻓﻪ ﻛـــﺮده ،ﺧﺎﺻـــﻴﺖ Nameآن را ﺑﺮاﺑـــﺮ ﺑـــﺎ btnReversingAnArrayو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Reversing an Arrayﻗﺮار دﻫﻴﺪ. (2روي اﻳﻦ دﻛﻤﻪ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: private void btnReversingAnArray_Click(object sender, )EventArgs e { – // Reverse the order // elements will be in descending order ;)Array.Reverse(strFriends // List your friends ;)AddItemsToList(strFriends } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ ي Reversing an Arrayﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣـﻲ ﻛﻨﻴـﺪ ﻛـﻪ ﻫﻤﺎﻧﻨـﺪ ﺷﻜﻞ 5-5ﻧﺎﻣﻬﺎي ﻣﻮﺟﻮد در ﻟﻴﺴﺖ ﺑﻪ ﺻﻮرت ﻣﻌﻜﻮس ﻧﻤﺎﻳﺶ داده ﺷﺪه اﻧﺪ.
ﺷﻜﻞ 5-5
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟
١٧٢
ﺗﺎﺑﻊ Reverseﻋﻨﺎﺻﺮ ﻣﻮﺟﻮد در ﻳﻚ آراﻳﻪ ي ﻳﻚ ﺑﻌﺪي را ﺑﻪ ﺻﻮرت ﻣﻌﻜﻮس در آن آراﻳﻪ ﻗﺮار ﻣﻲ دﻫﺪ .ﻫﻨﮕﺎﻣﻲ ﻛـﻪ آراﻳـﻪ ي strFriendsرا ﺑﻪ اﻳﻦ ﻣﺘﺪ ارﺳﺎل ﻣﻲ ﻛﻨﻴﺪ ،در ﺣﻘﻴﻘﺖ از ﻣﺘﺪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻛﻪ ﻋﻨﺎﺻﺮ اﻳﻦ آراﻳﻪ را از آﺧﺮ ﺑﻪ اول ﻗﺮار دﻫﺪ: – // Reverse the order // elements will be in descending order ;)Array.Reverse(strFriends ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻋﻨﺎﺻﺮ آراﻳﻪ ﺑﻪ ﺻﻮرت ﻣﻌﻜﻮس در آن ﻗﺮار ﮔﺮﻓﺘﻨﺪ ،ﻛﺎﻓﻲ اﺳﺖ آراﻳﻪ را ﺑﻪ ﻣﺘﺪ AddItemsToListﺑﻔﺮﺳﺘﻴﺪ ﺗـﺎ آن را در ﻟﻴﺴﺖ ﻧﻤﺎﻳﺶ دﻫﺪ. // List your friends ;)AddItemsToList(strFriends ﻧﻜﺘﻪ :اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ آراﻳﻪ ﺑﻪ ﺻﻮرت ﻧﺰوﻟﻲ اﻟﻔﺒﺎﻳﻲ ﻣﺮﺗﺐ ﺷﻮد ،ﻛﺎﻓﻲ اﺳﺖ آراﻳﻪ را ﺑﻪ وﺳﻴﻠﻪ ﺗﺎﺑﻊ Sortﺑﻪ ﺻﻮرت ﺻﻌﻮدي اﻟﻔﺒﺎﻳﻲ ﻣﺮﺗﺐ ﻛﻨﻴﺪ ،ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﺗﺎﺑﻊ Reverseآن را ﺑﻪ ﺻﻮرت ﻣﻌﻜﻮس درآورﻳﺪ .ﺑﻪ اﻳﻦ ﺻﻮرت آراﻳﻪ ﺑﻪ ﺻﻮرت اﻟﻔﺒـﺎﻳﻲ ﻧﺰوﻟـﻲ ﻣﺮﺗﺐ ﻣﻲ ﺷﻮد.
ﻣﻘﺪار دﻫﻲ اوﻟﻴﻪ ﺑﻪ آراﻳﻪ ﻫﺎ: در وﻳﮋوال C#ﻣﻲ ﺗﻮاﻧﻴﺪ آراﻳﻪ ﻫﺎ را در ﻫﻤﺎن ﺧﻄﻲ ﻛﻪ ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﺪ ،ﻣﻘﺪار دﻫﻲ ﻛﻨﻴﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻧﻴـﺎزي ﻧﻴـﺴﺖ ﻛـﻪ ﺑﻌـﺪ از ﺗﻌﺮﻳﻒ آراﻳﻪ از ﭼﻨﺪﻳﻦ ﺧﻂ ﻛﺪ ﻫﻤﺎﻧﻨﺪ زﻳﺮ ﺑﺮاي ﭘﺮ ﻛﺮدن آراﻳﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ: // Declare an array ;]string[] strFriends = new string[4 array ;""Robbin ;""Bryan ;""Stephanie ;""Sydney ;""Katie
// Populate the = ]strFriends[0 = ]strFriends[1 = ]strFriends[2 = ]strFriends[3 = ]strFriends[4
در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ،ﺑﺎ ﭼﮕﻮﻧﮕﻲ ﻣﻘﺪاردﻫﻲ آراﻳﻪ ﻫﺎ در ﻳﻚ ﺧﻂ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻣﻘﺪاردﻫﻲ اوﻟﻴﻪ ﺑﻪ آراﻳﻪ ﻫﺎ (1در ﻗـﺴﻤﺖ ﻃﺮاﺣـﻲ ﻓــﺮم ،ﻛﻨﺘـﺮل Buttonدﻳﮕــﺮي را ﺑـﻪ Form1اﺿـﺎﻓﻪ ﻛــﺮده ،ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑــﺮ btnInitializingArrayWithValuesو ﺧﺎﺻـــــــﻴﺖ Textآن را ﺑﺮاﺑـــــــﺮ ﺑـــــــﺎ Initializing Array With Valuesﻗﺮار دﻫﻴﺪ. ١٧٣
(2روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن وارد ﻛﻨﻴﺪ: (private void btnInitializingArrayWithValues_Click )object sender, EventArgs e { // Declare an populate an array { ][String[] strMyFriends = new string "Robbin","Bryan","Stephanie", ;}""Sudney","Katie // List your friends ;)AddItemsToList(strMyFriends } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﺮ روي دﻛﻤﻪ ي ﺟﺪﻳﺪ ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻟﻴﺴﺖ ،ﺑﺎ ﻋﻨﺎﺻﺮ ﻣﻮﺟﻮد در آراﻳﻪ ﭘـﺮ ﻣـﻲ ﺷﻮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ آراﻳﻪ را ﺗﻌﺮﻳﻒ ﻛﺮدﻳﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﻘﺎدﻳﺮ ﻫﺮ ﻳﻚ از ﻋﻨﺎﺻﺮ آن را ﺑﻪ ﺗﺮﺗﻴﺐ در ﻳﻚ ﺟﻔـﺖ آﻛـﻮﻻد وارد ﻛﻨﻴـﺪ .در اﻳـﻦ ﺣﺎﻟﺖ ،وﻳﮋوال C#از ﺧﺎﻧﻪ ﺻﻔﺮم آراﻳﻪ ﺷﺮوع ﻣﻲ ﻛﻨﺪ و ﻣﻘﺎدﻳﺮ وارد ﺷﺪه را ﺑﻪ ﺗﺮﺗﻴﺐ در ﺧﺎﻧﻪ ﻫﺎي آراﻳﻪ ﻗﺮار ﻣﻲ دﻫﺪ .در اﻳـﻦ ﻣﺜـﺎل ﭘﻨﺞ رﺷﺘﻪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ وﻳﺮﮔﻮل از ﻳﻜﺪﻳﮕﺮ ﺟﺪا ﺷﺪه اﻧﺪ را در آراﻳﻪ ﻗﺮار داده اﻳﻢ .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻃﻮل آراﻳﻪ را وارد ﻧﻜﺮده اﻳﻢ ،ﺑﻠﻜﻪ ﻃﻮل آراﻳﻪ ﺑﺮ اﺳﺎس ﻣﻘﺎدﻳﺮ وارد ﺷﺪه در داﺧﻞ آﻛﻮﻻد ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺗﻮﺳﻂ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻣﺤﺎﺳﺒﻪ ﻣﻴﺸﻮد. // Declare an populate an array { ][String[] strMyFriends = new string "Robbin","Bryan","Stephanie", ;}""Sudney","Katie اﻟﺒﺘﻪ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ ﺑﻴﻨﻴﺪ اﻳﻦ روش ﺑﺮاي ﻣﻘﺪار دﻫﻲ ﺑﻪ آراﻳﻪ ﻫﺎي ﺑﺰرگ ﻣﻨﺎﺳﺐ ﻧﻴﺴﺖ .اﮔﺮ در ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ آراﻳﻪ ﺑﺰرﮔﻲ را ﭘـﺮ ﻛﻨﻴﺪ ،ﺑﻬﺘﺮ اﺳﺖ از روﺷﻲ ﻛﻪ در ﺑﺨﺶ ﻗﺒﻞ ﮔﻔﺘﻪ ﺷﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﻳﻌﻨﻲ ﺑﺎ اﺳﺘﻔﺎده از ﻧﺎم آراﻳﻪ و اﻧـﺪﻳﺲ ﺧﺎﻧـﻪ ﻣـﻮرد ﻧﻈـﺮ ،ﻣﻘـﺪار آن ﻋﻨﺼﺮ را وارد ﻛﻨﻴﺪ.
ﻣﻔﻬﻮم ﺷﻤﺎرﻧﺪه ﻫﺎ:
١٧٤
ﻣﺘﻐﻴﺮﻫﺎﻳﻲ ﻛﻪ ﺗﺎﻛﻨﻮن اﻳﺠﺎد ﻛﺮده اﻳﻢ ،ﻫﻴﭻ ﻣﺤﺪودﻳﺘﻲ در ﻧﻮع اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺴﺘﻨﺪ در ﺧﻮد ذﺧﻴﺮه ﻛﻨﻨﺪ ﻧﺪاﺷﺘﻨﺪ .ﺑﺮاي ﻣﺜﺎل اﮔـﺮ ﻣﺘﻐﻴﺮي را از ﻧﻮع intﺗﻌﺮﻳﻒ ﻣﻲ ﻛﺮدﻳﺪ ،ﻣﻲ ﺗﻮاﻧﺴﺘﻴﺪ ﻫﺮ ﻋﺪد ﺻﺤﻴﺤﻲ را در آن ﻧﮕﻬـﺪاري ﻛﻨﻴـﺪ .1اﻳـﻦ ﻣـﺴﺌﻠﻪ ﺑـﺮاي ﻣﺘﻐﻴﺮﻫـﺎي stringو doubleﻫﻢ وﺟﻮد داﺷﺖ. اﻣﺎ در ﺑﻌﻀﻲ از ﺷﺮاﻳﻂ ،ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ ﻣﺘﻐﻴﺮ ﺷﻤﺎ ،اﻋﺪاد ﻣﺤﺪودي را در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ ﻣـﻲ ﺧﻮاﻫﻴـﺪ ﻣﺘﻐﻴﺮي از ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ و ﺗﻌﺪاد درﻫﺎي ﻳﻚ اﺗﻮﻣﺒﻴﻞ را در آن ذﺧﻴﺮه ﻛﻨﻴﺪ .ﻗﻄﻌﺎ ﻧﻤـﻲ ﺧﻮاﻫﻴـﺪ اﺟـﺎزه دﻫﻴـﺪ ﻛـﻪ ﻋـﺪد 16327در اﻳﻦ ﻣﺘﻐﻴﺮ ذﺧﻴﺮه ﺷﻮد .ﺑﺮاي رﻓﻊ اﻳﻦ ﻣﺸﻜﻞ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺷﻤﺎرﻧﺪه ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
اﺳﺘﻔﺎده از ﺷﻤﺎرﻧﺪه ﻫﺎ: ﺑﺎ اﺳﺘﻔﺎده از ﺷﻤﺎرﻧﺪه ﻫﺎ ﻣﻴﺘﻮاﻧﻴﺪ ﻧﻮع ﻫﺎي داده اي ﺟﺪﻳﺪي ﺑﺮ اﺳﺎس ﻧﻮع ﻫﺎي داده اي ﻣﻮﺟﻮد از ﻗﺒﻴـﻞ short ،long ،int و ﻳﺎ byteﺑﺴﺎزﻳﺪ .ﻣﺘﻐﻴﺮﻫﺎﻳﻲ ﻛﻪ از اﻳﻦ ﻧﻮع داده ي ﺟﺪﻳﺪ اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ ،ﻓﻘـﻂ ﻣـﻲ ﺗﻮاﻧﻨـﺪ ﻣﻘـﺪاري را داﺷـﺘﻪ ﺑﺎﺷـﻨﺪ ﻛـﻪ ﺷـﻤﺎ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻴﺘﻮاﻧﻴﺪ در ﺑﺮﻧﺎﻣﻪ از وارد ﺷﺪن اﻋﺪاد ﻏﻴﺮ ﻣﻨﻄﻘﻲ در ﻣﺘﻐﻴﺮ ﻫﺎ ﺟﻠـﻮﮔﻴﺮي ﻛﻨﻴـﺪ .ﻫﻤﭽﻨـﻴﻦ اﺳـﺘﻔﺎده از ﺷﻤﺎرﻧﺪه ﻫﺎ در ﻛﺪ ﺑﺎﻋﺚ اﻓﺰاﻳﺶ ﺧﻮاﻧﺎﻳﻲ و وﺿﻮح ﻣﻲ ﺷﻮد .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ،ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛـﺮد ﻛـﻪ ﭼﮕﻮﻧـﻪ ﻣﻴﺘـﻮان ﺑﺮﻧﺎﻣﻪ اي ﺳﺎﺧﺖ ﻛﻪ ﺑﺮ اﺳﺎس ﺳﺎﻋﺖ ،ﻳﻜﻲ از اﻋﻤﺎل ﻗﺎﺑﻞ اﺟﺮا در ﻳﻚ روز را اﻧﺘﺨﺎب ﻛﻨﺪ.
آﻣﺎده ﺷﺪن ﺑﺮاي رﻓﺘﻦ ﺑﻪ ﻣﺤﻞ ﻛﺎر. رﻓﺘﻦ ﺑﻪ ﻣﺤﻞ ﻛﺎر. در ﻣﺤﻞ ﻛﺎر ﺑﻮدن. رﻓﺘﻦ ﺑﺮاي ﻧﻬﺎر. ﺑﺮﮔﺸﺘﻦ از ﻣﺤﻞ ﻛﺎر. ﺑﺎ دوﺳﺘﺎن ﺑﻮدن. آﻣﺎده ﺷﺪن ﺑﺮاي ﺧﻮاب. ﺧﻮاﺑﻴﺪن.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﺷﻤﺎرﻧﺪه ﻫﺎ (1ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﺤﺖ وﻳﻨﺪوز ﺟﺪﻳﺪ اﻳﺠﺎد ﻛﻨﻴﺪ و ﻧﺎم آن را ﺑﺮاﺑﺮ ﺑﺎ Enum Demoﻗـﺮار دﻫﻴﺪ. (2ﺷﻤﺎرﻧﺪه ﻫﺎ ﻣﻌﻤﻮﻻ ﺑﻪ ﻋﻨﻮان ﻋﻀﻮي از ﻛﻼﺳﻲ ﻛﻪ در ﺣﺎل ﻛﺪ ﻧﻮﻳﺴﻲ در آن ﻫﺴﺘﻴﺪ ،ﺗﻌﺮﻳﻒ ﻣﻲ ﺷﻮﻧﺪ .ﺑﻌﺪ از اﻳﻨﻜﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ Form1ﺑﺎز ﺷﺪ ،روي ﻓﺮم ﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ و ﮔﺰﻳﻨﻪ ي View Codeرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﺑﺮاي اﻳﻦ ﻓﺮم ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﺑـﺎﻻي ﭘﻨﺠـﺮه ،ﺑﻌـﺪ از ﻧـﺎم ﻛﻼس وارد ﻛﻨﻴﺪ:
1اﻟﺒﺘﻪ ﺑﻪ ﺧﺎﻃﺮ ﻣﺤﺪود ﺑﻮدن ﻓﻀﺎي ﺣﺎﻓﻈﻪ اي ﻛﻪ ﺑﻪ ﻳﻚ ﻣﺘﻐﻴﺮ intاﺧﺘﺼﺎص داده ﻣﻲ ﺷﻮد ،ﻓﻘﻂ اﻋـﺪاد در ﺑـﺎزه ﺧﺎﺻـﻲ را ﻣﻴﺘـﻮان در اﻳـﻦ ﻧـﻮع ﻣﺘﻐﻴﻴـﺮ ﻫـﺎ ﻧﮕﻬﺪاري ﻛﺮد .اﻣﺎ ﻫﺮ ﻋﺪدي ﻛﻪ در اﻳﻦ ﺑﺎزه وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ را ﻣﻴﺘﻮان در ﻣﺘﻐﻴﺮﻫﺎي ﻋﺪد ﺻﺤﻴﺢ ذﺧﻴﺮه ﻛﺮد و در ﺑﻴﻦ اﻋﺪاد ﻣﻮﺟﻮد در اﻳﻦ ﺑﺎزه ﻣﺤـﺪودﻳﺘﻲ وﺟـﻮد ﻧﺪارد.
١٧٥
public partial class Form1 : Form { private enum DayAction { GettingReadyForWork = 0, TravelingToWork, AtWork, AtLunch, TravelingFromWork, RelaxingForFriends, GettingReadyForBed, Asleep ;} (3ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺷﻤﺎرﻧﺪه را ﺗﻌﺮﻳﻒ ﻛﺮدﻳﺪ ،ﻣﻴﺘﻮاﻧﻴﺪ ﻣﺘﻐﻴﺮي ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ﻛﻪ ﻧﻮع داده اي آن ﺑﺮاﺑﺮ ﺑﺎ اﻳﻦ ﺷـﻤﺎرﻧﺪه ﺑﺎﺷـﺪ .ﻣﺘﻐﻴـﺮ زﻳﺮ را در ﻛﻼس ﻣﺮﺑﻮط ﺑﻪ Form1ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ: // Declare variable ;private DayAction CurrentState (4ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ Form1ﺑﺮﮔﺮدﻳﺪ و ﺧﺎﺻﻴﺖ Textﻓﺮم را ﺑﺮاﺑـﺮ ﺑـﻪ ? What's Matt Doingﺗﻐﻴـﺮ دﻫﻴﺪ. (5ﺣﺎل ﻳﻚ ﻛﻨﺘﺮل DateTimePickerﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮده و ﺧﺎﺻﻴﺘﻬﺎي آن را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺎدﻳﺮ زﻳﺮ ﻗﺮار دﻫﻴﺪ:
ﺧﺎﺻﻴﺖ Nameآن را ﺑﻪ dtpHourﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Formatآن را ﺑﻪ Timeﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺧﺎﺻﻴﺖ ShowUpDownرا ﺑﺮاﺑﺮ ﺑﺎ trueﻗﺮار دﻫﻴﺪ. ﻣﻘﺪار Valueرا 00:00 AMوارد ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ Sizeرا ﺑﺮاﺑﺮ ﺑﺎ 91;20وارد ﻛﻨﻴﺪ.
(6ﻳﻚ ﻛﻨﺘﺮل Labelدر ﻓـﺮم ﻗـﺮار داده ،ﺧﺎﺻـﻴﺖ Nameآن را ﺑـﻪ lblStateو ﺧﺎﺻـﻴﺖ Textآن را ﺑـﻪ State Not Initializedﺗﻐﻴﻴﺮ دﻫﻴﺪ .اﻧﺪازه ﻓﺮم ﺧﻮد را ﻧﻴﺰ ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ ﻓﺮم ﺷﻤﺎ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 6-5ﺷﻮد.
ﺷﻜﻞ 6-5
١٧٦
ﺳﭙﺲ ﻛﺪﻫﺎي ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ. اﻳﺠﺎد ﺷﻮدForm1 ﻣﺮﺑﻮط ﺑﻪLoad ( ﺑﺮ روي زﻣﻴﻨﻪ ي ﻓﺮم ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ روﻳﺪاد7 .را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ private void Form1_Load(object sender, EventArgs e) { // Set the hour property to the current hour this.Hour = DateTime.Now.Hour; } :( ﺣﺎل ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در اﻳﻦ ﻗﺴﻤﺖ را در ﭘﺎﻳﻴﻦ ﻛﺪي ﻛﻪ در ﻗﺴﻤﺖ ﺳﻮم اﻳﻦ ﺑﺨﺶ وارد ﻛﺮدﻳﺪ ﻗﺮار دﻫﻴﺪ8 // Hour property private int Hour { get { // Return the current hour displayed return dtpHour.Value.Hour; } set { // Set the date using the hour // passed to this property dtpHour.Value = new DateTime( DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, value, 0, 0); // Set the display text lblState.Text = "At " + value + ":00 Matt is "; } } ﻣﺘــﺪ ﻣﺮﺑــﻮط ﺑــﻪ روﻳــﺪاد. دو ﺑــﺎر ﻛﻠﻴــﻚ ﻛﻨﻴــﺪdtpHour ( ﺑــﻪ ﻗــﺴﻤﺖ ﻃﺮاﺣــﻲ ﻓــﺮم ﺑﺮﮔﺮدﻳــﺪ و ﺑــﺮ روي ﻛﻨﺘــﺮل9 ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿـﺎﻓﻪ. اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﺧﻮاﻫﺪ ﺷﺪValueChanged :ﻛﻨﻴﺪ private void dtpHour_ValueChanged(object sender,EventArgs e) { // Update the hour property this.Hour = dtpHour.Value.Hour; } ﻣـﺸﺎﻫﺪه. ﻛﻠﻴـﻚ ﻛﻨﻴـﺪDateTimePicker ( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﺮ روي ﻋﻼﻣﺖ ﻫﺎي ﺑﺎﻻ و ﭘﺎﻳﻴﻦ ﻛﻨﺎر ﻛﻨﺘﺮل10 .(7-5 ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣﺘﻦ داﺧﻞ ﻛﻨﺘﺮل ﻟﻴﺒﻞ ﺗﻐﻴﻴﺮ ﻣﻲ ﻛﻨﺪ و ﺳﺎﻋﺖ اﻧﺘﺨﺎب ﺷﺪه را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ )ﺷﻜﻞ
١٧٧
ﺷﻜﻞ 7-5
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ،ﻛﺎرﺑﺮ ﻣﻴﺘﻮاﻧﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل DateTimePickerﻳﻚ ﺳﺎﻋﺖ از ﺷﺒﺎﻧﻪ روز را اﻧﺘﺨﺎب ﻛﻨﺪ .ﺳﭙﺲ ﺷﻤﺎ ﺑـﺎ ﺗﻮﺟﻪ ﺑﻪ ﺳﺎﻋﺖ اﻧﺘﺨﺎب ﺷﺪه ﺗﻮﺳﻂ ﻛﺎرﺑﺮ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻣﺖ در آن ﺳﺎﻋﺖ ﻣﺸﻐﻮل اﻧﺠﺎم ﻛﺪاﻣﻴﻚ از ﻫﺸﺖ ﻛـﺎر ﺗﻌﺮﻳـﻒ ﺷـﺪه اﺳﺖ .ﺑﺮاي اﻳﻦ ﻛﺎر اﺑﺘﺪا ﺑﺎﻳﺪ ﺳﺎﻋﺖ ﻣﺸﺨﺺ ﺷﺪه ﺗﻮﺳﻂ ﻛﺎرﺑﺮ را در ﻣﻜﺎﻧﻲ ﻧﮕﻬﺪاري ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻳﻚ ﺧﺎﺻﻴﺖ ﺟﺪﻳﺪ ﺑﻪ ﻓﺮﻣﻲ ﻛﻪ در ﺣﺎل ﻛﺎر ﺑﺎ آن ﻫﺴﺘﻴﻢ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ .اﻳﻦ ﺧﺎﺻﻴﺖ ﻫﻤﺎﻧﻨﺪ دﻳﮕﺮ ﺧﺎﺻﻴﺘﻬﺎي ﻓﺮم ﻣﺜﻞ Nameاﺳﺖ .ﻧﺎم اﻳـﻦ ﺧﺎﺻـﻴﺖ ﺟﺪﻳـﺪ Hourاﺳﺖ و ﺑﺮاي ﺗﻨﻈﻴﻢ ﺳﺎﻋﺖ در ﻛﻨﺘﺮل DateTimePickerو ﻛﻨﺘﺮل ﻟﻴﺒـﻞ ﺑـﻪ ﻛـﺎر ﻣـﻲ رود .ﺑـﺮاي ﺗﻌﺮﻳـﻒ ﻳـﻚ ﺧﺎﺻﻴﺖ ﺟﺪﻳﺪ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﻧﻮع داده اي و ﻧﺎم آن را ﻣﺸﺨﺺ ﻛﻨﻴﺪ و ﺳﭙﺲ ﻣﺎﻧﻨﺪ زﻳﺮ در ﺑﺪﻧـﻪ آن ﺧﺎﺻـﻴﺖ ،دو ﺑـﻼك ﺑـﻪ ﻧﺎﻣﻬـﺎي setو getﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ: private int Hour { get { … ;return dtpHour.Value.Hour } set { … } } ﺑﻪ ﺑﻼﻛﻬﺎي getو setدرون ﺧﺎﺻﻴﺖ ﺗﻮﺟﻪ ﻛﻨﻴﺪ .دﺳﺘﻮرات ﺑﻼك getﻛﻪ ﺷـﺎﻣﻞ دﺳـﺘﻮر returnﻫـﻢ ﻫـﺴﺘﻨﺪ زﻣـﺎﻧﻲ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﺑﺨﻮاﻫﻴﻢ ﻣﻘﺪار ذﺧﻴﺮه ﺷﺪه در ﺧﺎﺻﻴﺖ را ﺑﺪﺳﺖ آورﻳﻢ .در ﺑﻼك getﻻزم ﻧﻴﺴﺖ ﻧﻮع ﻣﻘﺪار ﺑﺮﮔﺮداﻧـﺪه ﺷـﺪه ﺗﻮﺳﻂ آن را ﻣﺸﺨﺺ ﻛﻨﻴﻢ ،زﻳﺮا اﻳﻦ ﻧﻮع ﻫﻢ اﻛﻨﻮن در ﺧﻮد ﺗﻌﺮﻳﻒ ﺧﺎﺻﻴﺖ ﺑﻪ ﺻﻮرت intﻣـﺸﺨﺺ ﺷـﺪه اﺳـﺖ .ﭘـﺲ دﺳـﺘﻮرات ﺑﻼك getﺑﺎﻳﺪ ﻣﻘﺪاري را از ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ ﺑﺮﮔﺮداﻧﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻫﻨﮕﺎﻣﻲ ﻛﻪ از اﻳﻦ ﺧﺎﺻﻴﺖ در ﺳـﻤﺖ راﺳـﺖ ﻋﻼﻣـﺖ ﻣـﺴﺎوي اﺳﺘﻔﺎده ﻛﻨﻴﻢ ،ﺑﺮﻧﺎﻣﻪ ﻧﻴﺎز دارد ﻛﻪ ﺑﻪ ﻣﻘﺪار آن دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﺪ ،ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ دﺳـﺘﻮرات ﺑﺨـﺶ getرا اﺟـﺮا ﻣﻲ ﻛﻨﺪ. دﺳﺘﻮرات ﺑﺨﺶ setزﻣﺎﻧﻲ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﺑﺨﻮاﻫﻴﻢ ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ را ﺗﻐﻴﻴﺮ دﻫﻴﻢ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ از اﻳـﻦ ﺧﺎﺻـﻴﺖ در ﺳـﻤﺖ ﭼﭗ ﻳﻚ ﺗﺴﺎوي اﺳﺘﻔﺎده ﻛﻨﻴﻢ ،ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ،setﺣﺎﺻﻞ ﻋﺒﺎرت ﺳﻤﺖ راﺳﺖ ﺗﺴﺎوي را در ﺧﺎﺻﻴﺖ ﻗﺮار ﻣﻲ دﻫﺪ .در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻧﺎم و ﻳﺎ ﻧﻮع داده اي ﻣﻘﺪاري ﻛﻪ ﺑﻪ ﺑﻼك setﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد را ﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﻧﻮع داده اي اﻳﻦ ﻣﻘـﺪار
١٧٨
ﻛﻪ ﺑﺮاﺑﺮ ﺑﺎ ﻧﻮع داده اي ﺧﺎﺻﻴﺖ ﺧﻮاﻫﺪ ﺑﻮد .ﻣﻘﺪار ﻓﺮﺳﺘﺎده ﺷﺪه ﻫﻢ ﺑﺎ ﻛﻠﻤﻪ ﻛﻠﻴـﺪي valueﺑـﻪ ﺑـﻼك setارﺳـﺎل ﻣـﻲ ﺷـﻮد. ﺑﻨﺎﺑﺮاﻳﻦ در ﺑﻼك setﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻣﻘﺪار ﻓﺮﺳﺘﺎده ﺷﺪه ،ﺑﺎﻳﺴﺘﻲ از ﻛﻠﻤﻪ ﻛﻠﻴﺪي valueاﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺷﺮوع ﻣﻲ ﺷﻮد ،ﻣﻘﺪار ﺧﺎﺻﻴﺖ Hourرا ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺪار ﻛﻨﻮﻧﻲ ﺳﺎﻋﺖ ﺳﻴﺴﺘﻢ ﻗﺮار ﻣﻲ دﻫﻴﻢ .ﺑـﺮاي دﺳﺘﺮﺳـﻲ ﺑـﻪ ﻣﻘﺪار ﻛﻨﻮﻧﻲ ﺳﺎﻋﺖ ﺳﻴﺴﺘﻢ ،ﻣﻲ ﺗﻮاﻧﻴﻢ از ﺧﺎﺻﻴﺖ Nowدر ﻛﻼس DateTimeاﺳﺘﻔﺎده ﻛﻨﻴﻢ: )private void Form1_Load(object sender, EventArgs e { // Set the hour property to the current hour ;this.Hour = DateTime.Now.Hour } ﻳﻜـﻲ از ﻣــﻮاﻗﻌﻲ ﻛــﻪ ﺑﺎﻳــﺪ ﺧﺎﺻــﻴﺖ Hourرا در ﻓــﺮم ﺗﻨﻈــﻴﻢ ﻛﻨﻴـﺪ ،زﻣــﺎﻧﻲ اﺳــﺖ ﻛــﻪ ﺧﺎﺻــﻴﺖ Valueﻣﺮﺑــﻮط ﺑــﻪ ﻛﻨﺘــﺮل DateTimePickerﺗﻐﻴﻴﺮ ﻣﻲ ﻛﻨﺪ ،ﻳﺎ ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻛﺎرﺑﺮ زﻣﺎن ﻧﻤﺎﻳﺶ داده ﺷﺪه در اﻳﻦ ﻛﻨﺘﺮل را ﺗﻐﻴﻴﺮ ﻣﻲ دﻫـﺪ .ﺑـﺮاي اﻳﻦ ﻛﺎر از ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ValueChangedﻛﻨﺘﺮل DateTimePickerاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ: private void dtpHour_ValueChanged(object sender,EventArgs )e { // Update the hour property ;this.Hour = dtpHour.Value.Hour } ﻫﻤﭽﻨﻴﻦ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺧﺎﺻﻴﺖ Hourدر ﻓﺮم ﺗﻐﻴﻴﺮ ﻛﺮد ﺑﺎﻳﺪ ﻣﻘﺪار ﻧﻤﺎﻳﺶ داده ﺷﺪه ﺗﻮﺳﻂ ﻛﻨﺘﺮل DateTimePickerو ﻧﻴﺰ ﻛﻨﺘﺮل ﻟﻴﺒﻞ را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺪار ﺟﺪﻳﺪ ﻗﺮار دﻫﻴﺪ .ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻣﻮرد را ﻣﻲ ﺗﻮاﻧﻴﺪ در ﺑﻼك setدر ﺧﺎﺻﻴﺖ وارد ﻛﻨﻴﺪ ﺗﺎ ﺑﺎ ﻫﺮ ﺑﺎر ﺗﻐﻴﻴﺮ ﻣﻘﺪار ،Hourاﺟﺮا ﺷﻮد. اوﻟﻴﻦ ﻣﻮردي ﻛﻪ ﺑﺎﻳﺪ در ﺑﻼك setﺗﻐﻴﻴﺮ دﻫﻴﺪ ،ﻣﻘـﺪار ﻛﻨﺘـﺮل DateTimePickerاﺳـﺖ .ﻣﻤﻜـﻦ اﺳـﺖ ﺗـﺼﻮر ﻛﻨﻴـﺪ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻣﻘﺪار ﺳﺎﻋﺖ اﻳﻦ ﻛﻨﺘﺮل از ﺧﺎﺻﻴﺖ Value.Hourاﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ ،ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ ﺗﻨﻈﻴﻢ اﻳـﻦ ﺧﺎﺻﻴﺖ ﻣﻮﺟﺐ ﺷﻮﻳﻢ ﻛﻪ ﻣﻘﺪار ﺟﺪﻳﺪي در اﻳﻦ ﻛﻨﺘﺮل ﻧﻤﺎﻳﺶ داده ﺷﻮد .اﻣﺎ ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ Hourاز ﻧﻮع ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ ﻫﺴﺘﻨﺪ و ﻧﻤﻲ ﺗﻮان آﻧﻬﺎ را ﺑﻪ ﺗﻨﻬﺎﻳﻲ ﺗﻨﻈﻴﻢ ﻛﺮد .ﺑﺮاي ﺗﻨﻈﻴﻢ ﻣﻘﺪار ﺳﺎﻋﺖ در اﻳﻦ ﻛﻨﺘﺮل ،ﺑﺎﻳﺪ ﻣﻘﺪار ﻛﻞ ﺧﺎﺻﻴﺖ Valueرا ﺗﻐﻴﻴـﺮ دﻫـﻴﻢ. ﺧﺎﺻﻴﺖ Valueﻳﻚ ﻣﺘﻐﻴﺮ از ﻧﻮع DateTimeرا درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي اﻳﻨﻜﻪ ﻓﻘﻂ ﻣﻘﺪار Hourرا ﺗﻐﻴﻴـﺮ دﻫـﻴﻢ، ﻳﻚ ﻣﺘﻐﻴﺮ ﺟﺪﻳﺪ از ﻧﻮع DateTimeﺗﻌﺮﻳﻒ ﻛﺮده و ﺗﻤﺎم ﻣﻘﺎدﻳﺮ آن ﺑﻪ ﺟﺰ ﻣﻘﺪار Hourرا ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺎدﻳﺮ ﻗﺒﻠﻲ ﻗﺮار ﻣﻲ دﻫﻴﻢ. ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﻣﺘﻐﻴﺮ ﺟﺪﻳﺪ از ﻧﻮع DateTimeاز دﺳﺘﻮر newاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ )در ﻓﺼﻞ 10ﺑﻪ ﻃﻮر ﻛﺎﻣﻞ ﺑﺎ اﻳﻦ دﺳﺘﻮر آﺷﻨﺎ ﻣﻲ ﺷﻮﻳﺪ( .ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﻣﺘﻐﻴﺮ ﺟﺪﻳﺪ از ﻧﻮع DateTimeﺑﺎﻳﺪ ﻣﻘﺎدﻳﺮ ﻣﺨﺘﻠﻒ زﻣﺎن را ﺑﺮاي آن ﻓـﺮاﻫﻢ ﻛـﺮد .ﻣﻘـﺪار ،Year Monthو Dayرا ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ Nowﻛﻼس DateTimeﺑﺪﺳﺖ ﻣـﻲ آورﻳـﻢ .ﺳـﺎﻋﺖ را ﺑﺮاﺑـﺮ ﺑـﺎ ﺳـﺎﻋﺖ ﻣـﻮرد ﻧﻈﺮﻣﺎن )ﺳﺎﻋﺖ ﻓﺮﺳﺘﺎده ﺷﺪه ﺑﻪ ﺧﺎﺻﻴﺖ (Hourﻗﺮار ﻣﻲ دﻫﻴﻢ و دﻗﻴﻘﻪ و ﺛﺎﻧﻴﻪ را ﻫﻢ ﺑﺮاﺑﺮ ﺑﺎ ﺻﻔﺮ در ﻧﻈﺮ ﻣﻲ ﮔﻴﺮﻳﻢ. // Set the date using the hour passed to this property dtpHour.Value = new DateTime(DateTime.Now.Year, ;)DateTime.Now.Month, DateTime.Now.Day, value, 0, 0
١٧٩
ﻣﺘﻦ ﻧﺸﺎن داده ﺷﺪه در ﻛﻨﺘﺮل ﻟﻴﺒﻞ اﺳﺖ ﻛﻪ ﺑﺎﻳﺪ ﻣﻘـﺪار ﺟﺪﻳـﺪ ﺳـﺎﻋﺖ را ﻧﻤـﺎﻳﺶ، ﺗﻐﻴﻴﺮ ﻛﻨﺪset دوﻣﻴﻦ ﻣﻮردي ﻛﻪ ﺑﺎﻳﺪ در ﺑﻼك :دﻫﺪ // Set the display text lblState.text = "At " + value + ":00 Matt is "; اﻳﻦ ﻣﻮرد را ﻧﻴﺰ اﻧﺠﺎم ﻣﻲ، در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ.در اﻳﻦ ﺑﺨﺶ ﻣﺸﺨﺺ ﻧﻜﺮدﻳﻢ ﻛﻪ ﻣﺖ در آن ﺳﺎﻋﺖ ﻣﺸﻐﻮل ﺑﻪ ﭼﻪ ﻛﺎري اﺳﺖ .دﻫﻴﻢ
:ﺗﻌﻴﻴﻦ ﻣﻮﻗﻴﺖ ﺑـﺮاي اﻳـﻦ ﻛـﺎر. ﻣﻮﻗﻌﻴﺖ ﻣﺖ را ﻣـﺸﺨﺺ ﻛـﺮد، ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ ﺗﻐﻴﻴﺮ ﺳﺎﻋﺖ،در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﻴﺪ و ﺳﭙﺲ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴـﺪ ﻛـﻪ ﻛـﺪاﻣﻴﻚ از ﻣﻘـﺎدﻳﺮ ﻣﻮﺟـﻮد درDateTimePicker ﺳﺎﻋﺖ را از ﻛﻨﺘﺮل . آن را ﺑﺮ روي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﺪ، ﺑﻌﺪ از ﺗﻌﻴﻴﻦ اﻳﻦ ﻣﻮرد. ﺑﺮاي اﻳﻦ ﺳﺎﻋﺖ ﻣﻨﺎﺳﺐ اﺳﺖDayAction ﺷﻤﺎرﻧﺪه
ﺗﻌﻴﻴﻦ ﻣﻮﻗﻌﻴﺖ:اﻣﺘﺤﺎن ﻛﻨﻴﺪ را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴـﺮHour ﺧﺎﺻﻴﺖset ﺑﺎز ﻛﻨﻴﺪ و ﻛﺪ ﻣﻮﺟﻮد در ﺑﻼكForm1 ( ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻣﺘﻦ را ﺑﺮاي1 :دﻫﻴﺪ set { // Set the date using the hour passed to this property dtpHour.Value = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, value, 0, 0); // Determine the state if (value >= 6 && value < 7) CurrentState = DayAction.GettingReadyForWork; else if (value > 7 && value < 8) CurrentState = DayAction.TravelingToWork; else if (value >= 8 && value < 13) CurrentState = DayAction.AtWork; else if (value >= 13 && value < 14) CurrentState = DayAction.AtLunch; else if (value >= 14 && value < 17) CurrentState = DayAction.AtWork; else if (value >= 17 && value < 18) CurrentState = DayAction.TravelingFromWork; else if (value >= 18 && value < 22)
١٨٠
;CurrentState = DayAction.RelaxingForFriends )else if (value >= 22 && value < 23 ;CurrentState = DayAction.GettingReadyForBed else ;CurrentState = DayAction.Asleep // Set the display text lblState.Text = "At " + value + ":00 Matt is " + ;CurrentState } (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي ﻋﻼﻣﺖ ﻫﺎي ﺑﺎﻻ و ﭘﺎﻳﻴﻦ ﻛﻨﺘﺮل DateTimePickerﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻧﺘﻴﺠﻪ اي را ﻣﺸﺎﺑﻪ ﺷﻜﻞ 8-5ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 8-5
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در ﺣﺎل ﻧﻮﺷﺘﻦ اﻳﻦ ﻛﺪﻫﺎ ،ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﻣﻘﺪار ﻣﺘﻐﻴﺮ CurrentStateرا ﺗﻨﻈﻴﻢ ﻛﻨﻴـﺪ ،ﻟﻴـﺴﺘﻲ در وﻳـﮋوال اﺳﺘﻮدﻳﻮ ﺑﺎز ﺷﺪه و ﻣﻘﺎدﻳﺮ ﻣﻤﻜﻦ ﺑﺮاي اﻳﻦ ﻣﺘﻐﻴﺮ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ )ﺷﻜﻞ .(9-5 وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﻣﻲ داﻧﺪ ﻛﻪ ﻣﺘﻐﻴﺮ CurrentSateاز ﻧﻮع DayActionﺗﻌﺮﻳﻒ ﺷـﺪه اﺳـﺖ .ﻫﻤﭽﻨـﻴﻦ وﻳـﮋوال اﺳﺘﻮدﻳﻮ ﻣﻲ داﻧﺪ ﻛﻪ DayActionﻳﻚ ﺷﻤﺎرﻧﺪه اﺳﺖ ﻛﻪ ﻫﺸﺖ ﻣﻘﺪار ﻣﺨﺘﻠﻒ را ﻣﻲ ﺗﻮاﻧﺪ در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ ،و ﻫﺮ ﻛـﺪام از اﻳﻦ ﻣﻘﺎدﻳﺮ در ﭘﻨﺠﺮه اي ﻛﻪ ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﻛﺪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ ﻧﺸﺎن داده ﻣﻲ ﺷﻮد.
ﺷﻜﻞ 9-5
١٨١
اﮔﺮ در ﻫﻨﮕﺎم ﻧﻤﺎﻳﺶ ﻣﻘﺪار CurrentStateدر ﻟﻴﺒﻞ ﻣﺘﻨﻬﺎي دﻳﮕﺮ را ﻧﻤﺎﻳﺶ ﻧﺪﻫﻴﺪ و ﻓﻘﻂ ﻣﺘﻐﻴﺮ CurrentState را در ﻟﻴﺒﻞ ﻗﺮار دﻫﻴﺪ ﻣﺎﻧﻨﺪ ﻛﺪ زﻳﺮ ،ﻫﻨﮕﺎم ﺧﻄﺎ ﺑﺎ ﻛﺎﻣﭙﺎﻳﻞ روﺑﺮو ﺧﻮاﻫﻴﺪ ﺷﺪ. ;lblState.Text = CurrentState اﻳﻦ ﺧﻄﺎ ﺑﻪ اﻳﻦ دﻟﻴﻞ اﺳﺖ ﻛﻪ ﻧﻮع ﻣﺘﻐﻴﺮ CurrentStateدر ﺣﻘﻴﻘﺖ از ﻧﻮع ﻋﺪد ﺻـﺤﻴﺢ اﺳـﺖ و ﻧﻤـﻲ ﺗﻮاﻧـﺪ ﺑـﻪ ﺻـﻮرت ﻣﺴﺘﻘﻴﻢ در ﻳﻚ ﻟﻴﺒﻞ ﻗﺮار ﺑﮕﻴﺮد .ﺑﺮاي اﻳﻦ ﻛﻪ اﻳﻦ ﻣﻘﺪار را در ﻟﻴﺒﻞ ﻗﺮار دﻫﻴﺪ ﺑﺎﻳﺪ آن را ﺑﻪ رﺷﺘﻪ ﺗﺒﺪﻳﻞ ﻛﻨﻴﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻳﻦ ﻣﺘﻐﻴﺮ را ﺑــﺎ دﻳﮕــﺮ رﺷــﺘﻪ ﻫــﺎ اﺳــﺘﻔﺎده ﻣــﻲ ﻛﻨﻴــﺪ )ﻫﻤﺎﻧﻨــﺪ ﻛــﺪ ﻧﻮﺷــﺘﻪ ﺷــﺪه در ﺑﺮﻧﺎﻣــﻪ( ،وﻳــﮋوال C#ﺑــﻪ ﺻــﻮرت اﺗﻮﻣﺎﺗﻴــﻚ ﻣﻘــﺪار CurrentStateرا ﺑــﻪ رﺷــﺘﻪ ﺗﺒــﺪﻳﻞ ﻣــﻲ ﻛﻨــﺪ و در ﻟﻴﺒــﻞ ﻗــﺮار ﻣــﻲ دﻫــﺪ .در ﻣــﻮاﻗﻌﻲ ﻛــﻪ ﻣــﻲ ﺧﻮاﻫﻴــﺪ ﻣﻘــﺪار CurrentStateرا ﺑﻪ ﺗﻨﻬﺎﻳﻲ ﻧﻤﺎﻳﺶ دﻫﻴﺪ ﺑﺎﻳﺴﺘﻲ ﺑﺎ اﺳﺘﻔﺎده از ﺗﺎﺑﻊ )( ToStringآن را ﺑﻪ رﺷـﺘﻪ ﺗﺒـﺪﻳﻞ ﻛﻨﻴـﺪ و ﺳﭙﺲ در ﻟﻴﺒﻞ ﻗﺮار دﻫﻴﺪ. اﺳﺘﻔﺎده از ﺷﻤﺎرﻧﺪه ﻫﺎ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﻳﻚ ﻋﺪد ﺧﺎص را از ﺑﻴﻦ ﻳﻚ ﺳﺮي ﻣﻘﺎدﻳﺮ ﻣﺸﺨﺺ اﻧﺘﺨﺎب ﻛﻨﻴـﺪ ﺑـﺴﻴﺎر ﻣﻨﺎﺳـﺐ اﺳـﺖ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﻴﺸﺘﺮ ﺑﺎ ﺗﻮاﺑﻊ و ﻛﻼﺳﻬﺎي داﺧﻠﻲ .NETﻛﺎر ﻛﻨﻴﺪ ،ﻣﺘﻮﺟﻪ ﺧﻮاﻫﻴﺪ ﺷﺪ ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﺑﺴﻴﺎري از ،.NETاز ﺷﻤﺎرﻧﺪه ﻫﺎ اﺳﺘﻔﺎده ﺷﺪه اﺳﺖ.
ﻣﻔﻬﻮم ﺛﺎﺑﺖ ﻫﺎ: ﻳﻜﻲ دﻳﮕﺮ از ﺗﻤﺮﻳﻦ ﻫﺎي ﺧﻮب ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻛﻪ ﺑﺎﻳﺪ ﺑﺎ آن آﺷﻨﺎ ﺷﻮﻳﺪ اﺳﺘﻔﺎده از ﺛﺎﺑﺖ ﻫﺎ اﺳﺖ .ﺗﺼﻮر ﻛﻨﻴﺪ در ﺣﺎل ﻧﻮﺷﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺮاي ﻣﺤﺎﺳﺒﻪ ﻣﺎﻟﻴﺎت ﺑﺮاي ﺣﻘﻮق ﻛﺎرﻣﻨﺪان ﻳﻚ ﺷﺮﻛﺖ ﻫﺴﺘﻴﺪ .در ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ،درﺻﺪ ﻣﺎﻟﻴﺎﺗﻲ ﻛﻪ ﺑﺎﻳﺪ از ﺣﻘـﻮق ﻫـﺮ ﻛﺎرﻣﻨـﺪ ﻛﻢ ﺷﻮد ﻓﺮﺿﺎً Aدرﺻﺪ اﺳﺖ .ﺑﻌﺪ از ﻣﺪﺗﻲ اﻳﻦ ﻣﻘﺪار ﺑﻪ ﻋﺪدي ﻣﺎﻧﻨﺪ Bﺗﻐﻴﻴﺮ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ .در اﻳﻦ ﺣﺎﻟﺖ ﺑﺎﻳﺪ ﺗﻤﺎم ﻗﺴﻤﺘﻬﺎﻳﻲ از ﺑﺮﻧﺎﻣﻪ ﻛﻪ ﻣﺎﻟﻴﺎت را Aدرﺻﺪ وارد ﻛﺮده اﻳﺪ ﭘﻴﺪا ﻛﻨﻴﺪ و ﻋﺪد Aرا ﺑﻪ Bﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺣﺎل اﮔﺮ ﺣﺠﻢ ﺑﺮﻧﺎﻣﻪ ﺑﺰرگ ﺑﺎﺷﺪ ،ﻛﺎر ﺑﺴﻴﺎر ﺧﺴﺘﻪ ﻛﻨﻨﺪه و ﻃﻮﻻﻧﻲ را ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﺪ .ﺑﺎ اﺳﺘﻔﺎده از ﺛﺎﺑﺖ ﻫﺎ در ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺑﺮوز ﭼﻨﻴﻦ ﻣﺸﻜﻼﺗﻲ ﺟﻠـﻮﮔﻴﺮي ﻛﻨﻴـﺪ .ﻫﻤﭽﻨـﻴﻦ ﺛﺎﺑـﺖ ﻫـﺎ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﺧﻮاﻧﺎﻳﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ اﻓﺰاﻳﺶ ﭘﻴﺪا ﻛﻨﺪ.
اﺳﺘﻔﺎده از ﺛﺎﺑﺖ ﻫﺎ: ﻓﺮض ﻛﻨﻴﺪ در ﺑﺮﻧﺎﻣﻪ ي زﻳﺮ دو ﻣﺘﺪ ﻣﺘﻔﺎوت ﻣﺎﻧﻨﺪ زﻳﺮ دارﻳﺪ و در ﻫﺮ ﻛﺪام ﻣﻲ ﺧﻮاﻫﻴﺪ ﻓﺎﻳﻞ ﻣﺸﺨﺼﻲ را ﺑﺎز ﻛﻨﻴـﺪ و روي آن ﻋﻤﻠﻴـﺎﺗﻲ اﻧﺠﺎم دﻫﻴﺪ: )(public void DoSomething { ?// What's the file name ;"string FileName = @"C:\Temp\Demo.txt // Open the file ... } )(public void DoSomethingElse
١٨٢
{ // What's the file name ;"string FileName = @"C:\Temp\Demo.txt // Open the file ... } در اﻳﻦ ﻛﺪ دو ﺛﺎﺑﺖ رﺷﺘﻪ اي ﺗﻌﺮﻳﻒ ﺷﺪه و ﻧﺎم ﻓﺎﻳﻞ در آﻧﻬﺎ ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ .اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺿﻌﻒ ﻫﺎي زﻳﺎدي دارد ،ﺑـﻪ اﻳـﻦ ﻋﻠﺖ ﻛﻪ ﻧﺎم ﻓﺎﻳﻞ در دو ﻣﺘﻐﻴﺮ ﻣﺠﺰا ﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ و اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻧﺎم ﻓﺎﻳﻞ را ﺗﻐﻴﺮ دﻫﻴﺪ ﺑﺎﻳﺪ در ﻫﺮ دو ﻣﺘﺪ ﺗﻐﻴﻴﺮ اﻳﺠﺎد ﻛﻨﻴﺪ. در اﻳﻦ ﻣﺜﺎل ﻫﺮ دو ﻣﺘﺪ در ﻛﻨﺎر ﻫﻢ ﻗﺮار دارﻧﺪ و ﺣﺠﻢ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﻛﻮﭼﻚ اﺳﺖ ،اﻣﺎ ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑـﺴﻴﺎر ﺑـﺰرگ ﺑﺎﺷـﺪ و از اﻳـﻦ رﺷﺘﻪ ﺑﺨﻮاﻫﻴﺪ در 50 ،10و ﻳﺎ ﺑﻴﺶ از 1000ﻗﺴﻤﺖ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻳﻦ ﺻﻮرت اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻧﺎم ﻓﺎﻳﻞ را ﺗﻐﻴﻴﺮ دﻫﻴـﺪ ،ﺑﺎﻳـﺪ در ﺗﻤـﺎم اﻳﻦ ﻗﺴﻤﺘﻬﺎ ﻧﺎم را ﻋﻮض ﻛﻨﻴﺪ .اﻳﻦ ﻣﻮرد ،دﻗﻴﻘﺎ ﻳﻜﻲ از ﻣﻮاردي اﺳﺖ ﻛﻪ ﻣﻮﺟﺐ ﺑﻪ وﺟﻮد آﻣﺪن ﺧﻄﺎﻫﺎي زﻳـﺎد در ﻧﻮﺷـﺘﻦ و ﻧﮕﻬـﺪاري ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺷﻮد. ﺑﺮاي رﻓﻊ اﻳﻦ ﻣﺸﻜﻞ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﻧﺎم ﻛﻠﻲ ﺑﺮاي اﻳﻦ ﺛﺎﺑﺖ رﺷﺘﻪ اي ﭘﻴﺪا ﻛﻨﻴﺪ و در ﺑﺮﻧﺎﻣﻪ از اﻳﻦ ﻧﺎم ﺑﻪ ﺟﺎي ﻧﺎم ﻓﺎﻳﻞ اﺳﺘﻔﺎده ﻛﻨﻴـﺪ. ﺑﻪ اﻳﻦ ﻛﺎر ﺗﻌﺮﻳﻒ ﻳﻚ "ﺛﺎﺑﺖ" ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ،ﺛﺎﺑﺖ ﻧﻮع ﺧﺎﺻﻲ از ﻣﺘﻐﻴﺮ اﺳﺖ ﻛﻪ ﻣﻘـﺪار آن در ﻃـﻮل ﺑﺮﻧﺎﻣـﻪ ﻗﺎﺑـﻞ ﺗﻐﻴﻴﺮ ﻧﻴﺴﺖ .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﺨﺶ ﺑﻌﺪ ،ﻧﺤﻮه ﺗﻌﺮﻳﻒ و اﺳﺘﻔﺎده از آﻧﻬﺎ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﺛﺎﺑﺘﻬﺎ (1ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﺑﺮﻧﺎﻣﻪ ﺗﺤﺖ وﻳﻨﺪوز ﺟﺪﻳﺪي اﻳﺠﺎد ﻛﺮده و ﻧﺎم آن را Constants Demoﻗﺮار دﻫﻴﺪ. (2در ﻣﺤﻴﻂ ﻃﺮاﺣﻲ ﻓﺮم ،ﺳﻪ ﻛﻨﺘﺮل Buttonﺑﺮ روي ﻓﺮم ﻗﺮار داده و ﺧﺎﺻـﻴﺖ Nameآﻧﻬـﺎ را ﺑـﻪ ﺗﺮﺗﻴـﺐ ﺑـﺎ ﻣﻘـﺎدﻳﺮ btnTwo ،btnOneو btnThreeﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ .ﺳﭙﺲ ﺧﺎﺻﻴﺖ Textاﻳﻦ ﻛﻨﺘﺮل ﻫـﺎ را ﺑﺮاﺑـﺮ ﺑـﺎ ،One Twoو Threeﻗﺮار دﻫﻴﺪ .ﺑﻌﺪ از اﻳﻦ ﻣﻮارد ﻓﺮم ﺷﻤﺎ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 10-5ﺑﺎﺷﺪ.
ﺷﻜﻞ 10-5 (3ﺑﻪ ﺑﺨﺶ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﺑﺮوﻳﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﺑﺎﻻي ﻛﺪ ﺑﻌﺪ از ﺗﻌﺮﻳﻒ ﻛﻼس From1ﻗﺮار دﻫﻴﺪ: public partial class Form1 : Form
١٨٣
{ // File name constant private const @"C:\Temp\Demo.txt";
string
strFileName
آنClick دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑـﻮط ﺑـﻪ روﻳـﺪادbtnOne ( ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ و ﺑﺮ روي دﻛﻤﻪ4 : ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ.اﻳﺠﺎد ﺷﻮد private void btnOne_Click(object sender, EventArgs e) { // Using a constant MessageBox.Show("1: " + strFileName, "Constants Demo"); } آن ﻧﻴﺰ اﻳﺠﺎدClick دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ روﻳﺪادbtnTwo ( ﻣﺠﺪدا ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ و روي دﻛﻤﻪ5 : ﺳﭙﺲ ﻛﺪ زﻳﺮ را در آن ﻣﺘﺪ وارد ﻛﻨﻴﺪ.ﺷﻮد private void btnTwo_Click(object sender, EventArgs e) { // Using a constant MessageBox.Show("2: " + strFileName, "Constants Demo"); } آن واردClick ( در آﺧﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن ﺳﻮم روي ﻓﺮم دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در ﻗـﺴﻤﺖ ﻣﺮﺑـﻮط ﺑـﻪ روﻳـﺪاد6 :ﻛﻨﻴﺪ private void btnThree_Click(object sender, EventArgs e) { // Using a constant MessageBox.Show("3: " + strFileName, "Constants Demo"); } . ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد11-5 ﻧﺘﻴﺠﻪ اي را ﻣﺸﺎﺑﻪ ﺷﻜﻞ.( ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن اول ﻛﻠﻴﻚ ﻛﻨﻴﺪ7
11-5 ﺷﻜﻞ ١٨٤
=
اﮔﺮ ﺑﺮ روي دﻛﻤﻪ ﻫﺎي ﻓﺮﻣﺎن دوم و ﺳﻮم ﻫﻢ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﻫﻤﻴﻦ ﻧﺎم ﻓﺎﻳﻞ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ،ﺛﺎﺑﺖ ﻫﺎ ﻫﻤﺎﻧﻨﺪ ﻣﺘﻐﻴﺮ ﻫﺎ ﻫﺴﺘﻨﺪ ﺑﺎ اﻳﻦ ﺗﻔﺎوت ﻛﻪ ﻣﻘﺪار آﻧﻬﺎ در ﻃﻮل اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻤﻲ ﺗﻮاﻧـﺪ ﺗﻐﻴﻴـﺮ ﻛﻨـﺪ .ﺗﻌﺮﻳـﻒ ﺛﺎﺑﺖ ﻫﺎ ﻫﻤﺎﻧﻨﺪ ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴﺮ ﻫﺎ اﺳﺖ ،ﺑﺎ اﻳﻦ ﺗﻔﺎوت ﻛﻪ ﻗﺒﻞ از ﺗﻌﺮﻳﻒ ﻧﻮع داده اي ﺑﺎﻳﺪ از ﻳﻚ ﻋﺒﺎرت constﻧﻴﺰ اﺳﺘﻔﺎده ﻛﺮد. // File name constant ;"private const string strFileName = @"C:\Temp\Demo.txt ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﺛﺎﺑﺘﻬﺎ ﻫﻢ ﻣﺎﻧﻨﺪ ﻣﺘﻐﻴﺮﻫﺎ داراي ﻳﻚ ﻧﻮع داده اي ﻫﺴﺘﻨﺪ و ﺑﺎﻳﺪ داراي ﻣﻘﺪار اوﻟﻴﻪ ﺑﺎﺷﻨﺪ ﻛﻪ ﻫﻨﮕﺎم ﺗﻌﺮﻳﻒ آن را ﻣـﺸﺨﺺ ﻣﻲ ﻛﻨﻴﻢ. ﺑﺮاي اﺳﺘﻔﺎده از ﺛﺎﺑﺘﻬﺎ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻣﺘﻐﻴﺮﻫﺎ ،ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﻧﺎم آﻧﻬﺎ را در ﺑﺮﻧﺎﻣﻪ وارد ﻛﻨﻴﻢ: )private void btnOne_Click(object sender, EventArgs e { // Using a constant MessageBox.Show("1: " + strFileName, "Constants ;)"Demo } ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻗﺒﻼ ﮔﻔﺘﻢ ،ﻣﺰﻳﺖ اﺳﺘﻔﺎده از ﺛﺎﺑﺘﻬﺎ در اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﺑﺎ ﺗﻐﻴﻴﺮ ﻗﺴﻤﺘﻲ از ﻛﺪ ،در ﺑﺨﺸﻬﺎي زﻳﺎدي از ﺑﺮﻧﺎﻣﻪ ﺗﻐﻴﺮ اﻳﺠﺎد ﻛﻨﻴﺪ .اﻟﺒﺘﻪ دﻗﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻣﻘﺎدﻳﺮ ﺛﺎﺑﺘﻬﺎ را ﻓﻘﻂ در ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﻛﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﻐﻴﻴﺮ دﻫﻴﺪ و ﻫﻨﮕﺎﻣﻲ ﻛـﻪ ﺑﺮﻧﺎﻣـﻪ در ﺣـﺎل اﺟﺮا ﺑﺎﺷﺪ اﻳﻦ ﻣﻘﺎدﻳﺮ ﺛﺎﺑﺖ ﻫﺴﺘﻨﺪ. ﻧﻜﺘﻪ :ﻣﻤﻜﻦ اﺳﺖ ﺗﻌﺮﻳﻒ ﻣﻔﻬﻮم ﺛﺎﺑﺖ در اﺑﺘﺪا ﻛﻤﻲ ﺧﻨﺪه دار ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ" ،ﺛﺎﺑﺖ ﻣﺘﻐﻴﺮي اﺳﺖ ﻛﻪ ﻣﻘﺪار آن ﻧﻤﻲ ﺗﻮاﻧﺪ ﺗﻐﻴﻴﺮ ﻛﻨـﺪ". اﻣﺎ اﻳﻦ ﺗﻌﺮﻳﻒ را ﻓﻘﻂ ﺑﺮاي درك ﺑﻬﺘﺮ اﻳﻦ ﻣﻔﻬﻮم ﺑﻪ ﻛﺎر ﺑﺮده ام .در ﺣﻘﻴﻘﺖ اﺳﺘﻔﺎده ﻛﺮدن و ﻳﺎ ﻧﻜﺮدن از ﺛﺎﺑﺖ ﻫﺎ ﻫﻴﭻ ﺗﻔـﺎوﺗﻲ در ﻛـﺪ ﻧﻬﺎﻳﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ )ﻛﺪ ﻣﺤﻠﻲ و ﻳﺎ ﻛﺪ (MSILو ﻳﺎ در ﺳﺮﻋﺖ اﺟﺮاي آن ﻧﺪارد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺛﺎﺑﺖ ﻫﺎ ﻓﻘﻂ ﺑـﺮاي اﻓـﺰاﻳﺶ ﺧﻮاﻧـﺎﻳﻲ ﺑﺮﻧﺎﻣﻪ و ﻫﻤﭽﻨﻴﻦ ﺳﺎدﮔﻲ ﺗﻐﻴﻴﺮات آﺗﻲ آن ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ .اﮔﺮ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ از ﺛﺎﺑﺘﻲ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ ﻛﺎﻣﭙﺎﻳﻠﺮ ﺗﻤـﺎم ﻛـﺪ ﺑﺮﻧﺎﻣﻪ را ﺟﺴﺘﺠﻮ ﻛﺮده و ﻫﺮ ﺟﺎ ﺑﻪ ﻧﺎم ﺛﺎﺑﺖ ﺑﺮﺧﻮرد ﻛﻨﺪ ،ﻣﻘﺪار آن را ﺑﺎ ﻣﻘﺪار ﻣﺸﺨﺺ ﺷﺪه ﺑﺮاي ﺛﺎﺑﺖ ﻋﻮض ﻣﻲ ﻛﻨﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺗﻌﺮﻳﻒ ﻳﻚ ﺛﺎﺑﺖ ﺑﺮ ﺧﻼف ﻣﺘﻐﻴﺮ ﻫﻴﭻ ﻓﻀﺎﻳﻲ از ﺑﺮﻧﺎﻣﻪ را در زﻣﺎن اﺟﺮا اﺷﻐﺎل ﻧﻤﻲ ﻛﻨﺪ.
ﺛﺎﺑﺘﻬﺎ ﺑﺎ ﻧﻮﻋﻬﺎي داده اي ﮔﻮﻧﺎﮔﻮن: در اﻳﻦ ﺑﺨﺶ ،ﻓﻘﻂ از ﻧﻮع داده اي رﺷﺘﻪ ﺑﺮاي ﺗﻌﺮﻳﻒ ﺛﺎﺑﺖ ﻫﺎ اﺳﺘﻔﺎده ﻛﺮدﻳﻢ ،اﻣﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي واﻗﻌﻲ از ﻫﺮ ﻧﻮع داده اي ﻛﻪ ﺗـﺎﻛﻨﻮن ﺑﺎ آن آﺷﻨﺎ ﺷﺪه اﻳﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮاي ﺗﻌﺮﻳﻒ ﻳﻚ ﺛﺎﺑﺖ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻟﺒﺘﻪ دﻗﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ اﺷﻴﺎﻳﻲ ﻛﻪ از ﻛﻼﺳﻬﺎ ﺑﻪ وﺟﻮد ﻣﻲ آﻳﻨﺪ )ﭼـﻪ
١٨٥
ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در .NETو ﭼﻪ ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ آﻧﻬﺎ را ﻣﻲ ﺳﺎزد( ﻧﻤﻲ ﺗﻮاﻧﻨﺪ در ﺛﺎﺑﺖ ﻫﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮﻧﺪ .در ﻣﻮرد ﻛﻼﺳﻬﺎ در ﻓﺼﻞ 9ﺑﻴﺸﺘﺮ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد. ﺑﺮاي ﻣﺜﺎل ،اﻋﺪاد ﺻﺤﻴﺢ ﻳﻜﻲ از ﻧﻮع ﻫﺎي داده اي ﻫﺴﺘﻨﺪ ﻛﻪ در ﺗﻌﺮﻳﻒ ﺛﺎﺑﺖ ﻫﺎ زﻳﺎد ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ: ;public const int intHourAsleepPerDay = 8
ﺳﺎﺧﺘﺎرﻫﺎ: ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﻧﺮم اﻓﺰار در ﺑﻴﺸﺘﺮ ﻣﻮاﻗﻊ ﻧﻴﺎز ﺧﻮاﻫﻴﺪ داﺷﺖ ﻣﻘﺪاري اﻃﻼﻋﺎت ﻛﻪ ﻫﺮ ﻛﺪام ﻧﻮع داده اي ﻣﺘﻔﺎوﺗﻲ دارﻧﺪ ،وﻟـﻲ ﻫﻤﮕـﻲ ﺑـﻪ ﻳﻚ ﻣﻮﺿﻮع ﻣﺮﺗﺒﻂ ﻣﻲ ﺷﻮﻧﺪ را در ﻳﻚ ﮔﺮوه ذﺧﻴﺮه ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺧﻮاﻫﻴﺪ اﻃﻼﻋﺎت ﻣﺮﺑـﻮط ﺑـﻪ ﻳـﻚ ﻣـﺸﺘﺮك از ﻗﺒﻴـﻞ ﻧـﺎم و آدرس او )از ﻧﻮع رﺷﺘﻪ اي( و ﻧﻴﺰ ﻣﻘﺪار داراﻳﻲ او )از ﻧﻮع ﻋﺪدي( را در ﻳﻚ ﮔﺮوه اﻃﻼﻋﺎت ذﺧﻴﺮه ﻛﻨﻴﺪ .ﺑﺮاي ﻧﮕﻬﺪاري ﭼﻨﻴﻦ اﻃﻼﻋﺎﺗﻲ، ﻳﻚ ﻛﻼس وﻳﮋه ﻃﺮاﺣﻲ ﻣﻲ ﻛﻨﻴﺪ و اﻃﻼﻋﺎت را در ﻳﻚ ﺷﻴﺊ از آن ﻛﻼس ﻗﺮار ﻣﻲ دﻫﻴﺪ ﻛﻪ اﻳﻦ روش در ﻓﺼﻞ 9ﺗﻮﺿـﻴﺢ داده ﻣـﻲ ﺷﻮد .اﻣﺎ روش دﻳﮕﺮ ﺑﺮاي ﻧﮕﻬﺪاري اﻳﻦ ﻣﺠﻤﻮﻋﻪ اﻃﻼﻋﺎت ،اﺳﺘﻔﺎده از ﺳﺎﺧﺘﺎرﻫﺎ اﺳﺖ .ﺳﺎﺧﺘﺎرﻫﺎ ﻧﻴﺰ ﻛﺎرﺑﺮدي ﻣﺎﻧﻨﺪ ﻛﻼﺳﻬﺎ دارﻧـﺪ اﻣـﺎ ﺳﺎده ﺗﺮ ﻫﺴﺘﻨﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ آﻧﻬﺎ را در اﻳﻦ ﻗﺴﻤﺖ ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد. ﺑﻌﺪﻫﺎ ﻫﻨﮕﺎم ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ،ﻧﻴﺎز ﺧﻮاﻫﻴﺪ داﺷﺖ ﻛﻪ ﺗﺼﻤﻴﻢ ﺑﮕﻴﺮﻳﺪ ﺑﺮاي ﻳﻚ ﺣﺎﻟﺖ ﺧﺎص ﺑﺎﻳﺪ از ﻛﻼﺳﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ و ﻳﺎ از ﺳﺎﺧﺘﺎرﻫﺎ. ﺑﻪ ﻋﻨﻮان ﻳﻚ ﻗﺎﻧﻮن ﻛﻠﻲ ﻫﻤﻮاره در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻣﺘﺪﻫﺎ ،ﺗﻮاﺑﻊ ،ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﻐﻴﺮﻫﺎي زﻳﺎدي را ﻛﻪ ﻫﻤﮕﻲ ﺑﻪ ﻫﻢ ﻣﺮﺗﺒﻂ ﻫﺴﺘﻨﺪ در ﻳﻚ ﮔﺮوه ﻗﺮار دﻫﻴﺪ ،ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ از ﻛﻼﺳﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﺳﺎﺧﺘﺎرﻫﺎ را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ .ﻓﻘﻂ در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ اﮔﺮ ﻳﻚ ﺳﺮي اﻃﻼﻋﺎت را در ﻳﻚ ﺳﺎﺧﺘﺎر ﻗﺮار دﻫﻴﺪ و ﭘﺲ از ﻣﺪﺗﻲ ﺑﺨﻮاﻫﻴﺪ آن را ﺑﻪ ﻳﻚ ﻛـﻼس ﺗﺒﺪﻳﻞ ﻛﻨﻴﺪ ،ﻣﺸﻜﻞ زﻳﺎدي را ﺧﻮاﻫﻴﺪ داﺷﺖ .ﭘﺲ ﺑﻬﺘﺮ اﺳﺖ ﻗﺒﻞ از ﺗﻌﺮﻳﻒ ﻛﻼس و ﻳﺎ ﺳﺎﺧﺘﺎر ،ﺑﻪ دﻗﺖ ﺑﺮرﺳﻲ ﻛﻨﻴﺪ ﻛـﻪ ﻛـﺪام ﻣـﻮرد ﺑﺮاي اﺳﺘﻔﺎده ﺷﻤﺎ ﻣﻨﺎﺳﺐ ﺗﺮ اﺳﺖ.
اﻳﺠﺎد ﺳﺎﺧﺘﺎرﻫﺎ: در اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ،ﺑﺎ ﻧﺤﻮه اﻳﺠﺎد ﻳﻚ ﺳﺎﺧﺘﺎر آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻳﻚ ﺳﺎﺧﺘﺎر (1ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﺑﺮﻧﺎﻣﻪ ﺗﺤﺖ وﻳﻨﺪوز ﺟﺪﻳﺪي ﺑﻪ ﻧﺎم Structure Demoاﻳﺠﺎد ﻛﻨﻴﺪ. (2ﺑﻌﺪ از اﻳﻦ ﻛﻪ ﭘﺮوژه اﻳﺠﺎد ﺷﺪ ،در ﭘﻨﺠﺮه Solution Explorerﺑﺮ روي ﻧﺎم ﭘﺮوژه ﻛﻠﻴـﻚ راﺳـﺖ ﻛـﺮده ،از ﻣﻨﻮي ﻧﻤﺎﻳﺶ داده ﺷﺪه ﮔﺰﻳﻨﻪ Addرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺳﭙﺲ از زﻳﺮ ﻣﻨﻮي ﺑﺎز ﺷـﺪه ﮔﺰﻳﻨـﻪ … Classرا اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ. ﭘﻨﺠﺮه اي ﺑﻪ ﻧﺎم Add New Item – Structure Demoﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ .در ﻗﺴﻤﺖ ﻧـﺎم، ﻋﺒﺎرت Customerرا وارد ﻛﺮده و ﺳﭙﺲ ﺑﺮ روي دﻛﻤﻪ Addﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ آﻳﺘﻢ ﺟﺪﻳﺪي ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﻮد. (3ﺑﻌﺪ از اﻳﻨﻜﻪ ﺻﻔﺤﻪ اي ﻛﻪ ﺟﺪﻳﺪاً اﻳﺠﺎد ﻛﺮده اﻳﺪ ﻧﻤﺎﻳﺶ داده ﺷﺪ ،ﻛﺪﻫﺎي داﺧﻞ آن را ﭘﺎك ﻛﻨﻴﺪ و ﻛﺪﻫﺎي زﻳﺮ را ﺑﻪ ﺟـﺎي آن وارد ﻛﻨﻴﺪ:
١٨٦
public struct Customer { // Public members ;public string FirstName ;public string LastName ;public string Email } ﻧﻜﺘﻪ :ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ ﻛﻪ ﺑﺨﺶ ﺗﻌﺮﻳﻒ ﻛﻼس ،ﺑﺎ ﺗﻌﺮﻳﻒ ﺳﺎﺧﺘﺎر ﺑﺎ ﻛﻠﻤﻪ ي ﻛﻠﻴﺪي structﺟﺎﻳﮕﺰﻳﻦ ﺷﺪه اﺳﺖ. (4ﺑﻪ ﺑﺨﺶ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ Form1ﺑﺮﮔﺮدﻳﺪ .ﭼﻬﺎر ﻛﻨﺘﺮل ،Labelﭼﻬﺎر ﻛﻨﺘﺮل TextBoxو ﻳـﻚ ﻛﻨﺘـﺮل Buttonﺑﺮ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ .اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ را ﺑﻪ ﻧﺤﻮي ﺑﺮ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ ﻛﻪ ﻓﺮم ﺷـﻤﺎ ﻣـﺸﺎﺑﻪ ﺷـﻜﻞ 12-5 ﺷﻮد. (5ﺧﺎﺻﻴﺖ Nameﻛﻨﺘﺮل ﻫﺎ را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ:
label1را ﺑﻪ lblNameﺗﻐﻴﻴﺮ دﻫﻴﺪ. textBox1را ﺑﻪ txtNameﺗﻐﻴﻴﺮ دﻫﻴﺪ. Label2را ﺑﻪ lblFirstNameﺗﻐﻴﻴﺮ دﻫﻴﺪ. textBox2را ﺑﻪ txtFirstNameﺗﻐﻴﻴﺮ دﻫﻴﺪ. Label3را ﺑﻪ lblLastNameﺗﻐﻴﻴﺮ دﻫﻴﺪ. textBox3را ﺑﻪ txtLastNameﺗﻐﻴﻴﺮ دﻫﻴﺪ. Label4را ﺑﻪ lblEmailﺗﻐﻴﻴﺮ دﻫﻴﺪ. textBox4را ﺑﻪ txtEmailﺗﻐﻴﻴﺮ دﻫﻴﺪ. Button1را ﺑﻪ ﺗﻐﻴﻴﺮ دﻫﻴﺪ.
(6ﺧﺎﺻﻴﺖ Textﻛﻨﺘﺮﻟﻬﺎي زﻳﺮ را ﺑﻪ ﻣﻘﺎدﻳﺮ ﻣﺸﺨﺺ ﺷﺪه ﺗﻐﻴﻴﺮ دﻫﻴﺪ:
ﻛﻨﺘﺮل lblNameرا ﺑﻪ Nameﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﻛﻨﺘﺮل lblFirstNameرا ﺑﻪ First Nameﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﻛﻨﺘﺮل lblLastNameرا ﺑﻪ Last Nameﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﻛﻨﺘﺮل lblEmailرا ﺑﻪ Emailﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﻛﻨﺘﺮل btnTestرا ﺑﻪ Testﺗﻐﻴﻴﺮ دﻫﻴﺪ.
١٨٧
12-5 ﺷﻜﻞ ﺳﭙﺲ ﻛـﺪﻫﺎي ﻣـﺸﺨﺺ، اﻳﻦ ﻛﻨﺘﺮل اﻳﺠﺎد ﺷﻮدClick دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ روﻳﺪادButton ( ﺑﺮ روي ﻛﻨﺘﺮل7 :ﺷﺪه در زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ private void btnTest_Click(object sender, EventArgs e) { // Create a new customer Customer objCustomer; objCustomer.FirstName = "Michael"; objCustomer.LastName = "Dell"; objCustomer.Email = "
[email protected]"; // Display the customer DisplayCustomer(objCustomer); } : وارد ﻛﻨﻴﺪForm1 ( ﺳﭙﺲ زﻳﺮﺑﺮﻧﺎﻣﻪ زﻳﺮ را در ﻛﻼس8 private void DisplayCustomer(Customer objCustomer) { // Display the customer details on the form txtFirstName.Text = objCustomer.FirstName; txtLastName.Text = objCustomer.LastName; txtEmail.Text = objCustomer.Email; } . را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد13-5 ﻧﺘﻴﺠﻪ اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ. ﻛﻠﻴﻚ ﻛﻨﻴﺪTest ( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ ي9
١٨٨
ﺷﻜﻞ 13-5
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺮاي ﺗﻌﺮﻳﻒ ﻳﻚ ﺳﺎﺧﺘﺎر ﺑﺎﻳﺪ از ﻛﻠﻤﻪ ﻛﻠﻴﺪي structدر C#اﺳﺘﻔﺎده ﻛﻨﻴﺪ .درون ﺑﻼك اﻳﻦ ﺳﺎﺧﺘﺎر ﺑﺎﻳـﺪ ﻣﺘﻐﻴﺮﻫـﺎﻳﻲ ﻛـﻪ ﻣـﻲ ﺧﻮاﻫﻴﺪ در اﻳﻦ ﮔﺮوه ﺑﺎﺷﻨﺪ را ﺑﻪ ﻫﻤﺮاه اﺳﻢ و ﻧﻮع داده اي آﻧﻬﺎ ﻣﺸﺨﺺ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﻋﻀﻮ ﻫﺎي اﻳﻦ ﺳﺎﺧﺘﺎر ﻣﻲ ﮔﻮﻳﻨﺪ. public struct Customer { // Public members ;public string FirstName ;public string LastName ;public string Email } ﺑﻪ ﻛﻠﻤﻪ ﻛﻠﻴﺪي publicدر ﻣﻘﺎﺑﻞ ﻫﺮ ﻳﻚ از ﻣﺘﻐﻴﻴﺮ ﻫﺎ و ﻫﻤﭽﻨﻴﻦ ﻗﺒﻞ از ﺧﻮد ﺗﻌﺮﻳﻒ ﺳﺎﺧﺘﺎر ﺗﻮﺟﻪ ﻛﻨﻴﺪ .در ﺑﺮﻧﺎﻣﻪ ﻫـﺎي ﻗﺒﻠـﻲ، ﻛﻠﻤﻪ privateﻧﻴﺰ ﻛﻪ ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴﺐ ﺑﻪ ﻛﺎر ﻣﻲ رﻓﺖ را دﻳﺪه ﺑﻮدﻳﺪ .ﻛﻠﻤﻪ publicﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﺷﻤﺎ در ﻛﺪﻫﺎي ﺧﺎرج از ﺳﺎﺧﺘﺎر Customerﻫﻢ ﻣﻴﺘﻮاﻧﻴﺪ ﺑﻪ ﻣﺘﻐﻴﺮﻫﺎي آن )ﻣﺎﻧﻨﺪ (FirstNameدﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ و ﻣﻘﺪار آن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ. در داﺧــﻞ ﻣﺘــﺪ btnTest_Clickﻣﺘﻐﻴــﺮي را از ﻧــﻮع داده اي Customerﺗﻌﺮﻳــﻒ ﻣــﻲ ﻛﻨﻴــﺪ .اﮔــﺮ ﺳــﺎﺧﺘﺎر Customerرا از ﻧﻮع ﻛﻼس ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﺮدﻳﺪ ،در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ ﻣﻘﺪار اوﻟﻴـﻪ آن را ﻧﻴـﺰ ﺑـﺎ اﺳـﺘﻔﺎده از ﻛﻠﻤـﻪ ﻛﻠﻴـﺪي new ﻣﺸﺨﺺ ﻣﻲ ﻛﺮدﻳﺪ .ﻧﺤﻮه اﻳﻦ ﻛﺎر در ﻓﺼﻞ 10ﺗﻮﺿﻴﺢ داده ﺷﺪه اﺳﺖ. )private void btnTest_Click(object sender, EventArgs e { // Create a new customer ;Customer objCustomer ﺑﻌﺪ از ﺗﻌﺮﻳﻒ اﻳـﻦ ﻣﺘﻐﻴـﺮ از ﻧـﻮع ،Customerﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﻪ ﻫـﺮ ﻳـﻚ از ﻣﺘﻐﻴﺮﻫـﺎي ﻣﻮﺟـﻮد در اﻳـﻦ ﺳـﺎﺧﺘﺎر ﺑـﺎ اﺳـﺘﻔﺎده از objCustomerدﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻧﺎم objCustomerرا وارد ﻛﺮدﻳﺪ ﻳﻚ ﻧﻘﻄﻪ ﻧﻴﺰ ﻗـﺮار دﻫﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺗﻤﺎم اﻋﻀﺎي اﻳﻦ ﺳﺎﺧﺘﺎر ﺑﻪ وﺳﻴﻠﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﻨﺪ ﺷﺪ و ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﻘﺪار ﻫـﺮ ﻳـﻚ از آﻧﻬـﺎ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ. ١٨٩
;"objCustomer.FirstName = "Michael ;"objCustomer.LastName = "Dell ;"objCustomer.Email = "
[email protected] // Display the customer ;)DisplayCustomer(objCustomer } در اﻧﺘﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻫﻢ ﻣﺘﺪ DisplayCustomerرا ﻣـﻲ ﻧﻮﻳـﺴﻴﻢ .وﻇﻴﻔـﻪ اﻳـﻦ ﻣﺘـﺪ اﻳـﻦ اﺳـﺖ ﻛـﻪ ﻳـﻚ ﺳـﺎﺧﺘﺎر از ﻧـﻮع Customerرا ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ورودي درﻳﺎﻓﺖ ﻛﻨﺪ و ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻣﻘـﺎدﻳﺮ وارد ﺷـﺪه در اﻋـﻀﺎي اﻳـﻦ ﺳـﺎﺧﺘﺎر ﺧﺎﺻـﻴﺖ Textﻫﺮ ﻛﺪام از TextBoxﻫﺎي روي ﻓﺮم را ﺗﻨﻈﻴﻢ ﻛﻨﺪ. )private void DisplayCustomer(Customer objCustomer { // Display the customer details on the form ;txtFirstName.Text = objCustomer.FirstName ;txtLastName.Text = objCustomer.LastName ;txtEmail.Text = objCustomer.Email }
اﺿﺎﻓﻪ ﻛﺮدن ﺧﺎﺻﻴﺖ ﺑﻪ ﺳﺎﺧﺘﺎرﻫﺎ: ﻫﻨﮕﺎم ﺗﻌﺮﻳﻒ ﻳﻚ ﺳﺎﺧﺘﺎر ،ﻋﻼوه ﺑﺮ ﻣﺘﻐﻴﺮ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺧﺎﺻﻴﺖ ﻧﻴﺰ ﺑﺮاي آن ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ .ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﺧﺎﺻﻴﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻫﻤﺎن روﺷﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ Enum Demoﺑﻪ ﻛﺎر ﺑﺮدﻳﻢ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ﭼﮕﻮﻧﮕﻲ اﻳﻦ ﻛﺎر را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﺧﺎﺻﻴﺖ Name (1وﻳﺮاﻳﺸﮕﺮ ﻛﺪ را ﺑﺮاي ﺳﺎﺧﺘﺎر Customerﺑﺎز ﻛﻨﻴﺪ و ﺳﭙﺲ ﻛﺪ زﻳﺮ را ﺑﻪ اﻳﻦ ﺳﺎﺧﺘﺎر اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ ﺗـﺎ ﻳـﻚ ﺧﺎﺻـﻴﺖ ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ ﺑﻪ اﻳﻦ ﺳﺎﺧﺘﺎر اﺿﺎﻓﻪ ﺷﻮد: // Public members ;public string FirstName ;public string LastName ;public string Email // Name Property public string Name { get { ١٩٠
;return FirstName + " " + LastName } } ﻧﻜﺘﻪ :ﺧﺎﺻﻴﺘﻬﺎي ﻳﻚ ﻛﻼس و ﻳﺎ ﻳﻚ ﺳﺎﺧﺘﺎر ﺑﻪ ﺳﻪ ﺻﻮرت ﻣﻲ ﺗﻮاﻧﻨﺪ ﺗﻌﺮﻳﻒ ﺷﻮﻧﺪ :ﻳﺎ ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ ﺑﺎﺷﻨﺪ ،ﻳﺎ ﻓﻘﻂ-ﻧﻮﺷﺘﻨﻲ ﺑﺎﺷﻨﺪ و ﻳﺎ ﺧﻮاﻧﺪﻧﻲ-ﻧﻮﺷﺘﻨﻲ ﺑﺎﺷﻨﺪ .ﺑﺮاي اﻳﻦ ﻛﻪ ﺑﺘﻮان ﻣﻘﺪار ﻳﻚ ﺧﺎﺻﻴﺖ را ﺗﻨﻈﻴﻢ ﻛﺮد ﺑﺎﻳﺪ ﺑﺨﺶ setرا در آن ﻗـﺮار داد .ﺑـﺮاي اﻳـﻦ ﻛـﻪ ﺑﺘﻮان ﻣﻘﺪار ﻛﻨﻮﻧﻲ آن را ﺑﺪﺳﺖ آورد ﺑﺎﻳﺪ ﺑﺨﺶ getرا در آن وارد ﻛﺮد .اﮔﺮ ﻳﻚ ﺧﺎﺻﻴﺖ داراي ﻫﺮ دو ﺑﺨﺶ ﺑﺎﺷﺪ ،ﺧﺎﺻﻴﺖ از ﻧـﻮع ﺧﻮاﻧﺪﻧﻲ-ﻧﻮﺷﺘﻨﻲ ﺧﻮاﻫﺪ ﺑﻮد .در اﻳﻦ ﻗﺴﻤﺖ ﺑﺮاي اﻳﻦ ﻛﻪ ﺧﺎﺻﻴﺖ ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ ﺑﺎﺷﺪ ،ﻗﺴﻤﺖ setرا ﺑﺮاي آن ﻗﺮار ﻧـﺪادﻳﻢ و ﻓﻘـﻂ ﺑﺨﺶ getدر آن ﻧﻮﺷﺘﻴﻢ. (2اﻛﻨﻮن وﻳﺮاﻳﺸﮕﺮ ﻛﺪ را ﺑﺮاي Form1ﺑﺎز ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳـﺮ را ﺑـﻪ ﻣﺘـﺪ DisplayCustomer اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )private void DisplayCustomer(Customer objCustomer { // Display the customer details on the form ;txtName.Text = objCustomer.Name ;txtFirstName.Text = objCustomer.FirstName ;txtLastName.Text = objCustomer.LastName ;txtEmail.Text = objCustomer.Email } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ ي Testﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﺎدر Nameﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ )ﺷﻜﻞ (13-5ﺧﺎﻟﻲ ﻣﻲ ﻣﺎﻧﺪ ،ﺣﺎﻻ ﺑﺎ ﻧﺎم و ﻧﺎم ﺧﺎﻧﻮادﮔﻲ ﻣﺸﺘﺮك ﭘﺮ ﻣﻲ ﺷﻮد.
ﻛﺎر ﺑﺎ ﻟﻴﺴﺖ ﻫﺎي ﭘﻴﻮﻧﺪي: ﻓﺮض ﻛﻨﻴﺪ ﻛﻪ ﻣﻴﺨﻮاﻫﻴﺪ ﻟﻴﺴﺘﻲ از اﻃﻼﻋﺎت ﺗﻤﺎم ﻣﺸﺘﺮﻛﻴﻦ ﺧﻮد داﺷﺘﻪ ﺑﺎﺷﻴﺪ .در اﻳﻦ ﺣﺎﻟﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ از آراﻳﻪ ﻫـﺎ اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ ،اﻣـﺎ ﻫﻤﻴﺸﻪ ﻫﻢ ﻛﺎر ﺑﺎ آراﻳﻪ ﻫﺎ ﭼﻨﺪان ﺳﺎده ﻧﻴﺴﺖ.
اﮔﺮ ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻳﻚ ﻣﺸﺘﺮك ﺟﺪﻳﺪ را ﺑﻪ آراﻳﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ اﻧﺪازه آراﻳﻪ را ﺗﻐﻴﻴﺮ دﻫﻴـﺪ و ﺳـﭙﺲ ﻣـﺸﺘﺮك را ﺑـﻪ اﻧﺘﻬﺎي آراﻳﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ آراﻳﻪ اي ﺟﺪﻳﺪ ﻛﻪ ﻳﻚ واﺣﺪ ﺑﺰرﮔﺘﺮ از آراﻳﻪ ﻛﻨﻮﻧﻲ اﺳﺖ اﻳﺠـﺎد ﻛﻨﻴـﺪ و ﺳـﭙﺲ ﺗﻤﺎم ﻋﻨﺎﺻﺮ آراﻳﻪ ﻛﻨﻮﻧﻲ را ﺑﻪ آراﻳﻪ ﺟﺪﻳﺪ ﻣﻨﺘﻘﻞ ﻛﻨﻴﺪ و ﻣﺸﺘﺮك ﺟﺪﻳﺪ را ﻧﻴﺰ ﺑﻪ آراﻳﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .در اﻧﺘﻬﺎ ﻧﻴﺰ آراﻳﻪ اول را از ﺑﻴﻦ ﺑﺒﺮﻳﺪ. اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻳﻚ ﻣﺸﺘﺮك را از آراﻳﻪ ﺣﺬف ﻛﻨﻴﺪ ﺑﺎﻳﺪ ﺑﻪ ﺻﻮرت ﺧﻄﻲ در ﺗﻤﺎم ﻋﻨﺎﺻﺮ آراﻳﻪ ﺑﻪ دﻧﺒﺎل ﻣﺸﺘﺮك ﺑﮕﺮدﻳﺪ و ﭘـﺲ از ﭘﻴﺪا ﻛﺮدن ﻣﻜﺎن آن ،ﺗﻤﺎم ﻋﻨﺎﺻﺮ اﻳﻦ آراﻳﻪ را ﺑﻪ ﺟﺰ ﻋﻨﺼﺮي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺣﺬف ﻛﻨﻴﺪ ،در ﻳﻚ آراﻳﻪ ﺟﺪﻳﺪ ﻗﺮار دﻫﻴﺪ و آراﻳﻪ ﻛﻨﻮﻧﻲ را از ﺑﻴﻦ ﺑﺒﺮﻳﺪ. ﺑﺮاي اﻳﻦ ﻛﻪ ﻳﻜﻲ از ﻣﺸﺘﺮﻛﻴﻦ ﻟﻴﺴﺖ را ﺑﺎ ﻣﺸﺘﺮك دﻳﮕﺮي ﺗﻌﻮﻳﺾ ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ ﻣﺸﺘﺮك اول را در آراﻳﻪ ﭘﻴﺪا ﻛﻨﻴﺪ و ﺳﭙﺲ ﺑﻪ ﺻﻮرت دﺳﺘﻲ ﻣﺸﺘﺮك اول را ﺑﺎ ﻣﺸﺘﺮك دوم ﺟﺎ ﺑﻪ ﺟﺎ ﻛﻨﻴﺪ.
١٩١
ﺑﺎ اﺳﺘﻔﺎده از ﻟﻴﺴﺖ ﻫﺎي ﭘﻴﻮﻧﺪي در .NETﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻛﻼس ArrayListﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﻫﺴﺘﻨﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑـﻪ راﺣﺘـﻲ در ﻃﻮل ﺑﺮﻧﺎﻣﻪ آراﻳﻪ ﻫﺎ را ﻛﻨﺘﺮل ﻛﻨﻴﺪ.
اﺳﺘﻔﺎده از ﻟﻴﺴﺖ ﻫﺎي ﭘﻴﻮﻧﺪي: ﻧﺤﻮه اﺳﺘﻔﺎده از ﻟﻴﺴﺖ ﻫﺎي ﭘﻴﻮﻧﺪي در اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ﺷﺮح داده ﺷﺪه اﺳﺖ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﻟﻴﺴﺖ ﻫﺎي ﭘﻴﻮﻧﺪي (1ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ و ﻳﻚ ﻛﻨﺘﺮل ListBoxرا ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﻣﻜـﺎن ﻛﻨﺘـﺮل ﻫـﺎي روي ﻓـﺮم را ﺑـﻪ ﻧﺤــﻮي ﺗﻐﻴﻴــﺮ دﻫﻴــﺪ ﻛــﻪ ﻓــﺮم ﺷــﻤﺎ ﻣــﺸﺎﺑﻪ ﺷــﻜﻞ 14-5ﺷــﻮد .ﺧﺎﺻــﻴﺖ Nameاﻳــﻦ ListBoxرا ﺑﺮاﺑــﺮ ﺑــﺎ lstCustomersو ﺧﺎﺻﻴﺖ IntegralHeightآن را ﺑﺮاﺑﺮ ﺑﺎ Falseﻗﺮار دﻫﻴﺪ. ﻧﻜﺘﻪ :ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻠﻴﺪ Ctrl+Aﺗﻤﺎم ﻛﻨﺘﺮل ﻫﺎي روي ﻓﺮم را اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺳﭙﺲ آﻧﻬﺎ را ﺑﻪ ﻣﻮﻗﻌﻴﺖ ﺟﺪﻳﺪﺷﺎن ﺑﺒﺮﻳﺪ.
ﺷﻜﻞ 14-5 (2وﻳﺮاﻳﺸﮕﺮ ﻛﺪ را ﺑﺮاي Form1ﺑﺎز ﻛﺮده و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﺑﺘﺪاي ﻛﻼس ،Form1ﺑﻌﺪ از ﺗﻌﺮﻳﻒ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ: public partial class Form1 : Form { // Form level members
١٩٢
private ArrayList objCustomers = new ArrayList(); ﺑﻪ ﻋﺒﺎرت دﻳﮕـﺮ اﻳـﻦ ﻛـﻼس را ﺟـﺰ، را ﻛﺎﻣﻞ ﻧﻜﺮدArrayList وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﺎم ﻛﻼس، اﮔﺮ ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ اﻳﻦ ﻛﺪ:ﻧﻜﺘﻪ اﻳــﻦ ﻛــﻼس در ﻓــﻀﺎي ﻧــﺎم.ﻛﻼﺳــﻬﺎي ﺗﻌﺮﻳــﻒ ﺷــﺪه ﻧﺪاﺷــﺖ ﺑﺎﻳــﺴﺘﻲ ﻓــﻀﺎي ﻧــﺎم آن را ﺑــﻪ ﺑﺮﻧﺎﻣــﻪ ﺧــﻮد اﺿــﺎﻓﻪ ﻛﻨﻴــﺪ ﺑـﺮاي. ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻣﻲ ﺷﻮدusing ﻳﻚ ﻓﻀﺎي ﻧﺎم ﺑﺎ اﺳﺘﻔﺎده از ﻛﻠﻤﻪ ﻛﻠﻴﺪي. ﻗﺮار داردSystem.Collection ﺑﺮوﻳـﺪ و ﻛـﺪForm1 ﺑﻪ ﺑﺎﻻﺗﺮﻳﻦ ﺧﻂ در ﻗﺴﻤﺖ ﻛﺪﻫﺎي ﻣﺮﺑﻮط ﺑﻪ،System.Collection اﺿﺎﻓﻪ ﻛﺮدن ﻓﻀﺎي ﻧﺎم :زﻳﺮ را وارد ﻛﻨﻴﺪ using System.Collections; . ﺑﻴﺸﺘﺮ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮدusing در ﻓﺼﻞ ﻧﻬﻢ در راﺑﻄﻪ ﺑﺎ ﻛﻠﻤﻪ ﻛﻠﻴﺪي :( ﺣﺎل ﻣﺘﺪ زﻳﺮ را ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﻣﺸﺘﺮك ﺟﺪﻳﺪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ3 public void CreateCustomer(string FirstName, string LastName, string Email) { // Declare a customer object Customer objNewCustomer; // Create the new customer objNewCustomer.FirstName = FirstName; objNewCustomer.LastName = LastName; objNewCustomer.Email = Email; // Add the new customer to the list objCustomers.Add(objNewCustomer); // Add the new customer to the ListBox control lstCustomers.Items.Add(objNewCustomer); } : را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪbtnTest_Click ( ﺳﭙﺲ ﻣﺘﺪ4 private void btnTest_Click(object sender, EventArgs e) { // Create some customers CreateCustomer("Darrel", "Hilton", "
[email protected]"); CreateCustomer("Frank", "Peoples", "
[email protected]"); CreateCustomer("Bill", "Scott", "
[email protected]"); } ١٩٣
(5ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ ي Testﻛﻠﻴﻚ ﻛﻨﻴﺪ ﻧﺘﻴﺠﻪ اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 15-5را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 15-5 ﺷﻤﺎ ﭼﻨﺪﻳﻦ ﻣﺘﻐﻴﺮ از ﺳﺎﺧﺘﺎر Customerرا ﺑﻪ ﻟﻴﺴﺖ اﺿﺎﻓﻪ ﻛﺮدﻳﺪ ،اﻣﺎ ﭼﻴﺰي ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻛﻨﺘـﺮل ListBoxﻧﻤـﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﭼﻨﺪﻳﻦ ﻋﺒﺎرت Customerاﺳﺖ .ﻛﻨﺘﺮل ListBoxﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺪ ﻣﻘﺎدﻳﺮ رﺷﺘﻪ اي را ﺑﻪ ﻟﻴﺴﺖ ﺧﻮد اﺿـﺎﻓﻪ ﻛﻨـﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻣﺘﻐﻴﺮ از ﺳﺎﺧﺘﺎر Customerرا ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل ﻣﻲ ﻓﺮﺳﺘﻴﺪ ،وﻳﮋوال C#ﻣﺘﺪ )( ToStringرا ﺑﺮاي اﻳـﻦ ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ .ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض ،اﻳﻦ ﻣﺘﺪ ﻧﺎم ﺳﺎﺧﺘﺎر و ﻳﺎ ﻛﻼس را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ ﻧﻪ ﻣﺤﺘﻮﻳﺎﺗﻲ از آن ﺳـﺎﺧﺘﺎر را ﻛـﻪ ﺷﻤﺎ ﻣﻲ ﺧﻮاﻫﻴﺪ .ﻛﺎري ﻛﻪ در اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻣﺘﺪ )( ToStringرا ﺑﻪ ﻧﺤﻮي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ ﻋﺒـﺎرت ﺑﺎ ﻣﻌﻨﻲ ﺗﺮي را ﺑﺮﮔﺮداﻧﺪ .ﭼﮕﻮﻧﮕﻲ اﻳﻦ ﻛﺎر را در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺑﺎزﻧﻮﻳﺴﻲ ﻣﺘﺪ )(ToString (1ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﺑﺮاي ﺳﺎﺧﺘﺎر Customerرا ﺑﺎز ﻛﺮده و ﻛﺪ زﻳﺮ در اﻳﻦ ﺳﺎﺧﺘﺎر ،ﺑﻌﺪ از ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﺮ ﻫﺎ ﻗﺮار دﻫﻴﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻛﺪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،اﻳﻦ ﺗﺎﺑﻊ داراي XML Document Commentاﺳﺖ .از ﻓـﺼﻞ ﺳـﻪ ﺑـﻪ ﺧﺎﻃﺮ دارﻳﺪ ﻛﻪ ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن اﻳﻦ ﻧﻮع ﺗﻮﺿﻴﺤﺎت ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ از ﺳﻪ ﻛﺎراﻛﺘﺮ /ﻣﺘﻮاﻟﻲ ﻗﺒﻞ از ﻣﺘﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. >/// <summary /// Overrides the default ToString method >/// ///
StringReturns the customer name and email >address
١٩٤
;" )" return Name + " (" + Email + } (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ ي Testﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻧﺘﻴﺠﻪ اي را ﻣﺸﺎﺑﻪ ﺷﻜﻞ 16-5ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 16-5
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻣﺘﻐﻴﺮ از ﻧﻮع داده اي Customerﺑﻪ ﻟﻴﺴﺖ اﺿﺎﻓﻪ ﺷﻮد ،ﻛﻨﺘﺮل ListBoxﺗﺎﺑﻊ ToSringاﻳﻦ ﻣﺘﻐﻴـﺮ را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده و رﺷﺘﻪ اي ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ ﺗﺎﺑﻊ ﺑﺮﮔﺮداﻧﺪه ﻣﻲ ﺷﻮد را درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ .در اﻳـﻦ ﻛـﺪ ،ﻣﺘـﺪ ToStringرا ﺑـﻪ ﺻﻮرﺗﻲ ﺑﺎزﻧﻮﻳﺴﻲ ﻛﺮدﻳﻢ ﻛﻪ ﺑﻪ ﺟﺎي ﺑﺮﮔﺮداﻧﺪن ﻧﺎم ﺧﻮد ﺳﺎﺧﺘﺎر ،ﻳﻚ ﻋﺒﺎرت ﺑﺎ ﻣﻌﻨﻲ را ﻧﻤﺎﻳﺶ دﻫﺪ. >/// <summary /// Overrides the default ToString method >/// ///
StringReturns the customer name and email >address
١٩٥
را، از ﻫﺮ ﻧﻮﻋﻲ ﻛﻪ ﺑﺎﺷـﻨﺪ، ﻣﻲ ﺗﻮاﻧﺪ ﻟﻴﺴﺘﻲ از اﺷﻴﺎ و ﻳﺎ ﺳﺎﺧﺘﺎرﻫﺎ، اﻳﺠﺎد ﻣﻲ ﺷﻮدArrayList ﻳﻚ ﻟﻴﺴﺖ ﭘﻴﻮﻧﺪي ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﻲ ﺗﻮاﻧﻴﺪ اﺷﻴﺎﻳﻲ از ﻧﻮع ﻫﺎي ﮔﻮﻧﺎﮔﻮن را در اﻳﻦ ﻟﻴﺴﺖ ذﺧﻴﺮه ﻛﻨﻴﺪ )اﻳﻦ ﻣﻮرد ﻣﻘﺪاري ﺟﻠﻮﺗﺮ در.در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ اﻳﺠﺎد ﻛﺮدﻳﻢ ﻛﻪ ﺑﺮ اﺳـﺎس ﭘﺎراﻣﺘﺮﻫـﺎﻳﻲCreateCustomer در اﻳﻦ ﻣﺜﺎل ﻣﺘﺪي ﺑﻪ ﻧﺎم.(اﻳﻦ ﻓﺼﻞ ﺑﻴﺸﺘﺮ ﺗﻮﺿﻴﺢ داده ﺷﺪه : را اﻳﺠﺎد ﻣﻲ ﻛﺮدCustomer ﻳﻚ ﻣﺘﻐﻴﺮ از ﻧﻮع،ﻛﻪ ﺑﻪ آن ﻓﺮﺳﺘﺎده ﺷﺪه ﺑﻮد public void CreateCustomer(string FirstName, string LastName, string Email) { // Declare a customer object Customer objNewCustomer; // Create the new customer objNewCustomer.FirstName = FirstName; objNewCustomer.LastName = LastName; objNewCustomer.Email = Email; ﺑــﻪ ﻧــﺎمArrayList آن را ﺑــﻪ ﻟﻴــﺴﺖ ﭘﻴﻮﻧــﺪﻳﻲ ﻛــﻪ از ﻛــﻼس،ﻫﻨﮕــﺎﻣﻲ ﻛــﻪ ﻣﺘﻐﻴــﺮ ﻣــﻮرد ﻧﻈﺮﻣــﺎن را اﻳﺠــﺎد ﻛــﺮدﻳﻢ . اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﻢ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢobjCustomers // Add the new customer to the list objCustomers.Add(objNewCustomer); :ﻫﻤﭽﻨﻴﻦ ﻣﺘﻐﻴﺮ اﻳﺠﺎد ﺷﺪه را ﺑﻪ ﻛﻨﺘﺮل ﻟﻴﺴﺖ ﺑﺎﻛﺲ ﻧﻴﺰ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ آن را ﻧﻤﺎﻳﺶ دﻫﺪ // Add the new customer to the ListBox control lstCustomers.Items.Add(objNewCustomer); } ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ آن ﻳﻚ ﻣﺸﺘﺮك ﺟﺪﻳﺪ ﺗﻌﺮﻳﻒ ﻛﺮده و آن را ﺑﻪ، را ﺗﻌﺮﻳﻒ ﻛﺮدﻳﺪCreateCustomer ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺘﺪ :ﻟﻴﺴﺖ ﺑﺎﻛﺲ ﻧﻴﺰ اﺿﺎﻓﻪ ﻛﻨﻴﺪ private void btnTest_Click(object sender, EventArgs e) { // Create some customers CreateCustomer("Darrel", "Hilton", "
[email protected]"); CreateCustomer("Frank", "Peoples", "
[email protected]"); CreateCustomer("Bill", "Scott", "
[email protected]"); }
١٩٦
:ﺣﺬف ﻳﻚ ﻋﻨﺼﺮ از ﻟﻴﺴﺖ ﻫﺎي ﭘﻴﻮﻧﺪي ﻛﺎرﻫﺎﻳﻲ ﻛﻪ اﻧﺠﺎم آﻧﻬـﺎ ﺑـﺎ، در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺒﻠﻲ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻧﻮع ﻟﻴﺴﺖ ﻫﺎ.ﺗﺎﻛﻨﻮن ﺑﺎ ﻣﺒﺎﻧﻲ ﻛﺎر ﺑﺎ ﻟﻴﺴﺖ ﻫﺎي ﭘﻴﻮﻧﺪي آﺷﻨﺎ ﺷﺪﻳﺪ در. ﺑﺮاي ﻣﺜﺎل ﺗﻮاﻧﺴﺘﻴﻢ ﭼﻨﺪﻳﻦ ﻋﻨﺼﺮ ﺟﺪﻳﺪ را ﺑﻪ راﺣﺘﻲ ﺑﻪ اﻳﻦ ﻟﻴﺴﺖ اﺿﺎﻓﻪ ﻛﻨـﻴﻢ.آراﻳﻪ ﻫﺎ ﺑﺴﻴﺎر ﻣﺸﻜﻞ ﺑﻮد را ﺑﻪ راﺣﺘﻲ اﻧﺠﺎم دادﻳﻢ .اﻳﻦ ﺑﺨﺶ ﭼﮕﻮﻧﮕﻲ ﭘﺎك ﻛﺮدن ﺑﻌﻀﻲ از ﻋﻨﺎﺻﺮ ﻳﻚ ﻟﻴﺴﺖ را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد
ﭘﺎك ﻛﺮدن ﻣﺸﺘﺮﻛﻴﻦ:اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺳـﭙﺲ ﺧﺎﺻـﻴﺖ. ﺟﺪﻳﺪ ﺑـﻪ ﻗـﺴﻤﺖ ﭘـﺎﻳﻴﻦ ﻓـﺮم اﺿـﺎﻓﻪ ﻛﻨﻴـﺪButton ﻳﻚ ﻛﻨﺘﺮل،( ﺑﺎ اﺳﺘﻔﺎده از ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم1 . ﺗﻐﻴﻴﺮ دﻫﻴﺪDelete آن را ﺑﻪText و ﺧﺎﺻﻴﺖbtnDelete آن را ﺑﻪName : آن وارد ﻛﻨﻴﺪClick ( ﺑﺮ روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد2 private void btnDelete_Click(object sender, EventArgs e) { // If no customer is selected in the ListBox then... if (lstCustomers.SelectedIndex == -1) { // Display a message MessageBox.Show("You must select a customer to " + "delete!", "Structure Demo"); // Exit the method return; } // Prompt the user to delete the selected customer DialogResult result = MessageBox.Show( "Are you sure you want to delete " + SelectedCustomer.Name + "? ", "Structure Demo", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (result == DialogResult.Yes) { // Get the customer to be deleted Customer objCustomerToDelete = SelectedCustomer; // Remove the customer from the ArrayList objCustomers.Remove(objCustomerToDelete); // Remove the customer from the ListBox lstCustomers.Items.Remove(objCustomerToDelete); } } ١٩٧
(3ﺳﭙﺲ ﺧﺎﺻﻴﺖ SelectedCustomerﻛﻪ در ﻛـﺪ ﺑـﺎﻻ اﺳـﺘﻔﺎده ﺷـﺪه اﺳـﺖ را ﺑـﻪ ﺻـﻮرت زﻳـﺮ ﺑـﻪ ﻛـﻼس Form1اﺿﺎﻓﻪ ﻛﻨﻴﺪ. public Customer SelectedCustomer { get { // Return the selected customer [return (Customer)lstCustomers.Items ;]lstCustomers.SelectedIndex } } (4ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ ي Testﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﺪون اﻳﻨﻜﻪ ﻣﺸﺘﺮﻛﻲ را از ﻟﻴﺴﺖ اﻧﺘﺨﺎب ﻛﻨﻴﺪ ،ﺑﺮ روي دﻛﻤـﻪ Deleteﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛﺎدر ﭘﻴﻐﺎﻣﻲ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣﻲ ﮔﻮﻳﺪ ﺑﺎﻳﺪ ﻳﻚ ﻣﺸﺘﺮك را از ﻟﻴﺴﺖ اﻧﺘﺨﺎب ﻛﻨﻴـﺪ ﺗـﺎ ﺑﺘﻮاﻧﻴﺪ آن را ﺣﺬف ﻛﻨﻴﺪ. (5ﺣﺎل ﻳﻚ ﻣﺸﺘﺮك را اﻧﺘﺨﺎب ﻛﻨﻴﺪ و ﺑﺮ روي دﻛﻤﻪ ي Deleteﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛﺎدر ﭘﻴﻐﺎﻣﻲ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛـﺮد ﻛـﻪ ﺑﺮاي ﺣﺬف ﻣﺸﺘﺮك از ﺷﻤﺎ ﺳﻮال ﻣﻲ ﻛﻨﺪ؟ )ﺷﻜﻞ (17-5 (6ﺑﺮ روي ﮔﺰﻳﻨﻪ Yesﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﮔﺰﻳﻨﻪ اﻧﺘﺨﺎﺑﻲ ﺷﻤﺎ از ﻟﻴﺴﺖ ﭘﺎك ﻣﻲ ﺷﻮد.
ﺷﻜﻞ 17-5
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟
١٩٨
ﻳﻜﻲ از ﻧﻜﺘﻪ ﻫﺎي اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﺧﺎﺻﻴﺘﻲ ﺑﻮد ﻛـﻪ ﻣـﺸﺘﺮك اﻧﺘﺨـﺎب ﺷـﺪه در ﻛﻨﺘـﺮل ListBoxرا ﺑﺮﻣـﻲ ﮔﺮداﻧـﺪ .ﺧﺎﺻـﻴﺖ SelectedIndexدر ﻛﻨﺘﺮل ،ListBoxاﻧﺪﻳﺲ ﻋﻨﺼﺮ اﻧﺘﺨﺎب ﺷﺪه در ﻟﻴﺴﺖ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .اﻣﺎ اﮔﺮ ﻫﻴﭻ ﻋﻨﺼﺮي در ﻟﻴﺴﺖ اﻧﺘﺨﺎب ﻧﺸﺪه ﺑﺎﺷﺪ ،اﻳﻦ ﺗﺎﺑﻊ ﻋﺪد -1را ﻧﺘﻴﺠﻪ ﻣﻲ دﻫﺪ. public Customer SelectedCustomer { get { // Return the selected customer [return (Customer)lstCustomers.Items ;]lstCustomers.SelectedIndex } } ﻫﻤﺎﻧﻨﺪ ﺧﺎﺻﻴﺖ Nameدر ﺳﺎﺧﺘﺎر ،Customerاﻳﻦ ﺧﺎﺻﻴﺖ ﻧﻴﺰ از ﻧﻮع ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ اﻳﺠﺎد ﺷﺪه اﺳﺖ .ﻫﻤﺎﻧﻄﻮر ﻛـﻪ ﻣـﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،اﻳﻦ ﺧﺎﺻﻴﺖ ﻓﻘﻂ داراي ﺑﻼك getاﺳﺖ و ﺑﻼك setﻧﺪارد .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ در ﺑﺮﻧﺎﻣﻪ ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﻪ ﻣﻘـﺪار ﻛﻨـﻮﻧﻲ اﻳﻦ ﺧﺎﺻﻴﺖ دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﻴﻢ و ﻧﻤﻲ ﺗﻮاﻧﻴﻢ ﻣﻘﺪار آن را ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ. درون ﻛﻨﺘﺮل ﻛﻨﻨﺪه ي روﻳﺪاد Clickﺑﺮاي دﻛﻤﻪ Deleteاﺑﺘﺪا ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ آﻳﺎ ﻣﺸﺘﺮﻛﻲ از ﻟﻴﺴﺖ اﻧﺘﺨﺎب ﺷﺪه اﺳـﺖ ﻳﺎ ﻧﻪ؟ در ﺻﻮرﺗﻲ ﻛﻪ ﻫﻴﭻ ﻓﺮدي از ﻟﻴﺴﺖ اﻧﺘﺨﺎب ﻧﺸﺪه ﺑﻮد ،ﺑﺎ ﻧﻤﺎﻳﺶ ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﺑﻪ ﻛﺎرﺑﺮ ﻣﻲ ﮔـﻮﻳﻴﻢ ﻛـﻪ ﺑﺎﻳـﺪ ﻳـﻚ ﻣـﺸﺘﺮك را اﻧﺘﺨﺎب ﻛﻨﺪ ﺗﺎ ﺑﺘﻮاﻧﺪ آن را ﺣﺬف ﻛﻨﺪ .ﺳﭙﺲ از ﻣﺘﺪ ﺧﺎرج ﻣﻲ ﺷﻮﻳﻢ و ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻣﻲ دﻫﻴﻢ ﻛﻪ ﻓﺮدي را از ﻟﻴﺴﺖ اﻧﺘﺨﺎب ﻛﻨﺪ. // If no customer is selected in the ListBox then... )if (lstCustomers.SelectedIndex == -1 { // Display a message " MessageBox.Show("You must select a customer to ;)""delete!", "Structure Demo
+
// Exit the method ;return } اﮔﺮ ﻛﺎرﺑﺮ ﻣﺸﺘﺮﻛﻲ را از ﻟﻴﺴﺖ اﻧﺘﺨﺎب ﻛﺮده ﺑﻮد ،ﻧﺎم او را در ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﺪ ﺗﺎ ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ ﻛﺎرﺑﺮ ﻣﻲ ﺧﻮاﻫـﺪ آن را از ﻟﻴﺴﺖ ﺣﺬف ﻛﻨﺪ. (DialogResult result = MessageBox.Show "Are you sure you want to delete " + SelectedCustomer.Name + "? ", "Structure Demo", MessageBoxButtons.YesNo, ;)MessageBoxIcon.Question )if (result == DialogResult.Yes {
١٩٩
ﻧﺤﻮه اﺳﺘﻔﺎده از ﺗﺎﺑﻊ MessageBox.Showدر اﻳﻦ ﻗﺴﻤﺖ ،ﻣﻘﺪاري ﺑﺎ دﻓﻌﺎت ﻗﺒﻞ ﺗﻔﺎوت دارد .ﻫﻤﺎﻧﻄﻮر ﻛـﻪ ﭘـﻴﺶ ﺗـﺮ ﻧﻴـﺰ ﮔﻔﺘﻢ 1ﻳﻚ ﺗﺎﺑﻊ ﻣﻲ ﺗﻮاﻧﺪ در ﺣﺎﻟﻲ ﻛﻪ ﻓﻘﻂ ﻳﻚ ﻧﺎم دارد ،ﭘﺎراﻣﺘﺮﻫﺎي ﻣﺨﺘﻠﻔﻲ را ﺑﻪ ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻛﻨﺪ .اﮔﺮ در ﻫﻨﮕﺎم ﻛﺎر ﺑﺎ اﻳﻦ ﺗﺎﺑﻊ ﺑﻪ راﻫﻨﻤﺎﻳﻲ ﻛﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ درﺑﺎره اﻳﻦ ﺗﺎﺑﻊ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ دﻗﺖ ﻛﻨﻴﺪ ،ﻣﺘﻮﺟﻪ ﺧﻮاﻫﻴﺪ ﺷﺪ ﻛﻪ اﻳﻦ ﺗﺎﺑﻊ ﺑﻪ ﭼﻨـﺪﻳﻦ روش ﻣـﻲ ﺗﻮاﻧﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد .ﻳﻜﻲ از اﻳﻦ روﺷﻬﺎ ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﻧﻴﺰ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ ،ﻳﻚ رﺷﺘﻪ را ﺑﻪ ﻋﻨﻮان ﻣﺘﻦ اﺻﻠﻲ و رﺷﺘﻪ دﻳﮕﺮي را ﻧﻴﺰ ﺑﺮاي ﻧﻤﺎﻳﺶ در ﻋﻨﻮان ﭘﻨﺠﺮه درﻳﺎﻓﺖ ﻣﻲ ﻛﺮد و ﻛﺎدر ﭘﻴﻐﺎﻣﻲ را ﺑﺮ اﺳﺎس اﻳﻦ اﻃﻼﻋﺎت ﻧﻤﺎﻳﺶ ﻣﻲ داد. در اﻳﻦ ﺑﺮﻧﺎﻣﻪ از ﻳﻜﻲ دﻳﮕﺮ از ﺣﺎﻟﺘﻬﺎي ﺗﺎﺑﻊ MessageBox.Showاﺳﺘﻔﺎده ﻛﺮده اﻳﻢ .اﻳﻦ ﺣﺎﻟﺖ ﻋﻼوه ﺑﺮ ﭘﺎراﻣﺘﺮﻫﺎي ﻗﺒﻠﻲ، دﻛﻤﻪ ﻫﺎي ﻓﺮﻣﺎن و آﻳﻜـﻮﻧﻲ ﻛـﻪ ﺑﺎﻳـﺪ در ﻛـﺎدر ﻧﻤـﺎﻳﺶ دﻫـﺪ را ﻧﻴـﺰ درﻳﺎﻓـﺖ ﻣـﻲ ﻛﻨـﺪ .دﻛﻤـﻪ ﻫـﺎي ﻓﺮﻣـﺎن ﺑﺎﻳـﺪ از ﺷـﻤﺎرﻧﺪه ي MessageBoxButtonsو آﻳﻜﻮن ﺑﺎﻳﺪ از ﺷﻤﺎرﻧﺪه ي MessageBoxIconاﻧﺘﺨﺎب ﺷﻮد .در اﻳﻨﺠـﺎ ﻋـﻼوه ﺑـﺮ ﻣﺸﺨﺺ ﻛﺮدن ﻣﺘﻨﻬﺎﻳﻲ ﻛﻪ ﺑﺎﻳﺪ در ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﺷﻮد ،ﺑﻪ وﻳﮋوال C#ﮔﻔﺘﻪ اﻳﻢ ﻛﻪ ﺑﻪ ﺟﺎي دﻛﻤﻪ ،OKدﻛﻤﻪ ﻫﺎي Yesو No را ﺑﻪ ﻫﻤﺮاه ﻳﻚ ﻋﻼﻣﺖ ﺳﻮال ﺑﺮ روي ﻛﺎدر ﻧﻤﺎﻳﺶ دﻫﺪ .ﺑﺮاي اﻳﻦ ﻛﻪ ﺑﻔﻬﻤﻴﻢ ﻛﺎرﺑﺮ ﻛﺪام ﮔﺰﻳﻨﻪ را اﻧﺘﺨﺎب ﻛﺮده اﺳﺖ ،ﺑﺎﻳـﺪ از ﻧﺘﻴﺠـﻪ اي ﻛﻪ ﺗﻮﺳﻂ ﺗﺎﺑﻊ ﺑﺮﮔﺮداﻧﺪه ﻣﻲ ﺷﻮد اﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻳﻦ ﺗﺎﺑﻊ ﻧﺘﻴﺠﻪ ﺧﻮد را ﺑﻪ ﺻﻮرت ﺷﻴﺊ از ﻛﻼس DialogResultﺑﺮﻣﻲ ﮔﺮداﻧﺪ .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ اﺑﺘﺪا ﻣﺘﻐﻴﺮي از اﻳﻦ ﻛﻼس اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ،ﺳﭙﺲ ﻧﺘﻴﺠﻪ ﺑﺮﮔﺮداﻧﺪه ﺷﺪه ﺗﻮﺳﻂ ﺗﺎﺑﻊ را در آن ﻗﺮار ﻣﻲ دﻫﻴﻢ. ﺣﺎل ﺑﺎﻳﺪ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ﻛﻪ ﻛﺎرﺑﺮ دﻛﻤﻪ Yesرا ﻓﺸﺮده اﺳﺖ ﻳﺎ ﻧﻪ؟ ﺑﺮاي اﻳﻦ ﻛﺎر از دﺳﺘﻮر ifاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .اﮔﺮ ﻣﻘـﺪار ﻣﺘﻐﻴـﺮي ﻛﻪ از ﻧﻮع DialogResultﺗﻌﺮﻳﻒ ﻛﺮدﻳﻢ ﺑﺮاﺑﺮ ﺑﺎ DialogResult.Yesﺑﺎﺷﺪ ،ﺑﻪ اﻳﻦ ﻣﻌﻨـﻲ اﺳـﺖ ﻛـﻪ ﻛـﺎرﺑﺮ ﮔﺰﻳﻨﻪ Yesرا اﻧﺘﺨﺎب ﻛﺮده اﺳﺖ .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻛﺎرﺑﺮ از ﺣﺬف ﻣﺸﺘﺮك ﻣﻨـﺼﺮف ﺷـﺪه اﺳـﺖ و ﮔﺰﻳﻨـﻪ Noرا اﻧﺘﺨـﺎب ﻛـﺮده اﺳﺖ.2 ﺑﺮاي ﺣﺬف ﻛﺎرﺑﺮ از ﻟﻴﺴﺖ ،ﻣﺘﻐﻴﺮي را از ﻧﻮع ﺳﺎﺧﺘﺎر Customerﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ و ﻣﺸﺘﺮﻛﻲ را ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ از ﻟﻴﺴﺖ ﺣـﺬف ﻛﻨﻴﻢ در آن ﻗﺮار ﻣﻲ دﻫﻴﻢ: // Get the customer to be deleted ;Customer objCustomerToDelete = SelectedCustomer ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ Removeﻛﻼس ArrayListﻣﻲ ﺗﻮاﻧﻴﻢ ﻣﺸﺘﺮك اﻧﺘﺨﺎب ﺷﺪه را از ﻟﻴﺴﺖ ﺣﺬف ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ ﻣﺘﻐﻴﺮي را ﻛﻪ در ﻣﺮﺣﻠﻪ ﻗﺒﻞ ،ﻣﺸﺘﺮك را در آن ذﺧﻴﺮه ﻛﺮدﻳﻢ ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ ﻣﺘﺪ ﺑﻔﺮﺳﺘﻴﻢ: // Remove the customer from the ArrayList ;)objCustomers.Remove(objCustomerToDelete ﺑﺮاي ﺣﺬف ﻛﺎرﺑﺮ از ﻟﻴﺴﺖ ﺑﺎﻛﺲ ﻫﻢ ﺑﺎﻳﺪ از روﺷﻲ ﻣﺸﺎﺑﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ: // Remove the customer from the ListBox ;)lstCustomers.Items.Remove(objCustomerToDelete
ﻧﻤﺎﻳﺶ ﻋﻨﺎﺻﺮ ﻣﻮﺟﻮد در ﻟﻴﺴﺖ ﭘﻴﻮﻧﺪي:
1رﺟﻮع ﻛﻨﻴﺪ ﺑﻪ ﺑﺨﺶ ﻣﺮﺗﺐ ﺳﺎزي آراﻳﻪ ﻫﺎ در ﻫﻤﻴﻦ ﻓﺼﻞ 2در ﻓﺼﻞ ﻫﻔﺘﻢ در ﻣﻮرد اﺳﺘﻔﺎده از ﻛﺎدر ﭘﻴﻐﺎم ﺑﻪ ﺗﻔﺼﻴﻞ ﺑﺤﺚ ﺧﻮاﻫﻴﻢ ﻛﺮد.
٢٠٠
ﺑﺮاي ﻛﺎﻣﻞ ﺷﺪن ﺑﺮﻧﺎﻣﻪ ،ﺑﺎﻳﺪ ﻳﻚ ﺳﺮي از ﻗﺎﺑﻠﻴﺖ ﻫﺎ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ راﺑﻂ ﻛﺎرﺑﺮي ﺑﺮﻧﺎﻣﻪ ﺑﻬﺒﻮد ﭘﻴﺪا ﻛﻨﺪ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ،ﻛﺪ درون روﻳﺪاد SelectedIndexChangedﻣﺮﺑﻮط ﺑﻪ ListBoxرا ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ ﺧﻮاﻫﻴﺪ داد ﺗﺎ ﻫـﺮ ﺑﺎر ﻛﻪ ﻣﺸﺘﺮك ﺟﺪﻳﺪي را از ListBoxاﻧﺘﺨﺎب ﻛﻨﻴﺪ ،اﻃﻼﻋﺎت او ﺑﺮ روي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﺷﻮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻧﻤﺎﻳﺶ اﻃﻼﻋﺎت ﻣﺸﺘﺮك اﻧﺘﺨﺎب ﺷﺪه در ﺻﻔﺤﻪ (1در ﺑﺨــﺶ ﻃﺮاﺣــﻲ ﻓــﺮم ﺑــﺮ روي ﻟﻴــﺴﺖ ﺑــﺎﻛﺲ دو ﺑــﺎر ﻛﻠﻴــﻚ ﻛﻨﻴــﺪ .ﺑــﻪ اﻳــﻦ ﺗﺮﺗﻴــﺐ ﻣﺘــﺪ ﻣﺮﺑــﻮط ﺑــﻪ روﻳــﺪاد SelectedIndexChangedﺑﻪ ﻃﻮر اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﻣﻲ ﺷﻮد .ﻛﺪ ﻣﺸﺨﺺ ﺷـﺪه در زﻳـﺮ را ﺑـﻪ اﻳـﻦ ﻣﺘـﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: (private void lstCustomers_SelectedIndexChanged )object sender, EventArgs e { // Display the customer details ;)DisplayCustomer(SelectedCustomer } (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﺮ روي دﻛﻤﻪ ي ﻓﺮﻣﺎن Testﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ آﻳﺘﻢ ﻫﺎي ﻣﻮرد ﻧﻴﺎز در ListBoxﻗـﺮار ﮔﻴﺮﻧـﺪ. ﺣﺎل اﮔﺮ ﺑﺮ روي ﻧﺎم ﻳﻜﻲ از ﻣﺸﺘﺮﻛﻴﻦ در ﻟﻴﺴﺖ ﺑﺎﻛﺲ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ،ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 18-5اﻃﻼﻋـﺎت او در ﻛﺎدرﻫـﺎي ﻣﺘﻨـﻲ روي ﻓﺮم ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ.
ﺷﻜﻞ 18-5
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟
٢٠١
ArrayListﻳﻜﻲ از اﻧﻮاع ﻛﻠﻜﺴﻴﻮن ﻫﺎي ﻣﻮﺟﻮد در .NETاﺳﺖ ﻛﻪ از آن اﺳﺘﻔﺎده زﻳﺎدي ﺷﺪه اﺳﺖ .ﻳﻚ ﻛﻠﻜـﺴﻴﻮن راﻫـﻲ اﺳﺖ ﺑﺮاي ﺳﺎﺧﺘﻦ راﺣﺖ ﮔﺮوه ﻫﺎﻳﻲ از ﻋﻨﺎﺻﺮ ﻣﺮﺗﺒﻂ ﺑﻪ ﻫﻢ .اﮔﺮ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي Structure Demoﻧﮕـﺎﻫﻲ ﺑﻴﻨﺪازﻳـﺪ و ﻛـﺪ ﺗﺎﺑﻊ CreateCustomerرا ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ ،ﻣﺘﻮﺟﻪ ﻣﻲ ﺷﻮﻳﺪ ﻛﻪ ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻣﺸﺘﺮك ﺑﻪ ﻟﻴـﺴﺖ ،ﻫﻤﺎﻧﻨـﺪ اﺿـﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻣﺸﺘﺮك ﺑﻪ ﻟﻴﺴﺖ ﭘﻴﻮﻧﺪي ،از ﺗﺎﺑﻊ Addاﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﺪ. // Add the new customer to the list ;)objCustomers.Add(objNewCustomer // Add the new customer to the ListBox control ;)lstCustomers.Items.Add(objNewCustomer ﺑﺮاي ﺣﺬف ﻳﻚ ﻣﺸﺘﺮك ﻫﻢ )ﭼﻪ در ﻟﻴﺴﺖ ﺑﺎﻛﺲ و ﭼﻪ در ﻟﻴﺴﺖ ﭘﻴﻮﻧﺪي( از ﻣﺘﺪ Removeاﺳﺘﻔﺎده ﻛﺮدﻳﺪ: // Remove the customer from the ArrayList ;)objCustomers.Remove(objCustomerToDelete // Remove the customer from the ListBox ;)lstCustomers.Items.Remove(objCustomerToDelete ﭘﻴﺸﻨﻬﺎد ﻣﻲ ﺷﻮد ﻛﻪ ﻫﻨﮕﺎم ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻟﻴﺴﺘﻲ از ﻋﻨﺎﺻﺮ ﻣﺮﺗﺒﻂ ﺑﻪ ﻫﻢ را ﻧﮕﻬﺪاري ﻛﻨﻴﺪ ،از ﻛﻠﻜـﺴﻴﻮن ﻫـﺎ اﺳـﺘﻔﺎده ﻛﻨﻴﺪ .در زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺗﺤﺖ .NETو ﻫﻤﭽﻨﻴﻦ در ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﻛﺘﺎﺑﺨﺎﻧﻪ ﻛﻼس ،.NETﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﺳﻌﻲ ﻛﺮده اﺳﺖ ﺗﻤﺎم ﻛﻠﻜﺴﻴﻮن ﻫﺎ ﺻﺮﻓﻨﻈﺮ از ﻧﻮع ﻣﻘﺪاري ﻛﻪ ﺑﺎﻳﺪ ذﺧﻴﺮه ﻛﻨﻨﺪ ،ﺑﻪ ﻳﻚ روش ﻛﺎر ﻛﻨﻨﺪ .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ اﺳﺖ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺮ ﺟـﺎ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﻋﻨﺼﺮي را ﺣﺬف ﻛﻨﻴﺪ از ﻣﺘﺪ Removeو اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻋﻨﺼﺮي را اﺿﺎﻓﻪ ﻛﻨﻴﺪ از ﻣﺘﺪ Addاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ،ﭼـﻪ در ﺣﺎل ﻛﺎر ﺑﺎ ﻳﻚ ArrayListﺑﺎﺷﻴﺪ ،ﭼﻪ در ﺣﺎل ﻛﺎر ﺑﺎ ﻋﻨﺎﺻﺮ ﻣﻮﺟﻮد در ﻳﻚ ﻟﻴﺴﺖ ﺑﺎﻛﺲ. اﻳﻦ ﺛﺒﺎت و ﻳﻜﺴﺎﻧﻲ در ﺗﻮاﺑﻊ و ﻛﻼﺳﻬﺎ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ اﺟﺎزه ﻣﻲ دﻫﺪ ﺗﺎ ﺑﺘﻮاﻧﺪ آﻣﻮﺧﺘﻪ ﻫـﺎي ﺧـﻮد را از ﻳـﻚ ﻣﻮﺿـﻮع ،ﺑـﺮاي ﻛـﺎر ﺑـﺎ ﻣﻮﺿﻮﻋﺎت ﻣﺸﺎﺑﻪ ﻧﻴﺰ ﺑﻪ ﻛﺎر ﺑﺒﺮد .ﭘﺲ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد ﺳﺎﺧﺘﺎرﻫﺎي داده اي ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ،ﺑﻬﺘﺮ اﺳﺖ اﻳﻦ ﻗﻮاﻋﺪ را ﻧﻴﺰ رﻋﺎﻳﺖ ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ در ﺣﺎل اﻳﺠﺎد ﻳﻚ ﻛﻼس ﻫﻤﺎﻧﻨﺪ ﻛﻠﻜﺴﻴﻮن ﻫﺎ ﻫﺴﺘﻴﺪ و ﻣﻲ ﺧﻮاﻫﻴﺪ ﻛﻪ ﻣﺘـﺪي ﺑـﺮاي ﺣـﺬف ﻋﻨﺎﺻﺮ در آن ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ﺑﻬﺘﺮ اﺳﺖ ﻧﺎم آن را ﺑﺮاﺑﺮ ﺑﺎ Removeﻗﺮار دﻫﻴﺪ ،ﻧﻪ ﻋﺒﺎرﺗﻬﺎي ﻣﺸﺎﺑﻪ ﻣﺎﻧﻨﺪ Deleteو ﻳﺎ … .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﮔﺮ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺨﻮاﻫﺪ از ﻛﻼس ﺷﻤﺎ اﺳﺘﻔﺎده ﻛﻨﺪ ،ﻧﺎم Removeﺑﺮاي او آﺷﻨﺎ ﺧﻮاﻫﺪ ﺑﻮد و ﻣﻲ ﺗﻮاﻧﺪ ﻋﻤﻠﻜﺮد اﻳﻦ ﻣﺘـﺪ را ﺣﺪس ﺑﺰﻧﺪ.
اﻳﺠﺎد ﺟﺪاول ﻗﺎﺑﻞ ﺟﺴﺘﺠﻮ ﺑﺎ Hashtableﻫﺎ: ﺗﺎﻛﻨﻮن اﮔﺮ ﻣﻲ ﺧﻮاﺳﺘﻴﺪ ﻋﻨﺼﺮي را در ﻳﻚ آراﻳﻪ ﻳﺎ ﻳﻚ ﻟﻴﺴﺖ ﭘﻴﻮﻧﺪي ﭘﻴﺪا ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ اﻧﺪﻳﺲ ﻋﺪد ﺻﺤﻴﺢ آن ﻋﻨﺼﺮ را ﻛﻪ ﻣﻌﺮف ﻣﻜﺎن ﻗﺮار ﮔﺮﻓﺘﻦ آن ﻋﻨﺼﺮ ﺑﻮد ﻣﺸﺨﺺ ﻣﻲ ﻛﺮدﻳﺪ .اﻣﺎ اﮔﺮ ﻣﻲ ﺧﻮاﺳﺘﻴﺪ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ آن ﻋﻨﺼﺮ از ﻣﻘﺪار دﻳﮕﺮي ﺑﻪ ﺟﺰ اﻧﺪﻳﺲ اﺳـﺘﻔﺎده ﻛﻨﻴﺪ ،ﻧﻤﻲ ﺗﻮاﻧﺴﺘﻴﺪ اﻳﻦ روش را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ .ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ در ﺑﺮﻧﺎﻣﻪ ﻗﺒﻞ ﻣﻲ ﺧﻮاﺳـﺘﻴﺪ اﻃﻼﻋـﺎت ﻣـﺸﺘﺮﻛﻴﻦ را ﺑـﺮ اﺳـﺎس آدرس ﭘﺴﺖ اﻟﻜﺘﺮوﻧﻴﻜﻲ آﻧﻬﺎ ﺑﺪﺳﺖ آورﻳﺪ. در اﻳﻦ ﻗﺴﻤﺖ ﻧﻮع ﺧﺎﺻﻲ از ﻛﻠﻜﺴﻴﻮن ﻫﺎ ﺑﻪ ﻧﺎم Hashtableرا ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ روﺷﻬﺎي ﺑﻬﺘﺮي را ﺑﺮاي ﺟﺴﺘﺠﻮ اراﺋﻪ ﻣﻲ دﻫﻨﺪ .اﻳﻦ ﻛﻠﻜﺴﻴﻮن ﻫﺎ ﺑﺮ اﺳﺎس ﻳﻚ ﻣﻘﺪار ﻛﻠﻴﺪي ﻛﻪ ﺑﺮاي آﻧﻬﺎ ﻣﺸﺨﺺ ﻣﻲ ﺷﻮد ،آراﻳﻪ را ﺟﺴﺘﺠﻮ ﻣﻲ ﻛﻨﻨﺪ.
٢٠٢
اﺳﺘﻔﺎده از :Hashtable Hashtableﻧﻮﻋﻲ ﻛﻠﻜﺴﻴﻮن اﺳﺖ ﻛﻪ ﻫﺮ ﻋﻨﺼﺮ آن داراي ﻳﻚ ﻛﻠﻴﺪ اﺳﺖ .ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﻠﻴﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻣﻘﺪار ﻋﻨﺼﺮ در ﻛﻠﻜﺴﻴﻮن دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ اﻃﻼﻋﺎت ﻣﺸﺘﺮﻛﻲ ﺑﺎ ﻧﺎم Darrelرا ﻛﻪ از ﻧـﻮع Customerاﺳـﺖ در ﻳﻚ Hashtableﻗﺮار ﻣﻲ دﻫﻴﺪ و ﻣﻘﺪار ﻛﻠﻴﺪي اﻳﻦ ﻋﻨﺼﺮ را ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎ آدرس ﭘﺴﺖ اﻟﻜﺘﺮوﻧﻴﻜﻲ او ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﺪ .در اﻳﻦ ﺻﻮرت اﮔﺮ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت اﻳﻦ ﻣﺸﺘﺮك آدرس ﭘﺴﺖ اﻟﻜﺘﺮوﻧﻴﻜﻲ او را وارد ﻛﻨﻴﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺳﺮﻋﺖ او را در ﻟﻴـﺴﺖ ﭘﻴـﺪا ﻛﻨﻴﺪ. ﻫﻨﮕـــﺎﻣﻲ ﻛـــﻪ دو ﻋﻨـــﺼﺮ ﻛﻠﻴـــﺪ و ﻣﻘـــﺪار را ﺑـــﻪ Hashtableاﺿـــﺎﻓﻪ ﻣـــﻲ ﻛﻨﻴـــﺪ ،ﻋﻨـــﺼﺮ ﻛﻠﻴـــﺪ ﺗـــﺎﺑﻌﻲ ﺑـــﻪ ﻧـــﺎم )( System.Object.GetHashCodeرا ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ .اﻳﻦ ﺗﺎﺑﻊ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ ﻣﻨﺤﺼﺮ ﺑﻪ ﻓـﺮد را ﺑـﺮاي ﻛﻠﻴﺪ ﺑﺮﻣﻲ ﮔﺮداﻧﺪ ﻛﻪ ﺑﻪ ﻋﻨﻮان ﺷﻨﺎﺳﻪ ي آن اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد .اﻳﻦ ﻋﺪد ﺑﻪ ﺻﻮرﺗﻲ اﺳﺖ ﻛﻪ اﮔﺮ ﭼﻨﺪ ﺑﺎر دﻳﮕﺮ ﻫﻢ ﺗﺎﺑﻊ ﺑﺮاي اﻳﻦ ﻋﻨﺼﺮ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮد ﻋﺪد ﻳﻜﺴﺎﻧﻲ ﺑﺮﻣﻲ ﮔﺮدد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺑﻪ ﻋﻨـﺼﺮي در ﻳـﻚ Hashtableدﺳﺘﺮﺳـﻲ ﭘﻴـﺪا ﻛﻨﻴﺪ ،ﻛﻠﻴﺪ آن ﻋﻨﺼﺮ از ﺷﻤﺎ ﮔﺮﻓﺘﻪ ﺷﺪه و ﺗﺎﺑﻊ GetHashCodeﻣﺮﺑﻮط ﺑﻪ آن ﻛﻠﻴﺪ اﺟﺮا ﻣﻲ ﺷﻮد .ﺷﻨﺎﺳﻪ اي ﻛﻪ ﺑـﻪ وﺳـﻴﻠﻪ ي اﻳﻦ ﺗﺎﺑﻊ ﺑﻪ دﺳﺖ ﻣﻲ آﻳﺪ ﺑﺎ ﺗﻤﺎم ﺷﻨﺎﺳﻪ ﻫﺎي ﻣﻮﺟﻮد در Hashtableﻣﻘﺎﻳﺴﻪ ﻣﻲ ﺷﻮد .اﮔﺮ آن ﺷﻨﺎﺳﻪ در ﻟﻴـﺴﺖ وﺟـﻮد داﺷـﺘﻪ ﺑﺎﺷﺪ ،ﻣﻘﺪار ﻣﺮﺗﺒﻂ ﺑﻪ آن ﻛﻠﻴﺪ ﺑﺮﻣﻲ ﮔﺮدد. ﺟﺴﺘﺠﻮ در ﻳﻚ Hashtableﺑﺴﻴﺎر ﺳﺮﻳﻊ اﻧﺠﺎم ﻣﻲ ﺷﻮد .زﻳﺮا ﺻﺮﻓﻨﻈﺮ از ﻧﻮع ﻋﻨﺼﺮي ﻛﻪ در اﻳﻦ ﺟﺪول ذﺧﻴﺮه ﻣﻲ ﻛﻨﻴﺪ ،ﻳـﻚ ﻋﺪد ﺻﺤﻴﺢ ﻛﻮﭼﻚ ﺑﻪ ﻋﻨﻮان ﺷﻨﺎﺳﻪ ﻋﻨﺼﺮ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮد .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻧﺤـﻮه اﺳـﺘﻔﺎده از Hashtableﻫـﺎ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد. ﻧﻜﺘﻪ :ﻋﺪد ﺻﺤﻴﺤﻲ ﻛﻪ ﺑﺮاي ذﺧﻴﺮه ﺷﻨﺎﺳﻪ ي ﻳﻚ ﻛﻠﻴﺪ در Hashtableﺑﻪ ﻛﺎر ﻣﻲ رود ﻓﻘﻂ 4ﺑﺎﻳﺖ از ﺣﺎﻓﻈﻪ را اﺷﻐﺎل ﻣـﻲ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ رﺷﺘﻪ اي ﺷﺎﻣﻞ 100ﻛﺎراﻛﺘﺮ را ﻛﻪ 200ﺑﺎﻳﺖ ﻓﻀﺎ اﺷﻐﺎل ﻣﻲ ﻛﻨﺪ ﺑﻪ ﻋﻨﻮان ﻛﻠﻴﺪ در ﻧﻈﺮ ﺑﮕﻴﺮﻳـﺪ ،ﺑـﺮاي ﺟـﺴﺘﺠﻮ در ﺟﺪول ﻓﻘﻂ اﻋﺪاد 4ﺑﺎﻳﺘﻲ ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﻣﻘﺎﻳﺴﻪ ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﺑﺎﻋﺚ اﻓﺰاﻳﺶ ﺳﺮﻋﺖ ﻣﻲ ﺷﻮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از Hashtableﻫﺎ (1وﻳﺮاﻳﺸﮕﺮ ﻛﺪ را ﺑﺮاي ﻓﺮم ﺑﺎز ﻛﺮده و ﺗﻐﻴﻴﺮ زﻳﺮ را در ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﺮ objCustomersاﻳﺠﺎد ﻛﻨﻴﺪ: public partial class Form1 : Form { // Form level members ;)(private Hashtable objCustomers = new Hashtable (2ﺑﻪ ﻗﺴﻤﺖ ﻛﺪﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﺗﺎﺑﻊ CreateCustomerﺑﺮوﻳﺪ و ﻛﺪﻫﺎي آن را ﺑﻪ ﺻﻮرت ﻣـﺸﺨﺺ ﺷـﺪه در زﻳـﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ: public void CreateCustomer(string FirstName, string )LastName, string Email
٢٠٣
{ // Declare a customer object Customer objNewCustomer; // Create the new customer objNewCustomer.FirstName = FirstName; objNewCustomer.LastName = LastName; objNewCustomer.Email = Email; // Add the new customer to the list objCustomers.Add(Email.ToLower(),objNewCustomer); // Add the new customer to the ListBox control lstCustomers.Items.Add(objNewCustomer); : ﺑﺮوﻳﺪ و ﺗﻐﻴﺮات ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در آن اﻳﺠﺎد ﻛﻨﻴﺪbtnDelete_Click ( ﺑﻪ ﺑﺨﺶ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻣﺘﺪ3 // Prompt the user to delete the selected customer DialogResult result = MessageBox.Show( "Are you sure you want to delete " + SelectedCustomer.Name + "? ", "Structure Demo", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (result == DialogResult.Yes) { // Get the customer to be deleted Customer objCustomerToDelete = SelectedCustomer; // Remove the customer from the ArrayList objCustomers.Remove(txtEmail.Text.ToLower()); // Remove the customer from the ListBox lstCustomers.Items.Remove(objCustomerToDelete); } اﻳﻦ ﻛﻨﺘﺮل را ﺑﺮاﺑﺮName ﺧﺎﺻﻴﺖ. ﺟﺪﻳﺪي را ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﺪButton ( ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ و ﻛﻨﺘﺮل4 ﻓﺮم ﺷﻤﺎ در اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ. ﻗﺮار دﻫﻴﺪLookup آن را ﺑﺮاﺑﺮ ﺑﺎText و ﺧﺎﺻﻴﺖbtnLookup ﺑﺎ . ﺑﺎﺷﺪ19-5
٢٠٤
19-5 ﺷﻜﻞ ﺳﭙﺲ ﻛﺪﻫﺎي زﻳـﺮ را. آن اﻳﺠﺎد ﺷﻮدClick دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪادLookup ( ﺑﺮ روي دﻛﻤﻪ ي5 :ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ private void btnLookup_Click(object sender, EventArgs e) { // If the customer found in the Hashtable if (objCustomers.Contains(txtEmail.Text.ToLower()) == true) // Display the customer name MessageBox.Show("The customer name is: " + ((Customer)objCustomers[txtEmail.Text.ToLower()]).Name , "Structure Demo"); else //Display an error MessageBox.Show("There is no custome rwith the " + "email address: " + txtEmail.Text, "Structure Demo"); } اﮔـﺮ ﻳـﻚ آدرس ﭘـﺴﺖ. ﻛﻠﻴﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﻟﻴـﺴﺖ از ﻧـﺎم ﻣـﺸﺘﺮﻛﻴﻦ ﭘـﺮ ﺷـﻮدTest ( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﺮ روي دﻛﻤﻪ6 ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﻛـﺎدرLookup وارد ﻛﻨﻴﺪ و ﺑﺮ روي دﻛﻤـﻪEmail اﻟﻜﺘﺮوﻧﻴﻜﻲ ﻛﻪ در ﻟﻴﺴﺖ وﺟﻮد ﻧﺪارد را در ﺑﺨﺶ . ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد20-5 ﭘﻴﻐﺎﻣﻲ را ﻣﺸﺎﺑﻪ ﺷﻜﻞ
٢٠٥
ﺷﻜﻞ 20-5 (7اﮔﺮ ﻳﻚ آدرس ﭘﺴﺖ اﻟﻜﺘﺮوﻧﻴﻜﻲ ﻛﻪ در ﻟﻴﺴﺖ وﺟﻮد دارد ،ﺑـﺮاي ﻣﺜـﺎل
[email protected] را در ﻗﺴﻤﺖ Emailوارد ﻛﻨﻴﺪ و دﻛﻤﻪ Lookupرا ﻓﺸﺎر دﻫﻴﺪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛـﻪ ﻧـﺎم ﻓـﺮد در ﻛـﺎدر ﭘﻴﻐـﺎم ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺮاي اﻳﺠﺎد ﻳﻚ ،HashTableﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﺮ objCustomersرا ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻴﻢ: // Form level members ;)(private Hashtable objCustomers = new Hashtable ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻧﻮع داده اي ﻣﺘﻐﻴﺮ ،objCustomersاز ﻧﻮع HashTableﺧﻮاﻫـﺪ ﺑـﻮد و ﻋﻨﺎﺻـﺮ اﻳﺠـﺎد ﺷـﺪه در ﻣﺘـﺪ CreateCustomerﺑﻪ ﺟﺎي ذﺧﻴﺮه ﺷﺪن در ArrayListدر ﻳﻚ HashTableذﺧﻴﺮه ﻣﻲ ﺷﻮﻧﺪ. ﺑﺮ ﺧﻼف ﻣﺘﺪﻫﺎي Addﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺒﻠﻲ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﻣﺘﺪ Addﻣﺮﺑﻮط ﺑﻪ HashTableدو ﭘﺎراﻣﺘﺮ درﻳﺎﻓـﺖ ﻣـﻲ ﻛﻨﺪ .اوﻟﻴﻦ ﭘﺎراﻣﺘﺮ ﻋﻨﺼﺮ ﻛﻠﻴﺪ اﺳﺖ ،ﻛﻪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ از آدرس ﭘﺴﺖ اﻟﻜﺘﺮوﻧﻴﻜﻲ ﺑﻪ ﻋﻨﻮان ﻛﻠﻴﺪ اﺳﺘﻔﺎده ﻛـﺮده اﻳـﻢ .در اﺿـﺎﻓﻪ ﻛـﺮدن ﻳﻚ آﻳﺘﻢ ﺑﻪ HashTableاز ﻫﺮ ﻋﻨﺼﺮي ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻋﻨﻮان ﻛﻠﻴﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﻓﻘﻂ ﺑﺎﻳﺪ دﻗﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ اﻳﻦ ﻋﻨﺼﺮ ﺑﺎﻳﺪ در آراﻳﻪ ﻣﻨﺤﺼﺮ ﺑﻪ ﻓﺮد ﺑﺎﺷﺪ و ﻧﻤﻲ ﺗﻮاﻧﻴﺪ از ﻳﻚ ﻋﻨﺼﺮ ﺑﻪ ﻋﻨﻮان ﻛﻠﻴﺪ دو آﻳـﺘﻢ در HashTableاﺳـﺘﻔﺎده ﻛﻨﻴـﺪ .در ﻏﻴـﺮ اﻳـﻦ ﺻﻮرت ﺑﺮﻧﺎﻣﻪ ﻫﻨﮕﺎم اﺟﺮا ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟﻪ ﺷﺪه و ﺑﺴﺘﻪ ﻣﻲ ﺷﻮد .ﭘﺎراﻣﺘﺮ دوم اﻳﻦ ﻣﺘﺪ ،آﻳﺘﻤﻲ اﺳﺖ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻫﻤﺮاه ﺑﺎ اﻳـﻦ ﻛﻠﻴـﺪ در HashTableﻗﺮار دﻫﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﺮ ﺑﺎر ﻛﻪ اﻳﻦ ﻛﻠﻴﺪ را ﺑﻪ HashTableﺑﺪﻫﻴﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ اﻳـﻦ آﻳـﺘﻢ دﺳﺘﺮﺳـﻲ ﭘﻴﺪا ﻛﻨﻴﺪ. // Add the new customer to the list ;)objCustomers.Add(Email.ToLower(),objNewCustomer
٢٠٦
ﺑﺮاي ﺣﺬف ﻳﻚ آﻳﺘﻢ از HashTableﺑﺎﻳﺪ ﻛﻠﻴﺪ آن را ﻛﻪ ﻫﻤﺎن آدرس ﭘﺴﺖ اﻟﻜﺘﺮوﻧﻴﻜﻲ اﺳﺖ ﻣﺸﺨﺺ ﻛﻨﻴﺪ. // Remove the customer from the ArrayList ;))(objCustomers.Remove(txtEmail.Text.ToLower ﻧﻜﺘﻪ :ﺑﺮاي ﺟﻠﻮﮔﻴﺮي از ﺣﺴﺎﺳﻴﺖ ﻧﺴﺒﺖ ﺑﻪ ﻧﻮع ﺣﺮوف ﻫﻨﮕﺎم اﺿﺎﻓﻪ و ﻳﺎ ﺣﺬف ﻛﺮدن ﻳﻚ آﻳﺘﻢ ﺑـﻪ ،HashTableاﺑﺘـﺪا ﺗﻤـﺎم ﺣﺮوف آدرس ﭘﺴﺖ اﻟﻜﺘﺮوﻧﻴﻜﻲ را ﺑﺎ اﺳﺘﻔﺎده از ﺗﺎﺑﻊ ToLowerﺑﻪ ﺣﺮوف ﻛﻮﭼﻚ ﺗﺒﺪﻳﻞ ﻣﻲ ﻛﻨﻴﻢ ،ﺳﭙﺲ رﺷﺘﻪ ﺟﺪﻳﺪ را ﺑﻪ ﻋﻨﻮان ﻛﻠﻴﺪ آراﻳﻪ در ﻧﻈﺮ ﻣﻲ ﮔﻴﺮﻳﻢ. ﺣﺎل ﻣﻲ ﺧﻮاﻫﻴﻢ در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ btnLookupﻛﺪي ﻗﺮار دﻫﻴﻢ ﻛـﻪ ﻛـﺎرﺑﺮ ﺑﺘﻮاﻧـﺪ ﺑـﺎ وارد ﻛـﺮدن آدرس ﭘـﺴﺖ اﻟﻜﺘﺮوﻧﻴﻜﻲ ،ﻧﺎم ﻣﺸﺘﺮك را ﻣﺸﺎﻫﺪه ﻛﻨﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از آدرس وارد ﺷـﺪه در HashTableﺑـﻪ دﻧﺒـﺎل ﻣـﺸﺘﺮك ﺑﮕﺮدﻳﻢ .ﺑﺮاي اﻃﻼع از اﻳﻨﻜﻪ آﻳﺎ آﻳﺘﻢ ﻣﻮرد ﻧﻈﺮ ﻣﺎ در HashTableوﺟﻮد دارد ﻳـﺎ ﻧـﻪ ،ﺑﺎﻳـﺪ از ﺗـﺎﺑﻊ Containsاﺳـﺘﻔﺎده ﻛﻨﻴﻢ .اﻳﻦ ﺗﺎﺑﻊ ﻳﻚ ﻛﻠﻴﺪ را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﻣﻲ ﮔﻴﺮد و ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ آﻳﺘﻤﻲ ﺑﺎ ﻛﻠﻴﺪ داده ﺷﺪه در ﻟﻴﺴﺖ وﺟﻮد دارد ﻳﺎ ﻧـﻪ؟ اﮔـﺮ ﻣﻘﺪار ﺑﺮﮔﺮداﻧﺪه ﺷﺪه ﺗﻮﺳﻂ اﻳﻦ ﺗﺎﺑﻊ ﺑﺮاﺑﺮ ﺑﺎ trueﺑﻮد ،ﻳﻌﻨﻲ آﻳﺘﻢ در ﻟﻴﺴﺖ وﺟﻮد دارد. // If the customer found in the Hashtable == ))(if (objCustomers.Contains(txtEmail.Text.ToLower )true ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻳﻦ آﻳﺘﻢ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻫﻤﺎﻧﻨﺪ دﺳﺘﺮﺳﻲ ﺑﻪ ﻋﻨﺎﺻﺮ در ﻳﻚ آراﻳﻪ ﻋﻤﻞ ﻛﻨﻴﻢ و ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از ﻳـﻚ ﻋـﺪد ﺻـﺤﻴﺢ ،از ﻛﻠﻴﺪ ﻛﻪ در اﻳﻨﺠﺎ ﻫﻤﺎن آدرس ﭘﺴﺖ اﻟﻜﺘﺮوﻧﻴﻜﻲ اﺳﺖ ﺑﻪ ﻋﻨﻮان اﻧﺪﻳﺲ اﺳﺘﻔﺎده ﻛﻨﻴﻢ: // Display the customer name MessageBox.Show("The customer name is: " + ((Customer)objCustomers[txtEmail.Text.ToLower()]).Name, ;)""Structure Demo ﺗﻤﺎم آﻳﺘﻢ ﻫﺎ ﻗﺒﻞ از اﻳﻦ ﻛﻪ در HashTableذﺧﻴﺮه ﺷﻮﻧﺪ ،ﺑﻪ ﺷﻴﺊ از ﻛﻼس Objectﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻌﺪ از اﻳﻦ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻠﻴﺪ ،ﻣﻜﺎن آﻧﻬﺎ را در آراﻳﻪ ﭘﻴﺪا ﻛﺮدﻳﻢ ،ﻗﺒﻞ از اﺳﺘﻔﺎده ﺑﺎﻳﺪ آﻧﻬﺎ را ﺑﻪ ﻧﻮع داده اي اﺻﻠﻲ ﺧﻮد ﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺒﻞ ﮔﻔﺘﻢ 1ﺑﺮاي اﻳﻨﻜﻪ ﻳﻚ ﻣﺘﻐﻴﺮ را ﺑﻪ ﻧﻮع داده اي دﻳﮕﺮي ﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ ﺑﺎﻳﺪ از ﻋﻤﻠﮕﺮ )( اﺳﺘﻔﺎده ﻛﻨـﻴﻢ .در اﻳـﻦ ﻗـﺴﻤﺖ ﺑـﺮاي ﺗﺒﺪﻳﻞ آﻳﺘﻢ ذﺧﻴﺮه ﺷﺪه در HashTableاز ﻧﻮع Objectﺑﻪ ﻧﻮع Customerﺑﻪ ﺻﻮرت زﻳﺮ ﻋﻤﻞ ﻣﻲ ﻛﻨﻴﻢ: ])((Customer)objCustomers[txtEmail.Text.ToLower ﺣﺎل ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ Nameﻧﺎم ﻣﺮﺑﻮط ﺑﻪ ﻣﺸﺘﺮك را در ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ دﻫﻴﻢ.
1رﺟﻮع ﻛﻨﻴﺪ ﺑﻪ ﺑﺨﺶ ﺗﺒﺪﻳﻞ ﻧﻮﻋﻬﺎي داده اي
٢٠٧
ﺟﻠﻮﮔﻴﺮي از وارد ﺷﺪن ﻋﻨﺎﺻﺮ ﺗﻜﺮاري: ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ از ﻳﻚ ﻛﻠﻴﺪ ﻧﻤﻲ ﺗﻮان دو ﺑﺎر در ﻳﻚ HashTableاﺳﺘﻔﺎده ﻛﺮد .اﻳﻦ ﻛﺎر ﺑﺎﻋﺚ ﺑـﻪ وﺟـﻮد آﻣـﺪن ﺧﻄـﺎ در زﻣﺎن اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺷﻮد .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ ﺑﺎﻳﺪ ﻗﺒﻞ از اﻳﻨﻜﻪ ﻋﻨﺼﺮي را ﺑﻪ ﻳﻚ HashTableاﺿﺎﻓﻪ ﻛﻨﻴﻢ ،از ﻣﻨﺤﺼﺮ ﺑـﻪ ﻓـﺮد ﺑﻮدن آن ﻣﻄﻤﺌﻦ ﺷﻮﻳﻢ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﭼﮕﻮﻧﮕﻲ ﺟﻠﻮﮔﻴﺮي از اﻳﻦ ﺧﻄﺎ در ﺑﺮﻧﺎﻣﻪ را ﺧﻮاﻫﻴﺪ دﻳﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺟﻠﻮﮔﻴﺮي از وارد ﺷﺪن ﻋﻨﺎﺻﺮ ﺗﻜﺮاري (1ﺑﺮاي ﻣﺸﺎﻫﺪه اﻳﻦ ﻛﻪ در ﺻﻮرت وارد ﻛﺮدن ﻛﻠﻴﺪ ﺗﻜﺮاري ﺑﻪ ،HashTableﭼﮕﻮﻧﻪ ﺧﻄﺎ اﻳﺠﺎد ﻣﻲ ﺷﻮد ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي دﻛﻤﻪ ي Testﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻟﻴﺴﺖ ﻣﺸﺘﺮﻛﻴﻦ ﭘﺮ ﺷﻮد .ﺣﺎل ﻣﺠﺪدا ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن Testﻛﻠﻴـﻚ ﻛﻨﻴﺪ .ﭘﻨﺠﺮه ﺧﻄﺎﻳﻲ را ﻣﺸﺎﺑﻪ ﺷﻜﻞ 21-5ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 21-5 (2ﺑﺮ روي دﻛﻤﻪ ي Stop Debuggingدر ﻧﻮار اﺑﺰار وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﺟـﺮاي ﺑﺮﻧﺎﻣـﻪ ﻣﺘﻮﻗـﻒ ﺷﻮد. (3وﻳﺮاﻳﺸﮕﺮ ﻛﺪ را ﺑﺮاي Form1ﺑﺎز ﻛﻨﻴﺪ و ﺑﻪ ﻣﺤﻞ ﻣﺘﺪ CreateCustomerﺑﺮوﻳﺪ .ﻛـﺪ زﻳـﺮ را ﺑـﻪ اﻳـﻦ ﻣﺘـﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ ﻫﺮ ﺑﺎر ﻗﺒﻞ از اﻳﻨﻜﻪ ﻣﺸﺘﺮك ﺑﻪ ﻟﻴﺴﺖ اﺿﺎﻓﻪ ﺷﻮد از ﻋﺪم وﺟﻮد آن در ﻟﻴﺴﺖ ﻣﻄﻤﺌﻦ ﺷﻮﻳﻢ: public void CreateCustomer(string FirstName, )string LastName, string Email { // Declare a customer object ;Customer objNewCustomer // Create the new customer ;objNewCustomer.FirstName = FirstName
٢٠٨
objNewCustomer.LastName = LastName; objNewCustomer.Email = Email; // Check if the customer isn't currently in the list if (objCustomers.Contains(Email.ToLower()) == false) { // Add the new customer to the list objCustomers.Add(Email.ToLower(), objNewCustomer); // Add the new customer to the ListBox control lstCustomers.Items.Add(objNewCustomer); } else { MessageBox.Show("The customer: " + FirstName + " + LastName + " is currently in the list! ", "Structure Demo");
" } }
. ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻟﻴﺴﺖ ﻣﺸﺘﺮﻛﻴﻦ ﻛﺎﻣﻞ ﺷﻮدTest ( ﻣﺠﺪدا ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﺮ روي دﻛﻤﻪ ي4 ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﻣﺸﺘﺮﻛﻲ را ﺑـﺮاي ﺑـﺎر دوم ﺑـﻪ. ﻛﻠﻴﻚ ﻛﻨﻴﺪTest ( ﺣﺎل دوﺑﺎره روي دﻛﻤﻪ ي5 در ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﻛﻪ ﻣﺸﺘﺮك ﻫﻢ اﻛﻨﻮن در ﻟﻴﺴﺖ وﺟـﻮد دارد و ﻧﻤـﻲ ﺗﻮاﻧﻴـﺪ آن را،ﻟﻴﺴﺖ وارد ﻛﻨﻴﺪ .ﻣﺠﺪدا ﺑﻪ ﻟﻴﺴﺖ اﺿﺎﻓﻪ ﻛﻨﻴﺪ
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ زﻳـﺮا در. دﻟﻴﻞ آن ﻧﻴﺰ ﻣﺸﺨﺺ اﺳـﺖ.ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﺑﺮاي ﺑﺎر دوم ﻛﻪ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻣﻲ ﻛﻨﻴﺪ ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟﻪ ﻧﻤﻲ ﺷﻮﻳﺪ در اﻳﻦ ﺻﻮرت اﮔﺮ ﻛﻠﻴﺪ.اﺟﺮاي دوم ﺑﺮﻧﺎﻣﻪ ﻓﻘﻂ در ﺻﻮرﺗﻲ ﻳﻚ آﻳﺘﻢ ﺑﻪ ﻟﻴﺴﺖ اﺿﺎﻓﻪ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﻠﻴﺪ آن در ﺟﺪول وﺟﻮد ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ را ﺑﺮﮔﺮداﻧﺪه و ﺑﺮﻧﺎﻣﻪ آﻳﺘﻢ را ﺑﻪ ﻟﻴـﺴﺖ اﺿـﺎﻓﻪ ﻣـﻲfalse ﺗﺎﺑﻊ ﻣﻘﺪار، ﺑﻔﺮﺳﺘﻴﻢContains آﻳﺘﻢ را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ ﺗﺎﺑﻊ :ﻛﻨﺪ // Check if the customer isn't currently in the list if (objCustomers.Contains(Email.ToLower()) == false) { // Add the new customer to the list objCustomers.Add(Email.ToLower(), objNewCustomer); // Add the new customer to the ListBox control lstCustomers.Items.Add(objNewCustomer); }
٢٠٩
اﮔﺮ ﺗﺎﺑﻊ Containsﻣﻘﺪار trueرا ﺑﺮﮔﺮداﻧﺪ ،ﻣﻲ ﺗﻮان ﻧﺘﻴﺠﻪ ﮔﺮﻓﺖ ﻛﻪ آﻳﺘﻢ در ﻟﻴﺴﺖ وﺟﻮد داﺷﺘﻪ اﺳﺖ .ﭘﺲ ﺑﺎ ﻧﻤﺎﻳﺶ ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم اﻳﻦ ﻣﻮرد را ﺑﻪ اﻃﻼع ﻛﺎرﺑﺮ ﻣﻲ رﺳﺎﻧﻴﻢ و از ﺗﺎﺑﻊ ﺧﺎرج ﻣﻲ ﺷﻮﻳﻢ. else { " MessageBox.Show("The customer: " + FirstName + + LastName + " is currently in the list! ", ;)""Structure Demo
" }
ﻧﺘﻴﺠﻪ: در اﻳﻦ ﻓﺼﻞ روﺷﻬﺎﻳﻲ را ﺑﺮاي ﻣﺪﻳﺮﻳﺖ و ﻧﮕﻬﺪاري ﮔﺮوه ﻫﺎي ﭘﻴﭽﻴﺪه داده اي ﻓﺮا ﮔﺮﻓﺘﻴﻢ .ﻓﺼﻞ را ﺑﺎ آﻣـﻮﺧﺘﻦ ﻣﻔـﺎﻫﻴﻢ آراﻳـﻪ ﺷـﺮوع ﻛﺮده و ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻣﺘﻐﻴﺮﻫﺎﻳﻲ را اﻳﺠﺎد ﻛﺮد ﻛﻪ ﺑﻴﺶ از ﻳﻚ ﻣﻘﺪار را در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﻨﺪ. ﺳﭙﺲ ﺑﻪ ﺑﺮرﺳﻲ ﻣﻔﺎﻫﻴﻢ ﺷﻤﺎرﻧﺪه ﻫﺎ و ﺛﺎﺑﺖ ﻫﺎ ﭘﺮداﺧﺘﻴﻢ .دﻳﺪﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ اﻳﻦ دو ﻗﺎﺑﻠﻴﺖ ﺑﺎﻋـﺚ ﻣـﻲ ﺷـﻮﻧﺪ ﻛـﻪ ﻛـﺪﻫﺎي ﺧﻮاﻧـﺎﺗﺮي ﺑﻨﻮﻳﺴﻴﻢ .ﺑﺎ اﺳﺘﻔﺎده از ﺷﻤﺎرﻧﺪه ﻫﺎ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از ﻣﺘﻐﻴﺮﻫﺎي اﺑﺘﺪاﻳﻲ ،ﻧﻮع ﻫﺎي ﻗﺎﺑﻞ ﻓﻬﻢ ﺗﺮي را اﺳﺘﻔﺎده ﻛﻨﻴﻢ ،ﻣـﺜﻼ ﺑـﻪ ﺟﺎي اﺳﺘﻔﺎده از ﻛﺪ " "mode = 3ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻛﺪ " "mode = MyMode.Menuاﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺛﺎﺑﺖ ﻫـﺎ اﻳـﻦ اﺟﺎزه را ﻣﻲ دﻫﻨﺪ ﻛﻪ ﻳﻚ اﺳﻢ ﺧﺎص را ﺑﻪ ﻳﻚ ﻣﻘﺪار ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﻛﺪ اﺳﺘﻔﺎده ﺷﺪه اﺳﺖ ﻧـﺴﺒﺖ دﻫـﻴﻢ و در ﻛـﺪ از اﺳـﻢ ﻣﺸﺨﺺ ﺷﺪه اﺳﺘﻔﺎده ﻛﻨﻴﻢ. ﺳﭙﺲ ﺳﺎﺧﺘﺎرﻫﺎ را ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ .دﻳﺪﻳﻢ ﻛﻪ ﺳﺎﺧﺘﺎرﻫﺎ ﻫﻤﺎﻧﻨﺪ ﻛﻼﺳﻬﺎ ﻫﺴﺘﻨﺪ و اﺟﺎزه ﻣﻲ دﻫﻨﺪ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﻓـﺮد ﻳـﺎ ﻣـﻮرد ﺧﺎص را در ﻳﻚ ﮔﺮوه ﻗﺮار دﻫﻴﻢ .ﺳﭙﺲ ﺑﺎ اﻧﻮاع ﻣﺨﺘﻠﻒ ﻛﻠﻜﺴﻴﻮن ﻫﺎ از ﻗﺒﻴﻞ ArrayListآﺷـﻨﺎ ﺷـﺪﻳﻢ در آﺧـﺮ ﻫـﻢ ﻛـﻼس HashTableو ﻓﻮاﻳﺪ آن را ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ و ﻣـﺸﺎﻫﺪه ﻛـﺮدﻳﻢ ﻛـﻪ ﭼﮕﻮﻧـﻪ ﻣـﻲ ﺗـﻮان ﺑـﺎ اﺳـﺘﻔﺎده از آن ﻛﻠﻜـﺴﻴﻮﻧﻲ ﻗـﻮﻳﺘﺮ از ArrayListﻫﺎ اﻳﺠﺎد ﻛﺮد. در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ:
ﺗﻌﺮﻳﻒ آراﻳﻪ اي از ﻋﻨﺎﺻﺮ ﻣﺮﺗﺒﻂ ﺑﻪ ﻫﻢ ﺣﺮﻛﺖ در ﺑﻴﻦ ﻋﻨﺎﺻﺮ آراﻳﻪ و ﭘﻴﺪا ﻛﺮدن آﺧﺮﻳﻦ ﻋﻨﺼﺮ آن ﺗﻌﺮﻳﻒ ﻳﻚ ﺷﻤﺎرﻧﺪه ﺑﺎ اﺳﺘﻔﺎده از enum اﻳﺠﺎد و اﺳﺘﻔﺎده از ﺳﺎﺧﺘﺎرﻫﺎ ﺑﺮاي ﻧﮕﻬﺪاري داده ﻫﺎي ﻣﺮﺗﺒﻂ ﺑﻪ ﻫﻢ اﺳﺘﻔﺎده از ArrayListﺑﺮاي ﻧﮕﻬﺪاري اﻧﻮاع ﻣﺘﻐﻴﻴﺮ ﻫﺎ اﺳﺘﻔﺎده از ﻛﻠﻜﺴﻴﻮن ﻫﺎ ﺑﺮاي ﻧﮕﻬﺪاري و ﻣﺪﻳﺮﻳﺖ داده ﻫﺎي ﻣﺮﺗﺒﻂ ﺑﻪ ﻫﻢ
ﺗﻤﺮﻳﻦ:
٢١٠
ﺗﻤﺮﻳﻦ :1 ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﺤﺖ وﻳﻨﺪوز اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ ﺷﺎﻣﻞ ﺳﻪ ﻛﻨﺘﺮل Buttonﺑﺎﺷﺪ .ﻳﻚ ﺷﻤﺎرﻧﺪه ﺷﺎﻣﻞ ﺳﻪ ﻧﺎم را ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ. ﺑﺮاي ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickﻫﺮ ﻳﻚ از دﻛﻤﻪ ﻫﺎ ﻛﺪي ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﻣﺤﺘﻮي ﻳﻜﻲ از ﻧﺎم ﻫﺎ و ﻣﻘﺪار ﻣﺘﻨﺎﻇﺮ آن را در ﺷﻤﺎرﻧﺪه ﻧﻤﺎﻳﺶ دﻫﺪ) .ﺑﺮاي ﻧﻤﺎﻳﺶ ﻣﻘﺪار ﻋﺪدي ﻣﺘﻨﺎﻇﺮ ﺑﺎ ﻫﺮ ﻳﻚ از آﻳﺘﻢ ﻫﺎي ﺷﻤﺎرﻧﺪه ،ﻧﻮع آن را ﺑﻪ ﻋﺪد ﺻﺤﻴﺢ ﺗﺒﺪﻳﻞ ﻛﻨﻴﺪ(
٢١١
ﻓﺼﻞ ﺷﺸﻢ :اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﭘﻴﺶ ﻧﻴﺰ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،در C#ﭘﻨﺠﺮه ﻫﺎ ﺑﻪ ﻧﺎم ﻓﺮم ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮﻧﺪ .در ﭘﻨﺞ ﻓﺼﻞ ﻗﺒﻠﻲ از اﻳﻦ ﻓﺮم ﻫﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﺪ ،اﻣﺎ درك ﻛﺎﻣﻠﻲ از آن ﻧﺪاﺷﺘﻴﺪ و ﺑﻴﺸﺘﺮ ﺑﺮ روي ﻛﺪﻫﺎﻳﻲ ﻛﻪ درون آن ﻣﻲ ﻧﻮﺷـﺘﻴﺪ ﺗﻤﺮﻛـﺰ ﻣـﻲ ﻛﺮدﻳﺪ. در اﻳﻦ ﻓﺼﻞ ،ﺑﻴﺸﺘﺮ ﺑﺎ ﺟﺰﺋﻴﺎت ﻓﺮﻣﻬﺎي وﻳﻨﺪوزي آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ و ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑـﺎ اﺳـﺘﻔﺎده از ﻓﺮﻣﻬـﺎي وﻳﻨﺪوزي در وﻳﮋوال ،C#ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﺑﺎ اﻣﻜﺎﻧﺎت ﻛﺎﻣﻞ ﻧﻮﺷﺖ .در اﻳﻦ ﻓﺼﻞ ﺑﻪ ﺻﻮرت ﻛﻠﻲ ﺑﻪ ﺑﺮرﺳﻲ ﻣﺒﺎﺣﺚ زﻳﺮ ﺧﻮاﻫﻴﻢ ﭘﺮداﺧﺖ:
اﺿﺎﻓﻪ ﻛﺮدن ﺧﺼﻮﺻﻴﺎت ﺑﻴﺸﺘﺮ ﺑﻪ ﻓﺮم ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮﻟﻬﺎي TextBox ،Buttonو .RadioButton اﻳﺠﺎد ﻳﻚ ﻧﻮار اﺑﺰار ﺳﺎده ﻛﻪ داراي دﻛﻤﻪ ﻫﺎﻳﻲ ﺑﺮاي ﭘﺎﺳﺦ ﺑﻪ روﻳﺪادﻫﺎ ﺑﺎﺷﺪ. اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي ﻛﻪ داراي ﺑﻴﺶ از ﻳﻚ ﻓﺮم ﺑﺎﺷﻨﺪ.
ﭘﺎﺳﺦ ﺑﻪ روﻳﺪادﻫﺎ: اﻳﺠﺎد ﻳﻚ راﺑﻂ ﮔﺮاﻓﻴﻜﻲ ﻛﺎرﺑﺮ 1ﺑﺎ اﺳﺘﻔﺎده از ﻓﺮﻣﻬﺎي وﻳﻨﺪوزي ﺗﺎ ﺣﺪ زﻳﺎدي ﺑﻪ ﭘﺎﺳﺦ دادن ﺑﻪ روﻳﺪادﻫﺎ ﺑﺴﺘﮕﻲ دارد .ﺑـﻪ ﻫﻤـﻴﻦ ﻋﻠـﺖ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺮاي وﻳﻨﺪوز ﻋﻤﻮﻣﺎً ﺑﻪ ﻋﻨﻮان ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ روﻳﺪاد ﮔﺮا ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮد .ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒـﻞ ﻣـﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﻓﺮم ﺑﺎ اﺳﺘﻔﺎده از ﻣﺎوس ﻛﻨﺘﺮل ﻫﺎي ﻣﻮرد ﻧﻈﺮﺗـﺎن را ﺑـﺮ روي ﻳـﻚ ﻓـﺮم ﺧـﺎﻟﻲ ﻛـﻪ در ﺑﺨـﺶ Forms Designerاﺳﺖ ﻗﺮار ﻣﻲ دﻫﻴﺪ .ﻫﺮ ﻛﺪام از اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ ﺷﻤﺎ ﺑﮕﻮﻳﻨﺪ ﻛﻪ ﭼﻪ زﻣﺎﻧﻲ ﻳﻚ روﻳﺪاد اﺗﻔـﺎق ﻣـﻲ اﻓﺘـﺪ. ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎﻧﻲ ﻛﻪ ﺑﺮ روي ﻓﺮم ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ ﻛﻠﻴﻚ ﻛﻨﻴﺪ آن دﻛﻤﻪ ،روﻳﺪاد ﻛﻠﻴﻚ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﻃﻼع ﻣﻲ دﻫﺪ .ﺑﻨﺎﺑﺮاﻳﻦ اﻳﻦ ﻓﺮﺻﺖ ﺑﻪ ﺷﻤﺎ داده ﻣﻲ ﺷﻮد ﻛﻪ ﻛﺪﻫﺎﻳﻲ را در ﺑﺮﻧﺎﻣﻪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﺗﺎ ﺑﺎ ﻛﻠﻴﻚ ﺷﺪن ﺑـﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن اﺟﺮا ﺷﻮﻧﺪ .ﻧﺤﻮه اﺳﺘﻔﺎده از اﻳﻦ ﻣﻮارد را در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ.
ﺗﻨﻈﻴﻢ ﻳﻚ روﻳﺪاد ﺑﺮاي ﻛﻨﺘﺮل :Button ﻳﻚ روش ﺧﻮب ﺑﺮاي ﺗﻮﺿﻴﺢ ﻣﻔﻬﻮم روﻳﺪاد ،اﻳﺠﺎد ﻳﻚ روﻳﺪاد ﺑﺮاي دﻛﻤﻪ ﻓﺮﻣﺎن اﺳﺖ .ﺑﺮاي ﻣﺜﺎل ﻳﻚ روﻳﺪاد ﻛﻠﻴﻚ ﻛﻪ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ آن ﻫﻨﮕﺎم ﻛﻠﻴﻚ ﺷﺪن ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن اﺟﺮا ﺷﻮد .در ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي روﻳﺪادﻫﺎي زﻳﺎدي وﺟﻮد دارﻧﺪ ﻛﻪ ﻫـﺮ ﻳـﻚ در ﻣﻮاﻗـﻊ ﺧﺎﺻﻲ رخ ﻣﻲ دﻫﻨﺪ .ﺗﺎﻛﻨﻮن اﺳﺘﻔﺎده از روﻳﺪاد ﻛﻠﻴﻚ ﻣﺮﺑﻮط ﺑﻪ دﻛﻤﻪ ﻓﺮﻣـﺎن را در ﻋﻤـﻞ دﻳـﺪه اﻳـﺪ ..در ﺑﺨـﺶ اﻣﺘﺤـﺎن ﻛﻨﻴـﺪ ﺑﻌـﺪ، روﻳﺪادﻫﺎي ﺑﻴﺸﺘﺮي از ﻛﻨﺘﺮل دﻛﻤﻪ ﻓﺮﻣﺎن را ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﻣﺸﺎﻫﺪه ﻧﻜﺮدﻳﺪ ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از روﻳﺪادﻫﺎي دﻛﻤﻪ ﻓﺮﻣﺎن
1راﺑﻂ ﮔﺮاﻓﻴﻜﻲ ﻛﺎرﺑﺮ ﻳﺎ ،GUIﻣﺤﻴﻄﻲ اﺳﺖ ﻛﻪ در آن ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺎ ﻛﻠﻴﻚ ﺑﺮ روي ﺑﺮﻧﺎﻣﻪ ﻫﺎ و ﻳﺎ دﻛﻤﻪ ﻫﺎي ﻓﺮﻣﺎن ،ﺑﻪ آﻧﻬﺎ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ
٢١٢
(1وﻳﮋوال اﺳﺘﻮدﻳﻮ را اﺟﺮا ﻛﻨﻴﺪ و ﮔﺰﻳﻨﻪ … File New Projectرا از ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻧﺘﺨﺎب ﻛﻨﻴﺪ .در ﭘﻨﺠﺮه ،New Projectﮔﺰﻳﻨـﻪ Visual C#را از ﻗـﺴﻤﺖ Project Typesو ﮔﺰﻳﻨـﻪ Windows Applicationرا از ﻗــﺴﻤﺖ Templatesاﻧﺘﺨــﺎب ﻛﻨﻴــﺪ .در ﻗــﺴﻤﺖ ،Nameﻧــﺎم Hello World 2را وارد ﻛﻨﻴﺪ و ﺳﭙﺲ ﺑﺮ روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﭘﺮوژه اﻳﺠﺎد ﺷﻮد. (2ﺑﺮ روي ﻓﺮم اﻳﺠﺎد ﺷـﺪه ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ و ﺳـﭙﺲ در ﭘﻨﺠـﺮه Propertiesﺧﺎﺻـﻴﺖ Textرا از Form1ﺑـﻪ Hello, World! 2.0ﺗﻐﻴﻴﺮ دﻫﻴﺪ. (3ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒـﻪ اﺑـﺰار ﻳـﻚ ﻛﻨﺘـﺮل Buttonﺑـﺮ روي ﻓـﺮم ﻗـﺮار داده ،ﺧﺎﺻـﻴﺖ Textآن را ﺑـﻪ Hello ! Worldو ﺧﺎﺻﻴﺖ Nameآن را ﺑﻪ btnSayHelloﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺳﭙﺲ اﻧﺪازه ﻓـﺮم و ﻛﻨﺘـﺮل Button را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 6-1ﺷﻮد.
ﺷﻜﻞ 1-6 (4ﺑﺮ روي ﻛﻨﺘﺮل Buttonﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ. )private void btnSayHello_Click(object sender, EventArgs e { // Display a MessageBox ;)MessageBox.Show("Hello World!", this.Text } (5در ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ،ﺑﻪ دو ﻛﺎدر ﺑﺎﻻي ﺻﻔﺤﻪ ﺗﻮﺟﻪ ﻛﻨﻴﺪ .ﻛﺎدر ﺳﻤﺖ ﭼـﭗ ﻣﺮﺑـﻮط ﺑـﻪ ﻧﻤـﺎﻳﺶ ﻛﻼﺳـﻬﺎ اﺳـﺖ و ﻧـﺎم ﻛﻼﺳﻬﺎي ﺗﻌﺮﻳﻒ ﺷﺪه در اﻳﻦ ﻗﺴﻤﺖ ،در اﻳﻦ ﻛﺎدر ﻗﺮار ﻣﻲ ﮔﻴﺮد .در ﺣﺎﻟﺖ ﻋﺎدي ﻓﻘﻂ ﻳﻚ ﻛﻼس ﻛﻪ ﻣﺮﺑﻮط ﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﺳﺖ در اﻳﻦ ﻗﺴﻤﺖ وﺟﻮد دارد .اﻣﺎ اﮔﺮ ﻛﻼﺳﻬﺎي دﻳﮕﺮي را در اﻳﻦ ﻗﺴﻤﺖ ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ،ﻧﺎم آﻧﻬﺎ ﻧﻴﺰ ﺑﻪ اﻳـﻦ ﻟﻴـﺴﺖ اﺿـﺎﻓﻪ ﻣﻲ ﺷﻮد .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻛﻼﺳﻲ ﺑﻪ ﻧﺎم TempClassدر ﻗﺴﻤﺖ ﭘﺎﻳﻴﻦ ﻛﻼس Form1در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ ﻣﺤﺘﻮﻳﺎت اﻳﻦ ﻛﺎدر ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 2-6ﺧﻮاﻫﺪ ﺑﻮد.
ﺷﻜﻞ 2-6 (6ﺑﻌﺪ از اﻳﻨﻜﻪ ﻳﻜﻲ از ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﻟﻴﺴﺖ ﺳﻤﺖ ﭼﭗ را اﻧﺘﺨﺎب ﻛﺮدﻳﺪ ،اﻋﻀﺎي آن ﻛﻼس ﻣﺎﻧﻨﺪ ﻣﺘﺪﻫﺎ ،ﺧﺎﺻﻴﺖ ﻫﺎ و ...در ﻟﻴﺴﺖ ﺳﻤﺖ راﺳﺖ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ در ﻟﻴﺴﺖ ﺳﻤﺖ ﭼﭗ ،ﻛﻼس ﻣﺮﺑﻮط ﺑـﻪ ﻓـﺮم Form1را اﻧﺘﺨﺎب ﻛﻨﻴﺪ ،اﻋﻀﺎي آن ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 3-6ﺧﻮاﻫﻨﺪ ﺑﻮد .ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻟﻴﺴﺖ در زﻳﺮ ﺗﻌﺮﻳﻒ ﺷﺪه اﻧﺪ:
٢١٣
ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﻣﺤﺘﻮﻳﺎت اﻳﻦ ﻟﻴﺴﺖ ﺑﺮ اﺳﺎس ﻧﺎم ﻛﻼﺳﻲ ﻛﻪ در ﺳﻤﺖ ﭼﭗ اﻧﺘﺨﺎب ﻣﻲ ﻛﻨﻴﺪ ﺗﻐﻴﻴـﺮ ﻣـﻲ ﻛﻨـﺪ .ﺑـﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻟﻴﺴﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻴﻦ اﻋﻀﺎي ﻣﻮﺟﻮد در ﻳﻚ ﻛﻼس ﺟﺎ ﺑﻪ ﺟﺎ ﺷﻮﻳﺪ .اﻟﺒﺘـﻪ وﻇﻴﻔـﻪ اﺻـﻠﻲ اﻳـﻦ ﻟﻴـﺴﺖ ﻧﻤﺎﻳﺶ ﺗﻤﺎم اﻋﻀﺎي ﻣﺮﺗﺒﻂ ﺑﺎ ﻛﻼﺳﻲ اﺳﺖ ﻛﻪ در ﻟﻴﺴﺖ ﺳﻤﺖ ﭼﭗ اﻧﺘﺨﺎب ﻛﺮده اﻳﺪ. در اﺑﺘﺪاي اﻳﻦ ﺑﺮﻧﺎﻣﻪ ،ﻳﻚ دﻛﻤﻪ ﻓﺮﻣﺎن ﺑﻪ ﻧﺎم btnSayHelloﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮدﻳﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻟﻴﺴﺖ ﻧﻴﺰ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،ﻓﺮم ﻣﺎ داراي ﻳﻚ ﻋﻀﻮ از ﻧـﻮع ﻛﻨﺘـﺮل Buttonﺑـﻪ ﻧـﺎم btnSayHello اﺳﺖ .ﺑﺎ اﻧﺘﺨﺎب اﻳﻦ ﮔﺰﻳﻨﻪ از ﻟﻴﺴﺖ ﺳﻤﺖ ﭼﭗ ،وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺷﻤﺎ را ﺑﻪ ﺧﻄﻲ از ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺑﺮد ﻛﻪ اﻳـﻦ ﻛﻨﺘـﺮل در آن ﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ.
ﺷﻜﻞ 3-6 ﺑﻌــﺪ از اﻳﻨﻜــﻪ ﻛﻨﺘــﺮل Buttonرا ﺑــﻪ ﻓــﺮم اﺿــﺎﻓﻪ ﻛــﺮدﻳﻢ ،ﻣﺘــﺪي ﺑــﺮاي روﻳــﺪاد ﻛﻠﻴــﻚ آن ﺑــﻪ ﻧــﺎم btnSayHello_Clickاﻳﺠــﺎد ﻛــﺮدﻳﻢ .ﭘــﺲ ﻳﻜــﻲ دﻳﮕــﺮ از اﻋــﻀﺎي ﻓــﺮم ﻣــﺎ ﻧﻴــﺰ ﻣﺘــﺪي ﺑــﻪ ﻧــﺎم btnSayHello_Clickﺧﻮاﻫﺪ ﺑﻮد .ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻟﻴﺴﺖ ﻣـﺸﺎﻫﺪه ﻣـﻲ ﻛﻨﻴـﺪ ،اﻳـﻦ ﻋـﻀﻮ از ﻛـﻼس Form1ﻧﻴﺰ در ﻟﻴﺴﺖ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﺳﺖ ﻛﻪ ﺑﺎ اﻧﺘﺨﺎب آن ﻣﻜﺎن ﻧﻤﺎ ﺑﻪ ﻗﺴﻤﺘﻲ از ﺑﺮﻧﺎﻣﻪ ﻛﻪ اﻳﻦ ﻣﺘﺪ ﻗـﺮار دارد ﻣﻨﺘﻘﻞ ﻣﻲ ﺷﻮد. ﻫﺮ ﻛﻼس داراي ﻣﺘﺪي ﻫﻤﻨﺎم ﺑﺎ ﻧﺎم ﻛﻼس اﺳﺖ .اﮔﺮ ﺑﻪ ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻟﻴﺴﺖ ﺳﻤﺖ راﺳﺖ دﻗﺖ ﻛﻨﻴﺪ ،ﻣﺘﺪي را ﺑﺎ ﻧﺎم Form1ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد .اﻳﻦ ﻣﺘﺪ ﻛﻪ ﺑﻪ ﻧﺎم ﺳﺎزﻧﺪه ﻛﻼس ﻧﻴﺰ ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮد ،ﺷﺎﻣﻞ ﻛﺪﻫﺎﻳﻲ اﺳﺖ ﻛﻪ در اﺑﺘﺪاي اﺟﺮاي ﻛﻼس ،ﺷﺮاﻳﻂ اوﻟﻴﻪ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻛﻼس را ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﺑﺨﻮاﻫﻴـﺪ ﻛـﺪي ﻫﻨﮕﺎم اﻳﺠﺎد ﺷﺪن ﻳﻚ ﺷﻴﺊ از ﻳﻚ ﻛﻼس اﺟﺮا ﺷﻮد ،ﺑﺎﻳﺪ آن را در اﻳﻦ ﻗﺴﻤﺖ ﻗﺮار دﻫﻴﺪ. ﻳﻜﻲ دﻳﮕﺮ از ﮔﺰﻳﻨﻪ ﻫﺎي اﻳﻦ ﻟﻴﺴﺖ ،ﮔﺰﻳﻨﻪ Disposeاﺳﺖ .ﻛﻼس ﺗﺸﻜﻴﻞ دﻫﻨـﺪه ﻓـﺮم داراي ﺗـﺎﺑﻌﻲ ﺑـﻪ ﻧـﺎم Disposeاﺳﺖ ﻛﻪ ﻣﻨﺎﺑﻊ ﮔﺮﻓﺘﻪ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ﻛﻨﺘﺮﻟﻬﺎي ﻛﻼس را در ﭘﺎﻳﺎن اﺟﺮاي اﻳﻦ ﻓﺮم از ﺑﺮﻧﺎﻣـﻪ آزاد ﻣـﻲ ﻛﻨﺪ. ﻳﻜــــﻲ دﻳﮕــــﺮ از اﻋــــﻀﺎي ﻛــــﻼس Form1ﻛــــﻪ در ﻟﻴــــﺴﺖ ﻣــــﺸﺎﻫﺪه ﻣــــﻲ ﻛﻨﻴــــﺪ ،ﻣﺘــــﺪ InitializeComponentاﺳﺖ ﻛﻪ ﻣﺴﺌﻮل ﻣﻘﺪار دﻫﻲ اوﻟﻴﻪ ﺑﻪ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟـﻮد در ﻛـﻼس اﺳـﺖ. ﺑﺮاي ﻣﺜﺎل ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﺗﻨﻈﻴﻢ ﻧﺎم ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻓﺮم ،ﺗﻨﻈﻴﻢ ﺧﺎﺻﻴﺖ Textآﻧﻬﺎ و ﻳﺎ ﻫﺮ ﺗﻐﻴﻴﺮ دﻳﮕـﺮي ﻛـﻪ ﺑﺎ اﺳﺘﻔﺎده از ﻗﺴﻤﺖ Form Designerﺑﻪ وﺟﻮد ﻣﻲ آورﻳﺪ ،در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﻃﻮر اﺗﻮﻣﺎﺗﻴﻚ ﺗﻮﺳﻂ وﻳـﮋوال اﺳﺘﻮدﻳﻮ ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد .ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﺗﺎ ﺣﺪ اﻣﻜﺎن ﻛﺪﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻣﺘـﺪ را ﺑـﻪ ﺻـﻮرت دﺳـﺘﻲ ﺗﻐﻴﻴـﺮ ﻧﺪﻫﻴﺪ و از ﺑﺨﺶ Form Designerﺑﺮاي ﺗﻐﻴﻴﺮ ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ وﻳﮋوال 2005 C#آﻳﻜﻮن ﻛﻮﭼﻜﻲ را در ﺳﻤﺖ ﭼﭗ ﻫﺮ ﻳﻚ از ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟـﻮد در ﻟﻴﺴﺖ ﻗﺮار ﻣﻲ دﻫﺪ .ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ آﻳﻜﻮﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻧﻮع آﻧﻬﺎ را ﺗﺸﺨﻴﺺ دﻫﻴﺪ .ﺑﺮاي ﻣﺜﺎل ،ﻳـﻚ ﺟﻌﺒـﻪ ي ﺻـﻮرﺗﻲ
٢١٤
رﻧﮓ ﻛﻮﭼﻚ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻳﻚ ﻣﺘﺪ اﺳﺖ ،ﻳﻚ ﺟﻌﺒﻪ آﺑﻲ رﻧﮓ ﻛﻮﭼﻚ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻳﻚ ﻋﻀﻮ از ﻛﻼس اﺳـﺖ و .... ﻧﻜﺘﻪ :در ﻛﻨﺎر اﻳﻦ آﻳﻜﻮﻧﻬﺎ ﻛﻪ ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن ﻧﻮع ﻋﻀﻮﻫﺎي ﻳﻚ ﻛﻼس ﺑﻪ ﻛﺎر ﻣﻲ رود ،آﻳﻜﻮﻧﻬﺎي ﻛﻮﭼـﻚ دﻳﮕـﺮي ﻧﻴـﺰ ﻗـﺮار دارﻧﺪ ﻛﻪ ﻧﻮع ﺗﻌﺮﻳﻒ ﺷﺪن آن ﻋﻀﻮ از ﻛﻼس را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻨﺪ .ﺑﺮاي ﻣﺜﺎل ،ﻛﻠﻴﺪ زرد رﻧﮓ ﻛﻮﭼﻚ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ آن ﻋﻀﻮ از ﻧﻮع Protectedاﺳﺖ ،و ﻳﺎ ﻗﻔﻞ ﺧﺎﻛﺴﺘﺮي رﻧﮓ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻋﻀﻮ از ﻧﻮع privateﺗﻌﺮﻳﻒ ﺷـﺪه اﺳـﺖ .در ﻣﻮرد ﻣﻔﻬﻮم اﻳﻦ ﻛﻠﻤﺎت در ﻓﺼﻠﻬﺎي ﺑﻌﺪ ﺑﻴﺸﺘﺮ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد. (7ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮاي Form1ﺑﺮﮔﺮدﻳﺪ و دﻛﻤﻪ ﻓﺮﻣﺎن btnSayHelloرا در ﻓﺮم اﻧﺘﺨﺎب ﻛﻨﻴﺪ .در ﭘﻨﺠﺮه Propertiesﺑﺮ روي آﻳﻜﻮن زرد رﻧﮓ ﺑﺎﻻي ﭘﻨﺠﺮه ﻳﻌﻨﻲ آﻳﻜﻮن Eventsﻛﻠﻴﻚ ﻛﻨﻴﺪ )ﺷﻜﻞ .(4-6ﺑﻪ اﻳـﻦ ﺗﺮﺗﻴﺐ ﻟﻴﺴﺘﻲ ﻃﻮﻻﻧﻲ از ﻣﺘﺪﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل دﻛﻤﻪ ﻓﺮﻣﺎن را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
٢١٥
ﺷﻜﻞ 4-6 ﻳﻜﻲ از اﻳﻦ روﻳﺪاد ﻫﺎ ،روﻳﺪاد ﻛﻠﻴﻚ اﺳﺖ ﻛﻪ ﺑﻪ ﺻﻮرت ﭘﺮرﻧﮓ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﺳﺖ .ﻋﻠﺖ اﻳﻦ ﺗﻔﺎوت در اﻳﻦ اﺳـﺖ ﻛـﻪ ﺷﻤﺎ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺮاي روﻳﺪاد ﻛﻠﻴﻚ اﻳﻦ ﻛﻨﺘﺮل ،ﻳﻚ ﻣﺘﺪ را ﻣﺸﺨﺺ ﻛﺮده اﻳﺪ .اﮔﺮ ﺑﺮ روي روﻳﺪاد ﻛﻠﻴﻚ در اﻳﻦ ﻗـﺴﻤﺖ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ،ﺑﻪ ﺑﺨﺶ ﺗﻌﺮﻳﻒ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد در ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﺧﻮاﻫﻴﺪ رﻓﺖ. (8ﺣــﺎل روﻳــﺪاد دﻳﮕــﺮي را ﺑــﺮاي ﻛﻨﺘــﺮل Buttonﺗﻌﺮﻳــﻒ ﻣــﻲ ﻛﻨــﻴﻢ .از ﻟﻴــﺴﺖ ﻧﻤــﺎﻳﺶ داده ﺷــﺪه در ﭘﻨﺠــﺮه Propertiesﮔﺰﻳﻨﻪ MouseEnterرا ﭘﻴﺪا ﻛﺮده و ﺑﺮ روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴـﺪ .روﻳـﺪاد ﺟﺪﻳـﺪي ﺑـﺮاي ﻛﻨﺘﺮل Buttonاﻳﺠﺎد ﻣﻲ ﺷﻮد .ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ روﻳﺪاد اﺿﺎﻓﻪ ﻛﻨﻴﺪ:
٢١٦
private void btnSayHello_MouseEnter(object sender, )EventArgs e { // Change the Button text ;"!btnSayHello.Text = "The Mouse is here } اﻳﻦ روﻳﺪاد زﻣﺎﻧﻲ اﺟﺮا ﻣﻲ ﺷﻮد ﻛﻪ اﺷﺎره ﮔﺮ ﻣﺎوس وارد ﻛﻨﺘﺮل ﺷﻮد ،ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ از ﻣﺤﺪوده ي ﺧـﺎرج از Button ﺑﻪ ﻟﺒﻪ ي Buttonﺑﺮﺳﺪ. (9ﺑﺮاي ﺗﻜﻤﻴﻞ اﻳﻦ ﺑﺨﺶ ،ﺑﺎﻳﺪ ﻳﻚ روﻳﺪاد دﻳﮕﺮ ﻧﻴﺰ اﻳﺠﺎد ﻛﻨﻴﺪ .ﻣﺠﺪداً ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ Form1ﺑﺮﮔـﺸﺘﻪ و ﭘﺲ از اﻧﺘﺨﺎب ﻛﻨﺘﺮل ،Buttonدر ﺑﺎﻻي ﭘﻨﺠﺮه ي Propertiesﺑﺮ روي آﻳﻜﻮن Eventsﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻟﻴﺴﺖ ﺗﻤﺎم روﻳﺪادﻫﺎي اﻳﻦ ﻛﻨﺘﺮل را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ .از ﻟﻴﺴﺖ ﻧﻤﺎﻳﺶ داده ﺷـﺪه ﮔﺰﻳﻨـﻪ MouseLeaveرا اﻧﺘﺨـﺎب ﻛﺮده و ﺑﺮ روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﺪ دﻳﮕﺮي ﺑﺮاي اﻳﻦ روﻳﺪاد اﻳﺠﺎد ﻣﻲ ﺷﻮد .ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳـﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ. private void btnSayHello_MouseLeave(object sender, )EventArgs e { // Chenage the Button text ;"!btnSayHello.Text = "The mouse has gone } روﻳﺪاد MouseLeaveﻫﻨﮕﺎﻣﻲ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد ﻛﻪ اﺷﺎره ﮔﺮ ﻣﺎوس از ﻣﺤﺪوده ي ﻳﻚ ﻛﻨﺘﺮل ﺧﺎرج ﺷـﻮد .ﺑـﺮاي ﻣﺜﺎل در اﻳﻨﺠﺎ ﻫﻨﮕﺎﻣﻲ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد ﻛﻪ اﺷﺎره ﮔﺮ ﻣﺎوس از روي ﻛﻨﺘﺮل Buttonﺑﻪ ﻛﻨﺎر ﺑﺮود. (10ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده ،ﻣﺎوس را ﺑﺮ روي ﻛﻨﺘﺮل Buttonﺑﺒﺮﻳﺪ و از روي آن رد ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣـﺘﻦ روي ﻛﻨﺘﺮل ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 5-6ﺗﻐﻴﻴﺮ ﺧﻮاﻫﺪ ﻛﺮد.
ﺷﻜﻞ 5-6
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اﻏﻠﺐ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ داراي ﺗﻌﺪاد زﻳﺎدي روﻳﺪاد ﻫﺴﺘﻨﺪ .اﻟﺒﺘﻪ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻋﺎدي ،ﺗﻌﺪاد ﻛﻤـﻲ از آﻧﻬـﺎ ﺑـﻪ ﻃﻮر ﺛﺎﺑﺖ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد .ﺑﺮاي ﻣﺜﺎل روﻳﺪاد ﻛﻠﻴﻚ ﻛﻨﺘﺮل ،Buttonﻳﻜﻲ از روﻳﺪادﻫﺎﻳﻲ اﺳـﺖ ﻛـﻪ ﺑـﻪ ﺷـﺪت ﻣـﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد.
٢١٧
در وﻳﮋوال C#ﻫﺮ ﻛﻨﺘﺮل ﻳﻚ روﻳﺪاد ﭘﻴﺶ ﻓﺮض دارد ﻛﻪ ﺑﺎ دو ﺑﺎر ﻛﻠﻴﻚ ﺑـﺮ روي آن ﻛﻨﺘـﺮل ،ﻣﺘـﺪ ﻣﺮﺑـﻮط ﺑـﻪ آن روﻳـﺪاد ﺑـﻪ ﻃـﻮر اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﻣﻲ ﺷﻮد .اﻳﻦ روﻳﺪاد ﻣﻌﻤﻮﻻً ﭘﺮ ﻛﺎرﺑﺮد ﺗﺮﻳﻦ روﻳﺪاد آن ﻛﻨﺘﺮل اﺳﺖ .ﺑﺮاي ﻣﺜﺎل در ﻛﻨﺘﺮل ،Buttonروﻳﺪاد ﻛﻠﻴـﻚ ﺑﻪ ﻋﻨﻮان روﻳﺪاد ﭘﻴﺶ ﻓﺮض در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮد. ﻳﻜﻲ دﻳﮕﺮ از روﻳﺪادﻫﺎي ﻛﻨﺘﺮل ،Buttonروﻳﺪاد MouseEnterاﺳﺖ ﻛﻪ ﺑﺎ وارد ﺷﺪن اﺷﺎره ﮔﺮ ﻣﺎوس ﺑﻪ ﻣﺤﺪوده ﻛﻨﺘﺮل ﻓﻌﺎل ﻣﻲ ﺷﻮد. private void btnSayHello_MouseEnter(object sender, )EventArgs e { // Change the Button text ;"!btnSayHello.Text = "The Mouse is here } در اﻳﻦ ﻫﻨﮕﺎم ﻣﻲ ﺗﻮاﻧﻴﻢ ﺧﺎﺻﻴﺖ Textﻛﻨﺘﺮل را ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﺗﺎ ﺗﻐﻴﻴﺮ ﻣﻮﻗﻌﻴﺖ اﺷﺎره ﮔﺮ ﻣﺎوس را ﻧـﺸﺎن دﻫـﺪ .در ﻗـﺴﻤﺘﻬﺎي ﻗﺒﻠـﻲ ﺑﺮاي ﺗﻐﻴﻴﺮ ﻳﻜﻲ از ﺧﺎﺻﻴﺖ ﻫﺎي ﻳﻚ ﻛﻨﺘﺮل ،از ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم در زﻣﺎن ﻃﺮاﺣﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ .اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣـﻲ ﻛﻨﻴﺪ ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮان از ﻛﺪﻫﺎي زﻣﺎن اﺟﺮا ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﺮد. ﻧﻜﺘﻪ :زﻣﺎن ﻃﺮاﺣﻲ 1در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻪ زﻣﺎﻧﻲ اﻃﻼق ﻣﻲ ﺷﻮد ﻛﻪ در ﺣﺎل ﻃﺮاﺣﻲ راﺑﻂ ﮔﺮاﻓﻴﻜﻲ ﺑﺮﻧﺎﻣـﻪ و ﻳـﺎ ﺣﺘـﻲ ﻧﻮﺷـﺘﻦ ﻛـﺪ ﻣﺮﺑﻮط ﺑﻪ آن ﻫﺴﺘﻴﺪ .در ﻣﻘﺎﺑﻞ ﺑﻪ زﻣﺎﻧﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ در ﺣﺎل اﺟﺮا اﺳﺖ ،زﻣﺎن اﺟﺮا 2ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد.
اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺳﺎده: وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005داراي ﻣﺠﻤﻮﻋﻪ ﻛﺎﻣﻠﻲ از ﻛﻨﺘﺮل ﻫﺎ اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮاي ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد از آﻧﻬـﺎ اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ .در ﻃﺮاﺣﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ،اﻏﻠﺐ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﻣﻴﺘﻮان ﺑﺮﻧﺎﻣﻪ را ﻃﺮاﺣﻲ ﻛﺮد .اﻣﺎ در ﻓﺼﻞ 13ﺧﻮاﻫﻴﺪ دﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻣﺨﺼﻮص ﺑﻪ ﺧﻮدﺗﺎن ﺑﺴﺎزﻳﺪ. در ﻗﺴﻤﺖ ﺑﻌﺪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ ﺗﺮﻛﻴﺐ اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ،ﺑﺮﻧﺎﻣﻪ ﺳﺎده اي را اﻳﺠﺎد ﻛﺮد .در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺳﺎده وﻳﻨﺪوزي اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﺪ ﻣﺘﻨﻲ را در ﻳﻚ ﻛﺎدر وارد ﻛﻨﺪ .ﺳـﭙﺲ ﺑﺮﻧﺎﻣـﻪ ﺗﻌـﺪاد ﺣـﺮوف ﻣﺘﻦ و ﺗﻌﺪاد ﻛﻠﻤﺎت آن را ﺷﻤﺮده و آن را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
اﻳﺠﺎد ﻓﺮم: ﺑﺮاي ﻧﻮﺷﺘﻦ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ،اوﻟﻴﻦ ﻛﺎر اﻳﺠﺎد ﻳﻚ ﭘﺮوژه ﺟﺪﻳﺪ و ﺳـﺎﺧﺘﻦ ﻳـﻚ ﻓـﺮم ﺑـﺮاي ﺑﺮﻧﺎﻣـﻪ اﺳـﺖ .اﻳـﻦ ﻓـﺮم ﺷـﺎﻣﻞ ﻳـﻚ ﻛﻨﺘـﺮل TextBoxﭼﻨﺪ ﺧﻄﻲ ﺧﻮاﻫﺪ ﺑﻮد ﺗﺎ ﻛﺎرﺑﺮ ﺑﺘﻮاﻧـﺪ ﻣـﺘﻦ ﻣـﻮرد ﻧﻈـﺮ ﺧـﻮد را در آن وارد ﻛﻨـﺪ .ﻫﻤﭽﻨـﻴﻦ ﺑﺮﻧﺎﻣـﻪ ﺷـﺎﻣﻞ دو ﻛﻨﺘـﺮل RadioButtonﺧﻮاﻫﺪ ﺑﻮد ﻛﻪ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻣﻲ دﻫﺪ ،ﺑﻴﻦ ﺷﻤﺮدن ﻛﻠﻤﺎت ﻣﺘﻦ و ﻳﺎ ﺣﺮوف آن ﻳﻚ ﻣﻮرد را اﻧﺘﺨﺎب ﻛﻨﺪ.
Design Time Run Time
1 2
٢١٨
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻓﺮم (1از ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﮔﺰﻳﻨﻪ … File New Projectرا اﻧﺘﺨـﺎب ﻛـﺮده و ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ وﻳﻨﺪوزي ﺟﺪﻳﺪ اﻳﺠﺎد ﻛﻨﻴﺪ .ﻧﺎم ﭘﺮوژه را Word Counterﻗﺮار دﻫﻴﺪ و ﺳﭙﺲ ﺑﺮ روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﭘﺮوژه اﻳﺠﺎد ﺷﻮد. (2ﺑﺮ روي ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﻧﺘﺨﺎب ﺷﻮد .ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه Propertiesﺧﺎﺻﻴﺖ Sizeرا ﺑﺮاﺑـﺮ ﺑﺎ ،424;312ﺧﺎﺻﻴﺖ StartPositionرا ﺑﺮاﺑﺮ ﺑﺎ CenterScreenو ﺧﺎﺻـﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Word Counterﻗﺮار دﻫﻴﺪ. (3ﻳﻚ ﻛﻨﺘﺮل TextBoxﺑﺮ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ و ﺧﺎﺻﻴﺘﻬﺎي آن را ﻣﻄﺎﺑﻖ ﺑﺎ ﻟﻴﺴﺖ زﻳﺮ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ txtWordsﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Locationرا ﺑﺮاﺑﺮ ﺑﺎ 8,23ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Multilineرا ﺑﺮاﺑﺮ ﺑﺎ Trueﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ ScrollBarsرا ﺑﺮاﺑﺮ ﺑﺎ Verticalﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Sizeرا ﺑﺮاﺑﺮ ﺑﺎ 400,217ﻗﺮار دﻫﻴﺪ. (4ﺑﺮاي اﻳﻦ ﻛﻪ ﻛﺎرﺑﺮ را در اﺳﺘﻔﺎده از ﻓﺮم راﻫﻨﻤﺎﻳﻲ ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ ﻳﻚ ﺑﺮﭼﺴﺐ ﻧﻴﺰ در ﻓﺮم ﻗﺮار دﻫﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر از ﺟﻌﺒﻪ اﺑـﺰار ﻛﻨﺘﺮل Labelرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ و آن را ﺑﺎ اﺳﺘﻔﺎده از ﻣﺎوس ﻫﻤﺎﻧﻨﺪ ﻗﺮار دادن ﻛﻨﺘﺮل ،TextBoxﺑﺮ روي ﻓـﺮم ﻗـﺮار دﻫﻴﺪ .ﺳﭙﺲ ﺧﺎﺻﻴﺖ Textاﻳﻦ ﻛﻨﺘﺮل را ﺑﺮاﺑﺮ ﺑﺎ Enter some text into this boxﻗﺮار دﻫﻴﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻼﺣﻈﻪ ﻣﻲ ﻛﻨﻴﺪ ،در اﻳﻦ ﻗﺴﻤﺖ ﺧﺎﺻﻴﺖ Nameﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل ﻟﻴﺒﻞ را ﺗﻐﻴﻴﺮ ﻧﺪادﻳﻢ .دﻟﻴـﻞ اﻳـﻦ اﻣـﺮ در اﻳﻦ اﺳﺖ ﻛﻪ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻧﺨﻮاﻫﻴﺪ از ﻳﻚ ﻛﻨﺘﺮل در ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﺑﺮاي آن ﻳﻚ ﻧـﺎم ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ،ﻧﻴﺎز دارﻳﻢ از ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘـﺮل TextBoxدر ﻛـﺪ اﺳـﺘﻔﺎده ﻛﻨـﻴﻢ ﺗـﺎ ﺑﺘﻮاﻧﻴﻢ ﻛﻠﻤﺎت و ﺣﺮوف داﺧﻞ آن را ﺑﺸﻤﺎرﻳﻢ .اﻣﺎ ﻧﻴﺎزي ﻧﺪارﻳﻢ ﻛﻪ از ﻛﻨﺘﺮل ﻟﻴﺒﻞ اﻃﻼﻋﺎﺗﻲ را درﻳﺎﻓﺖ ﻛﻨـﻴﻢ و ﻳـﺎ در ﻃـﻮل اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺧﺎﺻﻴﺘﻲ از آن را ﺗﻐﻴﻴﺮ دﻫﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﻧﺎم آن را ﺗﻐﻴﻴﺮ ﻧﻤﻲ دﻫﻴﻢ و اﺟﺎزه ﻣﻲ دﻫﻴﻢ ﻫﻤـﺎن ﻣﻘـﺪار اوﻟﻴـﻪ ﺑـﺎﻗﻲ ﺑﻤﺎﻧﺪ. (5ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﻗﺎدر ﺧﻮاﻫﺪ ﺑﻮد ﺗﻌﺪاد ﻛﻠﻤﺎت و ﻧﻴﺰ ﺗﻌﺪاد ﺣﺮوف داﺧﻞ ﻳﻚ ﻣﺘﻦ را ﺑﺸﻤﺎرد .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﻴﺪ ﻛـﻪ ﺷﻤﺎرش ﺗﻌﺪاد ﻛﻠﻤﺎت و ﻳﺎ ﺗﻌﺪاد ﺣﺮوف را اﻧﺘﺨﺎب ﻛﻨﺪ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﻣـﻲ ﺗﻮاﻧﻴـﺪ از دو ﻛﻨﺘـﺮل RadioButton اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ،دو ﻛﻨﺘﺮل RadioButtonدر ﻛﻨﺎر ﻫﻢ و در ﭘـﺎﻳﻴﻦ TextBoxﺑـﺮ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ ﺧﺎﺻﻴﺘﻬﺎي اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺎدﻳﺮ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ وارد ﻛﻨﻴﺪ. ﺑﺮاي دﻛﻤﻪ رادﻳﻮﻳﻲ اول:
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ radCountCharsﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Checkedرا ﺑﺮاﺑﺮ ﺑﺎ Trueﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textرا ﺑﺮاﺑﺮ ﺑﺎ Charsﻗﺮار دﻫﻴﺪ.
ﺑﺮاي دﻛﻤﻪ رادﻳﻮﻳﻲ دوم:
٢١٩
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ radCountWordsﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textرا ﺑﺮاﺑﺮ ﺑﺎ Wordsﻗﺮار دﻫﻴﺪ.
(6ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ ﻣﺘﻨﻲ را در ﻛﺎدر ﻣﺸﺨﺺ ﺷﺪه وارد ﻛﺮد ،ﺑﺮﻧﺎﻣﻪ ﺗﻌﺪاد ﻛﺎراﻛﺘﺮ ﻫﺎ و ﻳﺎ ﺗﻌﺪاد ﻛﻠﻤﺎت آن را ﺧﻮاﻫﺪ ﺷﻤﺮد .در ﻣﺮﺣﻠﻪ ﺑﻌﺪ اﻳﻦ ﺗﻌﺪاد ﺑﺎﻳﺪ ﺑﻪ وﺳﻴﻠﻪ ﭘﻴﻐﺎم ﻣﻨﺎﺳﺐ ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ داده ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ،ﺑﺮاي ﻧﻤﺎﻳﺶ ﻧﺘﻴﺠﻪ دو ﻛﻨﺘﺮل ﻟﻴﺒـﻞ را در ﻛﻨﺎر ﻛﻨﺘﺮﻟﻬﺎي RadioButtonدر ﻓﺮم ﻗﺮار دﻫﻴﺪ. (7ﻛﻨﺘﺮل ﻟﻴﺒﻞ اول )ﻛﻪ داراي ﻧﺎم label2اﺳﺖ( ﻓﻘﻂ ﺑﺮاي ﻧﻤﺎﻳﺶ ﻳﻚ ﻣﺘﻦ ﺛﺎﺑـﺖ در ﻃـﻮل ﺑﺮﻧﺎﻣـﻪ ﺑـﻪ ﻛـﺎر ﻣـﻲ رود، ﺑﻨﺎﺑﺮاﻳﻦ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﻧﺎم آن را ﺗﻐﻴﻴﺮ دﻫﻴﻢ .ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﺧﺎﺻﻴﺖ Textآن را ﺑﺎ The result are: ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ .ﻟﻴﺒﻞ دوم ﺑﺮاي ﻧﻤﺎﻳﺶ ﻧﺘﻴﺠﻪ ﺑﻪ ﻛﺎر ﻣﻲ رود .ﺑﻨﺎﺑﺮاﻳﻦ ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑـﺎ lblResults ﻗﺮار ﻣﻲ دﻫﻴﻢ و ﻣﺘﻦ داﺧﻞ ﻗﺴﻤﺖ Textآن را ﻧﻴﺰ ﭘﺎك ﻣﻲ ﻛﻨﻴﻢ .ﺑﻌﺪ از اﻧﺠﺎم اﻳﻦ ﻣﻮارد ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﺷـﻤﺎ ﺑﺎﻳـﺪ ﻣـﺸﺎﺑﻪ ﺷﻜﻞ 6-6ﺑﺎﺷﺪ. (8ﺣﺎل ﻛﻪ ﻛﻨﺘﺮل ﻫﺎ را در ﻣﻜﺎن ﻣﻮرد ﻧﻈﺮﺗﺎن ﺑﺮ روي ﻓﺮم ﻗﺮار دادﻳﺪ ،ﺑﻬﺘﺮ اﺳﺖ ﻛﺎري ﻛﻨﻴﺪ ﻛـﻪ در ﺟـﺎي ﺧـﻮد ﺛﺎﺑـﺖ ﺑـﺎﻗﻲ ﺑﻤﺎﻧﻨﺪ و ﻣﻮﻗﻌﻴﺖ ﺷﺎن ﺑﻪ ﻃﻮر ﺗﺼﺎدﻓﻲ ﺗﻐﻴﻴﺮ ﻧﻜﻨﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻳﻜﻲ از ﻛﻨﺘﺮﻟﻬﺎي روي ﻓﺮم را اﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ ﮔﺰﻳﻨﻪ Format Lock Controlsرا از ﻧﻮار ﻣﻨﻮ اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺧﺎﺻـﻴﺖ Lockedﻫﻤـﻪ ﻛﻨﺘﺮل ﻫﺎ ﺑﺮاﺑﺮ ﺑﺎ Trueﺧﻮاﻫﺪ ﺷﺪ و اﺣﺘﻤﺎل اﻳﻦ وﺟﻮد ﻧﺨﻮاﻫﺪ داﺷﺖ ﻛﻪ ﻳﻜﻲ از اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﺑﻪ ﻃـﻮر ﺗـﺼﺎدﻓﻲ ﭘـﺎك ﺷﻮد ،اﻧﺪازه اش ﺗﻐﻴﻴﺮ داده ﺷﻮد و ﻳﺎ ﻣﻜﺎن آن در ﻓﺮم ﺗﻐﻴﻴﺮ ﻛﻨﺪ.
ﺷﻜﻞ 6-6
ﺷﻤﺎرش ﻛﺎراﻛﺘﺮ ﻫﺎ: ﺣﺎل ﻛﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻃﺮاﺣﻲ ﺷﺪ ،ﺑﺎﻳﺪ ﺗﻌـﺪادي ﻣﺘـﺪ ﺑـﺮاي روﻳـﺪادﻫﺎي ﻣـﻮرد ﻧﻴـﺎز ﻃﺮاﺣـﻲ ﻛﻨﻴـﺪ ﺗـﺎ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻛـﺎرﺑﺮ ﻣﺘﻨـﻲ را در TextBoxوارد ﻛﺮد ،ﺗﻌﺪاد ﻛﺎراﻛﺘﺮﻫﺎي آن ﻣﺘﻦ در ﭘﺎﻳﻴﻦ ﻓﺮم ﻧﻤﺎﻳﺶ داده ﺷﻮد .ﺑﺮ روي ﻧﺎم ﻓـﺮم در ﻗـﺴﻤﺖ Solution
٢٢٠
Explorerو ﻳﺎ ﺑﺮ روي ﺧﻮد ﻓﺮم ﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ View Codeرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ Form1ﺑﺮوﻳﺪ .ﺑﺮاي اﻳﻨﻜﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻫﻢ ﺗﻌﺪاد ﻛﺎراﻛﺘﺮﻫﺎي ﻳﻚ ﻣﺘﻦ و ﻫﻢ ﺗﻌﺪاد ﻛﻠﻤـﺎت آن را ﺑـﺸﻤﺎرﻳﺪ ﻧﻴﺎز دارﻳﺪ ﻛﻪ ﺗﻮاﺑﻌﻲ ﺟﺪاﮔﺎﻧﻪ ﺑﺮاي اﻳﻦ دو ﻣﻮرد ﺑﻨﻮﻳﺴﻴﺪ .در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ،ﻛﺪي ﺧﻮاﻫﻴﻢ ﻧﻮﺷـﺖ ﻛـﻪ ﺗﻌـﺪاد ﻛﺎراﻛﺘﺮﻫـﺎي ﻳﻚ ﻣﺘﻦ را ﺑﺸﻤﺎرد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺷﻤﺎرش ﻛﺎراﻛﺘﺮ ﻫﺎ (1در ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ،ﻛﺪ زﻳﺮ را درون ﻛﻼس ﻣﺮﺑﻮط ﺑﻪ Form1وارد ﻛﻨﻴﺪ .ﺑﻪ ﻳﺎد دارﻳﺪ ﻛﻪ ﺑﺮاي ﻗﺮار دادن ﺑﺨـﺸﻬﺎي ﺗﻮﺿﻴﺤﻲ از ﻧﻮع XML Document Commentﺑﺎﻳﺪ ﺳﻪ ﻛﺎراﻛﺘﺮ /را ﺑﻪ ﻃﻮر ﻣﺘﻮاﻟﻲ ﻗﺒﻞ از ﺗﺎﺑﻊ وارد ﻛﻨﻴﺪ. >/// <summary /// Count the characters in a blick of text >/// The string containing the text to >/// count characters inThe number of characters in the >/// string
٢٢١
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻼﺣﻈﻪ ﻣﻲ ﻛﻨﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎراﻛﺘﺮي را در TextBoxوارد ﻣﻲ ﻛﻨﻴﺪ ،ﻛﻨﺘﺮل ﻟﻴﺒﻞ ﭘﺎﻳﻴﻦ ﻓـﺮم ﺗﻌـﺪاد ﻛﺎراﻛﺘﺮﻫـﺎي ﻣﻮﺟﻮد در ﻣﺘﻦ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .زﻳﺮا ﻫﺮ ﺑﺎر ﻛﻪ ﻣﺘﻦ داﺧﻞ TextBoxﺗﻐﻴﻴﺮ ﻣﻲ ﻛﻨﺪ ،روﻳﺪاد TextChangedﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﺮ ﺑﺎر ﻛﻪ ﻣﺘﻦ ﺟﺪﻳﺪي وارد ﺷﻮد ،ﻗﺴﻤﺘﻲ از ﻣﺘﻦ ﻗﺒﻠﻲ ﺣﺬف ﺷﻮد و در ﻛﻞ ﻗﺴﻤﺘﻲ از ﻣﺘﻦ ﺑﻪ ﻫﺮ ﻧﺤﻮي ﺗﻐﻴﻴﺮ ﻛﻨـﺪ، ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد ﺗﺎﺑﻊ CountCharactersرا ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ و ﻣﺘﻦ داﺧﻞ TextBoxرا ﺑﻪ ﻋﻨﻮان ﭘـﺎراﻣﺘﺮ ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻣﻲ ﻓﺮﺳﺘﺪ .اﻳﻦ ﻣﺘﺪ ﻧﻴﺰ ﺗﻌﺪاد ﻛﺎراﻛﺘﺮﻫﺎي ﻣﻮﺟﻮد در ﻣﺘﻦ را ﺷﻤﺮده و ﻧﺘﻴﺠﻪ را در ﻣﺘﻐﻴﺮ intCharsﻗﺮار ﻣﻲ دﻫﺪ.
ﺷﻜﻞ 7-6
// Count the number of characters ;)int intChars = CountCharacters(txtWords.Text ﺳﭙﺲ ﻋﺪد ﺑﻪ دﺳﺖ آﻣﺪه ﺑﺎ ﭘﻴﻐﺎم ﻣﻨﺎﺳﺐ در ﻛﻨﺘﺮل ﻟﻴﺒﻞ ﻗﺮار ﻣﻲ ﮔﻴﺮد ﺗﺎ ﺗﻌﺪاد ﻛﺎراﻛﺘﺮﻫﺎي ﻣﻮﺟﻮد در ﻣﺘﻦ ﺑﻪ ﻛﺎرﺑﺮ اﻃﻼع داده ﺷﻮد. // Display the results ;"lblResults.Text = intChars + " characters
ﺷﻤﺎرش ﻛﻠﻤﺎت: اﮔﺮﭼﻪ ﻧﻮﺷﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال 2005 C#ﺑﺴﻴﺎر ﺳﺎده ﺑﻪ ﻧﻈﺮ ﻣﻲ رﺳﺪ ،اﻣﺎ اراﺋﻪ ﻳﻚ راه ﺣﻞ ﻇﺮﻳﻒ و ﻛﺎرآﻣﺪ ﺑﺮاي ﻳﻚ ﻣﺴﺌﻠﻪ ﺑﻪ ﺗﺮﻛﻴﺒﻲ از ﺗﺠﺮﺑﻪ و اﺳﺘﺪﻻل ﻧﻴﺎز دارد.
٢٢٢
ﺑﺮاي ﻣﺜﺎل ﻫﻤﻴﻦ ﺑﺮﻧﺎﻣﻪ را در ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ .ﺷﻤﺎ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ دﻛﻤﻪ رادﻳـﻮﻳﻲ Wordsاﻧﺘﺨـﺎب ﺷـﺪه ﺑـﻮد ،ﺑﺮﻧﺎﻣـﻪ ﺗﻌـﺪاد ﻛﻠﻤﺎت را ﺑﺸﻤﺎرد و ﻫﻨﮕﺎﻣﻲ ﻛﻪ دﻛﻤﻪ رادﻳﻮﻳﻲ Charsاﻧﺘﺨﺎب ﺷﺪه ﺑﻮد ﺑﺮﻧﺎﻣﻪ ﺗﻌﺪاد ﻛﺎراﻛﺘﺮ ﻫﺎ را ﺑﺸﻤﺎرد .در اﻳﻦ ﻣﻮرد ﺑﺎﻳﺪ ﺑـﻪ دو ﻣﻮرد ﺗﻮﺟﻪ ﻛﻨﻴﺪ .اول اﻳﻨﻜﻪ زﻣﺎﻧﻲ ﻛﻪ ﺑﻪ روﻳﺪاد TextChangedﭘﺎﺳﺦ ﻣﻲ دﻫﻴﺪ ،ﺑﺮاي ﺷﻤﺎرش ﺗﻌﺪاد ﻛﻠﻤﺎت ﺑﺎﻳﺪ از ﻳﻚ ﺗـﺎﺑﻊ و ﺑﺮاي ﺷﻤﺎرش ﺗﻌﺪاد ﻛﺎراﻛﺘﺮ ﻫﺎ ﺑﺎﻳﺪ از ﺗﺎﺑﻌﻲ دﻳﮕﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻟﺒﺘﻪ اﻳﻦ ﻣﻮرد زﻳﺎد ﺳﺨﺖ ﻧﻴﺴﺖ. دوم اﻳﻨﻜﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺮ روي ﻳﻜﻲ از ﻛﻨﺘﺮﻟﻬﺎي RadioButtonﻛﻠﻴﻚ ﻣـﻲ ﻛﻨـﺪ ،ﺑﺎﻳـﺪ ﻣـﺘﻦ ﻧﻤـﺎﻳﺶ داده ﺷـﺪه را از " "Charactersﺑﻪ " "Wordsو ﻳﺎ ﺑﺮﻋﻜﺲ ﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺣﺎل ،ﺗﻌﺪاد ﺑﻴﺸﺘﺮي روﻳﺪاد را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ و ﺑﻌﺪ از ﺗﻤﺎم ﺷﺪن ﺑﺮﻧﺎﻣﻪ ،ﻣﻨﻄﻘﻲ ﻛﻪ در ﭘﺸﺖ ﺗﻜﻨﻴﻜﻬﺎي آن ﺑﻪ ﻛﺎر رﻓﺘﻪ اﺳﺖ را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺷﻤﺎرش ﻛﻠﻤﺎت (1اﮔﺮ ﻫﻤﭽﻨﺎن ﺑﺮﻧﺎﻣﻪ در ﺣﺎل اﺟﺮا اﺳﺖ ،آن را ﻣﺘﻮﻗﻒ ﻛﻨﻴﺪ .اوﻟﻴﻦ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴـﺪ اﻳـﻦ اﺳـﺖ ﻛـﻪ ﺗـﺎﺑﻊ دﻳﮕـﺮي ﺑﻨﻮﻳــﺴﻴﺪ ﻛــﻪ ﺗﻌــﺪاد ﻛﻠﻤــﺎت ﻣﻮﺟــﻮد در ﻳــﻚ ﻣــﺘﻦ ﻣــﺸﺨﺺ را ﺑـﺸﻤﺎرد .ﻛــﺪ زﻳــﺮ را ﺑــﻪ ﺑﺮﻧﺎﻣــﻪ اﺿــﺎﻓﻪ ﻛﻨﻴــﺪ ﺗــﺎ ﺗــﺎﺑﻊ CountWordsاﻳﺠﺎد ﺷﻮد: >/// <summary /// Counts the number of words in a block of text >/// The string containing the text to >/// count words in///
The number of words in the string
٢٢٣
if (radCountWords.Checked == true) { // Update the results lblResults.Text = CountWords(txtWords.Text) + " words"; } else { // Update the results lblResults.Text = CountCharacters(txtWords.Text) + " characters"; } } ﺗـﺎﺑﻊ، را ﻓﺮاﺧـﻮاﻧﻲ ﻛﻨـﻴﻢCountCharacters ﺗـﺎﺑﻊ،( ﺣﺎل ﺑﻪ ﺟﺎي اﻳﻨﻜﻪ در ﻣﺘـﺪ ﻣﺮﺑـﻮط ﺑـﻪ روﻳـﺪاد ﻛﻠﻴـﻚ3 . ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻐﻴﻴﺮات زﻳﺮ را در اﻳﻦ ﻣﺘﺪ اﻳﺠﺎد ﻛﻨﻴﺪ. را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢUpdateDisplay private void txtWords_TextChanged(object sender, EventArgs e) { // Something chenged, so display the results UpdateDisplay(); } و ﻳﺎ ﺑﺮ ﻋﻜﺲ ﺗﻐﻴﻴﺮWords ﺑﻪChars ( در آﺧﺮ ﺑﺎﻳﺪ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ دﻛﻤﻪ رادﻳﻮﻳﻲ از4 ﻳﻜﻲCheckedChanged ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﺪ از روﻳﺪاد. ﻋﺪد ﻧﻤﺎﻳﺶ داده ﺷﺪه در ﺻﻔﺤﻪ ﻧﻴﺰ ﺗﻐﻴﻴﺮ ﻛﻨﺪ،ﻛﺮد را اﻧﺘﺨـﺎب ﻛـﺮده و درradCountWords ﻛﻨﺘـﺮل، در ﻗﺴﻤﺖ ﻃﺮاﺣـﻲ ﻓـﺮم.از دﻛﻤﻪ ﻫﺎي رادﻳﻮﻳﻲ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ روﻳﺪادﻫﺎي ﻣﺮﺑﻮط ﺑﻪ اﻳـﻦ ﻛﻨﺘـﺮل ﻧﻤـﺎﻳﺶ دادهEvents ﺑﺮ روي آﻳﻜﻮنProperties ﭘﻨﺠﺮه در ﻣﺘـﺪ. را اﻧﺘﺨﺎب ﻛﺮده و ﺑﺮ روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴـﺪCheckedChanged روﻳﺪاد، از ﻟﻴﺴﺖ روﻳﺪادﻫﺎ.ﺷﻮﻧﺪ : ﻛﺪ زﻳﺮ را وارد ﻛﻨﻴﺪ،اﻳﺠﺎد ﺷﺪه ﺑﺮاي اﻳﻦ روﻳﺪاد private void radCountWords_CheckedChanged(object sender, EventArgs e) { // Something chenged, so display the results UpdateDisplay(); } : ﻧﻴﺰ ﺗﻜﺮار ﻛﻨﻴﺪradCountChars ( ﻣﺮاﺣﻞ ﻗﺒﻞ را ﺑﺮاي ﻛﻨﺘﺮل5 private void radCountChars_CheckedChanged(object sender, EventArgs e) { // Something chenged, so display the results ٢٢٤
UpdateDisplay(); } . ﻛﻠﻴـﻚ ﻛﻨﻴـﺪWords ﺳﭙﺲ ﺑﺮ روي دﻛﻤﻪ رادﻳـﻮﻳﻲ.( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﻣﺘﻨﻲ را در ﻗﺴﻤﺖ ﻣﺸﺨﺺ ﺷﺪه وارد ﻛﻨﻴﺪ6 .(8-6 ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻣﺘﻦ ﻧﻤﺎﻳﺶ داده ﺷﺪه در ﻓﺮم ﺗﻐﻴﻴﺮ ﻛﺮده و ﺗﻌﺪاد ﻛﻠﻤﺎت را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ )ﺷﻜﻞ
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ : را ﺑﺮرﺳﻲ ﻛﻨﻴﻢCountWords ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﻧﺤﻮه ﻋﻤﻠﻜﺮد ﺗﺎﺑﻊ،ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﻪ ﺑﺮرﺳﻲ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﺑﺮﻧﺎﻣﻪ ﺑﭙﺮدازﻳﻢ /// <summary> /// Counts the number of words in a block of text /// /// <param name="text">The string containing the text to /// count words in ///
The number of words in the string private int CountWords(string text) { // Is the text box empty if (txtWords.Text == String.Empty) return 0; // Split the words string[] strWords = text.Split(' '); // Return the number of words return strWords.Length; }
٢٢٥
ﺷﻜﻞ 8-6 در اﺑﺘﺪاي ﺗﺎﺑﻊ ،ﻣﻘﺪار ﺧﺎﺻﻴﺖ Textﻣﺮﺑﻮط ﺑﻪ TextBoxرا ﺑﺎ ﻋﻀﻮ Emptyاز ﻛﻼس Stringﺑﺮرﺳﻲ ﻣﻲ ﻛﻨـﻴﻢ ﺗـﺎ از وﺟﻮد ﻣﺘﻦ در آن ﻣﻄﻤﺌﻦ ﺷﻮﻳﻢ .ﻋﻀﻮ Emptyاز ﻛﻼس Stringﺑﺮاﺑﺮ ﺑﺎ رﺷﺘﻪ اي ﺑﻪ ﻃﻮل ﺻﻔﺮ )""( اﺳﺖ ،ﺑﻨﺎﺑﺮاﻳﻦ اﮔـﺮ ﻣﻘﺪار داﺧﻞ ﺧﺎﺻﻴﺖ Textﺑﺮاﺑﺮ ﺑﺎ اﻳﻦ ﻋﻀﻮ ﺑﺎﺷﺪ ﻣﻲ ﺗﻮان ﻓﻬﻤﻴﺪ ﻛﻪ ﻣﺘﻨﻲ داﺧﻞ TextBoxوارد ﻧﺸﺪه اﺳﺖ .در اﻳـﻦ ﺣﺎﻟـﺖ ﺗﺎﺑﻊ ﻣﻘﺪار ﺻﻔﺮ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ. ﺗﺎﺑﻊ Splitاز ﻛﻼس Stringﻳﻚ رﺷﺘﻪ را درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ و آن را ﺑﻪ آراﻳﻪ اي از رﺷﺘﻪ ﻫﺎ ﺗﺒﺪﻳﻞ ﻛﺮده و ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .اﻳﻦ ﺗﺎﺑﻊ ﻳﻚ ﻛﺎراﻛﺘﺮ و ﻳﺎ آراﻳﻪ اي از ﻛﺎراﻛﺘﺮ ﻫﺎ را ﺑﻪ ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻛﺮده و از ﻛﺎراﻛﺘﺮ ﻫﺎ ﺑﻪ ﻋﻨﻮان ﺟﺪا ﻛﻨﻨﺪه اﺳﺘﻔﺎده ﻣﻲ ﻛﻨـﺪ ﺗـﺎ رﺷﺘﻪ وارد ﺷﺪه را ﺑﻪ ﭼﻨﺪ زﻳﺮ رﺷﺘﻪ ﺗﻘﺴﻴﻢ ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل در اﻳﻦ ﺑﺮﻧﺎﻣﻪ رﺷﺘﻪ داﺧﻞ TextBoxرا ﺑﻪ ﻫﻤﺮاه ﻛﺎراﻛﺘﺮ ﻓﺎﺻـﻠﻪ ) ‘ ‘( ﺑﻪ ﺗﺎﺑﻊ ﻣﻲ ﻓﺮﺳﺘﻴﻢ .ﺗﺎﺑﻊ ﻧﻴﺰ رﺷﺘﻪ را ﺑﻪ ﭼﻨﺪ زﻳﺮ رﺷﺘﻪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻓﺎﺻﻠﻪ از ﻫﻢ ﺟﺪا ﺷﺪه اﻧﺪ ﺗﺒﺪﻳﻞ ﻛﺮده و ﻧﺘﻴﺠﻪ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ. ﺑﻨﺎﺑﺮاﻳﻦ آراﻳﻪ اي ﻛﻪ اﻳﻦ ﺗﺎﺑﻊ ﺑﺮﻣﻲ ﮔﺮداﻧﺪ ﺣﺎوي ﻛﻠﻤﺎت رﺷﺘﻪ ورودي ﺧﻮاﻫﺪ ﺑﻮد .ﺑﻌﺪ از آن ﻣﻲ ﺗﻮاﻧﻴﻢ ﻃﻮل آراﻳﻪ ﻛﻪ در ﺣﻘﻴﻘﺖ ﺗﻌﺪاد ﻛﻠﻤﺎت رﺷﺘﻪ اﺻﻠﻲ اﺳﺖ را ﺑﺮﮔﺮداﻧﻴﻢ. ﻧﻜﺘﻪ :در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻓﺮض ﻛﺮده اﻳﻢ ﻛﻪ رﺷﺘﻪ ﺑﻪ ﺻﻮرت اﺳﺘﺎﻧﺪارد در TextBoxوارد ﺷﺪه اﺳﺖ ،ﻳﻌﻨﻲ ﺗﻤﺎم ﻛﻠﻤﺎت ﻓﻘﻂ ﺑـﺎ ﻳـﻚ ﻛﺎراﻛﺘﺮ ﻓﺎﺻﻠﻪ از ﻳﻜﺪﻳﮕﺮ ﺟﺪا ﺷﺪه اﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﺑﻴﻦ ﻛﻠﻤﺎت ﻣﺘﻨﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ وارد ﻣﻲ ﻛﻨﻴﺪ ﺑﻴﺶ از ﻳﻚ ﻓﺎﺻﻠﻪ وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ، ﺗﻌﺪاد ﻛﻠﻤﺎت ﺑﻪ ﺻﻮرت ﻧﺎدرﺳﺖ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد. ﻧﻜﺘﻪ :ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﺗﺎﺑﻊ Splitﻳﻚ ﻛﺎراﻛﺘﺮ و ﻳﺎ آراﻳﻪ اي از ﻛﺎراﻛﺘﺮ ﻫﺎ را ﺑﻪ ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻣﻲ ﻛﻨـﺪ ،ﺑﻨـﺎﺑﺮاﻳﻦ اﮔـﺮ ﺑﺨﻮاﻫﻴﺪ ﻛﺎراﻛﺘﺮ ﻓﺎﺻﻠﻪ را ﺑﻪ ﺗﺎﺑﻊ ﺑﻔﺮﺳﺘﻴﺪ ﺑﺎﻳﺪ از ' ' اﺳﺘﻔﺎده ﻛﻨﻴﺪ ﻧﻪ از " " .زﻳﺮا در C#ﻋﻼﻣﺖ " ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن رﺷﺘﻪ ﺑﻪ ﻛﺎر ﻣﻲ رود و ﻋﻼﻣﺖ ' ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن ﻛﺎراﻛﺘﺮ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ،ﻋﺒﺎرت " " ﺑﻪ ﻋﻨﻮان ﻳﻚ رﺷﺘﻪ ﺑـﺎ ﻃـﻮل ﻳـﻚ در ﻧﻈـﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮد و ﻋﺒﺎرت ' ' ﺑﻪ ﻋﻨﻮان ﻳﻚ ﻛﺎراﻛﺘﺮ. ﻳﻜﻲ از ﻋﺎدت ﻫﺎي ﺧﻮب ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ در اﻳﻦ اﺳﺖ ﻛﻪ ﻓﻘﻂ ﺑﻪ ﻣﻘﺪار ﻣﻮرد ﻧﻴﺎز در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ،ﻛﺪ ﻧﻮﺷﺘﻪ ﺷﻮد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ اﮔـﺮ در ﻣﻮﻗﻌﻴﺘﻲ ﻣﺠﺒﻮر ﺷﺪﻳﺪ ﻛﻪ از ﻳﻚ ﻛﺪ دوﺑﺎر اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،روﺷﻲ را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ ﻛﻪ آن ﻛﺪ را ﻓﻘﻂ ﻳﻚ ﺑﺎر ﺑﻨﻮﻳﺴﻴﺪ .ﺑﺮاي ﻣﺜـﺎل در اﻳـﻦ
٢٢٦
ﺑﺮﻧﺎﻣﻪ ،در دو ﻗﺴﻤﺖ ﻧﻴﺎز داﺷﺘﻴﺪ ﻛﻪ ﻣﺘﻦ داﺧﻞ lblResultsرا ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ ﺗﻌﺪاد درﺳﺖ ﻛﻠﻤﺎت و ﻳﺎ ﻛﺎراﻛﺘﺮ ﻫـﺎ را ﻧﻤـﺎﻳﺶ دﻫﺪ .ﺑﻬﺘﺮﻳﻦ روش ﺑﺮاي اﻳﻦ ﻛﺎر در اﻳﻦ اﺳﺖ ﻛﻪ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﺗﻐﻴﻴﺮ ﻣﺘﻦ داﺧﻞ lblResultsرا در داﺧـﻞ ﻳـﻚ ﻣﺘـﺪ ﻣﺠـﺰا ﻣﺎﻧﻨﺪ UpdateDisplayﻗﺮار دﻫﻴﺪ .ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﺑـﻪ راﺣﺘـﻲ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﻫﻨﮕـﺎم ﻧﻮﺷـﺘﻦ ﻛـﺪ ﻣﺮﺑـﻮط ﺑـﻪ روﻳـﺪادﻫﺎي TextChangedو CheckedChanedﻓﻘﻂ ﻣﺘﺪ ﻗﺒﻠﻲ را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﻦ داﺧﻞ lblResultsﺗﺼﺤﻴﺢ ﺷﻮد .ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ روش ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﻧﻪ ﺗﻨﻬﺎ ﻛﻮﺗﺎﻫﺘﺮ ﺷﺪه و ﻧﮕﻬﺪاري و ﺗﻐﻴﻴﺮ آن در آﻳﻨﺪه راﺣﺖ ﺗﺮ ﻣﻲ ﺷﻮد ،ﺑﻠﻜﻪ ﻫﻨﮕﺎم اﻳﺠﺎد ﺧﻄﺎ در ﺑﺮﻧﺎﻣﻪ ﺗﺼﺤﻴﺢ آن راﺣﺖ ﺗﺮ ﺻﻮرت ﻣﻲ ﮔﻴﺮد. )(private void UpdateDisplay { ?// Do we want to count words )if (radCountWords.Checked == true { // Update the results = lblResults.Text ;"CountWords(txtWords.Text) + " words } else { // Update the results = lblResults.Text ;"CountCharacters(txtWords.Text) + " characters } }
اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﭘﻴﭽﻴﺪه ﺗﺮ: ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻋﺎدي ﻋﻼوه ﺑﺮ ﻛﻨﺘﺮﻟﻬﺎﻳﻲ ﻣﺎﻧﻨﺪ Buttonو ﻳﺎ TextBoxو ،...ﻋﻤﻮﻣﺎ داراي ﺑﺨﺸﻬﺎﻳﻲ ﻣﺎﻧﻨـﺪ ﻧـﻮار اﺑـﺰار و ﻧـﻮار وﺿﻌﻴﺖ ﻧﻴﺰ ﻫﺴﺘﻨﺪ .اﻳﺠﺎد اﻳﻦ ﻗﺴﻤﺘﻬﺎ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در وﻳﮋوال C#ﻛﺎر ﺑﺴﻴﺎر ﺳﺎده اي اﺳﺖ. در ﺑﺨﺶ ﺑﻌﺪ ﺑﺮﻧﺎﻣﻪ اي ﺧﻮاﻫﻴﻢ ﻧﻮﺷﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ آن ﺑﺘﻮاﻧﻴﻢ ﻣﺘﻦ وارد ﺷﺪه در ﺑﺮﻧﺎﻣﻪ را ﺗﻐﻴﻴﺮ دﻫﻴﻢ .ﺑﺮاي ﻣﺜﺎل رﻧـﮓ ﻣـﺘﻦ را ﺗﻐﻴﻴـﺮ دﻫﻴﻢ و ﻳﺎ آن را ﺑﻪ ﺣﺮوف ﺑﺰرگ و ﻳﺎ ﻛﻮﭼﻚ ﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ.
ﺑﺮﻧﺎﻣﻪ وﻳﺮاﻳﺸﮕﺮ ﻣﺘﻦ: در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ،ﺑﺮﻧﺎﻣﻪ اي ﺧﻮاﻫﻴﻢ ﻧﻮﺷﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ آن ﺑﺘﻮان ﻣﺘﻦ وارد ﺷﺪه در ﻳﻚ TextBoxرا وﻳـﺮاﻳﺶ ﻛـﺮد. در اﻳﻦ ﺑﺮﻧﺎﻣﻪ از ﻳﻚ ﻧﻮار اﺑﺰار اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﻪ وﺳﻴﻠﻪ آن رﻧﮓ ﻣﺘﻦ را ﺗﻐﻴﻴﺮ دﻫﻴﻢ و ﻳﺎ آن را ﺑﻪ ﺣﺮوف ﺑﺰرگ و ﻳﺎ ﻛﻮﭼﻚ ﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ. ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ از ﻳﻚ ﻧﻮار وﺿﻌﻴﺖ ﻧﻴﺰ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮ روي ﻳﻜﻲ از ﻛﻠﻴﺪﻫﺎي ﻧﻮار اﺑﺰار ﻛﻠﻴﻚ ﺷـﺪ، وﺿﻌﻴﺖ ﺑﺮﻧﺎﻣﻪ را ﺑﺮ اﺳﺎس آن ﻧﻤﺎﻳﺶ دﻫﻴﻢ. اوﻟﻴﻦ ﻣﺮﺣﻠﻪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻳﻚ ﭘﺮوژه ﺟﺪﻳﺪ اﺳﺖ.
٢٢٧
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ وﻳﺮاﻳﺸﮕﺮ ﻣﺘﻦ (1ﻳﻚ ﭘﺮوژه وﻳﻨﺪوزي ﺟﺪﻳﺪ اﻳﺠﺎد ﻛﺮده و ﻧﺎم آن را Text Editorﻗﺮار دﻫﻴﺪ. (2در اﻏﻠﺐ ﻣﻮارد ﻧﺎم Form1ﺑﺮاي ﻳﻚ ﻓﺮم ﻣﻨﺎﺳﺐ ﻧﻴﺴﺖ ،زﻳﺮا در ﺑﺮﻧﺎﻣﻪ ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻦ ﻧـﺎم ﻧﻤـﻲ ﺗـﻮان ﻓـﺮم ﻫـﺎ را از ﻳﻜﺪﻳﮕﺮ ﺗﺸﺨﻴﺺ داد .ﺑﺮاي ﺗﻐﻴﻴﺮ ﻧﺎم ﻓﺮم اﻳﻦ ﺑﺮﻧﺎﻣـﻪ ،در ﭘﻨﺠـﺮه Solution Explorerﺑـﺮ روي ﻧـﺎم ﻓـﺮم ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ Renameرا اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ .ﺳـﭙﺲ ﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ 9-6ﻧـﺎم ﻓـﺮم را ﺑـﻪ TextEditor.csﺗﻐﻴﻴﺮ دﻫﻴﺪ.
ﺷﻜﻞ 9-6 (3ﺣﺎل ﺑﺮ روي ﻓﺮم در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗـﺎ اﻧﺘﺨـﺎب ﺷـﻮد .ﺳـﭙﺲ در ﭘﻨﺠـﺮه Propertiesﺧﺎﺻـﻴﺖ Textآن را ﺑﻪ Text Editorو ﺧﺎﺻﻴﺖ Sizeﻓﺮم را ﺑﻪ 600;460ﺗﻐﻴﻴﺮ دﻫﻴﺪ. در ﻗﺴﻤﺖ ﺑﻌﺪ ﺑﻪ ﻃﺮاﺣﻲ راﺑﻂ ﻛﺎرﺑﺮي ﺑﺮﻧﺎﻣﻪ ﺧﻮاﻫﻴﻢ ﭘﺮداﺧﺖ.
اﻳﺠﺎد ﻧﻮار اﺑﺰار: ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﻳﻚ ﻧﻮار اﺑﺰار ﻣﺠﻤﻮﻋﻪ اي از ﻛﻨﺘﺮل ﻫﺎ اﺳﺖ ﻛﻪ اﻏﻠﺐ آﻧﻬﺎ Buttonﻫﺴﺘﻨﺪ ،ﻫﻤﺎﻧﻨـﺪ ﻧـﻮار اﺑـﺰار ﻣﻮﺟـﻮد در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ .2005در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻳﻚ ﻧﻮار اﺑﺰار ﺑﺮاي ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﺮده و Buttonﻫﺎي ﻣﻮرد ﻧﻴﺎز را ﻧﻴـﺰ ﺑﻪ آن اﺿﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﻧﻮار اﺑﺰار
٢٢٨
(1 (2
(3 (4
ﺑﺎ اﺳﺘﻔﺎده از ﻗﺴﻤﺖ ﺟﻌﺒﻪ اﺑﺰار وﻳﮋوال اﺳﺘﻮدﻳﻮ ،ﻛﻨﺘﺮل ToolStripرا اﻧﺘﺨﺎب ﻛﺮده و ﺑـﻪ وﺳـﻴﻠﻪ ﻣـﺎوس آن را ﺑـﺮ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ .اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ در ﺑﺎﻻي ﻓﺮم ﻗﺮار ﺧﻮاﻫﺪ ﮔﺮﻓﺖ. ﺑﺮاي اﻳﻦ ﻛﻪ ﺑﺘﻮاﻧﻴﻢ ﺗﻌﺪادي ﻛﻨﺘﺮل را ﺑـﻪ ﻧـﻮار اﺑـﺰار اﺿـﺎﻓﻪ ﻛﻨـﻴﻢ ،ﺑﺎﻳـﺪ از ﭘﻨﺠـﺮه Items Collection Editorاﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺑﺮاي ﻧﻤﺎﻳﺶ اﻳﻦ ﭘﻨﺠﺮه ﺑﺮ روي ﻧﻮار اﺑﺰار در ﺑﺎﻻي ﻓﺮم ﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ و از ﻣﻨﻮي ﺑﺎز ﺷـﺪه ﮔﺰﻳﻨﻪ … Edit Itemsرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. در اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﺎﻳﺪ ﺷﺶ ﻛﻨﺘﺮل Buttonﺑﻪ ﻧﻮار اﺑﺰار اﺿﺎﻓﻪ ﻛﻨـﻴﻢ ﺗـﺎ در ﺑﺮﻧﺎﻣـﻪ از آﻧﻬـﺎ اﺳـﺘﻔﺎده ﻛﻨـﻴﻢ .دﻛﻤـﻪ ﻫـﺎي UpperCase ،LowerCase ،Blue ،Red ،Clearو دﻛﻤﻪ .About ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي Items Collection Editorﻣﻲ ﺗﻮاﻧﻴﺪ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮرد ﻧﻴـﺎز ﺧـﻮد را ﺑـﻪ ﻧـﻮار اﺑﺰار اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﺮاي اﻧﺘﺨﺎب ﻧﻮع ﻛﻨﺘﺮل ﺑﺎﻳﺪ از ComboBoxاي ﻛﻪ در ﮔﻮﺷﻪ ﺑﺎﻻي ﺳـﻤﺖ ﭼـﭗ ﺻـﻔﺤﻪ ﻗـﺮار دارد اﺳﺘﻔﺎده ﻛﻨﻴﺪ .از ﻟﻴﺴﺖ اﻳﻦ ﻗﺴﻤﺖ ﮔﺰﻳﻨﻪ Buttonرا اﻧﺘﺨﺎب ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ Addﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻳﻚ ﻛﻨﺘـﺮل Buttonﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻟﻴﺴﺘﻲ از ﺧﺎﺻﻴﺘﻬﺎي ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل را ،ﻫﻤﺎﻧﻨﺪ ﺧﺎﺻﻴﺘﻬﺎي ﻣﻮﺟـﻮد در ﭘﻨﺠﺮه Propertiesﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد .ﺑﺮاي ﺗﻤﺎم ﻛﻨﺘﺮﻟﻬﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﺿـﺎﻓﻪ ﻣـﻲ ﻛﻨـﻴﻢ ﺑﺎﻳـﺪ ﻧـﺎم و ﻧﺤﻮه ﻧﻤﺎﻳﺶ آﻧﻬﺎ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ ،ﻳﻚ آﻳﻜﻮن ﻣﻨﺎﺳﺐ ﺑﺮاي آﻧﻬﺎ اﻧﺘﺨﺎب ﻛﻨﻴﺪ ،ﻣـﺘﻦ داﺧـﻞ آﻧﻬـﺎ را ﭘـﺎك ﻛﻨﻴـﺪ و ﻳـﻚ ﻣـﺘﻦ راﻫﻨﻤــﺎي ﻣﻨﺎﺳــﺐ ﺑــﺮاي آﻧﻬــﺎ ﻗــﺮار دﻫﻴــﺪ .ﺧﺎﺻــﻴﺖ Nameﻛﻨﺘــﺮل Buttonﺟﺪﻳــﺪ را ﻫﻤﺎﻧﻨــﺪ ﺷــﻜﻞ 10-6ﺑــﻪ tbrClearﺗﻐﻴﻴﺮ دﻫﻴﺪ .اﻳﻦ ﻛﻨﺘﺮل ﺑﺮاي ﭘﺎك ﻛﺮدن ﻣﺘﻦ وارد ﺷﺪه در داﺧﻞ وﻳﺮاﻳﺸﮕﺮ ﺑﻪ ﻛﺎر ﻣﻲ رود.
ﺷﻜﻞ 10-6 (5ﺧﺎﺻﻴﺖ DisplayStyleآن را ﻧﻴﺰ ﺑﻪ Imageﺗﻐﻴﻴﺮ دﻫﻴﺪ. (6در ﻟﻴﺴﺖ ﺧﺎﺻﻴﺘﻬﺎي ﻣﻮﺟﻮد ﺑﺮاي اﻳﻦ ﻛﻨﺘﺮل ،ﺧﺎﺻﻴﺖ Imageرا اﻧﺘﺨﺎب ﻛﺮده و ﺑﺮ روي ﻋﻼﻣﺖ … روﺑﺮوي آن ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﭘﻨﺠﺮه Select Resourceﺑﺎز ﺷﻮد .در اﻳﻦ ﭘﻨﺠﺮه ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن Importﻛﻠﻴﻚ ﻛﻨﻴﺪ .در ﭘﻨﺠﺮه Openﺑﻪ آدرس زﻳﺮ ﺑﺮوﻳﺪ و ﻓﺎﻳﻞ document.icoرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ) .اﮔﺮ ﺑﺮﻧﺎﻣﻪ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ را در ﻓﻮﻟﺪر دﻳﮕﺮي ﻧﺼﺐ ﻛﺮده اﻳﺪ ﺑﻪ ﺟﺎي اﻳﻦ آدرس از آدرﺳﻲ ﻛﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ در آن ﻗﺮار دارد اﺳﺘﻔﺎده ﻛﻨﻴﺪ(
٢٢٩
\C:\Program Files\Microsoft Visual Studio 8 \Common7 VS2005ImageLibrary\icons\WinXP ﺳـﭙﺲ ﺑـﺮ روي دﻛﻤـﻪ OKدر ﭘﻨﺠـﺮه Select Resourceﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﺑـﻪ ﻗـﺴﻤﺖ Items Collection Editorﺑﺎزﮔﺮدﻳﺪ. (7ﺧﺎﺻــﻴﺖ ImageScalingرا ﺑــﻪ noneو ﺧﺎﺻــﻴﺖ ToolTipTextرا ﺑﺮاﺑــﺮ ﺑــﺎ Newﻗــﺮار دﻫﻴــﺪ. ﻫﻤﭽﻨﻴﻦ ﻣﻘﺪار وارد ﺷﺪه ﺑﺮاي ﺧﺎﺻﻴﺖ Textرا ﻧﻴﺰ ﭘﺎك ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﻨﺘﺮل Buttonاول اﻳﺠﺎد ﺷﺪه اﺳﺖ. (8دﻛﻤﻪ ي ﺑﻌﺪي ﻛﻪ اﺿﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛﺮد ،دﻛﻤﻪ ي Redاﺳﺖ .اﻣﺎ اﺑﺘﺪا ﺑﺎﻳﺪ ﻳﻚ ﺧﻂ ﺟـﺪا ﻛﻨﻨـﺪه ﺑـﻴﻦ دﻛﻤـﻪ Clearو دﻛﻤﻪ Redﻗﺮار دﻫﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر در ﭘﻨﺠﺮه Item Collection Editorاز ﻟﻴﺴﺖ ﺟﻌﺒﻪ ﺗﺮﻛﻴﺒـﻲ، ﮔﺰﻳﻨﻪ Seperatorرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ و ﺳﭙﺲ ﺑﺮ روي ﻛﻠﻴﺪ Addﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻧﻴـﺎزي ﻧﻴـﺴﺖ ﻛـﻪ ﺧﺎﺻـﻴﺘﻬﺎي اﻳـﻦ ﻛﻨﺘﺮل را ﺗﻐﻴﻴﺮ دﻫﻴﺪ و ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﻤﺎم ﺧﺎﺻﻴﺘﻬﺎي ﭘﻴﺶ ﻓﺮض آن را ﻗﺒﻮل ﻛﻨﻴﺪ. (9ﻣﺮاﺣﻞ 4ﺗﺎ 7را ﺑﺮاي اﻳﺠﺎد دﻛﻤﻪ ﻓﺮﻣﺎن دوم ﺗﻜﺮار ﻛﻨﻴﺪ و ﺧﺎﺻﻴﺘﻬﺎي اﻳﻦ دﻛﻤﻪ ﻓﺮﻣﺎن را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺎدﻳﺮ زﻳﺮ ﻗﺮار دﻫﻴـﺪ .از اﻳﻦ دﻛﻤﻪ ﻓﺮﻣﺎن ﺑﺮاي ﺗﻐﻴﻴﺮ رﻧﮓ ﻣﺘﻦ ﺑﻪ رﻧﮓ ﻗﺮﻣﺰ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن دﻛﻤﻪ ﻓﺮﻣـﺎن ﻗﺒـﻞ از اﻳﻨﻜـﻪ ﺑـﺮ روي دﻛﻤﻪ Addﻛﻠﻴﻚ ﻛﻨﻴﺪ ،ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﮔﺰﻳﻨﻪ Buttonدر ﺟﻌﺒﻪ ﺗﺮﻛﻴﺒﻲ اﻧﺘﺨﺎب ﺷﺪه ﺑﺎﺷﺪ:
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ tbrRedوارد ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ DisplayStyleرا ﺑﺮاﺑﺮ ﺑﺎ Imageﻗﺮار دﻫﻴﺪ. ﺑﺮاي ﺧﺎﺻﻴﺖ Imageاز آدرس \VS2005ImageLibrary\icons\Misc\servicestopped.i coاﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ ImageScalingرا ﺑﺮاﺑﺮ ﺑﺎ Noneﻗﺮار دﻫﻴﺪ. ﻣﻘﺪار ﻣﻮﺟﻮد در ﺧﺎﺻﻴﺖ Textرا ﭘﺎك ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ ToolTipTextرا ﺑﺮاﺑﺮ ﺑﺎ Redﻗﺮار دﻫﻴﺪ.
(10ﻣﺮاﺣﻞ 4ﺗﺎ 7را ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن دﻛﻤﻪ ﻓﺮﻣﺎن Blueﺗﻜﺮار ﻛﻨﻴﺪ و در اﻳﻦ ﻣﺮﺣﻠﻪ از ﺧﺎﺻﻴﺘﻬﺎي زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ tbrBlueوارد ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ DisplayStyleرا ﺑﺮاﺑﺮ ﺑﺎ Imageﻗﺮار دﻫﻴﺪ. ﺑﺮاي ﺧﺎﺻﻴﺖ Imageاز آدرس \VS2005ImageLibrary\icons\Misc\services.icoاﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ ImageScalingرا ﺑﺮاﺑﺮ ﺑﺎ Noneﻗﺮار دﻫﻴﺪ. ﻣﻘﺪار ﻣﻮﺟﻮد در ﺧﺎﺻﻴﺖ Textرا ﭘﺎك ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ ToolTipTextرا ﺑﺮاﺑﺮ ﺑﺎ Blueﻗﺮار دﻫﻴﺪ.
(11در اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﺎﻳﺪ ﺑﻴﻦ دﻛﻤﻪ ﻫﺎي Blueو UpperCaseﻧﻴﺰ ﻳﻚ ﺧﻂ ﺟﺪا ﻛﻨﻨﺪه ﻗـﺮار دﻫـﻴﻢ .در ﺟﻌﺒـﻪ ﺗﺮﻛﻴﺒـﻲ ﺻﻔﺤﻪ ي Items Collection Editorﮔﺰﻳﻨﻪ Seperatorرا اﻧﺘﺨﺎب ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ Addﻛﻠﻴﻚ ﻛﻨﻴﺪ .در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﻧﻴﺎزي ﻧﻴﺴﺖ ﺧﺎﺻﻴﺘﻲ از اﻳﻦ ﻛﻨﺘﺮل را ﺗﻐﻴﻴﺮ دﻫﻴﺪ. (12ﺣﺎل ﺑﺎﻳﺪ ﻛﻨﺘﺮل Buttonﺟﺪﻳﺪي اﺿﺎﻓﻪ ﻛﻨﻴﻢ ﺗﺎ ﻣﺘﻦ داﺧﻞ وﻳﺮاﻳﺸﮕﺮ را ﺑﻪ ﺣﺮوف ﺑﺰرگ ﺗﺒﺪﻳﻞ ﻛﻨﺪ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﻣﺮاﺣﻞ 4ﺗﺎ 7را ﺑﺮاي اﻳﺠﺎد دﻛﻤﻪ ﻓﺮﻣﺎن UpperCaseﺗﻜﺮار ﻛﻨﻴﺪ و در اﻳﻦ ﻣﺮﺣﻠﻪ از ﺧﺎﺻﻴﺘﻬﺎي زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ:
٢٣٠
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ tbrUpperCaseوارد ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ DisplayStyleرا ﺑﺮاﺑﺮ ﺑﺎ Imageﻗﺮار دﻫﻴﺪ. ﺑﺮاي ﺧﺎﺻﻴﺖ Imageاز آدرس \VS2005ImageLibrary\icons\WinXP\fonFile.icoاﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ ImageScalingرا ﺑﺮاﺑﺮ ﺑﺎ Noneﻗﺮار دﻫﻴﺪ. ﻣﻘﺪار ﻣﻮﺟﻮد در ﺧﺎﺻﻴﺖ Textرا ﭘﺎك ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ ToolTipTextرا ﺑﺮاﺑﺮ ﺑﺎ Upper Caseﻗﺮار دﻫﻴﺪ.
(13ﻛﻨﺘﺮل Buttonدﻳﮕﺮي ﺑﺮاي Lowercaseاﻳﺠﺎد ﻛﻨﻴﺪ ﺗﺎ ﺑﻪ وﺳﻴﻠﻪ آن ﺑﺘﻮاﻧﻴﻢ ﻣﺘﻦ را ﺑﻪ ﺣﺮوف ﻛﻮﭼﻚ ﺗﺒـﺪﻳﻞ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﻨﺘﺮل از ﺧﺎﺻﻴﺘﻬﺎي زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ tbrLowerCaseوارد ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ DisplayStyleرا ﺑﺮاﺑﺮ ﺑﺎ Imageﻗﺮار دﻫﻴﺪ. ﺑﺮاي ﺧﺎﺻﻴﺖ Imageاز آدرس \VS2005ImageLibrary\icons\WinXP\fonfont.icoاﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ ImageScalingرا ﺑﺮاﺑﺮ ﺑﺎ Noneﻗﺮار دﻫﻴﺪ. ﻣﻘﺪار ﻣﻮﺟﻮد در ﺧﺎﺻﻴﺖ Textرا ﭘﺎك ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ ToolTipTextرا ﺑﺮاﺑﺮ ﺑﺎ Lower Caseﻗﺮار دﻫﻴﺪ.
(14ﺑﺎ ﺗﻐﻴﻴﺮ ﮔﺰﻳﻨﻪ اﻧﺘﺨﺎب ﺷﺪه در ﺟﻌﺒﻪ ﺗﺮﻛﻴﺒﻲ ﺑـﻪ Seperatorو ﻛﻠﻴـﻚ ﻛـﺮدن ﺑـﺮ روي دﻛﻤـﻪ Addﺟـﺪا ﻛﻨﻨـﺪه دﻳﮕﺮي ﺑﻴﻦ دﻛﻤﻪ ﻫﺎي LowerCaseو Aboutﻗﺮار دﻫﻴﺪ. (15در اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﺎﻳﺪ دﻛﻤﻪ اي ﺑﺮاي ﻗﺴﻤﺖ Aboutﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﺮاﺣﻞ 4ﺗﺎ 7را ﺑـﺮاي اﻳﺠـﺎد ﻳـﻚ دﻛﻤﻪ ﻓﺮﻣﺎن ﺟﺪﻳﺪ ﺗﻜﺮار ﻛﻨﻴﺪ و اﻳﻦ ﺑﺎر از ﺧﺎﺻﻴﺘﻬﺎي زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ tbrHelpAboutوارد ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ DisplayStyleرا ﺑﺮاﺑﺮ ﺑﺎ Imageﻗﺮار دﻫﻴﺪ. ﺑﺮاي ﺧﺎﺻﻴﺖ Imageاز آدرس \VS2005ImageLibrary\icons\WinXP\help.icoاﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ ImageScalingرا ﺑﺮاﺑﺮ ﺑﺎ Noneﻗﺮار دﻫﻴﺪ. ﻣﻘﺪار ﻣﻮﺟﻮد در ﺧﺎﺻﻴﺖ Textرا ﭘﺎك ﻛﻨﻴﺪ. ﺧﺎﺻﻴﺖ ToolTipTextرا ﺑﺮاﺑﺮ ﺑﺎ Aboutﻗﺮار دﻫﻴﺪ.
(16در ﭘﻨﺠﺮه Items Collection Editorﺑﺮ روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﭘﻨﺠـﺮه ﺑـﺴﺘﻪ ﺷـﻮد و ﺑـﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ. (17ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن ﺑﺮ روي دﻛﻤﻪ Save Allدر ﻧﻮار اﺑﺰار وﻳﮋوال اﺳﺘﻮدﻳﻮ ،ﺗﻐﻴﻴﺮات اﻳﺠﺎد ﺷﺪه در ﺑﺮﻧﺎﻣﻪ را ذﺧﻴﺮه ﻛﻨﻴﺪ.
٢٣١
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻛﻨﺘﺮل ToolStripﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﻓﺮم ﻗﺮار داده ﺷﻮد ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺑﻪ ﻳﻜﻲ از ﻛﻨﺎره ﻫﺎي ﻓﺮم ﻣﺘﺼﻞ ﻣﻲ ﺷﻮد .در اﻳـﻦ ﺑﺮﻧﺎﻣﻪ ،اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﺑﺎﻻي ﻓﺮم ﻣﺘﺼﻞ ﺷﺪه اﺳﺖ. ﺷﺶ ﻛﻨﺘﺮل Buttonو ﺳﻪ ﺟﺪا ﻛﻨﻨﺪه اي ﻛﻪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﺪه اﻧﺪ ،ﻫﺮ ﻳﻚ ﻫﻤﺎﻧﻨﺪ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻌﻤﻮﻟﻲ ﻛﻪ ﺑـﺮ روي ﻓـﺮم ﻗـﺮار ﻣﻲ ﮔﻴﺮﻧﺪ ،ﻗﺎﺑﻞ اﻧﺘﺨﺎب ﺷﺪن ﻫﺴﺘﻨﺪ و ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﻧﺘﺨﺎب آﻧﻬﺎ ،ﺧﺼﻮﺻﻴﺎت آﻧﻬﺎ را در ﻗﺴﻤﺖ Propertiesﻣﺸﺎﻫﺪه ﻛﻨﻴـﺪ و ﻧﻴﺰ ﺑﻪ روﻳﺪادﻫﺎي اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ .در ﻗﺴﻤﺘﻬﺎي ﺑﻌﺪي ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑـﻪ روﻳـﺪادﻫﺎي اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﻫﻤﺎﻧﻨﺪ روﻳﺪاد ﻛﻠﻴﻚ ﭘﺎﺳﺦ دﻫﻴﻢ. ﻳﻚ ﻛﻨﺘﺮل در ﻧﻮار اﺑﺰار ﻣﻲ ﺗﻮاﻧﺪ ﻓﻘﻂ داراي ﻋﻜﺲ ﺑﺎﺷﺪ ،ﻓﻘﻂ داراي ﻧﻮﺷﺘﻪ ﺑﺎﺷﺪ و ﻳﺎ داراي ﻫﻢ ﻋﻜﺲ و ﻫﻢ ﻧﻮﺷﺘﻪ ﺑﺎﺷﺪ .اﻣﺎ در ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ دﻛﻤﻪ ﻫﺎي روي ﻧﻮار اﺑﺰار ﻓﻘﻂ داراي ﻋﻜﺲ ﻫﺴﺘﻨﺪ .ﺑﻪ ﻫﻤﻴﻦ ﻋﻠﺖ ﺧﺎﺻـﻴﺖ DisplayStyleاﻳـﻦ ﻛﻨﺘـﺮل ﻫـﺎ را ﺑﺮاﺑﺮ ﺑﺎ Imageﻗﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ ﻓﻘﻂ ﻳﻚ ﻋﻜﺲ ﺑﺮاي ﻫﺮ دﻛﻤﻪ ﻓﺮﻣﺎن ﻧﻤﺎﻳﺶ داده ﺷﻮد .ﻫﻤﭽﻨﻴﻦ ﺑﺮاي اﻳﻨﻜـﻪ اﻧـﺪازه ﻋﻜـﺴﻬﺎي ﻣﺸﺨﺺ ﺷﺪه ﺑﺮاي ﻛﻨﺘﺮل ﻫﺎ ﺗﻐﻴﻴﺮ ﻧﻜﻨﺪ و ﺗﻤﺎم ﻋﻜﺴﻬﺎ در اﻧﺪازه اوﻟﻴﻪ ﺧﻮد ﺑﺎﻗﻲ ﺑﻤﺎﻧﻨـﺪ ،ﺧﺎﺻـﻴﺖ ImageScalingآﻧﻬـﺎ را ﺑﺮاﺑﺮ ﺑﺎ Noneﻗﺮار ﻣﻲ دﻫﻴﻢ. ﺧﺎﺻﻴﺖ ToolTipTextﺑﻪ وﻳﮋوال C#اﻳﻦ اﻣﻜﺎن را ﻣﻲ دﻫﺪ ﻛﻪ ﻳﻚ راﻫﻨﻤﺎي ﻣﺨﺘﺼﺮ ﺑﺮاي ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻧﻮار اﺑـﺰار اﻳﺠﺎد ﻛﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﺷﺎره ﮔﺮ ﻣﺎوس ﺑﺮاي ﻣﺪت ﻛﻮﺗﺎﻫﻲ ﺑﺮ روي اﻳﻦ ﻛﻨﺘﺮل ﻣﺎﻧﺪ ،ﭘﻨﺠﺮه ﻛﻮﭼﻜﻲ ﺑﺎز ﻣﻲ ﺷﻮد و ﻣـﺘﻦ ﻧﻮﺷﺘﻪ ﺷﺪه در اﻳﻦ ﺧﺎﺻﻴﺖ را ﺑﻪ ﻋﻨﻮان راﻫﻨﻤﺎ ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. در اﻳﻦ ﻣﺮﺣﻠﻪ ﻧﻮار اﺑﺰار ﺷﻤﺎ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 11-6ﺷﺪه ﺑﺎﺷﺪ.
ﺷﻜﻞ 11-6
اﻳﺠﺎد ﻧﻮار وﺿﻌﻴﺖ: ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي دﻳﮕﺮ ﻣﺸﺎﻫﺪه ﻛﺮده اﻳﺪ ،ﻳﻚ ﻧﻮار وﺿﻌﻴﺖ ،ﭘﻨﻞ ﻛﻮﭼﻜﻲ اﺳﺖ ﻛﻪ در ﭘﺎﻳﻦ ﺻﻔﺤﻪ ﻗﺮار ﻣﻲ ﮔﻴﺮد و وﺿﻌﻴﺖ ﻛﻨﻮﻧﻲ ﺑﺮﻧﺎﻣﻪ را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻧﺤﻮه اﻳﺠﺎد ﻧﻮار وﺿﻌﻴﺖ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻳﻚ ﻧﻮار وﺿﻌﻴﺖ (1ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار وﻳﮋوال اﺳﺘﻮدﻳﻮ ،ﻳﻚ ﻛﻨﺘﺮل StatusStripرا در ﻓﺮم ﻗﺮار دﻫﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛـﻪ اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﻃﻮر اﺗﻮﻣﺎﺗﻴﻚ در ﻗﺴﻤﺖ ﭘﺎﻳﻦ ﻓﺮم ﻗﺮار ﮔﺮﻓﺘﻪ و ﻃﻮل آن ﻧﻴﺰ ﺑﻪ اﻧﺪازه ﻃـﻮل ﺻـﻔﺤﻪ ﺧﻮاﻫـﺪ ﺷـﺪ .ﺧﺎﺻـﻴﺖ RenderModeاﻳﻦ ﻛﻨﺘﺮل را ﺑﻪ Systemﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ ﻛﻨﺘﺮل ﺑﻪ ﺻﻮرت ﻣﺴﻄﺢ درآﻳﺪ. (2در اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﺎﻳﺪ ﻳﻚ ﻛﻨﺘﺮل ﻟﻴﺒﻞ را ﺑﻪ ﻟﻴﺴﺖ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در StatusStripاﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗـﺎ ﺑﺘﻮاﻧﻴـﺪ ﻣـﺘﻦ ﻫﺎي ﻣﻮرد ﻧﻈﺮﺗﺎن را در آن ﻧﻤﺎﻳﺶ دﻫﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺮ روي ﻧﻮار وﺿﻌﻴﺖ اﺿﺎﻓﻪ ﺷﺪه ﺑﻪ ﻓـﺮم ﻛﻠﻴـﻚ راﺳـﺖ ﻛـﺮده و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ … Edit Itemsرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ ﭘﻨﺠﺮه Items Collection Editor
٢٣٢
ﺑﺎز ﺷﻮد .اﻳﻦ ﭘﻨﺠﺮه ﻧﻴﺰ ﻣﺸﺎﺑﻪ ﭘﻨﺠﺮه ي Items Collection Editorﺑﺮاي ﻛﻨﺘﺮل ﻧﻮار اﺑﺰار اﺳﺖ .در ﺟﻌﺒﻪ ﺗﺮﻛﻴﺒﻲ ﺳﻤﺖ ﭼﭗ اﻳﻦ ﭘﻨﺠﺮه ،ﮔﺰﻳﻨﻪ StatusLabelرا اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ و ﺳـﭙﺲ ﺑـﺮ روي دﻛﻤـﻪ ي Add ﻛﻠﻴﻚ ﻛﻨﻴﺪ. (3ﺧﺎﺻﻴﺖ ﻫﺎي ﻛﻨﺘﺮل ﻟﻴﺒﻞ اﺿﺎﻓﻪ ﺷﺪه ﺑﻪ ﻧﻮار وﺿﻌﻴﺖ را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺎدﻳﺮ زﻳﺮ ﻗﺮار دﻫﻴﺪ:
ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑﺎ sspStatusﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ DisplayStyleآن را ﺑﻪ Textﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textآن را ﺑﻪ Readyﺗﻐﻴﻴﺮ دﻫﻴﺪ.
(4ﺑﺮ روي دﻛﻤﻪ OKدر ﭘﻨﺠﺮه Items Collection Editorﻛﻠﻴﻚ ﻛﻨﻴﺪ. (5ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﺑﺮوﻳﺪ و ﻛﺪ زﻳﺮ را در ﺑﻪ ﻛﻼس ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: // Get or set the text on the status bar public string StatusText { get { ;return sspStatus.Text } set { ;sspStatus.Text = value } } در اﻳﻦ ﻣﺮﺣﻠﻪ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ ،زﻳﺮا ﻫﻨﻮز ﻛﺪ اﺻﻠﻲ آن را وارد ﻧﻜﺮده اﻳﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻬﺘﺮ اﺳﺖ ﻣﺮوري ﺑـﺮ ﻗـﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005وﻳﮋﮔﻴﻬﺎي زﻳﺎدي ﺑﺮاي راﺣﺖ ﺗﺮ ﻛﺮدن ﻃﺮاﺣﻲ ﻓﺮم دارد .ﻳﻜﻲ از ﻣﻮاردي ﻛﻪ ﻫﻤﻮاره در ﻧﺴﺨﻪ ﻫﺎي ﻗﺒﻠﻲ ﺑﺎﻋﺚ دردﺳﺮ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﻣﻲ ﺷﺪ ،ﺗﻨﻈﻴﻢ اﻧﺪازه ي ﻛﻨﺘﺮل ﻫﺎ ﻫﻨﮕﺎم ﺗﻐﻴﻴﺮ اﻧﺪازه ﻓﺮم ﺗﻮﺳﻂ ﻛﺎرﺑﺮ ﺑﻮد .ﺑﺮاي ﻣﺜﺎل ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻓﺮم را ﺑـﺮاي اﻧﺪازه 600*400ﻃﺮاﺣﻲ ﻣﻲ ﻛﺮد .اﻣﺎ ﻫﻨﮕﺎم اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ،ﻛﺎرﺑﺮ اﻧﺪازه ي ﻓﺮم را ﺑﻪ 800*700و ﻳﺎ ﻫﺮ اﻧﺪازه دﻳﮕـﺮي ﺗﻐﻴﻴـﺮ ﻣـﻲ داد. ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺗﻤﺎم ﻛﻨﺘﺮل ﻫﺎ ﺑﻪ ﻃﻮر ﻧﺎﻣﺮﺗﺐ ﺑﺮ روي ﻓﺮم ﻗﺮار ﻣﻲ ﮔﺮﻓﺘﻨﺪ. در وﻳــﮋوال اﺳــﺘﻮدﻳﻮ ،2005ﻛﻨﺘــﺮل ﻫـﺎ ﻣــﻲ ﺗﻮاﻧﻨــﺪ ﺑــﻪ ﻳﻜــﻲ از ﻟﺒــﻪ ﻫــﺎي ﻓــﺮم ﻣﺘــﺼﻞ ﺷــﻮﻧﺪ .ﺑــﻪ ﺻــﻮرت ﭘــﻴﺶ ﻓــﺮض ﻛﻨﺘــﺮل StatusStripﺑﻪ ﭘﺎﻳﻦ ﻓﺮم ﻣﺘﺼﻞ ﻣﻲ ﺷﻮد .اﻟﺒﺘﻪ اﻳﻦ ﺧﺎﺻﻴﺖ ﻗﺎﺑﻞ ﺗﻐﻴﻴﺮ اﺳﺖ و ﻣﻲ ﺗﻮاﻧﻴﺪ در ﺻـﻮرت ﻟـﺰوم ﺑـﺎ اﺳـﺘﻔﺎده از
٢٣٣
ﺧﺎﺻﻴﺖ Dockآن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ .1ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻧﺪازه ﻓﺮم ﺗﻐﻴﻴﺮ ﻛﻨﺪ ،ﭼﻪ در زﻣﺎن ﻃﺮاﺣﻲ و ﭼـﻪ در زﻣـﺎن اﺟـﺮا ،ﻧـﻮار وﺿﻌﻴﺖ )ﻛﻨﺘﺮل (StatusStripﻣﻮﻗﻌﻴﺖ ﺧﻮد را ﺑﺎ اﻧﺪازه ﺟﺪﻳﺪ ﻓﺮم ﺗﻨﻈﻴﻢ ﺧﻮاﻫﺪ ﻛﺮد. ﻣﻤﻜﻦ اﺳﺖ ﺑﭙﺮﺳﻴﺪ ﻛﻪ ﭼﺮا در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻳﻚ ﺧﺎﺻﻴﺖ ﺑﻪ ﻧﺎم StatusTextاﻳﺠﺎد ﻛﺮده ام و وﻇﻴﻔـﻪ ي ﺗﻨﻈـﻴﻢ ﻛـﺮدن ﻣـﺘﻦ داﺧﻞ ﻧﻮار وﺿﻌﻴﺖ را ﺑﻪ آن ﺳﭙﺮده ام .ﺧﻮب اﻳﻦ ﻣﻮرد ﺑﻪ ﻋﻠﺖ ﺗﺠﺮد 2ﺑﺮﻧﺎﻣﻪ اﺳﺖ .ﻓﺮض ﻛﻨﻴﻢ در آﻳﻨﺪه اﻓـﺮادي ﺑﺨﻮاﻫﻨـﺪ از ﺑﺮﻧﺎﻣـﻪ ي وﻳﺮاﻳﺸﮕﺮ ﻣﺘﻨﻲ ﻛﻪ ﺷﻤﺎ ﻧﻮﺷﺘﻪ اﻳﺪ ،ﺑﻪ ﻋﻨﻮان ﻳﻜﻲ از ﻓﺮﻣﻬﺎي ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻨﺪ .ﺣﺎل ﻣﻤﻜﻦ اﺳﺖ اﻳـﻦ اﻓـﺮاد در ﻗـﺴﻤﺘﻲ از ﺑﺮﻧﺎﻣﻪ ﺑﺨﻮاﻫﻨﺪ ﻛﻪ ﻣﺘﻦ داﺧﻞ ﻧﻮار وﺿﻌﻴﺖ اﻳﻦ ﻓﺮم را ﺗﻐﻴﻴﺮ دﻫﻨﺪ .اﮔﺮ در ﺑﺮﻧﺎﻣﻪ از ﻳﻚ ﺧﺎﺻﻴﺖ ﺑﺮاي ﺗﻐﻴﻴﺮ و ﻳﺎ دﺳﺘﺮﺳﻲ ﺑﻪ ﻣﺘﻦ ﻧـﻮار وﺿﻌﻴﺖ اﺳﺘﻔﺎده ﻛﻨﻴﻢ ،آن اﻓﺮاد در آﻳﻨﺪه ﺻﺮﻓﻨﻈﺮ از اﻳﻨﻜﻪ ﻣﺎ ،از ﭼﻪ ﻧﻮار اﺑﺰاري در وﻳﺮاﻳﺸﮕﺮ ﻣﺘﻦ ﺧﻮد اﺳﺘﻔﺎده ﻣـﻲ ﻛﻨـﻴﻢ و ﻳـﺎ ﺑـﺪون ﺗﻮﺟﻪ ﺑﻪ اﻳﻨﻜﻪ آن ﻧﻮار اﺑﺰار ﺑﻪ ﭼﻪ ﺻﻮرت ﻣﺘﻦ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ ،ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﺧﺎﺻﻴﺖ ﻣﺘﻦ داﺧـﻞ ﻧـﻮار اﺑـﺰار را ﺗﻐﻴﻴـﺮ دﻫﻨﺪ. دﻟﻴﻞ اﻳﻨﻜﻪ اﻳﻦ ﺧﺎﺻﻴﺖ را از ﻧﻮع publicﺗﻌﺮﻳﻒ ﻛﺮده ام ﻧﻴﺰ ﺑﻪ ﻫﻤﻴﻦ ﻣﻮرد ﺑﺮﻣﻲ ﮔﺮدد .در ﺣﻘﻴﻘﺖ ﻋﺒﺎرت publicﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻛﺪﻫﺎي دﻳﮕﺮي ﻛﻪ در ﺧﺎرج از اﻳﻦ ﻓﺎﻳﻞ ﻫﺴﺘﻨﺪ ،ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ اﻳﻦ ﺧﺎﺻﻴﺖ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ و از آن اﺳﺘﻔﺎده ﻛﻨﻨﺪ. اﮔﺮ ﻧﺨﻮاﻫﻴﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕﺮ اﻳﻦ ﺧﺎﺻﻴﺖ را ﺗﻐﻴﻴﺮ دﻫﻨﺪ ،ﺑﺎﻳﺪ اﻳﻦ ﺧﺎﺻﻴﺖ را از ﻧﻮع privateﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ .در ﻓﺼﻮل 9ﺗـﺎ 13 ﺑﻴﺸﺘﺮ ﺑﺎ اﻳﻦ ﻣﻔﺎﻫﻴﻢ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ. در ﻗﺴﻤﺘﻬﺎي ﺑﻌﺪي اﻳﻦ ﺑﺮﻧﺎﻣﻪ ،ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺑﻌﻀﻲ از ﻣﺘﺪﻫﺎ و ﻳﺎ ﺧﺎﺻﻴﺖ ﻫﺎ ﺑﻪ ﺻﻮرت privateو ﺑﺮﺧﻲ دﻳﮕـﺮ ﺑـﻪ ﺻﻮرت publicﺗﻌﺮﻳﻒ ﺷﺪه اﻧﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﻮﺟﻪ ﻣﻲ ﺷﻮﻳﺪ ﻛﻪ ﻛﺪاﻣﻴﻚ ﺑﻪ وﺳﻴﻠﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳـﺴﺎن دﻳﮕـﺮ ﻧﻴـﺰ ﻗﺎﺑـﻞ اﺳـﺘﻔﺎده ﻫﺴﺘﻨﺪ و ﻛﺪاﻣﻴﻚ ﻧﻤﻲ ﺗﻮاﻧﻨﺪ ﺗﻮﺳﻂ آﻧﺎن ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮﻧﺪ.
اﻳﺠﺎد ﻗﺴﻤﺖ وﻳﺮاﻳﺶ ﻣﺘﻦ: در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪTextBox ،اي را در ﻓﺮم ﻗﺮار ﻣﻲ دﻫﻴﻢ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺘﻮاﻧﺪ ﻣﺘﻦ ﻣـﻮرد ﻧﻈـﺮ ﺧـﻮد را در آن وارد ﻛﻨـﺪ .ﻫـﺮ ﻛﻨﺘﺮل TextBoxداراي ﺧﺎﺻﻴﺘﻲ ﺑﻪ ﻧﺎم Multilineاﺳﺖ ﻛﻪ ﺑﻪ ﺻﻮرت ﭘـﻴﺶ ﻓـﺮض ﺑﺮاﺑـﺮ ﺑـﺎ Falseاﺳـﺖ .اﻳـﻦ ﺧﺎﺻﻴﺖ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ آﻳﺎ ﻛﻨﺘﺮل ﻣﻲ ﺗﻮاﻧﺪ ﺑﻴﺶ از ﻳﻚ ﺧﻂ ﻣﺘﻦ را در ﺧﻮد ﺟﺎي دﻫﺪ ﻳﺎ ﺧﻴﺮ .اﮔﺮ ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ را ﺑﺮاﺑﺮ ﺑـﺎ trueﻗﺮار دﻫﻴﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ اﻧﺪازه ي TextBoxرا ﺑﻪ ﻫﺮ اﻧﺪازه اي ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺗﻐﻴﻴﺮ دﻫﻴﺪ و ﻛﻨﺘﺮل ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺪ ﻫﺮ ﭼﻨﺪ ﺧﻂ ﻣﺘﻦ ﻛﻪ در آن وارد ﺷﻮد را ﻧﻤﺎﻳﺶ دﻫﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻗﺴﻤﺖ وﻳﺮاﻳﺶ ﻣﺘﻦ (1ﺑﻪ ﻗﺴﻤﺖ ﻣﺮﺑﻮط ﺑﻪ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮوﻳﺪ و ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﻚ ﻛﻨﺘﺮل TextBoxﺑـﺮ روي ﻓـﺮم ﻗﺮار دﻫﻴﺪ. (2ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل را ﻣﻄﺎﺑﻖ ﺑﺎ ﻣﻘﺎدﻳﺮ زﻳﺮ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑﺎ txtEditﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Dockآن را ﺑﺮاﺑﺮ ﺑﺎ Fillﻗﺮار دﻫﻴﺪ.
1ﻳﻜﻲ دﻳﮕﺮ از ﺧﺎﺻﻴﺘﻬﺎي ﭘﺮ ﻛﺎرﺑﺮد ﻫﻤﺎﻧﻨﺪ ،Dockﺧﺎﺻﻴﺖ Anchorاﺳﺖ ﻛﻪ ﻓﺎﺻﻠﻪ ﻳﻚ ﻛﻨﺘﺮل را ﺑﺎ ﺑﻌﻀﻲ از ﻟﺒﻪ ﻫﺎي ﻓﺮم ﺑﻪ اﻧﺪازه ﻣﺸﺨﺼﻲ ﻧﮕـﻪ ﻣـﻲ دارد .ﺑﺮاي اﻃﻼﻋﺎت ﺑﻴﺸﺘﺮ در ﻣﻮرد اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﻪ راﻫﻨﻤﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ. 2 Abstraction
٢٣٤
ﺧﺎﺻﻴﺖ MultiLineرا ﺑﺮاﺑﺮ ﺑﺎ Trueﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ ScrollBarsرا ﺑﺮاﺑﺮ ﺑﺎ Verticalﻗﺮار دﻫﻴﺪ.
ﺑﻌﺪ از اﻳﻦ ﻣﻮارد ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 12-6ﺑﺎﺷﺪ.
ﭘﺎك ﻛﺮدن ﺑﺨﺶ وﻳﺮاﻳﺸﮕﺮ ﻣﺘﻦ: در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ،ﺧﺎﺻﻴﺘﻲ ﺑﻪ ﻧﺎم EditTextاﻳﺠﺎد ﺧﻮاﻫﻴﺪ ﻛـﺮد ﻛـﻪ ﺑـﻪ وﺳـﻴﻠﻪ آن ﺑﺘﻮاﻧﻴـﺪ ﻣـﺘﻦ ﻣـﻮارد ﺷـﺪه در TextBoxرا درﻳﺎﻓﺖ ﻛﺮده و ﻳﺎ آن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﺎك ﻛﺮدن ﻣﺘﻦ داﺧﻞ TextBoxﺑﺴﻴﺎر ﺳـﺎده ﺧﻮاﻫـﺪ ﺑـﻮد، ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ اﻳﻦ ﺧﺎﺻﻴﺖ را ﺑﺮاﺑﺮ ﺑﺎ ﻳﻚ رﺷﺘﻪ ﺧﺎﻟﻲ ﻣﺎﻧﻨﺪ String.Emptyﻗﺮار دﻫﻴﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﭘﺎك ﻛﺮدن ﻣﺘﻦ داﺧﻞ وﻳﺮاﻳﺸﮕﺮ
ﺷﻜﻞ 12-6
(1ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﺑﺮوﻳﺪ و ﻛﺪ زﻳﺮ را در آن وارد ﻛﻨﻴﺪ:
٢٣٥
// Gets or sets the text that you are editing public string EditText { get { ;return txtEdit.Text } set { ;txtEdit.Text = value } } ﻫﻤﺎﻧﻨﺪ ﻗﺴﻤﺖ ﻗﺒﻞ ،ﺑﺎ ﺗﻌﺮﻳﻒ ﻳﻚ ﺧﺎﺻﻴﺖ ﺑﺮاي ﺗﻨﻈﻴﻢ ﻣﺘﻦ داﺧﻞ وﻳﺮاﻳﺸﮕﺮ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن دﻳﮕﺮي ﻛﻪ ﺑﺨﻮاﻫﻨﺪ از اﻳـﻦ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻨﺪ اﺟﺎزه ﻣﻲ دﻫﻴﻢ ﺻﺮﻓﻨﻈﺮ از اﻳﻨﻜﻪ ﭼﮕﻮﻧﻪ ﻣﺘﻦ داﺧﻞ ﺑﺮﻧﺎﻣﻪ ﺗﻐﻴﻴﺮ ﻣﻲ ﻛﻨﺪ ،از اﻳﻦ ﺧﺎﺻﻴﺖ اﺳﺘﻔﺎده ﻛـﺮده و ﻣﺘﻦ را ﺗﻐﻴﻴﺮ دﻫﻨﺪ .اﻟﺒﺘﻪ اﻳﻦ ﻧﻜﺘﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي ﻛﺎرﺑﺮد ﻛﻤﺘـﺮي دارد .اﻳـﻦ ﻧﻜﺘـﻪ ﺑﻴـﺸﺘﺮ در ﻃﺮاﺣـﻲ ﻛﻼﺳـﻬﺎ، ﻛﻨﺘﺮل ﻫﺎ و ﻳﺎ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎ ﺑﻪ ﻛﺎر ﻣﻲ رود ،ﻫﻤﺎﻧﻨﺪ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ ﻫﻢ اﻛﻨﻮن از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ﻣﺎﻧﻨـﺪ .Button در ﻓﺼﻮل ﺑﻌﺪي ﺑﺎ اﻳﻦ ﻣﻮارد ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. (2ﺣﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﺘﺪي اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﺧﺎﺻﻴﺖ ،ﻣﺘﻦ داﺧﻞ وﻳﺮاﻳﺸﮕﺮ را ﭘﺎك ﻛﻨﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺪ زﻳﺮ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: // Clears the txtEdit control )(public void ClearEditBox { // Set the EditText property ;EditText = String.Empty // Reset the font color ;txtEdit.ForeColor = Color.Black // Set the status bar text ;"!StatusText = "Text box cleared } (3ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ و ﻛﻨﺘﺮل TextBoxرا در ﻓﺮم اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺑﺎ دو ﺑﺎر ﻛﻠﻴﻚ ﺑﺮ روي اﻳﻦ ﻛﻨﺘـﺮل ،ﻣﺘـﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد TextChangedرا اﻳﺠﺎد ﻛﺮده و ﻛﺪ زﻳﺮ را در آن وارد ﻛﻨﻴﺪ: private void txtEdit_TextChanged(object sender, EventArgs )e { // Reset the status bar text ;"StatusText = "Ready }
٢٣٦
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اوﻟﻴﻦ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﺪ ،ﭘﺎك ﻛﺮدن TextBoxاﺳﺖ .در ﺑﺨﺶ ﺑﻌﺪي ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از ClearEditBoxدر ﻧﻮار اﺑﺰار ،ﻣﺘﻦ داﺧﻞ TextBoxرا ﭘﺎك ﻛﺮد. ﺗﻨﻬﺎ ﻛﺎري ﻛﻪ اﻳﻦ ﻣﺘﺪ اﻧﺠﺎم ﻣﻲ دﻫﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﺧﺎﺻﻴﺖ EditTextرا ﺑﺮاﺑﺮ ﺑﺎ ﻳﻚ رﺷﺘﻪ ﺧـﺎﻟﻲ ﻣﺎﻧﻨـﺪ ﻋـﻀﻮ Emptyاز ﻛﻼس Stringﻗﺮار دﻫﺪ .ﺳﭙﺲ ﺧﺎﺻﻴﺖ ForeColorاز TextBoxرا ﺑﺮاﺑﺮ ﺑﺎ رﻧﮓ ﺳﻴﺎه ﻗﺮار ﻣﻲ دﻫﺪ .اﻳﻦ ﺧﺎﺻﻴﺖ رﻧﮓ ﻣﺘﻦ ﻣﻮﺟﻮد در TextBoxرا ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ .در اﻧﺘﻬﺎ ﻧﻴﺰ ﻋﺒﺎرت Text box clearedرا در ﻧﻮار اﺑـﺰار ﻣـﻲ ﻧﻮﻳﺴﺪ ﺗﺎ ﻣﺸﺨﺺ ﻛﻨﺪ ﻛﻪ ﻣﺘﻦ داﺧﻞ وﻳﺮاﻳﺸﮕﺮ ﭘﺎك ﺷﺪه اﺳﺖ. // Clears the txtEdit control )(public void ClearEditBox { // Set the EditText property ;EditText = String.Empty // Reset the font color ;txtEdit.ForeColor = Color.Black // Set the status bar text ;"!StatusText = "Text box cleared } ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ EditTextﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﺗﺎ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎﻧﻲ ﻛﻪ ﺑﺨﻮاﻫﻨـﺪ از اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ اﺳـﺘﻔﺎده ﻛﻨﻨـﺪ، ﺑﺘﻮاﻧﻨﺪ ﺑﺪون ﺗﻮﺟﻪ ﺑﻪ اﻳﻨﻜﻪ ﺷﻤﺎ ﭼﮕﻮﻧﻪ ﻣﺘﻦ داﺧﻞ ﺑﺮﻧﺎﻣﻪ را ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻴﺪ اﻳﻦ ﻛﺎر را اﻧﺠﺎم دﻫﻨﺪ. // Gets or sets the text that you are editing public string EditText { get { ;return txtEdit.Text } set { ;txtEdit.Text = value } }
ﭘﺎﺳﺦ ﺑﻪ روﻳﺪادﻫﺎي ﻧﻮار اﺑﺰار: در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻧﻮﺷﺘﻦ ﻛﺪﻫﺎي ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻧﻮار اﺑـﺰار را ﺷـﺮوع ﺧـﻮاﻫﻴﻢ ﻛـﺮد .در ﻓـﺼﻞ ﻫﺸﺘﻢ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺎ اﻳﺠﺎد ﻣﻨﻮ در ﺑﺮﻧﺎﻣﻪ ﻫﺎ آﺷﻨﺎ ﺷﺪﻳﺪ ،ﻣﺘﻮﺟﻪ ﺧﻮاﻫﻴﺪ ﺷﺪ ﻛﻪ در ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻧﻮار اﺑﺰار ﻫﻤﺎن
٢٣٧
ﻛﺎري را اﻧﺠﺎم ﻣﻲ دﻫﻨﺪ ﻛﻪ ﻣﻨﻮ ﻫﺎ اﻧﺠﺎم ﻣﻲ دﻫﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻋﻤﻠﻜﺮد دﻛﻤﻪ Newدر ﻧﻮار اﺑـﺰار ﻣﻌـﺎدل ﻋﻤﻠﻜـﺮد ﮔﺰﻳﻨـﻪ Newدر ﻣﻨﻮي Fileﺧﻮاﻫﺪ ﺑﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺧﻮاﻫﻴﺪ ﺗﻮاﻧﺴﺖ ﺑﺮاي ﻫﺮ دوي اﻳﻦ ﻣﻮارد از ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪﻫﺎي ﻳﻜﺴﺎن اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﭘﺎﺳﺦ دادن ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ دﻛﻤﻪ ﻫﺎي ﻓﺮﻣﺎن ﻣﻮﺟﻮد در ﻧﻮار اﺑﺰار (1ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮوﻳﺪ و در ﻧﻮار اﺑﺰار ﺑﺎﻻي ﻓﺮم ،ﺑﺮ روي دﻛﻤﻪ ي ) tbrClearاوﻟﻴﻦ دﻛﻤﻪ ﻓﺮﻣﺎن در ﻧﻮار اﺑـﺰار( دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ روﻳﺪاد ﻣﺮﺑﻮط ﺑﻪ ﻣﺘﺪ Clickاﻳﻦ ﻛﻨﺘﺮل اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳـﻦ ﻣﺘـﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )private void tbrClear_Click(object sender, EventArgs e { // Clear the edit box ;)(ClearEditBox } (2ﺑﺮاي ﻛﻨﺘﺮل Buttonدوم ﺑﺎﻳﺪ زﻳﺮﺑﺮﻧﺎﻣﻪ اي ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ ﻣﺘﻦ داﺧﻞ TextBoxرا ﺑﻪ رﻧﮓ ﻗﺮﻣﺰ درآورد و اﻳﻦ ﻣﻮرد را در ﻧﻮار وﺿﻌﻴﺖ ﻧﻴﺰ اﻋﻼم ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﺘﺪ زﻳﺮ را در ﺑﺨﺶ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ وارد ﻛﻨﻴﺪ: )(public void RedText { // Make the text red ;txtEdit.ForeColor = Color.Red // Update the status bar text ;"StatusText = "The text is red } (3ﺣﺎل ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺸﺘﻪ ،دﻛﻤﻪ ي tbrRedرا در ﻧﻮار اﺑﺰار اﻧﺘﺨﺎب ﻛﺮده و ﺑﺮ روي آن دو ﺑـﺎر ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ. ﺳﭙﺲ در ﻣﺘﺪ اﻳﺠﺎد ﺷﺪه ﺑﺮاي روﻳﺪاد Clickاﻳﻦ ﻛﻨﺘﺮل ،ﻛﺪ زﻳﺮ را ﺑﻨﻮﻳﺴﻴﺪ: )private void tbrRed_Click(object sender, EventArgs e { // Make the text red ;)(RedText } ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﻣﺘﻨﻲ را در TextBoxوارد ﻛﻨﻴﺪ .ﺳﭙﺲ ﺑﺮ روي دﻛﻤﻪ Redدر ﻧﻮار اﺑﺰار ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣﺘﻦ وارد ﺷﺪه ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 13-6ﺑﻪ رﻧﮓ ﻗﺮﻣﺰ درﻣﻲ آﻳﺪ .اﮔﺮ ﺑﻌﺪ از آن ﻣﺘﻦ ،ﻣﺘﻨﻲ را ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ ﻛﻨﻴﺪ ،رﻧﮓ آن ﻧﻴﺰ ﻗﺮﻣﺰ ﺧﻮاﻫﺪ ﺑﻮد.
٢٣٨
ﺷﻜﻞ 13-6 (4ﺣﺎل ﺑﺮ روي دﻛﻤﻪ ي Clearﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣﺘﻦ وارد ﺷﺪه از ﺑﺮﻧﺎﻣﻪ ﭘﺎك ﻣﻲ ﺷﻮد و رﻧـﮓ ﻣـﺘﻦ ﻧﻴﺰ ﺑﻪ ﺣﺎﻟﺖ اوﻟﻴﻪ ﺑﺎزﻣﻲ ﮔﺮدد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﮔﺮ ﻣﺘﻨﻲ را در ﺑﺮﻧﺎﻣﻪ وارد ﻛﻨﻴﺪ رﻧﮓ آن ﺳﻴﺎه ﺧﻮاﻫﺪ ﺑﻮد. (5ﺑﺮﻧﺎﻣﻪ را ﻣﺘﻮﻗﻒ ﻛﻨﻴﺪ و ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﺑﺮﮔﺮدﻳﺪ .ﻛﺪ زﻳﺮ را ﺑﻪ اﻳﻦ ﻗﺴﻤﺖ اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ زﻳﺮﺑﺮﻧﺎﻣﻪ اي اﻳﺠﺎد ﺷﻮد ﻛﻪ رﻧﮓ ﻣﺘﻦ را ﺑﻪ آﺑﻲ ﺗﻐﻴﻴﺮ دﻫﺪ: )(public void BlueText { // Make the text blue ;txtEdit.ForeColor = Color.Blue // Update the status bar text ;"StatusText = "The text is blue } (6در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ،دﻛﻤﻪ ي tbrBlueرا از ﻧﻮار اﺑﺰار اﻧﺘﺨﺎب ﻛﺮده و ﺑﺮ روي آن دو ﺑـﺎر ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗـﺎ روﻳـﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷﻮد .ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )private void tbrBlue_Click(object sender, EventArgs e {
٢٣٩
// Make the text blue BlueText(); } ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺪ زﻳﺮ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ.( ﺣﺎل ﺑﻪ زﻳﺮ ﺑﺮﻧﺎﻣﻪ اي ﻧﻴﺎز دارﻳﻢ ﻛﻪ ﻣﺘﻦ داﺧﻞ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﺣﺮوف ﺑﺰرگ ﺗﺒﺪﻳﻞ ﻛﻨﺪ7 :ﻛﻨﻴﺪ public void UppercaseText() { // Make the text uppercase EditText = EditText.ToUpper(); // Update the status bar text StatusText = "The text is all uppercase"; } در ﻧﻮار اﺑﺰار دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳـﺪادtbrUpperCase ﺑﺮ روي دﻛﻤﻪ ي،( در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم8 : ﺳﭙﺲ ﻛﺪ زﻳﺮ را در آن ﻣﺘﺪ وارد ﻛﻨﻴﺪ.ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷﻮد private void tbrUpperCase_Click(object sender, EventArgs e) { // Make the text uppercase UppercaseText(); } :( ﺑﺮاي ﺗﻐﻴﻴﺮ ﻣﺘﻦ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺣﺮوف ﻛﻮﭼﻚ ﻧﻴﺰ ﺑﻪ ﻣﺘﺪ زﻳﺮ ﻧﻴﺎز دارﻳﻢ9 public void LowercaseText() { // Make the text lowercase EditText = EditText.ToLower(); // Update the status bar text StatusText = "The text is all lowercase"; } : را اﻳﺠﺎد ﻛﺮده و ﻛﺪ زﻳﺮ را در آن وارد ﻛﻨﻴﺪtbrLowerCase ( ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ دﻛﻤﻪ ي10 private void tbrLowerCase_Click(object sender, EventArgs e) { // Make the text lowercase LowercaseText(); }
٢٤٠
(11ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﻣﺘﻨﻲ را در آن وارد ﻛﻨﻴـﺪ ﻛـﻪ ﺗﺮﻛﻴﺒـﻲ از ﺣـﺮوف ﻛﻮﭼـﻚ و ﺑـﺰرگ ﺑﺎﺷـﺪ .ﺳـﭙﺲ ﺑـﺮ روي دﻛﻤـﻪ ي Upper Caseﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻣﺘﻦ وارد ﺷﺪه ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 14-6ﺑﻪ ﺣـﺮوف ﺑـﺰرگ ﺗﺒـﺪﻳﻞ ﻣـﻲ ﺷﻮد .ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴﺐ اﮔﺮ ﺑﺮ روي دﻛﻤﻪ Lower Caseﻛﻠﻴﻚ ﻛﻨﻴﺪ ،ﻣﺘﻦ ﺑﻪ ﺣﺮوف ﻛﻮﭼﻚ ﺗﺒﺪﻳﻞ ﻣﻲ ﺷـﻮد .ﻛﻠﻴـﻚ ﻛﺮدن ﺑﺮ روي دﻛﻤﻪ ﻫﺎي Redو Blueﻧﻴﺰ ﺑﺎﻋﺚ ﺗﻐﻴﻴﺮ رﻧﮓ ﺑﺮﻧﺎﻣـﻪ ﻣـﻲ ﺷـﻮد .در اﻧﺘﻬـﺎ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﺮ روي دﻛﻤـﻪ Clearﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﻦ ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ ﭘﺎك ﺷﺪه و ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺣﺎﻟﺖ اول ﺑﺮﮔﺮدد.
ﺷﻜﻞ 14-6
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اﻳﻦ ﺑﺨﺶ از اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﺴﻴﺎر ﺳﺎده ﺑـﻮد .در ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي ﻗﺒﻠـﻲ ﭼﮕـﻮﻧﮕﻲ اﻳﺠـﺎد ﻣﺘـﺪي ﺑـﺮاي روﻳـﺪاد Clickﻳـﻚ ﻛﻨﺘـﺮل Buttonرا ﻣﺸﺎﻫﺪه ﻛﺮده ﺑﻮدﻳﺪ ،اﻳﺠﺎد روﻳﺪاد Clickﺑﺮاي ﻛﻨﺘﺮﻟﻬﺎي Buttonﻣﻮﺟﻮد در ﻧﻮار اﺑﺰار ﻧﻴﺰ ﻛﺎﻣﻼً ﻣﺸﺎﺑﻪ ﻣﻮارد ﻗﺒﻠﻲ اﺳﺖ .اوﻟﻴﻦ ﻛﺎري ﻛﻪ اﻧﺠﺎم دادﻳﻢ ،اﻳﺠﺎد روﻳﺪاد Clickﺑﺮاي دﻛﻤﻪ ي Clearو اﺿﺎﻓﻪ ﻛﺮدن ﻛﺪي ﺑـﻮد ﻛـﻪ زﻳﺮﺑﺮﻧﺎﻣـﻪ ClearEditBoxرا ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﺪ: )private void tbrClear_Click(object sender, EventArgs e { // Clear the edit box ;)(ClearEditBox
٢٤١
} در ﻣﺮﺣﻠﻪ ﺑﻌﺪ ،زﻳﺮﺑﺮﻧﺎﻣﻪ اي ﻧﻮﺷﺘﻴﻢ ﻛﻪ رﻧﮓ ﻣﺘﻦ وارد ﺷﺪه در ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﻗﺮﻣﺰ ﺗﻐﻴﻴﺮ دﻫﺪ و اﻳﻦ ﺗﻐﻴﻴﺮ را در ﻧﻮار وﺿـﻌﻴﺖ ﻧﻴـﺰ اﻋـﻼم ﻛﻨﺪ .ﺑﺮاي ﺗﻐﻴﻴﺮ رﻧﮓ ﻣﺘﻦ وارد ﺷﺪه در TextBoxﺑﺎﻳﺪ از ﺧﺎﺻﻴﺖ ForeColorاﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺑﺮاي ﺗﻌﻴﻴﻦ رﻧﮓ ﻣﻮرد ﻧﻈﺮ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﻢ از ﺷﻤﺎرﻧﺪه ي Colorاﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺧﺎﺻﻴﺖ ForeColorﺑﻪ رﻧﮓ ﻗﺮﻣﺰ ﺑﺎﻗﻲ ﻣﻲ ﻣﺎﻧﺪ ﺗﺎ آن را ﻣﺠﺪداً ﺗﻐﻴﻴـﺮ دﻫﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﺗﺎ ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن Clearﻛﻠﻴﻚ ﻧﻜﻨﻴﻢ ،رﻧﮓ ﻣﺘﻦ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺻﻮرت ﻗﺮﻣﺰ ﺧﻮاﻫﺪ ﺑﻮد .ﻛﻠﻴـﻚ ﻛـﺮدن ﺑـﺮ روي دﻛﻤﻪ Clearﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻣﺘﻨﻲ ﻛﻪ از آن ﺑﻪ ﺑﻌﺪ در ﺑﺮﻧﺎﻣﻪ وارد ﻣﻲ ﺷﻮد .ﺑﻪ رﻧﮓ ﺳﻴﺎه ﻧﻤﺎﻳﺶ داده ﺷﻮد: )(public void RedText { // Make the text red ;txtEdit.ForeColor = Color.Red // Update the status bar text ;"StatusText = "The text is red } ﺑﻌﺪ از اﻳﻨﻜﻪ رﻧﮓ ﻣﺘﻦ ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﻗﺮﻣﺰ ﺗﻐﻴﻴﺮ دادﻳﻢ ،اﻳﻦ ﺗﻐﻴﻴﺮ در ﻧﻮار وﺿﻌﻴﺖ ﻧﻴﺰ ﻧﺸﺎن داده ﻣﻲ ﺷﻮد .ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻛـﺎرﺑﺮ ﻣﺘﻨﻲ را در ﺑﺮﻧﺎﻣﻪ ﺗﺎﻳﭗ ﻛﻨﺪ ،ﻣﺘﻦ ﻧﻮار وﺿﻌﻴﺖ ﻧﻴﺰ ﺑﻪ Readyﺗﻐﻴﻴﺮ ﻣﻲ ﻛﻨﺪ .زﻳﺮا در اﻳﻦ ﺣﺎﻟﺖ ﻣـﺘﻦ داﺧـﻞ TextBoxﺗﻐﻴﻴـﺮ ﻛﺮده و ﺑﻨﺎﺑﺮاﻳﻦ روﻳﺪاد TextChangedﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل TextBoxﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد .اﻳﻦ روﻳﺪاد ﻧﻴﺰ ﻣﺘﻦ ﻧﻮار وﺿـﻌﻴﺖ را ﺑﻪ Readyﺗﻐﻴﻴﺮ ﻣﻲ دﻫﺪ. اﮔﺮ ﻛﺎرﺑﺮ ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن Upper Caseدر ﻧﻮار اﺑﺰار ﻛﻠﻴﻚ ﻛﻨﺪ ،ﺑﺮﻧﺎﻣـﻪ ﻣﺘـﺪ UppercaseTextرا ﻓﺮاﺧـﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ ،اﻳﻦ ﻣﺘﺪ ﻧﻴﺰ ﺑﺎ اﺳﺘﻔﺎده از ﺗﺎﺑﻊ ToUpperﻣﺘﻦ ﻣﻮﺟﻮد در ﺧﺎﺻﻴﺖ EditTextرا ﺑﻪ ﺣﺮوف ﺑﺰرگ ﺗﺒﺪﻳﻞ ﻣﻲ ﻛﻨﺪ: // Make the text uppercase ;)(EditText = EditText.ToUpper ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴﺐ ﻛﻠﻴﻚ ﻛﺮدن ﺑﺮ روي دﻛﻤﻪ ي Lower Caseﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﻣﺘﻦ ﻣﻮﺟـﻮد در ﺑﺮﻧﺎﻣـﻪ ﺑـﻪ ﺣـﺮوف ﻛﻮﭼـﻚ ﺗﺒﺪﻳﻞ ﺷﻮد: // Make the text lowercase ;)(EditText = EditText.ToLower ﺗﻤﺎﻣﻲ اﻳﻦ زﻳﺮﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﻪ وﺳﻴﻠﻪ روﻳﺪاد ﻛﻠﻴﻚ ﻣﺮﺑﻮط ﺑﻪ دﻛﻤﻪ ي ﻣﺮﺑﻮط ﺑﻪ ﺧﻮدﺷﺎن در ﻧﻮار اﺑﺰار ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮﻧﺪ و ﺑﻌـﺪ از اﻳﻨﻜـﻪ ﺗﻐﻴﻴﺮ ﻣﻮرد ﻧﻈﺮ را در ﻣﺘﻦ اﻳﺠﺎد ﻛﺮدﻧﺪ ،ﻣﺘﻦ ﻣﻮﺟﻮد در ﻧﻮار وﺿﻌﻴﺖ را ﻧﻴﺰ ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻨﺪ ﻛﻪ ﻧﺸﺎن دﻫﻨﺪه ي ﺗﻐﻴﻴـﺮ اﻳﺠـﺎد ﺷﺪه در ﺑﺮﻧﺎﻣﻪ ﺑﺎﺷﺪ.
ﻣﻔﻬﻮم ﻓﻮﻛﻮس:
٢٤٢
اﮔﺮ ﻫﻨﮕﺎم اﺟﺮاي ﺑﺮﻧﺎﻣﻪ دﻗﺖ ﻛﻨﻴﺪ ،ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ در ﺣﺎل اﺟﺮا اﺳﺖ و ﺷﻤﺎ ﺑﻪ ﺑﺮﻧﺎﻣﻪ دﻳﮕﺮي ﻣﻲ روﻳـﺪ و ﺳﭙﺲ ﺑﻪ ﻫﻤﻴﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺎز ﻣﻴﮕﺮدﻳﺪ ،ﺗﻤﺎم ﻣﺘﻦ وارد ﺷﺪه در ﺟﻌﺒﻪ ﻣﺘﻨﻲ ﺑﻪ ﺻﻮرت اﻧﺘﺨﺎب ﺷﺪه در ﻣﻲ آﻳﺪ .اﻳﻦ ﻣـﻮرد ﺑـﻪ اﻳـﻦ دﻟﻴـﻞ اﺳﺖ ﻛﻪ ﻓﻮﻛﻮس 1ﺑﺮﻧﺎﻣﻪ ﺑﺮ روي ﻛﻨﺘﺮل TextBoxﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ .در اﺻﻄﻼح ،ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻳـﻚ ﻛﻨﺘـﺮل در ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ اﻧﺘﺨﺎب ﺷﻮد ،ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد ﻛﻪ ﻓﻮﻛﻮس ﺑﺮ روي آن ﻛﻨﺘﺮل ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ .ﺑﺮاي ﻣﺜﺎل ﺑﻪ ﺷﻜﻞ 15-6دﻗﺖ ﻛﻨﻴﺪ .در اﻳـﻦ ﺷـﻜﻞ دو ﻛﻨﺘﺮل Buttonﺑﺮ روي ﻓﺮم ﻗﺮار ﮔﺮﻓﺘﻪ اﻧﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ ﺑﻴﻨﻴﺪ در اﻳﻦ ﻓﺮم ﻳﻜﻲ از ﻛﻨﺘﺮل ﻫﺎ ﺑﻪ ﺻﻮرت اﻧﺘﺨـﺎب ﺷـﺪه اﺳـﺖ. ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﻛﻠﻴﺪ Enterﻓﺸﺎر داده ﺷﻮد ،ﻫﻤﺎﻧﻨﺪ اﻳﻦ ﺧﻮاﻫﺪ ﺑﻮد ﻛﻪ ﺑﺎ ﻣﺎوس ﺑﺮ روي دﻛﻤﻪ ي اﻧﺘﺨـﺎب ﺷـﺪه ﻛﻠﻴـﻚ ﺷـﻮد و ﻛـﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن اﺟﺮا ﻣﻲ ﺷﻮد.
ﺷﻜﻞ 15-6 اﮔﺮ ﭼﻨﺪﻳﻦ ﻛﻨﺘﺮل TextBoxدر ﻳﻚ ﻓﺮم ﻗﺮار داﺷﺘﻪ ﺑﺎﺷﻨﺪ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺘﻨﻲ را در ﺑﺮﻧﺎﻣﻪ ﺗﺎﻳﭗ ﻛﻨﻴﺪ ،ﻣﺘﻦ در ﻛﻨﺘﺮﻟﻲ ﻧﻮﺷﺘﻪ ﻣـﻲ ﺷﻮد ﻛﻪ داراي ﻓﻮﻛﻮس اﺳﺖ. ﺑﺮاي اﻳﻦ ﻛﻪ ﺑﻴﻦ ﻛﻨﺘﺮل ﻫﺎي ﻣﻮﺟﻮد در ﻳﻚ ﻓﺮم ﺟﺎ ﺑﻪ ﺟﺎ ﺷﻮﻳﺪ و ﻛﻨﺘﺮل دﻳﮕﺮي را ﺑﻪ ﺻﻮرت اﻧﺘﺨﺎب ﺷﺪه در آورﻳﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻛﻠﻴﺪ Tabدر ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل در ﻓﺮم ﻧﻤﺎﻳﺶ داده ﺷﺪه در ﺷﻜﻞ 15-6اﮔﺮ ﻛﺎرﺑﺮ ﻛﻠﻴﺪ Tabرا ﻓﺸﺎر دﻫﺪ ،دﻛﻤـﻪ ﻓﺮﻣـﺎن " "I do notﺑﻪ ﺻﻮرت اﻧﺘﺨﺎب ﺷﺪه در ﻣﻲ آﻳﺪ .ﺑﺎ ﻓﺸﺎر ﻣﺠﺪد ﻛﻠﻴـﺪ Tabﻓﻮﻛـﻮس ﺑـﻪ دﻛﻤـﻪ ﻓﺮﻣـﺎن "I Have " Focusﺑﺮﻣﻲ ﮔﺮدد. اﻳﻦ ﻛﻪ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﻓﺸﺎر ﻛﻠﻴﺪ Tabﻓﻮﻛﻮس ﭼﮕﻮﻧﻪ ﺑﻴﻦ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻓﺮم ﺟﺎ ﺑﻪ ﺟﺎ ﺷﻮد ﺑﻪ ﺻﻮرت اﺗﻔﺎﻗﻲ اﻧﺘﺨﺎب ﻧﻤـﻲ ﺷﻮد .ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﻃﺮاﺣﻲ ﻓﺮم ،ﻛﻨﺘﺮﻟﻲ را ﺑﺮ روي ﻓﺮم ﻗﺮار ﻣﻲ دﻫﻴﺪ ﻋﺪدي ﺑﻪ ﺧﺎﺻﻴﺖ TabIndexآن ﻛﻨﺘﺮل ﻧﺴﺒﺖ داده ﻣﻲ ﺷﻮد .ﺑﺮاي اوﻟﻴﻦ ﻛﻨﺘﺮل اﻳﻦ ﻋﺪد ﺻﻔﺮ ﺧﻮاﻫﺪ ﺑﻮد ،ﺑﺮاي ﻛﻨﺘﺮل دوم ﻳﻚ ،ﺑﺮاي ﻛﻨﺘﺮل ﺳﻮم ﻋﺪد دو و … .ﺑﻨـﺎﺑﺮاﻳﻦ اﮔـﺮ ﻫﻨﮕـﺎم اﺟـﺮاي ﺑﺮﻧﺎﻣﻪ ﻛﻠﻴﺪ Tabرا ﻓﺸﺎر دﻫﻴﺪ ،ﻓﻮﻛﻮس ﺑﻪ ﺗﺮﺗﻴﺐ ﻗﺮار ﮔﺮﻓﺘﻦ ﻛﻨﺘﺮل ﻫﺎ ﺑﺮ روي ﻓﺮم ﺑﻴﻦ آﻧﻬﺎ ﺟﺎ ﺑﻪ ﺟﺎ ﻣﻲ ﺷﻮد .اﻟﺒﺘﻪ ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﻓﺮم ﻣﻲ ﺗﻮاﻧﻴﺪ ﻋﺪد ﻣﻮﺟﻮد در ﺧﺎﺻﻴﺖ TabIndexرا ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ ﻓﻮﻛﻮس ﺑﻪ ﺷﻜﻠﻲ ﻛﻪ ﺗﻤﺎﻳﻞ دارﻳﺪ ﺑـﻴﻦ ﻛﻨﺘـﺮل ﻫـﺎ ﺣﺮﻛـﺖ ﻛﻨﺪ. ﻧﻜﺘﻪ :ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻛﻨﺘﺮل ﻟﻴﺒﻞ داراي ﺧﺎﺻﻴﺖ TabIndexاﺳﺖ ،اﻣﺎ ﻫﻨﮕﺎم اﺟﺮاي ﺑﺮﻧﺎﻣﻪ اﻳﻦ ﻛﻨﺘﺮل ﻧﻤﻲ ﺗﻮاﻧﺪ داراي ﻓﻮﻛﻮس ﺑﺎﺷﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻓﻮﻛﻮس ﺑﻪ ﻛﻨﺘﺮل ﺑﻌﺪي ﻣﺎﻧﻨﺪ TextBoxو ﻳﺎ Buttonﻣﻨﺘﻘﻞ ﻣﻲ ﺷﻮد. ﺗﻐﻴﻴﺮ ﻋﺪد ﻣﻮﺟﻮد در ﺧﺎﺻﻴﺖ TabIndexﺑﺮاي ﺗﻨﻈﻴﻢ ﺗﻐﻴﻴﺮ ﻓﻮﻛﻮس ﺑﻴﻦ ﻛﻨﺘﺮل ﻫﺎ ﻛﺎر ﻣﺸﻜﻠﻲ اﺳـﺖ .وﻳـﮋوال اﺳـﺘﻮدﻳﻮ 2005 داراي اﺑﺰاري اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ آن ﻣﻲ ﺗﻮان اﻳﻦ ﻛﺎر را ﺑﺴﻴﺎر راﺣﺖ ﺗﺮ اﻧﺠـﺎم داد .ﮔﺰﻳﻨـﻪ View Tab Orderرا در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻧﺘﺨﺎب ﻛﻨﻴﺪ ،ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻓﺮم ﺷﻤﺎ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 16-6ﺧﻮاﻫﺪ ﺷﺪ. اﻋﺪادي ﻛﻪ در ﻛﻨﺎر ﻛﻨﺘﺮل ﻫﺎ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ ،ﺗﺮﺗﻴﺐ ﺗﻐﻴﻴﺮ ﻓﻮﻛﻮس ﺑﻴﻦ ﻛﻨﺘﺮل ﻫﺎ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻨﺪ .اﻳﻦ اﻋﺪاد ﺑﻪ ﺗﺮﺗﻴﺐ ﻗـﺮار ﮔﺮﻓﺘﻦ ﻛﻨﺘﺮل ﻫﺎ ﺑﺮ روي ﻓﺮم ﺗﻨﻈﻴﻢ ﺷﺪه اﻧﺪ .ﺑﺮاي اﻳﻨﻜﻪ اﻳﻦ ﺗﺮﺗﻴﺐ را ﺧﻮدﺗﺎن ﻣﺸﺨﺺ ﻛﻨﻴﺪ ،ﺑﺮ روي اﻳﻦ اﻋﺪاد ﺑﻪ ﺗﺮﺗﻴﺒـﻲ ﻛـﻪ ﻣـﻲ
Focus
1
٢٤٣
ﺧﻮاﻫﻴﺪ ﻓﻮﻛﻮس ﺗﻐﻴﻴﺮ ﻛﻨﺪ ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .ﺑﻌـﺪ از ﻣـﺸﺨﺺ ﻛـﺮدن ﺗﺮﺗﻴـﺐ ﺗﻐﻴﻴـﺮ ﻓﻮﻛـﻮس ﻣﺠـﺪدا ﮔﺰﻳﻨـﻪ View Tab Orderرا از ﻧﻮار ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ اﻋﺪاد ﻧﻤﺎﻳﺶ داده ﺷﺪه از ﻛﻨﺎر ﻛﻨﺘﺮل ﻫﺎ ﺣﺬف ﺷﻮﻧﺪ.
اﺳﺘﻔﺎده از ﭼﻨﺪﻳﻦ ﻓﺮم در ﺑﺮﻧﺎﻣﻪ: ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي داراي دو ﻧﻮع ﭘﻨﺠﺮه ﻫﺴﺘﻨﺪ :ﭘﻨﺠﺮه ﻫﺎي ﻣﻌﻤﻮﻟﻲ و ﻛﺎدرﻫﺎي ﻣﺤﺎوره اي .ﻳﻚ ﭘﻨﺠﺮه ﻣﻌﻤﻮﻟﻲ ،ﺻﻔﺤﻪ اﺻﻠﻲ راﺑﻂ ﻛﺎرﺑﺮ را در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .ﺑﺮاي ﻣﺜﺎل در ﺑﺮﻧﺎﻣﻪ ،Wordﻛﺎرﺑﺮ از ﻳﻚ ﭘﻨﺠﺮه ﻋﺎدي ﻛﻪ ﺻﻔﺤﻪ اﺻﻠﻲ ﺑﺮﻧﺎﻣـﻪ را ﺗـﺸﻜﻴﻞ ﻣﻲ دﻫﺪ ﺑﺮاي وارد ﻛﺮدن و ﻳﺎ وﻳﺮاﻳﺶ ﻣﺘﻦ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ.
ﺷﻜﻞ 16-6 ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﻋﻤﻞ ﺧﺎﺻﻲ را در ﺑﺮﻧﺎﻣﻪ اﻧﺠﺎم دﻫﻴﺪ ،ﻳﻚ ﻛﺎدر ﻣﺤﺎوره اي ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .اﻳﻦ ﻧﻮع از ﭘﻨﺠﺮه ﻫﺎ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﺑﺴﺘﻪ ﻧﺸﺪه اﻧﺪ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎره ﻧﻤﻲ دﻫﻨﺪ ﻛﻪ ﺑﻪ ﺻﻔﺤﻪ اﺻﻠﻲ ﺑﺮﻧﺎﻣـﻪ دﺳﺘﺮﺳـﻲ ﭘﻴـﺪا ﻛﻨـﺪ .ﺑـﺮاي ﻣﺜـﺎل اﮔـﺮ در ﺑﺮﻧﺎﻣـﻪ Wordﮔﺰﻳﻨﻪ Printرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ ،ﻳﻚ ﻛﺎدر ﻣﺤﺎوره اي ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن ﺑـﺮ روي دﻛﻤـﻪ ﻫﺎي OKو ﻳﺎ Cancelﻛﺎدر را ﻧﺒﻨﺪﻳﺪ ،ﻧﺨﻮاﻫﻴﺪ ﺗﻮاﻧﺴﺖ ﻣﺘﻦ داﺧﻞ ﺳﻨﺪ Wordرا ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﻛﺎدرﻫﺎﻳﻲ ﻛﻪ ﺑﻪ اﻳﻦ ﺻـﻮرت در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ ،ﺑﻪ ﻓﺮﻣﻬﺎي ﻣﻘﻴﺪ 1و ﻳﺎ ﻓﺮﻣﻬﺎي ﻣﻮدال ﻣﻌﺮوف ﻫﺴﺘﻨﺪ.
Modal Forms
1
٢٤٤
ﻛﺎدرﻫﺎي ﻣﺤﺎوره اي ﻫﻤﺎﻧﻨﺪ ﻛﺎدر ﻣﺮﺑﻮط ﺑﻪ ﭼﺎپ و ﻳﺎ ﻛﺎدرﻫﺎي ﻣﺸﺎﺑﻪ ﺑﺎ آن ،در ﻓﺼﻞ ﻫﻔﺘﻢ ﺑﺮرﺳﻲ ﺧﻮاﻫﻨﺪ ﺷﺪ .در اﻳﻦ ﺑﺨﺶ ﺑﺮ روي اﺿﺎﻓﻪ ﻛﺮدن ﻓﺮﻣﻬﺎي ﻋﺎدي ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﺗﻤﺮﻛﺰ ﺧﻮاﻫﻴﻢ ﻛﺮد و در ﺗﻤﺮﻳﻦ ﺑﻌﺪ ،ﻳﻚ ﻓﺮم ﺳﺎده را ﺑﻪ ﺻﻮرت ﻣﻮدال ﻧﻤﺎﻳﺶ ﺧﻮاﻫﻴﻢ داد.
ﻓﺮم :About ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ داراي ﻳﻚ ﻛﺎدر ﻣﺤﺎوره اي Aboutﻫﺴﺘﻨﺪ ﻛﻪ ﻧﺎم ﺑﺮﻧﺎﻣﻪ و ﻫﻤﭽﻨﻴﻦ ﺣﻘﻮق ﻣﻮﻟﻒ آن را ﺷﺮح ﻣﻲ دﻫـﺪ .در ﺑﺮﻧﺎﻣـﻪ ﻗﺒﻠﻲ ﻳﻚ ﻛﻨﺘﺮل Buttonﺑﺮاي اﻳﻦ ﻗﺴﻤﺖ در ﻧﻮار اﺑﺰار ﻗﺮار دادﻳﻢ .ﺣﺎل ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ آن را اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﻓﺮم About (1ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻓﺮم ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﭘﻨﺠﺮه Solution Explorerاﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛـﺎر در اﻳﻦ ﭘﻨﺠﺮه ﺑﺮ روي ﻧﺎم ﭘﺮوژه ي Text Editorﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ و از ﻣﻨﻮي ﺑـﺎز ﺷـﺪه ﮔﺰﻳﻨـﻪ Add Windows Formsرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .در ﭘﻨﺠـﺮه Add New Item – Text Editorﻫﻤﺎﻧﻨـﺪ ﺷﻜﻞ 17-6در ﻗﺴﻤﺖ Templatesﮔﺰﻳﻨﻪ About Boxرا اﻧﺘﺨـﺎب ﻛـﺮده و ﺳـﭙﺲ در ﻛـﺎدر Nameﻧـﺎم About.csرا وارد ﻛﻨﻴﺪ .در اﻧﺘﻬﺎ ﺑﺮ روي دﻛﻤﻪ Addﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻓﺮم ﺟﺪﻳﺪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﻮد.
ﺷﻜﻞ 17-6 (2ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮاي ﭘﻨﺠﺮه Aboutﻧﻤﺎﻳﺶ داده ﺷﻮد ،ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺗﻤﺎم ﻗـﺴﻤﺘﻬﺎﻳﻲ ﻛـﻪ در ﻳﻚ ﻛﺎدر Aboutﻣﻌﻤﻮﻟﻲ وﺟﻮد دارد ،در اﻳﻦ ﻓﺮم ﻧﻴﺰ ﻗﺮار داده ﺷﺪه اﺳﺖ .ﺑﺮاي ﻣﺜﺎل ﻓﺮم ،داراي ﻗـﺴﻤﺘﻬﺎﻳﻲ ﺑـﺮاي ﻗـﺮار دادن ﻧﺎم ﺑﺮﻧﺎﻣﻪ ،ﻧﺴﺨﻪ ي ﺑﺮﻧﺎﻣﻪ ،اﻃﻼﻋﺎت ﺣﻘﻮق ﻣﻮﻟﻒ و ...اﺳﺖ.
٢٤٥
(3ﺑﺮ روي ﻓﺮم ﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ و ﮔﺰﻳﻨﻪ View Codeرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺗﺎﺑﻊ ﺳﺎزﻧﺪه ي ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس اﻳﻦ ﻓﺮم داراي ﭼﻨﺪﻳﻦ ﺧﻂ ﻛﺪ اﺳﺖ ﻛﻪ ﻫﻨﮕﺎم ﻧﻤﺎﻳﺶ داده ﺷﺪن ﻓﺮم ،اﻃﻼﻋﺎت ﺑﺮﻧﺎﻣﻪ را در ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟـﻮد در ﻓﺮم ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻨﺪ .در اﺑﺘﺪاي ﻛﺪﻫﺎ ﺗﻮﺿﻴﺤﺎﺗﻲ ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ ﺗﺎ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ اﻃﻼع دﻫﺪ ﻛﻪ ﺑﺮاي ﻧﻤـﺎﻳﺶ درﺳـﺖ اﻃﻼﻋﺎت در ﻓﺮم ،Aboutﺑﺎﻳﺪ اﻃﻼﻋﺎت ﺑﺮﻧﺎﻣـﻪ را در ﻗـﺴﻤﺖ Assembly Informationﺑﺮﻧﺎﻣـﻪ وارد ﻛﻨﺪ. (4ﺑـﺮ روي ﻧـﺎم ﭘـﺮوژه در ﭘﻨﺠـﺮه Solution Explorerﻛﻠﻴـﻚ راﺳـﺖ ﻛـﺮده و از ﻣﻨـﻮي ﺑـﺎز ﺷـﺪه ﮔﺰﻳﻨـﻪ Propertiesرا اﻧﺘﺨﺎب ﻛﻨﻴـﺪ .ﺻـﻔﺤﻪ ي Applicationاز ﭘﻨﺠـﺮه Propertiesﻣﺮﺑـﻮط ﺑـﻪ ﭘﺮوژه ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .در اﻳﻦ ﺻﻔﺤﻪ ﺑﺮ روي دﻛﻤﻪ ي Assembly Informationﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﻛﺎدر Assembly Informationﻧﻤﺎﻳﺶ داده ﺷﻮد .اﻃﻼﻋﺎت ﻧﻮﺷﺘﻪ ﺷﺪه در ﻛﺎدرﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ ﭘﻨﺠﺮه را ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 18-6ﺗﻐﻴﻴﺮ دﻫﻴﺪ و ﺳﭙﺲ ﺑﺮ روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﭘﻨﺠﺮه ﺑﺴﺘﻪ ﺷﻮد.
ﺷﻜﻞ 18-6 (5ﺣﺎل در ﻓﺮم اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ )ﻓﺮم (TextEditor.csﺑﻪ زﻳﺮﺑﺮﻧﺎﻣﻪ اي ﻧﻴﺎز دارﻳﺪ ﻛﻪ ﻛﺎدر Aboutرا ﻧﻤﺎﻳﺶ دﻫﺪ. ﺑﺮاي اﻳﻦ ﻛﺎر ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻓﺮم TextEditorرا ﺑﺎز ﻛﺮده و ﻛﺪ زﻳﺮ را در آن وارد ﻛﻨﻴﺪ: )(public void ShowAboutBox { // Display the About dialog box ;)(About objAbout = new About ;)objAbout.ShowDialog(this }
٢٤٦
(6در اﻧﺘﻬﺎ ﺑﺎﻳﺪ ﻛﺪي ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آن ﻫﻨﮕﺎم ﻛﻠﻴﻚ ﺷﺪن ﺑﺮ روي دﻛﻤﻪ Aboutدر ﻧﻮار اﺑـﺰار ،ﻓـﺮم About ﻧﻤــﺎﻳﺶ داده ﺷــﻮد .ﺑــﺮاي اﻳــﻦ ﻛــﺎر در ﻗــﺴﻤﺖ ﻃﺮاﺣــﻲ ﻓــﺮم ﻣﺮﺑــﻮط ﺑــﻪ TextEditorﺑــﺮ روي ﻛﻨﺘــﺮل tbrHelpAboutدر ﻧﻮار اﺑﺰار دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳـﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: )private void tbrHelpAbout_Click(object sender, EventArgs e { // Display the about dialog box ;)(ShowAboutBox } (7ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ ي Aboutدر ﻧﻮار اﺑﺰار ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻛﺎدري ﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ -6 19ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
ﺷﻜﻞ 19-6
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در زﺑﺎن C#ﻫﺮ ﻓﺮم ،از ﻳﻚ ﻛﻼس ﻫﻢ ﻧﺎم ﺑﺎ ﻓﺮم ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ .ﺑﺮاي ﻧﻤﺎﻳﺶ ﻓﺮم اﺑﺘﺪا ﺑﺎﻳﺪ ﻳﻚ ﺷﻴﺊ از آن ﻛﻼس اﻳﺠـﺎد ﻛـﺮد. ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻣﺘﺪ ShowAboutBoxﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،اﺑﺘﺪا از ﻛﻼس ﻣﺮﺑﻮط ﺑﻪ ﻓﺮم Aboutﻳـﻚ ﺷـﻴﺊ ﺟﺪﻳـﺪ اﻳﺠـﺎد ﻛﺮده اﻳﻢ و ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ShowDialogاز ﺷﻴﺊ اﻳﺠﺎد ﺷﺪه ،ﻓﺮم را ﺑﻪ ﺻـﻮرت ﻣـﻮدال در ﺻـﻔﺤﻪ ﻧﻤـﺎﻳﺶ داده اﻳـﻢ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻋﺒﺎرت thisرا ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻣﻲ ﻓﺮﺳﺘﻴﺪ ،در ﺣﻘﻴﻘﺖ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻛﺎدر ﻣﺤﺎوره اي About
٢٤٧
ﻣﺮﺑﻮط ﺑﻪ ﻓﺮم TextEditorاﺳﺖ و ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ اﻳﻦ ﻛﺎدر ﺑﺴﺘﻪ ﻧﺸﺪه اﺳﺖ ﻛﺎرﺑﺮ ﻧﻤﻲ ﺗﻮاﻧـﺪ ﺑـﻪ ﻓـﺮم TextEditor دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ. )(public void ShowAboutBox { // Display the About dialog box ;)(About objAbout = new About ;)objAbout.ShowDialog(this } ﺑﺮاي ﻧﻤﺎﻳﺶ ﻓﺮم Aboutﺑﺎﻳﺪ در روﻳـﺪاد Clickﻣﺮﺑـﻮط ﺑـﻪ ﻛﻨﺘـﺮل tbrHelpAboutزﻳـﺮ ﺑﺮﻧﺎﻣـﻪ ﻧﻮﺷـﺘﻪ ﺷـﺪه را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ: )private void tbrHelpAbout_Click(object sender, EventArgs e { // Display the about dialog box ;)(ShowAboutBox } در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻓﺮﻣﻬﺎي از ﭘﻴﺶ ﻃﺮاﺣﻲ ﺷﺪه زﻳﺎدي وﺟﻮد دارد ﻛﻪ ﺑﺎﻋﺚ ﺗﺴﺮﻳﻊ در ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻲ ﺷﻮد .ﻳﻜﻲ از اﻳﻦ ﻓﺮم ﻫـﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﭘﻨﺠﺮه Aboutاﺳﺖ ﻛﻪ ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن آن ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻛـﺎدر Aboutرا در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ دﻫﻴﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺻﻔﺤﻪ Aboutﺑﺨﻮاﻫﺪ در ﺣﺎﻓﻈﻪ ﻗﺮار ﺑﮕﻴﺮد ،ﺗﺎﺑﻊ ﺳﺎزﻧﺪه آن اﺟﺮا ﻣﻲ ﺷﻮد و اﻳﻦ ﺗﺎﺑﻊ ﻧﻴﺰ ﺑـﻪ ﻃـﻮر اﺗﻮﻣﺎﺗﻴـﻚ ﺣـﺎوي ﻛﺪي اﺳﺖ ﻛﻪ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﻓﺮم Aboutرا ﺑﺮ اﺳﺎس اﻃﻼﻋﺎت ﺑﺮﻧﺎﻣﻪ ﺗﻜﻤﻴﻞ ﻣﻲ ﻛﻨﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ ﮔﻔﺘﻢ 1ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﭼﻪ ﺗﻮﻟﻴﺪ ﻛﻨﻨﺪه ي ﻳﻚ ﻓﺎﻳﻞ اﺟﺮاﻳﻲ ) (EXEﺑﺎﺷﺪ ،ﻣﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ﻫـﺎﻳﻲ ﻛـﻪ ﺗـﺎﻛﻨﻮن اﻳﺠﺎد ﻛﺮده اﻳﻢ و ﭼﻪ ﻣﺤﺘﻮي ﻛﻼﺳﻬﺎ و ﺗﻮاﺑﻌﻲ ﺑﺮاي اﺳﺘﻔﺎده در ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕﺮ ﺑﺎﺷﺪ ﻣﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ در ﻓﺼﻮل 12و 13اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ،ﺑﻌﺪ از ﻛﺎﻣﭙﺎﻳﻞ در ﻓﺎﻳﻠﻬﺎﻳﻲ ﻛﻪ ﺑﻪ اﺳﻤﺒﻠﻲ ﻣﻌﺮوف ﻫﺴﺘﻨﺪ ذﺧﻴﺮه ﻣﻲ ﺷـﻮد .ﻫﻤﭽﻨـﻴﻦ ذﻛـﺮ ﺷـﺪ ﻛـﻪ اﻳـﻦ ﻓﺎﻳﻠﻬـﺎ ﺣـﺎوي اﻃﻼﻋﺎﺗﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﻪ اﻃﻼﻋﺎت ﻣﺘﺎ ﻣﻌﺮوف اﺳﺖ و ﺷﺎﻣﻞ ﻣﺸﺨﺼﺎت اﺳﻤﺒﻠﻲ ﻣﻲ ﺷﻮد .ﺣﺎل اﮔﺮ ﺑﻪ ﻛﺪﻫﺎي ﻣﻮﺟﻮد در ﺗﺎﺑﻊ ﺳﺎزﻧﺪه اﻳﻦ ﻓــﺮم ﻧﮕـــﺎﻫﻲ ﺑﻴﻨﺪازﻳــﺪ ،ﻣﺘﻮﺟـــﻪ ﻣــﻲ ﺷـــﻮﻳﺪ ﻛــﻪ اﻳـــﻦ ﻛــﺪﻫﺎ ﺑـــﺎ اﺳــﺘﻔﺎده از ﻛـــﻼس Assemblyدر ﻓــﻀﺎي ﻧـــﺎم System.Reflectionﺑﻪ اﻃﻼﻋـﺎت ﻣﺘـﺎي اﺳـﻤﺒﻠﻲ ﺑﺮﻧﺎﻣـﻪ دﺳﺘﺮﺳـﻲ ﭘﻴـﺪا ﻛـﺮده و ﻣﺸﺨـﺼﺎت ﻻزم ﺑـﺮاي ﺻـﻔﺤﻪ Aboutرا از آﻧﻬﺎ اﺳﺘﺨﺮاج ﻣﻲ ﻛﻨﻨﺪ .ﺳﭙﺲ اﻳﻦ اﻃﻼﻋﺎت را در ﻗﺴﻤﺘﻬﺎي ﻣﻨﺎﺳﺐ در ﺻﻔﺤﻪ Aboutﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻨﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻓﺮم ﻫﺎ در وﻳﮋوال اﺳﺘﻮدﻳﻮ ،ﻣﻲ ﺗﻮان ﺑﻪ راﺣﺘﻲ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﺑﺮﻧﺎﻣﻪ را ﺗﻜﻤﻴﻞ ﻛﺮد.
ﻧﺘﻴﺠﻪ:
1رﺟﻮع ﻛﻨﻴﺪ ﺑﻪ ﻓﺼﻞ دوم "ﭼﺎرﭼﻮب .NETو ارﺗﺒﺎط آن ﺑﺎ "C#
٢٤٨
در اﻳﻦ ﻓﺼﻞ ﺑﻪ ﻣﻌﺮﻓﻲ وﻳﮋﮔﻴﻬﺎي ﭘﻴﺸﺮﻓﺘﻪ ﺗﺮ ﻓﺮم ﻫﺎ در ﺑﺮﻧﺎﻣﻪ و ﻧﻴﺰ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در وﻳﮋوال اﺳـﺘﻮدﻳﻮ ﭘـﺮداﺧﺘﻴﻢ .ﻃﺒﻴﻌـﺖ روﻳـﺪاد ﮔــﺮاي وﻳﻨــﺪوز را ﺑﺮرﺳــﻲ ﻛــﺮدﻳﻢ و ﺑــﺎ ﺳــﻪ روﻳــﺪاد ﭘــﺮ ﻛــﺎرﺑﺮد ﻛﻨﺘــﺮل دﻛﻤــﻪ ﻓﺮﻣــﺎن ) MouseEnter ،Clickو (MouseLeaveآﺷﻨﺎ ﺷﺪﻳﻢ. در اﺑﺘﺪا ﺑﺮﻧﺎﻣﻪ ﺳﺎده اي اﻳﺠﺎد ﻛﺮدﻳﺪ ﻛﻪ ﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣﻲ داد ﻣﺘﻨﻲ را وارد ﻛﻨﻴﺪ و ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ ﺗﻌﺪاد ﻛﻠﻤـﺎت و ﻳـﺎ ﺗﻌـﺪاد ﻛﺎراﻛﺘﺮﻫـﺎي ﻣﺘﻦ را ﻧﻤﺎﻳﺶ ﻣﻲ داد. ﺳﭙﺲ ﺗﻮﺟﻪ ﺧﻮد را ﺑﺮ روي ﺑﺮﻧﺎﻣﻪ ي ﭘﻴﭽﻴﺪه ﺗﺮي ﻣﺘﻤﺮﻛﺰ ﻛﺮدﻳﻢ و ﺑﺮﻧﺎﻣﻪ اي ﻃﺮاﺣﻲ ﻛﺮدﻳﻢ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ آن ﻣﻲ ﺗﻮاﻧﺴﺘﻴﺪ رﻧﮓ و ﻳـﺎ ﺣﺎﻟﺖ ﺣﺮوف وارد ﺷﺪه در آن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ .در اﻳﻦ ﭘﺮوژه ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از ﻧـﻮار اﺑـﺰار و ﻧـﻮار وﺿـﻌﻴﺖ، ﻗﺎﺑﻠﻴﺘﻬﺎي ﺑﺮﻧﺎﻣﻪ را اﻓﺰاﻳﺶ داد .ﻫﻤﭽﻨﻴﻦ ﻓﺮم دﻳﮕﺮي اﺿﺎﻓﻪ ﻛﺮدﻳﻢ ﺗﺎ اﻃﻼﻋﺎت ﻣﺨﺘﺼﺮي از ﻗﺒﻴﻞ ﻧﺎم ﺑﺮﻧﺎﻣﻪ ،ﻧـﺴﺨﻪ ﺑﺮﻧﺎﻣـﻪ و ﺣﻘـﻮق ﻣﻮﻟﻒ آن را ﻧﻤﺎﻳﺶ دﻫﺪ. در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ:
ﻧﻮﺷﺘﻦ ﻛﺪي ﻛﻪ ﺑﻪ روﻳﺪادﻫﺎي ﻣﺨﺘﻠﻒ ﻳﻚ ﻛﻨﺘﺮل ﭘﺎﺳﺦ دﻫﺪ. ﺧﺎﺻﻴﺘﻬﺎي ﻳﻚ ﻛﻨﺘﺮل را ﺑﺮاي ﺗﻨﻈﻴﻢ ﻇﺎﻫﺮ آن ﻛﻨﺘﺮل ﺗﻐﻴﻴﺮ دﻫﻴﺪ. از ﻛﻨﺘﺮﻟﻬﺎي ToolStripو StatusStripﺑﺮاي ﻧﻤﺎﻳﺶ ﻧﻮار اﺑﺰار و ﻧﻮار وﺿﻌﻴﺖ در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. در ﺑﺮﻧﺎﻣﻪ ﺧﻮد از ﺑﻴﺶ از ﻳﻚ ﻓﺮم اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
ﺗﻤﺮﻳﻦ:
ﺗﻤﺮﻳﻦ :1 ﻳﻚ ﺑﺮﻧﺎﻣﻪ وﻳﻨﺪوزي اﻳﺠﺎد ﻛﻨﻴﺪ و ﺑﻪ وﺳﻴﻠﻪ ﺟﻌﺒـﻪ اﺑـﺰار ،دو دﻛﻤـﻪ ﻓﺮﻣـﺎن ﺑـﺮ روي ﻓـﺮم ﺑﺮﻧﺎﻣـﻪ ﻗـﺮار دﻫﻴـﺪ .ﻣﺘـﺪي ﺑـﺮاي روﻳـﺪاد MouseUpدﻛﻤﻪ ﻓﺮﻣﺎن اول ﺑﻪ وﺟﻮد آورﻳﺪ و در آن ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ دﻫﻴﺪ .ﻫﻤﻴﻦ ﻛﺎر را ﺑﺮاي روﻳـﺪاد LostFocus دﻛﻤﻪ ﻓﺮﻣﺎن دوم ﺗﻜﺮار ﻛﻨﻴﺪ .ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ روﻳﺪادﻫﺎ ﭼﻪ ﻫﻨﮕﺎم رخ ﻣﻲ دﻫﻨﺪ.
ﺗﻤﺮﻳﻦ :2 ﻳﻚ ﺑﺮﻧﺎﻣﻪ وﻳﻨﺪوزي اﻳﺠﺎد ﻛﻨﻴﺪ و ﻳﻚ ﻧﻮار اﺑﺰار و ﻳﻚ ﻧﻮار وﺿﻌﻴﺖ ﺑﺮ روي ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻗﺮار دﻫﻴﺪ .در ﻗﺴﻤﺖ ﭘﺎﻳﻴﻦ ﻃﺮاﺣـﻲ ﻓـﺮم ﺑـﺮ روي ﻛﻨﺘﺮل ToolStripﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﮔﺰﻳﻨﻪ Insert Standard Itemsرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ دﻛﻤـﻪ ﻫﺎي ﻓﺮﻣﺎن اﺳﺘﺎﻧﺪارد ﻧﻮار اﺑﺰار ﺑﻪ آن اﺿﺎﻓﻪ ﺷﻮﻧﺪ .ﺑﺮاي روﻳﺪاد ﻛﻠﻴﻚ ﻫﺮ ﻛﺪام از اﻳﻦ دﻛﻤﻪ ﻫﺎي ﻓﺮﻣﺎن ﻛﺪي را اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ ﻛـﻪ ﺑـﺎ ﻧﻤﺎﻳﺶ ﭘﻴﻐﺎﻣﻲ در ﻧﻮار وﺿﻌﻴﺖ ﻣﺸﺨﺺ ﻛﻨﺪ ﻛﺪام دﻛﻤﻪ ﻓﺮﻣﺎن ﻓﺸﺎر داده ﺷﺪه اﺳﺖ.
٢٤٩
ﻓﺼﻞ ﻫﻔﺘﻢ :ﻧﻤﺎﻳﺶ ﻛﺎدرﻫﺎي ﻣﺤﺎوره اي وﻳﮋوال 2005 C#داراي ﭼﻨﺪﻳﻦ ﻛﺎدر ﻣﺤﺎوره اي دروﻧﻲ اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ در ﻃﺮاﺣﻲ ﻇﺎﻫﺮ ﺑﺮﻧﺎﻣﻪ ،ﻛﻤﻚ زﻳﺎدي ﻛﻨﺪ .اﻳﻦ ﻛﺎدرﻫﺎ ،در ﺣﻘﻴﻘﺖ ﻫﻤﺎن ﭘﻨﺠﺮه ﻫﺎي ﻋﻤﻮﻣﻲ ﻫﺴﺘﻨﺪ ﻛﻪ در ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز ﻣـﺸﺎﻫﺪه ﻛـﺮده اﻳـﺪ .ﺑـﻪ ﻋـﻼوه اﻳـﻦ ﻛﺎدرﻫـﺎ داراي ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي ﻓﺮاواﻧﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ ﻛﺎدرﻫﺎ را ﺑﺎ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد ﻫﻤﺎﻫﻨﮓ ﻛﻨﻴﺪ. در اﻳﻦ ﻓﺼﻞ:
ﺑﺎ روﺷﻬﺎي ﻣﺨﺘﻠﻒ اﻳﺠﺎد ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﺑﺎ آﻳﻜﻮﻧﻬﺎ و ﻳﺎ دﻛﻤﻪ ﻫﺎي ﮔﻮﻧﺎﮔﻮن آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. ﺑﺎ ﻧﺤﻮه ي اﻳﺠﺎد ﻳﻚ ﻛﺎدر Openﻛﻪ ﺑﺘﻮاﻧﻴﺪ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻓﺎﻳﻠﻬﺎ از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. ﭼﮕﻮﻧﮕﻲ اﻳﺠﺎد ﻳﻚ ﻛﺎدر Saveﻛﻪ ﺑﺘﻮاﻧﻴﺪ از آن ﺑﺮاي ذﺧﻴﺮه اﻃﻼﻋﺎت ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد. ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از ﻛﺎدر Fontﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﻴﺪ ﻓﻮﻧﺖ ﻣﻮرد ﻧﻈـﺮ ﺧـﻮد را اﻧﺘﺨـﺎب ﻛﻨﺪ. ﺑﺎ ﻛﺎدر Colorو ﻣﻮارد اﺳﺘﻔﺎده از آن در ﺑﺮﻧﺎﻣﻪ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﻛﺎدر Printﻗﺎﺑﻠﻴﺘﻬﺎي ﻣﺮﺑﻮط ﺑﻪ اﻣﻮر ﭼﺎپ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛﺮد.
در اﻳﻦ ﻓﺼﻞ ،اﻳﻦ ﻛﺎدرﻫﺎي ﻣﺤﺎوره اي را ﺑﻪ ﺗﻔﺼﻴﻞ ﻣﻮرد ﺑﺮرﺳﻲ ﻗﺮار ﺧﻮاﻫﻴﻢ داد و ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﺑﻪ وﺳﻴﻠﻪ آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ داراي ﻇﺎﻫﺮي ﺣﺮﻓﻪ اي ﺗﺮ ﻫﺴﺘﻨﺪ را ﻃﺮاﺣﻲ ﻛﻨﻴﻢ.
ﻛﺎدر ﻣﺤﺎوره اي :MessageBox ﻫﻤﺎﻧﻄﻮر ﻛﻪ از اﺑﺘﺪاي ﻛﺘﺎب ﺗﺎ ﻛﻨﻮن ﻣﺘﻮﺟﻪ ﺷﺪه اﻳﺪ ،ﻛﺎدر MessageBoxﻳﻜﻲ از ﻛﺎدرﻫﺎﻳﻲ اﺳﺖ ﻛﻪ در اﻏﻠﺐ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣـﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد .از اﻳﻦ ﻛﺎدر ﻋﻤﻮﻣﺎً ﺑﺮاي ﻧﻤﺎﻳﺶ ﻳﻚ ﭘﻴﻐﺎم ﺑﻪ ﻛﺎرﺑﺮ و درﻳﺎﻓﺖ ﺟﻮاب ﻛﺎرﺑﺮ ﺑﻪ آن ﭘﻴﻐﺎم اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد .ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺒﻠﻲ ﺑﻪ ﺻﻮرت ﻳﻜﻨﻮاﺧﺖ از اﻳﻦ ﻛﺎدر اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ ،اﻣﺎ اﻳﻦ ﻛﺎدر ﻣﻲ ﺗﻮاﻧﺪ ﺑﺮ اﺳﺎس ﻣﻮﻗﻌﻴـﺖ ﺑﺮﻧﺎﻣـﻪ داراي ﻇﺎﻫﺮي ﻣﺘﻔﺎوت ﺑﺎﺷﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﻴﻢ ﻋﻼوه ﺑﺮ ﻧﻤﺎﻳﺶ ﻣﺘﻦ در آن ،آﻳﻜﻮن ﺧﺎﺻﻲ را ﻧﻴﺰ ﺑﺮاي آن ﻣﺸﺨﺺ ﻛﻨﻴﻢ و ﻳﺎ دﻛﻤﻪ ﻫﺎي دﻳﮕﺮي ﺑﻪ ﺟﺰ دﻛﻤﻪ OKدر آن ﻗﺮار دﻫﻴﻢ. در اﺳﺘﻔﺎده ي روزﻣﺮه از ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﺎﻣﭙﻴﻮﺗﺮي ،ﻛﺎدرﻫﺎي ﭘﻴﻐﺎم ﮔﻮﻧﺎﮔﻮﻧﻲ را ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ داراي آﻳﻜﻮﻧﻬـﺎﻳﻲ ﻣﺎﻧﻨـﺪ آﻳﻜﻮﻧﻬـﺎي ﺷﻜﻞ 1-7ﻫﺴﺘﻨﺪ .در اﻳﻦ ﺑﺨﺶ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان از اﻳﻦ آﻳﻜﻮﻧﻬﺎ در ﻛﺎدرﻫﺎي ﻣﺤﺎوره اي اﺳﺘﻔﺎده ﻛﺮد.
ﺷﻜﻞ 1-7 ﻫﻨﮕﺎم اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ وﻳﻨﺪوزي ،در ﻣﻮاﻗﻌﻲ ﻧﻴﺎز دارﻳﺪ ﻛﻪ ﻣﻮردي را ﺑﻪ ﻛﺎرﺑﺮ اﻃﻼع دﻫﻴﺪ و ﻳﺎ ﺑﻪ ﻛﺎرﺑﺮ ﻫﺸﺪار دﻫﻴﺪ ﻛﻪ ﻳـﻚ ﭘﻴـﺸﺎﻣﺪ ﻏﻴﺮ ﻣﻨﺘﻈﺮه رخ داده اﺳﺖ .ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ ﻛﺎرﺑﺮ اﻃﻼﻋﺎﺗﻲ از ﺑﺮﻧﺎﻣﻪ را ﺗﻐﻴﻴﺮ داده اﺳﺖ و ﺑﺪون ذﺧﻴﺮه ﻛـﺮدن ﺗﻐﻴﻴـﺮات ﺳـﻌﻲ در ﺑﺴﺘﻦ ﺑﺮﻧﺎﻣﻪ دارد .در اﻳﻦ ﺣﺎﻟﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﺣﺎوي آﻳﻜﻮن ﻫﺸﺪار )ﺳﻮﻣﻴﻦ آﻳﻜـﻮن از ﭼـﭗ( و ﻳـﺎ آﻳﻜـﻮن اﻃﻼﻋـﺎت )اوﻟـﻴﻦ آﻳﻜﻮن از ﭼﭗ( و ﻳﻚ ﭘﻴﻐﺎم ﻣﻨﺎﺳﺐ را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ دﻫﻴﺪ و ﺑﮕﻮﻳﻴﺪ ﻛﻪ در ﺻﻮرت ﺑﺴﺘﻪ ﺷﺪه ﺑﺮﻧﺎﻣﻪ ﺗﻤﺎم اﻃﻼﻋـﺎت ذﺧﻴـﺮه ﻧـﺸﺪه از
٢٥٠
ﺑﻴﻦ ﻣﻲ روﻧﺪ .ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺗﻮاﻧﻴﺪ دﻛﻤﻪ ﻫﺎي OKو Cancelرا در ﻛﺎدر ﭘﻴﻐﺎم ﻗﺮار دﻫﻴﺪ ﺗﺎ ﻛﺎرﺑﺮ ﺑﺘﻮاﻧﺪ ﺑﻪ ﺑﺴﺘﻦ ﺑﺮﻧﺎﻣﻪ اداﻣﻪ دﻫﺪ و ﻳﺎ اﻳﻦ ﻋﻤﻞ را ﻟﻐﻮ ﻛﻨﺪ. در ﻣﻮاردي ﻣﺸﺎﺑﻪ ﻣﻮرد ﺑﺎﻻ ،اﺳﺘﻔﺎده از ﻛﺎدر ﭘﻴﻐﺎم ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺗﺴﺮﻳﻊ ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻛﻤﻚ ﻛﻨﺪ .زﻳﺮا ﺑﻪ وﺳﻴﻠﻪ آن ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ ﻧﻤـﺎﻳﺶ ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﻣﻨﺎﺳﺐ ﺷﺎﻣﻞ آﻳﻜﻮن و دﻛﻤﻪ ﻫﺎي ﻣﻮرد ﻧﻈﺮ ،ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﻴﺪ در ﻣﻮرد ﻳـﻚ ﻣـﺴﺌﻠﻪ ﺧـﺎص ﺗـﺼﻤﻴﻢ ﮔﻴـﺮي ﻛﻨـﺪ. ﻫﻤﭽﻨﻴﻦ ﺑﺎ اﺳﺘﻔﺎده از ﻛﺎدر ﭘﻴﻐﺎم در ﺑﺨﺶ ﻣﺪﻳﺮﻳﺖ ﺧﻄﺎ در ﺑﺮﻧﺎﻣﻪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﺧﻄﺎﻫﺎي اﺗﻔﺎق اﻓﺘﺎده در ﺑﺮﻧﺎﻣﻪ را ﺑﺎ آﻳﻜﻮن و دﻛﻤﻪ ﻫﺎي ﻣﻨﺎﺳﺐ ﺑﻪ ﻛﺎرﺑﺮ اﻃﻼع دﻫﻴﺪ. ﻗﺒﻞ از اﻳﻨﻜﻪ اﺳﺘﻔﺎده از ﻛﺎدرﻫﺎي ﭘﻴﻐﺎم ﮔﻮﻧﺎﮔﻮن را در ﻛﺪ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ،اﺑﺘﺪا ﺑﻬﺘﺮ اﺳﺖ ﺑﺎ ﻛـﻼس MessageBoxآﺷـﻨﺎ ﺷـﻮﻳﻢ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ اﻳﻦ ﻛﻼس داراي ﻣﺘﺪي ﺑﻪ ﻧﺎم Showاﺳﺖ ﻛﻪ ﺑﺮاي ﻧﻤﺎﻳﺶ ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﺑـﻪ ﻛـﺎر ﻣـﻲ رود .ﻋﻨـﻮان ﻛـﺎدر ﭘﻴﻐﺎم ،ﻣﺘﻦ ﻧﻤﺎﻳﺶ داده ﺷﺪه در آن ،آﻳﻜﻮﻧﻬﺎ و ﻧﻴﺰ دﻛﻤﻪ ﻫﺎي ﻓﺮﻣﺎن ﻛﺎدر ﭘﻴﻐﺎم ﻫﻤﻪ ﺑﻪ وﺳﻴﻠﻪ ﭘﺎراﻣﺘﺮﻫﺎي اﻳﻦ ﻣﺘﺪ ﻣﺸﺨﺺ ﻣﻲ ﺷﻮﻧﺪ. اﻳﻦ ﻣﻮرد در اﺑﺘﺪا ﻣﻤﻜﻦ اﺳﺖ ﻣﻘﺪاري ﭘﻴﭽﻴﺪه ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ ،اﻣﺎ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ اﺳﺘﻔﺎده از آن ﺑﺴﻴﺎر ﺳﺎده اﺳﺖ.
آﻳﻜﻮﻧﻬﺎي ﻗﺎﺑﻞ اﺳﺘﻔﺎده در ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم: آﻳﻜﻮن ﻫﺎي ﻗﺎﺑﻞ اﺳﺘﻔﺎده در ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم را در ﺷﻜﻞ 1-7ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ .در ﺟﺪول زﻳﺮ ﭼﻬﺎر آﻳﻜﻮن ﻗﺎﺑﻞ اﺳـﺘﻔﺎده در ﻛـﺎدر ﭘﻴﻐـﺎم آورده ﺷﺪه اﺳﺖ .در ﺣﻘﻴﻘﺖ آﻳﻜﻮن ﻣﻮرد اﺳﺘﻔﺎده در اﻳﻦ ﻗﺴﻤﺖ از ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ درﻳﺎﻓﺖ ﻣﻲ ﺷﻮد و ﻓﻌﻼً ﭼﻬﺎر آﻳﻜﻮن ﺑﺮاي اﻳﻦ ﻣـﻮارد در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ ﻛﻪ ﺑﺮاي ﻫﻤﺎﻫﻨﮕﻲ ﺑﻌﻀﻲ از آﻧﻬﺎ داراي ﭼﻨﺪ ﻧﺎم ﻫﺴﺘﻨﺪ: ﻧﺎم ﻋﻀﻮ
ﺗﻮﺿﻴﺢ
Asterisk
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻳﻚ آﻳﻜﻮن اﻃﻼﻋﺎت در ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﺷﻮد.
Information
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻳﻚ آﻳﻜﻮن اﻃﻼﻋﺎت در ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﺷﻮد.
Error
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻳﻚ آﻳﻜﻮن ﺧﻄﺎ در ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﺷﻮد.
Hand
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻳﻚ آﻳﻜﻮن ﺧﻄﺎ در ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﺷﻮد.
Stop
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻳﻚ آﻳﻜﻮن ﺧﻄﺎ در ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﺷﻮد.
Exclamation
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻳﻚ آﻳﻜﻮن ﻫﺸﺪار در ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﺷﻮد.
Warning
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻳﻚ آﻳﻜﻮن ﻫﺸﺪار در ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﺷﻮد.
Question
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻳﻚ ﻋﻼﻣﺖ ﺳﻮال در ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﺷﻮد.
None
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ آﻳﻜﻮﻧﻲ در ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﻧﺸﻮد.
دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد ﺑﺮاي ﻛﺎدر ﭘﻴﻐﺎم: در ﻫﺮ ﻛﺎدر ﭘﻴﻐﺎم ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻜﻲ از ﭼﻨﺪﻳﻦ ﮔﺮوه دﻛﻤﻪ ي ﻣﻮﺟﻮد را ﻧﻤﺎﻳﺶ دﻫﻴﺪ .در ﺟﺪول زﻳﺮ ﮔﺰﻳﻨﻪ ﻫﺎي ﻗﺎﺑﻞ اﻧﺘﺨـﺎب ﺑـﺮاي اﻳـﻦ ﻣﻮرد ﺷﺮح داده ﺷﺪه اﻧﺪ:
٢٥١
ﻧﺎم ﻋﻀﻮ
ﺷﺮح
AbortRetryIgnore
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺎدر ﺷﺎﻣﻞ دﻛﻤﻪ ﻫـﺎي Retry ،Abortو Cancel ﺑﺎﺷﺪ.
OK
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺎدر ﺷﺎﻣﻞ دﻛﻤﻪ OKﺑﺎﺷﺪ.
OKCancel
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺎدر ﺷﺎﻣﻞ دﻛﻤﻪ ﻫﺎي OKو Cancelﺑﺎﺷﺪ.
RetryCancel
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺎدر ﺷﺎﻣﻞ دﻛﻤﻪ ﻫﺎي Retryو Cancelﺑﺎﺷﺪ.
YesNo
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺎدر ﺷﺎﻣﻞ دﻛﻤﻪ ﻫﺎي Yesو Noﺑﺎﺷﺪ.
YesNoCancel
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺎدر ﺷﺎﻣﻞ دﻛﻤﻪ ﻫﺎي Yesو Noو Cancelﺑﺎﺷﺪ.
ﺗﻨﻈﻴﻢ دﻛﻤﻪ ي ﭘﻴﺶ ﻓﺮض: ﻫﻨﮕﺎم ﺗﻨﻈﻴﻢ وﻳﮋﮔﻴﻬﺎي ﻣﺨﺘﻠﻒ ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﺑﺮاي ﻧﻤﺎﻳﺶ ،ﻋﻼوه ﺑﺮ ﻣﺸﺨﺺ ﻛﺮدن دﻛﻤﻪ ﻫﺎي آن ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣـﺸﺨﺺ ﻛﻨﻴـﺪ ﻛـﻪ ﻛﺪام دﻛﻤﻪ ﺑﻪ ﻋﻨﻮان ﭘﻴﺶ ﻓﺮض در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﻮد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ وﻳﮋﮔﻲ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ در ﺑﻴﻦ دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻛﺎدر ،ﻛﺪام دﻛﻤﻪ ﺑﺎﻳﺪ داراي ﻓﻮﻛﻮس ﺑﺎﺷﺪ .ﺑﺎ ﺗﻨﻈﻴﻢ اﻳﻦ ﻣﻮرد ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﻴﺪ ﻛﻪ ﺑﻌـﺪ از ﺧﻮاﻧـﺪن ﻣـﺘﻦ ﻛـﺎدر ﭘﻴﻐﺎم ،ﺑﺎ ﻓﺸﺎر دادن ﻛﻠﻴﺪ Enterو ﺑﺪون ﺣﺮﻛﺖ ﻣﺎوس ،دﻛﻤﻪ ي ﭘﻴﺶ ﻓﺮض را اﻧﺘﺨﺎب ﻛﻨﺪ .ﺑﺮاي ﺗﻨﻈﻴﻢ اﻳﻦ ﻣﻮرد ﺑﺎﻳﺪ از ﺷﻤﺎرﻧﺪه MessageBoxDefaultButtonاﺳﺘﻔﺎده ﻛﻨﻴﺪ ﻛﻪ ﺷﺮح ﮔﺰﻳﻨﻪ ﻫﺎي آن در ﺟﺪول زﻳﺮ آﻣﺪه اﺳﺖ: ﻧﺎم ﻋﻀﻮ
ﺷﺮح
Button 1
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ دﻛﻤﻪ اول در ﻛﺎدر ﭘﻴﻐﺎم ﺑﻪ ﻋﻨﻮان دﻛﻤﻪ ﭘﻴﺶ ﻓﺮض در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﻮد.
Button 2
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ دﻛﻤﻪ دوم در ﻛﺎدر ﭘﻴﻐﺎم ﺑﻪ ﻋﻨﻮان دﻛﻤﻪ ﭘﻴﺶ ﻓﺮض در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﻮد.
Button 3
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ دﻛﻤﻪ ﺳﻮم در ﻛﺎدر ﭘﻴﻐﺎم ﺑﻪ ﻋﻨﻮان دﻛﻤﻪ ﭘﻴﺶ ﻓﺮض در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﻮد.
ﺗﺮﺗﻴﺐ اﻳﻦ دﻛﻤﻪ ﻫﺎ از ﺳﻤﺖ ﭼﭗ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮد .ﺑﺮاي ﻣﺜﺎل اﮔﺮ در ﻛﺎدر ﭘﻴﻐﺎم ﺳﻪ دﻛﻤﻪ Yesو Noو Cancelداﺷﺘﻪ ﺑﺎﺷﻴﺪ و دﻛﻤﻪ ﺳﻮم را ﺑﻪ ﻋﻨﻮان دﻛﻤﻪ ﭘﻴﺶ ﻓﺮض ﻣﺸﺨﺺ ﻛﻨﻴﺪ ،دﻛﻤﻪ Cancelﭘﻴﺶ ﻓﺮض ﺧﻮاﻫﺪ ﺑﻮد .ﻫﻤﭽﻨـﻴﻦ اﮔـﺮ در ﻛـﺎدر ﭘﻴﻐﺎم دو دﻛﻤﻪ Yesو Noداﺷﺘﻪ ﺑﺎﺷﻴﺪ و دﻛﻤﻪ ﺳﻮم را ﺑﻪ ﻋﻨﻮان ﭘﻴﺶ ﻓﺮض ﻣﺸﺨﺺ ﻛﻨﻴﺪ ،دﻛﻤﻪ Yesﭘﻴﺶ ﻓﺮض ﺧﻮاﻫﺪ ﺑﻮد.
ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﺨﺘﻠﻒ ﻛﺎدر ﭘﻴﻐﺎم:
٢٥٢
ﻫﻨﮕــﺎم ﻛــﺎر ﺑــﺎ ﻛــﺎدر ﭘﻴﻐــﺎم ﻋــﻼوه ﺑــﺮ ﮔﺰﻳﻨــﻪ ﻫــﺎي ﺑــﺎﻻ ،ﻣــﻮارد دﻳﮕــﺮي ﻧﻴــﺰ ﻗﺎﺑــﻞ ﺗﻨﻈــﻴﻢ اﺳــﺖ ﻛــﻪ در ﺷــﻤﺎرﻧﺪه MessageBoxOptionsﻗﺮار دارد .ﺑﻌﻀﻲ از ﻣﻮارد ﭘﺮ ﻛﺎرﺑﺮد ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻗﺎﺑﻞ ﺗﻨﻈﻴﻢ ﻫﺴﺘﻨﺪ ،در ﺟﺪول زﻳﺮ ﺗﻮﺿﻴﺢ داده ﺷﺪه اﻧﺪ: ﻧﺎم ﻋﻀﻮ
ﺷﺮح
RightAlign
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻣﺘﻦ داﺧﻞ ﻛﺎدر ﭘﻴﻐﺎم ﺑﺎﻳﺪ از ﺳﻤﺖ راﺳﺖ ﻧﻮﺷﺘﻪ ﺷﻮد .اﻳـﻦ ﺣﺎﻟـﺖ ﺑـﺮ ﻋﻜـﺲ ﺣﺎﻟﺖ ﭘﻴﺶ ﻓﺮض اﺳﺖ ﻛﻪ ﻣﺘﻦ از ﺳﻤﺖ ﭼﭗ ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد.
RTLReading
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺎدر ﭘﻴﻐﺎم ﺑﺎﻳﺪ ﺑﺮاي ﻧﻤﺎﻳﺶ ﻣﺘﻦ راﺳﺖ ﺑﻪ ﭼﭗ ،ﺗﻨﻈﻴﻢ ﺷﻮد .اﻳﻦ ﺣﺎﻟﺖ ﺑـﺮاي ﻧﻤﺎﻳﺶ ﻣﺘﻦ ﺑﻪ زﺑﺎﻧﻬﺎﻳﻲ ﻣﻨﺎﺳﺐ اﺳﺖ ﻛﻪ از راﺳﺖ ﺑﻪ ﭼﭗ ﻧﻮﺷﺘﻪ ﻣﻲ ﺷـﻮﻧﺪ )ﻣﺎﻧﻨـﺪ ﻓﺎرﺳـﻲ( .ﺑـﺮاي ﻣﺜﺎل در اﻳﻦ ﺣﺎﻟﺖ آﻳﻜﻮن ﻛﺎدر ﭘﻴﻐﺎم در ﺳﻤﺖ راﺳﺖ ﻣﺘﻦ ﻗﺮار ﻣﻲ ﮔﻴﺮد.
ﺣﺎﻟﺘﻬﺎي ﻣﺨﺘﻠﻒ اﺳﺘﻔﺎده از ﻣﺘﺪ :Show ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﺑﺮاي ﻧﻤﺎﻳﺶ ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم از ﻣﺘﺪ Showﻛﻼس MessageBoxاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .ﻛﺪي ﻛﻪ در زﻳـﺮ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻣﺘﺪ Showرا ﺑﻪ ﮔﻮﻧﻪ اي ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﻣﺸﺎﺑﻪ ﺷﻜﻞ 2-7را ﻧﻤﺎﻳﺶ دﻫﺪ .در اﻳﻦ ﻛﺪ ﻣﺘﻨﻲ ﻛﻪ ﺑﺎﻳﺪ در ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﺷﻮد ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ اول ﺑﻪ ﻣﺘﺪ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد و ﺑﻪ دﻧﺒﺎل آن ﻧﻴﺰ ﻣﺘﻨﻲ ﻛﻪ ﺑﺎﻳﺪ در ﻧـﻮار ﻋﻨـﻮان ﻛـﺎدر ﻗﺮار ﺑﮕﻴﺮد وارد ﻣﻲ ﺷﻮد .ﺳﭙﺲ دﻛﻤﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﺎﻳﺪ ﺑﻪ وﺳﻴﻠﻪ ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﺷﻮد و ﻧﻴﺰ آﻳﻜﻮن ﻛﺎدر ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ .در اﻧﺘﻬﺎ ﻧﻴﺰ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﻛﻪ ﻛﺪام دﻛﻤﻪ ﻓﺮﻣﺎن ﺑﻪ ﻋﻨﻮان ﭘﻴﺶ ﻓﺮض در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﻮد. MessageBox.Show("My Text", "My Caption", MessageBoxButtons.OKCancel, MessageBoxIcon.Information, ;)MessageBoxDefaultButton.Button1
ﺷﻜﻞ 2-7 ﺣﺎل ﻛـﻪ ﺑـﺎ آﻳﻜﻮﻧﻬـﺎ و دﻛﻤـﻪ ﻫـﺎي ﻗﺎﺑـﻞ اﺳـﺘﻔﺎده در ﻛـﺎدر ﭘﻴﻐـﺎم آﺷـﻨﺎ ﺷـﺪﻳﺪ ،ﺑﻬﺘـﺮ اﺳـﺖ ﺑـﻪ ﺑﺮرﺳـﻲ ﻣﺘـﺪ Showاز ﻛـﻼس MessageBoxﺑﭙﺮدازﻳﻢ .اﻳﻦ ﻣﺘﺪ ﺑﻪ ﭼﻨﺪﻳﻦ روش ﻗﺎﺑﻞ اﺳﺘﻔﺎده اﺳﺖ و ﺑﺮاي ﻓﺮاﺧﻮاﻧﻲ آن ﻣﻲ ﺗﻮاﻧﻴﺪ ﭘﺎراﻣﺘﺮﻫﺎي ﮔﻮﻧﺎﮔﻮﻧﻲ را ﺑﻪ آن ارﺳﺎل ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل در ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ از اﺑﺘﺪاي ﻛﺘﺎب ﺗﺎﻛﻨﻮن ﻧﻮﺷﺘﻪ اﻳﻢ ،ﺗﻨﻬﺎ ﻣﺘﻨﻲ ﻛﻪ ﺑﺎﻳﺪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﺪ را ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻣﻲ ﻓﺮﺳﺘﺎدﻳﻢ ،اﻣﺎ در ﻣﺜﺎل ﻗﺒﻞ ﺑﻴﺸﺘﺮ ﺟﺰﺋﻴﺎت ﻛﺎدر ﭘﻴﻐﺎم را ﺑﺮاي ﻣﺘﺪ ﻣﺸﺨﺺ ﻛﺮدﻳﻢ .ﭘﺮ ﻛﺎرﺑﺮد ﺗﺮﻳﻦ ﻧﻮﻋﻬﺎي ﻓﺮاﺧـﻮاﻧﻲ اﻳـﻦ ﻣﺘـﺪ در ﻟﻴﺴﺖ زﻳﺮ آﻣﺪه اﺳﺖ:
٢٥٣
)MessageBox.Show(Text )MessageBox.Show(Text,Caption )MessageBox.Show(Text,Caption,Button )MessageBox.Show(Text,Caption,Button,Icon MessageBox.Show(Text,Caption,Button,Icon,DefaultButton )
در اﻳﻦ ﻟﻴﺴﺖ ﭘﺎراﻣﺘﺮ Textﻛﻪ ﻳﻚ ﭘﺎراﻣﺘﺮ اﺟﺒﺎري اﺳﺖ ،ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻣﺘﻨﻲ اﺳﺖ ﻛﻪ ﺑﺎﻳﺪ ﺗﻮﺳﻂ ﻛﺎدر ﻧﻤـﺎﻳﺶ داده ﺷـﻮد و ﻣـﻲ ﺗﻮاﻧﺪ ﻳﻚ ﻣﻘﺪار ﺛﺎﺑﺖ و ﻳﺎ ﻳﻚ ﻣﺘﻐﻴﺮ رﺷﺘﻪ اي ﺑﺎﺷﺪ .ﺑﻘﻴﻪ ﭘﺎراﻣﺘﺮﻫﺎي اﻳﻦ ﺗﺎﺑﻊ ﺑﻪ ﺻﻮرت اﺧﺘﻴﺎري ﻫﺴﺘﻨﺪ:
:Captionﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻣﺘﻨﻲ اﺳﺖ ﻛﻪ ﺑﺎﻳﺪ در ﻧﻮار ﻋﻨﻮان ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﺷﻮد .اﮔﺮ اﻳﻦ ﭘﺎراﻣﺘﺮ ﺑﻪ ﺗـﺎﺑﻊ ﻓﺮﺳـﺘﺎده ﻧﺸﻮد ،ﻣﺘﻨﻲ در ﻧﻮار ﻋﻨﻮان ﻧﻤﺎﻳﺶ داده ﻧﻤﻲ ﺷﻮد. :Buttonﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻣﻘﺪاري از ﺷﻤﺎرﻧﺪه MessageBoxButtonsاﺳﺖ .اﻳﻦ ﭘـﺎراﻣﺘﺮ ﺑـﻪ ﺷـﻤﺎ اﻳـﻦ اﻣﻜﺎن را ﻣﻲ دﻫﺪ ﻛﻪ ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ ﻛﺪام دﻛﻤﻪ ﻫﺎ در ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ .اﮔﺮ اﻳﻦ ﭘﺎراﻣﺘﺮ ﺣﺬف ﺷﻮد ،ﻓﻘﻂ دﻛﻤـﻪ OKدر ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد. :Iconﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻣﻘﺪاري از ﺷﻤﺎرﻧﺪه MessageBoxIconاﺳﺖ و ﺑﺮاي ﺗﻌﻴﻴﻦ آﻳﻜﻮﻧﻲ ﻛﻪ ﺑﺎﻳﺪ در ﻛـﺎدر ﻧﻤﺎﻳﺶ داده ﺷﻮد ﺑﻪ ﻛﺎر ﻣﻲ رود .اﮔﺮ اﻳﻦ ﭘﺎراﻣﺘﺮ ﺣﺬف ﺷﻮد آﻳﻜﻮﻧﻲ در ﻛﺎرد ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﻧﺨﻮاﻫﺪ ﺷﺪ. :DefaultButtonﻣــﺸﺨﺺ ﻛﻨﻨــﺪه ﻣﻘــﺪاري از ﺷــﻤﺎرﻧﺪه MessageBoxDefaultButton اﺳﺖ و ﺑﺮاي ﺗﻌﻴﻴﻦ دﻛﻤﻪ ﻓﺮﻣﺎن ﭘﻴﺶ ﻓﺮض در ﻓﺮم ﺑﻪ ﻛﺎر ﻣﻲ رود .اﮔﺮ اﻳﻦ ﻣﻘﺪار در ﻓﺮاﺧﻮاﻧﻲ ﺗﺎﺑﻊ ﺗﻌﻴﻴﻦ ﻧﺸﻮد ،دﻛﻤﻪ اول ﺑﻪ ﻋﻨﻮان دﻛﻤﻪ ﻓﺮﻣﺎن ﭘﻴﺶ ﻓﺮض در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮد.
ﺗﻤﺎم ﺣﺎﻟﺘﻬﺎي ﻣﺘﺪ Showﻛﻪ در ﺑﺎﻻ ذﻛﺮ ﺷﺪ ﻣﻘـﺪاري را از ﻧـﻮع ﺷـﻤﺎرﻧﺪه DialogResultﺑﺮﻣـﻲ ﮔﺮداﻧﻨـﺪ .اﻳـﻦ ﻣﻘـﺪار ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﺪاﻣﻴﻚ از دﻛﻤﻪ ﻫﺎي ﻛﺎدر ﭘﻴﻐﺎم ﺗﻮﺳﻂ ﻛـﺎرﺑﺮ اﻧﺘﺨـﺎب ﺷـﺪه اﺳـﺖ .در ﺟـﺪول زﻳـﺮ ﺗﻤـﺎم ﮔﺰﻳﻨـﻪ ﻫـﺎي ﺷـﻤﺎرﻧﺪه DialogResultﻣﻮرد ﺑﺮرﺳﻲ ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ. ﻧﺎم ﻋﻀﻮ
ﺷﺮح
Abort
ﻣﻘﺪار ﺑﺎزﮔﺸﺘﻲ Abortاﺳﺖ و ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺮ روي دﻛﻤﻪ Abortﻛﻠﻴﻚ ﻛﺮده اﺳﺖ.
Cancel
ﻣﻘﺪار ﺑﺎزﮔﺸﺘﻲ Cancelاﺳﺖ و ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺮ روي دﻛﻤـﻪ Cancelﻛﻠﻴـﻚ ﻛـﺮده اﺳﺖ.
Ignore
ﻣﻘﺪار ﺑﺎزﮔﺸﺘﻲ Ignoreاﺳﺖ و ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺮ روي دﻛﻤـﻪ Ignoreﻛﻠﻴـﻚ ﻛـﺮده اﺳﺖ.
No
ﻣﻘﺪار ﺑﺎزﮔﺸﺘﻲ Noاﺳﺖ و ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺮ روي دﻛﻤﻪ Noﻛﻠﻴﻚ ﻛﺮده اﺳﺖ.
None
ﻣﻘﺪار ﺑﺎزﮔﺸﺘﻲ Noneاﺳﺖ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻫﻨﻮز ﮔﺰﻳﻨﻪ اي از ﻛﺎدر ﭘﻴﻐﺎم ﺗﻮﺳﻂ ﻛﺎرﺑﺮ اﻧﺘﺨﺎب ﻧﺸﺪه اﺳﺖ.
OK
ﻣﻘﺪار ﺑﺎزﮔﺸﺘﻲ Cancelاﺳﺖ و ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺮ روي دﻛﻤـﻪ Cancelﻛﻠﻴـﻚ ﻛـﺮده اﺳﺖ.
٢٥٤
Retry
ﻣﻘﺪار ﺑﺎزﮔﺸﺘﻲ Retryاﺳﺖ و ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺮ روي دﻛﻤﻪ Retryﻛﻠﻴﻚ ﻛﺮده اﺳﺖ.
Yes
ﻣﻘﺪار ﺑﺎزﮔﺸﺘﻲ Yesاﺳﺖ و ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺮ روي دﻛﻤﻪ Yesﻛﻠﻴﻚ ﻛﺮده اﺳﺖ.
ﻛﺎدرﻫﺎي ﭘﻴﻐﺎم ﻧﻤﻮﻧﻪ: در ﻣﻮاردي ﻛﻪ ﻓﻘﻂ ﻳﻚ دﻛﻤﻪ در ﻛﺎدر ﭘﻴﻐﺎم ﺑﻪ ﻛﺎر ﻣﻲ رود ﻧﻴﺎزي ﺑﻪ ﺑﺮرﺳﻲ ﻧﺘﻴﺠﻪ ﻛﺎدر ﭘﻴﻐﺎم ﻧﺪارﻳﻢ ،اﻣﺎ اﮔﺮ در ﻛﺎدر ﭘﻴﻐﺎم از ﺑـﻴﺶ از ﻳﻚ دﻛﻤﻪ اﺳﺘﻔﺎده ﻛﻨﻴﻢ ﺑﻌﺪ از ﻧﻤﺎﻳﺶ ﺑﺎﻳﺪ ﻧﺘﻴﺠﻪ را ﻧﻴﺰ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣـﻲ ﺗﻮان ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﺑﺎ ﺑﻴﺶ از ﻳﻚ دﻛﻤﻪ ﻧﻤﺎﻳﺶ داد و ﺳﭙﺲ ﻣﺸﺨﺺ ﻛﺮد ﻛﻪ ﻛﺎرﺑﺮ ﻛﺪام دﻛﻤﻪ را اﻧﺘﺨﺎب ﻛﺮده اﺳﺖ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻛﺎدر ﭘﻴﻐﺎم ﺑﺎ دو دﻛﻤﻪ (1
(2 (3 (4
وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005را اﺟﺮا ﻛﺮده و از ﻧﻮار ﻣﻨﻮ ،ﮔﺰﻳﻨﻪ … File New Projectرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. در ﭘﻨﺠﺮه ي New Projectاز ﻗﺴﻤﺖ Templatesﮔﺰﻳﻨـﻪ Windows Applicationرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ و در ﺑﺨﺶ Nameﻧﺎم Simple MessageBoxرا وارد ﻛﻨﻴﺪ .ﺳﭙﺲ روي دﻛﻤـﻪ OKﻛﻠﻴـﻚ ﻛﻨﻴﺪ ﺗﺎ ﭘﺮوژه اﻳﺠﺎد ﺷﻮد. Simple ﺑــﺮ روي ﻓــﺮم ﺑﺮﻧﺎﻣــﻪ در ﻗــﺴﻤﺖ ﻃﺮاﺣــﻲ ﻓــﺮم ﻛﻠﻴــﻚ ﻛــﺮده و ﺳــﭙﺲ ﺧﺎﺻــﻴﺖ Textآن را ﺑــﻪ MessageBoxﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ،ﻳﻚ ﻛﻨﺘﺮل Buttonﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮده ،ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑـﺮ ﺑـﺎ btnShowو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Showﻗﺮار دﻫﻴﺪ. ﺳﭙﺲ ﻳﻚ ﻛﻨﺘﺮل Labelدر ﻓﺮم ﻗﺮار دﻫﻴﺪ .اﻳﻦ ﻛﻨﺘﺮل ﺑﺮاي ﻧﻤﺎﻳﺶ ﮔﺰﻳﻨﻪ اي ﺑﻪ ﻛﺎر ﻣﻲ رود ﻛﻪ ﻛﺎرﺑﺮ از ﻛـﺎدر ﭘﻴﻐـﺎم اﻧﺘﺨﺎب ﻛﺮده اﺳﺖ .ﺧﺎﺻﻴﺖ Nameاﻳﻦ ﮔﺰﻳﻨﻪ را ﺑﻪ lblResultو ﺧﺎﺻﻴﺖ Textآن را ﺑﻪ Nothing Clickedﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺳﭙﺲ اﻧﺪازه ﻓﺮم را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ﻛﻪ ﻓﺮم ﺷﻤﺎ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 3-7ﺷﻮد.
ﺷﻜﻞ 3-7 (5ﺑﺮ روي دﻛﻤﻪ ي Showدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در آن وارد ﻛﻨﻴﺪ: )private void btnShow_Click(object sender, EventArgs e { (if ( MessageBox.Show "Your Internet Connection will be closed now!", "Dial-Up Networking Notification",
٢٥٥
MessageBoxButtons.OKCancel, MessageBoxIcon.None, )MessageBoxDefaultButton.Button1 == )DialogResult.OK { ;"!lblResult.Text = "OK Clicked // Call some method here... } else { ;"!lblResult.Text = "Cancel Clicked // Call some method here... } } (6ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ ي Showﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 4-7ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 4-7 (7ﺑﺮ روي دﻛﻤﻪ ي OKو ﻳﺎ دﻛﻤﻪ Cancelﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻧﺘﻴﺠﻪ اﻧﺘﺨﺎب ﺷﻤﺎ در ﻟﻴﺒﻞ ﻧﻤـﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﻳﻦ ﻛﺪ اﺑﺘﺪا ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ Showﻛﺎدر ﭘﻴﻐﺎﻣﻲ را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ دادﻳﻢ .ﺳﭙﺲ در ﻳﻚ دﺳﺘﻮر ifﺑﺮرﺳﻲ ﻛﺮده اﻳﻢ ﻛﻪ ﻛـﺎرﺑﺮ ﭼﻪ ﮔﺰﻳﻨﻪ اي را اﻧﺘﺨﺎب ﻛﺮده اﺳﺖ: (MessageBox.Show "Your Internet Connection will be closed now!", "Dial-Up Networking Notification", MessageBoxButtons.OKCancel, null, )MessageBoxDefaultButton.Button1 == )DialogResult.OK
( if
ﺗﻮﺟﻪ ﻛﻨﻴﺪ در ﻓﺮاﺧﻮاﻧﻲ ﺗﺎﺑﻊ Showﻣﺸﺨﺺ ﻛﺮده اﻳﻢ ﻛﻪ دﻛﻤﻪ ﻫﺎي OKو Cancelﺑﺮ روي ﻓـﺮم ﻗـﺮار ﺑﮕﻴﺮﻧـﺪ و ﻫﻤﭽﻨـﻴﻦ دﻛﻤﻪ OKﺑﻪ ﻋﻨﻮان دﻛﻤﻪ ﭘﻴﺶ ﻓﺮض در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﻮد.
٢٥٦
ﻫﻤﭽﻨـــﻴﻦ ﻣـــﺸﺎﻫﺪه ﻣـــﻲ ﻛﻨﻴـــﺪ ﻛـــﻪ در دﺳـــﺘﻮر ،ifﻣﻘـــﺪار ﺑﺮﮔـــﺸﺖ داده ﺷـــﺪه ﺗﻮﺳـــﻂ ﺗـــﺎﺑﻊ Showرا ﺑـــﺎ ﻣﻘـــﺪار DialogResult.OKﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ .در ﺻﻮرﺗﻲ ﻛﻪ اﻳﻦ دو ﻣﻘﺪار ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﻣﺴﺎوي ﻧﺒﻮدﻧﺪ ﻣﻲ ﺗﻮان ﻓﻬﻤﻴﺪ ﻛﺎرﺑﺮ ﮔﺰﻳﻨﻪ ي Cancelرا اﻧﺘﺨﺎب ﻛﺮده اﺳﺖ .ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺗﻮاﻧﺴﺘﻴﺪ در اﻳﻦ ﻣﻘﺎﻳﺴﻪ از ﮔﺰﻳﻨـﻪ ي DialogResult.Cancel ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. اﺳﺘﻔﺎده از اﻳﻦ روش ﻣﻘﺎﻳﺴﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ دو دﻛﻤﻪ در ﻛﺎدر وﺟﻮد دارد روش ﻣﻨﺎﺳﺒﻲ اﺳﺖ .اﻣﺎ ﺑﺮاي ﺷﺮاﻳﻄﻲ ﻛﻪ ﺳﻪ دﻛﻤﻪ در ﻛﺎدر ﻗﺮار دارﻧﺪ ﻣﻲ ﺗﻮان از روﺷﻬﺎي ﻛﻮﺗﺎه ﺗﺮي اﺳﺘﻔﺎده ﻛﺮد .در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،اﻳﻦ ﻣﻮرد را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﺳﻪ دﻛﻤﻪ ﻓﺮﻣﺎن در ﻛﺎدر ﭘﻴﻐﺎم (1اﮔﺮ ﻫﻤﭽﻨﺎن ﺑﺮﻧﺎﻣﻪ در ﺣﺎل اﺟﺮا اﺳﺖ آن را ﻣﺘﻮﻗﻒ ﻛﺮده و ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ Form1ﺑﺮوﻳﺪ. (2دﻛﻤﻪ ي دﻳﮕﺮي ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮده ،ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑـﺎ btn3Buttonsو ﺧﺎﺻـﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ 3 Buttonsﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ ﺑﺮ روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷـﻮد. ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: )private void btn3Buttons_Click(object sender, EventArgs e { // Declare a variable ;DialogResult intResult
+
// Get the results of the button clicked (intResult = MessageBox.Show ""The A Drive is not ready.\n\nPlease insert a " diskette into drive.", "Device Not Ready", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error, ;)MessageBoxDefaultButton.Button2 // Process the results of the button clicked )switch (intResult { case DialogResult.Abort: // Do abort processing here... ;"!lblResult.Text = "Abort clicked ;break case DialogResult.Retry: // Do retry processing here... ;"!lblResult.Text = "Retry clicked ;break case DialogResult.Ignore: // Do ignore processing here... ;"!lblResult.Text = "Ignore clicked ;break } ٢٥٧
} (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ ي 3 Buttonsﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﺑـﺎ ﺳـﻪ دﻛﻤـﻪ ﻣـﺸﺎﺑﻪ ﺷﻜﻞ 5-7را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﻛﺎدر ﭘﻴﻐﺎم ،دﻛﻤﻪ ي دوم ﺑﻪ ﺻﻮرت ﭘـﻴﺶ ﻓـﺮض اﻧﺘﺨـﺎب ﺷـﺪه اﺳﺖ.
ﺷﻜﻞ 5-7
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در ﻓﺼﻞ ﭘﻨﺠﻢ ﻛﻪ در ﻣﻮرد ﺷﻤﺎرﻧﺪه ﻫﺎ ﺻﺤﺒﺖ ﻣﻲ ﻛﺮدﻳﻢ ،ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﺷﻤﺎرﻧﺪه ﻫﺎ در ﺣﻘﻴﻘﺖ ﻧﻮﻋﻲ ﻋﺪد ﺻﺤﻴﺢ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﻪ ﻫﺮ ﻳﻚ از آﻧﻬﺎ ﻋﺪدي ﻧﺴﺒﺖ داده ﻣﻲ ﺷﻮد .ﻧﻮع DialogResultﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻣﺘﺪ Showﺑﺮﮔﺸﺘﻪ ﻣﻲ ﺷﻮد ﻧﻴﺰ ﻧـﻮﻋﻲ ﻋﺪد ﺻﺤﻴﺢ اﺳﺖ .در اﻳﻦ ﻣﺜﺎل اﺑﺘﺪا ﻣﺘﻐﻴﺮي از ﻧﻮع ﺷﻤﺎرﻧﺪه DialogResultﺗﻌﺮﻳﻒ ﻛﺮده و ﻣﻘﺪار ﺑﺮﮔﺸﺘﻲ از ﻣﺘﺪ Show را )ﻣﻘﺪاري ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺎرﺑﺮ اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ( در آن ﻗﺮار دﻫﻴﻢ. // Declare a variable ;DialogResult intResult
+
// Get the results of the button clicked (intResult = MessageBox.Show ""The A Drive is not ready.\n\nPlease insert a " diskette into drive.", "Device Not Ready", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error, ;)MessageBoxDefaultButton.Button2
ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻓﺼﻠﻬﺎي ﻗﺒﻞ ﮔﻔﺘﻢ ،ﺑﺮاي اﺳﺘﻔﺎده از ﻛﺎراﻛﺘﺮ ﻫﺎي ﻛﻨﺘﺮﻟﻲ در ﻳﻚ رﺷـﺘﻪ از ﻋﻼﻣـﺖ \ اﺳـﺘﻔﺎده ﻣـﻲ ﻛﻨﻨـﺪ .1ﻳﻜـﻲ از ﻛﺎراﻛﺘﺮ ﻫﺎي ﻛﻨﺘﺮﻟﻲ ،ﻛﺎراﻛﺘﺮ nاﺳﺖ ﻛﻪ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد اداﻣﻪ ﻣﺘﻦ در ﻳﻚ ﺧﻂ ﺟﺪﻳﺪ ﻧﻤﺎﻳﺶ داده ﺷﻮد .در اﻳﻨﺠـﺎ ﺑـﺮاي اﻳﻨﻜـﻪ اداﻣـﻪ ﻣﺘﻨﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ در ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ دﻫﻴﻢ در دو ﺧﻂ ﭘﺎﻳﻴﻦ ﺗﺮ ﻗﺮار ﺑﮕﻴﺮد از ﻛﺎراﻛﺘﺮ ﻛﻨﺘﺮﻟﻲ nدو ﺑﺎر اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ. در اﻧﺘﻬﺎ ﻧﻴﺰ ﻧﺘﻴﺠﻪ ﺑﺮﮔﺸﺖ داده ﺷﺪه ﺗﻮﺳﻂ ﻛﺎدر ﭘﻴﻐﺎم را ﺗﻮﺳﻂ ﻳﻚ دﺳﺘﻮر switchﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ: // Process the results of the button clicked 1رﺟﻮع ﻛﻨﻴﺪ ﺑﻪ ﻓﺼﻞ ﭼﻬﺎرم ﺑﺨﺶ ﺣﻠﻘﻪ ﻫﺎي foreach
٢٥٨
)switch (intResult { case DialogResult.Abort: // Do abort processing here... ;"!lblResult.Text = "Abort clicked ;break case DialogResult.Retry: // Do retry processing here... ;"!lblResult.Text = "Retry clicked ;break case DialogResult.Ignore: // Do ignore processing here... ;"!lblResult.Text = "Ignore clicked ;break } ﻧﻜﺘﻪ :ﻫﻤﻮاره دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ از ﻛﺎدر ﭘﻴﻐﺎم ﺑﻴﺶ از اﻧﺪازه اﺳﺘﻔﺎده ﻧﻜﻨﻴﺪ و ﺳﻌﻲ ﻛﻨﻴﺪ ﺑﺮاي اﺳﺘﻔﺎده از آن دﻟﻴﻞ ﻣﻨﺎﺳﺒﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،زﻳﺮا اﺳﺘﻔﺎده ﺑﻴﺶ از اﻧﺪازه از آن ﺑﺎﻋﺚ ﻧﺎراﺣﺘﻲ ﻛﺎرﺑﺮ ﻣﻲ ﺷﻮد .در ﻣﻮاﻗﻌﻲ از ﻛـﺎدر ﭘﻴﻐـﺎم اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ ﻛـﻪ ﺑﺨﻮاﻫﻴـﺪ ﻛـﺎرﺑﺮ را از رخ دادن ﺧﻄﺎﻳﻲ در ﺑﺮﻧﺎﻣﻪ آﮔﺎه ﻛﻨﻴﺪ و ﻳﺎ ﺑﻪ ﻛﺎرﺑﺮ در ﻣﻮرد ﻳﻚ ﻣﺴﺌﻠﻪ ﻣﻬﻢ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺑﺎﻋﺚ اﻳﺠﺎد ﺧﻄﺎ و ﻳﺎ از دﺳﺖ رﻓﺘﻦ اﻃﻼﻋﺎت ﺷـﻮد ﻫﺸﺪار دﻫﻴﺪ .ﻳﻚ ﻣﺜﺎل ﺑﺮاي ﻛﺎر ﻫﻨﮕﺎﻣﻲ اﺳﺖ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺪون ذﺧﻴﺮه ﺗﻐﻴﺮات ﺳﻌﻲ در ﺧﺎرج ﺷـﺪن از ﺑﺮﻧﺎﻣـﻪ را داﺷـﺘﻪ ﺑﺎﺷـﺪ .در اﻳـﻦ ﻣﻮاﻗﻊ ،ﺑﺎﻳﺪ ﺑﻪ ﻛﺎرﺑﺮ اﻃﻼع دﻫﻴﺪ ﻛﻪ اﮔﺮ اداﻣﻪ دﻫﺪ ﻣﻤﻜﻦ اﺳﺖ ﺗﻤﺎم ﺗﻐﻴﻴﺮاﺗﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﺮده اﺳﺖ از ﺑﻴﻦ ﺑﺮود.
ﻛﻨﺘﺮل :OpenFileDialog ﺗﻘﺮﻳﺒﺎً در ﻧﻮﺷﺘﻦ ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي ﺷﺮاﻳﻄﻲ وﺟﻮد دارد ﻛﻪ ﺑﺨﻮاﻫﻴﺪ داده ﻫﺎﻳﻲ را در ﻓﺎﻳﻞ ﻧﻮﺷﺘﻪ و ﻳﺎ از آن ﺑﺨﻮاﻧﻴﺪ ،ﭘـﺲ ﺑـﻪ ﻛﻨﺘﺮﻟﻲ ﻧﻴﺎز دارﻳﺪ ﺗﺎ ﺑﻪ وﺳﻴﻠﻪ ي آن ﺑﺘﻮاﻧﻴﺪ ﻓﺎﻳﻠﻲ را ﺑﺎز ﻛﻨﻴﺪ و ﻳﺎ داده ﻫﺎﻳﻲ را در ﻳﻚ ﻓﺎﻳـﻞ ذﺧﻴـﺮه ﻛﻨﻴـﺪ .در ﭼـﺎرﭼﻮب .NETدو ﻛﻨﺘﺮل ﺑﺮاي اﻳﻦ ﻣﻮارد در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ OpenFileDialog :و .SaveFileDialogدر اﻳﻦ ﺑﺨـﺶ ﺑـﻪ ﺑﺮرﺳﻲ ﻛﻨﺘﺮل OpenFileDialogﻣـﻲ ﭘـﺮدازﻳﻢ و در ﺑﺨـﺶ ﺑﻌـﺪ ﻧﻴـﺰ ﻛﻨﺘـﺮل SaveFileDialogرا ﺑﺮرﺳـﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي ﻣﺎﻧﻨﺪ Wordو ﻳﺎ Paintﻛﺎر ﻣﻲ ﻛﻨﻴﺪ ،ﻣﻌﻤﻮﻻ ﺑﺮاي ﺑﺎز ﻛﺮدن ﻳﻚ ﻓﺎﻳﻞ و ﻳـﺎ ذﺧﻴـﺮه آن و ﻳﺎ ...ﺑﺎ ﻣﺤﻴﻄﻲ ﻳﻜﺴﺎن روﺑﺮو ﻣﻲ ﺷﻮﻳﺪ .اﻳﻦ ﻧﻮع ﻛﺎدرﻫﺎ ،ﺑﻪ ﺻﻮرت ﻳﻚ ﻣﺠﻤﻮﻋﻪ ي اﺳﺘﺎﻧﺪارد در وﻳﻨﺪوز وﺟﻮد دارد و ﺑﺮﻧﺎﻣـﻪ ﻧﻮﻳـﺴﺎن ﻣﻲ ﺗﻮاﻧﻨﺪ از آﻧﻬﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻨﺪ. در .NETﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﭘﻨﺠﺮه Openاز اﻳﻦ ﻣﺠﻤﻮﻋﻪ ﺑﺎﻳـﺪ از ﻛـﻼس OpenFileDialogاﺳـﺘﻔﺎده ﻛـﺮد .ﺑـﺮاي اﺳﺘﻔﺎده از اﻳﻦ ﻛﻼس در .NETﻣﺎﻧﻨﺪ ﻫﺮ ﻛﻼس دﻳﮕﺮي ﺑﺎﻳﺪ ﻳﻚ ﻣﺘﻐﻴﺮ از آن اﻳﺠﺎد و ﺳﭙﺲ ﺧﺎﺻﻴﺘﻬﺎي آن را ﺑﻪ وﺳﻴﻠﻪ ﻛﺪ ﺗﻨﻈـﻴﻢ ﻛﺮد ،و ﻳﺎ ﻣﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﻓﺮم اﻳﻦ ﻛﻨﺘﺮل را در ﺑﺮﻧﺎﻣﻪ ﻗﺮار داده و از آن اﺳﺘﻔﺎده ﻛـﺮد .در ﻫـﺮ دو ﺣﺎﻟـﺖ ﺷﻴﺊ اﻳﺠﺎد ﺷﺪه داراي ﻣﺘﺪﻫﺎ ،روﻳﺪادﻫﺎ و ﺧﺎﺻﻴﺘﻬﺎي ﻳﻜﺴﺎن ﺧﻮاﻫﺪ ﺑﻮد. ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل در ﺟﻌﺒﻪ اﺑﺰار ،ﺑﺎﻳﺪ ﺑﻪ ﺑﺨﺶ Dialogsآن ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ و ﺑﺎ اﺳﺘﻔﺎده از ﻣﺎوس اﻳﻦ ﻛﻨﺘﺮل را ﺑﺮ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ .ﺑﻌﺪ از آن ﺗﻨﻬﺎ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﺪ ،اﻳﻦ اﺳﺖ ﻛﻪ ﺧﺎﺻﻴﺘﻬﺎي ﻣﻮرد ﻧﻈﺮﺗﺎن ﺑﻪ وﺳﻴﻠﻪ ﭘﻨﺠﺮه Properties ﺗﻨﻈﻴﻢ ﻛﺮده و ﺳﭙﺲ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ ﻧﻤﺎﻳﺶ آن را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ.
٢٥٩
ﺑﺮاي اﺳﺘﻔﺎده از ﻛﻨﺘﺮل OpenFileDialogﺑﻪ ﺻﻮرت ﻛﻼس ،اﺑﺘﺪا ﺑﺎﻳﺪ ﺷﻴﺊ از ﻧﻮع اﻳـﻦ ﻛـﻼس اﻳﺠـﺎد ﻛﻨﻴـﺪ .ﺳـﭙﺲ در ﻣﻮاﻗﻌﻲ ﻛﻪ ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل ﻧﻴﺎز داﺷﺘﻴﺪ ،ﺑﻪ اﻳﻦ ﺷﻴﺊ ﻣﻘﺪار ﺑﺪﻫﻴﺪ و از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﭘﺲ از ﭘﺎﻳﺎن اﺳﺘﻔﺎده ﻧﻴﺰ ﻣـﻲ ﺗﻮاﻧﻴـﺪ آن را ﻧـﺎﺑﻮد ﻛﻨﻴﺪ ﺗﺎ ﻣﻨﺎﺑﻊ اﺷﻐﺎل ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ آن آزاد ﺷﻮﻧﺪ. در اﻳﻦ ﻓﺼﻞ ﺑﺎ OpenFileDialogﺑﻪ ﺻﻮرت ﻳﻚ ﻛﻨﺘﺮل ﺑﺮﺧﻮرد ﻣﻲ ﻛﻨﻴﻢ .اﻣـﺎ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻛـﺎﻣﻼً ﻣﻔﻬـﻮم آن را درك ﻛﺮدﻳﺪ و ﺗﻮاﻧﺴﺘﻴﺪ ﺑﻪ راﺣﺘﻲ در ﺑﺮﻧﺎﻣﻪ از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ از اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﺻﻮرت ﻳﻚ ﻛـﻼس ﻧﻴـﺰ اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ .ﻣﻔﻬـﻮم ﻛﻼﺳﻬﺎ و ﻧﺤﻮه اﺳﺘﻔﺎده از آﻧﻬﺎ در ﻓﺼﻞ ﻧﻬﻢ ﺑﻪ ﻃﻮر ﻣﻔﺼﻞ ﺷﺮح داده ﺷﺪه اﻧﺪ. ﺑﺮاي ﻧﻤﺎﻳﺶ ﭘﻨﺠﺮه ي Openﻛﺎﻓﻲ اﺳﺖ ﻣﺘﺪ ShowDialogآن را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ ،ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﻨﺠـﺮه اي ﻣـﺸﺎﺑﻪ ﺷـﻜﻞ 6-7ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
ﺷﻜﻞ 6-7
ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل :OpenFileDialog اﮔﺮﭼﻪ ﻛﺎدر ﻣﺤﺎوره اي ﻧﻤﺎﻳﺶ داده ﺷﺪه در ﺷﻜﻞ 6-7ﻳﻚ ﺻﻔﺤﻪ Openاﺳﺘﺎﻧﺪارد در وﻳﻨﺪوز اﺳﺖ و ﻣﻌﻤﻮﻻً ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻳﻦ ﻛﺎدر را در ﺑﺮﻧﺎﻣﻪ اي ﻣـﺸﺎﻫﺪه ﻣـﻲ ﻛﻨﻴـﺪ ﻓﻘـﻂ ﻓﺎﻳﻠﻬـﺎي ﺧﺎﺻـﻲ در آن ﻧﻤـﺎﻳﺶ داده ﺷـﺪه اﺳـﺖ )ﺑـﺮاي ﻣﺜـﺎل اﻳـﻦ ﻛـﺎدر در ﺑﺮﻧﺎﻣـﻪ ي Notepadﻓﻘﻂ ﻓﺎﻳﻠﻬﺎي ﻣﺘﻨﻲ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ( ،اﻣﺎ در اﻳﻦ ﻛﺎدر ﻫﻴﭻ ﻣﺤﺪودﻳﺘﻲ در ﻧﻮع ﻓﺎﻳﻠﻬﺎي ﻗﺎﺑﻞ ﻧﻤﺎﻳﺶ دﻳﺪه ﻧﻤﻲ ﺷﻮد. در اﻳﻦ ﭘﻨﺠﺮه ﺗﻤﺎم ﻓﺎﻳﻠﻬﺎي ﻣﻮﺟﻮد در ﻓﻮﻟﺪر ﺟﺎري را ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ و ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻛﻪ ﭼـﻪ ﻧـﻮع ﻓﺎﻳﻠﻬـﺎﻳﻲ را ﻧﻤـﺎﻳﺶ دﻫﺪ .ﺑﺮاي ﻓﻴﻠﺘﺮ ﻛﺮدن ﻧﻮع ﻓﺎﻳﻠﻬﺎي ﻧﻤﺎﻳﺶ داده ﺷﺪه در اﻳﻦ ﻛﺎدر ﺑﺎﻳﺪ از ﺧﺎﺻﻴﺘﻬﺎي اﻳﻦ ﻛﻨﺘﺮل اﺳﺘﻔﺎده ﻛﺮده و آﻧﻬﺎ را ﺑﻪ ﻧﺤﻮي ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ﻛﻪ ﻛﺎدر ،ﻓﺎﻳﻠﻬﺎي ﻣﻮرد ﻧﻈﺮ ﺷﻤﺎ را ﻧﻤﺎﻳﺶ دﻫﺪ.
٢٦٠
اﻟﺒﺘﻪ اﻳﻦ ﻳﻜﻲ از ﻣﻮاردي اﺳﺖ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺘﻬﺎي اﻳﻦ ﻛﻨﺘﺮل ﻗﺎﺑﻞ ﺗﻨﻈﻴﻢ اﺳﺖ .در ﺟﺪول زﻳﺮ ﻟﻴﺴﺘﻲ از ﺧﺎﺻﻴﺘﻬﺎي ﭘﺮ ﻛـﺎرﺑﺮد اﻳﻦ ﻛﻨﺘﺮل را ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ: ﺧﺎﺻﻴﺖ
ﺷﺮح
AddExtension
اﻳﻦ ﺧﺎﺻﻴﺖ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ اﮔﺮ ﻛﺎرﺑﺮ ﭘﺴﻮﻧﺪي را ﺑـﺮاي ﻓﺎﻳـﻞ ﻣـﺸﺨﺺ ﻧﻜـﺮد، ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻃﻮر اﺗﻮﻣﺎﺗﻴﻚ ﭘﺴﻮﻧﺪ را ﺑﻪ ﻓﺎﻳﻞ اﺿﺎﻓﻪ ﻛﻨﺪ ﻳﺎ ﻧﻪ؟ اﻳﻦ ﻣﻮرد ﺑﻴﺸﺘﺮ در ﭘﻨﺠـﺮه SaveFileDialogﻛﻪ در ﺑﺨﺶ ﺑﻌﺪ ﺗﻮﺿﻴﺢ داده ﺧﻮاﻫﺪ ﺷﺪ اﺳﺘﻔﺎده ﻣـﻲ ﺷﻮد.
CheckFileExist
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ اﮔﺮ ﻛﺎرﺑﺮ آدرس ﻓﺎﻳﻠﻲ را وارد ﻛﺮد ﻛﻪ وﺟـﻮد ﻧﺪاﺷـﺖ ،ﺑﺮﻧﺎﻣـﻪ ﭘﻴﻐـﺎم ﺧﻄﺎﻳﻲ را ﻧﻤﺎﻳﺶ ﺑﺪﻫﺪ ﻳﺎ ﻧﻪ؟
CheckPathExist
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ اﮔﺮ ﻛﺎرﺑﺮ آدرس ﻣﺴﻴﺮي را وارد ﻛﺮد ﻛﻪ وﺟﻮد ﻧﺪاﺷﺖ ،ﺑﺮﻧﺎﻣـﻪ ﭘﻴﻐـﺎم ﺧﻄﺎﻳﻲ را ﻧﻤﺎﻳﺶ ﺑﺪﻫﺪ ﻳﺎ ﻧﻪ؟
DefaultExt
ﭘﺴﻮﻧﺪ ﭘﻴﺶ ﻓﺮض را ﺑﺮاي ﻓﺎﻳﻞ اﻧﺘﺨﺎب ﺷﺪه ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ.
DereferenceLinks
ﺑﺎ ﺷﻮرت ﻛﺎت ﻫﺎ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد و ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ اﮔﺮ ﻛﺎرﺑﺮ ﻳﻚ ﺷﻮرت ﻛـﺎت را اﻧﺘﺨﺎب ﻛﺮد ،ﻣﺴﻴﺮ ﻓﺎﻳﻞ اﺻﻠﻲ ﺑﺮﮔﺸﺖ داده ﺷﻮد ) (Trueو ﻳﺎ ﻣﺴﻴﺮ ﺧـﻮد ﻓﺎﻳـﻞ ﺷﻮرت ﻛﺎت ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﺑﺮﮔﺮدد).(False
FileName
ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻧﺎم ﻓﺎﻳﻠﻲ اﺳﺖ ﻛﻪ در اﻳﻦ ﭘﻨﺠﺮه اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ.
FileNames
ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻧﺎم ﻓﺎﻳﻠﻬﺎﻳﻲ اﺳﺖ ﻛﻪ در اﻳﻦ ﭘﻨﺠﺮه اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ .اﻳﻦ ﺧﺎﺻﻴﺖ از ﻧﻮع ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ اﺳﺖ.
Filter
اﻳﻦ ﺧﺎﺻﻴﺖ ﺣﺎوي رﺷﺘﻪ اي اﺳﺖ ﻛﻪ ﺑﺮاي ﻓﻴﻠﺘﺮ ﻛﺮدن ﻓﺎﻳﻠﻬﺎﻳﻲ ﻛـﻪ ﺑﺎﻳـﺪ در ﭘﻨﺠـﺮه Openﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ ﺑﻪ ﻛﺎر ﻣﻲ رود .ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ رﺷـﺘﻪ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ،ﭼﻨـﺪﻳﻦ ﮔﺮوه ﻓﻴﻠﺘﺮ را ﺑﺮاي اﻳﻦ ﭘﻨﺠﺮه ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﺗﺎ در ﺟﻌﺒﻪ ﺗﺮﻛﻴﺒﻲ ﻣﻮﺟﻮد در اﻳﻦ ﭘﻨﺠـﺮه ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ و ﻛﺎرﺑﺮ ﺑﺘﻮاﻧﺪ ﻳﻜﻲ از آﻧﻬﺎ را اﻧﺘﺨﺎب ﻛﻨﺪ.
FilterIndex
ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﺷﻤﺎره ﻓﻴﻠﺘﺮي اﺳﺖ ﻛﻪ ﻛﺎرﺑﺮ ﻫﻢ اﻛﻨﻮن در اﻳﻦ ﺻﻔﺤﻪ اﻧﺘﺨـﺎب ﺷـﺪه اﺳﺖ.
InitialDirectory
ﻣﺸﺨﺺ ﻛﻨﻨﺪه آدرس ﻣﺴﻴﺮي اﺳﺖ ﻛﻪ ﺑﺎﻳﺪ در اﺑﺘﺪا ،در ﭘﻨﺠﺮه Openﻧﻤـﺎﻳﺶ داده ﺷﻮد.
Multiselect
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳﺎ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﭼﻨﺪﻳﻦ ﻓﺎﻳﻞ را در اﻳﻦ ﭘﻨﺠﺮه اﻧﺘﺨﺎب ﻛﻨﺪ و ﻳﺎ ﻧﻪ؟
ReadOnlyChecked
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳﺎ ﻗﺴﻤﺖ ReadOnlyدر ﭘﻨﺠﺮه Openاﻧﺘﺨﺎب ﺷﺪه اﺳـﺖ و ﻳﺎ ﻧﻪ؟
RestoreDirectory
ﺗﻌﻴﻴﻦ ﻣﻲ ﻛﻨﺪ آﻳﺎ ﻛﺎدر Openﺑﺎﻳﺪ آدرس ﻣﺴﻴﺮي ﻛﻪ ﻗﺒﻞ از ﺑﺴﺘﻪ ﺷﺪن در آن ﻗﺮار داﺷﺖ را ﺑﺮﮔﺮداﻧﺪ ﻳﺎ ﻧﻪ؟
ShowHelp
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳﺎ دﻛﻤﻪ Helpﻧﻴﺰ در ﭘﻨﺠﺮه Openﻧﻤﺎﻳﺶ داده ﺷﻮد ﻳﺎ ﻧﻪ؟
٢٦١
ShowReadOnly
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳﺎ اﻣﻜﺎن ﺗﻌﻴﻴﻦ اﻳﻦ ﻛﻪ ﻓﺎﻳﻞ ﺑﻪ ﺻﻮرت ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ ﺑﺎز ﺷﻮد ﺑﺮاي ﻛﺎرﺑﺮ وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ ﻳﺎ ﻧﻪ؟
Title
ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻣﺘﻨﻲ اﺳﺖ ﻛﻪ در ﻧﻮار ﻋﻨﻮان ﭘﻨﺠﺮه Openﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
ValidateNames
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ آﻳﺎ ﭘﻨﺠﺮه ﻓﻘﻂ ﺑﺎﻳﺪ ﻧﺎم ﻓﺎﻳﻠﻬﺎي ﻣﻌﺘﺒﺮ وﻳﻨﺪوزي را ﻗﺒﻮل ﻛﻨﺪ و ﻳﺎ ﻫﺮ ﻧﺎﻣﻲ را ﻣﻲ ﺗﻮاﻧﺪ درﻳﺎﻓﺖ ﻛﻨﺪ؟
ﻣﺘﺪﻫﺎي :OpenFileDialog اﮔﺮﭼﻪ ﻣﺘﺪﻫﺎي زﻳﺎدي در ﻛﻨﺘﺮل OpenFileDialogوﺟـﻮد دارﻧـﺪ ،اﻣـﺎ در ﻣﺜـﺎل ﻫـﺎي اﻳـﻦ ﺑﺨـﺶ ﺑﻴـﺸﺘﺮ ﺑـﺮ روي ﻣﺘـﺪ ShowDialogﺗﻤﺮﻛﺰ ﺧﻮاﻫﻴﻢ ﻛﺮد .در ﻟﻴﺴﺖ زﻳﺮ ،ﻧﺎم و ﺷﺮح اﺳﺘﻔﺎده ﺑﻌﻀﻲ از ﺗﻮاﺑﻊ ﭘﺮ ﻛﺎرﺑﺮد اﻳﻦ ﻛﻨﺘﺮل آﻣﺪه اﺳﺖ:
:Disposeﺣﺎﻓﻈﻪ اﺷﻐﺎل ﺷﺪه ﺗﻮﺳﻂ اﻳﻦ ﻛﻨﺘﺮل را آزاد ﻣﻲ ﻛﻨﺪ. :OpenFileﻓﺎﻳﻠﻲ را ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻛﺎرﺑﺮ در ﭘﻨﺠﺮه Openاﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ﺑﻪ ﺻﻮرت ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ ﺑﺎز ﻣﻲ ﻛﻨﺪ. ﻧﺎم ﻓﺎﻳﻞ ﺑﻪ وﺳﻴﻠﻪ ﺧﺎﺻﻴﺖ FileNameﻣﺸﺨﺺ ﻣﻲ ﺷﻮد. :Resetﻣﻘﺪار ﺗﻤﺎم ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل OpenFileDialogرا ﺑﻪ ﺣﺎﻟﺖ اوﻟﻴﻪ ﺑﺮﻣﻲ ﮔﺮداﻧﺪ. :ShowDialogﻛﺎدر ﻣﺤﺎوره اي ﭘﻨﺠﺮه Openرا ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
اﺳﺘﻔﺎده از ﺗﺎﺑﻊ ShowDialogﺑﺴﻴﺎر واﺿﺢ اﺳﺖ ،زﻳﺮا اﻳﻦ ﻣﺘﺪ ﻫﻴﭻ ﭘﺎراﻣﺘﺮي را ﺑﻪ ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻧﻤـﻲ ﻛﻨـﺪ .ﺑﻨـﺎﺑﺮاﻳﻦ ﻗﺒﻞ از اﻳﻨﻜﻪ اﻳﻦ ﺗﺎﺑﻊ را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ ﺗﻤﺎم ﺧﺎﺻﻴﺘﻬﺎي ﻣﻮردﻧﻈﺮ را در ﻛﻨﺘﺮل ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ .ﺑﻌﺪ از اﻳﻨﻜﻪ ﭘﻨﺠـﺮه Openﻧﻤـﺎﻳﺶ داده ﺷﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ ﺑﺮرﺳﻲ ﻣﻘﺪار ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻛﻪ ﭼﻪ ﻓﺎﻳﻞ و ﻳﺎ ﭼﻪ ﻓﺎﻳﻠﻬﺎﻳﻲ ،در ﭼﻪ ﻣﺴﻴﺮﻫﺎﻳﻲ اﻧﺘﺨﺎب ﺷﺪه اﻧﺪ. ﻳﻚ ﻧﻤﻮﻧﻪ از ﻓﺮاﺧﻮاﻧﻲ اﻳﻦ ﻣﺘﺪ در ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﺳﺖ: ;)(openFileDialog1.ShowDialog اﻳﻦ ﻣﺘﺪ ﻣﻘﺪاري از ﻧﻮع ﺷﻤﺎرﻧﺪه ي DialogResultﺑﻪ ﺻﻮرت OKو ﻳﺎ Cancelﺑﺮﻣﻲ ﮔﺮداﻧﺪ .ﻣﻘﺪار OKﺑـﻪ ﻣﻌﻨـﻲ ﻛﻠﻴﻚ ﻛﺮدن ﻛﺎرﺑﺮ ﺑﺮ روي دﻛﻤﻪ ي Openو ﻣﻘﺪار Cancelﺑﺮاﺑﺮ ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي Cancelاﺳﺖ .ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷـﻴﺪ ﻛﻪ اﻳﻦ ﻛﻨﺘﺮل ﻫﻴﭻ ﻓﺎﻳﻠﻲ را ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﺎز ﻧﻤﻲ ﻛﻨﺪ و ﻳﺎ ﻣﺤﺘﻮﻳﺎت آن را ﻧﻤﻲ ﺧﻮاﻧﺪ .اﻳﻦ ﻛﻨﺘﺮل ﻓﻘﻂ راﺑﻄﻲ اﺳﺖ ﻛﻪ ﺑﻪ ﻛـﺎرﺑﺮ اﺟـﺎزه ﻣﻲ دﻫﺪ ﻳﻚ ﻳﺎ ﭼﻨﺪ ﻓﺎﻳﻞ را ﺑﺮاي ﺑﺎز ﺷﺪن ﺑﻪ وﺳﻴﻠﻪ ي ﺑﺮﻧﺎﻣﻪ ﻣﺸﺨﺺ ﻛﻨﺪ .ﺑﻌـﺪ از اﻳـﻦ ﻣﺮﺣﻠـﻪ ،ﺷـﻤﺎ ﺑﺎﻳـﺪ در ﺑﺮﻧﺎﻣـﻪ ﻧـﺎم و آدرس ﻓﺎﻳﻠﻬﺎي ﻣﺸﺨﺺ ﺷﺪه ﺗﻮﺳﻂ ﻛﺎرﺑﺮ را ﺑﻪ وﺳﻴﻠﻪ ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل OpenFileDialogﺑﺪﺳـﺖ آورده و ﺳـﭙﺲ آﻧﻬـﺎ را ﺑـﺎز ﻛﻨﻴﺪ.
اﺳﺘﻔﺎده از ﻛﻨﺘﺮل :OpenFileDialog ﺣﺎل ﻛﻪ ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي ﻣﻬﻢ ﻛﻨﺘﺮل OpenFileDialogرا ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ ،ﺑﻬﺘﺮ اﺳﺖ از اﻳﻦ ﻛﻨﺘﺮل در ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ اﺳﺘﻔﺎده ﻛﻨﻴﻢ ﺗﺎ ﺑﺎ ﻧﺤﻮه اﺳﺘﻔﺎده از آن در ﺑﺮﻧﺎﻣﻪ آﺷﻨﺎ ﺷﻮﻳﻢ.
٢٦٢
در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل OpenFileDialogﺑﺮﻧﺎﻣﻪ اي ﺧﻮاﻫﻴﺪ ﻧﻮﺷﺖ ﻛﻪ ﻛـﺎرﺑﺮ ﺑﺘﻮاﻧـﺪ در آن ﻳـﻚ ﻓﺎﻳـﻞ ﻣﺘﻨﻲ را ﻣﺸﺨﺺ ﻛﻨﺪ و ﺑﺮﻧﺎﻣﻪ ﻣﺤﺘﻮﻳﺎت آن ﻓﺎﻳﻞ را در ﻳﻚ TextBoxﻧﻤﺎﻳﺶ دﻫﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻛﺎر ﺑﺎ ﻛﻨﺘﺮل OpenFileDialog (1در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﻚ ﭘﺮوژه وﻳﻨﺪوزي ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم Dialogsاﻳﺠﺎد ﻛﻨﻴﺪ. (2ﺑﺮاي ﺗﻐﻴﻴﺮ ﻧﺎم ﻓﺮم ﺧﻮد ،در ﭘﻨﺠﺮه Solution Explorerﺑﺮ روي ﻧﺎم ﻓﺮم ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ Renameرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺳﭙﺲ ﻧﺎم ﻓﺮم را ﺑـﻪ Dialogs.csﺗﻐﻴﻴـﺮ دﻫﻴـﺪ .ﺑـﺎ اﺳـﺘﻔﺎده از ﭘﻨﺠـﺮه Propertiesﺧﺎﺻﻴﺘﻬﺎي ﻓﺮم را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ:
ﺧﺎﺻﻴﺖ Sizeآن را ﺑﺮاﺑﺮ ﺑﺎ 456;304ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ StartPositionرا ﺑﺮاﺑﺮ ﺑﺎ CenterScreenﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textرا ﺑﺮاﺑﺮ ﺑﺎ Dialogsﻗﺮار دﻫﻴﺪ.
(3ﺑﺮاي اﻳﻦ ﻛﻪ ﻓﺎﻳﻞ ﻣﺸﺨﺺ ﺷﺪه ﺗﻮﺳﻂ ﻛﺎرﺑﺮ را در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ دﻫﻴﺪ ،ﺑﻪ ﻳﻚ ﻛﻨﺘﺮل TextBoxﻧﻴﺎز دارﻳﺪ .ﻫﻤﭽﻨﻴﻦ ﺑﺎﻳﺪ ﻳﻚ ﻛﻨﺘﺮل Buttonﻧﻴﺰ ﺑﺮ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ ﺗﺎ ﻛﺎرﺑﺮ ﺑـﻪ وﺳـﻴﻠﻪ آن ﺑﺘﻮاﻧـﺪ ﭘﻨﺠـﺮه Openرا ﻧﻤـﺎﻳﺶ دﻫـﺪ. ﺑﻨﺎﺑﺮاﻳﻦ ﻳﻚ ﻛﻨﺘﺮل TextBoxو ﻳﻚ ﻛﻨﺘﺮل Buttonﺑﻪ ﻓﺮم ﺧﻮد اﺿﺎﻓﻪ ﻛـﺮده و ﺧﺎﺻـﻴﺘﻬﺎي آن را ﺑـﺮ اﺳـﺎس ﻟﻴﺴﺖ زﻳﺮ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ Nameﻛﻨﺘﺮل TextBoxرا ﺑﺮاﺑﺮ ﺑﺎ ،txtFileﺧﺎﺻﻴﺖ Anchorرا ﺑﺮاﺑﺮ ﺑﺎ ،Top Right،Left،Bottomﺧﺎﺻﻴﺖ Locationرا ﺑﺮاﺑﺮ ﺑﺎ 8,8ﺧﺎﺻﻴﺖ MultiLineرا ﺑﺮاﺑﺮ ﺑﺎ Trueﺧﺎﺻﻴﺖ ScrollBarsرا ﺑﺮاﺑﺮ ﺑـﺎ Verticalو ﺧﺎﺻـﻴﺖ Sizeرا ﺑﺮاﺑـﺮ ﺑـﺎ 352;264ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Nameدﻛﻤﻪ ﻓﺮﻣﺎن را ﺑﺮاﺑﺮ ﺑﺎ btnOpenﺧﺎﺻـﻴﺖ Textآن را ﺑﺮاﺑـﺮ ﺑـﺎ Openﺧﺎﺻـﻴﺖ Anchorرا ﺑﺮاﺑﺮ ﺑﺎ Top,Rightو ﺧﺎﺻﻴﺖ Locationرا ﺑﺮاﺑﺮ ﺑﺎ 367,8ﻗﺮار دﻫﻴﺪ.
(4ﺑﻌﺪ از اﻳﻨﻜﻪ ﻛﻨﺘﺮل ﻫﺎ را در ﻓﺮم ﻗﺮار دادﻳﺪ و ﺧﺎﺻﻴﺖ آﻧﻬﺎ را ﻃﺒﻖ ﻟﻴﺴﺖ ﻗﺒﻠﻲ ﺗﻨﻈﻴﻢ ﻛﺮدﻳﺪ ،ﻓﺮم ﺑﺮﻧﺎﻣـﻪ ﺷـﻤﺎ ﺑﺎﻳـﺪ ﻣـﺸﺎﺑﻪ ﺷﻜﻞ 7-7ﺷﺪه ﺑﺎﺷﺪ.
٢٦٣
ﺷﻜﻞ 7-7 ﻧﻜﺘﻪ :ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺧﺎﺻﻴﺖ Anchorرا ﺑﺮاي ﻛﻨﺘﺮﻟﻬﺎي اﻳﻦ ﻓﺮم ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ ،ﺑﺎ ﺗﻐﻴﻴﺮ اﻧﺪازه ﻓﺮم ﺑﻪ وﺳﻴﻠﻪ ﻛﺎرﺑﺮ اﻧﺪازه ﻛﻨﺘـﺮل ﻫـﺎ ﻧﻴﺰ ﺑﻪ ﺻﻮرت ﻣﺘﻨﺎﺳﺐ ﺗﻐﻴﻴﺮ ﺧﻮاﻫﺪ ﻛﺮد. (5در ﻧﻮار اﺑﺰار ﺑﻪ ﻗﺴﻤﺖ Dialogsﺑﺮوﻳﺪ ،ﻛﻨﺘﺮل FileOpenDialogرا اﻧﺘﺨﺎب ﻛﺮده و ﺑـﺮ روي آن دو ﺑـﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﻗﺴﻤﺖ ﭘﺎﻳﻴﻦ ﻣﺤﻴﻂ ﻃﺮاﺣﻲ وﻳﮋوال اﺳﺘﻮدﻳﻮ اﺿﺎﻓﻪ ﺧﻮاﻫﺪ ﺷﺪ .ﺣـﺎل ﻣـﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ ﻛﻨﺘﺮل را در اﻳﻦ ﻗﺴﻤﺖ اﻧﺘﺨﺎب ﻛﺮده و ﺧﺎﺻﻴﺘﻬﺎي ﻣﺨﺘﻠﻒ آن را ﺑﻪ وﺳﻴﻠﻪ ﭘﻨﺠﺮه Propertiesﺗﻨﻈـﻴﻢ ﻛﻨﻴﺪ .ﺑﺎ وﺟﻮد اﻳﻦ ﻓﻌﻼً ﻧﺎم و ﺧﺎﺻﻴﺘﻬﺎي ﭘﻴﺶ ﻓﺮض اﻳﻦ ﻛﻨﺘـﺮل را ﻗﺒـﻮل ﻛﻨﻴـﺪ .در ﻗـﺴﻤﺘﻬﺎي ﺑﻌـﺪي ﺑـﺎ اﺳـﺘﻔﺎده از ﻛـﺪ ﺧﺎﺻﻴﺘﻬﺎي ﻣﻮرد ﻧﻈﺮ را در اﻳﻦ ﻛﻨﺘﺮل ﺗﻐﻴﻴﺮ ﺧﻮاﻫﻴﻢ داد. (6ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﺑﺮوﻳﺪ و در اﺑﺘﺪاي ﻛﻼس ﻣﺮﺑﻮط ﺑﻪ ﻓﺮم ،ﻳﻚ ﻣﺘﻐﻴﺮ رﺷﺘﻪ اي ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ﺗﺎ ﻧﺎم ﻓﺎﻳﻞ در آن ذﺧﻴﺮه ﺷﻮد .در ﻗﺴﻤﺘﻬﺎي ﺑﻌﺪي ﺑﺮﻧﺎﻣﻪ ،ﻧﺎم ﻓﺎﻳﻠﻲ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻛﺎدر Openﺑﺮﮔﺸﺘﻪ ﻣﻲ ﺷﻮد را در اﻳـﻦ ﻣﺘﻐﻴﻴـﺮ ذﺧﻴـﺮه ﺧـﻮاﻫﻴﻢ ﻛﺮد: public partial class Dialogs : Form { // Declare variables ;private string strFileName (7ﺣﺎل ﺑﺎﻳﺪ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﺑﺎز ﻛﺮدن ﻛﺎدر Openرا در روﻳﺪاد ﻛﻠﻴﻚ ﻛﻨﺘﺮل btnOpenﻗﺮار دﻫﻴﻢ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﺑـﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮوﻳﺪ و ﺑﺮ روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴـﻚ آن اﻳﺠـﺎد ﺷـﻮد .ﺳـﭙﺲ ﻛﺪﻫﺎي ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )private void btnOpen_Click(object sender, EventArgs e { // Set the OpenFileDialog properties
٢٦٤
"|openFileDialog1.Filter = "Text files (*.txt) |*.txt ;"*+ " All files (*.*) |*. ;openFileDialog1.FilterIndex = 1 ;"openFileDialog1.Title = "Demo Open File Dialog // Show the OpenFileDialog and if the user clicks the // Open button, load the file )if (openFileDialog1.ShowDialog() == DialogResult.OK { // Save the file name ;strFileName = openFileDialog1.FileName // Read the contents of the file = txtFile.Text ;)System.IO.File.ReadAllText(strFileName } } (8ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﺮم اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﺷﺪ ،ﺑﺮ روي دﻛﻤﻪ ي Openﻛﻠﻴﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﻛـﺎدر ﻣﺤﺎوره اي Openﻧﻤﺎﻳﺶ داده ﺷﻮد .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﻋﻨﻮان اﻳﻦ ﻛﺎدر ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻛﺪ ﻣﺸﺨﺺ ﻛﺮده ﺑﻮدﻳﺪ ﺗﻐﻴﻴﺮ ﻛـﺮده اﺳﺖ .در ﺟﻌﺒﻪ ﺗﺮﻛﻴﺒﻲ Files of type:در ﭘﺎﻳﻴﻦ ﻛﺎدر ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ دو ﻧﻮع ﻓﻴﻠﺘﺮ ﺑـﺮاي ﻧﻤﺎﻳﺶ ﻓﺎﻳﻠﻬﺎ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ. (9ﻳﻜﻲ از ﻓﻴﻠﺘﺮﻫﺎي ﻧﻤﺎﻳﺶ داده ﺷﺪه در اﻳﻦ ﻗﺴﻤﺖ را اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺳﭙﺲ ﻳﻚ ﻓﺎﻳﻞ ﻣﺘﻨﻲ را در دﻳﺴﻚ ﻣﺸﺨﺺ ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ Openﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 8-7ﻣﺤﺘﻮﻳﺎت ﻓﺎﻳﻞ در ﻓـﺮم ﻧﻤـﺎﻳﺶ داده ﺧﻮاﻫـﺪ ﺷﺪ. (10ﺑﺮاي اﻣﺘﺤﺎن ،از ﺑﺮﻧﺎﻣﻪ ﺧﺎرج ﺷﻮﻳﺪ و ﻣﺠﺪداً آن را اﺟﺮا ﻛﻨﻴـﺪ .ﺳـﭙﺲ ﺑـﺮ روي دﻛﻤـﻪ ي Openﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻛﺎدر Openداﻳﺮﻛﺘﻮري را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ ﻛﻪ در اﺟﺮاي ﻗﺒﻠﻲ ﺑﺮﻧﺎﻣﻪ ﻓﺎﻳﻞ را از آن اﻧﺘﺨﺎب ﻛﺮدﻳﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻗﺒﻞ از ﻧﻤﺎﻳﺶ دادن ﻛﺎدر ﻣﺤﺎوره اي Openﺑﺎﻳﺪ ﺑﻌﻀﻲ از ﺧﺼﻮﺻﻴﺎت آن را ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ﺗﺎ ﻛﺎدر ﺑـﻪ ﻧﺤـﻮي ﻣﻨﺎﺳـﺐ ﺑـﺮاي ﺑﺮﻧﺎﻣـﻪ ﻧﻤﺎﻳﺶ داده ﺷﻮد .اوﻟﻴﻦ ﺧﺎﺻﻴﺘﻲ ﻛﻪ ﺑﺎﻳﺪ ﺗﻨﻈﻴﻢ ﺷﻮد ،ﺧﺎﺻﻴﺖ Filterاﺳﺖ .اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣﻲ دﻫﺪ ﻓﻴﻠﺘﺮﻫـﺎﻳﻲ ﻛـﻪ در ﺟﻌﺒﻪ ﺗﺮﻛﻴﺒﻲ Files of type:در ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ را ﻣﺸﺨﺺ ﻛﻨﻴﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﻳﻚ ﻓﻴﻠﺘﺮ ﺑﺮاي ﭘﺴﻮﻧﺪي ﺧﺎص اﻳﺠﺎد ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ اﺑﺘﺪا ﺗﻮﺿﻴﺢ آن ﻓﻴﻠﺘﺮ را وارد ﻛﺮده ،ﺳﭙﺲ ﻳﻚ ﺧﻂ ﻋﻤﻮدي )|( ﻗﺮار دﻫﻴﺪ و در اﻧﺘﻬﺎ ﻧﻴﺰ ﭘـﺴﻮﻧﺪ ﻓﺎﻳـﻞ را وارد ﻛﻨﻴﺪ .اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﭼﻨﺪﻳﻦ ﻓﻴﻠﺘﺮ در اﻳﻦ ﻛﺎدر وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﻨﺪ ،ﺑﺎﻳﺪ ﻫﺮ ﻳﻚ از آﻧﻬﺎ ﺑﻪ وﺳﻴﻠﻪ ﻳﻚ ﺧﻂ ﻋﻤﻮدي از ﻳﻜـﺪﻳﮕﺮ ﺟـﺪا ﻛﻨﻴﺪ.
٢٦٥
ﺷﻜﻞ 8-7
// Set the OpenFileDialog properties = openFileDialog1.Filter ;"*"Text files (*.txt) |*.txt| All files (*.*) |*. دوﻣﻴﻦ ﺧﺎﺻﻴﺘﻲ ﻛﻪ ﺑﺎﻳﺪ ﺗﻨﻈﻴﻢ ﺷﻮد ،ﺧﺎﺻﻴﺖ FilterIndexاﺳﺖ ﻛﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﺪام ﻓﻴﻠﺘﺮ ﺑﺎﻳـﺪ ﺑـﻪ ﺻـﻮرت ﭘـﻴﺶ ﻓﺮض در ﻓﺮم در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﻮد .ﻣﻘﺪار 1ﺑﺮاي اﻳﻦ ﺧﺎﺻﻴﺖ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻓﻴﻠﺘﺮ اول ﺑﻪ ﻋﻨﻮان ﻓﻴﻠﺘﺮ ﭘﻴﺶ ﻓﺮض در ﻧﻈﺮ ﮔﺮﻓﺘـﻪ ﻣﻲ ﺷﻮد. ;openFileDialog1.FilterIndex = 1 در اﻧﺘﻬﺎ ﻧﻴﺰ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ Titleﻋﻨﻮان ﭘﻨﺠﺮه Openرا ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻴﻢ: ;"openFileDialog1.Title = "Demo Open File Dialog ﺑﺮاي ﻧﻤﺎﻳﺶ ﻛﺎدر Openﺑﺎﻳﺪ از ﺗﺎﺑﻊ Showاﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ اﻳﻦ ﺗﺎﺑﻊ ﻣﻘﺪاري از ﻧـﻮع DialogResult را ﺑﺮﻣﻴﮕﺮداﻧﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺮاﺑﺮ ﺑﺎ DialogResult.OKو ﻳﺎ DialogResult.Cancelﺑﺎﺷﺪ .اﮔﺮ ﻛﺎرﺑﺮ در ﭘﻨﺠﺮه Openﺑﺮ روي دﻛﻤﻪ Openﻛﻠﻴﻚ ﻛﻨﺪ ﻣﻘﺪار DialogResult.OKﺗﻮﺳﻂ ﺗﺎﺑﻊ ﺑﺮﮔﺮداﻧﺪه ﻣﻲ ﺷﻮد .در ﺻﻮرﺗﻲ ﻛﻪ ﻛﺎرﺑﺮ دﻛﻤﻪ Cancelرا اﻧﺘﺨﺎب ﻛﻨﺪ ﻣﻘﺪار ﺑﺎزﮔﺸﺘﻲ ﺑﺮاﺑﺮ ﺑﺎ DialogResult.Cancelﺧﻮاﻫﺪ ﺑﻮد. // Show the OpenFileDialog and if the user clicks the // Open button, load the file )if (openFileDialog1.ShowDialog() == DialogResult.OK
٢٦٦
در ﭼﺎرﭼﻮب ،.NETﻓﻀﺎي ﻧﺎم System.IOداراي ﺗﻤﺎم ﺗﻮاﺑﻊ و ﻛﻼﺳﻬﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﻛﻨﺘﺮل ورودي و ﺧﺮوﺟﻲ ﻣﻲ ﺑﺎﺷﺪ. ﺑﺮاي درﻳﺎﻓﺖ اﻃﻼﻋﺎت درون ﻓﺎﻳﻞ ﻣﺘﻨﻲ ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻛﻼس Fileدر اﻳﻦ ﻓﻀﺎي ﻧﺎم اﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﮔﺮ ﻳﻚ ﻓﻀﺎي ﻧﺎم ﺑﺎ اﺳـﺘﻔﺎده از دﺳﺘﻮر usingدر اﺑﺘﺪاي ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﻛﻼس ﻣﺸﺨﺺ ﺷﻮد ،در ﻃﻮل ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗـﻮان ﺑـﺪون ذﻛـﺮ ﻛـﺮدن ﻓـﻀﺎي ﻧـﺎم ،از ﻛﻼﺳﻬﺎي داﺧﻞ آن اﺳﺘﻔﺎده ﻛﺮد .1ﺑﺮاي ﻣﺜﺎل ﻛﻼس MessageBoxﻛﻪ ﺑﺮاي ﻧﻤﺎﻳﺶ ﻛﺎدر ﭘﻴﻐﺎم از آن اﺳـﺘﻔﺎده ﻣـﻲ ﻛﻨـﻴﻢ در ﻓﻀﺎي ﻧﺎم System.Windows.Formsﻗﺮار دارد .اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺒﻠﻲ ﻧﻴﺰ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﺑﺪون اﻳﻨﻜﻪ ﻓﻀﺎي ﻧﺎم اﻳـﻦ ﻛـﻼس را ﻣـﺸﺨﺺ ﻛﻨـﻴﻢ از آن در ﺑﺮﻧﺎﻣـﻪ اﺳـﺘﻔﺎده ﻛـﺮده اﻳـﻢ .اﻳـﻦ ﻣـﻮرد ﺑـﻪ اﻳـﻦ ﻋﻠـﺖ اﺳـﺖ ﻛـﻪ ﻓـﻀﺎي ﻧـﺎم System.Windows.Formsﺑﺎ اﺳﺘﻔﺎده از راﻫﻨﻤﺎي usingدر اﺑﺘﺪاي ﻛﺪ )ﻗﺒﻞ از ﺗﻌﺮﻳﻒ ﻛﻼس( ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿـﺎﻓﻪ ﺷﺪه اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ در ﻃﻮل ﺑﺮﻧﺎﻣﻪ ﺑﺮاي اﺳﺘﻔﺎده از اﻳﻦ ﻛﻼس ﻧﻴﺎزي ﺑﻪ ذﻛﺮ ﻛﺮدن ﻓﻀﺎي ﻧﺎم آن ﻧﺪارﻳﻢ. اﻣﺎ در ﻣﻮرد ﻛﻼس Fileاﮔﺮ ﺑﻪ اﺑﺘﺪاي ﻛﺪ ﻧﮕﺎه ﻛﻨﻴﺪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻓﻀﺎي ﻧﺎم ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛﻼس ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻧـﺸﺪه اﺳﺖ ،ﭘﺲ ﺑﺮاي اﺳﺘﻔﺎده از آن ﺑﺎﻳﺪ ﻧﺎم ﻛﻼس را ﺑﻪ ﻫﻤﺮاه ﻓﻀﺎي ﻧﺎم آن ﻳﻌﻨﻲ ﺑﻪ ﺻﻮرت System.IO.Fileﺑﻪ ﻛﺎر ﺑﺒﺮﻳﻢ. // Read the contents of the file = txtFile.Text ;)System.IO.File.ReadAllText(strFileName ﺑﺎ اﺳﺘﻔﺎده از ﺗﺎﺑﻊ ReadAllTextدر ﻛﻼس System.IO.Fileﻣﻲ ﺗﻮاﻧﻴﻢ ﻣﺤﺘﻮﻳﺎت ﻳﻚ ﻓﺎﻳﻞ ﻣﺘﻨﻲ را از دﻳﺴﻚ ﺑﺨﻮاﻧﻴﻢ .دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﺗﺎﺑﻊ ReadAllTextﺑﻪ ﮔﻮﻧﻪ اي ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ ﻛﻪ ﺑﺮاي اﺳﺘﻔﺎده از آن ﻻزم ﻧﻴﺴﺖ اﺑﺘﺪا ﻳـﻚ ﺷـﻴﺊ از ﻛﻼس Fileاﻳﺠﺎد ﻛﻨﻴﻢ .اﻳﻦ ﻧﻮع ﺗﻮاﺑﻊ ،ﺗﻮاﺑﻊ Staticﻧﺎﻣﻴﺪه ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ در ﻓﺼﻞ دﻫﻢ ﺑﺎ ﻣﻔﻬﻮم آﻧﻬﺎ آﺷﻨﺎ ﺧـﻮاﻫﻴﻢ ﺷـﺪ. اﻳﻦ ﺗﺎﺑﻊ ﭘﺎراﻣﺘﺮي از ﻧﻮع رﺷﺘﻪ ﻛﻪ ﺣﺎوي آدرس ﻓﺎﻳﻞ ﻣﻮرد ﻧﻈﺮ اﺳﺖ را درﻳﺎﻓﺖ ﻛﺮده و ﻣﺘﻦ داﺧﻞ ﻓﺎﻳـﻞ را ﺑـﻪ ﺻـﻮرت رﺷـﺘﻪ ﺑﺮﻣـﻲ ﮔﺮداﻧﺪ. در اﻳــﻦ ﺑﺮﻧﺎﻣــﻪ اﺑﺘــﺪا آدرﺳــﻲ ﻛــﻪ ﺑــﻪ وﺳــﻴﻠﻪ ﻛﻨﺘــﺮل OpenFileDialogﻣــﺸﺨﺺ ﺷــﺪه اﺳــﺖ را در ﻣﺘﻐﻴﻴــﺮ strFileNameﻗﺮار ﻣﻲ دﻫﻴﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻟﻴﺴﺖ ﺧﺎﺻﻴﺘﻬﺎي اﻳﻦ ﻛﻨﺘﺮل ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﻧﺎم ﻓﺎﻳﻞ اﻧﺘﺨـﺎب ﺷـﺪه ﺗﻮﺳـﻂ ﻛﺎرﺑﺮ در ﺧﺎﺻﻴﺖ FileNameآن ﻗﺮار ﻣﻲ ﮔﻴﺮد .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر زﻳﺮ ﻧﺎم ﻓﺎﻳﻞ را در ﻣﺘﻐﻴﻴـﺮ strFileName ﻗﺮار ﻣﻲ دﻫﻴﻢ. // Save the file name ;strFileName = openFileDialog1.FileName ﺳﭙﺲ ﺑـﺎ اﺳـﺘﻔﺎده از ﺗـﺎﺑﻊ ReadAllTextﻛـﻼس Fileو ارﺳـﺎل ﻣﺘﻐﻴﻴـﺮ strFileNameﺑـﻪ ﻋﻨـﻮان ﭘـﺎراﻣﺘﺮ، ﻣﺤﺘﻮﻳﺎت ﻓﺎﻳﻞ را ﺧﻮاﻧﺪه و ﻧﺘﻴﺠﻪ را ﻛﻪ ﺑﻪ ﺻﻮرت ﻣﺘﻐﻴﺮ رﺷﺘﻪ اي ﺑﺮﮔﺸﺖ داده ﻣﻲ ﺷﻮد در TextBoxﻗﺮار ﻣﻲ دﻫﻴﻢ. // Read the contents of the file ;)txtFile.Text = System.IO.File.ReadAllText(strFileName در اﻳﻦ ﺗﻤﺮﻳﻦ ﺑﺎ ﻗﺴﻤﺘﻲ از ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي ﻛﻼس OpenFileDialogآﺷﻨﺎ ﺷﺪﻳﻢ .اﻣﺎ ﻫﻤﭽﻨﺎن ﺗﻌﺪاد زﻳﺎدي از آﻧﻬـﺎ ﺑﺎﻗﻲ ﻣﺎﻧﺪه اﺳﺖ ﻛﻪ درﺑﺎره آﻧﻬﺎ ﺻﺤﺒﺘﻲ ﻧﻜﺮده اﻳﻢ .ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ ﺗﻤﺮﻳﻦ و اﺳﺘﻔﺎده از اﻳﻦ ﻛﻨﺘﺮل در ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي ﮔﻮﻧـﺎﮔﻮن ﺑـﺎ ﺗﻮاﺑـﻊ و ﻗﺎﺑﻠﻴﺘﻬﺎي ﻓﺮاواﻧﻲ ﻛﻪ اراﺋﻪ ﻣﻲ دﻫﺪ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺷﻮﻳﺪ. 1راﻫﻨﻤﺎي usingدر زﺑﺎن C#ﺑﺎ دﺳﺘﻮر usingدر C++ﻣﻘﺪاري ﻣﺘﻔﺎوت اﺳﺖ و ﺑﻴﺸﺘﺮ ﻣﻲ ﺗﻮان آن را ﻣﺸﺎﺑﻪ دﺳـﺘﻮر ﭘـﻴﺶ ﭘﺮدازﻧـﺪه include در C++ﺗﻠﻘﻲ ﻛﺮد .در ﻣﻮرد usingدر اداﻣﻪ ي ﻛﺘﺎب ﺑﻴﺸﺘﺮ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد.
٢٦٧
ﻛﻨﺘﺮل :SaveFileDialog ﺣﺎل ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل OpenFileDialogﻳﻚ ﻓﺎﻳﻞ را ﺑﺎز ﻛﺮده و از اﻃﻼﻋﺎت آن در ﺑﺮﻧﺎﻣﻪ اﺳـﺘﻔﺎده ﻛﻨﻴﺪ ،ﺑﻬﺘﺮ اﺳﺖ ﺑﻪ ﺑﺮرﺳﻲ ﻛﻨﺘﺮل SaveFileDialogﺑﭙﺮدازﻳﻢ ﺗﺎ ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ ﻛـﻪ ﭼﮕﻮﻧـﻪ ﻣـﻲ ﺗـﻮان ﺑـﻪ وﺳـﻴﻠﻪ آن اﻃﻼﻋﺎﺗﻲ را در دﻳﺴﻚ ذﺧﻴﺮه ﻛﺮد .ﻫﻤﺎﻧﻨﺪ ﻛﻨﺘﺮل ،OpenFileDialogاﻳﻦ ﻛﻨﺘﺮل ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺪ ﻫﻢ ﺑﻪ ﺻﻮرت ﻳﻚ ﻛﻨﺘـﺮل و ﻫﻢ ﺑﻪ ﺻﻮرت ﻳﻚ ﻛﻼس ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد .اﻟﺒﺘﻪ در اﻳﻦ ﻗﺴﻤﺖ از SaveFileDialogﺑـﻪ ﻋﻨـﻮان ﻳـﻚ ﻛﻨﺘـﺮل اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ،اﻣﺎ ﺑﻌﺪ از اﻳﻨﻜﻪ ﺑﺎ اﻳﻦ ﻛﻨﺘﺮل ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺷﺪﻳﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ از آن ﺑﻪ ﻋﻨﻮان ﻳﻚ ﻛﻼس ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﺑﻌﺪ از اﻳﻨﻜﻪ ﻓﺎﻳﻠﻲ را در ﺑﺮﻧﺎﻣﻪ ﺑﺎز ﻛﺮدﻳﺪ ،ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ ﺗﻐﻴﻴﺮاﺗﻲ در آن اﻳﺠﺎد ﻛﺮده و ﻧﺘﻴﺠﻪ را در دﻳﺴﻚ ذﺧﻴﺮه ﻛﻨﻴـﺪ .در اﻳـﻦ ﺷﺮاﻳﻂ اﺳﺖ ﻛﻪ ﻛﻨﺘﺮل SaveFileDialogﻣﻲ ﺗﻮاﻧﺪ ﻣﻮﺛﺮ واﻗﻊ ﺷﻮد .ﻛﻨﺘﺮل SaveFileDialogﻧﻴﺰ ﻛـﺎرﻛﺮدي ﻣﺸﺎﺑﻪ ﻛﻨﺘﺮل OpenFileDialogدارد ،اﻟﺒﺘﻪ در ﺟﻬﺖ ﻋﻜﺲ .اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣﻲ دﻫﺪ ﻳﻚ ﻧـﺎم و آدرس را ﺑـﺮاي ذﺧﻴﺮه ي ﻳﻚ ﻓﺎﻳﻞ در دﻳﺴﻚ از ﻛﺎرﺑﺮ درﻳﺎﻓﺖ ﻛﻨﻴﺪ .ﻣﺠﺪداً ﺑﺎﻳﺪ ذﻛﺮ ﻛـﻨﻢ ﻛـﻪ ﻫﻤﺎﻧﻨـﺪ ﻛﻨﺘـﺮل OpenFileDialogاﻳـﻦ ﻛﻨﺘﺮل ﻧﻴﺰ ﻓﺎﻳﻠﻲ را در دﻳﺴﻚ ذﺧﻴﺮه ﻧﻤﻲ ﻛﻨﺪ ،ﺑﻠﻜﻪ ﻓﻘﻂ ﻳﻚ راﺑﻂ اﺳﺘﺎﻧﺪارد را ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﻪ وﺟﻮد ﻣﻲ آورد ﺗـﺎ ﻛـﺎرﺑﺮ ﺑـﻪ وﺳـﻴﻠﻪ آن ﺑﺘﻮاﻧﺪ ﻣﺤﻠﻲ را ﺑﺮاي ذﺧﻴﺮه اﻃﻼﻋﺎت ﻣﺸﺨﺺ ﻛﻨﺪ.
ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل :SaveFileDialog در ﺟﺪول زﻳﺮ ﻟﻴﺴﺘﻲ از ﺧﺼﻮﺻﻴﺖ ﻫﺎي ﭘﺮ ﻛﺎرﺑﺮد ﻛﻨﺘﺮل SaveFileDialogﺑـﻪ ﻫﻤـﺮاه ﻛـﺎرﺑﺮد آﻧﻬـﺎ آورده ﺷـﺪه اﺳـﺖ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ اﻳﻦ ﻛﻨﺘﺮل )و ﻳﺎ اﻳﻦ ﻛﻼس ،ﺑﺴﺘﻪ ﺑﻪ ﻧﻮﻋﻲ ﻛﻪ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ( ،ﺧﺎﺻﻴﺘﻬﺎي زﻳﺎدي دارد ﻛﻪ ﻣﻲ ﺗﻮان ﺑﻪ وﺳﻴﻠﻪ آﻧﻬﺎ ،رﻓﺘﺎر ﻛﻨﺘﺮل را در ﺑﺮﻧﺎﻣﻪ ﺗﻐﻴﻴﺮ داد. ﺧﺎﺻﻴﺖ
ﺷﺮح
AddExtension
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ اﮔﺮ ﻛﺎرﺑﺮ ﭘﺴﻮﻧﺪ ﻓﺎﻳﻞ را ﺗﻌﻴﻴﻦ ﻧﻜﺮد ،ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻃﻮر اﺗﻮﻣﺎﺗﻴﻚ ﭘﺴﻮﻧﺪ را ﺑﻪ ﻓﺎﻳﻞ اﺿﺎﻓﻪ ﻛﻨﺪ.
CheckFileExist
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ اﮔﺮ ﻛﺎرﺑﺮ ﻧﺎم ﻓﺎﻳﻠﻲ را ﻣﺸﺨﺺ ﻛﺮد ﻛـﻪ در دﻳـﺴﻚ وﺟـﻮد داﺷـﺖ، ﭘﻴﻐﺎم ﻫﺸﺪاري ﻧﻤﺎﻳﺶ داده ﺷﻮد ﻳﺎ ﻧﻪ؟ اﻳﻦ ﻣﻮرد ﻣﻌﻤﻮﻻ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻛـﺎرﺑﺮ ﺑﺨﻮاﻫـﺪ ﻓﺎﻳﻞ را ﺑﺮ روي ﻳﻚ ﻓﺎﻳﻞ ﻣﻮﺟﻮد ﺑﻨﻮﻳﺴﺪ ﻛﺎرﺑﺮد دارد.
CheckPathExist
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ اﮔﺮ ﻛﺎرﺑﺮ آدرس ﻓﺎﻳﻠﻲ را ﻣﺸﺨﺺ ﻛﺮد ﻛﻪ در دﻳﺴﻚ وﺟﻮد ﻧﺪاﺷﺖ، ﭘﻴﻐﺎم ﻫﺸﺪاري ﻧﻤﺎﻳﺶ داده ﺷﻮد ﻳﺎ ﻧﻪ؟
CreatePrompt
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ اﮔﺮ ﻛﺎرﺑﺮ ﻓﺎﻳﻠﻲ را ﻣﺸﺨﺺ ﻛﺮد ﻛﻪ وﺟﻮد ﻧﺪاﺷـﺖ ،ﺑـﺮاي اﻳﺠـﺎد آن ﻓﺎﻳﻞ از ﻛﺎرﺑﺮ ﺳﻮال ﺷﻮد ﻳﺎ ﻧﻪ؟
DefaultExt
ﭘﺴﻮﻧﺪ ﭘﻴﺶ ﻓﺮض را در اﻳﻦ ﻛﺎدر ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ.
DereferenceLinks
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ اﮔﺮ ﻛﺎرﺑﺮ ﻳﻚ ﺷﻮرت ﻛﺎت را اﻧﺘﺨﺎب ﻛﺮد ،آدرس ﻓﺎﻳـﻞ اﺻـﻠﻲ ﻛـﻪ ﺷﻮرت ﻛﺎت ﺑﻪ آن اﺷﺎره ﻣﻲ ﻛﻨﺪ ﺑﺮﮔﺸﺘﻪ ﺷﻮد و ﻳﺎ آدرس ﺧﻮد ﻓﺎﻳﻞ ﺷـﻮرت ﻛـﺎت ﺑـﻪ
٢٦٨
ﺑﺮﻧﺎﻣﻪ ﺑﺮﮔﺮدد. FileName
ﻧﺎم ﻓﺎﻳﻠﻲ ﻛﻪ در ﻛﺎدر ﺗﻮﺳﻂ ﻛﺎرﺑﺮ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﻪ ﺻﻮرت ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ اﺳﺖ.
FileNames
ﻧﺎم ﻓﺎﻳﻠﻬﺎﻳﻲ ﻛﻪ در ﻛﺎدر ﺗﻮﺳﻂ ﻛﺎرﺑﺮ اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .اﻳـﻦ ﺧﺎﺻـﻴﺖ ﻛﻪ ﺷﺎﻣﻞ ﻳﻚ آراﻳﻪ رﺷﺘﻪ اي اﺳﺖ ﻧﻴﺰ ﺑﻪ ﺻﻮرت ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ اﺳﺖ.
Filter
اﻳﻦ ﺧﺎﺻﻴﺖ ﺣﺎوي رﺷﺘﻪ اي اﺳﺖ ﻛﻪ ﺑﺮاي ﻓﻴﻠﺘﺮ ﻛﺮدن ﻓﺎﻳﻠﻬﺎﻳﻲ ﻛـﻪ ﺑﺎﻳـﺪ در ﭘﻨﺠـﺮه Saveﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ ﺑﻪ ﻛﺎر ﻣﻲ رود .ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ رﺷـﺘﻪ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ،ﭼﻨـﺪﻳﻦ ﮔﺮوه ﻓﻴﻠﺘﺮ را ﺑﺮاي اﻳﻦ ﭘﻨﺠﺮه ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﺗﺎ در ﺟﻌﺒﻪ ﺗﺮﻛﻴﺒﻲ ﻣﻮﺟﻮد در اﻳﻦ ﭘﻨﺠـﺮه ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ و ﻛﺎرﺑﺮ ﺑﺘﻮاﻧﺪ ﻳﻜﻲ از آﻧﻬﺎ را اﻧﺘﺨﺎب ﻛﻨﺪ.
FilterIndex
ﻣﺸﺨﺺ ﻛﻨﻨﺪه اﻧﺪﻳﺲ ﻓﻴﻠﺘﺮي اﺳﺖ ﻛﻪ ﻫﻢ اﻛﻨﻮن در ﻛﺎدر ﻣﺤﺎوره اي اﻧﺘﺨـﺎب ﺷـﺪه اﺳﺖ.
InitialDirectory
ﻣﺸﺨﺺ ﻛﻨﻨﺪه آدرس داﻳﺮﻛﺘﻮري اﺳﺖ ﻛﻪ ﺑﺎﻳﺪ در اﺑﺘـﺪا ،در ﭘﻨﺠـﺮه Saveﻧﻤـﺎﻳﺶ داده ﺷﻮد.
OverwritePrompt
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ اﮔﺮ ﻛﺎرﺑﺮ ﺧﻮاﺳﺖ ﻓﺎﻳﻞ را ﺑﺮ روي ﻓﺎﻳﻞ دﻳﮕﺮي ذﺧﻴـﺮه ﻛﻨـﺪ ،ﭘﻴﻐـﺎم ﻫﺸﺪار ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ داده ﺷﻮد ﻳﺎ ﻧﻪ؟
ResotreDirectory
ﺗﻌﻴﻴﻦ ﻣﻲ ﻛﻨﺪ آﻳﺎ ﻛﺎدر Saveﺑﺎﻳﺪ آدرس داﻳﺮﻛﺘﻮري را ﻛﻪ ﻗﺒﻞ از ﺑﺴﺘﻪ ﺷﺪن در آن ﻗﺮار داﺷﺖ ،ﺑﺮﮔﺮداﻧﺪ ﻳﺎ ﻧﻪ؟
ShowHelp
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ آﻳﺎ دﻛﻤﻪ Helpﻧﻴﺰ در ﭘﻨﺠﺮه Openﻧﻤـﺎﻳﺶ داده ﺷـﻮد ﻳـﺎ ﻧﻪ؟
Title
ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻣﺘﻨﻲ اﺳﺖ ﻛﻪ در ﻧﻮار ﻋﻨﻮان ﭘﻨﺠﺮه Openﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
ValidateNames
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ آﻳﺎ ﭘﻨﺠﺮه ﻓﻘﻂ ﺑﺎﻳﺪ ﻧﺎم ﻓﺎﻳﻠﻬﺎي ﻣﻌﺘﺒﺮ وﻳﻨﺪوزي را ﻗﺒﻮل ﻛﻨﺪ و ﻳﺎ ﻫﺮ ﻧﺎﻣﻲ را ﺑﺘﻮاﻧﺪ درﻳﺎﻓﺖ ﻛﻨﺪ؟
ﻣﺘﺪﻫﺎي ﻛﻨﺘﺮل :SaveFileDialog ﻣﺘﺪﻫﺎي ﻛﻨﺘﺮل SaveFileDialogﻫﻤﺎﻧﻨﺪ ﻣﺘﺪﻫﺎي OpenFileDialogﻫﺴﺘﻨﺪ .ﺑﺮاي ﻣﻄﺎﻟﻌﻪ ﻣﺘﺪﻫﺎي ﻛﻨﺘـﺮل OpenFileDialogﻣــﻲ ﺗﻮاﻧﻴــﺪ ﺑــﻪ ﺑﺨــﺶ ﻗﺒﻠــﻲ ﻣﺮاﺟﻌــﻪ ﻛﻨﻴــﺪ .در ﺗﻤــﺎم ﻣﺜــﺎل ﻫــﺎي ﺑﻌــﺪي ﻧﻴــﺰ ﻫﻤﺎﻧﻨــﺪ ﻛﻨﺘــﺮل OpenFileDialogاز ﺗﺎﺑﻊ ShowDialogﺑﺮاي ﻧﻤﺎﻳﺶ ﻛﺎدر Saveاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ.
اﺳﺘﻔﺎده از ﻛﻨﺘﺮل :SaveFileDialog
٢٦٩
ﺑﺮاي ﺑﺮرﺳﻲ ﻧﺤﻮه ﻛﺎرﻛﺮد ﻛﻨﺘﺮل ،SaveFileDialogاز ﭘﺮوژه Dialogsدر ﻗﺴﻤﺖ ﻗﺒﻠﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .در اﻳـﻦ ﻗﺴﻤﺖ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﺻﻮرﺗﻲ ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﻛﻪ ﻣﺘﻦ داﺧﻞ TextBoxرا در ﻓﺎﻳﻠﻲ ذﺧﻴﺮه ﻛﻨﺪ. در اﻳﻦ ﻗﺴﻤﺖ ،ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل SaveFileDialogﭘﻨﺠﺮه Save Fileرا ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ داده و ﺑـﻪ او اﺟـﺎزه ﻣﻲ دﻫﻴﻢ ﺗﺎ ﻣﻜﺎﻧﻲ را ﺑﺮاي ذﺧﻴﺮه ﻣﺤﺘﻮﻳﺎت TextBoxﻣﺸﺨﺺ ﻛﻨﺪ .ﺳﭙﺲ ﻣﺤﺘﻮﻳﺎت داﺧﻞ آن را در ﻓﺎﻳﻠﻲ در ﻣـﺴﻴﺮ ﻣـﺸﺨﺺ ﺷﺪه ﺗﻮﺳﻂ ﻛﺎرﺑﺮ ذﺧﻴﺮه ﻣﻲ ﻛﻨﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻛﺎر ﺑﺎ ﻛﻨﺘﺮل SaveFileDialog (1ﺑﺮﻧﺎﻣﻪ Dialogsرا ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﻢ ،ﻣﺠﺪدا ﺑﺎز ﻛﻨﻴﺪ. (2در ﻓﺮم اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ ﻛﻨﺘﺮل Buttonدﻳﮕﺮي اﺿﺎﻓﻪ ﻛﺮده و ﺧﺎﺻﻴﺘﻬﺎي آن را ﺑﺮاﺑﺮ ﺑﺎ ﻟﻴﺴﺖ زﻳﺮ ﻗﺮار دﻫﻴﺪ.
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ btnSaveﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textرا ﺑﺮاﺑﺮ ﺑﺎ Saveﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Anchorرا ﺑﺮاﺑﺮ ﺑﺎ Top,Rightﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Locationرا ﺑﺮاﺑﺮ ﺑﺎ 367;38ﻗﺮار دﻫﻴﺪ.
(3در ﺟﻌﺒﻪ اﺑﺰار ﺑﻪ ﻗﺴﻤﺖ Dialogsﺑﺮوﻳﺪ و ﺑﺮ روي ﻛﻨﺘﺮل SaveFileDialogدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳـﻦ ﺗﺮﺗﻴﺐ ﻳﻚ ﻛﻨﺘﺮل SaveFileDialogدر ﻗﺴﻤﺖ ﭘﺎﻳﻴﻦ ﻃﺮاﺣﻲ ﻓﺮم ﻗﺮار ﻣﻲ ﮔﻴﺮد. (4ﺑﺮ روي دﻛﻤﻪ ي btnSaveدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛـﺪ زﻳـﺮ را در آن ﻣﺘﺪ وارد ﻛﻨﻴﺪ: )private void btnSave_Click(object sender, EventArgs e { // Set the save dialog properties ;"saveFileDialog1.DefaultExt = "txt ;saveFileDialog1.FileName = strFileName = saveFileDialog1.Filter ;"*"Text files (*.txt)|*.txt|All files (*.*)|*. ;saveFileDialog1.FilterIndex = 1 ;saveFileDialog1.OverwritePrompt = true ;"saveFileDialog1.Title = "Demo Save File Dialog // Show the Save file dialog and if the user clicks // Save button, save the file )if (saveFileDialog1.ShowDialog() == DialogResult.OK { // Save the file name ;strFileName = saveFileDialog1.FileName
the
// Write the contents of the text box in file (System.IO.File.WriteAllText
٢٧٠
;)strFileName, txtFile.Text } } (5در اﻳﻦ ﻣﺮﺣﻠﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮﻧﺎﻣﻪ ﺧﻮد را ﺗﺴﺖ ﻛﻨﻴﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ ﭘﺮوژه را اﺟﺮا ﻛﺮده و ﻣﺘﻦ ﺳﺎده اي را داﺧﻞ آن وارد ﻛﻨﻴﺪ .ﺳﭙﺲ ﺑﺮ روي دﻛﻤﻪ ي Saveﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻛﺎدر ﻣﺤﺎوره اي Saveﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ. (6ﻧﺎﻣﻲ را ﺑﺮاي ﻓﺎﻳﻞ اﻧﺘﺨﺎب ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﻦ داﺧـﻞ TextBoxدر ﻓـﺎﻳﻠﻲ ﺑﺎ ﻧﺎم و ﻣﺴﻴﺮي ﻛﻪ ﻣﺸﺨﺺ ﻛﺮده ﺑﻮدﻳﺪ ذﺧﻴﺮه ﻣﻲ ﺷﻮد .ﺑﺮاي اﻣﺘﺤﺎن اﻳﻦ ﻣﻮرد ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن ﺑـﺮ روي دﻛﻤـﻪ ي Openﻓﺎﻳﻞ اﻳﺠﺎد ﺷﺪه را ﻣﺠﺪداً در ﺑﺮﻧﺎﻣﻪ ﺑﺎز ﻛﺮده و ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ. (7ﺑﺮاي ﺗﺴﺖ ﻋﻤﻠﻜﺮد ﺧﺎﺻﻴﺖ OverwritePromptدر ﻛﻨﺘﺮل SaveFileDialogﻣﺘﻦ دﻳﮕﺮي را در TextBoxوارد ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ ي Saveﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺠﺪداً ﻣﺴﻴﺮ و ﻧﺎم ﻓﺎﻳﻞ ﻗﺒﻠـﻲ را ﺑـﺮاي ذﺧﻴـﺮه ﻓﺎﻳـﻞ ﺟﺪﻳﺪ وارد ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﭘﻴﻐﺎﻣﻲ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 9-7ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و ﻣﻲ ﮔﻮﻳﺪ ﻛﻪ ﻓﺎﻳﻠﻲ ﺑﺎ اﻳـﻦ ﻧـﺎم ﻣﻮﺟﻮد اﺳﺖ .آﻳﺎ ﻣﻲ ﺧﻮاﻫﻴﺪ آن را ﺑﺎ اﻳﻦ ﻓﺎﻳﻞ ﺗﻌﻮﻳﺾ ﻛﻨﺪ؟ در ﺻﻮرﺗﻲ ﻛﻪ ﺑﺮ روي ﮔﺰﻳﻨﻪ Yesﻛﻠﻴﻚ ﻛﻨﻴﺪ ،ﻓﺎﻳـﻞ ﻗﺒﻠـﻲ ﭘﺎك ﻣﻲ ﺷﻮد و ﻓﺎﻳﻞ ﺟﺪﻳﺪ ﺑﻪ ﺟﺎي آن ﻗﺮار ﻣﻲ ﮔﻴﺮد .اﮔﺮ ﺑﺮ روي ﮔﺰﻳﻨﻪ Noﻛﻠﻴﻚ ﻛﻨﻴﺪ ،ﺑﻪ ﻛﺎدر Saveﺑﺮﻣﻲ ﮔﺮدﻳﺪ ﺗﺎ ﻧﺎم دﻳﮕﺮي را ﺑﺮاي ﻓﺎﻳﻞ اﻧﺘﺨﺎب ﻛﻨﻴﺪ.
ﺷﻜﻞ 9-7 ﻧﻜﺘﻪ :ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺻﻔﺤﻪ Saveو ﻳﺎ Openﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ،ﻣﻨﻮﻳﻲ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻛﻠﻴﻚ راﺳﺖ ﻧﻤﺎﻳﺶ داده اﺟﺎزه ﻣﻲ دﻫﺪ ﻛﺎرﻫﺎﻳﻲ را از ﻗﺒﻴﻞ اﻧﺘﻘﺎل ﻓﺎﻳﻞ ﺑﻪ ﻣﺤﻠﻲ دﻳﮕﺮ ،ﺣﺬف ﻓﺎﻳﻞ و ﻳﺎ ﺗﻐﻴﻴﺮ ﻧﺎم آن را اﻧﺠﺎم دﻫﻴﺪ .ﻫﻤﭽﻨﻴﻦ ﺑﺮ ﺣﺴﺐ اﻳﻨﻜﻪ ﭼﻪ ﻧﺮم اﻓﺰارﻫﺎﻳﻲ ﺑﺮ روي ﺳﻴﺴﺘﻢ ﺷﻤﺎ ﻧﺼﺐ ﺷﺪه ﺑﺎﺷﻨﺪ ﮔﺰﻳﻨﻪ ﻫﺎي دﻳﮕﺮي ﻧﻴﺰ در اﻳﻦ ﻣﻨﻮ ﻧﻤﺎﻳﺶ داده ﻣـﻲ ﺷـﻮﻧﺪ .ﺑـﺮاي ﻣﺜـﺎل اﮔـﺮ WinZipﻳـﺎ WinRarﺑﺮ روي ﺳﻴﺴﺘﻢ ﺷﻤﺎ ﻧﺼﺐ ﺷﺪه ﺑﺎﺷﺪ ،در اﻳﻦ ﭘﻨﺠﺮه ﻣﻲ ﺗﻮاﻧﻴﺪ ﻓﺎﻳﻠﻬﺎ را ﻓﺸﺮده ﻛﻨﻴﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻗﺒﻞ از ﻧﻤﺎﻳﺶ ﻛﻨﺘﺮل SaveFileDialogﺑﺎﻳﺪ ﺑﻌﻀﻲ از ﺧﺎﺻﻴﺘﻬﺎي آن را ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ﺗﺎ ﺑﺘﻮاﻧﻴﺪ از آن ﺑﻪ ﺻﻮرت ﻣﻨﺎﺳﺐ در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ اول ﺧﺎﺻﻴﺖ DefaultExtرا ﺗﻨﻈﻴﻢ ﻛﺮده اﻳﻢ .اﮔﺮ ﻛﺎرﺑﺮ ﻫﻨﮕﺎم ﻣﺸﺨﺺ ﻛﺮدن ﻧﺎم ﻓﺎﻳﻞ ﭘﺴﻮﻧﺪي ﺑﺮاي آن ﻣﺸﺨﺺ ﻧﻜﺮده ﺑﺎﺷﺪ ،ﭘﺴﻮﻧﺪي ﻛﻪ در اﻳﻦ ﺧﺎﺻﻴﺖ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﺑﻪ ﻃﻮر اﺗﻮﻣﺎﺗﻴﻚ ﺑﻪ اﻧﺘﻬﺎي ﻓﺎﻳﻞ اﺿﺎﻓﻪ ﻣﻲ ﺷﻮد .ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ ﻛﺎرﺑﺮ ﻫﻨﮕﺎم ذﺧﻴﺮه ﻓﺎﻳﻞ ﻧﺎم testرا ﺑﺪون ﻫﻴﭻ ﭘـﺴﻮﻧﺪي وارد ﻛـﺮده و ﺑـﺮ روي دﻛﻤـﻪ Save ﻛﻠﻴﻚ ﻣﻲ ﻛﻨﺪ .در اﻳﻦ ﺣﺎﻟﺖ ﭘﺴﻮﻧﺪي ﻛﻪ در اﻳﻦ ﺧﺎﺻﻴﺖ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﺑﻪ اﻧﺘﻬـﺎي ﻓﺎﻳـﻞ اﺿـﺎﻓﻪ ﺷـﺪه و ﺳـﭙﺲ ﻓﺎﻳـﻞ ﺑـﺎ ﻧـﺎم test.txtدر دﻳﺴﻚ ذﺧﻴﺮه ﻣﻲ ﺷﻮد.
٢٧١
;"saveFileDialog1.DefaultExt = "txt ﺳﭙﺲ ﺧﺎﺻﻴﺖ FileNameاز اﻳﻦ ﻛﻨﺘﺮل را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺪار ﻣﺘﻐﻴﺮ strFileNameﻗﺮار ﻣﻲ دﻫﻴﻢ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻓﺎﻳـﻞ را ﺑﺎ اﺳﺘﻔﺎده از دﻛﻤﻪ ي Openﺑﺎز ﻛﻨﻴﺪ ،ﻧﺎم آن در اﻳﻦ ﻣﺘﻐﻴﺮ ذﺧﻴﺮه ﻣﻲ ﺷﻮد .ﺑﺎ ﻗﺮار دادن اﻳﻦ ﻣﺘﻐﻴﺮ در ﺧﺎﺻـﻴﺖ FileName ﻛﻨﺘﺮل SaveFileDialogﺑﺎﻋﺚ ﻣﻲ ﺷﻮﻳﻢ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺪون وارد ﻛﺮدن ﻧﺎم ﻓﺎﻳﻞ ﺑﺘﻮاﻧﺪ ﻳﻚ ﻓﺎﻳﻞ را ﺑﺎز ﻛﺮده ،آن را وﻳﺮاﻳﺶ ﻛﻨﺪ و ﺳﭙﺲ آن را ذﺧﻴﺮه ﻛﻨﺪ .اﻟﺒﺘﻪ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺎ ﺗﻐﻴﻴﺮ اﻳﻦ ﻧﺎم در ﻛﺎدر Saveﻧﺎم ﺟﺪﻳﺪي ﺑﺮاي ﻓﺎﻳﻞ اﻧﺘﺨﺎب ﻛﻨﺪ و ﻳـﺎ ﻓﺎﻳـﻞ را در ﻣﺴﻴﺮ دﻳﮕﺮي ذﺧﻴﺮه ﻛﻨﺪ. ;saveFileDialog1.FileName = strFileName در دو ﺧﻂ ﺑﻌﺪي ﺧﺎﺻﻴﺖ Filterو FilterIndexﻛﻨﺘﺮل را ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﻨﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻓﺎﻳﻠﻬﺎي ﺧﺎﺻـﻲ در ﻛـﺎدر ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﻨﺪ ﺷﺪ: = saveFileDialog1.Filter ;"*"Text files (*.txt)|*.txt|All files (*.*)|*. ;saveFileDialog1.FilterIndex = 1
ﺧﺎﺻﻴﺖ OverwritePromptﻣﻘﺪاري را از ﻧﻮع Booleanﻗﺒﻮل ﻣﻲ ﻛﻨﺪ .اﮔﺮ ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ را ﺑﺮاﺑﺮ ﺑﺎ True ﻗﺮار دﻫﻴﺪ ،در ﺻﻮرﺗﻲ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺨﻮاﻫﺪ ﻓﺎﻳﻠﻲ را ﺑﺮ روي ﻓﺎﻳﻞ دﻳﮕﺮي ذﺧﻴﺮه ﻛﻨﺪ ﺑﻪ او ﻫﺸﺪار داده ﻣﻲ ﺷﻮد .اﮔﺮ ﻣﻘـﺪار اﻳـﻦ ﺧﺎﺻـﻴﺖ ﺑﺮاﺑﺮ ﺑﺎ Falseﺑﺎﺷﺪ ،در ﺻﻮرت رخ دادن ﭼﻨﻴﻦ ﻣﺸﻜﻠﻲ ،ﺑﺪون اﻳﻨﻜﻪ ﻣﻮردي ﺑﻪ ﻛﺎرﺑﺮ اﻃﻼع داده ﺷﻮد ﻓﺎﻳﻞ ﻗﺒﻠﻲ ﭘﺎك ﻣﻲ ﺷـﻮد و ﻓﺎﻳﻞ ﺟﺪﻳﺪ ﺑﺮ روي آن ذﺧﻴﺮه ﻣﻲ ﺷﻮد. ;saveFileDialog1.OverwritePrompt = true در اﻧﺘﻬﺎ ﻧﻴﺰ ﻋﻨﻮان ﭘﻨﺠﺮه Saveرا ﺗﻌﻴﻴﻦ ﻣﻲ ﻛﻨﻢ ﺗﺎ ﺑﺎ ﻧﺎم ﺑﺮﻧﺎﻣﻪ ﻫﻤﺎﻫﻨﮓ ﺷﻮد: ;"saveFileDialog1.Title = "Demo Save File Dialog ﺑﻌﺪ از اﻳﻨﻜﻪ ﺧﺎﺻﻴﺘﻬﺎي ﻣﺨﺘﻠﻒ ﻛﺎدر Saveرا ﺗﻨﻈﻴﻢ ﻛﺮدﻳﻢ ،ﻣﻲ ﺗﻮاﻧﻴﻢ ﻛﺎدر را ﻧﻤـﺎﻳﺶ دﻫـﻴﻢ .ﺳـﭙﺲ ﺑـﺎ اﺳـﺘﻔﺎده از دﺳـﺘﻮر if ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺮ روي دﻛﻤﻪ Saveﻛﻠﻴﻚ ﻛﺮده اﺳﺖ و ﻳﺎ ﺑﺮ روي دﻛﻤﻪ .Cancelدر اﻳـﻦ ﻛﻨﺘـﺮل ﻫـﻢ ﻫﻤﺎﻧﻨـﺪ ﻛﻨﺘﺮل OpenFileDialogاﮔﺮ ﻛﺎرﺑﺮ ﺑﺮ روي دﻛﻤﻪ Saveﻛﻠﻴـﻚ ﻛﻨـﺪ ﻣﻘـﺪار DialogResult.OKو اﮔـﺮ ﻛﺎرﺑﺮ ﺑﺮ روي دﻛﻤﻪ ﻓﺮﻣﺎن Cancelﻛﻠﻴﻚ ﻛﻨﺪ ﻣﻘﺪار DialogResult.Cancelﺑﺮﮔﺸﺖ داده ﻣﻲ ﺷﻮد. )if (saveFileDialog1.ShowDialog() == DialogResult.OK اﮔﺮ ﻛﺎرﺑﺮ ﮔﺰﻳﻨﻪ Saveرا اﻧﺘﺨﺎب ﻛﺮده ﺑﻮد ،اﺑﺘﺪا ﺑﺎﻳﺪ ﻧﺎم ﻓﺎﻳﻞ را در ﻣﺘﻐﻴﺮ strFileNameذﺧﻴﺮه ﻛﻨـﻴﻢ .ﺳـﭙﺲ ﻣﺠـﺪداً از ﻛﻼس Fileﺑﺮاي ذﺧﻴﺮه ﻣﺤﺘﻮﻳﺎت ﻓﺮم ،درون ﻓﺎﻳﻞ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .اﻣﺎ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ از ﻣﺘﺪ WriteAllTextدر اﻳﻦ ﻛﻼس اﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﺳﺘﻔﺎده از اﻳﻦ ﻣﺘﺪ ﻧﻴﺰ ﺑﻪ ﻧﻤﻮﻧﻪ ﺳﺎزي از اﻳﻦ ﻛﻼس ﻧﻴﺎزي ﻧﺪارد .اﻳﻦ ﻣﺘﺪ آدرس ﻳـﻚ ﻓﺎﻳـﻞ و ﻳـﻚ ﻣﺘﻐﻴﻴـﺮ
٢٧٢
رﺷﺘﻪ اي ﻛﻪ ﺣﺎوي ﻣﺤﺘﻮﻳﺎت ﻓﺎﻳﻞ اﺳﺖ را ﺑﻪ ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻛﺮده و در آدرس ﺗﻌﻴﻴﻦ ﺷﺪه ،ﻓﺎﻳﻠﻲ را ﺑـﺎ ﻣﺤﺘﻮﻳـﺎﺗﻲ ﻛـﻪ ﺑـﻪ آن ﻓﺮﺳﺘﺎده ﺷﺪه اﺳﺖ اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ: // Save the file name ;strFileName = saveFileDialog1.FileName // Write the contents of the text box in file (System.IO.File.WriteAllText ;)strFileName, txtFile.Text
ﻛﻨﺘﺮل :FontDialog ﺑﻌﻀﻲ ﻣﻮاﻗﻊ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﻴﺪ ﻛﻪ ﻓﻮﻧﺖ ﺧﺎﺻﻲ را اﻧﺘﺨـﺎب ﻛﻨـﺪ ﺗـﺎ اﻃﻼﻋـﺎت او ﺑـﺎ آن ﻓﻮﻧـﺖ ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ ،و ﻳﺎ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ ﻟﻴﺴﺘﻲ از ﺗﻤﺎم ﻓﻮﻧﺖ ﻫﺎﻳﻲ ﻛﻪ در ﺳﻴﺴﺘﻢ ﻛﺎرﺑﺮ ﻧـﺼﺐ ﺷـﺪه اﺳـﺖ را در ﺑﺮﻧﺎﻣـﻪ اﺳـﺘﻔﺎده ﻛﻨﻴﺪ .در اﻳﻦ ﻣﻮاﻗﻊ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻛﻨﺘﺮل FontDialogاﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻳﻦ ﻛﻨﺘﺮل ﺗﻤﺎم ﻓﻮﻧﺘﻬﺎي ﻧﺼﺐ ﺷﺪه در ﺳﻴـﺴﺘﻢ ﻛـﺎرﺑﺮ را در ﻳﻚ ﻛﺎدر اﺳﺘﺎﻧﺪارد ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ و ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻣﻲ دﻫﺪ ﺗﺎ ﻓﻮﻧﺖ ﺧﺎﺻﻲ را ﺑﻴﻦ آﻧﻬﺎ اﻧﺘﺨﺎب ﻛﻨﺪ. ﻫﻤﺎﻧﻨﺪ ﻛﺎدرﻫﺎي OpenFileDialogو ،SaveFileDialogﻛﺎدر ﻣﺤﺎوره اي FontDialogﻫـﻢ ﻣـﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺻﻮرت ﻳﻚ ﻛﻨﺘﺮل و ﻫﻢ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺻﻮرت ﻳﻚ ﻛﻼس ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد .اﺳﺘﻔﺎده از اﻳـﻦ ﻛـﺎدر ﺑـﺴﻴﺎر راﺣـﺖ اﺳـﺖ. ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﺗﻌﺪادي از ﺧﺎﺻﻴﺘﻬﺎي آن را ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ،ﻛﺎدر را ﻧﻤﺎﻳﺶ دﻫﻴﺪ و ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺘﻬﺎي ﻛﺎدر ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻛـﻪ ﻛﺪام ﻓﻮﻧﺖ ﺗﻮﺳﻂ ﻛﺎرﺑﺮ اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ.
ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل :FontDialog ﺟﺪول زﻳﺮ ﻟﻴﺴﺘﻲ از ﺧﺎﺻﻴﺘﻬﺎي ﭘﺮ ﻛﺎرﺑﺮد FontDialogرا ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. ﺧﺎﺻﻴﺖ
ﺷﺮح
AllowScriptChange
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳﺎ ﻛـﺎرﺑﺮ ﻣـﻲ ﺗﻮاﻧـﺪ ﺑـﺎ اﺳـﺘﻔﺎده از ﻗـﺴﻤﺖ Scriptﻛـﺎدر، ﻣﺠﻤﻮﻋﻪ ﻛﺎراﻛﺘﺮﻫﺎﻳﻲ ﺟﺪاي از آﻧﭽﻪ در ﻗﺴﻤﺖ Scriptﻣﺸﺨﺺ ﺷﺪه اﺳﺖ را اﻧﺘﺨﺎب ﻛﻨﺪ ﻳﺎ ﻧﻪ؟ در ﺻﻮرت اﻳﻨﻜﻪ ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﺮاﺑﺮ ﺑﺎ Trueﺑﺎﺷﺪ ،ﺗﻤـﺎم ﻣﺠﻤﻮﻋﻪ ﻛﺎراﻛﺘﺮ ﻫﺎي ﻣﻮﺟﻮد در ﻗﺴﻤﺖ Scriptﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
Color
رﻧﮓ ﻓﻮﻧﺖ اﻧﺘﺨﺎب ﺷﺪه را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ.
Font
ﻧﺎم ﻓﻮﻧﺖ اﻧﺘﺨﺎب ﺷﺪه را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ.
FontMustExist
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ اﮔﺮ ﻛﺎرﺑﺮ ﻧﺎم ﻓﻮﻧﺘﻲ را اﻧﺘﺨﺎب ﻛﺮد ﻛﻪ وﺟﻮد ﻧﺪاﺷﺖ ،ﻛﺎدر ﭘﻴﻐـﺎﻣﻲ ﺑﺮاي ﺧﻄﺎ ﻧﻤﺎﻳﺶ داده ﺷﻮد ﻳﺎ ﻧﻪ؟
MaxSize
ﺣﺪاﻛﺜﺮ اﻧﺪازه اي ﻛﻪ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺮاي ﻓﻮﻧﺖ اﻧﺘﺨﺎب ﻛﻨﺪ را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ.
٢٧٣
MinSize
ﺣﺪاﻗﻞ اﻧﺪازه اي ﻛﻪ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺮاي ﻓﻮﻧﺖ اﻧﺘﺨﺎب ﻛﻨﺪ را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ.
ShowApply
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﺎدر ﻣﺤﺎوره اي ﻛﻪ ﻧﻤﺎﻳﺶ داده ﻣـﻲ ﺷـﻮد ﺑﺎﻳـﺪ داراي دﻛﻤـﻪ ي Applyﻧﻴﺰ ﺑﺎﺷﺪ ﻳﺎ ﻧﻪ؟
ShowColor
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ در ﻛﺎدر ﻓﻮﻧﺖ ،اﻣﻜﺎن اﻧﺘﺨﺎب رﻧﮓ ﻧﻴﺰ وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ ﻳﺎ ﻧﻪ؟
ShowEffects
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳﺎ ﻛﺎدر ﻓﻮﻧﺖ ﺑﺎﻳﺪ داراي ﻗﺴﻤﺘﻲ ﺑﺮاي ﺗﻌﻴﻴﻦ ﺧﻂ دار ﺑـﻮدن ،زﻳـﺮ ﺧﻂ دار ﺑﻮدن و ﻳﺎ اﻧﺘﺨﺎب رﻧﮓ ﻣﺘﻦ ﺗﻮﺳﻂ ﻛﺎرﺑﺮ ﺑﺎﺷﺪ ﻳﺎ ﻧﻪ؟
ShowHelp
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳﺎ ﻛﺎدر ﻓﻮﻧﺖ داراي دﻛﻤﻪ ﻓﺮﻣﺎن Helpﺑﺎﺷﺪ ﻳﺎ ﻧﻪ؟
ﻣﺘﺪﻫﺎي ﻛﻨﺘﺮل :FontDialog در ﻣﺜﺎل ﻫﺎي ﺑﻌﺪي ﻓﻘﻂ از ﻳﻜﻲ از ﻣﺘﺪﻫﺎي ﻛﻨﺘﺮل FontDialogاﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ آن ﻧﻴﺰ ﻣﺘـﺪ ShowDialog ﺑﺮاي ﻧﻤﺎﻳﺶ ﻛﺎدر ﻣﺤﺎوره اي ﺧﻮاﻫﺪ ﺑﻮد .ﻋﻼوه ﺑﺮ اﻳﻦ ﻣﺘﺪ ﻣﺘﺪﻫﺎي زﻳﺎدي ﺑﺮاي اﻳﻦ ﻛﻨﺘﺮل وﺟﻮد دارﻧـﺪ ،ﻣﺎﻧﻨـﺪ ﻣﺘـﺪ Resetﻛـﻪ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻣﻘﺪار ﺗﻤﺎم ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل ﺑﻪ ﺣﺎﻟﺖ اول ﺑﺮﮔﺮدد.
اﺳﺘﻔﺎده از ﻛﻨﺘﺮل :FontDialog ﺑــﺮاي ﻧﻤــﺎﻳﺶ ﻛﻨﺘــﺮل FontDialogﻧﻴــﺎز ﺑــﻪ ﺗﻨﻈــﻴﻢ ﻫــﻴﭻ ﻣﻘــﺪاري ﻧﻴــﺴﺖ ،ﺑﻠﻜــﻪ ﻣــﻲ ﺗــﻮان ﺑــﻪ ﻃــﻮر ﻣــﺴﺘﻘﻴﻢ ﻣﺘــﺪ ShowDialogاﻳﻦ ﻛﻨﺘﺮل را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮد ﺗﺎ ﻛﺎدر ﻣﺤﺎوره اي ﻧﻤﺎﻳﺶ داده ﺷﻮد. ;)(fontDialog1.ShowDialog در اﻳﻦ ﺻﻮرت ﻛﺎدر ﻣﺤﺎوره اي ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 10-7ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
٢٧٤
ﺷﻜﻞ 10-7 ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻛﺎدر ﻓﻮﻧﺖ داراي ﻳﻚ ﺑﺨﺶ Effectsاﺳﺖ ﻛﻪ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻣﻲ دﻫﺪ ﺗﻌﻴﻴﻦ ﻛﻨﺪ ﻳﻚ ﻓﻮﻧﺖ داراي ﺧﻂ و ﻳﺎ زﻳﺮ ﺧﻂ ﻧﻴﺰ ﺑﺎﺷﺪ .ﻧﻤﺎﻳﺶ اﻳﻦ ﺑﺨﺶ ﺑﻪ اﻳﻦ ﻋﻠﺖ اﺳﺖ ﻛﻪ ﺧﺎﺻـﻴﺖ ShowEffectsﺑـﻪ ﻃـﻮر ﭘـﻴﺶ ﻓـﺮض داراي ﻣﻘـﺪار trueاﺳــﺖ .در اﻳــﻦ ﻛــﺎدر ﻗــﺴﻤﺖ Colorﺑــﺮاي اﻧﺘﺨــﺎب رﻧــﮓ ﻧﻤــﺎﻳﺶ داده ﻧــﺸﺪه اﺳــﺖ ،زﻳــﺮا ﻣﻘــﺪار ﭘــﻴﺶ ﻓــﺮض ShowColorﺑﺮاﺑﺮ ﺑﺎ Falseاﺳﺖ .ﺑﺮاي ﻧﻤﺎﻳﺶ ﻗﺴﻤﺖ رﻧﮓ ،ﺑﺎﻳﺴﺘﻲ ﻗﺒﻞ از ﻓﺮاﺧﻮاﻧﻲ ﺗـﺎﺑﻊ ShowDialogﻣﻘـﺪار اﻳﻦ ﺧﺎﺻﻴﺖ را ﺑﺮاﺑﺮ ﺑﺎ Trueﻗﺮار داد. ;fontDialog1.ShowColor = true ;)(fontDialog1.ShowDialog ﻣﺘــﺪ ShowDialogاز اﻳــﻦ ﻛــﺎدر ﻣﺤــﺎوره اي ﻧﻴــﺰ ،ﻫﻤﺎﻧﻨــﺪ ﺗﻤــﺎم ﻣﺘــﺪﻫﺎي ShowDialogﻣﻘــﺪاري را از ﻧــﻮع DialogResultﺑﺮﻣـــﻲ ﮔﺮداﻧـــﺪ .اﻳـــﻦ ﻣﻘـــﺪار ﻣـــﻲ ﺗﻮاﻧـــﺪ ﺑﺮاﺑـــﺮ ﺑـــﺎ DialogResult.OKو ﻳـــﺎ DialogResult.Cancelﺑﺎﺷﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎدر ﻓﻮﻧﺖ ﻧﻤﺎﻳﺶ داده ﺷﺪ و ﻛﺎرﺑﺮ ﺑﺮ روي ﮔﺰﻳﻨﻪ OKﻛﻠﻴﻚ ﻛﺮد ،ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﺎ اﺳـﺘﻔﺎده از ﺧﺎﺻـﻴﺘﻬﺎي Colorو Fontﻛﻨﺘﺮل FontDialogﺑﺮرﺳﻲ ﻛﻨﻴﺪ ﻛﻪ ﻛﺎرﺑﺮ ﭼﻪ ﻧﻮع ﻓﻮﻧﺖ و ﭼﻪ رﻧﮕﻲ را اﻧﺘﺨﺎب ﻛﺮده اﺳﺖ و ﺳﭙﺲ آن را در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ و ﻳﺎ در ﻣﺘﻐﻴﺮي ﻗﺮار داده و در ﺑﺨﺸﻬﺎي ﺑﻌﺪي اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﺣﺎل ﻛﻪ ﺑﺎ اﻳﻦ ﻛﺎدر و ﻧﺤﻮه ﻛﺎرﻛﺮد آن آﺷﻨﺎ ﺷﺪﻳﺪ ،در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ از آن اﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد .در ﺑﺨﺶ ﺑﻌﺪ ،از ﺑﺮﻧﺎﻣـﻪ اي ﻛـﻪ در دو ﻣﺜﺎل ﻗﺒﻠﻲ اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﻢ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ و آن را ﻣﻘﺪاري ﮔﺴﺘﺮش ﻣﻲ دﻫﻴﻢ .در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺴﺖ در ﺑﺮﻧﺎﻣـﻪ ﻓﺎﻳﻠﻲ را ﺑﺎز ﻛﺮده ،ﺗﻐﻴﻴﺮاﺗﻲ را در آن اﻧﺠﺎم دﻫﺪ و ﺳﭙﺲ ﻓﺎﻳﻞ را ذﺧﻴﺮه ﻛﻨﺪ .در اﻳﻦ ﻗﺴﻤﺖ ﺑﺨﺸﻲ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿـﺎﻓﻪ ﻣـﻲ ﻛﻨـﻴﻢ ﻛـﻪ ﻛﺎرﺑﺮ ﺑﻪ وﺳﻴﻠﻪ آن ﺑﺘﻮاﻧﺪ ﻓﻮﻧﺖ ﻣﺘﻦ درون TextBoxرا ﺗﻐﻴﻴﺮ دﻫﺪ.
٢٧٥
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻛﺎر ﺑﺎ ﻛﻨﺘﺮل FontDialog (1ﻣﺠﺪدا ﭘﺮوژه Dialogsرا ﺑﺎز ﻛﻨﻴﺪ. (2در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ،ﻛﻨﺘﺮل Buttonدﻳﮕﺮي ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮده و ﺧﺎﺻﻴﺘﻬﺎي آن را ﻣﻄﺎﺑﻖ ﻟﻴﺴﺖ زﻳﺮ ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ btnFontﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Anchorرا ﺑﺮاﺑﺮ ﺑﺎ Top, Rightﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Anchorرا ﺑﺮاﺑﺮ ﺑﺎ 367;68ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textرا ﺑﺮاﺑﺮ ﺑﺎ Fontﻗﺮار دﻫﻴﺪ.
(3ﺑﺮاي ﻧﻤﺎﻳﺶ ﻛﺎدر ﻓﻮﻧﺖ ﺑﺎﻳﺪ ﻳﻚ ﻛﻨﺘﺮل FontDialogﺑﺮ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ .ﺑﺮاي اﻳـﻦ ﻛـﺎر در ﺟﻌﺒـﻪ اﺑـﺰار ﺑـﻪ ﻗﺴﻤﺖ Dialogsﺑﺮوﻳﺪ و در آﻧﺠﺎ ﺑﺮ روي ﻛﻨﺘﺮل FontDialogدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴـﺪ .ﺑـﻪ اﻳـﻦ ﺻـﻮرت ﻳـﻚ ﻛﻨﺘﺮل FontDialogدر ﻗﺴﻤﺖ ﭘﺎﻳﻦ ﻣﺤﻴﻂ ﻃﺮاﺣﻲ در وﻳﮋوال اﺳﺘﻮدﻳﻮ اﺿﺎﻓﻪ ﺧﻮاﻫﺪ ﺷـﺪ .ﺗﻤـﺎم ﺗﻨﻈﻴﻤـﺎت ﭘـﻴﺶ ﻓﺮض اﻳﻦ ﻛﻨﺘﺮل را ﻗﺒﻮل ﻛﻨﻴﺪ و ﺧﺎﺻﻴﺘﻬﺎي آن را ﺗﻐﻴﻴﺮ ﻧﺪﻫﻴﺪ. (4ﺑﺮ روي دﻛﻤﻪ ي btnFontدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳـﺮ را ﺑـﻪ آن ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )private void btnFont_Click(object sender, EventArgs e { // Set the FontDialog control properties ;fontDialog1.ShowColor = true // Show the Font dialog )if (fontDialog1.ShowDialog() == DialogResult.OK { // If the OK button was clicked set the font // in the text box on the form ;txtFile.Font = fontDialog1.Font // Set the color of the font in the text box // on the form ;txtFile.ForeColor = fontDialog1.Color } } (5ﺑﺎ ﻛﻠﻴﻚ ﺑﺮ روي دﻛﻤﻪ Startدر ﻧﻮار اﺑﺰار ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﺷﺪ ﺑـﺮ روي دﻛﻤـﻪ ي Fontﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻛﺎدر ﻣﺤﺎوره اي Fontﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 11-7ﻧﻤﺎﻳﺶ داده ﺷﻮد .ﻓﻮﻧﺖ و رﻧﮓ ﺟﺪﻳﺪي را ﺑﺮاي TextBoxاﻧﺘﺨﺎب ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ. (6ﺣﺎل ﭼﻨﺪﻳﻦ ﺧﻂ ﻣﺘﻦ را در ﻓﺮم وارد ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣﺘﻦ ﺑﺎ ﻓﻮﻧﺖ و رﻧﮓ ﺟﺪﻳﺪ ﻧﻮﺷﺘﻪ ﺧﻮاﻫﺪ ﺷﺪ. (7ﻫﻤﭽﻨﻴﻦ اﮔﺮ ﻓﺎﻳﻠﻲ را ﺑﺎ اﺳﺘﻔﺎده از دﻛﻤﻪ ي Openﺑﺎز ﻛﻨﻴﺪ ،رﻧﮓ و ﻓﻮﻧﺖ ﺟﺪﻳﺪ در آن اﻋﻤﺎل ﻣﻲ ﺷﻮد .ﺑﺮاي ﺗﺴﺖ اﻳـﻦ ﻣﻮرد روي دﻛﻤﻪ ي Openﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻛﺎدر Openﻧﻤﺎﻳﺶ داده ﺷﻮد ،ﺳﭙﺲ ﻳﻚ ﻓﺎﻳﻞ ﻣﺘﻨﻲ را اﻧﺘﺨﺎب ﻛـﺮده و آن را ﺑﺎز ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻣﺤﺘﻮﻳﺎت ﻓﺎﻳﻞ ﺑﺎ رﻧﮓ و ﻓﻮﻧﺖ ﺟﺪﻳﺪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
٢٧٦
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ،ﻗﺴﻤﺖ رﻧﮓ ﻛﺎدر Fontﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض ﻧﻤﺎﻳﺶ داده ﻧﻤﻲ ﺷﻮد ﭘﺲ ﺑﺮﻧﺎﻣـﻪ را ﺑـﺎ ﺗﻨﻈـﻴﻢ ﻣﻘـﺪار اﻳـﻦ ﺧﺎﺻﻴﺖ ﺑﺎ Trueآﻏﺎز ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻫﻨﮕﺎم ﻧﻤﺎﻳﺶ ﻛﺎدر ،Fontﻗﺴﻤﺖ Colorﻧﻴﺰ ﻧﻤﺎﻳﺶ داده ﺷﻮد. // Set the FontDialog control properties ;fontDialog1.ShowColor = true
ﺷﻜﻞ 11-7 ﺳﭙﺲ ﻛﺎدر Fontرا ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ و ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ دﺳﺘﻮر ifﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺮ روي دﻛﻤﻪ OKﻛﻠﻴـﻚ ﻛـﺮده اﺳــﺖ و ﻳــﺎ ﺑــﺮ روي دﻛﻤــﻪ .Cancelاﮔــﺮ ﻛــﺎرﺑﺮ ﺑــﺮ روي دﻛﻤــﻪ OKﻛﻠﻴــﻚ ﻛــﺮده ﺑﺎﺷــﺪ ،ﻫﻤﺎﻧﻨــﺪ ﻛﺎدرﻫــﺎي دﻳﮕــﺮ ،ﻣﻘــﺪار DialogResult.OKﺑﻪ وﺳﻴﻠﻪ ﺗﺎﺑﻊ ShowDialogﺑﺮﮔﺸﺘﻪ ﻣﻲ ﺷﻮد. // Show the Font dialog )if (fontDialog1.ShowDialog() == DialogResult.OK { // If the OK button was clicked set the font // in the text box on the form ;txtFile.Font = fontDialog1.Font // Set the color of the font in the text box // on the form ;txtFile.ForeColor = fontDialog1.Color ٢٧٧
} ﺑﺮاي ﺗﻐﻴﻴﺮ ﻓﻮﻧﺖ ، TextBoxﺧﺎﺻﻴﺖ Fontآن را ﺑﺮاﺑﺮ ﺑﺎ ﻓﻮﻧﺘﻲ ﻗﺮار ﻣﻲ دﻫﻴﻢ ﻛـﻪ ﻛـﺎرﺑﺮ در ﻛﻨﺘـﺮل FontDialog اﻧﺘﺨﺎب ﻛـﺮده اﺳـﺖ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﺑﺎﻳـﺪ از ﺧﺎﺻـﻴﺖ Fontﻛﻨﺘـﺮل FontDialogاﺳـﺘﻔﺎده ﻛﻨـﻴﻢ .ﻫﻤﭽﻨـﻴﻦ ﺧﺎﺻـﻴﺖ ForeColorﻛﻨﺘﺮل TextBoxرا ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎ ﺧﺎﺻﻴﺖ Colorﻛﻨﺘﺮل FontDialogﻗﺮار ﻣﻲ دﻫـﻴﻢ .ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴﺐ رﻧﮓ ﻣﺘﻦ داﺧﻞ TextBoxﺑﺮاﺑﺮ ﺑﺎ رﻧﮕﻲ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﺎرﺑﺮ در ﻛﺎدر Fontاﻧﺘﺨﺎب ﻛﺮده اﺳﺖ.
ﻛﻨﺘﺮل :ColorDialog در ﻣﻮاﻗﻌﻲ ﻣﻤﻜﻦ اﺳﺖ ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﻴﺪ رﻧﮕﻲ را در ﺑﺮﻧﺎﻣﻪ اﻧﺘﺨﺎب ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ از اﻳﻦ رﻧﮓ در ﺗﻨﻈﻴﻢ رﻧﮓ ﭘﺲ زﻣﻴﻨﻪ ي ﻓﺮم ،در ﺗﻨﻈﻴﻢ رﻧﮓ ﻳﻚ ﻛﻨﺘﺮل و ﻳﺎ ﺑﺮاي ﺗﻨﻈﻴﻢ رﻧﮓ ﻣﺘﻦ داﺧـﻞ TextBoxاﺳـﺘﻔﺎده ﻛﻨﻴـﺪ. وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﻫﻤﺎﻧﻨﺪ ﻛﺎدر ،Fontﻳﻚ ﻛﺎدر اﺳﺘﺎﻧﺪارد ﻧﻴﺰ ﺑﺮاي اﻧﺘﺨﺎب رﻧﮓ در اﺧﺘﻴﺎر ﺑﺮﻧﺎﻣـﻪ ﻧـﻮﻳﺲ ﻗـﺮار ﻣـﻲ دﻫـﺪ ﻛـﻪ ColorDialogﻧﺎم دارد .ﻫﻤﺎﻧﻨﺪ ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ،ﻛﺎدر ColorDialogﻫﻢ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﻋﻨﻮان ﻳﻚ ﻛﻨﺘﺮل و ﻫﻢ ﺑـﻪ ﻋﻨﻮان ﻳﻚ ﻛﻼس ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد. ﻛﻨﺘﺮل ColorDialogﻛﻪ در ﺷﻜﻞ 12-7ﻧﺸﺎن داده ﺷﺪه اﺳﺖ ،ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻣـﻲ دﻫـﺪ ﺑـﻴﻦ 48رﻧـﮓ اﺑﺘـﺪاﻳﻲ رﻧﮕـﻲ را اﻧﺘﺨﺎب ﻛﻨﺪ.
ﺷﻜﻞ 12-7 دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻋﻼوه ﺑﺮ اﻳﻦ رﻧﮕﻬﺎي اﺑﺘﺪاﻳﻲ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺮ روي دﻛﻤﻪ ي Define Custom Colorﻛﻠﻴﻚ ﻛـﺮده و ﺑﺎ ﺗﺮﻛﻴﺐ رﻧﮕﻬﺎ ،رﻧﮓ ﻣﻮرد ﻧﻈﺮ ﺧﻮد را اﻳﺠﺎد ﻛﻨﺪ .اﻳﻦ ﻣﻮرد ﺑﺎﻋﺚ اﻧﻌﻄﺎف ﭘﺬﻳﺮي ﺑﻴﺸﺘﺮ اﻳﻦ ﻛﺎدر ﻣﻲ ﺷﻮد و ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻣﻲ دﻫﺪ رﻧﮓ ﻣﻮرد ﻧﻈﺮ ﺧﻮد را اﻳﺠﺎد ﻛﺮده و در ﺑﺮﻧﺎﻣﻪ از آن اﺳﺘﻔﺎده ﻛﻨﺪ )ﺷﻜﻞ .(13-7
٢٧٨
ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل :ColorDialog ﻗﺒﻞ از اﻳﻨﻜﻪ از اﻳﻦ ﻛﻨﺘﺮل در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﺑﻌﻀﻲ از ﺧﺎﺻﻴﺘﻬﺎي ﭘﺮ ﻛﺎرﺑﺮد آن را ﺑﺮرﺳـﻲ ﻛﻨـﻴﻢ .در ﺟـﺪول زﻳـﺮ ﻧـﺎم ﺗﻌﺪادي از آن ﺧﺎﺻﻴﺖ ﻫﺎ و ﻧﻴﺰ ﻛﺎرﺑﺮد آﻧﻬﺎ ﺷﺮح داده ﺷﺪه اﺳﺖ: ﺧﺎﺻﻴﺖ
ﺷﺮح
AllowFullOpe n
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ آﻳﺎ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ از ﻗﺴﻤﺖ Custom Colorﻧﻴﺰ ﺑﺮاي ﺗﻌﺮﻳـﻒ رﻧﮓ ﺟﺪﻳﺪ اﺳﺘﻔﺎده ﻛﻨﺪ ﻳﺎ ﻧﻪ .در ﺻﻮرﺗﻲ ﻛﻪ ﻣﻘﺪار اﻳﻦ ﮔﺰﻳﻨﻪ ﺑﺮاﺑﺮ ﺑﺎ Falseﺑﺎﺷـﺪ ،دﻛﻤـﻪ ﻓﺮﻣﺎن Define Custom Colorsﻏﻴﺮ ﻓﻌﺎل ﺧﻮاﻫﺪ ﺑﻮد.
AnyColor
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ آﻳﺎ ﻛﺎدر ﻣﺤﺎوره اي ﺗﻤﺎم رﻧﮕﻬﺎي ﻣﻮﺟﻮد را ﺑﻪ ﻋﻨـﻮان رﻧﮕﻬـﺎي اﺑﺘـﺪاﻳﻲ ﻧﻤﺎﻳﺶ دﻫﺪ ﻳﺎ ﻧﻪ؟
Color
رﻧﮕﻲ ﻛﻪ در ﻛﺎدر ﺑﻪ وﺳﻴﻠﻪ ﻛﺎرﺑﺮ اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ.
CustomColors
ﻣﺠﻤﻮﻋﻪ رﻧﮕﻬﺎﻳﻲ را ﻛﻪ در ﺑﺨﺶ Custom Colorﻛﺎدر ﻧﻤـﺎﻳﺶ داده ﻣـﻲ ﺷـﻮد را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ.
FullOpen
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛـﻪ ﻫﻨﮕـﺎم ﻧﻤـﺎﻳﺶ داده ﺷـﺪن ﻛـﺎدر Colorﻗـﺴﻤﺖ Colorﻫﻢ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض دﻳﺪه ﺷﻮد ﻳﺎ ﻧﻪ؟
ShowHelp
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ دﻛﻤﻪ ﻓﺮﻣﺎن Helpدر ﻛﺎدر Colorﻧﻤﺎﻳﺶ داده ﺷﻮد ﻳﺎ ﻧﻪ؟
Custom
ﺷﻜﻞ 13-7
٢٧٩
ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﺧﺎﺻﻴﺘﻬﺎي اﻳﻦ ﻛﻨﺘﺮل ﻧﺴﺒﺖ ﺑﻪ ﻛﻨﺘﺮل ﻫﺎي ﻗﺒﻠﻲ ﻛﻤﺘﺮ اﺳﺖ .ﻫﻤﻴﻦ ﻣﻮرد ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ اﺳﺘﻔﺎده از اﻳﻦ ﻛﻨﺘﺮل ﺣﺘﻲ از ﻛﻨﺘﺮﻟﻬﺎي ﻗﺒﻠﻲ ﻧﻴﺰ راﺣﺖ ﺗﺮ ﺑﺎﺷﺪ. ﻫﻤﺎﻧﻨﺪ ﻛﺎدرﻫﺎي ﻗﺒﻠﻲ ،ﻛﻨﺘﺮل ColorDialogﻧﻴﺰ داراي ﺗﺎﺑﻊ ShowDialogاﺳﺖ ﻛﻪ ﺑﺎﻋـﺚ ﻧﻤـﺎﻳﺶ آن ﻣـﻲ ﺷـﻮد. ﻧﺤﻮه ﻛﺎرﻛﺮد اﻳﻦ ﺗﺎﺑﻊ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻦ ﻗﺴﻤﺖ از ﺗﻮﺿﻴﺢ ﻣﺠﺪد آن ﺻﺮﻓﻨﻈﺮ ﻣﻲ ﻛﻨﻴﻢ.
اﺳﺘﻔﺎده از ﻛﻨﺘﺮل :ColorDialog ﺑﺮاي ﻧﻤﺎﻳﺶ ﻛﺎدر Colorﺗﻨﻬﺎ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﻣﺘﺪ ShowDialogآن را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ: ;)(colorDialog1.ShowDialog اﻳﻦ ﺗﺎﺑﻊ ﻣﻘﺪاري را از ﻧﻮع DialogResultﺑﺮﻣﻲ ﮔﺮداﻧﺪ ﻛﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﺎرﺑﺮ در ﻛﺎدر ﺑﺮ روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﺮده اﺳﺖ و ﻳﺎ ﺑﺮ روي دﻛﻤﻪ .Cancelﻫﻤﺎﻧﻨﺪ ﻗﺴﻤﺖ ﻗﺒﻠﻲ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ دﺳﺘﻮر ifﻧﺘﻴﺠﻪ ﻛﺎدر را ﺑﺮرﺳﻲ ﻛﻨﻴﺪ. ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻣﻘﺪار رﻧﮕﻲ ﻛﻪ ﺗﻮﺳﻂ ﻛﺎرﺑﺮ در اﻳﻦ ﻛﺎدر اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ﺑﺎﻳﺪ از ﺧﺎﺻﻴﺖ Colorاﻳـﻦ ﻛﻨﺘـﺮل اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ. ﺳﭙﺲ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ رﻧﮓ را ﺑﻪ ﻛﻨﺘﺮﻟﻬﺎﻳﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ رﻧﮓ آﻧﻬﺎ را ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ ﻧﺴﺒﺖ دﻫﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ رﻧـﮓ ﻣـﺘﻦ ﻳـﻚ TextBoxرا ﺑﺮاﺑﺮ ﺑﺎ رﻧﮓ اﻧﺘﺨﺎب ﺷﺪه در اﻳﻦ ﻛﺎدر ﻗﺮار دﻫﻴﺪ: ;txtFile.ForeColor = colorDialog1.Color در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﻪ ﭘﺮوژه ﻗﺒﻠﻲ اﻣﻜﺎﻧﻲ را اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺘﻮاﻧﺪ ﺑﻪ وﺳﻴﻠﻪ آن رﻧﮓ زﻣﻴﻨﻪ ﻓﺮم را ﺗﻐﻴﻴﺮ دﻫﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻛﺎر ﺑﺎ ﻛﻨﺘﺮل ColorDialog (1ﭘﺮوژه Dialogsرا ﺑﺎز ﻛﺮده و ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ Form1ﺑﺮوﻳﺪ. (2ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل Buttonﺑﺮ روي ﻓﺮم ﻗﺮار داده و ﺧﺎﺻﻴﺘﻬﺎي آن را ﻣﻄـﺎﺑﻖ ﺑـﺎ ﻣﻘـﺎدﻳﺮ زﻳـﺮ ﺗﻨﻈـﻴﻢ ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑﺎ btnColorﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Anchorآن را ﺑﺮاﺑﺮ ﺑﺎ Top,Rightﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Locationآن را ﺑﺮاﺑﺮ ﺑﺎ 367;98ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Colorﻗﺮار دﻫﻴﺪ.
(3ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻗﺴﻤﺖ Dialogsﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل ColorDialogﺑـﻪ ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ .اﻳـﻦ ﻛﻨﺘﺮل ﺑﻪ ﻗﺴﻤﺖ ﭘﺎﻳﻦ ﻃﺮاﺣﻲ ﻓﺮم اﺿﺎﻓﻪ ﺧﻮاﻫﺪ ﺷﺪ.
٢٨٠
(4ﺑﺮ روي دﻛﻤﻪ ي btnColorدو ﺑﺎر ﻛﻠﻴﻚ ﻛﺮده ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳـﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )private void btnColoe_Click(object sender, EventArgs e { // Show the Color dialog )if (colorDialog1.ShowDialog() == DialogResult.OK { // Set the BackColor property of the form ;this.BackColor = colorDialog1.Color } } (5 (6
(7 (8
ﺗﻤﺎم ﻛﺪي ﻛﻪ ﺑﺎﻳﺪ وارد ﻣﻲ ﻛﺮدﻳﺪ ﻫﻤﻴﻦ ﺑﻮد .ﺑﺮاي اﻣﺘﺤﺎن ﺑﺮﻧﺎﻣﻪ ﺑﺮ روي دﻛﻤﻪ Startدر ﻧﻮار اﺑﺰار ﻛﻠﻴﻚ ﻛﻨﻴﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﺷﺪ ،ﺑﺮ روي دﻛﻤﻪ ي Colorﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻛﺎدر ﻣﺤـﺎوره اي Colorﻧﻤـﺎﻳﺶ داده ﺷﻮد .در اﻳﻦ ﻛﺎدر ﻳﻜﻲ از رﻧﮕﻬﺎي اﺑﺘﺪاﻳﻲ را اﻧﺘﺨﺎب ﻛﺮده و ﻳﺎ روي دﻛﻤـﻪ Define Custom Color ﻛﻠﻴﻚ ﻛﻨﻴﺪ و رﻧﮕﻲ را از آن ﻗﺴﻤﺖ اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺳﭙﺲ روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻛﺎدر ﺑﺴﺘﻪ ﺷﻮد. ﺑﺎ ﻛﻠﻴﻚ روي دﻛﻤﻪ OKدر ﻛﺎدر Colorرﻧﮓ زﻣﻴﻨﻪ ﻓﺮم ﺑﺎ رﻧﮕﻲ ﻛﻪ در ﻛﺎدر اﻧﺘﺨﺎب ﻛﺮده ﺑﻮدﻳﺪ ﺗﻌﻮﻳﺾ ﻣﻲ ﺷﻮد. ﻫﻤﺎﻧﻨﺪ ﻛﺎدر Fontﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﻗﺒﻞ از ﻧﻤﺎﻳﺶ ﻓﺮم ،ﺧﺎﺻﻴﺖ Colorرا ﺑﺮاﺑﺮ رﻧﮓ اﻧﺘﺨﺎب ﺷﺪه در ﻣﺮﺣﻠـﻪ ﻗﺒﻠـﻲ ﻗﺮار دﻫﻴﺪ .زﻳﺮا ﻛﻨﺘﺮل ColorDialogﺧﻮد ﻣﻘﺪار رﻧﮕﻲ ﻛﻪ آﺧﺮﻳﻦ ﺑﺎر ﺗﻮﺳﻂ ﻛﺎرﺑﺮ اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ را ﻧﮕﻬـﺪاري ﻣﻲ ﻛﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﻌﺪ از اﻳﻨﻜﻪ ﻛﺎرﺑﺮ ﻣﺠﺪداً وارد اﻳﻦ ﻛﺎدر ﺷﺪ ،ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﺪ رﻧﮕﻲ ﻛﻪ در ﻣﺮﺣﻠﻪ ﻗﺒﻞ اﻧﺘﺨﺎب ﻛـﺮده ﺑﻮد ،ﻫﻤﭽﻨﺎن ﺑﻪ ﺻﻮرت اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اﻳﻦ ﻣﺮﺗﺒﻪ ﺑﺮاي ﻓﺮاﺧﻮاﻧﻲ ﺗﺎﺑﻊ ShowDialogﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﺧﺎﺻﻴﺘﻬﺎي ﻛﺎدر Colorرا ﺗﻐﻴﻴﺮ دﻫﻴﻢ .ﺑﻪ ﻫﻤـﻴﻦ دﻟﻴـﻞ ﺑـﻪ ﻗﺴﻤﺖ ﻓﺮاﺧﻮاﻧﻲ ﺗﺎﺑﻊ درون دﺳﺘﻮر ifﻣﻲ روﻳﻢ .ﻫﻤﺎﻧﻨﺪ ﺑﺨﺸﻬﺎي ﻗﺒﻠﻲ ،اﮔﺮ ﻛﺎرﺑﺮ در ﻛـﺎدر Colorروي دﻛﻤـﻪ ي OKﻛﻠﻴـﻚ ﻛﻨﺪ ﺗﺎﺑﻊ ShowDialogﻣﻘﺪار DialogResult.OKرا ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .ﺑﻪ ﻫﻤﻴﻦ ﻋﻠـﺖ در دﺳـﺘﻮر ifﺑﺮرﺳـﻲ ﻣـﻲ ﻛﻨﻴﻢ ﻛﻪ ﻣﻘﺪار ﺑﺮﮔﺸﺘﻲ از ﺗﺎﺑﻊ ﺑﺮاﺑﺮ ﺑﺎ DialogResult.OKﻫﺴﺖ ﻳﺎ ﻧﻪ؟ // Show the Color dialog )if (colorDialog1.ShowDialog() == DialogResult.OK اﮔﺮ ﻣﻘﺪار ﺑﺮﮔﺸﺘﻲ ﺑﺮاﺑﺮ ﺑﺎ DialogResult.OKﺑﻮد ﺑﺎﻳﺪ رﻧﮓ ﭘﻴﺶ زﻣﻴﻨﻪ ﻓﺮم را ﺗﻐﻴﻴﺮ دﻫﻴﻢ .ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ در ﻗـﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﻧﻴﺰ ﮔﻔﺘﻴﻢ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﺧﺎﺻﻴﺘﻬﺎي ﻳﻚ ﻛﻼس ،درون ﺧﻮد ﻛـﻼس ﺑﺎﻳـﺪ از ﻛﻠﻤـﻪ ﻛﻠﻴـﺪي thisاﺳـﺘﻔﺎده ﻛﻨـﻴﻢ .ﺑـﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﺧﺎﺻﻴﺘﻬﺎي ﻓﺮم ﻧﻴﺰ ،ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ درون ﻛﻼس ﻓﺮم ﻫﺴﺘﻴﻢ از ﻛﻠﻤﻪ ﻛﻠﻴﺪي thisاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .ﺳـﭙﺲ ﺧﺎﺻـﻴﺖ BackColorﻓﺮم را ﺑﺮاﺑﺮ ﺑﺎ رﻧﮕﻲ ﻗﺮار ﻣﻲ دﻫﻴﻢ ﻛﻪ ﺗﻮﺳﻂ ﻛﺎرﺑﺮ در ﻛﺎدر Colorاﻧﺘﺨﺎب ﺷﺪه اﺳﺖ. // Set the BackColor property of the form ;this.BackColor = colorDialog1.Color ٢٨١
ﻛﻨﺘﺮل :PrintDialog ﻫﺮ ﺑﺮﻧﺎﻣﻪ اي ﻣﻌﻤﻮﻻً در ﻗﺴﻤﺘﻲ ﻧﻴﺎز ﺑﻪ اﻣﻜﺎن ﭼﺎپ دارد .اﻳﻦ ﻧﻴﺎز ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺻﻮرت ﻧﻴﺎز ﺑـﻪ ﭼـﺎپ ﺳـﺎده ي ﻳـﻚ ﻣـﺘﻦ و ﻳـﺎ ﻣـﻮارد ﭘﻴﺸﺮﻓﺘﻪ ﺗﺮي ﻣﺎﻧﻨﺪ ﭼﺎپ ﻗﺴﻤﺘﻲ از ﻣﺘﻦ و ﻳﺎ ﺻﻔﺤﺎت ﻣﺸﺨﺼﻲ از آن ﺑﺎﺷﺪ .در ﻗﺴﻤﺖ ﺑﻌﺪ ﺑﻪ ﺑﺮرﺳﻲ ﭼﮕﻮﻧﮕﻲ ﭼﺎپ ﻳﻚ ﻣـﺘﻦ ﺳـﺎده ﺧﻮاﻫﻴﻢ ﭘﺮداﺧﺖ و ﻧﺤﻮه اﺳﺘﻔﺎده از ﻛﻼﺳﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﭼﺎپ در .NETرا ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد. ﻳﻜﻲ از ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ در وﻳﮋوال 2005 C#ﺑﺮاي ﭼﺎپ ﺑﻪ ﻛﺎر ﻣﻲ رود ،ﻛﻨﺘﺮل PrintDialogاﺳﺖ .اﻳﻦ ﻛﻨﺘﺮل ﻛﺎر ﭼـﺎپ را اﻧﺠﺎم ﻧﻤﻲ دﻫﺪ ،ﺑﻠﻜﻪ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻣﻲ دﻫﺪ ﻛﻪ ﭼﺎﭘﮕﺮي را ﺑﺮاي ﭼﺎپ اﻧﺘﺨﺎب ﻛﺮده و ﺗﻨﻈﻴﻤﺎت ﻗﺒﻞ از ﭼﺎپ را در آن ﭼﺎﭘﮕﺮ اﻧﺠـﺎم دﻫﺪ .ﺑﺮاي ﻣﺜﺎل ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ در اﻳﻦ ﻛﺎدر ﺟﻬﺖ ﺻﻔﺤﻪ ،ﻛﻴﻔﻴﺖ ﭼﺎپ و ﻳﺎ ﻣﺤﺪوده ﻣﻮردﻧﻈﺮ ﺑﺮاي ﭼﺎپ را ﺗﻌﻴﻴﻦ ﻛﻨـﺪ .ﺷـﻤﺎ از اﻳـﻦ وﻳﮋﮔﻲ ﻫﺎ در ﻣﺜﺎل ﺑﻌﺪي اﺳﺘﻔﺎده ﻧﺨﻮاﻫﻴﺪ ﻛﺮد ،اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ 14-7ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﺗﻤﺎم اﻳﻦ ﻗﺎﺑﻠﻴﺖ ﻫﺎ ﺑﻪ وﺳـﻴﻠﻪ ﻛـﺎدر PrintDialogﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ اﺳﺖ. ﻫﻤﺎﻧﻨﺪ ﺗﻤﺎم ﻛﺎدرﻫﺎﻳﻲ ﻛﻪ در ﺑﺨﺸﻬﺎي ﻗﺒﻠﻲ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﻛﺎدر Printﻧﻴﺰ داراي دو دﻛﻤﻪ OKو Cancelاﺳﺖ .ﺑﻨـﺎﺑﺮاﻳﻦ ﺗـــــﺎﺑﻊ ShowDialogﻣﺮﺑـــــﻮط ﺑـــــﻪ اﻳـــــﻦ ﻛـــــﺎدر ﻫـــــﻢ ﻣﻘـــــﺪار DialogResult.OKو ﻳـــــﺎ DialogResult.Cancelرا ﺑﺮﻣﻲ ﮔﺮداﻧﺪ و ﻣﻲ ﺗﻮاﻧﻴﺪ از دﺳﺘﻮر ifﺑﺮاي ﺑﺮرﺳﻲ ﻧﺘﻴﺠـﻪ ﺑﺮﮔـﺸﺖ داده ﺷـﺪه ﺗﻮﺳـﻂ ﻛﺎدر اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
ﺷﻜﻞ 14-7
٢٨٢
ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل :PrintDialog در ﺟﺪول زﻳﺮ ﻟﻴﺴﺘﻲ از ﺧﺎﺻﻴﺘﻬﺎي ﭘﺮ ﻛﺎرﺑﺮد ﻛﻨﺘﺮل PrintDialogو ﻧﻴﺰ ﺗﻮﺿﻴﺢ آﻧﻬﺎ آﻣﺪه اﺳﺖ: ﺧﺎﺻﻴﺖ
ﺷﺮح
AllowPrintToFile
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳﺎ در ﻛﺎدر ﮔﺰﻳﻨﻪ Print To Fileﻓﻌﺎل ﺑﺎﺷﺪ ﻳﺎ ﻧﻪ؟
AllowSelection
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ در ﻛﺎدر ،دﻛﻤﻪ رادﻳﻮﻳﻲ Selectinﻓﻌﺎل ﺑﺎﺷﺪ ﻳﺎ ﻧﻪ؟
AllowSomePages
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ در ﻛﺎدر ،دﻛﻤﻪ رادﻳﻮﻳﻲ Pagesﻓﻌﺎل ﺑﺎﺷﺪ ﻳﺎ ﻧﻪ؟
Document
ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﺳﻨﺪي اﺳﺖ ﻛﻪ ﺑﺮاي ﭼﺎپ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد.
PrinterSettings
ﺗﻨﻈﻴﻤﺎﺗﻲ ﻛﻪ در ﻛﺎدر ،ﺑﺮاي ﭼﺎﭘﮕﺮ اﻧﺘﺨﺎﺑﻲ اﻋﻤﺎل ﻣﻲ ﺷﻮد را ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ.
PrintToFile
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳﺎ ﮔﺰﻳﻨﻪ Print to fileاﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ﻳﺎ ﻧﻪ؟
ShowHelp
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳﺎ دﻛﻤﻪ ﻓﺮﻣﺎن Helpدر ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﺷﻮد ﻳﺎ ﻧﻪ؟
ShowNetwork
ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ دﻛﻤﻪ ﻓﺮﻣﺎن Networkدر ﻛﺎدر Printﻧﻤﺎﻳﺶ داده ﺷـﻮد ﻳﺎ ﻧﻪ؟
اﺳﺘﻔﺎده از ﻛﻨﺘﺮل :PrintDialog ﺑﺮاي ﻧﻤﺎﻳﺶ ﻛﺎدر Printﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﺗﺎﺑﻊ ShowDialogآن را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺻﻮرت ﻛﺎدر Printﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 14-7ﻧﺸﺎن داده ﺧﻮاﻫﺪ ﺷﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﭘﻴﺸﺘﺮ ﻧﻴﺰ ﮔﻔﺘﻢ ﻛﻨﺘﺮل PrintDialogﻓﻘﻂ ﻛﺎدري را ﺑﺮاي ﺗﻨﻈﻴﻤـﺎت ﭼـﺎپ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ و ﻫﻴﭻ ﻣﺘﻨﻲ را ﻧﻤﻲ ﺗﻮاﻧﺪ ﭼﺎپ ﻛﻨﺪ .ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ ﺑﺮاي ﻧﻤﺎﻳﺶ ﻛﺎدر Printﻣﻲ ﺗﻮاﻧﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد: ;)(printDialog1.ShowDialog
ﻛﻼس :PrintDocument ﻗﺒﻞ از اﻳﻨﻜﻪ ﺗﺎﺑﻊ ShowDialogدر ﻛﻨﺘﺮل PrintDialogرا ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ ﺧﺎﺻﻴﺖ Documentﻛـﻼس PrintDialogرا ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ .اﻳﻦ ﺧﺎﺻﻴﺖ ﻣﻘﺪاري را از ﻧﻮع ﻛﻼس PrintDocumentدرﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ .ﻛـﻼس PrintDocumentﻣﻲ ﺗﻮاﻧﺪ ﺗﻨﻈﻴﻤﺎت ﭼﺎﭘﮕﺮ را درﻳﺎﻓﺖ ﻛﺮده و ﺳﭙﺲ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ آن ﺗﻨﻈﻴﻤﺎت ،ﺧﺮوﺟﻲ ﺧﻮد )ﻛﻪ در ﺣﻘﻴﻘﺖ ﻫﻤـــﺎن اﻃﻼﻋـــﺎت ﻣـــﻮرد ﻧﻈـــﺮ ﻣـــﺎ اﺳـــﺖ( را ﺑـــﺮاي ﭼـــﺎپ ﺑـــﻪ ﭼـــﺎﭘﮕﺮ ﻣـــﻲ ﻓﺮﺳـــﺘﺪ .اﻳـــﻦ ﻛـــﻼس در ﻓـــﻀﺎي ﻧـــﺎم System.Drawing.Printingﻗﺮار دارد .ﭘﺲ ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﻗﺒﻞ از اﺳﺘﻔﺎده از آن ﺑﺮاي اﻳﻨﻜﻪ ﻫﺮ ﺑﺎر ﻧﺎم ﻛﺎﻣﻞ اﻳﻦ ﻓﻀﺎي ﻧﺎم را وارد ﻧﻜﻨﻴﻢ ،ﺑﺎ اﺳﺘﻔﺎده از راﻫﻨﻤﺎي usingآن را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ.
٢٨٣
ﺧﺼﻮﺻﻴﺎت ﻛﻼس :PrintDocument ﻗﺒﻞ از اداﻣﻪ ﺑﻬﺘﺮ اﺳﺖ ﻧﮕﺎﻫﻲ ﺑﻪ ﺑﻌﻀﻲ از ﺧﺼﻮﺻﻴﺎت ﻣﻬﻢ ﻛﻼس PrintDocumentﻛﻪ در ﺟﺪول زﻳـﺮ آﻣـﺪه اﻧـﺪ داﺷـﺘﻪ ﺑﺎﺷﻴﻢ. ﺧﺼﻮﺻﻴﺖ
ﺷﺮح
DefaultPageSettings
ﻣﺸﺨﺺ ﻛﻨﻨﺪه ي ﺗﻨﻈﻴﻤﺎت ﭘﻴﺶ ﻓﺮض ﭼﺎﭘﮕﺮ ﺑـﺮاي ﭼـﺎپ ﺳـﻨﺪ )اﻃﻼﻋـﺎت( ﻣﻮرد ﻧﻈﺮ اﺳﺖ.
DocumentName
ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻧﺎﻣﻲ اﺳﺖ ﻛﻪ ﻫﻨﮕﺎم ﭼﺎپ ﺳﻨﺪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﻫﻤﭽﻨﻴﻦ اﻳﻦ ﻧﺎم در ﻛﺎدر Print Statusو در ﻟﻴﺴﺖ اﺳﻨﺎد ﻣﻮﺟـﻮد در ﺻـﻒ ﭼﺎپ ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن ﺳﻨﺪ ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد.
PrintController
ﻣﺤﺘﻮي ﺷﻴﺊ از ﻛﻼس PrintControllerاﺳﺖ ﻛﻪ ﭘﺮوﺳﻪ ﭼﺎپ را ﻣﺪﻳﺮﻳﺖ ﻣﻲ ﻛﻨﺪ.
PrinterSettings
ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﭼﺎﭘﮕﺮي اﺳﺖ ﻛﻪ ﺑﺮاي ﭼﺎپ اﻳﻦ ﺳﻨﺪ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد.
ﭼﺎپ ﻳﻚ ﺳﻨﺪ: ﻣﺘـــﺪ Printاز ﻛـــﻼس PrintDocumentﺳـــﻨﺪي را ﺑـــﻪ وﺳـــﻴﻠﻪ ﭼـــﺎﭘﮕﺮ ﻣـــﺸﺨﺺ ﺷـــﺪه در ﺧﺎﺻـــﻴﺖ PrinterSettingsﭼﺎپ ﻣﻲ ﻛﻨﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻳﻦ ﺗﺎﺑﻊ را در ﺑﺮﻧﺎﻣﻪ ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ ،ﻫﺮ ﺑﺎر ﻛـﻪ ﺻـﻔﺤﻪ اي ﺑﺨﻮاﻫـﺪ ﺑـﻪ وﺳﻴﻠﻪ اﻳﻦ ﺗﺎﺑﻊ ﭼﺎپ ﺷﻮد ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد PrintPageاز ﻛﻼس PrintDocumentﻧﻴﺰ ﻓﺮاﺧـﻮاﻧﻲ ﻣـﻲ ﺷـﻮد. ﺗﺎﺑﻊ Printﺑﻪ وﺳﻴﻠﻪ اﻳﻦ ﻣﺘﺪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺪام ﺑﺨﺶ از ﻓﺎﻳﻞ ﺑﺎﻳﺪ در ﺻﻔﺤﻪ ﺟﺎري ﭼﺎپ ﺷـﻮد .ﺑﻨـﺎﺑﺮاﻳﻦ ﻗﺒـﻞ از اﻳﻨﻜـﻪ ﺑﺘﻮاﻧﻴﺪ ﻣﺘﻨﻲ را ﭼﺎپ ﻛﻨﻴﺪ ﺑﺎﻳﺪ ﻣﺘﺪي را ﺑﺮاي اﻳﻦ روﻳﺪاد اﻳﺠﺎد ﻛﻨﻴﺪ .ﺳﭙﺲ در اﻳﻦ ﻣﺘﺪ ﺑﺎﻳﺪ ﻳﻚ ﺻﻔﺤﻪ از ﻣـﺘﻦ را ﺑـﻪ وﺳـﻴﻠﻪ ﻛـﻼس StreamReaderاز ﻓﺎﻳﻞ ﺧﻮاﻧﺪه و آن را ﺑﻪ ﭼﺎﭘﮕﺮ ﺑﻔﺮﺳﺘﻴﺪ ﺗﺎ ﭼﺎپ ﺷﻮد. در ﺑﺨــﺶ اﻣﺘﺤــﺎن ﻛﻨﻴــﺪ زﻳــﺮ ﻣــﺸﺎﻫﺪه ﺧــﻮاﻫﻴﻢ ﻛــﺮد ﻛــﻪ ﭼﮕﻮﻧــﻪ ﻣــﻲ ﺗــﻮان ﻣﺤﺘﻮﻳــﺎت ﻳــﻚ ﻓﺎﻳــﻞ ﻣﺘﻨــﻲ را ﺑــﻪ وﺳــﻴﻠﻪ ﻛــﻼس PrintDocumentﭼﺎپ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻛﺎر ﺑﺎ ﻛﻨﺘﺮل PrintDialog (1 (2
در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ،ﭘﺮوژه Dialogsرا ﺑﺎز ﻛﻨﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻛﻨﺘﺮل Buttonدﻳﮕﺮي را ﺑﺮ روي ﻓﺮم ﻗﺮار داده و ﺧﺎﺻﻴﺘﻬﺎي آن را ﻣﻄﺎﺑﻖ ﻟﻴﺴﺖ زﻳﺮ ﺗﻨﻈـﻴﻢ ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ btnPrintﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Anchorرا ﺑﺮاﺑﺮ ﺑﺎ Top,Rightﻗﺮار دﻫﻴﺪ.
٢٨٤
. ﻗﺮار دﻫﻴﺪ367;128 را ﺑﺮاﺑﺮ ﺑﺎLocation ﺧﺎﺻﻴﺖ . ﻗﺮار دﻫﻴﺪPrint را ﺑﺮاﺑﺮ ﺑﺎText ﺧﺎﺻﻴﺖ
دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑـﺮ رويPrintDialog ﺑﺮوﻳﺪ و ﺑﺮ روي ﻛﻨﺘﺮلPrinting در ﺟﻌﺒﻪ اﺑﺰار ﺑﻪ ﻗﺴﻤﺖ در ﭘﺎﻳﻴﻦ ﻗـﺴﻤﺖ ﻃﺮاﺣـﻲ ﻓـﺮم ﻗـﺮار ﻣـﻲ، ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ اﻳﻦ ﻛﻨﺘﺮل ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻛﺎدرﻫﺎي ﻗﺒﻠﻲ.ﻓﺮم ﻗﺮار ﺑﮕﻴﺮد .ﮔﻴﺮد : ﻓﻀﺎي ﻧﺎﻣﻬﺎي زﻳﺮ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪusing ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﺑﺮوﻳﺪ و ﺑﺎ اﺳﺘﻔﺎده از راﻫﻨﻤﺎي
(3
(4
using System.IO; using System.Drawing.Printing; :ﺣﺎل ﻣﺘﻐﻴﺮﻫﺎي زﻳﺮ را ﺑﻪ ﺻﻮرت ﻋﻤﻮﻣﻲ در اﺑﺘﺪاي ﻛﻼس ﻣﺮﺑﻮط ﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ
(5
// Declare variables private string strFileName; private StreamReader objStreamToPrint; private Font objPrintFont; دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آنbtnPrint ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ و ﺑﺮ روي دﻛﻤﻪ ي : ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ.اﻳﺠﺎد ﺷﻮد
(6
private void btnPrint_Click(object sender, EventArgs e) { // Declare an object for the PrintDocument class PrintDocument objPrintDocument = new PrintDocument(); // Set the DocumentName property objPrintDocument.DocumentName = "Text File Print Demo"; // Set the PrintDialog properties printDialog1.AllowPrintToFile = false; printDialog1.AllowSelection = false; printDialog1.AllowSomePages = false; // Set the Document property for // the objPrintDocument object printDialog1.Document = objPrintDocument; // Show the Print dialog if (printDialog1.ShowDialog() == DialogResult.OK) { // If the user clicked on the OK button ٢٨٥
// then set the StreamReader object to // the file name in the strFileName variable objStreamToPrint = new StreamReader(strFileName); // Set the printer font objPrintFont = new Font("Arial", 10); // Set the PrinterSettings property of the // objPrintDocument Object to the // PrinterSettings property returned from the // PrintDialog control objPrintDocument.PrinterSettings = printDialog1.PrinterSettings; // Add an event handler for the PrintPage event of // the objPrintDocument object objPrintDocument.PrintPage += new PrintPageEventHandler(prtPage); // Print the text file objPrintDocument.Print(); // Clean up objStreamToPrint.Close(); objStreamToPrint = null; } } :ﺳﭙﺲ ﻣﺘﺪ زﻳﺮ را در ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ وارد ﻛﻨﻴﺪ
(7
private void prtPage(object sender, PrintPageEventArgs e) { // Declare variables float sngLinesPerpage = 0; float sngVerticalPosition = 0; int intLineCount = 0; float sngLeftMargin = e.MarginBounds.Left; float sngTopMargin = e.MarginBounds.Top; string strLine; // Work out the number of lines per page. // Use the MarginBounds on the event to do this sngLinesPerpage = e.MarginBounds.Height / objPrintFont.GetHeight(e.Graphics);
٢٨٦
// Now iterate through the file printing out each line. // This assumes that a single line is not wider than // the page width. Check intLineCount first so that we // don’t read a line that we won’t print strLine = objStreamToPrint.ReadLine(); while((intLineCount < sngLinesPerpage) && (strLine != null)) { // Calculate the vertical position on the page sngVerticalPosition = sngTopMargin + (intLineCount * objPrintFont.GetHeight(e.Graphics)); // Pass a StringFormat to DrawString for the // Print Preview control e.Graphics.DrawString(strLine, objPrintFont, Brushes.Black, sngLeftMargin, sngVerticalPosition, new StringFormat()); // Increment the line count intLineCount = intLineCount + 1; // If the line count is less than the lines per // page then read another line of text if (intLineCount < sngLinesPerpage) { strLine = objStreamToPrint.ReadLine(); } } // If we have more lines then print another page if (strLine != null) { e.HasMorePages = true; } else { e.HasMorePages = false; } } در ﻧﻮار اﺑﺰار ﻛﻠﻴﻚ ﻛﻨﻴـﺪ ﺗـﺎStart ﺑﻨﺎﺑﺮاﻳﻦ روي دﻛﻤﻪ.ﺣﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﻋﻤﻠﻜﺮد ﻛﺪﻫﺎي اﻳﻦ ﻗﺴﻤﺖ را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ .ﺑﺮﻧﺎﻣﻪ اﺟﺮا ﺷﻮد
٢٨٧
(8
(9در ﻓﺮم اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ روي دﻛﻤﻪ ي Openﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻓﺎﻳﻠﻲ را ﺑﺎز ﻛﻨﻴﺪ ﺗﺎ ﻣﺤﺘﻮﻳـﺎت آن در ﻓـﺮم ﻧﻤـﺎﻳﺶ داده ﺷـﻮد. ﺳﭙﺲ ﺑﺮ روي دﻛﻤﻪ ي Printﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻛﺎدر ﻣﺤﺎوره اي Printﻫﻤﺎﻧﻨﺪ ﺷـﻜﻞ 15-7ﻧﻤـﺎﻳﺶ داده ﺷـﻮد. ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﻛﺎدر ﮔﺰﻳﻨﻪ Print to fileو ﻫﻤﭽﻨﻴﻦ ﻗـﺴﻤﺘﻬﺎي Selectionو Pages ﻏﻴﺮ ﻓﻌﺎل ﻫﺴﺘﻨﺪ .دﻟﻴﻞ ﻏﻴﺮ ﻓﻌﺎل ﺑﻮدن اﻳﻦ ﻗﺴﻤﺘﻬﺎ ﺑﻪ ﺧﺎﻃﺮ اﻳﻦ اﺳﺖ ﻛﻪ ﻗﺒـﻞ از ﻓﺮاﺧـﻮاﻧﻲ ﺗـﺎﺑﻊ ShowDialog ﺧﺎﺻـــــﻴﺘﻬﺎي AllowSelection ،AllowPrintToFileو AllowSomePagesرا ﺑﺮاﺑﺮ ﺑﺎ Falseﻗﺮار دادﻳﻢ .اﮔﺮ در ﺳﻴﺴﺘﻢ ﺧﻮد ﺑﻴﺶ از ﻳﻚ ﭼﺎﭘﮕﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 15-7ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﻌﻴـﻴﻦ ﻛﻨﻴﺪ ﻛﻪ ﻓﺎﻳﻞ ﺑﺎز ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ﻛﺪام ﭼﺎﭘﮕﺮ ،ﭼﺎپ ﺷﻮد. (10روي دﻛﻤﻪ Printدر ﻛﺎدر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺤﺘﻮﻳﺎت ﻓﺎﻳﻞ ﭼﺎپ ﺷﻮﻧﺪ.
ﺷﻜﻞ 15-7
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﻗﺴﻤﺘﻬﺎي اﻳﻦ ﺑﺮﻧﺎﻣﻪ ،ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ دﻛﻤﻪ ي btnPrintاﺳﺖ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴـﺪ اﻳﻦ ﻣﺘﺪ را ﺑﺎ ﺗﻌﺮﻳﻒ ﻳﻚ ﺷﻴﺊ از ﻛﻼس PrintDocumentآﻏﺎز ﻛﺮدﻳﻢ .ﻋﻤﻞ اﺻﻠﻲ ﭼﺎپ ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ ﺷﻴﺊ ﺻـﻮرت ﻣـﻲ ﮔﻴﺮد: ;)(PrintDocument objPrintDocument = new PrintDocument
٢٨٨
ﺳﭙﺲ ﺧﺎﺻﻴﺖ DocumentNameﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﺷﻴﺊ را ﺗﻨﻈﻴﻢ ﻛﺮدﻳﻢ .اﮔﺮ ﻫﻤﺰﻣﺎن ﭼﻨﺪ ﺑﺮﻧﺎﻣـﻪ ﺑﺨﻮاﻫﻨـﺪ از ﭼـﺎﭘﮕﺮ اﺳـﺘﻔﺎده ﻛﻨﻨﺪ ،ﺳﻨﺪﻫﺎي آﻧﻬﺎ در ﻳﻚ ﺻﻒ ﭼﺎپ ﻗﺮار ﻣﻲ ﮔﻴﺮد .ﻧﺎﻣﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ وارد ﻣﻲ ﻛﻨﻴﻢ ،ﺑﺮاي ﻣـﺸﺨﺺ ﻛـﺮدن ﺳـﻨﺪ ﻣﺮﺑـﻮط ﺑـﻪ ﺑﺮﻧﺎﻣﻪ ﻣﺎ در ﺻﻒ ﭼﺎپ ﺑﻪ ﻛﺎر ﻣﻲ رود. Print
File
"Text
=
objPrintDocument.DocumentName ;"Demo
در ﻗﺴﻤﺖ ﺑﻌﺪ ،ﺑﻪ ﺗﻨﻈﻴﻢ ﺑﻌﻀﻲ از ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل PrintDialogﻣﻲ ﭘﺮدازﻳﻢ .در اﻳﻦ ﺑﺨﺶ ﻓﻘﻂ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻳﻚ ﻋﻤـﻞ ﭼﺎپ ﺳﺎده را اﻧﺠﺎم دﻫﻴﻢ ،ﺑـﻪ ﻫﻤـﻴﻦ دﻟﻴـﻞ ﺑﻬﺘـﺮ اﺳـﺖ ﻗـﺴﻤﺘﻬﺎي Print to fileو ﻫﻤﭽﻨـﻴﻦ Selectionو Pagesرا در ﻛﺎدر Printﻏﻴﺮ ﻓﻌﺎل ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺎﻓﻲ اﺳﺖ ﺧﺎﺻﻴﺘﻬﺎي ﻣﺮﺑـﻮط ﺑـﻪ آﻧﻬـﺎ را ﺑﺮاﺑـﺮ ﺑـﺎ falseﻗـﺮار دﻫﻴﻢ: ;printDialog1.AllowPrintToFile = false ;printDialog1.AllowSelection = false ;printDialog1.AllowSomePages = false ﻗﺒﻞ از ﻧﻤﺎﻳﺶ ﻛﺎدر Printﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﺗﻨﻈﻴﻤﺎﺗﻲ ﻛﻪ ﻛﺎرﺑﺮ در اﻳﻦ ﻛﺎدر ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ،ﺑﺮاي ﭼﺎپ ﭼﻪ ﺳﻨﺪي ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ ﺧﺎﺻﻴﺖ Documentﻛﻨﺘﺮل PrintDialogرا ﺑﺮاﺑﺮ ﺑـﺎ ﺷـﻴﺊ PrintDocumentاي ﻗﺮار دﻫﻴﺪ ﻛﻪ ﻧﺸﺎن دﻫﻨﺪه ي ﺳﻨﺪ ﻣﻮرد ﻧﻈﺮ اﺳﺖ. ;printDialog1.Document = objPrintDocument ﺣﺎل ﻣﻲ ﺗﻮاﻧﻴﻢ ﻛﺎدر Printرا ﻧﻤﺎﻳﺶ دﻫﻴﻢ .ﻫﻤﺎﻧﻨﺪ ﻛﺎدرﻫﺎي ﻗﺒﻠﻲ ،ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺎﻓﻲ اﺳﺖ ﻣﺘﺪ ShowDialogﻣﺮﺑـﻮط ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ ﻧﻴﺰ ﻣﻘﺪاري را از ﻧﻮع DialogResultﺑﺮﻣﻲ ﮔﺮداﻧﺪ .اﮔﺮ ﻛﺎرﺑﺮ در ﻛـﺎدر روي دﻛﻤـﻪ ي Printﻛﻠﻴــﻚ ﻛﻨــﺪ ،ﺗــﺎﺑﻊ DialogResult.OKو اﮔــﺮ ﻛــﺎرﺑﺮ روي دﻛﻤــﻪ ي Cancelﻛﻠﻴــﻚ ﻛﻨــﺪ ،ﺗــﺎﺑﻊ DialogResult.Cancelرا ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .ﻫﻤﺎﻧﻨﺪ ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر ifﻧﺘﻴﺠﻪ را ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ. )if (printDialog1.ShowDialog() == DialogResult.OK اﮔﺮ ﻛﺎرﺑﺮ در ﻛﺎدر روي دﻛﻤﻪ Printﻛﻠﻴﻚ ﻛﻨﺪ ﺑﺎﻳﺪ ﻣﺤﺘﻮﻳﺎت ﻓﺎﻳﻠﻲ ﻛﻪ آدرس آن در ﻣﺘﻐﻴﺮ strFileNameﻗـﺮار دارد را ﭼﺎپ ﻛﻨﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ اﺑﺘﺪا ﻳﻚ ﺷﻴﺊ از ﻧﻮع StreamReaderﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ .اﻳﻦ ﺷﻴﺊ ﺑﺮاي دﺳﺘﺮﺳـﻲ ﺑـﻪ ﻣﺤﺘﻮﻳـﺎت ﻳـﻚ ﻓﺎﻳﻞ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد و ﻫﻨﮕﺎم ﺗﻌﺮﻳﻒ آن ﺑﺎﻳﺪ آدرس ﻓﺎﻳﻞ ﻣﻮرد ﻧﻈﺮ را ﺑﻪ آن ﺑﻔﺮﺳﺘﻴﻢ .ﭘﺲ ﻣﺘﻐﻴﻴﺮ strFileName ﻛﻪ ﺣﺎوي آدرس ﻓﺎﻳﻞ اﺳﺖ را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ اﻳﻦ ﺷﻴﺊ ارﺳﺎل ﻣﻲ ﻛﻨﻴﻢ. ;)objStreamToPrint = new StreamReader(strFileName ﺳﭙﺲ ﺑﺎﻳﺪ ﻓﻮﻧﺖ و اﻧﺪازه ﻣﺘﻦ را ﺑﺮاي ﭼﺎپ ﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﺑﻪ ﻫﻤﻴﻦ ﻋﻠﺖ ﺷﻴﺊ را ز ﻧﻮع Fontﺗﻌﺮﻳﻒ ﻛﺮده و ﻓﻮﻧـﺖ Arialو اﻧﺪازه 10را ﺑﺮاي آن ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ.
٢٨٩
;)objPrintFont = new Font("Arial", 10 ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ ﻧﻴﺰ ﮔﻔﺘﻢ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ روﻳﺪاد ﺑﻪ وﺳﻴﻠﻪ ﻳﻚ ﻛﻼس رخ ﻣﻲ دﻫﺪ ،ﺗﻌﺪادي از ﺗﻮاﺑﻊ ﺑﺮاي ﭘﺎﺳـﺦ دادن ﺑﻪ آن روﻳﺪاد اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ .ﺑﺮاي ﻣﺜﺎل در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﺑﺎ دو ﺑﺎر ﻛﻠﻴﻚ ﺑﺮ روي ﻳﻚ ﻛﻨﺘـﺮل Buttonدر زﻣـﺎن ﻃﺮاﺣﻲ ،ﻣﺘﺪي اﻳﺠﺎد ﻣﻲ ﺷﺪ و اﻳﻦ ﻣﺘﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي آن ﻛﻨﺘﺮل در ﻃﻲ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻛﻠﻴﻚ ﻣﻲ ﻛﺮد ،ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﺪ .ﺑﺮاي ﺑﺮرﺳﻲ دﻗﻴﻘﺘﺮ اﻳﻦ ﻣﻮرد ﺑﺎﻳﺪ ﺑﮕﻮﻳﻢ ﻛﻪ ﻫﺮ روﻳﺪاد ﺷﺎﻣﻞ ﻟﻴﺴﺘﻲ از ﺗﻮاﺑﻊ اﺳﺖ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ روﻳﺪاد رخ ﻣﻲ دﻫـﺪ ،ﻛـﻼس ﻣﺮﺑﻮﻃﻪ ﺗﻤﺎم ﺗﻮاﺑﻊ ﻣﻮﺟﻮد در ﻟﻴﺴﺖ ﻣﺮﺑﻮط ﺑﻪ آن روﻳﺪاد را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﭼﻨﺪﻳﻦ ﻣﺘﺪ ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ و آﻧﻬﺎ را ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ ﻳﻚ Buttonاﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮ روي آن دﻛﻤﻪ ﻛﻠﻴﻚ ﺷﻮد ﺗﻤﺎم ﻣﺘﺪﻫﺎﻳﻲ ﻛﻪ ﺑـﻪ آن اﺿـﺎﻓﻪ ﻛﺮده اﻳﺪ اﺟﺮا ﺧﻮاﻫﻨﺪ ﺷﺪ. در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ ﮔﻔﺘﻢ ﻛﻪ ﻛﻼس PrintDocumentﺑﺮاي اﻳﻨﻜﻪ ﺗﺸﺨﻴﺺ دﻫﺪ ﭼﻪ ﻣﺘﻨﻲ را ﺑﺎﻳﺪ ﭼﺎپ ﻛﻨﺪ ،در ﻫﺮ ﺻـﻔﺤﻪ روﻳﺪاد PrintPageرا ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ .ﺑﻪ ﻋﺒﺎرت دﻗﻴﻖ ﺗﺮ ﺑﺎﻳﺪ ﺑﮕﻮﻳﻴﻢ ﻛﻪ اﻳﻦ ﻛﻼس در ﻫﺮ ﻣﺮﺣﻠﻪ ﺗﻤﺎم ﺗﻮاﺑﻌﻲ ﻛﻪ در ﻟﻴﺴﺖ روﻳــﺪاد PrintPageﻫــﺴﺘﻨﺪ را اﺟــﺮا ﻣــﻲ ﻛﻨــﺪ .ﭘــﺲ ﺑﺎﻳــﺪ ﻣﺘــﺪي را اﻳﺠــﺎد ﻛﻨــﻴﻢ و آن را ﺑــﻪ ﻟﻴــﺴﺖ ﻣﺘــﺪﻫﺎي روﻳــﺪاد PrintPageاﺿﺎﻓﻪ ﻛﻨـﻴﻢ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﻣﺘـﺪ prtPageرا اﻳﺠـﺎد ﻛـﺮده و آن را ﺑـﻪ وﺳـﻴﻠﻪ دﺳـﺘﻮر زﻳـﺮ ﺑـﻪ روﻳـﺪاد PrintPageاﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ:1 =objPrintDocument.PrintPage + ;)new PrintPageEventHandler(prtPage ﺣﺎل ﺑﺎﻳﺪ ﭼﺎﭘﮕﺮ ﻣﻮرد اﺳﺘﻔﺎده ﺑﺮاي ﭼﺎپ و ﻫﻤﭽﻨﻴﻦ ﺗﻨﻈﻴﻢ ﻫﺎي آن را ،ﺑﺮاي ﺷﻴﺊ PrintDocumentﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﺑـﺮاي اﻳﻦ ﻛﺎر ﻛﺎﻓﻲ اﺳﺖ ﺗﻨﻈﻴﻤﻬﺎﻳﻲ ﻛﻪ ﻛﺎرﺑﺮ در ﻛﺎدر Printﻣـﺸﺨﺺ ﻛـﺮده اﺳـﺖ را ﺑـﻪ اﻳـﻦ ﺷـﻴﺊ ﺑﻔﺮﺳـﺘﻴﻢ .ﺗﻨﻈـﻴﻢ ﻫـﺎي ﻛـﺎدر Printدر ﺧﺎﺻــــﻴﺖ PrinterSettingsذﺧﻴــــﺮه ﻣــــﻲ ﺷــــﻮﻧﺪ .ﭘــــﺲ ﻛــــﺎﻓﻲ اﺳــــﺖ ﺧﺎﺻــــﻴﺖ objPrintDocument.PrinterSettingsرا ﺑﺮاﺑﺮ ﺑﺎ آن ﻗﺮار دﻫﻴﻢ. = objPrintDocument.PrinterSettings ;printDialog1.PrinterSettings ﺣﺎل ﺑﺎﻳﺪ ﻣﺘﺪ Printرا ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ روﻳﺪاد PrintPageرا اﺣﻀﺎر ﻣﻲ ﻛﻨﺪ و اﺣﻀﺎر اﻳﻦ روﻳﺪاد ﻧﻴﺰ ﺑﺎﻋـﺚ ﻣـﻲ ﺷﻮد ﻛﻪ ﻛﺪ درون ﻣﺘﺪ prtPageاﺟﺮا ﺷﻮد. ;)(objPrintDocument.Print ﻧﻜﺘﻪ دﻳﮕﺮي ﻛﻪ در اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻣﺘﺪ ﺑﻪ ﻳﻚ روﻳﺪاد ﺑﺎﻳﺪ در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻣﺘـﺪﻫﺎﻳﻲ ﻛـﻪ ﻣـﻲ ﺗﻮاﻧﻨـﺪ ﺑـﻪ روﻳـﺪاد PrintPageاﺿﺎﻓﻪ ﺷﻮﻧﺪ ﺑﺎﻳﺪ داراي ﺳﺎﺧﺘﺎر ﺧﺎﺻﻲ ﺑﺎﺷﻨﺪ .اﻳﻦ ﻣﺘﺪﻫﺎ ﻧﺒﺎﻳﺪ ﻣﻘﺪاري را ﺑﺮﮔﺮداﻧﻨﺪ )ﻣﻘﺪار ﺑﺮﮔـﺸﺘﻲ آﻧﻬـﺎ ﺑﺎﻳـﺪ ﺑـﻪ ﺻﻮرت voidﺗﻌﺮﻳﻒ ﺷﻮد( .ﻫﻤﭽﻨﻴﻦ ﺑﺎﻳﺪ دو ﭘﺎراﻣﺘﺮ را از ورودي درﻳﺎﻓﺖ ﻛﻨﻨﺪ :اوﻟﻴﻦ ﭘﺎراﻣﺘﺮ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﺷـﻴﺊ اﺳـﺖ ﻛـﻪ اﻳـﻦ روﻳﺪاد را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده اﺳﺖ .ﻧﺎم اﻳﻦ ﭘﺎراﻣﺘﺮ senderو ﻧﻮع آن از ﻧﻮع ﻛﻼس Objectﺧﻮاﻫﺪ ﺑﻮد .دوﻣﻴﻦ ﭘﺎراﻣﺘﺮ ﺑﺎﻳﺪ ﺷﻴﺊ از ﻧﻮع ﻛﻼس PrintPageEventArgsﺑﺎﺷﺪ .اﻳﻦ ﭘﺎراﻣﺘﺮ ﺣﺎوي اﻃﻼﻋﺎﺗﻲ در ﻣﻮرد ﺻﻔﺤﻪ اي ﻛﻪ ﺑﺎﻳﺪ ﭼﺎپ ﺷﻮد ﺧﻮاﻫﺪ ﺑﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﺘﺪ prtPageﻛﻪ ﺑﺎﻳﺪ ﺑﻪ وﺳﻴﻠﻪ روﻳﺪاد PrintPageﻓﺮاﺧﻮاﻧﻲ ﺷﻮد ﻣﺸﺎﺑﻪ زﻳﺮ ﺧﻮاﻫﺪ ﺑﻮد:
1در دو ﻓﺼﻞ ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا و ﻓﺼﻮل ﺑﻌﺪ از آن ،ﻣﺘﺪﻫﺎ را دﻗﻴﻖ ﺗﺮ ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد.
٢٩٠
)private void prtPage(object sender, PrintPageEventArgs e ﺣﺎل ﺑﻪ ﺑﺮرﺳﻲ ﻛﺪﻫﺎﻳﻲ ﻣﻲ ﭘﺮدازﻳﻢ ﻛﻪ در داﺧﻞ اﻳﻦ ﻣﺘﺪ ﺑﺎﻳﺪ اﺟﺮا ﺷﻮﻧﺪ .اﺑﺘﺪا ﺑﺎﻳﺪ ﺗﻌﺪادي ﻣﺘﻐﻴﻴﺮ ﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ و ﻣﻘﺎدﻳﺮ آﻧﻬﺎ را ﺗﻨﻈـﻴﻢ ﻛﻨﻴﻢ .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﻣﻘﺎدﻳﺮ ﻣﺘﻐﻴﺮﻫﺎي sngLeftMarginو sngTopMarginﺑﻪ وﺳﻴﻠﻪ ﻣﻘﺎدﻳﺮ ﻣﻮﺟـﻮد در ﭘـﺎراﻣﺘﺮ PrintPageEventArgsﻛﻪ ﺑﻪ ﻣﺘﺪ ارﺳﺎل ﻣﻲ ﺷﻮد ﺗﻨﻈﻴﻢ ﺧﻮاﻫﺪ ﺷﺪ. ;float sngLinesPerpage = 0 ;float sngVerticalPosition = 0 ;int intLineCount = 0 ;float sngLeftMargin = e.MarginBounds.Left ;float sngTopMargin = e.MarginBounds.Top ;string strLine ﺣﺎل ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ در ﻫﺮ ﺻﻔﺤﻪ ﭼﻨﺪ ﺧﻂ ﻣﻲ ﺗﻮاﻧﺪ ﭼﺎپ ﺷﻮد .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ ارﺗﻔﺎع ﻗﺎﺑﻞ ﭼـﺎپ در ﺻـﻔﺤﻪ را ﺑـﺮ ارﺗﻔـﺎع ﻓﻮﻧــﺖ )ارﺗﻔــﺎع ﻫــﺮ ﺧــﻂ( ﺗﻘــﺴﻴﻢ ﻛﻨــﻴﻢ .ﺑــﺮاي دﺳﺘﺮﺳــﻲ ﺑــﻪ ارﺗﻔــﺎع ﻗﺎﺑــﻞ ﭼــﺎپ در ﺻــﻔﺤﻪ ﻣــﻲ ﺗــﻮاﻧﻴﻢ از ﺧﺎﺻــﻴﺖ MarginBounds.Heightدر ﺷﻴﺊ eاز ﻛﻼس PrintPageEventArgsاﺳﺘﻔﺎده ﻛﻨﻴﻢ )اﻳﻦ ﺷﻴﺊ ،ﺑـﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ ﻣﺘﺪ ﻓﺮﺳﺘﺎده ﺷﺪه اﺳﺖ(. ارﺗﻔﺎع ﻗﺎﺑﻞ ﭼﺎپ در ﺻﻔﺤﻪ در ﻛﺎدر PrintDialogﺗﻨﻈﻴﻢ ﺷـﺪه و در ﺧﺎﺻـﻴﺖ PrinterSettingsﻗـﺮار ﻣـﻲ ﮔﻴﺮد .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ در ﻛﺪﻫﺎي ﻗﺒﻠﻲ اﻳـﻦ ﺧﺎﺻـﻴﺖ را در ﺧﺎﺻـﻴﺖ PrinterSettingsﻣﺮﺑـﻮط ﺑـﻪ ﺷـﻴﺊ objPrintDocumentﻗــﺮار دادﻳــﻢ .ﺷــﻴﺊ objPrintDoumentﻫــﻢ ﻫﻨﮕــﺎﻣﻲ ﻛــﻪ ﺑﺨﻮاﻫــﺪ روﻳــﺪاد PrintPageرا ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﺪ ،اﻳﻦ ﻣﻘﺪار را ﺑﻪ وﺳـﻴﻠﻪ ﺷـﻴﺊ از ﻛـﻼس PrintPageEventArgsﺑـﻪ ﻣﺘـﺪﻫﺎي ﻓﺮاﺧﻮاﻧﻲ ﺷﺪه ﻣﻲ ﻓﺮﺳﺘﺪ. sngLinesPerpage = e.MarginBounds.Height / ;)objPrintFont.GetHeight(e.Graphics ﭘﺲ ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﻐﻴﻴﺮ sngLinesPerPageﺣﺎوي ﺗﻌﺪاد ﺧﻄﻮﻃﻲ ﺧﻮاﻫﺪ ﺑﻮد ﻛﻪ در ﻫﺮ ﺻﻔﺤﻪ ﻗﺮار ﻣﻲ ﮔﻴﺮد .ﺣﺎل ﺑﺎﻳﺪ ﻣﺤﺘﻮﻳﺎت ﻓﺎﻳﻞ را ﺧﻂ ﺑﻪ ﺧﻂ ﺧﻮاﻧﺪه و در ﺻﻔﺤﻪ ﺑﺮاي ﭼﺎپ ﻗﺮار دﻫﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﺣﻠﻘﻪ ،ﻣﺘﻦ داﺧﻞ ﻓﺎﻳﻞ را ﺧـﻂ ﺑﻪ ﺧﻂ در ﺻﻔﺤﻪ وارد ﻣﻲ ﻛﻨﻴﻢ .اﺟﺮاي اﻳﻦ ﺣﻠﻘﻪ ﺗﺎ زﻣﺎﻧﻲ اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻳﺎ ﻣﺘﻦ داﺧﻞ ﻓﺎﻳﻞ ﺗﻤﺎم ﺷﻮد و ﺑﻪ اﻧﺘﻬﺎي ﻓﺎﻳﻞ ﺑﺮﺳﻴﻢ و ﻳﺎ ﺗﻌﺪاد ﺧﻄﻬﺎﻳﻲ ﻛﻪ در ﺻﻔﺤﻪ ﻗﺮار داده اﻳﻢ ﺑﺮاﺑﺮ ﺑﺎ ﺣﺪاﻛﺜﺮ ﺗﻌﺪاد ﺧﻄﻬﺎﻳﻲ ﺷﻮد ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ در ﻳﻚ ﺻﻔﺤﻪ وارد ﻛﻨﻴﻢ ،ﺑـﻪ ﻋﺒـﺎرت دﻳﮕﺮ ﺻﻔﺤﻪ ﭘﺮ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ اﺑﺘﺪا اوﻟﻴﻦ ﺧﻂ را ﺧﻮاﻧﺪه و در ﻣﺘﻐﻴﺮ strLineﻗﺮار ﻣﻲ دﻫﻴﻢ و ﺳﭙﺲ ﺣﻠﻘﻪ را اﺟﺮا ﻣﻲ ﻛﻨﻴﻢ: ;)(strLine = objStreamToPrint.ReadLine =! while((intLineCount < sngLinesPerpage) && (strLine ))null { ﻗﺒﻞ از اﻳﻨﻜﻪ ﻣﺘﻨﻲ را در ﺻﻔﺤﻪ ﻗﺮار دﻫﻴﻢ ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ ﻣﻮﻗﻌﻴﺖ ﻋﻤﻮدي ﻣﺘﻦ در ﺻﻔﺤﻪ ﭼﻘﺪر اﺳﺖ .ﺑـﻪ ﻋﺒـﺎرت دﻳﮕـﺮ ﺑﺎﻳـﺪ ﻓﺎﺻﻠﻪ ﻣﺘﻦ را از ﺑﺎﻻي ﺻﻔﺤﻪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﺑﺮاي ﺗﻌﻴﻴﻦ ﻓﺎﺻﻠﻪ ﻣﺘﻦ از ﺑﺎﻻي ﺻﻔﺤﻪ ﺑﺎﻳﺪ اﻧﺪازه ﻗـﺴﻤﺖ ﺳـﻔﻴﺪ ﺑـﺎﻻي ﺻـﻔﺤﻪ را ﺑـﺎ
٢٩١
ارﺗﻔﺎع ﺗﻌﺪاد ﺧﻄﻬﺎﻳﻲ ﻛﻪ ﺗﺎﻛﻨﻮن ﭼﺎپ ﺷﺪه اﻧﺪ ﺟﻤﻊ ﻛﻨﻴﻢ .ﺑﺮاي ﻣﺤﺎﺳﺒﻪ ارﺗﻔﺎع ﺗﻌﺪاد ﺧﻄﻬﺎﻳﻲ ﻛﻪ ﺗﺎﻛﻨﻮن ﭼﺎپ ﺷﺪه اﻧﺪ ﻧﻴﺰ ﺑﺎﻳﺪ ﺣﺎﺻﻞ ﺿﺮب ﺗﻌﺪاد ﺧﻄﻬﺎﻳﻲ ﻛﻪ در ﺻﻔﺤﻪ ﭼﺎپ ﺷﺪه اﻧﺪ در ارﺗﻔﺎع ﻫﺮ ﺧﻂ را ﺑﺪﺳﺖ آورﻳﻢ: sngVerticalPosition = sngTopMargin + ;))(intLineCount * objPrintFont.GetHeight(e.Graphics ﺑﺮاي اﻳﻨﻜﻪ واﻗﻌﺎً ﻣﺘﻦ را ﺑﻪ ﭼﺎﭘﮕﺮ ﺑﻔﺮﺳﺘﻴﻢ ﺑﺎﻳـﺪ از ﺗـﺎﺑﻊ DrawStringدر ﻛـﻼس Graphicsاﺳـﺘﻔﺎده ﻛﻨـﻴﻢ .ﻛـﻼس Graphicsﺑﻪ ﺻﻮرت ﻳﻜﻲ از ﺧﺎﺻﻴﺘﻬﺎي ﻛـﻼس PrintPageEventArgsﺑـﻪ اﻳـﻦ ﻣﺘـﺪ ﻓﺮﺳـﺘﺎده ﻣـﻲ ﺷـﻮد. ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ ﻛﻪ ﺗﺎﺑﻊ DrawStringدرﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ ﻋﺒﺎرﺗﻨﺪ از :ﻣﺘﻨﻲ ﻛﻪ ﺑﺎﻳﺪ ﭼﺎپ ﺷﻮد ،ﻓﻮﻧﺖ ﻣﺘﻨﻲ ﻛﻪ ﺑﺎﻳﺪ ﭼﺎپ ﺷﻮد ،رﻧـﮓ ﻣﺘﻨﻲ ﻛﻪ ﺑﺎﻳﺪ ﭼﺎپ ﺷﻮد )اﻳﻦ رﻧﮓ ﺑﺎﻳﺪ از ﺷﻤﺎرﻧﺪه ي Brushesاﻧﺘﺨﺎب ﺷﻮد( ،ﻓﺎﺻﻠﻪ ﻣﺘﻦ از ﺳﻤﺖ ﭼﭗ ﺻﻔﺤﻪ ،ﻓﺎﺻﻠﻪ ﻣـﺘﻦ از ﺑﺎﻻي ﺻﻔﺤﻪ ،و ﻗﺎﻟﺐ ﻣﺘﻦ ﺑﺮاي ﭼﺎپ.در اﻳﻦ ﻗـﺴﻤﺖ ﻗـﺎﻟﺒﻲ ﺑـﺮاي ﻣـﺘﻦ ﻣـﺸﺨﺺ ﻧﻤـﻲ ﻛﻨـﻴﻢ ﺑﻠﻜـﻪ ﻳـﻚ ﺷـﻴﺊ ﺟﺪﻳـﺪ از ﻛـﻼس StringFormatاﻳﺠﺎد ﻛﺮده و آن را ﺑﻪ ﺗﺎﺑﻊ ﻣﻲ ﻓﺮﺳﺘﻴﻢ. e.Graphics.DrawString(strLine, objPrintFont, Brushes.Black, sngLeftMargin, sngVerticalPosition, ;))(new StringFormat ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻳﻚ ﺧﻂ از ﻣﺘﻦ را ﭼﺎپ ﻛﺮده اﻳﻢ ،ﭘﺲ ﻳﻚ واﺣﺪ ﺑﻪ ﺗﻌﺪاد ﺧﻄﻬﺎ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ: ;intLineCount = intLineCount + 1 ﺣﺎل ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﺻﻔﺤﻪ ﭘﺮ ﺷـﺪه اﺳـﺖ ﻳـﺎ ﻧـﻪ .اﮔـﺮ ﺻـﻔﺤﻪ ﭘـﺮ ﻧـﺸﺪه ﺑـﻮد ﺧـﻂ دﻳﮕـﺮي را از ﻓﺎﻳـﻞ ﺧﻮاﻧـﺪه و در ﻣﺘﻐﻴﻴـﺮ strLineﻗﺮار ﻣﻴﺪﻫﻴﻢ ﺗﺎ ﺣﻠﻘﻪ ﺑﺎ ﺧﻂ ﺟﺪﻳﺪ اداﻣﻪ ﭘﻴﺪا ﻛﻨﺪ: )if (intLineCount < sngLinesPerpage { ;)(strLine = objStreamToPrint.ReadLine } ﺑﻌﺪ از اﻳﻨﻜﻪ ﻳﻚ ﺻﻔﺤﻪ ﻛﺎﻣﻼً ﭘﺮ ﺷﺪ ،ﺑﺮﻧﺎﻣﻪ از ﺣﻠﻘﻪ ﺧﺎرج ﻣﻲ ﺷﻮد .ﺣﺎل ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ ﺻﻔﺤﻪ دﻳﮕﺮي ﻫﻢ ﺑﺎﻳﺪ ﭼﺎپ ﺷـﻮد و ﻳﺎ اﻳﻨﻜﻪ ﻣﺘﻦ داﺧﻞ ﻓﺎﻳﻞ ﺗﻤﺎم ﺷﺪه اﺳﺖ .اﮔﺮ ﻣﺘﻦ داﺧﻞ ﻓﺎﻳﻞ ﺗﻤـﺎم ﺷـﺪه ﺑـﻮد ﺑﺎﻳـﺪ ﺧﺎﺻـﻴﺖ HasMorePagesرا ﺑﺮاﺑـﺮ ﺑـﺎ falseﻗﺮار دﻫﻴﻢ ﻛﻪ ﺗﺎﺑﻊ Printﺑﺎر دﻳﮕﺮ ﺑﺎﻋﺚ ﻓﺮاﺧﻮاﻧﻲ ﺷﺪن روﻳﺪاد PrintPageﻧﺸﻮد .اﻣﺎ اﮔﺮ ﻣـﺘﻦ ﺗﻤـﺎم ﻧـﺸﺪه ﺑﻮد ،ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﺑﺮاي ﭼﺎپ اداﻣﻪ ي ﻣﺘﻦ ،ﺧﺎﺻﻴﺖ HasMorePagesرا ﺑﺮاﺑﺮ ﺑﺎ trueﻗﺮار دﻫﻴﻢ .ﺑﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﺗـﺎﺑﻊ Printﺑﺎر دﻳﮕﺮ روﻳﺪاد PrintPageرا ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ ﺗﺎ ﻣﺘﺪ prtPageﺑﺘﻮاﻧﺪ ﺻﻔﺤﻪ ﺑﻌﺪ را ﭼﺎپ ﻛﻨﺪ. )if (strLine != null { ;e.HasMorePages = true } else
٢٩٢
{ ;e.HasMorePages = false } ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺗﻤﺎم ﻣﺘﻦ داﺧﻞ ﻓﺎﻳﻞ ﺑﻪ ﭼﺎﭘﮕﺮ ﻓﺮﺳﺘﺎده ﺷﺪ ،وﻇﻴﻔﻪ ﻣﺘﺪ Printﺗﻤﺎم ﺷﺪه اﺳﺖ و ﺑﺮﻧﺎﻣﻪ ﺑﻪ اداﻣـﻪ ﻛـﺪﻫﺎي ﻣﻮﺟـﻮد در ﻣﺘﺪ btnPrint_Clickﺑﺮﻣﻲ ﮔﺮدد .ﺗﻨﻬﺎ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ در اداﻣﻪ اﻧﺠﺎم دﻫﻴﻢ اﻳﻦ اﺳﺖ ﻛﻪ ﻓﻀﺎي اﺷـﻐﺎل ﺷـﺪه ﺑـﻪ وﺳـﻴﻠﻪ اﺷﻴﺎي ﻣﺮﺑﻮط ﺑﻪ ﭼﺎپ و ﻧﻴﺰ اﺷﻴﺎي ﻣﺮﺑﻮط ﺑﻪ ﺧﻮاﻧﺪن از ﻓﺎﻳﻞ را آزاد ﻛﻨﻴﻢ. ;)(objStreamToPrint.Close ;objStreamToPrint = null
ﻛﻨﺘﺮل :FolderBrowserDialog ﺑﻌﻀﻲ از ﻣﻮاﻗﻊ ﻣﻤﻜﻦ اﺳﺖ در ﺑﺮﻧﺎﻣﻪ ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﻴﺪ ﻛﻪ ﺑﻪ ﺟﺎي اﻧﺘﺨﺎب ﻳﻚ ﻓﺎﻳﻞ ،ﻳﻚ ﻓﻮﻟﺪر را ﻣﺸﺨﺺ ﻛﻨـﺪ. ﺑﺮاي ﻣﺜﺎل ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ ﻛﺎرﺑﺮ ﻓﻮﻟﺪري را ﺑﺮاي ذﺧﻴﺮه ﻓﺎﻳﻠﻬﺎي ﭘﺸﺘﻴﺒﺎن 1و ﻳﺎ ﻓﻮﻟﺪري را ﺑﺮاي ذﺧﻴـﺮه ﻓﺎﻳﻠﻬـﺎي ﻣـﻮﻗﺘﻲ ﺑﺮﻧﺎﻣـﻪ ﻣﺸﺨﺺ ﻛﻨﺪ.در اﻳﻦ ﻣﻮاﻗﻊ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل ،FolderBrowserDialogﻛـﺎدر اﺳـﺘﺎﻧﺪارد Browse For Folderرا در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ دﻫﻴﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ در دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي ﻧﻴﺰ ﻣﺸﺎﻫﺪه ﻛﺮده ﺑﺎﺷﻴﺪ ،اﻳﻦ ﻛﺎدر ﻓﻘﻂ ﻓﻮﻟﺪرﻫﺎي ﻣﻮﺟﻮد در ﻛﺎﻣﭙﻴﻮﺗﺮ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ و ﺑﻪ واﺳﻄﻪ آن ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﻓﻮﻟﺪري را در ﺑﺮﻧﺎﻣﻪ ﻣﺸﺨﺺ ﻛﻨﺪ. ﻫﻤﺎﻧﻨﺪ ﺗﻤﺎم ﻛﺎدرﻫﺎي دﻳﮕﺮ ،ﻛﺎدر FolderBrowserﻧﻴﺰ ﻫﻢ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺻﻮرت ﻛﻨﺘﺮل ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴـﺮد و ﻫـﻢ ﺑـﻪ ﺻﻮرت ﻳﻚ ﻛﻼس .ﺷﻜﻞ 16-7ﻳﻚ ﻛﺎدر FolderBrowserرا ﺑﺪون ﺗﻨﻈﻴﻢ ﺧﺎﺻﻴﺘﻬﺎي آن )ﺑﺎ ﻣﻘﺎدﻳﺮ ﭘﻴﺶ ﻓﺮض ﺧﺎﺻﻴﺖ ﻫﺎ( ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در ﻗﺴﻤﺖ ﭘﺎﻳﻴﻦ اﻳﻦ ﻓﺮم ﻳﻚ دﻛﻤﻪ ﻓﺮﻣﺎن Make New Folderوﺟـﻮد دارد ﻛـﻪ ﺑـﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻣﻲ دﻫﺪ ﻓﻮﻟﺪر ﺟﺪﻳﺪي را اﻳﺠﺎد ﻛﻨﺪ.
Backup Files
1
٢٩٣
ﺷﻜﻞ 16-7
ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل :FolderBrowser ﻗﺒﻞ از اﻳﻨﻜﻪ ﻧﺤﻮه اﺳﺘﻔﺎده از اﻳﻦ ﻛﻨﺘﺮل را در ﻛﺪ ﻣﺸﺎﻫﺪه ﻛﻨﻴﻢ ﺑﻬﺘﺮ اﺳﺖ ﺑﻪ ﺑﺮرﺳـﻲ ﺧﺎﺻـﻴﺘﻬﺎي ﻣﻬـﻢ آن ﺑﭙـﺮدازﻳﻢ .در ﺟـﺪول زﻳـﺮ ﻟﻴﺴﺘﻲ از ﻧﺎم و ﻧﺤﻮه اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺘﻬﺎي ﻣﻬﻢ اﻳﻦ ﻛﻨﺘﺮل آورده ﺷﺪه اﺳﺖ. ﻧﺎم ﺧﺎﺻﻴﺖ
ﺷﺮح
Description
ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻣﺘﻨﻲ اﺳﺖ ﻛﻪ ﺑﻪ ﻋﻨﻮان ﺗﻮﺿﻴﺢ در ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
RootFolder
ﻣﺸﺨﺺ ﻛﻨﻨﺪه آدرس ﻓﻮﻟﺪري اﺳﺖ ﻛﻪ ﺑﻪ ﺻﻮرت ﭘـﻴﺶ ﻓـﺮض ﺑﺎﻳـﺪ در ﻛـﺎدر ﻧﻤﺎﻳﺶ داده ﺷﻮد.
SelectedPath
ﻣﺸﺨﺺ ﻛﻨﻨﺪه آدرس ﻣﺴﻴﺮي اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻛﺎرﺑﺮ اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ.
ShowNewFolderButton
ﻣـﺸﺨﺺ ﻣـﻲ ﻛﻨـﺪ آﻳـﺎ دﻛﻤـﻪ ي Make New Folderدر ﻛـﺎدر ﻧﻤﺎﻳﺶ داده ﺷﻮد ﻳﺎ ﻧﻪ؟
ﻛﺎدر ﻣﺤﺎوره اي FolderBrowserاوﻟﻴﻦ ﻛﺎدري اﺳﺖ ﻛﻪ ﺗﻘﺮﻳﺒﺎً از ﺗﻤﺎم ﺧﺎﺻﻴﺘﻬﺎي آن اﺳﺘﻔﺎده ﺧﻮاﻫﻴﺪ ﻛﺮد. ﻫﻤﺎﻧﻨﺪ ﺗﻤﺎم ﻛﺎدرﻫﺎي دﻳﮕﺮ ،اﻳﻦ ﻛﻨﺘﺮل ﻧﻴﺰ داراي ﻣﺘﺪي ﺑﻪ ﻧﺎم ShowDialogاﺳﺖ ﻛﻪ ﺑﺎﻋﺚ ﻧﻤﺎﻳﺶ داده ﺷﺪن ﻛﺎدر در ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺷﻮد .ﻧﺤﻮه اﺳﺘﻔﺎده از اﻳﻦ ﻣﺘﺪ در اﻳﻦ ﻛﻨﺘﺮل ﻫﻤﺎﻧﻨﺪ ﻛﺎدرﻫﺎي دﻳﮕﺮ اﺳﺖ ،ﺑﻨﺎﺑﺮاﻳﻦ ﻧﻴﺎزي ﺑﻪ ﺗﻮﺿﻴﺢ ﻣﺠﺪد آن ﻧﻴﺴﺖ.
٢٩٤
اﺳﺘﻔﺎده از ﻛﻨﺘﺮل :FolderBrowser ﻫﻤﺎﻧﻨﺪ ﺗﻤﺎم ﻛﺎدرﻫﺎي ﻣﺤﺎوره اي دﻳﮕﺮ ،ﻗﺒﻞ از ﻧﻤﺎﻳﺶ ﻛـﺎدر Browse For Folderﺑﺎﻳـﺪ ﺑﻌـﻀﻲ از ﺧﺎﺻـﻴﺘﻬﺎي آن را ﺗﻐﻴﻴﺮ دﻫﻴﻢ .ﺳﻪ ﺧﺎﺻﻴﺘﻲ ﻛﻪ ﻋﻤﻮﻣﺎً ﻗﺒﻞ از ﻧﻤﺎﻳﺶ اﻳﻦ ﻛﺎدر ﺗﻨﻈﻴﻢ ﻣﻲ ﺷﻮﻧﺪ در ﻗﻄﻌﻪ ﻛﺪ زﻳـﺮ ﻧـﺸﺎن داده ﺷـﺪه اﻧـﺪ .اوﻟـﻴﻦ ﺧﺎﺻـﻴﺖ Descriptionاﺳﺖ ﻛﻪ ﻳﻚ ﺗﻮﺿﻴﺢ و ﻳﺎ دﺳﺘﻮراﻟﻌﻤﻞ را ﺑﺮاي ﻛﺎرﺑﺮ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .ﻣﺘﻨﻲ ﻛـﻪ در اﻳـﻦ ﺧﺎﺻـﻴﺖ ﻗﺮار داده ﺷﻮد ،ﻫﻨﮕﺎم ﻓﺮاﺧﻮاﻧﻲ ﺗﺎﺑﻊ ShowDialogدر ﺑﺎﻻي ﻛﺎدر ﻧﻮﺷﺘﻪ ﺧﻮاﻫﺪ ﺷﺪ. ﺧﺎﺻﻴﺖ ﺑﻌﺪي ﺧﺎﺻﻴﺖ RootFolderاﺳﺖ .اﻳﻦ ﺧﺎﺻﻴﺖ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻫﻨﮕﺎم ﻧﻤﺎﻳﺶ ﻛﺎدر ،ﭼﻪ ﻓﻮﻟـﺪري ﺑـﻪ ﺻـﻮرت ﭘﻴﺶ ﻓﺮض ﻧﻤﺎﻳﺶ داده ﺷﻮد .اﻳﻦ ﺧﺎﺻﻴﺖ ﻣﻘﺪاري را از ﺷﻤﺎرﻧﺪه Environment.SpecialFolderدرﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ و اﻳﻦ ﺷﻤﺎرﻧﺪه ﻧﻴﺰ ﺧﻮد ﺣﺎوي آدرس ﻓﻮﻟﺪرﻫﺎي ﻣﺨﺼﻮص ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ وﻳﻨﺪوز ﻣﺎﻧﻨﺪ ﻓﻮﻟﺪر My Documentsاﺳﺖ. ﺧﺎﺻﻴﺖ دﻳﮕﺮي ﻛﻪ ﻗﺒﻞ از ﻧﻤﺎﻳﺶ ﻛﺎدر ﺗﻨﻈﻴﻢ ﻣﻲ ﺷﻮد ،ﺧﺎﺻـﻴﺖ ShowNewFolderButtonاﺳـﺖ .اﮔـﺮ ﻣﻘـﺪار اﻳـﻦ ﺧﺎﺻﻴﺖ ﺑﺮاﺑﺮ ﺑﺎ trueﺑﺎﺷﺪ ،دﻛﻤﻪ ي Make New Folderدر ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﺗﺎ ﺑﻪ ﻛﺎرﺑﺮ اﺟـﺎزه داده ﺷـﻮد ﻓﻮﻟﺪر ﺟﺪﻳﺪي را اﻳﺠﺎد ﻛﻨﺪ .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت اﻳﻦ دﻛﻤﻪ ﻧﻤﺎﻳﺶ داده ﻧﺨﻮاﻫﺪ ﺷﺪ. = folderBrowserDialog1.Description ;""Select a folder for your backups: = folderBrowserDialog1.RootFolder ;Environment.SpecialFolder.MyComputer ;folderBrowserDialog1.ShowNewFolderButton = false ﺑﻌﺪ از ﺗﻨﻈﻴﻢ ﺧﺎﺻﻴﺘﻬﺎي ﻻزم ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﺗﺎﺑﻊ ShowDialogﻛﺎدر Browse For Folderرا ﻧﻤﺎﻳﺶ دﻫﻴﺪ: ;)(folderBrowserDialog1.ShowDialog اﻳﻦ ﺗﺎﺑﻊ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻛﺎدرﻫﺎي ﻗﺒﻠﻲ ﻣﻘﺪاري را از ﻧﻮع DialogResultﺑﺮﻣﻲ ﮔﺮداﻧﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳـﺘﻔﺎده از ﻳـﻚ دﺳـﺘﻮر ifﺑﻪ ﺑﺮرﺳﻲ ﻧﺘﻴﺠﻪ آن ﺑﭙﺮدازﻳﺪ .ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ آدرس ﻓﻮﻟﺪري ﻛـﻪ ﻛـﺎرﺑﺮ اﻧﺘﺨـﺎب ﻛـﺮده اﺳـﺖ ﻣـﻲ ﺗﻮاﻧﻴـﺪ از ﻣﻘـﺪار ﺧﺎﺻـﻴﺖ SelectedPathاﺳﺘﻔﺎده ﻛﺮده و آن را در ﻣﺘﻐﻴﺮي ذﺧﻴﺮه ﻛﻨﻴﺪ .اﻳﻦ ﺧﺎﺻﻴﺖ آدرس ﻛﺎﻣﻞ ﻓﻮﻟﺪر اﻧﺘﺨﺎب ﺷﺪه ﺗﻮﺳﻂ ﻛـﺎرﺑﺮ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻛﺎرﺑﺮ ﻓﻮﻟﺪر tempرا درون دراﻳﻮ Cاﻧﺘﺨﺎب ﻛﻨﺪ ،ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﻪ ﺻﻮرت C:\tempﺧﻮاﻫـﺪ ﺑﻮد. ;strFileName = folderBrowserDialog1.SelectedPath در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻣﺠﺪداً از ﭘﺮوژه Dialogsاﺳﺘﻔﺎده ﻛﺮده و ﻛﺎدر Browse For Folderرا ﻧﻤﺎﻳﺶ ﻣﻲ دﻫـﻴﻢ. اﮔﺮ ﻛﺎرﺑﺮ ﻓﻮﻟﺪري را در اﻳﻦ ﻛﺎدر اﻧﺘﺨﺎب ﻛﺮد ،آدرس آن را در TextBoxدرون ﻓﺮم ﻧﻤﺎﻳﺶ ﺧﻮاﻫﻴﻢ داد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻛﺎر ﺑﺎ ﻛﻨﺘﺮل FolderBrowser (1ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم در ﭘﺮوژه Dialogsﺑﺮوﻳﺪ.
٢٩٥
(2ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻛﻨﺘﺮل Buttonدﻳﮕﺮي را ﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮده و ﺧﺎﺻﻴﺘﻬﺎي آن را ﺑﺮ ﻃﺒـﻖ ﻟﻴـﺴﺖ زﻳـﺮ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ btnBrowseﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textرا ﺑﺮاﺑﺮ ﺑﺎ Browseﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Locationرا ﺑﺮاﺑﺮ ﺑﺎ 367;158ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Anchorرا ﺑﺮاﺑﺮ ﺑﺎ Top,Rightﻗﺮار دﻫﻴﺪ.
(3ﺣﺎل ﺑﺎﻳﺪ ﻳﻚ ﻛﻨﺘﺮل FolderBrowserDialogرا ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛـﺎر در ﺟﻌﺒـﻪ اﺑـﺰار ﺑـﻪ ﻗﺴﻤﺖ Dialogsﺑﺮوﻳﺪ و ﺑﺮ روي ﻛﻨﺘﺮل FolderBrowserDialogدو ﺑـﺎر ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ اﻳﻦ ﻛﻨﺘﺮل ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻛﻨﺘﺮﻟﻬﺎي ﻗﺒﻠﻲ ﺑﻪ ﻗﺴﻤﺖ ﭘﺎﻳﻴﻦ ﺑﺨﺶ ﻃﺮاﺣﻲ ﻓﺮم اﺿﺎﻓﻪ ﺧﻮاﻫﺪ ﺷﺪ. (4ﺑﺮ روي دﻛﻤﻪ ي btnBrowseدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳـﺮ را در آن ﻣﺘﺪ وارد ﻛﻨﻴﺪ: )private void btnBrowse_Click(object sender, EventArgs e { // Set the FolderBrowserDialog control properties = folderBrowserDialog1.Description ;""Select a folder for your backups: = folderBrowserDialog1.RootFolder ;Environment.SpecialFolder.MyComputer ;folderBrowserDialog1.ShowNewFolderButton = false // Show the Browse For Folder dialog == )(if (folderBrowserDialog1.ShowDialog )DialogResult.OK { // Display the selected folder ;txtFile.Text = folderBrowserDialog1.SelectedPath } } (5ﺗﻤﺎم ﻛﺪ ﻣﻮرد ﻧﻴﺎز ﺑﺮاي اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﻤﻴﻦ ﺑﻮد .ﺑﺮاي اﻣﺘﺤﺎن ﻋﻤﻠﻜﺮد ﺑﺮﻧﺎﻣـﻪ ،در ﻧـﻮار اﺑـﺰار روي دﻛﻤـﻪ Startﻛﻠﻴـﻚ ﻛﻨﻴﺪ. (6ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻓـﺮم ﺑﺮﻧﺎﻣـﻪ ﻧﻤـﺎﻳﺶ داده ﺷـﺪ ،روي دﻛﻤـﻪ ي Browseﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .ﻛـﺎدر Browse For Folderﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 17-7ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
٢٩٦
ﺷﻜﻞ 17-7 (7ﻓﻮﻟﺪري را در ﻛﺎﻣﭙﻴﻮﺗﺮ ﺧﻮد ﻣﺸﺨﺺ ﻛﺮده و روي دﻛﻤﻪ ﻓﺮﻣﺎن OKﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛـﺮد ﻛـﻪ آدرس ﻛﺎﻣـﻞ ﻓﻮﻟﺪر ﻣﺸﺨﺺ ﺷﺪه ،ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 18-7در ﻓﺮم ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
ﺷﻜﻞ 18-7
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻗﺒﻞ از اﻳﻨﻜﻪ ﻛﺎدر Browse For Folderرا ﻧﻤﺎﻳﺶ دﻫﻴﺪ ،ﺑﺎﻳﺪ ﺑﻌﻀﻲ از ﺧﺎﺻﻴﺘﻬﺎي آن را ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ﺗـﺎ ﻇـﺎﻫﺮ آن ﺑـﺎ ﺑﺮﻧﺎﻣﻪ ﻫﻤﺎﻫﻨﮓ ﺷﻮد .اوﻟﻴﻦ ﺧﺎﺻﻴﺖ ،ﺧﺎﺻﻴﺖ Descriptionاﺳﺖ ﻛﻪ ﺑﺮاي راﻫﻨﻤﺎﻳﻲ ﻛﺎرﺑﺮ در ﻣﻮرد اﻳﻦ ﻛﺎدر ﺑـﻪ ﻛـﺎر ﻣـﻲ ٢٩٧
رود .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣـﻲ ﻛﻨﻴـﺪ ﻣﻘـﺪار اﻳـﻦ ﻣﺘﻐﻴﻴـﺮ در اﺑﺘـﺪاي اﻳـﻦ ﻛـﺎدر ﻧﻤـﺎﻳﺶ داده ﻣـﻲ ﺷـﻮد .ﺧﺎﺻـﻴﺖ ﺑﻌـﺪي ،ﺧﺎﺻـﻴﺖ RootFolderاﺳﺖ ﻛﻪ ﻓﻮﻟﺪر ﭘﻴﺶ ﻓﺮض را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ My Computerرا ﺑﻪ ﻋﻨﻮان ﻓﻮﻟﺪر ﭘﻴﺶ ﻓﺮض در ﻧﻈﺮ ﮔﺮﻓﺘﻪ اﻳﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،ﻫﻨﮕﺎم ﻧﻤﺎﻳﺶ ﻛﺎدر دراﻳﻮﻫـﺎي ﻣﻮﺟـﻮد در My Computerﺑـﻪ ﻃـﻮر ﭘﻴﺶ ﻓﺮض ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ .در اﻧﺘﻬﺎ ﻧﻴﺰ ﺧﺎﺻـﻴﺖ ShowNewFolderButtonرا ﺑﺮاﺑـﺮ ﺑـﺎ falseﻗـﺮار ﻣـﻲ دﻫﻴﻢ ﺗﺎ اﻳﻦ دﻛﻤﻪ در ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﻧﺸﻮد. // Set the FolderBrowserDialog control properties = folderBrowserDialog1.Description ;""Select a folder for your backups: = folderBrowserDialog1.RootFolder ;Environment.SpecialFolder.MyComputer ;folderBrowserDialog1.ShowNewFolderButton = false ﺳﭙﺲ ﻛﺎدر اي را ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ShowDialogﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ و ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از دﺳـﺘﻮر ifﺑﺮرﺳـﻲ ﻣـﻲ ﻛﻨـﻴﻢ ﻛـﻪ ﻛﺎرﺑﺮ روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﺮده اﺳﺖ و ﻳﺎ روي دﻛﻤﻪ :Cancel // Show the Browse For Folder dialog == )(if (folderBrowserDialog1.ShowDialog )DialogResult.OK { اﮔﺮ ﻛﺎرﺑﺮ روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﺮده ﺑﻮد ،آدرس ﻓﻮﻟﺪر اﻧﺘﺨﺎب ﺷﺪه ﺗﻮﺳﻂ ﻛﺎرﺑﺮ را ﻛﻪ در ﺧﺎﺻـﻴﺖ SelectedPathﻗـﺮار ﮔﺮﻓﺘﻪ اﺳﺖ در ﻓﺮم ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ. // Display the selected folder ;txtFile.Text = folderBrowserDialog1.SelectedPath
ﻧﺘﻴﺠﻪ: در اﻳﻦ ﻓﺼﻞ ﺑﻌﻀﻲ از ﻛﺎدرﻫﺎ را ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﮋوال 2005 C#ﻗﺎﺑﻞ اﺳﺘﻔﺎده اﺳﺖ را ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ .اﻳـﻦ ﻛﺎدرﻫـﺎ ﻋﺒـﺎرت اﻧـﺪ ،FontDialog ،SaveFileDialog ،OpenFileDialog از،MessageBox: PrintDialog ،ColorDialogو .FolderBrowserDialogﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣـﺸﺎﻫﺪه ﻛﺮدﻳـﺪ ،اﻳـﻦ ﻛﺎدرﻫﺎ راﺑﻄﻬﺎي ﻛﺎرﺑﺮي اﺳﺘﺎﻧﺪارد را ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻓﺮاﻫﻢ ﻣﻲ ﻛﻨﻨﺪ و ﺑﻪ واﺳﻄﻪ آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮﻧﺎﻣﻪ اي ﺑﺎ ﻇﺎﻫﺮ ﺣﺮﻓﻪ اي ﺗـﺮ و ﻣـﺸﺎﺑﻪ دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي ﻃﺮاﺣﻲ ﻛﻨﻴﺪ. اﮔﺮﭼﻪ ﺑﺮاي اﺳﺘﻔﺎده از اﻳﻦ ﻛﺎدرﻫﺎ از ﻛﻨﺘﺮﻟﻬﺎي ﻣﺘﻨﺎﻇﺮ آﻧﻬﺎ در ﺟﻌﺒﻪ اﺑﺰار اﺳﺘﻔﺎده ﻛﺮدﻳﺪ ،اﻣﺎ ﺑﻪ ﺧﺎﻃﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﺗﻤﺎم اﻳﻦ ﻛﺎدرﻫـﺎ ﻣﻲ ﺗﻮاﻧﻨﺪ ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﻛﻼس ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮﻧﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻛﻼس ﻣﺘﻨﺎﻇﺮ ﺑﺎ اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﻧﻴﺰ ﻫﻤﻴﻦ ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘـﺪﻫﺎ را اراﺋﻪ ﻣﻲ دﻫﻨﺪ و ﺗﻔﺎوﺗﻲ ﻧﺪارد ﻛﻪ در ﺑﺮﻧﺎﻣﻪ از آﻧﻬﺎ ﺑﻪ ﻋﻨﻮان ﻛﻼس اﺳﺘﻔﺎده ﻛﻨﻴﺪ و ﻳﺎ ﺑﻪ ﻋﻨﻮان ﻛﻨﺘﺮل .ﺑﺮاي اﺳﺘﻔﺎده از اﻳﻦ ﻛﺎدرﻫﺎ ﺑﻪ ﺻﻮرت ﻛﻨﺘﺮل ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﺘﻐﻴﺮي را از ﻧﻮع ﻛﻼس ﻣﺮﺗﺒﻂ ﺑﺎ ﻛﺎدر ﻣﻮرد ﻧﻈﺮﺗﺎن ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ و در ﻫﺮ ﻗﺴﻤﺘﻲ از ﺑﺮﻧﺎﻣﻪ ﻛﻪ ﺧﻮاﺳﺘﻴﺪ از آن
٢٩٨
ﻛﺎدر اﺳﺘﻔﺎده ﻛﻨﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر newﻛﺎدر را اﻳﺠﺎد ﻛﻨﻴﺪ .ﺑﻌﺪ از اﺳﺘﻔﺎده ﻫﻢ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﺘﻐﻴﻴﺮ را از ﺑﻴﻦ ﺑﺒﺮﻳﺪ ﺗـﺎ ﺣﺎﻓﻈـﻪ ﮔﺮﻓﺘـﻪ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ آن آزاد ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺣﺎﻓﻈﻪ ﻛﻤﺘﺮي در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﺧﻮاﻫﻴﺪ ﻛﺮد و ﺑﺮﻧﺎﻣﻪ ﻛﺎراﻳﻲ ﺑﻴﺸﺘﺮي ﺧﻮاﻫﺪ داﺷﺖ. در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ:
ﺑﺎ اﺳﺘﻔﺎده از ﻛﻼس MessageBoxﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ دﻫﻴﺪ. در ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم از آﻳﻜﻮن و دﻛﻤﻪ ﻫﺎي ﻣﻮرد ﻧﻈﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. از ﻛﻨﺘﺮل OpenFileDialogاﺳﺘﻔﺎده ﻛﻨﻴﺪ و ﻣﺤﺘﻮﻳﺎت ﻳﻚ ﻓﺎﻳﻞ را ﺑﺨﻮاﻧﻴﺪ. از ﻛﻨﺘﺮل SaveFileDialogاﺳﺘﻔﺎده ﻛﺮده و اﻃﻼﻋﺎﺗﻲ را در ﻳﻚ ﻓﺎﻳﻞ ﺑﻨﻮﻳﺴﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل FontDialogرﻧﮓ و ﻓﻮﻧﺖ ﻳﻚ ﻣﺘﻦ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل ColorDialogرﻧﮓ ﭘﻴﺶ زﻣﻴﻨﻪ ﻳﻚ ﻛﻨﺘﺮل ،ﻣﺎﻧﻨﺪ ﻓﺮم را ﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل PrintDialogﻣﺘﻨﻲ را ﭼﺎپ ﻛﻨﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل FolderBrowserDialogﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﻴﺪ ﻓﻮﻟﺪري را در ﺑﺮﻧﺎﻣﻪ اﻧﺘﺨﺎب ﻛﻨﺪ.
ﺗﻤﺮﻳﻦ:
ﺗﻤﺮﻳﻦ :1 ﺑﺮﻧﺎﻣﻪ وﻳﻨﺪوزي ﺳﺎده اي اﻳﺠﺎد ﻛﺮده و در ﻓﺮم آن ﻳﻚ TextBoxو دو Buttonﻗﺮار دﻫﻴﺪ .ﻛﻨﺘﺮل ﻫﺎي Buttonرا ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ﻛﻪ ﻓﺎﻳﻠﻲ را ﺑﺎز ﻛﺮده ،ﻧﻤﺎﻳﺶ دﻫﻨﺪ و آن را ذﺧﻴﺮه ﻛﻨﻨـﺪ .ﺑـﺮاي ﺑـﺎز ﻛـﺮدن و ذﺧﻴـﺮه ﻛـﺮدن ﻓﺎﻳـﻞ از ﻛﻼﺳـﻬﺎي OpenFileDialogو SaveFileDialogاﺳﺘﻔﺎده ﻛﻨﻴﺪ )ﻧﻪ از ﻛﻨﺘﺮﻟﻬﺎي آﻧﻬﺎ(. راﻫﻨﻤﺎﻳﻲ :ﺑﺮاي ﺗﻌﺮﻳﻒ ﻛﻼﺳﻬﺎي ﻣﺘﻨﺎﻇﺮ ﺑﺎ ﻛﻨﺘﺮﻟﻬﺎي OpenFileDialogو SaveFileDialogﻣﻲ ﺗﻮاﻧﻴﺪ از دﺳﺘﻮرات زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ: ;)(OpenFileDialog openFileDialog1 = new OpenFileDialog ;)(SaveFileDialog saveFileDialog1 = new SaveFileDialog
ﺗﻤﺮﻳﻦ :2 ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺳﺎده ي وﻳﻨـﺪوزي اﻳﺠـﺎد ﻛﻨﻴـﺪ ﻛـﻪ ﺷـﺎﻣﻞ ﻳـﻚ ﻛﻨﺘـﺮل Labelو ﻳـﻚ ﻛﻨﺘـﺮل Buttonﺑﺎﺷـﺪ .در ﻛﻨﺘـﺮل Buttonﻛﺪي را وارد ﻛﻨﻴﺪ ﻛﻪ ﻳﻚ ﻛﺎدر Browser For Folderرا ﻧﻤﺎﻳﺶ دﻫﺪ .ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﻛﺎدر دﻛﻤﻪ ي Make New Folderرا ﻧﻴﺰ ﻓﻌﺎل ﻛﻨﻴﺪ .ﻓﻮﻟﺪر My Documentsرا در اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﻋﻨﻮان ﻓﻮﻟﺪر ﭘﻴﺶ ﻓﺮض ﻗﺮار
٢٩٩
Browserاز ﻛـــﻼس For داده و ﺳـــﭙﺲ ﻛـــﺎدر را ﻧﻤـــﺎﻳﺶ دﻫﻴـــﺪ .ﺑـــﺮاي اﺳـــﺘﻔﺎده از ﻛـــﺎدر Folder FolderBrowserDialogاﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻧﺘﻬﺎ ﻧﻴﺰ آدرس اﻧﺘﺨﺎب ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي ﻛـﺎرﺑﺮ را در ﻛﻨﺘـﺮل Label ﻗﺮار دﻫﻴﺪ.
٣٠٠
ﻓﺼﻞ ﻫﺸﺘﻢ :ﻣﻨﻮ ﻫﺎ ﻣﻨﻮ ﻫﺎ ﺟﺰ ﺗﻔﻜﻴﻚ ﻧﺎﭘﺬﻳﺮ ﻫﺮ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮب ﻣﺤﺴﻮب ﻣﻲ ﺷﻮﻧﺪ و راﻫﻲ راﺣﺖ و ﭘﺮ ﻛﺎرﺑﺮد ﺑﺮاي دﺳﺘﺮﺳﻲ ﻛـﺎرﺑﺮ ﺑـﻪ ﺗﻤـﺎم ﻗـﺴﻤﺘﻬﺎي ﺑﺮﻧﺎﻣﻪ را ﻓﺮاﻫﻢ ﻣﻲ ﻛﻨﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﺑﺮﻧﺎﻣﻪ ي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺎ اﺳﺘﻔﺎده از ﻣﻨﻮ ﻫﺎ ،ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ اﻳـﻦ اﻣﻜـﺎن را ﻣـﻲ دﻫـﺪ ﻛـﻪ ﺑـﻪ راﺣﺘﻲ ﺑﻪ اﺑﺰارﻫﺎي اﻳﻦ ﻣﺤﻴﻂ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ و ﺑﺘﻮاﻧﺪ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﺪ .ﻫﻤﭽﻨﻴﻦ در ﻣﺤﻴﻂ ﻛﺪ ﻧﻮﻳﺴﻲ ﺑﺎ اﺳﺘﻔﺎده از ﻣﻨـﻮ ﻫـﺎي ﻓﺮﻋﻲ 1ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ راﺣﺘﻲ اﻋﻤﺎﻟﻲ ﻣﺎﻧﻨﺪ ﻛﺎت ﻛﺮدن ،ﻛﭙﻲ ﻛﺮدن ،و ﻳﺎ ﺟﺴﺘﺠﻮ در ﺑﻴﻦ ﻛﺪ را اﻧﺠﺎم دﻫﻴﺪ. در اﻳﻦ ﻓﺼﻞ ﻧﺤﻮه اﻳﺠﺎد ﻣﻨﻮ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﮋوال C#را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد .در ﻃﻲ ﻓﺼﻞ ﻧﺤﻮه ي اﻳﺠـﺎد و ﻣـﺪﻳﺮﻳﺖ ﻣﻨـﻮ ﻫـﺎ و زﻳﺮﻣﻨﻮ ﻫﺎ و ﻫﻤﭽﻨﻴﻦ ﻧﺤﻮه اﻳﺠﺎد ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد .وﻳﮋوال 2005 C#دو ﻧﻮع ﻛﻨﺘﺮل ﺑﺮاي ﻛﺎر ﺑﺎ ﻣﻨﻮ ﻫﺎ در ﺟﻌﺒﻪ اﺑﺰار ﺧﻮد دارد ﻛﻪ در اﻳﻦ ﻓﺼﻞ ﻫﺮ دوي آﻧﻬﺎ را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد. در اﻳﻦ ﻓﺼﻞ:
ﺑﺎ ﻧﺤﻮه ي اﻳﺠﺎد ﻣﻨﻮ ﻫﺎ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. ﺑﺎ ﻧﺤﻮه ي اﻳﺠﺎد زﻳﺮ ﻣﻨﻮ ﻫﺎ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. ﭼﮕﻮﻧﮕﻲ اﺳﺘﻔﺎده از ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
درك وﻳﮋﮔﻴﻬﺎي ﻳﻚ ﻣﻨﻮ: ﻛﻨﺘﺮﻟﻲ ﻛﻪ در وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﺑﺮاي اﻳﺠﺎد ﻣﻨﻮ در ﺑﺮﻧﺎﻣﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد MenuStrip ،ﻧﺎم دارد .اﻳـﻦ ﻛﻨﺘـﺮل داراي ﭼﻨﺪﻳﻦ وﻳﮋﮔﻲ ﻛﻠﻴﺪي اﺳﺖ .اوﻟﻴﻦ و ﻣﻬﻤﺘﺮﻳﻦ وﻳﮋﮔﻲ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ آن ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺳـﺮﻋﺖ و ﺑـﻪ راﺣﺘـﻲ ﻣﻨـﻮ ﻫـﺎ و زﻳﺮﻣﻨﻮ ﻫﺎي ﻣﻮرد ﻧﻴﺎز در ﺑﺮﻧﺎﻣﻪ را اﻳﺠﺎد ﻛﻨﻴﺪ. ﻣﻨﻮ ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ ﻛﻨﺘﺮل اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ ﻋﻼوه ﺑﺮ ﻣﺘﻨﻲ ﻛﻪ ﺑﺮاي ﻫﺮ ﻣﻨﻮ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ ،ﻣـﻲ ﺗﻮاﻧﻨـﺪ ﺷـﺎﻣﻞ ﺗـﺼﻮﻳﺮ ،ﻛﻠﻴـﺪ دﺳﺘﺮﺳﻲ ،ﺷﻮرت ﻛﺎت و ﻳﺎ ﺣﺘﻲ ﺑﻪ ﺻﻮرت ﮔﺰﻳﻨﻪ ي ﻗﺎﺑﻞ اﻧﺘﺨﺎب ﺑﺎﺷﻨﺪ.
ﺗﺼﺎوﻳﺮ: ﺣﺘﻤﺎً ﺗﺎﻛﻨﻮن ﺗﺼﺎوﻳﺮ ﻛﻨﺎر ﻣﻨﻮ ﻫﺎ را در ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي ﻣﺎﻧﻨﺪ Wordو ﻳﺎ ﺣﺘﻲ ﺧﻮد وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻣﺸﺎﻫﺪه ﻛﺮده اﻳﺪ .ﺗﺎ ﻗﺒﻞ از وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﺑﺮاي ﻧﻤﺎﻳﺶ ﺗﺼﻮﻳﺮ در ﻛﻨﺎر ﻣﻨﻮ ﻫﺎي ﺧﻮد ﻳﺎ ﺑﺎﻳﺪ ﺣﺠﻢ زﻳﺎدي از ﻛﺪ را در ﺑﺮﻧﺎﻣﻪ وارد ﻛﺮده و ﻳـﺎ از ﻛﻨﺘﺮﻟﻬﺎي ﺷﺨﺺ-ﺛﺎﻟﺚ 2اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻧﺪ .اﻣﺎ در وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﺑﺮاي ﻫﺮ ﮔﺰﻳﻨﻪ ي ﻣﻨﻮ ،ﻳﻚ ﺧﺎﺻـﻴﺖ Imageﻧﻴـﺰ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ وﺳﻴﻠﻪ آن ﺗﺼﻮﻳﺮي را ﻣﻌﻴﻦ ﻛﻨﻴﺪ ﺗﺎ در ﻛﻨﺎر ﻣﻨﻮ ﻧﻤﺎﻳﺶ داده ﺷﻮد.
1ﻣﻨﻮي ﻓﺮﻋﻲ ﻳﺎ Pop-Up Menuﻣﻨﻮﻳﻲ ﻛﻪ ﺑﺎ ﻛﻠﻴﻚ راﺳﺖ در ﻳﻚ ﻣﺤﺪوده ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد. Third-Party Controls
2
٣٠١
ﻛﻠﻴﺪﻫﺎي دﺳﺘﺮﺳﻲ: ﻳﻚ ﻛﻠﻴﺪ دﺳﺘﺮﺳﻲ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻣﻲ دﻫﺪ ﻛﻪ ﺑﺎ ﻓﺸﺎر ﻛﻠﻴﺪ Altو آن ﻛﻠﻴﺪ در ﺻﻔﺤﻪ ﻛﻠﻴﺪ ،ﺑﻪ ﻣﻨﻮ دﺳﺘﺮﺳـﻲ ﭘﻴـﺪا ﻛﻨـﺪ .ﻛﻠﻴـﺪﻫﺎي دﺳﺘﺮﺳﻲ ﺑﺮاي ﻫﺮ ﻣﻨﻮ ﺑﻪ ﺻﻮرت ﻳﻚ ﺣﺮف ﻫﺴﺘﻨﺪ ﻛﻪ در ﻧﺎم ﻣﻨﻮ ﺑﺎ ﻳﻚ زﻳﺮ ﺧﻂ ﻣﺸﺨﺺ ﻣﻲ ﺷﻮﻧﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﻠﻴﺪ Altﻫﻤـﺮاه ﺑﺎ ﻛﻠﻴﺪ دﺳﺘﺮﺳﻲ ﻣﻨﻮ در ﺻﻔﺤﻪ ﻛﻠﻴﺪ ﻓﺸﺎر داده ﺷﺪ ،ﻣﻨﻮي ﻣﺮﺑﻮﻃﻪ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ وﺳﻴﻠﻪ ﻛﻠﻴﺪﻫﺎي ﻣﻜﺎن ﻧﻤﺎ ﺑﻴﻦ ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻨﻮ ﺟﺎ ﺑﻪ ﺟﺎ ﺷﻮد.
ﺷﻮرت ﻛﺎت ﻫﺎ: ﺑﻪ وﺳﻴﻠﻪ ﺷﻮرت ﻛﺎت ﻫﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺪون اﻳﻨﻜﻪ ﻣﻨﻮي ﻣﻮرد ﻧﻈﺮ را ﻧﻤﺎﻳﺶ دﻫﻴﺪ ،ﮔﺰﻳﻨﻪ اي را از آن اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺷﻮرت ﻛـﺎت ﻫـﺎ ﺑـﻪ ﺻﻮرت ﺗﺮﻛﻴﺐ ﻳﻚ ﻛﻠﻴﺪ ﻛﻨﺘﺮﻟﻲ ﻫﻤﺮاه ﺑﺎ ﻳﻚ ﻛﻠﻴﺪ اﺻﻠﻲ اﺳﺖ ،ﻣﺎﻧﻨﺪ ﺷﻮرت ﻛﺎت Ctrl + Xﺑﺮاي ﻛﺎت ﻛﺮدن ﻳﻚ ﻣﺘﻦ.
ﻋﻼﻣﺖ ﺗﻴﻚ: ﻋﻼﻣﺖ ﺗﻴﻚ ،ﻋﻼﻣﺘﻲ اﺳﺖ ﻛﻪ در ﻛﻨﺎر ﺑﻌﻀﻲ از ﻣﻨﻮ ﻫﺎ ﺑﻪ ﺟﺎي ﻋﻜﺲ ﻗﺮار ﻣﻲ ﮔﻴﺮد و ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ اﻳﻦ ﮔﺰﻳﻨـﻪ ﻫـﻢ اﻛﻨـﻮن اﻧﺘﺨﺎب ﺷﺪه و ﻳﺎ در ﺣﺎل اﺳﺘﻔﺎده اﺳﺖ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻣﻨﻮي Viewرا از وﻳﮋوال اﺳـﺘﻮدﻳﻮ اﻧﺘﺨـﺎب ﻛـﺮده و ﺳـﭙﺲ ﺑـﻪ زﻳـﺮ ﻣﻨـﻮي ToolBarsﺑﺮوﻳﺪ ،ﻧﺎم ﺗﻤﺎم ﻧﻮار اﺑﺰارﻫﺎي ﻣﻮﺟﻮد در وﻳﮋوال اﺳﺘﻮدﻳﻮ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻛﻨﺎر ﺑﻌﻀﻲ از آﻧﻬﺎ ﻳـﻚ ﻋﻼﻣـﺖ ﺗﻴﻚ ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ .وﺟﻮد اﻳﻦ ﻋﻼﻣﺖ در ﻛﻨﺎر ﻳﻚ ﮔﺰﻳﻨﻪ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻧﻮار اﺑﺰار ﻣﺮﺑﻮط ﺑﻪ آن ﮔﺰﻳﻨﻪ ﻫﻢ اﻛﻨﻮن در وﻳـﮋوال اﺳﺘﻮدﻳﻮ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﺳﺖ. ﺷﻜﻞ 1-8وﻳﮋﮔﻲ ﻫﺎﻳﻲ ﻛﻪ ﻳﻚ ﻣﻨﻮ ﻣﻲ ﺗﻮاﻧﺪ داﺷﺘﻪ ﺑﺎﺷﺪ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،اﻳﻦ ﻣﻨﻮي ﻧﻤﻮﻧﻪ ﻋـﻼوه ﺑﺮ ﺗﻤﺎم وﻳﮋﮔﻴﻬﺎﻳﻲ ﻛﻪ ذﻛﺮ ﻛﺮدﻳﻢ ﻳﻚ ﻣﻨﻮي ﺟﺪا ﻛﻨﻨﺪه ﻧﻴﺰ دارد .ﻳﻚ ﻣﻨﻮي ﺟﺪا ﻛﻨﻨﺪه ﺑﻪ ﺻﻮرت ﻳﻚ ﺧﻂ اﻓﻘﻲ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و ﺑﺮاي دﺳﺘﻪ ﺑﻨﺪي ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﺮﺗﺒﻂ ﺑﻪ ﻫﻢ در ﻣﻨﻮ ﺑﻪ ﻛﺎر ﻣﻲ رود.
ﺷﻜﻞ 1-8
٣٠٢
ﺷﻜﻞ 1-8ﻣﻨﻮي ﺑﺮﻧﺎﻣﻪ را در زﻣﺎن اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .اﻳﻦ ﻣﻨﻮ در زﻣﺎن ﻃﺮاﺣﻲ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 2-8ﺧﻮاﻫﺪ ﺑﻮد.
ﺷﻜﻞ 2-8 در ﻫﻨﮕﺎم ﻛﺎر ﺑﺎ ﻛﻨﺘﺮل MenuStripاوﻟﻴﻦ ﻧﻜﺘﻪ اي ﻛﻪ ﺟﻠﺐ ﺗﻮﺟﻪ ﻣﻲ ﻛﻨﺪ ،اﻳﻦ اﺳﺖ ﻛﻪ ﻋﻼوه ﺑﺮ ﻣﻨﻮ ﻫﺎي اﻳﺠﺎد ﺷﺪه در اﻳﻦ ﻛﻨﺘﺮل ،ﻣﻨﻮﻳﻲ ﻫﻢ وﺟﻮد دارد ﻛﻪ ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﮔﺰﻳﻨﻪ ي ﺟﺪﻳﺪ ﺑﻪ ﻣﻨﻮ و ﻳﺎ زﻳﺮ ﻣﻨﻮ ﺑﻪ ﻛﺎر ﻣﻲ رود .ﻫﺮ زﻣﺎن ﻛﻪ ﺑﺎ اﺳـﺘﻔﺎده از اﻳﻦ ﮔﺰﻳﻨﻪ در ﻛﻨﺘﺮل MenuStripﻳﻚ ﻣﻨﻮي ﺟﺪﻳﺪ اﻳﺠﺎد ﻛﻨﻴﺪ ،ﮔﺰﻳﻨﻪ دﻳﮕﺮي ﻣﺸﺎﺑﻪ ﻗﺒﻠﻲ در اﻳﻦ ﻗﺴﻤﺖ اﻳﺠﺎد ﺧﻮاﻫﺪ ﺷﺪ.
ﭘﻨﺠﺮه :Properties ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻣﻨﻮ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮدﻳﺪ و در ﺣﺎل ﺗﻐﻴﻴﺮ وﻳﮋﮔﻲ ﻫﺎي آن ﺑﻮدﻳﺪ ،ﭘﻨﺠﺮه Proipertiesﺧﺎﺻـﻴﺘﻬﺎي آن ﻣﻨﻮ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ و ﻣﺎﻧﻨﺪ ﻫﺮ ﻛﻨﺘﺮل دﻳﮕﺮي ﻣﻲ ﺗﻮاﻧﻴﺪ ﺧﺎﺻﻴﺘﻬﺎي آن را ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ .ﺷﻜﻞ 3-8ﭘﻨﺠﺮه Propertiesرا ﺑﺮاي ﻳﻚ ﻛﻨﺘﺮل ﻣﻨﻮ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. در ﻃﺮاﺣﻲ ﻣﻨﻮ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﻤﻮاره ﺑﺎﻳﺪ در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻣﻨﻮي ﺑﺮﻧﺎﻣﻪ ﺧﻮد را ﻫﻤﺎﻧﻨﺪ ﻣﻨﻮي دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫـﺎي وﻳﻨـﺪوزي اﻳﺠـﺎد ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻣﻨﻮ ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ وﻳﮋوال اﺳﺘﻮدﻳﻮ Word ،و ﻳﺎ Outlookﺗﻮﺟـﻪ ﻛﻨﻴـﺪ .در ﺗﻤـﺎم اﻳـﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻨﻮﻳﻲ ﺑﻪ ﻧﺎم Fileوﺟﻮد دارد و ﮔﺰﻳﻨﻪ اي ﺑﻪ ﻧﺎم Exitدر اﻳﻦ ﻣﻨﻮ اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ آن ﻣﻲ ﺗﻮان از ﺑﺮﻧﺎﻣﻪ ﺧﺎرج ﺷﺪ. ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ در ﺑﺮﻧﺎﻣﻪ ﺧﻮد از ﻣﻨﻮ اﺳﺘﻔﺎده ﻛﺮدﻳﺪ ،ﺑﻬﺘﺮ اﺳﺖ ﻣﻨﻮﻳﻲ ﺑﻪ ﻧﺎم ﻓﺎﻳﻞ اﻳﺠـﺎد ﻛـﺮده و ﺣـﺪاﻗﻞ ﮔﺰﻳﻨـﻪ Exitرا در آن ﻗـﺮار دﻫﻴﺪ .اﮔﺮ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻣﻲ دﻫﺪ ﻋﻤﻠﻴﺎﺗﻲ ﻣﺎﻧﻨﺪ ﻛﺎت ﻛﺮدن و ﻳﺎ ﻛﭙﻲ ﻛـﺮدن را اﻧﺠـﺎم دﻫـﺪ ،ﺑﻬﺘـﺮ اﺳـﺖ ﻣﻨـﻮﻳﻲ ﺑـﻪ ﻧـﺎم Editاﻳﺠﺎد ﻛﺮده و اﻳﻦ ﮔﺰﻳﻨﻪ ﻫﺎ را در آن ﻗﺮار دﻫﻴﺪ. ﻧﻜﺘﻪ :در ﻛﺘﺎﺑﺨﺎﻧﻪ MSDNﻛﻪ ﻫﻤﺮاه ﺑﺎ وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﻧﺼﺐ ﻣـﻲ ﺷـﻮد ،ﺑﺨـﺸﻲ ﺑـﻪ ﻧـﺎم User Interface Design and Developmentوﺟﻮد دارد ﻛﻪ ﻣﺴﺎﺋﻞ ﺑﺴﻴﺎري را راﺟﻊ ﺑﻪ ﻃﺮاﺣﻲ راﺑﻂ ﻛﺎرﺑﺮي اﺳﺘﺎﻧﺪارد ﺑﺮاي ﺑﺮﻧﺎﻣـﻪ ﻫﺎي وﻳﻨﺪوزي ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﺪ .ﺑﺮاي اﻃﻼع در ﻣﻮرد ﭼﮕﻮﻧﮕﻲ ﻃﺮاﺣﻲ اﺳﺘﺎﻧﺪارد راﺑﻄﻬﺎي ﻛﺎرﺑﺮي ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ آن ﺑﺨﺶ ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ. دﻟﻴﻞ اﻳﻨﻜﻪ ﻣﻨﻮ ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺑﺎﻳﺪ ﻫﻤﺎﻧﻨﺪ ﻣﻨﻮ ﻫﺎي دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ وﻳﻨﺪوزي ﺑﺎﺷﺪ در اﻳﻦ اﺳﺖ ﻛﻪ ﺑﻪ اﻳﻦ ﺻﻮرت ﻛﺎرﺑﺮان ﻫﻨﮕﺎم ﻛﺎر ﺑﺎ ﺑﺮﻧﺎﻣﻪ اﺣﺴﺎس راﺣﺘﻲ ﺑﻴﺸﺘﺮي ﻣﻲ ﻛﻨﻨﺪ و ﻣﻲ ﺗﻮاﻧﻨﺪ از آﺷﻨﺎﻳﻲ ﻗﺒﻠﻲ ﺧﻮد ﺑﺎ ﻣﻨﻮ ﻫﺎي دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ،در ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻨﺪ و ﻧﻴﺎزي ﻧﺪارﻧﺪ ﻛﻪ ﻋﻤﻠﻜﺮد ﺗﻤﺎﻣﻲ ﻣﻨﻮ ﻫﺎ را از اﺑﺘﺪا ﻳﺎد ﺑﮕﻴﺮﻧﺪ .اﻟﺒﺘﻪ ﻫﻤﻮاره در ﻣﻨﻮي ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﮔﺰﻳﻨﻪ ﻫﺎﻳﻲ وﺟﻮد دارﻧـﺪ ﻛـﻪ در ﺑﺮﻧﺎﻣـﻪ
٣٠٣
ﻫﺎي دﻳﮕﺮ ﻧﻴﺴﺘﻨﺪ .در ﻣﻮرد اﻳﻦ ﮔﺰﻳﻨﻪ ﻫﺎ ﻣﻴﺘﻮاﻧﻴﺪ آﻧﻬﺎ را در ﭼﻨﺪ ﻣﻨﻮي ﺧﺎص در ﺑﻴﻦ ﻣﻨﻮ ﻫﺎ ﻗﺮار دﻫﻴﺪ .اﻣـﺎ ﻫﻤـﻮاره ﻗـﺮار دادن ﮔﺰﻳﻨـﻪ ﻫﺎي ﻋﻤﻮﻣﻲ در ﻗﺴﻤﺘﻬﺎي ﺛﺎﺑﺖ ﻳﻚ ﻣﻨﻮ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﺎرﺑﺮ زودﺗﺮ ﺑﺎ ﻧﺤﻮه ﻛﺎرﻛﺮد ﺑﺮﻧﺎﻣﻪ آﺷﻨﺎ ﺷﻮد.
ﺷﻜﻞ 3-8
اﻳﺠﺎد ﻣﻨﻮ ﻫﺎ: ﺣﺎل ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﺑﺒﻴﻨﻴﻢ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﻨﻮ اﻳﺠﺎد ﻛﺮد .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺮﻧﺎﻣﻪ اي اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛـﺮد ﻛـﻪ ﺷﺎﻣﻞ ﻳﻚ ﻧﻮار ﻣﻨﻮ ،دو ﻧﻮار اﺑﺰار و دو TextBoxﺑﺎﺷﺪ .ﻧﻮار ﻣﻨـﻮ ﺷـﺎﻣﻞ ﻣﻨـﻮ ﻫـﺎي Tools ،View ،Edit ،Fileو Helpو ﭼﻨﺪﻳﻦ ﮔﺰﻳﻨﻪ و زﻳﺮ ﻣﻨﻮ در ﻫﺮ ﻳﻚ از آﻧﻬﺎ ﺧﻮاﻫﺪ ﺑﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﻤـﺎم وﻳﮋﮔـﻲ ﻫـﺎي ﻣﻨـﻮ ﻫـﺎ را در ﺑﺮﻧﺎﻣـﻪ ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ .ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ از ﭼﻨﺪ ﺑﺨﺶ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ ،ﻧﻮﺷﺘﻦ آن را ﻧﻴﺰ ﺑﻪ ﭼﻨﺪ ﻗﺴﻤﺖ ﺗﻘﺴﻴﻢ ﻣﻲ ﻛﻨﻴﻢ و در ﻗﺴﻤﺖ اول ﺑﻪ ﻃﺮاﺣﻲ ﻣﻨﻮ ﻫﺎ ﻣﻲ ﭘﺮدازﻳﻢ.
ﻃﺮاﺣﻲ ﻣﻨﻮ ﻫﺎ:
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻣﻨﻮ ﻫﺎ
٣٠٤
(1وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005را اﺟﺮا ﻛﺮده و ﮔﺰﻳﻨﻪ … File New Projectرا از ﻧﻮار ﻣﻨﻮ اﻧﺘﺨﺎب ﻛﻨﻴـﺪ. در ﻛـﺎدر New Projectﮔﺰﻳﻨـﻪ Windows Applicationرا از ﻗـﺴﻤﺖ Templates اﻧﺘﺨﺎب ﻛﺮده و در ﻛﺎدر Nameﮔﺰﻳﻨﻪ Menusرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﭘﺮوژه ﺟﺪﻳﺪ اﻳﺠﺎد ﺷﻮد. (2در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ،روي ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻛﻠﻴﻚ ﻛﺮده و ﺧﺎﺻﻴﺘﻬﺎي آن را ﻣﻄﺎﺑﻖ ﻟﻴﺴﺖ زﻳﺮ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ Sizeرا ﺑﺮاﺑﺮ ﺑﺎ 300;168ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ StartPositionرا ﺑﺮاﺑﺮ ﺑﺎ CenterScreenﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textرا ﺑﺮاﺑﺮ ﺑﺎ Menu Demoﻗﺮار دﻫﻴﺪ.
(3ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ،ﻳﻚ ﻛﻨﺘﺮل MenuStripرا در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻗﺮار دﻫﻴﺪ .اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﻃﻮر اﺗﻮﻣﺎﺗﻴﻚ در ﺑـﺎﻻي ﻓﺮم ﻗﺮار ﺧﻮاﻫﺪ ﮔﺮﻓﺖ .ﻋﻼوه ﺑﺮ ﻛﻨﺘﺮﻟﻲ ﻛﻪ در ﺑﺎﻻي ﻓﺮم ﻗﺮار داده ﻣﻲ ﺷﻮد ،ﻛﻨﺘﺮﻟﻲ ﻫﻢ ﻫﻤﺎﻧﻨﺪ ﻛﻨﺘﺮﻟﻬﺎي ﻛﺎدر ﻣﺤﺎوره اي ﻛﻪ در ﻓﺼﻞ ﻫﻔﺘﻢ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﺑﻪ ﻗﺴﻤﺖ ﭘﺎﻳﻴﻦ ﺑﺨﺶ ﻃﺮاﺣﻲ ﻓﺮم اﺿﺎﻓﻪ ﻣﻲ ﺷﻮد. (4در ﻗﺴﻤﺖ ﭘـﺎﻳﻴﻦ ﻃﺮاﺣـﻲ روي ﻛﻨﺘـﺮل menuStrip1ﻛﻠﻴـﻚ راﺳـﺖ ﻛﻨﻴـﺪ و از ﻣﻨـﻮي ﻓﺮﻋـﻲ ﺑـﺎز ﺷـﺪه ﮔﺰﻳﻨـﻪ Insert Standard Itemsرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ ﮔﺰﻳﻨﻪ ﻫﺎي ﻳﻚ ﻣﻨﻮي اﺳﺘﺎﻧﺪارد در ﻧﻮار ﻣﻨﻮي ﺑﺎﻻي ﻓﺮم ﻗﺮار ﺑﮕﻴﺮد. (5ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ 4-8ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،ﻳﻚ ﻗﺴﻤﺖ ﺳﻔﻴﺪ رﻧﮓ در ﺳﻤﺖ راﺳﺖ ﻣﻨﻮي Helpوﺟـﻮد دارد ﻛـﻪ ﺑـﻪ وﺳﻴﻠﻪ آن ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﻨﻮ ﻫﺎي ﺟﺪﻳﺪ را اﻳﺠﺎد ﻛﻨﻴﺪ .ﺑﺮاي اﻳﺠﺎد ﻣﻨﻮي ﺟﺪﻳﺪ ﻋﻼوه ﺑﺮ اﺳﺘﻔﺎده از اﻳﻦ ﻗـﺴﻤﺖ ،ﻣـﻲ ﺗﻮاﻧﻴـﺪ از ﭘﻨﺠﺮه Items Collection Editorﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
ﺷﻜﻞ 4-8 ﻧﻮار ﻣﻨﻮي ﺑـﺎﻻي ﺻـﻔﺤﻪ را اﻧﺘﺨـﺎب ﻛـﺮده و ﺳـﭙﺲ در ﭘﻨﺠـﺮه Propertiesروي دﻛﻤـﻪ … در ﻣﻘﺎﺑـﻞ ﮔﺰﻳﻨـﻪ Itemsﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎدر Items Collection Editorﻧﻤﺎﻳﺶ داده ﻣـﻲ ﺷـﻮد .در اﻳﻦ ﻛﺎدر روي دﻛﻤﻪ ﻓﺮﻣﺎن Addﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻳﻚ ﻣﻨﻮي ﺟﺪﻳﺪ ﺑﻪ ﻧﻮار ﻣﻨﻮ اﺿﺎﻓﻪ ﺷﻮد. ﺑﺮاي اﻳﻨﻜﻪ ﻧﺎم ﻣﻨﻮي ﺟﺪﻳﺪ ﺑﺎ ﻧﺎم ﻣﻨﻮ ﻫﺎﻳﻲ ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻠﻲ ﺑﻪ ﻧﻮار ﻣﻨﻮ اﺿـﺎﻓﻪ ﻛـﺮدﻳﻢ ﻫﻤﺎﻫﻨـﮓ ﺑﺎﺷـﺪ ،ﻧـﺎم آن را ﺑـﻪ viewToolStripMenuItemﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺣﺎل ﺧﺎﺻﻴﺖ Textﻣﻨﻮي ﺟﺪﻳﺪ را ﺑﻪ &Viewﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﻛﺎراﻛﺘﺮ & ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن ﻛﻠﻴﺪ دﺳﺘﺮﺳـﻲ ﺑـﻪ ﻳـﻚ ﻣﻨﻮ ﺑﻪ ﻛﺎر ﻣﻲ رود .اﻳﻦ ﻛﺎراﻛﺘﺮ ﻗﺒﻞ از ﻫﺮ ﺣﺮﻓﻲ ﻛﻪ ﻗﺮار ﺑﮕﻴﺮد ،ﻣﻲ ﺗﻮان ﺑﺎ ﺗﺮﻛﻴﺐ آن ﺣﺮف ﺑـﺎ ﻛﻠﻴـﺪ Altﺑـﻪ آن ﻣﻨـﻮ دﺳﺘﺮﺳﻲ داﺷﺖ .در ﻣﻨﻮﻳﻲ ﻛﻪ اﻳﺠﺎد ﻛﺮدﻳﻢ ﻛﺎراﻛﺘﺮ & ﻗﺒﻞ از ﺣﺮف Vﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ ،ﺑﻨـﺎﺑﺮاﻳﻦ در ﻃـﻮل اﺟـﺮاي ﺑﺮﻧﺎﻣـﻪ ﻛﺎرﺑﺮ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻳﻦ ﻣﻨﻮ ﻣﻲ ﺗﻮاﻧﺪ از ﺗﺮﻛﻴﺐ ﻛﻠﻴﺪﻫﺎي Alt + Vاﺳﺘﻔﺎده ﻛﻨﺪ.
٣٠٥
(6
(7
(8
(9
ﺣﺎل ﺑﺎﻳﺪ ﻣﻨﻮي ﺟﺪﻳﺪ را ﺑﻴﻦ ﻣﻨﻮ ﻫﺎي Editو Toolsﻗﺮار دﻫﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻨﻮي Viewرا در ﻟﻴﺴﺖ ﻣﻨﻮ ﻫﺎ اﻧﺘﺨﺎب ﻛﺮده و روي ﻓﻠﺶ ﺑﻪ ﺳﻤﺖ ﺑﺎﻻ در ﺳﻤﺖ راﺳﺖ ﻟﻴﺴﺖ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﻨﻮي Viewدر ﻣﻜﺎن درﺳـﺖ ﺧـﻮد ﻗـﺮار ﺑﮕﻴﺮد. ﺣﺎل از ﺑﻴﻦ ﺧﺎﺻﻴﺘﻬﺎي ﻣﻨﻮي Viewﺧﺎﺻﻴﺖ DropDownItemsرا اﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤﻪ ي … در ﻣﻘﺎﺑﻞ آن ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﭘﻨﺠﺮه دﻳﮕﺮي ﻣﺸﺎﺑﻪ ﭘﻨﺠﺮه Items Collection Editorﺑﺎز ﻣﻲ ﺷﻮد ﻛﻪ ﺑﻪ وﺳـﻴﻠﻪ آن ﻣﻲ ﺗﻮاﻧﻴﺪ ،ﻣﻨﻮ ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺗﺤﺖ ﻣﻨﻮي Viewﻗﺮار ﮔﻴﺮﻧﺪ را اﻳﺠﺎد ﻛﻨﻴﺪ. در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻓﻘﻂ ﻳﻚ ﻣﻨﻮ ﺗﺤﺖ ﻣﻨﻮي Viewﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷـﻮد و آن ﻫـﻢ ﻣﻨـﻮي ToolBarsﺧﻮاﻫـﺪ ﺑـﻮد. ﺑﻨـﺎﺑﺮاﻳﻦ در ﭘﻨﺠـﺮه Items Collection Editorدوم ،روي دﻛﻤـﻪ Addﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﻣﻨـﻮي دﻳﮕﺮي اﺿﺎﻓﻪ ﺷﻮد. ﻣﺠﺪدا ﺑﺮاي ﺳﺎزﮔﺎري ﻧﺎم ﻣﻨﻮي ﺟﺪﻳﺪ ﺑﺎ دﻳﮕﺮ ﻣﻨﻮ ﻫﺎ ،ﻧـﺎم آن را ﺑـﻪ toolbarToolStripMenuItem ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﻫﻤﭽﻨﻴﻦ ﺧﺎﺻﻴﺖ Textاﻳﻦ ﻣﻨﻮ را ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎ &Toolbarsﻗﺮار دﻫﻴﺪ. در اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﺎﻳﺪ دو زﻳﺮ ﻣﻨﻮ ﺑﻪ ﻣﻨﻮي Toolbarsاﺿﺎﻓﻪ ﻛﻨﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﺧﺎﺻﻴﺖ DropDownItemsرا در ﺑﻴﻦ ﺧﺎﺻﻴﺘﻬﺎي ﻣﻨﻮي Toolbarsاﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤﻪ … ﻣﻘﺎﺑﻞ آن ﻛﻠﻴﻚ ﻛﻨﻴﺪ. ﭘﻨﺠﺮه Items Collection Editorدﻳﮕﺮي ﺑﺎز ﺧﻮاﻫﺪ ﺷﺪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ آن ﻣﻲ ﺗﻮاﻧﻴﺪ زﻳﺮ ﻣﻨﻮ ﻫـﺎي ﻣﺮﺑﻮط ﺑﻪ ﻣﻨﻮي Toolbarsرا اﻳﺠﺎد ﻛﻨﻴﺪ .در اﻳﻦ ﭘﻨﺠﺮه روي دﻛﻤﻪ Addﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻳﻚ ﻣﻨﻮي ﺟﺪﻳـﺪ اﻳﺠـﺎد ﺷﻮد .ﻧﺎم اﻳﻦ ﻣﻨﻮ را ﺑﺮاﺑﺮ ﺑﺎ mainToolStripMenuItemو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑـﺮ ﺑـﺎ &Main ﻗﺮار دﻫﻴﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ اﺟﺮا ﻣﻲ ﺷﻮد ،ﻧﻮار اﺑﺰار Mainﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﻛﻨﺎر اﻳﻦ ﻣﻨﻮ ﺑﺎﻳﺪ ﻋﻼﻣﺘﻲ ﻗﺮار ﺑﮕﻴﺮد ﺗﺎ ﻣﺸﺨﺺ ﻛﻨﺪ ﻛﻪ اﻳﻦ ﻧﻮار اﺑﺰار در ﺣﺎل ﺣﺎﺿﺮ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﺳﺖ .ﺧﺎﺻـﻴﺖ Checkedاﻳـﻦ ﻣﻨﻮ را ﺑﺮاﺑﺮ ﺑﺎ Trueﻗﺮار دﻫﻴﺪ ﺗﺎ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض ﻳﻚ ﻋﻼﻣﺖ ﺗﻴﻚ در ﻛﻨﺎر آن ﻗـﺮار ﺑﮕﻴـﺮد .ﻫﻤﭽﻨـﻴﻦ ﺧﺎﺻـﻴﺖ CheckOnClickاﻳﻦ ﻣﻨﻮ را ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎ Trueﻗﺮار دﻫﻴﺪ ﺗﺎ ﺑﺎ ﻛﻠﻴﻚ ﻛﺎرﺑﺮ روي اﻳﻦ ﻣﻨﻮ ،ﻋﻼﻣﺖ ﺗﻴﻚ ﻛﻨﺎر آن ﺑﺮداﺷﺘﻪ ﺷﻮد و ﻳﺎ ﻗﺮار داده ﺷﻮد. زﻳﺮ ﻣﻨﻮي دﻳﮕﺮي ﻛﻪ ﺑﺎﻳﺪ در اﻳﻦ ﻗﺴﻤﺖ اﺿﺎﻓﻪ ﻛﻨﻴﻢ ،زﻳﺮ ﻣﻨﻮي Formattingاﺳـﺖ .روي دﻛﻤـﻪ Addﻛﻠﻴـﻚ ﻛﻨﻴـــﺪ ﺗـــﺎ زﻳـــﺮ ﻣﻨـــﻮي ﺟﺪﻳـــﺪي ﺑـــﻪ اﻳـــﻦ ﻗـــﺴﻤﺖ اﺿـــﺎﻓﻪ ﺷـــﻮد .ﺳـــﭙﺲ ﺧﺎﺻـــﻴﺖ Nameآن را ﺑـــﻪ formattingToolStripMenuItemو ﺧﺎﺻــﻴﺖ Textآن را ﺑﺮاﺑــﺮ ﺑــﺎ &Formatting ﻗﺮار دﻫﻴﺪ. ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ اﻳﻦ زﻳﺮ ﻣﻨﻮ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض ﻧﻤﺎﻳﺶ داده ﻧﻤﻲ ﺷﻮد ،ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛـﻪ ﺧﺎﺻـﻴﺖ Checkedآن را ﺑﺮاﺑﺮ ﺑﺎ Trueﻗﺮار دﻫﻴﺪ .اﻣﺎ ﺑﺎﻳﺪ ﺧﺎﺻﻴﺖ CheckedOnClickرا ﺑﺮاﺑﺮ ﺑﺎ Trueﻗﺮار دﻫﻴﺪ ﺗﺎ در ﺻﻮرﺗﻲ ﻛﻪ ﻛﺎرﺑﺮ روي اﻳﻦ ﮔﺰﻳﻨﻪ ﻛﻠﻴﻚ ﻛﺮد ،ﻋﻼﻣﺖ ﺗﻴﻚ در ﻛﻨﺎر آن ﻧﻤﺎﻳﺶ داده ﺷﺪه و ﻳﺎ از ﻛﻨﺎر آن ﺑﺮداﺷﺘﻪ ﺷﻮد. روي دﻛﻤﻪ OKدر ﺗﻤﺎم ﻛﺎدرﻫﺎي Items Collection Editorﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺗﻤﺎم آﻧﻬﺎ ﺑﺴﺘﻪ ﺷﻮﻧﺪ. ﺣﺎل اﮔﺮ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و در ﻣﻨﻮي Viewروي ﮔﺰﻳﻨﻪ Toolbarsﻛﻠﻴﻚ ﻛﻨﻴﺪ ،زﻳﺮ ﻣﻨﻮﻳﻲ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 5-8 ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﺗﻤﺎم ﺳﻌﻲ ﺧﻮد را ﻛﺮده اﺳﺖ ﺗﺎ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ را از اﻧﺠﺎم ﻛﺎرﻫﺎي ﺗﻜﺮاري و ﺧﺴﺘﻪ ﻛﻨﻨﺪه رﻫﺎ ﻛﻨﺪ .ﻳﻜـﻲ از اﻳـﻦ ﻣﻮارد اﻳﺠﺎد ﻣﻨﻮ ﻫﺎي اﺳﺘﺎﻧﺪاردي اﺳﺖ ﻛﻪ در ﻫﻤﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻳﺎﻓـﺖ ﻣـﻲ ﺷـﻮد .ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ ﻣـﺸﺎﻫﺪه ﻛﺮدﻳـﺪ ﺑـﺎ اﺳـﺘﻔﺎده از ﮔﺰﻳﻨـﻪ
٣٠٦
Insert Standard Itemsﻣﻨﻮ ﻫﺎﻳﻲ ﻛﻪ در ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد ﺑﺎ ﺟﺰﺋﻴﺎت ﻛﺎﻣﻞ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﺪ .ﺑﻪ اﻳﻦ ﺻﻮرت ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﻤﺮﻛﺰ ﺑﻴﺸﺘﺮي روي ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﺨﺼﻮص ﺑﺮﻧﺎﻣﻪ ﺧﻮد داﺷﺘﻪ ﺑﺎﺷﻴﺪ .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺟﺰ ﻣﻨﻮ ﻫﺎي اﺳﺘﺎﻧﺪارد ،ﻓﻘﻂ ﻛﺎﻓﻲ اﺳﺖ ﻣﻨﻮي Viewرا ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ ﻛﻪ اﻳﻦ ﻣﻨﻮ ﺧﻮد ﻧﻴﺰ ﺷﺎﻣﻞ ﻣﻨﻮي Toolbarsو زﻳﺮﻣﻨﻮ ﻫـﺎي Mainو Formattingاﺳﺖ.
ﺷﻜﻞ 5-8
اﺿﺎﻓﻪ ﻛﺮدن ﻧﻮار اﺑﺰارﻫﺎ و ﻛﻨﺘﺮل ﻫﺎ: ﺣﺎل ﻛﻪ ﻣﻨﻮ ﻫﺎي ﻣﻮرد ﻧﻴﺎز در ﺑﺮﻧﺎﻣﻪ را اﻳﺠﺎد ﻛﺮدﻳﻢ ،ﺑﻪ ﺳﺮاغ ﻧﻮار اﺑﺰارﻫﺎ و دﻛﻤﻪ ﻫﺎي آن ﻣﻲ روﻳﻢ .ﻣﻨﻮ ﻫـﺎﻳﻲ ﻛـﻪ در ﺑﺨـﺶ ﻗﺒﻠـﻲ اﻳﺠﺎد ﻛﺮدﻳﻢ ،ﻧﻤﺎﻳﺶ داده ﺷﺪن و ﻳﺎ ﻧﺸﺪن اﻳﻦ ﻧﻮار اﺑﺰارﻫﺎ را ﻛﻨﺘﺮل ﺧﻮاﻫﻨﺪ ﻛﺮد .ﻫﻤﭽﻨﻴﻦ دو TextBoxﻧﻴـﺰ ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛﺮد ﺗﺎ ﺑﻪ وﺳﻴﻠﻪ دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻧﻮار اﺑﺰار و ﻳﺎ ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻨﻮ ﻫﺎ ﺑﺘﻮاﻧﻴﻢ ﻣﺘﻦ داﺧﻞ ﻳﻜﻲ از آن را ﻛﺎت و ﻳﺎ ﻛﭙﻲ ﻛـﺮده و در دﻳﮕﺮي ﻗﺮار دﻫﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﻧﻮار اﺑﺰارﻫﺎ و ﻛﻨﺘﺮل ﻫﺎ (1در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﻪ دو ﻧﻮار اﺑﺰار ﻧﻴﺎز دارﻳﺪ .اﺑﺘﺪا ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل ToolStripﺑﺮ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ. ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﻃﻮر اﺗﻮﻣﺎﺗﻴﻚ در ﻗﺴﻤﺖ ﺑﺎﻻي ﻓﺮم ﻗﺮار ﻣﻲ ﮔﻴﺮد .ﺧﺎﺻﻴﺖ Nameاﻳﻦ ﻧﻮار اﺑـﺰار را ﺑﻪ tspFormattingﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﻫﻤﭽﻨﻴﻦ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﻧﻤﻲ ﺧﻮاﻫﻴﻢ اﻳﻦ ﻧﻮار اﺑﺰار ﺑﻪ ﻃـﻮر ﭘـﻴﺶ ﻓـﺮض در ﻓﺮم ﻧﻤﺎﻳﺶ داده ﺷﻮد ،ﺧﺎﺻﻴﺖ Visibleآن را ﺑﺮاﺑﺮ falseﻗﺮار دﻫﻴﺪ. (2در اﻳﻦ ﻧﻮار اﺑﺰار ﺑﻪ ﺳﻪ دﻛﻤﻪ ﻧﻴﺎز دارﻳﻢ .ﺑﻨﺎﺑﺮاﻳﻦ در ﺑﻴﻦ ﺧﺼﻮﺻﻴﺎت آن ،ﮔﺰﻳﻨﻪ Itemsرا اﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤﻪ ي … ﻣﻘﺎﺑﻞ آن ﻛﻠﻴﻚ ﻛﻨﻴﺪ. در ﭘﻨﺠــﺮه Items Collection Editorروي دﻛﻤــﻪ ي Addﻛﻠﻴــﻚ ﻛﻨﻴــﺪ ﺗــﺎ ﻳــﻚ ﻛﻨﺘــﺮل Buttonﺑﻪ اﻳﻦ ﻧﻮار اﺑﺰار اﺿﺎﻓﻪ ﺷﻮد .ﻣﻲ ﺗﻮاﻧﻴﺪ ﺧﺎﺻﻴﺖ ﻧﺎم و دﻳﮕﺮ ﺧﺎﺻﻴﺘﻬﺎي اﻳﻦ ﻛﻨﺘﺮل را ﺗﻐﻴﻴﺮ ﻧﺪﻫﻴﺪ ،زﻳـﺮا ﻧﻤـﻲ ﺧﻮاﻫﻴﺪ از آن در ﻛﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺗﻨﻬﺎ ﺧﺎﺻﻴﺖ DisplayStyleآن را ﺑﺮاﺑـﺮ ﺑـﺎ Imageﻗـﺮار داده و ﺳـﭙﺲ روي دﻛﻤﻪ … در ﻣﻘﺎﺑﻞ ﺧﺎﺻﻴﺖ Imageﻛﻠﻴﻚ ﻛﻨﻴﺪ. در ﭘﻨﺠﺮه Select Resourceروي دﻛﻤﻪ Importsﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﺑﻪ آدرس زﻳﺮ ﺑﺮوﻳﺪ: \C:\Program Files\Microsoft Visual Studio 8\Common7 ٣٠٧
(3
(4
(5 (6
(7 (8
\VS2005ImageLibrary\Bitmaps\Commands\highColor در اﻳﻦ ﻓﻮﻟﺪر ،ﻓﺎﻳـﻞ AlignTableCellMiddleLeftJustHS.bmpرا اﻧﺘﺨـﺎب ﻛـﺮده و روي دﻛﻤﻪ Openﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺳﭙﺲ در ﭘﻨﺠﺮه Select Resourceروي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑﺴﺘﻪ ﺷﻮد. در ﭘﻨﺠـﺮه Items Collection Editorﺑـﺎر دﻳﮕـﺮ روي دﻛﻤـﻪ Addﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﻛﻨﺘـﺮل Buttonدﻳﮕﺮي ﺑﻪ ﻧﻮار اﺑﺰار اﺿﺎﻓﻪ ﺷﻮد .ﺧﺎﺻـﻴﺖ DisplayStyleآن را ﺑﺮاﺑـﺮ ﺑـﺎ Imageﻗـﺮار داده و ﺳــﭙﺲ ﻓﺎﻳــﻞ AlignTableCellMiddleCenterHS.bmpاز آدرس ﻗﺒﻠــﻲ را ﺑــﺮاي ﺧﺎﺻــﻴﺖ Imageآن ﻣﺸﺨﺺ ﻛﻨﻴﺪ. ﻛﻨﺘﺮل Buttonدﻳﮕﺮي ﺑﻪ ﻧﻮار اﺑﺰار اﺿﺎﻓﻪ ﻛﺮده ،ﺧﺎﺻﻴﺖ DisplayStyleآن را ﺑﺮاﺑـﺮ ﺑـﺎ Imageﻗـﺮار دﻫﻴﺪ .ﺑﺮاي اﻳﻦ دﻛﻤـﻪ ،ﻓﺎﻳـﻞ AlignTableCellMiddleRightHS.bmpرا ﺑـﻪ ﻋﻨـﻮان ﺗـﺼﻮﻳﺮ ﻣﺸﺨﺺ ﻛﻨﻴﺪ. در ﭘﻨﺠﺮه Items Collection Editorروي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑﺴﺘﻪ ﺷﻮد. ﺣﺎل ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ،ﻧﻮار اﺑﺰار دوم را ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮده و ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑـﺮ ﺑـﺎ tspMainﻗـﺮار دﻫﻴﺪ .اﻳﻦ ﻧﻮار اﺑﺰار ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻧﻮار اﺑﺰار ﻗﺒﻠﻲ در ﺑﺎﻻي ﻓﺮم ﻗﺮار ﻣﻲ ﮔﻴﺮد .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ اﻳﻦ ﻧـﻮار اﺑـﺰار ﺷـﺎﻣﻞ دﻛﻤﻪ ﻫﺎي اﺳﺘﺎﻧﺪار ﺑﺎﺷﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ روي ﻛﻨﺘﺮل tspMainدر ﭘﺎﻳﻴﻦ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨـﻮي ﻓﺮﻋﻲ ﻛﻪ ﺑﺎز ﻣﻲ ﺷﻮد ﮔﺰﻳﻨﻪ Insert Standard Itemsرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. ﻳﻚ ﻛﻨﺘﺮل Panelاز ﺟﻌﺒﻪ اﺑﺰار روي ﻓﺮم ﻗﺮار داده و ﺧﺎﺻﻴﺖ Dockآن را ﺑﺮاﺑﺮ ﺑﺎ Fillﻗﺮار دﻫﻴﺪ ﺗﺎ ﺗﻤﺎم ﻓـﺮم را درﺑﺮ ﮔﻴﺮد. دو ﻛﻨﺘﺮل TextBoxروي ﻓﺮم ﻗﺮار دﻫﻴﺪ و ﻣﻘﺪار ﭘﻴﺶ ﻓﺮض ﺧﺎﺻﻴﺘﻬﺎي آن را ﺗﻐﻴـﺮي ﻧﺪﻫﻴـﺪ .ﻣﻜـﺎن و اﻧـﺪازه اﻳـﻦ ﻛﻨﺘﺮل ﻫﺎ ﻣﻬﻢ ﻧﻴﺴﺘﻨﺪ ،اﻣﺎ ﺑﺎﻳﺪ ﺑﻪ اﻧﺪازه ﻛﺎﻓﻲ ﺑﺰرگ ﺑﺎﺷﻨﺪ ﺗﺎ ﺑﺘﻮاﻧﻴﺪ ﻣﺘﻨﻲ را در آن ﺑﻨﻮﻳﺴﻴﺪ .ﻓﺮم ﻛﺎﻣـﻞ ﺷـﺪه ﺑﺮﻧﺎﻣـﻪ ﺑﺎﻳـﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 6-8ﺑﺎﺷﺪ .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﻓﺮم ﻧﻮار اﺑﺰار دوم ﻣﺸﺎﻫﺪه ﻧﻤﻲ ﺷﻮد ،زﻳﺮا ﺧﺎﺻﻴﺖ Visibleآن ﺑﺮاﺑـﺮ ﺑﺎ falseﻗﺮار داده ﺷﺪه اﺳﺖ.
ﺷﻜﻞ 6-8
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺎ ﭼﮕﻮﻧﮕﻲ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل ToolStripدر ﻓﺼﻞ ﺷﺸﻢ آﺷﻨﺎ ﺷﺪﻳﺪ ،ﺑﺮاي ﻣﻄﺎﻟﻌﻪ ي ﻣﺠﺪد آن ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮﻧﺎﻣﻪ ي Text Editorرا ﻛﻪ در آن ﻓﺼﻞ ﺗﻤﺮﻳﻦ ﻛﺮدﻳﻢ ﻣﺸﺎﻫﺪه ﻛﻨﻴـﺪ .ﻛﻨﺘـﺮل ToolStripﻧﻴـﺰ ﻫﻤﺎﻧﻨـﺪ ﻛﻨﺘـﺮل MenuStrip داراي ﮔﺰﻳﻨﻪ Insert Standard Itemsاﺳﺖ ﻛﻪ ﺑﺎ ﻗﺮار دادن دﻛﻤﻪ ﻫﺎي ﻋﻤﻮﻣﻲ در ﻧـﻮار اﺑـﺰار ،ﺣﺠـﻢ زﻳـﺎدي از ﻛﺎرﻫﺎي ﺗﻜﺮاري را در ﺑﺮﻧﺎﻣﻪ ﻛﻢ ﻣﻲ ﻛﻨﺪ .ﺑﺪون ﺷﻚ اﺳﺘﻔﺎده از اﻳﻦ ﮔﺰﻳﻨﻪ ﺑﻬﺘﺮﻳﻦ راه ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن دﻛﻤﻪ ﻫﺎي اﺳﺘﺎﻧﺪارد ﺑﻪ ﻳـﻚ
٣٠٨
ﻧﻮار اﺑـﺰار اﺳـﺖ .اﻟﺒﺘـﻪ ﺑﻌـﺪ از اﻳﻨﻜـﻪ اﻳـﻦ دﻛﻤـﻪ ﻫـﺎ در ﻧـﻮار اﺑـﺰار ﻗـﺮار داده ﺷـﺪ ،ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﺎ اﺳـﺘﻔﺎده از ﭘﻨﺠـﺮه Collection Editorﻣﻜﺎن آﻧﻬﺎ را ﺗﻐﻴﻴﺮ داده و ﻳﺎ دﻛﻤﻪ ﻫﺎي ﺟﺪﻳﺪي ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،ﻧﻮار اﺑﺰار Formattingدﻳﺪه ﻧﻤﻲ ﺷﻮد زﻳﺮا ﺧﺎﺻﻴﺖ Visibleآن ﺑﺮاﺑﺮ ﺑـﺎ Falseﻗﺮار داده ﺷﺪه اﺳﺖ .ﺑﺮاي ﻣﺸﺎﻫﺪه اﻳﻦ ﻧﻮار اﺑﺰار ﺑﺎﻳﺪ روي ﻛﻨﺘﺮل ﻣﺮﺑﻮط ﺑﻪ آن در ﻗﺴﻤﺖ ﭘﺎﻳﻴﻦ ﻃﺮاﺣﻲ ﻓﺮم ﻛﻠﻴﻚ ﻛﻨﻴﺪ. Items
ﻧﻮﺷﺘﻦ ﻛﺪ ﺑﺮاي ﻣﻨﻮ ﻫﺎ: ﺣﺎل ﻛﻪ ﺗﻤﺎم ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮرد ﻧﻴﺎز را در ﻓﺮم ﻗﺮار دادﻳﻢ ،ﺑﺎﻳﺪ ﻛﺪ ﻧﻮﻳﺴﻲ آﻧﻬﺎ را ﺷﺮوع ﻛﻨﻴﻢ .اﺑﺘﺪا ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻋﻤﻠﻜـﺮد ﻣﻨـﻮ ﻫـﺎ را ﻣـﻲ ﻧﻮﻳﺴﻴﻢ .ﺑﻌﺪ از اﺗﻤﺎم آن ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﺑﻌﻀﻲ از دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻧﻮار اﺑﺰار Mainرا ﻛﺎﻣﻞ ﻣﻲ ﻛﻨﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻧﻮﺷﺘﻦ ﻛﺪ ﻣﻨﻮي File (1ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم رﻓﺘﻪ و ﺑﺎ اﺳﺘﻔﺎده از ﻧﻮار ﻣﻨﻮ ،ﮔﺰﻳﻨﻪ Newرا از ﻣﻨـﻮي Fileاﻧﺘﺨـﺎب ﻛﻨﻴـﺪ .ﺳـﭙﺲ ﺑـﻪ ﭘﻨﺠـﺮه Propertiesﺑﺮوﻳﺪ و روي آﻳﻜﻮن Eventsﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ روﻳﺪادﻫﺎي اﻳﻦ ﮔﺰﻳﻨﻪ از ﻣﻨﻮ ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ .از ﻟﻴﺴﺖ روﻳﺪادﻫﺎ ،روﻳﺪاد ﻛﻠﻴﻚ را اﻧﺘﺨﺎب ﻛﺮده و روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑـﻪ آن اﻳﺠـﺎد ﺷـﻮد .ﺳـﭙﺲ ﻛـﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void newToolStripMenuItem_Click(object sender, )EventArgs e { // Clear the text boxes ;textBox1.Text = string.Empty ;textBox2.Text = string.Empty // Set focus to the first text box ;)(textBox1.Focus } (2ﻋﻤﻠﻜﺮد دﻛﻤﻪ Newدر ﻧﻮار اﺑﺰار Mainﻧﻴﺰ ﻣﺸﺎﺑﻪ ﻋﻤﻠﻜﺮد اﻳﻦ ﮔﺰﻳﻨﻪ از ﻧﻮار ﻣﻨﻮ اﺳﺖ .ﺑﺮاي ﻧﻮﺷﺘﻦ ﻛﺪ ﻣﺮﺑﻮط ﺑـﻪ اﻳـﻦ دﻛﻤﻪ ،ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم رﻓﺘﻪ و دﻛﻤﻪ Newرا از ﻧﻮار اﺑﺰار اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺳﭙﺲ از ﻟﻴﺴﺖ روﻳـﺪادﻫﺎي اﻳـﻦ ﻛﻨﺘـﺮل در ﭘﻨﺠﺮه Propertiesروﻳﺪاد ﻛﻠﻴﻚ را اﻧﺘﺨﺎب ﻛﺮده و روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ آن اﻳﺠـﺎد ﺷـﻮد. ﺑﻪ ﻋﻠﺖ ﻣﺸﺎﺑﻪ ﺑﻮدن ﻋﻤﻠﻜﺮد اﻳﻦ ﻣﺘﺪ ﺑﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ ﮔﺰﻳﻨﻪ Newدر ﻣﻨﻮي ،Fileدر اﻳﻦ ﻗﺴﻤﺖ ﻛﺎﻓﻲ اﺳﺖ ﻛﺪ زﻳﺮ را ﺑﻪ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void newToolStripButton_Click(object sender, )EventArgs e { // Call the newToolStripMenuItem_Click method ;)newToolStripButton_Click(sender, e
٣٠٩
} (3ﻫﻤﺎﻧﻨﺪ ﻗﺴﻤﺖ ﻳﻚ ،ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ ﮔﺰﻳﻨﻪ exitToolStripmenuItemدر ﻣﻨـﻮي File را اﻳﺠﺎد ﻛﺮده ،ﺳﭙﺲ ﻛﺪ زﻳﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void exitToolStripMenuItem_Click(object sender, )EventArgs e { // Colse the form and exit ;)(Application.Exit }
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ ﮔﺰﻳﻨﻪ Newﻛﺎﻣﻼً واﺿﺢ اﺳﺖ .در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﺣﺎﻟﺖ اوﻟﻴﻪ ﺑﺮﮔﺮداﻧﻴﻢ .ﺑﺮاي اﻳـﻦ ﻛـﺎر ﻧﻴـﺰ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﻣﺘﻦ داﺧﻞ TextBoxﻫﺎ را ﭘﺎك ﻛﺮده و ﻓﻮﻛﻮس را ﺑﻪ TextBoxاول اﻧﺘﻘﺎل دﻫﻴﻢ ﺗﺎ اﮔﺮ ﻛﺎرﺑﺮ ﻣﺘﻨـﻲ را وارد ﻛﺮد ،در اﻳﻦ ﻗﺴﻤﺖ ﻧﻮﺷﺘﻪ ﺷﻮد .ﺑﺮاي ﭘﺎك ﻛﺮدن ﻣﺘﻦ داﺧﻞ TextBoxﻫﺎ ﻧﻴﺰ ﻛـﺎﻓﻲ اﺳـﺖ ﺧﺎﺻـﻴﺖ Textآﻧﻬـﺎ را ﺑﺮاﺑـﺮ ﺑـﺎ ﺧﺎﺻﻴﺖ Emptyاز ﻛﻼس Stringﻗﺮار دﻫﻴﻢ. // Clear the text boxes ;textBox1.Text = string.Empty ;textBox2.Text = string.Empty // Set focus to the first text box ;)(textBox1.Focus دﻛﻤﻪ ي Newدر ﻧﻮار اﺑﺰار ﻧﻴﺰ ﺑﺎﻳﺪ ﻫﻤﻴﻦ ﻋﻤﻞ را اﻧﺠﺎم دﻫﺪ ،اﻣﺎ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ اﻳﻦ ﻛﺪ را ﺑﺮاي اﻳﻦ ﻛﻨﺘﺮل ﻧﻴﺰ ﺗﻜﺮار ﻛﻨﻴﻢ .ﻳﻜﻲ از ﻛﺎرﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻧﺠﺎم دﻫﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻣﺘـﺪي ﻣﺠـﺰا ﺑـﺮاي اﻳـﻦ ﻣـﻮرد ﺑﻨﻮﻳـﺴﻴﺪ و اﻳـﻦ ﻣﺘـﺪ را در ﻣﺘـﺪﻫﺎي newToolStripButton_Clickو newToolStripMenuItem_Clickﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ .اﻣﺎ روش ﺑﻬﺘﺮي ﻫﻢ وﺟﻮد دارد و اﻳﻦ اﺳﺖ ﻛﻪ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻗﺴﻤﺖ را در ﻳﻜﻲ از اﻳﻦ زﻳﺮﺑﺮﻧﺎﻣﻪ ﻫﺎ ﭘﻴﺎده ﺳﺎزي ﻛﺮد و در ﻣﺘﺪ دﻳﮕﺮ آن زﻳﺮﺑﺮﻧﺎﻣﻪ را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮد .در اﻳﻨﺠﺎ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛـﺎر را در ﻣﺘـﺪ newToolStripMenuItem_Clickﻗـﺮار دادﻳﻢ و در زﻳﺮﺑﺮﻧﺎﻣﻪ ي newToolStripButton_Clickآن را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮدﻳﻢ .ﺑﻪ ﻋﻠﺖ اﻳﻨﻜـﻪ ﭘﺎراﻣﺘﺮﻫـﺎي ﻫـﺮ دوي اﻳﻦ ﻣﺘﺪﻫﺎ ﻳﻜﺴﺎن اﺳﺖ ،ﺑﺮاي ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ اول ،ﻣﻲ ﺗﻮاﻧﻴﻢ از ﭘﺎراﻣﺘﺮﻫﺎي ﻣﺘﺪ دوم اﺳﺘﻔﺎده ﻛﻨﻴﻢ. // Call the newToolStripMenuItem_Click method ;)newToolStripButton_Click(sender, e ﺣﺎل ﭼﻪ از دﻛﻤﻪ Newدر ﻧﻮار اﺑﺰار اﺳﺘﻔﺎده ﻛﻨﻴﺪ و ﭼﻪ ﮔﺰﻳﻨﻪ Newاز ﻣﻨﻮي ﻓﺎﻳﻞ را اﻧﺘﺨﺎب ﻛﻨﻴﺪ ،ﻧﺘﻴﺠﻪ ﻣﺸﺎﺑﻪ اي درﻳﺎﻓﺖ ﺧﻮاﻫﻴـﺪ ﻛﺮد.
٣١٠
در ﮔﺰﻳﻨﻪ ي Exitاز ﻣﻨﻮي Fileﺑﺎﻳﺪ ﻛﺪي را ﻗﺮار دﻫﻴﺪ ﺗﺎ ﺑﺮﻧﺎﻣﻪ را ﺗﻤﺎم ﻛﻨﺪ .ﺑﺮاي اﻳﻦ ﻛـﺎر ﻣـﻲ ﺗﻮاﻧﻴـﺪ از ﻣﺘـﺪ Exitدر ﻛﻼس Applicationاﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻳﻦ ﻣﺘﺪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ را ﻣﻲ ﺑﻨﺪد ،ﺗﻤﺎم ﻣﻨﺎﺑﻊ اﺷﻐﺎل ﺷﺪه ﺑﻪ وﺳـﻴﻠﻪ آن را آزاد ﻛـﺮده و ﺑـﻪ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺧﺎﺗﻤﻪ ﻣﻲ دﻫﺪ. // Colse the form and exit ;)(Application.Exit ﺣﺎل ﻛﻪ ﺑﺨﺶ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻣﻨﻮي Fileو دﻛﻤﻪ ﻫﺎي ﻣﺘﻨﺎﻇﺮ آن در ﻧﻮار اﺑﺰار ﺑﻪ ﭘﺎﻳﺎن رﺳﻴﺪ ،ﺑﻪ ﻣﻨﻮي Editﻣﻲ روﻳﻢ ﺗـﺎ ﻛـﺪ ﻣﺮﺑﻮط ﺑﻪ ﮔﺰﻳﻨﻪ ﻫﺎي آن را ﺑﻨﻮﻳﺴﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻧﻮﺷﺘﻦ ﻛﺪ ﻣﻨﻮ Edit (1اوﻟﻴﻦ ﮔﺰﻳﻨﻪ در ﻣﻨﻮي ،Editﮔﺰﻳﻨﻪ Undoاﺳﺖ .ﺑﺮاي ﻧﻮﺷﺘﻦ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﮔﺰﻳﻨﻪ ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮوﻳﺪ و روي ﮔﺰﻳﻨﻪ Undoدر ﻣﻨﻮي Editدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳـﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: private void undoToolStripMenuItem_Click(object sender, )EventArgs e { // Declare a TextBox object and // set it to the ActiveControl ;TextBox objTextBox = (TextBox)this.ActiveControl // Undo the last operation ;)(objTextBox.Undo } (2ﺣﺎل ﺑﺎﻳﺪ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﮔﺰﻳﻨﻪ Cutاز اﻳﻦ ﻣﻨﻮ را ﺑﻨﻮﻳﺴﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﮔﺰﻳﻨﻪ Cutرا از ﻣﻨـﻮي Editاﻧﺘﺨﺎب ﻛﺮده و روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﻣﻲ ﺷﻮد .ﻛﺪ زﻳـﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: private void cutToolStripMenuItem_Click(object sender, )EventArgs e { // Declare a TextBox object and // set it to the ActiveControl ;TextBox objTextBox = (TextBox)this.ActiveControl // Copy the text to the clipboard and clear the field ;)(objTextBox.Cut }
٣١١
ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ اﺳﺘﻔﺎده از ﻧﻮار اﺑﺰار در ﻗـﺴﻤﺖ. در ﻧﻮار اﺑﺰار ﻧﻴﺰ ﻣﺸﺎﺑﻪ ﻋﻤﻠﻜﺮد اﻳﻦ ﮔﺰﻳﻨﻪ در ﻧﻮار ﻣﻨﻮ اﺳﺖCut ( ﻋﻤﻠﻜﺮد دﻛﻤﻪ3 . را اﻧﺘﺨﺎب ﻛﺮده و روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠـﺎد ﺷـﻮدCut دﻛﻤﻪ ي،ﻃﺮاﺣﻲ ﻓﺮم . را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪcutToolStripMenuItem_Click زﻳﺮ ﺑﺮﻧﺎﻣﻪ،ﺳﭙﺲ در اﻳﻦ ﻣﺘﺪ private void cutToolStripButton_Click(object sender, EventArgs e) { // Call the cutToolStripMenuItem_Click procedure cutToolStripMenuItem_Click(sender, e); } ﺑـﺎ دو ﺑـﺎر. اﺳـﺖCut ﻛﺪ اﻳﻦ ﮔﺰﻳﻨﻪ ﻧﻴﺰ ﺑﻪ ﻧﺴﺒﺖ ﻣـﺸﺎﺑﻪ ﮔﺰﻳﻨـﻪ. اﺳﺖCopy ﮔﺰﻳﻨﻪ،Edit ( ﮔﺰﻳﻨﻪ ﺑﻌﺪي در ﻣﻨﻮي4 : ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن را اﻳﺠﺎد ﻛﺮده و ﻛﺪ زﻳﺮ را در آن وارد ﻛﻨﻴﺪ،ﻛﻠﻴﻚ روي اﻳﻦ ﮔﺰﻳﻨﻪ در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم private void copyToolStripMenuItem_Click(object sender, EventArgs e) { // Declare a TextBox object and // set it to the ActiveControl TextBox objTextBox = (TextBox)this.ActiveControl; // Copy the text to the clipboard objTextBox.Copy(); } ﺑﺮاي اﻳﻦ ﻛﺎر. در ﻧﻮار اﺑﺰار را اﻳﺠﺎد ﻛﺮده و در آن ﻣﺘﺪ ﻗﺒﻠﻲ را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪCopy ( ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ دﻛﻤﻪ ي5 :ﻛﺎﻓﻲ اﺳﺖ ﻛﺪ زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ private void copyToolStripButton_Click(object sender, EventArgs e) { // Call the copyToolStripMenuItem_Click procedure copyToolStripMenuItem_Click(sender, e); } . روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ، را اﻧﺘﺨﺎب ﻛﺮدهPaste ﮔﺰﻳﻨﻪ يEdit ( ﺣﺎل ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ و از ﻣﻨﻮي6 : ﻛﺪ زﻳﺮ را وارد ﻛﻨﻴﺪ،در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن ﻛﻪ ﺑﻪ ﻃﻮر اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﻣﻲ ﺷﻮد private void pasteToolStripMenuItem_Click(object sender, EventArgs e) { // Declare a TextBox object and // set it to the ActiveControl TextBox objTextBox = (TextBox)this.ActiveControl;
٣١٢
// Copy the data from the clipboard to the textbox ;)(objTextBox.Paste } (7ﺑﺮاي ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ دﻛﻤﻪ ي Pasteدر ﻧﻮار اﺑﺰار ﻧﻴﺰ ﻣﻲ ﺗﻮان از ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ﻗﺒﻠﻲ اﺳﺘﻔﺎده ﻛﺮد .ﺑﻨـﺎﺑﺮاﻳﻦ ﺑﺎ دو ﺑﺎر ﻛﻠﻴﻚ روي دﻛﻤﻪ Pasteدر ﻧﻮار اﺑﺰار ،ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن را اﻳﺠﺎد ﻛﺮده و ﻛـﺪ زﻳـﺮ را در آن وارد ﻛﻨﻴﺪ: private void pasteToolStripButton_Click(object sender, )EventArgs e { // Call the pasteToolStripButton_Click procedure ;)pasteToolStripButton_Click(sender, e } (8آﺧﺮﻳﻦ ﮔﺰﻳﻨﻪ در ﻣﻨﻮي Editﮔﺰﻳﻨﻪ ي Select Allاﺳﺖ .ﺑﺮاي ﻧﻮﺷﺘﻦ ﻛﺪ ﻣﺮﺑﻮط ﺑـﻪ اﻳـﻦ ﮔﺰﻳﻨـﻪ ﺑـﺎ دو ﺑـﺎر ﻛﻠﻴﻚ روي آن ،ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن را اﻳﺠﺎد ﻛﺮده و ﻛﺪ زﻳﺮ را در آن وارد ﻛﻨﻴﺪ: private void selectAllToolStripMenuItem_Click(object sender, EventArgs )e { // Declare a TextBox object and // set it to the ActiveControl ;TextBox objTextBox = (TextBox)this.ActiveControl // Select all text ;)(objTextBox.SelectAll }
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻧﻮﺷﺘﻦ ﻛﺪ ﻣﻨﻮي Editرا ﺑﺎ ﮔﺰﻳﻨﻪ Undoﺷﺮوع ﻛﺮدﻳﻢ .ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ در ﻓﺮم ﺧﻮد دو TextBoxدارﻳﻢ ،ﻳﺎ ﺑﺎﻳﺪ ﺑـﻪ ﻧﺤـﻮي ﺑﻔﻬﻤﻴﻢ ﻛﻪ ﻛﺪام TextBoxدر ﻓﺮم اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ،ﻳﺎ از ﻳﻚ روش ﻛﻠﻲ اﺳﺘﻔﺎده ﻛﻨﻴﻢ ﻛﻪ ﺑﺮاي ﻫﺮ دو TextBoxﻛﺎرﺑﺮد داﺷﺘﻪ ﺑﺎﺷﺪ .در اﻳﻦ ﻣﺘﺪ از روﺷﻲ ﻛﻠﻲ اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺮاي ﻫﺮ دو TextBoxﺑﻪ ﻛﺎر رود. ﺑــﺮاي اﻳﻨﻜــﻪ ﺑــﻪ ﻛﻨﺘﺮﻟــﻲ ﻛــﻪ ﻫــﻢ اﻛﻨــﻮن در ﻓــﺮم اﻧﺘﺨــﺎب ﺷــﺪه اﺳــﺖ دﺳﺘﺮﺳــﻲ داﺷــﺘﻪ ﺑﺎﺷــﻴﻢ ،ﻣــﻲ ﺗــﻮاﻧﻴﻢ از ﺧﺎﺻــﻴﺖ ActiveControlدر ﻓﺮم اﺳﺘﻔﺎده ﻛﻨﻴﻢ )ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ ﻧﻴﺰ ذﻛﺮ ﺷﺪ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑـﻪ ﺧﺎﺻـﻴﺘﻬﺎي ﻓـﺮم از ﻛﻠﻤﻪ ﻛﻠﻴﺪي thisاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ( .اﻳﻦ ﺧﺎﺻﻴﺖ ،ﺷﻴﺊ اي را از ﻧﻮع Controlﺑﺮﻣﻲ ﮔﺮداﻧﺪ و ﺑﺎﻳﺪ ﻗﺒﻞ از اﺳﺘﻔﺎده از آن در ﺑﺮﻧﺎﻣﻪ آن را ﺑﻪ ﻧﻮع ﻛﻨﺘﺮﻟﻲ ﻛﻪ ﻣﻮرد ﻧﻈﺮﻣﺎن اﺳﺖ ﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ .ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ اﻳﻨﻜﻪ در اﻳﻦ ﻓﺮم ﻓﻘﻂ دو ﻛﻨﺘﺮل وﺟﻮد دارﻧﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻨـﺪ ﺑــﻪ ﻋﻨــﻮان ﻛﻨﺘــﺮل ﻓﻌــﺎل ﺑﺎﺷــﻨﺪ و ﻫــﺮ دوي آﻧﻬــﺎ ﻧﻴــﺰ از ﻧــﻮع TextBoxﻫــﺴﺘﻨﺪ ،ﭘــﺲ ﻛﻨﺘﺮﻟــﻲ ﻛــﻪ ﺑــﻪ وﺳــﻴﻠﻪ ﺧﺎﺻــﻴﺖ ActiveControlﻣﺸﺨﺺ ﻣﻲ ﺷﻮد ﺣﺘﻤﺎً ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﻳﻚ ﺷﻴﺊ از ﻛـﻼس TextBoxﺗﺒـﺪﻳﻞ ﺷـﻮد .ﺑﻨـﺎﺑﺮاﻳﻦ ﺷـﻴﺊ
٣١٣
ﺟﺪﻳﺪي از ﻧﻮع TextBoxﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ و ﻛﻨﺘﺮﻟﻲ را ﻛﻪ ﺧﺎﺻﻴﺖ ActiveControlﺑﺮﻣﻲ ﮔﺮداﻧﺪ ،ﺑﻌﺪ از ﺗﺒﺪﻳﻞ ﻧﻮع، در آن ﻗﺮار ﻣﻲ دﻫﻴﻢ: // Declare a TextBox object and // set it to the ActiveControl ;TextBox objTextBox = (TextBox)this.ActiveControl ﺣﺎل ﻛﻪ ﺑﻪ TextBoxﻛﻪ در ﻓﺮم اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ دﺳﺘﺮﺳﻲ دارﻳﻢ ،ﺑﺮاي ﻟﻐﻮ آﺧﺮﻳﻦ ﻋﻤﻞ آن ﻛﺎﻓﻲ اﺳﺖ ﻣﺘﺪ Undoرا در آن ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ ﻛﻪ ﻋﻀﻮي از ﻛﻼس TextBoxاﺳﺖ ،ﻣﻲ ﺗﻮاﻧﺪ آﺧﺮﻳﻦ ﺗﻐﻴﻴﺮي را ﻛﻪ ﻛﺎرﺑﺮ در آن TextBoxاﻳﺠﺎد ﻛﺮده اﺳﺖ را ﻟﻐﻮ ﻛﻨﺪ. // Undo the last operation ;)(objTextBox.Undo ﻧﻜﺘﻪ :در اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ActiveControlﺑﺴﻴﺎر راﺣﺖ ﺑﻮد ،زﻳﺮا ﻓﻘـﻂ دو ﻛﻨﺘـﺮل TextBoxدر ﻓـﺮم ﻗﺮار داﺷﺖ .ﭘﺲ ﻣﻲ ﺗﻮاﻧﺴﺘﻴﻢ ﺑﺪون ﻧﮕﺮاﻧﻲ از ﺑﻪ وﺟﻮد آﻣﺪن ﺧﻄﺎ در ﺑﺮﻧﺎﻣﻪ ،ﻣﻘﺪار ﺑﺮﮔﺸﺘﻲ از اﻳﻦ ﺧﺎﺻﻴﺖ را ﺑـﻪ ﺷـﻴﺊ اي از ﻛـﻼس TextBoxﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ .اﻣﺎ در ﺷﺮاﻳﻄﻲ ﻛﻪ ﻛﻨﺘﺮل ﻫـﺎي ﮔﻮﻧـﺎﮔﻮﻧﻲ در ﺑﺮﻧﺎﻣـﻪ وﺟـﻮد دارﻧـﺪ ،ﻣﻤﻜـﻦ اﺳـﺖ ﻛـﺎرﺑﺮ ﻳـﻚ ﻛﻨﺘـﺮل Buttonرا اﻧﺘﺨــﺎب ﻛــﺮده و ﺳــﭙﺲ روي ﮔﺰﻳﻨــﻪ ي Undoﻛﻠﻴــﻚ ﻛﻨــﺪ .در اﻳــﻦ ﺻــﻮرت ﻣﻘــﺪار ﺑﺮﮔــﺸﺘﻲ ﺗﻮﺳــﻂ ﺧﺎﺻــﻴﺖ ActiveControlاز ﻧﻮع TextBoxﻧﺨﻮاﻫﺪ ﺑﻮد و ﺗﺒﺪﻳﻞ آن ﺑﻪ TextBoxﻧﻴﺰ ﺑﺎﻋﺚ اﻳﺠﺎد ﺧﻄﺎ در ﺑﺮﻧﺎﻣﻪ ﺧﻮاﻫﺪ ﺷﺪ .در اﻳﻦ ﺷﺮاﻳﻂ ﺑﺮاي ﺑﺪﺳﺖ آوردن ﻛﻨﺘﺮل ﻓﻌﺎل در ﻳﻚ ﻓﺮم ﺑﺎﻳﺪ از روﺷﻬﺎي دﻳﮕﺮي اﺳﺘﻔﺎده ﻛﻨﻴﻢ ﻛﻪ در ﻓـﺼﻠﻬﺎي ﺑﻌـﺪي ﺑـﺎ آﻧﻬـﺎ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﻣﻲ ﺷﻮﻳﺪ. ﮔﺰﻳﻨﻪ ﺑﻌﺪي در ﻣﻨﻮي ،Editﮔﺰﻳﻨﻪ Cutاﺳﺖ .در اﻳﻦ ﮔﺰﻳﻨﻪ ﻧﻴﺰ ،ﺑﺮاي ﻛﺎت ﻛـﺮدن ﻣـﺘﻦ ،اﺑﺘـﺪا ﺑﺎﻳـﺪ ﺑـﻪ ﻛﻨﺘـﺮل ﻓﻌـﺎل در ﻓـﺮم دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ از روش ﻗﺒﻠﻲ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل اﺳﺘﻔﺎده ﻣﻲ ﻛﻨـﻴﻢ .ﺑﻌـﺪ از ﻣـﺸﺨﺺ ﻛـﺮدن ﻛﻨﺘـﺮل ﻓﻌﺎل در ﻓﺮم و ﺗﺒﺪﻳﻞ آن ﺑﻪ ﺷﻴﺊ از ﻛﻼس ،TextBoxﻛﺎﻓﻲ اﺳﺖ ﻣﺘﺪ Cutﻣﺮﺑﻮط ﺑﻪ آن را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ .اﻳـﻦ ﻣﺘـﺪ ﻳﻜـﻲ از ﻋﻀﻮ ﻫﺎي ﻛﻼس TextBoxاﺳﺖ ﻛﻪ ﻣﺘﻦ داﺧﻞ ﻛﺎدر را از آن ﭘﺎك ﻛﺮده و در داﺧﻞ ﻛﻠﻴﭗ ﺑﺮد ﻗﺮار ﻣﻲ دﻫﺪ: // Declare a TextBox object and // set it to the ActiveControl ;TextBox objTextBox = (TextBox)this.ActiveControl // Copy the text to the clipboard and clear the field ;)(objTextBox.Cut ﻋﻤﻠﻜﺮد دﻛﻤﻪ ي Cutدر ﻧﻮار اﺑﺰار ﻧﻴﺰ ﻣﺸﺎﺑﻪ اﻳﻦ ﮔﺰﻳﻨﻪ در ﻧﻮار ﻣﻨﻮ اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﻛﺎﻓﻲ اﺳﺖ در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ از اﻳـﻦ ﻛﻨﺘﺮل ،ﻣﺘﺪي را ﻛﻪ ﺑﺮاي ﮔﺰﻳﻨﻪ Cutدر ﻧﻮار ﻣﻨﻮ ﻧﻮﺷﺘﻴﻢ ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ: private void cutToolStripButton_Click(object sender, )EventArgs e { // Call the cutToolStripMenuItem_Click procedure ;)cutToolStripMenuItem_Click(sender, e
٣١٤
} ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﮔﺰﻳﻨﻪ Copyﻧﻴﺰ ﻣﺸﺎﺑﻪ ﮔﺰﻳﻨﻪ Cutاﺳﺖ .ﻛﺎﻓﻲ اﺳﺖ ﻛﻨﺘﺮل ﻓﻌﺎل در ﻓﺮم را ﻣﺸﺨﺺ ﻛﺮده و ﺑﻌـﺪ از ﺗﺒـﺪﻳﻞ آن ﺑـﻪ ﺷﻴﺊ اي از ﻧﻮع ،TextBoxﻣﺘﺪ Copyآن را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ .ﻣﺘﺪ Copyﻛﻪ ﻋﻀﻮ ﻛﻼس TextBoxاﺳﺖ ،ﻳﻚ ﻛﭙﻲ از ﻣﺘﻦ داﺧﻞ ﻛﺎدر را در ﻛﻠﻴﭗ ﺑﺮد ﻗﺮار ﻣﻲ دﻫﺪ. // Declare a TextBox object and // set it to the ActiveControl ;TextBox objTextBox = (TextBox)this.ActiveControl // Copy the text to the clipboard ;)(objTextBox.Copy ﺑﺮاي روﻳﺪاد ﻛﻠﻴﻚ دﻛﻤﻪ ي Copyدر ﻧﻮار اﺑﺰار ﻫﻢ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﻣﺘﺪ ﻗﺒﻠﻲ را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ: private void copyToolStripButton_Click(object sender, )EventArgs e { // Call the copyToolStripMenuItem_Click procedure ;)copyToolStripMenuItem_Click(sender, e } ﺑﺮاي ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ ﮔﺰﻳﻨﻪ Pasteاز ﻣﻨﻮي Editو ﻫﻤﭽﻨﻴﻦ دﻛﻤﻪ ي Pasteدر ﻧﻮار اﺑﺰار ﻫﻢ ﻣـﻲ ﺗـﻮاﻧﻴﻢ از روﺷﻲ ﻣﺸﺎﺑﻪ ﻣﻮارد ﻗﺒﻠﻲ اﺳﺘﻔﺎده ﻛﻨﻴﻢ. ﺑﺮاي ﮔﺰﻳﻨﻪ Select Allدر اﻳﻦ ﻣﻨﻮ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻣﺘـﺪ SelectAllﻛـﻪ ﻋـﻀﻮي از ﻛـﻼس TextBoxاﺳـﺖ را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﺗﻤﺎم ﻣﺘﻦ ﻣﻮﺟﻮد در TextBoxاﻧﺘﺨﺎب ﺷﻮد: // Declare a TextBox object and // set it to the ActiveControl ;TextBox objTextBox = (TextBox)this.ActiveControl // Select all text ;)(objTextBox.SelectAll
ﻛﺪ ﻧﻮﻳﺴﻲ ﻣﻨﻮي Viewو ﻧﻮار اﺑﺰارﻫﺎ: ﺑﻌﺪ از اﺗﻤﺎم ﻣﻨﻮ ﻫﺎي Fileو Editو دﻛﻤﻪ ﻫﺎي ﻧﻮار اﺑﺰار ﻣﺮﺗﺒﻂ ﺑﺎ آﻧﻬﺎ ،ﻧﻮﺑﺖ ﺑﻪ ﻣﻨﻮي Viewﻣﻲ رﺳﺪ ﺗﺎ ﻛﺪ ﻣﺮﺑﻮط ﺑـﻪ آن را در ﺑﺮﻧﺎﻣﻪ وارد ﻛﻨﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻧﻮﺷﺘﻦ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻣﻨﻮي View
٣١٥
(1در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﻪ ﻣﻨﻮي Viewﺑﺮوﻳﺪ و ﮔﺰﻳﻨﻪ Mainرا از زﻳﺮ ﻣﻨﻮي Toolbarsاﻧﺘﺨﺎب ﻛﻨﻴـﺪ .ﺳـﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ،Propertiesروي روﻳﺪاد ﻛﻠﻴﻚ در ﻟﻴﺴﺖ روﻳﺪادﻫﺎي اﻳﻦ ﮔﺰﻳﻨﻪ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﻣﺘـﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷﻮد .ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void mainToolStripMenuItem_Click(object sender, )EventArgs e { // Toggle the visibility of the Main toolbar // based on this menu item's Checked property )if (mainToolStripMenuItem.Checked { ;tspMain.Visible = true } else { ;tspMain.Visible = false } } (2ﺑﺮاي ﮔﺰﻳﻨﻪ Formattingاز اﻳﻦ زﻳﺮﻣﻨﻮ ﻧﻴﺰ ﺑﺎﻳﺪ از ﻛﺪي ﻣﺸﺎﺑﻪ ﻗﺴﻤﺖ ﻗﺒﻠﻲ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎ دو ﺑـﺎر ﻛﻠﻴﻚ روي اﻳﻦ ﮔﺰﻳﻨﻪ در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ،ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن را اﻳﺠﺎد ﻛﺮده و ﻛﺪ زﻳﺮ را در آن وارد ﻛﻨﻴﺪ: (private void formattingToolStripMenuItem_Click )object sender, EventArgs e { // Toggle the visibility of the Main toolbar // based on this menu item's Checked property = spFormatting.Visible ;formattingToolStripMenuItem.Checked }
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﮔﺰﻳﻨﻪ Mainاز زﻳﺮ ﻣﻨﻮي Toolbarsاﻧﺘﺨﺎب ﺷﻮد ،ﺑﺮ اﺳﺎس اﻳﻨﻜﻪ ﺧﺎﺻﻴﺖ Checkedاﻳﻦ ﮔﺰﻳﻨﻪ ﺑﺮاﺑـﺮ ﺑـﺎ Trueو ﻳﺎ Falseاﺳﺖ ،ﻳﻚ ﻋﻼﻣﺖ ﺗﻴﻚ در ﻛﻨﺎر آن ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و ﻳﺎ اﻳﻦ ﻋﻼﻣـﺖ از ﻛﻨـﺎر آن ﺑﺮداﺷـﺘﻪ ﻣـﻲ ﺷـﻮد. ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗﻮاﻧﻴﻢ در روﻳﺪاد ﻛﻠﻴﻚ اﻳﻦ ﮔﺰﻳﻨﻪ ﻛﺪي را وارد ﻛﻨﻴﻢ ﻛﻪ اﮔﺮ اﻳﻦ ﮔﺰﻳﻨﻪ ﻋﻼﻣﺖ ﺧﻮرده ﺑـﻮد )ﺧﺎﺻـﻴﺖ Checkedآن ﺑﺮاﺑﺮ ﺑﺎ trueﺑﻮد( ﻧﻮار اﺑﺰار Mainﻧﻤﺎﻳﺶ داده ﺷﻮد )ﺧﺎﺻﻴﺖ Visibleآن ﺑﺮاﺑﺮ ﺑﺎ Trueﺷﻮد( .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت اﻳﻦ ﻧﻮار اﺑﺰار ﻧﻤﺎﻳﺶ داده ﻧﺨﻮاﻫﺪ ﺷﺪ. // Toggle the visibility of the Main toolbar // based on this menu item's Checked property )if (mainToolStripMenuItem.Checked
٣١٦
{ ;tspMain.Visible = true } else { ;tspMain.Visible = false } ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ در ﺷﺮط دﺳﺘﻮر ifﻧﻴﺎزي ﻧﻴﺴﺖ از ﻋﺒﺎرت mainToolStripMenuItem.Check == true اﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ذﻛﺮ ﺷﺪ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻋﺒﺎرت داﺧﻞ ﭘﺮاﻧﺘﺰ ﻣﻘﺎﺑﻞ ifﺑﺮاﺑﺮ ﺑﺎ trueﺑﺎﺷﺪ ،دﺳـﺘﻮرات داﺧـﻞ ﺑـﻼك if اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﻪ ﻃﻮر ﻣﺴﺘﻘﻴﻢ از ﺧﻮد ﺧﺎﺻﻴﺖ در ﻣﻘﺎﺑﻞ دﺳﺘﻮر ifاﺳﺘﻔﺎده ﻛﻨـﻴﻢ .اﮔـﺮ ﻣﻘـﺪار ﺧﺎﺻـﻴﺖ ﺑﺮاﺑـﺮ ﺑـﺎ trueﺑﻮد ،دﺳﺘﻮرات داﺧﻞ ﺑﻼك ifاﺟﺮا ﻣﻲ ﺷﻮد و در ﻏﻴﺮ اﻳﻦ ﺻﻮرت دﺳﺘﻮرات داﺧﻞ ﺑﻼك elseاﺟﺮا ﻣﻲ ﺷﻮﻧﺪ. ﺑـﺮاي ﮔﺰﻳﻨــﻪ Formattingﻧﻴـﺰ ﻣــﻲ ﺗــﻮاﻧﻴﻢ از ﻫﻤـﺎن روش اﺳــﺘﻔﺎده ﻛﻨـﻴﻢ ﺗــﺎ ﻣﻘــﺪار ﺧﺎﺻـﻴﺖ Visibleﻧــﻮار اﺑــﺰار Formattingﺑﺮ اﺳﺎس اﻧﺘﺨﺎب ﺷﺪن و ﻳﺎ ﻧﺸﺪن اﻳﻦ ﮔﺰﻳﻨﻪ ﻣﺸﺨﺺ ﺷﻮد .اﻣﺎ روش ﺑﻬﺘﺮي ﻧﻴﺰ ﺑﺮاي ﻧﻮﺷﺘﻦ اﻳـﻦ ﻛـﺪ وﺟـﻮد دارد و اﻳﻦ اﺳﺖ ﻛﻪ ﻣﻘﺪار ﺧﺎﺻﻴﺖ Checkedاﻳﻦ ﮔﺰﻳﻨﻪ از ﻧﻮار ﻣﻨﻮ را ﺑﻪ ﻃﻮر ﻣﺴﺘﻘﻴﻢ در ﺧﺎﺻﻴﺖ Visibleﻧﻮار اﺑﺰار ﻗـﺮار دﻫﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻧﻴﺎزي ﺑﻪ ﺑﺮرﺳﻲ ﺷﺮط ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر ifﻧﻴﺴﺖ و ﻫﻤﺎن ﻛﺪ ﻗﺒﻠﻲ را ﻣﻲ ﺗﻮاﻧﻴﻢ در ﻳـﻚ ﺧـﻂ ﭘﻴـﺎده ﺳـﺎزي ﻛﻨﻴﻢ .اﻳﻦ روش ﻧﺴﺒﺖ ﺑﻪ روش ﻗﺒﻠﻲ ﻋﻼوه ﺑﺮ ﻛﻮﺗﺎه ﺗﺮ ﺑﻮدن ،از ﺳﺮﻋﺖ اﺟﺮاي ﺑﺎﻻﺗﺮي ﻧﻴﺰ ﺑﺮﺧﻮردار اﺳﺖ .اﻟﺒﺘﻪ ﻣﻤﻜﻦ اﺳـﺖ ﺗﻔـﺎوت ﺳﺮﻋﺖ اﻳﻦ روش در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﻮﭼﻜﻲ ﻣﺎﻧﻨﺪ اﻳﻦ ﻣﺜﺎل ﭼﻨﺪان ﻣﻮرد ﺗﻮﺟﻪ واﻗﻊ ﻧﺸﻮد ،اﻣﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺣﺠﻢ ﺑﺮﻧﺎﻣﻪ زﻳﺎد ﺷﻮد اﺳـﺘﻔﺎده از اﻳﻦ ﺗﻜﻨﻴﻚ ﻫﺎ در ﺑﺮﻧﺎﻣﻪ ﺑﺎﻋﺚ اﻓﺰاﻳﺶ ﭼﺸﻤﮕﻴﺮ ﺳﺮﻋﺖ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺷﻮد. // Toggle the visibility of the Main toolbar // based on this menu item's Checked property = spFormatting.Visible ;formattingToolStripMenuItem.Checked
اﻣﺘﺤﺎن ﺑﺮﻧﺎﻣﻪ: ﻫﺮ ﭼﻪ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ ﻣﻲ ﻧﻮﻳﺴﻴﺪ ﭘﻴﭽﻴﺪه ﺗﺮ ﻣﻲ ﺷﻮد ،ﺗﺴﺖ ﻛﺮدن ﻣﺪاوم ﺑﺮاي اﻃﻤﻴﻨﺎن از ﻧﺤﻮه ﻋﻤﻠﻜﺮد آن ﻧﻴـﺰ ﻣﻬﻤﺘـﺮ ﻣـﻲ ﺷـﻮد .در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻫﺮ ﭼﻪ ﺑﻴﺸﺘﺮ ﺧﻄﺎﻫﺎي آن را ﭘﻴﺪا ﻛﺮده و ﺗﺼﺤﻴﺢ ﻛﻨﻴﺪ ،ﺑﻬﺘﺮ ﻣﻲ ﺗﻮاﻧﻴﺪ آن را ﭘﻴﺎده ﺳﺎزي ﻛﻨﻴﺪ .در ﻧﺘﻴﺠﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮﻧﺎﻣـﻪ اي ﭘﺎﻳﺪار ﺗﺮ و ﺑﺎ ﻗﺎﺑﻠﻴﺖ اﻃﻤﻴﻨﺎن ﺑﻴﺸﺘﺮي اﻳﺠﺎد ﻛﻨﻴﺪ. ﺑﺮاي ﺗﺴﺖ ﻛﺮدن ﻳﻚ ﺑﺮﻧﺎﻣﻪ ،ﻧﻪ ﺗﻨﻬﺎ ﺑﺎﻳﺪ ﻋﻤﻠﻜﺮد ﻋﺎدي آن را ﺑﺮرﺳﻲ ﻛﻨﻴﺪ ،ﺑﻠﻜﻪ ﺑﺎﻳﺪ ﻣﻘﺪارﻫﺎي ﻣﺨﺘﻠﻔﻲ ﻛﻪ ﻛـﺎرﺑﺮ ﻣﻤﻜـﻦ اﺳـﺖ در ﺑﺮﻧﺎﻣﻪ وارد ﻛﻨﺪ را ﻧﻴﺰ ﺑﻪ ﻋﻨﻮان ورودي ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﺑﻔﺮﺳﺘﻴﺪ و رﻓﺘﺎر ﺑﺮﻧﺎﻣﻪ را در آن ﺷﺮاﻳﻂ ﺑﺮرﺳﻲ ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴـﺪ در ﺣـﺎل ﻃﺮاﺣﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻫﺴﺘﻴﺪ ﻛﻪ اﻃﻼﻋﺎت ﻛﺎرﺑﺮ را ﺑﻪ وﺳﻴﻠﻪ ﻳـﻚ ﻓـﺮم درﻳﺎﻓـﺖ ﻣـﻲ ﻛﻨـﺪ و در ﻳـﻚ ﺟـﺪول در ﺑﺎﻧـﻚ اﻃﻼﻋﺎﺗﻲ ﻗﺮار ﻣﻲ دﻫﺪ .ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺧﻮب و ﭘﺎﻳﺪار ،ﻗﺒﻞ از اﻳﻨﻜﻪ اﻃﻼﻋﺎت ﻛﺎرﺑﺮ را ﺑﺮاي ذﺧﻴـﺮه ﺷـﺪن ﺑـﻪ ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ ﺑﻔﺮﺳـﺘﺪ، ﺻﺤﺖ ﻧﻮع داده اي ﺗﻤﺎم آﻧﻬﺎ را ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻗﺒﻞ از اﻳﻨﻜﻪ ﺳﻦ ﻛﺎرﺑﺮ را در ﺟﺪول ذﺧﻴﺮه ﻛﻨﺪ ،ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﺣﺘﻤـﺎً ﻣﻘﺪار وارد ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ﻛﺎرﺑﺮ ﺑﺮاي اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺻﻮرت ﻋﺪدي ﺑﺎﺷﺪ و ﻛﺎرﺑﺮ ﻣﺘﻨﻲ را در اﻳﻦ ﻗﺴﻤﺖ وارد ﻧﻜﺮده ﺑﺎﺷﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ از اﻳﺠﺎد ﺧﻄﺎ در ﺑﺮﻧﺎﻣﻪ و ﺗﻮﻗﻒ اﺟﺮا آن ﻧﻴﺰ ﻣﻲ ﺗﻮان ﺗﺎ ﺣﺪ اﻣﻜﺎن ﺟﻠﻮﮔﻴﺮي ﻛﺮد. ٣١٧
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻣﺘﺤﺎن ﺑﺮﻧﺎﻣﻪ (1ﺣﺎل ﻛﻪ راﺑﻂ ﻛﺎرﺑﺮي ﺑﺮﻧﺎﻣﻪ را ﻃﺮاﺣﻲ ﻛﺮدﻳﻢ و ﻛﺪ ﺑﻴﺸﺘﺮ ﻗﺴﻤﺘﻬﺎي آن را ﻧﻴﺰ وارد ﻛﺮدﻳﻢ ،ﺑﺎﻳﺪ ﻋﻤﻠﻜﺮد آن را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ. ﺑﺮاي اﻳﻦ ﻛﺎر روي دﻛﻤﻪ Startدر ﻧﻮار اﺑﺰار ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑﺮﻧﺎﻣﻪ اﺟﺮا ﺷﻮد .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﺮم اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﺷﺪ ،ﻣﺸﺎﺑﻪ ﺷﻜﻞ 7-8ﻓﻘﻂ ﻳﻜﻲ از ﻧﻮار اﺑﺰارﻫﺎ ﻗﺎﺑﻞ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﺪ ﺑﻮد.
ﺷﻜﻞ 7-8 (2
(3
(4
(5
از ﻧﻮار ﻣﻨﻮ ،ﻣﻨﻮي Viewرا اﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ ﺑﻪ زﻳﺮ ﻣﻨﻮي Toolbarsﺑﺮوﻳﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴـﺪ ﻛـﻪ در اﻳـﻦ زﻳﺮﻣﻨﻮ دو ﮔﺰﻳﻨﻪ Mainو Formattingوﺟﻮد دارﻧﺪ ﻛﻪ در ﻛﻨﺎر ﮔﺰﻳﻨﻪ اول ﻳـﻚ ﻋﻼﻣـﺖ ﺗﻴـﻚ ﻗـﺮار دارد .اﻳـﻦ ﻋﻼﻣﺖ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻫﻢ اﻛﻨﻮن اﻳﻦ ﻧﻮار اﺑﺰار در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻗﺎﺑﻞ ﻣﺸﺎﻫﺪه اﺳﺖ .روي ﮔﺰﻳﻨﻪ Formatting در اﻳﻦ ﻗﺴﻤﺖ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻧﻮار اﺑﺰار Formattingﻫﻢ ﻧﻤﺎﻳﺶ داده ﺷﻮد. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﺑﺎ ﻧﻤﺎﻳﺶ اﻳﻦ ﻧﻮار اﺑﺰار ،ﺗﻤﺎم ﻛﻨﺘﺮل ﻫﺎ در ﻓﺮم ﺑﻪ اﻧﺪازه ﻻزم ﺑﻪ ﺳـﻤﺖ ﭘـﺎﻳﻴﻦ ﺣﺮﻛـﺖ ﻛﺮدﻧـﺪ. دﻟﻴﻞ اﻳﻦ اﻣﺮ در اﻳﻦ اﺳﺖ ﻛﻪ ﻳﻚ ﻛﻨﺘﺮل Panelدر ﻓـﺮم ﻗـﺮار داده و ﺑﻌـﺪ از ﺗﻨﻈـﻴﻢ ﺧﺎﺻـﻴﺖ Dockآن ﺑـﺎ ﻣﻘـﺪار ،Fillدو TextBoxرا در آن ﻗﺮار دادﻳﺪ .ﺑﺎ اﻧﺠﺎم اﻳﻦ ﻛﺎر ،ﻣﻮﻗﻌﻴﺖ ﻛﻨﺘﺮل ﻫﺎ ﻣﻲ ﺗﻮاﻧـﺪ در ﺻـﻮرت ﻟـﺰوم در ﻓـﺮم ﺗﻐﻴﻴﺮ ﻛﻨﺪ .اﮔﺮ ﻛﻨﺘﺮل Panelرا از ﻓﺮم ﺣﺬف ﻛﻨﻴﺪ و ﻛﻨﺘﺮﻟﻬﺎي TextBoxرا در ﺧـﻮد ﻓـﺮم ﻗـﺮار دﻫﻴـﺪ ،ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺑﺎ ﻧﻤﺎﻳﺶ ﻧﻮار اﺑﺰار ،Formattingﻛﻨﺘﺮل TextBoxاول روي ﻧﻮار اﺑﺰار Mainﻗﺮار ﺧﻮاﻫـﺪ ﮔﺮﻓﺖ ﻧﻮار اﺑﺰار Mainﻗﺎﺑﻞ ﻣﺸﺎﻫﺪه ﻧﺨﻮاﻫﺪ ﺑﻮد. ﺣﺎل اﮔﺮ ﻣﺠﺪداً ﺑﻪ زﻳﺮ ﻣﻨﻮي Toolbarsدر ﻣﻨﻮي Viewﺑﺮوﻳﺪ ،ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ در ﻛﻨـﺎر ﻫـﺮ دو ﮔﺰﻳﻨـﻪ ﻫﺎي Mainو Formattingﻳﻚ ﻋﻼﻣﺖ ﺗﻴﻚ ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ ﻛﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ در ﺣﺎل ﺣﺎﺿـﺮ ﻫـﺮ دوي اﻳﻦ ﻧﻮار اﺑﺰارﻫﺎ در ﺣﺎل ﻧﻤﺎﻳﺶ اﺳﺖ. ﺣﺎل ﻋﻤﻠﻜﺮد ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻨﻮي Editرا ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ .ﻣﺘﻨﻲ را در ﻛﻨﺘـﺮل TextBoxاول وارد ﻛـﺮده و ﺳـﭙﺲ ﮔﺰﻳﻨﻪ Select Allرا از ﻣﻨﻮي Editاﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛـﻪ ﺗﻤـﺎم ﻣـﺘﻦ ﻧﻮﺷـﺘﻪ ﺷـﺪه در آن اﻧﺘﺨﺎب ﺧﻮاﻫﻨﺪ ﺷﺪ. ﺣﺎل ﻣﻲ ﺧﻮاﻫﻴﻢ ﻣﺘﻦ اﻧﺘﺨﺎب ﺷﺪه در TextBoxاول را در ﻛﻠﻴﭗ ﺑﺮد ﻛﭙﻲ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎ ﻣـﺎوس روي دﻛﻤـﻪ ي Copyدر ﻧﻮار اﺑﺰار ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻳﺎ ﮔﺰﻳﻨﻪ Copyرا از ﻣﻨﻮي Editاﻧﺘﺨﺎب ﻛﻨﻴﺪ. ﻣﻜﺎن ﻧﻤﺎ را در TextBoxدوم ﻗﺮار دﻫﻴﺪ و ﺳﭙﺲ روي دﻛﻤﻪ ي Pasteدر ﻧﻮار اﺑﺰار ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻳﺎ از ﻧﻮار ﻣﻨـﻮ ﮔﺰﻳﻨﻪ Edit Pasteرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﻦ ﻧﻮﺷﺘﻪ ﺷﺪه در TextBoxاول ،ﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ 8-8در TextBoxدوم ﻧﻴﺰ ﻗﺮار ﺧﻮاﻫﺪ ﮔﺮﻓﺖ.
٣١٨
ﺷﻜﻞ 8-8 (6
(7
(8
(9
ﻛﻨﺘﺮل TextBoxاول را اﻧﺘﺨﺎب ﻛـﺮده و ﮔﺰﻳﻨـﻪ Edit Undoرا از ﻧـﻮار ﻣﻨـﻮ اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ ،ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺗﻐﻴﻴﺮاﺗﻲ ﻛﻪ در اﻳﻦ ﻛﻨﺘﺮل اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﺪ ﻟﻐﻮ ﻣﻲ ﺷﻮد .ﻣﻤﻜﻦ اﺳﺖ اﻧﺘﻈﺎر داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛـﻪ ﺑـﺎ اﻧﺘﺨـﺎب اﻳﻦ ﮔﺰﻳﻨﻪ ،آﺧﺮﻳﻦ ﺗﻐﻴﻴﺮ ،ﻳﻌﻨﻲ ﻣﺘﻨﻲ ﻛﻪ در TextBoxدوم وارد ﻛﺮده اﻳﺪ ﭘﺎك ﺷﻮد .اﻣﺎ وﻳﻨﺪوز ﺗﻐﻴﻴﺮات ﻳﻚ ﻛﻨﺘـﺮل را ﺑﺮاي ﻟﻐﻮ آﻧﻬﺎ ﺑﻪ ﻃﻮر ﺟﺪاﮔﺎﻧﻪ ذﺧﻴﺮه ﻣﻲ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﻫﻨﮕﺎﻣﻲ ﻛﻪ TextBoxاول را اﻧﺘﺨﺎب ﻛﺮده اﻳﺪ روي ﮔﺰﻳﻨـﻪ Undoﻛﻠﻴﻚ ﻛﻨﻴﺪ ،ﺗﻐﻴﻴﺮات ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل ﻟﻐﻮ ﻣﻲ ﺷﻮﻧﺪ. آﺧﺮﻳﻦ ﮔﺰﻳﻨﻪ اي ﻛﻪ در ﻣﻨﻮي Editﺑﺎﻳﺪ ﻣﻮرد ﺑﺮرﺳﻲ ﻗﺮار ﺑﮕﻴﺮد ،ﮔﺰﻳﻨﻪ Cutاﺳﺖ .ﻣﺘﻨـﻲ را در TextBoxاول وارد ﻛﺮده و ﺑﺎ اﻧﺘﺨﺎب ﮔﺰﻳﻨﻪ Edit Select Allاز ﻧﻮار ﻣﻨﻮ ،ﺗﻤﺎم آن را اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺳﭙﺲ ﺑﺎ ﻛﻠﻴـﻚ روي دﻛﻤﻪ Cutدر ﻧﻮار اﺑﺰار و ﻳﺎ اﻧﺘﺨﺎب ﮔﺰﻳﻨﻪ Edit Cutاز ﻧﻮار ﻣﻨﻮ ،ﻣﺘﻦ ﻧﻮﺷﺘﻪ ﺷﺪه در اﻳﻦ ﻛﻨﺘـﺮل را از آن ﺣﺬف ﻛﺮده و در ﻛﻠﻴﭗ ﺑﺮد ﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ ﻣﻜﺎن ﻧﻤﺎ را در اﻧﺘﻬﺎي ﻣﺘﻦ ﻣﻮﺟﻮد در TextBoxدوم ﺑﺮده و ﺑﺎ ﻓـﺸﺎر دادن ﺷﻮرت ﻛﺎت ﮔﺰﻳﻨﻪ ،(Ctrl+V) Pasteﻣﺘﻦ داﺧﻞ ﻛﻠﻴﭗ ﺑﺮد را در اﻳﻦ TextBoxﻗﺮار دﻫﻴﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﺑﺎ ﻧﻮﺷﺘﻦ ﻣﻘﺪار ﺑﺴﻴﺎر ﻛﻤﻲ ﻛﺪ،ﮔﺰﻳﻨـﻪ ﻫـﺎي Copy ،Cutو Pasteرا در اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ ﻫﻤﺎﻧﻨﺪ دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي اﻳﺠﺎد ﻛﺮدﻳﻢ. ﺑﻪ ﻣﻨﻮي Fileﺑﺮوﻳﺪ و ﮔﺰﻳﻨﻪ Newرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﻦ داﺧﻞ ﻫﺮ دو TextBoxﭘﺎك ﺧﻮاﻫﺪ ﺷﺪ، ﭘﺲ اﻳﻦ ﮔﺰﻳﻨﻪ ﻧﻴﺰ ﺑﻪ درﺳﺘﻲ ﻛﺎر ﻣﻲ ﻛﻨﺪ .ﺗﻨﻬﺎ ﮔﺰﻳﻨﻪ ﺑﺎﻗﻲ ﻣﺎﻧﺪه ﺑﺮاي ﺑﺮرﺳﻲ ﻛـﺮدن ،ﮔﺰﻳﻨـﻪ Exitاز ﻣﻨـﻮي File اﺳﺖ. ﻗﺒﻞ از ﺧﺮوج از ﺑﺮﻧﺎﻣﻪ ،روي ﻳﻜﻲ از TextBoxﻫﺎ ﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻳﻚ ﻣﻨﻮي ﻓﺮﻋﻲ ﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ 9-8ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ ﻣﻨﻮ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و ﺑﺮاي اﺿـﺎﻓﻪ ﻛـﺮدن آن ﺑـﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺎز ﺑﻪ ﻧﻮﺷﺘﻦ ﻛﺪ و ﻳﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل ﺧﺎﺻﻲ ﻧﻴﺴﺖ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ اﻳﻦ وﻳﮋﮔﻲ ﺗﻮﺳﻂ وﻳﻨﺪوز ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻣﻲ ﺷﻮد .اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺑﺨﺶ ﺑﻌﺪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد در وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005روﺷﻬﺎﻳﻲ ﺑﺮاي ﺣﺬف اﻳﻦ ﻣﻨﻮ و ﻧﻤـﺎﻳﺶ ﻣﻨﻮي ﻣﻮردﻧﻈﺮ ﺧﻮدﺗﺎن در اﻳﻦ ﻗﺴﻤﺖ وﺟﻮد دارد.
٣١٩
ﺷﻜﻞ 9-8 (10ﺑﺮاي ﺑﺮرﺳﻲ ﻋﻤﻠﻜﺮد آﺧﺮﻳﻦ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ ،از ﻧﻮار ﻣﻨﻮ ﮔﺰﻳﻨﻪ File Exitرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ از ﺑﺮﻧﺎﻣﻪ ﺧﺎرج ﺷﻮﻳﺪ.
ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ: ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ 1ﻣﻨﻮ ﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﺎ ﻛﻠﻴﻚ راﺳﺖ ﻛﺎرﺑﺮ روي ﻳﻚ ﻛﻨﺘﺮل و ﻳﺎ روي ﻳﻚ ﻓﺮم ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ .ﺑﻪ وﺳﻴﻠﻪ اﻳـﻦ ﻣﻨﻮ ﻫﺎ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺳﺮﻋﺖ ﺑﻪ ﻛﺎرﻫﺎي ﻋﻤﻮﻣﻲ ﻛﻪ در ﻗﺴﻤﺘﻲ از ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺷﺪت ﺑﻪ آﻧﻬﺎ ﻧﻴﺎز ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ دﺳﺘﺮﺳﻲ داﺷـﺘﻪ ﺑﺎﺷـﺪ. ﺑﺮاي ﻣﺜﺎل ﻣﻨﻮي ﻓﺮﻋﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﻧﻤﺎﻳﺶ داده ﺷﺪ اﻳﻦ اﻣﻜﺎن را ﺑﻪ ﻛﺎرﺑﺮ ﻣﻲ دﻫـﺪ ﻛـﻪ ﺑـﻪ راﺣﺘـﻲ و ﺑـﻪ ﺳﺮﻋﺖ ،ﺑﻪ ﮔﺰﻳﻨﻪ ﻫﺎي ﭘﺮ ﻛﺎرﺑﺮد ﻣﻨﻮي Editﺑﺮاي وﻳﺮاﻳﺶ ﻣﺘﻦ درون ﻳﻚ ،TextBoxدﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ. ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺮ ﺣﺴﺐ ﻛﻨﺘﺮﻟﻲ ﻛﻪ ﻛﺎرﺑﺮ اﻧﺘﺨﺎب ﻛﺮده اﺳﺖ ﺗﻐﻴﻴﺮ ﻛﻨﻨﺪ .ﺑﺮاي ﻣﺜـﺎل ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ در دﻳﮕـﺮ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي وﻳﻨﺪوزي ﻣﺸﺎﻫﺪه ﻛﺮده اﻳﺪ ،اﮔﺮ در ﻓﺮم ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻳﻚ ﻛﻨﺘﺮل TextBoxرا اﻧﺘﺨﺎب ﻛﺮده و روي آن ﻛﻠﻴﻚ راﺳـﺖ ﻛﻨﻴـﺪ ﻣﻨـﻮي ﻓﺮﻋﻲ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﻛﻪ ﺑﺎ ﻣﻨﻮي ﻓﺮﻋﻲ ﻣﺮﺑﻮط ﺑﻪ ﺧﻮد ﻓﺮم ﺗﻔﺎوت دارد. وﻳﻨﺪوز ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض ﻳﻚ ﻣﻨﻮي ﻓﺮﻋﻲ ﺑﺮاي ﻛﻨﺘﺮﻟﻬﺎي TextBoxﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ و ﺗﺎ ﻛﺎرﺑﺮ ﺑﺘﻮاﻧﺪ ﺑﻪ وﺳﻴﻠﻪ آن ﻛﺎرﻫﺎي ﻋﻤﻮﻣﻲ ﻣﺎﻧﻨﺪ Copy ،Cutو ﻳﺎ Pasteرا اﻧﺠﺎم دﻫﺪ .اﻟﺒﺘﻪ در ﺻﻮرت ﻟﺰوم ﻣﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ ﻣﻨﻮ را ﺑﺎ ﻫﺮ ﻣﻨﻮي دﻳﮕﺮي ﺟﺎﻳﮕﺰﻳﻦ ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ در ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﻣﺘﻦ داﺧﻞ TextBoxﻫﺎ را ﻛﭙﻲ ﻛﻨﺪ ،اﻣﺎ ﻧﻤﻲ ﺧﻮاﻫﻴﺪ اﺟﺎزه دﻫﻴـﺪ ﻛـﻪ اﻳﻦ ﻣﺘﻦ ﻛﺎت ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﻨﻮي ﺟﺪﻳﺪي اﻳﺠﺎد ﻛﻨﻴﺪ و از آن ﺑـﻪ ﻋﻨـﻮان ﻣﻨـﻮي ﻓﺮﻋـﻲ در ﻛﻨﺘـﺮل ﻫـﺎي TextBox اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺳﭙﺲ در اﻳﻦ ﻣﻨﻮ ﮔﺰﻳﻨﻪ Cutرا ﻏﻴﺮ ﻓﻌﺎل ﻛﻨﻴﺪ. ﺑﺮاي اﻳﺠﺎد ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻛﻨﺘﺮل ContextMenuStripاﺳـﺘﻔﺎده ﻛﻨﻴـﺪ .ﻋﻤﻠﻜـﺮد اﻳـﻦ ﻛﻨﺘﺮل و ﻧﺤﻮه اﻳﺠﺎد ﻣﻨﻮ در آن ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻛﻨﺘﺮل MenuStripاﺳﺖ .ﺗﻔﺎوت اﻳﻦ ﻛﻨﺘﺮل ﺑـﺎ ﻛﻨﺘـﺮل MenuStripدر آن اﺳﺖ ﻛﻪ در ﻛﻨﺘﺮل ContextMenuStripﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﻣﻨﻮ در ﺑﺎﻻﺗﺮﻳﻦ ﺳﻄﺢ داﺷﺘﻪ ﺑﺎﺷﻴﺪ و دﻳﮕﺮ ﻣﻨﻮ ﻫﺎ ﺑﺎﻳﺪ ﺑـﻪ
1ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ ﻳﺎ .Pop-Up Menusﻧﺎم دﻳﮕﺮ اﻳﻦ ﻣﻨﻮ ﻫﺎ ،ﻣﻨﻮ ﻫﺎي زﻣﻴﻨﻪ ﻳﺎ Context Menusاﺳﺖ.
٣٢٠
ﻋﻨﻮان زﻳﺮ ﻣﺠﻤﻮﻋﻪ آن واﻗﻊ ﺷﻮﻧﺪ ،در ﺻﻮرﺗﻲ ﻛﻪ در ﻛﻨﺘﺮل MenuStripﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺗﻌﺪاد دﻟﺨـﻮاه ﻣﻨـﻮ در ﺑـﺎﻻﺗﺮﻳﻦ ﺳـﻄﺢ داﺷﺘﻪ ﺑﺎﺷﻴﺪ. ﺑﻴﺸﺘﺮ ﻛﻨﺘﺮﻟﻬﺎﻳﻲ ﻛﻪ در ﺟﻌﺒﻪ اﺑﺰار وﺟﻮد دارﻧﺪ داراي ﺧﺎﺻﻴﺘﻲ ﺑﻪ ﻧﺎم ContextMenuStripﻫﺴﺘﻨﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺷﻴﺊ اي را از اﻳﻦ ﻧﻮع ﻗﺒﻮل ﻛﻨﻨﺪ .ﺑﺎ ﺗﻨﻈﻴﻢ اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﺮاي ﻫﺮ ﻳﻚ از ﻛﻨﺘﺮل ﻫﺎ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي آن ﻛﻨﺘﺮل ﻛﻠﻴﻚ راﺳﺖ ﻛﻨﺪ ﻣﻨـﻮي ﻓﺮﻋﻲ ﻛﻪ ﺑﻪ آن ﻧﺴﺒﺖ داده ﺷﺪه اﺳﺖ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد. ﺑﻌﻀﻲ از ﻛﻨﺘﺮل ﻫﺎ ﻫﻤﺎﻧﻨﺪ ComboBoxو ﻳﺎ ListBoxداراي ﻳﻚ ﻣﻨﻮي ﻓﺮﻋﻲ ﭘﻴﺶ ﻓﺮض ﻧﻴﺴﺘﻨﺪ .دﻟﻴﻞ اﻳﻦ ﻣﻮرد ﻫﻢ ﺑـﻪ اﻳﻦ ﻋﻠﺖ اﺳﺖ ﻛﻪ اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﺑﻴﺶ از ﻳﻚ آﻳﺘﻢ را در ﺧﻮد ﻧﮕﻪ داري ﻣﻲ ﻛﻨﻨﺪ و ﻣﺎﻧﻨﺪ ﻛﻨﺘﺮل TextBoxﻓﻘﻂ ﻳﻚ آﻳـﺘﻢ درون آﻧﻬﺎ وﺟﻮد ﻧﺪارد .اﻟﺒﺘﻪ اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﻧﻴﺰ داراي ﺧﺎﺻﻴﺖ ContextMenuStripﻫﺴﺘﻨﺪ ﻛﻪ ﺑﻪ وﺳـﻴﻠﻪ آن ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﻳـﻚ ﻣﻨﻮي ﻓﺮﻋﻲ را در ﺑﺮﻧﺎﻣﻪ ﺑﺮاي آﻧﻬﺎ اﻳﺠﺎد ﻛﻨﻴﺪ.
اﻳﺠﺎد ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ: ﺣﺎل ﻛﻪ ﺑﺎ ﻣﻔﻬﻮم ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ آﺷﻨﺎ ﺷﺪﻳﺪ ،ﺑﻪ ﺑﺮرﺳﻲ آﻧﻬﺎ در ﻛﺪ و ﭼﮕﻮﻧﮕﻲ اﺳﺘﻔﺎده از آن در ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳـﮋوال 2005 C#ﻣـﻲ ﭘﺮدازﻳﻢ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺮﻧﺎﻣـﻪ ي ﻗـﺴﻤﺖ ﻗﺒﻠـﻲ را ﺑـﺎ اﺿـﺎﻓﻪ ﻛـﺮدن ﻳـﻚ ﻣﻨـﻮي ﻓﺮﻋـﻲ ﻣﺨـﺼﻮص ﺑـﺮاي ﻛﻨﺘﺮﻟﻬـﺎي TextBoxﻛﺎﻣﻞ ﻣﻲ ﻛﻨﻴﻢ .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻳﻚ ﻣﻨﻮي ﻓﺮﻋﻲ اﻳﺠـﺎد ﻛـﺮده و ﺑـﺮاي ﻫـﺮ دو ﻛﻨﺘـﺮل TextBoxاز آن اﺳـﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد .اﻟﺒﺘﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ دو ﻣﻨﻮي ﻓﺮﻋﻲ اﻳﺠﺎد ﻛﺮده و در ﻫﺮ ﻳﻚ ﻣﻨﻮ ﻫﺎي ﺟﺪاﮔﺎﻧﻪ ﻗﺮار دﻫﻴﻢ ﻛﻪ ﻛﺎرﻫﺎي ﻣﺘﻔﺎوﺗﻲ را اﻧﺠﺎم دﻫﻨﺪ، ﺳﭙﺲ ﻫﺮ ﻳﻚ از آﻧﻬﺎ را ﺑﻪ ﻳﻜﻲ از TextBoxﻫﺎ ﻧﺴﺒﺖ دﻫﻴﻢ ،وﻟﻲ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺎزي ﺑﻪ اﻳﻦ ﻛﺎر ﻧﻴﺴﺖ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ (1 (2 (3
(4 (5
ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮوﻳﺪ و ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ،ﻳﻚ ﻛﻨﺘﺮل ContextMenuStripدر ﻓﺮم ﻗـﺮار دﻫﻴـﺪ. اﻳﻦ ﻛﻨﺘﺮل ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻛﻨﺘﺮل MenuStripﺑﻪ ﻗﺴﻤﺖ ﭘﺎﻳﻴﻦ ﺑﺨﺶ ﻃﺮاﺣﻲ ﻓﺮم اﺿﺎﻓﻪ ﻣﻲ ﺷﻮد. در ﭘﻨﺠﺮه Propertiesﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل ،روي دﻛﻤﻪ … ﻣﻘﺎﺑﻞ ﺧﺎﺻﻴﺖ Itemsآن ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﭘﻨﺠـﺮه Items Collection Editorﻧﻤﺎﻳﺶ داده ﺷﻮد. در ﭘﻨﺠﺮه Items Collection Editorروي دﻛﻤﻪ ي Addﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗـﺎ ﻳـﻚ ﻣﻨـﻮ ﺑـﻪ ﻟﻴـﺴﺖ اﺿﺎﻓﻪ ﺷﻮد .ﺧﺎﺻﻴﺖ Nameاﻳﻦ ﻣﻨﻮ را ﺑﺮاﺑﺮ ﺑﺎ contextUndoToolStripMenuItemو ﺧﺎﺻﻴﺖ Textآن را ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎ Undoﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ روي دﻛﻤﻪ … در ﻣﻘﺎﺑﻞ ﺧﺎﺻﻴﺖ Imageﻛﻠﻴﻚ ﻛﻨﻴﺪ و از ﭘﻨﺠـﺮه Select Resourceآﻳﻜﻮﻧﻲ را ﺑﺮاي اﻳﻦ ﻣﻨﻮ اﻧﺘﺨﺎب ﻛﻨﻴﺪ. ﺣﺎل ﺑﺎﻳﺪ ﻳﻚ ﺧﻂ ﺟﺪا ﻛﻨﻨﺪه ﺑﻴﻦ ﮔﺰﻳﻨﻪ Undoو دﻳﮕﺮ ﮔﺰﻳﻨﻪ ﻫﺎ ﻗﺮار دﻫﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر از ﻟﻴﺴﺖ ﻛﻨـﺎر دﻛﻤـﻪ ،Add ﮔﺰﻳﻨﻪ Separatorرا اﻧﺘﺨﺎب ﻛﺮده و ﺑﺮ روي دﻛﻤﻪ Addﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻳﻚ ﺟﺪا ﻛﻨﻨﺪه در اﻳﻦ ﻗﺴﻤﺖ واﻗﻊ ﺷﻮد. ﻣﺠﺪداً از ﻟﻴﺴﺖ ﺳﻤﺖ راﺳﺖ دﻛﻤﻪ Addﮔﺰﻳﻨﻪ MenuItemرا اﻧﺘﺨﺎب ﻛـﺮده و ﺳـﭙﺲ روي دﻛﻤـﻪ Addﻛﻠﻴـﻚ ﻛﻨﻴـــﺪ ﺗـــﺎ ﮔﺰﻳﻨـــﻪ دﻳﮕـــﺮي ﺑـــﻪ اﻳـــﻦ ﻣﻨـــﻮ اﺿـــﺎﻓﻪ ﺷـــﻮد .ﺧﺎﺻـــﻴﺖ Nameاﻳـــﻦ ﮔﺰﻳﻨـــﻪ را ﺑﺮاﺑـــﺮ ﺑـــﺎ contextCutToolStripMenuItemو ﺧﺎﺻﻴﺖ Textآن را Cutﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ ﺑﺎ ﺗﻨﻈـﻴﻢ ﺧﺎﺻﻴﺖ Imageآن ﺑﻪ وﺳﻴﻠﻪ ﭘﻨﺠﺮه Select Resourceآﻳﻜﻮﻧﻲ را ﺑﺮاي اﻳﻦ ﻣﻨﻮ اﻧﺘﺨﺎب ﻛﻨﻴﺪ.
٣٢١
(6
(7
(8
(9
(10
(11
(12
(13
در ﭘﻨﺠﺮه Items Collection Editorﮔﺰﻳﻨﻪ دﻳﮕﺮي را ﺑﻪ ﻣﻨﻮ اﺿﺎﻓﻪ ﻛﺮده ،ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑﺎ contextCopyToolStripMenuItemو ﺧﺎﺻـﻴﺖ Textآن را ﺑﺮاﺑـﺮ ﺑـﺎ Copyﻗـﺮار دﻫﻴﺪ .ﺳﭙﺲ آﻳﻜﻮﻧﻲ را ﺑﺮاي ﺧﺎﺻﻴﺖ Imageآن در ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ ﺗﺎ در ﻣﻨﻮ ﻧﻤﺎﻳﺶ داده ﺷﻮد. ﻣﺠﺪداً روي دﻛﻤﻪ Addﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﮔﺰﻳﻨﻪ دﻳﮕﺮي ﺑـﻪ ﻣﻨـﻮ اﺿـﺎﻓﻪ ﺷـﻮد .ﺧﺎﺻـﻴﺖ Nameاﻳـﻦ ﮔﺰﻳﻨـﻪ را ﺑﺮاﺑـﺮ ﺑـﺎ contextPasteToolStripMenuItemو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Pasteﻗﺮار دﻫﻴـﺪ. ﻫﻤﭽﻨﻴﻦ آﻳﻜﻮﻧﻲ را ﺑﺮاي آن در ﻗﺴﻤﺖ Imageﻣﺸﺨﺺ ﻛﻨﻴﺪ. ﺣﺎل ﺑﺎﻳﺪ ﺟﺪا ﻛﻨﻨﺪه دﻳﮕﺮي ﺑﻴﻦ ﮔﺰﻳﻨﻪ ﻫﺎي اﻳﻦ ﻗﺴﻤﺖ و ﻗﺴﻤﺖ ﺑﻌﺪي ﻣﻨﻮ ﻗﺮار دﻫـﻴﻢ .ﺑﻨـﺎﺑﺮاﻳﻦ از ﻟﻴـﺴﺖ ﺳـﻤﺖ راﺳـﺖ دﻛﻤﻪ Addﮔﺰﻳﻨﻪ Separatorرا اﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤﻪ ﻓﺮﻣﺎن Addﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑﻪ ﻟﻴﺴﺖ ﻣﻨﻮ ﻫﺎ اﺿﺎﻓﻪ ﺷﻮد .ﺑﻪ دﻟﻴﻞ اﻳﻨﻜﻪ از اﻳﻦ ﻣﻨﻮ در ﻛﺪ اﺳﺘﻔﺎده ﻧﻤﻲ ﻛﻨﻴﻢ ،ﻧﻴـﺎزي ﻧﻴـﺴﺖ ﻛـﻪ ﺧﺎﺻـﻴﺘﻬﺎي آن را ﺗﻐﻴﻴـﺮ دﻫﻴـﺪ و ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺧﺎﺻﻴﺘﻬﺎي ﭘﻴﺶ ﻓﺮض آن را ﻗﺒﻮل ﻛﻨﻴﺪ. ﻣﺠﺪداً از ﻟﻴﺴﺖ ﺳﻤﺖ راﺳﺖ دﻛﻤﻪ ،Addﮔﺰﻳﻨﻪ MenuItemرا اﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤﻪ Addﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﮔﺰﻳﻨـــﻪ دﻳﮕـــﺮي ﺑـــﻪ ﻟﻴـــﺴﺖ Membersاﺿـــﺎﻓﻪ ﺷـــﻮد .ﺧﺎﺻـــﻴﺖ Nameﮔﺰﻳﻨـــﻪ ﺟﺪﻳـــﺪ را ﺑﺮاﺑـــﺮ ﺑـــﺎ contextSelectAllToolStripMenuItemو ﺧﺎﺻـﻴﺖ Textآن را ﺑـﻪ Select Allﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺑﺮاي اﻳﻦ ﮔﺰﻳﻨﻪ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ آﻳﻜﻮﻧﻲ را ﺗﻌﻴﻴﻦ ﻛﻨﻴـﺪ ،ﺑﻨـﺎﺑﺮاﻳﻦ ﻣـﻲ ﺗﻮاﻧﻴـﺪ در ﭘﻨﺠـﺮه Items Collection Editorروي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑﺴﺘﻪ ﺷﻮد. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﺑﺮﮔﺮدﻳﺪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻣﻨﻮي ﻓﺮﻋﻲ ﻛﻪ اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﺪ در ﺑﺎﻻي ﻓﺮم ﻧﻤـﺎﻳﺶ داده ﻣـﻲ ﺷﻮد ،ﺑﺮاي ﺣﺬف آن در ﻗﺴﻤﺘﻲ از ﻓﺮم ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﺮاي ﻧﻤﺎﻳﺶ ﻣﺠﺪد آن ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﻛﻨﺘـﺮل ﻣﺮﺑـﻮط ﺑـﻪ آن را از ﭘـﺎﻳﻴﻦ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم اﻧﺘﺨﺎب ﻛﻨﻴﺪ. ﻛﻨﺘـــــﺮل TextBoxاول را در ﻓـــــﺮم اﻧﺘﺨـــــﺎب ﻛـــــﺮده و در ﻗـــــﺴﻤﺖ ،Propertiesﺧﺎﺻـــــﻴﺖ ContextMenuStripآن را ﺑﺮاﺑﺮ ﺑﺎ ) contextMenuStrip1ﻳﺎ ﻫﺮ ﻧﺎم دﻳﮕﺮي ﻛﻪ ﺑـﻪ ﻛﻨﺘـﺮل ﻣﺮﺑﻮط ﺑﻪ ﻣﻨﻮي ﻓﺮﻋﻲ ﻧﺴﺒﺖ داده اﻳﺪ( ﻗﺮار دﻫﻴﺪ .اﻳﻦ ﻋﻤﻞ را ﺑﺮاي ﻛﻨﺘﺮل TextBoxدوم ﻧﻴﺰ ﺗﻜﺮار ﻛﻨﻴﺪ. در اﻳﻦ ﻣﺮﺣﻠﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻇﺎﻫﺮ ﻣﻨﻮي ﻓﺮﻋﻲ را ﻛﻪ اﻳﺠﺎد ﻛﺮده اﻳﺪ ﺑﺮرﺳﻲ ﻛﻨﻴﺪ .اﻟﺒﺘﻪ ﺗﺎﻛﻨﻮن ﻫﻴﭻ ﻛﺪي ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل اﺿﺎﻓﻪ ﻧﻜﺮده اﻳﺪ ،ﭘﺲ ﻫﻴﭻ ﻳﻚ از ﻛﻨﺘﺮﻟﻬﺎي آن ﻛﺎر ﻧﻤﻲ ﻛﻨﻨﺪ .ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﻌﺪ از ﻧﻤﺎﻳﺶ داده ﺷـﺪن ﻓـﺮم ،روي ﻛﻨﺘـﺮل TextBoxاول ﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ .اﻳﻦ ﺑﺎر ﺑﻪ ﺟﺎي ﻣﻨﻮي ﻓﺮﻋﻲ ﭘﻴﺶ ﻓﺮض وﻳﻨﺪوز ،ﻣﻨﻮي ﻓﺮﻋـﻲ ﻛـﻪ ﺳـﺎﺧﺘﻪ ﺑﻮدﻳـﺪ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 10-8ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .اﻳﻦ ﻛﺎر را ﺑﺮاي TextBoxدوم ﻧﻴﺰ ﺗﻜﺮار ﻛﻨﻴﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣـﺸﺎﻫﺪه ﻣـﻲ ﻛﻨﻴﺪ ،ﻣﻨﻮي ﻓﺮﻋﻲ ﻳﻜﺴﺎﻧﻲ ﺑﺮاي ﻫﺮ دوي آﻧﻬﺎ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد. از ﺑﺮﻧﺎﻣﻪ ﺧﺎرج ﺷﻮﻳﺪ و ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ .در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻨﻮي ﻓﺮﻋﻲ را وارد ﻛﻨﻴﻢ .از ﭘﺎﻳﻴﻦ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ،ﻛﻨﺘﺮل contextMenuStripرا اﻧﺘﺨﺎب ﮔﺮده ﺗﺎ ﻣﻨﻮي ﻓﺮﻋﻲ ﺑﺮﻧﺎﻣـﻪ در ﺑﺎﻻي ﻓﺮم ﻧﻤﺎﻳﺶ داده ﺷﻮد .در اﻳﻦ ﻣﻨﻮ ،روي ﮔﺰﻳﻨﻪ Undoﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷﻮد، ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: (private void contextUndoToolStripMenuItem_Click )object sender, EventArgs e { // Call the undoToolStripMenuItem_Click procedure ;)undoToolStripMenuItem_Click(sender, e }
٣٢٢
10-8 ﺷﻜﻞ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴـﻚ آنCut ( ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ و در ﻣﻨﻮي ﻓﺮﻋﻲ روي ﮔﺰﻳﻨﻪ14 : ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ.اﻳﺠﺎد ﺷﻮد private void contextCutToolStripMenuItem_Click( object sender, EventArgs e) { // Call the cutToolStripMenuItem_Click procedure cutToolStripMenuItem_Click(sender, e); } ﺳـﭙﺲ. در ﻣﻨﻮي ﻓﺮﻋﻲ ﻧﻴﺰ ﺗﻜﺮار ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷـﻮدCopy ( ﻫﻤﻴﻦ ﻣﺮاﺣﻞ را ﺑﺮاي ﮔﺰﻳﻨﻪ15 :ﻛﺪ زﻳﺮ را در آن وارد ﻛﻨﻴﺪ private void contextCopyToolStripMenuItem_Click( object sender, EventArgs e) { // Call the copyToolStripMenuItem_Click procedure copyToolStripMenuItem_Click(sender, e); } ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن را اﻳﺠﺎد ﻛﺮده و ﻛﺪ زﻳﺮ را در، در ﻣﻨﻮي ﻓﺮﻋﻲ ﺑﺮﻧﺎﻣﻪPaste ( ﺑﺎ دو ﺑﺎر ﻛﻠﻴﻚ روي ﮔﺰﻳﻨﻪ16 :آن وارد ﻛﻨﻴﺪ private void contextPasteToolStripMenuItem_Click( object sender, EventArgs e) { // Call the pasteToolStripMenuItem_Click procedure pasteToolStripMenuItem_Click(sender, e); }
٣٢٣
(17آﺧﺮﻳﻦ ﮔﺰﻳﻨﻪ اي ﻛﻪ ﺑﺎﻳﺪ ﻛﺪ آن را ﺑﻨﻮﻳﺴﻴﺪ ،ﮔﺰﻳﻨﻪ Select Allاﺳﺖ .ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮوﻳـﺪ و روي اﻳـﻦ ﮔﺰﻳﻨﻪ در ﻣﻨﻮي ﻓﺮﻋﻲ ﻧﻤﺎﻳﺶ داده ﺷﺪه در ﺑﺎﻻي ﻓﺮم دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑـﻪ روﻳـﺪاد ﻛﻠﻴـﻚ آن اﻳﺠـﺎد ﺷـﻮد. ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: (private void contextSelectAllToolStripMenuItem_Click )object sender, EventArgs e { // Call the selectAllToolStripMenuItem_Click procedure ;)selectAllToolStripMenuItem_Click(sender, e } (18ﺗﻤﺎم ﻛﺪي ﻛﻪ ﺑﺎﻳﺪ ﺑﺮاي ﻣﻨﻮي ﻓﺮﻋﻲ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﻧﻮﺷﺘﻴﺪ ،ﻫﻤﻴﻦ ﺑﻮد .ﺳﺎده ﺑﻮد ،ﻧﻪ؟ ﺣﺎﻻ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑﺮﻧﺎﻣـﻪ را اﺟـﺮا ﻛﻨﻴـﺪ و ﻋﻤﻠﻜﺮد ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﺨﺘﻠﻒ ﻣﻨﻮي ﻓﺮﻋﻲ ﺑﺮﻧﺎﻣﻪ را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ .اﻳﻦ ﮔﺰﻳﻨﻪ ﻫﺎ ﻧﻴﺰ ﻋﻤﻠﻜﺮدي ﻣﺸﺎﺑﻪ دﻛﻤﻪ ﻫﺎي ﻣﻮﺟـﻮد در ﻧﻮار اﺑﺰار و ﻳﺎ ﮔﺰﻳﻨﻪ ﻫﺎي ﻧﻮار ﻣﻨﻮ دارﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻔﺎوﺗﻲ ﻧﺪارد ﻛﻪ ﺑﺮاي ﻳﻚ ﻛﺎر ﺧﺎص از ﻧﻮار اﺑﺰار ،ﻧﻮار ﻣﻨﻮ و ﻳﺎ ﻣﻨﻮي ﻓﺮﻋﻲ اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در اﻳﻦ ﺗﻤﺮﻳﻦ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﻛﻨﺘﺮل ContextMenuStripﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻛﻨﺘﺮل MenuStripﻛﺎر ﻣﻲ ﻛﻨﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺗﻤﺎم وﻳﮋﮔﻲ ﻫﺎﻳﻲ ﻛﻪ در ﻛﻨﺘﺮل MenuStripوﺟﻮد دارﻧـﺪ در ﻛﻨﺘـﺮل ContextMenuStrip ﻧﻴﺰ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺳﺎدﮔﻲ ﺑﻪ ﻃﺮاﺣﻲ ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ ﺑﭙﺮدازﻳﺪ .ﺑﻪ ﻧﺎم ﮔﺬاري ﻣﻨﻮ ﻫﺎي ﻓﺮﻋـﻲ ﻧﻴﺰ ﺗﻮﺟﻪ ﻛﻨﻴﺪ .در اﺑﺘﺪاي ﻧﺎم ﺗﻤﺎم آﻧﻬﺎ از contextاﺳﺘﻔﺎده ﺷﺪه اﺳﺖ ﺗﺎ ﺑﻴﻦ ﮔﺰﻳﻨﻪ ﻫﺎي اﻳﻦ ﻣﻨﻮ و ﮔﺰﻳﻨـﻪ ﻫـﺎي ﻣﻨـﻮي اﺻـﻠﻲ ﺑﺮﻧﺎﻣﻪ ﺗﻔﺎوت اﻳﺠﺎد ﺷﻮد و ﺗﺸﺨﻴﺺ آﻧﻬﺎ از ﻫﻢ ﺳﺎده ﺗﺮ ﺑﺎﺷﺪ. ﻛﺪﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي ﮔﺰﻳﻨﻪ ﻫﺎي اﻳﻦ ﻣﻨﻮ ﻧﻮﺷﺘﻴﺪ ﻧﻴﺰ ﻧﻜﺘﻪ ﺗﺎزه اي ﻧﺪاﺷﺖ .ﻣﺘﺪ ﻣﺮﺑﻮط ﺑـﻪ ﻛﺎرﻫـﺎﻳﻲ ﻣﺎﻧﻨـﺪ ،Paste ،Copy ،Cut Select Allو ﻏﻴﺮه را در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ ﻧﻮﺷﺘﻪ ﺑﻮدﻳﺪ و در اﻳﻦ ﻗﺴﻤﺖ ﻓﻘﻂ آﻧﻬﺎ را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮدﻳﺪ.
ﻓﻌﺎل و ﻏﻴﺮ ﻓﻌﺎل ﻛﺮدن ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻨﻮ و دﻛﻤﻪ ﻫﺎي ﻧﻮار اﺑﺰار: ﻫﻤﻮاره ﺷﺮاﻳﻄﻲ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ وﺟﻮد ﻣﻲ آﻳﺪ ﻛﻪ ﻛﺎرﺑﺮ ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻌﻀﻲ از ﻛﺎرﻫﺎي ﺧﺎص را اﻧﺠﺎم دﻫـﺪ .ﺑـﺮاي ﻣﺜـﺎل ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻣﺘﻨﻲ درون ﻛﻠﻴﭗ ﺑﺮد ﻗﺮار ﻧﮕﺮﻓﺘﻪ اﺳﺖ ﻛﺎرﺑﺮ ﻧﻤﻲ ﺗﻮاﻧﺪ آن را در TextBoxﻗﺮار دﻫﺪ و ﻳﺎ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻣﺘﻨـﻲ در ﺑﺮﻧﺎﻣـﻪ اﻧﺘﺨـﺎب ﻧﺸﺪه اﺳﺖ ﻛﺎرﺑﺮ ﻧﻤﻲ ﺗﻮاﻧﺪ آن را درون ﻛﻠﻴﭗ ﺑﺮد ﻗﺮار دﻫﺪ .در ﭼﻨﻴﻦ ﺷﺮاﻳﻄﻲ ﺑﻬﺘﺮ اﺳﺖ ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ اﻣﻮر در ﻧﻮار ﻣﻨـﻮ و ﻳﺎ ﻧﻮار اﺑﺰار ﻏﻴﺮ ﻓﻌﺎل ﺑﺎﺷﻨﺪ .ﻧﺤﻮه ﻓﻌﺎل ﻛﺮدن و ﻳﺎ ﻏﻴﺮ ﻓﻌﺎل ﻛﺮدن دﻛﻤﻪ ﻫﺎي ﻧﻮار اﺑﺰار و ﻳﺎ ﮔﺰﻳﻨﻪ ﻫﺎي ﻧﻮار ﻣﻨﻮ را در ﺑﺨـﺶ اﻣﺘﺤـﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻓﻌﺎل و ﻏﻴﺮ ﻓﻌﺎل ﻛﺮدن ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻨﻮ و دﻛﻤﻪ ﻫﺎي ﻧﻮار اﺑﺰار
٣٢٤
دﻛﻤﻪ ﻫﺎي ﻧﻮار اﺑﺰار و ﻳﺎ ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻨـﻮي،( اﺑﺘﺪا زﻳﺮﺑﺮﻧﺎﻣﻪ اي ﻣﻲ ﻧﻮﻳﺴﻴﻢ ﻛﻪ ﺑﺎ ﺑﺮرﺳﻲ ﺷﺮاﻳﻂ ﺑﺮﻧﺎﻣﻪ ﮔﺰﻳﻨﻪ ﻫﺎي ﻧﻮار ﻣﻨﻮ1 ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﺑﺮﻧﺎﻣﻪ در ﺣﺎل اﺟﺮا اﺳﺖ آن را ﻣﺘﻮﻗﻒ ﻛﺮده و ﻛﺪ زﻳﺮ را ﺑﻪ ﻛﻼس ﺣﺎوي ﻓﺮم.ﻓﺮﻋﻲ را ﻓﻌﺎل و ﻳﺎ ﻏﻴﺮ ﻓﻌﺎل ﻛﻨﺪ :ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ private void ToggleMenus() { // Declare a TextBox object and // set it to the ActiveControl TextBox objTextBox = (TextBox)this.ActiveControl; // Toggle the Undo menu items undoToolStripMenuItem.Enabled = objTextBox.CanUndo; contextUndoToolStripMenuItem.Enabled = objTextBox.CanUndo; // Toggle the Cut toolbar button and menu items if (objTextBox.SelectionLength == 0) { cutToolStripMenuItem.Enabled = false; contextCutToolStripMenuItem.Enabled = false; cutToolStripButton.Enabled = false; } else { cutToolStripMenuItem.Enabled = true; contextCutToolStripMenuItem.Enabled = true; cutToolStripButton.Enabled = true; } // Toggle the Copy toolbar button and menu items copyToolStripMenuItem.Enabled = Convert.ToBoolean(objTextBox.SelectionLength); contextCopyToolStripMenuItem.Enabled = Convert.ToBoolean(objTextBox.SelectionLength); copyToolStripButton.Enabled = Convert.ToBoolean(objTextBox.SelectionLength); // Toggle the Paste toolbar button and menu items pasteToolStripMenuItem.Enabled = Clipboard.ContainsText(); contextPasteToolStripMenuItem.Enabled = Clipboard.ContainsText(); pasteToolStripButton.Enabled = Clipboard.ContainsText(); // Toggle the Select All menu items
٣٢٥
= selectAllToolStripMenuItem.Enabled ;)(objTextBox.SelectionLength < objTextBox.Text.Length = contextSelectAllToolStripMenuItem.Enabled ;)(objTextBox.SelectionLength < objTextBox.Text.Length } (2در ﻓﺮم اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻓﻘﻂ دو TextBoxروي ﻓﺮم در ﻓﻌﺎل ﺑﻮدن و ﻳﺎ ﻧﺒﻮدن دﻛﻤﻪ ﻫﺎي ﻧﻮار اﺑﺰار و ﻳﺎ ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻨﻮ ﻫﺎ ﺗﺎﺛﻴﺮ دارﻧﺪ .ﭘﺲ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ ﻣﺎوس ﺧﻮد را روي ﻳﻜﻲ از اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﺑـﺮد ،ﺗـﺎﺑﻊ ToggleMenus را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ ﺗﺎ ﻣﺸﺨﺺ ﺷﻮد ﻛﺪام ﻛﻨﺘﺮل ﻫﺎ ﺑﺎﻳﺪ ﻓﻌﺎل ﺑﺎﺷﻨﺪ و ﻛﺪاﻣﻴﻚ ﻧﺒﺎﻳﺪ ﻓﻌﺎل ﺑﺎﺷﻨﺪ .ﺑﺮاي اﻳـﻦ ﻛـﺎر ﺑـﻪ ﻗـﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮوﻳﺪ و ﻛﻨﺘـﺮل TextBoxاول را اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ .ﺳـﭙﺲ در ﭘﻨﺠـﺮه Propertiesروي آﻳﻜـﻮن Eventsﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻟﻴﺴﺖ روﻳﺪادﻫﺎي اﻳﻦ ﻛﻨﺘﺮل ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ .از اﻳـﻦ ﻟﻴـﺴﺖ ﮔﺰﻳﻨـﻪ MouseMoveرا اﻧﺘﺨﺎب ﻛﺮده و روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: private void textBox1_MouseMove(object sender, )MouseEventArgs e { // Toggle the menu items and toolbar buttons ;)(ToggleMenus } (3ﻣﺮاﺣﻞ ﻗﺒﻠﻲ را ﺑﺮاي ﻛﻨﺘﺮل TextBoxدوم ﻧﻴﺰ اﺟﺮا ﻛﻨﻴﺪ و ﻛﺪ زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد MouseMoveآن وارد ﻛﻨﻴﺪ: private void textBox2_MouseMove(object sender, )MouseEventArgs e { // Toggle the menu items and toolbar buttons ;)(ToggleMenus } (4ﺣﺎل ﻣﺠﺪداً ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﻣﺘﻨﻲ را درون TextBoxاول وارد ﻛﻨﻴﺪ .ﺳﭙﺲ روي آن ﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ ﺗﺎ ﻣﻨـﻮي ﻓﺮﻋﻲ آن ﻧﻤﺎﻳﺶ داده ﺷﻮد .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻓﻘﻂ ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻨﺎﺳﺐ ﻗﺎﺑﻞ اﻧﺘﺨﺎب ﻫﺴﺘﻨﺪ و دﻳﮕﺮ ﮔﺰﻳﻨﻪ ﻫﺎ ﻏﻴﺮ ﻓﻌـﺎل ﺷﺪه اﻧﺪ )ﺷﻜﻞ .(11-8
٣٢٦
ﺷﻜﻞ 11-8
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اوﻟﻴﻦ ﻛﺎري ﻛﻪ در زﻳﺮﺑﺮﻧﺎﻣﻪ ToggleMenusاﻧﺠﺎم دﻫﻴﻢ ،اﻳﻦ اﺳﺖ ﻛﻪ ﻛﻨﺘﺮل ﻓﻌﺎل را در ﻓﺮم ﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻣـﻮرد ﻣﻲ ﺗﻮاﻧﻴﻢ روﺷﻲ را ﻛﻪ در ﺑﺨﺸﻬﺎي ﻗﺒﻠﻲ اﺳﺘﻔﺎده ﻛﺮدﻳﻢ ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﻢ. // Declare a TextBox object and // set it to the ActiveControl ;TextBox objTextBox = (TextBox)this.ActiveControl اوﻟﻴﻦ ﮔﺰﻳﻨﻪ ي ﻣﻨﻮي ،Editﮔﺰﻳﻨﻪ Undoاﺳﺖ ،ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ اﻳﻦ ﮔﺰﻳﻨﻪ ﺷﺮوع ﻣﻲ ﻛﻨﻴﻢ .ﻛﻼس TextBoxداراي ﺧﺎﺻـﻴﺘﻲ ﺑﻪ ﻧﺎم CanUndoاﺳﺖ ﻛﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳﺎ ﻣﻲ ﺗﻮان آﺧﺮﻳﻦ ﻋﻤﻞ اﻧﺠﺎم ﺷﺪه در آن TextBoxرا ﻟﻐﻮ ﻛﺮد ﻳﺎ ﻧﻪ؟ ﻣﻘـﺪار ﺑﺮﮔﺸﺘﻲ اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﺮاﺑﺮ ﺑﺎ Trueو ﻳﺎ Falseﺧﻮاﻫﺪ ﺑﻮد ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ آن را ﺑﻪ ﻃـﻮر ﻣـﺴﺘﻘﻴﻢ در ﺧﺎﺻـﻴﺖ Enabled ﮔﺰﻳﻨﻪ Undoﻗﺮار دﻫﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﮔﺮ آﺧﺮﻳﻦ ﻋﻤﻞ اﻧﺠﺎم ﺷﺪه در TextBoxﻗﺎﺑﻞ ﺑﺮﮔﺸﺖ ﺑﺎﺷﺪ ،ﺧﺎﺻﻴﺖ Enabled آن ﺑﺮاﺑﺮ ﺑﺎ Trueﺧﻮاﻫﺪ ﺷﺪ و در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﺑﺮاﺑﺮ ﺑﺎ Falseﺧﻮاﻫﺪ ﺑﻮد. // Toggle the Undo menu items ;undoToolStripMenuItem.Enabled = objTextBox.CanUndo = contextUndoToolStripMenuItem.Enabled ;objTextBox.CanUndo ﮔﺰﻳﻨﻪ ﺑﻌﺪي در ﻣﻨﻮي ،Editﮔﺰﻳﻨﻪ Cutاﺳﺖ .ﺑـﺮاي ﺗﻌﻴـﻴﻦ ﻓﻌـﺎل ﻳـﺎ ﻏﻴـﺮ ﻓﻌـﺎل ﺑـﻮدن اﻳـﻦ ﮔﺰﻳﻨـﻪ ﻣـﻲ ﺗـﻮاﻧﻴﻢ از ﺧﺎﺻـﻴﺖ SelectionLengthﻛﻼس TextBoxاﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻳﻦ ﺧﺎﺻﻴﺖ ﻣﻘﺪاري از ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ ﻛﻪ ﻣـﺸﺨﺺ ﻛﻨﻨـﺪه ﺗﻌﺪاد ﻛﺎراﻛﺘﺮ ﻫﺎي اﻧﺘﺨﺎب ﺷﺪه در TextBoxاﺳﺖ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .اﮔـﺮ ﻣﻘـﺪار اﻳـﻦ ﺧﺎﺻـﻴﺖ ﺑﺮاﺑـﺮ ﺑـﺎ 0ﺑـﻮد ﻳﻌﻨـﻲ ﻣﺘﻨـﻲ در TextBoxاﻧﺘﺨﺎب ﻧﺸﺪه اﺳﺖ ،ﭘﺲ ﻧﻤﻲ ﺗﻮان آن را Cutﻛﺮد .در اﻳﻦ ﺣﺎﻟﺖ ﺑﺎﻳﺪ ﮔﺰﻳﻨﻪ Cutرا در ﻧﻮار ﻣﻨﻮ ،ﻧﻮار اﺑﺰار و ﻣﻨﻮي ﻓﺮﻋﻲ ﻏﻴﺮ ﻓﻌﺎل ﻛﻨﻴﻢ:
٣٢٧
// Toggle the Cut toolbar button and menu items )if (objTextBox.SelectionLength == 0 { ;cutToolStripMenuItem.Enabled = false ;contextCutToolStripMenuItem.Enabled = false ;cutToolStripButton.Enabled = false } else { ;cutToolStripMenuItem.Enabled = true ;contextCutToolStripMenuItem.Enabled = true ;cutToolStripButton.Enabled = true } ﺑﻌﺪ از اﻳﻦ ﮔﺰﻳﻨﻪ ،ﮔﺰﻳﻨﻪ Copyرا از ﻣﻨﻮي Editﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ .اﻳﻦ ﮔﺰﻳﻨﻪ ﻧﻴﺰ ﻣﺎﻧﻨﺪ ،Cutﻫﻨﮕﺎﻣﻲ ﻗﺎﺑﻞ اﻧﺘﺨﺎب اﺳـﺖ ﻛـﻪ ﻣﺘﻨﻲ در TextBoxاﻧﺘﺨﺎب ﺷﺪه ﺑﺎﺷﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي ﺗﻌﻴﻴﻦ ﻓﻌﺎل ﻳﺎ ﻏﻴﺮ ﻓﻌﺎل ﺑﻮدن آن ﻣﻲ ﺗﻮاﻧﻴﻢ ﻫﻤﺎﻧﻨﺪ ﮔﺰﻳﻨﻪ Cutار ﺑﺮرﺳﻲ ﺧﺎﺻﻴﺖ SelectionLengthاﺳﺘﻔﺎده ﻛﻨﻴﻢ .روش دﻳﮕﺮي ﻛﻪ ﻣﻲ ﺗﻮان در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﻛﺎر ﺑﺮد ،ﺗﺒﺪﻳﻞ ﻣﻘﺪار ﻣﻮﺟﻮد در ﺧﺎﺻﻴﺖ SelectionLengthﺑﻪ ﻧﻮع Booleanاﺳﺖ .ﺑﺮاي ﺗﺒﺪﻳﻞ ﻳﻚ ﻧﻮع داده اي ﺑﻪ ﻧﻮع داده اي دﻳﮕﺮ ﻣﻲ ﺗﻮاﻧﻴﻢ از ﺗﻮاﺑﻊ ﻣﻮﺟﻮد در ﻛﻼس Convertاﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﻳﻜﻲ از اﻳﻦ ﺗﻮاﺑﻊ ﺑﺮاي ﺗﺒﺪﻳﻞ ﻳﻚ ﻣﻘﺪار intﺑـﻪ Booleanﺑـﻪ ﻛـﺎر ﻣﻲ رود .اﮔﺮ ﻋﺪد ﺻﺤﻴﺤﻲ ﻛﻪ ﺑﻪ اﻳﻦ ﺗﺎﺑﻊ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد ﺗﺎ ﺗﺒﺪﻳﻞ ﺷﻮد ،ﺑﺮاﺑﺮ ﺑـﺎ ﺻـﻔﺮ ﺑﺎﺷـﺪ ﻣﻘـﺪار ﺑﺮﮔـﺸﺘﻲ اﻳـﻦ ﺗـﺎﺑﻊ ﺑﺮاﺑـﺮ ﺑـﺎ Falseﺧﻮاﻫﺪ ﺑﻮد در ﻏﻴﺮ اﻳﻦ ﺻﻮرت اﻳـﻦ ﺗـﺎﺑﻊ ﻣﻘـﺪار Trueرا ﺑﺮﻣـﻲ ﮔﺮداﻧـﺪ .ﺑﻨـﺎﺑﺮاﻳﻦ در اﻳﻨﺠـﺎ ﻧﻴـﺰ اﮔـﺮ ﻣﻘـﺪار ﺧﺎﺻـﻴﺖ SelectionLengthﺑﺮاﺑﺮ ﺑﺎ ﺻﻔﺮ ﺑﺎﺷﺪ ،ﺗﺎﺑﻊ ﻣﻘﺪار Falseرا ﺑﺮﮔﺮداﻧﺪه و ﺑﺎﻋﺚ ﻏﻴﺮﻓﻌﺎل ﺷـﺪن ﮔﺰﻳﻨـﻪ Copyﻣـﻲ ﺷﻮد .در ﺻﻮرﺗﻲ ﻛﻪ ﻛﺎرﺑﺮ ﻣﺘﻨﻲ را در TextBoxاﻧﺘﺨﺎب ﻛﺮده ﺑﺎﺷﺪ ،ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﺮاﺑﺮ ﺑﺎ ﻋﺪدي ﺑﻪ ﺟﺰ ﺻﻔﺮ ﺧﻮاﻫﺪ ﺑـﻮد .در ﻧﺘﻴﺠﻪ ﺗﺎﺑﻊ ﻣﻘﺪار Trueرا ﺑﺮﻣﻲ ﮔﺮداﻧﺪ و ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﮔﺰﻳﻨﻪ Copyﻓﻌﺎل ﺷﻮد. ﻧﻜﺘﻪ :ﺗﺎﺑﻊ ToBooleanاز ﻛﻼس ،Convertﻓﻘﻂ ﺑﺎزاي ﻋﺪد ﺻﺤﻴﺢ ﺻﻔﺮ ﻣﻘﺪار Falseﺑﺮﻣﻲ ﮔﺮداﻧﺪ .ﻫﺮ ﭘـﺎراﻣﺘﺮي ﺑﻪ ﺟﺰ ﺻﻔﺮ ،ﭼﻪ ﻣﻘﺪار ﻣﺜﺒﺖ ﺑﺎﺷﺪ و ﭼﻪ ﻣﻨﻔﻲ ،ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ اﻳﻦ ﺗﺎﺑﻊ ﻣﻘﺪار Trueرا ﺑﺮﮔﺮداﻧﺪ. ﻧﻜﺘﻪ :از ﻟﺤﺎظ ﺳﺮﻋﺖ ،اﻳﻦ روش ﺑﺎ روﺷﻲ ﻛﻪ در ﻣﻮرد ﮔﺰﻳﻨﻪ Cutاﺳﺘﻔﺎده ﻛﺮدﻳﻢ ﺗﻔﺎوت زﻳﺎدي ﻧـﺪارد و ﺗﻨﻬـﺎ ﻣﺰﻳـﺖ روش دوم در ﻛﻮﺗﺎه ﺗﺮ ﺑﻮدن آن اﺳﺖ .اﻟﺒﺘﻪ در روش دوم ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﺑﺮاي اﻓﺰاﻳﺶ ﺳﺮﻋﺖ اﺟـﺮاي ﻛـﺪ ،اﺑﺘـﺪا ﻣﺘﻐﻴـﺮي را از ﻧـﻮع Boolean ﺗﻌﺮﻳﻒ ﻛﺮده و ﻣﻘﺪار ﺑﺮﮔﺸﺘﻲ از ﺗﺎﺑﻊ Convert.ToBooleanرا در آن ﻗﺮار دﻫﻴﻢ .ﺳﭙﺲ ﻣﻘـﺪار اﻳـﻦ ﻣﺘﻐﻴﻴـﺮ را ﺑـﻪ ﺳـﻪ ﺧﺎﺻﻴﺖ ﻣﻮرد ﻧﻈﺮ ﻧﺴﺒﺖ دﻫﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻓﻘﻂ ﻳﻚ ﺑﺎر ﺗﺎﺑﻊ Convert.ToBooleanرا ﻓﺮاﺧﻮاﻧﻲ ﺧـﻮاﻫﻴﻢ ﻛـﺮد و از ﻓﺮاﺧﻮاﻧﻲ ﺑﻲ ﻣﻮرد اﻳﻦ ﺗﺎﺑﻊ ﻧﻴﺰ ﺟﻠﻮﮔﻴﺮي ﻣﻲ ﺷﻮد. // Toggle the Copy toolbar button and menu items = copyToolStripMenuItem.Enabled ;)Convert.ToBoolean(objTextBox.SelectionLength = contextCopyToolStripMenuItem.Enabled ;)Convert.ToBoolean(objTextBox.SelectionLength
٣٢٨
= copyToolStripButton.Enabled ;)Convert.ToBoolean(objTextBox.SelectionLength ﮔﺰﻳﻨﻪ ﺑﻌﺪي در ﻣﻨﻮي ،Editﮔﺰﻳﻨﻪ Pasteاﺳﺖ .روش ﺗﻌﻴﻴﻦ ﻓﻌﺎل و ﻳﺎ ﻏﻴﺮ ﻓﻌﺎل ﺑﻮدن اﻳﻦ ﮔﺰﻳﻨﻪ ﺑﺎ ﮔﺰﻳﻨﻪ ﻫﺎي دﻳﮕﺮ ﻣﻘﺪاري ﻣﺘﻔﺎوت اﺳﺖ .در اﻳﻦ ﻣﻮرد ﺑﺎﻳﺪ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ﻛﻪ آﻳﺎ ﻣﺘﻨﻲ در داﺧﻞ ﻛﻠﻴﭗ ﺑﻮرد ﻗﺮار دارد ﻳﺎ ﻧﻪ؟ ﺑﺮاي ﺗﺸﺨﻴﺺ اﻳﻦ ﻣﻮرد ﻧﻴﺰ ﻣﻲ ﺗـﻮاﻧﻴﻢ از ﻣﺘﺪ ContainsTextدر ﻛﻼس Clipboardاﺳـﺘﻔﺎده ﻛﻨـﻴﻢ .ﻛـﻼس Clipboardﺟﺰﺋـﻲ از ﻓـﻀﺎي ﻧـﺎم System.Windows.Formsاﺳﺖ ﻛﻪ ﺑﻪ ﻃﻮر اﺗﻮﻣﺎﺗﻴﻚ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻣﻲ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑـﺪون ﻣـﺸﺨﺺ ﻛﺮدن ﻓﻀﺎي ﻧﺎم آن ،از اﻳﻦ ﻛﻼس اﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺗﺎﺑﻊ ContainsTextﻣﻘﺪاري را از ﻧﻮع Booleanﺑﺮﻣﻲ ﮔﺮداﻧـﺪ ﻛـﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳﺎ ﻣﺘﻨﻲ در ﻛﻠﻴﭗ ﺑﻮرد ﻗﺮار دارد ﻳﺎ ﻧﻪ؟در ﺻﻮرت وﺟﻮد ﻣﺘﻦ در ﻛﻠﻴﭗ ﺑﻮرد اﻳﻦ ﺗﺎﺑﻊ ﻣﻘﺪار Trueرا ﺑﺮﻣﻲ ﮔﺮداﻧـﺪ، ﻛﻪ ﺑﺎ ﻧﺴﺒﺖ دادن آن ﺑﻪ ﺧﺎﺻﻴﺖ Enabledاز ﮔﺰﻳﻨﻪ Pasteﺑﺎﻋﺚ ﻓﻌﺎل ﺷﺪن اﻳﻦ ﮔﺰﻳﻨﻪ ﻣﻲ ﺷﻮﻳﻢ .در ﺻـﻮرﺗﻲ ﻛـﻪ ﻣﺘﻨـﻲ وﺟﻮد ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ ﻫﻢ اﻳﻦ ﺗﺎﺑﻊ ﺑﺎ ﺑﺮﮔﺮداﻧﺪن ﻣﻘﺪار Falseﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﮔﺰﻳﻨﻪ Pasteﻏﻴﺮ ﻓﻌﺎل ﺷﻮد. // Toggle the Paste toolbar button and menu items = pasteToolStripMenuItem.Enabled ;)(Clipboard.ContainsText = contextPasteToolStripMenuItem.Enabled ;)(Clipboard.ContainsText = pasteToolStripButton.Enabled ;)(Clipboard.ContainsText ﮔﺰﻳﻨﻪ آﺧﺮي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ ﻣﻮرد ﺑﺮرﺳﻲ ﻗﺮار ﮔﻴﺮد ،ﮔﺰﻳﻨﻪ Select Allاﺳﺖ .اﻳﻦ ﮔﺰﻳﻨﻪ ﺑﺎﻳﺪ ﻫﻨﮕﺎﻣﻲ ﻓﻌﺎل ﺑﺎﺷﺪ ﻛﻪ ﺗﻤﺎم ﻣﺘﻦ داﺧﻞ ﻳﻚ TextBoxاﻧﺘﺨﺎب ﻧﺸﺪه ﺑﺎﺷﺪ .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﺑﺎﻳﺪ اﻳﻦ ﮔﺰﻳﻨﻪ ﻏﻴﺮ ﻓﻌﺎل ﺑﺎﺷﺪ .ﺑﺮاي ﺑﺮرﺳﻲ اﻳﻨﻜـﻪ ﺗﻤـﺎم ﻣﺘﻦ داﺧﻞ ﻳﻚ TextBoxاﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ﻳﺎ ﻧﻪ ﻣﻘﺪار ﻣﻮﺟﻮد در ﺧﺎﺻﻴﺖ SelectionLengthرا ﺑـﺎ ﻃـﻮل ﻣـﺘﻦ ﻣﻘﺎﻳﺴﻪ ﻣﻲ ﻛﻨﻴﻢ .اﮔﺮ ﻃﻮل ﻣﺘﻦ ﺑﺰرﮔﺘﺮ از ﻣﻘﺪار اﻧﺘﺨﺎب ﺷﺪه از ﻣﺘﻦ ﺑﻮد ،ﻳﻌﻨﻲ ﺑﺨﺸﻲ از ﻣﺘﻦ اﻧﺘﺨﺎب ﺷﺪه اﺳـﺖ .در اﻳـﻦ ﺣﺎﻟـﺖ ﻣـﻲ ﺗﻮاﻧﻴﻢ ﮔﺰﻳﻨﻪ Select Allرا ﻓﻌﺎل ﻛﻨﻴﻢ. // Toggle the Select All menu items = selectAllToolStripMenuItem.Enabled ;)(objTextBox.SelectionLength < objTextBox.Text.Length = contextSelectAllToolStripMenuItem.Enabled ;)(objTextBox.SelectionLength < objTextBox.Text.Length ﺑﺮاي ﻓﻌﺎل و ﻳﺎ ﻏﻴﺮ ﻓﻌﺎل ﻛﺮدن ﮔﺰﻳﻨﻪ ﻫﺎي ﻧﻮار ﻣﻨﻮ و ﻳﺎ ﻧﻮار اﺑﺰار ،ﺑﺎﻳﺪ اﻳﻦ زﻳﺮﺑﺮﻧﺎﻣﻪ را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ .ﺑﻬﺘﺮﻳﻦ ﻣﻜﺎن ﺑـﺮاي ﻓﺮاﺧـﻮاﻧﻲ اﻳﻦ ﺗﺎﺑﻊ ،درون روﻳﺪاد MouseMoveﻛﻨﺘﺮل TextBoxاﺳﺖ .اﻳﻦ روﻳﺪاد ﻫﻨﮕﺎﻣﻲ رخ ﻣﻲ دﻫﺪ ﻛـﻪ ﻣـﺎوس از روي ﻛﻨﺘـﺮل ﻋﺒﻮر ﻛﻨﺪ ،ﻛﻪ در اﻳﻦ ﺣﺎﻟﺖ ﻣﻲ ﺗﻮان ﺣﺪس زد ﻣﻤﻜﻦ اﺳﺖ ﻛﺎرﺑﺮ ﺑﺨﻮاﻫﺪ روي TextBoxﻛﻠﻴﻚ )و ﻳـﺎ ﻛﻠﻴـﻚ راﺳـﺖ( ﻛـﺮده و ﮔﺰﻳﻨﻪ اي را اﻧﺘﺨﺎب ﻛﻨﺪ. private void textBox1_MouseMove(object sender, )MouseEventArgs e { // Toggle the menu items and toolbar buttons
٣٢٩
;)(ToggleMenus }
ﻧﺘﻴﺠﻪ: در اﻳﻦ ﻓﺼﻞ در ﻃﻲ ﭼﻨﺪﻳﻦ ﺗﻤﺮﻳﻦ ﻛﺎرﺑﺮدي و ﺑﺎ اﺳﺘﻔﺎده از ﭼﻨﺪ ﻣﺜﺎل ﺑﺎ ﻧﺤﻮه اﺳﺘﻔﺎده از ﻣﻨﻮ ﻫﺎ ،زﻳﺮﻣﻨﻮ ﻫﺎ و ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد در آن آﺷﻨﺎ ﺷﺪﻳﻢ .ﻫﻤﭽﻨﻴﻦ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان از ﭼﻨﺪ ﻧﻮار اﺑﺰار در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﺮد ،ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ اﻳﻦ ﻣـﻮرد ﻣـﺪﻧﻈﺮ اﻳـﻦ ﻓﺼﻞ ﻧﺒﻮده اﺳﺖ .ﻋﻼوه ﺑﺮ اﻳﻦ آﻣﻮﺧﺘﻴﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﺑﺮاي ﻣﻨﻮ ﻫﺎ ﻛﻠﻴﺪﻫﺎي دﺳﺘﺮﺳﻲ ،ﺷﻮرت ﻛﺎت و ﻳﺎ آﻳﻜﻮن ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ. در ﻃﻲ اﻳﺠﺎد ﻧﻮار اﺑﺰار ،Editﺑﺎ ﻧﺤﻮه ﻛﺎرﺑﺮد ﺗﻜﻨﻴﻜﻬﺎي اﺑﺘﺪاﻳﻲ وﻳﺮاﻳﺶ ﻣﺘﻦ ﺑـﻪ وﺳـﻴﻠﻪ ﺗﻮاﺑـﻊ دروﻧـﻲ ﻛـﻼس TextBoxو ﻛﻼس Clipboardآﺷﻨﺎ ﺷﺪﻳﺪ و ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﺑﻪ ﺳﺎدﮔﻲ ﻣﻲ ﺗﻮان اﻳﻦ وﻳﮋﮔﻲ ﻫﺎ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮد – وﻳﮋﮔﻴﻬـﺎﻳﻲ ﻛﻪ ﻛﺎرﺑﺮ از ﻫﺮ ﺑﺮﻧﺎﻣﻪ وﻳﻨﺪوزي اﻧﺘﻈﺎر دارد. ﻫﻤﭽﻨﻴﻦ ﺑﺎ ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ ﻛﻪ وﻳﻨﺪوز ﺑﻪ ﻃﻮر ﭘﻴﺶ ﻓﺮض ﺑﺮاي ﻛﻨﺘﺮل ﻫﺎ ﻗﺮار ﻣـﻲ دﻫـﺪ و ﻧﻴـﺰ ﭼﮕـﻮﻧﮕﻲ اﻳﺠـﺎد ﻣﻨـﻮ ﻫـﺎي ﻓﺮﻋـﻲ ﻣﺨﺼﻮص ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﺧﻮدﺗﺎن آﺷﻨﺎ ﺷﺪﻳﺪ. در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ:
ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل MenuStripﺑﻪ ﺑﺮﻧﺎﻣﻪ ﺧﻮد ﻣﻨﻮ و زﻳﺮﻣﻨﻮ اﺿﺎﻓﻪ ﻛﻨﻴﺪ. در ﻛﻨﺎر ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻣﻨﻮي ﺑﺮﻧﺎﻣﻪ ﻋﻼﻣﺖ ﺗﻴﻚ ﻗﺮار دﻫﻴﺪ. ﺑﻪ ﻣﻨﻮ ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﺧﻮد ﺷﻮرت ﻛﺎت و ﻛﻠﻴﺪ دﺳﺘﺮﺳﻲ اﺧﺘﺼﺎص دﻫﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل ContextMenuStripﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﺧﻮد ﻣﻨﻮ ﻫﺎي ﻓﺮﻋﻲ اﻳﺠﺎد ﻛﻨﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺘﻬﺎي ﻣﻮﺟﻮد در ﻛﻼس ،TextBoxﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻨﻮ ﻫﺎ را در ﺻﻮرت ﻟﺰوم ﻓﻌﺎل و ﻳﺎ ﻏﻴﺮ ﻓﻌﺎل ﻛﻨﻴﺪ.
ﺗﻤﺮﻳﻦ: ﺑﺮاي اﻳﻨﻜﻪ ﻇﺎﻫﺮ ﺑﺮﻧﺎﻣـﻪ اي ﻛـﻪ در اﻳـﻦ ﻓـﺼﻞ اﻳﺠـﺎد ﻛﺮدﻳـﺪ ﺑﻴـﺸﺘﺮ ﻣـﺸﺎﺑﻪ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي وﻳﻨـﺪوزي ﺑﺎﺷـﺪ ،ﺑـﺎ اﺳـﺘﻔﺎده از ﻛﻨﺘـﺮل StatusStripﻳﻚ ﻧﻮار اﺑﺰار ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ و ﻛﺪي را ﺑﺮاي آن ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ ﻫﻨﮕﺎم اﻧﺠﺎم دادن اﻋﻤـﺎﻟﻲ ﻣﺎﻧﻨـﺪ ،Cut Paste ،Copyو … ﻣﺘﻦ ﻣﻨﺎﺳﺒﻲ ﺑﺮاي ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ داده ﺷﻮد.
٣٣٠
ﻓﺼﻞ ﻧﻬﻢ :ﺳﺎﺧﺘﻦ اﺷﻴﺎ از زﻣﺎﻧﻲ ﻛﻪ ﺑﺎ ﻛﺎﻣﭙﻴﻮﺗﺮ آﺷﻨﺎ ﺷﺪﻳﺪ ﺗﺎﻛﻨﻮن ﻣﻤﻜﻦ اﺳﺖ واژه ﺷﻴﺊ ﮔﺮاﻳﻲ را زﻳﺎد ﺷﻨﻴﺪه ﺑﺎﺷﻴﺪ .ﻣﻤﻜﻦ اﺳـﺖ ﺷـﻨﻴﺪه ﺑﺎﺷـﻴﺪ ﻛـﻪ اﻳـﻦ ﻣﺒﺤﺚ ،ﻳﻜﻲ از ﻣﺒﺎﺣﺚ ﺳﺨﺖ و ﻏﻴﺮ ﻗﺎﺑﻞ درك ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﺳﺖ .در ﺳﺎﻟﻬﺎي اول ﻛﻪ اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻪ وﺟﻮد آﻣﺪه ﺑـﻮد اﻳـﻦ ﮔﻔﺘﻪ ﺻﺤﺖ داﺷﺖ ،اﻣﺎ زﺑﺎﻧﻬﺎ و اﺑﺰارﻫﺎي ﻣﺪرن اﻣﺮوزي ﺑﺎﻋﺚ ﺷﺪه اﻧﺪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا ﺑـﻪ ﻣﺒﺤﺜـﻲ ﺑـﺴﻴﺎر ﺳـﺎده ﺗﺒـﺪﻳﻞ ﺷـﻮد. ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا ﻣﻨﺎﻓﻊ زﻳﺎدي را ﺑﺮاي ﺗﻮﺳﻌﻪ ﮔﺮان ﻧﺮم اﻓﺰاري 1دارد ،ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺎﻧﻨﺪ C# ،C++و وﻳﮋوال ﺑﻴﺴﻴﻚ و … ﺳﻌﻲ ﻛﺮده اﻧﺪ ﺑﻪ ﻧﺤﻮي رﺷﺪ ﻛﻨﻨﺪ ﻛﻪ ﺑﻪ ﺳﺎده ﮔﻲ ﺑﺘﻮان ﺑﻪ وﺳﻴﻠﻪ آﻧﻬﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺷﻴﺊ ﮔـﺮا را ﻃﺮاﺣـﻲ و ﭘﻴـﺎده ﺳﺎزي ﻛﺮد. در ﺑﻴﺸﺘﺮ ﻓﺼﻠﻬﺎي اﻳﻦ ﻛﺘﺎب از اﺷﻴﺎ و ﻛﻼﺳﻬﺎ اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ ،اﻣﺎ در اﻳﻦ ﻓﺼﻞ ﺑﺮ ﻣﺒﺤﺚ ﺷﻴﺊ ﮔﺮاﻳﻲ ﺗﻤﺮﻛﺰ ﺧﻮاﻫﻴﻢ ﻛﺮد و آن را ﺑﻪ ﺗﻔﺼﻴﻞ ﻣﻮرد ﺑﺮرﺳﻲ ﻗﺮار ﺧﻮاﻫﻴﻢ داد .ﻫﻤﭽﻨﻴﻦ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﺑﺮ ﭘﺎﻳﻪ ﺗﺠﺮﺑﻴﺎت و آﻣﻮﺧﺘﻪ ﻫﺎﻳﻲ ﻛﻪ در ﻓﺼﻠﻬﺎي ﻗﺒﻞ از ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳـﺴﻲ ﺑﺪﺳﺖ آورده اﻳﺪ و ﻣﻮاردي ﻛﻪ در اﻳﻦ ﻓﺼﻞ ﻣﻲ آﻣﻮزﻳﺪ ،ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺟﺎﻟﺒﻲ را ﺑﺎ وﻳﮋوال C#اﻳﺠﺎد ﻛﻨﻴﻢ. در اﻳﻦ ﻓﺼﻞ:
ﺑﺎ ﻧﺤﻮه ي ﺳﺎﺧﺘﻦ ﻳﻚ ﻛﻼس ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﺑﺎ ﭼﻨﺪﻳﻦ ﻣﺘﺪ و ﺧﺎﺻﻴﺖ ﮔﻮﻧﺎﮔﻮن آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ. ﺑﺎ ﻣﻔﻬﻮم ارث ﺑﺮدن ﻳﻚ ﻛﻼس از ﻛﻼﺳﻲ ﻛﻪ ﻗﺒﻼً اﻳﺠﺎد ﻛﺮده اﻳﺪ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. ﭼﮕﻮﻧﮕﻲ ﺗﻐﻴﻴﺮ دادن ﻣﺘﺪﻫﺎي ﻛﻼس ﭘﺎﻳﻪ در ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد. ﭼﮕﻮﻧﮕﻲ اﻳﺠﺎد ﻓﻀﺎي ﻧﺎم را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﻣﻔﻬﻮم اﺷﻴﺎ: ﻳﻚ ﺷﻴﺊ در دﻧﻴﺎي واﻗﻌﻲ ،اﻏﻠﺐ ﻫﺮ ﭼﻴﺰي اﺳﺖ ﻛﻪ ﺑﺘﻮاﻧﻴﺪ ﺗﺼﻮر ﻛﻨﻴﺪ .ﻣﻌﻤﻮﻻً در ﺗﻤﺎم ﻃﻮل روز در ﺣﺎل ﻛﺎر ﻛﺮدن ﺑﺎ اﺷﻴﺎي ﻓﻴﺰﻳﻜـﻲ ﻣﺎﻧﻨﺪ ﺗﻠﻮﻳﺰﻳﻮﻧﻬﺎ ،اﺗﻮﻣﺒﻴﻠﻬﺎ ،ﻣﺸﺘﺮﻛﻴﻦ ،2ﮔﺰارﺷﺎت ،ﻻﻣﭗ ﻫﺎ و ﻳﺎ ﻫﺮ ﭼﻴﺰ دﻳﮕﺮي ﻫﺴﺘﻴﺪ .در ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎ ﻧﻴﺰ ،ﻳﻚ ﺷﻴﺊ ﻣـﺸﺨﺺ ﻛﻨﻨـﺪه ﻫﺮ ﭼﻴﺰي اﺳﺖ ﻛﻪ در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﻲ ﺑﻴﻨﻴﺪ و ﻳﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺎن از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻓﺮم ﺑﺮﻧﺎﻣﻪ ،دﻛﻤﻪ ﻫﺎي ﻧﻮار اﺑـﺰار، ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻣﻨﻮ ﻫﺎ و ...ﻫﻤﻪ ﻧﻤﻮﻧﻪ ﻫﺎﻳﻲ از اﺷﻴﺎ در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﺴﺘﻨﺪ .اﺷﻴﺎي دﻳﮕﺮي ﻧﻴﺰ در ﻛﺎﻣﭙﻴﻮﺗﺮ وﺟـﻮد دارﻧـﺪ ﻛـﻪ ﻧﻤـﻮد ﻇﺎﻫﺮي ﻧﺪارﻧﺪ ،اﻣﺎ در ﺑﺨﺸﻬﺎي ﻣﺨﺘﻠﻒ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ ﻣﺎﻧﻨﺪ ﺷﻴﺊ ﺑﺮاي ﻛﻨﺘﺮل ﻛﺎرﺑﺮان ﻳﻚ ﺑﺮﻧﺎﻣﻪ .ﻛﺎرﺑﺮ ﺑﺮﻧﺎﻣﻪ ﭼﻨﻴﻦ ﺷـﻴﺊ را در ﺑﺮﻧﺎﻣﻪ ﻧﻤﻲ ﺑﻴﻨﺪ اﻣﺎ در ﻃﻮل اﺟﺮاي ﺑﺮﻧﺎﻣﻪ اﻳﻦ ﺷﻴﺊ وﺟﻮد دارد و وﻇﺎﻳﻒ ﺧﻮد را اﻧﺠﺎم ﻣﻲ دﻫﺪ. ﻓﺮض ﻛﻨﻴﺪ ﻣﻲ ﺧﻮاﻫﻴﺪ در ﻗﺴﻤﺘﻲ از ﺑﺮﻧﺎﻣﻪ ﺑﺮاي ﻳﻜﻲ از ﻛﺎرﺑﺮان ،ﺻﻮرت ﺣﺴﺎب ﺻﺎدر ﻛﻨﻴﺪ .در اﻳﻦ ﺻـﻮرت ﺑﺎﻳـﺪ در ﺑﺮﻧﺎﻣـﻪ ي ﺧـﻮد ﻳﻚ ﺷﻴﺊ ﺑﺮاي ﻧﺸﺎن دادن ﺻﻮرت ﺣﺴﺎب و ﻳﻚ ﺷﻴﺊ ﻧﻴﺰ ﺑﺮاي ﻧﺸﺎن دادن ﻛﺎرﺑﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ .ﻓـﺮض ﻛﻨﻴـﺪ Customerﺷـﻴﺊ ﻣﺮﺑﻮط ﺑﻪ ﻛﺎرﺑﺮ و Billﺷﻴﺊ ﻣﺮﺑﻮط ﺑﻪ ﺻﻮرت ﺣﺴﺎب ﺑﺎﺷﺪ .ﺷﻴﺊ Customerداراي ﺧﺼﻮﺻﻴﺖ ﻫﺎ اﻳـﻲ ﻣﺎﻧﻨـﺪ ﻧـﺎم ،آدرس، ﺗﻠﻔﻦ و … اﺳﺖ ﻛﻪ ﻫﺮ ﻛﺎرﺑﺮ داراﺳﺖ .ﺑﻪ ﻋﻼوه ،اﻳﻦ ﺷﻴﺊ ﺑﺎﻳﺪ ﺑﺘﻮاﻧﺪ ﻳﻚ ﺻﻮرت ﺣﺴﺎب ﺑﺮاي ﺧﻮد اﻳﺠﺎد ﻛﻨﺪ و ﻣﻲ داﻧﻴﺪ ﻛـﻪ در اﻳـﻦ ﺑﺮﻧﺎﻣﻪ ،ﺻﻮرت ﺣﺴﺎب ﻫﺎ را ﺑﺎ ﺷﻴﺊ اي از ﻧﻮع Billﻧﺸﺎن ﻣﻲ دﻫﻴﻢ .ﭘﺲ در واﻗﻊ ﻣـﻲ ﺗـﻮان ﮔﻔـﺖ ﺷـﻴﺊ Customerﺑﺎﻳـﺪ ﺑﺘﻮاﻧﺪ ﻳﻚ ﺷﻴﺊ از ﻧﻮع Billاﻳﺠﺎد ﻛﻨﺪ ﻛﻪ ﺻﻮرت ﺣﺴﺎب ﻛﺎرﺑﺮ را ﻧﺸﺎن دﻫﺪ.
1ﻣﻨﻈﻮر از ﺗﻮﺳﻌﻪ ﮔﺮان ﻧﺮم اﻓﺰاري ،اﻓﺮادي اﺳﺖ ﻛﻪ در زﻣﻴﻨﻪ ي ﻃﺮاﺣﻲ و ﺗﻮﺳﻌﻪ ي ﻧﺮم اﻓﺰار ﻓﻌﺎﻟﻴﺖ دارﻧﺪ ﻣﺎﻧﻨﺪ ﻃﺮاﺣﺎن ﻧﺮم اﻓﺰار ،ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن و .... 2ﺷﺎﻳﺪ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﺗﻌﺮﻳﻒ ﺷﻴﺊ ،ﻳﻚ ﻣﺸﺘﺮك را ﻧﺘﻮان ﻳﻚ ﺷﻴﺊ ﻣﺤﺴﻮب ﻛﺮد .اﻣﺎ در اﻳﻨﺠﺎ ﻓﺮض ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻫﺮ ﭼﻴـﺰي ﻛـﻪ در دﻧﻴـﺎي واﻗﻌـﻲ وﺟـﻮد دارد ﻳـﻚ ﺷﻴﺊ اﺳﺖ.
٣٣١
ﺷﻴﺊ Billﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺪ ﺟﺰﺋﻴﺎت ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﺻﻮرت ﺣﺴﺎب را در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ و ﻧﻴﺰ اﻣﻮر ﻣﺮﺑﻮط ﺑﻪ آن را اﻧﺠﺎم دﻫﺪ .ﺑﺮاي ﻣﺜﺎل اﻳﻦ ﺷﻴﺊ ﺑﺎﻳﺪ ﺑﺘﻮاﻧﺪ ﺻﻮرت ﺣﺴﺎب اﻳﺠﺎد ﺷﺪه را ﭼﺎپ ﻛﻨﺪ. اﻣﺎ ﻧﻜﺘﻪ ﻣﻬﻢ و ﻗﺎﺑﻞ ﺗﻮﺟﻪ در اﻳﻨﺠﺎ اﻳﻦ اﺳﺖ ﻛﻪ اﻳﻦ اﺷﻴﺎ ﺑﺎﻳﺪ ﻫﻮﺷﻤﻨﺪي ﻻزم ﺑﺮاي اﻧﺠﺎم ﺗﻤﺎم ﻛﺎرﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﺧﻮدﺷـﺎن را داﺷـﺘﻪ ﺑﺎﺷﻨﺪ .در ﻣﺜﺎل ﻗﺒﻠﻲ ،اﮔﺮ ﺷﻴﺊ اي از ﻧﻮع Customerداﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻣﺨﺼﻮص ﺑﻪ ﻳﻜﻲ از ﻛﺎرﺑﺮان ﺑﺮﻧﺎﻣﻪ اﺳﺖ ،ﻣﻲ ﺗﻮاﻧﻴـﺪ ﺑـﻪ ﺳﺎدﮔﻲ ﺑﻪ آن ﺷﻴﺊ ﺑﮕﻮﻳﻴﺪ ﻛﻪ "ﻳﻚ ﺻﻮرت ﺣﺴﺎب ﺑﺮاي ﺧﻮدت اﻳﺠﺎد ﻛﻦ" .ﺳﭙﺲ اﻳﻦ ﺷﻴﺊ ﺑﺎﻳﺪ ﺑﺘﻮاﻧﺪ ﺗﻤﺎم ﻛﺎرﻫﺎي ﻃﻮﻻﻧﻲ و ﺣﺘﻲ ﺳﺨﺖ ﻣﺮﺑﻮط ﺑﻪ اﻳﺠﺎد ﻛﺮدن ﻳﻚ ﺻﻮرت ﺣﺴﺎب را اﻧﺠﺎم داده و در اﻧﺘﻬﺎ ﻳﻚ ﺷﻴﺊ ﺟﺪﻳﺪ از ﻧﻮع Billرا ﺑﻪ ﻋﻨﻮان ﺻﻮرت ﺣـﺴﺎب ﺧﻮد ﺑﻪ ﺷﻤﺎ ﺑﺮﮔﺮداﻧﺪ .ﻫﻤﭽﻨﻴﻦ اﮔﺮ ﺷﻴﺊ از ﻧﻮع Billﺑﻪ ﻋﻨﻮان ﺻﻮرت ﺣﺴﺎب ﻳﻜﻲ از ﻛﺎرﺑﺮان ﺧﻮد در اﺧﺘﻴﺎر داﺷﺘﻴﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑـﻪ آن ﺑﮕﻮﻳﻴﺪ ﻛﻪ "ﺟﺰﺋﻴﺎت ﺻﻮرت ﺣﺴﺎب را ﭼﺎپ ﻛﻦ" و ﺷﻴﺊ Billﻧﻴﺰ ﺑﺎﻳﺪ ﻗﺎﺑﻠﻴﺖ اﻧﺠﺎم اﻳﻦ ﻛﺎر را داﺷﺘﻪ ﺑﺎﺷﺪ. اﮔﺮ ﺑﻪ ﺧﺎﻃﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،ﻫﻨﮕﺎم ﻣﻌﺮﻓﻲ اﻟﮕﻮرﻳﺘﻢ ﻫﺎ و ﭼﮕﻮﻧﮕﻲ ﺗﺒﺪﻳﻞ آﻧﻬﺎ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﺎﻣﭙﻴﻮﺗﺮي ﮔﻔﺘﻴﻢ ﻛﻪ ﺑﺮاي ﺣﻞ ﻳﻚ ﻣـﺴﺌﻠﻪ ﺑﺎﻳﺪ ﺑﺘﻮان آن را ﺑﻪ ﻗﺴﻤﺘﻬﺎي ﻛﻮﭼﻜﺘﺮ ﺗﻘﺴﻴﻢ ﻛﺮد .ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا ﻧﻴﺰ ﺑﻪ اﻳﻦ دﻟﻴﻞ در ﻣﻬﻨﺪﺳﻲ ﻧﺮم اﻓﺰار ﻛـﺎرﺑﺮد ﺑـﺴﻴﺎري دارد ﻛﻪ ﻣﻲ ﺗﻮان ﺑﻪ وﺳﻴﻠﻪ آن ﻳﻚ ﻣﺴﺌﻠﻪ ﭘﻴﭽﻴﺪه را ﺑﻪ ﺑﻬﺘﺮﻳﻦ ﻧﺤﻮ ﺑﻪ ﭼﻨﺪﻳﻦ ﻗﺴﻤﺖ ﻛﻮﭼﻜﺘﺮ ﺗﻘﺴﻴﻢ ﻛﺮد و ﺳﭙﺲ ﺑﺎ ﻗﺮار دادن آﻧﻬـﺎ ﻛﻨـﺎر ﻫﻢ ،ﺑﻪ راه ﺣﻞ ﻣﺴﺌﻠﻪ اﺻﻠﻲ رﺳﻴﺪ .ﻣﻤﻜﻦ اﺳﺖ ﺑﮕﻮﻳﻴﺪ ﻛﻪ اﻳﻦ ﻛﺎر ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ﻫﺎ ﻧﻴﺰ اﻣﻜﺎن ﭘﺬﻳﺮ اﺳﺖ ،ﭘﺲ ﭼﻪ ﻧﻴﺎزي اﺳﺖ ﻛـﻪ از ﺷﻴﺊ ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﻢ؟ در ﺗﻮﺿﻴﺤﺎت ﻗﺒﻠﻲ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ رواﺑﻄﻲ ﻛـﻪ ﺑـﺮاي Customerو Billﺷـﺮح داده ﺷـﺪ ﺑـﺴﻴﺎر ﻣﺸﺎﺑﻪ دﻧﻴﺎي واﻗﻌﻲ اﺳﺖ .در ﺣﻘﻴﻘﺖ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا ﺳﻌﻲ ﻣﻲ ﺷﻮد ﺗﻤﺎم ﻣﻮارد ﺷﺒﻴﻪ ﺑﻪ آﻧﭽﻪ در واﻗﻌﻴـﺖ وﺟـﻮد دارد اﻳﺠـﺎد ﺷﻮد و ﺗﻤﺎم رواﺑﻂ ﺑﻴﻦ اﺷﻴﺎ ﻧﻴﺰ ﺑﺮ اﻳﻦ اﺳﺎس ﺻﻮرت ﮔﻴﺮد. ﻣﻮرد دﻳﮕﺮي ﻛﻪ ﺑﺎﻋﺚ ﻗﺪرت ﻓﺮاوان ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا ﻣﻲ ﺷﻮد در اﻳﻦ اﺳﺖ ﻛﻪ ،ﺷﻤﺎ ﺑﻪ ﻋﻨﻮان ﻳﻜﻲ از اﻓﺮادي ﻛﻪ از ﻳـﻚ ﺷـﻴﺊ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ﻧﻴﺎزي ﺑﻪ داﻧﺴﺘﻦ اﻳﻨﻜﻪ ﭼﮕﻮﻧﻪ آن ﺷﻴﺊ درﺧﻮاﺳﺘﻬﺎي ﺷﻤﺎ را اﻧﺠﺎم ﻣﻲ دﻫﺪ ﻧﺪارﻳﺪ .اﻳـﻦ ﻣـﻮرد در دﻧﻴـﺎي واﻗﻌـﻲ ﻧﻴـﺰ ﺻﺎدق اﺳﺖ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺣﺎل اﺳﺘﻔﺎده از ﻳﻚ ﻣﻮﺑﺎﻳﻞ ﻫﺴﺘﻴﺪ ،ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﺑﺪاﻧﻴﺪ اﻳﻦ دﺳﺘﮕﺎه ﺑﻪ ﺻﻮرت دروﻧﻲ ﭼﮕﻮﻧﻪ ﻛـﺎر ﻣـﻲ ﻛﻨﺪ؟ ﺣﺘﻲ اﮔﺮ ﻧﺤﻮه ﻋﻤﻠﻜﺮد آن را ﺑﺪاﻧﻴﺪ و ﻳﺎ ﺣﺘﻲ آن را ﺧﻮدﺗﺎن اﺧﺘﺮاع ﻛﺮده ﺑﺎﺷﻴﺪ ﻧﻴﺰ ،ﺳﺎده ﺗﺮ اﺳﺖ ﻛـﻪ ﺑـﺮاي ﻛـﺎر ﺑـﺎ آن از راﺑـﻂ ﻛﺎرﺑﺮي ﺳﺎده اي ﻛﻪ در اﺧﺘﻴﺎر ﺷﻤﺎ ﻗﺮار ﻣﻲ ﮔﻴﺮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺻﻮرت از ﺧﻄﺎﻫﺎي اﺣﺘﻤﺎﻟﻲ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﻫﻨﮕـﺎم ﻛـﺎر ﺑـﺎ آن اﻳﺠﺎد ﺷﻮد ﻧﻴﺰ ﺟﻠﻮﮔﻴﺮي ﻣﻲ ﻛﻨﻴﺪ .اﻳﻦ ﻣﻮرد در ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎ ﻫﻢ ﺻﺎدق اﺳﺖ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺑﺎ ﻳﻚ ﺷﻴﺊ ﻛﺎر ﻛﻨﻴﺪ ،ﺣﺘـﻲ اﮔـﺮ آن ﺷﻴﺊ را ﺧﻮدﺗﺎن اﻳﺠﺎد ﻛﺮده ﺑﺎﺷﻴﺪ ،ﺑﻬﺘﺮ اﺳﺖ از راﺑﻂ ﺳﺎده و راﺣﺘﻲ ﻛﻪ آن ﺷﻴﺊ ﻓـﺮاﻫﻢ ﻣـﻲ ﻛﻨـﺪ اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ و اﺟـﺎزه دﻫﻴـﺪ ﻛـﻪ ﭘﻴﭽﻴﺪﮔﻲ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ وﻇﻴﻔﻪ ي آن ﺷﻴﺊ در ﭘﺸﺖ راﺑﻂ ﺳﺎده ي آن ﭘﻨﻬﺎن ﺑﻤﺎﻧﺪ. ﺑﺮاي ﺗﻮﺿﻴﺢ ﺑﻴﺸﺘﺮ در ﻣﻮرد اﺷﻴﺎ ،ﺑﻬﺘﺮ اﺳﺖ ﻳﻚ ﺷﻴﺊ ﻣﺎﻧﻨﺪ ﺗﻠﻮﻳﺰﻳﻮن را در دﻧﻴﺎي واﻗﻌﻲ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ .ﻳﻚ دﺳﺘﮕﺎه ﺗﻠﻮﻳﺰﻳﻮن را در ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ .ﻳﻚ ﺳﺮي از ﻛﺎرﻫﺎ ﻫﺴﺘﻨﺪ ﻛﻪ ﻣﻲ داﻧﻴﺪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ ﻳﻚ ﺗﻠﻮﻳﺰﻳﻮن آﻧﻬﺎ را اﻧﺠﺎم داد .ﻣﺎﻧﻨﺪ:
ﺗﻤﺎﺷﺎي ﺗﺼﻮﻳﺮ روي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ. ﺗﻐﻴﻴﺮ دادن ﻛﺎﻧﺎل ﺗﻠﻮﻳﺰﻳﻮن. ﺗﻐﻴﻴﺮ ﺻﺪاي ﺗﻠﻮﻳﺰﻳﻮن. ﺧﺎﻣﻮش و ﻳﺎ روﺷﻦ ﻛﺮدن آن.
ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺣﺎل اﺳﺘﻔﺎده از ﻳﻚ ﺗﻠﻮﻳﺰﻳﻮن ﻫﺴﺘﻴﺪ ،ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﺑﺪاﻧﻴﺪ اﺟﺰاي ﺗﺸﻜﻴﻞ دﻫﻨﺪه ﻳﻚ ﺗﻠﻮﻳﺰﻳﻮن ﭼﮕﻮﻧﻪ درﺧﻮاﺳـﺘﻬﺎي ﺷﻤﺎ را اﻧﺠﺎم ﻣﻲ دﻫﻨﺪ .اﺣﺘﻤﺎﻻً اﮔﺮ از ﺷﻤﺎ ﺑﺨﻮاﻫﻨﺪ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻔﻲ را در ﻛﻨﺎر ﻫﻢ ﻗﺮار دﻫﻴﺪ و ﻳﻚ ﺗﻠﻮﻳﺰﻳـﻮن ﻣـﺪرن اﻳﺠـﺎد ﻛﻨﻴـﺪ، ﻗﺎدر ﺑﻪ اﻧﺠﺎم ﭼﻨﻴﻦ ﻛﺎري ﻧﺨﻮاﻫﻴﺪ ﺑﻮد .اﻟﺒﺘﻪ ﻣﻤﻜﻦ اﺳﺖ ﺑﻌﺪ از ﻣﺪﺗﻬﺎ ﻣﻄﺎﻟﻌﻪ و آزﻣﺎﻳﺶ ﺑﺘﻮاﻧﻴﺪ ﻳﻚ دﺳﺘﮕﺎه ﺗﻠﻮﻳﺰﻳﻮن ﺳﺎده اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ ﺑﺎز ﻫﻢ ﺑﻪ ﭘﻴﺸﺮﻓﺘﮕﻲ ﺗﻠﻮﻳﺰﻳﻮن ﻫﺎﻳﻲ ﻛﻪ اﻛﺜﺮ ﻣﺮدم از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﻧﺨﻮاﻫﺪ ﺑﻮد .ﺑﺎ وﺟﻮد اﻳﻦ ،ﻫﻢ ﺷﻤﺎ و ﻫﻢ اﻏﻠﺐ ﻣﺮدم ﻣﻲ داﻧﻨﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﺑﺎﻳﺪ از ﻳﻚ دﺳﺘﮕﺎه ﺗﻠﻮﻳﺰﻳﻮن اﺳﺘﻔﺎده ﻛﻨﻨﺪ ،ﭼﮕﻮﻧﻪ ﻛﺎﻧﺎل آن را ﺗﻐﻴﻴﺮ دﻫﻨﺪ ،ﭼﮕﻮﻧﻪ ﺻﺪاي آن را ﺗﻨﻈـﻴﻢ ﻛﻨﻨـﺪ ،ﭼﮕﻮﻧـﻪ آن را ﺧﺎﻣﻮش و ﻳﺎ روﺷﻦ ﻛﻨﻨﺪ و ﻏﻴﺮه.
٣٣٢
اﺷﻴﺎ در ﻣﻬﻨﺪﺳﻲ ﻧﺮم اﻓﺰار ﻧﻴﺰ اﺳﺎﺳﺎً ﺑﻪ ﻫﻤﻴﻦ روش ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﺷﻴﺊ در اﺧﺘﻴﺎر داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺳﺎدﮔﻲ از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ و ﺑﺨﻮاﻫﻴﺪ ﻛﻪ وﻇﺎﻳﻒ ﻻزم را اﻧﺠﺎم دﻫﺪ .ﺑﺮاي اﻳﻦ ﻣﻮارد ﻻزم ﻧﻴﺴﺖ ﺑﺪاﻧﻴﺪ ﻛﻪ ﺷﻴﺊ ﺑﻪ ﺻﻮرت دروﻧﻲ ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ و ﻳﺎ ﻻزم ﻧﻴﺴﺖ ﺣﺘﻲ ﻛﻮﭼﻜﺘﺮﻳﻦ اﻃﻼﻋﺎﺗﻲ در ﻣﻮرد ﻧﺤﻮه ﻋﻤﻠﻜﺮد آن داﺷﺘﻪ ﺑﺎﺷﻴﺪ. اﺷﻴﺎي ﻧﺮم اﻓﺰاري ﻋﻤﻮﻣﺎً داراي ﻣﺸﺨﺼﺎت زﻳﺮ ﻫﺴﺘﻨﺪ:
ﻫﻮﻳﺖ :ﻳﻚ ﺷﻴﺊ ﻫﻤﻮاره ﻧﻮع ﺧﻮد را ﻣﻲ داﻧﺪ .ﺑﺮاي ﻣﺜﺎل ﻳﻚ ﺗﻠﻮﻳﺰﻳﻮن ﻫﻤﻮاره ﻣﻴﺪاﻧﺪ ﻛـﻪ ﻳـﻚ ﺷـﻴﺊ از ﻧـﻮع ﺗﻠﻮﻳﺰﻳـﻮن اﺳﺖ. ﺣﺎﻟﺖ :ﻫﺮ ﺷﻴﺊ در ﻫﺮ زﻣﺎﻧﻲ وﺿﻌﻴﺖ و ﺣﺎﻟﺖ ﺧﻮد را ﻣﻴﺪاﻧﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ در ﺣﺎل ﻣـﺸﺎﻫﺪه ﻛﺎﻧـﺎل 4از ﻳـﻚ ﺗﻠﻮﻳﺰﻳـﻮن ﺑﺎﺷﻴﺪ و ﺑﺨﻮاﻫﻴﺪ ﻛﻪ ﺗﻠﻮﻳﺰﻳﻮن ﺷﻤﺎره ﻛﺎﻧﺎﻟﻲ را ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ روي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﺪ ،ﻋﺪد 4را ﻧﻤﺎﻳﺶ ﺧﻮاﻫﺪ داد. رﻓﺘﺎر :ﺑﻪ ﻋﻜﺲ اﻟﻌﻤﻞ ﻳﻚ ﺷﻴﺊ در ﻣﻘﺎﺑﻞ درﺧﻮاﺳﺘﻬﺎي ﻛﺎرﺑﺮ ،رﻓﺘـﺎر آن ﺷـﻴﺊ ﻣـﻲ ﮔﻮﻳﻨـﺪ .ﺑـﺮاي ﻣﺜـﺎل ﻓـﺮض ﻛﻨﻴـﺪ از ﺗﻠﻮﻳﺰﻳﻮن ﺑﺨﻮاﻫﻴﺪ ﺗﺎ ﺻﺪاي آن زﻳﺎد ﺷﻮد .اﻳﻦ اﻓﺰاﻳﺶ ﺻﺪاي ﺗﻠﻮﻳﺰﻳﻮن ﺟﺰﺋﻲ از رﻓﺘﺎر آن ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد.
ﻛﭙﺴﻮﻟﻲ ﺑﻮدن: ﻣﻔﻬﻮم اﺻﻠﻲ ﻛﻪ در ﭘﺸﺖ ﺷﻴﺊ-ﮔﺮاﻳﻲ ﻗﺮار دارد ﻛﭙﺴﻮﻟﻲ ﺑﻮدن 1اﺳﺖ .اﻳﻦ ﻣﻔﻬﻮم ﺑﺎ وﺟﻮد ﺳﺎده ﺑﻮدن ،از اﻫﻤﻴـﺖ زﻳـﺎدي ﺑﺮﺧـﻮردار اﺳﺖ .اﻳﺪه ﻛﻠﻲ ﻛﻪ ﻛﭙﺴﻮﻟﻲ ﺑﻮدن اراﺋﻪ ﻣﻲ دﻫﺪ ﺑﻪ اﻳﻦ ﺻﻮرت اﺳﺖ ﻛﻪ رﻓﺘﺎر ﻳﻚ ﺷﻴﺊ ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﺑﺎﻳﺪ دور از دﻳﺪ ﻛـﺎرﺑﺮ ﺑﺎﺷـﺪ .ﺑـﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻻزم ﻧﺒﺎﺷﺪ ،ﻛﺎرﺑﺮ ﻧﺒﺎﻳﺪ ﻣﺘﻮﺟﻪ ﺷﻮد ﻛﻪ ﻳﻚ ﺷﻴﺊ ﭼﮕﻮﻧﻪ درﺧﻮاﺳﺘﻬﺎي او را اﻧﺠﺎم ﻣﻲ دﻫﺪ. ﻛﻨﺘﺮل OpenFileDialogﻛﻪ در ﻓﺼﻠﻬﺎي ﻗﺒﻞ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ را ﺑﻪ ﺧﺎﻃﺮ ﺑﻴﺎورﻳﺪ .ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻣـﻲ ﺧﻮاﺳـﺘﻴﻢ ﻳﻜﻲ از آﻧﻬﺎ را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﻴﻢ ،ﺑﻌﺪ از اﻳﻨﻜﻪ وﺿﻌﻴﺖ آن را ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ﻫﺎ ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﺮدﻳﻢ ،از آن ﻣﻲ ﺧﻮاﺳـﺘﻴﻢ ﻛـﻪ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﺷﻮد )ﺑﺎ اﺳﺘﻔﺎده از ﺗﺎﺑﻊ .(ShowDialogوﻟﻲ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ آن ﺷﻴﺊ ﻫﻴﭻ اﻃﻼﻋـﺎﺗﻲ را در ﻣـﻮرد ﻧﺤﻮه ﻧﻤﺎﻳﺶ داده ﺷﺪﻧﺶ در ﺻﻔﺤﻪ ﺑﺮوز ﻧﻤﻲ داد و ﻣﺎ ﻧﻴﺰ ﻧﻴﺎزي ﺑﻪ داﻧﺴﺘﻦ اﻳﻦ ﻛﻪ ﭼﮕﻮﻧﻪ اﻳﻦ ﺷﻴﺊ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﻣـﻲ ﺷـﻮد ﻧﺪاﺷﺘﻴﻢ .اﻳﻦ ﻣﻮرد ﻛﻪ ﺷﻴﺊ ،OpenFileDialogﻧﺤﻮه اﻧﺠﺎم دادن وﻇﺎﻳﻔﺶ را از ﻛﺎرﺑﺮ ﭘﻨﻬﺎن ﻣﻲ ﻛﺮد ،ﺟﺰﺋـﻲ از ﻛﭙـﺴﻮﻟﻲ ﺑﻮدن آن ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد.
ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎ: ﺑﺮاي ارﺗﺒﺎط ﺑﺎ ﻳﻚ ﺷﻴﺊ از ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺘﻬﺎي آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ .در ﺗﻌﺮﻳﻒ آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ:
ﻣﺘﺪ ﻫﺎ :روﺷﻬﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ آن ﻣﻲ ﺗﻮان ﺑﻪ ﻳﻚ ﺷﻴﺊ ﮔﻔﺖ ﭼﮕﻮﻧﻪ وﻇﻴﻔﻪ ﺧﺎﺻﻲ را اﻧﺠﺎم دﻫﺪ.
ﺧﺎﺻﻴﺖ ﻫﺎ :اﻋﻀﺎﻳﻲ از ﻳﻚ ﺷﻴﺊ ﻫﺴﺘﻨﺪ ﻛﻪ وﻳﮋﮔﻴﻬﺎي آن را ﺷﺮح ﻣﻲ دﻫﻨﺪ.
در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ ،ﻣﺘﺪ ﻫﺎ ﺑﻪ ﻋﻨﻮان ﻗﻄﻌﻪ ﻛﺪ ﻫﺎﻳﻲ ﻣﻌﺮﻓﻲ ﺷﺪه ﺑﻮدﻧﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺴﺘﻨﺪ وﻇﻴﻔـﻪ ﻣﺸﺨـﺼﻲ را اﻧﺠـﺎم دﻫﻨـﺪ .اﻟﺒﺘـﻪ اﻳـﻦ ﺗﻌﺮﻳﻒ درﺳﺖ اﺳﺖ ،اﻣﺎ ﺗﻌﺮﻳﻒ ﺑﺴﻴﺎر ﺳﺎده اي از ﻳﻚ ﻣﺘﺪ اﺳﺖ .ﺗﻌﺮﻳﻒ ﻛﺎﻣﻞ ﻣﺘﺪ ﻛﻪ ﻓﻘﻂ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷـﻴﺊ ﮔـﺮا ﺻـﺎدق اﺳـﺖ، ﻋﺒﺎرت اﺳﺖ از ﻛﺪ ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ﻳﻚ ﺷﻴﺊ ﻣﻲ ﮔﻮﻳﻨﺪ ﭼﮕﻮﻧﻪ وﻇﻴﻔﻪ ﻣﺸﺨﺼﻲ را اﻧﺠﺎم دﻫﺪ. Encapsulation
1
٣٣٣
ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي روﺷﻦ ﻛﺮدن ﻳﻚ ﺗﻠﻮﻳﺰﻳﻮن ﺑﺎﻳﺪ ﻣﺘﺪي را ﭘﻴﺪا ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ ﻛﺎر را اﻧﺠﺎم دﻫﺪ ،زﻳﺮا ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ اﻳﻦ ﻣﺘـﺪﻫﺎ ﻫـﺴﺘﻨﺪ ﻛﻪ ﺑﻪ ﻳﻚ ﺷﻴﺊ ﻣﻲ ﮔﻮﻳﻨﺪ ﭼﮕﻮﻧﻪ ﻳﻚ وﻇﻴﻔﻪ ﻣﺸﺨﺺ را اﻧﺠﺎم دﻫﻨﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛﺎر را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﺪ ،ﻓﺮض ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﺷﻴﺊ ﺑﻪ واﺳﻄﻪ اﻳﻦ ﻣﺘﺪ ﻣﻲ داﻧﺪ ﻛﻪ ﭼﮕﻮﻧﻪ درﺧﻮاﺳﺖ ﺷﻤﺎ را اﻧﺠﺎم دﻫﺪ. ﺧﺎﺻﻴﺖ ﻫﺎ ﻧﻴﺰ ﺑﺮاي ﺗﻨﻈﻴﻢ ﺣﺎﻟﺘﻬﺎ و وﻳﮋﮔﻴﻬﺎي ﻳﻚ ﺷﻴﺊ ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ .در اﻳﻦ ﻣﻮرد ﻧﻴﺰ وﻇﻴﻔﻪ ﺷﻴﺊ اﺳﺖ ﻛﻪ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﺣﺎﻟﺘﻲ ﻛـﻪ ﺑﺮاي آن ﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ ﻋﻤﻞ ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﻛﺎﻧﺎل ﻳﻚ ﺗﻠﻮﻳﺰﻳﻮن را از 4ﺑﻪ 3ﺗﻐﻴﻴﺮ دﻫﻴﺪ ،ﻛﺎﻓﻲ اﺳﺖ ﻣﻘـﺪار ﺧﺎﺻﻴﺖ ﻣﺮﺑﻮط ﺑﻪ ﻛﺎﻧﺎل را ﺑﺮاﺑﺮ ﺑﺎ 3ﻗﺮار دﻫﻴﺪ و ﺗﻠﻮﻳﺰﻳﻮن ﺑﺎﻳﺪ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ ،ﺗﺼﻮﻳﺮ را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﺑﻪ ﺧﺎﻃﺮ دارﻳﺪ ﻫﻨﮕﺎم ﻛﺎر ﺑﺎ ﺷﻴﺊ OpenFileDialogدر ﺑﺨﺶ ﻛﺎدرﻫﺎي ﻣﺤﺎوره اي ،ﻛﺎﻓﻲ ﺑﻮد ﻛـﻪ ﺧﺎﺻـﻴﺖ ﻣﺮﺑﻮط ﺑﻪ ﻣﺘﻦ ﻧﻮار ﻋﻨﻮان آن را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺪار دﻟﺨﻮاه ﻗﺮار دﻫﻴﺪ .ﺑﻌﺪ از آن ،وﻇﻴﻔﻪ ﺷﻴﺊ OpenFileDialogﻣﺤـﺴﻮب ﻣـﻲ ﺷﺪ ﺗﺎ ﻣﺘﻦ ﻣﺸﺨﺺ ﺷﺪه را در ﻧﻮار ﻋﻨﻮان ﻧﻤﺎﻳﺶ دﻫﺪ.
روﻳﺪادﻫﺎ: روﻳﺪادﻫﺎ ﺑﻪ ﻋﻨﻮان ﻋﻀﻮي از اﺷﻴﺎ ﻫﺴﺘﻨﺪ ﻛﻪ ﭘﻴﻐﺎﻣﻲ را آﻣﺎده ﻛﺮده و ﺑﻪ دﻳﮕﺮ ﺑﺨﺸﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﻓﺮﺳﺘﻨﺪ .زﻣﺎﻧﻲ ﻛﻪ ﻳـﻚ ﻣـﻮرد ﻗﺎﺑـﻞ ﺗﻮﺟﻪ ﺑﺮاي ﻳﻚ ﺷﻴﺊ رخ داد ،آن ﺷﻴﺊ روﻳﺪادي را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﻪ وﺳﻴﻠﻪ ﻳﻚ ﭘﻴﻐﺎم ،ﺑﺨﺸﻬﺎي دﻳﮕـﺮ ﺑﺮﻧﺎﻣـﻪ را از اﻳﻦ روﻳﺪاد ﻣﻄﻠﻊ ﻛﺮده و ﻫﻤﭽﻨﻴﻦ اﻃﻼﻋﺎت ﻻزم را ﻧﻴﺰ در ﻣﻮرد اﻳﻦ روﻳﺪاد در اﺧﺘﻴﺎر اﻳﻦ ﺑﺨﺸﻬﺎ ﻗﺮار ﻣﻲ دﻫـﺪ .اﻳـﻦ ﭘﻴﻐـﺎم ﻓﻘـﻂ ﺑـﻪ ﻗﺴﻤﺘﻬﺎﻳﻲ از ﺑﺮﻧﺎﻣﻪ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد ﻛﻪ ﭘﻴﺶ از اﺗﻔﺎق اﻓﺘﺎدن روﻳﺪاد ،از ﺑﺮﻧﺎﻣﻪ درﺧﻮاﺳﺖ ﻛﺮده ﺑﺎﺷﻨﺪ ﺗﺎ اﻳﻦ ﻣـﻮرد را ﺑـﻪ آﻧﻬـﺎ اﻃـﻼع دﻫﺪ. ﺑﻪ ﻋﻨﻮان ﻣﺜﺎل روﻳﺪاد Clickرا ﻛﻪ در ﺑﺨﺸﻬﺎي ﻗﺒﻠﻲ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ در ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ .اﻳﻦ روﻳﺪاد زﻣﺎﻧﻲ رخ ﻣﻲ دﻫﺪ ﻛـﻪ ﻛﺎرﺑﺮ ﻣﺎوس را روي ﻛﻨﺘﺮل ﺑﺮده و در آﻧﺠﺎ ﻛﻠﻴﻚ ﻛﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺷﻴﺊ Buttonﺗﻤﺎم اﺷـﻴﺎي ﻻزم را از رخ دادن اﻳـﻦ روﻳـﺪاد ﻣﻄﻠﻊ ﻣﻲ ﻛﻨﺪ .ﺑﺮاي اﻳﻨﻜﻪ ﺷﻴﺊ اي از اﻳﻦ روﻳﺪاد ﻣﻄﻠﻊ ﺷﻮد ،ﺑﺎﻳﺪ ﻗﺒﻞ از آن ﺑﻪ ﺷـﻴﺊ Buttonﺑﮕﻮﻳـﺪ در ﺻـﻮرت رخ دادن اﻳـﻦ روﻳﺪاد ﺑﻪ آن ﻧﻴﺰ اﻃﻼع داده ﺷﻮد. روش اﻳﻦ ﻛﺎر را در ﻓﺼﻠﻬﺎي ﻗﺒﻞ ﻧﻴﺰ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ .ﺑﺮاي اﺳﺘﻔﺎده از اﻳﻦ روﻳﺪاد اﺑﺘﺪا ﺗﺎﺑﻌﻲ را ﺑﺎ ﻗﺎﻟﺒﻲ ﺧﺎص اﻳﺠﺎد ﻣﻲ ﻛﺮدﻳﻢ و ﺳﭙﺲ ﺑﻪ ﺷﻴﺊ Buttonاﻃﻼع ﻣﻲ دادﻳﻢ ﻛﻪ در ﺻﻮرت وﻗﻮع اﻳﻦ روﻳﺪاد ،ﺗﺎﺑﻊ ﻣﺸﺨﺺ ﺷﺪه را اﺟﺮا ﻛﻨـﺪ )اﻟﺒﺘـﻪ ﺑﻴـﺸﺘﺮ اﻳـﻦ ﻛﺎرﻫـﺎ ﺑـﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺗﻮﺳﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻧﺠﺎم ﻣﻲ ﺷﺪ( .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي ﻛﻨﺘﺮل Buttonﻛﻠﻴـﻚ ﻣـﻲ ﻛـﺮد ،اﻳـﻦ ﻛﻨﺘـﺮل ﺗﻮاﺑﻌﻲ ﻛﻪ ﻣﺸﺨﺺ ﺷﺪه ﺑﻮدﻧﺪ را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﺮد و ﻫﻤﭽﻨﻴﻦ اﻃﻼﻋﺎت ﻣﻮرد ﻧﻴﺎز آﻧﻬﺎ را ﻧﻴﺰ ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ آﻧﻬﺎ ارﺳﺎل ﻣﻲ ﻛﺮد.
ﻗﺎﺑﻞ روﻳﺖ ﺑﻮدن: ﻳﻜﻲ از وﻳﮋﮔﻴﻬﺎي ﺷﻴﺊ اي ﻛﻪ ﺧﻮب ﻃﺮاﺣﻲ ﺷﺪه اﺳﺖ ،اﻳﻦ اﺳﺖ ﻛﻪ اﺳﺘﻔﺎده از آن راﺣﺖ ﺑﺎﺷﺪ .ﺑﺮاي ﻣﺜﺎل اﮔـﺮ ﺑﺨﻮاﻫﻴـﺪ ﻳـﻚ ﺷـﻴﺊ ﺗﻠﻮﻳﺰﻳﻮن ﻃﺮاﺣﻲ ﻛﻨﻴﺪ ﺑﺎﻳﺪ ﺑﺪاﻧﻴﺪ ﻛﻪ ﭼﻪ ﻓﺮﻛﺎﻧﺴﻲ ﺑﺮاي اﻳﻦ ﺷﻴﺊ ﻣﻮرد ﻧﻴﺎز اﺳﺖ .اﻣﺎ آﻳﺎ ﻓﺮدي ﻛﻪ از ﺗﻠﻮﻳﺰﻳﻮن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ ﻧﻴﺰ ﺑﺎﻳﺪ اﻳﻦ ﻣﻮرد را ﺑﺪاﻧﺪ؟ و ﻳﺎ ﺣﺘﻲ ﻣﻬﻤﺘﺮ اﻳﻨﻜﻪ آﻳﺎ ﻣﻲ ﺗﻮان ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه داد اﻳﻦ ﻣﻘﺪار ﻓﺮﻛﺎﻧﺲ را ﺑﻪ ﺻﻮرت ﻣﺴﺘﻘﻴﻢ ﺗﻐﻴﻴﺮ دﻫﺪ. ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﻳﻚ ﺷﻴﺊ ﻫﻤﻮاره ﺑﺨﺸﻬﺎﻳﻲ از آن ﺑﻪ ﺻﻮرت ﺷﺨﺼﻲ و ﺑﺨﺸﻬﺎي دﻳﮕﺮي ﺑﻪ ﺻﻮرت ﻋﻤﻮﻣﻲ ﻫﺴﺘﻨﺪ .ﺑﺨﺸﻬﺎي ﻋﻤـﻮﻣﻲ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺗﻮﺳﻂ ﻫﻤﻪ ﻛﺎرﺑﺮان ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮﻧﺪ ،اﻣﺎ ﺑﺨﺸﻬﺎي ﺷﺨﺼﻲ ﻓﻘﻂ ﺗﻮﺳﻂ ﺧﻮد ﺷﻴﺊ ﻗﺎﺑﻞ دﺳﺘﺮﺳـﻲ ﻫـﺴﺘﻨﺪ .ﻣﻨﻄـﻖ و روﺷﻲ ﻛﻪ ﺷﻴﺊ ﺑﺎ آن ﻛﺎر ﻣﻲ ﻛﻨﺪ ﻣﻌﻤﻮﻻ در ﺑﺨﺸﻬﺎي ﺷﺨﺼﻲ ﺷﻴﺊ ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ و ﻣﻲ ﺗﻮاﻧﺪ ﺷﺎﻣﻞ ﻣﺘﺪﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﺑﺎﺷﺪ ﻛﻪ ﺑﺮاي ﻋﻤﻠﻜﺮد ﺷﻴﺊ ﻣﻬﻢ ﻫﺴﺘﻨﺪ وﻟﻲ ﻧﺒﺎﻳﺪ ﺗﻮﺳﻂ ﻛﺎرﺑﺮان ﺑﻪ ﻃﻮر ﻣﺴﺘﻘﻴﻢ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد.
٣٣٤
ﺑﺮاي ﻣﺜﺎل ﻳﻚ ﺗﻠﻮﻳﺰﻳﻮن ﻣﻤﻜﻦ اﺳﺖ داراي ﻣﺘﺪ ﻫﺎﻳﻲ ﺑﺮاي وﺻﻞ ﻛﺮدن ﺑﺮق ﺑﻪ اﺟﺰا ،ﺟﺮﻳﺎن دادن ﺑﺮق در ﻣﺪارﻫﺎ و … ﺑﺎﺷﺪ .اﻣـﺎ اﻳـﻦ ﻣﺘﺪﻫﺎ ﻧﺒﺎﻳﺪ ﺗﻮﺳﻂ ﻛﺎرﺑﺮ ﺑﻪ ﻃﻮر ﻣﺴﺘﻘﻴﻢ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮﻧﺪ ،ﺑﻠﻜﻪ ﻛﺎرﺑﺮ ﺑﺎﻳﺪ ﻣﺘﺪ SwitchOnرا ﺑﺮاي روﺷﻦ ﺷﺪن دﺳﺘﮕﺎه ﻓﺮاﺧـﻮاﻧﻲ ﻛﻨﺪ ،ﺳﭙﺲ اﻳﻦ ﻣﺘﺪ ﺑﺎﻳﺪ ﺑﻪ ﺗﺮﺗﻴﺐ ﻣﺘﺪﻫﺎي ﮔﻔﺘﻪ ﺷﺪه را اﺳﺘﻔﺎده ﻛﺮده و ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ دﺳﺘﮕﺎه را روﺷﻦ ﻛﻨﺪ .ﺑﻪ ﻋﻨﻮان ﻣﺜﺎﻟﻲ دﻳﮕـﺮ ،در ﺷﻴﺊ ﺗﻠﻮﻳﺰﻳﻮن ﻳﻚ ﺧﺎﺻﻴﺖ ﻋﻤﻮﻣﻲ ﺑﻪ ﻧﺎم ﻛﺎﻧﺎل وﺟﻮد دارد ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﺧﺎﺻﻴﺖ ﺧﺼﻮﺻﻲ ﺑﻪ ﻧﺎم ﻓﺮﻛﺎﻧﺲ ﻛﺎر ﻣـﻲ ﻛﻨـﺪ .ﺗـﺎ زﻣﺎﻧﻲ ﻛﻪ ﺗﻠﻮﻳﺰﻳﻮن ﻧﺪاﻧﺪ ﺑﺮاي ﻫﺮ ﻛﺎﻧﺎل ﺑﺎﻳﺪ از ﭼﻪ ﻓﺮﻛﺎﻧﺴﻲ اﺳﺘﻔﺎده ﻛﻨﺪ ،ﻧﻤﻲ ﺗﻮاﻧﺪ آﻧﻬﺎ را ﻧﻤﺎﻳﺶ دﻫﺪ .اﻣﺎ ﻛﺎرﺑﺮ ﺗﻠﻮﻳﺰﻳـﻮن ﻧﺒﺎﻳـﺪ ﺑـﻪ ﻃﻮر ﻣﺴﺘﻘﻴﻢ ﺑﺘﻮاﻧﺪ ﻓﺮﻛﺎﻧﺲ را ﺗﻐﻴﻴﺮ دﻫﺪ .ﺑﻠﻜﻪ ﺑﺎﻳﺪ ﺑﻪ وﺳﻴﻠﻪ ﺗﻐﻴﻴﺮ ﺧﺎﺻﻴﺖ ﻛﺎﻧﺎل ،ﻣﻮﺟﺐ ﺗﻐﻴﻴﺮ ﻓﺮﻛﺎﻧﺲ ﺷﻮد. ﺣﺎل ﻛﻪ ﺑﺎ ﻣﻔﺎﻫﻴﻢ اﺑﺘﺪاﻳﻲ ﺷﻴﺊ ﮔﺮاﻳﻲ آﺷﻨﺎ ﺷﺪﻳﺪ ،ﺑﻬﺘﺮ اﺳﺖ ﺑﻪ ﺑﺮرﺳﻲ اﺳﺘﻔﺎده از اﻳﻦ ﻣﻮارد در ﺑﺮﻧﺎﻣﻪ ﺑﭙﺮدازﻳﻢ .در اﻏﻠﺐ ﻛﺪ ﻫﺎﻳﻲ ﻛـﻪ در ﻓﺼﻠﻬﺎي ﻗﺒﻞ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ ،ﺧﻄﻲ ﻣﺎﻧﻨﺪ ﻛﺪ زﻳﺮ دﻳﺪه ﻣﻲ ﺷﺪه اﺳﺖ: ;)lstData.Items.Add(strData اﻳﻦ ﻛﺪ ﻧﻤﻮﻧﻪ اي ﻋﺎدي از ﺷﻴﺊ ﮔﺮاﻳﻲ اﺳﺖ .در اﻳﻦ ﻛﺪ lstDataدر ﺣﻘﻴﻘﺖ ﻳﻚ ﺷﻴﺊ و Itemsﻧﻴﺰ ﺧﺎﺻﻴﺘﻲ از اﻳﻦ ﺷـﻴﺊ اﺳﺖ .ﺧﺎﺻﻴﺖ Itemsﺧﻮد ﻧﻴﺰ ﻳﻚ ﺷﻴﺊ اﺳﺖ ﻛﻪ داراي ﻣﺘﺪي ﺑﻪ ﻧﺎم Addاﺳﺖ .ﻋﻼﻣﺖ ﻧﻘﻄﻪ ) (.ﺑﻪ وﻳﮋوال C#ﻣـﻲ ﮔﻮﻳـﺪ ﻛﻪ ﻛﻠﻤﻪ ﺳﻤﺖ راﺳﺖ ،ﻧﺎم ﻋﻀﻮي از ﺷﻴﺊ ﺳﻤﺖ ﭼﭗ اﺳـﺖ .ﺑﻨـﺎﺑﺮاﻳﻦ در اﻳـﻦ ﻛـﺪ Items ،ﻋـﻀﻮي از lstDataو Add ﻋﻀﻮي از Itemsﺑﻪ ﺷﻤﺎر ﻣﻲ رود. lstDataﻳــﻚ ﻧﻤﻮﻧــﻪ از ﻛــﻼس System.Windows.Forms.ListBoxاﺳــﺖ .اﻳــﻦ ﻛــﻼس ﻳﻜــﻲ از ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﭼﺎرﭼﻮب .NETاﺳﺖ ﻛﻪ در ﻓﺼﻞ دوم ﺑﺎ آن آﺷﻨﺎ ﺷﺪﻳﺪ .ﻛﻼس ListBoxﺑﺮاي ﻧﻤﺎﻳﺶ ﻟﻴﺴﺘﻲ از ﻋﻨﺎﺻﺮ در ﻓﺮم ﺑﻪ ﻛﺎر ﻣﻲ رود و ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻣﻲ دﻫﺪ ﻛﻪ ﻋﻨﺎﺻﺮي را از آن اﻧﺘﺨﺎب ﻛﻨﺪ .اﮔﺮ دﻗﺖ ﻛﻨﻴﺪ ﻧﻤﻮﻧﻪ ﻫﺎي زﻳﺎدي از ﻛﭙﺴﻮﻟﻲ ﺑـﻮدن را در اﻳﻦ ﻛﻼس ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد .ﺷﻤﺎ ﺑﻪ ﻋﻨﻮان ﻳﻜﻲ از ﻛﺎرﺑﺮان اﻳﻦ ﻛﻼس ،ﻧﻴﺎزي ﻧﺪارﻳﺪ ﻛﻪ ﺑﺪاﻧﻴﺪ ﺑﺮاي ﻧﻤﺎﻳﺶ ﻟﻴﺴﺘﻲ از ﻋﻨﺎﺻﺮ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ و ﻳﺎ درﻳﺎﻓﺖ ورودي ﻛﺎرﺑﺮ از ﭼﻪ ﺗﻜﻨﻮﻟﻮژﻳﻬﺎﻳﻲ ﺑﺎﻳﺪ اﺳﺘﻔﺎده ﻛـﺮد .ﺣﺘـﻲ ﻣﻤﻜـﻦ اﺳـﺖ ﺗـﺎﻛﻨﻮن ﻧـﺎم ﻣـﻮاردي ﻣﺎﻧﻨـﺪ ،stdin ،GDI+دراﻳﻮرﻫﺎي ﻛﻴﺒﻮرد ،دراﻳﻮرﻫﺎي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ و ﻳﺎ ﺑﺴﻴﺎري از ﺗﻜﻨﻮﻟﻮژﻳﻬﺎي ﭘﻴﭽﻴﺪه دﻳﮕﺮي ﻛﻪ در اﻳـﻦ ﻛـﻼس ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ را ﻧﻴﺰ ﻧﺸﻨﻴﺪه ﺑﺎﺷﻴﺪ .اﻣﺎ ﺑﻪ راﺣﺘﻲ ﻣﻲ ﺗﻮاﻧﻴﺪ از اﻳﻦ ﻛﻼس اﺳـﺘﻔﺎده ﻛـﺮده و ﻋﻨﺎﺻـﺮ ﻣـﻮرد ﻧﻈﺮﺗـﺎن را ﺑـﻪ ﺻﻮرت ﻟﻴﺴﺖ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﻴﺪ. اﻟﺒﺘﻪ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در اﺑﺘﺪاي ﻓﺼﻞ ﻧﻴﺰ ﮔﻔﺘﻢ ListBox ،ﻳﻜﻲ از اﺷﻴﺎﻳﻲ اﺳﺖ ﻛﻪ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﺷـﺪه اﺳـﺖ .ﻋﻤﻮﻣـﺎً ﻳـﻚ ﺑﺮﻧﺎﻣﻪ از ﺗﻌﺪاد زﻳﺎدي ﺷﻴﺊ ﺗﺸﻜﻴﻞ ﻣﻲ ﺷﻮد ﻛﻪ ﻓﻘﻂ ﺑﻌﻀﻲ از آﻧﻬﺎ ﻫﻤﺎﻧﻨﺪ ﺷﻴﺊ ListBoxﻗﺎﺑﻞ ﻣﺸﺎﻫﺪه ﻫـﺴﺘﻨﺪ .اﺷـﻴﺎي ﺑـﺴﻴﺎر دﻳﮕﺮي ﻧﻴﺰ ﻫﺴﺘﻨﺪ ﻛﻪ در اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻘﺶ دارﻧﺪ ،اﻣﺎ از ﻧﻈﺮ ﻛﺎرﺑﺮ ﭘﻨﻬﺎن ﻫﺴﺘﻨﺪ و در ﺣﺎﻓﻈﻪ وﻇﻴﻔﻪ ﺧﻮد را اﻧﺠﺎم ﻣﻲ دﻫﻨﺪ.
ﻳﻚ ﻛﻼس ﭼﻴﺴﺖ؟ ﻛﻼس ﺗﻌﺮﻳﻔﻲ اﺳﺖ ﻛﻪ ﺑﺮاي ﻳﻚ ﻧﻮع ﺧﺎص از ﺷﻴﺊ ﺑﻪ ﻛﺎر ﻣﻲ رود .ﻛﻼﺳﻬﺎ را ﻋﻤﻮﻣﺎً در دﻧﻴﺎي واﻗﻌـﻲ ﻧﻤـﻲ ﺗـﻮان ﻧـﺸﺎن داد .ﺑـﺮاي ﻧﻤﻮﻧﻪ ،ﻣﺜﺎل ﺗﻠﻮﻳﺰﻳﻮن در ﺑﺨﺶ ﻗﺒﻞ را در ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ .در دﻧﻴﺎي واﻗﻌﻲ ﻫﻴﭽﮕﺎه ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﺷﻴﺊ اي را ﻣـﺸﺨﺺ ﻛﻨﻴـﺪ و ﺑﮕﻮﻳﻴـﺪ ﻛـﻪ "اﻳﻦ ﺗﻠﻮﻳﺰﻳﻮن اﺳﺖ" .ﺑﻠﻜﻪ ﻫﻤﻮاره ﻣﻲ ﺗﻮاﻧﻴﺪ ﺷﻴﺊ اي را ﻣﺸﺨﺺ ﻛﻨﻴﺪ و ﺑﮕﻮﻳﻴﺪ "اﻳﻦ ﻳﻚ ﻧﻤﻮﻧﻪ از ﺗﻠﻮﻳﺰﻳﻮن اﺳﺖ" .زﻳـﺮا ﻫﻤـﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ،ﺗﻠﻮﻳﺰﻳﻮن ﻳﻚ ﺗﻌﺮﻳﻒ اﺳﺖ و ﻧﻤﻲ ﺗﻮان در دﻧﻴﺎي واﻗﻌﻲ آن را ﻧﻤﺎﻳﺶ داد .ﺑﻠﻜﻪ ﺑﺎﻳﺪ اﺑﺘﺪا آن را ﻧﻤﻮﻧﻪ ﺳﺎزي ﻛﺮد. در دﻧﻴﺎي ﻧﺮم اﻓﺰار ﻧﻴﺰ ﻛﻼﺳﻬﺎ ﺑﻪ ﻫﻤﻴﻦ ﺻﻮرت ﻫﺴﺘﻨﺪ .ﻳﻚ ﻛﻼس از ﻛﺪﻫﺎي ﻻزم ﺑﺮاي ذﺧﻴﺮه و ﻧﮕﻬﺪاري ﻣﻘﺎدﻳﺮ ﺧﺎﺻﻴﺖ ﻫﺎ ،اﻧﺠـﺎم دادن ﻣﺘﺪﻫﺎ ،ﺗﻌﻴﻴﻦ زﻣﺎن رخ دادن روﻳﺪادﻫﺎ و … ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ .اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻳﻚ ﺷﻴﺊ ﻧﺮم اﻓﺰاري اﻳﺠﺎد ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ ﺑﺪاﻧﻴﺪ ﻛﻪ درون آن ﺷﻴﺊ دﻗﻴﻘﺎً ﺑﺎﻳﺪ ﭼﮕﻮﻧﻪ ﻛﺎر ﻛﻨﺪ .ﺳﭙﺲ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛﺎرﻛﺮد را ﺑﻪ وﺳﻴﻠﻪ ﻳﻚ زﺑـﺎن ﺑﺮﻧﺎﻣـﻪ ﻧﻮﻳـﺴﻲ ﻣﺎﻧﻨـﺪ C#در ﻗﺎﻟـﺐ ﻳـﻚ ﻛﻼس ﻣﻲ ﻧﻮﻳﺴﻴﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ دﻳﮕﺮي ﺑﺨﻮاﻫﺪ از ﺷﻴﺊ ﻛﻪ اﻳﺠﺎد ﻛﺮده اﻳﺪ اﺳﺘﻔﺎده ﻛﻨﺪ ،ﻓﻘﻂ ﺑﻪ اﻳﻦ ﺷـﻴﺊ ﻣـﻲ
٣٣٥
ﮔﻮﻳﺪ ﻛﻪ "ﺻﺪا را زﻳﺎد ﻛﻦ" .در اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﺎﻳﺪ ﺑﻪ ﻋﻨﻮان ﻛﺴﻲ ﻛﻪ اﻳﻦ ﺷﻴﺊ را اﻳﺠﺎد ﻛﺮده اﺳﺖ ﺑﺪاﻧﻴﺪ ﭼﮕﻮﻧﻪ ﺑﻪ آﻣﭙﻠـﻲ ﻓـﺎﻳﺮ دﺳـﺘﻮر دﻫﻴﺪ ﻛﻪ ﺧﺮوﺟﻲ ﺻﺪا را زﻳﺎد ﻛﻨﺪ. ﻧﻜﺘﻪ :در ﻣﺜﺎل ﺑﺎﻻ ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﺧﻮد آﻣﭙﻠﻲ ﻓﺎﻳﺮ ﻧﻴﺰ ﻳﻚ ﺷﻴﺊ اﺳﺖ ،ﺑﻨﺎﺑﺮاﻳﻦ ﻻزم ﻧﻴﺴﺖ دﻗﻴﻘﺎً ﺑﺪاﻧﻴﺪ ﻛـﻪ آﻣﭙﻠـﻲ ﻓـﺎﻳﺮ ﺑـﻪ ﺻـﻮرت دروﻧﻲ ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ .در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا ،ﻳﻚ ﺷﻴﺊ ﻣﻌﻤﻮﻻ از ﭼﻨﺪﻳﻦ ﺷﻴﺊ دﻳﮕﺮ ﺑﻪ اﺿﺎﻓﻪ ﻣﻘﺪاري ﻛﺪ ﺑﺮاي اﻳﺠﺎد ارﺗﺒـﺎط ﺑﻴﻦ آﻧﻬﺎ ﺗﺸﻜﻴﻞ ﻣﻲ ﺷﻮد ،ﻫﻤﺎﻧﻄﻮر ﻛﻪ در دﻧﻴﺎي واﻗﻌﻲ ﻧﻴﺰ ﻳﻚ ﺗﻠﻮﻳﺰﻳﻮن از ﭼﻨﺪﻳﻦ ﻗﺴﻤﺖ ﻋﺎدي ﺑﻪ اﺿﺎﻓﻪ ﻣﻘﺪاري ﻣﺪار ﺑـﺮاي اﻳﺠـﺎد ارﺗﺒﺎط ﺑﻴﻦ آن ﻗﺴﻤﺘﻬﺎ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ. ﻫﺮ ﺷﻴﺊ ي ﻛﻪ از ﻳﻚ ﻛﻼس اﻳﺠﺎد ﺷﻮد ،ﺑﻪ ﻋﻨﻮان ﻧﻤﻮﻧﻪ اي از آن ﻛﻼس در ﻧﻈـﺮ ﮔﺮﻓﺘـﻪ ﻣـﻲ ﺷـﻮد .ﺑﻨـﺎﺑﺮاﻳﻦ اﮔـﺮ 50ﻋـﺪد ﺷـﻴﺊ ﺗﻠﻮﻳﺰﻳﻮن داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،در ﺣﻘﻴﻘﺖ 50ﻧﻤﻮﻧﻪ از ﻛﻼس ﺗﻠﻮﻳﺰﻳﻮن دارﻳﺪ .ﻋﻤﻞ اﻳﺠﺎد ﻳﻚ ﻧﻤﻮﻧﻪ ﺟﺪﻳﺪ از ﻳﻚ ﻛﻼس را ﻧﻤﻮﻧﻪ ﺳـﺎزي ﻣﻲ ﮔﻮﻳﻨﺪ .از اﻳﻦ ﺑﻪ ﺑﻌﺪ ﺧﻮاﻫﻴﻢ ﮔﻔﺖ ﻛﻪ "ﻳﻚ ﻛﻼس اﻳﺠﺎد ﻛﻨﻴﺪ" اﻣﺎ در ﻣﻮرد اﺷﻴﺎ ﻣﻲ ﮔﻮﻳﻴﻢ "ﻳﻚ ﺷـﻴﺊ را ﻧﻤﻮﻧـﻪ ﺳـﺎزي ﻛﻨﻴـﺪ" )اﻟﺒﺘﻪ اﻳﻦ ﺗﻔﺎوت در ﮔﻔﺘﺎر ﻓﻘﻂ ﺑﺮاي رﻓﻊ اﺑﻬﺎم اﺳﺖ( .اﻳﺠﺎد ﻳﻚ ﻛﻼس در زﻣﺎن ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ،زﻣﺎﻧﻲ ﻛﻪ در ﺣﺎل ﻧﻮﺷﺘﻦ ﻛـﺪ ﺑﺮﻧﺎﻣـﻪ ﻫﺴﺘﻴﺪ ﺻﻮرت ﻣﻲ ﮔﻴﺮد .اﻣﺎ ﻧﻤﻮﻧﻪ ﺳﺎزي اﺷﻴﺎ از ﻛﻼس در زﻣﺎن اﺟﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﺨﻮاﻫﺪ از آن ﺷﻴﺊ اﺳﺘﻔﺎده ﻛﻨﺪ ﺻﻮرت ﻣﻲ ﮔﻴﺮد. ﻳﻚ ﻣﺜﺎل ﺧﻮب ﺑﺮاي اﻳﻦ ﻣﻮرد ،ﻣﺜﺎل ﻗﺎﻟﺒﻬﺎي ﻓﻠﺰي اﺳﺖ .ﻓﺮض ﻛﻨﻴﺪ ﻳﻚ ﻗﺎﻟﺐ ﻓﻠﺰي داﻳﺮه اي و ﻣﻘﺪاري ﺧﻤﻴﺮ در اﺧﺘﻴﺎر دارﻳﺪ .ﻗﺎﻟﺐ ﻫﻤﻮاره ﺷﻜﻞ ﺛﺎﺑﺘﻲ دارد و ﺑﻪ ﺗﻨﻬﺎﻳﻲ ﺑﺮاي ﺷﻤﺎ ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﻧﻴﺴﺖ .ﺑﻠﻜﻪ ﺑﺎﻳﺪ ﻣﻘﺪاري ﺧﻤﻴﺮ در آن ﻗﺮار دﻫﻴﺪ ﺗﺎ ﺧﻤﻴﺮ ﻫﺎ ﺑﻪ ﺷﻜﻞ ﻗﺎﻟﺐ درآﻳﻨﺪ .ﺳﭙﺲ از ﺧﻤﻴﺮ ﻫﺎي ﺷﻜﻞ ﮔﺮﻓﺘﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻳﺠﺎد داﻳﺮه ﻫﺎ از ﻧﻈﺮ ﻗﺎﻟﺐ ﻫﻴﭻ ﻣﺤﺪودﻳﺘﻲ وﺟﻮد ﻧﺪارد ،ﺑﻠﻜﻪ ﺑـﻪ ﻫـﺮ اﻧـﺪازه ﻛﻪ ﺧﻤﻴﺮ در اﺧﺘﻴﺎر داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻗﺎﻟﺐ ،داﻳﺮه اﻳﺠﺎد ﻛﻨﻴﺪ .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﻗﺎﻟﺐ ﻫﻴﭻ ﻣﻮﻗـﻊ از ﺑـﻴﻦ ﻧﻤـﻲ رود وﻟـﻲ داﻳﺮه ﻫﺎﻳﻲ ﻛﻪ ﺑﺎ آن اﻳﺠﺎد ﻛﺮده اﻳﺪ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ دﻳﮕﺮ ﻧﻴﺎزي ﺑﻪ آﻧﻬﺎ ﻧﺪاﺷﺘﻪ ﺑﺎﺷﻴﺪ و ﻳﺎ ﺑﺨﻮاﻫﻴﺪ ﺑﻪ وﺳﻴﻠﻪ آﻧﻬـﺎ ﺷـﻜﻞ دﻳﮕـﺮي اﻳﺠـﺎد ﻛﻨﻴﺪ از ﺑﻴﻦ ﻣﻲ روﻧﺪ .ﻛﻼﺳﻬﺎ و اﺷﻴﺎ ﻧﻴﺰ ﭼﻨﻴﻦ راﺑﻄﻪ اي دارﻧﺪ .ﻛﻼﺳﻬﺎ ﺑﻪ ﺻﻮرت ﻳﻚ ﻗﺎﻟﺐ ﻫﺴﺘﻨﺪ و ﺣﺎﻓﻈـﻪ ﻳـﻚ ﻛـﺎﻣﭙﻴﻮﺗﺮ ﻧﻴـﺰ ﺑـﻪ ﺻﻮرت ﺧﻤﻴﺮ ﻫﺎ .ﺑﺮاي اﻳﺠﺎد ﺷﻴﺊ از ﻛﻼس ،ﺧﻮد ﻛﻼس ﻣﺤﺪودﻳﺘﻲ در ﻣﻮرد ﺗﻌﺪاد اﺷﻴﺎي اﻳﺠﺎد ﺷﺪه ﻧﺪارد ،ﺗﻨﻬﺎ ﻣﺤـﺪودﻳﺖ از ﻃـﺮف ﻣﻘﺪار ﺣﺎﻓﻈﻪ ﻣﻮﺟﻮد در ﻛﺎﻣﭙﻴﻮﺗﺮ اﺳﺖ .ﻫﻤﭽﻨﻴﻦ ﻳﻚ ﻛﻼس از اﺑﺘﺪا وﺟﻮد دارد ،اﻣﺎ ﻳﻚ ﺷﻴﺊ ﻓﻘـﻂ ﻫﻨﮕـﺎﻣﻲ وﺟـﻮد دارد ﻛـﻪ ﺑﺨﻮاﻫـﺪ اﺳﺘﻔﺎده ﺷﻮد .ﺑﻌﺪ از اﺗﻤﺎم ﻛﺎر آن ،ﺷﻴﺊ از ﺣﺎﻓﻈﻪ ﭘﺎك ﻣﻲ ﺷﻮد. ﻫﻨﮕﺎﻣﻲ ﻛﻪ در زﻣﺎن اﺟﺮاي ﺑﺮﻧﺎﻣﻪ از ﻳﻚ ﻛﻼس ﻧﻤﻮﻧﻪ ﺳﺎزي ﻛﺮدﻳﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﺧﺎﺻﻴﺘﻬﺎي ﻧﻤﻮﻧﻪ اﻳﺠﺎد ﺷﺪه را ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ،ﻣﺘـﺪﻫﺎي آن را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ و … .ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ ﻛﻪ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻛﻼﺳﻲ ﺑﺮاي ﺗﻠﻮﻳﺰﻳﻮن اﻳﺠﺎد ﻛﺮده اﻳﺪ .در زﻣﺎن اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣـﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻫﺮ ﺗﻌﺪاد ﻛﻪ ﺑﺨﻮاﻫﻴﺪ از اﻳﻦ ﻛﻼس ﻧﻤﻮﻧﻪ ﺳﺎزي ﻛﻨﻴﺪ .ﺳﭙﺲ ﺑﺮاي ﻣﺜﺎل ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ SwitchOnاز ﻳﻜـﻲ از ﻧﻤﻮﻧـﻪ ﻫﺎ ،آن ﻧﻤﻮﻧﻪ از ﺗﻠﻮﻳﺰﻳﻮن را روﺷﻦ ﻛﻨﻴﺪ و ﻳﺎ ﺑﺎ ﺗﻨﻈﻴﻢ ﺧﺎﺻﻴﺖ Channelﻳﻜﻲ از ﻧﻤﻮﻧﻪ ﻫﺎ ،ﻛﺎﻧﺎل آن ﻧﻤﻮﻧﻪ از ﺗﻠﻮﻳﺰﻳـﻮن را ﺗﻐﻴﻴـﺮ دﻫﻴﺪ.
1
اﻳﺠﺎد ﻛﻼﺳﻬﺎ: در ﻓﺼﻠﻬﺎي ﻗﺒﻠﻲ ﺑﻪ ﻛﺮّات ﻛﻼس ﻫﺎﻳﻲ اﻳﺠﺎد ﻛﺮده و از آن در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻧﻤﻮﻧﻪ اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ .ﺑﻪ ﻃﻮر ﻛﻠﻲ ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻟﮕﻮرﻳﺘﻢ ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﻃﺮاﺣﻲ ﻛﺮدﻳﺪ ،اﺷﻴﺎي زﻳﺎدي در دﻧﻴﺎي واﻗﻌﻲ در آن دﻳﺪه ﻣﻲ ﺷﻮﻧﺪ .ﺑﺮاي ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﺗﻤﺎم اﻳﻦ اﺷﻴﺎي واﻗﻌﻲ را ،ﺑﻪ اﺷﻴﺎي در ﺑﺮﻧﺎﻣﻪ ﺧﻮدﺗﺎن ﺗﺒﺪﻳﻞ ﻛﻨﻴﺪ .ﺑﻪ ﻣﺜﺎل زﻳﺮ ﺗﻮﺟﻪ ﻛﻨﻴﺪ:
Instantiation
1
٣٣٦
ﻟﻴﺴﺘﻲ ﻣﺸﺘﻤﻞ ﺑﺮ 10ﻛﺎرﺑﺮ را از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﻧﺘﺨﺎب ﻛﻦ. از اوﻟﻴﻦ ﻛﺎرﺑﺮ اﻧﺘﺨﺎب ﺷﺪه ﺷﺮوع ﻛﻦ و ﺑﺮاي ﻫﺮ ﻳﻚ ﺻﻮرت ﺣﺴﺎب او را آﻣﺎده ﻛﻦ. زﻣﺎﻧﻲ ﻛﻪ ﻫﺮ ﻳﻚ از ﺻﻮرت ﺣﺴﺎب ﻫﺎ آﻣﺎده ﺷﺪﻧﺪ ،ﺑﺎ اﺳﺘﻔﺎده از ﭼﺎﭘﮕﺮ آن را ﭼﺎپ ﻛﻦ.
ﺑﺮاي اﻳﻨﻜﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻃﻮر ﻛﺎﻣﻞ ﺷﻴﺊ ﮔﺮا ﺑﺎﺷﺪ ،ﺑﺎﻳﺪ ﻫﺮ ﺷﻴﺊ ﻛﻪ در دﻧﻴﺎي واﻗﻌﻲ آن ﺑﺮﻧﺎﻣـﻪ وﺟـﻮد دارد ،ﺑـﻪ ﺷـﻴﺊ در آن ﺑﺮﻧﺎﻣـﻪ ﺗﺒﺪﻳﻞ ﺷﻮد .ﺑﺮاي ﻣﺜﺎل:
:Customerﻳﻚ ﺷﻴﺊ ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن ﻛﺎرﺑﺮ.
:Billﻳﻚ ﺷﻴﺊ ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن ﺻﻮرت ﺣﺴﺎب اﻳﺠﺎد ﺷﺪه.
:Printerﻳﻚ ﺷﻴﺊ ﻛﻪ ﻳﻚ ﭼﺎﭘﮕﺮ ﺳﺨﺖ اﻓﺰاري را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ و ﻣﻲ ﺗﻮاﻧﺪ ﺑﺮاي ﭼﺎپ ﺻﻮرت ﺣـﺴﺎب ﻣـﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد.
ﻫﻨﮕﺎﻣﻲ ﻛﻪ از وﻳﮋوال 2005 C#ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴـﺪ ،ﻣﺠﻤﻮﻋـﻪ وﺳـﻴﻌﻲ از ﻛﻼﺳـﻬﺎ را ﺗﺤـﺖ ﻋﻨـﻮان ﻛﺘﺎﺑﺨﺎﻧـﻪ ﻛﻼس ﭼﺎرﭼﻮب 1.NETدر اﺧﺘﻴﺎر دارﻳﺪ .اﻳﻦ ﻛﻼﺳﻬﺎ ﻫﺮ ﭼﻴﺰي ﺑﺮاي ﻣﺤﺎﺳﺒﺎت در ﻣﺤﻴﻄﻲ ﻛـﻪ ﻣـﻲ ﺧﻮاﻫﻴـﺪ ﺑـﺮاي آن ﺑﺮﻧﺎﻣـﻪ ﺑﻨﻮﻳﺴﻴﺪ را ﭘﻮﺷﺶ ﻣﻲ دﻫﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺮاي .NETﺑﻪ ﺳﺎدﮔﻲ اﺳﺘﻔﺎده از ﭼﻨﺪ ﻛﻼس و اﻳﺠﺎد ارﺗﺒﺎط درﺳﺖ ﺑﻴﻦ آﻧﻬـﺎ و ﻳﺎ ﺗﺮﻛﻴﺐ ﭼﻨﺪ ﻛﻼس و اﻳﺠﺎد ﻳﻚ ﻛﻼس ﺟﺪﻳﺪ اﺳﺖ .ﻣﻌﻤﻮﻻً ﻫﻨﮕﺎم ﺳﺎﺧﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ،ﺑﻌﻀﻲ از ﻛﻼﺳﻬﺎي ﻣﻮرد ﻧﻴﺎزﺗﺎن در ﭼﺎرﭼﻮب .NETوﺟﻮد دارﻧﺪ و ﺑﻌﻀﻲ از آﻧﻬﺎ را ﻧﻴﺰ ﺑﺎﻳﺪ ﺧﻮدﺗﺎن اﻳﺠﺎد ﻛﻨﻴﺪ. ﺑﺮاي ﻣﺜﺎل در ﭼﺎرﭼﻮب .NETﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي ﭼﺎپ و ﻳﺎ ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ وﺟﻮد دارد ،ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ در اﻟﮕﻮرﻳﺘﻢ ﺧﻮد ﺑﻪ دﺳﺘﺮﺳﻲ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ و ﻳﺎ ﭼﺎپ اﻃﻼﻋﺎت ﻧﻴﺎز داﺷﺘﻴﺪ ،ﻻزم ﻧﻴﺴﺖ ﻛﻪ ﻛﻼس آﻧﻬـﺎ را ﻣﺠـﺪداً ﺑﻨﻮﻳـﺴﻴﺪ .اﮔـﺮ ﺑﺨﻮاﻫﻴﺪ ﻣﻄﻠﺒﻲ را ﭼﺎپ ﻛﻨﻴﺪ ﻛﺎﻓﻲ اﺳﺖ ﺷﻴﺊ از ﻛﻼس ﻣﺮﺑﻮط ﺑﻪ ﭼﺎپ را ﻧﻤﻮﻧﻪ ﺳﺎزي ﻛﻨﻴﺪ ،ﺑﻪ آن ﺷﻴﺊ ﺑﮕﻮﻳﻴﺪ ﻛﻪ ﭼﻪ ﻣﻄﻠﺒﻲ را ﻣﻲ ﺧﻮاﻫﻴﺪ ﭼﺎپ ﻛﻨﻴﺪ و ﺳﭙﺲ آن ﺷﻴﺊ ﻋﻤﻞ ﭼﺎپ را ﺑﺮاي ﺷﻤﺎ اﻧﺠﺎم ﻣﻲ دﻫﺪ .ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﺑﺪاﻧﻴﺪ ﺷﻴﺊ ﻣﺬﻛﻮر ﭼﮕﻮﻧﻪ ﺳﻨﺪ ﺷﻤﺎ را ﺑـﻪ دﺳﺘﻮرات PostScriptﺗﺒﺪﻳﻞ ﻣﻲ ﻛﻨﺪ و از ﻃﺮﻳﻖ ﭘﻮرت ﻣﺨﺼﻮص ﭼﺎﭘﮕﺮ آن را ﺑﻪ دﺳﺘﮕﺎه ﻣﻲ ﻓﺮﺳﺘﺪ ،ﻓﻘﻂ ﻛﺎﻓﻲ اﺳﺖ ﻧﺤﻮه ﻛﺎرﺑﺮد ﻣﺘﺪﻫﺎ و ﺧﺎﺻﻴﺘﻬﺎي آن را ﺑﺪاﻧﻴﺪ ،ﺑﻘﻴﻪ ﻣﻮارد را ﺧﻮد ﺷﻴﺊ اﻧﺠﺎم ﻣﻲ دﻫﺪ.
ﻗﺎﺑﻠﻴﺖ اﺳﺘﻔﺎده ﻣﺠﺪد: ﻳﻜﻲ از زﻳﺒﺎﺗﺮﻳﻦ ﺟﻨﺒﻪ ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا ﻗﺎﺑﻠﻴﺖ اﺳﺘﻔﺎده ﻣﺠﺪد 2از ﻳﻚ ﻛﺪ اﺳﺖ .ﺑﺮاي درك ﺑﻬﺘﺮ اﻳـﻦ ﻗﺎﺑﻠﻴـﺖ ﺑﻬﺘـﺮ اﺳـﺖ ﻣﺜﺎﻟﻲ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ .ﻓﺮض ﻛﻨﻴﺪ در ﻳﻚ ﺷﺮﻛﺖ ﺧﺪﻣﺎت ﺗﻠﻔﻨﻲ ﻛﺎر ﻣﻲ ﻛﻨﻴﺪ و ﺑﻪ دو ﺑﺮﻧﺎﻣﻪ ي ﻣﺘﻔﺎوت ﻧﻴﺎز دارﻳـﺪ .ﺑﺮﻧﺎﻣـﻪ اول ﺑـﺮاي ﻛﻨﺘﺮل اﻣﻮر ﻣﺸﺘﺮﻛﻴﻦ ﺗﻠﻔﻦ ﺛﺎﺑﺖ و ﺑﺮﻧﺎﻣﻪ دوم ﺑﺮاي ﻛﻨﺘﺮل اﻣﻮر ﻣﺸﺘﺮﻛﻴﻦ ﺗﻠﻔﻦ ﻫﻤﺮاه اﺳﺖ .در ﻫﺮ ﻛﺪام از اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻧﻴﺎز اﺳﺖ ﻛﻪ از ﻛﻼﺳﻲ ﺑﻪ ﻧﺎم Customerاﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ اﻳﻦ دو ﺑﺮﻧﺎﻣﻪ را ﺑﻨﻮﻳﺴﻴﺪ ،اﺣﺘﻤﺎﻻ ﻫﺮ دو را ﺑﺎ ﻫﻢ ﺷﺮوع ﻧﺨﻮاﻫﻴﺪ ﻛﺮد .از ﺑﺮﻧﺎﻣﻪ اول ﺷﺮوع ﻣﻲ ﻛﻨﻴﺪ ،ﻫﻨﮕﺎﻣﻲ ﻛـﻪ ﺗﻤﺎم ﺷﺪ ﺑﺮﻧﺎﻣﻪ دوم را ﺷﺮوع ﻣﻲ ﻛﻨﻴﺪ .ﺣﺎل ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﺑﺮاي ﻫﺮ ﻛﺪام از آﻧﻬﺎ ﻳﻚ ﻛﻼس Customerﺟﺪاﮔﺎﻧﻪ ﺑﻨﻮﻳـﺴﻴﺪ و ﻳـﺎ ﻳﻚ ﻛﻼس ﻛﻠﻲ ﺑﺮاي Customerدر ﺑﺮﻧﺎﻣﻪ اول ﺑﻨﻮﻳﺴﻴﺪ و در ﺑﺮﻧﺎﻣﻪ ي دوم از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ؟ ﺧﻮب ﻣﺸﺨﺺ اﺳﺖ ﻛﻪ روش دوم ﺑﻬﺘﺮ اﺳﺖ.
.NET Framework Class Library Reusability
1 2
٣٣٧
اﺳﺘﻔﺎده ﻣﺠﺪد از ﻳﻚ ﻛﻼس در ﺣﺎﻟﺖ ﻛﻠﻲ ﻣﻮرد ﺧﻮﺑﻲ ﺑﻪ ﺷﻤﺎر ﻣﻲ رود اﻣﺎ ﭼﻨﺪ ﻧﻜﺘﻪ ﻫﻢ ﺑﺎﻳﺪ ﺑﺮاي اﻳﻦ ﻣﻮرد در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷـﻮد .ﺑـﻪ ﺻﻮرت اﻳﺪه آل اﮔﺮ ﻳﻚ ﻛﻼس Customerرا ﺑﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﻨﻴﺪ و ﺳﭙﺲ در ﺑﺮﻧﺎﻣـﻪ دﻳﮕـﺮي ﺑـﻪ اﺳـﺘﻔﺎده از ﻛﻼﺳـﻲ ﻣﺸﺎﺑﻪ ﻛﻼس Customerﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،ﺑﺎﻳﺪ ﺑﺘﻮاﻧﻴﺪ از ﻛﻼس Customerﻗﺒﻠﻲ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﻣﻤﻜﻦ اﺳـﺖ در ﺑﻌـﻀﻲ ﺷﺮاﻳﻂ ﺑﻪ دﻻﻳﻠﻲ ﻧﺘﻮاﻧﻴﺪ از ﻛﻼس Customerدر ﺑﺮﻧﺎﻣﻪ ﺟﺪﻳﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻟﺒﺘﻪ ﻧﻤﻲ ﺗﻮان دﻻﻳﻞ ﻣـﺸﺨﺺ و ﻗـﺎﻃﻌﻲ را ﺑﻴـﺎن ﻛﺮد و ﮔﻔﺖ ﻛﻪ ﭼﻪ زﻣﺎﻧﻲ ﺷﺮاﻳﻄﻲ ﭘﻴﺶ ﻣﻲ آﻳﻨﺪ ﻛﻪ ﻧﻤﻲ ﺗﻮان از ﻳﻚ ﻛﻼس در ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕﺮ اﺳﺘﻔﺎده ﻛـﺮد .وﻟـﻲ ﻣﻤﻜـﻦ اﺳـﺖ ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﺪ از ﻛﻼس Customerدر ﭼﻨﺪ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﻣﺠﺒﻮر ﺷﻮﻳﺪ آن را ﺑﻪ ﻧﺤﻮي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ ﺑﺴﻴﺎر ﭘﻴﭽﻴـﺪه ﺷﻮد .در اﻳﻦ ﺷﺮاﻳﻂ اﻳﺠﺎد ﭼﻨﺪ ﻛﻼس ﺳﺎده و اﺳﺘﻔﺎده از آﻧﻬﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺨﺼﻮص ﺑﻪ ﺧﻮد ،راﺣﺖ ﺗﺮ از اﻳﺠﺎد ﻳﻚ ﻛﻼس ﭘﻴﭽﻴﺪه و اﺳﺘﻔﺎده از آن در ﭼﻨﺪ ﺑﺮﻧﺎﻣﻪ اﺳﺖ .ﻓﻬﻤﻴﺪن اﻳﻨﻜﻪ ﻳﻚ ﻛﻼس را ﭼﮕﻮﻧﻪ ﺑﺎﻳﺪ ﻧﻮﺷﺖ ﺗﺎ ﻫﻢ ﺳـﺎدﮔﻲ در آن رﻋﺎﻳـﺖ ﺷـﻮد و ﻫـﻢ ﻗﺎﺑﻠﻴـﺖ اﺳﺘﻔﺎده ﻣﺠﺪد ،ﺑﻪ ﺗﺠﺮﺑﻪ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا ﺑﺴﺘﮕﻲ دارد .ﻫﺮﭼﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺑﻴﺸﺘﺮي ﺑﻨﻮﻳﺴﻴﺪ ،ﺑﻬﺘﺮ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﻛـﻼس ﻫـﺎﻳﻲ ﻃﺮاﺣﻲ ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ دو ﻓﺎﻛﺘﻮر در آﻧﻬﺎ ﺑﻪ ﺑﻬﺘﺮﻳﻦ ﻧﺤﻮ رﻋﺎﻳﺖ ﺷﻮﻧﺪ.
ﻃﺮاﺣﻲ ﻳﻚ ﺷﻴﺊ: ﺑﺮ ﺧﻼف ﻣﻄﺎﻟﺒﻲ ﻛﻪ از اﺑﺘﺪاي ﻓﺼﻞ ﺗﺎﻛﻨﻮن ﺑﺮرﺳﻲ ﻛﺮده اﻳﻢ ،ﺑﻪ ﻋﻨﻮان اوﻟﻴﻦ ﭘﺮوژه اﻳﻦ ﻓﺼﻞ ﻧﻤﻲ ﺧﻮاﻫﻴﻢ ﻳﻚ اﻟﮕﻮرﻳﺘﻢ ﺗﻌﺮﻳﻒ ﻛﺮده و ﺳﭙﺲ اﺷﻴﺎي ﻣﻮرد ﻧﻴﺎز آن را اﻳﺠﺎد ﻛﻨﻴﻢ .ﺑﻠﻜﻪ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﺑﺎ اراﺋﻪ ﻳﻚ ﻣﺜﺎل ،ﻛﺎرﺑﺮد ﻣﻄﺎﻟﺒﻲ ﻛﻪ در ﻗـﺴﻤﺘﻬﺎي ﻗﺒـﻞ ﺑـﻪ ﺻـﻮرت ﺗﺌﻮري ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﺷﺪﻳﺪ را در ﻋﻤﻞ ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ .ﻣﺜﺎﻟﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد ،ﻃﺮاﺣﻲ ﻳـﻚ ﻛـﻼس ﺑـﺮاي اﺗﻮﻣﺒﻴـﻞ اﺳﺖ. در ﻣﻮرد ﭼﻨﻴﻦ ﻛﻼﺳﻲ ،اﺻﻮل ﻣﺸﺨﺼﻲ ﻫﺴﺘﻨﺪ ﻛﻪ در اﺑﺘﺪا ﺑﺎﻳﺪ آﻧﻬﺎ را ﺑﺪاﻧﻴﺪ:
ﻇﺎﻫﺮ آن ﭼﮕﻮﻧﻪ اﺳﺖ :ﻇﺎﻫﺮ ﻳﻚ اﺗﻮﻣﺒﻴﻞ ﺷﺎﻣﻞ ﻣﻮاردي ﻣﺎﻧﻨﺪ ﻣﺪل ،رﻧﮓ ،ﺗﻌﺪاد درﻫﺎ و ﻣﻮاردي ﻣﺸﺎﺑﻪ اﺳﺖ .اﻳﻦ ﮔﻮﻧﻪ وﻳﮋﮔﻴﻬﺎي ﻳﻚ اﺗﻮﻣﺒﻴﻞ ﻫﻨﮕﺎم اﻳﺠﺎد ﺷﺪن آن ﺗﻨﻈﻴﻢ ﻣﻲ ﺷﻮد و ﻣﻌﻤﻮﻻً ﺗﺎ اﻧﺘﻬﺎي ﻋﻤﺮ ﺷﻴﺊ ﻧﻴﺰ ﺛﺎﺑﺖ اﺳﺖ. ﺗﻮاﻧﺎﻳﻲ ﻫﺎي آن ﭼﻴﺴﺖ :ﻗﺪرت و اﻧﺪازه ﻣﻮﺗﻮر ،ﺗﺮﻛﻴﺐ و ﺗﻌﺪاد ﺳﻴﻠﻨﺪرﻫﺎ و ﻏﻴﺮه. وﺿﻌﻴﺖ ﻛﻨﻮﻧﻲ آن ﭼﻴﺴﺖ :اﺗﻮﻣﺒﻴﻞ ﺛﺎﺑﺖ اﺳﺖ ،ﺑﻪ ﺟﻠﻮ ﺣﺮﻛﺖ ﻣﻲ ﻛﻨﺪ و ﻳﺎ ﺑﻪ ﻋﻘﺐ ﺣﺮﻛﺖ ﻣﻲ ﻛﻨـﺪ ،ﺳـﺮﻋﺖ و ﺟﻬﺖ آن ﭼﻘﺪر اﺳﺖ؟ 1 ﻣﻮﻗﻌﻴﺖ ﻣﻜﺎﻧﻲ آن ﭼﻴﺴﺖ :ﺷﻴﺊ اﺗﻮﻣﺒﻴﻞ ﻣﻌﻤﻮﻻ داراي ﺷﻴﺊ دﻳﮕﺮي از ﻧﻮع GPSاﺳﺖ ﻛـﻪ ﻣﻮﻗﻌﻴـﺖ ﻣﻜـﺎﻧﻲ آن را ﻧﺴﺒﺖ ﺑﻪ دﻳﮕﺮ اﺷﻴﺎ )ﻣﺜﻼً اﺗﻮﻣﺒﻴﻞ ﻫﺎي دﻳﮕﺮ( ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
ﻋﻼوه ﺑﺮ اﻳﻦ ﻣﻲ ﺧﻮاﻫﻴﺪ اﺷﻴﺎﻳﻲ ﻛﻪ از اﻳﻦ ﻛﻼس ﻧﻤﻮﻧﻪ ﺳﺎزي ﻣﻲ ﺷﻮﻧﺪ ،ﻗﺎﺑﻞ ﻛﻨﺘﺮل ﻧﻴﺰ ﺑﺎﺷﻨﺪ .ﺑﺮاي ﻣﺜﺎل:
ﺑﺘﻮاﻧﻴﺪ ﺳﺮﻋﺖ آن را ﻛﺎﻫﺶ دﻫﻴﺪ. ﺑﺘﻮاﻧﻴﺪ ﺳﺮﻋﺖ آن را اﻓﺰاﻳﺶ دﻫﻴﺪ. ﺑﺘﻮاﻧﻴﺪ ﺟﻬﺖ ﺣﺮﻛﺖ آن را ﺑﻪ ﺳﻤﺖ ﭼﭗ ﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺑﺘﻮاﻧﻴﺪ ﺟﻬﺖ ﺣﺮﻛﺖ آن را ﺑﻪ ﺳﻤﺖ راﺳﺖ ﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺑﺘﻮاﻧﻴﺪ آن را ﻣﺘﻮﻗﻒ ﻛﻨﻴﺪ.
Global Positioning System
1
٣٣٨
ﻫﻤﺎﻧﻄﻮر ﻛﻪ در اﺑﺘﺪاي ﻓﺼﻞ ﮔﻔﺘﻢ ،اﺑﺘﺪا ﺑﺎﻳﺪ ﺳﻪ ﻣﻮرد را در راﺑﻄﻪ ﺑﺎ اﻳﻦ ﻛﻼس ﻣﺸﺨﺺ ﻛﻨﻴﺪ :ﻫﻮﻳﺖ ،ﺣﺎﻟﺖ و رﻓﺘﺎر .ﻓﺮض ﻣﻲ ﻛﻨـﻴﻢ ﻛﻪ ﺟﻨﺒﻪ ﻫﻮﻳﺖ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ و اﺷﻴﺎي اﻳﻦ ﻛﻼس ﻣﻲ داﻧﻨﺪ ﻛﻪ از ﻧﻮع اﺗﻮﻣﺒﻴﻞ ﻫﺴﺘﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻪ ﺑﺮرﺳـﻲ دو ﺟﻨﺒـﻪ دﻳﮕـﺮ، ﻳﻌﻨﻲ ﺣﺎﻟﺖ و رﻓﺘﺎر ﻣﻲ ﭘﺮدازﻳﻢ.
ﺣﺎﻟﺖ: ﺣﺎﻟﺖ ،وﺿﻌﻴﺖ ﻛﻨﻮﻧﻲ ﻳﻚ ﺷﻴﺊ از ﻛﻼس را ﺗﻮﺻﻴﻒ ﻣﻲ ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ،ﻣﻮﻗﻌﻴﺖ و ﺳﺮﻋﺖ اﺗﻮﻣﺒﻴﻞ ﺑﺨﺸﻲ از ﺣﺎﻟﺖ آن ﺑﻪ ﺷﻤﺎر ﻣـﻲ روﻧﺪ .ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﻳﻚ ﻛﻼس ،اﺑﺘﺪا ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻛﻪ ﺑﺮاي داﻧﺴﺘﻦ ﺣﺎﻟﺖ ﻳﻚ ﺷﻴﺊ ﭼﻪ ﻣﻮاردي را ﺑﺎﻳﺪ در ﻧﻈﺮ ﺑﮕﻴﺮﻳـﺪ .ﻫﻨﮕـﺎم ﻃﺮاﺣﻲ ﻛﻼس اﺗﻮﻣﺒﻴﻞ ﺳﺮﻋﺖ آن در ﺗﻌﻴﻴﻦ ﺣﺎﻟﺖ آن اﻫﻤﻴﺖ زﻳﺎدي دارد ،اﻣﺎ ﺑﺮاي ﻃﺮاﺣﻲ ﻛﻼس ،Customerﺳﺮﻋﺖ ﻣﻔﻬﻮﻣﻲ ﻧﺪارد ﺑﻠﻜﻪ آدرس ﻛﺎرﺑﺮ ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﻋﻮاﻣﻞ در ﺣﺎﻟﺖ ﻛﻨﻮﻧﻲ آن ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد. ﺣﺎﻟﺖ ﻳﻚ ﺷﻴﺊ ،ﻣﻌﻤﻮﻻ ﺑﻪ ﺻﻮرت ﻣﻘﺎدﻳﺮي درون آن ﻧﮕﻬﺪاري ﻣﻲ ﺷﻮﻧﺪ .ﺑﻌﻀﻲ از اﻳﻦ ﻣﻘﺎدﻳﺮ ﺑﻪ ﺻﻮرت ﻋﻤـﻮﻣﻲ ) (Publicدر اﺧﺘﻴﺎر ﻛﺎرﺑﺮان ﻗﺮار داده ﻣﻲ ﺷﻮﻧﺪ و ﻛﺎرﺑﺮان ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ وﺳﻴﻠﻪ ﺧﺼﻮﺻﻴﺎت ﻛﻼس آﻧﻬﺎ را ﺗﻐﻴﻴﺮ دﻫﻨﺪ ،ﺑﻌـﻀﻲ دﻳﮕـﺮ ﻧﻴـﺰ ﺑـﻪ ﺻـﻮرت ﺧﺼﻮﺻﻲ ) (Privateﻫﺴﺘﻨﺪ و ﻓﻘﻂ ﺑﻪ وﺳﻴﻠﻪ اﺷﻴﺎي آن ﻛﻼس ﻣﻲ ﺗﻮاﻧﻨﺪ اﺳـﺘﻔﺎده ﺷـﻮﻧﺪ .ﻫﻤﭽﻨـﻴﻦ ﺑﻌـﻀﻲ از ﺣﺎﻟﺘﻬـﺎي ﻳـﻚ ﻛﻼس ﻧﻴﺰ ،ﻓﻘﻂ ﻗﺎﺑﻞ ﺧﻮاﻧﺪن ﻫﺴﺘﻨﺪ و ﻛﺎرﺑﺮ ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺻﻮرت ﻣﺴﺘﻘﻴﻢ آﻧﻬﺎ را ﺗﻐﻴﻴﺮ دﻫﺪ .ﺑـﺮاي ﻣﺜـﺎل اﺗﻮﻣﺒﻴـﻞ ﺧﺎﺻـﻴﺘﻲ ﺑـﻪ ﻧـﺎم ﺳﺮﻋﺖ ﺳﻨﺞ دارد ﻛﻪ ﺳﺮﻋﺖ ﺷﻴﺊ را در ﻫﺮ ﻟﺤﻈﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ .ﻛﺎرﺑﺮ اﺗﻮﻣﺒﻴﻞ ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺪ اﻳﻦ ﺳﺮﻋﺖ را ﺑﺨﻮاﻧﺪ ،اﻣﺎ ﻧﻤﻲ ﺗﻮاﻧـﺪ آن را ﺑﻪ ﻃﻮر ﻣﺴﺘﻘﻴﻢ ﺗﻐﻴﻴﺮ دﻫﺪ – ﺑﺮاي ﺗﻐﻴﻴﺮ آن ﺑﺎﻳﺪ ﺑﻪ وﺳﻴﻠﻪ ﻣﺘﺪﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ Accelerateو ﻳﺎ Breakﺑﺎﻋﺚ اﻓﺰاﻳﺶ و ﻳﺎ ﻛﺎﻫﺶ ﺳﺮﻋﺖ ﺷﻮد.
رﻓﺘﺎر: ﺑﻪ ﻋﻜﺲ اﻟﻌﻤﻞ ﻳﻚ ﺷﻴﺊ از ﻛﻼس در ﻣﻘﺎﺑﻞ درﺧﻮاﺳﺘﻬﺎي ﻛﺎرﺑﺮ ،رﻓﺘﺎر آن ﺷﻴﺊ ﻣﻲ ﮔﻮﻳﻨﺪ .زﻣﺎﻧﻲ ﻛﻪ ﻣﺘﺪي را از ﻳﻚ ﺷﻴﺊ ﻓﺮاﺧـﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﺪ ،در ﺣﻘﻴﻘﺖ از ﺷﻴﺊ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻛﻪ وﻇﻴﻔﻪ اي را ﺑﺮاي ﺷﻤﺎ اﻧﺠﺎم دﻫﺪ و آن ﺷﻴﺊ ﻧﻴﺰ در ﻣﻘﺎﺑﻞ اﻳﻦ درﺧﻮاﺳﺖ ﻋﻜﺲ اﻟﻌﻤﻠﻲ را ﻧﺸﺎن ﻣﻲ دﻫﺪ .ﺑﻨﺎﺑﺮاﻳﻦ رﻓﺘﺎر ﻳﻚ ﺷﻴﺊ ﻣﻌﻤﻮﻻً ﺑﻪ ﻣﺘﺪﻫﺎ ﻣﺮﺑﻮط اﺳﺖ .اﻟﺒﺘﻪ رﻓﺘﺎر ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺧﺎﺻﻴﺘﻬﺎي ﻳﻚ ﺷﻴﺊ ﻧﻴﺰ ﻣﺮﺑﻮط ﺑﺎﺷﺪ .در ﻣﺜﺎل ﺗﻠﻮﻳﺰﻳﻮن ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻠﻲ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،اﮔﺮ ﺧﺎﺻﻴﺖ ﻛﺎﻧﺎل آن را ﺑﺮاﺑﺮ ﺑﺎ ﻋﺪد ﺧﺎﺻﻲ ﻗﺮار دﻫﻴﺪ ،ﺑﺎﻋـﺚ ﻣـﻲ ﺷـﻮﻳﺪ ﻛـﻪ آن ﺷﻴﺊ ﺑﺎ ﺗﻐﻴﻴﺮ ﺗﺼﻮﻳﺮ ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ،رﻓﺘﺎر ﺧﻮد را ﻧﻤﺎﻳﺶ دﻫﺪ. رﻓﺘﺎر ﻳﻚ ﺷﻴﺊ از ﻛﻼس ﻣﻌﻤﻮﻻ ﺑﻪ ﺻﻮرت ﭼﻨﺪﻳﻦ ﺧﻂ ﻛﺪ اﺳﺖ ﻛﻪ وﻇﻴﻔﻪ ﺧﺎﺻﻲ را اﻧﺠﺎم ﻣﻲ دﻫﺪ .اﻳﻦ ﻛﺪﻫﺎ ﻣﻌﻤﻮﻻ ﻳﻚ و ﻳـﺎ ﻫـﺮ دوي ﻣﻮارد زﻳﺮ را درﺑﺮ ﻣﻲ ﮔﻴﺮﻧﺪ:
ﺗﻐﻴﻴﺮ ﺣﺎﻟﺖ ﺧﻮد ﺷﻴﺊ :ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺘﺪ Accelerateرا ﺑﺮاي ﺷﻴﺊ از ﻛﻼس اﺗﻮﻣﺒﻴـﻞ ﻓﺮاﺧـﻮاﻧﻲ ﻣـﻲ ﻛﻨﻴـﺪ، ﺑﺎﻋﺚ ﻣﻲ ﺷﻮﻳﺪ ﻛﻪ آن ﺷﻴﺊ ﺳﺮﻳﻌﺘﺮ ﺣﺮﻛﺖ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺣﺎﻟﺖ آن را ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻴﺪ. اﺛﺮ ﮔﺬاﺷﺘﻦ روي دﻧﻴﺎي ﺧﺎرج از ﺷﻴﺊ :اﻳﻦ ﻣﻮرد ﻣﻲ ﺗﻮاﻧﺪ ﺷﺎﻣﻞ ﺗﻐﻴﻴﺮ دادن اﺷﻴﺎي دﻳﮕﺮ در ﺑﺮﻧﺎﻣﻪ ،ﻧﻤﺎﻳﺶ ﻣﻄﻠﺒﻲ روي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ،ذﺧﻴﺮه اﻃﻼﻋﺎت روي دﻳﺴﻚ ،ﻳﺎ ﭼﺎپ ﻳﻚ ﺳﻨﺪ از ﺑﺮﻧﺎﻣﻪ ﺑﺎﺷﺪ.
در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻳﻚ ﭘﺮوژه ﺟﺪﻳﺪ اﻳﺠﺎد ﻛﺮده و ﻛﻼس Carرا در آن ﺑﻪ وﺟﻮد ﻣﻲ آورﻳﻢ.
٣٣٩
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﭘﺮوژه ﺟﺪﻳﺪ و ﻛﻼس Car (1وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005را اﺟﺮا ﻛﺮده و از ﻧﻮار ﻣﻨﻮ ﮔﺰﻳﻨﻪ … File New Projectرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. (2ﻫﻨﮕﺎﻣﻲ ﻛـﻪ ﻛـﺎدر New Projectﻧﻤـﺎﻳﺶ داده ﺷـﺪ ،از ﻗـﺴﻤﺖ Templatesﮔﺰﻳﻨـﻪ Console Applicationرا اﻧﺘﺨﺎب ﻛﺮده ،ﻧﺎم Objectsرا در ﻛﺎدر Nameوارد ﻛﻨﻴﺪ .ﺳﭙﺲ روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﭘﺮوژه اﻳﺠﺎد ﺷﻮد. (3ﺣﺎل ﺑﺎﻳﺪ ﻳﻚ ﻛﻼس ﺟﺪﻳﺪ ﺑﻪ اﻳﻦ ﭘﺮوژه اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ .در ﭘﻨﺠـﺮه Solution Explorerروي ﻧـﺎم ﭘـﺮوژه ﻛﻠﻴـﻚ راﺳـﺖ ﻛـﺮده و ﮔﺰﻳﻨـﻪ Add Classرا اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ .در ﻛـﺎدر – Add New Item Objectsﻧﺎم Car.csرا ﺑﻪ ﻋﻨﻮان ﻧﺎم ﻛﻼس ﻣﺸﺨﺺ ﻛﺮده و روي دﻛﻤﻪ Addﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﻛﻼس ﺟﺪﻳﺪ اﻳﺠﺎد ﺷﺪه و ﺑﻪ Solution Explorerﻧﻴﺰ اﺿﺎﻓﻪ ﻣﻲ ﺷﻮد.
ﻧﮕﻬﺪاري ﺣﺎﻟﺖ: ﺗﺎﻛﻨﻮن ﻣﺘﻮﺟﻪ ﺷﺪﻳﻢ ﺣﺎﻟﺖ ﻳﻚ ﺷﻴﺊ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ آن ﺷﻴﺊ در راﺑﻄﻪ ﺑﺎ ﺧﻮد ﭼﻪ ﭼﻴﺰﻫﺎﻳﻲ را ﻣﻲ داﻧﺪ .اﻣﺎ ﺳﻮاﻟﻲ ﻛـﻪ در اﻳﻨﺠـﺎ ﭘﻴﺶ ﻣﻲ آﻳﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﭼﮕﻮﻧﻪ ﺣﺎﻟﺖ ﻳﻚ ﺷﻴﺊ را در آن ﻧﮕﻬﺪاري ﻛﻨﻴﻢ؟ ﺧﻮب ،ﻋﻤﻮﻣﺎً ﺑﺮاي اﻳﻦ ﻛـﺎر ،ﻣﺘﻐﻴﺮﻫـﺎﻳﻲ را درون ﻛـﻼس ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻨﺪ و ﺳﭙﺲ ﺣﺎﻟﺖ ﺷﻴﺊ را در آﻧﻬﺎ ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﻨﺪ .در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا ﺑﻪ اﻳﻦ ﻣﺘﻐﻴﺮ ﻫﺎ ﻓﻴﻠﺪ 1ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد. ﻣﻌﻤﻮﻻ ﻣﺘﺪﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﻛﻪ در ﻳﻚ ﻛﻼس اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ،ﻳﺎ ﺣﺎﻟﺖ ﺷﻴﺊ را ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻨﺪ و ﻳﺎ از آن ﺑﺮاي اﻧﺠﺎم وﻇﻴﻔﻪ ﺧـﻮد اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ .ﻓﺮض ﻛﻨﻴﺪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺧﺎﺻﻴﺘﻲ اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ رﻧﮓ ﻳﻚ ﺷﻴﺊ از ﻛﻼس Carرا ﻣﺸﺨﺺ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕـﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ اﻳﻦ ﺧﺎﺻﻴﺖ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ ،ﻓﻴﻠﺪ اﻳﻦ ﺣﺎﻟﺖ ﺗﻐﻴﻴﺮ ﻛﺮده و ﻣﻘﺪار ﺟﺪﻳﺪ رﻧﮓ را در ﺧﻮد ذﺧﻴﺮه ﻣﻲ ﻛﻨﺪ .ﻫﻤﭽﻨﻴﻦ اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ را ﺑﺪﺳﺖ آورﻳﺪ ،ﻓﻴﻠﺪ اﻳﻦ ﺣﺎﻟﺖ ﺧﻮاﻧﺪه ﺧﻮاﻫﺪ ﺷﺪ و ﻣﻘﺪار آن ﺑﻪ ﻋﻨﻮان رﻧﮓ ﺷﻴﺊ ﺑﻪ ﺷﻤﺎ ﺑﺮﮔﺮداﻧﺪه ﻣﻲ ﺷﻮد. از ﻳﻚ ﺟﻬﺖ ،ﻣﻲ ﺗﻮان ﮔﻔﺖ ﻛﻪ ﺧﺎﺻﻴﺖ ﻫﺎ ﻧﻴﺰ ﻣﺎﻧﻨﺪ ﻣﺘﺪﻫﺎ ﺑﺎﻋﺚ ﺑﺮوز رﻓﺘﺎر از ﺷﻴﺊ ﻣﻲ ﺷﻮﻧﺪ .ﻫﺮ ﺧﺎﺻﻴﺖ ،ﻣﻌﻤﻮﻻً از دو ﻣﺘﺪ ﺗـﺸﻜﻴﻞ ﺷﺪه اﺳﺖ :ﻣﺘﺪ getو ﻣﺘﺪ ) setﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﺑﻼﻛﻬﺎي } … { getو }…{ setﻣﺸﺨﺺ ﻣﻲ ﺷﻮﻧﺪ( .ﻳـﻚ ﻣﺘـﺪ ﺳـﺎده getﺑﺮاي ﺧﺎﺻﻴﺖ Colorدر ﻛﻼس ،Carﻓﻘﻂ ﺷﺎﻣﻞ ﻛﺪي اﺳﺖ ﻛﻪ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﻣﻘﺪار ذﺧﻴﺮه ﺷﺪه در ﻓﻴﻠـﺪ ﻣﺮﺑـﻮط ﺑـﻪ اﻳـﻦ ﺣﺎﻟﺖ ،رﻧﮓ ﺷﻴﺊ را ﺑﻪ ﻛﺎرﺑﺮ اﻋﻼم ﻣﻲ ﻛﻨﺪ ،ﻫﻤﭽﻨﻴﻦ ﻳﻚ ﻣﺘﺪ ﺳﺎده setﺑﺮاي ﺧﺎﺻﻴﺖ Colorﻓﻘـﻂ ﺷـﺎﻣﻞ ﻛـﺪي اﺳـﺖ ﻛـﻪ ﻣﻘﺪار اﻳﻦ ﻓﻴﻠﺪ را ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﻣﻘﺪار ﻣﻮرد ﻧﻈﺮ ﻛﺎرﺑﺮ ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﻨﺪ. اﻣﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي واﻗﻌﻲ اﻳﻦ ﻣﺘﺪﻫﺎ در ﺧﺎﺻﻴﺖ Colorﺑﻪ اﻳﻦ ﺳﺎدﮔﻲ ﻧﻴﺴﺘﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ ﻣﻲ ﺧﻮاﻫﻴﺪ از ﻛﻼس Car در ﻳﻚ ﺑﺎزي اﺗﻮﻣﺒﻴﻞ راﻧﻲ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻳﻦ ﺻﻮرت ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ ﺧﺎﺻﻴﺖ Colorﻳﻚ ﺷﻴﺊ از ﻛﻼس Carرا ﺗﻐﻴﻴﺮ داد، ﻣﺘﺪ setاز اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﺎﻳﺪ ﻋﻼوه ﺑﺮ ذﺧﻴﺮه رﻧﮓ در ﻓﻴﻠﺪ ﻣﺮﺑﻮﻃﻪ ،رﻧﮓ اﺗﻮﻣﺒﻴﻠﻲ ﻛﻪ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﺳﺖ را ﻧﻴﺰ ﺗﻐﻴﻴـﺮ دﻫﺪ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺮاي اﻳﺠﺎد ﺧﺎﺻﻴﺖ Colorدر ﻛﻼس ،Carﻳﻚ ﻓﻴﻠﺪ ﺑﻪ ﻧﺎم Colorو از ﻧﻮع ) publicﺗـﺎ ﺑﻪ وﺳﻴﻠﻪ ﻛﺎرﺑﺮ ﻧﻴﺰ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﺑﺎﺷﺪ( ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ .دﻗﺖ ﻛﻨﻴﺪ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ اﻳﻦ ﻛﻪ در اﻳﻦ ﻣﺜﺎل از ﻓﻴﻠﺪ ﺑﻪ ﺟﺎي ﺧﺎﺻـﻴﺖ اﺳـﺘﻔﺎده ﻛﺮده اﻳﻢ ،اﻣﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي واﻗﻌﻲ ﻫﻴﭽﮕﺎه ﻧﺒﺎﻳﺪ ﺑﻪ ﺟﺎي اﻳﻨﻜﻪ از ﻳﻚ ﺧﺎﺻﻴﺖ ﺑﺎ ﻣﺘﺪﻫﺎي getو setاﻳﺠﺎد ﻛﻨﻴﺪ ،از ﻓﻴﻠﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
Field
1
٣٤٠
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻧﻤﻮﻧﻪ ﺳﺎزي ﻳﻚ ﺷﻴﺊ و اﺿﺎﻓﻪ ﻛﺮدن ﺧﺎﺻﻴﺖ Color (1ﻛﺪ زﻳﺮ را ﺑﻪ ﻛﻼس Carاﺿﺎﻓﻪ ﻛﻨﻴﺪ: ;public string Color (2ﻛﺪ ﻻزم ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻓﻴﻠﺪ ﺑﻪ ﻛﻼس ،ﻫﻤﻴﻦ ﺑﻮد! ﺣﺎل ﺑﺎﻳﺪ ﺑﻪ ﻧﺤﻮي از ﻛﻼﺳﻲ ﻛﻪ اﻳﺠﺎد ﻛﺮده اﻳﻢ اﺳﺘﻔﺎده ﻛﻨـﻴﻢ ﺗﺎ ﻋﻤﻠﻜﺮد آن را ﺑﺒﻴﻨﻴﻢ .ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ،Solution Explorerﻓﺎﻳﻞ Program.csرا ﺑﺎز ﻛﺮده و ﻛﺪ زﻳﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )static void Main(string[] args { // Create a new Car ;)(Car objCar = new Car // Set the Color property to Red ;"objCar.Color = "Red // Show what the value of the property is ;)" Console.WriteLine("My car is this color: ;)Console.WriteLine(objCar.Color // Wait for input from the user ;)(Console.ReadLine } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﭘﻨﺠﺮه ﺟﺪﻳﺪي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 1-9ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
ﺷﻜﻞ 1-9 (4ﺑﺮاي اﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻛﻠﻴﺪ Enterرا از ﺻﻔﺤﻪ ﻛﻠﻴﺪ ﻓﺸﺎر دﻫﻴﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺗﻌﺮﻳﻒ ﻳﻚ ﻓﻴﻠﺪ ﺑﺴﻴﺎر راﺣﺖ اﺳﺖ .ﻛﺪ:
٣٤١
;public string Color ﺑﻪ ﻛﻼس ﻣﻲ ﮔﻮﻳﺪ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻳﻚ ﻓﻴﻠﺪ ﺑﻪ ﻧﺎم Colorاﻳﺠﺎد ﻛﻨﻴﺪ و در آن رﺷﺘﻪ اي از ﻛﺎراﻛﺘﺮ ﻫـﺎ را ﻧﮕﻬـﺪاري ﻛﻨﻴـﺪ .ﻛﻠﻤـﻪ ﻛﻠﻴﺪي publicدر اﺑﺘﺪاي اﻳﻦ ﻓﻴﻠﺪ ﺑﻪ ﻛﻼس ﻣﻲ ﮔﻮﻳﺪ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ اﻳﻦ ﻓﻴﻠﺪ ﺑﻪ وﺳﻴﻠﻪ ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳـﺴﺎﻧﻲ ﻛـﻪ ﺑﺨﻮاﻫﻨـﺪ از اﻳﻦ ﻛﻼس اﺳﺘﻔﺎده ﻛﻨﻨﺪ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﺑﺎﺷﺪ. ﻧﻜﺘﻪ :ﻣﺘﻐﻴﺮﻫﺎﻳﻲ ﻛﻪ در ﺑﺪﻧﻪ ﻳﻚ ﻛﻼس ﺗﻌﺮﻳﻒ ﻣﻲ ﺷﻮﻧﺪ )ﻳﻌﻨﻲ درون ﺧﻮد ﻛﻼس ﺗﻌﺮﻳﻒ ﺷـﺪه اﻧـﺪ ،ﻧـﻪ در ﻣﺘـﺪﻫﺎي ﻣﻮﺟـﻮد در آن ﻛﻼس( ،از دﻳﺪ ﺧﻮد ﻛﻼس ،ﻋﻀﻮ داده اي و از دﻳﺪ ﻛﺴﺎﻧﻲ ﻛﻪ از ﻛﻼس اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﻓﻴﻠﺪ ﻧﺎﻣﻴﺪه ﻣﻲ ﺷﻮﻧﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻛﺪ ﻧﻮﺷﺘﻪ ﺷﺪه در ﻓﺎﻳﻞ Program.csﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،اﺳﺘﻔﺎده از ﻳﻚ ﻛﻼس ﺑﺴﻴﺎر راﺣﺖ اﺳﺖ .اﻳﻦ ﭘﺮوﺳﻪ از دو ﻣﺮﺣﻠﻪ ﺗﺸﻜﻴﻞ ﻣﻲ ﺷﻮد .اﺑﺘﺪا ﺑﺎﻳﺪ ﻣﺘﻐﻴﺮي را ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ﻛﻪ ﺑﺘﻮاﻧﺪ ﺷﻴﺊ از آن ﻛﻼس را در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ؛ ﺳﭙﺲ آن ﺷﻴﺊ را ﻧﻤﻮﻧﻪ ﺳﺎزي ﻣﻲ ﻛﻨﻴﺪ .ﻛﺪ زﻳﺮ ﻣﺘﻐﻴﺮي را ﺑﻪ ﻧﺎم objCarﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﺪ و ﺑﻪ آن ﻣﻲ ﮔﻮﻳﺪ ﻛﻪ ﻓﻘﻂ ﺑﺎﻳﺪ اﺷﻴﺎﻳﻲ از ﻛﻼس Car را در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ. ;Car objCar ﺑﻌﺪ از ﺗﻌﺮﻳﻒ ،objCarاﻳﻦ ﻣﺘﻐﻴﻴﺮ ﺷﺎﻣﻞ ﻫﻴﭻ ﺷﻴﺊ از ﻛﻼس Carﻧﻴﺴﺖ ،زﻳﺮا ﻓﻘﻂ ﻧﻮع ﺷﻴﺊ ﻛﻪ ﺑﺎﻳﺪ در اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻧﮕﻬـﺪاري ﺷﻮد را ﻣﺸﺨﺺ ﻛﺮده اﻳﺪ .اﻳﻦ ﺧﻂ ﻛﺪ ﻣﺎﻧﻨﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﮕﻮﻳﻴﺪ ﻗﻠّﺎﺑﻲ ﺑﻪ ﺷﻤﺎ ﺑﺪﻫﺪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ آن ﺑﺘﻮاﻧﻴﺪ ﻳﻚ ﺷـﻴﺊ از ﻛﻼس Carرا آوﻳﺰان ﻛﻨﻴﺪ ،و ﺳﭙﺲ ﻧﺎم آن ﻗﻠّﺎب را objCarﻗﺮار دﻫﻴﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﻮز ﻫﻴﭻ ﭼﻴﺰ ﺑﻪ اﻳﻦ ﻗﻠّﺎب آوﻳﺰان ﻧﻜﺮده اﻳﺪ. ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ ﻳﻚ ﺷﻴﺊ از ﻛﻼس Carرا ﻧﻤﻮﻧﻪ ﺳﺎزي ﻛﻨﻴﺪ .اﻳﻦ ﻋﻤﻞ ﺑﻪ وﺳﻴﻠﻪ ﻛﻠﻤﻪ ﻛﻠﻴﺪي newاﻧﺠﺎم ﻣﻲ ﺷﻮد: ;)(objCar = new Car اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻓﺼﻠﻬﺎي ﻗﺒﻠﻲ ﻧﻴﺰ دﻳﺪﻳﺪ ،ﻣﻲ ﺗﻮان اﻳﻦ دو ﻣﺮﺣﻠﻪ را در ﻳﻚ ﺧﻂ اﻧﺠﺎم داد: ;)(Car objCar = new Car ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻦ ﺧﻂ ﺑﻪ وﻳﮋوال C#ﻣﻲ ﮔﻮﻳﻴﺪ ﻛﻪ " objCarرا ﺑﻪ ﺷﻴﺊ ﻛﻪ ﺟﺪﻳﺪاً از ﻛﻼس Carﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﺪه اﺳﺖ ارﺟﺎع ﺑﺪه" .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ "ﻳﻚ ﺷﻴﺊ ﺟﺪﻳﺪ از ﻛﻼس Carﻧﻤﻮﻧﻪ ﺳﺎزي ﻛﺮده و آن را از ﻗﻠّﺎﺑﻲ ﺑﻪ ﻧﺎم objCarآوﻳﺰان ﻛﻦ". ﻧﻜﺘﻪ :ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا ،ﻳﻚ ﺷﻴﺊ ﻣﻲ ﺗﻮاﻧﺪ در ﻳﻚ ﻟﺤﻈﻪ از ﭼﻨـﺪﻳﻦ ﻗﻠّـﺎب آوﻳـﺰان ﺷـﻮد ،و ﺑﻨـﺎﺑﺮاﻳﻦ داراي ﭼﻨﺪﻳﻦ ﻧﺎم ﺑﺎﺷﺪ .اﻳﻦ ﻣﻮرد ﻣﻤﻜﻦ اﺳﺖ ﻛﻤﻲ ﮔﻴﺞ ﻛﻨﻨﺪه ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ ،اﻣﺎ در ﺑﺴﻴﺎري از ﻣﻮارد ﺑﺎﻋﺚ راﺣﺘﻲ ﻛﺎرﻫﺎ ﻣﻲ ﺷﻮد .ﺗﺼﻮر ﻛﻨﻴـﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺴﺘﻴﺪ ﻛﻠﻴﺪﻫﺎي ﺧﻮد را در ﻳﻚ زﻣﺎن از ﭼﻨﺪ ﺟﺎ آوﻳﺰان ﻛﻨﻴﺪ – ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﻴﺪا ﻛﺮدن آﻧﻬﺎ ﺑﺴﻴﺎر راﺣﺖ ﺗﺮ ﺑﻮد!
٣٤٢
ﺑﻌﺪ از اﻳﻨﻜﻪ ﻳﻚ ﻧﻤﻮﻧﻪ از ﺷﻴﺊ اﻳﺠﺎد ﻛﺮدﻳﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﺧﺎﺻﻴﺖ ﻫﺎي آن را ﺗﻨﻈﻴﻢ و ﻳﺎ ﻣﺘـﺪﻫﺎي آن را ﻓﺮاﺧـﻮاﻧﻲ ﻛﻨﻴـﺪ .ﺑـﺮاي ﺗﻨﻈـﻴﻢ ﺧﺎﺻﻴﺖ 1Colorﺷﻴﺊ ﺟﺪﻳﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻛﺪ زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ: // Set the Color property to Red ;"objCar.Color = "Red ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﻘﺪار ﻳﻚ ﺧﺎﺻﻴﺖ را ﺗﻨﻈﻴﻢ ﻛﺮدﻳﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﻫﺮ ﭼﻨﺪ ﺑﺎر ﻛﻪ ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﺑﻪ آن دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﻴﺪ و ﻳﺎ ﻣﺠﺪداً ﻣﻘـﺪار آن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ .در اﻳﻨﺠﺎ ،ﻧﺤﻮه دﺳﺘﺮﺳﻲ ﺑﻪ ﻣﻘﺪار ﻳﻚ ﺧﺎﺻـﻴﺖ را ﺑـﺎ ارﺳـﺎل ﺧﺎﺻـﻴﺖ Colorﺑـﻪ ﻣﺘـﺪ WriteLineاز ﻛﻼس Consoleﻧﻤﺎﻳﺶ داده اﻳﻢ: // Show what the value of the property is ;)" Console.WriteLine("My car is this color: ;)Console.WriteLine(objCar.Color ﺧﻂ Console.ReadLineﺑﻪ اﻳﻦ ﺧﺎﻃﺮ اﺳﺖ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﻌﺪ از اﺗﻤﺎم ﻛﺎر ﺻﺒﺮ ﻛﻨﺪ ﺗﺎ ﻛﺎرﺑﺮ ﻛﻠﻴﺪ Enterرا ﻓﺸﺎر دﻫﺪ، ﺳﭙﺲ ﺑﺴﺘﻪ ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﻨﺠﺮه ﻛﻨﺴﻮل ﻗﺒﻞ از ﺑﺴﺘﻪ ﺷﺪن ﺻﺒﺮ ﻣﻲ ﻛﻨﺪ ﺗﺎ ﻛﻠﻴﺪ Enterرا ﻓﺸﺎر دﻫﻴﺪ. // Wait for input from the user ;)(Console.ReadLine ﻧﻜﺘﻪ :ﺑﺮﻧﺎﻣﻪ ﻫﺎي Consoleدر ،.NETﻳﻚ روش ﺧﻮب ﺑﺮاي ﺗﺴﺖ ﻋﻤﻠﻜﺮد ﻛﻼس ﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﻧﻤﻮد ﻇﺎﻫﺮي ﻧﺪارﻧـﺪ و ﻓﻘﻂ در ﺣﺎﻓﻈﻪ ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ ،زﻳﺮا ﺑﺎ اﺳﺘﻔﺎده از آﻧﻬﺎ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﺑﻪ اﻳﺠﺎد ﻳﻚ راﺑﻂ ﮔﺮاﻓﻴﻜﻲ ﺗﻮﺟﻪ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ ﻧﻤﺎﻳﺶ ﭼﻨﺪ ﺧﻂ ﻣﺘﻦ در ﻣﻮاﻗﻊ ﻣﻮرد ﻧﻴﺎز از وﺿﻌﻴﺖ ﺷﻴﺊ ﻣﻄﻠﻊ ﺷﻮﻳﺪ.
ﺧﺎﺻﻴﺖ ﻫﺎي ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ: در ﻗﺴﻤﺖ ﻗﺒﻞ ﺑﺎ ﻧﺤﻮه اﻳﺠﺎد ﻳﻚ ﻋﻀﻮ داده اي )ﻳﺎ ﻫﻤﺎن ﻓﻴﻠﺪ( ﺑﺮاي ﻛﻼس آﺷﻨﺎ ﺷﺪﻳﺪ و ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣـﻲ ﺗـﻮان از آن اﺳﺘﻔﺎده ﻛﺮد .اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﻫﻴﭽﮕﺎه ﻧﺒﺎﻳﺪ اﺟﺎزه دﻫﻴﺪ ﻛﻪ ﻛﺎرﺑﺮ ﺑﻪ ﻃﻮر ﻣﺴﺘﻘﻴﻢ ﻣﻘﺪار ﻣﻮﺟﻮد در ﻳﻚ ﻓﻴﻠـﺪ را ﺗﻐﻴﻴـﺮ دﻫـﺪ ،ﺑﻠﻜـﻪ ﻫﻤﻮاره ﺑﺎﻳﺪ ﻳﻚ ﺧﺎﺻﻴﺖ اﻳﺠﺎد ﻛﻨﻴﺪ ﺗﺎ ﻛﺎرﺑﺮ ﺑﻪ وﺳﻴﻠﻪ آن ﺧﺎﺻﻴﺖ ﻣﻘﺪار ﻓﻴﻠﺪ را ﺗﻐﻴﻴﺮ دﻫﺪ و ﻳﺎ ﺑﻪ آن دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﺪ .ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﺧﺎﺻﻴﺖ ﻫﺎ ﺑﻪ وﺳﻴﻠﻪ دو ﻣﺘﺪ ﺗﻌﺮﻳﻒ ﻣﻲ ﺷﻮﻧﺪ ،اﻣﺎ ﻧﺤﻮه اﺳﺘﻔﺎده از آﻧﻬﺎ ﺑﺮاي ﻛﺎرﺑﺮ ،دﻗﻴﻘﺎً ﻣﺸﺎﺑﻪ ﻓﻴﻠﺪ ﻫﺎ اﺳـﺖ .در ﺣﻘﻴﻘـﺖ ﻣـﻲ ﺗـﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ ﺧﺎﺻﻴﺖ ﻫﺎ ،ﻣﺘﺪﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﻣﺸﺎﺑﻪ ﻳﻚ ﻓﻴﻠﺪ ﺑﺎ آﻧﻬﺎ ﻛﺎر ﻛﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ،اﻧﺘﺨﺎب اﻳﻦ ﻛﻪ ﺑﺮاي ﻳﻚ ﻣﻮرد ﺧﺎص از ﻣﺘﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ و ﻳﺎ از ﺧﺎﺻﻴﺖ ،ﺑﻪ اﻳﻦ ﺑﺴﺘﮕﻲ دارد ﻛﻪ ﻛﺎرﺑﺮ ﺑﺎ ﻛﺪاﻣﻴﻚ ﻣﻲ ﺗﻮاﻧﺪ راﺣﺖ ﺗﺮ ﻛﺎر ﻛﻨﺪ. ﻳﻜﻲ از ﻣﺸﻜﻼﺗﻲ ﻛﻪ در ﺻﻮرت دﺳﺘﺮﺳﻲ ﻣﺴﺘﻘﻴﻢ ﻛﺎرﺑﺮ ﺑﻪ ﻓﻴﻠﺪ ﻣﻤﻜﻦ اﺳﺖ ﺑﻪ وﺟﻮد آﻳﺪ ،اﻳﻦ اﺳﺖ ﻛﻪ در اﻳﻦ ﺻﻮرت ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﻫﻢ ﻣﻘﺪار ﻣﻮﺟﻮد در ﻓﻴﻠﺪ را ﺑﺨﻮاﻧﺪ و ﻫﻢ آن را ﺗﻐﻴﻴﺮ دﻫﺪ .در ﺷﺮاﻳﻄﻲ ﻣﻤﻜﻦ اﺳﺖ ﻧﺨﻮاﻫﻴﺪ اﺟﺎزه دﻫﻴﺪ ﻛﻪ ﻛﺎرﺑﺮ ﻓﻴﻠـﺪ را ﺗﻐﻴﻴـﺮ دﻫـﺪ، ﺑﻠﻜﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻓﻴﻠﺪ ﺑﻪ ﺻﻮرت ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ ﺑﺎﺷﺪ و ﻛﺎرﺑﺮ ﻓﻘﻂ ﺑﺘﻮاﻧﺪ اﻃﻼﻋﺎت آن را ﺑﺨﻮاﻧﺪ. 1در ﻛﻼس Color ،Carﻳﻚ ﻓﻴﻠﺪ اﺳﺖ ﻧﻪ ﻳﻚ ﺧﺎﺻﻴﺖ .اﻟﺒﺘﻪ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ﻧﻴﺰ ﻣﺎﻧﻨﺪ اﺳﺘﻔﺎده از ﻓﻴﻠﺪ اﺳﺖ و ﻓﻘﻂ ﻧﺤﻮه ﺗﻌﺮﻳﻒ آن در ﻛـﻼس ﺗﻔـﺎوت دارد .در اﻳﻦ ﻛﻼس ﺑﺮاي ﺳﺎده ﮔﻲ Color ،را ﺑﻪ ﺻﻮرت ﻓﻴﻠﺪ ﺗﻌﺮﻳﻒ ﻛﺮده اﻳﻢ ،وﻟﻲ ﺑﺮاي اﻳﻨﻜﻪ ﻣﻲ ﺧـﻮاﻫﻴﻢ ﺧﺎﺻـﻴﺖ ﻫـﺎ را ﺑﺮرﺳـﻲ ﻛﻨـﻴﻢ ،از آن ﺑـﻪ ﻋﻨـﻮان ﺧﺎﺻﻴﺖ ﻳﺎد ﻣﻲ ﻛﻨﻴﻢ.
٣٤٣
ﺳﺮﻋﺖ اﺗﻮﻣﺒﻴﻞ ﻳﻚ ﻧﻤﻮﻧﻪ ﺧﻮب ﺑﺮاي اﻳﻦ اﺳﺖ ﻛﻪ ﻣﺸﺨﺺ ﺷﻮد ﭼﮕﻮﻧﻪ ﻣﺪﻟﻲ از ﻳﻚ ﺷﻴﺊ واﻗﻌﻲ در ﻛﺎﻣﭙﻴﻮﺗﺮ ،ﺑﺎﻳﺪ دﻗﻴﻘﺎً ﻣﺸﺎﺑﻪ ﻫﻤﺎن ﺷﻴﺊ ﻋﻤﻞ ﻛﻨﺪ .در ﻳﻚ اﺗﻮﻣﺒﻴﻞ واﻗﻌﻲ اﮔﺮ در ﺣﺎل ﺣﺮﻛﺖ ﺑﺎ ﺳﺮﻋﺖ 60ﻛﻴﻠﻮﻣﺘﺮ در ﺳﺎﻋﺖ ﻫﺴﺘﻴﺪ ،ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺳﺎدﮔﻲ ﺳﺮﻋﺖ را ﺑـﻪ ﻫﺮ ﻋﺪدي ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺑﺎ اﺳﺘﻔﺎده از ﺳﺮﻋﺖ ﺳﻨﺞ ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻋﺪد ﺳﺮﻋﺖ را ﺑﺨﻮاﻧﻴﺪ ،اﻣﺎ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﻧﮕﺸﺖ ﻋﻘﺮﺑﻪ ي ﺳﺮﻋﺖ ﺳﻨﺞ را ﺟﺎ ﺑﻪ ﺟﺎ ﻛﻨﻴﺪ ﺗﺎ ﺳﺮﻋﺖ اﺗﻮﻣﺒﻴﻞ ﺗﻐﻴﻴﺮ ﻛﻨﺪ .ﺑﺮاي ﺗﻐﻴﻴﺮ ﺳﺮﻋﺖ ﺑﺎﻳﺪ از ﭘﺪال ﮔﺎز و ﻳﺎ ﭘﺪال ﺗﺮﻣﺰ ﺑﺮاي اﻓﺰاﻳﺶ و ﻳﺎ ﻛﺎﻫﺶ ﺳﺮﻋﺖ اﺗﻮﻣﺒﻴﻞ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺪل ﻛﺮدن ﻋﻤﻠﻜﺮد اﻳﻦ ﭘﺪاﻟﻬﺎ در ﻛﻼس ،Carﺑﺎﻳﺪ ﻣﺘﺪﻫﺎﻳﻲ اﻳﺠﺎد ﻛﻨﻴـﺪ ﻛـﻪ ﺳـﺮﻋﺖ را ﺗﻐﻴﻴـﺮ دﻫﻨﺪ ) ،(Decelerate ،Accelerateﻫﻤﭽﻨﻴﻦ ﻳﻚ ﺧﺎﺻﻴﺖ ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ ﻧﻴﺰ ﺑـﻪ ﻧـﺎم Speedاﻳﺠـﺎد ﻛﻨﻴـﺪ ﺗـﺎ ﺳﺮﻋﺖ ﻛﻨﻮﻧﻲ اﺗﻮﻣﺒﻴﻞ را ﻧﻤﺎﻳﺶ دﻫﺪ. ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻬﺘﺮ اﺳﺖ ﺑﺮاي ﺟﻠﻮﮔﻴﺮي از اﻳﻦ ﻣﺸﻜﻞ و ﻫﻤﭽﻨﻴﻦ ﻣﺸﻜﻼت ﻣﺸﺎﺑﻪ ،از ﻳﻚ ﺧﺎﺻﻴﺖ ﺑﺮاي درﻳﺎﻓﺖ ﻣﻘـﺪار اﻳـﻦ ﻓﻴﻠـﺪ اﺳـﺘﻔﺎده ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﻗﺒﻞ از ﻗﺮار دادن ﻣﻘﺪار ﻣﻮرد ﻧﻈﺮ در ﻓﻴﻠﺪ ،از درﺳﺖ ﺑﻮدن آن ﻣﻄﻤﺌﻦ ﺷﻮﻳﻢ. اﻟﺒﺘﻪ ﺑﺮاي ﻧﮕﻬﺪاري ﻣﻘﺪار ﺳﺮﻋﺖ ﻣﺴﻠﻤﺎً ﺑﻪ ﻳﻚ ﻋﻀﻮ داده اي در ﻛﻼس ﻧﻴﺎز دارﻳﺪ ،اﻣﺎ اﻳـﻦ ﻋـﻀﻮ داده اي ﺑﺎﻳـﺪ ﻓﻘـﻂ ﺑﺘﻮاﻧـﺪ ﺗﻮﺳـﻂ اﻋﻀﺎي ﻛﻼس ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد و ﻳﺎ ﺗﻐﻴﻴﺮ داده ﺷﻮد .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ ﺑﺮاي ﺗﻌﺮﻳﻒ آن از ﻛﻠﻤـﻪ ﻛﻠﻴـﺪي privateاﺳـﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ: ;private int _speed ﻣﺘﻐﻴﻴﺮ _speedدر اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺻﻮرت privateﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ ،ﺑﻨﺎﺑﺮاﻳﻦ ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺪ ﺗﻮﺳﻂ ﻣﺘﺪﻫﺎﻳﻲ ﻛﻪ در داﺧـﻞ ﻛﻼس وﺟﻮد دارﻧﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد .ﻛﺎرﺑﺮان ﻛﻼس ،Carﺣﺘﻲ از وﺟﻮد ﭼﻨﻴﻦ ﻋﻀﻮي ﻧﻴﺰ ﻣﻄﻠﻊ ﻧﺨﻮاﻫﻨﺪ ﺑـﻮد .ﻫﻤﭽﻨـﻴﻦ در ﻛﻼس ﺧﺎﺻﻴﺘﻲ ﺑﻪ ﻧﺎم Speedﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻛﺎرﺑﺮ ﺑﻪ وﺳﻴﻠﻪ آن ﺑﺘﻮاﻧﺪ از ﻣﻘﺪار اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻛﻪ ﻧـﺸﺎن دﻫﻨـﺪه ﺳـﺮﻋﺖ ﺷـﻴﺊ اﺳﺖ ﻣﻄﻠﻊ ﺷﻮد .در اﻳﻦ ﻛﻼس ﻧﺎم ﻓﻴﻠﺪ ﻣﺮﺑﻮط ﺑﻪ ﺳﺮﻋﺖ و ﻫﻤﭽﻨﻴﻦ ﺧﺎﺻﻴﺖ آن ﻳﻜﻲ اﺳﺖ ،ﺑﺮاي ﺟﻠﻮﮔﻴﺮي از اﻳﻦ ﺗﺸﺎﺑﻪ ﻣﻌﻤـﻮﻻً در اﺑﺘﺪاي ﻧﺎم ﻓﻴﻠﺪ ،ﻳﻚ زﻳﺮ ﺧﻂ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻧﺎم ﻓﻴﻠﺪ _speed ،و ﻧﺎم ﺧﺎﺻﻴﺖ Speed ،ﺧﻮاﻫﺪ ﺷﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﺧﺎﺻﻴﺖ Speed (1ﺑﺮاي ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﺮي ﻛﻪ ﻓﻘﻂ ﺑﻪ وﺳﻴﻠﻪ اﻋﻀﺎي ﻛـﻼس ﻗﺎﺑـﻞ دﺳﺘﺮﺳـﻲ ﺑﺎﺷـﺪ ،ﺑـﻪ ﺟـﺎي ﻛﻠﻤـﻪ ﻛﻠﻴـﺪي publicاز privateاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .ﻛﺪ زﻳﺮ را ﺑﻪ ﻛﻼس Carاﺿﺎﻓﻪ ﻛﻨﻴﺪ: ;private int _speed (2ﺑﺮاي اﻳﻨﻜﻪ ﻛﺎرﺑﺮ ﺑﺘﻮاﻧﺪ از اﻧﺪازه ﺳﺮﻋﺖ ﻣﻄﻠﻊ ﺷﻮد ،ﺑﺎﻳﺪ ﻳﻚ ﺧﺎﺻﻴﺖ ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﻢ .ﻛـﺪ زﻳـﺮ را ﺑـﻪ ﻛﻼس Carاﺿﺎﻓﻪ ﻛﻨﻴﺪ: // Speed - Read-Only property to return the speed public int Speed { get { ;return _speed } }
٣٤٤
اﻳـﻦ ﻣﺘـﺪ ﻣﻘـﺪاري را ﺑـﺮ ﺣـﺴﺐ. ﺑﺮاي ﺗﻨﻈﻴﻢ ﺳﺮﻋﺖ اﺗﻮﻣﺒﻴﻞ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢAccelerate ( ﺣﺎل ﻣﺘﺪي را ﺑﻪ ﻧﺎم3 ﻛـﺪ زﻳـﺮ را ﺑﻌـﺪ از ﺧﺎﺻـﻴﺖ.ﻛﻴﻠﻮﻣﺘﺮ ﺑﺮ ﺳﺎﻋﺖ ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ و ﺳﺮﻋﺖ ﺷﻴﺊ را ﺑﺮاﺑﺮ آن ﻗﺮار ﻣـﻲ دﻫـﺪ : وارد ﻛﻨﻴﺪSpeed // Accelerate - Add kmph to the speed public void Accelerate(int accelerateBy) { // Adjust the speed _speed += accelerateBy; } ﻓﺎﻳﻞ را ﺑﺎز ﻛﻨﻴﺪ و ﻛﺪ. اﻳﺠﺎد ﻛﻨﻴﺪProgram.cs ﻓﺎﻳﻞMain ﺑﺎﻳﺪ ﺗﻐﻴﻴﺮاﺗﻲ را در زﻳﺮ ﺑﺮﻧﺎﻣﻪ،( ﺑﺮاي ﺗﺴﺖ ﻛﻼس4 :آن را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ static void Main(string[] args) { // Create a new Car Car objCar = new Car(); // Report the speed Console.WriteLine("The car's speed is: "); Console.WriteLine(objCar.Speed); // Accelerate objCar.Accelerate(5); // Report the new speed Console.WriteLine("The car's speed is now: "); Console.WriteLine(objCar.Speed); // Wait for input from the user Console.ReadLine(); } : ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ2-9 ﭘﻨﺠﺮه اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ. در ﻧﻮار اﺑﺰار ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪStart ( ﺑﺎ ﻛﻠﻴﻚ روي دﻛﻤﻪ5
٣٤٥
ﺷﻜﻞ 2-9
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اوﻟﻴﻦ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ در ﻛﻼس Carﻳﻚ ﻋﻀﻮ داده اي از ﻧﻮع privateﺑﻪ ﻧـﺎم _speedاﻳﺠـﺎد ﻛﻨﻴﺪ: ;private int _speed ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺷﻴﺊ از اﻳﻦ ﻛﻼس ﺳﺎﺧﺘﻪ ﺷﻮد ،ﻣﻘﺪار _speedدر آن ﺷﻴﺊ ﺑﺮاﺑﺮ ﺑﺎ ﺻﻔﺮ ﺧﻮاﻫﺪ ﺑﻮد زﻳﺮا ﻣﻘﺪار ﭘﻴﺶ ﻓﺮض ﻣﺘﻐﻴﻴﺮ ﻫﺎي ﻧﻮع داده اي intﺑﺮاﺑﺮ ﺑﺎ ﺻﻔﺮ اﺳﺖ. ﺳﭙﺲ ﺧﺎﺻﻴﺘﻲ ﺑﺮاي ﺑﺮﮔﺮداﻧﺪن ﻣﻘﺪار ﺳﺮﻋﺖ ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ: // Speed - Read-Only property to return the speed public int Speed { get { ;return _speed } } ﻫﻨﮕﺎم ﺗﻌﺮﻳﻒ ﻳﻚ ﺧﺎﺻﻴﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ آن را ﺑﻪ ﺻﻮرت ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ ،ﻓﻘﻂ ﻧﻮﺷﺘﻨﻲ ،و ﻳﺎ ﺧﻮاﻧﺪﻧﻲ-ﻧﻮﺷﺘﻨﻲ ﻣﺸﺨﺺ ﻛﻨﻴﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺨﻮاﻫﺪ ﺑﻪ ﻣﻘﺪار ﻳﻚ ﺧﺎﺻﻴﺖ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ ،ﻛﺪﻫﺎي ﻧﻮﺷﺘﻪ ﺷﺪه در ﺑﻼك ،getو اﮔـﺮ ﺑﺨﻮاﻫـﺪ ﻣﻘﺪار ﺧﺎﺻﻴﺖ را ﺗﻐﻴﻴﺮ دﻫﺪ ﻛﺪﻫﺎي ﺑﻼك setاﺟﺮا ﻣﻲ ﺷﻮﻧﺪ .ﭘﺲ اﮔﺮ ﻫﻨﮕﺎم اﻳﺠﺎد ﻳﻚ ﺧﺎﺻﻴﺖ ،ﺑـﻼك getرا در آن ﻧﻨﻮﻳـﺴﻴﺪ آن ﺧﺎﺻﻴﺖ ﻗﺎﺑﻞ ﺧﻮاﻧﺪن ﻧﺨﻮاﻫﺪ ﺑﻮد و ﺑﻪ ﻳﻚ ﺧﺎﺻﻴﺖ ﻓﻘﻂ-ﻧﻮﺷﺘﻨﻲ ﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮد .ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴـﺐ اﮔـﺮ ﺑـﻼك setرا از ﻳـﻚ ﺧﺎﺻﻴﺖ ﺣﺬف ﻛﻨﻴﺪ ،ﺧﺎﺻﻴﺖ ﻗﺎﺑﻞ ﻧﻮﺷﺘﻦ ﻧﺨﻮاﻫﺪ ﺑﻮد و ﺑﻪ ﺧﺎﺻﻴﺖ ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ ﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮد .در ﺻـﻮرﺗﻲ ﻛـﻪ در ﺧﺎﺻـﻴﺖ ﻫـﻢ ﺑﻼك getو ﻫﻢ ﺑﻼك setوﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ ،ﺧﺎﺻﻴﺖ ﺧﻮاﻧﺪﻧﻲ-ﻧﻮﺷﺘﻨﻲ ﺧﻮاﻫﺪ ﺑﻮد. ﺑﻌﺪ از اﻳﺠﺎد ﺧﺎﺻﻴﺖ ،Speedﻣﺘﺪي ﺑﻪ ﻧﺎم Accelerateاﻳﺠﺎد ﻛﺮده اﻳﻢ .اﻳﻦ ﻣﺘﺪ ﻣﻘﺪاري را ﺑﺮﻧﻤﻲ ﮔﺮداﻧﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ ﻧـﻮع ﺑﺮﮔﺸﺘﻲ آن را voidﻗﺮار ﻣﻲ دﻫﻴﻢ. // Accelerate - Add kmph to the speed
٣٤٦
)public void Accelerate(int accelerateBy { // Adjust the speed ;_speed += accelerateBy } اﻳﻦ ﻣﺘﺪ ﻳﻚ ﭘﺎراﻣﺘﺮ ﺑﻪ ﻧﺎم accelerateByدرﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن ﻣﻘﺪار اﻓﺰاﻳﺶ ﺳﺮﻋﺖ ﺑﻪ ﻛﺎر ﻣﻲ رود. ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﺗﻨﻬﺎ ﻛﺎري ﻛﻪ اﻳﻦ ﺗﺎﺑﻊ اﻧﺠﺎم ﻣﻲ دﻫﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻣﻘﺪار درﻳﺎﻓﺘﻲ را ﺑﻪ ﻓﻴﻠﺪ _speedاﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ .در دﻧﻴﺎي واﻗﻌﻲ ﻓﺸﺎر روي ﭘﺪال ﮔﺎز ،ﻫﻤﺮاه ﺑﺎ ﻓﺎﻛﺘﻮرﻫﺎي دﻳﮕﺮي ﻣﺎﻧﻨﺪ ﺳﺮﻋﺖ ﺑﺎد و ﻳﺎ اﺻﻄﻜﺎك ﺑﺎ ﺳﻄﺢ زﻣﻴﻦ ،ﺳﺮﻋﺖ ﺟﺪﻳﺪ اﺗﻮﻣﺒﻴﻞ ﺗﻌﻴﻴﻦ ﻣﻲ ﺷﻮد. ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺳﺮﻋﺖ ﻧﺘﻴﺠﻪ اﺛﺮ ﭼﻨﺪ ﻓﺎﻛﺘﻮر ﺑﺮ ﻳﻜﺪﻳﮕﺮ اﺳﺖ ،ﻧﻪ ﻓﻘﻂ ﺗﻐﻴﻴﺮ دادن ﻳﻚ ﻋﺪد .ﺑﺮاي ﺷﺒﻴﻪ ﺳﺎزي واﻗﻌﻲ اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳـﺪ ﻛﺪﻫﺎي ﭘﻴﭽﻴﺪه ﺗﺮي ﻧﻮﺷﺖ .اﻣﺎ در اﻳﻨﺠﺎ ﺑﺮاي اﻳﻨﻜﻪ ﻣﺜﺎل ﻫﻤﭽﻨﺎن ﺳﺎده ﺑﺎﻗﻲ ﺑﻤﺎﻧﺪ ،ﻣﻘﺪار ﻣﻌﻴﻦ ﺷﺪه ﺑـﻪ وﺳـﻴﻠﻪ ﻛـﺎرﺑﺮ را ﺑـﺎ ﺳـﺮﻋﺖ ﻛﻨﻮﻧﻲ ﺟﻤﻊ ﻣﻲ ﻛﻨﻴﻢ. ﺳﺮﻋﺖ ﺑﺨﺸﻴﺪن ﺑﻪ اﺗﻮﻣﺒﻴﻞ ﻧﻤﻮﻧﻪ دﻳﮕﺮي از ﻛﭙﺴﻮﻟﻲ ﺑﻮدن اﺳﺖ .ﺑﺮاي ﺷﺘﺎب دادن ﺑﻪ ﻳـﻚ اﺗﻮﻣﺒﻴـﻞ در دﻧﻴـﺎي واﻗﻌـﻲ ،ﺳﻴـﺴﺘﻤﻬﺎي زﻳﺎدي ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﻓﻌﺎﻟﻴﺖ ﻣﻲ ﻛﻨﻨﺪ ﺗﺎ اﺗﻮﻣﺒﻴﻞ ﺑﻪ ﺳﺮﻋﺖ ﻣﻮرد ﻧﻈﺮ ﻛﺎرﺑﺮ ﺑﺮﺳﺪ .اﻣﺎ راﻧﻨﺪه ﺑﻪ ﻋﻨﻮان ﻛﺴﻲ ﻛـﻪ در ﺣـﺎل اﺳـﺘﻔﺎده از اﻳـﻦ ﺷﻴﺊ اﺳﺖ ،ﻫﻴﭻ اﻃﻼﻋﻲ از اﻳﻦ ﺳﻴﺴﺘﻢ ﻫﺎ ﻧﺪارد .در اﻳﻦ ﻣﺜـﺎل ﻫـﻢ ﺑـﻪ ﻫﻤـﻴﻦ ﺻـﻮرت اﺳـﺖ .ﻓـﺮدي ﻛـﻪ در ﺣـﺎل اﺳـﺘﻔﺎده از ﻣﺘـﺪ Accelerateاﺳﺖ ،در ﻣﻮرد اﻳﻨﻜﻪ اﻳﻦ ﻣﺘﺪ ﭼﮕﻮﻧﻪ ﺳﺮﻋﺖ را اﻓﺰاﻳﺶ ﻣﻲ دﻫﺪ ﻫﻴﭻ اﻃﻼﻋﻲ ﻧﺪارد و ﻓﻘﻂ ﻣﻲ داﻧـﺪ ﻛـﻪ ﺑـﺮاي اﻓﺰاﻳﺶ ﺳﺮﻋﺖ ﺑﺎﻳﺪ از آن اﺳﺘﻔﺎده ﻛﻨﺪ. اﺳﺘﻔﺎده از ﻗﺴﻤﺘﻬﺎي ﺟﺪﻳﺪ ﺑﺴﻴﺎر ﺳﺎده اﺳﺖ .اﺑﺘﺪا ﺷﻴﺊ از اﻳﻦ ﻛﻼس را ﻫﻤﺎﻧﻨﺪ ﻗﺴﻤﺖ ﻗﺒﻞ ﻧﻤﻮﻧﻪ ﺳﺎزي ﻣﻲ ﻛﻨﻴﺪ: // Create a new Car ;)(Car objCar = new Car ﺳﭙﺲ ﺳﺮﻋﺖ اوﻟﻴﻪ را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﺪ: // Report the speed ;)" Console.WriteLine("The car's speed is: ;)Console.WriteLine(objCar.Speed ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ،Accelerateﺳﺮﻋﺖ ﺷﻴﺊ را اﻓﺰاﻳﺶ ﻣﻲ دﻫﻴﺪ: // Accelerate ;)objCar.Accelerate(5 در اﻧﺘﻬﺎ ﻧﻴﺰ ﺳﺮﻋﺖ ﺟﺪﻳﺪ را اﻋﻼم ﻣﻲ ﻛﻨﻴﺪ: // Report the new speed ;)" Console.WriteLine("The car's speed is now: ;)Console.WriteLine(objCar.Speed
٣٤٧
ﺧﺎﺻﻴﺘﻬﺎي ﺧﻮاﻧﺪﻧﻲ-ﻧﻮﺷﺘﻨﻲ: ﺗﺎﻛﻨﻮن ﻣﺘﻮﺟﻪ ﺷﺪﻳﻢ ﻛﻪ ﻳﻜﻲ از دﻻﻳﻞ ﺑﺮﺗﺮي اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ﻫﺎ ﺑﻪ ﺟﺎي ﻓﻴﻠﺪ ﻫﺎ ،در اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻـﻴﺖ ﻫـﺎ ﻣـﻲ ﺗﻮان از ﺗﻐﻴﻴﺮ دادن ﻣﺴﺘﻘﻴﻢ ﻓﻴﻠﺪ ﺗﻮﺳﻂ ﻛﺎرﺑﺮ ﺟﻠﻮﮔﻴﺮي ﻛﺮد ،ﻫﻤﺎﻧﻨﺪ ﺧﺎﺻﻴﺖ Speedﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ ﺑﻪ ﺻﻮرت ﻓﻘـﻂ-ﺧﻮاﻧـﺪﻧﻲ ﺗﻌﺮﻳﻒ ﺷﺪ .اﻣﺎ در اﻳﻨﺠﺎ ﻣﻜﻦ اﺳﺖ ﺳﻮال ﻛﻨﻴﺪ ﺑﺮاي ﻣﻮاردي ﻛﻪ ﻛﺎرﺑﺮ ﻫﻢ ﻣﻲ ﺗﻮاﻧﺪ ﻣﻘﺪار ﻳﻚ ﻓﻴﻠﺪ را ﺑﺨﻮاﻧﺪ و ﻫﻢ آن را ﺗﻐﻴﻴـﺮ دﻫـﺪ، ﭼﺮا ﺑﺎﻳﺪ ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از ﻓﻴﻠﺪ ،از ﺧﺎﺻﻴﺖ اﺳﺘﻔﺎده ﻛﻨﻴﻢ؟ ﺧﻮب ،اﮔﺮ ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از ﻓﻴﻠﺪ از ﺧﺎﺻﻴﺖ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﻛﺪﻫﺎﻳﻲ را ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﺗﺎ ﻫﻨﮕﺎم ﺧﻮاﻧﺪه ﺷﺪن و ﻳﺎ ﻧﻮﺷﺘﻪ ﺷﺪن ﻓﻴﻠﺪ ﺗﻮﺳﻂ ﻛﺎرﺑﺮ اﺟﺮا ﺷﻮﻧﺪ ،و اﻳﻦ ﻣﻮرد از اﻫﻤﻴﺖ زﻳﺎدي ﺑﺮﺧﻮردار اﺳﺖ. ﺑﺮاي ﻣﺜﺎل ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ﻫﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻗﺒﻞ از اﻳﻨﻜﻪ ﻣﻘﺪاري ﺑﻪ ﻳﻚ ﻓﻴﻠﺪ اﺧﺘﺼﺎص داده ﺷﻮد ،از درﺳﺖ ﺑﻮدن آن ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ. ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻓﻴﻠﺪي ﺑﻪ ﻧﺎم ،NumberOfDoorsﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن ﺗﻌﺪاد درﻫﺎي ﻳﻚ اﺗﻮﻣﺒﻴـﻞ در ﻛﻼس Carﻗﺮار دﻫﻴﺪ .ﻧﻮع داده اي اﻳﻦ ﻓﻴﻠﺪ از ﻛﻼس ﺑﺎﻳﺪ از ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ ﺑﺎﺷﺪ ﺗﺎ ﺑﺘﻮاﻧﺪ ﺗﻌﺪاد درﻫﺎي ﻳﻚ اﺗﻮﻣﺒﻴـﻞ را در ﺧـﻮد ﻧﮕﻪ دارد .اﻣﺎ ﻣﺴﻠﻤﺎً ﻧﻤﻲ ﺧﻮاﻫﻴﺪ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺘﻮاﻧﺪ ﻋﺪد 0و ﻳﺎ ﻋﺪد 65500را در اﻳﻦ ﻓﻴﻠﺪ وارد ﻛﻨﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻋﺪد وارد ﺷﺪه ﺗﻮﺳﻂ ﻛﺎرﺑﺮ در ﺑﺎزه 2ﺗﺎ 6ﺑﺎﺷﺪ. ﻧﻜﺘﻪ :ﻣﻤﻜﻦ اﺳﺖ ﺑﮕﻮﻳﻴﺪ ﻛﻪ اﻳﻦ ﻛﻼس ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ دﻳﮕﺮي ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد ،ﺑﻨﺎﺑﺮاﻳﻦ وﻇﻴﻔﻪ اوﺳﺖ ﻛﻪ ﻫﻨﮕـﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﺪ ﻣﻘﺪاري را در اﻳﻦ ﻓﻴﻠﺪ ﻗﺮار دﻫﺪ از درﺳﺖ ﺑﻮدن آن ﻣﻄﻤﺌﻦ ﺷﻮد .در ﻃﺮاﺣﻲ ﻳﻚ ﻛﻼس ،وﻇﻴﻔﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ اﺳﺖ ﻛـﻪ ﺗـﺎ ﺣﺪ ﻣﻤﻜﻦ ﻛﺎر را ﺑﺮاي اﻓﺮادي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻨﺪ از ﻛﻼس اﺳﺘﻔﺎده ﻛﻨﻨﺪ ﺳﺎده ﻛﻨﺪ .رﺳﻴﺪﮔﻲ ﻛﺮدن ﺑﻪ ﺻﺤﺖ داده ﻫـﺎي ورودي ،ﻳﻜـﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﺟﻨﺒﻪ ﻫﺎي ﻃﺮاﺣﻲ ﻳﻚ ﻛﻼس ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد. ﻫﻤﭽﻨﻴﻦ ﻫﻤﻮاره ﺧﺎﺻﻴﺖ ﻫﺎ ﻣﻘﺪارﻫﺎي ذﺧﻴﺮه ﺷﺪه در ﻳﻚ ﻓﻴﻠﺪ را ﺑﺮﻧﻤﻲ ﮔﺮداﻧﻨﺪ ،ﺑﻠﻜﻪ ﻣﻤﻜﻦ اﺳﺖ ﻣﻘﺪاري را از ﺟﺎي دﻳﮕﺮي ﺑﺪﺳـﺖ آورﻧﺪ و ﻳﺎ آن را ﺑﺮ اﺳﺎس ﻳﻚ ﺳﺮي اﻃﻼﻋﺎت ﻣﺤﺎﺳﺒﻪ ﻛﺮده و ﺑﺮﮔﺮداﻧﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﺑﺨﻮاﻫﻴﺪ ﺗﻌـﺪاد ﻛـﻞ ﺳﻔﺎرﺷـﺎت ﻳـﻚ ﻣﺸﺘﺮي را ﺑﻪ ﻋﻨﻮان ﻳﻚ ﺧﺎﺻﻴﺖ در ﻛﻼس Customerﻗﺮار دﻫﻴﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﻫﻨﮕـﺎم ﻃﺮاﺣـﻲ ﻳـﻚ ﻛـﻼس ﺑـﺮاي ،Customerﻓﻴﻠﺪي ﺑﺮاي ﻧﮕﻬﺪاري اﻳﻦ ﻋﺪد ﻣﺸﺨﺺ ﻧﻤﻲ ﺷﻮد ،ﺑﻠﻜﻪ ﻳﻚ ﺷﻴﺊ ﺑﺎﻳﺪ در ﺻﻮرت ﻟﺰوم ،آن را ﻣﺤﺎﺳﺒﻪ ﻛﻨﺪ .در اﻳﻦ ﺻﻮرت ﻣﻲ ﺗﻮاﻧﻴﺪ در ﻗﺴﻤﺖ getﻳﻚ ﺧﺎﺻﻴﺖ ،ﻛﺪي را ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ ﺑﺎ ﺗﻮﺟـﻪ ﺑـﻪ ﻟﻴـﺴﺖ ﺳﻔﺎرﺷـﺎت ﻳـﻚ ﻣـﺸﺘﺮي در ﻳـﻚ ﺑﺎﻧـﻚ اﻃﻼﻋﺎﺗﻲ ،ﺗﻌﺪاد ﻛﻞ آﻧﻬﺎ را ﻣﺤﺎﺳﺒﻪ ﻛﺮده و ﺑﺮﮔﺮداﻧﺪ .اﻳﻦ ﻣﻮارد در ﺑﺨﺸﻬﺎي ﺑﻌﺪي ﻣﻮرد ﺑﺮرﺳﻲ ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻬﺘﺮ اﺳﺖ ﺑـﻪ ﻣﺴﺌﻠﻪ ﺗﻌﺪاد درﻫﺎي اﺗﻮﻣﺒﻴﻞ ﺑﺮﮔﺮدﻳﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﺧﺎﺻﻴﺖ NumberOfDoors (1اوﻟﻴﻦ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻓﻴﻠﺪي ﺑﺮاي ﻧﮕﻬﺪاري ﺗﻌﺪاد درﻫـﺎي ﻳـﻚ ﺷـﻴﺊ از ﻛـﻼس Carرا ،در آن اﻳﺠﺎد ﻛﻨﻴﺪ .ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض در ﻧﻈﺮ ﻣﻲ ﮔﻴﺮﻳﻢ ﻛﻪ ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﺮاﺑﺮ ﺑﺎ 4اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﻛﺪ ﻣـﺸﺨﺺ ﺷـﺪه در زﻳﺮ را ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ: ;public string Color ;private int _speed ;private int _numberOfDoors = 4
٣٤٨
(2ﺣﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﺧﺎﺻﻴﺘﻲ ﺑﺮاي ﺗﻨﻈﻴﻢ و ﻳﺎ دﺳﺘﺮﺳﻲ ﺑﻪ ﺗﻌﺪاد در ﻫﺎي اﺗﻮﻣﺒﻴﻞ اﻳﺠﺎد ﻛﻨﻴﺪ و ﻫﻤﻮاره ﺑﺮرﺳـﻲ ﻛﻨﻴـﺪ ﻛـﻪ ﻋـﺪد ﻣﻮﺟﻮد ﺑﺮاي اﻳﻦ ﻓﻴﻠﺪ ﺑﻴﻦ 2ﺗﺎ 6ﺑﺎﺷﺪ .ﻛﺪ زﻳﺮ را ﺑﻌﺪ از ﻣﺘﺪ Accelerateدر ﻛﻼس Carوارد ﻛﻨﻴﺪ: // NumberOfDoors - get/set the number of doors public int NumberOfDoors { // Called when the property is read get { ;return _numberOfDoors } // Called when the property is set set { // Is the new value between two and six )if (value >= 2 && value <= 6 { ;_numberOfDoors = value } } } ﻧﻜﺘﻪ :در اﻳﻦ ﻓﺼﻞ از اﻳﺠﺎد ﺧﻄﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻋﺪدي ﺧﺎرج از ﻣﺤﺪوده ﻣﻮرد ﻧﻈﺮ وارد ﺷﺪ ﺻﺮﻓﻨﻈﺮ ﻣﻲ ﻛﻨﻴﻢ .اﻣﺎ اﺻـﻮﻻ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻳﻚ ﻋﺪد ﻧﺎ ﻣﻌﺘﺒﺮ در ﻛﻼس وارد ﺷﺪ ،ﺑﺎﻳﺪ ﻳﻚ ﺧﻄﺎ اﻳﺠﺎد ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻓﺮدي ﻛﻪ در ﺣﺎل اﺳـﺘﻔﺎده از ﻛـﻼس اﺳـﺖ ﻣﺘﻮﺟـﻪ رخ دادن ﺧﻄﺎ ﺷﺪه و در ﻣﻮرد ﭼﮕﻮﻧﮕﻲ ﺑﺮﺧﻮرد ﺑﺎ اﻳﻦ ﺧﻄﺎ ﺗﺼﻤﻴﻢ ﮔﻴﺮي ﻣﻲ ﻛﻨﺪ .در ﻣﻮرد ﭼﮕﻮﻧﮕﻲ اﻳﺠﺎد اﻳﻦ ﻧـﻮع ﺧﻄﺎﻫـﺎ در ﻓـﺼﻞ 11 ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد. (3ﺑﺮاي ﺑﺮرﺳﻲ ﺗﻐﻴﻴﺮاﺗﻲ ﻛﻪ در ﻛﻼس اﻳﺠﺎد ﻛﺮده اﻳﺪ ،ﺑﺎﻳﺪ زﻳﺮ ﺑﺮﻧﺎﻣﻪ Mainدر Program.csرا ﺑـﻪ ﺻـﻮرت زﻳـﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ: )static void Main(string[] args { // Create a new Car ;)(Car objCar = new Car // Report the number of doors ;)" Console.WriteLine("The number of doors is: ;)Console.WriteLine(objCar.NumberOfDoors // Try Changing the number of doors to 1000 ;objCar.NumberOfDoors = 1000 // Report the number of doors ;)" Console.WriteLine("The number of doors is:
٣٤٩
;)Console.WriteLine(objCar.NumberOfDoors // Now try changing the number of doors to 2 ;objCar.NumberOfDoors = 2 // Report the number of doors ;)" Console.WriteLine("The number of doors is: ;)Console.WriteLine(objCar.NumberOfDoors // Wait for input from the user ;)(Console.ReadLine } ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﺻﻔﺤﻪ اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 3-9ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 3-9
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اﺑﺘﺪا ﻳﻚ ﻓﻴﻠﺪ ﺑﺮاي ﻧﮕﻬﺪاري ﺗﻌﺪاد در ﻫﺎ ﺑﻪ ﺻﻮرت privateﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ .ﻫﻤﭽﻨﻴﻦ ﻣﻘﺪار ﭘﻴﺶ ﻓﺮض اﻳﻦ ﻓﻴﻠﺪ را ﻧﻴﺰ 4در ﻧﻈﺮ ﻣﻲ ﮔﻴﺮﻳﻢ. ;private int _numberOfDoors = 4 دﻟﻴﻞ اﻳﻨﻜﻪ در اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﻪ اﻳﻦ ﻓﻴﻠﺪ ﻋﺪد داده اﻳﻢ ﻧﻴﺰ ﻣﺸﺨﺺ اﺳﺖ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﻣـﻲ ﺧـﻮاﻫﻴﻢ ﺗﻌـﺪاد درﻫـﺎي ﻳـﻚ اﺗﻮﻣﺒﻴـﻞ ﻫﻤﻮاره ﺑﻴﻦ 2ﺗﺎ 6ﺑﺎﺷﺪ .ﻫﻤﭽﻨﻴﻦ ﻣﻲ داﻧﻴﻢ ﻛﻪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض داراي ﻣﻘﺪار 0اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ اﻳﻦ ﻓﻴﻠﺪ ﻣﻘﺪار ﻧﺪﻫﻴﻢ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺷﻴﺊ اﻳﺠﺎد ﻣﻲ ﺷﻮد ،ﺗﻌﺪاد در ﻫﺎ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض ﺑﺮاﺑﺮ ﺑﺎ ﺻﻔﺮ ﺧﻮاﻫﺪ ﺑﻮد. ﺑﻌﺪ از ﺗﻌﺮﻳﻒ ﻓﻴﻠﺪ ﻧﻮﺑﺖ ﺑﻪ ﺧﻮد ﺧﺎﺻﻴﺖ ﻣﻲ رﺳﺪ .ﺑﺨﺶ getﻛﻪ ﻫﻤﺎﻧﻨﺪ ﻗﺴﻤﺖ ﻗﺒﻞ اﺳﺖ و ﻧﻜﺘﻪ ﺟﺪﻳﺪي ﻧﺪارد – ﻓﻘﻂ ﻛﺎﻓﻲ اﺳﺖ ﻣﻘﺪار ﻓﻴﻠﺪ _numberOfDoorsرا ﺑﺮﮔﺮداﻧﺪ .اﻣﺎ در ﺑﻼك setاﺑﺘﺪا ﺑﺎﻳﺪ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ﻋﺪدي ﻛﻪ ﻛـﺎرﺑﺮ ﺑـﻪ اﻳـﻦ ﺧﺎﺻـﻴﺖ ﻓﺮﺳﺘﺎده اﺳﺖ ﻣﻌﺘﺒﺮ ﺑﺎﺷﺪ ،ﺳﭙﺲ آن را در _numberOfDoorsﻗﺮار دﻫﻴﻢ )ﻣﻘﺪاري ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻛﺎرﺑﺮ ﺑﻪ ﺧﺎﺻﻴﺖ ﻓﺮﺳـﺘﺎده ﻣﻲ ﺷﻮد ﺑﺎ ﻛﻠﻤﻪ ﻛﻠﻴﺪي valueﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ اﺳﺖ(: // NumberOfDoors - get/set the number of doors
٣٥٠
public int NumberOfDoors { // Called when the property is read get { ;return _numberOfDoors } // Called when the property is set set { // Is the new value between two and six )if (value >= 2 && value <= 6 { ;_numberOfDoors = value } } } ﺑﻘﻴــﻪ ﻛــﺪي ﻫــﻢ ﻛــﻪ ﺑــﻪ ﻓﺎﻳــﻞ Program.csاﺿــﺎﻓﻪ ﻛــﺮده اﻳــﺪ ،ﻣــﻮرد ﭘﻴﭽﻴــﺪه اي ﻧﻴــﺴﺖ .اﺑﺘــﺪا ﻣﻘــﺪار اوﻟﻴــﻪ ﻓﻴﻠــﺪ _numberOfDoorsرا ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﺪ ،ﺳﭙﺲ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﺪ اﻳﻦ ﻣﻘﺪار را ﺑﻪ 1000ﺗﻐﻴﻴﺮ دﻫﻴﺪ .در اﻳﻦ ﻫﻨﮕﺎم ﻛـﺪي ﻛـﻪ ﺑﺮاي ﺗﻌﻴﻴﻦ ﺻﺤﺖ داده ﻫﺎ در ﺧﺎﺻﻴﺖ NumberOfDoorsوارد ﺷﺪه اﺳﺖ ،اﺟﺎزه ﻧﻤﻲ دﻫﺪ ﻛﻪ ﻣﻘﺪار ﺧﺎﺻﻴﺖ ﺑﻪ 1000ﺗﻐﻴﻴﺮ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻘﺪار ﻓﻴﻠﺪ _numberOfDoorsﻫﻤﭽﻨﺎن ﺑﺮاﺑﺮ ﺑﺎ 4ﺑﺎﻗﻲ ﻣﻲ ﻣﺎﻧﺪ .در اﻧﺘﻬﺎ ﻧﻴﺰ ﻣﻘﺪار ﺧﺎﺻﻴﺖ را ﺑﺮاﺑـﺮ ﺑـﺎ ﻳـﻚ ﻣﻘﺪار ﻣﻨﻄﻘﻲ ﻣﺎﻧﻨﺪ 2ﻗﺮار ﻣﻲ دﻫﻴﻢ و ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﺗﻌﺪاد درﻫﺎ ﺗﻐﻴﻴﺮ ﻣﻲ ﻛﻨﺪ. ﻧﻜﺘﻪ :اﮔﺮﭼﻪ ﻣﻤﻜﻦ اﺳﺖ روش ﻛﺎرﻛﺮد ﺧﺎﺻﻴﺘﻬﺎي ﺧﻮاﻧﺪﻧﻲ-ﻧﻮﺷﺘﻨﻲ و ﻫﻤﭽﻨﻴﻦ ﻓﻴﻠﺪ ﻫﺎي publicﻣﺎﻧﻨﺪ ﻫﻢ ﺑﻪ ﻧﻈﺮ رﺳﺪ ،اﻣﺎ ﺑﺎ ﻫﻢ ﺗﻔﺎوت زﻳﺎدي دارﻧﺪ .زﻣﺎﻧﻲ ﻛﻪ وﻳﮋوال 2005 C#ﺑﺨﻮاﻫﺪ ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ را ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﺪ ،ﺑﺎ ﻗﺴﻤﺘﻬﺎﻳﻲ ﻛﻪ ﻛﺎرﺑﺮ از ﺧﺎﺻﻴﺖ اﺳﺘﻔﺎده ﻛﺮده اﺳﺖ ،ﻫﻤﺎﻧﻨﺪ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ رﻓﺘﺎر ﻣﻲ ﻛﻨﺪ .ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ﻫﺎ ﺑﻪ ﺟﺎي ﻓﻴﻠـﺪ ﻫـﺎي publicﺑﺎﻋـﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ اﻧﻌﻄﺎف ﭘﺬﻳﺮ ﺗﺮ ﺷﺪه و ﻗﺎﺑﻠﻴﺖ ﮔﺴﺘﺮش ﺑﻴﺸﺘﺮي داﺷﺘﻪ ﺑﺎﺷﺪ.
ﻣﺘﺪ :IsMoving ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺣﺎل ﻃﺮاﺣﻲ ﻳﻚ ﻛﻼس ﻫﺴﺘﻴﺪ ،ﺑﺎﻳﺪ ﻫﻤﻮاره اﻳﻦ ﺳﻮال را در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ "ﭼﮕﻮﻧﻪ ﻣـﻲ ﺗـﻮاﻧﻢ اﺳـﺘﻔﺎده از اﻳـﻦ ﻛﻼس را ﺳﺎده ﺗﺮ ﻛﻨﻢ؟" .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻛﺎرﺑﺮ ﺑﺨﻮاﻫﺪ ﺗﺸﺨﻴﺺ دﻫﺪ آﻳﺎ اﻳﻦ اﺗﻮﻣﺒﻴﻞ در ﺣﺎل ﺣﺮﻛﺖ اﺳﺖ ﻳﺎ ﻧﻪ ،ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﺪ اﻳﻦ ﻛﺎر را اﻧﺠﺎم دﻫﺪ؟ ﻳﻚ راه ﺑﺮاي اﻧﺠﺎم اﻳﻦ ﻛﺎر ،ﺑﺮرﺳﻲ ﺧﺎﺻﻴﺖ Speedاﺳﺖ .اﮔﺮ ﻣﻘﺪار ﺑﺮﮔﺸﺘﻲ ﺗﻮﺳﻂ اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﺮاﺑﺮ ﺑﺎ ﺻـﻔﺮ ﺑﺎﺷـﺪ ،ﻣـﻲ ﺗـﻮان ﻓﻬﻤﻴﺪ ﻛﻪ اﺗﻮﻣﺒﻴﻞ ﺗﻮﻗﻒ ﻛﺮده اﺳﺖ .اﮔﺮ ﺑﺮرﺳﻲ اﻳﻦ ﻣﻮرد را ﺑﻪ ﻛﺎرﺑﺮ واﮔﺬار ﻛﻨﻴﻢ ،ﻛﺎرﺑﺮ ﻧﻴﺰ ﺑﺮ اﺳﺎس ﺑﺮداﺷـﺖ ﺧـﻮد از ﻧﺤـﻮه ﻛـﺎرﻛﺮد ﻛﻼس ﺑﺮاي ﻧﺘﻴﺠﻪ ﮔﻴﺮي اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ و ﻣﻤﻜﻦ اﺳﺖ او از اﻳﻦ روش ﺑﺮاي ﺑﺮرﺳﻲ ﺗﻮﻗﻒ اﺗﻮﻣﺒﻴﻞ اﺳﺘﻔﺎده ﻧﻜﻨﺪ .اﻟﺒﺘﻪ در اﻳـﻦ ﻣـﻮرد واﺿﺢ اﺳﺖ ﻛﻪ ﻫﻤﻮاره ﺳﺮﻋﺖ ﺻﻔﺮ ﺑﺮاﺑﺮ ﺑﺎ ﺗﻮﻗﻒ اﺗﻮﻣﺒﻴﻞ اﺳﺖ ،اﻣﺎ در ﻣﻮاردي ﻣﺸﺎﺑﻪ ﺣﺘﻲ اﮔﺮ %99اﻓﺮادي ﻛﻪ از ﻛﻼس اﺳﺘﻔﺎده ﻣـﻲ ﻛﻨﻨﺪ در ﻳﻚ ﻣﻮرد اﺷﺘﺮاك ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻨﺪ ،ﺑﺎﻳﺪ ﺑﺮاي وﺿﻮح ﺑﻴﺸﺘﺮ ﻛﺎر ﺑﺎ ﻛﻼس ﻣﺘﺪي ﻃﺮاﺣﻲ ﻛﺮد ﻛﻪ ﺑﻪ آن ﻣﻮرد ﭘﺎﺳﺦ دﻫﺪ. ﺑﻨﺎﺑﺮاﻳﻦ در ﻣﺜﺎل ﺑﺎﻻ ،ﺑﻬﺘﺮ اﺳﺖ ﻣﺘﺪي ﻃﺮاﺣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻣﺸﺨﺺ ﻛﻨﺪ آﻳﺎ اﺗﻮﻣﺒﻴﻞ ﺗﻮﻗﻒ ﻛﺮده و ﻳﺎ در ﺣﺎل ﺣﺮﻛﺖ اﺳﺖ.
٣٥١
IsMoving اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪ:اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﻣﻘـﺪاري را از ﻧـﻮع، ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﺪ اﻳﻦ اﺳﺖ ﻛـﻪ ﭘـﺲ از ﺑﺮرﺳـﻲ ﺳـﺮﻋﺖ اﺗﻮﻣﺒﻴـﻞIsMoving ( ﺗﻤﺎم ﻛﺎري ﻛﻪ ﻣﺘﺪ1 ﺑﻌـﺪ،Car ﻛﺪ زﻳﺮ را در ﻛـﻼس. ﺑﺮﮔﺮداﻧﺪ ﺗﺎ ﻣﺸﺨﺺ ﺷﻮد اﺗﻮﻣﺒﻴﻞ ﺗﻮﻗﻒ ﻛﺮده و ﻳﺎ در ﺣﺎل ﺣﺮﻛﺖ اﺳﺖBoolean : وارد ﻛﻨﻴﺪNumberOfDoors از ﺧﺎﺻﻴﺖ // IsMoving - is the car moving? public Boolean IsMoving() { // Is the car's speed zero? if (Speed == 0) return false; return true; } : اﻳﺠﺎد ﻛﻨﻴﺪProgram.cs ﻓﺎﻳﻞMain ﺗﻐﻴﻴﺮات ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در زﻳﺮ ﺑﺮﻧﺎﻣﻪ،( ﺑﺮاي ﺗﺴﺖ اﻳﻦ ﻣﺘﺪ2 static void Main(string[] args) { // Create a new Car Car objCar = new Car(); // Accelerate the car to 25kmph objCar.Accelerate(25); // Report whether or not the car is moving if (objCar.IsMoving() == true) { Console.WriteLine("The car is moving!"); } else { Console.WriteLine("The car is stopped!"); } // Wait for input from the user Console.ReadLine(); } . ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد4-9 ﭘﻨﺠﺮه ﺟﺪﻳﺪي را ﻣﺸﺎﺑﻪ ﺷﻜﻞ.( ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ3
٣٥٢
ﺷﻜﻞ 4-9
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﻳﻦ ﻗﺴﻤﺖ ﻓﻘﻂ ﻣﺘﺪ ﺳﺎده اي را ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﺮده اﻳﻢ ﻛﻪ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﺧﺎﺻﻴﺖ ،Speedدر ﺻﻮرت ﻏﻴﺮ ﺻﻔﺮ ﺑﻮدن آن ﻣﻘﺪار trueو در ﺻﻮرت ﺻﻔﺮ ﺑﻮدن آن ﻣﻘﺪار falseرا ﺑﺮﻣﻲ ﮔﺮداﻧﺪ. ?// IsMoving - is the car moving )(public Boolean IsMoving { ?// Is the car's speed zero )if (Speed == 0 ;return false ;return true } ﻣﻤﻜﻦ اﺳﺖ در اﺑﺘﺪا از ﺣﺎﻟﺖ ﻧﻮﺷﺘﻪ ﺷﺪن اﻳﻦ ﺗﺎﺑﻊ ﺗﻌﺠﺐ ﻛﻨﻴﺪ و اﻳﻦ ﺳﻮال ﭘﻴﺶ ﺑﻴﺎﻳـﺪ ﻛـﻪ ﭼـﺮا دﺳـﺘﻮر returnدوم در ﺑﺨـﺶ elseﻗﺮار داده ﻧﺸﺪه اﺳﺖ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ دﺳﺘﻮر returnﺑﺮاي ﺑﺮﮔﺮداﻧﺪن ﻣﻘﺪاري ﺗﻮﺳﻂ ﺗﺎﺑﻊ ،ﺑﻪ ﻛـﺪي ﻛـﻪ ﺗـﺎﺑﻊ را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده اﺳﺖ ﺑﻪ ﻛﺎر ﻣﻲ رود .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ،در اﺟﺮاي ﺗﺎﺑﻊ ﺑﻪ اوﻟﻴﻦ returnرﺳﻴﺪ ،ﺑﻘﻴﻪ دﺳﺘﻮرات ﺗـﺎﺑﻊ را اﺟـﺮا ﻧﻤـﻲ ﻛﻨﺪ و ﺑﻪ ﻣﺘﺪي ﻛﻪ ﺗﺎﺑﻊ را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده اﺳﺖ ﺑﺮﻣﻲ ﮔﺮدد .ﭘﺲ در اﻳﻨﺠـﺎ اﮔـﺮ ﻣﻘـﺪار Speedﺑﺮاﺑـﺮ ﺑـﺎ ﺻـﻔﺮ ﺑـﻮد ،ﺑﺮﻧﺎﻣـﻪ ﻣﻘـﺪار falseرا ﺑﺮﻣﻲ ﮔﺮداﻧﺪ و دﺳﺘﻮر return trueرا ﻧﻴﺰ اﺟﺮا ﻧﻤﻲ ﻛﻨﺪ .اﻣﺎ اﮔﺮ ﻣﻘﺪار Speedﻣﺨﺎﻟﻒ ﺻﻔﺮ ﺑﻮد ،ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺧﻂ ﺑﻌﺪ از ifﻣﻲ آﻳﺪ ﻛﻪ در اﻳﻦ ﺣﺎﻟﺖ ﺑﺎﻳﺪ ﻣﻘﺪار trueرا ﺑﺮﮔﺮداﻧﺪ .اﻟﺒﺘﻪ اﻳﻦ ﻧﻮع ﻧﻮﺷﺘﻦ ﻛﺪ ﻓﻘﻂ ﺑﺎﻋﺚ ﻛﻮﺗﺎﻫﻲ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺷـﻮد و در ﺳﺮﻋﺖ اﺟﺮاي آن ﻫﻴﭻ ﺗﺎﺛﻴﺮي ﻧﺪارد. اﮔﺮﭼﻪ ﻣﺘﺪي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺗﻌﺮﻳﻒ ﻛﺮده اﻳﻢ ﺳﺎده اﺳﺖ ،اﻣﺎ از ﮔﻴﺞ ﺷﺪن ﻛﺎرﺑﺮ در ﻣﻮرد اﻳﻨﻜﻪ ﺑﺮاي ﺗﻌﻴﻴﻦ ﻣﺘﻮﻗـﻒ ﺑـﻮدن اﺗﻮﻣﺒﻴـﻞ ﭼﻪ ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ را ﺑﺎﻳﺪ ﺑﺮرﺳﻲ ﻛﻨﺪ ﺟﻠﻮﮔﻴﺮي ﻣﻲ ﻛﻨﺪ. اﻣﺎ ﻗﺒﻞ از اﻳﻨﻜﻪ ﺷﺮوع ﻛﻨﻴﺪ و ﺑﺮاي ﻫﺮ ﻣﺴﺌﻠﻪ اي در ﻛﻼس ﻳﻚ ﻣﺘﺪ اﻳﺠﺎد ﻛﻨﻴﺪ ،ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻫﺮ ﭼﻪ ﺗﻌﺪاد ﻣﺘﺪﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي ﻳﻚ ﻛﻼس ﺑﻴﺸﺘﺮ ﺑﺎﺷﻨﺪ ،ﻛﺎر ﺑﺎ آن ﻣﺸﻜﻞ ﺗﺮ ﺧﻮاﻫﺪ ﺑﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ در ﻧﻈﺮ ﮔﺮﻓﺘﻦ اﻳﻦ ﻧﻜﺘﻪ و ﻣﻮرد ﻗﺒﻠﻲ در اﻳﺠﺎد ﻣﺘﺪ و ﺧﺎﺻﻴﺖ ﺑﺮاي ﻳﻚ ﻛﻼس ﺗﻌﺎدل را رﻋﺎﻳﺖ ﻛﻨﻴﺪ. ﻣﻤﻜﻦ اﺳﺖ ﺗﺼﻮر ﻛﻨﻴﺪ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﻣﺘﺪي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺗﻌﺮﻳﻒ ﻛﺮدﻳﻢ ﺑﺎﻋﺚ اﻳﺠﺎد ﻫﻴﭻ رﻓﺘﺎري در ﺑﺮﻧﺎﻣﻪ ﻧﻤﻲ ﺷﻮد ،ﺑﻬﺘﺮ ﺑﻮد از ﻳﻚ ﺧﺎﺻﻴﺖ در اﻳﻦ ﻣﻮرد اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ .ﺑﻠﻪ ،ﻣﻲ ﺗﻮاﻧﺴﺘﻴﻢ ﺑﺮاي اﻳﻦ ﻣﻮرد از ﻳﻚ ﺧﺎﺻﻴﺖ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻣﺎ ،اﺳﺘﻔﺎده از ﻣﺘﺪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﺎرﺑﺮ ﺑﻔﻬﻤﺪ ﻛﻪ اﻳﻦ ﻧﺘﻴﺠﻪ ﺑﻪ ﺻﻮرت ﻣﺴﺘﻘﻴﻢ از ﻳﻚ ﻓﻴﻠﺪ ﺧﻮاﻧﺪه ﻧﻤﻲ ﺷﻮد ،ﺑﻠﻜﻪ ﺗﻮﺳﻂ ﺷﻴﺊ ﻣﺤﺎﺳﺒﻪ ﻣﻲ ﺷﻮد.
٣٥٣
ﻣﺘﺪﻫﺎي ﺳﺎزﻧﺪه: ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﺟﻨﺒﻪ ﻫﺎي ﻃﺮاﺣﻲ ﻛﻼﺳﻬﺎ ،ﻣﻔﻬﻮم ﻣﺘﺪ ﺳﺎزﻧﺪه 1در ﻛﻼس اﺳـﺖ .اﻳﻦ ﻣﺘﺪﻫﺎ ﺷﺎﻣﻞ ﻛـﺪﻫﺎﻳﻲ ﻫـﺴﺘﻨﺪ ﻛـﻪ ﻫﻨﮕﺎم ﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﺪن ﻳﻚ ﺷﻴﺊ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ .اﻳﻦ ﻣﻮرد ﻫﻨﮕﺎﻣﻲ ﻣﻔﻴﺪ اﺳﺖ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﻗﺒـﻞ از اﻳﻨﻜـﻪ ﻛـﺎرﺑﺮ از ﻳـﻚ ﺷﻴﺊ اﺳﺘﻔﺎده ﻛﻨﺪ ،آن را ﺑﻪ ﺻﻮرت ﺧﺎﺻﻲ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﺑﺨﻮاﻫﻴﺪ ﺑﻪ ﺑﻌﻀﻲ از ﺧﺎﺻﻴﺖ ﻫﺎي آن ﻣﻘـﺪار اوﻟﻴـﻪ ﻧـﺴﺒﺖ دﻫﻴـﺪ، ﻫﻤﺎﻧﻨﺪ ﺧﺎﺻﻴﺖ NumberOfDoorsدر ﻛﻼس .Car ﻣﺘﺪﻫﺎي ﺳﺎزﻧﺪه در ﻛﻼس ﻣﺘﺪﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﻧﺎم آﻧﻬﺎ ﺑﺎ ﻧﺎم ﻛﻼس ﻳﻜﻲ اﺳﺖ .ﻫﻤﭽﻨﻴﻦ ﻧﺒﺎﻳﺪ ﺑﺮاي اﻳﻦ ﻣﺘﺪﻫﺎ ﻫﻴﭻ ﻣﻘـﺪار ﺑﺎزﮔـﺸﺘﻲ ﻣﺸﺨﺺ ﻛﺮد )ﺣﺘﻲ .(voidﻳﻚ ﺗﺎﺑﻊ ﺳﺎزﻧﺪه ﺑﺮاي ﻛﻼس ،Carﻣﺘﺪي ﻣﺎﻧﻨﺪ زﻳﺮ ﺧﻮاﻫﺪ ﺑﻮد: )(public Car { // Do some initialization here }
اﻳﺠﺎد ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه: در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ،ﻧﺤﻮه اﻳﺠﺎد ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه ي ﺳﺎده را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه (1ﺑﺮاي اﻳﻨﻜﻪ ﻧﺤﻮه ﻛﺎرﻛﺮد ﻣﺘﺪ ﺳﺎزﻧﺪه را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ،ﺑﺎﻳﺪ ﻣﻘﺪار اوﻟﻴﻪ 4را از ﻣﻘﺎﺑﻞ ﺗﻌﺮﻳـﻒ _numebrOfDoors ﺣﺬف ﻛﻨﻴﻢ .در ﻛﻼس Carﺗﻐﻴﻴﺮات ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را وارد ﻛﻨﻴﺪ: ;public string Color ;private int _speed ;private int _numberOfDoors (2ﺣﺎل ﻣﺘﺪ زﻳﺮ را اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ ﺗﺎﺑﻊ ﺳﺎزﻧﺪه آن اﻳﺠﺎد ﺷﻮد .ﻫﺮ ﻛﺪي ﻛﻪ در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ ،ﻫﻨﮕﺎم ﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﻴﺊ اﺟـﺮا ﻣﻲ ﺷﻮد. // Constructor )(public Car { // Set the default values ;"Color = "White ;_speed = 0 ;_numberOfDoors = 4 Constructor
1
٣٥٤
} . زﻳﺮا ﻣﻘﺪار اﻳﻦ ﻣﺘﻐﻴﺮ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض ﺑﺮاﺑﺮ ﺑﺎ ﺻﻔﺮ ﻣـﻲ ﺷـﻮد،_ ﺑﺎ ﻋﺪد ﺻﻔﺮ ﻛﺎري ﺑﻴﻬﻮده اﺳﺖspeed ﺗﻨﻈﻴﻢ ﻣﻘﺪار:ﻧﻜﺘﻪ . ﻣﻘﺪار اﻳﻦ ﻣﺘﻐﻴﻴﺮ را ﻧﻴﺰ در اﻳﻦ ﻣﺮﺣﻠﻪ ﺗﻨﻈﻴﻢ ﻛﺮده اﻳﻢ،اﻣﺎ ﺑﺮاي ﺗﻜﻤﻴﻞ ﺷﺪن ﻣﺜﺎل ﺑﻪ ﺻﻮرت زﻳﺮ اﺿﺎﻓﻪProgram.cs ﺑﻬﺘﺮ اﺳﺖ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﺟﺪاﻳﻲ را در ﻓﺎﻳﻞ،Car ( ﺑﺮاي ﺗﺴﺖ ﻣﺘﺪ ﺳﺎزﻧﺪه ﻛﻼس3 .ﻛﻨﻴﺪ ﺗﺎ اﻃﻼﻋﺎت ﻳﻚ ﺷﻴﺊ از ﻛﻼس را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﺪ // DisplayCarDetails – // procedure that displays the car's details static void DisplayCarDetails(Car theCar) { // Display the details of the car Console.WriteLine("Color: " + theCar.Color); Console.WriteLine("Number of doors: " + theCar.NumberOfDoors); Console.WriteLine("Current speed: " + theCar.Speed); } . را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﺪDisplayCarDetails را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ ﻣﺘﺪMain ( ﺣﺎل زﻳﺮ ﺑﺮﻧﺎﻣﻪ4 static void Main(string[] args) { // Create a new Car Car objCar = new Car(); // Display the details of the car DisplayCarDetails(objCar); // Wait for input from the user Console.ReadLine(); } . ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد5-9 ﭘﻨﺠﺮه اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ.( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ5
5-9 ﺷﻜﻞ
٣٥٥
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺷﻴﺊ ﺟﺪﻳﺪي از ﻛﻼس Carﺑﺨﻮاﻫﺪ اﻳﺠﺎد ﺷﻮد ،ﻛﺪي ﻛﻪ درون ﺗﺎﺑﻊ ﺳﺎزﻧﺪه ﻧﻮﺷﺘﻪ اﻳﺪ اﺟﺮا ﻣﻲ ﺷﻮد .ﺑﻪ اﻳﻦ ﺻﻮرت ﻣﻲ ﺗﻮاﻧﻴﺪ ﺧﺎﺻﻴﺖ ﻫﺎي ﻛﻼس را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺎدﻳﺮ ﻣﻮرد ﻧﻈﺮﺗﺎن ﻗﺮار دﻫﻴﺪ. // Constructor )(public Car { // Set the default values ;"Color = "White ;_speed = 0 ;_numberOfDoors = 4 } ﻧﺘﻴﺠﻪ اﻳﻦ ﻣﻘﺪار دﻫﻲ اوﻟﻴﻪ را ﻫﻨﮕﺎم اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ،زﻣﺎﻧﻲ ﻛﻪ اﻃﻼﻋﺎت ﻛﻼس در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛـﺮد. دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ اﮔﺮ ﺑﺮاي ﻣﺘﺪ ﺳﺎزﻧﺪه ﻧﻮع داده ﺑﺮﮔﺸﺘﻲ ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ و ﻳﺎ ﺣﺘﻲ از ﻛﻠﻤﻪ voidاﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟﻪ ﺧﻮاﻫﻴﺪ ﺷـﺪ. ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﺘﺪ ﺳﺎزﻧﺪه ﻳﻚ ﻛﻼس ﻫﻤﻮاره داراي ﺳﺎﺧﺘﺎر ﻣﺸﺨﺼﻲ اﺳﺖ. ﺑﺮاي ﺗﺴﺖ ﺷﻴﺊ ،از ﻳﻚ ﻣﺘﺪ ﺟﺪا ﺑﻪ ﻧﺎم DisplayCarDetailsدر ﻓﺎﻳﻞ Program.csاﺳﺘﻔﺎده ﻣﻲ ﻛﻨـﻴﻢ .ﺑـﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﻣﺸﺨﺼﺎت ﭼﻨﺪﻳﻦ ﺷﻴﺊ از ﻧﻮع Carرا ﻧﻤﺎﻳﺶ دﻫﻴﻢ و ﻳﺎ ﻣﺸﺨﺼﺎت ﻳـﻚ ﺷـﻴﺊ را ﭼﻨـﺪﻳﻦ ﻣﺮﺗﺒـﻪ ﻧﻤـﺎﻳﺶ دﻫﻴﻢ ،ﺑﻪ ﻛﺪ ﻛﻤﺘﺮي ﻧﻴﺎز ﺧﻮاﻫﻴﻢ داﺷﺖ. ﻧﻜﺘﻪ :دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻣﺘﺪ DisplayCarDetailsﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﺪ در ﻣﺘﺪ Mainﻓﺮاﺧﻮاﻧﻲ ﺷـﻮد ﺣﺘﻤـﺎً ﺑﺎﻳـﺪ از ﻧـﻮع staticﺗﻌﺮﻳﻒ ﺷﻮد .در ﻣﻮرد ﻣﺘﺪﻫﺎي staticو ﻧﺤﻮه اﺳﺘﻔﺎده از آﻧﻬﺎ در ﻓﺼﻞ 10ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد.
وراﺛﺖ: وراﺛﺖ 1ﻳﻜﻲ از ﻣﺒﺎﺣﺚ ﭘﻴﺸﺮﻓﺘﻪ و ﻫﻤﭽﻨﻴﻦ ﻛﺎرﺑﺮدي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷـﻴﺊ ﮔـﺮا ﻣﺤـﺴﻮب ﻣـﻲ ﺷـﻮد .در ﭼـﺎرﭼﻮب .NETاز وراﺛـﺖ اﺳﺘﻔﺎده زﻳﺎدي ﺷﺪه اﺳﺖ و ﺣﺘﻲ ﺧﻮد ﺷﻤﺎ ﺗﺎﻛﻨﻮن ﻛﻼس ﻫﺎﻳﻲ اﻳﺠﺎد ﻛﺮده اﻳﺪ ﻛﻪ از ﻛﻼﺳﻬﺎي دﻳﮕﺮ ارث ﺑﺮده اﻧﺪ – ﻫﺮ ﻓﺮم وﻳﻨﺪوزي ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد اﻳﺠﺎد ﻣﻲ ﻛﺮدﻳﺪ ،در ﺣﻘﻴﻘﺖ ﻳﻚ ﻛﻼس ﺟﺪﻳﺪ ﺑﻮد ﻛﻪ از ﺑﺴﻴﺎري از اﻃﻼﻋﺎت ﺧﻮد را از ﻛﻼس ﻣﺮﺑﻮط ﺑﻪ ﻳـﻚ ﻓﺮم ﺧﺎﻟﻲ ﺑﻪ ارث ﻣﻲ ﺑﺮد. وراﺛﺖ ﺑﺮاي اﻳﺠﺎد اﺷﻴﺎي ﺑﻪ ﻛﺎر ﺑﺮده ﻣﻲ ﺷﻮد ﻛﻪ "ﺗﻤﺎم اﻋﻀﺎي ﻳﻚ ﺷﻴﺊ دﻳﮕﺮ را داﺷﺘﻪ ﺑﺎﺷﺪ و ﻋﻼوه ﺑﺮ آﻧﻬﺎ ،ﺷـﺎﻣﻞ ﭼﻨـﺪﻳﻦ ﻋـﻀﻮ ﺟﺪﻳﺪ ﺑﺮاي ﺧﻮدش ﺑﺎﺷﺪ" .ﻫﺪف اﺻﻠﻲ وراﺛﺖ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺘﻮاﻧﻴﺪ ﻛﺎراﻳﻲ ﻫﺎي ﻳﻚ ﻛﻼس را ،ﺑﺪون اﻳﻨﻜﻪ ﺑﺪاﻧﻴﺪ آن ﻛﻼس ﺑﻪ ﺻﻮرت دروﻧﻲ ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ ،اﻓﺰاﻳﺶ دﻫﻴﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﺎ اﺳﺘﻔﺎده از وراﺛﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ اﺷﻴﺎﻳﻲ را ﺑﺮ ﭘﺎﻳﻪ اﺷﻴﺎي دﻳﮕﺮ ﻛﻪ ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن دﻳﮕﺮي ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ اﻳﺠﺎد ﻛﻨﻴﺪ ،ﺑﺪون اﻳﻨﻜﻪ ﺑﺪاﻧﻴﺪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن اﺻﻠﻲ ﭼﮕﻮﻧﻪ آن ﺷﻴﺊ ﭘﺎﻳﻪ را اﻳﺠﺎد ﻛﺮده اﻧﺪ.
Inheritance
1
٣٥٦
ﺑﻪ وﺳﻴﻠﻪ وراﺛﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻳﻜﻲ از ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد اﺳﺘﻔﺎده ﻛﺮده ،ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي ﺟﺪﻳﺪي ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ و ﻳـﺎ ﺑﻌـﻀﻲ از ﻣﺘﺪﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي آن را ﺑﺎ ﻣﺘﺪﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي ﻣﻮرد ﻧﻈﺮ ﺧﻮدﺗﺎن ﻋﻮض ﻛﻨﻴﺪ و ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﻼس ﺟﺪﻳﺪي اﻳﺠـﺎد ﻛﻨﻴـﺪ ﻛـﻪ دﻗﻴﻘﺎً ﻧﻴﺎزﻫﺎي ﺗﺎن را ﺑﺮﻃﺮف ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ،ﺑﺎ اﺳﺘﻔﺎده از ﻛﻼس Carﻛﻪ ﻳﻚ ﻛﻼس ﻛﻠﻲ اﺳﺖ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﻛﻼﺳﻬﺎي ﺧﺎﺻﻲ ﺗﺮي ﻣﺎﻧﻨﺪ ﻛﻼﺳﻲ ﺑﺮاي اﺗﻮﻣﺒﻴﻞ ﻫﺎي ﻣﺴﺎﺑﻘﻪ اي ،ﻛﻼﺳﻲ ﺑﺮاي وﺳﺎﻳﻞ ﻧﻘﻠﻴﻪ ﺳﻨﮕﻴﻦ ،ﻛﻼﺳﻲ ﺑﺮاي اﺗﻮﻣﺒﻴﻞ ﻫﺎي ﺳﻮاري و … اﻳﺠﺎد ﻛﻨﻴﺪ. ﻓﺮض ﻛﻨﻴﺪ ﻣﻲ ﺧﻮاﻫﻴﺪ اﺗﻮﻣﺒﻴﻞ ﻫﺎي ﻣﺴﺎﺑﻘﻪ اي را در ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﻪ وﺳﻴﻠﻪ ﻛﻼﺳـﻲ ﺑـﻪ ﻧـﺎم SportsCarﻣـﺪل ﻛﻨﻴـﺪ .ﻛـﻼس SportsCarﻣﺸﺎﺑﻪ ﻛﻼس Carﺧﻮاﻫﺪ ﺑﻮد اﻣﺎ در ﺑﻌﻀﻲ از ﻗﺴﻤﺘﻬﺎ ﺗﻔﺎوﺗﻬﺎي ﺟﺰﺋﻲ دارد .ﺑﺮاي ﻣﺜﺎل ﺗﻌﺪاد درﻫـﺎ در اﺗﻮﻣﺒﻴـﻞ ﻫﺎي ﻣﺴﺎﺑﻘﻪ اي ﻣﻤﻜﻦ اﺳﺖ ﺑﻴﻦ 2ﺗﺎ 6ﻧﺒﺎﺷﺪ و ﻳﺎ در اﻳﻦ ﻛﻼس ،ﻋﻼوه ﺑﺮ ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي ﻣﻮﺟﻮد در ﻛﻼس Carﺑﻪ ﻣﺘﺪﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﻧﻴﺎز دارﻳﺪ ﻛﻪ اﻃﻼﻋﺎﺗﻲ را در ﻣﻮرد ﻛﺎراﻳﻲ و ﻋﻤﻠﻜـﺮد اﺗﻮﻣﺒﻴـﻞ ﺑـﻪ ﻛـﺎرﺑﺮ ﺑﺪﻫـﺪ ،ﻣﺎﻧﻨـﺪ ﻣﺘـﺪﻫﺎي Weightو ﻳـﺎ PowerToWeightRatioﻛﻪ در ﺷﻜﻞ 6-9ﻧﻴﺰ ﻧﺸﺎن داده ﺷﺪه اﻧﺪ. ﻧﻜﺘﻪ :ﺑﻪ ﻛﻼﺳﻲ ﻛﻪ از ﻛﻼس دﻳﮕﺮي ﺑﻪ ارث ﮔﺮﻓﺘﻪ ﺷﻮد )ﻫﻤﺎﻧﻨﺪ ﻛﻼس SportsCarدر ﻣﺜﺎل ﺑﺎﻻ( ،ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه
1
و ﺑﻪ ﻛﻼﺳﻲ ﻛﻪ ﻛﻼﺳﻬﺎي دﻳﮕﺮ از آن ﻣﺸﺘﻖ ﻣﻲ ﺷﻮﻧﺪ )ﻣﺎﻧﻨﺪ ﻛﻼس Carدر ﻣﺜﺎل ﺑﺎﻻ( ﻛﻼس ﭘﺎﻳﻪ 2ﻣﻲ ﮔﻮﻳﻨﺪ. ﻳﻜﻲ از ﻣﻮاردي ﻛﻪ در ﻣﻮرد وراﺛﺖ ﺑﺎﻳﺪ ﺑﺪاﻧﻴﺪ ،ﻧﺤﻮه دﺳﺘﺮﺳﻲ ﻛـﻼس ﻣـﺸﺘﻖ ﺷـﺪه ﺑـﻪ ﻋـﻀﻮ ﻫـﺎي publicو private ﻛﻼس ﭘﺎﻳﻪ اﺳﺖ .ﻫﺮ ﻋﻀﻮ publicاز ﻛﻼس ﭘﺎﻳﻪ ﺑﻪ وﺳﻴﻠﻪ ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ اﺳﺖ ،اﻣﺎ ﻛﻼس ﻫﺎي ﻣﺸﺘﻖ ﺷﺪه ﺑﻪ ﻋﻀﻮ ﻫﺎي privateﻛﻼس ﭘﺎﻳﻪ دﺳﺘﺮﺳﻲ ﻧﺪارﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﻛﻼس SportsCarﺑﺨﻮاﻫﺪ ﺳﺮﻋﺖ ﻳﻚ ﺷﻴﺊ را ﺗﻐﻴﻴﺮ دﻫﺪ ﺑﺎﻳﺪ از ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي ﻣﻮﺟﻮد در ﻛﻼس Carاﺳﺘﻔﺎده ﻛﻨﺪ و ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺻﻮرت ﻣﺴﺘﻘﻴﻢ ﺑﻪ ﻓﻴﻠﺪ _speedدﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ. ﺷﻜﻞ 6-9
اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي ﺟﺪﻳﺪ: ﺑﺮاي درك ﺑﻬﺘﺮ وراﺛﺖ ،در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﻛﻼس ﺟﺪﻳﺪي ﺑﻪ ﻧﺎم SportsCarاﻳﺠﺎد ﻣﻲ ﻛﻨـﻴﻢ ﻛـﻪ از ﻛـﻼس Car ﻣﺸﺘﻖ ﺷﻮد و ﺑﻪ وﺳﻴﻠﻪ آن ﺑﺘﻮاﻧﻴﺪ ﻧﺴﺒﺖ وزن اﺗﻮﻣﺒﻴﻞ ﺑﻪ ﻧﻴﺮوي ﻣﻮﺗﻮر آن را ﺑﺪاﻧﻴﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺑﻪ ارث ﺑﺮدن از ﻛﻼس Car (1ﺑﺮاي اﻳﻦ ﻣﺜﺎل ﺑﺎﻳﺪ ﻳﻚ ﻓﻴﻠﺪ publicﺑﻪ ﻛﻼس Carاﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ ﻗﺪرت اﺗﻮﻣﺒﻴﻞ را ﺑﺮ ﺣﺴﺐ اﺳﺐ ﺑﺨـﺎر در ﺧـﻮد ذﺧﻴﺮه ﻛﻨﺪ .اﻟﺒﺘﻪ اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﻪ ﺻﻮرت دﻗﻴﻖ و درﺳﺖ ﻛﺎر ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ ﻳﻚ ﺧﺎﺻﻴﺖ اﻳﺠﺎد ﻛﻨﻴﺪ و ﺑﻪ وﺳﻴﻠﻪ آن از درﺳـﺖ ﺑﻮدن ﻣﻘﺪار وارد ﺷﺪه ﺗﻮﺳﻂ ﻛﺎرﺑﺮ ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ .اﻣﺎ در اﻳﻨﺠﺎ ﺳﺎدﮔﻲ و ﺳﺮﻋﺖ ﺑﺮاي ﻣـﺎ اﻫﻤﻴـﺖ ﺑﻴـﺸﺘﺮي دارد ،ﺑﻨـﺎﺑﺮاﻳﻦ از ﻓﻴﻠﺪ ﺑﻪ ﺟﺎي ﺧﺎﺻﻴﺖ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .ﻓﺎﻳﻞ ﺣﺎوي ﻛﻼس Carرا ﺑﺎز ﻛﺮده و ﻛﺪ زﻳﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ: ;public string Color Derived Class Base Class
1 2
٣٥٧
;public int HorsePower ;private int _speed ;private int _numberOfDoors (2ﭘﻨﺠﺮه Solution Explorerﺑﺮوﻳﺪ و روي ﻧﺎم ﭘﺮوژه ﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ .از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨـﻪ Add Classرا اﻧﺘﺨــﺎب ﻛــﺮده و ﺑــﺎ اﺳــﺘﻔﺎده از ﭘﻨﺠــﺮه اي ﻛــﻪ ﻧﻤــﺎﻳﺶ داده ﻣــﻲ ﺷــﻮد ﻛــﻼس ﺟﺪﻳــﺪي ﺑــﻪ ﻧــﺎم SportsCar.csاﻳﺠﺎد ﻛﻨﻴﺪ. (3ﺣﺎل ﺑﺎﻳﺪ ﺑﻪ ﻛﻼس SportsCarﺑﮕﻮﻳﻴﻢ ﻛﻪ از ﻛﻼس Carﻣﺸﺘﻖ ﺷﻮد .ﺑـﺮاي اﻳـﻦ ﻛـﺎر در ﻣﻘﺎﺑـﻞ ﻧـﺎم ﻛـﻼس SportsCarﻳﻚ ﻋﻼﻣﺖ :ﻗﺮار داده و ﺳﭙﺲ ﻧﺎم ﻛﻼس ﭘﺎﻳﻪ را ذﻛﺮ ﻣﻲ ﻛﻨﻴﺪ )ﻛﻪ در اﻳﻨﺠﺎ ﺑﺮاﺑﺮ ﺑﺎ Carاﺳـﺖ(. ﺗﻌﺮﻳﻒ ﻛﻼس SportsCarرا ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ: class SportsCar : Car { (4ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﻼس SportsCarداراي ﺗﻤﺎم ﻣﺘﺪﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﻛﻼس Carﺷﺎﻣﻞ ﻣـﻲ ﺷـﻮد .در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ ﻳﻚ ﻓﻴﻠﺪ publicﻛﻪ ﻣﺨﺼﻮص ﻛﻼس SportsCarاﺳﺖ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨـﻴﻢ .ﺑـﺮاي اﻳـﻦ ﻛﺎر ﻛﺪ زﻳﺮ را ﺑﻪ اﻳﻦ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ: ;public int Weight (5ﺑﺮاي ﺗﺴﺖ ﻛﻼس ﺟﺪﻳﺪ ﺑﺎﻳﺪ ﻳﻚ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﺟﺪﻳﺪ ﺑﻪ ﻓﺎﻳﻞ Program.csاﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻛﺪ زﻳﺮ را ﺑـﻪ اﻳـﻦ ﻓﺎﻳﻞ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: – // DisplaySportsCarDetails // procedure that displays a sports car’s details static void DisplaySportsCarDetails(SportsCar )theCar { // Display the details of the sports car ;)(Console.WriteLine Console.WriteLine("Sports Car Horsepower: " + ;)theCar.HorsePower Console.WriteLine("Sports Car Weight: " + ;)theCar.Weight } (6ﺣﺎل زﻳﺮ ﺑﺮﻧﺎﻣﻪ Mainدر ﻓﺎﻳﻞ Program.csرا ﺗﻐﻴﻴﺮ دﻫﻴﻢ .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﺑـﻪ ﻓﻴﻠﺪ Weightدﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ ،ﺑﺎﻳﺪ ﻳﻚ ﺷﻴﺊ از ﻛﻼس SportsCarاﻳﺠﺎد ﻛﻨﻴﻢ ﻧﻪ ﻳﻚ ﺷﻴﺊ از ﻛـﻼس .Carﺗﻐﻴﻴﺮات زﻳﺮ را در ﻣﺘﺪ Mainاﻳﺠﺎد ﻛﻨﻴﺪ: )static void Main(string[] args {
٣٥٨
// Create a new sport car object SportsCar objCar = new SportsCar(); // Modify the number of doors objCar.NumberOfDoors = 2; // Set the horsepower and weight (KG) objCar.HorsePower = 240; objCar.Weight = 1085; // Display the details of the car DisplayCarDetails(objCar); DisplaySportsCarDetails(objCar); // Wait for input from the user Console.ReadLine(); } . ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ7-9 ﭘﻨﺠﺮه اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ.( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ7
7-9 ﺷﻜﻞ
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻧﺎم ﻛﻼس ﭘﺎﻳﻪ را در ﻣﻘﺎﺑﻞ ﻧـﺎم، ﺑﺎﻳﺪ ﻫﻨﮕﺎم ﺗﻌﺮﻳﻒ ﻛﻼس،ﺑﺮاي اﻳﻨﻜﻪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻳﻚ ﻛﻼس از ﻛﻼس دﻳﮕﺮي ﻣﺸﺘﻖ ﺷﺪه اﺳﺖ . ﻗﺮار دﻫﻴﻢ: ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه ﺑﻌﺪ از ﻋﻼﻣﺖ class SportsCar : Car اﻣـﺎ ﺑـﺎ وﺟـﻮد اﻳـﻦ ﻛـﻼس، ﺧﻮاﻫﺪ ﺑـﻮدCar ﺷﺎﻣﻞ ﺗﻤﺎم ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي ﻛﻼسSportsCar ﺑﻪ اﻳﻦ ﺻﻮرت ﻛﻼس ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻓﻴﻠـﺪ ﺟﺪﻳـﺪ ﺗﻌﺮﻳـﻒ. دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪCar ﻛﻼسprivate ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻪ اﻋﻀﺎيSportsCar :ﻣﻲ ﻛﻨﻴﺪ
٣٥٩
;public int Weight اﻳﻦ ﻓﻴﻠﺪ ﻓﻘﻂ در اﺷﻴﺎي ﻛﻪ از ﻛﻼس SportsCarﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﻮﻧﺪ وﺟﻮد ﺧﻮاﻫﻨﺪ داﺷﺖ و اﺷﻴﺎي ﻛﻪ از ﻛﻼس Carﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﻮﻧﺪ ﺷﺎﻣﻞ ﭼﻨﻴﻦ ﻓﻴﻠﺪي ﻧﺨﻮاﻫﻨـﺪ ﺑـﻮد .ﺑـﻪ اﻳـﻦ ﻣـﻮرد ﻫﻤـﻮاره ﺗﻮﺟـﻪ ﻛﻨﻴـﺪ – اﮔـﺮ ﺷـﻴﺊ ﻛـﻪ اﻳﺠـﺎد ﻣـﻲ ﻛﻨﻴـﺪ از ﻛـﻼس SportsCarﻧﺒﺎﺷﺪ و ﺑﺨﻮاﻫﻴﺪ ﺑﻪ ﻓﻴﻠﺪ Weightدر آن ﺷﻴﺊ دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﻴﺪ ،ﻫﻨﮕـﺎم ﻛﺎﻣﭙﺎﻳـﻞ ﺑﺮﻧﺎﻣـﻪ ﺑـﺎ ﺧﻄـﺎ ﻣﻮاﺟـﻪ ﺧﻮاﻫﻴﺪ ﺷﺪ .ﻓﻴﻠﺪ Weightﺗﺤﺖ ﻫﻴﭻ ﺷﺮاﻳﻄﻲ ﻧﻤﻲ ﺗﻮاﻧﺪ در اﺷﻴﺎﻳﻲ ﻛﻪ از ﻛﻼس Carﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﺪه اﻧﺪ وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ ) ﺑﺮاي روﺷﻦ ﺷﺪن ﺑﻬﺘﺮ اﻳﻦ ﻣﻄﻠﺐ ،ﺷﻜﻞ 6-9را ﺑﺒﻴﻨﻴﺪ(. زﻳﺮ ﺑﺮﻧﺎﻣﻪ DisplaySportsCarDetailsﺧﺎﺻﻴﺖ Horsepowerاز ﻛﻼس Carو ﻫﻤﭽﻨـﻴﻦ ﺧﺎﺻـﻴﺖ Weightاز ﻛﻼس SportsCarرا ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﺑـﻪ ﻋﻠـﺖ اﻳﻨﻜـﻪ ﻛـﻼس SportsCarاز ﻛـﻼس Carﻣﺸﺘﻖ ﺷﺪه اﺳﺖ ﺷﺎﻣﻞ ﺗﻤﺎم ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻛﻼس اﺳﺖ. – // DisplaySportsCarDetails // procedure that displays a sports car’s details static void DisplaySportsCarDetails(SportsCar )theCar { // Display the details of the sports car ;)(Console.WriteLine Console.WriteLine("Sports Car Horsepower: " + ;)theCar.HorsePower Console.WriteLine("Sports Car Weight: " + ;)theCar.Weight } ﺣﺎل در زﻳﺮ ﺑﺮﻧﺎﻣﻪ Mainاﺑﺘﺪا ﺑﺎﻳﺪ ﻳﻚ ﺷﻴﺊ از ﻛﻼس SportsCarاﻳﺠﺎد ﻛﻨـﻴﻢ ﺗـﺎ ﺑﺘـﻮاﻧﻴﻢ ﺑـﻪ ﻣﻘـﺪار ﻓﻴﻠـﺪ Weight دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ: // Create a new sport car object ;)(SportsCar objCar = new SportsCar ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻫﻨﮕﺎم اﺳﺘﻔﺎده از ﺗﺎﺑﻊ DisplayCarDetailsﺑﻪ ﺟﺎي اﻳﻨﻜﻪ ﻳﻚ ﺷﻴﺊ از ﻧـﻮع Carرا ﺑﻪ آن ﺑﻔﺮﺳﺘﻴﻢ ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻳﻚ ﺷﻴﺊ SportsCarاﺳﺘﻔﺎده ﻛﻨـﻴﻢ ،زﻳـﺮا ﻛـﻼس SportsCarزﻳـﺮ ﻣﺠﻤﻮﻋـﻪ ﻛـﻼس Carاﺳﺖ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻫﺮ ﺷﻴﺊ از ﻧﻮع SportsCarدر ﺣﻘﻴﻘﺖ ﻳﻚ ﺷﻴﺊ از ﻧﻮع Carاﺳﺖ )ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ در دﻧﻴـﺎي واﻗﻌﻲ ﻧﻴﺰ ﻫﺮ اﺗﻮﻣﺒﻴﻞ ﻣﺴﺎﺑﻘﻪ اي ،در واﻗـﻊ ﻳـﻚ اﺗﻮﻣﺒﻴـﻞ اﺳـﺖ( .ﺑﻌـﺪ از ﻓﺮاﺧـﻮاﻧﻲ ﻣﺘـﺪ ،DisplayCarDetailsﻣﺘـﺪ DisplaySportsCarDetailsرا اﺣﻈﺎر ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺧﺎﺻﻴﺘﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﺷﻴﺊ SportsCarﻧﻴـﺰ ﻧﻤـﺎﻳﺶ داده ﺷﻮد. // Display the details of the car ;)DisplayCarDetails(objCar ;)DisplaySportsCarDetails(objCar
٣٦٠
:GetPowerToWeightRatio اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪ ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن ﻧﺴﺒﺖ وزن اﺗﻮﻣﺒﻴﻞ ﺑﻪ ﻧﻴﺮوي ﻣﻮﺗﻮر آن ﺑﻪ ﻛﺎر ﻣﻲ رود و ﻣﻲGetPowerToWeightRatio ﻣﺘﺪ PowerToWaightRatio ﺧﻮاﻧﺪﻧﻲ اﻳﺠﺎد ﺷﻮد )ﻛﻪ در اﻳﻦ ﺻـﻮرت ﻧـﺎم آن ﺑﺎﻳـﺪ ﺑـﻪ-ﺗﻮاﻧﺪ ﺑﻪ ﺻﻮرت ﻳﻚ ﺧﺎﺻﻴﺖ ﻓﻘﻂ . اﻣﺎ ﺑﺮاي ﺗﻜﻤﻴﻞ ﻣﺜﺎل اﻳﻦ ﻗﺴﻤﺖ ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ آن را ﺑﻪ ﺻﻮرت ﻳﻚ ﻣﺘﺪ ﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ،(ﺗﻐﻴﻴﺮ ﻛﻨﺪ
GetPowerToWeightRatio اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪ:اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﺮاي اﻳـﻦ ﻛـﺎر ﻛـﺪ زﻳـﺮ را ﺑـﻪ.( ﺑﺮاي ﻣﺤﺎﺳﺒﻪ ﻣﻘﺪار ﻣﻮرد ﻧﻈﺮ در اﻳﻦ ﻣﺘﺪ ﺑﺎﻳﺪ ﻧﻴﺮوي ﻣﻮﺗﻮر را ﺑﺮ وزن اﺗﻮﻣﺒﻴﻞ ﺗﻘﺴﻴﻢ ﻛﻨﻴﺪ1 : اﺿﺎﻓﻪ ﻛﻨﻴﺪSportsCar ﻛﻼس // GetPowerToWeightRatio - work out the power to // weight public double GetPowerToWeightRatio() { // Calculate the power-to-weight ratio return (double)HorsePower / Weight; } Program.cs در ﻓﺎﻳـﻞDisplaySportsCarDetails ﻛﺪ زﻳﺮ را ﺑﻪ ﻣﺘﺪ،( ﺑﺮاي ﻣﺸﺎﻫﺪه ﻧﺘﻴﺠﻪ2 :اﺿﺎﻓﻪ ﻛﻨﻴﺪ // DisplaySportsCarDetails – //procedure that displays a sports car’s details static void DisplaySportsCarDetails(SportsCar theCar) { // Display the details of the sports car Console.WriteLine(); Console.WriteLine("Sports Car Horsepower: " + theCar.HorsePower); Console.WriteLine("Sports Car Weight: " + theCar.Weight); Console.WriteLine("Power-to-Weight Ratio: " + theCar.GetPowerToWeightRatio()); } . ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ8-9 ﭘﻨﺠﺮه اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ.( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ3
٣٦١
ﺷﻜﻞ 8-9
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻣﺠﺪداً ﺗﻤﺎم ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻣﺘﺪ ﺟﺪﻳﺪي را ﺑﻪ ﻧـﺎم GetPowerToWeightRatioﺑـﻪ ﻛـﻼس SportsCarاﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ 9-9ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،اﻳﻦ ﻣﺘﺪ ﺑﺮاي ﺗﻤﺎم اﺷﻴﺎﻳﻲ ﻛﻪ از ﻛﻼس SportsCarﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﺪه ﺑﺎﺷﻨﺪ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﺧﻮاﻫﺪ ﺑﻮد. ﺷﻜﻞ 9-9 ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﻣﺘﺪ ﻗﺒﻞ از ﺗﻘﺴﻴﻢ ﻧﻴﺮوي ﻣﻮﺗﻮر اﺗﻮﻣﺒﻴﻞ ﺑﺮ وزن آن ،ﻓﻴﻠﺪ ﺣﺎوي ﻧﻴﺮوي ﻣﻮﺗـﻮر را ﺑـﻪ ﻧـﻮع داده اي double ﺗﺒﺪﻳﻞ ﻛﺮده اﻳﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﮔﻔﺘﻢ ،ﺗﻘﺴﻴﻢ ﻳﻚ ﻣﺘﻐﻴﺮ از ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ ﺑﺮ ﻣﺘﻐﻴـﺮ دﻳﮕـﺮي از ﻧـﻮع ﻋـﺪد ﺻـﺤﻴﺢ، ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﺣﺎﺻﻞ ﻧﻴﺰ از ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ ﺑﺎﺷﺪ .اﻣﺎ در اﻳﻦ ﻣﺘﺪ ﻣﺎ ﺑﻪ ﻗﺴﻤﺖ اﻋﺸﺎر ﺣﺎﺻﻞ ﺗﻘﺴﻴﻢ ﻧﻴﺎز دارﻳﻢ. ﺑﺎ ﺗﺒﺪﻳﻞ ﻳﻜﻲ از ﻃﺮﻓﻴﻦ ﺗﻘﺴﻴﻢ ﺑﻪ ﻧﻮع داده اي ،doubleﺑﺎﻋﺚ ﻣﻲ ﺷﻮﻳﻢ ﻛﻪ ﻧﻮع داده اي دو ﻣﻮردي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻨﺪ ﺑـﺮ ﻳﻜـﺪﻳﮕﺮ ﺗﻘﺴﻴﻢ ﺷﻮﻧﺪ ﻣﺘﻔﺎوت ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﺑﺨﻮاﻫﺪ اﻳﻦ دو ﻣﻘﺪار را ﺑﺮ ﻫﻢ ﺗﻘﺴﻴﻢ ﻛﻨﺪ ﻧﻮع داده اي ﻛﻮﭼﻜﺘﺮ را ) (intﺑﻪ ﻧﻮع داده اي ﺑﺰرﮔﺘﺮ ) (doubleﺗﺒﺪﻳﻞ ﻣـﻲ ﻛﻨـﺪ و ﺳـﭙﺲ ﺗﻘـﺴﻴﻢ را اﻧﺠـﺎم ﻣـﻲ دﻫـﺪ ،ﻫﻤﭽﻨـﻴﻦ ﺣﺎﺻـﻞ ﺗﻘـﺴﻴﻢ را ﻧﻴـﺰ از ﻧـﻮع doubleﺑﺮﻣﻲ ﮔﺮداﻧﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﻌﺪ از ﺗﻘﺴﻴﻢ ﺑﻪ ﻣﻘﺪار اﻋﺸﺎري ﻧﻴﺰ دﺳﺘﺮﺳﻲ ﺧﻮاﻫﻴﻢ داﺷﺖ. // Calculate the power-to-weight ratio ;return (double)HorsePower / Weight
ﺗﻐﻴﻴﺮ دادن ﭘﻴﺶ ﻓﺮض ﻫﺎ: ﻋﻼوه ﺑﺮ اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي ﺟﺪﻳﺪ ﺑﻪ ﻳﻚ ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه ،در ﺷﺮاﻳﻄﻲ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ ﻳﻜـﻲ از ﻣﺘـﺪﻫﺎ و ﻳـﺎ ﺧﺎﺻﻴﺖ ﻫﺎي ﻛﻼس ﭘﺎﻳﻪ ،در ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه ﺑﻪ ﮔﻮﻧﻪ اي دﻳﮕﺮ ﻋﻤﻞ ﻛﻨﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳـﺪ آن ﻣﺘـﺪ و ﻳـﺎ ﺧﺎﺻـﻴﺖ را از اول در ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه ﺑﻨﻮﻳﺴﻴﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺑﺨﺶ ﻣﺘﺪﻫﺎي ﺳﺎزﻧﺪه ﮔﻔﺘﻴﻢ ،اﻳﻦ ﻣﺘﺪﻫﺎ زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﺷﻴﺊ از ﻛﻼس ﺑﺨﻮاﻫﺪ ﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﻮد ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮﻧﺪ و اﺟﺎزه ﻣﻲ دﻫﻨﺪ ﻛﻪ ﺣﺎﻟﺖ اوﻟﻴﻪ اﻋﻀﺎي ﻳﻚ ﺷﻴﺊ را ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ .در ﻣﺘﺪ ﺳﺎزﻧﺪه ﻛﻼس ،Carﻣﻘﺪار _numberOfDoorsرا ﺑﺮاﺑﺮ ﺑﺎ 4در ﻧﻈﺮ ﮔﺮﻓﺘﻴﻢ در ﺻﻮرﺗﻲ ﻛﻪ ﺑﻪ ﻃﻮر ﻣﻌﻤﻮل ﺗﻌﺪاد درﻫﺎ ﺑﺮاي ﻳﻚ اﺗﻮﻣﺒﻴﻞ ﻣﺴﺎﺑﻘﻪ اي 2در اﺳﺖ .در ﻣﺜﺎل ﻗﺒﻠـﻲ ﺑـﺎ ﺗﻨﻈـﻴﻢ
٣٦٢
اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﻌﺪ از اﻳﺠﺎد ﺷﻴﺊ ،ﺗﻌﺪاد درﻫﺎ را ﺑﺮاﺑﺮ ﺑﺎ 2ﻗﺮار دادﻳﻢ .اﻣﺎ ﺳﻮال اﻳﻦ اﺳﺖ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ اﻳﻦ ﻣﻘﺪار را ﻫﻨﮕـﺎم ﻧﻤﻮﻧـﻪ ﺳﺎزي ﺷﺪن ﺷﻴﺊ از ﻛﻼس SportsCarﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ؟ اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻳﻜﻲ از ﻣﺘﺪﻫﺎي ﻛﻼس ﭘﺎﻳﻪ را ﺑﺎ ﻳﻚ ﻣﺘﺪ ﺟﺪﻳﺪ در ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه ﻛﻪ ﺗﻮﺳﻂ ﺧﻮدﺗﺎن ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ ﺗﻌﻮﻳﺾ ﻛﻨﻴﺪ، ﺑﻪ اﻳﻦ ﭘﺮوﺳﻪ overrideﻛﺮدن ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﮔﺮ آن ﻣﺘﺪ را در ﻳﻚ ﺷﻴﺊ از ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ، ﻣﺘﺪ ﺟﺪﻳﺪ اﺟﺮا ﻣﻲ ﺷﻮد اﻣﺎ اﮔﺮ اﻳﻦ ﻣﺘﺪ را در ﻳﻚ ﺷﻴﺊ از ﻛﻼس ﭘﺎﻳﻪ ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ ،ﻣﺘﺪ ﻗﺪﻳﻤﻲ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺧﻮاﻫـﺪ ﮔﺮﻓـﺖ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧـﻪ ﻣـﻲ ﺗـﻮان ﻣﺘـﺪ ﺳـﺎزﻧﺪه ﻛـﻼس Carرا در ﻛـﻼس ،SportsCar overrideﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ override :ﻛﺮدن ﻣﺘﺪ ﺳﺎزﻧﺪه (1ﺑﺮاي overrideﻛﺮدن ﻣﺘﺪ ﺳﺎزﻧﺪه ﻛﻼس Carدر ﻛﻼس ،SportsCarﺗﻨﻬﺎ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ اﻧﺠـﺎم دﻫﻴـﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه ﺟﺪﻳﺪ ﺑﺮاي ﻛﻼس SportsCarاﻳﺠﺎد ﻛﻨﻴﺪ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﻛـﺪ زﻳـﺮ را ﺑـﻪ ﻛـﻼس SportsCarاﺿﺎﻓﻪ ﻛﻨﻴﺪ: // Constructor )(public SportsCar { // Change the default values ;"Color = "Green ;NumberOfDoors = 2 } (2ﺧﻂ زﻳﺮ را از زﻳﺮ ﺑﺮﻧﺎﻣﻪ Mainدر ﻓﺎﻳﻞ Program.csﺣﺬف ﻛﻨﻴﺪ. // Modify the number of doors ;objCar.NumberOfDoors = 2 (3ﺣﺎل ﺑﺮاي ﺗﺴﺖ ﻛﺮدن ﻣﺘﺪ ﺳﺎزﻧﺪه ﻛﻼس ،SportsCarﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﺑﻌﺪ از اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﭘﻨﺠـﺮه اي ﻣـﺸﺎﺑﻪ ﺷﻜﻞ 10-9را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 10-9
٣٦٣
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻣﺘﺪ ﺳﺎزﻧﺪه اي ﻛﻪ ﺑﺮاي ﻛﻼس SportsCarاﻳﺠﺎد ﻛﺮده اﻳﺪ ،ﺑﻌﺪ از ﻣﺘﺪ ﺳﺎزﻧﺪه ﻣﻮﺟﻮد در ﻛﻼس Carاﺟﺮا ﻣﻲ ﺷـﻮد .ﺗﻮﺟـﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه ﺑﺮاي ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه اﻳﺠﺎد ﻛﻨﻴﺪ ،ﺑﺎز ﻫﻢ ﻣﺘﺪ ﺳﺎزﻧﺪه ﻣﻮﺟﻮد در ﻛﻼس ﭘﺎﻳـﻪ اﺣـﻀﺎر ﻣـﻲ ﺷﻮد .اﻣﺎ ،.NETﻣﺘﺪ ﺳﺎزﻧﺪه ﻛﻼس ﭘﺎﻳﻪ را ﻗﺒﻞ از ﻣﺘﺪ ﺳﺎزﻧﺪه ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ .در ﺣﻘﻴﻘﺖ ﺗﺮﺗﻴﺐ اﺟﺮاي ﻣﺘﺪﻫﺎ ﺑﻪ اﻳﻦ ﺻﻮرت اﺳﺖ ﻛﻪ اﺑﺘﺪا ﻣﺘﺪ زﻳﺮ اﺟﺮا ﻣﻲ ﺷﻮد: // Constructor )(public Car { // Set the default values ;"Color = "White ;_speed = 0 ;_numberOfDoors = 4 } ﺳﭙﺲ ﻣﺘﺪ زﻳﺮ اﺟﺮا ﻣﻲ ﺷﻮد: // Constructor )(public SportsCar { // Change the default values ;"Color = "Green ;NumberOfDoors = 2 } ﻫﻤﭽﻨــﻴﻦ ﺗﻮﺟــﻪ ﻛﻨﻴــﺪ ﻛــﻪ ﺑــﺮاي ﺗﻐﻴﻴــﺮ دادن ﺗﻌــﺪاد درﻫــﺎ در ﻛــﻼس ﻣــﺸﺘﻖ ﺷــﺪه ﻧﻤــﻲ ﺗــﻮاﻧﻴﻢ ﺑــﻪ ﺻــﻮرت ﻣــﺴﺘﻘﻴﻢ ﺑــﻪ ﻓﻴﻠــﺪ _numberOfDoorsدﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ ،زﻳﺮا اﻳﻦ ﻓﻴﻠـﺪ در ﻛـﻼس ﭘﺎﻳـﻪ از ﻧـﻮع privateﺗﻌﺮﻳـﻒ ﺷـﺪه اﺳـﺖ و ﻣﺘﺪﻫﺎي ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه ﺑﻪ آن دﺳﺘﺮﺳﻲ ﻧﺪارﻧﺪ .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻـﻴﺖ NumberOfDoorsﺗﻌـﺪاد درﻫـﺎ را ﺑﺮاﺑﺮ ﺑﺎ 2ﻗﺮار ﻣﻲ دﻫﻴﻢ.
ﭼﻨﺪ ﺷﻜﻠﻲ ﺑﻮدن :ﻛﻠﻤﻪ اي ﺗﺮﺳﻨﺎك ،ﻣﻔﻬﻮﻣﻲ ﺳﺎده ﻳﻜﻲ دﻳﮕﺮ از اﺻﻮل ﻣﻬﻢ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا ،ﻣﻔﻬﻮم ﭼﻨﺪ ﺷﻜﻠﻲ 1ﺑﻮدن اﺳﺖ .اﺣﺘﻤﺎﻻً اﻳﻦ ﻣﻔﻬﻮم ﻳﻜﻲ از ﺳـﺨﺖ ﺗـﺮﻳﻦ ﻣﻔـﺎﻫﻴﻢ ﺷﻴﺊ ﮔﺮاﻳﻲ ﺑﻪ ﻧﻈﺮ ﻣﻲ آﻳﺪ ،اﻣﺎ درك آن ﺑﺴﻴﺎر راﺣﺖ اﺳﺖ .در ﺣﻘﻴﻘﺖ ﺗﺎﻛﻨﻮن در ﺑﺮﻧﺎﻣﻪ ﻫـﺎي ﻗﺒﻠـﻲ ﺧـﻮد ﻧﻴـﺰ از ﭼﻨـﺪ ﺷـﻜﻠﻲ ﺑـﻮدن اﺳﺘﻔﺎده ﻛﺮده اﻳﺪ. ﺑﺎر دﻳﮕﺮ ﺑﻪ ﻛﺪ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ي DisplayCarDetailsﺗﻮﺟﻪ ﻛﻨﻴﺪ: )static void DisplayCarDetails(Car theCar Polymorphism
1
٣٦٤
{ // Display the details of the car ;)Console.WriteLine("Color: " + theCar.Color Console.WriteLine("Number of doors: " + ;)theCar.NumberOfDoors Console.WriteLine("Current speed: " + ;)theCar.Speed } ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺧﻂ اول ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،اﻳﻦ ﻣﺘﺪ ﭘﺎراﻣﺘﺮي از ﻧﻮع Carﺑﻪ ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ .اﻣﺎ ﻫﻨﮕﺎم ﻓﺮاﺧـﻮاﻧﻲ آن ﭘﺎراﻣﺘﺮي از ﻧﻮع SportsCarﺑﻪ آن ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد. // Create a new sport car object ;)(SportsCar objCar = new SportsCar // Display the details of the car ;)DisplayCarDetails(objCar ﺳﻮاﻟﻲ ﻛﻪ ﭘﻴﺶ ﻣﻲ آﻳﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﻪ ﻣﺘﺪي ﻛﻪ ﭘﺎراﻣﺘﺮي از ﻧﻮع Carدارد ،ﺷـﻴﺊ از ﻧـﻮع SportsCarرا ﻓﺮﺳﺘﺎد؟ ﺧﻮب ،ﭼﻨﺪ ﺷﻜﻠﻲ ﺑﻮدن ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻳﻚ ﺷﻴﺊ از ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه ﺑﺘﻮاﻧﺪ در ﻣﻮاﻗﻌﻲ ﻛﻪ ﺑﻪ ﻳﻚ ﺷﻴﺊ از ﻛـﻼس ﭘﺎﻳـﻪ ﻧﻴـﺎز اﺳﺖ ،ﻫﻤﺎﻧﻨﺪ ﺷﻴﺊ اي از ﻛﻼس ﭘﺎﻳﻪ ﻋﻤﻞ ﻛﻨﺪ .در اﻳﻦ ﻣﺜﺎل ﺷﻤﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ ﺷﻴﺊ اي از SportsCarﻫﻤﺎﻧﻨـﺪ ﻳـﻚ ﺷـﻴﺊ از ﻛﻼس Carرﻓﺘﺎر ﻛﻨﻴﺪ ،زﻳﺮا ﻛﻼس SportsCarاز ﻛﻼس Carﻣﺸﺘﻖ ﺷﺪه اﺳﺖ .ﭼﻨﺪ ﺷﻜﻠﻲ ﺑﻮدن ﺑﻪ اﻳﻦ دﻟﻴﻞ اﺳﺖ ﻛﻪ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺑﺨﺶ وراﺛﺖ ﮔﻔﺘﻴﻢ ،ﻫﺮ ﺷﻴﺊ از ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه ﺑﺎﻳﺪ داراي ﺗﻤﺎم ﻗﺎﺑﻠﻴﺘﻬﺎي ﻳﻚ ﺷﻴﺊ از ﻛﻼس ﭘﺎﻳـﻪ ﺑﺎﺷـﺪ؛ اﮔﺮﭼـﻪ ﻣﻲ ﺗﻮاﻧﺪ ﻣﺘﺪﻫﺎ و ﻳﺎ ﺧﺎﺻﻴﺘﻬﺎي ﺑﻴﺸﺘﺮي ﻧﻴﺰ داﺷﺘﻪ ﺑﺎﺷﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﻣﺘﺪي را از ﻛﻼس Carﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ ،ﻛـﻼس SportsCarﻧﻴﺰ ﺣﺘﻤﺎً داراي اﻳﻦ ﻣﺘﺪ ﺧﻮاﻫﺪ ﺑﻮد. اﻟﺒﺘﻪ واﺿﺢ اﺳﺖ ﻛﻪ ﻋﻜﺲ اﻳﻦ ﻣﻮرد درﺳﺖ ﻧﻴﺴﺖ .ﻣﺘﺪ DisplaySportsCarDetailsﻛﻪ ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ: static void DisplaySportsCarDetails(SportsCar )theCar ﻧﻤﻲ ﺗﻮاﻧﺪ ﻳﻚ ﺷﻴﺊ از ﻧﻮع Carرا ﻧﻴﺰ ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻛﻨﺪ .ﻛﻼس Carﺗﻀﻤﻴﻦ ﻧﻤﻲ ﻛﻨﺪ ﻛﻪ ﻫﺮ ﻣﺘﺪ و ﻳﺎ ﺧﺎﺻـﻴﺘﻲ ﻛـﻪ در ﻛﻼس SportsCarوﺟﻮد دارد را داﺷﺘﻪ ﺑﺎﺷﺪ ،زﻳﺮا ﻣﺘﺪﻫﺎ و ﻳﺎ ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ در ﻛﻼس SportsCarوﺟﻮد دارﻧﺪ ﻛـﻪ در ﻛﻼس Carﺗﻌﺮﻳﻒ ﻧﺸﺪه اﺳﺖ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ SportsCarﻧﻮع ﺧﺎﺻﻲ از Carاﺳﺖ.
Overrideﻛﺮدن ﻣﺘﺪﻫﺎي ﺑﻴﺸﺘﺮ: اﮔﺮﭼﻪ در ﻗﺴﻤﺖ ﻗﺒﻠﻲ ﻣﺘﺪ ﺳﺎزﻧﺪه ﻛﻼس Carرا در ﻛﻼس override ،SportsCarﻛﺮدﻳﻢ ،اﻣﺎ ﺑﻬﺘـﺮ اﺳـﺖ ﻛـﻪ ﺑـﺎ ﻧﺤﻮه overrideﻛﺮدن ﻳﻚ ﺗﺎﺑﻊ ﻣﻌﻤﻮﻟﻲ ﻧﻴﺰ آﺷﻨﺎ ﺷﻮﻳﻢ.
٣٦٥
ﻣﺘـﺪ. ﺑﺎﻳﺪ آن ﻣﺘﺪ در ﻛـﻼس ﭘﺎﻳـﻪ وﺟـﻮد داﺷـﺘﻪ ﺑﺎﺷـﺪ، ﻛﻨﻴﻢoverride ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﻳﻚ ﻣﺘﺪ را زﻳﺮا ﻋﻤﻠﻜﺮد آن در ﻫﺮ دو ﻧﻮع ﻣﺸﺎﺑﻪ، ﻧﺒﺎﻳﺪ ﺗﻔﺎوﺗﻲ داﺷﺘﻪ ﺑﺎﺷﺪSportsCar و ﻛﻼسCar در ﻛﻼسAccelerate ﻫﻢ ﻓﻘﻂ ﺑﺮاي راﺣﺘﻲ ﻛﺎرﺑﺮ اﺿﺎﻓﻪ ﺷﺪه اﺳﺖ و ﺑﻪ ﻋﻨﻮان رﻓﺘﺎر ﺷﻴﺊ ﺑﻪ ﺷﻤﺎر ﻧﻤﻲ رود ﻛـﻪ آن راIsMoving ﻫﻤﭽﻨﻴﻦ ﻣﺘﺪ.اﺳﺖ اﺿـﺎﻓﻪCalculateAccelerationRate ﺑﻨﺎﺑﺮاﻳﻦ ﻧﻴﺎز دارﻳﻢ ﻛﻪ ﻣﺘﺪ ﺟﺪﻳـﺪي ﺑـﻪ ﻧـﺎم. ﻛﻨﻴﻢoverride در. اﻣﺎ در اﺗﻮﻣﺒﻴﻞ ﻫﺎي ﻣﺴﺎﺑﻘﻪ اي ﺑﺎﻳﺪ ﻣﺤﺎﺳﺒﻪ ﺷـﻮد، ﻓﺮض ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ در ﻳﻚ اﺗﻮﻣﺒﻴﻞ ﻋﺎدي اﻳﻦ ﻣﻘﺪار ﻳﻚ ﻋﺪد ﺛﺎﺑﺖ اﺳﺖ.ﻛﻨﻴﻢ . ﻛﺮدن اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢoverride ﻣﺘﺪ ﺟﺪﻳﺪي ﺑﺮاي،ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ
ﻛﺮدن ﻳﻚ ﻣﺘﺪ دﻳﮕﺮoverride اﺿﺎﻓﻪ ﻛﺮدن و:اﻣﺘﺤﺎن ﻛﻨﻴﺪ : اﺿﺎﻓﻪ ﻛﻨﻴﺪCar ( ﻣﺘﺪ زﻳﺮ را ﺑﻪ ﻛﻼس1 // CalculateAccelerationRate – // assume a constant for a normal car public double CalculateAccelerationRate() { // If we assume a normal car goes from 0-60 in // 14 seconds, that's an average of 4.2 kmph/s return 4.2; } : را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪDisplayCarDetails زﻳﺮ ﺑﺮﻧﺎﻣﻪ ي،( ﺣﺎل ﺑﺮاي ﺗﺴﺖ اﻳﻦ ﻣﺘﺪ2 // DisplayCarDetails – // procedure that displays the car's details static void DisplayCarDetails(Car theCar) { // Display the details of the car Console.WriteLine("Color: " + theCar.Color); Console.WriteLine("Number of doors: " + theCar.NumberOfDoors); Console.WriteLine("Current speed: " + theCar.Speed); Console.WriteLine("Acceleration Rate: " + theCar.CalculateAccelerationRate()); } . ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد11-9 ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺧﺮوﺟﻲ ﻣﺸﺎﺑﻪ ﺷﻜﻞ،( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ3
٣٦٦
ﺷﻜﻞ 11-9 (4ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﻳﻜﻲ از ﻣﺘﺪﻫﺎي ﻛﻼس ﭘﺎﻳﻪ را در ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه overrideﻛﻨﻴﻢ ،آن ﻣﺘﺪ در ﻛـﻼس ﭘﺎﻳـﻪ ﺑﺎﻳﺪ ﺑﺎ ﻛﻠﻤﻪ ﻛﻠﻴﺪي virtualﺗﻌﺮﻳﻒ ﺷﺪه ﺑﺎﺷﺪ .ﺑﻨﺎﺑﺮاﻳﻦ در ﻣﺘﺪ ﺟﺪﻳﺪ ﻛـﻼس ،Carﻛﻠﻤـﻪ virtualرا ﺑـﻪ ﺻﻮرت زﻳﺮ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )(public virtual double CalculateAccelerationRate (5ﺣـــﺎل ﻣـــﻲ ﺗﻮاﻧﻴـــﺪ ﻣﺘـــﺪ CalculateAccelerationRateرا در ﻛـــﻼس ،SportsCar overrideﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ ﻣﺘﺪي در ﻛﻼس SportsCarاﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ ﻧﺎم ،ﺗﻌﺪاد ﭘﺎراﻣﺘﺮ ﻫﺎ و ﻧﻴـﺰ ﻣﻘﺪار ﺑﺮﮔﺸﺘﻲ آن دﻗﻴﻘﺎً ﻣﺸﺎﺑﻪ اﻳﻦ ﻣﺘﺪ در ﻛﻼس Carﺑﺎﺷﺪ و ﻫﻤﭽﻨﻴﻦ در ﺗﻌﺮﻳﻒ ﻣﺘﺪ از ﻛﻠﻤﻪ ﻛﻠﻴﺪي override اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﻣﺘﺪ زﻳﺮ را ﺑﻪ ﻛﻼس SportsCarاﺿﺎﻓﻪ ﻛﻨﻴﺪ: // CalculateAccelerationRate// take the power/weight into consideration )(public override double CalculateAccelerationRate { // You'll assume the same 4.2 value, but you'll // multiply it by the power/weight ratio ;)(return 4.2 * GetPowerToWeightRatio } ﻧﻜﺘﻪ :ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺑﺨﺶ ﻗﺒﻠﻲ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﺑﺮاي overrideﻛﺮدن ﻣﺘﺪ ﺳﺎزﻧﺪه ﻳﻚ ﻛﻼس ،ﻧﻴﺎزي ﺑﻪ اﺳـﺘﻔﺎده از ﻛﻠﻤـﻪ ﻛﻠﻴﺪي overrideﻧﻴﺴﺖ .وﻳﮋوال C#اﻳﻦ ﻛﺎر را ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻧﺠﺎم ﻣﻲ دﻫﺪ. (6ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷـﻜﻞ 12-9ﻣـﺸﺎﻫﺪه ﻣـﻲ ﻛﻨﻴـﺪ ،اﻳـﻦ ﻣﺮﺗﺒـﻪ از ﻣﺘـﺪ ﺗﻌﺮﻳـﻒ ﺷـﺪه در ﻛـﻼس SportsCarاﺳﺘﻔﺎده ﺷﺪه اﺳﺖ.
٣٦٧
ﺷﻜﻞ 12-9
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﻪ وﺳﻴﻠﻪ overrideﻛﺮدن ﻳﻚ ﻣﺘﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﭘﻴﺎده ﺳﺎزي 1ﻣﺘﺪﻫﺎي ﻣﻮﺟﻮد در ﻛﻼس ﭘﺎﻳﻪ را در ﻛـﻼس ﻣـﺸﺘﻖ ﺷـﺪه ﺗﻐﻴﻴـﺮ دﻫﻴﺪ .اﻟﺒﺘﻪ اﻳﻦ ﻛﺎر ﺑﺮاي ﺗﻤﺎم ﻣﺘﺪﻫﺎي ﻛﻼس ﭘﺎﻳﻪ ﻣﻤﻜﻦ ﻧﻴﺴﺖ ،ﺑﻠﻜﻪ ﻣﺘﺪ ﻣﻮرد ﻧﻈﺮ ﺑﺎﻳﺪ ﺑﺎ ﻛﻠﻤـﻪ ﻛﻠﻴـﺪي virtualﻣـﺸﺨﺺ ﺷﻮد ﺗﺎ ﺑﺘﻮاﻧﻴﺪ آن را در ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه overrideﻛﻨﻴﺪ. ﻣﺠﺪداً ﺑﻪ ﻣﻔﻬﻮم ﻛﭙﺴﻮﻟﻲ ﺑﻮدن ﺑﺮﻣﻲ ﮔﺮدﻳﻢ .ﺑﻌﺪ از overrideﻛﺮدن ﻣﺘﺪ ،ﻓﺮدي ﻛﻪ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ اﺻﻼً ﺗﻔـﺎوﺗﻲ را در اﺟﺮاي ﻣﺘﺪ ﻣﺘﻮﺟﻪ ﻧﻤﻲ ﺷﻮد – او ﻓﻘﻂ ﺑﻪ ﻫﻤﺎن ﺻﻮرﺗﻲ ﻛﻪ از اﻳﻦ ﻣﺘﺪ ﻗﺒﻞ از overrideﺷﺪن اﺳﺘﻔﺎده ﻣﻲ ﻛﺮد ﻫﻢ اﻛﻨﻮن ﻫـﻢ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ .اﻣﺎ اﻳﻦ ﻣﺮﺗﺒﻪ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ در واﻗﻊ در ﺣﺎل ﻛﺎر ﺑﺎ ﻳﻚ ﺷﻴﺊ از ﻛﻼس SportsCarاﺳﺖ ﻧﺘﻴﺠـﻪ ﻣﺘﻔـﺎوﺗﻲ را درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ. overrideﻛﺮدن ﻳﻚ ﻣﺘﺪ از ﺑﺴﻴﺎري از ﺟﻬﺎت ﺑﺎ overrideﻛﺮدن ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه ﺗﻔﺎوت دارد .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳـﻚ ﻣﺘـﺪ ﺳﺎزﻧﺪه را overrideﻣﻲ ﻛﻨﻴﺪ ،ﻗﺒﻞ از اﻳﻨﻜﻪ ﻣﺘﺪ ﺳﺎزﻧﺪه ي ﺟﺪﻳﺪ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮد ﻣﺘﺪ ﺳﺎزﻧﺪه ﻗﺒﻠﻲ ﻓﺮاﺧﻮاﻧﻲ ﺧﻮاﻫﺪ ﺷﺪ .اﻣـﺎ اﮔـﺮ ﻳـــﻚ ﻣﺘـــﺪ ﻋـــﺎدي را overrideﻛﻨﻴـــﺪ ،ﻣﺘـــﺪ ﻗﺒﻠـــﻲ ﻓﻘـــﻂ در ﺻـــﻮرﺗﻲ ﻓﺮاﺧـــﻮاﻧﻲ ﺧﻮاﻫـــﺪ ﺷـــﺪ ﻛـــﻪ از دﺳـــﺘﻮر base.MethodNameاﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﻛﻠﻤﻪ ﻛﻠﻴﺪي baseدر ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻋﻀﺎي ﻛـﻼس ﭘﺎﻳـﻪ ﺑﻪ ﻛﺎر ﻣﻲ رود. ﻓﺮض ﻛﻨﻴﺪ ﻣﺘﺪ CalculateAccelerationRateدر ﻛﻼس Carﻳﻚ ﻣﻘﺪار ﺛﺎﺑﺖ را ﺑﺮﻧﻤﻲ ﮔﺮداﻧﺪ ،ﺑﻠﻜﻪ ﺑﻌـﺪ از اﻧﺠﺎم دادن ﻳﻚ ﺳﺮي ﻣﺤﺎﺳﺒﺎت ،ﻣﻘﺪاري را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ و ﺷﻤﺎ ﻣﻲ ﺧﻮاﻫﻴﺪ اﻳﻦ ﻣﺘﺪ در ﻛﻼس ،SportsCarﻋﻼوه ﺑﺮ اﻧﺠﺎم دادن آن ﻣﺤﺎﺳﺒﺎت ،ﻣﻘﺪار ﻧﻬﺎﻳﻲ را در ﻣﻘﺪار ﺗﺎﺑﻊ GetPowerToWeightRatioﻧﻴﺰ ﺿﺮب ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗﻮاﻧﻴـﺪ از دﺳﺘﻮر زﻳﺮ در ﻣﺘﺪ overrideﺷﺪه در ﻛﻼس SportsCarاﺳﺘﻔﺎده ﻛﻨﻴﺪ: * )(return (base.CalculateAccelerationRate ;))(GetPowerToWeightRatio ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﺑﺘﺪا ﺗﺎﺑﻊ CalculateAccelerationRateاز ﻛـﻼس ﭘﺎﻳـﻪ ﻓﺮاﺧـﻮاﻧﻲ ﻣـﻲ ﺷـﻮد .ﺳـﭙﺲ ﻣﻘـﺪار ﺑﺮﮔﺸﺘﻲ اﻳﻦ ﺗﺎﺑﻊ در ﻣﻘﺪار ﺑﺮ ﮔﺸﺘﻲ ﺗﺎﺑﻊ GetPowerToWeightRatioﺿﺮب ﺷﺪه و ﻧﺘﻴﺠﻪ ﺑﻪ ﻋﻨـﻮان ﻣﻘـﺪار ﺟﺪﻳـﺪ ﺗﺎﺑﻊ CalculateAccelerationRateﺑﺮﻣﻲ ﮔﺮدد.
– Implementation 1ﺑﻪ ﻳﻚ ﺳﺮي دﺳﺘﻮراﺗﻲ ﻛﻪ درون ﻳﻚ ﻣﺘﺪ ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ و ﻧﺤﻮه ﻋﻤﻠﻜﺮد آن را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻨﺪ ،ﭘﻴﺎده ﺳﺎزي آن ﻣﺘـﺪ ﻣـﻲ ﮔﻮﻳﻨﺪ.
٣٦٨
ﺑﻪ ارث ﺑﺮدن از ﻛﻼس :Object آﺧﺮﻳﻦ ﻣﻄﻠﺒﻲ ﻛﻪ در ﻣﻮرد وراﺛﺖ ﺑﺎﻳﺪ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ اﻳﻦ اﺳﺖ ﻛﻪ در .NETﺣﺘﻲ اﮔﺮ ﻛﻼﺳﻲ را ﺑﻪ ﺻﻮرت ﻋﺎدي و ﺑﺪن ﺗﻌﻴﻴﻦ ﻛﺮدن ﻛﻼس ﭘﺎﻳﻪ ﺑﺮاي آن ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ ،آن ﻛﻼس از ﻛﻼﺳﻲ ﺑﻪ ﻧﺎم Objectﻣﺸﺘﻖ ﻣﻲ ﺷﻮد .ﻛﻼس Objectﺷﺎﻣﻞ ﭼﻬـﺎر ﻣﺘـﺪ اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﻀﻤﻴﻦ ﻛﻨﻴﺪ در ﺗﻤﺎم ﻛﻼﺳﻬﺎي ﻧﻮﺷﺘﻪ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ .NETوﺟﻮد دارﻧﺪ .اﻟﺒﺘﻪ ﺷﺮح وﻇﻴﻔﻪ اﻳـﻦ ﻣﺘـﺪﻫﺎ ﺧـﺎرج از ﻣﺒﺎﺣﺚ اﻳﻦ ﻛﺘﺎب اﺳﺖ ،ﺑﺎ وﺟﻮد اﻳﻦ دو ﺗﺎﺑﻊ ﭘﺮ اﺳﺘﻔﺎده از آﻧﻬﺎ را در اﻳﻦ ﻗﺴﻤﺖ ﻣﻌﺮﻓﻲ ﻣﻲ ﻛﻨﻴﻢ:
:ToStringاﻳﻦ ﻣﺘﺪ رﺷﺘﻪ اي ﻛﻪ ﺣﺎوي ﻣﺘﻨﻲ ﺑﺮاي ﻣﻌﺮﻓﻲ ﻛﺮدن ﺷﻴﺊ اﺳﺖ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .ﺑﻪ ﺧﺎﻃﺮ دارﻳﺪ ﻛـﻪ در اﺑﺘﺪاي ﻓﺼﻞ ﮔﻔﺘﻢ ﻫﺮ ﺷﻴﺊ ﺑﺎﻳﺪ ﺑﺪاﻧﺪ ﻛﻪ از ﭼﻪ ﻧﻮﻋﻲ اﺳﺖ .در ﺣﻘﻴﻘﺖ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻣﺘﺪ ،ﻳﻚ ﺷﻴﺊ ﻧﻮع ﺧﻮد را ﺑﻪ ﺷـﻤﺎ اﻋﻼم ﻣﻲ ﻛﻨﺪ .اﻟﺒﺘﻪ اﻳﻦ در ﺻﻮرﺗﻲ اﺳﺖ ﻛﻪ اﻳﻦ ﻣﺘﺪ overrideﻧﺸﺪه ﺑﺎﺷﺪ .ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﻛﻼس ،ﻣﻲ ﺗﻮاﻧﻴﺪ اﻳـﻦ ﻣﺘﺪ را overrideﻛﻨﻴﺪ ﺗﺎ ﻳﻚ رﺷﺘﻪ ي ﺑﺎ ﻣﻌﻨـﻲ ﺑـﺮاي ﻣـﺸﺨﺺ ﻛـﺮدن ﺷـﻴﺊ ﺑﺮﮔﺮداﻧـﺪ ،ﺑـﺮاي ﻣﺜـﺎل در ﻛـﻼس Customerاﻳﻦ ﻣﺘﺪ را ﺑﻪ ﺻﻮرﺗﻲ overrideﻛﻨﻴﺪ ﻛﻪ ﻧﺎم ﻣﺸﺘﺮك را ﺑﺮﮔﺮداﻧﺪ .اﮔﺮ در ﻳﻚ ﻛﻼس اﻳﻦ ﺗﺎﺑﻊ را overrideﻧﻜﻨﻴﺪ ،ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض ﻧﺎم ﻛﻼس ﺗﻮﺳﻂ اﻳﻦ ﺗﺎﺑﻊ ﺑﺮﮔﺸﺖ داده ﻣﻲ ﺷﻮد. :GetTypeاﻳﻦ ﻣﺘﺪ ﺷﻴﺊ را از ﻛﻼس Typeﺑﺮﻣﻲ ﮔﺮداﻧﺪ ﻛﻪ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻧﻮع داده اي ﻛﻼس اﺳﺖ.
ﺑﻪ ﺧﺎﻃﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻻزم ﻧﻴﺴﺖ ﻳﻚ ﻛﻼس را ﺑﺎ اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ :از ﻛﻼس Objectﻣـﺸﺘﻖ ﻛﻨﻴـﺪ ،زﻳـﺮا اﻳـﻦ ﻛـﺎر ﺑـﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻧﺠﺎم ﻣﻲ ﺷﻮد.
اﺷﻴﺎ و ﺳﺎﺧﺘﺎرﻫﺎ: ﺑﺎ ﻧﺤﻮه ﻛﺎر ﺑﺎ ﺳﺎﺧﺘﺎرﻫﺎ در ﻓﺼﻞ ﭘﻨﺠﻢ آﺷﻨﺎ ﺷﺪﻳﺪ .ﺳﺎﺧﺘﺎرﻫﺎ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻛﻼﺳﻬﺎ راﻫﻲ را ﻓﺮاﻫﻢ ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ ﺑﺘﻮاﻧﻴـﺪ ﭼﻨـﺪﻳﻦ ﻗﻄﻌـﻪ از اﻃﻼﻋﺎت ﻣﺮﺗﺒﻂ ﺑﻪ ﻫﻢ را در ﻳﻚ ﮔﺮوه ﻗﺮار دﻫﻴﺪ .ﻳﻚ ﺳﺎﺧﺘﺎر ﻫﻢ ﻣﻲ ﺗﻮاﻧﺪ ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﻛﻼس ،ﻋﻼوه ﺑﺮ ﻓﻴﻠﺪ ﺷﺎﻣﻞ ﺧﺎﺻـﻴﺖ و ﻣﺘـﺪ ﻧﻴﺰ ﺑﺎﺷﺪ .در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎ ﺑﻌﻀﻲ از ﺗﻔﺎوﺗﻬﺎي ﻛﻼﺳﻬﺎ و ﺳﺎﺧﺘﺎرﻫﺎ آﺷﻨﺎ ﻣﻲ ﺷﻮﻳﻢ. 2 در اﺻﻄﻼح ﻛﺎﻣﭙﻴﻮﺗﺮي ،ﺳﺎﺧﺘﺎرﻫﺎ ﺑﻪ ﻋﻨﻮان ﻧﻮع ﻫﺎي ﻣﻘﺪاري 1و ﻛﻼﺳﻬﺎ ﺑﻪ ﻋﻨﻮان ﻧﻮع ﻫﺎي ارﺟﺎﻋﻲ ﺷﻨﺎﺧﺘﻪ ﻣـﻲ ﺷـﻮﻧﺪ .ﻫـﺮ ﻣﺘﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد ،ﻗﺴﻤﺘﻲ از ﺣﺎﻓﻈﻪ را اﺷﻐﺎل ﻣﻲ ﻛﻨﺪ و ﻣﺘﻐﻴﻴﺮ ﻫﺎﻳﻲ ﻛﻪ در ﻃﻮل ﻛﺎر ﺧﻮد ﺑﻪ آﻧﻬﺎ ﻧﻴﺎز دارد را در اﻳـﻦ ﻗﺴﻤﺖ اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ و ﻣﻌﻤﻮﻻً ﺑﻌﺪ از اﺟﺮاي ﺗﺎﺑﻊ ،اﻳﻦ ﻗﺴﻤﺖ از ﺣﺎﻓﻈﻪ ﻧﻴﺰ آزاد ﻣﻲ ﺷﻮد .ﻫﻤﭽﻨﻴﻦ ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ ﻛﻪ ﺑﻪ آن ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮﻧﺪ ﻧﻴﺰ در ﺣﻘﻴﻘﺖ در اﻳﻦ ﻗﺴﻤﺖ از ﺣﺎﻓﻈﻪ ﻛﭙﻲ ﻣﻲ ﺷﻮﻧﺪ ﺗﺎ ﻣﺘﺪ ﺑﺘﻮاﻧﺪ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﺪ. ﺳﺎﺧﺘﺎرﻫﺎ ﻣﻌﻤﻮﻻً اﻧﺪازه ﻫﺎي ﻛﻮﭼﻜﻲ دارﻧﺪ ،ﺑﺮاي ﻣﺜﺎل ﺷﺎﻣﻞ ﭼﻨﺪﻳﻦ ﻣﺘﻐﻴﺮ از ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ و ﻳﺎ ﭼﻨﺪ رﺷﺘﻪ ﻫﺴﺘﻨﺪ ﻛﻪ ﻣﻘﺪار ﻛﻤﻲ از ﻓﻀﺎي ﺣﺎﻓﻈﻪ را اﺷﻐﺎل ﻣﻲ ﻛﻨﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ راﺣﺘﻲ آﻧﻬﺎ را ﺑﻪ ﻓﻀﺎي ﻣﺨﺼﻮص ﻳﻚ ﺗﺎﺑﻊ اﻧﺘﻘﺎل دﻫﺪ ﺗﺎ ﺗﺎﺑﻊ ﺑﺘﻮاﻧﺪ از آن اﺳﺘﻔﺎده ﻛﻨﺪ .اﻣﺎ ﻛﻼﺳﻬﺎ ﺑﺴﻴﺎر ﺑﺰرﮔﺘﺮ از ﺳﺎﺧﺘﺎرﻫﺎ ﻫﺴﺘﻨﺪ .ﻳﻚ ﻛﻼس ﻣﻌﻤﻮﻻً ﺷﺎﻣﻞ ﭼﻨﺪﻳﻦ ﻋﻀﻮ از ﻛﻼﺳﻬﺎي دﻳﮕـﺮ اﺳـﺖ .ﺑـﺮاي ﻣﺜﺎل ﻛﻼﺳﻲ ﺑﻪ ﻧﺎم Controlدر ﭼﺎرﭼﻮب .NETوﺟﻮد دارد ﻛﻪ ﺗﻤﺎم ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮرد اﺳﺘﻔﺎده از آن ﻣـﺸﺘﻖ ﻣـﻲ ﺷـﻮﻧﺪ .اﻳـﻦ ﻛﻼس ﺷﺎﻣﻞ 205ﻓﻴﻠﺪ )ﻛﻪ ﺑﺴﻴﺎري از آﻧﻬﺎ ﺷﺎﻣﻞ ﺷﻴﺊ اي از ﻳﻚ ﻛﻼس دﻳﮕﺮ ﻫـﺴﺘﻨﺪ( 7 ،ﻣﺘـﺪ ﺳـﺎزﻧﺪه 163 ،ﺧﺎﺻـﻴﺖ و 524ﻣﺘـﺪ اﺳﺖ .ﻣﺴﻠﻢ اﺳﺖ ﻛﻪ ﻓﻀﺎﻳﻲ ﻛﻪ ﭼﻨﻴﻦ ﻛﻼﺳﻲ از ﺣﺎﻓﻈﻪ اﺷﻐﺎل ﻣﻲ ﻛﻨﺪ ﺑﺴﻴﺎر ﺑﻴﺸﺘﺮ از ﻳﻚ ﺳـﺎﺧﺘﺎر اﺳـﺖ و ﻛـﺎﻣﭙﻴﻮﺗﺮ ﻧﻤـﻲ ﺗﻮاﻧـﺪ در ﺻﻮرت ﻟﺰوم آن را ﺑﻪ راﺣﺘﻲ ﺑﻪ ﻓﻀﺎي ﻣﺨﺼﻮص ﺑﻪ ﻳﻚ ﺗﺎﺑﻊ اﻧﺘﻘﺎل دﻫﺪ .ﺑﺮاي ﺣﻞ اﻳﻦ ﻣﺸﻜﻞ از آدرس ﻛﻼﺳﻬﺎ در ﺣﺎﻓﻈـﻪ اﺳـﺘﻔﺎده
Value Type Reference Type
1 2
٣٦٩
ﻣﻲ ﻛﻨﻨﺪ .ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ ﻛﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﺷﻴﺊ ﺑﺮاي ﻣﺮﺗﺒﻪ اول در ﻗﺴﻤﺘﻲ از ﺣﺎﻓﻈﻪ اﻳﺠﺎد ﻣﻲ ﺷﻮد ،اﮔﺮ ﺑﺨﻮاﻫﻴﻢ آن را ﺑﻪ ﻳﻚ ﺗـﺎﺑﻊ ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ اﻧﺘﻘﺎل دﻫﻴﻢ ﻛﻞ ﺷﻴﺊ را ﻣﺠﺪداً در ﻓﻀﺎي ﻣﺨﺼﻮص ﺗﺎﺑﻊ ﻛﭙﻲ ﻧﻤﻲ ﻛﻨﻴﻢ ،ﺑﻠﻜﻪ آدرس ﻛﻨﻮﻧﻲ ﺷـﻴﺊ را در ﺣﺎﻓﻈـﻪ ﺑـﻪ ﺗﺎﺑﻊ ﻣﻲ ﻓﺮﺳﺘﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺗﺎﺑﻊ در ﺻﻮرت ﻧﻴﺎز ﻣﻲ ﺗﻮاﻧﺪ ﺑﺎ اﺳﺘﻔﺎده از آدرس ﺷﻴﺊ ،ﺑﻪ آن دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ. ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ در ﺻﻮرت ﻧﻴﺎز ﺑﻪ اﻧﺘﻘﺎل ﺳﺎﺧﺘﺎرﻫﺎ ﻣﻘﺪار آﻧﻬﺎ ﻣﻨﺘﻘﻞ ﻣﻲ ﺷﻮد ،ﺑﻪ آﻧﻬﺎ ﻧﻮع ﻫﺎي ﻣﻘﺪاري و ﺑﺮاي اﻳﻨﻜﻪ در ﺻـﻮرت ﻧﻴﺎز ﺑﻪ اﻧﺘﻘﺎل ﻛﻼﺳﻬﺎ ﻓﻘﻂ آدرس ﻗﺮارﮔﻴﺮي آﻧﻬﺎ در ﺣﺎﻓﻈﻪ ﻣﻨﺘﻘﻞ ﻣﻲ ﺷﻮد ،ﺑﻪ ﻛﻼﺳﻬﺎ ﻧﻮع ﻫﺎي ارﺟﺎﻋﻲ ﻣﻲ ﮔﻮﻳﻨﺪ. در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﮔﻔﺘﻢ ﻛﻪ ﻳﻚ ﺷﻴﺊ از ﻛﻼس ﻣﻲ ﺗﻮاﻧﺪ داراي ﭼﻨﺪﻳﻦ ﻧﺎم ﺑﺎﺷﺪ )ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ از ﭼﻨﺪﻳﻦ ﻗﻼب آوﻳﺰان ﺷﻮد( .دﻟﻴـﻞ اﻳﻦ ﻣﻮرد اﻳﻦ اﺳﺖ ﻛﻪ ﻳﻚ ﻣﺘﻐﻴﺮ ﻛﻪ ﺑﺮاي ﻳﻚ ﺷﻴﺊ از ﻛﻼس ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ در واﻗﻊ ﻣﺤﺘﻮي ﺧﻮد ﺷﻴﺊ ﻧﻴﺴﺖ ،ﺑﻠﻜﻪ ﻣﺤﺘﻮي آدرس ﻗﺮارﮔﻴﺮي آن ﺷﻴﺊ در ﺣﺎﻓﻈﻪ اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗﻮاﻧﻴﻢ ﭼﻨﺪﻳﻦ ﻣﺘﻐﻴﺮ ﺑﺎ ﻧﺎﻣﻬﺎي ﻣﺘﻔﺎوت ﺗﻌﺮﻳـﻒ ﻛﻨـﻴﻢ و آدرس ﺷـﻴﺊ را در آﻧﻬـﺎ ﻗـﺮار دﻫﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﺷﻴﺊ از ﻫﺮ ﻛﺪام از اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﻫﻤﭽﻨﻴﻦ اﮔﺮ ﺑﺎ اﺳﺘﻔﺎده از ﻳﻜﻲ از اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﺷﻴﺊ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ ،ﺷﻴﺊ ﻣﻮردﻧﻈﺮ ﺑﺮاي ﺗﻤﺎم ﻣﺘﻐﻴﻴﺮ ﻫﺎي دﻳﮕﺮ ﻧﻴﺰ ﺗﻐﻴﻴﺮ ﻣﻲ ﻛﻨﺪ. ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎم ﺗﺼﻤﻴﻢ ﮔﻴﺮي ﺑﻴﻦ ﺳﺎﺧﺘﺎر و ﻛﻼس ﻫﻤﻮاره در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ اﮔﺮ اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴـﺪ در ﻳـﻚ ﮔـﺮوه ﻗـﺮار دﻫﻴﺪ ﻛﻮﭼﻚ ﺑﻮدﻧﺪ ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ از ﺳﺎﺧﺘﺎرﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت اﺳﺘﻔﺎده از ﻛﻼﺳﻬﺎ ﺑﻬﺘﺮ از اﺳـﺘﻔﺎده از ﺳـﺎﺧﺘﺎرﻫﺎ اﺳـﺖ. اﻟﺒﺘﻪ ﻛﻼﺳﻲ ﻛﻪ در ﺑﺎﻻ ﻣﺜﺎل زدﻳﻢ ﻧﻴﺰ ﻛﻼس ﺑﺴﻴﺎر ﺑﺰرﮔﻲ اﺳﺖ و ﺣﺘﻤﺎً ﻧﺒﺎﻳﺪ ﺣﺠﻢ اﻃﻼﻋﺎت ﺑﻪ اﻳﻦ اﻧﺪازه ﺑﺎﺷﺪ ﺗﺎ از ﻛـﻼس اﺳـﺘﻔﺎده ﻛﻨﻴﺪ. ﻫﻤﭽﻨﻴﻦ ﻳﻜﻲ دﻳﮕﺮ از ﺗﻔﺎوﺗﻬﺎي ﺳﺎﺧﺘﺎرﻫﺎ ﺑﺎ ﻛﻼﺳﻬﺎ در اﻳﻦ اﺳﺖ ﻛﻪ ﺳﺎﺧﺘﺎرﻫﺎ داراي ﻣﺒﺤﺚ وراﺛﺖ ﻧﻴﺴﺘﻨﺪ.
ﻛﻼﺳﻬﺎي ﭼﺎرﭼﻮب :.NET اﮔﺮﭼﻪ ﭼﺎرﭼﻮب .NETرا در ﻓﺼﻞ دوم ﺑﻪ ﻃﻮر ﻛﻠﻲ ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ ،در اﻳﻦ ﻗﺴﻤﺖ ﺳﻌﻲ ﻣﻲ ﻛﻨـﻴﻢ ﺑـﻪ ﻗـﺴﻤﺘﻬﺎﻳﻲ از ﺳـﺎﺧﺘﺎر اﻳـﻦ ﭼﺎرﭼﻮب ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ در ﻃﺮاﺣﻲ ﻛﻼﺳﻬﺎ ﺑﻪ ﺷﻤﺎ ﻛﻤﻚ ﻛﻨﺪ ﻧﮕﺎﻫﻲ ﺑﻴﻨﺪازﻳﻢ .ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﻗﺴﻤﺖ ﻓـﻀﺎي ﻧﺎﻣﻬـﺎ و ﻧﺤـﻮه اﻳﺠـﺎد و اﺳﺘﻔﺎده از آﻧﻬﺎ در ﺑﺮﻧﺎﻣﻪ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد.
ﻓﻀﺎي ﻧﺎم: ﻳﻜﻲ از ﻗﺴﻤﺘﻬﺎي ﻣﻬﻢ ﭼﺎرﭼﻮب ،.NETﻛﻠﻜﺴﻴﻮن ﻋﻈﻴﻢ ﻛﻼﺳﻬﺎي آن اﺳﺖ .در ﭼﺎرﭼﻮب .NETﺣﺪود 3500ﻛﻼس در راﺑﻄﻪ ﺑﺎ ﻣﻮارد ﻣﺨﺘﻠﻒ وﺟﻮد دارد ،اﻣﺎ ﺳﻮال اﻳﻦ اﺳﺖ ﻛﻪ ﭼﮕﻮﻧﻪ ﺑﻪ ﻋﻨﻮان ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻛـﻼس ﻣـﻮرد ﻧﻈﺮﺗـﺎن را در ﺑـﻴﻦ اﻳـﻦ ﻛﻼﺳﻬﺎ ﭘﻴﺪا ﻛﻨﻴﺪ؟ 1 ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﭼﺎرﭼﻮب .NETﺑﻪ ﭼﻨﺪﻳﻦ ﮔﺮوه ﻣﺨﺘﻠﻒ ﺑﻪ ﻧﺎم ﻓﻀﺎي ﻧﺎم ﺗﻘﺴﻴﻢ ﻣﻲ ﺷﻮد ﻛﻪ ﻫﺮ ﻛﺪام از آﻧﻬﺎ ﺣﺎوي ﭼﻨﺪﻳﻦ ﻛﻼس ﻣﺮﺗﺒﻂ ﺑﻪ ﻫﻢ اﺳﺖ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﮔﺮ ﺑﻪ دﻧﺒﺎل ﻛﻼﺳﻲ ﺑﺮاي ﻳﻚ ﻛﺎر ﺧﺎص ﺑﺎﺷﻴﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻓﻘﻂ ﻛﻼﺳﻬﺎي داﺧﻞ ﻓﻀﺎي ﻧـﺎم ﻣﺮﺑﻮط ﺑﻪ آن ﻛﺎر را ﺟﺴﺘﺠﻮ ﻛﻨﻴﺪ. ﺧﻮد اﻳﻦ ﻓﻀﺎي ﻧﺎﻣﻬﺎ ﻧﻴﺰ ﺑﻪ ﺻﻮرت ﺳﻠﺴﻠﻪ ﻣﺮاﺗﺒﻲ ﻫﺴﺘﻨﺪ ،ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ ﻛﻪ ﻳﻚ ﻓﻀﺎي ﻧﺎم ﺧﻮد ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺪ ﺷﺎﻣﻞ ﭼﻨﺪﻳﻦ ﻓﻀﺎي ﻧﺎم دﻳﮕﺮ ﺑﺎﺷﺪ ،ﻛﻪ آﻧﻬﺎ ﻧﻴﺰ ﺑﻪ ﻧﻮﺑﻪ ﺧﻮد ﻛﻼﺳﻬﺎي داﺧﻞ آن ﻓﻀﺎي ﻧﺎم را دﺳﺘﻪ ﺑﻨﺪي ﻣﻲ ﻛﻨﻨﺪ. ﺑﻴﺸﺘﺮ ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﭼﺎرﭼﻮب .NETدر ﻓﻀﺎي ﻧﺎم Systemو ﻳﺎ ﻓﻀﺎي ﻧﺎﻣﻬﺎي ﻣﻮﺟﻮد در آن دﺳﺘﻪ ﺑﻨﺪي ﺷﺪه اﻧﺪ .ﺑﺮاي ﻣﺜﺎل:
NameSpace
1
٣٧٠
System.Dataﺷﺎﻣﻞ ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت ذﺧﻴﺮه ﺷﺪه در ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺖ. System.Xmlﺷﺎﻣﻞ ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي ﺧﻮاﻧﺪن و ﻧﻮﺷﺘﻦ ﺳﻨﺪﻫﺎي XMLاﺳﺖ. System.Windows.Formsﺷﺎﻣﻞ ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي ﺗﺮﺳﻴﻢ ﻳﻚ ﻓﺮم و ﻛﻨﺘﺮﻟﻬﺎي آن روي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ اﺳﺖ. System.Netﺷﺎﻣﻞ ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي اﻳﺠﺎد ارﺗﺒﺎﻃﺎت ﺷﺒﻜﻪ اي در ﺑﺮﻧﺎﻣﻪ اﺳﺖ.
ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻛﻼس در ﻳﻚ ﻓﻀﺎي ﻧﺎم ﻗﺮار ﻣﻲ ﮔﻴﺮد ،ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ آن ﻋﻼوه ﺑﺮ ذﻛﺮ ﻧﺎم ﻛﻼس ،ﺑﺎﻳـﺪ ﻓـﻀﺎي ﻧـﺎم آن را ﻧﻴـﺰ ﻣﺸﺨﺺ ﻛﻨﻴﻢ .اﻟﺒﺘﻪ ﺗﺎﻛﻨﻮن در ﺑﺮﻧﺎﻣﻪ ﻫﺎ از ﻧﺎم ﻛﻮﺗﺎه ﺷﺪه آﻧﻬﺎ ،ﻳﻌﻨﻲ ﻓﻘﻂ ﻧﺎم ﺧﻮد ﻛﻼس اﺳﺘﻔﺎده ﻛﺮده و ﻓﻀﺎي ﻧـﺎم آن را ﻣـﺸﺨﺺ ﻧﻤﻲ ﻛﺮدﻳﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ در ﻗﺴﻤﺖ ﻗﺒﻠﻲ وﻗﺘﻲ ﮔﻔﺘﻴﻢ ﻛﻪ ﺗﻤﺎم ﻛﻼﺳﻬﺎ از ﻛﻼس Objectﻣﺸﺘﻖ ﻣـﻲ ﺷـﻮﻧﺪ ،در ﺣﻘﻴﻘـﺖ ﻧـﺎم ﻛﻼس را ﺧﻼﺻـﻪ ﻛـﺮدﻳﻢ .زﻳـﺮا ﻛـﻼس Objectدر ﻓـﻀﺎي ﻧـﺎم Systemﻗـﺮار دارد و ﻫﻤـﻪ ﻛﻼﺳـﻬﺎ در واﻗـﻊ از ﻛـﻼس System.Objectﻣــﺸﺘﻖ ﻣــﻲ ﺷــﻮﻧﺪ .ﻫﻤﭽﻨــﻴﻦ ﻛــﻼس Consoleدر واﻗــﻊ ﻧــﺎم ﺧﻼﺻــﻪ ﺷــﺪه ﻛــﻼس System.Consoleاﺳﺖ و ﻛﺪ زﻳﺮ: ;)(Console.ReadLine ﺑﺎ ﻛﺪ زﻳﺮ ﻣﻌﺎدل اﺳﺖ: ;)(System.Console.ReadLine ﻫﺮ ﻛﻼس ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﻳﻚ ﻓﻀﺎي ﻧﺎم ﺗﻌﻠﻖ داﺷﺘﻪ ﺑﺎﺷﺪ و ﻫﻤﭽﻨﻴﻦ ﻧﻤﻲ ﺗﻮاﻧﺪ ﻋﻀﻮ ﻫﻴﭻ ﻓﻀﺎي ﻧﺎﻣﻲ ﻧﺒﺎﺷﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻫـﺮ ﻛﻼس ﺑﺎﻳﺪ دﻗﻴﻘﺎً در ﻳﻚ ﻓﻀﺎي ﻧﺎم ﻗﺮار داﺷﺘﻪ ﺑﺎﺷﺪ .اﻣﺎ ﺳﻮال اﻳﻦ اﺳﺖ ﻛﻪ ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ ﺗﺎﻛﻨﻮن ﻣﻲ ﻧﻮﺷﺘﻴﻢ ﻋﻀﻮ ﭼﻪ ﻓﻀﺎي ﻧﺎﻣﻲ ﺑﻮدﻧﺪ؟ ﺧﻮب ،اﮔﺮ ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻧﮕﺎه دﻗﻴﻘﺘﺮي ﺑﻴﺎﻧﺪازﻳﺪ ،ﺧﻮاﻫﻴﺪ دﻳﺪ ﻛﻪ در ﺑﺎﻻﺗﺮﻳﻦ ﻗﺴﻤﺖ ﻛﺪ ،ﺑﻼﻛﻲ وﺟﻮد دارد ﻛﻪ ﺑﺎ ﻛﻠﻤﻪ ﻛﻠﻴﺪي namespaceﺷﺮوع ﻣﻲ ﺷﻮد و در ﻣﻘﺎﺑﻞ آن ﻧﺎم ﭘﺮوژه وارد ﺷﺪه اﺳﺖ .ﺑﺮاي ﻣﺜﺎل ﻛﻼس ﻫـﺎﻳﻲ ﻛـﻪ در اﻳـﻦ ﻓـﺼﻞ در ﭘﺮوژه Objectsاﻳﺠﺎد ﻛﺮدﻳﻢ ،ﻫﻤﮕﻲ درون ﺑﻼﻛﻲ ﺑﻪ ﺻﻮرت زﻳﺮ ﻗﺮار ﮔﺮﻓﺘﻪ ﺑﻮدﻧﺪ: namespace Objects { … } ﺑﻨــﺎﺑﺮاﻳﻦ ﻧــﺎم اﺻــﻠﻲ ﻛــﻼس Carﺑــﻪ ﺻــﻮرت Objects.Carو ﻧــﺎم اﺻــﻠﻲ ﻛــﻼس SportsCarﺑــﻪ ﺻــﻮرت Objects.SportsCarﺑﻮده اﺳﺖ. ﻫﺪف اﺻﻠﻲ اﻳﺠﺎد ﻓﻀﺎﻫﺎي ﻧﺎم در .NETﺳﺎده ﺗﺮ ﻛﺮدن اﺳﺘﻔﺎده از ﻛﻼﺳﻬﺎ ﺑﺮاي ﻛﺎرﺑﺮان آﻧﻬﺎ اﺳﺖ .ﻓﺮض ﻛﻨﻴﺪ ﻛﻼﺳـﻬﺎي ﺧـﻮد را ﺑﻌﺪ از ﺗﻜﻤﻴﻞ ﺷﺪن در اﺧﺘﻴﺎر ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ دﻳﮕﺮي ﻗﺮار دﻫﻴﺪ ﺗﺎ از آﻧﻬﺎ در ﺑﺮﻧﺎﻣﻪ ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﺪ .اﮔﺮ او ﻧﻴﺰ در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد ﻛﻼﺳـﻲ ﺑﻪ ﻧﺎم Carاﻳﺠﺎد ﻛﺮده ﺑﻮد ،ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻴﻦ اﻳﻦ دو ﻛﻼس ﺗﻔﺎوت ﻗﺎﺋﻞ ﺷﻮد؟ ﺧﻮب ،ﻧﺎم واﻗﻌﻲ ﻛﻼس ﺷﻤﺎ در ﺣﻘﻴﻘﺖ ﺑﺮاﺑﺮ ﺑـﺎ Objects.Carاﺳـﺖ و ﻧـﺎم ﻛـﻼس او ﻧﻴـﺰ ﻣـﻲ ﺗﻮاﻧـﺪ ﻫـﺮ ﭼﻴـﺰي ﻣﺎﻧﻨـﺪ MyOwnNameSpace.Carﺑﺎﺷﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﺣﺘﻤﺎل اﺷﺘﺒﺎه ﺷﺪن اﻳﻦ دو ﻛﻼس ﺑﺎ ﻳﻜﺪﻳﮕﺮ از ﺑﻴﻦ ﻣﻲ رود.
٣٧١
ﻧﻜﺘﻪ :اﻟﺒﺘﻪ دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻧﺎم Objectsﻛﻪ ﺑﺮاي ﻓﻀﺎي ﻧﺎم اﻳﻦ ﭘﺮوژه اﻧﺘﺨﺎب ﻛﺮدﻳﻢ ،اﺻﻼً ﻧـﺎم ﻣﻨﺎﺳـﺒﻲ ﺑـﺮاي ﻳـﻚ دﺳـﺘﻪ از ﻛﻼﺳﻬﺎي ﻣﺮﺗﺒﻂ ﺑﻪ ﻫﻢ ﻧﻴﺴﺖ ،زﻳﺮا ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻧﻤﻲ ﺗﻮان ﻫﻴﭻ اﻃﻼﻋﺎﺗﻲ راﺟﻊ ﺑﻪ ﻛﻼﺳﻬﺎي داﺧﻞ اﻳﻦ ﻓﻀﺎي ﻧـﺎم ﺑﺪﺳـﺖ آورد .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻓﻘﻂ اﻳﻦ ﻧﺎم را اﻧﺘﺨﺎب ﻛﺮدﻳﻢ ﻛﻪ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﺑﺮﻧﺎﻣﻪ ﻫﺎي اﻳﻦ ﻓﺼﻞ ﺑﺎﺷﺪ. ﺑﺮاي آﺷﻨﺎﻳﻲ ﺑﻴﺸﺘﺮ ﺑﺎ ﻓﻀﺎي ﻧﺎﻣﻬﺎي ﻣﻮﺟﻮد در .NETﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺿﻤﻴﻤﻪ ي 2ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ.
راﻫﻨﻤﺎي :using ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻓﺼﻞ ﻫﻔﺘﻢ ﮔﻔﺘﻢ ،ﺑﺮاي اﺳﺘﻔﺎده از ﻳﻚ ﻛﻼس ﺑﺪون ذﻛﺮ ﻓﻀﺎي ﻧﺎم آن ،ﺑﺎﻳﺪ ﻓﻀﺎي ﻧـﺎم آن ﻛـﻼس را ﺑـﺎ اﺳـﺘﻔﺎده از راﻫﻨﻤﺎي 1usingﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ .اﻫﻤﻴﺖ اﺳﺘﻔﺎده از اﻳﻦ راﻫﻨﻤﺎ ﻣﻤﻜﻦ اﺳﺖ ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺣﺎل ﻛﺎر ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﻮﭼـﻚ ﻫــﺴﺘﻴﺪ ،ﻧﻤﺎﻳــﺎن ﻧــﺸﻮد ،اﻣــﺎ ﻓــﺮض ﻛﻨﻴــﺪ ﺑﺨﻮاﻫﻴــﺪ ﺑــﻪ ﻛﻼﺳــﻲ ﻣﺎﻧﻨــﺪ ServiceDescriptionدر ﻓــﻀﺎي ﻧــﺎم System.Web.Services.Descriptionدﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﻴﺪ .واﺿﺢ اﺳﺖ ﻛﻪ ذﻛﺮ اﺳﻢ ﻛـﻼس و ﻓـﻀﺎي ﻧﺎم آن در ﻫﺮ ﺑﺎر اﺳﺘﻔﺎده از اﻳﻦ ﻛﻼس ﻛﺎر ﺑﺴﻴﺎر ﺳﺨﺘﻲ اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ﻓﻀﺎي ﻧﺎم آن ،ﻫﺮ ﻣﺮﺗﺒﻪ ﻓﻘﻂ ﻧﺎم ﻛﻼس را ذﻛﺮ ﻛﻨﻴﺪ. ﺗﻤﺎم ﻓﻀﺎي ﻧﺎﻣﻬﺎﻳﻲ ﻛﻪ ﻣـﻲ ﺧﻮاﻫﻴـﺪ ﺑـﻪ ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ ،ﺑﺎﻳـﺪ در اﺑﺘـﺪاي ﻛـﺪ و ﻗﺒـﻞ از ﻫـﺮ دﺳـﺘﻮري )ﻗﺒـﻞ از دﺳـﺘﻮر namespaceﻛﻪ ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن ﻓﻀﺎي ﻧﺎم ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻛﺎر ﻣﻲ رود( ،ﺑﺎ اﺳﺘﻔﺎده از usingﻣﺸﺨﺺ ﺷﻮﻧﺪ. ﺗﻨﻬﺎ ﻣﺸﻜﻠﻲ ﻛﻪ ﻫﻨﮕﺎم اﺳﺘﻔﺎده از اﻳﻦ راﻫﻨﻤﺎ ﻣﻤﻜﻦ اﺳﺖ رخ دﻫـﺪ اﻳـﻦ اﺳـﺖ ﻛـﻪ در دو ﻓـﻀﺎي ﻧـﺎﻣﻲ ﻛـﻪ ﺑـﺎ اﺳـﺘﻔﺎده از راﻫﻨﻤـﺎي usingﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﺪ دو ﻛﻼس ﻫﻢ ﻧﺎم وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ .ﺑﺮاي ﻣﺜﺎل ﻓـﺮض ﻛﻨﻴـﺪ دو ﻓـﻀﺎي ﻧـﺎم Objectsو MyOwnNameSpaceﻛﻪ ﻫﺮ دو داراي ﻛﻼس Carﻫﺴﺘﻨﺪ را ﺑﺎ اﺳﺘﻔﺎده از راﻫﻨﻤﺎي usingﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ .در اﻳﻦ ﺻﻮرت ﺑﺮاي اﺳﺘﻔﺎده از اﻳﻦ ﻛﻼس در ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﻧﺎم ﻛﺎﻣﻞ آن را ﻣﺸﺨﺺ ﻛﻨﻴﺪ )ﺑﺮاي ﻣﺜﺎل .(Objects.Car ﻳﻜﻲ از اﺑﺰارﻫﺎي ﺧﻮب وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮاي ﻣﺸﺎﻫﺪه ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ اﺿﺎﻓﻪ ﺷـﺪه اﻧـﺪObject Browser ، اﺳﺖ .ﺑﺮاي ﻧﻤﺎﻳﺶ اﻳﻦ اﺑﺰار ﻣﻲ ﺗﻮاﻧﻴﺪ از ﮔﺰﻳﻨﻪ View Object Browserدر ﻧﻮار ﻣﻨﻮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ )ﺷـﻜﻞ -9 (13
– using directive 1ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ ﻛﺎرﺑﺮد اﻳﻦ ﻛﻠﻤﻪ در اﻳﻦ ﺣﺎﻟﺖ ﺑﺎ ﻛﺎرﺑﺮد آن در ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻋﻨﻮان دﺳﺘﻮر usingﻣﺘﻔﺎوت اﺳﺖ .ﻛـﺎرﺑﺮد دﺳﺘﻮر usingدر ﻓﺼﻠﻬﺎي ﺑﻌﺪي ﺗﻮﺿﻴﺢ داده ﺧﻮاﻫﺪ ﺷﺪ.
٣٧٢
ﺷﻜﻞ 13-9 ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﭘﻨﺠﺮه ﻋﻼوه ﺑﺮ ﻛﻼﺳﻬﺎ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﺘﺪﻫﺎ ،ﻓﻴﻠﺪ ﻫﺎ و ﺧﺎﺻﻴﺘﻬﺎي ﻣﻮﺟﻮد در ﻳـﻚ ﻛـﻼس را ﻧﻴـﺰ ﻣـﺸﺎﻫﺪه ﻛﻨﻴـﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،ﻛﻼس Carدر ﻓﻀﺎي ﻧﺎﻣﻲ ﻛﻪ ﺑﺮاﺑﺮ ﺑﺎ ﻧﺎم ﭘﺮوژه اﺳﺖ ﻗﺮار ﮔﺮﻓﺘﻪ اﺳـﺖ )ﻓـﻀﺎي ﻧﺎﻣﻬـﺎ در ﺷﻜﻞ ﺑﺎ ﻋﻼﻣﺖ }{ ﻣﺸﺨﺺ ﺷﺪه اﻧﺪ( و ﻫﻤﭽﻨﻴﻦ اﻳﻦ ﻛﻼس از ﻛﻼس Objectﻣﺸﺘﻖ ﺷﺪه اﺳﺖ .ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻫﻨﮕﺎم ﺗﻌﺮﻳﻒ ﻛﻼس Carﻫﻴﭻ ﻛﻼس ﭘﺎﻳﻪ اي ﺑﺮاي آن ﻣﺸﺨﺺ ﻧﻜﺮدﻳﺪ ،اﻣﺎ اﻳﻦ ﻛﻼس ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ از ﻛﻼس Objectﻣﺸﺘﻖ ﺷﺪه اﺳﺖ.
وراﺛﺖ در ﭼﺎرﭼﻮب :.NET ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ وراﺛﺖ ﻳﻜﻲ از ﻣﺒﺎﺣﺚ ﭘﻴﺸﺮﻓﺘﻪ و ﻣﻬﻢ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا ﺑﻪ ﺷﻤﺎر ﻣﻲ رود .در اﻳﻦ ﻓﺼﻞ ﺑﻪ ﺻﻮرﺗﻲ اﺟﻤـﺎﻟﻲ ﺑﺎ اﻳﻦ ﻣﺒﺤﺚ آﺷﻨﺎ ﺷﺪﻳﻢ ،اﻣﺎ در ﭼﺎرﭼﻮب .NETﺑﻪ ﺷﺪت از وراﺛﺖ اﺳﺘﻔﺎده ﺷﺪه اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻬﺘﺮ اﺳﺖ ﭼﻨﺪ ﻧﻜﺘﻪ اﺳﺎﺳﻲ دﻳﮕـﺮ را ﻧﻴﺰ در اﻳﻦ راﺑﻄﻪ ذﻛﺮ ﻛﻨﻴﻢ. ﻳﻜﻲ از ﻣﻮاردي ﻛﻪ ﺑﺎﻳﺪ در اﻳﻦ راﺑﻄﻪ ﺑﺪاﻧﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ در .NETﻫﻴﭻ ﻛﻼﺳﻲ ﻧﻤﻲ ﺗﻮاﻧـﺪ ﺑـﻪ ﺻـﻮرت ﻣـﺴﺘﻘﻴﻢ از ﺑـﻴﺶ از ﻳـﻚ ﻛﻼس ﻣﺸﺘﻖ ﺷﻮد .ﻫﻤﭽﻨﻴﻦ ذﻛﺮ ﺷﺪ ﻛﻪ اﮔﺮ ﺑﺮاي ﻳﻚ ﻛﻼس ،ﻛﻼس ﭘﺎﻳﻪ ﻣﺸﺨﺺ ﻧﺸﻮد آن ﻛﻼس ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ از ﻛـﻼس Objectﻣﺸﺘﻖ ﻣﻲ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗﻮاﻧﻴﻢ از اﻳﻦ دو ﮔﻔﺘﻪ ﻧﺘﻴﺠﻪ ﺑﮕﻴﺮﻳﻢ ﻛﻪ در .NETﻫﺮ ﻛﻼس ﺑﺎﻳﺪ از دﻗﻴﻘﺎً ﻳـﻚ ﻛـﻼس ﻣﺸﺘﻖ ﺷﻮد. اﻟﺒﺘﻪ اﻳﻨﻜﻪ ﻣﻲ ﮔﻮﻳﻴﻢ ﻫﺮ ﻛﻼس ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺪ از ﻳﻚ ﻛﻼس ﻣﺸﺘﻖ ﺷﻮد ،ﻣﻨﻈﻮر ﻣﺸﺘﻖ ﺷﺪن ﻣﺴﺘﻘﻴﻢ اﺳـﺖ ﻧـﻪ ﻣـﺸﺘﻖ ﺷـﺪن ﻏﻴـﺮ ﻣﺴﺘﻘﻴﻢ .ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻗﺒﻞ ﻛﻼﺳﻲ ﺑﻪ ﻧﺎم Porscheاﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ از ﻛﻼس SportsCarﻣـﺸﺘﻖ ﺷﻮد .اﻳﻦ ﻛﻼس ﺑﻪ ﺻﻮرت ﻣﺴﺘﻘﻴﻢ از ﻓﻘﻂ ﻳﻚ ﻛﻼس ﺑﻪ ﻧﺎم SportsCarو ﺑﻪ ﺻﻮرت ﻏﻴﺮ ﻣﺴﺘﻘﻴﻢ از ﻛﻼس Carﻣـﺸﺘﻖ ﺷﺪه اﺳﺖ.
ﻧﺘﻴﺠﻪ: در اﻳﻦ ﻓﺼﻞ ﺑﺎ ﻣﻔﺎﻫﻴﻢ اﺑﺘﺪاﻳﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا آﺷﻨﺎ ﺷﺪﻳﻢ .ﻓﺼﻞ را ﺑﺎ آﻣﻮﺧﺘﻦ اﻳﻨﻜﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻳﻚ ﻛﻼس ﺑـﺎ ﻣﺘـﺪﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي ﮔﻮﻧﺎﮔﻮن اﻳﺠﺎد ﻛﺮد ﺷﺮوع ﻛﺮدﻳﻢ و ﺳﭙﺲ ﻳﻚ ﻛﻼس ﺑﺮاي ﻣﺪل ﻛﺮدن ﻳـﻚ اﺗﻮﻣﺒﻴـﻞ اﻳﺠـﺎد ﻛـﺮدﻳﻢ .ﺳـﭙﺲ ﻣﺘـﺪﻫﺎ و ﺧﺎﺻﻴﺘﻬﺎي دﻳﮕﺮي ﺑﻪ اﻳﻦ ﻛﻼس اﺿﺎﻓﻪ ﻛﺮدﻳﻢ و آن را در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻛﺎر ﺑﺮدﻳﻢ. ﻗﺒﻞ از اﻳﻨﻜﻪ وارد ﺑﺤﺚ وراﺛﺖ ﺷﻮﻳﻢ ،ﺑﺎ ﺑﺤﺚ ﻣﺘﺪﻫﺎي ﺳﺎزﻧﺪه و ﻧﺤﻮه ﻛﺎرﺑﺮد آﻧﻬﺎ آﺷـﻨﺎ ﺷـﺪﻳﻢ .ﺳـﭙﺲ در ﻣﺒﺤـﺚ وراﺛـﺖ ﺗﻌـﺪادي از ﻣﺒﺎﺣﺚ ﻣﻬﻢ ﻃﺮاﺣﻲ ﺷﻴﺊ ﮔﺮا از ﻗﺒﻴﻞ ﭼﻨﺪ ﺷﻜﻠﻲ ﺑﻮدن و overrideﻛﺮدن را ﻧﻴﺰ ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ. در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ:
اﻳﺠﺎد ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي ﻣﺨﺘﻠﻒ در ﻳﻚ ﻛﻼس. اﻳﺠﺎد ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه ﺑﺮاي ﻛﻼس ﺗﺎ ﺷﺮاﻳﻂ اوﻟﻴﻪ اﺷﻴﺎي ﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﺪه از آن ﻛﻼس را ﺗﻨﻈﻴﻢ ﻛﻨﺪ. اﻳﺠﺎد ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ از ﻛﻼس دﻳﮕﺮي ﻣﺸﺘﻖ ﺷﻮﻧﺪ. Overrideﻛﺮدن ﻣﺘﺪﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي ﻛﻼس ﭘﺎﻳﻪ در ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه. ﻣﻔﻬﻮم و ﭼﮕﻮﻧﮕﻲ اﺳﺘﻔﺎده از ﻓﻀﺎي ﻧﺎم.
٣٧٣
٣٧٤
ﻓﺼﻞ دﻫﻢ :ﻣﺒﺎﺣﺚ ﭘﻴﺸﺮﻓﺘﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا در ﻓﺼﻞ ﻧﻬﻢ ﺑﺎ ﻣﻘﺪﻣﺎت ﭼﮕﻮﻧﮕﻲ اﻳﺠﺎد اﺷﻴﺎ و ﻧﺤﻮه ﻃﺮاﺣﻲ ﻳﻚ ﻛﻼس آﺷﻨﺎ ﺷﺪﻳﺪ .ﻗﺒﻞ از آن ﻓﺼﻞ ،از ﻛﻼﺳﻬﺎي زﻳﺎدي در ﭼﺎرﭼﻮب .NETﺑﺮاي اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﺪ .اﻣﺎ ﺑﺎ اﻃﻼﻋﺎﺗﻲ ﻛﻪ در ﻓﺼﻞ ﻗﺒﻞ ﺑﺪﺳﺖ آوردﻳﻢ ﻧﻤـﻲ ﺗـﻮان ﻛـﻼس ﻫـﺎﻳﻲ ﻛﺎرﺑﺮدي و ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﻃﺮاﺣﻲ ﻛﺮد .در اﻳﻦ ﻓﺼﻞ ﺑﺎ ﻧﺤﻮه اﻳﺠﺎد ﻛﻼس ﻫﺎﻳﻲ ﻛﺎرآﻣﺪ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ. در اﺑﺘﺪاي اﻳﻦ ﻓﺼﻞ ﺑﻌﺪ از ﻣﻌﺮﻓﻲ ﺗﻌﺪادي از ﻣﺒﺎﺣﺚ ﺑﺎﻗﻲ ﻣﺎﻧﺪه ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷـﻴﺊ ﮔـﺮا ﻣﺎﻧﻨـﺪ interfaceﻫـﺎ و ﻧﻴـﺰ ﺳـﺮﺑﺎر ﮔﺬاري ﻣﺘﺪ ﻫﺎ ،ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﺑﻪ ﺻﻮرت ﻋﻤﻠﻲ ﻳﻚ ﻛﻼس ﻛﺎرﺑﺮدي اﻳﺠﺎد ﻛﻨﻴﻢ .ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در اﻳﻦ ﻓﺼﻞ ﺑﺮرﺳـﻲ ﻣـﻲ ﻛﻨـﻴﻢ، ﻫﻤﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺒﻠﻲ ﺑﻪ ﺻﻮرت ﻳﻚ ﻻﻳﻪ ﺧﻮاﻫﺪ ﺑﻮد .اﻳﺪه اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي دو ﻻﻳﻪ در ﻓﺼﻞ ﺳﻴﺰدﻫﻢ ﺑﺮرﺳﻲ ﺧﻮاﻫﺪ ﺷﺪ .در ﻃـﻲ اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي ﻣﺜﺎل در اﻳﻦ ﻓﺼﻞ ،ﺑﺎ ﻧﺤﻮه اﻳﺠﺎد ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪ ﻫﺎﻳﻲ ﻛﻪ در ﺑﻴﻦ ﺗﻤﺎم اﺷﻴﺎي ﻳﻚ ﻛﻼس ﻣﺸﺘﺮك ﺑﺎﺷﻨﺪ ﻧﻴﺰ آﺷـﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. در اﻳﻦ ﻓﺼﻞ:
ﭼﮕﻮﻧﮕﻲ اﻳﺠﺎد ﭼﻨﺪ ﺗﺎﺑﻊ ﺑﺎ ﻧﺎﻣﻬﺎي ﻳﻜﺴﺎن و ﺗﻌﺮﻳﻔﻬﺎي ﻣﺘﻔﺎوت را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد. ﺑﺎ ﭼﮕﻮﻧﮕﻲ اﻳﺠﺎد ﻗﺎﻟﺐ ﺧﺎص ﺑﺮاي ﻛﻼس ﺑﺎ اﺳﺘﻔﺎده از interfaceﻫﺎ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. ﻧﺤﻮه ي اﻳﺠﺎد ﻛﻼس ﻫﺎي ﻛﺎرﺑﺮدي در ﺑﺮﻧﺎﻣﻪ ﻫﺎ را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد. ﻧﺤﻮه اﻳﺠﺎد ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي ﻣﺸﺘﺮك در ﺑﺮﻧﺎﻣﻪ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد.
ﺳﺮﺑﺎر ﮔﺬاري ﻣﺘﺪ ﻫﺎ: ﻳﻜﻲ از ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ در ﻓﺼﻞ ﻫﻔﺘﻢ ﺑﺎ آن آﺷﻨﺎ ﺷﺪﻳﻢ ،ﻛﻼس MessageBoxﺑﻮد ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ آن ﻣﻲ ﺗﻮاﻧﺴﺘﻴﻢ ﻳـﻚ ﻛـﺎدر ﭘﻴﻐﺎم را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﻴﻢ .اﻳﻦ ﻛﻼس ﺷﺎﻣﻞ ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي زﻳﺎدي ﺑﻮد ،اﻣﺎ در ﺑﺮﻧﺎﻣﻪ ﻫـﺎ ﻓﻘـﻂ از ﻳﻜـﻲ از ﻣﺘـﺪﻫﺎي آن اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ :ﻣﺘﺪ .Showﻧﻜﺘﻪ ﺟﺎﻟﺒﻲ ﻛﻪ در اﻳﻦ ﻣﺘﺪ وﺟﻮد داﺷﺖ اﻳﻦ ﺑﻮد ﻛﻪ ﺑﻪ ﻫﺮ ﺻﻮرﺗﻲ ﻛﻪ ﻧﻴﺎز داﺷﺘﻴﻢ ،ﻣﻲ ﺗﻮاﻧﺴﺘﻴﻢ اﻳﻦ ﻣﺘﺪ را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﺴﺘﻴﻢ ﻓﻘﻂ ﻳﻚ ﻣﺘﻦ ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ آن ارﺳﺎل ﻛﻨﻴﻢ و ﺗﺎ آن ﻣﺘﻦ در ﻳـﻚ ﻛـﺎدر ﻧﻤـﺎﻳﺶ داده ﺷﻮد ،ﻳﺎ اﻳﻨﻜﻪ ﻣﻲ ﺗﻮاﻧﺴﺘﻴﻢ ﻋﻼوه ﺑﺮ ﻣﺸﺨﺺ ﻛﺮدن ﻣﺘﻨﻲ ﻛﻪ ﺑﺎﻳﺪ ﻧﻤﺎﻳﺶ داده ﺷﻮد ،ﻋﻨﻮان ﭘﻨﺠﺮه را ﻧﻴﺰ ﻣﺸﺨﺺ ﻛﻨـﻴﻢ و ﻳـﺎ …. اﻣﺎ ﺳﻮال اﻳﻦ اﺳﺖ ﻛﻪ ﻣﻌﻤﻮﻻً ﻫﻨﮕﺎم ﺗﻌﺮﻳﻒ ﻣﺘﺪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﭘﺎراﻣﺘﺮﻫﺎي ﻣﻮرد ﻧﻴﺎز آن ﭼﻴﺴﺖ و ﺑﻪ ﭼﻪ ﺗﺮﺗﻴﺐ ﺑﺎﻳـﺪ ﺑـﻪ ﻣﺘـﺪ ارﺳﺎل ﺷﻮد ،ﭘﺲ ﭼﮕﻮﻧﻪ در ﻣﺘﺪ Showاز ﻛﻼس ،MessageBoxﺗﻌﺪاد ﭘﺎراﻣﺘﺮ ﻫﺎ ﻗﺎﺑﻞ ﺗﻐﻴﻴﺮ ﺑﻮد؟ ﺧﻮب ،در ﻫﺮ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻣﺘﺪ ﻫﺎﻳﻲ اﻳﺠﺎد ﻛﻨﻴﻢ ﻛﻪ ﻧﺎم ﻳﻜﺴﺎﻧﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ ،اﻣﺎ ﭘﺎراﻣﺘﺮﻫﺎي ﻣﺨﺘﻠﻔﻲ را درﻳﺎﻓﺖ ﻛﻨﻨﺪ و ﻛـﺪ ﻫـﺎي ﻣﺘﻔﺎوﺗﻲ ﻫﻢ در آﻧﻬﺎ ﻗﺮار دﻫﻴﻢ .ﺑﻪ اﻳﻦ ﻧﻮع ﺗﻌﺮﻳﻒ ﻣﺘﺪ ،ﺳﺮﺑﺎر ﮔﺬاري ﻣﺘﺪ ﻫﺎ 1ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد .ﺑﺮاي ﻣﺜﺎل ﻣﺘﺪ زﻳﺮ را در ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ. ﻓﺮض ﻣﻲ ﻛﻨﻴﻢ اﻳﻦ ﻣﺘﺪ ﻋﺪد ﺻﺤﻴﺤﻲ را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ و آن را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ: )public void Dispaly(int DisplayValue { // Implementation omitted }
Method Overloading
1
٣٧٥
ﻓﺮض ﻛﻨﻴﺪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻣﺘﺪي داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻣﺎﻧﻨﺪ اﻳﻦ ﻣﺘﺪ ﻋﻤﻞ ﻛﻨﺪ وﻟﻲ ﻳﻚ رﺷﺘﻪ ي ﻣﺘﻨﻲ را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻛﻨﺪ و آن را ﻧﻤﺎﻳﺶ دﻫﺪ .در اﻳﻦ ﺻﻮرت ﺑﺎﻳﺪ ﻣﺘﺪي ﺟﺪﻳﺪ ﺑﺎ ﻧﺎﻣﻲ ﻣﺘﻔﺎوت اﻳﺠﺎد ﻛﻨﻴﺪ .ﺣﺎل اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻣﺘﺪي ﺑﺎ ﻫﻤﻴﻦ ﻋﻤﻠﻜﺮد داﺷﺘﻪ ﺑﺎﺷـﻴﺪ وﻟـﻲ ﻣﺪت زﻣﺎن ﻧﻤﺎﻳﺶ داده ﺷﺪن ﻋﺪد ﻳﺎ ﻣﺘﻦ را ﻧﻴﺰ از ﻛﺎرﺑﺮ درﻳﺎﻓﺖ ﻛﻨﺪ و آن را در زﻣﺎن ﻣﺸﺨﺺ ﺷﺪه ﻧﻤﺎﻳﺶ دﻫﺪ ،در اﻳﻦ ﺻﻮرت ﺑﺎﻳـﺪ ﻣﺘﺪ دﻳﮕﺮي ﺑﺎ ﻧﺎﻣﻲ ﺟﺪﻳﺪ اﻳﺠﺎد ﻛﻨﻴﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ،اﮔﺮ ﺗﻌﺪاد ﺣﺎﻟﺘﻬﺎ زﻳﺎد ﺷﻮد اﻳﻦ روش زﻳﺎد ﺟﺎﻟـﺐ ﻧﺨﻮاﻫـﺪ ﺑـﻮد .ﻫﻤﭽﻨـﻴﻦ ﻣﻤﻜﻦ اﺳﺖ اﺳﺎﻣﻲ ﻣﺘﺪ ﻫﺎ ﻳﺎ ﻃﻮﻻﻧﻲ ﺷﻮد و ﻳﺎ ﺑﻲ ﻣﻌﻨﻲ. 1 راه ﺣﻞ اﻳﻦ ﻣﺸﻜﻞ اﺳﺘﻔﺎده از ﺳﺮﺑﺎر ﮔﺬاري در ﻣﺘﺪ ﻫﺎ اﺳﺖ .ﻣﺘﺪﻫﺎي ﺳﺮﺑﺎر ﮔﺬاري ﺷﺪه ﻣﺘﺪ ﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﻧﺎم ﻳﻜـﺴﺎﻧﻲ دارﻧـﺪ اﻣـﺎ ﻣﻲ ﺗﻮاﻧﻨﺪ ﻧﻮع داده ﺑﺮﮔﺸﺘﻲ از آﻧﻬﺎ و ﻳﺎ ﺗﻌـﺪاد ﭘﺎراﻣﺘﺮﻫـﺎي ورودي آﻧﻬـﺎ ﻣﺨﺘﻠـﻒ ﺑﺎﺷـﺪ )ﺣﺘـﻲ ﺳـﻄﺢ دﺳﺘﺮﺳـﻲ ﺑـﻪ آﻧﻬـﺎ ﻧﻴـﺰ ﻣﺎﻧﻨـﺪ publicو ﻳﺎ privateﺑﻮدن آﻧﻬﺎ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺪ ﺗﻔﺎوت داﺷﺘﻪ ﺑﺎﺷﺪ( .اﻟﺒﺘﻪ دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻣﺘﺪﻫﺎي ﺳـﺮﺑﺎر ﮔـﺬاري ﺷـﺪه ﻧﻤـﻲ ﺗﻮاﻧﻨﺪ ﻓﻘﻂ از ﻧﻈﺮ ﻧﻮع داده ﺑﺮﮔﺸﺘﻲ ﺗﻔﺎوت داﺷﺘﻪ ﺑﺎﺷﻨﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ در ﻳﻚ ﻛﻼس ،دو ﻣﺘﺪ ﺑـﺎ ﻳـﻚ ﻧـﺎم و ﻳـﻚ ﻧـﻮع ﭘﺎراﻣﺘﺮ ورودي داﺷﺘﻪ ﺑﺎﺷﻴﺪ وﻟﻲ ﻧﻮع داده ﺑﺮﮔﺸﺘﻲ آﻧﻬﺎ ﺗﻔﺎوت داﺷﺘﻪ ﺑﺎﺷﺪ ،ﺑﺮاي ﻣﺜﺎل ﻳﻜﻲ از آﻧﻬﺎ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ ﺑﺮﮔﺮداﻧﺪ و دﻳﮕـﺮي ﻳﻚ رﺷﺘﻪ .ﺗﺎﺑﻊ ﻫﺎي ﺳﺮﺑﺎر ﮔﺬاري ﺷﺪه ﺑﺎﻳﺪ ﻧﺎم ﻣﺸﺎﺑﻪ داﺷﺘﻪ ﺑﺎﺷﻨﺪ و ﺗﻌﺪاد و ﻳﺎ ﻧﻮع ﭘﺎراﻣﺘﺮﻫﺎي آﻧﻬﺎ ﻧﻴﺰ ﺣﺘﻤﺎً ﻣﺘﻔﺎوت ﺑﺎﺷـﺪ .ﻧـﻮع داده ﺑﺮﮔﺸﺘﻲ و ﺳﻄﺢ دﺳﺘﺮﺳﻲ آﻧﻬﺎ ﻧﻴﺰ ﻫﻢ ﻣﻲ ﺗﻮاﻧﺪ ﻣﺘﻔﺎوت ﺑﺎﺷﺪ و ﻫﻢ ﻣﺸﺎﺑﻪ ﺑﺎﺷﺪ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ﻧﺤﻮه اﺳﺘﻔﺎده از ﺳﺮﺑﺎر ﮔﺬاري در ﻣﺘﺪ ﻫﺎ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺳﺮﺑﺎر ﮔﺬاري ﺗﻮاﺑﻊ (1ﺑﺎ اﺳﺘﻔﺎده از ﮔﺰﻳﻨﻪ … File New Projectدر ﻧﻮار ﻣﻨﻮ ﻳﻚ ﭘﺮوژه ﺟﺪﻳﺪ اﻳﺠﺎد ﻛﻨﻴـﺪ .در ﻗـﺴﻤﺖ Templatesاز ﭘﻨﺠﺮه New Projectﮔﺰﻳﻨﻪ Console Applicationرا اﻧﺘﺨﺎب ﻛﺮده و ﻧﺎم ﭘﺮوژه را Overloading Demoوارد ﻛﻨﻴﺪ .ﺳﭙﺲ روي دﻛﻤﻪ OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﭘﺮوژه اﻳﺠﺎد ﺷﻮد. (2ﻓﺎﻳﻞ Program.csرا ﺑﺎز ﻛﺮده و ﻣﺘﺪ زﻳﺮ را در آن اﻳﺠﺎد ﻛﻨﻴﺪ: // A method for displaying an integer )static void Display(int I { Console.WriteLine("This is an integer: " + ;))(I.ToString } (3ﺣﺎل ﻣﻲ ﺧﻮاﻫﻴﻢ ﻣﺘﺪي ﺑﺎ ﻫﻤﻴﻦ ﻧﺎم داﺷﺘﻪ ﺑﺎﺷﻴﻢ ،وﻟﻲ ﻳﻚ رﺷﺘﻪ را ﺑﻪ ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﺘـﺪ زﻳـﺮ را ﺑـﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: // this method has the same name as the previous // method, but is distinguishable by signature )static void Display(string str { ;)Console.WriteLine("This is a string: " + str }
1ﺑﻪ وﺳﻴﻠﻪ زﺑﺎن C#ﻣﻲ ﺗﻮاﻧﻴﺪ ﻋﻤﻠﮕﺮ ﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ +و ﻳﺎ – و … را ﻧﻴﺰ ﺳﺮﺑﺎر ﮔﺬاري ﻛﻨﻴﺪ .در اﻳﻦ ﻣﻮرد در اداﻣﻪ ﻓﺼﻞ ﺗﻮﺿﻴﺢ داده ﺷﺪه اﺳﺖ.
٣٧٦
(4ﺣﺎل ﻣﺘﺪ Mainرا ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ ﺗﻮاﺑﻊ اﻳﺠﺎد ﺷﺪه را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ: )static void Main(string[] args { // Displaying an integer ;)Display(20 // Displaying a string ;)"Display("Overloading Demo ;)(Console.ReadLine } (5ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﭘﻨﺠﺮه اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 1-10ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 1-10
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﺑﺘﺪاي ﺑﺮﻧﺎﻣﻪ ﻣﺘﺪي ﺑﺮاي ﻧﻤﺎﻳﺶ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ در ﺧﺮوﺟﻲ اﻳﺠﺎد ﻛﺮدﻳﻢ .اﻳﻦ ﻣﺘﺪ ﻫﻤﺎﻧﻨﺪ ﻣﺘـﺪﻫﺎي ﻋـﺎدي اﺳـﺖ و ﻫـﻴﭻ ﻧﻜﺘـﻪ ﺧﺎﺻﻲ در اﻳﺠﺎد ﻛﺮدن آن ﻧﺒﺎﻳﺪ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﻮد .اﻟﺒﺘﻪ دﻗﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻓﺼﻞ ﻗﺒﻞ ﻫﻢ ﮔﻔﺘﻢ ،اﻳـﻦ ﻣﺘـﺪ ﻫـﺎ ﺑـﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻨﺪ ﺗﻮﺳﻂ ﻣﺘﺪ Mainﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﺑﺎﺷﻨﺪ ﺑﺎﻳﺪ از ﻧﻮع staticﺗﻌﺮﻳﻒ ﺷﻮﻧﺪ. // A method for displaying an integer )static void Display(int I { Console.WriteLine("This is an integer: " + ;))(I.ToString } ﺑﻌﺪ از آن ﺑﺮاي اﻳﺠﺎد ﻣﺘﺪي ﻛﻪ ﺑﺘﻮاﻧﺪ ﻳﻚ رﺷﺘﻪ را ﻧﻤﺎﻳﺶ دﻫﺪ ،از ﻧﺎم ﻣﺘﺪ ﻗﺒﻠﻲ اﺳﺘﻔﺎده ﻛﺮدﻳﻢ .وﻟﻲ اﻳﻦ ﺑﺎر ﭘﺎراﻣﺘﺮﻫـﺎي ورودي آن را ﺑﻪ ﺻﻮرت ﻳﻚ رﺷﺘﻪ ﺗﻌﺮﻳﻒ ﻛﺮدﻳﻢ. // this method has the same name as the previous // method, but is distinguishable by signature )static void Display(string str ٣٧٧
{ ;)Console.WriteLine("This is a string: " + str } ﺑﻪ اﻳﻦ ﺻﻮرت ﻫﻨﮕﺎم ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ Displayاﮔﺮ ﻳﻚ ﻋﺪد ﺑﻪ آن ارﺳﺎل ﻛﻨﻴﻢ ،ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﻣﺘـﺪ اول را ﻓﺮاﺧـﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ و اﮔﺮ ﻫﻢ ﻳﻚ رﺷﺘﻪ ﺑﻪ آن ارﺳﺎل ﻛﻨﻴﻢ ﺑﺮﻧﺎﻣﻪ از ﻣﺘﺪ دوم اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ .اﻳﻦ ﻣﻮرد را در ﻫﻨﮕﺎم اﺳـﺘﻔﺎده از اﻳـﻦ ﻣﺘـﺪ ﻫـﺎ در ﻗﺴﻤﺖ Mainﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ .اﺑﺘﺪا ﻋﺪد ﻓﺮﺳﺘﺎده ﺷﺪه ﺑﻪ ﻣﺘﺪ ﺑﻪ ﻫﻤﺮاه ﻳﻚ ﭘﻴﻐﺎم در ﺻﻔﺤﻪ ﭼﺎپ ﻣﻲ ﺷﻮد ﺗﺎ ﻣـﺸﺨﺺ ﺷـﻮد ﻛـﻪ ﺑﺮﻧﺎﻣﻪ از ﻣﺘﺪ اول اﺳﺘﻔﺎده ﻛﺮده اﺳﺖ .در ﻣﺮﺗﺒﻪ دوم ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ﻫﻢ ،رﺷﺘﻪ ﻓﺮﺳﺘﺎده ﺷﺪه ﺑﻪ ﻫﻤﺮاه ﭘﻴﻐﺎﻣﻲ ﺑﺮاي ﻣـﺸﺨﺺ ﺷـﺪن ﻣﺘـﺪ دوم در ﺻﻔﺤﻪ ﭼﺎپ ﻣﻲ ﺷﻮد. )static void Main(string[] args { // Displaying an integer ;)Display(20 // Displaying a string ;)"Display("Overloading Demo ;)(Console.ReadLine }
اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي :Static ﺑﻌﻀﻲ ﻣﻮاﻗﻊ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ از ﺗﻮاﺑﻊ و ﻣﺘﺪ ﻫﺎﻳﻲ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ﻛﻪ ﻣﺨﺘﺺ ﺑﻪ ﻳﻚ ﺷﻴﺊ از ﻛﻼس ﻧﺒﺎﺷﻨﺪ ،ﺑﻠﻜﻪ ﺑـﻪ ﻛـﻞ ﻛـﻼس اﺧﺘﺼﺎص داﺷﺘﻪ ﺑﺎﺷﻨﺪ .ﺗﺼﻮر ﻛﻨﻴﺪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻛﻼﺳﻲ ﻃﺮاﺣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻧﺎم ﻛﺎرﺑﺮي و ﻛﻠﻤﻪ ﻋﺒﻮر را ﺑﺮاي ﻛﺎرﺑﺮان ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ ذﺧﻴـﺮه ﻛﻨﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻤﻜﻦ اﺳﺖ از ﻛﺪي ﻣﺸﺎﺑﻪ زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ: public class User { // Public members ;public string UserName // Private members ;private string _password } ﺣﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﻛﻠﻤﻪ ﻋﺒﻮر ﻫﺮ ﻛﺎرﺑﺮ ﻧﺒﺎﻳﺪ از ﺗﻌﺪاد ﻛﺎراﻛﺘﺮ ﻫﺎي ﻣﺸﺨﺼﻲ )ﻓﺮﺿﺎً 6ﻛﺎراﻛﺘﺮ( ﻛﻤﺘﺮ ﺑﺎﺷﺪ .ﺑﺮاي اﻳﻦ ﻛـﺎر ﻳـﻚ ﻓﻴﻠـﺪ ﺟﺪﻳﺪ در ﻛﻼس ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﺪ و ﺣﺪاﻗﻞ ﺗﻌﺪاد ﻛﺎراﻛﺘﺮ ﻫﺎي ﻣﺠﺎز ﺑﺮاي ﻛﻠﻤﻪ ﻋﺒﻮر را در آن ذﺧﻴﺮه ﻣﻲ ﻛﻨﻴﺪ: public class User { // Public members ٣٧٨
;public string UserName // Private members ;private string _password ;private string MinPasswordLength = 6 // Password property public string Password { get { ;return _password } set { )if (value.Length >= this.MinPasswordLength ;_password = value } } } ﺧﻮب ،ﺗﺎﻛﻨﻮن ﻫﻤﻪ ﭼﻴﺰ ﻋﺎدي و واﺿﺢ ﺑﻪ ﻧﻈﺮ ﻣﻲ رﺳﺪ .اﻣﺎ ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ 5000ﻛﺎرﺑﺮ داﺷﺘﻪ ﺑﺎﺷﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ 5000ﺷﻴﺊ از اﻳﻦ ﻛﻼس ﺑﺎﻳﺪ در ﺣﺎﻓﻈﻪ اﻳﺠﺎد ﺷﻮد و ﻫﺮ ﻛﺪام از اﻳﻦ ﺷﻴﺊ ﻫﺎ ﻧﻴﺰ ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﻧﺎم MinPasswordLengthدارﻧﺪ ﻛـﻪ 4ﺑﺎﻳﺖ ﻓﻀﺎ را اﺷﻐﺎل ﻣﻲ ﻛﻨﻨﺪ .ﺑﻪ اﻳﻦ ﺻﻮرت ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ 20ﻛﻴﻠﻮ ﺑﺎﻳﺖ از ﺣﺎﻓﻈﻪ ﺑﺮاي ﻧﮕﻬﺪاري ﻳﻚ ﻋﺪد ﻛﻮﭼﻚ اﺳـﺘﻔﺎده ﺷﺪه اﺳﺖ .اﮔﺮﭼﻪ در ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎي اﻣﺮوزي 20ﻛﻴﻠﻮ ﺑﺎﻳﺖ ﻓﻀﺎي زﻳﺎدي ﻣﺤﺴﻮب ﻧﻤﻲ ﺷﻮد ،اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻓﺼﻞ ﺳﻮم ﮔﻔﺘﻢ ﻧﺒﺎﻳـﺪ ﺑﻲ دﻟﻴﻞ ﺣﺎﻓﻈﻪ را ﻫﺪر داد .ﺑﺮاي اﻳﻦ ﻛﺎر روﺷﻬﺎي ﺑﻬﺘﺮي ﻧﻴﺰ وﺟﻮد دارد.
اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ﻫﺎي :Static در ﻣﺜﺎل ﻗﺒﻠﻲ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ ﻣﻘﺪار ﺣﺪاﻗﻞ ﻛﺎراﻛﺘﺮ ﻫﺎي ﻳﻚ ﻛﻠﻤﻪ ﻋﺒﻮر را در ﻳﻚ ﻓﻴﻠﺪ از ﻛﻼس ذﺧﻴﺮه ﻛﻨﻴﺪ ،ﺳﭙﺲ آن ﻓﻴﻠـﺪ را در ﺑﻴﻦ ﺗﻤﺎم اﺷﻴﺎﻳﻲ ﻛﻪ از آن ﻛﻼس ﻧﻤﻮﻧﻪ ﺳﺎزي ﻣﻲ ﺷﻮﻧﺪ ،ﺑﻪ اﺷﺘﺮاك ﺑﮕﺬارﻳﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺎزاي ﻫﺮ ﺗﻌﺪاد ﻛﺎرﺑﺮي ﻛـﻪ در ﺑﺮﻧﺎﻣـﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،ﻓﻘﻂ ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﻧﺎم MinPasswordLengthاﻳﺠﺎد ﺷـﺪه و 4ﺑﺎﻳـﺖ ﻓـﻀﺎ اﺷـﻐﺎل ﻣـﻲ ﺷـﻮد .در ﺑﺨـﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻛﺎر را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ﻫﺎي Static (1وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005را ﺑﺎز ﻛﻨﻴﺪ و ﭘﺮوژه وﻳﻨﺪوزي ﺟﺪﻳﺪي ﺑﺎ وﻳﮋوال C#ﺑﻪ ﻧﺎم Static Demoاﻳﺠﺎد ﻛﻨﻴﺪ. (2ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ Form1ﻧﻤﺎﻳﺶ داده ﺷﺪ ،ﻋﻨﻮان ﻓﺮم را ﺑﻪ Static Demoﺗﻐﻴﻴﺮ دﻫﻴـﺪ .ﺳـﭙﺲ ﺑـﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ،ﻳﻚ ﻛﻨﺘﺮل ،ListBoxﻳﻚ ﻛﻨﺘﺮل Labelو ﻳﻚ ﻛﻨﺘﺮل NumericUpDownرا در ﻓﺮم ﻗﺮار دﻫﻴﺪ .ﺑﻌﺪ از ﺗﻐﻴﻴﺮ اﻧﺪازه اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ،ﻓﺮم ﺷﻤﺎ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 2-10ﺑﺎﺷﺪ.
٣٧٩
2-10 ﺷﻜﻞ . ﺗﻐﻴﻴﺮ دﻫﻴﺪlstUsers را ﺑﻪListBox ﻛﻨﺘﺮلName ( ﺧﺎﺻﻴﺖ3 ﺧﺎﺻــﻴﺖ،nupMinPasswordLength را ﺑــﻪNumericUpDown ﻛﻨﺘــﺮلName ( ﺧﺎﺻــﻴﺖ4 . ﺗﻐﻴﻴﺮ دﻫﻴﺪ6 آن را ﺑﻪValue و ﺧﺎﺻﻴﺖ10 آن را ﺑﻪMaximum ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ و ﻛـﺪUser ﻛﻼس ﺟﺪﻳﺪي ﺑﻪ ﻧﺎم،Solution Explorer ( ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه5 :ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در آن ﻗﺮار دﻫﻴﺪ class User { // Public members public string Username; public static int MinPasswordLength = 6; // Private members private string _password; // Password property public string Password { get { return _password; } set { if (value.Length >= MinPasswordLength) _password = value; } } }
٣٨٠
: ﺑﺮوﻳﺪ و ﻛﺪ زﻳﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪForm1 ( ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ6 public partial class Form1 : Form { // Private member private ArrayList arrUserList = new ArrayList(); ﺑﺎﻳــــﺪ ﻓــــﻀﺎي ﻧــــﺎمArrayList ﻫﻤــــﺎﻧﻄﻮر ﻛــــﻪ ﺑــــﻪ ﺧــــﺎﻃﺮ دارﻳــــﺪ ﺑــــﺮاي اﺳــــﺘﻔﺎده از ﻛــــﻼس . ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد اﺿﺎﻓﻪ ﻛﻨﻴﺪusing را ﺑﺎ اﺳﺘﻔﺎده ازSystem.Collections : اﺿﺎﻓﻪ ﻛﻨﻴﺪForm1 ﻣﺘﺪ زﻳﺮ را ﺑﻪ ﻛﻼس ﻣﺮﺑﻮط ﺑﻪ،( ﺣﺎل7 private void UpdateDisplay() { // Clear the list lstUsers.Items.Clear(); // Add the users to the list box foreach (User objUsers in arrUserList) { lstUsers.Items.Add(objUsers.Username + ", " + objUsers.Password + " (" + User.MinPasswordLength + ")"); } } ﺑﻪ اﻳﻦ ﺗﺮﺗﻴـﺐ ﻣﺘـﺪ ﻣﺮﺑـﻮط ﺑـﻪ روﻳـﺪاد. ﺑﺮﮔﺮدﻳﺪ و ﺑﺮ روي ﻓﺮم دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪForm1 ( ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻣﺮﺑﻮط ﺑﻪ8 : ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ. اﻳﻦ ﻓﺮم ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﻣﻲ ﺷﻮدLoad private void Form1_Load(object sender, EventArgs e) { // Load 100 users for (int i = 0; i < 100; i++) { // Create a new user User objUser = new User(); objUser.Username = "Robbin" + i; objUser.Password = "Password15"; // Add the user to the array list arrUserList.Add(objUser); }
٣٨١
// Update the display ;)(UpdateDisplay } (9ﻣﺠﺪداً ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ Form1ﺑﺮﮔﺮدﻳـﺪ و روي ﻛﻨﺘـﺮل nupMinPasswordLengthدو ﺑـﺎر ﻛﻠﻴـﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ValueChangedاﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﻣﻲ ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: (private void nupMinPasswordLength_ValueChanged )object sender, EventArgs e { // Set the minimum password length = User.MinPasswordLength ;(int)nupMinPasswordLength.Value // Update the display ;)(UpdateDisplay } (10ﺣﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﺑﺎ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﺑﺎ ﻓﺮﻣﻲ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 3-10ﻣﻮاﺟﻪ ﺷﻮﻳﺪ.
ﺷﻜﻞ 3-10 (11ﻋﺪد ﻣﻮﺟﻮد در ﻛﻨﺘﺮل NumericUpDownرا ﻛﻢ و ﻳﺎ زﻳﺎد ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛـﻪ اﻋـﺪاد داﺧـﻞ ﭘﺮاﻧﺘـﺰ در ﻟﻴﺴﺖ ﻧﻴﺰ ﻛﻢ و ﻳﺎ زﻳﺎد ﻣﻲ ﺷﻮﻧﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟
٣٨٢
ﺑﺮاي اﻳﻨﻜﻪ ﻳﻚ ﻓﻴﻠﺪ ،ﺧﺎﺻﻴﺖ و ﻳﺎ ﻳﻚ ﻣﺘﺪ را در ﻛﻼس ﺑﻪ ﻋﻨﻮان ﻋﻀﻮ ﻣﺸﺘﺮك ﺑﻴﻦ ﺗﻤﺎم اﺷﻴﺎ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ،ﺑﺎﻳـﺪ از ﻛﻠﻤـﻪ ﻛﻠﻴـﺪي staticاﺳﺘﻔﺎده ﻛﻨﻴﻢ. ;public static int MinPasswordLength = 6 ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﻪ وﻳﮋوال 2005 C#ﻣﻲ ﮔﻮﻳﻴﻢ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ اﻳﻦ ﻋﻀﻮ ﺑﻴﻦ ﺗﻤﺎم اﺷﻴﺎﻳﻲ ﻛﻪ از اﻳﻦ ﻛﻼس ﻧﻤﻮﻧﻪ ﺳﺎزي ﻣﻲ ﺷﻮﻧﺪ ﺑﻪ اﺷﺘﺮاك ﮔﺬاﺷﺘﻪ ﺷﻮد. اﻋﻀﺎي staticدر ﻳﻚ ﻛﻼس ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ وﺳﻴﻠﻪ ي اﻋﻀﺎي ﻏﻴﺮ staticآن ﻛﻼس ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮﻧﺪ .ﺑﺮاي ﻣﺜﺎل در ﺑﺮﻧﺎﻣــﻪ ي ﺑــﺎﻻ ،ﻋــﻀﻮ MinPasswordLengthﻛــﻪ ﻳــﻚ ﻋــﻀﻮ staticاﺳــﺖ ﺑــﻪ وﺳــﻴﻠﻪ ي ﺧﺎﺻــﻴﺖ Passwordﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﺮﻓﺖ: // Password property public string Password { get { ;return _password } set { )if (value.Length >= MinPasswordLength ;_password = value } } ﻧﻜﺘﻪ ﻣﻬﻤﻲ ﻛﻪ در اﻳﻨﺠﺎ ﻫﻤﻮاره ﺑﺎﻳﺪ ﻣﺪﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺮ ﺧﻼف _passwordو Passwordﻛﻪ ﻓﻘﻂ ﺑـﻪ ﻳﻚ ﺷﻴﺊ از ﻛﻼس Userﺗﻌﻠﻖ دارﻧﺪ )ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﺎزاي ﻫﺮ ﺷﻴﺊ از اﻳﻦ ﻛﻼس ،ﻳﻚ ﻓﻴﻠﺪ _passwordو ﻳﻚ ﺧﺎﺻﻴﺖ Passwordوﺟﻮد دارد( ،اﻣﺎ MinPasswordLengthﺑﻪ ﺗﻤﺎم اﺷﻴﺎﻳﻲ ﻛﻪ از اﻳﻦ ﻛﻼس اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ ﺗﻌﻠـﻖ دارد، ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﺗﻐﻴﻴﺮي در اﻳﻦ ﻓﻴﻠﺪ اﻳﺠﺎد ﺷﻮد ،اﻳﻦ ﺗﻐﻴﻴﺮ ﺑﺮ ﺗﻤﺎم اﺷﻴﺎي ﻣﻮﺟﻮد اﺛﺮ ﺧﻮاﻫﺪ ﮔﺬاﺷﺖ. در ﻓﺮم ﺑﺮﻧﺎﻣﻪ از ﻣﺘﺪ UpdateDisplayﺑﺮاي ﭘﺮ ﻛﺮدن ﻟﻴﺴﺖ اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ .ﻛﺪ ﻫﺎي اﻳﻦ ﻣﺘﺪ ﻫﻢ ﻛﺎﻣﻼً واﺿﺢ ﻫـﺴﺘﻨﺪ. ﻓﻘﻂ دﻗﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻋﻀﺎي Staticﻳﻚ ﻛﻼس ﻧﻤﻲ ﺗﻮاﻧﻴﺪ از اﺷﻴﺎي ﻧﻤﻮﻧﻪ ﺳـﺎزي ﺷـﺪه از آن ﻛـﻼس اﺳـــﺘﻔﺎده ﻛﻨﻴـــﺪ .ﺑـــﺮاي ﻣﺜـــﺎل در ﻣﺘـــﺪ ،UpdateDisplayﺷـــﻴﺊ objUserﺣـــﺎوي ﻓﻴﻠـــﺪي ﺑـــﻪ ﻧـــﺎم MinPasswordLengthﻧﺨﻮاﻫﺪ ﺑﻮد .ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻳﻦ اﻋﻀﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﺑﺎﻳﺪ از ﻧﺎم ﺧﻮد ﻛـﻼس اﺳﺘﻔﺎده ﻛﺮد. )(private void UpdateDisplay { // Clear the list ;)(lstUsers.Items.Clear // Add the users to the list box )foreach (User objUsers in arrUserList
٣٨٣
{ lstUsers.Items.Add(objUsers.Username + ", " + objUsers.Password + " (" + ;)")" User.MinPasswordLength + } } در ﺷﻜﻞ 4-10ﻧﻴﺰ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻫﻨﮕـﺎم ﻧﻮﺷـﺘﻦ ﻛـﺪ ،زﻣـﺎﻧﻲ ﻛـﻪ ﻧـﺎم ﻛـﻼس را وارد ﻣـﻲ ﻛﻨﻴـﺪ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ اﻋـﻀﺎي staticﻛﻼس را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
ﺷﻜﻞ 4-10 اﻳﻦ ﻣﻮارد ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ ﻋﺪد ﻣﻮﺟﻮد در ﻛﻨﺘﺮل NumericUpDownرا ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﺪ ﺟﺎﻟﺐ ﺗﺮ ﻣـﻲ ﺷـﻮد .در اﻳـﻦ ﻫﻨﮕـﺎم ﺧﺎﺻﻴﺖ MinPasswordLengthﺗﻐﻴﻴﺮ ﻣﻲ ﻛﻨﺪ ،اﻣﺎ ﭼﻮن اﻳﻦ ﻓﻴﻠﺪ ﺑﻪ ﺷﻴﺊ ﺧﺎﺻﻲ ﺗﻌﻠﻖ ﻧﺪارد ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ اﻳﻦ ﻓﻴﻠـﺪ را ﺑﺮاي ﺗﻚ ﺗﻚ اﺷﻴﺎ ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺑﻠﻜﻪ ﻛﺎﻓﻲ اﺳﺖ ﺑﺎ اﺳﺘﻔﺎده از ﻧﺎم ﻛﻼس ،ﻓﻘﻂ ﻳﻚ ﺑﺎر ﻣﻘﺪار اﻳﻦ ﻓﻴﻠﺪ را ﻋﻮض ﻛﻨﻴﺪ ﺗـﺎ ﻛـﻞ اﺷـﻴﺎي ﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﺪه از ﻛﻼس ﺗﻐﻴﻴﺮ ﻛﻨﻨﺪ: (private void nupMinPasswordLength_ValueChanged )object sender, EventArgs e { // Set the minimum password length = User.MinPasswordLength ;(int)nupMinPasswordLength.Value // Update the display ;)(UpdateDisplay } اﻟﺒﺘﻪ ﻣﻘﺪار ﺧﺎﺻـﻴﺖ Valueاز ﻛﻨﺘـﺮل NumericUpDownاز ﻧـﻮع Decimalاﺳـﺖ و ﺑـﺮاي اﻳﻨﻜـﻪ آن را در ﻓﻴﻠـﺪ MinPasswordLengthﻗﺮار دﻫﻴﻢ ﺑﺎﻳﺪ آن را ﺑﻪ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ ﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻓﺼﻞ ﻫﺎي ﻗﺒﻠﻲ ﮔﻔﺘﻢ ﺑﺎﻳﺪ از ﻋﻤﻠﮕﺮ )( ﺑﻪ ﺻﻮرت زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﻢ: // Set the minimum password length = User.MinPasswordLength ;(int)nupMinPasswordLength.Value
٣٨٤
اﺳﺘﻔﺎده از ﻣﺘﺪﻫﺎي :Static در ﺑﺨﺶ ﻗﺒﻠﻲ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻳﻚ ﻓﻴﻠﺪ publicرا ﺑﻪ ﺻﻮرت اﺷﺘﺮاﻛﻲ ﻣﻌﺮﻓـﻲ ﻛـﺮد .در اﻳـﻦ ﻗـﺴﻤﺖ ﻫـﻢ ﺑـﻪ ﭼﮕﻮﻧﮕﻲ اﻳﺠﺎد ﻳﻚ ﻣﺘﺪ ﻛﻪ ﺑﻴﻦ ﺗﻤﺎم اﺷﻴﺎ ﻣﺸﺘﺮك ﺑﺎﺷﺪ ﺧﻮاﻫﻴﻢ ﭘﺮداﺧﺖ .در ﺑﺨﺶ اﻣﺘﺤـﺎن ﻛﻨﻴـﺪ ﺑﻌـﺪ ،ﻣﺘـﺪي از ﻧـﻮع static اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﺑﺘﻮاﻧﺪ ﻳﻚ ﻧﻤﻮﻧﻪ از ﻛﻼس Userرا اﻳﺠﺎد ﻛﻨﺪ .ﺗﻨﻬﺎ ﻣﺤﺪودﻳﺘﻲ ﻛﻪ اﻳﻦ ﻣﺘﺪ ﻫﺎ ﻧﺴﺒﺖ ﺑﻪ ﻣﺘﺪﻫﺎي ﻫﻤﺎﻧﻨﺪ ﺧﻮد دارﻧﺪ در اﻳﻦ اﺳﺖ ﻛﻪ اﻳﻦ ﻣﺘﺪ ﻫﺎ ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي staticﻛﻼس دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ. ﻧﻜﺘﻪ :ﻣﺜﺎل زﻳﺮ ﻓﻘﻂ ﻳﻚ ﻣﺜﺎل ﺗﺼﻨﻌﻲ ﺑﺮاي ﻣﻌﺮﻓﻲ ﻣﺘﺪﻫﺎي staticاﺳﺖ ،زﻳﺮا اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﺪ ﺑﺪون اﺳﺘﻔﺎده از اﻳﻦ ﻧﻮع ﻣﺘـﺪ ﻫﺎ ﻧﻴﺰ ﺑﻪ ﺳﺎدﮔﻲ اﻧﺠﺎم ﺷﻮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﻣﺘﺪﻫﺎي static (1ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ را ﺑﺮاي ﻛﻼس Userﺑﺎز ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ public static User CreateUser(string UserName, )string Password { // Declare a new User object ;)(User objUser = new User // Set the user properties ;objUser.Username = UserName ;objUser.Password = Password // Return the new user ;return objUser } (2ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ را ﺑﺮاي Form1ﺑﺎز ﻛﻨﻴﺪ و ﺑﻪ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Loadﻓﺮم ﺑﺮوﻳﺪ .ﻛﺪ ﻣﻮﺟﻮد در اﻳﻦ ﻣﺘـﺪ را ﺑﻪ ﺻﻮرﺗﻲ ﻛﻪ در زﻳﺮ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﺗﻐﻴﻴﺮ دﻫﻴﺪ .دﻗﺖ ﻛﻨﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻧـﺎم ﻛـﻼس Userرا وارد ﻛﻨﻴـﺪ ،وﻳـﮋوال اﺳﺘﻮدﻳﻮ ﻣﺘﺪ CreateUserرا ﻧﻴﺰ ﺑﻪ ﻋﻨﻮان ﻳﻜﻲ از ﮔﺰﻳﻨﻪ ﻫﺎي ﻗﺎﺑﻞ اﻧﺘﺨﺎب ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. )private void Form1_Load(object sender, EventArgs e { // Load 100 users )for (int i = 0; i < 100; i++ { // Create a new user = User objUser ;)"User.CreateUser("Robbin" + i,"Password15
٣٨٥
// Add the user to the array list ;)arrUserList.Add(objUser } // Update the display ;)(UpdateDisplay } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ در ﺧﺮوﺟﻲ ﺑﺮﻧﺎﻣﻪ ﻫﻴﭻ ﺗﻐﻴﻴﺮي اﻳﺠﺎد ﻧﺸﺪه اﺳﺖ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻧﻜﺘﻪ ﻣﻬﻤﻲ ﻛﻪ در اﻳﻦ ﻣﺜﺎل وﺟﻮد دارد اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺎ وارد ﻛﺮدن ﻧﺎم ﻛﻼس ،Userﻧﺎم ﻣﺘﺪ CreateUserﻧﻴﺰ ﺑـﻪ ﻋﻨـﻮان ﻳﻜﻲ از ﮔﺰﻳﻨﻪ ﻫﺎي ﻗﺎﺑﻞ اﻧﺘﺨﺎب ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .دﻟﻴﻞ اﻳﻦ ﻣﻮرد اﻳﻦ اﺳﺖ ﻛﻪ اﻳﻦ ﻣﺘﺪ ﺑﻪ ﻋﻨﻮان ﻳﻚ ﻣﺘـﺪ staticﺗﻌﺮﻳـﻒ ﺷﺪه اﺳﺖ و ﺑﻴﻦ ﺗﻤﺎم اﺷﻴﺎﻳﻲ ﻛﻪ از اﻳﻦ ﻛﻼس ﻧﻤﻮﻧﻪ ﺳﺎزي ﻣﻲ ﺷﻮﻧﺪ ﻣﺸﺘﺮك اﺳﺖ .ﭘﺲ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ آن ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻧﺎم ﺧـﻮد ﻛﻼس اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي ﺗﻌﺮﻳﻒ ﻳﻚ ﻣﺘﺪ ،staticﻣﻲ ﺗﻮاﻧﻴﺪ در ﻫﻨﮕﺎم ﺗﻌﺮﻳﻒ ﻛﻼس از ﻛﻠﻤـﻪ ﻛﻠﻴـﺪي staticاﺳـﺘﻔﺎده ﻛﻨﻴﺪ. public static User CreateUser(string UserName, )string Password ﻳﻜﻲ از ﻧﻜﺎﺗﻲ ﻛﻪ ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﻣﺘﺪﻫﺎي staticﺑﺎﻳﺪ در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ اﻳﻦ ﻣﺘﺪ ﻫﺎ ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﻨـﺪ ﺑـﻪ اﻋـﻀﺎي staticﻛﻼس دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ .دﻟﻴﻞ اﻳﻦ اﻣﺮ ﻫﻢ ﺳﺎده اﺳﺖ ،زﻳﺮا اﻳﻦ ﻣﺘﺪ ﺑﻪ ﺷﻴﺊ ﺧﺎﺻﻲ واﺑﺴﺘﻪ ﻧﻴﺴﺖ .ﺑﻨـﺎﺑﺮاﻳﻦ اﮔـﺮ در اﻳﻦ ﻣﺘﺪ از اﻋﻀﺎي ﻣﻌﻤﻮﻟﻲ ﻛﻼس ،ﻛﻪ ﺑﺎزاي ﻫﺮ ﺷﻴﺊ ﻳﻚ ﻧﻤﻮﻧﻪ از آﻧﻬﺎ وﺟﻮد دارد اﺳﺘﻔﺎده ﺷﻮد ،ﻫﻨﮕﺎم ﻓﺮاﺧﻮاﻧﻲ اﻳﻦ ﻣﺘﺪ ﻧﻤـﻲ ﺗـﻮان ﺗﺸﺨﻴﺺ داد ﻛﻪ اﻋﻀﺎي ﻣﺮﺑﻮط ﺑﻪ ﻛﺪام ﺷﻴﺊ از ﻛﻼس ﻣﺪ ﻧﻈﺮ اﺳﺖ.
ﺳﺮﺑﺎر ﮔﺬاري ﻋﻤﻠﮕﺮ ﻫﺎ: در ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺗﺎﻛﻨﻮن ﻧﻮﺷﺘﻪ اﻳﻢ از ﻋﻤﻠﮕﺮ ﻫﺎي اﺳﺘﺎﻧﺪارد ﻣﺎﻧﻨﺪ +و ﻳﺎ – ﺑﺮاي ﻛﺎر ﺑﺮ روي ﻧﻮع ﻫﺎي داده اي ﺧﺎﺻﻲ ﻣﺎﻧﻨﺪ اﻋـﺪاد ﺻﺤﻴﺢ ،اﻋﺪاد اﻋﺸﺎري و ﻳﺎ رﺷﺘﻪ ﻫﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ .اﻳﻦ ﻋﻤﻠﮕﺮ ﻫﺎ ﺑﻪ ﺻﻮرت دروﻧﻲ ﺑﺮاي ﻛﺎر ﺑـﺎ اﻳـﻦ ﻧـﻮع ﻫـﺎي داده اي ﺑﺮﻧﺎﻣـﻪ رﻳﺰي ﺷﺪه اﻧﺪ .ﺑﻌﻀﻲ از زﻳﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺎﻧﻨﺪ C#ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ اﺟﺎزه ﻣﻲ دﻫﻨﺪ ﻛﻪ ﻋﻤﻠﻜﺮد اﻳﻦ ﻋﻤﻠﮕﺮ ﻫـﺎ را ﺑـﻪ ﮔﻮﻧـﻪ اي ﺗﻐﻴﻴﺮ دﻫﻨﺪ ﺗﺎ ﺑﺎ ﺳﺎﺧﺘﺎرﻫﺎ و ﻳﺎ ﻛﻼﺳﻬﺎي ﻧﻮﺷﺘﻪ ﺷﺪه ﺗﻮﺳﻂ آﻧﻬﺎ ﻧﻴﺰ ﻛﺎر ﻛﻨﻨﺪ. ﺑﺮاي ﻣﺜﺎل ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﻢ ﺳﺎﺧﺘﺎري را اﻳﺠﺎد ﻛﻨﻴﻢ ﻛﻪ ﺑﺘﻮاﻧﺪ اﻋﺪاد ﻣﺨﺘﻠﻂ را در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣـﻲ داﻧﻴـﺪ ﻫـﺮ ﻋﺪد ﻣﺨﺘﻠﻂ از ﻳﻚ ﻗﺴﻤﺖ ﺣﻘﻴﻘﻲ و ﻳﻚ ﻗﺴﻤﺖ ﻣﻮﻫﻮﻣﻲ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ .ﻓﺮض ﻛﻨﻴﺪ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ،ﻛﻼﺳﻲ را ﺑﺮاي ﻧﮕﻬـﺪاري از اﻋﺪاد ﻣﺨﺘﻠﻂ ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻌﺮﻳﻒ ﻛﺮده اﻳﺪ: public class ComplexNumber {
٣٨٦
;public double real ;public double imaginary } ﺑﺮاي ﺟﻤﻊ دو ﺷﻴﺊ از اﻳﻦ ﻛﻼس ،ﺑﺎﻳﺪ ﻗﺴﻤﺘﻬﺎي ﺣﻘﻴﻘﻲ ﻫﺮ ﻛﺪام را ﺑﺎ ﻫﻢ و ﻗﺴﻤﺘﻬﺎي ﻣﻮﻫﻮﻣﻲ را ﻧﻴﺰ ﺑﺎ ﻫﻢ ﺟﻤﻊ ﻛﻨﻴﻢ .اﻣﺎ ﻋﻤﻠﮕﺮ + ﺑﻪ ﺻﻮرت ﻋﺎدي ﻧﻤﻲ ﺗﻮاﻧﺪ اﺷﻴﺎﻳﻲ ﻛﻪ از اﻳﻦ ﻛﻼس ﻧﻤﻮﻧﻪ ﺳﺎزي ﻣﻲ ﺷﻮﻧﺪ را ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﺟﻤﻊ ﻛﻨﺪ .در C#اﻳﻦ ﻗﺎﺑﻠﻴﺖ وﺟـﻮد دارد ﺗـﺎ ﺑﺮاي ﻋﻤﻠﮕﺮ +ﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﺑﺎﻳﺪ دو ﺷﻴﺊ از اﻳﻦ ﻧﻮع را ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﺟﻤﻊ ﻛﻨﺪ .ﺑﻌﺪ از اﻳﻦ ﻛﺎر ،اﻳﻦ ﻋﻤﻠﮕـﺮ ﻗـﺎدر ﺧﻮاﻫـﺪ ﺑـﻮد ﻫﻤﺎﻧﻄﻮر ﻛﻪ دو ﻋﺪد ﻋﺎدي را ﺑﺎ ﻫﻢ ﺟﻤﻊ ﻣﻲ ﻛﻨﺪ ،دو ﺷﻴﺊ از ﻛﻼس ComplexNumberرا ﻧﻴﺰ ﺑﺎ ﻫﻢ ﺟﻤﻊ ﻛﻨﺪ .ﺑﻪ اﻳﻦ ﻛـﺎر ﺳﺮﺑﺎر ﮔﺬاري ﻋﻤﻠﮕﺮ 1ﻣﻲ ﮔﻮﻳﻨﺪ. ﻧﻜﺘﻪ :ﺑﺴﻴﺎري از زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺎﻧﻨﺪ Javaو ﻳﺎ Visual Basicاﺟﺎزه ﻧﻤﻲ دﻫﻨﺪ ﻛﻪ ﻋﻤﻠﮕﺮ ﻫﺎ را ﺳﺮﺑﺎر ﮔﺬاري ﻛﻨﻴﺪ .در اﻳﻦ زﺑﺎﻧﻬﺎ ﻣﻌﻤﻮﻻً از ﻳﻚ ﻣﺘﺪ ﺑﺎ ﻧﺎﻣﻲ ﻣﺸﺎﺑﻪ ﻋﻤﻠﮕﺮ )ﻫﻤﺎﻧﻨﺪ ﻣﺘﺪ (Addﺑﺮاي اﻧﺠﺎم دادن آن ﻋﻤـﻞ در ﻛـﻼس اﺳـﺘﻔﺎده ﻣـﻲ ﻛﻨﻨﺪ. ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﺑﺎ ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻛﺎر در C#آﺷﻨﺎ ﺷﻮﻳﻢ ،ﺑﺎﻳﺪ ﻋﻤﻠﮕﺮ ﻫﺎ را ﺑﻬﺘﺮ ﺑﺸﻨﺎﺳﻴﻢ .ﭘﺲ اﺑﺘﺪا ﻧﻜـﺎت دﻳﮕـﺮي ﻛـﻪ ﻻزم اﺳﺖ در ﻣﻮرد ﻫﺮ ﻋﻤﻠﮕﺮ ﺑﺪاﻧﻴﺪ را ﺑﺮرﺳﻲ ﻛﺮده و ﺳﭙﺲ ﺑﻪ ﺳﺮاغ ﻧﺤﻮه ي ﺳﺮﺑﺎر ﮔﺬاري آﻧﻬﺎ ﻣﻲ روﻳﻢ.
درك ﻋﻤﻠﮕﺮ ﻫﺎ: ﻫﺮ ﻋﻤﻠﮕﺮ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ داراي اوﻟﻮﻳﺖ ﺧﺎﺻﻲ اﺳﺖ .ﺑﺮاي ﻣﺜﺎل اوﻟﻮﻳﺖ ﻋﻤﻠﮕﺮ * ﺑﻴﺸﺘﺮ از ﻋﻤﻠﮕﺮ +اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑـﺮاي ارزﻳـﺎﺑﻲ ﻣﻘﺪار ﻋﺒﺎرت ،A + B * Cاﺑﺘﺪا ﻣﻘﺪار Bدر ﻣﻘﺪار Cﺿﺮب ﺷﺪه و ﺣﺎﺻﻞ آن ﺑﺎ ﻣﻘﺪار Aﺟﻤﻊ ﻣﻲ ﺷﻮد. ﻫﻤﭽﻨﻴﻦ ﻫﺮ ﻋﻤﻠﮕﺮ داراي ﺷﺮﻛﺖ ﭘﺬﻳﺮي ﺧﺎﺻﻲ اﺳﺖ ﻛﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آن ﻋﻤﻠﮕﺮ از ﺳﻤﺖ ﭼﭗ ﺑﻪ راﺳﺖ ارزﻳﺎﺑﻲ ﻣﻲ ﺷﻮد و ﻳﺎ از ﺳﻤﺖ راﺳﺖ ﺑﻪ ﭼﭗ .ﺑﺮاي ﻣﺜﺎل ﻋﻤﻠﮕﺮ = داراي ﺷﺮﻛﺖ ﭘﺬﻳﺮي ﭼﭗ اﺳﺖ .ﺑﻪ ﺑﻴﺎن دﻳﮕﺮ ﺑﺮاي ارزﻳﺎﺑﻲ ﻣﻘﺪار ﻋﺒﺎرت = A = B Cﻣﻘﺪار Cدر Bو ﺳﭙﺲ در Aﻗﺮار ﻣﻲ ﮔﻴﺮد. ﻋﻤﻠﮕﺮ ﻳﮕﺎﻧﻲ ﻋﻤﻠﮕﺮي اﺳﺖ ﻛﻪ ﻓﻘﻂ ﺑﺮ روي ﻳﻚ ﻋﻤﻠﻮﻧﺪ ،ﻛﺎر ﻣﻲ ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻋﻤﻠﮕﺮ ++ﻛﻪ ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ واﺣـﺪ ﺑـﻪ ﻣﺘﻐﻴﺮ ﺑﻪ ﻛﺎر ﻣﻲ رود ،ﻓﻘﻂ ﺑﻪ ﻳﻚ ﻋﻤﻠﻮﻧﺪ ﻧﻴﺎز دارد. ﻋﻤﻠﮕﺮ دوﺗﺎﻳﻲ ﻧﻴﺰ ﻋﻤﻠﮕﺮي اﺳﺖ ﻛﻪ ﺑﺮ روي دو ﻋﻤﻠﻮﻧﺪ ﻛﺎر ﻣﻲ ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻋﻤﻠﮕﺮ +ﺑﺮاي ﻛﺎر ﺧﻮد ﺑﻪ دو ﻋﻤﻠﻮﻧﺪ ﻧﻴﺎز دارد. ﻫﻨﮕﺎم ﺳﺮﺑﺎر ﮔﺬاري ﻋﻤﻠﮕﺮ ﻫﺎ ﺑﺎﻳﺪ ﻫﻤﻮاره ﻧﻜﺎت زﻳﺮ را در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ:
ﻫﻨﮕﺎم ﺳﺮﺑﺎر ﮔﺬاري ﻋﻤﻠﮕﺮ ﻫﺎ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ اوﻟﻮﻳﺖ و ﻳﺎ ﺗﺮﺗﻴﺐ ﺷﺮﻛﺖ ﭘﺬﻳﺮي آﻧﻬﺎ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ .زﻳﺮا اﻳﻦ ﻣـﻮارد ﺑـﻪ ﻣﻔﻬـﻮم ﻋﻤﻠﮕﺮ ﺑﺴﺘﮕﻲ دارﻧﺪ و ﺑﺮ اﺳﺎس ﻧﻮع داده اي ﻛﻪ ﺑﺎ آﻧﻬﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد ﻧﺒﺎﻳﺪ ﺗﻐﻴﻴﺮ ﻛﻨﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻋﺒﺎرت A + B * Cﺻﺮف ﻧﻈﺮ از ﻧﻮع داده اي ﻣﺘﻐﻴﻴﺮ ﻫﺎي B ، Aو Cﻫﻤﻮاره ﺑﻪ ﺻﻮرت ) A + (B * Cارزﻳﺎﺑﻲ ﻣﻲ ﺷﻮد.
Operator Overloading
1
٣٨٧
ﻫﻨﮕﺎم ﺳﺮﺑﺎر ﮔﺬاري ﻋﻤﻠﮕﺮ ﻫﺎ ﻣﺠﺎز ﻧﻴﺴﺘﻴﺪ ﻛﻪ ﺗﻌﺪاد ﻋﻤﻠﻮﻧﺪ ﻫﺎي ﻣﻮرد ﻧﻴﺎز آن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻋﻤﻠﮕﺮ * ﻫﻤﻮاره دو ﻋﻤﻠﻮﻧﺪ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ و ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﻋﻤﻠﻜﺮد آن را ﺑﺮاي ﻳﻚ ﻛﻼس ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ ﺑـﻪ ﺳـﻪ ﻋﻤﻠﻮﻧـﺪ ﻧﻴـﺎز داﺷﺘﻪ ﺑﺎﺷﺪ. ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﺠﺎز ﻧﻴﺴﺘﻴﺪ ﻛﻪ ﻋﻤﻠﮕﺮ ﻫﺎي ﺟﺪﻳﺪي را اﻳﺠﺎد ﻛﺮده و ﻣﻔﻬﻮﻣﻲ را ﺑﻪ آن اﺧﺘـﺼﺎص دﻫﻴـﺪ .ﺑـﺮاي ﻣﺜﺎل ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﻋﻤﻠﮕﺮي را ﺑﻪ ﺻﻮرت ** ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ.
ﭼﮕﻮﻧﮕﻲ ﺳﺮﺑﺎر ﮔﺬاري ﻋﻤﻠﮕﺮ ﻫﺎ: در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ،ﻛﻼﺳﻲ را ﺑﺮاي ﻧﮕﻬﺪاري اﻋﺪاد ﻣﺨﺘﻠﻂ اﻳﺠﺎد ﻛﺮده و ﻋﻤﻠﮕﺮ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﺟﻤـﻊ و ﺗﻔﺮﻳـﻖ را ﺑـﻪ ﻧﺤـﻮي ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻴﻢ ﻛﻪ ﺑﺘﻮاﻧﻨﺪ ﺑﺎ اﺷﻴﺎي ﺳﺎﺧﺘﻪ ﺷﺪه از اﻳﻦ ﻛﻼس ﻧﻴﺰ ﻛﺎر ﻛﻨﻨﺪ .ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ اي اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ دو ﻋـﺪد ﻣﺨـﺘﻠﻂ را از ﻛﺎرﺑﺮ درﻳﺎﻓﺖ ﻛﻨﺪ و ﺣﺎﺻﻞ ﺟﻤﻊ و ﺗﻔﺮﻳﻖ آﻧﻬﺎ را ﻧﻤﺎﻳﺶ دﻫﺪ. ﻧﻜﺘﻪ :ﻳﻚ ﻋﺪد ﻣﺨﺘﻠﻂ را ﺑﻪ ﺻﻮرت ) (R+Iiﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻨﺪ ﻛﻪ Rﻗﺴﻤﺖ ﺣﻘﻴﻘﻲ آن و Iﻗﺴﻤﺖ ﻣﻮﻫﻮﻣﻲ آن اﺳـﺖ ،ﻣﺎﻧﻨـﺪ ) . (2+3.4iاﮔﺮ ﻗﺴﻤﺖ ﺣﻘﻴﻘﻲ ﻋﺪد ﻣﺨﺘﻠﻂ اول را ﺑﺎ R1و ﻗﺴﻤﺖ ﻣﻮﻫﻮﻣﻲ آن را ﺑﺎ I1ﻧﻤﺎﻳﺶ دﻫﻴﻢ ،ﻫﻤﭽﻨﻴﻦ ﺑﺮاي ﻧﻤـﺎﻳﺶ ﻗﺴﻤﺘﻬﺎي ﺣﻘﻴﻘﻲ و ﻣﻮﻫﻮﻣﻲ ﻋﺪد دوم ﻧﻴﺰ از R2و I2اﺳﺘﻔﺎده ﻛﻨﻴﻢ ،ﻓﺮﻣﻮل ﺟﻤﻊ و ﺗﻔﺮﻳﻖ اﻳﻦ اﻋﺪاد ﺑﻪ ﺻﻮرت زﻳﺮ ﺧﻮاﻫﺪ ﺑﻮد: : (R1+R2) + (I1+I2)iﺟﻤﻊ : (R1-R2) + (I1-I2)iﺗﻔﺮﻳﻖ
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺳﺮﺑﺎر ﮔﺬاري ﻋﻤﻠﮕﺮ ﻫﺎ (1 (2 (3
(4 (5
ﺑﺎ اﺳﺘﻔﺎده از ﮔﺰﻳﻨﻪ ي … File New Projectدر وﻳﮋوال اﺳﺘﻮدﻳﻮ ،ﺑﺮﻧﺎﻣﻪ ي وﻳﻨـﺪوزي ﺟﺪﻳـﺪي ﺑﻪ ﻧﺎم Operator Overloading Demoاﻳﺠﺎد ﻛﻨﻴﺪ. Operator ﺑﻌــﺪ از اﻳﻨﻜــﻪ ﻓــﺮم ﺑﺮﻧﺎﻣــﻪ ﻧﻤــﺎﻳﺶ داده ﺷــﺪ ،ﺧﺎﺻــﻴﺖ Textﻣﺮﺑــﻮط ﺑــﻪ آن را ﺑﺮاﺑــﺮ ﺑــﺎ Overloading Demoﻗﺮار دﻫﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ،ﭼﻬﺎر ﻛﻨﺘﺮل TextBoxﺑﺮ روي ﻓﺮم ﻗﺮار داده و ﻧﺎم آﻧﻬـﺎ را ﺑـﻪ ﺗﺮﺗﻴـﺐ ﺑـﻪ ،txtReal1 txtReal2 ،txtImg1و txtImg2ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﻫﻤﭽﻨﻴﻦ ﺑﺎ اﺳﺘﻔﺎده از ﭼﻨﺪ ﻛﻨﺘﺮل Labelﻣـﺸﺨﺺ ﻛﻨﻴﺪ ﻛﻪ ﻫﺮ ﻛﻨﺘﺮل TextBoxﻣﺮﺑﻮط ﺑﻪ ﻧﮕﻬﺪاري ﭼﻪ ﻣﻘﺪاري اﺳﺖ. ﻳﻚ ﻛﻨﺘﺮل Buttonروي ﻓﺮم ﻗﺮار داده ،ﺧﺎﺻﻴﺖ Nameآن را ﺑـﻪ btnCalculateو ﺧﺎﺻـﻴﺖ Text آن را ﺑﻪ Calculateﺗﻐﻴﻴﺮ دﻫﻴﺪ. دو ﻛﻨﺘﺮل Labelﺑﻪ ﻧﺎﻣﻬﺎي lblSumو lblMinusدر ﻓﺮم ﻗﺮار دﻫﻴﺪ ﺗﺎ ﻧﺘﻴﺠﻪ ﻣﺤﺎﺳﺒﺎت را ﺑﻪ وﺳـﻴﻠﻪ آﻧﻬـﺎ ﺑﻪ ﻛﺎرﺑﺮ اﻃﻼع دﻫﻴﻢ .ﺧﺎﺻﻴﺖ Textاﻳﻦ دو ﻛﻨﺘﺮل را ﺑﻪ ﺗﺮﺗﻴـﺐ ﺑﺮاﺑـﺮ ﺑـﺎ Sum is:و Minus is:ﻗـﺮار دﻫﻴﺪ .ﺑﻌﺪ از ﺗﻨﻈﻴﻢ اﻧﺪازه ﻛﻨﺘﺮل ﻫﺎ ﻓﺮم ﺷﻤﺎ ﺑﺎﺷﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 5-10ﺑﺎﺷﺪ.
٣٨٨
5-10 ﺷﻜﻞ ﺑـﻪ ﺑﺮﻧﺎﻣـﻪComplexNumber ﻛﻼس ﺟﺪﻳﺪي ﺑﻪ ﻧـﺎمSolution Explorer ( ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه6 . ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﺑﺪﻧﻪ ي آن ﻛﻼس وارد ﻛﻨﻴﺪ،اﺿﺎﻓﻪ ﻛﺮده class ComplexNumber { public double Real = 0; public double Imaginary = 0; // Override ToString() to display a complex number // in the traditional format public override string ToString() { return (Real + " + " + Imaginary + "i"); } } ComplexNumber ﻣﺘﺪ زﻳـﺮ را ﺑـﻪ ﻛـﻼس،( را ﺑﺮاي اﻳﻦ ﻛﻼس ﺳﺮﺑﺎر ﮔﺬاري ﻛﻨﻴﻢ+) ( ﺑﺮاي اﻳﻨﻜﻪ ﻋﻤﻠﮕﺮ ﺟﻤﻊ7 :اﺿﺎﻓﻪ ﻛﻨﻴﺪ // Overloading '+' operator: public static ComplexNumber operator +(ComplexNumber a, ComplexNumber b) { // Create a new ComplexNumber object to store the sum ComplexNumber sum = new ComplexNumber(); // Calculate the sum sum.Real = a.Real + b.Real; sum.Imaginary = a.Imaginary + b.Imaginary; return sum; } : اﺿﺎﻓﻪ ﻛﻨﻴﺪComplexNumber ( ﻧﻴﺰ ﺑﺎﻳﺪ ﻣﺘﺪ زﻳﺮ را ﺑﻪ ﻛﻼس-) ( ﺑﺮاي ﺳﺮﺑﺎر ﮔﺬاري ﻋﻤﻠﮕﺮ ﺗﻔﺮﻳﻖ8 // Overloading '-' operator:
٣٨٩
public static ComplexNumber operator -(ComplexNumber a, ComplexNumber b) { // Create a new ComplexNumber object to store the minus ComplexNumber minus = new ComplexNumber(); // Calculate the minus minus.Real = a.Real - b.Real; minus.Imaginary = a.Imaginary - b.Imaginary; return minus; } ﺑـﻪ ﭼﻬـﺎر ﺷـﻴﺊ از ﻧـﻮع،( ﺑﺮاي ﻣﺤﺎﺳـﺒﻪ ي ﺟﻤـﻊ و ﺗﻔﺮﻳـﻖ دو ﻋـﺪد ﻣﺨـﺘﻠﻂ اي ﻛـﻪ ﻛـﺎرﺑﺮ در ﺑﺮﻧﺎﻣـﻪ وارد ﻛـﺮده اﺳـﺖ9 دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗـﺎ ﻣﺘـﺪ ﻣﺮﺑـﻮط ﺑـﻪbtnCalculate ﺑﺮ روي ﻛﻨﺘﺮل. ﻧﻴﺎز دارﻳﻢComplexNumber : ﺳﭙﺲ ﻛﺪ زﻳﺮ را در آن وارد ﻛﻨﻴﺪ. آن اﻳﺠﺎد ﺷﻮدClick روﻳﺪاد private void btnCalculate_Click(object sender, EventArgs e) { ComplexNumber number1 = new ComplexNumber(); ComplexNumber number2 = new ComplexNumber(); number1.Real = double.Parse(txtReal1.Text); number1.Imaginary = double.Parse(txtImg1.Text); number2.Real = double.Parse(txtReal2.Text); number2.Imaginary = double.Parse(txtImg2.Text); ComplexNumber sum = new ComplexNumber(); ComplexNumber minus = new ComplexNumber(); sum = number1 + number2; minus = number1 - number2; lblSum.Text = "Sum is: " + sum.ToString(); lblMinus.Text = "Minus is: " + minus.ToString(); } Calculate ﺳـﭙﺲ ﺑـﺮ روي دﻛﻤـﻪ ي.( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و دو ﻋﺪد ﻣﺨﺘﻠﻂ را در ﻛﺎدرﻫﺎي ﻣﺘﻨﻲ ﻓـﺮم وارد ﻛﻨﻴـﺪ10 : ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد6-10 ﻧﺘﻴﺠﻪ اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ.ﻛﻠﻴﻚ ﻛﻨﻴﺪ
٣٩٠
ﺷﻜﻞ 6-10
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺮﻧﺎﻣﻪ را ﺑﺎ اﻳﺠﺎد ﻛﻼﺳﻲ ﺑﺮاي ﻧﮕﻬﺪاري اﻋﺪاد ﻣﺨﺘﻠﻂ آﻏﺎز ﻣﻲ ﻛﻨﻴﻢ .ﺑﺮاي ﻧﮕﻬﺪاري اﻳـﻦ اﻋـﺪاد ﺑـﻪ دو ﻓﻴﻠـﺪ ،ﻳﻜـﻲ ﺑـﺮاي ﻧﮕﻬـﺪاري ﻗﺴﻤﺖ ﺣﻘﻴﻘﻲ و دﻳﮕﺮي ﺑﺮاي ﻧﮕﻬﺪاري ﻗﺴﻤﺖ ﻣﻮﻫﻮﻣﻲ ﻋﺪد ﻧﻴﺎز دارﻳﻢ .ﺑﻌﺪ از اﻳﺠﺎد اﻳﻦ دو ﻓﻴﻠﺪ ،ﺑﺮاي اﻳﻜﻪ ﺑﺘـﻮاﻧﻴﻢ راﺣـﺖ ﺗـﺮ اﻳـﻦ اﻋﺪاد را ﻧﻤﺎﻳﺶ دﻫﻴﻢ ،ﻣﺘﺪ ToStringرا ﺑﻪ ﮔﻮﻧﻪ اي overrideﻣﻲ ﻛﻨﻴﻢ ﺗﺎ اﻳﻦ اﻋﺪاد را ﺑﻪ ﻓـﺮم ﻋـﺎدي ﻧﻤـﺎﻳﺶ دﻫـﺪ. ﺑﺮاي اﻳﻦ ﻛﺎر از روﺷﻲ ﻛﻪ در ﻓﺼﻞ ﻗﺒﻠﻲ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ: // Override ToString() to display a complex number // in the traditional format )(public override string ToString { ;)"return (Real + " + " + Imaginary + "i } در ﻣﺮﺣﻠﻪ ي ﺑﻌﺪ ﺑﺎﻳﺪ ﻋﻤﻠﮕﺮ ﻫﺎي ﺟﻤﻊ و ﺗﻔﺮﻳﻖ را ﺑﺮاي اﻳﻦ ﻛﻼس ﺳﺮﺑﺎر ﮔﺬاري ﻛﻨﻴﻢ .ﺑﺮاي ﺳﺮﺑﺎر ﮔﺬاري ﻳﻚ ﻋﻤﻠﮕﺮ ﺑﺎﻳﺪ ﻣﺘﺪي ﺑـﺎ ﻳﻚ ﻗﺎﻟﺐ ﺧﺎص ﺑﻪ ﺻﻮرت staticو publicﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ .ﻧﺎم اﻳﻦ ﻣﺘﺪ ﺑﺎﻳﺪ ﺑﺎ ﻛﻠﻤﻪ ي ﻛﻠﻴـﺪي operatorﺷـﺮوع ﺷﺪه و ﺳﭙﺲ ﻋﻤﻠﮕﺮ ﻣﻮرد ﻧﻈﺮ را وارد ﻛﺮد .ﺑﺮاي ﻣﺜﺎل ﻧﺎم ﻣﺘﺪي ﻛﻪ ﺑﺮاي ﺳﺮﺑﺎر ﮔﺬاري ﻋﻤﻠﮕﺮ ﺟﻤـﻊ ﺑـﻪ ﻛـﺎر ﻣـﻲ رود ﺑﺎﻳـﺪ ﺑﺮاﺑـﺮ ﺑـﺎ operator +ﺑﺎﺷﺪ. ﭘﺎراﻣﺘﺮﻫﺎي اﻳﻦ ﻣﺘﺪ ،ﻋﻤﻠﻮﻧﺪ ﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﺮاي آن ﻋﻤﻠﮕﺮ ﻻزم اﺳﺖ .ﻣﺜﻼ ﻋﻤﻠﮕﺮ ﺟﻤﻊ ﺑﻪ دو ﻋﻤﻠﻮﻧﺪ ﻧﻴـﺎز دارد ﺗـﺎ ﺑﺘﻮاﻧـﺪ آن را ﺑـﺎ ﻳﻜﺪﻳﮕﺮ ﺟﻤﻊ ﻛﻨﺪ ،ﭘﺲ ﺑﺎﻳﺪ دو ﭘﺎراﻣﺘﺮ را ﺑﺮاي ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ ﺳﺮﺑﺎر ﮔﺬاري اﻳﻦ ﻋﻤﻠﮕﺮ ﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﺧﺮوﺟﻲ اﻳﻦ ﻣﺘﺪ ﻫـﻢ ﺑﺎﻳـﺪ ﻫـﻢ ﻧﻮع ﺑﺎ ﻧﺘﻴﺠﻪ ي آن ﻋﻤﻠﮕﺮ ﺑﺎﺷﺪ .ﺑﺮاي ﻣﺜﺎل در ﻋﻤﻠﮕﺮ ﺟﻤﻊ ،ﺧﺮوﺟﻲ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ ﺳﺮﺑﺎر ﮔﺬاري آن ﺑﺎﻳﺪ ﺑﺮاﺑﺮ ﺑﺎ ﻧﻮع ﻣﺘﻐﻴﺮي ﺑﺎﺷﺪ ﻛـﻪ ﺑﻪ ﻋﻨﻮان ﺣﺎﺻﻞ ﺟﻤﻊ ﻣﺸﺨﺺ ﻣﻲ ﺷﻮد. در ﺑﺮﻧﺎﻣﻪ ﻗﺒﻞ ﺑﺮاي اﻳﻨﻜﻪ ﻋﻤﻠﮕﺮ +را ﺳﺮﺑﺎر ﮔﺬاري ﻛﻨﻴﻢ ،ﺑﺎﻳﺪ ﻣﺘﺪي ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ: public static ComplexNumber operator +(ComplexNumber a, )ComplexNumber b ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ اﻳﻦ ﻣﺘﺪ ﺑﺎﻳﺪ ﺑﻪ ﺻﻮرت staticو publicﺗﻌﺮﻳﻒ ﺷﻮد .ﻫﻤﭽﻨﻴﻦ در ﻧﺎم آن ﻧﻴﺰ ﺑﺎﻳﺪ از ﻛﻠﻤـﻪ ي ﻛﻠﻴـﺪي operatorو ﻋﻤﻠﮕﺮي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺳﺮﺑﺎر ﮔﺬاري ﺷﻮد اﺳﺘﻔﺎده ﻛﻨﻴﻢ )در اﻳﻨﺠﺎ .(operator +ﻋﻤﻠﻮﻧﺪ ﻫﺎﻳﻲ ﻛـﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﻋﻤﻠﮕﺮ +ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮﻧﺪ ،ﻫﺮ دو از ﻧﻮع ﻋﺪد ﻣﺨﺘﻠﻂ ﻫﺴﺘﻨﺪ .ﺑﻪ ﺑﻴﺎن ﺑﻬﺘـﺮ ﻫـﺮ دوي ﻋﻤﻠﻮﻧـﺪ ﻫـﺎ ،ﺷـﻴﺊ اي از ﻧـﻮع ComplexNumberﻫﺴﺘﻨﺪ .ﭘﺲ ﭘﺎراﻣﺘﺮﻫﺎي ورودي ﻣﺘﺪ ﻧﻴﺰ از ﻧﻮع ComplexNumberﺧﻮاﻫﻨﺪ ﺑﻮد.
٣٩١
ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ اﮔﺮ ﻣﻲ ﺧﻮاﺳﺘﻴﻢ ﻋﻤﻠﮕﺮ +را ﺑﻪ ﮔﻮﻧﻪ اي ﺳﺮﺑﺎر ﮔﺬاري ﻛﻨﻴﻢ ﻛﻪ ﺑﺘﻮاﻧﻴﻢ ﻳﻚ ﺷﻴﺊ از ﻧـﻮع ComplexNumber را ﺑﺎ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ ﺟﻤﻊ ﻛﻨﻴﻢ ،ﺑﺎﻳﺪ در ﻣﺘﺪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﺮدﻳﻢ ﻛﻪ ﻳـﻚ ﺷـﻴﺊ از ﻧـﻮع ComplexNumberو ﻳﻚ ﻋﺪد از ﻧﻮع intرا ﺑﻪ ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻛﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﺴﺘﻴﻢ از دﺳﺘﻮري ﻣﺎﻧﻨﺪ زﻳﺮ ﺑﺮاي ﺟﻤﻊ ﻳﻚ ﻋﺪد ﻣﺨـﺘﻠﻂ ﺑﺎ ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ اﺳﺘﻔﺎده ﻛﻨﻴﻢ: ;Sum = number1 + 20 ﺑﻌﺪ از اﻳﻨﻜﻪ دو ﺷﻴﺊ از ﻧﻮع ComplexNumberرا ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﺟﻤﻊ ﻛـﺮدﻳﻢ ،ﻧﺘﻴﺠـﻪ ﻧﻴـﺰ از ﻧـﻮع ComplexNumber ﺧﻮاﻫﺪ ﺑﻮد ،ﭘﺲ ﺑﺎﻳﺪ ﺧﺮوﺟﻲ )ﻣﻘﺪار ﺑﺮﮔﺸﺘﻲ ﻣﺘﺪ( را از ﻧﻮع ComplexNumberﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﺳﭙﺲ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻧﺤﻮه ﺟﻤـﻊ ﻛﺮدن دو ﺷﻴﺊ از ﻧﻮع ﻣﺸﺨﺺ ﺷﺪه را در ﺑﺪﻧﻪ ي ﻣﺘﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ .در اﻳﻦ ﺟﺎ ﺑﺮاي ﺟﻤﻊ دو ﻣﻘﺪار ﻓﺮﺳﺘﺎده ﺷـﺪه ،ﺷـﻴﺊ ﺟﺪﻳـﺪي از ﻧﻮع ComplexNumberﺗﻌﺮﻳﻒ ﻛﺮده ،ﻗﺴﻤﺘﻬﺎي ﺣﻘﻴﻘﻲ دو ﻋﺪد را ﺑﺎ ﻳﻜﺪﻳﮕﺮ و ﻗﺴﻤﺘﻬﺎي ﻣﻮﻫﻮﻣﻲ آن را ﻧﻴـﺰ ﺑـﺎ ﻫـﻢ ﺟﻤـﻊ ﻛﺮده ﺣﺎﺻﻞ را در ﺷﻴﺊ ComplexNumberﺟﺪﻳﺪ ﻗﺮار ﻣﻲ دﻫﻴﻢ .ﺳﭙﺲ اﻳﻦ ﺷﻴﺊ را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﻣﻲ ﮔﺮداﻧﻴﻢ. // Overloading '+' operator: public static ComplexNumber operator +(ComplexNumber a, )ComplexNumber b { // Create a new ComplexNumber object to store the sum ;)(ComplexNumber sum = new ComplexNumber // Calculate the sum ;sum.Real = a.Real + b.Real ;sum.Imaginary = a.Imaginary + b.Imaginary ;return sum } ﺑــﺮاي ﺳــﺮﺑﺎر ﮔــﺬاري ﻋﻤﻠﮕــﺮ – ﻧﻴــﺰ از ﻫﻤــﻴﻦ روش اﺳــﺘﻔﺎده ﻣــﻲ ﻛﻨــﻴﻢ .اﻳــﻦ ﻋﻤﻠﮕــﺮ ﻧﻴــﺰ ﻣﺎﻧﻨــﺪ +دو ﺷــﻴﺊ از ﻧــﻮع ComplexNumberرا درﻳﺎﻓﺖ ﻛﺮده و ﺣﺎﺻﻞ را ﻧﻴﺰ ﺑﻪ ﺻﻮرت ComplexNumberﺑﺮﻣﻲ ﮔﺮداﻧﺪ. // Overloading '-' operator: public static ComplexNumber operator -(ComplexNumber a, )ComplexNumber b { // Create a new ComplexNumber object to store the // minus ;)(ComplexNumber minus = new ComplexNumber // Calculate the minus ;minus.Real = a.Real - b.Real ;minus.Imaginary = a.Imaginary - b.Imaginary ;return minus
٣٩٢
} ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن اﻳﻦ دو ﻣﺘﺪ ﺑﻪ ﻛﻼس ،ComplexNumberاﻳﻦ ﻛﻼس دﻳﮕﺮ ﻛﺎﻣﻞ ﺷﺪه اﺳـﺖ و ﻣـﻲ ﺗـﻮاﻧﻴﻢ از آن در ﺑﺮﻧﺎﻣـﻪ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .در ﺻﻔﺤﻪ ي اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ ﭼﻬﺎر ﻛﺎدر ﻣﺘﻨﻲ ﺑﺮاي درﻳﺎﻓﺖ ﻗﺴﻤﺘﻬﺎي ﻣﻮﻫﻮﻣﻲ و ﺣﻘﻴﻘﻲ دو ﻋﺪد ﻣﺨﺘﻠﻄﻲ ﻛﻪ ﺑﺎﻳﺪ ﺑـﺎ ﻫـﻢ ﺟﻤﻊ و ﺗﻔﺮﻳﻖ ﺷﻮﻧﺪ ﻗﺮار داده اﻳﻢ .اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ اﻳﻦ اﻋﺪاد ﺑﻪ ﺻﻮرت ﻣﺘﻦ در اﻳﻦ ﻛﺎدر ﻫﺎ وارد ﻣﻲ ﺷﻮﻧﺪ ،ﭘﺲ اﺑﺘـﺪا آﻧﻬـﺎ را ﺑﻪ ﻋﺪد ﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ .در ﻓﺼﻞ ﺳﻮم ﮔﻔﺘﻢ ﻛﻪ ﺑﺮاي ﺗﺒﺪﻳﻞ ﻳﻚ رﺷﺘﻪ ي ﺣﺎوي ﻋﺪد ﺑـﻪ ﻳـﻚ ﻋـﺪد ﺑﺎﻳـﺪ از ﻣﺘـﺪ Parseدر ﻛـﻼس ﻣﺮﺑﻮط ﺑﻪ ﻧﻮع داده اي آن ﻋﺪد اﺳﺘﻔﺎده ﻛﻨﻴﻢ .در اﻳﻦ ﻗﺴﻤﺖ ﻫﻢ ،ﺑﻪ اﻳﻦ ﻋﻠﺖ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﻴﻢ ﺑﺘﻮاﻧﺪ اﻋﺪاد اﻋﺸﺎري ﻧﻴﺰ وارد ﻛﻨﺪ ،ﻧﻮع داده اي اﻋﺪاد ﻣﻮﺟﻮد در ﻛﺎدر ﻫﺎ را ﺑﺮاﺑﺮ ﺑﺎ doubleدر ﻧﻈﺮ ﮔﺮﻓﺘﻪ و از ﺗﺎﺑﻊ Parseﻣﺮﺑـﻮط ﺑـﻪ آن اﺳـﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻣﺘﻦ وارد ﺷﺪه درون ﻛﺎدر ﺑﻪ ﻋﺪدي از ﻧﻮع Doubleﺗﺒﺪﻳﻞ ﺷﻮد. ;)number1.Real = double.Parse(txtReal1.Text ;)number1.Imaginary = double.Parse(txtImg1.Text ;)number2.Real = double.Parse(txtReal2.Text ;)number2.Imaginary = double.Parse(txtImg2.Text ﺣــﺎل ﻛــﻪ اﺷــﻴﺎي ﻣﺮﺑــﻮط ﺑــﻪ ﻧﮕﻬــﺪاري اﻋــﺪاد ﻣﺨــﺘﻠﻂ وارد ﺷــﺪه ﺑــﻪ وﺳــﻴﻠﻪ ﻛــﺎرﺑﺮ را اﻳﺠــﺎد ﻛــﺮدﻳﻢ ،دو ﺷــﻴﺊ ﺟﺪﻳــﺪ از ﻧــﻮع ComplexNumberاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺣﺎﺻﻞ ﺟﻤﻊ و ﻫﻤﭽﻨﻴﻦ ﺣﺎﺻﻞ ﺗﻔﺮﻳﻖ اﻳﻦ اﻋﺪاد را در آﻧﻬﺎ ﻗﺮار دﻫﻴﻢ. ;)(ComplexNumber sum = new ComplexNumber ;)(ComplexNumber minus = new ComplexNumber ﺑﻌﺪ از ﺗﻌﺮﻳﻒ اﻳﻦ دو ﺷﻴﺊ ﺑﻪ ﻗﺴﻤﺖ ﺟﺎﻟﺐ ﺑﺮﻧﺎﻣﻪ ﻣﻲ رﺳﻴﻢ .ﺑﻪ ﻧﺤﻮه اﺳـﺘﻔﺎده از ﻋﻤﻠﮕـﺮ ﺟﻤـﻊ ﺑـﺮاي ﺟﻤـﻊ ﻛـﺮدن دو ﺷـﻴﺊ از ﻧـﻮع ComplexNumberﺗﻮﺟﻪ ﻛﻨﻴﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﻪ اﻳﻦ دﺳﺘﻮر ﻣﻲ رﺳـﺪ ،ﻣﺘـﺪ operator +را ﻓﺮاﺧـﻮاﻧﻲ ﻛـﺮده، ﻣﺘﻐﻴﻴﺮ ﺳﻤﺖ ﭼﭗ ﻋﻼﻣﺖ +را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ اول و ﻣﺘﻐﻴﻴﺮ ﺳﻤﺖ راﺳﺖ را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ دوم ﺑﻪ ﻣﺘﺪ ﻣﻲ ﻓﺮﺳﺘﺪ .ﻣﻘـﺪار ﺑﺮﮔـﺸﺘﻲ ﻣﺘﺪ را ﻧﻴﺰ ﺑﻪ ﻋﻨﻮان ﺣﺎﺻﻞ ﻋﺒﺎرت در ﻣﺘﻐﻴﻴﺮ sumﻗﺮار ﻣﻲ دﻫﺪ .ﺳﭙﺲ ﻫﻤﻴﻦ ﻋﻤﻞ را ﺑﺮاي ﻗﺴﻤﺖ ﺗﻔﺮﻳـﻖ ﻧﻴـﺰ اﻧﺠـﺎم ﻣـﻲ دﻫـﺪ و ﺣﺎﺻﻞ ﻋﺒﺎرت ﻣﺮﺑﻮط ﺑﻪ آن را در ﻣﺘﻐﻴﻴﺮ minusﻗﺮار ﻣﻲ دﻫﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﻐﻴﻴﺮ sumﺣﺎوي ﻧﺘﻴﺠﻪ ي ﻣﺘﺪ operator ) +ﻳﺎ ﻫﻤﺎن ﺣﺎﺻﻞ ﺟﻤﻊ دو ﻋﺪد ﻣﺨﺘﻠﻂ( و ﻣﺘﻐﻴﻴﺮ minusﺣﺎوي ﻧﺘﻴﺠﻪ ﻣﺘﺪ – ) operatorﻳﺎ ﻫﻤـﺎن ﺣﺎﺻـﻞ ﺗﻔﺮﻳـﻖ دو ﻋﺪد ﻣﺨﺘﻠﻂ( ﺧﻮاﻫﺪ ﺑﻮد. ;sum = number1 + number2 ;minus = number1 - number2 ﺑﻌﺪ از ﻣﺤﺎﺳﺒﻪ ي اﻳﻦ دو ﻣﻘﺪار ،ﺑﺎﻳﺪ ﻧﺘﻴﺠﻪ را در ﺧﺮوﺟﻲ ﭼﺎپ ﻛﻨﻴﻢ .اﻣـﺎ ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﻧﻴـﺎزي ﻧﻴـﺴﺖ ﻛـﻪ از ﻓﻴﻠـﺪ ﻫـﺎي ﻛـﻼس ComplexNumberاﺳﺘﻔﺎده ﻛﻨـﻴﻢ .ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ ﺧـﺎﻃﺮ دارﻳـﺪ در اﺑﺘـﺪاي ﺑﺮﻧﺎﻣـﻪ ،ﻣﺘـﺪ ToStringرا ﺑـﻪ ﮔﻮﻧـﻪ اي overrideﻛﺮدﻳﻢ ﻛﻪ ﻋﺪد ﻣﺨﺘﻠﻂ ﻣﺮﺑﻮط ﺑﻪ ﺷﻴﺊ را ﺑﻪ ﺻﻮرت ﻣﻄﻠﻮب ﻧﻤﺎﻳﺶ دﻫﺪ .ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻦ ﻗﺴﻤﺖ ﻛﺎﻓﻲ اﺳـﺖ ﺑـﺮاي ﻫﺮ ﻳﻚ از اﺷﻴﺎي sumو minusاﻳﻦ ﻣﺘﺪ را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده و ﺣﺎﺻﻞ را در ﻳﻚ ﻟﻴﺒﻞ ﻧﻤﺎﻳﺶ دﻫﻴﻢ. ;)(lblSum.Text = "Sum is: " + sum.ToString ;)(lblMinus.Text = "Minus is: " + minus.ToString
٣٩٣
در اﻳﻦ ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﺴﺘﻴﻢ ﻫﻤﻴﻦ ﻛﺎر را ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪﻫﺎي ﻋﺎدي ﻣﺎﻧﻨﺪ ﻳﻚ ﻣﺘﺪ Addﻧﻴﺰ اﻧﺠﺎم دﻫـﻴﻢ ،اﻣـﺎ اﺳـﺘﻔﺎده از اﻳـﻦ روش ﺳﺎدﮔﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ و ﻧﻴﺰ ﺧﻮاﻧﺎﻳﻲ ﻛﺪ را اﻓﺰاﻳﺶ ﻣﻲ دﻫﺪ .ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﺑﺨﻮاﻫﻴﺪ ﭼﻬﺎر ﺷـﻴﺊ C ،B ،Aو Dرا ﺑـﺎ ﻳﻜـﺪﻳﮕﺮ ﺟﻤﻊ ﻛﻨﻴﺪ .در اﻳﻦ ﺻﻮرت اﮔﺮ ﺑﺨﻮاﻫﻴﺪ از ﻣﺘﺪﻫﺎي ﻋﺎدي اﺳﺘﻔﺎده ﻛﻨﻴﺪ ﺑﺎﻳﺪ ﻓﺮﺿﺎً ﭼﻬﺎر ﻣﺮﺗﺒـﻪ ﻣﺘـﺪ Addرا ﻓﺮاﺧـﻮاﻧﻲ ﻛﻨﻴـﺪ ،اﻣـﺎ ﺑـﺎ اﺳﺘﻔﺎده از ﺳﺮﺑﺎر ﮔﺬاري ﻋﻤﻠﮕﺮ ﺟﻤﻊ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ راﺣﺘﻲ از دﺳﺘﻮر A+B+C+Dاﺳﺘﻔﺎده ﻛﻨﻴﺪ.
ﻛﻼﺳﻬﺎي :Abstract ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﺗﻤﺎم ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد از آﻧﻬﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ در ﺣﻘﻴﻘﺖ ﻳﻚ ﺷﻴﺊ از ﻛﻼﺳﻲ ﻣﺮﺑﻮط ﺑـﻪ آن ﻛﻨﺘﺮل ﻫﺴﺘﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻛﻨﺘﺮل Buttonروي ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻗﺮار ﻣﻲ دﻫﻴﺪ ،در ﺣﻘﻴﻘﺖ ﻳﻚ ﺷﻴﺊ از ﻛﻼﺳﻲ ﺑﻪ ﻧﺎم Buttonاﻳﺠﺎد ﻛﺮده اﻳﺪ و در ﻃﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﺑﺎ آن ﺷﻴﺊ ﻛﺎر ﻣﻲ ﻛﻨﻴﺪ. ﻓﺮض ﻛﻨﻴﺪ ﺑﺨﻮاﻫﻴﺪ ﻛﻼس ﻣﺮﺑﻮط ﺑﻪ ﭼﻨﻴﻦ ﻛﻨﺘﺮل ﻫﺎﻳﻲ را در ﺑﺮﻧﺎﻣﻪ ﺑﻨﻮﻳﺴﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر اﺑﺘﺪا ﺑﺎﻳﺪ ﻳﻚ ﻛﻼس ﭘﺎﻳﻪ ،ﺑﺮاي ﻣﺜﺎل ﺑـﻪ ﻧﺎم Windowاﻳﺠﺎد ﻛﺮده و ﺗﻤﺎم ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي ﻣﺸﺘﺮك ﺑﻴﻦ ﻛﻨﺘﺮل ﻫﺎ را در اﻳﻦ ﻛﻼس ﻗﺮار دﻫﻴـﺪ .ﺳـﭙﺲ ﺗﻤـﺎم ﻛﻨﺘـﺮل ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ اﻳﺠﺎد ﻛﻨﻴﺪ را ،ﻣﺎﻧﻨﺪ ﻛﻨﺘﺮل Buttonو ﻳﺎ ﻛﻨﺘﺮل ،TextBoxاز اﻳﻦ ﻛﻼس ﺑﻪ ارث ﺑﺒﺮﻳﺪ .در اﻳﻦ ﺣﺎﻟـﺖ ﻣﺴﻠﻤﺎً ﻧﻤﻲ ﺧﻮاﻫﻴﺪ ﺑﻌﺪﻫﺎ ﻛﺴﻲ ﺑﺘﻮاﻧﺪ ﺷﻴﺊ را از ﻛﻼس Windowﻧﻤﻮﻧﻪ ﺳﺎزي ﻛﻨﺪ و از آن ﺷﻴﺊ در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﺪ ،ﭼﻮن اﻳـﻦ اﻣﺮ ﺑﻲ ﻣﻌﻨﻲ اﺳﺖ .ﻛﻼس Windowﻧﺸﺎن دﻫﻨﺪه ﻫﻴﭻ ﻛﻨﺘﺮل ﺧﺎﺻﻲ ﻧﻴﺴﺖ ،ﺑﻠﻜﻪ ﻓﻘﻂ ﺑﻪ ﻋﻨﻮان ﻳـﻚ ﻛـﻼس ﭘﺎﻳـﻪ ﺑـﺮاي ﺗﻤـﺎم ﻛﻨﺘﺮل ﻫﺎ ﺑﻪ ﻛﺎر ﻣﻲ رود .ﺑﻨـﺎﺑﺮاﻳﻦ اﻳـﻦ ﻛـﻼس را ﺑـﻪ ﻋﻨـﻮان ﻳـﻚ ﻛـﻼس abstractﻣـﺸﺨﺺ ﻣـﻲ ﻛﻨﻴـﺪ .ﻛـﻼس ﻫـﺎي abstractﺑﻪ ﺑﻴﺎن ﺳﺎده ﺗﺮ ﻛﻼس ﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﻧﻤﻲ ﺗﻮان ﻫﻴﭻ ﺷﻴﺊ را از آﻧﻬﺎ ﻧﻤﻮﻧﻪ ﺳﺎزي ﻛـﺮد و ﺣﺘﻤـﺎً ﺑﺎﻳـﺪ ﺑـﻪ ﻋﻨـﻮان ﻛﻼس ﻫﺎي ﭘﺎﻳﻪ ﺑﺮاي دﻳﮕﺮ ﻛﻼﺳﻬﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮﻧﺪ. ﺣــﺎل ﺗــﺼﻮر ﻛﻨﻴــﺪ ﻛــﻪ ﻣــﻲ ﺧﻮاﻫﻴــﺪ ﺗﻤــﺎم ﻛﻨﺘــﺮل ﻫــﺎﻳﻲ ﻛــﻪ از ﻛــﻼس Windowﻣــﺸﺘﻖ ﻣــﻲ ﺷــﻮﻧﺪ داراي ﻣﺘــﺪي ﺑــﻪ ﻧــﺎم DrawWindowﺑﺎﺷﻨﺪ ﻛﻪ آن ﻛﻨﺘﺮل را در ﺻﻔﺤﻪ رﺳﻢ ﻛﻨﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ ﻣﺘﺪي ﺑﻪ ﻧـﺎم DrawWindowدر ﻛـﻼس Windowاﻳﺠﺎد ﻛﻨﻴﺪ .اﻣﺎ ﻧﺤﻮه رﺳﻢ ﻫﺮ ﻛﻨﺘﺮل ﺑﻪ ﻧﻮع آن ﺑﺴﺘﮕﻲ دارد و ﻫﻴﭻ ﻧﻘﻄﻪ ي اﺷﺘﺮاﻛﻲ در اﻳﻦ ﻣﻮرد ﺑﻴﻦ ﻛﻨﺘﺮل ﻫﺎ وﺟـﻮد ﻧﺪارد ﻛﻪ ﺑﺨﻮاﻫﻴﺪ آن را در ﺑﺪﻧﻪ ي اﻳﻦ ﻣﺘﺪ ﻗﺮار دﻫﻴﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ اﻳﻦ ﻣﺘﺪ ﻧﻤﻲ ﺗﻮاﻧﺪ ﺷﺎﻣﻞ ﻫﻴﭻ ﻛﺪي ﺑﺎﺷﺪ .ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻫﺮ ﻛﻨﺘﺮﻟﻲ ﻛﻪ ﺑﺎ ﻣﺸﺘﻖ ﺷﺪن از ﻛﻼس Windowاﻳﺠﺎد ﻣﻲ ﺷﻮد ،ﺣﺘﻤﺎً اﻳﻦ ﻣﺘﺪ را در ﺧﻮد overrideﻛﻨﺪ ﺗﺎ ﺑﻪ اﻳﻦ وﺳـﻴﻠﻪ ﻧﺤﻮه ي رﺳﻢ آن ﻛﻨﺘﺮل در ﺻﻔﺤﻪ ﻣﺸﺨﺺ ﺷﻮد .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﺪ آن ﻣﺘﺪ را از ﻧﻮع abstractﻣﺸﺨﺺ ﻛﻨﻴﺪ .ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴﺐ ﻫﺮ ﻛﻼﺳﻲ ﻛﻪ از ﻛﻼس Windowﺑﻪ ﻋﻨﻮان ﻛﻼس ﭘﺎﻳﻪ اﺳﺘﻔﺎده ﻛﻨﺪ ﻣﻮﻇﻒ اﺳﺖ ﻛﻪ ﺗﻤﺎم اﻋـﻀﺎي abstractآن ﻛﻼس را در ﺧﻮد overrideﻛﻨﺪ .اﻟﺒﺘﻪ دﻗﺖ داﺷﺘﻪ ﺑﺎﺷـﻴﺪ ﻛـﻪ ﻳـﻚ ﻋـﻀﻮ abstractﻓﻘـﻂ ﻣـﻲ ﺗﻮاﻧـﺪ در ﻛﻼﺳـﻬﺎي abstractاﻳﺠﺎد ﺷﻮد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ در ﻳﻚ ﻛﻼس ﻋﺎدي ،ﻳﻚ ﻋﻀﻮ abstractاﻳﺠﺎد ﻛﻨﻴﺪ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﻣﺜﺎﻟﻲ ﻛﻪ در ﺑﺎﻻ ﻋﻨﻮان ﺷﺪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺳﺎده ﭘﻴﺎده ﺳﺎزي ﻛﻨﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻛﻼﺳﻬﺎي Abstract (1ﺑﺎ اﺳﺘﻔﺎده از ﮔﺰﻳﻨﻪ ي … File New Projectدر ﻧﻮار ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ ،ﻳﻚ ﭘـﺮوژه ﺗﺤـﺖ ﻛﻨﺴﻮل ﺟﺪﻳﺪ ﺑﺎ وﻳﮋوال C#ﺑﻪ ﻧﺎم Abstract Demoاﻳﺠﺎد ﻛﻨﻴﺪ. (2ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي Solution Explorerﻳﻚ ﻛﻼس ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم Windowﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ. (3ﺗﻌﺮﻳﻒ ﻛﻼس Windowرا ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ:
٣٩٤
namespace Abstract_Demo { abstract public class Window { دﻗـﺖ ﻛﻨﻴـﺪ ﻣﺘـﺪي ﻛـﻪ در اﻳـﻦ ﻛـﻼس ﺑـﻪ ﺻـﻮرت. اﺿـﺎﻓﻪ ﻛﻨﻴـﺪWindow ( ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ ﻛـﻼس4 . ﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ ﻧﺒﺎﻳﺪ ﺣﺎوي ﻛﺪ ﺑﺎﺷﺪabstract abstract public class Window { public int Left; public int Top; // Constructor method to set // the initial value of fields public Window() { this.Top = 0; this.Left = 0; } // simulates drawing the window // notice: no implementation abstract public void DrawWindow(); } ﺑـﻪListBox ﻛﻼس ﺟﺪﻳﺪي ﺑﻪ ﻧﺎم،Window و ﺑﻌﺪ از ﻛﻼسAbstract_Demo ( در داﺧﻞ ﻓﻀﺎي ﻧﺎم5 ﻣﺸﺘﻖ ﻣﻲ ﺷﻮد و ﺑﻪ ﺻﻮرت ﻓﺮﺿﻲ ﻳـﻚ ﻟﻴـﺴﺖ ﺑـﺎﻛﺲ را درWindow اﻳﻦ ﻛﻼس از ﻛﻼس.ﺻﻮرت زﻳﺮ ﺗﻌﺮﻳﻒ ﻛﻨﻴﺪ زﻳـﺮا، در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﮕـﺮان ﻧﺒﺎﺷـﻴﺪListBox در ﻣﻮرد ﺗﺪاﺧﻞ ﻧﺎم اﻳﻦ ﻛﻼس ﺑﺎ ﻛﻼس.ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ اﺳﺖ وﻟـﻲ ﻛـﻼسAbstract_Demo ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﺪ در ﻓﻀﺎي ﻧﺎمListBox ﻛﻼس . اﺳﺖSystem.Windows.Forms وﻳﮋوال اﺳﺘﻮدﻳﻮ در ﻓﻀﺎي ﻧﺎمListBox // ListBox derives from Window public class ListBox : Window { private string listBoxContents; // new member variable // constructor adds a parameter public ListBox(int top,int left,string contents) { Top = top; Left = left; listBoxContents = contents; }
٣٩٥
// an overridden version implementing the // abstract method public override void DrawWindow() { Console.WriteLine("Writing string to the" + " listbox: " + listBoxContents); } } ﺑـﺮاي. اﻳﺠﺎد ﻛﻨـﻴﻢWindow ﺑﺎ اﺳﺘﻔﺎده از ﻛﻼس،Button ( ﺣﺎل ﻣﻲ ﺧﻮاﻫﻴﻢ ﻛﻨﺘﺮل دﻳﮕﺮي ﻧﻴﺰ ﻣﺎﻧﻨﺪ ﻳﻚ ﻛﻨﺘﺮل6 ﺑﻪ ﺻﻮرت زﻳـﺮ اﻳﺠـﺎدAbstract_Demo در ﻓﻀﺎي ﻧﺎمListBox اﻳﻦ ﻛﺎر ﻛﻼس دﻳﮕﺮي را ﺑﻌﺪ از ﻛﻼس :ﻛﻨﻴﺪ // Button control that derives from Window class public class Button : Window { // The new class's constructor public Button(int top, int left) { Top = top; Left = left; } // implement the abstract method public override void DrawWindow() { Console.WriteLine("Drawing a button at " + Top + ", " + Left); } } وﻳﺮاﻳـﺸﮕﺮ ﻛـﺪ ﺑـﺮاي.( اﻳﺠﺎد ﻛﻼﺳﻬﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﭘﺎﻳﺎن رﺳﻴﺪ و ﺣﺎﻻ ﺑﺎﻳﺪ ﻧﺤﻮه ﻋﻤﻠﻜﺮد آﻧﻬﺎ را ﺑﺮرﺳﻲ ﻛﻨـﻴﻢ7 . وارد ﻛﻨﻴﺪMain را ﺑﺎز ﻛﺮده و ﻛﺪ زﻳﺮ را در ﻣﺘﺪProgram.cs ﻓﺎﻳﻞ static void Main(string[] args) { // Create two list boxes and one ListBox lstBox1 = new ListBox(1, ListBox lstBox2 = new ListBox(3, Button newButton = new Button(5, // Draw all objects on the form lstBox1.DrawWindow(); lstBox2.DrawWindow(); newButton.DrawWindow();
٣٩٦
button 2, "First List Box"); 4,"Second List Box"); 6);
;)(Console.ReadLine } (8ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ ،ﻧﺘﻴﺠﻪ اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 7-10را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 7-10
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺮﻧﺎﻣﻪ را ﺑﺎ ﺗﻌﺮﻳﻒ ﻳﻚ ﻛﻼس ﭘﺎﻳﻪ ﺑﻪ ﻧﺎم Windowﺷﺮوع ﻣﻲ ﻛﻨﻴﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ اﻳﻦ ﻛﻼس ﺑﺎﻳﺪ ﺑﻪ ﮔﻮﻧﻪ اي ﺑﺎﺷﺪ ﻛﻪ ﺗﻤﺎم ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪ ﻫﺎﻳﻲ را ﻛﻪ ﺑﻴﻦ ﺗﻤﺎم ﻛﻨﺘﺮل ﻫﺎ ﻣﺸﺘﺮك اﺳﺖ ﺷﺎﻣﻞ ﺷﻮد .ﻫﻤﭽﻨﻴﻦ ﺑﺮاي اﻳﻨﻜﻪ ﻧﺘﻮان ﺷﻴﺊ را از اﻳـﻦ ﻛـﻼس اﻳﺠـﺎد ﻛﺮد ،آن را ﺑﻪ ﺻﻮرت abstractﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨـﻴﻢ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﻛـﺎﻓﻲ اﺳـﺖ ﻫﻨﮕـﺎم ﺗﻌﺮﻳـﻒ ﻛـﻼس ،ﻛﻠﻤـﻪ ي ﻛﻠﻴـﺪي abstractرا ﺑﻪ اﺑﺘﺪاي آن اﺿﺎﻓﻪ ﻛﻨﻴﻢ. abstract public class Window ﺗﻤﺎم ﻛﻨﺘﺮل ﻫﺎ در ﻳﻚ ﻓﺮم داراي ﻣﻮﻗﻌﻴﺖ ﻣﻜﺎﻧﻲ ﻣﻌﻴﻨﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ دو ﺧﺎﺻﻴﺖ ) Topﻓﺎﺻﻠﻪ ي ﻛﻨﺘـﺮل از ﺑـﺎﻻي ﻓـﺮم( و ) Leftﻓﺎﺻﻠﻪ ي ﻛﻨﺘﺮل از ﺳﻤﺖ ﭼﭗ ﻓﺮم( ﻣﺸﺨﺺ ﻣﻲ ﺷﻮﻧﺪ .ﭘﺲ ﻫﻤﻪ ي آﻧﻬﺎ ﺑﺎﻳﺪ ﺷﺎﻣﻞ دو ﻓﻴﻠﺪ ﺑﻪ ﻧﺎﻣﻬـﺎي Topو Left ﺑﺎﺷﻨﺪ .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ اﻳﻦ دو ﻓﻴﻠﺪ را در ﻛﻼس Windowﻗﺮار ﻣﻲ دﻫﻴﻢ. ;public int Left ;public int Top ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺗﻤﺎم ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ از اﻳﻦ ﻛﻼس ﻣﺸﺘﻖ ﻣﻲ ﺷﻮﻧﺪ ،ﺣﺘﻤﺎً ﻣﺘﺪي ﺑﻪ ﻧﺎم DrawWindowداﺷﺘﻪ ﺑﺎﺷـﻨﺪ ﺗـﺎ آﻧﻬﺎ را در ﻓﺮم رﺳﻢ ﻛﻨﺪ .اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ اﻳﻦ ﻣﺘﺪ ﺑﺮاي ﻫﺮ ﻛﻨﺘﺮل ﻣﺘﻔـﺎوت اﺳـﺖ و ﻧﻤـﻲ ﺗـﻮاﻧﻴﻢ ﭘﻴـﺎده ﺳـﺎزي آن را در ﻛـﻼس Windowﻗﺮار دﻫﻴﻢ ،ﺑﻨﺎﺑﺮاﻳﻦ آن را در ﻛﻼس ﭘﺎﻳﻪ ﺑﻪ ﺻﻮرت abstractﻣﻌﺮﻓﻲ ﻣﻲ ﻛﻨﻴﻢ ﺗـﺎ ﺗﻤـﺎم ﻛـﻼس ﻫـﺎﻳﻲ ﻛـﻪ از ﻛﻼس Windowﻣﺸﺘﻖ ﻣﻲ ﺷﻮﻧﺪ ﭼﻨﻴﻦ ﻣﺘﺪي را در ﺧﻮد اﻳﺠﺎد ﻛﻨﻨﺪ .ﺑﻪ اﻳﻦ ﺻﻮرت ﻣﻲ ﺗﻮاﻧﻴﻢ ﺗﻀﻤﻴﻦ ﻛﻨﻴﻢ ﻛﻪ ﺗﻤﺎم ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ از ﻛﻼس Windowﻣﺸﺘﻖ ﻣﻲ ﺷﻮﻧﺪ داراي ﻣﺘﺪي ﺑﻪ ﻧﺎم DrawWindowﻫﺴﺘﻨﺪ ﻛﻪ آﻧﻬﺎ را در ﺻـﻔﺤﻪ رﺳـﻢ ﻣـﻲ ﻛﻨـﺪ. دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ اﮔﺮ ﻣﺘﺪي در ﻳﻚ ﻛﻼس ﺑﻪ ﻋﻨﻮان abstractﻣﻌﺮﻓﻲ ﺷﻮد ،آن ﻣﺘﺪ ﻧﺒﺎﻳﺪ ﺷﺎﻣﻞ ﻫﻴﭻ دﺳﺘﻮري ﺑﺎﺷـﺪ .ﺑـﻪ ﻋﺒـﺎرت دﻳﮕﺮ آن ﻣﺘﺪ ﻧﺒﺎﻳﺪ داراي ﭘﻴﺎده ﺳﺎزي ﺑﺎﺷﺪ.
٣٩٧
// Simulates drawing the window // Notice: NO implementation ;)(abstract public void DrawWindow در اﻧﺘﻬﺎ ﻧﻴﺰ ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه ﺑﺮاي اﻳﻦ ﻛﻼس اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻣﻘﺪار اوﻟﻴﻪ ﻓﻴﻠﺪ ﻫﺎي Topو Leftرا ﻣﺸﺨﺺ ﻛﻨﺪ. // Constructor method to set // the initial value of fields )(public Window { ;this.Top = 0 ;this.Left = 0 } ﺣﺎل ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻼس ،Windowﻛﻨﺘﺮﻟﻬﺎي ﻣﻮرد ﻧﻈﺮﻣﺎن را اﻳﺠﺎد ﻛﻨﻴﻢ .اﺑﺘﺪا از ﻛﻨﺘﺮﻟﻲ ﻫﻤﺎﻧﻨﺪ ListBoxﺷـﺮوع ﻣـﻲ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﻼﺳﻲ ﺑﻪ ﻧﺎم ListBoxاﻳﺠﺎد ﻛﺮده و ﻛﻼس Windowرا ﺑﻪ ﻋﻨﻮان ﻛﻼس ﭘﺎﻳـﻪ ي آن ﻣـﺸﺨﺺ ﻣـﻲ ﻛﻨﻴﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺑﺨﺶ ﻓﻀﺎي ﻧﺎم ﮔﻔﺘﻢ ،ﻧﺎم ﻛﺎﻣﻞ اﻳﻦ ﻛﻼس ﺑﻪ ﺻـﻮرت Abstract_Demo.ListBoxاﺳـﺖ، ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ ﻛﻼس ListBoxﻣﺮﺑﻮط ﺑﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻛﻪ ﺑﻪ ﻧﺎم System.Windows.Forms.ListBox اﺳﺖ اﺷﺘﺒﺎه ﻧﺨﻮاﻫﺪ ﺷﺪ. در اﻳﻦ ﻛﻼس ﻓﻴﻠﺪ ﺟﺪﻳﺪي ﺑﻪ ﻧﺎم listBoxContentsاز ﻧﻮع رﺷﺘﻪ اي اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻋﻼوه ﺑﺮ ﻣﻮﻗﻌﻴـﺖ ﻫـﺮ ﻟﻴـﺴﺖ ﺑﺎﻛﺲ ،ﻣﺤﺘﻮﻳﺎت آن را ﻧﻴﺰ ﺑﺘﻮاﻧﻴﻢ ﻧﮕﻬﺪاري ﻛﻨﻴﻢ و در ﻣﻮاﻗﻊ ﻣﻮرد ﻧﻴﺎز ﻧﻤﺎﻳﺶ دﻫﻴﻢ. // ListBox derives from Window public class ListBox : Window { private string listBoxContents; // new member variable ﻫﻤﭽﻨﻴﻦ ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه ﻧﻴﺰ در اﻳﻦ ﻛﻼس ﻗﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ ﻣﻘﺪار ﻓﻴﻠﺪ ﻫﺎ را ﺗﻨﻈﻴﻢ ﻛﻨﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣـﺸﺎﻫﺪه ﻣـﻲ ﻛﻨﻴـﺪ اﻳـﻦ ﻣﺘـﺪ ﺳﺎزﻧﺪه ﻫﻤﺎﻧﻨﺪ ﻣﺘﺪﻫﺎي ﻣﻌﻤﻮﻟﻲ ﺳﻪ ﭘﺎراﻣﺘﺮ ﻣﻲ ﮔﻴﺮد :ﭘﺎراﻣﺘﺮ اول ﺑﺮاي ﺗﻌﻴﻴﻦ ﻓﺎﺻﻠﻪ ي ﻛﻨﺘـﺮل از ﺳـﻤﺖ ﭼـﭗ )ﻣﻘـﺪار ﻓﻴﻠـﺪ ،(Top ﭘﺎراﻣﺘﺮ دوم ﺑﺮاي ﺗﻌﻴﻴﻦ ﻓﺎﺻﻠﻪ ي ﻛﻨﺘﺮل از ﺑﺎﻻي ﻓﺮم )ﻣﻘﺪار ﻓﻴﻠﺪ (Leftو ﭘﺎراﻣﺘﺮ ﺳﻮم ﺑﺮاي ﺗﻌﻴﻴﻦ ﻣﺘﻨﻲ ﻛﻪ ﺑﺎﻳﺪ در ﻟﻴﺴﺖ ﺑـﺎﻛﺲ ﻗﺮار ﮔﻴﺮد )ﻣﻘﺪار ﺧﺎﺻﻴﺖ .(listBoxContentsﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﻢ در ﻫﻤﺎن اﺑﺘﺪاي اﻳﺠﺎد ﺷﻴﺊ از ﻛـﺎرﺑﺮ ﺑﺨـﻮاﻫﻴﻢ ﻛﻪ ﻣﻘﺪار اﻳﻦ ﻣﻮارد را ﺗﻌﻴﻴﻦ ﻛﻨﺪ. // constructor adds a parameter )public ListBox(int top,int left,string contents { ;Top = top ;Left = left ;listBoxContents = contents }
٣٩٨
ﻧﻜﺘﻪ :اﮔﺮ ﻣﺘﺪ ﺳﺎزﻧﺪه ي ﻳﻚ ﻛﻼس ﭘﺎراﻣﺘﺮ داﺷﺘﻪ ﺑﺎﺷﺪ ،ﻫﻨﮕﺎم ﻧﻤﻮﻧﻪ ﺳﺎزي ﻳﻚ ﺷﻴﺊ از آن ﻛﻼس ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر newﺑﺎﻳـﺪ ﻣﻘﺪار آن ﭘﺎراﻣﺘﺮ ﻫﺎ را ﺑﻪ ﻛﻼس ﻓﺮﺳﺘﺎد .ﺑﺮاي ﻣﺜﺎل ﺑﻪ ﻧﺤﻮه ﻧﻤﻮﻧﻪ ﺳﺎزي اﺷﻴﺎي ﻛﻼس ListBoxدر ﻣﺘﺪ Mainﺗﻮﺟﻪ ﻛﻨﻴـﺪ. ﺑﻌﺪ از دﺳﺘﻮر ،newدر ﻣﻘﺎﺑﻞ اﺳﻢ ﻛﻼس ﻣﻘﺪارﻫﺎي ﻻزم ﺑﺮاي اﻳﺠﺎد ﻛﻼس ﻧﻴﺰ ﺑﻪ ان ﻓﺮﺳﺘﺎده ﺷﺪه اﻧﺪ. ;)"ListBox lstBox1 = new ListBox(1, 2, "First List Box اﻟﺒﺘﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻧﺎم ﻛﻼس را ﺑﻌﺪ از دﺳﺘﻮر newدر اﻳﻦ ﻗﺴﻤﺖ وارد ﻛﺮدﻳﺪ ،وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﺑﺮاي ﻧﻤﻮﻧﻪ ﺳﺎزي ﻳﻚ ﺷﻴﺊ از اﻳﻦ ﻛﻼس ،ﭼﻪ ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ را ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ )ﺷﻜﻞ (8-10
ﺷﻜﻞ 8-10 ﻫﻨﻮز ﻛﻼس ListBoxﻛﺎﻣﻞ ﻧﺸﺪه اﺳﺖ و اﮔﺮ در اﻳﻦ ﻣﺮﺣﻠﻪ آن را ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﻴﻢ ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟـﻪ ﺧـﻮاﻫﻴﻢ ﺷـﺪ .زﻳـﺮا ﻫﻨـﻮز ﻣﺘـﺪ DrawWindowرا در اﻳــﻦ ﻛــﻼس overrideﻧﻜــﺮده اﻳــﻢ و در ﻛــﻼس Windowﻫــﻢ اﻳــﻦ ﻣﺘــﺪ ﺑــﻪ ﺻــﻮرت abstractﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ،ﭘﺲ ﺑﺎﻳﺪ در ﻛﻼس ﻣﺸﺘﻖ ﺷـﺪه overrideﺷـﻮد .ﺑﻨـﺎﺑﺮاﻳﻦ ﻫﻤﺎﻧﻨـﺪ override ﻛﺮدن ﻣﺘﺪﻫﺎي ﻋـﺎدي ﻛـﻪ در ﻗـﺴﻤﺘﻬﺎي ﻗﺒـﻞ ﻣـﺸﺎﻫﺪه ﻛـﺮده اﻳـﺪ ،ﻣﺘـﺪ DrawWindowاز ﻛـﻼس ﭘﺎﻳـﻪ را در اﻳـﻦ ﻛـﻼس overrideﻣﻲ ﻛﻨﻴﻢ. // an overridden version implementing the // abstract method )(public override void DrawWindow { Console.WriteLine("Writing string to the" + ;)" listbox: " + listBoxContents } اﻟﺒﺘﻪ در اﻳﻦ ﻗﺴﻤﺖ درﮔﻴﺮ ﻧﺤﻮه ي ﭘﻴﺎده ﺳﺎزي اﻳﻦ ﻣﺘﺪ ﻧﻤﻲ ﺷﻮﻳﻢ ،ﺑﻠﻜﻪ ﻓﻘﻂ ﻣﻲ ﺧـﻮاﻫﻴﻢ ﻧﺤـﻮه overrideﻛـﺮدن ﻣﺘـﺪﻫﺎي abstractدر ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه را ﺗﻮﺿﻴﺢ دﻫﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻦ ﻣﺘﺪ ،ﻓﻘﻂ در ﺧﺮوﺟﻲ ﭼﺎپ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻳﻚ ﻟﻴـﺴﺖ ﺑـﺎﻛﺲ ﺑﺎ ﻣﺸﺨﺼﺎت ﻣﻌﻴﻦ ﺷﺪه رﺳﻢ ﺷﺪ. ﺣﺎل ﻛﻪ ﻛﻨﺘﺮل اول را اﻳﺠﺎد ﻛﺮدﻳﻢ ،ﺑﻪ ﺳﺮاغ ﻛﻨﺘﺮل ﺑﻌﺪي ﻛﻪ ﻳﻚ Buttonاﺳﺖ ﻣﻲ روﻳﻢ .ﺑﺮاي اﻳﺠﺎد اﻳﻦ ﻛﻨﺘـﺮل ﻧﻴـﺰ ﻫﻤﺎﻧﻨـﺪ ﻛﻨﺘﺮل ،ListBoxﻳﻚ ﻛﻼس ﺑﻪ ﻧﺎم Buttonاﻳﺠﺎد ﻛﺮده و ﻛﻼس Windowرا ﺑﻪ ﻋﻨﻮان ﻛﻼس ﭘﺎﻳﻪ ي آن ﻣـﺸﺨﺺ ﻣﻲ ﻛﻨﻴﻢ. // Button control that derives from Window class public class Button : Window {
٣٩٩
ﺑﻘﻴﻪ ﻣﻮارد اﻳﻦ ﻛﻼس ﻧﻴﺰ ﻣﺸﺎﺑﻪ ﻛﻼس ListBoxاﺳﺖ و ﻫﻴﭻ اﺑﻬﺎﻣﻲ در آن وﺟﻮد ﻧﺪارد .اﻟﺒﺘﻪ دﻗﺖ ﻛﻨﻴـﺪ در اﻳـﻦ ﻛـﻼس ﻧﻴـﺰ ﻫﻤﺎﻧﻨﺪ ﻛﻼس ،ListBoxاﮔﺮ ﻣﺘﺪ DrawWindowرا overrideﻧﻜﻨﻴﻢ ،ﺑﺎ ﺧﻄﺎي زﻣـﺎن ﻛﺎﻣﭙﺎﻳـﻞ ﻣﻮاﺟـﻪ ﺧـﻮاﻫﻴﻢ ﺷﺪ. // The new class's constructor )public Button(int top, int left { ;Top = top ;Left = left } // implement the abstract method )(public override void DrawWindow { Console.WriteLine("Drawing a button at " + Top ;)+ ", " + Left } ﺣﺎل ﻛﻪ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮرد ﻧﻈﺮﻣﺎن را اﻳﺠﺎد ﻛﺮدﻳﻢ ،ﺑﺎﻳﺪ آﻧﻬﺎ را در ﺑﺮﻧﺎﻣﻪ ﺗﺴﺖ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ،اﺑﺘﺪا دو ﺷﻴﺊ از ﻧـﻮع ListBox و ﻳﻚ ﺷﻴﺊ ﻧﻴﺰ از ﻧﻮع Buttonاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ .ﺳﭙﺲ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ DrawWindowدر آﻧﻬﺎ ،اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ 7-10ﻧﻴﺰ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ DrawWindowدر اﻳﻦ اﺷﻴﺎ ،آﻧﻬﺎ در ﺻـﻔﺤﻪ رﺳﻢ ﻣﻲ ﺷﻮﻧﺪ. button ;)"2, "First List Box ;)"4,"Second List Box ;)6
// Create two list boxes and one ListBox lstBox1 = new ListBox(1, ListBox lstBox2 = new ListBox(3, Button newButton = new Button(5, // Draw all objects on the form ;)(lstBox1.DrawWindow ;)(lstBox2.DrawWindow ;)(newButton.DrawWindow
ﻧﻜﺘﻪ :از ﻳﻚ ﻛﻼس ،abstractﻣﻲ ﺗﻮان ﻳﻚ ﻛﻼس abstractدﻳﮕﺮ ﻣﺸﺘﻖ ﻛﺮد .ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻛﻼﺳﻲ ﺑﻪ ﻧﺎم Buttonاﻳﺠﺎد ﻛﻨﻴﺪ ،اﻣـﺎ اﺟـﺎزه ﻧﺪﻫﻴـﺪ ﻛـﺴﻲ از اﻳـﻦ ﻛـﻼس ﺷـﻴﺊ را اﻳﺠـﺎد ﻛﻨـﺪ .ﺑﻠﻜـﻪ ﻛـﻼس ﻫـﺎﻳﻲ ﻣﺎﻧﻨـﺪ RadioButton ،Commandو … را از اﻳﻦ ﻛﻼس ﻣﺸﺘﻖ ﻛﻨﻴﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻛـﻼس Buttonﺧـﻮد ﺑﺎﻳـﺪ ﻳـﻚ ﻛـﻼس abstractﺑﺎﺷﺪ ﻛﻪ از ﻛﻼس abstractدﻳﮕﺮي ﺑﻪ ﻧﺎم windowﻣﺸﺘﻖ ﻣﻲ ﺷـﻮد )ﺷـﻜﻞ .(9-10در اﻳـﻦ ﺣﺎﻟـﺖ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﻣﺘﺪﻫﺎي abstractﻛﻼس ﭘﺎﻳﻪ را در ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه overrideﻛﻨﻴﺪ و ﻣﻲ ﺗﻮاﻧﻴﺪ از ﭘﻴـﺎده ﺳـﺎزي ﻣﺘﺪ DrawWindowدر ﻛﻼس Buttonﺻﺮﻓﻨﻈﺮ ﻛﻨﻴﺪ.
٤٠٠
ﺷﻜﻞ 9-10
ﻛﻼﺳﻬﺎي :sealed در ﻗﺴﻤﺖ ﻗﺒﻞ ﺑﺎ ﻛﻼﺳﻬﺎي abstractآﺷﻨﺎ ﺷﺪﻳﺪ و ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻛﻼس ﻫﺎﻳﻲ داﺷﺖ ﻛﻪ ﻓﻘﻂ ﺑﻪ ﻋﻨﻮان ﻛﻼس ﭘﺎﻳﻪ اﺳﺘﻔﺎده ﺷﻮﻧﺪ و ﻧﺘﻮان ﺷﻴﺊ اي از آﻧﻬﺎ ﻧﻤﻮﻧﻪ ﺳﺎزي ﻛﺮد. ﻛﻼﺳﻬﺎي sealedدﻗﻴﻘﺎً ﻣﻔﻬﻮﻣﻲ ﻋﻜﺲ ﻛﻼﺳﻬﺎي abstractدارﻧﺪ .ﺑﻪ ﻋﺒـﺎرت دﻳﮕـﺮ ﻛﻼﺳـﻬﺎي sealedﻛـﻼس ﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﻧﻤﻲ ﺗﻮان آﻧﻬﺎ را ﺑﻪ ﻋﻨﻮان ﻛﻼس ﭘﺎﻳﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار داد و از آﻧﻬﺎ ﻛﻼس ﺟﺪﻳﺪي را ﻣﺸﺘﻖ ﻛﺮد ،ﺑﻠﻜﻪ ﻓﻘـﻂ ﻣـﻲ ﺗﻮان از آﻧﻬﺎ ﺑﺮاي ﻧﻤﻮﻧﻪ ﺳﺎزي اﺷﻴﺎ اﺳﺘﻔﺎده ﻛﺮد .ﺑﺮاي ﺗﻌﺮﻳﻒ ﻳﻚ ﻛﻼس sealedﺑﺎﻳﺪ از ﻛﻠﻤﻪ ي ﻛﻠﻴـﺪي sealedﻗﺒـﻞ از ﺗﻌﺮﻳﻒ ﻛﻼس ﻫﻤﺎﻧﻨﺪ ﻛﺪ زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. public sealed class SealedClass { // Implementation here ... }
Interfaceﻫﺎ: ﺑﻪ ﺑﻴﺎن ﺳﺎده ﻣـﻲ ﺗـﻮاﻧﻢ ﺑﮕـﻮﻳﻢ ﻛـﻪ interfaceﻳـﻚ ﻗـﺮارداد در ﻧـﻮع رﻓﺘـﺎر ﻳـﻚ ﻛـﻼس اﺳـﺖ .ﻫـﺮ ﻛﻼﺳـﻲ ﻛـﻪ ﻳـﻚ interfaceرا ﺑــﻪ ﻛــﺎر ﺑﺒــﺮد ،در ﺣﻘﻴﻘــﺖ ﺗــﻀﻤﻴﻦ ﻣــﻲ ﻛﻨــﺪ ﭘﻴــﺎده ﺳــﺎزي ﺗﻤــﺎم ﻣﺘــﺪ ﻫــﺎ ،ﺧﺎﺻــﻴﺖ ﻫــﺎ و ...ﻛــﻪ در آن interfaceوﺟﻮد دارد را در ﺧﻮد اﻳﺠﺎد ﻛﻨﺪ. ﻓﺮض ﻛﻨﻴﺪ در ﺣﺎل ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ اي ﺑﺮاي ﻛﻨﺘﺮل اﻣﻮر داﺧﻠﻲ ﻳﻚ ﺷﺮﻛﺖ ﻫﺴﺘﻴﺪ .در ﻧﻮﺷﺘﻦ ﭼﻨﻴﻦ ﺑﺮﻧﺎﻣﻪ اي ﻣﺴﻠﻤﺎً ﺑﺎﻳﺪ از ﻛﻼﺳـﻬﺎي زﻳﺎدي اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﺑﺮاي ﻣﺜﺎل ﻳﻚ ﻛﻼس ﺑﺮاي ﻛﻨﺘﺮل اﻣﻮر ﻣﺎﻟﻲ ﺷﺮﻛﺖ ﺑﻪ ﻧـﺎم ،Financialﻛﻼﺳـﻲ ﺑـﺮاي ﻛﻨﺘـﺮل اﻣـﻮر ﻛﺎرﻣﻨﺪان ﺷﺮﻛﺖ ﺑﻪ ﻧﺎم ،Employeesﻛﻼﺳﻲ ﺑﺮاي ﻛﻨﺘﺮل اﻣﻮر ﭼـﺎپ در ﺑﺮﻧﺎﻣـﻪ ﺑـﻪ ﻧـﺎم Printو ...ﺣـﺎل ﻣﻤﻜـﻦ اﺳـﺖ ﺑﺨﻮاﻫﻴﺪ ﻣﺘﺪي در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﻨﻴﺪ ﺗﺎ اﻃﻼﻋﺎت ﻣﻬﻤﻲ ﻛﻪ در ﺑﻌﻀﻲ از ﻛﻼﺳﻬﺎ ﻗﺮار دارﻧﺪ را در دﻳﺴﻚ ذﺧﻴﺮه ﻛﻨﺪ .ﺧﻮب ،واﺿﺢ اﺳـﺖ ﻛﻪ ﻛﻼﺳﻲ ﻣﺜﻞ ﻛﻼس Printاﻃﻼﻋﺎﺗﻲ ﺑﺮاي ذﺧﻴﺮه ﺷﺪن در دﻳﺴﻚ ﻧﺪارد ،اﻣﺎ ﻛﻼﺳﻲ ﻣﺎﻧﻨﺪ ﻛـﻼس Financialو ﻳـﺎ ﻛﻼس Employeesداراي اﻃﻼﻋﺎت ﻣﻬﻤﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﺎﻳﺪ ذﺧﻴﺮه ﺷﻮﻧﺪ ﺗﺎ در ﺻـﻮرت از دﺳـﺖ رﻓـﺘﻦ آﻧﻬـﺎ در ﺑﺮﻧﺎﻣـﻪ ،ﺑﺘـﻮان اﻃﻼﻋﺎت را ﺑﺎزﻳﺎﺑﻲ ﻛﺮد .ﺳﻮاﻟﻲ ﻛﻪ در اﻳﻨﺠﺎ ﭘﻴﺶ ﻣﻲ آﻳﺪ اﻳﻦ اﺳﺖ ﻛﻪ اﻳﻦ ﻣﺘﺪ را ﺑﺎﻳﺪ ﭼﮕﻮﻧﻪ ﻧﻮﺷﺖ ﺗﺎ ﺑﺘﻮاﻧﺪ اﻳﻦ ﻛﺎر را اﻧﺠﺎم دﻫﺪ؟ ٤٠١
ﻳﻚ روش اﻳﻦ اﺳﺖ ﻛﻪ در ﺧﺎرج از ﺗﻌﺮﻳﻒ ﻛﻼﺳﻬﺎ ،ﺑﺎزاي ﻫﺮ ﻛﻼﺳﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ اﻃﻼﻋﺎﺗﺶ در دﻳﺴﻚ ذﺧﻴﺮه ﺷﻮد ﻳﻚ ﻧـﺴﺨﻪ از ﻣﺘﺪ را اﻳﺠﺎد ﻛﻨﻴﻢ .ﺑﺮاي ﻣﺜﺎل ﻳﻚ ﻣﺘﺪ ﺑﺎ ﻧﺎم Saveاﻳﺠـﺎد ﻛﻨـﻴﻢ ﻛـﻪ ﭘـﺎراﻣﺘﺮي از ﻧـﻮع Financialدرﻳﺎﻓـﺖ ﻛﻨـﺪ ﺳـﭙﺲ اﻃﻼﻋﺎت ﻣﻬﻢ ﺷﻴﺊ اي ﻛﻪ ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد را در دﻳﺴﻚ ذﺧﻴﺮه ﻛﻨﻴﻢ .1ﻫﻤﭽﻨﻴﻦ ﻣﺘﺪ Saveرا ﺳﺮﺑﺎر ﮔـﺬاري ﻛـﺮده ﺗـﺎ ﭘﺎراﻣﺘﺮي از ﻛﻼس Employeesدرﻳﺎﻓﺖ ﻛﻨﺪ و ﭘﻴﺎده ﺳﺎزي آن را ﻧﻴـﺰ ﺑـﻪ ﮔﻮﻧـﻪ اي ﺗﻐﻴﻴـﺮ دﻫـﻴﻢ ﺗـﺎ اﻃﻼﻋـﺎت ﻣﻬـﻢ اﺷـﻴﺎي Employeesرا ذﺧﻴﺮه ﻛﻨﺪ و ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴﺐ اﻳﻦ ﻛﺎر را ﺑﺮاي ﺗﻤﺎم ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺧـﻮاﻫﻴﻢ اﻃﻼﻋـﺎت ﺷـﺎن در دﻳـﺴﻚ ذﺧﻴﺮه ﺷﻮد ﺗﻜﺮار ﻛﻨﻴﻢ. اﻣﺎ اﻳﻦ ﻛﺎر ﻣﻨﻄﻘﻲ ﺑﻪ ﻧﻈﺮ ﻧﻤﻲ رﺳﺪ ،زﻳﺮا ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺗﻌﺪاد زﻳﺎدي ﻣﺘﺪ ﺑﻪ ﻧﺎم Saveﻛﻪ ﻫﺮ ﻛﺪام داراي ﭘﻴﺎده ﺳﺎزي ﻣﺨﺼﻮص ﺑﻪ ﺧﻮد ﻫﺴﺘﻨﺪ در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﺧﻮاﻫﺪ ﺷﺪ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﻧﮕﻬﺪاري و ﻓﻬﻢ ﺑﺮﻧﺎﻣﻪ را ﻣﺸﻜﻞ ﻛﻨﺪ. ﻳﻚ روش ﺑﻬﺘﺮ اﻳﻦ اﺳﺖ ﻛﻪ در داﺧﻞ ﻫﺮ ﻛﻼس ﻣﺘﺪي ﺑﻪ ﻧﺎم RetrieveDataاﻳﺠﺎد ﻛﻨﻴﻢ ﺗﺎ اﻃﻼﻋﺎت ﻣﻬﻢ ﻣﺮﺑﻮط ﺑـﻪ آن ﻛﻼس را ﻛﻪ ﺑﺎﻳﺪ ذﺧﻴﺮه ﺷﻮﻧﺪ در ﻗﺎﻟﺐ رﺷﺘﻪ ﺑﺮﮔﺮداﻧﺪ ،ﺳﭙﺲ ﻣﺘﺪ Saveرا در ﺧﺎرج از ﻫﻤﻪ ي ﻛﻼﺳﻬﺎ ،ﺑـﻪ ﮔﻮﻧـﻪ اي ﺑﻨﻮﻳـﺴﻴﻢ ﺗـﺎ ﺑﺘﻮاﻧﺪ ﻫﺮ ﺷﻴﺊ اي ﻛﻪ داراي ﻣﺘﺪ RetrieveDataﺑﺎﺷﺪ را درﻳﺎﻓﺖ ﻛﻨﺪ و اﻃﻼﻋﺎت ﺑﺮﮔﺸﺘﻲ از اﻳﻦ ﻣﺘﺪ را در دﻳـﺴﻚ ذﺧﻴـﺮه ﻛﻨﺪ .ﺳﭙﺲ ﻫﻨﮕﺎم اﺳﺘﻔﺎده ﻛﺎﻓﻲ اﺳﺖ ﺗﻚ ﺗﻚ اﺷﻴﺎﻳﻲ ﻛﻪ داراي ﻣﺘﺪ RetrieveDataﻫﺴﺘﻨﺪ را ﺑﻪ ﻋﻨﻮان ﭘـﺎراﻣﺘﺮ ﺑـﻪ ﻣﺘـﺪ Saveﻓﺮﺳﺘﺎده ﺗﺎ اﻃﻼﻋﺎت ﺷﺎن در دﻳﺴﻚ ذﺧﻴﺮه ﺷﻮد .اﻣﺎ ﺳﻮال اﻳﻨﺠﺎﺳﺖ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﻪ ﻣﺘﺪ Saveﺑﮕﻮﻳﻴﻢ ﻛﻪ "ﻓﻘﻂ اﺷﻴﺎﻳﻲ را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻛﻦ ﻛﻪ داراي ﻣﺘﺪ RetrieveDataﻫﺴﺘﻨﺪ".؟ در ﻓﺼﻞ ﻧﻬﻢ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ اﮔﺮ ﻳﻚ ﻣﺘﺪ ،ﺑﻪ ﭘﺎراﻣﺘﺮي از ﻧﻮع ﻳﻚ ﻛﻼس ﭘﺎﻳﻪ )ﻣﺎﻧﻨﺪ (Carﻧﻴﺎز داﺷﺖ ،اﺷﻴﺎﻳﻲ ﻛﻪ از ﻛﻼﺳـﻬﺎي ﻣﺸﺘﻖ ﺷﺪه از آن ﻛﻼس ﻧﻤﻮﻧﻪ ﺳﺎزي ﻣﻲ ﺷﺪﻧﺪ ﻧﻴﺰ )ﻫﻤﺎﻧﻨﺪ اﺷﻴﺎي ﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﺪه از ﻛﻼس (SportsCarﻣﻲ ﺗﻮاﻧﺴﺘﻨﺪ ﺑـﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ آن ﻓﺮﺳﺘﺎده ﺷﻮﻧﺪ .اﻳﻦ ﻣﻮرد ﺑﻪ اﻳﻦ ﻋﻠﺖ اﻣﻜﺎن ﭘﺬﻳﺮ ﺑﻮد ﻛﻪ ﻛﻼس ﭘﺎﻳﻪ ﺗﻀﻤﻴﻦ ﻣﻲ ﻛﺮد ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه ﺗﻤﺎم ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي ﻣﻮرد ﻧﻴﺎز را داﺷﺘﻪ ﺑﺎﺷﺪ .اﻣﺎ ﻣﺸﺨﺺ اﺳﺖ ﻛﻪ در ﻣﺘﺪ Saveﻧﻤﻲ ﺗﻮاﻧﻴﻢ از اﻳﻦ روش اﺳﺘﻔﺎده ﻛﻨﻴﻢ ،زﻳﺮا در اﻳـﻦ ﺑﺮﻧﺎﻣﻪ ﻛﻼﺳﻬﺎي ﻣﺨﺘﻠﻔﻲ وﺟﻮد دارﻧﺪ ﻛﻪ وﻇﺎﻳﻒ ﮔﻮﻧﺎﮔﻮﻧﻲ را اﻧﺠﺎم ﻣﻲ دﻫﻨﺪ و ﻧﻤﻲ ﺗﻮان ﻳﻚ ﻛﻼس ﭘﺎﻳﻪ ﺑﺮاي ﻫﻤـﻪ آﻧﻬـﺎ ﻣـﺸﺨﺺ ﻛﺮد ﺗﺎ ﻣﺘﺪ Saveرا در آن ﻛﻼس ﭘﺎﻳـﻪ ﻗـﺮار دﻫـﻴﻢ .ﺑـﺮاي ﻣﺜـﺎل ﻛـﻼس Financialﻣﻤﻜـﻦ اﺳـﺖ از ﻛﻼﺳـﻲ ﺑـﻪ ﻧـﺎم FinanBaseﻣﺸﺘﻖ ﺷﻮد ،اﻣﺎ ﻛﻼس Employeesﻣﻤﻜﻦ اﺳﺖ از ﻛﻼس EmpBaseﻣﺸﺘﻖ ﺷﻮد و ﻳﺎ ﺣﺘﻲ اﺻﻼً از ﻫﻴﭻ ﻛﻼﺳﻲ ﻣﺸﺘﻖ ﻧﺸﻮد. در اﻳﻦ ﮔﻮﻧﻪ ﻣـﻮارد ﺑﻬﺘـﺮﻳﻦ راه ،اﺳـﺘﻔﺎده از Interfaceﻫـﺎ اﺳـﺖ .ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ ﮔﻔـﺘﻢ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻳـﻚ ﻛـﻼس از ﻳـﻚ interfaceاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ ،در ﺣﻘﻴﻘﺖ ﺗﻀﻤﻴﻦ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﺗﻤﺎم ﻣﺘﺪ ﻫـﺎ ،ﺧﺎﺻـﻴﺖ ﻫـﺎ و ...ﻛـﻪ در آن interface ﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ را در ﺧﻮد ﭘﻴﺎده ﺳﺎزي ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﺘﺪ ) RetrieveDataو ﻫﺮ ﻣﺘﺪ و ﻳﺎ ﺧﺎﺻﻴﺖ دﻳﮕـﺮي ﻛـﻪ ﻣﻤﻜﻦ اﺳﺖ ﺑﺮاي ذﺧﻴﺮه ﺳﺎزي در دﻳﺴﻚ ﻣﻮرد ﻧﻴﺎز ﺑﺎﺷﺪ( را در ﻳـﻚ Interfaceﺑـﻪ ﻧـﺎم 2IStorableﻗـﺮار دﻫﻴـﺪ، ﺳﭙﺲ ﻫﺮ ﻛﻼﺳﻲ ﻛﻪ ﺑﺨﻮاﻫﺪ ﻗﺎﺑﻠﻴﺖ ذﺧﻴﺮه ﺷﺪن در دﻳﺴﻚ را داﺷﺘﻪ ﺑﺎﺷﺪ ﺑﺎﻳﺪ از اﻳﻦ Interfaceاﺳﺘﻔﺎده ﻛﻨﺪ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در ﺑﺎﻻ ﺗﻮﺿﻴﺢ داده ﺷﺪ را ﺑﻪ ﺻﻮرﺗﻲ ﺳﺎده اﻧﺠﺎم دﻫﻴﻢ ﺗﺎ ﺑﺎ ﻧﺤـﻮه اﺳـﺘﻔﺎده از Interfaceﻫﺎ در ﺑﺮﻧﺎﻣﻪ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺷﻮﻳﺪ .اﻟﺒﺘﻪ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در زﻳﺮ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﻛﺎﻣﻼً ﺧﻼﺻﻪ ﺷﺪه اﺳﺖ ،ﺑـﺮاي ﻣﺜـﺎل در ﻛﻼس Financialﻓﻘﻂ از دو ﻓﻴﻠﺪ ﺑﺮاي ﻧﮕﻬﺪاري درآﻣﺪﻫﺎ و ﻫﺰﻳﻨﻪ ﻫﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .در ﻛﻼس Employeesﻧﻴـﺰ ﻓﺮض ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻓﻘﻂ ﺑﻪ ذﺧﻴﺮه ﻛﺮدن اﻃﻼﻋﺎت ﻣﺨﺘﺼﺮي از ﻳﻚ ﻛﺎرﻣﻨﺪ ﻧﻴﺎز دارﻳﻢ .اﻣﺎ ﻣﺴﻠﻤﺎً در ﻳﻚ ﺑﺮﻧﺎﻣـﻪ واﻗﻌـﻲ اﻳـﻦ ﻛﻼﺳـﻬﺎ ﺑﺴﻴﺎر ﺑﺰرﮔﺘﺮ ﻫﺴﺘﻨﺪ و ﺟﺰﺋﻴﺎت ﺑﻴﺸﺘﺮي را ﺷﺎﻣﻞ ﻣﻲ ﺷﻮﻧﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از Interfaceﻫﺎ در ﺑﺮﻧﺎﻣﻪ
1ﺑﺎ ﻓﺮض اﻳﻦ ﻛﻪ ﺗﻤﺎم ﺧﺎﺻﻴﺖ ﻫﺎ و ﻓﻴﻠﺪﻫﺎﻳﻲ ﻛﻪ ﺑﺎﻳﺪ در دﻳﺴﻚ ذﺧﻴﺮه ﺷﻮﻧﺪ ﺑﻪ ﺻﻮرت publicﺗﻌﺮﻳﻒ ﺷﺪه ﺑﺎﺷﻨﺪ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﺑﻪ آﻧﻬﺎ دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﻴﻢ. 2ﻣﻌﻤﻮﻻ ﻧﺎم Interfaceﻫﺎ ﺑﺎ ﻳﻚ ﺣﺮف Iﺑﺰرگ ﺷﺮوع ﻣﻲ ﺷﻮد ﺗﺎ ﺑﻪ راﺣﺘﻲ ﻗﺎﺑﻞ ﺗﺸﺨﻴﺺ ﺑﺎﺷﻨﺪ.
٤٠٢
ﭘـﺮوژه ﺟﺪﻳـﺪي، در ﻧﻮار ﻣﻨﻮي وﻳـﮋوال اﺳـﺘﻮدﻳﻮFile New Project… ( ﺑﺎ اﺳﺘﻔﺎده از ﮔﺰﻳﻨﻪ ي1 . ﻗﺮار دﻫﻴﺪInterface Demo اﻳﺠﺎد ﻛﺮده و ﻧﺎم آن را ﺑﺮاﺑﺮ ﺑﺎ روي ﻧﺎم ﭘﺮوژه ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨـﻪ،Solution Explorer ( ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي2 Add New Item – Interface را اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ ﺗـﺎ ﭘﻨﺠـﺮه يAdd Class… ي را ﺑﺮاي ﻛﻼس اﻧﺘﺨـﺎب ﻛـﺮده و روي دﻛﻤـﻪ يFinancial.cs ﻧﺎمName ﺳﭙﺲ در ﻛﺎدر. ﺑﺎز ﺷﻮدDemo . اﻳﺠﺎد ﺷﻮدFinancial ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻛﻼسOK از ﻛﻠﻤـﻪ ي ﻛﻠﻴـﺪيInterface ﺑﺮاي اﻳﺠﺎد ﻳـﻚ. ﻣﻮرد ﻧﻴﺎز در ﺑﺮﻧﺎﻣﻪ را اﻳﺠﺎد ﻛﻨﻴﻢInterface ( اﺑﺘﺪا ﺑﺎﻳﺪ3 ﻗﺒﻞ از ﺗﻌﺮﻳﻒ ﻛﻼس،Interface_Demo ﻛﺪ زﻳﺮ را در داﺧﻞ ﻓﻀﺎي ﻧﺎم. اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪinterface ﻗﺮار دﻫﻴﺪFinancial namespace Interface_Demo { // Define functions and properties needed for // an object to be storable public interface IStorable { // A method for retrieving important data string RetrieveData(); // A property to set the path for saving data string SavePath { get; set; } } class Financial { ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳـﺮ را ﺑـﻪ. را ﺗﻌﺮﻳﻒ ﻛﻨﻴﻢFinancial ( ﺣﺎل ﺑﺎﻳﺪ ﻓﻴﻠﺪ ﻫﺎي ﻣﻮرد ﻧﻴﺎز در ﻛﻼس4 : اﺿﺎﻓﻪ ﻛﻨﻴﺪFinancial داﺧﻞ ﻛﻼس class Financial { // Define some fields in class to store data public string _savePath = @"C:\FinancialBackup.dat"; public long Expenditures; public long Earnings;
٤٠٣
(5ﺑﺮاي ﺗﻨﻈﻴﻢ ﻣﻘﺎدﻳﺮ اوﻟﻴﻪ ﻓﻴﻠﺪ ﻫﺎي Expenditureو Earningsﻣﻲ ﺗﻮاﻧﻴﻢ ﻳﻚ ﻣﺘـﺪ ﺳـﺎزﻧﺪه ﺑـﻪ ﻛـﻼس اﺿﺎﻓﻪ ﻛﻨﻴﻢ .اﻣﺎ ﺑﻬﺘﺮ اﺳﺖ ﺑﻪ ﺟﺎي اﻳﻨﻜﻪ ﻣﻘﺪارﻫﺎي ﭘﻴﺶ ﻓﺮﺿﻲ را ﺑﻪ اﻳﻦ دو ﻓﻴﻠﺪ اﺧﺘﺼﺎص دﻫﻴﻢ ،ﻣﻘﺪار آﻧﻬﺎ را ﺑﻪ ﺻـﻮرت ﭘﺎراﻣﺘﺮﻫﺎي ﻣﺘﺪ ﺳﺎزﻧﺪه از ﻛﺎرﺑﺮ درﻳﺎﻓﺖ ﻛﻨﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﺘﺪ ﺳﺎزﻧﺪه اي ﻫﻤﺎﻧﻨﺪ زﻳﺮ در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﻨﻴﺪ: // Class Constructor that takes two arguments )public Financial(long expend, long earn { ;this.Expenditures = expend ;this.Earnings = earn } (6ﺣﺎل ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ ﻛﻼس Financialاز اﻳﻨﺘﺮﻓﻴﺲ IStorableاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ .ﺑﺮاي اﻳـﻦ ﻛـﺎر ﺑﺎﻳﺪ ﻫﻤﺎﻧﻨﺪ ﻣﺸﺨﺺ ﻛﺮدن ﻳﻚ ﻛﻼس ﭘﺎﻳﻪ ﺑﺮاي ﻳﻚ ﻛﻼس ﻋﻤﻞ ﻛﻨﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻌﺮﻳﻒ ﻛﻼس Financialرا ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ: class Financial : IStorable { (7ﺣﺎل ﻛﻪ ﻣﺸﺨﺺ ﻛﺮدﻳﻢ اﻳﻦ ﻛﻼس از اﻳﻨﺘﺮﻓﻴﺲ IStorableاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ ،ﺑﺎﻳﺪ ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ Interfaceﻣﺸﺨﺺ ﺷﺪه اﺳﺖ را در ﻛﻼس اﻳﺠﺎد ﻛﻨﻴﻢ .در اﻳﻨﺘﺮﻓﻴﺲ IStorableﻳـﻚ ﻣﺘـﺪ و ﻳـﻚ ﺧﺎﺻﻴﺖ وﺟﻮد دارد .اﺑﺘﺪا از ﻣﺘﺪ RetrieveDataﺷﺮوع ﻣﻲ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺪ زﻳﺮ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ. دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﺗﻌﺮﻳﻒ اﻳﻦ ﻣﺘﺪ دﻗﻴﻘﺎً ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺗﻌﺮﻳﻔﻲ ﺑﺎﺷﺪ ﻛﻪ در داﺧﻞ Interfaceﻣﺸﺨﺺ ﺷﺪه اﺳﺖ. // Implementation of RetrieveData method // in IStorable interface )(public string RetrieveData { ;string result ;result = "Expenditure = " + this.Expenditures ;result += " Earnings = " + this.Earnings ;return result } (8ﺑﻌﺪ از اﻳﺠﺎد ﻣﺘﺪ ﻣﺸﺨﺺ ﺷﺪه ،ﺑﺎﻳﺪ ﺧﺎﺻﻴﺘﻲ ﻛﻪ در Interfaceﺗﻌﻴﻴﻦ ﺷﺪه اﺳﺖ را ﻧﻴـﺰ در داﺧـﻞ ﻛـﻼس اﻳﺠـﺎد ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺪ زﻳﺮ را ﻧﻴﺰ ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ: // Implementation of SavePath property // in IStorable interface public string SavePath { get { ;return _savePath
٤٠٤
} set { ;_savePath = value } } (9ﺑﻌﺪ از اﺗﻤﺎم ﻛﻼس ،Financialﻛﻼس Employeesرا آﻏﺎز ﻣﻲ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠـﺮه ي ،Solution Explorerروي ﻧﺎم ﭘﺮوژه ﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨـﻪ ي Add … Classرا اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ .ﺳـﭙﺲ ﺑـﺎ اﺳـﺘﻔﺎده از ﭘﻨﺠـﺮه ي ،Add New Itemﻛـﻼس ﺟﺪﻳـﺪي ﺑـﻪ ﻧـﺎم Employeesﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ. (10ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﻓﻘﻂ ﻧﺤﻮه اﺳﺘﻔﺎده از Interfaceﻫﺎ ﻣﺪ ﻧﻈﺮ ﻣﺎﺳﺖ ،ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻼﺳﻬﺎي ﺑﺮﻧﺎﻣﻪ را ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﺳﺎده اﻳﺠﺎد ﻛﻨﻴﻢ.ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ ﺑﺮاي اﻳﻦ ﻛﻼس ﻓﻘﻂ دو ﻓﻴﻠﺪ ﺑﺮاي ﻧﮕﻬﺪاري اﻃﻼﻋﺎت ﻳﻚ ﻛﺎرﻣﻨﺪ ،ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه ﺑﺮاي ﺗﻨﻈﻴﻢ ﻣﻘﺪار اوﻟﻴﻪ اﻳﻦ دو ﻓﻴﻠﺪ و ﻳﻚ ﻓﻴﻠﺪ ﻧﻴﺰ ﺑﺮاي ﻧﮕﻬﺪاري آدرس ﻓﺎﻳﻠﻲ ﻛﻪ ﺑﺎﻳﺪ ﺑﺮاي ذﺧﻴﺮه اﻃﻼﻋﺎت اﺳﺘﻔﺎده ﺷﻮد اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺪ زﻳﺮ را ﺑﻪ ﻛﻼس Employeesاﺿﺎﻓﻪ ﻛﻨﻴﺪ: ;"public string _savePath = @"C:\EmployeesBackup.dat ;public long EmployeeID ;public string EmployeeName )public Employees(int ID, string Name { ;this.EmployeeID = ID ;this.EmployeeName = Name } (11ﻫﻤﺎﻧﻨﺪ ﻛﻼس ،Financialاﻳﻦ ﻛﻼس ﻧﻴﺰ ﻧﻴﺎز دارد ﻛﻪ اﻃﻼﻋﺎت ﺧﻮد را در دﻳﺴﻚ ذﺧﻴـﺮه ﻛﻨـﺪ .ﭘـﺲ اﻳﻨﺘـﺮﻓﻴﺲ IStorableرا ﺑﺮاي اﻳﻦ ﻛﻼس ﻧﻴﺰ ﺑﺎﻳﺪ ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺗﻌﺮﻳﻒ ﻛﻼس را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ: namespace Interface_Demo { class Employees : IStorable { (12اﮔﺮ ﺑﺮاي ﭼﻨﺪ ﻟﺤﻈﻪ ،اﺷﺎره ﮔﺮ ﻣﺎوس را ﺑﺮ روي ﻧﺎم اﻳﻨﺘﺮﻓﻴﺲ ﻗﺮار دﻫﻴﺪ ،ﻛﺎدر ﻛﻮﭼﻜﻲ ﻫﻤﺎﻧﻨﺪ ﺷـﻜﻞ 10-10ﻧﻤـﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ .ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ ﻛﺎدر ﻣﻲ ﺗﻮاﻧﻴﺪ از وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺨﻮاﻫﻴﺪ ﻛﻪ ﺗﻌﺮﻳﻒ ﺗﻤﺎم ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي اﻳﻦ اﻳﻨﺘـﺮﻓﻴﺲ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ اﺿﺎﻓﻪ ﻛﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻓﻘﻂ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﭘﻴﺎده ﺳﺎزي ﻣﻮرد ﻧﻈﺮﺗﺎن را در ﻣﺘﺪ ﻫـﺎ و ﺧﺎﺻـﻴﺖ ﻫـﺎي ﻣﺮﺑــﻮط ﻗــﺮار دﻫﻴــﺪ .ﺑــﺮاي اﻳــﻦ ﻛــﺎر در ﻛــﺎدري ﻛــﻪ در ﺷــﻜﻞ 10-10ﻧﻴــﺰ ﻧﻤــﺎﻳﺶ داده ﺷــﺪه اﺳــﺖ ،روي ﮔﺰﻳﻨــﻪ ي ' Implement interface 'IStorableﻛﻠﻴﻚ ﻛﻨﻴﺪ.
٤٠٥
10-10 ﺷﻜﻞ ﺑﻪ ﻛﻼسIStorable ﺗﻤﺎم ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي ﻣﻮﺟﻮد در اﻳﻨﺘﺮﻓﻴﺲ،( ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﺑﺎ اﻧﺘﺨﺎب اﻳﻦ ﮔﺰﻳﻨﻪ13 : در ﺗﻤﺎم اﻳﻦ ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎ ﻛﺪي ﻣﺸﺎﺑﻪ زﻳﺮ ﻗﺮار دارد.اﺿﺎﻓﻪ ﻣﻲ ﺷﻮﻧﺪ throw new Exception( "The method or operation is not implemented."); : را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪRetrieveData ( ﻛﺪ ﻣﻮﺟﻮد در ﻣﺘﺪ14 public string RetrieveData() { // Define a variable to store results string result; // Produce the result result = "Employee ID: " + this.EmployeeID; result += " Employee Name: " + this.EmployeeName; return result; } : را ﻧﻴﺰ ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪSavePath ﺧﺎﺻﻴﺖset وget ( ﻛﺪ درون ﺑﺨﺸﻬﺎي15 public string SavePath { get { return _savePath; } set { _savePath = value; } } ﺑـﺎ اﺳـﺘﻔﺎده از. ﺣﺎل ﺑﺎﻳﺪ ﻛﺪي ﺑﺮاي ﺗﺴﺖ ﻛﺮدن ﺑﺮﻧﺎﻣﻪ ﺑﻨﻮﻳﺴﻴﻢ،( ﺗﺎ اﻳﻨﺠﺎ ﻛﻼس ﻫﺎي ﻣﻮرد ﻧﻴﺎز در ﺑﺮﻧﺎﻣﻪ را اﻳﺠﺎد ﻛﺮده اﻳﻢ16 Main را ﺑﺎز ﻛـﺮده و ﻛـﺪ زﻳـﺮ را ﺑـﻪ ﻣﺘـﺪProgram.cs ﻓﺎﻳﻞSolution Explorer ﭘﻨﺠﺮه ي
٤٠٦
ﻣﻲ ﺗﻮاﻧﻴﺪ از اﻳـﻦ. ﺗﻌﺮﻳﻒ ﻧﺸﺪه اﺳﺖSave ﻫﻨﮕﺎم اﺿﺎﻓﻪ ﻛﺮدن ﻛﺪ ﺑﺎ ﭘﻴﻐﺎم ﺧﻄﺎﻳﻲ ﻣﻮاﺟﻪ ﻣﻲ ﺷﻮﻳﺪ ﻛﻪ ﻣﺘﺪ.اﺿﺎﻓﻪ ﻛﻨﻴﺪ . زﻳﺮا اﻳﻦ ﻣﺘﺪ را در ﻣﺮﺣﻠﻪ ﺑﻌﺪ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد،ﭘﻴﻐﺎم ﺻﺮﻓﻨﻈﺮ ﻛﻨﻴﺪ static void Main(string[] args) { // Instantiating the needed variables Financial finan = new Financial(264399, 368547); Employees emp = new Employees(1, "John Smith"); // Writing information about created objects Console.WriteLine("A Financial object created!"); Console.WriteLine("Expenditure: " + finan.Expenditures); Console.WriteLine("Earning: " + finan.Earnings); Console.WriteLine("An Employees object created!"); Console.WriteLine("Employee ID: " + emp.EmployeeID); Console.WriteLine("Employee Name: " + emp.EmployeeName); Console.WriteLine("Press any key to save data" + " on disk."); Console.Read(); Save(finan); Console.WriteLine("Financial information saved at: " + finan.SavePath); Save(emp); Console.WriteLine("Employees information saved at: " + emp.SavePath); Console.Read(); } ﭘﺲ ﺑـﺎ اﺳـﺘﻔﺎده از، ﻧﻴﺎز دارﻳﻢSystem.IO در ﻓﻀﺎي ﻧﺎمFile ﺑﻪ اﺳﺘﻔﺎده از ﻛﻼسSave ( ﺑﺮاي ﻧﻮﺷﺘﻦ ﻣﺘﺪ17 :راﻫﻨﻤﺎي زﻳﺮ اﻳﻦ ﻓﻀﺎي ﻧﺎم را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ using System.IO; :( ﻣﺘﺪ زﻳﺮ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ ﻗﺴﻤﺖ ﺗﺴﺖ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﺗﻜﻤﻴﻞ ﺷﻮد18 static void Save(IStorable obj) { // Define a variable to store important data string data;
٤٠٧
// Retrieving important data to save on disk ;)(data = obj.RetrieveData // Saving retrieved data on disk ;)File.WriteAllText(obj.SavePath, data } (19ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﭘﻨﺠﺮه اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 11-10ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ اﻃﻼﻋﺎت اﺷﻴﺎي ﺳـﺎﺧﺘﻪ ﺷـﺪه را ﻧﻤـﺎﻳﺶ ﻣﻲ دﻫﺪ.
ﺷﻜﻞ 11-10 (20ﻛﻠﻴﺪي را در ﺑﺮﻧﺎﻣﻪ ﻓﺸﺎر دﻫﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﻃﻼﻋﺎت ﻛﻼﺳﻬﺎ در ﻓﺎﻳﻠﻬﺎي ﻣﺸﺨﺺ ﺷﺪه ذﺧﻴـﺮه ﻣـﻲ ﺷـﻮﻧﺪ .ﺑﺮﻧﺎﻣـﻪ ﻧﻴـﺰ ذﺧﻴﺮه ﺷﺪن اﻳﻦ اﻃﻼﻋﺎت را ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 12-10اﻋﻼم ﻣﻲ ﻛﻨﺪ.
ﺷﻜﻞ 12-10
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ interface ،ﻳﻚ ﻗﺮار داد اﺳﺖ .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﺑﺘﺪا ﻳﻚ اﻳﻨﺘﺮﻓﻴﺲ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ،ﺑﻪ ﺑﻴﺎن دﻳﮕـﺮ ﻗـﺮاردادي اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻫﺮ ﻛﻼﺳﻲ ﻛﻪ ﺑﺨﻮاﻫﺪ اﻃﻼﻋﺎﺗﺶ را در دﻳﺴﻚ ذﺧﻴﺮه ﻛﻨﺪ ﺑﺎﻳﺪ از آن ﻗﺮار داد ﭘﻴﺮوي ﻛﻨﺪ .در اﻳﻦ ﻗـﺮارداد ﻧﻴـﺰ ذﻛـﺮ ﻣﻲ ﻛﻨﻴﻢ ﻫﺮ ﻛﻼﺳﻲ ﻛﻪ ﺑﺨﻮاﻫﺪ اﻃﻼﻋﺎﺗﺶ را در دﻳﺴﻚ ذﺧﻴﺮه ﻛﻨﺪ ﺑﺎﻳﺪ ﺗﺎﺑﻌﻲ ﺑﻪ ﻧﺎم RetrieveDataداﺷﺘﻪ ﺑﺎﺷﺪ ﻛﻪ اﻳـﻦ ﺗﺎﺑﻊ اﻃﻼﻋﺎت ﻣﻬﻢ ﻛﻼس را از ﻧﻮع رﺷﺘﻪ ﺑﺮﮔﺮداﻧﺪ .ﻫﻤﭽﻨﻴﻦ ﻛﻼس ﻣﺬﻛﻮر ﺑﺎﻳـﺪ داراي ﺧﺎﺻـﻴﺘﻲ از ﻧـﻮع ﺧﻮاﻧـﺪﻧﻲ-ﻧﻮﺷـﺘﻨﻲ ﺑـﻪ ﻧـﺎم SavePathﺑﺎﺷﺪ ﻛﻪ ﻣﺴﻴﺮ ذﺧﻴﺮه اﻃﻼﻋﺎت را ﺑﺮﮔﺮداﻧﺪ.
٤٠٨
// Define functions and properties needed for // an object to be storable public interface IStorable { // A method for retrieving important data ;)(string RetrieveData // A property to set the path for saving data string SavePath { ;get ;set } } در ﻃﺮاﺣﻲ ﻳﻚ اﻳﻨﺘﺮﻓﻴﺲ دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻫﻤﺎﻧﻨﺪ ﻛﻼﺳﻬﺎي ،Abstractﻧﺒﺎﻳﺪ ﻫﻴﭻ ﮔﻮﻧـﻪ ﭘﻴـﺎده ﺳـﺎزي اي ﺑـﺮاي ﻣﺘـﺪ ﻫـﺎ و ﻳـﺎ ﺧﺎﺻﻴﺖ ﻫﺎ ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ .ﺑﻠﻜﻪ ﻓﻘﻂ ﻛﺎﻓﻲ اﺳﺖ ﻧﺎم ،ﻧﻮع داده ﺑﺮﮔﺸﺘﻲ و ﻫﻤﭽﻨﻴﻦ ﭘﺎراﻣﺘﺮﻫﺎي آﻧﻬﺎ را ﻣﺸﺨﺺ ﻛﻨﻴﺪ .ﻫﻤﭽﻨﻴﻦ ﻧﺒﺎﻳﺪ ﻫـﻴﭻ ﺳﻄﺢ دﺳﺘﺮﺳﻲ از ﻗﺒﻴﻞ publicو ﻳﺎ privateﺑﺮاي ﻳﻚ اﻳﻨﺘﺮﻓﻴﺲ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ،ﺑﻠﻜﻪ ﺳﻄﺢ دﺳﺘﺮﺳـﻲ ﺗﻤـﺎم ﻣﺘـﺪ ﻫـﺎ و ﺧﺎﺻﻴﺘﻬﺎي آن ﺑﺮاﺑﺮ ﺑﺎ ﺳﻄﺢ دﺳﺘﺮﺳﻲ ﺧﻮد interfaceﻣﻲ ﺑﺎﺷﺪ .ﺑﺮاي ﻣﺜـﺎل در اﻳﻨﺘﺮﻓﻴـﺴﻲ ﻛـﻪ در ﺑﺮﻧﺎﻣـﻪ ي ﻗﺒﻠـﻲ اﻳﺠـﺎد ﻛﺮدﻳﻢ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻫﻴﭻ ﺳﻄﺢ دﺳﺘﺮﺳﻲ اي ﺑﺮاي ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎ ﺗﻌﻴﻴﻦ ﻧﺸﺪه اﺳﺖ ،اﻣﺎ ﺳﻄﺢ دﺳﺘﺮﺳﻲ اﻳﻨﺘﺮﻓﻴﺲ ﺑﺮاﺑـﺮ ﺑﺎ publicﻣﺸﺨﺺ ﺷﺪه اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﺳﻄﺢ دﺳﺘﺮﺳﻲ ﻛﻠﻴﻪ اﻋﻀﺎ ﺑﺮاﺑﺮ ﺑﺎ publicﺧﻮاﻫﺪ ﺑﻮد. ﺣﺎل ﻫﺮ ﻛﻼﺳﻲ ﻛﻪ از اﻳﻨﺘﺮﻓﻴﺲ IStorableاﺳﺘﻔﺎده ﻛﻨـﺪ ﺑـﺮ ﻃﺒـﻖ اﻳـﻦ ﻗـﺮارداد ﻣﻮﻇـﻒ ﺧﻮاﻫـﺪ ﺑـﻮد ﻛـﻪ ﻣﺘـﺪي ﺑـﻪ ﻧـﺎم RetrieveDataاز ﻧﻮع publicداﺷﺘﻪ ﺑﺎﺷﺪ ﻛﻪ ﻫﻴﭻ ﭘﺎراﻣﺘﺮي درﻳﺎﻓـﺖ ﻧﻜﻨـﺪ و ﻫﻤﭽﻨـﻴﻦ ﻳـﻚ stringرا ﺑـﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﮔﺮداﻧﺪ .ﻫﻤﭽﻨﻴﻦ اﻳﻦ ﻛﻼس ﺑﺎﻳﺪ ﻳﻚ ﺧﺎﺻﻴﺖ ﺧﻮاﻧﺪﻧﻲ-ﻧﻮﺷﺘﻨﻲ ﺑﻪ ﻧﺎم SavePathاز ﻧـﻮع publicداﺷـﺘﻪ ﺑﺎﺷﺪ ﻛﻪ ﻳﻚ رﺷﺘﻪ را ﺑﺮﮔﺮداﻧﺪ. ﺗﻌﺮﻳﻒ ﻛﻼس Financialﻛﺎﻣﻼً واﺿﺢ اﺳﺖ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﺑﺮاي اﻳﻨﻜﻪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻓﻘﻂ ﺑﺘﻮاﻧﻴﻢ ﺑﺮ ﻧﺤﻮه ﻛﺎر اﻳﻨﺘﺮﻓﻴﺲ ﻫﺎ ﺗﻤﺮﻛﺰ ﻛﻨﻴﻢ ،ﻛﻼﺳﻬﺎ را ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﺳﺎده ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ .اﻳﻦ ﻛﻼس ﺷﺎﻣﻞ دو ﻓﻴﻠﺪ ﺑﺮاي ﻧﮕﻬﺪاري ﻫﺰﻳﻨـﻪ ﻫـﺎ و ﻣﺨـﺎرج اﺳـﺖ. ﻫﻤﭽﻨﻴﻦ ﺑﻪ ﻓﻴﻠﺪ دﻳﮕﺮي ﻧﻴﺰ در اﻳﻦ ﻛﻼس ﻧﻴﺎز دارﻳﻢ ﺗﺎ ﻣﻜﺎن ذﺧﻴﺮه ﺷﺪن اﻃﻼﻋﺎت ﻛﻼس در دﻳﺴﻚ را در آن ﻧﮕﻬﺪاري ﻛﻨﻴﻢ. // Define some fields in class to store data ;"public string _savePath = @"C:\FinancialBackup.dat ;public long Expenditures ;public long Earnings ﻫﻤﭽﻨﻴﻦ ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه ﺑﺮاي اﻳﻦ ﻛﻼس اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻣﻘﺪار اوﻟﻴﻪ ﻓﻴﻠﺪ ﻫﺎي ﺷﻴﺊ را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺎدﻳﺮ ﻣﻮرد ﻧﻈﺮ ﻛﺎرﺑﺮ ﻗﺮار دﻫﺪ. // Class Constructor that takes two arguments )public Financial(long expend, long earn { ;this.Expenditures = expend ;this.Earnings = earn }
٤٠٩
ﺑﺮاي اﻳﻨﻜﻪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻳﻚ ﻛﻼس از ﻗﺮاردادﻫﺎي ﻳﻚ اﻳﻨﺘﺮﻓﻴﺲ ﺧﺎص ﭘﻴﺮوي ﻣﻲ ﻛﻨﺪ ﺑﺎﻳﺪ ﻧﺎم اﻳﻨﺘـﺮﻓﻴﺲ را ﺑﻌـﺪ از ﻛـﺎراﻛﺘﺮ :در ﻣﻘﺎﺑﻞ ﻧﺎم ﻛﻼس ذﻛﺮ ﻛﻨﻴﻢ ،دﻗﻴﻘﺎً ﻣﺸﺎﺑﻪ ﻣﺸﺨﺺ ﻛﺮدن ﻳﻚ ﻛﻼس ﭘﺎﻳﻪ ﺑﺮاي ﻛﻼس .اﻟﺒﺘﻪ دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ در وراﺛﺖ ﻫﺮ ﻛﻼس ﻓﻘـﻂ ﻣﻲ ﺗﻮاﻧﺴﺖ ﺷﺎﻣﻞ ﻳﻚ ﻛﻼس ﭘﺎﻳﻪ ﺑﺎﺷﺪ ،اﻣﺎ ﻫﺮ ﻛﻼس ﻣﻲ ﺗﻮاﻧﻨﺪ ﭼﻨﺪﻳﻦ اﻳﻨﺘﺮﻓﻴﺲ را در ﺧﻮد ﺑﻪ ﻛﺎر ﺑﺒﺮد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑـﺮ ﺧـﻼف وراﺛﺖ ،ﻳﻚ ﻛﻼس ﻣﻲ ﺗﻮاﻧﻨﺪ از ﻗﻮاﻋﺪ ﭼﻨﺪﻳﻦ اﻳﻨﺘﺮﻓﻴﺲ ﭘﻴﺮوي ﻛﻨﺪ و ﻣﺘﺪﻫﺎي ﺗﻌﻴﻴﻦ ﺷﺪه در آﻧﻬﺎ را در ﺧﻮد اﻳﺠﺎد ﻛﻨـﺪ .ﺑـﺮاي اﻳﻨﻜـﻪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻼس Financialاز اﻳﻨﺘﺮﻓﻴﺲ IStorableاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ ،ﺗﻌﺮﻳﻒ ﻛﻼس را ﺑﻪ ﺻـﻮرت زﻳـﺮ ﺗﻐﻴﻴـﺮ ﻣﻲ دﻫﻴﻢ: class Financial : IStorable { ﺣﺎل ﺑﺎﻳﺪ ﻳﻚ ﻣﺘﺪ ﺑﻪ ﻧﺎم RetrieveDataدر ﻛﻼس اﻳﺠﺎد ﻛﻨﻴﻢ ﻛﻪ اﻃﻼﻋﺎت ﻣﻬﻢ ﻛﻼس را در ﻗﺎﻟﺐ رﺷـﺘﻪ ﺑﺮﮔﺮداﻧـﺪ .اﻳـﻦ ﻣﺘﺪ ﺑﺎﻳﺪ از ﻧﻮع Publicﺑﺎﺷﺪ و ﻫﻤﭽﻨﻴﻦ ﻧﺒﺎﻳﺪ ﭘﺎراﻣﺘﺮي را درﻳﺎﻓﺖ ﻛﻨﺪ ،در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟﻪ ﺧﻮاﻫﻴـﺪ ﺷﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﺘﺪي را ﺑﻪ ﺻﻮرت زﻳﺮ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ: // Implementation of RetrieveData method // in IStorable interface )(public string RetrieveData { ;string result ;result = "Expenditure = " + this.Expenditures ;result += " Earnings = " + this.Earnings ;return result } در اﻳﻦ ﻣﺘﺪ ﻧﻴﺰ ﻣﻘﺎدﻳﺮ ﻣﻮﺟﻮد در ﻓﻴﻠﺪ ﻫﺎي ﻛﻼس را در داﺧﻞ ﻳﻚ ﻣﺘﻐﻴﺮ رﺷﺘﻪ اي ﻗﺮار داده و آن را ﺑﺮﻣﻲ ﮔﺮداﻧﻴﻢ .ﺣﺎل ﺑﺎﻳـﺪ ﺧﺎﺻـﻴﺖ اي ﻛﻪ در اﻳﻨﺘﺮﻓﻴﺲ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ را ﻧﻴﺰ در ﻛﻼس اﻳﺠﺎد ﻛﻨـﻴﻢ .اﻳـﻦ ﺧﺎﺻـﻴﺖ در اﻳﻨﺘـﺮﻓﻴﺲ داراي ﺑﺨـﺸﻬﺎي getو set اﺳﺖ ،ﭘﺲ در ﻛﻼس ﻧﻴﺰ ﺑﺎﻳﺪ داراي اﻳﻦ ﺑﺨﺸﻬﺎ ﺑﺎﺷﺪ ،ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﺎﻳﺪ ﺧﻮاﻧﺪﻧﻲ-ﻧﻮﺷﺘﻨﻲ ﺑﺎﺷﺪ. // Implementation of SavePath property // in IStorable interface public string SavePath { get { ;return _savePath } set { ;_savePath = value } }
٤١٠
ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﻪ ﻛﻼس ،ﺗﻤﺎم ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي ﻣﻮرد ﻧﻴﺎز را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮده اﻳﻢ .ﺣـﺎل ﺑـﻪ ﻃﺮاﺣـﻲ ﻛـﻼس ﺑﻌﺪي ﻳﻌﻨﻲ ﻛﻼس Employeesﻣﻲ ﭘﺮدازﻳﻢ .در اﻳﻦ ﻛﻼس ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻛﻼس Financialدو ﻓﻴﻠـﺪ ﺑـﺮاي ﻧﮕﻬـﺪاري اﻃﻼﻋﺎت ﻛﺎرﻣﻨﺪ ،ﻳﻚ ﻓﻴﻠﺪ ﺑﺮاي ﻧﮕﻬﺪاري آدرﺳﻲ ﻛﻪ ﺑﺎﻳﺪ اﻃﻼﻋﺎت ﻛﻼس در آن ذﺧﻴﺮه ﺷﻮد و ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن اوﻟﻴﻪ ﻓﻴﻠﺪ ﻫﺎي ﻛﻼس اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ: ;"public string _savePath = @"C:\EmployeesBackup.dat ;public long EmployeeID ;public string EmployeeName )public Employees(int ID, string Name { ;this.EmployeeID = ID ;this.EmployeeName = Name } اﻛﻨﻮن ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ اﻳﻦ ﻛﻼس ﻧﻴﺰ از ﻗﻮاﻋﺪ ﻣﻮﺟﻮد در اﻳﻨﺘﺮﻓﻴﺲ IStorableﭘﻴﺮوي ﻣﻲ ﻛﻨﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻫﻤﺎﻧﻨـﺪ ﻛﻼس ،Financialﻧﺎم اﻳﻨﺘﺮﻓﻴﺲ را در ﻣﻘﺎﺑﻞ ﻧﺎم ﻛﻼس ذﻛﺮ ﻣﻲ ﻛﻨﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺎﻳﺪ ﻣﺘـﺪ RetrieveDataو ﻫﻤﭽﻨﻴﻦ ﺧﺎﺻﻴﺖ SavePathرا ﻧﻴﺰ در ﻛﻼس اﻳﺠﺎد ﻛﻨﻴﻢ. )(public string RetrieveData { // Define a variable to store results ;string result // Produce the result ;result = "Employee ID: " + this.EmployeeID ;result += " Employee Name: " + this.EmployeeName ;return result } public string SavePath { get { ;return _savePath } set { ;_savePath = value } }
٤١١
ﺑﻌﺪ از ﺗﻤﺎم ﺷﺪن ﻃﺮاﺣﻲ ﻛﻼﺳﻬﺎي ﻣﻮرد ﻧﻴﺎز در ﺑﺮﻧﺎﻣﻪ ،ﺑﺎﻳﺪ ﻗﺴﻤﺘﻲ را ﺑﺮاي ﺑﺮرﺳﻲ ﻧﺤﻮه ﻋﻤﻠﻜﺮد آن ﺑﻨﻮﻳﺴﻴﻢ .در ﻣﺘﺪ Mainاﺑﺘـﺪا دو ﺷﻴﺊ از ﻧﻮع Financialو Employeesاﻳﺠﺎد ﻛﺮده و اﻃﻼﻋﺎت آﻧﻬﺎ را ﺑـﺎ اﺳـﺘﻔﺎده از ﻣﺘـﺪ WriteLineﺑـﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ: // Instantiating the needed variables ;)Financial finan = new Financial(264399, 368547 ;)"Employees emp = new Employees(1, "John Smith // Writing information about created objects ;)"!Console.WriteLine("A Financial object created Console.WriteLine("Expenditure: " + ;)finan.Expenditures ;)Console.WriteLine("Earning: " + finan.Earnings ;)"!Console.WriteLine("An Employees object created ;)Console.WriteLine("Employee ID: " + emp.EmployeeID Console.WriteLine("Employee Name: " + ;)emp.EmployeeName ﺣﺎل ﺑﻪ ﻗﺴﻤﺘﻲ ﻣﻲ رﺳﻴﻢ ﻛﻪ راﺣﺘﻲ ﻛﺎر ﺑﺎ اﻳﻨﺘﺮﻓﻴﺲ ﻫﺎ را ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ وﺿﻮح درك ﻛﻨﻴـﺪ .ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ ﮔﻔـﺘﻢ ﻫﻨﮕـﺎم اﻳﺠـﺎد ﻣﺘـﺪ ،Saveﺑﺮاي ﻣﺎ ﺗﻔﺎوﺗﻲ ﻧﺪارد ﻛﻪ ﭼﻪ ﺷﻴﺊ اي ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد ﺑﻠﻜﻪ ﻓﻘﻂ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺷﻴﺊ اي ﻛـﻪ ﻓﺮﺳـﺘﺎده ﻣـﻲ ﺷـﻮد داراي ﻣﺘﺪي ﺑﻪ ﻧﺎم RetrieveDataﺑﺎﺷﺪ ﺗﺎ اﻃﻼﻋﺎت ﻣﻬﻢ آن ر در ﻗﺎﻟﺐ رﺷﺘﻪ ﺑﺮﮔﺮداﻧﺪ .ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺧـﻮاﻫﻴﻢ اﻳـﻦ ﺷـﻴﺊ داراي ﺧﺎﺻﻴﺘﻲ ﺑﻪ ﻧﺎم SavePathﺑﺎﺷﺪ ﻛﻪ آدرس ذﺧﻴﺮه ﺷﺪن ﻓﺎﻳﻞ را ﺑﺮﮔﺮداﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻪ راﺣﺘﻲ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑـﻪ ﻣﺘـﺪ Save ﺑﮕﻮﻳﻴﻢ ﭘﺎراﻣﺘﺮي ﻛﻪ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ ﺣﺘﻤﺎ ﺑﺎﻳﺪ از ﻗﻮاﻋﺪ اﻳﻨﺘﺮﻓﻴﺲ IStorableﭘﻴﺮوي ﻛﺮده ﺑﺎﺷﺪ. )static void Save(IStorable obj ﻧﻜﺘﻪ اي ﻛﻪ ﺑﺎﻳﺪ ﺑﻪ آن ﺗﻮﺟﻪ ﻛﻨﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ در ﺑﺪﻧﻪ ي ﻣﺘﺪ Saveﻓﻘﻂ ﺑﻪ ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘـﺪ ﻫـﺎﻳﻲ از ﺷـﻴﺊ objدﺳﺘﺮﺳـﻲ دارﻳﻢ ﻛﻪ در اﻳﻨﺘﺮﻓﻴﺲ IStorableﺗﻌﺮﻳﻒ ﺷﺪه اﻧﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﺷﻴﺊ اي از ﻧـﻮع Employeesرا ﺑـﻪ ﻣﺘـﺪ Save ﺑﻔﺮﺳﺘﻴﻢ ،درون اﻳﻦ ﻣﺘﺪ ﻓﻘﻂ ﺑﻪ ﺧﺎﺻﻴﺖ SavePathو ﻣﺘﺪ RetrieveDataاز آن ﺷﻴﺊ دﺳﺘﺮﺳـﻲ ﺧـﻮاﻫﻴﻢ داﺷـﺖ و ﻧﻤﻲ ﺗﻮاﻧﻴﻢ ﺑﻪ ﻣﻘﺪار ﻓﻴﻠﺪ EmployeeIDدﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ )ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ اﻳﻦ ﻓﻴﻠﺪ از ﻧﻮع publicاﺳﺖ( .دﻟﻴﻞ اﻳـﻦ اﻣﺮ ﻫﻢ ﻛﺎﻣﻼً واﺿﺢ اﺳﺖ .در ﻫﻨﮕﺎم ﺗﻌﺮﻳﻒ ﻣﺘﺪ ﻣﺸﺨﺺ ﻛﺮده اﻳﻢ ﻛﻪ اﺷﻴﺎﻳﻲ ﻛﻪ ﺑﻪ ﻣﺘﺪ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮﻧﺪ ﻓﻘﻂ ﺑﺎﻳﺪ داراي ﻣﺘﺪ ﻫـﺎ و ﺧﺎﺻﻴﺘﻬﺎي ﺗﻌﺮﻳﻒ ﺷﺪه در اﻳﻨﺘﺮﻓﻴﺲ IStorableﺑﺎﺷﻨﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ ﻧﻤﻲ ﺗﻮاﻧﻴﻢ اﻧﺘﻈﺎر ﺑﻴﺸﺘﺮي از ﭘﺎراﻣﺘﺮﻫﺎي ﻓﺮﺳﺘﺎده ﺷﺪه ﺑﻪ اﻳﻦ ﻣﺘﺪ داﺷﺘﻪ ﺑﺎﺷﻴﻢ .در ﺑﺪﻧﻪ ي ﻣﺘﺪ ﻫﻢ ﻛﺎﻓﻲ اﺳﺖ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ RetrieveDataاﻃﻼﻋﺎت ﻣﻬﻢ ﭘـﺎراﻣﺘﺮ ﻓﺮﺳـﺘﺎده ﺷـﺪه را ﺑﺪﺳﺖ آورﻳﻢ ،ﺳﭙﺲ ﺑﺎ اﺳـﺘﻔﺎده از ﻣﺘـﺪ WriteAllTextدر ﻛـﻼس ،Fileاﻃﻼﻋـﺎت را در آدرﺳـﻲ ﻛـﻪ درون ﻛـﻼس ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﻗﺮار ﻣﻲ دﻫﻴﻢ: // Define a variable to store important data ;string data // Retrieving important data to save on disk ;)(data = obj.RetrieveData // Saving retrieved data on disk
٤١٢
;)File.WriteAllText(obj.SavePath, data ﻧﻜﺘﻪ :دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ در ﻫﻨﮕﺎم ﺗﻌﺮﻳﻒ ﻳﻚ اﻳﻨﺘﺮﻓﻴﺲ ،ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﻓﻴﻠﺪي در آن اﻳﺠﺎد ﻛﻨﻴﺪ .ﺑﻪ ﻋﺒـﺎرت دﻳﮕـﺮ ﻧﻤـﻲ ﺗﻮاﻧﻴـﺪ ﻛﻼﺳـﻬﺎي اﺳﺘﻔﺎده ﻛﻨﻨﺪه از ﻳﻚ اﻳﻨﺘﺮﻓﻴﺲ را ﻣﻠﺰم ﺑﻪ ﺗﻌﺮﻳﻒ ﻳﻚ ﻓﻴﻠﺪ ﺧﺎص ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل اﺳﺘﻔﺎده از اﻳﻨﺘﺮﻓﻴﺲ زﻳﺮ در ﺑﺮﻧﺎﻣﻪ ﻣﻮﺟﺐ ﺑﺮوز ﺧﻄﺎ ﺧﻮاﻫﺪ ﺷﺪ: public interface IInvalid { ;int MakesAnError // Other members of this interface goes here } ﺣﺎل ﻛﻪ ﺑﺎ ﺑﻴﺸﺘﺮ ﺗﻜﻨﻴﻜﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا آﺷﻨﺎ ﺷﺪﻳﺪ ،در اداﻣﻪ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﺗﻜﻨﻴﻜﻬﺎ ﺑﺮﻧﺎﻣﻪ اي ﻛـﺎرﺑﺮدي اﻳﺠﺎد ﻛﺮده ﺗﺎ ﺑﺎ ﻧﺤﻮه اﺳﺘﻔﺎده از آﻧﻬﺎ در ﻋﻤﻞ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺷﻮﻳﻢ.
٤١٣
اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻛﺎرﺑﺮدي: در اﻳﻦ ﻗﺴﻤﺖ از ﻓﺼﻞ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮاﻫﻴﻢ ﻧﻮﺷﺖ ﻛﻪ ﺑﻪ وﺳـﻴﻠﻪ آن ﺑﺘﻮاﻧﻴـﺪ ﺳـﺎﻳﺘﻬﺎي ﻣﻮﺟـﻮد در ﺑﺨـﺶ Favoritesاﻳﻨﺘﺮﻧـﺖ اﻛﺴﭙﻠﻮرر را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ .ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ دﻛﻤﻪ اي ﻗﺮار ﻣﻲ دﻫﻴﻢ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ آن ﺑﺘﻮاﻧﻴﺪ آن ﺳﺎﻳﺘﻬﺎ را ﺑﺎ اﺳـﺘﻔﺎده از اﻳﻨﺘﺮﻧـﺖ اﻛﺴﭙﻠﻮرر ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ.
ﺷﻮرت ﻛﺎت ﻫﺎي اﻳﻨﺘﺮﻧﺘﻲ و Favoritesﻫﺎ: اﺣﺘﻤﺎﻻً ﺗﺎﻛﻨﻮن ﺑﺎ ﻗﺴﻤﺖ Favoritesدر اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﺑﺮﺧﻮرد ﻛﺮده اﻳﺪ و ﻋﻤﻠﻜﺮد آن را ﻧﻴﺰ ﻣﻲ داﻧﻴـﺪ .اﻣـﺎ ﻧﻜﺘـﻪ اي ﻛـﻪ ﻣﻤﻜﻦ اﺳﺖ در اﻳﻦ ﻣﻮرد ﻧﺪاﻧﻴﺪ ،اﻳﻦ اﺳﺖ ﻛﻪ اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﭼﮕﻮﻧﻪ اﻃﻼﻋﺎت ﻣﻮﺟﻮد در ﻗﺴﻤﺖ Favoritesرا ذﺧﻴـﺮه ﻣـﻲ ﻛﻨﺪ؟ در ﺣﻘﻴﻘﺖ ،ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻗﺴﻤﺖ Favoritesﻓﻘﻂ ﻣﺨﺼﻮص اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﻧﻴﺴﺘﻨﺪ و ﻫﺮ ﺑﺮﻧﺎﻣﻪ اي ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ آﻧﻬﺎ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ ،ﻓﻘﻂ ﻛﺎﻓﻲ اﺳﺖ ﻣﻜﺎن ذﺧﻴﺮه ﺷﺪه اﻳﻦ ﻓﺎﻳﻠﻬﺎ را ﺑﺪاﻧﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ در وﻳﻨﺪوز ،XPﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻲ ﺗﻮاﻧﻨﺪ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﻫﺮ ﻛﺎرﺑﺮ را در ﻓﻮﻟـﺪر ﻣﺨـﺼﻮص ﺑـﻪ آن ﻛـﺎرﺑﺮ ﻛـﻪ در ﻣﺴﻴﺮ C:\Documents and Settingsﻗﺮار دارد ،ﺑﻨﻮﻳﺴﻨﺪ .در اﻳﻦ ﻣﺴﻴﺮ ﺑﺎزاي ﻫﺮ ﻛﺎرﺑﺮ ﻳـﻚ ﻓﻮﻟـﺪر ﺑـﻪ ﻧـﺎم او وﺟﻮد دارد .ﺑﺮاي ﻣﺜﺎل ﻛﺎﻣﭙﻴﻮﺗﺮي ﻛﻪ در ﺷﻜﻞ 13-10ﻧﺸﺎن داده ﺷﺪه اﺳﺖ ﻳﻚ ﻛﺎرﺑﺮ ﺑﻪ ﻧﺎم Mohammadوﺟﻮد دارد. ﻧﻜﺘــﻪ :در اﻳــﻦ ﻣــﺴﻴﺮ ﻋــﻼوه ﺑــﺮ ﻓﻮﻟــﺪر ﻫــﺎﻳﻲ ﻣﺨــﺼﻮص ﻛــﺎرﺑﺮان ﻛــﺎﻣﭙﻴﻮﺗﺮ ،ﻓﻮﻟــﺪر ﻫــﺎي دﻳﮕــﺮي ﻧﻴ ـﺰ وﺟــﻮد دارد .ﻓﻮﻟــﺪر Administratorﺑﺮاي ﻣﺪﻳﺮ ﭘﻴﺶ ﻓـﺮض ﺳﻴـﺴﺘﻢ اﺳـﺖ و در ﺳﻴـﺴﺘﻢ ﻋﺎﻣـﻞ ﻫـﺎي وﻳﻨـﺪوز 2000و ﻳـﺎ وﻳﻨـﺪوز XP Professionalوﺟﻮد دارد .ﻓﻮﻟﺪر All Usersﺣﺎوي اﻃﻼﻋﺎﺗﻲ اﺳﺖ ﻛﻪ ﺑﻴﻦ ﺗﻤﺎم ﻛﺎرﺑﺮان ﻣـﺸﺘﺮك اﺳـﺖ .ﻓﻮﻟـﺪر Default Userﻧﻴﺰ ﻳﻚ ﻓﻮﻟﺪر ﻣﺨﺼﻮص اﺳﺖ ﻛﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻛﺎرﺑﺮ ﺑﺮاي اوﻟﻴﻦ ﺑﺎر از ﺳﻴﺴﺘﻢ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ ،وﻳﻨﺪوز ﺗﻨﻈﻴﻤﺎت ﻣﺸﺨﺺ ﺷﺪه در اﻳﻦ ﻓﻮﻟﺪر را ﺑﺮاي او ﺑﻪ ﻛﺎر ﻣﻲ ﺑﺮد.
ﺷﻜﻞ 13-10
٤١٤
ﺑﺮ اﺳﺎس ﺗﻨﻈﻴﻤﺎت اﻣﻨﻴﺘﻲ ﻛﺎﻣﭙﻴﻮﺗﺮي ﻛﻪ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ،ﻣﻤﻜﻦ اﺳﺖ ﺑﻪ ﻣﺤﺘﻮﻳﺎت اﻳﻦ ﻓﻮﻟﺪر دﺳﺘﺮﺳﻲ ﻧﺪاﺷﺘﻪ ﺑﺎﺷﻴﺪ و ﻳﺎ اﻳﻨﻜﻪ ﻓﻘﻂ ﺑﺘﻮاﻧﻴﺪ ﻣﺤﺘﻮﻳﺎت ﻓﻮﻟﺪر ﻣﺨﺼﻮص ﺑﻪ ﻛﺎرﺑﺮي ﻛﻪ در ﺣﺎل اﺳﺘﻔﺎده از آن ﻫﺴﺘﻴﺪ را ﻣﺸﺎﻫﺪه ﻛﻨﻴـﺪ .ﺑﻌـﺪ از اﻳﻨﻜـﻪ وارد ﻳﻜـﻲ از اﻳـﻦ ﻓﻮﻟﺪر ﻫﺎ ﺷﺪﻳﺪ ،ﻳﻚ دﺳﺘﻪ دﻳﮕﺮ از ﻓﻮﻟﺪر ﻫﺎ را ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 14-10ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد )اﻟﺒﺘﻪ ﻣﻤﻜﻦ اﺳـﺖ ﻣﺤﺘﻮﻳـﺎت آن ﻓﻮﻟـﺪر ﺑـﺮ اﺳﺎس ﺗﻨﻈﻴﻤﺎت ﻛﺎﻣﭙﻴﻮﺗﺮ ﺷﻤﺎ ﺑﺎ ﻣﺤﺘﻮﻳﺎت ﻧﻤﺎﻳﺶ داده ﺷﺪه در ﺷﻜﻞ ﻣﺘﻔﺎوت ﺑﺎﺷﺪ(. ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در ﺷﻜﻞ 14-10ﺑﻌﻀﻲ از ﻓﻮﻟﺪر ﻫﺎ ﻛﻤﺮﻧﮓ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﻧﺪ زﻳﺮا اﻳﻦ ﻓﻮﻟﺪر ﻫـﺎ ﺑـﻪ ﺻـﻮرت ﭘـﻴﺶ ﻓـﺮض ﻣﺨﻔـﻲ ﻫﺴﺘﻨﺪ .ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ ﺑﺮ ﺣﺴﺐ ﺗﻨﻈﻴﻤﺎت ﻛﺎﻣﭙﻴﻮﺗﺮي ﻛﻪ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ،ﻣﻤﻜﻦ اﺳﺖ اﻳـﻦ ﻓﻮﻟـﺪرﻫﺎي ﻛﻤﺮﻧـﮓ ﻧﻤـﺎﻳﺶ داده ﻧﺸﻮﻧﺪ .اﻟﺒﺘﻪ در اﻳﻦ ﻗﺴﻤﺖ از اﻳﻦ ﻓﻮﻟﺪر ﻫﺎ اﺳﺘﻔﺎده ﻧﺨﻮاﻫﻴﻢ ﻛﺮد و ﻓﻘﻂ ﺑﺎ ﻓﻮﻟﺪر Favoritesﻛﺎر ﻣﻲ ﻛﻨـﻴﻢ ﻛـﻪ در ﻫـﺮ ﺣـﺎل ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ اﻳﻦ ﻓﻮﻟﺪر و ﻓﻮﻟﺪرﻫﺎي درون آن ﻣﻜﺎﻧﻲ ﻫﺴﺘﻨﺪ ﻛﻪ وﻳﻨﺪوز ،اﻃﻼﻋﺎت ﺷﺨﺼﻲ ﻫﺮ ﻛﺎرﺑﺮ را در آﻧﻬﺎ ذﺧﻴـﺮه ﻣـﻲ ﻛﻨـﺪ. ﺑﺮاي ﻣﺜﺎل:
:Cookiesاﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﺻﻔﺤﺎت وﺑﻲ ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮده اﻳﺪ را ﻧﮕﻪ داري ﻣﻲ ﻛﻨﺪ.
:Desktopﻓﺎﻳﻠﻬﺎ و ﻓﻮﻟﺪر ﻫﺎﻳﻲ ﻛﻪ در Desktopﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ در اﻳﻦ ﻗﺴﻤﺖ ذﺧﻴﺮه ﻣﻲ ﺷﻮﻧﺪ.
:Favoritesآﻳﺘﻢ ﻫﺎي ﻣﻮﺟﻮد در ﻗﺴﻤﺖ Favoritesاﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر در اﻳﻦ ﻓﻮﻟﺪر ذﺧﻴﺮه ﻣﻲ ﺷﻮﻧﺪ.
:My Documentsﻣﻜﺎﻧﻲ ﺑﺮاي ذﺧﻴﺮه اﻃﻼﻋﺎت ،ﻋﻜﺴﻬﺎ و ﺳﻨﺪﻫﺎي اﻳﺠﺎد ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ﻛﺎرﺑﺮ اﺳﺖ.
:Start Menuﻟﻴﺴﺘﻲ از آﻳﻜﻮن ﻫﺎ و ﻓﻮﻟﺪر ﻫﺎﻳﻲ ﻛﻪ زﻣﺎن اﺳﺘﻔﺎده از ﻣﻨﻮي Startﻧﻤﺎﻳﺶ داده ﻣـﻲ ﺷـﻮﻧﺪ را ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ. :User Dataاﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﻛﺎرﺑﺮ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ را ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ.
ﺷﻜﻞ 14-10 در اﻳﻦ ﻗﺴﻤﺖ ﻓﻘﻂ از ﻓﻮﻟﺪر Favoritesاﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد ،ﺑﻨﺎﺑﺮاﻳﻦ اﻳﻦ ﻓﻮﻟﺪر را ﺑـﺎز ﻛﻨﻴـﺪ .در اﻳـﻦ ﻓﻮﻟـﺪر ﻟﻴـﺴﺘﻲ ﺷـﺎﻣﻞ ﺗﻌﺪادي ﻟﻴﻨﻚ ﺑﻪ آدرس ﻫﺎي اﻳﻨﺘﺮﻧﺘﻲ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻟﻴﻨﻚ ﻫﺎي اﻳﻦ ﻗـﺴﻤﺖ ﺑـﺎ ﻟﻴﻨـﻚ ﻫـﺎي ﻣﻮﺟـﻮد در ﻗﺴﻤﺖ Favoritesاﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﺑﺮاﺑﺮ ﻫﺴﺘﻨﺪ .اﮔﺮ روي ﻫﺮ ﻛﺪام از اﻳﻦ ﻟﻴﻨﻚ ﻫﺎ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ،اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﺑﺎز ﺷﺪه و ﺑﻪ ﺳﺎﻳﺘﻲ ﻛﻪ ﻟﻴﻨﻚ ﺑﻪ آن اﺷﺎره ﻣﻲ ﻛﻨﺪ ﻣﻲ رود.
٤١٥
ﺣﺎل ﻛﻪ ﻣﺘﻮﺟﻪ ﺷﺪﻳﺪ ﮔﺰﻳﻨﻪ ﻫﺎي ﻗﺴﻤﺖ Favoritesدر اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر در ﭼﻪ ﻓﻮﻟﺪري ﻧﮕﻬـﺪاري ﻣـﻲ ﺷـﻮﻧﺪ ،ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑﺮﻧﺎﻣﻪ اي ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ اﻳﻦ ﻓﻮﻟﺪر را ﺑﺎز ﻛﺮده و از ﻟﻴﻨﻚ ﻫﺎي درون آن اﺳﺘﻔﺎده ﻛﻨﺪ ،ﺑﺮاي ﻣﺜﺎل آﻧﻬﺎ را ﺑﻪ ﻳﻚ ﻟﻴﺴﺖ اﺿﺎﻓﻪ ﻛﻨﺪ ،ﺳـﺎﻳﺖ ﻣﺮﺑﻮط ﺑﻪ آﻧﻬﺎ را ﺑﺎ اﺳﺘﻔﺎده از اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﻧﻤﺎﻳﺶ دﻫﺪ و … .در اﻳﻦ ﻣﺜﺎل از ﻓﻮﻟﺪر ﻫﺎﻳﻲ ﻛﻪ در ﻗﺴﻤﺖ Favoritesوﺟﻮد دارﻧﺪ ﺻﺮف ﻧﻈﺮ ﻣﻲ ﻛﻨﻴﻢ و ﻓﻘﻂ ﺑﺎ ﻓﺎﻳﻠﻬﺎي اﻳﻦ ﻗﺴﻤﺖ ﻛﺎر ﺧﻮاﻫﻴﻢ ﻛﺮد. اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﻌﺪ از اﺗﻤﺎم ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 15-10ﺧﻮاﻫﺪ ﺑﻮد.
ﺷﻜﻞ 15-10
اﺳﺘﻔﺎده از ﻛﻼﺳﻬﺎ: ﺗﺎﻛﻨﻮن در ﻣﺜﺎل ﻫﺎي ﻗﺒﻠﻲ اﻳﻦ ﻛﺘﺎب ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﺎده اي اﻳﺠﺎد ﻣﻲ ﻛﺮدﻳﺪ ﻛﻪ ﺑﻴﺸﺘﺮ وﻇﺎﻳﻒ ﺷﺎن را در ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﻧﺠﺎم ﻣﻲ دادﻧﺪ .در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻛﻼﺳﻲ اﻳﺠﺎد ﻛﻨﻴﻢ ﻛﻪ ﻟﻴﺴﺘﻲ از ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد در Favoritesرا ﻧﻤﺎﻳﺶ دﻫﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻟﻴﺴﺘﻲ ﻛﻪ اﻳﻦ ﻛﻼس اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ در ﻫﺮ ﺑﺮﻧﺎﻣﻪ و ﺑﻪ ﻫﺮ ﻧﺤﻮي ﻛﻪ ﺑﺨﻮاﻫﻴﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻟﻴﺴﺖ را ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﻟﻴﺴﺖ ﺑﺎﻛﺲ ﻧﻤﺎﻳﺶ دﻫﻴﺪ و ﺳﭙﺲ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﻴﺪ ﻛﻪ ﺑﺎ اﺳـﺘﻔﺎده از اﻳﻨﺘﺮﻧـﺖ اﻛـﺴﭙﻠﻮرر آﻧﻬﺎ را ﻣﺸﺎﻫﺪه ﻛﻨﺪ. ﺑﻬﺘﺮﻳﻦ راه ﺑﺮاي اﻳﺠﺎد ﭼﻨﻴﻦ ﺑﺮﻧﺎﻣﻪ اي اﻳﻦ اﺳﺖ ﻛﻪ ﻛﻼس ﻫﺎﻳﻲ را ﺑﻪ ﺻﻮرت زﻳﺮ اﻳﺠﺎد ﻛﻨﻴﻢ:
:WebFavoriteﻫﺮ ﺷﻴﺊ از اﻳﻦ ﻛﻼس ﺑﺮاي ﻧﮕﻬـﺪاري ﻳﻜـﻲ از ﮔﺰﻳﻨـﻪ ﻫـﺎي ﻣﻮﺟـﻮد در Favoritesو ﻫﻤﭽﻨﻴﻦ وﻳﮋﮔﻲ ﻫﺎي آن ﻣﺎﻧﻨﺪ Nameو URLﺑﻪ ﻛﺎر ﻣﻲ رود. :Favoritesاﻳﻦ ﻛﻼس ﻣﻲ ﺗﻮاﻧﺪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻛﺎرﺑﺮ را ﺑﺮاي ﭘﻴﺪا ﻛﺮدن Favoritesﺟﺴﺘﺠﻮ ﻛﻨـﺪ ،ﺑـﺮاي ﻫـﺮ ﻳﻚ از ﮔﺰﻳﻨﻪ ﻫﺎي Favoriteﻳﻚ ﺷﻴﺊ از ﻛﻼس WebFavoriteاﻳﺠﺎد ﻛﺮده و اﺷﻴﺎي اﻳﺠـﺎد ﺷـﺪه را در ﻳﻚ آراﻳﻪ ﻗﺮار دﻫﺪ.
٤١٦
اﻳﻦ دو ﻛﻼس اﺻﻄﻼﺣﺎ ﻗﺴﻤﺖ back-endﺑﺮﻧﺎﻣﻪ را ﺗﺸﻜﻴﻞ ﻣﻲ دﻫﻨﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ ﺗﻤـﺎم ﻛـﻼس ﻫـﺎﻳﻲ ﻛﻪ وﻇﻴﻔﻪ ي ﺧﺎﺻﻲ را در ﺑﺮﻧﺎﻣﻪ اﻧﺠﺎم ﻣﻲ دﻫﻨﺪ اﻣﺎ ﻫﻴﭻ راﺑﻂ ﮔﺮاﻓﻴﻜﻲ ﺧﺎﺻﻲ ﻧﺪارﻧﺪ ﺗﺎ در ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ داده ﺷـﻮد ،ﻗـﺴﻤﺖ back-endﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﺗﺸﻜﻴﻞ ﻣﻲ دﻫﻨﺪ .ﺟﺪا ﻛﺮدن اﻳﻦ ﻗﺴﻤﺘﻬﺎ از ﻇﺎﻫﺮ ﺑﺮﻧﺎﻣﻪ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﺗﺎ ﺑﺘﻮاﻧﻴﺪ از اﻳـﻦ ﻛﻼﺳـﻬﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕﺮ ﺧﻮد ﻧﻴﺰ ﺑﻪ راﺣﺘﻲ اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ )اﺳـﺘﻔﺎده ﻣﺠـﺪد از ﻛـﺪ( .ﻫﻤﭽﻨـﻴﻦ ﺑـﺮاي ﺗﻜﻤﻴـﻞ اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ ﺑـﻪ ﻳـﻚ ﻗـﺴﻤﺖ front-endﻧﻴﺰ ﻧﻴﺎز دارﻳﺪ ﻛﻪ راﺑﻂ ﻛﺎرﺑﺮي ﺑﺮﻧﺎﻣﻪ را ﺗﺸﻜﻴﻞ ﻣﻲ دﻫﺪ .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ،اﻳﻦ ﻗﺴﻤﺖ ﺷﺎﻣﻞ ﻳﻚ ﻓـﺮم وﻳﻨـﺪوزي و ﭼﻨﺪ ﻛﻨﺘﺮل ﻋﺎدي ﺧﻮاﻫﺪ ﺑﻮد. در ﭼﻨﺪ ﺑﺨﺶ ﺑﻌﺪي ،ﺑﻪ ﻃﺮاﺣﻲ ﻛﻼﺳﻬﺎي ﻣﻮرد ﻧﻴﺎز و ﻫﻤﭽﻨﻴﻦ راﺑﻂ ﮔﺮاﻓﻴﻜﻲ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در ﺷﻜﻞ 16-10ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﺧـﻮاﻫﻴﻢ ﭘﺮداﺧﺖ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي Favorites Viewer (1ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005را ﺑﺎز ﻛﻨﻴﺪ و ﻳﻚ ﭘﺮوژه وﻳﻨﺪوزي ﺟﺪﻳـﺪ ﺑـﻪ ﻧـﺎم Favorites Viewerاﻳﺠـﺎد ﻛﻨﻴﺪ. (2ﺧﺎﺻﻴﺘﻬﺎي ﻓﺮم را ﺑﺮ ﻃﺒﻖ ﻟﻴﺴﺖ زﻳﺮ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ Sizeرا ﺑﺮاﺑﺮ ﺑﺎ 464;280ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ StartPositionرا ﺑﺮاﺑﺮ ﺑﺎ CenterScreenﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textرا ﺑﺮاﺑﺮ ﺑﺎ My Favoritesﻗﺮار دﻫﻴﺪ.
(3ﻳﻚ ﻛﻨﺘﺮل ListViewﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﺪ و اﻧﺪازه آن را ﺑﻪ ﺻﻮرﺗﻲ ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 15-10ﺷﻮد .ﺳﭙﺲ ﺧﺎﺻﻴﺖ ﻫﺎي آن را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ:
ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑﺎ lstFavoritesﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Anchorآن را ﺑﺮاﺑﺮ ﺑﺎ Left,Right,Top,Bottomﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Viewرا ﺑﺮاﺑﺮ ﺑﺎ Detailsﻗﺮار دﻫﻴﺪ.
(4ﺧﺎﺻﻴﺖ Columnsﻛﻨﺘﺮل lstFavoritesرا ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي Propertiesاﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤﻪ ي … در ﻣﻘﺎﺑﻞ آن ﻛﻠﻴﻚ ﻛﻨﻴـﺪ .ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﻛـﺎدر ColumnHeader Collection Editorﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ. (5در اﻳﻦ ﻛﺎدر روي دﻛﻤﻪ ي Addﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺳﭙﺲ ﺧﺎﺻﻴﺖ ﻫﺎي ﺳﺘﻮن ﺟﺪﻳﺪ را ﻛـﻪ در ﺑﺨـﺶ Membersاﺿـﺎﻓﻪ ﺷﺪه اﺳﺖ ،ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺎدﻳﺮ زﻳﺮ ﻗﺮار دﻫﻴﺪ:
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ hdrNameﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Nameﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Widthآن را ﺑﺮاﺑﺮ ﺑﺎ 250ﻗﺮار دﻫﻴﺪ.
(6ﻣﺠﺪداً روي دﻛﻤﻪ ي Addﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺳﺘﻮن ﺟﺪﻳﺪي ﺑﻪ ﻗﺴﻤﺖ Membersاﺿﺎﻓﻪ ﺷﻮد .ﺳﭙﺲ ﺧﺎﺻﻴﺖ ﻫﺎي اﻳﻦ ﺳﺘﻮن را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺎدﻳﺮ زﻳﺮ ﻗﺮار دﻫﻴﺪ:
٤١٧
ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑﺎ hdrUrlﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Urlﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Widthآن را ﺑﺮاﺑﺮ ﺑﺎ 250ﻗﺮار دﻫﻴﺪ.
(7روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻛﺎدر ColumnHeader Collection Editorﺑﺴﺘﻪ ﺷﻮد. (8ﻳﻚ ﻛﻨﺘﺮل LinkLabelﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮده و ﺧﺎﺻﻴﺖ ﻫﺎي آن را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺎدﻳﺮ زﻳﺮ ﻗﺮار دﻫﻴﺪ.
ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑﺎ lnkUrlﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Anchorآن را ﺑﺮاﺑﺮ ﺑﺎ Bottom, Left, Rightﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ TextAlignرا ﺑﺮاﺑﺮ ﺑﺎ MiddleLeftﻗﺮار دﻫﻴﺪ.
(9ﻓﺮم ﻛﺎﻣﻞ ﺷﺪه ي ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 16-10ﺷﺪه ﺑﺎﺷﺪ.
ﺷﻜﻞ 16-10
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺗﻤﺎم ﻛﺎري ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﻧﺠﺎم دادﻳﺪ ،ﻃﺮاﺣﻲ ﻇﺎﻫﺮ ﺑﺮﻧﺎﻣﻪ ﺑﻮد ﺗﺎ ﺑﺘﻮاﻧﺪ ﻧﺘﻴﺠﻪ ي ﺑﺪﺳﺖ آﻣﺪه را ﻧﻤﺎﻳﺶ دﻫﺪ .در اﻳﻦ ﻓـﺮم ﻛﻨﺘـﺮل ListViewﺑﺮاي ﻧﻤﺎﻳﺶ ﻧﺎم و آدرس ﻫﺮ ﻳﻚ از ﮔﺰﻳﻨﻪ ﻫـﺎي ﻣﻮﺟـﻮد در ﻓﻮﻟـﺪر Favoritesﺑـﻪ ﻛـﺎر ﻣـﻲ رود .ﻛﻨﺘـﺮل LinkLabelﻫﻢ ﺑﺮاي ﺑﺎز ﻛﺮدن ﺑﺮﻧﺎﻣﻪ ي ﻣﺮورﮔﺮ و ﻧﻤﺎﻳﺶ ﺳﺎﻳﺖ اﻧﺘﺨﺎب ﺷﺪه در ﻟﻴﺴﺖ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد. ﺗﺎﻛﻨﻮن ﻣﺮاﺣﻞ اوﻟﻴﻪ ﻛﺎر را اﻧﺠﺎم داده اﻳﻢ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛـﻪ ﭼﮕﻮﻧـﻪ ﻣـﻲ ﺗـﻮان ﻛﻼﺳـﻬﺎي ﺑﺨـﺶ back-endﺑﺮﻧﺎﻣﻪ را اﻳﺠﺎد ﻛﺮد.
٤١٨
WebFavorite اﻳﺠﺎد ﻛﻼس:اﻣﺘﺤﺎن ﻛﻨﻴﺪ ( ﻛﻠﻴـﻚFavorites Viewer) روي ﻧﺎم ﭘﺮوژهSolution Explorer ( ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي1 Add New را اﻧﺘﺨﺎب ﻛﻨﻴـﺪ ﺗـﺎ ﻛـﺎدرAdd Class… راﺳﺖ ﻛﻨﻴﺪ و ﺳﭙﺲ از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ ي ﻋﺒـــﺎرتName در ﻗـــﺴﻤﺖ. ﻧﻤـــﺎﻳﺶ داده ﺷـــﻮدItem – Favorites Viewer . ﻛﻠﻴﻚ ﻛﻨﻴﺪAdd را وارد ﻛﺮده و روي دﻛﻤﻪ يWebFavorite.cs : را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪSystem.IO ( ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر زﻳﺮ ﻓﻀﺎي ﻧﺎم2 using System.IO; namespace Favorites_Viewer : ﺑﺮاي اﻳﻦ ﻛﺎر اﺑﺘﺪا دو ﻓﻴﻠﺪ ﻛﻪ در زﻳﺮ آﻣﺪه اﺳﺖ را ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ.( ﺣﺎل ﻃﺮاﺣﻲ ﺧﻮد ﻛﻼس را ﺷﺮوع ﻣﻲ ﻛﻨﻴﻢ3 // Public Members public string Name; public string Url; : ﻫﻤﺎﻧﻨﺪ زﻳﺮ ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ ﻣﻘﺎدﻳﺮ ﻣﻮرد ﻧﻴﺎز را در ﻓﻴﻠﺪ ﻫﺎي ﻛﻼس ﻗﺮار دﻫﺪLoad ( ﻫﻤﭽﻨﻴﻦ ﻳﻚ ﻣﺘﺪ ﺑﻪ ﻧﺎم4 public void Load(string FileName) { // Declare variables string strData; string[] strLines; FileInfo objFileInfo = new FileInfo(FileName); // Set the Name member to the file name // minus the extension Name = objFileInfo.Name.Substring(0, objFileInfo.Name.Length – objFileInfo.Extension.Length); // Read the entire contents of the file strData = File.ReadAllText(FileName); // Split the lines of data in the file strLines = strData.Split('\n'); // Process each line looking for the URL foreach(string strLine in strLines) { // Does the line of data start with URL=
٤١٩
))"=if (strLine.StartsWith("URL { // Yes, Set the Url member to the actual URL ;)Url = strLine.Substring(4 // Exit the foreach loop ;break } } }
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺗﻨﻬﺎ ﻧﻜﺘﻪ ي ﻣﻬﻤﻲ ﻛﻪ در اﻳﻦ ﻛﻼس ﻗﺮار دارد اﻳﻦ اﺳﺖ ﻛﻪ اﻳﻦ ﻛﻼس ﭼﮕﻮﻧﻪ ﻫﻨﮕﺎم ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ Loadاﻃﻼﻋﺎت داﺧﻞ ﺧﻮد را ﭘﺮ ﻣﻲ ﻛﻨﺪ؟ در اﺑﺘﺪاي اﻳﻦ ﻣﺘﺪ ﺑﺎﻳﺪ ﻣﺘﻐﻴﻴﺮ ﻫﺎي ﻣﻮرد ﻧﻴﺎز در ﻣﺘﺪ را ﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ .ﻳﻚ ﻣﺘﻐﻴﺮ ﺑﻪ ﻧﺎم strDataاﻳﺠﺎد ﻛـﺮده و ﺗﻤـﺎم ﻣﺤﺘﻮﻳـﺎت ﻓﺎﻳﻠﻲ ﻛﻪ در ﺣﺎل ﺑﺮرﺳﻲ اﺳﺖ را در آن ﻗﺮار ﻣﻲ دﻫﻴﻢ )ﻫﺮ ﻓﺎﻳﻠﻲ ﻛﻪ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻳﻜﻲ از ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻨﻮي Favoritesدر اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر اﺳﺖ ،در ﺣﻘﻴﻘﺖ ﻳﻚ ﻓﺎﻳﻞ ﻣﺘﻨﻲ اﺳﺖ ﻛﻪ ﻣﺤﺘﻮﻳﺎت آن ﺑﺎ وﻳﺮاﻳﺸﮕﺮي ﻣﺎﻧﻨﺪ notepadﻧﻴﺰ ﻗﺎﺑﻞ ﻣﺸﺎﻫﺪه اﺳﺖ. ﭘﺲ ﻣﻲ ﺗﻮاﻧﻴﻢ در ﺑﺮﻧﺎﻣﻪ ﻣﺤﺘﻮﻳﺎت آن ﻓﺎﻳﻞ را ﺧﻮاﻧﺪه و در ﻳﻚ ﻣﺘﻐﻴﺮ رﺷﺘﻪ اي ﻗﺮار دﻫـﻴﻢ( .ﻫﻤﭽﻨـﻴﻦ ﻳـﻚ آراﻳـﻪ رﺷـﺘﻪ اي ﺑـﻪ ﻧـﺎم strLinesﺗﻌﺮﻳﻒ ﻛﺮده و ﻫﺮ ﺧﻂ از اﻃﻼﻋﺎت ﻣﺘﻐﻴﺮ strDataرا در ﻳﻚ ﻋﻨﺼﺮ از آن ﻗﺮار ﻣﻲ دﻫﻴﻢ .در آﺧـﺮ ﻫـﻢ ﻳـﻚ ﺷﻴﺊ از ﻛﻼس FileInfoاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﻪ اﻃﻼﻋﺎت ﻛﺎﻣﻞ ﻓﺎﻳﻠﻲ ﻛﻪ ﻧﺎم و آدرس آن ﺑﻪ ﻣﺘﺪ ﻓﺮﺳﺘﺎده ﻣـﻲ ﺷـﻮد دﺳﺘﺮﺳـﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ. )public void Load(string FileName { // Declare variables ;string strData ;string[] strLines ;)FileInfo objFileInfo = new FileInfo(FileName ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻓﻮﻟﺪر Favoritesﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﻧﺎم ﻫﺮ ﻓﺎﻳﻞ ﺑﺮاﺑﺮ ﺑﺎ ﻧﺎم ﮔﺰﻳﻨﻪ اي اﺳﺖ ﻛـﻪ در ﻟﻴـﺴﺖ Favorites اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﻣﺎﻧﻨﺪ .Radio Station Guideﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻧﺎم ﻓﺎﻳﻞ ﺑـﺮاي ﺗﻨﻈـﻴﻢ ﺧﺎﺻﻴﺖ Nameدر ﻛﻼس اﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻟﺒﺘﻪ ﭘﺎراﻣﺘﺮ FileNameﻛﻪ ﺑﻪ ﻛﻼس ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد ﺣـﺎوي آدرس ﻛﺎﻣـﻞ ﻓﺎﻳـﻞ C:\Documents And اﺳــﺖ ﻛــﻪ ﺷــﺎﻣﻞ آدرس ﻓﺎﻳــﻞ ،ﻧــﺎم ﻓﺎﻳــﻞ و ﭘــﺴﻮﻧﺪ ﻓﺎﻳــﻞ ﻣــﻲ ﺷــﻮد )ﺑــﺮاي ﻣﺜــﺎل Settings\Administrator\Favorites\Extensible Markup .(Language.urlﻛﺎري ﻛﻪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﻢ اﻳﻦ اﺳﺖ ﻛﻪ ﻧﺎم ﻓﺎﻳﻞ را از اﻳﻦ رﺷﺘﻪ ﺟﺪا ﻛﺮده و در ﻓﻴﻠﺪ Nameﻗﺮار دﻫﻴﻢ. ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻛﻼس FileInfoاﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﺑﺘﺪا ﺷﻴﺊ اي از اﻳﻦ ﻛﻼس ﺑﻪ ﻧﺎم objFileInfoاﻳﺠـﺎد ﻣﻲ ﻛﻨﻴﻢ و ﻫﻨﮕﺎم ﻧﻤﻮﻧﻪ ﺳﺎزي آن ،آدرس ﻓﺎﻳﻞ ﻣﻮرد ﻧﻈﺮ را ﻛﻪ در FileNameﻗﺮار دارد ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ ﺗﺎﺑﻊ ﺳﺎزﻧﺪه ﻛﻼس FileInfoﻣﻲ ﻓﺮﺳﺘﻴﻢ .ﺣﺎل ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ ﺷﻴﺊ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﻪ اﻃﻼﻋﺎت ﻣﺨﺘﻠﻒ ﻓﺎﻳـﻞ از ﻗﺒﻴـﻞ ﻧـﺎم و ﻳـﺎ آدرس آن دﺳﺘﺮﺳـﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ.
٤٢٠
ﻳﻜﻲ از ﺧﺎﺻﻴﺖ ﻫﺎي ﺷﻴﺊ ،objFileInfoﺧﺎﺻﻴﺖ Nameاﺳﺖ ﻛﻪ ﺑـﻪ وﺳـﻴﻠﻪ آن ﻣـﻲ ﺗـﻮاﻧﻴﻢ ﺑـﻪ ﻧـﺎم و ﭘـﺴﻮﻧﺪ ﻓﺎﻳـﻞ "Extensible Markup دﺳﺘﺮﺳــﻲ ﭘﻴــﺪا ﻛﻨــﻴﻢ )ﺑــﺮاي ﻣﺜــﺎل اﻳــﻦ ﺧﺎﺻــﻴﺖ ﺑــﺮاي ﻓﺎﻳــﻞ ﺑــﺎﻻ ﻣﻘــﺪار " Language.urlرا ﺑﺮﻣﻲ ﮔﺮداﻧﺪ( .در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ از اﻳﻦ ﺧﺎﺻﻴﺖ اﺳﺘﻔﺎده ﻛﺮده و ﻧﺎم و ﭘﺴﻮﻧﺪ ﻓﺎﻳﻞ را ﺑﺪﺳﺖ ﻣﻲ آورﻳﻢ، ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ SubStringﻧﺎم ﻓﺎﻳﻞ را از ﭘﺴﻮﻧﺪ آن ﺟﺪا ﻣﻲ ﻛﻨﻴﻢ. ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ دو ﭘﺎراﻣﺘﺮ را ﺑﺮاي ﻣﺘﺪ Substringﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﭘﺎراﻣﺘﺮ اول از اﻳﻦ ﻣﺘﺪ اﻧﺪﻳﺲ ﺷﺮوع ﻛﺎراﻛﺘﺮ ﻫﺎ اﺳﺖ .در اﻳﻨﺠﺎ ﻧﺎم ﻓﺎﻳﻞ از ﻛﺎراﻛﺘﺮ اول ﺷﺮوع ﻣﻲ ﺷﻮد ،ﭘﺲ اﻧﺪﻳﺲ ﺷﺮوع را ﺻﻔﺮ در ﻧﻈﺮ ﻣﻲ ﮔﻴﺮﻳﻢ .1ﭘﺎراﻣﺘﺮ دوم ﺗﻌﺪاد ﻛﺎراﻛﺘﺮ ﻫﺎﻳﻲ اﺳﺖ ﻛـﻪ ﺑﺎﻳﺪ از رﺷﺘﻪ ﺟﺪا ﺷﻮﻧﺪ .ﺑﺮاي اﻳﻨﻜﻪ ﻓﻘﻂ ﻧﺎم ﻓﺎﻳﻞ را ﺑﺪﺳﺖ آورﻳﻢ ﺑﺎﻳﺪ اﻳﻦ ﭘﺎراﻣﺘﺮ را ﺑﻪ ﺻﻮرت "ﻃﻮل ﻛﻞ رﺷﺘﻪ ﻣﻨﻬـﺎي ﻃـﻮل ﭘـﺴﻮﻧﺪ آن" وارد ﻛﻨﻴﻢ. ﺑﺮاي ﻣﺜﺎل در ﻓﺎﻳﻞ ﺑﺎﻻ ﻃﻮل ﻛﻞ رﺷﺘﻪ ي " "Extensible Markup Language.urlﺑﺮاﺑﺮ ﺑﺎ 30ﻛﺎراﻛﺘﺮ اﺳﺖ و ﻃﻮل ﭘﺴﻮﻧﺪ آن 4ﻛﺎراﻛﺘﺮ ،ﭘﺲ ﻣﺘﺪ Substringاز ﻛﺎراﻛﺘﺮ اول ﻳﻌﻨﻲ ﺣﺮف Rﺷﺮوع ﻣـﻲ ﻛﻨـﺪ و ﺗـﺎ 30-4ﻳﻌﻨـﻲ 26 ﻛﺎراﻛﺘﺮ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻋﺒﺎرت .urlاز اﻧﺘﻬﺎي رﺷﺘﻪ ﺣﺬف ﻣﻲ ﺷﻮد. // Set the Name member to the file name // minus the extension Name = objFileInfo.Name.Substring(0, objFileInfo.Name.Length;)objFileInfo.Extension.Length ﺣﺎل ﺑﺎﻳﺪ ﻣﺤﺘﻮﻳﺎت ﻓﺎﻳﻞ را ﺧﻮاﻧﺪه و در ﻣﺘﻐﻴﻴﺮ strDataﻗﺮار دﻫﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻣﺘﺪ ReadAllTextدر ﻛﻼس System.Fileاﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ ﻓﺎﻳﻞ ﻣﻮرد ﻧﻈﺮ را ﺑﺎز ﻣﻲ ﻛﻨﺪ ،ﺗﻤﺎم ﻣﺤﺘﻮﻳﺎت داﺧﻞ آن را درون ﻣﺘﻐﻴﺮ ﻣﺸﺨﺺ ﺷﺪه ﻗﺮار ﻣﻲ دﻫﺪ ،ﻓﺎﻳﻞ را ﻣﻲ ﺑﻨﺪد و ﻣﻨﺎﺑﻊ ﮔﺮﻓﺘﻪ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ آن را ﻧﻴﺰ آزاد ﻣﻲ ﻛﻨﺪ. // Read the entire contents of the file ;)strData = File.ReadAllText(FileName ﺑﻌﺪ از اﻳﻦ ﻛﻪ ﻛﺪ ﺑﺎﻻ ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ اﺟﺮا ﺷﺪ ،ﻣﺘﻐﻴﺮ strDataداراي ﻣﺘﻨﻲ ﻣﺸﺎﺑﻪ ﻣـﺘﻦ زﻳـﺮ ﺧﻮاﻫـﺪ ﺑـﻮد .اﻳـﻦ ﻣـﺘﻦ ﻣﺮﺑـﻮط ﺑـﻪ ﻣﺤﺘﻮﻳﺎت ﻓﺎﻳﻞ Extensible Markup Language.urlاﺳﺖ. ][DEFAULT BASEURL=http://www.w3.org/XML/ ][InternetShortcut URL=http://www.w3.org/XML/ Modified=B0C9EC877EB3C401E2 اﻣﺎ ﻛﺎر ﺑﺎ اﻳﻦ اﻃﻼﻋﺎت ﺑﻪ ﺻﻮرﺗﻲ ﻛﻪ در اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ ﻛﻤﻲ ﻣﺸﻜﻞ اﺳﺖ .ﺑﺮاي راﺣﺘﻲ ﻛﺎر ﺑﻬﺘﺮ اﺳﺖ آراﻳﻪ اي رﺷﺘﻪ اي اﻳﺠﺎد ﻛﺮده و ﻫﺮ ﺧﻂ از اﻳﻦ اﻃﻼﻋﺎت را درون ﻳﻜﻲ از ﻋﻨﺎﺻﺮ آن ﻗﺮار دﻫﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣـﻲ ﺗـﻮاﻧﻴﻢ از ﻣﺘـﺪ Splitدر ﻛـﻼس
1اﮔﺮ ﻳﻚ رﺷﺘﻪ را ﺑﻪ ﺻﻮرت آراﻳﻪ اي از ﻛﺎراﻛﺘﺮ ﻫﺎي ﻣﺘﻮاﻟﻲ در ﻧﻈﺮ ﺑﮕﻴﺮﻳﻢ ،ﻫﻤﺎﻧﻄﻮر ﻛﻪ در آراﻳﻪ ﻫﺎ اﻧﺪﻳﺲ ﻋﻨﺼﺮ اول ﺑﺮاﺑـﺮ ﺑـﺎ ﺻـﻔﺮ اﺳـﺖ ،در رﺷـﺘﻪ ﻫـﺎ ﻧﻴـﺰ اﻧﺪﻳﺲ ﻛﺎراﻛﺘﺮ اول ﺑﺮاﺑﺮ ﺑﺎ ﺻﻔﺮ اﺳﺖ.
٤٢١
Stringاﺳﺘﻔﺎده ﻛﻨﻴﻢ .1از ﻣﺘﺪ Splitﭼﻨﺪﻳﻦ ﻧﺴﺨﻪ ﺳﺮﺑﺎر ﮔﺬاري ﺷﺪه اﺳﺖ .ﻧﺴﺨﻪ اي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﻛﺎراﻛﺘﺮ ﻫﺎﻳﻲ ﻛﻪ ﺑﺎﻳﺪ ﺑﻪ ﻋﻨﻮان ﺟﺪا ﻛﻨﻨﺪه در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﻮﻧﺪ را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺑﺨﺸﻬﺎي ﻗﺒﻠﻲ ﻧﻴﺰ ﮔﻔﺘﻢ ﻛﺎراﻛﺘﺮ ﻛﻨﺘﺮﻟﻲ ' '\nدر C#ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن ﺧﻂ ﺟﺪﻳﺪ ﺑﻪ ﻛﺎر ﻣﻲ رود .در اﻳﻨﺠﺎ ﻧﻴﺰ ﺑﺮاي اﻳﻦ ﻛﻪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻣﺘﻦ داﺧﻞ ) strDataﻳﺎ ﻣﺤﺘﻮﻳﺎت ﻓﺎﻳﻠﻲ ﻛﻪ ﺧﻮاﻧﺪه ﺷﺪه( ﺑﺎﻳﺪ ﺑﺮ اﺳﺎس ﺧﻂ ﺟﺪﻳﺪ ﺟـﺪا ﺷـﻮﻧﺪ اﻳـﻦ ﻛﺎراﻛﺘﺮ را ﺑﻪ ﻋﻨﻮان ﺟﺪا ﻛﻨﻨﺪه ﺑﻪ ﻣﺘﺪ Splitﻣﻲ ﻓﺮﺳﺘﻴﻢ. // Split the lines of data in the file ;)'strLines = strData.Split('\n ﺑﻌﺪ از اﺟﺮاي اﻳﻦ ﺧﻂ از ﺑﺮﻧﺎﻣﻪ ،ﻫﺮ ﻳﻚ از ﺧﻄﻮط ﻓﺎﻳﻞ ﻣﻮرد ﺑﺮرﺳﻲ ،در ﻳﻜﻲ از ﻋﻨﺎﺻـﺮ آراﻳـﻪ ي strLinesﻗـﺮار ﻣـﻲ ﮔﻴـﺮد. ﺳﭙﺲ ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﺣﻠﻘﻪ ي foreachﻋﻨﺎﺻﺮ آراﻳﻪ ي strLinesرا ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ﺗـﺎ ﺑـﻪ ﺧﻄـﻲ ﺑﺮﺳـﻴﻢ ﻛـﻪ ﺑـﺎ ﻋﺒﺎرت "= "URLﺷﺮوع ﺷﻮد .ﺑﺮاي ﺗﺸﺨﻴﺺ اﻳﻨﻜﻪ ﻳﻚ ﻣﺘﻐﻴﺮ رﺷﺘﻪ اي ﺑﺎ ﻋﺒﺎرت ﺧﺎﺻﻲ ﺷﺮوع ﻣﻲ ﺷﻮد ﻳﺎ ﻧﻪ ﻣـﻲ ﺗـﻮاﻧﻴﻢ از ﻣﺘـﺪ StartsWithدر ﻛﻼس Stringاﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ ﻳﻚ ﻋﺒﺎرت را درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ و ﻳﻚ ﻣﻘـﺪار Booleanرا ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .اﮔﺮ اﻳﻦ ﻣﻘﺪار ﺑﺮاﺑﺮ ﺑﺎ trueﺑﻮد ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ رﺷﺘﻪ ي ﻣﻮرد ﻧﻈﺮ ﺑﺎ ﻋﺒﺎرت ﻣﺸﺨﺺ ﺷـﺪه ﺷـﺮوع ﻣـﻲ ﺷـﻮد. ﭘﺲ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻧﺘﻴﺠﻪ ي ﺑﺮﮔﺸﺘﻲ از اﻳﻦ ﻣﺘﺪ را ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ دﺳﺘﻮر ifﺑﺮرﺳﻲ ﻛﻨﻴﻢ. // Process each line looking for the URL )foreach(string strLine in strLines { =// Does the line of data start with URL ))"=if (strLine.StartsWith("URL { اﮔﺮ ﺧﻄﻲ ﻛﻪ در ﺣﺎل ﺑﺮرﺳﻲ آن ﻫﺴﺘﻴﻢ ﺑﺎ ﻋﺒﺎرت "= "URLﺷﺮوع ﺷﻮد ،ﻳﻌﻨﻲ آدرس ﻣﻮرد ﻧﻈﺮ ﻣﺎ ﻛـﻪ ﺑﺎﻳـﺪ در ﻓﻴﻠـﺪ Urlﻗـﺮار ﮔﻴﺮد در اﻳﻦ ﺧﻂ ﻗﺮار دارد .ﭘﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ،Substringآن را ﺑﺪﺳﺖ آورده و در ﻓﻴﻠﺪ urlﻗﺮار ﻣﻲ دﻫـﻴﻢ .ﺑـﻪ ﻋﻠـﺖ اﻳﻨﻜﻪ ﭼﻬﺎر ﻛﺎراﻛﺘﺮ اوﻟﻲ ﺧﻂ )ﻛﺎراﻛﺘﺮ ﻫﺎي 0ﺗﺎ (3ﻣﺤﺘﻮي ﻋﺒﺎرت "= "URLﻫﺴﺘﻨﺪ ،ﭘﺲ ﺑﻪ ﺗﺎﺑﻊ Substringﻣﻲ ﮔـﻮﻳﻴﻢ ﻛﻪ از ﻛﺎراﻛﺘﺮ ﭘﻨﺠﻢ ﺗﺎ اﻧﺘﻬﺎي رﺷﺘﻪ را ﺑﺮﮔﺮداﻧﺪ و در ﻓﻴﻠﺪ Urlﻗﺮار دﻫﺪ. // Yes, Set the Url member to the actual URL ;)Url = strLine.Substring(4 // Exit the foreach loop ;break ﺑﺮرﺳﻲ ﺑﻘﻴﻪ ﻋﻨﺎﺻﺮ آراﻳﻪ ﻧﻴﺰ ﻛﺎر ﺑﻴﻬﻮده اي اﺳﺖ ،زﻳﺮا ﺧﻂ ﻣﻮرد ﻧﻈﺮﻣﺎن را ﭘﻴﺪا ﻛﺮده اﻳﻢ .ﭘﺲ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر breakاز ﺣﻠﻘـﻪ ي foreachﺧﺎرج ﻣﻲ ﺷﻮﻳﻢ.
1اﮔﺮ ﺑﻪ ﻛﺪ دﻗﺖ ﻛﻨﻴﺪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻣﺘﺪ Splitاز ﻣﺘﻐﻴﻴﺮ strDataاﺳﺘﻔﺎده ﻛﺮده اﻳﻢ .دﻟﻴﻠـﻲ اﻳـﻦ اﻣـﺮ ﻧﻴـﺰ اﻳـﻦ اﺳـﺖ ﻛـﻪ strDataرا ﻣﻲ ﺗﻮان ﺑﻪ ﺻﻮرت ﺷﻴﺊ اي در ﻧﻈﺮ ﮔﺮﻓﺖ ﻛﻪ از ﻛﻼس Stringﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﺪه اﺳﺖ.
٤٢٢
ﭘﻴﺪا ﻛﺮدن ﮔﺰﻳﻨﻪ ﻫﺎي :Favorites ﺑﺮاي ﺗﻜﻤﻴﻞ ﺷﺪن ﻗﺴﻤﺖ back-endﺑﺮﻧﺎﻣﻪ ،ﺑﻪ ﻛﻼس دﻳﮕﺮي ﻧﻴﺎز دارﻳﺪ ﻛﻪ ﺑﺘﻮاﻧﺪ آراﻳﻪ اي از اﺷﻴﺎي WebFavorite را در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ .اﻳﻦ ﻛﻼس ﺑﺎﻳﺪ ﺑﺘﻮاﻧﺪ ﻓﻮﻟﺪر Favoritesرا ﺑﺮرﺳﻲ ﻛﺮده و ﺑﺎزاي ﻫﺮ ﻓﺎﻳﻠﻲ ﻛﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ ﻳﻚ ﺷﻴﺊ ﺟﺪﻳﺪ از ﻧﻮع WebFavoriteﻣﺘﻨﺎﺳﺐ ﺑﺎ اﻃﻼﻋﺎت ﻓﺎﻳﻞ اﻳﺠﺎد ﻛﺮده و ﺑﻪ آراﻳﻪ اﺿﺎﻓﻪ ﻛﻨﺪ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ﭼﻨﻴﻦ ﻛﻼﺳﻲ را اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻛﻼس Favorites (1ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي ،Solution Explorerﻛﻼس ﺟﺪﻳﺪي ﺑﻪ ﻧﺎم Favoritesاﻳﺠﺎد ﻛﻨﻴﺪ. (2ﺣﺎل ﺑﺎﻳﺪ ﻓﻴﻠﺪي از ﻧﻮع ArrayListدر ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﻨﻴﻢ ﺗﺎ اﺷﻴﺎﻳﻲ ﻛﻪ از ﻧﻮع WebFavoriteاﻳﺠـﺎد ﻣـﻲ ﺷﻮﻧﺪ را در آن ﻗﺮار دﻫﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺪ زﻳﺮ را ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ: class Favorites { // Public member public System.Collections.ArrayList FavoriteCollection ;)(= new ArrayList (3در اﻳﻦ ﻛﻼس ﺑﻪ ﺧﺎﺻﻴﺘﻲ ﻧﻴﺎز دارﻳﻢ ﺗﺎ آدرس ﻓﻮﻟﺪر Favoritesرا در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻛﺎرﺑﺮ ﺑﺮﮔﺮداﻧﺪ ﺑﻨﺎﺑﺮاﻳﻦ اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﺎﻳﺪ از ﻧﻮع ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ ﺑﺎﺷﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ: public string FavoritesFolder { get { // Return the path to the user's Favorites folder (return Environment.GetFolderPath ;)Environment.SpecialFolder.Favorites } } (4در آﺧﺮ ﻧﻴﺰ ﺑﺎﻳﺪ ﻣﺘﺪي ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﻛﻪ ﻓﺎﻳﻠﻬﺎي درون ﻓﻮﻟﺪر Favoritesرا ﺑﺮرﺳﻲ ﻛﻨﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﺎﻳﻠﻲ را ﭘﻴﺪا ﻛﺮد ،ﻳﻚ ﺷﻴﺊ WebFavoriteﺑﺮاي آن اﻳﺠﺎد ﻛﺮده و ﺑﻪ ArrayListاﺿﺎﻓﻪ ﻛﻨﺪ .در اﻳـﻦ ﻛـﻼس دو ﻧﺴﺨﻪ از اﻳﻦ ﻣﺘﺪ را اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ؛ ﻳﻜـﻲ از آﻧﻬـﺎ ﺑـﺮاي ﺑﺪﺳـﺖ آوردن آدرس ﻓﻮﻟـﺪر ،Favoritesاز ﺧﺎﺻـﻴﺖ FavoritesFolderدر ﻛﻼس اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ ،دﻳﮕﺮي اﻳﻦ آدرس را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ .ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن دو ﻣﺘﺪ ﺑﻪ ﻛﻼس ،ﻛﺪ زﻳﺮ را در ﻛﻼس ﻗﺮار دﻫﻴﺪ: )(public void ScanFavorites {
٤٢٣
// Scan the favorites folder ;)ScanFavorites(this.FavoritesFolder } )public void ScanFavorites(string FolderName { // Process each file in the Favorites folder foreach (string strFile in ))System.IO.Directory.GetFiles(FolderName { // If the file has a url extension... ))if (strFile.EndsWith(".url",true,null { // Create and use a new instance // of the WebFavorite class = WebFavorite objWebFavorite ;)(new WebFavorite // Load the file information ;)objWebFavorite.Load(strFile // Add the object to the collection ;)FavoriteCollection.Add(objWebFavorite } } } ﺑﺮاي اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي اﺻﻠﻲ ،ﺑﺎﻳﺪ ﺷﻴﺊ اي از ﻧـﻮع Favoritesاﻳﺠـﺎد ﻛـﺮده ،ﻓﻮﻟـﺪر Favoritesرا ﺟـﺴﺘﺠﻮ ﻛﻨﻴـﺪ و ﻋﻨﺎﺻﺮي ﻛﻪ در آن ﻓﻮﻟﺪر ﭘﻴﺪا ﻣﻲ ﺷﻮد را ﺑﻪ ﻟﻴﺴﺖ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .اﻳﻦ ﻛﺎر در اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ اﻧﺠﺎم ﺧﻮاﻫﺪ ﺷﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻓﺼﻞ ﭘﻨﺠﻢ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﺑﺮاي اﻳﺠﺎد ﻳﻚ آراﻳﻪ ﻛﻪ ﻃﻮل ﻣﺸﺨﺼﻲ ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ و ﺑﺘﻮاﻧﻴﺪ ﺑﻪ راﺣﺘﻲ اﺷﻴﺎﻳﻲ را ﺑـﻪ آن اﺿﺎﻓﻪ ﻛﺮده و ﻳﺎ ﺣﺬف ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ از ﻛﻼس ArrayListاﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﺷـﻴﺊ اي از اﻳـﻦ ﻧـﻮع را اﻳﺠـﺎد ﻣـﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ اﺷﻴﺎي اﻳﺠﺎد ﺷﺪه از ﻧﻮع ) WebFavoriteﻛﻪ ﺗﻌﺪاد آﻧﻬﺎ ﻧﻴﺰ ﻣﺸﺨﺺ ﻧﻴﺴﺖ( را در آن ﻗﺮار دﻫﻴﻢ. اﻣﺎ ﺳﻮال اﻳﻨﺠﺎﺳﺖ ﻛﻪ ﭼﮕﻮﻧﻪ اﻳﻦ ﻟﻴﺴﺖ را ﭘـﺮ ﻛﻨـﻴﻢ؟ ﺧـﻮب ،در ﻛـﻼس Favoritesﻣﺘـﺪي ﺳـﺮﺑﺎر ﮔـﺬاري ﺷـﺪه ﺑـﻪ ﻧـﺎم ScanFavoritesاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ .ﻧﺴﺨﻪ ي دوم اﻳﻦ ﻣﺘﺪ آدرس ﻓﻮﻟﺪري را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻣـﻲ ﻛﻨـﺪ و درون آن ﻓﻮﻟﺪر ﺑﻪ دﻧﺒﺎل ﻓﺎﻳﻠﻬﺎﻳﻲ ﺑﺎ ﭘﺴﻮﻧﺪ .urlﻣﻲ ﮔﺮدد .اﻣﺎم ﺑﻬﺘﺮ اﺳﺖ ﻗﺒـﻞ از ﺑﺮرﺳـﻲ ﻧﺤـﻮه ﻛـﺎر اﻳـﻦ ﻣﺘـﺪ ،ﻧﺤـﻮه ﻛـﺎرﻛﺮد ﺧﺎﺻـﻴﺖ FavoritesFolderرا ﺑﺮرﺳﻲ ﻛﻨﻴﻢ. ﺑﻪ دﻟﻴﻞ اﻳﻨﻜﻪ ﺑﺮ ﺣﺴﺐ ﻛﺎرﺑﺮي ﻛﻪ ﻫﻢ اﻛﻨﻮن در ﺣﺎل اﺳﺘﻔﺎده از ﻛﺎﻣﭙﻴﻮﺗﺮ اﺳﺖ ﻣﻤﻜﻦ اﺳﺖ آدرس ﻓﻮﻟـﺪر Favoritesﺗﻐﻴﻴـﺮ ﻛﻨــﺪ ،ﺑﻬﺘــﺮﻳﻦ راه ﺑــﺮاي ﺑﺪﺳــﺖ آوردن آدرس اﻳــﻦ ﻓﻮﻟــﺪر ،ﭘﺮﺳــﻴﺪن آن از وﻳﻨــﺪوز اﺳــﺖ .ﺑــﺮاي اﻳــﻦ ﻛــﺎر ﻣــﻲ ﺗــﻮاﻧﻴﻢ از ﻣﺘــﺪ GetFolderPathﻛﻪ در ﻛﻼس System.Environmentﻗﺮار دارد اﺳﺘﻔﺎده ﻛﻨﻴﻢ: public string FavoritesFolder
٤٢٤
{ get { // Return the path to the user's Favorites folder (return Environment.GetFolderPath ;)Environment.SpecialFolder.Favorites } } اﻳﻦ ﻣﺘﺪ ﻳﻜﻲ از ﮔﺰﻳﻨﻪ ﻫﺎي ﺷﻤﺎرﻧﺪه ي Environment.SpecialFolderرا ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ و آدرس آن ﻓﻮﻟﺪر را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .ﺷﻤﺎرﻧﺪه ي SpecialFolderﺣﺎوي ﻧﺎم ﺗﻌﺪادي از ﻓﻮﻟـﺪرﻫﺎي ﺧـﺎص اﺳـﺖ ﻛـﻪ ﻣﻌﻤـﻮﻻً ﻫﻨﮕﺎم ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ زﻳﺎد ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد )ﻣﺎﻧﻨﺪ ﻓﻮﻟﺪر My Documentsو ﻳﺎ .(Program Files ﺑﺮاي اﻳﻨﻜﻪ در ﺑﺮﻧﺎﻣﻪ ي اﺻﻠﻲ از ﻛﻼس Favoritesﺑﺨﻮاﻫﻴﻢ ﺗﺎ ﺑﺎ ﺟﺴﺘﺠﻮي ﻓﻮﻟﺪر ،Favoritesﻟﻴـﺴﺖ ﺧـﻮد را ﭘـﺮ ﻛﻨـــﺪ ﺑﺎﻳـــﺪ ﻧـــﺴﺨﻪ ي اول از ﻣﺘـــﺪ ScanFavoritesرا ﻓﺮاﺧـــﻮاﻧﻲ ﻛﻨـــﻴﻢ .اﻳـــﻦ ﻧـــﺴﺨﻪ ﺑـــﺎ اﺳـــﺘﻔﺎده از ﺧﺎﺻـــﻴﺖ ،FavoritesFolderآدرس ﻓﻮﻟﺪر Favoritesرا ﺑﺪﺳﺖ آورده و آن را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ ﻧﺴﺨﻪ ي دوم از اﻳـﻦ ﻣﺘﺪ ﻣﻲ ﻓﺮﺳﺘﺪ. )(public void ScanFavorites { // Scan the favorites folder ;)ScanFavorites(this.FavoritesFolder } ﻛﺎري ﻛﻪ ﻧﺴﺨﻪ ي دوم از ﻣﺘﺪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻓﺎﻳﻠﻬﺎي ﻣﻮﺟﻮد در آدرﺳﻲ ﻛﻪ ﺑﻪ آن ﻓﺮﺳﺘﺎده ﺷﺪه اﺳﺖ را ﺑﺪﺳـﺖ آورده و آﻧﻬﺎ را ﭘـﺮدازش ﻛﻨـﺪ .ﺑـﺮاي ﺑﺪﺳـﺖ آوردن ﻟﻴـﺴﺖ ﻓﺎﻳﻠﻬـﺎي ﻣﻮﺟـﻮد در آن ﻓﻮﻟـﺪر ﻣـﻲ ﺗـﻮاﻧﻴﻢ از ﻣﺘـﺪ GetFilesدر ﻛـﻼس System.IO.Directoryاﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ آدرس ﻓﻮﻟﺪري را ﻛﻪ ﺑﺎﻳﺪ ﺑﺮرﺳﻲ ﻛﻨﺪ را ﺑﻪ ﻋﻨـﻮان ﭘـﺎراﻣﺘﺮ درﻳﺎﻓـﺖ ﻣﻲ ﻛﻨﺪ و آراﻳﻪ اي از ﻧﺎم ﻓﺎﻳﻠﻬﺎي ﻣﻮﺟﻮد در آن را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ اﺳـﺘﻔﺎده از ﻳـﻚ ﺣﻠﻘـﻪ ي foreach آﻧﻬﺎ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ .ﻣﺘﻐﻴﺮي را از ﻧﻮع رﺷﺘﻪ اي و ﺑﻪ ﻧﺎم strFilesدر ﺣﻠﻘﻪ ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﺎ ﻫﺮ ﺑﺎر ﮔﺮدش ﺣﻠﻘﻪ ﻧﺎم ﻳﻜﻲ از ﻓﺎﻳﻞ ﻫﺎ در آن ﻗﺮار ﮔﻴﺮد. // Process each file in the Favorites folder foreach (string strFile in ))System.IO.Directory.GetFiles(FolderName { درون ﺣﻠﻘﻪ ي foreachاﺑﺘﺪا ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ آﻳﺎ ﭘﺴﻮﻧﺪ ﻓﺎﻳﻞ ﺑﺮاﺑﺮ ﺑﺎ .urlاﺳﺖ ﻳﺎ ﻧﻪ؟ ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗـﻮاﻧﻴﻢ از ﻣﺘـﺪ EndsWithدر ﻛﻼس Stringاﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﻣﺘﺪ EndsWithﻳﻚ ﻣﺘﺪ ﺳﺮﺑﺎر ﮔﺬاري ﺷﺪه اﺳﺖ و ﻧﺴﺨﻪ اي ﻛـﻪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﺳﻪ ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ .ﭘﺎراﻣﺘﺮ اول ﻋﺒﺎرﺗﻲ اﺳﺖ ﻛﻪ ﺑﺎﻳﺪ ﺑﺎ اﻧﺘﻬﺎي رﺷﺘﻪ ﻣﻘﺎﻳﺴﻪ ﺷﻮد ،در اﻳﻨﺠـﺎ ﻋﺒﺎرت " ".urlرا ﺑﺮاي اﻳﻦ ﭘﺎراﻣﺘﺮ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .ﭘﺎراﻣﺘﺮ دوم ﻳﻚ ﻣﻘﺪار Booleanاﺳﺖ ﻛﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳـﺎ ﻣﺘـﺪ EndsWithدر ﻫﻨﮕﺎم ﻣﻘﺎﻳﺴﻪ ﺣﺎﻟﺖ ﺣﺮوف را ﻧﻴﺰ در ﻧﻈﺮ ﺑﮕﻴﺮد ﻳﺎ ﻧﻪ؟ در اﻳﻦ ﻗﺴﻤﺖ ﻧﻤﻲ ﺧﻮاﻫﻴﻢ ﻣﻘﺎﻳﺴﻪ ي ﻣـﺘﻦ ﺑـﻪ ﺻـﻮرت ﺣﺴﺎس ﺑﻪ ﺑﺰرﮔﻲ و ﻳﺎ ﻛﻮﭼﻜﻲ ﺣﺮوف اﻧﺠﺎم ﺷﻮد ﭘﺲ ﻣﻘﺪار trueرا ﺑﺮاي اﻳﻦ ﭘﺎراﻣﺘﺮ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .ﭘﺎراﻣﺘﺮ ﺳﻮم ﻫﻢ ﺷـﻴﺊ اي
٤٢٥
را از ﻧﻮع System.Globalization.CultureInfoدرﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ ،اﻳﻦ ﺷﻴﺊ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﺗﻨﻈﻴﻤﺎت ﻣﺤﻠﻲ اﺳﺖ ﻛﻪ ﺑﺎﻳﺪ ﻫﻨﮕﺎم ﻣﻘﺎﻳﺴﻪ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﻮﻧﺪ ،اﻣﺎ در اﻳﻨﺠﺎ ﺑﺮاي اﻳﻨﻜﻪ ﺗﻨﻈﻴﻤﺎت ﻣﺤﻠﻲ ﭘﻴﺶ ﻓـﺮض ﺑـﻪ ﻛـﺎر ﮔﺮﻓﺘـﻪ ﺷـﻮد از ﻋﺒﺎرت nullﺑﺮاي اﻳﻦ ﭘﺎراﻣﺘﺮ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ. // If the file has a url extension... ))if (strFile.EndsWith(".url",true,null { اﮔﺮ ﻓﺎﻳﻠﻲ ﻛﻪ در ﺣﺎل ﺑﺮرﺳﻲ اﺳﺖ داراي ﭘـﺴﻮﻧﺪ .urlﺑﺎﺷـﺪ ﺑﺎﻳـﺪ ﺷـﻴﺊ ﺟﺪﻳـﺪي از ﻧـﻮع WebFavoriteاﻳﺠـﺎد ﻛﻨﻴـﺪ، اﻃﻼﻋﺎت آن ﻓﺎﻳﻞ را در داﺧﻞ ﺷﻴﺊ ﻗﺮار دﻫﻴﺪ و ﺳﭙﺲ ﺷﻴﺊ را ﺑﻪ آراﻳﻪ ي Favoritesاﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛـﺎر اﺑﺘـﺪا ﺑﺎﻳـﺪ ﺷﻴﺊ اي را از ﻧﻮع WebFavoriteاﻳﺠﺎد ﻛﺮده و ﺳﭙﺲ ﻣﺘﺪ Loadرا در آن ﺷﻴﺊ ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴـﺪ و آدرس ﻓﺎﻳـﻞ را ﺑـﻪ آن ﻣﺘﺪ ﺑﻔﺮﺳﺘﻴﺪ ،در اﻧﺘﻬﺎ ﻧﻴﺰ ﺷﻴﺊ را در آراﻳﻪ ﻗﺮار دﻫﻴﺪ. // Create and use a new instance // of the WebFavorite class ;)(WebFavorite objWebFavorite = new WebFavorite // Load the file information ;)objWebFavorite.Load(strFile // Add the object to the collection ;)FavoriteCollection.Add(objWebFavorite در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺎ اﺳﺘﻔﺎده از ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﺑﺨﺶ اﻳﺠﺎد ﻛﺮدﻳﻢ ﻟﻴﺴﺖ داﺧﻞ ﻓﺮم را ﺑﺎ ﻓﺎﻳﻠﻬـﺎي ﻣﻮﺟـﻮد در ﻓﻮﻟـﺪر Favoritesﻛﺎرﺑﺮ ﻛﺎﻣﻞ ﻣﻲ ﻛﻨﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﺷﻴﺊ اي از ﻛﻼس Favorites (1در ﻓﺮم اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ ،روي ﻗﺴﻤﺘﻲ ﺧﺎﻟﻲ از ﻓﺮم دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Loadآن اﻳﺠﺎد ﺷـﻮد .ﺳـﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ. )private void Form1_Load(object sender, EventArgs e { // Create a new instance of the Favorites class ;)(Favorites objFavorites = new Favorites // Scan the Favorites folder ;)(objFavorites.ScanFavorites // Process each objWebFavorite object // in the Favorites collection foreach (WebFavorite objWebFavorite in )objFavorites.FavoriteCollection
٤٢٦
{ // Declare a ListViewItem object ListViewItem objListViewItem = new ListViewItem(); // Set the properties of ListViewItem object objListViewItem.Text = objWebFavorite.Name; objListViewItem.SubItems.Add(objWebFavorite.Url); // Add the ListViewItem object to the ListView lstFavorites.Items.Add(objListViewItem); } } . ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد17-10 ﭘﻨﺠﺮه اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ،( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ2
17-10 ﺷﻜﻞ
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اﻳﺠﺎد ﻛﺮده و ﺳـﭙﺲ ﻧـﺴﺨﻪ ي ﺑـﺪون ﭘـﺎراﻣﺘﺮ از ﻣﺘـﺪFavorites اﺑﺘﺪا ﺷﻴﺊ را از ﻧﻮع، ﻓﺮمLoad در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد آراﻳـﻪ ي، ﺷـﺪن ﻓـﺮمload ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ از ﻛﻼس ﻣﻲ ﺧـﻮاﻫﻴﻢ ﻛـﻪ ﻫﻨﮕـﺎم. را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢScanFavorites Favorites اﻳﺠﺎد ﻛﺮده و ﺑﺎزاي ﻫﺮ ﻳﻚ از ﮔﺰﻳﻨﻪ ﻫﺎﻳﻲ ﻛﻪ در ﻓﻮﻟﺪرFavoritesCollection ﺟﺪﻳﺪي ﺑﻪ ﻧﺎم . ﺗﺸﻜﻴﻞ دﻫﺪ و آن را ﺑﻪ آراﻳﻪ اﺿﺎﻓﻪ ﻛﻨﺪWebFavorite دارد ﻳﻚ ﺷﻴﺊ از ﻧﻮع // Create a new instance of the Favorites class Favorites objFavorites = new Favorites(); // Scan the Favorites folder objFavorites.ScanFavorites();
٤٢٧
ﺑﻌـــﺪ از اﺗﻤـــﺎم ﻣﺘـــﺪ ،ScanFavoritesآراﻳـــﻪ ي FavoritesCollectionﺑـــﺎ ﻋﻨﺎﺻـــﺮي از ﻧـــﻮع WebFavoriteﭘﺮ ﺷﺪه اﺳﺖ .ﺣﺎل ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻋﻨﺎﺻﺮ اﻳﻦ آراﻳﻪ در ﻛﻼس ،Favoritesآﻳﺘﻢ ﻫﺎي درون ﻟﻴﺴﺖ را ﻛﺎﻣﻞ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﺎﻧﻨﺪ ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ از ﻳﻚ ﺣﻠﻘﻪ ي foreachاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﺘـﻮاﻧﻴﻢ ﺗﻤـﺎم ﻋﻨﺎﺻـﺮ آراﻳـﻪ را ﭘﻴﻤﺎﻳﺶ ﻛﻨﻴﻢ. ﻗﺒــﻞ از اداﻣــﻪ ﺑﻬﺘــﺮ اﺳــﺖ ﺑــﻪ اﻳــﻦ ﻧﻜﺘــﻪ ﺗﻮﺟــﻪ ﻛﻨﻴــﺪ ﻛــﻪ آﻳــﺘﻢ ﻫــﺎي درون ﻛﻨﺘــﺮل ،ListViewاﺷــﻴﺎي از ﻛــﻼس ListViewItemﻫﺴﺘﻨﺪ ﻛﻪ در ﻳﻚ آراﻳﻪ ﻗﺮار دارﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي اﻳﻨﻜﻪ ﻳﻚ آﻳﺘﻢ ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل اﺿﺎﻓﻪ ﻛﻨﻴﻢ ،ﺑﺎﻳﺪ ﻳﻚ ﺷﻴﺊ از ﻧﻮع ListViewItemاﻳﺠﺎد ﻛﺮده و آن را ﺑﻪ ﻛﻨﺘﺮل اﺿﺎﻓﻪ ﻛﻨﻴﻢ. درون ﺣﻠﻘﻪ ي foreachاﺑﺘﺪا ﺷﻴﺊ اي را از ﻛﻼس ListViewItemﻧﻤﻮﻧﻪ ﺳﺎزي ﻛﺮده و ﺧﺎﺻـﻴﺖ Textآن را ﺑـﺎ ﺗﻮﺟﻪ ﺑﻪ ﻓﻴﻠﺪ Nameدر ﻛﻼس WebFavoriteﻛﺎﻣﻞ ﻣﻲ ﻛﻨﻴﻢ .ﺳﭙﺲ آدرس ﻟﻴﻨﻚ ﻣﻮرد ﻧﻈﺮ را ﻧﻴﺰ ﻛﻪ در ﻓﻴﻠﺪ Urlﻗﺮار دارد ﺑﻪ ﺧﺎﺻﻴﺖ SubItemsاز ListViewItemاﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ. // Declare a ListViewItem object ;)(ListViewItem objListViewItem = new ListViewItem // Set the properties of ListViewItem object ;objListViewItem.Text = objWebFavorite.Name ;)objListViewItem.SubItems.Add(objWebFavorite.Url در اﻧﺘﻬﺎ ﻧﻴﺰ ﺷﻴﺊ ListViewItemرا ﺑﻪ ﺧﺎﺻﻴﺖ Itemsاز ﻛﻨﺘﺮل ListViewاﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ در ﻓﺮم ﻧﻤـﺎﻳﺶ داده ﺷﻮد. // Add the ListViewItem object to the ListView ;)lstFavorites.Items.Add(objListViewItem ﺧﻮب ،ﺗﺎ اﻳﻨﺠﺎ ﺑﺮﻧﺎﻣﻪ ي ﻣﺎ ﻗﺎدر اﺳﺖ ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻣﻨﻮي Favoritesاﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر را ﺑﻪ ﺻﻮرت ﻳـﻚ ﻟﻴـﺴﺖ در ﻓﺮم ﻧﻤﺎﻳﺶ دﻫﺪ ،اﻣﺎ ﻫﻨﻮز ﻧﻤﻲ ﺗﻮاﻧﺪ ﺳﺎﻳﺘﻲ ﻛﻪ اﻳﻦ ﻟﻴﻨﻚ ﻫﺎ ﺑﻪ آن اﺷﺎره ﻣﻲ ﻛﻨﻨﺪ را ﺑﺎز ﻛﻨﺪ .ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻛﺎر را ﻧﻴـﺰ در ﺑﺨـﺶ ﺑﻌﺪي ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد.
ﻣﺸﺎﻫﺪه ي ﻟﻴﻨﻚ ﻫﺎ: در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻗﺎﺑﻠﻴﺘﻲ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ ﺗﺎ ﻛﺎرﺑﺮ ﺑﺘﻮاﻧﺪ ﺑﺎ اﻧﺘﺨﺎب ﻳـﻚ ﻟﻴﻨـﻚ از ﻟﻴـﺴﺖ ،ﻣﺤﺘﻮﻳـﺎت آن ﻟﻴﻨﻚ را درون اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﻣﺸﺎﻫﺪه ﻛﻨﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻣﺸﺎﻫﺪه ي ﻟﻴﻨﻚ ﻫﺎ (1ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻣﺮﺑﻮط ﺑﻪ Form1ﺑﺮوﻳﺪ و ﻛﻨﺘﺮل lstFavoritesرا از ﻓﺮم اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺳﭙﺲ در ﭘﻨﺠﺮه ي Propertiesروي آﻳﻜﻮن Eventsﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻟﻴﺴﺘﻲ از روﻳﺪاد اي اﻳﻦ ﻛﻨﺘـﺮل ﻧﻤـﺎﻳﺶ داده ﺷـﻮد .در
٤٢٨
اﻳﻦ ﻟﻴﺴﺖ روﻳﺪاد Clickرا ﭘﻴﺪا ﻛﺮده و روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ آن اﻳﺠﺎد ﺷﻮد ،ﺳﭙﺲ ﻛﺪ زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )private void lstFavorites_Click(object sender, EventArgs e { // Update the link label control Text property lnkUrl.Text = "Visit " + ;lstFavorites.SelectedItems[0].Text // Clear the default hyperlink ;)(lnkUrl.Links.Clear // Add the selected hyperlink to the LinkCollection lnkUrl.Links.Add(6, lstFavorites.SelectedItems[0].Text.Length, ;)lstFavorites.SelectedItems[0].SubItems[1].Text } (2ﻣﺠﺪداً ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ و روي ﻛﻨﺘﺮل LinkLabelدو ﺑﺎر ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﻣﺘـﺪ ﻣﺮﺑـﻮط ﺑـﻪ روﻳـﺪاد LinkClickedآن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void lnkUrl_LinkClicked(object sender, )LinkLabelLinkClickedEventArgs e { (System.Diagnostics.Process.Start ;) )(e.Link.LinkData.ToString } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي ﻫﺮ ﻛﺪام از آﻳﺘﻢ ﻫﺎي درون ﻟﻴﺴﺖ ،ﻛﻨﺘﺮل ﭘﺎﻳﻴﻦ ﻓـﺮم ﺗﻐﻴﻴـﺮ ﻛﺮده ﺗﺎ ﻧﺎم آن آﻳﺘﻢ را ﻧﻤﺎﻳﺶ دﻫﺪ )ﺷﻜﻞ 15-10را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ( .اﮔﺮ روي اﻳﻦ ﻧﺎم ﻛﻠﻴﻚ ﻛﻨﻴﺪ ،اﻳﻨﺘﺮﻧـﺖ اﻛـﺴﭙﻠﻮرر ﺑـﺎز ﺷﺪه و ﺳﺎﻳﺖ ﻣﺮﺑﻮط ﺑﻪ آن را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻨﮕﺎﻣﻲ ﻛﻪ روي ﻳﻜﻲ از آﻳﺘﻢ ﻫﺎي درون ﻛﻨﺘﺮل ListViewﻛﻠﻴﻚ ﻣﻲ ﻛﻨﻴﺪ ،ﻣﺘﺪ ﻣﺮﺑـﻮط ﺑـﻪ روﻳـﺪاد Clickاﻳـﻦ ﻛﻨﺘـﺮل ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد .در اﻳﻦ ﻣﺘﺪ ﻛﺪي را ﻗﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ ﺑﺮ اﺳﺎس آﻳﺘﻤﻲ ﻛﻪ در ﻟﻴﺴﺖ اﻧﺘﺨﺎب ﺷﺪه اﺳـﺖ ﻣـﺘﻦ ﻣﻨﺎﺳـﺒﻲ را در ﻛﻨﺘـﺮل LinkLabelﻧﻤﺎﻳﺶ دﻫﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﻫﺮ ﻳﻚ از آﻳﺘﻢ ﻫﺎي درون ﻛﻨﺘﺮل ListViewﻳﻚ ﺷﻴﺊ از ﻛـﻼس ListViewItemاﺳـﺖ .ﺑـﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ آﻳﺘﻤﻲ ﻛﻪ ﻫﻢ اﻛﻨﻮن در ﻟﻴﺴﺖ اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ﻣﻲ ﺗﻮاﻧﻴﻢ از ﺧﺎﺻﻴﺖ SelectedItemsاﺳﺘﻔﺎده ﻛﻨﻴﻢ ﻛﻪ ﺑـﻪ ﺻﻮرت آراﻳﻪ اي از ﻧﻮع ListViewItemاﺳﺖ .دﻟﻴﻞ آراﻳﻪ اي ﺑﻮدن اﻳﻦ ﺧﺎﺻﻴﺖ اﻳﻦ اﺳﺖ ﻛﻪ در ﻛﻨﺘـﺮل ListView ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻴﺶ از ﻳﻚ آﻳﺘﻢ را از ﻟﻴﺴﺖ اﻧﺘﺨﺎب ﻛﻨﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ ﺧﺎﺻﻴﺖ SelectedItemsﺑﺎﻳﺪ ﺑﻪ ﺻﻮرت ﻳﻚ آراﻳﻪ ﺑﺎﺷﺪ
٤٢٩
ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﺑﻪ ﺗﻤﺎم آﻳﺘﻢ ﻫﺎي اﻧﺘﺨﺎب ﺷﺪه دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ .اﻟﺒﺘﻪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ،ﻣﺎ ﻓﻘﻂ آﻳﺘﻢ اول را در ﻛﻨﺘﺮل LinkLabel ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ ﺑﻨﺎﺑﺮاﻳﻦ در آراﻳﻪ ي SelectedItemsﻓﻘﻂ ﺑﻪ ﻋﻨﺼﺮ اول )ﺑﺎ اﻧﺪﻳﺲ ﺻﻔﺮ( ﻧﻴﺎز دارﻳﻢ .ﺑﺮاي دﺳﺘﺮﺳـﻲ ﺑـﻪ اﻃﻼﻋﺎت دﻳﮕﺮ ﺳﺘﻮن ﻫﺎي ﻓﻴﻠﺪ اﻧﺘﺨﺎب ﺷﺪه در ﻟﻴﺴﺖ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﻢ از ﺧﺎﺻﻴﺖ SubItemsاﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﻣﺜﻼً ﺑﺮاي دﺳﺘﺮﺳـﻲ ﺑﻪ آدرس ﻟﻴﻨﻚ اﻧﺘﺨﺎب ﺷﺪه ﻛﻪ در ﺳﺘﻮن اول ﻗﺮار دارد ،از ] SubItems[1اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ. ﺑﺮاي ﺗﻨﻈـﻴﻢ ﻣﺘﻨـﻲ ﻛـﻪ در ﻛﻨﺘـﺮل LinkLabelﻧﻤـﺎﻳﺶ داده ﻣـﻲ ﺷـﻮد ،ﺧﺎﺻـﻴﺖ Textآن را ﺑﺮاﺑـﺮ ﺑـﺎ ﺛﺎﺑـﺖ رﺷـﺘﻪ اي " "Visitﺑﻪ اﺿﺎﻓﻪ ي ﻧﺎم آﻳﺘﻢ اﻧﺘﺨﺎب ﺷﺪه در ﻟﻴﺴﺖ ﻗﺮار ﻣﻲ دﻫﻴﻢ .ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻧﺎم آﻳﺘﻢ اﻧﺘﺨﺎب ﺷﺪه ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﻢ از ﺧﺎﺻﻴﺖ Textآن اﺳﺘﻔﺎده ﻛﻨﻴﻢ: // Update the link label control Text property lnkUrl.Text = "Visit " + ;lstFavorites.SelectedItems[0].Text ﺧﺎﺻﻴﺖ Linksاز ﻛﻨﺘﺮل ،LinkLabelﺑﻪ ﺻﻮرت آراﻳﻪ اي از ﻧـﻮع LinkCollectionاﺳـﺖ و ﺷـﺎﻣﻞ ﻟﻴﻨـﻚ ﻫﺎﻳﻲ اﻳﻨﺘﺮﻧﺘﻲ ﻣﻲ ﺷﻮد ﻛﻪ اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ آﻧﻬﺎ اﺷﺎره ﻣﻲ ﻛﻨﺪ .ﺑﻨـﺎﺑﺮاﻳﻦ ﺑﺎﻳـﺪ Urlآﻳﺘﻤـﻲ ﻛـﻪ در ﻟﻴـﺴﺖ lstFavorites اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ را ﺑﻪ اﻳﻦ ﺧﺎﺻﻴﺖ اﺿﺎﻓﻪ ﻛﻨﻴﻢ .اﻣﺎ اﺑﺘﺪا ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﻣﺤﺘﻮﻳﺎت آن را ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ Clearﭘﺎك ﻛﻨﻴﻢ. // Clear the default hyperlink ;)(lnkUrl.Links.Clear ﺣﺎل ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ،Addﻟﻴﻨﻚ ﻣﺮﺑﻮط ﺑﻪ آﻳﺘﻢ اﻧﺘﺨﺎب ﺷﺪه در ﻟﻴﺴﺖ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﻢ .ﻣﺘﺪ Addﻳﻚ ﻣﺘﺪ ﺳـﺮﺑﺎر ﮔﺬاري ﺷﺪه اﺳﺖ و ﻧﺴﺨﻪ اي از اﻳﻦ ﻣﺘﺪ ﻛﻪ از آن اﺳﺘﻔﺎده ﻣـﻲ ﻛﻨـﻴﻢ ،ﺳـﻪ ﭘـﺎراﻣﺘﺮ درﻳﺎﻓـﺖ ﻣـﻲ ﻛﻨـﺪ Length ،Start :و .LinkDataﭘﺎراﻣﺘﺮ Startﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ از ﻛﺠﺎي رﺷﺘﻪ اي ﻛﻪ ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد ﺑﺎﻳﺪ ﺑﻪ ﻋﻨـﻮان ﻟﻴﻨـﻚ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﻮد .ﭘﺎراﻣﺘﺮ Lengthﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻃﻮل رﺷـﺘﻪ اي اﺳـﺖ ﻛـﻪ ﺑﺎﻳـﺪ ﺑـﻪ ﻋﻨـﻮان ﻟﻴﻨـﻚ ﻣـﺸﺨﺺ ﺷـﻮد .ﭘـﺎراﻣﺘﺮ LinkDataﻧﻴﺰ رﺷﺘﻪ ي ﺣﺎوي ﻟﻴﻨﻚ را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ .در اﻳﻨﺠﺎ ﺑﺮاي اﻳﻨﻜـﻪ ﻋﺒـﺎرت " "Visitﺣـﺬف ﺷـﻮد ،ﻧﻘﻄـﻪ ﺷﺮوع را 6در ﻧﻈﺮ ﮔﺮﻓﺘﻪ اﻳﻢ ،ﻫﻤﭽﻨﻴﻦ ﻃﻮل ﻟﻴﻨﻚ را ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎ ﻃﻮل ﻟﻴﻨﻜﻲ ﻛﻪ در ﻟﻴﺴﺖ اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ﻗﺮار داده اﻳﻢ. // Add the selected hyperlink to the LinkCollection lnkUrl.Links.Add(6, lstFavorites.SelectedItems[0].Text.Length, ;)lstFavorites.SelectedItems[0].SubItems[1].Text ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي ﻛﻨﺘﺮل LinkLabelﻛﻠﻴﻚ ﻛﻨﺪ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑـﻪ روﻳـﺪاد Clickاﻳـﻦ ﻛﻨﺘـﺮل ﻓﺮاﺧـﻮاﻧﻲ ﻣـﻲ ﺷـﻮد، ﺑﻨﺎﺑﺮاﻳﻦ در اﻳـﻦ ﻣﺘـﺪ ﺑﺎﻳـﺪ ﻛـﺪي را ﻗـﺮار دﻫـﻴﻢ ﺗـﺎ ﻣﺤﺘﻮﻳـﺎت ﻟﻴﻨـﻚ را ﻧﻤـﺎﻳﺶ دﻫـﺪ .ﺑـﻪ اﻳـﻦ ﻣﺘـﺪ ﭘـﺎراﻣﺘﺮي ﺑـﻪ ﻧـﺎم eاز ﻧـﻮع LinkLabelLinkClickedEventArgsﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد ﻛﻪ ﺣﺎوي اﻃﻼﻋﺎﺗﻲ ﻣﺎﻧﻨﺪ آدرس ﻟﻴﻨﻚ ﻣـﻮرد ﻧﻈـﺮ اﺳــﺖ .ﺑــﺮاي ﻧﻤــﺎﻳﺶ ﻟﻴﻨــﻚ ﻛــﺎﻓﻲ اﺳــﺖ اﻳــﻦ آدرس را ﺑﺪﺳــﺖ آورﻳــﻢ و آن را ﺑــﻪ ﻋﻨــﻮان ﭘــﺎراﻣﺘﺮ ﺑــﻪ ﻣﺘــﺪ Startاز ﻛــﻼس System.Diagnostics.Processﺑﻔﺮﺳﺘﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ،ﻣﺮورﮔﺮ اﻳﻨﺘﺮﻧﺖ ﺑﺎز ﻣـﻲ ﺷـﻮد و ﻣﺤﺘﻮﻳـﺎت ﻟﻴﻨـﻚ اﻧﺘﺨﺎب ﺷﺪه را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. (System.Diagnostics.Process.Start ;) )(e.Link.LinkData.ToString
٤٣٠
اﻳﺠﺎد ﻧﻤﻮﻧﻪ اي دﻳﮕﺮ از ﺑﺮﻧﺎﻣﻪ ي :Favorite Viewer ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ اﺳﺘﻔﺎده از ﻛﻼﺳﻬﺎ ﺑﺮاي ﺟﺪا ﺳﺎزي ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﺑﺮﻧﺎﻣﻪ ،اﻳـﻦ اﻣﻜـﺎن را ﻣـﻲ دﻫـﺪ ﺗـﺎ ﺑﺘـﻮاﻧﻴﻢ از آن ﻛـﺪﻫﺎ در ﻗﺴﻤﺘﻬﺎي دﻳﮕﺮ ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺑﺮاي اﺛﺒﺎت اﻳﻦ ﻣﻄﻠﺐ در اﻳـﻦ ﻗـﺴﻤﺖ ﺑﺮﻧﺎﻣـﻪ ي دﻳﮕـﺮي ﻣـﺸﺎﺑﻪ ﺑﺮﻧﺎﻣـﻪ ي Favorite Viewerﻗﺴﻤﺖ ﻗﺒﻞ ،اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ و از ﻛﻼﺳﻬﺎي آن ﺑﺮﻧﺎﻣﻪ ،ﻣﺎﻧﻨﺪ ﻛﻼس Favoritesو ﻳـﺎ WebFavorite در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ.
اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي :Favorites Tray در اﻳﻦ ﻗﺴﻤﺖ ﺑﺮﻧﺎﻣﻪ اي اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﺑﻪ ﺻﻮرت ﻳﻚ آﻳﻜﻮن در ﻛﻨﺎر ﺳﺎﻋﺖ ﺳﻴﺴﺘﻢ ﻗﺮار ﮔﻴﺮد و ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن ﻛﺎرﺑﺮ ﺑﺮ روي اﻳﻦ آﻳﻜﻮن ﻟﻴﺴﺘﻲ از ﮔﺰﻳﻨﻪ ﻫﺎي ،Favoritesﺑﻪ ﺻﻮرت ﻳﻚ ﻣﻨﻮ ﻧﻤﺎﻳﺶ داده ﺷﻮد )ﺷﻜﻞ .(18-10ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛـﺎرﺑﺮ ﻣـﻲ ﺗﻮاﻧﺪ ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي ﻫﺮ ﻛﺪام از ﮔﺰﻳﻨﻪ ﻫﺎي اﻳﻦ ﻣﻨﻮ ﻣﺤﺘﻮﻳﺎت آن ﻟﻴﻨﻚ را در اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﻣﺸﺎﻫﺪه ﻛﻨﺪ.
ﺷﻜﻞ 18-10
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي Favorites Tray (1 (2
(3
(4
در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ،ﮔﺰﻳﻨﻪ ي … File New Projectرا از ﻧﻮار ﻣﻨـﻮ اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ و ﺑـﻪ وﺳﻴﻠﻪ ي ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﺷﺪه ،ﻳﻚ ﭘﺮوژه ي وﻳﻨﺪوزي ﺑﺎ وﻳﮋوال C#ﺑﻪ ﻧﺎم Favorites Trayاﻳﺠﺎد ﻛﻨﻴﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﺷﺪ ،ﻣﻘـﺪار ﺧﺎﺻـﻴﺖ WindowStateآن را ﺑـﻪ Minimizedو ﻣﻘـﺪار ﺧﺎﺻﻴﺖ ShowInTaskBarرا ﺑﻪ Falseﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴـﺐ از ﻧﻤـﺎﻳﺶ داده ﺷـﺪن ﻓـﺮم ﺟﻠـﻮﮔﻴﺮي ﺧﻮاﻫﻴﺪ ﻛﺮد. ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘـﺮل NotifyIconدر ﻓـﺮم ﻗـﺮار داده ،ﺧﺎﺻـﻴﺖ Nameاﻳـﻦ ﻛﻨﺘـﺮل را ﺑﺮاﺑـﺮ ﺑـﺎ icnNotifyو ﺧﺎﺻﻴﺖ Textآن را ﺑـﻪ Right-click me to view Favorites ﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺣﺎل ﻓﺮم ﺑﺮﻧﺎﻣﻪ را اﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ در ﭘﻨﺠﺮه ي Propertiesروي آﻳﻜـﻮن Eventsﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﻟﻴﺴﺖ روﻳﺪاد ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻓﺮم ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ .در اﻳﻦ ﻟﻴﺴﺖ روﻳﺪاد VisibleChangedرا اﻧﺘﺨﺎب ﻛﺮده و روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳﻦ ﻣﺘﺪ ﻗﺮار دﻫﻴﺪ. private void Form1_VisibleChanged(object sender,
٤٣١
)EventArgs e { // If the user can see us, hide us )if (this.Visible ;this.Visible = false } (5ﺣﺎل ﺑﺎﻳﺪ آﻳﻜﻮﻧﻲ را ﺑﺮاي ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﻨﻴﻢ ،در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻫﻴﭻ ﭼﻴﺰ ﻛﻪ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﺑﺮﻧﺎﻣﻪ ﺑﺎﺷﺪ در ﺳﻴﺴﺘﻢ ﻧﻤﺎﻳﺶ داده ﻧﻤﻲ ﺷﻮد و ﺑﻪ اﻳﻦ ﺗﺮﺗﻴـﺐ ﻛـﺎرﺑﺮ ﻧﻤـﻲ ﺗﻮاﻧـﺪ از ﺑﺮﻧﺎﻣـﻪ ﺑﺨﻮاﻫـﺪ ﺗـﺎ ﻛـﺎري را اﻧﺠـﺎم دﻫـﺪ .ﺑـﺎ اﺳـﺘﻔﺎده از ﭘﻨﺠـﺮه ي Solution Explorerﺑﺮ روي ﻧﺎم ﺑﺮﻧﺎﻣﻪ ) (Favorites Trayﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴـﺪ و از ﻣﻨـﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ ي Add New Itemرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .در ﻗﺴﻤﺖ Tamplatesﻫﻤﺎﻧﻨﺪ ﺷـﻜﻞ ،19-10 ﮔﺰﻳﻨﻪ ي Icon Fileرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ و در ﻛﺎدر Nameﻫﻢ ﻧﺎم Tray.icoرا وارد ﻛﻨﻴﺪ .ﺳﭙﺲ روي ﻛﻠﻴﺪ Addﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﻳﻦ ﻓﺎﻳﻞ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﻮد.
ﺷﻜﻞ 19-10 (6ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﺑﺰار Image Editorدر وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .از اﻳﻦ اﺑﺰار ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮاي ﻃﺮاﺣﻲ آﻳﻜﻮن ﻫﺎ ،اﺷﺎره ﮔﺮﻫﺎ و ﻳﺎ ﻓﺎﻳﻠﻬﺎي ﺗﺼﻮﻳﺮي ﺟﺪﻳﺪ در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در ﻧﻮار اﺑﺰار اﻳﻦ ﻗﺴﻤﺖ ،ﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ 20-10 اﺑﺰارﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮاي اﻳﻦ ﻛﺎر از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ را ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ.
ﺷﻜﻞ 20-10 (7اﮔﺮ ﺟﻌﺒﻪ رﻧﮓ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 21-10در ﺻـﻔﺤﻪ دﻳـﺪه ﻧﻤـﻲ ﺷـﻮد ،ﺑـﺎ اﻧﺘﺨـﺎب ﮔﺰﻳﻨـﻪ ي Image Show Color Windowاﻳﻦ ﭘﻨﺠﺮه را ﺑﻪ ﺻﻔﺤﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ. ٤٣٢
ﺷﻜﻞ 21-10 (8
(9
(10
(11 (12 (13
ﻗﺒﻞ از اﻳﻨﻜﻪ ﻃﺮاﺣﻲ آﻳﻜﻮن را ﺷﺮوع ﻛﻨﻴﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﻧﻮع آﻳﻜﻮن را ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ .وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﻪ ﺻـﻮرت ﭘـﻴﺶ ﻓـﺮض ﻳﻚ آﻳﻜﻮن 32*32اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ ،اﻣﺎ اﻳﻦ آﻳﻜﻮن ﺑﺰرﮔﺘﺮ از ﭼﻴﺰي اﺳﺖ ﻛﻪ ﻧﻴﺎز دارﻳﻢ .ﺑﺎ اﺳﺘﻔﺎده از ﻧﻮار ﻣﻨـﻮ ﮔﺰﻳﻨـﻪ ي Image New Image Typeرا اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ ﺗـﺎ ﻛـﺎدر New Icon Image Type ﻧﻤﺎﻳﺶ داده ﺷﻮد .ﺳﭙﺲ در اﻳﻦ ﻛﺎدر ﮔﺰﻳﻨـﻪ ي 16*16, 256 Colorرا اﻧﺘﺨـﺎب ﻛـﺮده و روي OKﻛﻠﻴـﻚ ﻛﻨﻴﺪ. ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻳﻚ آﻳﻜﻮن 16*16ﻧﻴﺰ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻣﻲ ﺷﻮد ،اﻣﺎ آﻳﻜﻮن ﻗﺒﻠـﻲ از ﺑـﻴﻦ ﻧﻤـﻲ رود .اﮔـﺮ آﻳﻜـﻮن ﻗﺒﻠـﻲ ﻫﻤﭽﻨﺎن در ﺑﺮﻧﺎﻣﻪ ﺑﺎﻗﻲ ﺑﻤﺎﻧﺪ ﻣﻤﻜﻦ اﺳﺖ ﺑﻌﺪﻫﺎ ﺑﺎ ﻣﺸﻜﻞ ﻣﻮاﺟﻪ ﺷﻮﻳﻢ ،ﭘﺲ ﺑﻬﺘﺮ اﺳﺖ آن را ﺣﺬف ﻛﻨﻴﻢ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﮔﺰﻳﻨـﻪ ي Image Current Image Type 32*32, 16 Colorرا از ﻧـﻮار ﻣﻨﻮ اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺳﭙﺲ ﺑﻼﻓﺎﺻـﻠﻪ ﮔﺰﻳﻨـﻪ ي Image Delete Image Typeرا اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ. ﻫﻤﻴﻦ ﻣﺮاﺣﻞ را ﺑﺮاي ﮔﺰﻳﻨﻪ ي 16*16, 16 Colorﻧﻴﺰ ﺗﻜﺮار ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻓﻘﻂ ﻳﻚ آﻳﻜﻮن ﺑﻪ ﺻﻮرت 16*16, 256 Colorدر اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻗﻲ ﻣﻲ ﻣﺎﻧﺪ. اﮔﺮ ﺣﺲ ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻓﺮد ﺧﻼﻗﻲ ﻫﺴﺘﻴﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ آﻳﻜﻮن ﻣﻮرد ﻧﻈﺮﺗﺎن را ﺑﺮاي اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ ﻃﺮاﺣـﻲ ﻛﻨﻴـﺪ ،در ﻏﻴـﺮ اﻳـﻦ ﺻﻮرت ﻣﻲ ﺗﻮاﻧﻴﺪ ﻛﺎري ﻛﻪ ﻣﺎ در اﻳﻦ ﻗﺴﻤﺖ اﻧﺠﺎم ﻣﻲ دﻫﻴﻢ را اﻧﺠﺎم دﻫﻴﺪ .ﻳﻌﻨﻲ ﺑﻪ ﻧﺤﻮي از آﻳﻜـﻮن اﻳﻨﺘﺮﻧـﺖ اﻛـﺴﭙﻠﻮرر ﺑﺮاي اﻳﻦ ﻗﺴﻤﺖ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﺑﺎ اﻧﺘﺨﺎب ﮔﺰﻳﻨﻪ ي File Save Tray.icoاز ﻧﻮار ﻣﻨﻮ آﻳﻜﻮن ﺑﺮﻧﺎﻣﻪ را در دﻳﺴﻚ ذﺧﻴﺮه ﻛﻨﻴﺪ. ﺑــﻪ ﻗــﺴﻤﺖ ﻃﺮاﺣــﻲ ﻓــﺮم ﺑﺮﮔﺮدﻳــﺪ و ﻛﻨﺘــﺮل icnNotifyرا اﻧﺘﺨــﺎب ﻛﻨﻴــﺪ .ﺳــﭙﺲ ﺑــﺎ اﺳــﺘﻔﺎده از ﭘﻨﺠــﺮه ي ،Propertiesﺧﺎﺻﻴﺖ Iconاﻳﻦ ﻛﻨﺘﺮل را ﺑﺮاﺑﺮ ﺑﺎ آﻳﻜﻮﻧﻲ ﻛﻪ در ﻣﺮﺣﻠﻪ ي ﻗﺒﻞ اﻳﺠﺎد ﻛﺮدﻳﺪ ﻗﺮار دﻫﻴﺪ. ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪ ه ﻣﻲ ﻛﻨﻴﺪ آﻳﻜﻮﻧﻲ ﻛﻪ ﻃﺮاﺣﻲ ﻛﺮده اﻳﺪ در ﻛﻨﺎر ﺳﺎﻋﺖ ﺳﻴﺴﺘﻢ ﻗـﺮار ﻣـﻲ ﮔﻴـﺮد ،اﻣـﺎ ﻫـﻴﭻ ﭘﻨﺠﺮه اي از ﺑﺮﻧﺎﻣﻪ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﻧﻤﻲ ﺷﻮد )ﺷﻜﻞ .(22-10ﻫﻤﭽﻨﻴﻦ اﮔﺮ اﺷﺎره ﮔﺮ ﻣﺎوس را ﺑـﺮاي ﻟﺤﻈـﺎﺗﻲ روي اﻳﻦ آﻳﻜﻮن ﻗﺮار دﻫﻴﺪ ،ﻣﺘﻨﻲ را ﻛﻪ در ﺧﺎﺻﻴﺖ Textﻛﻨﺘﺮل Notify Iconوارد ﻛﺮده ﺑﻮدﻳﺪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ.
ﺷﻜﻞ 22-10 (14ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ در اﻳﻦ ﺣﺎﻟﺖ ﻫﻴﭻ راﻫﻲ ﺑﺮاي ﺑﺴﺘﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴـﺰ وﺟـﻮد ﻧـﺪارد .ﺑـﻪ ﻣﺤـﻴﻂ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ ﺑﺮﮔﺮدﻳﺪ و ﮔﺰﻳﻨﻪ ي Debug Stop Debuggingرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﺘﻮﻗﻒ ﺷﻮد. (15ﺑﺎ اﻧﺠﺎم اﻳﻦ ﻛﺎر اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﺘﻮﻗﻒ ﻣﻲ ﺷﻮد اﻣﺎ آﻳﻜﻮن آن ﻫﻤﭽﻨﺎن در ﺻﻔﺤﻪ ﺑﺎﻗﻲ ﻣﻲ ﻣﺎﻧﺪ .ﺑـﺮاي ﺣـﺬف آﻳﻜـﻮن ﻧﻴـﺰ، اﺷﺎره ﮔﺮ ﻣﺎوس را ﺑﺮ روي آن ﻗﺮار دﻫﻴﺪ ﺗﺎ ﻧﺎﭘﺪﻳﺪ ﺷﻮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟
٤٣٣
ﻣﻌﻴﻦ ﻛﺮدن اﻳﻦ ﻛﻪ ﻓﺮم در Taskbarﻧﻤﺎﻳﺶ داده ﻧﺸﻮد ) (ShowInTaskBar = Falseو ﻫﻤﭽﻨﻴﻦ ﺑﻪ ﺻﻮرت Minimizeاﺟﺮا ﺷﻮد ) (WindowState = Minimizedﻣﻮﺟﺐ ﻣﻲ ﺷﻮد ﻛﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻗﺎﺑﻞ ﻣﺸﺎﻫﺪه ﻧﺒﺎﺷﺪ. در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﻢ ﻓﻘﻂ ﻣﻲ ﺧﻮاﻫﻴﻢ آﻳﻜﻮن ﺑﺮﻧﺎﻣﻪ در ﻛﻨﺎر ﺳﺎﻋﺖ ﻧﻤﺎﻳﺶ داده ﺷﻮد و ﺑﻪ ﻧﻤﺎﻳﺶ داده ﺷﺪن ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻧﻴﺎزي ﻧﺪارﻳﻢ .اﻣـﺎ ﺗﺎﻛﻨﻮن ﻓﻘﻂ ﻧﻴﻤﻲ از ﻛﺎر را اﻧﺠﺎم داده اﻳﺪ زﻳﺮا ﺑﺎز ﻫﻢ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻠﻴـﺪﻫﺎي Alt + Tabدر ﺻـﻔﺤﻪ ﻧﻤـﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﺑﺮاي ﺟﻠﻮﮔﻴﺮي از اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻛﺪ زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﻢ. private void Form1_VisibleChanged(object sender, )EventArgs e { // If the user can see us, hide us )if (this.Visible ;this.Visible = false } ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎرﺑﺮ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻠﻴﺪﻫﺎي Alt + Tabﻫﻢ ﻧﻤﻲ ﺗﻮاﻧﺪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ را ﺑﺒﻴﻨﺪ.
ﻧﻤﺎﻳﺶ ﮔﺰﻳﻨﻪ ﻫﺎي :Favorites در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ،ﻗﺎﺑﻠﻴﺖ ﻧﻤﺎﻳﺶ ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻓﻮﻟﺪر Favoritesرا ﺑﻪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛﺮد .اﻣـﺎ ﺑﺮاي اﻳﻦ ﻛﺎر ﻻزم اﺳﺖ ﻛﻪ ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ Favorites Viewerاﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﻢ را ﺑﻪ اﻳﻦ ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ ﻛﻨﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻧﻤﺎﻳﺶ ﮔﺰﻳﻨﻪ ﻫﺎي Favorites (1ﺑـﺮاي ﻛﺎﻣـﻞ ﻛـﺮدن ﺑﺮﻧﺎﻣـﻪ ي Favorites Trayﺑﺎﻳـﺪ اﺷـﻴﺎﻳﻲ را از ﻛﻼﺳـﻬﺎي WebFavoriteو Favoritesاﻳﺠــﺎد ﻛﻨــﻴﻢ .ﭘــﺲ اﺑﺘــﺪا ﺑﺎﻳــﺪ اﻳــﻦ ﻛﻼﺳـﻬﺎ را ﺑــﻪ ﺑﺮﻧﺎﻣــﻪ اﺿــﺎﻓﻪ ﻛﻨــﻴﻢ .ﺑــﺎ اﺳــﺘﻔﺎده از ﭘﻨﺠــﺮه ي Solution Explorerروي ﻧﺎم ﭘﺮوژه ي Favorites Trayﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ و از ﻣﻨﻮي ﺑـﺎز ﺷﺪه ﮔﺰﻳﻨﻪ ي … Add Existing Itemرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺑﺎ اﺳﺘﻔﺎده از ﻛﺎدري ﻛﻪ ﺑﺎز ﻣـﻲ ﺷـﻮد ﻓﺎﻳـﻞ ﻣﺮﺑﻮط ﺑﻪ ﻛـﻼس Favoritesرا ﭘﻴـﺪا ﻛﻨﻴـﺪ )اﻳـﻦ ﻓﺎﻳـﻞ در ﻓﻮﻟـﺪر ﻣﺮﺑـﻮط ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ ي Favorites Viewerﻗﺮار دارد( و ﺳﭙﺲ روي ﻛﻠﻴﺪ Addﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻓﺎﻳﻞ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛﻼس ﺑﻪ ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ ﺷﺪه و در ﭘﻨﺠﺮه ي Solution Explorerﻗﺎﺑﻞ ﻣﺸﺎده اﺳﺖ. (2ﻫﻤﻴﻦ ﻣﺮاﺣﻞ را ﺗﻜﺮار ﻛﻨﻴﺪ ﺗﺎ ﻓﺎﻳﻞ ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس WebFavoriteﻧﻴﺰ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﻮد. (3ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮوﻳﺪ و ﻛﻨﺘﺮل NotifyIconرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺳـﭙﺲ ﺑـﻪ ﭘﻨﺠـﺮه ي Properties ﺑﺮوﻳﺪ و روي آﻳﻜﻮن Eventsﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻟﻴﺴﺘﻲ از روﻳﺪاد ﻫﺎي اﻳﻦ ﻛﻨﺘﺮل ﻧﻤﺎﻳﺶ داده ﺷﻮد .در اﻳﻦ ﻟﻴﺴﺖ روﻳـﺪاد Clickرا اﻧﺘﺨﺎب ﻛﺮده و روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را ﺑـﻪ اﻳـﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ:
٤٣٤
private void icnNotify_Click(object sender, EventArgs e) { // Create a new instance of the Favorites class Favorites_Viewer.Favorites objFavorites = new Favorites_Viewer.Favorites(); // Scan the Favorites folder objFavorites.ScanFavorites(); // Clear current menu items FavoritesMenu.Items.Clear(); // Process each objWebFavorite object // in the Favorites collection foreach (Favorites_Viewer.WebFavorite objWebFavorite in objFavorites.FavoriteCollection) { // Declare a ToolStripMenuItem object ToolStripMenuItem objMenuItem = new ToolStripMenuItem(); // Set the properties of ToolStripMenuItem object objMenuItem.Text = objWebFavorite.Name; objMenuItem.Tag = objWebFavorite.Url; // Add a handler to Click event of new menu item objMenuItem.Click += new EventHandler(MenuItems_Click); // Add the ToolStripMenuItem object // to the ContextMenu FavoritesMenu.Items.Add(objMenuItem); } // Create a Seperator item and adding it // to context menu ToolStripSeparator objSeperatorItem = new ToolStripSeparator(); FavoritesMenu.Items.Add(objSeperatorItem); // Create an Exit menu item and set it's properties ToolStripMenuItem objExitItem = new ToolStripMenuItem(); objExitItem.Text = "Exit"; objExitItem.Click += new EventHandler(ExitMenuItem_Click);
٤٣٥
// Add Exit menu item to context menu ;)FavoritesMenu.Items.Add(objExitItem } (4ﺣﺎل ﺑﺎﻳﺪ دو ﻣﺘﺪ ﺑﺮاي ﻛﻨﺘﺮل روﻳﺪاد ﻛﻠﻴﻚ ﻣﻨﻮي ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﻨﻴﻢ .ﻣﺘﺪ اول ﻫﻨﮕﺎﻣﻲ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷـﻮد ﻛـﻪ ﻛـﺎرﺑﺮ روي ﻳﻜﻲ از ﻟﻴﻨﻚ ﻫﺎ ﻛﻠﻴﻚ ﻛﻨﺪ ،ﭘﺲ اﻳﻦ ﻣﺘﺪ ﺑﺎﻳﺪ ﺑﺘﻮاﻧﺪ اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر را ﺑﺎز ﻛﻨﺪ و ﻟﻴﻨﻚ را ﻧﻤﺎﻳﺶ دﻫﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﺘـﺪ زﻳﺮ را ﺑﻪ ﻛﻼس Form1اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void MenuItems_Click(object sender, )System.EventArgs e { // Create a ToolStripMenuItem // and fill it with sender parameter ;ToolStripMenuItem s = (ToolStripMenuItem)sender // Open the internet explorer to view selected // favorite ;))(System.Diagnostics.Process.Start(s.Tag.ToString } (5ﻣﺘﺪ دوم ﻧﻴﺰ ﻫﻨﮕﺎﻣﻲ اﺣﻀﺎر ﻣﻲ ﺷﻮد ﻛﻪ ﻛﺎرﺑﺮ روي ﮔﺰﻳﻨﻪ ي Exitﻛﻠﻴﻚ ﻣﻲ ﻛﻨﺪ و ﻣﻲ ﺧﻮاﻫﺪ از ﺑﺮﻧﺎﻣﻪ ﺧـﺎرج ﺷـﻮد. ﺑﺮاي اﺿﺎﻓﻪ ﺷﺪن اﻳﻦ ﻣﺘﺪ ،ﻛﺪ زﻳﺮ را ﺑﻪ ﻛﻼس Form1اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void ExitMenuItem_Click(object sender, )System.EventArgs e { ;)(Application.Exit } (6ﺑﺎ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ،آﻳﻜﻮﻧﻲ ﻣﺎﻧﻨﺪ ﻣﺮاﺣﻞ ﻗﺒﻞ در ﻛﻨﺎر ﺳﺎﻋﺖ ﺳﻴﺴﺘﻢ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﺑﺎ ﻛﻠﻴﻚ راﺳﺖ ﺑﺮ روي اﻳﻦ آﻳﻜﻮن، ﻟﻴﺴﺘﻲ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 23-10ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﻫﺮ ﻛﺪام از ﻟﻴﻨﻚ ﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻟﻴﺴﺖ را ﻛﻪ اﻧﺘﺨﺎب ﻛﻨﻴﺪ ،اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﺑﺎز ﻣﻲ ﺷﻮد و ﻣﺤﺘﻮﻳﺎت آن را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
ﺷﻜﻞ 23-10
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ٤٣٦
ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﺗﻘﺮﻳﺒﺎ ﻣﺸﺎﺑﻪ ﺑﺮﻧﺎﻣﻪ ي Favorites Viewerاﺳﺖ ،ﻓﻘﻂ ﺗﻐﻴﻴﺮات ﻛـﻮﭼﻜﻲ در آن اﻳﺠﺎد ﺷﺪه اﺳﺖ .دﻟﻴﻞ اﻳﻦ ﺗﻐﻴﻴﺮات ﻧﻴﺰ اﻳﻦ ﺑﻮده اﺳﺖ ﻛﻪ ﻇﺎﻫﺮ ﺑﺮﻧﺎﻣﻪ را ﺗﻐﻴﻴﺮ داده اﻳﻢ ،در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻗﺴﻤﺖ اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ ﻛﻪ از ﻛﻼﺳﻬﺎي Favoritesو WebFavoriteﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ ،ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ ﺑﺮاﺑﺮ اﺳﺖ. ﭘﺮوﺳﻪ ي ﻣﺮﺑﻮط ﺑﻪ اﻳﺠﺎد ﻣﻨﻮي ﺑﺮﻧﺎﻣﻪ را اﻳﻦ ﺑﺎر ﺑﻪ ﺟﺎي آﻧﻜﻪ در روﻳﺪاد Loadﻓﺮم ﻗﺮار دﻫﻴﻢ ،در روﻳـﺪاد Clickﻣﺮﺑـﻮط ﺑـﻪ ﻛﻨﺘﺮل NotifyIconﻗﺮار ﻣﻲ دﻫﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﺮ ﺑﺎر ﻛﻪ ﻛﺎرﺑﺮ روي آﻳﻜﻮن ﻛﻠﻴﻚ ﻛﻨﺪ ،اﺑﺘـﺪا ﻣﻨـﻮ اﻳﺠـﺎد ﺷـﺪه و ﺳـﭙﺲ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد. در اﻳﻦ ﻣﺘﺪ ﻫﻤﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻠﻲ ،اﺑﺘﺪا ﺷﻴﺊ اي از ﻛﻼس Favoritesاﻳﺠﺎد ﻛﺮده و ﺳﭙﺲ ﻣﺘﺪ ScanFavorites را در آن ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ آراﻳﻪ ي FavoriteCollectionرا ﻛﺎﻣﻞ ﻛﻨﺪ .اﻟﺒﺘﻪ دﻗﺖ ﻛﻨﻴﺪ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﻓﻀﺎي ﻧﺎم ﻛﻼس Favoritesﺑﺮاﺑﺮ ﺑﺎ Favorite_Viewerاﺳﺖ ،ﻳﺎ ﺑﺎﻳﺪ اﻳﻦ ﻓﻀﺎي ﻧﺎم را ﺑﺎ اﺳﺘﻔﺎده از راﻫﻨﻤﺎي using ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ و ﻳﺎ ﻫﻤﺎﻧﻨﺪ ﺑﺎﻻ ،ﻧﺎم ﻛﺎﻣﻞ ﻛﻼس را ذﻛﺮ ﻛﻨﻴﻢ. // Create a new instance of the Favorites class = Favorites_Viewer.Favorites objFavorites ;)(new Favorites_Viewer.Favorites // Scan the Favorites folder ;)(objFavorites.ScanFavorites ﻗﺒﻞ از اﻳﻦ ﻛﻪ در ﺗﻚ ﺗﻚ ﻋﻨﺎﺻﺮ آراﻳﻪ ﺑﮕﺮدﻳﻢ و آﻧﻬﺎ را در ﻣﻨﻮ ﻗﺮار دﻫﻴﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﻣﻨﻮ را ﺧﺎﻟﻲ ﻛﻨﻴﻢ. // Clear current menu items ;)(FavoritesMenu.Items.Clear ﻫﻤﺎﻧﻨﺪ ﻛﻨﺘﺮل ،ListViewﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻛﻨﺘﺮل ContextMenuStripﻧﻴﺰ در ﺣﻘﻴﻘﺖ اﺷـﻴﺎﻳﻲ از ﻛـﻼس ToolStripMenuItemﻫــﺴﺘﻨﺪ .ﺑﻨــﺎﺑﺮاﻳﻦ در ﺣﻠﻘـــﻪ ي foreachﺑــﺎزاي ﻫــﺮ ﻋﻨـــﺼﺮي ﻛــﻪ در آراﻳـــﻪ ي FavoriteCollectionﻗﺮار دارد ،ﻳﻚ ﺷﻴﺊ از ﻛﻼس ToolStripMenuItemاﻳﺠﺎد ﻛـﺮده و ﺧﺎﺻـﻴﺖ ﻫﺎي آن را ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﻨﻴﻢ. اوﻟﻴﻦ ﺧﺎﺻﻴﺘﻲ ﻛﻪ ﺑﺎﻳﺪ ﺗﻨﻈﻴﻢ ﺷﻮد ﻣﺘﻨﻲ اﺳﺖ ﻛﻪ ﺑﺮاي اﻳﻦ ﮔﺰﻳﻨﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﺑﺎ ﺗﻨﻈﻴﻢ ﺧﺎﺻﻴﺖ Textاﻳـﻦ ﺷـﻴﺊ ،ﻣـﺘﻦ ﻣﻨﺎﺳﺒﻲ را ﺑﺮاي آن ﻗﺮار ﻣﻲ دﻫﻴﻢ .ﻫﻤﭽﻨﻴﻦ ﺑﺎﻳﺪ ﺑﻪ ﻧﺤﻮي ﻟﻴﻨﻚ ﮔﺰﻳﻨﻪ ي ﻣﺮﺑﻮﻃﻪ را ﻧﻴﺰ در آن ﻗﺮار دﻫﻴﻢ ﺗﺎ ﻫﻨﮕﺎﻣﻲ ﻛـﻪ ﻛـﺎرﺑﺮ روي آن ﮔﺰﻳﻨﻪ ﻛﻠﻴﻚ ﻛﺮد ،ﻣﻨﻮ ﺑﺪاﻧﺪ ﭼﻪ ﻟﻴﻨﻜﻲ را ﺑﺎﻳﺪ ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﻧﻤﺎﻳﺶ دﻫﺪ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﻟﻴﻨـﻚ را ﺑـﺎ اﺳـﺘﻔﺎده از ﺧﺎﺻﻴﺖ Urlﺑﺪﺳﺖ آورده و در ﺧﺎﺻﻴﺖ Tagﻗﺮار ﻣﻲ دﻫﻴﻢ. // Declare a ToolStripMenuItem object = ToolStripMenuItem objMenuItem ;)(new ToolStripMenuItem // Set the properties of ToolStripMenuItem object ;objMenuItem.Text = objWebFavorite.Name ;objMenuItem.Tag = objWebFavorite.Url
٤٣٧
ﺣﺎل ﺑﺎﻳﺪ در اﻳﻦ ﻣﺮﺣﻠﻪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي اﻳﻦ ﮔﺰﻳﻨﻪ ﻛﻠﻴﻚ ﻣﻲ ﻛﻨﺪ ،ﭼﻪ ﻣﺘﺪي ﺑﺎﻳﺪ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮد .ﭼﻮن اﻳﻦ ﻣﺘـﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ اﺳﺖ ،ﭘﺲ ﺑﺎﻳﺪ ﺑﺮ ﻃﺒﻖ ﺳﺎﺧﺘﺎر ﺧﺎﺻﻲ ﺑﺎﺷﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ اﻳﻦ ﻣﺘﺪ ﺣﺘﻤـﺎً ﺑﺎﻳـﺪ از ﻧـﻮع voidﺑﺎﺷـﺪ و دو ﭘــﺎراﻣﺘﺮ ،ﻳﻜــﻲ از ﻧــﻮع System.EventArgsو ﻳﻜــﻲ از ﻧــﻮع objectدرﻳﺎﻓــﺖ ﻛﻨــﺪ .ﺑﻨــﺎﺑﺮاﻳﻦ ﻣﺘــﺪي ﺑــﻪ ﻧــﺎم MenuItems_Clickﺑﺎ اﻳﻦ ﻣﺸﺨﺼﺎت اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ،ﺳﭙﺲ ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن اﻳﻦ ﻣﺘﺪ ﺑﻪ روﻳﺪاد Clickﺷﻴﺊ اي ﻛـﻪ از ﻧﻮع ToolStripMenuItemاﻳﺠﺎد ﻛﺮده اﻳﻢ ،ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ اﻳﻦ ﻣﺘﺪ ﺑﺎﻳﺪ ﻫﻨﮕﺎم ﻛﻠﻴﻚ ﺷﺪن روي اﻳﻦ ﮔﺰﻳﻨـﻪ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮد. // Add a handler to Click event of new menu item objMenuItem.Click += new ;)EventHandler(MenuItems_Click ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺗﻤﺎم ﺧﺎﺻﻴﺖ ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﺷﻴﺊ ToolStripMenuItemرا ﺗﻨﻈﻴﻢ ﻛﺮده اﻳﻢ و ﻣﻲ ﺗﻮاﻧﻴﻢ آن را ﺑـﻪ ﻣﻨﻮي ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ. // Add the ToolStripMenuItem object to the ContextMenu ;)FavoritesMenu.Items.Add(objMenuItem ﺑﻌﺪ از اﺗﻤﺎم اﻳﻦ ﺣﻠﻘﻪ ،ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻓﻮﻟﺪر Favoritesﺑﻪ ﻣﻨﻮ اﺿﺎﻓﻪ ﺷﺪه اﻧﺪ ،اﻣﺎ ﻫﻨﻮز ﻣﻨﻮ ﻛﺎﻣﻞ ﻧﺸﺪه اﺳﺖ و ﺑﺎﻳﺪ دو ﮔﺰﻳﻨﻪ ي دﻳﮕﺮ ﻧﻴﺰ ﺑﻪ آن اﺿﺎﻓﻪ ﺷﻮد :ﻳﻚ ﺧﻂ ﺟﺪا ﻛﻨﻨﺪه و ﻳﻚ ﮔﺰﻳﻨﻪ ﺑﺮاي ﺧﺮوج از ﺑﺮﻧﺎﻣﻪ .ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﺧﻂ ﺟﺪا ﻛﻨﻨﺪه ﺑﻪ ﻣﻨـﻮ ﺑﺎﻳﺪ ﺷﻴﺊ اي را از ﻧﻮع ToolStripSeperatorاﻳﺠﺎد ﻛﺮده و آن را ﺑﻪ ﻣﻨﻮ اﺿﺎﻓﻪ ﻛﻨﻴﻢ. // Create a Seperator item and adding it // to context menu = ToolStripSeparator objSeperatorItem ;)(new ToolStripSeparator ;)FavoritesMenu.Items.Add(objSeperatorItem ﺑﺮاي اﻳﺠﺎد ﮔﺰﻳﻨﻪ ي ﺧﺮوج از ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﻛﺎﻓﻲ اﺳﺖ ﻣﺎﻧﻨﺪ ﻗﺴﻤﺘﻬﺎي ﻗﺒـﻞ ﻋﻤـﻞ ﻛﻨـﻴﻢ .اﻣـﺎ دﻗـﺖ داﺷـﺘﻪ ﺑﺎﺷـﻴﺪ دي ﻛـﻪ در روﻳـﺪاد Clickاﻳﻦ ﮔﺰﻳﻨﻪ ﻗﺮار ﻣﻲ ﮔﻴﺮد ﺑﺎ ﻛﺪ روﻳﺪاد Clickدﻳﮕﺮ ﮔﺰﻳﻨﻪ ﻫﺎ ﻣﻘﺪاري ﺗﻔﺎوت دارد .ﭘﺲ ﺑﺮاي آن ،ﻣﺘﺪي ﺟﺪاﮔﺎﻧﻪ )اﻣﺎ ﺑـﺎ ﻫﻤﺎن ﺳﺎﺧﺘﺎر و ﺑﺎ ﻫﻤﺎن ﭘﺎراﻣﺘﺮﻫﺎي ورودي و ﺧﺮوﺟﻲ( ﺑﻪ ﻧﺎم ExitMenuItem_Clickاﻳﺠﺎد ﻛﺮده و آن را ﺑـﻪ روﻳـﺪاد Clickﺷﻴﺊ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ .در آﻧﻬﺎ ﻧﻴﺰ ﺷﻴﺊ را ﺑﻪ ﻣﻨﻮ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ. // Create an Exit menu item and set it's properties = ToolStripMenuItem objExitItem ;)(new ToolStripMenuItem ;"objExitItem.Text = "Exit =objExitItem.Click + ;)new EventHandler(ExitMenuItem_Click // Add Exit menu item to context menu ;)FavoritesMenu.Items.Add(objExitItem
٤٣٨
ﻛﺪ درون ﻣﺘﺪ ExitMenuItem_Clickﺳﺎده اﺳﺖ و ﺗﺎﻛﻨﻮن ﺑﻪ ﻣﺮاﺗـﺐ از آن اﺳـﺘﻔﺎده ﻛـﺮده اﻳـﺪ ،ﺑﻨـﺎﺑﺮاﻳﻦ ﻧﻴـﺎزي ﺑـﻪ ﺗﻮﺿﻴﺢ ﻧﺪارد .ﭘﺲ ﺑﻪ ﺳﺮاغ ﻛﺪ درون ﻣﺘﺪ MenuItems_Clickﻣﻲ روﻳﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﻣﺘﺪ ﻫﺎﻳﻲ ﻛـﻪ ﺑـﺮاي روﻳـﺪاد ﻛﻠﻴﻚ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮﻧﺪ ،ﺑﺎﻳﺪ دو ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻛﻨﻨﺪ .ﻳﻜﻲ از اﻳﻦ ﭘﺎراﻣﺘﺮ ﻫﺎ ﺷﻴﺊ اي از ﻛﻼس Objectﺑـﻪ ﻧـﺎم sender اﺳﺖ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ روﻳﺪادي ﺑﺮاي ﻳﻚ ﺷﻴﺊ رخ ﺑﺪﻫﺪ ،ﺑﺮاي ﻣﺜﺎل روي ﻳﻜﻲ از ﮔﺰﻳﻨﻪ ﻫـﺎي ﻣﻨـﻮ ﻛﻠﻴـﻚ ﺷـﻮد درون ﻣﺘـﺪ ﺑـﺎ اﺳﺘﻔﺎده از ﭘﺎراﻣﺘﺮ senderﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﻪ اﻳﻦ ﺷﻴﺊ دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﻴﻢ .ﭘﺲ درون ﻣﺘﺪ MenuItems_Clickﻫﻢ ﻣـﻲ ﺗـــﻮاﻧﻴﻢ ﺑـــﺎ اﺳـــﺘﻔﺎده از ﭘـــﺎراﻣﺘﺮ senderﺑـــﻪ ﺷـــﻴﺊ اي ﻛـــﻪ روي آن ﻛﻠﻴـــﻚ ﺷـــﺪه اﺳـــﺖ )و ﻣـــﺴﻠﻤﺎً از ﻧـــﻮع ToolStripMenuItemاﺳﺖ( دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ. در اﻳﻦ ﻣﺘﺪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﻪ اﻃﻼﻋﺎﺗﻲ ﻛﻪ درون ﺧﺎﺻﻴﺖ Tagﻣﺮﺑﻮط ﺑﻪ ﺷﻴﺊ ﻗﺮار دارد دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﻴﻢ ،ﭘﺲ اﺑﺘﺪا ﺷـﻴﺊ را از ﻧـﻮع Objectﺑﻪ ﻧﻮع ToolStripMenuItemﺗﺒﺪﻳﻞ ﻛﺮده و ﻣـﺘﻦ داﺧـﻞ Tagرا ﺑﺪﺳـﺖ ﻣـﻲ آورﻳـﻢ .ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻗﺒﻼ ﻟﻴﻨﻚ ﻣﺮﺑﻮط ﺑﻪ ﻫﺮ ﮔﺰﻳﻨﻪ را در اﻳﻦ ﺧﺎﺻﻴﺖ ﻗﺮار دادﻳﻢ ،ﭘﺲ ﺣﺎﻻ ﻫﻢ ﺑﺎ ﺑﻪ دﺳـﺖ آوردن ﻣﻘـﺪار ﺧﺎﺻـﻴﺖ ،Tag ﻟﻴﻨــﻚ ﻣﺮﺑــﻮط ﺑــﻪ آن ﮔﺰﻳﻨــﻪ را ﺑﺪﺳــﺖ آورده اﻳــﻢ .ﺣــﺎل ﻓﻘــﻂ ﻛــﺎﻓﻲ اﺳــﺖ اﻳــﻦ ﻟﻴﻨــﻚ را ﺑــﻪ ﻣﺘــﺪ Startاز ﻛــﻼس System.Diagnostics.Processﺑﻔﺮﺳﺘﻴﻢ ﺗﺎ آن را در اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﻧﻤﺎﻳﺶ دﻫﺪ. // Create a ToolStripMenuItem // and fill it with sender parameter ;ToolStripMenuItem s = (ToolStripMenuItem)sender // Open the internet explorer to view selected // favorite ;))(System.Diagnostics.Process.Start(s.Tag.ToString ﻧﻜﺘﻪ ي ﻣﻬﻤﻲ ﻛﻪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ وﺟﻮد دارد ﻧﺤﻮه ي ﻧﻮﺷﺘﻦ ﺷﺪن آن ﻧﻴﺴﺖ ،ﺑﻠﻜﻪ اﺳﺘﻔﺎده از ﻛﻼس ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ اي دﻳﮕﺮ اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﻫﺮ ﺑﺎر ﺑﺮاي اﻳﺠﺎد ﻳﻚ اﺗﻮﻣﺒﻴﻞ ﺟﺪﻳﺪ ﻧﻴﺎز ﻧﺪارﻳﺪ ﻛﻪ اﺑﺘﺪا ﭼﺮخ را اﺧﺘﺮاع ﻛﻨﻴﺪ. ﻣﺸﻜﻞ اﻳﻦ روش اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن اﻳـﻦ ﻛﻼﺳـﻬﺎ ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ در ﺣﻘﻴﻘـﺖ ﻋـﻼوه ﺑـﺮ ﻧـﺴﺨﻪ اي ﻛـﻪ در ﻓﻮﻟـﺪر ﺑﺮﻧﺎﻣـﻪ ي Favorite Viewerﻗﺮار داﺷﺖ ﻳﻚ ﻛﭙﻲ از آﻧﻬﺎ را ﻧﻴﺰ در ﺑﺮﻧﺎﻣﻪ ﺧﻮد اﻳﺠﺎد ﻛﺮدﻳﻢ .اﻳﻦ روش راه ﻣﻨﺎﺳﺒﻲ ﻧﻴﺴﺖ ،زﻳﺮا ﺑـﻪ اﻳﻦ ﺗﺮﺗﻴﺐ دو ﻧﺴﺨﻪ از ﻛﻼس در دﻳﺴﻚ وﺟﻮد دارد و ﻓﻀﺎي ﺑﻴﺸﺘﺮي را اﺷﻐﺎل ﻣﻲ ﻛﻨﺪ .اﻟﺒﺘـﻪ ﺣﺠـﻢ اﻳـﻦ ﻛﻼﺳـﻬﺎ ﻛﻮﭼـﻚ اﺳـﺖ و ﻣﻤﻜﻦ اﺳﺖ اﻳﻦ اﺷﻐﺎل ﻓﻀﺎ در ﻣﻘﺎﺑﻞ ﻓﻮاﻳﺪي ﻛﻪ اراﻳﻪ ﻣﻲ دﻫﻨﺪ ﻧﺎﭼﻴﺰ ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ. ﻳﻚ روش دﻳﮕﺮ ﺑﺮاي اﻧﺠﺎم اﻳﻦ ﻛﺎر اﺳﺘﻔﺎده از ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس اﺳﺖ .ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس ،ﭘﺮوژه ﻫﺎي ﻣﺠﺰاﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﻓﻘﻂ ﺷﺎﻣﻞ ﻛﻼﺳﻬﺎي ﮔﻮﻧﺎﮔﻮن ﻣﻲ ﺷﻮﻧﺪ و ﻣﻲ ﺗﻮاﻧﻨﺪ ﺗﻮﺳﻂ ﭼﻨﺪﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮﻧﺪ .در ﻓﺼﻞ دوازدﻫﻢ ﺑﺎ اﻳﻦ ﻧﻮع ﭘﺮوژه ﻫـﺎ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﻣﻲ ﺷﻮﻳﻢ.
ﻧﺘﻴﺠﻪ: در ﻃﻲ اﻳﻦ ﻓﺼﻞ ﺳﻌﻲ ﻛﺮدﻳﻢ ﺑﺎ ﻣﺒﺎﺣﺚ ﭘﻴﺸﺮﻓﺘﻪ ي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا آﺷﻨﺎ ﺷﻮﻳﻢ .در اﺑﺘﺪا ي ﻓﺼﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛـﻪ ﭼﮕﻮﻧـﻪ ﻣﻲ ﺗﻮان ﭼﻨﺪﻳﻦ ﻧﺴﺨﻪ ي ﮔﻮﻧﺎﮔﻮن از ﻳﻚ ﻣﺘﺪ اﻳﺠﺎد ﻛﺮد ﻛﻪ ﻫﺮ ﻳﻚ ،ﭘﺎراﻣﺘﺮﻫﺎي ﺧﺎص ﺧﻮد را درﻳﺎﻓﺖ ﻛﻨﻨﺪ و ﭘﻴـﺎده ﺳـﺎزي ﺧـﺎص ﺧﻮد را ﻧﻴﺰ داﺷﺘﻪ ﺑﺎﺷﻨﺪ .ﻫﻤﭽﻨﻴﻦ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻋﻤﻠﮕﺮ ﻫﺎي ﻣﻮﺟﻮد در C#را ﺗﻐﻴﻴﺮ داد ﺗﺎ ﺑﺎ ﻛـﻼس ﻫـﺎﻳﻲ ﻛـﻪ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﻧﻴﺰ ﻛﺎر ﻛﻨﻨﺪ ،ﺑﺮاي ﻣﺜﺎل ﻋﻤﻠﮕﺮ +ﺑﺘﻮاﻧﺪ دو ﻣﺘﻐﻴﻴﺮ از ﻧﻮع ComplexNumberرا ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﺟﻤﻊ ﻛﻨﺪ. ﺳﭙﺲ ﺑﻪ ﻣﻌﺮﻓﻲ ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﭘﺮداﺧﺘﻴﻢ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ در ﺑﻴﻦ ﺗﻤﺎم اﺷﻴﺎﻳﻲ ﻛﻪ از ﻛﻼس ﺳﺎﺧﺘﻪ ﻣﻲ ﺷﻮﻧﺪ ﻣـﺸﺘﺮك ﺑﺎﺷـﻨﺪ ،و ﻓﻮاﻳﺪ اﺳﺘﻔﺎده از اﻳﻦ ﻧﻮع ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎ را ﻧﻴﺰ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ .در اداﻣﻪ ي ﺑﺨﺶ ﻧﻴﺰ ﺑﻪ اﻧﻮاع وﻳﮋه اي از وراﺛﺖ ،ﻳﻌﻨﻲ ﻛﻼﺳـﻬﺎي
٤٣٩
Sealedو ﻛﻼﺳﻬﺎي Abstractآﺷﻨﺎ ﺷﺪﻳﻢ و ﻣﻮارد اﺳﺘﻔﺎده از آﻧﻬﺎ را در ﺑﺮﻧﺎﻣﻪ ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ .ﺳﭙﺲ ﺑـﻪ ﻋﻨـﻮان آﺧـﺮﻳﻦ ﻣﺒﺤﺚ ﺗﺌﻮري در اي ﻓﺼﻞ ﺑﻪ ﻣﻌﺮﻓﻲ و ﻣﺮور اﺟﻤﺎﻟﻲ اﻳﻨﺘﺮﻓﻴﺲ ﻫﺎ ﭘﺮداﺧﺘﻴﻢ .اﻳﻨﺘﺮﻓﻴﺲ ﻫﺎ ﻛـﺎرﺑﺮد زﻳـﺎدي در ﺑﺮﻧﺎﻣـﻪ ﻧﻮﻳـﺴﻲ .NET دارﻧﺪ و در ﻓﺼﻞ ﻫﺎي ﺑﻌﺪ ﺑﻴﺸﺘﺮ از آﻧﻬﺎ اﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد. در ﭘﺎﻳﺎن ﻓﺼﻞ ﻧﻴﺰ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻋﻤﻠﻲ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻼﺳﻬﺎ اﻳﺠﺎد ﻛﺮدﻳﻢ ﺗﺎ ﺑﻪ ﻣﺰاﻳﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔـﺮا و ﻣﻬﻤﺘـﺮﻳﻦ آن ﻳﻌﻨـﻲ ﻗﺎﺑﻠﻴﺖ اﺳﺘﻔﺎده ﻣﺠﺪد از ﻛﺪ ﺑﻴﺸﺘﺮ ﭘﻲ ﺑﺒﺮﻳﻢ. در اﻳﻦ ﻓﺼﻞ ﻣﺒﺎﺣﺚ ﺗﺌﻮري زﻳﺎدي را ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ ،اﻣﺎ اﻳﻦ ﻣﺒﺎﺣﺚ از ﻣﻬﻤﺘﺮﻳﻦ ﻣﺒﺎﺣﺚ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا ﺑﻪ ﺷـﻤﺎر ﻣـﻲ روﻧـﺪ و درك آﻧﻬﺎ از اﻫﻤﻴﺖ زﻳﺎدي ﺑﺮﺧﻮردار اﺳﺖ .ﺑﻬﺘﺮ اﺳﺖ ﺑﺎ ﺑﺮرﺳﻲ ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﻛﺘﺎﺑﺨﺎﻧـﻪ ي ﻛـﻼس .NETو ﻳـﺎ ﻫـﺮ ﻛـﻼس دﻳﮕﺮي ﺳﻌﻲ ﻛﻨﻴﺪ ﺑﺮ اﻳﻦ ﻣﺒﺎﺣﺚ ﻣﺴﻠﻂ ﺷﻮﻳﺪ ،زﻳﺮا اﻳﻦ ﻣﻄﺎﻟﺐ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﺎرﺑﺮدي ﻧﻘﺶ زﻳﺎدي را اﻳﻔﺎ ﻣﻲ ﻛﻨﻨﺪ. در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ:
ﺳﺮﺑﺎر ﮔﺬاري ﻣﺘﺪﻫﺎي ﻣﺨﺘﻠﻒ و اﻳﺠﺎد ﭼﻨﺪ ﻧﺴﺨﻪ از ﻳﻚ ﻣﺘﺪ. ﺗﻌﺮﻳﻒ ﻧﺤﻮه ي ﻋﻤﻠﻜﺮد ﺟﺪﻳﺪ ﺑﺮاي ﻳﻚ ﻋﻤﻠﮕﺮ و ﺳﺮﺑﺎر ﮔﺬاري آن. اﻳﺠﺎد ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪ ﻫﺎي staticو ﭼﮕﻮﻧﮕﻲ اﺳﺘﻔﺎده از آﻧﻬﺎ در ﺑﺮﻧﺎﻣﻪ. ﻣﻔﻬﻮم و ﻧﺤﻮه ي ﻛﺎرﺑﺮد ﻛﻼﺳﻬﺎي abstractدر ﺑﺮﻧﺎﻣﻪ. ﻣﻔﻬﻮم و ﻧﺤﻮه ي ﻛﺎرﺑﺮد ﻛﻼﺳﻬﺎي sealedدر ﺑﺮﻧﺎﻣﻪ. ﭼﮕﻮﻧﮕﻲ ﺗﻌﺮﻳﻒ ﻳﻚ interfaceو ﺗﻔﺎوت آن ﺑﺎ ﻛﻼس ﻫﺎي ﻋﺎدي و ﻳﺎ ﻛﻼﺳﻬﺎي .abstract
٤٤٠
ﻓﺼﻞ ﻳﺎزدﻫﻢ :اﺷﻜﺎل زداﻳﻲ و ﻛﻨﺘﺮل ﺧﻄﺎ در ﺑﺮﻧﺎﻣﻪ اﺷﻜﺎل زداﻳﻲ ﻳﻜﻲ از ﻗﺴﻤﺘﻬﺎي ﻣﻬﻢ ﻫﺮ ﭘﺮوژه ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ آن ﻣﻲ ﺗﻮاﻧﻴﺪ ﺧﻄﺎﻫﺎي ﻣﻮﺟﻮد در ﻛﺪ ﺑﺮﻧﺎﻣﻪ و ﻳﺎ ﻣﻨﻄﻖ آن را ﻣﺘﻮﺟﻪ ﺷﺪه و رﻓﻊ ﻛﻨﻴﺪ .وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005اﺑﺰارﻫﺎي ﭘﻴﺸﺮﻓﺘﻪ اي ﺑﺮاي اﻳﻦ ﻛﺎر در اﺧﺘﻴﺎر ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﻗﺮار ﻣﻲ دﻫﺪ ﻛﻪ اﻳﻦ اﺑﺰارﻫﺎ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ وﺳﻴﻠﻪ ﺗﻤﺎم زﺑﺎﻧﻬﺎﻳﻲ ﻛﻪ ﺗﻮﺳﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ ﺷﻮﻧﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻧﺤﻮه ي اﺷﻜﺎل زداﻳﻲ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ اﺑﺰارﻫﺎ را در ﻳﻜﻲ از زﺑﺎﻧﻬﺎي وﻳـﮋوال اﺳـﺘﻮدﻳﻮ 2005ﻳـﺎد ﮔﺮﻓﺘﻴـﺪ ،ﻣـﻲ ﺗﻮاﻧﻴـﺪ از آن در ﺗﻤـﺎم زﺑﺎﻧﻬﺎي دﻳﮕﺮ ﻣﻮﺟﻮد در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﺻﺮﻓﻨﻈﺮ از اﻳﻦ ﻛﻪ ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺗﺎ ﭼﻪ اﻧﺪازه ﺧﻮب و ﻛﺎرآﻣﺪ ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ ،ﻫﻤﻮاره ﻣﻤﻜﻦ اﺳﺖ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﺷﺮاﻳﻂ ﭘﻴﺶ ﺑﻴﻨﻲ ﻧـﺸﺪه اي ﻣﻮاﺟﻪ ﺷﻮد ﻛﻪ ﺑﺎﻋﺚ ﺗﻮﻗﻒ اﺟﺮاي آن ﺷﻮد .اﮔﺮ در ﻛﺪ ﺑﺮﻧﺎﻣﻪ اﻳﻦ ﮔﻮﻧﻪ ﺷﺮاﻳﻂ را ﻛﻨﺘﺮل ﻧﻜﻨﻴﺪ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ در ﺣﺎﻟﺖ اﺟﺮا ﺑـﺎ اﻳﻦ ﺷﺮاﻳﻂ ﻣﻮاﺟﻪ ﺷﻮد ﭘﻴﻐﺎم ﺧﻄﺎي ﭘﻴﺶ ﻓﺮض CLRرا ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .اﻳﻦ ﭘﻴﻐﺎم ﺧﻄﺎ ﺑﻪ ﻛﺎرﺑﺮ اﻋﻼم ﻣﻲ ﻛﻨﺪ ﻛـﻪ ﻳـﻚ ﺧﻄـﺎي ﻛﻨﺘﺮل ﻧﺸﺪه در ﺑﺮﻧﺎﻣﻪ رخ داده اﺳﺖ و ﺷﺎﻣﻞ اﻃﻼﻋﺎﺗﻲ ﻓﻨﻲ در ﻣﻮرد ﺧﻄﺎي اﺗﻔﺎق اﻓﺘﺎده اﺳﺖ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ آن ﻧﻤﻲ ﺗﻮاﻧﺪ ﻣﺘﻮﺟﻪ ﺷﻮد ﻋﻠﺖ رﺧﺪاد ﺧﻄﺎ ﭼﻪ ﺑﻮده و ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﺪ آن را ﺗﺼﺤﻴﺢ ﻛﻨﺪ. در اﻳﻦ ﻣﻮاﻗﻊ اﺳﺖ ﻛﻪ اﻫﻤﻴﺖ ﻛﻨﺘﺮل ﺧﻄﺎ در ﺑﺮﻧﺎﻣﻪ ﻣﺸﺨﺺ ﻣﻲ ﺷﻮد .وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005داراي ﺗﻮاﺑﻊ و ﺳﺎﺧﺘﺎرﻫﺎﻳﻲ ﻋﻤﻮﻣﻲ ﺑﺮاي ﻛﻨﺘﺮل ﺧﻄﺎ در ﺑﺮﻧﺎﻣﻪ اﺳﺖ ﻛﻪ ﺑﻴﻦ ﺗﻤﺎم زﺑﺎﻧﻬﺎي آن ﻣﺸﺘﺮك اﺳﺖ .ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ ﺗﻮاﺑﻊ و ﺳﺎﺧﺘﺎرﻫﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﻗﺴﻤﺖ از ﻛﺪ ﺑﺮﻧﺎﻣـﻪ را ﺑﺮرﺳﻲ ﻛﺮده و ﻫﺮ ﺧﻄﺎﻳﻲ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ در آن ﻗﺴﻤﺖ رخ دﻫﺪ را ﻣﺸﺨﺺ ﻛﻨﻴﺪ .ﺳﭙﺲ ﻛـﺪي ﺑﻨﻮﻳـﺴﻴﺪ ﻛـﻪ اﮔـﺮ ﺧﻄـﺎﻳﻲ در آن ﻗﺴﻤﺖ از ﻛﺪ اﺗﻔﺎق اﻓﺘﺎد ،ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ دﻫﺪ و رخ دادن آن ﺧﻄﺎ و ﻧﺤﻮه ﺗﺼﺤﻴﺢ آن را اﻋﻼم ﻛﻨﺪ .ﻫﻤﭽﻨﻴﻦ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﺪون ﺗﻮﺟﻪ ﺑﻪ ﺧﻄﺎي اﺗﻔﺎق اﻓﺘﺎده ﺑﻪ اﺟﺮاي ﺧﻮد اداﻣﻪ دﻫﺪ. در اﻳﻦ ﻓﺼﻞ ﺑﻌﻀﻲ از وﻳﮋﮔﻴﻬﺎي اﺷﻜﺎل زداﻳﻲ ﻣﻮﺟﻮد در وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005را ﺑﺮرﺳﻲ ﻛﺮده و ﻧﺤﻮه اﺷﻜﺎل زداﻳـﻲ از ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ ﻧﻤﻮﻧﻪ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد .ﻫﻤﭽﻨﻴﻦ ﺑﺎ ﻧﺤﻮه اﺳﺘﻔﺎده از Breakpointﻫـﺎ در ﺑﺮﻧﺎﻣـﻪ ﺑـﺮاي ﺗﻮﻗـﻒ اﺟـﺮاي ﺑﺮﻧﺎﻣـﻪ در ﺧـﻂ ﻣﺸﺨﺼﻲ از ﻛﺪ و ﺑﺮرﺳﻲ وﺿﻌﻴﺖ ﺑﺮﻧﺎﻣﻪ در آن ﺧﻂ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ .ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ اﻣﻜﺎن و اﻣﻜﺎﻧﺎت ﻧﻈﻴﺮ آن ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﺘﻮﺟﻪ ﺷـﻮﻳﺪ ﻛﻪ در ﻫﺮ ﻟﺤﻈﻪ ﺑﺮﻧﺎﻣﻪ ﭼﻪ ﻛﺎري اﻧﺠﺎم ﻣﻲ دﻫﺪ. در اﻳﻦ ﻓﺼﻞ:
اﻧﻮاع ﺧﻄﺎﻫﺎﻳﻲ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﺷﻮﻧﺪ و ﻧﺤﻮه ﺗﺼﺤﻴﺢ ﻫﺮ ﻛﺪام از آﻧﻬﺎ را ﻓﺮا ﻣﻲ ﮔﻴﺮﻳﺪ. ﭼﮕﻮﻧﮕﻲ ﻳﺎﻓﺘﻦ ﺧﻄﺎﻫﺎي ﻣﻮﺟﻮد در ﻳﻚ ﺑﺮﻧﺎﻣﻪ و ﺗﺼﺤﻴﺢ آﻧﻬﺎ را ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﺪ. ﻧﺤﻮه ﻛﻨﺘﺮل ﺧﻄﺎﻫﺎ و ﺷﺮاﻳﻂ ﭘﻴﺶ ﺑﻴﻨﻲ ﻧﺸﺪه در ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
اﻧﻮاع ﻣﺨﺘﻠﻒ ﺧﻄﺎﻫﺎ: ﺧﻄﺎﻫﺎﻳﻲ ﻛﻪ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ رخ ﻣﻲ دﻫﻨﺪ ﺑﻪ ﺳﻪ دﺳﺘﻪ ﻛﻠﻲ ﺗﻘﺴﻴﻢ ﻣﻲ ﺷﻮﻧﺪ :ﺧﻄﺎﻫـﺎي دﺳـﺘﻮري ،ﺧﻄﺎﻫـﺎي زﻣـﺎن اﺟـﺮا و ﺧﻄﺎﻫـﺎي ﻣﻨﻄﻘﻲ .در اﻳﻦ ﺑﺨﺶ ﺑﻪ ﺑﺮرﺳﻲ اﻳﻦ ﺳﻪ ﻧﻮع ﺧﻄﺎ ﻣﻲ ﭘﺮدازﻳﻢ و ﺗﻔﺎوﺗﻬﺎي آﻧﻬﺎ را ﺑﻴﺎن ﻣﻲ ﻛﻨﻴﻢ.
ﺧﻄﺎﻫﺎي دﺳﺘﻮري:
٤٤١
ﺧﻄﺎﻫﺎي دﺳﺘﻮري 1ﺳﺎده ﺗﺮﻳﻦ ﻧﻮع ﺧﻄﺎﻫﺎ از ﻧﻈﺮ ﭘﻴﺪا ﻛﺮدن و رﻓﻊ ﻛﺮدن ﻫﺴﺘﻨﺪ .اﻳﻦ ﮔﻮﻧﻪ ﺧﻄﺎﻫﺎ ﻣﻌﻤﻮﻻً زﻣﺎﻧﻲ رخ ﻣﻲ دﻫﻨﺪ ﻛـﻪ ﻛﺪ ﻧﻮﺷﺘﻪ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ﺷﻤﺎ از ﻧﻈﺮ ﻛﺎﻣﭙﺎﻳﻠﺮ ﺧﻄﺎ داﺷﺘﻪ ﺑﺎﺷﺪ و ﻛﺎﻣﭙﺎﻳﻠﺮ ﻧﺘﻮاﻧﺪ آن را ﺗﻔﺴﻴﺮ ﻛﻨﺪ .ﻣﻤﻜﻦ اﺳﺖ دﺳـﺘﻮري را ﻧـﺎﻗﺺ وارد ﻛﺮده ﺑﺎﺷﻴﺪ ،ﺗﺮﺗﻴﺐ ﻧﻮﺷﺘﻦ دﺳﺘﻮرات را رﻋﺎﻳﺖ ﻧﻜﺮده ﺑﺎﺷﻴﺪ و ﻳﺎ ﺣﺘﻲ ﻋﻤﻮﻣﻲ ﺗﺮ از ﻫﻤﻪ آﻧﻬـﺎ اﻳﻨﻜـﻪ در وارد ﻛـﺮدن دﺳـﺘﻮرات ﺧﻄـﺎي ﺗﺎﻳﭙﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ ﻛﻪ ﻣﺘﻐﻴﺮي را در ﺑﺮﻧﺎﻣﻪ ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﺪ و ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﻧـﺎم آن را اﺷﺘﺒﺎه وارد ﻣﻲ ﻛﻨﻴﺪ. ﻣﺤﻴﻂ ﻃﺮاﺣﻲ و ﺗﻮﺳﻌﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005 .NETداراي اﺑﺰاري ﻗﻮي ﺑﺮاي ﺑﺮرﺳﻲ درﺳـﺘﻲ دﺳـﺘﻮرات وارد ﺷـﺪه ﺗﻮﺳـﻂ ﺑﺮﻧﺎﻣـﻪ ﻧﻮﻳﺲ اﺳﺖ .ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ اﺑﺰار اﺣﺘﻤﺎل اﻳﺠﺎد ﺧﻄﺎي دﺳﺘﻮري ﺑﻪ ﺷﺪت ﻛﺎﻫﺶ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ ،اﻣﺎ ﺑﺎز ﻫﻢ اﻳﻦ اﺣﺘﻤﺎل ﺑﻪ ﺻﻔﺮ ﻧﻤﻲ رﺳﺪ و ﻣﻤﻜﻦ اﺳﺖ ﭼﻨﻴﻦ ﺧﻄﺎﻫﺎﻳﻲ در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﺷﻮﻧﺪ. ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﻣﺘﻐﻴﺮي را درون ﻳﻚ زﻳﺮ ﺑﺮﻧﺎﻣﻪ از ﻧﻮع privateﺗﻌﺮﻳﻒ ﻛﺮده اﻳﺪ .ﺑﻼﻓﺎﺻﻠﻪ ﺑﻌﺪ از ﻧﻮﺷﺘﻦ ﭼﻨﻴﻦ ﻛﺪي، وﻳﮋوال اﺳﺘﻮدﻳﻮ زﻳﺮ آن ﺧﻂ ﻗﺮﻣﺰي ﻗﺮار ﻣﻲ دﻫﺪ ﻛﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ اﻳﻦ ﻧﻮع ﺗﻌﺮﻳﻒ از ﻧﻈﺮ ﻛﺎﻣﭙـﺎﻳﻠﺮ ﻧﺎدرﺳـﺖ اﺳـﺖ .ﺣـﺎل اﮔـﺮ ﺑـﺎ ﻣﺎوس روي ﻋﺒﺎرت ﻣﺸﺨﺺ ﺷﺪه ﺑﺮوﻳﺪ ،ﻛﺎدر ﻛﻮﭼﻜﻲ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و ﻋﻠﺖ ﻧﺎدرﺳﺖ ﺑﻮدن آن را ﺑﻴﺎن ﻣﻲ ﻛﻨﺪ .ﺑﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ آن را اﺻﻼح ﻛﻨﻴﺪ )ﺷﻜﻞ .(1-11
ﺷﻜﻞ 1-11 روش دﻳﮕﺮي ﺑﺮاي ﻣﺸﺎﻫﺪه ﺗﻤﺎم ﺧﻄﺎﻫﺎي دﺳﺘﻮري ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده از ﭘﻨﺠـﺮه Error Listاﺳـﺖ .در اﻳـﻦ ﭘﻨﺠـﺮه ﺟﺪوﻟﻲ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﻛﻪ در آن ﺧﻄﺎﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ ﻟﻴﺴﺖ ﺷﺪه اﻧﺪ .در ﻣﻘﺎﺑﻞ ﻫﺮ ﺧﻄﺎ ﻧﻴﺰ ﺗﻮﺿﻴﺤﻲ درﺑـﺎره ي آن ﺧﻄـﺎ، ﻧﺎم ﻓﺎﻳﻞ ﺣﺎوي ﺧﻄﺎ ،ﺷﻤﺎره ﺳﻄﺮ و ﺳﺘﻮن ﺧﻄﺎ و ﻫﻤﭽﻨﻴﻦ ﻧﺎم ﭘﺮوژه اي ﻛﻪ ﺧﻄﺎ در آن رخ داده ،آورده ﺷﺪه اﺳﺖ. ﭘﻨﺠﺮه Error Listدر ﭘﺎﻳﻴﻦ ﻣﺤﻴﻂ ﻃﺮاﺣﻲ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻗﺮار دارد .ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻳﻦ ﭘﻨﺠﺮه ﻧﻤـﺎﻳﺶ داده ﺷـﺪ ،ﺑـﺎ دو ﺑـﺎر ﻛﻠﻴﻚ ﻛﺮدن روي ﻫﺮ ﺧﻄﺎ ﻣﻜﺎن ﻧﻤﺎ ﺑﻪ ﺧﻂ ﺷﺎﻣﻞ ﺧﻄﺎ ﻣﻨﺘﻘﻞ ﻣﻲ ﺷﻮد و ﻣﻲ ﺗﻮاﻧﻴﺪ ﺧﻄﺎ را ﺑﺮرﺳﻲ ﻛﺮده و ﺗﺼﺤﻴﺢ ﻛﻨﻴﺪ. ﺑﻌﻀﻲ ﻣﻮاﻗﻊ زﻳﺮ ﻗﺴﻤﺘﻬﺎﻳﻲ از ﻛﺪ ﺧﻂ ﺳﺒﺰ ﻛﺸﻴﺪه ﻣﻲ ﺷﻮد .اﻳﻦ ﺧﻄﻬﺎ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﻫﺸﺪارﻫﺎﻳﻲ در ﻛﺪ ﻫﺴﺘﻨﺪ و از ﻛﺎﻣﭙﺎﻳـﻞ ﺷـﺪن ﻛﺪ ﺟﻠﻮﮔﻴﺮي ﻧﻤﻲ ﻛﻨﻨﺪ .اﻟﺒﺘﻪ ﺑﻬﺘﺮ اﺳﺖ ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﻗﺒﻞ از اﺟﺮاي ﺑﺮﻧﺎﻣﻪ اﻳﻦ ﻫﺸﺪارﻫﺎ را ﻧﻴﺰ ﺗـﺼﺤﻴﺢ ﻛﻨﻴـﺪ ،زﻳـﺮا ﻣﻤﻜـﻦ اﺳـﺖ در ﻫﻨﮕﺎم اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﻮﺟﺐ ﺑﻪ وﺟﻮد آﻣﺪن ﺷﺮاﻳﻂ ﻧﺎ ﻣﻄﻠﻮﺑﻲ ﺷﻮﻧﺪ. ﺑﻪ ﻋﻨﻮان ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ ﻛﻪ در ﻳﻚ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻣﺘﻐﻴﺮي را ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﺪ ،اﻣﺎ ﺗﺎ ﭘﺎﻳﺎن آن زﻳﺮ ﺑﺮﻧﺎﻣﻪ از ﻣﺘﻐﻴﺮ ﺗﻌﺮﻳـﻒ ﺷـﺪه اﺳـﺘﻔﺎده اي ﻧﻤﻲ ﻛﻨﻴﺪ .در اﻳﻦ ﺷﺮاﻳﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ زﻳﺮ اﻳﻦ ﻣﺘﻐﻴﺮ ﺧﻂ ﺳﺒﺰي ﻗﺮار ﻣﻲ دﻫﺪ ﺗﺎ ﻫﺸﺪاري را در اﻳﻦ ﻗﺴﻤﺖ ﻣﺸﺨﺺ ﻛﻨﺪ .ﺑﺮاي ﺗﺼﺤﻴﺢ اﻳﻦ ﻫﺸﺪار اﮔﺮ ﺑﻪ اﻳﻦ ﻣﺘﻐﻴﺮ در زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺎز دارﻳﺪ از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﺧﻂ ﻣﺮﺑﻮط ﺑﻪ ﺗﻌﺮﻳﻒ آن را ﭘـﺎك ﻛﻨﻴﺪ. ﻳﻜﻲ از وﻳﮋﮔﻴﻬﺎي دﻳﮕﺮ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻛﻪ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﺧﻄﺎﻫﺎي دﺳﺘﻮري در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺣﺪاﻗﻞ ﺑﺮﺳﻨﺪ ،وﻳﮋﮔﻲ ﺗﻜﻤﻴﻞ ﺧﻮدﻛـﺎر ﻣﺘﻦ ﻳﺎ IntelliSenseاﺳﺖ .ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ وﻳﮋﮔﻲ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﻛﺪي را ﺑﻨﻮﻳﺴﻴﺪ ﻛﺎدري ﺑﺎز ﻣﻲ ﺷﻮد و ﺑـﺮ اﺳـﺎس ﭼﻨﺪﻳﻦ ﻓﺎﻛﺘﻮر ﻣﺨﺘﻠﻒ از ﻗﺒﻴﻞ ﺣﺮوﻓﻲ ﻛﻪ وارد ﻛﺮده اﻳﺪ ،دﺳﺘﻮرات ﻗﺒﻠﻲ و ﻳﻚ ﺳﺮي اﻃﻼﻋﺎت دﻳﮕﺮ ،ﻛﻠﻤﻪ اي را ﺑـﺮاي ﻗـﺮار دادن در آن ﻣﻜﺎن ﭘﻴﺸﻨﻬﺎد ﻣﻲ ﻛﻨﺪ )ﺷﻜﻞ .(2-11ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺳﺮﻋﺖ و ﺑﺪون اﻳﻨﻜﻪ ﭼﻴﺰي را ﺑﻪ ﺧـﺎﻃﺮ ﺑـﺴﭙﺎرﻳﺪ ،ﻧـﺎم اﻋـﻀﺎي ﻛﻼﺳﻬﺎ ،ﻧﺎم ﺳﺎﺧﺘﺎرﻫﺎ و ﻳﺎ ﻓﻀﺎي ﻧﺎﻣﻬﺎﻳﻲ ﻛﻪ ﺑﺎ آﻧﻬﺎ ﻛﺎر ﻣﻲ ﻛﻨﻴﺪ را در ﺑﺮﻧﺎﻣﻪ وارد ﻛﻨﻴﺪ.
Syntax Errors
1
٤٤٢
ﺷﻜﻞ 2-11 ﻫﻤﭽﻨﻴﻦ اﮔﺮ در اﻳﻦ ﻟﻴﺴﺖ ﺑﺮاي ﻣﺪت ﻛﻮﺗﺎﻫﻲ روي ﻳﻚ ﮔﺰﻳﻨﻪ ﺻﺒﺮ ﻛﻨﻴﺪ ،ﻛﺎدر ﻛﻮﭼﻜﻲ ﻛﻪ ﺣﺎوي ﻣﺘﻦ راﻫﻨﻤﺎﻳﻲ در ﻣـﻮرد ﮔﺰﻳﻨـﻪ ي اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ،ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﻣﺘﻦ راﻫﻨﻤﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد اﻃﻼﻋﺎت ﻣﻔﻴﺪي را ﺑﺮاي ﻫـﺮ ﻣﺘـﺪ و ﻳـﺎ ﻋﻀﻮ ﻛﻼس ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .ﺑﺮاي ﻣﺜﺎل در اﻳﻦ ﭘﻨﺠﺮه ﻧﺎم و ﻧﻮع ﺗﻤﺎم ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي ﻓﺮاﺧﻮاﻧﻲ ﻳﻚ ﻣﺘﺪ ﻻزم اﺳﺖ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﭘﺎراﻣﺘﺮﻫﺎي ﻳﻚ ﻣﺘﺪ را ﺑﻪ ﺧﺎﻃﺮ ﺑﺴﭙﺎرﻳﺪ و اﺣﺘﻤﺎل اﻳﺠﺎد ﺧﻄﺎ را ﻧﻴـﺰ در ﻓﺮاﺧـﻮاﻧﻲ آن ﻛـﺎﻫﺶ ﻣﻲ دﻫﺪ .ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﻛﺎدر ﺗﻌﺪاد ﻧﺴﺨﻪ ﻫﺎﻳﻲ ﻛﻪ از ﻳﻚ ﻣﺘﺪ ﻣﻮﺟﻮد اﺳﺖ ﻧﻴﺰ ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ در اﻳـﻦ ﻛـﺎدر ﮔﻔﺘـﻪ ﻣﻲ ﺷﻮد ﻛﻪ اﻳﻦ ﺗﺎﺑﻊ ﺑﻪ ﭼﻨﺪ ﺻﻮرت ﺳﺮﺑﺎر ﮔﺬاري ﺷﺪه اﺳﺖ .ﻋﻼوه ﺑﺮ اﻳﻦ ﻣﻮارد ،ﺧﻄﺎﻫﺎﻳﻲ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﻫﻨﮕﺎم اﺟﺮاي اﻳﻦ ﺗﺎﺑﻊ رخ دﻫﺪ ﻧﻴﺰ در ﭘﺎﻳﻴﻦ اﻳﻦ ﻛﺎدر ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد. ﺑﻪ ﻋﻨﻮان ﻣﺜﺎل ﻛﺎدر راﻫﻨﻤﺎﻳﻲ ﻛﻪ در ﺷﻜﻞ 3-11ﻧﻤﺎﻳﺶ داده ﺷﺪه اﺳـﺖ ﻣـﺸﺨﺺ ﻣـﻲ ﻛﻨـﺪ ﻛـﻪ ورودي ﻣﺘـﺪ SubString ﻣﻘﺪاري از ﻧﻮع ﻋﺪد ﺻﺤﻴﺢ ﺑﻮده و ﺧﺮوﺟﻲ آن ﻳﻚ ﻣﺘﻐﻴﻴﺮ رﺷﺘﻪ اي اﺳﺖ .ﻋﺒـﺎرت ") "(+1 Overloadsﻣـﺸﺨﺺ ﻣـﻲ ﻛﻨﺪ ﻛﻪ دو ﻧﺴﺨﻪ ي ﻣﺘﻔﺎوت از اﻳﻦ ﻣﺘﺪ وﺟﻮد دارد .ﻫﻤﭽﻨﻴﻦ در ﭘﺎﻳﻴﻦ اﻳﻦ ﻛﺎدر ﻣﺸﺨﺺ ﻣﻲ ﺷﻮد ﻛﻪ اﻳﻦ ﺗﺎﺑﻊ ﻣﻤﻜﻦ اﺳﺖ ﺧﻄـﺎﻳﻲ را از ﻧﻮع System.ArgumentOutOfRangeExceptionاﻳﺠﺎد ﻛﻨﺪ ﻛﻪ ﺑﺎﻳﺪ ﻫﻨﮕـﺎم ﻧﻮﺷـﺘﻦ ﺑﺮﻧﺎﻣـﻪ در ﻧﻈـﺮ ﮔﺮﻓﺖ.
ﺷﻜﻞ 3-11
٤٤٣
ﻋﻼوه ﺑﺮ اﻳﻦ ﻣﻮرد ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻧﺎم ﻳﻚ ﻣﺘﺪ را در ﺑﺮﻧﺎﻣﻪ ﺑﻨﻮﻳﺴﻴﺪ و ﺑﺨﻮاﻫﻴﺪ ﭘﺎراﻣﺘﺮﻫﺎي آن را وارد ﻛﻨﻴﺪ ،ﻛﺎدر راﻫﻨﻤﺎي دﻳﮕﺮي ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﭘﺎراﻣﺘﺮﻫﺎي ﻳﻜﻲ از ﻧﺴﺨﻪ ﻫﺎي ﻣﺘﺪ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .اﮔﺮ از اﻳﻦ ﻣﺘﺪ ﺑﻴﺶ از ﻳـﻚ ﻧـﺴﺨﻪ وﺟـﻮد داﺷﺘﻪ ﺑﺎﺷﺪ ،ﺑﺎ ﻓﺸﺎر دادن ﻛﻠﻴﺪﻫﺎي ﻣﻜﺎن ﻧﻤﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﻧﺴﺨﻪ ﻫﺎي دﻳﮕﺮ را ﻧﻴﺰ ﻣﺸﺎﻫﺪه ﻛﻨﻴـﺪ .ﻫﻤﭽﻨـﻴﻦ در اﻳـﻦ ﻛﺎدر ﻧﺎم و ﻧﻮع ﭘﺎراﻣﺘﺮﻫﺎي ﺗﺎﺑﻊ و ﺗﻮﺿﻴﺢ ﻫﺮ ﻛﺪام از ﭘﺎراﻣﺘﺮ ﻫﺎ ﻧﻴﺰ آورده ﺷﺪه اﺳﺖ )ﺷﻜﻞ .(4-11
ﺷﻜﻞ 4-11 ﻋﻼوه ﺑﺮ اﻳﻦ ﻣﻮارد ،وﻳﮋﮔﻴﻬﺎي ﺑﺴﻴﺎر دﻳﮕﺮي در ﻣﺤﻴﻂ ﺗﻮﺳﻌﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ وﺟﻮد دارد ﻛﻪ ﺑﺎﻋﺚ ﻛﻤﺘﺮ ﺷﺪن ﺧﻄﺎﻫﺎي دﺳﺘﻮري ﻣـﻲ ﺷﻮد .ﺗﻨﻬﺎ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﺪ ،اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺎ ﺷﻨﺎﺧﺖ اﻳﻦ وﻳﮋﮔﻴﻬﺎ و اﺳﺘﻔﺎده ﺻﺤﻴﺢ از آﻧﻬﺎ از ﺑﻪ وﺟﻮد آﻣﺪن ﺧﻄﺎﻫﺎي دﺳﺘﻮري در ﺑﺮﻧﺎﻣﻪ ﺟﻠﻮﮔﻴﺮي ﻛﻨﻴﺪ.
ﺧﻄﺎﻫﺎي اﺟﺮاﻳﻲ: ﺧﻄﺎﻫﺎي اﺟﺮاﻳﻲ 1و ﻳﺎ ﺧﻄﺎﻫﺎي زﻣﺎن اﺟﺮا 2ﺧﻄﺎﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ در زﻣﺎن اﺟﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ رخ ﻣﻲ دﻫﻨﺪ .اﻳﻦ ﺧﻄﺎﻫﺎ ﻋﻤﻮﻣﺎً ﺑﻪ اﻳﻦ ﻋﻠﺖ رخ ﻣﻲ دﻫﻨﺪ ﻛﻪ ﺑﻌﻀﻲ از ﻋﻮاﻣﻞ ﺧﺎرج از ﺑﺮﻧﺎﻣﻪ ﻣﺎﻧﻨﺪ ﻛﺎرﺑﺮ ،ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ،دﻳـﺴﻚ ﺳـﺨﺖ ﻣﻮﺟـﻮد در ﻛـﺎﻣﭙﻴﻮﺗﺮ و ﻳـﺎ … رﻓﺘﺎري ﻏﻴﺮ ﻗﺎﺑﻞ ﭘﻴﺶ ﺑﻴﻨﻲ از ﺧﻮد ﺑﺮوز ﻣﻲ دﻫﻨﺪ. در ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻫﻤﻮاره اﻳﻦ ﻧﻮع ﻣﺴﺎﺋﻞ را ﻧﻴﺰ ﺑﺎﻳﺪ ﻣﺪﻧﻈﺮ ﻗﺮار داد و ﻛﺪ ﻣﻨﺎﺳﺒﻲ ﺑﺮاي ﻛﻨﺘﺮل رخ دادن اﻳﻦ ﺧﻄﺎﻫـﺎ ﻧﻮﺷـﺖ. اﻟﺒﺘﻪ ﻧﻤﻲ ﺗﻮان از رخ دادن ﭼﻨﻴﻦ ﺧﻄﺎﻫﺎﻳﻲ در ﺑﺮﻧﺎﻣﻪ ﺟﻠﻮﮔﻴﺮي ﻛﺮد ،اﻣﺎ ﻣﻲ ﺗﻮان ﺑﺎ ﻧﻮﺷﺘﻦ ﻛﺪ ﻫﺎي ﻣﻨﺎﺳﺐ ﺑﺮاي ﻛﻨﺘﺮل آﻧﻬـﺎ ،ﻫﻨﮕـﺎم ﺑﺮوز ﭼﻨﻴﻦ ﺧﻄﺎﻫﺎﻳﻲ ﻳﺎ ﺑﺎ ﻧﻤﺎﻳﺶ ﭘﻴﻐﺎم ﻣﻨﺎﺳﺐ از ﺑﺮﻧﺎﻣﻪ ﺧﺎرج ﺷﺪ و ﻳﺎ ﺑﺪون در ﻧﻈﺮ ﮔﺮﻓﺘﻦ ﺧﻄﺎ از اﺟﺮاي ﺑﻘﻴﻪ ﻛﺪ ﺻﺮﻓﻨﻈﺮ ﻛـﺮد و ﺑـﻪ ﻛﺎرﺑﺮ اﻃﻼع داد ﻛﻪ ﭼﮕﻮﻧﻪ از ﺑﺮوز ﻣﺠﺪد اﻳﻦ ﺧﻄﺎ ﺟﻠﻮﮔﻴﺮي ﻛﻨﺪ .ﻧﺤﻮه ﻛﻨﺘﺮل ﺧﻄﺎﻫﺎي زﻣﺎن اﺟﺮا در ﻗﺴﻤﺘﻬﺎي ﺑﻌﺪي اﻳـﻦ ﻓـﺼﻞ ﺑـﻪ ﺗﻔﺼﻴﻞ ﺷﺮح داده ﺷﺪه اﺳﺖ. ﺧﻄﺎﻫﺎي اﺟﺮاﻳﻲ ﻣﻌﻤﻮﻻً ﻫﻨﮕﺎم ﺗﺴﺖ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ در زﻣﺎن ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ﻣﺸﺨﺺ ﻣﻲ ﺷﻮﻧﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﻌﺪ از ﺗﺸﺨﻴﺺ آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻛﺪي ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ رﻓﺘﺎر ﺑﺮﻧﺎﻣﻪ را در آن ﺷﺮاﻳﻂ ﻛﻨﺘﺮل ﻛﻨﺪ و از ﺗﻮﻗﻒ ﻧﺎﮔﻬﺎﻧﻲ ﺑﺮﻧﺎﻣﻪ ﺟﻠﻮﮔﻴﺮي ﻛﻨﻴﺪ .ﻧﺤﻮه اﻳﻦ ﻛﺎر در ﺑﺨﺶ اﺷﻜﺎل زداﻳﻲ در اداﻣﻪ ي ﻓﺼﻞ ﻛﺎﻣﻼً ﺗﻮﺿﻴﺢ داده ﺷﺪه اﺳﺖ.
ﺧﻄﺎﻫﺎي ﻣﻨﻄﻘﻲ:
Execution Errors Run-Time Errors
1 2
٤٤٤
ﺧﻄﺎﻫﺎي ﻣﻨﻄﻘﻲ 1ﻳﺎ ﺧﻄﺎﻫﺎي ﻣﻔﻬﻮﻣﻲ ،ﺧﻄﺎﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮﻧﺪ ﺑﺮﻧﺎﻣﻪ ﻧﺘﺎﻳﺞ ﻧﺎ ﻣﻄﻠﻮﺑﻲ را ﺗﻮﻟﻴﺪ ﻛﻨﺪ .اﺣﺘﻤﺎﻻً ﺑﻴـﺸﺘﺮﻳﻦ ﻧﻮع ﺧﻄﺎﻫﺎي ﻣﻨﻄﻘﻲ ﻛﻪ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ وﺟﻮد ﻣﻲ آﻳﻨﺪ ،ﺣﻠﻘﻪ ﻫﺎي ﺑﻲ ﻧﻬﺎﻳﺖ ﻫﺴﺘﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻛﺪ زﻳﺮ را در ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ: )(private void PerformLoopExample { ;int intIndex )while (intIndex < 10 { // Some logic here } } اﮔﺮ در ﻛﺪ داﺧﻞ اﻳﻦ ﺣﻠﻘﻪ ﻣﻘﺪار intIndexﺑﻪ ﻧﺤﻮي ﺗﻐﻴﻴﺮ ﻧﻜﻨﺪ ﻛﻪ ﺑﻪ ﻋﺪدي ﺑﺰرﮔﺘﺮ از 10ﺑﺮﺳﺪ ،ﺑﺮﻧﺎﻣﻪ در ﻳﻚ ﺣﻠﻘﻪ ﺑﻴﻨﻬﺎﻳﺖ ﻗﺮار ﻣﻲ ﮔﻴﺮد .اﻳﻦ ﻳﻚ ﻣﺜﺎل ﺳﺎده از ﺧﻄﺎﻫﺎي ﻣﻨﻄﻘﻲ در ﺑﺮﻧﺎﻣﻪ ﺑﻮد ،اﻣﺎ ﺣﺘﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﺑﺎ ﺗﺠﺮﺑﻪ ﻧﻴﺰ ﻣﻤﻜﻦ اﺳﺖ در ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﻛﺪ دﭼﺎر ﭼﻨﻴﻦ ﺧﻄﺎﻫﺎﻳﻲ در ﺑﺮﻧﺎﻣﻪ ﺧﻮد ﺷﻮﻧﺪ. ﭘﻴﺪا ﻛﺮدن ﺧﻄﺎﻫﺎي ﻣﻨﻄﻘﻲ و رﻓﻊ آﻧﻬﺎ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﻌﻤﻮﻻً از دﻳﮕﺮ ﺧﻄﺎﻫﺎ ﻣﺸﻜﻞ ﺗﺮ اﺳﺖ ،زﻳﺮا ﺑﺮاي ﺗـﺸﺨﻴﺺ آﻧﻬـﺎ ﺑﺎﻳـﺪ ﻋﻤﻠﻜـﺮد ﺗﻤﺎم ﻗﺴﻤﺘﻬﺎي ﺑﺮﻧﺎﻣﻪ را در ﻣﻘﺎﺑﻞ ﻣﻘﺎدﻳﺮ ﻣﺨﺘﻠﻒ ورودي ﺑﺮرﺳﻲ ﻛﺮده و ﻣﺸﺎﻫﺪه ﻛﺮد ﻛﻪ آﻳﺎ ﻧﺘﻴﺠﻪ ﻣﻄﻠﻮب ﺗﻮﺳـﻂ ﺑﺮﻧﺎﻣـﻪ ﺗﻮﻟﻴـﺪ ﻣـﻲ ﺷﻮد ﻳﺎ ﻧﻪ؟ ﺧﻄﺎي ﻣﻨﻄﻘﻲ دﻳﮕﺮي ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﺷﻮد ،ﺧﻄﺎ در ﻣﻘﺎﻳﺴﻪ ﻫﺎ اﺳﺖ .ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻣﻘـﺪار ﻳـﻚ ﻣﺘﻐﻴﺮ را ﺑﺎ ورودي ﻛﺎرﺑﺮ ﻣﻘﺎﻳﺴﻪ ﻛﺮده و در ﺻﻮرت ﺑﺮاﺑﺮ ﺑﻮدن اﻳﻦ دو ﻣﻘﺪار ،ﻋﻤﻞ ﺧﺎﺻـﻲ را در ﺑﺮﻧﺎﻣـﻪ اﻧﺠـﺎم دﻫﻴـﺪ .در اﻳـﻦ ﺷـﺮاﻳﻂ ﻣﻌﻤﻮﻻً ﻧﻤﻲ ﺧﻮاﻫﻴﺪ ﻛﻪ ﻣﻘﺎﻳﺴﻪ ﻧﺴﺒﺖ ﺑﻪ ﺑﺰرﮔﻲ و ﻛﻮﭼﻜﻲ ﺣﺮوف ﺣﺴﺎس ﺑﺎﺷﺪ .ﻓﺮض ﻛﻨﻴﺪ ﺑﺮاي اﻳﻦ ﻣﻘﺎﻳﺴﻪ از ﻛﺪ زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ: )if (strFileName == txtInput.Text { // Perform some logic here } در اﻳﻦ ﺷﺮاﻳﻂ ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ strFileNameﺑﺮاﺑﺮ ﺑﺎ Index.Htmlو ﻣﻘﺪار ﻣﻮﺟـﻮد در TextBox ﺑﺮاﺑﺮ ﺑﺎ index.htmlﺑﺎﺷﺪ ،ﻧﺘﻴﺠﻪ ﻣﻘﺎﻳﺴﻪ ﻧﺎدرﺳﺖ ﺧﻮاﻫﺪ ﺑﻮد و ﻛﺪ داﺧﻞ دﺳﺘﻮر ifاﺟـﺮا ﻧﺨﻮاﻫـﺪ ﺷـﺪ .ﻳﻜـﻲ از روﺷـﻬﺎي ﺟﻠﻮﮔﻴﺮي از اﻳﻦ ﺧﻄﺎﻫﺎ در اﻳﻦ اﺳﺖ ﻛﻪ اﺑﺘﺪا ،ﻫﺮ دو ﻣﻘﺪاري ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﺎ ﻫﻢ ﻣﻘﺎﻳﺴﻪ ﻛﻨﻴﺪ را ﺑﻪ ﺣﺮوف ﺑﺰرگ و ﻳﺎ ﺣﺮوف ﻛﻮﭼﻚ ﺗﺒﺪﻳﻞ ﻛﻨﻴﺪ )ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺗﻮاﺑﻊ ToUpperو ﻳﺎ ToLowerدر ﻛـﻼس Stringاﺳـﺘﻔﺎده ﻛﻨﻴـﺪ( .ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴﺐ اﮔﺮ ﻣﺘﻨﻲ ﻛﻪ ﻛﺎرﺑﺮ در TextBoxوارد ﻛﺮده اﺳﺖ ﺑﺎ ﻣﺘﻦ ﻣﻮﺟﻮد در ﻣﺘﻐﻴﻴﺮ strFileNameﺑﺮاﺑـﺮ ﺑﺎﺷـﺪ و ﻓﻘـﻂ از ﻧﻈﺮ ﺑﺰرﮔﻲ و ﻳﺎ ﻛﻮﭼﻜﻲ ﻛﺎراﻛﺘﺮ ﻫﺎ ﺑﺎ ﻫﻢ ﺗﻔﺎوت داﺷﺘﻪ ﺑﺎﺷﻨﺪ ﺣﺎﺻﻞ ﻣﻘﺎﻳﺴﻪ درﺳﺖ ﺧﻮاﻫﺪ ﺑﻮد. ﻧﻜﺘﻪ :ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﺧﻄﺎﻫﺎي ﻣﻨﻄﻘﻲ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺳﺨﺖ ﺗﺮﻳﻦ ﻧﻮع ﺧﻄﺎﻫﺎ از ﻧﻈﺮ ﺗﺸﺨﻴﺺ و رﻓﻊ ﻫﺴﺘﻨﺪ و ﻫﻤﭽﻨﻴﻦ ﻣﻤﻜـﻦ اﺳـﺖ ﺑﺎﻋﺚ ﺗﻮﻗﻒ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ و ﻳﺎ ﺗﻮﻟﻴﺪ ﻧﺘﻴﺠﻪ ﻧﺎﻣﻄﻠﻮب ﺗﻮﺳﻂ آن ﺷﻮﻧﺪ ﺑﺎﻳﺪ ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﻛﺪ از درﺳﺖ ﺑﻮدن ﻣﻨﻄﻖ آن اﻃﻤﻴﻨﺎن ﺣﺎﺻـﻞ ﻛﻨﻴﺪ و ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ ﻛﻪ روﺷﻲ ﻛﻪ ﺑﺮاي اﺟﺮاي اﻳﻦ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻛﺎر ﻣﻲ ﺑﺮﻳﺪ درﺳﺖ اﺳﺖ .ﻫﻤﭽﻨﻴﻦ ﺑﺎﻳﺪ ﺗﻤـﺎم ﺧﻄﺎﻫـﺎﻳﻲ ﻛـﻪ ﻣﻤﻜﻦ اﺳﺖ ﺑﻪ وﺳﻴﻠﻪ ﻛﺎرﺑﺮ در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﺷﻮد را ﻧﻴﺰ ﺑﺮرﺳﻲ ﻛﺮده و ﻛﻨﺘﺮل ﻛﻨﻴﺪ .ﻫﺮ ﭼﻪ ﻛﻪ ﺑﻴﺸﺘﺮ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳـﺴﻲ ﺗﺠﺮﺑـﻪ ﻛـﺴﺐ ﻛﻨﻴﺪ ،ﺑﻴﺸﺘﺮ ﺑﺎ ﺧﻄﺎﻫﺎي ﻋﻤﻮﻣﻲ و ﺧﻄﺎﻫﺎﻳﻲ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺗﻮﺳﻂ ﻛﺎرﺑﺮ اﻳﺠﺎد ﺷﻮﻧﺪ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. Logic Errors
1
٤٤٥
ﻳﻜﻲ از ﺑﻬﺘﺮﻳﻦ راه ﻫﺎ ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن و از ﺑﻴﻦ ﺑﺮدن ﺧﻄﺎﻫﺎي ﻣﻨﻄﻘﻲ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده از اﻣﻜﺎﻧـﺎت اﺷـﻜﺎل زداﻳـﻲ ﺑﺮﻧﺎﻣـﻪ اﺳﺖ ﻛﻪ در وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﻗﺮار دارد .ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ اﻣﻜﺎﻧﺎت و وﻳﮋﮔﻴﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ راﺣﺘﻲ ﺣﻠﻘﻪ ﻫﺎي ﺑﻲ ﻧﻬﺎﻳﺖ را ﺗﺸﺨﻴﺺ داده و ﻳﺎ ﺑﻪ ﺗﺼﺤﻴﺢ ﻣﻘﺎﻳﺴﻪ ﻫﺎي ﻧﺎدرﺳﺖ در ﺑﺮﻧﺎﻣﻪ ﺑﭙﺮدازﻳﺪ.
اﺷﻜﺎل زداﻳﻲ: اﺷﻜﺎل زداﻳﻲ از ﻳﻚ ﺑﺮﻧﺎﻣﻪ ،ﻫﻤﻮاره ﺑﺨﺸﻲ ﺟﺪا ﻧﺸﺪﻧﻲ از ﻣﺮاﺣﻞ ﻧﻮﺷﺘﻦ ﻳﻚ ﻧﺮم اﻓﺰار اﺳﺖ ،زﻳﺮا ﺣﺘﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳـﺴﺎن ﺑـﺎ ﺗﺠﺮﺑـﻪ ﻧﻴـﺰ ﻣﻤﻜﻦ اﺳﺖ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد ﺧﻄﺎ ﻫﺎﻳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ .داﻧﺴﺘﻦ اﻳﻦ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﻪ راﺣﺘﻲ اﺷﻜﺎﻻت ﻳﻚ ﺑﺮﻧﺎﻣـﻪ را ﻣـﺸﺨﺺ ﻛﺮده و آﻧﻬﺎ را رﻓﻊ ﻛﺮد ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﺑﺘﻮاﻧﻴﺪ ﺑﻪ ﺳﺮﻋﺖ و ﺑﺎ ﺣﺪاﻗﻞ ﺧﻄﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﻮرد ﻧﻈﺮﺗﺎن را ﭘﻴﺎده ﺳﺎزي ﻛﻨﻴﺪ. در ﺑﺨﺶ ﺑﻌﺪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﻤﻮﻧﻪ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد و ﺑﻪ اﺷﻜﺎل زداﻳﻲ آن ﺧﻮاﻫﻴﻢ ﭘﺮداﺧﺖ .در ﻃﻮل ﻛﺎر ﺑـﺮ روي اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ ﺳـﻌﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﺑﺎ breakpointﻫﺎ ،ﭼﮕﻮﻧﮕﻲ اﺟﺮاي ﺧﻂ ﺑﻪ ﺧﻂ ﻛﺪ ،ﺑﺮرﺳﻲ ﻣﻮﻗﻌﻴﺖ ﺑﺮﻧﺎﻣﻪ ﺑﻌﺪ از اﺟـﺮاي ﻫـﺮ ﺧـﻂ و ...آﺷـﻨﺎ ﺷﻮﻳﻢ.
اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻤﻮﻧﻪ: در ﺗﻤﺮﻳﻦ ﻫﺎي ﻣﺨﺘﻠﻒ ﺑﺨﺶ "اﻣﺘﺤﺎن ﻛﻨﻴﺪ" اﻳﻦ ﻓﺼﻞ ،ﺑﺮﻧﺎﻣﻪ ي ﺳﺎده اي ﺧﻮاﻫﻴﻢ ﻧﻮﺷﺖ و ﺳﻌﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد در ﻃﻲ اﻳﻦ ﺑﺮﻧﺎﻣـﻪ، ﻧﮕﺎﻫﻲ ﺑﻪ وﻳﮋﮔﻴﻬﺎي ﻋﻤﻮﻣﻲ و ﭘﺮ ﻛﺎرﺑﺮد وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﺑﺮاي اﺷﻜﺎل زداﻳﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ داﺷﺘﻪ ﺑﺎﺷﻴﻢ .در اﻳﻦ ﺑﺮﻧﺎﻣـﻪ آدرس ﻳـﻚ ﻓﺎﻳﻞ ﻣﺘﻨﻲ را ﺑﻪ وﺳﻴﻠﻪ ﻳﻚ ﻛﻨﺘﺮل TextBoxاز ﻛﺎرﺑﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﻴﻢ و ﻣﺤﺘﻮﻳـﺎت آن را ﻧﻤـﺎﻳﺶ ﻣـﻲ دﻫـﻴﻢ و ﻳـﺎ آدرﺳـﻲ را درﻳﺎﻓﺖ ﻛﺮده و ﻣﺤﺘﻮﻳﺎت داﺧﻞ TextBoxرا در ﻓﺎﻳﻠﻲ در آن آدرس ذﺧﻴﺮه ﻣﻲ ﻛﻨﻴﻢ .اﻟﺒﺘﻪ ﻫﻤﺎﻧﻄﻮر ﻛـﻪ ﻣـﻲ داﻧﻴـﺪ و در ﻓـﺼﻮل ﻗﺒﻠـــﻲ ﻧﻴـــﺰ ﻣـــﺸﺎﻫﺪه ﻛﺮدﻳـــﺪ ﺑﻬﺘـــﺮﻳﻦ راه ﺑـــﺮاي اﻳـــﻦ ﻛـــﺎر اﺳـــﺘﻔﺎده از ﻛﻨﺘـــﺮل ﻫـــﺎي OpenFileDialogو SaveFileDialogاﺳﺖ ،اﻣﺎ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﺑﻬﺘﺮ روي ﺧﻄﺎ ﻳﺎﺑﻲ در ﺑﺮﻧﺎﻣﻪ ﺗﻤﺮﻛـﺰ ﻛﻨـﻴﻢ ،آدرس را ﺑـﻪ ﺻﻮرت ﻣﺴﺘﻘﻴﻢ از ﻛﺎرﺑﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﻤﻮﻧﻪ ﺑﺮاي اﺷﻜﺎل زداﻳﻲ (1ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ وﻳﻨﺪوزي ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم ErrorHandlingاﻳﺠﺎد ﻛﻨﻴﺪ. (2روي ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﻧﺘﺨﺎب ﺷﻮد ،ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠـﺮه Propertiesﺧﺎﺻـﻴﺘﻬﺎي آن را ﺑﺮاﺑـﺮ ﺑـﺎ ﻣﻘﺎدﻳﺮ زﻳﺮ ﻗﺮار دﻫﻴﺪ:
ﺧﺎﺻﻴﺖ Sizeرا ﺑﺮاﺑﺮ 445;315ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ StartPositionرا ﺑﺮاﺑﺮ ﺑﺎ CenterScreenﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textرا ﺑﺮاﺑﺮ ﺑﺎ Error Handlingﻗﺮار دﻫﻴﺪ.
٤٤٦
(3ﺣﺎل ﺑﺎﻳﺪ ﺗﻌﺪادي ﻛﻨﺘﺮل روي ﻓﺮم ﻗﺮار داده و ﺧﺎﺻﻴﺘﻬﺎي آﻧﻬﺎ را ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ .اﺑﺘﺪا ﻳﻚ ﻛﻨﺘﺮل TextBoxاﻳﺠﺎد ﻛﺮده و ﺧﺎﺻﻴﺘﻬﺎي آن را ﻃﺒﻖ ﻟﻴﺴﺖ زﻳﺮ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ.
ﺧﺎﺻﻴﺖ Multilineآن را ﺑﺮاﺑﺮ ﺑﺎ trueﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Sizeرا ﺑﺮاﺑﺮ ﺑﺎ 419;210ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ txtBodyﻗﺮار دﻫﻴﺪ.
ﻳﻚ ﻛﻨﺘﺮل TextBoxدﻳﮕﺮ در ﻓﺮم ﻗﺮار داده و ﺧﺎﺻﻴﺘﻬﺎي آن را ﻣﻄﺎﺑﻖ ﺑﺎ ﻟﻴﺴﺖ زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ:
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ txtAddressﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Locationرا ﺑﺮاﺑﺮ ﺑﺎ 13;43ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Sizeرا ﺑﺮاﺑﺮ ﺑﺎ 448;254ﻗﺮار دﻫﻴﺪ.
ﻳﻚ ﻛﻨﺘﺮل Buttonﺑﺮ روي ﻓﺮم ﻗﺮار داده ،ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑﺎ btnOpenو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Openﻗﺮار دﻫﻴﺪ .ﻛﻨﺘﺮل Buttonدﻳﮕﺮي ﺑﺎ ﻧﺎم btnSaveﺑﺮ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ و ﺧﺎﺻﻴﺖ Text آن را ﺑﺎ Saveﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ .در اﻧﺘﻬﺎ ﻧﻴﺰ ﻳﻚ ﻛﻨﺘﺮل Labelﻛﻪ ﺣﺎوي ﻣﺘﻦ “Enter the address ” of file to open/save:ﺑﺎﺷﺪ را ﺑﻪ ﮔﻮﻧﻪ اي در ﻓﺮم ﻗﺮار دﻫﻴﺪ ﻛﻪ ﭘﻨﺠﺮه ي ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 5-11ﺷﻮد. (4ﺑﻬﺘﺮ اﺳﺖ ﻗﺒﻞ از اﻳﻨﻜﻪ ﻃﺮاﺣﻲ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﺑﺮﻧﺎﻣﻪ را ﺷﺮوع ﻛﻨﻴﻢ ،ﺑﺎ ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ) و اﻟﺒﺘﻪ ﺳـﺎده ﺗـﺮﻳﻦ( اﺑﺰارﻫﺎي ﺧﻄﺎ ﻳﺎﺑﻲ در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﻌﻨﻲ ﭘﻨﺠﺮه ي Error Listآﺷﻨﺎ ﺷﻮﻳﻢ .ﺑﺮاي ﻧﻤﺎﻳﺶ اﻳﻦ ﭘﻨﺠـﺮه ،از ﻧـﻮار ﻣﻨﻮ ﮔﺰﻳﻨﻪ ي View Error Listرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ.
ﺷﻜﻞ 5-11
٤٤٧
(5در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ،روي دﻛﻤﻪ ي Openدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: )private void btnOpen_Click(object sender, EventArgs e { ;int unusedInt ;DateTime unassignedObject ;)unassignedObject.AddDays(1 } (6ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ در اﻳﻦ ﻛﺪ ﻳﻚ ﺧﻄﺎ وﺟﻮد دارد و اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺪون اﻳﻨﻜﻪ ﺑـﺎ اﺳـﺘﻔﺎده از دﺳـﺘﻮر newﺑـﻪ ﻣﺘﻐﻴﻴـﺮ unassignedObjectﻣﻘﺪار اوﻟﻴﻪ دﻫﻴﻢ ،از آن در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ .ﺧـﻮب ،ﺑـﺎ ﻓـﺸﺎر دادن ﻛﻠﻴـﺪ F5 ﺳﻌﻲ ﻛﻨﻴﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .1ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ در زﻳﺮ ﻣﺘﻐﻴﻴﺮ unsedIntﺧﻄﻲ ﺳﺒﺰ رﻧﮓ و در زﻳﺮ ﻣﺘﻐﻴﻴـﺮ unassignedObjectﺧﻄﻲ آﺑﻲ رﻧﮓ ﻛﺸﻴﺪه ﻣﻲ ﺷﻮد .ﻫﻤﭽﻨﻴﻦ ﭘﻨﺠﺮه ي Error Listﻧﻴﺰ ﮔﺰﻳﻨﻪ ﻫﺎﻳﻲ را ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 6-11ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
ﺷﻜﻞ6-11 (7ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ در اﻳﻦ ﭘﻨﺠﺮه ﻋﻨﻮان ﺷﺪه اﺳﺖ ﻛﻪ در ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ ﺑﺮﻧﺎﻣﻪ ،ﻛﺎﻣﭙﺎﻳﻠﺮ ﺑﺎ ﻳﻚ ﺧﻄﺎ و ﻳﻚ ﻫﺸﺪار ﻣﻮﺟﻪ ﺷﺪه اﺳﺖ .ﻫﺸﺪار ﻛﻪ در ﮔﺰﻳﻨﻪ ي اول و ﺑﺎ ﻳﻚ ﻋﻼﻣﺖ زرد رﻧﮓ ﻣﺸﺨﺺ ﺷﺪه اﺳـﺖ ﻣﺮﺑـﻮط ﺑـﻪ ﺧـﻂ 21از ﻓﺎﻳﻞ Form1.csدر ﭘـﺮوژه ي ErrorHandlingاﺳـﺖ .اﻳـﻦ ﻫـﺸﺪار ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ در ﻗـﺴﻤﺖ Descriptionآﻣﺪه اﺳﺖ ﺑﻪ ﻋﻠﺖ ﺗﻌﺮﻳﻒ ﻳﻚ ﻣﺘﻐﻴﻴﺮ در ﺑﺮﻧﺎﻣﻪ و اﺳﺘﻔﺎده ﻧﻜـﺮدن از آن اﺳـﺖ .وﻳـﮋوال اﺳـﺘﻮدﻳﻮ ﻫﺸﺪار ﻫﺎ را در ﻛﺪ ﺑﺎ زﻳﺮ ﺧﻂ ﺳﺒﺰ رﻧﮓ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. (8ﮔﺰﻳﻨﻪ ي دوم در اﻳﻦ ﭘﻨﺠﺮه ﻧﻴﺰ ﻛﻪ ﺑﺎ ﻋﻼﻣـﺖ ﻗﺮﻣـﺰ ﻣـﺸﺨﺺ ﺷـﺪه اﺳـﺖ ،ﻣﺮﺑـﻮط ﺑـﻪ ﻳـﻚ ﺧﻄـﺎ در ﺧـﻂ 23از ﻓﺎﻳـﻞ Form1.csدر ﭘﺮوژه ي ErrorHandlingاﺳﺖ .ﻋﻠﺖ ﺑﻪ وﺟﻮد آﻣﺪن اﻳﻦ ﺧﻄﺎ ﻧﻴﺰ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺑﺨﺶ Descriptionﺗﻮﺿﻴﺢ داده ﺷﺪه اﺳﺖ ،اﺳﺘﻔﺎده از ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑﺪون ﻣﻘﺪار دﻫﻲ اوﻟﻴـﻪ ﺑـﻪ آن اﺳـﺖ .ﺧﻄـﺎ ﻫـﺎ در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺎ زﻳﺮ ﺧﻂ آﺑﻲ رﻧﮓ در ﻛﺪ ﻣﺸﺨﺺ ﻣﻲ ﺷﻮﻧﺪ. (9ﺣﺎل ﻛﺪ درون ﻣﺘﺪ btnOpen_Clickرا ﺑﻪ ﺻﻮرت ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ.
1ﻛﻠﻴﺪ ﻫﺎ و ﻳﺎ ﺗﺮﻛﻴﺒﺎت ﻛﻠﻴﺪي ﻛﻪ در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ ،ﺑﺴﺘﻪ ﺑﻪ ﺗﻨﻈﻴﻢ ﻫﺎي ﻛﺎرﺑﺮ ﻣﻤﻜﻦ اﺳﺖ ﺗﻔﺎوت داﺷﺘﻪ ﺑﺎﺷﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻤﻜـﻦ اﺳـﺖ ﺑـﺎ ﻓـﺸﺎر ﻛﻠﻴﺪ F5ﺑﺮﻧﺎﻣﻪ اﺟﺮا ﻧﺸﻮد .ﺑﺮاي اﻃﻼع از ﻛﻠﻴﺪ ﻣﺮﺑﻮط ﺑﻪ ﺷﺮوع اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ،ﻋﺒﺎرت ﻧﻮﺷﺘﻪ ﺷﺪه در ﻣﻘﺎﺑﻞ ﮔﺰﻳﻨـﻪ ي Start Debuggingدر ﻣﻨـﻮي Debugرا ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ.
٤٤٨
)private void btnOpen_Click(object sender, EventArgs e { ;)txtBody.Text = File.ReadAllText(txtAddress.Text } (10ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﺪون اﻳﻨﻜﻪ در ﻛﻨﺘﺮل txtAddressآدرس ﻓﺎﻳﻞ را وارد ﻛﻨﻴﺪ روي دﻛﻤﻪ ي Openﻛﻠﻴﻚ ﻛﻨﻴﺪ .در اﻳﻦ ﺣﺎﻟﺖ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﻳﻚ ﺧﻄﺎي زﻣﺎن اﺟﺮا ﻣﻮاﺟﻪ ﻣﻲ ﺷﻮد و ﻛﺎدري را ﻣﺸﺎﺑﻪ ﺷﻜﻞ 7-11ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،ﻧﻮع ﺧﻄﺎﻳﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﺎ آن ﻣﻮاﺟﻪ ﺷﺪه اﺳﺖ در ﻧﻮار ﻋﻨـﻮان اﻳـﻦ ﻛـﺎدر ﻧﻤـﺎﻳﺶ داده ﺷـﺪه اﺳﺖ .در اﻳﻦ ﻗﺴﻤﺖ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﺧﻄﺎﻳﻲ از ﻧﻮع ArgumentExceptionﻣﻮاﺟﻪ ﺷﺪه اﺳﺖ .در ﭘﺎﻳﺎن اﻳـﻦ ﻓـﺼﻞ ﺑﺎ اﻳﻦ ﻧﻮع ﺧﻄﺎﻫﺎ و ﻣﻔﻬﻮم آﻧﻬﺎ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ .ﻫﻤﭽﻨﻴﻦ در ﻗـﺴﻤﺖ Troubleshooting tips اﻳﻦ ﻛﺎدر ،ﻟﻴﻨﻚ ﻫﺎﻳﻲ در ﻣﻮرد ﭼﮕﻮﻧﮕﻲ رﻓﻊ اﻳﻦ ﺧﻄﺎ آورده ﺷﺪه اﺳﺖ .در ﭘـﺎﻳﻴﻦ ﻛـﺎدر ﻧﻴـﺰ ﻗـﺴﻤﺘﻲ ﺑـﻪ ﻧـﺎم View … Detailsوﺟﻮد دارد ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آن ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺟﺰﺋﻴﺎت ﺧﻄﺎي ﺑﻪ وﺟﻮد آﻣﺪه ﻣﻄﻠﻊ ﺷﻮﻳﺪ.
ﺷﻜﻞ 7-11 (11در ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﺷﺪه ،روي ﮔﺰﻳﻨﻪ ي … View Detailsﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﭘﻨﺠﺮه ي View Details ﻣﺸﺎﺑﻪ ﺷﻜﻞ 8-11ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﭘﻨﺠﺮه ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ اﻃﻼﻋﺎت دﻳﮕﺮي در ﻣﻮرد ﺧﻄﺎي ﺑـﻪ وﺟـﻮد آﻣﺪه از ﻗﺒﻴﻞ ﭘﻴﻐﺎم آن ﺧﻄﺎ ،ﻟﻴﻨﻜﻲ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت ﺑﻴﺸﺘﺮ در ﻣﻮرد ﺧﻄﺎ ،ﻣﺘﺪي ﻛﻪ ﺑﺎﻋﺚ ﺑـﻪ وﺟـﻮد آﻣـﺪن ﺧﻄـﺎ ﺷﺪه اﺳﺖ و ...دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ.
٤٤٩
8-11 ﺷﻜﻞ Debug ﮔﺰﻳﻨﻪ ي، ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﺑﺮﮔﺮدﻳﺪ و ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻧﻮار ﻣﻨﻮOK ( در اﻳﻦ ﭘﻨﺠﺮه روي دﻛﻤﻪ ي12 . را اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﺘﻮﻗﻒ ﺷﻮدStop Debugging : را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪbtnOpen_Click ( ﺣﺎل ﻛﺪ ﻣﺘﺪ13 private void btnOpen_Click(object sender, EventArgs e) { if (txtAddress.Text != String.Empty) { txtBody.Text = File.ReadAllText(txtAddress.Text); } } دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ اﻳﻦ ﻛﻨﺘﺮل ﻧﻴﺰSave ( ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ و روي دﻛﻤﻪ ي14 : ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ.اﻳﺠﺎد ﺷﻮد private void btnSave_Click(object sender, EventArgs e) { if (txtAddress.Text != String.Empty) { File.WriteAllText(txtAddress.Text, txtBody.Text); } }
٤٥٠
(15ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺑﻌﺪ از وارد ﻛﺮدن آدرس ﻳﻚ ﻓﺎﻳﻞ ﻣﺘﻨﻲ در ﻛﻨﺘـﺮل ،txtAddressروي دﻛﻤـﻪ ي Open ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻣﺤﺘﻮﻳﺎت ﻓﺎﻳﻞ در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ. ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ در اﻳﻦ ﻗﺴﻤﺖ از اﻳﺠﺎد ﺧﻄﺎ ﺟﻠﻮﮔﻴﺮي ﻛﺮدﻳﻢ ،اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ اﻳﻦ روش ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺻﻮرت ﻛﻠﻲ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد .زﻳﺮا ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻛﺎرﺑﺮ آدرس ﻓﺎﻳﻞ را ﺑﻪ ﺻﻮرت ﻧﺎدرﺳﺖ وارد ﻛﻨﺪ ،ﺑﺮﻧﺎﻣﻪ ﻣﺠﺪداً ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟﻪ ﺧﻮاﻫﺪ ﺷـﺪ. روش ﺻﺤﻴﺢ ﻛﻨﺘﺮل اﻳﻦ ﻧﻮع ﺧﻄﺎﻫﺎ در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده از دﺳﺘﻮرات tryو catchاﺳﺖ ﻛﻪ در ﺑﺨﺸﻬﺎي ﺑﻌﺪي اﻳﻦ ﻓﺼﻞ ﺗﻮﺿﻴﺢ داده ﺷﺪه اﺳﺖ .اﻣﺎ ﻗﺒﻞ از اﻳﻦ ﻛﻪ ﺑﺎ دﺳﺘﻮرات ﻛﻨﺘﺮل ﺧﻄﺎ در ﻛﺪ ﺑﺮﻧﺎﻣﻪ آﺷﻨﺎ ﺷﻮﻳﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﻧﺤﻮه ﻛﺎر اﺑﺰارﻫﺎي دﻳﮕﺮ اﺷـﻜﺎل زداﻳـﻲ در وﻳﮋوال اﺳﺘﻮدﻳﻮ را ﻧﻴﺰ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ.
ﻛﻨﺘﺮل اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از Breakpointﻫﺎ: ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺣﺎل ﻃﺮاﺣﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺑﺰرگ ﺑﺎﺷﻴﺪ ،ﻣﻤﻜﻦ اﺳﺖ ﺑﺮاي ﻓﻬﻤﻴﺪن اﺷﻜﺎﻻت ﻗﺴﻤﺘﻲ از ﻛﺪ ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺗﺎ آن ﻗﺴﻤﺖ اﺟـﺮا ﺷـﻮد و ﺳـﭙﺲ در ﺧﻄـﻲ ﺧـﺎص ﻣﺘﻮﻗـﻒ ﺷـﺪه ﺗـﺎ وﺿـﻌﻴﺖ آن را ﺑﺮرﺳـﻲ ﻛﻨﻴـﺪ .در اﻳـﻦ ﺷـﺮاﻳﻂ ﻣـﻲ ﺗﻮاﻧﻴـﺪ از breakpointﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﻳﻚ ﺧﻂ از ﺑﺮﻧﺎﻣﻪ ﻳﻚ breakpointﻗﺮار ﻣﻲ دﻫﻴﺪ ،ﺑﺮﻧﺎﻣﻪ ﺗﺎ آن ﺧـﻂ اﺟﺮا ﻣﻲ ﺷﻮد اﻣﺎ ﺧﻂ ﺷﺎﻣﻞ breakpointرا اﺟﺮا ﻧﻜﺮده و ﻗﺒﻞ از آن ﻣﺘﻮﻗﻒ ﻣﻲ ﺷﻮد. ﺑﺮاي ﺗﻌﻴﻴﻦ breakpointدر ﻳﻚ ﺧﻂ ،ﻫﻢ در زﻣﺎن اﺟﺮاي ﺑﺮﻧﺎﻣﻪ و ﻫﻢ در زﻣﺎن ﻧﻮﺷﺘﻦ ﻛﺪ آن ﻣﻲ ﺗﻮاﻧﻴﺪ اﻗـﺪام ﻛﻨﻴـﺪ .ﺑـﺮاي اﻳﻦ ﻛﺎر ﻛﺎﻓﻲ اﺳﺖ در ﻧﺎﺣﻴﻪ ﺧﺎﻛﺴﺘﺮي رﻧﮓ ﺳﻤﺖ ﭼﭗ ﺧﻂ ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ در آن ﻧﺎﺣﻴﻪ ﻳﻚ داﻳﺮه ي ﻗﺮﻣﺰ رﻧﮓ ﻗﺮار ﻣﻲ ﮔﻴﺮد .ﺑﺮاي ﺣﺬف ﻳﻚ breakpointﻧﻴﺰ ﻛﺎﻓﻲ اﺳﺖ ﻣﺠﺪداً ﺑﺮ روي داﻳﺮه ي ﻗﺮﻣﺰ رﻧﮓ ﻛﻨﺎر ﺧﻂ ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ breakpointﺑﻪ وﺟﻮد آﻣﺪه در آن ﺧﻂ ﺣﺬف ﺧﻮاﻫﺪ ﺷﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ در اﺟﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺧﻄﻲ ﺷﺎﻣﻞ ﻳﻚ breakpointﻣﻲ رﺳﺪ ،اﺟﺮاي ﺑﺮﻧﺎﻣﻪ را ﻣﺘﻮﻗﻒ ﻣﻲ ﻛﻨﺪ و ﺑـﻪ ﻗﺴﻤﺖ ﻛﺪ ﻧﻮﻳﺴﻲ ﺑﺮﻧﺎﻣﻪ ﺑﺮﻣﻴﮕﺮدد .اﻟﺒﺘﻪ دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻛﺎﻣﻼً ﻣﺘﻮﻗﻒ ﻧﻤﻲ ﺷﻮد ،ﺑﻠﻜﻪ وﻗﻔﻪ اي در آن اﻳﺠﺎد ﻣﻲ ﺷـﻮد ﺗـﺎ ﺑﺘﻮاﻧﻴﺪ وﺿﻌﻴﺖ ﺑﺮﻧﺎﻣﻪ را در آن ﻗﺴﻤﺖ ﺑﺮرﺳﻲ ﻛﻨﻴﺪ ،ﺳﭙﺲ ﻣﻲ ﺗﻮاﻧﻴﺪ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ را اداﻣﻪ دﻫﻴﺪ .ﺑﻪ اﻳـﻦ ﺣﺎﻟـﺖ در اﺻـﻄﻼح ،ﺣﺎﻟـﺖ breakﮔﻔﺘﻪ ﻣﻲ ﺷﻮد. در ﺑﺨﺸﻬﺎي "اﻣﺘﺤﺎن ﻛﻨﻴﺪ" ﺑﻌﺪي ،ﺑﺎ breakpointﻫﺎ و ﻧﻴﺰ اﻣﻜﺎﻧﺎت و وﻳﮋﮔﻴﻬﺎﻳﻲ ﻛﻪ ﺑﺮاي اﺷـﻜﺎل زداﻳـﻲ از ﻛـﺪ در ﺣﺎﻟـﺖ breakوﺟﻮد دارﻧﺪ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﻣﻲ ﺷﻮﻳﻢ .اﻣﺎ ﻗﺒﻞ از اداﻣﻪ ﺑﺮاي ﺳﺎدﮔﻲ ﻛﺎر ﺑﻬﺘﺮ اﺳﺖ ﻧﻮار اﺑـﺰار Debugرا ﺑـﻪ ﻣﺤـﻴﻂ وﻳـﮋوال اﺳﺘﻮدﻳﻮ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎ اﺳﺘﻔﺎده از ﻧﻮار ﻣﻨﻮ ،ﮔﺰﻳﻨـﻪ ي View Toolbars Debugرا اﻧﺘﺨـﺎب ﻛﻨﻴﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻛﺎر ﺑﺎ breakpointﻫﺎ (1ﺑﺮﻧﺎﻣﻪ ي ErrorHandlingﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ اﻳﺠﺎد ﻛﺮدﻳﻢ را ﻣﺠﺪداً ﺑﺎز ﻛﺮده و ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮوﻳـﺪ. ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑـﺰار ﻛﻨﺘـﺮل Buttonﺟﺪﻳـﺪي ﺑـﺮ روي ﻓـﺮم ﻗـﺮار داده ،ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑـﺮ ﺑـﺎ btnTestو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Testﻗﺮار دﻫﻴﺪ. (2ﺑﺮ روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ. )private void btnTest_Click(object sender, EventArgs e
٤٥١
{ ;int counter = 0 )for (counter = 0; counter < 100; counter++ { ;"txtBody.Text += counter.ToString() + "\t } } (3در ﻧﻮار ﺧﺎﻛﺴﺘﺮي ﺳﻤﺖ ﭼﭗ ﺧﻄﻲ ﻛﻪ ﺷﺎﻣﻞ دﺳﺘﻮر داﺧﻞ ﺣﻠﻘﻪ forاﺳﺖ ،ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ داﻳـﺮه اي ﻗﺮﻣـﺰ رﻧـﮓ در آن ﻧﻤﺎﻳﺶ داده ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺮاي آن ﺧﻂ از ﺑﺮﻧﺎﻣﻪ ﻳﻚ breakpointاﻳﺠﺎد ﻛﺮده اﻳﺪ .ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ. (4ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﺷﺪ ،ﺑﺮ روي دﻛﻤﻪ ي Testﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﺧﻂ اول از ﻣﺘﺪ btnTest_Clickرا اﺟﺮا ﻣﻲ ﻛﻨﺪ و ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﻪ اﺑﺘﺪاي دﺳﺘﻮر forﻣﻲ رﺳﺪ ،ﭘﻨﺠﺮه ي ﻣﺮﺑﻮط ﺑـﻪ ﻣﺤـﻴﻂ ﻛﺪ ﻧﻮﻳﺴﻲ وﻳﮋوال اﺳﺘﻮدﻳﻮ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .در اﻳﻦ ﻫﻨﮕﺎم دﺳﺘﻮر داﺧﻞ ﺣﻠﻘﻪ ي forﺑﺎ رﻧﮓ زرد ﻣﺸﺨﺺ ﻣﻲ ﺷﻮد و ﻫﻤﭽﻨﻴﻦ در داﺧﻞ داﻳﺮه ﻗﺮﻣﺰ رﻧﮓ ﻛﻨﺎر دﺳﺘﻮر ﻧﻴﺰ ﻳﻚ ﻓﻠﺶ زرد رﻧﮓ ﻗﺮار ﺧﻮاﻫﺪ ﮔﺮﻓﺖ )ﺷﻜﻞ (9-11 ﻫﻤﭽﻨﻴﻦ اﮔﺮ ﺑﻪ ﭘﺎﻳﻴﻦ ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﮕﺎه ﻛﻨﻴﺪ ،ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﭘﻨﺠﺮه ﻫـﺎي ﺑﻴـﺸﺘﺮي ﻧـﺴﺒﺖ ﺑـﻪ ﺣﺎﻟـﺖ ﻋﺎدي در ﺣﺎل ﻧﻤﺎﻳﺶ ﻫﺴﺘﻨﺪ و ﺑﺎ اﻧﺘﺨﺎب ﻫﺮ ﻳﻚ از اﻳﻦ ﭘﻨﺠﺮه ﻫﺎ اﻃﻼﻋﺎت ﺧﺎﺻﻲ در ﻣـﻮرد آن ﻟﺤﻈـﻪ از اﺟـﺮاي ﺑﺮﻧﺎﻣـﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد )اﻟﺒﺘﻪ ﻣﻤﻜﻦ اﺳﺖ ﺗﻌﺪاد اﻳﻦ ﭘﻨﺠﺮه ﻫﺎ در ﻛﺎﻣﭙﻴﻮﺗﺮ ﺷﻤﺎ ﻧﺴﺒﺖ ﺑﻪ ﺷﻜﻞ ﺑﻴﺸﺘﺮ و ﻳﺎ ﻛﻤﺘﺮ ﺑﺎﺷﺪ(.
ﺷﻜﻞ 9-11 ﺑﻬﺘﺮ اﺳﺖ ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﻪ اداﻣﻪ ي اﻳﻦ ﺑﺨﺶ از "اﻣﺘﺤﺎن ﻛﻨﻴﺪ" ﺑﭙﺮدازﻳﻢ ،ﺑﺎ ﺑﻌﻀﻲ از ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻧﻮار اﺑﺰار Debug آﺷﻨﺎ ﺑﺸﻮﻳﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ از آﻧﻬﺎ در اﺷﻜﺎل زداﻳﻲ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﻢ.
ﮔﺰﻳﻨﻪ ﻫﺎي ﭘﺮ ﻛﺎرﺑﺮد در ﻧﻮار اﺑﺰار :Debug در ﻧﻮار اﺑﺰار Debugﺳﻪ آﻳﻜﻮن وﺟﻮد دارﻧﺪ ﻛﻪ ﻣﻌﻤﻮﻻ ﻛﺎرﺑﺮد زﻳﺎدي در اﺷﻜﺎل زداﻳﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ دارﻧﺪ )ﺷﻜﻞ .(10-11ﺑﺎ اﺳـﺘﻔﺎده از اﻳﻦ ﮔﺰﻳﻨﻪ ﻫﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ در ﺣﺎﻟﺖ breakﻗﺮار ﮔﺮﻓﺖ ،آن را ﺧﻂ ﺑﻪ ﺧﻂ اﺟﺮا ﻛﻨﻴـﺪ و روﻧـﺪ ﺗﻐﻴﻴـﺮ ﻣﺘﻐﻴﻴـﺮ ﻫـﺎ و اﺷﻴﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ را ﺑﺮرﺳﻲ ﻛﻨﻴﺪ.
٤٥٢
آﻳﻜﻮن اول ﻣﺮﺑﻮط ﺑﻪ ﮔﺰﻳﻨﻪ ي Step Intoاﺳﺖ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ روي اﻳﻦ آﻳﻜﻮن ﻛﻠﻴﻚ ﻛﻨﻴﺪ ،ﻛﺎﻣﭙﺎﻳﻠﺮ ﻳـﻚ ﺧـﻂ از ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﻣﺠﺪداً ﺗﻮﻗﻒ ﻣﻲ ﻛﻨﺪ و ﺑﻪ ﺣﺎﻟﺖ breakﺑﺮﻣﻲ ﮔﺮدد .اﮔﺮ ﺧﻄﻲ ﻛﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ آن را اﺟﺮا ﻛﺮده ﺷﺎﻣﻞ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪي ﺑﺎﺷﺪ ،ﻛﺎﻣﭙﺎﻳﻠﺮ ﺑﻪ اوﻟﻴﻦ دﺳﺘﻮر درون اﻳﻦ ﻣﺘﺪ ﻣﻲ رود و در آﻧﺠﺎ ﻣﺘﻮﻗﻒ ﻣﻲ ﺷﻮد. آﻳﻜﻮن دوم ﻣﺮﺑﻮط ﺑﻪ ﮔﺰﻳﻨﻪ ي Step Overاﺳﺖ .ﺑﺎ ﻛﻠﻴﻚ ﺑﺮ روي اﻳﻦ آﻳﻜﻮن ،ﻫﻤﺎﻧﻨﺪ آﻳﻜﻮن Step Into ﻛﺎﻣﭙﺎﻳﻠﺮ ﻳﻚ ﺧﻂ از ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻣﻲ ﻛﻨﺪ و در اﺑﺘﺪاي ﺧﻂ ﺑﻌﺪ ﺗﻮﻗﻒ ﻣﻲ ﻛﻨـﺪ .ﺗﻔـﺎوت اﻳـﻦ ﮔﺰﻳﻨـﻪ ﺑـﺎ ﮔﺰﻳﻨـﻪ Step Intoدر اﻳﻦ اﺳﺖ ﻛﻪ اﮔﺮ ﺧﻄﻲ ﻛﻪ ﺑﺎﻳﺪ اﺟﺮا ﺷﻮد ﺷﺎﻣﻞ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪي ﺑﺎﺷﺪ ،ﻛﺎﻣﭙﺎﻳﻠﺮ آن ﻣﺘﺪ را ﻛﺎﻣﻼً اﺟﺮا ﻣﻲ ﻛﻨﺪ و در اﺑﺘﺪاي ﺧﻂ ﺑﻌﺪ در ﻣﺘﺪ ﺟﺎري ﻣﺘﻮﻗﻒ ﻣﻲ ﺷﻮد. آﺧﺮﻳﻦ آﻳﻜﻮن ﻧﻴﺰ ﻣﺮﺑﻮط ﺑﻪ Step Outاﺳﺖ .ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ آﻳﻜﻮن ﺑﺮﻧﺎﻣﻪ ﺗﺎ اﻧﺘﻬﺎي ﻣﺘﺪ ﺟﺎري اﺟﺮا ﻣﻲ ﺷﻮد و در اوﻟﻴﻦ ﺧﻂ ،ﺑﻌﺪ از ﺧﻄﻲ ﻛﻪ اﻳﻦ ﻣﺘﺪ را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده ﺑﻮد ﻣﺘﻮﻗﻒ ﻣﻲ ﺷﻮد .ﻋﻤﻮﻣﺎً ﻫﺮ ﻣﺘﺪ ،ﺣﺘﻲ ﻣﺘﺪﻫﺎي ﻣﺮﺑﻮط ﺑﻪ روﻳﺪادﻫﺎ ﻧﻴﺰ ﺗﻮﺳﻂ ﻣﺘﺪ دﻳﮕﺮي ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎﻣﻲ ﻛﻪ از اﻳﻦ ﮔﺰﻳﻨﻪ اﺳﺘﻔﺎده ﻛﻨﻴﻢ ،ﺑﺮﻧﺎﻣﻪ اﺟﺮاي ﻣﺘﺪ ﺟـﺎري را ﺑـﻪ ﭘﺎﻳﺎن ﻣﻲ رﺳﺎﻧﺪ و ﺑﻪ ﻣﺘﺪي ﻛﻪ اﻳﻦ ﻣﺘﺪ را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده ﺑﻮد ﺑﺮﻣﻲ ﮔﺮدد .ﺳﭙﺲ در اوﻟﻴﻦ ﺧـﻂ ﺑﻌـﺪ از ﻓﺮاﺧـﻮاﻧﻲ اﻳـﻦ ﻣﺘـﺪ ﻣﺘﻮﻗﻒ ﻣﻲ ﺷﻮد.
ﺷﻜﻞ 10-11 ﻳﻜﻲ دﻳﮕﺮي از وﻳﮋﮔﻲ ﻫﺎي ﻣﻬﻤﻲ ﻛﻪ ﺑﻬﺘﺮ اﺳﺖ ﻗﺒﻞ از اداﻣﻪ ي ﻓﺼﻞ ﺑﺎ آن آﺷﻨﺎ ﺷﻮﻳﻢ ،ﺧﺎﺻﻴﺖ Run To Cursorاﺳﺖ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻳﻚ breakpointﺑﺮﺧﻮرد ﻣﻲ ﻛﻨﺪ و ﻣﺘﻮﻗﻒ ﻣﻲ ﺷﻮد ،اﮔﺮ ﺑﻪ ﻧﻮار ﺧﺎﻛﺴﺘﺮي رﻧﮓ ﺳﻤﺖ ﭼـﭗ آن ﻧﮕـﺎه ﻛﻨﻴﺪ ﻳﻚ ﻓﻠﺶ زرد رﻧﮓ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺑﻪ ﻛﺪي ﻛﻪ در ﺣﺎل اﺟﺮا ﺑﻮده اﺳﺖ اﺷﺎره ﻣﻲ ﻛﻨﺪ .اﮔـﺮ ﺑـﺎ ﻣـﺎوس روي اﻳـﻦ ﻓﻠـﺶ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﻜﺎن آن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ )ﺑﺮاي ﻣﺜﺎل ﻛﻤﻲ ﺑﺎﻻﺗﺮ و ﻳﺎ ﻛﻤﻲ ﭘﺎﻳﻴﻦ ﺗﺮ ﺑﺒﺮﻳﺪ( ﺗﺎ ﺑﻪ ﻛﺪ دﻳﮕﺮي اﺷﺎره ﻛﻨﺪ .ﺣـﺎل اﮔـﺮ ﺑﺮ روي دﻛﻤﻪ ي Startدر ﻧﻮار ﻣﻨﻮ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ اداﻣﻪ ﭘﻴﺪا ﻛﻨﺪ ،اﺟﺮاي ﺑﺮﻧﺎﻣﻪ از ﺧﻄﻲ ﻛـﻪ ﻓﻠـﺶ در ﺣـﺎل اﺷـﺎره ﻛﺮدن ﺑﻪ آن اﺳﺖ اداﻣﻪ ﭘﻴﺪا ﺧﻮاﻫﺪ ﻛﺮد. ﺣﺎل ﺑﻪ اداﻣﻪ ي ﺑﺨﺶ "اﻣﺘﺤﺎن ﻛﻨﻴﺪ" ﻗﺒﻞ ﺑﺮﻣﻲ ﮔﺮدﻳﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻛﺎر ﺑﺎ breakpointﻫﺎ )اداﻣﻪ( (1اﮔﺮ ﺑﺮﻧﺎﻣﻪ ي ErrorHandlingﻫﻨﻮز در ﺣﺎل اﺟﺮا اﺳﺖ آن را ﺑﺒﻨﺪﻳـﺪ .ﻫﻤﭽﻨـﻴﻦ ﺑـﺎ ﻛﻠﻴـﻚ ﻛـﺮدن روي ﺗﻤـﺎم breakpointﻫﺎﻳﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ وﺟﻮد دارﻧﺪ ،آﻧﻬﺎ را ﺣﺬف ﻛﻨﻴﺪ. (2ﻛﺪ ﻧﻮﺷﺘﻪ ﺷﺪه در ﻣﺘﺪ btnTest_Clickرا اﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ از ﻧﻮار ﻣﻨﻮ ﮔﺰﻳﻨﻪ ي Refactor … Extract Methodرا اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ ﺗـﺎ ﭘﻨﺠـﺮه ي Extract Methodﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ 11-11 ﻧﻤﺎﻳﺶ داده ﺷﻮد.
٤٥٣
ﺷﻜﻞ 11-11 (3
(4 (5
(6
در ﻗﺴﻤﺖ New method nameﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ،ﻧﺎم TestMethodرا وارد ﻛـﺮده و روي دﻛﻤـﻪ ي OK ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺤﺘﻮﻳﺎت ﻣﺘﺪ btnTest_Clickدر ﻣﺘﺪ ﺟﺪﻳﺪي ﺑﻪ ﻧﺎم TestMethodﻗـﺮار ﺧﻮاﻫﻨﺪ ﮔﺮﻓﺖ .ﻛﺪ درون ﻣﺘﺪ btnTest_Clickﻫﻢ ﺑﻪ ﻛﺪي ﺑﺮاي ﻓﺮاﺧـﻮاﻧﻲ ﻣﺘـﺪ TestMethodﺗﻐﻴﻴـﺮ ﺧﻮاﻫﺪ ﻛﺮد. ﺣﺎل در ﻧﻮار ﺧﺎﻛﺴﺘﺮي رﻧﮓ ﻛﻨﺎر دﺳﺘﻮر داﺧﻠﻲ ﺣﻠﻘﻪ ي ) forدﺳﺘﻮري ﻛﻪ ﻣﺘﻦ داﺧـﻞ ﻛﻨﺘـﺮل txtBodyرا ﺗﻐﻴﻴـﺮ ﻣﻲ دﻫﺪ( ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻳﻚ breakpointﺑﺮاي اﻳﻦ ﺧﻂ اﻳﺠﺎد ﺷﻮد. ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و روي دﻛﻤﻪ ي Testﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﺮاي اوﻟﻴﻦ ﺑﺎر ﺑﺨﻮاﻫﺪ دﺳﺘﻮر داﺧـﻞ ﺣﻠﻘـﻪ را اﺟﺮا ﻛﻨﺪ breakpoint ،ﻗﺮار داده ﺷﺪه در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ در اﺟﺮاي ﺑﺮﻧﺎﻣﻪ وﻗﻔﻪ اﻳﺠﺎد ﺷـﻮد .ﺑﻌـﺪ از ﺗﻮﻗﻒ ﺑﺮﻧﺎﻣﻪ ﭼﻨﺪﻳﻦ ﺑﺎر روي آﻳﻜﻮن Step Intoدر ﻧﻮار اﺑﺰار Debugﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣـﺸﺎﻫﺪه ﻣـﻲ ﻛﻨﻴـﺪ ﻛـﻪ ﺑـﺎ ﻛﻠﻴﻚ روي اﻳﻦ آﻳﻜﻮن ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﺧﻂ ﺑﻪ ﺧﻂ اﺟﺮا ﻣﻲ ﺷﻮد. ﺣﺎل breakpointدر ﻛﻨﺎر اﻳﻦ دﺳﺘﻮر را ﺣـﺬف ﻛﻨﻴـﺪ .ﺳـﭙﺲ در ﻧـﻮار اﺑـﺰار Debugروي آﻳﻜـﻮن Step Outﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺗﺎ اﻧﺘﻬﺎي ﻣﺘﺪ TestMethodرا اﺟﺮا ﻣﻲ ﻛﻨـﺪ و در اوﻟـﻴﻦ ﺧـﻂ درون ﻣﺘﺪ btnTest_Clickﺗﻮﻗﻒ ﻣﻲ ﻛﻨﺪ )ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻛﺪ ﺑﺮﻧﺎﻣﻪ دﻳﺪﻳﺪ ،ﻣﺘﺪ TestMethodﺗﻮﺳﻂ ﻣﺘﺪ btnTest_Clickﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد .ﭘﺲ ﻣﺘـﺪ btnTest_Clickدر ﻟﻴـﺴﺖ ﻣﺘـﺪﻫﺎي در ﺣـﺎل اﺟﺮا ،ﻗﺒﻞ از ﻣﺘﺪ TestMethodﻗﺮار ﻣﻲ ﮔﻴﺮد(.
در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎ ﻧﺤﻮه ي اﺳﺘﻔﺎده از breakpointﻫﺎ ﺑﻪ ﺻﻮرت ﺳﺎده آﺷﻨﺎ ﺷﺪﻳﻢ .اﻣﺎ اﻧﻌﻄﺎف ﭘـﺬﻳﺮي breakpoint ﻫﺎ ﺑﻴﺶ از آﻧﭽﻪ اﺳﺖ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮاي ﻳﻜﻲ از دﺳﺘﻮرات درون ﺣﻠﻘﻪ ي whileﻳـﻚ breakpointﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ breakpointﺑﻌﺪ از ﺑﻴﺴﺖ ﺑﺎر اﺟﺮاي ﺣﻠﻘﻪ ﺑﺎﻋﺚ اﻳﺠﺎد وﻗﻔـﻪ در ﺑﺮﻧﺎﻣﻪ ﺷﻮد .و ﻳﺎ ﺷﺮط ﺧﺎﺻﻲ را ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ و ﺑﮕﻮﻳﻴﺪ ﻛﻪ در ﺻﻮرت درﺳﺖ ﺑﻮدن اﻳﻦ ﺷﺮط breakpoint ،ﺑﺎﻋﺚ اﻳﺠـﺎد وﻗﻔـﻪ در اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺷﻮد و در ﻏﻴﺮ اﻳﻦ ﺻﻮرت breakpointﻏﻴﺮ ﻓﻌﺎل ﺑﺎﺷﺪ .ﺑﺮاي ﺗﻌﻴﻴﻦ اﻳﻦ ﺷﺮاﻳﻂ ﺑﺎﻳﺪ اﺑﺘـﺪا ﺑـﺎ ﻧﺤـﻮه ﻛـﺎرﻛﺮد ﭘﻨﺠﺮه ي Breakpointsآﺷﻨﺎ ﺷﻮﻳﻢ .در ﺑﺨﺶ ﺑﻌﺪي ﺑﻪ اﻳﻦ ﻣﻄﻠﺐ ﺧﻮاﻫﻴﻢ ﭘﺮداﺧﺖ.
ﭘﻨﺠﺮه ي :Breakpoints
٤٥٤
ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﭘﻨﺠﺮه ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﻤﺎﻣﻲ breakpointﻫﺎﻳﻲ ﻛﻪ در ﺑﺮﻧﺎﻣـﻪ وﺟـﻮد دارﻧـﺪ را در ﻳـﻚ ﻟﻴـﺴﺖ ﻣـﺸﺎﻫﺪه ﻛﻨﻴـﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻳﻜﻲ از اﻳﻦ breakpointﻫﺎ ﺑﺮﺳﺪ ،ﮔﺰﻳﻨـﻪ ي ﻣﺮﺑـﻮط ﺑـﻪ آن breakpointدر ﻟﻴـﺴﺖ ﺑﺮﺟﺴﺘﻪ ﺧﻮاﻫﺪ ﺷﺪ .ﺑﺮاي ﻧﻤﺎﻳﺶ ﭘﻨﺠﺮه ي Breakpointsﻣﻲ ﺗﻮاﻧﻴﺪ در ﻧﻮار اﺑﺰار Debugروي ﺳﻤﺖ راﺳﺖ ﺗﺮﻳﻦ آﻳﻜﻮن ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻳﺎ ﺑﺎ اﺳﺘﻔﺎده از ﻧﻮار ﻣﻨﻮ ﮔﺰﻳﻨﻪ ي Debug Windows Breakpointsرا اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ. ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﻨﺠﺮه ي Breakpointsﻣﺸﺎﺑﻪ ﺷﻜﻞ 12-11ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
ﺷﻜﻞ 12-11 در اﻳﻦ ﭘﻨﺠﺮه ﻋﻼوه ﺑﺮ ﻧﻤﺎﻳﺶ ﻣﻜﺎن ﻫﺮ ،breakpointﺷﺮط اﺟﺮاي آن و ﺗﻌﺪاد دﻓﻌﺎﺗﻲ ﻛﻪ ﺗﺎﻛﻨﻮن ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﻳﻦ breakpointﺑﺮﺧﻮرد ﻛﺮده اﺳﺖ ﻧﻴﺰ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﭘﻨﺠﺮه ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ breakpoint ﺟﺪﻳﺪ ﺗﻌﺮﻳﻒ ﻛﺮده ،ﻳﻜﻲ از breakpointﻫﺎي ﻛﻨﻮﻧﻲ را ﺣﺬف ﻛﺮده ،آن را ﻏﻴﺮ ﻓﻌﺎل ﻛﻨﻴﺪ و ﻳﺎ وﻳﮋﮔﻲ ﻫﺎي آن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﻳﻜﻲ از اﻳﻦ وﻳﮋﮔﻲ ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﭘﻨﺠﺮه ﻗﺎﺑﻞ ﺗﻨﻈﻴﻢ اﺳﺖ اﻳﻦ اﺳﺖ ﻛﻪ ﻫﺮ breakpointﻓﻘﻂ در ﺷﺮاﻳﻂ ﺧﺎﺻﻲ ﺑﺎﻋﺚ اﻳﺠﺎد وﻗﻔﻪ در اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺷﻮد .ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻞ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻓﻘﻂ ﻫﻨﮕﺎﻣﻲ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﺘﻮﻗﻒ ﺷﻮد ﻛﻪ ﻣﻘﺪار ﺷﻤﺎرﻧﺪه ي counterﺑﺮاﺑﺮ ﺑﺎ 10ﺑﺎﺷﺪ .ﺑﺮاي اﻳﻨﻜﻪ ﺑﺮاي ﻳﻚ breakpointﺷﺮط ﺧﺎﺻﻲ ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ ،روي ﻧﺎم آن در ﭘﻨﺠﺮه ي Breakpointsﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ و از ﻣﻨﻮﻳﻲ ﻛﻪ ﺑﺎز ﻣﻲ ﺷﻮد ﮔﺰﻳﻨﻪ ي … Conditionرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .در اﻳﻦ ﺻﻮرت ﭘﻨﺠﺮه اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 13-11ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
ﺷﻜﻞ 13-11 ﺑﺮاي ﻣﺜﺎل در اﻳﻦ ﭘﻨﺠﺮه ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﻓﻘﻂ ﻫﻨﮕﺎﻣﻲ اﻳﻦ breakpointﺑﺎﻳﺪ ﻣﻮﺟﺐ اﻳﺠﺎد وﻗﻔﻪ در ﺑﺮﻧﺎﻣﻪ ﺷﻮد ﻛﻪ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ counterﺑﺮاﺑﺮ ﺑﺎ 10ﺑﺎﺷﺪ. ﻳﻜﻲ دﻳﮕﺮ از وﻳﮋﮔﻲ ﻫﺎي breakpointﻫﺎ ﻛﻪ در اﻳﻦ ﭘﻨﺠﺮه ﻗﺎﺑﻞ ﺗﻨﻈﻴﻢ اﺳﺖ اﻳﻦ اﺳﺖ ﻛﻪ breakpointﻓﻘﻂ در ﺗﻌﺪاد دﻓﻌﺎت ﺗﻜﺮار ﻣﺸﺨﺼﻲ ﻓﻌﺎل ﺷﻮد .اﻳﻦ وﻳﮋﮔﻲ ﺑﻴﺸﺘﺮ ﺑﺮاي breakpointﻫﺎﻳﻲ ﺑﻪ ﻛﺎر ﻣﻲ رود ﻛﻪ درون ﻳﻚ ﺣﻠﻘﻪ ﻗﺮار ٤٥٥
ﻣﻲ ﮔﻴﺮﻧﺪ و ﺑﺮﻧﺎﻣﻪ در ﻃﻮل اﺟﺮا ﭼﻨﺪﻳﻦ ﺑﺎر ﺑﺎ آﻧﻬﺎ ﻣﻮاﺟﻪ ﻣﻲ ﺷﻮد .ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ در ﺑﺮﻧﺎﻣﻪ ﻗﺒﻠﻲ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻋﺪد درون ﻣﺘﻐﻴﺮ counterﺑﺮاﺑﺮ ﺑﺎ ﺿﺮﻳﺒﻲ از 10ﺑﻮد )اﻋﺪاد 30 ،20 ،10و breakpoint ،(...ﻓﻌﺎل و در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻏﻴﺮ ﻓﻌﺎل ﺑﺎﺷﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر روي breakpointﻣﻮرد ﻧﻈﺮﺗﺎن در ﭘﻨﺠﺮه ي Breakpointsﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ ي … Hit Countرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﻨﺠﺮه ي Breakpoint Hit Count ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 14-11ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
ﺷﻜﻞ 14-11 در اﻳﻦ ﭘﻨﺠﺮه ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻛﻪ breakpointﺑﻌﺪ از دﻓﻌﺎت ﺗﻜﺮار ﻣﺸﺨﺼﻲ اﺟﺮا ﺷﻮد )ﺑﺮاي ﻣﺜﺎل ﺑﻌﺪ از 10ﺑﺎر(، ﻫﻤﻮاره اﺟﺮا ﺷﻮد ،ﻓﻘﻂ وﻗﺘﻲ ﻣﺮﺗﺒﻪ اﺟﺮا ﺿﺮﻳﺐ ﻋﺪد ﺧﺎﺻﻲ ﺑﻮد اﺟﺮا ﺷﻮد و ﻳﺎ ﻓﻘﻂ در nاﻣﻴﻦ ﻣﺮﺗﺒﻪ اﺟﺮا ﺷﻮد. اﺑﺰارﻫﺎ و ﭘﻨﺠﺮه ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﺷﺪﻳﻢ ،ﻓﻘﻂ ﻗﺴﻤﺘﻲ از اﺑﺰارﻫﺎي ﻣﻮﺟﻮد در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮاي اﺷﻜﺎل زداﻳﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﻮدﻧﺪ .ﭘﻨﺠﺮه ﻫﺎي ﺑﺴﻴﺎر دﻳﮕﺮي ﻣﺎﻧﻨﺪ ،Locals ،Command Window ،Immediate Window Watch ،Autosو ...ﻧﻴﺰ وﺟﻮد دارﻧﺪ ﻛﻪ اﻟﺒﺘﻪ ﺗﻮﺿﻴﺢ ﺗﻤﺎم آﻧﻬﺎ ﺧﺎرج از اﻫﺪاف اﻳﻦ ﻛﺘﺎب اﺳﺖ .ﺑﺮاي آﺷﻨﺎﻳﻲ ﺑﺎ اﻳﻦ ﭘﻨﺠﺮه ﻫﺎ و ﻧﻴﺰ ﻧﺤﻮه ي اﺳﺘﻔﺎده از آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺳﻴﺴﺘﻢ راﻫﻨﻤﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ ) (MSDNﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ .واﺿﺢ اﺳﺖ ﻛﻪ ﻫﺮ ﭼﻪ ﺑﺎ ﻧﺤﻮه ي ﻛﺎرﻛﺮد اﻳﻦ اﺑﺰارﻫﺎ و ﭘﻨﺠﺮه ﻫﺎ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺑﺎﺷﻴﺪ ،راﺣﺖ ﺗﺮ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺧﻄﺎﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ را ﭘﻴﺪا ﻛﺮده و آﻧﻬﺎ را ﺑﺮﻃﺮف ﻛﻨﻴﺪ.
ﻛﻨﺘﺮل اﺳﺘﺜﻨﺎ ﻫﺎ در ﺑﺮﻧﺎﻣﻪ: ﻫﻤﺎﻧﻄﻮر ﻛﻪ در اﺑﺘﺪاي ﻓﺼﻞ ﮔﻔﺘﻢ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﻤﻜﻦ اﺳﺖ در ﻃﻮل اﺟﺮاي ﺧﻮد ﺑﺎ ﺷﺮاﻳﻂ ﭘﻴﺶ ﺑﻴﻨﻲ ﻧﺸﺪه اي ﻣﻮاﺟﻪ ﺷﻮد .ﺑﺮاي ﻣﺜـﺎل در ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻠﻲ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ اﮔﺮ ﻛﺎرﺑﺮ ﻧﺎم ﻓﺎﻳﻞ را در ﻛﻨﺘﺮل txtAddressﺑﻪ ﺻﻮرت ﻧﺎدرﺳﺖ وارد ﻛﻨﺪ ،ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﻳﻚ ﺣﺎﻟﺖ ﭘﻴﺶ ﺑﻴﻨﻲ ﻧﺸﺪه ﻣﻮاﺟﻪ ﻣﻲ ﺷﻮد .اﻣﺎ ﺑﺎ ﻫﻴﭻ ﻛﺪام از اﺑﺰارﻫﺎ و روﺷﻬﺎﻳﻲ ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﻓﺼﻞ ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﺷﺪﻳﻢ ﻧﻤﻲ ﺗـﻮان از رخ دادن ﭼﻨﻴﻦ ﺣﺎﻟﺘﻲ ﺟﻠﻮﮔﻴﺮي ﻛﺮد و ﻳﺎ آﻧﻬﺎ را در ﻃﻲ ﺑﺮﻧﺎﻣﻪ ﻛﻨﺘﺮل ﻛﺮد. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﻳﻚ ﭼﻨﻴﻦ ﺣﺎﻟﺖ اﺳﺘﺜﻨﺎﻳﻲ ﻣﻮاﺟﻪ ﻣﻲ ﺷﻮد ،ﺑﺮاي ﻣﺜﺎل ﻳﻚ ارﺗﺒﺎط ﺷﺒﻜﻪ اي در ﺑﺮﻧﺎﻣﻪ ﻗﻄﻊ ﻣﻲ ﺷـﻮد و ﻳـﺎ ﻓﺎﻳـﻞ ﻣﻮرد ﻧﻈﺮ ﺑﺮاي اﻣﺮي ﺧﺎص در ﻛﺎﻣﭙﻴﻮﺗﺮ ﭘﻴﺪا ﻧﻤﻲ ﺷﻮد ،در اﺻﻄﻼح ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد ﻛﻪ ﻳﻚ اﺳﺘﺜﻨﺎ 1رخ داده اﺳﺖ .رخ دادن ﻳﻚ اﺳﺘﺜﻨﺎ ﻫــﻢ ﻣــﻲ ﺗﻮاﻧــﺪ ﺑــﻪ وﺳــﻴﻠﻪ ﻛﻼﺳــﻬﺎي ﺗﻌﺮﻳــﻒ ﺷــﺪه در .NETاﻋــﻼم ﺷــﻮد )ﺑــﺮاي ﻣﺜــﺎل ﺳــﻌﻲ ﻛﻨﻴــﺪ ﺑــﺎ اﺳــﺘﻔﺎده از ﻛــﻼس ،System.IO.Fileﻓﺎﻳﻠﻲ را ﺑﺎز ﻛﻨﻴﺪ ﻛﻪ وﺟﻮد ﻧﺪارد( ﻫﻢ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ وﺳﻴﻠﻪ ي ﻣﺘﺪي درون ﻛﻼﺳـﻬﺎي ﺗﻌﺮﻳـﻒ ﺷـﺪه در ﺑﺮﻧﺎﻣﻪ اﻋﻼم ﺷﻮد )ﺑﺮاي ﻣﺜﺎل ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ﻳﻜﻲ از ﻣﺘﺪﻫﺎي ﻛﻼس ﻓﺮﺳﺘﺎده اﻧﺪ داراي ﻣﻘﺪار اﺷﺘﺒﺎﻫﻲ اﺳﺖ(. Exception
1
٤٥٦
ﺑﺮاي اﻋﻼم ﻛﺮدن اﻳﻨﻜﻪ ﻳﻚ اﺳﺘﺜﻨﺎ رخ داده اﺳﺖ ،اﺑﺘﺪا ﺑﺎﻳﺪ ﻳﻚ ﺷﻴﺊ از ﻛﻼس ) Exceptionو ﻳﺎ ﻛﻼﺳـﻬﺎي ﻣـﺸﺘﻖ ﺷـﺪه از اﻳﻦ ﻛﻼس( اﻳﺠﺎد ﺷﻮد و اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ اﺳﺘﺜﻨﺎي ﺑﻪ وﺟﻮد آﻣﺪه در اﻳﻦ ﺷﻴﺊ ﻗﺮار ﮔﻴﺮد .ﺳﭙﺲ اﻳﻦ ﺷﻴﺊ در اﺻـﻄﻼح ﺑﺎﻳـﺪ ﺗﻮﺳـﻂ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ ﺑﺎ اﻳﻦ اﺳﺘﺜﻨﺎ ﻣﻮاﺟﻪ ﺷﺪه اﺳﺖ ،ﭘﺮﺗﺎب 1ﺷﻮد. ﻣﻤﻜﻦ اﺳﺖ اﻳﻦ ﻋﺒﺎرت ﻛﻪ "ﺷﻴﺊ ﺣﺎوي اﻃﻼﻋﺎت ﺧﻄﺎ ﺑﺎﻳﺪ از ﻃﺮف ﺑﺮﻧﺎﻣﻪ ﭘﺮﺗﺎب ﺷﻮد" در اﺑﺘﺪا ﻛﻤﻲ ﮔﻴﺞ ﻛﻨﻨﺪه و ﻳﺎ ﻧﺎ ﻣﻔﻬﻮم ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ و ﻳﺎ ﻣﻤﻜﻦ اﺳﺖ اﻳﻦ ﺳﻮال ﺑﻪ وﺟﻮد ﺑﻴﺎﻳﺪ ﻛﻪ ﺑﻌﺪ از ﭘﺮﺗﺎب ﺷﺪن اﻳﻦ ﺷﻴﺊ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان اﺳﺘﺜﻨﺎي ﺑﻪ وﺟﻮد آﻣﺪه را ﻛﻨﺘﺮل ﻛﺮد؟ ﺧﻮب ،ﺑﺮاي ﻛﻨﺘﺮل اﻳﻦ ﻧﻮع ﺣﺎﻟﺘﻬﺎ در ﻛﺪ ﻣﻌﻤﻮﻻً از ﺑﻼك ﻫﺎي try/catchاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻛﺪي ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺑﺎ ﻳﻚ اﺳﺘﺜﻨﺎ ﻣﻮاﺟﻪ ﺷﻮد را درون ﻳﻚ ﺑﻼك tryﻗﺮار ﻣﻲ دﻫﻨﺪ .اﮔﺮ در ﻫﻨﮕﺎم اﺟﺮاي اﻳﻦ ﻛﺪ اﺳﺘﺜﻨﺎﻳﻲ رخ داد ،ﺷﻴﺊ اي از ﻧﻮع Exceptionﺑﻪ وﺟﻮد آﻣﺪه و ﭘﺮﺗﺎب ﻣﻲ ﺷﻮد .در اﻳﻦ ﺣﺎﻟﺖ اوﻟﻴﻦ ﺑﻼك catchﻛﻪ ﺷﺮاﻳﻂ درﻳﺎﻓـﺖ ﺷـﻴﺊ ﭘﺮﺗـﺎب ﺷﺪه را داﺷﺘﻪ ﺑﺎﺷﺪ ،آن را درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ و ﺑﻪ ﻛﻨﺘﺮل اﺳﺘﺜﻨﺎي ﺑﻪ وﺟﻮد آﻣﺪه ﻣﻲ ﭘﺮدازد. ﺑﻌﺪ از اﻳﻨﻜﻪ ﻳﻜﻲ از ﺑﻼك ﻫﺎي catchﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ ﺗﻮاﻧﺴﺖ ﺷﻴﺊ ﭘﺮﺗﺎب ﺷﺪه را درﻳﺎﻓﺖ ﻛﻨﺪ ،ﺑﻪ ﺑﺮرﺳـﻲ ﺣﺎﻟـﺖ اﺳـﺘﺜﻨﺎي ﺑـﻪ وﺟﻮد آﻣﺪه ﻣﻲ ﭘﺮدازد .در اﻳﻦ ﺣﺎﻟﺖ اﮔﺮ اﻳﻦ ﺑﻼك ﺑﺘﻮاﻧﺪ ،اﺳﺘﺜﻨﺎي ﺑﻪ وﺟﻮد آﻣﺪه را ﺗﺼﺤﻴﺢ ﻛﺮده و ﻳـﺎ ﺑـﺪون در ﻧﻈـﺮ ﮔـﺮﻓﺘﻦ آن ﺑـﻪ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ اداﻣﻪ ﻣﻲ دﻫﺪ .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﭘﻴﻐﺎم ﻣﻨﺎﺳﺒﻲ را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ دﻫﺪ و ﺑﺮﻧﺎﻣﻪ را ﺑﻪ اﺗﻤﺎم ﻣﻲ رﺳﺎﻧﺪ. ﺑﻼك ﻫﺎي try/catchﺑﺎ ﺳﺎﺧﺘﺎري ﺑﻪ ﺻﻮرت زﻳﺮ در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ. )(MethodA usual statements
Some dangerous codes that may encounter with unavoidable exceptions goes here
Some codes to handle exceptions
private void { // Some try { // // } catch { // } }
ﻧﻜﺘﻪ :درك ﺗﻔﺎوت ﺑﻴﻦ ﺧﻄﺎﻫﺎي ﻣﻮﺟﻮد در ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﺣﺎﻟﺘﻬﺎي اﺳﺘﺜﻨﺎﻳﻲ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺑﺮﻧﺎﻣﻪ ﺑﺎ آﻧﻬﺎ ﻣﻮاﺟﻪ ﺷﻮد از اﻫﻤﻴﺖ زﻳـﺎدي ﺑﺮﺧﻮردار اﺳﺖ .ﺧﻄﺎﻫﺎي ﻣﻮﺟﻮد در ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﻣﻌﻤﻮﻻ ﺑﻪ ﻋﻠﺖ ﺧﻄﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ در ﻫﻨﮕﺎم ﭘﻴﺎده ﺳﺎزي ﻛﺪ ﺑﺮﻧﺎﻣﻪ اﺳﺖ .اﻣﺎ اﺳﺘﺜﻨﺎ ﻫـﺎ ﻣﻌﻤﻮﻻً ﺑﻪ ﻋﻠﺖ رخ دادن ﺷﺮاﻳﻂ ﻗﺎﺑﻞ ﭘﻴﺶ ﺑﻴﻨﻲ اﻣﺎ اﺟﺘﻨﺎب ﻧﺎﭘﺬﻳﺮ اﺳﺖ .ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ در ﺷﺮاﻳﻄﻲ ﺧـﺎص در ﻳـﻚ ﺣﻠﻘﻪ ي ﺑﻴﻨﻬﺎﻳﺖ ﻗﺮار ﻣﻲ ﮔﻴﺮد و ﻛﺎرﺑﺮ ﻧﺎﭼﺎر ﺑﻪ ﺑﺴﺘﻦ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺷﻮد .ﭼﻨﻴﻦ رخ دادي ﺑﻪ ﻋﻠﺖ اﺷﺘﺒﺎه ﺑﺮﻧﺎﻣـﻪ ﻧـﻮﻳﺲ اﺳـﺖ و ﺧﻄـﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد .اﻣﺎ ﺗﺼﻮر ﻛﻨﻴﺪ در ﺣﺎل ﺧﻮاﻧﺪ اﻃﻼﻋﺎت ﻳﻚ ﻓﺎﻳﻞ در ﺷﺒﻜﻪ ﻫﺴﺘﻴﺪ ﻛﻪ ﻧﺎﮔﻬﺎن ﺷﺒﻜﻪ ﻗﻄـﻊ ﻣـﻲ ﺷـﻮد. وﻗﻮع ﭼﻨﻴﻦ ﺷﺮاﻳﻄﻲ در ﺑﺮﻧﺎﻣﻪ ﻗﺎﺑﻞ ﭘﻴﺶ ﺑﻴﻨﻲ اﺳﺖ اﻣﺎ واﺿﺢ اﺳﺖ ﻛﻪ ﻧﻤﻲ ﺗﻮان از آﻧﻬﺎ ﺟﻠﻮﮔﻴﺮي ﻛـﺮد .اﻳـﻦ دﺳـﺘﻪ ﻣـﻮارد ﺟﺰﺋـﻲ از اﺳﺘﺜﻨﺎ ﻫﺎ ﺑﻪ ﺷﻤﺎر ﻣﻲ روﻧﺪ و ﺑﺎﻳﺪ ﺑﻪ درﺳﺘﻲ در ﺑﺮﻧﺎﻣﻪ ﻛﻨﺘﺮل ﺷﻮﻧﺪ.
ﭼﮕﻮﻧﮕﻲ ﻳﺎﻓﺘﻦ ﺑﻼك Catchﺑﺮاي ﻳﻚ اﺳﺘﺜﻨﺎ:
Throw
1
٤٥٧
ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻗﺴﻤﺘﻲ از ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﻳﻚ اﺳﺘﺜﻨﺎ ﻣﻮاﺟﻪ ﺷﺪ ،ﺷﻴﺊ اي از ﻧﻮع Exceptionرا اﻳﺠﺎد ﻛـﺮده و ﺑﻌـﺪ از اﻳﻨﻜﻪ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ اﺳﺘﺜﻨﺎي ﺑﻪ وﺟﻮد آﻣﺪه را در آن ﻗﺮار داد ،آن را ﭘﺮﺗﺎب ﻣﻲ ﻛﻨﺪ .ﺳﭙﺲ اﻳﻦ ﺷﻴﺊ ﭘﺮﺗـﺎب ﺷـﺪه ﻣـﻲ ﺗﻮاﻧـﺪ ﺑـﻪ وﺳﻴﻠﻪ ي ﻳﻜﻲ از ﺑﻼك ﻫﺎي catchدرﻳﺎﻓﺖ ﺷﻮد .اﻣﺎ ﺑﺎﻳﺪ ﺑﻪ اﻳﻦ ﻧﻜﺘﻪ ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﺑﻼك catchاي ﻛﻪ اﻳﻦ ﺷﻴﺊ ﭘﺮﺗﺎب ﺷﺪه را درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ ،ﻟﺰوﻣﺎً ﻧﺒﺎﻳﺪ در ﻫﻤﺎن ﻣﺘﺪي ﺑﺎﺷﺪ ﻛﻪ ﺣﺎﻟﺖ اﺳﺘﺜﻨﺎ ﺑﻪ وﺟﻮد آﻣﺪه اﺳﺖ. ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺳﻪ ﻣﺘﺪ ﺑﻪ ﻧﺎﻣﻬﺎي Aو Bو Cوﺟﻮد دارﻧﺪ .ﻣﺘﺪ Aﻣﺘﺪ Bرا ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ و ﻣﺘﺪ Bﻧﻴـﺰ ﻣﺘﺪ Cرا ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ )ﺷﻜﻞ .(15-11ﺣﺎل ﻓﺮض ﻛﻨﻴﺪ ﻛﻪ دﺳﺘﻮر دوم در ﻣﺘﺪ Cﺑﺎ ﻳﻚ اﺳﺘﺜﻨﺎ ﻣﻮاﺟﻪ ﺷﻮد .در اﻳﻦ ﺣﺎﻟﺖ ﻣﺘـﺪ C ﺷﻴﺊ اي از ﻧﻮع Exceptionرا اﻳﺠﺎد ﻛﺮده و اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ اﺳﺘﺜﻨﺎ را در آن ﻗﺮار ﻣﻲ دﻫﺪ و ﺳـﭙﺲ آن را ﭘﺮﺗـﺎب ﻣـﻲ ﻛﻨﺪ .ﺑﺮﻧﺎﻣﻪ اﺑﺘﺪا ﻣﺘﺪ Cرا ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﺪ ﺗﺎ ﺑﺒﻴﻨﺪ آﻳﺎ ﺑﻼك catchدر اﻳﻦ ﻣﺘﺪ وﺟﻮد دارد ﻛﻪ ﺑﺘﻮاﻧـﺪ اﺳـﺘﺜﻨﺎي ﺑـﻪ وﺟـﻮد آﻣـﺪه را ﻛﻨﺘﺮل ﻛﻨﺪ؟ در ﺻﻮرﺗﻲ ﻛﻪ ﭼﻨﻴﻦ ﺑﻼﻛﻲ در ﻣﺘﺪ Cﻳﺎﻓﺘﻪ ﺷﺪ ،ﻛﻨﺘﺮل ﺑﺮﻧﺎﻣﻪ ﺑﻪ اﻳﻦ ﺑﻼك ﻣﻲ رود .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﺷﻴﺊ ﭘﺮﺗﺎب ﺷﺪه ﺗﻮﺳﻂ ﻣﺘﺪ Cﺑﻪ ﻣﺘﺪ Bﺧﻮاﻫﺪ رﻓﺖ .درون ﻣﺘﺪ Bﺑﺮﻧﺎﻣﻪ ﻣﺠﺪداً ﺑﻪ دﻧﺒﺎل ﻳﻚ ﺑﻼك catchﻣﻲ ﮔﺮدد ﺗﺎ ﺑﺘﻮاﻧﺪ اﺳﺘﺜﻨﺎي ﺑـﻪ وﺟـﻮد آﻣﺪه را درﻳﺎﻓﺖ و ﻛﻨﺘﺮل ﻛﻨﺪ .ﻫﻤﻴﻦ ﻣﺮاﺣﻞ ﺑﺮاي ﻣﺘﺪ Aﻧﻴﺰ ﺗﻜﺮار ﻣﻲ ﺷﻮد .اﮔﺮ در ﻫﻴﭻ ﻛﺪام از ﻣﺘـﺪﻫﺎي Aو Bو Cﺑﻼﻛـﻲ ﺑـﺮاي ﻛﻨﺘﺮل اﻳﻦ اﺳﺘﺜﻨﺎ ﻳﺎﻓﺘﻪ ﻧﺸﺪ ،ﺷﻴﺊ ﭘﺮﺗﺎب ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي CLRدرﻳﺎﻓﺖ ﻣﻲ ﺷﻮد و ﭘﻴﻐﺎم ﺧﻄﺎي ﭘﻴﺶ ﻓﺮض ﺑـﺮاي آن ﻧﻤـﺎﻳﺶ داده ﺷﺪه و ﺑﺮﻧﺎﻣﻪ ﺑﺴﺘﻪ ﻣﻲ ﺷﻮد.
ﺷﻜﻞ 15-11
ﻛﻼس :Exception ﺑﺮاي اﻳﻦ ﻛﻪ رخ دادن ﻳﻚ اﺳﺘﺜﻨﺎ اﻋﻼم ﺷﻮد ،ﺑﺎﻳﺪ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ اﺳﺘﺜﻨﺎ در ﺷﻴﺊ اي ﺧﺎص ﻗـﺮار ﺑﮕﻴـﺮد و ﺳـﭙﺲ اﻳـﻦ ﺷـﻴﺊ ﭘﺮﺗﺎب ﺷﻮد .اﻳﻦ ﺷﻴﺊ ﺑﺎﻳﺪ از ﻛﻼس Exceptionو ﻳﺎ ﻳﻜﻲ از ﻛﻼﺳﻬﺎي ﻣﺸﺘﻖ ﺷﺪه از آن ،ﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﺪه ﺑﺎﺷﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻜﻲ از ﻛﻼﺳﻬﺎي .NETﺑﺎ ﻳﻚ اﺳﺘﺜﻨﺎ ﻣﻮاﺟﻪ ﺷﻮد ،ﺑﺴﺘﻪ ﺑﻪ ﻧﻮع آن اﺳﺘﺜﻨﺎ ﻳﻚ ﺷﻴﺊ ﻣﻨﺎﺳﺐ را اﻳﺠﺎد ﻛﺮده و ﭘﺮﺗﺎب ﻣﻲ ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﭘﺎراﻣﺘﺮ ﻧﺎدرﺳﺘﻲ ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻓﺮﺳﺘﺎده ﺷﻮد ﺷﻴﺊ از ﻛﻼس ArgumentExceptionﺗﻮﻟﻴﺪ و ﭘﺮﺗﺎب ﻣﻲ ﺷــﻮد .اﮔــﺮ آدرس ﻓﺎﻳــﻞ و ﻳــﺎ داﻳﺮﻛﺘــﻮري ﻛــﻪ ﺑــﻪ اﻳــﻦ ﻣﺘــﺪ ﻓﺮﺳــﺘﺎده ﺷــﺪه اﺳــﺖ وﺟــﻮد ﻧﺪاﺷــﺘﻪ ﺑﺎﺷــﺪ ،ﺷــﻴﺊ اي از ﻛــﻼس DirectoryNotFoundExceptionو ﻳﺎ FileNotFoundExceptionاﻳﺠـﺎد ﺷـﺪه و ﭘﺮﺗـﺎب ﻣﻲ ﺷﻮد .ﺗﻤﺎم ﻛـﻼس ﻫـﺎﻳﻲ ﻛـﻪ ﺑـﺮاي اﻋـﻼم ﻳـﻚ اﺳـﺘﺜﻨﺎ ﺗﻮﺳـﻂ .NETﻣـﻮرد اﺳـﺘﻔﺎده ﻗـﺮار ﻣـﻲ ﮔﻴﺮﻧـﺪ ،از ﻛﻼﺳـﻲ ﺑـﻪ ﻧـﺎم SystemExceptionﻣﺸﺘﻖ ﺷﺪه اﻧﺪ.1 اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﻓﻘﻂ .NETﻧﻴﺴﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ رخ دادن ﻳﻚ اﺳﺘﺜﻨﺎ را اﻋﻼم ﻛﻨﺪ .ﺑﻠﻜﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻧﻴﺰ اﮔﺮ در ﻛﻼس ﻫـﺎﻳﻲ ﻛﻪ ﻃﺮاﺣﻲ ﻣﻲ ﻛﻨﺪ ﺑﺎ ﻳﻚ اﺳﺘﺜﻨﺎ ﻣﻮاﺟﻪ ﺷﺪ ،ﻣﻲ ﺗﻮاﻧﺪ از اﻳﻦ روش اﺳﺘﻔﺎده ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻃﺮاﺣﻲ ﻛﻼس Carدر ﻓﺼﻞ ﻧﻬﻢ را ﺑـﻪ ﺧﻄﺮ ﺑﻴﺎورﻳﺪ .ﺧﺎﺻﻴﺖ NumberOFDoorsدر اﻳﻦ ﻛﻼس ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺪ اﻋﺪاد در ﺑﺎزه ي 1ﺗﺎ 6را ﻗﺒﻮل ﻛﻨـﺪ .ﺑﻨـﺎﺑﺮاﻳﻦ ﻣـﻲ 1ﻛﻼس SystemExceptionﺧﻮد ﻧﻴﺰ از ﻛﻼس Exceptionﻣﺸﺘﻖ ﻣﻲ ﺷﻮد.
٤٥٨
ﺗﻮاﻧﻴــﺪ ﻋــﺪد ﻓﺮﺳــﺘﺎده ﺷــﺪه ﺑــﻪ اﻳــﻦ ﺧﺎﺻــﻴﺖ را ﺑﺮرﺳــﻲ ﻛــﺮده و اﮔــﺮ ﺧــﺎرج از اﻳــﻦ ﻣﺤــﺪوده ﺑــﻮد ،ﺷــﻴﺊ اي را از ﻛــﻼس ArgumentOutOfRangeExceptionاﻳﺠﺎد ﻛﺮده و آن را ﭘﺮﺗﺎب ﻛﻨﻴﺪ و ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ رخ دادن ﻳـﻚ اﺳـﺘﺜﻨﺎ در اﻳﻦ ﻛﻼس را اﻋﻼم ﻛﻨﻴﺪ. اﮔﺮ ﻫﻢ ﻫﻴﭻ ﻳﻚ از ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در .NETﺑﺮاي اﺳﺘﺜﻨﺎي ﺑﻪ وﺟﻮد آﻣﺪه در ﻛﻼس ﺷﻤﺎ ﻣﻨﺎﺳﺐ ﻧﺒﻮد ،ﻣﻲ ﺗﻮاﻧﻴـﺪ ﺧﻮدﺗـﺎن ﻳـﻚ ﻛﻼس ﺑﺮاي اﻳﻦ اﺳﺘﺜﻨﺎ اﻳﺠﺎد ﻛﻨﻴﺪ و ﺳﭙﺲ ﺷﻴﺊ اي را از آن ﻧﻤﻮﻧﻪ ﺳﺎزي ﻛﺮده و ﭘﺮﺗﺎب ﻛﻨﻴﺪ .اﻟﺒﺘﻪ اﻳﻦ ﻛﻼس ﺣﺘﻤـﺎً ﺑﺎﻳـﺪ از ﻛـﻼس ApplicationExceptionﻣﺸﺘﻖ ﺷﺪه ﺑﺎﺷﺪ. اﮔﺮ ﺑﺨﻮاﻫﻢ ﻣﻄﺎﻟﺐ ﺑﺎﻻ را دﺳﺘﻪ ﺑﻨﺪي ﻛﻨﻢ ،ﺑﺎﻳﺪ ﺑﮕﻮﻳﻢ ﻛﻪ اﺷﻴﺎﻳﻲ ﻛﻪ ﻫﻨﮕﺎم رخ دادن ﻳﻚ اﺳﺘﺜﻨﺎ ﺑﻪ وﺟﻮد آﻣـﺪه و ﭘﺮﺗـﺎب ﻣـﻲ ﺷـﻮﻧﺪ، ﺣﺘﻤﺎً ﺑﺎﻳﺪ از ﻛﻼس Exceptionو ﻳﺎ ﻳﻜﻲ از ﻛﻼس ﻫﺎي ﻣﺸﺘﻖ ﺷﺪه از آن ﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﻮﻧﺪ .از ﻛﻼس Exception دو ﻛﻼس ﻛﻠﻲ ﺑﻪ ﻧﺎﻣﻬﺎي SystemExceptionو ApplicationExceptionﻣﺸﺘﻖ ﻣﻲ ﺷﻮﻧﺪ .ﺣﺎل اﮔﺮ ﻳﻜﻲ از ﻛﻼﺳﻬﺎي دروﻧﻲ .NETﺑﺎ اﺳﺘﺜﻨﺎ ﻣﻮاﺟﻪ ﺷﺪ ،آن ﻛﻼس ﺑﺮاي اﻋﻼم رخ دادن اﺳـﺘﺜﻨﺎ از ﻳﻜـﻲ از ﻛﻼﺳـﻬﺎي ﻣـﺸﺘﻖ ﺷـﺪه از ﻛـــــــــﻼس SystemExceptionﻣﺎﻧﻨـــــــــﺪ ﻛـــــــــﻼس ArgumentExceptionو ﻳـــــــــﺎ FileNotFoundExceptionاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ .اﻣﺎ اﮔﺮ ﻛﻼﺳﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻃﺮاﺣﻲ ﻛﺮده اﻳﻢ ﺑﺎ اﺳـﺘﺜﻨﺎ ﻣﻮاﺟـﻪ ﺷـﺪ، ﻫﻢ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻣﺎﻧﻨﺪ ،.NETاز ﻛﻼﺳﻬﺎي ﻣﺸﺘﻖ ﺷﺪه از SystemExceptionاﺳﺘﻔﺎده ﻛﻨﻴﻢ و ﻫـﻢ ﻣـﻲ ﺗـﻮاﻧﻴﻢ ﻛـﻼس ﺟﺪﻳﺪي را از ﻛﻼس ApplicationExceptionﻣﺸﺘﻖ ﻛـﺮده و از آن ﺑـﺮاي اﻋـﻼم رخ دادن اﺳـﺘﺜﻨﺎ اﺳـﺘﻔﺎده ﻛﻨـﻴﻢ )ﺷﻜﻞ .(16-11
ﺷﻜﻞ 16-11
دﺳﺘﻮر :throw ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﺑﺮاي اﻋﻼم رخ دادن ﻳﻚ اﺳﺘﺜﻨﺎ در ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﺷﻴﺊ اي را از ﻧﻮع Exceptionاﻳﺠـﺎد ﻛـﺮده و آن را ﭘﺮﺗـﺎب ﻛﻨﻴﺪ .ﺑﺮاي ﭘﺮﺗﺎب ﺷﻴﺊ اﻳﺠﺎد ﺷﺪه ﻣﻲ ﺗﻮاﻧﻴﺪ از دﺳﺘﻮر throwاﺳﺘﻔﺎده ﻛﻨﻴﺪ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌـﺪ ،ﻳـﻚ ﻛـﻼس آزﻣﺎﻳـﺸﻲ اﻳﺠﺎد ﻛﺮده و در ﻳﻜﻲ از ﻣﺘﺪﻫﺎي اﻳﻦ ﻛﻼس ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ دﺳﺘﻮر اﻋﻼم ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﻳﻚ اﺳﺘﺜﻨﺎ رخ داده اﺳﺖ .ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ اﮔﺮ ﺑﺮاي ﻳﻚ اﺳﺘﺜﻨﺎي ﺑﻪ وﺟﻮد آﻣﺪه ﻫﻴﭻ ﺑﻼك catchاي ﻳﺎﻓﺖ ﻧﺸﻮد ،ﭼﻪ اﺗﻔﺎﻗﻲ رخ ﺧﻮاﻫﺪ داد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از دﺳﺘﻮر throw
٤٥٩
(1ﺑﺎ اﺳﺘﻔﺎده از ﻧﻮار ﻣﻨﻮي وﻳـﮋوال اﺳـﺘﻮدﻳﻮ ﮔﺰﻳﻨـﻪ ي … File New Projectرا اﻧﺘﺨـﺎب ﻛـﺮده و ﺳﭙﺲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ ﻛﻨﺴﻮل ) (Console Applicationﺑﻪ ﻧـﺎم ThrowCommandاﻳﺠـﺎد ﻛﻨﻴﺪ. (2در ﻓﺎﻳﻞ ،Program.csاز ﻛﻼس Programﻛﻼس ﺟﺪﻳﺪي ﺑﻪ ﻧﺎم Testerاﻳﺠـﺎد ﻛـﺮده و ﻛـﺪ زﻳـﺮ را درون اﻳﻦ ﻛﻼس ﻗﺮار دﻫﻴﺪ. class Tester { )(public void Run { ;)"Console.WriteLine("Enter Run... ;)(Func1 ;)"Console.WriteLine("Exit Run... } )(public void Func1 { ;)"Console.WriteLine("Enter Func1... ;)(Func2 ;)"Console.WriteLine("Exit Func1... } )(public void Func2 { ;)"Console.WriteLine("Enter Func2... ;)(throw new System.Exception ;)"Console.WriteLine("Exit Func2... } } (3در ﻛﻼس Programﺑﻪ ﻗﺴﻤﺖ ﻣﺮﺑﻮط ﺑﻪ ﻣﺘﺪ Mainﺑﺮوﻳﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷـﺪه در زﻳـﺮ را ﺑـﻪ ﺑﺪﻧـﻪ ي اﻳـﻦ ﻣﺘـﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ. )static void Main(string[] args { ;)"Console.WriteLine("Enter Main... ;)(Tester t = new Tester ;)(t.Run ;)"Console.WriteLine("Exit Main... } (4ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﭘﻨﺠﺮه اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 17-11ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .اﻳـﻦ ﭘﻨﺠـﺮه را ﻗـﺒﻼً ﻧﻴـﺰ ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺣﺎل ﻛﺎر ﺑﺎ ﭘﺮوژه ي ErrorHandlingﺑﻮدﻳﺪ ﻣﺸﺎﻫﺪه ﻛﺮده اﻳﺪ .اﻣﺎ اﻳـﻦ ﻣﺮﺗﺒـﻪ اﻃﻼﻋـﺎت درون اﻳﻦ ﻛﺎدر ﺑﺮ اﺳﺎس اﺳﺘﺜﻨﺎﻳﻲ اﺳﺖ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر throwاﻳﺠﺎد ﻛﺮده اﻳﻢ.
٤٦٠
ﺷﻜﻞ 17-11 (5ﺑﺎ اﻧﺘﺨﺎب ﮔﺰﻳﻨﻪ ي Debug Stop Debuggingاز ﻧﻮار ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮﻧﺎﻣﻪ را ﺑﺒﻨﺪﻳﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﻴﭻ ﻛﺎر ﺧﺎﺻﻲ اﻧﺠﺎم ﻧﻤﻲ ﺷﻮد ،ﻓﻘﻂ ﭼﻨﺪ ﺗﺎﺑﻊ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮﻧﺪ و وارد و ﺧﺎرج ﺷﺪن از ﺗﺎﺑﻊ در ﺧﺮوﺟﻲ ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد .در اﺑﺘﺪا ﺑﺮﻧﺎﻣﻪ ﻳﻚ ﺷﻴﺊ از ﻛﻼس Testerاﻳﺠﺎد ﻛﺮده و ﻣﺘﺪ Runرا از اﻳـﻦ ﺷـﻴﺊ ﻓﺮاﺧـﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ .ﻣﺘﺪ Runﺑﻌﺪ از ﻧﻮﺷﺘﻦ ﻋﺒﺎرﺗﻲ در ﺧﺮوﺟﻲ ﻣﺘـﺪ Func1را ﻓﺮاﺧـﻮاﻧﻲ ﻛـﺮده و ﻣﺘـﺪ Func1ﻧﻴـﺰ ﻣﺘـﺪ Func2را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ .درون ﻣﺘﺪ ،Func2ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر newﻳﻚ ﺷـﻴﺊ ﺟﺪﻳـﺪ از ﻛـﻼس System.Exception اﻳﺠﺎد ﻛﺮده و ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر throwآن را ﭘﺮﺗﺎب ﻣﻲ ﻛﻨﻴﻢ. ﺑﺎ اﻳﻦ ﻛﺎر ﺑﺮﻧﺎﻣﻪ ﺑﻼﻓﺎﺻﻠﻪ درون ﻣﺘﺪ Func2ﺑﻪ دﻧﺒﺎل ﻳﻚ ﺑﻼك catchﻣﻲ ﮔﺮدد ﺗﺎ ﺑﺘﻮاﻧﺪ اﻳﻦ ﺧﻄﺎ را ﻛﻨﺘﺮل ﻛﻨﺪ .اﻣـﺎ ﻫـﻴﭻ ﺑﻼﻛﻲ را ﭘﻴﺪا ﻧﻤﻲ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻪ ﺳﺮاغ ﻣﺘﺪ ) Func1ﻛﻪ اﺣﻀﺎر ﻛﻨﻨﺪه ي ﻣﺘﺪ Func2ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد( ﺧﻮاﻫﺪ رﻓﺖ .در اﻳﻦ ﻣﺘﺪ ﻫﻢ ﻫﻴﭻ ﺑﻼك catchاي ﻳﺎﻓﺖ ﻧﻤﻲ ﺷﻮد .ﺑﻪ ﻫﻤـﻴﻦ ﺗﺮﺗﻴـﺐ ﻣﺘـﺪ ﻫـﺎي Runو Mainﻧﻴـﺰ ﺑـﺮاي ﻳـﺎﻓﺘﻦ ﻳـﻚ ﺑـﻼك catchﻣﻨﺎﺳﺐ ﺑﺮرﺳﻲ ﻣﻲ ﺷﻮﻧﺪ .اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻛﺪ ﻫﻢ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،ﭼﻨﻴﻦ ﺑﻼﻛـﻲ ﻳﺎﻓـﺖ ﻧﻤـﻲ ﺷـﻮد .ﺑﻨـﺎﺑﺮاﻳﻦ CLR اﺟﺮاي ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﺣﺎﻟﺖ ﺗﻌﻠﻴﻖ در آورده و ﭘﻴﻐﺎم ﺧﻄﺎي ﭘﻴﺶ ﻓﺮض را ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 17-11ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. ﻧﻜﺘﻪ :دﻗﺖ ﻛﻨﻴﺪ در اﻳﻨﺠﺎ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﺑﺮﻧﺎﻣﻪ ﺑﻪ وﺳﻴﻠﻪ ي وﻳﮋوال اﺳﺘﻮدﻳﻮ اﺟﺮا ﺷﺪه اﺳﺖ ﭼﻨﻴﻦ ﭘﻴﻐﺎم ﺧﻄـﺎﻳﻲ ﻧﻤـﺎﻳﺶ داده ﺷـﺪه و ﺧﻄﻲ ﻛﻪ ﺑﺎﻋﺚ ﺑﻪ وﺟﻮد آﻣﺪن ﺧﻄﺎ ﺷﺪه اﺳﺖ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .اﮔﺮ ﻓﺎﻳﻞ اﺟﺮاﻳﻲ اﻳﻦ ﺑﺮﻧﺎﻣﻪ را ﺑﺪون اﺳـﺘﻔﺎده از وﻳـﮋوال اﺳـﺘﻮدﻳﻮ اﺟﺮا ﻛﻨﻴﺪ ،ﭘﻴﻐﺎﻣﻲ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 18-11ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد .ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻓﺎﻳﻞ اﺟﺮاﻳﻲ ﺑﺮﻧﺎﻣـﻪ ﺑـﻪ ﻓﻮﻟـﺪري ﻛـﻪ ﺑﺮﻧﺎﻣـﻪ را در آن اﻳﺠﺎد ﻛﺮده اﻳﺪ ﺑﺮوﻳﺪ ،ﻓﺎﻳﻞ اﺟﺮاﻳﻲ ﺑﺮﻧﺎﻣﻪ در ﻓﻮﻟﺪر bin\debugﻗﺮار دارد .ﻫﻤﭽﻨﻴﻦ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻣﺤﺘﻮﻳﺎت اﻳﻦ ﺻﻔﺤﻪ ﺑﻪ زﻳﺎن ﻓﺎرﺳﻲ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﻧﺪ .دﻟﻴﻞ اﻳﻦ ﻣﻮرد اﻳﻦ اﺳﺖ ﻛﻪ ﺗﻨﻈﻴﻤﺎت ﻣﺤﻠﻲ اﻳﻦ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﺮاﺑﺮ ﺑﺎ ﻛـﺸﻮر اﻳـﺮان و زﺑـﺎن ﻓﺎرﺳـﻲ اﺳﺖ .اﮔﺮ ﺗﻨﻈﻴﻤﺎت ﻛﺎﻣﭙﻴﻮﺗﺮ ﺷﻤﺎ ﺑﺮاﺑﺮ ﺑﺎ زﺑﺎن اﻧﮕﻠﻴﺴﻲ اﺳﺖ ،ﻣﺤﺘﻮﻳﺎت اﻳﻦ ﺻﻔﺤﻪ ﺑﻪ زﺑﺎن اﻧﮕﻠﻴﺴﻲ ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
٤٦١
ﺷﻜﻞ 18-11 در اﻳﻨﺠﺎ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﻫﻴﭻ ﺣﺎﻟﺖ ﺧﺎﺻﻲ ﺑﺮاي اﻋﻼم ﻳﻚ اﺳﺘﺜﻨﺎ رخ ﻧﺪاده اﺳﺖ )ﻧﻪ ارﺗﺒﺎط ﺷﺒﻜﻪ اي ﻗﻄﻊ ﺷﺪه اﺳﺖ ،ﻧﻪ ﺗﻘﺴﻴﻢ ﺑﺮ ﺻﻔﺮ ﺻﻮرت ﮔﺮﻓﺘﻪ اﺳﺖ و ﻧﻪ (...ﺻﺮﻓﺎ ﻳﻚ ﺷﻴﺊ از ﻛﻼس Exceptionرا اﻳﺠﺎد ﻛﺮده و ﭘﺮﺗﺎب ﻣﻲ ﻛﻨﻴﻢ .اﻣﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي واﻗﻌـﻲ ﺑﻬﺘﺮ اﺳﺖ ﺑﺎ ﺑﺮرﺳﻲ ﻋﻠﺖ رخ دادن اﺳﺘﺜﻨﺎ ،از ﻳﻜﻲ از ﻛﻼﺳﻬﺎي دﻳﮕﺮ .NETﻣﺘﻨﺎﺳﺐ ﺑﺎ ﺣﺎﻟﺖ ﺑـﻪ وﺟـﻮد آﻣـﺪه اﺳـﺘﻔﺎده ﻛﻨـﻴﻢ و ﻳـﺎ ﻛﻼس ﻣﺨﺼﻮﺻﻲ را ﻃﺮاﺣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﻬﺘﺮ ﻣﺸﺨﺺ ﺷﻮد ﻛﻪ ﻋﻠﺖ ﺑﻪ وﺟﻮد آﻣﺪن ﺧﻄﺎ ﭼﻪ ﺑﻮده اﺳﺖ. اﺳﺘﻔﺎده از اﻳﻦ روش ﻣﺰاﻳﺎي دﻳﮕﺮي را ﻧﻴﺰ ﺷﺎﻣﻞ ﻣﻲ ﺷﻮد ﻛﻪ ﺑﻌﺪ از آﺷﻨﺎﻳﻲ ﺑﺎ ﺑﻼك ﻫـﺎي tryو ،catchﺑـﻪ اﻫﻤﻴـﺖ آن ﭘـﻲ ﺧﻮاﻫﻴﺪ ﺑﺮد.
دﺳﺘﻮرات tryو :catch ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﻳﻚ اﺳﺘﺜﻨﺎي رخ داده را ﻛﻨﺘﺮل ﻛﻨﻴﻢ ،ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر catchﺑﻼﻛﻲ اﻳﺠﺎد ﻛﻨﻴﻢ ﻛﻪ ﺑﺘﻮاﻧﺪ ﺷﻴﺊ ﭘﺮﺗـﺎب ﺷﺪه ﺑﺮاي آن اﺳﺘﺜﻨﺎ را درﻳﺎﻓﺖ ﻛﻨﺪ .اﻣﺎ ﺑﻼك catchﺑﻪ ﺗﻨﻬﺎﻳﻲ ﻧﻤﻲ ﺗﻮاﻧﺪ اﻳﺠﺎد ﺷﻮد ﺑﺎﻳﺪ ﻫﻤﺮاه ﺑـﺎ ﺑـﻼك tryﺗﻌﺮﻳـﻒ ﺷـﻮد. ﺑﺮاي ﺗﻌﺮﻳﻒ ﺑﻼك tryﻫﻢ ﻣﻲ ﺗﻮاﻧﻴﺪ از دﺳﺘﻮر tryاﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺪي ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﻣﻮﺟﺐ اﻳﺠﺎد اﺳﺘﺜﻨﺎ ﺷـﻮد را در ﻳﻚ ﺑﻼك tryﻗﺮار ﻣﻲ دﻫﻴﻢ و ﺳﭙﺲ ﻳﻚ ﺑﻼك catchﺑﻌﺪ از ﺑﻼك tryﻧﻴﺰ ﻣﻲ ﻧﻮﻳﺴﻴﻢ ﺗﺎ در ﺻـﻮرت ﺑـﺮوز اﺳـﺘﺜﻨﺎ ﻛﻨﺘﺮل ﺑﺮﻧﺎﻣﻪ ﺑﻪ اﻳﻦ ﺑﻼك ﻓﺮﺳﺘﺎده ﺷﻮد. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻧﺤﻮه ي اﺳﺘﻔﺎده از اﻳﻦ دﺳﺘﻮرات را در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از دﺳﺘﻮرات tryو catch (1ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳـﺘﻮدﻳﻮ ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ ي ﺗﺤـﺖ ﻛﻨـﺴﻮل ﺟﺪﻳـﺪ ) (Console Applicationﺑـﻪ ﻧـﺎم TryCatchDemoاﻳﺠﺎد ﻛﻨﻴﺪ.
٤٦٢
وارد ﻛﻨﻴﺪ ﺗﺎ ﻛﻼﺳﻲ ﺑﻪ ﻧﺎمProgram ﻗﺒﻞ از ﺗﻌﺮﻳﻒ ﻛﻼسTryCatchDemo ( ﻛﺪ زﻳﺮ را در داﺧﻞ ﻓﻀﺎي ﻧﺎم2 : ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﻮدTester class Tester { public void Run() { Console.WriteLine("Enter Run..."); Func1(); Console.WriteLine("Exit Run..."); } public void Func1() { Console.WriteLine("Enter Func1..."); Func2(); Console.WriteLine("Exit Func1..."); } public void Func2() { Console.WriteLine("Enter Func2..."); try { Console.WriteLine("Entering try block..."); throw new System.Exception(); Console.WriteLine("Exiting try block..."); } catch { Console.WriteLine( "Exception caught and handled!"); } Console.WriteLine("Exit Func2..."); } } . ﻗﺮار دﻫﻴﺪProgram از ﻛﻼسMain ( دﺳﺘﻮرات ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﻧﻴﺰ در ﺑﺪﻧﻪ ي ﻣﺘﺪ3 static void Main(string[] args) { Console.WriteLine("Enter Main..."); Tester t = new Tester(); t.Run(); Console.WriteLine("Exit Main..."); Console.ReadLine();
٤٦٣
} (4ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر throwرخ دادن ﻳﻚ اﺳﺘﺜﻨﺎ در ﺑﺮﻧﺎﻣﻪ اﻋـﻼم ﺷﺪه اﺳﺖ ،اﻣﺎ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﺘﻮﻗﻒ ﻧﻤﻲ ﺷﻮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﺗﻤﺎم ﻗﺴﻤﺖ ﻫﺎ واﺿﺢ اﺳﺖ .ﻗﺴﻤﺘﻲ از دﺳﺘﻮر ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺑﺎﻋﺚ رخ دادن اﺳـﺘﺜﻨﺎ ﺷـﻮد )اﻟﺒﺘـﻪ در اﻳﻨﺠـﺎ ﻫﻤـﻮاره اﺳﺘﺜﻨﺎ رخ ﺧﻮاﻫﺪ داد( درون ﻳﻚ ﺑﻼك tryﻗﺮار داده ﺷﺪه اﺳﺖ .ﺑﺮﻧﺎﻣﻪ وارد ﻣﺘﺪ Func2ﻣﻲ ﺷﻮد و اﻳﻦ ﻣﻮرد را در ﺧﺮوﺟﻲ ﭼﺎپ ﻣﻲ ﻛﻨﺪ .ﺳﭙﺲ وارد ﺑﻼك tryﻣﻲ ﺷﻮد و ﺑﻌﺪ از ﭼﺎپ ﻋﺒﺎرت در ﺧﺮوﺟﻲ ﺑﺎ رخ دادن ﻳﻚ اﺳﺘﺜﻨﺎ روﺑﺮو ﻣﻲ ﺷﻮد .ﺑـﺎ رخ دادن اﺳـﺘﺜﻨﺎ ﺑﺮﻧﺎﻣﻪ ﺑﻪ دﻧﺒﺎل ﻳﻚ ﺑﻼك catchﻣﻲ ﮔﺮدد ﺗﺎ ﺑﺘﻮاﻧﺪ اﻳﻦ اﺳﺘﺜﻨﺎ را ﻛﻨﺘﺮل ﻛﻨﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴـﺪ ﻧﺰدﻳﻜﺘـﺮﻳﻦ ﺑـﻼك درون ﻣﺘــﺪ ،Func2ﺑﻌــﺪ از ﺑــﻼك tryﻗــﺮار دارد .ﺑﻨــﺎﺑﺮاﻳﻦ ﻛﻨﺘــﺮل ﺑﺮﻧﺎﻣــﻪ ﺑــﻪ اﻳــﻦ ﻗــﺴﻤﺖ ﻣﻨﺘﻘــﻞ ﻣــﻲ ﺷــﻮد و ﻋﺒــﺎرت "! "Exception caught and handledدر ﺧﺮوﺟﻲ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد. )(public void Func2 { ;)"Console.WriteLine("Enter Func2... try { ;)"Console.WriteLine("Entering try block... ;)(throw new System.Exception ;)"Console.WriteLine("Exiting try block... } catch { (Console.WriteLine ;)"!"Exception caught and handled } ;)"Console.WriteLine("Exit Func2... } دﻗﺖ ﻛﻨﻴﺪ ﺑﻌﺪ از اﻳﻨﻜﻪ دﺳﺘﻮرات درون ﺑﻼك catchﺗﻤﺎم ﺷﺪ ،ﻛﻨﺘﺮل ﺑﺮﻧﺎﻣﻪ ﺑﻪ داﺧﻞ ﺑﻼك tryﺑﺮ ﻧﻤﻲ ﮔﺮدد .ﺑﻠﻜـﻪ از ﺑـﻼك catchﺧﺎرج ﺷﺪه و اداﻣﻪ ي دﺳﺘﻮرات ﺑﻌﺪ از اﻳﻦ ﺑﻼك در ﻣﺘﺪ را اﺟﺮا ﻣﻲ ﻛﻨـﺪ )ﻋﺒـﺎرت " "Exit Func2...را در ﺧﺮوﺟﻲ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ( .ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻤﺎم دﺳﺘﻮراﺗﻲ ﻛﻪ ﺑﻌﺪ از رخ دادن ﻳﻚ اﺳـﺘﺜﻨﺎ در ﺑـﻼك tryوﺟـﻮد دارﻧـﺪ اﺟـﺮا ﻧﺨﻮاﻫﻨـﺪ ﺷـﺪ )ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻋﺒﺎرت " "Exiting try block...در ﺧﺮوﺟﻲ ﻧﻤﺎﻳﺶ داده ﻧﻤﻲ ﺷﻮد(. اﻳﻦ ﻣﻮرد ﺑﺮاي ﺣﺎﻟﺘﻬﺎﻳﻲ ﻛﻪ اﺳﺘﺜﻨﺎ ﺗﻮﺳﻂ ﻳﻚ ﺑﻼك catchﺧﺎرج از اﻳﻦ ﻣﺘﺪ درﻳﺎﻓﺖ ﻣﻲ ﺷﺪ ﻧﻴﺰ ﺻﺎدق اﺳﺖ .ﺑﺮاي ﻣﺜـﺎل ﺗـﺼﻮر ﻛﻨﻴﺪ ﻛﻪ دﺳﺘﻮرات ﻣﺘﺪ Func2درون ﺑﻼك tryﻗﺮار ﻧﮕﺮﻓﺘﻪ ﺑﺎﺷﻨﺪ ،ﺑﻠﻜﻪ دﺳﺘﻮرات ﻣﺘـﺪ Runدرون ﺑـﻼك tryﺑﺎﺷـﻨﺪ .در اﻳﻦ ﺻﻮرت ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ در ﻣﺘﺪ Func2ﺑﺎ اﺳﺘﺜﻨﺎ ﻣﻮاﺟﻪ ﻣﻲ ﺷﺪ ،ﻫﻴﭻ ﺑﻼﻛﻲ ﺑﺮاي ﻛﻨﺘﺮل اﻳﻦ اﺳﺘﺜﻨﺎ در اﻳﻦ ﻣﺘـﺪ ﭘﻴـﺪا ﻧﻤـﻲ ﻛﺮد .ﺑﻨﺎﺑﺮاﻳﻦ از اﺟﺮاي ﺑﻘﻴﻪ ي دﺳﺘﻮرات اﻳﻦ ﻣﺘﺪ ﺻﺮﻓﻨﻈﺮ ﻣﻲ ﻛﺮد و ﺑﻪ درون ﻣﺘﺪ Func1ﻣـﻲ رﻓـﺖ .درون ﻣﺘـﺪ Func1ﻧﻴـﺰ ﺑﻼك ﻣﻨﺎﺳﺒﻲ ﭘﻴﺪا ﻧﻤﻲ ﻛﺮد ،ﺑﻨﺎﺑﺮاﻳﻦ دﺳﺘﻮرات ﺑﺎﻗﻴﻤﺎﻧﺪه در ﻣﺘﺪ Func1را ﻧﻴﺰ اﺟﺮا ﻧﻤﻲ ﻛﺮد و ﺑﻪ ﻣﺘﺪ Runﻣﻲ رﻓﺖ .در اﻳﻦ ﻣﺘﺪ
٤٦٤
ﻛﻨﺘﺮل ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﺑﻼك catchﻣﻮﺟﻮد ﻣﻲ ﺳﭙﺮد و اﺟﺮاي ﺑﺮﻧﺎﻣﻪ از دﺳﺘﻮرات اﻳﻦ ﻣﺘﺪ ﺑﻪ ﺑﻌﺪ اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﺮد )اﻳـﻦ ﺗﻐﻴﻴـﺮات را در ﻛﺪ اﻳﺠﺎد ﻛﻨﻴﺪ و ﺑﻌﺪ از اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ،ﺧﺮوﺟﻲ آن را ﺑﺮرﺳﻲ ﻛﻨﻴﺪ ﺗﺎ ﺑﻬﺘﺮ ﺑﺎ ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻣﻮارد آﺷﻨﺎ ﺷﻮﻳﺪ(.
اﻳﺠﺎد ﺑﻼك ﻫﺎي catchاﺧﺘﺼﺎﺻﻲ: ﺑﻼك catchاي ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻠﻲ اﻳﺠﺎد ﻛﺮدﻳﻢ ،اﺳﺘﺜﻨﺎ ﻫﺎﻳﻲ را ﻛﻪ ﺷﻴﺊ ﻣﺮﺑﻮط ﺑﻪ آﻧﻬﺎ از ﻧﻮع Exceptionﺑـﻮد ﻣـﻲ ﺗﻮاﻧﺴﺖ ﻛﻨﺘﺮل ﻛﻨﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻛﻼس از ﻛﻼس دﻳﮕﺮي ﻣﺸﺘﻖ ﺷﻮد ،اﺷﻴﺎﻳﻲ ﻛﻪ از ﻛﻼس ﻧﻤﻮﻧـﻪ ﺳـﺎزي ﺷﺪه اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ ﺻﻮرت اﺷﻴﺎﻳﻲ از ﻛﻼس ﭘﺎﻳﻪ رﻓﺘﺎر ﻛﻨﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻨﺠﺎ ﻫـﻢ اﮔـﺮ ﺑـﺮاي ﻣﺜـﺎل اﺳـﺘﺜﻨﺎﻳﻲ از ﻧـﻮع ArgumentExceptionﺑــﻪ وﺟــﻮد ﻣــﻲ آﻣــﺪ ،ﺷــﻴﺊ ﻣﺮﺑــﻮط ﺑــﻪ اﻳــﻦ اﺳــﺘﺜﻨﺎ ﻣــﻲ ﺗﻮاﻧــﺴﺖ ﺑــﻪ ﺷــﻴﺊ اي از ﻧــﻮع Exceptionﺗﺒﺪﻳﻞ ﺷﻮد و ﺳﭙﺲ ﺗﻮﺳﻂ اﻳﻦ ﺑﻼك catchﻛﻨﺘﺮل ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗـﻮاﻧﻴﻢ ﺑﮕـﻮﻳﻴﻢ ﺑـﻼك catchاي ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻠﻲ اﻳﺠﺎد ﻛﺮدﻳﻢ ﻫﺮ ﻧﻮع اﺳﺘﺜﻨﺎﻳﻲ را ﻣﻲ ﺗﻮاﻧﺴﺖ ﻛﻨﺘﺮل ﻛﻨﺪ. اﻣﺎ در ﺷﺮاﻳﻄﻲ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﻢ ﻳﻚ ﺑﻼك catchرا ﺑﻪ ﻧﺤﻮي اﻳﺠﺎد ﻛﻨﻴﻢ ﻛﻪ ﻓﻘﻂ ﺑﺘﻮاﻧﺪ ﻧﻮع ﺧﺎﺻﻲ از اﺳﺘﺜﻨﺎ ﻫـﺎ را ﻛﻨﺘـﺮل ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ در ﻗﺴﻤﺘﻲ از ﻳﻚ ﻣﺘﺪ در ﺣﺎل ﺧﻮاﻧﺪن ﻳﻚ ﻓﺎﻳﻞ از ﺷﺒﻜﻪ ﻫﺴﺘﻴﺪ و ﻣﻲ ﺧﻮاﻫﻴﺪ اﮔﺮ در ﻃﻲ اﻳﻦ ﻣﺪت ﺷﺒﻜﻪ ﻗﻄﻊ ﺷﺪ از اداﻣﻪ ي ﺧﻮاﻧﺪن ﻓﺎﻳﻞ ﺻﺮﻓﻨﻈﺮ ﻛﺮده و ﺑﻘﻴﻪ ي دﺳﺘﻮرات ﻣﺘﺪ را اﺟﺮا ﻛﻨﻴﺪ .اﻣـﺎ اﮔـﺮ اﺳـﺘﺜﻨﺎي دﻳﮕـﺮي در ﻣﺘـﺪ رخ داد ﻣـﻲ ﺧﻮاﻫﻴﺪ آن اﺳﺘﺜﻨﺎ ﺑﻪ ﻣﺘﺪ ﺑﺎﻻﺗﺮ ﻣﻨﺘﻘﻞ ﺷﻮد )ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻧﻤﻲ ﺧﻮاﻫﻴﺪ اﺳﺘﺜﻨﺎ ﻫﺎي دﻳﮕﺮ ،درون اﻳﻦ ﻣﺘﺪ ﻛﻨﺘﺮل ﺷﻮﻧﺪ( .در اﻳﻦ ﺣﺎﻟـﺖ ﺑﺎﻳﺪ ﺑﻼك catchرا ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ ﻓﻘﻂ اﺳﺘﺜﻨﺎ ﻫﺎي ﻧﻮع ﺧﺎﺻﻲ را ﺑﺘﻮاﻧﺪ درﻳﺎﻓﺖ ﻛﻨﺪ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴـﺪ ﺑﻌـﺪ در ﻃﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻛﺎر ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﺑﻼك ﻫﺎي catchاﺧﺘﺼﺎﺻﻲ (1ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳـﺘﻮدﻳﻮ ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ ي ﺗﺤـﺖ ﻛﻨـﺴﻮل ﺟﺪﻳـﺪ ) (Console Applicationﺑـﻪ ﻧـﺎم DedicatedCatchDemoاﻳﺠﺎد ﻛﻨﻴﺪ. (2درون ﻓﻀﺎي ﻧﺎم ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ و ﺧﺎرج از ﻛﻼس Programﻛﺪ زﻳﺮ را وارد ﻛﻨﻴﺪ ﺗﺎ ﻛـﻼس ﺟﺪﻳـﺪي در ﺑﺮﻧﺎﻣـﻪ اﻳﺠﺎد ﺷﻮد. class Tester { )(public void Run { try { ;double a = 5 ;double b = 0 Console.WriteLine("Dividing " + a + ;)"" by " + b + "... Console.WriteLine(a + " / " + b + ;))" = " + DoDivide(a, b } // most derived exception type first
٤٦٥
catch (System.DivideByZeroException) { Console.WriteLine( "DivideByZeroException caught!"); } catch (System.ArithmeticException) { Console.WriteLine( "ArithmeticException caught!"); } // generic exception type last catch { Console.WriteLine( "Unknown exception caught"); } } // do the division if legal public double DoDivide(double a, double b) { if (b == 0) throw new System.DivideByZeroException(); if (a == 0) throw new System.ArithmeticException(); return a / b; } } . اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ ﺑﺮﻧﺎﻣﻪ ﻛﺎﻣﻞ ﺷﻮدProgram در ﻛﻼسMain ( ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ ﺑﺪﻧﻪ ي ﻣﺘﺪ3 static void Main(string[] args) { Console.WriteLine("Enter Main..."); Tester t = new Tester(); t.Run(); Console.WriteLine("Exit Main..."); Console.ReadLine(); } ﻛﻠـﻲ درﻳﺎﻓـﺖ ﻧﺨﻮاﻫـﺪ ﺷـﺪcatch ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ اﺳﺘﺜﻨﺎي ﺑﻪ وﺟﻮد آﻣﺪه ﺗﻮﺳﻂ ﺑـﻼك.( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ4 ﺑﻠﻜـﻪ ﺑـﻪ ﻋﻠـﺖ اﻳﻨﻜـﻪ،(" در ﺧﺮوﺟﻲ ﭼﺎپ ﻧﻤـﻲ ﺷـﻮدUnknown exception caught" )ﻋﺒﺎرت اﺳــﺖ ﻛﻨﺘـﺮل ﺑﺮﻧﺎﻣـﻪ ﺑـﻪ اوﻟـﻴﻦ ﺑــﻼكDivideByZeroException اﺳـﺘﺜﻨﺎي ﺑـﻪ وﺟـﻮد آﻣـﺪه از ﻧـﻮع " در ﺧﺮوﺟـﻲDivideByZeroException caught!" ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد و ﻋﺒﺎرتcatch .(19-11 ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد )ﺷﻜﻞ
٤٦٦
ﺷﻜﻞ 19-11
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در ﻛﻼس Testerدر ﺑﺮﻧﺎﻣﻪ ي ﺑﺎﻻ ،ﻣﺘﺪ Runاز ﻣﺘﺪ DoDivideﺑﺮاي ﺗﻘﺴﻴﻢ دو ﻋﺪد اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ .اﻳـﻦ ﻣﺘـﺪ اﺑﺘـﺪا ﭘﺎراﻣﺘﺮ ﻫﺎ را ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﺪ ،اﮔﺮ ﭘﺎراﻣﺘﺮ دوم ﺻﻔﺮ ﺑﻮد ﺷﻴﺊ اي از ﻧﻮع DivedieByZeroExceptionاﻳﺠﺎد ﻛﺮده و ﭘﺮﺗﺎب ﻣﻲ ﻛﻨﺪ ،زﻳﺮا اﻧﺠﺎم ﭼﻨﻴﻦ ﺗﻘﺴﻴﻤﻲ در ﺑﺮﻧﺎﻣﻪ ﺑﺎﻋﺚ ﺑﻪ وﺟﻮد آﻣﺪن ﺧﻄﺎ ﻣﻲ ﺷﻮد .ﻫﻤﭽﻨﻴﻦ اﮔﺮ ﭘﺎراﻣﺘﺮ اول ﺻـﻔﺮ ﺑـﻮد اﻳـﻦ ﻣﺘـﺪ اﺳﺘﺜﻨﺎﻳﻲ را از ﻧﻮع ArithmeticExceptionﺗﻮﻟﻴﺪ ﻣﻲ ﻛﻨﺪ .اﻟﺒﺘﻪ در اﻳﻦ ﺣﺎﻟﺖ ﻧﺒﺎﻳﺪ اﺳﺘﺜﻨﺎﻳﻲ ﺗﻮﻟﻴﺪ ﺷﻮد زﻳـﺮا ﺗﻘـﺴﻴﻢ ﺻﻔﺮ ﺑﺮ ﻫﺮ ﻋﺪدي ﻳﻚ ﺗﻘﺴﻴﻢ ﻣﻨﻄﻘﻲ اﺳﺖ .اﻣﺎ ﺑﺮاي اﻳﻨﻜﻪ ﻣﺜﺎل اﻳﻦ ﻗﺴﻤﺖ ﻛﺎﻣﻞ ﺷﻮد ﻣﺘﺪ DoDivideدر ﺻﻮرﺗﻲ ﻛﻪ ﭘـﺎراﻣﺘﺮ اول ﺻﻔﺮ ﺑﺎﺷﺪ اﺳﺘﺜﻨﺎﻳﻲ را از ﻧﻮع ArithmeticExceptionﺗﻮﻟﻴﺪ ﻣﻲ ﻛﻨﺪ. // do the division if legal )public double DoDivide(double a, double b { )if (b == 0 ;)(throw new System.DivideByZeroException )if (a == 0 ;)(throw new System.ArithmeticException ;return a / b } در ﺑﺪﻧﻪ ي ﻣﺘﺪ Runدو ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﻧﺎﻣﻬﺎي aو bﺗﻌﺮﻳﻒ ﻛﺮده و ﻣﻘﺎدﻳﺮ 5و 0را در آﻧﻬﺎ ﻗﺮار ﻣﻲ دﻫﻴﻢ .ﺳﭙﺲ ﺳـﻌﻲ ﻣـﻲ ﻛﻨـﻴﻢ ﺑـﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ DoDivideآﻧﻬﺎ را ﺑﺮ ﻳﻜﺪﻳﮕﺮ ﺗﻘﺴﻴﻢ ﻛﻨﻴﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ در اﻳﻦ ﺣﺎﻟﺖ ﻣﺘـﺪ DoDivideاﺳـﺘﺜﻨﺎي DivideByZeroExceptionرا اﻳﺠﺎد ﻛﺮده و ﭘﺮﺗﺎب ﻣﻲ ﻛﻨﺪ و ﭼﻮن در ﻣﺘﺪ DoDivideﻗﺴﻤﺘﻲ ﺑﺮاي ﻛﻨﺘـﺮل اﻳﻦ اﺳﺘﺜﻨﺎ وﺟﻮد ﻧﺪارد ،ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻣﺘﺪ Runﺑﺮﻣﻲ ﮔﺮدد .در ﻣﺘﺪ Runﺳﻪ ﺑﻼك catchﻣﺨﺘﻠﻒ وﺟﻮد دارد .ﺑﻼك اول ﻓﻘﻂ ﻣـﻲ ﺗﻮاﻧﺪ اﺳﺘﺜﻨﺎ ﻫﺎﻳﻲ از ﻧﻮع DivideByZeroExceptionرا درﻳﺎﻓﺖ ﻛﻨﺪ .ﺑﻼك دوم ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺪ اﺳﺘﺜﻨﺎ ﻫـﺎﻳﻲ از ﻧـﻮع ArithmeticExceptionرا درﻳﺎﻓﺖ ﻛﻨﺪ و ﺑﻼك ﺳﻮم ﻫﺮ ﻧﻮع اﺳﺘﺜﻨﺎﻳﻲ را ﻣﻲ ﺗﻮاﻧﺪ ﻛﻨﺘـﺮل ﻛﻨـﺪ .ﺑﻨـﺎﺑﺮاﻳﻦ اﺳـﺘﺜﻨﺎي ﺗﻮﻟﻴﺪ ﺷﺪه در ﻣﺘﺪ DoDivideﺗﻮﺳﻂ ﺑﻼك اول درﻳﺎﻓﺖ ﻣﻲ ﺷﻮد و ﺑﺮﻧﺎﻣﻪ از درون اﻳﻦ ﺑﻼك اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ. )(public void Run { try { ;double a = 5 ٤٦٧
;double b = 0 Console.WriteLine("Dividing " + a + ;)"" by " + b + "... Console.WriteLine(a + " / " + b + ;))" = " + DoDivide(a, b } // most derived exception type first )catch (System.DivideByZeroException { (Console.WriteLine ;)"!"DivideByZeroException caught } )catch (System.ArithmeticException { (Console.WriteLine ;)"!"ArithmeticException caught } // generic exception type last catch { (Console.WriteLine ;)""Unknown exception caught } } ﺗﻮﺟــﻪ ﻛﻨﻴــﺪ ﻛــﻪ ﻛــﻼس ﻣﺮﺑــﻮط ﺑــﻪ اﺳــﺘﺜﻨﺎي DivideByZeroExceptionاز ﻛــﻼس ﻣﺮﺑــﻮط ﺑــﻪ اﺳــﺘﺜﻨﺎي ،ArithmeticExceptionو ﺧﻮد اﻳﻦ ﻛﻼس ﻧﻴﺰ از ﻛﻼس Exceptionﻣﺸﺘﻖ ﻣﻲ ﺷﻮد .ﭘﺲ اﺷـﻴﺎي ﻧﻤﻮﻧـﻪ ﺳــــــﺎزي ﺷــــــﺪه از ﻛــــــﻼس DivideByZeroExceptionﻣــــــﻲ ﺗﻮاﻧﻨــــــﺪ ﺑــــــﻪ ﻛﻼﺳــــــﻬﺎي ArithmeticExceptionو ﻳﺎ Exceptionﻧﻴﺰ ﺗﺒﺪﻳﻞ ﺷﻮﻧﺪ. ﺑﻨـــﺎﺑﺮاﻳﻦ اﮔـــﺮ در ﻣﺘـــﺪ Runﺗﺮﺗﻴـــﺐ ﻗﺮارﮔﻴـــﺮي ﺑـــﻼك ﻫـــﺎي catchرا ﺗﻐﻴﻴـــﺮ دﻫـــﻴﻢ ،ﺑـــﺮاي ﻣﺜـــﺎل ﺑـــﻼك ArithmeticExceptionرا ﻗﺒﻞ از ﺑﻼك DivideByZeroExceptionﻗﺮار دﻫﻴﻢ ﺑﺮﻧﺎﻣﻪ ﻫﻴﭽﮕـﺎه وارد ﺑــﻼك DivideByZeroExceptionﻧﺨﻮاﻫــﺪ ﺷــﺪ .زﻳــﺮا اﮔــﺮ ﺷــﻴﺊ ﻣﺮﺑــﻮط ﺑــﻪ ﻳــﻚ اﺳــﺘﺜﻨﺎ از ﻧــﻮع DivideByZeroExceptionﺑﺎﺷﺪ ،وﻗﺘﻲ ﺑﺎ ﺑﻼﻛﻲ از ﻧﻮع ArithmeticExceptionﺑﺮﺧﻮرد ﻛﻨﺪ ﺑﻪ اﻳﻦ ﻛﻼس ﺗﺒﺪﻳﻞ ﺷﺪه و ﻛﻨﺘﺮل ﺑﺮﻧﺎﻣﻪ وارد اﻳﻦ ﺑﻼك ﺧﻮاﻫﺪ ﺷﺪ .ﺑﻨﺎﺑﺮاﻳﻦ دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻫﻤﻮاره ﺑﻼك ﻫـﺎي catchﻣﺮﺑـﻮط ﺑـﻪ درﻳﺎﻓﺖ اﺳﺘﺜﻨﺎ ﻫﺎي ﺧﺎص را ﻗﺒﻞ از ﺑﻼك ﻫﺎي catchﻣﺮﺑﻮط ﺑﻪ درﻳﺎﻓﺖ اﺳﺘﺜﻨﺎ ﻫﺎي ﻋﻤﻮﻣﻲ ﻗﺮار دﻫﻴﺪ.
ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي ﻛﻼس :Exception در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﻫﻤﻮاره ﮔﻔﺘﻪ ﺷﺪه اﺳﺖ ﻛﻪ ﺑﺮاي اﻋﻼم رخ دادن ﻳﻚ اﺳﺘﺜﻨﺎ ﺑﺎﻳﺪ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ آن اﺳـﺘﺜﻨﺎ را در ﻳـﻚ ﺷـﻴﺊ از ﻧﻮع Exceptionﻗﺮار داد و ﺳﭙﺲ آن را ﭘﺮﺗﺎب ﻛﺮد ﺗﺎ ﺑﻪ وﺳﻴﻠﻪ ي ﻳﻚ ﺑﻼك درﻳﺎﻓﺖ ﺷﻮد .ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻣﻮارد را ﻧﻴـﺰ در ﻣﺜﺎل ﻫﺎي ﻗﺒﻠﻲ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ .اﻣﺎ در اﻳﻨﺠﺎ اﻳﻦ ﺳﻮال ﭘﻴﺶ ﻣﻲ آﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان درون ﻳﻚ ﺑﻼك catchﺑﻪ اﻃﻼﻋﺎﺗﻲ در ﻣﻮرد اﺳﺘﺜﻨﺎي ﺑﻪ وﺟﻮد آﻣﺪه دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﺮد.
٤٦٨
ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت ﻳﻚ اﺳﺘﺜﻨﺎ در ﺑﻼك catchﻣﻲ ﺗﻮاﻧﻴﻢ از ﻛﻼس Exceptionو ﻳﺎ ﻛﻼﺳـﻬﺎي ﻣـﺸﺘﻖ ﺷـﺪه از آن اﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻳﻚ ﺑﻼك catchﺑﺮاي درﻳﺎﻓﺖ اﺳﺘﺜﻨﺎ ﻫـﺎﻳﻲ از ﻧـﻮع ArithmeticException در ﻣﺘﺪ ﻗﺮار دادﻳﻢ ،درون اﻳﻦ ﺑﻼك ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑـﻪ ﺗﻤـﺎم ﺧﺎﺻـﻴﺖ ﻫـﺎ و ﻣﺘـﺪﻫﺎي ﻛـﻼس ArithmeticException دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ .ﻗﺒﻞ از اﻳﻨﻜﻪ ﻧﺤﻮه ي اﻳﻦ ﻛﺎر را در ﺑﺮﻧﺎﻣﻪ ﻣﺸﺎﻫﺪه ﻛﻨﻴﻢ ،ﺑﻬﺘﺮ اﺳﺖ اﺑﺘﺪا ﺑﺎ ﻳﻚ ﺳﺮي از ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي ﻣﻬﻢ ﻛﻼس ) Exceptionﻛﻪ ﻣﺴﻠﻤﺎً در ﺗﻤﺎم ﻛﻼﺳﻬﺎي ﻣﺸﺘﻖ ﺷﺪه از آن ﻧﻴﺰ وﺟﻮد دارﻧﺪ( آﺷﻨﺎ ﺷﻮﻳﻢ. اوﻟﻴﻦ و ﻣﻬﻤﺘﺮﻳﻦ ﺧﺎﺻﻴﺖ اﻳﻦ ﻛﻼس ،ﺧﺎﺻﻴﺖ Messageﻣﻲ ﺑﺎﺷﺪ ﻛﻪ ﺣﺎوي اﻃﻼﻋﺎﺗﻲ در ﻣﻮرد دﻟﻴﻞ رخ دادن اﻳﻦ اﺳﺘﺜﻨﺎ اﺳﺖ. ﻛﺪي ﻛﻪ اﺳﺘﺜﻨﺎ در آن رخ داده اﺳﺖ ،ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ را ﺗﻨﻈﻴﻢ ﻛﺮده و ﺳﭙﺲ ﺷﻴﺊ را ﭘﺮﺗﺎب ﻣﻲ ﻛﻨﺪ .اﻣﺎ ﺑﻌﺪ از ﺗﻨﻈـﻴﻢ ﺷـﺪن دﻳﮕـﺮ ﻧﻤﻲ ﺗﻮان ﻣﻘﺪار آن را ﺗﻐﻴﻴﺮ داد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ اﻳﻦ ﺧﺎﺻﻴﺖ ﻳﻚ ﺧﺎﺻﻴﺖ ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ اﺳﺖ. ﺧﺎﺻﻴﺖ ﻣﻬﻢ دﻳﮕﺮ ﺧﺎﺻﻴﺖ HelpLinkاﺳﺖ و ﺣﺎوي ﻟﻴﻨﻜﻲ اﺳﺖ ﻛﻪ ﺑﻪ راﻫﻨﻤﺎي اﺳﺘﺜﻨﺎي ﺑﻪ وﺟﻮد آﻣﺪه اﺷﺎره ﻣـﻲ ﻛﻨـﺪ .اﻳـﻦ ﺧﺎﺻﻴﺖ ﺑﻪ ﺻﻮرت ﺧﻮاﻧﺪﻧﻲ-ﻧﻮﺷﺘﻨﻲ اﺳﺖ و ﻣﻘﺪار آن در ﻫﺮ ﻗﺴﻤﺘﻲ از ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺗﻐﻴﻴﺮ ﻛﻨﺪ. در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺮﻧﺎﻣﻪ اي ﺧﻮاﻫﻴﻢ ﻧﻮﺷﺖ و در آن ﻗﺒﻞ از اﻋﻼم رخ دادن ﻳﻚ اﺳﺘﺜﻨﺎ ﻣﻘﺪار ﺑﻌﻀﻲ از ﺧﺎﺻـﻴﺖ ﻫـﺎي آن را ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﻨﻴﻢ .ﻫﻤﭽﻨﻴﻦ در ﺑﻼك catchاز ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺘﻬﺎي ﺗﻨﻈﻴﻢ ﺷﺪه اﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد ﺗﺎ ﺑﻪ اﻃﻼﻋـﺎت اﺳـﺘﺜﻨﺎي ﺑـﻪ وﺟﻮد آﻣﺪه دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺧﺎﺻﻴﺘﻬﺎي ﻛﻼس Exception (1ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮﻧﺎﻣﻪ اي ﺗﺤﺖ ﻛﻨﺴﻮل ﺑﻪ ﻧﺎم ExceptionPropertiesاﻳﺠﺎد ﻛﻨﻴﺪ. (2درون ﻓﻀﺎي ﻧﺎم ﺑﺮﻧﺎﻣﻪ و ﻗﺒﻞ از ﻛﻼس Programﻛﺪ زﻳﺮ را وارد ﻛﻨﻴﺪ ﺗﺎ ﻛﻼس Testerﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﻮد. class Tester { )(public void Run { try { ;)"Console.WriteLine("Open file here ;double a = 12 ;double b = 0 " = " Console.WriteLine(a + " / " + b + ;))+ DoDivide(a, b (Console.WriteLine ;)""This line may or may not print } // most derived exception type first )catch (System.DivideByZeroException e { (Console.WriteLine " "\nDivideByZeroException! Msg: ;)+ e.Message " Console.WriteLine("\nHelpLink: ;)+ e.HelpLink
٤٦٩
} catch { Console.WriteLine( "Unknown exception caught"); } } // do the division if legal public double DoDivide(double a, double b) { if (b == 0) { DivideByZeroException e = new DivideByZeroException(); e.HelpLink = "http://www.HelpSite.com"; throw e; } if (a == 0) throw new ArithmeticException(); return a / b; } }
. اﺿﺎﻓﻪ ﻛﻨﻴﺪProgram درون ﻛﻼسMain ( ﻛﺪ زﻳﺮ را ﻧﻴﺰ ﺑﻪ ﺑﺪﻧﻪ ي ﻣﺘﺪ3 static void Main(string[] args) { Console.WriteLine("Enter Main..."); Tester t = new Tester(); t.Run(); Console.WriteLine("Exit Main..."); Console.ReadLine(); } ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ و اﻃﻼﻋﺎت ﺗﻨﻈﻴﻢ ﺷﺪه ﻣﺮﺑﻮط ﺑﻪ ﺧﻄﺎﻳﻲ ﻛﻪ ﺑﻪ20-11 ﭘﻨﺠﺮه اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ.( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ4 .وﺟﻮد آﻣﺪه اﺳﺖ در آن ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد
٤٧٠
ﺷﻜﻞ 20-11
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻧﺤﻮه ي ﻋﻤﻠﻜﺮد اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﻣﺸﺎﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻞ اﺳﺖ .ﻓﻘﻂ در ﻣﺘﺪ DoDivideدر اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﮔﺮ ﭘﺎراﻣﺘﺮ دوم ﺑﺮاﺑﺮ ﺑـﺎ ﺻـﻔﺮ ﺑﺎﺷﺪ ،اﺑﺘﺪا ﺷﻴﺊ اي از ﻧﻮع DivideByZeroExceptionاﻳﺠﺎد ﺷﺪه و ﺧﺎﺻﻴﺖ HelpLinkآن ﺑﺮاﺑـﺮ ﺑـﺎ آدرس ﺳﺎﻳﺘﻲ ﻗﺮار داده ﻣﻲ ﺷﻮد ﻛﻪ درﺑﺎره ي اﻳﻦ اﺳﺘﺜﻨﺎ اﻃﻼﻋﺎﺗﻲ دارد .ﺳﭙﺲ ﺷﻴﺊ اﻳﺠﺎد ﺷﺪه ﺑﺎ اﺳﺘﻔﺎده از دﺳـﺘﻮر throwﭘﺮﺗـﺎب ﻣـﻲ ﺷﻮد. در ﻣﺘﺪ Runﻫﻢ اﮔﺮ اﺳﺘﺜﻨﺎﻳﻲ از ﻧﻮع DivideByZeroExceptionرخ دﻫـﺪ ،ﭘﻴﻐـﺎم ﻣﺮﺑـﻮط ﺑـﻪ آن اﺳـﺘﺜﻨﺎ )ﻣﻘـﺪار ﺧﺎﺻﻴﺖ (Messageو آدرس ﺳﺎﻳﺖ ﺣﺎوي اﻃﻼﻋﺎت درﺑﺎره ي آن )ﻣﻘﺪار ﺧﺎﺻﻴﺖ (HelpLinkدر ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﻣـﻲ ﺷﻮد.
ﻧﺘﻴﺠﻪ: در اﻳﻦ ﻓﺼﻞ ﺑﺎ ﻣﻘﺪﻣﺎت ﻛﻨﺘﺮل ﺧﻄﺎ ﻫﺎ و اﺳﺘﺜﻨﺎ ﻫﺎ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ آﺷﻨﺎ ﺷﺪﻳﻢ .در اﺑﺘﺪاي ﻓﺼﻞ ﺑﻪ دﺳﺘﻪ ﺑﻨﺪي اﻧﻮاع ﺧﻄﺎ ﻫﺎ ﭘـﺮداﺧﺘﻴﻢ و ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛﻪ ﺳﻪ ﻧﻮع ﺧﻄﺎي ﻛﻠﻲ وﺟﻮد دارد ﻛﻪ روش ﻛﻨﺘﺮل ﻫﺮ ﻛﺪام از آﻧﻬﺎ ﻧﻴـﺰ ﻣﺘﻔـﺎوت اﺳـﺖ .اوﻟـﻴﻦ ﻧـﻮع ﺧﻄـﺎ ،ﺧﻄﺎﻫـﺎي دﺳﺘﻮري ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از اﺑﺰارﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ ﭘﻨﺠﺮه ي Error Listو ﻳـﺎ وﻳﺮاﻳـﺸﮕﺮ ﻛـﺪ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ ﺑـﻪ ﺳـﺎدﮔﻲ ﺗﺸﺨﻴﺺ داده ﺷﺪه و ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﺮﻧﺎﻣﻪ ﻛﺎﻣﭙﺎﻳﻞ و اﺟﺮا ﺷﻮد رﻓﻊ ﻣﻲ ﺷﻮﻧﺪ. ﻧﻮع دوم ﺧﻄﺎﻫﺎ ،ﺧﻄﺎﻫﺎي ﻣﻨﻄﻘﻲ ﻫﺴﺘﻨﺪ و ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﺳﺨﺖ ﺗﺮﻳﻦ ﻧﻮع ﺧﻄﺎﻫﺎ از ﻧﻈﺮ ﺗﺸﺨﻴﺺ و رﻓﻊ ﺑﻪ ﺷـﻤﺎر ﻣـﻲ روﻧـﺪ .در وﻳﮋوال اﺳﺘﻮدﻳﻮ .NETاﺑﺰارﻫﺎي زﻳﺎدي ﺑﺮاي ﺗﺸﺨﻴﺺ اﻳﻦ ﺧﻄﺎ ﻫﺎ وﺟﻮد دارد ﻛﻪ ﻫﺮ ﭼﻪ ﺑﻴﺸﺘﺮ ﺑﺎ اﻳﻦ اﺑﺰارﻫﺎ آﺷﻨﺎ ﺑﺎﺷـﻴﺪ ،ﺳـﺎده ﺗـﺮ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﻳﻦ ﻧﻮع ﺧﻄﺎﻫﺎ ﻣﻘﺎﺑﻠﻪ ﻛﻨﻴﺪ .در اﻳﻦ ﻓﺼﻞ ﺑﺎ ﻣﻬﻤﺘﺮﻳﻦ اﺑﺰار در اﻳﻦ زﻣﻴﻨﻪ ﻳﻌﻨﻲ Breakpointﻫﺎ آﺷـﻨﺎ ﺷـﺪﻳﻢ .اﻣـﺎ اﺑﺰارﻫﺎي ﺑﺴﻴﺎر دﻳﮕﺮي ﻧﻴﺰ وﺟﻮد دارﻧﺪ ﻛﻪ ﺑﻬﺘﺮ اﺳﺖ ﻧﺤﻮه ي ﻛﺎر ﺑﺎ آﻧﻬﺎ را ﻧﻴـﺰ ﻳـﺎد ﺑﮕﻴﺮﻳـﺪ ،ﻣﺎﻧﻨـﺪ ﭘﻨﺠـﺮه ي Watchﻛـﻪ ﺑـﺮاي ﻣﺸﺎﻫﺪه ي ﻣﻘﺪار ﻫﺮ ﺷﻴﺊ و ﻳﺎ ﻣﺘﻐﻴﻴﺮ در ﺑﺮﻧﺎﻣﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد ،ﭘﻨﺠﺮه ي Immediateﻛﻪ ﺑﺮاي اﺟﺮاي ﻳﻚ دﺳﺘﻮر ﺧﺎرج از دﺳﺘﻮرات ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ ،زﻣﺎﻧﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ در ﺣﺎﻟﺖ Breakاﺳﺖ ﺑﻪ ﻛﺎر ﻣﻲ رود و ... در اﻧﺘﻬﺎي ﻓﺼﻞ ﻧﻴﺰ روﺷﻬﺎي ﻣﺨﺘﻠﻒ ﺑﺮﺧﻮرد ﺑﺎ ﺧﻄﺎﻫﺎي زﻣﺎن اﺟﺮا را ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ و دﻳﺪﻳﻢ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ در اﻳﻦ ﺷﺮاﻳﻂ ﺑﺎ اﺳـﺘﻔﺎده از ﺑﻼك ،try/catchﻳﺎ ﺑﻪ ﻛﺎرﺑﺮ اﻃﻼع دﻫﻴﻢ ﻛﻪ ﺧﻄﺎﻳﻲ رخ داده اﺳﺖ و ﺳﭙﺲ از ﺑﺮﻧﺎﻣﻪ ﺧﺎرج ﺷﻮﻳﻢ ،ﻳﺎ ﺧﻄﺎ را رﻓـﻊ ﻛـﺮده و ﺑﺮﻧﺎﻣﻪ را اداﻣﻪ دﻫﻴﻢ .ﻫﻤﭽﻨﻴﻦ ﺑﺎ ﻧﺤﻮه ي ﺗﻮﻟﻴﺪ ﺧﻄﺎﻫﺎي زﻣﺎن اﺟﺮا در ﻣﻮاﻗﻊ ﻣﻮرد ﻧﻴﺎز ﻧﻴﺰ آﺷﻨﺎ ﺷﺪﻳﻢ. در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ:
٤٧١
اﻧﻮاع ﻣﺨﺘﻠﻒ ﺧﻄﺎﻫﺎﻳﻲ ﻛﻪ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﻤﻜﻦ اﺳﺖ ﺑﻪ وﺟﻮد آﻳﺪ را ﻧﺎم ﺑﺮده و ﺗﻮﺿﻴﺢ دﻫﻴﺪ. ﺑﺘﻮاﻧﻴﺪ از اﺑﺰارﻫﺎي ﻣﻮﺟﻮد در وﻳﮋوال اﺳﺘﻮدﻳﻮ اﺳﺘﻔﺎده ﻛﺮده و ﺧﻄﺎﻫﺎي دﺳﺘﻮري اﻳﺠﺎد ﺷﺪه را ﺑﺮ ﻃﺮف ﻛﻨﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از اﺑﺰارﻫﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﻛﻨﺘﺮل ﻛﺮده و ﺧﻄﺎﻫﺎي ﻣﻨﻄﻘﻲ ﻣﻮﺟﻮد در آن را رﻓﻊ ﻛﻨﻴﺪ. ﺑﺘﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ﺑﻼك try/catchدر ﺑﺮﻧﺎﻣﻪ ،ﺧﻄﺎﻫﺎي زﻣﺎن اﺟﺮا را ﻛﻨﺘﺮل ﻛﻨﻴﺪ. در ﻣﻮاﻗﻊ ﻣﻮرد ﻧﻴﺎز ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر throwرخ دادن ﺧﻄﺎﻳﻲ را در ﺑﺮﻧﺎﻣﻪ اﻋﻼم ﻛﻨﻴﺪ.
٤٧٢
ﻓﺼﻞ دوازدﻫﻢ :اﻳﺠﺎد ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس در اﻳﻦ ﻓﺼﻞ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﻪ ﻃﺮاﺣﻲ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس ﺑﭙﺮدازﻳﻢ ،ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎﻳﻲ ﻛﻪ ﺣﺎوي ﭼﻨﺪﻳﻦ ﻛﻼس ﺑﺎﺷﻨﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر از ﺗﻤﺎم ﻣﻄﺎﻟﺒﻲ ﻛﻪ ﺗﺎﻛﻨﻮن در اﻳﻦ ﻛﺘﺎب آﻣﻮﺧﺘﻪ اﻳﺪ اﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد ،ﭘﺲ ﺑﻬﺘﺮ اﺳﺖ ﻗﺒﻞ از ﺷﺮوع ﻓﺼﻞ ﻣﺮوري ﺑﺮ اﻳﻦ ﻣﻄﺎﻟﺐ داﺷﺘﻪ ﺑﺎﺷﻴﻢ .ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺗﺎﻛﻨﻮن ﻃﺮاﺣﻲ ﻛﺮده اﻳﻢ ﺑﻪ اﻳﻦ ﺻﻮرت ﺑﻮده اﻧﺪ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﺗﻌﺪادي ﻛﻨﺘﺮل ﺑﺮ روي ﻓﺮم ﻗﺮار ﻣﻲ دادﻳﻢ ،ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي Propertiesﺧﺎﺻﻴﺘﻬﺎي اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ را ﺗﻨﻈﻴﻢ ﻛﺮده و در اﻧﺘﻬﺎ ﻧﻴﺰ ﻛﺪ ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﻋﻤﻠﻜﺮد آﻧﻬﺎ را ﻣﻲ ﻧﻮﺷﺘﻴﻢ .ﺗﻤﺎم اﻳﻦ ﻣﻮارد درون ﻳﻚ ﻓﺮم در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻧﺠﺎم ﻣﻲ ﺷﺪ .اوﻟﻴﻦ ﻧﻜﺘﻪ ي ﻗﺎﺑﻞ ﺗﻮﺟﻪ در اﻳﻦ ﻗﺴﻤﺖ اﻳﻦ اﺳﺖ ﻛﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﺮﻣﻲ را ﺑﺎ اﺳﺘﻔﺎده از ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻃﺮاﺣﻲ ﻣﻲ ﻛﺮدﻳﻢ )ﺑﺮاي ﻣﺜﻞ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮرد ﻧﻴﺎز را در آن ﻗﺮار ﻣﻲ دادﻳﻢ( ،در ﺣﻘﻴﻘﺖ در ﺣﺎل اﻳﺠﺎد ﻛﻼس ﺟﺪﻳﺪي ﺑﻮدﻳﻢ ﻛﻪ اﻳﻦ ﻛﻼس از ﻛﻼس System.Windows.Forms.Formﻣﺸﺘﻖ ﺷﺪه ﺑﻮد. وﻗﺘﻲ در ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﻓﺮم ﺗﻐﻴﻴﺮي در ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻣﻲ ﻛﺮدﻳﺪ ،وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻛﺪ ﻻزم ﺑﺮاي آن ﺗﻐﻴﻴﺮ را ﺗﺸﺨﻴﺺ ﻣﻲ داده و آن را ﺑﻪ اﻳﻦ ﻛﻼس ﺟﺪﻳﺪ اﺿﺎﻓﻪ ﻣﻲ ﻛﺮد .ﺑﺮاي ﻣﺸﺎﻫﺪه ي ﻛﺪ ﻫﺎﻳﻲ ﻛﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮاي اﻳﺠﺎد ﻛﻼس ﻣﻮرد ﻧﻴﺎز ﺷﻤﺎ ﻣﻲ ﻧﻮﻳﺴﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ در ﭘﻨﺠﺮه ي Solution Explorerروي ﻋﻼﻣﺖ ﻣﺜﺒﺖ ﻛﻨﺎر ﻓﺎﻳﻞ ﻣﺮﺑﻮط ﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ،ﺑﺮاي ﻣﺜﺎل ﻓﺎﻳﻞ ،Form1.csﺳﭙﺲ ﻓﺎﻳﻞ Form1.Designer.csرا ﺑﺎز ﻛﻨﻴﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ را اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ ،ﻳﻚ ﺷﻴﺊ ﺟﺪﻳﺪ از اﻳﻦ ﻛﻼس ﻧﻤﻮﻧﻪ ﺳﺎزي ﻣﻲ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻤﺎم ﻣﻮاردي ﻛﻪ در ﻓﺼﻞ ﻧﻬﻢ و دﻫﻢ در ﻣﻮرد اﺷﻴﺎ ﮔﻔﺘﻴﻢ ،در ﻣﻮرد ﻓﺮم ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ ﻧﻴﺰ ﺻﺎدق اﺳﺖ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﺎﻧﻨﺪ ﻫﺮ ﺷﻴﺊ دﻳﮕﺮي ،ﻓﺮم ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ ﻣﻲ ﺗﻮاﻧﺪ داراي ﺣﺎﻟﺖ و ﻳﺎ رﻓﺘﺎر ﺑﺎﺷﺪ .ﺷﻤﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد ﻣﺘﻐﻴﻴﺮ ﻫﺎ و ﻳﺎ ﻛﻨﺘﺮل ﻫﺎﻳﻲ را اﻳﺠﺎد ﻛﻨﻴﺪ )ﺣﺎﻟﺖ ﺷﻴﺊ( و ﻳﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻋﻤﻞ ﺧﺎﺻﻲ را ،ﺑﺮاي ﻣﺜﺎل ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي ﻳﻚ ﻛﻨﺘﺮل ﻛﻠﻴﻚ ﻣﻲ ﻛﻨﺪ در ﻓﺮم اﻧﺠﺎم دﻫﻴﺪ )رﻓﺘﺎر ﺷﻴﺊ( .ﺑﻪ ﺻﻮرت ﺗﺌﻮري ﺑﺮاي ﻧﻮﺷﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻳﻚ وﻳﺮاﻳﺸﮕﺮ ﻣﺘﻨﻲ ﺳﺎده ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻟﺒﺘﻪ در اﻳﻦ ﺣﺎﻟﺖ ﺑﺎﻳﺪ ﺗﻤﺎم ﻛﺪ ﻫﺎﻳﻲ ﻛﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮاي ﺗﻜﻤﻴﻞ ﻛﻼس ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﻣﻲ ﻧﻮﻳﺴﺪ ،ﺗﻮﺳﻂ ﺧﻮد ﺷﻤﺎ ﻧﻮﺷﺘﻪ ﺷﻮد .اﻳﻦ ﻣﻮرد در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺑﺰرگ و ﺣﺘﻲ ﻣﺘﻮﺳﻂ ﺑﻪ اﻣﺮي ﻏﻴﺮ ﻋﻤﻠﻲ ﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮد، ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﺑﺮاي ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي از ﻳﻚ ﻣﺤﻴﻂ ﻃﺮاﺣﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ. ﭘﺲ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ ﻛﻪ از اﺑﺘﺪاي اﻳﻦ ﻛﺘﺎب ﺗﺎﻛﻨﻮن در ﺣﺎل ﻃﺮاﺣﻲ ﻛﻼﺳﻬﺎ ﺑﻮده اﻳﺪ ،در ﻓﺼﻞ ﻧﻬﻢ ﻧﻴﺰ ﺑﺎ ﻧﺤﻮه اﻳﺠﺎد ﻛﻼﺳﻬﺎ از ﭘﺎﻳﻪ آﺷﻨﺎ ﺷﺪﻳﺪ .ﺑﺮﻧﺎﻣﻪ ي Objectsرا در اﻳﻦ ﻓﺼﻞ ﺑﻪ ﺧﺎﻃﺮ ﺑﻴﺎورﻳﺪ ،اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺷﺎﻣﻞ دو ﻛﻼس ﺑﻪ ﻧﺎﻣﻬﺎي Carو SportsCarﺑﻮد .در آن ﻓﺼﻞ اﻳﻦ ﻛﻼﺳﻬﺎ را در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ ﻛﻨﺴﻮل اﻳﺠﺎد ﻛﺮدﻳﻢ زﻳﺮا ﺗﺴﺖ ﻛﺮدن ﻧﺤﻮه ي ﻋﻤﻠﻜﺮد ﻛﻼﺳﻬﺎ در اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺳﺎده ﺗﺮ ﺑﻮد .اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ اﻳﻦ ﻛﻼﺳﻬﺎ ﺑﺪون ﻫﻴﭻ ﺗﻐﻴﻴﺮي ﻣﻲ ﺗﻮاﻧﺴﺘﻨﺪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز و ﻳﺎ ﺣﺘﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب و وب ﺳﺮوﻳﺲ ﻫﺎ ﻧﻴﺰ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮﻧﺪ .در ﺣﻘﻴﻘﺖ ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﻣﺰاﻳﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻪ ﺻﻮرت ﺷﻴﺊ ﮔﺮا اﻳﻦ اﺳﺖ ﻛﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻛﻼس ﻣﻨﺎﺳﺐ را ﻃﺮاﺣﻲ ﻣﻲ ﻛﻨﻴﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ از آن در ﺗﻤﺎم ﻗﺴﻤﺘﻬﺎي ﻣﻮرد ﻧﻴﺎز در ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕﺮ ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. در اﻳﻦ ﻓﺼﻞ:
ﺑﺎ ﭼﮕﻮﻧﮕﻲ اﻳﺠﺎد ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ و ﺧﻮاﻫﻴﺪ دﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان در ﻣﻮرد ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼﺳﻲ ﻛﻪ ﻋﻀﻮ ﭼﺎرﭼﻮب .NETﻧﻴﺴﺘﻨﺪ اﻃﻼﻋﺎﺗﻲ را ﺑﺪﺳﺖ آورد. ﺑﺎ ﭼﮕﻮﻧﮕﻲ ﻧﺎﻣﮕﺬاري ﻗﻮي در اﺳﻤﺒﻠﻲ ﻫﺎ )ﻓﺎﻳﻠﻬﺎي ﻛﺎﻣﭙﺎﻳﻞ ﺷﺪه( آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ ﺗﺎ ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ ﺑﺘﻮاﻧﻴﺪ از ﻣﻨﺤﺼﺮ ﺑﻪ ﻓﺮد ﺑﻮدن اﺳﻤﺒﻠﻲ ﻫﺎ ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ. ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻳﻚ اﺳﻤﺒﻠﻲ را در ﻣﻜﺎﻧﻲ ﻋﻤﻮﻣﻲ ﺑﻪ ﻧﺎم Global Assembly Cacheﻳﺎ GACﻗﺮار داد ﺗﺎ ﺑﻪ وﺳﻴﻠﻪ ي ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻫﺎي در ﺣﺎل اﺟﺮا در آن ﻛﺎﻣﭙﻴﻮﺗﺮ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﺑﺎﺷﻨﺪ.
٤٧٣
ﻣﻔﻬﻮم ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس: ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻓﺼﻞ دﻫﻢ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﺑﻪ ﻟﻴﺴﺘﻲ از ﮔﺰﻳﻨﻪ ﻫﺎي Favoritesدﺳﺘﺮﺳـﻲ داﺷـﺘﻪ ﺑﺎﺷـﻴﻢ و ﺑﺘﻮاﻧﻴﻢ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﻢ دو ﻛﻼس ﻣﺨﺘﻠﻒ را ﻃﺮاﺣﻲ ﻛﺮدﻳﻢ .ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﻼﺳﻬﺎ دو ﺑﺮﻧﺎﻣﻪ ي ﻣﺨﺘﻠﻒ اﻳﺠـﺎد ﻛـﺮده ﺗـﺎ ﮔﺰﻳﻨﻪ ﻫﺎي Favoritesرا ﻧﻤﺎﻳﺶ دﻫﻨﺪ ،ﻳﻜﻲ از آﻧﻬﺎ ﮔﺰﻳﻨﻪ ﻫﺎي ﻣﻮﺟﻮد را ﺑﻪ ﺻﻮرت ﻋـﺎدي در ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ ي وﻳﻨـﺪوزي و دﻳﮕﺮي ﺑﻪ وﺳﻴﻠﻪ ي ﻳﻚ ﻣﻨﻮ در ﻛﻨﺎر ﺳﺎﻋﺖ ﺳﻴﺴﺘﻢ ﻧﻤﺎﻳﺶ ﻣﻲ داد .در آﻧﺠﺎ ﺑﺮاي اﻳﻦ ﻛﻪ ﺑﺘﻮاﻧﻴﻢ از ﻛﻼﺳﻬﺎي ﻃﺮاﺣﻲ ﺷﺪه در ﻫـﺮ دو ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﻢ ،ﻓﺎﻳﻞ ﺳﻮرس آﻧﻬﺎ را از ﺑﺮﻧﺎﻣﻪ ي اول در ﺑﺮﻧﺎﻣﻪ ي دوم ﻛﭙﻲ ﻛـﺮدﻳﻢ .اﻳـﻦ روش ،روش ﺳـﺮﻳﻊ و ﺳـﺎده اي ﺑـﺮاي اﺳﺘﻔﺎده ي ﻣﺠﺪد از ﻳﻚ ﻛﺪ اﺳﺖ اﻣﺎ ﻣﺸﻜﻼﺗﻲ ﻧﻴﺰ دارد:
ﺑﺮاي اﺳﺘﻔﺎده از اﻳﻦ روش ﺑﺎﻳﺪ ﺑﻪ ﺳﻮرس ﻛﻼﺳﻬﺎي ﻧﻮﺷﺘﻪ ﺷﺪه دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ .اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﻳﻜﻲ از ﻣﺰﻳﺖ ﻫﺎي اﺳﺘﻔﺎده از ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا در اﻳﻦ اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻛﻼﺳﻬﺎي ﻃﺮاﺣﻲ ﺷـﺪه را ﺑـﻪ ﺻـﻮرت ﻳـﻚ "ﺟﻌﺒـﻪ ي ﺳﻴﺎه" در اﺧﺘﻴﺎر ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن دﻳﮕﺮ ﻗﺮار دﻫﻴﺪ .ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن دﻳﮕﺮ ،ﺑﺮاي اﺳﺘﻔﺎده از ﻛﻼس ﺷﻤﺎ ﻧﻴﺎزي ﻧﺪارﻧﺪ ﻛﻪ ﺑﺪاﻧﻨﺪ آن ﻛﻼس ﺑﻪ ﺻﻮرت دروﻧﻲ ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ .ﻫﻤﭽﻨﻴﻦ ﻣﻤﻜﻦ اﺳﺖ اﮔﺮ ﻛﻼﺳﻲ را ﻃﺮاﺣﻲ ﻛﻨﻴﺪ ﺑﺨﻮاﻫﻴﺪ ﻛﺪ آن ﻛﻼس ﺑـﻪ ﺻﻮرت ﺳﺮي ﺑﺎﻗﻲ ﺑﻤﺎﻧﺪ .ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ ﻛﻼس ﺧﻮد را ﺑﺮاي اﺳﺘﻔﺎده در اﺧﺘﻴﺎر ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن دﻳﮕﺮ ﻗـﺮار دﻫﻴـﺪ ،اﻣـﺎ اﺟﺎزه ﻧﺪﻫﻴﺪ ﻛﻪ آن را ﺗﻐﻴﻴﺮ دﻫﻨﺪ و ﻳﺎ ادﻋﺎ ﻛﻨﻨﺪ ﻛﻪ آن ﻛﻼس ﺑﻪ وﺳﻴﻠﻪ آﻧﻬﺎ ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ. ﻫﺮ ﺑﺎر ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺑﺮﻧﺎﻣﻪ را ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﻴﺪ ،ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ اﻳﻦ ﺻﻮرت ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﺪه اﻧﺪ ﻧﻴﺰ ﺑﺎﻳﺪ ﻛﺎﻣﭙﺎﻳﻞ ﺷـﻮﻧﺪ. ﻣﻤﻜﻦ اﺳﺖ اﻳﻦ ﻣﻮرد در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﻮﭼﻚ ﻛﻪ ﻓﻘﻂ از ﭼﻨﺪ ﻛﻼس ﺳﺎده اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ زﻳـﺎد ﭼـﺸﻤﮕﻴﺮ ﻧﺒﺎﺷـﺪ ،اﻣـﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺑﺰرگ ﻛﻪ ﻛﻼﺳﻬﺎي زﻳﺎدي را ﺑﻪ ﻛﺎر ﻣﻲ ﺑﺮﻧﺪ ،اﻳﻦ ﻣﻮرد ﻣﻮﺟﺐ ﻛﻨﺪ ﺷﺪن ﺳﺮﻋﺖ ﻛﺎﻣﭙﺎﻳﻞ ﻣﻲ ﺷـﻮد .ﻫﻤﭽﻨـﻴﻦ ﺑﻪ اﻳﻦ ﺻﻮرت ﺣﺠﻢ ﺑﺮﻧﺎﻣﻪ ي ﺗﻮﻟﻴﺪ ﺷﺪه ﻧﻴﺰ ﺑﺴﻴﺎر زﻳﺎد ﺧﻮاﻫﺪ ﺑﻮد ،زﻳﺮا ﻓﺎﻳﻞ اﺟﺮاﻳﻲ ﻛﻪ در ﻣﺮﺣﻠﻪ ي ﻛﺎﻣﭙﺎﻳـﻞ ﺗﻮﻟﻴـﺪ ﻣـﻲ ﺷﻮد ﺷﺎﻣﻞ ﺗﻤﺎﻣﻲ اﻳﻦ ﻛﺪﻫﺎ ﺧﻮاﻫﺪ ﺑﻮد. اﮔﺮ در اﻳﻦ ﻛﻼس ﺧﻄﺎﻳﻲ را ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ و ﺧﻮاﺳﺘﻴﺪ آن را ﺗﺼﺤﻴﺢ ﻛﻨﻴﺪ و ﻳﺎ ﺗـﺼﻤﻴﻢ ﮔﺮﻓﺘﻴـﺪ ﻗـﺴﻤﺘﻲ از ﺑﺮﻧﺎﻣـﻪ را ﺑـﻪ ﻧﺤﻮي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ ﻋﻤﻠﻜﺮد ﺑﺮﻧﺎﻣﻪ ﺑﻬﺘﺮ و ﻛﺎرآﻣﺪﺗﺮ ﺷﻮد ،ﺑﺎﻳﺪ اﻳﻦ ﺗﻐﻴﺮات را در ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ از اﻳﻦ ﻛﻼس اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ اﻋﻤﺎل ﻛﻨﻴﺪ.
راه ﺣﻠﻲ ﻛﻪ ﺑﺮاي رﻓﻊ اﻳﻦ ﻣﺸﻜﻼت در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺗﻮان ﺑﻪ ﻛﺎر ﺑﺮد اﺳﺘﻔﺎده از ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛـﻼس اﺳـﺖ .ﻳـﻚ ﻛﺘﺎﺑﺨﺎﻧـﻪ ي ﻛﻼس ،1ﺷﺎﻣﻞ ﻣﺠﻤﻮﻋﻪ اي از ﻛﻼس ﻫﺎ اﺳﺖ ﻛﻪ ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ درون ﻳﻚ ﻓﺎﻳﻞ ﻣﺠﺰا ﺑﺎ ﭘﺴﻮﻧﺪ .DLL2ﻗـﺮار ﻣـﻲ ﮔﻴﺮﻧـﺪ .اﻳـﻦ ﻓﺎﻳﻠﻬﺎ ﺑﻪ ﺗﻨﻬﺎﻳﻲ ﻗﺎﺑﻞ اﺟﺮا ﻧﻴﺴﺘﻨﺪ ،ﺑﻠﻜﻪ ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻨﺪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕﺮ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮﻧﺪ .ﺑﺎ اﺳـﺘﻔﺎده از ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺪون دﺳﺘﺮﺳﻲ ﺑﻪ ﻛﺪ ،از آﻧﻬﺎ در ﭼﻨﺪ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﻫﻤﭽﻨﻴﻦ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫـﺎ ﻫـﺮ ﺑﺎر ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻛﺎﻣﭙﺎﻳﻞ ﻣﻲ ﺷﻮد ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻓﺎﻳﻠﻬﺎ ﻧﻴﺰ ﻛﺎﻣﭙﺎﻳﻞ ﺷﻮﻧﺪ .اﮔﺮ ﻫﻢ ﻳﻜﻲ از ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎ ﺗﻐﻴﻴﺮ ﻛﻨﺪ ،ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ از ﻛﺪ ﺗﻐﻴﻴﺮ داده ﺷﺪه اﺳﺘﻔﺎده ﺧﻮاﻫﻨﺪ ﻛﺮد.
اﻳﺠﺎد ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس: ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ،ﺣﺎوي دﺳﺘﻮراﻟﻌﻤﻞ ﻫﺎﻳﻲ ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس در وﻳﮋوال اﺳـﺘﻮدﻳﻮ 2005 .NETﻧـﺴﺨﻪ ي Standardو ﻳﺎ ﻧﺴﺨﻪ ﻫﺎي ﺑﺎﻻﺗﺮ اﺳﺖ. Class Library Dynamic Link Library
1 2
٤٧٤
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس (1ﺑﺎ اﺳﺘﻔﺎده از ﻧﻮاي ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ ،ﮔﺰﻳﻨﻪ ي … File New Projectرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. (2از ﻟﻴـﺴﺖ Project Typeﮔﺰﻳﻨـﻪ ي Visual C#و ﺳـﭙﺲ از ﻗـﺴﻤﺖ Templatesآﻳﻜـﻮن Classرا اﻧﺘﺨـــــﺎب ﻛﻨﻴـــــﺪ )ﺷـــــﻜﻞ .(1-12در ﻛـــــﺎدر Nameﻧﻴـــــﺰ ﻧـــــﺎم Library InternetFavoritesرا وارد ﻛﺮده و روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ.
ﺷﻜﻞ 12-1 (3ﻳﻚ ﭘﺮوژه ي ﺟﺪﻳﺪ از ﻧﻮع Class Libraryاﻳﺠﺎد ﺷﺪه و ﻳﻚ ﻛـﻼس ﻧﻴـﺰ ﺑـﻪ ﺻـﻮرت ﭘـﻴﺶ ﻓـﺮض ﺑـﻪ ﻧـﺎم Class1.csﺑــﻪ اﻳــﻦ ﭘــﺮوژه اﺿــﺎﻓﻪ ﻣــﻲ ﺷــﻮد .در ﭘﻨﺠــﺮه ي Solution Explorerروي ﻧــﺎم Class1.csﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ ي Deleteرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ اﻳﺠﺎد اﻳﻦ ﻧﻮع ﭘﺮوژه ﺑﺴﻴﺎر راﺣﺖ ﺑﻮد .اﻣﺎ اﺟﺎزه دﻫﻴﺪ ﻛﺎرﻫﺎﻳﻲ ﻛﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ در اﻳﻦ ﭼﻨﺪ ﻣﺮﺣﻠﻪ اﻧﺠﺎم ﻣﻲ دﻫﺪ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ .در اﺑﺘﺪا ﺗﻌﻴﻴﻦ ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻗﺎﻟﺐ ﭘﺮوژه اي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ اﻳﺠـﺎد ﻛﻨﻴـﺪ از ﻧـﻮع Class Library ٤٧٥
اﺳﺖ .ﻗﺎﻟﺐ ﻳﻚ ﭘﺮوژه ﺗﻌﻴﻴﻦ ﻣﻲ ﻛﻨﺪ ﻛﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﭼﮕﻮﻧﻪ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﺑﺮﻧﺎﻣﻪ را ﺗﻨﻈﻴﻢ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑـﺎ ﺗﻐﻴﻴـﺮ دادن ﻗﺎﻟـﺐ اﻳﻦ ﭘﺮوژه ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺒﻠﻲ ﺗﻔﺎوﺗﻬﺎي زﻳﺎدي دارد .اوﻟﻴﻦ ﺗﻔﺎوت در اﻳﻦ اﺳﺖ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫـﺎي وﻳﻨﺪوزي ﻗﺒﻠﻲ ،اﺑﺘﺪا ﻳﻚ ﻓﺮم وﻳﻨﺪوزي ﺧﺎﻟﻲ ﺑﻪ ﻧﺎم Form1.csدر ﻣﺤﻴﻂ ﻃﺮاﺣﻲ ﻓـﺮم در اﺧﺘﻴـﺎر ﺷـﻤﺎ ﻗـﺮار ﻣـﻲ ﮔﺮﻓـﺖ .اﻣـﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﭘﺮوژه اي از ﻧﻮع Class Libraryاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ ،ﻫﻴﭻ ﻓﺮﻣﻲ در اﺧﺘﻴﺎر ﺷﻤﺎ ﻗﺮار داده ﻧﻤﻲ ﺷﻮد ،ﺑﻠﻜـﻪ ﻳـﻚ ﻛﻼس ﺧﺎﻟﻲ ﺑﻪ ﻧﺎم Class1.csﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد. ﺗﻔﺎوت اﺳﺎﺳﻲ دﻳﮕﺮي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ وﺟﻮد دارد اﻳﻦ اﺳﺖ ﻛﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ ،وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻣﻲ داﻧﺪ ﻛﻪ ﺑﺎﻳﺪ ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ ﺑﺮﻧﺎﻣﻪ ﻳﻚ ﻓﺎﻳﻞ ﻗﺎﺑﻞ اﺟﺮا ﺗﻮﻟﻴﺪ ﻛﻨﺪ .اﻣﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﭘـﺮوژه اي از ﻧـﻮع Class Library اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ ،وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ ﻓﺎﻳﻠﻲ را اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ ﻛﻪ ﺑﻪ ﺗﻨﻬﺎﻳﻲ ﻗﺎﺑﻞ اﺟﺮا ﻧﺨﻮاﻫﺪ ﺑﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﻧﻮع ﭘﺮوژه اي ﻛـﻪ اﻧﺘﺨﺎب ﻣﻲ ﻛﻨﻴﺪ در ﻧﻮع ﻓﺎﻳﻠﻲ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺗﻮﻟﻴﺪ ﻣﻲ ﺷﻮد ﺗﺎﺛﻴﺮ ﺧﻮاﻫﺪ ﮔﺬاﺷﺖ .اﮔﺮ ﭘﺮوژه اي را از ﻧﻮع Class Libraryاﻳﺠﺎد ﻛﻨﻴﺪ ،وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻓﺎﻳﻠﻲ ﺑﺎ ﭘﺴﻮﻧﺪ dllو در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻓﺎﻳﻠﻲ ﺑﺎ ﭘـﺴﻮﻧﺪ exeﺑـﻪ ﻋﻨـﻮان ﺧﺮوﺟـﻲ ﺑﺮﻧﺎﻣﻪ ﺗﻮﻟﻴﺪ ﺧﻮاﻫﺪ ﻛﺮد. ﺑﻌﺪ از اﻳﻨﻜﻪ ﭘﺮوژه ي ﻣﻮرد ﻧﻈﺮ را اﻳﺠﺎد ﻛﺮدﻳﻢ ،ﻓﺎﻳﻠﻲ ﻛﻪ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض ﺗﻮﺳﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﻪ وﺟﻮد آﻣـﺪه اﺳـﺖ را ﺣـﺬف ﻣﻲ ﻛﻨﻴﻢ .داﺷﺘﻦ ﻳﻚ ﻛﻼس ﺑﺎ ﻧﺎم Class1در ﺑﺮﻧﺎﻣﻪ ﻛﺎرﺑﺮدي ﻧﺪارد ،ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻬﺘﺮ اﺳﺖ از اﺑﺘﺪا ﻓﺎﻳﻠﻬﺎ و ﻛﻼس ﻫﺎﻳﻲ ﺑﺎ ﻧﺎﻣﻬـﺎي ﻣﻌﻨﻲ دار در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﻨﻴﻢ. در ﻓﺼﻞ دﻫﻢ ﻛﻼس ﻫﺎﻳﻲ را ﻃﺮاﺣﻲ ﻛﺮده و ﺳﭙﺲ از آﻧﻬﺎ در دو ﺑﺮﻧﺎﻣﻪ ي ﮔﻮﻧﺎﮔﻮن اﺳﺘﻔﺎده ﻛﺮدﻳﻢ :ﺑﺮﻧﺎﻣـﻪ ي Favorites Viewerو ﺑﺮﻧﺎﻣﻪ ي .Favorites Trayدر اﻳﻦ ﺑﺨﺶ ﻣﻲ ﺧﻮاﻫﻴﻢ اﻳﻦ ﻛﻼﺳﻬﺎ را از اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺟﺪا ﻛـﺮده و ﺑﺮﻧﺎﻣـﻪ ﻫﺎ را ﻧﻴﺰ ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﺗﺎ ﻫﺮ دوي آﻧﻬﺎ از ﻳﻚ ﻧﺴﺨﻪ ي ﻛﺎﻣﭙﺎﻳﻞ ﺷﺪه از اﻳﻦ ﻛﻼﺳﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻨﺪ .اﻟﺒﺘﻪ ﻣﻴﺪاﻧﻴﺪ ﻛﻪ اﻳﻦ ﺣﺎﻟﺖ ﻳﻚ ﺣﺎﻟﺖ ﻏﻴﺮ واﻗﻌﻲ اﺳﺖ ،زﻳﺮا در ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻋﻤﻮﻣﺎً اﺑﺘﺪا ﻛﻼﺳﻬﺎ را در ﻳﻚ ﭘﺮوژه ﻃﺮاﺣﻲ ﻣﻲ ﻛﻨﻨﺪ و ﺳﭙﺲ ﺑﻪ ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ي اﺻﻠﻲ ﻣﻲ ﭘﺮدازﻧﺪ ،ﻧﻪ اﻳﻨﻜﻪ ﻣﺎﻧﻨﺪ اﻳﻨﺠﺎ اﺑﺘﺪا ﺑﺮﻧﺎﻣﻪ ي اﺻﻠﻲ را ﻃﺮاﺣﻲ ﻛﻨﻨﺪ ﺳﭙﺲ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ آن را ﺗﻔﻜﻴﻚ ﻛﺮده و در ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس ﻗﺮار دﻫﻨﺪ .ﻫﺪف ﻣﺎ از اﻳﻦ ﺑﺨﺶ ﻓﻘﻂ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺎ ﭼﮕﻮﻧﮕﻲ اﻳﺠﺎد ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس و ﻧﺤﻮه ي اﺳﺘﻔﺎده از آن در ﭼﻨﺪ ﭘﺮوژه از ﭘﺎﻳﻪ آﺷﻨﺎ ﺷﻮﻳﺪ .ﺑﺮاي ﺷﺮوع در ﻳﻚ ﭘﻨﺠﺮه ي وﻳﮋوال اﺳﺘﻮدﻳﻮ ي ﺟﺪﻳﺪ ﭘـﺮوژه ي Favorites Viewerرا ﺑـﺎز ﻛﻨﻴﺪ .ﺑﻪ ﺧﺎﻃﺮ دارﻳﺪ ﻛﻪ اﻳﻦ ﭘﺮوژه ﺷﺎﻣﻞ ﻓﺎﻳﻠﻬﺎي زﻳﺮ ﺑﻮده اﺳﺖ.
Favorites.csﻛﻪ ﺣﺎوي ﻛﻼس Favoritesﺑﻮد. WebFavorite.csﻛﻪ ﺣﺎوي ﻛﻼس WebFavoriteﺑﻮد. Form1.csﻛﻪ ﺣﺎوي ﻛﻼس Form1ﺑﻮد .اﻳﻦ ﻛﻼس ﻓﺮم اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ را ﺗﺸﻜﻴﻞ ﻣﻲ داد.
از اﻳﻦ ﻟﻴﺴﺖ ،دو ﻓﺎﻳﻞ اول را در ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﻣﺠﺰا ﻗﺮار ﻣﻲ دﻫﻴﻢ .ﻓﺎﻳﻞ ﺳﻮم ﻓﻘﻂ ﺑﻪ اﻳﻦ ﭘﺮوژه ﻣﺮﺑﻮط اﺳﺖ و ﺑﻪ آن ﻧﻴﺎزي ﻧﺪارﻳﻢ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺣﺎوي ﻛﻼﺳـﻬﺎي Favoritesو WebFavoriteاﻳﺠـﺎد ﻛﻨﻴﻢ.
اﻳﺠﺎد ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺑﺮاي :Favorites Viewer در ﻓﺼﻞ دوم ﺑﺎ ﻣﻔﻬﻮم راه ﺣﻞ ﻫﺎ و دﻟﻴﻞ اﺳﺘﻔﺎده از آﻧﻬﺎ آﺷﻨﺎ ﺷﺪﻳﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﺑﻪ ﺧﺎﻃﺮ دارﻳﺪ در آن ﻓﺼﻞ ذﻛﺮ ﺷﺪ ﻛﻪ ﻳﻚ راه ﺣـﻞ ﻣﻲ ﺗﻮاﻧﺪ ﺷﺎﻣﻞ ﺑﻴﺶ از ﻳﻚ ﭘﺮوژه ﺑﺎﺷﺪ .در راه ﺣﻞ ﺑﺮﻧﺎﻣﻪ ي Favorites Viewerﻓﻘﻂ ﻳﻚ ﭘﺮوژه وﺟﻮد دارد و آن ﻫﻢ ﭘﺮوژه ي Favorites Viewerاﺳﺖ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﭘﺮوژه ي دﻳﮕﺮي از ﻧﻮع Class Library را ﺑﻪ اﻳﻦ راه ﺣﻞ اﺿﺎﻓﻪ ﻛﺮده و ﺳﭙﺲ ﻛﻼﺳﻬﺎي ﺑﺮﻧﺎﻣﻪ را ﺑﻪ اﻳﻦ ﭘﺮوژه ﻣﻨﺘﻘﻞ ﻣﻲ ﻛﻨﻴﻢ.
٤٧٦
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﭘﺮوژه ي Class Libraryﺑﻪ راه ﺣﻞ (1 (2 (3 (4
(5
ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي InternetFavoritesﺑﺮوﻳﺪ و ﺑﻌﺪ از ذﺧﻴﺮه ي آن ،وﻳﮋوال اﺳﺘﻮدﻳﻮ را ﺑﺒﻨﺪﻳﺪ. ﭘﺮوژه ي Favorites Viewerرا در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺎز ﻛﻨﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﻧﻮار ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﮔﺰﻳﻨﻪ ي … File Add Existing Projectرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. در ﭘﻨﺠﺮه ي ﺑﺎز ﺷﺪه ﺑﻪ ﻓﻮﻟﺪري ﺑﺮوي ﻛـﻪ ﺑﺮﻧﺎﻣـﻪ ي InternetFavoritesرا در آن اﻳﺠـﺎد ﻛـﺮده اﻳـﺪ و ﺳﭙﺲ در آﻧﺠﺎ ﻓﺎﻳﻞ InternetFavorites.csprojرا اﻧﺘﺨﺎب ﻛـﺮده و روي دﻛﻤـﻪ ي OKﻛﻠﻴـﻚ ﻛﻨﻴﺪ. در ﭘﻨﺠﺮه ي Solution Explorerروي ﻧﺎم ﭘـﺮوژه ي Favorites Viewerﻛﻠﻴـﻚ راﺳـﺖ ﻛﺮده و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ ي Set As Startup Projectرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺎ اﻧﺠﺎم اﻳﻦ ﻛﺎرﻫﺎ در راه ﺣﻞ ﺧﻮد دو ﭘﺮوژه ﺧﻮاﻫﻴﺪ داﺷﺖ :ﻳﻚ ﭘﺮوژه ي وﻳﻨـﺪوزي و ﻳـﻚ ﻛﺘﺎﺑﺨﺎﻧـﻪ ي ﻛـﻼس .اﻟﺒﺘـﻪ ﻓﻌـﻼً ﭘـﺮوژه ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺧﺎﻟﻲ اﺳﺖ و ﺗﻤﺎم ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ ﺑﺎﻳﺪ در آن ﻗﺮار ﺑﮕﻴﺮﻧﺪ درون ﭘﺮوژه ي وﻳﻨﺪوزي ﻫﺴﺘﻨﺪ. در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺒﻠﻲ ﻧﺤﻮه اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻛﻼس ﺑﻪ ﺑﺮﻧﺎﻣﻪ را ﻣﺸﺎﻫﺪه ﻛﺮده اﻳﺪ .در اﻳﻦ ﺟﺎ ﻫﻢ ﻣـﻲ ﺗﻮاﻧﻴـﺪ از ﻫﻤـﺎن روش اﺳـﺘﻔﺎده ﻛﻨﻴﺪ ،ﻳﻌﻨﻲ روي ﻧﺎم ﭘﺮوژه ﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ و از ﻣﻨﻮي ﻧﻤﺎﻳﺶ داده ﺷﺪه ﮔﺰﻳﻨـﻪ ي Add Classرا اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ .اﻣـﺎ ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي InternetFavoritesاﺿﺎﻓﻪ ﻛﻨﻴﻢ ﻗﺒﻼً ﻃﺮاﺣﻲ ﺷﺪه اﻧﺪ .ﭘﺲ ﻧﻴﺎزي ﺑﻪ اﺳﺘﻔﺎده از اﻳﻦ روش ﻧﻴﺴﺖ و ﺑﻪ راﺣﺘﻲ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ ﻣﺎوس اﻳﻦ ﻛﻼس ﻫﺎ را از ﺑﺮﻧﺎﻣﻪ ي Favorites Viewer ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي InternetFavoritesﻣﻨﺘﻘﻞ ﻛﻨﻴﻢ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ اﻳﻦ روش را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻧﺘﻘﺎل ﻛﻼﺳﻬﺎ ﺑﻴﻦ دو ﭘﺮوژه (1ﺑﺎ اﺳـﺘﻔﺎده از ﭘﻨﺠـﺮه ي Solution Explorerﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ 2-12ﻓﺎﻳـﻞ Favorites.csرا اﻧﺘﺨﺎب ﻛﺮده و ﺑﺎ ﻣﺎوس آن را ﺑﻪ ﭘﺮوژه ي InternetFavoritesﻣﻨﺘﻘﻞ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻳـﻚ ﻛﭙـﻲ از اﻳﻦ ﻓﺎﻳﻞ ﺑﻪ داﺧﻞ ﻓﻮﻟﺪر اﻳﻦ ﭘﺮوژه ﻓﺮﺳﺘﺎده ﺧﻮاﻫﺪ ﺷﺪ.
٤٧٧
ﺷﻜﻞ 2-12 (2ﻫﻤــــﻴﻦ ﻛــــﺎر را ﺑــــﺮاي ﻓﺎﻳــــﻞ WebFavorite.csﻧﻴــــﺰ ﺗﻜــــﺮار ﻛﻨﻴــــﺪ ﺗــــﺎ ﺑــــﻪ ﭘــــﺮوژه ي InternetFavoritesﻣﻨﺘﻘﻞ ﺷﻮد. Favorites (3ﺣــﺎل ﻓﺎﻳﻠﻬــﺎي Favorites.csو WebFavorite.csرا از ﭘــﺮوژه ي Viewerاﻧﺘﺨﺎب ﻛﺮده و روي آﻧﻬﺎ ﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ .ﺳﭙﺲ ﺑﺎ اﻧﺘﺨﺎب ﮔﺰﻳﻨﻪ ي Deleteآﻧﻬـﺎ را از اﻳـﻦ ﭘـﺮوژه ﺣﺬف ﻛﻨﻴﺪ. (4در اﻧﺘﻬﺎ ﺑﺎﻳﺪ ﻓﻀﺎي ﻧﺎم دو ﻓﺎﻳﻠﻲ ﻛﻪ ﺑﻪ ﭘﺮوژه ي InternetFavoritesاﺿﺎﻓﻪ ﺷﺪه اﻧﺪ را ﺗﺼﺤﻴﺢ ﻛﻨﻴﺪ .ﺑـﺮ روي ﻓﺎﻳﻞ Favorites.csدر ﭘﻨﺠﺮه ي Solution Explorerدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗـﺎ ﻛـﺪ درون آن ﻧﻤــــﺎﻳﺶ داده ﺷــــﻮد .ﻣــــﺸﺎﻫﺪه ﺧﻮاﻫﻴــــﺪ ﻛــــﺮد ﻛــــﻪ ﻛــــﻼس Favoritesدر ﻓــــﻀﺎي ﻧــــﺎم Favorites_Viewerﻗــــﺮار ﮔﺮﻓﺘــــﻪ اﺳــــﺖ .ﻧــــﺎم ﻣﻘﺎﺑــــﻞ دﺳــــﺘﻮر namespaceرا ﺑــــﻪ InternetFavoritesﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ ﻓﻀﺎي ﻧﺎم آن ﺗﻨﻈﻴﻢ ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴـﺐ ﻛـﺪ درون اﻳـﻦ ﻓﺎﻳـﻞ ﺑﺎﻳـﺪ ﻣﺸﺎﺑﻪ زﻳﺮ ﺑﺎﺷﺪ. namespace InternetFavorites { public class Favorites { (5ﻫﻤﻴﻦ ﻣﺮاﺣﻞ را ﺑﺮاي ﻓﺎﻳﻞ WebFavorite.csﻧﻴﺰ ﺗﻜﺮار ﻛﺮده و ﻓﻀﺎي ﻧﺎم آن را ﻧﻴـﺰ ﺗﻐﻴﻴـﺮ دﻫﻴـﺪ ﺗـﺎ ﻫـﺮ دو ﻛﻼس Favoritesو WebFavoriteدر ﻳﻚ ﻓﻀﺎي ﻧﺎم ﻗﺮار ﺑﮕﻴﺮﻧﺪ. ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ ﺷﺎﻣﻞ دو ﭘﺮوژه ﺧﻮاﻫﺪ ﺑﻮد ﻛﻪ ﻫﺮ ﻳﻚ داراي ﻓﺎﻳﻞ ﻫﺎي ﻣﺮﺗﺒﻂ ﺑﻪ ﺧﻮد اﺳﺖ .دﻗﺖ ﻛﻨﻴﺪ ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ اﻳﻦ دو ﭘﺮوژه در ﻳﻚ راه ﺣﻞ ﻫﺴﺘﻨﺪ ،اﻣﺎ ﺑﻪ ﻓﺎﻳﻠﻬﺎي ﻫﻢ دﺳﺘﺮﺳﻲ ﻧﺪارﻧﺪ و ﻧﻤﻲ ﺗﻮاﻧﻨﺪ ﻓﺎﻳﻠﻬﺎي ﻳﻜﺪﻳﮕﺮ را ﺑﺒﻴﻨﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﺳﻌﻲ ﻛﻨﻴﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ ،ﭘﻴﻐﺎم ﺧﻄﺎﻳﻲ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و اﻋﻼم ﻣﻲ ﻛﻨـﺪ ﻛـﻪ ﻛـﻼس Favoritesو WebFavorite ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ ﭘﻴﺪا ﻧﺸﺪه اﺳﺖ. اﻳــﻦ ﺧﻄــﺎ ﺑــﻪ اﻳــﻦ دﻟﻴــﻞ رخ ﻣــﻲ دﻫــﺪ ﻛــﻪ ﻛــﺪ ﻫــﺎي درون ﻓﺎﻳــﻞ Form1.csﻧﻤــﻲ ﺗﻮاﻧﻨــﺪ ﻛﻼﺳــﻬﺎي درون ﺑﺮﻧﺎﻣــﻪ ي InternetFavoritesرا ﻣﺸﺎﻫﺪه ﻛﻨﻨﺪ و ﺑﻪ آﻧﻬﺎ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ .رﻓﻊ اﻳﻦ ﻣﺸﻜﻞ ﺷﺎﻣﻞ دو ﻣﺮﺣﻠﻪ ﻣﻲ ﺷﻮد.
٤٧٨
ﭘﺮوژه ي ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس را ﺑﻪ ﺻﻮرت ﻳﻚ ارﺟﺎع ،ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺻﻮرت ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ﻣﻲ ﺗﻮاﻧﺪ ﺑﺮاي ﭘﻴﺪا ﻛﺮدن ﻛﻼﺳﻬﺎي ﻣﻮرد ﻧﻴﺎز ﺧﻮد ،ﺧﺮوﺟﻲ ﭘـﺮوژه ي ،InternetFavoritesﻳﻌﻨـﻲ ﻓﺎﻳـﻞ InternetFavorites.dllﻛﻪ ﺣﺎوي ﻛﻼﺳﻬﺎي ﻣﻮرد ﻧﻴﺎز اﺳﺖ را ﻧﻴﺰ ﺟﺴﺘﺠﻮ ﻛﻨﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﻛﻼﺳﻬﺎ در ﻓﻀﺎي ﻧﺎﻣﻲ ﻫﻢ ﻧﺎم ﺑﺎ ﭘﺮوژه ي ﺧﻮد ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي اﻳﻦ ﻛﻪ ﺑﺘﻮاﻧﻴﺪ ﻓﻘﻂ ﺑـﺎ ذﻛﺮ ﻧﺎم ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﻓﺎﻳﻞ InternetFavorites.dllﺑﻪ آﻧﻬﺎ دﺳﺘﺮﺳﻲ داﺷـﺘﻪ ﺑﺎﺷـﻴﺪ ،ﺑﺎﻳـﺪ ﺑـﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر usingﻓﻀﺎي ﻧﺎم آﻧﻬﺎ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .اﻟﺒﺘﻪ ﺑﺪون اﻧﺠﺎم اﻳﻦ ﻛﺎر ﻧﻴـﺰ ﻣـﻲ ﺗﻮاﻧﻴـﺪ از ﻛﻼﺳـﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،اﻣﺎ در اﻳﻦ ﺻﻮرت ﺑﺎﻳﺪ ﻧﺎم ﻛﺎﻣﻞ ﻛﻼﺳﻬﺎ )ﻳﻌﻨﻲ ﻧﺎم ﺧﻮد ﻛﻼس ﻫﻤﺮاه ﺑﺎ ﻓﻀﺎي ﻧﺎم آن( را ذﻛﺮ ﻛﻨﻴﺪ.
در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻧﺤﻮي اﻧﺠﺎم اﻳﻦ دو ﻣﻮرد را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ارﺟﺎع ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي (1روي ﻧﺎم ﭘﺮوژه ي Favorites Viewerدر ﭘﻨﺠـﺮه ي Solution Explorerﻛﻠﻴـﻚ راﺳـﺖ ﻛﺮده و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ ي … Add Referenceرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. (2در ﻛﺎدر Add Referenceﺑﻪ ﻗﺴﻤﺖ Projectsﺑﺮوﻳﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛـﺮد ﻛـﻪ ﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ 3-12 ﭘﺮوژه ي InternetFavoritesدر ﻟﻴﺴﺖ اﻳﻦ ﻗﺴﻤﺖ وﺟﻮد دارد .روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴـﺪ ﺗـﺎ اﻳـﻦ ﭘﺮوژه ﺑﻪ ﻋﻨﻮان ﻳﻚ ﻣﺮﺟﻊ ﺑﻪ ﭘﺮوژه ي Favorites Viewerاﺿﺎﻓﻪ ﺷﻮد.
ﺷﻜﻞ 3-12
٤٧٩
(3در اﺑﺘﺪاي ﻓﺎﻳﻞ Form1.csﺑﺎ اﺳﺘﻔﺎده از راﻫﻨﻤـﺎي usingﻓـﻀﺎي ﻧـﺎم InternetFavoritesرا ﻣﺎﻧﻨﺪ زﻳﺮ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ. ;using InternetFavorites
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ارﺟﺎع ﺑﻪ ﭘﺮوژه ي InternetFavoritesدر ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي در ﻣﺮاﺣـﻞ 1و ،2در ﺣﻘﻴﻘـﺖ ﺑـﻪ وﻳـــﮋوال اﺳـــﺘﻮدﻳﻮ ﮔﻔﺘـــﻪ اﻳـــﺪ ﻛـــﻪ ﻓﺎﻳـــﻞ FavoritesViewer.exeﺑـــﺮاي اﺟـــﺮا ﺷـــﺪن ﺑـــﻪ ﻓﺎﻳـــﻞ InternetFavorites.dllو ﻛﻼﺳﻬﺎي داﺧﻞ آن ﻧﻴﺎز دارد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣـﻲ دﻫـﺪ در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد از ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ در ﻓﺎﻳﻞ InternetFavorites.dllوﺟﻮد دارد اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﻧﻜﺘﻪ :ﻫﺮ زﻣﺎن ﻛﻪ ﺑﺨﻮاﻫﻴﺪ از ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ ﺑﺎﻳﺪ ﻳﻚ ارﺟـﺎع ﺑـﻪ آن ﻛﺘﺎﺑﺨﺎﻧـﻪ را در ﺑﺮﻧﺎﻣـﻪ اﻳﺠﺎد ﻛﻨﻴﺪ .اﮔﺮ آن ﻛﺘﺎﺑﺨﺎﻧﻪ ﺑﻪ ﺻﻮرت ﻳﻚ ﭘﺮوژه از ﻧﻮع Class Libraryدر ﺑﺮﻧﺎﻣﻪ ﺑﻮد ﻣﻲ ﺗﻮاﻧﻴﺪ از روش ﻗﺒـﻞ اﺳـﺘﻔﺎده ﻛﻨﻴﺪ .اﮔﺮ ﻫﻢ ﺑﻪ ﺻﻮرت ﻳـﻚ ﻓﺎﻳـﻞ dllﻛﺎﻣﭙﺎﻳـﻞ ﺷـﺪه ﺑـﻮد ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﺎ اﺳـﺘﻔﺎده از ﻗـﺴﻤﺖ Browseدر ﻛـﺎدر Add Referenceآدرس ﻓﺎﻳﻞ را ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﺗﺎ وﻳﮋوال اﺳﺘﻮدﻳﻮ آن را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﺪ. ﺗـــﺎ ﻗﺒـــﻞ از ﻣﺮﺣﻠـــﻪ ي ﺳـــﻮم ﺑـــﺎ وﺟـــﻮد اﻳﻨﻜـــﻪ ﻣـــﺸﺨﺺ ﻛـــﺮده اﻳـــﺪ ﻛـــﻪ ﺑﺮﻧﺎﻣـــﻪ ﺑﺎﻳـــﺪ از ﻛﻼﺳـــﻬﺎي درون ﭘـــﺮوژه ي InternetFavoritesاﺳﺘﻔﺎده ﻛﻨﺪ ،اﻣﺎ اﮔﺮ ﺳﻌﻲ ﻛﻨﻴﺪ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ ﺑﺎ ﭘﻴﻐﺎم ﺧﻄﺎ ﻣﻮاﺟﻪ ﺧﻮاﻫﻴﺪ ﺷـﺪ .دﻟﻴـﻞ اﻳـﻦ ﺧﻄﺎ ﻧﻴﺰ اﻳﻦ اﺳﺖ ﻛﻪ ﺳﻌﻲ ﻛﺮده اﻳﺪ ﺑﺪون ذﻛﺮ ﻧﺎم ﻛﺎﻣﻞ ﻛﻼﺳﻬﺎي Favoritesو WebFavoriteاز آﻧﻬـﺎ در ﺑﺮﻧﺎﻣـﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺗﻤﺎم اﻳﻦ ﻛﻼﺳﻬﺎ در ﻓﻀﺎي ﻧﺎم InternetFavoritesﻫﺴﺘﻨﺪ ،ﭘﺲ ﺑﺮاي اﺳﺘﻔﺎده از آﻧﻬﺎ ﻳـﺎ ﺑﺎﻳـﺪ ﻓـﻀﺎي ﻧﺎم آن را ﺑﺎ اﺳﺘﻔﺎده از راﻫﻨﻤﺎي usingﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮد و ﻳﺎ ﻧﺎم ﻛﻼس را ﺑﻪ ﻧﺎم ﻛﺎﻣﻞ آن ﺗﻐﻴﻴﺮ داد .ﻣﺴﻠﻤﺎً اﺳﺘﻔﺎده از راﻫﻨﻤﺎي usingﺳﺎده ﺗﺮ اﺳﺖ ،ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ راﻫﻨﻤﺎ ﻓﻀﺎي ﻧﺎم InternetFavoritesرا ﺑﻪ ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ ﻣـﻲ ﻛﻨﻴﻢ. ﺧﻮب ،ﺗﻤﺎم ﻣﺮاﺣﻞ ﻣﻮرد ﻧﻴﺎز ﺑﺮاي اﻳﻦ ﻗﺴﻤﺖ ﻫﻤﻴﻦ ﺑﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ ﺑﻪ دو ﻗﺴﻤﺖ ﺗﻘﺴﻴﻢ ﺷﺪ :ﻳﻜﻲ ﺷﺎﻣﻞ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ﻛﻮﭼﻚ ﺑﺮاي ﻗﺴﻤﺖ ﻛﺎرﺑﺮي ﺑﺮﻧﺎﻣﻪ و دﻳﮕﺮي ﻧﻴﺰ ﺷﺎﻣﻞ ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺣﺎوي ﻛﻼس ﻫﺎي ﻣﻮرد ﻧﻴﺎز در ﻗﺴﻤﺖ ﻛﺎرﺑﺮي ﺑﺮﻧﺎﻣﻪ .ﺣﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ ،ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻫﻤﺎﻧﻨﺪ ﻗﺒﻞ ﺑﻪ درﺳﺘﻲ ﻛﺎر ﻣﻲ ﻛﻨﺪ. ،Favoritesوﻳـــﮋوال اﺳـــﺘﻮدﻳﻮ اﺑﺘـــﺪا ﺑﺮﻧﺎﻣـــﻪ ي دﻗـــﺖ ﻛﻨﻴـــﺪ ﻛـــﻪ ﺑـــﺮاي ﻛﺎﻣﭙﺎﻳـــﻞ ﺑﺮﻧﺎﻣـــﻪ ي Viewer InternetFavoritesرا ﻛﺎﻣﭙﺎﻳﻞ ﻛﺮده و ﻓﺎﻳﻞ dllآن را ﺗﻮﻟﻴﺪ ﻣﻲ ﻛﻨﺪ .ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي را ﻛﺎﻣﭙﺎﻳﻞ ﻛﺮده و ﻓﺎﻳﻞ exeرا ﺗﻮﻟﻴﺪ ﻣﻲ ﻛﻨﺪ .دﻟﻴﻞ اﻳﻦ ﻣﻮرد ﻫﻢ ﻣﺸﺨﺺ اﺳـﺖ ،زﻳـﺮا ﻛـﺎرﻛﺮد ﺑﺮﻧﺎﻣـﻪ ي Favorites Viewerﺑـﻪ ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در InternetFavoritesﺑﺴﺘﮕﻲ دارد.
ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﭼﻨﺪ ﻻﻳﻪ:
٤٨٠
در ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻞ ﺑﺎ اﻳﺠﺎد ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس در ﺣﻘﻴﻘﺖ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ دو ﻻﻳﻪ 1ﺗﻘﺴﻴﻢ ﻛﺮدﻳﻢ .ﻳﻜـﻲ از اﻳـﻦ ﻻﻳـﻪ ﻫـﺎ ﻛﻼﺳـﻬﺎي ﻣﻮﺟﻮد در ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺑﻮد .وﻇﻴﻔﻪ اﻳﻦ ﻻﻳﻪ اﻳﻦ ﺑـﻮد ﻛـﻪ ﻛـﺎﻣﭙﻴﻮﺗﺮ ﻛـﺎرﺑﺮ را ﺟـﺴﺘﺠﻮ ﻛـﺮده و ﺗﻤـﺎم ﮔﺰﻳﻨـﻪ ﻫـﺎي ﻣﻮﺟـﻮد در ﺑﺨﺶ Favoritesﭘﻴﺪا ﻛﺮده و در ﻳﻚ آراﻳﻪ ﻗﺮار دﻫﺪ .ﻻﻳﻪ ي دﻳﮕﺮ ﻧﻴﺰ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي اﻳﺠﺎد ﺷﺪه ﺑﻮد .وﻇﻴﻔﻪ ي اﻳﻦ ﻻﻳﻪ اﻳﻦ ﺑﻮد ﻛﻪ ﮔﺰﻳﻨﻪ ﻫﺎي Favoritesﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻻﻳﻪ ي ﻗﺒﻠﻲ در آراﻳﻪ ﻗﺮار داده ﺷﺪه ﺑـﻮد را ﺑـﻪ ﻧﺤـﻮ ﻣﻨﺎﺳـﺒﻲ ﺑـﻪ ﻛـﺎرﺑﺮ ﻧﻤﺎﻳﺶ دﻫﺪ و ﻫﻤﭽﻨﻴﻦ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﺪ ﺗﺎ آﻧﻬﺎ را ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﻣﺸﺎﻫﺪه ﻛﻨﺪ. ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس ﻣﻌﻤﻮﻻً اﺑﺰار ﺑﺴﻴﺎر ﻣﻨﺎﺳﺒﻲ ﺑﺮاي اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﭼﻨﺪ ﻻﻳﻪ ﺑﻪ ﺷﻤﺎر ﻣﻲ روﻧﺪ ،زﻳﺮا ﺑـﻪ وﺳـﻴﻠﻪ آﻧﻬـﺎ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﻗﺴﻤﺖ ﻫﺎي ﻣﺨﺘﻠﻒ ﺑﺮﻧﺎﻣﻪ را در ﻻﻳﻪ ﻫﺎي ﺟﺪاﮔﺎﻧﻪ ﺗﻘﺴﻴﻢ ﻛﻨﻴﺪ .اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺳﺎده ﺑﻪ ﺷﻤﺎر ﻣﻲ رﻓﺖ ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ ﻓﻘﻂ از دو ﻻﻳﻪ ﺗﺸﻜﻴﻞ ﺷﺪه ﺑﻮد .اﻣﺎ ﻣﻤﻜﻦ اﺳﺖ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺑﺰرگ ﻋﺒﺎرت "ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﭼﻨﺪ ﻻﻳﻪ" را زﻳﺎد ﺑـﺸﻨﻮﻳﺪ .در دﻧﻴـﺎي واﻗﻌـﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﭼﻨﺪ ﻻﻳﻪ ﺣﺪاﻗﻞ از ﺳﻪ ﻻﻳﻪ ي ﻣﺨﺘﻠﻒ و ﻣﺠﺰا ﺗﺸﻜﻴﻞ ﻣﻲ ﺷﻮﻧﺪ و اﻳﻦ ﺳﻪ ﻻﻳﻪ ﻧﻴﺰ ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻌﺮﻳﻒ ﻣﻲ ﺷﻮﻧﺪ:
ﻻﻳﻪ ي داده ﻫﺎ 2ﻓﻘﻂ ﺑﺮ روي درﻳﺎﻓﺖ اﻃﻼﻋﺎت ﺧﺎم از ﻳﻚ ﻣﻨﺒﻊ اﻃﻼﻋﺎﺗﻲ و ﻓﺮﺳﺘﺎدن اﻃﻼﻋﺎت ﭘﺮدازش ﺷـﺪه ﺑـﻪ اﻳـﻦ ﻣﻨﺒﻊ ﺗﻤﺮﻛﺰ ﻣﻲ ﻛﻨﺪ .اﻳﻦ ﻣﻨﺒﻊ اﻃﻼﻋﺎﺗﻲ ﻣﻲ ﺗﻮاﻧﺪ ﺷﺎﻣﻞ ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ،ﻳﻚ ﻓﺎﻳﻞ ﻣﺘﻨﻲ و ﻳﺎ ﻫﺮ ﻧﻮع ﻣﻨﺒﻊ اﻃﻼﻋـﺎﺗﻲ دﻳﮕﺮ ﺑﺎﺷﺪ .اﻳﻦ ﻻﻳﻪ در ﻧﻮع و ﻳﺎ ﻣﻔﻬﻮم اﻃﻼﻋﺎت ﻓﺮﺳﺘﺎده ﺷﺪه و ﻳﺎ درﻳﺎﻓﺖ ﺷﺪه ﻫﻴﭻ دﺧﺎﻟﺘﻲ ﻧﺪارد و ﻓﻘﻂ ﻣﻮﻇﻒ اﺳﺖ ﻛﻪ وﻇﻴﻔﻪ ي ﺧﻮاﻧﺪن و ﻧﻮﺷﺘﻦ در ﻣﻨﺒﻊ اﻃﻼﻋﺎﺗﻲ را اﻧﺠﺎم دﻫﺪ .در ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻠﻲ ﻓﻮﻟﺪر Favoritesدر ﻛﺎﻣﭙﻴﻮﺗﺮ ﻛﺎرﺑﺮ ﺑﻪ ﻋﻨﻮان ﻻﻳﻪ ي اﻃﻼﻋﺎت ﺑﻪ ﺷﻤﺎر ﻣﻲ رﻓﺖ. ﻻﻳﻪ ي ﺗﺠﺎري 3در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ،ﻓﻘﻂ ﻣﻘﺮرات و ﻗﻮاﻧﻴﻦ ﺧﺎﺻﻲ را ﺑﺮ داده ﻫﺎﻳﻲ ﻛﻪ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ درﻳﺎﻓﺖ ﻣﻲ ﺷﻮﻧﺪ و ﻳﺎ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮﻧﺪ اﻋﻤﺎل ﻣﻲ ﻛﻨﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﻴﺸﺘﺮ ﺗﻮﺟﻪ اﻳﻦ ﻻﻳﻪ ﺑﺮ اﻳﻦ اﺳﺖ ﻛـﻪ ﺑـﺮاي ﻣﺜـﺎل داده ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮﻧﺪ ﺣﺘﻤﺎً داراي ﺷـﺮاﻳﻂ ﺧﺎﺻـﻲ ﺑﺎﺷـﻨﺪ و ﻗﺒـﻞ از ﻧﻮﺷـﺘﻪ ﺷـﺪن در ﺑﺎﻧـﻚ اﻃﻼﻋﺎﺗﻲ ﺻﺤﺖ آﻧﻬﺎ ﺑﺮرﺳﻲ ﺷﻮد .ﺑﺮاي ﻣﺜﺎل در ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻞ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴـﺪ ﻗﺒـﻞ از اﻳﻨﻜـﻪ اﻃﻼﻋـﺎت در ﺑﺮﻧﺎﻣـﻪ ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ ،از درﺳﺖ ﺑﻮدن ﻟﻴﻨﻚ ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ و ﻳﺎ از ﻧﻤﺎﻳﺶ داده ﺷﺪن ﻟﻴﻨﻚ ﻫـﺎي ﺧﺎﺻـﻲ در ﺑﺮﻧﺎﻣـﻪ ﺟﻠـﻮﮔﻴﺮي ﻛﻨﻴﺪ .اﻟﺒﺘﻪ ﻣﻤﻜﻦ اﺳﺖ ﻛﺪ ﻫﺎﻳﻲ ﻧﻴﺰ در اﻳﻦ ﻗﺴﻤﺖ ﻗﺮار داده ﺷﻮﻧﺪ ﺗﺎ داده ﻫﺎ را ﺗﻐﻴﻴﺮ دﻫﻨﺪ و ﻳﺎ ﻛﺎرﻫـﺎﻳﻲ روي آﻧﻬـﺎ اﻧﺠـﺎم دﻫﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻤﻜﻦ اﺳﺖ ﻛﺪ ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﻧﻤﺎﻳﺶ دادن ﻳﻚ ﻟﻴﻨﻚ در ﺑﺮﻧﺎﻣﻪ در اﻳﻦ ﻻﻳﻪ ﻗﺮار داده ﺷﻮد. ﻻﻳﻪ ي اراﺋﻪ دﻫﻨﺪه 4داده ﻫﺎي رﺳﻴﺪه را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ و ﺑﻪ او اﺟﺎزه ﻣﻲ دﻫﺪ ﺗﺎ ﺑﺎ اﻳﻦ داده ﻫﺎ ﻛـﺎر ﻛﻨـﺪ .در اﻳﻦ ﻣﺜﺎل ،ﺑﺮاي اﻳﻦ ﻻﻳﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي اﻳﺠﺎد ﻛﺮدﻳﺪ ﻛﻪ ﻟﻴﻨﻚ ﻫﺎ را ﺑﻪ ﺻﻮرت ﻳﻚ ﻟﻴـﺴﺖ ﻧﻤـﺎﻳﺶ ﻣـﻲ دﻫـﺪ و ﻫﻤﭽﻨﻴﻦ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻣﻲ دﻫﺪ ﺗﺎ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر آﻧﻬﺎ را ﻣﺸﺎﻫﺪه ﻛﻨﺪ.
ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ ﻃﺮاﺣﻲ ﻛﺮدﻳﻢ ﺑﺴﻴﺎر ﻛﻮﭼﻚ ﺑﻮد ،ﺑﻨﺎﺑﺮاﻳﻦ ﻧﻴﺎزي ﻧﺒﻮد ﻛﻪ ﻻﻳﻪ ي داده را از ﻻﻳﻪ ي ﺗﺠﺎري ﻣﺠـﺰا ﻛﻨـﻴﻢ. اﻣﺎ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺑﺰرگ ،ﺗﻘﺴﻴﻢ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﭼﻨﺪ ﻻﻳﻪ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﻣﺪﻳﺮﻳﺖ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ آن ﺑﺴﻴﺎر ﺳـﺎده ﺗـﺮ اﻧﺠـﺎم ﺷـﻮد، ﺣﺘﻲ اﮔﺮ ﺑﺎ اﻳﻦ روش ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ زﻣﺎن ﺑﻴﺸﺘﺮي را ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﺪ. ﻳﻜﻲ دﻳﮕﺮ از ﻣﺰاﻳﺎي ﺗﻘﺴﻴﻢ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﭼﻨﺪ ﻻﻳﻪ در اﻳﻦ اﺳﺖ ﻛﻪ ﺑﻪ اﻳﻦ ﺻﻮرت ﻣﻲ ﺗﻮاﻧﻴﺪ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﺑﺮﻧﺎﻣﻪ را ﻫﻨﮕـﺎم ﻧﻴـﺎز ﺑﻪ راﺣﺘﻲ ﺗﻐﻴﻴﺮ دﻫﻴﺪ ،ﺑﺪون اﻳﻨﻜﻪ دﻳﮕﺮ ﻗﺴﻤﺘﻬﺎ ﻧﻴﺎزي ﺑﻪ ﺗﻐﻴﻴﺮ ﻛﺮدن داﺷﺘﻪ ﺑﺎﺷﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﺑﻌـﺪ از ﻣـﺪﺗﻲ اﺳـﺘﻔﺎده از ﻧﻮع ﺧﺎﺻﻲ از ﻣﺮورﮔﺮ ﻫﺎ ﺑﻪ ﺟﺰ اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﻓﺮاﮔﻴﺮ ﺷﻮد و ﺷﻤﺎ ﺑﺨﻮاﻫﻴﺪ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد را ﺑﻪ ﺻﻮرﺗﻲ ﺗﻐﻴﻴـﺮ دﻫﻴـﺪ ﻛـﻪ اﻃﻼﻋـﺎت ﻣﻮرد ﻧﻴﺎز ﺧﻮد را از ﻣﻨﻮي Favoritesاﻳﻦ ﻣﺮورﮔﺮ درﻳﺎﻓﺖ ﻛﻨﺪ .در اﻳﻦ ﺣﺎﻟﺖ ﻓﻘـﻂ ﻻزم اﺳـﺖ ﻛـﻪ ﻛـﺪ ﻣﺮﺑـﻮط ﺑـﻪ درﻳﺎﻓـﺖ اﻃﻼﻋﺎت را در ﻻﻳﻪ ي داده ﻫﺎ ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻗﺴﻤﺘﻬﺎ و ﻻﻳﻪ ﻫﺎي دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﺑﺪون ﺗﻐﻴﻴﺮ ﺑﺎﻗﻲ ﻣﻲ ﻣﺎﻧﻨﺪ و ﻣﺎﻧﻨﺪ ﻗﺒـﻞ ﺑـﻪ درﺳﺘﻲ ﺑﺎ ﻻﻳﻪ ي داده اي ﺟﺪﻳﺪ ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ. 1
Layer Data Layer 3 Business Layer 4 Presentation Layer 2
٤٨١
ﻧﻜﺘﻪ :ﻫﺪف از ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﭼﻨﺪ ﻻﻳﻪ ،ﭘﻴﭽﻴﺪه ﺗﺮ از آن اﺳﺖ ﻛﻪ در اﻳﻦ ﻛﺘﺎب ﻣﻮرد ﺑﺮرﺳﻲ ﻗﺮار ﮔﻴﺮد .اﻣﺎ ﺑﺮاي آﺷـﻨﺎﻳﻲ ﻣﻘـﺪﻣﺎﺗﻲ ﺑـﺎ اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ و ﻧﻘﺶ .NETدر آن ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺿﻤﻴﻤﻪ ي 2ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ. در اداﻣﻪ ي ﻓﺼﻞ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان از ﻛﺘﺎﺑﺨﺎﻧﻪ ﻛﻼس InternetFavoritesﻛـﻪ در ﺣﻘﻴﻘـﺖ ﺗﺮﻛﻴﺒﻲ از دو ﻻﻳﻪ ي داده اي و ﻻﻳﻪ ي ﺗﺠﺎري اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﺳﺖ در ﺑﺮﻧﺎﻣﻪ اي دﻳﮕـﺮ ﺑـﻪ ﻧـﺎم Favorites Trayاﺳـﺘﻔﺎده ﻛﺮد. ﻧﻜﺘﻪ :در اﻳﻦ ﻓﺼﻞ ﻓﻘﻂ ﺑﺎ ﭘﺮوژه ي اﻧﺠﺎم ﺷﺪه در ﻓﺼﻞ دﻫﻢ ﻛﺎر ﻣﻲ ﻛﻨﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﻪ ﺟﺎي ﻧﻮﺷـﺘﻦ ﻛـﺪ ﺑﻴـﺸﺘﺮ ﺑـﺮ ﻣﻔﻬﻮم و ﻧﺤﻮه ي ﻛﺎرﻛﺮد ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس ﺗﻤﺮﻛﺰ ﻛﻨﻴﻢ.
اﺳﺘﻔﺎده از ﻧﺎﻣﮕﺬاري ﻗﻮي ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در ﻣﺮﺣﻠﻪ ي ﻗﺒﻞ اﻳﺠﺎد ﻛﺮدﻳﺪ ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ دو ﻓﺎﻳﻞ ﻣﺠﺰا ﺗﻮﻟﻴﺪ ﻣﻲ ﻛﻨﺪ :ﻳﻚ ﻓﺎﻳﻞ exeو ﻳﻚ ﻓﺎﻳﻞ dllﻛﻪ ﻫﺮ دوي آﻧﻬﺎ ﺑﻪ وﺳﻴﻠﻪ ي ﺷﻤﺎ ﻃﺮاﺣﻲ و ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ .ﻣﺴﻠﻤﺎً ﻣﻄﻤﺌﻦ ﻫﺴﺘﻴﺪ ﻛﻪ ﻓﺮد دﻳﮕﺮي ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد را ﺑـﺮ اﺳـﺎس ﻛﻼﺳـﻬﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻓﺎﻳﻞ dllﻧﺨﻮاﻫﺪ ﻧﻮﺷﺖ و ﻳﺎ ﻓﺮد دﻳﮕﺮي ﺑﻪ ﺟﺰ ﺷﻤﺎ ﻛﺪ ﻫﺎي درون اﻳﻦ ﻓﺎﻳـﻞ dllرا ﺗﻐﻴﻴـﺮ ﻧﺨﻮاﻫـﺪ داد .اﻣـﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي واﻗﻌﻲ ﻣﻌﻤﻮﻻً ﭼﻨﻴﻦ ﺷﺮاﻳﻄﻲ ﺑﻪ وﺟﻮد ﻧﻤﻲ آﻳﺪ .در ﺑﺮﻧﺎﻣﻪ ﻫﺎي واﻗﻌﻲ اﻏﻠﺐ از dllﻫﺎﻳﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻳﻚ ﮔﺮوه ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻧﻮﺷﺘﻪ ﺷﺪه و ﺑﻪ ﺻﻮرت ﮔﺴﺘﺮده در ﺑﻴﻦ دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﺗﻮزﻳﻊ ﺷﺪه اﻧﺪ و ﻳﺎ ﻣﻤﻜﻦ اﺳـﺖ ﻋـﻀﻮ ﻳـﻚ ﮔﺮوه ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺎﺷﻴﺪ ﻛﻪ در آن اﻓﺮادي روي ﻳﻚ dllو اﻓﺮاد دﻳﮕﺮي روي ﻳﻚ ﻓﺎﻳﻞ exeﻛﺎر ﻣﻲ ﻛﻨﻨﺪ. ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﻓﺮد Aدر ﺣﺎل ﻛﺎر روي ﻓﺎﻳﻞ InternetFavorites.dllاﺳﺖ و ﻓﺮد Bﻧﻴﺰ روي ﻓﺎﻳـﻞ FavoritesViewer.exeﻛﺎر ﻣﻲ ﻛﻨﺪ .ﻓﺮد Aاﺣﺴﺎس ﻣﻲ ﻛﻨﺪ ﻛـﻪ ﻧـﺎم ScanFavoritesﻧـﺎم ﻣﻨﺎﺳـﺒﻲ ﻧﻴﺴﺖ و آن را ﺑﻪ LoadFavoritesﺗﻐﻴﻴﺮ ﻣﻲ دﻫﺪ .ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ را ﻛﺎﻣﭙﺎﻳﻞ ﻛﺮده و ﻓﺎﻳﻞ dllﺟﺪﻳﺪي را ﺗﻮﻟﻴﺪ ﻣﻲ ﻛﻨـﺪ. ﻓﺮد Bﺑﺪون اﻳﻨﻜﻪ اﻳﻦ ﻣﻮرد را ﺑﺪاﻧﺪ ﺑﺮﻧﺎﻣﻪ ي FavoritesViewer.exeرا اﺟﺮا ﻛﺮده و اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﺳﻌﻲ ﻣﻲ ﻛﻨـﺪ ﻛﻪ ﻣﺘﺪ ScanFavoritesرا ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﺪ .اﻣﺎ اﻳﻦ ﻣﺘﺪ دﻳﮕﺮ وﺟﻮد ﻧﺪارد ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟﻪ ﺷـﺪه و ﻣﺘﻮﻗـﻒ ﻣـﻲ ﺷﻮد. اﻟﺒﺘﻪ ﻣﻤﻜﻦ اﺳﺖ ﺑﮕﻮﻳﻴﺪ ﻛﻪ در اﻳﻦ ﻣﻮرد ﻓﺮد Aﻧﺒﺎﻳﺪ ﻧﺎم ﻣﺘﺪ را در ﻓﺎﻳﻞ dllﺗﻐﻴﻴﺮ ﻣﻲ داد و ﺑﺎﻳﺪ ﻣﺘﻮﺟﻪ ﻣﻲ ﺑﻮد ﻛـﻪ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎﻳﻲ وﺟﻮد دارﻧﺪ ﻛﻪ اﺟﺮاي آﻧﻬﺎ ﺑﻪ ﻣﺘﺪ ScanFavoritesدر اﻳﻦ ﻛﻼس ﺑﺴﺘﮕﻲ دارد .اﻣﺎ ﻫﻤـﻮاره ﺑﺮﻧﺎﻣـﻪ ﻧﻮﻳـﺴﺎﻧﻲ ﻫـﺴﺘﻨﺪ ﻛـﻪ ﺑﺪون ﺗﻮﺟﻪ ﺑﻪ ﻣﺸﻜﻼت ﻧﺎﺷﻲ از اﻳﻦ ﻛﺎر ،ﺑﻪ اﻳﻦ ﺻﻮرت ﻋﻤﻞ ﻣﻲ ﻛﻨﺪ و ﻣﻮﺟﺐ از ﻛﺎر اﻓﺘﺎدن ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻲ ﺷﻮﻧﺪ. ﻣﺸﻜﻞ دﻳﮕﺮي ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ در اﻳﻦ ﺣﺎﻟﺖ رخ دﻫﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻫﻤﺰﻣﺎن ﺑﺎ ﻓﺮد ،Aﻓﺮد Cﻧﻴﺰ ﻳـﻚ ﻛﺘﺎﺑﺨﺎﻧـﻪ ي ﻛـﻼس ﺑـﻪ ﻧـﺎم InternetFavoritesاﻳﺠﺎد ﻛﺮده و ﺑﺨﻮاﻫﺪ از آن اﺳﺘﻔﺎده ﻛﻨﺪ .اﻳﻦ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺑﺎ ﻓﺎﻳﻞ ﻧﻮﺷﺘﻪ ﺷﺪه ﺑﻪ وﺳـﻴﻠﻪ ي ﻓﺮد Aﺗﻔﺎوت دارد و اﮔﺮ ﻫﺮ دوي آﻧﻬﺎ ﺑﺮاي ﻛﺎر روي ﻳﻚ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻗﺮار ﺑﮕﻴﺮﻧﺪ اﻳﻦ دو ﻓﺎﻳﻞ ﺑﺎ ﻫـﻢ اﺷـﺘﺒﺎه ﺧﻮاﻫﻨـﺪ ﺷـﺪ و ﻣﺠـﺪداً ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﻪ درﺳﺘﻲ ﻛﺎر ﻧﺨﻮاﻫﻨﺪ ﻛﺮد. ﻣﺸﻜﻼﺗﻲ ﻛﻪ ﺑﻪ اﻳﻦ ﺻﻮرت ﺑﺮاي ﻣﺪﻳﺮﻳﺖ ﻓﺎﻳﻠﻬﺎي DLLرخ ﻣﻲ دﻫﺪ از اﺑﺘﺪاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ وﻳﻨﺪوز وﺟﻮد داﺷﺘﻪ اﺳﺖ و ﺑﻪ ﻛﺎﺑﻮﺳﻲ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﺗﺒﺪﻳﻞ ﺷﺪه ﺑﻮد ،ﺑﻪ ﺻﻮرﺗﻲ ﻛﻪ ﻣﻌﻤﻮﻻ از آﻧﻬﺎ ﺑﻪ ﻋﻨﻮان "ﺟﻬﻨﻢ DLLﻫـﺎ" 1ﻳـﺎد ﻣـﻲ ﻛﻨﻨـﺪ .در ﻣﺤـﻴﻂ .NET ﺗﻼش زﻳﺎدي ﺷﺪه اﺳﺖ ﺗﺎ اﻳﻦ ﻣﺸﻜﻼت ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﺑﺮﻃﺮف ﺷﻮد .ﻋﻤﺪه ي ﻣﺸﻜﻼﺗﻲ ﻛﻪ ﺑﻪ اﻳﻦ ﺻﻮرت ﻫﺴﺘﻨﺪ ،دو دﻟﻴﻞ ﻛﻠﻲ دارﻧﺪ:
DLL Hell
1
٤٨٢
از ﻳﻚ ﻓﺎﻳﻞ DLLﻣﻤﻜﻦ اﺳﺖ ﭼﻨﺪﻳﻦ ﻧﺴﺨﻪ وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ و ﻫﺮ ﻛﺪام ﻧﻴﺰ ﻣﻤﻜﻦ اﺳﺖ ﺑﻪ ﻧﺤﻮي ﻣﺘﻔﺎوت ﻋﻤﻞ ﻛﻨﻨـﺪ. ﻫﻤﭽﻨﻴﻦ ﺑﺎ اﺳﺘﻔﺎده از ﻧﺎم ﻓﺎﻳﻞ ﻧﻤﻲ ﺗﻮان ﻧﺴﺨﻪ ي آن را ﺗﺸﺨﻴﺺ داد. اﻓﺮاد و ﺷﺮﻛﺘﻬﺎي ﻣﺨﺘﻠﻒ ﻣﻲ ﺗﻮاﻧﻨﺪ ﻓﺎﻳﻠﻬﺎي DLLاي ﺑﺎ ﻧﺎم ﻣﺸﺎﺑﻪ اﻳﺠﺎد ﻛﻨﻨﺪ.
ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ اﺳﻤﺒﻠﻲ ﺑﻪ ﺻﻮرت ﻗﻮي ﻧﺎﻣﮕﺬاري ﺷﻮد 1اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﺷﻤﺎره ي ﻧـﺴﺨﻪ و ﻧﻮﻳـﺴﻨﺪه ي آن اﺳـﻤﺒﻠﻲ ﻧﻴـﺰ در آن ذﺧﻴﺮه ﻣﻲ ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻨﮕﺎم اﺳﺘﻔﺎده از ﻳﻚ اﺳﻤﺒﻠﻲ ﻣﻲ ﺗﻮان ﺑﻴﻦ ﻧﺴﺨﻪ ي ﻣﻮرد اﺳﺘﻔﺎده در ﺑﺮﻧﺎﻣﻪ و ﻧﺴﺨﻪ ﻫﺎي ﺟﺪﻳﺪﺗﺮ و ﻳﺎ ﻗﺪﻳﻤﻲ ﺗﺮ ﺗﻔﺎوت ﻗﺎﺋﻞ ﺷﺪ .ﻫﻤﭽﻨﻴﻦ ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ ﻣﻲ ﺗﻮان ﻓﺎﻳﻞ InternetFavorites.dllﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻓﺮد Aﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ را از ﻓﺎﻳﻞ InternetFavorites.dllﻛﻪ ﺗﻮﺳﻂ ﻓﺮد Cﻧﻮﺷﺘﻪ ﺷـﺪه اﺳـﺖ ﺗـﺸﺨﻴﺺ داد .ﺑـﺎ ﻧﺎﻣﮕﺬاري ﻗﻮي ﻳﻚ اﺳﻤﺒﻠﻲ ﻣﻲ ﺗﻮان اﻃﻼﻋﺎت دﻳﮕﺮي را ﻧﻴﺰ در ﻣﻮرد آن اﺳﻤﺒﻠﻲ در آن ذﺧﻴﺮه ﻛﺮد ﺗﺎ ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ از ﻣﻨﺤﺼﺮ ﺑﻪ ﻓﺮد ﺑﻮدن ﻳﻚ اﺳﻤﺒﻠﻲ ﻣﻄﻤﺌﻦ ﺷﺪ )ﺑﺮاي ﻣﺜﺎل ﻓﺮﻫﻨﮓ و زﺑﺎﻧﻲ ﻛﻪ ﺑﺮاي ﻧﻮﺷﺘﻦ آن اﺳﻤﺒﻠﻲ ﺑﻪ ﻛﺎر رﻓﺘﻪ اﺳﺖ (2اﻣﺎ در اﻳﻦ ﻗﺴﻤﺖ ﻓﻘﻂ ﺑـﺮ ﻣﺸﺨﺺ ﻛﺮدن ﻧﻮﻳﺴﻨﺪه و ﻧﺴﺨﻪ ي ﻳﻚ اﺳﻤﺒﻠﻲ ﺗﻤﺮﻛﺰ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﻀﺎ ﻛﺮدن اﺳﻤﺒﻠﻲ ﻫﺎ: ﻳﻚ راه ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن اﻳﻦ ﻣﻮﺿﻮع ﻛﻪ ﻳﻚ اﺳﻤﺒﻠﻲ ﺑﻪ وﺳﻴﻠﻪ ي ﭼﻪ ﻛﺴﻲ ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ اﻳﻦ اﺳﺖ ﻛـﻪ آن اﺳـﻤﺒﻠﻲ اﻣـﻀﺎ ﺷﻮد .ﺑﺮاي اﻧﺠﺎم اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﺟﻔﺖ-ﻛﻠﻴﺪ اﻳﺠﺎد ﻛﺮده و ﺳﭙﺲ ﺑﺎ اﻳﻦ ﻛﻠﻴﺪ ﻫﺎ اﺳﻤﺒﻠﻲ را اﻣﻀﺎ ﻛﻨﻴﺪ .اﻳﻦ ﻛﻠﻴﺪ ﻫﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺗﻮﻟﻴﺪ ﻣﻲ ﺷﻮﻧﺪ ﺑﻪ ﺻﻮرت ﻣﻨﺤﺼﺮ ﺑﻪ ﻓﺮد ﻫﺴﺘﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ وﻗﺘﻲ ﺗﻮﺳﻂ ﻓﺮد ﻳﺎ ﺷﺮﻛﺘﻲ ﺑﺮاي اﻣﻀﺎ ﻛﺮدن ﻳﻚ اﺳﻤﺒﻠﻲ ﺑﻪ ﻛﺎر روﻧـﺪ ،ﻣـﻲ ﺗﻮان از ﻧﻮﺷﺘﻪ ﺷﺪن آن اﺳﻤﺒﻠﻲ ﺗﻮﺳﻂ آن ﻓﺮد و ﻳﺎ ﺷﺮﻛﺖ ﻣﻄﻤﺌﻦ ﺷﺪ .اﺻﻮﻟﻲ ﻛﻪ در ﭘﺸﺖ اﻣﻀﺎ ﻛﺮدن اﻳﻦ اﺳﻤﺒﻠﻲ ﻫﺎ ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ ﻣﺒﺎﺣﺚ ﻛﺎﻣﻼً ﭘﻴﭽﻴﺪه اي ﻫﺴﺘﻨﺪ ،اﻣﺎ ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻛﺎر ﺑﺴﻴﺎر ﺳﺎده اﺳﺖ. ﻧﻜﺘﻪ :ﻳﻚ اﺳﻤﺒﻠﻲ ﻛﻪ ﺑﻪ ﺻﻮرت ﻗﻮي ﻧﺎﻣﮕﺬاري ﻣﻲ ﺷﻮد ﻧﻤﻲ ﺗﻮاﻧﺪ از ﻳﻚ اﺳﻤﺒﻠﻲ ﻛﻪ ﺑﻪ ﺻﻮرت ﻋﺎدي ﻧﺎﻣﮕﺬاري ﺷﺪه اﺳﺖ اﺳﺘﻔﺎده ﻛﻨﺪ ،زﻳﺮا ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻤﻜﻦ اﺳﺖ ﻛﻨﺘﺮل ﻧﺴﺨﻪ ﻫﺎ در اﻳﻦ اﺳﻤﺒﻠﻲ از ﺑﻴﻦ ﺑﺮود. ﻧﺎﻣﮕﺬاري ﻳﻚ اﺳﻤﺒﻠﻲ ﺑﻪ ﺻﻮرت ﻗﻮي ﺷﺎﻣﻞ دو ﻣﺮﺣﻠﻪ ﻣﻲ ﺷﻮد:
اﻳﺠﺎد ﻳﻚ ﺟﻔﺖ-ﻛﻠﻴﺪ ﻛﻪ ﺑﺮاي ﻧﺎﻣﮕﺬاري اﺳﻤﺒﻠﻲ ﺑﻪ ﻛﺎر ﻣﻲ رود .ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻛﺎر را در ﺑﺨـﺶ اﻣﺘﺤـﺎن ﻛﻨﻴـﺪ ﺑﻌـﺪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد. ﻛﻠﻴﺪ اﻳﺠﺎد ﺷﺪه را ﺑﻪ اﺳﻤﺒﻠﻲ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ اﺳﻤﺒﻠﻲ اﻳﻦ ﻛﻠﻴﺪ ﺑﺮاي ﻧﺎﻣﮕﺬاري ﻗﻮي آن ﺑـﻪ ﻛـﺎر ﻣﻲ رود.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻳﻚ ﺟﻔﺖ-ﻛﻠﻴﺪ
1ﺑﻪ اﻳﻦ ﻧﻮع اﺳﻤﺒﻠﻲ ﻫﺎ Strongly Named Assembliesﻧﻴﺰ ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد. Assembly Culture
2
٤٨٣
(1ﺑﺎ اﺳﺘﻔﺎده از ﻣﻨﻮي Startدر وﻳﻨﺪوز ﮔﺰﻳﻨﻪ ي All Programs Microsoft Visual Studio 2005 Visual Studio 2005 Tools Visual Studio 2005 Command Promptرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. (2در ﺧﻂ ﻓﺮﻣﺎﻧﻲ ﻛﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ،دﺳﺘﻮر زﻳﺮ را ﺗﺎﻳﭗ ﻛﻨﻴﺪ: sn –k InternetFavoritesKey.snk ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻓﺎﻳﻠﻲ ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﺟﻔـﺖ-ﻛﻠﻴـﺪ در داﻳﺮﻛﺘـﻮري ﻛـﻪ در آن ﻗـﺮار دارﻳـﺪ اﻳﺠـﺎد ﻣـﻲ ﺷـﻮد ) در اي ﺣﺎﻟـﺖ .(C:\Program Files\Microsoft Visual Studio 8\VC
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اﺟﺮاي ﺧﻂ ﻓﺮﻣﺎن وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻣﺤﻴﻄﻲ ﻫﻤﺎﻧﻨﺪ ﻣﺤﻴﻂ DOSﻧﻤﺎﻳﺶ داده ﺷﻮد ﻛﻪ اﻳﻦ ﻣﺤﻴﻂ ﺑـﺮاي ﻛـﺎر ﺑـﺎ اﺑﺰارﻫﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺗﻨﻈﻴﻢ ﺷﺪه اﺳﺖ .ﻳﻜﻲ از اﻳﻦ اﺑﺰارﻫﺎ ﻛﻪ ﺑﺮاي اﻳﺠﺎد ﺟﻔﺖ-ﻛﻠﻴﺪ ﺑﻪ ﻛﺎر ﻣﻲ رود ،ﻓﺎﻳـﻞ sn.exeاﺳـﺖ و ﺑﻪ ﺻﻮرت دﺳﺘﻮر snﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد .ﻫﻨﮕﺎم اﺟﺮاي اﻳﻦ دﺳﺘﻮر از ﺳﻮﻳﻴﭻ kاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﺗـﺎ ﺗﻌﻴـﻴﻦ ﻛﻨـﻴﻢ ﻛـﻪ ﻣـﻲ ﺧﻮاﻫﻴﻢ ﻳﻚ ﺟﻔﺖ-ﻛﻠﻴﺪ ﺟﺪﻳﺪ در ﻓﺎﻳﻞ ﻣﺸﺨﺺ ﺷﺪه اﻳﺠﺎد ﻛﻨﻴﻢ. ﺑﻌـــﺪ از اﺟـــﺮاي اﻳـــﻦ دﺳـــﺘﻮر ﻳـــﻚ ﺟﻔـــﺖ ﻛﻠﻴـــﺪ در ﻓﺎﻳـــﻞ InternetFavoritesKey.snkﺑـــﻪ آدرس C:\Program Files\Microsoft Visual Studio 8\VCاﻳﺠﺎد ﻣﻲ ﺷﻮد .اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ ﻓﺎﻳﻞ را ﺑﻪ ﻣﻜﺎن ﻣﻨﺎﺳﺐ ﺗﺮي ﻣﺎﻧﻨﺪ ﻓﻮﻟﺪر ﭘﺮوژه اﻧﺘﻘﺎل دﻫﻴﺪ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﻧﺤﻮه ي اﺳـﺘﻔﺎده از ﻓﺎﻳـﻞ را ﺑـﺮاي ﻧﺎﻣﮕﺬاري ﻗﻮي ﻳﻚ اﺳﻤﺒﻠﻲ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻧﺎﻣﮕﺬاري ﻗﻮي اﺳﻤﺒﻠﻲ InternetFavorites (1 (2 (3 (4
(5
در ﭘﻨﺠﺮه ي Explorer Solutionروي ﮔﺰﻳﻨﻪ ي Propertiesدر ﻗـﺴﻤﺖ ﻣﺮﺑـﻮط ﺑـﻪ ﭘـﺮوژه ي InternetFavoritesدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ. در ﻧﻮار ﺳﻤﺖ ﭼﭗ ﭘﻨﺠﺮه اي ﻛﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد روي ﻋﺒﺎرت Signingﻛﻠﻴﻚ ﻛﻨﻴﺪ )ﺷﻜﻞ .(4-12 در اي ﻗﺴﻤﺖ ﮔﺰﻳﻨﻪ ي ” “Sign the assemblyرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. در ﻗﺴﻤﺖ Choose a strong name key fileﻛﻠﻴـﻚ ﻛـﺮده و ﮔﺰﻳﻨـﻪ ي … Browseرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺳﭙﺲ در ﭘﻨﺠﺮه ي ﻧﻤﺎﻳﺶ داده ﺷﺪه ﺑﻪ آدرس ﻓﺎﻳﻞ ﺟﻔﺖ-ﻛﻠﻴﺪي ﻛﻪ اﻳﺠﺎد ﻛـﺮده اﻳـﺪ ﺑﺮوﻳـﺪ و آن ﻓﺎﻳـﻞ را اﻧﺘﺨﺎب ﻛﻨﻴﺪ. ﺑﺮﻧﺎﻣﻪ را ﻣﺠﺪداً ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻓﺎﻳﻞ dllﺗﻮﻟﻴﺪ ﺷﺪه ﺑﻪ ﺻﻮرت ﻗﻮي ﻧﺎﻣﮕﺬاري ﺧﻮاﻫﺪ ﺷﺪ.
٤٨٤
ﺷﻜﻞ 4-12
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﺟﻔﺖ ﻛﻠﻴﺪ را ﺑﻪ اﻳﻦ ﺻﻮرت ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﺪ ،ﻛﺎﻣﭙﺎﻳﻠﺮ ﻛﻠﻴﺪ ﻋﻤﻮﻣﻲ اﻳﻦ ﺟﻔﺖ ﻛﻠﻴﺪ را ﺑﻪ اﺳﻤﺒﻠﻲ اﺿﺎﻓﻪ ﻣـﻲ ﻛﻨﺪ .ﻫﻤﭽﻨﻴﻦ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻠﻴﺪ ﺧﺼﻮﺻﻲ ،ﻣﺤﺘﻮﻳﺎت اﺳﻤﺒﻠﻲ را ﺑﻪ ﻧﺤﻮي ﺧﺎص ﻛﺪ ﮔﺬاري ﻛﺮده و ﻣﺘﻦ ﻛﺪ ﺷﺪه را در اﺳﻤﺒﻠﻲ ﻗﺮار ﻣﻲ دﻫﺪ. در ﺳﻴﺴﺘﻢ رﻣﺰﻧﮕﺎري ﺑﺎ اﺳﺘﻔﺎده از ﻛﻠﻴﺪﻫﺎي ﻋﻤﻮﻣﻲ-ﺧﺼﻮﺻﻲ ،ﻳﻚ ﭘﻴﻐﺎم ﺑﺎ اﺳﺘﻔﺎده از ﻳﻜﻲ از اﻳﻦ ﻛﻠﻴﺪ ﻫﺎ رﻣﺰ ﮔﺬاري ﻣـﻲ ﺷـﻮد اﻣـﺎ ﺑﺮاي ﺑﺎز ﻛﺮدن رﻣﺰ آن ﺑﺎﻳﺪ از ﻛﻠﻴﺪ دﻳﮕﺮ اﺳﺘﻔﺎده ﻛﺮد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﻛﻠﻴﺪ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﻫﻢ ﻋﻤﻞ ﻗﻔـﻞ ﻛـﺮدن و ﻫـﻢ ﻋﻤﻞ ﺑﺎز ﻛﺮدن ﭘﻴﻐﺎم را اﻧﺠﺎم دﻫﻴﺪ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ در اﻳﻦ روش ﻳﻚ ﻣﺘﻦ را ﺑﺎ اﺳﺘﻔﺎده از ﻛﻠﻴﺪ اول ﻗﻔﻞ ﻛﻨﻴﺪ ،ﺗﻤﺎم اﻓﺮادي ﻛﻪ ﻛﻠﻴـﺪ دوم را در اﺧﺘﻴﺎر دارﻧﺪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﻣﺘﻦ ﻗﻔﻞ ﺷﺪه را ﺑﺨﻮاﻧﻨﺪ ،اﻣﺎ ﻧﻤﻲ ﺗﻮاﻧﻨﺪ آن را ﺗﻐﻴﻴﺮ داده ،ﻣﺠﺪداً ﻗﻔﻞ ﻛﺮده و ﺗﻮزﻳﻊ ﻛﻨﻨﺪ. ﺑﺮاي اﻣﻀﺎي اﺳﻤﺒﻠﻲ ﻫﺎ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ روش ﺑﻪ اﻳﻦ ﺻﻮرت ﻋﻤﻞ ﻣﻲ ﺷﻮد ﻛﻪ ﺑﻌﺪ از اﻳﺠﺎد ﻓﺎﻳﻞ اﺳﻤﺒﻠﻲ ،ﻣﺤﺘﻮﻳﺎت آن را ﺑﺎ اﺳﺘﻔﺎده از ﻛﻠﻴﺪ ﺧﺼﻮﺻﻲ ﻗﻔﻞ ﻛﺮده ،ﺳﭙﺲ ﻓﺎﻳﻞ ﻗﻔﻞ ﺷﺪه را ﺑﻪ ﻫﻤﺮاه ﻛﻠﻴﺪ ﻋﻤﻮﻣﻲ ﺗﻮزﻳﻊ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺗﻤﺎم اﻓﺮاد ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﺎ اﺳـﺘﻔﺎده از ﻛﻠﻴﺪ ﻋﻤﻮﻣﻲ اﻳﻦ ﻓﺎﻳﻞ را ﺑﺎز ﻛﺮده و از آن اﺳﺘﻔﺎده ﻛﻨﻨﺪ .اﻣﺎ ﻧﻤﻲ ﺗﻮاﻧﻨﺪ آن را ﺗﻐﻴﻴﺮ داده و ﻣﺠﺪداً ﻗﻔﻞ ﻛﻨﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ روش ﻣﻲ ﺗﻮان ﻣﻄﻤﺌﻦ ﺷﺪ ﻛﻪ ﻓﺮدي ﺑﻪ ﺟﺰ دارﻧﺪه ي ﻛﻠﻴﺪ ﺧﺼﻮﺻﻲ ﻧﻤﻲ ﺗﻮاﻧﺪ ﻓﺎﻳﻞ را ﺗﻐﻴﻴﺮ دﻫﺪ. ﺑﺮرﺳﻲ اﻳﻦ ﻣﻮارد ﺗﻮﺳﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻧﺠﺎم ﻣﻲ ﺷﻮد .ﺑﻪ اﻳﻦ ﺻﻮرت ﻛﻪ اﮔﺮ ﻓﺎﻳﻠﻲ ﻛﻪ ﺑﻪ ﺻﻮرت ﻗﻮي ﻧﺎﻣﮕﺬاري ﺷﺪه اﺳـﺖ ﺗﻮﺳـﻂ اﻓﺮاد دﻳﮕﺮي ﺗﻐﻴﻴﺮ داده ﺷﻮد ،وﻳﮋوال اﺳﺘﻮدﻳﻮ از اﺟﺮاي اﻳﻦ ﻓﺎﻳﻞ ﺧﻮدداري ﺧﻮاﻫﺪ ﻛﺮد .اﻟﺒﺘﻪ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﺣﺠﻢ ﻳﻚ اﺳـﻤﺒﻠﻲ ﻣﻌﻤـﻮﻻً زﻳﺎد اﺳﺖ و ﻗﻔﻞ ﮔﺬاري و ﺑﺎز ﻛﺮدن آن ﻣﻤﻜﻦ اﺳﺖ ﺑﺎﻋﺚ ﻛﺎﻫﺶ ﺳﺮﻋﺖ ﺷﻮد ،در اﻳـﻦ روش ﻗـﺴﻤﺖ ﺧﺎﺻـﻲ از ﻓﺎﻳـﻞ اﺳـﻤﺒﻠﻲ ﻛـﺪ ﮔﺬاري ﻣﻲ ﺷﻮد ﻛﻪ اﻟﺒﺘﻪ اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﻗﺎﺑﻞ ﺗﺸﺨﻴﺺ ﻧﻴﺴﺖ و ﺑﻪ ﺻﻮرت ﭘﺮاﻛﻨﺪه اﻧﺘﺨﺎب ﻣﻲ ﺷﻮد.
٤٨٥
ﻧﺴﺨﻪ ﻫﺎي ﻳﻚ اﺳﻤﺒﻠﻲ: ﻧﺴﺨﻪ ي ﻳﻚ ﻓﺎﻳﻞ اﻏﻠﺐ ﺗﺮﺗﻴﺐ ﺗﻮﻟﻴﺪ آن را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .ﻫﻨﮕﺎم اﻳﺠﺎد اﺳﻤﺒﻠﻲ در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﻧﮕـﺮان ﻧـﺴﺨﻪ ي آن ﺑﺎﺷﻴﺪ ،زﻳﺮا وﻳﮋوال C#آن را ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﻨﺪ .ﻫﺮ ﺑﺎر ﻛﻪ ﻳﻚ ﻓﺎﻳﻞ اﺳﻤﺒﻠﻲ را ﻛﺎﻣﭙﺎﻳﻞ ﻣﻲ ﻛﻨﻴﺪ ﻋﺪدي ﻛـﻪ ﺑﻪ ﻋﻨﻮان ﻧﺴﺨﻪ ي ﻓﺎﻳﻞ ﺑﻪ ﻛﺎر ﻣﻲ رود ﺗﻮﺳﻂ وﻳﮋوال C#ﺑﻪ روز رﺳﺎﻧﺪه ﻣﻲ ﺷﻮد ﺗﺎ ﺷﻤﺎره ي ﻧﺴﺨﻪ ي ﺟﺪﻳﺪ را اﻋﻼم ﻛﻨﺪ. ﻋﺪدي ﻛﻪ ﺑﻪ ﻋﻨﻮان ﻧﺴﺨﻪ ي ﻳﻚ اﺳﻤﺒﻠﻲ ﺑﻪ ﻛﺎر ﻣﻲ رود از ﭼﻬﺎر ﺑﺨﺶ ﺗﺸﻜﻴﻞ ﺷـﺪه اﺳـﺖ Build ،Minor ،Major :و Solutionروي ﻓﺎﻳــﻞ .Revisionﺑــﺮاي ﻣــﺸﺎﻫﺪه ي ﻣﻘــﺪار اﻳــﻦ اﻋــﺪاد در ﭘﻨﺠــﺮه ي Explorer Propertiesﻣﺮﺑﻮط ﺑﻪ ﭘﺮوژه دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﭘﻨﺠﺮه ي ﻧﻤﺎﻳﺶ داده ﺷﺪه در ﺷﻜﻞ 4-12ﻣﺠﺪداً ﻇﺎﻫﺮ ﺷﻮد .ﺳﭙﺲ روي Assembly ﻗـــﺴﻤﺖ Applicationﻛﻠﻴـــﻚ ﻛـــﺮده و در ﭘﻨﺠـــﺮه ي ﻧﻤـــﺎﻳﺶ داده ﺷـــﺪه روي دﻛﻤـــﻪ ي Informationﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛـﺎدر Assembly Informationﻣـﺸﺎﺑﻪ ﺷـﻜﻞ 5-12ﻧﻤـﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
ﺷﻜﻞ 5-12 ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺗﺼﻮﻳﺮ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﺳﺖ ،ﺑﺎ ﻫﺮ ﺑﺎر ﻛﺎﻣﭙﺎﻳﻞ ﻛﺮدن ﺷﻤﺎره ي ﻣﺮﺑﻮط ﺑﻪ ﻗﺴﻤﺖ Majorﺑﺮاﺑﺮ ﺑﺎ 1و ﺷـﻤﺎره ي ﻣﺮﺑﻮط ﺑﻪ ﻗﺴﻤﺖ Minorﺑﺮاﺑﺮ ﺑﺎ 0اﺳﺖ .ﺑﻘﻴﻪ ﺷﻤﺎره ﻫﺎ ﻧﻴﺰ ﺑﻪ وﺳﻴﻠﻪ ي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺗﻨﻈﻴﻢ ﻣﻲ ﺷﻮﻧﺪ ﺗﺎ در ﻫﺮ ﺑﺎر ،ﻓـﺎﻳﻠﻲ ﻛـﻪ ﺗﻮﻟﻴﺪ ﻣﻲ ﺷﻮد ﺑﻪ ﺻﻮرت ﻣﻨﺤﺼﺮ ﺑﻪ ﻓﺮد ﺑﺎﺷﺪ .اﻟﺒﺘﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻋﺪاد ﻣﻮﺟﻮد در اﻳﻦ ﻗﺴﻤﺖ را ﺧﻮدﺗﺎن وارد ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺻﻮرت وﻳـﮋوال اﺳﺘﻮدﻳﻮ آﻧﻬﺎ را ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ ﺗﻐﻴﻴﺮ ﻧﺨﻮاﻫﺪ داد و اﻳﻦ اﻋﺪاد ﺛﺎﺑﺖ ﻣﻲ ﻣﺎﻧﻨﺪ ﺗﺎ ﻣﺠﺪداً آﻧﻬﺎ ﺗﻐﻴﻴﺮ دﻫﻴﺪ.
٤٨٦
ﻧﻜﺘﻪ :ﺗﻮﺻﻴﻪ ﻣﻲ ﺷﻮد ﻛﻪ ﻫﻤﻮاره ﻧﺴﺨﻪ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﺻﻮرت دﺳﺘﻲ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ،ﺑﻪ ﺧﺼﻮص اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﺮﻧﺎﻣـﻪ را ﺗﻮزﻳﻊ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮ ﺷﻤﺎره ي ﻧﺴﺨﻪ ﻫﺎ ﻛﻨﺘﺮل ﻛﺎﻣﻞ داﺷﺘﻪ ﺑﺎﺷﻴﺪ و از ﺑﺮوز اﺷﻜﺎﻻﺗﻲ ﻛﻪ ﻣﻤﻜـﻦ اﺳـﺖ ﺑـﺎ ﺗﻨﻈـﻴﻢ اﺗﻮﻣﺎﺗﻴﻚ ﺷﻤﺎره ﻧﺴﺨﻪ ي ﺑﺮﻧﺎﻣﻪ ﺑﻪ وﺟﻮد آﻳﺪ ﻫﻢ ﺟﻠﻮﮔﻴﺮي ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺛﺒﺖ ﻛﺮدن ﻳﻚ اﺳﻤﺒﻠﻲ: ﻫﺮ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ ﺗﺤﺖ .NETﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد ،ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺗﻤﺎم ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼﺳﻲ ﻛﻪ در ﻳﻚ ﻛﺎﻣﭙﻴﻮﺗﺮ وﺟـﻮد دارد دﺳﺘﺮﺳـﻲ داﺷﺘﻪ ﺑﺎﺷﺪ .ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﺪ از ﻛﻼﺳﻬﺎي درون ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس در ﺑﺮﻧﺎﻣﻪ ي ﺧـﻮد اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ اﺑﺘـﺪا ﺑﺎﻳـﺪ ﻓﺎﻳـﻞ dll ﻣﺮﺑﻮط ﺑﻪ آن ﻛﺘﺎﺑﺨﺎﻧﻪ را در ﻓﻮﻟﺪر ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻗﺮار داده و ﺳﭙﺲ از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻳﻦ ﻣﻮرد در راﺑﻄﻪ ﺑﺎ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫـﺎي ﻛﻼﺳـﻲ ﻛﻪ در ﭼﻨﺪ ﺑﺮﻧﺎﻣﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ ﻣﺸﻜﻼﺗﻲ را اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻛﺘﺎﺑﺨﺎﻧـﻪ ي ﻛـﻼس InternetFavorites.dllرا ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ اﻳﺠﺎد ﻛﺮدﻳﻢ در دو ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﻣﺠﺒـﻮر ﺧﻮاﻫﻴﺪ ﺑﻮد ﻛﻪ ﻓﺎﻳﻞ dllاﻳﻦ ﻛﺘﺎﺑﺨﺎﻧﻪ را در ﻓﻮﻟﺪر ﻫﺮ دو ﺑﺮﻧﺎﻣﻪ ﻛﭙﻲ ﻛﻨﻴﺪ. در اﻳﻦ ﺣﺎﻟﺖ ﻓﺮض ﻛﻨﻴﺪ ﺧﻄﺎﻳﻲ در اﻳﻦ ﻛﺘﺎﺑﺨﺎﻧﻪ اﻳﺠﺎد ﺷﻮد و ﺑﺮاي ﺗﺼﺤﻴﺢ آن ﺑﺨﻮاﻫﻴﺪ آن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ ،و ﻳـﺎ ﺣﺘـﻲ ﺑـﻪ ﻫـﺮ دﻟﻴـﻞ دﻳﮕﺮي ﻣﺠﺒﻮر ﺑﻪ ﺗﻐﻴﻴﺮ ﻛﻼﺳﻬﺎي اﻳﻦ ﻛﺘﺎﺑﺨﺎﻧﻪ ﺷﻮﻳﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺠﺒﻮر ﺧﻮاﻫﻴﺪ ﺑﻮد ﺑﻌﺪ از اﻳﻨﻜﻪ ﻓﺎﻳﻞ dllﺟﺪﻳﺪ را اﻳﺠﺎد ﻛﺮدﻳﺪ، آن را در ﻓﻮﻟﺪر ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ از اﻳﻦ ﻛﺘﺎﺑﺨﺎﻧﻪ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﻗﺮار دﻫﻴﺪ ﻛﻪ ﻣﺴﻠﻤﺎً اﻳﻦ ﻛﺎر ﻣﻨﻄﻘﻲ ﺑﻪ ﻧﻈﺮ ﻧﻤﻲ رﺳﺪ. ﺑﺮاي رﻓﻊ اﻳﻦ ﻣﺸﻜﻞ ﺑﻬﺘﺮ اﺳﺖ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼﺳﻲ ﻛﻪ ﺑﻪ ﺻﻮرت ﻋﻤﻮﻣﻲ ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ ﻫـﺎ ﻣـﻮرد اﺳـﺘﻔﺎده ﻗـﺮار ﻣـﻲ ﮔﻴﺮﻧـﺪ را در ﻓﻮﻟﺪري ﺧﺎص ﻗﺮار دﻫﻴﻢ و ﺳﭙﺲ ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﺘﻮاﻧﻨﺪ ﺑﻪ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس ﻣﻮﺟﻮد در آن ﻓﻮﻟﺪر دﺳﺘﺮﺳـﻲ داﺷـﺘﻪ ﺑﺎﺷـﻨﺪ و از آن اﺳﺘﻔﺎده ﻛﻨﻨﺪ .اﻳﻦ ﻓﻮﻟﺪر ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻓﺼﻞ دوم ﻫﻢ ﻣﻘﺪاري ﺑﺎ آن آﺷﻨﺎ ﺷﺪﻳﻢ GAC1 ،ﻧﺎم دارد .ﻫﺮ ﺑﺮﻧﺎﻣـﻪ در .NETﻣـﻲ ﺗﻮاﻧـﺪ ﻋﻼوه ﺑﺮ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس ﻣﻮﺟﻮد در ﻓﻮﻟﺪر ﺧﻮد ﺑﺮﻧﺎﻣﻪ ،ﺑﻪ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛـﻼس ﻣﻮﺟـﻮد در GACﻧﻴـﺰ دﺳﺘﺮﺳـﻲ داﺷـﺘﻪ ﺑﺎﺷـﺪ. ﻫﻤﭽﻨﻴﻦ اﺳﻤﺒﻠﻲ ﻫﺎﻳﻲ ﻛﻪ داراي ﻧﺎﻣﻬﺎي ﻳﻜﺴﺎن ﺑﺎﺷﻨﺪ وﻟﻲ از ﻧﻈﺮ ﻧﺴﺨﻪ و ﻳﺎ ﻧﻮﻳﺴﻨﺪه و ﻳﺎ … ﺗﻔﺎوت داﺷﺘﻪ ﺑﺎﺷﻨﺪ ﻧﻴﺰ در اﻳﻦ ﻓﻮﻟﺪر ﺑﻪ ﺻـــﻮرت درﺳـــﺖ ﻧﮕـــﻪ داري ﺷـــﺪه و ﺑـــﺎ ﻳﻜـــﺪﻳﮕﺮ اﺷـــﺘﺒﺎه ﻧﺨﻮاﻫﻨـــﺪ ﺷـــﺪ .اﻳـــﻦ ﻓﻮﻟـــﺪر در وﻳﻨـــﺪوز XPدر آدرس C:\Windows\Assemblyو در وﻳﻨﺪوز 2000در آدرس C:\WinNT\Assemblyﻗﺮار دارد. اﻣﺎ ﺑﺮاي ﻗﺮار دادن ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس در اﻳﻦ ﻗﺴﻤﺖ ،ﻧﺒﺎﻳﺪ آن را ﻫﻤﺎﻧﻨﺪ ﻓﺎﻳﻞ ﻫﺎي ﻋﺎدي در اﻳﻦ ﻓﻮﻟﺪر ﻛﭙﻲ ﻛـﺮد .ﺑﻠﻜـﻪ ﺑﺎﻳـﺪ از اﺑﺰار ﺧﺎﺻﻲ ﺑﻪ ﻧﺎم gacutilاﺳﺘﻔﺎده ﻛﺮد ﻛﻪ ﻧﺤﻮه ﻛﺎر آن در ﻗﺴﻤﺖ ﺑﻌﺪي ﺗﻮﺿﻴﺢ داده ﺷﺪه اﺳﺖ.
اﺑﺰار :GacUtil Gacutilﺑﺮﻧﺎﻣﻪ اي اﺳﺖ ﻛﻪ ﻫﻤﺮاه ﺑﺎ ﭼﺎرﭼﻮب .NETاراﺋﻪ ﺷﺪه اﺳﺖ و ﺑﺮاي ﻗـﺮار دادن و ﻳـﺎ ﺣـﺬف ﻛـﺮدن ﻳـﻚ ﻓﺎﻳـﻞ در GACﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد .اﻳﻦ اﺑﺰار ﻧﻴﺰ ﻣﺎﻧﻨﺪ اﺑﺰار snﺗﻮﺳﻂ ﺧﻂ ﻓﺮﻣﺎن ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ اﺳﺖ. ﺑﺮاي ﻛﺎر ﺑﺎ اﻳﻦ اﺑﺰار ﻣﺠـﺪداً ﺧـﻂ ﻓﺮﻣـﺎن Visual Studio 2005 Command Promptرا ﺑـﺎ اﺳـﺘﻔﺎده از ﻣﻨﻮي Startﺑﺎز ﻛﺮده و ﺳﭙﺲ ﺑﻪ ﻓﻮﻟﺪر binدر ﻓﻮﻟﺪري ﻛﻪ ﺑﺮﻧﺎﻣـﻪ ي InternetFavoritesدر آن ﻗـﺮار دارد ﺑﺮوﻳﺪ .2ﺑﺮاي ﻧﺼﺐ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس InternetFavorites.dllدر GACدﺳﺘﻮر زﻳﺮ را وارد ﻛﻨﻴﺪ: Gacutil –i InternetFavorites.dll Global Assembly Cache
1
2ﺑﺮاي ﺣﺮﻛﺖ در ﺑﻴﻦ ﻓﻮﻟﺪر ﻫﺎ در ﺧﻂ ﻓﺮﻣﺎن ﻣﻲ ﺗﻮاﻧﻴﺪ از دﺳﺘﻮر cdاﺳﺘﻔﺎده ﻛﻨﻴﺪ.
٤٨٧
ﺑﺎ اﺳﺘﻔﺎده از ﺳﻮﻳﻴﭻ Iﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ اﺳﻤﺒﻠﻲ را در GACﻗﺮار دﻫﻴﺪ .ﺑﺮاي ﺣﺬف اﺳﻤﺒﻠﻲ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺳﻮﻳﻴﭻ uﺑـﻪ ﺻـﻮرت زﻳـﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ: Gacutil –u InternetFavorites.dll ﺧﻮب ،ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس InternetFavorites.dllدر GACﻧﺼﺐ ﺷﺪه اﺳﺖ و ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻌﺪ از اﺿﺎﻓﻪ ﻛﺮدن ارﺟﺎﻋﻲ از اﻳﻦ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮدﺗﺎن از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ در ﻗـﺴﻤﺘﻬﺎي ﻗﺒـﻞ ﻣـﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ارﺟﺎع ﺑﻪ ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺑﺎﻳـﺪ از ﻗـﺴﻤﺖ .NETدر ﭘﻨﺠـﺮه ي Add Reference اﺳﺘﻔﺎده ﻛﻨﻴﻢ )ﺷﻜﻞ .(12-3اﻣﺎ ﻧﻜﺘﻪ اي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ وﺟﻮد دارد اﻳﻦ اﺳﺖ ﻛﻪ ﻓﻘﻂ ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛـﻼس ﺑـﻪ GACﻧﻤﻲ ﺗﻮان آن را در ﻟﻴﺴﺖ ﻣﻮﺟﻮد در ﭘﻨﺠﺮه ي Add Referenceﻧﻴﺰ ﻣﺸﺎﻫﺪه ﻛﺮد و از آن در ﺑﺮﻧﺎﻣـﻪ اﺳـﺘﻔﺎده ﻛـﺮد، ﺑﻠﻜﻪ ﺑﺮاي ﻧﻤﺎﻳﺶ داده ﺷﺪن ﻓﺎﻳﻞ ﻣﺮﺑﻮط ﺑﻪ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس در اﻳﻦ ﻟﻴﺴﺖ ﺑﺎﻳﺪ آن را در رﺟﻴﺴﺘﺮي وﻳﻨﺪوز ﻧﻴﺰ ﺛﺒﺖ ﻛﻨﻴﻢ. دﻟﻴﻞ اﻳﻦ ﻣﻮرد ﻫﻢ اﻳﻦ اﺳﺖ ﻛﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮاي ﮔﺮدآوري ﻧﺎم اﺳﻤﺒﻠﻲ ﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻟﻴﺴﺖ ﻋـﻼوه ﺑـﺮ ﺟـﺴﺘﺠﻮي ،GAC ﺑﻌﻀﻲ از ﻛﻠﻴﺪ ﻫﺎي رﺟﻴﺴﺘﺮي را ﻧﻴﺰ ﺟﺴﺘﺠﻮ ﻣﻲ ﻛﻨﺪ ﺗﺎ ﻣﺴﻴﺮ واﻗﻌﻲ اﺳﻤﺒﻠﻲ ﻫـﺎي ﻣـﻮرد ﻧﻈـﺮ را ﭘﻴـﺪا ﻛﻨـﺪ .ﭘـﺲ ﺑﺎﻳـﺪ ﻛﻠﻴـﺪي را در رﺟﻴﺴﺘﺮي ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ ﺗﺎ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺘﻮاﻧﺪ اﺳﻤﺒﻠﻲ InternetFavoritesرا ﻧﻴﺰ ﺑﺒﻴﻨﺪ و در اﻳﻦ ﻟﻴﺴﺖ ﻗـﺮار دﻫـﺪ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻛﺎر را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻗﺮار دادن ﻧﺎم اﺳﻤﺒﻠﻲ در ﻟﻴﺴﺖ ﻣﻮﺟﻮد در ﻛﺎدر Add Reference (1ﺑﺮ روي ﻣﻨﻮي Startﻛﻠﻴﻚ ﻛﺮده و ﮔﺰﻳﻨﻪ ي Runرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. (2در ﭘﻨﺠﺮه ي Runﻋﺒﺎرت regeditرا وارد ﻛﺮده و ﻛﻠﻴﺪ Enterرا ﻓﺸﺎر دﻫﻴﺪ ﺗﺎ ﭘﻨﺠـﺮه ي Registry Editorﻧﻤﺎﻳﺶ داده ﺷﻮد. (3در اﻳﻦ ﭘﻨﺠﺮه ﺑﺎ اﺳﺘﻔﺎده از ﻗﺴﻤﺖ ﺳﻤﺖ ﭼﭗ ﺑﻪ ﻛﻠﻴﺪ زﻳﺮ ﺑﺮوﻳﺪ: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Assembl \yFolders (4ﺑﺮ روي ﻓﻮﻟﺪر AssemblyFoldersﻛﻠﻴﻚ راﺳﺖ ﻛﻨﻴﺪ و ﮔﺰﻳﻨﻪ ي New Keyرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. (5ﻛﻠﻴﺪي ﺑﺎ ﻧﺎم دﻟﺨﻮاه اﻳﺠﺎد ﻛﻨﻴﺪ .در اﻳﻦ ﻗﺴﻤﺖ ﻣﺎ ﻧﺎم Developer Assembliesرا وارد ﻣﻲ ﻛﻨﻴﻢ. (6در ﻗﺴﻤﺖ ﺳﻤﺖ راﺳﺖ ﭘﻨﺠﺮه روي ﮔﺰﻳﻨﻪ ي ) (Defaultدو ﺑﺎر ﻛﻠﻴﻚ ﻛﺮده و آدرس ﻳﻚ ﻓﻮﻟـﺪر را در ﭘﻨﺠـﺮه اي ﻛﻪ ﺑﺎز ﻣﻲ ﺷﻮد وارد ﻛﻨﻴـﺪ .در اﻳـﻦ ﻗـﺴﻤﺖ ﻣـﺎ آدرس C:\Developer Assembliesرا وارد ﻛـﺮدﻳﻢ )ﺷﻜﻞ .(6-12
٤٨٨
ﺷﻜﻞ 6-12 (7ﺣﺎل ﭘﻨﺠﺮه ي Windows Explorerرا ﺑﺎز ﻛﺮده و آدرﺳﻲ ﻛﻪ در ﻣﺮﺣﻠﻪ ي ﻗﺒﻞ وارد ﻛﺮدﻳـﺪ را اﻳﺠـﺎد ﻛﻨﻴـﺪ )اﻟﺒﺘﻪ اﮔﺮ وﺟﻮد ﻧﺪارد( .ﺳﭙﺲ ﻓﺎﻳﻞ InternetFavorites.dllرا در اﻳﻦ آدرس ﻛﭙﻲ ﻛﻨﻴﺪ. (8ﺑﺮاي اﻳﻨﻜﻪ ﺗﻨﻈﻴﻤﺎﺗﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﻳﺠﺎد ﻛﺮدﻳﻢ اﺛﺮ ﻛﻨﻨﺪ ،ﻣﻜﻦ اﺳﺖ ﻣﺠﺒﻮر ﺑﺎﺷـﻴﺪ ﻛـﻪ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ را ﺑﺒﻨﺪﻳـﺪ و ﻣﺠﺪداً ﺑﺎز ﻛﻨﻴﺪ .ﺑﻌﺪ از اﻳﻦ ﻛﺎر ﺑﺮ روي ﻧﺎم ﭘﺮوژه در ﭘﻨﺠﺮه ي Solution Explorerﻛﻠﻴﻚ ﻛﺮده و ﮔﺰﻳﻨـﻪ Addرا اﻧﺘﺨــﺎب ﻛﻨﻴــﺪ .ﺑــﻪ اﻳــﻦ ﺗﺮﺗﻴــﺐ ﻣــﺸﺎﻫﺪه ﺧﻮاﻫﻴــﺪ ﻛــﺮد ﻛــﻪ ﻧــﺎم اﺳــﻤﺒﻠﻲ ي Reference InternetFavoritesﻧﻴﺰ در ﻟﻴﺴﺖ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد )ﺷﻜﻞ .(7-12
ﺷﻜﻞ 7-12
٤٨٩
ﻃﺮاﺣﻲ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس: ﺗﺎﻛﻨﻮن ﻣﺘﻮﺟﻪ ﺷﺪه اﻳﺪ ﻛﻪ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس ﭼﻪ ﻓﻮاﻳﺪي دارﻧﺪ و ﭼﮕﻮﻧﻪ و در ﭼﻪ ﻗﺴﻤﺘﻬﺎﻳﻲ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ .ﻫﻤﭽﻨﻴﻦ ﻣﻔﺎﻫﻴﻢ ﻛﻼﺳﻬﺎ ،اﺷﻴﺎ و ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس را ﻧﻴﺰ درك ﻛﺮده اﻳﺪ. ﻗﺒﻞ از ﻃﺮاﺣﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﺑﻪ دﻗﺖ ﺑﺮرﺳﻲ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﻮﺟﻪ ﺷﻮﻳﺪ ﻛﻪ دﻗﻴﻘﺎً ﻣﻲ ﺧﻮاﻫﻴﺪ ﭼﻪ ﭼﻴﺰي را ﻃﺮاﺣﻲ ﻛﻨﻴﺪ .ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﻣﻌﻤﺎر ﻛﻪ ﻣﻲ ﺧﻮاﻫﺪ ﻳﻚ ﺧﺎﻧﻪ را ﻃﺮاﺣﻲ ﻛﻨﺪ ،ﺑﺎﻳﺪ اﺑﺘﺪا ﺑﺪاﻧﻴﺪ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻫﺮ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ ﭼﻪ ﻛﺎري را و ﺑﻪ ﭼﻪ ﻧﺤـﻮ اﻧﺠـﺎم دﻫـﺪ ﺗـﺎ ﺑﺘﻮاﻧﻴﺪ ﻃﺮح درﺳﺘﻲ از ﺑﺮﻧﺎﻣﻪ را اﻳﺠﺎد ﻛﻨﻴﺪ. ﻣﻌﻤﻮﻻً ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻃﺮاﺣﺎن ﻧﺮم اﻓﺰار ﻣﻲ ﺧﻮاﻫﻨﺪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﻃﺮاﺣﻲ ﻛﺮده ،ﺗﺤﻠﻴﻞ ﻛﻨﻨﺪ و ﻳﺎ ﻳﻚ ﻗﺎﻟﺐ ﻛﻠﻲ ﺑﺮاي ﻛﺪ ﻫﺎي آن ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﻨﻨﺪ از اﺑﺰارﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ Microsoft Visioﺑﺮاي ﺗﺮﺳﻴﻢ اﻳﻦ ﻣﻮارد اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ ﻣﻌﻤﻮﻻً ﺑﺮاي ﻛﺎر ﺑﺎ وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﻧﻴﺰ ﺗﻨﻈﻴﻢ ﺷﺪه اﻧﺪ Visio .داراي اﻧﻮاع ﻣﺨﺘﻠﻔﻲ از ﺳﻤﺒﻞ ﻫﺎ اﺳﺖ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از آﻧﻬﺎ ﻣﻲ ﺗﻮان ﺑـﺮ اﺳـﺎس ﻗﻮاﻋـﺪ ﻳﻜﻲ از ﻣﺪﻫﺎي ﺗﺮﺳﻴﻢ ﻃﺮح ﺑﺮﻧﺎﻣﻪ ،ﻃﺮح ﻛﻠﻲ ،ﻓﻠﻮ ﭼﺎرت و ﻳﺎ اﻧﻮاع دﻳﮕﺮ دﻳﺎﮔﺮام ﻫﺎ را ﺑﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﺮد .ﻳﻜﻲ از ﻣﻌﺮوﻓﺘـﺮﻳﻦ ﻣﺪﻟﻬﺎي ﺗﺮﺳﻴﻢ ﻃﺮح و ﻣﺪل ﺑﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ UML1 ،اﺳﺖ ﻛﻪ ﺑﻴﺸﺘﺮﻳﻦ ﻛﺎرﺑﺮد را در ﻃﺮاﺣﻲ و ﻣﻌﻤﺎري ﻳـﻚ ﻧـﺮم اﻓـﺰار داردUML . ﺷﺎﻣﻞ ﭼﻨﺪﻳﻦ ﺳﻤﺒﻞ و ﻋﻼﻣﺖ اﺳﺖ ﻛﻪ ﻫﺮ ﻛﺪام در ﺗﺮﺳﻴﻢ ﻃﺮح ﻛﻠﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﻔﻬﻮم و ﻣﻌﻨﻲ ﺧﺎﺻﻲ را ﻣﻲ رﺳﺎﻧﻨﺪ. ﻧﺤﻮه اﺳﺘﻔﺎده از UMLدر ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻮردي اﺳﺖ ﻛﻪ ﺑﻴﺸﺘﺮ در ﻣﺒﺎﺣﺚ ﻣﻬﻨﺪﺳﻲ ﻧﺮم اﻓﺰار ﻣﻮرد ﺑﺮرﺳﻲ ﻗﺮار ﻣﻲ ﮔﻴﺮد و در اﻳـﻦ ﻛﺘﺎب ﻧﻤﻲ ﺧﻮاﻫﻴﻢ در اﻳﻦ ﻣﻮرد ﺻﺤﺒﺖ ﻛﻨﻴﻢ .اﻣﺎ ﺑﻬﺘﺮ اﺳﺖ ﺑﺪاﻧﻴﺪ ﻛﻪ ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﻳﻚ ﻛﻼس اﮔﺮ ﺑﻪ ﺳﻮاﻻﺗﻲ ﻣﺎﻧﻨﺪ "اﻳـﻦ ﻛـﻼس ﻳﺎﺑﺪ داراي ﭼﻪ ﻣﺘﺪ ﻫﺎ و ﻳﺎ ﭼﻪ ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ ﺑﺎﺷﺪ؟" و ﻳﺎ "آﻳﺎ ﻛﻼس ﺑﺎﻳﺪ ﻋﻼوه ﺑﺮ ﻣﺘﺪ داراي ﺧﺎﺻﻴﺖ ﻧﻴـﺰ ﺑﺎﺷـﺪ؟" ﭘﺎﺳـﺦ درﺳـﺘﻲ داده ﻧﺸﻮد ﻣﻤﻜﻦ اﺳﺖ ﻛﻪ ﺑﺎز ﻫﻢ ﻛﻼس ﺑﺘﻮاﻧﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد ،اﻣﺎ ﻣﻄﻤﺌﻨﺎ ﺑﻪ ﺻﻮرت ﻛﺎرآﻣﺪ ﻋﻤﻞ ﻧﺨﻮاﻫﺪ ﻛﺮد. ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺷﺎﻣﻞ 20ﻛﻼس اﺳﺖ ﻛﻪ ﻫﺮ ﻳﻚ 40ﻣﺘﺪ و ﻳﺎ ﺧﺎﺻﻴﺖ دارﻧﺪ و ﻫﺮ ﻣﺘﺪ ﻧﻴﺰ ﺣـﺪاﻗﻞ 15ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ .ﭼﻨﻴﻦ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼﺳﻲ ﻣﺴﻠﻤﺎً ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺳﺎدﮔﻲ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد .در ﺣﻘﻴﻘﺖ ﺑﺎﻳﺪ ﺑﮕﻮﻳﻢ ﻛـﻪ ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﻫﻴﭽﮕﺎه ﻧﺒﺎﻳﺪ ﺑﻪ اﻳﻦ ﺻﻮرت ﻃﺮاﺣﻲ ﺷﻮد. در ﻋﻮض ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﻳﻚ ﻛﻼس ﻫﻤﻮاره ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﻗﺎﻧﻮن زﻳﺮ را رﻋﺎﻳﺖ ﻛﻨﻴﺪ :ﺳﺎدﮔﻲ .ﺗﻘﺮﻳﺒﺎ ﻣﻲ ﺗﻮان ﮔﻔﺖ ﻛﻪ ﺳﺎدﮔﻲ ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﻓﺎﻛﺘﻮر ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ در ﻃﺮاﺣﻲ ﻳﻚ ﻛﻼس ﺑﺎﻳﺪ ﻣﺪ ﻧﻈﺮ ﻗﺮار داده ﺷﻮد .ﺑﺮاي ﻣﺜﺎل ﻫﻤﻮاره اﺳﺘﻔﺎده از ﭼﻨﺪ ﻛـﻼس ﻛﻮﭼـﻚ ﻛﻪ ﻫﺮ ﻳﻚ وﻇﻴﻔﻪ ي ﺧﺎﺻﻲ را اﻧﺠﺎم ﻣﻲ دﻫﻨﺪ ﺑﺴﻴﺎر ﺑﻬﺘﺮ از اﺳﺘﻔﺎده از ﻳﻚ ﻛﻼس ﺑﺰرگ اﺳﺖ ﻛﻪ ﻫﻤﻪ ي ﻛﺎرﻫﺎ را اﻧﺠﺎم ﻣﻲ دﻫﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺣﺎل ﻛﺎر ﺑﺎ ﻳﻚ ﻛﻼس ﺑﺰرگ و ﺑﺴﻴﺎر ﭘﻴﭽﻴﺪه در ﻳﻚ ﺳﻴﺴﺘﻢ ﻧﺮم اﻓﺰاري ﻫﺴﺘﻴﺪ ،درك ﻛﺪ درون ﭼﻨﻴﻦ ﺑﺮﻧﺎﻣﻪ اي ﺑﺴﻴﺎر ﭘﻴﭽﻴﺪه و ﻣﺸﻜﻞ ﺧﻮاﻫﺪ ﺑﻮد و اﻏﻠﺐ ﺧﻄﺎ ﻳﺎﺑﻲ و ﺗﻐﻴﻴﺮ ﭼﻨﻴﻦ ﻛﺪ ﻫﺎﻳﻲ ﺑﻪ ﻛﺎﺑﻮس ﺷﺒﻴﻪ ﻣﻲ ﺷﻮد .در ﺑﻴـﺸﺘﺮ ﻣﻮاﻗـﻊ در ﭼﻨـﻴﻦ ﺷـﺮاﻳﻄﻲ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﻛﻼﺳﻬﺎي ﻣﻮرد اﺳﺘﻔﺎده در ﺑﺮﻧﺎﻣﻪ ﺑﻪ اﻳﻦ ﺻﻮرت ﻃﺮاﺣﻲ ﺷﻮﻧﺪ .ﺑﻠﻜﻪ ﻣﻲ ﺗﻮان ﺑﺎ ﺗﻘﺴﻴﻢ اﻳـﻦ ﻛﻼﺳـﻬﺎ ﺑـﻪ ﻛﻼﺳـﻬﺎي ﻛﻮﭼﻜﺘﺮ ،ﻫﻢ ﻧﮕﻪ داري و ﺧﻄﺎ ﻳﺎﺑﻲ را در آﻧﻬﺎ ﺳﺎده ﺗﺮ ﻛﺮد و ﻫﻢ در ﻣﻮاﻗﻊ ﻣﻮرد ﻧﻴﺎز از اﻳﻦ ﻛﻼﺳﻬﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕـﺮ ﻧﻴـﺰ اﺳـﺘﻔﺎده ﻛﺮد. در ﻃﺮاﺣﻲ ﻳﻚ ﻛﻼس ﻫﻤﻮاره ﺳﻌﻲ ﻛﻨﻴﺪ ﺑﻪ ﻧﺤﻮي ﻋﻤﻞ ﻛﻨﻴﺪ ﻛﻪ اﺳﺘﻔﺎده ﻛﻨﻨﺪ ﮔﺎن از آن ﺑﺘﻮاﻧﻨﺪ ﺑﻪ راﺣﺘﻲ و ﺑﺪون ﻧﻴﺎز ﺑﻪ ﻣﻄﺎﻟﻌـﻪ ي ﻣﻘﺪار زﻳﺎدي ﻣﺴﺘﻨﺪات ،آن ﻛﻼس را ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار دﻫﻨﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ ﺑﻪ ﻣﻮارد زﻳﺮ ﻫﻤﻮاره ﺑﻪ ﺻﻮرت ﻳﻚ ﻗﺎﻧﻮن ﻋﻤﻞ ﻛﻨﻴﺪ:
ﺳﻌﻲ ﻛﻨﻴﺪ ﻛﻪ ﺗﻌﺪاد ﭘﺎراﻣﺘﺮﻫﺎي ﻣﺘﺪ ﻫﺎ را ﺣﺪاﻛﺜﺮ ﭘﻨﺞ و ﻳﺎ ﺷﺶ ﭘﺎراﻣﺘﺮ ﻗﺮار دﻫﻴﺪ ،ﻣﮕﺮ در ﺷﺮاﻳﻄﻲ ﻛﻪ واﻗﻌﺎً ﺑﻪ ﭘﺎراﻣﺘﺮﻫـﺎي ﺑﻴﺸﺘﺮي ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﺳﺘﻔﺎده از ﻳﻚ ﻛﻼس ﺑﺴﻴﺎر ﺳﺎده ﺗﺮ ﺧﻮاﻫﺪ ﺑﻮد.
Unified Modeling Language
1
٤٩٠
ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ ﻛﻪ ﻣﺘﺪ و ﺗﻤﺎم ﭘﺎراﻣﺘﺮﻫﺎي آن داراي ﻧﺎم ﻣﻌﻨﻲ داري ﻫﺴﺘﻨﺪ .ﻫﻤﻮاره ﺑﻬﺘﺮ اﺳﺖ از اﺳـﺎﻣﻲ اي ﻛـﻪ ﺑـﻪ راﺣﺘـﻲ ﺧﻮاﻧــﺪه ﻣــﻲ ﺷــﻮﻧﺪ ﺑــﻪ ﺟــﺎي اﺳــﺎﻣﻲ ﻛﻮﺗــﺎه اﺳــﺘﻔﺎده ﻛﻨﻴــﺪ .ﺑــﺮاي ﻣﺜــﺎل اﺳــﺘﻔﺎده از stdNoﺑــﻪ ﺟــﺎي StudentNumberروش ﻣﻨﺎﺳﺒﻲ ﻧﻴﺴﺖ. ﻫﻴﭻ ﮔﺎه ﻻزم ﻧﻴﺴﺖ ﻛﻪ در ﻳﻚ ﻛﻼس از ﺗﻤﺎم ﺗﻮاﺑﻊ و ﺧﺎﺻﻴﺘﻬﺎي ﻣﻤﻜﻦ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻮﺟﺐ ﻣﻲ ﺷﻮﻳﺪ ﻛﻪ ﻛﺎرﺑﺮ ﻫﻨﮕﺎم اﺳﺘﻔﺎده از آن ﻛﻼس ﺑﺮاي ﻛﺎر ﺑﺎ ﻳﻚ ﻣﺘﺪ ﺑﺎ اﻧﺘﺨﺎب ﻫﺎي زﻳﺎدي روﺑﺮو ﺑﺎﺷﺪ ﻛﻪ اﻳﻦ اﻣﺮ اﺳـﺘﻔﺎده از ﻛـﻼس را ﺑﺮاي ﻛﺎرﺑﺮ ﻣﺸﻜﻞ ﺗﺮ و ﭘﻴﭽﻴﺪه ﺗﺮ ﻣﻲ ﻛﻨﺪ .ﺣﺘﻲ ﻣﻤﻜﻦ اﺳﺖ ﺑﺴﻴﺎري از اﻳﻦ ﻛﻼﺳﻬﺎ اﺻﻼً ﻣﻮرد اﺳـﺘﻔﺎده ي ﻋﻤـﻮﻣﻲ ﻗـﺮار ﻧﮕﻴﺮﻧﺪ و وﺟﻮد آﻧﻬﺎ در ﻛﻼس ﺑﻴﻬﻮده ﺑﺎﺷﺪ. ﺳﻌﻲ ﻛﻨﻴﺪ در ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ﺣﺪاﻗﻞ ﺗﻌﺪاد ﻛﻼس را ﻗﺮار دﻫﻴﺪ .زﻳﺮا ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﺳـﺘﻔﺎده از آن ﻛﺘﺎﺑﺨﺎﻧـﻪ و درك ﻋﻤﻠﻜـﺮد ﻛﻼﺳﻬﺎي آن ﺑﺴﻴﺎر ﺳﺎده ﺗﺮ ﺧﻮاﻫﺪ ﺑﻮد. اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ﻫﺎ در ﻳﻚ ﻛﻼس ﺑﺴﻴﺎر ﭘﺮ ﻛﺎرﺑﺮد اﺳﺖ و ﻣﻮﺟﺐ راﺣﺘﻲ اﺳﺘﻔﺎده از آن ﻛﻼس ﻣﻲ ﺷﻮد.
اﺳﺘﻔﺎده از ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺷﺨﺺ ﺛﺎﻟﺚ:1 ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺑﻪ ﻳﻚ ﻓﺎﻳﻞ dllﻛﺎﻣﭙﺎﻳﻞ ﻣﻲ ﺷﻮد .ﺑﺮاي اﺳﺘﻔﺎده از ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧـﻪ ي ﻛﻼس ﻓﻘﻂ ﺑﻪ اﻳﻦ ﻓﺎﻳﻞ dllﻧﻴﺎز اﺳﺖ و ﻻزم ﻧﻴﺴﺖ ﻛﻪ ﻛﺎرﺑﺮ ﺑﻪ ﺳﻮرس اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣـﻲ ﺗﻮاﻧﻴﺪ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺧﻮد را در ﻳﻚ ﻓﺎﻳﻞ Dllﻛﺎﻣﭙﺎﻳﻞ ﻛﺮده و آن را ﺑﺮاي اﺳﺘﻔﺎده ﺗﻮﺳﻂ اﻓﺮاد دﻳﮕﺮ ﺗﻮزﻳﻊ ﻛﻨﻴﺪ و ﻳـﺎ ﻓﺎﻳﻠﻬـﺎي dllﻛﻪ ﺣﺎوي ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس ﻫﺴﺘﻨﺪ را درﻳﺎﻓﺖ ﻛﺮده و از آن در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧـﻮد اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ .ﺑـﺎ ﻧﺤـﻮه ي اﻳﺠـﺎد ﻳـﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس در ﻗﺴﻤﺖ ﻗﺒﻞ آﺷﻨﺎ ﺷﺪﻳﻢ و ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺑـﻪ ﻧـﺎم InternetFavorites.dllﻧﻴـﺰ ﻃﺮاﺣﻲ ﻛﺮدﻳﻢ .در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎ ﻧﺤﻮه ي اﺳﺘﻔﺎده از اﻳﻦ ﻓﺎﻳﻠﻬﺎي dllدر ﺑﺮﻧﺎﻣﻪ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ و ﺳﻌﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛـﻪ از ﻓـﺎﻳﻠﻲ ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ اﻳﺠﺎد ﻛﺮدﻳﻢ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﻢ.
اﺳﺘﻔﺎده از ﻓﺎﻳﻞ :InetrnetFavorites.dll در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ ﻧﺤﻮه ي اﻳﺠﺎد ﻳﻚ ارﺟﺎع ﺑﻪ ﻳﻚ ﭘﺮوژه ي ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس را در ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ ﻣـﺸﺎﻫﺪه ﻛـﺮدﻳﻢ .اﻳـﻦ ﻣـﻮرد ﺑـﻪ ﺧﺼﻮص در ﻣﻮاردي ﻛﻪ ﺑﺨﻮاﻫﻴﻢ ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس را در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﺴﺖ ﻛﻨﻴﻢ ﺑﺴﻴﺎر ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴـﺮد .اﻣـﺎ در اﻳـﻦ ﻣﺜﺎل ﻣﻲ ﺧﻮاﻫﻴﻢ واﻧﻤﻮد ﻛﻨﻴﻢ ﻛﻪ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس InternetFavorites.dllﺗﻮﺳﻂ ﻣﺎ ﻃﺮاﺣـﻲ ﻧـﺸﺪه اﺳـﺖ، ﺑﻠﻜﻪ ﻓﺎﻳﻞ آن را از ﻓﺮد دﻳﮕﺮي درﻳﺎﻓﺖ ﻛﺮده اﻳﻢ و ﺣﺎل ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﺮﻧﺎﻣـﻪ ي Favorites Trayرا ﺑـﻪ ﮔﻮﻧـﻪ اي ﺗﻐﻴﻴـﺮ دﻫﻴﻢ ﺗﺎ از اﻳﻦ ﻓﺎﻳﻞ اﺳﺘﻔﺎده ﻛﻨﺪ .اﻳﻦ ﻳﻚ روش ﺑﺴﻴﺎر ﺳﺎده و ﺳﺮﻳﻊ ﺑﺮاي ﻧﻤﺎﻳﺶ ﻧﺤﻮه ي اﺳﺘﻔﺎده از ﻳﻚ ﻓﺎﻳﻞ dllدر ﺑﺮﻧﺎﻣﻪ اﺳﺖ. اﻣﺎ ﺑﻪ ﺧﺎﻃﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي واﻗﻌﻲ ﺑﺎﻳﺪ اﺑﺘﺪا ارﺟﺎﻋﻲ از ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿـﺎﻓﻪ ﻛـﺮده و ﺳـﭙﺲ از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
اﻣﺘﺤــﺎن ﻛﻨﻴــﺪ :اﺳــﺘﻔﺎده از InternetFavorites.dllدر ﺑﺮﻧﺎﻣــﻪ ي
Favorites
Tray
1ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼﺳﻲ ﻛﻪ ﺗﻮﺳﻂ اﻓﺮاد و ﮔﺮوﻫﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ دﻳﮕﺮي ﻧﻮﺷﺘﻪ ﺷﺪه اﻧﺪ و ﺑﻪ ﺻﻮرت ﺟﺪاﮔﺎﻧﻪ در ﺑﺎزار ﺑﻪ ﻓﺮوش ﻣﻲ رﺳﻨﺪ.
٤٩١
(1 (2 (3
(4
ﭘﺮوژه ي Favorites Trayرا در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺎز ﻛﻨﻴﺪ. ﻓﺎﻳﻞ ﻫﺎي WebFavorite.csو Favorites.csرا از ﭘﺮوژه ﺣﺬف ﻛﻨﻴﺪ. ﺣﺎل ﺑﺎﻳﺪ ارﺟﺎﻋﻲ را ﺑﻪ ﻓﺎﻳﻞ InternetFavorites.dllدر ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر در ﭘﻨﺠـﺮه ي Solution Explorerروي ﻧﺎم ﭘﺮوژه ي Favorites Trayﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ ي Add Referenceرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .در ﻗﺴﻤﺖ .NETدر اﻳﻦ ﭘﻨﺠﺮه ،ﻟﻴـﺴﺖ را ﺣﺮﻛـﺖ داده ﺗﺎ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس InternetFavorites.dllرا ﭘﻴﺪا ﻛﻨﻴﺪ .ﺳﭙﺲ آن را اﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤـﻪ ي OKﻛﻠﻴﻚ ﻛﺮده ﺗﺎ ﭘﻨﺠﺮه ي Add Referenceﺑﺴﺘﻪ ﺷﻮد. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﺑﻪ ﺧﺎﻃﺮ دارﻳﺪ ،ﻓﻀﺎي ﻧﺎم ﻣﻮرد اﺳـﺘﻔﺎده در اﻳـﻦ ﻛﺘﺎﺑﺨﺎﻧـﻪ ي ﻛـﻼس InternetFavorites اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ ﻫﻤﺎﻧﻨﺪ دﻳﮕﺮ ﻓﻀﺎي ﻧﺎﻣﻬﺎ ،اﻳﻦ ﻓﻀﺎي ﻧﺎم را ﻧﻴﺰ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎ اﺳﺘﻔﺎده از راﻫﻨﻤﺎي usingﻣﺎﻧﻨﺪ زﻳﺮ ،اﻳﻦ ﻓﻀﺎي ﻧﺎم را ﻧﻴﺰ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد اﺿﺎﻓﻪ ﻛﻨﻴﺪ. ;using InternetFavorites
(5ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻫﻤﺎﻧﻨﺪ ﻗﺒﻞ ﺑﻪ درﺳﺘﻲ ﻛﺎر ﻣﻲ ﻛﻨﺪ ،اﻣـﺎ اﻳـﻦ ﺑـﺎر ﺑـﻪ ﺟـﺎي اﺳـﺘﻔﺎده از ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﻓﺎﻳﻞ اﺟﺮاﻳﻲ ﺑﺮﻧﺎﻣﻪ ،از ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﻓﺎﻳﻞ dllاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮدي اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ارﺟﺎع ﺑﻪ ﻓﺎﻳﻞ dllﺣﺘﻲ از اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ارﺟﺎع ﺑـﻪ ﻳـﻚ ﭘـﺮوژه ي ﻛﺘﺎﺑﺨﺎﻧـﻪ ي ﻛﻼس ﻧﻴﺰ ﺳﺎده ﺗﺮ ﺑﻮد .ﻫﻤﭽﻨﻴﻦ دﻳﺪﻳﺪ ﻛﻪ ﭼﻪ ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﺑﻪ ﺻﻮرت ﻳﻚ ﻓﺎﻳﻞ dllﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿـﺎﻓﻪ ﺷـﻮد و ﭼـﻪ ﺑـﻪ ﺻﻮرت ﻳﻚ ﭘﺮوژه ،در ﻫﺮ دو ﺣﺎﻟﺖ ﺑﻪ ﻳﻚ ﺻﻮرت ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد .ﺗﻨﻬﺎ ﺗﻔﺎوت در اﻳﻦ روش ﻧﺴﺒﺖ ﺑﻪ اﺳﺘﻔﺎده از ﻛﺘﺎﺑﺨﺎﻧـﻪ ي ﻛﻼس ﺑﻪ ﺻﻮرت ﻗﺒﻠﻲ در اﻳﻦ اﺳﺖ ﻛﻪ در اﻳﻦ ﺣﺎﻟﺖ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻛﺪ ﺑﺮﻧﺎﻣﻪ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ. اﻟﺒﺘﻪ ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻛﺪ ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،ﺑﺎز ﻫﻢ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻃﻼﻋﺎت زﻳﺎدي را در راﺑﻄـﻪ ﺑـﺎ ﻛﻼس ﻫﺎي ﻣﻮﺟﻮد در آن ﺑﻪ دﺳﺖ آورﻳﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻔﻬﻤﻴﺪ ﻛﻪ ﻫﺮ ﻛﻼس داراي ﭼﻨﺪ ﻣﺘﺪ ،ﺧﺎﺻﻴﺖ ،ﻓﻴﻠﺪ و ﻳﺎ ...اﺳﺖ و ﻳـﺎ اﻳﻨﻜﻪ ﻫﺮ ﻣﺘﺪ ﭼﻨﺪ ﭘﺎراﻣﺘﺮ و از ﭼﻪ ﻧﻮع ﻫﺎﻳﻲ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ .ﺑﺮاي ﻓﻬﻤﻴﺪن اﻳﻦ ﻣﻮارد در ﻣﻮرد ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﻣـﻲ ﺗﻮاﻧﻴـﺪ از اﺑﺰار Object Browserاﺳﺘﻔﺎده ﻛﻨﻴﺪ.
اﺳﺘﻔﺎده از :Object Browser ﺑﺮاي ﻣﺸﺎﻫﺪه ي ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﻪ ﻛﺎر رﻓﺘﻪ اﻧـﺪ ﻣـﻲ ﺗﻮاﻧﻴـﺪ از اﺑـﺰاري ﺳـﺮﻳﻊ و ﺳـﺎده ﺑـﻪ ﻧـﺎم Object Browserاﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ اﺑﺰار ﻣﻲ ﺗﻮاﻧﻴﺪ ﻛﻼﺳﻬﺎ و ﻫﻤﭽﻨﻴﻦ ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﻛﻪ درون ﻫﺮ ﻛﻼس ﺑﻪ ﻛﺎر رﻓﺘﻪ اﻧﺪ را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ و اﻃﻼﻋﺎت ﻻزم در ﻣﻮرد آﻧﻬﺎ را ﻧﻴﺰ ﺑﺪﺳﺖ آورﻳﺪ .ﺑﺮاي ﻣﺸﺎﻫﺪه ي ﭘﻨﺠﺮه ي Object Browser در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻛﺎﻓﻲ اﺳﺖ ﻛﻠﻴﺪ F2را ﻓﺸﺎر دﻫﻴﺪ .اﻟﺒﺘﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﮔﺰﻳﻨﻪ ي View Object Browserو ﻳﺎ آﻳﻜﻮن Object Browserدر ﻧﻮار اﺑﺰار ﻧﻴﺰ ﺑﺮاي ﻧﻤﺎﻳﺶ اﻳﻦ ﭘﻨﺠﺮه اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
٤٩٢
اﻳﻦ اﺑﺰار ﻋﻤﻮﻣﺎً ﺑﺮاي درﻳﺎﻓﺖ اﻃﻼﻋﺎت ﻣﺨﺘﺼﺮ و ﺳﺮﻳﻊ در ﻣﻮرد ﻛﻼﺳﻬﺎي ﻣﻮرد اﺳﺘﻔﺎده در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻛﺎر ﻣـﻲ رود .ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﺗﻤﺎم اﺳﻤﺒﻠﻲ ﻫﺎ و ﻓﻀﺎي ﻧﺎﻣﻬﺎﻳﻲ ﻛﻪ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻛﺎر رﻓﺘﻪ اﻧﺪ در ﭘﻨﺠﺮه ي Object Browserﺑـﻪ ﺻﻮرت ﻳﻚ ﻟﻴﺴﺖ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﻧﺪ. در اﻳﻦ ﭘﻨﺠﺮه ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﺗﻤﺎم اﻋﻀﺎي ﻳﻚ ﻛﻼس از ﻗﺒﻴﻞ ﻣﺘﺪ ﻫﺎ ،ﺷﻤﺎرﻧﺪه ﻫﺎ ،ﺛﺎﺑﺖ ﻫﺎ و ...ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ و ﺑﺮاي ﻫﺮ ﻋﻀﻮ ﻧﻴﺰ ﺑﺮ اﺳﺎس ﻧﻮع آن آﻳﻜﻮن ﺧﺎﺻﻲ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .در ﺷﻜﻞ 8-12ﻛﻼس Favoritesو اﻋـﻀﺎي آن ﻧﻤﺎﻳﺶ داده ﺷﺪه اﻧﺪ .ﺑﺮاي ﻧﻤﺎﻳﺶ اﻳﻦ ﻛﻼس اﺑﺘﺪا ﺑﺎﻳﺪ اﺳﻤﺒﻠﻲ InternetFavoritesرا اﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ در اﻳﻦ اﺳﻤﺒﻠﻲ ﻓﻀﺎي ﻧﺎم InternetFavoritesرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .در اﻧﺘﻬﺎ ﻧﻴﺰ روي ﻛﻼس Favoritesدر اﻳﻦ ﻓﻀﺎي ﻧﺎم ﻛﻠﻴﻚ ﻛﻨﻴﺪ.
ﺷﻜﻞ 8-12 ﻧﻜﺘﻪ :دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ در ﻳﻚ اﺳﻤﺒﻠﻲ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻴﺶ از ﻳﻚ ﻓﻀﺎي ﻧﺎم وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ و ﻳﻚ ﻓﻀﺎي ﻧﺎم ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺑﻴﺶ از ﻳﻚ اﺳﻤﺒﻠﻲ ﺗﻘﺴﻴﻢ ﺷﻮد. ﻛﺘﺎﺑﺨﺎﻧﻪ ي MSDNداراي ﻣﺴﺘﻨﺪات و اﻃﻼﻋﺎت ﺑﺴﻴﺎر زﻳﺎدي در ﻣﻮرد ﻛﻼﺳﻬﺎي ﻧﺼﺐ ﺷﺪه ﻫﻤﺮاه ﺑﺎ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ در ﭼـﺎرﭼﻮب .NETاﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد ﺑﻴﺸﺘﺮ از ﻛﻼﺳﻬﺎي دروﻧﻲ .NETاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ،ﻛﻤﺘﺮ ﺑـﻪ ﻛـﺎر ﺑـﺎ Object Browserﻧﻴﺎز ﺧﻮاﻫﻴﺪ داﺷﺖ .اﻳﻦ اﺑﺰار ﺑﻴﺸﺘﺮ ﻫﻨﮕﺎﻣﻲ ﻛﺎرآﻣﺪ ﺧﻮاﻫﺪ ﺑﻮد ﻛﻪ ﺑﺨﻮاﻫﻴﺪ از ﻳـﻚ ﻛﺘﺎﺑﺨﺎﻧـﻪ ي ﻛـﻼس ﻧﻮﺷـﺘﻪ ﺷـﺪه ﺗﻮﺳﻂ ﺷﺨﺺ ﺛﺎﻟﺚ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ﻛﻪ راﻫﻨﻤﺎﻳﻲ ﻫﻢ ﺑﺮاي اﺳﺘﻔﺎده از آن ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس در دﺳﺘﺮس ﻧﺪارﻳﺪ .در اﻳﻦ ﻣﻮارد ﻣﻲ ﺗﻮاﻧﻴـﺪ ﺑﺎ ﻣﺸﺎﻫﺪه ي ﻧﺎم ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎ ﻋﻤﻠﻜﺮد آﻧﻬﺎ را ﻣﺘﻮﺟﻪ ﺷﻮﻳﺪ .اﻟﺒﺘﻪ اﻳﻦ ﺷﺮاﻳﻂ وﻗﺘﻲ ﺻﺎدق ﺧﻮاﻫﻨـﺪ ﺑـﻮد ﻛـﻪ ﺑﺮﻧﺎﻣـﻪ ﻧـﻮﻳﺲ آن ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس ﻧﺎم ﻣﻨﺎﺳﺒﻲ ﺑﺮاي ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎي آن ﻛﻼس اﻧﺘﺨﺎب ﻛﺮده ﺑﺎﺷﺪ.
٤٩٣
در ﺑﻌﻀﻲ ﺷﺮاﻳﻂ ﻳﻚ ﻓﺎﻳﻞ DLLﻣﻲ ﺗﻮاﻧﺪ در ﻣﻮرد ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﺧﻮد و ﻧﻴﺰ ﻫﺮ ﻳﻚ از ﻣﺘﺪ ﻫـﺎ و ﺧﺎﺻـﻴﺖ ﻫـﺎي آن ﻛـﻼس ﺗﻮﺿﻴﺢ ﻣﺨﺘﺼﺮي اراﺋﻪ دﻫﺪ .در اﻳﻦ ﺣﺎل ﺑﺎﻳﺪ ﻫﻨﮕـﺎم ﻃﺮاﺣـﻲ ﻛـﻼس ﺑـﺮاي ﻣـﺸﺨﺺ ﻛـﺮدن ﺗﻮﺿـﻴﺤﺎت ﻣﺮﺑـﻮط ﺑـﻪ ﻫـﺮ ﻋـﻀﻮ از Attributeﻫﺎ اﺳﺘﻔﺎده ﻛﺮد ﻛﻪ ﺻﺤﺒﺖ در راﺑﻄﻪ ﺑﺎ اﻳﻦ ﻣﻮﺿﻮع از ﻣﺒﺎﺣﺚ اﻳﻦ ﻛﺘﺎب ﺧﺎرج اﺳﺖ.
ﻧﺘﻴﺠﻪ: ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس ﺑﺨﺸﻲ ﺟﺪا ﻧﺸﺪﻧﻲ در وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﺑﻪ ﺷﻤﺎر ﻣﻲ روﻧﺪ و در ﺣﻘﻴﻘﺖ از اﻫﻤﻴﺖ زﻳﺎدي در ﺗﻤﺎﻣﻲ زﺑﺎﻧﻬـﺎي ﭼﺎرﭼﻮب .NETﺑﺮﺧﻮردار ﻫﺴﺘﻨﺪ .ﺑﺎ اﺳﺘﻔﺎده از آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ راﺣﺘﻲ ﻛﻼﺳﻬﺎي ﻣﻮرد اﺳﺘﻔﺎده در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد را دﺳـﺘﻪ ﺑﻨـﺪي ﻛﺮده و در ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕﺮ ﻧﻴﺰ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. در اﻳﻦ ﻓﺼﻞ ﺑﺎ ﻧﺤﻮه ي اﻳﺠﺎد ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس و ﻧﻴﺰ ﻧﺤﻮه ي اﺳﺘﻔﺎده از ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس اﻳﺠﺎد ﺷﺪه ﺗﻮﺳﻂ اﻓﺮاد دﻳﮕﺮ آﺷـﻨﺎ ﺷﺪﻳﻢ .ﻫﻤﭽﻨﻴﻦ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻳﻚ اﺳﻤﺒﻠﻲ را ﺑﻪ ﺻﻮرت ﻗﻮي ﻧﺎﻣﮕﺬاري ﻛﺮد و ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ از ﻗـﺮار ﮔـﺮﻓﺘﻦ در ﺟﻬﻨﻢ DLLﻫﺎ ﺟﻠﻮﮔﻴﺮي ﻛﺮد. در ﻓﺼﻞ ﺳﻴﺰدﻫﻢ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻛﻨﺘﺮل ﻫﺎﻳﻲ را ﻃﺮاﺣﻲ ﻛﺮد ﻛﻪ ﺑﺘﻮاﻧﻨﺪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي و ﻓﺮﻣﻬـﺎي اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮﻧﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﻪ ﺟﺎي ﻃﺮاﺣﻲ ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ ﻓﻘﻂ ﺷﺎﻣﻞ ﻛﺪ ﻫﺎﻳﻲ ﺑﺮاي اﻧﺠﺎم ﻳﻚ ﺳﺮي اﻣﻮر ﺧﺎص در ﭘﺸﺖ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺑﺎﺷﻨﺪ ،ﻛﻼس ﻫﺎﻳﻲ را ﻃﺮاﺣﻲ ﻛﺮد ﻛﻪ داراي راﺑﻂ ﻛﺎرﺑﺮي ﻣﺸﺨﺼﻲ ﺑﺎﺷﻨﺪ و ﺑﺘﻮاﻧﻨﺪ در ﻓـﺮم ﻫﺎي وﻳﻨﺪوزي ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮﻧﺪ .در آن ﻓﺼﻞ ﻧﻴﺰ ﻣﺠﺪداً ﺑﺎ اﻫﻤﻴﺖ اﺳﺘﻔﺎده ي ﻣﺠﺪد از ﻛﺪ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ.
ﺗﻤﺮﻳﻦ: Favoritesرا ﺑـــﻪ ﺻـــﻮرﺗﻲ ﺗﻐﻴﻴـــﺮ دﻫﻴـــﺪ ﻛـــﻪ ﺑـــﻪ ﺟـــﺎي اﺳـــﺘﻔﺎده از ﭘـــﺮوژه ي ﺑﺮﻧﺎﻣـــﻪ ي Viewer InternetFavoritesاز ﻓﺎﻳﻞ dllﻛﺎﻣﭙﺎﻳﻞ ﺷﺪه ﺑﺮاي اﻳﻦ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس اﺳﺘﻔﺎده ﻛﻨﺪ.
٤٩٤
ﻓﺼﻞ ﺳﻴﺰدﻫﻢ :اﻳﺠﺎد ﻛﻨﺘﺮﻟﻬﺎي ﺳﻔﺎرﺷﻲ ﺗﺎﻛﻨﻮن در ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ در ﻃﻮل اﻳﻦ ﻛﺘﺎب اﻳﺠﺎد ﻛﺮده اﻳﻢ ،از ﻛﻨﺘﺮﻟﻬﺎي زﻳﺎدي ﻛﻪ ﻫﻤـﺮاه ﺑـﺎ .NETاراﺋـﻪ ﺷـﺪه ﺑﻮدﻧـﺪ اﺳـﺘﻔﺎده ﻛﺮدﻳﻢ ،از ﻛﻨﺘﺮل Buttonﮔﺮﻓﺘﻪ ﺗﺎ ﻛﻨﺘﺮل ﻫﺎي TextBoxو .ListBoxﺣﺘﻲ ﻣﻤﻜﻦ اﺳﺖ ﺳـﻌﻲ ﻛـﺮده ﺑﺎﺷـﻴﺪ ﻛـﻪ از ﻛﻨﺘﺮﻟﻬﺎي ﭘﻴﺸﺮﻓﺘﻪ ﺗﺮ دﻳﮕﺮي ﻣﺎﻧﻨﺪ DataGridو TreeViewدر ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ و ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﺷﻮﻳﺪ .اﻟﺒﺘـﻪ ﻛﺎر ﺑﺎ اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ در اﺑﺘﺪا ﻛﻤﻲ ﻣﺸﻜﻞ ﺑﻪ ﻧﻈﺮ ﻣﻲ رﺳﺪ ،ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﻣﻌﻤـﻮﻻً داراي ﺧﺎﺻـﻴﺖ ﻫـﺎ و ﻣﺘـﺪﻫﺎي زﻳـﺎدي ﻫـﺴﺘﻨﺪ .ﺑـﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ راﺑﻂ ﻫﺎي ﻛﺎرﺑﺮي ﺑﻬﺘﺮي و ﻗﻮي ﺗﺮي اﻳﺠﺎد ﻛﻨﻴﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻫﺮ ﭼﻪ ﺑﻴﺸﺘﺮ در اﺳﺘﻔﺎده از اﻳـﻦ ﻛﻨﺘﺮل ﻫﺎ ﻣﻬﺎرت داﺷﺘﻪ ﺑﺎﺷﻴﺪ و ﺑﻴﺸﺘﺮ ﺑﺎ ﻧﺤﻮه ي ﻛﺎرﺑﺮد آﻧﻬﺎ آﺷﻨﺎ ﺑﺎﺷﻴﺪ ،ﺑﻪ ﺳﺮﻋﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ راﺑﻂ ﻫﺎي ﻛـﺎرﺑﺮي ﻛﺎرآﻣـﺪي را اﻳﺠـﺎد ﻛﻨﻴﺪ .ﻳﻜﻲ دﻳﮕﺮ از ﺟﻨﺒﻪ ﻫﺎي ﻣﻬﻢ اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﻗﺎﺑﻠﻴﺖ اﺳﺘﻔﺎده ي ﻣﺠﺪد از آﻧﻬﺎ اﺳﺖ .ﻫﺮ ﺑﺎر ﻛﻪ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ﺟﺪﻳـﺪي اﻳﺠـﺎد ﻛﻨﻴﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ راﺣﺘﻲ ﻳﻚ ﻛﻨﺘﺮل Buttonرا از ﺟﻌﺒﻪ اﺑـﺰار در ﻓـﺮم ﺑﺮﻧﺎﻣـﻪ ﻗـﺮار دﻫﻴـﺪ و ﺳـﭙﺲ اﻳـﻦ ﻛﻨﺘـﺮل ﻣﺎﻧﻨـﺪ ﻛﻨﺘـﺮل Buttonدر ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕﺮ ﻛﺎر ﻣﻲ ﻛﻨﺪ .اﺳﺘﻔﺎده ي ﻣﺠﺪد از ﻛﻨﺘﺮل ﻫﺎ و ﺳﺎدﮔﻲ اﻧﺠﺎم آن در وﻳﮋوال ) C#و ﻛـﻼً در زﺑﺎﻧﻬـﺎي ﺗﺤﺖ (.NETﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﻓﺎﻛﺘﻮر ﻫﺎي ﻣﻮﻓﻘﻴﺖ اﻳﻦ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ و اﻳﻦ ﻣﺤﻴﻂ ﻃﺮاﺣﻲ و ﺗﻮﺳﻌﻪ ﺑﻪ ﺷﻤﺎر ﻣﻲ رود. در اﻳﻦ ﻓﺼﻞ:
در ﻣﻮرد ﻛﻨﺘﺮﻟﻬﺎي وﻳﻨﺪوزي و ﻧﺤﻮه ي ﻛﺎرﻛﺮد آﻧﻬﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻄﺎﻟﺒﻲ را ﺧﻮاﻫﻴﺪ آﻣﻮﺧﺖ. ﺑﺎ اﻳﺠﺎد و اﺳﺘﻔﺎده از ﻛﻨﺘﺮﻟﻬﺎي وﻳﻨﺪوزي آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. ﺑﺎ ﻧﺤﻮه ي اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪ و روﻳﺪاد ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از ﻛﺪ ،ﻧﺤﻮه ي ﻋﻤﻠﻜﺮد اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ را در زﻣﺎن ﻃﺮاﺣﻲ و زﻣـﺎن اﺟـﺮا ﺗﻌﻴﻴﻦ ﻛﺮد.
ﻧﻜﺘﻪ :ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻓﺼﻞ اﻳﺠﺎد ﺧﻮاﻫﻨﺪ ﺷﺪ ﺑﺮاي اﺳﺘﻔﺎده در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز ﻣﻨﺎﺳﺐ ﻫﺴﺘﻨﺪ ﻧﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤـﺖ وب .ﺑﺮاي ﻧﺤﻮه ي اﻳﺠﺎد ﻛﻨﺘﺮﻟﻬﺎي ﺳﻔﺎرﺷﻲ ﺗﺤﺖ وب ﺑﻪ ﻓﺼﻞ ﻫﺠﺪﻫﻢ ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ .در اﻳﻦ ﻓﺼﻞ ﻓﻘـﻂ روي ﻛﻨﺘـﺮل ﻫـﺎي ﺗﺤـﺖ وﻳﻨﺪوز ﺗﻤﺮﻛﺰ ﺧﻮاﻫﻴﻢ ﻛﺮد.
ﻛﻨﺘﺮﻟﻬﺎي وﻳﻨﺪوزي: ﻣﻤﻜﻦ اﺳﺖ اﺑﺘﺪا از ﺧﻮد ﺳﻮال ﻛﻨﻴﺪ اﻳﺠﺎد ﻛﻨﺘﺮﻟﻬﺎي ﺳﻔﺎرﺷﻲ ﭼﻪ دﻟﻴﻠﻲ ﻣﻤﻜﻦ اﺳﺖ داﺷﺘﻪ ﺑﺎﺷﺪ .ﺧـﻮب ،دﻻﻳـﻞ زﻳـﺎدي ﺑـﺮاي اﻳﺠـﺎد ﻛﻨﺘﺮﻟﻬﺎي ﺳﻔﺎرﺷﻲ ﺗﺤﺖ وﻳﻨﺪوز وﺟﻮد دارﻧﺪ:
ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮﻟﻬﺎي ﺳﻔﺎرﺷﻲ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻳﻚ ﻛﻨﺘﺮل در ﭼﻨﺪ ﻗﺴﻤﺖ ﺑﺮﻧﺎﻣـﻪ و ﻳـﺎ ﺣﺘـﻲ در ﭼﻨـﺪﻳﻦ ﺑﺮﻧﺎﻣـﻪ ي ﻣﺨﺘﻠـﻒ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻘﺪار ﻛﺪ ﻣﻮرد ﻧﻴﺎز ﺑﻪ ﺷﺪت ﻛﺎﻫﺶ ﻣﻲ ﻳﺎﺑﺪ )اﺳﺘﻔﺎده ي ﻣﺠﺪد از ﻛﺪ(. ﻣﻲ ﺗﻮاﻧﻴﺪ ﻛﺪ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﻛﻨﺘﺮل را در ﻛﻼس ﻫﻤﺎن ﻛﻨﺘﺮل ﻗﺮار دﻫﻴﺪ و ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺎﻋﺚ ﺷﻮﻳﺪ ﻛـﻪ ﻛـﺪ ﺑﺮﻧﺎﻣـﻪ ﺑﺴﻴﺎر واﺿﺢ ﺗﺮ ﺷﻮد و ﺳﺎده ﺗﺮ ﺑﺘﻮان آن را درك ﻛﺮد .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﻛﻨﺘﺮل Buttonرا ﺑﻪ ﺻﻮرﺗﻲ اﻳﺠـﺎد ﻛﻨﻴـﺪ ﻛﻪ ﺑﺘﻮاﻧﺪ روﻳﺪاد Clickﺧﻮد را ﻛﻨﺘﺮل ﻛﻨﺪ ،ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ دﻳﮕﺮ ﻧﻴﺎزي ﻧﺪارﻳﺪ اﻳﻦ روﻳﺪاد را در ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣـﻪ ﻛﻨﺘﺮل ﻛﻨﻴﺪ.
٤٩٥
ﺑﺮاي اﺳﺘﻔﺎده ﻣﺠﺪد از ﻛﻨﺘﺮل ﻫﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎ دو روش ﻛﻠﻲ وﺟﻮد دارﻧﺪ .روش اول اﻳﻦ اﺳﺖ ﻛﻪ ﺳﻮرس اﺻﻠﻲ ﻛﻨﺘﺮل را ﺑﻪ ﻫـﺮ ﺑﺮﻧﺎﻣـﻪ اي ﻣﻲ ﺧﻮاﻫﻴﺪ از ﻛﻨﺘﺮل در آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ اﺿﺎﻓﻪ ﻛﺮده و ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ را ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل در ﻓﺎﻳـﻞ اﺟﺮاﻳﻲ ﺑﺮﻧﺎﻣﻪ ﻗﺮار ﻣﻲ ﮔﻴﺮد .در ﻃﻲ اﻳﻦ ﻓﺼﻞ ﺑﻪ ﻋﻠﺖ ﺳﺎدﮔﻲ اﻳﻦ روش از آن اﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﺑﻴﺸﺘﺮ ﺗﻤﺮﻛﺰ ﺧﻮد را ﺑـﺮ ﻧﺤﻮه ي ﻋﻤﻠﻜﺮد ﻛﻨﺘﺮل ﻫﺎ ﻣﺘﻤﺮﻛﺰ ﻛﻨﻴﻢ. روش دوم اﻳﺠﺎد ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻨﺘﺮل اﺳﺖ .ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻨﺘﺮل ﻫﻤﺎﻧﻨﺪ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس ﻫﺴﺘﻨﺪ ﻛﻪ در ﻓﺼﻞ ﻗﺒـﻞ ﺑـﺎ آﻧﻬـﺎ آﺷـﻨﺎ ﺷﺪﻳﻢ .در ﺣﻘﻴﻘﺖ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻨﺘﺮل ،ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼﺳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ داراي ﻳﻚ راﺑﻂ ﻛﺎرﺑﺮي ﻧﻴﺰ ﻣـﻲ ﺑﺎﺷـﻨﺪ .ﻫﻤﺎﻧﻨـﺪ ﻛﺘﺎﺑﺨﺎﻧـﻪ ﻫﺎي ﻛﻼس ،ﻛﺘﺎﺑﺨﺎﻧﻪ اي ﻛﻨﺘﺮل ﻧﻴﺰ در ﻓﺎﻳﻞ اﺳﻤﺒﻠﻲ ﺟﺪاﮔﺎﻧﻪ ي ﻣﺮﺑﻮط ﺧﻮدﺷﺎن ﻗﺮار ﻣﻲ ﮔﻴﺮﻧـﺪ و ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑﻌـﺪ از ﺛﺒـﺖ آﻧﻬـﺎ در GACﺑﺎ اﺳﺘﻔﺎده از روﺷﻬﺎﻳﻲ ﻛﻪ در ﻓﺼﻞ ﻗﺒﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،از آﻧﻬﺎ در ﭼﻨﺪﻳﻦ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻳﻦ روش ﺑﺴﻴﺎر ﺟـﺎﻟﺒﺘﺮ از روش ﻗﺒﻠﻲ اﺳﺖ ،زﻳﺮا ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻓﺎﻳﻞ DLLﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ را در اﺧﺘﻴﺎر دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﻗﺮار دﻫﻴﺪ ﺗـﺎ ﺑﺘﻮاﻧﻨـﺪ از آن در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻨﺪ .ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ راﺣﺘﻲ اﺳﻤﺒﻠﻲ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ و ﺑـﻪ ﺷـﻜﻞ ﺟﺪﻳـﺪي ﺗﺒـﺪﻳﻞ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﻳﻦ ﺗﻐﻴﻴﺮات را درﻳﺎﻓﺖ ﻛﺮده و ﺑﺎ ﻓﺎﻳﻞ ﺟﺪﻳﺪ ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ ،ﺑﺪون اﻳﻨﻜـﻪ ﻧﻴـﺎز ﺑﺎﺷـﺪ ﻣﺠـﺪداً آﻧﻬـﺎ را ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﻴﺪ .ﺗﻜﻨﻴﻚ ﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي ﻃﺮاﺣﻲ ﻛﻨﺘﺮل ﺑﻪ ﻛﺎر ﻣﻲ رود در ﻫﺮ دو ﻣﻮرد ﻣﺸﺎﺑﻪ اﺳﺖ ،ﭼﻪ ﻛﻨﺘﺮل را ﺑﻪ ﺻﻮرت ﻳﻚ ﭘﺮوژه ي ﻣﺠﺰا اﻳﺠﺎد ﻛﺮده و از آن در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﻢ ،ﭼﻪ ﻛﻨﺘﺮل را در ﺑﺮﻧﺎﻣﻪ ﻃﺮاﺣﻲ ﻛﺮده و در ﻫﻤﺎن ﻗﺴﻤﺖ ﻧﻴﺰ از آن اﺳﺘﻔﺎده ﻛﻨﻴﻢ.
اﻳﺠﺎد و ﺗﺴﺖ ﻛﺮدن ﻛﻨﺘﺮل ﻫﺎي ﺳﻔﺎرﺷﻲ: ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﻤﻜﻦ اﺳﺖ ﺑﻪ ﻛﻨﺘﺮﻟﻲ ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﺑﻪ ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ وﺻﻞ ﺷﻮد و اﻃﻼﻋﺎت ﺧﺎﺻﻲ ﻣﺎﻧﻨﺪ ﻧـﺎم ﻛﺎرﺑﺮي و ﻛﻠﻤﻪ ي ﻋﺒﻮر ﻳﻚ ﻛﺎرﺑﺮ را اﺳﺘﺨﺮاج ﻛﻨﺪ .اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻳﻚ ﻛﻨﺘﺮل ﻗﻮي و ﻛﺎرآﻣﺪ ﺑﺮاي اﻳﻦ ﻛﺎر اﻳﺠﺎد ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ ﺑﻪ ﻧﺤﻮي آن را ﻃﺮاﺣﻲ ﻛﻨﻴﺪ ﻛﻪ آن ﻛﻨﺘﺮل در ﺑﻴﺸﺘﺮ ﻣﻮارد ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﺑﺎﺷﺪ و ﻫﻤﭽﻨﻴﻦ ﻛﺎرﺑﺮ ﺑﺘﻮاﻧﺪ ﺑﻪ راﺣﺘﻲ آن را ﺗﻨﻈﻴﻢ ﻛﻨﺪ ﺗﺎ وﻇﻴﻔﻪ ي ﻣـﺪﻧﻈﺮ او را اﻧﺠﺎم دﻫﺪ .در اﻳﻦ ﻣﻮارد ﺑﻬﺘﺮ اﺳﺖ اﻣﻮري را ﻣﺎﻧﻨﺪ ﻣﺘﺼﻞ ﺷﺪن ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ،درﻳﺎﻓﺖ ﻧﺘﺎﻳﺞ ﻣـﻮرد ﻧﻴـﺎز و ﻗـﺮار دادن ﻧﺘـﺎﻳﺞ ﺑﺪﺳﺖ آﻣﺪه در ﻛﻨﺘﺮل ﻫﺎي دﻳﮕﺮ را دور از ﭼﺸﻢ ﻛﺎرﺑﺮ اﻧﺠﺎم دﻫﻴﺪ ،ﺑﻪ ﺻﻮرﺗﻲ ﻛﻪ ﻛﺎرﺑﺮاﻧﻲ ﻛﻪ از ﻛﻨﺘـﺮل ﺷـﻤﺎ اﺳـﺘﻔﺎده ﻣـﻲ ﻛﻨﻨـﺪ در راﺑﻄﻪ ﺑﺎ اﻳﻦ ﻣﻮارد ﻫﻴﭻ اﻃﻼﻋﻲ ﻧﺪاﺷﺘﻪ ﺑﺎﺷﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ از درﮔﻴﺮ ﺷﺪن آﻧﻬﺎ در اﻳﻦ ﮔﻮﻧﻪ ﻣﻮارد ﺟﻠﻮﮔﻴﺮي ﻛﻨﻴﺪ و ﺑﻪ آﻧﻬـﺎ اﺟﺎزه دﻫﻴﺪ ﻛﻪ روي ﻣﺴﺎﺋﻞ و وﻇﺎﻳﻒ ﻣﺮﺑﻮط ﺑﻪ ﺧﻮدﺷﺎن ﺗﻤﺮﻛﺰ ﻛﻨﻨﺪ. ﻃﺮاﺣﻲ ﻳﻚ ﻛﻨﺘﺮل ﺳﻔﺎرﺷﻲ از ﭘﺎﻳﻪ ،ﻛﺎر ﺳﺨﺘﻲ ﻧﻴﺴﺖ .از ﺟﻬﺘﻲ اﻧﺠﺎم ﭼﻨﻴﻦ ﻛﺎري ﻣﺸﺎﺑﻪ ﻃﺮاﺣﻲ ﻳﻚ ﻓﺮم در ﺑﺮﻧﺎﻣﻪ ﻫـﺎي وﻳﻨـﺪوزي اﺳﺖ .در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وﻳﻨﺪوز اﻳﺠﺎد ﻛﻨﻴﻢ ﻛﻪ از ﻳﻚ ﻛﻨﺘﺮل ﺳﻔﺎرﺷﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،اﺑﺘﺪا ﻳﻚ ﻛﻨﺘﺮل ﺳﻔﺎرﺷﻲ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﺷﺎﻣﻞ ﺳﻪ ﻛﻨﺘﺮل Buttonﺑﺎﺷﺪ و ﺑﺎ ﻓﺸﺎر ﻫﺮ ﻳﻚ از اﻳﻦ دﻛﻤﻪ ﻫﺎ ﻳﻚ ﭘﻴﻐﺎم در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﺷﻮد .ﺳﭙﺲ ﻧﺤﻮه ي اﺳﺘﻔﺎده از اﻳﻦ ﻛﻨﺘﺮل در ﺑﺮﻧﺎﻣﻪ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد. ﻧﻜﺘﻪ :ﻛﻨﺘﺮﻟﻬﺎي ﺳﻔﺎرﺷﻲ اي ﻛﻪ در ﻃﺮاﺣﻲ آﻧﻬﺎ از ﭼﻨﺪﻳﻦ ﻛﻨﺘﺮل دﻳﮕﺮ اﺳﺘﻔﺎده ﺷﺪه اﺳﺖ ﻋﻤﻮﻣﺎً ﺑﻪ ﻋﻨﻮان ﻛﻨﺘﺮل ﻫـﺎي ﻣﺘـﺮاﻛﻢ ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮﻧﺪ.
1
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد اوﻟﻴﻦ ﻛﻨﺘﺮل ﺳﻔﺎرﺷﻲ (1ﺑﺮﻧﺎﻣـﻪ ي وﻳـﮋوال اﺳـﺘﻮدﻳﻮ 2005را ﺑـﺎز ﻛـﺮده ﺑـﺎ اﺳـﺘﻔﺎده از ﻧـﻮا ﻣﻨـﻮ ﮔﺰﻳﻨـﻪ ي File New … Projectاﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ ﻛﺎدر New Projectﻧﻤﺎﻳﺶ داده ﺷـﻮد .در ﻗـﺴﻤﺖ Project Type Aggregate Controls
1
٤٩٦
اﻳﻦ ﻛﺎدر ،ﮔﺰﻳﻨـﻪ ي Visual C#را اﻧﺘﺨـﺎب ﻛـﺮده و از ﻗـﺴﻤﺖ Templatesﮔﺰﻳﻨـﻪ ي Windows Control Libraryرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .در ﻗﺴﻤﺖ Nameﻋﺒـﺎرت MyNamespaceControlرا وارد ﻛﺮده و ﺳﭙﺲ روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ. (2ﺣﺎل روي UserControl1.csدر ﭘﻨﺠﺮه ي Solution Explorerﻛﻠﻴﻚ ﻛﺮده و ﺑـﺎ اﺳـﺘﻔﺎده از ﭘﻨﺠـﺮه ي Propertiesﺧﺎﺻـﻴﺖ File Nameآن را ﺑـﻪ MyNamespace.csﺗﻐﻴﻴـﺮ دﻫﻴـﺪ. ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻣﺤﻴﻄﻲ ﻣﺸﺎﺑﻪ ﻣﺤﻴﻂ ﻃﺮاﺣﻲ ﻓﺮم در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﺑﻪ ﭼﺸﻢ ﻣﻲ ﺧﻮرد ،وﻟﻲ در اﻳﻦ ﻣﺤﻴﻂ ﺑﺨﺸﻬﺎﻳﻲ ﻣﺎﻧﻨﺪ ﻧﻮار ﻋﻨﻮان و ﻳﺎ ﺣﺎﺷﻴﻪ ﻫﺎي ﻓﺮم وﺟﻮد ﻧﺪارد .ﻋﻤﺪﺗﺎً ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﻳﻚ ﻛﻨﺘﺮل ،ﻛﻨﺘﺮل ﻫﺎي ﻣﻮﺟﻮد را در اﻳـﻦ ﻗـﺴﻤﺖ ﻗﺮار ﻣﻲ دﻫﻴﻢ و ﺳﭙﺲ ﻛﺪ ﻫﺎﻳﻲ ﻛﻪ ﻗﺮار اﺳﺖ در ﭼﻨﺪﻳﻦ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار داده ﺷﻮﻧﺪ را در اﻳﻦ ﻛﻨﺘﺮل ﻫـﺎ وارد ﻣﻲ ﻛﻨﻴﻢ. (3ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﺳﻪ ﻛﻨﺘﺮل Buttonروي ﻓﺮم ﻗﺮار داده و ﺧﺎﺻﻴﺖ Textآﻧﻬﺎ را ﺑﻪ ﺻﻮرﺗﻲ ﺗﻨﻈﻴﻢ ﻛﻨﻴـﺪ ﻛـﻪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 1-13ﺷﻮﻧﺪ .ﻫﻤﭽﻨﻴﻦ ﺑﺎ ﺗﻨﻈﻴﻢ اﻧﺪازه ي ﻫﺮ ﻳﻚ از اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ،ﻓﺮم ﺧﻮد را ﻣﺸﺎﺑﻪ ﻓﺮم ﺷﻜﻞ 1-13اﻳﺠـﺎد ﻛﻨﻴﺪ.
ﺷﻜﻞ 1-13 (4ﺧﺎﺻــــﻴﺖ Nameاﻳــــﻦ ﻛﻨﺘــــﺮل ﻫــــﺎ را ﺑــــﻪ ﺗﺮﺗﻴــــﺐ ﺑﺮاﺑــــﺮ ﺑــــﺎ ،btnApplicatinName btnExecutablePathو btnApplicationVersionﻗﺮار دﻫﻴﺪ. (5ﺗﺎ اﻳﻨﺠﺎ ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي Buttonﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﻳﺠﺎد ﻛﺮده اﻳﻢ ﻫﻴﭻ اﺗﻔﺎق ﺧﺎﺻﻲ رخ ﻧﻤﻲ دﻫﺪ – ﭘـﺲ ﻧﻴﺎز دارﻳﻢ ﻛﻪ ﻣﺘﺪي را اﻳﺠﺎد ﻛﺮده و ﻫﻨﮕﺎم رخ دادن روﻳﺪاد ﻛﻠﻴﻚ ،Buttonآن ﻣﺘﺪ را ﻓﺮاﺧـﻮاﻧﻲ ﻛﻨـﻴﻢ .روي ﻛﻨﺘـﺮل btnApplicationNameدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ اﻳﺠﺎد ﺷﺪه وارد ﻛﻨﻴﺪ. private void btnApplicationName_Click(object sender, )EventArgs e { MessageBox.Show("Application Name is: " + ;)Application.ProductName } (6ﻣﺠﺪداً ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻛﻨﺘﺮل ﺑﺮﮔﺸﺘﻪ و روي ﻛﻨﺘﺮل btnExecutablePathدو ﺑﺎر ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﻣﺘـﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickاﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در آن ﻣﺘﺪ وارد ﻛﻨﻴﺪ. private void btnExecutablePath_Click(object sender, )EventArgs e { MessageBox.Show("Executable Path is: " + ;)Application.ExecutablePath
٤٩٧
} (7در آﺧﺮ ﻧﻴﺰ ﻣﺠﺪداً ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣـﻲ ﻓـﺮم ﺑﺮﮔﺮدﻳـﺪ و روي ﻛﻨﺘـﺮل btnApplicationVersionدو ﺑـﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ آن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در آن وارد ﻛﻨﻴﺪ: private void btnApplicationVersion_Click(object sender, )EventArgs e { MessageBox.Show("Application Version is: " + ;)Application.ProductVersion } (8ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻛﻨﺘﺮﻟﻲ ﻛﻪ ﻃﺮاﺣﻲ ﻛﺮده اﻳﺪ ﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ 2-13در ﻛـﺎدر TestContainerﻧﻤـﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﺎدر ﻣﻲ ﺗﻮاﻧﻴﺪ ﻧﺤﻮه ي ﻋﻤﻠﻜﺮد ﻛﻨﺘﺮل ﺧﻮد را ﺑﺮرﺳﻲ ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﺑﺎ ﻛﻠﻴـﻚ روي ﻫـﺮ ﻳﻚ از دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣﺘﻦ ﻣﻨﺎﺳﺒﻲ در ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﺑﻌﺪ از اﺗﻤﺎم ﻛﺎر ﺑﺎ اﻳﻦ ﭘﻨﺠﺮه روي دﻛﻤﻪ ي Closeﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑﺴﺘﻪ ﺷﻮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ اﻳﺠﺎد راﺑﻂ ﻛﺎرﺑﺮي ﺑﺮاي ﻳﻚ ﻛﻨﺘﺮل ﺗﻔﺎوت زﻳﺎدي ﺑﺎ اﻳﺠﺎد راﺑﻂ ﻛﺎرﺑﺮي در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ﻧﺪارد. ﻛﺎﻓﻲ اﺳﺖ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮرد ﻧﻴﺎز ﺧﻮد را ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ ي اﺑﺰار در ﻣﺤﻴﻂ ﻃﺮاﺣﻲ ﻛﻨﺘﺮل ﻗﺮار دﻫﻴﻢ .ﺳﭙﺲ ﻛﺪ ﻻزم ﺑﺮاي ﻋﻤﻠﻜﺮد اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ را ﻫﻤﺎﻧﻨﺪ روﺷﻬﺎﻳﻲ ﻛﻪ در ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ در ﻣﺘﺪ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻫﺮ ﻛﻨﺘﺮل وارد ﻣﻲ ﻛﻨﻴﻢ. ﻛﺪي ﻛﻪ در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickﻛﻨﺘﺮل btnApplicationNameوارد ﻛﺮدﻳﻢ ﺑﺎ اﺳﺘﻔﺎده از ﺗﻮاﺑﻊ اﺳـﺘﺎﺗﻴﻚ ﻣﻮﺟﻮد در ﻛﻼس ،Applicationﻧﺎم ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در ﺣﺎل اﺟﺮا اﺳﺖ را در ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. private void btnApplicationName_Click(object sender, )EventArgs e { MessageBox.Show("Application Name is: " + ;)Application.ProductName } ﻛﺪ وارد ﺷﺪه در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickﻛﻨﺘـﺮل btnExecutablePathﻧﻴـﺰ ﻋﻤﻠﻜـﺮدي ﻣـﺸﺎﺑﻪ دارد ،ﺑـﺎ اﻳـﻦ ﺗﻔﺎوت ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ExecutablePathاز ﻛﻼس Applicationﻣﺴﻴﺮ ﺑﺮﻧﺎﻣـﻪ ي در ﺣﺎل اﺟﺮا را ﺑﺪﺳﺖ آورده و آن را در ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ. private void btnExecutablePath_Click(object sender, )EventArgs e { MessageBox.Show("Executable Path is: " + ;)Application.ExecutablePath
٤٩٨
}
ﺷﻜﻞ 2-13 در اﻧﺘﻬﺎ ﻧﻴﺰ ﻛﺪ ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﻣﺘﺪ ﻣﺮﺑﻮط ﺑـﻪ روﻳـﺪاد Clickﻛﻨﺘـﺮل btnApplicationVersionرا وارد ﻣـﻲ ﻛﻨﻴﻢ ﺗﺎ ﻧﺴﺨﻪ ي ﺑﺮﻧﺎﻣﻪ ي ﻣﻮرد اﺳﺘﻔﺎده را ﻧﻤﺎﻳﺶ دﻫﺪ. private void btnApplicationVersion_Click(object sender, )EventArgs e { MessageBox.Show("Application Version is: " + ;)Application.ProductVersion } ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣـﻪ را ﻛﺎﻣﭙﺎﻳـﻞ ﻛﻨﻴـﺪ ،اﻳـﻦ ﻛﻨﺘـﺮل ﺑـﻪ ﺻـﻮرت اﺗﻮﻣﺎﺗﻴـﻚ ﺑـﻪ ﻗـﺴﻤﺖ MyNamespace Control Componentsدر ﺟﻌﺒﻪ اﺑﺰار اﺿﺎﻓﻪ ﺧﻮاﻫﺪ ﺷﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ ﻛﻨﺘﺮل را ﻣﺎﻧﻨﺪ ﻫﺮ ﻛﻨﺘﺮل دﻳﮕﺮي در ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي وﻳﻨﺪوزي ﺧﻮد ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار دﻫﻴﺪ .اﻟﺒﺘﻪ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ﺑﻪ راه ﺣﻞ ﻣﻮﺟﻮد در اﻳﻦ ﻗﺴﻤﺖ اﺿـﺎﻓﻪ ﻧﻜﻨﻴـﺪ اﻳـﻦ ﻛﻨﺘﺮل در ﺟﻌﺒﻪ اﺑﺰار دﻳﺪه ﻧﺨﻮاﻫﺪ ﺷﺪ. ﺑﺮاي ﺑﺮرﺳﻲ ﻋﻤﻠﻜﺮد اﻳﻦ ﻛﻨﺘﺮل ﻓﻘﻂ ﻛﺎر ﻛﺮدن ﺑﺎ آن در ﭘﻨﺠﺮه ي TestContainerﻛﺎﻓﻲ ﻧﻴﺴﺖ ،ﺑﻠﻜﻪ ﺑﻬﺘﺮ اﺳﺖ ﻛﻨﺘـﺮل اﻳﺠﺎد ﺷﺪه را در ﻳﻚ ﻓﺮم وﻳﻨﺪوزي ﻗﺮار دﻫﻴﻢ ﻛﻪ اﻳﻦ ﻛﺎر را ﻧﻴﺰ در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ اﻧﺠﺎم ﺧﻮاﻫﻴﻢ داد.
٤٩٩
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﻛﻨﺘﺮل ﺳﻔﺎرﺷﻲ اﻳﺠﺎد ﺷﺪه ﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ (1 (2
(3 (4 (5
روي ﻣﻨﻮي Fileﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﮔﺰﻳﻨﻪ ي Add New Projectرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. در ﭘﻨﺠﺮه ي Add New Projectﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ ﻛـﻪ ﮔﺰﻳﻨـﻪ ي Windows Applicationدر ﻗﺴﻤﺖ Templatesاﻧﺘﺨﺎب ﺷﺪه اﺳـﺖ .ﺳـﭙﺲ ﻋﺒـﺎرت Controlsرا در ﻓﻴﻠـﺪ Nameوارد ﻛـﺮده و روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ. در ﺟﻌﺒﻪ اﺑﺰار ﻗﺴﻤﺖ MyNamespaceControl Componentsرا اﻧﺘﺨـﺎب ﻛـﺮده و روي ﮔﺰﻳﻨـﻪ ي UserControl1دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻳﻚ ﻧﻤﻮﻧﻪ از اﻳﻦ ﻛﻨﺘﺮل در Form1ﻗﺮار داده ﺷﻮد. روي ﭘﺮوژه ي Controlsدر ﭘﻨﺠﺮه ي Solution Explorerﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﻋﺒﺎرت ﮔﺰﻳﻨﻪ ي Set as Startup Projectرا از ﻣﻨﻮي ﺑﺎز ﺷﺪه اﻧﺘﺨﺎب ﻛﻨﻴﺪ. ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﺳﻪ دﻛﻤﻪ اي ﻛﻪ در ﻛﻨﺘﺮل ﺳﻔﺎرﺷﻲ ﻗﺮار داده ﺑﻮدﻳﻢ در اﻳﻦ ﻗـﺴﻤﺖ ﻧﻤـﺎﻳﺶ داده ﻣﻲ ﺷـﻮﻧﺪ و ﺑـﺎ ﻛﻠﻴـﻚ روي ﻫـﺮ ﻛـﺪام از آﻧﻬـﺎ ﻛـﺎدر ﭘﻴﻐـﺎﻣﻲ ﻣـﺸﺎﺑﻪ ﻛـﺎدر ﭘﻴﻐـﺎم ﻧﻤـﺎﻳﺶ داده ﺷـﺪه در ﭘﻨﺠـﺮه ي TestContainerدﻳﺪه ﺧﻮاﻫﺪ ﺷﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻛﻨﺘﺮل ﻫﺎي ﺳﻔﺎرﺷﻲ ﻛﻪ ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ ﻫﻤﺎﻧﻨﺪ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ ﺗﺎﻛﻨﻮن از آﻧﻬﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﺳﺘﻔﺎده ﻛﺮده ﺑـﻮدﻳﻢ ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ .ﺑﺮاي اﺳﺘﻔﺎده از اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﻛﺎﻓﻲ اﺳﺖ آﻧﻬﺎ را از ﺟﻌﺒﻪ اﺑﺰار اﻧﺘﺨﺎب ﻛﺮده ،ﺑﺮ روي ﻓﺮم ﻗـﺮار دﻫﻴـﺪ و ﺳـﭙﺲ ﺑﺮﻧﺎﻣـﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻻزم ﻧﻴﺴﺖ ﻫﻴﭻ ﻛﺪي را ﺑﺮاي روﻳﺪاد Clickدﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻛﻨﺘﺮل ﺑﻨﻮﻳﺴﻴﺪ ،زﻳﺮا ﻛﺪ ﻻزم ﺑﺮاي ﻋﻤﻠﻜﺮد اﻳﻦ دﻛﻤﻪ ﻫﺎ در ﺧﻮد ﻛﻨﺘﺮل ﻗﺮار داده ﺷﺪه اﺳﺖ.
اﻳﺠﺎد ﻛﺮدن ﺧﺎﺻﻴﺖ ﺑﺮاي ﻛﻨﺘﺮل ﻫﺎي ﺳﻔﺎرﺷﻲ: ﻳﻚ ﻛﻨﺘﺮل ﺳﻔﺎرﺷﻲ ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﻛﻼس اﻳﺠﺎد ﻣﻲ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﻤﺎم ﻋﻀﻮ ﻫﺎﻳﻲ را ﻛﻪ ﺑﺮاي ﻳﻚ ﻛﻼس اﻳﺠﺎد ﻣﻲ ﻛﺮدﻳـﺪ ﺑﺮاي ﻳﻚ ﻛﻨﺘﺮل ﺳﻔﺎرﺷﻲ ﻧﻴﺰ اﻳﺠﺎد ﻛﻨﻴﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺧﺎﺻﻴﺖ ﻫﺎ ،ﻣﺘﺪ ﻫﺎ و ﻳﺎ روﻳﺪاد ﻫﺎﻳﻲ را ﺑﻪ ﻳﻚ ﻛﻨﺘـﺮل ﺳﻔﺎرﺷـﻲ اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ اﻓﺮادي ﻛﻪ آن ﻛﻨﺘﺮل را در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد ﺑﻪ ﻛﺎر ﻣﻲ ﺑﺮﻧﺪ ﺑﺘﻮاﻧﻨﺪ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻨﺪ .اﺑﺘﺪا ﻧﺤﻮه ي اﺿـﺎﻓﻪ ﻛـﺮدن ﻳـﻚ ﺧﺎﺻﻴﺖ را ﺑﻪ ﻛﻨﺘﺮل ﺳﻔﺎرﺷﻲ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد. ﻛﻨﺘﺮﻟﻬﺎي ﺳﻔﺎرﺷﻲ ﻣﻲ ﺗﻮاﻧﻨﺪ داراي دو ﻧﻮع ﺧﺎﺻﻴﺖ ﺑﺎﺷﻨﺪ :ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ در زﻣـﺎن ﻃﺮاﺣـﻲ و ﺑـﺎ اﺳـﺘﻔﺎده از ﭘﻨﺠـﺮه ي Propertiesﺗﻐﻴﻴﺮ داده ﺷﻮﻧﺪ و ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﻛﻪ ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﺪ ﻧﻮﻳﺴﻲ و در زﻣﺎن اﺟﺮا ﺗﻐﻴﻴﺮ داده ﺷﻮﻧﺪ .1ﺑـﺮاي ﻣﺜـﺎل 1ﺑﻪ ﺧﺎﻃﺮ دارﻳﺪ ﻛﻪ ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ،ﺑﺮﻧﺎﻣﻪ را ﺑﻪ دو زﻣﺎن ﻣﺨﺘﻠﻒ ﺗﻘﺴﻴﻢ ﻣﻲ ﻛﺮدﻳﻢ :زﻣﺎن ﻃﺮاﺣﻲ و زﻣﺎن اﺟـﺮا .زﻣـﺎن ﻃﺮاﺣـﻲ ﺑـﻪ زﻣـﺎﻧﻲ اﻃﻼق ﻣﻲ ﺷﺪ ﻛﻪ در ﺣﻞ ﻃﺮاﺣﻲ راﺑﻂ ﻛﺎرﺑﺮي ﺑﺮﻧﺎﻣﻪ و ﻳﺎ ﻛﺪ ﻧﻮﻳﺴﻲ ﺑﻮدﻳﻢ وم زﻣﺎن اﺟﺮا ﻧﻴﺰ ﺑﻪ زﻣﺎﻧﻲ ﮔﻔﺘﻪ ﻣﻲ ﺷﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ در ﺣﺎل اﺟﺮا ﺑـﻮد .اﻣـﺎ ﭘـﺮوژه ﻫـﺎي ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮﻟﻬﺎي ﺳﻔﺎرﺷﻲ ﺑﻪ ﺳﻪ ﺑﺎزه ي زﻣﺎﻧﻲ ﺗﻘﺴﻴﻢ ﻣﻲ ﺷﻮﻧﺪ :زﻣﺎﻧﻲ ﻛﻪ در ﺣﺎل ﻃﺮاﺣﻲ و ﻛﺪ ﻧﻮﻳﺴﻲ ﺧﻮد ﻛﻨﺘﺮل ﻫﺴﺘﻴﻢ ،زﻣﺎﻧﻲ ﻛﻪ ﻛﺎر ﻃﺮاﺣـﻲ ﻛﻨﺘـﺮل ﺑـﻪ ﭘﺎﻳﺎن رﺳﻴﺪه اﺳﺖ و در ﺣﺎل اﺳﺘﻔﺎده از ﻛﻨﺘﺮل ﻃﺮاﺣﻲ ﺷﺪه در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻫﺴﺘﻴﻢ وﻟﻲ ﺧﻮد ﺑﺮﻧﺎﻣﻪ در ﺣﺎﻟﺖ ﻃﺮاﺣﻲ اﺳﺖ ،زﻣﺎﻧﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ اي ﻛـﻪ از ﻛﻨﺘـﺮل در آن اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ در ﺣﺎل اﺟﺮا اﺳﺖ. در اﻳﻦ ﻗﺴﻤﺖ ﻣﻨﻈﻮر از زﻣﺎن ﻃﺮاﺣﻲ ،ﺑﺎزه ي زﻣﺎﻧﻲ دوم ﻳﻌﻨﻲ زﻣﺎﻧﻲ ﻛﻪ ﻛﻨﺘﺮل را ﻃﺮاﺣﻲ ﻛﺮده و در ﺣﺎل اﺳﺘﻔﺎده از آن در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻫﺴﺘﻴﻢ ﻣﻲ ﺑﺎﺷـﺪ و ﻣﻨﻈـﻮر از زﻣﺎن اﺟﺮا ،ﺑﺎزه ي زﻣﺎﻧﻲ ﺳﻮم ﻳﻌﻨﻲ زﻣﺎﻧﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ از ﻛﻨﺘﺮل در آن اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ در ﺣﺎل اﺟﺮا اﺳﺖ ﻣﻲ ﺑﺎﺷﺪ.
٥٠٠
ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ در زﻣﺎن ﻃﺮاﺣﻲ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺘﻬﺎي ﻳﻚ ﻛﻨﺘﺮل ،رﻧﮓ ﻣﻮرد اﺳﺘﻔﺎده در آن و ﻳﺎ ﻓﻮﻧﺖ ﻧﻮﺷﺘﻪ ﻫﺎي آن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ .اﻣﺎ ﺑﺨﻮاﻫﻴﺪ در زﻣﺎن اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ﻫﺎ ﺑﺮاي ﻣﺜﺎل ﺑﻪ آدرس ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ ﻛـﻪ ﺑـﻪ آن ﻣﺘـﺼﻞ ﺷـﺪه اﻳـﺪ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ.
اﺿﺎﻓﻪ ﻛﺮدن ﺧﺎﺻﻴﺖ ﻫﺎ: در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺧﺎﺻﻴﺘﻲ ﺑﻪ ﻛﻨﺘﺮل اﺿﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛﺮد ﺗﺎ ﺑﺘﻮاﻧﻴﺪ آن را ﭼﻪ در زﻣﺎن اﺟﺮا و ﭼﻪ در زﻣﺎن ﻃﺮاﺣﻲ ﺗﻐﻴﻴﺮ دﻫﻴـﺪ. ﻧﺎم اﻳﻦ ﺧﺎﺻﻴﺖ ApplicationNameاﺳﺖ و ﻧﺎم ﺑﺮﻧﺎﻣﻪ را ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻳﻦ ﺧﺎﺻـﻴﺖ در ﺑﺮﻧﺎﻣـﻪ ﺗﻐﻴﻴـﺮ ﻛﺮد ،ﻣﺘﻦ ﻣﻮﺟﻮد در ﻧﻮار ﻋﻨﻮان ﻛﺎدرﻫﺎي ﭘﻴﻐﺎم را ﺗﻐﻴﻴﺮ ﺧﻮاﻫﻴﻢ داد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﺧﺎﺻﻴﺖ ﺟﺪﻳﺪ ﺑﻪ ﻛﻨﺘﺮل MyNamespace (1ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﺪ ﻳﻚ ﺧﺎﺻﻴﺖ را ﺑﻪ ﻛﻨﺘﺮل اﺿﺎﻓﻪ ﻛﻨﻴﺪ ،اﺑﺘﺪا ﺑﺎﻳﺪ ﻳﻚ ﻓﻴﻠﺪ در ﻛﻼس ﻣﺮﺑﻮط ﺑﻪ آن ﻛﻨﺘﺮل اﻳﺠﺎد ﻛﻨﻴـﺪ ﺗـﺎ ﻣﻘﺪار آن ﺧﺎﺻﻴﺖ را ﻧﮕﻬﺪاري ﻛﻨﺪ .ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑـﻪ ﻓـﻀﺎي ﻧـﺎم MyNamespaceﺑﺮوﻳـﺪ و ﻛـﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﺑﺘﺪاي ﻛﻼس UserControl1اﺿﺎﻓﻪ ﻛﻨﻴﺪ: public partial class UserControl1 : UserControl { // Private members ;"" = private string strApplicationName (2ﺑﻌﺪ از اﻳﺠﺎد اﻳﻦ ﻓﻴﻠﺪ ،ﺑﺎﻳﺪ ﻳﻚ ﺧﺎﺻﻴﺖ اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ ﻣﻘﺪار ﺑﺘﻮان ﺑﻪ وﺳﻴﻠﻪ ي آن ﻣﻘﺪار ﻣﻮﺟﻮد در اﻳﻦ ﻓﻴﻠـﺪ را ﺗﻐﻴﻴـﺮ داد. ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺪ زﻳﺮ را ﺑﻌﺪ از ﻛﺪي ﻛﻪ در ﻗﺴﻤﺖ اول وارد ﻛﺮدﻳﺪ ﺑﻨﻮﻳﺴﻴﺪ: public string ApplicationName { get { ;return strApplicationName } set { ;strApplicationName = value } } (3ﺑﺮاي اﻳﻨﻜﻪ ﻣﻘﺪار ﻣﻮﺟﻮد در اﻳﻦ ﺧﺎﺻﻴﺖ در ﻧﻮار ﻋﻨﻮان ﻛﺎدرﻫﺎي ﭘﻴﻐﺎم ﻧﻴﺰ ﻧﻤﺎﻳﺶ داده ﺷﻮد ،ﺑﺎﻳﺪ ﭘـﺎراﻣﺘﺮ Captionاز ﻣﺘﺪ Showرا ﺑﺎ ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺪ ﻣﻮﺟﻮد در روﻳﺪاد ﻛﻠﻴﻚ ﻫﺮ ﺳـﻪ ﻛﻨﺘـﺮل Button ﻣﻮﺟﻮد در ﻓﺮم را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ:
٥٠١
private void btnApplicationName_Click(object sender, )EventArgs e { MessageBox.Show("Application Name is: " + Application.ProductName, ;)this.ApplicationName } private void btnExecutablePath_Click(object sender, )EventArgs e { MessageBox.Show("Executable Path is: " + Application.ExecutablePath, ;)this.ApplicationName } private void btnApplicationVersion_Click(object sender, )EventArgs e { MessageBox.Show("Application Version is: " + Application.ProductVersion, ;)this.ApplicationName } (4
(5
(6 (7
ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﺪ از ﺧﺎﺻﻴﺖ اﺿﺎﻓﻪ ﺷﺪه در ﻛﻨﺘﺮل اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﻛﺎﻓﻲ اﺳﺖ ﻳﻚ ﺑﺎر ﭘﺮوژه ي ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل را ﻛﺎﻣﭙﺎﻳـﻞ ﻛﻨﻴﺪ .روي ﻧـﺎم ﭘـﺮوژه ي MyNamespace Controlدر ﭘﻨﺠـﺮه ي Solution Explorer ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﮔﺰﻳﻨﻪ ي Buildرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ ﺑﺮﻧﺎﻣﻪ ﻣﺠﺪداً ﻛﺎﻣﭙﺎﻳﻞ ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺧﺎﺻﻴﺖ اي ﻛـﻪ در اﻳﻦ ﻗﺴﻤﺖ اﺿﺎﻓﻪ ﻛﺮدﻳﺪ ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﺧﻮاﻫﺪ ﺑﻮد. ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑـﻮط ﺑـﻪ Form1ﺑﺮﮔـﺸﺘﻪ و ﻛﻨﺘـﺮل UserControl11را در ﻓـﺮم اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ. ﻣـــﺸﺎﻫﺪه ﺧﻮاﻫﻴـــﺪ ﻛـــﺮد ﻛـــﻪ ﺧﺎﺻـــﻴﺖ ApplicationNameدر ﻗـــﺴﻤﺖ Miscدر ﭘﻨﺠـــﺮه ي Propertiesﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد )اﮔﺮ ﺧﺎﺻﻴﺖ ﻫﺎ را ﺑﺮ اﺳﺎس ﺣﺮوف اﻟﻔﺒﺎﻳﻲ ﻣﺮﺗﺐ ﻛﺮده ﺑﺎﺷﻴﺪ ،اﻳﻦ ﺧﺎﺻﻴﺖ در ﻣﻜﺎن ﻣﻨﺎﺳﺐ ﺧﻮد ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد(. ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ را ﺑﺮاﺑﺮ ﺑﺎ My Windows Applicationﻗﺮار دﻫﻴﺪ. ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و روي ﻳﻜﻲ از دﻛﻤـﻪ ﻫـﺎ ﺑـﻪ دﻟﺨـﻮاه ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛـﺮد ﻛـﻪ ﻋﺒـﺎرت My Windows Applicationدر ﻧﻮار ﻋﻨﻮان ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﻣﻘﺪار اوﻟﻴﻪ ي ﺧﺎﺻﻴﺖ ApplicationNameﺑﺮاﺑﺮ ﺑﺎ رﺷﺘﻪ ي ﺗﻬـﻲ در ﻧﻈـﺮ ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ ،ﻫﻤﻴﻦ ﻣﻘﺪار ﻧﻴﺰ ﺑﻪ ﭘﻨﺠﺮه ي Propertiesﻓﺮﺳﺘﺎده ﻣﻲ ﺷـﻮد و اﻳـﻦ ﺧﺎﺻـﻴﺖ ﺑـﻪ ﺻـﻮرت اوﻟﻴـﻪ ﻣﻘـﺪاري
٥٠٢
ﻧﺨﻮاﻫﺪ داﺷﺖ .ﺣﺎل اﮔﺮ در زﻣﺎن ﻃﺮاﺣﻲ ﻣﻘﺪاري را ﺑﺮاي آن ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ ،ﻫﻨﮕﺎم اﺟﺮاي ﺑﺮﻧﺎﻣﻪ اﻳﻦ ﻣﻘـﺪار در ﻧـﻮار ﻋﻨـﻮان ﻫـﺮ ﻳـﻚ از ﻛﺎدرﻫﺎي ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺤﻴﻂ ﻃﺮاﺣﻲ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺨﻮاﻫﺪ ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي Propertiesﺧﺎﺻﻴﺖ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﻛﻨﺘـﺮل را ﻧﻤﺎﻳﺶ دﻫﺪ ،ﺑﻪ درون ﺷﻴﺊ ﻣﺮﺑﻮط ﺑﻪ آن ﻛﻨﺘﺮل رﻓﺘﻪ و ﻣﻘﺪار ﻫﺮ ﻳﻚ از ﺧﺎﺻﻴﺖ را درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ و در اﻳـﻦ ﭘﻨﺠـﺮه ﻧﻤـﺎﻳﺶ ﻣـﻲ دﻫﺪ .ﻫﻤﭽﻨﻴﻦ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﻘﺪار ﻳﻜﻲ از اﻳﻦ ﺧﺎﺻﻴﺖ ﻫﺎ را ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي Propertiesﺗﻐﻴﻴﺮ دﻫﻴﺪ ،ﻣﺤـﻴﻂ ﻃﺮاﺣـﻲ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﻪ ﺷﻴﺊ ﻣﺮﺑﻮط ﺑﻪ آن ﻛﻨﺘﺮل رﻓﺘﻪ و ﻣﻘﺪار آن ﺧﺎﺻﻴﺖ را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺪار ﺟﺪﻳﺪ ﻗﺮار ﻣﻲ دﻫﺪ.
اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪ ﺑﻪ ﻛﻨﺘﺮل ﻫﺎي ﺳﻔﺎرﺷﻲ: ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺗﺎﻛﻨﻮن ﺣﺪس زده ﺑﺎﺷﻴﺪ ،وﻗﺘﻲ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﺧﺎﺻﻴﺖ را ﺑﺮاي ﻳﻚ ﻛﻨﺘﺮل ﺳﻔﺎرﺷﻲ اﻳﺠﺎد ﻛﻨﻴﺪ ،ﻣﺴﻠﻤﺎً ﻣـﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﻣﺘﺪ را ﻧﻴﺰ ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺗﻤﺎم ﻛﺎري ﻛﻪ ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻣﺘﺪ ﺑﻪ ﻛﻨﺘﺮل ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻳﻚ ﺗﺎﺑﻊ و ﻳﺎ زﻳﺮ ﺑﺮﻧﺎﻣﻪ از ﻧﻮع publicرا ﺑﻪ ﻛﻨﺘﺮل اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ آن ﻣﺘﺪ را در زﻣﺎن ﻛﺎر ﺑﺎ ﻛﻨﺘـﺮل ﻓﺮاﺧـﻮاﻧﻲ ﻛﻨﻴـﺪ. ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻛﺎر را در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻣﺘﺪ ﺑﻪ ﻛﻨﺘﺮل اﻳﺠﺎد ﺷﺪه (1ﺑــﻪ ﻗــﺴﻤﺖ وﻳﺮاﻳــﺸﮕﺮ ﻛــﺪ ﻣﺮﺑــﻮط ﺑــﻪ ﻓﺎﻳــﻞ UserControl1.csﺑﺮوﻳــﺪ و ﻣﺘــﺪ زﻳــﺮ را ﺑــﻪ ﻛــﻼس UserControl1اﺿﺎﻓﻪ ﻛﻨﻴﺪ. )(public string FormCaption { ;return Application.OpenForms[0].Text } (2ﺣﺎل ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ Form1ﺑﺮﮔﺮدﻳﺪ و ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘـﺮل Buttonﺟﺪﻳـﺪ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ .ﺧﺎﺻﻴﺖ Nameاﻳـﻦ ﻛﻨﺘـﺮل را ﺑـﺎ ﻣﻘـﺪار btnFormNameو ﺧﺎﺻـﻴﺖ Textآن را ﺑـﺎ ﻣﻘـﺪار Form Nameﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ. (3روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳـﺪاد Clickاﻳـﻦ ﻛﻨﺘـﺮل اﺿـﺎﻓﻪ ﻛﻨﻴﺪ: private void btnFormName_Click(object sender, )EventArgs e { MessageBox.Show(userControl11.FormCaption(), ;)""Form1 }
٥٠٣
(4ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و روي دﻛﻤﻪ ي Form Nameﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻛﺎرد ﭘﻴﻐﺎﻣﻲ ﻧﻤﺎﻳﺶ داده ﺷﺪه و ﻧﺎم اوﻟﻴﻦ ﻓﺮم ﺑﺎز ﺑﺮﻧﺎﻣﻪ را اﻋﻼم ﻣﻲ ﻛﻨﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اﻳﺠﺎد ﻳﻚ ﺗﺎﺑﻊ و ﻳﺎ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﺑﺮاي ﻳﻚ ﻛﻨﺘﺮل ﺗﻔﺎوت ﭼﻨﺪاﻧﻲ ﺑﺎ اﻳﺠﺎد ﻳﻚ ﺗﺎﺑﻊ و ﻳﺎ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﺑﺮاي ﻳﻚ ﻛـﻼس ﻧـﺪارد .اﻟﺒﺘـﻪ ﺗﻮﺟـﻪ ﻛﻨﻴﺪ ﻣﺘﺪي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ ﺑﺎﻳﺪ از ﻧﻮع Publicﺑﺎﺷﺪ ﺗﺎ ﺑﺘﻮاﻧﺪ ﺗﻮﺳﻂ اﻓﺮادي ﻛﻪ از اﻳﻦ ﻛﻨﺘﺮل اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد. ﻣﺘﺪي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﻋﻤﻞ ﺧﺎﺻﻲ را اﻧﺠﺎم ﻧﻤﻲ دﻫﻴﺪ .ﻓﻘﻂ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻـﻴﺖ OpenFormsدر ﻛـﻼس Applicationﻟﻴﺴﺘﻲ از ﺗﻤﺎم ﻓﺮﻣﻬﺎﻳﻲ از ﺑﺮﻧﺎﻣﻪ ﻛﻪ ﻫﻢ اﻛﻨﻮن ﺑﺎز ﻫﺴﺘﻨﺪ را درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ و ﻧﺎم اوﻟﻴﻦ ﻓﺮم را در ﻳﻚ ﻛـﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. )(public string FormCaption { ;return Application.OpenForms[0].Text } ﺑﺮاي اﺳﺘﻔﺎده از اﻳﻦ ﻣﺘﺪ در ﺑﺮﻧﺎﻣﻪ ،ﻣﺎﻧﻨﺪ اﺳﺘﻔﺎده از ﻣﺘﺪ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ دﻳﮕﺮ ﻛﻨﺘﺮل ﻫﺎ ﻋﻤﻞ ﻣﻲ ﻛﻨﻴﻢ .ﻳﻌﻨﻲ اﺑﺘﺪا ﻧﺎم ﻛﻨﺘﺮل را وارد ﻣﻲ ﻛﻨﻴﻢ ﺳﭙﺲ ﻳﻚ " ".ﻗﺮار ﻣﻲ دﻫﻴﻢ ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻟﻴﺴﺘﻲ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﻛﻪ ﻧﺎم ﻣﺘﺪ ﻣﻮرد ﻧﻈﺮ ﻣﺎ ﻧﻴﺰ در آن وﺟﻮد دارد. private void btnFormName_Click(object sender, )EventArgs e { MessageBox.Show(userControl11.FormCaption(), ;)""Form1 } ﺑﺮاي اﺳﺘﻔﺎده از ﻣﺘﺪي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﺿﺎﻓﻪ ﻛﺮده اﻳﻢ ﺣﺘﻲ ﻧﻴﺎزي ﺑﻪ ﻛﺎﻣﭙﺎﻳﻞ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ وﺟﻮد ﻧﺪارد .ﺑﻌﺪ از اﺿـﺎﻓﻪ ﻛـﺮدن ﻣﺘـﺪ ﺑـﻪ ﻛﻨﺘﺮل ،ﺑﻪ راﺣﺘﻲ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻣﺘﺪ در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
اﺿﺎﻓﻪ ﻛﺮدن روﻳﺪاد ﺑﻪ ﻛﻨﺘﺮل: ﺗﺎ اﻳﻨﺠﺎ ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ﺧﺎﺻﻴﺖ و ﻣﺘﺪ در ﻳﻚ ﻛﻨﺘﺮل آﺷﻨﺎ ﺷﺪﻳﻢ .در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻧﺤﻮه ي اﺿـﺎﻓﻪ ﻛـﺮدن روﻳـﺪاد ﺑـﻪ ﻳـﻚ ﻛﻨﺘﺮل را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ .ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ روﻳﺪاد ﺑﻪ ﻛﻨﺘﺮل ،اﻓﺮادي ﻛﻪ از آن ﻛﻨﺘﺮل اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﻣـﻲ ﺗﻮاﻧـﺪ ﻫﻨﮕـﺎم رخ دادن آن روﻳﺪاد ﻣﺘﺪﻫﺎي ﻣﺸﺨﺼﻲ را اﺟﺮا ﻛﻨﻨﺪ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺳﻪ روﻳﺪاد ﺑﺮاي ﻫﺮ ﻳﻚ از ﻛﻠﻴﺪ ﻫﺎي ﻣﻮﺟﻮد در ﻛﻨﺘﺮل اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻛـﺎرﺑﺮ روي ﻫﺮ ﻛﺪام از اﻳﻦ ﻛﻠﻴﺪ ﻫﺎ ﻛﻠﻴﻚ ﻛﻨﺪ روﻳﺪاد ﻣﺮﺑﻮط ﺑﻪ آن ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد.
٥٠٤
ﻧﻜﺘﻪ :ﺗﻮﺟﻪ ﺑﻪ اﻳﻦ ﻧﻜﺘﻪ ﺿﺮوري اﺳﺖ ﻛﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ از ﻳﻚ ﻛﻨﺘﺮل در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ و ﺑﺮاي ﻣﺜﺎل ﻣﺘـﺪي را ﺑـﺮاي روﻳﺪاد Clickآن ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﺪ ،زﻣﺎن رخ دادن روﻳﺪاد Clickﺑﻪ وﺳﻴﻠﻪ ي ﺧﻮد ﻛﻨﺘﺮل ﻣﺸﺨﺺ ﻣﻲ ﺷﻮد .ﭘـﺲ در اﻳـﻦ ﻗﺴﻤﺖ ﻛﻪ ﺧﻮدﻣﺎن در ﺣﺎل ﻃﺮاﺣﻲ ﻛﻨﺘﺮل ﻫﺴﺘﻴﻢ ،اﮔﺮ روﻳﺪادي را ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل اﺿﺎﻓﻪ ﻛﻨﻴﻢ زﻣﺎن رخ دادن اﻳﻦ روﻳﺪاد را ﻧﻴﺰ ﺧﻮدﻣﺎن ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد و ﻓﺮاﺧﻮاﻧﻲ ﻳﻚ روﻳﺪاد (1ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ روﻳﺪاد رخ ﻣﻲ دﻫﺪ ،ﻓﻘﻂ ﺗﻮاﺑﻊ ﺑﺎ ﺳﺎﺧﺘﺎرﻫﺎي ﺧﺎﺻﻲ ﻣﻲ ﺗﻮاﻧﻨﺪ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮﻧﺪ .ﭘﺲ ﺑﺮاي اﻳﺠﺎد ﻳﻚ روﻳﺪاد ﻧﻴﺰ ،اﺑﺘﺪا ﺑﺎﻳﺪ ﺳﺎﺧﺘﺎر ﺗﻮاﺑﻌﻲ ﻛﻪ اﻳﻦ روﻳﺪاد ﻣﻲ ﺗﻮاﻧﺪ ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﺪ را ﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﺑﺮاي اﻳـﻦ ﻛـﺎر ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻠﻤﻪ ي ﻛﻠﻴﺪي delegateﺳﺎﺧﺘﺎر ﺗﻮاﺑﻊ ﻣﻮرد ﻧﻴﺎز را ﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ .ﭘﺲ اﺑﺘﺪا ﻛﺪ زﻳﺮ را ﺑـﻪ ﻛـﻼس ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل اﺿﺎﻓﻪ ﻛﻨﻴﺪ: // Private members ;"" = private string strApplicationName // Public Delegates (public delegate void _ApplicationNameChanged ;)string AppName (2ﺣﺎل ﻛﻪ ﻧﻮع ﺗﻮاﺑﻊ ﻣﻮرد ﻧﻴﺎز ﺑﺮاي روﻳﺪاد را ﻣﺸﺨﺺ ﻛﺮدﻳﻢ ،ﺑﺎﻳﺪ ﺧﻮد روﻳﺪاد را ﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻧﻴﺰ ﺑﺎﻳﺪ از ﻛﻠﻤـﻪ ي ﻛﻠﻴﺪي eventﺑﻪ ﺻﻮرت زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﭘﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ روﻳـﺪاد ﻣـﻮرد ﻧﻈﺮﻣﺎن اﻳﺠﺎد ﺷﻮد: // Public Delegates (public delegate void _ApplicationNameChanged ;)string AppName // Public Events public event _ApplicationNameChanged ;ApplicationNameChanged (3در اﻧﺘﻬﺎ ﻧﻴﺰ ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ اﻳﻦ روﻳﺪاد در ﭼﻪ ﻣﻮاﻗﻌﻲ ﺑﺎﻳﺪ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮد .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ روﻳﺪاد ﻫﻨﮕـﺎﻣﻲ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮد ﻛﻪ ﻛﺎرﺑﺮ روي دﻛﻤﻪ ي btnApplicationNameﻛﻠﻴﻚ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻓﺮاﺧﻮاﻧﻲ روﻳﺪاد را ﺑﻪ ﺻﻮرت زﻳﺮ ﺑﻪ ﻣﺘﺪ btnApplicationName_Clickاﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ. private void btnApplicationName_Click(object sender, )EventArgs e { )if (this.ApplicationNameChanged != null { (this.ApplicationNameChanged
٥٠٥
;)Application.ProductName } MessageBox.Show("Application Name is: " + Application.ProductName, ;)this.ApplicationName } (4ﺑﺮﻧﺎﻣﻪ را ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﻴﺪ ﺗﺎ ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ ﺧﻄﺎي دﺳﺘﻮري در آن وﺟﻮد ﻧﺪارد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﻧﻴﺰ ﻣﻤﻜﻦ اﺳﺖ ﻣﺘﻮﺟﻪ ﺷﺪه ﺑﺎﺷﻴﺪ ،ﻳﻚ روﻳﺪاد را در ﺣﻘﻴﻘﺖ ﻣﻲ ﺗﻮان ﻣﺎﻧﻨﺪ ﻳﻚ آراﻳﻪ از ﺗﻮاﺑـﻊ در ﻧﻈـﺮ ﮔﺮﻓﺖ .1ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ روﻳﺪاد ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد ،در ﺣﻘﻴﻘﺖ ﺗﻮاﺑﻊ ﻣﻮﺟﻮد در اﻳﻦ آراﻳﻪ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮﻧﺪ .در ﻗﺴﻤﺖ آراﻳﻪ ﻫﺎ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﺗﻤﺎم ﻋﻨﺎﺻﺮ ﻳﻚ آراﻳﻪ ﺑﺎﻳﺪ از ﻳﻚ ﻧﻮع ﺑﺎﺷﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻧﻤﻲ ﺗﻮان آراﻳﻪ اي ﺗﻌﺮﻳـﻒ ﻛـﺮد ﻛﻪ ﺑﺘﻮاﻧﺪ اﻋﻀﺎﻳﻲ از ﻧﻮع intو ﻧﻴﺰ اﻋﻀﺎﻳﻲ از ﻧﻮع stringرا در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ .در روﻳﺪاد ﻫﺎ ﻧﻴﺰ ﺑﻪ ﻫﻤﻴﻦ ﺻﻮرت اﺳـﺖ. ﻳﻚ روﻳﺪاد ﻧﻤﻲ ﺗﻮاﻧﺪ ﺷﺎﻣﻞ ﺗﻮاﺑﻊ ﺑﺎ ﭘﺎراﻣﺘﺮ ﻫﺎ و ﺧﺮوﺟﻲ ﻫﺎي ﻣﺨﺘﻠﻒ ﺑﺎﺷﺪ .ﺑﻠﻜﻪ ﺗﻤﺎم ﺗﻮاﺑﻌﻲ ﻛﻪ در آراﻳﻪ ي ﻣﺮﺑﻮط ﺑـﻪ ﻳـﻚ روﻳـﺪاد ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ ﺑﺎﻳﺪ از ﻳﻚ ﻧﻮع ﺑﺎﺷﻨﺪ. در ﺗﻌﺮﻳﻒ ﻳﻚ روﻳﺪاد در ﻣﺮﺣﻠﻪ ي اول ﺑﺎﻳﺪ ﻧﻮع ﺗﻮاﺑﻌﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ در آن روﻳﺪاد ﻗﺮار ﺑﮕﻴﺮﻧﺪ را ﻣﺸﺨﺺ ﻛﻨﻴﻢ .اﻳﻦ ﻛﺎر ﺑـﺎ ﻛﻠﻤـﻪ ي ﻛﻠﻴﺪي delegateاﻧﺠﺎم ﻣﻲ ﺷﻮد .در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺗﻮاﺑﻌﻲ ﻛﻪ در اﻳﻦ روﻳﺪاد ﻗـﺮار ﻣـﻲ ﮔﻴﺮﻧـﺪ ﻳـﻚ ﭘـﺎراﻣﺘﺮ از ﻧـﻮع stringدرﻳﺎﻓﺖ ﻛﻨﻨﺪ و ﺧﺮوﺟﻲ ﻧﻴﺰ ﻧﺪاﺷﺘﻪ ﺑﺎﺷﻨﺪ )ﺧﺮوﺟﻲ آﻧﻬﺎ از ﻧﻮع voidﺑﺎﺷﺪ( .ﺑﻨﺎﺑﺮاﻳﻦ از ﻛﺪ زﻳﺮ ﺑﺮاي ﺗﻌﺮﻳﻒ ﻧﻮع ﺗﻮاﺑـﻊ ﻣﻮرد ﻧﻴﺎز )ﻳﺎ ﻫﻤﺎن (delegateاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ: // Public Delegates (public delegate void _ApplicationNameChanged ;)string AppName ﺑﻌﺪ از اﻳﻨﻜﻪ ﻧﻮع ﺗﻮاﺑﻊ را ﺗﻌﻴﻴﻦ ﻛﺮدﻳﻢ ،ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از آن ﻳﻚ روﻳﺪاد ﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ .در اﻳﻨﺠﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﻌﺮﻳﻒ ﻛـﺮدن ﻳـﻚ روﻳـﺪاد را ﻫﻤﺎﻧﻨﺪ ﺗﻌﺮﻳﻒ ﻛﺮدن ﻳﻚ آراﻳﻪ از ﻧﻮع delegateاﻳﺠﺎد ﺷﺪه در ﻣﺮﺣﻠﻪ ي ﻗﺒﻞ در ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ .ﺑﺮاي ﺗﻌﺮﻳﻒ ﻳﻚ روﻳﺪاد از ﻛﻠﻤﻪ ي ﻛﻠﻴﺪي eventﺑﻪ ﺻﻮرت زﻳﺮ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ: // Public Events public event _ApplicationNameChanged ;ApplicationNameChanged
1در زﺑﺎن C++ﻛﻪ ﻧﺴﻞ ﻗﺒﻠﻲ C#ﺑﻪ ﺷﻤﺎ ﻣﻲ رود ،ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻪ ﺻﻮرت روﻳﺪاد ﮔﺮا ﺑﺎﻳﺴﺘﻲ آراﻳﻪ ﻫﺎﻳﻲ اﻳﺠﺎد ﻣﻲ ﻛـﺮدﻳﻢ ﻛـﻪ ﻫـﺮ ﻳـﻚ از اﻋـﻀﺎي آن ﻳﻚ ﺗﺎﺑﻊ ﻣﻲ ﺑﻮد .ﺳﭙﺲ ﺗﻤﺎم ﻋﻨﺎﺻﺮ اﻳﻦ آراﻳﻪ را در ﻣﻮاﻗﻊ ﻣﻮرد ﻧﻴﺎز ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﺮدﻳﻢ .در C#اﻳﻦ ﻣﻮرد ﺑﻪ ﺻـﻮرﺗﻲ ﻛـﻪ در اﻳـﻦ ﻣﺜـﺎل ﻣـﺸﺎﻫﺪه ﻛﺮدﻳـﺪ ﭘﻴـﺎده ﺳﺎزي ﺷﺪه اﺳﺖ ،اﻣﺎ ﻣﻔﻬﻮم آن ﻫﻤﭽﻨﺎن ﻣﺎﻧﻨﺪ ﻗﺒﻞ اﺳﺖ.
٥٠٦
ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻓﺮض ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﻣﺮﺣﻠﻪ ﻳﻚ آراﻳﻪ ﺑﻪ ﻧﺎم ApplicationNameChangedاﻳﺠـﺎد ﻣـﻲ ﻛﻨﻴﻢ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺗﻮاﺑﻌﻲ از ﻧﻮع _ApplicationNameChangedرا در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻗﺒﻼ ﮔﻔﺘﻢ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻛﻨﺘﺮل را ﻃﺮاﺣﻲ ﻣﻲ ﻛﻨﻴﻢ و ﻣﻲ ﺧـﻮاﻫﻴﻢ ﻳـﻚ روﻳـﺪاد را ﺑـﻪ آن اﺿـﺎﻓﻪ ﻛﻨـﻴﻢ ،ﺑﺎﻳـﺪ زﻣـﺎن ﻓﺮاﺧﻮاﻧﻲ ﺗﻮاﺑﻊ داﺧﻞ آن روﻳﺪاد را ﻧﻴﺰ ﻣﺸﺨﺺ ﻛﻨﻴﻢ .در اﻳﻦ ﻛﻨﺘﺮل ﻣﻲ ﺧﻮاﻫﻴﻢ اﻳﻦ روﻳﺪاد زﻣﺎﻧﻲ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮد ﻛﻪ ﻛﺎرﺑﺮ روي دﻛﻤـﻪ ي btnApplicationNameﻛﻠﻴــﻚ ﻣــﻲ ﻛﻨــﺪ ،ﺑﻨــﺎﺑﺮاﻳﻦ ﻛــﺪ ﻣــﻮرد ﻧﻴــﺎز ﺑــﺮاي ﻓﺮاﺧــﻮاﻧﻲ روﻳــﺪاد را در ﻣﺘــﺪ btnApplicationName_Clickﻗﺮار ﻣﻲ دﻫﻴﻢ. ﻗﺒﻞ از ﻓﺮاﺧﻮاﻧﻲ ﻳﻚ روﻳﺪاد ﺑﺎﻳﺪ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﺒﻴﻨﻴﻢ آﻳﺎ ﻣﺘﺪي در ﻟﻴﺴﺖ روﻳﺪاد ﺑﺮاي ﻓﺮاﺧﻮاﻧﻲ ﻗﺮار دارد ﻳﺎ ﻧﻪ .زﻳﺮا اﮔﺮ ﻣﺘﺪي در اﻳﻦ ﻟﻴﺴﺖ ﻗﺮار ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ ﻧﻤﻲ ﺗﻮان آن را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮد .ﺑﺮاي ﺑﺮرﺳﻲ اﻳﻦ ﻣﻮرد در ﻳﻚ دﺳﺘﻮر ifﻣﻘﺪار روﻳﺪاد را ﺑـﺎ ﻋﺒـﺎرت null ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ .اﮔﺮ ﻣﻘﺪار روﻳﺪاد ﻣﺨﺎﻟﻒ ﺑﺎ ) nullﺗﻬﻲ( ﺑﻮد ،ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻣﺘﺪ ﻫﺎﻳﻲ در ﻟﻴﺴﺖ اﻳﻦ روﻳـﺪاد ﻗـﺮار دارﻧـﺪ و ﻣﻲ ﺗﻮاﻧﻴﻢ آن ﻣﺘﺪ ﻫﺎ را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ .ﺑﺮاي ﻓﺮاﺧﻮاﻧﻲ ﻳﻚ روﻳﺪاد ﺑﺎﻳﺪ ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﻣﺘﺪ ﻋﺎدي ﺑﺎ آن رﻓﺘﺎر ﻛﺮد .ﺑﺮاي ﻣﺜﺎل روﻳﺪادي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺗﻌﺮﻳﻒ ﻛﺮدﻳﻢ ﺷﺎﻣﻞ ﻣﺘﺪ ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﻳﻚ ﭘﺎراﻣﺘﺮ از ﻧـﻮع stringدرﻳﺎﻓـﺖ ﻣـﻲ ﻛﻨﻨـﺪ و ﻣﻘـﺪاري ﻫـﻢ ﺑﺮﻧﻤـﻲ ﮔﺮداﻧﻨﺪ .ﭘﺲ در اﻳﻨﺠﺎ ﻧﺎم روﻳﺪاد را ﺑﺎ رﺷﺘﻪ اي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ ﺗﻤﺎم ﻣﺘﺪ ﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ روﻳﺪاد ﻓﺮﺳـﺘﺎده ﺷـﻮد اﺣﻀﺎر ﻣﻲ ﻛﻨﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺗﻤﺎم ﻣﺘﺪ ﻫﺎﻳﻲ ﻛﻪ در ﻟﻴﺴﺖ اﻳﻦ روﻳﺪاد وﺟـﻮد دارﻧـﺪ را ﻓﺮاﺧـﻮاﻧﻲ ﻛـﺮده و رﺷﺘﻪ ي ﻣﺸﺨﺺ ﺷﺪه را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ آﻧﻬﺎ ارﺳﺎل ﻣﻲ ﻛﻨﺪ. )if (this.ApplicationNameChanged != null { (this.ApplicationNameChanged ;)Application.ProductName } ﺧﻮب ،ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺗﻤﺎم ﻣﺮاﺣﻞ ﻻزم ﺑﺮاي اﻳﺠﺎد ﻳﻚ روﻳﺪاد در اﻳﻦ ﻛﻨﺘﺮل ﻃﻲ ﺷﺪه اﺳﺖ و ﻣﻲ ﺗﻮاﻧﻴﻢ از روﻳﺪاد اﻳﺠﺎد ﺷـﺪه ﻫﻤﺎﻧﻨـﺪ روﻳﺪاد ﻫﺎي دﻳﮕﺮ ﻛﻨﺘﺮل ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ از روﻳﺪاد اﻳﺠﺎد ﺷﺪه در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از روﻳﺪاد اﻳﺠﺎد ﺷﺪه (1ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ Form1ﺑﺮوﻳﺪ و ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ،ﻳـﻚ ﻛﻨﺘـﺮل TextBoxﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ 3-13در ﻓﺮم ﻗﺮار دﻫﻴﺪ .ﺧﺎﺻﻴﺖ Textاﻳﻦ ﻛﻨﺘﺮل را ﻧﻴﺰ ﺑﺎ ﻣﻘﺪار txtApplicationNameﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ.
ﺷﻜﻞ 3-13
٥٠٧
(2ﺣﺎل ﻛﻨﺘﺮل UserControl11را از ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﻧﺘﺨﺎب ﻛﺮده و در ﭘﻨﺠﺮه ي Propertiesروي آﻳﻜـﻮن Eventsﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ روﻳﺪادﻫﺎي ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل ﻧﻤﺎﻳﺶ داده ﺷﻮد .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﺗﻤـﺎم روﻳـﺪاد ﻫـﺎﻳﻲ ﻛـﻪ ﺑﺮاي ﻳﻚ ﻛﻨﺘﺮل ﻣﻌﻤﻮﻟﻲ وﺟﻮد دارد در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﻟﻴﺴﺖ ﺷـﺪه اﻧـﺪ )ﺷـﻜﻞ . (4-13در ﻟﻴـﺴﺖ روﻳـﺪاد ﻫـﺎ ﺑـﻪ ﮔـﺮوه Miscﺑﺮوﻳﺪ و ﺑﺮ روي روﻳﺪاد ApplicationNameChangedدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻳﻚ ﻣﺘﺪ ﺑﺮاي اﻳﻦ روﻳﺪاد اﻳﺠﺎد ﺷﻮد.
ﺷﻜﻞ 4-13 (3ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ اﻳﺠﺎد ﺷﺪه وارد ﻛﻨﻴﺪ: (private void userControl11_ApplicationNameChanged )string AppName { ;txtApplicationName.Text = AppName } (4ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻫﺮ زﻣﺎن ﻛﻪ روي دﻛﻤـﻪ ي Application Nameﻛﻠﻴـﻚ ﻛﻨﻴـﺪ، اﺑﺘﺪا ﻛﺎدر ﻣﺘﻨﻲ داﺧﻞ ﻓﺮم ﺑﺎ اﺳﺘﻔﺎده از رﺷﺘﻪ ي ﺑﺮﮔﺮداﻧﺪه ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي روﻳﺪاد ﭘﺮ ﺷﺪه و ﺳﭙﺲ ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤـﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
٥٠٨
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اﺳﺘﻔﺎده از روﻳﺪاد ﻫﺎي ﻳﻚ ﻛﻨﺘﺮل ﺑﺴﻴﺎر واﺿﺢ اﺳﺖ و ﻛﺎري اﺳﺖ ﻛﻪ از اﺑﺘﺪاي ﻛﺘﺎب ﺗﺎﻛﻨﻮن ﺑﺎ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻣﺎﻧﻨـﺪ TextBoxو ﻳﺎ Buttonاﻧﺠﺎم ﻣﻲ داده اﻳﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﻛﻨﺘﺮل ﻣﻮرد ﻧﻈﺮ ﺧﻮد را در ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﻧﺘﺨﺎب ﻛﺮده و ﺑﺎ ﻛﻠﻴـﻚ روي آﻳﻜﻮن Eventsدر ﭘﻨﺠﺮه ي Propertiesﻟﻴﺴﺖ روﻳﺪاد ﻫﺎي آن را ﻣﺸﺎﻫﺪه ﻛﻨﻴﻢ .ﺳﭙﺲ در اﻳـﻦ ﻟﻴـﺴﺖ روﻳـﺪاد ﻣـﻮرد ﻧﻈﺮ ﺧﻮد را اﻧﺘﺨﺎب ﻛﺮده و روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﻢ .ﺑﺎ اﻳﻦ ﻛﺎر وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﻳﻚ ﻣﺘﺪ ﺑﺎ ﻫﻤﺎن ﺳﺎﺧﺘﺎري ﻛﻪ روﻳﺪاد ﻧﻴﺎز دارد اﻳﺠﺎد ﻛﺮده و آن را ﺑﻪ ﻟﻴﺴﺖ ﻣﺘﺪﻫﺎي ﻣﺮﺑﻮط ﺑﻪ آن روﻳﺪاد اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﺮ ﺑﺎر ﻛﻪ آن روﻳﺪاد رخ دﻫـﺪ ،ﻣﺘـﺪ اﻳﺠﺎد ﺷﺪه ﻧﻴﺰ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد. اﻏﻠﺐ ﻣﺘﺪ ﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي روﻳـﺪاد ﻫـﺎ در ﻗـﺴﻤﺘﻬﺎي ﻗﺒـﻞ ﺑـﻪ ﺻـﻮرت اﺗﻮﻣﺎﺗﻴـﻚ اﻳﺠـﺎد ﻣـﻲ ﺷـﺪ دو ﭘـﺎراﻣﺘﺮ ﺑـﻪ ﻧﺎﻣﻬـﺎي eاز ﻧـﻮع EventArgsو ﻧﻴﺰ senderاز ﻧﻮع objectرا درﻳﺎﻓﺖ ﻣﻲ ﻛﺮدﻧﺪ ،اﻣﺎ ﻣﺘﺪي ﻛﻪ در اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﻪ ﺻـﻮرت اﺗﻮﻣﺎﺗﻴـﻚ ﺑﺮاي روﻳﺪاد ApplicationNameChangedاﻳﺠﺎد ﺷﺪ ،ﻓﻘﻂ ﻳﻚ ﭘﺎراﻣﺘﺮ ﺑﻪ ﻧﺎم AppNameاز ﻧﻮع string را درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ .اﻳﻦ ﻣﻮرد ﻧﻴﺰ ﺑﻪ اﻳﻦ دﻟﻴﻞ اﺳﺖ ﻛﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻗﺎﻟﺐ ﻣﺘﺪ ﻫﺎﻳﻲ را ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﻳﺠـﺎد ﻣـﻲ ﻛﻨـﺪ از ﻗﺎﻟـﺐ ﺗﻌﺮﻳﻒ ﺷﺪه در ﻛﻼس ﺑﺮاي اﻳﺠﺎد روﻳﺪاد درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻗﺎﻟﺐ ﻣﺘﺪي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺮاي اﻳﻦ روﻳﺪاد اﻳﺠﺎد ﺷﺪه اﺳﺖ از delegateﺗﻌﺮﻳﻒ ﺷﺪه در داﺧﻞ ﻛﻨﺘﺮل ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ. ﺑﻌﺪ از اﻳﺠﺎد ﻣﺘﺪي ﺑﺮاي اﻳﻦ روﻳﺪاد ﻛﺎﻓﻲ اﺳﺖ ﻛﺪ ﻣﻮرد ﻧﻈﺮ ﺧﻮد را در آن وارد ﻛﻨﻴﻢ ﺗﺎ ﻫﺮ ﺑﺎر ﻛﻪ روﻳﺪاد رخ ﻣـﻲ دﻫـﺪ ،اﻳـﻦ ﻛـﺪ ﻧﻴـﺰ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮد .ﻛﺪي ﻛﻪ در اﻳﻨﺠﺎ وارد ﻣﻲ ﻛﻨﻴﻢ ،ﻓﻘﻂ ﻧﺎم ﺑﺮﻧﺎﻣﻪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﭘﺎراﻣﺘﺮ AppNameﺑﻪ ﻣﺘﺪ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد را در ﻛﺎدر ﻣﺘﻨﻲ ﻣﻮﺟﻮد در ﻓﺮم ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
زﻣﺎن اﺟﺮا ﻳﺎ زﻣﺎن ﻃﺮاﺣﻲ: در ﺷﺮاﻳﻂ ﺧﺎﺻﻲ ﻣﻤﻜﻦ اﺳﺖ ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﺑﺪاﻧﻴﺪ در ﺣﺎل ﺣﺎﺿﺮ ﻛﻨﺘﺮل ﺷﻤﺎ در زﻣﺎن ﻃﺮاﺣﻲ ﻗﺮار دارد و ﻳﺎ در زﻣﺎن اﺟـﺮا .ﻳـﻚ ﻛﻨﺘﺮل ﻫﻨﮕﺎﻣﻲ در زﻣﺎن ﻃﺮاﺣﻲ اﺳﺖ ﻛﻪ ﻛﺎرﺑﺮ آن را در ﻓﺮم ﻗﺮار داده اﺳﺖ و ﻣﻲ ﺗﻮاﻧﺪ ﺧﺎﺻﻴﺖ ﻫـﺎي آن را ﺑـﺎ اﺳـﺘﻔﺎده از ﭘﻨﺠـﺮه ي Propertiesﺗﻐﻴﻴﺮ دﻫﺪ .ﻫﻤﭽﻨﻴﻦ زﻣﺎﻧﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ي ﺣﺎوي ﻛﻨﺘﺮل اﺟﺮا ﺷﻮد و ﻛﺎرﺑﺮ ﺑﺘﻮاﻧﺪ از ﻣﺘﺪ ﻫﺎ و ﻳـﺎ روﻳـﺪاد ﻫـﺎي آن ﻛﻨﺘﺮل اﺳﺘﻔﺎده ﻛﻨﺪ ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﻨﺘﺮل در زﻣﺎن اﺟﺮا ﻗﺮار دارد. ﺑﺮاي ﻣﺜﺎل ﻣﻤﻜﻦ اﺳﺖ ﻛﻨﺘﺮل ﺷﻤﺎ ﺑﺨﻮاﻫﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺧﺎﺻﻴﺖ ﻣﺸﺨﺼﻲ از آن ﺗﻨﻈﻴﻢ ﺷﺪ ،ﺑﻪ ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺘﺼﻞ ﺷـﻮد .اﻣـﺎ اﮔﺮ ﻣﻘﺪار آن ﺧﺎﺻﻴﺖ در زﻣﺎن ﻃﺮاﺣﻲ ﺗﻨﻈﻴﻢ ﺷﻮد ﻣﺘﺼﻞ ﺷﺪن ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺮاي ﻛﻨﺘﺮل ﻣﻤﻜﻦ ﻧﺨﻮاﻫﺪ ﺑﻮد ،و اﻳﻦ ﻣـﻮرد ﻓﻘـﻂ زﻣﺎﻧﻲ اﻣﻜﺎن ﭘﺬﻳﺮ ﺧﻮاﻫﺪ ﺑﻮد ﻛﻪ ﺧﺎﺻﻴﺖ در زﻣﺎن اﺟﺮا و ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺪ ﺗﻨﻈﻴﻢ ﺷﻮد. ﻋﻤﻮﻣﺎً ﻫﺮ ﻛﻨﺘﺮل ﺧﻮد داراي ﻳﻚ ﺧﺎﺻﻴﺖ ﺑﻪ ﻧﺎم DesignModeاز ﻧﻮع ﺑﻮﻟﻴﻦ اﺳﺖ ﻛﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳـﺎ ﻛﻨﺘـﺮل در ﺣﺎﻟـﺖ ﻃﺮاﺣﻲ ﻗﺮار دارد ﻳﺎ ﻧﻪ؟ اﮔﺮ اﻳﻦ ﺧﺎﺻﻴﺖ ﻣﻘﺪار Trueرا ﺑﺮﮔﺮداﻧﺪ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻛﻨﺘﺮل در ﺣﺎﻟﺖ ﻃﺮاﺣﻲ اﺳـﺖ و اﮔـﺮ ﻣﻘـﺪار Falseرا ﺑﺮﮔﺮداﻧﺪ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻛﻨﺘﺮل در ﺣﺎﻟﺖ اﺟﺮا اﺳﺖ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻛﻨﺘﺮل Labelو ﻳﻚ ﻛﻨﺘﺮل Timerﺑﻪ UserControl1ﻣﻘﺪاري آن را ﺗﻐﻴﻴﺮ ﺧﻮاﻫﻴﻢ داد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﻨﺘﺮل در زﻣﺎن ﻃﺮاﺣﻲ ﺑﺎﺷﺪ ﻋﺒﺎرت ” “Design Modeدر ﻟﻴﺒﻞ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و زﻣﺎﻧﻲ ﻛﻪ ﻛﻨﺘﺮل در ﺣﺎﻟﺖ اﺟﺮا ﻗﺮار ﺑﮕﻴﺮد ،ﺳﺎﻋﺖ ﺳﻴﺴﺘﻢ در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻳﻚ ﻛﻨﺘﺮل ﻛﻪ "زﻣﺎن ﻃﺮاﺣﻲ" را ﻣﺘﻮﺟﻪ ﺷﻮد!
٥٠٩
(1 (2 (3
(4
ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻣﺮﺑﻮط ﺑﻪ UserControl1ﺑﺮوﻳﺪ و ﺳﭙﺲ اﻧﺪازه ي ﻓﻀﺎي ﻃﺮاﺣﻲ را ﻣﻘﺪاري ﺑـﺰرگ ﻛﻨﻴـﺪ ﺗـﺎ ﺑﺘﻮاﻧﻴﺪ ﻳﻚ ﻛﻨﺘﺮل ﻟﻴﺒﻞ را در زﻳﺮ ﻛﻨﺘﺮﻟﻬﺎي Buttonﻣﻮﺟﻮد در اﻳﻦ ﻗﺴﻤﺖ ﻗﺮار دﻫﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل Labelرا در زﻳﺮ ﻛﻨﺘﺮل ﻫﺎي Buttonﻗﺮار دﻫﻴﺪ و ﺧﺎﺻﻴﺖ Nameآن را ﺑـﺎ ﻣﻘﺪار lblTimeﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ. ﺣﺎل ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار روي ﻛﻨﺘﺮل Timerدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﻗﺴﻤﺖ ﭘﺎﻳﻴﻦ ﺑﺨﺶ ﻃﺮاﺣﻲ ﻛﻨﺘﺮل اﺿﺎﻓﻪ ﺷﻮد .ﻣﻘﺎدﻳﺮ ﭘﻴﺶ ﻓﺮض را ﺑﺮاي ﺧﺎﺻﻴﺘﻬﺎي اﻳﻦ ﻛﻨﺘﺮل ﻗﺒﻮل ﻛﻨﻴـﺪ ،ﻓﻘـﻂ ﺧﺎﺻـﻴﺖ Enabledآن را ﺑﺮاﺑـﺮ ﺑـﺎ Falseو ﺧﺎﺻﻴﺖ Intervalآن را ﺑﺮاﺑﺮ ﺑﺎ 100ﻗﺮار دﻫﻴﺪ. ﺣﺎل ﺑﺎﻳﺪ در زﻣﺎن ﺧﺎﺻﻲ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ﻛﻪ آﻳﺎ ﻛﻨﺘﺮل در زﻣﺎن ﻃﺮاﺣﻲ اﺳﺖ و ﻳﺎ در زﻣﺎن اﺟﺮا .ﺑﻬﺘﺮﻳﻦ ﻗﺴﻤﺖ ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﺘﺪ InitLayoutاﺳﺖ ﻛﻪ در ﻛﻼس System.Windows.Forms.Contorlﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ .اﻳﻦ ﻣﺘﺪ ﻫﻢ در زﻣﺎن ﻃﺮاﺣﻲ و ﻫﻢ در زﻣﺎن اﺟﺮا ﺑﻪ وﺳﻴﻠﻪ ي ﺑﺮﻧﺎﻣﻪ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد ،ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻬﺘﺮﻳﻦ ﻣﻜﺎن ﺑـﺮاي ﺑﺮرﺳﻲ اﻳﻦ ﻣﻮرد اﺳﺖ ﻛﻪ آﻳﺎ ﻛﻨﺘﺮل در زﻣﺎن ﻃﺮاﺣﻲ اﺳﺖ و ﻳﺎ در زﻣﺎن اﺟﺮا ،و اﮔﺮ در زﻣﺎن ﻃﺮاﺣﻲ ﺑﻮد ﻛﻨﺘﺮل Timer را ﻓﻌﺎل ﻛﻨﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻪ ﻗﺴﻤﺖ ﻛﺪ ﻧﻮﻳﺴﻲ ﻣﺮﺑﻮط ﺑﻪ UserControl1رﻓﺘﻪ و ﻛﺪ زﻳﺮ را ﺑﻪ اﻳـﻦ ﻛـﻼس اﺿـﺎﻓﻪ ﻛﻨﻴﺪ: )(protected override void InitLayout { // Are we in design mode )if (this.DesignMode { ;"lblTime.Text = "Design Mode } else { ;timer1.Enabled = true } }
(5در آﺧﺮ ﻧﻴﺰ ﺑﺎﻳﺪ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Tickﻛﻨﺘﺮل Timerرا ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ .اﻳـﻦ روﻳـﺪاد زﻣـﺎﻧﻲ ﻛـﻪ ﻛﻨﺘـﺮل Timerﻓﻌﺎل ﺑﺎﺷﺪ ،در ﻓﺎﺻﻠﻪ ي زﻣﺎﻧﻲ ﻣﺸﺨﺺ ﺷﺪه ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد .ﺑﺮ روي ﻛﻨﺘﺮل Timerدر ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Tickآن ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: )private void timer1_Tick(object sender, EventArgs e { // Display the time ;)(lblTime.Text = DateTime.Now.ToLongTimeString } (6ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﺪ ﺗﻐﻴﻴﺮات اﻋﻤﺎل ﺷﺪه در ﻛﻨﺘﺮل را در ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي Controlsﻧﻴﺰ درﻳﺎﻓﺖ ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ ﭘـﺮوژه ي ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل را ﺑـﻪ ﺻـﻮرت ﻛﺎﻣـﻞ ﻛﺎﻣﭙﺎﻳـﻞ ﻛﻨﻴـﺪ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﺑـﺎ اﺳـﺘﻔﺎده از ﭘﻨﺠـﺮه ي Solution Explorerروي ﭘﺮوژه ي MyNamespaceControlﻛﻠﻴﻚ راﺳـﺖ ﻛـﺮده و ﮔﺰﻳﻨـﻪ ي Buildرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ.
٥١٠
(7ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ Form1ﺑﺮﮔﺮدﻳﺪ و ﻛﻨﺘﺮل userControl1را از ﻓﺮم ﺣﺬف ﻛﻨﻴـﺪ .ﺳـﭙﺲ ﺑـﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل دﻳﮕﺮ از اﻳﻦ ﻧﻮع را در ﻓﺮم ﻗﺮار دﻫﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻨﺘﺮل Labelاﺿﺎﻓﻪ ﺷـﺪه ﻛﻪ ﺣﺎوي ﻣﺘﻦ Design Modeاﺳﺖ ،در اﻳﻦ ﻗﺴﻤﺖ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﺳﺖ )ﺷﻜﻞ (5-13
ﺷﻜﻞ 5-13 (8ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﻦ ﻣﻮﺟﻮد در Labelﺑﺎ ﺳﺎﻋﺖ ﻛﻨﻮﻧﻲ ﺳﻴﺴﺘﻢ ﺗﻌﻮﻳﺾ ﺧﻮاﻫﺪ ﺷﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻣﺘﺪ InitLayoutﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻛﻨﺘﺮل ﺑﺨﻮاﻫﺪ ﺑﻪ ﺻﻮرت اوﻟﻴﻪ ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ ﻣﻘﺪار دﻫﻲ ﺷﻮد ﻓﺮاﺧﻮاﻧﻲ ﺧﻮاﻫـﺪ ﺷـﺪ ،ﺣـﺎل ﭼﻪ ﻛﻨﺘﺮل در زﻣﺎن ﻃﺮاﺣﻲ ﺑﺎﺷﺪ و ﭼﻪ در زﻣﺎن اﺟﺮا .ﺧﺎﺻﻴﺖ DesignModeﻧﻴﺰ از اﻳﻦ ﻛﻨﺘﺮل ﻳﻚ ﻣﻘﺪار از ﻧـﻮع ﺑـﻮﻟﻴﻦ ﺑﺮﻣـﻲ ﮔﺮداﻧﺪ ،ﻛﻪ اﮔﺮ اﻳﻦ ﻣﻘﺪار ﺑﺮاﺑﺮ ﺑﺎ trueﺑﺎﺷﺪ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻛﻨﺘﺮل در زﻣﺎن ﻃﺮاﺣﻲ اﺳﺖ و اﮔﺮ ﺑﺮاﺑﺮ ﺑﺎ Falseﺑﺎﺷﺪ ﺑـﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻛﻨﺘﺮل در زﻣﺎن اﺟﺮا اﺳﺖ. اﮔﺮ ﻛﻨﺘﺮل در زﻣﺎن ﻃﺮاﺣﻲ ﺑﺎﺷﺪ ،ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﻣﺘﻦ ” “Design Modeرا در ﻟﻴﺒﻞ ﻧﻤﺎﻳﺶ دﻫﻴﺪ ،اﻣﺎ اﮔـﺮ ﻛﻨﺘـﺮل در زﻣـﺎن اﺟﺮا ﺑﺎﺷﺪ ﺑﺎﻳﺪ ﻛﻨﺘﺮل Timerرا ﻓﻌﺎل ﻛﻨﻴﺪ ﺗﺎ در ﻓﺎﺻﻠﻪ ﻫﺎي زﻣﺎﻧﻲ ﻣﺘﻮاﻟﻲ ﺳﺎﻋﺖ ﺳﻴﺴﺘﻢ را در ﭘﻨﺠﺮه ﻧﻤﺎﻳﺶ دﻫﺪ. )(protected override void InitLayout { // Are we in design mode )if (this.DesignMode { ;"lblTime.Text = "Design Mode } else { ;timer1.Enabled = true } }
٥١١
ﻣﺴﻠﻤﺎً ﻣﻮارد زﻳﺎدي وﺟﻮد دارد ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ رﻓﺘﺎر ﻛﻨﺘﺮﻟﻲ ﻛﻪ ﻃﺮاﺣﻲ ﻣﻲ ﻛﻨﻴﺪ در ﻫﻨﮕﺎم ﻃﺮاﺣﻲ و در ﻫﻨﮕﺎم اﺟﺮا ﻣﺘﻔـﺎوت ﺑﺎﺷـﺪ .در ﺗﻤﺎم اﻳﻦ ﻣﻮارد ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ DesignModeﺗﺸﺨﻴﺺ دﻫﻴﺪ ﻛﻪ ﻛﻨﺘﺮل در ﭼﻪ زﻣﺎﻧﻲ ﻗـﺮار دارد و ﺳـﭙﺲ ﻛـﺪ ﻣﻨﺎﺳﺒﻲ را اﺟﺮا ﻛﻨﻴﺪ. روﻳﺪاد Tickﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل Timerدر ﻓﺎﺻﻠﻪ ﻫﺎي زﻣﺎﻧﻲ ﻣﺘﻨﺎوب ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﺧﺎﺻﻴﺖ Intervalﻣﺸﺨﺺ ﻣـﻲ ﺷﻮد ﻓﺮاﺧﻮاﻧﻲ ﺷﺪه و ﻛﺪ درون آن ﺑﻪ وﺳﻴﻠﻪ ي ﺑﺮﻧﺎﻣﻪ اﺟﺮا ﻣﻲ ﺷﻮد .در اﻳﻨﺠﺎ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ اﻳﻦ روﻳﺪاد در ﻫﺮ 100ﻣﻴﻠﻲ ﺛﺎﻧﻴﻪ، ﻳﻚ ﺑﺎر ﻓﺮاﺧﻮاﻧﻲ ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﺮ زﻣﺎﻧﻲ ﻛﻪ اﻳﻦ ﻛﻨﺘﺮل ﻓﻌﺎل ﺷﻮد )ﻣﻘﺪار ﺧﺎﺻﻴﺖ Enabledﺑﺮاﺑﺮ ﺑﺎ trueﺷﻮد( در ﻫﺮ 100ﻣﻴﻠﻲ ﺛﺎﻧﻴﻪ ﻳﻚ ﺑﺎر زﻣﺎن ﺳﻴﺴﺘﻢ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺘﻬﺎي ﻣﻮﺟﻮد در ﻛﻼس DateTimeدرﻳﺎﻓﺖ ﺷﺪه و در ﺻـﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد. )private void timer1_Tick(object sender, EventArgs e { // Display the time ;)(lblTime.Text = DateTime.Now.ToLongTimeString } در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ در ﻇﺎﻫﺮ ﻛﻨﺘﺮل ﺗﻐﻴﻴﺮ اﻳﺠﺎد ﻛﺮده اﻳﻢ ،ﺑﺎﻳﺪ ﺑﻌﺪ از ﻛﺎﻣﭙﺎﻳﻞ ﻣﺠﺪد ﭘﺮوژه ي ﻣﺮﺑﻮط ﺑﻪ آن ﻛﻨﺘﺮل ﻓﻌﻠـﻲ را از داﺧﻞ ﻓﺮم ﺣﺬف ﻛﺮده و ﻳﻚ ﻧﻤﻮﻧﻪ ي ﺟﺪﻳﺪ از آن را در ﻓﺮم ﻗﺮار دﻫﻴﻢ .اﻣﺎ اﮔﺮ ﺻﺮﻓﺎً در ﻛﺪ ﻣﺮﺑﻮط ﺑـﻪ ﻛﻨﺘـﺮل ﺗﻐﻴﻴﺮاﺗـﻲ اﻳﺠـﺎد ﻛـﺮده ﺑﻮدﻳﻢ اﻳﻦ ﺗﻐﻴﻴﺮات ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺗﻮﺳﻂ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮرد اﺳﺘﻔﺎده در ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ درﻳﺎﻓﺖ ﻣﻲ ﺷﺪﻧﺪ.
اﻳﺠﺎد ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻓﺮم: در ﻗﺴﻤﺖ ﻗﺒﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﭼﻨﺪ وﻇﻴﻔﻪ ي ﻣﺮﺗﺒﻂ ﺑﻪ ﻳﻜﺪﻳﮕﺮ را در ﻗﺎﻟﺐ ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻨﺘﺮل دﺳـﺘﻪ ﺑﻨـﺪي ﻛﺮده و در ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ از آن اﺳﺘﻔﺎده ﻛﺮد .اﻣﺎ ﻫﻤﻮاره ﻧﻴﺰ ﻻزم ﻧﻴﺴﺖ ﻛﻪ ﻛﺎرﻫﺎي ﻣﻮرد ﻧﻴﺎز را ﺑﻪ ﺻﻮرت ﻳﻚ ﻛﻨﺘﺮل دﺳﺘﻪ ﺑﻨـﺪي ﻛﻨﻴﻢ و ﺳﭙﺲ در ﻳﻚ ﻓﺮم ﻗﺮار دﻫﻴﻢ ،ﺑﻠﻜﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻓﺮﻣﻬﺎي ﻋﻤﻮﻣﻲ اﻳﺠﺎد ﻛﺮده و از آن در ﻣﻮارد ﻣﻮرد ﻧﻴﺎز اﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻳـﻦ ﻛـﺎر، ﻫﻤﺎن ﻣﻨﻄﻖ اي اﺳﺖ ﻛﻪ ﺑﺮاي ﻧﻤﺎﻳﺶ ﻛﺎدر ﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ Open Fileو ﻳﺎ Printدر ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻛﺎر ﻣﻲ رود. ﻓﺮض ﻛﻨﻴﺪ ﺑﺨﻮاﻫﻴﺪ ﻳﻚ ﻓﺮم را در ﭼﻨﺪﻳﻦ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ اﻏﻠﺐ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي ﺧﻮد از ﻓﺮﻣﻲ ﺑﺮاي ﺟﺴﺘﺠﻮي ﻣﺸﺘﺮﻛﻴﻦ و ﻳﺎ از ﻓﺮﻣﻲ ﺑﺮاي ورود ﻛﺎرﺑﺮان و ﺗﻌﻴﻴﻦ ﻫﻮﻳﺖ آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻳﻦ ﻣﻮارد ﻣﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ ﻓﺮم ﻫﺎ را ﻃﺮاﺣﻲ ﻛﺮده و در ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻓﺮم ﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ ﻫﺮ زﻣﺎن ﻛﻪ ﺑﻪ اﺳﺘﻔﺎده از اﻳﻦ ﻓﺮم ﻫﺎ ﻧﻴﺎز داﺷﺘﻴﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ آﻧﻬﺎ را ﻧﻤﻮﻧﻪ ﺳﺎزي ﻛﺮده و در ﺑﺮﻧﺎﻣﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار دﻫﻴﺪ .اﻧﺠﺎم ﭼﻨﻴﻦ ﻛﺎري در .NETزﻳﺎد ﻣﺸﻜﻞ ﻧﻴﺴﺖ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ اﻧﺠـﺎم اﻳـﻦ ﻛﺎر ﺗﻔﺎوت ﭼﻨﺪاﻧﻲ ﺑﺎ اﻳﺠﺎد ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس و ﻳﺎ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻨﺘﺮل ﻧﺪارد .ﻓﻘﻂ ﺑﺎﻳﺪ ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘـﺪ ﻫـﺎﻳﻲ را ﺑـﻪ اﻳـﻦ ﻓـﺮم اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ ﻛﺎرﺑﺮ ﺑﺘﻮاﻧﺪ آن را ﺑﺮ اﺳﺎس ﻧﻴﺎز ﺧﻮد ﺗﻐﻴﻴﺮ داده ﺳﭙﺲ ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﺪ و ﻫﻤﭽﻨﻴﻦ ﺑﺘﻮاﻧﺪ ﻧﺘﻴﺠﻪ ي ﺑﺮﮔﺸﺖ داده ﺷـﺪه از آن ﻓﺮم را ﺑﺪﺳﺖ آورد.
اﻳﺠﺎد ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻓﺮم ﺣﺎوي ﻓﺮم ورود: در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻳﻚ ﻓﺮم ورود ﺳﺎده اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد .اﻟﺒﺘﻪ در ﻃﺮاﺣﻲ اﻳﻦ ﻓﺮم ،زﻳﺎد روي ﺗﻌﻴﻴﻦ ﻫﻮﻳﺖ ﻛﺎرﺑﺮ ﺗﻤﺮﻛﺰ ﻧﻤـﻲ ﻛﻨﻴﻢ و ﺳﻌﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﺑﻴﺸﺘﺮ ﺗﻮﺟﻪ ﺧﻮد را روي اﻳﺠﺎد و ﻧﻤﺎﻳﺶ ﻓﺮم ﺑﻪ ﻛﺎرﺑﺮ ﻣﺘﻤﺮﻛﺰ ﻛﻨﻴﻢ.
٥١٢
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﭘﺮوژه ي ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻓﺮم (1 (2
(3
(4
ﭘــﺮوژه ﻫــﺎﻳﻲ ﻛــﻪ ﻫــﻢ اﻛﻨــﻮن در ﻣﺤــﻴﻂ وﻳــﮋوال اﺳــﺘﻮدﻳﻮ ﺑــﺎز ﻫــﺴﺘﻨﺪ را ﺑﺒﻨﺪﻳــﺪ و ﻳــﻚ ﭘــﺮوژه ي ﺟﺪﻳــﺪ ﺑــﻪ ﻧــﺎم FormsLibraryاز ﻧﻮع Class Libraryاﻳﺠﺎد ﻛﻨﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي Solution Explorerروي ﻧﺎم ﭘـﺮوژه ﻛﻠﻴـﻚ راﺳـﺖ ﻛـﺮده و ﮔﺰﻳﻨـﻪ ي Add Referenceرا اﻧﺘﺨــــــﺎب ﻛﻨﻴــــــﺪ .ﺳــــــﭙﺲ از ﻣﻴــــــﺎن ﻛﺎﻣﭙﻮﻧﻨــــــﺖ ﻫــــــﺎي .NETﻣﻮﺟــــــﻮد، System.Windows.Formsرا اﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ. ﺣﺎل ﺑﺮ روي ﻧﺎم ﭘﺮوژه در ﭘﻨﺠﺮه ي Solution Explorerﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﮔﺰﻳﻨـﻪ ي Add Windows Formرا اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ ﺗـﺎ ﻳـﻚ ﻓـﺮم وﻳﻨـﺪوزي ﺟﺪﻳـﺪ ﺑـﻪ ﭘـﺮوژه اﺿـﺎﻓﻪ ﺷـﻮد .ﻧـﺎم اﻳـﻦ ﻓـﺮم را Login.csﻗﺮار داده و روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ. ﺑﺮاي اﻳﻨﻜﻪ ﻓﺮم ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﺷﻮد ﺑﺎﻳﺪ ﺗﻌﺪادي از ﺧﺎﺻﻴﺖ ﻫﺎي آن را ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺧﺎﺻـﻴﺖ ﻫـﺎي ﻓـﺮم را ﺑـﺮ اﺳﺎس ﻟﻴﺴﺖ زﻳﺮ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ FormBorderStyleرا ﺑﺮاﺑﺮ ﺑﺎ FixedDialogﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ MaximizeBoxرا ﺑﺮاﺑﺮ ﺑﺎ Falseﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ MinimizeBoxرا ﺑﺮاﺑﺮ ﺑﺎ Falseﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ StartPositionرا ﺑﺮاﺑﺮ ﺑﺎ CenterScreenﻗﺮار دﻫﻴﺪ.
(5ﺣﺎل دو ﻛﻨﺘﺮل ﻟﻴﺒﻞ ﺑﻪ ﻓﺮم اﺿـﺎﻓﻪ ﻛـﺮده و ﺧﺎﺻـﻴﺖ ﻫـﺎي Textآﻧﻬـﺎ را ﺑـﻪ ﺗﺮﺗﻴـﺐ ﺑﺮاﺑـﺮ ﺑـﺎ User Nameو Passwordﻗﺮار دﻫﻴﺪ. (6دو ﻛﻨﺘﺮل TextBoxروي ﻓﺮم ﻗﺮار دﻫﻴﺪ و ﺧﺎﺻﻴﺖ Nameآن ﻫﺎ را ﺑﻪ ﺗﺮﺗﻴﺐ ﺑﺎ ﻣﻘﺎدﻳﺮ txtUserNameو txtPasswordﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ .ﺳﭙﺲ ﺧﺎﺻﻴﺖ PasswordCharﻛﻨﺘﺮل txtPasswordرا ﺑﺮاﺑﺮ ﺑﺎ * ﻗﺮار دﻫﻴﺪ ﺗﺎ ﻛﻠﻤﻪ ي ﻋﺒﻮري ﻛﻪ در اﻳﻦ ﻛﺎدر وارد ﻣﻲ ﺷﻮد در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﻧﺸﻮد. (7ﻳﻚ ﻛﻨﺘﺮل Buttonﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮده و ﺧﺎﺻﻴﺖ ﻫﺎي آن را ﺑﺮ ﻃﺒﻖ ﻟﻴﺴﺖ زﻳﺮ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ btnOKﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textرا ﺑﺮاﺑﺮ ﺑﺎ OKﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ DialogResultرا ﺑﺮاﺑﺮ ﺑﺎ OKﻗﺮار دﻫﻴﺪ.
(8ﻛﻨﺘﺮل Buttonدﻳﮕﺮي روي ﻓﺮم ﻗﺮار داده و ﺧﺎﺻﻴﺖ ﻫﺎي آن را ﺑﺮ ﻃﺒﻖ ﻟﻴﺴﺖ زﻳﺮ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑﺎ btnCancelﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Cancelﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ DialogResultآن را ﺑﺮاﺑﺮ ﺑﺎ Cancelﻗﺮار دﻫﻴﺪ.
(9ﻓﺮم ﺗﻜﻤﻴﻞ ﺷﺪه ي ﺷﻤﺎ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 6-13ﺷﺪه ﺑﺎﺷﺪ.
٥١٣
6-13 ﺷﻜﻞ ﻛﻠﻴـﻚ راﺳـﺖ ﻛـﺮده و ﻧـﺎم آن را ﺑـﻪClass1.cs روي ﻓﺎﻳﻞSolution Explorer ( در ﭘﻨﺠﺮه ي10 : ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ آن ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ. ﺗﻐﻴﻴﺮ دﻫﻴﺪLoginEventArgs.cs public class LoginEventArgs : EventArgs { // Public member int UserID; // Constructor public LoginEventArgs(int userIdentifier) { UserID = userIdentifier; } } : وارد ﻛﻨﻴﺪLogin ﺑﺮوﻳﺪ و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻛﻼسLogin ( ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻓﺮم11 public partial class Login : Form { // Private members private int intAttemptCount = 0; private bool blnAllowClosing = false; private int intUserID; // Public delegates public delegate void _LoginFailed(Object sender, EventArgs e); public delegate void _LoginSucceeded(Object sender, LoginEventArgs e); public delegate void _LoginCancelled(Object sender, EventArgs e); // Public events public event _LoginFailed LoginFailed; public event _LoginSucceeded LoginSucceeded; public event _LoginCancelled LoginCancelled;
٥١٤
(12ﺣﺎل ﺑﺎﻳﺪ ﻳﻚ ﺧﺎﺻﻴﺖ ﻓﻘﻂ ﺧﻮاﻧﺪﻧﻲ ﺑﻪ ﻛﻼس اﻳﻦ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﻢ ﺗﺎ اﻓﺮادي ﻛﻪ از اﻳﻦ ﻓﺮم اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﺘﻮاﻧﺪ ﺷﻨﺎﺳﻪ ي ﻣﺮﺑﻮط ﺑﻪ ﻛﺎرﺑﺮي ﻛﻪ ﺗﻮاﻧﺴﺘﻪ اﺳﺖ ﺑﺎ ﻣﻮﻓﻘﻴﺖ وارد ﺳﻴﺴﺘﻢ ﺷﻮد را درﻳﺎﻓﺖ ﻛﻨﻨﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺪ زﻳﺮ را ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ: public int UserID { get { ;return intUserID } } (13ﺑﺮاي ﺳﺎدﮔﻲ ﺑﻴﺸﺘﺮ ﻛﺎر ﺑﺎ اﻳﻦ ﻛﻨﺘﺮل ﺑﻬﺘﺮ اﺳﺖ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﺮم ﻓﻌﺎل ﻣﻲ ﺷﻮد ،ﻛـﺎدر UserNameرا ﺑـﺎ ﻧـﺎم اي ﻛـﻪ ﻛﺎرﺑﺮ ﺑﻪ وﺳﻴﻠﻪ ي آن وارد وﻳﻨﺪوز ﺷﺪه اﺳﺖ ﭘﺮ ﻛﻨﻴﻢ .ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻧﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺎ آن وارد وﻳﻨـﺪوز ﺷـﺪه اﺳـﺖ ﻣـﻲ ﺗﻮاﻧﻴﻢ از ﺧﺎﺻﻴﺖ UserNameاز ﻛﻼس Environmentاﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻨﻜﻪ ﻫﻨﮕﺎم ﻓﻌـﺎل ﺷـﺪن ﻓـﺮم اﻳﻦ ﻛﺎر اﻧﺠﺎم ﺷﻮد ،از روﻳﺪاد Activatedدر ﻓﺮم اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ. ﻓﺮم Loginرا در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم اﻧﺘﺨﺎب ﻛﺮده و در ﭘﻨﺠـﺮه ي Propertiesروي آﻳﻜـﻮن Events ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻟﻴﺴﺖ روﻳﺪاد ﻫﺎي آن ﻧﻤﺎﻳﺶ داده ﺷﻮد .ﺳﭙﺲ در اﻳﻦ ﻟﻴﺴﺖ روﻳﺪاد Activatedرا اﻧﺘﺨﺎب ﻛـﺮده و روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: )private void Login_Activated(object sender, EventArgs e { // Populate the UserName text box ;txtUserName.Text = Environment.UserName // Set the focus to the password text box ;)(txtPassword.Focus } (14در اﻳﻦ ﻓﺮم ﻧﻴﺎز دارﻳﻢ ﻛﻪ ﺑﺴﺘﻪ ﺷﺪن ﻓﺮم را ﻛﻨﺘﺮل ﻛﻨﻴﻢ ﺗﺎ در ﺷﺮاﻳﻂ ﺧﺎﺻﻲ از آن ﺟﻠﻮﮔﻴﺮي ﻛﻨﻴﻢ و ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻧـﺪﻫﻴﻢ ﻛﻪ ﻓﺮم را ﺑﺒﻨﺪد .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﻢ از روﻳﺪاد FormClosingﻣﺮﺑﻮط ﺑﻪ ﻓﺮم Loginاﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﻣﺠﺪداً ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ ﻓﺮم Loginﺑﺮوﻳﺪ و ﻓﺮم را اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ .در ﻟﻴـﺴﺖ روﻳـﺪاد ﻫـﺎي آن در ﭘﻨﺠـﺮه ي ،Propertiesروي ﮔﺰﻳﻨﻪ ي FormClosingدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد ﺑﻪ ﺻـﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void Login_FormClosing(object sender, )FormClosingEventArgs e { // If we are not allowing the form to close... )if (!blnAllowClosing { // Set the cancel flag to true
٥١٥
e.Cancel = true; } } ﻛﻠﻴﻚ ﻛﺮد ﺑﺎﻳﺪ ﻛﺪي را اﺟﺮا ﻛﻨﻴﻢ ﺗﺎ ﻧﺎم ﻛـﺎرﺑﺮي و ﻛﻠﻤـﻪ ي ﻋﺒـﻮر او راOK ( ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ در اﻳﻦ ﻓﺮم روي دﻛﻤﻪ ي15 دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗـﺎ ﻣﺘـﺪ ﻣﺮﺑـﻮط ﺑـﻪbtnOK ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺸﺘﻪ و روي ﻛﻨﺘﺮل.ﻛﻨﺘﺮل ﻛﻨﺪ : ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ. آن اﻳﺠﺎد ﺷﻮدClick روﻳﺪاد private void btnOK_Click(object sender, EventArgs e) { // Was a user name entered? if(txtUserName.Text.Trim().Length > 0) { // Was the password correct? if(txtPassword.Text == "secret") { // Successful login, set the User ID intUserID = 27; // Raise the LoginSucceeded event if(this.LoginSucceeded != null) this.LoginSucceeded(this, new LoginEventArgs(intUserID)); // Turn on the allow closing flag blnAllowClosing = true; } else { // Inform the user // that the password was invalid MessageBox.Show("The password you entered" + " was invalid.","Login"); // Increment the attempt count intAttemptCount += 1; // Check the attempt count if (intAttemptCount == 3) { // Raise the LoginFailed event if(this.LoginFailed != null) this.LoginFailed(this, new EventArgs()); // Set the Cancel dialog result
٥١٦
= this.DialogResult ;DialogResult.Cancel // Turn on the allow closing flag ;blnAllowClosing = true } } } else { // Inform the user // that they must supply a user name MessageBox.Show("You must supply a User Name.", ;)""Login } } (16در اﻧﺘﻬﺎ ﻧﻴﺰ ﺑﺎﻳﺪ ﻛﺪي را ﺑﺮاي ﻛﻨﺘﺮل btnCancelﺑﻨﻮﻳﺴﻴﻢ ﺗﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي اﻳﻦ ﻛﻨﺘﺮل ﻛﻠﻴﻚ ﻛﺮد ،ﻋﻤـﻞ ﻣﻨﺎﺳﺒﻲ رخ دﻫﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺮدﻳﺪ و روي ﻛﻨﺘﺮل btnCancelدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: )private void btnCancel_Click(object sender, EventArgs e { // Raise the LoginCancelled event )if(this.LoginCancelled != null ;))(this.LoginCancelled(this, new EventArgs // Turn on the allow closing flag ;blnAllowClosing = true }
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﺑﺘﺪاي اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﻌﺪ از ﺳﺎﺧﺘﻦ ﭘﺮوژه ،ﻳﻚ ارﺟﺎع ﺑﻪ ﻓﺎﻳﻞ System.Windows.Formsدر ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻣﻲ ﻛﻨـﻴﻢ. ﻋﻠﺖ اﻳﻦ ﻛﺎر ﻧﻴﺰ اﻳﻦ اﺳﺖ ﻛﻪ ﻃﻲ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ از ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻓﻀﺎي ﻧﺎم اﺳﺘﻔﺎده ﻛﻨﻴﻢ و وﻳـﮋوال اﺳـﺘﻮدﻳﻮ ﺑـﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض اﻳﻦ ﻓﻀﺎي ﻧﺎم را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ از ﻧﻮع Class Libraryاﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ اﺿﺎﻓﻪ ﻧﻤﻲ ﻛﻨﺪ. ﺑﻌﺪ از اﻧﺠﺎم اﻳﻦ ﻛﺎر ﻳﻚ ﻓﺮم وﻳﻨﺪوزي ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮده ،ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮرد ﻧﻴﺎز را در آن ﻗـﺮار ﻣـﻲ دﻫـﻴﻢ و ﺧﺎﺻـﻴﺘﻬﺎي آن را ﻧﻴـﺰ ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﻨﻴﻢ .ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺗﻐﻴﻴﺮ ﻣﻲ دﻫـﻴﻢ ،ﺧﺎﺻـﻴﺖ DialogResultدر ﻛﻨﺘـﺮل Buttonاﺳﺖ .ﺑﺎ ﻣﻘﺪار دادن ﺑﻪ اﻳﻦ ﺧﺎﺻﻴﺖ ﺳﺒﺐ ﻣﻲ ﺷﻮﻳﻢ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي ﻳﻜﻲ از دﻛﻤﻪ ﻫﺎي OKو ﻳـﺎ Cancel ﻛﻠﻴـــﻚ ﻛﻨـــﺪ ،اﻳـــﻦ دﻛﻤـــﻪ ﻫـــﺎ ﺑﺎﻋـــﺚ ﺷـــﻮﻧﺪ ﻛـــﻪ ﻓـــﺮم ﺑـــﺴﺘﻪ ﺷـــﺪه و ﻣﻘـــﺪار DialogResult.OKو ﻳـــﺎ DialogResult.Cancelﺑﻪ اﺣﻀﺎر ﻛﻨﻨﺪه ي ﻓﺮم ﺑﺮﮔﺸﺖ داده ﺷﻮد. در ﻗﺴﻤﺖ ﻗﺒﻞ ﻫﻨﮕﺎﻣﻲ ﻛﻪ در راﺑﻄﻪ ﺑﺎ روﻳﺪاد ﻫﺎ و ﻧﺤﻮه ي اﻳﺠﺎد آﻧﻬﺎ ﺻﺤﺒﺖ ﻣﻲ ﻛﺮدﻳﻢ ،ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛﻪ ﺳـﺎﺧﺘﺎر ﺗـﻮاﺑﻌﻲ ﻛـﻪ در ﻟﻴﺴﺖ ﻳﻚ روﻳﺪاد ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﻫﻢ ﺑﺎﺷﺪ .ﻫﻤﭽﻨﻴﻦ دﻳﺪﻳﻢ ﻣﻌﻤﻮﻻً ﺗﻮاﺑﻌﻲ ﻛﻪ ﻫﻨﮕﺎم رخ دادن ﻳـﻚ روﻳـﺪاد ﻓﺮاﺧـﻮاﻧﻲ ﻣـﻲ
٥١٧
ﺷﻮﻧﺪ دو ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ ﻳﻜﻲ از آﻧﻬﺎ از ﻧﻮع Objectاﺳﺖ و دﻳﮕﺮي از ﻧﻮع EventArgsو ﻳﺎ ﻳﻜﻲ از ﻛـﻼس ﻫﺎي ﻣﺸﺘﻖ ﺷﺪه از آن .اﻟﺒﺘﻪ ﻫﻴﭻ اﻟﺰاﻣﻲ در رﻋﺎﻳﺖ اﻳﻦ ﻣﻮرد وﺟﻮد ﻧﺪارد و ﻣﻲ ﺗﻮان روﻳﺪاد ﻫﺎﻳﻲ را اﻳﺠﺎد ﻛﺮد ﻛﻪ ﻣﺘﺪ ﻫـﺎي آن ﻫـﻴﭻ ﭘﺎراﻣﺘﺮي درﻳﺎﻓﺖ ﻧﻜﻨﻨﺪ و ﻳﺎ ﺑﻴﺶ از دو ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻛﻨﻨﺪ )ﻫﻤﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻞ(. اﻣﺎ ﻣﻌﻤﻮﻻً ﺑﻪ ﺻﻮرت ﻗﺮارداد ﻫﻨﮕﺎم اﻳﺠﺎد ﻳﻚ روﻳﺪاد ،ﻣﺘﺪﻫﺎي ﻣﺮﺑﻮط ﺑﻪ آن را ﺑﻪ ﺻﻮرﺗﻲ ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ دو ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻛﻨﺪ:
ﭘﺎراﻣﺘﺮ اول ﻛﻪ از ﻧﻮع Objectاﺳﺖ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ي ﺷﻴﺊ اي اﺳﺖ ﻛﻪ اﻳﻦ روﻳﺪاد را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده اﺳﺖ. ﭘﺎراﻣﺘﺮ دوم ﻛﻪ از ﻧﻮع EventArgsو ﻳﺎ ﻳﻜﻲ از ﻛﻼس ﻫﺎي ﻣﺸﺘﻖ ﺷﺪه از آن اﺳﺖ ،ﺣﺎوي اﻃﻼﻋﺎت ﻻزم در ﻣـﻮرد روﻳﺪاد رخ داده اﺳﺖ .ﻣﻌﻤﻮﻻً اﮔﺮ ﻫﻨﮕﺎم رخ دادن ﻳﻚ روﻳﺪاد ﻧﻴﺎز ﻧﺒﺎﺷﺪ ﻛﻪ اﻃﻼﻋﺎت ﺧﺎﺻﻲ ﺑﻪ ﻣﺘﺪ ﻫﺎ ارﺳﺎل ﺷﻮد از ﻛﻼس EventArgsاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ .اﻣﺎ اﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ را ﺑﻪ ﻣﺘﺪ ﻫﺎ ارﺳﺎل ﻛﻨﻴﻢ ،ﻣـﻲ ﺗـﻮاﻧﻴﻢ ﻳـﻚ ﻛـﻼس از EventArgsﻣﺸﺘﻖ ﻛﺮده و ﻛﻼس را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﺪ اﻳـﻦ ﭘـﺎراﻣﺘﺮ ﻫـﺎ را در ﺧـﻮد ﻧﮕﻬـﺪاري ﻛﻨـﺪ. ﺳﭙﺲ ﭘﺎراﻣﺘﺮ دوم ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد را ،از ﻧﻮع ﻛﻼس اﻳﺠﺎد ﺷﺪه در ﻧﻈﺮ ﺑﮕﻴﺮﻳﻢ.
در ﺗﻌﺮﻳﻒ روﻳـﺪاد ﻫـﺎي ﻣﺮﺑـﻮط ﺑـﻪ اﻳـﻦ ﻛـﻼس ﻣـﻲ ﺧـﻮاﻫﻴﻢ اﻳـﻦ ﻗﺎﻋـﺪه را رﻋﺎﻳـﺖ ﻛﻨـﻴﻢ ،ﺑﻨـﺎﺑﺮاﻳﻦ اﺑﺘـﺪا ﻛﻼﺳـﻲ را از ﻛـﻼس EventArgsﻣﺸﺘﻖ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ اﻃﻼﻋﺎت ﻻزم ﺑﺮاي رخ دادن ﻳﻚ روﻳﺪاد را در آن ﻗﺮار دﻫﻴﻢ و ﺑﻪ ﻣﺘﺪ ﻫـﺎي ﻓﺮاﺧـﻮاﻧﻲ ﺷﺪه ارﺳﺎل ﻛﻨﻴﻢ .اﻟﺒﺘﻪ اﺳﺘﻔﺎده از اﻳﻦ ﻛﻼس ﻓﻘﻂ زﻣﺎﻧﻲ ﻻزم اﺳﺖ ﻛﻪ روﻳﺪاد LoginSucceededرخ دﻫﺪ .در اﻳـﻦ ﺣﺎﻟـﺖ ﻻزم اﺳﺖ ﻛﻪ ﺷﻨﺎﺳﻪ ي ﻛﺎرﺑﺮي ﻛﻪ ﺑﺎ ﻣﻮﻓﻘﻴﺖ وارد ﺳﻴﺴﺘﻢ ﺷﺪه اﺳﺖ را ﺑﻪ ﻣﺘﺪ ﻫﺎ ارﺳﺎل ﻛﻨﻴﻢ .در ﺑﻘﻴﻪ ي ﻣﻮارد ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻛـﻼس EventArgsاﺳﺘﻔﺎده ﻛﻨﻴﻢ .زﻳﺮا ﻫﻨﮕﺎم رخ دادن دﻳﮕﺮ روﻳﺪاد ﻫﺎ ﻻزم ﻧﻴﺴﺖ ﻫﻴﭻ اﻃﻼﻋﺎت ﺧﺎﺻﻲ را ﺑﻪ آﻧﻬﺎ ارﺳﺎل ﻛﻨﻴﻢ. public class LoginEventArgs : EventArgs { // Public member ;int UserID // Constructor )public LoginEventArgs(int userIdentifier { ;UserID = userIdentifier } } ﺑﻌﺪ از اﻧﺠﺎم دادن اﻳﻦ ﻣﻮارد ﺑﻪ ﻃﺮاﺣﻲ ﻓﺮم و ﻣﺘﺪ ﻫﺎي ﻣﻮرد ﻧﻴﺎز در آن ﻣﻲ ﭘﺮدازﻳﻢ .در اﺑﺘﺪا ﺳﻪ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع privateﺗﻌﺮﻳـﻒ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻣﺘﺪ ﻫﺎي داﺧﻞ ﻓﺮم ﻣـﻮرد اﺳـﺘﻔﺎده ﻗـﺮار ﺧﻮاﻫﻨـﺪ ﮔﺮﻓـﺖ .ﻣﺘﻐﻴﻴـﺮ intAttemptCountﺑـﺮاي ﺷﻤﺎرش ﺗﻌﺪاد ﻣﺮاﺗﺒﻲ اﺳﺖ ﻛﻪ ﻛﺎرﺑﺮ ﺳﻌﻲ ﻛﺮده اﺳﺖ وارد ﺳﻴﺴﺘﻢ ﺷﻮد و ﺑﺎ ﺷﻜﺴﺖ ﻣﻮاﺟﻪ ﺷﺪه اﺳﺖ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﻘﺪار اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﻋﺪد ﺳﻪ ﺑﺮﺳﺪ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺑﺴﺘﻪ ﺧﻮاﻫﺪ ﺷﺪ .ﻣﺘﻐﻴﻴﺮ blnAllowClosingﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن اﻳﻦ ﻣﻮرد ﺑﻪ ﻛﺎر ﻣﻲ رود ﻛﻪ آﻳﺎ ﻓﺮم ﻣﻲ ﺗﻮاﻧﺪ ﺑﺴﺘﻪ ﺷﻮد ﻳﺎ ﺧﻴﺮ .اﻳﻦ ﻣﺘﻐﻴﻴﺮ در ﻃﻲ ﺑﺮﻧﺎﻣﻪ و در ﺷﺮاﻳﻂ ﻣﺨﺘﻠﻒ ﻣﻘﺎدﻳﺮ ﻣﺨﺘﻠﻔﻲ را ﻗﺒﻮل ﺧﻮاﻫﺪ ﻛـﺮد. ﻣﺘﻐﻴﻴﺮ intUserIDﻧﻴﺰ ﺑﺮاي ذﺧﻴﺮه ي ﺷﻨﺎﺳﻪ ي ﻛﺎرﺑﺮي ﺑﻪ ﻛﺎر ﻣﻲ رود ﻛﻪ ﺗﻮاﻧﺴﺘﻪ اﺳﺖ ﺑﺎ ﻣﻮﻓﻘﻴـﺖ وارد ﺳﻴـﺴﺘﻢ ﺷـﻮد )ﺑـﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻧﺎم ﻛﺎرﺑﺮي و ﻛﻠﻤﻪ ي ﻋﺒﻮر را درﺳﺖ وارد ﻛﺮده اﺳﺖ(. public partial class Login : Form { // Private members
٥١٨
;private int intAttemptCount = 0 ;private bool blnAllowClosing = false ;private int intUserID ﺑﻌﺪ از ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴﺮ ﻫﺎي ﻣﻮرد ﻧﻴﺎز ،ﺑﺎﻳﺪ ﺳﻪ روﻳﺪاد ﺑﺮاي ﻓﺮم اﻳﺠﺎد ﻛﻨﻴﻢ .روﻳﺪاد اول LoginFailedاﺳﺖ و زﻣﺎﻧﻲ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﺎرﺑﺮ ﺳﻪ ﺑﺎر ﻛﻠﻤﻪ ي ﻛﺎرﺑﺮي را ﺑﻪ ﺻﻮرت ﻧﺎدرﺳﺖ وارد ﻛﺮده ﺑﺎﺷﺪ .در اﻳﻦ ﺣﺎﻟﺖ ﻧﻴﺎز ﻧﻴﺴﺖ اﻃﻼﻋـﺎت ﺧﺎﺻـﻲ ﺑـﻪ ﻣﺘـﺪ ﻫﺎﻳﻲ ﻛﻪ ﻗﺮار اﺳﺖ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮﻧﺪ ﻓﺮﺳﺘﺎده ﺷﻮد ،ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮ ﻃﺒﻖ ﻗﺮاردادي ﻛﻪ ﮔﻔﺘﻢ ﻣﺘﺪ ﻫﺎﻳﻲ ﻛﻪ ﻳﻚ ﭘﺎراﻣﺘﺮ از ﻧـﻮع Objectو ﻳﻚ ﭘﺎراﻣﺘﺮ از ﻧﻮع EventArgsدارﻧﺪ ﻣﻲ ﺗﻮاﻧﻨﺪ در ﻟﻴﺴﺖ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد ﻗﺮار ﺑﮕﻴﺮﻧﺪ. روﻳﺪاد دوم LogionSucceededاﺳﺖ و ﻫﻨﮕﺎﻣﻲ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﺎرﺑﺮ ﺑﺘﻮاﻧـﺪ ﺑـﻪ درﺳـﺘﻲ وارد ﺳﻴـﺴﺘﻢ ﺷـﻮد .ﺑـﻪ ﻋﺒﺎرت دﻳﮕﺮ اﻳﻦ روﻳﺪاد زﻣﺎﻧﻲ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﺎرﺑﺮ ﻧﺎم و ﻛﻠﻤﻪ ي ﻋﺒﻮر را ﺑﻪ درﺳﺘﻲ وارد ﻛﺮده ﺑﺎﺷﺪ .ﻣﺘﺪ ﻫﺎﻳﻲ ﻛـﻪ ﻫﻨﮕـﺎم رخ دادن اﻳﻦ روﻳﺪاد ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮﻧﺪ ،ﻧﻴﺎز دارﻧﺪ ﺷﻨﺎﺳﻪ ي ﻛﺎرﺑﺮي ﻛﻪ ﺗﻮاﻧﺴﺘﻪ اﺳﺖ وارد ﺷﻮد را درﻳﺎﻓﺖ ﻛﻨﻨﺪ .ﭘﺲ اﻳﻦ ﻣﺘﺪ ﻫﺎ ﺑﺎﻳﺪ ﻳﻚ ﭘﺎراﻣﺘﺮ از ﻧﻮع Objectو ﻳﻚ ﭘﺎراﻣﺘﺮ از ﻧﻮع ) LoginEventArgsﻛﻪ ﺧﻮد از ﻛﻼس EventArgsﻣﺸﺘﻖ ﺷـﺪه اﺳﺖ( درﻳﺎﻓﺖ ﻛﻨﻨﺪ ﺗﺎ ﺑﺘﻮاﻧﻨﺪ در ﻟﻴﺴﺖ روﻳﺪاد LoginSucceededﻗﺮار ﺑﮕﻴﺮﻧﺪ. روﻳﺪاد آﺧﺮ ﻧﻴﺰ روﻳﺪاد LoginCanceledاﺳﺖ و زﻣﺎﻧﻲ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﺎرﺑﺮ روي دﻛﻤﻪ ي Cancelﻛﻠﻴﻚ ﻛﻨﺪ. اﻳﻦ روﻳﺪاد ﻧﻴﺰ ﻣﺸﺎﺑﻪ روﻳﺪاد LoginFailedاﺳﺖ و ﻣﺘﺪ ﻫﺎﻳﻲ ﻛﻪ ﭘﺎراﻣﺘﺮي را از ﻧﻮع Objectو ﭘﺎراﻣﺘﺮ دﻳﮕﺮي را از ﻧﻮع EventArgsدرﻳﺎﻓﺖ ﻛﻨﻨﺪ ﻣﻲ ﺗﻮاﻧﻨﺪ در ﻟﻴﺴﺖ اﻳﻦ روﻳﺪاد ﻗﺮار ﺑﮕﻴﺮﻧﺪ. // Public delegates public delegate void _LoginFailed(Object sender, ;)EventArgs e public delegate void _LoginSucceeded(Object sender, ;)LoginEventArgs e public delegate void _LoginCancelled(Object sender, ;)EventArgs e // Public events ;public event _LoginFailed LoginFailed ;public event _LoginSucceeded LoginSucceeded ;public event _LoginCancelled LoginCancelled ﺑﻌﺪ از ﺗﻌﺮﻳﻒ روﻳﺪاد ﻫﺎي ﻣﻮرد ﻧﻴﺎز در ﻓﺮم ،ﻳﻚ ﺧﺎﺻﻴﺖ ﻓﻘﻂ-ﺧﻮاﻧﺪﻧﻲ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ اﻓﺮادي ﻛﻪ از اﻳﻦ ﻓﺮم در ﺑﺮﻧﺎﻣﻪ ﻫـﺎي ﺧـﻮد اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﺘﻮاﻧﻨﺪ ﺑﻪ ﺷﻨﺎﺳﻪ ي ﻛﺎرﺑﺮي ﻛﻪ وارد ﺳﻴﺴﺘﻢ ﺷﺪه اﺳﺖ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ. public int UserID { get { ;return intUserID } }
٥١٩
ﺑﻌﺪ از اﻳﻨﻜﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ در ﺣﺎﻓﻈﻪ ﺑﺎر ﮔﺬاري ﺷﺪ ،روﻳﺪاد Activatedآن ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد .در اﻳﻦ زﻣﺎن ﺑـﺮاي اﻳﻨﻜـﻪ ﻛـﺎر را ﺑﺮاي ﻛﺎرﺑﺮ ﺳﺎده ﺗﺮ ﻛﻨﻴﻢ ،ﻧﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺎ آن وارد وﻳﻨﺪوز ﺷﺪه اﺳﺖ را ﺑﺪﺳﺖ آورده و در ﻛـﺎدر User Nameﻗـﺮار ﻣـﻲ دﻫﻴﻢ .ﺑﺮاي ﺑﺪﺳﺖ آوردن ﻧﺎم ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﻴﻢ از ﺧﺎﺻﻴﺖ UserNameدر ﻛﻼس Environmentاﺳﺘﻔﺎده ﻛﻨﻴﻢ .1ﺑﻌـﺪ از ﻗﺮار دادن ﻧﺎم ﻛﺎرﺑﺮ در ﻓﻴﻠﺪ ،User Nameﻓﻮﻛﻮس را ﺑﻪ ﻛﺎدر Passwordاﺧﺘﺼﺎص ﻣﻲ دﻫﻴﻢ ﺗﺎ ﻋﺒﺎراﺗﻲ ﻛﻪ ﺑﻌـﺪ از اﻳـﻦ ﺗﺎﻳﭗ ﻣﻲ ﺷﻮﻧﺪ در ﻛﺎدر Passwordﻗﺮار ﮔﻴﺮﻧﺪ. )private void Login_Activated(object sender, EventArgs e { // Populate the UserName text box ;txtUserName.Text = Environment.UserName // Set the focus to the password text box ;)(txtPassword.Focus } ﺑﻪ ﺧﺎﻃﺮ دارﻳﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ در اﺑﺘﺪاي ﺑﺮﻧﺎﻣﻪ ﻛﻨﺘﺮﻟﻬﺎي Buttonرا ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮدﻳﻢ ،ﺧﺎﺻﻴﺖ DialogResultآﻧﻬـﺎ را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺪار OKو ﻳﺎ Cancelﻗﺮار دادﻳﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي ﻳﻜﻲ از اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﻛﻠﻴﻚ ﻛﻨﺪ ﻓﺮم ﺑﺮﻧﺎﻣـﻪ ﺑﺴﺘﻪ ﺷﺪه و ﻣﻘﺪار DialogResult.OKو ﻳﺎ DialogResult.Cancelﺑﻪ ﻋﻨـﻮان ﻧﺘﻴﺠـﻪ ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ ي اﺣﻀﺎر ﻛﻨﻨﺪه ي ﻓﺮم ﺑﺮﮔﺸﺖ داده ﻣﻲ ﺷﻮد .اﻣﺎ در اﻳﻦ ﻓﺮم ﻧﻤﻲ ﺧﻮاﻫﻴﻢ ﻫﻤﻮاره اﻳﻦ اﺗﻔﺎق رخ دﻫﺪ ،ﺑﺮاي ﻣﺜﺎل ﻧﻤـﻲ ﺧـﻮاﻫﻴﻢ ﻫﻤـﻮاره زﻣﺎﻧﻲ ﻛﻪ ﻛﺎرﺑﺮ روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﺮد )ﭼﻪ ﻛﻠﻤﻪ ي ﻋﺒﻮر درﺳﺖ وارد ﺷﺪه ﺑﺎﺷﺪ و ﭼﻪ ﻏﻠﻂ( ﻓﺮم ﺑﺮﻧﺎﻣـﻪ ﺑـﺴﺘﻪ ﺷـﺪه و ﻣﻘـﺪار DialogResult.OKﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﮔﺮدد .ﭘﺲ ﻧﻴﺎز دارﻳﻢ ﻛﻪ ﻫﻨﮕﺎم ﺑﺴﺘﻪ ﺷﺪن ﻓﺮم ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ﻛﻪ آﻳﺎ ﻓﺮم ﻣﻲ ﺗﻮاﻧﺪ ﺑﺴﺘﻪ ﺷﻮد ﻳﺎ ﻧﻪ؟ ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﻢ از روﻳﺪاد FormClosingاﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻳﻦ روﻳﺪاد زﻣﺎﻧﻲ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد ﻛﻪ ﻓﺮم در ﺣﺎل ﺑﺴﺘﻪ ﺷﺪن ﺑﺎﺷﺪ .در اﻳﻦ روﻳﺪاد ﻣﻘﺪار ﻓﻴﻠﺪ blnAllowCloseرا ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨـﻴﻢ .اﮔـﺮ ﻣﻘـﺪار اﻳـﻦ ﻓﻴﻠـﺪ ﺑﺮاﺑـﺮ ﺑـﺎ falseﺑﻮد ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻧﺒﺎﻳﺪ ﺑﺴﺘﻪ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻘﺪار Cancelرا در ﭘﺎراﻣﺘﺮ eﺑﺮاﺑﺮ ﺑـﺎ trueﻗـﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ از ﺑﺴﺘﻪ ﺷﺪن ﻓﺮم ﺟﻠﻮﮔﻴﺮي ﺷﻮد. private void Login_FormClosing(object sender, )FormClosingEventArgs e { // If we are not allowing the form to close... )if (!blnAllowClosing { // Set the cancel flag to true ;e.Cancel = true } }
1در .NETﺗﻌﺪاد ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ ﻣﺎﻧﻨﺪ ﻛﻼس Applicationو ﻳﺎ ﻛﻼس Environmentاﻃﻼﻋﺎت ﻻزم و ﻣﻮرد ﻧﻴﺎز را در اﺧﺘﻴﺎر ﻗﺮار ﻣـﻲ دﻫﻨﺪ ﺑﺴﻴﺎر زﻳﺎد اﺳﺖ ،ﺑﻪ ﺻﻮرﺗﻲ ﻛﻪ ﺻﺤﺒﺖ در راﺑﻄﻪ ﺑﺎ آﻧﻬﺎ از ﻳﻚ ﻳﺎ ﭼﻨﺪ ﻛﺘﺎب ﺑﻴﺸﺘﺮ ﺧﻮاﻫﺪ ﺷﺪ .ﺑﺮاي آﺷﻨﺎﻳﻲ ﺑﺎ اﻳﻦ ﻛﻼﺳﻬﺎ و ﺧﺎﺻﻴﺖ ﻫـﺎي آﻧﻬـﺎ ﺑﻬﺘـﺮ اﺳـﺖ ﻛﻪ ﺳﻴﺴﺘﻢ راﻫﻨﻤﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﺎ MSDNرا ﻣﻄﺎﻟﻌﻪ ﻛﻨﻴﺪ.
٥٢٠
ﺑﻌﺪ از اﺗﻤﺎم اﻳﻦ ﻗﺴﻤﺖ ﻫﺎ ﺑﻪ ﻛﻨﺘﺮل ﻫﺎي Buttonﻣﻮﺟﻮد در ﻓﺮم ﻣﻲ ﭘﺮدازﻳﻢ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﺮد، اﺑﺘﺪا ﺑﺎﻳﺪ ﻣﻄﻤﺌﻦ ﺷﻮﻳﻢ ﻛﻪ ﻛﺎدر User Nameﺧﺎﻟﻲ ﻧﻴﺴﺖ و ﻧﺎم ﻛﺎرﺑﺮي در آن وارد ﺷﺪه اﺳﺖ .ﺑﺮاي اﻳﻦ ﻛﺎر اﺑﺘﺪا ﻣﺘﺪ Trim را ﺑﺮاي ﻣﻘﺪار ﺧﺎﺻﻴﺖ Textﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺗﻤﺎم ﻓﻀﺎﻫﺎي ﺧﺎﻟﻲ اﻃﺮاف آن را ﺣﺬف ﻛﻨﺪ ،ﺳﭙﺲ ﻃـﻮل ﻣـﺘﻦ ﺑـﺎﻗﻲ ﻣﺎﻧـﺪه را ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﺑﺮاﺑﺮ ﺻﻔﺮ اﺳﺖ ﻳﺎ ﻧﻪ؟ اﮔﺮ ﻧﺎم ﻛﺎرﺑﺮي وارد ﺷﺪه ﺑﻮد ،ﻣﻘﺪار ﻓﻴﻠﺪ Passwordرا ﺑﺎ ﻛﻠﻤﻪ ي ﻋﺒﻮر ﻛﺎرﺑﺮ ﻣﻘﺎﻳﺴﻪ ﻣﻲ ﻛﻨﻴﻢ ) در اﻳﻨﺠﺎ ﺑﺮاي ﺳﺎدﮔﻲ ﻛـﺎر ،از ﻛﻠﻤﻪ ي ﻋﺒﻮر ﺛﺎﺑﺖ ” “secretاﺳﺘﻔﺎده ﺷﺪه اﺳﺖ( .در ﺻﻮرﺗﻲ ﻛﻪ ﻛﻠﻤﻪ ي ﻋﺒﻮر درﺳﺖ وارد ﺷﺪه ﺑﻮد ﻳـﻚ ﺷﻨﺎﺳـﻪ ﺑـﺮاي اﻳـﻦ ﻛﺎرﺑﺮ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ و ﻣﻘﺪار آن را در ﻓﻴﻠﺪ intUserIDﻗﺮار ﻣﻲ دﻫﻴﻢ ) در اﻳﻨﺠﺎ از ﻣﻘﺪار ﺛﺎﺑـﺖ 27اﺳـﺘﻔﺎده ﻛـﺮده اﻳـﻢ(، روﻳــﺪاد LoginSucceededرا ﻓﺮاﺧــﻮاﻧﻲ ﻛــﺮده و ﻣﻘــﺪار 27را ﺑــﻪ آن ارﺳــﺎل ﻣــﻲ ﻛﻨــﻴﻢ .در اﻧﺘﻬــﺎ ﻧﻴــﺰ ﻣﻘــﺪار blnAllowCloseرا ﺑﺮاﺑﺮ trueﻗﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ ﻓﺮم Loginﺑﺘﻮاﻧﺪ ﺑﺴﺘﻪ ﺷﻮد. اﻟﺒﺘﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي واﻗﻌﻲ ﻣﻲ ﺗﻮاﻧﻴﺪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺘﺼﻞ ﺷﻮﻳﺪ و ﻛﻠﻤﻪ ي ﻋﺒﻮر ﻛﺎرﺑﺮ را اﺳﺘﺨﺮاج ﻛﻨﻴﺪ .ﺳﭙﺲ آن را ﺑﺎ ﻣﻘﺪار وارد ﺷﺪه ﺗﻮﺳﻂ ﻛﺎرﺑﺮ ﺑﺮرﺳﻲ ﻛﻨﻴﺪ و در ﺻﻮرت درﺳﺖ ﺑﻮدن آن ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﻴﺪ وارد ﺑﺮﻧﺎﻣﻪ ﺷﻮد. )private void btnOK_Click(object sender, EventArgs e { ?// Was a user name entered )if(txtUserName.Text.Trim().Length > 0 { ?// Was the password correct )"if(txtPassword.Text == "secret { // Successful login, set the User ID ;intUserID = 27 // Raise the LoginSucceeded event )if(this.LoginSucceeded != null this.LoginSucceeded(this, ;))new LoginEventArgs(intUserID // Turn on the allow closing flag ;blnAllowClosing = true } اﮔــﺮ ﻛﻠﻤــﻪ ي ﻋﺒــﻮر وارد ﺷــﺪه ﺑــﻪ وﺳــﻴﻠﻪ ﻛــﺎرﺑﺮ اﺷــﺘﺒﺎه ﺑﺎﺷــﺪ ،ﻛــﺎدر ﭘﻴﻐــﺎم ﻣﻨﺎﺳــﺒﻲ را ﻧﻤــﺎﻳﺶ داده و ﻣﻘــﺪار ﻣﺘﻐﻴﻴــﺮ intAttemptCountرا ﻧﻴﺰ ﻳﻚ واﺣﺪ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ .ﺳﭙﺲ ﻣﻘﺪار اﻳﻦ ﻣﺘﻐﻴﻴﺮ را ﺑﺎ ﻋﺪد 3ﻣﻘﺎﻳـﺴﻪ ﻣـﻲ ﻛﻨـﻴﻢ .اﮔـﺮ اﻳـﻦ ﻣﺮﺗﺒﻪ ي ﺳﻮﻣﻲ ﺑﻮد ﻛﻪ ﻛﺎرﺑﺮ ﻛﻠﻤﻪ ي ﻋﺒﻮر را اﺷﺘﺒﺎه وارد ﻣـﻲ ﻛـﺮد ،روﻳـﺪاد LoginFailedرا ﻓﺮاﺧـﻮاﻧﻲ ﻛـﺮده و ﺧﺎﺻـﻴﺖ DialogResultﻓﺮم را ﺑﺮاﺑﺮ ﺑﺎ Cancelﻗﺮار ﻣﻲ دﻫﻴﻢ .در اﻧﺘﻬﺎ ﻧﻴﺰ ﻣﻘﺪار ﺧﺎﺻﻴﺖ blnAllowClosingرا ﺑﺮاﺑﺮ ﺑﺎ trueﻗﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ ﻓﺮم ﺑﺘﻮاﻧﺪ ﺑﺴﺘﻪ ﺷﻮد و ﻣﻘﺪار Cancelرا ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﮔﺮداﻧﺪ. else { // Inform the user // that the password was invalid
٥٢١
MessageBox.Show("The password you entered" + " was invalid.","Login"); // Increment the attempt count intAttemptCount += 1; // Check the attempt count if (intAttemptCount == 3) { // Raise the LoginFailed event if(this.LoginFailed != null) this.LoginFailed(this, new EventArgs()); // Set the Cancel dialog result this.DialogResult = DialogResult.Cancel; // Turn on the allow closing flag blnAllowClosing = true; } } } ﻛﺎدر ﭘﻴﻐﺎﻣﻲ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ ﻛﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﭘﺮ ﻛﺮدن اﻳـﻦ ﻛـﺎدر، وارد ﻧﺸﺪه ﺑﻮدUser Name اﮔﺮ ﻫﻴﭻ ﻧﺎﻣﻲ در ﻛﺎدر .اﻟﺰاﻣﻲ اﺳﺖ else { // Inform the user // that they must supply a user name MessageBox.Show("You must supply a User Name.", "Login"); } اﮔﺮ ﻛﺎرﺑﺮ روي دﻛﻤـﻪ. وارد ﺷﺪه اﺳﺖ ﻧﻴﺰ ﻛﺎﻣﻼً واﺿﺢ اﺳﺖbtnCancel ﻛﻨﺘﺮلClick ﻛﺪي ﻛﻪ در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد را ﻓﺮاﺧـــﻮاﻧﻲ ﻛـــﺮده و ﻣﻘـــﺪار ﻓﻴﻠـــﺪLoginCanceled ﻛـــﺎﻓﻲ اﺳـــﺖ روﻳـــﺪاد، ﻛﻠﻴـــﻚ ﻛﻨـــﺪCancel ي . ﻗﺮار دﻫﻴﺪ ﺗﺎ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﺑﺘﻮاﻧﺪ ﺑﺴﺘﻪ ﺷﻮدtrue را ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎblnAllowClosing private void btnCancel_Click(object sender, EventArgs e) { // Raise the LoginCancelled event if(this.LoginCancelled != null) this.LoginCancelled(this, new EventArgs()); // Turn on the allow closing flag
٥٢٢
;blnAllowClosing = true }
اﺳﺘﻔﺎده از ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻓﺮم اﻳﺠﺎد ﺷﺪه: ﺣﺎل ﻛﻪ ﻓﺮم Loginرا ﻃﺮاﺣﻲ ﻛﺮدﻳﻢ ،ﻣﻲ ﺗﻮاﻧﻴﻢ از آن در ﻫﺮ ﻗﺴﻤﺖ از ﻫﺮ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ ﻻزم ﺑﻮد اﺳﺘﻔﺎده ﻛﻨـﻴﻢ .در اﻳـﻦ ﺑﺨـﺶ ﺑﺮاي ﺑﺮرﺳﻲ ﻋﻤﻠﻜﺮد اﻳﻦ ﻓﺮم ،ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ﺟﺪﻳﺪ را ﺑﻪ اﻳﻦ Solutionاﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ ،دﻗﻴﻘﺎً ﻣﺎﻧﻨﺪ ﻛﺎري ﻛﻪ ﺑـﺮاي ﺗﺴﺖ ﻛﻨﺘﺮل اﻳﺠﺎد ﺷﺪه در ﻗﺴﻤﺖ ﻫﺎي ﻗﺒﻞ اﻧﺠﺎم ﻣﻲ دادﻳﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﻓﺮم Loginدر ﻳﻚ ﺑﺮﻧﺎﻣﻪ (1
(2
(3
(4 (5
ﺑﺎ اﺳﺘﻔﺎده از ﻧﻮار ﻣﻨﻮي وﻳﮋوال اﺳـﺘﻮدﻳﻮ ﮔﺰﻳﻨـﻪ ي … File Add New Projectرا اﻧﺘﺨـﺎب ﻛﻨﻴﺪ ﺗﺎ ﻛﺎدر Add New Projectﻧﻤﺎﻳﺶ داده ﺷﻮد .ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﺎدر ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وﻳﻨـﺪوز ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم Secure Loginﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻠﻲ اﺿﺎﻓﻪ ﻛﻨﻴﺪ. در ﭘﻨﺠﺮه ي Solution Explorerروي ﻧﺎم ﭘﺮوژه ي Secure Loginﻛﻠﻴﻚ راﺳﺖ ﻛـﺮده و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ ي Set as Startup Projectرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ اﻳﻦ ﭘﺮوژه را ﺑﻪ ﻋﻨﻮان ﭘﺮوژه ي آﻏﺎزﻳﻦ در ﻧﻈﺮ ﻣﻲ ﮔﻴﺮد. در اﻳﻦ ﻣﺮﺣﻠﻪ ﻧﻴﺎز دارﻳﻢ ﻛﻪ ﻳﻚ ارﺟـﺎع از ﭘـﺮوژه ي FormsLibraryﺑـﻪ ﭘـﺮوژه ي Secure Login اﺿﺎﻓﻪ ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ از ﻓﺮم داﺧﻞ ﭘﺮوژه ي FormsLibraryاﺳـﺘﻔﺎده ﻛﻨـﻴﻢ .در ﭘﻨﺠـﺮه ي Solution Explorerروي ﭘﺮوژه ي Secure Loginﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨـﻮي ﺑـﺎز ﺷـﺪه ﮔﺰﻳﻨـﻪ ي Add Referenceرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .در ﻛﺎدر Add Referenceروي ﻗﺴﻤﺖ Projectsﻛﻠﻴﻚ ﻛﻨﻴﺪ .در ﻟﻴﺴﺖ ﻧﻤﺎﻳﺶ داده ﺷﺪه در اﻳﻦ ﻗﺴﻤﺖ ،ﭘﺮوژه ي FormsLibraryرا اﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤﻪ ي OKﻛﻠﻴـﻚ ﻛﻨﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل Labelﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮده و ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑـﺮ ﺑـﺎ lblUserID ﻗﺮار دﻫﻴﺪ. ﺣﺎل ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس Form1ﺑﺮوﻳﺪ .ﺑﺮاي ﻧﻮﺷﺘﻦ ﻛﺪ ﻫﺎي اﻳﻦ ﻗﺴﻤﺖ ﻻزم اﺳﺖ ﻛﻪ از ﻓﻀﺎي ﻧﺎم FormsLibraryاﺳﺘﻔﺎده ﻛﻨﻴﻢ ،ﭘﺲ دﺳﺘﻮر زﻳﺮ را ﺑﻪ اﺑﺘﺪاي ﻛﺪﻫﺎ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: ;using FormsLibrary
(6ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم Form1ﺑﺮﮔﺸﺘﻪ و روي ﻗﺴﻤﺖ ﺧﺎﻟﻲ ﻓﺮم دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑـﻮط ﺑـﻪ روﻳـﺪاد Load آن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ ﻗﺮار دﻫﻴﺪ: )private void Form1_Load(object sender, EventArgs e { ))(using (Login objLogin = new Login { == )if (objLogin.ShowDialog(this
٥٢٣
)System.Windows.Forms.DialogResult.OK { // Update the label with the User ID lblUserID.Text = "User ID = " + ;objLogin.UserID } else { // Inform the user that the login failed ;)"MessageBox.Show("Login Failed // Close this form since the login failed ;)(this.Close } } } (7ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻓﺮم Loginﻧﻤﺎﻳﺶ داده ﺷﺪه و در ﻛﺎدر User Nameاﻳﻦ ﻓﺮم ،ﻧـﺎم ﻛﺎرﺑﺮي ﻛﻪ ﺑﺎ آن وارد وﻳﻨﺪوز ﺷﺪه اﻳﺪ ﻧﻴﺰ ﻗﺮار دارد .در ﻛﺎدر Passwordﻛﻠﻤﻪ ي ﻋﺒﻮري ﺑﻪ ﺟﺰ secretرا وارد ﻛﺮده و روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و ﻣﻲ ﮔﻮﻳﺪ ﻛﻪ ﻛﻠﻤﻪ ي ﻋﺒﻮر وارد ﺷﺪه اﺷﺘﺒﺎه اﺳﺖ .اﻳﻦ ﻛﺎر را دو ﺑﺎر دﻳﮕﺮ ﺗﻜﺮار ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤـﺎﻳﺶ داده ﺷـﺪه و رخ دادن روﻳﺪاد LoginFailedرا ﻋﻨﻮان ﻣﻲ ﻛﻨﺪ .در اﻧﺘﻬﺎ ﻧﻴﺰ ﺑﺮﻧﺎﻣﻪ ﺑﺴﺘﻪ ﻣﻲ ﺷﻮد. (8ﺑﺎر دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و زﻣﺎﻧﻲ ﻛﻪ ﻓﺮم Loginﻧﻤﺎﻳﺶ داده ﺷﺪ ،روي دﻛﻤﻪ ي Cancelﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺠﺪداً ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﻧﻤﺎﻳﺶ داده ﺷﺪه و ﺑﺮﻧﺎﻣﻪ ﺑﺴﺘﻪ ﺧﻮاﻫﺪ ﺷﺪ. (9ﺣﺎل ﺑﺮﻧﺎﻣﻪ را ﺑﺮاي آﺧﺮﻳﻦ ﺑﺎر اﺟﺮا ﻛﺮده و ﻛﻠﻤﻪ ي secretرا در ﻛﺎدر Passwordوارد ﻛﻨﻴﺪ ،اﻟﺒﺘﻪ دﻗـﺖ ﻛﻨﻴـﺪ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻛﻠﻤﻪ ي ﻋﺒﻮر ﺑﻪ اﻧﺪازه ي ﺣﺮوف ﺣﺴﺎس اﺳﺖ .ﺣﺎل روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛﺮد ﻛﻪ ﻓﺮم Loginﺑﺴﺘﻪ ﺷﺪه و ﻓﺮم Form1ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﻋـﺪد 27ﻧﻴـﺰ ﺑـﻪ ﻋﻨـﻮان ﺷﻨﺎﺳـﻪ ي ﻛـﺎرﺑﺮ در ﻛﻨﺘﺮل Labelﻓﺮم ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﻳﻚ روش ﺧﻮب و ﻛﺎرآﻣﺪ ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﻓﺮم ﻫﺎي ورود اﻣﻦ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد آﺷﻨﺎ ﺷﺪﻳﺪ .اﮔﺮ ﻛﺎرﺑﺮ ﻧﺘﻮاﻧﺪ ﻛﻠﻤﻪ ي ﻋﺒﻮر و ﻧﺎم ﻛﺎرﺑﺮي را وارد ﻛﻨﺪ ،ﺑﺮﻧﺎﻣﻪ ﺑﺪون اﻳﻨﻜﻪ ﺣﺘﻲ ﻓﺮم اﺻﻠﻲ را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ دﻫﺪ ﺑﺴﺘﻪ ﺧﻮاﻫﺪ ﺷﺪ. اوﻟﻴﻦ ﻛﺎري ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﻧﺠـﺎم ﻣـﻲ دﻫـﻴﻢ اﻳـﻦ اﺳـﺖ ﻛـﻪ ﻳـﻚ ارﺟـﺎع از ﭘـﺮوژه ي FormsLibraryدر ﭘـﺮوژه ي Secure Loginاﻳﺠﺎد ﻛﻨﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﭘـﺮوژه ي FormsLibraryﻧﻴـﺰ در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از راﻫﻨﻤﺎي ،usingﻓﻀﺎي ﻧﺎم FormsLibraryرا ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ .اﻟﺒﺘﻪ اﻳﻦ ﻛﺎر ﺿﺮوري ﻧﻴﺴﺖ ،وﻟﻲ ﺑﺮاي اﻳﻨﻜﻪ ﻧﺨﻮاﻫﻴﻢ در ﻃﻲ ﺑﺮﻧﺎﻣﻪ ﻧﺎم ﻛﺎﻣﻞ ﻛﻼﺳﻬﺎ را وارد ﻛﻨﻴﻢ ﺑﻬﺘﺮ اﺳﺖ اﻳـﻦ ﻓـﻀﺎي ﻧـﺎم را اﺿـﺎﻓﻪ ﻛﻨﻴﻢ. ;using FormsLibrary
٥٢٤
ﻛﺪي ﻛﻪ در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Loadﻓﺮم ﻗﺮار داده اﻳﻢ ﻛﺎﻣﻼً واﺿﺢ و ﺳﺎده اﺳﺖ .در اﺑﺘﺪا ﺗﻤﺎم ﻛﺪ را درون ﻳـﻚ ﺑـﻼك ﻛـﻪ ﺑـﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر usingاﻳﺠﺎد ﺷﺪه اﺳﺖ ﻗﺮار داده اﻳﻢ .در ﻓﺼﻠﻬﺎي ﻗﺒﻠﻲ ﮔﻔﺘﻢ ﻛﻪ ﻛﻠﻤﻪ ي usingﺑﻪ دو ﺻـﻮرت ﻣـﻲ ﺗﻮاﻧـﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد :در ﺣﺎﻟﺖ اول اﻳﻦ ﻛﻠﻤﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺻﻮرت راﻫﻨﻤﺎي usingﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻓﻀﺎي ﻧﺎم ﺑﻪ ﺑﺮﻧﺎﻣـﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد ،ﻛﻪ اﻳﻦ ﺣﺎﻟﺖ را ﺗﺎﻛﻨﻮن ﺑﻪ ﻣﺮاﺗﺐ ﻣﺸﺎﻫﺪه ﻛﺮده اﻳﺪ. در ﺣﺎﻟﺖ دوم اﻳﻦ ﻛﻠﻤﻪ ﺑﻪ ﺻﻮرت دﺳﺘﻮر usingﺑﻪ ﻛﺎر ﻣﻲ رود .اﮔﺮ ﺑﺨﻮاﻫﻴﻢ از ﻳﻚ ﺷﻴﺊ ﺳﻨﮕﻴﻦ ﻛﻪ ﻓﻀﺎي زﻳـﺎدي از ﺣﺎﻓﻈـﻪ را اﺷﻐﺎل ﻣﻲ ﻛﻨﺪ اﺳﺘﻔﺎده ﻛﻨﻴﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﻣﻮﻗﻊ ﻧﻴﺎز آن را اﻳﺠﺎد ﻛﺮده و ﺑﻌﺪ از اﺳﺘﻔﺎده ﻧﻴﺰ ﺑﻼﻓﺎﺻﻠﻪ آن را از ﺑﻴﻦ ﺑﺒﺮﻳﻢ .ﺑﺮاي اﻃﻤﻴﻨـﺎن از اﻳﻦ ﻛﻪ اﻳﻦ ﺷﻴﺊ ﻓﻘﻂ در زﻣﺎن ﻣﻮرد ﻧﻴﺎز وﺟﻮد دارد ،از دﺳﺘﻮر usingﺑﻪ اﻳﻦ ﺻﻮرت اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﻛـﻪ در ﭘﺮاﻧﺘـﺰ ﺟﻠـﻮي اﻳـﻦ دﺳﺘﻮر ﺷﻴﺊ را اﻳﺠﺎد ﻛﺮده و ﺳﭙﺲ ﻳﻚ ﺑﻼك ﺑﻌﺪ از دﺳﺘﻮر اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ .در داﺧﻞ اﻳﻦ ﺑﻼك ﻣﻲ ﺗﻮاﻧﻴﻢ از آن ﺷﻴﺊ اﺳـﺘﻔﺎده ﻛﻨـﻴﻢ، اﻣﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﻪ اﻧﺘﻬﺎي ﺑﻼك ﺑﺮﺳﺪ ﺷﻴﺊ را ﻧﺎﺑﻮد ﻣﻲ ﻛﻨﺪ و اﻳﻦ ﺷﻴﺊ در ﺧﺎرج ﺑﻼك ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﻧﺨﻮاﻫﺪ ﺑﻮد. ﻓﺮم Loginﻧﻴﺰ ﻳﻚ ﺷﻴﺊ ﺳﻨﮕﻴﻦ ﺑﻪ ﺷﻤﺎ ﻣﻲ رود .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر usingﻳﻚ ﺑﻼك اﻳﺠﺎد ﻛﺮده و در داﺧﻞ آن از اﻳﻦ ﻓﺮم اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .ﺑﻪ ﻣﺤﺾ اﻳﻨﻜﻪ ﺑﺮﻧﺎﻣﻪ ﺑﻪ اﻧﺘﻬﺎي ﺑﻼك ﺑﺮﺳﺪ ،اﻳﻦ ﺷﻴﺊ را ﻧﺎﺑﻮد ﻛﺮده و ﺣﺎﻓﻈﻪ ي اﺷﻐﺎل ﺷﺪه ﺑﻪ وﺳـﻴﻠﻪ ي آن را ﻧﻴﺰ آزاد ﻣﻲ ﻛﻨﺪ. ))(using (Login objLogin = new Login { } در داﺧﻞ دﺳﺘﻮر usingاز ﻳﻚ دﺳﺘﻮر ifاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻓﺮم Loginاﻳﺠﺎد ﺷﺪه را ﻧﻤﺎﻳﺶ داده و ﻧﺘﻴﺠﻪ ي ﺑﺮﮔﺸﺖ داده ﺷﺪه از آن را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ .ﺑﺮاي ﻧﻤﺎﻳﺶ ﻳﻚ ﻓﺮم ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻣﺘﺪ Showو ﻳﺎ ﻣﺘﺪ ShowDialogاﺳﺘﻔﺎده ﻛﻨﻴﻢ .در اﻳﻨﺠﺎ از ﻣﺘﺪ ShowDialogاﺳﺘﻔﺎده ﻛﺮده و ﭘﺎراﻣﺘﺮ thisرا ﺑﻪ آن ارﺳﺎل ﻣﻲ ﻛﻨﻴﻢ .اﻳﻦ ﭘﺎراﻣﺘﺮ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﻼس ﺟـﺎري ﻳﻌﻨﻲ ﻛﻼس ،Form1ﻓﺮم Loginرا ﻧﻤﺎﻳﺶ داده اﺳﺖ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ اﻳﻦ ﭘﺎراﻣﺘﺮ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ Form1ﺑﻪ ﻋﻨﻮان ﻣﺎﻟــﻚ ﻓــﺮم Loginﺑــﻪ ﺷــﻤﺎر ﻣــﻲ رود .در اﻧﺘﻬــﺎ ﻧﻴــﺰ ﻧﺘﻴﺠــﻪ ي ﺑﺮﮔــﺸﺖ داده ﺷــﺪه از ﻓــﺮم را ﺑــﺎ ﺛﺎﺑــﺖ OKاز ﺷــﻤﺎرﻧﺪه ي DialogResultﻣﻘﺎﻳﺴﻪ ﻣﻲ ﻛﻨﻴﻢ. اﮔﺮ ﻣﺘﺪ ShowDialogﻧﺘﻴﺠﻪ ي DialogResult.OKرا ﺑﺮﮔﺮداﻧﺪ ،ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻛﺎرﺑﺮ ﺗﻮاﻧﺴﺘﻪ اﺳﺖ ﻧـﺎم ﻛﺎرﺑﺮي و ﻛﻠﻤﻪ ي ﻋﺒﻮر را ﺑﻪ درﺳﺘﻲ وارد ﻛﻨﺪ .ﭘﺲ ﻣﺘﻦ ﻛﻨﺘﺮل lblUserIDرا ﺑﺮاﺑﺮ ﺑﺎ ﺷﻨﺎﺳﻪ ي ﻣﻮﺟـﻮد در ﻓـﺮم Login ﻗﺮار داده و اﺟﺎزه ﻣﻲ دﻫﻴﻢ ﻛﻪ Form1در ﺣﺎﻓﻈﻪ ﺑﺎرﮔﺬاري ﺷﺪه و ﻧﻤﺎﻳﺶ داده ﺷﻮد. اﮔﺮ ﻓﺮم Loginﻣﻘﺪار OKرا ﺑﺮﮔﺸﺖ ﻧﺪﻫﺪ ،ﭘﺲ ﺣﺘﻤﺎً ﻣﻘﺪار Cancelرا ﺑﺮﻣﻲ ﮔﺮداﻧـﺪ .در اﻳـﻦ ﺻـﻮرت ﺑﺮﻧﺎﻣـﻪ وارد ﻗـﺴﻤﺖ elseﻣﻲ ﺷﻮد .در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﺣﺎوي ﻋﺒـﺎرت Login Failedﻧﻤـﺎﻳﺶ داده ﻣـﻲ ﺷـﻮد .ﺳـﭙﺲ ﻣﺘـﺪ Closeﻣﺮﺑﻮط ﺑﻪ ﻓﺮم ﺟﺎري )ﻛﻪ ﺑﺎ ﻛﻠﻤﻪ ي ﻛﻠﻴﺪي thisﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ اﺳﺖ( ،ﻓﺮاﺧﻮاﻧﻲ ﺷﺪه و ﺑﺮﻧﺎﻣﻪ ﺑﺴﺘﻪ ﻣﻲ ﺷﻮد. ))(using (Login objLogin = new Login { == )if (objLogin.ShowDialog(this )System.Windows.Forms.DialogResult.OK { // Update the label with the User ID lblUserID.Text = "User ID = " + ;objLogin.UserID } else
٥٢٥
{ // Inform the user that the login failed ;)"MessageBox.Show("Login Failed // Close this form since the login failed ;)(this.Close } }
اﺳﺘﻔﺎده از روﻳﺪاد ﻫﺎي ﻣﻮﺟﻮد در ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻓﺮم: ﺣﺎل ﻛﻪ ﻳﻚ روش ﺳﺎده اﺳﺘﻔﺎده از ﻓﺮم Loginرا ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ،ﺑﻬﺘﺮ اﺳﺖ از اﻳﻦ ﻓﺮم ﺑﻪ ﺻﻮرت ﻛﺎﻣﻞ ﺗـﺮي اﺳـﺘﻔﺎده ﻛﻨـﻴﻢ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﺑﺮﻧﺎﻣﻪ اي اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ از ﻓﺮم Loginاﺳﺘﻔﺎده ﻛﻨﺪ و در ﻃﻮل اﻳﻦ ﺑﺮﻧﺎﻣﻪ روﻳﺪاد ﻫـﺎي ﻣﻮﺟـﻮد در ﻓﺮم Loginرا ﻧﻴﺰ ﺑﻪ ﻛﺎر ﺧﻮاﻫﻴﻢ ﺑﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از روﻳﺪاد ﻫﺎي ﻣﻮﺟﻮد در ﻓﺮم Login (1
(2
(3
(4 (5
در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ و در ﻫﻤﺎن Solutionاي ﻛﻪ دو ﭘـﺮوژه ي ﻗﺒﻠـﻲ را در آن اﻳﺠـﺎد ﻛﺮدﻳـﺪ ،ﺑـﻪ ﭘﻨﺠـﺮه ي Solution Explorerﺑﺮوﻳﺪ و روي ﻧﺎم solutionﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ ي … Add New Projectرا اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ .در ﻛـﺎدر Add New Projectﮔﺰﻳﻨـﻪ ي Windows Applicationرا از ﻗـﺴﻤﺖ Templatesاﻧﺘﺨـﺎب ﻛـﺮده و ﻋﺒـﺎرت Access Controlرا در ﻛﺎدر Nameوارد ﻛﻨﻴﺪ .در اﻧﺘﻬﺎ ﻧﻴﺰ روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﭘﺮوژه ي ﺟﺪﻳﺪ اﻳﺠﺎد ﺷﻮد. ﺣﺎل ﺑﺎﻳﺪ اﻳﻦ ﭘﺮوژه را ﺑﻪ ﻋﻨﻮان ﭘﺮوژه ي آﻏﺎزﻳﻦ در اﻳﻦ solutionﻣـﺸﺨﺺ ﻛﻨـﻴﻢ .ﺑﻨـﺎﺑﺮاﻳﻦ روي ﻧـﺎم ﭘـﺮوژه ي Access Controlدر ﭘﻨﺠﺮه ي Solution Explorerﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﮔﺰﻳﻨﻪ ي Set as Startup Projectرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. ﻣﺠﺪداً ﺑﺎﻳﺪ ﻳﻚ ارﺟﺎع از ﭘﺮوژه ي FormsLibraryرا ﺑﻪ اﻳﻦ ﭘﺮوژه ﻧﻴﺰ اﺿﺎﻓﻪ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر روي ﭘﺮوژه ي Access Controlدر ﭘﻨﺠﺮه ي Solution Explorerﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨﻮي ﺑﺎز ﺷـﺪه ﮔﺰﻳﻨــﻪ ي … Add Referenceرا اﻧﺘﺨــﺎب ﻛﻨﻴــﺪ .در ﻛــﺎدر Add Referenceروي ﻗــﺴﻤﺖ Projectsﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ دو ﭘﺮوژه ي دﻳﮕﺮ اﻳـﻦ solutionدر ﻟﻴـﺴﺖ اﻳـﻦ ﻗـﺴﻤﺖ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﻧﺪ .از اﻳﻦ ﻟﻴﺴﺖ ﭘﺮوژه ي FormsLibraryرا اﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل Buttonرا ﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ي Access Controlاﺿﺎﻓﻪ ﻛﺮده ،ﺧﺎﺻـﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑﺎ btnLoginو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Loginﻗﺮار دﻫﻴﺪ. ﻳﻚ ﻛﻨﺘﺮل Labelﻧﻴﺰ ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮده و آن را زﻳﺮ ﻛﻨﺘﺮل Buttonﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ ﺧﺎﺻـﻴﺖ Nameاﻳـﻦ ﻛﻨﺘﺮل را ﺑﺎ ﻣﻘﺪار lblMessageﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ .ﻓﺮم ﺗﻜﻤﻴﻞ ﺷﺪه ي اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 7-13ﺑﺎﺷﺪ.
٥٢٦
ﺷﻜﻞ 7-13 (6ﺣﺎل ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ Form1ﺑﺮوﻳﺪ و ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر زﻳﺮ ،ﻓﻀﺎي ﻧﺎم FormsLibraryرا ﺑﻪ ﻓـﺮم اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: ;using FormsLibrary (7ﺑﻌﺪ از اﺿﺎﻓﻪ ﻛﺮدن ﻓﻀﺎي ﻧﺎم ،FormsLibraryﻳﻚ ﺷﻴﺊ از ﻛﻼس Loginرا در ﻛﻼس Form1اﻳﺠـﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ در اﻳﻦ ﻓﺮم ﺑﺘﻮاﻧﻴﻢ از ﻓﺮم Loginاﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻟﺒﺘﻪ ﻓﻌﻼً ﺑﻪ اﻳﻦ ﺷﻴﺊ ﻣﻘﺪار اوﻟﻴﻪ ﻧﻤﻲ دﻫﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺪ زﻳﺮ را ﺑﻪ اﺑﺘﺪاي ﻛﻼس Form1اﺿﺎﻓﻪ ﻛﻨﻴﺪ: public partial class Form1 : Form { ;Login objLogin (8ﺑﺮاي اﺳﺘﻔﺎده از روﻳﺪادﻫﺎي ﻣﻮﺟﻮد در ﻓﺮم Loginاﺑﺘﺪا ﺑﺎﻳﺪ ﻣﺘﺪ ﻫﺎﻳﻲ را ﺑﺎ ﺳﺎﺧﺘﺎرﻫﺎﻳﻲ ﻛﻪ ﺗﻌﻴﻴﻦ ﻛـﺮدﻳﻢ اﻳﺠـﺎد ﻛﻨـﻴﻢ. اﺑﺘﺪا ﻣﺘﺪي ﺑﺮاي روﻳﺪاد LoginCanceledاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﺘﺪ زﻳﺮ را ﺑﻪ ﻛﻼس Form1اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void objLogin_LoginCancelled(Object sender, )EventArgs e { ;"!lblMessage.Text = "Login Cancelled } (9ﺳﭙﺲ ﺑﺎﻳﺪ ﻣﺘﺪي را ﺑﺮاي روﻳﺪاد LoginFailedو ﻧﻴﺰ روﻳﺪاد LoginSucceededاﻳﺠﺎد ﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ ﻫﺎ ﻧﻴﺰ ﺑﺎﻳﺪ داراي ﺳﺎﺧﺘﺎر ﺗﻌﻴﻴﻦ ﺷﺪه ﺑﺎﺷﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻛﺪ زﻳﺮ را ﺑﻪ ﻛﻼس Form1اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ اﻳﻦ دو ﻣﺘﺪ اﻳﺠﺎد ﺷﻮﻧﺪ: private void objLogin_LoginFailed(Object sender, )EventArgs e { ;"!lblMessage.Text = "Login Failed } private void objLogin_LoginSucceeded(Object sender, )LoginEventArgs e {
٥٢٧
lblMessage.Text = "The Login was successful for " + ;"the UserID: " + e.UserID } (10ﻳﻚ ﻗﺴﻤﺖ دﻳﮕﺮ از ﻛﺪ ﺑﺎﻗﻲ ﻣﺎﻧﺪه اﺳﺖ ﺗﺎ ﺑﺮﻧﺎﻣﻪ ي اﻳﻦ ﻗﺴﻤﺖ ﺗﻜﻤﻴﻞ ﺷﻮد .ﺑﻪ ﺑﺨﺶ ﻃﺮاﺣﻲ ﻓﺮم Form1ﺑﺮﮔﺮدﻳﺪ و روي ﻛﻨﺘﺮل btnLoginدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickآن اﻳﺠﺎد ﺷﻮد ،ﺳـﭙﺲ ﻛـﺪ زﻳـﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: )private void btnLogin_Click(object sender, EventArgs e { ;)(objLogin = new Login (objLogin.LoginCancelled += new Login._LoginCancelled ;)objLogin_LoginCancelled (objLogin.LoginFailed += new Login._LoginFailed ;)objLogin_LoginFailed (objLogin.LoginSucceeded += new Login._LoginSucceeded ;)objLogin_LoginSucceeded ;)objLogin.ShowDialog(this } (11ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ Form1ﻧﻤـﺎﻳﺶ داده ﺷـﺪ ،روي دﻛﻤـﻪ ي Loginﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .در ﻓـﺮم Loginروي دﻛﻤﻪ ي Cancelﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﻳﻦ ﻓﺮم ﺑﺴﺘﻪ ﺷﻮد .ﻣﺸﺎﻫﺪه ﻣـﻲ ﻛﻨﻴـﺪ ﻛـﻪ ﻛﻨﺘـﺮل Labelدر Form1ﻣﺘﻦ Login Cancelledرا ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. (12ﻣﺠﺪداً روي دﻛﻤﻪ ي Loginﻛﻠﻴﻚ ﻛﺮده و در ﻛﺎدر Passwordﻓﺮم Loginﻛﻠﻤﻪ اي ﺑﻪ ﺟـﺰ secret را وارد ﻛﻨﻴﺪ .ﺳﻪ ﺑﺎر روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻛﻨﺘﺮل Labelدر ﻓﺮم Form1ﻋﺒﺎرت Login Failedرا ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. (13ﺑﺮاي آﺧﺮﻳﻦ ﺑﺎر روي دﻛﻤﻪ ي Loginﻛﻠﻴﻚ ﻛﺮده و زﻣﺎﻧﻲ ﻛﻪ ﻓﺮم Loginﻧﻤﺎﻳﺶ داده ﺷﺪ ،ﻋﺒﺎرت secret را در ﻛﺎدر Passwordوارد ﻛﻨﻴﺪ .ﺑﺎ ﻛﻠﻴـﻚ روي دﻛﻤـﻪ ي OKﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛـﺮد ﻛـﻪ ﻛﻨﺘـﺮل Labelدر Form1وارد ﺷﺪن ﻳﻚ ﻛﺎرﺑﺮ ﺑﺎ ﺷﻨﺎﺳﻪ ي 27را ﻋﻨﻮان ﻣﻲ ﻛﻨﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ روﺷﻲ ﻣﻌﺮﻓﻲ ﺷﺪ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از آن ﻣﻲ ﺗﻮاﻧﻴﺪ دﺳﺘﺮﺳﻲ اﻓﺮاد ﻣﺨﺘﻠﻒ را ﺑﻪ ﺑﻌﻀﻲ از ﻗـﺴﻤﺘﻬﺎي ﺑﺮﻧﺎﻣـﻪ ﻣﺤـﺪود ﻛﻨﻴـﺪ. ﻣﻌﻤﻮﻻً ﻫﻤﻪ ي ﻛﺎرﺑﺮان ﺑﻪ اﻏﻠﺐ ﻗﺴﻤﺘﻬﺎي ﻳﻚ ﺑﺮﻧﺎﻣﻪ دﺳﺘﺮﺳﻲ دارﻧﺪ ،اﻣﺎ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ ﻛﻪ ﻓﻘﻂ اﻓـﺮاد ﺧﺎﺻـﻲ ﺑـﻪ ﻗـﺴﻤﺘﻲ از ﺑﺮﻧﺎﻣﻪ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ .در اﻳﻦ ﺻﻮرت ﻣﻲ ﺗﻮاﻧﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻛﺎرﺑﺮ ﺳـﻌﻲ ﻛـﺮد ﺑـﻪ آن ﻗـﺴﻤﺖ از ﺑﺮﻧﺎﻣـﻪ وارد ﺷـﻮد ،ﻛـﺎدر Loginرا ﻧﻤﺎﻳﺶ دﻫﻴﺪ .ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از روﻳﺪاد ﻫﺎي ﻣﺨﺘﻠﻔﻲ ﻛﻪ در اﻳﻦ ﻓﺮم اﻳﺠﺎد ﻛﺮده اﻳﻢ ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ ﻛﻪ آﻳﺎ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧـﺪ وارد آن ﻗﺴﻤﺖ ﺷﻮد ﻳﺎ ﻧﻪ؟
٥٢٨
اﻳﻦ ﭘﺮوژه ﻧﻴﺰ ﺗﻘﺮﻳﺒﺎً ﻣﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻞ اﺳﺖ .اﺑﺘﺪا ﻳﻚ ارﺟﺎع ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي FormsLibraryرا در آن اﻳﺠﺎد ﻛﺮده و ﻓـﻀﺎي ﻧﺎم FormsLibraryرا ﻧﻴﺰ ﺑﻪ آن اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ .ﺳﭙﺲ ﻳﻚ ﺷﻴﺊ از ﻧﻮع Loginرا در اﺑﺘﺪاي ﻛﻼس اﻳﺠﺎد ﻣﻲ ﻛﻨـﻴﻢ ﺗﺎ ﺗﻤﺎم ﻣﺘﺪ ﻫﺎ ﺑﺘﻮاﻧﻨﺪ ﺑﻪ آن دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ. ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ روﻳﺪاد ﻫﺎي ﻣﻮﺟﻮد در ﻓﺮم Loginرا ﻛﻨﺘﺮل ﻛﻨﻴﻢ ،ﺑﺎﻳﺪ ﻣﺘﺪ ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺗﻮان در ﻟﻴﺴﺖ اﻳﻦ روﻳﺪاد ﻫـﺎ اﺿـﺎﻓﻪ ﻛﺮد را اﻳﺠﺎد ﻛﻨﻴﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ اﻳﻦ ﻣﺘﺪ ﻫﺎ ﺑﺎﻳﺪ داراي ﺳﺎﺧﺘﺎر ﺧﺎﺻﻲ ﺑﺎﺷﻨﺪ و ﺳﺎﺧﺘﺎر آﻧﻬﺎ ﻧﻴﺰ در ﻛـﻼس Loginﺗﻌﺮﻳـﻒ ﺷﺪه اﺳﺖ. ﺑﻨﺎﺑﺮاﻳﻦ ﺳـﻪ ﻣﺘـﺪ ﺑـﻪ ﻧـﺎم ﻫـﺎي objLofin_LoginCancelled ،objLogin_LoginFailedو objLogin_LoginSucceededاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ آﻧﻬﺎ را ﺑﻪ ﻟﻴﺴﺖ روﻳﺪاد ﻫﺎي ﻓﺮم Loginاﺿﺎﻓﻪ ﻛﻨﻴﻢ .ﻧـﺎم اﻳﻦ ﻣﺘﺪ ﻫﺎ را ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﻪ ﺻﻮرت دﻟﺨﻮاه اﻧﺘﺨﺎب ﻛﻨﻴﻢ .ﻣﻌﻤﻮﻻً در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﺎم ﻣﺘﺪ ﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي روﻳﺪاد ﺧﺎﺻﻲ ﻫﺴﺘﻨﺪ ﺷﺎﻣﻞ ﻧﺎم ﻛﻨﺘﺮل ﺑﻪ ﻫﻤﺮاه ﺑﺎ ﻧﺎم روﻳﺪاد اﺳﺖ .در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ از اﻳﻦ ﻗﺎﻋﺪه ﭘﻴﺮوي ﻣﻲ ﻛﻨﻴﻢ .در اﻳﻦ ﻗﺴﻤﺖ ﻧﺎم ﻫﺮ ﻣﺘﺪ ﻣﺸﺨﺺ ﻣـﻲ ﻛﻨـﺪ ﻛﻪ ﻣﺮﺑﻮط ﺑﻪ ﭼﻪ روﻳﺪادي اﺳﺖ ،ﺑﻨﺎﺑﺮاﻳﻦ ﺳﺎﺧﺘﺎر آن ﻣﺘﺪ را ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎ ﺳﺎﺧﺘﺎر ﻣﻮرد ﻧﻴﺎز ﺑﺮاي آن روﻳﺪاد در ﻧﻈﺮ ﻣﻲ ﮔﻴﺮﻳﻢ. private void objLogin_LoginCancelled(Object sender, )EventArgs e { ;"!lblMessage.Text = "Login Cancelled } private void objLogin_LoginFailed(Object sender, )EventArgs e { ;"!lblMessage.Text = "Login Failed } private void objLogin_LoginSucceeded(Object sender, )LoginEventArgs e { lblMessage.Text = "The Login was successful for " + ;"the UserID: " + e.UserID } درون ﻫﺮ ﻳﻚ از اﻳﻦ روﻳﺪاد ﻫﺎ ﻧﻴﺰ ﻛﺪ ﻣﻨﺎﺳﺒﻲ ﻗﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ در ﺻﻮرﺗﻲ ﻛﻪ روﻳﺪاد ﻣﺮﺑﻮﻃﻪ رخ داد و اﻳﻦ ﻣﺘﺪ ﻫﺎ اﺟـﺮا ﺷـﺪﻧﺪ ،ﻣـﺘﻦ ﻣﻨﺎﺳﺒﻲ در ﻓﺮم ﻧﻤﺎﻳﺶ داده ﺷﻮد. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي دﻛﻤﻪ ي Loginﻛﻠﻴﻚ ﻛﺮد ،ﺑﺎﻳﺪ ﻓﺮم Loginرا ﻧﻤﺎﻳﺶ دﻫـﻴﻢ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر اﺑﺘـﺪا ﺑﺎﻳـﺪ ﺑـﻪ ﺷـﻴﺊ objLoginﻛﻪ در اﺑﺘﺪاي ﻛﻼس اﻳﺠﺎد ﻛﺮدﻳﻢ ﻣﻘﺪار اوﻟﻴﻪ دﻫﻴﻢ. ;)(objLogin = new Login ﺑﻌﺪ از اﻧﺠﺎم اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ ﻣﺘﺪ ﻫﺎﻳﻲ را ﻛﻪ در ﻣﺮﺣﻠﻪ ي ﻗﺒﻞ اﻳﺠﺎد ﻛﺮدﻳﻢ ﺑﻪ روﻳﺪاد ﻫﺎي ﻣﻮﺟﻮد در ﻓﺮم Loginاﺿﺎﻓﻪ ﻛﻨﻴﻢ .ﺑـﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻣﺘﺪ ﺑﻪ ﻳﻚ روﻳﺪاد ،اﺑﺘﺪا ﺑﺎﻳﺪ ﻳﻚ ﺷﻴﺊ ﺟﺪﻳﺪ از ﻧﻮع delegateاي ﻛﻪ ﺳﺎﺧﺘﺎر ﻣﺘـﺪﻫﺎي ﻣـﻮرد ﻧﻴـﺎز ﺑـﺮاي آن روﻳﺪاد را ﻣﺸﺨﺺ ﻣﻲ ﻛﺮد اﻳﺠﺎد ﻛﺮده و ﻧﺎم ﻣﺘﺪ را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ اﻳﻦ ﺷﻴﺊ ارﺳﺎل ﻛﻨﻴﻢ .ﺳﭙﺲ اﻳﻦ ﺷﻴﺊ را ﺑﺎ اﺳـﺘﻔﺎده از ﻋﻤﻠﮕـﺮ = +ﺑﻪ روﻳﺪاد اﺿﺎﻓﻪ ﻛﻨﻴﻢ.
٥٢٩
(objLogin.LoginCancelled += new Login._LoginCancelled ;)objLogin_LoginCancelled (objLogin.LoginFailed += new Login._LoginFailed ;)objLogin_LoginFailed (objLogin.LoginSucceeded += new Login._LoginSucceeded ;)objLogin_LoginSucceeded ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﺪ objLogin_LoginCancelledﺑـﻪ روﻳـﺪاد LoginCancelledاﺿـﺎﻓﻪ ﺷـﺪه ،ﻣﺘـﺪ objLogin_LoginFailedﺑﻪ روﻳﺪاد LoginFailedاﺿﺎﻓﻪ ﺷﺪه و .... در اﻧﺘﻬﺎ ﻧﻴﺰ ﻛﺎﻓﻲ اﺳﺖ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ShowDialogﻓﺮم Loginرا ﻧﻤﺎﻳﺶ دﻫﻴﻢ. ;)objLogin.ShowDialog(this در اﻳﻦ ﻗﺴﻤﺖ دو روش ﺑﺮاي اﺳﺘﻔﺎده از ﻓﺮم Loginرا ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ و ﻫﻤﺎﻧﻄﻮر ﻛﻪ در اﺑﺘﺪاي ﻫﺮ ﻛﺪام از اﻳـﻦ روش ﻫـﺎ ﮔﻔـﺘﻢ، اﻳﻦ ﻓﺮم ﻣﻲ ﺗﻮاﻧﺪ در ﻫﺮ ﻛﺪام از اﻳﻦ ﺷﺮاﻳﻂ )ﻛﻪ ﻛﺎﻣﻼً ﻣﺘﻔﺎوت از ﻫﻢ ﻧﻴﺰ ﻫﺴﺘﻨﺪ( ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد .ﺗﻨﻬﺎ ﻛﺎري ﻛـﻪ ﻛـﺎﻓﻲ اﺳـﺖ اﻧﺠﺎم دﻫﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﺗﻮاﺑﻊ و ﻣﺘﺪﻫﺎي داﺧﻞ ﻓﺮم را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ ﻧﺎم ﻛﺎرﺑﺮي و ﻛﻠﻤﻪ ي ﻋﺒـﻮر را ﺑـﻪ درﺳـﺘﻲ ﺑﺮرﺳـﻲ ﻛﺮده و ﻧﺘﻴﺠﻪ را ﺑﻪ ﻓﺮم اﺻﻠﻲ ﺑﺮﮔﺮداﻧﺪ.
ﻧﺘﻴﺠﻪ: در اﻳﻦ ﻓﺼﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻳﻚ راﺑﻂ ﻛﺎرﺑﺮي را در ﭼﻨﺪ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ و ﻳﺎ ﺣﺘﻲ در ﭼﻨﺪ ﺑﺮﻧﺎﻣﻪ ي ﻣﺨﺘﻠﻒ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار داد .اﻳﻦ ﻛﺎر ﺑﻪ دو روش اﻣﻜﺎن ﭘﺬﻳﺮ اﺳﺖ .اول اﻳﻨﻜﻪ ﻳﻚ ﻛﻨﺘﺮل ﺳﻔﺎرﺷﻲ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل ﻫﺎي ﻣﻮﺟﻮد اﻳﺠﺎد ﻛـﺮده و ﺳﭙﺲ ﻛﺎراﻳﻲ ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺧﻮد را ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪ ﻫﺎ ،ﺧﺎﺻﻴﺖ ﻫﺎ و ﻳﺎ روﻳﺪاد ﻫﺎي ﺟﺪﻳﺪ در اﻳﻦ ﻛﻨﺘﺮل ﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ از اﻳـﻦ ﻛﻨﺘﺮل ﻣﺎﻧﻨﺪ ﻛﻨﺘﺮﻟﻬﺎي دﻳﮕﺮ از ﻗﺒﻴﻞ TextBoxو ﻳﺎ Buttonدر ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. روش دﻳﮕﺮ اﻳﻦ اﺳﺖ ﻛﻪ ﻓﺮﻣﻲ را ﻃﺮاﺣﻲ ﻛﺮده و ﺗﻤﺎم ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺘﻬﺎي ﻣﻮرد ﻧﻴﺎز را ﺑﻪ اﻳﻦ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺳﭙﺲ در ﻫﺮ ﻗﺴﻤﺖ از ﻫﺮ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ ﺑﻪ اﻳﻦ ﻓﺮم ﻧﻴﺎز داﺷﺘﻴﺪ ،آن را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده و از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻇﺎﻫﺮي ﭘﻴﻮﺳﺘﻪ و ﭘﺎﻳـﺪار ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد اﻳﺠﺎد ﻛﻨﻴﺪ. در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ:
ﻳﻚ ﻛﻨﺘﺮل وﻳﻨﺪوزي ﭼﻴﺴﺖ و ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﭼﮕﻮﻧﻪ ﻳﻚ ﻛﻨﺘﺮل وﻳﻨﺪوزي اﻳﺠﺎد ﻛﻨﻴﻢ؟ ﭼﮕﻮﻧﻪ ﻣﺘﺪ ﻫﺎ ،ﺧﺎﺻﻴﺖ ﻫﺎ و ﻳﺎ روﻳﺪاد ﻫﺎﻳﻲ را ﺑﻪ ﻛﻨﺘﺮل ﺧﻮد اﺿﺎﻓﻪ ﻛﻨﻴﻢ؟ زﻣﺎن اﺟﺮا و زﻣﺎن ﻃﺮاﺣﻲ ﭼﻴﺴﺘﻨﺪ و ﭼﻪ ﺗﻔﺎوت ﻫﺎﻳﻲ دارﻧﺪ؟ ﭼﮕﻮﻧﻪ ﻳﻚ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس اﻳﺠﺎد ﻛﻨﻴﻢ ﻛﻪ داراي ﻓﺮم ﻫﺎي ﻋﻤﻮﻣﻲ ﭘﺮ ﻛﺎرﺑﺮد ﺑﺎﺷﻨﺪ؟
٥٣٠
ﺗﻤﺮﻳﻦ: ﺧﺎﺻﻴﺘﻲ ﺑﻪ ﻧﺎم SuppressMsgBoxاز ﻧﻮع Booleanرا ﺑﻪ ﻛﻨﺘﺮل MyNamespaceاﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺳـﭙﺲ ﻣﺘـﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickﻛﻨﺘﺮﻟﻬﺎي Buttonﻣﻮﺟﻮد در ﻓﺮم را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ در ﺻﻮرﺗﻲ ﻛـﻪ ﻣﻘـﺪار اﻳـﻦ ﺧﺎﺻـﻴﺖ ﺑﺮاﺑﺮ ﺑﺎ Falseﺑﻮد ﻛﺎدر ﭘﻴﻐﺎﻣﻲ را ﻧﻤﺎﻳﺶ دﻫﻨﺪ و در ﻏﻴﺮ اﻳﻦ ﺻﻮرت از ﻧﻤﺎﻳﺶ ﻛﺎدر ﭘﻴﻐﺎم ﺧﻮدداري ﻛﻨﻨﺪ.
٥٣١
ﻓﺼﻞ ﭼﻬﺎردﻫﻢ :اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﮔﺮاﻓﻴﻜﻲ در ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺗﺎﻛﻨﻮن در ط.ل اﻳﻦ ﻛﺘﺎب اﻧﺠﺎم داده اﻳﺪ ،راﺑﻂ ﮔﺮاﻓﻴﻜﻲ ﺑﺮﻧﺎﻣﻪ را از اﺑﺘﺪا ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟـﻮد در وﻳـﮋوال اﺳﺘﻮدﻳﻮ اﻳﺠﺎد ﻣﻲ ﻛﺮدﻳﺪ .اﻣﺎ ﺧﻮب اﺳﺖ ﺑﺪاﻧﻴﺪ زﻣﺎﻧﻲ ﻛﻪ از وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ،ﻫﻴﭻ اﺟﺒﺎري ﻧﻴـﺴﺖ ﻛﻪ از ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﺑﺎ ﺷﻜﻞ و ﺷﻤﺎﻳﻞ ﻣﻮﺟﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﻠﻜﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺧﻮدﺗﺎن ﻣﺤﻴﻂ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﺻﻮرت دﻟﺨﻮاه رﺳـﻢ ﻛﻨﻴـﺪ و ﺑـﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻗﺎدر ﺧﻮاﻫﻴﺪ ﺑﻮد ﻛﻪ ﻇﺎﻫﺮ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﻫﺮ ﺷﻜﻠﻲ ﻛﻪ ﺗﻤﺎﻳﻞ دارﻳﺪ ﻃﺮاﺣﻲ ﻛﻨﻴﺪ. در ﻃﻲ اﻳﻦ ﻓﺼﻞ ﻧﮕﺎﻫﻲ ﻛﻠﻲ ﺑﺮ ﺗﻮاﺑﻊ و ﻗﺎﺑﻠﻴﺘﻬﺎي ﻣﻮﺟﻮد در وﻳﮋوال اﺳﺘﻮدﻳﻮ در راﺑﻄﻪ ﺑﺎ ﮔﺮاﻓﻴﻚ و رﺳﻢ دو ﺑﻌـﺪي ﺧـﻮاﻫﻴﻢ داﺷـﺖ و ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﺑﺎ ﻣﻔﺎﻫﻴﻢ ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﮔﺮاﻓﻴﻜﻲ ﭘﻴﭽﻴﺪه آﺷﻨﺎ ﺷﻮﻳﻢ .ﻋﻼوه ﺑﺮ اﻳﻦ ﺳﻌﻲ ﻣﻲ ﻛﻨـﻴﻢ ﻛـﻪ ﺑﻌـﻀﻲ از ﻗﺎﺑﻠﻴﺘﻬـﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ در راﺑﻄﻪ ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﭼﻨﺪ رﺳﺎﻧﻪ اي را ﺑﺮرﺳﻲ ﻛﺮده و ﺑﺎ اﺳﺘﻔﺎده از ﻓﺎﻳﻠﻬﺎي ﻣﺘﺪاوﻟﻲ ﻣﺎﻧﻨﺪ .png ، .jpgو ﻳـﺎ .gifدر ﺑﺮﻧﺎﻣﻪ ﻫﺎ آﺷﻨﺎ ﺷﻮﻳﻢ. در اﻳﻦ ﻓﺼﻞ:
در راﺑﻄﻪ ﺑﺎ ﻓﻀﺎي ﻧﺎم System.Drawingﻣﻄﺎﻟﺒﻲ را ﺧﻮاﻫﻴﺪ آﻣﻮﺧﺖ. ﻧﺤﻮه ي اﺳﺘﻔﺎده از ﻛﻼﺳﻬﺎي Penو Brushرا ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد. ﺑﺎ ﭼﮕﻮﻧﮕﻲ اﻧﺘﺨﺎب و اﺳﺘﻔﺎده از رﻧﮕﻬﺎي ﻣﺨﺘﻠﻒ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. ﺑﺎ ﻧﺤﻮه ي ﺗﻐﻴﻴﺮ اﻧﺪازه ي ﺗﺼﻮﻳﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﺸﺎﺑﻪ Paintاﻳﺠﺎد ﺧﻮاﻫﻴﺪ ﻛﺮد.
اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي Paintﺳﺎده: در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي Paintﺳﺎده اﻳﺠﺎد ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻻزم اﺳﺖ ﻛﻪ ﭼﻨﺪ ﻛﻨﺘﺮل ﺳﻔﺎرﺷﻲ اﻳﺠﺎد ﻛﺮده و ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از آﻧﻬﺎ در ﻳﻚ ﭘﺮوژه ي وﻳﻨﺪوزي ،ﺑﺮﻧﺎﻣﻪ ي Paintرا اﻳﺠﺎد ﻛﻨﻴﻢ.
اﻳﺠﺎد ﻳﻚ ﭘﺮوژه ﻫﻤﺮاه ﺑﺎ ﻛﻨﺘﺮل ﻫﺎي ﺳﻔﺎرﺷﻲ: اﻧﮕﻴﺰه ي اﺳﺘﻔﺎده از ﻛﻨﺘﺮﻟﻬﺎي ﺳﻔﺎرﺷﻲ ﺑﺮاي اﻳﺠﺎد اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺴﻴﺎر ﺳﺎده اﺳﺖ :ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﻫﻤﻮاره ﺑﻬﺘﺮ اﺳﺖ ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﻣﺆﻟﻔﻪ ﻫﺎ و ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي ﻛﻮﭼﻚ ﺗﻘﺴﻴﻢ ﻛﻨﻴﻢ .ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﺗﻜﻨﻴﻚ اﮔﺮ ﺑﻌﺪﻫﺎ ﺑﺨﻮاﻫﻴﺪ در ﻗﺴﻤﺘﻲ از ﺑﺮﻧﺎﻣﻪ ي ﺧـﻮد از ﺑﺮﻧﺎﻣـﻪ اي ﻣﺸﺎﺑﻪ اﻳﻦ ﻣﻮرد اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﺑﻪ ﺳﺎدﮔﻲ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ ﻛﺎر را اﻧﺠﺎم دﻫﻴﺪ. ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي اﺳﺘﻔﺎده در اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد از ﻳﻚ ﺟﻨﺒﻪ ﺑﺎ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﺑﺎ آﻧﻬـﺎ آﺷـﻨﺎ ﺷـﺪﻳﺪ ﺗﻔﺎوت دارﻧﺪ .اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﺧﻮد وﻇﻴﻔﻪ دارﻧﺪ ﻛﻪ ﻇﺎﻫﺮ و ﺷﻜﻞ ﺧﻮد را در ﻳﻚ ﻓﺮم ﺗﺮﺳﻴﻢ ﻛﻨﻨﺪ و ﻣﺎﻧﻨﺪ ﻛﻨﺘﺮﻟﻬﺎي ﻗﺒﻠﻲ ﻛﻪ اﻳﺠـﺎد ﻣـﻲ ﻛﺮدﻳﻢ ﺑﻪ وﺳﻴﻠﻪ ي ﻛﻼس ﭘﺎﻳﻪ در ﻓﺮم ﺗﺮﺳﻴﻢ ﻧﻤﻲ ﺷﻮﻧﺪ.1
1ﺑﻪ ﭼﻨﻴﻦ ﻛﻨﺘﺮل ﻫﺎﻳﻲ Owner-Draw User Controlﮔﻔﺘﻪ ﻣﻲ ﺷﻮد.
٥٣٢
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﭘﺮوژه (1 (2
(3
(4
(5 (6
ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وﻳﻨﺪوز ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم MyPaintاﻳﺠﺎد ﻛﻨﻴﺪ. در ﭘﻨﺠﺮه ي Solution Explorerروي ﻧﺎم ﭘﺮوژه ي MyPaintﻛﻠﻴﻚ راﺳﺖ ﻛـﺮده و از ﻣﻨـﻮي ﺑـﺎز ﺷﺪه ﮔﺰﻳﻨﻪ ي … Add User Controlرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺳـﭙﺲ ﻧـﺎم PaintCanvas.csرا در ﻗﺴﻤﺖ Nameوارد ﻛﺮده و روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ. ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻛﻨﺘﺮل PaintCanvasﺑﺮوﻳﺪ و روي ﭘﺲ زﻣﻴﻨﻪ ي ﻛﻨﺘﺮل ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﻧﺘﺨﺎب ﺷﻮد .ﺳﭙﺲ ﺑـﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي Propertiesﺧﺎﺻﻴﺖ BackColorآن را ﺑﻪ Whiteﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر روي ﺧﺎﺻﻴﺖ BackColorﻛﻠﻴﻚ ﻛﺮده و از ﻗﺴﻤﺖ Customرﻧﮓ ﺳﻔﻴﺪ را اﻧﺘﺨﺎب ﻛﻨﻴﺪ. ﻗﺒﻞ از اﻳﻦ ﻛﻪ ﺑﺘﻮاﻧﻴﺪ از اﻳﻦ ﻛﻨﺘﺮل در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ ﻳﻚ ﺑﺎر ﺑﺮﻧﺎﻣﻪ را ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎ اﺳـﺘﻔﺎده از ﻧﻮار ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﮔﺰﻳﻨﻪ ي Build Build MyPaintرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﻨﺘﺮل PaintCanvasدر ﺟﻌﺒﻪ اﺑﺰار ﻗﺮار ﻣﻲ ﮔﻴﺮد و ﻣﻲ ﺗﻮاﻧﻴﺪ از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﺣﺎل ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم Form1ﺑﺮﮔﺸﺘﻪ و ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻛﻨﺘﺮل PaintCanvasرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ و ﺑﺮ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ .ﻫﻤﭽﻨﻴﻦ ﺧﺎﺻﻴﺖ Dockاﻳﻦ ﻛﻨﺘﺮل را ﻧﻴﺰ ﺑﻪ Fillﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺑﺮاي ﻣﺮﺗﺐ ﺗﺮ ﺷﺪن ﺑﺮﻧﺎﻣﻪ ﺧﺎﺻﻴﺖ Textﻓﺮم را ﻧﻴﺰ ﺑﻪ My Paintﺗﻐﻴﻴﺮ دﻫﻴﺪ.
ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﮔﺮاﻓﻴﻜﻲ ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ؟ ﺻﻔﺤﺎت ﻛﺎﻣﭙﻴﻮﺗﺮ از ﺻﺪﻫﺎ ﻫﺰار ﻧﻘﻄﻪ ي رﻳﺰ ﺑﻪ ﻧﺎم ﭘﻴﻜﺴﻞ 1ﺗﺸﻜﻴﻞ ﺷﺪه اﻧﺪ .اﻳﻦ ﻧﻘﺎط ﺑﺴﻴﺎر رﻳﺰ ﻫﺴﺘﻨﺪ و ﺑﻪ ﺻـﻮرت ﻋـﺎدي ﻧﻤـﻲ ﺗﻮان آﻧﻬﺎ را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ از ﻳﻜﺪﻳﮕﺮ ﺗﻔﻜﻴﻚ ﻛﺮد ،اﻣﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﻛﻨﺎر ﻳﻜﺪﻳﮕﺮ ﻗﺮار ﻣﻲ ﮔﻴﺮﻧـﺪ ﻣـﻲ ﺗﻮاﻧﻨـﺪ ﻳـﻚ ﺗـﺼﻮﻳﺮ را در ﺻﻔﺤﻪ ي ﻛﺎﻣﭙﻴﻮﺗﺮ ﻧﻤﺎﻳﺶ دﻫﻨﺪ .ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ در ﻫﺮ ﻣﺎﻧﻴﺘﻮري ﭘﻴﻜﺴﻞ ﻫﺎ اﻧﺪازه ي ﻣﺸﺨﺺ و ﺛﺎﺑﺘﻲ دارﻧﺪ ،در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﺎﻣﭙﻴﻮﺗﺮي از آﻧﻬﺎ ﺑﻪ ﻋﻨﻮان واﺣﺪ اﻧﺪازه ﮔﻴﺮي اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ. اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﺪاﻧﻴﺪ ﻛﻪ ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺷﻤﺎ از ﭼﻨﺪ ﭘﻴﻜﺴﻞ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ ،ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﻮﺟﻮد را ﻛﻮﭼـﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﺑﺘﻮاﻧﻴﺪ ﻣﺤﻴﻂ دﺳﻚ ﺗﺎپ را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ .در دﺳﻚ ﺗﺎپ ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨـﻮي ﺑـﺎز ﺷـﺪه ﮔﺰﻳﻨـﻪ ي Propertiesرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .در ﭘﻨﺠﺮه ي Display Propertiesﺑﻪ ﻗﺴﻤﺖ Settingsﺑﺮوﻳﺪ .در ﻗﺴﻤﺖ ﭼﭗ ﭘﺎﻳﻴﻦ اﻳـﻦ ﭘﻨﺠﺮه ﺗﻌﺪاد ﭘﻴﻜﺴﻞ ﻫﺎي ﺗﺸﻜﻴﻞ دﻫﻨﺪه ي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ .ﺑـﺮاي ﻣﺜـﺎل در ﺷـﻜﻞ 1-14ﺻـﻔﺤﻪ ﻧﻤـﺎﻳﺶ از 1024 ﭘﻴﻜﺴﻞ اﻓﻘﻲ و 768ﭘﻴﻜﺴﻞ ﻋﻤﻮدي ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ. 3 2 ﻣﻌﻤﻮﻻً در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﮔﺮاﻓﻴﻜﻲ از دو روش ﻛﻠﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨـﺪ :روش ﺗﺮﺳﻴﻢ ﺑﻴﺖ ﻣﭙﻲ و روش ﺗﺮﺳﻴﻢ ﺑﺮداري .ﺑﻨـﺎﺑﺮاﻳﻦ ﺑﻬﺘﺮ اﺳﺖ ﻗﺒﻞ از ﻫﺮ ﭼﻴﺰ ﺑﺎ ﻣﻔﻬﻮم اﻳﻦ دو روش و ﺗﻔﺎوﺗﻬﺎي آﻧﻬﺎ آﺷﻨﺎ ﺷﻮﻳﻢ.
1
Pixel Bitmap Graphics 3 Vector Graphics 2
٥٣٣
ﺷﻜﻞ 1-14
ﺗﺮﺳﻴﻢ ﺑﻴﺖ ﻣﭙﻲ: در اﻳﻦ روش ﻳﻚ ﻓﻀﺎ ﺑﺮاي ﺗﺮﺳﻴﻢ در اﺧﺘﻴﺎر ﺷﻤﺎ ﻗﺮار داده ﻣﻲ ﺷﻮد و ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از اﺑﺰارﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ ﻣﺪادﻫﺎ و ﻳـﺎ ﻗﻠـﻢ ﻣﻮﻫـﺎ، ﺗﺼﺎوﻳﺮي را در اﻳﻦ ﻓﻀﺎ رﺳﻢ ﻛﻨﻴﺪ .در روش ﺗﺮﺳﻴﻢ ﺑﻴﺖ ﻣﭙﻲ ،ﻓﻀﺎي رﺳﻢ ﺑﻪ ﭘﻴﻜﺴﻞ ﻫﺎ ﺗﻘﺴﻴﻢ ﻣﻲ ﺷﻮد و ﻫﺮ ﭘﻴﻜﺴﻞ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧـﺪ رﻧﮓ ﻣﺸﺨﺼﻲ داﺷﺘﻪ ﺑﺎﺷﺪ .ﺑﺮﻧﺎﻣﻪ اي ﮔﺮاﻓﻴﻜﻲ ﻛﻪ ﺑﺎ آن در ﺣﺎل ﺗﺮﺳﻴﻢ در ﻣﺤﻴﻂ ﻫﺴﺘﻴﺪ ،وﻇﻴﻔﻪ دارد ﺑﺮ اﺳﺎس رﻧـﮓ اﻧﺘﺨـﺎﺑﻲ ﺷـﻤﺎ، ﻧﺤﻮه ي ﺣﺮﻛﺖ ﻣﺎوس در ﺻﻔﺤﻪ و اﺑﺰاري ﻛﻪ اﻧﺘﺨﺎب ﻛﺮده اﻳﺪ ،رﻧﮓ ﻫﺮ ﭘﻴﻜﺴﻞ را ﺗﻨﻈﻴﻢ ﻛﻨﺪ. ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ ي ﮔﺮاﻓﻴﻜﻲ ﻓﺎﻳﻞ ﺗﺮﺳﻴﻤﻲ ﺷﻤﺎ را در ﻗﺎﻟﺐ ﻳﻚ ﺑﻴﺖ ﻣﭗ ذﺧﻴﺮه ﻣﻲ ﻛﻨﺪ ،ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﺨﺘﺼﺎت ﻫﺮ ﭘﻴﻜﺴﻞ و رﻧﮓ آن را در ﻓﺎﻳﻞ ﻗﺮار ﻣﻲ دﻫﺪ .ﻳﻚ ﺗﺼﻮﻳﺮ ﺑﻴﺖ ﻣﭗ در ﺣﻘﻴﻘﺖ ﻳﻚ آراﻳﻪ ي دو ﺑﻌﺪي از ﭘﻴﻜﺴﻞ ﻫﺎ اﺳﺖ ﻛﻪ ﻫﺮ ﻋﻨﺼﺮ آن ﻛﻪ ﺑﺎ اﺳـﺘﻔﺎده از xو yﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ اﺳﺖ رﻧﮓ آن ﭘﻴﻜﺴﻞ را در ﺧﻮد ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ. ﻧﻜﺘﻪ :ﻧﺎم ﺑﻴﺖ ﻣﭗ ﻳﺎ ” “Bitmapاز زﻣﺎﻧﻲ ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ ﻛﻪ ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎ ﺑﻪ ﺻﻮرت ﺗﻚ رﻧـﮓ ﺑـﻮد .ﺑـﻪ اﻳـﻦ ﺻﻮرت ﻫﺮ ﭘﻴﻜﺴﻞ ﺑﻪ وﺳﻴﻠﻪ ي ﻳﻚ ﺑﻴﺖ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﺪ ﻛﻪ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ﺳﻴﺎه و ﻳﺎ ﺳﻔﻴﺪ ﺑﻮدن آن ﭘﻴﻜﺴﻞ ﺑﻮد. ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﺑﺎ اﺳﺘﻔﺎده از اﺑﺰارﻫﺎي ﺗﺮﺳﻴﻢ ﺑﻴﺖ ﻣﭙﻲ ﻳﻚ ﻣﺴﺘﻄﻴﻞ رﺳﻢ ﻛﻨﻴﺪ ،ﻫﻨﮕﺎم ذﺧﻴﺮه اﻳﻦ ﻣﺴﺘﻄﻴﻞ ﺑﻪ ﺻﻮرت ﻳﻚ ﻣﺠﻤﻮﻋﻪ از ﭘﻴﻜﺴﻞ ﻫﺎ و رﻧﮓ آﻧﻬﺎ ذﺧﻴﺮه ﻣﻲ ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﻌﺪ از رﺳﻢ ﻣﺴﺘﻄﻴﻞ و ذﺧﻴﺮه ي آن دﻳﮕﺮ ﻗـﺎدر ﻧﺨﻮاﻫﻴـﺪ ﺑـﻮد ﻛـﻪ آن را ﺗﻐﻴﻴـﺮ ٥٣٤
دﻫﻴﺪ ،ﺑﺮاي ﻣﺜﺎل ﻃﻮل و ﻳﺎ ﻋﺮض ﻣﺴﺘﻄﻴﻞ رﺳﻢ ﺷﺪه را زﻳﺎد ﻛﻨﻴﺪ .زﻳﺮا ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻳﻦ ﻣﺴﺘﻄﻴﻞ ﺑﻪ ﺻﻮرت ﻳﻚ ﻣﺠﻤﻮﻋﻪ ﭘﻴﻜﺴﻞ در ﻛﺎﻣﭙﻴﻮﺗﺮ ذﺧﻴﺮه ﺷﻮد ،دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻧﻤﻲ ﺗﻮاﻧﻨﺪ ﻣﺴﺘﻄﻴﻞ ﺑﻮدن آن را ﺗﺸﺨﻴﺺ دﻫﻨﺪ .در اﻳـﻦ ﺣﺎﻟـﺖ ﺑـﺮاي ﺗﻐﻴﻴـﺮ آن ﺑﺎﻳـﺪ ﻣـﺴﺘﻄﻴﻞ ﺟﺪﻳﺪي را ﺑﺮ روي آن رﺳﻢ ﻛﻨﻴﺪ. ﻧﻜﺘﻪ :ﺗﺼﺎوﻳﺮي ﺑﺎ ﭘﺴﻮﻧﺪ .gif ،.jpgو ﻳﺎ .pngﻫﻤﻪ روﺷﻬﺎﻳﻲ ﺑﺮاي ذﺧﻴﺮه ي ﺗﺼﻮﻳﺮ در ﻗﺎﻟﺐ ﺑﻴﺖ ﻣﭙﻲ ﻫﺴﺘﻨﺪ .اﻟﺒﺘﻪ اﻳﻦ ﻓﺮﻣﺖ ﻫﺎ ﺑﺎ اﺳﺘﻔﺎده از روﺷﻬﺎي ﺧﺎص ذﺧﻴﺮه ﺳﺎزي ﺑﺎﻋﺚ ﻛﺎﻫﺶ ﺣﺠﻢ ﺗﺼﺎوﻳﺮ و اﻓﺰاﻳﺶ ﺳﺮﻋﺖ داﻧﻠﻮد آﻧﻬﺎ در اﻳﻨﺘﺮﻧﺖ ﻣﻲ ﺷﻮﻧﺪ.
ﺗﺮﺳﻴﻢ ﺑﺮداري: ﺗﺮﺳﻴﻢ ﺑﺮداري ﺑﺎ اﺳﺘﻔﺎده از روش ﻛﺎﻣﻼً ﻣﺘﻔﺎوﺗﻲ ﺗﺼﺎوﻳﺮ را رﺳﻢ ﻣﻲ ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﺑﺎ اﺳﺘﻔﺎده از روش ﺑﺮداري ﻳﻚ ﻣﺴﺘﻄﻴﻞ رﺳﻢ ﻛﻨﻴﺪ ،ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﺷﺪن ﻳﻚ ﻣﺴﺘﻄﻴﻞ در ﻣﻜﺎن آن را ذﺧﻴﺮه ﻣﻲ ﻛﻨﺪ ،ﻧﻪ ﻳﻚ ﻣﺠﻤﻮﻋﻪ از ﭘﻴﻜﺴﻞ ﻫﺎ و رﻧﮓ آﻧﻬﺎ را .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ در روش ﺑﺮداري ﻧﺤﻮه ي ﺗﺮﺳﻴﻢ ﻳﻚ ﺗﺼﻮﻳﺮ ﺑﺎ اﺳﺘﻔﺎده از ﻣﻌﺎدﻻت رﻳﺎﺿﻲ ذﺧﻴﺮه ﻣﻲ ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳـﻚ ﺗـﺼﻮﻳﺮ را ﺑـﺎ اﺳﺘﻔﺎده از اﻳﻦ روش رﺳﻢ ﻛﻨﻴﺪ ،ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺟﺰء ﺟﺰء اﻳﻦ ﺗﺼﻮﻳﺮ را ﺗﺸﺨﻴﺺ داده و از ﻫﻢ ﺗﻔﻜﻴـﻚ ﻛﻨـﺪ .ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﺑﻌـﺪ از ذﺧﻴﺮه ﺳﺎزي اﻳﻦ ﺗﺼﺎوﻳﺮ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻫﺮ ﺟﺰء از آن را اﻧﺘﺨﺎب ﻛﺮده و ﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﺗﺼﺎوﻳﺮ در روش ﺑﺮداري ﺑﻪ ﺻﻮرت ﻣﺘﻔﺎوﺗﻲ ذﺧﻴﺮه ﻣﻲ ﺷﻮﻧﺪ ،اﻣﺎ ﺑﺮاي ﻧﻤﺎﻳﺶ آﻧﻬﺎ در ﺻﻔﺤﻪ ﺑﺎﻳﺪ اﻳﻦ ﺗﺼﺎوﻳﺮ را ﺑﻪ ﺑﻴﺖ ﻣﭗ ﺗﺒﺪﻳﻞ ﻛﺮد و ﺳﭙﺲ آﻧﻬﺎ را ﻧﻤﺎﻳﺶ داد .زﻳﺮا روﺷﻬﺎﻳﻲ ﻛﻪ در رﺳﻢ ﺑﺮداري اﺳﺘﻔﺎده ﻣﻲ ﺷﻮﻧﺪ ﺑﺮاي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻗﺎﺑﻞ ﻓﻬﻢ ﻧﻴـﺴﺘﻨﺪ و ﺗﺼﻮﻳﺮ اﺑﺘﺪا ﺑﺎﻳﺪ ﺑﻪ ﺻﻮرت ﻣﺠﻤﻮﻋﻪ اي از ﭘﻴﻜﺴﻞ ﻫﺎ و رﻧﮓ آﻧﻬﺎ ﺗﺒﺪﻳﻞ ﺷﺪه )ﺑﻴﺖ ﻣﭙﻲ( و ﺳﭙﺲ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﺷـﻮد .اﻳـﻦ ﭘﺮوﺳﻪ ﻣﻌﻤﻮﻻً ﺑﻪ ﻧﺎم رﻧﺪر ﻛﺮدن 1ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮد. ﺑﺮﻧﺎﻣﻪ ي ﮔﺮاﻓﻴﻜﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد از روش ﺗﺮﺳﻴﻢ ﺑﺮداري اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ .اﻟﺒﺘﻪ ﻫﻴﭻ دﻟﻴﻞ ﺧﺎﺻﻲ ﺑﺮاي اﻧﺘﺨـﺎب اﻳﻦ روش وﺟﻮد ﻧﺪارد ،ﻓﻘﻂ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ روش ﺑﻬﺘﺮ ﻣﻲ ﺗﻮان ﻧﺤﻮه ي ﻋﻤﻠﻜﺮد اﺑﺰارﻫﺎي ﺗﺮﺳﻴﻢ را در ﭼﺎرﭼﻮب .NETدرك ﻛﺮد.
اﻳﺠﺎد ﻛﻼس :GraphicsItem در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ دو اﺑﺰار اﺑﺘﺪاﻳﻲ ﺑﺮاي رﺳﻢ اﻳﺠﺎد ﻛﻨﻴﻢ :داﻳﺮه و ﻣﺴﺘﻄﻴﻞ .ﻫﺮ ﻛﺪام از اﻳﻦ اﺑﺰارﻫﺎ ﻧﻴﺎز دارﻧﺪ ﻛـﻪ ﺑﺪاﻧﻨـﺪ در ﭼـﻪ ﻧﺎﺣﻴﻪ اي از ﻣﺤﻴﻂ رﺳﻢ )و ﻫﻤﭽﻨﻴﻦ در ﭼﻪ ﻗﺴﻤﺘﻲ از ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ( ﺑﺎﻳﺪ ﻗﺮار ﺑﮕﻴﺮﻧﺪ ،ﭼﻪ رﻧﮕﻲ ﺑﺎﻳﺪ داﺷﺘﻪ ﺑﺎﺷﻨﺪ و ...ﺑﻨـﺎﺑﺮاﻳﻦ ﻳـﻚ ﻛﻼس ﭘﺎﻳﻪ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ و ﺗﻤﺎم اﻳﻦ ﻣﻮارد را در آن ﻗﺮار ﻣﻲ دﻫﻴﻢ .ﺳﭙﺲ ﻛﻼﺳﻬﺎي ﻣﺮﺑـﻮط ﺑـﻪ داﻳـﺮه و ﻣـﺴﺘﻄﻴﻞ را از آن ﻣـﺸﺘﻖ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻛﻼﺳﻬﺎي GraphicsItemو GraphicsCircle (1اﺑﺘﺪا ﺑﺎﻳﺪ ﻳﻚ ﻛﻼس ﺟﺪﻳﺪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨـﻴﻢ .ﺑﻨـﺎﺑﺮاﻳﻦ در ﭘﻨﺠـﺮه ي Solution Explorerروي ﻧـﺎم ﭘﺮوژه ﻛﻠﻴﻚ راﺳﺖ ﻛـﺮده و از ﻣﻨـﻮي ﺑـﺎز ﺷـﺪه ﮔﺰﻳﻨـﻪ ي … Add Classرا اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ .ﺳـﭙﺲ ﻋﺒـﺎرت GraphicsItem.csرا در ﻛﺎدر Nameوارد ﻛﺮده و روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ.
Rendering
1
٥٣٥
ﺑﻨـﺎﺑﺮاﻳﻦ ﺑـﺎ. اﺳـﺘﻔﺎده ﻛﻨـﻴﻢSystem.Drawing ( در اﻳﺠﺎد اﻳﻦ ﻛﻼس ﺑﺎﻳﺪ از ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﻓـﻀﺎي ﻧـﺎم2 : اﻳﻦ ﻓﻀﺎي ﻧﺎم را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ،اﺳﺘﻔﺎده از دﺳﺘﻮر زﻳﺮ using System.Drawing; دﻗﺖ ﻛﻨﻴﺪ ﻛـﻪ. اﻳﺠﺎد ﺷﻮدGraphicsItem اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ ﻛﻼسGraphicsItem.cs ( ﻛﺪ زﻳﺮ را ﺑﻪ3 ﻧﺒﺎﻳﺪ اﺟﺎزه دﻫﻴﻢ ﺷﻴﺊ اي از اﻳﻦ ﻛﻼس ﻣﺸﺘﻖ ﺷﻮد و ﻓﻘﻂ ﺑﺎﻳﺪ ﺑﻪ ﻋﻨﻮان ﻛﻼس ﭘﺎﻳﻪ ﺑﺮاي دﻳﮕﺮ ﻛﻼﺳﻬﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار .1 ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢabstract ﺑﻨﺎﺑﺮاﻳﻦ آن را از ﻧﻮع،ﮔﻴﺮد abstract class GraphicsItem { // Public members public Color color; public Boolean IsFilled; public Rectangle rectangle; // Public methods public abstract void Draw(Graphics graphics); // Add an item at the given point public void SetPoint(int x, int y, int graphicSize, Color graphicColor, Boolean graphicIsFilled) { // Set the rectangle depending // on the graphic and the size rectangle = new Rectangle( x – (graphicSize / 2), y - (graphicSize / 2), graphicSize, graphicSize); // Set the Color and IsFilled members color = graphicColor; IsFilled = graphicIsFilled; } } GraphicsCircle.cs ﻛﻼس دﻳﮕﺮي ﺑﻪ ﻧـﺎمSolution Explorer ( ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي4 دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ ﻛـﻼس. اﻳﺠﺎد ﺷﻮدGraphicsCricle اﻳﺠﺎد ﻛﺮده و ﻛﺪ زﻳﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ ﻛﻼس . ﺷﻮدoverride ﻧﻴﺰ در آنDraw ﻣﺸﺘﻖ ﺷﺪه و ﻣﺘﺪGraphicsItem ﺑﺎﻳﺪ از ﻛﻼس public class GraphicsCircle : GraphicsItem { . و دﻟﻴﻞ اﺳﺘﻔﺎده از آﻧﻬﺎ ﺑﻪ ﻓﺼﻞ دﻫﻢ "ﻣﺒﺎﺣﺚ ﭘﻴﺸﺮﻓﺘﻪ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔﺮا" ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪabstract ﺑﺮاي آﺷﻨﺎﻳﻲ ﺑﺎ ﻛﻼﺳﻬﺎي1
٥٣٦
)public override void Draw(Graphics graphics { // Create a new pen SolidBrush objSolidBrush = new ;)SolidBrush(this.Color // Draw the circle graphics.FillEllipse(objSolidBrush, ;)this.Rectangle } }
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻛﻼس GraphicsItemدر اﻳﻦ ﻗﺴﻤﺖ ﺷﺎﻣﻞ ﺗﻤﺎﻣﻲ اﻋﻀﺎﻳﻲ اﺳﺖ ﻛﻪ ﺑﺎﻳﺪ در اﺑﺰارﻫﺎي اﺑﺘﺪاﻳﻲ ﺗﺮﺳﻴﻢ وﺟﻮد داﺷـﺘﻪ ﺑﺎﺷـﻨﺪ. ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻤﺎم ﻛﻼﺳﻬﺎي ﻣﺮﺑﻮط ﺑﻪ اﺑﺰارﻫﺎي ﺗﺮﺳﻴﻢ ﻣﺎﻧﻨﺪ GraphicsCircleﺑﺎﻳﺪ از اﻳﻦ ﻛﻼس ﻣﺸﺘﻖ ﺷﻮﻧﺪ ،اﻣﺎ ﻧﺒﺎﻳﺪ اﺟﺎزه دﻫﻴﻢ ﻛﻪ ﺷﻴﺊ اي ﺑﻪ ﺻﻮرت ﻣﺴﺘﻘﻴﻢ از اﻳﻦ ﻛﻼس ﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﻮد .ﭘﺲ اﻳﻦ ﻛﻼس را از ﻧﻮع abstractﻣﻌﺮﻓﻲ ﻣﻲ ﻛﻨﻴﻢ. ﻫﻤﭽﻨﻴﻦ در ﺗﻤﺎم اﺑﺰارﻫﺎي ﺗﺮﺳﻴﻢ ﺑﺎﻳﺪ ﻣﺘﺪي ﺑﻪ ﻧﺎم Drawداﺷﺘﻪ ﺑﺎﺷﻴﻢ ﺗﺎ ﺑﻪ وﺳﻴﻠﻪ ي آن ﺑﺘﻮاﻧﻴﻢ ﺷـﻜﻞ را رﺳـﻢ ﻛﻨـﻴﻢ .اﻣـﺎ ﭘﻴـﺎده ﺳﺎزي اﻳﻦ ﻣﺘﺪ در ﻫﺮ اﺑﺰاري ﻣﺘﻔﺎوت اﺳﺖ .ﭘﺲ اﻳﻦ ﻣﺘﺪ را ﺑﻪ ﺻﻮرت abstractﻣﻌﺮﻓﻲ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺗﻤﺎم ﻛﻼس ﻫـﺎﻳﻲ ﻛـﻪ از GraphicsItemﻣﺸﺘﻖ ﻣﻲ ﺷﻮﻧﺪ ،اﻳﻦ ﻣﺘﺪ را overrideﻛﺮده و ﭘﻴﺎده ﺳﺎزي ﻣﺮﺑﻮط ﺑﻪ ﺧﻮد را در آن ﻗﺮار دﻫﻨﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ SetPointﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از ﻣﻮﻗﻌﻴﺖ ﻛﻨﻮﻧﻲ ﻣﺎوس و ﻧﻴﺰ رﻧﮓ و اﻧﺪازه ي ﻣﺸﺨﺺ ﺷﺪه ﺗﻮﺳـﻂ ﭘـﺎراﻣﺘﺮ ﻫﺎ ،ﺑﻪ ﻓﻴﻠﺪ ﻫﺎي ﻣﻮﺟﻮد در ﺷﻴﺊ ﻣﻘﺪار دﻫﻴﻢ .در اﻳﻦ ﻣﺘﺪ اﺑﺘﺪا ﻳﻚ ﻣﺴﺘﻄﻴﻞ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ. ﻣﻌﻤﻮﻻً ﺑﺮاي رﺳﻢ ﻳﻚ داﻳﺮه از ﻣﺮﻛﺰ و ﺷﻌﺎع آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ،اﻣﺎ در .NETﺑﺮاي رﺳﻢ ﻳﻚ داﻳﺮه ﺑﺎﻳﺪ ﻣﺴﺘﻄﻴﻞ اي ﻛﻪ آن داﻳﺮه را درﺑﺮ ﻣﻲ ﮔﻴﺮد را ﻣﺸﺨﺺ ﻛﻨﻴﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ اﺳﺘﻔﺎده از ﻣﻮﻗﻌﻴﺖ ﻣﺎوس و ﻧﻴﺰ اﻧﺪازه ي ﺷﻜﻠﻲ ﻛﻪ ﺑﺎﻳﺪ ﺗﺮﺳﻴﻢ ﺷـﻮد )ﻛـﻪ ﺑـﺎ اﺳـﺘﻔﺎده از ﭘﺎراﻣﺘﺮ graphicSizeﺑﻪ ﻣﺘﺪ ارﺳﺎل ﻣﻲ ﺷﻮد( ،ﻣﻮﻗﻌﻴﺖ ﮔﻮﺷﻪ ي ﺑﺎﻻ و ﺳﻤﺖ ﭼﭗ ﻣﺴﺘﻄﻴﻞ را ﺑﺪﺳﺖ ﻣﻲ آورﻳﻢ و ﻣـﺴﺘﻄﻴﻞ را اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ. ﻣﺘﺪ ﺳﺎزﻧﺪه ي ﻛﻼس Rectangleﺑﺮاي اﻳﺠﺎد ﻳﻚ ﻣﺴﺘﻄﻴﻞ ﻋﻼوه ﺑﺮ اﻳﻦ دو ﭘﺎراﻣﺘﺮ ﺑﻪ ﻃﻮل و ﻋﺮض ﻣﺴﺘﻄﻴﻞ ﻧﻴﺰ ﻧﻴـﺎز دارد ﻛﻪ ﺑﺮاي آﻧﻬﺎ از ﻣﻘﺪار graphicSizeاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .در اﻧﺘﻬﺎ ﻧﻴﺰ رﻧﮓ ﺷﻜﻞ و اﻳﻨﻜﻪ آﻳﺎ ﺑﺎﻳﺪ ﺑﻪ ﺻﻮرت ﺗﻮﭘﺮ رﺳﻢ ﺷﻮد ﻳـﺎ ﻧﻪ را ﻧﻴﺰ در ﻓﻴﻠﺪ ﻫﺎي ﻣﺮﺗﺒﻂ در ﻛﻼس ذﺧﻴﺮه ﻣﻲ ﻛﻨﻴﻢ. // Add an item at the given point public void SetPoint(int x, int y, int graphicSize, Color graphicColor, )Boolean graphicIsFilled { // Set the rectangle depending // on the graphic and the size (rectangle = new Rectangle x - (graphicSize / 2), y - (graphicSize / 2), ;)graphicSize, graphicSize
٥٣٧
// Set the Color and IsFilled members ;color = graphicColor ;IsFilled = graphicIsFilled } ﺑﻌﺪ از اﺗﻤﺎم ﻛﻼس ،GraphicsItemﻛﻼس GraphicsCircleرا از آن ﻣﺸﺘﻖ ﻣﻲ ﻛﻨﻴﻢ .در اﻳﻦ ﻛـﻼس ﻻزم ﻧﻴﺴﺖ ﻣﺘﺪ و ﻳﺎ ﻓﻴﻠﺪ ﺧﺎﺻﻲ را اﻳﺠﺎد ﻛﻨﻴﻢ و ﻓﻘﻂ ﺑﺎﻳﺪ ﻣﺘﺪ Drawرا ﻛﻪ در ﻛﻼس ﭘﺎﻳﻪ ﺑﻪ ﺻﻮرت abstractﻣـﺸﺨﺺ ﺷـﺪه اﺳﺖ overrideﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ ﻫﻤﺎﻧﻄﻮر ﻛﻪ از ﻧﺎم آن ﻣﺸﺨﺺ اﺳﺖ ،وﻇﻴﻔﻪ ي رﺳﻢ ﺷﻜﻞ را ﺑﺮ ﻋﻬﺪه دارد .رﺳـﻢ ﻳـﻚ ﺷـﻜﻞ ﻧﻴﺰ ﻣﻌﻤﻮﻻً ﺑﻪ ﺻﻮرت ﻓﺮاﺧﻮاﻧﻲ ﭼﻨﺪ ﻣﺘﺪ ﺳﺎده از ﻛﻼس Graphicsﺻﻮرت ﻣﻲ ﮔﻴﺮد .در اﻳﻦ ﻣﺘﺪ اﺣﺘﻴﺎج دارﻳﻢ ﻛﻪ ﻳﻚ داﻳـﺮه را در ﺻﻔﺤﻪ رﺳﻢ ﻛﻨﻴﻢ ،ﺑﻨﺎﺑﺮاﻳﻦ از ﻣﺘﺪ FillEllipseاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ ﺑﺮ ﺣﺴﺐ ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ ﻛﻪ ﺑﻪ آن ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد ﻣﻲ ﺗﻮاﻧـﺪ داﻳـﺮه ﻫـﺎ و ﻳـﺎ ﺑﻴـﻀﻲ ﻫـﺎي ﺗـﻮﭘﺮ را در ﺻـﻔﺤﻪ رﺳـﻢ ﻛﻨـﺪ .ﺑـﺮاي رﺳـﻢ داﻳـﺮه و ﻳـﺎ ﺑﻴـﻀﻲ ﻣﻌﻤـﻮﻟﻲ ﺑﺎﻳـﺪ از ﻣﺘـﺪ DrawEllipseاﺳﺘﻔﺎده ﻛﻨﻴﻢ. ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ داﻳﺮه ي ﻣﻮرد ﻧﻈﺮ را رﺳﻢ ﻛﻨﻴﻢ ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ از ﭼﻪ ﻧﻮع ﻗﻠﻢ ﻣﻮﻳﻲ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﺮاي رﻧﮓ آﻣﻴﺰي ﺷـﻜﻞ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ ﺷﻴﺊ اي از ﻛﻼس Brushو ﻳﺎ ﻛﻼﺳﻬﺎي ﻣﺸﺘﻖ ﺷﺪه از آن اﺳﺘﻔﺎده ﻛﻨﻴﻢ .در اﻳﻨﺠﺎ ﺑـﺮاي ﺗﻌﻴـﻴﻦ ﻧﻮع ﻗﻠﻢ ﻣﻮ ،ﻳﻚ ﺷﻴﺊ از ﻛﻼس SolidBrushﺑﺎ رﻧﮓ ﻣﺸﺨﺺ ﺷﺪه در ﻓﻴﻠﺪ colorاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ. در ﺣﻘﻴﻘﺖ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ FillEllipseﺑﻪ اﻳﻦ ﺻﻮرت ،ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻣﻲ ﮔﻮﻳﻴﻢ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﻗﻠﻢ ﻣﻮي ﻣﺸﺨﺺ ﺷـﺪه در ﺷﻴﺊ ،objSolidBrushداﻳﺮه اي را در ﻣﺤﺪوده ي ﺗﻌﻴﻴﻦ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي rectangleرﺳﻢ ﻛﻨﺪ. public class GraphicsCircle : GraphicsItem { )public override void Draw(Graphics graphics { // Create a new pen SolidBrush objSolidBrush = new ;)SolidBrush(this.Color // Draw the circle graphics.FillEllipse(objSolidBrush, ;)this.Rectangle } }
ﻣﺨﺘﺼﺎت ﺻﻔﺤﻪ و ﻣﺨﺘﺼﺎت ﺑﺮﻧﺎﻣﻪ: ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ راﺑﻂ ﻛﺎرﺑﺮي را ﺧﻮدﺗﺎن رﺳﻢ ﻛﻨﻴﺪ ،ﻣﻌﻤﻮﻻً ﺑﻪ داﻧﺴﺘﻦ ﻣﻮﻗﻌﻴﺖ ﻣﺎوس زﻳﺎد اﺣﺘﻴﺎج ﭘﻴﺪا ﺧﻮاﻫﻴﺪ ﻛﺮد. ﻗﺒﻞ از اﻳﻦ ﮔﻔﺘﻴﻢ ﻛﻪ واﺣﺪ اﻧﺪازه ﮔﻴﺮي ﺑﺮاي رﺳﻢ اﺷﻜﺎل در .NETﭘﻴﻜﺴﻞ اﺳﺖ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ وﻗﺘﻲ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻣﻮﻗﻌﻴﺖ ﻣﺎوس را ﺑﺪﺳﺖ آورﻳﻢ )ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﺪاﻧﻴﻢ ﻣﺎوس روي ﻛﻨﺘﺮل ﺧﺎﺻﻲ ﻗﺮار دارد ﻳﺎ ﻧﻪ( ،ﻧﺘﻴﺠﻪ اي ﻛﻪ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﻴﻢ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻣﺎوس در ﻛﺪام ﭘﻴﻜﺴﻞ از ﺻﻔﺤﻪ ﻗﺮار دارد .ﻣﻌﻤﻮﻻً اﮔﺮ ﻣﺎوس در ﮔﻮﺷﻪ ﺳﻤﺖ ﭼﭗ ﺑﺎﻻي ﻓﺮم ﻗﺮار داﺷﺘﻪ ﺑﺎﺷﺪ ،ﻣﻘﺪار 0,0و اﮔﺮ در ﮔﻮﺷﻪ ﺳﻤﺖ راﺳﺖ در ﭘﺎﻳﻴﻦ ﻓﺮم ﻗﺮار داﺷﺘﻪ ﺑﺎﺷﺪ ،ﻣﻘﺪار 1024*768ﺑﻪ ﻋﻨﻮان ﻣﻮﻗﻌﻴﺖ ﻣﺎوس ﺑﺮﮔﺸﺖ داده ﻣﻲ ﺷﻮد.
٥٣٨
ﻣﻤﻜﻦ اﺳﺖ اﻳﻦ ﻣﻮرد ﺑﺴﻴﺎر واﺿﺢ ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ ،اﻣﺎ ﺑﺎﻳﺪ دﻗﺖ ﻛﻨﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺎوس در ﻓﺮم ﻳﻚ ﺑﺮﻧﺎﻣـﻪ ﻗـﺮار دارد ﻣﻮﻗﻌﻴـﺖ ﻣـﺎوس ﻧﺴﺒﺖ ﺑﻪ ﮔﻮﺷﻪ ﻫﺎي ﻓﺮم ﺳﻨﺠﻴﺪه ﻣﻲ ﺷﻮد ﻧﻪ ﻧﺴﺒﺖ ﺑﻪ ﮔﻮﺷﻪ ﻫﺎي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ. ﺑﺮاي ﻣﺜﺎل ﺑﻪ ﺷﻜﻞ 2-14دﻗﺖ ﻛﻨﻴﺪ .در اﻳﻦ ﺷﻜﻞ ﺑﺮﻧﺎﻣﻪ ي MyPaintﻛﻪ ﺗﻘﺮﻳﺒﺎً در ﮔﻮﺷﻪ ي ﺳﻤﺖ راﺳﺖ ﭘﺎﻳﻴﻦ ﻓﺮم ﻗﺮار دارد ﻧﺸﺎن داده ﺷﺪه اﺳﺖ .ﺻﻔﺤﻪ ﻧﻤﺎﻳﺸﻲ ﻛﻪ در اﻳﻦ ﺷﻜﻞ ﻧﺸﺎن داده ﺷﺪه اﺳﺖ داراي 1024ﭘﻴﻜﺴﻞ اﻓﻘﻲ و 768ﭘﻴﻜﺴﻞ ﻋﻤﻮدي اﺳـﺖ، ﺑﻨﺎﺑﺮاﻳﻦ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ي MyPaintﻧﺴﺒﺖ ﺑﻪ ﮔﻮﺷﻪ ي ﺑﺎﻻ ﺳﻤﺖ ﭼﭗ ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﺗﻘﺮﻳﺒﺎً در ﻣﻮﻗﻌﻴﺖ ) (500,300ﻗـﺮار دارد.
ﺷﻜﻞ 2-14 ﻫﺮ ﻓﺮم داراي ﻳﻚ ﻣﺤﺪوده اﺳﺖ ﻛﻪ ﻣﻌﻤﻮﻻً ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮرد اﺳﺘﻔﺎده در ﺑﺮﻧﺎﻣﻪ ،در آن ﻣﺤﺪوده ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .اﻳﻦ ﻣﺤﺪوده ﺷﺎﻣﻞ ﺗﻤﺎم ﻣﺤﻴﻂ ﻃﺮاﺣﻲ ﻓﺮم ﺑﻪ ﺟﺰ ﻗﺴﻤﺘﻬﺎي اﺿﺎﻓﻲ ﻣﺎﻧﻨﺪ ﺣﺎﺷﻴﻪ ي ﻓﺮم ،ﻧﻮار ﻋﻨﻮان ،ﻧﻮار ﻣﻨﻮ و ﻧﻮار اﺑﺰار ﻣﻲ ﺷﻮد .ﻣﻌﻤﻮﻻً ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺣﺎل ﺗﺮﺳﻴﻢ ﻳﻚ ﻛﻨﺘﺮل در ﻓﺮم ﻫﺴﺘﻴﺪ ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﻴﺪ از اﻳﻦ ﻧﺎﺣﻴﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ،ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻧﻴﺎزي ﻧﺪارﻳﺪ ﻛﻪ ﻣﻮﻗﻌﻴﺖ ﻛﻨﺘﺮل ﻫﺎ را ﻧﺴﺒﺖ ﺑﻪ ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﺑﺪاﻧﻴﺪ .ﺑﻨﺎﺑﺮاﻳﻦ در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻣﻮﻗﻌﻴﺖ ﻣﺎوس و دﻳﮕﺮ ﻛﻨﺘﺮل ﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻧﺎﺣﻴﻪ ﻧﺴﺒﺖ ﺑﻪ ﮔﻮﺷﻪ ي ﺑﺎﻻ ﺳﻤﺖ ﭼﭗ ﻓﺮم ﮔﺰارش ﻣﻲ ﺷﻮﻧﺪ. در اﻳﻦ ﻣﺜﺎل اﮔﺮ ﻣﺎوس ﺧﻮد را در ﮔﻮﺷﻪ ي ﺑﺎﻻ ﺳﻤﺖ ﭼﭗ ﻓﺮم در ﺷﻜﻞ 2-14ﻗﺮار دﻫﻴﺪ ،دو ﻧﻮع ﻣﺨﺘﺼﺎت ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮاي آن درﻳﺎﻓﺖ ﻛﻨﻴﺪ:
٥٣٩
ﻣﺨﺘﺼﺎت اول ﻣﺎوس ) (510,330اﺳﺖ و ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻣﻘﺪاري از ﻣﺨﺘﺼﺎت ﻟﺒﻪ ي ﻓﺮم ﻧﺴﺒﺖ ﺑﻪ ﮔﻮﺷﻪ ي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﭘﺎﻳﻴﻦ ﺗﺮ اﺳﺖ .اﻳﻦ ﻣﺨﺘﺼﺎت ﻣﻌﻤﻮﻻً ﺑﻪ ﻋﻨﻮان ﻣﺨﺘﺼﺎت ﻣﻄﻠﻖ 1ﻫﻢ ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮد. ﻣﺨﺘﺼﺎت دوم ﻓﺮم ﭼﻴﺰي در ﺣﺪود ) (0,0اﺳﺖ ﻛﻪ ﻧﺴﺒﺖ ﺑﻪ ﻟﺒﻪ ي ﻣﺤﻴﻂ ﻃﺮاﺣﻲ ﻓﺮم ﺳﻨﺠﻴﺪه ﻣﻲ ﺷﻮد .اﻳﻦ ﻣﺨﺘﺼﺎت ﺑﻪ ﻣﻜﺎن ﻓﺮم در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﺑﺴﺘﮕﻲ ﻧﺪارد و ﻓﺮم در ﻫﺮ ﻧﻘﻄﻪ اي از ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻛﻪ ﻗﺮار داﺷﺘﻪ ﺑﺎﺷﺪ، ﻣﺨﺘﺼﺎت اﻳﻦ ﻧﻘﻄﻪ ﺗﻘﺮﻳﺒﺎً ) (0,0ﺧﻮاﻫﺪ ﺑﻮد .اﻳﻦ ﻣﺨﺘﺼﺎت ﻣﻌﻤﻮﻻً ﺑﻪ ﻋﻨﻮان ﻣﺨﺘﺼﺎت ﻧﺴﺒﻲ 2ﻓﺮم ﻧﻴﺰ ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮد.
ﺑﺮرﺳﻲ ﺣﺮﻛﺎت ﻣﺎوس و رﺳﻢ اﺷﻴﺎي :GraphicsCircle ﺑﺮاي ﻧﻮﺷﺘﻦ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ي ﮔﺮاﻓﻴﻜﻲ ،ﺣﺮﻛﺎت ﻣﺎوس ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺎرﺑﺮ را دﻧﺒﺎل ﻣﻲ ﻛﻨـﻴﻢ و ﺳـﭙﺲ اﺷـﻴﺎﻳﻲ را از ﻳﻜـﻲ از ﻛﻼﺳـﻬﺎي ﻣﺸﺘﻖ ﺷﺪه از GraphicsItemاﻳﺠﺎد ﻛﺮده و در ﻳﻚ ﻟﻴﺴﺖ ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﻴﻢ .زﻣﺎﻧﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﻢ ﺷﻜﻞ ﺗﺮﺳـﻴﻢ ﺷـﺪه ﺑـﻪ وﺳﻴﻠﻪ ي ﻛﺎرﺑﺮ را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﻴﻢ ،در ﺑﻴﻦ اﺷﻴﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻟﻴﺴﺖ ﺣﺮﻛﺖ ﻛـﺮده و ﻣﺘـﺪ Drawرا در ﻫـﺮ ﻛـﺪام از آﻧﻬـﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻛﺪ اﻳﻦ ﻣﻮارد را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :رﺳﻢ اﺷﻜﺎل اﻳﺠﺎد ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺎرﺑﺮ در ﺻﻔﺤﻪ (1در ﭘﻨﺠﺮه ي Solution Explorerروي ﻛﻨﺘﺮل PaintCanvasﻛﻠﻴﻚ راﺳﺖ ﻛـﺮده و ﮔﺰﻳﻨـﻪ ي View Codeرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺳﭙﺲ ﺷﻤﺎرﻧﺪه ﻫﺎي ﻣـﺸﺨﺺ ﺷـﺪه در زﻳـﺮ را ﺑـﻪ ﻛـﻼس PaintCanvas اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺷﻤﺎرﻧﺪه ي اول ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن ﻧﻮع اﺑﺰاري ﻛﻪ ﺑﺮاي رﺳﻢ ﺑﻪ ﻛﺎر رﻓﺘﻪ اﺳﺖ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد )داﻳﺮه و ﻳـﺎ ﻣﺴﺘﻄﻴﻞ( ،ﺷﻤﺎرﻧﺪه ي دوم ﻧﻴﺰ ﺑﺮاي ﺗﻌﻴﻴﻦ ﺿﺨﺎﻣﺖ آن اﺑﺰار ﺑﻪ ﻛﺎر ﻣﻲ رود. public partial class PaintCanvas : UserControl { public enum GraphicTools { CirclePen = 0 } public enum GraphicSizes { Samll = 4, Medium = 10, Large = 20 } (2ﻓﻴﻠﺪ ﻫﺎي زﻳﺮ را ﻧﻴﺰ ﺑﻪ ﻛﻼس PaintCanvasاﺿﺎﻓﻪ ﻛﻨﻴﺪ:
Absolute Position Relative Position
1 2
٥٤٠
// Public members ;)(public ArrayList GraphicsItems = new ArrayList ;public GraphicTools GraphicTool = GraphicTools.CirclePen ;public GraphicSizes GraphicSize = GraphicSizes.Medium ;public Color GraphicColor = Color.Black در ﻟﻴﺴﺖ زﻳﺮ ﻛﺎرﺑﺮد ﻫﺮ ﻳﻚ از اﻳﻦ ﻓﻴﻠﺪ ﻫﺎ ﺷﺮح داده ﺷﺪه اﺳﺖ .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﺑﺮاي اﻳﻦ ﻓﻴﻠﺪ ﻫﺎ ﻣﻘﺪار ﭘﻴﺶ ﻓﺮض در ﻧﻈﺮ ﮔﺮﻓﺘﻪ اﻳـﻢ ﺗﺎ ﻣﻘﺪار دﻫﻲ اوﻟﻴﻪ ﺑﻪ آﻧﻬﺎ ﺳﺎده ﺗﺮ ﺷﻮد.
GraphicsItemsﺷﺎﻣﻞ ﻟﻴﺴﺘﻲ از اﺷﻴﺎي ﻣﺸﺘﻖ ﺷﺪه از ﻛﻼس GraphicsItemاﺳﺖ ﻛﻪ ﺷﻜﻞ رﺳﻢ ﺷﺪه در ﻓﺮم را ﺗﺸﻜﻴﻞ ﻣﻲ دﻫﻨﺪ. GraphicToolﺣﺎوي اﺑﺰاري اﺳﺖ ﻛﻪ ﻫﻢ اﻛﻨﻮن ﺑﺮاي ﺗﺮﺳﻴﻢ در ﻓﺮم ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ. GraphicSizeﺣﺎوي اﻧﺪازه ي ﺿﺨﺎﻣﺖ اﺑﺰاري اﺳﺖ ﻛﻪ ﻫﻢ اﻛﻨﻮن ﺑﺮاي ﺗﺮﺳﻴﻢ در ﻓﺮم ﻣﻮرد اﺳـﺘﻔﺎده ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ. GraphicColorﺣﺎوي رﻧﮓ اﺑﺰاري اﺳﺖ ﻛﻪ ﺑﺮاي ﺗﺮﺳﻴﻢ در ﻓﺮم ﺑﻪ ﻛﺎر ﻣﻲ رود.
(3رﺳﻢ ﻳﻚ ﺷﻜﻞ در ﻓﺮم ﺑﺎ اﺳﺘﻔﺎده از ﻣﺎوس از دو ﻣﺮﺣﻠﻪ ﺗﺸﻜﻴﻞ ﻣﻲ ﺷﻮد .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي ﻣﺎوس ﻛﻠﻴﻚ ﻣﻲ ﻛﻨـﺪ و ﺳﭙﺲ در ﺣﺎﻟﻲ ﻛﻪ ﻛﻠﻴﺪ ﻣﺎوس را ﻧﮕﻪ داﺷﺘﻪ اﺳﺖ ،ﻣﻮﻗﻌﻴﺖ ﻣﺎوس را ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﺪ .در اﻳﻦ ﺣﺎﻟﺖ ﺑﺎﻳﺪ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻛـﺎرﺑﺮ ﻣﺎوس را ﺣﺮﻛﺖ ﻣﻲ دﻫﺪ ،ﺑﻪ ﺻﻮرت ﻣـﺪاوم اﺷـﻴﺎﻳﻲ را از ﻧـﻮع GraphicsCircleاﻳﺠـﺎد ﻛـﺮده و ﺑـﻪ ﻟﻴـﺴﺖ GraphicsItemsاﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﺎ اﻳﻦ ﻛﺎر ﻟﻴﺴﺖ GraphicsItemsﺣـﺎوي اﺷـﻴﺎﻳﻲ ﺧﻮاﻫـﺪ ﺑـﻮد ﻛـﻪ ﻛﺎرﺑﺮ ﺑﺎ ﭘﺎﻳﻴﻦ ﻧﮕﻪ داﺷﺘﻦ ﻛﻠﻴﺪ ﻣﺎوس و ﺣﺮﻛﺖ آن در ﻓﺮم رﺳﻢ ﻛﺮده اﺳﺖ .ﺑﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ وﻳﻨـﺪوز از ﺷـﻤﺎ ﺧﻮاﺳﺖ ﺗﺎ ﻛﻨﺘﺮل را رﺳﻢ ﻛﻨﻴﺪ ،ﻛﺎﻓﻲ اﺳﺖ در ﺑﻴﻦ اﺷﻴﺎي ﻣﻮﺟﻮد در ﻓﺮم ﺣﺮﻛﺖ ﻛﺮده و ﻣﺘﺪ Drawرا در ﻫﺮ ﻳﻚ از آﻧﻬـﺎ ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده ﺗﺎ در ﺻﻔﺤﻪ رﺳﻢ ﺷﻮﻧﺪ .ﻣﺘﺪ زﻳﺮ را ﺑﻪ ﻛﻼس PaintCanvasاﺿﺎﻓﻪ ﻛﻨﻴﺪ: )private void DoMousePaint(MouseEventArgs e { // Store the new item somewhere ;GraphicsItem objGraphicsItem = null ?// What tool are you using )switch(GraphicTool { // CirclePen case GraphicTools.CirclePen: { // Create a new graphics circle = GraphicsCircle objGraphicsCircle ;)(new GraphicsCircle // Set the point for drawing objGraphicsCircle.SetPoint(e.X, e.Y, (int)GraphicSize,
٥٤١
GraphicColor, true); // Store this for addition objGraphicsItem = objGraphicsCircle; break; } } // Were you given an item? if( objGraphicsItem != null) { // Add it to the list GraphicsItems.Add(objGraphicsItem); // Invalidate the control this.Invalidate(); } } ﺳـﭙﺲ در. ﺑﺮوﻳﺪ و ﺑﺮ روي ﻗﺴﻤﺘﻲ از ﻛﻨﺘﺮل ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﻧﺘﺨﺎب ﺷﻮدPaintCanvas ( ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻛﻨﺘﺮل4 ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻟﻴـﺴﺘﻲ از روﻳـﺪادﻫﺎي اﻳـﻦ ﻛﻨﺘـﺮل را ﻣـﺸﺎﻫﺪهEvents روي آﻳﻜﻮنProperties ﭘﻨﺠﺮه ي ﺳـﭙﺲ ﻛـﺪ زﻳـﺮ را در ﻣﺘـﺪ. را اﻧﺘﺨﺎب ﻛﺮده و روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴـﺪMouseDown در اﻳﻦ ﻟﻴﺴﺖ روﻳﺪاد.ﻛﻨﻴﺪ :ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد وارد ﻛﻨﻴﺪ private void PaintCanvas_MouseDown(object sender, MouseEventArgs e) { // Is the left mouse button down? if( e.Button == MouseButtons.Left) DoMousePaint(e); } روﻳــﺪادProperties ( ﻣﺠــﺪداً ﺑــﻪ ﻗــﺴﻤﺖ ﻃﺮاﺣــﻲ ﻛﻨﺘــﺮل ﺑﺮﮔــﺸﺘﻪ و در اﻳــﺴﺖ روﻳــﺪادﻫﺎ در ﭘﻨﺠــﺮه ي5 ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ. را اﻧﺘﺨﺎب ﻛﺮده و روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪMouseMove :روﻳﺪاد وارد ﻛﻨﻴﺪ private void PaintCanvas_MouseMove(object sender, MouseEventArgs e) { // Is the left mouse button down? if (e.Button == MouseButtons.Left) DoMousePaint(e); }
٥٤٢
(6در آﺧﺮ ﻧﻴﺰ ﻫﻤﻴﻦ ﻣﺮاﺣﻞ را ﺗﻜﺮار ﻛﺮده ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Paintرا ﻧﻴﺰ اﻳﺠﺎد ﻛﻨﻴﺪ .ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳـﻦ ﻣﺘـﺪ وارد ﻛﻨﻴﺪ: private void PaintCanvas_Paint(object sender, )PaintEventArgs e { // Go through the list foreach (GraphicsItem objGraphicsItem in )GraphicsItems { // Ask each item to draw itself ;)objGraphicsItem.Draw(e.Graphics } } (7ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن ﻣﺎوس روي ﻓﺮم و ﺣﺮﻛﺖ دادن آن ﺷﻜﻠﻲ را در ﻓﺮم رﺳﻢ ﻛﻨﻴﺪ. ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺮﻧﺎﻣﻪ اي ﻣﺸﺎﺑﻪ Paintاﻳﺠﺎد ﻛﺮده اﻳﺪ .اﻟﺒﺘﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ اﮔﺮ ﺧﻄﻬﺎي رﺳﻢ ﺷﺪه در ﻓﺮم زﻳﺎد ﺷﻮﻧﺪ ،ﺑﺮﻧﺎﻣﻪ ﺑﻴﺶ از ﺣﺪ ﻛﻨﺪ ﺧﻮاﻫﺪ ﺷﺪ .در راﺑﻄﻪ ﺑﺎ اﻳﻦ ﻣﻮرد ﺑﻌﺪﻫﺎ ﺑﻴﺸﺘﺮ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد ،اﻣﺎ اﺑﺘﺪا ﺑﻬﺘﺮ اﺳﺖ ﺧﻮد ﺑﺮﻧﺎﻣﻪ و ﻧﺤـﻮه ي ﻋﻤﻠﻜـﺮد آن را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ زﻣﺎﻧﻲ ﻛﻪ ﻛﺎرﺑﺮ ﻣـﺎوس را روي ﻳـﻚ ﺷـﻴﺊ از ﻛﻨﺘـﺮل PaintCanvasﺣﺮﻛـﺖ ﻣـﻲ دﻫـﺪ ،روﻳـﺪاد MouseMoveآن ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد .در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ آﻳﺎ ﻛﻠﻴﺪ ﭼﭗ ﻣﺎوس ﻓﺸﺎر داده ﺷﺪه اﺳﺖ ﻳﺎ ﻧﻪ .اﮔﺮ اﻳﻦ ﻛﻠﻴﺪ ﻓﺸﺎر داده ﺷﺪه ﺑﻮد ،ﻣﺘﺪ DoMousePaintرا ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده و ﺷﻴﺊ MouseEventArgsرا ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ آن ﻣﻲ ﻓﺮﺳﺘﻴﻢ. private void PaintCanvas_MouseMove(object sender, )MouseEventArgs e { ?// Is the left mouse button down )if (e.Button == MouseButtons.Left ;)DoMousePaint(e } ﭘﺮوﺳﻪ ي اﺻﻠﻲ ﺗﺮﺳﻴﻢ ﺷﻜﻞ در ﻣﺘﺪ DoMousePaintاﻧﺠﺎم ﻣﻲ ﺷﻮد .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ اﻳﻦ ﻣﺘﺪ زﻣﺎﻧﻲ ﻓﺮاﺧـﻮاﻧﻲ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﺎرﺑﺮ ﻛﻠﻴﺪ ﭼﭗ ﻣﺎوس را ﻓﺸﺎر داده و ﺳﭙﺲ ﻣﺎوس را روي ﻛﻨﺘﺮل ﺣﺮﻛﺖ دﻫﺪ .در اﻳﻦ ﺣﺎﻟﺖ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﻣﻮﻗﻌﻴـﺖ ﻣﺎوس ﺑﻪ وﺳﻴﻠﻪ ي ﺷﻴﺊ اي از ﻛﻼس MouseEventArgsﺑﻪ اﻳﻦ ﻣﺘﺪ ارﺳﺎل ﻣﻲ ﺷﻮد ،و ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ اﻃﻼﻋﺎت و اﻃﻼﻋﺎﺗﻲ دﻳﮕﺮ از ﻗﺒﻴﻞ ﻧﻮع اﺑﺰار ،ﺿﺨﺎﻣﺖ اﺑﺰار و ...ﺷﻜﻞ ﺟﺪﻳﺪ را ﺗﺮﺳﻴﻢ ﻛﻨﻴﻢ.
٥٤٣
ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﺑﺮاي رﺳﻢ ﻳﻚ ﺷﻜﻞ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺎوس ،ﺑﺎﻳﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ در ﻧﻘﻄﻪ اي از ﻛﻨﺘﺮل ﻛﻠﻴﻚ ﻣﻲ ﻛﻨﺪ )و ﻳـﺎ در ﺣﺎﻟﻲ ﻛﻪ ﻛﻠﻴﺪ ﻣﺎوس را ﻧﮕﻪ داﺷﺘﻪ اﺳﺖ ،ﻣﺎوس را از روي ﻧﻘﻄﻪ اي ﻣﻲ ﮔﺬراﻧﺪ( ،ﺑﺮ اﺳﺎس اﺑﺰاري ﻛﻪ اﻧﺘﺨﺎب ﻛﺮده اﺳﺖ ﻳﺎ ﻳﻚ داﻳـﺮه ي ﻛﻮﭼﻚ و ﻳﺎ ﻳﻚ ﻣﺴﺘﻄﻴﻞ ﻛﻮﭼﻚ در آن ﻧﻘﻄﻪ رﺳﻢ ﻣﻲ ﺷﻮد .اﻳﻦ داﻳﺮه ﻫﺎ و ﻳﺎ ﻣﺴﺘﻄﻴﻞ ﻫﺎي ﻛﻮﭼﻚ در ﺣﻘﻴﻘﺖ ﻣﺎﻧﻨﺪ ﻧﻘﻄﻪ ﻋﻤﻞ ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ اﮔﺮ در ﻛﻨﺎر ﻳﻜﺪﻳﮕﺮ ﻗﺮار ﺑﮕﻴﺮﻧﺪ ،ﺷﻜﻠﻲ را ﺗﺸﻜﻴﻞ ﻣﻲ دﻫﻨﺪ. ﭘﺲ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ آراﻳﻪ اي اﻳﺠﺎد ﻛﻨﻴﻢ و ﻧﻘﻄﻪ ﻫﺎﻳﻲ را ﻛﻪ ﺷﻜﻞ از آﻧﻬﺎ ﺗﺸﻜﻴﻞ ﻣﻲ ﺷﻮد را در آن آراﻳﻪ ﻗﺮار دﻫـﻴﻢ .ﺑـﻪ ﻋﺒـﺎرت دﻳﮕﺮ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ آراﻳﻪ اي اﻳﺠﺎد ﻛﻨﻴﻢ و اﺷﻴﺎﻳﻲ را ﻛﻪ از ﻛﻼس داﻳﺮه و ﻳﺎ ﻣﺴﺘﻄﻴﻞ اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ را در آن ﻗﺮار دﻫﻴﻢ .ﺷﻜﻠﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ ﺑﻪ اﻳﻦ آراﻳﻪ اﺿﺎﻓﻪ ﺷﻮد ﭼﻪ ﻳﻚ داﻳﺮه ﺑﺎﺷﺪ )از ﻛﻼس GraphicsCircleﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﺪه ﺑﺎﺷﺪ(و ﭼــﻪ ﻳــﻚ ﻣــﺴﺘﻄﻴﻞ ،از ﻛــﻼس ﭘﺎﻳــﻪ GraphicsItemﻣــﺸﺘﻖ ﺷــﺪه اﺳــﺖ .ﭘــﺲ ﻣــﻲ ﺗﻮاﻧــﺪ در آراﻳــﻪ اي از ﻧــﻮع GraphicsItemﻗﺮار ﺑﮕﻴﺮد .ﺑﻨﺎﺑﺮاﻳﻦ اﺑﺘﺪا ﻳﻚ ﺷﻴﺊ از ﻛﻼس GraphicsItemاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻧﻘﻄﻪ را اﻳﺠﺎد ﻛﺮدﻳﻢ ،ﺑﺘﻮاﻧﻴﻢ آن را در اﻳﻦ ﺷﻴﺊ ﻗﺮار داده و ﺳﭙﺲ ﺑﻪ آراﻳﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ. ﻧﻜﺘﻪ :ﻣﻤﻜﻦ اﺳﺖ در اﻳﻨﺠﺎ اﻳﻦ ﺳﻮال ﺑﻪ وﺟﻮد آﻳﺪ ﻛﻪ ﻛﻼس GraphicsItemاز ﻧﻮع Abstractاﺳﺖ و ﻧﻤﻲ ﺗـﻮان ﺷﻴﺊ را از آن اﻳﺠﺎد ﻛﺮد ،ﭘﺲ ﭼﮕﻮﻧﻪ در اﻳﻦ ﻗﺴﻤﺖ اﻳﻦ ﻛﺎر را اﻧﺠﺎم داده اﻳﻢ؟ دﻗﺖ ﻛﻨﻴﺪ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﺷﻴﺊ ﻧﻤﻮﻧـﻪ ﺳـﺎزي ﻧـﺸﺪه ﺑﺎﺷﺪ )ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر ،(newﺷﻴﺊ اﻳﺠﺎد ﻧﺸﺪه اﺳﺖ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻳﻚ ﺷﻴﺊ زﻣﺎﻧﻲ اﻳﺠﺎد ﻣﻲ ﺷﻮد ﻛﻪ ﻧﻤﻮﻧـﻪ ﺳـﺎزي ﺷـﻮد .در اﻳﻨﺠﺎ ﻧﻴﺰ ﻣﺎ ﻓﻘﻂ ﻣﺘﻐﻴﺮي را اﻳﺠﺎد ﻛﺮده اﻳﻢ ﻛﻪ ﺑﺘﻮاﻧﻴﻢ ﺷﻴﺊ اي از ﻧﻮع GraphicsItemو ﻳﺎ ﻳﻜﻲ از ﻛﻼﺳﻬﺎي ﻣـﺸﺘﻖ ﺷﺪه از آن را در اﻳﻦ ﻣﺘﻐﻴﻴﺮ ذﺧﻴﺮه ﻛﻨﻴﻢ .اﻣﺎ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﻧﻤﻲ ﺗﻮاﻧﻴﻢ ﺷﻴﺊ از ﻛـﻼس GraphicsItemرا ﻧﻤﻮﻧـﻪ ﺳـﺎزي ﻛﻨﻴﻢ ،ﭘﺲ در اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﻴﻢ اﺷﻴﺎﻳﻲ را ﻧﮕﻬﺪاري ﻛﻨﻴﻢ ﻛﻪ از ﻛﻼس ﻫﺎي ﻣﺸﺘﻖ ﺷﺪه از ) GraphicsItemﻣﺎﻧﻨـﺪ (GraphicsCircleﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﺪه ﺑﺎﺷﻨﺪ. در ﺣﻘﻴﻘﺖ ﻫﺪف ﻣﺎ ﻧﻴﺰ در اﻳﻨﺠﺎ اﻳﻦ اﺳﺖ ﻛﻪ ﻣﺘﻐﻴـﺮي داﺷـﺘﻪ ﺑﺎﺷـﻴﻢ ﻛـﻪ ﺑﺘﻮاﻧـﺪ اﺷـﻴﺎﻳﻲ ﻛـﻪ از ﻛﻼﺳـﻬﺎي ﻣـﺸﺘﻖ ﺷـﺪه از ﻛـﻼس GraphicsItemاﻳﺠــﺎد ﻣــﻲ ﺷــﻮﻧﺪ را در آن ذﺧﻴــﺮه ﻛﻨــﻴﻢ .ﺑﻨــﺎﺑﺮاﻳﻦ آن ﻣﺘﻐﻴﻴــﺮ را ﺑﺎﻳــﺪ از ﻧــﻮع ﻛــﻼس ﭘﺎﻳــﻪ ﻳﻌﻨــﻲ GraphicsItemﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ. )private void DoMousePaint(MouseEventArgs e { // Store the new item somewhere ;GraphicsItem objGraphicsItem = null ﺣﺎل ﺑﺎﻳﺪ ﺗﺸﺨﻴﺺ دﻫﻴﻢ ﻛﻪ ﻛﺎرﺑﺮ ﻣﻲ ﺧﻮاﻫﺪ ﺑﺮاي رﺳﻢ ﻧﻘﻄﻪ ﺑﺮ روي ﻳﻚ ﺷﻜﻞ ،از ﻳﻚ داﻳﺮه ي ﻛﻮﭼﻚ اﺳﺘﻔﺎده ﻛﻨـﺪ و ﻳـﺎ از ﻳـﻚ ﻣﺴﺘﻄﻴﻞ ﻛﻮﭼﻚ و ﻳﺎ ،...اﻳﻦ ﻣﻮرد ﻧﻴﺰ ﺑﺴﺘﮕﻲ ﺑﻪ اﺑﺰاري دارد ﻛﻪ ﻛﺎرﺑﺮ در ﺑﺮﻧﺎﻣﻪ ﺑﺮاي رﺳﻢ اﻧﺘﺨﺎب ﻣﻲ ﻛﻨﺪ .اﻳﻦ اﺑﺰار ﻣﻲ ﺗﻮاﻧﺪ ﻳﻜﻲ از ﺛﺎﺑﺖ ﻫﺎي ي ﻣﻮﺟﻮد در ﺷﻤﺎرﻧﺪه ي GraphicToolsﺑﺎﺷﺪ ،ﻛﻪ اﻟﺒﺘﻪ ﻓﻌﻼً ﻓﻘﻂ ﺷﺎﻣﻞ ﻳﻚ ﻋـﻀﻮ ﻳﻌﻨـﻲ CirclePen اﺳﺖ. اﮔﺮ اﺑﺰار اﻧﺘﺨﺎب ﺷﺪه از ﻧﻮع CirclePenﺑﺎﺷﻨﺪ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻛﺎرﺑﺮ ﻣﻲ ﺧﻮاﻫﺪ ﻧﻘﻄﻪ ﻫﺎي اﻳﺠﺎد ﻛﻨﻨـﺪه ي ﺷـﻜﻞ ﺑـﻪ ﺻﻮرت ﻳﻚ داﻳﺮه ﺑﺎﺷﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي ﺗﺸﻜﻴﻞ اﻳﻦ ﻧﻘﻄﻪ ﻫﺎ ﺑﺎﻳﺪ از ﻛﻼس GraphicsCircleاﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﭘﺲ در اﻳـﻦ ﻗﺴﻤﺖ ﺷﻴﺊ اي از ﻧﻮع GraphicsCircleاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ. )switch(GraphicTool { // CirclePen case GraphicTools.CirclePen: {
٥٤٤
// Create a new graphics circle = GraphicsCircle objGraphicsCircle ;)(new GraphicsCircle ﺳﭙﺲ ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ SetPointدر اﻳﻦ ﺷﻴﺊ ،اﻃﻼﻋﺎت ﻻزم در ﻣﻮرد ﻣﺤﻞ ﻗﺮار ﮔﻴﺮي اﻳﻦ ﻧﻘﻄـﻪ و ﻧﻴـﺰ اﻧـﺪازه ي آن را ﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﻣﺤﻞ ﻗﺮار ﮔﻴﺮي اﻳﻦ ﻧﻘﻄﻪ ﻛﻪ ﺑﺎﻳﺪ در ﻣﺤﻞ ﻛﻨﻮﻧﻲ ﻣﺎوس ﺑﺎﺷﺪ ،ﭘﺲ دو ﭘﺎراﻣﺘﺮ اول را ﺑﺮاﺑﺮ ﺑﺎ ﻣﺤﻞ ﻛﻨﻮﻧﻲ ﻣﺎوس ﻛـﻪ در ﺷــﻴﺊ eوﺟــﻮد دارد ﻗــﺮار ﻣــﻲ دﻫــﻴﻢ .ﺿــﺨﺎﻣﺖ ﻧﻘﻄــﻪ ﻧﻴــﺰ ﺑﺎﻳــﺪ ﺑــﺎ اﺳــﺘﻔﺎده از ﻳﻜــﻲ از ﺛﺎﺑــﺖ ﻫــﺎي ﻣﻮﺟــﻮد در ﺷــﻤﺎرﻧﺪه ي GraphicSizesﺗﻌﻴﻴﻦ ﺷﻮد اﻣﺎ ﻧﻮع آن ﺑﺎﻳﺪ ﻋﺪد ﺻﺤﻴﺢ ﺑﺎﺷﺪ ،ﭘﺲ ﻣﻘﺪار اﻧﺘﺨﺎﺑﻲ از اﻳﻦ ﺷﻤﺎرﻧﺪه را ﺑـﻪ ﻳـﻚ ﻋـﺪد ﺻـﺤﻴﺢ ﺗﺒﺪﻳﻞ ﻛﺮده و ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺳﻮم ﺑﻪ ﻣﺘﺪ SetPointﻣﻲ ﻓﺮﺳﺘﻴﻢ .ﭘﺎراﻣﺘﺮ ﭼﻬﺎرم رﻧﮓ ﻧﻘﻄﻪ را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ،ﭘـﺲ ﻣﻘـﺪار ﻓﻴﻠﺪ GraphicColorرا ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﭼﻬﺎرم ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻣﻲ ﻓﺮﺳﺘﻴﻢ .ﭘﺎراﻣﺘﺮ آﺧﺮ ﻧﻴﺰ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ آﻳﺎ ﺑﺎﻳﺪ ﺷـﻜﻞ ﺑﻪ ﺻﻮرت ﺗﻮﭘﺮ رﺳﻢ ﺷﻮد ﻳﺎ ﻧﻪ .در اﻳﻦ ﺟﺎ ﺗﻌﻴﻴﻦ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﺷﻜﻞ ﺑﻪ ﺻﻮرت ﺗﻮﭘﺮ رﺳﻢ ﺷﻮد. // Set the point for drawing objGraphicsCircle.SetPoint(e.X, e.Y, (int)GraphicSize, ;)GraphicColor, true ﺑﻌﺪ از ﺗﻨﻈﻴﻢ ﻗﺴﻤﺖ ﻫﺎي ﻣﺨﺘﻠﻒ ﻧﻘﻄﻪ اي ﻛﻪ ﺑﺎﻳﺪ در ﻓﺮم ﻗﺮار ﮔﻴﺮد ،ﻧﻘﻄﻪ را در ﺷﻴﺊ اي از ﻧﻮع GraphicsItemﻗﺮار ﻣـﻲ دﻫﻴﻢ ﺗﺎ ﺑﻌﺪا ﺑﺘﻮاﻧﻴﻢ آن را ﺑﻪ ﻟﻴﺴﺖ ﻧﻘﻄﻪ ﻫﺎي ﺗﺸﻜﻴﻞ دﻫﻨﺪه ي ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﻢ. // Store this for addition ;objGraphicsItem = objGraphicsCircle ;break ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻧﻘﻄﻪ ي ﻣﻮرد ﻧﻈﺮ اﻳﺠﺎد ﺷﺪه اﺳﺖ .ﺣﺎل ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ اﮔـﺮ ﻣﻘـﺪاري در ﺷـﻴﺊ objGraphicsItem ﻗﺮار ﮔﺮﻓﺘﻪ ﺑﻮد )ﻣﻘﺪار آن ﻣﺨﺎﻟﻒ nullﺑﻮد( ،آن را ﺑﻪ آراﻳﻪ ي ﻧﻘﺎط ﺗﺸﻜﻴﻞ دﻫﻨﺪه ي ﻓﺮم اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ. ?// Were you given an item )if( objGraphicsItem != null { // Add it to the list ;)GraphicsItems.Add(objGraphicsItem در اﻧﺘﻬﺎ ﻧﻴﺰ ﻣﺘﺪ Invalidateرا در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ) (thisﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢ .ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ اﻳﻦ ﻣﺘﺪ در ﺣﻘﻴﻘﺖ ﺑﻪ ﺑﺮﻧﺎﻣـﻪ ﻣـﻲ ﮔﻮﻳﻴﻢ ﻛﻪ ﻗﺴﻤﺘﻲ از ﻇﺎﻫﺮ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﺗﻐﻴﻴﺮ ﻛﺮده اﺳﺖ و وﻳﻨﺪوز ﺑﺎﻳﺪ آن را ﻣﺠﺪداً رﺳﻢ ﻛﻨﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ وﻳﻨﺪوز ﻳﻚ ﻓﺮم را در ﺻـﻔﺤﻪ ﻧﻤﺎﻳﺶ داد ،ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻻزم ﻧﺒﺎﺷﺪ آن را ﻣﺠﺪداً رﺳﻢ ﻧﻤﻲ ﻛﻨﺪ .اﻳﻦ ﻛﻪ ﭼﻪ ﻫﻨﮕﺎم ﺑﺎﻳﺪ ﻳﻚ ﻛﻨﺘﺮل دوﺑﺎره رﺳﻢ ﺷﻮد ﺗﻮﺳﻂ ﺧﻮد وﻳﻨﺪوز ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﻣﺸﺨﺺ ﻣﻲ ﺷﻮد ،اﻣﺎ اﮔﺮ ﻻزم ﺑﺎﺷﺪ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ Invalidateﺑﻪ وﻳﻨﺪوز ﺑﮕﻮﻳﻴﻢ ﻛﻪ ﻓـﺮم را ﻣﺠﺪداً رﺳﻢ ﻛﻨﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ روش ﺑﻪ وﻳﻨﺪوز ﻣﻲ ﮔﻮﻳﻴﻢ ﻛﻪ ﻇﺎﻫﺮ ﻳﻜﻲ از ﻛﻨﺘﺮل ﻫﺎي ﻣﻮﺟـﻮد در ﻓـﺮم ﺑﺮﻧﺎﻣـﻪ ﺗﻐﻴﻴﺮ ﻛﺮده اﺳﺖ و ﺑﺎﻳﺪ ﻓﺮم را ﻣﺠﺪداً رﺳﻢ ﻛﻨﺪ. // Invalidate the control
٥٤٥
;)(this.Invalidate } ﻧﻜﺘﻪ :اﮔﺮ ﺑﺎ اﺳﺘﻔﺎده از ﻛﺪ ،ﻓﻘﻂ ﻇﺎﻫﺮ ﻳﻜﻲ از ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻓﺮم را ﺗﻐﻴﻴﺮ دادﻳﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﺘـﺪ Invalidateرا در آن ﻛﻨﺘﺮل ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ ﺗﺎ وﻳﻨﺪوز ﻓﻘﻂ آن ﻛﻨﺘﺮل را ﻣﺠﺪداً رﺳﻢ ﻛﻨﺪ. ﺧﻮب ،ﺗﺎﻛﻨﻮن زﻣﺎن ﺣﺮﻛﺖ ﻣﺎوس ﺑﺮ روي ﻓﺮم را ﺗﺸﺨﻴﺺ داده اﻳﻢ و در اﻳﻦ زﻣﺎن ﺑﺮ اﺳﺎس اﺑﺰاري ﻛﻪ ﻛﺎرﺑﺮ اﻧﺘﺨﺎب ﻛﺮده ﺑﻮد ،ﺷـﻴﺊ ﻣﻨﺎﺳﺒﻲ را اﻳﺠﺎد ﻛﺮده و آن را ﺑﻪ ﻟﻴﺴﺖ ﻧﻘﻄﻪ ﻫﺎي ﻧﻤﺎﻳﺶ دﻫﻨﺪه ي ﻓﺮم اﺿﺎﻓﻪ ﻛﺮدﻳﻢ .ﻫﻤﭽﻨﻴﻦ ﺑﻪ وﻳﻨﺪوز ﻧﻴﺰ اﻋﻼم ﻛﺮدﻳﻢ ﻛﻪ ﻃﺎﻫﺮ ﻓﺮم ﻣﺠﺪداً ﺑﺎﻳﺪ در ﺻﻔﺤﻪ رﺳﻢ ﺷﻮد ﺗﺎ ﺗﻐﻴﻴﺮات اﻳﺠﺎد ﺷﺪه ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ .ﺧﻮب ﻓﻜﺮ ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﭼﻪ ﻛﺎرﻫﺎي دﻳﮕﺮي را ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﻢ ﺗﺎ ﺑﺮﻧﺎﻣﻪ ﻛﺎﻣﻞ ﺷﻮد؟ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻓﺮم و ﻳﺎ ﻳﻚ ﻛﻨﺘﺮل درون ﻓﺮم ﺑﻪ ﺗﺮﺳﻴﻢ ﻣﺠﺪد ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﺪ ،ﺑﺎﻳﺪ اﺟﺎزه دﻫﻴﻢ ﻛﻪ وﻳﻨﺪوز ﺧﻮدش ﺗﺼﻤﻴﻢ ﺑﮕﻴﺮد ﻛﻪ ﭼﻪ زﻣﺎﻧﻲ ﺑﺎﻳﺪ ﻓﺮم را رﺳﻢ ﻛﻨﺪ .در ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ وﻳﻨﺪوز ﺑﺮاي اﻓﺰاﻳﺶ ﺳﺮﻋﺖ و ﻛﺎراﻳﻲ ،رﺳﻢ ﻛﻨﺘـﺮل ﻫـﺎ در ﺻـﻔﺤﻪ از اﻫﻤﻴـﺖ ﻛﻤـﻲ ﺑﺮﺧﻮردارﻧﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ وﻳﻨﺪوز زﻣﺎﻧﻲ اﻳﻦ ﻛﺎرﻫﺎ را اﻧﺠﺎم ﻣﻲ دﻫﺪ ﻛﻪ ﺑﻪ اﻧﺪازه ي ﻛﺎﻓﻲ وﻗﺖ آزاد داﺷﺘﻪ ﺑﺎﺷﺪ .رﺳﻢ ﻳﻚ ﻛﻨﺘﺮل و ﻳـﺎ ﻳـﻚ ﻓﺮم در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ از ﻧﻈﺮ وﻳﻨﺪوز ﻳﻚ ﻣﻮرد ﺣﻴﺎﺗﻲ و ﺿﺮوري ﺗﻠﻘﻲ ﻧﻤﻲ ﺷﻮد ،ﺑﻨﺎﺑﺮاﻳﻦ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ از ﺳﻴـﺴﺘﻢ ﻋﺎﻣـﻞ اﻧﺘﻈـﺎر داﺷـﺘﻪ ﺑﺎﺷﻴﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻓﺮم را ﺑﻪ ﺻﻮرت ﻧﺎ ﻣﻌﺘﺒﺮ ﻣﺸﺨﺺ ﻛﺮدﻳﺪ ،وﻳﻨﺪوز ﺑﻪ ﺳﺮﻋﺖ آن را ﻣﺠﺪداً در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ رﺳﻢ ﻛﻨﺪ .اﺣﺘﻤـﺎﻻً اﻳﻦ ﻣﻮرد را در ﻫﻨﮕﺎم ﻛﺎر ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎ زﻳﺎد ﻣﺸﺎﻫﺪه ﻛﺮده اﻳﺪ ﻛﻪ اﮔﺮ وﻳﻨﺪوز در ﺣﺎل اﻧﺠﺎم ﻓﻌﺎﻟﻴﺖ ﺳﻨﮕﻴﻨﻲ در ﻓﺮم ﺑﺎﺷﺪ ،ﭘﻨﺠﺮه ي ﻓـﺮم ﺑﻪ ﺻﻮرت ﻳﺦ زده ﺷﺪه و ﻫﻴﭻ ﭼﻴﺰ ﻧﻤﺎﻳﺶ داده ﻧﻤﻲ ﺷﻮﻧﺪ. ﺑﻨﺎﺑﺮاﻳﻦ ﻧﺒﺎﻳﺪ ﻫﻴﭻ ﻣﻮﻗﻊ وﻳﻨﺪوز را ﻣﺠﺒﻮر ﻛﻨﻴﺪ ﻛﻪ ﻓﺮم ﺷﻤﺎ را ﺑﻪ ﺳﺮﻋﺖ در ﺻﻔﺤﻪ رﺳﻢ ﻛﻨﺪ .در اﻳﻦ ﺳﻴـﺴﺘﻢ ﻋﺎﻣـﻞ ﺑـﻴﺶ از ﭼﻨـﺪﻳﻦ ﻫﺰار ﺧﻂ ﻛﺪ وﺟﻮد دارﻧﺪ ﻛﻪ ﺑﻬﺘﺮﻳﻦ زﻣﺎن ﺑﺮاي رﺳﻢ ﻣﺠﺪد ﻳﻚ ﻛﻨﺘﺮل در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻨﺪ .ﺑﻨـﺎﺑﺮاﻳﻦ ﻓﻘـﻂ ﻛـﺎﻓﻲ اﺳﺖ ﻛﻨﺘﺮﻟﻲ ﻛﻪ ﻧﻴﺎز ﺑﻪ ﺗﺮﺳﻴﻢ ﻣﺠﺪد دارد را ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ Invalidateﻣﺸﺨﺺ ﻛﻨﻴﺪ و ﺳﭙﺲ اﺟﺎزه دﻫﻴﺪ ﻛﻪ وﻳﻨﺪوز در اوﻟﻴﻦ ﻓﺮﺻﺖ ﻣﻤﻜﻦ آن را ﻣﺠﺪداً رﺳﻢ ﻛﻨﺪ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ وﻳﻨﺪوز ﺑﺨﻮاﻫﺪ ﻳﻚ ﻓﺮم و ﻳﺎ ﻳﻚ ﻛﻨﺘـﺮل را ﻣﺠـﺪداً در ﺻـﻔﺤﻪ ﻧﻤـﺎﻳﺶ رﺳـﻢ ﻛﻨـﺪ ،روﻳـﺪاد Paintرا در آن ﻛﻨﺘـﺮل ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ ﻣﺘﺪي را اﻳﺠﺎد ﻛﻨﻴﻢ ﺗﺎ ﻫﻨﮕﺎم رخ دادن اﻳﻦ روﻳﺪاد اﻳﻦ ﻣﺘﺪ اﺟﺮا ﺷﺪه و ﻛﻨﺘﺮل ﻣﻮرد ﻧﻈﺮ ﻣـﺎ را در ﻓـﺮم رﺳﻢ ﻛﻨﺪ .در اﻳﻦ ﻣﺘﺪ ﻧﻴﺰ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ Drawاز ﺗﻚ ﺗﻚ ﻧﻘﻄﻪ ﻫـﺎي ﻣﻮﺟـﻮد در ﻓـﺮم ﺑﺨـﻮاﻫﻴﻢ ﻛـﻪ ﺧـﻮد را در ﺻﻔﺤﻪ رﺳﻢ ﻛﻨﻨﺪ .ﭘﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﺣﻠﻘﻪ ي foreachﺑﻴﻦ ﺗﻤﺎم ﻧﻘﻄﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻟﻴﺴﺖ ﺣﺮﻛﺖ ﻛﺮده و ﻣﺘـﺪ Draw را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢ. private void PaintCanvas_Paint(object sender, )PaintEventArgs e { // Go through the list foreach (GraphicsItem objGraphicsItem in )GraphicsItems { // Ask each item to draw itself ;)objGraphicsItem.Draw(e.Graphics } } ﻫﻨﮕﺎﻣﻲ ﻛﻪ وﻳﻨﺪوز روﻳﺪاد Paintرا ﻓﺮاﺧﻮاﻧﻲ ﻛﺮد ،اﻃﻼﻋﺎت ﻻزم در راﺑﻄﻪ ﺑﺎ رخ دادن اﻳـﻦ روﻳـﺪاد را ﺑـﺎ اﺳـﺘﻔﺎده از ﺷـﻴﺊ اي از ﻛﻼس PaintEventArgsﺑﻪ ﻣﺘﺪ ﻫﺎ ﻣﻲ ﻓﺮﺳﺘﺪ .اﻳﻦ ﺷﻴﺊ ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي ﻓﺮاواﻧـﻲ دارد و ﻳﻜـﻲ از آﻧﻬـﺎ ﺧﺎﺻـﻴﺖ ٥٤٦
Graphicsاﺳﺖ ﻛﻪ ﺷﻴﺊ اي را از ﻧﻮع System.Drawing.Graphicsﺑﺮﻣﻲ ﮔﺮداﻧﺪ .اﻳﻦ ﺷﻴﺊ ﺷـﺎﻣﻞ ﻣﺘـﺪ ﻫﺎ و ﺗﻮاﺑﻊ زﻳﺎدي اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺮاي ﺗﺮﺳﻴﻢ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد ،ﺑﻨﺎﺑﺮاﻳﻦ اﻳﻦ ﺷﻴﺊ را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑـﻪ ﻣﺘـﺪ Drawﻣـﻲ ﻓﺮﺳﺘﻴﻢ ﺗﺎ در ﺻﻮرت ﻧﻴﺎز ﺑﺘﻮاﻧﺪ از آن اﺳﺘﻔﺎده ﻛﻨﺪ. ﺣﺎل ﻛﻪ ﺗﻘﺮﻳﺒﺎً ﺑﺎ ﻧﺤﻮه ي ﻛﺎرﻛﺮد اﻳﻦ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ آﺷﻨﺎ ﺷﺪﻳﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﻋﻠﺖ ﻛﻨﺪ ﺷﺪن ﺑﺮﻧﺎﻣﻪ و ﭼـﺸﻤﻚ زدن آن ﻫﻨﮕـﺎم رﺳـﻢ ﻳﻚ ﺷﻜﻞ در ﻓﺮم را ﺑﺮرﺳﻲ ﻛﺮده و آن را رﻓﻊ ﻛﻨﻴﻢ.
ﻧﺎ ﻣﻌﺘﺒﺮ ﺳﺎزي: ﻛﺪي ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ وارد ﻛﺮدﻳﻢ ﻛﺎﻣﻼً درﺳﺖ ﻛﺎر ﻣﻲ ﻛﻨﺪ ،اﻣﺎ اﮔﺮ ﻣﻘﺪاري ﺷﻜﻞ در ﺻﻔﺤﻪ رﺳﻢ ﻛﻨﻴﻢ ﺳﺮﻋﺖ ﺑﺮﻧﺎﻣﻪ ﻛﺎﻫﺶ ﭘﻴـﺪا ﻛﺮده و ﺑﺮﻧﺎﻣﻪ ﺷﺮوع ﺑﻪ ﭼﺸﻤﻚ زدن ﺧﻮاﻫﺪ ﻛﺮد .دﻟﻴﻞ آن ﻧﻴﺰ اﻳﻦ اﺳﺖ ﻛﻪ ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﻧﻜﺎت ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ را در ﻧﻈﺮ ﻧﮕﺮﻓﺘﻴﻢ :ﺣﺠﻢ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ اﻧﺠﺎم ﺷﻮد را ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﻛﺎﻫﺶ دﻫـﻴﻢ .رﺳـﻢ ﻣﺠـﺪد ﻳـﻚ ﻛﻨﺘـﺮل در ﺻـﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻛﺎري اﺳﺖ ﻛﻪ ﺑﻪ ﻛﻨﺪي اﻧﺠﺎم ﻣﻲ ﺷﻮد .ﻫﺮ ﭼﻪ ﻣﺤﺪوده اي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺗﺮﺳﻴﻢ ﻛﻨﻴﻢ ﻛـﻮﭼﻜﺘﺮ ﺑﺎﺷـﺪ ،ﺳـﺮﻋﺖ ﺗﺮﺳـﻴﻢ آن ﻧﺎﺣﻴﻪ ﺑﻴﺸﺘﺮ ﺧﻮاﻫﺪ ﺑﻮد و ﻇﺎﻫﺮ ﺑﺮﻧﺎﻣﻪ ﺳﺮﻳﻌﺘﺮ ﺗﺮﺳﻴﻢ ﻣﻲ ﺷﻮد. ﻋﻠﺖ ﭼﺸﻤﻚ زدن ﻓﺮم ﺑﺮﻧﺎﻣﻪ در اﻳﻦ اﺳﺖ ﻛﻪ ﺗﺮﺳﻴﻢ ﻛﻨﺘﺮل ﺗﻮﺳﻂ وﻳﻨﺪوز ﻃﻲ دو ﻣﺮﺣﻠﻪ اﻧﺠﺎم ﻣﻲ ﺷﻮد .اﺑﺘﺪا وﻳﻨـﺪوز ﺗﻤـﺎم ﻣﺤـﺪوده اي ﻛﻪ ﺑﺎﻳﺪ دوﺑﺎره رﺳﻢ ﺷﻮﻧﺪ را ﭘﺎك ﻣﻲ ﻛﻨﺪ ،ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ آن ﻧﺎﺣﻴﻪ ﺑﻪ رﻧﮓ ﺳﻔﻴﺪ درﺧﻮاﻫﺪ آﻣﺪ .ﺳﭙﺲ ﺑﻪ ﺷﻤﺎ اﺟﺎزه داده ﻣـﻲ ﺷـﻮد ﻛﻪ آن ﻗﺴﻤﺖ را ﻣﺠﺪداً ﺗﺮﺳﻴﻢ ﻛﻨﻴﺪ. در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ Invalidateدر ﻓﺮم ،از وﻳﻨﺪوز ﻣﻲ ﺧﻮاﻫﻴﺪ ﻛﻪ ﺗﻤﺎم ﻓﺮم را ﻣﺠﺪداً رﺳﻢ ﻛﻨﺪ ،اﻣﺎ ﻻزم ﺑـﻪ اﻳـﻦ ﻛﺎر ﻧﻴﺴﺖ و ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ اﻳﻦ ﻣﺘﺪ در ﻗﺴﻤﺘﻲ ﻛﻪ ﻧﻘﻄﻪ ي ﺟﺪﻳﺪ ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ ،از وﻳﻨﺪوز ﺑﺨﻮاﻫﻴﺪ ﻛﻪ ﻓﻘـﻂ آن ﻣﺤـﺪوده را ﻣﺠﺪداً رﺳﻢ ﻛﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻧﺎﺣﻴﻪ ي ﻛﻮﭼﻜﺘﺮي ﻧﻴﺎز ﺑﻪ ﺗﺮﺳﻴﻢ ﻣﺠﺪد ﺧﻮاﻫﺪ داﺷﺖ و ﺳﺮﻋﺖ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ اﻓﺰاﻳﺶ ﭘﻴﺪا ﺧﻮاﻫﺪ ﻛﺮد. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻛﺎر را ﺑﺎ ﻫﻢ ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻧﺎ ﻣﻌﺘﺒﺮ ﺳﺎزي ﻳﻚ ﻣﺤﺪوده ي ﻣﺸﺨﺺ (1در ﻛﻼس PaintCanvasﻣﺘﺪ DoMousePaintرا ﭘﻴﺪا ﻛﺮده و ﻓﺮاﺧﻮاﻧﻲ ﻣﺘـﺪ Invalidateرا ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ ﻓﻘﻂ ﻧﺎﺣﻴﻪ ي ﻣﺸﺨﺺ ﺷﺪه ﺗﻮﺳﻂ ﻣﺴﺘﻄﻴﻞ ﻣﻮﺟﻮد در ﺷﻴﺊ objGraphicsItem ﻣﺠﺪد رﺳﻢ ﺷﻮد: // Invalidate the control ;)this.Invalidate(objGraphicsItem.rectangle (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻫﻨﮕﺎم رﺳﻢ ﺷﻜﻞ ،ﻫﺮ ﭼﻪ ﻗﺪر ﻫﻢ ﻛﻪ ﺷﻜﻞ ﺑﺰرگ ﺷﻮد ﻓﺮم ﭼـﺸﻤﻚ ﻧﺨﻮاﻫـﺪ زد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟
٥٤٧
ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺘﺪ SetPointدر ﺷﻴﺊ اﻳﺠﺎد ﺷﺪه از ﻛﻼس GraphicsCircleرا ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﺪ ،اﻳﻦ ﻣﺘﺪ ﻣﻘـﺪار ﻓﻴﻠﺪ rectangleرا ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﺣﺎوي ﻣﺤﺪوده ي ﻗﺮارﮔﻴﺮي ﻧﻘﻄﻪ ي ﺟﺪﻳﺪ اﻳﺠﺎد ﺷﺪه ﺑﺎﺷﺪ. در اﻳﻦ ﻗﺴﻤﺖ ﻫﻨﮕﺎم ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ this.Invalidateﻣﺴﺘﻄﻴﻞ ﻣﻮﺟﻮد در اﻳﻦ ﻓﻴﻠﺪ را ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻣﻲ ﻓﺮﺳﺘﻴﺪ و ﺑﻪ اﻳـﻦ ﺗﺮﺗﻴﺐ ﺑﺮاي ﻣﺘﺪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻓﻘﻂ اﻳﻦ ﻗﺴﻤﺖ از ﻓﺮم ﻣﺠﺪداً ﺑﺎﻳﺪ ﺗﺮﺳﻴﻢ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ وﻳﻨﺪوز ﻫﻢ ﻓﻘﻂ اﻳﻦ ﻗﺴﻤﺖ از ﻓـﺮم را ﭘﺎك ﻣﻲ ﻛﻨﺪ و ﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣﻲ دﻫﺪ ﺗﺎ آن را رﺳﻢ ﻛﻨﻴﺪ.
ﺑﻬﻴﻨﻪ ﺳﺎزي ﻛﺮدن رﺳﻢ: اﮔﺮ ﻫﻨﮕﺎم ﻛﺎر ﺑﺎ ﺑﺮﻧﺎﻣﻪ دﻗﺖ ﻛﺮده ﺑﺎﺷﻴﺪ ﻣﺘﻮﺟﻪ ﻣﻲ ﺷﻮﻳﺪ ﻛﻪ ﺑﻌﺪ از اﻳﻨﻜﻪ ﻣﻘﺪاري از ﺷﻜﻞ را در ﻓﺮم رﺳﻢ ﻛﺮدﻳﺪ ،ﻧﻘﻄﻪ ﻫـﺎﻳﻲ ﻛـﻪ در ﻓﺮم ﻗﺮار ﻣﻲ دﻫﻴﺪ ﺑﻪ ﺻﻮرت ﻧﺎﻫﻤﻮار رﺳﻢ ﻣﻲ ﺷﻮﻧﺪ .ﺑﺮاي ﻋﻠﺖ اﻳﻦ ﻣﺸﻜﻞ ﺑﺎﻳﺪ ﺑﮕﻮﻳﻴﻢ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﺷﻜﻞ ﺑـﺰرگ ﻣـﻲ ﺷـﻮد ،در ﺣﻘﻴﻘﺖ ﻧﻘﺎﻃﻲ ﻛﻪ آن را ﺗﺸﻜﻴﻞ ﻣﻲ دﻫﻨﺪ زﻳﺎدﺗﺮ ﻣﻲ ﺷﻮﻧﺪ ﺑﻨﺎﺑﺮاﻳﻦ رﺳﻢ ﺗﻤﺎم اﻳﻦ ﻧﻘﺎط در ﻓﺮم ﻣﺪت زﻣﺎن ﺑﻴﺸﺘﺮي ﻃـﻮل ﻣـﻲ ﻛـﺸﺪ. ﻫﺮﭼﻪ ﻗﺪر ﻫﻢ ﻛﻪ ﻣﺪت زﻣﺎن رﺳﻢ اﻳﻦ ﻧﻘﺎط در ﻓـﺮم ﻃـﻮﻻﻧﻲ ﺗـﺮ ﺷـﻮد ،ﻫﻨﮕـﺎم ﺣﺮﻛـﺖ ﻣـﺎوس در ﺻـﻔﺤﻪ ﺗﻌـﺪادي از روﻳـﺪادﻫﺎي MouseMoveﻧﻤﻲ ﺗﻮاﻧﻨﺪ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮﻧﺪ و ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎم ﻋﺒﻮر ﻣﺎوس از آن ﻗﺴﻤﺖ از ﻓﺮم ﻧﻘﻄﻪ اي در ﺻﻔﺤﻪ رﺳﻢ ﻧﻤﻲ ﺷﻮد و ﺷﻜﻞ ﺑﻪ ﺻﻮرت ﻧﺎﻫﻤﻮار در ﻣﻲ آﻳﺪ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﻧﺤﻮه ي ﺣﻞ اﻳﻦ ﻣﺸﻜﻞ را ﺑﺎ ﻫﻢ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺑﻬﻴﻨﻪ ﺳﺎزي رﺳﻢ (1ﻣﺘﺪ PaintCanvas_Paintدر ﻛﻼس PaintCanvasرا ﭘﻴﺪا ﻛﺮده و ﻛﺪ ﻣﺸﺨﺺ ﺷـﺪه در زﻳـﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void PaintCanvas_Paint(object sender, )PaintEventArgs e { // Go through the list foreach (GraphicsItem objGraphicsItem )in GraphicsItems (if (e.ClipRectangle.IntersectsWith ) )objGraphicsItem.rectangle // Ask each item to draw itself ;)objGraphicsItem.Draw(e.Graphics } (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺷﻜﻠﻲ را در ﻓﺮم رﺳﻢ ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺷﻜﻞ ﺑﺴﻴﺎر ﻧﺮﻣﺘﺮ رﺳﻢ ﺧﻮاﻫﺪ ﺷﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟
٥٤٨
ﻛﻼس PaintEventArgsﺣﺎوي ﺧﺎﺻﻴﺘﻲ ﺑﻪ ﻧﺎم ClipRectangleاﺳﺖ ﻛـﻪ اﻃﻼﻋـﺎت ﻳـﻚ ﻣـﺴﺘﻄﻴﻞ را در ﺧﻮد ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ .اﻳﻦ ﻣﺴﺘﻄﻴﻞ ﻣﺤﺪوده اي از ﻓﺮم ﻛﻪ از ﻧﻮع ﻧﺎ ﻣﻌﺘﺒﺮ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ را ﻣﻌﻴﻦ ﻣﻲ ﻛﻨﺪ ،ﻛﻪ اﻳﻦ ﻣﺤـﺪوده ﺑـﻪ ﻧﺎم ﻣﺴﺘﻄﻴﻞ ﭼﻴﺪه ﺷﺪه 1ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮد .ﻛﻼس Rectangleﻧﻴﺰ داراي ﻣﺘـﺪي ﺑـﻪ ﻧـﺎم IntersectsWith اﺳﺖ ﻛﻪ ﻳﻚ ﻣﻘﺪار ﺑﻮﻟﻴﻦ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ و اﻳﻦ ﻣﻘﺪار ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ آﻳﺎ دو ﻣﺴﺘﻄﻴﻞ ﻫﻤﭙﻮﺷﺎﻧﻲ دارﻧﺪ ﻳﺎ ﻧـﻪ )رو ﻫـﻢ ﻗـﺮار ﻣـﻲ ﮔﻴﺮﻧﺪ ﻳﺎ ﻧﻪ(؟ ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﻢ در اﻳﻦ ﺣﻠﻘﻪ ،ﻣﺴﺘﻄﻴﻞ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ي ﻣﺤﺪوده ي ﺗـﻚ ﺗـﻚ ﻋﻨﺎﺻـﺮ ﻣﻮﺟـﻮد در ﻟﻴـﺴﺖ را ﺑـﺎ ﻣـﺴﺘﻄﻴﻞ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ي ﻣﺤﺪوده ي ﻋﻨﺼﺮ ﻛﻨﻮﻧﻲ ﻛﻪ ﺑﺎﻳﺪ رﺳﻢ ﺷﻮد ،ﻣﻘﺎﻳﺴﻪ ﻛﺮده و ﺑﺒﻴﻨﻴﻢ ﻛﻪ ﻫﻤﭙﻮﺷﺎﻧﻲ دارﻧﺪ ﻳﺎ ﻧﻪ .در ﺻﻮرﺗﻲ ﻛﻪ اﻳﻦ دو ﻣﺴﺘﻄﻴﻞ ﻫﻤﭙﻮﺷﺎﻧﻲ داﺷﺘﻪ ﺑﺎﺷﺪ ﻻزم اﺳﺖ ﻛﻪ آن را در ﻓﺮم رﺳﻢ ﻛﻨﻴﻢ و در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻣﻲ ﺗـﻮاﻧﻴﻢ ﻧﻘﻄـﻪ ي ﺑﻌـﺪي در ﻟﻴـﺴﺖ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ. دو ﺗﻜﻨﻴﻜﻲ ﻛﻪ ﺑﺮاي ﺑﻬﺒﻮد ﺑﺮﻧﺎﻣﻪ در اﻳﻦ ﻗﺴﻤﺖ اﺳﺘﻔﺎده ﻛﺮدﻳﻢ )رﺳﻢ ﻧﺎﺣﻴﻪ اي ﻛﻪ ﻻزم اﺳﺖ ﺗﺮﺳﻴﻢ ﺷﻮد ﺑﻪ ﺟﺎي رﺳـﻢ ﺗﻤـﺎم ﻓـﺮم و ﻧﻴﺰ رﺳﻢ ﻧﻘﻄﻪ اي ﻛﻪ ﺟﺪﻳﺪاً اﻳﺠﺎد ﺷﺪه اﺳﺖ ﺑﻪ ﺟﺎي رﺳﻢ ﺗﻤﺎم ﻧﻘﺎط( دو ﻧﻜﺘﻪ ي ﺑـﺴﻴﺎر ﻣﻬـﻢ در ﻧﻮﺷـﺘﻦ ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ ي ﮔﺮاﻓﻴﻜـﻲ ﻣﺤﺴﻮب ﻣﻲ ﺷﻮﻧﺪ وﺑﺎ ﺣﺬف ﻫﺮ ﻳﻚ از آﻧﻬﺎ از ﺑﺮﻧﺎﻣﻪ ،ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ راﺣﺘﻲ ﺷﻜﻠﻲ را در ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﻨﻴﺪ.
اﻧﺘﺨﺎب رﻧﮓ: ﺣﺎل ﻛﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺳﺎده ي ﻧﻘﺎﺷﻲ اﻳﺠﺎد ﻛﺮدﻳﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﻛﻨﺘﺮﻟﻲ ﺑﺴﺎزﻳﻢ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آن ﺑﺘﻮاﻧﻴﻢ رﻧـﮓ اﺑـﺰار ﻣـﻮرد اﺳـﺘﻔﺎده ﺑﺮاي ﺗﺮﺳﻴﻢ در ﻓﺮم را ﻧﻴﺰ ﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﻣﺎﻧﻨﺪ ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﮔﺮاﻓﻴﻜﻲ ﻳﻚ ﭘﺎﻟﺖ رﻧﮓ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد و ﺑﻪ وﺳﻴﻠﻪ ي آن ﭘﺎﻟـﺖ، در ﻫﺮ ﻟﺤﻈﻪ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻣﻲ دﻫﻴﻢ دو رﻧﮓ را اﻧﺘﺨﺎب ﻛﻨﺪ :ﻳﻚ رﻧﮓ ﺑﺮاي ﻛﻠﻴﻚ ﭼﭗ ﻣﺎوس و رﻧـﮓ دﻳﮕـﺮ ﺑـﺮاي ﻛﻠﻴـﻚ راﺳـﺖ ﻣﺎوس. ﺑﺮاي اﻳﺠﺎد اﻳﻦ ﻛﻨﺘﺮل روﺷﻬﺎي زﻳﺎدي وﺟﻮد دارﻧﺪ ،اﻣﺎ ﻣﻨﻄﻘﻲ ﺗﺮﻳﻦ و ﺳﺎده ﺗﺮﻳﻦ روش اﻳﻦ اﺳﺖ ﻛﻪ ﻛﻨﺘﺮﻟـﻲ ﺣـﺎوي ﭼﻨـﺪﻳﻦ ﻛﻨﺘـﺮل ﺷﺒﻴﻪ Buttonاﻳﺠﺎد ﻛﻨﻴﻢ .ﺳﭙﺲ رﻧﮓ ﭘﺲ زﻣﻴﻨﻪ ي ﻫﺮ ﻳﻚ از اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ را ﺑﺮاﺑﺮ ﺑﺎ ﻳﻜﻲ از رﻧﮕﻬﺎي ﻣﻮرد ﻧﻈﺮ در ﭘﺎﻟﺖ رﻧﮓ ﻗﺮار دﻫﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺎ ﻛﻠﻴﻚ روي ﻫﺮ ﻛﺪام از اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﻳﻚ رﻧﮓ را اﻧﺘﺨﺎب ﻛﺮده و از آن ﺑﺮاي رﺳـﻢ ﺷـﻜﻞ اﺳﺘﻔﺎده ﻛﻨﺪ .در ﻗﺴﻤﺖ ﺑﻌﺪ ،ﻧﺤﻮه ي اﻳﺠﺎد ﭼﻨﻴﻦ ﻛﻨﺘﺮﻟﻲ را از ﭘﺎﻳﻪ ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻳﺠﺎد ﻛﻨﺘﺮل :ColorPalette ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﻳﻚ ﻛﻨﺘﺮل ﺑﺮاي ﭘﺎﻟﺖ رﻧﮓ در ﺑﺮﻧﺎﻣﻪ ﺑﺴﺎزﻳﻢ ،ﺑﺎﻳﺪ دو ﻛـﻼس اﻳﺠـﺎد ﻛﻨـﻴﻢ .ﻛـﻼس اول ،ﻛﻼﺳـﻲ اﺳـﺖ ﺑـﻪ ﻧـﺎم ColorPaletteﻛﻪ از ﻛﻼس UserControlﻣﺸﺘﻖ ﻣﻲ ﺷﻮد .اﻳﻦ ﻛﻼس ﺑﺮاي ﺗﺮﺳﻴﻢ راﺑﻂ ﮔﺮاﻓﻴﻜﻲ ﻛﻨﺘﺮل ﭘﺎﻟﺖ رﻧﮓ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد .ﻛﻼس دوم ﻧﻴﺰ ﻛﻼﺳﻲ ﺑـﻪ ﻧـﺎم ColorPaletteButtonاﺳـﺖ ﻛـﻪ ﺑـﺮاي ﻧﻤـﺎﻳﺶ رﻧﮕﻬﺎي ﻣﻮﺟﻮد در ﭘﺎﻟﺖ ﺑﻪ ﻛﺎر ﻣﻲ رود. در اﻳﺠﺎد ﭘﺎﻟﺖ رﻧﮓ ،ﻇﺎﻫﺮ و ﻣﻜﺎن ﻗﺮارﮔﻴﺮي دﻛﻤﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي اﻧﺘﺨﺎب رﻧﮓ در ﺻﻔﺤﻪ ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ را ﺑﺎﻳﺪ ﺧﻮدﻣـﺎن ﻣـﺸﺨﺺ ﻛﻨﻴﻢ و ﻫﻤﭽﻨﻴﻦ ﺑﺎﻳﺪ اﻳﻦ ﻇﺎﻫﺮ را ﻫﻨﮕﺎم ﺗﻐﻴﻴﺮ اﻧﺪازه ي ﻛﻨﺘﺮل ﻧﻴﺰ ﺣﻔﻆ ﻛﻨﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﺘﺪي اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻫﻨﮕﺎم رخ دادن روﻳﺪاد Resizeﻓﺮاﺧﻮاﻧﻲ ﺷﻮد و ﻣﻜﺎن ﻗﺮارﮔﻴﺮي رﻧﮕﻬﺎ در ﻛﻨﺘﺮل ﭘﺎﻟﺖ رﻧﮓ را ﺗﻨﻈﻴﻢ ﻛﻨﺪ.
Clipping Rectangle
1
٥٤٩
ﺑﺮاي اﻳﻦ ﻛـﺎر از ﺑـﺎﻻ ﺳـﻤﺖ. ﺑﺎﻳﺪ ﻣﻜﺎن ﻗﺮارﮔﻴﺮي ﻫﺮ رﻧﮓ را در ﭘﺎﻟﺖ ﻣﺸﺨﺺ ﻛﻨﻴﺪ، ﻓﺮاﺧﻮاﻧﻲ ﺷﺪResize ﻫﻨﮕﺎﻣﻲ ﻛﻪ روﻳﺪاد ﺑﻪ ﺳﻄﺮ ﺑﻌـﺪ، ﺳﭙﺲ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﻪ اﻧﺘﻬﺎي ﻳﻚ ﺳﻄﺮ رﺳﻴﺪﻳﺪ.ﭼﭗ ﻛﻨﺘﺮل ﺷﺮوع ﻣﻲ ﻛﻨﻴﺪ و ﻳﻜﻲ ﻳﻜﻲ رﻧﮕﻬﺎ را در ﭘﺎﻟﺖ ﻗﺮار ﻣﻲ دﻫﻴﺪ .رﻓﺘﻪ و رﻧﮕﻬﺎ را در ﺳﻄﺮ ﺟﺪﻳﺪ ﻗﺮار ﻣﻲ دﻫﻴﺪ
ColorPalette اﻳﺠﺎد ﻛﻨﺘﺮل:اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﻛــــــﻼس ﺟﺪﻳــــــﺪي ﺑــــــﻪ ﻧــــــﺎمSolutionExplorer ( ﺑــــــﺎ اﺳــــــﺘﻔﺎده از ﭘﻨﺠــــــﺮه ي1 ﻓﻀﺎي، ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮده و ﺳﭙﺲ ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ﻛﺪ زﻳﺮ ﺑﻪ اﻳﻦ ﻛﻼسColorPaletteButton.cs : را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪSystem.Drawing ﻧﺎم using System.Drawing; :( ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳﻦ ﻛﻼس وارد ﻛﻨﻴﺪ2 public class ColorPaletteButton { // Publiuc members public Color color = System.Drawing.Color.Black; public Rectangle rectangle; // Constructor public ColorPaletteButton(Color objColor) { color = objColor; } // Move the button to the given position public void SetPosition(int x, int y, int buttonSize) { // Update the members rectangle = new Rectangle(x, y, buttonSize, buttonSize); } // Draw the button public void Draw(Graphics graphics) { // Draw the color block SolidBrush objSolidBrush = new SolidBrush(color); graphics.FillRectangle(objSolidBrush, rectangle); // Draw an edge around the control Pen objPen = new Pen(Color.Black);
٥٥٠
;)graphics.DrawRectangle(objPen, rectangle } } (3ﺣﺎل ﻳﻚ ﻛﻨﺘﺮل ﺳﻔﺎرﺷﻲ ﺑﻪ ﻧﺎم ColorPaletteﺑﻪ ﭘﺮوژه ي MyPaintاﺿﺎﻓﻪ ﻛﻨﻴـﺪ .در ﻗـﺴﻤﺖ ﻃﺮاﺣـﻲ ﻛﻨﺘﺮل ،روي اﻳﻦ ﻛﻨﺘﺮل ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﮔﺰﻳﻨﻪ ي View Codeرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ ﻛﺪ ﻣﺮﺑـﻮط ﺑـﻪ اﻳـﻦ ﻛﻨﺘـﺮل ﻧﻤﺎﻳﺶ داده ﺷﻮد .ﺳﭙﺲ ﻓﻴﻠﺪ ﻫﺎي زﻳﺮ را ﺑﻪ ﻛﻼس اﻳﻦ ﻛﻨﺘﺮل اﺿﺎﻓﻪ ﻛﻨﻴﺪ: // Public members ;)(public ArrayList Buttons = new ArrayList ;public int ButtonSize = 15 ;public int ButtonSpacing = 5 ;public Color LeftColor = Color.Black ;public Color RightColor = Color.White اﻳﻦ ﻓﻴﻠﺪ ﻫﺎ ﺑﺮاي ﻣﻮارد زﻳﺮ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ:
ﻟﻴﺴﺖ Buttonsﻟﻴﺴﺘﻲ از دﻛﻤﻪ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ رﻧﮕﻬﺎي درون ﭘﺎﻟﺖ را ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ. ButtonSizeاﻧﺪازه ي ﻫﺮ دﻛﻤﻪ را در ﭘﺎﻟﺖ رﻧﮓ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ. ButtonSpacingﻓﻀﺎي ﺧﺎﻟﻲ ﺑﻴﻦ ﻫﺮ ﻳﻚ از دﻛﻤﻪ ﻫﺎ را در ﭘﺎﻟﺖ رﻧﮓ ﺗﻌﻴﻴﻦ ﻣﻲ ﻛﻨﺪ. LeftColorرﻧﮕﻲ ﻛﻪ ﻫﻢ اﻛﻨﻮن ﺑﺮاي ﻛﻠﻴﺪ ﭼﭗ ﻣﺎوس در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ را ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ. RightColorرﻧﮕﻲ ﻛﻪ ﻫﻢ اﻛﻨﻮن ﺑﺮاي ﻛﻠﻴﺪ راﺳﺖ ﻣﺎوس در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه اﺳـﺖ را ﻧﮕﻬـﺪاري ﻣـﻲ ﻛﻨﺪ.
(4ﺣﺎل ﻣﺘﺪ زﻳﺮ را ﻧﻴﺰ ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ: Add a new color button to the control )public void AddColor(Color newColor { // Create the button ColorPaletteButton objColorPaletteButton = new ;)ColorPaletteButton(newColor // Add it to the list ;)Buttons.Add(objColorPaletteButton } (5ﻣﻲ ﺧﻮاﻫﻴﻢ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﻨﺘﺮل اﻳﺠﺎد ﻣﻲ ﺷﻮد ﭼﻨﺪ رﻧﮓ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض در آن وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ ،ﺑﻨـﺎﺑﺮاﻳﻦ ﻛـﺪي را درون ﻣﺘﺪ ﺳﺎزﻧﺪه ي آن ﻗﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ ﻫﻨﮕﺎم اﻳﺠﺎد ﻛﻨﺘﺮل ده رﻧﮓ اﺑﺘﺪاﻳﻲ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺪ زﻳـﺮ را ﺑﻪ ﻣﺘﺪ ﺳﺎزﻧﺪه ي ﻛﻼس ColorPaletteاﺿﺎﻓﻪ ﻛﻨﻴﺪ: )(public ColorPalette { ٥٥١
InitializeComponent(); // Add the colors AddColor(Color.Black); AddColor(Color.White); AddColor(Color.Red); AddColor(Color.Blue); AddColor(Color.Green); AddColor(Color.Gray); AddColor(Color.DarkRed); AddColor(Color.DarkBlue); AddColor(Color.DarkGreen); AddColor(Color.DarkGray); } ﺳـﭙﺲ ﺑـﺎ. ﺑﺮﮔﺸﺘﻪ و روي ﺧﻮد ﻛﻨﺘﺮل ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗـﺎ اﻧﺘﺨـﺎب ﺷـﻮدColorPalette ( ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻛﻨﺘﺮل6 از اﻳـﻦ. ﻟﻴﺴﺖ روﻳﺪادﻫﺎي ﻛﻨﺘـﺮل را ﻧﻤـﺎﻳﺶ دﻫﻴـﺪ،Properties در ﭘﻨﺠﺮه يEvents ﻛﻠﻴﻚ روي آﻳﻜﻮن ﺳﭙﺲ ﻛـﺪ، را اﻧﺘﺨﺎب ﻛﺮده و روي آن دوﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد اﻳﺠﺎد ﺷﻮدResize ﻟﻴﺴﺖ روﻳﺪاد :زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ private void ColorPalette_Resize(object sender, EventArgs e) { // Declare variables to hold the position int intX = 0; int intY = 0; // Go through the array and position the buttons foreach (ColorPaletteButton objColorPaletteButton in Buttons) { // Position the button objColorPaletteButton.SetPosition(intX, intY, ButtonSize); // Move to the next one intX += (ButtonSize + ButtonSpacing); // Do we need to go down to the next row if (intX + ButtonSize > Width) { // Move y intY += (ButtonSize + ButtonSpacing); // Reset x intX = 0;
٥٥٢
} } // Redraw ;)(this.Invalidate } (7ﻣﺠﺪداً ﺑﻪ ﻟﻴﺴﺖ روﻳﺪادﻫﺎ در ﭘﻨﺠﺮه ي Propertiesﺑﺮﮔﺮدﻳﺪ و روﻳﺪاد Paintرا اﻧﺘﺨﺎب ﻛﺮده روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void ColorPalette_Paint(object sender, )PaintEventArgs e { // Loop through the buttons foreach (ColorPaletteButton objColorPaletteButton )in Buttons ?// Do we need to draw (if (e.ClipRectangle.IntersectsWith ))objColorPaletteButton.rectangle ;)objColorPaletteButton.Draw(e.Graphics } (8 (9
(10
(11
(12
ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﺪ از ﻛﻨﺘﺮل اﻳﺠﺎد ﺷﺪه در ﻓﺮم اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ﺑﺎﻳﺪ ﻳﻚ ﺑﺎر ﭘﺮوژه را ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﻴﺪ .ﺑﺎ اﺳـﺘﻔﺎده از ﻧﻮار ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﮔﺰﻳﻨﻪ ي Build Buildرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ ﺑﺮﻧﺎﻣﻪ ﻛﺎﻣﭙﺎﻳﻞ ﺷﻮد. ﺑﻌــﺪ از اﻳﻨﻜــﻪ ﺑﺮﻧﺎﻣــﻪ ﻛﺎﻣﭙﺎﻳــﻞ ﺷــﺪ ،ﺑــﻪ ﻗــﺴﻤﺖ ﻃﺮاﺣــﻲ ﻓــﺮم ﻣﺮﺑــﻮط ﺑــﻪ Form1ﺑﺮوﻳــﺪ .در اﻳــﻦ ﻓــﺮم ﻛﻨﺘــﺮل PaintCanvasرا اﻧﺘﺨﺎب ﻛﺮده و ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي Propertiesﻣﻘﺪار ﺧﺎﺻﻴﺖ Dockآن را ﺑـﻪ Noneﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺣﺎل ﭘﻨﺠﺮه ي ﻓﺮم را ﻣﻘﺪاري ﺑﺰرﮔﺘﺮ ﻛﻨﻴﺪ ﺗﺎ ﻓﻀﺎي ﻛﻤﻲ در ﭘﺎﻳﻴﻦ آن اﻳﺠﺎد ﺷﻮد. ﺑﺎ اﺳﺘﻔﺎده از ﻗﺴﻤﺖ MyPaint Componentsدر ﺟﻌﺒﻪ اﺑـﺰار ﻳـﻚ ﻛﻨﺘـﺮل ColorPaletteرا در ﭘﺎﻳﻴﻦ ﻓﺮم ﻗﺮار داده و ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑﺎ paletteColorﻗﺮار دﻫﻴـﺪ .ﻫﻤﭽﻨـﻴﻦ ﺧﺎﺻـﻴﺖ Dock اﻳﻦ ﻛﻨﺘﺮل را ﻧﻴﺰ ﺑﺎ ﻣﻘﺪار Bottomﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ. ﺣﺎل ﻛﻨﺘﺮل PaintCanvasرا اﻧﺘﺨﺎب ﻛﺮده ،اﮔﺮ ﻻزم اﺳﺖ اﻧﺪازه ي آن را در ﻓﺮم ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ و ﺳـﭙﺲ ﺧﺎﺻـﻴﺖ Anchorآن را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺪار Top, Right, Left, Bottomﻗﺮار دﻫﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻓﺮم ﺷـﻤﺎ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 3-14ﺷﺪه ﺑﺎﺷﺪ. اﻧﺪازه ي ﻓﺮم را ﻣﻘﺪاري ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ رﻧﮕﻬﺎي ﻣﻮﺟﻮد در ﭘﺎﻟﺖ رﻧﮓ ﺑﻪ ﺻﻮرت ﻣﻨﺎﺳﺐ در ﻣﻜﺎن ﺧﻮد ﻗﺮار ﺧﻮاﻫﻨﺪ ﮔﺮﻓﺖ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺧﻮﺷﺒﺨﺘﺎﻧﻪ ﻛﻼس ColorPaletteButtonﻗﺴﻤﺖ ﭘﻴﭽﻴﺪه اي ﻧﺪارد ﻛﻪ درك آن ﻣﺸﻜﻞ ﺑﺎﺷﺪ و ﻳـﺎ ﻧﻴـﺎز ﺑـﻪ ﺗﻮﺿـﻴﺢ زﻳﺎدي داﺷﺘﻪ ﺑﺎﺷﺪ .اﻳﻦ ﻛﻼس از دو ﻓﻴﻠﺪ ﺑﺮاي ﻧﮕﻬﺪاري رﻧﮓ دﻛﻤﻪ و ﻧﻴﺰ ﻣﺴﺘﻄﻴﻠﻲ ﻛﻪ ﺑﺮاي آن دﻛﻤﻪ ﻛﺸﻴﺪه ﻣﻲ ﺷﻮد ﺗﺸﻜﻴﻞ ﺷـﺪه
٥٥٣
اﺳﺖ .ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﻛﻼس ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه وﺟﻮد دارد ﻛﻪ ﻣﻘﺪار ﻓﻴﻠﺪ ﻧﮕﻬﺪارﻧﺪه ي رﻧﮓ را ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴـﻚ ﺑـﺮ اﺳـﺎس ورودي ﻣﺘﺪ ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﻨﺪ. public class ColorPaletteButton { // Publiuc members ;public Color color = System.Drawing.Color.Black ;public Rectangle rectangle // Constructor )public ColorPaletteButton(Color objColor { ;color = objColor }
ﺷﻜﻞ 3-14 اﻳﻦ ﻛﻼس داراي ﻣﺘﺪي ﺑﻪ ﻧﺎم Drawاﺳﺖ و زﻣﺎﻧﻲ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد ﻛﻪ ﺑﺨﻮاﻫﻴﻢ اﻳﻦ دﻛﻤﻪ را در ﭘﺎﻟﺖ رﻧﮓ ﻗﺮار دﻫﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻳﻚ ﻣﺮﺑﻊ ﺗﻮﭘﺮ ﺑﺎ اﺳﺘﻔﺎده از رﻧﮕﻲ ﻛﻪ اﻳﻦ دﻛﻤﻪ ﻣﻌﺮف آن اﺳﺖ رﺳﻢ ﻣﻲ ﺷﻮد .ﺳﭙﺲ ﻳﻚ ﻣﺮﺑﻊ ﺗﻮﺧﺎﻟﻲ ﺑﻪ رﻧﮓ ﺳﻴﺎه در اﻃﺮاف ﻣﺮﺑﻊ اول رﺳﻢ ﻣﻲ ﺷﻮد ﻛﻪ ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﺣﺎﺷﻴﻪ ﺑﺮاي آن ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد. // Draw the button )public void Draw(Graphics graphics { // Draw the color block SolidBrush objSolidBrush = new ;)SolidBrush(color
٥٥٤
graphics.FillRectangle(objSolidBrush, ;)rectangle // Draw an edge around the control ;)Pen objPen = new Pen(Color.Black ;)graphics.DrawRectangle(objPen, rectangle } ﻫﻤﭽﻨﻴﻦ اﻳﻦ ﻛﻼس داراي ﻣﺘﺪي ﺑﻪ ﻧﺎم SetPositionاﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ ﻛﻪ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ ،ﻣﻜﺎن رﺳﻢ دﻛﻤﻪ را در ﭘﺎﻟﺖ رﻧﮓ ﺗﻌﻴﻴﻦ ﻣﻲ ﻛﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻧﺪازه ي ﻓﺮم ﺗﻐﻴﻴﺮ ﻛﺮد ﻣﻲ ﺗﻮاﻧﻴﻢ ﻣﻮﻗﻌﻴﺖ ﺟﺪﻳﺪ دﻛﻤﻪ را )ﻳﻌﻨﻲ ﻣﻜﺎن ﮔﻮﺷﻪ ي ﺑﺎﻻ ﺳﻤﺖ ﭼﭗ آن را( ﺑﻪ ﻫﻤﺮاه اﻧﺪازه ي دﻛﻤﻪ ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻓﺮﺳﺘﺎده و ﺳﭙﺲ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ Drawدﻛﻤﻪ را در اﻳﻦ ﻣﻜﺎن ﺟﺪﻳﺪ رﺳﻢ ﻛﻨﻴﻢ. // Move the button to the given position public void SetPosition(int x, int y, )int buttonSize { // Update the members rectangle = new ;)Rectangle(x, y, buttonSize, buttonSize } اﺣﺘﻤﺎﻻً ﺟﺎﻟﺐ ﺗﺮﻳﻦ ﻗﺴﻤﺖ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﺘﺪ ColorPalette_Resizeاﺳﺖ .اﻟﮕﻮرﻳﺘﻤﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺮاي ﺗﻌﻴﻴﻦ ﻣﻮﻗﻌﻴﺖ دﻛﻤﻪ ﻫﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ،اﻟﮕﻮرﻳﺘﻤﻲ اﺳﺖ ﻛﻪ ﻣﻌﻤﻮﻻً ﺑﺮاي ﺗﻌﻴﻴﻦ ﻣﻜﺎن ﻛﻨﺘﺮل ﻫﺎ و ﻳﺎ ﺷﻴﺊ ﻫﺎي ﮔﺮاﻓﻴﻜﻲ دﻳﮕﺮ ﺑﻪ ﻛﺎر ﻣﻲ رود .ﺑﺮاي رﺳﻢ ﻛﻨﺘﺮل اﻧﺪازه ي ﻫﺮ ﻛﺪام از آﻧﻬﺎ )ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺷﺎﻣﻞ اﻧﺪازه ي ﺧﻮد دﻛﻤﻪ و اﻧﺪازه ي ﻓﻀﺎي ﺑﻴﻦ دﻛﻤﻪ ﻫﺎ اﺳﺖ( و ﻧﻴﺰ ﻣﺤﺪوده ي ﻫﺮ ﻳﻚ را ﻧﻴﺰ ﻣﻲ داﻧﻴﻢ .ﺗﻨﻬﺎ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﻢ اﻳﻦ اﺳﺖ ﻛﻪ از ﮔﻮﺷﻪ ي ﺑﺎﻻ ﺳﻤﺖ ﭼﭗ ﺷﺮوع ﻛﻨﻴﻢ و ﻳﻜﻲ ﻳﻜﻲ دﻛﻤﻪ ﻫﺎ را در ﺻﻔﺤﻪ رﺳﻢ ﻛﻨﻴﻢ ﺗﺎ دﻳﮕﺮ ﻓﻀﺎﻳﻲ در آن ﺧﻂ ﺑﺎﻗﻲ ﻧﻤﺎﻧﺪه ﺑﺎﺷﺪ ،ﺳﭙﺲ ﺑﻪ ﺧﻂ ﺑﻌﺪي ﺑﺮوﻳﻢ .ﺑﺮاي ﺷﺮوع اﺑﺘﺪا ﺑﺎﻳﺪ ﺣﻠﻘﻪ اي اﻳﺠﺎد ﻛﻨﻴﻢ ﺗﺎ ﺑﻴﻦ ﺗﻤﺎم دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد ﺣﺮﻛﺖ ﻛﻨﺪ. private void ColorPalette_Resize(object sender, )EventArgs e { // Declare variables to hold the position ;int intX = 0 ;int intY = 0 // Go through the array and position the buttons foreach (ColorPaletteButton objColorPaletteButton )in Buttons { ﻣﺘﻐﻴﻴﺮ intXﻣﻜﺎن اﻓﻘﻲ و ﻣﺘﻐﻴﻴﺮ intYﻣﻜﺎن ﻋﻤﻮدي را ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ و ﻣﻘﺪار اوﻟﻴﻪ ي آﻧﻬﺎ ﻧﻴﺰ ) (0,0اﺳﺖ .ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ ﻛﻪ اوﻟﻴﻦ دﻛﻤﻪ در ﻣﻮﻗﻌﻴﺖ ) (0,0در ﻛﻨﺘﺮل ﻗﺮار ﺧﻮاﻫﺪ ﮔﺮﻓﺖ.
٥٥٥
// Position the button ;)objColorPaletteButton.SetPosition(intX, intY, ButtonSize ﺑﻌﺪ از ﻗﺮار دادن اﻳﻦ دﻛﻤﻪ ،ﻣﻮﻗﻌﻴﺖ اﻓﻘﻲ را ﺑﻪ اﻧﺪازه ي ﻃﻮل ﻳﻚ دﻛﻤﻪ و ﻧﻴﺰ ﻓﺎﺻﻠﻪ ي ﺑﻴﻦ دو دﻛﻤﻪ ﺑﻪ ﺳﻤﺖ راﺳﺖ ﻣﻨﺘﻘﻞ ﻣﻲ ﻛﻨﻴﻢ .ﺳﭙﺲ ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ آﻳﺎ اﮔﺮ دﻛﻤﻪ ي دﻳﮕﺮي را در اﻳﻦ ﺧﻂ ﻗﺮار دﻫﻴﻢ ،ﻃﻮل آن از ﻃﻮل ﻛﻨﺘﺮل ﭘﺎﻟﺖ رﻧﮓ ﺑﻴﺸﺘﺮ ﺧﻮاﻫﺪ ﺷﺪ ﻳﺎ ﻧﻪ؟ در ﺻﻮرﺗﻲ ﻛﻪ ﻓﻀﺎﻳﻲ در آن ﻗﺴﻤﺖ وﺟﻮد ﻧﺪاﺷﺖ ،ﻣﻘﺪار ﻋﻤﻮدي را ) (intYﺑﻪ اﻧﺪازه ي ﻃﻮل ﻳﻚ دﻛﻤﻪ و ﻧﻴﺰ ﻓﺎﺻﻠﻪ ي ﺑﻴﻦ دو دﻛﻤﻪ ﺑﻪ ﭘﺎﻳﻴﻦ ﻣﻨﺘﻘﻞ ﻛﺮده و ﻣﻘﺪار اﻓﻘﻲ را ﺑﺮاﺑﺮ ﺑﺎ ﺻﻔﺮ ﻗﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ ﻣﺠﺪداً از اﺑﺘﺪاي ﺧﻂ ﺑﺮاي رﺳﻢ دﻛﻤﻪ ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﺪ. // Move to the next one ;)intX += (ButtonSize + ButtonSpacing // Do we need to go down to the next row )if (intX + ButtonSize > Width { // Move y ;)intY += (ButtonSize + ButtonSpacing // Reset x ;intX = 0 } } در آﺧﺮ ﻧﻴﺰ ﻣﺘﺪ Invalidateدر ﻛﻨﺘﺮل را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ ﻇﺎﻫﺮ اﻳﻦ ﻛﻨﺘﺮل ﻧﺎ ﻣﻌﺘﺒﺮ اﺳﺖ و ﺑﺎﻳﺪ ﺗﻮﺳﻂ وﻳﻨﺪوز ﻣﺠﺪداً رﺳﻢ ﺷﻮد. // Redraw ;)(this.Invalidate }
ﭘﺎﺳﺦ دادن ﺑﻪ ﻛﻠﻴﻚ ﻫﺎ: ﻛﻨﺘﺮﻟﻲ ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ ﺑﺮاي اﺳﺘﻔﺎده ﺑﻪ ﻋﻨﻮان ﻳﻚ ﭘﺎﻟﺖ رﻧﮓ اﻳﺠﺎد ﻛﺮدﻳﻢ ،ﺑﺎﻳﺪ ﺑﺘﻮاﻧﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي ﻳﻜﻲ از رﻧﮕﻬﺎ ﻛﻠﻴﻚ ﻛﺮد ،روﻳﺪاد ﻣﻨﺎﺳﺒﻲ را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﺪ .ﺑﻪ ﻫﻤﻴﻦ ﻣﻨﻈﻮر در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﭼﻨﺪ روﻳﺪاد را ﺑﻪ اﻳﻦ ﻛﻼس اﺿﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛـﺮد .ﺑـﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ از اﻳﻦ ﻛﻨﺘﺮل اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ ﻣﻲ ﺗﻮاﻧﺪ ﻣﺘﺪ ﻫﺎﻳﻲ را اﻳﺠﺎد ﻛﺮده و ﺗﻌﻴﻴﻦ ﻛﻨﺪ ﻛﻪ ﻫﻨﮕﺎم رخ دادن ﻫـﺮ ﻳـﻚ از اﻳﻦ روﻳﺪادﻫﺎ اﻳﻦ ﻣﺘﺪ ﻫﺎ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮﻧﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﭘﺎﺳﺦ دادن ﺑﻪ ﻛﻠﻴﻚ ﻫﺎ
٥٥٦
ﺑﺮوﻳﺪ و ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ﻛﺪ زﻳﺮ ﺑﻪ اﻳﻦ ﻛﻼس دو ﻣﺘﺪ ﻣﻮردColorPalette ( ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﺑﺮاي ﻛﻼس1 :ﻧﻈﺮ را اﻳﺠﺎد ﻛﻨﻴﺪ // Public Delegates public delegate void _leftClick(Object sender, EventArgs e); public delegate void _rightClick(Object sender, EventArgs e); // Public Events public event _leftClick LeftClick; public event _rightClick RightClick; ( در اﻳﻦ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻣﺘﺪي ﻧﻴﺎز دارﻳﻢ ﻛﻪ ﻣﻮﻗﻌﻴﺖ ﻣﺎوس را درﻳﺎﻓﺖ ﻛﺮده و اﻋـﻼم ﻛﻨـﺪ ﻛـﻪ اﺷـﺎره ﮔـﺮ ﻣـﺎوس روي2 : ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﺘﺪ زﻳﺮ را ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ.ﻛﺪاﻣﻴﻚ از ﻛﻠﻴﺪ ﻫﺎي ﻣﻮﺟﻮد در ﭘﺎﻟﺖ رﻧﮓ ﻗﺮار دارد public ColorPaletteButton GetButtonAt(int X, int Y) { // Go through each button in the collection foreach (ColorPaletteButton objColorPaletteButton in Buttons) // Is this button in the rectangle? if (objColorPaletteButton.rectangle.Contains( X, Y)) return objColorPaletteButton; // If no button found, return null value return null; } از اﻳﻦ ﻟﻴﺴﺖ روﻳﺪاد، رﻓﺘﻪColorPalette ﺑﻪ ﻟﻴﺴﺖ روﻳﺪادﻫﺎي ﻛﻨﺘﺮلProperties ( ﺣﺎل در ﭘﻨﺠﺮه ي3 ﺳﭙﺲ ﻛﺪ زﻳـﺮ را ﺑـﻪ. را اﻧﺘﺨﺎب ﻛﺮده و روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد اﻳﺠﺎد ﺷﻮدMouseUp :اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ private void ColorPalette_MouseUp(object sender, MouseEventArgs e) { // Find the button that we clicked ColorPaletteButton objColorPaletteButton = GetButtonAt(e.X, e.Y); if (objColorPaletteButton != null) {
٥٥٧
?// Was the left button was clicked )if (e.Button == MouseButtons.Left { // Set the color ;LeftColor = objColorPaletteButton.color // Raise the event ;))(LeftClick(this, new EventArgs } )else if (e.Button == MouseButtons.Right { // Set the color ;RightColor = objColorPaletteButton.color // Raise the event ;))(RightClick(this, new EventArgs } } } (4ﺑﺮاي ﺗﺴﺖ ﻛﻨﺘﺮل ﺟﺪﻳﺪ ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ Form1رﻓﺘـﻪ و ﻛﻨﺘـﺮل PaintCanvasرا اﻧﺘﺨـﺎب ﻛﻨﻴﺪ .ﺳﭙﺲ ﺧﺎﺻﻴﺖ Nameاﻳﻦ ﻛﻨﺘﺮل را ﺑﻪ Canvasﺗﻐﻴﻴﺮ دﻫﻴﺪ. (5ﺑﺮﻧﺎﻣﻪ را ﻳﻚ ﺑﺎر ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﻴﺪ ﺗﺎ ﺗﻐﻴﻴﺮاﺗﻲ ﻛﻪ در ﻛﻨﺘﺮل ColorPaletteاﻳﺠﺎد ﻛﺮده اﻳﻢ اﻋﻤﺎل ﺷﻮﻧﺪ. (6ﺳﭙﺲ ﻛﻨﺘﺮل paletteColorرا از ﻓﺮم Form1اﻧﺘﺨﺎب ﻛﺮده و ﺑﺎ اﺳﺘﻔﺎده از ﻟﻴﺴﺖ روﻳﺪادﻫﺎي اﻳﻦ ﻛﻨﺘﺮل در ﭘﻨﺠﺮه ي ،Propertiesروﻳﺪاد LeftClickرا اﻧﺘﺨﺎب ﻛﺮده و روي آن دوﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد اﻳﺠﺎد ﺧﻮاﻫﺪ ﺷﺪ .ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: private void paletteControl_LeftClick(object sender, )EventArgs e { ;Canvas.GraphicColor = paletteControl.LeftColor } (7ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .اﻳﻦ ﻣﺮﺗﺒﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ ﻛﻠﻴﻚ روي ﻫﺮ ﻛﺪام از رﻧﮓ ﻫﺎﻳﻲ ﻛﻪ در ﭘﺎﻳﻴﻦ ﻓﺮم ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ ،رﻧﮓ ﻣﻮرد اﺳﺘﻔﺎده ﺑﺮاي ﺗﺮﺳﻴﻢ در ﻓﺮم را ﺗﻐﻴﻴﺮ دﻫﻴﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﻋﻨﻮان دﻛﻤﻪ در ﭘﺎﻟﺖ رﻧﮓ اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ ﻣﻘﺪاري ﺑﺎ ﻛﻨﺘﺮﻟﻬـﺎي Buttonﻛـﻪ در ﻗـﺴﻤﺘﻬﺎي ﻗﺒﻞ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ ﺗﻔﺎوت دارﻧﺪ .ﻛﻨﺘﺮﻟﻬﺎي Buttonﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ ﺑـﻪ اﻧـﺪازه ي ﻛـﺎﻓﻲ ﻫﻮﺷﻤﻨﺪ ﺑﻮدﻧﺪ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ روي آﻧﻬﺎ ﻛﻠﻴﻚ ﺷﻮد را ﺗﺸﺨﻴﺺ داده و ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ روﻳﺪادي در آن زﻣﺎن ﻛﺎر ﺧﺎﺻﻲ را اﻧﺠـﺎم دﻫﻨـﺪ .اﻣـﺎ
٥٥٨
دﻛﻤﻪ ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ در ﭘﺎﻟﺖ رﻧﮓ اﻳﺠﺎد ﻛﺮدﻳﻢ ،در ﺣﻘﻴﻘﺖ ﻓﻘﻂ ﻗﺴﻤﺘﻲ از ﻣﺤﺪوده ي ﭘﺎﻟﺖ رﻧـﮓ ﻫـﺴﺘﻨﺪ .ﺑﻨـﺎﺑﺮاﻳﻦ زﻣـﺎن ﻛﻠﻴﻚ ﺷﺪن روي آﻧﻬﺎ را ﺑﺎﻳﺪ ﺧﻮدﻣﺎن ﺗﺸﺨﻴﺺ دﻫﻴﻢ. ﺑﺮاي اﻳﻦ ﻛﺎر از ﻣﺘﺪ GetButtonAtاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ ﻣﻮﻗﻌﻴﺖ ﻛﻨﻮﻧﻲ اﺷﺎره ﮔﺮ ﻣﺎوس را ﻣﻲ ﮔﻴﺮد و ﺳﭙﺲ ﺑﺮرﺳـﻲ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻛﺪاﻣﻴﻚ از دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد در ﭘﺎﻟﺖ رﻧﮓ ﺷﺎﻣﻞ اﻳﻦ ﻣﻮﻗﻌﻴﺖ ﻣﻲ ﺷﻮﻧﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ اﺷﺎره ﮔـﺮ ﻣﺎوس روي ﻛﺪاﻣﻴﻚ از دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد در ﭘﺎﻟﺖ رﻧﮓ ﻗﺮار دارد. در اﻳﻨﺠﺎ ﺑﺮاي ﺗﺸﺨﻴﺺ اﻳﻨﻜﻪ اﺷـﺎره ﮔـﺮ ﻣـﺎوس در ﻣﺤـﺪوده ي ﻣﺮﺑـﻊ ﺷـﻜﻞ ﻛـﺪاﻣﻴﻚ از دﻛﻤـﻪ ﻫـﺎ ﻗـﺮار دارد ﻣـﻲ ﺗـﻮاﻧﻴﻢ از ﻣﺘـﺪ Containsدر ﻛﻼس Rectangleاﺳﺘﻔﺎده ﻛﻨﻴﻢ. )public ColorPaletteButton GetButtonAt(int X, int Y { // Go through each button in the collection foreach (ColorPaletteButton objColorPaletteButton )in Buttons ?// Is this button in the rectangle (if (objColorPaletteButton.rectangle.Contains ))X, Y ;return objColorPaletteButton // If no button found, return null value ;return null } اﻟﺒﺘﻪ ﻣﺸﺨﺺ اﺳﺖ ﻛﻪ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ در ﻧﺎﺣﻴﻪ اي از اﻳﻦ ﻛﻨﺘﺮل ﻛﻠﻴﻚ ﻛﻨﺪ ﻛﻪ ﻫﻴﭻ دﻛﻤـﻪ اي در آن ﻗـﺴﻤﺖ وﺟـﻮد ﻧﺪاﺷـﺘﻪ ﺑﺎﺷـﺪ. ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﺗﺎ اﻧﺘﻬﺎي ﺣﻠﻘﻪ ﻫﻴﭻ ﻣﻘﺪاري از ﺗﺎﺑﻊ ﺑﺮﮔﺸﺖ داده ﻧﺸﺪ ،ﻣﻘﺪار nullرا ﺑﺮﻣﻲ ﮔﺮداﻧﻴﻢ ﺗﺎ ﻣﺸﺨﺺ ﺷﻮد ﻛـﻪ در ﻧﺎﺣﻴـﻪ اي ﻛﻪ ﻛﻠﻴﻚ ﺷﺪه دﻛﻤﻪ اي وﺟﻮد ﻧﺪاﺷﺘﻪ اﺳﺖ. ﺑﻌﺪ از اﺗﻤﺎم اﻳﻦ ﺗﺎﺑﻊ ،ﻣﺘﺪي را اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ روﻳﺪاد MouseUpاﻳﻦ ﻛﻨﺘﺮل رخ داد ،اﻳﻦ ﻣﺘﺪ ﻓﺮاﺧﻮاﻧﻲ ﺷﻮد .در اﻳﻦ ﻣﺘﺪ اﺑﺘﺪا ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ GetButtonAtﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻛﺎرﺑﺮ روي ﻛﺪاﻣﻴﻚ از دﻛﻤﻪ ﻫـﺎي ﻣﻮﺟـﻮد در ﭘﺎﻟـﺖ رﻧـﮓ ﻛﻠﻴﻚ ﻛﺮده اﺳﺖ .ﺳﭙﺲ اﮔﺮ ﻛﺎرﺑﺮ روي دﻛﻤﻪ اي ﻛﻠﻴﻚ ﻛﺮده ﺑﻮد )ﻣﻘﺪار ﺑﺮﮔﺸﺘﻲ از ﺗﺎﺑﻊ ﻣﺨﺎﻟﻒ nullﺑﻮد( ،ﺑﺮ ﺣﺴﺐ اﻳﻨﻜﻪ ﻛـﺎرﺑﺮ ﺑﺮاي ﻛﻠﻴﻚ ﻛﺮدن از ﻛﻠﻴﺪ ﭼﭗ و ﻳﺎ راﺳﺖ ﻣﺎوس اﺳﺘﻔﺎده ﻛﺮده اﺳﺖ ﻣﻘﺪار LeftColorو ﻳﺎ RightColorرا ﺑﺮاﺑﺮ ﺑـﺎ رﻧﮓ اﻧﺘﺨﺎﺑﻲ ﻗﺮار داده و روﻳﺪاد ﻣﺘﻨﺎﻇﺮ آن را ﻧﻴﺰ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢ. private void ColorPalette_MouseUp(object sender, )MouseEventArgs e { // Find the button that we clicked = ColorPaletteButton objColorPaletteButton ;)GetButtonAt(e.X, e.Y )if (objColorPaletteButton != null { ?// Was the left button was clicked )if (e.Button == MouseButtons.Left {
٥٥٩
// Set the color ;LeftColor = objColorPaletteButton.color // Raise the event ;))(LeftClick(this, new EventArgs } )else if (e.Button == MouseButtons.Right { // Set the color ;RightColor = objColorPaletteButton.color // Raise the event ;))(RightClick(this, new EventArgs } } } اﻣﺎ ﻫﻨﻮز ﻛﻨﺘﺮل PaintCanvasدر ﻓﺮم اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺎ ﻳﻚ رﻧﮓ ﻛـﺎر ﻛﻨـﺪ .ﺑﻨـﺎﺑﺮاﻳﻦ ﻣﺘـﺪي را ﺑـﺮاي روﻳـﺪاد LeftClickﻛﻨﺘﺮل paletteColorدر ﻧﻈﺮ ﻣﻲ ﮔﻴﺮﻳﻢ ﺗﺎ ﺑـﺎ ﻓﺮاﺧـﻮاﻧﻲ اﻳـﻦ ﻣﺘـﺪ رﻧـﮓ ﻣـﻮرد اﺳـﺘﻔﺎده در ﻛﻨﺘـﺮل PaintCanvasﺑــﺮ اﺳــﺎس رﻧــﮓ اﻧﺘﺨــﺎﺑﻲ در ﻓــﺮم ﺗﻐﻴﻴــﺮ ﻛﻨــﺪ .ﺑــﺮاي ﺗﻨﻈــﻴﻢ رﻧــﮓ ﻛﻨﺘــﺮل ﻧﻴــﺰ ﺑﺎﻳــﺪ از ﺧﺎﺻــﻴﺖ GraphicColorاﺳﺘﻔﺎده ﻛﻨﻴﻢ. private void paletteControl_LeftClick(object sender, )EventArgs e { ;Canvas.GraphicColor = paletteControl.LeftColor }
اﺳﺘﻔﺎده از دو رﻧﮓ در ﺑﺮﻧﺎﻣﻪ: در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﻛﻪ ﺑﺘﻮاﻧﻴﻢ ﺑﺎ دو رﻧﮓ ﻧﻴﺰ در آن ﻛﺎر ﻛﻨـﻴﻢ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﺑﺎﻳـﺪ دو ﻓﻴﻠـﺪ publicﺑﻪ ﻛﻼس PaintCanvasاﺿﺎﻓﻪ ﻛﻨﻴﻢ ﺗﺎ رﻧﮕﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﻛﻠﻴﺪ ﭼﭗ و راﺳﺖ ﻣﺎوس در آﻧﻬﺎ ﻧﮕﻬﺪاري ﺷـﻮﻧﺪ. ﻫﻤﭽﻨﻴﻦ ﺑﺎﻳﺪ ﻛﺪ ﻫﺎي دﻳﮕﺮ را ﻧﻴﺰ ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﺗﺎ ﺗﺸﺨﻴﺺ دﻫﻨﺪ ﻛﻪ ﻛﻠﻴﺪ ﭼﭗ ﻣﺎوس ﻓﺸﺎر داده ﺷﺪه اﺳﺖ و ﻳﺎ ﻛﻠﻴﺪ راﺳﺖ ﻣﺎوس؟
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از دو رﻧﮓ در ﺑﺮﻧﺎﻣﻪ (1اﺑﺘﺪا ﺑﺎﻳﺪ در ﻛﻼس PaintCanvasدو ﻣﺘﻐﻴﻴﺮ اﻳﺠﺎد ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ رﻧﮕﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﻛﻠﻴﺪ ﭼﭗ و راﺳﺖ ﻣﺎوس را در آﻧﻬﺎ ﻧﮕﻬﺪاري ﻛﻨﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ را ﺑﺮاي ﻛﻼس PaintCanvasﺑﺎز ﻛﺮده و ﺗﻐﻴﻴﺮات زﻳﺮ را در ﻛـﺪ آن ﻛﻼس وارد ﻛﻨﻴﺪ:
٥٦٠
// Public members public ArrayList GraphicsItems = new ArrayList(); public GraphicTools GraphicTool = GraphicTools.CirclePen; public GraphicSizes GraphicSize = GraphicSizes.Medium; public Color GraphicLeftColor = Color.Black; public Color GraphicRightColor = Color.White; اﺳﺘﻔﺎده ﻛﻨﻴﻢ ﺗﺎMouseEventArgs در ﻛﻼسButton ﺑﺎﻳﺪ از ﺧﺎﺻﻴﺖDoMousePaint ( در ﻣﺘﺪ2 ﻛﺪ ﻧﻮﺷﺘﻪ ﺷﺪه در اﻳﻦ ﻣﺘﺪ را ﺑﻪ ﺻﻮرت زﻳـﺮ ﺗﻐﻴﻴـﺮ.ﺗﺸﺨﻴﺺ دﻫﻴﻢ ﻛﻪ ﻛﺪام رﻧﮓ ﺑﺎﻳﺪ ﺑﺮاي اﻳﺠﺎد ﺷﻜﻞ ﺑﻪ ﻛﺎر ﮔﺮﻓﺘﻪ ﺷﻮد :دﻫﻴﺪ private void DoMousePaint(MouseEventArgs e) { // Store the new item somewhere GraphicsItem objGraphicsItem = null; // What color do we want to use? Color objColor = GraphicLeftColor; if (e.Button == MouseButtons.Right) objColor = GraphicRightColor; // What tool are you using? switch(GraphicTool) { // CirclePen case GraphicTools.CirclePen: { // Create a new graphics circle GraphicsCircle objGraphicsCircle = new GraphicsCircle(); // Set the point for drawing objGraphicsCircle.SetPoint(e.X, e.Y, (int)GraphicSize, objColor, true); // Store this for addition objGraphicsItem = objGraphicsCircle; break; } } // Were you given an item?
٥٦١
if( objGraphicsItem != null) { // Add it to the list GraphicsItems.Add(objGraphicsItem); // Invalidate the control this.Invalidate(objGraphicsItem.rectangle) ; } } راDoMousePaint ﻓﻘــﻂ زﻣــﺎﻧﻲ ﻣﺘــﺪMouseMove وMouseDown ( در اﻳــﻦ ﻛــﻼس روﻳــﺪادﻫﺎي3 ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ ﻛﺪ ﻣﻮﺟﻮد در اﻳﻦ ﻣﺘﺪ ﻫﺎ را ﻧﻴﺰ ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ.ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ ﻛﻠﻴﺪ ﭼﭗ ﻣﺎوس ﻓﺸﺎر داده ﺷﺪه ﺑﺎﺷﺪ ﭘﺲ ﺗﻐﻴﻴﺮات زﻳـﺮ را در اﻳـﻦ دو ﻣﺘـﺪ. اﻳﻦ ﻣﺘﺪ را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻨﺪ،دﻫﻴﻢ ﻛﻪ در ﺻﻮرت ﻓﺸﺎر داده ﺷﺪن ﻛﻠﻴﺪ راﺳﺖ ﻣﺎوس ﻧﻴﺰ :وارد ﻛﻨﻴﺪ private void PaintCanvas_MouseDown(object sender, MouseEventArgs e) { // Is the left mouse button down? if( e.Button == MouseButtons.Left || e.Button == MouseButtons.Right) DoMousePaint(e); } private void PaintCanvas_MouseMove(object sender, MouseEventArgs e) { // Is the left mouse button down? if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right) DoMousePaint(e); } را ﻧﻴﺰ ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﺗﺎ ﺑﻪForm1 در ﻛﻼسpaletteColor_LeftClick ( ﺳﭙﺲ ﺑﺎﻳﺪ ﻣﺘﺪ4 ﺑﻨـﺎﺑﺮاﻳﻦ ﺑـﻪ. را ﺗﻨﻈﻴﻢ ﻛﻨـﺪGraphicLeftColor ﺧﺎﺻﻴﺖ،GraphicColor ﺟﺎي ﺗﻨﻈﻴﻢ ﺧﺎﺻﻴﺖ : ﺑﺮوﻳﺪ و ﺗﻐﻴﻴﺮات زﻳﺮ را در اﻳﻦ ﻣﺘﺪ اﻳﺠﺎد ﻛﻨﻴﺪForm1 ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس private void paletteControl_LeftClick(object sender, EventArgs e) { Canvas.GraphicLeftColor = paletteControl.LeftColor; }
٥٦٢
(5در آﺧــﺮ ﻧﻴــﺰ ﺑﺎﻳــﺪ ﻣﺘــﺪ ﻣﺮﺑــﻮط ﺑــﻪ روﻳــﺪاد RightClickرا اﻳﺠــﺎد ﻛﻨــﻴﻢ .ﺑــﺮاي اﻳــﻦ ﻛــﺎر روي روﻳــﺪاد RightClickدر ﻗﺴﻤﺖ Eventsﭘﻨﺠﺮه ي Propertiesدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل اﻳﻦ روﻳﺪاد اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: private void paletteControl_RightClick(object sender, )EventArgs e { = Canvas.GraphicRightColor ;paletteControl.RightColor } ﺣﺎل اﮔﺮ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻠﻴﺪ راﺳﺖ و ﭼﭗ ﻣﺎوس دو رﻧﮓ را اﻧﺘﺨﺎب ﻛـﺮده و از آﻧﻬﺎ ﺑﺮاي ﺗﺮﺳﻴﻢ ﻓﺮم اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
ﻣﺸﺨﺺ ﻛﺮدن رﻧﮕﻬﺎي ﻣﻮرد اﺳﺘﻔﺎده: ﻣﻄﻤﺌﻨﺎً ﺗﺎﻛﻨﻮن ﻣﺘﻮﺟﻪ ﺷﺪه اﻳﺪ ﻛﻪ اﺳﺘﻔﺎده از ﺑﺮﻧﺎﻣﻪ ي MyPaintﻣﻘﺪاري ﮔﻴﺞ ﻛﻨﻨﺪه اﺳﺖ ،زﻳﺮا ﺑﺎ اﻧﺘﺨـﺎب ﻳـﻚ رﻧـﮓ از ﭘﺎﻟـﺖ رﻧﮓ ﻫﻴﭻ روﺷﻲ ﺑﺮاي ﻓﻬﻤﻴﺪن اﻳﻦ ﻛﻪ ﭼﻪ رﻧﮕﻲ ﺑﺮاي ﻛﻠﻴﺪ راﺳﺖ و ﭼﻪ رﻧﮕﻲ ﺑﺮاي ﻛﻠﻴﺪ ﭼﭗ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ وﺟـﻮد ﻧـﺪارد. ﺑﺮاي رﻓﻊ اﻳﻦ ﻣﺸﻜﻞ در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻴﻢ ﺗﺎ ﺑﺮ روي دﻛﻤـﻪ اي ﻛـﻪ رﻧـﮓ آن ﺑـﺮاي ﻛﻠﻴـﺪ راﺳﺖ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ ﺣﺮف Rو ﺑﺮ روي دﻛﻤﻪ اي ﻛﻪ رﻧﮓ آن ﺑﺮاي ﻛﻠﻴﺪ ﭼﭗ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ ،ﺣﺮف L ﻧﻤﺎﻳﺶ داده ﺷﻮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻣﺸﺨﺺ ﻛﺮدن رﻧﮕﻬﺎي ﻣﻮرد اﺳﺘﻔﺎده (1اﺑﺘﺪا ﺑﺎﻳﺪ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﻛﻪ اﺷﻴﺎي اﻳﺠﺎد ﺷﺪه از ﻛﻼس ColorPaletteButtonﺑﺪاﻧﻨﺪ ﺑﻪ ﭼﻪ ﻛﻠﻴﺪي ﺗﻌﻠﻖ دارﻧﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻗﺴﻤﺖ وﻳﺮاﻳـﺸﮕﺮ ﻛـﺪ ﺑـﺮاي ﻛـﻼس ColorPaletteButtonرا ﺑـﺎز ﻛﺮده و ﻛﺪ زﻳﺮ را ﺑﻪ اﺑﺘﺪاي ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ از اﻳﻦ ﺷﻤﺎرﻧﺪه در ﻛﻼس اﺳﺘﻔﺎده ﻛﻨﻴﻢ: public class ColorPaletteButton { // Public enumerations public enum ButtonAssignments { None = 0, LeftButton = 1, RightButton = 2 }
٥٦٣
( ﺳﭙﺲ ﻓﻴﻠﺪ زﻳﺮ را ﻧﻴﺰ ﺑﻪ اﻳﻦ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﺗﻮﺳﻂ آن ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ رﻧﮓ ﻫﺮ دﻛﻤـﻪ ﺑـﻪ ﭼـﻪ ﻛﻠﻴـﺪي از2 .ﻣﺎوس ﻧﺴﺒﺖ داده ﺷﺪه اﺳﺖ // Publiuc members public Color color = System.Drawing.Color.Black; public Rectangle rectangle; public ButtonAssignments ButtonAssignment = ButtonAssignments.None; را روي دﻛﻤﻪ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ آﻧﻬﺎ در ﭘﺎﻟﺖ رﻧﮓR و ﻳﺎ ﺣﺮفL را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﻛﻪ ﺣﺮفDraw ( ﺣﺎل ﺑﺎﻳﺪ ﻣﺘﺪ3 : اﺿﺎﻓﻪ ﻛﻨﻴﺪDraw ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺪ زﻳﺮ را ﺑﻪ ﻣﺘﺪ.ﻧﻤﺎﻳﺶ دﻫﺪ // Draw the button public void Draw(Graphics graphics) { // Draw the color block SolidBrush objSolidBrush = new SolidBrush(color); graphics.FillRectangle(objSolidBrush, rectangle); // Draw an edge around the control Pen objPen = new Pen(Color.Black); graphics.DrawRectangle(objPen, rectangle); // Are you selected? if (ButtonAssignment != ButtonAssignments.None) { // Create a Font Font objFont = new Font("verdana", 80, FontStyle.Bold); // Set the default button assignment String strButtonText = "L"; // Update the button assignment if necessary if (ButtonAssignment == ButtonAssignments.RightButton) { strButtonText = "R"; } // What brush do you want? if (color.R < 100 || color.B < 100 || color.G < 100) { objSolidBrush = new
٥٦٤
SolidBrush(Color.White); } else { objSolidBrush = new SolidBrush(Color.Black); } // Draw the text "L" or "R" graphics.DrawString(strButtonText, objFont, objSolidBrush, rectangle.Left, rectangle.Right); } } ﺑﺮوﻳﺪ و ﻛﺪ زﻳﺮ را ﺑﻪ اﻳﻦ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺑﻪ وﺳﻴﻠﻪPaletteColor ( ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس4 ي اﻳﻦ دو ﻓﻴﻠﺪ ﻣﻲ ﺗﻮاﻧﻴﻢ در ﻫﺮ ﻟﺤﻈﻪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ رﻧﮓ ﭼﻪ دﻛﻤﻪ اي از ﭘﺎﻟﺖ رﻧﮓ ﺑﺎﻳﺪ ﺑﻪ ﻋﻨﻮان رﻧـﮓ ﻛﻠﻴـﺪ ﭼـﭗ .ﻣﺎوس و رﻧﮓ ﭼﻪ دﻛﻤﻪ اي ﺑﺎﻳﺪ ﺑﻪ ﻋﻨﻮان رﻧﮓ ﻛﻠﻴﺪ راﺳﺖ ﻣﺎوس ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد // Private members private ColorPaletteButton LeftButton; private ColorPaletteButton RightButton; در اﻳـﻦ. اﻣﺎ ﻛـﺎر ﺳـﺎده اي را اﻧﺠـﺎم ﻣـﻲ دﻫـﺪ،( ﻛﺪي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ وارد ﻣﻲ ﻛﻨﻴﻢ ﻣﻤﻜﻦ اﺳﺖ ﻣﻘﺪاري ﻃﻮﻻﻧﻲ ﺑﺎﺷﺪ5 ﻫﻤﭽﻨﻴﻦ ﺑﺎﻳﺪ.ﻗﺴﻤﺖ ﺑﺎﻳﺪ ﺗﻐﻴﻴﺮاﺗﻲ اﻳﺠﺎد ﻛﻨﻴﻢ ﺗﺎ ﻣﻄﻤﺌﻦ ﺷﻮﻳﻢ ﻳﻚ رﻧﮓ ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻪ ﻫﺮ دو ﻛﻠﻴﺪ ﻣﺎوس ﻧﺴﺒﺖ داده ﺷﻮد ﺑﻨﺎﺑﺮاﻳﻦ.( را از روي دﻛﻤﻪ ي ﻗﺒﻠﻲ در ﭘﺎﻟﺖ رﻧﮓ ﭘﺎك ﻛﻨﻴﻢ و آن را روي دﻛﻤﻪ ي ﺟﺪﻳﺪ ﻗﺮار دﻫﻴﻢR )و ﻳﺎ ﺣﺮفL ﺣﺮف ﺗﻐﻴﻴـﺮات زﻳـﺮ را در.اﻳﻦ دو دﻛﻤﻪ در ﭘﺎﻟﺖ رﻧﮓ را ﻧﻴﺰ ﺑﺎﻳﺪ از ﻧﻮع ﻧﺎ ﻣﻌﺘﺒﺮ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﺗﺎ ﻣﺠﺪداً ﺗﻮﺳﻂ وﻳﻨﺪوز رﺳﻢ ﺷﻮﻧﺪ : اﻳﺠﺎد ﻛﻨﻴﺪColorPalette_MouseUp ﻣﺘﺪ private void ColorPalette_MouseUp(object sender, MouseEventArgs e) { // Find the button that we clicked ColorPaletteButton objColorPaletteButton = GetButtonAt(e.X, e.Y); if (objColorPaletteButton != null) { // Was the left button was clicked? if (e.Button == MouseButtons.Left) { // Make sure that this button is not // the current right button if (objColorPaletteButton != RightButton) {
٥٦٥
// Set the color LeftColor = objColorPaletteButton.color; // Clear the existing selection if (LeftButton != null) { LeftButton.ButtonAssignment = ColorPaletteButton.ButtonAssignments.None; this.Invalidate( LeftButton.rectangle); } // Mark the button objColorPaletteButton.ButtonAssignment = ColorPaletteButton.ButtonAssignments.LeftButton; this.Invalidate( objColorPaletteButton.rectangle); LeftButton = objColorPaletteButton; // Raise the event LeftClick(this, new EventArgs()); } } else if { // // if {
(e.Button == MouseButtons.Right) Make sure that this button is not the current left button (objColorPaletteButton != LeftButton) // Set the color RightColor = objColorPaletteButton.color;
// Clear the existing selection if (RightButton != null) { RightButton.ButtonAssignment = ColorPaletteButton.ButtonAssignments.None; this.Invalidate( RightButton.rectangle); }
٥٦٦
// Mark the button objColorPaletteButton.ButtonAssignment = ColorPaletteButton.ButtonAssignments.RightButton; this.Invalidate( objColorPaletteButton.rectangle); RightButton = objColorPaletteButton; // Raise the event RightClick(this, new EventArgs()); } } } } ﻳﻜﻲ از دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد در ﭘﺎﻟﺖ رﻧﮓ ﺑـﻪ،( در آﺧﺮ ﻧﻴﺰ ﺑﺎﻳﺪ ﻛﺪي را وارد ﻛﻨﻴﻢ ﺗﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺷﺮوع ﺑﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ6 را ﺑـﻪ ﻧﺤـﻮيAddColor ﺑﺮاي اﻳـﻦ ﻛـﺎر ﻣﺘـﺪ.ﻛﻠﻴﺪ ﭼﭗ ﻣﺎوس و رﻧﮓ دﻳﮕﺮ ﺑﻪ ﻛﻠﻴﺪ راﺳﺖ ﻣﺎوس ﻧﺴﺒﺖ داده ﺷﻮد رﻧﮓ اول را ﺑﺮاي ﻛﻠﻴﺪ ﭼﭗ و رﻧـﮓ دوم را ﺑـﺮاي،ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻴﻢ ﺗﺎ اﮔﺮ ﻫﻴﭻ رﻧﮕﻲ ﺑﻪ دو ﻛﻠﻴﺪ ﻣﺎوس ﻧﺴﺒﺖ داده ﻧﺸﺪه ﺑﻮد : ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻐﻴﻴﺮات زﻳﺮ را در اﻳﻦ ﻣﺘﺪ اﻳﺠﺎد ﻛﻨﻴﺪ.ﻛﻠﻴﺪ راﺳﺖ در ﻧﻈﺮ ﺑﮕﻴﺮد // Add a new color button to the control public void AddColor(Color newColor) { // Create the button ColorPaletteButton objColorPaletteButton = new ColorPaletteButton(newColor); // Add it to the list Buttons.Add(objColorPaletteButton); // do we have a button assigned // to the left button yet? if (LeftButton != null) { objColorPaletteButton.ButtonAssignment = ColorPaletteButton.ButtonAssignments.LeftButton; LeftButton = objColorPaletteButton; } else if(RightButton != null) // How about the right button { objColorPaletteButton.ButtonAssignment = ColorPaletteButton.ButtonAssignments.RightButton; RightButton = objColorPaletteButton;
٥٦٧
} } (7ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ رﻧﮓ اﻧﺘﺨﺎب ﺷﺪه ﺑﺮاي ﻛﻠﻴﺪﻫﺎي ﭼﭗ و راﺳﺖ ﻣﺎوس در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ وﺳﻴﻠﻪ ي ﺣﺮوف Lو ﻳﺎ Rﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ و ﺑﺎ ﺗﻐﻴﻴﺮ رﻧﮓ اﻧﺘﺨﺎﺑﻲ در ﭘﺎﻟﺖ رﻧﮓ ﻣﻜﺎن اﻳـﻦ ﺣـﺮوف ﻧﻴـﺰ ﺗﻐﻴﻴـﺮ ﻣـﻲ ﻛﻨـﺪ )ﺷﻜﻞ .(4-14
ﺷﻜﻞ 4-14
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اوﻟﻴﻦ ﻛﺎري ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ اﻧﺠﺎم ﻣﻲ دﻫﻴﻢ اﻳﻦ اﺳﺖ ﻛﻪ ﻳﻚ ﺷﻤﺎرﻧﺪه در ﻛﻼس ColorPaletteButton اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﻪ وﺳﻴﻠﻪ ي آن ﺑﺘﻮاﻧﻴﻢ وﺿﻌﻴﺖ ﻫﺮ دﻛﻤﻪ را ﺗﻌﻴﻴﻦ ﻛﻨﻴﻢ: // Public enumerations public enum ButtonAssignments { None = 0, LeftButton = 1, RightButton = 2 } ﻫﻤﺎﻧﻄﻮر ﻛﻪ در اﻋﻀﺎي اﻳﻦ ﺷﻤﺎرﻧﺪه ﻧﻴﺰ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﺪ ،رﻧﮓ ﻫﺮ دﻛﻤﻪ از ﭘﺎﻟﺖ رﻧﮓ ﻣﻲ ﺗﻮاﻧﺪ ﺳﻪ ﺣﺎﻟﺖ داﺷﺘﻪ ﺑﺎﺷﺪ :ﻳـﺎ ﺑـﻪ ﻫـﻴﭻ ﻳﻚ از ﻛﻠﻴﺪﻫﺎي ﻣﺎوس ﻧﺴﺒﺖ داده ﻧﺸﺪه ﺑﺎﺷﺪ ،ﻳﺎ ﺑﺮاي ﻛﻠﻴﺪ ﭼﭗ ﻣﺎوس در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه ﺑﺎﺷﺪ و ﻳﺎ ﺑﺮاي ﻛﻠﻴﺪ راﺳﺖ ﻣﺎوس در ﻧﻈـﺮ
٥٦٨
ﮔﺮﻓﺘﻪ ﺷﺪه ﺑﺎﺷﺪ .ﻋﻼوه ﺑﺮ اﻳﻦ ﻻزم اﺳﺖ ﻛﻪ دو ﻓﻴﻠﺪ ﻧﻴﺰ ﺑﻪ ﻛﻼس ColorPaletteاﺿﺎﻓﻪ ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﺑﻪ وﺳﻴﻠﻪ ي آﻧﻬﺎ در اﻳﻦ ﻛﻼس ﺗﺸﺨﻴﺺ دﻫﻴﻢ ﻛﻪ ﻛﺪاﻣﻴﻚ از دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد در ﭘﺎﻟﺖ رﻧﮓ ﺑﻪ ﻛﻠﻴﺪ ﭼﭗ و راﺳﺖ ﻣﺎوس ﻧﺴﺒﺖ داده ﺷﺪه اﻧﺪ .وﻇﻴﻔﻪ ي اﻳﻦ دو ﻓﻴﻠﺪ اﻳﻦ اﺳﺖ ﻛﻪ در ﻫﺮ ﻟﺤﻈﻪ ﻣﺸﺨﺺ ﻛﻨﻨﺪ ﻛﻪ ﭼﻪ دﻛﻤﻪ اي ﺑﺮاي ﻛﻠﻴﺪ ﭼﭗ ﻣﺎوس و ﭼﻪ دﻛﻤـﻪ اي ﺑـﺮاي ﻛﻠﻴـﺪ راﺳـﺖ ﻣﺎوس در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ. // Private members ;private ColorPaletteButton LeftButton ;private ColorPaletteButton RightButton اﺳﺘﻔﺎده از اﻳﻦ دو ﻓﻴﻠﺪ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ راﺣﺖ ﺗﺮ ﺑﺘﻮاﻧﻴﻢ دﻛﻤﻪ ي اﻧﺘﺨﺎب ﺷﺪه در ﭘﺎﻟﺖ رﻧﮓ را ﺗﻐﻴﻴﺮ دﻫﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ دﻳﮕﺮ ﻻزم ﻧﻴﺴﺖ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ رﻧﮓ ﻣﻮرد ﻧﻈﺮ ﺧﻮد را ﺗﻐﻴﻴﺮ داد در ﺑﻴﻦ ﺗﻤﺎم دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد در ﭘﺎﻟﺖ رﻧﮓ ﺣﺮﻛﺖ ﻛﺮده و ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ﻛﻪ ﺣﺮف Lو ﻳﺎ Rاز روي ﻛﺪاﻣﻴﻚ از اﻳﻦ دﻛﻤﻪ ﻫﺎ ﺑﺎﻳﺪ ﺣﺬف ﺷﻮد .ﺑﺮاي ﻣﺜﺎل ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺎ اﺳـﺘﻔﺎده از ﻛﻠﻴـﺪ ﭼـﭗ ﻣـﺎوس روي ﻳﻜﻲ از دﻛﻤﻪ ﻫﺎي ﻣﻮﺟﻮد در ﭘﺎﻟﺖ ﻛﻠﻴـﻚ ﻣـﻲ ﻛﻨـﺪ ،ﻛـﺎﻓﻲ اﺳـﺖ ﻛـﻪ ﺧﺎﺻـﻴﺖ ButtonAssignmentدﻛﻤـﻪ اي ﻛـﻪ LeftButtonﺑﻪ آن اﺷﺎره ﻣﻲ ﻛﻨﺪ را ﺑﺮاﺑﺮ ﺑﺎ ButtonAssignment.Noneﻗﺮار داده و رﻧﮓ اﻧﺘﺨـﺎﺑﻲ ﻛـﺎرﺑﺮ را در ﻓﻴﻠﺪ LeftButtonﻗﺮار دﻫﻴﻢ .ﺳﭙﺲ ﺧﺎﺻﻴﺖ ButtonAssignmentدر دﻛﻤﻪ اي ﻛﻪ ﺟﺪﻳﺪاً اﻧﺘﺨـﺎب ﺷـﺪه اﺳﺖ را ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎ ButtonAssignment.LeftButtonﻗﺮار دﻫﻴﻢ. ﺗﻨﻬﺎ ﻣﺘﺪي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻣﻤﻜﻦ اﺳﺖ ﻣﻘﺪاري ﮔﻴﺞ ﻛﻨﻨﺪه ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ ،ﻣﺘـﺪ ColorPalette_MouseUpاﺳـﺖ. در اﻳﻦ ﻣﺘﺪ ﻗﺒﻞ از اﻳﻨﻜﻪ دﻛﻤﻪ اي از ﭘﺎﻟﺖ رﻧﮓ را ﺑﺮاي ﻛﻠﻴﺪ ﭼﭗ ﻣﺎوس در ﻧﻈﺮ ﺑﮕﻴﺮﻳﻢ ،ﺑﺎﻳﺪ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ﻛﻪ آن دﻛﻤـﻪ ﺑـﺮاي ﻛﻠﻴـﺪ راﺳﺖ ﻣﺸﺨﺺ ﻧﺸﺪه ﺑﺎﺷﺪ. private void ColorPalette_MouseUp(object sender, )MouseEventArgs e { // Find the button that we clicked = ColorPaletteButton objColorPaletteButton ;)GetButtonAt(e.X, e.Y )if (objColorPaletteButton != null { ?// Was the left button was clicked )if (e.Button == MouseButtons.Left { // Make sure that this button is not // the current right button )if (objColorPaletteButton != RightButton { در اﻳﻦ ﺻﻮرت ﻣﻲ ﺗﻮاﻧﻴﻢ ﺧﺎﺻﻴﺖ LeftColorرا ﺑﺮاﺑﺮ ﺑﺎ رﻧﮓ دﻛﻤﻪ اي ﻛﻪ ﺗﻮﺳﻂ ﻛﺎرﺑﺮ اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ﻗﺮار دﻫﻴﻢ: // Set the color ;LeftColor = objColorPaletteButton.color
٥٦٩
ﺳﭙﺲ ﺑﺎﻳﺪ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ﻛﻪ آﻳﺎ ﻗﺒﻞ از اﻳﻦ ﻧﻴﺰ رﻧﮕﻲ ﺑﺮاي دﻛﻤﻪ ي ﭼﭗ ﻣﺎوس در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه ﺑﻮد ،ﻛﻪ در اﻳﻦ ﺻﻮرت ﺑﺎﻳﺪ ﺧﺎﺻﻴﺖ ButtonAssignmentآن را ﺑﻪ Noneﺑﺮﮔﺮداﻧﻴﻢ و ﻣﺘﺪ Invalidateرا ﺑﺮاي آن ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ ﺗﺎ ﺣـﺮف L از روي اﻳﻦ دﻛﻤﻪ از ﭘﺎﻟﺖ رﻧﮓ ﺣﺬف ﺷﻮد: // Clear the existing selection )if (RightButton != null { = RightButton.ButtonAssignment ;ColorPaletteButton.ButtonAssignments.None ;)this.Invalidate(RightButton.rectangle } ﻋــﻼوه ﺑــﺮ اﻳــﻦ ﺑﺎﻳــﺪ ﺧﺎﺻــﻴﺖ ButtonAssignmentدﻛﻤــﻪ اي ﻛــﻪ ﺟﺪﻳــﺪاً اﻧﺘﺨــﺎب ﺷــﺪه اﺳــﺖ را ﻧﻴــﺰ ﺑﺮاﺑــﺮ ﺑــﺎ LeftButtonﻗﺮار دﻫﻴﻢ و ﻣﺘﺪ Invalidateرا ﺑﺮاي آن ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻨﮕـﺎم ﺗﺮﺳـﻴﻢ ﻣﺠـﺪد ﻓـﺮم، ﺣﺮف Lﺑﺮ روي اﻳﻦ دﻛﻤﻪ از ﭘﺎﻟﺖ رﻧﮓ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﻫﻤﭽﻨﻴﻦ ﺑﺎﻳﺪ ﺧﺎﺻﻴﺖ LeftButtonرا ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑـﺎ دﻛﻤـﻪ اي ﻗﺮار دﻫﻴﺪ ﻛﻪ اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ﺗﺎ در ﻣﻮاﻗﻊ ﻧﻴﺎز ﺑﺘﻮاﻧﻴﻢ از آن اﺳﺘﻔﺎده ﻛﻨﻴﻢ: // Mark the button = objColorPaletteButton.ButtonAssignment ;ColorPaletteButton.ButtonAssignments.LeftButton ;)this.Invalidate(objColorPaletteButton.rectangle ;LeftButton = objColorPaletteButton در آﺧﺮ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ روﻳﺪاد LeftClickرا ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢ: // Raise the event ;))(LeftClick(this, new EventArgs ﺑﻘﻴﻪ ي ﻣﺘﺪ ColorPalette_MouseUpﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ اﻳﻦ ﻗﺴﻤﺖ اﺳﺖ ،ﺑﺎ اﻳﻦ ﺗﻔﺎوت ﻛـﻪ دﺳـﺘﻮرﻫﺎي آن ﺑـﺮاي ﻛﻠﻴـﺪ راﻳﺖ ﻣﺎوس اﻧﺠﺎم ﻣﻲ ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﻪ اﺑﺘﺪا ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ دﻛﻤﻪ اي ﻛﻪ ﺑﺮاي ﻛﻠﻴﺪ راﺳﺖ ﻣﺎوس اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ،ﺑﻪ ﻛﻠﻴـﺪ ﭼﭗ ﺗﻌﻠﻖ ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ ،در اﻳﻦ ﺻﻮرت رﻧﮓ اﻳﻦ دﻛﻤﻪ را ﺑﻪ ﺧﺎﺻﻴﺖ RightColorﻧﺴﺒﺖ ﻣﻲ دﻫﻴﻢ و …. ﺑﻌﺪ از اﺗﻤﺎم اﻳﻦ ﻣﺘﺪ ،ﺑﻪ ﻣﺘﺪ Drawدر ﻛﻼس ColorPaletteButtonﻣﻲ روﻳﻢ .در اﻳﻦ ﻣﺘﺪ ﺑﻌﺪ از رﺳﻢ ﻳﻚ دﻛﻤﻪ در ﭘﺎﻟﺖ رﻧﮓ ،ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ آﻳﺎ اﻳﻦ دﻛﻤﻪ ﺑﻪ ﻛﻠﻴﺪي از ﻣﺎوس ﻧﺴﺒﺖ داده ﺷﺪه اﺳﺖ و در اﻳﻦ ﺻﻮرت ﺣﺮﻓﻲ ﻣﺘﻨﺎﺳـﺐ ﺑـﺎ ﻛﻠﻴـﺪ ﻣﺎوس را روي اﻳﻦ دﻛﻤﻪ ﻣﻲ ﻧﻮﻳﺴﻴﻢ )در ﻣﻮرد ﺗﺮﺳﻴﻢ ﻣﺘﻦ در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ اﺧﺘﺼﺎر ﺗﻮﺿﻴﺢ داده ﺷﺪه اﺳﺖ ،اﻣـﺎ در ﻗـﺴﻤﺘﻬﺎي ﺑﻌـﺪي اﻳــﻦ ﻓــﺼﻞ در اﻳــﻦ ﻣــﻮرد ﺑﻴــﺸﺘﺮ ﺻــﺤﺒﺖ ﺧــﻮاﻫﻴﻢ ﻛــﺮد( .ﺑــﺮاي رﺳــﻢ ﻳــﻚ ﻣــﺘﻦ اﺑﺘــﺪا ﺑﺎﻳــﺪ ﺑــﺎ اﻳﺠــﺎد ﺷــﻴﺊ اي از ﻛــﻼس System.Drawing.Fontﻓﻮﻧﺖ ﻣﺘﻦ را ﻣﺸﺨﺺ ﻛﻨـﻴﻢ .در اﻳﻨﺠـﺎ ﻓـﻮﻧﺘﻲ از ﻧـﻮع verdanaﺑـﺎ اﻧـﺪازه ي 8و Boldاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ: // Draw the button ٥٧٠
public void Draw(Graphics graphics) { // Draw the color block SolidBrush objSolidBrush = new SolidBrush(color); graphics.FillRectangle(objSolidBrush, rectangle); // Draw an edge around the control Pen objPen = new Pen(Color.Black); graphics.DrawRectangle(objPen, rectangle); // Are you selected? if (ButtonAssignment != ButtonAssignments.None) { // Create a Font Font objFont = new Font("verdana", 80, FontStyle.Bold); :ﺳﭙﺲ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﭼﻪ ﺣﺮﻓﻲ ﺑﺎﻳﺪ روي اﻳﻦ دﻛﻤﻪ از ﭘﺎﻟﺖ رﻧﮓ ﻧﻤﺎﻳﺶ داده ﺷﻮد // Set the default button assignment String strButtonText = "L"; // Update the button assignment if necessary if (ButtonAssignment == ButtonAssignments.RightButton) { strButtonText = "R"; } در اﻳﻦ ﻗﺴﻤﺖ ﻧﻤﻲ ﺗﻮاﻧﻴﻢ از ﻳﻚ رﻧﮓ ﺛﺎﺑﺖ ﺑﺮاي ﻧﻮﺷـﺘﻦ ﻣـﺘﻦ.ﺣﺎﻻ ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻣﺘﻦ ﺑﺎ ﭼﻪ رﻧﮕﻲ ﻧﻮﺷﺘﻪ ﺷﻮد اﻳﻦ ﻣﺘﻦ روي رﻧﮕﻬﺎي روﺷﻦ ﺑﻪ درﺳﺘﻲ دﻳﺪه ﻧﻤـﻲ، زﻳﺮا ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻫﻤﻮاره ﻣﺘﻦ را ﺑﺎ اﺳﺘﻔﺎده از رﻧﮓ ﺳﻔﻴﺪ ﺑﻨﻮﻳﺴﻴﻢ.اﺳﺘﻔﺎده ﻛﻨﻴﻢ اﮔـﺮ رﻧـﮓ دﻛﻤـﻪ اي ﻛـﻪ ﻣـﻲ ﺧـﻮاﻫﻴﻢ روي آن. ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ دﻗﺖ ﻛﻨﻴﻢ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻣﺘﻦ را روي ﭼﻪ رﻧﮕﻲ ﻧﻤﺎﻳﺶ دﻫـﻴﻢ.ﺷﻮد : در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﺑﻬﺘﺮ اﺳﺖ رﻧﮓ ﺳﻔﻴﺪ را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﻢ،ﺑﻨﻮﻳﺴﻴﻢ روﺷﻦ ﺑﻮد ﺑﺎﻳﺪ از رﻧﮓ ﺳﻴﺎه اﺳﺘﻔﺎده ﻛﻨﻴﻢ // What brush do you if (color.R < 100 || { objSolidBrush = } else { objSolidBrush = }
want? color.B < 100 || color.G < 100) new SolidBrush(Color.White);
new SolidBrush(Color.Black);
:در آﺧﺮ ﻧﻴﺰ ﻣﺘﻦ را ﺑﺎ اﺳﺘﻔﺎده از ﺗﻨﻈﻴﻤﺎت ﻣﺸﺨﺺ ﺷﺪه در ﺻﻔﺤﻪ رﺳﻢ ﻣﻲ ﻛﻨﻴﻢ ٥٧١
"// Draw the text "L" or "R graphics.DrawString(strButtonText, objFont, objSolidBrush, rectangle.Left, ;)rectangle.Right } }
اﺳﺘﻔﺎده از رﻧﮕﻬﺎي ﺑﻴﺸﺘﺮ در ﺑﺮﻧﺎﻣﻪ: ﺗﺎﻛﻨﻮن ﺗﻤﺎم رﻧﮕﻬﺎﻳﻲ ﻛﻪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ ،رﻧﮕﻬﺎﻳﻲ ﺑﻮدﻧﺪ ﻛﻪ در ﭼـﺎرﭼﻮب .NETﺗﻌﺮﻳـﻒ ﺷـﺪه ﺑﻮدﻧـﺪ ﺑـﺮاي ﻣﺜـﺎل Color.Blackو ﻳﺎ .Color.Blueاﻟﺒﺘﻪ ﺗﻌﺪاد رﻧﮕﻬﺎﻳﻲ ﻛﻪ ﺑﻪ اﻳﻦ ﺻﻮرت در .NETوﺟﻮد دارﻧﺪ ﺑﺴﻴﺎر زﻳﺎد اﺳﺖ و ﺷﺎﻳﺪ در اﺑﺘﺪا ﻛﺎﻓﻲ ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ ،اﻣﺎ در ﺷﺮاﻳﻄﻲ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﻢ ﻛﻪ رﻧﮕﻲ را ﺧﻮدﻣﺎن ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨـﻴﻢ ﻛـﻪ در اﻳـﻦ ﻟﻴـﺴﺖ وﺟﻮد ﻧﺪارد. ﻧﻜﺘﻪ :ﺑﺮاي ﻣﺸﺎﻫﺪه ﻟﻴﺴﺖ ﺗﻤﺎم رﻧﮕﻬﺎﻳﻲ ﻛﻪ در .NETﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻗﺴﻤﺖ ” “All Membersﻣﺮﺑﻮط ﺑﻪ ” “Color Structureدر ﺳﻴﺴﺘﻢ راﻫﻨﻤﺎي MSDNﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ .ﻫﻤﭽﻨﻴﻦ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ در ﺣـﺎل ﻛـﺪ ﻧﻮﻳـﺴﻲ در وﻳﺮاﻳﺸﮕﺮ ﻛﺪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻫﺴﺘﻴﺪ ،ﺑﺎ وارد ﻛﺮدن ﻧﺎم ﺷﻤﺎرﻧﺪه ي Colorﺳﻴﺴﺘﻢ ﻫﻮﺷﻤﻨﺪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻟﻴﺴﺖ رﻧﮕﻬﺎي ﻣﻮﺟﻮد در اﻳﻦ ﺷﻤﺎرﻧﺪه را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. وﻳﻨﺪوز ﺑﺮاي ﻧﻤﺎﻳﺶ ﻳﻚ رﻧﮓ از ﻳﻚ ﻋﺪد 24ﺑﻴﺘﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ .اﻳﻦ ﻋﺪد ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﺷﺎﻣﻞ 3ﺑﺎﻳـﺖ ﻣـﻲ ﺷـﻮد و ﻫـﺮ ﺑﺎﻳﺖ آن ﺑﺮاي ﻧﻤﺎﻳﺶ ﻣﻘﺪار ﻳﻜﻲ از ﺳﻪ رﻧﮓ اﺻﻠﻲ )ﻗﺮﻣﺰ ،ﺳﺒﺰ،آﺑﻲ(در رﻧﮓ ﻣﻮرد ﻧﻈﺮ ﺑﻪ ﻛﺎر ﻣـﻲ رود – اﻳـﻦ روش ﻣﻌﻤـﻮﻻً ﺑـﻪ ﻧـﺎم "ﻣﺸﺨﺺ ﻛﺮدن رﻧﮓ ﺑﻪ ﺻﻮرت "RGB1ﺷﻨﺎﺧﺘﻪ ﺷﺪه اﺳﺖ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ ﻣﺸﺨﺺ ﻛﺮدن ﺳﻪ ﻋﺪد در ﺑﺎزه ي ﺻﻔﺮ ﺗـﺎ 255ﻣﻘﺪار ﻫﺮ ﻳﻚ از ﺳﻪ رﻧﮓ اﺻﻠﻲ را در رﻧﮓ ﻧﻬﺎﻳﻲ ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ و ﺑﺎ ﺗﺮﻛﻴﺐ اﻳﻦ ﻣﻘﺪار ﻫﺎ ﺑﻪ ﻳﻜﻲ از 16,7ﻣﻴﻠﻴﻮن رﻧﮕـﻲ ﻛـﻪ ﻣـﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ روش ﻧﻤﺎﻳﺶ داد دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﺑﺎ ﻗـﺮار دادن ﻋـﺪد 255ﺑـﺮاي Redو 0ﺑـﺮاي Greenو Blueﻣﻲ ﺗﻮاﻧﻴﺪ رﻧﮓ ﻗﺮﻣﺰ را اﻳﺠﺎد ﻛﻨﻴﺪ .ﻗﺮار دادن ﻫﺮ ﺳﻪ ﻣﻘﺪار ﺑﺎ ﻋﺪد ﺻﻔﺮ رﻧﮓ ﺳﻴﺎه و ﺗﻨﻈﻴﻢ آﻧﻬﺎ ﺑﺎ ﻋﺪد 255رﻧـﮓ ﺳـﻔﻴﺪ را ﻧﺘﻴﺠﻪ ﻣﻲ دﻫﺪ. ﺑﺮاي درك ﺑﻬﺘﺮ اﻳﻦ ﻣﻮﺿﻮع در ﻗﺴﻤﺖ ﺑﻌﺪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ رﻧﮓ دﻟﺨﻮاه ﺧﻮد را ﺑـﻪ ﺻـﻮرت دﺳـﺘﻲ اﻳﺠـﺎد ﻛﺮده و آن را در ﭘﺎﻟﺖ رﻧﮓ ﻗﺮار دﻫﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن رﻧﮕﻬﺎي دﻟﺨﻮاه (1ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻛﻨﺘﺮل ColorPaletteﺑﺮوﻳﺪ و ﺑﻌﺪ از ﻛﻠﻴﻚ ﻛﺮدن در ﻗﺴﻤﺖ ﺧﺎﻟﻲ از اﻳـﻦ ﻛﻨﺘـﺮل ،ﺧﺎﺻـﻴﺖ BackColorرا در ﭘﻨﺠﺮه ي Propertiesاﻧﺘﺨﺎب ﻛﻨﻴﺪ.
Red-Green-Blue
1
٥٧٢
(2 (3
(4 (5
در ﻟﻴﺴﺖ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﻪ ﻗﺴﻤﺖ Customﺑﺮوﻳﺪ و روي ﻳﻜﻲ از 16ﻣﺮﺑﻊ ﺳﻔﻴﺪ ﻣﻮﺟﻮد در ﭘﺎﻳﻴﻦ اﻳﻦ ﻗـﺴﻤﺖ ﻛﻠﻴﺪ راﺳﺖ ﻣﺎوس را ﻓﺸﺎر دﻫﻴﺪ. ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎدر Colorﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ .در اﻳﻦ ﻛﺎدر ﺑﺎ اﺳﺘﻔﺎده از ﻣﺎوس رﻧـﮓ ﻣـﻮرد ﻧﻈـﺮ ﺧـﻮد را اﻧﺘﺨـﺎب ﻛﻨﻴﺪ .در ﻗﺴﻤﺖ ﺳﻤﺖ راﺳﺖ ﭘﺎﻳﻴﻦ اﻳﻦ ﻓﺮم ﺳﻪ ﻛﺎدر ﻣﺘﻨـﻲ وﺟـﻮد دارﻧـﺪ ﻛـﻪ ﺑـﺎ ﻋﺒـﺎرات Green ،Redو Blue ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 5-14ﻣﺸﺨﺺ ﺷﺪه اﻧﺪ .اﻋﺪادي ﻛﻪ در اﻳﻦ ﺳﻪ ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ را ﻳﺎداﺷﺖ ﻛﻨﻴﺪ. ﻛﺎدر Define Colorرا ﺑﺒﻨﺪﻳﺪ. ﺑﺎ اﺳﺘﻔﺎده از وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس ColorPaletteﺑﻪ ﻗﺴﻤﺖ ﻣﺘﺪ ﺳﺎزﻧﺪه ي اﻳﻦ ﻛﻼس ﺑﺮوﻳﺪ .در ﻣﺘﺪ ﺳﺎزﻧﺪه ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ AddColorدﻛﻤﻪ ي دﻳﮕﺮي را ﻫﻤﺎﻧﻨﺪ ﻛﺪي ﻛﻪ در ﻗﺴﻤﺖ زﻳﺮ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﺑﻪ ﭘﺎﻟﺖ رﻧﮓ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .اﻟﺒﺘﻪ ﺳﻪ ﻋﺪدي ﻛﻪ ﻣﻦ در اﻳﻦ ﻗﺴﻤﺖ اﺳﺘﻔﺎده ﻛﺮده ام را ﺑﺎ ﺳﻪ ﻋﺪد ﻣﺮﺑﻮط ﺑﻪ رﻧﮓ اﻧﺘﺨﺎﺑﻲ ﺧـﻮد ﺗﻐﻴﻴـﺮ دﻫﻴﺪ )دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ اﻋﺪاد را ﺑﻪ ﺗﺮﺗﻴﺐ وارد ﻛﻨﻴﺪ :ﻋﺪد اول ﻣﺮﺑﻮط ﺑﻪ رﻧﮓ ﻗﺮﻣﺰ اﺳﺖ ،ﻋﺪد دوم ﻣﺮﺑﻮط ﺑﻪ رﻧﮓ ﺳﺒﺰ و ﻋـﺪد ﺳﻮم ﻧﻴﺰ ﻣﺮﺑﻮط ﺑﻪ رﻧﮓ آﺑﻲ اﺳﺖ(. )(public ColorPalette { ;)(InitializeComponent // Add the colors ;)AddColor(Color.Black ;)AddColor(Color.White ;)AddColor(Color.Red ;)AddColor(Color.Blue ;)AddColor(Color.Green ;)AddColor(Color.Gray ;)AddColor(Color.DarkRed ;)AddColor(Color.DarkBlue ;)AddColor(Color.DarkGreen ;)AddColor(Color.DarkGray ;))AddColor(Color.FromArgb(208, 112, 222 }
٥٧٣
ﺷﻜﻞ 5-14 (6ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ رﻧﮓ اﻧﺘﺨﺎﺑﻲ ﺷﻤﺎ ﻧﻴﺰ ﺑﻪ ﭘﺎﻟﺖ رﻧﮓ اﺿﺎﻓﻪ ﺷﺪه اﺳﺖ. ﻣﺘﺪ FromArgbﻳﻜﻲ از ﻣﺘﺪﻫﺎي اﺳﺘﺎﺗﻴﻚ ﻣﻮﺟﻮد در ﻛﻼس Colorاﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ از آن ﺑﺮاي ﺗﻌﺮﻳـﻒ رﻧﮕﻬـﺎي ﻣـﻮرد ﻧﻈﺮ ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
اﺳﺘﻔﺎده از ﻛﺎدر :Color ﻫﺮ ﻣﻘﺪار ﻛﻪ رﻧﮕﻬﺎي ﺑﻴﺸﺘﺮي را در اﺑﺘﺪاي ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺑﺎ ﭘﺎﻟﺖ رﻧﮓ اﺿﺎﻓﻪ ﻛﻨﻴﺪ ،ﺑﺎز ﻫﻢ ﻣﻤﻜﻦ اﺳﺖ ﻛـﺎرﺑﺮ ﺑﺨﻮاﻫـﺪ از رﻧﮕﻲ اﺳﺘﻔﺎده ﻛﻨﺪ ﻛﻪ در ﭘﺎﻟﺖ وﺟﻮد ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ .ﺑﻬﺘﺮﻳﻦ روش ﺑﺮاي اﻳﻨﻜﻪ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﻴﻢ از ﻫﺮ رﻧﮕﻲ ﻛـﻪ ﺗﻤﺎﻳـﻞ دارد اﺳـﺘﻔﺎده ﻛﻨﺪ ،اﻳﻦ اﺳﺖ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻛﺎدر ) Colorﻛﻪ در ﻓﺼﻞ ﻫﻔﺘﻢ ﺑﺎ آن آﺷﻨﺎ ﺷﺪﻳﻢ( را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﻢ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ ﺧﻮاﻫﻴﻢ داد ﻛﻪ ﻛﺎرﺑﺮ ﺑﺘﻮاﻧﺪ رﻧﮓ ﻣﻮرد ﻧﻈﺮ ﺧﻮد را ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺎدر ﻣﺤﺎوره اي Colorاﻧﺘﺨﺎب ﻛﻨﺪ.
اﻧﺘﺨﺎب ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از ﻛﺎدر Colorدر ﺑﺮﻧﺎﻣﻪ
٥٧٤
(1ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓـﺮم ﻣﺮﺑـﻮط ﺑـﻪ ﻛﻨﺘـﺮل ColorPaletteﺑﺮوﻳـﺪ و ﺑـﺎ اﺳـﺘﻔﺎده از ﺟﻌﺒـﻪ اﺑـﺰار ،ﻳـﻚ ﻛﻨﺘـﺮل ColorDialogرا ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺳﭙﺲ ﺧﺎﺻﻴﺖ Nameﻛﻨﺘﺮل را ﺑﺮاﺑـﺮ ﺑـﺎ dlgColorﻗـﺮار دﻫﻴﺪ. (2ﺣﺎل ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻛﻼس ColorPaletteﺑﺮوﻳﺪ و ﻣﺘﺪ ColorPalette_MouseUp در اﻳﻦ ﻗﺴﻤﺖ را ﭘﻴﺪا ﻛﻨﻴﺪ .ﻣﻲ ﺧﻮاﻫﻴﻢ اﻳﻦ ﻣﺘﺪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﻛﻪ اﮔﺮ ﻛﺎرﺑﺮ در ﻧﺎﺣﻴﻪ اي از اﻳﻦ ﻛﻨﺘـﺮل ﻛﻠﻴـﻚ ﻛﺮد ﻛﻪ ﻫﻴﭻ دﻛﻤﻪ اي از ﭘﺎﻟﺖ وﺟﻮد ﻧﺪاﺷﺖ )ﺑﻪ ﻋﺒـﺎرت دﻳﮕـﺮ روي ﻫـﻴﭻ دﻛﻤـﻪ اي از ﭘﺎﻟـﺖ ﻛﻠﻴـﻚ ﻧﻜـﺮده ﺑـﻮد( ،ﻛـﺎدر Colorرا ﻧﻤﺎﻳﺶ دﻫﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﺪ رﻧﮓ دﻟﺨﻮاه ﺧﻮد را ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻦ ﻛﺎدر ﺑﻪ ﭘﺎﻟﺖ رﻧﮓ اﺿﺎﻓﻪ ﻛﻨﺪ .ﺑﻪ ﻗﺴﻤﺖ اﻧﺘﻬـﺎي اﻳﻦ ﻣﺘﺪ ﺑﺮوﻳﺪ و ﻳﻚ ﻋﺒﺎرت elseﺑﻪ ﻫﻤﺮاه ﻛﺪي ﻛﻪ در زﻳﺮ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ را ﺑﻪ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void ColorPalette_MouseUp(object sender, )MouseEventArgs e { // Find the button that we clicked = ColorPaletteButton objColorPaletteButton ;)GetButtonAt(e.X, e.Y )if (objColorPaletteButton != null { … // Raise the event ;))(RightClick(this, new EventArgs } } } else { // Display the Color dialog )if (dlgColor.ShowDialog() == DialogResult.OK { // Add the new color ;)AddColor(dlgColor.Color // Resize the palette to show the color ;))(OnResize(new EventArgs } } } (3ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و روي ﻗﺴﻤﺘﻲ ﺧﺎﻟﻲ از ﭘﺎﻟﺖ رﻧﮓ ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .ﻣـﺸﺎﻫﺪه ﻣـﻲ ﻛﻨﻴـﺪ ﻛـﻪ ﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ 6-14ﻛـﺎدر Colorﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و ﻣﻲ ﺗﻮاﻧﻴﺪ رﻧﮓ ﻣﻮرد ﻧﻈﺮ ﺧﻮد را ﺑﻪ ﭘﺎﻟﺖ اﺿﺎﻓﻪ ﻛﻨﻴﺪ.
٥٧٥
ﺷﻜﻞ 6-14
اﺳﺘﻔﺎده از رﻧﮕﻬﺎي ﺳﻴﺴﺘﻤﻲ: ﺗﺎﻛﻨﻮن ﻧﺤﻮه ي اﺳﺘﻔﺎده از رﻧﮕﻬﺎي ﺗﻌﺮﻳﻒ ﺷﺪه در .NETو ﻫﻤﭽﻨﻴﻦ اﺳﺘﻔﺎده از رﻧﮕﻬﺎي ﻣﻮرد ﻧﻈـﺮ ﺧﻮدﺗـﺎن را در ﺑﺮﻧﺎﻣـﻪ ﻣـﺸﺎﻫﺪه ﻛﺮدﻳﺪ .ﻣﻮرد آﺧﺮي ﻛﻪ ﺑﺎﻳﺪ در ﻣﻮرد رﻧﮕﻬﺎ ﺑﺪاﻧﻴﺪ ،اﺳﺘﻔﺎده از رﻧﮕﻬﺎي ﺳﻴﺴﺘﻤﻲ در ﺑﺮﻧﺎﻣﻪ اﺳﺖ. در ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ وﻳﻨﺪوز اﻳﻦ اﻣﻜﺎن ﺑﺮاي ﻛﺎرﺑﺮ وﺟﻮد دارد ﻛﻪ رﻧﮓ ﻫﺮ ﻗﺴﻤﺘﻲ ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﺪ را ﺑﻪ ﮔﻮﻧﻪ اي دﻟﺨﻮاه ﺗﻐﻴﻴـﺮ دﻫـﺪ، ﺑﺮاي ﻣﺜﺎل رﻧﮓ دﻛﻤﻪ ﻫﺎ ،رﻧﮓ ﻣﻨﻮ ﻫﺎ ،رﻧﮓ ﻧﻮار ﻋﻨﻮان و ﻳﺎ … را ﺑﻪ رﻧﮓ دﻟﺨﻮاه ﺧﻮد در آورد .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ اﮔـﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻳﻚ راﺑﻂ ﮔﺮاﻓﻴﻜﻲ ﺑﺮاي ﻛﻨﺘﺮل ﺧﻮد ﻃﺮاﺣﻲ ﻛﻨﻴﺪ ،ﺑﻬﺘﺮ اﺳﺖ اﻳﻦ ﻧﻜﺘﻪ را در ﻧﻈـﺮ داﺷـﺘﻪ ﺑﺎﺷـﻴﺪ ﻛـﻪ از ﻳـﻚ ﺳﻴـﺴﺘﻢ ﺑـﻪ ﺳﻴﺴﺘﻢ دﻳﮕﺮ ﻣﻤﻜﻦ اﺳﺖ رﻧﮓ ﻛﻨﺘﺮل ﻫﺎ ﻛﺎﻣﻼً ﺗﻐﻴﻴﺮ ﻛﻨﺪ )ﺑﺮاي ﻣﺜﺎل ﻣﻤﻜﻦ اﺳﺖ ﻛﺎرﺑﺮي وﻳﻨﺪوز را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻨﻈﻴﻢ ﻛﻨﺪ ﺗـﺎ رﻧـﮓ دﻛﻤﻪ ﻫﺎ ﺑﻪ رﻧﮓ آﺑﻲ ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ( ،ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ ﻇﺎﻫﺮ ﻛﻨﺘﺮل ﺧﻮد را ﺑﻪ ﮔﻮﻧﻪ اي ﻃﺮاﺣﻲ ﻛﻨﻴﺪ ﻛﻪ ﺑﺮ اﺳﺎس ﻇﺎﻫﺮ ﺳﻴـﺴﺘﻤﻲ ﻛـﻪ در آن ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد ﺗﻐﻴﻴﺮ ﻛﻨﺪ. ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﺪ از رﻧﮕﻬﺎي ﺳﻴﺴﺘﻤﻲ ﻛﻪ در .NETﺗﻌﺮﻳﻒ ﺷﺪه اﻧﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ رﻧﮕﻬﺎي ﺳﻴـﺴﺘﻤﻲ ﺑﺎﻳـﺪ ﻛﻼس System.Drawing.SystemColorsرا ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ .ﺑﺮاي ﻣﺸﺎﻫﺪه ي ﻟﻴﺴﺘﻲ از ﺗﻤﺎم رﻧﮕﻬﺎي ﺳﻴﺴﺘﻤﻲ ﻣﻮﺟﻮد در اﻳﻦ ﻛﻼس ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻗﺴﻤﺖ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛﻼس در ﺳﻴﺴﺘﻢ راﻫﻨﻤﺎي MSDNاﺳﺘﻔﺎده ﻛﻨﻴـﺪ .ﻫﻤﭽﻨـﻴﻦ ﺑـﺎ اﺳـﺘﻔﺎده از اﺑﺰار Object Browserو ﻳﺎ وﻳﮋﮔﻲ ﻫﻮﺷﻤﻨﺪي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻫﻨﮕﺎم ﻛﺪ ﻧﻮﻳﺴﻲ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻟﻴﺴﺖ رﻧﮕﻬﺎي ﻣﻮﺟـﻮد در اﻳﻦ ﻗﺴﻤﺖ را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،رﻧﮕﻲ را ﺑﻪ ﭘﺎﻟﺖ رﻧﮓ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻫﻢ رﻧﮓ ﻧﻮار ﻣﻨﻮي ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﺎﺷﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از رﻧﮕﻬﺎي ﺳﻴﺴﺘﻤﻲ ٥٧٦
(1وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس ColorPaletteرا ﺑﺎز ﻛﺮده و ﺑﻪ ﻣﺘﺪ ﺳﺎزﻧﺪه ي اﻳﻦ ﻛـﻼس ﺑﺮوﻳـﺪ .ﺳـﭙﺲ ﻛـﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )(public ColorPalette { ;)(InitializeComponent // Add the colors ;)AddColor(Color.Black ;)AddColor(Color.White ;)AddColor(Color.Red ;)AddColor(Color.Blue ;)AddColor(Color.Green ;)AddColor(Color.Gray ;)AddColor(Color.DarkRed ;)AddColor(Color.DarkBlue ;)AddColor(Color.DarkGreen ;)AddColor(Color.DarkGray ;))AddColor(Color.FromArgb(208, 112, 222 ;)AddColor(SystemColors.MenuBar } (2ﺑﺎ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ رﻧﮓ ﺟﺪﻳﺪي ،ﻫﻤﺮﻧﮓ ﺑﺎ ﻧﻮار ﻣﻨﻮي وﻳﻨﺪوز ﺑﻪ ﭘﺎﻟﺖ رﻧﮓ اﺿﺎﻓﻪ ﺷﺪه اﺳﺖ.
اﺳﺘﻔﺎده از اﺑﺰارﻫﺎي ﻣﺘﻔﺎوت: ﺣﺎﻻ ﻛﻪ ﺗﻮاﻧﺴﺘﻴﻢ ﺑﺎ ﻣﻮﻓﻘﻴﺖ اﺳﺘﻔﺎده از اﺑﺰار داﻳﺮه ي ﺗﻮﭘﺮ را ﺑﻪ ﻫﻤﺮاه ﺗﻤﺎم اﻣﻜﺎﻧﺎت ﻻزم ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﺗﻮﺟﻪ ﺧﻮد را روي اﺿﺎﻓﻪ ﻛﺮدن اﺑﺰارﻫﺎي دﻳﮕﺮ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻗﺮار دﻫﻴﻢ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﻧﻮار ﻣﻨﻮﻳﻲ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آن ﻣﻲ ﺗﻮاﻧﻴﺪ اﺑﺰار ﻣﻮرد اﺳﺘﻔﺎده در ﺑﺮﻧﺎﻣﻪ را اﻧﺘﺨﺎب ﻛﻨﻴﺪ. ﻧﻜﺘﻪ :ﺑﺮاي ﺗﻜﻤﻴﻞ اﻳﻦ ﺑﺨﺶ از ﺑﺮﻧﺎﻣﻪ ﻻزم اﺳﺖ ﻛﻪ ﻳﻚ ﻧﻮار ﻣﻨﻮ ﺑﻪ ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ ﻛﻨـﻴﻢ .اﮔـﺮ اﺣـﺴﺎس ﻣـﻲ ﻛﻨﻴـﺪ در اﺳـﺘﻔﺎده از ﻛﻨﺘﺮﻟﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﻧﻮار ﻣﻨﻮ ﻣﺸﻜﻠﻲ دارﻳﺪ ،ﺑﻪ ﻓﺼﻞ ﻫﺸﺘﻢ ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﻣﻨﻮ ﺑﻪ ﺑﺮﻧﺎﻣﻪ (1ﺑﻪ ﻗـﺴﻤﺖ ﻃﺮاﺣـﻲ ﻓـﺮم ﻣﺮﺑـﻮط ﺑـﻪ Form1ﺑﺮوﻳـﺪ و ﺧﺎﺻـﻴﺖ Anchorﻛﻨﺘـﺮل PaintCanvasرا ﺑـﻪ Left, Right, Bottomﺗﻐﻴﻴﺮ دﻫﻴﺪ.
٥٧٧
(2 (3
(4
(5
(6
ﺣﺎل ﺑﺮ روي ﻧﻮار ﻋﻨﻮان ﻓﺮم ﻛﻠﻴﻚ ﻛﺮده ﺗﺎ ﻓﺮم اﻧﺘﺨﺎب ﺷﻮد ،ﺳﭙﺲ اﻧﺪازه ي آن را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ ﺑﺘﻮاﻧﻴﺪ ﻳـﻚ ﻛﻨﺘﺮل MenuStripرا در ﺑﺎﻻي آن ﻗﺮار دﻫﻴﺪ. ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﺑـﻪ ﻗـﺴﻤﺖ Menus & Toolbarsﺑﺮوﻳـﺪ و روي ﻛﻨﺘـﺮل MenuStripدو ﺑـﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻳﻚ ﻧﻤﻮﻧﻪ از اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﻧﺎم MenuStrip1در ﭘﺎﻳﻴﻦ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻗﺮار ﺧﻮاﻫـﺪ ﮔﺮﻓﺖ .روي اﻳﻦ ﻛﻨﺘﺮل ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و در ﻣﻨﻮﻳﻲ ﻛـﻪ ﺑـﺎز ﻣـﻲ ﺷـﻮد ﮔﺰﻳﻨـﻪ ي Insert Standard Itemsرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ. در ﺻﻮرت ﻟﺰوم اﻧﺪازه ي ﻓﺮم را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ ﻛﻨﺘﺮل PaintCanvasدﻗﻴﻘﺎً ﭘﺎﻳﻴﻦ ﻧﻮار ﻣﻨﻮ ﻗﺮار ﺑﮕﻴـﺮد. ﺳﭙﺲ ﻛﻨﺘﺮل PaintCanvasرا اﻧﺘﺨﺎب ﻛﺮده و ﺧﺎﺻﻴﺖ Anchorآن را ﻣﺠـﺪداً ﺑـﻪ Top, Left, Bottom, Rightﺑﺮﮔﺮداﻧﻴﺪ. ﺣﺎل ﺑﻪ ﻣﻨﻮي Toolsدر ﻛﻨﺘﺮل MenuStrip1ﺑﺮوﻳﺪ و در اﻳﻦ ﻣﻨـﻮ ،در ﻛـﺎدر ﺳـﻔﻴﺪ ﭘـﺎﻳﻴﻦ ﻣﻨـﻮ ﻛـﻪ ﻋﺒـﺎرت Type Hereدر آن ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ ﻛﻠﻴﻚ ﻛﺮده و ﻋﺒﺎرت &Circleرا در اﻳﻦ ﻗﺴﻤﺖ وارد ﻛﻨﻴﺪ ﺗﺎ ﮔﺰﻳﻨـﻪ ي ﺟﺪﻳﺪي ﺑﻪ ﻣﻨﻮي Toolsاﺿﺎﻓﻪ ﺷﻮد .ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي Propertiesﺧﺎﺻﻴﺖ Checkedآن را ﺑﻪ Trueو ﺧﺎﺻﻴﺖ CheckOnClickرا ﻧﻴﺰ ﺑﻪ Trueﺗﻐﻴﻴﺮ دﻫﻴﺪ. در ﻛﺎدر Type Hereﺑﻌﺪي در ﭘﺎﻳﻴﻦ ﮔﺰﻳﻨﻪ ي Circleﻛﻠﻴﻚ ﻛﺮده و ﻋﺒـﺎرت &Hollow Circle را در آن وارد ﻛﻨﻴﺪ .ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي Propertiesﺧﺎﺻﻴﺖ CheckOnClickاﻳـﻦ ﮔﺰﻳﻨـﻪ را ﺑﺮاﺑﺮ ﺑﺎ Trueﻗﺮار دﻫﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 7-14ﺷﺪه ﺑﺎﺷﺪ.
ﺷﻜﻞ 7-14
اﺳﺘﻔﺎده از داﻳﺮه ﻫﺎي ﺗﻮﺧﺎﻟﻲ:
٥٧٨
در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﺑﺮاي ﺗﺮﺳﻴﻢ ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺴﺘﻴﻢ از داﻳﺮه ﻫﺎي ﺗﻮﭘﺮ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﺑﺮﻧﺎﻣـﻪ را ﺑـﻪ ﮔﻮﻧـﻪ اي ﺗﻐﻴﻴﺮ ﺧﻮاﻫﻴﻢ داد ﻛﻪ ﺑﺘﻮاﻧﻴﻢ اﺑﺰار ﻣﻮرد اﺳﺘﻔﺎده ﺑﺮاي ﺗﺮﺳﻴﻢ ﻳﻚ ﺷﻜﻞ را ﺗﻌﻴﻴﻦ ﻛﻨﻴﻢ .ﺑﺮاي ﻣﺜﺎل از ﻗﻠﻤﻲ ﺑﻪ ﺷـﻜﻞ داﻳـﺮه ﻫـﺎي ﺗـﻮﭘﺮ اﺳﺘﻔﺎده ﻛﻨﻴﻢ و ﻳﺎ ﻗﻠﻤﻲ ﺑﻪ ﺷﻜﻞ داﻳﺮه ﻫﺎي ﺗﻮﺧﺎﻟﻲ را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺳﺘﻔﺎده از داﻳﺮه ﻫﺎي ﺗﻮﺧﺎﻟﻲ (1اوﻟﻴﻦ ﻛﺎري ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ اﻧﺠـﺎم دﻫـﻴﻢ اﻳـﻦ اﺳـﺖ ﻛـﻪ ﺷـﻤﺎرﻧﺪه ي GraphicToolsﻛـﻪ در ﻛـﻼس PaintCanvasﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﻛﻪ ﺷﺎﻣﻞ اﺑﺰاري ﺑﺮاي داﻳـﺮه ي ﺗﻮﺧـﺎﻟﻲ ﻧﻴـﺰ ﺑـﺸﻮد. ﺑﻨﺎﺑﺮاﻳﻦ ﺑـﻪ ﻗـﺴﻤﺖ وﻳﺮاﻳـﺸﮕﺮ ﻛـﺪ ﻣﺮﺑـﻮط ﺑـﻪ ﻛـﻼس PaintCanvasﺑﺮوﻳـﺪ و ﺗﻐﻴﻴـﺮ زﻳـﺮ را در ﺷـﻤﺎرﻧﺪه ي PaintCanvasاﻳﺠﺎد ﻛﻨﻴﺪ: public partial class PaintCanvas : UserControl { public enum GraphicTools { CirclePen = 0, HollowCirclePen = 1 } (2ﺑـــﻪ ﻗـــﺴﻤﺖ ﻃﺮاﺣـــﻲ ﻓـــﺮم ﻣﺮﺑـــﻮط ﺑـــﻪ Form1ﺑﺮوﻳـــﺪ و در ﻧـــﻮار ﻣﻨـــﻮي ﺑـــﺎﻻي ﻓـــﺮم ،روي ﻛﻨﺘـــﺮل circleToolStripMenuItemدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickاﻳﻦ ﻛﻨﺘﺮل اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void circleToolStripMenuItem_Click(object sender, )EventArgs e { // Set the tool = Canvas.GraphicTool ;PaintCanvas.GraphicTools.CirclePen // Uncheck the Hollow Circle menu item ;hollowCircleToolStripMenuItem.Checked = false } (3ﺣـــــﺎل ﻣﺠـــــﺪداً ﺑـــــﻪ ﻗـــــﺴﻤﺖ ﻃﺮاﺣـــــﻲ ﻓـــــﺮم ﻣﺮﺑـــــﻮط ﺑـــــﻪ Form1ﺑﺮﮔـــــﺸﺘﻪ و روي ﻛﻨﺘـــــﺮل hollowCircleToolStripMenuItemدر ﻣﻨﻮي Toolsدر ﻧﻮار ﻣﻨـﻮي ﺑـﺎﻻي ﻓـﺮم دو ﺑـﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickاﻳﻦ ﻛﻨﺘﺮل اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳـﻦ ﻣﺘـﺪ وارد ﻛﻨﻴﺪ: (private void hollowCircleToolStripMenuItem_Click )object sender, EventArgs e
٥٧٩
{ // Set the tool Canvas.GraphicTool = PaintCanvas.GraphicTools.HollowCirclePen; // Uncheck the Circle menu item circleToolStripMenuItem.Checked = false; } در ﻣﻨـﻮيExit اﻣﺎ ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﮔﺰﻳﻨﻪ ي،( ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﮔﺰﻳﻨﻪ ﻫﺎي دﻳﮕﺮ ﻧﻮار ﻣﻨﻮ را ﻧﻴﺰ ﺗﻜﻤﻴﻞ ﻛﻨﻴﻢ4 ﭘﺲ در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم روي اﻳﻦ ﮔﺰﻳﻨـﻪ دو ﺑـﺎر. را ﻧﻴﺰ وارد ﻛﻨﻴﻢ ﺗﺎ در ﺑﺮﻧﺎﻣﻪ ﺑﺘﻮاﻧﻴﻢ از اﻳﻦ ﻣﻨﻮ اﺳﺘﻔﺎده ﻛﻨﻴﻢFile : ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﻨﻮ اﺿﺎﻓﻪ ﻛﻨﻴﺪ. آن اﻳﺠﺎد ﺷﻮدClick ﻛﻠﻴﻚ ﻛﺮده ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد private void exitToolStripMenuItem_Click(object sender, EventArgs e) { // Close the application this.Close(); } را ﻣﺠــــﺪداً ﺑــــﺎز ﻛــــﺮده و دﺳــــﺘﻮرات ﻣﻮﺟــــﻮد در ﺑــــﻼكPaintCanvas ( وﻳﺮاﻳــــﺸﮕﺮ ﻛــــﺪ ﻛــــﻼس5 . ا ﺑﻪ ﺻﻮرت ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪDoMousePaint در ﻣﺘﺪswitch(GraphicTool) // What tool are you using? switch(GraphicTool) { // CirclePen case GraphicTools.CirclePen: } // Create a new graphics circle GraphicsCircle objGraphicsCircle = new GraphicsCircle(); // Set the point for drawing objGraphicsCircle.SetPoint(e.X, e.Y, (int)GraphicSize, objColor, true); // Store this for addition objGraphicsItem = objGraphicsCircle; break; } // HollowCirclePen case GraphicTools.HollowCirclePen: { // Create a new graphics circle ٥٨٠
GraphicsCircle objGraphicsCircle = new GraphicsCircle(); // Set the point for drawing objGraphicsCircle.SetPoint(e.X, e.Y, (int)GraphicSize, objColor, false); // Store this for addition objGraphicsItem = objGraphicsCircle; break; } } را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﻛﻪ ﺗـﺸﺨﻴﺺ دﻫـﺪ ﭼـﻪGraphicsCircle در ﻛﻼسDraw ( ﺑﻌﺪ از اﻳﻦ ﺑﺎﻳﺪ ﻣﺘﺪ6 ﺑﻨـﺎﺑﺮاﻳﻦ وﻳﺮاﻳـﺸﮕﺮ ﻛـﺪ ﻛـﻼس.ﻣﻮاﻗﻌﻲ ﺑﺎﻳﺪ داﻳﺮه ي ﺗﻮﺧﺎﻟﻲ رﺳﻢ ﻛﻨـﺪ و ﭼـﻪ ﻣـﻮاﻗﻌﻲ ﺑﺎﻳـﺪ داﻳـﺮه ي ﺗـﻮﭘﺮ رﺳـﻢ ﻛﻨـﺪ : اﻳﺠﺎد ﻛﻨﻴﺪDraw را ﺑﺎز ﻛﺮده و ﺗﻐﻴﻴﺮات زﻳﺮ را در ﻣﺘﺪGraphicsCircle public override void Draw(Graphics graphics) { if (IsFilled) { // Create a new pen SolidBrush objSolidBrush = new SolidBrush(this.color); // Draw the circle graphics.FillEllipse(objSolidBrush, this.rectangle); } else { // Create a pen Pen pen = new Pen(this.color); // Use DrawEllipse instead Rectangle objRectangle = this.rectangle; objRectangle.Inflate(-1, -1); graphics.DrawEllipse(pen, objRectangle); } } اﺑـﺰار ﮔﺮاﻓﻴﻜـﻲ ﻛـﻪ ﻣـﻲ ﺧﻮاﻫﻴـﺪ از آنTools ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳـﺘﻔﺎده از ﻣﻨـﻮي.( ﺣﺎﻻ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ7 .(8-14 اﺳﺘﻔﺎده ﻛﻨﻴﺪ را اﻧﺘﺨﺎب ﻛﺮده و رﺳﻢ ﺷﻜﻞ را ﺑﺎ آن اﺑﺰار اﻧﺠﺎم دﻫﻴﺪ )ﺷﻜﻞ
٥٨١
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي ﻛﻲ از اﺑﺰارﻫﺎي ﻣﻮﺟﻮد در ﻣﻨﻮي Toolsﻛﻠﻴﻚ ﻣﻲ ﻛﻨﺪ ،روﻳﺪاد Clickآن اﺑﺰار ﻓﺮاﺧـﻮاﻧﻲ ﻣـﻲ ﺷـﻮد. ﻫﻨﮕﺎم ﻓﺮاﺧﻮاﻧﻲ اﻳﻦ روﻳﺪاد اﺑﺘﺪا ﺑﺎﻳﺪ ﺧﺎﺻﻴﺖ GraphicToolدر ﻛﻨﺘﺮل PaintCanvasرا ﺑﺮاﺑﺮ ﺑﺎ اﺑﺰار اﻧﺘﺨﺎب ﺷﺪه ﻗﺮار دﻫﻴﻢ ،ﺳﭙﺲ ﺑﺎﻳﺪ ﻋﻼﻣﺖ ﺗﻴﻚ ﻛﻨﺎر اﻳﻦ ﮔﺰﻳﻨﻪ ﻫﺎ در ﻧﻮار ﻣﻨﻮ را ﺗﺼﺤﻴﺢ ﻛﻨﻴﻢ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﮔﺰﻳﻨﻪ اﻧﺘﺨﺎب ﺷﻮد ،ﻋﻼﻣﺖ ﺗﻴﻚ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ در ﻛﻨﺎر آن ﻗﺮار ﻣﻲ ﮔﻴﺮد اﻣﺎ ﻋﻼﻣﺖ ﺗﻴﻚ ﻛﻪ در ﻛﻨﺎر ﮔﺰﻳﻨﻪ ي ﻗﺒﻠﻲ ﻗﺮار داﺷﺘﻪ اﺳﺖ ﺑﺮداﺷﺘﻪ ﻧﻤﻲ ﺷﻮد .ﺑﻨـﺎﺑﺮاﻳﻦ در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickﻫﺮ ﮔﺰﻳﻨﻪ ،ﺑﺎﻳﺪ اﻳﻦ ﻋﻼﻣﺖ را ﺑﻪ ﺻﻮرت دﺳﺘﻲ از ﻛﻨﺎر ﮔﺰﻳﻨﻪ ي دﻳﮕﺮ ﺣﺬف ﻛﻨﻴﻢ: (private void hollowCircleToolStripMenuItem_Click )object sender, EventArgs e { // Set the tool = Canvas.GraphicTool ;PaintCanvas.GraphicTools.HollowCirclePen // Uncheck the Circle menu item ;circleToolStripMenuItem.Checked = false }
ﺷﻜﻞ 8-14 ﺻﺮﻓﻨﻈﺮ از ﻧﻮع اﺑﺰاري ﻛﻪ ﺑﺮاي ﺗﺮﺳﻴﻢ اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﺷﺎره ﮔﺮ ﻣﺎوس ﺑﺨﻮاﻫﺪ ﺑﺎ ﺣﺮﻛﺖ روي ﺻﻔﺤﻪ ﺷﻜﻠﻲ را ﺗﺮﺳﻴﻢ ﻛﻨﺪ ﻣﺘﺪ DoMousePaintاز ﻛﻼس PaintCanvasﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﻗﺴﻤﺖ switchاﻳﻦ ﻣﺘﺪ را ﺑﺎﻳﺪ ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﻛﻪ ﺑﺴﺘﻪ ﺑﻪ اﺑﺰاري ﻛﻪ اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ،ﺷﻜﻞ ﻣﻨﺎﺳﺒﻲ را اﻳﺠﺎد ﻛﺮده و ﺑﻪ آراﻳﻪ ي اﺟﺰاي ﺗﺸﻜﻴﻞ دﻫﻨﺪه
٥٨٢
و اﮔﺮ ﺑﺨﻮاﻫﻴﻢtrue ﻳﻚ داﻳﺮه ي ﺗﻮﺧﺎﻟﻲ رﺳﻢ ﺷﻮد ﺑﺎﻳﺪ ﭘﺎراﻣﺘﺮ، اﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﺑﺎ ﻫﺮ ﺑﺎر ﻛﻠﻴﻚ ﻛﺮدن روي ﻓﺮم.ي ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﺪ . ﺑﻔﺮﺳﺘﻴﻢSetPoint را ﺑﻪ ﻣﺘﺪfalse ﻳﻚ داﻳﺮه ي ﺗﻮﭘﺮ رﺳﻢ ﺷﻮد ﺑﺎﻳﺪ ﭘﺎراﻣﺘﺮ switch(GraphicTool) { // CirclePen case GraphicTools.CirclePen: } // Create a new graphics circle GraphicsCircle objGraphicsCircle = new GraphicsCircle(); // Set the point for drawing objGraphicsCircle.SetPoint(e.X, e.Y, (int)GraphicSize, objColor, true); // Store this for addition objGraphicsItem = objGraphicsCircle; break; } // HollowCirclePen case GraphicTools.HollowCirclePen: { // Create a new graphics circle GraphicsCircle objGraphicsCircle = new GraphicsCircle(); // Set the point for drawing objGraphicsCircle.SetPoint(e.X, e.Y, (int)GraphicSize, objColor, false); // Store this for addition objGraphicsItem = objGraphicsCircle; break; } } ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﺑﺎﻳﺪ داﻳﺮهSetPoint ﻛﻪ ﺑﻪ ﻣﺘﺪgraphicIsFilled ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﺎراﻣﺘﺮ ﺷﺮﻃﻲ را ﻗﺮار ﻣﻲ دﻫﻴﻢGraphicsCircle در ﻛﻼسDraw ﺑﻨﺎﺑﺮاﻳﻦ در ﻣﺘﺪ.ي ﺗﻮﺧﺎﻟﻲ رﺳﻢ ﻛﻨﻴﻢ و ﻳﺎ داﻳﺮه ي ﺗﻮﭘﺮ . ﻳﻚ داﻳﺮه ي ﺗﻮﭘﺮ رﺳﻢ ﻛﻨﺪFillEllipse اﻳﻦ ﻣﺘﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ، ﺑﻮدtrue ﺑﺮاﺑﺮ ﺑﺎIsFilled ﺗﺎ اﮔﺮ ﺧﺎﺻﻴﺖ . ﻳﻚ داﻳﺮه ي ﺗﻮﭘﺮ رﺳﻢ ﻣﻲ ﻛﻨﺪDrawEllipse ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪDraw در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻣﺘﺪ ﺑﻪ اﻳﻦ ﺻﻮرت ﻛﻪ ﻫﻨﮕﺎم، از ﻳﻚ ﺣﻘﻪ ي ﻛﻮﭼﻚ اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ،در اﻳﻦ ﻣﺘﺪ ﺑﺮاي اﻳﻨﻜﻪ داﻳﺮه ﻫﺎي ﺗﻮﺧﺎﻟﻲ ﺑﻬﺘﺮ ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ داﻳﺮه اي ﻛﻪ در ﺻﻔﺤﻪ رﺳﻢ ﻣﻲ ﺷﻮد واﺿﺢ ﺗﺮ ﺧﻮاﻫﺪ.رﺳﻢ اﻳﻦ داﻳﺮه ﻃﻮل و ﻋﺮض آن را ﻳﻚ واﺣﺪ ﻛﺎﻫﺶ ﻣﻲ دﻫﻴﻢ
٥٨٣
ﺑﻮد .دﻟﻴﻞ اﻳﻦ ﻣﻮرد ﺑﻪ ﻋﻠﺖ ﻃﺒﻴﻌﺖ ﺧﺎﺻﻲ اﺳﺖ ﻛﻪ ﺳﻴﺴﺘﻢ ﮔﺮاﻓﻴﻜﻲ وﻳﻨﺪوز ﺑﺮ اﺳﺎس آن ﻛﺎر ﻣﻲ ﻛﻨﺪ .ﻫﺮ ﭼﻪ ﺑﻴﺸﺘﺮ در اﻳﻦ زﻣﻴﻨﻪ ﻓﻌﺎﻟﻴﺖ ﻛﻨﻴﺪ ،در اﻳﻦ ﻣﻮارد ﻧﻴﺰ ﺗﺠﺮﺑﻪ ي ﺑﻴﺸﺘﺮي ﺑﺪﺳﺖ ﺧﻮاﻫﻴﺪ آورد. )public override void Draw(Graphics graphics { )if (IsFilled { // Create a new pen SolidBrush objSolidBrush = new ;)SolidBrush(this.color // Draw the circle graphics.FillEllipse(objSolidBrush, ;)this.rectangle } else { // Create a pen ;)Pen pen = new Pen(this.color // Use DrawEllipse instead ;Rectangle objRectangle = this.rectangle ;)objRectangle.Inflate(-1, -1 ;)graphics.DrawEllipse(pen, objRectangle } } ﺧﻮب ،ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺗﻤﺎم ﻗﺴﻤﺘﻬﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﮔﺮاﻓﻴﻜﻲ ﺳﺎده را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮدﻣﺎن اﺿﺎﻓﻪ ﻛﺮدﻳﻢ و ﺗﻘﺮﻳﺒـﺎً ﺗﻤـﺎم ﻧﻜﺎت اﺑﺘﺪاﻳﻲ ﻛﻪ ﻻزم ﺑﻮد ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﮔﺮاﻓﻴﻜﻲ دو ﺑﻌﺪي در وﻳﻨﺪوز ﺑﺪاﻧﻴﻢ را ﻧﻴﺰ ﺑﺎ ﻫﻢ ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ .در اداﻣﻪ ي ﻓﺼﻞ ﺳـﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻣﻘﺪاري ﻫﻢ ﺑﻪ ﻣﺒﺤﺚ ﻛﺎر ﺑﺎ ﻋﻜﺴﻬﺎ در وﻳﮋوال 2005 C#ﺑﭙﺮدازﻳﻢ.
ﻛﺎر ﺑﺎ ﻋﻜﺴﻬﺎ: در ﭼﺎرﭼﻮب .NETﺑﺮاي ﺳﺎدﮔﻲ ﻛﺎر ﺑﺎ ﻋﻜﺲ ،ﺗﻤﺎم اﻣﻜﺎﻧﺎت ﻻزم ﺑﺮاي ذﺧﻴﺮه ﻛﺮدن و ﻫﻤﭽﻨﻴﻦ ﻧﻤﺎﻳﺶ دادن ﻗﺎﻟﺒﻬﺎي ﻋﻤـﻮﻣﻲ ،ﺑـﻪ ﺻﻮرت دروﻧﻲ اﻳﺠﺎد ﺷﺪه اﺳﺖ .ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ راﺣﺘﻲ ﻋﻜﺴﻬﺎﻳﻲ را ﺑﺎ ﻗﺎﻟﺒﻬﺎي زﻳﺮ ذﺧﻴﺮه ﻛﺮده و ﻳﺎ ﻧﻤﺎﻳﺶ دﻫﻴﺪ:
:.bmpﻗﺎﻟﺐ اﺳﺘﺎﻧﺪار وﻳﻨﺪوز ﺑﺮاي ﺗﺼﺎوﻳﺮي ﻛﻪ ﺑﻪ ﺻﻮرت ﺑﻴﺖ ﻣﭙﻲ ذﺧﻴﺮه ﻣﻲ ﺷﻮﻧﺪ. :.gifﻗﺎﻟﺐ اﺳﺘﺎﻧﺪارد ﺗﺼﺎوﻳﺮ ﻛﻮﭼﻚ اﻳﻨﺘﺮﻧﺘﻲ ﻛﻪ ﻣﻌﻤﻮﻻً ﺣﺠﻢ ﻛﻢ و ﻛﻴﻔﻴﺖ ﭘﺎﻳﻴﻨﻲ دارﻧﺪ. .jpegو ﻳﺎ :.jpgﻗﺎﻟﺐ ﻣﺮﺑﻮط ﺑﻪ ﻋﻜﺴﻬﺎﻳﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻛﻴﻔﻴﺖ ﻣﻄﻠﻮب و ﻧﻴـﺰ ﺣﺠـﻢ ﻛﻤـﻲ داﺷـﺘﻪ ﺑﺎﺷـﻨﺪ ﺗـﺎ ﺑﺘﻮاﻧﻴﻢ در اﻳﻨﺘﺮﻧﺖ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﻢ. :.pngﻛﺎرﺑﺮدي ﻣﺸﺎﺑﻪ ﻓﺎﻳﻠﻬﺎﻳﻲ ﺑﺎ ﻗﺎﻟﺐ .gifدارد. :.tiffﻓﺮﻣﺖ ﻓﺎﻳﻞ اﺳﺘﺎﻧﺪارد ﺑﺮاي ذﺧﻴﺮه و ﻳﺎ ﺗﻐﻴﻴﺮ در ﻓﺎﻳﻠﻬﺎي اﺳﻜﻦ ﺷﺪه اﺳﺖ.
٥٨٤
.wmfو ﻳﺎ :.emfﻓﺮﻣﺖ اﺳﺘﺎﻧﺪارد ﺑﺮاي ﻓﺎﻳﻠﻬﺎﻳﻲ از ﻧﻮع Windows Metafile :.icoﻗﺎﻟﺐ اﺳﺘﺎﻧﺪارد ﺑﺮاي ذﺧﻴﺮه ي آﻳﻜﻮن ﺑﺮﻧﺎﻣﻪ ﻫﺎ :.exifﻗﺎﻟﺐ ﻓﺎﻳﻞ اﺳﺘﺎﻧﺪارد ﻛﻪ ﻣﻌﻤﻮﻻً ﺑﻪ ﺻﻮرت دروﻧﻲ ﺑﻴﻦ دورﺑﻴﻦ ﻫﺎي دﻳﺠﻴﺘﺎﻟﻲ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد.
ﻗﺒﻞ از .NETﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎﻧﻲ ﻛﻪ ﻣﻲ ﺧﻮاﺳﺘﻨﺪ ﺑﺎ ﺗﺼﺎوﻳﺮ ﻣﻮرد اﺳﺘﻔﺎده در اﻳﻨﺘﺮﻧﺖ ﻛﺎر ﻛﻨﻨﺪ و ﻳﺎ از آﻧﻬﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧـﻮد اﺳـﺘﻔﺎده ﻛﻨﻨﺪ )ﻣﻌﻤﻮﻻً ﺗﺼﺎوﻳﺮي ﺑﺎ ﭘﺴﻮﻧﺪ ﻫﺎي .gifو ﻳﺎ (.jpgﻣﺠﺒﻮر ﺑﻮدﻧﺪ ﻛﻨﺘﺮﻟﻬﺎي ﺳﻔﺎرﺷﻲ ﻧﻮﺷﺘﻪ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي ﺷﺮﻛﺖ ﻫـﺎي دﻳﮕﺮ را در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد ﺑﻪ ﻛﺎر ﺑﺒﺮﻧﺪ .اﻣﺎ اﻛﻨﻮن ﻛﺎر ﺑﺎ اﻳﻦ ﻧﻮع ﺗﺼﺎوﻳﺮ ﺑﻪ ﺻﻮرت دروﻧﻲ در .NETﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ ﺷﻮد و ﻣﻲ ﺗﻮاﻧﻴـﺪ ﺑﻪ ﺳﺎدﮔﻲ از آﻧﻬﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ. اﻣﺎ ﺟﺎﻟﺐ اﻳﻨﺠﺎﺳﺖ ﻛﻪ .NETﻧﻪ ﺗﻨﻬﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻓﺎﻳﻠﻬﺎ را ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ ﻛﻨﺪ ،ﺑﻠﻜﻪ اﺟﺎزه ي ذﺧﻴﺮه ي ﻳﻚ ﺗﺼﻮﻳﺮ در ﻫـﺮ ﻳـﻚ از اﻳﻦ ﻗﺎﻟﺐ ﻫﺎ ﻧﻴﺰ ﻣﻲ دﻫﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﻋﻜﺲ ﺑﺎ ﭘﺴﻮﻧﺪ .gifرا ﺑﺎز ﻛﺮده و ﺳـﭙﺲ آن را ﺑـﺎ ﭘـﺴﻮﻧﺪ دﻳﮕـﺮي ﻣﺎﻧﻨﺪ .pngو ﻳﺎ .bmpذﺧﻴﺮه ﻛﻨﻴﺪ .ﺑﺮاي ﻛﺎر ﺑﺎ ﺗﺼﺎوﻳﺮ در .NETدو روش ﻛﻠـﻲ وﺟـﻮد دارد .اول اﻳـﻦ اﺳـﺖ ﻛـﻪ از ﻛﻨﺘـﺮل PictureBoxدر ﺟﻌﺒﻪ اﺑﺰار اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﺮاي ﻛﺎر ﺑﺎ اﻳﻦ ﻛﻨﺘﺮل ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳـﻚ ﻧﻤﻮﻧـﻪ از آن را در ﻓـﺮم ﺑﺮﻧﺎﻣـﻪ ﻗـﺮار داده و ﺳﭙﺲ ﭼﻪ در زﻣﺎن اﺟﺮا و ﭼﻪ در زﻣﺎن ﻃﺮاﺣﻲ آدرس ﻳﻚ ﻋﻜﺲ را ﺑﺮاي آن ﻣﺸﺨﺺ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﻳﻦ ﻛﻨﺘﺮل آن ﻋﻜـﺲ را در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .اﻟﺒﺘﻪ اﻳﻦ روش ﻓﻘﻂ ﺑﺮاي ﻧﻤﺎﻳﺶ ﻋﻜﺴﻬﺎي ﺛﺎﺑﺖ در ﺑﺮﻧﺎﻣﻪ ﻣﻨﺎﺳﺐ اﺳﺖ .روش دﻳﮕﺮ اﻳﻦ اﺳﺖ ﻛﻪ ﻋﻜﺴﻬﺎ را در داﺧﻞ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ ﺧﻮدﺗﺎن اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ ﻧﻤﺎﻳﺶ دﻫﻴﺪ .در اداﻣﻪ ي ﻓﺼﻞ ﺑﺮﻧﺎﻣـﻪ ي MyPaintرا ﺑـﻪ ﮔﻮﻧـﻪ اي ﺗﻐﻴﻴـﺮ ﺧﻮاﻫﻴﻢ داد ﻛﻪ ﺑﺘﻮاﻧﻴﻢ ﺑﻪ ﺟﺎي ﺗﺮﺳﻴﻢ روي ﻳﻚ ﻓﺮم ﺳﻔﻴﺪ و ﺧﺎﻟﻲ ،روي ﻳﻜﻲ از ﻋﻜﺴﻬﺎﻳﻲ ﻛﻪ از دﻳﺴﻚ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﻢ، ﺗﺼﻮﻳﺮي را رﺳﻢ ﻛﻨﻴﻢ.
ﻧﻤﺎﻳﺶ ﺗﺼﺎوﻳﺮ: ﺑﺮاي ﻧﻤﺎﻳﺶ ﻳﻚ ﺗﺼﻮﻳﺮ ﺑﺎﻳﺪ از ﺷﻴﺊ اي از ﻛﻼس System.Drawing.Imageاﺳﺘﻔﺎده ﻛﻨﻴﻢ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ ﺧﻮاﻫﻴﻢ داد ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﻳﻚ ﻋﻜﺲ ﺧﺎص را در ﭘﺲ زﻣﻴﻨﻪ ي ﻓﺮﻣﻲ ﻛﻪ در آن ﻧﻘﺎﺷﻲ ﻣﻲ ﻛﻨـﻴﻢ ﻧﻤـﺎﻳﺶ دﻫﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺗﻨﻈﻴﻢ ﻋﻜﺲ ﭘﺲ زﻣﻴﻨﻪ (1ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ Form1ﺑﺮوﻳﺪ و ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘـﺮل OpenFileDialogرا روي ﻓﺮم ﻗﺮار دﻫﻴﺪ .ﺳﭙﺲ ﺧﺎﺻﻴﺖ Nameاﻳﻦ ﻛﻨﺘـﺮل را ﺑﺮاﺑـﺮ ﺑـﺎ dlgFileOpenBackgroundﻗـﺮار دﻫﻴﺪ. (2ﺣﺎل ﺑﺎﻳﺪ ﻛﺎري ﻛﻨﻴﻢ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻛﺎرﺑﺮ روي ﮔﺰﻳﻨـﻪ ي Openدر ﻣﻨـﻮي Fileﻛﻠﻴـﻚ ﻛـﺮد ،ﭘﻨﺠـﺮه ي Open Fileﻧﻤﺎﻳﺶ داده ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ در ﻣﻨﻮي Fileﻣﻮﺟﻮد در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ،روي ﮔﺰﻳﻨﻪ ي Openدو ﺑﺎر ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickاﻳﻦ ﻛﻨﺘﺮل اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: private void openToolStripMenuItem_Click(object sender, )EventArgs e { // Set the open file dialog properties
٥٨٥
dlgFileOpenBackground.Filter = "Image files" + " (*.gif,*.jpg,*.jpeg,*.bmp,*.wmf,*.png)" + "|*.gif;*.jpg;*.jpeg;*.bmp;*.wmf;*.png|All" + " files (*.*)|*.*"; dlgFileOpenBackground.FilterIndex = 1; dlgFileOpenBackground.Title = "Open Picture Files"; // Show the dialog if (dlgFileOpenBackground.ShowDialog() == DialogResult.OK) { // Create a new image that references the file Image backgroundImage = Image.FromFile( dlgFileOpenBackground.FileName); // Set the background of the canvas Canvas.BackgroundImage = backgroundImage; } } ﻧﻤـﺎﻳﺶ دادهOpen ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗـﺎ ﻛـﺎدر ﻣﺤـﺎوره ايFile در ﻣﻨﻮيOpen ( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و روي ﮔﺰﻳﻨﻪ ي3 ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛـﺮد ﻛـﻪ. در اﻳﻦ ﻛﺎدر آدرس ﻳﻚ ﻓﺎﻳﻞ ﺗﺼﻮﻳﺮ ﺑﺎ ﻳﻜﻲ از ﻓﺮﻣﺖ ﻫﺎي ﻣﺸﺨﺺ ﺷﺪه را ﻣﻌﻴﻦ ﻛﻨﻴـﺪ.ﺷﻮد . در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد9-14 ﺗﺼﻮﻳﺮ اﻧﺘﺨﺎﺑﻲ ﺷﻤﺎ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ
9-14 ﺷﻜﻞ
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟
٥٨٦
ﻣﻤﻜﻦ اﺳﺖ ﺑﺎ ﺧﻮد ﺑﮕﻮﻳﻴﺪ "ﻣﻦ ﻛﻪ ﺑﺮاي ﻧﻤﺎﻳﺶ ﺗﺼﻮﻳﺮ ﻛﺎري اﻧﺠﺎم ﻧﺪادم؟" ،ﺧﻮب ﺣﻖ ﺑﺎ ﺷﻤﺎﺳﺖ .ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﺪ ﺗﺼﻮﻳﺮي را در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ دﻫﻴـﺪ ﻧﻴـﺎزي ﻧﺪارﻳـﺪ ﻛـﻪ از ﻛـﺪ زﻳـﺎدي اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ .ﻛﻨﺘﺮﻟﻬـﺎي ﺳﻔﺎرﺷـﻲ ﻛـﻪ اﻳﺠـﺎد ﻣـﻲ ﻛﻨـﻴﻢ ﻫﻤـﻪ از ﻛـﻼس UserControlﻣﺸﺘﻖ ﻣﻲ ﺷﻮﻧﺪ و اﻳﻦ ﻛﻼس ﻧﻴﺰ ﺧﻮد ﺑﻪ ﺻﻮرت ﻏﻴﺮ ﻣﺴﺘﻘﻴﻢ از ﻛﻼس Controlﻣﺸﺘﻖ ﻣﻲ ﺷﻮد .در ﻛﻼس Controlﺧﺎﺻﻴﺘﻲ ﺑﻪ ﻧﺎم BackgroundImageﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺷﻴﺊ اي از ﻧـﻮع Image را در ﺧﻮد ﻧﮕﻬﺪاري ﻛﺮده و آن را ﺑﻪ ﻋﻨﻮان ﺗﺼﻮﻳﺮ ﭘﺲ زﻣﻴﻨﻪ ﻧﻤﺎﻳﺶ دﻫﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﺗﺼﻮﻳﺮ ﻣـﻮرد ﻧﻈـﺮ ﺧـﻮد را اﻧﺘﺨـﺎب ﻛﺮده و ﺷﻴﺊ Imageﻣﺮﺑﻮط ﺑﻪ آن را در اﻳﻦ ﺧﺎﺻﻴﺖ ﻗﺮار دﻫﻴﺪ .ﺑﻘﻴﻪ ي ﻛﺎرﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﺗﺮﺳﻴﻢ ﺗﺼﻮﻳﺮ ﺑﻪ ﻋﻬﺪه ي ﻛﻼس ﭘﺎﻳـﻪ ﺧﻮاﻫﺪ ﺑﻮد. ﺑﻌﺪ از اﻳﻨﻜﻪ آدرس ﻓﺎﻳﻞ ﺗﺼﻮﻳﺮ را ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺎدر Openﺑﺪﺳﺖ آوردﻳﻢ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ اﺳﺘﺎﺗﻴﻚ FromFileاز ﻛﻼس Imageآن را در ﻳﻚ ﺷﻴﺊ از ﻛﻼس Imageﻗﺮار دﻫﻴﻢ .اﺳﺘﻔﺎده از اﻳﻦ ﻛﻼس ﺳﺎده ﺗـﺮﻳﻦ روش ﺑـﺮاي ﻧﻤـﺎﻳﺶ ﻳـﻚ ﻓﺎﻳﻞ ﺗﺼﻮﻳﺮ ﻣﻮﺟﻮد در ﻛﺎﻣﭙﻴﻮﺗﺮ اﺳﺖ. // Show the dialog == )(if (dlgFileOpenBackground.ShowDialog )DialogResult.OK { // Create a new image that references the file (Image backgroundImage = Image.FromFile ;)dlgFileOpenBackground.FileName // Set the background of the canvas ;Canvas.BackgroundImage = backgroundImage } ﻣﻤﻜﻦ اﺳﺖ ﺣﺲ ﻛﻨﻴﺪ ﺑﺎ ﻗﺮار دادن ﻳﻚ ﻋﻜﺲ در ﭘﺲ زﻣﻴﻨﻪ ي ﺑﺮﻧﺎﻣﻪ ،ﺳﺮﻋﺖ ﺑﺮﻧﺎﻣﻪ ﻛﺎﻫﺶ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ .ﻋﻠﺖ اﻳﻦ اﻣﺮ در اﻳﻦ اﺳﺖ ﻛﻪ ﺗﺮﺳﻴﻢ ﻳﻚ ﻋﻜﺲ در ﻓﺮم ﻛﺎر ﺳﻨﮕﻴﻨﻲ اﺳﺖ و اﻧﺠﺎم آن زﻣﺎن زﻳﺎدي را ﺻﺮف ﻣـﻲ ﻛﻨـﺪ .ﺑـﺮاي رﻓـﻊ اﻳـﻦ ﻣـﺸﻜﻞ ﻣـﻲ ﺗﻮاﻧﻴـﺪ از ﻋﻜﺴﻬﺎي ﻛﻮﭼﻜﺘﺮ ﺑﺮاي ﻧﻤﺎﻳﺶ در ﻓﺮم اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
ﺗﻐﻴﻴﺮ اﻧﺪازه ي ﺗﺼﺎوﻳﺮ: در ﻗﺴﻤﺖ ﻗﺒﻞ اﮔﺮ ﻋﻜﺴﻲ ﻛﻪ ﺑﺮاي ﻓﺮم در ﻧﻈﺮ ﻣﻲ ﮔﺮﻓﺘﻴﺪ ﻛﻮﭼﻜﺘﺮ از اﻧﺪازه ي ﻓﺮم ﺑﻮد ،و ﻳﺎ اﻧﺪازه ي ﻓﺮم را ﺑﻪ ﮔﻮﻧـﻪ اي ﺗﻐﻴﻴـﺮ ﻣـﻲ دادﻳﺪ ﻛﻪ ﺑﺰرﮔﺘﺮ از اﻧﺪازه ي ﻋﻜﺲ ﺷﻮد ﻣﺘﻮﺟﻪ ﻣﻲ ﺷﺪﻳﺪ ﻛﻪ ﭼﻨﺪﻳﻦ ﻛﭙﻲ از ﻋﻜﺲ اﻧﺘﺨﺎﺑﻲ ﺷﻤﺎ در ﻛﻨﺎر ﻫﻢ ﭼﻴﺪه ﻣـﻲ ﺷـﻮد ﺗـﺎ ﻓـﺮم ﺑﺮﻧﺎﻣﻪ ﭘﺮ ﺷﻮد .ﻫﻤﭽﻨﻴﻦ اﮔﺮ اﻧﺪازه ي ﻓﺮم از اﻧﺪازه ي ﻋﻜﺲ اﻧﺘﺨﺎﺑﻲ ﺷﻤﺎ ﻛﻮﭼﻜﺘﺮ ﺑﺎﺷﺪ ،ﻣﻘﺪاري از ﻋﻜﺲ در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﻧﻤـﻲ ﺷﻮد .ﺑﻬﺘﺮ اﺳﺖ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﻛﻪ ﺑﺎ ﺗﻐﻴﻴﺮ اﻧﺪازه ي ﻋﻜﺲ آن را در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ دﻫﺪ .در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴـﺪ ﺑﻌﺪي ،ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﺑﺎ ﺗﻐﻴﻴﺮ اﻧﺪازه ي ﻋﻜﺲ آن را ﺑﻪ اﻧﺪازه ي ﻓﺮم در آورده و ﻧﻤﺎﻳﺶ دﻫﻴﻢ وﻇﻴﻔﻪ ي ﻧﻤﺎﻳﺶ ﺗﺼﻮﻳﺮ را از ﻛﻼس Controlﺧﻮاﻫﻴﻢ ﮔﺮﻓﺖ و در ﺧﻮدﻣﺎن آن را اﻧﺠﺎم ﺧﻮاﻫﻴﻢ داد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻧﻤﺎﻳﺶ ﺗﺼﻮﻳﺮ در ﻛﻼس PaintCanvas
٥٨٧
(1ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس PaintCanvasرا ﺑﺎز ﻛﻨﻴﺪ. (2در اﻳـــﻦ ﻗـــﺴﻤﺖ ﺑـــﻪ ﺟـــﺎي اﺳـــﺘﻔﺎده از ﻣﺘـــﺪ ﻣﺮﺑـــﻮط ﺑـــﻪ روﻳـــﺪاد Paintاز ﻣﺘـــﺪ دﻳﮕـــﺮي ﺑـــﻪ ﻧـــﺎم OnPaintBackgroundاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻗﺒﻞ از ﻓﺮاﺧﻮاﻧﻲ روﻳﺪاد Paintﻓﺮاﺧـﻮاﻧﻲ ﻣـﻲ ﺷـﻮد .ﻛـﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ ﻛﻼس PaintCanvasاﺿﺎﻓﻪ ﻛﻨﻴﺪ: (protected override void OnPaintBackground )PaintEventArgs e { // Paint the invalid region // with the background brush SolidBrush backgroundBrush = new ;)SolidBrush(BackColor e.Graphics.FillRectangle(backgroundBrush, ;)e.ClipRectangle // Paint the image )if (BackgroundImage != null { // Find our client rectangle Rectangle clientRectangle = new Rectangle(0, 0, ;)Width, Height // Draw the image e.Graphics.DrawImage(BackgroundImage, ;)clientRectangle } } (3ﺣﺎل ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻛﻨﺘﺮل PaintCanvasﺑﺮﮔﺸﺘﻪ و روي ﻗﺴﻤﺘﻲ از اﻳﻦ ﻛﻨﺘﺮل ﻛﻠﻴﻚ ﻛﻨﻴـﺪ ﺗـﺎ اﻧﺘﺨـﺎب ﺷﻮد .ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻗﺴﻤﺖ Eventsدر ﭘﻨﺠﺮه ي Propertiesروﻳﺪاد Resizeرا اﻧﺘﺨﺎب ﻛـﺮده و روي آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ روﻳﺪاد اﻳﺠﺎد ﺷﻮد .ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳﻦ روﻳﺪاد وارد ﻛﻨﻴﺪ: private void PaintCanvas_Resize(object sender, )EventArgs e { // Invalidate the control ;)(this.Invalidate } (4ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﻋﻜﺴﻲ را ﻛﻪ ﺑﻪ اﻧﺪازه ي ﻓﺮم ﻧﺒﺎﺷﺪ را ﺑﺮاي ﻧﻤﺎﻳﺶ ﺑﻪ ﻋﻨﻮان ﭘﺲ زﻣﻴﻨﻪ اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ اﻧﺪازه ي ﺗﺼﻮﻳﺮ ﺗﻐﻴﻴﺮ ﻣﻲ ﻛﻨﺪ ﺗﺎ ﺑﻪ اﻧﺪازه ي ﻓﺮم در آﻳﺪ )ﺷﻜﻞ .(10-14
٥٨٨
ﺷﻜﻞ 10-14
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﻧﻴﺰ ﮔﻔﺘﻢ ﻫﺮ ﺗﺮﺳﻴﻢ از دو ﻣﺮﺣﻠﻪ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ .در ﻣﺮﺣﻠﻪ ي اول ﺳﻄﺢ ﻛﻨﺘﺮل ﭘﺎك ﻣـﻲ ﺷـﻮد ،در اﻳﻦ ﻗﺴﻤﺖ روﻳﺪاد PaintBackgroundﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد .در ﻣﺮﺣﻠﻪ ي دوم ﻧﻴﺰ ﺑﻪ ﻛﻨﺘﺮل ﻓﺮﺻﺖ داده ﻣﻲ ﺷﻮد ﺗﺎ ﺧﻮد را ﺗﺮﺳﻴﻢ ﻛﻨﺪ ،در اﻳﻦ ﻣﺮﺣﻠﻪ ﻧﻴﺰ روﻳﺪاد Paintﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑـﺮاي ﻫـﺮ ﺗﺮﺳـﻴﻢ وﻳﻨـﺪوز ﺑـﺎ ﻓﺮاﺧـﻮاﻧﻲ روﻳـﺪاد PaintBackgroundﭘﺲ زﻣﻴﻨﻪ ي ﺻﻔﺤﻪ را رﺳﻢ ﻣﻲ ﻛﻨﺪ ،ﺳﭙﺲ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ روﻳﺪاد Paintدر ﻛﻨﺘـﺮل ،ﺑـﻪ ﻛﻨﺘـﺮل اﺟﺎزه ﻣﻲ دﻫﺪ ﺗﺎ ﺧﻮد را روي ﭘﺲ زﻣﻴﻨﻪ ي اﻳﺠﺎد ﺷﺪه رﺳﻢ ﻛﻨﺪ. در ﻣﺘﺪ OnPaintBackgroundاﺑﺘﺪا ﺑﺎﻳﺪ ﻓﺮم ﺗﺎ ﭘﺎك ﻛﻨﻴﻢ در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻣﻤﻜﻦ اﺳﺖ ﺗﺼﺎوﻳﺮ درﺳـﺖ ﻧﻤـﺎﻳﺶ داده ﻧﺸﻮﻧﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻳﻚ ﻗﻠﻢ ﻣﻮي ﺟﺪﻳﺪ از ﻛﻼس SolidBrushﺑﻪ رﻧﮓ ﭘﺲ زﻣﻴﻨﻪ ي ﻛﻨﺘﺮل اﻳﺠﺎد ﻛﺮده و ﺑﺎ اﺳﺘﻔﺎده از آن ﻳﻚ ﻣﺴﺘﻄﻴﻞ ﺗﻮﭘﺮ ﺑﻪ اﻧﺪازه و رﻧﮓ ﻗﺴﻤﺘﻲ از ﻓﺮم ﻛﻪ از ﻧﻮع ﻧﺎ ﻣﻌﺘﺒﺮ ﻣﺸﺨﺺ ﺷـﺪه اﺳـﺖ ) (ClipRectangleرﺳـﻢ ﻣـﻲ ﻛﻨﻴﻢ. (protected override void OnPaintBackground )PaintEventArgs e { // Paint the invalid region // with the background brush SolidBrush backgroundBrush = new ;)SolidBrush(BackColor e.Graphics.FillRectangle(backgroundBrush, ;)e.ClipRectangle
٥٨٩
ﺑﻌﺪ از اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ ﺗﺼﻮﻳﺮ ﻣﻮرد ﻧﻈﺮ را در ﭘﺲ زﻣﻴﻨﻪ ي ﻓﺮم رﺳـﻢ ﻛﻨـﻴﻢ .ﺑـﺮاي رﺳـﻢ ﻳـﻚ ﺗـﺼﻮﻳﺮ ﻣـﻲ ﺗـﻮاﻧﻴﻢ ﺑـﻪ ﺳـﺎدﮔﻲ از ﻣﺘـﺪ DrawImageدر ﻛﻼس Graphicsاﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻣﺎ در اﻳﻨﺠﺎ ﻗﺒﻞ از اﻳﻨﻜﻪ ﺗﺼﻮﻳﺮ را رﺳﻢ ﻛﻨﻴﻢ ﺑﺎﻳﺪ ﻣﺤـﺪوده ي رﺳـﻢ آن را ﻧﻴﺰ ﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻫﻨﮕﺎم ﻓﺮاﺧﻮاﻧﻲ ﻣﺘـﺪ DrawImageﺑـﺮاي رﺳـﻢ ﺗـﺼﻮﻳﺮ ،ﻣﺤـﺪوده ي آن )ﺷـﻴﺊ اي از ﻛﻼس (Rectangleو ﻧﻴﺰ ﺧﻮد ﺗﺼﻮﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻣﻲ ﻓﺮﺳﺘﻴﻢ و ﺳﭙﺲ ﺗﺼﻮﻳﺮ را رﺳﻢ ﻣﻲ ﻛﻨﻴﻢ: // Paint the image )if (BackgroundImage != null { // Find our client rectangle Rectangle clientRectangle = new Rectangle(0, 0, ;)Width, Height // Draw the image e.Graphics.DrawImage(BackgroundImage, ;)clientRectangle } }
ﻣﺘﺪ ﻫﺎي دﻳﮕﺮ ﻛﻼس :Graphics در اﻳﻦ ﻓﺼﻞ ﺳﻌﻲ ﻛﺮدﻳﻢ ﻛﻪ ﺑﺎ ﺑﻌﻀﻲ از وﻳﮋﮔﻴﻬﺎي ﮔﺮاﻓﻴﻜﻲ ﻛﻪ در .NETوﺟﻮد دارﻧﺪ آﺷﻨﺎ ﺷﻮﻳﻢ و ﻣﻬﻤﺘﺮﻳﻦ آﻧﻬﺎ را ﺑﺮرﺳﻲ ﻛﻨـﻴﻢ. در ﻃﻮل ﻓﺼﻞ ﻫﻤﭽﻨﻴﻦ ﺑﺎ ﻳﻜﻲ از ﻣﻬﻤﺘـﺮﻳﻦ ﻛـﻼس ﻫـﺎﻳﻲ ﻛـﻪ ﺑـﺮاي ﻛﺎرﻫـﺎي ﮔﺮاﻓﻴﻜـﻲ در .NETوﺟـﻮد دارد ﺑـﻪ ﻧـﺎم ﻛـﻼس Graphicsﻧﻴــﺰ آﺷــﻨﺎ ﺷــﺪﻳﻢ و از ﺑﻌــﻀﻲ از ﻣﺘــﺪﻫﺎي ﭘــﺮ ﻛــﺎرﺑﺮد آن اﺳــﺘﻔﺎده ﻛــﺮدﻳﻢ .در زﻳــﺮ ﺗﻌــﺪادي از ﻣﺘــﺪﻫﺎي ﻛــﻼس Graphicsﻛﻪ اﺳﺘﻔﺎده ي زﻳﺎدي در ﺑﺮﻧﺎﻣﻪ ﻫﺎ دارﻧﺪ را ﺑﻪ اﺧﺘﺼﺎر ﻣﻌﺮﻓﻲ ﻣﻲ ﻛﻨﻴﻢ.
DrawLineﺑﻴﻦ دو ﻧﻘﻄﻪ ي ﻣﺸﺨﺺ ﺧﻄﻲ را رﺳﻢ ﻣﻲ ﻛﻨﺪ. DrawCurveو DrawClosedCurveﻳﻚ ﻣﺠﻤﻮﻋﻪ از ﻧﻘﺎط را درﻳﺎﻓـﺖ ﻛـﺮده و ﺑـﻴﻦ اﻳـﻦ ﻧﻘـﺎط ﻳـﻚ ﻣﻨﺤﻨﻲ رﺳﻢ ﻣﻲ ﻛﻨﺪ. DrawArcﻳﻚ ﻛﻤﺎن )ﻗﺴﻤﺘﻲ از ﻳﻚ داﻳﺮه( را در ﺻﻔﺤﻪ رﺳﻢ ﻣﻲ ﻛﻨﺪ. DrawPieﻗﺴﻤﺘﻲ از ﻳﻚ داﻳﺮه را رﺳﻢ ﻣﻲ ﻛﻨﺪ )ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﻧﻤﻮدار داﻳﺮه اي(. DrawPolygonﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﻣﺠﻤﻮﻋﻪ ﻧﻘﺎط ،ﻳﻚ ﭼﻨﺪ ﺿﻠﻌﻲ را در ﺻﻔﺤﻪ رﺳﻢ ﻣﻲ ﻛﻨﺪ. DrawIconﻳﻚ آﻳﻜﻮن را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
ﺗﻤﺎم اﻳﻦ ﻣﺘﺪ ﻫﺎ اﺷﻴﺎﻳﻲ را از ﻧﻮع Rectangle ،Pen ،Brushو ﻳﺎ Pointﻛﻪ در ﻃﻲ ﻓﺼﻞ ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﺷـﺪﻳﺪ را ﺑـﻪ ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﻨﺪ .ﻫﻤﭽﻨﻴﻦ اﻳﻦ ﺗﻮاﺑﻊ ،ﺗﻮاﺑﻊ ﻣﺘﻨﺎﻇﺮي ﻧﻴﺰ دارﻧﺪ ﻛﻪ ﺑﺎ ﻧﺎم Fillﺷﺮوع ﻣﻲ ﺷﻮﻧﺪ .وﻇﻴﻔﻪ ي اﻳﻦ ﺗﻮاﺑﻊ اﻳﻦ اﺳﺖ ﻛﻪ اﺷﻜﺎل را ﺑﻪ ﺻﻮرت ﺗﻮﭘﺮ رﺳﻢ ﻛﻨﻨﺪ.
٥٩٠
ﻧﺘﻴﺠﻪ: در اﻳﻦ ﻓﺼﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ در ﻓﺮﻣﻬﺎي ﺑﺮﻧﺎﻣﻪ و ﻳﺎ در ﻛﻨﺘﺮﻟﻬﺎي ﺳﻔﺎرﺷﻲ ﻛﻪ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴـﺪ ،راﺑـﻂ ﻛـﺎرﺑﺮي را ﺧﻮدﺗﺎن ﻃﺮاﺣﻲ ﻛﻨﻴﺪ .در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ،ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﻛﻨﺘﺮل ﺳﻔﺎرﺷﻲ ﻣﺠﺒﻮر ﺑﻮدﻳﻢ ﻛﻪ ﺑﺮاي ﻃﺮاﺣﻲ راﺑﻂ ﻛﺎرﺑﺮي آن از ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد اﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻣﺎ در اﻳﻦ ﺑﺨﺶ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﺑﺎ ﻇﺎﻫﺮ دﻟﺨﻮاه ﻃﺮاﺣﻲ ﻛﺮد .در ﻃﻲ ﻓﺼﻞ ﻧﻴـﺰ ﺑﻴﺸﺘﺮ ﺑﺮ روي ﻧﻮﺷﺘﻦ ﻛﻨﺘﺮﻟﻬﺎي ﺳﻔﺎرﺷﻲ ﻛﻪ از ﻛﻼس System.Windows.Forms.UserControlﻣﺸﺘﻖ ﻣﻲ ﺷﻮﻧﺪ ﺗﻤﺮﻛﺰ ﻛﺮدﻳﻢ ﺗﺎ ﺑﺎ اﺻﻮل ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺒﺘﻨﻲ ﺑﺮ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺷﻮﻳﻢ. ﺑﻌﺪ از ﺗﻮﺿﻴﺢ ﺗﺼﺎوﻳﺮ ﺑﺮداري و ﺗﺼﺎوﻳﺮ ﺑﻴﺖ ﻣﭙﻲ و ﺗﻔﺎوﺗﻬﺎي آﻧﻬﺎ ،ﺑﺮﻧﺎﻣﻪ اي اﻳﺠﺎد ﻛﺮدﻳﻢ ﻛﻪ ﺑـﻪ ﻛـﺎرﺑﺮ اﺟـﺎزه ﻣـﻲ داد ﺑـﺎ ﻗـﺮار دادن ﺗﻌﺪادي ﻧﻘﻄﻪ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺎوس در ﻛﻨﺎر ﻳﻜﺪﻳﮕﺮ ﺷﻜﻠﻲ را رﺳﻢ ﻛﻨﺪ .ﺳﭙﺲ ﻛﻨﺘﺮﻟﻲ اﻳﺠـﺎد ﻛـﺮدﻳﻢ ﻛـﻪ ﻛـﺎرﺑﺮ ﺑـﻪ وﺳـﻴﻠﻪ ي آن ﻣـﻲ ﺗﻮاﻧﺴﺖ رﻧﮓ اﺑﺰار ﻣﻮرد اﺳﺘﻔﺎده ﺧﻮد را ﻧﻴﺰ ﺗﻐﻴﻴﺮ دﻫﺪ .ﻫﻤﭽﻨﻴﻦ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣـﻲ ﺗـﻮان ﺑـﺎ اﺳـﺘﻔﺎده از ﻛـﺎدر Color رﻧﮕﻬﺎي ﺟﺪﻳﺪي را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮد و ﻳﺎ ﺑﺎ اﺳﺘﻔﺎده از ﺳﻴﺴﺘﻢ ﻧﻤﺎﻳﺶ رﻧﮓ ﺑﻪ ﺻﻮرت ،RGBرﻧﮕﻬﺎي ﺟﺪﻳﺪي را اﻳﺠﺎد ﻛﺮد. ﺳﭙﺲ ﻧﮕﺎه ﻣﺨﺘﺼﺮي ﺑﻪ ﻛﻼس Imageاﻧﺪاﺧﺘﻴﻢ و ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣـﻲ ﺗـﻮان ﺑـﺎ اﺳـﺘﻔﺎده از اﻳـﻦ ﻛـﻼس ﺗـﺼﺎوﻳﺮ ﺑـﺎ ﭘﺴﻮﻧﺪﻫﺎي ﻣﺨﺘﻠﻒ از ﻗﺒﻴﻞ .gifو ﻳﺎ .bmpرا در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داد. در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ:
در روﻳﺪاد ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ﻣﺎوس ﻣﺮﺑﻮط ﻣﻲ ﺷﻮد ،ﺑﺘﻮاﻧﻴﺪ ﻣﺨﺘﺼﺎت Xو Yاﺷﺎره ﮔﺮ ﻣﺎوس در ﺻﻔﺤﻪ را ﺑﺪﺳﺖ آورﻳﺪ. ﺑﺎ ﻧﺎ ﻣﻌﺘﺒﺮ ﻣﺸﺨﺺ ﻛﺮدن ﻗﺴﻤﺘﻬﺎي ﺿﺮوري ﻓﺮم ،از ﻛﻨﺪ ﺷﺪن ﺑﺮﻧﺎﻣﻪ و ﭼﺸﻤﻚ زدن آن ﺟﻠﻮﮔﻴﺮي ﻛﻨﻴﺪ. ﺑﺘﻮاﻧﻴﺪ از رﻧﮕﻬﺎي ﺳﻴﺴﺘﻤﻲ ﻫﻤﺎﻧﻨﺪ رﻧﮕﻬﺎي ﻋﺎدي و ﻳﺎ ﻣﻘﺎدﻳﺮ RGBاﺳﺘﻔﺎده ﻛﻨﻴﺪ. اﺑﺰارﻫﺎي ﮔﺮاﻓﻴﻜﻲ ﻣﺨﺘﻠﻔﻲ ﻫﻤﺎﻧﻨﺪ Circleو ﻳﺎ HollowCircleاﻳﺠﺎد ﻛﻨﻴﺪ. ﺗﺼﺎوﻳﺮي را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﻴﺪ و ﻳﺎ ﺗﻐﻴﻴﺮاﺗﻲ در اﻧﺪازه ي آﻧﻬﺎ اﻳﺠﺎد ﻛﻨﻴﺪ.
٥٩١
ﻓﺼﻞ ﭘﺎﻧﺰدﻫﻢ :اﺳﺘﻔﺎده از ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ اﻏﻠﺐ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﺎﻣﭙﻴﻮﺗﺮي ﻛﻪ اﻣﺮوزه ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮﻧﺪ ﺑﻪ ﻧﺤﻮي ﺑﺎ داده ﻫﺎ و اﻃﻼﻋﺎت ﻣﺨﺘﻠﻒ ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ .در وﻳـﮋوال 2005 C# ﺑﻴﺸﺘﺮ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ،داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺧﻮد را در ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ راﺑﻄﻪ اي ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ در ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻧﻴﺎز دارﻳﺪ ﻛﻪ ﺑﺘﻮاﻧﻴﺪ در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد ﺑﺎ ﻧﺮم اﻓﺰارﻫﺎي ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻧﻮع ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋـﺎﺗﻲ ،ﻣﺎﻧﻨـﺪ ،SQL Server Oracle ،Accessو ﻳﺎ Sybaseﻛﺎر ﻛﻨﻴﺪ. در وﻳﮋوال 2005 C#اﺑﺰارﻫﺎ و وﻳﺰاردﻫﺎي زﻳﺎدي ﺑﺮاي ﻣﺘﺼﻞ ﺷﺪن ﺑﻪ اﻧﻮاع ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ وﺟﻮد دارد .ﺑﻪ وﺳـﻴﻠﻪ ي اﻳـﻦ اﺑﺰارﻫـﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻃﻼﻋﺎت ﺧﻮد را در درون اﻳﻦ ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ ﻗﺮار دﻫﻴﺪ و ﻳﺎ آن را از ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ درﻳﺎﻓﺖ ﻛﺮده و ﺗﻐﻴﻴـﺮات ﻣـﻮرد ﻧﻈﺮ ﺧﻮد را روي آﻧﻬﺎ اﻧﺠﺎم دﻫﻴﺪ .در ﻃﻲ اﻳﻦ ﻓﺼﻞ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﺑﺎ اﻳﻦ اﺑﺰارﻫﺎ و ﻧﺤﻮه ي ﻛـﺎرﻛﺮد آﻧﻬـﺎ در ﺑﺮﻧﺎﻣـﻪ ﺑﻴـﺸﺘﺮ آﺷـﻨﺎ ﺷﻮﻳﻢ. در ﻓﺼﻞ ﺷﺎﻧﺰدﻫﻢ ﺗﻤﺮﻛﺰ ﺧﻮد را روي اﺳﺘﻔﺎده از ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ از ﻃﺮﻳﻖ ﻛﺪ ﻧﻮﻳﺴﻲ ﻗﺮار ﺧﻮاﻫﻴﻢ داد و ﻣﺸﺎﻫﺪه ﺧـﻮاﻫﻴﻢ ﻛـﺮد ﻛـﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان از ﻃﺮﻳﻖ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻪ ﺻﻮرت ﻣﺴﺘﻘﻴﻢ ﺑﻪ اﻳﻦ ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﺮد .ﺑﻌﺪ از اﻳﻨﻜﻪ ﻣﻘـﺪاري در ﻛـﺪ ﻧﻮﻳﺴﻲ ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ ﺗﻤﺮﻳﻦ ﻛﺮدﻳﺪ ،ﺧﻮاﻫﻴﺪ دﻳﺪ ﻛﻪ اﺳﺘﻔﺎده از ﻛﺪ ﻧﺴﺒﺖ ﺑﻪ اﺳﺘﻔﺎده از وﻳﺰاردﻫﺎ و اﺑﺰار ﻫﺎ زﻣﺎن ﺑـﺴﻴﺎر ﻛﻤﺘـﺮي را اﺷﻐﺎل ﻣﻲ ﻛﻨﺪ. در اﻳﻦ ﻓﺼﻞ:
ﺑﺎ ﻣﻔﻬﻮم ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. ﺑﺎ دﺳﺘﻮر SELECTدر زﺑﺎن SQLآﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ و از آن اﺳﺘﻔﺎده ﺧﻮاﻫﻴﺪ ﻛﺮد. ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي دﺳﺘﺮﺳﻲ ﺑﻪ داده ﻫﺎي درون ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﺪ ﻛﺮد. ﺑﺎ ﻧﺤﻮه ي اﺳﺘﻔﺎده از داده ﻫﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوز آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ. از وﻳﺰاردﻫﺎي دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت در وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005اﺳﺘﻔﺎده ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﻧﻜﺘﻪ :ﺑﺮاي اﻧﺠﺎم ﺗﻤﺮﻳﻨﺎت و ﻣﺜﺎل ﻫﺎي اﻳﻦ ﻓﺼﻞ ﻻزم اﺳﺖ ﻛﻪ ﻧﺴﺨﻪ ي ) 2000و ﻳـﺎ ﺑـﺎﻻﺗﺮ( ﺑﺮﻧﺎﻣـﻪ ي Accessﻛﻪ ﺟﺰﺋﻲ از ﺑﺮﻧﺎﻣﻪ ي Microsoft Officeﺑﻪ ﺷﻤﺎر ﻣﻲ رود را ﻧﺼﺐ ﻛﻨﻴﺪ.
Microsoft
ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﭼﻴﺴﺖ؟ اﺻﻮﻻ ﻫﺮ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ 1ﺷﺎﻣﻞ ﻳﻚ و ﻳﺎ ﭼﻨﺪ ﻓﺎﻳﻞ ﺑﺰرگ و ﭘﻴﭽﻴﺪه اﺳﺖ ﻛﻪ داده ﻫﺎ در آن در ﻳﻚ ﻗﺎﻟﺐ و ﻓﺮﻣﺖ ﺳـﺎﺧﺖ ﻳﺎﻓﺘـﻪ ذﺧﻴﺮه ﻣﻲ ﺷﻮﻧﺪ .ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ 2ﻣﻌﻤﻮﻻ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اي اﻃﻼق ﻣﻲ ﺷﻮد ﻛﻪ اﻳﻦ ﻓﺎﻳﻞ و ﻳﺎ ﻓﺎﻳﻠﻬﺎ و ﻧﻴﺰ داده ﻫﺎي درون آﻧﻬـﺎ را ﻣﺪﻳﺮﻳﺖ ﻣﻲ ﻛﻨﺪ .در ﻃﻲ اﻳﻦ ﻓﺼﻞ از ﺑﺮﻧﺎﻣﻪ ي Microsoft Accessﺑـﻪ ﻋﻨـﻮان ﻣﻮﺗـﻮر ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ اﺳـﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد.
Database Database Engine
1 2
٥٩٢
اﺷﻴﺎي ﻣﻮﺟﻮد در :Access ﻳﻚ ﻓﺎﻳﻞ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ) Accessﻛﻪ ﭘﺴﻮﻧﺪ آن ﻧﻴﺰ .mdbاﺳﺖ( ﻣﻌﻤـﻮﻻً از ﻗـﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻔـﻲ ﻣﺎﻧﻨـﺪ ﺟﺪوﻟﻬﺎ ،ﭘﺮس وﺟﻮ ﻫﺎ ،ﻓﺮم ﻫﺎ ،ﮔﺰارﺷﺎت ،ﻣﺎﻛﺮو ﻫﺎ و ﻣﺎژول ﻫﺎ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ .ﺑﻪ اﻳﻦ ﻗـﺴﻤﺘﻬﺎي ﺗـﺸﻜﻴﻞ دﻫﻨـﺪه ي ﻳـﻚ ﺑﺎﻧـﻚ اﻃﻼﻋﺎﺗﻲ ،اﺷﻴﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ 1ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد .در ﻳﻚ ﻓﺎﻳﻞ ﻣﺮﺑﻮط ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻋﻤﻮﻣﺎً داده ﻫﺎي زﻳﺎدي وﺟﻮد دارﻧﺪ و ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ ﻣﻮﺗﻮر ﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺎﻧﻨﺪ Accessﺳﻌﻲ ﻣﻲ ﻛﻨﻨﺪ ﺑﺎ اراﺋﻪ دادن اﻣﻜﺎﻧﺎت اﺿﺎﻓﻲ ،ﺑﻪ ﻛﺎرﺑﺮان اﺟﺎزه دﻫﻨﺪ ﺑﺎ اﻳـﻦ اﻃﻼﻋﺎت ﻛﺎر ﻛﻨﻨﺪ .در ﺑﻴﻦ اﺷﻴﺎﻳﻲ ﻛﻪ در ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ Accessوﺟﻮد دارﻧﺪ ،ﺟﺪوﻟﻬﺎ و ﭘﺮس وﺟﻮ ﻫﺎ ﺑـﺮاي ﻧﮕﻬـﺪاري داده ﻫﺎ و ﻳﺎ دﺳﺘﺮﺳﻲ ﺑﻪ آﻧﻬﺎ ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ .دﻳﮕﺮ اﺷﻴﺎي ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺎﻧﻨﺪ ﻓﺮم ﻫﺎ و ﻳﺎ ﮔﺰارﺷﺎت ﺑـﺮاي اﻳـﻦ اﺳـﺖ ﻛـﻪ ﻛـﺎرﺑﺮان ﺑﺘﻮاﻧﻨﺪ ﺑﻪ ﺳﺎدﮔﻲ ﺑﺎ داده ﻫﺎي ﻣﻮﺟﻮد در ﺟﺪاول ﻛﺎر ﻛﻨﻨﺪ. اﻣﺎ ﺑﻪ ﻫﺮ ﺣﺎل ﺑﻪ ﻋﻠﺖ ﭘﻴﭽﻴﺪه ﺑﻮدن ﺳﺎﺧﺘﺎر ﻣﻮﺗﻮر ﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ،ﻛﺎرﺑﺮان ﻣﻌﻤﻮﻟﻲ ﺣﺘﻲ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻗﺴﻤﺘﻬﺎ ﻧﻴﺰ ﻧﻤﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ درﺳﺘﻲ از اﻃﻼﻋﺎت درون ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺘﻔﺎده ﻛﻨﻨﺪ .ﻫﺪف ﻣﺎ از ﻧﻮﺷﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال C# 2005و ﻳﺎ ﻫﺮ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ دﻳﮕﺮ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﻴﻢ ﺑﻪ ﺳﺎدﮔﻲ از اﻃﻼﻋﺎت درون ﺑﺎﻧﻜﻬﺎ اﺳﺘﻔﺎده ﻛﻨﺪ .ﭘﺲ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻓﻘﻂ ﺑﻪ اﻃﻼﻋﺎت درون ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻧﻴﺎز ﺧﻮاﻫﻴﻢ داﺷﺖ ،ﻧﻪ ﺑﻪ ﻗﺴﻤﺘﻬﺎﻳﻲ ﻣﺎﻧﻨﺪ ﻓﺮم ﻫﺎ و ﻳﺎ ﮔﺰارﺷﺎت .ﺑﻨﺎﺑﺮاﻳﻦ در ﻃﻲ اﻳﻦ ﻓﺼﻞ ﺑﻴﺸﺘﺮ ﺗﻤﺮﻛﺰ ﺧﻮد را روي دو ﻗﺴﻤﺖ اﺻﻠﻲ ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ ﻳﻌﻨﻲ ﺟﺪوﻟﻬﺎ و ﭘﺮس وﺟﻮ ﻫﺎ ﻗﺮار ﻣﻲ دﻫﻴﻢ.
ﺟﺪوﻟﻬﺎ: ﻳﻚ ﺟﺪول 2ﺷﺎﻣﻞ ﻳﻚ ﻣﺠﻤﻮﻋﻪ از اﻃﻼﻋﺎت اﺳﺖ ﻛﻪ ﻣﻌﻤﻮﻻً ﺣﺎوي ﻳﻚ و ﻳﺎ ﭼﻨﺪ ﺳﺘﻮن و ﻧﻴﺰ ﻳﻚ و ﻳﺎ ﭼﻨﺪ ردﻳﻒ از داده ﻫﺎ اﺳـﺖ. در ) Accessو ﻧﻴﺰ ﺑﻴﺸﺘﺮ ﺑﺎﻧﻚ ﻫﺎي اﻃﻼﻋﺎﺗﻲ( ﺑﻪ ﻫﺮ ﻳﻚ از اﻳﻦ ﺳﺘﻮﻧﻬﺎ ﻳﻚ ﻓﻴﻠﺪ 3ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد .ﻫﻤﭽﻨﻴﻦ ﻫـﺮ ردﻳـﻒ از اﻳـﻦ اﻃﻼﻋﺎت ﻧﻴﺰ ﻳﻚ رﻛﻮرد 4ﻧﺎﻣﻴﺪه ﻣﻲ ﺷﻮﻧﺪ .ﻫﺮ ﻓﻴﻠﺪ در ﻳﻚ ﺟﺪول از ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ ،ﻳﻜـﻲ از ﻣﺸﺨـﺼﻪ ﻫـﺎي داده اي ﻛـﻪ در آن ﺟﺪول ذﺧﻴﺮه ﺷﺪه اﺳﺖ را ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻓﻴﻠﺪي ﺑﻪ ﻧﺎم FirstNameدر ﻳﻚ ﺟـﺪول ،ﻣـﺸﺨﺺ ﻛﻨﻨـﺪه ي ﻧـﺎم ﻣﺸﺘﺮك و ﻳﺎ ﻛﺎرﻣﻨﺪي اﺳﺖ ﻛﻪ اﻃﻼﻋﺎت او در آن ﺟﺪول ذﺧﻴﺮه ﺷﺪه اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ اﻳﻦ ﻓﻴﻠﺪ ﻳﻜﻲ از ﻣﺸﺨﺼﻪ ﻫـﺎي آن ﻛﺎرﻣﻨـﺪ و ﻳـﺎ ﻣﺸﺘﺮك را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .در ﻫﺮ ﺟﺪول ،ﻳﻚ رﻛﻮرد ﺷﺎﻣﻞ ﻳﻚ ﻣﺠﻤﻮﻋﻪ از ﻓﻴﻠﺪ ﻫﺎ اﺳﺖ ﻛﻪ اﻃﻼﻋﺎت و ﻣﺸﺨﺼﻪ ﻫـﺎي ﻣﺮﺑـﻮط ﺑـﻪ ﻳﻚ ﻧﻤﻮﻧﻪ از داده ﻫﺎﻳﻲ ﻛﻪ در آن ﺟﺪول ذﺧﻴﺮه ﺷﺪه اﺳﺖ را ﻧﺸﺎن ﻣﻲ دﻫﺪ .ﺑﺮاي ﻣﺜﺎل ﺟﺪوﻟﻲ را در ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ ﻛﻪ داراي دو ﻓﻴﻠﺪ )دو ﺳﺘﻮن اﻃﻼﻋﺎت( ﺑﻪ ﻧﺎﻣﻬﺎي FirstNameو LastNameاﺳﺖ و ﺑﺮاي ﻧﮕﻬﺪاري اﺳﺎﻣﻲ ﻛﺎرﻣﻨﺪان اﺳـﺘﻔﺎده ﻣـﻲ ﺷـﻮد .ﺑـﻪ ﻣﺠﻤﻮﻋﻪ ي ﻧﺎم و ﻧﺎم ﺧﺎﻧﻮادﮔﻲ ﻫﺮ ﻛﺎرﻣﻨﺪي ﻛﻪ اﻃﻼﻋﺎت او در اﻳﻦ ﺟﺪول وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ ﻳﻚ رﻛﻮرد ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد. ﺑﺮاي ﻣﺜﺎل در ﺷﻜﻞ FirstName ،EmployeeID ،1-15و ...ﻓﻴﻠﺪ ﻫﺎي اﻳﻦ ﺟﺪول و ﻫﺮ ردﻳﻒ از اﻃﻼﻋﺎت ﻧﻴﺰ رﻛـﻮرد ﻫﺎي آن را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ.
1
Database Objects Table 3 Field 4 Record 2
٥٩٣
ﺷﻜﻞ 1-15
ﭘﺮس وﺟﻮ ﻫﺎ: در ﻫﺮ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻋﻤﻮﻣﺎً ﺑﻪ ﻳﻚ ﺳﺮي از دﺳﺘﻮرات ﻛﻪ زﺑﺎن ) SQL1ﺑﻪ ﺻﻮرت "اس-ﻛﻴﻮ-ال" و ﻳﺎ "ﺳـﻲ ﻛـﻮ ال" ﺗﻠﻔـﻆ ﻣـﻲ ﺷﻮد( ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ و ﺑﺮاي درﻳﺎﻓﺖ اﻃﻼﻋﺎت از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ و ﻳﺎ اﻳﺠﺎد ﺗﻐﻴﻴﺮاﺗﻲ در اﻃﻼﻋﺎت ﻣﻮﺟﻮد در ﺑﺎﻧﻚ ﺑـﻪ ﻛـﺎر ﻣـﻲ رود، ﻳﻚ ﭘﺮس وﺟﻮ 2ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد .ﺑﺎ اﺳﺘﻔﺎده از ﭘﺮس وﺟﻮ ﻫﺎ ﻣﻲ ﺗﻮاﻧﻴﻢ داده ﻫﺎﻳﻲ را درون ﺟﺪول ﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ وارد ﻛﻨﻴﻢ ،آﻧﻬﺎ را از ﻳﻚ و ﻳﺎ ﭼﻨﺪ ﺟﺪول ﺑﺪﺳﺖ آورده و ﻳﺎ ﺗﻐﻴﻴﺮاﺗﻲ را در آﻧﻬﺎ اﻳﺠﺎد ﻛﻨﻴﻢ. در ﻳﻚ ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﻪ دو روش ﻣﻲ ﺗﻮاﻧﻴﻢ از ﭘﺮس وﺟﻮ ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .اول اﻳﻦ اﺳﺖ ﻛﻪ ﻳﻚ دﺳﺘﻮر SQLرا ﺑﻨﻮﻳـﺴﻴﻢ و ﺳﭙﺲ آن را اﺟﺮا ﻛﺮده و ﻧﺘﻴﺠﻪ ي آن را ﻣﺸﺎﻫﺪه ﻛﻨﻴﻢ .روش دوم اﻳﻦ اﺳﺖ ﻛﻪ ﻫﻤﺎﻧﻨﺪ دﻳﮕﺮ زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻳﻚ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﺑـﺎ اﺳﺘﻔﺎده از دﺳﺘﻮرات SQLاﻳﺠﺎد ﻛﻨﻴﻢ و ﺳﭙﺲ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ آن زﻳﺮ ﺑﺮﻧﺎﻣﻪ اﻃﻼﻋﺎت ﻻزم را از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺪﺳﺖ آورﻳﻢ .3در ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ زﺑﺎن وﻳﮋوال C#ﻣﻲ ﻧﻮﻳﺴﻴﻢ ﻧﻴﺰ ،ﻫﻢ ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻳﻚ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت ﻣﻮرد ﻧﻴﺎز اﺳـﺘﻔﺎده ﻛﻨـﻴﻢ و ﻫﻢ ﻣﻲ ﺗﻮاﻧﻴﻢ دﺳﺘﻮر SQLﻣﻮرد ﻧﻴﺎز را ﺑﺎ اﺳﺘﻔﺎده از ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ ﺑﻔﺮﺳـﺘﻴﻢ و ﻧﺘـﺎﻳﺞ ﺣﺎﺻـﻞ را درﻳﺎﻓـﺖ ﻛـﺮده و ﻧﻤﺎﻳﺶ دﻫﻴﻢ. اﻟﺒﺘﻪ اﺳﺘﻔﺎده از زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻳﻚ ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻧﺴﺒﺖ ﺑﻪ دﺳﺘﻮرات ﻣﻌﻤﻮﻟﻲ از ﺳﺮﻋﺖ ﺑﻴـﺸﺘﺮي ﺑﺮﺧـﻮردار اﺳـﺖ. زﻳﺮا ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﻲ ﺗﻮاﻧﺪ دﺳﺘﻮرات درون آن زﻳﺮ ﺑﺮﻧﺎﻣﻪ را ﺗﺤﻠﻴﻞ ﻛﺮده و ﻳﻚ روش ﻛﻠﻲ ﺑﺮاي ﺳﺮﻳﻌﺘﺮ اﺟﺮا ﻛﺮدن آن اﻳﺠﺎد ﻛﻨﺪ ) ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﻲ ﺗﻮاﻧﺪ آﻧﻬﺎ را ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﺪ( .اﻣﺎ دﺳﺘﻮراﺗﻲ ﻛﻪ ﺑﻪ ﺻﻮرت ﻋﺎدي ﺑﻪ ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﻲ دﻫـﻴﻢ ﺗـﺎ آﻧﻬـﺎ را اﺟﺮا ﻛﻨﺪ و داده ﻫﺎي ﻣﺮﺑﻮط را ﺑﺮﮔﺮداﻧﺪ ﻫﺮ ﻣﺮﺗﺒﻪ ﻻزم اﺳﺖ ﻛﻪ ﺗﻔﺴﻴﺮ ﺷﺪه و ﺳﭙﺲ اﺟﺮا ﺷﻮﻧﺪ و اﻳﻦ ﻣﻮرد ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﺳـﺮﻋﺖ اﺟﺮاي ﻛﻤﺘﺮي ﻧﺴﺒﺖ ﺑﻪ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ داﺷﺘﻪ ﺑﺎﺷﻨﺪ. ﺑﺮاي درك ﺑﻬﺘﺮ ﻣﻔﻬﻮم ﭘﺮس وﺟﻮ ﻫﺎ ﺑﻬﺘﺮ اﺳﺖ اﺑﺘﺪا ﻣﻘﺪاري ﺑﺎ زﺑـﺎن SQLو دﺳـﺘﻮرات آن آﺷـﻨﺎ ﺷـﻮﻳﻢ .ﺧﻮﺷـﺒﺨﺘﺎﻧﻪ ،زﺑـﺎن SQL ﻧﺴﺒﺖ ﺑﻪ زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ دﻳﮕﺮ ﺑﺴﻴﺎر ﺳﺎده ﺗﺮ اﺳﺖ و ﺑﻪ ﺳﺮﻋﺖ ﻣﻲ ﺗﻮان ﻧﺤﻮه ي اﺳﺘﻔﺎده از آن را ﻳﺎد ﮔﺮﻓﺖ.
1
Structured Query Language Query 3ﺑﻪ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي ﭘﺮس وﺟﻮ از ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد ،زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻫـﺎي ذﺧﻴـﺮه ﺷـﺪه و ﻳـﺎ Stored Proceduresﮔﻔﺘـﻪ ﻣﻲ ﺷﻮد. 2
٥٩٤
دﺳﺘﻮر SELECTدر زﺑﺎن :SQL زﺑﺎن SQLﺑﺮ ﺧﻼف ﭼﻴﺰي ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺗﺼﻮر ﻛﻨﻴﺪ ،زﻳﺎد ﻣﺸﺎﺑﻪ زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻛﻪ ﺗﺎﻛﻨﻮن دﻳﺪه اﻳﺪ ﻧﻴﺴﺖ .دﺳﺘﻮرات اﻳـﻦ زﺑﺎن ﺑﻪ وﺳﻴﻠﻪ ي ﻣﻮﺳﺴﻪ ي اﺳﺘﺎﻧﺪارد ﻣﻠﻲ آﻣﺮﻳﻜﺎ ) (ANSIﺑﻪ ﺻﻮرت اﺳﺘﺎﻧﺪارد در آﻣﺪه اﺳﺖ .ﻧـﺴﺨﻪ ي اﺳـﺘﺎﻧﺪارد اﻳـﻦ زﺑـﺎن ﻛـﻪ ANSI SQLﻧﻴﺰ ﻧﺎﻣﻴﺪه ﻣﻲ ﺷﻮد ،ﺑﻪ وﺳﻴﻠﻪ ي ﺗﻤﺎم ﻣﻮﺗﻮر ﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ ﺷﻮد .اﻣﺎ ﻫﺮ ﻳﻚ از اﻳﻦ ﻣﻮﺗﻮر ﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﻣﻜﺎﻧﺎت ﻣﺨﺼﻮص ﺑﻴﺸﺘﺮي را ﻧﻴﺰ ﺑﻪ اﻳﻦ زﺑﺎن اﺿﺎﻓﻪ ﻛﺮده اﻧﺪ ﻛﻪ ﻣﻌﻤﻮﻻً ﻓﻘﻂ در ﻫﻤﺎن ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ ﻗﺎﺑـﻞ اﺳﺘﻔﺎده اﺳﺖ. ﻣﺰاﻳﺎي ﻳﺎدﮔﻴﺮي ANSI SQLدر اﻳﻦ اﺳﺖ ﻛﻪ ،ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﺻﻮل دﺳﺘﻮرات زﺑﺎن SQLرا آﻣﻮﺧﺘﻴﺪ ﻣـﻲ ﺗﻮاﻧﻴـﺪ از آﻧﻬﺎ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ SQLدر ﺗﻤﺎم ﻣﻮﺗﻮر ﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺮاي اﻳـﻦ ﻛـﻪ ﺑﺘﻮاﻧﻴـﺪ ﻣﻮﺗـﻮر ﺑﺎﻧـﻚ اﻃﻼﻋﺎﺗﻲ ﺧﻮد را ﺗﻐﻴﻴﺮ دﻫﻴﺪ ،ﻓﻘﻂ ﻛﺎﻓﻲ اﺳﺖ ﻧﺤﻮه ي ﻛﺎرﻛﺮد ﺑﺎ راﺑﻂ ﮔﺮاﻓﻴﻜﻲ آن را ﻳـﺎد ﺑﮕﻴﺮﻳـﺪ و ﺳـﭙﺲ ﻣـﻲ ﺗﻮاﻧﻴـﺪ از دﺳـﺘﻮرات SQLاﺳﺘﺎﻧﺪارد در آن ﻣﺤﻴﻂ ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻟﺒﺘﻪ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﻫﺮ ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ داراي دﺳﺘﻮرات ﺧﺎص ﺧﻮد اﺳﺖ ك ﺑﺎﻋﺚ اﻓﺰاﻳﺶ ﻛﺎراﻳﻲ و ﺑﻬﻴﻨﻪ ﺳﺎﺧﺘﻦ اﺟﺮاي دﺳﺘﻮرات ﻣﻲ ﺷﻮد .اﻣﺎ ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﺑﻬﺘﺮ اﺳﺖ از اﻳﻦ دﺳﺘﻮرات در ﺑﺮﻧﺎﻣﻪ اي ﺧﻮد اﺳـﺘﻔﺎده ﻧﻜﻨﻴﺪ و دﺳﺘﻮرات اﺳﺘﺎﻧﺪارد SQLرا ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻫﺮ زﻣﺎن ﻛﻪ ﻻزم ﺑﺎﺷﺪ ﺑﻪ ﺳﺎدﮔﻲ ﻣﻮﺗـﻮر ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ ﺧﻮد را ﺗﻐﻴﻴﺮ دﻫﻴﺪ. زﺑﺎن SQLاز ﺗﻌﺪاد ﻛﻤﻲ دﺳﺘﻮر ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ ﻛﻪ ﻫﺮ ﻳﻚ ﻛﺎر ﺧﺎﺻﻲ را اﻧﺠﺎم ﻣﻲ دﻫﻨﺪ .ﻳﻜﻲ از ﭘﺮ ﻛﺎرﺑﺮد ﺗﺮﻳﻦ و ﻣﻬﻤﺘﺮﻳﻦ اﻳﻦ دﺳﺘﻮرات ،دﺳﺘﻮر SELECTاﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آن ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﻳﺎ ﭼﻨﺪ ﻓﻴﻠﺪ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﻳﺎ ﭼﻨﺪ رﻛـﻮرد در ﺟـﺪاول ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺧﻮد را ﺑﺪﺳﺖ آورﻳﺪ .اﻟﺒﺘﻪ دﻗﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي دﺳﺘﻮر SELECTﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﻴﺪ داده ﻫﺎ را از ﺟـﺪاول ﺑﺪﺳﺖ آورﻳﺪ ،اﻣﺎ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﻫﻴﭻ ﺗﻐﻴﻴﺮي در آﻧﻬﺎ اﻳﺠﺎد ﻛﻨﻴﺪ. ﺳﺎده ﺗﺮﻳﻦ دﺳﺘﻮر SELECTدر زﺑﺎن SQLﻣﺸﺎﺑﻪ دﺳﺘﻮر زﻳﺮ اﺳﺖ: ;SELECT * FROM Employees اﻳﻦ دﺳﺘﻮر ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻔﻬﻮم ﻛﻠﻤﺎت آن ﻧﻴﺰ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻨﺪ ،ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ " اﻃﻼﻋﺎت ﻣﻮﺟﻮد در ﺗﻤﺎم ﻓﻴﻠﺪ ﻫـﺎي ﻣﺮﺑـﻮط ﺑﻪ ﻫﻤﻪ ي رﻛﻮرد ﻫﺎي ﺟﺪول Employeesرا اﻧﺘﺨﺎب ﻛﻦ " .ﻋﻼﻣﺖ * در دﺳﺘﻮر SELECTﺑـﻪ ﻣﻌﻨـﻲ "ﺗﻤـﺎم ﻓﻴﻠـﺪ ﻫـﺎ" اﺳﺖ .ﻛﻠﻤﻪ ي Employeesﻧﻴﺰ ﻧﺎم ﺟﺪوﻟﻲ در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺖ ﻛﻪ اﻳﻦ دﺳﺘﻮر ﺑﺎﻳﺪ ﺑﺮ روي آن اﺟﺮا ﺷﻮد. اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻓﻘﻂ ﻓﻴﻠﺪ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻧﺎم و ﻧﺎم ﺧﺎﻧﻮادﮔﻲ اﻓﺮادي ﻛﻪ اﻃﻼﻋﺎت آﻧﻬﺎ در ﺟـﺪول Employeesوارد ﺷـﺪه اﺳـﺖ را ﺑﺪﺳﺖ آورﻳﺪ ،ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﻋﻼﻣﺖ * را ﺑﺎ ﻧﺎم ﻓﻴﻠﺪ ﻫﺎي ﻣﻮرد ﻧﻈﺮ ﺧﻮد ﺑﻪ ﺻﻮرت زﻳﺮ ﻋﻮض ﻛﻨﻴﺪ: ;SELECT [First Name], [Last Name] FROM Employees دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻫﻨﮕﺎم وارد ﻛﺮدن اﻳﻦ دﺳﺘﻮر ﺣﺘﻤﺎً ﺑﺎﻳﺪ از ﻋﻼﻣﺖ ﺑﺮﻳﺲ )][( در اﺑﺘﺪاي ﻧﺎم ﻓﻴﻠﺪ ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .زﻳﺮا ﻧﺎم اﻳﻦ ﻓﻴﻠﺪ ﻫـﺎ ﺣﺎوي ﻓﻀﺎي ﺧﺎﻟﻲ ) (Spaceاﺳﺖ و ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ در ﺗﻔـﺴﻴﺮ ﻧـﺎم First Nameﺑـﺎ ﻣـﺸﻜﻞ ﻣﻮاﺟـﻪ ﺷـﻮد. اﺳﺘﻔﺎده از ﺑﺮﻳﺲ ﺑﻪ ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﻲ ﮔﻮﻳﺪ ﻛﻪ ﺗﺎ ﺑﺴﺘﻪ ﺷﺪن ﺑﺮﻳﺲ را ﺑﻪ ﻋﻨﻮان ﻳﻚ ﻧﺎم در ﻧﻈﺮ ﺑﮕﻴﺮد .اﻟﺒﺘﻪ اﮔﺮ ﻧﺎم اﻳﻦ ﻓﻴﻠـﺪ ﺣﺎوي ﻛﺎراﻛﺘﺮ ﻓﻀﺎي ﺧﺎﻟﻲ ﻧﺒﻮد ﻣﻲ ﺗﻮاﻧﺴﺘﻴﺪ از اﻳﻦ ﺑﺮﻳﺴﻬﺎ اﺳﺘﻔﺎده ﻧﻜﻨﻴﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ دﺳﺘﻮرات SQLﻫﻤﺎﻧﻨﺪ زﺑﺎن اﻧﮕﻠﻴﺴﻲ ﻋﺎدي و روزﻣﺮه ﻫﺴﺘﻨﺪ و ﺣﺘﻲ ﻓﺮدي ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻧﻴﺴﺖ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺪ آن را ﺧﻮاﻧﺪه و ﻣﻔﻬﻮم آن را درك ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﻓﻘﻂ داده ﻫـﺎﻳﻲ ﻛـﻪ داراي ﺷـﺮط ﺧﺎﺻـﻲ ﻫـﺴﺘﻨﺪ از ﺟـﺪول اﻧﺘﺨﺎب ﺷﺪه و ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ ،ﻛﺎﻓﻲ اﺳﺖ از ﻋﺒﺎرت WHEREدر ﭘﺎﻳﺎن دﺳﺘﻮر SELECTاﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﻣﺜﻼً اﮔـﺮ ﺑﺨـﻮاﻫﻴﻢ در دﺳﺘﻮر ﻗﺒﻞ ﻓﻘﻂ اﻓﺮادي ﻛﻪ ﻧﺎم ﺧﺎﻧﻮادﮔﻲ آﻧﻬﺎ ﺑﺎ ﺣﺮف Dﺷﺮوع ﻣﻲ ﺷﻮﻧﺪ اﻧﺘﺨﺎب ﺷﻮﻧﺪ ،ﺑﺎﻳﺪ از دﺳﺘﻮر زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﻢ:
٥٩٥
SELECT [First Name], [Last Name] FROM Employees ;’*WHERE [Last Name] LIKE ‘D ﻋﺒﺎرت WHEREﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻓﻘﻂ داده ﻫﺎﻳﻲ از ﺟﺪول اﻧﺘﺨﺎب ﺷﻮﻧﺪ ﻛﻪ در ﺷـﺮط ﻣﻘﺎﺑـﻞ ﻋﺒـﺎرت WHEREﺻـﺪق ﻣـﻲ ﻛﻨﻨـﺪ. ﺑﻨﺎﺑﺮاﻳﻦ دﺳﺘﻮر SELECTﻗﺒﻠﻲ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛـﻪ ﻣﻮﺗـﻮر ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ ﺑـﻪ داﺧـﻞ ﺟـﺪول Employeesﺑـﺮود و ﻓﻴﻠـﺪ First Nameو Last Nameﺗﻤﺎم رﻛﻮرد ﻫﺎﻳﻲ ﻛﻪ Last Nameآﻧﻬﺎ ﺑﺎ ﺣﺮف Dﺷـﺮوع ﻣـﻲ ﺷـﻮد را اﻧﺘﺨـﺎب ﻛﻨﺪ .ﻋﺒﺎرت ’* ‘Dﻧﻴﺰ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ "ﻫﺮ ﻋﺒﺎرﺗﻲ ﻛﻪ ﺑﺎ ﺣﺮف Dﺷﺮوع ﺷﺪه اﺳﺖ" .ﺑﺮاي ﻣﺜﺎل ﻋﺒﺎرت ’* ‘*Dﺑـﻪ اﻳـﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ "ﻫﺮ ﻋﺒﺎرﺗﻲ ﻛﻪ در آن ﺣﺮف Dوﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ". در آﺧﺮ ﻧﻴﺰ ﺑﻌﺪ از اﻳﻨﻜﻪ داده ﻫﺎي ﻣﻮرد ﻧﻈﺮ ﺧﻮد را اﻧﺘﺨﺎب ﻛﺮدﻳﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ آﻧﻬﺎ را ﺑﻪ ﻧﺤﻮي ﻛﻪ ﺗﻤﺎﻳﻞ دارﻳﺪ ﺑﻪ ﺻﻮرت ﺻـﻌﻮدي و ﻳـﺎ ﻧﺰوﻟﻲ ﻣﺮﺗﺐ ﻛﻨﻴﺪ ،ﺑﺮاي ﻣﺜﺎل ﺑﺮ اﺳﺎس ﻓﻴﻠﺪ .First Nameﺑﺮاي اﻳـﻦ ﻛـﺎر ﺑﺎﻳـﺪ در اﻧﺘﻬـﺎي دﺳـﺘﻮر SELECTاز ﻋﺒـﺎرت ORDER BYاﺳﺘﻔﺎده ﻛﻨﻴﺪ: SELECT [First Name], [Last Name] FROM Employees ;]WHERE [Last Name] LIKE ‘D*’ ORDER BY [First Name اﺟﺮاي اﻳﻦ دﺳﺘﻮر ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد اﻃﻼﻋﺎﺗﻲ ﻛﻪ از ﺟﺪول اﻧﺘﺨﺎب ﻣﻲ ﺷﻮﻧﺪ ،ﻗﺒﻞ از ﻧﻤـﺎﻳﺶ داده ﺷـﺪن ﺑـﺮ اﺳـﺎس ﻓﻴﻠـﺪ First Nameو ﺑﻪ ﺻﻮرت ﺻﻌﻮدي ﻣﺮﺗﺐ ﺷﻮﻧﺪ .ﺑﺮاي ﻣﺜﺎل ﺧﺮوﺟﻲ اﻳﻦ دﺳﺘﻮر ﻣﻲ ﺗﻮاﻧﺪ ﻣﺎﻧﻨﺪ زﻳﺮ ﺑﺎﺷﺪ: Dunn Dunstan Dean
Angela David Zebedee
ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ در اﻳﻦ ﻗﺴﻤﺖ از ﻳﻚ دﺳﺘﻮر ﺗﻘﺮﻳﺒﺎً ﻛﺎﻣﻞ اﺳﺘﻔﺎده ﻛﺮدﻳﻢ ،اﻣﺎ درك آن ﻧﻴﺰ ﺑﺴﻴﺎر ﺳﺎده ﺑﻮد و ﺗﻘﺮﻳﺒﺎً ﺑﺴﻴﺎر ﻣﺸﺎﺑﻪ ﭼﻴﺰي ﺑﻮد ﻛﻪ در زﺑﺎن اﻧﮕﻠﻴﺴﻲ ﺑﺮاي ﺑﻴﺎن ﻣﻨﻈﻮر ﺧﻮد ﺑﺎﻳﺪ ﻋﻨﻮان ﻛﻨﻴﺪ .ﻣﻌﻤﻮﻻً ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻃﻼﻋﺎت را ﺑـﺮ اﺳـﺎس ﻓﻴﻠـﺪ ﻫـﺎي رﺷﺘﻪ اي ﻣﺮﺗﺐ ﻣﻲ ﻛﻨﻴﺪ ،داده ﻫﺎ ﺑﻪ ﺻﻮرت ﺻﻌﻮدي ﻣﺮﺗﺐ ﻣﻲ ﺷﻮﻧﺪ .ﺑﻪ اﻳﻦ ﺻﻮرت ﻛﻪ اﻃﻼﻋﺎت ﺑﺎ ﺣﺮف Aاﺑﺘﺪا و اﻃﻼﻋﺎت ﺑﺎ ﺣﺮف Zدر اﻧﺘﻬﺎ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ .اﻣﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ اﻃﻼﻋﺎت را ﺑﺮ اﺳﺎس ﻳﻚ ﻓﻴﻠﺪ ﻋﺪدي ﻣﺮﺗـﺐ ﻛﻨﻴـﺪ ،ﻣﻤﻜـﻦ اﺳـﺖ ﺗﻤﺎﻳـﻞ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ داده ﻫﺎي ﺑﺰرﮔﺘﺮ اﺑﺘﺪا ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ .ﺑﺮاي ﻣﺜﺎل ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ اﻃﻼﻋﺎﺗﻲ ﻛﻪ اﻧﺘﺨﺎب ﻣﻲ ﺷﻮﻧﺪ ،ﺑـﺮ اﺳـﺎس ﻗﻴﻤﺖ ﻛﺎﻻ ﻣﺮﺗﺐ ﺷﺪه و ﻛﺎﻻﻫﺎي ﮔﺮاﻧﺘﺮ ﻧﻴﺰ در ﺑﺎﻻي ﺟﺪول ﻗﺮار ﺑﮕﻴﺮﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻻزم اﺳﺖ ﻛﻪ اﻃﻼﻋﺎت را ﺑﻪ ﺻﻮرت ﻧﺰوﻟـﻲ ﻣﺮﺗـﺐ ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺎﻓﻲ اﺳﺖ در ﭘﺎﻳﺎن دﺳﺘﻮر ORDER BYاز ﻋﺒﺎرت DESC1اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ داده ﻫﺎ ﺑﻪ ﺻـﻮرت ﻧﺰوﻟﻲ ﻣﺮﺗﺐ ﺧﻮاﻫﻨﺪ ﺷﺪ. SELECT [First Name], [Last Name] FROM Employees ;WHERE [Last Name] LIKE ‘D*’ ORDER BY [First Name] DESC اﺟﺮاي دﺳﺘﻮر ﺑﺎﻻ ﻧﺘﺎﻳﺠﻲ را ﻣﺸﺎﺑﻪ زﻳﺮ ﺑﺮﻣﻲ ﮔﺮداﻧﺪ: Dean Dunstan
Zebedee David Descending
1
٥٩٦
Dunn
Angela
ﻧﻜﺘﻪ :اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ در دﺳﺘﻮر ﺧﻮد ﻣﺸﺨﺼﺎً ﻗﻴﺪ ﻛﻨﻴﺪ ﻛﻪ اﻃﻼﻋﺎت ﺑﺎﻳﺪ ﺑﺮ اﺳﺎس ﺻﻌﻮدي ﻣﺮﺗﺐ ﺷﻮﻧﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ در اﻧﺘﻬﺎي دﺳـﺘﻮر ORDER BYاز ﻋﺒﺎرت ASCاﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻟﺒﺘﻪ اﺳﺘﻔﺎده از اﻳﻦ ﻋﺒﺎرت اﻟﺰاﻣﻲ ﻧﻴﺴﺖ زﻳﺮا ﺑﻪ ﺻﻮرت ﭘـﻴﺶ ﻓـﺮض اﻃﻼﻋـﺎت ﺑـﻪ ﺻﻮرت ﺻﻌﻮدي ﻣﺮﺗﺐ ﻣﻲ ﺷﻮﻧﺪ. ﺑﻪ ﻃﻮر ﺧﻼﺻﻪ ﻣﻲ ﺗﻮان ﮔﻔﺖ ﻛﻪ دﺳﺘﻮر SELECTﻣﻲ ﺗﻮاﻧﺪ ﺑﺎ ﺳﺎﺧﺘﺎري ﻣﺸﺎﺑﻪ زﻳﺮ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد: SELECT select-list FROM table-name ][WHERE search-condition ]][ORDER BY order-by-expression [ASC | DESC اﻳﻦ ﻋﺒﺎرت ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ در ﻗﺴﻤﺖ select-listﺣﺘﻤﺎً ﺑﺎﻳﺪ ﻟﻴﺴﺘﻲ از ﻧﺎم ﻓﻴﻠﺪ ﻫﺎي ﻣﻮرد ﻧﻈﺮ و ﻳﺎ ﻋﻼﻣﺖ * ﺑـﺮاي اﻧﺘﺨـﺎب ﺗﻤﺎم ﻓﻴﻠﺪ ﻫﺎ را ذﻛﺮ ﻛﻨﻴﺪ .ﻫﻤﭽﻨﻴﻦ در ﻗﺴﻤﺖ table-listﻧﻴﺰ ﺑﺎﻳﺪ ﻧﺎم ﺟﺪول ﻣﻮرد ﻧﻈﺮ را ﺑﻴﺎورﻳﺪ .ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻋﺒﺎرت WHEREدر دﺳﺘﻮر SELECTﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻓﻘﻂ داده ﻫﺎﻳﻲ ﻛﻪ در ﺷﺮط search-conditionﺻﺪق ﻣﻲ ﻛﻨﻨـﺪ اﻧﺘﺨـﺎب ﺧﻮاﻫﻨﺪ ﺷﺪ .ﺑﺎ اﺳﺘﻔﺎده از ﻗﺴﻤﺖ ORDER BYﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ داده ﻫﺎ را ﻣﺮﺗﺐ ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳـﺪ در ﻗـﺴﻤﺖ order-by- expressionﻓﻴﻠﺪي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ داده ﻫﺎ ﺑﺮ اﺳﺎس آن ﻣﺮﺗﺐ ﺷﻮﻧﺪ را ذﻛﺮ ﻛﻨﻴﺪ .ﺑﺮاي ﺻﻌﻮدي و ﻳﺎ ﻧﺰوﻟﻲ ﺑﺪون ﻣﺮﺗﺐ ﺳﺎزي ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻋﺒﺎرت ASCو ﻳﺎ DESCدر اﻧﺘﻬﺎي دﺳﺘﻮر اﺳﺘﻔﺎده ﻛﻨﻴﺪ. اﻟﺒﺘﻪ اﮔﺮ ﺑﺨﻮاﻫﻴﺪ داده ﻫﺎ را از ﭼﻨﺪﻳﻦ ﺟﺪول ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺘﺨﺮاج ﻛﻨﻴﺪ و ﻳﺎ ﺑﺮ اﺳﺎس راﺑﻄﻪ ي ﺧﺎﺻﻲ ﺑـﻪ داده ﻫـﺎ دﺳﺘﺮﺳـﻲ ﭘﻴﺪا ﻛﻨﻴﺪ ،دﺳﺘﻮرات SQLﺑﻪ ﻣﻘﺪار ﻗﺎﺑﻞ ﻣﻼﺣﻈﻪ اي ﭘﻴﭽﻴﺪه ﺧﻮاﻫﻨﺪ ﺷﺪ ﻛﻪ ﺗﻮﺿﻴﺢ اﻳﻦ ﮔﻮﻧﻪ دﺳﺘﻮرات از اﻫﺪاف اﻳـﻦ ﻛﺘـﺎب ﺧـﺎرج اﺳﺖ و در ﺑﺮﻧﺎﻣﻪ ﻫﺎي اﻳﻦ ﻓﺼﻞ و ﻓﺼﻞ ﺑﻌﺪ ﻧﻴﺰ ﺑﻪ آﻧﻬﺎ ﻧﻴﺎزي ﻧﺨﻮاﻫﻴﻢ داﺷﺖ. در ﻫﺮ ﺣﺎل ﺑﻬﺘﺮﻳﻦ روش ﺑﺮاي ﻳﺎدﮔﻴﺮي ﻧﺤﻮه ي اﺳﺘﻔﺎده از دﺳﺘﻮرات ،SQLﺗﻤﺮﻳﻦ و ﻛﺎر ﻛﺮدن ﺑﺎ اﻳﻦ دﺳﺘﻮرات اﺳـﺖ .ﻗﺒـﻞ از اﻳـﻦ ﻛﻪ ﺑﻪ اداﻣﻪ ي ﻓﺼﻞ ﺑﭙﺮدازﻳﻢ ﺑﻬﺘﺮ اﺳﺖ ﺑﻪ ﺳﻮاﻻت زﻳﺮ ﺑﻪ ﺻﻮرت ذﻫﻨﻲ ﭘﺎﺳﺦ دﻫﻴﺪ.
ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻳﻚ دﺳﺘﻮر SELECTﺑﻨﻮﻳﺴﻴﻢ ﻛﻪ داده ﻫﺎي ﻣﻮﺟﻮد در ﻓﻴﻠﺪ ﻫﺎي Description ،Name و Priceرا از ﻳﻚ ﺟﺪول ﺑﻪ ﻧﺎم Productsاﺳﺘﺨﺮاج ﻛﻨﺪ؟ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان دﺳﺘﻮر ﺑﺎﻻ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ داد ﺗﺎ ﻓﻘﻂ داده ﻫﺎﻳﻲ را ﺑﺮﮔﺮداﻧﺪ ﻛﻪ در ﻓﻴﻠﺪ Descriptionآﻧﻬـﺎ ﻋﺒﺎرت DVDوﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ؟ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان اﻃﻼﻋﺎت ﺑﺎﻻ را ﺑﺮ اﺳﺎس ﻗﺴﻤﺖ ﺑﻪ ﮔﻮﻧﻪ اي ﻣﺮﺗﺐ ﻛﺮد ﻛﻪ اﺟﻨﺎس ﮔﺮاﻧﺘﺮ در اﺑﺘﺪاي ﺟﺪول ﻗﺮار ﺑﮕﻴﺮﻧﺪ؟
ﭘﺮس وﺟﻮ ﻫﺎ در :Access در ﻛﺎر ﺑﺎ ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ ،زﺑﺎن SQLاز اﻫﻤﻴﺖ ﺧﺎﺻﻲ ﺑﺮﺧﻮردار اﺳﺖ .ﺑﻪ ﮔﻮﻧﻪ اي ﻛـﻪ اﮔـﺮ ﺑﺨﻮاﻫﻴـﺪ ﺑﺮﻧﺎﻣـﻪ اي ﺑﻨﻮﻳـﺴﻴﺪ ﻛـﻪ از ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ و داده ﻫﺎي درون آن اﺳﺘﻔﺎده ﻛﻨﺪ ،در ﻣﻮاﻗﻊ زﻳﺎدي ﺑﻪ اﺳﺘﻔﺎده از اﻳﻦ زﺑـﺎن ﻧﻴـﺎز ﭘﻴـﺪا ﺧﻮاﻫﻴـﺪ ﻛـﺮد .در ﺑﺮﻧﺎﻣـﻪ ي Accessاﺑﺰارﻫﺎ و وﻳﺰاردﻫﺎي زﻳﺎدي وﺟﻮد دارد ﻛﻪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﺗﺎزه ﻛﺎر ﻛﻤﻚ ﻣﻲ ﻛﻨﺪ ﺑﺘﻮاﻧﻨﺪ دﺳـﺘﻮرات SQLﻣـﻮرد ﻧﻈـﺮ ﺧﻮد را اﻳﺠﺎد ﻛﻨﻨﺪ .اﻟﺒﺘﻪ اﻳﻦ اﺑﺰارﻫﺎ در ﺑﻌﻀﻲ ﻣﻮاﻗﻊ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﺣﺮﻓﻪ اي ﻧﻴﺰ در ﻧﻮﺷﺘﻦ دﺳﺘﻮرات SQLﻛﻤﻚ زﻳﺎدي ﻣﻲ ﻛﻨﻨﺪ. در اداﻣﻪ ي اﻳﻦ ﺑﺨﺶ ﺑﺎ ﻧﺤﻮه ي اﺳﺘﻔﺎده از اﻳﻦ اﺑﺰارﻫﺎ در ﻣﺤﻴﻂ Accessآﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ .اﻳـﻦ اﺑﺰارﻫـﺎ در اﻧﺘﻬـﺎ ،ﻳـﻚ ﺳـﺮي ٥٩٧
دﺳﺘﻮرات SQLﺗﻮﻟﻴﺪ ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ آﻧﻬﺎ را ﻣﺸﺎﻫﺪه ﻛﺮده و ﺗﻐﻴﻴﺮات ﻣﻮرد ﻧﻈﺮ ﺧﻮد را در آﻧﻬﺎ اﻳﺠﺎد ﻛﻨﻴﺪ .ﺑﺮرﺳﻲ و ﻣﺮور اﻳـﻦ دﺳﺘﻮرات و ﻧﺘﺎﻳﺞ اﺟﺮاي آﻧﻬﺎ ،ﻣﻲ ﺗﻮاﻧﺪ ﻛﻤﻚ زﻳﺎدي ﺑﻪ ﻳﺎدﮔﻴﺮي دﺳﺘﻮرات SQLﺑﻜﻨﺪ.
اﻳﺠﺎد ﻳﻚ ﭘﺮس وﺟﻮ: در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺎ اﺳﺘﻔﺎده از ﺑﺮﻧﺎﻣﻪ ي Accessﻳﻚ ﭘﺮس وﺟﻮي ﺳﺎده اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﺗﺎ ﺑﺘﻮاﻧﺪ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﻣﺸﺘﺮﻛﻴﻦ ﻛﻪ در ﺟﺪول Customersدر ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ Northwind.mdbذﺧﻴـﺮه ﺷـﺪه اﺳـﺖ را ﺑﺪﺳـﺖ آورده و ﻧﻤﺎﻳﺶ دﻫﺪ .ﺑﺮاي اﺟﺮاي اﻳﻦ ﺗﻤﺮﻳﻦ ﻻزم اﺳﺖ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻧﻤﻮﻧﻪ اي ﻛﻪ ﻫﻤﺮاه ﺑﺎ Microsoft Officeﻧﺼﺐ ﻣـﻲ ﺷﻮد در ﺳﻴﺴﺘﻢ ﺷﻤﺎ وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻳﻚ ﭘﺮس وﺟﻮي ﻧﻤﻮﻧﻪ اﻳﺠﺎد ﻛـﺮده و دﺳـﺘﻮر SQLﺗﻮﻟﻴـﺪ ﺷـﺪه ﺑـﻪ وﺳﻴﻠﻪ ي Accessرا ﺑﺎ ﻫﻢ ﻣﺸﺎﻫﺪه ﻛﻨﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﻳﺠﺎد ﻳﻚ ﭘﺮس وﺟﻮ (1ﺑﺮﻧﺎﻣﻪ ي Microsoft Accessرا ﺑﺎز ﻛﺮده و در ﻧﻮار اﺑﺰار اﻳﻦ ﺑﺮﻧﺎﻣـﻪ ،روي آﻳﻜـﻮن Openﻛﻠﻴـﻚ ﻛﻨﻴـﺪ. C:\Program Files\Microsoft ﺳــﭙﺲ در ﻛــﺎرد ﻣﺤــﺎوره اي Openﺑــﻪ آدرس Office\Office11\Samplesﺑﺮوﻳــﺪ و ﻓﺎﻳــﻞ Northwind.mdbرا اﻧﺘﺨــﺎب ﻛــﺮده و روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ. ﻧﻜﺘﻪ :آدرس ﻧﺼﺐ ﺑﺮﻧﺎﻣﻪ ي Officeﺑﺮ اﺳﺎس ﻧﺴﺨﻪ اي از Officeﻛﻪ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ و ﻧﻴﺰ ﻣﺴﻴﺮي ﻛـﻪ ﻫﻨﮕـﺎم ﻧﺼﺐ اﻧﺘﺨﺎب ﻛﺮده اﻳﺪ ﻣﻤﻜﻦ اﺳﺖ ﺗﻔﺎوت داﺷﺘﻪ ﺑﺎﺷﺪ. (2ﺑﺎ ﺑﺎز ﺷﺪن ﻓﺎﻳﻞ ﻣﺮﺑﻮط ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ،Northwind.mdbﭘﻨﺠﺮه اي در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﻛـﻪ در ﻧﻮار ﺳﻤﺖ ﭼﭗ آن دو ﻗﺴﻤﺖ ﺑـﻪ ﻧﺎﻣﻬـﺎي Objectsو Groupsوﺟـﻮد دارد .در ﺑﺨـﺶ Objectsاﺷـﻴﺎي ﻣﻮﺟﻮد در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ )ﻛﻪ ﭘﻴﺸﺘﺮ در ﻣﻮرد آﻧﻬﺎ ﺻﺤﺒﺖ ﻛﺮدﻳﻢ( ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ .در ﺑﺨﺶ Groupsﻧﻴـﺰ ﻣـﻲ ﺗﻮاﻧﻴﺪ اﺷﻴﺎﻳﻲ از ﻫﺮ ﻧﻮع را ﻛﻪ ﺑﻪ ﻫﻢ ارﺗﺒﺎط دارﻧﺪ در ﻳﻚ ﮔﺮوه ﻗﺮار دﻫﻴﺪ )ﺷﻜﻞ .(2-15 (3ﺑﺮاي اﻳﻨﻜﻪ ﺑﺒﻴﻨﻴﺪ ﭼﮕﻮﻧﻪ ﺑﺮﻧﺎﻣﻪ ي Accessﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ دﺳﺘﻮر SELECTﻣﻮرد ﻧﻴﺎز ﺷﻤﺎ را اﻳﺠﺎد ﻛﻨﺪ ،ﺑﺎﻳﺪ در ﻗﺴﻤﺖ Objectsروي آﻳﻜﻮن Queriesﻛﻠﻴﻚ ﻛﻨﻴﺪ. (4در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ ﻳﻚ ﭘﺮس وﺟﻮي ﺟﺪﻳﺪ اﻳﺠﺎد ﻛﻨﻴﻢ ،ﺑﻨﺎﺑﺮاﻳﻦ در ﻗـﺴﻤﺖ ﺳـﻤﺖ راﺳـﺖ روي ﻋﺒـﺎرت “Create ” query in Design viewﻛﻠﻴﻚ ﻛﻨﻴﺪ )ﺷﻜﻞ (3-15
٥٩٨
ﺷﻜﻞ 2-15
ﺷﻜﻞ 3-15 (5ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﻨﺠﺮه ي Show Tableﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﺗﺎ ﺑﻪ وﺳﻴﻠﻪ ي آن ﺑﺘﻮاﻧﻴﺪ ﺟﺪول و ﻳﺎ ﺟﺪاوﻟﻲ ﻛﻪ ﻣـﻲ ﺧﻮاﻫﻴﺪ از آﻧﻬﺎ در ﭘﺮس وﺟﻮي ﺧﻮد اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ را اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ .در اﻳـﻦ ﻗـﺴﻤﺖ ﻓﻘـﻂ ﺑـﻪ ﻳـﻚ ﺟـﺪول ﻧﻴـﺎز دارﻳـﻢ: .Customersﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻦ ﭘﻨﺠﺮه ﺟﺪول Customersرا اﻧﺘﺨـﺎب ﻛـﺮده و روي دﻛﻤـﻪ ي Addﻛﻠﻴـﻚ ﻛﻨﻴﺪ ﺗﺎ اﻳﻦ ﺟﺪول ﺑﻪ ﻗﺴﻤﺖ Query Designerاﺿﺎﻓﻪ ﺷﻮد .ﺳﭙﺲ روي دﻛﻤﻪ ي Closeﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗـﺎ ﭘﻨﺠﺮه ي Show Tableﺑﺴﺘﻪ ﺷﻮد.
٥٩٩
(6ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺗﻤﺎم ﻓﻴﻠﺪ ﻫﺎي ﻣﻮﺟﻮد در ﺟﺪول Customerﺑﻪ ﻫﻤﺮاه ﻳﻚ ﻋﻼﻣﺖ ﺳﺘﺎره ﻧﻤـﺎﻳﺶ داده ﻣـﻲ ﺷـﻮد .ﺑـﻪ وﺳﻴﻠﻪ ي اﻳﻦ ﻟﻴﺴﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻓﻴﻠﺪ ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺧﻮد را اﻧﺘﺨﺎب ﻛﻨﻴﺪ و ﻳﺎ ﺑﺎ اﻧﺘﺨﺎب ﻋﻼﻣﺖ * ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻛـﻪ ﺗﻤـﺎم ﻓﻴﻠﺪ ﻫﺎ ﺑﺎﻳﺪ اﻧﺘﺨﺎب ﺷﻮﻧﺪ .در اﻳﻦ ﻗﺴﻤﺖ ﻓﻘﻂ ﺑﻪ ﻓﻴﻠﺪ ﻫﺎي ﻣﺤﺪودي ﻧﻴﺎز دارﻳﻢ ،ﺑﻨﺎﺑﺮاﻳﻦ ﻻزم ﻧﻴﺴﺖ ﻛـﻪ ﻫﻤـﻪ ي آﻧﻬـﺎ را اﻧﺘﺨﺎب ﻛﻨﻴﻢ .در ﻟﻴﺴﺖ ﻓﻴﻠﺪ ﻫـﺎي ﻣﻮﺟـﻮد در ﺑﺮﻧﺎﻣـﻪ ،روي ﻓﻴﻠـﺪ CompanyNameدر ﺟـﺪول Customers ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑﻪ اوﻟﻴﻦ ﺳﺘﻮن در ﺟﺪول ﭘﺎﻳﻴﻦ ﭘﻨﺠﺮه اﺿﺎﻓﻪ ﺷﻮد .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻗﺴﻤﺖ Fieldو Table در اﻳﻦ ﺳﺘﻮن ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﭘﺮ ﺧﻮاﻫﻨﺪ ﺷﺪ .ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻗﺴﻤﺖ Sortرا ﻧﻴﺰ ﺗﻨﻈـﻴﻢ ﻛﻨﻴـﺪ ﺗـﺎ داده ﻫـﺎ ﺑـﺮ اﺳﺎس اﻳﻦ ﻓﻴﻠﺪ ،ﺑﻪ ﺻﻮرت ﻧﺰوﻟﻲ و ﻳﺎ ﺻﻌﻮدي ﻣﺮﺗﺐ ﺷﻮﻧﺪ .در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺧﻮاﻫﻴﻢ داده ﻫﺎ ﺑﺮ اﺳـﺎس ﺻـﻌﻮدي ﻣﺮﺗـﺐ ﺷﻮﻧﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ روي ﻗﺴﻤﺖ Sortﻛﻠﻴﻚ ﻛﺮده و ﮔﺰﻳﻨﻪ ي Ascendingرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﻨﺠﺮه ي ﺷﻤﺎ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 4-15ﺷﺪه ﺑﺎﺷﺪ.
ﺷﻜﻞ 4-15 (7ﻋﻼوه ﺑﺮ ﻓﻴﻠﺪ CompanyNameﻻزم اﺳﺖ ﻛﻪ ﻓﻴﻠﺪ ContactNameرا ﻧﻴـﺰ ﺑـﻪ ﭘـﺮس وﺟـﻮ اﺿـﺎﻓﻪ ﻛﻨـﻴﻢ. ﺑﻨﺎﺑﺮاﻳﻦ روي ﻓﻴﻠﺪ ContactNameدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴـﻚ در ﺳـﺘﻮن ﺑﻌـﺪي در ﺟـﺪول ﭘـﺎﻳﻴﻦ ﺻﻔﺤﻪ ﻗﺮار ﺑﮕﻴﺮد .ﺳﭙﺲ ﺑﻪ ﻫﻤﻴﻦ روش ﻓﻴﻠﺪ ContactTitleرا ﻧﻴﺰ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .در اﻳﻦ ﻣﺮﺣﻠﻪ ﭘﻨﺠﺮه ي ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 5-15ﺷﺪه ﺑﺎﺷﺪ. (8روي دﻛﻤﻪ ي Saveدر ﻧﻮار اﺑﺰار ﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻋﺒـﺎرت CustomerQueryرا در ﭘﻨﺠـﺮه ي Save As وارد ﻛﺮده و ﻛﻠﻴﺪ OKرا ﻓﺸﺎر دﻫﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﺮس وﺟﻮي ﺷﻤﺎ ﺑﻪ اﻳﻦ ﻧﺎم در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ذﺧﻴﺮه ﻣﻲ ﺷﻮد. (9در ﻧﻮار اﺑﺰار روي آﻳﻜﻮن Runﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻳﻚ ﻋﻼﻣﺖ ! ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﻳـﻦ ﭘـﺮس وﺟـﻮ اﺟـﺮا ﺷﺪه و ﻧﺘﻴﺠﻪ ي آن ﻧﻤﺎﻳﺶ داده ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻧﺘﻴﺠﻪ اي را ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 6-15ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد .دﻗﺖ ﻛﻨﻴﺪ ﻛـﻪ ﻧﺘﺎﻳﺞ ﻧﻤﺎﻳﺶ داده ﺷﺪه ﺑﺮ اﺳﺎس ﻓﻴﻠﺪ CompanyNameﺑﻪ ﺻﻮرت ﺻﻌﻮدي ﻣﺮﺗﺐ ﺷﺪه اﻧﺪ.
٦٠٠
ﺷﻜﻞ 5-15
ﺷﻜﻞ 6-15
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺮ اﺳﺎس ﺗﻨﻈﻴﻤﺎت و اﻧﺘﺨﺎب ﻫﺎﻳﻲ ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ اﻧﺠﺎم دادﻳﺪ Access ،دﺳﺘﻮر SQLﻣﻌﺎدل را ﻧﻮﺷﺘﻪ و آن را اﺟﺮا ﻣﻲ ﻛﻨﺪ و ﺳﭙﺲ ﻧﺘﻴﺠﻪ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ .ﺑﺮاي ﻣﺸﺎﻫﺪه ي دﺳﺘﻮر ﺗﻮﻟﻴﺪ ﺷﺪه ،از ﻣﻨﻮي Viewﮔﺰﻳﻨﻪ ي SQL Viewرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﻨﺠﺮه ي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 7-15ﻛﻪ ﺣﺎوي دﺳﺘﻮر SELECTﻣﻮرد ﻧﻈﺮ اﺳﺖ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد.
٦٠١
ﺷﻜﻞ 7-15 ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻳﻚ دﺳﺘﻮر SELECTﺑﻪ ﻫﻤﺮاه ﻧﺎم ﻓﻴﻠﺪ ﻫﺎي ﻣﻮرد ﻧﻴﺎز ،ﻣﺸﺎﺑﻪ ﻣﻮاردي ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ اﻳﺠﺎد ﺷﺪه اﺳﺖ .اﻟﺒﺘﻪ Accessﺑﺮاي ﻣﺸﺨﺺ ﺗﺮ ﺷﺪن دﺳﺘﻮر ،ﻗﺒﻞ از ﻧﺎم ﻓﻴﻠﺪ ﻫﺎ ﻧﺎم ﺟﺪول ﺣﺎوي آﻧﻬﺎ را ﻧﻴﺰ ﻗﺮار ﻣﻲ دﻫﺪ .اﻳﻦ ﻣﻮرد ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﻢ ﻓﻴﻠﺪ ﻫﺎﻳﻲ را از ﭼﻨﺪ ﺟﺪول اﻧﺘﺨﺎب ﻛﺮده و ﻧﻤﺎﻳﺶ دﻫﻴﻢ ،از ﭘﻴﺶ آﻣﺪن اﺷﺘﺒﺎه ﺑﻴﻦ ﻓﻴﻠﺪ ﻫﺎ ﺑﺎ ﻧﺎم ﺑﺮاﺑﺮ )اﻣﺎ در ﺟﺪوﻟﻬﺎي ﻣﺘﻔﺎوت( ﺟﻠﻮﮔﻴﺮي ﻣﻲ ﻛﻨﺪ .دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﺑﺮاي اﺳﺘﻔﺎده از ﻓﻴﻠﺪ ﻫﺎ در اﻳﻦ ﻗﺴﻤﺖ از ﺑﺮﻳﺲ اﺳﺘﻔﺎده ﻧﺸﺪه اﺳﺖ. دﻟﻴﻞ اﻳﻦ ﻣﻮرد ﻫﻢ در اﻳﻦ اﺳﺖ ﻛﻪ اﺳﺘﻔﺎده از ﺑﺮﻳﺲ ﻓﻘﻂ وﻗﺘﻲ ﺿﺮوري اﺳﺖ ﻛﻪ در ﻧﺎم ﻓﻴﻠﺪ ﻫﺎ ﻓﻀﺎي ﺧﺎﻟﻲ وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ. ﺑﻌﺪ از اﻳﻦ ﻗﺴﻤﺖ ،ﻋﺒﺎرت FROMﺑﻪ ﻫﻤﺮاه ﻧﺎم ﺟﺪوﻟﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ اﻃﻼﻋﺎت از آن اﺳﺘﺨﺮاج ﺷﻮد آﻣﺪه اﺳﺖ )در اﻳﻦ ﺣﺎل ،ﺟﺪول .(Customersﻋﺒﺎرت ORDER BYﻧﻴﺰ در اﻧﺘﻬﺎي دﺳﺘﻮر ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ اﻃﻼﻋﺎت ﺑﺎﻳﺪ ﺑﺮ اﺳﺎس ﻓﻴﻠﺪ Customers.CompanyNameﻣﺮﺗﺐ ﺷﻮﻧﺪ. ﺧﻮب ،ﺣﺎل ﻛﻪ دﺳﺘﻮر اﻳﺠﺎد ﺷﺪه در اﻳﻦ ﻗﺴﻤﺖ را ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ﻛﻪ اﻳﻦ دﺳﺘﻮرات ﭼﮕﻮﻧﻪ ﺑﻪ وﺳﻴﻠﻪ ي Accessاﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ؟ در اﺑﺘﺪاي اﻳﺠﺎد ﻳﻚ ﭘﺮس وﺟﻮ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺟﺪول ﻣﻮرد ﻧﻈﺮ ﺧﻮد ﻣﺎﻧﻨﺪ Customersرا اﻧﺘﺨﺎب ﻣﻲ ﻛﻨﻴﺪ Access ،دﺳﺘﻮري ﺑﻪ ﺻﻮرت زﻳﺮ اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ: SELECT ;FROM Customers اﻟﺒﺘﻪ ﻣﺸﺨﺺ اﺳﺖ ﻛﻪ اﻳﻦ دﺳﺘﻮر ،ﻳﻚ دﺳﺘﻮر ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﻧﻴﺴﺖ ،زﻳﺮا در اﻳﻦ دﺳﺘﻮر ﻣﺸﺨﺺ ﻧﻴﺴﺖ ﻛﻪ ﭼﻪ ﻓﻴﻠﺪ ﻫﺎﻳﻲ ﺑﺎﻳﺪ اﻧﺘﺨﺎب ﺷﻮﻧﺪ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ اوﻟﻴﻦ ﻓﻴﻠﺪي ﻛﻪ ﺑﺎﻳﺪ در اﻳﻦ ﭘﺮس وﺟﻮ وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ و ﻧﻮع ﻣﺮﺗﺐ ﺷﺪن آن را ﻣﺸﺨﺺ ﻛﺮدﻳﺪ ،دﺳﺘﻮر SQL ﻗﺒﻠﻲ ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ داده ﻣﻲ ﺷﻮد ﻛﻪ ﻳﻚ دﺳﺘﻮر ﻗﺎﺑﻞ اﺟﺮا اﺳﺖ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻧﺎم ﻓﻴﻠﺪ ﻣﻮرد اﺳﺘﻔﺎده در ﻣﻜﺎن ﻣﻨﺎﺳﺐ ﻗﺮار داده ﻣﻲ ﺷﻮد و ﻧﻴﺰ ﻋﺒﺎرت ﻣﺮﺑﻮط ﺑﻪ ﻣﺮﺗﺐ ﺳﺎزي ﺑﻪ ﺻﻮرت ﺻﻌﻮدي ﻧﻴﺰ ﺑﻪ دﺳﺘﻮر اﺿﺎﻓﻪ ﻣﻲ ﺷﻮد. SELECT Customers.CompanyName FROM Customers ;ORDER BY Customers.CompanyName ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﻴﻠﺪ ﻫﺎي دﻳﮕﺮي را ﺑﻪ اﻳﻦ ﭘﺮس وﺟﻮ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﺪ ،ﻧﺎم آن ﻓﻴﻠﺪ ﻫﺎ ﺑﻌﺪ از ﻧﺎم ﻓﻴﻠﺪ CompanyNameدر ﺧﻂ اول دﺳﺘﻮر ﻗﺮار ﺧﻮاﻫﺪ ﮔﺮﻓﺖ و در اﻧﺘﻬﺎ دﺳﺘﻮر ﺑﻪ آﻧﭽﻪ ﻛﻪ در ﺷﻜﻞ 7-15ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮد. ﺧﻮب ،ﺑﻬﺘﺮ اﺳﺖ ﻣﺠﺪداً ﺑﻪ ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮﮔﺸﺘﻪ و ﻣﻘﺪاري ﺑﺎ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي دﺳﺘﺮﺳﻲ ﺑﻪ داده ﻫﺎ ﻛﻪ ﺑﺮاي ﻛﺎر ﺑﺎ ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي ﻻزم ﻫﺴﺘﻨﺪ آﺷﻨﺎ ﺷﻮﻳﻢ .ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ در اﻳﻦ ﻓﺼﻞ از Accessﺑﻪ ﻋﻨﻮان ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد ،در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﻓﻘﻂ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎﻳﻲ را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ Accessﻣﻮرد ﻧﻴﺎز اﺳﺖ.
٦٠٢
ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي دﺳﺘﺮﺳﻲ اﻃﻼﻋﺎت: در وﻳﮋوال 2005 C#ﺑـﺮاي دﺳﺘﺮﺳـﻲ ﺑـﻪ اﻃﻼﻋـﺎت و ﻧﻤـﺎﻳﺶ آﻧﻬـﺎ ﺳـﻪ ﻛﺎﻣﭙﻮﻧﻨـﺖ ﻣﻬـﻢ و اﺻـﻠﻲ وﺟـﻮد دارﻧـﺪ ﻛـﻪ ﻋﺒﺎرﺗﻨـﺪ از : TableAdapter ،BindingSourceو .DataSetدو ﻛﺎﻣﭙﻮﻧﻨــــــــــــﺖ BindingSourceو DataSetﻫﻤــﺎﻧﻄﻮر ﻛــﻪ در ﺷــﻜﻞ 8-15ﻣــﺸﺎﻫﺪه ﻣــﻲ ﻛﻨﻴــﺪ در ﻗــﺴﻤﺖ Dataدر ﺟﻌﺒــﻪ اﺑــﺰار وﺟــﻮد دارﻧــﺪ .ﻛﺎﻣﭙﻮﻧﻨــﺖ TableAdapterﻧﻴﺰ ﺑﺮ اﺳﺎس ﻣﺴﻴﺮي ﻛﻪ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت درون ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ و ﻧﻤﺎﻳﺶ آﻧﻬﺎ ﻃﻲ ﻣﻲ ﻛﻨﻴﺪ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﺧﻮاﻫﺪ ﺷﺪ.
ﺷﻜﻞ 8-15 ﻧﻜﺘﻪ :اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎ ﻛﻪ ﻋﻤﻮﻣﺎً ﺑﻪ ﻋﻨﻮان ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي داده اي ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮﻧﺪ ،ﺧﻮد ﻓﻘﻂ ﭼﻨﺪﻳﻦ ﻛﻼس ﻫـﺴﺘﻨﺪ ،ﻣﺎﻧﻨـﺪ ﺗﻤـﺎم ﻛﻼس ﻫﺎي دﻳﮕﺮ .NETﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﺮدﻳﻢ .در اﻳﻦ ﻓﺼﻞ ﻓﻘﻂ ﺑـﺎ ﻧﺤـﻮه ي اﺳـﺘﻔﺎده از اﻳـﻦ ﻛﻼﺳـﻬﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي آﺷﻨﺎ ﻣﻲ ﺷﻮﻳﻢ .در ﻓﺼﻞ ﺑﻌﺪ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻛﻼﺳﻬﺎي ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫـﺎ را ﺑـﺎ ﺟﺰﺋﻴـﺎت ﺑﻴـﺸﺘﺮي ﺑﺮرﺳﻲ ﻛﻨﻴﻢ.
:DataSet ﻛﺎﻣﭙﻮﻧﻨﺖ DataSetدر ﺣﻘﻴﻘﺖ ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﻣﺨﺰن اﺳﺖ ﻛﻪ داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز را در ﺣﺎﻓﻈﻪ ي ﻛﺎﻣﭙﻴﻮﺗﺮ ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ .اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻛﻮﭼﻚ ﻋﻤﻞ ﻣﻲ ﻛﻨﺪ ﻛﻪ داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺧﻮد را در ﺣﺎﻓﻈﻪ ﻧﮕﻬـﺪاري ﻣـﻲ ﻛﻨﻨـﺪ .ﺑـﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ داده ﻫﺎ را درون ﺟﺪوﻟﻬﺎﻳﻲ ﻧﮕﻬﺪاري ﻛﺮده و ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻛﺎﻣﭙﻮﻧﻨﺖ DataViewﻛﻪ در ﻓﺼﻞ ﺷﺎﻧﺰدﻫﻢ ﺗﻮﺿﻴﺢ داده ﺧﻮاﻫﺪ ﺷﺪ ،ﺑﻪ ﭼﻨﺪﻳﻦ روش ﭘﺮس وﺟﻮ ﻫﺎﻳﻲ را روي اﻳﻦ داده ﻫﺎ اﺟﺮا ﻛﻨﻴﺪ.
٦٠٣
ﻛﺎﻣﭙﻮﻧﻨﺖ DataSetاز ﻗﺪرت و اﻣﻜﺎﻧﺎت زﻳﺎدي ﺑﺮﺧﻮردار اﺳﺖ .اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻋﻼوه ﺑﺮ اﻳﻦ ﺗﻮاﻧﺎﻳﻲ ذﺧﻴﺮه ي داده ﻫﺎ در ﺟـﺪاول، ﺣﺠﻢ زﻳﺎدي از ﻣﺘﺎدﻳﺘﺎ ، 1ﻳﺎ "اﻃﻼﻋﺎﺗﻲ درﺑﺎره ي داده ﻫﺎي ﻣﻮﺟﻮد" ،را ﻧﻴﺰ ﻧﮕﻪ داري ﻣﻲ ﻛﻨﺪ .اﻳﻦ اﻃﻼﻋﺎت ﺷﺎﻣﻞ ﻣﻮاردي ﻣﺎﻧﻨﺪ ﻧﺎم ﺟﺪول ﻫﺎ و ﻳﺎ ﻓﻴﻠﺪ ﻫﺎ ،ﻧﻮع داده ﻫﺎي ﻣﻮﺟﻮد اﻃﻼﻋﺎت ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﻣﺪﻳﺮﻳﺖ داده ﻫﺎ و ﻳﺎ اﻃﻼﻋﺎﺗﻲ در راﺑﻄﻪ ﺑﺎ ﻟﻐـﻮ ﻛـﺮدن ﺗﻐﻴﻴـﺮات اﻋﻤﺎل ﺷﺪه در داده ﻫﺎ ﻣﻲ ﺑﺎﺷﺪ. ﺗﻤﺎم اﻳﻦ اﻃﻼﻋﺎت در ﻗﺎﻟﺐ XMLدر ﺣﺎﻓﻈﻪ ذﺧﻴﺮه ﻣﻲ ﺷﻮﻧﺪ .ﺑﻪ ﻋﻼوه ﻳﻚ ﻛﺎﻣﭙﻮﻧﻨﺖ DataSetﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺳﺎدﮔﻲ در ﻗﺎﻟـﺐ XMLدر دﻳﺴﻚ ذﺧﻴﺮه ﺷﺪه و ﻳﺎ از ﻗﺎﻟﺐ XMLاز دﻳﺴﻚ در ﺣﺎﻓﻈﻪ ﻗﺮار داده ﺷﻮد .ﻫﻤﭽﻨﻴﻦ اﻳﻦ ﻛﻨﺘﺮل ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺻﻮرت XML از ﻃﺮﻳﻖ ﺷﺒﻜﻪ ﻫﺎي ﻣﺨﺘﻠﻒ ﻣﺎﻧﻨﺪ اﻳﻨﺘﺮﻧﺖ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕﺮ ﻓﺮﺳﺘﺎده ﺷﻮد و ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد. ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ داده ﻫﺎي ﻳﻚ ﻛﺎﻣﭙﻮﻧﻨﺖ DataSetدر ﺣﺎﻓﻈﻪ ﻗﺮار دارﻧﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺳﺎدﮔﻲ در ﺑﻴﻦ آﻧﻬـﺎ ﺑـﻪ ﺟﻠـﻮ و ﻳـﺎ ﻋﻘﺐ ﺣﺮﻛﺖ ﻛﻨﻴﺪ و ﻳﺎ در آﻧﻬﺎ ﺗﻐﻴﻴﺮاﺗﻲ را اﻳﺠﺎد ﻛﻨﻴﺪ .اﻟﺒﺘﻪ اﻳﻦ ﺗﻐﻴﻴﺮات در داده ﻫﺎي ﻣﻮﺟﻮد در ﺣﺎﻓﻈﻪ اﻋﻤﺎل ﻣﻲ ﺷﻮﻧﺪ و ﺗﺎ زﻣﺎﻧﻲ ﻛـﻪ ﻣﺸﺨﺺ ﻧﻜﻨﻴﺪ ﺑﻪ داده اي ﻣﻮﺟﻮد در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﻨﻌﻜﺲ ﻧﺨﻮاﻫﻨﺪ ﺷﺪ .در ﻣﻮرد اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ در ﻓﺼﻞ ﺑﻌﺪ ﺑﻴﺸﺘﺮ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد ،اﻣﺎ در اﻳﻦ ﻓﺼﻞ ﻓﻘﻂ داده ﻫﺎﻳﻲ را در آن ﻗﺮار داده و ﺳﭙﺲ ﺑـﻪ وﺳـﻴﻠﻪ ي ﻛﻨﺘﺮﻟﻬـﺎي دﻳﮕـﺮي آن داده ﻫـﺎ را در ﺑﺮﻧﺎﻣـﻪ ﻧﻤـﺎﻳﺶ ﺧﻮاﻫﻴﻢ داد.
:DataGridView اﻳﻦ ﻛﻨﺘﺮل ﺑﺮاي ﻧﻤﺎﻳﺶ داده ﻫﺎي ﻣﻮﺟﻮد در ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻛﺎر ﻣﻲ رود .ﺑﺮاي ﻛﺎر ﺑﺎ آن ﻛـﺎﻓﻲ اﺳـﺖ آن را ﺑـﻪ ﻣﻨﺒﻊ داده ﻫﺎي ﺧﻮد ،ﺑﺮاي ﻣﺜﺎل ﻳﻜﻲ از ﺟﺪوﻟﻬﺎي ﻣﻮﺟﻮد در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ،ﻣﺘﺼﻞ ﻛﺮده و ﺳﭙﺲ اﻳﻦ ﻛﻨﺘـﺮل را ﺗﻨﻈـﻴﻢ ﻛﻨﻴـﺪ ﺗـﺎ آن داده ﻫﺎ را ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﺟﺪول ،ﻳﻌﻨﻲ ﺳﺘﻮﻧﻬﺎ را ﺑﻪ ﺻﻮرت ﻋﻤﻮدي و ردﻳﻔﻬﺎ را ﺑﻪ ﺻﻮرت اﻓﻘﻲ ﻧﻤﺎﻳﺶ دﻫﺪ. ﻫﻤﭽﻨﻴﻦ اﻳﻦ ﻛﻨﺘﺮل داراي ﺧﺎﺻﻴﺘﻬﺎي زﻳﺎدي اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻇﺎﻫﺮ آن را ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ و ﺗﺎ ﺑﻪ ﺷﻜﻠﻲ ﻛﻪ ﻣـﺪ ﻧﻈـﺮ ﺷﻤﺎﺳﺖ ﺗﺒﺪﻳﻞ ﺷﻮد .ﻋﻼوه ﺑﺮ اﻳﻦ ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻦ ﻛﻨﺘﺮل ﻣﻲ ﺗﻮاﻧﻴﺪ ﻋﻨﻮان ﺳﺘﻮﻧﻬﺎي داده ﻫﺎ و ﻳﺎ روش ﻧﻤﺎﻳﺶ آﻧﻬﺎ ﻧﻴﺰ را ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ.
:BindingSource اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﻤﺎﻧﻨﺪ ﭘﻠﻲ ﺑﺮاي اﻳﺠﺎد ارﺗﺒﺎط ﺑﻴﻦ داده ﻫﺎي ﻣﻮﺟﻮد در ﻣﻨﺒﻊ داده اي ﺷﻤﺎ ) (DataSetو ﻧﻴﺰ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي ﻧﻤﺎﻳﺶ داده ﻫﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ ﺑﻪ ﻛﺎر ﻣﻲ رود .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺑﻪ وﺳﻴﻠﻪ ي ﻛﻨﺘﺮل ﻫﺎﻳﻲ داده ﻫـﺎي ﻣﻮﺟـﻮد در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد را ﻧﻤﺎﻳﺶ دﻫﻴﺪ ،و ﻳﺎ ﺑﻪ ﻫﺮ دﻟﻴﻞ دﻳﮕﺮي ﺑﺨﻮاﻫﻴﺪ ﺑﻪ آﻧﻬﺎ در ﻣﻨﺒﻊ اﻃﻼﻋﺎﺗﻲ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،اﻳﻦ ارﺗﺒﺎط ﺑﺎﻳﺪ از ﻃﺮﻳﻖ اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﺻﻮرت ﺑﮕﻴﺮد. ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ داده ﻫﺎي ﻣﻮﺟﻮد در ﻳﻚ DataSetرا ﺑﻪ وﺳـﻴﻠﻪ ي ﻳـﻚ ﻛﻨﺘـﺮل DataGridViewدر ﻓـﺮم ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده اﻳﺪ و ﺣﺎل ﻣﻲ ﺧﻮاﻫﻴﺪ اﻳﻦ داده ﻫﺎ ﺑﺮ اﺳﺎس ﻳﻜﻲ از ﺳﺘﻮﻧﻬﺎ ﻣﺮﺗﺐ ﺷﺪه و ﺳﭙﺲ ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﻛﻨﺘﺮل DataGridViewاﻳﻦ ﺗﻘﺎﺿﺎ را ﺑﻪ ﻛﺎﻣﭙﻮﻧﻨﺖ BindingSourceﻣﻲ ﻓﺮﺳﺘﺪ و ﺳﭙﺲ اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ آن را ﺑـﻪ ﻛﺎﻣﭙﻮﻧﻨﺖ DataSetاﻋﻼم ﻣﻲ ﻛﻨﺪ. در اداﻣﻪ ي اﻳﻦ ﻓﺼﻞ ﺑﺎ ﻧﺤﻮه ي اﺳﺘﻔﺎده از اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ.
Metadata
1
٦٠٤
:BindingNavigator ﻛﻨﺘﺮل BindingNavigatorﻳﻚ راﺑﻂ ﮔﺮاﻓﻴﻜﻲ اﺳﺘﺎﻧﺪارد را ﺑـﺮاي ﺣﺮﻛـﺖ ﺑـﻴﻦ رﻛـﻮرد ﻫـﺎي ﻣﻮﺟـﻮد در ﻳـﻚ ﺑﺎﻧـﻚ اﻃﻼﻋﺎﺗﻲ اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ .اﻳﻦ ﻛﻨﺘﺮل ﺑﺴﻴﺎر ﻣﺸﺎﺑﻪ ﻛﻨﺘﺮﻟﻲ اﺳﺖ ﻛﻪ در ﭘﺎﻳﻴﻦ ﺟﺪول ﻧﻤﺎﻳﺶ داده ﺷﺪه در ﺷﻜﻞ 6-15ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ. اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻛﺎﻣﭙﻮﻧﻨﺖ DataGridViewﻣﻲ ﺗﻮاﻧـﺪ ﺑـﻪ ﻛﻨﺘـﺮل BindingSourceﻣﺘـﺼﻞ ﺷـﺪه و از ﻃﺮﻳﻖ آن ﺑﻪ داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑـﺮاي ﻣﺜـﺎل ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ روي ﻛﻠﻴـﺪ Nextدر اﻳـﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻛﻠﻴﻚ ﻛﺮدﻳﺪ ﺗﺎ ﺑﻪ رﻛﻮرد ﺑﻌـﺪي اﻃﻼﻋـﺎت ﺑﺮوﻳـﺪ ،درﺧﻮاﺳـﺖ ﺷـﻤﺎ ﺑـﻪ وﺳـﻴﻠﻪ ي BindingNavigatorﺑـﻪ ﻛﺎﻣﭙﻮﻧﻨﺖ BindingSourceﻓﺮﺳﺘﺎده ﺷﺪه و ﺳﭙﺲ از ﻛﺎﻣﭙﻮﻧﻨﺖ BindingSourceﺑﻪ ﻛﺎﻣﭙﻮﻧﻨﺖ DataSet )و ﻳﺎ ﻫﺮ ﻣﻨﺒﻊ اﻃﻼﻋﺎﺗﻲ دﻳﮕﺮ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ( اﻋﻼم ﻣﻲ ﺷﻮد.
:TableAdapter ﺗﻨﻬﺎ ﻳﻚ ﻛﺎﻣﭙﻮﻧﻨﺖ داده اي دﻳﮕﺮ ﻣﺎﻧﺪه اﺳﺖ ﻛﻪ ﺑﺎﻳﺪ در ﻣﻮرد آن ﺻﺤﺒﺖ ﻛﻨﻴﻢ :ﻛﺎﻣﭙﻮﻧﻨﺖ .DataAdapterاﻳﻦ ﻛﺎﻣﭙﻮﻧﻨـﺖ در ﺟﻌﺒﻪ اﺑﺰار وﺟﻮد ﻧﺪارد ﻛﻪ ﺑﺘﻮاﻧﻴﺪ آن را ﻫﻤﺎﻧﻨﺪ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي ﻗﺒﻠﻲ ﺑﺮ روي ﻓﺮم ﻗﺮار دﻫﻴﺪ .ﺑﻠﻜﻪ ﺑﺴﺘﻪ ﺑﻪ روﺷﻲ ﻛـﻪ ﻛﺎﻣﭙﻮﻧﻨـﺖ ﻫـﺎي داده اي دﻳﮕﺮ را در ﺑﺮﻧﺎﻣﻪ ﻗﺮار داده و آﻧﻬﺎ را ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﻨﻴﺪ ،اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﻣﻲ ﺷﻮد. اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﺣﺎوي ﭘﺮس وﺟﻮ ﻫﺎﻳﻲ ﺑﺮاي اﻧﺘﺨﺎب داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ و ﻧﻴﺰ اﻃﻼﻋﺎﺗﻲ در ﻣﻮرد ﻧﺤﻮه ي اﺗﺼﺎل ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺑﺎﻧﻚ اﺳﺖ .ﻫﻤﭽﻨﻴﻦ اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﺣﺎوي ﻣﺘﺪ ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آﻧﻬﺎ ﻣﻲ ﺗﻮان داده ﻫﺎ را از ﺟﺪاول ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺪﺳﺖ آورد و در ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ DataSetﻗﺮار داد و ﺳﭙﺲ در ﺑﺮﻧﺎﻣﻪ از آن داده ﻫﺎ اﺳﺘﻔﺎده ﻛﺮد. اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ اﻳﻦ ﻗﺎﺑﻠﻴﺖ را دارد ﻛﻪ ﺑﺮ اﺳﺎس دﺳﺘﻮر SELECTاي ﻛﻪ ﺑﺮاي اﻧﺘﺨﺎب داده ﻫﺎ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑـﺮاي آن وارد ﻣـﻲ ﻛﻨﻴﺪ ،دﺳﺘﻮرات UPDATE ،INSERTو ﻧﻴﺰ DELETE1ﻣﻨﺎﺳﺐ ﺑﺮاي ﺗﻐﻴﻴﺮ داده ﻫﺎي اﻧﺘﺨﺎب ﺷﺪه در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﻳﺠـﺎد ﻛﻨﺪ. در ﻓﺼﻞ ﺑﻌﺪ ﺑﻴﺸﺘﺮ ﺑﺎ اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ.
اﺗﺼﺎل داده ﻫﺎ: اﺗﺼﺎل داده ﻫﺎ 2ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ داده ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺎﻣﭙﻮﻧﻨﺖ BindingSourceﺑﻪ آﻧﻬﺎ دﺳﺘﺮﺳﻲ دارﻳﺪ را ﺑﻪ ﻳﻚ ﻛﻨﺘﺮل ﺧﺎص ﻧﺴﺒﺖ دﻫﻴﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻳﻚ ﻛﻨﺘﺮل را ﺑﺘﻮاﻧﻴﺪ ﺑﻪ ﻧﺤﻮي ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ﻛﻪ داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺧﻮد را ﺑﻪ وﺳـﻴﻠﻪ ي ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي دﺳﺘﺮﺳﻲ داده ﻫﺎ در ﺑﺮﻧﺎﻣﻪ درﻳﺎﻓﺖ ﻛﻨﺪ و ﺳﭙﺲ آﻧﻬﺎ را ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ دﻫـﺪ .ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ آﻧﻬﺎ را ﻣﺸﺎﻫﺪه ﻛﺮده و ﻳﺎ ﺗﻐﻴﻴﺮات ﻣﻮرد ﻧﻈﺮ ﺧﻮد را در آﻧﻬﺎ اﻋﻤﺎل ﻛﻨﺪ .در وﻳﮋوال C#ﺗﻘﺮﻳﺒﺎً ﺗﻤﺎم ﻛﻨﺘﺮل ﻫﺎ ﺗـﺎ ﺣـﺪي اﺗﺼﺎل ﺑﻪ داده ﻫﺎ را ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ ﻛﻨﻨﺪ ،اﻣﺎ ﺑﻌﻀﻲ از ﻛﻨﺘﺮل ﻫﺎ ﻧﻴﺰ وﺟﻮد دارﻧﺪ ﻛﻪ ﻣﺨﺼﻮص اﻳﻦ ﻛﺎر ﻃﺮاﺣﻲ ﺷـﺪه اﻧـﺪ ،ﻣﺎﻧﻨـﺪ ﻛﻨﺘـﺮل DataGridViewو ﻳـــﺎ .TextBoxدر ﺑﺨـــﺶ اﻣﺘﺤـــﺎن ﻛﻨﻴـــﺪ ﺑﻌـــﺪ اﻃﻼﻋـــﺎﺗﻲ ﻛـــﻪ ﺑـــﻪ وﺳـــﻴﻠﻪ ي ﻛﺎﻣﭙﻮﻧﻨـــﺖ
1اﻳﻦ دﺳﺘﻮرات ﻧﻴﺰ ﻣﺎﻧﻨﺪ دﺳﺘﻮر SELECTاز دﺳﺘﻮرات زﺑﺎن SQLﺑﻪ ﺷﻤﺎر ﻣﻲ روﻧﺪ و ﺑﺮاي آﺷﻨﺎﻳﻲ ﺑﺎ آﻧﻬـﺎ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﻪ ﻛﺘﺎﺑﻬـﺎي آﻣﻮزﺷـﻲ زﺑـﺎن SQL ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ. 2 Data Binding
٦٠٥
BindingSourceﺑﻪ آﻧﻬﺎ دﺳﺘﺮﺳﻲ دارﻳﻢ را ﺑﻪ ﻛﻨﺘﺮل DataGridViewﻣﺘﺼﻞ ﻛﺮده و ﺑﻪ وﺳﻴﻠﻪ ي اﻳـﻦ ﻛﻨﺘـﺮل ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ .در ﺑﺨﺶ ﺑﻌﺪ ﻧﻴﺰ اﻳﻦ اﻃﻼﻋﺎت را ﺑﻪ وﺳﻴﻠﻪ ي ﻛﻨﺘﺮل TextBoxدر ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ ﺧﻮاﻫﻴﻢ داد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻣﺘﺼﻞ ﻛﺮدن داده ﻫﺎ ﺑﻪ ﻛﻨﺘﺮل DataGridView (1ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﻳﻚ ﺑﺮﻧﺎﻣـﻪ ي وﻳﻨـﺪوزي ﺟﺪﻳـﺪ ﺑـﻪ ﻧـﺎم Northwind Customers DataGridViewاﻳﺠﺎد ﻛﻨﻴﺪ. (2ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﺑﻪ ﻗﺴﻤﺖ Dataﺑﺮوﻳﺪ و ﺳﭙﺲ روي ﻛﻨﺘﺮل DataGridViewدو ﺑﺎر ﻛﻠﻴـﻚ ﻛـﺮده ﺗـﺎ ﻳﻚ ﻧﻤﻮﻧﻪ از اﻳﻦ ﻛﻨﺘﺮل روي ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻗﺮار ﺑﮕﻴﺮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎدر DataGridView Tasksﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 9-15ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ.
ﺷﻜﻞ 9-15 (3در اﻳﻦ ﻛﺎدر ،در ﻟﻴﺴﺖ روﺑﺮوي ﻋﺒﺎرت Choose Data Sourceﻛﻠﻴﻚ ﻛﺮده و ﺳـﭙﺲ در اﻳـﻦ ﻟﻴـﺴﺖ روي ﻟﻴﻨﻚ Add Project Data Sourceﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ وﻳـﺰارد Data Source Configuration Wizardﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ. (4در ﺻﻔﺤﻪ ي اول اﻳﻦ وﻳﺰارد ،ﻳﻌﻨﻲ ﭘﻨﺠﺮه ي Choose a Data Source Typeﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﻨﺒﻊ داده اي ﻣﻮرد ﻧﻈﺮ ﺧﻮدﺗﺎن را اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ 10-15ﻧﻴﺰ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺗﻮاﻧﻴـﺪ اﻧـﻮاع ﻣﺨﺘﻠﻔﻲ از ﻣﻨﺒﻊ ﻫﺎي داده اي را ﻣﺸﺨﺺ ﻛﺮده و ﺑﻪ آﻧﻬﺎ ﻣﺘﺼﻞ ﺷﻮﻳﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﻪ ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ ﻛﻪ ﺗﻮﺳﻂ ﻧﺮم اﻓﺰارﻫﺎي ﻣﺨﺘﻠﻔﻲ ﻣﺎﻧﻨﺪ Access ،Oracle ،SQL Serverو ﻳﺎ … اﻳﺠﺎد ﻣﻲ ﺷﻮد دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،روي آﻳﻜﻮن Databaseﻛﻠﻴﻚ ﻛﻨﻴﺪ .اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ از ﻃﺮﻳﻖ ﻳﻚ وب ﺳﺮوﻳﺲ ﺑـﻪ ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ ﺧﻮد ﻣﺘﺼﻞ ﺷﻮﻳﺪ روي آﻳﻜـﻮن Web Serviceﻛﻠﻴـﻚ ﻛﻨﻴـﺪ .آﻳﻜـﻮن Objectsﻧﻴـﺰ ﺑـﺮاي دﺳﺘﺮﺳـﻲ ﺑـﻪ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي داده اي در ﻻﻳﻪ ي ﻣﻨﻄﻖ ﺗﺠﺎري ﺑﻪ ﻛﺎر ﻣﻲ رود. در اﻳﻦ ﻗﺴﻤﺖ آﻳﻜﻮن Databaseرا اﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ روي دﻛﻤﻪ ي Nextﻛﻠﻴﻚ ﻛﻨﻴﺪ.
٦٠٦
ﺷﻜﻞ 10-15 (5 (6
(7
(8
(9
در ﭘﻨﺠـﺮه ي Choose Your Data Connectionروي دﻛﻤـﻪ ي New Connection ﻛﻠﻴﻚ ﻛﻨﻴﺪ. ﺑﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﭘﻨﺠـﺮه ي Choose Data Sourceﻧﻤـﺎﻳﺶ داده ﺧﻮاﻫـﺪ ﺷـﺪ .در اﻳـﻦ ﭘﻨﺠـﺮه ﮔﺰﻳﻨـﻪ ي Microsoft Access Database Fileرا از ﻟﻴـﺴﺖ Data Sourceاﻧﺘﺨـﺎب ﻛـﺮده و روي دﻛﻤﻪ ي Continueﻛﻠﻴﻚ ﻛﻨﻴﺪ. در ﻛﺎدر Add Connectionروي دﻛﻤﻪ ي Browseﻛﻠﻴﻚ ﻛـﺮده و ﺳـﭙﺲ ﺑـﻪ ﻓﻮﻟـﺪر Samplesدر ﻣﻜﺎن ﻧﺼﺐ ﺑﺮﻧﺎﻣﻪ ي Officeﺑﺮوﻳﺪ .اﻳﻦ ﻓﻮﻟﺪر ﺑـﻪ ﺻـﻮرت ﭘـﻴﺶ ﻓـﺮض ﺑـﺮاي Office 2003در آدرس C:\Program Files\Microsoft Office\Office11\Samplesﻗﺮار دارد. در اﻳﻦ آدرس ﻓﺎﻳﻞ Northwind.mdbرا اﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻧـﺎم و ﻣـﺴﻴﺮ ﻓﺎﻳﻞ اﻧﺘﺨﺎﺑﻲ ﺑﻪ ﻛﺎدر ﻣﺘﻨﻲ ﻣﻮﺟﻮد در ﭘﻨﺠﺮه ي Add Connectionاﺿﺎﻓﻪ ﺷﻮﻧﺪ .ﺳﭙﺲ در اﻳﻦ ﭘﻨﺠﺮه ﻧﻴﺰ روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻛﺎدر Add Connectionﺑﺴﺘﻪ ﺷـﻮد و ﺑـﻪ ﭘﻨﺠـﺮه ي Choose Your Data Connectionﺑﺮﮔﺮدﻳﺪ .در اﻳﻦ ﭘﻨﺠﺮه ﻧﻴﺰ روي دﻛﻤﻪ ي Nextﻛﻠﻴﻚ ﻛﻨﻴﺪ. ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ و از ﺷﻤﺎ ﻣﻲ ﭘﺮﺳﺪ ﻛﻪ ﻓﺎﻳﻞ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻛﻪ اﻧﺘﺨﺎب ﻛﺮده اﻳﺪ ﺟﺰﺋـﻲ از ﭘﺮوژه ﻧﻴﺴﺖ .آﻳﺎ ﻣﻲ ﺧﻮاﻫﻴﺪ اﻳﻦ ﻓﺎﻳﻞ ﺑﻪ ﻓﻮﻟﺪر ﭘﺮوژه ﻛﭙﻲ ﺷﺪه و از ﻧﺴﺨﻪ ي ﻛﭙﻲ آن اﺳﺘﻔﺎده ﺷﻮد؟ در اﻳﻦ ﻛـﺎدر روي دﻛﻤﻪ ي Yesﻛﻠﻴﻚ ﻛﻨﻴﺪ. Save the Connection String on the ﺑــﻪ اﻳــﻦ ﺗﺮﺗﻴــﺐ ﭘﻨﺠــﺮه ي Application Configuration Fileﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .در اﻳـﻦ ﭘﻨﺠـﺮه ﻧﻴـﺰ روي دﻛﻤـﻪ Nextﻛﻠﻴﻚ ﻛﻨﻴﺪ. ﺑﻌﺪ از ﻃﻲ اﻳﻦ ﻣﺮاﺣﻞ ﭘﻨﺠﺮه ي Choose Your Data Objectsﻧﻤـﺎﻳﺶ داده ﻣـﻲ ﺷـﻮد و ﺑـﻪ ﺷـﻤﺎ اﺟﺎزه ﻣﻲ دﻫﺪ ﺗﺎ داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز در ﺑﺮﻧﺎﻣﻪ را اﻧﺘﺨﺎب ﻛﻨﻴﺪ .در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﻛﻪ داده ﻫـﺎي ﻣـﻮرد
٦٠٧
ﻧﻴﺎز ﺷﻤﺎ از ﻳﻚ ﺟﺪول درون ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ وارد ﺑﺮﻧﺎﻣﻪ ﺷﻮﻧﺪ ،ﺑﺎ اﺟﺮاي ﭘﺮوﺳﻴﺠﺮ ﻫﺎي ذﺧﻴـﺮه ﺷـﺪه در ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ اﻳﺠﺎد ﺷﺪه و در اﺧﺘﻴﺎر ﺑﺮﻧﺎﻣﻪ ﻗﺮار ﺑﮕﻴﺮﻧﺪ و ﻳﺎ از روﺷﻬﺎي دﻳﮕﺮ ﻣﻮﺟﻮد دﻳﮕﺮ ﺑﺮاي ﮔﺮدآوري داده ﻫـﺎي ﻣـﻮرد ﻧﻴـﺎز اﺳـﺘﻔﺎده ﺷﻮد. در اي ﻗﺴﻤﺖ از ﭘﺮس وﺟﻮﻳﻲ ﻛﻪ در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﻗﺒﻞ اﻳﺠﺎد ﻛﺮده اﻳـﻢ اﺳـﺘﻔﺎده ﺧـﻮاﻫﻴﻢ ﻛـﺮد .ﺑﻨـﺎﺑﺮاﻳﻦ در ﻟﻴـﺴﺖ ﻧﻤﺎﻳﺶ دﻫﻨﺪه ي اﺷﻴﺎي ﻣﻮﺟﻮد در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ روي ﻋﻼﻣﺖ ﻣﺜﺒﺖ ﻛﻨﺎر Viewsﻛﻠﻴﻚ ﻛﺮده و ﺳﭙﺲ از ﻟﻴـﺴﺖ ﺑـﺎز ﺷــﺪه ﻫﻤﺎﻧﻨــﺪ ﺷــﻜﻞ 10-15ﮔﺰﻳﻨــﻪ ي CustomerQueryرا اﻧﺘﺨــﺎب ﻛﻨﻴــﺪ .اﮔــﺮ روي ﻋﻼﻣــﺖ ﻣﺜﺒــﺖ ﻛﻨــﺎر CustomerQueryﻛﻠﻴﻚ ﻛﻨﻴﺪ ﻟﻴﺴﺖ ﺗﻤﺎم ﻓﻴﻠﺪ ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻦ ﭘﺮس وﺟﻮ ﺑﺮﮔﺸﺘﻪ ﻣﻲ ﺷـﻮد ﻧﻤـﺎﻳﺶ داده ﺧﻮاﻫﻨﺪ ﺷﺪ .ﺑﻌﺪ از ﻣﺸﺎﻫﺪه ي اﻳﻦ ﺻﻔﺤﻪ روي دﻛﻤﻪ ي Finishﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻛـﺎر در اﻳـﻦ ﻗـﺴﻤﺖ ﺑـﻪ اﺗﻤـﺎم ﺑﺮﺳﺪ. در اﻳﻦ ﻟﺤﻈﻪ ،وﻳﺰارد ﻳﻚ ﺷـﻴﺊ از ﻧـﻮع DataSetﺑـﻪ ﻧـﺎم ،northwindDataSetﻳـﻚ ﺷـﻴﺊ از ﻧـﻮع BindingSourceﺑﻪ ﻧﺎم customerQueryBindingSourceو ﻧﻴـﺰ ﻳـﻚ ﺷـﻴﺊ از ﻧـﻮع TableAdapterﺑﻪ ﻧﺎم customerQueryTableAdapterاﻳﺠﺎد ﻣﻲ ﻛﻨﺪ.
ﺷﻜﻞ 11-15 (10در ﻓــﺮم اﺻـــﻠﻲ ﺑﺮﻧﺎﻣـــﻪ روي ﻣﺜﻠـــﺚ ﻛﻮﭼـــﻚ ﻛﻨــﺎر ﻛﻨﺘـــﺮل DataGridViewﻛﻠﻴـــﻚ ﻛـــﺮده ﺗـــﺎ ﻛـــﺎدر DataGridView Tasksﻧﻤﺎﻳﺶ داده ﺷﻮد .ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻧﻤﻲ ﺧﻮاﻫﻴﻢ داده ﻫـﺎي ﻣﻮﺟـﻮد را ﺣﺬف ﻛﺮده ،اﺿﺎﻓﻪ ﻛﻨﻴﻢ و ﻳـﺎ ﺗﻐﻴﻴـﺮ دﻫـﻴﻢ ،ﺑـﺎ ﻛﻠﻴـﻚ روي ﮔﺰﻳﻨـﻪ ﻫـﺎي Enable ،Enable Adding Editingو Enable Deletingﻋﻼﻣﺖ ﺗﻴﻚ ﻛﻨﺎر آﻧﻬﺎ را ﺣﺬف ﻛﻨﻴﺪ .اﻣﺎ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻛـﻪ ﺑﺘـﻮاﻧﻴﻢ داده
٦٠٨
ﻫﺎ را ﺑﺮ اﺳﺎس ﺳﺘﻮﻧﻬﺎي ﻣﻮرد ﻧﻈﺮ ﻣﺮﺗﺐ ﻛﻨﻴﻢ .ﭘﺲ روي ﮔﺰﻳﻨـﻪ ي Enable Column Reordering ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﻧﺘﺨﺎب ﺷﻮد .ﺳﭙﺲ در ﻗﺴﻤﺘﻲ از ﻧﻮار ﻋﻨﻮان ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﻳﻦ ﭘﻨﺠﺮه ﻣﺤﻮ ﺷﻮد. (11روي ﻛﻨﺘﺮل DataGridViewﻛﻠﻴـﻚ ﻛـﺮده و ﺳـﭙﺲ ﺑـﺎ اﺳـﺘﻔﺎده از ﭘﻨﺠـﺮه ي Propertiesﺧﺎﺻـﻴﺖ Dockآن را ﺑﻪ Fillﺗﻐﻴﻴﺮ دﻫﻴﺪ. (12ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴـﺪ ﻛـﺮد ﻛـﻪ ﻛﻨﺘـﺮل DataGridﺑـﻪ وﺳـﻴﻠﻪ ي اﻃﻼﻋـﺎت ﻣﻮﺟـﻮد در ﺑﺎﻧـﻚ اﻃﻼﻋﺎﺗﻲ ﭘﺮ ﺧﻮاﻫﺪ ﺷﺪ. ﺑﺎ ﻛﻠﻴﻚ روي ﻧﺎم ﻫﺮ ﻳﻚ از ﺳﺘﻮﻧﻬﺎي ﻣﻮﺟﻮد در ﺟﺪول ،ﻣﻲ ﺗﻮاﻧﻴﺪ اﻃﻼﻋﺎت را ﺑﺮ اﺳـﺎس آن ﺳـﺘﻮن ﺑـﻪ ﺻـﻮرت ﺻـﻌﻮدي ﻣﺮﺗﺐ ﻛﻨﻴﺪ .ﻛﻠﻴﻚ ﻣﺠﺪد روي ﻫﺮ ﺳﺘﻮن ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ اﻃﻼﻋﺎت ﺑﺮ اﺳﺎس آن ﺳﺘﻮن ﺑﻪ ﺻﻮرت ﻧﺰوﻟـﻲ ﻣﺮﺗـﺐ ﺷـﻮﻧﺪ. ﺑﺮاي ﺗﺸﺨﻴﺺ ﻧﺤﻮه ي ﻣﺮﺗﺐ ﺷﺪن اﻃﻼﻋﺎت ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺟﻬﺖ ﻣﺜﻠﺚ ﻛﻮﭼﻜﻲ ﻛﻪ در ﻛﻨﺎر ﻧﺎم ﺳﺘﻮن ﻧﻤﺎﻳﺶ داده ﻣـﻲ ﺷﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ در اﻳﻦ ﻗﺴﻤﺖ ﺗﻮاﻧﺴﺘﻴﺪ ﺑﺪون اﻳﻨﻜﻪ ﺣﺘﻲ ﻳﻚ ﺧﻂ ﻛﺪ در ﺑﺮﻧﺎﻣـﻪ وارد ﻛﻨﻴـﺪ داده ﻫـﺎﻳﻲ را از ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺪﺳﺖ آورده و آﻧﻬﺎ را ﻧﻤﺎﻳﺶ دﻫﻴﺪ .ﺗﻤﺎم ﻛﺪ ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺮاي اﻳﻦ ﻣﻮارد ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺗﻮﺳﻂ اﻳﻦ وﻳﺰارد ﻧﻮﺷﺘﻪ ﺷﺪه اﻧﺪ .1اﻳﻦ ﻣﻮرد ﺛﺎﺑﺖ ﻣﻲ ﻛﻨﺪ ﻛﻪ وﻳﺰاردﻫﺎ در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺗﺎ ﭼﻪ اﻧﺪازه ﻗﺪرﺗﻤﻨﺪ ﻋﻤﻞ ﻣﻲ ﻛﻨﻨﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺷﻴﻮه اي ﻛﻪ در اﻳﻦ ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ،ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻛﻪ ﺑﺘﻮاﻧﺪ اﻃﻼﻋﺎت ﻣﻮﺟﻮد در ﻳﻚ ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ را ﻧﻤـﺎﻳﺶ دﻫـﺪ اﺳﺘﻔﺎده ﻛﺮدﻳﻢ ﺑﺴﻴﺎر ﺳﺎده و آﺳﺎن ﺑﻮد .ﺑﺮﻧﺎﻣﻪ را ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻛﻨﺘﺮل DataGridViewﺑﻪ ﻓﺮم ﺷﺮوع ﻛﺮدﻳﻢ ،و ﻫﻤـﻴﻦ ﻣﻮرد ﻧﻴﺰ ﺑﺎﻋﺚ ﺷﺪ ﻛﻪ ﻛﺎدر Tasksﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل DataGridViewﻧﻤﺎﻳﺶ داده ﺷﻮد. در اﻳﻦ ﻛﺎدر ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از وﻳﺰارد Data Source Configuration Wizardو ﻃﻲ ﻛـﺮدن ﻳـﻚ ﺳﺮي ﻣﺮاﺣﻞ ﺳﺎده ،ﻳﻚ Data Sourceﺟﺪﻳﺪ اﻳﺠﺎد ﻛﻨﻴﻢ .در اﻳﻦ وﻳﺰارد اﺑﺘﺪا ﺑﺎﻳﺪ ﻧﻮع ﻣﻨﺒﻊ اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑـﻪ آن ﻣﺘﺼﻞ ﺷﻮﻳﻢ را ﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﺷﻴﺎي ﻣﻮﺟﻮد در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﻣﺸﺨﺺ ﻛﺮده اﻳﻢ ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﻨﺪ ﺷـﺪ و ﻣـﻲ ﺗﻮاﻧﻴﻢ آن اﺷﻴﺎﻳﻲ ﻛﻪ ﺑﻪ اﻃﻼﻋﺎت آن در ﺑﺮﻧﺎﻣﻪ ﻧﻴﺎز دارﻳﻢ را اﻧﺘﺨﺎب ﻛﻨﻴﻢ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ در اﻳﻦ وﻳﺰارد روي ﻛﻠﻴﺪ Finishﻛﻠﻴﻚ ﻣﻲ ﻛﻨﻴﻢ ،ﭼﻨﺪﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴـﻚ اﻳﺠـﺎد ﺷـﺪه و ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ اﺿﺎﻓﻪ ﻣﻲ ﺷﻮﻧﺪ .اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎ ﺷﺎﻣﻞ DataSet ،TableAdapterو ﻧﻴﺰ BindingSourceﻣﻲ ﺑﺎﺷﻨﺪ .از ﺑﻴﻦ اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎ ﻓﻘﻂ ﻛﺎﻣﭙﻮﻧﻨﺖ BindingSourceاﺳﺖ ﻛﻪ ﺑﺎ ﻧﺴﺒﺖ داده ﺷﺪن ﺑﻪ ﺧﺎﺻـﻴﺖ DataSourceدر ﻛﻨﺘﺮل ،DataGridViewﺑﺎﻋﺚ ﺑﺮﻗﺮاري ارﺗﺒﺎط ﺑﻴﻦ ﻛﻨﺘـﺮل DataGridViewو داده ﻫـﺎي ﻣﻮﺟـﻮد در ﺑﺮﻧﺎﻣـﻪ ﻣـﻲ ﺷﻮد. ﺑﻪ ﺧﺎﻃﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ روش ﻛﺎرﻛﺮد اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﺑﻪ اﻳﻦ ﺻﻮرت اﺳﺖ ﻛﻪ ﻫﻨﮕﺎم ﻧﻤﺎﻳﺶ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ،اﺑﺘﺪا داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺎﻣﭙﻮﻧﻨﺖ TableAdapterاز ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ درﻳﺎﻓﺖ ﺷﺪه و در اﺧﺘﻴﺎر ﻛﺎﻣﭙﻮﻧﻨﺖ DataSetﻗﺮار ﻣـﻲ ﮔﻴــﺮد .ﺳــﭙﺲ ﺗﻤــﺎم ﻛﻨﺘــﺮل ﻫــﺎي ﻣﻮﺟــﻮد در ﻓــﺮم ﻛــﻪ ﺑــﻪ اﻳــﻦ داده ﻫــﺎ ﻧﻴــﺎز دارﻧــﺪ ﻣــﻲ ﺗﻮاﻧﻨــﺪ ﺑــﺎ اﺳــﺘﻔﺎده از ﻛﺎﻣﭙﻮﻧﻨــﺖ BindingSourceﺑﻪ اﻳﻦ اﻃﻼﻋﺎت دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ ،زﻳـﺮا ﻛﺎﻣﭙﻮﻧﻨـﺖ BindingSourceﺗﻨﻬـﺎ ﻛـﺎﻣﭙﻮﻧﻨﺘﻲ اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ اﻃﻼﻋﺎت درون DataSetرا ﺑﺪﺳﺖ آورد. ﺗﻨﻬﺎ ﻫﺪﻓﻲ ﻛﻪ در اﻳﻦ ﺗﻤﺮﻳﻦ دﻧﺒﺎل ﻣﻲ ﻛﺮدﻳﻢ اﻳﻦ ﺑﻮد ﻛﻪ ﻣﺘﻮﺟﻪ ﺷﻮﻳﺪ اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﻗﺎﺑﻠﻴﺖ دﺳﺘﺮﺳﻲ ﺑﻪ داده ﻫﺎي ﻳـﻚ ﺑﺎﻧـﻚ اﻃﻼﻋﺎﺗﻲ ﺗﺎ ﭼﻪ اﻧﺪازه ﺳﺎده اﺳﺖ و ﻣﻲ ﺗﻮان ﺣﺘﻲ ﺑﺪون وارد ﻛﺮدن ﻳﻚ ﺧﻂ ﻛﺪ در ﺑﺮﻧﺎﻣﻪ اﻳﻦ ﻛﺎر را اﻧﺠﺎم داد .ﻓﻘﻂ ﻻزم اﺳﺖ ﻛﻪ ﻧﻮع
1در اﻳﻦ ﻗﺴﻤﺖ ،وﻳﺰاردي ﻛﻪ اﺳﺘﻔﺎده ﻛﺮدﻳﻢ در ﺣﺪود 900ﺧﻂ ﻛﺪ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮد.
٦٠٩
و ﻣﻜﺎن داده ﻫﺎي ﺧﻮد را ﺑﺮاي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻣﺸﺨﺺ ﻛﻨﻴﺪ و ﺳﭙﺲ ﻧﺤﻮه ي ﻧﻤﺎﻳﺶ آﻧﻬـﺎ را ﻧﻴـﺰ ﺗﻌﻴـﻴﻦ ﻛﻨﻴـﺪ ،ﺑﻘﻴـﻪ ي ﻛﺎرﻫـﺎ ﺑـﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻧﺠﺎم ﺧﻮاﻫﻨﺪ ﺷﺪ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺮﻧﺎﻣﻪ ي ﺟﺪﻳﺪي اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز را ﺑﻪ وﺳـﻴﻠﻪ ي ﭼﻨـﺪ ﻛﻨﺘـﺮل TextBox ﻧﻤﺎﻳﺶ دﻫﺪ .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺮ ﻛﻨﺘﺮل TextBoxرا ﺑﻪ ﻳﻜﻲ از ﻓﻴﻠﺪ ﻫﺎي ﺟﺪول ﻣـﻮرد ﻧﻈﺮﻣـﺎن در ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ ﻧـﺴﺒﺖ ﻣـﻲ دﻫﻴﻢ ،ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل BindingNavigatorﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻣﻲ دﻫـﻴﻢ ﺗـﺎ ﺑـﻴﻦ داده ﻫـﺎي ﻣﻮﺟـﻮد در ﺑﺮﻧﺎﻣـﻪ ﺣﺮﻛﺖ ﻛﻨﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻣﺘﺼﻞ ﻛﺮدن داده ﻫﺎ ﺑﻪ ﻛﻨﺘﺮل TextBox (1ﺑـﺎ اﺳـﺘﻔﺎده از وﻳـﮋوال اﺳـﺘﻮدﻳﻮ ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ ي وﻳﻨـﺪوزي ﺟﺪﻳـﺪ ﺑـﻪ ﻧـﺎم BindingNavigatorاﻳﺠﺎد ﻛﻨﻴﺪ. (2ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﺳﻪ ﻛﻨﺘﺮل Labelو ﺳﻪ ﻛﻨﺘﺮل TextBoxﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺳـﭙﺲ ﺧﺎﺻـﻴﺖ ﻫﺎ و ﻣﻜﺎن اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ داده و ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ﻛﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 12-15ﺷﻮد. Northwind Customers
ﺷﻜﻞ 12-15 (3در ﻓﺮم ﺑﺮﻧﺎﻣﻪ روي TextBoxاول ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﻧﺘﺨﺎب ﺷﻮد .ﺳﭙﺲ ﺑﺎ اﺳـﺘﻔﺎده از ﭘﻨﺠـﺮه ي Properties روي ﻋﻼﻣﺖ ﻣﺜﺒﺖ ﻛﻨﺎر ﺧﺎﺻﻴﺖ ) (DataBindingsاﻳﻦ ﻛﻨﺘﺮل ﻛﻠﻴﻚ ﻛﻨﻴﺪ .در ﻟﻴﺴﺘﻲ ﻛـﻪ ﻧﻤـﺎﻳﺶ داده ﻣـﻲ ﺷﻮد ،ﺧﺎﺻﻴﺖ Textرا اﻧﺘﺨﺎب ﻛﺮده و روي ﻋﻼﻣﺖ ﻣﺜﻠﺚ ﻛﻮﭼﻚ ﻣﻘﺎﺑﻞ آن ﻛﻠﻴﻚ ﻛﻨﻴﺪ. ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﻨﺠﺮه ي Data Sourceﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 13-15ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷـﻮد در اﻳـﻦ ﭘﻨﺠـﺮه روي ﻟﻴﻨـﻚ Data Source … Add Project Data Sourceﻛﻠﻴــﻚ ﻛﻨﻴــﺪ ﺗــﺎ وﻳــﺰارد ،Configuration Wizardﻫﻤﺎﻧﻨﺪ آﻧﭽﻪ در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﻗﺒﻞ ﻣﺸﺎﻫﺪه ﻛـﺮده ﺑﻮدﻳـﺪ ﻧﻤـﺎﻳﺶ داده ﺷﻮد.
٦١٠
ﺷﻜﻞ 13-15 (4 (5 (6
(7 (8
در ﭘﻨﺠـﺮه ي Choose a Data Source Typeآﻳﻜـﻮن Databaseرا اﻧﺘﺨـﺎب ﻛـﺮده و روي ﻛﻠﻴﺪ Nextﻛﻠﻴﻚ ﻛﻨﻴﺪ. در ﭘﻨﺠـﺮه ي Choose Your Data Connectionروي دﻛﻤـﻪ ي New Connection ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻛﺎدر Add Connectionﻧﻤﺎﻳﺶ داده ﺷﻮد. در ﻛﺎدر Add Connectionروي دﻛﻤﻪ ي Browseﻛﻠﻴﻚ ﻛـﺮده و ﺳـﭙﺲ ﺑـﻪ ﻓﻮﻟـﺪر Samplesدر ﻣﻜﺎن ﻧﺼﺐ ﺑﺮﻧﺎﻣﻪ ي Officeﺑﺮوﻳﺪ .اﻳﻦ ﻓﻮﻟﺪر ﺑـﻪ ﺻـﻮرت ﭘـﻴﺶ ﻓـﺮض ﺑـﺮاي Office 2003در آدرس C:\Program Files\Microsoft Office\Office11\Samplesﻗﺮار دارد. در اﻳﻦ آدرس ﻓﺎﻳﻞ Northwind.mdbرا اﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻧـﺎم و ﻣـﺴﻴﺮ ﻓﺎﻳﻞ اﻧﺘﺨﺎﺑﻲ ﺑﻪ ﻛﺎدر ﻣﺘﻨﻲ ﻣﻮﺟﻮد در ﭘﻨﺠﺮه ي Add Connectionاﺿﺎﻓﻪ ﺷﻮﻧﺪ .ﺳﭙﺲ در اﻳﻦ ﭘﻨﺠﺮه ﻧﻴﺰ روي دﻛﻤﻪ ي OKﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻛﺎدر Add Connectionﺑﺴﺘﻪ ﺷـﻮد و ﺑـﻪ ﭘﻨﺠـﺮه ي Choose Your Data Connectionﺑﺮﮔﺮدﻳﺪ .در اﻳﻦ ﭘﻨﺠﺮه ﻧﻴﺰ روي دﻛﻤﻪ ي Nextﻛﻠﻴﻚ ﻛﻨﻴﺪ. ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ و ﺑﻪ از ﺷﻤﺎ ﻣﻲ ﭘﺮﺳﺪ ﻛﻪ ﻓﺎﻳﻞ ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ ﻛـﻪ اﻧﺘﺨـﺎب ﻛـﺮده اﻳـﺪ ﺟﺰﺋﻲ از ﭘﺮوژه ﻧﻴﺴﺖ .آﻳﺎ ﻣﻲ ﺧﻮاﻫﻴﺪ اﻳﻦ ﻓﺎﻳﻞ ﺑﻪ ﻓﻮﻟﺪر ﭘﺮوژه ﻛﭙﻲ ﺷﺪه و از ﻧﺴﺨﻪ ي ﻛﭙﻲ آن اﺳﺘﻔﺎده ﺷﻮد؟ در اﻳﻦ ﻛﺎدر ﻧﻴﺰ روي دﻛﻤﻪ ي Yesﻛﻠﻴﻚ ﻛﻨﻴﺪ. در ﭘﻨﺠـﺮه ي Save the Connection String to the Application Configuration Fileﻧﻴﺰ روي دﻛﻤﻪ ي Nextﻛﻠﻴﻚ ﻛﻨﻴﺪ. در ﭘﻨﺠـﺮه ي ،Choose Your Database Objectsروي ﻋﻼﻣـﺖ ﻣﺜﺒـﺖ ﻛـﻪ در ﺳـﻤﺖ ﭼـﭗ Tablesﻗﺮار دارد ،در ﻟﻴﺴﺖ Database Objectsﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺳﭙﺲ در ﻟﻴﺴﺘﻲ ﻛﻪ ﺑﺮاي Tables ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد روي ﮔﺰﻳﻨﻪ ي Customersﻛﻠﻴﻚ ﻛﺮده ﺗﺎ ﻓﻴﻠﺪ ﻫﺎي اﻳﻦ ﺟـﺪول ﻧﻴـﺰ ﻧﻤـﺎﻳﺶ داده ﺷـﻮﻧﺪ .در اﻧﺘﻬﺎ ﻧﻴﺰ ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي ﻓﻴﻠـﺪ ﻫـﺎي ContactName ،CompanyNameو ContactTitle آﻧﻬﺎ را اﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ روي ﻛﻠﻴﺪ Finishﻛﻠﻴﻚ ﻛﻨﻴﺪ.
٦١١
(9ﻣﺠﺪداً در ﭘﻨﺠﺮه ي Propertiesروي ﻋﻼﻣﺖ ﻣﺜﻠﺚ ﻛﻮﭼﻚ ﻛﻪ در ﻣﻘﺎﺑـﻞ ﺧﺎﺻـﻴﺖ Textﻗـﺮار دارد ﻛﻠﻴـﻚ ﻛﻨﻴﺪ .اﻳﻦ ﺑﺎر ﭘﻨﺠﺮه ي Data Sourceﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 14-15ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﺑﻪ ﺗﺮﺗﻴﺐ روي ﻋﻼﻣﺖ ﻣﺜﺒـﺖ ،Project Data Sources ،Other Data ﻛﻨــﺎر ﮔﺰﻳﻨــﻪ ﻫــﺎي Sources NorthwindDataSetو در آﺧﺮ ﻧﻴﺰ Customersﻛﻠﻴﻚ ﻛﻨﻴﺪ. ﺣﺎل روي ﻓﻴﻠﺪ CompanyNameدر اﻳﻦ ﻗﺴﻤﺖ ﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎدر ﺑﺴﺘﻪ ﺷﺪه و ﺧﺎﺻـﻴﺖ Textدر اﻳﻦ TextBoxﺑﻪ ﻓﻴﻠﺪ CompanyNameدر ﻛﺎﻣﭙﻮﻧﻨﺖ DataSetﻣﺘﺼﻞ ﺧﻮاﻫﺪ ﺷﺪ. در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ اﮔﺮ ﺑﻪ ﭘﺎﻳﻴﻦ ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﮕﺎه ﻛﻨﻴﺪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺳـﻪ ﻛﺎﻣﭙﻮﻧﻨـﺖ ﻣـﻮرد ﻧﻴـﺎز ﺑـﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ داده ﻫﺎ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﺪه اﻧﺪ.
ﺷﻜﻞ 14-15 (10
(11 (12 (13
ﻛﻨﺘﺮل TextBoxدوم را از ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ ﺑﺎ اﺳـﺘﻔﺎده از ﻗـﺴﻤﺖ ) (DataBindingsدر ﭘﻨﺠﺮه ي Propertiesروي ﺧﺎﺻﻴﺖ Textﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻣﺸﺎﺑﻪ ﻗﺴﻤﺖ ﻗﺒﻞ ،ﻓﻴﻠﺪ ContactNameرا ﺑﻪ اﻳﻦ ﻛﺎدر اﺧﺘﺼﺎص دﻫﻴﺪ. ﻣﺮاﺣﻞ ﻗﺒﻞ را ﺑﺮاي TextBoxﺳﻮم ﻧﻴﺰ اﻧﺘﺨﺎب ﻛﺮده و ﻓﻴﻠﺪ ﺳﻮم ،ﻳﻌﻨﻲ ﻓﻴﻠﺪ ContactTitleرا ﻧﻴﺰ ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل ﻣﺘﺼﻞ ﻛﻨﻴﺪ. ﺣﺎل در ﺟﻌﺒﻪ اﺑﺰار ﺑﻪ ﻗﺴﻤﺖ Dataﺑﺮوﻳﺪ و روي ﻛﻨﺘﺮل BindingNavigatorدو ﺑﺎر ﻛﻠﻴﻚ ﻛﺮده ﺗﺎ ﻳـﻚ ﻧﻤﻮﻧﻪ از آن در ﻓﺮم ﻗﺮار ﺑﮕﻴﺮد .اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺑﻪ ﺑﺎﻻي ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻣﺘﺼﻞ ﺧﻮاﻫﺪ ﺷﺪ. ﺑــــــﺎ اﺳــــــﺘﻔﺎده از ﭘﻨﺠــــــﺮه ي Propertiesﺧﺎﺻــــــﻴﺖ BindingSourceﻛﻨﺘــــــﺮل BindingNavigatorرا ﺑﺮاﺑﺮ ﺑﺎ customersBindingSourceﻗﺮار دﻫﻴﺪ.
٦١٢
(14ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 15-15ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ .ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻦ ﻓﺮم ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻴﻦ رﻛﻮرد ﻫﺎي ﻣﻮﺟﻮد در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺟﺎ ﺑﻪ ﺟﺎ ﺷﻮﻳﺪ .ﺑﺮاي ﻣﺜﺎل ﺑﻪ رﻛﻮرد ﺑﻌﺪي و ﻳﺎ رﻛﻮرد ﻗﺒﻠﻲ ﺑﺮوﻳﺪ. ﻫﻤﭽﻨﻴﻦ ﻛﻠﻴﺪ ﻫﺎﻳﻲ ﻧﻴﺰ وﺟﻮد دارﻧﺪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ اوﻟﻴﻦ و ﻳﺎ آﺧﺮﻳﻦ رﻛﻮرد ﻣﻮﺟﻮد ﻣﻨﺘﻘﻞ ﺷﻮﻳﺪ. ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي دﻛﻤﻪ ي Deleteﻳﻜﻲ از رﻛﻮرد ﻫﺎي ﻣﻮﺟﻮد در DataSetﺣﺬف ﺧﻮاﻫﺪ ﺷﺪ ،اﻣﺎ ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ رﻛﻮرد از DataSetﺣﺬف ﻣﻲ ﺷﻮد ﻧﻪ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ .ﻫﻤﭽﻨﻴﻦ ﻛﻠﻴﻚ ﻛـﺮدن روي دﻛﻤـﻪ ي Newﻧﻴـﺰ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﻳﻚ رﻛﻮرد ﺟﺪﻳﺪ اﻳﺠﺎد ﺷﻮد .اﻳﻦ رﻛﻮرد ﻧﻴﺰ در DataSetاﻳﺠﺎد ﺧﻮاﻫﺪ ﺷﺪ ﻧﻪ در ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ. ﺑﺮاي اﻳﻨﻜﻪ ﺗﻐﻴﻴﺮات ﺑﻪ وﺟﻮد آﻣﺪه در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﻋﻤﺎل ﺷـﻮﻧﺪ ﻻزم اﺳـﺖ ﻣﻘـﺪاري ﻛـﺪ در ﺑﺮﻧﺎﻣـﻪ وارد ﻛﻨﻴﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ در ﻃﺮاﺣﻲ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ ﺣﺘـﻲ ﺑـﻪ وارد ﻛﺮدن ﻳﻚ ﺧﻂ ﻛﺪ ﻫﻢ ﻧﻴﺎز ﻧﺒﻮد.
ﺷﻜﻞ 15-15
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اﻳﻦ ﻗﺴﻤﺖ را ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ﺳﻪ ﻛﻨﺘﺮل TextBoxو ﻧﻴﺰ ﺳﻪ Labelﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ آﻏـﺎز ﻛـﺮدﻳﻢ .ﺳـﭙﺲ ﺳـﻌﻲ ﻛـﺮدﻳﻢ ﻛـﻪ ﺧﺎﺻﻴﺖ DataBindingsﻛﻨﺘﺮﻟﻬﺎي TextBoxرا ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ .در ﺣﻘﻴﻘـﺖ ﺑـﺎ اﻳـﻦ ﻛـﺎر ﻣـﻲ ﺧﻮاﺳـﺘﻴﻢ ﻛـﻪ ﺧﺎﺻـﻴﺖ Textاﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﺑﻪ ﻓﻴﻠﺪ ﻫﺎي ﻣﺸﺨﺼﻲ از داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ ﻣﺘﺼﻞ ﺷﻮﻧﺪ .اﻣﺎ اﺑﺘﺪا ﺑﺎﻳﺪ ﻳﻚ ﻣﻨﺒـﻊ اﻃﻼﻋـﺎﺗﻲ را ﺑـﺮاي ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻣﻲ ﻛﺮدﻳﻢ .اﻳﻦ ﻛﺎر را ﺑﺎ اﺳﺘﻔﺎده از وﻳﺰارد Data Source Configuration Wizardﻫﻤﺎﻧﻨﺪ ﺗﻤﺮﻳﻦ ﻗﺒﻞ اﻧﺠﺎم دادﻳﻢ. ﺑﻌﺪ از اﺗﻤﺎم وﻳﺰارد ،ﺳﻪ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻣﻮرد ﻧﻴﺎز ﻳﻌﻨﻲ BindingSource ،TableAdapterو ﻧﻴـﺰ DataSetﺑـﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﺷﺪه و ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﺪﻧﺪ .ﺳﭙﺲ ﺗﻮاﻧﺴﺘﻴﻢ ﺑـﺎ اﺳـﺘﻔﺎده از اﻳـﻦ ﻛﻨﺘـﺮل ﻫـﺎ ﺧﺎﺻـﻴﺖ Textﻫـﺮ ﻳـﻚ از TextBoxﻫﺎ را ﺑﻪ ﻳﻜﻲ از ﻓﻴﻠﺪ ﻫﺎي ﻣﻮﺟﻮد در DataSetﻣﺘﺼﻞ ﻛﻨﻴﻢ. ﺑﻌــﺪ از اﺿــﺎﻓﻪ ﻛــﺮدن ﻛﻨﺘــﺮل ،BindingNavigatorﺑــﺮاي ﺗﻨﻈــﻴﻢ آن ﻛــﺎﻓﻲ ﺑــﻮد ﻛــﻪ ﺑــﺎ اﺳــﺘﻔﺎده از ﭘﻨﺠــﺮه ي Propertiesﺧﺎﺻﻴﺖ BindingSourceآن را ﺑﺮاﺑﺮ ﺑﺎ ﻛﺎﻣﭙﻮﻧﻨﺖ BindingSourceاي ﻗﺮار دﻫﻴﻢ ﻛـﻪ در ﻣﺮﺣﻠﻪ ي ﻗﺒﻞ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﺷﺪه ﺑﻮد.
ﻧﺘﻴﺠﻪ:
٦١٣
ﻓﺼﻞ را ﺑﺎ ﺗﻌﺮﻳﻒ ﻣﻔﻬﻮم ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺷﺮوع ﻛﺮدﻳﻢ و آﻣﻮﺧﺘﻴﻢ ﻛﻪ ﺑﺎﻧﻚ ﻫﺎي اﻃﻼﻋﺎﺗﻲ ﺑﻪ ﭼﻪ ﻣﻮاردي ﮔﻔﺘﻪ ﻣﻲ ﺷـﻮد .ﺳـﭙﺲ ﺑـﻪ آﺷﻨﺎﻳﻲ ﺑﺎ زﺑﺎن SQLو ﻣﻌﺮﻓﻲ ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ دﺳﺘﻮرات آن ﻳﻌﻨﻲ دﺳﺘﻮر SELECTﭘﺮداﺧﺘﻴﻢ .ﺑﻌﺪ از اﺗﻤﺎم اﻳـﻦ ﻗـﺴﻤﺖ ﻧﻴـﺰ ﺑـﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻣﻮارد ،ﻳﻚ ﭘﺮس وﺟﻮ در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ Northwind.mdbاﻳﺠﺎد ﻛﺮده و ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛـﻪ Access ﭼﮕﻮﻧﻪ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ دﺳﺘﻮرات SQLﻣﻮرد ﻧﻴﺎز را ﺗﻮﻟﻴﺪ ﻛﺮده و اﺟﺮا ﻣﻲ ﻛﻨﺪ. ﺳﭙﺲ ﺑﻪ ﺑﺮرﺳﻲ ﻧﺤﻮه ي اﺳﺘﻔﺎده از داده ﻫﺎي ﻣﻮﺟﻮد در ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ﭘﺮداﺧﺘﻴﻢ و ﻣـﺸﺎﻫﺪه ﻛـﺮدﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان اﻃﻼﻋﺎت را ﺑﻪ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻣﺎﻧﻨـﺪ DataGridViewو ﻳـﺎ TextBoxﻣﺘـﺼﻞ ﻛـﺮد .ﺑـﺎ ﺗﻌـﺪادي از ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي ﻣﻬﻢ و ﺿﺮوري ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ Accessآﺷﻨﺎ ﺷﺪﻳﻢ و ﻣﺸﺎﻫﺪه ﻛـﺮدﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان آﻧﻬﺎ را ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﺑﺮ روي ﻓﺮم ﻗﺮار داد و ﻳﺎ ﺑﺎ اﺳﺘﻔﺎده از وﻳﺰاردﻫﺎ آﻧﻬﺎ را ﺑـﻪ ﺻـﻮرت اﺗﻮﻣﺎﺗﻴـﻚ اﻳﺠـﺎد ﻛﺮده و ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮد. در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ:
ﺗﻮﺿﻴﺢ دﻫﻴﺪ ﻛﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﭼﻴﺴﺖ و از ﭼﻪ اﺷﻴﺎﻳﻲ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ؟ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر SELECTدر زﺑﺎن SQLداده ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺧﻮد را از ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺪﺳﺖ آورﻳﺪ. ﺑﺎ اﺳـﺘﻔﺎده از وﻳـﺰارد Data Source Configuration Wizardﻛﺎﻣﭙﻮﻧﻨـﺖ ﻫـﺎي ﻻزم ﺑـﺮاي ﻣﺘﺼﻞ ﺷﺪن ﺑﻪ ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را اﻳﺠﺎد ﻛﻨﻴﺪ. ﻳﻚ ﻛﻨﺘﺮل DataGridViewرا ﺑﻪ داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ ﻣﺘﺼﻞ ﻛﻨﻴﺪ. ﻛﻨﺘﺮﻟﻬــــﺎي TextBoxرا ﺑــــﻪ ﻓﻴﻠــــﺪ ﻫــــﺎي ﻣﺸﺨــــﺼﻲ در DataSetﻣﺘــــﺼﻞ ﻛــــﺮده و از ﻛﻨﺘــــﺮل BindingNavigatorاﺳﺘﻔﺎده ﻛﻨﻴﺪ.
در اﻳﻦ ﻓﺼﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از وﻳﺰاردﻫﺎي ﻣﻮﺟﻮد در وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005داده ﻫـﺎي ﻣﻮﺟـﻮد در ﻳـﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را ﺑﻪ ﺳﺮﻋﺖ ﺑﻪ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻓﺮم ﻣﺘﺼﻞ ﻛﺮد .اﻣﺎ در ﺷﺮاﻳﻄﻲ ﻣﻤﻜﻦ اﺳﺖ ﻧﻴﺎز ﺑﻪ ﻛﻨﺘﺮل ﺑﻴـﺸﺘﺮ روي ﻧﺤـﻮه ي ارﺗﺒﺎط ﺑﺎ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ و ﻳﺎ ﻧﺤﻮه ي ﻣﺘﺼﻞ ﺷﺪن ﻛﻨﺘﺮل ﻫﺎ ﺑﻪ داده ﻫﺎ داﺷﺘﻪ ﺑﺎﺷﻴﺪ .در ﻓﺼﻞ ﺷﺎﻧﺰدﻫﻢ ﺳﻌﻲ ﺧﻮاﻫﻴﻢ ﻛـﺮد ﻛـﻪ ﺧـﻂ ﻣﺸﻲ ﻣﺘﻔﺎوﺗﻲ را ﻧﺴﺒﺖ ﺑﻪ اﻳﻦ ﻓﺼﻞ ﭘﻴﺶ ﮔﺮﻓﺘﻪ و ﺳﻌﻲ ﻛﻨﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ،ﻛﻨﺘﺮﻟﻬﺎي ﻳﻚ ﻓﺮم را ﺑﻪ داده ﻫـﺎي ﻣﻮﺟـﻮد در ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺘﺼﻞ ﻛﻨﻴﻢ .ﻫﻤﭽﻨﻴﻦ ﺑﺎ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي دﺳﺘﺮﺳﻲ ﺑﻪ داده ﻫﺎ ﺑﻬﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ و ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان از ﺧﺎﺻﻴﺖ ﻫﺎ و ﻳﺎ ﻣﺘﺪﻫﺎي آﻧﻬﺎ در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﺮد.
ﺗﻤﺮﻳﻦ:
ﺗﻤﺮﻳﻦ :1 ﭘﺮس وﺟﻮي ﺟﺪﻳﺪي را در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ Northwindاﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ ﺑﺘﻮاﻧﺪ اﻃﻼﻋﺎت درون ﻓﻴﻠﺪ ﻫـﺎي ،FirstName LastNameو Titleرا از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ Employeesﺑﺪﺳﺖ آورد .ﻫﻤﭽﻨﻴﻦ دﺳﺘﻮر را ﺑـﻪ ﮔﻮﻧـﻪ اي ﺑﻨﻮﻳـﺴﻴﺪ ﻛـﻪ ﻧﺘﺎﻳﺞ را ﺑﺮ اﺳﺎس ﺳﺘﻮن LastNameﻣﺮﺗـﺐ ﻛﻨـﺪ ،ﺳـﭙﺲ آن را ﺑـﻪ ﻧـﺎم EmployeeQueryذﺧﻴـﺮه ﻛﻨﻴـﺪ .ﺑﺮﻧﺎﻣـﻪ ي وﻳﻨﺪوزي اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ داده ﻫﺎي ﺣﺎﺻﻞ از اﺟﺮاي اﻳﻦ ﭘﺮس وﺟﻮ را در ﻳﻚ ﻛﻨﺘﺮل DataGridViewﻧﻤﺎﻳﺶ دﻫﺪ.
٦١٤
ﺗﻤﺮﻳﻦ :2 ﺑﺎ اﺳﺘﻔﺎده از ﭘﺮس وﺟﻮﻳﻲ ﻛﻪ در ﺗﻤﺮﻳﻦ ﻗﺒﻞ اﻳﺠﺎد ﻛﺮدﻳﺪ ،ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ﺟﺪﻳﺪي اﻳﺠﺎد ﻛﻨﻴـﺪ ﻛـﻪ ﺑﺘﻮاﻧـﺪ ﺑـﺎ اﺳـﺘﻔﺎده از ﭼﻨـﺪﻳﻦ TextBoxو ﻧﻴـﺰ ﻳــﻚ ﻛﻨﺘــﺮل BindingNavigatorداده ﻫــﺎي ﺣﺎﺻــﻞ از اﺟـﺮاي ﭘــﺮس وﺟــﻮ را ﺑــﻪ ﻛﻨﺘﺮﻟﻬــﺎي TextBoxﻣﺘﺼﻞ ﻛﻨﺪ.
٦١٥
ﻓﺼﻞ ﺷﺎﻧﺰدﻫﻢ :ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺎ SQL Serverو ADO.NET در ﻓﺼﻞ ﭘﺎﻧﺰدﻫﻢ ﺑﺎ ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ و ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﻪ ﺻﻮرت ﻣﻘﺪﻣﺎﺗﻲ آﺷﻨﺎ ﺷﺪﻳﻢ .ﺗﻮاﻧﺴﺘﻴﻢ اﻃﻼﻋﺎت داﺧﻞ ﻳـﻚ ﺟﺪول از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وﻳﻨﺪوز ﺑﺪﺳﺖ آورده و آن را در ﺟﺪوﻟﻲ در ﻓﺮم ﻧﻤﺎﻳﺶ دﻫﻴﻢ .ﻫﻤﭽﻨﻴﻦ ﺑﺪون اﻳﻨﻜﻪ ﻻزم ﺑﺎﺷﻴﺪ ﻛﺪي وارد ﻛﻨﻴﻢ ،ﺗﻮاﻧﺴﺘﻴﻢ اﻣﻜﺎﻧﺎﺗﻲ ﻣﺎﻧﻨﺪ ﻣﺮﺗﺐ ﻛﺮدن داده ﻫﺎ را ﻧﻴﺰ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ. ﺑﺮاي اﻧﺠﺎم ﺗﻤﺎم اﻳﻦ ﻣﻮارد از ﻳﻚ وﻳﺰارد اﺳﺘﻔﺎده ﻛﺮدﻳﻢ و آن وﻳﺰارد ﻧﻴﺰ ﻛﺪ ﻫﺎي زﻳﺎدي را ﺑﺮاي اﻧﺠﺎم ﻣﻮارد ﻣﻮرد ﻧﻈﺮ ﻣﺎ ﻧﻮﺷـﺖ ،ﻛـﺪ ﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ اﻳﺠﺎد ﻳﻚ اﺗﺼﺎل ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ،ﺗﻨﻈﻴﻢ ﻛﺮدن آداﭘﺘﻮر ﻫﺎي داده اي و ﻧﻴﺰ اﻳﺠﺎد ﻳﻚ DataSetﻣﺨﺼﻮص ﺑـﺮاي ﺟﺪاول ﻣﻮرد ﻧﻈﺮ ﻣﺎ .اﺳﺘﻔﺎده از اﻳﻦ روش ﺑﺮاي دﺳﺘﺮﺳﻲ ﺳﺎده ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ و اﻧﺠﺎم ﻛﺎرﻫﺎي ﻣﻌﻤﻮﻟﻲ ﻣﺎﻧﻨﺪ درﻳﺎﻓﺖ و ﻣﺸﺎﻫﺪه ي اﻃﻼﻋﺎت از ﻳﻚ ﻳﺎ ﭼﻨﺪ ﺟﺪول روش ﻣﻨﺎﺳﺒﻲ اﺳﺖ ،اﻣﺎ ﺑﺮاي ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺑﺰرﮔﺘﺮ ﻻزم اﺳﺖ ﻛﻪ ﻛﻨﺘﺮل ﺑﻴﺸﺘﺮي ﺑﺮ داده ﻫـﺎ و ﻳـﺎ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ داﺷﺘﻪ ﺑﺎﺷﻴﻢ و اﻳﻦ ﻛﺎر ﻧﻴﺰ ﻓﻘﻂ از ﻃﺮﻳﻖ ﻛﺪ ﻧﻮﻳﺴﻲ ﻣﻴﺴﺮ اﺳﺖ. در اﻳﻦ ﻓﺼﻞ ﺳﻌﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﻧﮕﺎه ﻋﻤﻴﻘﺘﺮي ﺑﻪ ﻣﺒﺤﺚ دﺳﺘﺮﺳﻲ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ .ﺗﻜﻨﻮﻟﻮژﻳﻬﺎﻳﻲ ﻛﻪ در ﻓﺼﻞ ﻗﺒﻞ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ داده ﻫﺎ و ﻳﺎ ﺗﻐﻴﻴﺮ در آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﺮدﻳﻢ ،از ﻗﺒﻴـﻞ ﻛﺎﻣﭙﻮﻧﻨـﺖ ﻫـﺎﻳﻲ ﺑـﺮاي درﻳﺎﻓـﺖ اﻃﻼﻋـﺎت از ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ، ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎﻳﻲ ﺑﺮاي ذﺧﻴﺮه ي آﻧﻬﺎ در ﺣﺎﻓﻈﻪ و ﻧﻴﺰ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎﻳﻲ ﺑﺮاي ﻣﺘﺼﻞ ﻛﺮدن اﻳﻦ داده ﻫﺎ ﺑﻪ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻓﺮم ،ﻫﻤـﻪ ﻣﺠﻤﻮﻋﺎً ﺑﻪ ﻧﺎم ADO.NETﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮﻧﺪ .در اﻳﻦ ﻓﺼﻞ ﺳﻌﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد ﺑﺎ ﺗﻮاﻧﺎﻳﻲ ﻫـﺎ و ﻗﺎﺑﻠﻴﺘﻬـﺎي دروﻧـﻲ ADO.NET ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ داده ﻫﺎي درون ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ و ﻧﻴﺰ اﻳﺠﺎد ﺗﻐﻴﻴﺮات در آﻧﻬﺎ آﺷﻨﺎ ﺷﻮﻳﻢ .ﻫﻤﭽﻨـﻴﻦ ﻣـﺸﺎﻫﺪه ﺧـﻮاﻫﻴﻢ ﻛـﺮد ﻛـﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان داده ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻳﻚ DataSetدرون ﺣﺎﻓﻈﻪ ذﺧﻴﺮه ﺷﺪه اﺳﺖ را ﺗﻐﻴﻴﺮ دﻫﻴﻢ ،ﻓﻴﻠﺘﺮ ﻛﺮده و ﻳﺎ وﻳﺮاﻳﺶ ﻛﻨﻴﻢ. داده ﻫﺎﻳﻲ ﻛﻪ از ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺘﺨﺮاج ﻣﻲ ﺷﻮﻧﺪ ،ﺑﺮاي ﻧﻤﺎﻳﺶ داده ﺷﺪن ﺑﺎﻳﺪ ﺑﻪ ﻳﻜﻲ از ﻛﻨﺘﺮل ﻫﺎي ﻣﻮﺟـﻮد در ﻓـﺮم ﻣﺘـﺼﻞ ﺷﻮﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻻزم اﺳﺖ ﻛﻪ اﺗﺼﺎل داده ﻫﺎ ﺑﻪ ﻛﻨﺘﺮل ﻫﺎ را ﻧﻴﺰ دﻗﻴﻖ ﺗﺮ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ در اﻳﻦ ﻓﺼﻞ ﻣـﺸﺎﻫﺪه ﺧـﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻓﺮم را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻨﻈﻴﻢ ﻛﺮد ﻛﻪ در ﻫﺮ ﻟﺤﻈﻪ ﻓﻘﻂ داده ﻫﺎي ﻣﺮﺑﻮط ﺑـﻪ ﻳـﻚ رﻛـﻮرد را ﻧﻤﺎﻳﺶ دﻫﻨﺪ )ﺑﺮاي ﻣﺜﺎل ،ﻣﺎﻧﻨﺪ TextBoxﻫﺎ( و ﻳﺎ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از اﺷـﻴﺎﻳﻲ ﻣﺎﻧﻨـﺪ CurrencyManager ﺑﻴﻦ رﻛﻮرد ﻫﺎ ﺣﺮﻛﺖ ﻛﺮد. در اﻳﻦ ﻓﺼﻞ:
ﺧﻮاﻫﻴﻢ آﻣﻮﺧﺖ ﻛﻪ اﺷﻴﺎي ADO.NETﭼﻴﺴﺘﻨﺪ؟ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻛﻨﺘﺮل ﻫﺎ را ﺑﻪ داده ﻫﺎ ﻣﺘﺼﻞ ﻛﺮد. روﺷﻬﺎي ﺟﺴﺘﺠﻮ و ﻳﺎ ﻣﺮﺗﺐ ﺳـﺎزي داده ﻫـﺎي داده ﻫـﺎي درون ﺣﺎﻓﻈـﻪ را ﺑـﺎ اﺳـﺘﻔﺎده از اﺷـﻴﺎي Data Viewدر ADO.NETﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد. ﺑﺎ ﻧﺤﻮه ي اﻧﺘﺨﺎب ،درج ،وﻳﺮاﻳﺶ و ﻳﺎ ﺣﺬف داده ﻫﺎ درون ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﻪ وﺳﻴﻠﻪ ي ADO.NETآﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ.
در ﻃﻲ اﻳﻦ ﻓﺼﻞ ﺑﺎ ﻧﺤﻮه ي اﺳﺘﻔﺎده از ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ اﻳﺠﺎد ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ SQL Serverﻧﻴـﺰ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ و ﺧﻮاﻫﻴﻢ دﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﻪ وﺳﻴﻠﻪ ي ﺳﺮوﻳﺲ دﻫﻨﺪه ي اﻃﻼﻋﺎﺗﻲ SqlClientﺑـﻪ آﻧﻬـﺎ دﺳﺘﺮﺳـﻲ ﭘﻴﺪا ﻛﺮد .ﺳﺮوﻳﺲ دﻫﻨﺪه ي اﻃﻼﻋﺎﺗﻲ ،SqlClientﻧﺴﺒﺖ ﺑﻪ ﺳﺮوﻳﺲ دﻫﻨﺪه ي اﻃﻼﻋﺎﺗﻲ ) OleDbﻛﻪ ﺑﺮاي ﻛﺎر ﺑﺎ ﺑﺎﻧـﻚ اﻃﻼﻋﺎﺗﻲ اﻳﺠﺎد ﺷﺪه ﺑﺎ Accessاﺳﺘﻔﺎده ﻣﻲ ﺷﻮد( از ﺳﺮﻋﺖ ﺑﻴﺸﺘﺮي ﺑﺮﺧﻮردار اﺳﺖ ،اﻣﺎ ﻓﻘﻂ ﻣـﻲ ﺗﻮاﻧـﺪ ﺑـﺎ ﺑﺎﻧﻜﻬـﺎي اﻃﻼﻋـﺎﺗﻲ ﺗﺤﺖ SQL Serverﻛﺎر ﻛﻨﺪ.
٦١٦
ﺑﺮاي اﻧﺠﺎم ﺗﻤﺮﻳﻨﺎت اﻳﻦ ﻓﺼﻞ ﻻزم اﺳﺖ ﻛﻪ ﺑﻪ ﻳﻜﻲ از ﻧﺮم اﻓﺰارﻫﺎي SQL Server ،SQL Server 7 ،MSDE 2000و ﻳﺎ SQL Server 2005دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ .زﻳﺮا در ﺑﺮﻧﺎﻣﻪ ﻫﺎي اﻳﻦ ﻓﺼﻞ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻧﻤﻮﻧﻪ اي ﻛـﻪ در اﻳﻦ ﻧﺮم اﻓﺰارﻫﺎ وﺟﻮد دارد )ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ (Pubsاﺳﺘﻔﺎده ﺷﺪه اﺳﺖ.
ADO.NET ﻫﻤﺎﻧﻄﻮر ﻛﻪ در اﺑﺘﺪاي ﻓﺼﻞ ﻧﻴﺰ ذﻛﺮ ﺷﺪ ،ﺑﻪ ﻣﺠﻤﻮﻋﻪ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎﻳﻲ ﻛـﻪ ﺑـﺮاي دﺳﺘﺮﺳـﻲ ﺑـﻪ داده ﻫـﺎي ﻳـﻚ ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ در .NETاﺳﺘﻔﺎده ﻣﻲ ﺷﻮد ADO.NET1ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد ADO.NET .ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ داده ﻫﺎ از ﻣﻌﻤـﺎري ﻏﻴـﺮ ﻣﺘـﺼﻞ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ .ﻣﻌﻤﺎري ﻏﻴﺮ ﻣﺘﺼﻞ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ اﺑﺘﺪا ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﻮرد ﻧﻈﺮ ﺧﻮد ﻣﺘﺼﻞ ﺷﺪه ،داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺧﻮد را از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ درﻳﺎﻓﺖ ﻛﺮده و آﻧﻬﺎ را در ﺣﺎﻓﻈﻪ ي ﻛﺎﻣﭙﻴﻮﺗﺮ ذﺧﻴﺮه ﻣﻲ ﻛﻨﺪ .ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻗﻄـﻊ ﻣﻲ ﺷﻮد و ﺗﻐﻴﻴﺮات ﻣﻮرد ﻧﻈﺮ ﺧﻮد را در داده ﻫﺎي ﻣﻮﺟﻮد در ﺣﺎﻓﻈﻪ اﻧﺠﺎم ﻣﻲ دﻫﺪ .ﻫﺮ زﻣﺎن ﻛـﻪ ﻻزم ﺑﺎﺷـﺪ ﺗﻐﻴﻴـﺮات اﻳﺠـﺎد ﺷـﺪه در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ذﺧﻴﺮه ﺷﻮﻧﺪ ،ﺑﺮﻧﺎﻣﻪ ﻳﻚ اﺗﺼﺎل ﺟﺪﻳﺪ را ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﻳﺠﺎد ﻛﺮده و از ﻃﺮﻳﻖ اﻳﻦ اﺗﺼﺎل ﺗﻐﻴﻴﺮاﺗـﻲ را ﻛـﻪ در داده ﻫﺎ اﻋﻤﺎل ﻛﺮده ﺑﻮد را در ﺟﺪاول اﺻﻠﻲ ﻧﻴﺰ اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ .ﻛﺎﻣﭙﻮﻧﻨﺖ اﺻﻠﻲ ﻛـﻪ داده ﻫـﺎي درﻳـﺎﻓﺘﻲ از ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ را در ﺣﺎﻓﻈـﻪ ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ ،ﻛﺎﻣﭙﻮﻧﻨﺖ DataSetاﺳﺖ .اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﺧﻮد از ﭼﻨﺪ ﻛﺎﻣﭙﻮﻧﻨﺖ دﻳﮕﺮ ﻣﺎﻧﻨﺪ اﺷﻴﺎﻳﻲ از ﻧﻮع DataTable ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ .ﺑﻌﺪ از اﻳﻨﻜﻪ داده ﻫﺎ در ﺣﺎﻓﻈﻪ ﻗﺮار ﮔﺮﻓﺘﻨﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻴﻦ آﻧﻬﺎ ﺟﺴﺘﺠﻮ ﻛﻨﻴﺪ ،دﺳﺘﻮرات SELECTﻣﻮرد ﻧﻈﺮ ﺧﻮد را روي آﻧﻬﺎ اﺟﺮا ﻛﺮده و آﻧﻬﺎ را ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ ﻓﻴﻠﺘﺮ ﻛﻨﻴﺪ و ﻳﺎ ﺗﻐﻴﻴﺮاﺗﻲ را در اﻳﻦ داده ﻫﺎ اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ در ﻃﻲ اﻳﻦ ﻓـﺼﻞ ﺑـﺎ ﻧﺤـﻮه ي اﻧﺠﺎم اﻳﻦ ﻣﻮارد آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ. اﺳﺘﻔﺎده از ﻣﻌﻤﺎري ﻏﻴﺮ ﻣﺘﺼﻞ ﻣﺰاﻳﺎي زﻳﺎدي دارد ﻛﻪ ﻣﻬﻤﺘﺮﻳﻦ آن اﻓﺰاﻳﺶ ﺗﻮاﻧﺎﻳﻲ ﺑﺮﻧﺎﻣﻪ در ﺳﺮوﻳﺲ دادن ﺑﻪ ﭼﻨﺪﻳﻦ ﻛﺎرﺑﺮ ﺑﻪ ﺻﻮرت ﻫﻤﺰﻣﺎن اﺳﺖ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ روش ﻣﻲ ﺗﻮاﻧﻴﻢ ﺗﻌﺪاد اﻓﺮادي ﻛﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ ﺻـﻮرت ﻫﻤﺰﻣـﺎن از ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻨﺪ را از ده ﻫﺎ ﻧﻔﺮ ﺑﻪ ﺻﺪﻫﺎ ﻧﻔﺮ اﻓﺰاﻳﺶ دﻫﻴﻢ .دﻟﻴﻞ اﻳﻦ ﻣﻮرد ﻧﻴﺰ در اﻳﻦ اﺳﺖ ﻛـﻪ در اﻳـﻦ روش ﺑﺮﻧﺎﻣـﻪ ﻫـﺎ ﻓﻘـﻂ در ﻣﻮاﻗﻊ ﻣﻮرد ﻧﻴﺎز ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺘﺼﻞ ﻣﻲ ﺷﻮﻧﺪ و ﺑﻌﺪ از اﺟﺮاي وﻇﺎﻳﻒ ﻻزم اﺗﺼﺎل ﺧﻮد را ﻗﻄﻊ ﻣﻲ ﻛﻨﻨﺪ ،ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﻣﻨـﺎﺑﻊ اﺳﺘﻔﺎده ﺷﺪه ﺑﺮاي اﺗﺼﺎل آﻧﻬﺎ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻧﻴﺰ آزاد ﺷﺪه و در اﺧﺘﻴﺎر ﻛﺎرﺑﺮان دﻳﮕﺮ ﻗﺮار ﻣﻲ ﮔﻴﺮد.
2
ﻓﻀﺎي ﻧﺎم :Data ﻛﻼﺳﻬﺎي اﺻﻠﻲ ADO.NETدر ﻓﻀﺎي ﻧﺎم System.Dataﻗﺮار دارﻧﺪ .اﻳﻦ ﻓﻀﺎي ﻧﺎم ﺧﻮد ﻧﻴﺰ ﺷﺎﻣﻞ ﭼﻨﺪ ﻓﻀﺎي ﻧﺎم دﻳﮕﺮ اﺳﺖ ﻛﻪ ﻣﻬﻤﺘﺮﻳﻦ آﻧﻬﺎ ﻋﺒﺎرﺗﻨﺪ از System.Data.OleDbو .System.Data.SqlClientﻓﻀﺎي ﻧـﺎم System.Data.SqlClientﺷﺎﻣﻞ ﻛﻼس ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﺑﺎﻧﻚ ﻫﺎي اﻃﻼﻋﺎﺗﻲ اﻳﺠـﺎد ﺷـﺪه ﺑـﻪ وﺳﻴﻠﻪ ي SQL Serverﺑﻪ ﻛﺎر ﻣﻲ رود .ﻓﻀﺎي ﻧﺎم System.Data.OleDbﻧﻴﺰ ﺣﺎوي ﻛﻼس ﻫﺎﻳﻲ اﺳـﺖ ﻛـﻪ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﺑﺎﻧﻚ ﻫﺎي اﻃﻼﻋﺎﺗﻲ از ﻧﻮع ) OLE3ﻣﺎﻧﻨﺪ ﺑﺎﻧﻚ ﻫﺎي اﻃﻼﻋﺎﺗﻲ (Accessﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴـﺮد .ﺑـﺮاي ﻣﺜﺎل در ﻓﺼﻞ ﻗﺒﻞ ﺑﺮاي اﺗﺼﺎل ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ از ﺑﻌﻀﻲ از ﻛﻼﺳﻬﺎي ﻓﻀﺎي ﻧﺎم +++ در ﻓـــــﻀﺎي ﻧـــــﺎم System.Dataدو ﻓـــــﻀﺎي ﻧـــــﺎم دﻳﮕـــــﺮ ﻧﻴـــــﺰ وﺟـــــﻮد دارﻧـــــﺪ ﻛـــــﻪ ﻋﺒﺎرﺗﻨـــــﺪ از System.Data.OracleClientو .System.Data.Odbcﻓــﻀﺎي ﻧــﺎم OracleClient ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﺑﺎﻧﻚ ﻫﺎي اﻃﻼﻋﺎﺗﻲ اﻳﺠﺎد ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ Oracleﻣـﻮرد اﺳـﺘﻔﺎده ﻗـﺮار ﻣـﻲ ﮔﻴـﺮد. 1
ActiveX Data Object Disconnected Architecture 3 Object Linking and Embedding 2
٦١٧
ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻓﻀﺎي ﻧﺎم ﻧﻴﺰ ،ﻫﻤﺎﻧﻨﺪ ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﻓﻀﺎي ﻧﺎم SqlClientﺑﺮاي دﺳﺘﺮﺳـﻲ ﺑـﻪ ﺑﺎﻧـﻚ ﻫـﺎي اﻃﻼﻋﺎﺗﻲ از ﻧﻮع Oracleﺑﻬﻴﻨﻪ ﺳﺎزي ﺷﺪه اﻧﺪ .ﻓﻀﺎي ﻧﺎم Odbcﻧﻴﺰ ﺣﺎوي ﻛﻼس ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﺑـﺮاي دﺳﺘﺮﺳـﻲ ﺑـﻪ ﺑﺎﻧـﻚ ﻫﺎي اﻃﻼﻋﺎﺗﻲ ﻗﺪﻳﻤﻲ از ﻧﻮع ODBC1ﻛﻪ ﺗﻜﻨﻮﻟﻮژي OleDBرا ﭘﺸﺘﻴﺒﺎﻧﻲ ﻧﻤﻲ ﻛﻨﻨﺪ اﻳﺠﺎد ﺷﺪه اﺳﺖ. ﻓﻀﺎي ﻧﺎﻣﻬﺎي OracleClient ،OleDb ،SqlClientو ﻧﻴﺰ Odbcدر ADO.NETﺑـﻪ ﻋﻨـﻮان ﺳـﺮوﻳﺲ دﻫﻨﺪه ﻫﺎي اﻃﻼﻋﺎﺗﻲ ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮﻧﺪ .در .NETﺳﺮوﻳﺲ دﻫﻨﺪه ﻫﺎي اﻃﻼﻋﺎﺗﻲ دﻳﮕﺮي ﻧﻴﺰ وﺟﻮد دارﻧﺪ ،اﻣﺎ در ﻃـﻲ اﻳـﻦ ﻛﺘـﺎب ﻓﻘﻂ ﺑﺮ روي دو ﺳﺮوﻳﺲ دﻫﻨﺪه ي اول ﺗﻤﺮﻛﺰ ﺧﻮاﻫﻴﻢ ﻛﺮد. در ﻃﻲ اﻳﻦ ﻓﺼﻞ ﺑﺎ اﺳﺘﻔﺎده از ﻓﻀﺎي ﻧﺎم SqlClientﺑﻪ ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ از ﻧﻮع SQL Serverدﺳﺘﺮﺳـﻲ ﺧـﻮاﻫﻴﻢ داﺷﺖ .اﻟﺒﺘﻪ ،در ADO.NETاﺳﺘﻔﺎده از دﻳﮕﺮ ﺳﺮوﻳﺲ دﻫﻨﺪه ﻫﺎي اﻃﻼﻋﺎﺗﻲ ﻧﻴﺰ ﺑﺴﻴﺎر ﻣﺸﺎﺑﻪ اﺳﺘﻔﺎده از اﻳﻦ ﺳﺮوﻳﺲ دﻫﻨﺪه اﺳـﺖ. ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻪ راﺣﺘﻲ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺗﻜﻨﻴﻚ ﻫﺎﻳﻲ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻓﻀﺎي ﻧﺎم ﺧﻮاﻫﻴﺪ آﻣﻮﺧﺖ در ﺳـﺮوﻳﺲ دﻫﻨـﺪه ﻫﺎي دﻳﮕﺮ ﻧﻴﺰ از ﻗﺒﻴﻞ OleDBاﺳﺘﻔﺎده ﻛﻨﻴﺪ و ﻳﺎ ﺗﻜﻨﻴﻜﻬﺎي ﺳﺮوﻳﺲ دﻫﻨﺪه ﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ OleDBرا در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴـﺰ ﺑـﻪ ﻛـﺎر ﺑﺒﺮﻳﺪ .در ADO.NETﺑﺮ اﺳﺎس ﻧﻮع ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻛﻪ داده ﻫﺎي ﺷﻤﺎ ﺑﻪ وﺳﻴﻠﻪ ي آن اﻳﺠـﺎد ﺷـﺪه اﻧـﺪ ،ﻳﻜـﻲ از ﺳـﺮوﻳﺲ دﻫﻨﺪه ﻫﺎي ﻣﻮﺟﻮد را اﻧﺘﺨﺎب ﻛﺮده و از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ .اﻣﺎ ﻻزم ﻧﻴﺴﺖ ﻛـﻪ ﻣﺠـﺪداً ﻧﺤـﻮه ي اﺳـﺘﻔﺎده از آن ﺳـﺮوﻳﺲ دﻫﻨـﺪه را ﻣﻄﺎﻟﻌﻪ ﻛﻨﻴﺪ زﻳﺮا ﺗﻤﺎﻣﻲ اﻳﻦ ﺳﺮوﻳﺲ دﻫﻨﺪه ﻫﺎ ﺑﺴﻴﺎر ﻣﺸﺎﺑﻪ ﻳﻜﺪﻳﮕﺮ ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ و اﮔﺮ ﻧﺤﻮه ي اﺳﺘﻔﺎده از ﻳﻜﻲ از آﻧﻬﺎ را ﺑﻴﺎﻣﻮزﻳﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ راﺣﺘﻲ از دﻳﮕﺮ ﺳﺮوﻳﺲ دﻫﻨﺪه ﻫﺎ ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در اﻳﻦ ﺳﺮوﻳﺲ دﻫﻨﺪه ﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﻪ ﺣﺪي زﻳﺎد ﻫﺴﺘﻨﺪ ﻛﻪ ﻧﻤﻲ ﺗﻮاﻧﻴﻢ ﺗﻤﺎم آﻧﻬﺎ را در اﻳﻦ ﻗﺴﻤﺖ ﻣﻌﺮﻓـﻲ ﻛﻨﻴﻢ .ﺑﺎ اﻳﻦ وﺟﻮد در اﻳﻦ ﻗﺴﻤﺖ اﺑﺘﺪا ﺑﺎ ﺗﻌﺪادي از ﻣﻬﻤﺘﺮﻳﻦ آﻧﻬﺎ ﻛﻪ در ﻃﻲ ﻣﺜﺎل ﻫﺎي اﻳﻦ ﻓﺼﻞ ﻧﻴﺰ ﺑﻪ ﻛﺎر رﻓﺘﻪ اﻧﺪ آﺷﻨﺎ ﻣﻲ ﺷـﻮﻳﻢ. اﻳﻦ ﻛﻼﺳﻬﺎ ﻋﺒﺎرﺗﻨﺪ از:
SqlConnection SqlCommand SqlDataAdapter SqlParameter
ﺑﻪ ﺧﺎﻃﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ اﻳﻦ ﻛﻼﺳﻬﺎ ﻓﻘﻂ ﺑﺮاي ارﺗﺒﺎط ﺑﺎ ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ SQL Serverﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ .ﺑﺮاي اﺳﺘﻔﺎده از ﺑﺎﻧﻚ ﻫﺎي اﻃﻼﻋﺎﺗﻲ OLEDBﻣﻲ ﺗﻮاﻧﻴﺪ از ﻛﻼﺳﻬﺎي ﻣﺘﻨﺎﻇﺮ اﻳﻨﻬﺎ در ﻓـﻀﺎي ﻧـﺎم System.Data.OleDb اﺳﺘﻔﺎده ﻛﻨﻴﺪ .در اﻳﻦ ﻓﻀﺎي ﻧﺎم ﻧﻴﺰ ﻫﻤﻴﻦ ﻛﻼﺳﻬﺎ وﺟﻮد دارﻧﺪ ﻛﻪ اﻟﺒﺘﻪ ﺑﺎ ﭘﻴﺸﻮﻧﺪ OleDbآﻏﺎز ﻣﻲ ﺷﻮﻧﺪ. ﻫﻤﭽﻨﻴﻦ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﺑﺮاي اﺳﺘﻔﺎده از اﻳـﻦ ﻛﻼﺳـﻬﺎ ﺑﺎﻳـﺪ ﻓـﻀﺎي ﻧـﺎم System.Data.SqlClientرا ﺑـﺎ اﺳﺘﻔﺎده از راﻫﻨﻤﺎي usingﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮد ﺗﺎ ﻻزم ﻧﺒﺎﺷﺪ ﻫﺮ ﺑﺎر ﻧﺎم ﻛﺎﻣﻞ آﻧﻬﺎ را وارد ﻛﻨﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻪ ﺧﺎﻃﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ در اﺑﺘﺪاي ﺑﺮﻧﺎﻣﻪ ﻫﺎي اﻳﻦ ﻗﺴﻤﺖ دﺳﺘﻮر زﻳﺮ را ﻧﻴﺰ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: ;using System.Data.SqlClient ﻫﻤﭽﻨــﻴﻦ ﺑــﺮاي اﺳــﺘﻔﺎده از ﻛﻼﺳــﻬﺎي ﭘﺎﻳــﻪ اي ADO.NETﻣﺎﻧﻨــﺪ DataSetو ﻳــﺎ DataViewﺑﺎﻳــﺪ ﻓــﻀﺎي ﻧــﺎم System.Dataرا ﻧﻴﺰ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ در اﺑﺘﺪاي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد دﺳﺘﻮر زﻳﺮ را ﻧﻴﺰ وارد ﻛﻨﻴﺪ. ;using System.Data
Open Database Connectivity
1
٦١٨
ﺧﻮب ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ اﺑﺘﺪا ﻧﮕﺎﻫﻲ ﺑﻪ ﻛﻼﺳﻬﺎي اﺻﻠﻲ ﻣﻮﺟﻮد در ﻓﻀﺎي ﻧﺎم SqlClientداﺷﺘﻪ ﺑﺎﺷﻴﻢ و ﻧﺤﻮه ي ﻛـﺎرﺑﺮد آﻧﻬـﺎ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ.
ﻛﻼس :SqlConnection ﺗﻘﺮﻳﺒﺎً ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ ﻛﻪ ﻛﻼس SqlConnectionدر ﻗﻠﺐ ﻛﻼس ﻫﺎﻳﻲ ﻗﺮار دارد ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻣﻮرد اﺳﺘﻔﺎده ﻗـﺮار ﻣﻲ دﻫﻴﻢ ،زﻳﺮا اﻳﻦ ﻛﻼس وﻇﻴﻔﻪ ي ﺑﺮﻗﺮاري ارﺗﺒﺎط ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ و ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را ﺑﺮ ﻋﻬﺪه دارد .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﻳﻚ ﻧﻤﻮﻧـﻪ از اﻳﻦ ﻛﻼس را اﻳﺠﺎد ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ ﭘﺎراﻣﺘﺮي را ﺑﻪ ﻧﺎم ConnectionStringﺑﻪ آن ارﺳﺎل ﻛﻨﻴﺪ .اﻳﻦ ﭘـﺎراﻣﺘﺮ ﻣﺘﻐﻴـﺮي از ﻧـﻮع رﺷﺘﻪ اي اﺳﺖ ﻛﻪ ﺷﺎﻣﻞ ﺗﻤﺎم داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﺑﺮﻗﺮاري اﺗﺼﺎل ﺑﻪ ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﻲ ﺷﻮد .اﻟﺒﺘﻪ ﺑﻌﺪ از اﻳﺠﺎد ﺷﻴﺊ اي از اﻳﻦ ﻛﻼس ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻢ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ConnectionStringدر اﻳﻦ ﻛﻼس ،ﻣﻘﺪار آن را ﺗﻐﻴﻴـﺮ داده و رﺷـﺘﻪ ي ﺟﺪﻳﺪي را ﺑﺮاي اﻳﻦ ﭘﺎراﻣﺘﺮ ﻣﺸﺨﺺ ﻛﻨﻴﻢ .در ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ در ﻓﺼﻞ ﻗﺒﻞ اﻳﺠﺎد ﻛﺮدﻳﻢ ،وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺎ اﺳﺘﻔﺎده از اﻃﻼﻋﺎﺗﻲ ﻛـﻪ در ﻛﺎدر Add Connectionدرﻳﺎﻓﺖ ﻣﻲ ﻛﺮد ،ﭼﻨﻴﻦ ﻣﺘﻨﻲ را اﻳﺠﺎد ﻛﺮده و در اﺧﺘﻴﺎر SqlConnectionﻗﺮار ﻣﻲ داد .اﻣﺎ اﻏﻠﺐ ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﻣﺘﻦ ﻻزم ﺑﺮاي ConnectionStringرا ﺧﻮدﻣﺎن ﺑﻨﻮﻳﺴﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر اﺑﺘﺪا ﺑﺎﻳﺪ ﺑﺪاﻧﻴﻢ ﻛـﻪ اﻳﻦ ﺳﺎﺧﺘﺎر اﻳﻦ ﻣﺘﻨﻬﺎ ﺑﺎﻳﺪ ﭼﮕﻮﻧﻪ ﺑﺎﺷﺪ.
اﻳﺠﺎد ﺑﺨﺸﻬﺎي ﻣﺨﺘﻠﻒ :ConnectionString ﺳﺎﺧﺘﺎر ﻣﺘﻨﻲ ﻛﻪ ﺑﺮاي ConnectionStringﺑﺎﻳﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد ﺑﺴﺘﮕﻲ ﺑﻪ ﺳﺮوﻳﺲ دﻫﻨـﺪه ي اﻃﻼﻋـﺎﺗﻲ دارد ﻛﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ دﻫﻴﻢ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﺑﺨﻮاﻫﻴﻢ از SQL Serverﺑﻪ ﻋﻨﻮان ﻣﻮﺗـﻮر ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ ﺑﺮﻧﺎﻣـﻪ ي ﺧـﻮد اﺳﺘﻔﺎده ﻛﻨﻴﻢ )ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻻزم اﺳﺖ ﻛﻪ از ﺳـﺮوﻳﺲ دﻫﻨـﺪه ي SqlClientدر ﺑﺮﻧﺎﻣـﻪ اﺳـﺘﻔﺎده ﻛﻨـﻴﻢ( ،ﺑﺎﻳـﺪ ﭘﺎراﻣﺘﺮﻫـﺎي Serverو . Databaseﻣﻘﺪار آﻧﻬﺎ را ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺟﺪول زﻳﺮ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﺳﺖ در اﻳﻦ ﻣﺘﻦ ﻣﺸﺨﺺ ﻛﻨﻴﻢ. ﭘﺎراﻣﺘﺮ
ﺗﻮﺿﻴﺢ
Server
ﻧﺎم ﺳﺮور ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻳﻦ ﭘﺎراﻣﺘﺮ ﻣﻌﻤﻮﻻ ﺣﺎوي ﻧـﺎم ﻛـﺎﻣﭙﻴﻮﺗﺮي اﺳـﺖ ﻛـﻪ ﻣﻮﺗـﻮر ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ SQL Serverدر آن ﻧـﺼﺐ ﺷـﺪه اﺳـﺖ .اﮔـﺮ SQL Serverﺑﺮ روي ﻫﻤﺎن ﻛﺎﻣﭙﻴﻮﺗﺮي ﻛﻪ ﺑﺮﻧﺎﻣﻪ را اﺟـﺮا ﻣـﻲ ﻛﻨـﺪ ﻧـﺼﺐ ﺷـﺪه اﺳـﺖ ،ﻣـﻲ ﺗﻮاﻧﻴـﺪ از ﻣﻘﺎدﻳﺮي ﻣﺎﻧﻨﺪ localو ﻳﺎ localhostﺑﺮاي اﻳﻦ ﭘﺎراﻣﺘﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻣـﺎ اﮔـﺮ از SQL Serverاي ﻛﻪ در ﻛﺎﻣﭙﻴﻮﺗﺮ دﻳﮕﺮي در ﺷﺒﻜﻪ ﻧﺼﺐ ﺷﺪه اﺳﺖ اﺳﺘﻔﺎده ﻣـﻲ ﻛﻨﻴـﺪ ،ﻻزم اﺳـﺖ ﻛـﻪ ﻣﻘﺪار اﻳﻦ ﭘﺎراﻣﺘﺮ را ﺑﺮاﺑﺮ ﺑﺎ ﻧﺎم آن ﻛﺎﻣﭙﻴﻮﺗﺮ در ﺷﺒﻜﻪ ﻗﺮار دﻫﻴﺪ .ﻫﻤﭽﻨﻴﻦ اﮔـﺮ در آن ﻛـﺎﻣﭙﻴﻮﺗﺮ ﺑـﻴﺶ از ﻳﻚ SQL Serverﻗﺮار داﺷﺘﻪ ﺑﺎﺷﺪ ،ﺑﺎﻳﺪ ﺑﻌﺪ از ﻧﺎم ﻛﺎﻣﭙﻴﻮﺗﺮ ﻳﻚ ﻋﻼﻣﺖ \ ﻗـﺮار داده و ﺳـﭙﺲ ﻧﺎم SQL Serverاي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار دﻫﻴﺪ را ذﻛﺮ ﻛﻨﻴﺪ.
Database
ﻧﺎم ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار دﻫﻴﺪ ،در اﻳﻦ ﭘﺎراﻣﺘﺮ ﻗﺮار ﻣﻲ ﮔﻴـﺮد )ﺑـﺮاي ﻣﺜـﺎل، ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ .(Pubs
٦١٩
ﺑﺮاي اﻳﺠﺎد اﻣﻨﻴﺖ در ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ اﻳﺠﺎد ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي ،SQL Serverﺑﺎﻳﺪ ﻫﻨﮕـﺎم دﺳﺘﺮﺳـﻲ ﺑـﻪ آﻧﻬـﺎ اﺑﺘـﺪا ﻫﻮﻳـﺖ اﺳﺘﻔﺎده ﻛﻨﻨﺪه ﺗﻮﺳﻂ SQL Serverﻣﺸﺨﺺ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﺗﻮﺳﻂ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ داده ﻫﺎي ﻣﻮﺟﻮد در ﻳﻚ ﺑﺎﻧـﻚ اﻃﻼﻋــﺎﺗﻲ دﺳﺘﺮﺳــﻲ داﺷــﺘﻪ ﺑﺎﺷــﻴﻢ ،ﺑﺎﻳــﺪ اﻃﻼﻋــﺎت ﻻزم ﺑــﺮاي اﻳــﻦ ﺗﻌﻴــﻴﻦ ﻫﻮﻳــﺖ را ﻫﻤــﺮاه ﺑــﺎ دﻳﮕــﺮ اﻃﻼﻋــﺎت در ﻣــﺘﻦ ConnectionStringﻣﺸﺨﺺ ﻛﻨﻴﻢ .اﻳﻦ ﺗﻌﻴﻴﻦ ﻫﻮﻳﺖ ﺑﻪ دو روش ﻣﻲ ﺗﻮاﻧﺪ ﺗﻮﺳﻂ SQL Serverاﻧﺠﺎم ﺷـﻮد. روش اول اﺳﺘﻔﺎده از ﻧﺎم ﻛﺎرﺑﺮي و ﻛﻠﻤﻪ ي ﻋﺒﻮر ﻻزم ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺖ ﻛﻪ در اﻳﻦ ﺻﻮرت ﺑﺎﻳﺪ اﻳﻦ دو ﭘﺎراﻣﺘﺮ را ﺑﻪ ﺻﻮرت ﻣﺴﺘﻘﻴﻢ در ﻣﺘﻦ ConnectionStringﻗﺮار دﻫﻴﻢ .روش دوم اﺳﺘﻔﺎده از اﻛﺎﻧﺖ ﻛﺎرﺑﺮي اي اﺳﺖ ﻛﻪ در وﻳﻨﺪوز از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ. ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از روش اول ﺗﻮﺳﻂ SQL Serverﺗﻌﻴﻴﻦ ﻫﻮﻳﺖ ﺷﻮﻳﻢ ،ﺑﺎﻳﺪ ﭘﺎراﻣﺘﺮﻫﺎي ﻧـﺎم ﻛـﺎرﺑﺮي و ﻛﻠﻤـﻪ ي ﻋﺒﻮر را ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺟﺪول زﻳﺮ ﺷﺮح داده ﺷﺪه اﺳﺖ ،در ﻣﺘﻦ ConnectionStringﻗﺮار دﻫﻴﻢ. ﭘﺎراﻣﺘﺮ
ﺗﻮﺿﻴﺢ
User ID
اﻳﻦ ﭘﺎراﻣﺘﺮ ﺑﺎﻳﺪ ﺣﺎوي ﻧﺎم ﻛﺎرﺑﺮي ﺑﺎﺷﺪ ﻛﻪ ﺑﺮاي اﺗﺼﺎل ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣـﻲ ﺧـﻮاﻫﻴﻢ از آن اﺳـﺘﻔﺎده ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ روش از ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ اﺳـﺘﻔﺎده ﻛﻨـﻴﻢ ،ﺑﺎﻳـﺪ ﻳـﻚ اﻛﺎﻧـﺖ ﻛﺎرﺑﺮي ﺑﻪ اﻳﻦ ﻧﺎم در SQL Serverاﻳﺠﺎد ﺷﺪه و اﺟﺎزه ي دﺳﺘﺮﺳﻲ ﺑﻪ داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﻧﻴـﺰ ﺑﻪ آن داده ﺷﻮد.
Password
ﻛﻠﻤﻪ ي ﻋﺒﻮري ﻛﻪ ﺑﺮاي اﻳﻦ ﻧﺎم ﻛﺎرﺑﺮي ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد.
ﻋﻼوه ﺑﺮ اﻳﻦ SQL Serverﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻨﻈﻴﻢ ﺷﻮد ﻛﻪ ﺑﺮاي ﺗﻌﻴﻴﻦ ﻫﻮﻳﺖ ﻛﺎرﺑﺮاﻧﻲ ﻛﻪ ﺑـﻪ آن دﺳﺘﺮﺳـﻲ ﭘﻴـﺪا ﻣـﻲ ﻛﻨﻨــﺪ ،از اﻛﺎﻧــﺖ وﻳﻨــﺪوزي ﻛــﻪ ﺑــﺎ آن وارد ﻛــﺎﻣﭙﻴﻮﺗﺮ ﺷــﺪه اﻧــﺪ اﺳــﺘﻔﺎده ﻛﻨــﺪ .در اﻳــﻦ ﺻــﻮرت دﻳﮕــﺮ ﻧﻴــﺎزي ﻧﻴــﺴﺖ ﻛــﻪ در ﻣــﺘﻦ ConnectionStringﻣﻘــﺎدﻳﺮ ﻧــﺎم ﻛــﺎرﺑﺮي و ﻛﻠﻤ ـﻪ ي ﻋﺒــﻮر را وارد ﻛﻨﻴــﺪ ،ﺑﻠﻜــﻪ ﻓﻘــﻂ ﺑﺎﻳــﺪ ﻣــﺸﺨﺺ ﻛﻨﻴــﺪ ﻛــﻪ از Integrated Securityاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ )اﻳﻦ ﺳﻴـﺴﺘﻢ ﺑـﻪ اﻳـﻦ ﻋﻠـﺖ Integrated Security ﻧﺎﻣﻴﺪه ﻣﻲ ﺷﻮد ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از آن وﻳﻨﺪوز و SQL Serverﺑﺎ ﻳﻜﺪﻳﮕﺮ ﺳﻌﻲ ﺧﻮاﻫﻨﺪ ﻛﻪ ﺑﻪ ﺣﺪاﻛﺜﺮ اﻣﻨﻴﺖ ﻣﻤﻜﻦ در اﻳﺠﺎد ﻳﻚ ارﺗﺒــﺎط دﺳﺘﺮﺳــﻲ ﭘﻴــﺪا ﻛﻨﻨــﺪ و دﻳﮕــﺮ ﻧﻴــﺎزي ﻧﺒﺎﺷــﺪ ﻛــﻪ ﻧــﺎم ﻛــﺎرﺑﺮي و ﻛﻠﻤــﻪ ي ﻋﺒــﻮر را ﺑــﻪ ﺻــﻮرت ﻣــﺴﺘﻘﻴﻢ در ﻣــﺘﻦ ConnectionStringﻗـــــﺮار دﻫـــــﻴﻢ( .ﺑـــــﺮاي اﺳـــــﺘﻔﺎده از اﻳـــــﻦ ﺳﻴـــــﺴﺘﻢ ﺑﺎﻳـــــﺪ ﻣﻘـــــﺪار ﭘـــــﺎراﻣﺘﺮ IntegratedSecurityرا در ﻣﺘﻦ ConnectionStringﺑﺮاﺑﺮ ﺑﺎ trueﻗﺮار دﻫﻴﺪ. اﻟﺒﺘﻪ ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ در اﻳﻦ روش ﻧﻴﺰ ﺑﺎﻳﺪ در ﻣﺤﻴﻂ SQL Serverﺑﻪ اﻛﺎﻧﺖ ﻛﺎرﺑﺮي اي ﻛﻪ ﺑﺮاي اﻳـﻦ ﻓـﺮد در وﻳﻨـﺪوز اﻳﺠﺎد ﺷﺪه اﺳﺖ ،اﺟﺎزه ي دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت ﻣﻮﺟﻮد داده ﺷﻮد ،در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻛﺎرﺑﺮ ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺘﺼﻞ ﺷﻮد. ﺑﺮاي اﻳﻨﻜﻪ ﺑﻬﺘﺮ ﻣﺘﻮﺟﻪ ﺷﻮﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﭘﺎراﻣﺘﺮﻫﺎي ﻻزم در ConnetionStringﺗﻨﻈﻴﻢ ﻣﻲ ﺷﻮﻧﺪ ،ﺑﻪ ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ ﻧﮕـﺎه ﻛﻨﻴﺪ .اﻳﻦ ﻛﺪ ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﺷﻴﺊ ﺟﺪﻳﺪ از ﻧﻮع SqlConnectionﺑﻪ ﻛﺎر ﻣﻲ رود. SqlConnection objConnection = new SqlConnection("Server=localhost;Database=Pubs;User" + ;)";" ID=sa;Password=csdotnet ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ اﻳﻦ ConnectionStringﺑﺮاي اﺳﺘﻔﺎده از ﻳﻚ SQL Serverﺑـﻪ ﻛـﺎر ﻣـﻲ رود. ﻣﻘﺪار localhostدر ﭘﺎراﻣﺘﺮ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﺳﺮور SQLﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ از آن اﺳﺘﻔﺎده ﻛﻨﻴﻢ در ﻛـﺎﻣﭙﻴﻮﺗﺮي ﻗـﺮار دارد ﻛﻪ ﺑﺮﻧﺎﻣﻪ در آن اﺟﺮا ﺷﺪه اﺳﺖ .ﻣﻘﺪار ﭘﺎراﻣﺘﺮ Databaseﻧﻴﺰ ﻧﺎم ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﻪ آن ﻣﺘﺼﻞ ﺷـﻮﻳﻢ را ﺗﻌﻴـﻴﻦ ﻣﻲ ﻛﻨﺪ ،در اﻳﻦ ﺟﺎ اﻳﻢ ConnectionStringﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ Pubsﺑﻪ ﻛﺎر ﻣـﻲ رود .در آﺧـﺮ ﻧﻴـﺰ
٦٢٠
ﻣﻘﺪار ﭘﺎراﻣﺘﺮ ﻫﺎي User IDو Passwordﻣﺸﺨﺺ ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﺑﺮاي ﺗﻌﻴﻴﻦ ﻧﺎم ﻛـﺎرﺑﺮي و ﻛﻠﻤـﻪ ي ﻋﺒـﻮر ﻻزم ﺑـﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ .دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﺑﺮاي ﺗﻌﻴﻴﻦ ﻣﻘﺪار ﻫﺮ ﭘﺎراﻣﺘﺮ از ﻋﻼﻣﺖ = و ﺑﺮاي ﺟﺪا ﻛﺮدن ﭘﺎراﻣﺘﺮﻫﺎي ﻣﺨﺘﻠﻒ از ﻳﻜﺪﻳﮕﺮ از ﻋﻼﻣﺖ ; اﺳﺘﻔﺎده ﺷﺪه اﺳﺖ.
ﻣﺘﺼﻞ ﺷﺪن و ﻗﻄﻊ ﻛﺮدن اﺗﺼﺎل ﺑﻪ ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ: ﺑﻌﺪ از اﻳﻦ ﻛﻪ ﺑﺎ اﻳﺠﺎد ConnectionStringﻧﺤﻮه ي ﺑﺮﻗﺮاري ارﺗﺒﺎط ﺑﺎ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را ﻣﺸﺨﺺ ﻛﺮدﻳﻢ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ﻫﺎي Openو Closeدر ﻛﻼس SqlConnectionﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺘﺼﻞ ﺷﺪه و ﻳﺎ اﺗﺼﺎل ﺧﻮد را ﻗﻄﻊ ﻛﻨﻴﻢ .ﻳﻚ ﻧﻤﻮﻧﻪ از اﻳﻦ ﻛﺎر در ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ ﻧﺸﺎن داده ﺷﺪه اﺳﺖ: // Open the database connection ;)(objConnection.Open // ... Use the connection ;)(objConnection.Close // Close the database connection اﻟﺒﺘﻪ ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺘﻬﺎي ﻓﺮاوان دﻳﮕﺮي در ﻛﻼس SqlConnectionوﺟﻮد دارﻧﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ در ﺑﺮﻧﺎﻣﻪ از آﻧﻬـﺎ اﺳـﺘﻔﺎده ﻛﻨﻴﻢ ،اﻣﺎ ﻣﻮاردي ﻛﻪ در اﻳﻦ ﺟﺎ ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﺷﺪﻳﻢ ،ﭘﺮ ﻛﺎرﺑﺮد ﺗﺮﻳﻦ آﻧﻬﺎ ﺑﻪ ﺷﻤﺎر ﻣﻲ روﻧﺪ و ﻓﻜﺮ ﻣﻲ ﻛﻨﻢ ﻛﻪ ﺑﺮاي ﺷﺮوع ﻓﻘﻂ آﺷﻨﺎﻳﻲ ﺑﺎ اﻳﻦ ﻣﻮارد ﻛﺎﻓﻲ ﺑﺎﺷﺪ.
ﻛﻼس :SqlCommand ﻛﻼس SqlCommandﺣﺎوي ﻳﻚ دﺳﺘﻮر SQLﺑﺮاي اﺟﺮا روي داده ﻫﺎي درﻳﺎﻓﺖ ﺷﺪه از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳـﺖ .اﻳـﻦ دﺳـﺘﻮر ﻣﻲ ﺗﻮاﻧﺪ ﻳﻚ دﺳﺘﻮر SELECTﺑﺮاي اﻧﺘﺨﺎب داده ﻫﺎﻳﻲ ﺧﺎص ،ﻳـﻚ دﺳـﺘﻮر INSERTﺑـﺮاي درج داده ﻫـﺎي ﺟﺪﻳـﺪ در ﺑﺎﻧـﻚ اﻃﻼﻋﺎﺗﻲ ،ﻳﻚ دﺳﺘﻮر DELETEﺑﺮاي ﺣﺬف داده ﻫﺎ از ﺑﺎﻧﻚ اﻃﻼﻋﺎت و ﻳﺎ ﺣﺘﻲ ﻓﺮاﺧﻮاﻧﻲ ﻳـﻚ ﭘﺮوﺳـﻴﺠﺮ ذﺧﻴـﺮه ﺷـﺪه در ﺑﺎﻧـﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺎﺷﺪ .دﺳﺘﻮر SQLاي ﻛﻪ در اﻳﻦ ﻛﻼس ﻧﮕﻪ داري ﻣﻲ ﺷﻮد ﻣﻲ ﺗﻮاﻧﺪ ﺷﺎﻣﻞ ﭘﺎراﻣﺘﺮ ﻫﺎ ﻧﻴﺰ ﺑﺎﺷﺪ. از ﻣﺘﺪ ﺳﺎزﻧﺪه ي ﻛﻼس SqlCommandﭼﻨﺪﻳﻦ ﻧﺴﺨﻪ ﺳﺮﺑﺎر ﮔﺬاري ﺷﺪه اﺳﺖ ،اﻣﺎ ﺳﺎده ﺗﺮﻳﻦ آﻧﻬﺎ ﺑﺮاي اﻳﺠـﺎد ﻳـﻚ ﺷـﻴﺊ از ﻛﻼس SqlCommandﻫﻴﭻ ﭘﺎراﻣﺘﺮي را درﻳﺎﻓﺖ ﻧﻤﻲ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻌﺪ از اﻳﺠﺎد ﺷﻴﺊ ،ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ﻫـﺎ و ﻳـﺎ ﻣﺘﺪﻫﺎي ﻣﻮﺟﻮد ،آن ﺷﻴﺊ را ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ .ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ ﻧﺤﻮه ي اﻳﺠﺎد ﻳﻚ ﺷﻴﺊ از ﻧﻮع SqlCommandرا ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ: ;)(SqlCommand objCommand = new SqlCommand در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﻌﻤﻮﻻ از اﺷﻴﺎي اﻳﺠﺎد ﺷﺪه از ﻛﻼس SqlCommandﺑﻪ ﺗﻨﻬﺎﻳﻲ اﺳﺘﻔﺎده ﻧﻤﻲ ﻛﻨﻨﺪ ،ﺑﻠﻜﻪ آﻧﻬﺎ را ﻫﻤﺮاه ﺑﺎ DataSetﻫﺎ و DataAdapterﻫﺎ ﺑـﻪ ﻛـﺎر ﻣـﻲ ﺑﺮﻧـﺪ .ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﻣـﻲ ﺗﻮاﻧﻨـﺪ از دﺳـﺘﻮر ،SELECT INSERTو ﻳﺎ … ﻛﻪ در آن ﻧﮕﻬﺪاري ﻣﻲ ﺷﻮد ﺑﺮاي ﻣﻘﺎﺻﺪ ﻣﻮرد ﻧﻴﺎز اﺳﺘﻔﺎده ﻛﻨﻨﺪ .ﻫﻤﭽﻨـﻴﻦ اﺷـﻴﺎي SqlCommandﻣـﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ ﻫﻤﺮاه اﺷﻴﺎي اﻳﺠﺎد ﺷﺪه از ﻛﻼس DataReaderﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮﻧﺪ .ﻛـﻼس DataReaderﻛـﺎرﺑﺮدي
٦٢١
ﻫﻤﺎﻧﻨﺪ DataSetدارد ،اﻣﺎ ﻣﻨﺎﺑﻊ ﺳﻴﺴﺘﻢ )ﻣﺎﻧﻨﺪ ﺣﺎﻓﻈﻪ و …( را ﻛﻤﺘﺮ ﻣﺼﺮف ﻣﻲ ﻛﻨﺪ و ﻧﻴﺰ اﻧﻌﻄﺎف ﭘـﺬﻳﺮي ﻛﻤﺘـﺮي ﻧﻴـﺰ دارد .در اداﻣﻪ ي اﻳﻦ ﻓﺼﻞ ﺑﻴﺸﺘﺮ ﺗﻤﺮﻛﺰ ﺧﻮد را روي ﻧﺤﻮه ي اﺳﺘﻔﺎده از اﻳﻦ اﺷﻴﺎ ﺑﺎ ﻛﻼس DataSetﻗﺮار ﺧﻮاﻫﻴﻢ داد.
ﺧﺎﺻﻴﺖ :Connection ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻲ از ﻳﻚ ﺷﻴﺊ از ﻛﻼس SqlCommandاﺳﺘﻔﺎده ﻛﻨﻴﻢ ﺑﺎﻳﺪ ﺑﻌﻀﻲ از ﺧﺎﺻﻴﺖ ﻫﺎي آن را ﺗﻨﻈﻴﻢ ﻛﻨـﻴﻢ .اوﻟـﻴﻦ ﺧﺎﺻﻴﺘﻲ ﻛﻪ ﺑﺎﻳﺪ ﺗﻨﻈﻴﻢ ﺷﻮد ،ﺧﺎﺻﻴﺖ Connectionاﺳﺖ .اﻳﻦ ﺧﺎﺻﻴﺖ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﺳـﺖ، ﻣﻲ ﺗﻮاﻧﺪ ﻳﻚ ﻣﻘﺪار از ﻧﻮع SqlConnectionرا درﻳﺎﻓﺖ ﻛﻨﺪ: ;objCommand.Connection = objConnection ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ دﺳﺘﻮر SQLاي ﻛﻪ در اﻳﻦ ﺷﻴﺊ ﻧﮕﻬﺪاري ﻣﻲ ﺷﻮد را ﺑﺎ ﻣﻮﻓﻘﻴﺖ اﺟﺮا ﻛﺮده و ﻧﺘﻴﺠﻪ ي آن را درﻳﺎﻓﺖ ﻛﻨـﻴﻢ ،ﺑﺎﻳـﺪ اﺑﺘﺪا ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ Openدر SqlConnectionاﺗﺼﺎل ﺑﺎ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را ﺑﺮﻗﺮار ﻛﺮده و ﺳﭙﺲ دﺳﺘﻮر را اﺟﺮا ﻛﻨﻴﻢ.
ﺧﺎﺻﻴﺖ :CommandText ﺧﺎﺻﻴﺖ ﺑﻌﺪي ﻛﻪ ﺑﺎﻳﺪ ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ ،ﺧﺎﺻﻴﺖ CommandTextاﺳﺖ .اﻳﻦ ﺧﺎﺻﻴﺖ ﻣﺘﻨﻲ را درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺣﺎوي ﻳﻚ دﺳﺘﻮر SQLو ﻳﺎ ﻓﺮاﺧﻮاﻧﻲ ﻳﻚ ﭘﺮوﺳﻴﺠﺮ ذﺧﻴﺮه ﺷﺪه در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺎﺷﺪ ﻛﻪ ﺑﺎﻳﺪ روي داده ﻫﺎ اﺟﺮا ﺷﻮد .ﺑﺮاي ﻣﺜـﺎل ﻗﻄﻌـﻪ ﻛﺪ زﻳﺮ ﻳﻚ ﻧﻤﻮﻧﻪ از دﺳﺘﻮر SQLﻛﻪ در اﻳﻦ ﺧﺎﺻﻴﺖ ﻗﺮار داده ﺷﺪه اﺳﺖ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ: SqlConnection objConnection = new SqlConnection("Server=localhost;Database=Pubs;User " + ;)";"ID=sa;Password=csdotnet ;)(SqlCommand objCommand = new SqlCommand ;objCommand.Connection = objConnection objCommand.CommandText = "INSERT INTO authors " + "(au_id, au_lname, au_fname, contract) " + ;")"VALUES('123-45-6789', 'Barnes', 'David', 1 دﺳﺘﻮر INSERTﻳﻜﻲ از دﺳﺘﻮرات ﺳﺎده ي SQLاﺳﺖ ﻛﻪ ﺑﺮاي درج ﻳﻚ رﻛﻮرد از اﻃﻼﻋﺎت در ﻳﻚ ﺟﺪول ﺑﻪ ﻛﺎر ﻣـﻲ رود .اﻳـﻦ دﺳﺘﻮر در اﻳﻦ ﻗﺴﻤﺖ ﺑﻴﺎن ﻣﻲ ﻛﻨﺪ ﻛﻪ "ﻳﻚ رﻛﻮرد ﺟﺪﻳﺪ از اﻃﻼﻋﺎت در ﺟﺪول authorsاﻳﺠﺎد ﻛﻦ .ﺳﭙﺲ ﻓﻴﻠﺪ au_idدر اﻳﻦ رﻛﻮرد را ﺑﺮاﺑﺮ ﺑﺎ ’ ‘123-45-6789ﻗـﺮار ﺑـﺪه ،ﻓﻴﻠـﺪ au_lnameرا ﺑﺮاﺑـﺮ ﺑـﺎ ’ ‘Barnesﻗـﺮار ﺑـﺪه ،ﻓﻴﻠـﺪ au_fnameرا ﺑﺮاﺑﺮ ﺑﺎ ’ ‘Davidﻗﺮار ﺑﺪه و ﻓﻴﻠﺪ contractرا ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎ 1ﻗﺮار ﺑﺪه". روش اﺳﺘﻔﺎده از دﺳﺘﻮر INSERTﺑﺮاي درج ﻳﻚ ردﻳﻒ از اﻃﻼﻋـﺎت در ﻳـﻚ ﺟـﺪول ﺑـﻪ اﻳـﻦ ﺻـﻮرت اﺳـﺖ ﻛـﻪ ﺑﻌـﺪ از دﺳـﺘﻮر INSERT INTOﻧﺎم ﺟﺪوﻟﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ اﻃﻼﻋﺎت در آن ﻗﺮار ﺑﮕﻴﺮد را ذﻛﺮ ﻣﻲ ﻛﻨﻴﻢ .ﺳﭙﺲ ﻧﺎم ﻓﻴﻠﺪ ﻫﺎﻳﻲ را ﻛﻪ ﺑﺎﻳﺪ ﻛﺎﻣﻞ ﻛﻨﻴﻢ را در داﺧﻞ ﻳﻚ ﭘﺮاﻧﺘﺰ ﻣﻲ آورﻳﻢ و ﻫﺮ ﻳﻚ را ﻧﻴﺰ ﺑﺎ ﻳﻚ وﻳﺮﮔﻮل از ﻫﻢ ﺟﺪا ﻣﻲ ﻛﻨﻴﻢ .ﺳـﭙﺲ ﻋﺒـﺎرت VALUESﻧﻮﺷـﺘﻪ و در ﻳﻚ ﭘﺮاﻧﺘﺰ دﻳﮕﺮ ،ﻣﻘﺪار ﻣﻮرد ﻧﻈﺮ ﺑﺮاي آن ﻓﻴﻠﺪ ﻫﺎ را ﺑﻪ ﺗﺮﺗﻴﺐ وارد ﻣﻲ ﻛﻨﻴﻢ.
٦٢٢
در اﻳﻨﺠﺎ ﻓﺮض ﻛﺮدﻳﻢ ﻛﻪ ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ،ﻣﻘﺪاري ﻛﻪ ﺑﺎﻳﺪ در ﻫﺮ ﻳﻚ از ﻓﻴﻠﺪ ﻫﺎ ﻗﺮار ﮔﻴﺮد ﻣﺸﺨﺺ اﺳﺖ .اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛـﻪ ﻣـﻲ داﻧﻴﺪ در اﻏﻠﺐ ﻣﻮارد ﭼﻨﻴﻦ ﺷﺮاﻳﻄﻲ رخ ﻧﻤﻲ دﻫﺪ و ﻣﻘﺪار ﻫﺮ ﻳﻚ از اﻳﻦ ﻓﻴﻠﺪ ﻫﺎ در ﻃﻮل اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺗﻮﺳﻂ ﻛﺎرﺑﺮ ﺗﻌﻴﻴﻦ ﻣـﻲ ﺷـﻮﻧﺪ. ﺧﻮﺷﺒﺨﺘﺎﻧﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ دﺳﺘﻮرات SQLرا ﺑﻪ ﮔﻮﻧﻪ اي اﻳﺠﺎد ﻛﻨﻴﻢ ﻛﻪ ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﻣﺘﺪ ،ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻛﻨﻨﺪ .ﺳﭙﺲ ﻫﻨﮕﺎم اﺟﺮاي ﺑﺮﻧﺎﻣﻪ اﻳﻦ ﭘﺎراﻣﺘﺮ ﻫﺎ را از ﻛﺎرﺑﺮ درﻳﺎﻓﺖ ﻛﺮده و آﻧﻬﺎ را در دﺳﺘﻮر ﻗﺮار ﻣﻲ دﻫـﻴﻢ و دﺳـﺘﻮر را اﺟـﺮا ﻣـﻲ ﻛﻨـﻴﻢ .ﺑﻬﺘـﺮ اﺳـﺖ ﻣﻘـﺪاري ﻫـﻢ ﺑـﺎ ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ در ﺷﻴﺊ SqlCommandﻗﺮار ﮔﻴﺮﻧﺪ آﺷﻨﺎ ﺷﻮﻳﻢ.
ﺧﺎﺻﻴﺖ :Parameters ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﻧﺤﻮه ي اﺳﺘﻔﺎده از ﭘﺎراﻣﺘﺮ ﻫﺎ در ﻳﻚ دﺳﺘﻮر SQLرا ﻣﺸﺎﻫﺪه ﻛﻨﻴﻢ ،ﺑﺎﻳﺪ ﺑﺎ ﻣﻔﻬـﻮم Placeholderﻫـﺎ آﺷﻨﺎ ﺷﻮﻳﻢ Placeholder .ﻫﺎ ﻣﺘﻐﻴﺮﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ در ﻳﻚ دﺳﺘﻮر SQLﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ و ﻣﻲ ﺗﻮاﻧﻨﺪ در زﻣﺎن اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺟﺎي ﺧﻮد را ﻋﺒﺎرﺗﻲ ﺧﺎص ﻋﻮض ﻛﻨﻨﺪ .اﻳﻦ ﻣﺘﻐﻴﺮ ﻫﺎ ﺑﺎ ﻋﻼﻣﺖ @ در ﻳﻚ دﺳﺘﻮر ﻣﺸﺨﺺ ﻣﻲ ﺷﻮﻧﺪ و ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ از آﻧﻬـﺎ در ﻳـﻚ دﺳﺘﻮر SQLاﺳﺘﻔﺎده ﻛﻨﻴﻢ ،ﻗﺒﻞ از اﺟﺮاي دﺳﺘﻮر ﺑﺎﻳﺪ ﺗﻤﺎﻣﻲ آﻧﻬﺎ را ﺑﺎ ﻣﻘﺎدﻳﺮ ﻣﻨﺎﺳﺐ ﺗﻌﻮﻳﺾ ﻛﻨﻴﻢ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﺑﺨﻮاﻫﻴﻢ در دﺳـﺘﻮر ﻗﺒﻞ ﻣﻘﺎدﻳﺮ ﻻزم ﺑﺮاي ﻗﺴﻤﺖ VALUESاز دﺳﺘﻮر INSERTرا در زﻣﺎن اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ،ﺑﺎﻳﺪ ﺟﺎي آﻧﻬﺎ را ﺑﺎ ﭼﻬـﺎر Placeholderﺑﻪ ﺻﻮرت زﻳﺮ ﻋﻮض ﻛﻨﻴﻢ: SqlConnection objConnection = new SqlConnection("Server=localhost;Database=Pubs;User " + ;)";"ID=sa;Password=csdotnet ;)(SqlCommand objCommand = new SqlCommand ;objCommand.Connection = objConnection objCommand.CommandText = "INSERT INTO authors " + "(au_id, au_lname, au_fname, contract) " + ;")"VALUES(@au_id, @au_lname, @au_fname, @au_contract ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ در اﻳﻨﺠﺎ ﺑﻪ ﺟﺎي اﻳﻨﻜﻪ از ﭼﻨﺪ ﻣﻘﺪار ﺛﺎﺑـﺖ در دﺳـﺘﻮر اﺳـﺘﻔﺎده ﻛﻨـﻴﻢ ،از ﭼﻨـﺪ placeholder اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ .ﻫﻤﭽﻨﻴﻦ ﺗﻤﺎم placeholderﻫﺎ در دﺳﺘﻮر ﺑﺎ اﺳﺘﻔﺎده از @ ﻣﺸﺨﺺ ﺷﺪه اﻧﺪ .اﻟﺒﺘﻪ ﻫﻴﭻ ﺿﺮورﺗﻲ ﻧﺪارد ﻛﻪ ﻧﺎم ﻳﻚ placeholderﻫﻤﻨﺎم ﺑﺎ ﻓﻴﻠﺪي ﺑﺎﺷﺪ ﻛﻪ ﻗﺮار اﺳﺖ ﻣﻘﺪار placeholderدر آن ﻗﺮار ﺑﮕﻴـﺮد .اﻣـﺎ اﻳـﻦ ﻛـﺎر ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺧﻮاﻧﺎﺗﺮ ﺷﺪه و درك آن ﺳﺎده ﺗﺮ ﺷﻮد. ﺧــﻮب ،ﺑﻌــﺪ از اﻳﻨﻜــﻪ ﺑــﺎ اﺳــﺘﻔﺎده از اﻳــﻦ روش ﭘﺎراﻣﺘﺮﻫــﺎﻳﻲ را در دﺳــﺘﻮر اﻳﺠــﺎد ﻛــﺮدﻳﻢ ،ﺑﺎﻳــﺪ ﻗﺒــﻞ از اﺟــﺮاي دﺳــﺘﻮر SQLاﻳــﻦ placeholderﻫﺎ را ﺑﺎ ﻣﻘﺎدﻳﺮ ﻣﻨﺎﺳﺐ ﺗﻌﻮﻳﺾ ﻛﻨﻴﻢ .اﻳﻦ ﻛﺎر ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ در زﻣﺎن اﺟﺮاي دﺳﺘﻮر اﻧﺠـﺎم ﻣــﻲ ﺷــﻮد .اﻣــﺎ اﺑﺘــﺪا ﺑﺎﻳــﺪ ﭘﺎراﻣﺘﺮﻫــﺎﻳﻲ را اﻳﺠ ـﺎد ﻛــﺮده و آن را در ﻟﻴــﺴﺖ Parametersدر ﺷــﻴﺊ اﻳﺠــﺎد ﺷــﺪه از ﻛــﻼس SqlCommandﻗﺮار دﻫﻴﻢ ﺗﺎ ﺑﺮﻧﺎﻣﻪ ﺑﺪاﻧﺪ ﻫﻨﮕﺎم اﺟﺮاي دﺳﺘﻮر ﻫـﺮ placeholderرا ﺑﺎﻳـﺪ ﺑـﺎ ﻣﻘـﺪار ﭼـﻪ ﻣﺘﻐﻴـﺮي در ﺑﺮﻧﺎﻣﻪ ﻋﻮض ﻛﻨﺪ .ﺗﻮﺟﻪ ﻛﻨﻴﺪ ه اﺻﻄﻼح ﭘﺎراﻣﺘﺮ در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ اﺷﺎره ﻣﻲ ﻛﻨﺪ ﻛﻪ ﺑﺮاي اﺟﺮاي ﻳﻚ دﺳـﺘﻮر SQLو ﻳـﺎ ﻳﻚ ﭘﺮوﺳﻴﺠﺮ ذﺧﻴﺮه ﺷﺪه در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻻزم اﺳﺖ ،ﻧﻪ ﺑﻪ ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ ﻛﻪ در وﻳﮋوال C#ﺑﻪ ﻣﺘﺪ ﻫﺎ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد. ﺑــﺮاي دﺳﺘﺮﺳــﻲ ﺑــﻪ ﻟﻴــﺴﺖ ﭘﺎراﻣﺘﺮﻫــﺎﻳﻲ ﻛــﻪ در ﻳــﻚ ﺷــﻴﺊ از ﻛــﻼس SqlCommandوﺟــﻮد دارد ﻣــﻲ ﺗــﻮاﻧﻴﻢ از ﺧﺎﺻــﻴﺖ Parametersدر اﻳﻦ ﻛﻼس اﺳﺘﻔﺎده ﻛﻨﻴﻢ.اﻳﻦ ﺧﺎﺻﻴﺖ ﺣﺎوي ﻟﻴـﺴﺘﻲ از placeholderﻫـﺎ ﺑـﻪ ﻫﻤـﺮاه ﻣﺘﻐﻴﺮﻫـﺎي واﺑــﺴﺘﻪ ﺑــﻪ آﻧﻬــﺎ اﺳــﺖ .ﺑﻨــﺎﺑﺮاﻳﻦ در ﺑﺮﻧﺎﻣــﻪ ﻗﺒــﻞ از اﺟــﺮاي دﺳــﺘﻮر ،ﺑﺎﻳــﺪ ﺑــﻪ وﺳــﻴﻠﻪ ي اﻳــﻦ ﻟﻴــﺴﺖ ﻣــﺸﺨﺺ ﻛﻨــﻴﻢ ﻛــﻪ ﻫــﺮ placeholderﺑﺎ ﻣﻘﺪار ﭼﻪ ﻣﺘﻐﻴﺮي ﺑﺎﻳﺪ ﺗﻌﻮﻳﺾ ﺷﻮد .ﺳﺎده ﺗﺮﻳﻦ روش اﻧﺠﺎم اﻳﻦ ﻛﺎر در ﻛﺪ زﻳﺮ ﻧﺸﺎن داده ﺷﺪه اﺳﺖ.
٦٢٣
SqlConnection objConnection = new SqlConnection("Server=localhost;Database=Pubs;User ;)";ID=sa;Password=csdotnet ;)(SqlCommand objCommand = new SqlCommand ;objCommand.Connection = objConnection objCommand.CommandText = "INSERT INTO authors " + "(au_id, au_lname, au_fname, contract) " + ;")"VALUES(@au_id, @au_lname, @au_fname, @au_contract objCommand.Parameters.AddWithValue("@au_id", ;)txtAuId.Text objCommand.Parameters.AddWithValue("@au_lname", ;)txtLastName.Text objCommand.Parameters.AddWithValue("@au_fname", ;)txtFirstName.Text objCommand.Parameters.AddWithValue("@au_contract", ;)chkContract.Checked ﻣﺘﺪ AddWithValueﻧﺎم ﻳﻚ placeholderو ﻣﺘﻐﻴﺮي ﻛﻪ ﻣﻘﺪار ﻣﺮﺑﻮط ﺑﻪ آن را در زﻣﺎن اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻛﺮده و آن را ﺑﻪ ﻟﻴﺴﺖ Parametersاﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل در اﻳﻦ ﻗﺴﻤﺖ ﻣﺸﺨﺺ ﻛﺮده اﻳﻢ ﻛﻪ ﻫﻨﮕﺎم اﺟﺮاي دﺳـﺘﻮر ،ﻣﻜـﺎن placeholderﺑـﺎ ﻧـﺎم @au_idﺑﺎﻳـﺪ ﺑـﺎ ﻣﻘـﺪار ﺧﺎﺻـﻴﺖ Textﻛﻨﺘـﺮل txtAuIdﻋﻮض ﺷﻮد .ﻫﻤﭽﻨﻴﻦ ﻣﻜﺎن placeholderﺑﺎ ﻧﺎم @au_lnameﻧﻴﺰ ﺑﺎﻳﺪ ﺑﺎ ﻣﻘـﺪار ﺧﺎﺻـﻴﺖ Text ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل txtLastNameﻋﻮض ﺷﻮد و ….
ﻣﺘﺪ :ExecuteNonQuery ﺑﻌﺪ از اﻧﺠﺎم ﺗﻤﺎم اﻳﻦ ﻣﺮاﺣﻞ ﻣﻲ ﺗﻮاﻧﻴﺪ دﺳﺘﻮر ﻣﻮﺟﻮد در اﻳﻦ ﺷﻴﺊ را روي داده ﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺟﺮا ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر اﺑﺘﺪا ﺑﺎﻳﺪ اﺗﺼﺎل ﺧﻮد را ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺮ ﻗﺮار ﻛﻨﻴـﺪ .ﺳـﭙﺲ ﺑـﺎ ﻓﺮاﺧـﻮاﻧﻲ ﻣﺘـﺪ ExecuteNonQueryدﺳـﺘﻮر ﻣﻮﺟـﻮد در ﺷـﻴﺊ SqlCommandرا اﺟﺮا ﻛﻨﻴﺪ .اﻟﺒﺘﻪ اﻳﻦ ﻣﺘﺪ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻧﺎم آن ﻧﻴﺰ ﻣﺸﺨﺺ ﻣـﻲ ﻛﻨـﺪ ﻓﻘـﻂ زﻣـﺎﻧﻲ ﻛـﺎرﺑﺮد دارد ﻛـﻪ ﺑﺨـﻮاﻫﻴﻢ دﺳﺘﻮري را روي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺟﺮا ﻛﻨﻴﻢ ﻛﻪ داده اي را ﺑﺮﻧﻤﻲ ﮔﺮداﻧﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ دﺳﺘﻮر ﻣﻮﺟﻮد در ﺷـﻴﺊ SqlCommand ﻳﻚ دﺳﺘﻮر SELECTﺑﺎﺷﺪ ﻛﻪ اﻃﻼﻋﺎﺗﻲ را از ﺟﺪاول اﺳﺘﺨﺮاج ﻛﺮده و آﻧﻬﺎ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻣﻲ دﻫﺪ ،ﻧﻤﻲ ﺗﻮاﻧﻴﻢ ﺑﺮاي اﺟﺮاي آن از اﻳﻦ ﻣﺘﺪ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻣﺎ اﮔﺮ دﺳﺘﻮر ﻣﻮرد اﺳﺘﻔﺎده ﻓﻘﻂ ﺗﻐﻴﻴﺮاﺗﻲ را در داده ﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﻳﺠﺎد ﻛﻨﺪ )ﺑﺮاي ﻣﺜﺎل ،ﻣﺎﻧﻨـﺪ اﻳﻨﺠـﺎ ﻳـﻚ رﻛﻮرد از اﻃﻼﻋﺎت را ﺑﻪ ﺟﺪول اﺿﺎﻓﻪ ﻛﻨﺪ(ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ آن ﻣﺘﺪ دﺳﺘﻮر را در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺟﺮا ﻛﻨﻴﻢ. اﻳﻦ ﻣﺘﺪ ﺑﻌﺪ از اﺟﺮا ﻋﺪدي را ﺑﻪ ﻋﻨﻮان ﺧﺮوﺟﻲ ﺑﺮﻣﻲ ﮔﺮداﻧﺪ ﻛﻪ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ي ﺗﻌﺪاد رﻛﻮرد ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﺑﺎ اﺟـﺮاي اﻳـﻦ دﺳـﺘﻮر SQLﺗﻐﻴﻴﺮ ﻛﺮده اﻧﺪ .اﻳﻦ ﻋﺪد ﻣﻌﻤﻮﻻ ﺑﺮاي ﺑﺮرﺳﻲ ﺻﺤﺖ اﺟﺮاي دﺳﺘﻮر ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد .ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ ﻧﺤـﻮه ي اﺳـﺘﻔﺎده از دﺳﺘﻮر ExecuteNonQueryرا در ﺑﺮﻧﺎﻣﻪ ﻧﺸﺎن ﻣﻲ دﻫﺪ. SqlConnection objConnection = new SqlConnection("Server=localhost;Database=Pubs;User ;)";ID=sa;Password=csdotnet ;)(SqlCommand objCommand = new SqlCommand ;objCommand.Connection = objConnection
٦٢٤
objCommand.CommandText = "INSERT INTO authors " + "(au_id, au_lname, au_fname, contract) " + ;")"VALUES(@au_id, @au_lname, @au_fname, @au_contract objCommand.Parameters.AddWithValue("@au_id", ;)txtAuId.Text objCommand.Parameters.AddWithValue("@au_lname", ;)txtLastName.Text objCommand.Parameters.AddWithValue("@au_fname", ;)txtFirstName.Text objCommand.Parameters.AddWithValue("@au_contract", ;)chkContract.Checked ;)(objConnection.Open ;)(objCommand.ExecuteNonQuery ;)(objConnection.Close
ﻛﻼس :SqlDataAdapter ﻛﻼس DataAdapterدر ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ،ﻫﻤﺎﻧﻨﺪ ﭘﻠﻲ ﺑﻴﻦ ﺟﺪاول ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ و ﻧﻴـﺰ داده ﻫـﺎي ﻣﻮﺟـﻮد در ﺣﺎﻓﻈﻪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي DataSetﻧﮕﻬﺪاري ﻣﻲ ﺷﻮﻧﺪ ،ﻋﻤﻞ ﻣﻲ ﻛﻨﻨﺪ .اﻳﻦ ﻛﻼس ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑـﻪ ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ از ﺷـﻴﺊ اﻳﺠﺎد ﺷﺪه از ﻛﻼس SqlCommandاي ﻛﻪ ﺑﻪ آن ﻧﺴﺒﺖ داده ﻣﻲ ﺷﻮد اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ و ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴـﺪ ،ﻫـﺮ ﺷـﻴﺊ از ﻛﻼس SqlCommandﺣﺎوي ﺷﻴﺊ اي از ﻛﻼس SqlConnectionاﺳﺖ ﻛﻪ ارﺗﺒﺎط آن را ﺑﺎ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺮﻗـﺮار ﻣــﻲ ﻛﻨــﺪ .ﺑﻨــﺎﺑﺮاﻳﻦ ﻣــﻲ ﺗــﻮاﻧﻴﻢ ﺑﮕــﻮﻳﻴﻢ ﻛــﻪ ﻛــﻼس DataAdapterﺑــﺮاي دﺳﺘﺮﺳــﻲ ﺑــﻪ ﺑﺎﻧــﻚ اﻃﻼﻋــﺎﺗﻲ از ﻛــﻼس SqlCommandو SqlConnectionاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ. ﻛﻼس DataAdapterداراي ﺧﺎﺻﻴﺘﻲ ﺑﻪ ﻧـﺎم SelectCommandاﺳـﺖ .اﻳـﻦ ﺧﺎﺻـﻴﺖ ﺣـﺎوي ﺷـﻴﺊ اي از ﻧـﻮع SqlCommandاﺳﺖ ﻛﻪ از دﺳﺘﻮر ﻣﻮﺟﻮد در آن ﺷﻴﺊ ،ﺑﺮاي درﻳﺎﻓﺖ داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز در ﺑﺮﻧﺎﻣﻪ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﻪ ﻛﺎر ﻣﻲ رود .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ DataAdapterدﺳﺘﻮري ﻛﻪ در اﻳﻦ ﺧﺎﺻﻴﺖ ﻧﮕﻬﺪاري ﻣﻲ ﺷﻮد را روي ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ اﺟـﺮا ﻛـﺮده و ﻧﺘﺎﻳﺞ آن را در ﻛﻼس ﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ DataSetو ﻳﺎ DataTableﻗﺮار ﻣﻲ دﻫﺪ ﺗﺎ در ﺑﺮﻧﺎﻣﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮﻧﺪ .ﻋـﻼوه ﺑﺮ اﻳﻦ ﻛﻼس DataAdapterداراي ﺧﺎﺻـﻴﺖ ﻫـﺎﻳﻲ ﺑـﻪ ﻧـﺎم InsertCommand ،DeleteCommandو UpdateCommandاﺳﺖ ﻛﻪ ﻫﺮ ﻳﻚ ﺷﻴﺊ اي از ﻧﻮع SqlCommandرا ﻗﺒﻮل ﻣﻲ ﻛﻨﻨﺪ و DataAdapterاز دﺳﺘﻮر ذﺧﻴﺮه ﺷﺪه در ﻫﺮ ﻳﻚ از آﻧﻬﺎ ﺑﻪ ﺗﺮﺗﻴﺐ ﺑﺮاي ﺣﺬف ،درج و ﻳﺎ وﻳﺮاﻳﺶ داده ﻫﺎ در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ .در ﺣﻘﻴﻘـﺖ، ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺎ در ﻃﻲ ﺑﺮﻧﺎﻣﻪ ﺗﻐﻴﻴﺮاﺗﻲ را درون داده ﻫﺎي ﻣﻮﺟﻮد در ﺣﺎﻓﻈﻪ ﻧﮕﻪ داري ﻣﻲ ﻛﻨﻴﻢ DataAdapter ،ﺑﺎ اﺳـﺘﻔﺎده از دﺳﺘﻮرات ﻣﻮﺟﻮد در اﻳﻦ ﺧﺎﺻﻴﺖ ﻫﺎ ﺗﻐﻴﻴﺮات ﻣﺎ را از داده ﻫﺎي ﻣﻮﺟﻮد در ﺣﺎﻓﻈﻪ ﺑﻪ داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ ﻣﻨﺘﻘـﻞ ﻣـﻲ ﻛﻨﺪ .ﻣﻤﻜﻦ اﺳﺖ اﺑﺘﺪا اﻳﻦ ﻣﻮارد ﻛﻤﻲ ﭘﻴﭽﻴﺪه ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﻨﺪ ،اﻣﺎ اﺳﺘﻔﺎده از آﻧﻬﺎ ﻣﺎﻧﻨﺪ ﺗﻤﺎم ﻗﺴﻤﺘﻬﺎي دﻳﮕﺮي ﻛﻪ ﺗﺎ ﻛﻨﻮن ﻣﺸﺎﻫﺪه ﻛﺮده اﻳﻢ ﺳﺎده ﻫﺴﺘﻨﺪ .در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان دﺳﺘﻮرات SELECTﻣﻮرد ﻧﻴﺎز را ﺑـﺮاي اﻧﺘﺨـﺎب داده ﻫـﺎ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﻳﺠﺎد ﻛﺮد .ﺑﺮاي ﺗﻜﻤﻴﻞ دﺳﺘﻮرات ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﻛﻼس DataAdapterﻧﻴﺰ ﻓﻘـﻂ ﻛـﺎﻓﻲ اﺳـﺖ ﻛـﻪ دﺳـﺘﻮر SELECTﻣﻮرد ﻧﻈﺮ ﺧﻮد را وارد ﻛﻨﻴﺪ .در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻛﻼﺳﻲ ﺑﻪ ﻧﺎم Command Builderوﺟﻮد دارد ﻛﻪ ﻣﻲ ﺗﻮاﻧـﺪ ﺑﺮ اﺳﺎس دﺳﺘﻮر SELECTوارد ﺷﺪه ،دﺳﺘﻮرات UPDATE ،INSERTو ﻳﺎ DELETEﻣﻨﺎﺳﺐ ﺗﻮﻟﻴﺪ ﻛﻨﺪ. ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ اﺑﺘﺪا ﺑﺎ ﻫﻢ ﺧﺎﺻﻴﺖ SelectCommandو ﻧﺤـﻮه ي اﺳـﺘﻔﺎده از آن را ﺑﺮرﺳـﻲ ﻛﻨـﻴﻢ .ﺳـﭙﺲ ﻣـﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از ،Command Builderدﺳﺘﻮرات دﻳﮕﺮ را ﻧﻴﺰ ﺗﻮﻟﻴﺪ ﻛﺮد.
٦٢٥
ﺧﺎﺻﻴﺖ :SelectCommand ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ 1-16ﻧﻴﺰ ﻧﺸﺎن داده ﺷﺪه اﺳﺖ ،ﺧﺎﺻﻴﺖ SelectCommandدر ﻛﻼس DataAdapterﺑﺮاي درﻳﺎﻓﺖ داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز در ﺑﺮﻧﺎﻣﻪ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ و ﻗﺮار دادن آﻧﻬﺎ در DataSetﺑﻪ ﻛﺎر ﻣﻲ رود. ﺷﻜﻞ 1-16 ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻼس DataAdapterاﻃﻼﻋﺎت ﻣﻮرد ﻧﻴﺎز را از ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ درﻳﺎﻓـﺖ ﻛﻨﻴـﺪ ،اﺑﺘـﺪا ﺑﺎﻳـــﺪ ﺧﺎﺻـــﻴﺖ SelectCommandرا در DataAdapterﺗﻨﻈـــﻴﻢ ﻛﻨﻴـــﺪ .اﻳـــﻦ ﺧﺎﺻـــﻴﺖ ﺷـــﻴﺊ اي از ﻧـــﻮع SqlCommandدرﻳﺎﻓﺖ ﻛﺮده ﻛﻪ اﻳﻦ ﺷﻴﺊ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ داده ﻫﺎ ﭼﮕﻮﻧﻪ ﺑﺎﻳﺪ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﻧﺘﺨﺎب ﺷﺪه و ﻧﻴﺰ ﭼـﻪ داده ﻫﺎﻳﻲ ﺑﺎﻳﺪ اﻧﺘﺨﺎب ﺷﻮﻧﺪ .اﺷﻴﺎﻳﻲ ﻛﻪ از ﻛﻼس SqlCommandاﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ ،ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻠﻲ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﺧﻮد ﻧﻴﺰ ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ دارﻧﺪ ﻛﻪ ﻗﺒﻞ از اﺳﺘﻔﺎده ﺑﺎﻳﺪ آﻧﻬﺎ را ﺗﻨﻈﻴﻢ ﻛﺮد .اﻳﻦ ﺧﺎﺻﻴﺖ ﻫﺎ ﻋﺒﺎرﺗﻨﺪ از:
:Connectionﻳﻚ ﺷﻴﺊ از ﻛﻼس SqlConnectionدر اﻳﻦ ﻗﺴﻤﺖ ﻗﺮار ﮔﺮﻓﺘﻪ و ﻧﺤﻮه ي اﺗـﺼﺎل ﺑـﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ. :CommandTextدﺳﺘﻮر SQLو ﻳﺎ ﻧﺎم ﭘﺮوﺳﻴﺠﺮ ذﺧﻴﺮه ﺷﺪه در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﺑﺎﻳﺪ ﺗﻮﺳـﻂ اﻳـﻦ ﺷـﻴﺊ اﺟـﺮا ﺷﻮد ،در اﻳﻦ ﻗﺴﻤﺖ ذﺧﻴﺮه ﻣﻲ ﺷﻮد.
در ﻗﺴﻤﺖ ﻗﺒﻞ از ﻳﻚ دﺳﺘﻮر SQLﻣﺸﺨﺺ در ﺧﺎﺻﻴﺖ CommandTextاز ﻛﻼس SqlCommandاﺳـﺘﻔﺎده ﻛـﺮدﻳﻢ. اﻣﺎ اﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﻧﺎم ﻳﻚ ﭘﺮوﺳﻴﺠﺮ ذﺧﻴﺮه ﺷﺪه در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را در اﻳﻦ ﺧﺎﺻﻴﺖ ﻗﺮار دﻫﻴﻢ ﺗﺎ اﺟﺮا ﺷﻮد ،ﺑﺎﻳﺪ ﺧﺎﺻﻴﺖ دﻳﮕﺮي ﺑﻪ ﻧﺎم CommandTypeرا ﻧﻴﺰ در ﻛﻼس SqlCommandﺗﻨﻈﻴﻢ ﻛﺮده و ﻣﻘﺪار آن را ﺑﺮاﺑﺮ ﺑـﺎ StoredProcedure ﻗﺮار دﻫﻴﻢ ﺗﺎ ﻣﺸﺨﺺ ﺷﻮد ﻛﻪ ﻣﺘﻦ درون CommandTextﻧﺎم ﻳﻚ ﭘﺮوﺳﻴﺠﺮ ذﺧﻴﺮه ﺷﺪه اﺳﺖ ،ﻧﻪ ﻳﻚ دﺳﺘﻮر .SQLاﻟﺒﺘﻪ در اﻳﻦ ﻓﺼﻞ ﻓﻘﻂ از دﺳﺘﻮرات SQLدر ﺧﺎﺻـﻴﺖ CommandTextاﺳـﺘﻔﺎده ﻣـﻲ ﻛﻨـﻴﻢ ،ﺑﻨـﺎﺑﺮاﻳﻦ ﻧﻴـﺎزي ﻧﻴـﺴﺖ ﻛـﻪ ﺧﺎﺻـﻴﺖ CommandTypeرا ﺗﻐﻴﻴﺮ داده و ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺪار ﺧﺎﺻﻲ ﻗﺮار دﻫﻴﻢ.
ﺗﻨﻈﻴﻢ ﺧﺎﺻﻴﺖ SelectCommandﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر :SQL ﻗﻄﻌﻪ ﻛﺪي ﻛﻪ در زﻳﺮ آورده ﺷﺪه اﺳﺖ ﻧﺤﻮه ي ﺗﻨﻈﻴﻢ ﺧﺎﺻﻴﺖ ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺮاي اﺟﺮاي ﻳﻚ دﺳﺘﻮر SQLﺑـﻪ وﺳـﻴﻠﻪ ي ﻛـﻼس DataAdapterرا ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ: // Declare a SqlDataAdapter object... ;)(SqlDataAdapter objDataAdapter = new SqlDataAdapter // Assign a new SqlCommand to the SelectCommand property ;)(objDataAdapter.SelectCommand = new SqlCommand // Set the SelectCommand properties... ;objDataAdapter.SelectCommand.Connection = objConnection
٦٢٦
= objDataAdapter.SelectCommand.CommandText "SELECT au_lname, au_fname FROM authors " + ;""ORDER BY au_lname, au_fname اوﻟﻴﻦ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ در اﻳﻦ ﻗﺴﻤﺖ اﻧﺠﺎم دﻫﻴﻢ اﻳﻦ اﺳﺖ ﻛﻪ ﺷﻴﺊ را از ﻧﻮع SqlDataAdapterاﻳﺠﺎد ﻛﻨـﻴﻢ .ﺳـﭙﺲ ﺑﺎﻳـﺪ ﺧﺎﺻﻴﺖ SelectCommandآن را ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ .ﺑﺮاي ﺗﻨﻈﻴﻢ اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﺎﻳﺪ ﻳﻚ ﺷـﻴﺊ از ﻛـﻼس SqlCommandرا ﺑﻪ آن ﻧﺴﺒﺖ دﻫﻴﻢ ،ﺑﻨﺎﺑﺮاﻳﻦ ﺷﻴﺊ اي را از اﻳﻦ ﻛﻼس اﻳﺠﺎد ﻛﺮده و ﺗﻨﻈﻴﻤﺎت ﻣﺮﺑﻮط ﺑـﻪ Connectionآن را ﻧﻴـﺰ اﻧﺠـﺎم ﻣـﻲ دﻫﻴﻢ ا ﺑﺘﻮاﻧﺪ ﺑﻪ ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺘﺼﻞ ﺷﻮد .در آﺧﺮ ﻧﻴﺰ ﺧﺎﺻﻴﺖ CommandTextآن را ﺑﺮاﺑﺮ ﺑﺎ ﻳﻚ دﺳـﺘﻮر SQLﻗـﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ آن را روي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺟﺮا ﻛﺮده و ﻧﺘﻴﺠﻪ را درﻳﺎﻓﺖ ﻛﻨﺪ.
ﺗﻨﻈﻴﻢ ﺧﺎﺻﻴﺖ SelectCommandﺑﺎ اﺳﺘﻔﺎده از ﭘﺮوﺳﻴﺠﺮ ذﺧﻴﺮه ﺷﺪه: در اﻳﻦ ﻗﺴﻤﺖ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﺑﺮاي اﺳﺘﻔﺎده از ﻳﻚ ﭘﺮوﺳﻴﺠﺮ ذﺧﻴﺮه ﺷﺪه در ﺑﺮﻧﺎﻣﻪ ﺧﺎﺻﻴﺘﻬﺎي ﻻزم را ﺑﺎﻳﺪ ﭼﮕﻮﻧﻪ ﺗﻨﻈﻴﻢ ﻛﺮد. ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻠﻲ ﻧﻴﺰ ﮔﻔﺘﻦ ،ﻳﻚ ﭘﺮوﺳﻴﺠﺮ ذﺧﻴﺮه ﺷﺪه ،ﻳﻚ ﻣﺠﻤﻮﻋﻪ از دﺳﺘﻮرات SQLاﺳﺖ ﻛﻪ ﺗﺤﺖ ﻳﻚ ﻧﺎم ﻣـﺸﺨﺺ و ﺑﻪ ﺻﻮرت ﻳﻚ واﺣﺪ در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﻳﺠﺎد ﺷﺪه و ﻧﮕﻬﺪاري ﻣﻲ ﺷـﻮد .در اﻳـﻦ ﻗـﺴﻤﺖ ﻓـﺮض ﻣـﻲ ﻛﻨـﻴﻢ ﭘﺮوﺳـﻴﺠﺮي ﺑـﻪ ﻧـﺎم usp_selectدر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ وﺟﻮد دارد ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از دﺳﺘﻮر ،SQLآن را ﻓﺮاﺧﻮاﻧﻲ ﻛـﺮده و ﻧﺘـﺎﻳﺞ اﺟﺮاي آن را درﻳﺎﻓﺖ ﻛﻨﻴﻢ .ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻛﺎر را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ: // Declare a SqlDataAdapter object... ;)(SqlDataAdapter objDataAdapter = new SqlDataAdapter // Assign a new SqlCommand to the SelectCommand property ;)(objDataAdapter.SelectCommand = new SqlCommand // Set the SelectCommand properties... ;objDataAdapter.SelectCommand.Connection = objConnection ;"objDataAdapter.SelectCommand.CommandText = "usp_select = objDataAdapter.SelectCommand.CommandType ;CommandType.StoredProcedure ﻫﻤــﺎﻧﻄﻮر ﻛــﻪ ﻣــﺸﺎﻫﺪ ه ﻣــﻲ ﻛﻨﻴــﺪ در اﻳــﻦ ﻗﻄﻌــﻪ ﺑﺮﻧﺎﻣــﻪ ،ﺑــﺮ ﺧــﻼف ﻗــﺴﻤﺖ ﻗﺒــﻞ ﻛــﻪ ﻳــﻚ دﺳــﺘﻮر SQLرا در ﺧﺎﺻــﻴﺖ CommandTextﻗﺮار ﻣﻲ دادﻳﻢ ،از ﻧﺎم ﻳﻚ ﭘﺮوﺳﻴﺠﺮ ذﺧﻴﺮه ﺷﺪه اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ .ﭘﺲ ﺑﺎﻳﺪ ﺑﻪ ﻧﺤﻮي ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ ﻣﺘﻦ داﺧﻞ CommandTextﻧﺎم ﻳﻚ ﭘﺮوﺳﻴﺠﺮ ذﺧﻴﺮه ﺷﺪه اﺳﺖ ،ﻧﻪ ﻳـﻚ دﺳـﺘﻮر .SQLﺑـﺮاي ﺗﻌﻴـﻴﻦ ﻧـﻮع ﻣـﺘﻦ ﻣﻮﺟـﻮد در اﻳـﻦ ﺧﺎﺻـــﻴﺖ ،ﺑﺎﻳـــﺪ از ﺧﺎﺻـــﻴﺖ CommandTypeاﺳـــﺘﻔﺎده ﻛﻨـــﻴﻢ .ﻣﻘـــﺪار ﭘـــﻴﺶ ﻓـــﺮض اﻳـــﻦ ﺧﺎﺻـــﻴﺖ ﺑﺮاﺑـــﺮ ﺑـــﺎ CommandType.Textاﺳﺖ ﻛﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻣﺘﻦ ﻣﻮﺟﻮد ﻳﻚ دﺳﺘﻮر SQLاﺳﺖ .در اﻳﻦ ﻗﻄﻌﻪ ﻛـﺪ ،اﻳـﻦ ﻣﻘـﺪار را ﺗﻐﻴﻴﺮ داده و ﺑﺮاﺑﺮ ﺑﺎ CommandType.StoredProcedureﻗﺮار ﻣﻲ دﻫﻴﻢ ﺗـﺎ ﻣـﺸﺨﺺ ﺷـﻮد ﻣﻘـﺪار ﻣﻮﺟـﻮد در ﺧﺎﺻﻴﺖ CommandTextﻧﺎم ﻳﻚ ﭘﺮوﺳﻴﺠﺮ ذﺧﻴﺮه ﺷﺪه اﺳﺖ.
٦٢٧
اﺳﺘﻔﺎده از Command Builderﺑﺮاي اﻳﺠﺎد دﺳﺘﻮرات SQLدﻳﮕﺮ: ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ SelectCommandﻣﻮﺟﻮد در ﻛﻼس DataAdapterﻣﻲ ﺗﻮاﻧﻴﻢ داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز در ﺑﺮﻧﺎﻣﻪ را از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺘﺨﺮاج ﻛﺮده و در ﻳﻚ DataSetدر ﺣﺎﻓﻈﻪ ﻗﺮار دﻫﻴﻢ .ﺳﭙﺲ در ﻃﻮل ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑـﻪ ﻛـﺎرﺑﺮ اﺟـﺎزه دﻫﻴﻢ ﺗﺎ ﺗﻐﻴﻴﺮات ﻣﻮرد ﻧﻈﺮ ﺧﻮد را در داده ﻫﺎي ﻣﻮﺟﻮد در ﺣﺎﻓﻈﻪ اﻳﺠﺎد ﻛﺮده و ﺑﻌﺪ از اﺗﻤﺎم آﻧﻬﺎ ،اﻳﻦ ﺗﻐﻴﻴﺮات را ﺑﻪ داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﻨﻌﻜﺲ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻻزم اﺳﺖ ﻛﻪ دﺳﺘﻮرات SQLﻣـﻮرد ﻧﻴـﺎز ﺑـﺮاي درج ،ﺣـﺬف و ﻳـﺎ وﻳـﺮاﻳﺶ داده ﻫـﺎي درﻳﺎﻓﺘﻲ را ﺑﻪ ﻛﻼس DataAdapterاﺿﺎﻓﻪ ﻛﻨﻴﻢ ﺗﺎ اﻳﻦ ﻛﻼس ﺑﺘﻮاﻧﺪ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ دﺳﺘﻮرات ،ﺗﻐﻴﻴـﺮات اﻳﺠـﺎد ﺷـﺪه را در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ وارد ﻛﻨﺪ. اﻣﺎ ﺑﺮاي اﻳﺠﺎد اﻳﻦ دﺳﺘﻮرات ﻻزم اﺳﺖ ﻛﻪ ﺑﻪ زﺑﺎن SQLﺗﺴﻠﻂ ﺑﻴﺸﺘﺮي داﺷﺘﻪ ﺑﺎﺷﻴﻢ .ﺧﻮﺷﺒﺨﺘﺎﻧﻪ روش ﺳﺎده ﺗﺮي ﻫﻢ ﺑـﺮاي اﻧﺠـﺎم اﻳﻦ ﻛﺎر وﺟﻮد دارد و آن اﺳﺘﻔﺎده از ﻛﻼس CommandBuilderاﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ دﺳـﺘﻮر SELECTاي ﻛـﻪ ﺑﺮاي DataAdapterوارد ﻛﺮده اﻳﻢ ،دﺳﺘﻮرات UPDATE ،INSERTو ﻧﻴﺰ DELETEﻣﻨﺎﺳﺐ ﺗﻮﻟﻴﺪ ﻛﻨﺪ .ﻗﻄﻌﻪ ﻛـﺪ زﻳﺮ ﻧﺤﻮه ي اﺳﺘﻔﺎده از اﻳﻦ دﺳﺘﻮر را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. // Declare a SqlDataAdapter object... ;)(SqlDataAdapter objDataAdapter = new SqlDataAdapter // Assign a new SqlCommand to the SelectCommand property ;)(objDataAdapter.SelectCommand = new SqlCommand // Set the SelectCommand properties... ;objDataAdapter.SelectCommand.Connection = objConnection ;"objDataAdapter.SelectCommand.CommandText = "usp_select = objDataAdapter.SelectCommand.CommandType ;CommandType.StoredProcedure // automatically create update/delete/insert commands = SqlCommandBuilder objCommandBuilder ;)new SqlCommandBuilder(objDataAdapter ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﻼس ،دﺳﺘﻮرات ﻻزم ﺑﺮاي ﻣﻨﻌﻜﺲ ﻛﺮدن ﺗﻐﻴﻴﺮات اﻳﺠﺎد ﺷﺪه از DataSetﺑـﻪ ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ ﺑـﻪ ﺻـﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد .در اداﻣﻪ ي ﻓﺼﻞ ﺑﺎ ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻛﺎر ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ ،اﻣﺎ ﻓﻌﻼ ﺑﻬﺘﺮ اﺳﺖ ﺑﺒﻴﻨﻴﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان داده ﻫﺎ را از ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺘﺨﺮاج ﻛﺮده و در ﻳﻚ DataSetدر ﺣﺎﻓﻈﻪ ﻗﺮار داد.
ﻣﺘﺪ :Fill ﺑـــﺎ اﺳـــﺘﻔﺎده از ﻣﺘـــﺪ Fillدر ﻛـــﻼس DataAdapterﻣـــﻲ ﺗﻮاﻧﻴـــﺪ دﺳـــﺘﻮر SQLﻣﻮﺟـــﻮد در ﺧﺎﺻـــﻴﺖ SelectCommandرا در ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ اﺟـﺮا ﻛـﺮده ،و ﺳـﭙﺲ داده ﻫـﺎي ﺑﺮﮔـﺸﺘﻲ از اﺟـﺮاي اﻳـﻦ دﺳـﺘﻮر را درون ﻳـﻚ DataSetدر ﺣﺎﻓﻈﻪ ﻗﺮار دﻫﻴﺪ .اﻟﺒﺘﻪ ﻗﺒﻞ از اﺳﺘﻔﺎده از اﻳﻦ ﻣﺘﺪ ،ﺑﺎﻳﺪ ﺷﻴﺊ اي از ﻧﻮع DataSetاﻳﺠﺎد ﻛﻨﻴﻢ. // Declare a SqlDataAdapter object... ٦٢٨
SqlDataAdapter objDataAdapter = new SqlDataAdapter(); // Assign a new SqlCommand to the SelectCommand property objDataAdapter.SelectCommand = new SqlCommand(); // Set the SelectCommand properties... objDataAdapter.SelectCommand.Connection = objConnection; objDataAdapter.SelectCommand.CommandText = "usp_select"; objDataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure; DataSet objDataSet = new DataSet(); داده ﻫـﺎFill ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘـﺪ، ﻣﻮرد ﻧﻴﺎز را اﻳﺠﺎد ﻛﺮدﻳﻢDataAdapter و ﻧﻴﺰDataSet ﺣﺎل ﻛﻪ ﺷﻴﺊ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﺑﺴﻴﺎري از ﻣﺘﺪ ﻫﺎي دﻳﮕﺮ داراي ﻧـﺴﺨﻪ ﻫـﺎي ﮔﻮﻧـﺎﮔﻮﻧﻲFill ﻣﺘﺪ. ﻗﺮار دﻫﻴﻢDataSet را از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ در : اﻣﺎ ﻳﻜﻲ از ﭘﺮ ﻛﺎرﺑﺮد ﺗﺮﻳﻦ آﻧﻬﺎ ﺑﻪ ﺻﻮرت زﻳﺮ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد،اﺳﺖ SqlDataAdapter.Fill(DataSet, String); ﭘـﺎراﻣﺘﺮ. اي اﺳـﺖ ﻛـﻪ ﺑﺎﻳـﺪ داده ﻫـﺎ در آن ﻗـﺮار ﺑﮕﻴﺮﻧـﺪDataSet ﻣﺸﺨﺺ ﻛﻨﻨﺪه ي ﻧﺎم، در اﻳﻦ ﻣﺘﺪDataSet ﭘﺎراﻣﺘﺮ ﻫـﺎDataSet . درون آن ﺟﺪول ﻗﺮار ﻣﻲ ﮔﻴﺮﻧـﺪDataSet ﻧﻴﺰ ﻧﺎم ﺟﺪوﻟﻲ را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ داده ﻫﺎ درString ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣـﻲ ﺧـﻮاﻫﻴﻢ داده اي را.ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻨﺪ ﻫﻤﺎﻧﻨﺪ ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ ﺷﺎﻣﻞ ﭼﻨﺪﻳﻦ ﺟﺪول ﻣﺨﺘﻠﻒ از اﻃﻼﻋﺎت ﺑﺎﺷﻨﺪ در آن ﻗﺮار دﻫﻴﻢ ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ ﻧﺎم ﺟﺪوﻟﻲ ﻛﻪ داده ﻫﺎ در آن ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ ﭼﻪ ﺑﺎﻳﺪ ﺑﺎﺷﺪ؟ در اﻳﻦ ﺟﺎ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻫـﺮ ﻧـﺎم ﻛـﻪ ﺑﻪ. اﻣﺎ ﺑﻬﺘﺮ اﺳﺖ ﻫﻤﻮاره از اﺳﺎﻣﻲ ﺟﺪاوﻟﻲ اﺳﺘﻔﺎده ﻛﻨﻴﻢ ﻛﻪ داده ﻫﺎ از آن ﮔﺮﻓﺘﻪ ﺷﺪه اﻧﺪ،ﺗﻤﺎﻳﻞ داﺷﺘﻪ ﺑﺎﺷﻴﻢ ﺑﺮاي ﺟﺪول اﻧﺘﺨﺎب ﻛﻨﻴﻢ .اﻳﻦ ﺗﺮﺗﻴﺐ درك ﺑﺮﻧﺎﻣﻪ ﺑﺴﻴﺎر راﺣﺖ ﺗﺮ ﺧﻮاﻫﺪ ﺑﻮد در ﺟﺪوﻟﻲFill ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ ﻳﻚ ﭘﺮوﺳﻴﺠﺮ ذﺧﻴﺮه ﺷﺪه در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را اﺟﺮا ﻛﺮده و ﻧﺘﺎﻳﺞ ﺑﺮﮔﺸﺘﻲ از آن را ﺑﻪ وﺳﻴﻠﻪ ي ﻣﺘﺪ : ﻗﺮار ﻣﻲ دﻫﺪobjDataSet درauthors ﺑﻪ ﻧﺎم // Declare a SqlDataAdapter object... SqlDataAdapter objDataAdapter = new SqlDataAdapter(); // Create an instance of a new select command object objDataAdapter.SelectCommand = new SqlCommand(); // Set the SelectCommand properties... objDataAdapter.SelectCommand.Connection = objConnection; objDataAdapter.SelectCommand.CommandText = "usp_select"; objDataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure; DataSet objDataSet = new DataSet(); // Fill the DataSet object with data... objDataAdapter.Fill(objDataSet, "authors");
٦٢٩
ﻣﺘﺪ Fillﺑﺮاي اﺗﺼﺎل ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ از ﺷـﻴﺊ Connectionاي ﻛـﻪ در ﺧﺎﺻـﻴﺖ SelectCommandﻗـﺮار دارد اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ .اﻳﻦ ﻣﺘﺪ اﺑﺘﺪا ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﺪ ﻛﻪ اﺗﺼﺎل اﻳﻦ Connectionﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ ﺑﺮﻗـﺮار اﺳـﺖ ﻳـﺎ ﻧـﻪ .در ﺻﻮرﺗﻲ ﻛﻪ اﺗﺼﺎل ﺑﺮﻗﺮار ﺑﺎﺷﺪ ،ﻣﺘﺪ Fillداده ﻫﺎي ﻣﻮرد ﻧﻴﺎز را از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺪﺳﺖ آورده ،اﻣﺎ اﺗـﺼﺎل Connection ﺑﺎ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را ﻗﻄﻊ ﻧﻤﻲ ﻛﻨﺪ .اﮔﺮ ﻫﻢ ارﺗﺒﺎط ﺷﻴﺊ Connectionﺑﺎ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻗﻄﻊ ﺑﺎﺷﺪ ،ﻣﺘﺪ Fillﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ Openارﺗﺒﺎط را ﺑﺮﻗﺮار ﻛﺮده و ﭘﺲ از ﺑﺪﺳﺖ آوردن اﻃﻼﻋﺎت ﻣﻮرد ﻧﻴﺎز ،ﻣﺘﺪ Closeرا ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ ﺗﺎ اﺗﺼﺎل ﺑﻪ ﺑﺎﻧـﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺠﺪداً ﻗﻄﻊ ﺷﻮد. ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ داده ﻫﺎ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ درون ﺣﺎﻓﻈﻪ ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ و ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺻﻮرت ﻣﺴﺘﻘﻞ آﻧﻬﺎ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ .دﻗﺖ ﻛﻨﻴﺪ ﻛـﻪ اﺑﺘﺪاي ﻛﻼس DataSetﻛﻠﻤﻪ ي Sqlوﺟﻮد ﻧﺪارد .دﻟﻴﻞ اﻳﻦ ﻣﻮرد ﻫﻢ اﻳـﻦ اﺳـﺖ ﻛـﻪ اﻳـﻦ ﻛـﻼس ﻣﺘﻌﻠـﻖ ﺑـﻪ ﻓـﻀﺎي ﻧـﺎم System.Data.SqlClientﻧﻴﺴﺖ ﺑﻠﻜﻪ در ﻓﻀﺎي ﻧﺎم System.Dataﻗﺮار دارد .ﺑﻪ ﻋﺒﺎرت دﻳﮕـﺮ ﻛـﻼس DataSetﺑﻪ ﺳﺮوﻳﺲ دﻫﻨﺪه ي اﻃﻼﻋﺎﺗﻲ ﺧﺎﺻﻲ از ﻗﺒﻴـﻞ SqlClientو ﻳـﺎ OleDbﺗﻌﻠـﻖ ﻧـﺪارد و وﻇﻴﻔـﻪ ي آن ﻧﮕﻬﺪاري اﻃﻼﻋﺎت ﺑﺪﺳﺖ آﻣﺪه )ﺑﻪ ﻫﺮ ﻧﺤﻮي( در ﺣﺎﻓﻈﻪ اﺳﺖ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻃﻼﻋﺎت را در ﺣﺎﻓﻈﻪ ﻗﺮار دادﻳﻢ دﻳﮕﺮ ﻧﻴﺎزي ﻧﻴﺴﺖ ﺑﺪاﻧﻴﻢ ﻛﻪ اﻳﻦ اﻃﻼﻋﺎت از ﻛﺠﺎ ﺑﺪﺳﺖ آﻣﺪه اﻧﺪ )ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﻢ آﻧﻬﺎ را دوﺑﺎره در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻗﺮار دﻫﻴﻢ(.
ﻛﻼس :DataSet ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﻛﻼس DataSetﺑﺮاي ﻧﮕﻬﺪاري اﻃﻼﻋﺎت ﺑﺪﺳﺖ آﻣﺪه از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ در ﺣﺎﻓﻈـﻪ ﺑـﻪ ﻛـﺎر ﻣـﻲ رود .اﻳـﻦ ﻛﻼس ﺷﺎﻣﻞ ﻣﺠﻤﻮﻋﻪ اي از ﺟﺪاول ،راﺑﻄﻪ ﻫﺎ ،ﻗﻴﺪ و ﺷﺮط ﻫﺎ و دﻳﮕﺮ ﻣﻮاردي اﺳﺖ ﻛﻪ از ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ ﺧﻮاﻧـﺪه ﺷـﺪه اﺳـﺖ .اﻳـﻦ ﻛﻼس ﺧﻮد ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻛﻮﭼﻚ ﻋﻤﻞ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ داده ﻫﺎ را درون ﺧـﻮد در ﺟـﺪاوﻟﻲ ﻣﺠـﺰا ﻧﮕﻬـﺪاري ﻛﺮده و ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﺪ ﻛﻪ آﻧﻬﺎ را وﻳﺮاﻳﺶ ﻛﻨﺪ .ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از ﻛﻼس DataViewﭘﺮس وﺟﻮ ﻫـﺎﻳﻲ را روي داده ﻫﺎي ﻣﻮﺟﻮد در آن اﺟﺮا ﻛﺮد. داده ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻛﻨﺘﺮل ﻗﺮار دارﻧﺪ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻗﻄﻊ ﻫﺴﺘﻨﺪ و ارﺗﺒﺎﻃﻲ ﺑﺎ ﺑﺎﻧﻚ ﻧﺪارﻧﺪ .در ﻃﻮل ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗـﻮاﻧﻴﻢ داده ﻫـﺎي ﻣﻮﺟــﻮد در آن را ﺣــﺬف ﻛــﺮده ،وﻳــﺮاﻳﺶ و ﻳــﺎ اﺿــﺎﻓﻪ ﻛﻨــﻴﻢ و ﺑﻌــﺪ از اﺗﻤــﺎم ﺗﻤــﺎم ﺗﻐﻴﻴــﺮات ﻣــﻮرد ﻧﻈــﺮ ،ﻣﺠــﺪداً ﺑــﺎ اﺳــﺘﻔﺎده از DataAdapterﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺘﺼﻞ ﺷﺪه و ﺗﻐﻴﻴﺮات را در ذﺧﻴﺮه ﻛﻨﻴﻢ. ﻛﻼس DataSetاز ﺳﺎﺧﺘﺎر XMLﺑﺮاي ذﺧﻴﺮه ي داده ﻫﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ )در ﻓﺼﻞ ﻧﻮزدﻫﻢ ﺑﺎ اﻳﻦ ﺳﺎﺧﺘﺎر ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧـﻮاﻫﻴﻢ ﺷﺪ( ،ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ داده ﻫﺎي ﻣﻮﺟﻮد در ﻳﻚ ﺷﻴﺊ از ﻛﻼس DataSetرا ﺑﻪ ﺳﺎدﮔﻲ در ﻳﻚ ﻓﺎﻳﻞ ذﺧﻴﺮه ﻛﺮده و ﻳﺎ آن را ﺑﺎ اﺳﺘﻔﺎده از ﺷﺒﻜﻪ ﺑﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ دﻳﮕﺮي ﻣﻨﺘﻘﻞ ﻛﻨﻴﺪ .اﻟﺒﺘﻪ ﻫﻨﮕﺎم ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ و ﻛﺎر ﺑﺎ DataSetﻻزم ﻧﻴﺴﺖ ﺑﺎ آﻧﻬـﺎ در ﻗﺎﻟـﺐ XMLرﻓﺘﺎر ﻛﻨﻴﺪ .ﺑﻠﻜﻪ ﻛﺎﻓﻲ اﺳﺖ ﺗﻤﺎم ﻛﺎرﻫﺎي ﻣﻮرد ﻧﻈﺮ ﺧﻮد را ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ﻫﺎ و ﻳـﺎ ﻣﺘـﺪﻫﺎي ﻣﻮﺟـﻮد در DataSet اﻧﺠﺎم دﻫﻴﺪ ،ﺑﻘﻴﻪ ي اﻣﻮر را ﻛﻼس DataSetﻛﻨﺘﺮل ﺧﻮاﻫﺪ ﻛﺮد. 1 ﻣﺎﻧﻨﺪ ﻫﺮ ﺳﻨﺪ XMLدﻳﮕﺮي ،ﻳﻚ DataSetﻧﻴﺰ داراي ﻳﻚ اﻟﮕﻮ اﺳﺖ )ﻓﺎﻳﻠﻲ ﻛﻪ ﺳﺎﺧﺘﺎر داده ﻫﺎي درون ﻳﻚ ﻳـﺎ ﭼﻨـﺪ ﻓﺎﻳـﻞ XMLرا ﺷﺮح ﻣﻲ دﻫﺪ( .در ﻓﺼﻞ ﻗﺒﻞ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از وﻳﺰارد ﻳﻚ DataSetرا ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮدﻳﻢ ،ﻓﺎﻳﻠﻲ ﺑﺎ ﭘﺴﻮﻧﺪ XSD2اﻳﺠﺎد ﺷﺪ و اﻟﮕﻮي DataSetدر آن ﻗﺮار ﮔﺮﻓﺖ )ﺷﻜﻞ .(2-16
Schema XML Schema Definition
1 2
٦٣٠
ﺷﻜﻞ 2-16 اﻳﻦ ﻓﺎﻳﻞ ﺣﺎوي اﻟﮕﻮي XMLاﻃﻼﻋﺎﺗﻲ ﺑﻮد ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي customerDataSetﻧﮕﻬﺪاري ﻣﻲ ﺷﺪ .ﺑـﻪ وﺳـﻴﻠﻪ ي اﻳـﻦ ﻓﺎﻳﻞ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻛﻼﺳﻲ را از ﻛﻼس DataSetﻣﺸﺘﻖ ﻣﻲ ﻛﺪ ﺗﺎ ﺑﺘﻮاﻧﺪ داده ﻫﺎي درﻳﺎﻓﺖ ﺷﺪه از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را در ﺷﻴﺊ اي از آن ﻛﻼس ﻧﮕﻬﺪاري ﻛﻨﺪ .اﻟﺒﺘﻪ ﺗﻤﺎم اﻳﻦ ﻣﻮارد ﻧﻴﺰ از دﻳﺪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ دور ﻣﻲ ﻣﺎﻧﺪ و ﺑﻪ ﺻﻮرت دروﻧـﻲ ﺗﻮﺳـﻂ DataSet اﻧﺠﺎم ﻣﻲ ﺷﻮد. ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻓﻴﻠﺪ ﻫﺎي درون ﻳﻚ ﺟﺪول از DataSetرا ﺑﻪ ﻛﻨﺘﺮﻟﻬﺎي درون ﻓﺮم ﻣﺘﺼﻞ ﻛﻨﻴﻢ ،ﺗﺎ آن ﻛﻨﺘﺮل ﻫﺎ داده ﻫـﺎي ﺧﻮد را ﺑﻪ وﺳﻴﻠﻪ ي آن ﻓﻴﻠﺪ ﺑﺪﺳﺖ آورﻧﺪ .در ﻓﺼﻞ ﻗﺒﻞ ﻣﻘﺪاري ﺑﺎ اﻧﺠﺎم اﻳﻦ ﻛﺎر آﺷﻨﺎ ﺷﺪﻳﺪ ،در اداﻣﻪ ي ﻓﺼﻞ ﻧﻴﺰ ﺑﻴﺸﺘﺮ در اﻳﻦ ﻣـﻮرد ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد.
ﻛﻼس :DataView ﻛﻼس DataViewﻋﻤﻮﻣﺎً ﺑﺮاي ﺟﺴﺘﺠﻮ ،ﻣﺮﺗﺐ ﻛﺮدن ،ﻓﻴﻠﺘﺮ ﻛﺮدن ،وﻳﺮاﻳﺶ ﻛﺮدن و ﻳﺎ ﺣﺮﻛﺖ ﻛـﺮدن در ﺑـﻴﻦ داده ﻫـﺎي درون ﻳﻚ DataSetﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد .ﻛﻨﺘﺮل DataViewﻳﻚ ﻛﻨﺘﺮل ﻗﺎﺑﻞ اﺗﺼﺎل اﺳﺖ ،ﺑﻪ اﻳﻦ ﻣﻌﻨـﻲ ﻛـﻪ ﻫﻤـﺎﻧﻄﻮر ﻛﻪ ﻣﻲ ﺗﻮان ﻛﻨﺘﺮل ﻫﺎ را ﺑﻪ ﻳﻚ DataSetﻣﺘﺼﻞ ﻛﺮد ،ﻣﻲ ﺗﻮان آﻧﻬﺎ را ﺑﻪ ﻳﻚ DataViewﻧﻴﺰ ﻣﺘﺼﻞ ﻛﺮد .در اﻳﻦ ﻣـﻮرد ﻧﻴﺰ در اداﻣﻪ ي ﻓﺼﻞ ﺑﻴﺸﺘﺮ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔﺘﻢ ﻳﻚ ﻛﻨﺘﺮل DataSetﻣﻲ ﺗﻮاﻧﺪ ﺷﺎﻣﻞ ﭼﻨﺪﻳﻦ ﺟﺪول ﺑﺎﺷﺪ ﻛـﻪ ﻫـﺮ ﻳـﻚ از آﻧﻬـﺎ ﺑـﻪ وﺳـﻴﻠﻪ ي ﻳـﻚ ﻛﻨﺘـﺮل DataTableﻣﺸﺨﺺ ﻣﻲ ﺷـﻮد .در ﺣﻘﻴﻘـﺖ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﺑـﺎ اﺳـﺘﻔﺎده از DataAdapterداده ﻫـﺎﻳﻲ را درون ﻳـﻚ DataSetﻗﺮار ﻣﻲ دﻫﻴﺪ ،اﺑﺘﺪا ﻳﻚ ﺟﺪول ﺟﺪﻳﺪ اﻳﺠﺎد ﻛﺮده )ﻳﻚ ﺷﻴﺊ ﺟﺪﻳـﺪ از ﻧـﻮع (DataTableو ﺳـﭙﺲ داده ﻫـﺎ را درون آن ﻗﺮار ﻣﻲ دﻫﻴﺪ و ﺑﻪ DataSetاﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﺪ .ﻛﺎري ﻛﻪ ﻛﻨﺘﺮل DataViewاﻧﺠﺎم ﻣﻲ دﻫﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣﻲ دﻫﺪ ﺑﻪ ﺻﻮرﺗﻲ ﻛﻪ ﺗﻤﺎﻳﻞ دارﻳﺪ ﺑﻪ داده ﻫﺎي درون ﻳﻜﻲ از ﺟﺪاول DataSetﻧﮕﺎه ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل آﻧﻬﺎ را ﺑـﻪ ﺻـﻮرت ﻣﺮﺗﺐ ﺷﺪه ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ و ﻳﺎ ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ،دﺳﺘﻮرات SQLﺧﺎﺻﻲ را روي اﻳﻦ ﺟﺪاول اﺟﺮا ﻛﺮده و ﻧﺘﺎﻳﺞ آﻧﻬﺎ را ﺑﺒﻴﻨﻴﺪ. ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﺷﻴﺊ از ﻛﻼس DataViewرا ﺑﻪ ﮔﻮﻧﻪ اي اﻳﺠﺎد ﻛﻨﻴﺪ ﻛـﻪ ﺷـﺎﻣﻞ ﺗﻤـﺎﻣﻲ داده ﻫـﺎي ﻣﻮﺟـﻮد در ﻳـﻚ ﺟـﺪول از DataSetﺑﺎﺷﺪ و ﻓﻘﻂ ﻧﺤﻮه ي ﻧﻤﺎﻳﺶ آﻧﻬﺎ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺑﺮاي ﻣﺜـﺎل اﮔـﺮ ﺟـﺪوﻟﻲ ﺑـﻪ ﻧـﺎم authorsدر DataSet وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ ﻛﻪ ﺑﺮ اﺳﺎس LastNameو ﺳﭙﺲ FirstNameﻣﺮﺗﺐ ﺷﺪه اﺳﺖ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳـﻚ DataViewرا ﺑﻪ ﮔﻮﻧﻪ اي اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ ﺣﺎوي ﻫﻤﺎن اﻃﻼﻋﺎت ﺑﺎﺷﺪ ،اﻣﺎ آﻧﻬـﺎ را اﺑﺘـﺪا ﺑـﺮ اﺳـﺎس FirstNameو ﺳـﭙﺲ LastName ﻣﺮﺗﺐ ﻛﻨﺪ .و ﻳﺎ ﺣﺘﻲ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ DataViewاﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ ﻓﻘﻂ ﻓﻴﻠﺪ LastNameاز ﺟﺪول authorsرا ﻧﻤﺎﻳﺶ دﻫﺪ و ﻳﺎ ﻓﻘﻂ ﻓﻴﻠﺪ FirstNameرا ﻧﻤﺎﻳﺶ دﻫﺪ و ….
٦٣١
اﻟﺒﺘﻪ ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ وﺳﻴﻠﻪ ي ﻛﻼس ،DataViewاﻃﻼﻋﺎت درون ﻳﻚ DataTableرا ﺑـﻪ ﮔﻮﻧـﻪ اي دﻳﮕـﺮ ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ ،ﺑﺎﻳﺪ دﻗﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ اﻃﻼﻋـﺎت درون DataViewدر ﺣﻘﻴﻘـﺖ ﻫﻤـﺎن اﻃﻼﻋـﺎت درون DataTable ﻫﺴﺘﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﺮ ﺗﻐﻴﻴﺮي ﻛﻪ در اﻃﻼﻋﺎت DataViewاﻳﺠﺎد ﺷﻮد ،در اﻃﻼﻋﺎت DataTableﻧﻴﺰ ﻣﻨﻌﻜﺲ ﺧﻮاﻫﺪ ﺷـﺪ و ﺑﺮ ﻋﻜﺲ. ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﺷﻴﺊ از ﻛﻼس DataViewﺑﺎﻳﺪ ﻧﺎم ﺟﺪوﻟﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﻪ آن ﻣﺘﺼﻞ ﺷﻮد را در ﻣﺘﺪ ﺳﺎزﻧﺪه ي آن ﻣﺸﺨﺺ ﻛﻨﻴﻢ .در ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ ،ﻳﻚ ﺷﻴﺊ از ﻛﻼس DataViewاﻳﺠﺎد ﺷﺪه و ﺑﻪ ﺟﺪول authorsاز objDataSetﻣﺘﺼﻞ ﻣﻲ ﺷﻮد .دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻳﻚ ﺟﺪول ﺧﺎص از DataSetاز ﺧﺎﺻﻴﺖ Tablesدر ﻛﻼس DataSetﺑﻪ ﻫﻤﺮاه ﻧﺎم ﺟﺪول ﻣﻮرد ﻧﻈﺮ اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ. // Set the DataView object to the DataSet object... DataView objDataView = new ;))"DataView(objDataSet.Tables("authors
ﺧﺎﺻﻴﺖ :Sort ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﺷﻴﺊ از ﻧﻮع DataViewاﻳﺠﺎد ﻛﺮده و آن را ﺑﻪ ﻳﻚ ﺟﺪول درون DataSetﻣﺘـﺼﻞ ﻛﺮدﻳـﺪ ،ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﻧﺤﻮه ي ﻧﻤﺎﻳﺶ داده ﻫﺎ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ داده ﻫﺎي درون ﺟـﺪول را ﺑـﻪ ﮔﻮﻧـﻪ اي ﻣﺘﻔـﺎوت ﻣﺮﺗـﺐ ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺧﺎﺻﻴﺖ Sortدر ﻛﻼس DataViewاﺳﺘﻔﺎده ﻛﺮده و ﻣﻘﺪار آن را ﺑﺮاﺑﺮ ﺑـﺎ ﻧـﺎم ﺳـﺘﻮن و ﻳـﺎ ﺳﺘﻮن ﻫﺎﻳﻲ ﻗﺮار دﻫﻴﺪ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ داده ﻫﺎ ﺑﺮ اﺳﺎس آﻧﻬﺎ ﻣﺮﺗـﺐ ﺷـﻮﻧﺪ .ﻗﻄﻌـﻪ ﻛـﺪ زﻳـﺮ ﺟـﺪول authorsرا ﺑـﻪ وﺳـﻴﻠﻪ ي DataViewاي ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ اﻳﺠﺎد ﻛﺮدﻳﻢ ،ﺑﺮ اﺳﺎس FirstNameو LastNameﻣﺮﺗﺐ ﻣﻲ ﻛﻨﺪ: ;"objDataView.Sort = "au_fname, au_lname ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻋﺒﺎرﺗﻲ ﻛﻪ ﺑﻪ اﻳﻦ ﺧﺎﺻﻴﺖ ﻧﺴﺒﺖ داده ﻣﻲ ﺷﻮد ،ﻫﻤﺎﻧﻨﺪ ﻋﺒﺎرﺗﻲ اﺳﺖ ﻛﻪ در ﻣﻘﺎﺑﻞ ORDER BYدر دﺳﺘﻮر SELECTزﺑﺎن SQLوارد ﻣﻲ ﻛﺮدﻳﻢ .در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ دﺳﺘﻮر ،SELECTﺗﻤﺎم ﻣﺮﺗﺐ ﺳﺎزي ﻫﺎ ﺑﻪ ﻃﻮر ﭘـﻴﺶ ﻓﺮض ﺑﻪ ﺻﻮرت ﺻﻌﻮدي اﻧﺠﺎم ﻣﻲ ﺷﻮﻧﺪ و ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﺗﺮﺗﻴﺐ ﻣﺮﺗﺐ ﺷﺪن آﻧﻬﺎ را ﺑﻪ ﺻﻮرت ﻧﺰوﻟﻲ ﺗﻐﻴﻴﺮ دﻫﻴﻢ ،ﺑﺎﻳـﺪ در ﻣﻘﺎﺑـﻞ ﻧﺎم ﺳﺘﻮن از ﻋﺒﺎرت DESCاﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺑﺮاي ﻣﺜﺎل ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ ،داده ﻫﺎي ﻣﻮﺟﻮد در ﺟـﺪول authorsرا ﺑـﺮ اﺳـﺎس ﻓﻴﻠـﺪ FirstNameﺑﻪ ﺻﻮرت ﺻﻌﻮدي و ﻓﻴﻠﺪ LastNameﺑﻪ ﺻﻮرت ﻧﺰوﻟﻲ ﻣﺮﺗﺐ ﻣﻲ ﻛﻨﺪ: ;"objDataView.Sort = "au_fname,au_lname DESC
ﺧﺎﺻﻴﺖ :RowFilter ﻋﻼوه ﺑﺮ ﻣﺮﺗﺐ ﻛﺮدن داده ﻫﺎ ،ﺑﺎ اﺳﺘﻔﺎده از DataViewﻣﻲ ﺗﻮاﻧﻴﺪ داده ﻫﺎي ﻣﻮﺟﻮد در ﻳﻚ ﺟﺪول را ﻓﻴﻠﺘﺮ ﻛﻨﻴﺪ ،ﺑﻪ ﮔﻮﻧﻪ اي ﻛﻪ ﻓﻘﻂ داده ﻫﺎﻳﻲ ﻛﻪ داراي ﺷﺮاﻳﻂ ﺧﺎﺻﻲ ﻫﺴﺘﻨﺪ ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ .اﻳﻦ اﻣﻜﺎن ﻫﻤﺎﻧﻨـﺪ ﻗـﺴﻤﺖ WHEREاز دﺳـﺘﻮر SELECTدر زﺑﺎن SQLاﺳﺖ ﻛﻪ ﺷﺮط ﺧﺎﺻﻲ را ﺑﺮاي ﻧﻤﺎﻳﺶ داده ﺷﺪن داده ﻫﺎ اﻳﺠﺎد ﻣﻲ ﻛﺮد .ﺑﺮاي ﻓﻴﻠﺘـﺮ ﻛـﺮدن اﻃﻼﻋـﺎت ﻧﻴـﺰ ﻣـﻲ ﺗﻮاﻧﻴـﺪ از ﺧﺎﺻﻴﺖ RowFilterاﺳﺘﻔﺎده ﻛﺮده و ﺷﺮط ﻣﻮرد ﻧﻈﺮ ﺧﻮد را در آن ﻗﺮار دﻫﻴﺪ .ﻧﺤﻮه ي وارد ﻛﺮدن دﺳﺘﻮرات در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ
٦٣٢
ﻫﻤﺎﻧﻨﺪ وارد ﻛﺮدن ﺷﺮط ﻫﺎ در ﻗﺴﻤﺖ WHEREاز دﺳﺘﻮر SELECTاﺳﺖ .ﻓﻘﻂ ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،ﺑﻪ ﻋﻠـﺖ اﻳﻨﻜـﻪ ﻛـﻞ ﻋﺒـﺎرت ﺷﺮط ﺑﺎﻳﺪ درون ﻋﻼﻣﺖ “ ﻗﺮار ﺑﮕﻴﺮﻧﺪ ،ﭘﺲ اﮔﺮ ﺑﺨﻮاﻫﻴﺪ رﺷﺘﻪ اي را در ﺷﺮط ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﺑﺎﻳﺪ آن را درون ﻋﻼﻣﺖ ‘ ﻗـﺮار دﻫﻴـﺪ. ﺑﺮاي ﻣﺜﺎل ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ در ﺟﺪول authorsﻓﻘﻂ اﻓﺮادي را ﻛﻪ LastNameآﻧﻬﺎ ﺑﺮاﺑـﺮ ﺑـﺎ Greenاﺳـﺖ ﻧﻤـﺎﻳﺶ ﻣـﻲ دﻫﺪ: // Set the DataView object to the DataSet object... DataView objDataView = new ;))"DataView(objDataSet.Tables("authors ;"'objDataView.RowFilter = "au_lname = 'Green و ﻳﺎ ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ در ﺟﺪول authorsاﻓﺮادي ﻛﻪ LastNameآﻧﻬﺎ ﻣﺨﺎﻟﻒ Greenاﺳﺖ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ: // Set the DataView object to the DataSet object... DataView objDataView = new ;))"DataView(objDataSet.Tables("authors ;"'objDataView.RowFilter = "au_lname <> 'Green ﺑﻪ ﻋﻼوه در ﺷﺮﻃﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ وارد ﻣﻲ ﻛﻨﻴﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻋﺒﺎرات ANDو ﻳﺎ ORﭼﻨﺪﻳﻦ ﺷﺮط را ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﺗﺮﻛﻴﺐ ﻛﺮده و ﺳﭙﺲ داده ﻫﺎ را ﺑﺮ اﺳﺎس ﺷﺮط ﻧﻬﺎﻳﻲ ﻧﻤﺎﻳﺶ دﻫﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ در ﺟﺪول authorsاﻓﺮادي را ﻧﻤﺎﻳﺶ ﻣـﻲ دﻫﺪ ﻛﻪ FirstNameآﻧﻬﺎ ﺑﺎ ﺣﺮف Dﺷﺮوع ﺷﺪه و LastNameآﻧﻬﺎ ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎ Greenﺑﺎﺷﺪ: = objDataView.RowFilter ;"'*"au_lname <> 'Green' AND au_fname LIKE 'D
ﻣﺘﺪ :Find ﺑﺮاي ﭘﻴﺪا ﻛﺮدن ﻳﻚ رﻛﻮرد ﺧﺎص از اﻃﻼﻋﺎت در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﻲ ﺗﻮاﻧﻴـﺪ از ﻣﺘـﺪ Findدر ﻛـﻼس DataViewاﺳـﺘﻔﺎده ﻛﻨﻴﺪ .اﻟﺒﺘﻪ ﻗﺒﻞ از ﻓﺮاﺧﻮاﻧﻲ اﻳﻦ ﻣﺘﺪ ،ﺑﺎﻳﺪ داده ﻫﺎي ﺟﺪول را ﺑﺮ ﺣﺴﺐ ﻓﻴﻠﺪي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺟـﺴﺘﺠﻮ را ﺑـﺮ اﺳـﺎس آن اﻧﺠـﺎم دﻫﻴـﺪ ﻣﺮﺗﺐ ﻛﻨﻴﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻗﺒﻞ از ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ،Findﺑﺎﻳﺪ داده ﻫﺎي ﻣﻮﺟﻮد در ﺟﺪول را ﺑﺮ اﺳﺎس ﺳﺘﻮﻧﻲ ﻛﻪ ﺣﺎوي ﻛﻠﻴـﺪ ﻣـﻮرد ﻧﻈﺮ ﺷﻤﺎﺳﺖ ﻣﺮﺗﺐ ﻛﻨﻴﺪ. ﺑﺮاي ﻣﺜـﺎل ﺗـﺼﻮر ﻛﻨﻴـﺪ ﻛـﻪ ﻣـﻲ ﺧﻮاﻫﻴـﺪ ﺑـﺎ اﺳـﺘﻔﺎده از objDataViewﻛـﻪ در ﻗـﺴﻤﺖ ﻗﺒـﻞ اﻳﺠـﺎد ﻛـﺮدﻳﻢ ،در ﺟـﺪول authorsﺑﻪ دﻧﺒﺎل رﻛﻮردي ﺑﮕﺮدﻳﺪ ﻛﻪ FirstNameآن ﺑﺮاﺑﺮ ﺑﺎ Annﺑﺎﺷﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر اﺑﺘﺪا ﺑﺎﻳﺪ ﺟﺪول را ﺑﺮ اﺳـﺎس ﻓﻴﻠﺪ au_fnameﻣﺮﺗﺐ ﻛﻨﻴﺪ ،ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ Findﺑﻪ دﻧﺒﺎل Annﺑﮕﺮدﻳﺪ .ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ روش اﻧﺠـﺎم اﻳـﻦ ﻛـﺎر را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ: ;int intPosition ;"objDataView.Sort = "au_fname ;)"intPosition = objDataView.Find("Ann
٦٣٣
ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ DataViewدر ﺟﺪول ﺑﻪ دﻧﺒﺎل ﻓﺮدي ﻣﻲ ﮔﺮدد ﻛﻪ FirstNameآن ﺑﺮاﺑﺮ ﺑﺎ Annﺑﺎﺷﺪ و ﺷﻤﺎره ي ﻣﻜﺎن آن را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .اﮔﺮ ﭼﻨﻴﻦ ﻓﺮدي در ﺟﺪول ﭘﻴﺪا ﻧﺸﺪ ،اﻳﻦ ﻣﺘﺪ ﻣﻘﺪار ﺗﻬﻲ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .دﻗﺖ ﻛﻨﻴﺪ ﺑﻪ ﻣﺤﺾ اﻳﻨﻜﻪ ﻣﺘـﺪ Find اوﻟﻴﻦ ﮔﺰﻳﻨﻪ را ﭘﻴﺪا ﻛﺮد ،ﻣﻜﺎن آن را ﺑﺮﮔﺮداﻧﺪه و از ﺟﺴﺘﺠﻮي اداﻣﻪ ي ﺟﺪول ﺻﺮﻓﻨﻈﺮ ﻣﻲ ﻛﻨﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﻣﻲ داﻧﻴﺪ ﻛﻪ ﺑﻴﺶ از ﻳـﻚ ﻓﺮم ﺑﺎ اﻳﻦ ﻧﺎم در ﺟﺪول وﺟﻮد دارد ﺑﺮاي ﻣﺸﺎﻫﺪﻫﻲ ﺗﻤﺎم آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ از روش ﻓﻴﻠﺘﺮ ﻛﺮدن ﻛﻪ ﺗﻮﺿﻴﺢ داده ﺷﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﻫﻤﭽﻨﻴﻦ اﻳﻦ ﻣﺘﺪ ﺑﻪ ﻛﻮﭼﻜﻲ و ﻳﺎ ﺑﺰرﮔﻲ ﺣﺮوف ﺣﺴﺎس ﻧﻴﺴﺖ و دﺳﺘﻮر ﺑﺎﻻ ﻫﺮ ﻓﺮدي ﻛﻪ ﻧﺎم او Annو ﻳـﺎ ANNو ﻳـﺎ … ﺑﺎﺷـﺪ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ. اﻟﺒﺘﻪ دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ ﻣﺘﺪ دﻗﻴﻘﺎً ﺑﻪ دﻧﺒﺎل ﻣﺘﻨﻲ ﻛﻪ وارد ﺷﺪه اﺳﺖ ﻣﻲ ﮔﺮدد ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ ﺗﻤﺎم ﻛﻠﻤﻪ و ﻳـﺎ ﻛﻠﻤـﺎﺗﻲ ﻛـﻪ ﻣـﻲ ﺧﻮاﻫﻴـﺪ ﺟﺴﺘﺠﻮ ﺑﺮ اﺳﺎس آن ﺻﻮرت ﮔﻴﺮد را ﺑﻪ ﺻﻮرت دﻗﻴﻖ در اﻳﻦ ﻗﺴﻤﺖ وارد ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ در ﺟﺪول ﺑﻪ دﻧﺒﺎل ﻓﺮدي ﺑﺎ ﻧﺎم ﺧﺎﻧﻮادﮔﻲ Del Castilloﺑﮕﺮدﻳﺪ ،ﻧﻤﻲ ﺗﻮاﻧﻴﺪ Delرا ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ ﻣﺘﺪ Findﺑﻔﺮﺳﺘﻴﺪ و اﻧﺘﻈﺎر داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ اﻳﻦ ﻧﺎم را ﺑﺮاي ﺷﻤﺎ ﺑﺮﮔﺮداﻧﺪ .ﺑﻠﻜﻪ ﺑﺎﻳﺪ ﻧﺎم ﻛﺎﻣﻞ او را در اﻳﻦ ﻗﺴﻤﺖ وارد ﻛﻨﻴﺪ ﻫﻤﺎﻧﻨﺪ دﺳﺘﻮر زﻳﺮ: ;"objDataView.Sort = "au_lname ;)"intPosition = objDataView.Find("del castillo در ﻗﺴﻤﺖ ﻗﺒﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از DataViewﻣﻲ ﺗﻮان ﻳﻚ ﺟﺪول را ﺑﺮ اﺳﺎس ﭼﻨﺪ ﻓﻴﻠﺪ ﻣﺮﺗﺐ ﻛﺮد .ﻫﻤـﻴﻦ ﻣـﻮرد ﺑﺮاي ﺟﺴﺘﺠﻮ ﻛﺮدن ﻧﻴﺰ ﺻﺎدق اﺳﺖ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮ اﺳﺎس ﭼﻨﺪ ﻓﻴﻠﺪ ﺑﻪ ﺟﺴﺘﺠﻮي داده ﻫﺎ ﺑﭙﺮدازﻳﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﻌـﺪ از ﻣﺮﺗﺐ ﻛﺮدن ﺟﺪول ،آراﻳﻪ اي از ﻧﻮع Objectاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ و ﺳﭙﺲ ﻣﻘﺪار ﻣﻮرد ﻧﺸﺮ ﺑﺮاي ﻫﺮ ﺳـﺘﻮن را در آن ﻗـﺮار ﻣـﻲ دﻫﻴـﺪ. ﺳﭙﺲ اﻳﻦ آراﻳﻪ را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ ﻣﺘﺪ Findﻣﻲ ﻓﺮﺳﺘﻴﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﺑﺒﻴﻨﻴﻢ ﻛﻪ آﻳﺎ ﻓﺮدي ﺑﺎ ﻧـﺎم Simonو ﻧـﺎم ﺧﺎﻧﻮادﮔﻲ Wattsدر ﺟﺪول وﺟﻮد دارد ﻳﺎ ﻧﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻗﻄﻌﻪ ﻛﺪ زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﻢ: ;int intPosition ;]Object[] arrValues = new Object[1 ;"objDataView.Sort = "au_fname, au_lname // Find the author named “Simon Watts”. ;"arrValues[0]= "Simon ;"arrValues[1] = "Watts ;)intPosition = objDataView.Find(arrValues ﻧﻜﺘﻪ :دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺣﺘﻤﺎً ﺑﺎﻳﺪ آراﻳﻪ اي از ﻧﻮع Objectﺑﻪ ﻣﺘﺪ Findﻓﺮﺳﺘﺎده ﺷﻮد .دﻟﻴﻞ اﻳﻦ اﻣﺮ ﻫـﻢ در اﻳـﻦ اﺳﺖ ﻛﻪ در .NETﺗﻤﺎم ﻧﻮع ﻫﺎي داده اي از ﻛﻼس Objectﻣﺸﺘﻖ ﻣﻲ ﺷﻮﻧﺪ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﺑﺨﻮاﻫﻴﻢ آراﻳﻪ اي داﺷﺘﻪ ﺑﺎﺷﻴﻢ ﻛﻪ ﻫﺮ ﻣﺘﻐﻴﺮي را ﺑﺘﻮاﻧﻲ در آن ﻗﺮار دﻫﻴﻢ ،ﺑﺎﻳﺪ آن را از ﻧﻮع Objectﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ .در اﻳﻦ ﺟﺎ ﻧﻴﺰ ﻻزم اﺳﺖ آراﻳﻪ اي داﺷﺘﻪ ﺑﺎﺷﻴﻢ ﻛﻪ ﺑﺘﻮاﻧﻴﻢ ﻣﺘﻐﻴﺮي از ﻫﺮ ﻧﻮع داده اي را در آن ﻗﺮار دﻫﻴﻢ .ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ ﺑﺨﻮاﻫﻴﺪ ﺟﺴﺘﺠﻮ در ﺟﺪول authorsرا ﺑـﻪ ﮔﻮﻧـﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ اﻓﺮادي ﻛﻪ ﺳﻦ آﻧﻬﺎ ﺑﺮاﺑﺮ ﺑﺎ 25و ﻧﻴﺰ ﻧﺎم آﻧﻬﺎ ﺑﺮاﺑﺮ ﺑﺎ Annاﺳﺖ را ﭘﻴﺪا ﻛﻨﻴﺪ .در اﻳﻦ ﺻﻮرت ﺑﺎﻳﺪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع ﻋﺪدي و ﻳﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع رﺷﺘﻪ اي را در آراﻳﻪ ﻗﺮار دﻫﻴﺪ.
اﺳﺘﻔﺎده از ﻛﻼﺳﻬﺎي ADO.NETدر ﻋﻤﻞ:
٦٣٤
ﺗﺎﻛﻨﻮن ﺑﺎ اﺻﻮل ﻛﺎر ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ADO.NETآﺷﻨﺎ ﺷﺪﻳﻢ و ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان داده ﻫﺎﻳﻲ را ﺑﻪ وﺳـﻴﻠﻪ ي اﻳﻦ ﻛﻼﺳﻬﺎ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ SQL Serverﺑﺪﺳﺖ آورده و ﻳﺎ در آﻧﻬﺎ وارد ﻛﺮد .اﻣﺎ ﺗﺎ اﻳﻦ ﻗﺴﻤﺖ از ﻓﺼﻞ ﻓﻘﻂ ذﻫﻦ ﺧـﻮد را ﺑﺎ ﻳﻚ ﺳﺮي از ﻣﻄﺎﻟﺐ ﺗﺌﻮري درﮔﻴﺮ ﻛﺮده ﺑﻮدﻳﻢ ،و ﺑﺮاي اﻳﻨﻜﻪ ﻣﻄﻤﺌﻦ ﺷﻮﻳﻢ ﻧﺤﻮه ي اﺳﺘﻔﺎده از اﻳﻦ ﻛﻼﺳﻬﺎ ،ﻣﺘﺪ ﻫﺎ ،ﺧﺎﺻﻴﺖ ﻫﺎ و … را درﺳﺖ درك ﻛﺮده اﻳﻢ ،ﺑﻬﺘﺮﻳﻦ راه اﻳﻦ اﺳﺖ ﻛﻪ از آﻧﻬﺎ در ﻳﻚ ﻣﺜﺎل ﻋﻤﻠﻲ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .در دو ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻗﺪرت DataSetﻫﺎ داده ﻫﺎ را از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺘﺨﺮاج ﻛﺮده و ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ ﺧﻮاﻫﻴﻢ داد .ﻣﻤﻜﻦ اﺳﺖ ﺑﻌﺪ از اﺗﻤﺎم اﻳـﻦ دو ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ،ﻻزم ﺑﺎﺷﺪ ﻛﻪ ﺑﻪ اول ﻓﺼﻞ ﺑﺮﮔﺮدﻳﺪ و ﻣﺠﺪداً ﺗﻤﺎم ﻣﻄﺎﻟﺒﻲ را ﻛﻪ در ﻣﻮرد ﻛﻼﺳﻬﺎي ADO.NETﻋﻨﻮان ﺷـﺪ را ﻣﺮور ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻃﻤﻴﻨﺎن ﺣﺎﺻﻞ ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ ﻣﻄﺎﻟﺐ ﺑﻪ ﻃﻮر ﻛﺎﻣﻞ در ذﻫﻦ ﺷﻤﺎ ﻗﺮار ﺧﻮاﻫﻨﺪ ﮔﺮﻓﺖ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ اول از ﻛﻼﺳـﻬﺎي SqlDataAdapter ،SqlConnection ،SqlCommandو ﻧﻴـﺰ DataSetاﺳﺘﻔﺎده ﻛﺮده و ﺑﻪ وﺳﻴﻠﻪ ي آﻧﻬﺎ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺳﺎده اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ داده ﻫﺎ را از ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺪﺳﺖ آورد و در ﻳﻚ ﻛﻨﺘﺮل DataGridﻧﻤﺎﻳﺶ دﻫﺪ .در واﻗﻊ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺧﻮاﻫﻴﻢ ﻧﻮﺷﺖ ،ﻋﻤﻠﻜﺮدي ﺑﺴﻴﺎر ﻣﺸﺎﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﻓﺼﻞ ﻗﺒﻞ ﺧﻮاﻫﺪ داﺷﺖ .اﻟﺒﺘﻪ ﺑﺎ اﻳﻦ ﺗﻔﺎوت ﻋﻤﺪه ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از وﻳﺰارد ،از ﻛﺪ ﻧﻮﻳﺴﻲ اﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد. ﻧﻜﺘﻪ :ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎي واﻗﻌﻲ ،ﻣﻌﻤﻮﻻ از وﻳﺰاردﻫﺎ و ﻛﺪ ﻧﻮﻳﺴﻲ ﺑﻪ ﺻﻮرت ﻫﻤﺰﻣﺎن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﺗﺎ ﺑﺘﻮاﻧﻨﺪ ﺑﻪ ﺳﺮﻋﺖ و ﺑﻪ راﺣﺘﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﺑﺎ اﻧﻌﻄﺎف ﭘﺬﻳﺮي ﺑﺎﻻ اﻳﺠﺎد ﻛﻨﻨﺪ .ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎﻳﻲ ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮدﻳﻢ را در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎ اﺳﺘﻔﺎده از ﻛﺪ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد .اﻟﺒﺘﻪ ﻧﺤﻮه ي اﺳﺘﻔﺎده از آﻧﻬﺎ در ﻫﺮ دو روش ﻳﻜﺴﺎن ﺧﻮاﻫﺪ ﺑﻮد .ﻫﻤﭽﻨﻴﻦ در ﻓـﺼﻞ ﻗﺒﻞ اﻏﻠﺐ از وﻳﺰاردﻫﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ ،در ﺻﻮرﺗﻲ ﻛﻪ در اﻳﻦ ﻓﺼﻞ ﺑﻴﺸﺘﺮ ﺑﺮ ﻛﺪ ﻧﻮﻳﺴﻲ ﺗﻤﺮﻛﺰ ﺧﻮاﻫﻴﻢ ﻛﺮد.
ﻛﺎرﺑﺮد DataSetدر ﺑﺮﻧﺎﻣﻪ: ﻗﺒﻞ از اﻳﻨﻜﻪ ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ ي اﻳﻦ ﻗﺴﻤﺖ رو ﺷﺮوع ﻛﻨﻴﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﺑﻪ ﺑﺮرﺳﻲ داده ﻫﺎي ﻛﻪ ﻣﻲ ﺧـﻮاﻫﻴﻢ در اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ ﻧﻤـﺎﻳﺶ دﻫﻴﻢ وﻧﻴﺰ راﺑﻄﻪ ي ﺑﻴﻦ آﻧﻬﺎ ﺑﭙﺮدازﻳﻢ .اﻃﻼﻋﺎت اﻳﻦ ﺑﺮﻧﺎﻣﻪ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ pubsدر SQL Server 2000اﺳﺘﺨﺮاج ﻣﻲ ﺷﻮﻧﺪ .اﻟﺒﺘﻪ اﮔﺮ از ﻧﺴﺨﻪ ﻫﺎي 7 ،2005و ﻳﺎ MSDEﺑﻪ ﺟﺎي SQL Server 2000اﺳﺘﻔﺎده ﻣـﻲ ﻛﻨﻴـﺪ ﻧﻴـﺰ ﺑﺎﻳـﺪ ﻫﻤﻴﻦ اﻃﻼﻋﺎت را در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ pubsﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ. اﻳﻦ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ اﻧﺘﺸﺎرات ﻓﺮﺿﻲ اﺳﺖ .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻟﻴﺴﺘﻲ از ﻧﻮﻳﺴﻨﺪﮔﺎن ،ﻛﺘﺎﺑﻬﺎﻳﻲ ﻛﻪ ﺗـﺎﻛﻨﻮن ﭼـﺎپ ﻛﺮده اﻧﺪ و ﻗﻴﻤﺖ ﻫﺮ ﻛﺪام را ﻧﻤﺎﻳﺶ دﻫﻴﻢ .در ﺷﻜﻞ 3-16اﻳﻦ ﺟﺪوﻟﻬﺎ را ﺑﻪ ﻫﻤﺮاه ﻓﻴﻠﺪ ﻫﺎي ﻣﻮﺟﻮد در ﻫﺮ ﻛﺪام و ﻧﻴﺰ راﺑﻄﻪ ﻫﺎي ﺑﻴﻦ آﻧﻬﺎ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻧﺎم و ﻧﺎم ﺧـﺎﻧﻮادﮔﻲ ﻧﻮﻳـﺴﻨﺪه را از ﺟـﺪول authorsﺑﺪﺳـﺖ آورده و ﺑﻪ ﻫﻤﺮاه ﻋﻨﻮان و ﻗﻴﻤﺖ ﻛﺘﺎب او ﻛﻪ در ﺟﺪول titlesﻗﺮار دارد ،در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ دﻫﻴﻢ .ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﻳﻚ ﻛﺘـﺎب ﻣـﻲ ﺗﻮاﻧﺪ ﺑﻴﺶ از ﻳﻚ ﻧﻮﻳﺴﻨﺪه داﺷﺘﻪ ﺑﺎﺷﺪ و ﻧﻴﺰ ﻳﻚ ﻧﻮﻳﺴﻨﺪه ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻴﺶ از ﻳﻚ ﻛﺘﺎب ﻧﻮﺷـﺘﻪ ﺑﺎﺷـﺪ ،اﻃﻼﻋـﺎت اﻳـﻦ دو ﺟـﺪول در ﺟﺪول دﻳﮕﺮي ﺑﻪ ﻧﺎم titleauthorﺑﻪ ﻳﻜﺪﻳﮕﺮ ﻣﺘﺼﻞ ﺷﺪه اﻧﺪ.
٦٣٥
ﺷﻜﻞ 3-16 ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ راﺑﻄﻪ ي ﻣﻮﺟﻮد ﺑﻴﻦ ﺟﺪاول و ﻧﻴﺰ اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ از آﻧﻬﺎ اﺳﺘﺨﺮاج ﻛﻨﻴﻢ دﺳﺘﻮر SELECTاي ﻛﻪ ﺑﺎﻳﺪ در اﻳـﻦ ﻣﻮرد اﺳﺘﻔﺎده ﻛﻨﻴﻢ ﻣﺸﺎﺑﻪ زﻳﺮ ﺧﻮاﻫﺪ ﺑﻮد: SELECT au_lname, au_fname, title, price FROM authors JOIN titleauthor ON authors.au_id = titleauthor.au_id JOIN titles ON titleauthor.title_id = titles.title_id ORDER BY au_lname, au_fname ﺧﻂ اول اﻳﻦ دﺳﺘﻮر ﻧﺎم ﻓﻴﻠﺪ ﻫﺎﻳﻲ را ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ از ﺟﺪاول اﺳﺘﺨﺮاج ﻛﻨﻴﻢ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ و ﺧﻂ دوم ﻫﻢ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ي ﻧﺎم ﺟﺪول اﺻﻠﻲ اﺳﺖ ﻛﻪ داده ﻫﺎ از آن اﺳﺘﺨﺮاج ﻣﻲ ﺷـﻮﻧﺪ .در اﻳـﻦ ﻗـﺴﻤﺖ داده ﻫـﺎ از دو ﺟـﺪول authorsو ﻧﻴـﺰ titles اﺳﺘﺨﺮاج ﻣﻲ ﺷﻮﻧﺪ ،اﻣﺎ ﺟﺪول authorsرا ﺑﻪ ﻋﻨﻮان ﺟﺪول اﺻﻠﻲ در ﻧﻈﺮ ﻣﻲ ﮔﻴﺮﻳﻢ. ﺧﻂ ﺳﻮم ﺑﻴﻦ ﺳﺘﻮن au_idدر ﺟﺪول authorsو ﻧﻴﺰ ﻫﻤﻴﻦ ﺳﺘﻮن در ﺟﺪول titleauthorراﺑﻄﻪ ﺑـﺮ ﻗـﺮار ﻣـﻲ ﻛﻨـﺪ .ﺑــﻪ اﻳـﻦ ﺗﺮﺗﻴــﺐ ﻫــﺮ زﻣـﺎن ﻛــﻪ ﻳــﻚ رﻛـﻮد از ﺟــﺪول authorsاﻧﺘﺨــﺎب ﺷـﻮد ،ﺗﻤــﺎم رﻛــﻮرد ﻫـﺎي ﻣﻮﺟــﻮد در ﺟــﺪول titleauthorﻛﻪ ﻣﻘﺪار ﺳﺘﻮن au_idآﻧﻬﺎ ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺪار اﻳﻦ ﺳﺘﻮن در رﻛﻮرد اﻧﺘﺨـﺎب ﺷـﺪه از ﺟـﺪول authors ﺑﺎﺷﺪ ﻧﻴﺰ اﻧﺘﺨﺎب ﺧﻮاﻫﻨﺪ ﺷﺪ. ﺧﻂ ﭼﻬﺎرم ﻧﻴﺰ ﻣﺎﻧﻨﺪ ﺧﻂ ﺳﻮم ،ﺑﻴﻦ ﺟﺪول titlesو ﺟﺪول titleauthorاز ﻃﺮﻳﻖ ﺳﺘﻮن title_idراﺑﻄﻪ ﺑﺮ ﻗﺮار ﻣﻲ ﻛﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﺮ زﻣﺎن ﻛﻪ ﻳﻚ رﻛﻮرد از ﺟﺪول titleauthorاﻧﺘﺨﺎب ﺷﻮد ،رﻛﻮرد ﻫﺎي ﻣﺘﻨﺎﻇﺮ آن در ﺟـﺪول titlesﻧﻴﺰ اﻧﺘﺨﺎب ﺧﻮاﻫﻨﺪ ﺷﺪ .ﺧﻂ آﺧﺮ ﻧﻴﺰ اﻃﻼﻋﺎت را ﺑﺮ اﺳﺎس ﻧﺎم ﺧﺎﻧﻮادﮔﻲ و ﺳﭙﺲ ﻧﺎم ،ﺑﻪ ﺻﻮرت ﺻﻌﻮدي ﻣﺮﺗﺐ ﻣﻲ ﻛﻨﺪ.
٦٣٦
ﻧﻜﺘﻪ :ﻣﻤﻜﻦ اﺳﺖ ﻛﻪ ﺗﻮﺿﻴﺤﺎت اﻳﻦ دﺳﺘﻮر SELECTﺑﺮاي درك آن ﻛﺎﻓﻲ ﻧﺒﺎﺷﺪ ،اﻣـﺎ در ﻫـﺮ ﺻـﻮرت ﺑـﺮاي اﺗﻤـﺎم اﻳـﻦ ﺑﺨـﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﺴﻨﺪه ﻣﻲ ﻛﻨﺪ .ﻣﺴﻠﻤﺎً ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ واﻗﻌﻲ ﺑﻨﻮﻳﺴﻴﺪ ،ﻧﻴﺎز ﺧﻮاﻫﻴﺪ داﺷـﺖ ﻛـﻪ ﻣﻔﻬـﻮم ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ راﺑﻄﻪ اي را درك ﻛﺮده ﺑﺎﺷﻴﺪ و ﻧﻴﺰ ﺑﺘﻮاﻧﻴﺪ دﺳﺘﻮرات SELECTﭘﻴﭽﻴـﺪه اي ﺑـﺮاي اﻧﺘﺨـﺎب داده ﻫـﺎ از ﭼﻨـﺪﻳﻦ ﺟﺪول ﺑﻨﻮﻳﺴﻴﺪ .ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻦ ﺻﻮرت ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﻛﺘﺎﺑﻬﺎﻳﻲ را در اﻳﻦ زﻣﻴﻨﻪ ﻧﻴﺰ ﻣﻄﺎﻟﻌﻪ ﻛﻨﻴﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﻣﺜﺎل DataSet (1ﺑﺎ اﺳﺘﻔﺎده از ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم DataSetExampleاﻳﺠﺎد ﻛﻨﻴﺪ. (2ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي ،Propertiesﺧﺎﺻﻴﺘﻬﺎي ﻓﺮم را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ:
ﺧﺎﺻﻴﺖ Sizeرا ﺑﺮاﺑﺮ ﺑﺎ 600; 230ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ StartPositionرا ﺑﺮاﺑﺮ ﺑﺎ CenterScreenﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textرا ﺑﺮاﺑﺮ ﺑﺎ Bound DataSetﻗﺮار دﻫﻴﺪ.
(3ﺑﺎ اﺳﺘﻔﺎده از ﻗﺴﻤﺖ Dataدر ﺟﻌﺒﻪ اﺑﺰار ،ﻳﻚ ﻛﻨﺘﺮل DataGridViewﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮده و ﺧﺎﺻﻴﺘﻬﺎي آن را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ:
ﺧﺎﺻﻴﺖ Nameرا ﺑﺮاﺑﺮ ﺑﺎ grdAuthorTitlesﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Anchorرا ﺑﺮاﺑﺮ ﺑﺎ Top, Left, Bottom, Rightﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Locationرا ﺑﺮاﺑﺮ ﺑﺎ 0;0ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Sizeرا ﺑﺮاﺑﺮ ﺑﺎ 592;203ﻗﺮار دﻫﻴﺪ.
(4وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس Form1را ﺑﺎز ﻛﺮده و اﺑﺘﺪا ﻓﻀﺎي ﻧﺎﻣﻬﺎﻳﻲ ﻛﻪ در ﻃﻮل ﺑﺮﻧﺎﻣﻪ ﺑﻪ آﻧﻬﺎ ﻧﻴﺎز ﺧﻮاﻫﻴﻢ داﺷـﺖ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر دﺳﺘﻮر زﻳﺮ را ﺑﻪ ﺑﺎﻻي ﺗﻌﺮﻳﻒ ﻛﻼس Form1اﺿﺎﻓﻪ ﻛﻨﻴﺪ: // Using Data and SqlClient namespaces... ;using System.Data ;using System.Data.SqlClient public partial class Form1 : Form { } (5در ﻣﺮﺣﻠﻪ ي ﺑﻌﺪ ﻻزم اﺳﺖ ﻛﻪ اﺷﻴﺎي ﻻزم ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ و درﻳﺎﻓﺖ داده ﻫﺎ را اﻳﺠﺎد ﻛﻨﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﻛـﺪ ﻫﺎي ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ ﻛﻪ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﻧﺎم ﻛﺎرﺑﺮي و ﻧﻴﺰ ﻛﻠﻤﻪ ي ﻋﺒﻮر در ConnectionStringﺑﻪ درﺳﺘﻲ وارد ﺷﺪه اﺳﺖ. public partial class Form1 : Form { ٦٣٧
SqlConnection objConnection = new SqlConnection( "server=localhost;database=pubs;" + "user id=sa;password="); SqlDataAdapter objDataAdapter = new SqlDataAdapter(); DataSet objDataSet = new DataSet(); public Form1() { دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ اﮔﺮ ﺳﺮور ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻛﻪ از اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ در ﻛﺎﻣﭙﻴﻮﺗﺮ دﻳﮕﺮي ﺑﻪ ﺟﺰ ﻛﺎﻣﭙﻴﻮﺗﺮي ﻛﻪ در ﺣﺎل اﺳـﺘﻔﺎده از آن:ﻧﻜﺘﻪ ﻫﻤﭽﻨـﻴﻦ ﺑﺎﻳـﺪ ﻣﻘـﺪار. ﺗﻐﻴﻴـﺮ دﻫﻴـﺪSQL Server را ﺑﻪ ﻧﺎم ﻛﺎﻣﭙﻴﻮﺗﺮ ﺣﺎويserver ﺑﺎﻳﺪ ﻣﻘﺪار ﭘﺎراﻣﺘﺮ،ﻫﺴﺘﻴﺪ ﻗﺮار دارد را ﻧﻴﺰ ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ﻛﻪ ﺑﻪ ﻳﻚ ﻧـﺎم ﻛـﺎرﺑﺮي و ﻛﻠﻤـﻪ ي ﻋﺒـﻮر ﻣﻨﺎﺳـﺐ درPassword وUser ID ﭘﺎراﻣﺘﺮﻫﺎي اﮔﺮ ﻧـﺎم ﻛـﺎرﺑﺮي. در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﺑﺮﻧﺎﻣﻪ ﻧﺨﻮاﻫﺪ ﺗﻮاﻧﺴﺖ ﺑﻪ داده ﻫﺎي ﻻزم در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﺪ.ﺳﺮور اﺷﺎره ﻛﻨﻨﺪ ذﻛﺮ ﻛﻨﻴـﺪ اﻣـﺎConnectionString را درPassword ﺑﺎﻳﺪ ﻗﺴﻤﺖ،ﻛﻪ در ﺳﺮور ﺗﻌﺮﻳﻒ ﻛﺮده اﻳﺪ ﻛﻠﻤﻪ ﻋﺒﻮر ﻧﺪارد Password=; ﺑﺮاي ﻣﺜﺎل.در ﻣﻘﺎﺑﻞ آن ﭼﻴﺰي ﻧﻨﻮﻳﺴﻴﺪ ﺑﺮﮔﺮدﻳﺪ و روي ﻧﻮار ﻋﻨﻮان آن دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗـﺎ ﻣﺘـﺪ ﻣﺮﺑـﻮط ﺑـﻪ روﻳـﺪادForm1 ( ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ6 : ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ. ﻓﺮم ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﺷﻮدLoad private void Form1_Load(object sender, EventArgs e) { // Set the SelectCommand properties... objDataAdapter.SelectCommand = new SqlCommand(); objDataAdapter.SelectCommand.Connection = objConnection; objDataAdapter.SelectCommand.CommandText = "SELECT au_lname, au_fname, title, price " + "FROM authors " + "JOIN titleauthor ON authors.au_id = " + "titleauthor.au_id " + "JOIN titles ON titleauthor.title_id = " + "titles.title_id " + "ORDER BY au_lname, au_fname"; objDataAdapter.SelectCommand.CommandType = CommandType.Text; // Open the database connection... objConnection.Open(); // Fill the DataSet object with data... objDataAdapter.Fill(objDataSet, "authors"); // Close the database connection... objConnection.Close();
٦٣٨
// Set the DataGridView properties // to bind it to our data... ;grdAuthorTitles.AutoGenerateColumns = true ;grdAuthorTitles.DataSource = objDataSet ;"grdAuthorTitles.DataMember = "authors // Clean up ;objDataAdapter = null ;objConnection = null } (7ﺑﺎ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﺘﻴﺠﻪ اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ 4-16ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد.
ﺷﻜﻞ 4-16 (8دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻛﻨﺘﺮل DataGridViewداراي ﺧﺎﺻﻴﺖ دروﻧﻲ ﻣﺮﺗﺐ ﻛﺮدن داده ﻫﺎ اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ روي ﻳﻜﻲ از ﻧﺎﻣﻬﺎي ﺳﺘﻮﻧﻬﺎ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ،داده ﻫﺎي ﻣﻮﺟﻮد در ﻓﺮم ﺑﺮ اﺳﺎس آن ﺳﺘﻮن ﻣﺮﺗﺐ ﻣﻲ ﺷﻮﻧﺪ .ﻫﻤﭽﻨﻴﻦ ﻛﻠﻴﻚ دوﺑـﺎره ﺑـﺮ روي ﻧﺎم ﻳﻚ ﺳﺘﻮن ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ داده ﻫﺎ ﺑﺮ ﺣﺴﺐ آن ﺳﺘﻮن ﺑﻪ ﺻﻮرت ﻧﺰوﻟﻲ ﻣﺮﺗﺐ ﺷﻮﻧﺪ. ﻧﻜﺘﻪ :در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻋﻠﺖ ﻛﻤﺒﻮد ﺟﺎ ﻛﺪ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻣﺪﻳﺮﻳﺖ ﺧﻄﺎﻫﺎ و اﺳﺘﺜﻨﺎ ﻫﺎي اﺣﺘﻤﺎﻟﻲ ﺣﺬف ﺷﺪه اﺳﺖ ،اﻣـﺎ ﺑﻬﺘـﺮ اﺳـﺖ در ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ ﻣﻲ ﻧﻮﻳﺴﻴﺪ اﻳﻦ ﻛﺪﻫﺎ را ﻧﻴﺰ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺸﺎﻫﺪه ي ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻓـﺼﻞ ﻳـﺎزدﻫﻢ "اﺷـﻜﺎل زداﻳﻲ و ﻛﻨﺘﺮل ﺧﻄﺎ در ﺑﺮﻧﺎﻣﻪ" ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺑﺮاي ﺷﺮوع ﻛﺎر اﺑﺘﺪا ﺑﺎﻳﺪ دو ﻓﻀﺎي ﻧﺎم زﻳﺮ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ: ;using System.Data ;using System.Data.SqlClient ٦٣٩
ﻓـــﻀﺎي ﻧـــﺎم System.Dataﺑـــﺮاي اﺳـــﺘﻔﺎده از ﻛﻼﺳـــﻬﺎي DataSetو DataViewو ﻓـــﻀﺎي ﻧـــﺎم System.Data.SqlClientﻧﻴــــــﺰ ﺑــــــﺮاي اﺳــــــﺘﻔﺎده از ﻛﻼﺳــــــﻬﺎي ،SqlDataAdapter SqlConnectionو SqlCommandﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﺪه اﻧﺪ. ﺳﭙﺲ ﺑﺎﻳﺪ اﺷﻴﺎﻳﻲ ﻛﻪ در ﻃﻮل ﺑﺮﻧﺎﻣﻪ ﺑﻪ آﻧﻬﺎ ﻧﻴﺎز دارﻳﻢ را اﻳﺠﺎد ﻛﻨﻴﻢ .ﻣﻤﻜﻦ اﺳﺖ ﺑﻌﺪﻫﺎ ﻫﻨﮕﺎم ﺗﻐﻴﻴﺮ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺨﻮاﻫﻴﻢ از اﻳـﻦ اﺷـﻴﺎ در ﭼﻨﺪﻳﻦ ﻣﺘﺪ از ﻛﻼس اﺳﺘﻔﺎده ﻧﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ آﻧﻬﺎ را ﺑﻪ ﺻﻮرت ﺳﺮاﺳﺮي در ﻛﻼس ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ: public partial class Form1 : Form { SqlConnection objConnection = new Connection("server=localhost;database=pubs;" + ;)"="User ID=sa;Password ;)(SqlDataAdapter objDataAdapter = new SqlDataAdapter ;)(DataSet objDataSet = new DataSet اوﻟﻴﻦ ﺷﻴﺊ اي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ اﻳﺠﺎد ﻛﻨﻴﻢ ﻳﻚ ﺷﻴﺊ از ﻛﻼس SqlConnectionاﺳﺖ ﺗﺎ ﺑﻪ وﺳﻴﻠﻪ ي آن ﺑﺘﻮاﻧﻴﻢ ﺑﻪ ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺘﺼﻞ ﺷﻮﻳﻢ .در اﻳﻨﺠﺎ ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ از ﻧﻮع SQL Serverاﺳﺖ و در ﻫﻤـﺎن ﻛـﺎﻣﭙﻴﻮﺗﺮي ﻗـﺮار دارد ﻛﻪ در ﺣﺎل اﺟﺮاي ﺑﺮﻧﺎﻣﻪ روي آن ﻫﺴﺘﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﺧﺎﺻﻴﺖ Serverرا ﺑﺮاﺑﺮ ﺑﺎ localhostﻗﺮار داده و ﻧﻴﺰ ﻣـﺸﺨﺺ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ از داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ pubsاﺳﺘﻔﺎده ﻛﻨﻴﻢ. ﺑﻌـــﺪ از اﻳﺠـــﺎد SqlConnectionﺑـــﺮاي ﺑﺮﻗـــﺮار ارﺗﺒـــﺎط ﺑـــﺎ ﺑﺎﻧـــﻚ اﻃﻼﻋـــﺎﺗﻲ ،ﺑﺎﻳـــﺪ ﻳـــﻚ ﺷـــﻴﺊ از ﻛـــﻼس SqlDataAdapterاﻳﺠــﺎد ﻛﻨــﻴﻢ ﺗــﺎ ﺑــﻪ وﺳــﻴﻠﻪ ي آن ﺑﺘــﻮاﻧﻴﻢ داده ا را از ﺑﺎﻧــﻚ اﻃﻼﻋــﺎﺗﻲ اﺳــﺘﺨﺮاج ﻛــﺮده و در ﻳــﻚ DataSetدر ﺣﺎﻓﻈﻪ ﻗﺮار دﻫﻴﻢ. در آﺧﺮ ﻧﻴﺰ ﺑﺎﻳﺪ ﻳﻚ ﺷﻴﺊ از ﻧﻮع DataSetاﻳﺠﺎد ﻛﻨﻴﻢ ﺗﺎ ﺑﻪ وﺳﻴﻠﻪ ي آن ﺑﺘﻮاﻧﻴﻢ داده ﻫﺎي درﻳﺎﻓﺖ ﺷﺪه از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را در ﺣﺎﻓﻈﻪ ﻧﮕﻬﺪاري ﻛﻨﻴﻢ .ﺑﻪ ﺧﺎﻃﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ اﻳﻦ ﺷﻴﺊ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺘﺼﻞ ﻧﻴﺴﺖ و ﺑﻌﺪ از درﻳﺎﻓﺖ داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز ،ارﺗﺒﺎط ﺧﻮد را ﻗﻄﻊ ﻣﻲ ﻛﻨﺪ. ﻧﻜﺘﻪ :در ﺑﻌﻀﻲ از ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ اﻳﻦ اﺷﻴﺎ را ﺑﻪ ﺻﻮرت ﺳﺮاﺳﺮي در ﻛﻼس ﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ .ﺑﻠﻜﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ آﻧﻬـﺎ را در ﻳـﻚ ﻣﺘﺪ اﻳﺠﺎد ﻛﺮده ،از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﻢ و ﺳﭙﺲ آﻧﻬﺎ را ﻧﺎﺑﻮد ﻛﻨﻴﻢ ﺗﺎ ﻓﻀﺎي اﺷﻐﺎل ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي آﻧﻬﺎ ﻧﻴﺰ آزاد ﺷﻮد .اﻣﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﻴﻢ ﻛﻪ داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ را ﺗﻐﻴﻴﺮ دﻫﺪ و ﺳﭙﺲ ﺑﺨﻮاﻫﻴﻢ اﻳﻦ ﺗﻐﻴﻴﺮات را در ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ وارد ﻛﻨﻴﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ اﻳﻦ اﺷﻴﺎ را ﺑﻪ ﺻﻮرت ﺳﺮاﺳﺮي ﺗﻌﺮﻳﻒ ﻛﻨﻴﻢ ﺗﺎ ﻫﻢ در ﺗﻮاﺑﻊ ﻣﺮﺑﻮط ﺑﻪ درﻳﺎﻓﺖ اﻃﻼﻋﺎت و ﻫﻢ در ﺗﻮاﺑﻊ ﻣﺮﺑﻮط ﺑﻪ ﻧﻮﺷﺘﻦ اﻃﻼﻋﺎت در ﺑﺎﻧﻚ ﺑﺘﻮاﻧﻴﻢ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﻢ. ﺑﻌﺪ از اﻳﺠﺎد اﺷﻴﺎي ﻣﻮرد ﻧﻴﺎز ،ﺑﺎﻳﺪ ﻛﺪي را ﻗﺒﻞ از ﻧﻤﺎﻳﺶ داده ﺷﺪن ﻓﺮم اﺟﺮا ﻛﻨﻴﻢ ﺗﺎ داده ﻫﺎ را از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ درﻳﺎﻓﺖ ﻛﺮده و آﻧﻬﺎ را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﺪ .ﺷﻴﺊ SqlDataAdapterﻣﺴﺌﻮل درﻳﺎﻓﺖ اﻃﻼﻋﺎت از ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ و ﻧﻤـﺎﻳﺶ آن روي ﻓـﺮم ﺑﺮﻧﺎﻣﻪ اﺳﺖ و اﻳﻦ ﻛﺎر را ﺑﺎ اﺳﺘﻔﺎده از ﺷﻴﺊ SqlCommandاي اﻧﺠﺎم ﻣﻲ دﻫﺪ ﻛﻪ در ﺧﺎﺻـﻴﺖ SelectCommandآن ﻗﺮار دارد .ﺑﻨـﺎﺑﺮاﻳﻦ اﺑﺘـﺪا ﺑﺎﻳـﺪ ﻳـﻚ ﺷـﻴﺊ از ﻧـﻮع SqlCommandاﻳﺠـﺎد ﻛـﺮده و ﺑﻌـﺪ از ﺗﻨﻈـﻴﻢ ﺧﺎﺻـﻴﺖ ﻫـﺎي آن ،آن را در SelectCommandﻗﺮار دﻫﻴﻢ. // Set the SelectCommand properties... ;)(objDataAdapter.SelectCommand = new SqlCommand
٦٤٠
;objDataAdapter.SelectCommand.Connection = objConnection = objDataAdapter.SelectCommand.CommandText "SELECT au_lname, au_fname, title, price " + "FROM authors " + "JOIN titleauthor ON authors.au_id = titleauthor.au_id " + "JOIN titles ON titleauthor.title_id = titles.title_id " + ;""ORDER BY au_lname, au_fname = objDataAdapter.SelectCommand.CommandType ;CommandType.Text ﺑﺮاي اﻳﻦ ﻛﺎر ﻧﻴﺰ اﺑﺘﺪا ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر newﻳـﻚ ﺷـﻴﺊ ﺟﺪﻳـﺪ از ﻧـﻮع SqlCommandاﻳﺠـﺎد ﻛـﺮده و آن را در ﺧﺎﺻـﻴﺖ SelectCommandﻗﺮار ﻣﻲ دﻫﻴﻢ .ﺳﭙﺲ ﺧﺎﺻﻴﺖ Connectionاﻳﻦ ﺷﻴﺊ ﺟﺪﻳﺪ را ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﻨﻴﻢ .اﻳـﻦ ﺧﺎﺻـﻴﺖ ﺑﺮاي اﻳﺠﺎد اﺗﺼﺎل ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﻪ ﻛﺎر ﻣﻲ رود. ﺑﻌﺪ از اﻳﻦ ﺑﺎﻳﺪ دﺳﺘﻮر SQLاي ﻛﻪ ﺑﺮاي درﻳﺎﻓﺖ داده ا از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﻪ ﻛﺎر ﻣﻲ رود را ﻣﺸﺨﺺ ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﺘﻦ ﺣـﺎوي دﺳﺘﻮر را در ﺧﺎﺻﻴﺖ CommandTextﻗﺮار داده و ﺑﺎ ﺗﻨﻈﻴﻢ ﺧﺎﺻﻴﺖ CommandTypeﻧﻴﺰ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨـﻴﻢ ﻛـﻪ اﻳـﻦ ﻣﺘﻦ ﺷﺎﻣﻞ ﻳﻚ دﺳﺘﻮر SQLاﺳﺖ. ﺑﻌﺪ از اﺗﻤﺎم ﺗﻤﺎم اﻳﻦ اﻣﻮر ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺘﺼﻞ ﺷﺪه ،داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز را درﻳﺎﻓﺖ ﻛﺮده و ﺳﭙﺲ اﺗﺼﺎل را ﻗﻄﻊ ﻛﻨﻴﻢ. ﺑﺮاي ﻣﺘﺼﻞ ﺷﺪن ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ از ﻣﺘﺪ Openدر ﻛﻼس SqlConnectionاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ: // Open the database connection... ;)(objConnection.Open ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ Fillدر ﻛﻼس SqlDataAdapterداده ﻫﺎي ﻣﻮرد ﻧﻴﺎز را از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ درﻳﺎﻓـﺖ ﻛـﺮده و در ﺷﻴﺊ اﻳﺠﺎد ﺷﺪه از ﻛﻼس DataSetدر ﺣﺎﻓﻈﻪ ﻗﺮار ﻣﻲ دﻫﻴﻢ .ﻫﻨﮕﺎم ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ Fillﻧﻴﺰ ،ﻧﺎم ﺷﻴﺊ DataSetو ﻧﻴﺰ ﻧﺎم ﺟﺪوﻟﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ داده ﻫﺎ در آن ﻗﺮار ﺑﮕﻴﺮﻧﺪ را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ ﻣﺘﺪ ارﺳﺎل ﻣﻲ ﻛﻨﻴﻢ .در اﻳﻨﺠﺎ ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ داده ﻫـﺎ از ﭼﻨﺪﻳﻦ ﺟﺪول ﻣﺨﺘﻠﻒ درﻳﺎﻓﺖ ﺷﺪه اﻧﺪ ﺑﺮاي ﻧﺎم ﺟﺪول از ﻧﺎم authorsاﺳﺘﻔﺎده ﻛﺮده اﻳﻢ. // Fill the DataSet object with data... ;)"objDataAdapter.Fill(objDataSet, "authors ﺑﻌﺪ از اﻳﻦ ﻛﺎر ﻧﻴﺰ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ Closeاز ﻛﻼس ،SqlConnectionاﺗﺼﺎل اﻳﺠﺎد ﺷﺪه ﺑﻪ ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ را ﻗﻄـﻊ ﻣﻲ ﻛﻨﻴﻢ. // Close the database connection... ;)(objConnection.Close اﻟﺒﺘﻪ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﻧﻴﺰ ﮔﻔﺘﻢ ،ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺪون اﻳﻨﻜﻪ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ Openﺑـﻪ ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ ﻣﺘـﺼﻞ ﺷـﺪه و ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ Closeاﺗﺼﺎل را ﻗﻄﻊ ﻛﻨﻴﻢ از ﻣﺘﺪ Fillﺑﺮاي ﭘﺮ ﻛﺮدن DataSetاﺳﺘﻔﺎده ﻛﻨـﻴﻢ .در اﻳـﻦ ﺣﺎﻟـﺖ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺘﺪ Fillﻣﺘﻮﺟﻪ ﺷﻮد ﻛﻪ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺘﺼﻞ ﻧﻴﺴﺖ ،ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﻣﺘﺪ Fillرا ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده و ﺑﻌـﺪ از اﺗﻤﺎم ﻛﺎر ﻧﻴﺰ اﺗﺼﺎل را ﻗﻄﻊ ﻣﻲ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺪون ﻫـﻴﭻ ﻣـﺸﻜﻠﻲ ،ﺧﻄﻬـﺎي ﻣﺮﺑـﻮط ﻓﺮاﺧـﻮاﻧﻲ ﻣﺘـﺪﻫﺎي Openو Closeرا از ﺑﺮﻧﺎﻣﻪ ﺣﺬف ﻛﻨﻴﻢ.
٦٤١
ﺑﻌﺪ از درﻳﺎﻓﺖ داده ﻫﺎ ﺑﺎﻳﺪ ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل DataGridViewرا ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧـﺪ داده ﻫـﺎي ﻣﻮﺟـﻮد را در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ دﻫﺪ .اوﻟﻴﻦ ﺧﺎﺻﻴﺖ ،ﺧﺎﺻﻴﺖ AutoGenerateColumnsاﺳـﺖ .ﺑـﺎ ﻗـﺮار دادن ﻣﻘـﺪار trueدر اﻳـﻦ ﺧﺎﺻﻴﺖ در ﺣﻘﻴﻘﺖ ﺑﻪ DataGridViewاﺟﺎزه ﻣﻲ دﻫﻴﻢ ﻛﻪ ﻫﻨﮕﺎم ﻧﻤﺎﻳﺶ داده ﻫﺎ ﺑﺮ روي ﻓﺮم ،ﺳـﺘﻮﻧﻬﺎي ﻣـﻮرد ﻧﻴـﺎز را ﺑـﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﻛﻨﺪ .ﺑﻌﺪ از اﻳﻦ ﻧﻴﺰ ﺑﺎﻳﺪ ﺧﺎﺻﻴﺖ DataSourceرا ﺑﺮاﺑﺮ ﺑﺎ ﻧﺎم DataSetاي ﻗﺮار دﻫـﻴﻢ ﻛـﻪ ﻣـﻲ ﺧﻮاﻫﻴﻢ ﻛﻨﺘﺮل DataGridViewداده ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺧﻮد را از آن درﻳﺎﻓﺖ ﻛﻨﺪ: //Set the DataGridView properties to bind it to our data... ;grdAuthorTitles.AutoGenerateColumns = true ;grdAuthorTitles.DataSource = objDataSet ;"grdAuthorTitles.DataMember = "authors ﺧﺎﺻــﻴﺖ DataMemberرا ﻧﻴــﺰ ﺑﺎﻳــﺪ ﺑﺮاﺑــﺮ ﺑــﺎ ﻧــﺎم ﺟــﺪوﻟﻲ از DataSetﻗــﺮار دﻫــﻴﻢ ﻛــﻪ ﻣــﻲ ﺧــﻮاﻫﻴﻢ داده اي آن در DataGridViewﻧﻤﺎﻳﺶ داده ﺷﻮد ،ﻛﻪ در اﻳﻨﺠﺎ ﺑﺮاﺑﺮ ﺑﺎ ﺟﺪول authorsاﺳﺖ. در آﺧﺮ ﻧﻴﺰ ﺑﺮاي اﻳﻨﻜﻪ ﺣﺎﻓﻈﻪ ي اﺷﻐﺎل ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ را آزاد ﻛﻨﻴﻢ ،آﻧﻬﺎ را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺪار nullﻗﺮار ﻣﻲ دﻫﻴﻢ: // Clean up ;objDataAdapter = null ;objConnection = null ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﻨﮕﺎم اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ،اﺑﺘﺪا DataGridViewﺑﺎ اﺳﺘﻔﺎده از اﻟﮕﻮي داده ﻫـﺎﻳﻲ ﻛـﻪ در DataSetﻗـﺮار دارد ﺳﺘﻮن ﻫﺎي ﻻزم ﺑﺮاي ﻧﻤﺎﻳﺶ داده ﻫﺎ در ﻓﺮم را اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ )اﻳﻦ اﻟﮕﻮ ﻫﻨﮕﺎم ﭘﺮ ﺷﺪن DataSetﺑﻪ وﺳـﻴﻠﻪ ي ﻣﺘـﺪ Fill اﻳﺠﺎد ﻣﻲ ﺷﻮد( .ﺳﭙﺲ ﺗﻤﺎم داد ﻫﺎ از DataSetدرﻳﺎﻓﺖ ﺷﺪه و در DataGridViewﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﻨﺪ ﺷﺪ. در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﺑﺎ ﺑﻌﻀﻲ از ﺧﺎﺻﻴﺖ ﻫﺎ و ﻣﺘﺪﻫﺎي DataGridViewﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آﻧﻬـﺎ ﻣـﻲ ﺗـﻮاﻧﻴﻢ ﻧﺤـﻮه ي ﻧﻤﺎﻳﺶ داده ﻫﺎ در ﺻﻔﺤﻪ را ﺗﻐﻴﻴﺮ دﻫﻴﻢ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺗﻐﻴﻴﺮ ﺧﺎﺻﻴﺖ ﻫﺎي DataGridView (1در زﻳﺮ ﻟﻴﺴﺘﻲ از ﺗﻐﻴﻴﺮاﺗﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ در ﻳﻚ DataGridViewاﻧﺠﺎم دﻫﻴﺪ ﺗﺎ داده ﻫﺎ ﺑﻬﺘﺮ ﻧﻤـﺎﻳﺶ داده ﺷـﻮﻧﺪ، آورده ﺷﺪه اﺳﺖ:
ﻋﻨﻮان ﺳﺘﻮﻧﻬﺎ را ﺑﺮاﺑﺮ ﺑﺎ ﻧﺎم ﻣﻨﺎﺳﺒﻲ ﻗﺮار دﻫﻴﺪ. اﻧﺪازه ي ﻫﺮ ﺳﺘﻮن را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ ﺑﺘﻮان ﺑﻪ راﺣﺘﻲ داده ﻫﺎي آن را ﻣﻄﺎﻟﻌﻪ ﻛﺮد. رﻧﮓ ﻫﺮ ردﻳﻒ از اﻃﻼﻋﺎت را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ ﺑﻪ ﺻﻮرت ﻣﺘﻤﺎﻳﺰ ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ. داده ﻫﺎ را در ﺳﺘﻮﻧﻬﺎ ﺑﻪ ﺻﻮرت راﺳﺖ-ﭼﻴﻦ ﻗﺮار دﻫﻴﺪ )ﺑﺮاي ﻧﻤﺎﻳﺶ داده ﻫﺎي ﻋﺪدي(.
ﺑﺮاي اﻧﺠﺎم اﻳﻦ ﻣﻮارد ،در ﻣﺘﺪ Form_Loadﺗﻐﻴﻴﺮات ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را اﻋﻤﺎل ﻛﻨﻴﺪ: )private void Form1_Load(object sender, EventArgs e {
٦٤٢
// Set the SelectCommand properties... objDataAdapter.SelectCommand = new SqlCommand(); objDataAdapter.SelectCommand.Connection = objConnection; objDataAdapter.SelectCommand.CommandText = "SELECT au_lname, au_fname, title, price " + "FROM authors " + "JOIN titleauthor ON authors.au_id = " + "titleauthor.au_id " + "JOIN titles ON titleauthor.title_id = " + "titles.title_id " + "ORDER BY au_lname, au_fname"; objDataAdapter.SelectCommand.CommandType = CommandType.Text; // Open the database connection... objConnection.Open(); // Fill the DataSet object with data... objDataAdapter.Fill(objDataSet, "authors"); // Close the database connection... objConnection.Close(); // Set the DataGridView properties // to bind it to our data... grdAuthorTitles.AutoGenerateColumns = true; grdAuthorTitles.DataSource = objDataSet; grdAuthorTitles.DataMember = "authors"; // Declare and set // the currency header alignment property... DataGridViewCellStyle objAlignRightCellStyle = new DataGridViewCellStyle(); objAlignRightCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; // Declare and set the alternating rows style... DataGridViewCellStyle objAlternatingCellStyle = new DataGridViewCellStyle(); objAlternatingCellStyle.BackColor = Color.WhiteSmoke; grdAuthorTitles.AlternatingRowsDefaultCellStyle = objAlternatingCellStyle; // Declare and set the style for currency cells ... DataGridViewCellStyle objCurrencyCellStyle = new DataGridViewCellStyle();
٦٤٣
objCurrencyCellStyle.Format = "c"; objCurrencyCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; // Change column names // and styles using the column name grdAuthorTitles.Columns["price"].HeaderCell.Value = "Retail Price"; grdAuthorTitles.Columns["price"].HeaderCell.Style = objAlignRightCellStyle; grdAuthorTitles.Columns["price"].DefaultCellStyle = objCurrencyCellStyle; // Change column names // and styles using the column index grdAuthorTitles.Columns[0].HeaderText = "Last Name"; grdAuthorTitles.Columns[1].HeaderText = "First Name"; grdAuthorTitles.Columns[2].HeaderText = "Book Title"; grdAuthorTitles.Columns[2].Width = 225; // Clean up objDataAdapter = null; objConnection = null; objCurrencyCellStyle = null; objAlternatingCellStyle = null; objAlignRightCellStyle = null; } ﺑﺎ ﻣﻘﺎﻳـﺴﻪ. ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ5-16 ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ داده ﻫﺎ در ﺟﺪوﻟﻲ ﻣﺸﺎﺑﻪ ﺷﻜﻞ.( ﻣﺠﺪداً ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ2 . ﻣﺘﻮﺟﻪ ﺗﻔﺎوت ﻫﺎي اﻳﺠﺎد ﺷﺪه در ﺑﺮﻧﺎﻣﻪ ﺧﻮاﻫﻴﺪ ﺷﺪ4-16 ي اﻳﻦ ﺷﻜﻞ ﺑﺎ ﺷﻜﻞ
5-16 ﺷﻜﻞ
٦٤٤
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اﺳــﺘﻴﻞ ﻫــﺮ ﺳــﻠﻮل در ﻛﻨﺘــﺮل DataGridViewﺑــﻪ ﺻــﻮرت وراﺛﺘــﻲ ﺗﻌﻴــﻴﻦ ﻣــﻲ ﺷــﻮد .ﺑــﻪ ﻋﺒــﺎرت دﻳﮕــﺮ در ﻫــﺮ ﻛﻨﺘــﺮل DataGridViewﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ اﺳﺘﻴﻞ ﻛﻠﻲ ﻣﺸﺨﺺ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﻳﻦ اﺳﺘﻴﻞ ﺑﻪ ﺗﻤﺎم ﺳﻠﻮﻟﻬﺎ ﺑﻪ ارث ﻣﻲ رﺳﺪ و ﺗﻤﺎم ﺳﻠﻮﻟﻬﺎي اﻳﻦ ﻛﻨﺘﺮل داراي ﻫﻤﻴﻦ اﺳﺘﻴﻞ ﺧﻮاﻫﻨﺪ ﺑﻮد ﻣﮕﺮ اﻳﻨﻜﻪ ﺑﻪ ﺻﻮرت ﻣﺸﺨﺺ آن را ﺗﻐﻴﻴﺮ دﻫﻴﻢ .در اﻳﻦ ﻛﻨﺘـﺮل ﺗﻤـﺎم ﻣﺠﻤﻮﻋـﻪ ﻫﺎي ﻋﻀﻮ ﻧﻴﺰ داراي ﺧﺎﺻﻴﺘﻲ ﺑﻪ ﻫﻤﻴﻦ ﺻﻮرت ﻫﺴﺘﻨﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ اﺳﺘﻴﻞ ﭘﻴﺶ ﻓﺮض ﻳﻚ DataGridViewرا ﺑﺮاﺑـﺮ ﺑـﺎ اﺳﺘﻴﻞ Aﻗﺮار دﻫﻴﻢ ،ﺗﻤﺎم ﺳﻠﻮﻟﻬﺎي اﻳﻦ ﻛﻨﺘﺮل داراي اﺳﺘﻴﻞ Aﺧﻮاﻫﻨﺪ ﺑﻮد .اﻣﺎ اﮔـﺮ اﺳـﺘﻴﻞ ﭘـﻴﺶ ﻓـﺮض ﻳـﻚ ﺳـﺘﻮن از ﺳـﻠﻮﻟﻬﺎ در DataGridViewرا ﺑﺮاﺑﺮ ﺑﺎ اﺳﺘﻴﻞ Bﻗﺮار دﻫﻴﻢ ،ﺗﻤﺎم ﺳﻠﻮﻟﻬﺎﻳﻲ ﻛﻪ در آن ﺳﺘﻮن ﻗﺮار دارﻧﺪ داراي اﺳﺘﻴﻞ Bﺧﻮاﻫﻨﺪ ﺷﺪ. اﺳﺘﻴﻞ ﻫﺮ ﺳﻠﻮل ﺑﻪ وﺳﻴﻠﻪ ي ﺷﻴﺊ اي از ﻧﻮع DataGridViewCellStyleﺗﻌﻴﻴﻦ ﻣﻲ ﺷـﻮد .ﺑﻨـﺎﺑﺮاﻳﻦ ﺑـﺮاي ﺷـﺮوع ﺷﻴﺊ اي از ﻧﻮع اﻳﻦ ﻛﻼس اﻳﺠﺎد ﻛﺮده و ﺧﺎﺻﻴﺖ Alignmentآن را ﺑﺮاﺑﺮ ﺑﺎ MiddleRightﻗﺮار ﻣﻲ دﻫﻴﻢ. // Declare and set // the currency header alignment property... DataGridViewCellStyle objAlignRightCellStyle = new ;)(DataGridViewCellStyle = objAlignRightCellStyle.Alignment ;DataGridViewContentAlignment.MiddleRight ﻗﺒﻞ از ﻫﺮ ﭼﻴﺰ ﺑﻬﺘﺮ اﺳﺖ ﺟﺪول اﻃﻼﻋﺎت در ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﻛﻪ ردﻳﻔﻬﺎ ﺑﻪ ﺻﻮرت ﻳﻜﻲ در ﻣﻴﺎن رﻧﮓ ﻣﺘﻔﺎوﺗﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ ،ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺧﻮاﻧﺪن اﻃﻼﻋﺎت ﺳﺎده ﺗﺮ ﻣﻲ ﺷﻮد .ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺎﻓﻲ اﺳﺖ رﻧﮓ ردﻳﻔﻬﺎي ﻓﺮد را ﺑﻪ ﺻـﻮرت ﻗﺒﻠـﻲ ﻗـﺮار داده و رﻧـــﮓ ردﻳﻔﻬـــﺎي زوج را ﺗﻐﻴﻴـــﺮ دﻫـــﻴﻢ .ﺑـــﺮاي اﻳﺠـــﺎد ﺗﻐﻴﻴـــﺮ در ردﻳﻔﻬـــﺎي ﻓـــﺮد ﻛـــﺎﻓﻲ اﺳـــﺖ ﺷـــﻴﺊ اي از ﻧـــﻮع DataGridViewCellStyleاﻳﺠﺎد ﻛﺮده و ﺑﻌﺪ از ﺗﻨﻈـﻴﻢ ﻗـﺴﻤﺘﻬﺎي ﻣـﻮرد ﻧﻈـﺮ در اﻳـﻦ ﺷـﻴﺊ ،آن را در ﺧﺎﺻـﻴﺖ AlternatingRowsDefaultCellStyleﻗﺮار دﻫﻴﻢ .در اﻳﻨﺠﺎ ﻧﻴﺰ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ روش رﻧـﮓ ردﻳﻔﻬـﺎي زوج را ﺑﻪ ﺻﻮرت WhiteSmokeدر ﻣﻲ آورﻳﻢ: // Declare and set the alternating rows style... DataGridViewCellStyle objAlternatingCellStyle = new ;)(DataGridViewCellStyle ;objAlternatingCellStyle.BackColor = Color.WhiteSmoke = grdAuthorTitles.AlternatingRowsDefaultCellStyle ;objAlternatingCellStyle در ﻣﺮﺣﻠﻪ ي ﺑﻌﺪ ﻧﻴﺰ ﺑﺎ اﻳﺠﺎد ﻳﻚ ﺷﻴﺊ ﺟﺪﻳﺪ از ﻛﻼس ،DataGridViewCellStyleآن را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻨﻈـﻴﻢ ﻣـﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﺪ اﻋﺪاد ﻣﺎﻟﻲ را ﺑﺎ ﻗﺎﻟﺐ ﺻﺤﻴﺢ و ﻧﻴﺰ از راﺳﺖ ﺑﻪ ﭼﭗ ﻧﻤﺎﻳﺶ دﻫﺪ. // Declare and set the style for currency cells ... DataGridViewCellStyle objCurrencyCellStyle = new ;)(DataGridViewCellStyle ;"objCurrencyCellStyle.Format = "c = objCurrencyCellStyle.Alignment ;DataGridViewContentAlignment.MiddleRight
٦٤٥
ﺳﭙﺲ ﺑﺎﻳﺪ ﻋﻨﻮان ﺳﺘﻮن priceرا ﺑﻪ ﻧﺎﻣﻲ ﺑﺎ ﻣﻌﻨﻲ ﺗﺮ ﺗﻐﻴﻴﺮ داده و دو اﺳﺘﻴﻠﻲ ﻛﻪ در ﻣﺮﺣﻠﻪ ي ﻗﺒﻞ اﻳﺠـﺎد ﻛـﺮده ﺑـﻮدﻳﻢ را )ﻳﻜـﻲ ﺑﺮاي ﻧﻤﺎﻳﺶ اﻋﺪاد ﻣﺎﻟﻲ و دﻳﮕﺮي ﺑﺮاي ﺗﻨﻈﻴﻢ ﻧﺤﻮه ي ﻧﻤﺎﻳﺶ ﺗﻴﺘﺮ ﻳﻜﻲ از ﺳﺘﻮﻧﻬﺎ( ﺑﻪ ﺳﻠﻮﻟﻬﺎي ﻣﻮرد ﻧﻈﺮ ﻧﺴﺒﺖ دﻫﻴﻢ. // Change column names and styles using the column name = grdAuthorTitles.Columns["price"].HeaderCell.Value ;""Retail Price = grdAuthorTitles.Columns["price"].HeaderCell.Style ;objAlignRightCellStyle = grdAuthorTitles.Columns["price"].DefaultCellStyle ;objCurrencyCellStyle در اﻧﺘﻬﺎ ﻧﻴﺰ ﻋﻨﻮان دﻳﮕﺮ ﺳﺘﻮﻧﻬﺎ را ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ HeaderTextو ﻳﺎ HeaderText.Valueﺑﻪ ﻧﺎم ﺑﺎ ﻣﻌﻨﻲ ﺗﺮي ﺗﻐﻴﻴﺮ ﺧﻮاﻫﻴﻢ داد .ﻫﻤﭽﻨﻴﻦ ﺑﺮاي اﻳﻨﻜﻪ ﻋﻨﻮان ﻛﺘﺎﺑﻬﺎ ﺑﻪ ﺳﺎدﮔﻲ ﻗﺎﺑﻞ ﺧﻮاﻧﺪ ﺑﺎﺷﺪ ،ﻃﻮل ﺳﻠﻮﻟﻬﺎي آن را اﻓﺰاﻳﺶ ﻣﻲ دﻫﻴﻢ: the column index ;""Last Name ;""First Name ;""Book Title
// Change column names and styles using = grdAuthorTitles.Columns[0].HeaderText = grdAuthorTitles.Columns[1].HeaderText = grdAuthorTitles.Columns[2].HeaderText ;grdAuthorTitles.Columns[2].Width = 225
در اﻳــﻦ ﻗــﺴﻤﺖ ﻣــﺸﺎﻫﺪه ﻛﺮدﻳــﺪ ﻛــﻪ ﭼﮕﻮﻧــﻪ ﻣــﻲ ﺗــﻮان داده ﻫــﺎي درون ﻳــﻚ DataSetرا ﺑــﻪ ﻳــﻚ ﻛﻨﺘــﺮل ﻣﺎﻧﻨــﺪ DataGridViewﻣﺘﺼﻞ ﻛﺮد .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،اﻳﻦ ﻣﺜﺎل را ﻣﻘﺪاري ﺑـﺴﻂ داده و ﺳـﻌﻲ ﺧـﻮاﻫﻴﻢ ﻛـﺮد داده ﻫـﺎي درون ﻳﻚ ﻛﻨﺘﺮل DataViewرا ﺑﻪ ﭼﻨﺪﻳﻦ ﻛﻨﺘﺮل ﻣﺘﺼﻞ ﻛﺮده و ﺳـﭙﺲ ﺑـﺎ اﺳـﺘﻔﺎده از ﺷـﻴﺊ CurrencyManager ﺑﻴﻦ آﻧﻬﺎ ﺣﺮﻛﺖ ﻛﻨﻴﻢ .اﻣﺎ ﻗﺒﻞ از اﻳﻨﻜﻪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ را ﺷﺮوع ﻛﻨﻴﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﻣﻘﺪاري در راﺑﻄﻪ ﺑﺎ اﺗﺼﺎل داده ،ﻧﺤﻮه ي اﻧﺠﺎم اﻳﻦ ﻛﺎر ﺑـﺎ ﻛﻨﺘﺮﻟﻬﺎي ﺳﺎده اي ﻣﺎﻧﻨﺪ TextBoxو ﭼﮕﻮﻧﮕﻲ ﺟﺎ ﺑﻪ ﺟﺎ ﺷﺪن ﺑﻴﻦ رﻛﻮرد ﻫﺎ ﺻﺤﺒﺖ ﻛﻨﻴﻢ.
اﺗﺼﺎل داده ﻫﺎ: ﻛﻨﺘﺮل DataGridViewﺑﻬﺘﺮﻳﻦ ﻛﻨﺘﺮل ﺑﺮاي ﻧﻤﺎﻳﺶ ﺗﻤﺎم داده ﻫﺎ در ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﺳﺖ .اﻳﻦ ﻛﻨﺘﺮل ﻋﻼوه ﺑﺮ اﻳﻦ ﻗﺎﺑﻠﻴﺖ ،ﻣـﻲ ﺗﻮاﻧﺪ ﺑﻪ راﺣﺘﻲ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه دﻫﺪ ﻛﻪ داده ﻫﺎ را ﺣﺬف و ﻳﺎ وﻳﺮاﻳﺶ ﻛﻨﺪ و ﻳﺎ داده ﻫﺎي ﺟﺪﻳﺪي را در ﺟﺪول وارد ﻛﻨﺪ .اﻣﺎ ﺑﺎ اﻳﻦ وﺟـﻮد ﻣﻤﻜﻦ اﺳﺖ در ﺷﺮاﻳﻂ ﺑﺨﻮاﻫﻴﺪ در ﻫﺮ ﻟﺤﻈﻪ ﻓﻘﻂ ﻳﻚ ﺳﻄﺮ از داده ﻫﺎ را در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ دﻫﻴﺪ .در اﻳﻦ ﻣﻮاﻗﻊ ﺗﻨﻬﺎ راه اﻳﻦ اﺳـﺖ ﻛـﻪ ﺗﻌﺪادي ﻛﻨﺘﺮل ﺳﺎده ﻣﺎﻧﻨﺪ TextBoxﺑﺮ روي ﻓﺮم ﻗﺮار داده و ﻫﺮ ﻳﻚ از آﻧﻬﺎ را ﺑﻪ ﻳﻜﻲ از ﻓﻴﻠـﺪ ﻫـﺎي ﺟـﺪول در ﺑﺮﻧﺎﻣـﻪ ﻣﺘـﺼﻞ ﻛﻨﻴﻢ ،ﺳﭙﺲ در ﻫﺮ ﻟﺤﻈﻪ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﺳﻄﺮ از اﻃﻼﻋﺎت را در اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﻗﺮار دﻫﻴﻢ .ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ روش ﻣﻲ ﺗﻮاﻧﻴـﺪ ﻛﻨﺘﺮل ﺑﻴﺸﺘﺮي روي داده ﻫﺎ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ،اﻣﺎ ﻛﺪي ﻛﻪ ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ در ﺑﺮﻧﺎﻣﻪ وارد ﻛﻨﻴﺪ ﻧﻴﺰ ﻣﺸﻜﻞ ﺗﺮ ﺧﻮاﻫﺪ ﺑﻮد ،زﻳﺮا ﺑﺎﻳﺪ ﺑﺮﻧﺎﻣﻪ اي ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ ﻫﺮ ﻳﻚ از ﻛﻨﺘﺮﻟﻬﺎي روي ﻓﺮم را ﺑﻪ ﻓﻴﻠﺪ ﻣﺮﺑﻮط ﻣﺘﺼﻞ ﻛﻨﺪ .ﺳﭙﺲ ﻗﺴﻤﺘﻲ را در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻃﺮاﺣﻲ ﻛﻨﻴﺪ ﻛﻪ ﺑﻪ وﺳـﻴﻠﻪ آن ﺑﺘﻮان در ﺑﻴﻦ ﺳﻄﺮ ﻫﺎي اﻃﻼﻋﺎت ﺣﺮﻛﺖ ﻛﺮد .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي اﻧﺠﺎم اﻳﻦ ﻛﺎر ﻻزم اﺳﺖ ﻛﻪ درﮔﻴﺮ اﻣﻮري ﻣﺎﻧﻨﺪ اﺗﺼﺎل ﻛﻨﺘـﺮل ﻫـﺎي ﺳﺎده ﺑﻪ داده ﻫﺎ و ﻧﻴﺰ ﻣﺪﻳﺮﻳﺖ اﻳﻦ اﺗﺼﺎﻻت ﺷﻮﻳﻢ.
٦٤٦
در ﺑﺤﺚ راﺟﻊ ﺑﻪ اﺗﺼﺎل داده ﻫﺎ ،ﻣﻨﻈﻮر از ﻛﻨﺘﺮل ﻫﺎي ﺳﺎده ﻛﻨﺘﺮل ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ در ﻫﺮ ﻟﺤﻈﻪ ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﻨﺪ ﻣﻘـﺪار ﻳـﻚ داده را در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﻨﺪ ،ﺑﺮاي ﻣﺜﺎل ﻣﺎﻧﻨﺪ RadioButton ،CheckBox ،TextBoxو ﻳﺎ ﻛﻨﺘﺮل ﻫﺎﻳﻲ از اﻳﻦ ﻗﺒﻴـﻞ. ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ ListBox ،comboBoxو ﻳﺎ DataGridViewﻛﻪ در ﻫﺮ ﻟﺤﻈﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻴﺶ از ﻳﻚ آﻳﺘﻢ از داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ را ﻧﻤﺎﻳﺶ دﻫﻨﺪ ﺑﻪ ﻋﻨﻮان ﻛﻨﺘﺮﻟﻬﺎي ﺳﺎده در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻧﻤﻲ ﺷﻮﻧﺪ.
BindingContextو :CurrencyManager ﻫﺮ ﻓﺮم داراي ﺷﻴﺊ اي از ﻧﻮع BindingContextاﺳﺖ ﻛﻪ اﺗﺼﺎﻻت ﻛﻨﺘﺮل ﻫﺎي درون ﻓﺮم را ﻣﺪﻳﺮﻳﺖ ﻣﻲ ﻛﻨﺪ .ﺑﻨـﺎﺑﺮاﻳﻦ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ ﺑﻪ ﺻﻮرت دروﻧﻲ داراي ﭼﻨﻴﻦ ﺷﻴﺊ اي اﺳﺖ ،ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ آن را در ﻛﺪ اﻳﺠﺎد ﻛﻨﻴﺪ. ﺷﻴﺊ BindingContextدر ﺣﻘﻴﻘﺖ ﻳﻚ ﻣﺠﻤﻮﻋﻪ از اﺷﻴﺎ از ﻧﻮع CurrencyManagerرا ﻣـﺪﻳﺮﻳﺖ ﻣـﻲ ﻛﻨـﺪ. وﻇﻴﻔﻪ ي CurrencyManagerﻧﻴﺰ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﻴﻦ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ ﺑـﻪ ﻣﻨﺒـﻊ داده اي )ﻣـﺜﻼ (DataSetﻣﺘـﺼﻞ ﻫﺴﺘﻨﺪ و ﻣﻨﺒﻊ داده اي ،و ﻧﻴﺰ اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﺑﺎ دﻳﮕﺮ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ در ﻓﺮم ﺑﻪ ﻫﻤﺎن ﻣﻨﺒﻊ داده اي ﻣﺘـﺼﻞ ﻫـﺴﺘﻨﺪ ﻫﻤـﺎﻫﻨﮕﻲ ﺑﺮﻗـﺮار ﻛﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮان ﻣﻄﻤﺌﻦ ﺷﺪ ﻛﻪ ﺗﻤﺎم اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ در ﻓﺮم در ﺣﺎل ﻧﻤﺎﻳﺶ داده ﻫﺎي ﻣﻮﺟﻮد در ﻳﻚ ﺳـﻄﺮ ﻫـﺴﺘﻨﺪ .ﺷـﻴﺊ CurrencyManagerﻣــﻲ ﺗﻮاﻧــﺪ اﻳــﻦ ﻫﻤــﺎﻫﻨﮕﻲ را ﺑــﻴﻦ ﻛﻨﺘــﺮل ﻫــﺎ و ﻣﻨــﺎﺑﻊ داده اي ﻣﺨﺘﻠﻔــﻲ ﻣﺎﻧﻨــﺪ ،DataSet DataView ،DataTableو ﻳﺎ DataSetViewاﻳﺠﺎد ﻛﻨﺪ .ﻫﺮ زﻣﺎن ﻛﻪ ﻳﻚ ﻣﻨﺒﻊ داده اي ﺟﺪﻳﺪ ﺑﻪ ﻓـﺮم ﺑﺮﻧﺎﻣـﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ ،ﻳﻚ ﺷﻴﺊ CurrencyManagerﺟﺪﻳﺪ ﻧﻴﺰ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﻣﻲ ﺷﻮد .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴـﺐ ﻛـﺎر ﺑـﺎ ﻛﻨﺘـﺮل ﻫﺎي ﻣﺘﺼﻞ ﺑﻪ ﻳﻚ ﻣﻨﺒﻊ داده اي در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﺑﺴﻴﺎر ﺳﺎده ﺧﻮاﻫﺪ ﺷﺪ. اﮔﺮ در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد از ﭼﻨﺪﻳﻦ ﻣﻨﺒﻊ داده اي ﻣﺨﺘﻠﻒ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع CurrencyManager اﻳﺠﺎد ﻛﺮده و آن را ﺑﻪ CurrencyManagerﻣﺮﺑﻮط ﺑﻪ ﻣﻨﺒﻊ داده اي ﻣﻮرد ﻧﻈـﺮ ﺧـﻮد در BindingContext ارﺟــﺎع دﻫﻴــﺪ .ﺑــﻪ اﻳــﻦ ﺗﺮﺗﻴــﺐ ﺑــﻪ وﺳــﻴﻠﻪ ي اﻳــﻦ ﻣﺘﻐﻴﻴــﺮ ﻣــﻲ ﺗﻮاﻧﻴــﺪ ﺑــﻪ CurrencyManagerﻣــﻮرد ﻧﻈــﺮ ﺧــﻮد در BindingContextدﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ و ﺑﻪ وﺳﻴﻠﻪ ي آن ﻧﻤﺎﻳﺶ داده ﻫﺎ را ﺑﺮ روي ﻓﺮم ﻛﻨﺘﺮل ﻛﻨﻴﺪ. ﻗﻄﻌــﻪ ﻛــﺪ زﻳــﺮ ﺑــﺎ اﺳــﺘﻔﺎده از ﺷــﻴﺊ DataSetاي ﻛــﻪ در ﺑﺮﻧﺎﻣــﻪ ي ﻗﺒــﻞ اﻳﺠــﺎد ﻛــﺮده ﺑــﻮدﻳﻢ ،ﻳــﻚ ارﺟــﺎع ﺑــﻪ ﺷــﻴﺊ CurrencyManagerاي ﻛﻪ ﻣﻨﺒﻊ داده اي ﻣﺮﺑﻮط ﺑﻪ ﺟﺪول authorsرا ﻛﻨﺘﺮل ﻣﻲ ﻛﺮد اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ .ﺑـﺮاي اﻳـﻦ ﻛــﺎر اﺑﺘــﺪا ﻳــﻚ ﻣﺘﻐﻴﻴــﺮ از ﻛــﻼس CurrencyManagerاﻳﺠــﺎد ﻣــﻲ ﻛﻨــﻴﻢ .ﺳــﭙﺲ ﻣﻘــﺪار اﻳــﻦ ﻣﺘﻐﻴﻴــﺮ را ﺑﺮاﺑــﺮ ﺑــﺎ CurrenyManagerﻣﺮﺑﻮط ﺑﻪ ﻣﻨﺒﻊ داده اي objDataSetدر BindinContextﻗﺮار ﻣﻲ دﻫـﻴﻢ .اﻟﺒﺘـﻪ دﻗﺖ ﻛﻨﻴﺪ ﺷﻴﺊ اي ﻛﻪ در BindingContextذﺧﻴﺮه ﻣﻲ ﺷﻮد از ﻧﻮع CurrencyManagerﻧﻴـﺴﺖ و ﺑﺎﻳـﺪ ﺑـﺎ اﺳﺘﻔﺎده از ﻋﻤﻠﮕﺮ )( آن را ﺑﻪ ﺻﻮرت ﺻﺮﻳﺢ ﺑﻪ CurrencyManagerﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ: ;CurrencyManager objCurrencyManager = objCurrencyManager ;)](CurrencyManager)(this.BindingContext[objDataSet ﺑﻌﺪ از اﻳﻨﻜﻪ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﺪ ،ارﺟﺎﻋﻲ ﺑﻪ اﻳﻦ ﺷﻴﺊ اﻳﺠﺎد ﻛﺮدﻳﻢ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ Positionﻣﻮﻗﻌﻴﺖ رﻛـﻮرد ﺟﺎري 1را ﻛﻨﺘﺮل ﻛﻨﻴﻢ .ﺑﺮاي ﻣﺜﺎل ﻛﺪ زﻳﺮ ﻣﻮﻗﻌﻴﺖ رﻛﻮرد ﺟﺎري را ﻳﻚ واﺣﺪ اﻓﺰاﻳﺶ ﻣﻲ دﻫﺪ:
1ﻣﻨﻈﻮر از رﻛﻮرد ﺟﺎري در CurrencyManagerﻳﻚ ﻣﻨﺒﻊ داده اي ،رﻛﻮردي اﺳﺖ ﻛﻪ ﺗﻤﺎم ﻛﻨﺘﺮل ﻫﺎي ﺳﺎده اي از ﻓﺮم ﻛـﻪ ﺑـﻪ اﻳـﻦ ﻣﻨﺒـﻊ داده اي ﻣﺘﺼﻞ ﺷﺪه اﻧﺪ ﺑﺎﻳﺪ اﻃﻼﻋﺎت آن را رﻛﻮرد را ﻧﻤﺎﻳﺶ دﻫﻨﺪ.
٦٤٧
;objCurrencyManager.Position += 1 و ﻳﺎ دﺳﺘﻮر زﻳﺮ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﺗﻤﺎم ﻛﻨﺘﺮل ﻫﺎي ﺳﺎده اي ﻛﻪ ﺑﻪ objDataSetﻣﺘﺼﻞ ﺷﺪه اﻧﺪ ،اﻃﻼﻋـﺎت رﻛـﻮرد ﻗﺒﻠـﻲ را ﻧﻤﺎﻳﺶ دﻫﻨﺪ: ;objCurrencyManager.Position -= 1 ﻫﻤﭽﻨﻴﻦ ﺑﺮاي ﻧﻤﺎﻳﺶ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ اوﻟﻴﻦ رﻛﻮرد در objDataSetﻣﻲ ﺗﻮاﻧﻴﻢ از ﻛﺪ زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﻢ: ;objCurrencyManager.Position = 0 ﺧﺎﺻﻴﺖ Countدر ﻛﻼس CurrencyManagerﺣﺎوي ﺗﻌﺪاد رﻛﻮرد ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ در ﻣﻨﺒﻊ داده اي ﻛﻪ ﺑﻪ وﺳـﻴﻠﻪ ي CurrencyManagerﻣﺪﻳﺮﻳﺖ ﻣﻲ ﺷﻮد وﺟﻮد دارد .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي ﻧﻤﺎﻳﺶ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ رﻛﻮرد آﺧﺮ در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻛﺪ زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ: ;objCurrencyManager.Position = objCurrencyManager.Count - 1 دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﻛﺪ از ﺗﻌﺪاد رﻛﻮرد ﻫﺎي ﻣﻮﺟﻮد ﻣﻨﻬﺎي ﻳﻚ ﺑﺮاي رﻓﺘﻦ ﺑﻪ آﺧﺮﻳﻦ رﻛﻮرد اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ .دﻟﻴﻞ اﻳﻦ ﻛﺎر اﻳﻦ اﺳﺖ ﻛﻪ اﻧﺪﻳﺲ رﻛﻮرد ﻫﺎ در اﻳﻦ ﺷﻴﺊ از ﺻﻔﺮ ﺷﺮوع ﻣﻲ ﺷﻮد ،ﺑﻨﺎﺑﺮاﻳﻦ اﻧﺪﻳﺲ رﻛﻮرد آﺧﺮ ﺑﺮاﺑﺮ ﺑﺎ ﺗﻌﺪاد ﻛﻞ رﻛﻮرد ﻫﺎ ﻣﻨﻬـﺎي ﻳـﻚ ﺧﻮاﻫـﺪ ﺑﻮد.
اﺗﺼﺎل ﻛﻨﺘﺮل ﻫﺎ: ﺑﺮاي اﺗﺼﺎل ﻳﻚ ﻛﻨﺘﺮل ﺑﻪ ﻳﻚ ﻣﻨﺒﻊ داده اي ،ﺑﺎﻳﺪ از ﺧﺎﺻﻴﺖ DataBindingsدر آن ﻛﻨﺘﺮل اﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﻳﻦ ﺧﺎﺻـﻴﺖ از ﻛﻼس DatabindingsCollectionاﺳﺖ و ﺧﻮد ﻧﻴﺰ داراي ﭼﻨﺪﻳﻦ ﺧﺎﺻﻴﺖ و ﻣﺘﺪ ﻣﺨﺘﻠﻒ اﺳﺖ .اﻣﺎ در اﻳﻦ ﻗﺴﻤﺖ از ﻣﺘﺪ Addآن اﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد. اﻳﻦ ﻣﺘﺪ ﺳﻪ ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻛﺮده و ﺑﻪ ﺻﻮرت زﻳﺮ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد: object.DataBindings.Add(propertyName, ;)dataSource, dataMember اﻳﻦ ﭘﺎراﻣﺘﺮ ﻫﺎ ﺑﺮاي ﻣﻮارد زﻳﺮ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ:
objectﻧﺎم ﻛﻨﺘﺮﻟﻲ اﺳﺖ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻳﻚ اﺗﺼﺎل ﺟﺪﻳﺪ ﺑﺮاي آن اﻳﺠﺎد ﻛﻨﻴﻢ. propertyNameﺣﺎوي ﻧﺎم ﺧﺎﺻﻴﺘﻲ اﺳﺖ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ در ﻃﻮل ﺑﺮﻧﺎﻣﻪ ﻣﻘﺪار ﺧﻮد را از ﻣﻨﺒﻊ داده اي درﻳﺎﻓﺖ ﻛﻨﺪ. dataSourceﻧﺎم ﻣﻨﺒﻊ داده اي ﻛﻪ اﺳﺖ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ اﻃﻼﻋﺎت ﻣﻮرد ﻧﻴﺎز ﺑﺮاي اﻳﻦ ﻛﻨﺘـﺮل را از آن درﻳﺎﻓـﺖ ﻛﻨـﻴﻢ و ﻣﻲ ﺗﻮاﻧﺪ ﺷﺎﻣﻞ ﻳﻚ DataTable ،DataView ،DataSetو ﻳﺎ ﻫﺮ ﻣﻨﺒﻊ داده اي دﻳﮕﺮي ﺑﺎﺷﺪ. dataMemberﻣــﺸﺨﺺ ﻛﻨﻨــﺪه ي ﻧــﺎم ﻓﻴﻠــﺪي از ﻣﻨﺒــﻊ داده اي اﺳــﺖ ﻛــﻪ ﻣــﻲ ﺧــﻮاﻫﻴﻢ آن را ﺑــﻪ ﺧﺎﺻــﻴﺖ propertyNameاز ﻛﻨﺘﺮل ﻣﺘﺼﻞ ﻛﻨﻴﻢ.
٦٤٨
ﻣﺜــﺎﻟﻲ از ﻧﺤــﻮه ي اﺳــﺘﻔﺎده از ﻣﺘــﺪ Addدر ﻗﻄﻌــﻪ ﻛــﺪ زﻳــﺮ آورده ﺷــﺪه اﺳــﺖ .ﻛــﺪ زﻳــﺮ ﺧﺎﺻــﻴﺖ Textدر ﻛﻨﺘــﺮل txtFirstNameرا ﺑﻪ ﻓﻴﻠﺪ au_fnameاز ﺷﻴﺊ objDataViewﻣﺘﺼﻞ ﻣﻲ ﻛﻨﺪ: txtFirstName.DataBindings.Add("Text", ;)"objDataView, "au_fname در ﻣﻮاﻗﻌﻲ ﻣﻤﻜﻦ اﺳﺖ ﺑﻌﺪ از اﻳﺠﺎد اﺗﺼﺎل در ﻳﻚ ﻛﻨﺘﺮل ﺑﺨﻮاﻫﻴﺪ ﺗﻤﺎم اﺗﺼﺎﻻت آن ﺑﺎ ﻣﻨﺎﺑﻊ داده اي را ﺣﺬف ﻛﻨﻴﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻣﺘﺪ Clearدر ﻛﻼس ControlBindingsCollectionاﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻳﻦ ﻣﺘﺪ ﺗﻤﺎم اﺗﺼﺎﻻﺗﻲ ﻛـﻪ ﺑﺮاي ﺧﺎﺻﻴﺘﻬﺎي ﻣﺨﺘﻠﻒ ﻳﻚ ﻛﻨﺘﺮل ﺗﻌﺮﻳﻒ ﺷﺪه ﺑﻮد را ﺣﺬف ﻣﻲ ﻛﻨﺪ .ﻧﺤﻮه ي اﺳﺘﻔﺎده از اﻳﻦ ﻣﺘﺪ در ﻛﺪ زﻳﺮ ﻧﺸﺎن داده ﺷﺪه اﺳﺖ: ;)(txtFirstName.DataBindings.Clear ﺣـــــﺎل ﻛـــــﻪ ﺑـــــﺎ اﺷـــــﻴﺎي ControlBindingsCollection ،BindingContextو ﻧﻴـــــﺰ CurrencyManagerآﺷﻨﺎ ﺷﺪﻳﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﻧﺤﻮه ي اﺳﺘﻔﺎده از آﻧﻬﺎ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﻧﻴﺰ ﻣﺸﺎﻫﺪه ﻛﻨﻴﻢ.
ﻣﺜﺎل اﻳﺠﺎد اﺗﺼﺎل: ﺑﺮاي ﻣﺜﺎﻟﻲ ﻛﻪ در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد ،ﻓﻘﻂ از ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ ﻣﻌﺮﻓﻲ ﺷﺪ اﺳـﺘﻔﺎده ﻧﺨـﻮاﻫﻴﻢ ﻛﺮد ،ﺑﻠﻜﻪ ﻛﻼس ﻫﺎي DataView ،SqlCommandو Sqlparameterرا ﻧﻴﺰ ﺑﻪ ﻛﺎر ﺧﻮاﻫﻴﻢ ﺑﺮد. ﻧﻜﺘﻪ :در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ از ﭘﺮس و ﺟﻮﻳﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻞ اﻳﺠﺎد ﻛﺮدﻳﻢ ،اﺳﺘﻔﺎده ﻛﺮده و ﻧﺎم و ﻧﺎم ﺧﺎﻧﻮادﮔﻲ ﻫﺮ ﻧﻮﻳـﺴﻨﺪه ،ﻋﻨـﺎوﻳﻦ ﻛﺘﺎﺑﻬﺎي ﭼﺎپ ﺷﺪه از او و ﻧﻴﺰ ﻗﻴﻤﺖ ﻫﺮ ﻛﺪام را در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ ﺧﻮاﻫﻴﻢ داد .اﻳﻦ ﻣﺜﺎل ﺑﺎ ﻣﺜﺎل ﻗﺒﻠﻲ ﻓﻘﻂ از اﻳﻦ ﻟﺤﺎظ ﺗﻔﺎوت دارد ﻛﻪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ در ﻫﺮ ﻟﺤﻈﻪ ﻓﻘﻂ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ رﻛﻮرد را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺗﺼﺎل ﻛﻨﺘﺮﻟﻬﺎي ﺳﺎده ﺑﻪ ﻣﻨﺒﻊ داده اي (1ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ وﻳﻨﺪوزي ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم BindingExampleاﻳﺠﺎد ﻛﻨﻴﺪ. (2ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل ToolTipﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .اﻳﻦ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻧﻴﺰ ﻣﺎﻧﻨﺪ ﺗﻤﺎم ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي دﻳﮕﺮ ﺑﻪ ﻗﺴﻤﺖ ﭘﺎﻳﻴﻦ ﺑﺨﺶ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ Form1اﺿﺎﻓﻪ ﺧﻮاﻫﺪ ﺷﺪ. (3ﺑﺮ روي ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﻧﺘﺨﺎب ﺷﻮد .ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠـﺮه ي Propertiesﺧﺎﺻـﻴﺘﻬﺎي آن را ﺑـﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ:
ﺧﺎﺻﻴﺖ FormBorderStyleرا ﺑﺮاﺑﺮ ﺑﺎ FixedDialogﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ MaximizeBoxرا ﺑﺮاﺑﺮ ﺑﺎ Falseﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ MinimizeBoxرا ﺑﺮاﺑﺮ ﺑﺎ Falseﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Sizeرا ﺑﺮاﺑﺮ ﺑﺎ 430;360ﻗﺮار دﻫﻴﺪ.
٦٤٩
ﺧﺎﺻﻴﺖ StartPositionرا ﺑﺮاﺑﺮ ﺑﺎ CenterScreenﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textرا ﺑﺮاﺑﺮ ﺑﺎ Binding Controlsﻗﺮار دﻫﻴﺪ.
(4در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ ﻛﻨﺘﺮل ﻫﺎﻳﻲ را ﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮده و ﺳﭙﺲ ﺧﺎﺻﻴﺘﻬﺎي ﻣﺨﺘﻠﻒ آﻧﻬﺎ را ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ ﺗﺎ ﻓﺮم ﺑﺮﻧﺎﻣـﻪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ 6-16ﺷﻮد. اﻳﻦ ﻣﺮاﺣﻞ ﺑﻪ اﻳﻦ دﻟﻴﻞ ﻃﻲ ﻣﻲ ﺷﻮﻧﺪ ﺗﺎ ﻇﺎﻫﺮ ﺑﺮﻧﺎﻣﻪ ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي واﻗﻌﻲ ﺷﻮد .ﺑﺎ اﻳﻦ وﺟﻮد ،اﻳـﻦ ﻣﺮاﺣـﻞ اﻫﻤﻴـﺖ زﻳﺎدي ﻧﺪارﻧﺪ و در ﺻﻮرت ﻟﺰوم ﻣﻲ ﺗﻮاﻧﻴﺪ از آﻧﻬﺎ ﺻﺮﻓﻨﻈﺮ ﻛﺮده و ﺧﻮدﺗﺎن ﻓﺮﻣﻲ را ﻣﺸﺎﺑﻪ ﺷﻜﻞ 6-16اﻳﺠﺎد ﻛﻨﻴﺪ .اﻟﺒﺘـﻪ در اﻳﻦ ﺻﻮرت دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ اﺳﺎﻣﻲ ﻛﻨﺘﺮل ﻫﺎ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ آﻧﭽﻪ ﺑﺎﺷﻨﺪ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻋﻨﻮان ﺷﺪه اﺳﺖ .در ﻏﻴﺮ اﻳﻦ ﺻـﻮرت ﻣﻤﻜﻦ اﺳﺖ در اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﻣﺸﻜﻞ ﻣﻮاﺟﻪ ﺷﻮﻳﺪ.
ﺷﻜﻞ 6-16 (5ﻳﻚ ﻛﻨﺘﺮل GroupBoxﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮده و ﺧﺎﺻﻴﺘﻬﺎي آن را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ:
ﺧﺎﺻﻴﺖ Locationرا ﺑﺮاﺑﺮ ﺑﺎ 8;8ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Sizeرا ﺑﺮاﺑﺮ ﺑﺎ 408;128ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textرا ﺑﺮاﺑﺮ ﺑﺎ Authors && Titlesﻗﺮار دﻫﻴﺪ.
ﻧﻜﺘﻪ :ﺑﺮاي ﻧﻤﺎﻳﺶ ﻋﻼﻣﺖ & در ﻋﻨﻮان ﻳﻚ ﻛﻨﺘﺮل GroupBoxﺑﺎﻳﺪ از ﻋﻼﻣﺖ && اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﺳﺘﻔﺎده از ﻳﻚ & در ﻋﻨﻮان ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﺎراﻛﺘﺮ ﺑﻌﺪ از آن ﺑﺎ زﻳﺮﺧﻂ ﻧﻤﺎﻳﺶ داده ﺷﻮد. (6ﭼﻬﺎر ﻛﻨﺘﺮل Labelﺑﺎ ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﻛﻪ در ﺟﺪول زﻳﺮ ﻋﻨﻮان ﺷﺪه اﺳﺖ را ﺑﻪ ﻛﻨﺘﺮل GroupBox1اﺿﺎﻓﻪ ﻛﻨﻴﺪ:
٦٥٠
AutoSize
Size
Text
Name
Location
False
Last Name
64;16
8;26
Label1
False
First Name
64;16
8;50
Label2
False
Book Title
56;16
8;74
Label3
False
Price
64;16
8;98
Label4
(7ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﭼﻬﺎر ﻛﻨﺘﺮل TextBoxﻧﻴﺰ ﺑﻪ GroupBox1در ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛـﺮده و ﺧﺎﺻـﻴﺘﻬﺎي آن را ﺑﺮ اﺳﺎس ﺟﺪول زﻳﺮ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ: Size
ReadOnly
Name
Location
True
88;20
72;24
txtLastName
True
88;20
72;48
txtFirstName
False
328;20
72;72
txtBookTitle
False
48;20
72;96
txtPrice
(8ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻛﻨﺘﺮل GroupBoxدﻳﮕﺮي ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﺮده و ﺧﺎﺻﻴﺘﻬﺎي آن را ﻃﺒـﻖ ﻟﻴـﺴﺖ زﻳـﺮ ﺗﻨﻈـﻴﻢ ﻛﻨﻴﺪ:
ﺧﺎﺻﻴﺖ Locationرا ﺑﺮاﺑﺮ ﺑﺎ 8;144ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Sizeرا ﺑﺮاﺑﺮ ﺑﺎ 408;168ﻗﺮار دﻫﻴﺪ. ﺧﺎﺻﻴﺖ Textرا ﺑﺮاﺑﺮ ﺑﺎ Navigationﻗﺮار دﻫﻴﺪ.
(9دو ﻛﻨﺘﺮل Labelﺑﻪ GroupBox2اﺿﺎﻓﻪ ﻛﺮده و ﺑﺮ اﺳﺎس ﺟﺪول زﻳﺮ آن را ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ: AutoSize
Text
Size
Location
Name
False
Field
64;16
8;23
Label5
False
Search Criteria
80;16
8;48
Label6
(10ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل ComboBoxﺑﻪ GroupBox2اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺧﺎﺻﻴﺖ Nameآن را ﺑﺮاﺑﺮ ﺑـﺎ ،cboFieldﺧﺎﺻﻴﺖ Locationرا ﺑﺮاﺑـﺮ ﺑـﺎ ،88;21ﺧﺎﺻـﻴﺖ Sizeرا ﺑﺮاﺑـﺮ 88;21و ﺧﺎﺻـﻴﺖ DropDownStyleرا ﺑﺮاﺑﺮ ﺑﺎ DropDownListﻗﺮار دﻫﻴﺪ. (11دو ﻛﻨﺘﺮل TextBoxﺑﻪ GroupBox2اﺿﺎﻓﻪ ﻛﺮده و ﺧﺎﺻﻴﺘﻬﺎي آن را ﺑﺮ اﺳﺎس ﺟﺪول زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ:
٦٥١
Name
Locatio n
Size
TabSto p
TextAlig n
txtSearchCriteri a
88;48
200;2 0
-
-
txtRecordPositio n
152;130
85;20
False
Center
: اﺿﺎﻓﻪ ﻛﺮده و ﺧﺎﺻﻴﺘﻬﺎي آﻧﻬﺎ را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪGroupBox2 ﺑﻪButton ( ده ﻛﻨﺘﺮل12
Name
Location
Size
Text
ToolTip on ToolTip 1
btnPerformSort
304;16
96;24
Perform Sort
-
btnPerformSearch
304;48
96;24
Perform Search
-
btnNew
40;88
72;24
New
-
btnAdd
120;88
72;24
Add
-
btnUpdate
200;88
72;24
Update
-
btnDelete
280;88
72;24
Delete
-
btnMoveFirst
88;128
29;24
|<
Move First
btnMovePrevious
120;128
29;24
<
Move Previou s
btnMoveNext
200;128
29;24
>
Move Next
btnMoveLast
272;128
29;24
|>
Move Last
،Name ﻧﻴــﺎزي ﺑــﻪ ﺗﻐﻴﻴــﺮ ﺧﺎﺻــﻴﺘﻬﺎي. ﺑــﻪ ﺑﺮﻧﺎﻣــﻪ اﺿــﺎﻓﻪ ﻛﻨﻴــﺪStatusStrip ( در آﺧــﺮ ﻧﻴــﺰ ﻳــﻚ ﻛﻨﺘــﺮل13 ﺑـﺎ اﺳـﺘﻔﺎده از ﻣﻨـﻮي ﻛﻨـﺎر آن ﻳـﻚ ﻛﻨﺘـﺮل، ﺑﻌﺪ از اﻧﺘﺨﺎب اﻳﻦ ﻛﻨﺘﺮل. اﻳﻦ ﻛﻨﺘﺮل ﻧﻴﺴﺖSize و ﻳﺎLocation . را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪStatusLabel . ﺑﺎﺷﺪ6-16 ﻓﺮم ﻛﺎﻣﻞ ﺷﺪه ي ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ،( ﺑﻌﺪ از اﺗﻤﺎم ﺗﻤﺎم اﻳﻦ ﻣﺮاﺣﻞ14
٦٥٢
و ﺑـﺎ ﻗـﺮار1 رﻓﺘـﻪForm1 ﺑﻪ ﻗﺴﻤﺖ وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛـﻼس.( ﺣﺎل ﻗﺴﻤﺖ ﻛﺪ ﻧﻮﻳﺴﻲ ﺑﺮﻧﺎﻣﻪ را ﺷﺮوع ﻣﻲ ﻛﻨﻴﻢ15 را ﺑـﻪSystem.Data.SqlClient وSystem.Data ﻓﻀﺎي ﻧـﺎم،دادن ﻛﺪ زﻳﺮ در ﺑﺎﻻي ﻛﺪﻫﺎ :ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ // Import Data and SqlClient namespaces using System.Data; using System.Data.SqlClient; ﻫﻤﭽﻨـﻴﻦ ﻳـﻚ.( ﺳﭙﺲ اﺷﻴﺎﻳﻲ ﻛﻪ ﺑﺎﻳﺪ ﺑﻪ ﺻﻮرت ﺳﺮاﺳﺮي در ﺑﺮﻧﺎﻣﻪ وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﻨﺪ را در اﺑﺘﺪاي ﻛﻼس ﺗﻌﺮﻳـﻒ ﻛﻨـﻴﻢ16 . اي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ در ﻃﻮل ﺑﺮﻧﺎﻣـﻪ ﺑـﻪ ﻛـﺎر ﺑﺒـﺮﻳﻢ را در آن ﻗـﺮار ﻣـﻲ دﻫـﻴﻢSQL رﺷﺘﻪ ي ﺛﺎﺑﺖ ﺗﻌﺮﻳﻒ ﻛﺮده و دﺳﺘﻮر : اﺿﺎﻓﻪ ﻛﻨﻴﺪForm1 ﺑﻨﺎﺑﺮاﻳﻦ ﻛﺪ زﻳﺮ را ﺑﻪ اﺑﺘﺪاي ﻛﻼس public partial class Form1 : Form { // Constant strings private const string _CommandText = "SELECT authors.au_id, au_lname, au_fname, " + "titles.title_id, title, price " + "FROM authors " + "JOIN titleauthor ON authors.au_id = " + "titleauthor.au_id " + "JOIN titles ON titleauthor.title_id = " + "titles.title_id " + "ORDER BY au_lname, au_fname"; private const string _ConnectionString = "server=localhost;database=pubs;" + "user id=sa;password=;"; // Declare global objects... SqlConnection objConnection; SqlDataAdapter objDataAdapter; DataSet objDataSet; DataView objDataView; CurrencyManager objCurrencyManager; را ﺑﺮ اﺳﺎس ﺗﻨﻈﻴﻤـﺎت ﺳـﺮور ﺑﺎﻧـﻚConnectionString ، ﻗﺒﻞ از وارد ﻛﺮدن ﻗﻄﻌﻪ ﻛﺪ ﺑﺎﻻ در ﺑﺮﻧﺎﻣﻪ:ﻧﻜﺘﻪ ﻣﺮﺑﻮط ﺑﻪ اﻛﺎﻧﺖ ﻛﺎرﺑﺮي ﺧﻮد را وارد ﻛﺮده و ﻫﻤﭽﻨﻴﻦ اﮔـﺮPassword وUser ID .اﻃﻼﻋﺎﺗﻲ ﺧﻮد ﺗﻐﻴﻴﺮ دﻫﻴﺪ . ﻧﺎم ﻛﺎﻣﭙﻴﻮﺗﺮ ﺳﺮور در ﺷﺒﻜﻪ را وارد ﻛﻨﻴﺪlocalhost ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از،ﺳﺮور روي ﻛﺎﻣﭙﻴﻮﺗﺮ دﻳﮕﺮي ﻗﺮار دارد :( ﻛﺪ درون ﻣﺘﺪ ﺳﺎزﻧﺪه ي ﻓﺮم را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ17 public Form1() . اﺳﺘﻔﺎده ﻛﻨﻴﺪF7 ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻛﻠﻴﺪ، ﺑﺮاي ﺟﺎ ﺑﻪ ﺟﺎ ﺷﺪن ﺑﻴﻦ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ و ﻗﺴﻤﺖ ﻛﺪ ﻧﻮﻳﺴﻲ در ﻳﻚ ﻓﺮم1
٦٥٣
{ objConnection = new SqlConnection(_ConnectionString); objDataAdapter = new SqlDataAdapter( _CommandText, objConnection); InitializeComponent(); } اﻳﻦ زﻳﺮ ﺑﺮﻧﺎﻣﻪ. اﺳﺖFillDataSetAndView زﻳﺮ ﺑﺮﻧﺎﻣﻪ اي ﺑﻪ ﻧﺎم،( اوﻟﻴﻦ زﻳﺮ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ ﺑﺎﻳﺪ اﻳﺠﺎد ﻛﻨﻴﻢ18 ﺑﻌـﺪ از ﺗﻌﺮﻳـﻒ،Form1 ﻛـﺪ زﻳـﺮ را ﺑـﻪ ﻛـﻼس.ﺑﻪ ﻫﻤﺮاه ﭼﻨﺪ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ي دﻳﮕﺮ در اﺑﺘﺪاي ﺑﺮﻧﺎﻣﻪ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮﻧﺪ :ﻣﺘﻐﻴﻴﺮ ﻫﺎ اﺿﺎﻓﻪ ﻛﻨﻴﺪ private void FillDataSetAndView() { // Initialize a new instance of the DataSet object... objDataSet = new DataSet(); // Fill the DataSet object with data... objDataAdapter.Fill(objDataSet, "authors"); // Set the DataView object to the DataSet object... objDataView = new DataView( objDataSet.Tables["authors"]); // Set our CurrencyManager object // to the DataView object... objCurrencyManager = (CurrencyManager)( this.BindingContext[objDataView]); } ( در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ زﻳﺮ ﺑﺮﻧﺎﻣﻪ اي ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﻛﻨﻴﻢ ﺗﺎ ﻛﻨﺘﺮﻟﻬـﺎي ﻣﻮﺟـﻮد در ﻓـﺮم را ﺑـﻪ ﻓﻴﻠـﺪ ﻫـﺎي ﻣﺮﺑـﻮط ﺑـﻪ آﻧﻬـﺎ در19 : اﺿﺎﻓﻪ ﻛﻨﺪDataView private void BindFields() { // Clear any previous bindings... txtLastName.DataBindings.Clear(); txtFirstName.DataBindings.Clear(); txtBookTitle.DataBindings.Clear(); txtPrice.DataBindings.Clear(); // Add new bindings to the DataView object... txtLastName.DataBindings.Add("Text", objDataView, "au_lname"); txtFirstName.DataBindings.Add("Text", objDataView, "au_fname");
٦٥٤
txtBookTitle.DataBindings.Add("Text", objDataView, "title"); txtPrice.DataBindings.Add("Text", objDataView, "price"); // Display a ready status... ToolStripStatusLabel1.Text = "Ready"; } :( ﺳﭙﺲ زﻳﺮ ﺑﺮﻧﺎﻣﻪ اي ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻣﻮﻗﻌﻴﺖ رﻛﻮرد ﺟﺎري را در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ دﻫﺪ20 private void ShowPosition() { // Always format the number // in the txtPrice field to include cents try { txtPrice.Text = Decimal.Parse(txtPrice.Text).ToString("##0.00"); } catch(System.Exception e) { txtPrice.Text = "0"; txtPrice.Text = Decimal.Parse(txtPrice.Text).ToString("##0.00"); } // Display the current position // and the number of records txtRecordPosition.Text = (objCurrencyManager.Position + 1) + " of " + objCurrencyManager.Count; } اﻣﺎ در ﻫﻴﭻ ﻗﺴﻤﺖ از ﻛﺪ از اﻳﻦ زﻳـﺮ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي اﻳﺠـﺎد ﺷـﺪه،( ﺗﺎ اﻳﻨﺠﺎ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ي ﻻزم را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮده اﻳﻢ21 . اﻳﻦ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻻزم اﺳﺖ ﻛﻪ ﻗﺒﻞ از ﻧﻤﺎﻳﺶ داده ﺷﺪن ﻓﺮم و ﻫﻨﮕﺎم ﻟـﻮد ﺷـﺪن آن ﻓﺮاﺧـﻮاﻧﻲ ﺷـﻮﻧﺪ.اﺳﺘﻔﺎده ﻧﻜﺮده اﻳﻢ ﻓـﺮمLoad ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮوﻳﺪ و روي ﻗﺴﻤﺖ ﺧﺎﻟﻲ از ﻓﺮم دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳـﺪاد ﻧـﻪ در ﻗـﺴﻤﺘﻲ ﺧـﺎﻟﻲ از ﻛﻨﺘـﺮل،اﻳﺠﺎد ﺷﻮد )دﻗـﺖ ﻛﻨﻴـﺪ ﻛـﻪ ﺑﺎﻳـﺪ در ﻳـﻚ ﻗـﺴﻤﺖ ﺧـﺎﻟﻲ از ﻓـﺮم دو ﺑـﺎر ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ : ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ.(GroupBox private void Form1_Load(object sender, EventArgs e) { // Add items to the combo box... cboField.Items.Add("Last Name"); cboField.Items.Add("First Name");
٦٥٥
cboField.Items.Add("Book Title"); cboField.Items.Add("Price"); // Make the first item selected... cboField.SelectedIndex = 0; // Fill the DataSet and bind the fields... FillDataSetAndView(); BindFields(); // Show the current record position... ShowPosition(); } ﺑﺮاي اﻳﻦ ﻛﺎر ﻻزم اﺳـﺖ ﻛـﻪ ﭼﻬـﺎر ﺑـﺎر ﺑـﻪ.( ﺣﺎل ﺑﺎﻳﺪ ﻛﺪ ﻛﻠﻴﺪﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﺣﺮﻛﺖ ﺑﻴﻦ رﻛﻮرد ﻫﺎ را در ﺑﺮﻧﺎﻣﻪ وارد ﻛﻨﻴﻢ22 ،btnMoveLast ،btnMoveFirst ﻗــﺴﻤﺖ ﻃﺮاﺣــﻲ ﻓــﺮم ﺑﺮوﻳــﺪ و روي ﻫــﺮ ﻛــﺪام از دﻛﻤــﻪ ﻫــﺎي ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻛﻠﻴﻚ ﻫـﺮ ﻳـﻚ از آﻧﻬـﺎbtnMoveNext وbtnMovePrevious : اﺿﺎﻓﻪ ﻛﻨﻴﺪbtnMoveFirst ﻛﻨﺘﺮلClick ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد.اﻳﺠﺎد ﺷﻮد private void btnMoveFirst_Click(object sender, EventArgs e) { // Set the record position to the first record... objCurrencyManager.Position = 0; // Show the current record position... ShowPosition(); } : اﺿﺎﻓﻪ ﻛﻨﻴﺪbtnMovePrevious ﻛﻨﺘﺮلClick ( ﻛﺪ زﻳﺮ را ﺑﻪ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد23 private void btnMovePrevious_Click(object sender, EventArgs e) { // Move to the previous record... objCurrencyManager.Position -= 1; // Show the current record position... ShowPosition(); } : اﺿﺎﻓﻪ ﻛﻨﻴﺪbtnMoveNext_Click ( ﻛﺪ زﻳﺮ را ﺑﻪ ﻣﺘﺪ24 private void btnMoveNext_Click(object sender, EventArgs e) { // Move to the next record...
٦٥٦
;objCurrencyManager.Position += 1 //Show the current record position... ;)(ShowPosition } (25در آﺧﺮ ﻧﻴﺰ ﺑﺮاي ﺗﻜﻤﻴﻞ اﻳﻦ ﻗﺴﻤﺖ ﻻزم اﺳﺖ ﻛﻪ ﻛﺪ زﻳﺮ را در ﻣﺘﺪ btnMoveLast_Clickﻗﺮار دﻫﻴﺪ: )private void btnMoveLast_Click(object sender, EventArgs e { // Set the record position to the last record... = objCurrencyManager.Position ;objCurrencyManager.Count - 1 // Show the current record position... ;)(ShowPosition } (26ﺗﺎ اﻳﻦ ﻗﺴﻤﺖ ﻛﺪ زﻳﺎدي را در ﺑﺮﻧﺎﻣﻪ وارد ﻛﺮده اﻳﻢ و اﺣﺘﻤﺎﻻ ﻣﺸﺘﺎق ﻫﺴﺘﻴﺪ ﻛﻪ ﻧﺘﻴﺠﻪ ي آن را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ .ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻛﻨﺘﺮﻟﻬﺎي ﻓﺮم ﻫﺮ ﻳﻚ ﺑﻪ ﻓﻴﻠﺪ ﻣﺮﺑﻮط ﺑﻪ ﺧﻮد در DataViewﻣﺘـﺼﻞ ﺷـﺪه اﻧـﺪ .روي ﻛﻠﻴﺪﻫﺎي ﻣﺮﺑﻮط ﺑﻪ اﺑﺘﺪا و ﻳﺎ اﻧﺘﻬﺎي رﻛﻮرد ﻫﺎ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻧﺤـﻮه ي ﻋﻤﻠﻜـﺮد ﻛـﻼس CurrencyManager ﺑﺮاي اﻳﺠﺎد ﻫﻤﺎﻫﻨﮕﻲ ﺑﻴﻦ رﻛﻮردي ﻛﻪ ﻛﻨﺘﺮل ﻫﺎ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻨﺪ را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ. ﺑﺎ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﻓﺮﻣﻲ را ﻣﺸﺎﺑﻪ ﺷﻜﻞ 7-16ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ .ﺗﺎ اﻳﻨﺠﺎ در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻓﻘﻂ ﻛﻠﻴﺪﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﺟـﺎ ﺑـﻪ ﺟـﺎ ﺷﺪن ﺑﻴﻦ رﻛﻮرد ﻫﺎ ﻋﻤﻞ ﻣﻲ ﻛﻨﻨﺪ .ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي ﻫﺮ ﻳﻚ از ﻛﻠﻴﺪﻫﺎي ﺑﻌﺪي و ﻗﺒﻠﻲ و ﻳﺎ روي ﻛﻠﻴﺪﻫﺎي ﻣﺮﺑـﻮط ﺑـﻪ اﺑﺘﺪا و اﻧﺘﻬﺎ ،ﺑﻴﻦ رﻛﻮرد ﻫﺎي ﻣﻮﺟﻮد در ﻓﺮم ﺟﺎ ﺑﻪ ﺟﺎ ﺷﻮﻳﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻫﺮ ﺑﺎر ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﻠﻴﺪ ﻫﺎ رﻛﻮرد ﺟﺎري را ﺗﻐﻴﻴﺮ دﻫﻴﺪ ،ﻋﺪد ﻧﻤﺎﻳﺶ داده ﺷﺪه در ﻛﺎدر در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﺗﻐﻴﻴﺮ ﻛﺮده و ﺷﻤﺎره رﻛﻮرد ﺟﺎري را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ.
٦٥٧
ﺷﻜﻞ 7-16 اﮔﺮ در رﻛﻮرد اﺑﺘﺪا ﺑﺎﺷﻴﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ روي ﻛﻠﻴﺪ ﻣﺮﺑﻮط ﺑﻪ رﻛﻮرد ﻗﺒﻠﻲ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ،اﻣﺎ ﻫﻴﭻ اﺗﻔﺎﻗﻲ رخ ﻧﺨﻮاﻫـﺪ داد زﻳـﺮا ﻫـﻢ اﻛﻨﻮن در رﻛﻮرد ﻗﺒﻠﻲ ﻫﺴﺘﻴﺪ .ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ آﺧﺮﻳﻦ رﻛﻮرد ﺑﺮوﻳﺪ و روي ﻛﻠﻴﺪ ﻣﺮﺑﻮط ﺑﻪ رﻛﻮرد ﺑﻌﺪي ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ. اﻣﺎ ﺑﺎز ﻫﻢ ﻫﻴﭻ ﺗﻐﻴﻴﺮي را ﻣﺸﺎﻫﺪه ﻧﺨﻮاﻫﻴﺪ ﻛﺮد ،زﻳﺮا در آﺧﺮﻳﻦ رﻛﻮرد ﻫﺴﺘﻴﺪ. ﻫﻤﭽﻨﻴﻦ اﮔﺮ ﻣﺎوس را روي ﻫﺮ ﻳﻚ از اﻳﻦ دﻛﻤﻪ ﻫﺎ ﺑﺒﺮﻳﺪ ،ﺗﻮﺿﻴﺤﻲ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻋﻤﻠﻜﺮد ﻛﻠﻴﺪ را ﺗﻮﺿﻴﺢ ﻣﻲ دﻫﺪ .اﻳﻦ ﻣﻮرد ﻓﻘﻂ ﺑﺮاي اﻳﺠﺎد راﺑﻂ ﻛﺎرﺑﺮي ﺑﻬﺘﺮ اﺿﺎﻓﻪ ﺷﺪه اﺳﺖ. ﻧﻜﺘﻪ :ﻗﺴﻤﺘﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﻣﺪﻳﺮﻳﺖ ﺧﻄﺎﻫﺎ و اﺳﺘﺜﻨﺎ ﻫﺎي اﺣﺘﻤﺎﻟﻲ از ﻛﺪ اﻳﻦ ﻗﺴﻤﺖ ﺣﺬف ﺷﺪه اﻧﺪ ﺗﺎ ﻣﻜـﺎن ﻛﻤﺘـﺮي ﮔﺮﻓﺘـﻪ ﺷـﻮد .در ﻫﻨﮕﺎم وارد ﻛﺮدن اﻳﻦ ﻛﺪ ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ اﻳﻦ ﻗﺴﻤﺖ را ﻧﻴﺰ اﺿﺎﻓﻪ ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺮور اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل و ﻣﺪﻳﺮﻳﺖ ﺧﻄﺎﻫﺎ و اﺳﺘﺜﻨﺎ ﻫﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻓﺼﻞ ﻳﺎزدﻫﻢ رﺟﻮع ﻛﻨﻴﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ – ﻓﻀﺎي ﻧﺎﻣﻬﺎ و ﺗﻌﺎرﻳﻒ ﻣﺎﻧﻨﺪ ﻗﺒﻞ اﺑﺘﺪا ﻓﻀﺎي ﻧﺎﻣﻬﺎي System.Dataو System.Data.SqlClientرا ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ. ﺳﭙﺲ ﻳﻚ ﺛﺎﺑﺖ رﺷﺘﻪ اي اﻳﺠﺎد ﻛﺮده و دﺳﺘﻮر SQLاي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﺮاي درﻳﺎﻓﺖ داده ﻫﺎ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ،از آن اﺳﺘﻔﺎده ﻛﻨﻴﻢ را در اﻳﻦ ﺛﺎﺑﺖ ﻗﺮار ﻣﻲ دﻫﻴﻢ .ﻫﻤﭽﻨﻴﻦ ﺛﺎﺑﺖ رﺷﺘﻪ اي دﻳﮕﺮي ﺗﻌﺮﻳﻒ ﻛﺮده و ﻣﺘﻦ ﻣﺮﺑﻮط ﺑﻪ اﺗﺼﺎل ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را در آن ﻗـﺮار ﻣﻲ دﻫﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ در ﻃﻮل ﺑﺮﻧﺎﻣﻪ اﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﺑﻪ ﺳﺮور دﻳﮕﺮي ﻣﺘﺼﻞ ﺷﻮﻳﻢ و ﻳﺎ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ اﻛﺎﻧﺘﻲ ﻛﻪ ﺑﺮاي اﺗﺼﺎل ﺑﻪ ﺑﺎﻧﻚ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ را ﺗﻐﻴﻴﺮ دﻫﻴﻢ ،ﻓﻘﻂ ﻻزم اﺳﺖ ﻛﻪ ﺗﻐﻴﻴﺮات را در اﻳﻦ ﺛﺎﺑﺖ رﺷﺘﻪ اي وارد ﻛﻨﻴﻢ .ﺑﻌﺪ از اﻳﻦ ﻛﺎر ﺑـﻪ ﺗﻌﺮﻳـﻒ اﺷﻴﺎي ﻣﻮرد ﻧﻴﺎز در ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﭘﺮدازﻳﻢ .ﺑﺎ ﺳﻪ ﺷﻴﺊ اول ﻛﻪ از ﻗﺴﻤﺖ ﻫﺎي ﻗﺒﻞ آﺷﻨﺎ ﻫﺴﺘﻴﺪ و ﻧﻴﺎزي ﺑﻪ ﺗﻮﺿﻴﺢ ﻧﺪارﻧﺪ.
٦٥٨
ﻣﻮارد اﺳﺘﻔﺎده از دو ﺷﻴﺊ آﺧﺮ ﻫﻢ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﺗﻮﺿﻴﺢ داده ﺷﺪه اﻧﺪ .از ﺷﻴﺊ DataViewﺑﺮاي ﺗﻐﻴﻴﺮ ﻧﺤﻮه ي ﻧﻤـﺎﻳﺶ داده ﻫﺎﻳﻲ ﻛﻪ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ درﻳﺎﻓﺖ و در DataSetﻧﮕﻬﺪاري ﺷﺪه اﻧﺪ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .ﺷﻴﺊ CurrencyManager ﻧﻴﺰ ﺑﺮاي اﻳﺠﺎد ﻫﻤﺎﻫﻨﮕﻲ در ﻧﻤﺎﻳﺶ داده ﻫﺎي ﻳﻚ رﻛﻮرد ﺑﻪ وﺳﻴﻠﻬﻲ ﭼﻨﺪ ﻛﻨﺘﺮل ﺳﺎده ﺑﻪ ﻛﺎر ﻣﻲ رود. // Constant strings = private const string _CommandText "SELECT authors.au_id, au_lname, au_fname, " + "titles.title_id, title, price " + "FROM authors " + "JOIN titleauthor ON authors.au_id = " + "titleauthor.au_id " + "JOIN titles ON titleauthor.title_id = " + "titles.title_id " + ;""ORDER BY au_lname, au_fname = private const string _ConnectionString "server=localhost;database=pubs;" + ;";="user id=sa;password // Declare global objects... ;SqlConnection objConnection ;SqlDataAdapter objDataAdapter ;DataSet objDataSet ;DataView objDataView ;CurrencyManager objCurrencyManager اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﺗﺎ اﻳﻨﺠﺎ ﻓﻘﻂ ﻣﺘﻐﻴﺮﻫﺎﻳﻲ ﺑﺮاي ﻧﮕﻬﺪاري اﻳﻦ اﺷﻴﺎ اﻳﺠﺎد ﻛﺮده اﻳﻢ و ﺧﻮد اﺷﻴﺎ ﻫﻨﻮز اﻳﺠﺎد ﻧﺸﺪه اﻧﺪ .از اﻳﻦ ﭘـﻨﺞ ﻣﺘﻐﻴﺮي ﻛﻪ در اﻳﻦ ﻣﺮﺣﻠﻪ ﺗﻌﺮﻳﻒ ﻛﺮده اﻳﻢ ،دو ﻣﺘﻐﻴﻴﺮ اول را ﺑﺎﻳﺪ در اﺑﺘﺪاي ﺑﺮﻧﺎﻣﻪ ﻧﻤﻮﻧﻪ ﺳﺎزي ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ آﻧﻬﺎ را از اﺑﺘﺪا در ﺑﺮﻧﺎﻣـﻪ ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﻢ .ﺑﻨﺎﺑﺮاﻳﻦ در ﻣﺘﺪ ﺳﺎزﻧﺪه ي ﻛﻼس ،Form1ﺑﺎ اﺳﺘﻔﺎده از ﺛﺎﺑﺖ ﻫﺎي رﺷﺘﻪ اي ﻛﻪ اﻳﺠﺎد ﻛـﺮده ﺑـﻮدﻳﻢ و ﺑـﻪ وﺳـﻴﻠﻪ ي دﺳﺘﻮر ،newدو ﻧﻤﻮﻧﻪ از ﻛﻼس SqlDataAdapterو SqlConnectionاﻳﺠﺎد ﻛﺮده و در اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﻫﺎ ﻗﺮار ﻣﻲ دﻫﻴﻢ. ﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﻴﺊ objConnectionﻛﻪ ﻫﻤﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻞ اﺳﺖ و ﻧﻴﺎزي ﺑﻪ ﺗﻮﺿﻴﺢ ﻧـﺪارد .اﻣـﺎ ﺑﻬﺘـﺮ اﺳـﺖ ﻛـﻪ ﻧﻤﻮﻧـﻪ ﺳﺎزي ﺷﻴﺊ objDataAdapterرا دﻗﻴﻖ ﺗﺮ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ .ﻫﻨﮕﺎم ﻧﻤﻮﻧﻪ ﺳـﺎزي اﻳـﻦ ﺷـﻴﺊ ،ﻳـﻚ ﻣـﺘﻦ ﺑـﻪ ﻋﻨـﻮان دﺳـﺘﻮر SQLاي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار دﻫﻴﻢ و ﻧﻴﺰ ﻳﻚ ﺷﻴﺊ از ﻧﻮع SqlConnectionرا ﺑﻪ ﻣﺘﺪ ﺳﺎزﻧﺪه ي اﻳﻦ ﻛﻼس ارﺳﺎل ﻛﺮدﻳﻢ .ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ ،ﻣﺘﺪ ﺳﺎزﻧﺪه ي ﻛﻼس SqlDataAdapterﺑـﺎ اﺳـﺘﻔﺎده از دﺳـﺘﻮر ،SQLﻳـﻚ ﺷـﻴﺊ از ﻧـﻮع SqlCommandاﻳﺠـــﺎد ﻛـــﺮده و آن را در ﺧﺎﺻـــﻴﺖ SelectCommandﻗـــﺮار ﻣـــﻲ دﻫـــﺪ .ﻫﻤﭽﻨـــﻴﻦ ﺷـــﻴﺊ SqlConnectionاي ﻛﻪ ﺑﻪ آن ﻓﺮﺳﺘﺎده اﻳﻢ را ﻧﻴﺰ ﺑﺮاي اﺗﺼﺎل ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ .ﺑﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﻧﻴـﺎزي ﻧﻴﺴﺖ ﻛﻪ اﻳﻦ اﺷﻴﺎ را ﺧﻮدﻣﺎن اﻳﺠﺎد ﻛﺮده و در ﺧﺎﺻﻴﺘﻬﺎي ﻣﺮﺑﻮط ﺑﻪ آﻧﻬﺎ ﻗﺮار دﻫﻴﻢ. )(public Form1 { ;)objConnection = new SqlConnection(_ConnectionString (objDataAdapter = new SqlDataAdapter ;)_CommandText, objConnection
٦٥٩
;)(InitializeComponent } ﻧﻜﺘﻪ :ﻣﻴﺪاﻧﻴﺪ ﻛﻪ ﻫﺮ ﻓﺮم ،ﺧﻮد ﻧﻴﺰ ﻳﻚ ﻛﻼس اﺳﺖ و ﻣﺎﻧﻨﺪ ﻫﺮ ﻛﻼس دﻳﮕﺮي داراي ﻳﻚ ﻣﺘﺪ ﺳﺎزﻧﺪه اﺳﺖ ﻛـﻪ ﻫﻨﮕـﺎم اﻳﺠـﺎد ﻳـﻚ ﺷﻴﺊ از آن ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد .ﻣﺘﺪ ﺳﺎزﻧﺪه ي Form1ﻧﻴﺰ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،ﻫﺮ زﻣﺎن ﻛـﻪ ﻧﻤﻮﻧـﻪ ي ﺟﺪﻳـﺪي از اﻳﻦ ﻓﺮم اﻳﺠﺎد ﺷﻮد ﻓﺮاﺧﻮاﻧﻲ ﺧﻮاﻫﺪ ﺷﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻫﺮ ﻛﺪي ﻛﻪ ﺑﺨﻮاﻫﻴﻢ در اﺑﺘﺪاي اﻳﺠﺎد ﻳﻚ ﻓﺮم ،زﻣﺎﻧﻲ ﻛﻪ ﻓﺮم در ﺣﺎل ﻧﻤﻮﻧﻪ ﺳـﺎزي ﺷــﺪن اﺳــﺖ اﺟــﺮا ﺷــﻮد را ﺑﺎﻳــﺪ در اﻳــﻦ ﻣﺘــﺪ وارد ﻛﻨــﻴﻢ .اﻳــﻦ ﻣﺘــﺪ ﺑــﻪ ﺻــﻮرت ﭘــﻴﺶ ﻓــﺮض داراي ﻓﺮاﺧــﻮاﻧﻲ ﻣﺘــﺪي ﺑــﻪ ﻧــﺎم InitializeComponentاﺳﺖ ﻛﻪ در ﻓﺎﻳـﻞ Form1.Designer.csﻗـﺮار دارد ) Form1ﻧـﺎم ﻓـﺮم ﺑﺮﻧﺎﻣﻪ اﺳﺖ و ﻣﻤﻜﻦ اﺳﺖ ﺗﻐﻴﻴﺮ ﻛﻨﺪ( .اﻳﻦ ﻣﺘﺪ در ﻫﻤﺎن اﺑﺘﺪاي ﻧﻤﻮﻧﻪ ﺳﺎزي ﺷﺪن ﻓﺮم ﻓﺮاﺧﻮاﻧﻲ ﺷﺪه و وﻇﻴﻔﻪ دارد ﻛـﻪ ﻛﻨﺘـﺮل ﻫـﺎ و اﺷﻴﺎي ﻣﻮﺟﻮد در ﻓﺮم را اﻳﺠﺎد ﻛﺮده و ﺧﺎﺻﻴﺘﻬﺎي آﻧﻬﺎ را ﺗﻨﻈﻴﻢ ﻛﻨﺪ.1 دﺳﺘﻮر SELECTاي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ ،در اﺻﻞ ﻫﻤﺎن دﺳﺘﻮري اﺳﺖ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻞ ﺑﻪ ﻛﺎر ﺑـﺮده اﻳـﻢ ،ﺑـﺎ اﻳﻦ ﺗﻔﺎوت ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻧﺎم ﭼﻨﺪ ﺳﺘﻮن دﻳﮕﺮ را ﻧﻴﺰ در ﻣﻘﺎﺑﻞ ﻋﺒﺎرت SELECTاﺿﺎﻓﻪ ﻛﺮده اﻳﻢ ﺗـﺎ اﻃﻼﻋـﺎت ﻣﻮﺟـﻮد در اﻳـﻦ ﺳﺘﻮن ﻫﺎ ﻧﻴﺰ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ درﻳﺎﻓﺖ ﺷﻮﻧﺪ. ﻗﺒﻞ از ﺳﺘﻮن au_idﻧﺎم ﺟﺪول authorsرا آورده اﻳﻢ ،زﻳﺮا اﻳﻦ ﺳﺘﻮن در ﺟـﺪول authortitleﻫـﻢ وﺟـﻮد دارد. ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ ﺑﺮاي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ اﻳﻦ ﺳﺘﻮن از ﻛﺪاﻣﻴﻚ از اﻳﻦ دو ﺟﺪول اﺳﺘﺨﺮاج ﺷﻮد .ﻫﻤﻴﻦ روش را ﺑﺮاي title_idﻧﻴﺰ ﺑﻪ ﻛﺎر ﺑﺮده اﻳﻢ ،زﻳﺮا اﻳﻦ ﺳﺘﻮن ﻧﻴﺰ در ﺟﺪول ﻫﺎي titlesو authortitleوﺟﻮد دارد.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ – FillDataSetAndView اوﻟﻴﻦ زﻳﺮ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ،زﻳﺮ ﺑﺮﻧﺎﻣﻪ ي FillDataSetAndViewاﺳﺖ .اﻳﻦ زﻳﺮ ﺑﺮﻧﺎﻣـﻪ در ﭼﻨﺪﻳﻦ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ ﻓﺮاﺧﻮاﻧﻲ ﺷﺪه و وﻇﻴﻔﻪ دارد ﻛﻪ اﻃﻼﻋﺎت را از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ درﻳﺎﻓﺖ ﻛﺮده و در DataSetﻗﺮار دﻫﺪ. در اﺑﺘﺪاي اﻳﻦ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ،ﻳﻚ ﻧﻤﻮﻧﻪ از ﺷﻴﺊ DataSetرا اﻳﺠﺎد ﻛﺮده و آن را در ﻣﺘﻐﻴﻴﺮ objDataSetﻗـﺮار ﻣـﻲ دﻫـﻴﻢ. اﻳﻦ ﻛﺎر را ﺑﻪ اﻳﻦ دﻟﻴﻞ در ﻣﺘﺪ ﺳﺎزﻧﺪه ي ﻛﻼس اﻧﺠﺎم ﻧﺪادﻳﻢ ،زﻳﺮا ﻣﻤﻜﻦ اﺳﺖ اﻳﻦ ﻣﺘﺪ در ﭼﻨﺪﻳﻦ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ ﻓﺮاﺧـﻮاﻧﻲ ﺷـﻮد و ﻣﻲ ﺧﻮاﻫﻴﻢ ﻫﺮ ﺑﺎر ﻛﻪ اﻳﻦ ﻣﺘﺪ ﻓﺮاﺧﻮاﻧﻲ ﺷﺪ DataSet ،ﻗﺒﻠﻲ از ﺑﻴﻦ ﺑﺮود و اﻃﻼﻋﺎﺗﻲ ﻛﻪ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﻪ دﺳﺖ ﻣﻲ آﻳـﺪ در ﻳﻚ DataSetﺟﺪﻳﺪ ﻗﺮار ﺑﮕﻴﺮد: )(private void FillDataSetAndView { // Initialize a new instance of the DataSet object... ;)(objDataSet = new DataSet ﺳﭙﺲ ﻣﺘﺪ Fillاز ﻛﻼس SqlDataAdapterرا ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ داده ﻫﺎ را از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ درﻳﺎﻓﺖ ﻛﺮده و در ﺷﻴﺊ objDataSetﻗﺮار دﻫﺪ .ﺑﻌﺪ از آن ﻧﻴﺰ ﺷﻴﺊ DataViewرا ﺑﻪ ﮔﻮﻧﻪ اي اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﺪ داده ﻫـﺎي ﻣﻮﺟـﻮد در ﺟﺪول authorsاز DataSetرا ﻧﻤﺎﻳﺶ دﻫﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﻪ ﺳﺎدﮔﻲ ﺑﻴﻦ داده ﻫﺎي ﻣﻮﺟﻮد در اﻳـﻦ ﺟـﺪول ﺣﺮﻛﺖ ﻛﺮده ،ﺟﺴﺘﺠﻮ ﻛﻨﻴﻢ و ﻳﺎ ﺗﺮﺗﻴﺐ ﻗﺮار ﮔﺮﻓﺘﻦ آﻧﻬﺎ را ﺗﻐﻴﻴﺮ داده و آﻧﻬﺎ ﺑﻪ ﺻﻮرت دﻟﺨﻮاه ﻣﺮﺗﺐ ﻛﻨﻴﻢ.
1ﻧﺤﻮه ي ﺗﻨﻈﻴﻢ ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل ﻫﺎ در اﻳﻦ ﻗﺴﻤﺖ ،ﺑﺮ اﺳﺎس ﺗﻐﻴﻴﺮاﺗﻲ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي Propertiesاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﻣﺸﺨﺺ ﻣﻲ ﺷﻮد.
٦٦٠
// Fill the DataSet object with data... ;)"objDataAdapter.Fill(objDataSet, "authors // Set the DataView object to the DataSet object... (objDataView = new DataView ;)]"objDataSet.Tables["authors ﺑﻌﺪ از ﻣﻘﺪار دﻫﻲ اوﻟﻴﻪ ﺑﻪ ﺷﻴﺊ ،objDataViewﺑﺎﻳﺪ ﺷﻴﺊ objCurrencyManagerرا ﻣﻘﺪار دﻫﻲ ﻛﻨـﻴﻢ .ﺑـﻪ ﺧﺎﻃﺮ دارﻳﺪ ﻛﻪ ﺷﻴﺊ BindingContextﺑﻪ ﺻﻮرت دروﻧﻲ در ﻫﺮ ﻓﺮم وﻳﻨﺪوزي وﺟﻮد داﺷﺘﻪ و ﺷﺎﻣﻞ ﻳﻚ ﻣﺠﻤﻮﻋﻪ از اﺷـﻴﺎ از ﻧﻮع CurrencyManagerاﺳﺖ ﻛﻪ ﻫﺮ ﻳﻚ ﺑﺮاي ﻳﻜﻲ از ﻣﻨﺎﺑﻊ داده اي ﻣﻮﺟﻮد در ﻓﺮم اﻳﺠﺎد ﺷﺪه اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ در اﻳـﻦ ﻗﺴﻤﺖ از ﻣﻴﺎن آﻧﻬﺎ ﺷﻴﺊ CurrencyManagerﻣﺮﺑﻮط ﺑﻪ ﻣﻨﺒﻊ داده اي objDataSetرا اﻧﺘﺨﺎب ﻣﻲ ﻛﻨﻴﻢ: // Set our CurrencyManager object // to the DataView object... ()objCurrencyManager = (CurrencyManager ;)]this.BindingContext[objDataView }
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ – BindFields زﻳﺮ ﺑﺮﻧﺎﻣﻪ ي ﺑﻌﺪي ﻛﻪ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ )زﻳﺮ ﺑﺮﻧﺎﻣﻪ ي (BindFieldsﺑﺮاي اﺗﺼﺎل ﻛﻨﺘﺮﻟﻬﺎي ﺳﺎده ي ﻣﻮﺟﻮد در ﻓﺮم ﺑـﻪ ﻓﻴﻠـﺪ ﻫﺎي ﻣﻮﺟﻮد در DataViewﺑﻪ ﻛﺎر ﻣﻲ رود .اﻳﻦ زﻳﺮ ﺑﺮﻧﺎﻣﻪ اﺑﺘﺪا ﺗﻤﺎم اﺗﺼﺎﻻت ﻣﻮﺟﻮد ﺑﺮاي ﻫﺮ ﻛﻨﺘﺮل را از ﺑﻴﻦ ﻣﻲ ﺑـﺮد ،ﺳـﭙﺲ آﻧﻬﺎ را ﺑﻪ ﻓﻴﻠﺪ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ آن در ﺷﻴﺊ objDataViewﻣﺘﺼﻞ ﻣﻲ ﻛﻨﺪ. ﺑــﺮاي ﺣــﺬف اﺗــﺼﺎل ﻫــﺎي ﻣﻮﺟــﻮد در ﻛﻨﺘــﺮل ﻫــﺎﻳﻲ ﻛــﻪ در ﻓــﺮم ﺑﺮﻧﺎﻣــﻪ ﻗــﺮار دارﻧــﺪ ،ﻛــﺎﻓﻲ اﺳــﺖ ﻣﺘــﺪ Clearاز ﺧﺎﺻــﻴﺖ ) DataBindingsﻛﻪ ﺷﺎﻣﻞ ﺷﻴﺊ اي از ﻧﻮع ControlBindingsColllectionاﺳـﺖ( را ﻓﺮاﺧـﻮاﻧﻲ ﻛﻨﻴﻢ. )(private void BindFields { // Clear any previous bindings... ;)(txtLastName.DataBindings.Clear ;)(txtFirstName.DataBindings.Clear ;)(txtBookTitle.DataBindings.Clear ;)(txtPrice.DataBindings.Clear ﺑﻌﺪ از اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻲ ﻣﺠﺪداً ﻛﻨﺘﺮل ﻫﺎ را ﺑﻪ ﻓﻴﻠﺪ ﻫﺎي ﻣﻮرد ﻧﻈﺮ در ﻣﻨﺒﻊ داده اي ﺧﻮد ﻳﻌﻨﻲ DataViewﻣﺘﺼﻞ ﻛﻨـﻴﻢ .ﺑـﺮاي اﻳــﻦ ﻛــﺎر ﻧﻴــﺰ از ﻣﺘــﺪ Addدر ﺷــﻴﺊ اي از ﻛــﻼس ،ControlBindingsCollectionﻛــﻪ ﺑــﻪ وﺳــﻴﻠﻪ ي DataBindingsﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ اﺳﺖ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒـﻞ ﻧﻴـﺰ ﮔﻔـﺘﻢ ،ﻣﺘـﺪ Addﺳـﻪ ﭘـﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ:
٦٦١
ﭘﺎراﻣﺘﺮ اول propertyNameاﺳﺖ و ﺷﺎﻣﻞ ﻧﺎم ﺧﺎﺻﻴﺘﻲ اﺳﺖ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﻪ ﻓﻴﻠﺪي از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺘﺼﻞ ﺷﻮد .در اﻳﻦ ﻗﺴﻤﺖ ﺑﺮاي اﻳﻨﻜﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺧﺎﺻﻴﺖ Textاز اﻳﻦ ﻛﻨﺘﺮل ﻫـﺎ ،ﻣﻘـﺪار ﺧـﻮد را از ﻓﻴﻠـﺪ ﻫـﺎي ﻣﻮﺟـﻮد در DataViewدرﻳﺎﻓﺖ ﻛﻨﻨﺪ ،ﻋﺒﺎرت ” “Textرا در اﻳﻦ ﭘﺎراﻣﺘﺮ ﻗﺮار ﻣﻲ دﻫﻴﻢ. ﭘﺎراﻣﺘﺮ ﺑﻌﺪي dataSourceاﺳﺖ و ﻧﺎم ﻣﻨﺒﻊ داده اي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﻪ آن ﻣﺘﺼﻞ ﺷﻮﻳﻢ را ﺗﻌﻴﻴﻦ ﻣﻲ ﻛﻨـﺪ .ﺗﻮﺟـﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛـﻪ اﻳـﻦ ﭘـﺎراﻣﺘﺮ ﻣـﻲ ﺗﻮاﻧـﺪ ﻫـﺮ ﺷـﻴﺊ اي ﻛـﻪ ﺣـﺎوي داده اﺳـﺖ را درﻳﺎﻓـﺖ ﻛﻨـﺪ ،ﻣﺎﻧﻨـﺪ ،DataSet DataViewو ﻳﺎ .DataTableﺑﺮاي اﻳﻦ ﻣﺜﺎل ﻳﻚ DataViewرا ﺑﻪ ﻋﻨﻮان ﻣﻨﺒﻊ داده اي ﺗﻌﻴـﻴﻦ ﻣـﻲ ﻛﻨﻴﻢ. ﭘﺎراﻣﺘﺮ آﺧﺮ ﻧﻴﺰ dataMemberاﺳﺖ .اﻳﻦ ﭘﺎراﻣﺘﺮ ﺣﺎوي ﻧﺎم ﻳﻚ ﻓﻴﻠﺪ در ﻣﻨﺒﻊ داده اي ﻣﺸﺨﺺ ﺷﺪه اﺳـﺖ ﻛـﻪ ﻣـﻲ ﺧﻮاﻫﻴﻢ ﺧﺎﺻﻴﺖ ﻣﻮرد ﻧﻈﺮ از ﻛﻨﺘﺮل ﺑﻪ آن ﻓﻴﻠﺪ ﻣﺘﺼﻞ ﺷﻮد .در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻧﺎم ﻳﻜﻲ از ﺳﺘﻮﻧﻬﺎي اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر SELECTاز ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺘﺨﺮاج ﻛﺮدﻳﺪ را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ. // Add new bindings to the DataView object... txtLastName.DataBindings.Add("Text", ;)"objDataView, "au_lname txtFirstName.DataBindings.Add("Text", ;)"objDataView, "au_fname txtBookTitle.DataBindings.Add("Text", ;)"objDataView, "title txtPrice.DataBindings.Add("Text", ;)"objDataView, "price
در اﻧﺘﻬﺎي اﻳﻦ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﭘﻴﻐﺎﻣﻲ را در ﻛﻨﺘﺮل Labelﻣﻮﺟﻮد در ﻧﻮار وﺿﻌﻴﺖ ﭘﺎﻳﻴﻦ ﻓﺮم ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ ﺗـﺎ ﺑـﻪ ﻛـﺎرﺑﺮ اﻃـﻼع دﻫﻴﻢ ﻛﻪ ﺑﺮﻧﺎﻣﻪ آﻣﺎده ﺷﺪه اﺳﺖ: // Display a ready status... ;"ToolStripStatusLabel1.Text = "Ready }
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ – ShowPosition ﺷﻴﺊ objCurrencyManagerﻣﺴﺌﻮل ﻧﮕﻬﺪاري ﻣﻮﻗﻌﻴﺖ رﻛﻮرد ﺟﺎري در objDataViewاﺳـﺖ .ﺑﻨـﺎﺑﺮاﻳﻦ در اﻳﻦ ﻣﺘﺪ ﺑﺎﻳﺪ از اﻳﻦ ﺷﻴﺊ اﺳﺘﻔﺎده ﻛﺮده و ﺑﻪ ﻛﺎرﺑﺮ اﻃﻼع دﻫﻴﻢ ﻛﻪ در ﺣﺎل ﻣﺸﺎﻫﺪه ي اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑـﻪ ﻛـﺪام ردﻳـﻒ از داده ﻫـﺎي ﻣﻮﺟﻮد در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺖ. اﻣﺎ ﻗﺒﻞ از اﻧﺠﺎم اﻳﻦ ﻛﺎر ،ﺑﻬﺘﺮ اﺳﺖ ﻧﺤﻮه ي ﻧﻤﺎﻳﺶ ﻋﺪدي ﻛﻪ در ﻛﺎدر ﻣﺘﻨﻲ ﻣﺘﺼﻞ ﺑﻪ ﺳﺘﻮن priceوﺟـﻮد دارد را ﺗﻐﻴﻴـﺮ دﻫـﻴﻢ. اﻳﻦ ﻋﺪد ﻧﻤﺎﻳﺶ دﻫﻨﺪه ي ﻗﻴﻤﺖ ﻛﺘﺎﺑﻲ اﺳﺖ ﻛﻪ ﻫﻢ اﻛﻨﻮن در ﺣﺎل ﻣـﺸﺎﻫﺪه ي اﻃﻼﻋـﺎت آن ﻫـﺴﺘﻴﻢ و ﺑـﺮ ﺣـﺴﺐ دﻻر ﻣـﻲ ﺑﺎﺷـﺪ. ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﻗﻴﻤﺖ ﻛﺘﺎﺑﻲ ﺑﺮاي ﻣﺜﺎل 40دﻻر ﺑﺎﺷﺪ ،ﻋﺪد 40در ﻛﺎدر ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .اﻣﺎ ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﺑﻌﺪ از اﻳﻦ ﻋﺪد ،دو رﻗـﻢ اﻋﺸﺎر ﻧﻴﺰ ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ ﺗﺎ ﻗﻴﻤﺖ ﻳﻚ ﻛﺘﺎب ﺑﻬﺘﺮ ﻣﺸﺨﺺ ﺷﻮد. ﺑﺮاي ﺗﻐﻴﻴﺮ در ﻧﺤﻮه ي ﻧﻤﺎﻳﺶ اﻳﻦ ﻋﺪد ،ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﻣﺘﻦ ﻣﻮﺟﻮد در ﻛـﺎدر Priceرا ﺑـﺎ اﺳـﺘﻔﺎده از ﻣﺘـﺪ Parseاز ﻛـﻼس Decimalﺑﻪ ﻳﻚ ﻋﺪد ﺗﺒﺪﻳﻞ ﻛﺮده ،ﺳﭙﺲ اﻳﻦ ﻋﺪد را ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ToStringو ﻣﺸﺨﺺ ﻛﺮدن ﻧﺤﻮه ي ﻓﺮﻣﺖ اﻳـﻦ ﻋﺪد ،آن را ﺑﻪ ﻣﺘﻦ ﺗﺒﺪﻳﻞ ﻛﻨﻴﺪ و ﻣﺠﺪداً در ﻛﺎدر priceﻗﺮار دﻫﻴﺪ .اﻟﺒﺘﻪ اﮔﺮ ﻛﺎدر Priceﺧﺎﻟﻲ ﺑﺎﺷﺪ ،ﻳﻌﻨـﻲ ﻗﻴﻤﺘـﻲ ﺑـﺮاي آن ٦٦٢
ﻛﺘﺎب ﻣﺸﺨﺺ ﻧﺸﺪه ﺑﺎﺷﺪ ،ﺧﻄﺎﻳﻲ در اﻳﻦ ﻗﺴﻤﺖ رخ ﻣﻲ دﻫﺪ ﻛﻪ ﻣﻮﺟﺐ ﻣﻲ ﺷﻮد اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﺘﻮﻗـﻒ ﺷـﻮد .در اﻳـﻦ ﻗـﺴﻤﺖ ﻣـﻲ ﺗﻮاﻧﻴﻢ از ﻳﻚ ﺑﻼك try…catchاﺳﺘﻔﺎده ﻛﺮده ﺗﺎ در ﺻﻮرﺗﻲ ﻛﻪ ﺧﻄﺎﻳﻲ ﺑﻪ وﺟﻮد آﻣﺪ )ﻳﻌﻨﻲ اﮔـﺮ ﻋـﺪدي در ﻛـﺎدر price وﺟﻮد ﻧﺪاﺷﺖ( ﻋﺪد ﺻﻔﺮ ﻗﺎﻟﺐ ﺑﻨﺪي ﺷﻮد و در ﻛﺎدر ﻗﺮار ﺑﮕﻴﺮد. )(private void ShowPosition { // Always format the number // in the txtPrice field to include cents try { = txtPrice.Text ;)"Decimal.Parse(txtPrice.Text).ToString("##0.00 } )catch(System.Exception e { ;"txtPrice.Text = "0 = txtPrice.Text ;)"Decimal.Parse(txtPrice.Text).ToString("##0.00 } // Display the current position // and the number of records = txtRecordPosition.Text (objCurrencyManager.Position + 1) + ;" of " + objCurrencyManager.Count } ﺧﻂ آﺧﺮ اﻳﻦ ﻣﺘﺪ ﻧﻴﺰ ﻣﻮﻗﻌﻴﺖ رﻛﻮرد ﺟﺎري ﺑﻪ ﻫﻤﺮاه ﺗﻌﺪاد رﻛﻮرد ﻫﺎﻳﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ وﺟﻮد دارﻧـﺪ را ﻧﻤـﺎﻳﺶ ﻣـﻲ دﻫـﺪ .ﺑـﺎ اﺳـﺘﻔﺎده از ﺧﺎﺻﻴﺖ Positionﻣﻲ ﺗﻮاﻧﻴﻢ ﻣﻜﺎن رﻛﻮرد ﺟﺎري را ﺑﺪﺳﺖ آورﻳﻢ .اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﻋﺪدي ﻛﻪ از اﻳﻦ ﺧﺎﺻﻴﺖ درﻳﺎﻓـﺖ ﻣﻲ ﻛﻨﻴﻢ ،اﻧﺪﻳﺲ رﻛﻮرد ﺟﺎري از ﺷﻤﺎره ي ﺻﻔﺮ اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ آن را ﺑﺎ ﻋﺪد ﻳﻚ ﺟﻤﻊ ﻛﻨﻴﻢ ﺗﺎ ﻣﻮﻗﻌﻴـﺖ واﻗﻌـﻲ رﻛـﻮرد ﺟـﺎري را ﺑﺪﺳﺖ آورﻳﻢ. ﺑﺮاي ﺑﺪﺳﺖ آوردن ﺗﻌﺪاد رﻛﻮرد ﻫﺎ ﻧﻴﺰ از ﺧﺎﺻﻴﺖ Countاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﺗﻌﺪاد رﻛﻮرد ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ را ﻧﻤـﺎﻳﺶ ﻣـﻲ دﻫﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ – Form_Load ﺑﻌﺪ از اﺗﻤﺎم ﺑﺮرﺳﻲ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﻮﺟﻮد در ﻛﻼس ،Form1ﺑﻬﺘﺮ اﺳﺖ ﻣﺘﺪي ﻛﻪ در آن از زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻫـﺎي ﻗﺒﻠـﻲ اﺳـﺘﻔﺎده ﺷـﺪه اﺳﺖ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ. در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻳﻚ ﻛﻨﺘﺮل ComboBoxوﺟﻮد دارد ﻛﻪ ﻫﻨﮕﺎم ﺟﺴﺘﺠﻮ و ﻳﺎ ﻣﺮﺗﺐ ﻛﺮدن داده ﻫﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴـﺮد .اﻳـﻦ ComboBoxﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻧﺎم ﺳﺘﻮﻧﻬﺎي داده اي ﻛﻪ در DataViewﻗﺮار دارﻧﺪ ﺗﻜﻤﻴﻞ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﺑـﺎ اﺳـﺘﻔﺎده از ﻣﺘـﺪ
٦٦٣
Addاز ﺧﺎﺻﻴﺖ Itemsاﻳﻦ ﻛﻨﺘﺮل ،ﻧﺎم ﺳﺘﻮﻧﻬﺎي ﻣﻮﺟﻮد را ﺑﻪ آن اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ .ﻫﻤﭽﻨﻴﻦ ﻧﺎم ﺳﺘﻮﻧﻬﺎ را ﺑﻪ ﻫﻤﺎن ﺗﺮﺗﻴﺒـﻲ ﻛـﻪ در DataViewﻗﺮار ﮔﺮﻓﺘﻪ اﻧﺪ ﺑﻪ ﻟﻴﺴﺖ اﺿﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛﺮد: )private void Form1_Load(object sender, EventArgs e { // Add items to the combo box... ;)"cboField.Items.Add("Last Name ;)"cboField.Items.Add("First Name ;)"cboField.Items.Add("Book Title ;)"cboField.Items.Add("Price ﺑﻌﺪ از اﺿﺎﻓﻪ ﻛﺮدن ﺗﻤﺎم آﻳﺘﻢ ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل ،ﻣﻲ ﺧﻮاﻫﻴﻢ ﻛﻪ اوﻟﻴﻦ آﻳﺘﻤﻲ ﻛﻪ اﺿﺎﻓﻪ ﻛﺮدﻳﻢ ﺑﻪ ﺻﻮرت اﻧﺘﺨﺎب ﺷﺪه ﻗـﺮار ﺑﮕﻴﺮد .ﺑﻨﺎﺑﺮاﻳﻦ ﺧﺎﺻﻴﺖ SelectedIndexرا ﺑﺮاﺑﺮ ﺑﺎ ﺻﻔﺮ ﻗﺮار ﻣﻲ دﻫﻴﻢ )زﻳﺮا در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ اﻧﺪﻳﺲ آﻳﺘﻢ ﻫـﺎ ﺑـﺎ ﺻـﻔﺮ ﺷﺮوع ﻣﻲ ﺷﻮد( // Make the first item selected... ;cboField.SelectedIndex = 0 ﺳﭙﺲ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ FillDataSetAndViewداده ﻫﺎ را از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺪﺳﺖ آورده و در ﻛﻨﺘﺮل DataSet در ﺑﺮﻧﺎﻣﻪ ﻗﺮار ﻣﻲ دﻫﻴﻢ .ﻫﻤﭽﻨﻴﻦ ﻛﻨﺘﺮل DataViewرا ﻧﻴﺰ ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ از آن اﺳﺘﻔﺎده ﻛﻨـﻴﻢ .ﺑﻌـﺪ از آن ﻧﻴـﺰ ﻣﺘـﺪ BindFieldsرا ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻛﻨﺘﺮل ﻫﺎي ﻣﻮﺟﻮد در ﻓﺮم را ﺑﻪ ﻓﻴﻠﺪ ﻫﺎي داده اي ﻣﻮﺟﻮد در DataViewﻣﺘﺼﻞ ﻛﻨﺪ .در آﺧﺮ ﻧﻴﺰ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ShowPositionﻣﻮﻗﻌﻴﺖ رﻛﻮرد ﺟﺎري و ﻧﻴﺰ ﺗﻌﺪاد رﻛﻮرد ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣـﻪ را در ﻓـﺮم ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ: // Fill the DataSet and bind the fields... ;)(FillDataSetAndView ;)(BindFields // Show the current record position... ;)(ShowPosition }
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ – ﺟﺎ ﺑﻪ ﺟﺎ ﺷﺪن ﺑﻴﻦ رﻛﻮرد ﻫﺎ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ي ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickﻛﻨﺘﺮل btnMoveFirstﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ اوﻟﻴﻦ رﻛﻮرد از داده ﻫﺎ در ﻓﺮم ﻧﻤﺎﻳﺶ داده ﺷﻮد .ﺑﺮاي اﻳﻦ ﻛﺎر از ﺧﺎﺻﻴﺖ Positionدر ﻛﻼس CurrencyManagerاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .ﺑﻪ ﻋﺒﺎرت دﻳﮕـﺮ ﺑﺎ ﻗﺮار دادن ﻣﻘﺪار ﺻﻔﺮ در ﺧﺎﺻﻴﺖ Positionﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ CurrencyManagerﺑﺎﻳﺪ ﺑـﻪ اوﻟـﻴﻦ رﻛـﻮرد ﻣﻮﺟﻮد ﺣﺮﻛﺖ ﻛﻨﺪ: // Set the record position to the first record... ;objCurrencyManager.Position = 0 ٦٦٤
ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﺑﻪ DataViewﻣﺘﺼﻞ ﺷﺪه اﻧﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ ﺗﻐﻴﻴﺮ ﻣﻮﻗﻌﻴﺖ رﻛﻮرد ﺟـﺎري ﺑـﻪ اوﻟـﻴﻦ رﻛﻮرد ،ﺗﻤﺎﻣﻲ ﻛﻨﺘﺮل ﻫﺎي ﻣﻮﺟﻮد در ﻓﺮم اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ رﻛﻮرد اول را ﻧﻤﺎﻳﺶ ﺧﻮاﻫﻨﺪ داد. ﺑﻌﺪ از ﺗﻌﻴﻴﻦ ﻣﻮﻗﻌﻴﺖ رﻛﻮرد ﺟﺎري در ﺑﺮﻧﺎﻣﻪ ،ﺑﺎﻳﺪ ﻣﺘﺪ ShowPositionرا ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ ﺗﺎ اﻃﻼﻋـﺎت ﻣﺮﺑـﻮط ﺑـﻪ ﻣﻮﻗﻌﻴـﺖ رﻛﻮرد ﺟﺎري در ﻓﺮم ﺑﻪ درﺳﺘﻲ ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ: // Show the current record position... ;)(ShowPosition ﺳﭙﺲ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل btnMovePreviousرا ﻣﻲ ﻧﻮﻳﺴﻴﻢ .در اﻳﻦ ﻣﺘﺪ ﺑﺎﻳﺪ ﺑﻪ رﻛﻮرد ﻗﺒﻠﻲ ﺣﺮﻛﺖ ﻛﻨﻴﻢ و ﺑﺮاي اﻳـﻦ ﻛﺎر ﻧﻴﺰ ﺑﺎﻳﺪ ﻳﻚ واﺣﺪ از ﺧﺎﺻﻴﺖ Positionﻛﻢ ﻛﻨﻴﻢ .ﺷﻴﺊ CurrencyManagerﻣﺘﻮﺟﻪ اﻳﻦ ﺗﻐﻴﻴﺮ ﺧﻮاﻫﺪ ﺷﺪ و در ﻧﺘﻴﺠﻪ ﺗﻤﺎم ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻓﺮم اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ رﻛﻮرد ﻗﺒﻠﻲ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻨﺪ. // Move to the previous record... ;objCurrencyManager.Position -= 1 ﻣﺠﺪداً در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﺑﻌﺪ از ﺗﻐﻴﻴﺮ رﻛﻮرد ﺟﺎري ،ﺑﺎﻳﺪ ﻣﺘﺪ ShowPositionرا ﻓﺮاﺧﻮاﻧﻲ ﻛﻨـﻴﻢ ﺗـﺎ اﻃﻼﻋـﺎت ﻧﻤـﺎﻳﺶ داده ﺷﺪه در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﺗﺼﺤﻴﺢ ﺷﻮﻧﺪ. در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل btnMoveNextﻧﻴﺰ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﺷﻤﺎره ي رﻛﻮرد ﺟﺎري را ﻛﻪ در ﺧﺎﺻﻴﺖ Positionﻗـﺮار دارد ﻳﻚ واﺣﺪ اﻓﺰاﻳﺶ دﻫﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ CurrencyManagerاﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ رﻛﻮرد ﺑﻌﺪي را در ﻛﺎدرﻫﺎي ﻣﻮﺟـﻮد در ﻓﺮم ﻧﻤﺎﻳﺶ ﺧﻮاﻫﺪ داد. // Move to the next record... ;objCurrencyManager.Position += 1 در آﺧﺮ ﻧﻴﺰ ﺑﺎﻳﺪ ﻛﺪي را ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻠﻴﺪ btnMoveLastﻗﺮار دﻫﻴﻢ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻛﺎرﺑﺮ روي اﻳـﻦ دﻛﻤـﻪ ﻛﻠﻴـﻚ ﻛـﺮد ،ﺑـﻪ آﺧﺮﻳﻦ رﻛﻮرد داده ﻫﺎ ﻣﻨﺘﻘﻞ ﺷﻮد .ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ ﺧﺎﺻﻴﺖ Positionرا ﺑﺮاﺑﺮ ﺑﺎ اﻧﺪﻳﺲ آﺧﺮﻳﻦ رﻛـﻮرد ﻣﻮﺟـﻮد ،ﻳﻌﻨـﻲ ﺗﻌـﺪاد رﻛﻮرد ﻫﺎ ﻣﻨﻬﺎي ﻳﻚ ﻗﺮار دﻫﻴﻢ و ﺳﭙﺲ ﻣﺘﺪ ShowPositionرا ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ ﺗﺎ اﻃﻼﻋﺎت ﻣﻮﺟﻮد در ﻓﺮم را ﺗﺼﺤﻴﺢ ﻛﻨﺪ: // Set the record position to the last record... = objCurrencyManager.Position ;objCurrencyManager.Count - 1 // Show the current record position... ;)(ShowPosition ﻧﻜﺘﻪ :در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ،ﻫﻤﺎﻧﻨﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ در اوﻟﻴﻦ رﻛﻮرد داده ﻫﺎ ﺑﻮدﻳﻢ ﺑﺎ ﻛﻠﻴﻚ ﺑﺮ روي دﻛﻤﻪ ي ﺑﻌﺪي اﺗﻔﺎق ﺧﺎﺻﻲ رخ ﻧﺨﻮاﻫﺪ داد .زﻳﺮا ﺑﻌﺪ از آﺧﺮﻳﻦ رﻛﻮرد داده ﻫﺎ دﻳﮕﺮ رﻛﻮردي وﺟﻮد ﻧـﺪارد ﻛـﻪ ﺑـﻪ آن ﺑـﺮوﻳﻢ .در اﻳـﻦ ﺷـﺮاﻳﻂ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﺎ ﺗﻨﻈـﻴﻢ ﺧﺎﺻـﻴﺖ Enabledدﻛﻤﻪ ي btnMoveNextو ﻳﺎ btnMovePreviousﺑﻪ ﻣﻘﺪار ،Falseاز ﻛﻠﻴﻚ ﻛـﺮدن روي آﻧﻬﺎ ﺟﻠﻮﮔﻴﺮي ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺮﻧﺎﻣﻪ ﻇﺎﻫﺮ ﺑﻬﺘﺮي ﭘﻴﺪا ﺧﻮاﻫﺪ ﻛﺮد .ﻣﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ ﻣﻮرد را ﺧﻮدﺗﺎن ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ.
٦٦٥
ﺑﻌﺪ از اﺗﻤﺎم اﻳﻦ ﻣﺘﺪ ،اﻳﻦ ﺑﺨﺶ از ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﭘﺎﻳﺎن ﻣﻲ رﺳﺪ .در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﺑﻪ ﻣﻮارد ﻣﺮﺑﻮط ﺑﻪ ﻣﺮﺗﺐ ﺳﺎزي داده ﻫﺎ ﺧﻮاﻫﻴﻢ ﭘﺮداﺧﺖ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﻗﺎﺑﻠﻴﺖ ﻣﺮﺗﺐ ﺳﺎزي ﺑﻪ ﺑﺮﻧﺎﻣﻪ (1ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ Form1ﺑﺮوﻳﺪ و روي دﻛﻤﻪ ي Perform Sortدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗـﺎ ﻣﺘـﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickاﻳﻦ ﻛﻨﺘﺮل اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ: private void btnPerformSort_Click(object sender, )EventArgs e { // Determine the appropriate item selected and set the // Sort property of the DataView object... )switch(cboField.SelectedIndex { case 0: // Last Name ;"objDataView.Sort = "au_lname ;break case 1: // First Name ;"objDataView.Sort = "au_fname ;break case 2: // Book Title ;"objDataView.Sort = "title ;break case 3: // Price ;"objDataView.Sort = "price ;break } // Call the click event for the MoveFirst button... ;)btnMoveFirst_Click(null, null // Display a message // that the records have been sorted... ;"ToolStripStatusLabel1.Text = "Records Sorted } (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ ﺗﺎ ﻗﺎﺑﻠﻴﺘﻲ را ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛـﺮدﻳﻢ را اﻣﺘﺤـﺎن ﻛﻨـﻴﻢ .در ﻛﻨﺘـﺮل ComboBox ﻣﻮﺟﻮد در ﻓﺮم ﻳﻚ ﺳﺘﻮن را اﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ روي دﻛﻤﻪ ي Perform Sortﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗـﺎ داده ﻫـﺎ ﺑـﺮ اﺳﺎس آن ﺳﺘﻮن ﻣﺮﺗﺐ ﺷﻮﻧﺪ .ﺷﻜﻞ 8-16ﻓﺮم ﺑﺮﻧﺎﻣﻪ را در ﺣﺎﻟﺘﻲ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ ﻛﻪ داده ﻫﺎي ﻣﻮﺟـﻮد در آن ﺑـﺮ اﺳـﺎس ﺳﺘﻮن Priceﻣﺮﺗﺐ ﺷﺪه اﻧﺪ:
٦٦٦
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﻣﺸﺨﺺ ﻛﻨﻴﻢcboField اوﻟﻴﻦ ﻛﺎري ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﻧﺠﺎم ﻣﻲ دﻫﻴﻢ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﻣﻘﺪار اﻧﺘﺨﺎب ﺷﺪه در ﻛﻨﺘﺮل .داده ﻫﺎ ﺑﺎﻳﺪ ﺑﺮ اﺳﺎس ﻛﺪام ﺳﺘﻮن ﻣﺮﺗﺐ ﺷﻮﻧﺪ // Determine the appropriate item selected and set the // Sort property of the DataView object... switch(cboField.SelectedIndex) { case 0: // Last Name objDataView.Sort = "au_lname"; break; case 1: // First Name objDataView.Sort = "au_fname"; break; case 2: // Book Title objDataView.Sort = "title"; break; case 3: // Price objDataView.Sort = "price"; break; }
8-16 ﺷﻜﻞ
٦٦٧
در اﻳﻨﺠــﺎ ﺑــﺎ اﺳــﺘﻔﺎده از دﺳــﺘﻮر switchﻣــﻲ ﺗــﻮاﻧﻴﻢ ﺣﺎﻟﺘﻬــﺎي ﻣﺨﺘﻠــﻒ ﻣﻘــﺪار ﺧﺎﺻــﻴﺖ SelectedIndexاز ComboBoxرا ﺑﺮرﺳﻲ ﻛﺮده و ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ ﻛﺎرﺑﺮ ﻣﻲ ﺧﻮاﻫﺪ داده ﻫﺎ را ﺑﺮ اﺳﺎس ﭼﻪ ﺳﺘﻮﻧﻲ ﻣﺮﺗﺐ ﻛﻨﺪ .ﺑﻌﺪ از ﻣﺸﺨﺺ ﺷﺪن ﻧﺎم ﺳﺘﻮن ﻣﻮرد ﻧﻈﺮ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺧﺎﺻﻴﺖ Sortرا ﺑﺮاﺑﺮ ﺑﺎ ﻧﺎم آن ﺳﺘﻮن ﻗﺮار دﻫﻴﻢ ﺗﺎ داده ﻫﺎ ﻣﺮﺗﺐ ﺷﻮﻧﺪ. ﺑﻌﺪ از ﻣﺮﺗﺐ ﺷﺪن داده ﻫﺎ ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﺑﻪ اوﻟﻴﻦ رﻛﻮرد داده ﻫﺎ ﺑﺮوﻳﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﭼﻨﺪﻳﻦ روش وﺟﻮد دارد .روش اول اﻳﻦ اﺳﺖ ﻛﻪ ﺧﺎﺻﻴﺖ Positionرا ﺑﺮاﺑﺮ ﺑﺎ ﺻﻔﺮ ﻗﺮار داده و ﺳﭙﺲ ﻣﺘﺪ ShowPositionرا ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ ،در واﻗﻊ ﻫﻤﺎن ﻛـﺎري را اﻧﺠﺎم دﻫﻴﻢ ﻛﻪ در ﻣﺘﺪ btnMoveFirst_Clickاﻧﺠﺎم داده اﻳﻢ .ﭘﺲ ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از اﻳﻦ روش ﺑﻬﺘﺮ اﺳﺖ ﻛـﻪ ﻣﺘـﺪ btnMoveFirst_Clickرا ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده و ﺑﻪ ﺟﺎي ﭘﺎراﻣﺘﺮﻫﺎي آن ﻣﻘﺪار nullرا ارﺳﺎل ﻛﻨـﻴﻢ .اﻧﺠـﺎم اﻳـﻦ ﻛـﺎر دﻗﻴﻘﺎً ﻣﺸﺎﺑﻪ اﻳﻦ اﺳﺖ ﻛﻪ ﻛﺎرﺑﺮ روي دﻛﻤﻪ ي btnMoveFirstﻛﻠﻴﻚ ﻛﺮده ﺑﺎﺷﺪ. ﻣﺘــﺪ btnMoveFirst_Clickدو ﭘــﺎراﻣﺘﺮ درﻳﺎﻓــﺖ ﻣــﻲ ﻛﻨــﺪ ،ﻳﻜــﻲ از ﻧــﻮع objectو دﻳﮕــﺮي از ﻧــﻮع .EventArgsﻫﻨﮕﺎم ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ﺑﺎﻳﺪ اﻳﻦ دو ﭘﺎراﻣﺘﺮ را ﺑﻪ آن ارﺳﺎل ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر ﻣـﻲ ﺗـﻮاﻧﻴﻢ دو ﺷـﻴﺊ ،ﻳﻜـﻲ از ﻧـﻮع EventArgsو دﻳﮕـﺮي از ﻧــﻮع Objectاﻳﺠــﺎد ﻛـﺮده و آﻧﻬــﺎ را ﺑــﻪ ﻣﺘــﺪ ارﺳـﺎل ﻛﻨــﻴﻢ .اﻣــﺎ ﻫﻤـﺎﻧﻄﻮر ﻛــﻪ در ﻛــﺪ ﻣﺘــﺪ btnMoveFirstﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ از اﻳﻦ دو ﭘﺎراﻣﺘﺮ ﻫﻴﭻ اﺳﺘﻔﺎده اي ﻧﻜﺮده اﻳﻢ ،ﺑﻨﺎﺑﺮاﻳﻦ ﻟﺰوﻣﻲ ﻧﺪارد ﻛﻪ ﻣﻘﺪاري ﺣﺎﻓﻈـﻪ را اﺧﺘﺼﺎص دﻫﻴﻢ ﺗﺎ دو ﺷﻴﺊ اﻳﺠﺎد ﻛﺮده و آﻧﻬﺎ را ﺑﻪ ﻣﺘﺪ ﺑﻔﺮﺳﺘﻴﻢ .ﺑﻠﻜﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﻪ ﺟﺎي اﻳﻦ دو ﺷﻴﺊ ،دو ﻣﻘـﺪار nullرا ﺑـﻪ ﻣﺘـﺪ ارﺳﺎل ﻛﻨﻴﻢ .اﻟﺒﺘﻪ ﻻزم اﺳﺖ ﺑﻪ اﻳﻦ ﻧﻜﺘﻪ دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ اﺳﺘﻔﺎده از اﻳﻦ روش ﻫﻨﮕﺎﻣﻲ ﻛﻪ از اﻳﻦ ﭘﺎراﻣﺘﺮ ﻫﺎ در ﻣﺘﺪ اﺳﺘﻔﺎده ﺷـﺪه ﺑﺎﺷـﺪ، ﺑﺎﻋﺚ اﻳﺠﺎد ﺧﻄﺎﻳﻲ از ﻧﻮع System.NullReferenceExceptionﻣﻲ ﺷﻮد. // Call the click event for the MoveFirst button... ;)btnMoveFirst_Click(null, null ﺑﻌﺪ از اﻳﻨﻜﻪ ﺑﻪ رﻛﻮرد اول رﻓﺘﻴﻢ ﻻزم اﺳﺖ ﻛﻪ ﻣﺘﻨﻲ را در ﻧﻮار وﺿﻌﻴﺖ ﻧﻤﺎﻳﺶ دﻫﻴﻢ ﺗﺎ ﻣﺸﺨﺺ ﺷﻮد ﻛﻪ داده ﻫﺎ ﻣﺮﺗﺐ ﺷﺪه اﻧﺪ .ﺑﺮاي اﻳﻦ ﻛﺎر از ﺧﺎﺻﻴﺖ Textدر ﻛﻨﺘﺮل ToolStripStatusLabel1اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ. // Display a message // that the records have been sorted... ;"ToolStripStatusLabel1.Text = "Records Sorted در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻗﺎﺑﻠﻴﺖ ﺟﺴﺘﺠﻮ ﻛﺮدن را ﻧﻴﺰ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن ﻗﺎﺑﻠﻴﺖ ﺟﺴﺘﺠﻮ ﺑﻪ ﺑﺮﻧﺎﻣﻪ (1ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮوﻳﺪ و روي دﻛﻤﻪ ي Perform Searchدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑـﻮط ﺑـﻪ روﻳـﺪاد Clickآن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: private void btnPerformSearch_Click(object sender, )EventArgs e { // Declare local variables... ;int intPosition
٦٦٨
// Determine the appropriate item selected and set the // Sort property of the DataView object... switch(cboField.SelectedIndex) { case 0: // Last Name objDataView.Sort = "au_lname"; break; case 1: // First Name objDataView.Sort = "au_fname"; break; case 2: // Book Title objDataView.Sort = "title"; break; case 3: // Price objDataView.Sort = "price"; break; } // If the search field is not price then... if (cboField.SelectedIndex < 3) { // Find the last name, first name, or title... intPosition = objDataView.Find(txtSearchCriteria.Text); } else { // otherwise find the price... intPosition = objDataView.Find( Decimal.Parse(txtSearchCriteria.Text)); } if (intPosition == -1) { // Display a message // that the record was not found... ToolStripStatusLabel1.Text = "Record Not Found"; } else { // Otherwise display a message that the record // was found and reposition the CurrencyManager // to that record... ToolStripStatusLabel1.Text = "Record Found"; objCurrencyManager.Position = intPosition; } // Show the current record position...
٦٦٩
;)(ShowPosition } (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ ﺗﺎ ﻗﺎﺑﻠﻴﺖ ﺟﺪﻳﺪ آن را ﻧﻴﺰ اﻣﺘﺤﺎن ﻛﻨﻴﻢ .ﻓﻴﻠﺪي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺟﺴﺘﺠﻮ ﺑﺮ اﺳـﺎس آن ﺻـﻮرت ﮔﻴـﺮد را از داﺧﻞ ComboBoxاﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ ﻋﺒﺎرت ﻣﻮرد ﺟﺴﺘﺠﻮ را در داﺧﻞ ﻓﻴﻠﺪ Search Criteriaوارد ﻛﻨﻴﺪ .در آﺧﺮ ﻧﻴﺰ روي دﻛﻤﻪ ي Perform Searchﻛﻠﻴﻚ ﻛﻨﻴﺪ. اﮔﺮ رﻛﻮرد ﻣﻮرد ﻧﻈﺮ ﺷﻤﺎ در ﺑﻴﻦ داده ﻫﺎ ﭘﻴﺪا ﺷﻮد ،ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ اﻃﻼﻋﺎت آن رﻛـﻮرد در ﻓـﺮم ﻧﻤـﺎﻳﺶ داده ﻣـﻲ ﺷﻮد و ﻣﻮﻗﻌﻴﺖ رﻛﻮرد ﺟﺎري ﺑﻪ رﻛﻮرد ﭘﻴﺪا ﺷﺪه ﺗﻐﻴﻴﺮ ﻣﻲ ﻛﻨﺪ .ﻫﻤﭽﻨﻴﻦ ﭘﻴﻐﺎﻣﻲ در ﻧﻮار اﺑﺰار ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد و ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ رﻛﻮرد ﻣﻮرد ﻧﻈﺮ ﭘﻴﺪا ﺷﺪه اﺳﺖ )ﺷﻜﻞ .(9-16ﻫﻤﭽﻨﻴﻦ اﮔﺮ ﻫﻴﭻ رﻛﻮردي ﭘﻴﺪا ﻧﺸﻮد ،ﻣﺘﻨﻲ در ﻧﻮار وﺿﻌﻴﺖ ﻧﻮﺷـﺘﻪ ﺧﻮاﻫﺪ ﺷﺪ و ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ داده ي ﻣﻮرد ﻧﻈﺮ ﭘﻴﺪا ﻧﺸﺪه اﺳﺖ.
ﺷﻜﻞ 9-16
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اﻳﻦ ﻗﺴﻤﺖ ﻣﻤﻜﻦ اﺳﺖ ﻛﻤﻲ ﭘﻴﭽﻴﺪه ﺗﺮ از ﻗﺴﻤﺖ ﻗﺒﻠﻲ ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ ،زﻳﺮا ﺑﺮاي اﻳﻦ ﻗﺴﻤﺖ ﻣـﻮارد ﺑﻴـﺸﺘﺮي را ﺑﺎﻳـﺪ ﺑﺮرﺳـﻲ ﻛـﺮده و ﺗﺼﻤﻴﻢ ﮔﻴﺮي ﻛﻨﻴﻢ ،ﺑﺮاي ﻣﺜﺎل ﺷﺮاﻳﻄﻲ ﻣﺎﻧﻨﺪ زﻣﺎﻧﻲ ﻛﻪ ﻫﻴﭻ رﻛﻮردي ﭘﻴﺪا ﻧﺸﻮد .اوﻟﻴﻦ ﻛﺎري ﻛﻪ در اﻳﻦ ﻣﺘﺪ اﻧﺠﺎم ﻣـﻲ دﻫـﻴﻢ اﻳﺠـﺎد ﻳﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع intاﺳﺖ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﻣﻜﺎن داده اي ﻛﻪ ﭘﻴﺪا ﺷﺪه اﺳﺖ )و ﻳﺎ ﭘﻴﺪا ﻧﺸﺪن آن را( در آن ﻧﮕﻬﺪاري ﻛﻨﻴﻢ. // Declare local variables... ;int intPosition
٦٧٠
ﺳﭙﺲ ﺑﺎﻳﺪ داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ را ﺑﺮ اﺳﺎس ﺳﺘﻮﻧﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ در آن ﺟﺴﺘﺠﻮ ﻛﻨﻴﻢ ﻣﺮﺗﺐ ﻛﻨﻴﻢ .زﻳﺮا ﻣﺘﺪ Findﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺪ در ﺳﺘﻮﻧﻬﺎي ﻣﺮﺗﺐ ﺷﺪه ﺑﻪ دﻧﺒﺎل داده ي ﻣﻮرد ﻧﻈﺮ ﺑﮕـﺮدد .ﺑﻨـﺎﺑﺮاﻳﻦ ﻫﻤﺎﻧﻨـﺪ ﻗـﺴﻤﺖ ﻗﺒـﻞ ﺑـﺎ اﺳـﺘﻔﺎده از دﺳـﺘﻮر switch ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﺟﺴﺘﺠﻮ در ﻛﺪام ﺳﺘﻮن ﻣﻲ ﺧﻮاﻫﺪ اﻧﺠﺎم ﺷﻮد ،ﺳﭙﺲ ﻣﻘﺪار ﺧﺎﺻﻴﺖ Sortرا ﺑﺮاﺑﺮ ﺑﺎ ﻧﺎم آن ﺳﺘﻮن ﻗـﺮار ﻣـﻲ دﻫﻴﻢ ﺗﺎ داده ﻫﺎ ﺑﺮ اﺳﺎس آن ﺳﺘﻮن ﻣﺮﺗﺐ ﺷﻮﻧﺪ: // Determine the appropriate item selected and set the // Sort property of the DataView object... )switch(cboField.SelectedIndex { case 0: // Last Name ;"objDataView.Sort = "au_lname ;break case 1: // First Name ;"objDataView.Sort = "au_fname ;break case 2: // Book Title ;"objDataView.Sort = "title ;break case 3: // Price ;"objDataView.Sort = "price ;break } ﻧﻜﺘـــﻪ :در اﻳـــﻦ ﻗـــﺴﻤﺖ ﺑـــﺮاي ﻣﺮﺗـــﺐ ﻛـــﺮدن داده ﻫـــﺎ ﺑـــﻪ ﺟـــﺎي اﺳـــﺘﻔﺎده از اﻳـــﻦ روش ،ﻣـــﻲ ﺗﻮاﻧـــﺴﺘﻴﻢ ﻣﺘـــﺪ btnPerformSort_Clickرا ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ ﺗﺎ آن ﻣﺘﺪ ﻋﻤﻞ ﻣﺮﺗﺐ ﺳﺎزي را اﻧﺠﺎم دﻫﺪ .ﺳـﭙﺲ ﺑـﺎ اﺳـﺘﻔﺎده از ﻣﺘـﺪ Findﺑﻪ دﻧﺒﺎل داده ي ﻣﻮرد ﻧﻈﺮ ﻣﻲ ﮔﺸﺘﻴﻢ .در اﻳﻦ ﺻﻮرت ﺑـﺮاي ﭘﺎراﻣﺘﺮﻫـﺎي ﻣﺘـﺪ btnPerformSort_Click ﻫﻢ ﻣﻲ ﺗﻮاﻧﺴﺘﻴﻢ از ﻣﻘﺪار nullاﺳﺘﻔﺎده ﻛﻨﻴﻢ. ﺳﺘﻮﻧﻬﺎي LastName ،FirstNameو ﻫﻤﭽﻨﻴﻦ ﺳﺘﻮن Titleداراي ﻣﻘﺎدﻳﺮ رﺷﺘﻪ اي ﻫﺴﺘﻨﺪ ،در ﺻﻮرﺗﻲ ﻛﻪ ﺳـﺘﻮن Priceداراي ﻣﻘﺪار ﻋﺪدي اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ اﺑﺘﺪا ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ ﺟﺴﺘﺠﻮ در ﻛﺪاﻣﻴﻚ از اﻳﻦ ﺳﺘﻮﻧﻬﺎ ﺻﻮرت ﺧﻮاﻫـﺪ ﮔﺮﻓـﺖ و ﺳﭙﺲ اﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﻛﻪ در ﺳﺘﻮن Priceﺟﺴﺘﺠﻮ ﻛﻨﻴﻢ ،ﻣﻘﺪار وارد ﺷﺪه در ﻛﺎدر txtSearchCriteriaرا ﺑـﻪ ﻋـﺪد از ﻧﻮع Decimalﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ. ﻣﺠﺪدا ﺑﺮاي ﺗﺸﺨﻴﺺ اﻳﻦ ﻣﻮرد ﻧﻴﺰ ﺑﺎﻳﺪ از ﺧﺎﺻﻴﺖ SelectedIndexدر ﻛﻨﺘﺮل cboFieldاﺳﺘﻔﺎده ﻛﻨﻴﻢ .اﮔﺮ ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ از 3ﻛﻤﺘﺮ ﺑﻮد ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻳﻜﻲ از ﺳﻪ ﺳﺘﻮن LastName ،FirstNameو ﻳـﺎ Titleاﻧﺘﺨـﺎب ﺷﺪه اﺳﺖ. در اﻳﻦ ﺷﺮاﻳﻂ ﻣﺘﺪ Findرا ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده و ﻣﻘﺪار وارد ﺷﺪه در ﻛﺎدر txtSearchCriteriaرا ﻧﻴﺰ ﺑﻪ ﻋﻨﻮان ﭘـﺎراﻣﺘﺮ ﺑﻪ آن ارﺳﺎل ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ در ﺳﺘﻮن ﻣﺸﺨﺺ ﺷﺪه ،ﺑﻪ دﻧﺒﺎل آن داده ﺑﮕﺮدد و ﺳﭙﺲ ﻧﺘﻴﺠـﻪ را در ﻣﺘﻐﻴﻴـﺮ intPositionﻗـﺮار دﻫﺪ. اﻣﺎ اﮔﺮ ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﺮاﺑﺮ ﺑﺎ 3ﺑﻮد ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﺟﺴﺘﺠﻮ ﺑﺎﻳﺪ ﺑﺮ اﺳﺎس ﻓﻴﻠﺪ Priceﺻﻮرت ﮔﻴـﺮد .ﺑﻨـﺎﺑﺮاﻳﻦ اﺑﺘـﺪا ﺑـﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ Parseدر ﻛﻼس Decimalﻣﺘﻦ وارد ﺷﺪه در ﻛﺎدر txtSearchCriteriaرا ﺑﻪ ﻳـﻚ ﻋـﺪد از ﻧﻮع Decimalﺗﺒﺪﻳﻞ ﻣﻲ ﻛﻨﻴﻢ .ﺳﭙﺲ آن را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ ﺑﻪ ﻣﺘﺪ Findارﺳﺎل ﻣﻲ ﻛﻨﻴﻢ.
٦٧١
// If the search field is not price then... )if (cboField.SelectedIndex < 3 { // Find the last name, first name, or title... = intPosition ;)objDataView.Find(txtSearchCriteria.Text } else { // otherwise find the price... (intPosition = objDataView.Find ;))Decimal.Parse(txtSearchCriteria.Text } ﺑﻌﺪ از اﻳﻨﻜﻪ ﻣﺘﺪ Findاز ﻛﻼس DataViewرا اﺟﺮا ﻛﺮده و ﻧﺘﻴﺠﻪ ي آن را در ﻣﺘﻐﻴﻴﺮ intPositionﻗـﺮار دادﻳـﻢ، ﺑﺎﻳﺪ اﻳﻦ ﻧﺘﻴﺠﻪ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ﺗﺎ ﻣﺸﺨﺺ ﺷﻮد داده ي ﻣﻮرد ﻧﻈﺮ ﭘﻴﺪا ﺷﺪه اﺳﺖ ﻳﺎ ﻧﻪ؟ اﮔﺮ اﻳﻦ ﻣﺘﻐﻴﻴﺮ ﺣﺎوي ﻣﻘﺪار -1ﺑـﻮد ﺑـﻪ اﻳـﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ داده ي ﻣﻮرد ﻧﻈﺮ ﭘﻴﺪا ﻧﺸﺪه اﺳﺖ .در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻫﺮ ﻋﺪدي ﺑﻪ ﺟﺰ ،-1ﻧﺸﺎن دﻫﻨﺪه ي ﺷﻤﺎره رﻛﻮرد اي اﺳﺖ ﻛﻪ ﺣﺎوي داده ي ﻣﻮرد ﻧﻈﺮ اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﻣﻘﺪار ﻣﺘﻐﻴﻴﺮ intPositionﺑﺮاﺑﺮ ﺑـﺎ -1ﺑـﻮد ﺑﺎﻳـﺪ ﭘﻴﻐـﺎﻣﻲ را در ﻧـﻮار وﺿـﻌﻴﺖ ﻧﻤﺎﻳﺶ دﻫﻴﻢ ﻛﻪ ﻣﺸﺨﺺ ﻛﻨﺪ داده ي ﻣﻮرد ﻧﻈﺮ ﻳﺎﻓﺘﻪ ﻧﺸﺪه اﺳﺖ .اﻣﺎ اﮔﺮ ﻋﺪدي ﺑﻪ ﺟﺰ -1در intPositionﻗﺮار داﺷـﺖ، ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ Positionاز ﻛﻼس CurrencyManagerﻣﻮﻗﻌﻴﺖ رﻛﻮرد ﺟﺎري در ﺑﺮﻧﺎﻣﻪ را ﺑـﻪ رﻛـﻮرد ﻳﺎﻓﺘﻪ ﺷﺪه ﺗﻐﻴﻴﺮ دﻫﻴﻢ و ﻫﻤﭽﻨﻴﻦ ﻣﺘﻨﻲ را در ﻧﻮار وﺿﻌﻴﺖ ﻧﻤﺎﻳﺶ دﻫﻴﻢ ﻛﻪ ﻣﺸﺨﺺ ﻛﻨﺪ داده ي ﻣﻮرد ﻧﻈﺮ ﭘﻴﺪا ﺷﺪه اﺳﺖ. )if (intPosition == -1 { // Display a message // that the record was not found... ;"ToolStripStatusLabel1.Text = "Record Not Found } else { // Otherwise display a message that the record // was found and reposition the CurrencyManager // to that record... ;"ToolStripStatusLabel1.Text = "Record Found ;objCurrencyManager.Position = intPosition } ﻧﻜﺘﻪ :ﻫﻨﮕﺎم اﺳﺘﻔﺎده از ﻣﺘﺪ Findدﻗﺖ ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ ﻣﺘﺪ دﻗﻴﻘﺎً ﻋﺒﺎرﺗﻲ را ﻛﻪ ﺑﻪ آن ﻓﺮﺳﺘﺎده ﺷﺪه اﺳﺖ ﺟـﺴﺘﺠﻮ ﻣـﻲ ﻛﻨـﺪ و ﻓﻘـﻂ زﻣﺎﻧﻲ ﺷﻤﺎره رﻛﻮرد داده اي ﺑﺮﻣﻲ ﮔﺮداﻧﺪ ﻛﻪ آن داده ﺑﺮاﺑﺮ ﺑﺎ ﻋﺒﺎرﺗﻲ ﺑﺎﺷﺪ ﻛﻪ ﺑﻪ ﻣﺘﺪ ﻓﺮﺳﺘﺎده ﺷﺪه اﺳﺖ .اﻟﺒﺘـﻪ اﻳـﻦ ﻣﺘـﺪ ﺑﺰرﮔـﻲ و ﻳـﺎ ﻛﻮﭼﻜﻲ ﺣﺮوف را در ﻧﻈﺮ ﻧﻤﻲ ﮔﻴﺮد .ﺑﺮاي ﻣﺜﺎل ﻋﺒﺎرت Annو ANNاز ﻧﻈﺮ اﻳﻦ ﻣﺘﺪ ﻳﻜﺴﺎن ﻫﺴﺘﻨﺪ و ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﻫﻨﮕـﺎم وارد ﻛﺮدن ﻣﺘﻦ ﺑﺮاي ﺟﺴﺘﺠﻮ ﺑﻪ اﻧﺪازه ي ﺣﺮوف ﻧﻴﺰ دﻗﺖ ﻛﻨﻴﺪ.
٦٧٢
آﺧﺮﻳﻦ ﻛﺎري ﻛﻪ در اﻳﻦ ﻣﺘﺪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﻢ اﻳﻦ اﺳﺖ ﻛﻪ ﻣﻮﻗﻌﻴﺖ رﻛﻮرد ﺟﺪﻳﺪ را در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﻫﻴﻢ و ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗـﻮاﻧﻴﻢ از ﻣﺘﺪ ShowPositionاﺳﺘﻔﺎده ﻛﻨﻴﻢ. ﺣﺎل ﺑﺮاي ﺗﻜﻤﻴﻞ ﺑﺮﻧﺎﻣﻪ ،ﺑﺎﻳﺪ ﻗﺎﺑﻠﻴﺖ ﻫﺎي اﺿﺎﻓﻪ ﻛﺮدن رﻛﻮرد ﺟﺪﻳﺪ ،ﺣﺬف ﻛﺮدن ﻳﻚ رﻛﻮرد و ﻳﺎ وﻳﺮاﻳﺶ ﻛﺮدن آن را ﻧﻴﺰ ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ .در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ،ﻧﺤﻮه ي اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ رﻛﻮرد ﺟﺪﻳﺪ ﺑﻪ داده ﻫﺎي ﻣﻮﺟﻮد را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :اﺿﺎﻓﻪ ﻛﺮدن رﻛﻮرد ﺟﺪﻳﺪ (1اﺑﺘﺪا ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم Form1ﺑﺮوﻳﺪ و روي دﻛﻤﻪ ي btnNewدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑـﻮط ﺑـﻪ روﻳـﺪاد Clickآن اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: )private void btnNew_Click(object sender, EventArgs e { // Clear the book title and price fields... ;"" = txtBookTitle.Text ;"" = txtPrice.Text } (2ﺣﺎل ﺑﺎﻳﺪ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻣﺘﺪ btnAdd_Clickرا وارد ﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ ﻣـﺴﺌﻮل اﺿـﺎﻓﻪ ﻛـﺮدن ﻳـﻚ رﻛـﻮرد داده اي ﺟﺪﻳﺪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺳﺖ .اﻳﻦ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ،ﻃﻮﻻﻧﻲ ﺗﺮﻳﻦ زﻳﺮ ﺑﺮﻧﺎﻣﻪ اي اﺳﺖ ﻛﻪ در اﻳﻦ ﭘﺮوژه وﺟﻮد دارد و ﻛﺪ زﻳـﺎدي را ﺷـﺎﻣﻞ ﻣﻲ ﺷﻮد .دﻟﻴﻞ آن ﻧﻴﺰ راﺑﻄﻪ ي ﺑﻴﻦ ﻋﻨﻮان ﻛﺘﺎﺑﻬﺎ و ﻧﻴﺰ ﻧﻮﻳﺴﻨﺪﮔﺎن آﻧﻬﺎ و ﻧﻴﺰ ﻛﻠﻴﺪ اﺻﻠﻲ ﻛﻪ ﺑﺮاي ﻋﻨﻮان ﻛﺘﺎﺑﻬﺎ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد اﺳﺖ .ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮوﻳﺪ و روي دﻛﻤﻪ ي Addدو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickاﻳﻦ ﻛﻨﺘﺮل اﻳﺠﺎد ﺷﻮد .ﺳﭙﺲ ﻛﺪ زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ: )private void btnAdd_Click(object sender, EventArgs e { // Declare local variables and objects... ;int intPosition, intMaxID ;String strID ;)(SqlCommand objCommand = new SqlCommand // Save the current record position... ;intPosition = objCurrencyManager.Position // Create a new SqlCommand object... (SqlCommand maxIdCommand = new SqlCommand "SELECT MAX(title_id)" + "FROM titles WHERE title_id LIKE 'DM%'", ;)objConnection // Open the connection, execute the command ;)(objConnection.Open ;)(Object maxId = maxIdCommand.ExecuteScalar
٦٧٣
// If the MaxID column is null... if (maxId == DBNull.Value) { // Set a default value of 1000... intMaxID = 1000; } else { // otherwise set the strID variable // to the value in MaxID... strID = (String)maxId; // Get the integer part of the string... intMaxID = int.Parse(strID.Remove(0, 2)); // Increment the value... intMaxID += 1; } // Finally, set the new ID... strID = "DM" + intMaxID.ToString(); // Set the SqlCommand object properties... objCommand.Connection = objConnection; objCommand.CommandText = "INSERT INTO titles " + "(title_id, title, type, price, pubdate) " + "VALUES(@title_id,@title,@type,@price,@pubdate);" + "INSERT INTO titleauthor (au_id, title_id) " + "VALUES(@au_id,@title_id)"; // Add parameters for the placeholders in the SQL in // the CommandText property... // Parameter for the title_id column... objCommand.Parameters.AddWithValue("@title_id", strID); // Parameter for the title column... objCommand.Parameters.AddWithValue("@title", txtBookTitle.Text); // Parameter for the type column objCommand.Parameters.AddWithValue("@type", "Demo"); // Parameter for the price column... objCommand.Parameters.AddWithValue("@price", txtPrice.Text).DbType = DbType.Currency;
٦٧٤
// Parameter for the pubdate column objCommand.Parameters.AddWithValue("@pubdate", DateTime.Now); // Parameter for the au_id column... objCommand.Parameters.AddWithValue("@au_id", this.BindingContext[objDataView,"au_id"].Current); // Execute the SqlCommand object // to insert the new data... try { objCommand.ExecuteNonQuery(); } catch(SqlException SqlExceptionErr) { MessageBox.Show(SqlExceptionErr.Message); } // Close the connection... objConnection.Close(); // Fill the dataset and bind the fields... FillDataSetAndView(); BindFields(); // Set the record position // to the one that you saved... objCurrencyManager.Position = intPosition; // Show the current record position... ShowPosition(); // Display a message that the record was added... ToolStripStatusLabel1.Text = "Record Added"; } ﺳﭙﺲ روي دﻛﻤـﻪ، اﻧﺘﺨﺎب ﻛﻨﻴﺪ،( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﻛﺎرﺑﺮي را ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻋﻨﻮان ﻛﺘﺎب ﺟﺪﻳﺪي را ﺑﺮاي او ﺛﺒﺖ ﻛﻨﻴﺪ3 ﺧﺎﻟﻲ ﺧﻮاﻫﻨـﺪ ﺷـﺪ و ﻣـﻲ ﺗﻮاﻧﻴـﺪ دادهPrice وBook Title ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎدرﻫﺎي. ﻛﻠﻴﻚ ﻛﻨﻴﺪAdd ي در ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺗﻌﺪاد رﻛﻮرد ﻫﺎﻳﻲ ﻛﻪ ﻫﻢ اﻛﻨـﻮن وﺟـﻮد دارﻧـﺪ. وارد ﻛﻨﻴﺪ10-16 ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻛﺘﺎب ﺟﺪﻳﺪ را ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ .(10-16 رﻛﻮرد در ﺷﻜﻞ25) ﺗﻮﺟﻪ ﻛﻨﻴﺪ
٦٧٥
ﺷﻜﻞ 10-16 (4ﺣﺎل ﻧﺎم ﻛﺘﺎب و ﻗﺴﻤﺖ آن را در ﻓﻴﻠﺪ ﻫﺎي ﻣﺮﺑﻮﻃﻪ وارد ﻛﺮده و روي دﻛﻤﻪ ي Addﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴـﺐ ﭘﻴﻐـﺎﻣﻲ در ﻧﻮار وﺿﻌﻴﺖ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و ﺑﻴﺎن ﻣﻲ ﻛﻨﺪ ﻛﻪ رﻛﻮرد ﺟﺪﻳﺪ ﺑﺎ ﻣﻮﻓﻘﻴﺖ اﺿﺎﻓﻪ ﺷﺪه اﺳﺖ .ﻫﻤﭽﻨﻴﻦ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ 11-16ﻣﺸﺨﺺ اﺳﺖ ﺗﻌﺪاد رﻛﻮرد ﻫﺎ در ﺑﺮﻧﺎﻣﻪ ﻳﻚ واﺣﺪ اﻓﺰاﻳﺶ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ )در اﻳﻦ ﺷﻜﻞ 26رﻛﻮرد وﺟﻮد دارد(.
ﺷﻜﻞ 11-16
٦٧٦
ﺣﺎل ﺑﻬﺘﺮ اﺳﺖ ﻧﺤﻮه ي ﻋﻤﻠﻜﺮد ﺑﺮﻧﺎﻣﻪ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺗﻨﻬﺎ اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ اﺿﺎﻓﻪ ﻛﻨﻴﻢ ،ﻧﺎم و ﻗﻴﻤﺖ ﻛﺘﺎب ﺟﺪﻳﺪ اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻪ ﺟﺎي اﻳﻨﻜـﻪ اﻃﻼﻋـﺎت داﺧـﻞ ﻛـﺎدر ﻫﺎي Priceو Book Titleرا اﻧﺘﺨﺎب ﻛﺮده ،ﭘﺎك ﻛﻨﻴﻢ و ﺳﭙﺲ اﻃﻼﻋﺎت ﺟﺪﻳﺪ را در آﻧﻬـﺎ وارد ﻛﻨـﻴﻢ ،ﻣـﻲ ﺗـﻮاﻧﻴﻢ ﺑـﻪ ﺳﺎدﮔﻲ روي ﻛﻠﻴﺪ Newدر ﻓﺮم ﻛﻠﻴﻚ ﻛﻨﻴﻢ .وﻇﻴﻔﻪ ي اﻳﻦ ﻛﻠﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ داده ﻫﺎي درون ﻛﺎدرﻫﺎي Priceو ﻧﻴﺰ Book Titleرا ﭘﺎك ﻛﻨﺪ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ داده ﻫﺎي ﺟﺪﻳﺪ را در آن وارد ﻛﻨﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ در ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ دﻛﻤﻪ ،ﺧﺎﺻـﻴﺖ Textاﻳـﻦ دو ﻛﻨﺘﺮل TextBoxرا ﺑﺮاﺑﺮ ﺑﺎ رﺷﺘﻪ ي ﺧﺎﻟﻲ ﻗﺮار ﻣﻲ دﻫﻴﻢ: )private void btnNew_Click(object sender, EventArgs e { // Clear the book title and price fields... ;"" = txtBookTitle.Text ;"" = txtPrice.Text } ﻫﻨﮕﺎﻣﻲ ﻛﻪ روي دﻛﻤﻪ ي Newﻛﻠﻴﻚ ﻛﻨﻴﺪ اﻳﻦ دو ﻛﺎدر ﺧﺎﻟﻲ ﺧﻮاﻫﻨﺪ ﺷﺪ ،ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﻛﺎرﺑﺮ در ﺣﺎل وﻳﺮاﻳﺶ ﻛﺮدن اﻃﻼﻋﺎت ﺑﺎﺷﺪ ﺗﻤﺎم ﺗﻐﻴﻴﺮات وارد ﺷﺪه از دﺳﺖ ﺧﻮاﻫﻨﺪ رﻓﺖ .ﻣﻌﻤﻮﻻ در ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻗﺴﻤﺘﻲ را ﺑﻪ ﻛﺪ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ از اﻳﻦ ﻧﻮع ﻣﺸﻜﻼت ﺟﻠﻮﮔﻴﺮي ﻛﻨﺪ ،اﻣﺎ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻓﻌﻼ ﻧﻴﺎزي ﺑﻪ اﻳﻦ ﻛﺎر ﻧﺪارﻳﻢ. ﺑﻬﺘﺮ اﺳﺖ ﻗﺒﻞ از ﺗﻮﺿﻴﺢ اداﻣﻪ ي ﻣﺘﺪ ،ﻣﻔﻬﻮم ﻛﻠﻴﺪ اﺻﻠﻲ در ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ را ﺗﻮﺿﻴﺢ دﻫﻴﻢ .در ﻫﺮ ﺟﺪول از ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ ﻛـﻪ ﺑﺨﻮاﻫﻴﻢ از ﻣﻨﺤﺼﺮ ﺑﻪ ﻓﺮد ﺑﻮدن داده ﻫﺎي ﻣﻮﺟﻮد در ﻫﺮ رﻛﻮرد از ﺟﺪول ﻣﻄﻤﺌﻦ ﺷﻮﻳﻢ ،ﻣﻌﻤﻮﻻ ﻳﻚ ﺳﺘﻮن از ﺟﺪول را ﺑﻪ ﻋﻨﻮان ﻛﻠﻴﺪ اﺻﻠﻲ 1در ﻧﻈﺮ ﻣﻲ ﮔﻴﺮﻳﻢ ،ﺳﭙﺲ آن را در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﻪ ﻋﻨـﻮان PrimaryKeyﻣـﺸﺨﺺ ﻣـﻲ ﻛﻨـﻴﻢ .ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﻢ داده اي را در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ وارد ﻛﻨﻴﻢ ،ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺑﺘﺪا ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﺪ ﻛﻪ رﻛﻮردي ﺑﺎ ﻛﻠﻴـﺪ اﺻـﻠﻲ ﻛﻪ ﺑﺮاي رﻛﻮرد ﺟﺪﻳﺪ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ وﺟﻮد ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ ،ﺳﭙﺲ رﻛﻮرد ﺟﺪﻳﺪ را ﺑﻪ ﺟﺪول ﻣﻮرد ﻧﻈﺮ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ. در ﺟﺪول titlesﻧﻴﺰ ﺳﺘﻮن title_idﻛﻪ ﺑﻪ ﻋﻨﻮان PrimaryKeyﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ،از ﻳﻚ ﭘﻴﺸﻮﻧﺪ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ي ﮔﺮوه ﻛﺘﺎب و ﻳﻚ ﻋﺪد ﺗﺮﺗﻴﺒﻲ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن ﻣﻘﺪاري ﻛﻪ ﺑﺎﻳﺪ در ﺳﺘﻮن ﻛﻠﻴـﺪ اﺻـﻠﻲ اﻳـﻦ ﺟﺪول ﻗﺮار ﺑﮕﻴﺮد ،اﺑﺘﺪا ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ ﺗﺎ ﻛﻨﻮن ﭼﻨﺪ ﻋﻨﻮان ﻛﺘﺎب از اﻳﻦ ﮔﺮوه در ﺟﺪول ﺛﺒﺖ ﺷﺪه اﻧﺪ .ﺳﭙﺲ ﻳﻚ واﺣﺪ ﺑﻪ ﻋـﺪد ﺑﺪﺳﺖ آﻣﺪه اﺿﺎﻓﻪ ﻛﺮده و آن را ﺑﻪ ﻋﻨﻮان ﻣﻘﺪار ﺳﺘﻮن ﻛﻠﻴﺪ اﺻﻠﻲ اﻳﻦ رﻛﻮرد ﻗﺮار دﻫﻴﻢ. در زﻳﺮ ﺑﺮﻧﺎﻣﻪ ي btnAdd_Clickاﺑﺘﺪا ﻣﺘﻐﻴﻴﺮ ﻫﺎ و اﺷﻴﺎﻳﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ در ﻃﻮل ﺑﺮﻧﺎﻣﻪ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﻢ را ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ .ﻣﺘﻐﻴﻴﺮ intPositionﺑﺮاي ﻧﮕﻬﺪاري ﻣﻮﻗﻌﻴﺖ رﻛﻮرد ﺟﺎري ﺑـﻪ ﻛـﺎر ﻣـﻲ رود و ﻣﺘﻐﻴﻴـﺮ intMaxIDﻧﻴـﺰ ﺑـﺮاي ﻧﮕﻬﺪاري ﺗﻌﺪاد ﻋﻨﺎوﻳﻦ ﻛﺘﺎﺑﻲ ﻛﻪ از ﻳﻚ ﮔﺮوه در ﺟﺪول ﺑﻪ ﺛﺒﺖ رﺳﻴﺪه اﻧﺪ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد .ﻣﺘﻐﻴـﺮ strIDﺑـﺮاي ﻧﮕﻬـﺪاري ﻛﻠﻴـﺪ اﺻﻠﻲ رﻛﻮردي ﻛﻪ ﻗﺮار اﺳﺖ در ﺟﺪول titlesﺛﺒﺖ ﺷﻮد ﺑﻪ ﻛﺎر ﻣﻲ رود .در آﺧﺮ ،ﺷﻴﺊ objCommandﻧﻴﺰ ﺑﺮاي ﻧﮕﻬﺪاري دﺳﺘﻮرات SQLﻣﺮﺑﻮط ﺑﻪ ﻗﺮار دادن ﻳﻚ رﻛﻮرد ﺟﺪﻳﺪ از اﻃﻼﻋﺎت در ﺟﺪول ﻫـﺎي titlesو authortitleﺑـﻪ ﻛـﺎر ﻣﻲ رود.
Primary Key
1
٦٧٧
ﺑﻬﺘﺮ اﺳﺖ ﻗﺒﻞ از ﻫﺮ ﭼﻴﺰ ﻣﻮﻗﻌﻴﺖ رﻛﻮرد ﺟﺎري را در ﻣﺘﻐﻴﻴﺮ intPositionﻗﺮار دﻫﻴﻢ ،ﺗﺎ ﺑﻌﺪ از اﻳﻨﻜﻪ رﻛـﻮرد داده اي ﺟﺪﻳـﺪ را ﺑﻪ ﺟﺪول در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺿﺎﻓﻪ ﻛﺮدﻳﻢ و ﻛﻨﺘﺮل DataViewرا ﭘﺮ ﻛﺮدﻳﻢ ،ﺑﺘﻮاﻧﻴﻢ ﻣﺠﺪداً ﺑﻪ اﻳﻦ رﻛﻮرد ﺑﺮﮔﺮدﻳﻢ: // Save the current record position... ;intPosition = objCurrencyManager.Position ﺣﺎل ﺑﺎﻳﺪ ﻳﻚ دﺳﺘﻮر SQLرا در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺟﺮا ﻛﻨﻴﻢ ﺗﺎ ﺑﺪاﻧﻴﻢ ﭼﻪ ﺷﻨﺎﺳﻪ اي را ﺑﺎﻳﺪ ﺑﻪ ﻋﻨﻮان ﻛﻠﻴـﺪ اﺻـﻠﻲ ﺑـﺮاي ﺛﺒـﺖ رﻛـﻮرد ﺟﺪﻳﺪ در ﺟﺪول titlesﺑﻪ ﻛﺎر ﺑﺒﺮﻳﻢ .اﻳﻦ دﺳﺘﻮر SQLرا در ﻳﻚ ﺷﻴﺊ از ﻛﻼس SqlCommandﻗﺮار ﻣﻲ دﻫﻴﻢ و ﺳﭙﺲ آن را در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺟﺮا ﻣﻲ ﻛﻨﻴﻢ .وﻇﻴﻔﻪ ي اﻳﻦ دﺳﺘﻮر اﻳﻦ اﺳﺖ ﻛﻪ در ﺑﻴﻦ ﺷﻨﺎﺳﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﺎ ﭘﻴﺸﻮﻧﺪ DMﺷـﺮوع ﻣـﻲ ﺷـﻮﻧﺪ، ﺷﻨﺎﺳﻪ اي ﻛﻪ داراي ﺑﺰرﮔﺘﺮﻳﻦ ﻋﺪد اﺳﺖ را ﺑﺮﮔﺮداﻧﺪ. ﻧﻜﺘﻪ :در ﺟﺪول titlesﻫﻴﭻ ﻛﺘﺎﺑﻲ در ﮔﺮوه Demoﻗﺮار ﻧﺪارد ،ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻤﺎم ﻛﺘﺎﺑﻬﺎﻳﻲ ﻛﻪ در ﻃﻮل ﺑﺮﻧﺎﻣﻪ ﺛﺒﺖ ﻣﻲ ﻛﻨـﻴﻢ را در ﮔﺮوه Demoﻗﺮار داده و ﭘﻴﺸﻮﻧﺪ DMرا ﺑﺮاي آﻧﻬﺎ در ﻧﻈﺮ ﻣﻲ ﮔﻴﺮﻳﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﻌﺪ از اﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ،ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﻢ داده ﻫﺎ را در ﻧﺮم اﻓﺰار ﻣﺮﺑﻮط ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ،ﺑﻪ راﺣﺘﻲ ﻣﻲ ﺗﻮاﻧﻴﻢ رﻛﻮرد ﻫﺎﻳﻲ ﻛﻪ ﺧﻮد اﺿﺎﻓﻪ ﻛـﺮده اﻳـﻢ را ﺗـﺸﺨﻴﺺ داده و آﻧﻬﺎ را ﺣﺬف ﻛﻨﻴﻢ. ﺗﺎﺑﻊ MAXﻛﻪ در اﻳﻦ دﺳﺘﻮر SQLاز آن اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ ،ﻳﻚ ﺳﺘﻮن از داده ﻫﺎ را درﻳﺎﻓﺖ ﻛﺮده و ﺑﺰرﮔﺘﺮﻳﻦ آن را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠـﻪ ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .ﻫﻤﭽﻨﻴﻦ در اﻳﻦ دﺳﺘﻮر از ﻋﺒﺎرت LIKEاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻓﻘﻂ داده ﻫﺎﻳﻲ ﺑﺮرﺳﻲ ﺷﻮﻧﺪ ﻛﻪ ﺑﺎ ) DMﻣﺸﺨﺺ ﻛﻨﻨﺪه ي ﮔﺮوه ﻛﺘﺎﺑﻬﺎي (Demoﺷﺮوع ﻣﻲ ﺷﻮﻧﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻦ دﺳﺘﻮر ﺑﻪ ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﻲ ﮔﻮﻳﻴﻢ ﻛﻪ از ﺳﺘﻮن title_idدر ﺟﺪول ،Titlesداده ﻫﺎﻳﻲ را ﻛﻪ ﺑﺎ DMﺷﺮوع ﻣﻲ ﺷﻮﻧﺪ را اﻧﺘﺨﺎب ﻛـﺮده و ﺳـﭙﺲ از ﺑـﻴﻦ اﻳـﻦ داده ﻫـﺎ، ﺑﺰرﮔﺘﺮﻳﻦ آﻧﻬﺎ را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﮔﺮدان: // Create a new SqlCommand object... (SqlCommand maxIdCommand = new SqlCommand "SELECT MAX(title_id)" + "FROM titles WHERE title_id LIKE 'DM%'", ;)objConnection ﻫﻤﺎﻧﻄﻮر ﻛﻪ اﺣﺘﻤﺎﻻ ﺗﺎ ﻛﻨﻮن ﻣﺘﻮﺟﻪ ﺷﺪه اﻳﺪ ،اﻳﻦ دﺳﺘﻮر ﻓﻘﻂ ﻳﻚ داده را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﻣـﻲ ﮔﺮداﻧـﺪ :ﺑﺰرﮔﺘـﺮﻳﻦ ﻣﻘـﺪار از ﺳـﺘﻮن title_idﻛﻪ ﺑﺎ ﻋﺒﺎرت DMﺷﺮوع ﻣﻲ ﺷﻮد .در ﭼﻨﻴﻦ ﺷﺮاﻳﻄﻲ ﺑﺮاي اﺟﺮاي دﺳﺘﻮر ،ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﻌﺪ از ﺑﺮﻗﺮاري اﺗﺼﺎل ﺑﻪ ﺑﺎﻧـﻚ اﻃﻼﻋــﺎﺗﻲ ﺑــﺎ اﺳــﺘﻔﺎده از ﻣﺘــﺪ Openدر ﻛــﻼس ،SqlConnectionﻣﺘــﺪ ExecuteScalarاز ﻛــﻼس SqlCommandرا ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ زﻣﺎﻧﻲ ﺑﻪ ﻛﺎر ﻣﻲ رود ﻛﻪ دﺳﺘﻮر SQLﻣﻮرد اﺳـﺘﻔﺎده ﻓﻘـﻂ ﻳـﻚ داده را ﺑﺮﮔﺮداﻧـﺪ.1 ﻣﻘﺪار ﺑﺮﮔﺸﺘﻲ اﻳﻦ ﻣﺘﺪ از ﻧﻮع Objectاﺳﺖ و ﺑﺎﻳﺪ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﻧﺘﻴﺠﻪ اي ﻛﻪ اﻧﺘﻈﺎر ﻣﻲ رود دﺳﺘﻮر SQLﻣﻮرد اﺳﺘﻔﺎده ﺑﺮﮔﺮداﻧـﺪ، آن را ﺑﻪ ﻧﻮع داده اي ﻣﻮرد ﻧﻈﺮ ﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ. // Open the connection, execute the command ;)(objConnection.Open ;)(Object maxId = maxIdCommand.ExecuteScalar 1اﻟﺒﺘﻪ اﻳﻦ ﻣﺘﺪ در ﺣﻘﻴﻘﺖ ﻣﻘﺪار ﻣﻮﺟﻮد در اوﻟﻴﻦ ردﻳﻒ از اوﻟﻴﻦ ﺳﺘﻮن را در ﺟﺪول ﻧﺘﻴﺠﻪ ﺑﺮ ﻣﻲ ﮔﺮداﻧﺪ .اﻣﺎ در دﺳﺘﻮري ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﻛﺎر ﺑﺮده اﻳـﻢ ﺳـﺘﻮﻧﻲ وﺟﻮد ﻧﺪارد و ﻓﻘﻂ ﻳﻚ ردﻳﻒ وﺟﻮد دارد ،ﺑﻨﺎﺑﺮاﻳﻦ دﻗﻴﻘﺎً داده اي را ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ اﺳﺘﻔﺎده ﻛﻨﻴﻢ ﺑﺮﻣﻲ ﮔﺮداﻧﺪ.
٦٧٨
ﺑﻌﺪ از اﺟﺮاي دﺳﺘﻮر SQLدر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ،ﺑﺎﻳﺪ ﻧﺘﻴﺠﻪ را ﺑﺎ ﻣﻘﺪار Nullﺑﺮرﺳﻲ ﻛﻨﻴﻢ: // If the MaxID column is null... )if (maxId == DBNull.Value اﮔﺮ اﻳﻦ ﺷﺮط ﺑﺮاﺑﺮ ﺑﺎ trueارزﻳﺎﺑﻲ ﺷﻮد ،ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ در ﺟﺪول titlesﻫﻴﭻ ﻛﻠﻴﺪ اﺻﻠﻲ ﻛﻪ ﺑـﺎ ﻣﻘـﺪار DMﺷـﺮوع ﺷﻮد وﺟﻮد ﻧﺪارد .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻘﺪار اوﻟﻴﻪ ﻣﺘﻐﻴﺮ intMaxIDرا ﺑﺮاﺑﺮ ﺑﺎ 1000ﻗﺮار ﻣﻲ دﻫﻴﻢ: // Set a default value of 1000... ;intMaxID = 1000 اﻣﺎ اﮔﺮ ﻣﻘﺪار ﺷﺮط ﺑﺮاﺑﺮ ﺑﺎ falseﺑﺎﺷﺪ ،ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﺣﺪاﻗﻞ ﻳﻚ ﻛﻠﻴﺪ اﺻﻠﻲ در ﺟـﺪول وﺟـﻮد دارد ﻛـﻪ ﺑـﺎ ﻋﺒـﺎرت DM ﺷﺮوع ﺷﻮد .در اﻳﻦ ﺣﺎﻟﺖ ﺑﺎﻳﺪ ﻋﺪد ﺻﺤﻴﺢ اﻳﻦ ﺷﻨﺎﺳﻪ را ﺑﺪﺳﺖ آورده ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ از ﭼﻪ ﻋﺪدي ﺑﺎﻳﺪ ﺑـﺮاي ﺷﻨﺎﺳـﻪ ي ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺑﺮاي اﻳﻦ ﻛﺎر اﺑﺘﺪا ﺑﺎﻳﺪ ﺷﻴﺊ maxIDرا ﺑﻪ رﺷﺘﻪ ﺗﺒﺪﻳﻞ ﻛﺮده و آن را در ﻣﺘﻐﻴﻴﺮ strIDﻗﺮار دﻫﻴﻢ: else { // otherwise set the strID variable // to the value in MaxID... ;strID = (String)maxId ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ Removeدر ﻛﻼس ،Stringدو ﺣﺮف اول اﻳﻦ رﺷﺘﻪ را ﺣﺬف ﻛﺮده ﺗﺎ ﻋﺒﺎرت DMاز اﺑﺘﺪاي آن ﭘﺎك ﺷﻮد و ﻓﻘﻂ ﻋﺪد ﻣﺸﺨﺺ ﻛﻨﻨﺪه ي ﺷﻨﺎﺳﻪ ﺑﺎﻗﻲ ﺑﻤﺎﻧﺪ .ﻣﺘﺪ Removeﺗﻌﺪادي ﻛﺎراﻛﺘﺮ ﻣﺸﺨﺺ را از ﻳﻚ رﺷﺘﻪ ﺣـﺬف ﻣـﻲ ﻛﻨـﺪ و ﺑﺎﻗﻴﻤﺎﻧﺪه آن را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .ﻳﻜﻲ از ﻧﺴﺨﻪ ﻫﺎي اﻳﻦ ﻣﺘﺪ ﻣﻜﺎن ﺷﺮوع و ﻧﻴﺰ ﺗﻌﺪاد ﻛﺎراﻛﺘﺮ ﻫﺎﻳﻲ ﻛﻪ ﺑﺎﻳﺪ ﺣﺬف ﺷﻮﻧﺪ را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻛﺮده و ﻣﺘﻦ ﺑﺪون ﻛﺎراﻛﺘﺮ ﻫﺎي ﻣﺸﺨﺺ ﺷﺪه را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ .در اﻳﻨﺠﺎ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ Removeاز ﻛﺎراﻛﺘﺮ ﺻﻔﺮم ﺷﺮوع ﻛﺮده و دو ﻛﺎراﻛﺘﺮ را ﺣﺬف ﻣﻲ ﻛﻨﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻋﺒﺎرت DMاز اﺑﺘﺪاي رﺷﺘﻪ ﺣﺬف ﻣﻲ ﺷﻮد .ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘـﺪ Parseاز ﻛﻼس ،intﻣﺘﻦ ﺑﺎﻗﻴﻤﺎﻧﺪه ﻛﻪ ﺷﺎﻣﻞ ﺷﻤﺎره ي ﺷﻨﺎﺳﻪ اﺳﺖ را ﺑﻪ ﻋﺪد ﺗﺒﺪﻳﻞ ﻣﻲ ﻛﻨﻴﻢ .در اﻧﺘﻬﺎ ﻧﻴﺰ ﺑـﺮاي ﻣـﺸﺨﺺ ﺷـﺪن ﺷـﻤﺎره ﺷﻨﺎﺳﻪ ي ﻣﻮرد ﻧﻴﺎز ،ﻳﻚ واﺣﺪ ﺑﻪ ﻋﺪد ﺑﺪﺳﺖ آﻣﺪه اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ. // Get the integer part of the string... ;))intMaxID = int.Parse(strID.Remove(0, 2 // Increment the value... ;intMaxID += 1 } ﺑﻌﺪ از ﻣﺸﺨﺺ ﺷﺪن ﺷﻤﺎره ي ﺷﻨﺎﺳﻪ ،ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﺷﻤﺎره و اﺿﺎﻓﻪ ﻛﺮدن ﭘﻴﺸﻮﻧﺪ DMﺑﻪ اﺑﺘﺪاي آن ﻳﻚ ﺷﻤﺎره ﺷﻨﺎﺳﻪ ي ﺟﺪﻳـﺪ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ. // Finally, set the new ID...
٦٧٩
;)(strID = "DM" + intMaxID.ToString ﺑﻌﺪ از ﻣﺸﺨﺺ ﺷﺪن ﺷﻨﺎﺳﻪ ي ﻣﻮرد ﻧﻴﺎز ،ﺑﺎﻳﺪ ﻳﻚ دﺳﺘﻮر SQLاﻳﺠﺎد ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﺪ داده ﻫﺎي ﻣﻮرد ﻧﻈﺮ را در ﺟﺪول titlesو authortitleﻗــﺮار دﻫــﺪ .اﮔــﺮ ﺑــﺎ دﻗــﺖ ﺑﻴــﺸﺘﺮي ﻛــﺪ ﻗﺒــﻞ را ﺑﺮرﺳــﻲ ﻛﻨﻴــﺪ ﻣﺘﻮﺟــﻪ ﺧﻮاﻫﻴــﺪ ﺷــﺪ ﻛــﻪ در ﺧﺎﺻــﻴﺖ CommandTextاز ﺷﻴﺊ ،objCommandدو دﺳﺘﻮر INSERTﻣﺠﺰا ﻗﺮار داده ﺷﺪه اﺳﺖ ﻛﻪ ﺑـﺎ ; از ﻳﻜـﺪﻳﮕﺮ ﺟـﺪا ﺷﺪه اﻧﺪ .در زﺑﺎن SQLﻧﻴﺰ ﺑﺮاي ﺟﺪا ﺳﺎزي دﺳﺘﻮرات و ﻧﻮﺷﺘﻦ ﻣﺘﻮاﻟﻲ آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻛﺎراﻛﺘﺮ ; اﺳﺘﻔﺎده ﻛﻨﻴﺪ .اﻳـﻦ دﺳـﺘﻮر SQL داراي ﭼﻨﺪﻳﻦ PlaceHolderاﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﻪ وﺳﻴﻠﻪ ي اﺷﻴﺎﻳﻲ از ﻧـﻮع SqlParameterآﻧﻬـﺎ را ﺑـﺎ ﻣﻘـﺎدﻳﺮ ﻣﻨﺎﺳﺐ ﺟﺎﻳﮕﺰﻳﻦ ﻛﻨﻴﻢ. ﻧﻜﺘﻪ :ﺑﻪ ﻋﻠﺖ راﺑﻄﻪ ي ﺧﺎﺻﻲ ﻛﻪ ﺑﻴﻦ دو ﺟﺪول titlesو authortitleوﺟﻮد دارد ،ﻫﻨﮕﺎم وارد ﻛـﺮدن داده اي در اﻳﻦ ﺟﺪاول اﺑﺘﺪا ﺑﺎﻳﺪ داده ﻫﺎ را در ﺟﺪول titlesوارد ﻛﺮده و ﺳﭙﺲ آﻧﻬـﺎ را در ﺟـﺪول authortitleﻗـﺮار دﻫـﻴﻢ .در دﺳﺘﻮر SQLﻗﺒﻞ ﻫﻢ اﮔﺮ ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﺧﻮاﻫﻴﺪ دﻳﺪ ﻛﻪ دﺳﺘﻮر INSERTﻣﺮﺑﻮط ﺑﻪ ﻗﺮار دادن داده ﻫﺎ در ﺟﺪول titlesﻗﺒﻞ از دﺳﺘﻮر INSERTﻣﺮﺑﻮط ﺑﻪ ﻗﺮار دادن داده ﻫﺎ در ﺟﺪول authortitleآﻣﺪه اﺳﺖ. ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻄﺎﺑﻖ ﻣﻌﻤﻮل Connectionاي ﻛﻪ ﺑﺎﻳﺪ ﺑﺮاي اﺗﺼﺎل ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد و ﻫﻤﭽﻨـﻴﻦ دﺳـﺘﻮر SQLﻣﻮرد ﻧﻈﺮ را در ﺧﺎﺻﻴﺘﻬﺎي Connectionو CommandTextﻗﺮار ﻣﻲ دﻫﻴﻢ: // Set the SqlCommand object properties... ;objCommand.Connection = objConnection objCommand.CommandText = "INSERT INTO titles " + "(title_id, title, type, price, pubdate) " + "VALUES(@title_id,@title,@type,@price,@pubdate);" + "INSERT INTO titleauthor (au_id, title_id) " + ;")"VALUES(@au_id,@title_id ﺑﻌــﺪ از اﻳــﻦ ،ﺑﺎﻳــﺪ ﺑــﺎزاي ﻫــﺮ ﻳــﻚ placeholderاي ﻛــﻪ در دﺳــﺘﻮر SQLﻗــﺮار داده اﻳــﻢ ،ﻳــﻚ ﻣﻘــﺪار ﺑــﻪ ﺧﺎﺻــﻴﺖ Parametersاﺿﺎﻓﻪ ﻛﻨﻴﻢ .اﻟﺒﺘﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ placeholderﻣﺮﺑـﻮط ﺑـﻪ title_idدو ﺑـﺎر اﺳﺘﻔﺎده ﺷﺪه اﺳﺖ ،ﻓﻘﻂ ﻳﻚ ﻋﻀﻮ ﺑﻪ ﺧﺎﺻﻴﺖ Parametersاﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ: // Add parameters for the placeholders in the SQL in // the CommandText property... // Parameter for the title_id column... objCommand.Parameters.AddWithValue("@title_id", ;)strID // Parameter for the title column... objCommand.Parameters.AddWithValue("@title", ;)txtBookTitle.Text // Parameter for the type column ;)"objCommand.Parameters.AddWithValue("@type", "Demo
٦٨٠
// Parameter for the price column... objCommand.Parameters.AddWithValue("@price", ;txtPrice.Text).DbType = DbType.Currency // Parameter for the pubdate column objCommand.Parameters.AddWithValue("@pubdate", ;)DateTime.Now // Parameter for the au_id column... objCommand.Parameters.AddWithValue("@au_id", ;)this.BindingContext[objDataView,"au_id"].Current ﺑﺮاي ﻣﻘﺪار ﭘﺎراﻣﺘﺮ ،@title_idاز ﻣﻘﺪار ﻣﻮﺟﻮد در ﻣﺘﻐﻴﻴﺮ strIDﻛﻪ ﭘﻴﺸﺘﺮ اﻳﺠﺎد ﻛﺮدﻳﻢ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .ﺑـﺮاي ﭘـﺎراﻣﺘﺮ @titleﻧﻴﺰ از ﻣﻘﺪاري ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺎرﺑﺮ در ﻛﺎدر Book Titleوارد ﺷﺪه اﺳﺖ اﺳـﺘﻔﺎده ﻣـﻲ ﻛﻨـﻴﻢ .ﺑـﺮاي ﭘـﺎراﻣﺘﺮ @priceﻣﻘﺪار ﻣﻮﺟﻮد در ﻛﺎدر Priceرا ﺑﻪ ﻛﺎر ﻣﻲ ﺑﺮﻳﻢ .اﻟﺒﺘﻪ ﻣﻘﺪار ﻣﻮﺟﻮد در اﻳﻦ ﻛﺎدر ﻳﻚ Stringاﺳﺖ و SQL Serverﻧﻤﻲ ﺗﻮاﻧﺪ آن را ﺑﻪ ﻃﻮر اﺗﻮﻣﺎﺗﻴﻚ ﺑﻪ ﻣﻘﺪار ﻋﺪدي ﺗﺒﺪﻳﻞ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻻزم اﺳﺖ ﻛﻪ ﺧﺎﺻﻴﺖ DbTypeآن را ﺑﺮاﺑﺮ ﺑﺎ DbType.Currencyﻗﺮار دﻫﻴﻢ ﺗﺎ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ اﻳﻦ ﻣﻘﺪار ،ﻳﻚ ﻣﻘﺪار ﻋﺪدي اﺳﺖ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ زﻣﺎن اﺟﺮاي دﺳﺘﻮر ،SQLﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﺨﻮاﻫﺪ اﻳﻦ ﭘﺎراﻣﺘﺮ را ﺑﺎ ﻣﻘﺪار آن ﺟﺎﻳﮕﺰﻳﻦ ﻛﻨﺪ ،ﺑﺎ آن ﺑﻪ ﺻﻮرت ﻳﻚ ﻋﺪد ﺑﺮﺧﻮرد ﻣﻲ ﻛﻨﺪ. ﺑﺮاي ﭘﺎراﻣﺘﺮ au_idﺑﺎﻳﺪ ﺷﻨﺎﺳﻪ ي ﻣﺮﺑﻮط ﺑﻪ ﻧﻮﻳﺴﻨﺪه اي ﻛﻪ ﻫﻢ اﻛﻨﻮن اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ را ﺑﺪﺳﺖ آورﻳـﻢ .در اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ ﻫـﻴﭻ ﻛﻨﺘﺮﻟﻲ ﺑﻪ ﺳﺘﻮن au_idﻣﺘﺼﻞ ﻧﺸﺪه اﺳﺖ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﺷﻨﺎﺳﻪ را ﺑﻪ وﺳﻴﻠﻪ ي آن ﺑﺪﺳﺖ آورﻳﻢ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي اﻧﺠﺎم اﻳﻦ ﻛـﺎر ﺑﺎﻳـﺪ از ﻣﻘﺪاري ﻛﺪ در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﺑﻬﺘﺮ اﺳﺖ اﺑﺘﺪا ﻛﺪ ﻣﻮرد اﺳﺘﻔﺎده را ﻛﻤﻲ دﻗﻴﻘﺘﺮ ﻧﮕﺎه ﻛﻨﻴﻢ: this.BindingContext[objDataView,"au_id"].Current ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﺧﺎﺻﻴﺖ BindingContextاز ﻳﻚ ﻓﺮم ،ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻣﻨﺎﺑﻊ داده اي ﻣﻮﺟﻮد در آن ﻓﺮم ﺑـﻪ ﻛـﺎر ﻣﻲ رود .در ﺣﻘﻴﻘﺖ اﻳﻦ ﺧﺎﺻﻴﺖ را ﻣﻲ ﺗﻮاﻧﻴﻢ ﻫﻤﺎﻧﻨﺪ ﻳﻚ آراﻳﻪ ي ﺳﻪ ﺑﻌﺪي در ﻧﻈﺮ ﺑﮕﻴﺮﻳﻢ ﻛﻪ در ﻳـﻚ ﺑﻌـﺪ آن ﻣﻨـﺎﺑﻊ داده اي ﻗـﺮار دارﻧﺪ ،و دو ﺑﻌﺪ دﻳﮕﺮ آن را ﺳﺘﻮﻧﻬﺎ و ردﻳﻒ ﻫﺎي اﻃﻼﻋﺎﺗﻲ ﻣﻮﺟﻮد در ﻫﺮ ﻣﻨﺒﻊ داده اي ﺗﺸﻜﻴﻞ ﻣﻲ دﻫﻨﺪ .در اﻳﻨﺠﺎ ﺑـﺎ ذﻛـﺮ ﻛـﺮدن ﻧـﺎم objDataViewو ﻧﻴــﺰ ” “au_idﻣــﺸﺨﺺ ﻛــﺮده اﻳــﻢ ﻛــﻪ ﻣــﻲ ﺧــﻮاﻫﻴﻢ ﺑــﻪ ﺳــﺘﻮن au_idاز ﻣﻨﺒــﻊ داده اي objDataViewدﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ .ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ Currentدر اﻳﻦ ﻗﺴﻤﺖ ،ﻣﺸﺨﺺ ﻣـﻲ ﻛﻨـﻴﻢ ﻛـﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ داده ي ﻣﻮﺟﻮد در رﻛﻮرد ﺟﺎري از ﺳﺘﻮن ﺗﻌﻴﻴﻦ ﺷﺪه را ﺑﺪﺳﺖ آورﻳﻢ. دو ﭘﺎراﻣﺘﺮ دﻳﮕﺮ ﻧﻴﺰ ﻧﻮع و زﻣﺎن اﻧﺘﺸﺎر ﻛﺘﺎب را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ از رﺷﺘﻪ ي ﺛﺎﺑﺖ Demoﺑﺮاي ﻧـﻮع ﻛﺘـﺎب ،و از ﺧﺎﺻﻴﺖ Nowدر ﻛﻼس DateTimeﻛﻪ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ي زﻣﺎن ﻛﻨﻮﻧﻲ اﺳﺖ ﺑﺮاي زﻣﺎن اﻧﺘﺸﺎر آن اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ: // Parameter for the type column ;)"objCommand.Parameters.AddWithValue("@type", "Demo // Parameter for the pubdate column objCommand.Parameters.AddWithValue("@pubdate", ;)DateTime.Now ﺑﻌﺪ از اﻳﻦ ﻛﻪ ﺗﻤﺎم ﭘﺎراﻣﺘﺮﻫﺎي ﻣﻮرد ﻧﻴﺎز را ﻣﺸﺨﺺ ﻛﺮدﻳﻢ ،ﻣﻲ ﺗﻮاﻧﻴﻢ دﺳﺘﻮر SQLاﻳﺠﺎد ﺷﺪه را اﺟﺮا ﻛﻨﻴﻢ .ﺑـﺮاي اﻳـﻦ ﻛـﺎر از ﻣﺘـﺪ ExecuteNonQueryدر ﻛﻼس SqlCommandاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ .اﻳﻦ ﻣﺘﺪ زﻣﺎﻧﻲ اﺳـﺘﻔﺎده ﻣـﻲ ﺷـﻮد ﻛـﻪ دﺳـﺘﻮر ٦٨١
SQLﻣﻮرد اﺳﺘﻔﺎده ،ﺷﺎﻣﻞ ﭘﺮس و ﺟﻮ ﻧﺒﺎﺷﺪ )ﺣﺎوي دﺳﺘﻮر SELECTﻧﺒﺎﺷﺪ( و ﻓﻘﻂ ﺑﺮاي اﻳﺠﺎد ﺗﻐﻴﻴﺮاﺗﻲ در ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ ﺑـﻪ ﻛﺎر ﺑﺮود .در اﻳﻨﺠﺎ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر INSERTداده ﻫﺎﻳﻲ را در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻗﺮار دﻫﻴﻢ ،ﭘﺲ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ اﺳـﺘﻔﺎده از ﻣﺘﺪ ExecuteNonQueryاﻳﻦ دﺳﺘﻮر را در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺟﺮا ﻛﻨﻴﻢ .ﺑﻌﺪ از آن ﻧﻴﺰ ﺑﺎﻳﺪ اﺗﺼﺎل ﺑـﻪ ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ را ﻗﻄﻊ ﻛﻨﻴﻢ. اﻳﻦ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ ﻳﻜﻲ از ﻗﺴﻤﺘﻬﺎﻳﻲ اﺳﺖ ﻛﻪ اﺣﺘﻤﺎل رخ دادن ﺧﻄﺎ در آن ﺑﺴﻴﺎر زﻳﺎد اﺳﺖ .ﺑﻨـﺎﺑﺮاﻳﻦ ﻳـﻚ ﺑـﻼك ﺧﻴﻠـﻲ ﺳـﺎده ي try…catchدر اﻳﻦ ﻗﺴﻤﺖ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ رخ دادن ﺧﻄﺎﻫﺎي اﺣﺘﻤﺎﻟﻲ را ﻛﻨﺘﺮل ﻛﻨﻴﻢ .در ﻗﺴﻤﺖ ﻛﻨﺘﺮل ﺧﻄـﺎ ،ﻓﻘـﻂ ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم ﻣﺘﻦ ﺧﻄﺎي ﺑﻪ وﺟﻮد آﻣﺪه را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ. try { ;)(objCommand.ExecuteNonQuery } )catch(SqlException SqlExceptionErr { ;)MessageBox.Show(SqlExceptionErr.Message } ﺳﭙﺲ ،ﺑﻌﺪ از ﻗﻄﻊ اﺗﺼﺎل ﺑﻪ ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ ،ﻣﺘـﺪﻫﺎي FillDataSetAndViewو BindFieldsرا ﻣﺠـﺪد ًا ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ اﻃﻼﻋﺎت ﺟﺪﻳﺪ را از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ درﻳﺎﻓﺖ ﻛﺮده و در DataSetﻗـﺮار دﻫـﻴﻢ ،زﻳـﺮا ﻣﻤﻜـﻦ اﺳﺖ در ﻃﻮل اﻳﻦ زﻣﺎﻧﻲ ﻛﻪ از ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻗﻄﻊ ﺑﻮده اﻳﻢ ﻓﺮد دﻳﮕﺮي ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي دﻳﮕﺮ وارد اﻳﻦ ﺳﺮور ﺷـﺪه و داده ﻫﺎي ﺟﺪول را ﺗﻐﻴﻴﺮ داده ﺑﺎﺷﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻣﻄﻤﺌﻦ ﺷﻮﻳﻢ ﻛﻪ ﺗﻤﺎم ﺗﻐﻴﻴﺮاﺗـﻲ ﻛـﻪ در اﻳـﻦ ﻣـﺪت در اﻳـﻦ ﺟـﺪول از ﺑﺎﻧـﻚ اﻃﻼﻋﺎﺗﻲ ﺑﻪ وﺟﻮد آﻣﺪه اﺳﺖ را درﻳﺎﻓﺖ ﻛﺮده اﻳﻢ. ﻧﻜﺘﻪ :ﺟﺪاول و ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ ﻛﻪ در SQL Serverاﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ ،ﻣﻲ ﺗﻮاﻧﻨﺪ در ﻳﻚ ﻟﺤﻈﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﭼﻨﺪ ﺑﺮﻧﺎﻣـﻪ ،و در ﺣﻘﻴﻘﺖ ﺑﻪ وﺳﻴﻠﻪ ي ﭼﻨﺪ ﻛﺎرﺑﺮ ﻣﺨﺘﻠﻒ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮﻧﺪ و ﻫﺮ ﻳﻚ از اﻳﻦ ﻛﺎرﺑﺮان ﻧﻴﺰ ﻣﻤﻜﻦ اﺳﺖ ﺗﻐﻴﻴﺮات ﻣﻮرد ﻧﻈﺮ ﺧﻮد را در داده ﻫﺎي ﺟﺪول وارد ﻛﻨﻨﺪ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ،ﺑﻌﺪ از اﻳﻨﻜﻪ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﺘﺼﻞ ﺷﺪ و داده ﻫﺎي ﻣﻮرد ﻧﻴـﺎز ﺧـﻮد را درﻳﺎﻓﺖ ﻛﺮد ،اﺗﺼﺎل را ﻗﻄﻊ ﻣﻲ ﻛﻨﺪ و ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ،ﺗﻐﻴﻴﺮاﺗﻲ ﻛﻪ در اﻳﻦ ﻣﺪت ﺗﻮﺳﻂ اﻓﺮاد دﻳﮕﺮ در داده ﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ اﻳﺠـﺎد ﻣﻲ ﺷﻮد ﺑﻪ وﺳﻴﻠﻪ ي ﺑﺮﻧﺎﻣﻪ درﻳﺎﻓﺖ ﻧﻤﻲ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ درﻳﺎﻓﺖ ﻣﺠﺪد اﻃﻼﻋﺎت در ﻗﺴﻤﺖ ﻗﺒﻞ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻣﻄﻤﺌﻦ ﺷـﻮﻳﻢ ﻛـﻪ ﺗﻤـﺎم ﺗﻐﻴﻴﺮاﺗﻲ ﻛﻪ در اﻳﻦ ﻣﺪت در داده ﻫﺎ ﺑﻪ وﺟﻮد آﻣﺪه اﺳﺖ را درﻳﺎﻓﺖ ﻛﺮده اﻳﻢ. ﺑﻌﺪ از اﻳﻦ ﻛﺎر ،ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ Positionدر ﺷﻴﺊ ،objCurrencyManagerرﻛـﻮرد ﺟـﺎري را ﺑـﻪ ﻫﻤـﺎن ﻣﻜﺎﻧﻲ ﺑﺮﻣﻲ ﮔﺮداﻧﻴﻢ ﻛﻪ ﻗﺒﻞ از ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ﻗﺮار داﺷﺖ .ﺑﺮاي اﻳﻦ ﻛﺎر از ﻣﻜـﺎن رﻛـﻮرد ﻛـﻪ ﻗﺒـﻞ از ﻓﺮاﺧـﻮاﻧﻲ ﻣﺘـﺪ آن را در ﻣﺘﻐﻴﻴـﺮ intPositionﻗﺮار داده ﺑﻮدﻳﻢ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ. ﺑﻌﺪ از ﺗﻐﻴﻴﺮ ﻣﻮﻗﻌﻴﺖ رﻛﻮردي ﻛﻪ در ﺣﺎل ﻧﻤﺎﻳﺶ داده ﺷﺪن اﺳﺖ ،ﻣﺘﺪ ShowPositionرا ﻧﻴﺰ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢ ﺗـﺎ ﺷـﻤﺎره رﻛﻮرد ﺟﺎري ﻧﻴﺰ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﺷﻮد.در آﺧﺮ ﭘﻴﻐﺎﻣﻲ را در ﻧﻮار وﺿﻌﻴﺖ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫـﻴﻢ ﺗـﺎ ﻣـﺸﺨﺺ ﺷـﻮد رﻛـﻮرد ﺟﺪﻳـﺪ ﺑـﺎ ﻣﻮﻓﻘﻴﺖ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺿﺎﻓﻪ ﺷﺪه اﺳﺖ. در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ،ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ دﻛﻤﻪ ي btnUpdateرا وارد ﺧﻮاﻫﻴﻢ ﻛﺮد .ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ دﻛﻤﻪ ﻣﻘـﺪاري ﺳـﺎده ﺗﺮ از ﻗﺴﻤﺖ ﻗﺒﻞ اﺳﺖ ،زﻳﺮا در اﻳﻦ ﻗﺴﻤﺖ ﻓﻘﻂ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﻌﻀﻲ از اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﻳﻜﻲ از رﻛﻮرد ﻫﺎي ﺟـﺪول titlesرا ﺗﻐﻴﻴﺮ دﻫﻴﻢ.
٦٨٢
وﻳﺮاﻳﺶ داده ﻫﺎ:اﻣﺘﺤﺎن ﻛﻨﻴﺪ Click دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑـﻪ روﻳـﺪادbtnUpdate ( ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮوي و روي دﻛﻤﻪ ي1 : ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ.آن اﻳﺠﺎد ﺷﻮد private void btnUpdate_Click(object sender, EventArgs e) { // Declare local variables and objects... int intPosition; SqlCommand objCommand = new SqlCommand(); // Save the current record position... intPosition = objCurrencyManager.Position; // Set the SqlCommand object properties... objCommand.Connection = objConnection; objCommand.CommandText = "UPDATE titles " + "SET title = @title, price = @price " + "WHERE title_id = @title_id"; objCommand.CommandType = CommandType.Text; // Add parameters for the placeholders in the SQL in // the CommandText property... // Parameter for the title field... objCommand.Parameters.AddWithValue("@title", txtBookTitle.Text); // Parameter for the price field... objCommand.Parameters.AddWithValue("@price", txtPrice.Text).DbType = DbType.Currency; // Parameter for the title_id field... objCommand.Parameters.AddWithValue("@title_id", this.BindingContext[objDataView,"title_id"].Current); // Open the connection... objConnection.Open(); // Execute the SqlCommand object to update the data... objCommand.ExecuteNonQuery(); // Close the connection... objConnection.Close(); // Fill the DataSet and bind the fields... ٦٨٣
;)(FillDataSetAndView ;)(BindFields // Set the record position // to the one that you saved... ;objCurrencyManager.Position = intPosition // Show the current record position... ;)(ShowPosition // Display a message that the record was updated... ;"ToolStripStatusLabel1.Text = "Record Updated } (2ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ .ﺣﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﻛﺘﺎﺑﻲ ﻛﻪ اﺿـﺎﻓﻪ ﻛـﺮده ﺑﻮدﻳـﺪ را ﺗﻐﻴﻴـﺮ دﻫﻴـﺪ و ﻳـﺎ ﺗﻐﻴﻴﺮاﺗـﻲ را در اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ دﻳﮕﺮ ﻛﺘﺎﺑﻬﺎ اﻳﺠﺎد ﻛﻨﻴﺪ .ﻳﻚ ﻛﺘﺎب را اﻧﺘﺨﺎب ﻛﺮده و ﺑﺎ اﺳﺘﻔﺎده از ﻛﺎدر Priceﻗﻴﻤـﺖ آن را ﺗﻐﻴﻴـﺮ دﻫﻴﺪ .ﺳﭙﺲ روي دﻛﻤﻪ ي Updateﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺗﻐﻴﻴﺮات ﻣﻮرد ﻧﻈﺮ ﺷﻤﺎ در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ذﺧﻴﺮه ﻣـﻲ ﺷﻮد و ﭘﻴﻐﺎﻣﻲ ﻧﻴﺰ در ﻧﻮار وﺿﻌﻴﺖ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و ﺛﺒﺖ ﺗﻐﻴﻴﺮات را اﻋﻼم ﻣﻲ ﻛﻨﺪ )ﺷﻜﻞ .(12-16
ﺷﻜﻞ 12-16
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟
٦٨٤
ﻣﺎﻧﻨﺪ ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ ،اوﻟﻴﻦ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﻢ ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﻴﺮ ﻫﺎ و اﺷﻴﺎي ﻣﻮرد ﻧﻴﺎز اﺳﺖ .در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﺑﻪ ﻳﻚ ﻣﺘﻐﻴﻴﺮ ﺑﺮاي ﻧﮕﻬﺪاري رﻛﻮرد ﺟﺎري و ﻧﻴﺰ ﻳﻚ ﺷﻴﺊ از ﻧﻮع SqlCommandﻧﻴﺎز دارﻳﻢ .ﺑﻌﺪ از ﺗﻌﺮﻳﻒ اﻳﻦ دو ،ﻫﻤﺎﻧﻨﺪ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻠﻲ ﻣﻜـﺎن رﻛﻮرد ﺟﺎري را در ﻣﺘﻐﻴﺮي ﻛﻪ اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﻢ ﻗﺮار ﻣﻲ دﻫﻴﻢ. ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ﻛﺪ زﻳﺮ ،ﺷﻴﺊ objConnectionرا در ﺧﺎﺻﻴﺖ Connectionاز ﺷـﻴﺊ SqlCommandﻗـﺮار ﻣﻲ دﻫﻴﻢ .ﻫﻤﭽﻨﻴﻦ دﺳﺘﻮر SQLﻣﻮرد ﻧﻈﺮ ﺧﻮد را ﻧﻴﺰ در ﺧﺎﺻﻴﺖ CommandTextوارد ﻣﻲ ﻛﻨـﻴﻢ .دﺳـﺘﻮر SQLاي ﻛـﻪ در اﻳﻦ ﻗﺴﻤﺖ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﻳﻚ دﺳﺘﻮر UPDATEاﺳﺖ ﻛﻪ ﺑﺮاي وﻳﺮاﻳﺶ ﺳـﺘﻮﻧﻬﺎي Priceو Titleاز ﻳﻜـﻲ از رﻛـﻮرد ﻫﺎي ﺟﺪول titlesﺑﻪ ﻛﺎر ﻣﻲ رود .ﺗﻮﺟـﻪ ﻛﻨﻴـﺪ ﻛـﻪ در اﻳـﻦ دﺳـﺘﻮر از ﺳـﻪ placeholderاﺳـﺘﻔﺎده ﻛـﺮده اﻳـﻢ :دو placeholderﺑﺮاي ﻣﻘﺎدﻳﺮ ﺟﺪﻳﺪي ﻛﻪ ﺑﺎﻳﺪ در ﺳﺘﻮن Priceو Titleﻗﺮار ﺑﮕﻴﺮﻧﺪ و ﻳﻚ placeholder ﻧﻴﺰ ﺑﺮاي title_idﻛﻪ در ﻗﺴﻤﺖ WHEREﺑﻪ ﻛﺎر ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ: // Set the SqlCommand object properties... ;objCommand.Connection = objConnection objCommand.CommandText = "UPDATE titles " + "SET title = @title, price = @price " + ;""WHERE title_id = @title_id ;objCommand.CommandType = CommandType.Text ﺑﻌـــﺪ از ﻗـــﺮار دادن دﺳـــﺘﻮر SQLدر ﺧﺎﺻـــﻴﺖ ،CommandTextﻣﻘـــﺪار CommandTypeرا ﻧﻴـــﺰ ﺑﺮاﺑـــﺮ ﺑـــﺎ CommandType.Textﻗﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛـﻪ ﻋﺒـﺎرت ﻣﻮﺟـﻮد در ﺧﺎﺻـﻴﺖ CommandTextﻳـﻚ دﺳﺘﻮر SQLاﺳﺖ. ﺣﺎل ﺑﺎﻳﺪ ﭘﺎراﻣﺘﺮﻫﺎي ﻻزم را ﺑﻪ ﺧﺎﺻﻴﺖ Parametersاﺿﺎﻓﻪ ﻛﻨﻴﻢ .اوﻟﻴﻦ ﭘﺎراﻣﺘﺮ @title ،اﺳـﺖ و ﺑﺎﻳـﺪ ﺷـﺎﻣﻞ ﻋﻨـﻮان ﺟﺪﻳﺪي ﺑﺎﺷﺪ ﻛﻪ ﺑﺮاي ﻛﺘﺎب در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ .اﻳﻦ ﻋﻨﻮان را ﻛﺎرﺑﺮ در ﻓﺮم ﺑﺮﻧﺎﻣﻪ وارد ﻛﺮده اﺳﺖ و ﺑﺮاي دﺳﺘﺮﺳـﻲ ﺑـﻪ آن ﻣـﻲ ﺗﻮاﻧﻴﻢ از ﺧﺎﺻـﻴﺖ Textدر ﻛﻨﺘـﺮل txtBookTitleاﺳـﺘﻔﺎده ﻛﻨـﻴﻢ .ﺑﻨـﺎﺑﺮاﻳﻦ ﻣﻘـﺪار ﭘـﺎراﻣﺘﺮ @titleرا ﺑﺮاﺑـﺮ ﺑـﺎ txtBookTitle.Textﻗﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﺨﻮاﻫﺪ اﻳﻦ دﺳﺘﻮر SQLرا ﺑﺮاي اﺟﺮا ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ ﺑﻔﺮﺳﺘﺪ ،ﻋﺒﺎرت @titleدر دﺳﺘﻮر را ﺑﺎ ﻣﻘﺪار ﻣﻮﺟﻮد در ﺧﺎﺻﻴﺖ Textﺟﺎﻳﮕﺰﻳﻦ ﻛﻨﺪ. ﭘﺎراﻣﺘﺮ دوم ﻣﺮﺑﻮط ﺑﻪ ﻗﺴﻤﺖ Priceدر دﺳﺘﻮر UPDATEاﺳﺖ .اﻳﻦ ﭘﺎراﻣﺘﺮ ﺑﺮاي ﺗﻐﻴﻴﺮ ﻗﻴﻤﺖ ﻛﺘﺎب ﺑﻪ ﻛﺎر ﻣﻲ رود و ﻣﻘـﺪار آن ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺎرﺑﺮ در ﺧﺎﺻﻴﺖ Textﻛﻨﺘﺮل txtPriceدر ﻓﺮم ﺑﺮﻧﺎﻣﻪ وارد ﺷﺪه اﺳﺖ .در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﺑﺨﺶ ﻗﺒﻠﻲ، ﺑﺎﻳﺪ ﺧﺎﺻﻴﺖ DbTypeاﻳﻦ ﭘﺎراﻣﺘﺮ را ﺗﻌﻴﻴﻦ ﻛﻨﻴﻢ ﺗﺎ رﺷﺘﻪ ي وارد ﺷﺪه در ﻛﻨﺘـﺮل ،txtPriceﻗﺒـﻞ از ﺟـﺎﻳﮕﺰﻳﻦ ﺷـﺪن در دﺳﺘﻮر ﺑﻪ ﻋﺪد ﺗﺒﺪﻳﻞ ﺷﻮد. ﭘﺎراﻣﺘﺮ آﺧﺮ ﻧﻴﺰ ﺷﺎﻣﻞ ﺷﻨﺎﺳﻪ ي ﻛﺘﺎﺑﻲ اﺳﺖ ﻛﻪ ﺑﺎﻳﺪ اﻃﻼﻋﺎت آن ﺗﻐﻴﻴﺮ ﻛﻨﺪ و در ﻗﺴﻤﺖ WHEREاز دﺳﺘﻮر UPDATEوارد ﺷـﺪه اﺳﺖ .ﻣﻘﺪار اﻳﻦ ﭘﺎراﻣﺘﺮ ﺑﺮاﺑﺮ ﺑﺎ ﺷﻨﺎﺳﻪ ي title_idاز رﻛﻮرد ﺟﺎري اﺳﺖ ﻛﻪ آن را ﻫﻤﺎﻧﻨﺪ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻠـﻲ ﺑﺪﺳـﺖ آورده و در دﺳﺘﻮر UPDATEﺟﺎﻳﮕﺰﻳﻦ ﻣﻲ ﻛﻨﻴﻢ. ﺑﻘﻴﻪ ي ﻛﺪ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻣﺘﺪ btnAdd_Clickاﺳﺖ و ﻧﻴﺎزي ﺑﻪ ﺗﻮﺿﻴﺢ ﻧﺪارد .ﻛﺪ ﻣﺮﺑـﻮط ﺑـﻪ دﻛﻤـﻪ ي آﺧـﺮ ﻳﻌﻨـﻲ دﻛﻤـﻪ ي Deleteﻧﻴﺰ در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪي ﺗﻮﺿﻴﺢ داده ﺷﺪه اﺳﺖ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﺣﺬف ﻛﺮدن ﻳﻚ رﻛﻮرد
٦٨٥
آنClick دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑـﻮط ﺑـﻪ روﻳـﺪادbtnDelete ( ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم رﻓﺘﻪ و روي دﻛﻤﻪ ي1 : ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ.اﻳﺠﺎد ﺷﻮد private void btnDelete_Click(object sender, EventArgs e) { // Declare local variables and objects... int intPosition; SqlCommand objCommand = new SqlCommand(); // Save the current record position - 1 for the one to // be deleted... intPosition = this.BindingContext[objDataView].Position - 1; // If the position is less than 0 set it to 0... if( intPosition < 0 ) intPosition = 0; // Set the Command object properties... objCommand.Connection = objConnection; objCommand.CommandText = "DELETE FROM titleauthor " + "WHERE title_id = @title_id;" + "DELETE FROM titles WHERE title_id = @title_id"; // Parameter for the title_id field... objCommand.Parameters.AddWithValue("@title_id", this.BindingContext[objDataView,"title_id"].Current); // Open the database connection... objConnection.Open(); // Execute the SqlCommand object to update the data... objCommand.ExecuteNonQuery(); // Close the connection... objConnection.Close(); // Fill the DataSet and bind the fields... FillDataSetAndView(); BindFields(); // Set the record position // to the one that you saved... this.BindingContext[objDataView].Position = intPosition; // Show the current record position...
٦٨٦
;)(ShowPosition // Display a message that the record was deleted... ;"ToolStripStatusLabel1.Text = "Record Deleted } (2ﺧﻮب ،ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﻳﻦ ﭘﺮوژه ﻧﻴﺰ ﺑﻪ ﭘﺎﻳﺎن رﺳﻴﺪ .اﻣﺎ ﺑﻬﺘﺮ اﺳﺖ ﻗﺒﻞ از اﻳﻨﻜﻪ از ﺗﻤﺎم ﺷﺪن آن ﺧﻮﺷـﺤﺎل ﺷـﻮﻳﻢ اﺑﺘـﺪا ﻗﺎﺑﻠﻴـﺖ ﺟﺪﻳﺪي ﻛﻪ اﺿﺎﻓﻪ ﻛﺮده اﻳﻢ را اﻣﺘﺤﺎن ﻛﻨﻴﻢ .ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﻫﺮ ﻛﺘﺎﺑﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺣﺬف ﻛﻨﻴﺪ را اﻧﺘﺨﺎب ﻛﻨﻴﺪ ،ﺳـﭙﺲ روي دﻛﻤﻪ ي Deleteﻛﻠﻴﻚ ﻛﻨﻴﺪ .ﺑﻪ ﺧﺎﻃﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﺑﺎﻣﻚ اﻃﻼﻋﺎﺗﻲ pubsﻛﻪ در اﻳﻦ ﺑﺮﻧﺎﻣـﻪ از آن اﺳـﺘﻔﺎده ﻛﺮده اﻳﻢ ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻧﻤﻮﻧﻪ اﺳﺖ و ﻣﻤﻜﻦ اﺳﺖ اﻓـﺮاد دﻳﮕـﺮي ﻧﻴـﺰ ﺑـﻪ اﻳـﻦ SQL Serverﻣﺘـﺼﻞ ﺷـﻮﻧﺪ و ﺑﺨﻮاﻫﻨﺪ از آن ﺑﺮاي ﺗﻤﺮﻳﻨﺎت ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻬﺘﺮ اﺳﺖ داده ﻫﺎﻳﻲ را ﺣﺬف ﻛﻨﻴﻢ ﻛﻪ در ﻗـﺴﻤﺖ ﻗﺒـﻞ اﻳﺠـﺎد ﻛـﺮده ﺑﻮدﻳﻢ .ﻗﺒﻞ از اﻳﻨﻜﻪ ﻳﻚ ﻛﺘﺎب را ﺣﺬف ﻛﻨﻴﺪ ،ﺑﻪ ﺷﻤﺎره ي رﻛﻮرد ﻫﺎ در ﺑﺮﻧﺎﻣﻪ ﺗﻮﺟﻪ ﻛﻨﻴﺪ ،ﺳﭙﺲ ﻛﺘﺎب ﻣﻮرد ﻧﻈﺮ ﺧﻮد را ﺣـﺬف ﻛﻨﻴﺪ )ﺷﻜﻞ .(13-16اﻟﺒﺘﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻣﻤﻜﻦ اﺳﺖ ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟﻪ ﺷﻮﻳﺪ ،زﻳﺮا ﻛﺘﺎﺑﻲ ﻛﻪ ﺑﺮاي ﺣﺬف اﻧﺘﺨﺎب ﻛﺮده اﻳﺪ ﻣﻤﻜـﻦ اﺳﺖ ﺑﺎ داده ﻫﺎي ﺟﺪول salesدر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ راﺑﻄﻪ داﺷﺘﻪ ﺑﺎﺷﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ ﻛﺘﺎب دﻳﮕﺮي را اﻧﺘﺨﺎب ﻛﺮده و ﺣﺬف ﻛﻨﻴﺪ.
ﺷﻜﻞ 13-16
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ اﻳﻦ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻣﻤﻜﻦ اﺳﺖ ﻛﻤﻲ ﭘﻴﭽﻴﺪه ﺗﺮ از زﻳﺮ ﺑﺮﻧﺎﻣﻪ ي btnUpdate_Clickﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ و دﻟﻴﻞ آن ﻧﻴـﺰ راﺑﻄـﻪ ي ﺑـﻴﻦ داده ﻫـﺎي ﻣﻮﺟـﻮد در ﺟـﺪول titlesو ﺟـﺪول authorsاﺳـﺖ .ﻫﻤــﺎﻧﻄﻮر ﻛـﻪ ﺑـﻪ ﺧـﺎﻃﺮ دارﻳـﺪ ،ﺟـﺪوﻟﻲ ﺑـﻪ ﻧــﺎم
٦٨٧
authortitleدر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ pubsوﺟﻮد دارد ﻛـﻪ راﺑﻄـﻪ ي ﺑـﻴﻦ داده ﻫـﺎي ﻣﻮﺟـﻮد در ﺟـﺪول authorsو ﺟﺪول titlesرا ﺗﻌﻴﻴﻦ ﻣﻲ ﻛﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻗﺒﻞ از اﻳﻨﻜﻪ رﻛﻮردي را از ﺟﺪول titlesﭘﺎك ﻛﻨﻴﻢ ،ﺑﺎﻧﻚ رﻛﻮرد ﻣﺮﺑﻮط ﺑـﻪ آن را از ﺟﺪول authortitleﺣﺬف ﻛﻨﻴﻢ .ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻦ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﺑﻪ دو دﺳﺘﻮر DELETEﻧﻴﺎز دارﻳﻢ. دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺘﻐﻴﻴﺮ ﻫﺎي ﻣﻮرد ﻧﻴﺎز را ﺗﻌﺮﻳﻒ ﻛﺮدﻳﻢ ،ﻣﻜﺎن رﻛﻮرد ﺟﺎري را ﺑﺮاﺑﺮ ﺑﺎ ﻣﻜﺎن رﻛﻮرد اﻧﺘﺨﺎب ﺷﺪه ﻣﻨﻬﺎي 1ﻗﺮار ﻣﻲ دﻫﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ آﺧﺮﻳﻦ رﻛﻮرد ﺑﺮود و آن را ﺣﺬف ﻛﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ رﻛﻮرد ﻗﺒﻠﻲ رﻛـﻮرد ﺣﺬف ﺷﺪه در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد .ﻫﻤﭽﻨﻴﻦ ﻗﺒﻞ از ﺣﺬف رﻛﻮرد ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ اﮔﺮ ﻛﺎرﺑﺮ در اوﻟـﻴﻦ رﻛـﻮرد ﻗـﺮار داﺷـﺘﻪ ﺑﺎﺷﺪ )ﺷﻤﺎره رﻛﻮرد ﺟﺎري ﻣﻨﻬﺎي ﻳﻚ از ﺻﻔﺮ ﻛﻤﺘﺮ ﺷﻮد( ،ﺷﻤﺎره رﻛﻮرد را ﺑﺮاﺑﺮ ﺑﺎ ﺻﻔﺮ ﻗﺮار دﻫﻴﻢ ﺗﺎ ﺑﻌﺪ از ﺣﺬف اوﻟﻴﻦ رﻛﻮرد ،رﻛﻮردي ﻛﻪ ﺑﻪ ﺑﺎ اﻧﺪﻳﺲ ﺻﻔﺮ ﻣﺸﺨﺺ ﻣﻲ ﺷﻮد ﻧﻤﺎﻳﺶ داده ﺷﻮد. ﻫﻤﭽﻨﻴﻦ ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ زﻳﺮ ﺑﺮﻧﺎﻣﻪ دﻳﮕﺮ از ﺷﻴﺊ CurrencyManagerاﺳﺘﻔﺎده ﻧﻜﺮده اﻳﻢ ،ﺑﻠﻜﻪ ﺑﻪ ﺻﻮرت ﻣـﺴﺘﻘﻴﻢ از ﺷﻴﺊ BindingContextدر ﻓﺮم اﺳﺘﻔﺎده ﻛﺮده و ﻣﻨﺒﻊ داده اي objDataViewرا ﺑﺮاي آن ﻣﺸﺨﺺ ﻛﺮده اﻳـﻢ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﺑﻪ ﺧﺎﻃﺮ دارﻳﺪ ﺷﻴﺊ BindingContextﻗﺴﻤﺘﻲ از ﻓﺮم ﺑﻪ ﺷﻤﺎر ﻣﻲ رود و ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن آن ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻛﺎر ﺧﺎﺻﻲ را اﻧﺠﺎم دﻫﻴﻢ .دﻟﻴﻞ اﻳﻦ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ از BindingContextاﺳﺘﻔﺎده ﻛﺮده اﻳﻢ اﻳﻦ اﺳﺖ ﻛـﻪ ﻧﺸﺎن دﻫﻴﻢ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان از اﻳﻦ ﺷﻴﺊ در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﺮد و ﺿﺮورﺗﻲ ﻧﺪارد ﻛﻪ ﺣﺘﻤﺎً در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺮاي ﺟـﺎ ﺑـﻪ ﺟـﺎ ﺷـﺪن ﺑـﻴﻦ رﻛﻮرد ﻫﺎ از ﺷﻴﺊ CurrencyManagerاﺳﺘﻔﺎده ﻛﻨﻴﻢ. // Declare local variables and objects... ;int intPosition ;)(SqlCommand objCommand = new SqlCommand // Save the current record position - 1 for the one to // be deleted... = intPosition ;this.BindingContext[objDataView].Position - 1 // If the position is less than 0 set it to 0... ) if( intPosition < 0 ;intPosition = 0 در اﻳﻦ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﺑﺮاي ﺗﻨﻈﻴﻢ ﺧﺎﺻﻴﺖ CommandTextاز ﺷﻴﺊ ،SqlCommandدو دﺳﺘﻮر DELETEاﻳﺠﺎد ﻛﺮده و آﻧﻬﺎ را ﺑﻪ وﺳﻴﻠﻪ ي ﻳﻚ ; از ﻫﻢ ﺟﺪا ﻣﻲ ﻛﻨﻴﻢ .ﺳﭙﺲ ﻋﺒﺎرت ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ دو دﺳﺘﻮر را در ﺧﺎﺻﻴﺖ CommandTextﻗﺮار ﻣﻲ دﻫﻴﻢ .دﺳﺘﻮر DELETEاول رﻛـﻮرد ﻣﺮﺑـﻮط ﺑـﻪ راﺑﻄـﻪ ي ﻛﺘـﺎﺑﻲ ﻛـﻪ ﻣـﻲ ﺧـﻮاﻫﻴﻢ ﺣـﺬف ﻛﻨـﻴﻢ و ﻧﻮﻳـﺴﻨﺪه ي آن را از ﺟـﺪول authortitleﺣﺬف ﻣﻲ ﻛﻨﺪ .دﺳﺘﻮر DELETEدوم ﻧﻴﺰ رﻛﻮرد ﻣﺮﺑﻮط ﺑﻪ ﺧﻮد ﻛﺘﺎب را از ﺟﺪول titlesﺣﺬف ﻣﻲ ﻛﻨﺪ. // Set the Command object properties... ;objCommand.Connection = objConnection objCommand.CommandText = "DELETE FROM titleauthor " + "WHERE title_id = @title_id;" + ;""DELETE FROM titles WHERE title_id = @title_id
٦٨٨
در اﻳﻦ ﻗـﺴﻤﺖ ﻧﻴـﺰ ﺑـﺮاي ﻛﻠﻴـﺪ اﺻـﻠﻲ ﻛـﻪ در ﻗـﺴﻤﺖ WHEREدو دﺳـﺘﻮر DELETEﻣـﻮرد اﺳـﺘﻔﺎده ﻗـﺮار ﻣـﻲ ﮔﻴـﺮد ،ﻳـﻚ placeholderاﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ .ﺳﭙﺲ ﻣﻘﺪار اﻳﻦ placeholderرا ﺑﺮاﺑﺮ ﺑﺎ ﺷﻨﺎﺳﻪ ي ﻣﺮﺑـﻮط ﺑـﻪ ﻛﺘـﺎﺑﻲ ﻛـﻪ ﻣـﻲ ﺧﻮاﻫﻴﻢ ﺣﺬف ﻛﻨﻴﻢ ﻗﺮار ﻣﻲ دﻫﻴﻢ )در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ اﻳﻦ ﻛﻪ از placeholderدر دو ﻗﺴﻤﺖ اﺳﺘﻔﺎده ﻛـﺮده اﻳـﻢ، اﻣﺎ ﻓﻘﻂ ﻳﻚ ﻋﻀﻮ را ﺑﻪ ﺧﺎﺻﻴﺖ Parametersاﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ(: // Parameter for the title_id field... objCommand.Parameters.AddWithValue("@title_id", ;)this.BindingContext[objDataView,"title_id"].Current ﺑﻘﻴﻪ س ﻛﺪ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺒﻠﻲ اﺳﺖ و ﺑﺎﻳﺪ ﺗﺎﻛﻨﻮن ﺑﻪ اﻧﺪازه ي ﻛﺎﻓﻲ ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ .ﺑﺎ اﺗﻤﺎم اﻳﻦ ﻣﺘﺪ ،اﻳﻦ ﭘـﺮوژه و اﻳﻦ ﻓﺼﻞ ﻧﻴﺰ ﺑﻪ ﭘﺎﻳﺎن ﻣﻲ رﺳﺪ .اﻣﻴﺪوارم ﻛﻪ ﺑﺎ اﺗﻤﺎم اﻳﻦ ﻓﺼﻞ اﻃﻼﻋﺎت ﺧﻮﺑﻲ در راﺑﻄﻪ ﺑﺎ اﺗﺼﺎل ﺑﻪ داده ﻫﺎ ،وارد ﻛـﺮدن داده ﻫـﺎي ﺟﺪﻳﺪ ،وﻳﺮاﻳﺶ و ﻳﺎ ﺣﺬف آﻧﻬﺎ ﺑﺎ اﺳﺘﻔﺎده از SQLدر ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺪﺳﺖ آورده ﺑﺎﺷﻴﺪ. ﻗﺒﻞ از اﻳﻨﻜﻪ ﻓﺼﻞ را ﺑﻪ ﭘﺎﻳﺎن ﺑﺮﺳﺎﻧﻴﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﻳﺎدآور ﺷﻮم ﻛﻪ ﻛﻨﺘﺮل ﺧﻄﺎﻫﺎ ﺑﺨﺶ ﻣﻬﻤﻲ از ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﺗـﺸﻜﻴﻞ ﻣـﻲ دﻫﻨـﺪ .در ﭘﺮوژه ي ﻗﺒﻠﻲ ﺑﻪ ﺟﺰ ﻳﻚ ﻗﺴﻤﺖ ،در ﺑﻘﻴﻪ ي ﻣﻮارد از ﻛﻨﺘﺮل ﺧﻄﺎﻫﺎ ﺻﺮﻓﻨﻈﺮ ﻛﺮدﻳﻢ ﺗﺎ ﻣﻜﺎن ﻛﻤﺘﺮي ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﮔﺮﻓﺘﻪ ﺷﻮد .ﻫﻤﭽﻨﻴﻦ ﻫﻨﮕﺎم وارد ﻛﺮدن داده ﻫﺎ در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ از ﺻﺤﻴﺢ ﺑﻮدن و ﻣﻌﺘﺒﺮ ﺑﻮدن آﻧﻬﺎ ﻧﻴﺰ ﺻـﺮﻓﻨﻈﺮ ﻛـﺮدﻳﻢ .ﺑﻨـﺎﺑﺮاﻳﻦ ﻣﻤﻜـﻦ اﺳﺖ ﻛﺎرﺑﺮ ﺳﻌﻲ ﻛﻨﺪ رﻛﻮردي را ﺑﺪون وارد ﻛﺮدن داده اي در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﻳﺠﺎد ﻛﻨﺪ و اﻳﻦ ﺧﻮد ﻣﻮﺟﺐ ﺑـﺮوز ﺧﻄـﺎ در ﺑﺮﻧﺎﻣـﻪ ﻣـﻲ ﺷﻮد.
ﻧﺘﻴﺠﻪ: در اﻳــﻦ ﻓــﺼﻞ ﺑــﻪ ﺑﻌــﻀﻲ از ﻛﻼﺳــﻬﺎي ﻣﻬــﻢ ADO.NETاز ﻗﺒﻴــﻞ ،SqlCommand ،SqlConnection SqlDataAdapterو SqlParametreﻧﮕﺎﻫﻲ اﻧﺪاﺧﺘﻴﻢ و ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛﻪ اﻳـﻦ ﻛﻼﺳـﻬﺎ ﭼﮕﻮﻧـﻪ ﻣـﻲ ﺗﻮاﻧﻨـﺪ ﻫﻨﮕﺎم درﻳﺎﻓﺖ اﻃﻼﻋﺎت ،وارد ﻛﺮدن اﻃﻼﻋﺎت ﺟﺪﻳﺪ ،ﺣﺬف اﻃﻼﻋﺎت ﺟﺎري و ﻳﺎ وﻳﺮاﻳﺶ آﻧﻬﺎ ﻛﻤﻚ ﻛﻨﻨﺪ .اﻟﺒﺘﻪ ﺗﻤﺎم اﻳﻦ ﻛﻼﺳﻬﺎ ﺑﺮاي ﺑﺎﻧﻚ ﻫﺎي اﻃﻼﻋﺎﺗﻲ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ SQL Serverاﻳﺠﺎد ﺷﺪه ﺑﺎﺷﻨﺪ .اﻳـﻦ ﻛﻼﺳـــﻬﺎ داراي ﻛﻼﺳـــﻬﺎي ﻣﺘﻨـــﺎﻇﺮي ﻫـــﺴﺘﻨﺪ ﻛـــﻪ ﺑـــﺎ ﭘﻴـــﺸﻮﻧﺪ OleDbﺷـــﺮوع ﻣـــﻲ ﺷـــﻮﻧﺪ و در ﻓـــﻀﺎي ﻧـــﺎم System.Data.OleDbﻗﺮار دارﻧﺪ. ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﻓﺼﻞ ﻛﻼﺳﻬﺎي DataSetو DataViewاز ﻓﻀﺎي ﻧﺎم System.Dataرا ﺑﺮرﺳﻲ ﻛﺮده و ﻧﺤـﻮه ي اﺳﺘﻔﺎده از آﻧﻬﺎ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ و دﻳﺪﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﻼﺳﻬﺎ اﺷﻴﺎﻳﻲ را اﻳﺠـﺎد ﻛـﺮد و داده ﻫﺎي ﻣﻮﺟﻮد در آﻧﻬﺎ را ﺑﻪ ﻛﻨﺘﺮﻟﻬـﺎي ﺳـﺎده ي ﻣﻮﺟـﻮد در ﻓـﺮم ﻣﺘـﺼﻞ ﻛـﺮد .در ﻃـﻮل ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي اﻳـﻦ ﻓـﺼﻞ ﺑﻴـﺸﺘﺮ ﺑـﺎ ﻛـﻼس DataViewﻛﺎر ﻛﺮدﻳﻢ .دﻳﺪﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﻼس در ﺑﻴﻦ داده ﻫﺎي ﻣﻮﺟﻮد در ﻓﺮم ﺟﺴﺘﺠﻮ اﻧﺠـﺎم داد و ﻳﺎ آﻧﻬﺎ را ﻣﺮﺗﺐ ﻛﺮد. ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻓﺮم ﻣﺘﺼﻞ ﻛﺮد و ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻛـﻼس CurrencyManagerﺑﻴﻦ اﻳﻦ داده ﻫﺎ ﺟﺎ ﺑﻪ ﺟﺎ ﺷﺪه و آﻧﻬﺎ را ﻛﻨﺘﺮل ﻛﺮد .ﻛﻼس CurrencyManagerﻳـﻚ روش ﺳﺮﻳﻊ و ﺳﺎده ﺑﺮاي ﻛﻨﺘﺮل ﺣﺮﻛﺖ ﺑﻴﻦ داده ﻫﺎي ﻣﻮﺟﻮد در ﻓﺮم را در ﺑﺮﻧﺎﻣﻪ ﻓﺮاﻫﻢ ﻣﻲ ﻛﻨﺪ. در اﻳﻦ ﻓﺼﻞ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ داده ﻫﺎ ،اﻳﺠﺎد داده ﻫﺎي ﺟﺪﻳﺪ ،ﺣﺬف داده ﻫﺎي ﻣﻮﺟﻮد و ﻳﺎ وﻳﺮاﻳﺶ آﻧﻬـﺎ از روﺷـﻬﺎي دﺳـﺘﻲ اﺳـﺘﻔﺎده ﻛﺮده و ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﺗﻤﺎم اﻳﻦ ﻣﻮارد را ﺧﻮدﻣﺎن در ﺑﺮﻧﺎﻣﻪ وارد ﻛﺮدﻳﻢ .اﻟﺒﺘﻪ در ﻣﻮاردي ﻛﻪ ﻧﻴﺎز ﺑﻪ ﺳﺮﻋﺖ ﺑﻴﺸﺘﺮ در ﻧﻮﺷـﺘﻦ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎ دارﻳﺪ ،ﻣﻲ ﺗﻮاﻧﻴﺪ از وﻳﺰارد ﻫﺎﻳﻲ ﻛﻪ در ﻓﺼﻞ ﻗﺒﻞ ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﺷﺪﻳﻢ اﺳﺘﻔﺎده ﻛﺮده و ﻓﻘﻂ در ﻣﻮارد ﺿﺮوري ﻛﺪ ﺗﻮﻟﻴﺪ ﺷﺪه ﺑﻪ وﺳـﻴﻠﻪ ي اﻳﻦ وﻳﺰاردﻫﺎ را ﺑﻪ ﺻﻮرت دﺳﺘﻲ ﺗﻐﻴﻴﺮ دﻫﻴﺪ .اﺳﺘﻔﺎده از روﺷﻬﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻓﺼﻞ ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﺷﺪﻳﻢ در ﻣﻮاﻗﻌﻲ ﻣﻔﻴﺪ اﺳﺖ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ
٦٨٩
ﻛﻨﺘﺮل ﻛﺎﻣﻠﻲ روي داده ﻫﺎ داﺷﺘﻪ ﺑﺎﺷﻴﺪ و ﻳﺎ ﻣﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در اﻳﻦ ﻓﺼﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ،ﺑﺎ ﺟﺪوﻟﻬﺎﻳﻲ ﭘﻴﭽﻴﺪه از داده ﻫﺎي واﺑﺴﺘﻪ ﺑﻪ ﻫﻢ در ارﺗﺒﺎط ﺑﺎﺷﻴﺪ. در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ:
ﺑﻪ ﺳﺎدﮔﻲ ﺑﺘﻮاﻧﻴﺪ از ﻛﻼﺳﻬﺎي ADO.NETﻛﻪ در اﻳﻦ ﻓﺼﻞ ﻣﻌﺮﻓﻲ ﺷﺪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﺑﺪاﻧﻴﺪ ﻛﻪ ﭼﻪ ﻣﻮاﻗﻌﻲ ﻻزم اﺳﺖ ﻛﻪ از DataSetو ﭼﻪ ﻣﻮاﻗﻌﻲ ﻻزم اﺳﺖ ﻛﻪ از DataViewاﺳﺘﻔﺎده ﻛﻨﻴﺪ. ﺑﺘﻮاﻧﻴﺪ ﺑﻪ ﺻﻮرت دﺳﺘﻲ و ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺪ ﺧﺎﺻﻴﺖ ﻫﺎي ﻣﻮﺟﻮد در ﻛﻨﺘﺮﻟﻬﺎي ﺑﺮﻧﺎﻣﻪ را ﺑـﻪ داده ﻫـﺎي DataSetو ﻳـﺎ DataViewﻣﺘﺼﻞ ﻛﻨﻴﺪ. ﺑﺘﻮاﻧﻴــﺪ ﺑــﺎ اﺳــﺘﻔﺎده از ﻛــﻼس CurrencyManagerﺑــﻴﻦ داده ﻫــﺎي ﻣﻮﺟــﻮد در DataSetو ﻳــﺎ DataViewﺣﺮﻛﺖ ﻛﻨﻴﺪ. ﺑﺘﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻼس DataViewداده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ را ﻣﺮﺗﺐ ﻛﺮده و ﻳﺎ در ﺑﻴﻦ آﻧﻬﺎ ﺟﺴﺘﺠﻮ ﻛﻨﻴﺪ.
ﺗﻤﺮﻳﻦ:
ﺗﻤﺮﻳﻦ :1 ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ داده ﻫﺎي ﻣﻮﺟﻮد در ﺟﺪول Authorsاز ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ Pubsرا ﺑـﻪ ﻛـﺎرﺑﺮ ﻧﻤـﺎﻳﺶ دﻫﺪ .ﺑﺮاي ﻧﻤﺎﻳﺶ داده ﻫﺎ از ﻳﻚ ﻛﻨﺘﺮل DataGridViewدر ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﺮده و ﺑﺮاي درﻳﺎﻓـﺖ داده ﻫـﺎ ﻧﻴـﺰ دﺳـﺘﻮر SQLﺳﺎده ي زﻳﺮ را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ: SELECT * FROM Authors
٦٩٠
ﻓﺼﻞ ﻫﻔﺪﻫﻢ :ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب اﻣﺮوزه ،اﻳﻨﺘﺮﻧﺖ ﻳﻜﻲ از ﺑﺨﺸﻬﺎي ﺑﺴﻴﺎر ﻣﻬﻢ و ﺣﻴﺎﺗﻲ در زﻧﺪﮔﻲ ﻛﺎري و ﺣﺘﻲ ﺷﺨﺼﻲ ﺑﺴﻴﺎري از اﻓﺮاد ﺑﻪ ﺷﻤﺎر ﻣﻲ رود .در ﭼﻨﺪ ﺳـﺎل اﺧﻴﺮ ،ﺑﺎﻧﻜﻬﺎ و ﻓﺮوﺷﮕﺎه ﻫﺎي اﻟﻜﺘﺮوﻧﻴﻜﻲ ﺑﺎﻋﺚ ﺷﺪه اﻧﺪ ﻛﻪ در زﻣﺎن و ﭘﻮل ﺑﺴﻴﺎري از اﻓﺮاد ﺻﺮﻓﻪ ﺟﻮﻳﻲ ﺷﻮد و دﻳﮕﺮ ﻧﻴﺎزي ﻧﺒﺎﺷﺪ ﻛـﻪ اﻓﺮاد ﺑﺮاي ﺧﺮﻳﺪ و ﻳﺎ ﺗﺠﺎرت ﺑﺎ ﺻﺮف وﻗﺖ و زﻣﺎن زﻳﺎد ،ﺑﻪ ﻣﻜﺎن ﻫﺎي ﺷﻠﻮغ رﻓﺖ و آﻣﺪ ﻛﻨﻨﺪ .ﺑﺎ وﺟﻮد ﻣﺸﻜﻼت اﻣﻨﻴﺘﻲ ﻛﻪ در اﻳﻦ ﻧﻮع ﺗﺠﺎرت وﺟﻮد دارد ،اﻣﺎ ﻫﻨﻮز ﺑﻴﺸﺘﺮ ﻣﺮدم ﺑﻪ دﻟﻴﻞ ﺳﺎدﮔﻲ و راﺣﺘﻲ آن و ﻧﻴﺰ ﺻﺮﻓﻪ ﺟﻮﻳﻲ زﻳﺎدي ﻛﻪ در زﻣﺎن و ﺳﺮﻣﺎﻳﻪ اﻳﺠﺎد ﻣـﻲ ﻛﻨـﺪ، ﺗﻤﺎﻳﻞ دارﻧﺪ ﻛﻪ از اﻳﻦ روش ﺗﺠﺎرت اﺳﺘﻔﺎده ﻛﻨﻨﺪ .اﻟﺒﺘﻪ در ﻣﻮرد اﻣﻨﻴﺖ ﻧﻴﺰ در ﺗﻤﺎم ﻣﻮارد ﺑﺮﻧﺎﻣﻪ ﻫﺎ در ﺣﺎل ﺑﻬﺒﻮد ﻫـﺴﺘﻨﺪ و روز ﺑـﻪ روز ﺳﻌﻲ ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ ﻣﺤﻴﻂ اﻳﻤﻦ ﺗﺮي را ﺑﺮاي ﺧﺮﻳﺪ و ﻓﺮوش و ﺗﺠﺎرت اﻟﻜﺘﺮوﻧﻴﻜﻲ اﻳﺠﺎد ﻛﻨﻨﺪ .اﻣﺎ ﺑﺎز ﻫﻢ ﻧﻤﻲ ﺗﻮان ﻣﻄﻤﺌﻦ ﺷﺪ ﻛﻪ ﻳﻚ ﻣﺤﻴﻂ از اﻣﻨﻴﺘﻲ ﺻﺪ در ﺻﺪ ﺑﺮﺧﻮردار اﺳﺖ. ﺑﺎ ﻧﮕﺎﻫﻲ ﺑﻪ آﻳﻨﺪه ﻣﻲ ﺗﻮان ﻣﻄﻤﺌﻦ ﺷﺪ ﻛﻪ ﺗﺠﺎرت در اﻳﻨﺘﺮﻧﺖ ﮔﺴﺘﺮش زﻳﺎدي ﭘﻴﺪا ﺧﻮاﻫﺪ ﻛﺮد ،ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮﻧﺎﻣـﻪ ﻧﻮﻳـﺴﺎن ﺑﺎﻳـﺪ ﺑﺘﻮاﻧﻨـﺪ ﺳﺎﻳﺘﻬﺎي دﻳﻨﺎﻣﻴﻚ و ﻗﻮي را ﺑﺮاي اﻳﻦ ﻣﻮارد اﻳﺠﺎد ﻛﻨﻨﺪ .در اﻳﻦ ﻓﺼﻞ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﺑﺎ ﭼﮕﻮﻧﮕﻲ اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب آﺷﻨﺎ ﺷﻮﻳﻢ .اﺑﺘﺪا ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﻣﻔﻬﻮم ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺗﺤﺖ وب را ﺑﻴﺎﻣﻮزﻳﻢ ،ﺳﭙﺲ ﺑﻪ ﺳﻤﺖ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ در وب ﺣﺮﻛـﺖ ﻛﻨﻴﻢ .ﻗﺒﻞ از اﻳﻨﻜﻪ وارد ﻧﻮﺷﺘﻦ ﻛﺪ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب ﺷﻮﻳﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﻛﻤﻲ ﺑﺎ اﺟﺰاي ﺗﺸﻜﻴﻞ دﻫﻨﺪه ي اﻳﻦ ﻧـﻮع ﺑﺮﻧﺎﻣـﻪ ﻫﺎ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن از آﻧﻬﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ آﺷﻨﺎ ﺷﻮﻳﻢ. در اﻳﻦ ﻓﺼﻞ:
ﺑﺎ ﻣﺒﺎﻧﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺒﺘﻨﻲ ﺑﺮ وب آﺷﻨﺎ ﻣﻲ ﺷﻮﻳﻢ. ﻣﺰاﻳﺎي ﻓﺮﻣﻬﺎي ﺗﺤﺖ وب ﺑﺮ ﻓﺮﻣﻬﺎي وﻳﻨﺪوزي را ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﻢ. ﭘﺮدازش ﺳﻤﺖ ﺳﺮور و ﭘﺮدازش ﺳﻤﺖ ﻛﻼﻳﻨﺖ را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد. ﺑﺎ ﻛﻨﺘﺮﻟﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﺑﺮرﺳﻲ ﺻﺤﺖ داده ﻫﺎ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ. ﺑﺎ ﻛﻨﺘﺮﻟﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﺣﺮﻛﺖ در ﺳﺎﻳﺖ ،ﺗﻌﻴﻴﻦ ﻫﻮﻳﺖ و ﻧﻴﺰ ﻓﺮﻣﻬﺎي اﺻﻠﻲ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ. از ﻛﻨﺘﺮل GridViewاﺳﺘﻔﺎده ﻛﺮده و ﻳﻚ ﻓﺮم ﺗﺤﺖ وب ﺑﺮاي ﻧﻤﺎﻳﺶ داده ﻫﺎ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد.
ﻧﻜﺘﻪ :ﻗﺴﻤﺘﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل ﺧﻄﺎ ﻫﺎ و اﺳﺘﺜﻨﺎ ﻫﺎ از ﺗﻤﺎم ﻗﺴﻤﺘﻬﺎي اﻣﺘﺤﺎن ﻛﻨﻴﺪ اﻳﻦ ﻓﺼﻞ ﺣﺬف ﺷﺪه اﻧﺪ ﺗﺎ ﻣﻜﺎن ﻛﻤﺘﺮي اﺷﻐﺎل ﺷﻮد .اﻣﺎ ﻫﻨﮕﺎم ﻧﻮﺷﺖ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺣﺘﻤﺎً ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل ﺧﻄﺎ را ﻧﻴﺰ وارد ﻛﻨﻴﺪ .ﺑﺮاي ﻣﺮور ﻣﻄﺎﻟﺐ ﻣﺮﺑﻮط ﺑـﻪ ﻛﻨﺘـﺮل ﺧﻄـﺎ ﻫـﺎ و اﺳﺘﺜﻨﺎ ﻫﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻓﺼﻞ ﻳﺎزدﻫﻢ ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ.
ﻣﻌﻤﺎري ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب: در ﻓﺼﻠﻬﺎي ﻗﺒﻠﻲ ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وﻳﻨﺪوز آﺷﻨﺎ ﺷﺪﻳﻢ و ﻧﺤﻮه ي ﻋﻤﻠﻜﺮد آﻧﻬﺎ را ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ .در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﻴﺸﺘﺮ ﭘﺮدازش ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ ،ﺗﻮﺳﻂ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻛﺎرﺑﺮي اﻧﺠﺎم ﻣﻲ ﺷﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده اﺳﺖ و ﺑﻪ ﺟﺰ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ در ﭼﻨﺪ ﻓﺼﻞ اﺧﻴﺮ اﻳﺠـﺎد ﻛﺮدﻳﻢ ،ﺑﻴﺸﺘﺮ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﻪ ﺻﻮرت ﻣﺴﺘﻘﻞ ﻋﻤﻞ ﻣﻲ ﻛﺮدﻧﺪ و در ﻃﻮل زﻣﺎن اﺟﺮا ﺑﻪ ﺑﺮﻧﺎﻣﻪ و ﻳﺎ ﺳﺮور دﻳﮕﺮي ﻧﻴـﺎز ﻧﺪاﺷـﺘﻨﺪ .اﻣـﺎ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺒﺘﻨﻲ ﺑﺮ وب ﺷﺮاﻳﻂ ﻛﺎﻣﻼً ﺗﻔﺎوت دارد .در اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻴﺸﺘﺮ ﭘﺮدازش ﺗﻮﺳﻂ ﺳﺮور اﻧﺠﺎم ﻣـﻲ ﺷـﻮد و ﺳـﭙﺲ ﻧﺘﻴﺠﻪ ﺑﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻛﺎرﺑﺮ )ﻛﻼﻳﻨﺖ( ﺑﺮﻣﻲ ﮔﺮدد و در ﻣﺮورﮔﺮ ﻛﺎرﺑﺮ )ﻣﺜﻼ اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر( ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد. ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ ،ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﭼﻴﺰي را ﺑﻪ ﻛﺎرﺑﺮان آن ﺑﺮﻧﺎﻣﻪ ﺑﺪﻫﻴﺪ ﺗﺎ در ﺳﻴﺴﺘﻢ ﺧـﻮد ﻧـﺼﺐ ﻛﻨﻨﺪ و ﺑﻪ واﺳﻄﻪ ي آن ﺑﺘﻮاﻧﻨﺪ از ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ اﺳﺘﻔﺎده ﻛﻨﻨﺪ .ﺑﻠﻜﻪ ﻓﻘﻂ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ را روي ﻳﻚ ﺳﺮور در ﺷﺒﻜﻪ ي وب
٦٩١
ﻧﺼﺐ ﻛﻨﻴﺪ ،ﺳﭙﺲ ﻫﺮ ﻓﺮدي ﻛﻪ ﺑﺘﻮاﻧﺪ ﺑﻪ اﻳﻦ ﺳﺮور وب ﺷﻤﺎ ﻣﺘﺼﻞ ﺷﻮد و ﻫﻤﭽﻨﻴﻦ در ﻛﺎﻣﭙﻴﻮﺗﺮ ﺧﻮد ﻳﻚ ﻣﺮورﮔﺮ وب داﺷﺘﻪ ﺑﺎﺷﺪ ،ﺑﻪ ﻋﻨﻮان ﻳﻜﻲ از ﻛﺎرﺑﺮان ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد و ﻣﻲ ﺗﻮاﻧﺪ از آن ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل ﻳﻚ ﻣﻮﺗﻮر ﺟﺴﺘﺠﻮ در اﻳﻨﺘﺮﻧﺖ ﻣﻲ ﺗﻮاﻧﺪ ﻧﻤﻮﻧﻪ ي ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي اﻳﻨﺘﺮﻧﺘﻲ ﺑﺎﺷﺪ .ﺑﺮاي اﺳﺘﻔﺎده از اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﭼﻴﺰي را در ﻛـﺎﻣﭙﻴﻮﺗﺮ ﺧـﻮد ﻧـﺼﺐ ﻛﻨﻴـﺪ، ﺑﻠﻜﻪ ﻛﺎﻓﻲ اﺳﺖ ﺑﻪ ﺷﺒﻜﻪ ي اﻳﻨﺘﺮﻧﺖ ﻣﺘﺼﻞ ﺑﺎﺷﻴﺪ و ﺑﺘﻮاﻧﻴﺪ ﺻﻔﺤﺎت ﻣﺮﺑﻮط ﺑﻪ آن ﻣﻮﺗﻮر ﺟﺴﺘﺠﻮ را در ﻣﺮورﮔﺮ ﺧﻮد ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ .ﺑـﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺷﻤﺎ ﻧﻴﺰ ﻳﻜﻲ از ﻛﺎرﺑﺮان آن ﺑﺮﻧﺎﻣﻪ ي اﻳﻨﺘﺮﻧﺘﻲ ،و ﻳﺎ ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ آن ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب ﻣﺤﺴﻮب ﻣﻲ ﺷـﻮﻳﺪ .ﻫﻤـﺎﻧﻄﻮر ﻛﻪ در اﻳﻦ ﻣﺜﺎل ﻧﻴﺰ ﻣﺸﺨﺺ اﺳﺖ در اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﻴﺸﺘﺮ ﭘﺮدازش در ﻛﺎﻣﭙﻴﻮﺗﺮ ﺳﺮور اﻧﺠﺎم ﻣـﻲ ﺷـﻮد و ﺳـﭙﺲ ﻧﺘﻴﺠـﻪ ي آن ﺑـﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻛﻼﻳﻨﺖ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد. در اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﺟﺒﺎري ﻧﻴﺴﺖ ﻛﻪ ﺗﻤﺎم ﭘﺮدازش در ﺳﺮور اﻧﺠﺎم ﺷﻮد و ﻣﻲ ﺗﻮان ﻣﻘﺪاري را ﻧﻴـﺰ در ﻛـﺎﻣﭙﻴﻮﺗﺮ ﻛﻼﻳﻨـﺖ اﻧﺠـﺎم داد. اﻟﺒﺘﻪ در اﻳﻦ ﺷﺮاﻳﻂ ﺑﺎﻳﺪ ﺣﺠﻢ ﭘﺮدازﺷﻲ ﻛﻪ ﺑﻪ ﺳﻤﺖ ﻛﻼﻳﻨﺖ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد را ﻧﻴﺰ در ﻧﻈﺮ ﺑﮕﻴﺮﻳﻢ .زﻳﺮا در اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ،اﻓﺮاد و ﻳﺎ ﻛﺎرﺑﺮان ﺑﺮﻧﺎﻣﻪ ،از ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﺎ و ﺳﻴﺴﺘﻤﻬﺎي ﮔﻮﻧﺎﮔﻮﻧﻲ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ .ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﺣﺠﻢ زﻳﺎدي از ﻛﺎرﻫﺎي ﺑﺮﻧﺎﻣﻪ را ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺎﻣﭙﻴﻮﺗﺮ ﻛﺎرﺑﺮ اﻧﺠﺎم دﻫﻴﻢ ،ﻣﻤﻜﻦ اﺳﺖ ﺑﻌﻀﻲ از ﻛﺎرﺑﺮان در اﺳﺘﻔﺎده از ﺑﺮﻧﺎﻣﻪ دﭼﺎر ﻣﺸﻜﻞ ﺷﻮﻧﺪ .اﻳﻦ ﻣﻮرد ﻳﻜﻲ از ﺗﻔﺎوﺗﻬﺎي اﺻﻠﻲ ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وﻳﻨﺪوز و ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب اﺳﺖ .ﺧﻮب ،ﺑﻬﺘﺮ اﺳﺖ ﻣﻘﺪاري ﺑﺎ ﺗﻔﺎوﺗﻬﺎي اﻳﻦ دو ﻧﻮع ﺑﺮﻧﺎﻣﻪ در وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005 .NETآﺷﻨﺎ ﺷﻮﻳﻢ. ﻫﻨﮕﺎﻣﻲ ﻛﻪ از ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وﻳﻨﺪوز ﺻﺤﺒﺖ ﻣﻲ ﻛﻨﻴﻢ ،ﻣﻌﻤﻮﻻ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻛﺎﻣﭙﺎﻳﻞ ﺷﺪه در اﺧﺘﻴﺎر دارﻳﻢ ﻛﻪ ﻓﺎﻳﻞ آن ﺑﺎﻳﺪ در اﺧﺘﻴﺎر ﻛﺎرﺑﺮان ﺑﺮﻧﺎﻣﻪ ﻗﺮار ﮔﻴﺮد ﺗﺎ آﻧﻬﺎ ﺑﺘﻮاﻧﻨﺪ ﺑﻌﺪ از ﻧﺼﺐ ﺑﺮﻧﺎﻣﻪ در ﻛﺎﻣﭙﻴﻮﺗﺮ ﺧﻮد ،از آن اﺳﺘﻔﺎده ﻛﻨﻨﺪ .ﺑﺮ ﺣﺴﺐ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻣﻤﻜﻦ اﺳﺖ ﻻزم ﺑﺎﺷﺪ ﻛﻪ ﻳﻚ ﻳﺎ ﭼﻨﺪ ﻓﺎﻳﻞ DLLو ﻳﺎ ﻓﺎﻳﻞ EXEدﻳﮕﺮ ﻧﻴﺰ ﻫﻤﺮاه ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﺗﻮزﻳﻊ ﺷﻮد ﺗﺎ اﻓﺮاد ﺑﺘﻮاﻧﻨﺪ از ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻨﺪ. در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب ،ﻣﻌﻤﻮﻻ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﻫﻴﭻ ﻓﺎﻳﻞ اﺟﺮاﻳﻲ و ﻳﺎ ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼﺳﻲ ﺑﻴﻦ ﻛﺎرﺑﺮان آن ﺑﺮﻧﺎﻣﻪ ﺗﻮزﻳـﻊ ﺷـﻮد. ﻛﺎرﺑﺮان ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﺑﻌﺪ از اﺗﺼﺎل ﺑﻪ اﻳﻨﺘﺮﻧﺖ ،ﻣﺮورﮔﺮ ﺧﻮد را ﺑﺎز ﻛﺮده و آدرس وب ﺳﺎﻳﺘﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ در آن ﻗـﺮار دارد را وارد ﻛﻨﻨـﺪ. ﺳﺮوري ﻛﻪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب ﺑﺮ روي آن ﻗﺮار داده ﺷﺪه اﺳﺖ ،ﻣﺴﺌﻮﻟﻴﺖ دارد ﻛﻪ ﺗﻤﺎم ﻣﻨﺎﺑﻊ ﻣﻮرد ﻧﻴﺎز ﺑﺮاي اﺟـﺮاي ﺑﺮﻧﺎﻣـﻪ را در اﺧﺘﻴﺎر آن ﻗﺮار دﻫﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺮورﮔﺮ ﻛﺎرﺑﺮ ،ﻓﻘﻂ وﺳﻴﻠﻪ اي اﺳﺖ ﻛﻪ ﻓﺮد ﺑﻪ وﺳﻴﻠﻪ ي آن ﻣﻲ ﺗﻮاﻧﺪ ﺑﻴﻦ ﺻﻔﺤﺎت ﺑﺮﻧﺎﻣﻪ ﺟﺎ ﺑﻪ ﺟـﺎ ﺷﻮد و ﻫﻤﭽﻨﻴﻦ ﻧﺘﺎﻳﺠﻲ ﻛﻪ از ﺳﺮور ﺑﺮﻧﺎﻣﻪ درﻳﺎﻓﺖ ﻣﻲ ﺷﻮد را ﻣﺸﺎﻫﺪه ﻛﻨﺪ. ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺗﻤﺎم ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ در ﻳﻚ واﺣﺪ ﻣﺘﻤﺮﻛﺰ ﻗﺮار ﻣﻲ ﮔﻴﺮد :ﻛﺎﻣﭙﻴﻮﺗﺮ ﺳﺮوري ﻛﻪ ﺑﺮﻧﺎﻣـﻪ در آن ﻗﺮار دارد .ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗﻮاﻧﻴﻢ در ﺻﻮرت ﻟﺰوم ﻫﺮ ﺗﻐﻴﻴﺮي ﻛﻪ ﻣﺪ ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﻢ را در ﻛﺪ ﻣﻮﺟﻮد در اﻳﻦ ﻛﺎﻣﭙﻴﻮﺗﺮ اﻋﻤﺎل ﻛﻨﻴﻢ .ﺑﻪ اﻳـﻦ ﺗﺮﺗﻴﺐ ﻣﺮﺗﺒﻪ ي ﺑﻌﺪ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺮاي اﺳﺘﻔﺎده از ﺑﺮﻧﺎﻣﻪ ﺑﻪ اﻳﻦ ﺳﺮور آﻣﺪ از ﻛﺪ ﺟﺪﻳﺪ اﺳﺘﻔﺎده ﺧﻮاﻫﺪ ﻛﺮد. ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب ﭼﻨﺪﻳﻦ ﻣﺰﻳﺖ ﻛﻠﻴﺪي و اﺻﻠﻲ دارﻧﺪ .اوﻟﻴﻦ و ﻣﻬﻤﺘﺮﻳﻦ ﻣﺰﻳﺖ اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻫﺰﻳﻨﻪ ي اوﻟﻴﻪ ﺗﻮزﻳﻊ اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ در ﺑﻴﻦ ﻛﺎرﺑﺮان اﺳﺖ ،زﻳﺮا ﺗﻘﺮﻳﺒﺎً در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﻳﻦ ﻛﺎر ﻫﻴﭻ ﻫﺰﻳﻨﻪ ي ﻧﺪارد .در ﻣﺪل ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻛﻼﻳﻨﺖ/ﺳـﺮور ﻗﺒﻠـﻲ، ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﺑﻴﻦ ﺗﻤﺎم ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﺎي ﻛﻼﻳﻨﺖ ﺗﻮزﻳﻊ ﻣﻲ ﺷﺪ ﺗﺎ ﻛﺎرﺑﺮاﻧﻲ ﻛﻪ از اﻳﻦ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﺑﺘﻮاﻧﻨﺪ ﺑﻪ ﺑﺮﻧﺎﻣـﻪ ي ﺳﺮور دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ .اﻳﻦ ﻛﺎر ،ﻣﺨﺼﻮﺻﺎ در ﻣﻮاردي ﻛﻪ ﺑﺮﻧﺎﻣﻪ ي ﻣﻮﺟﻮد در ﺳﺮور ﻣﻲ ﺑﺎﻳﺴﺖ ﺑﻪ وﺳﻴﻠﻪ ي ﭼﻨﺪﻳﻦ ﻛﻼﻳﻨـﺖ در دﻓﺎﺗﺮ ﻛﺎر ﻣﺨﺘﻠﻒ در ﭼﻨﺪ ﻧﻘﻄﻪ از دﻧﻴﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﺮﻓﺖ ﻛﺎر ﺑﺴﻴﺎر ﭘﺮ ﻫﺰﻳﻨﻪ اي ﺑﻮد. 1 ﻳﻜﻲ دﻳﮕﺮ از ﻣﺰاﻳﺎي ﻋﻤﺪه ي اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ،ﻫﺰﻳﻨﻪ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﺗﻮزﻳﻊ ﻧﺴﺨﻪ ﻫﺎي ﺑﺮوز رﺳﺎﻧﻲ در ﺑﻴﻦ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﻮد ،زﻳـﺮا اﻳﻦ ﻛﺎر ﻧﻴﺰ ﻫﻴﭻ ﻫﺰﻳﻨﻪ اي درﺑﺮ ﻧﺪاﺷﺖ .ﻛﺎﻓﻲ ﺑﻮد ﺗﻤﺎم ﻓﺎﻳﻠﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﺑﻪ روز رﺳﺎﻧﻲ ﺑﺮﻧﺎﻣﻪ و ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠـﻒ آن ،در ﻛـﺎﻣﭙﻴﻮﺗﺮ ﺳﺮور ﻛﻪ ﺑﺮﻧﺎﻣﻪ در آن ﻗﺮار ﮔﺮﻓﺘﻪ ﺑﻮد ﺗﻮزﻳﻊ ﺷﻮد .ﺑﻪ ﻣﺤﺾ اﻧﺠﺎم اﻳﻦ ﻛﺎر ،ﻧﺴﺨﻪ ي ﺟﺪﻳﺪ ﺑﺮﻧﺎﻣﻪ در دﺳﺘﺮس ﺗﻤﺎم اﻓـﺮادي ﻛـﻪ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻧﺪ ﻗﺮار ﻣﻲ ﮔﺮﻓﺖ و ﻣﺮﺗﺒﻪ ي ﺑﻌﺪ ﻛﻪ اﻳﻦ اﻓﺮاد ﺑﻪ ﺳﺮور ﻣﺘﺼﻞ ﻣﻲ ﺷﺪﻧﺪ از ﻧﺴﺨﻪ ي ﺟﺪﻳﺪ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻧـﺪ. در ﻣﺪل ﻗﺪﻳﻤﻲ ﻛﻼﻳﻨﺖ/ﺳﺮور ،ﺑﺮاي ﺑﻪ روز رﺳﺎﻧﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻻزم ﺑﻮد ﻛﻪ ﺑﺴﺘﻪ ﻫـﺎي ﺣـﺎوي ﻓﺎﻳﻠﻬـﺎي ﺑـﻪ روز رﺳـﺎﻧﻲ ﺑـﻴﻦ ﺗﻤـﺎﻣﻲ ﻛﻼﻳﻨﺖ ﻫﺎ ﺗﻮزﻳﻊ ﺷﻮد و آﻧﻬﺎ ﻧﻴﺰ اﻳﻦ ﺑﺴﺘﻪ ﻫﺎ را در ﻛﺎﻣﭙﻴﻮﺗﺮ ﺧﻮد ﻧﺼﺐ ﻛﻨﻨﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﻳﻦ ﻛﺎر ﻣﻤﻜﻦ ﺑﻮد ﭼﻨﺪﻳﻦ روز و ﻳـﺎ ﺣﺘـﻲ ﭼﻨﺪﻳﻦ ﻫﻔﺘﻪ زﻣﺎن ﺑﺒﺮد .اﻣﺎ در ﻣﺪل ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب ،ﻣﻲ ﺗﻮان ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ روز ﻛﺮد ﺑﺪون اﻳﻨﻜﻪ ﺣﺘﻲ ﻳﻜﻲ از ﻛﺎرﺑﺮان ﻧﻴﺰ ﻣﺘﻮﺟﻪ اﺧﺘﻼﻟﻲ در ﺑﺮﻧﺎﻣﻪ ﺷﻮد. Update Patches
1
٦٩٢
ﻳﻜﻲ دﻳﮕﺮ از ﻣﺰاﻳﺎي اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﻳﻦ اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ در ﻣﻌﻤﺎري دروﻧﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺗﻐﻴﻴﺮات اﺳﺎﺳﻲ اﻳﺠـﺎد ﻛﻨﻴـﺪ ،ﺑـﺪون اﻳﻨﻜـﻪ در ﻣﻮرد ﻛﺎرﺑﺮاﻧﻲ ﻛﻪ از ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﻧﮕﺮان ﺑﺎﺷﻴﺪ .ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﻣـﻲ ﺧﻮاﻫﻴـﺪ داده ﻫـﺎي ﺑﺮﻧﺎﻣـﻪ را از ﻳـﻚ ﺳـﺮور ﺿﻌﻴﻒ ،ﺑﻪ ﻳﻚ ﺳﺮور ﻗﻮي و ﺟﺪي ﻣﻨﺘﻘﻞ ﻛﻨﻴﺪ .ﻗﻄﻌﺎ ﺳﺮور ﺟﺪﻳﺪ داراي ﻧﺎم ﻣﺨﺼﻮص ﺑﻪ ﺧﻮد اﺳﺖ .در ﻣﺪل ﻛﻼﻳﻨﺖ/ﺳﺮور ﻗﺪﻳﻤﻲ ﻧﺎم ﺳﺮوري ﻛﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺮﻧﺎﻣﻪ در آن ﻗﺮار داﺷﺖ در ﻛﺪ ﻣﻮﺟﻮد در ﺳﻤﺖ ﻛﻼﻳﻨﺖ ﻧﮕﻬﺪاري ﻣﻲ ﺷﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي ﺗﻐﻴﻴﺮ ﺳﺮور ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ،ﻻزم ﺑﻮد ﻛﻪ ﻛﺪ ﻣﻮﺟﻮد در ﺗﻤﺎم ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﺎي ﻛﻼﻳﻨﺖ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ .اﻣﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب ﺑﺮاي ﺗﻐﻴﻴﺮ دادن ﺳﺮور ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﻮرد اﺳﺘﻔﺎده در ﺑﺮﻧﺎﻣﻪ ،ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﺗﻨﻈﻴﻤﺎت ﺳﺮوري ﻛﻪ ﺑﺮﻧﺎﻣﻪ روي آن ﻗﺮار دارد را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﻛـﻪ از ﺳﺮور ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺟﺪﻳﺪ اﺳﺘﻔﺎده ﻛﻨﺪ .در اﻳﻦ ﻣﺪت ﻧﻴﺰ ﺑﺮﻧﺎﻣﻪ و ﺗﻤﺎم ﻛﺎرﺑﺮاﻧﻲ ﻛﻪ در ﺣﺎل اﺳﺘﻔﺎده از آن ﻫﺴﺘﻨﺪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ راﺣﺘـﻲ ﺑﻪ ﻛﺎر ﺧﻮد اداﻣﻪ دﻫﻨﺪ. ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺘﻮﺟﻪ ﺷﺪﻳﺪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب ،ﻫﺮ ﻓﺮدي ﻛﻪ ﻳﻚ اﺗﺼﺎل ﺑﻪ ﺳﺮوري ﻛﻪ ﺑﺮﻧﺎﻣﻪ در آن ﻗﺮار دارد و ﻫﻤﭽﻨﻴﻦ ﻳﻚ ﻣﺮورﮔﺮ وب داﺷﺘﻪ ﺑﺎﺷﺪ ﻣﻲ ﺗﻮاﻧﺪ ﻳﻜﻲ از ﻛﺎرﺑﺮان ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺷﻤﺎر آﻳﺪ و ﺑﻪ آﺧﺮﻳﻦ ﻧﺴﺨﻪ ي ﺑﺮﻧﺎﻣﻪ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷـﺪ .ﺣـﺎل ﻛـﻪ ﺑـﺎ اﺻﻮل ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب آﺷﻨﺎ ﺷﺪﻳﻢ ،ﺑﻬﺘﺮ اﺳﺖ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ ﻛﻪ اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ؟
ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب در ﻣﻘﺎﻳﺴﻪ ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز: در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺑﺮرﺳﻲ ﻣﺰاﻳﺎ و ﻣﻌﺎﻳﺐ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز و ﻧﻴﺰ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ﺧﻮاﻫﻴﻢ ﭘﺮداﺧـﺖ .ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﻣـﻲ ﺗﻮاﻧﻴﺪ ﺗﺸﺨﻴﺺ دﻫﻴﺪ ﻛﻪ در ﭼﻪ ﻣﻮاﻗﻌﻲ ﺑﺎﻳﺪ از ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز و در ﭼﻪ ﻣﻮاﻗﻌﻲ ﺑﺎﻳﺪ از ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺗﺤﺖ وب اﺳـﺘﻔﺎده ﻛـﺮد .در اﻏﻠﺐ ﻣﻮارد ﻗﺒﻞ از ﻧﻮﺷﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﺗﺼﻤﻴﻢ ﺑﮕﻴﺮﻳﺪ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ از ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب اﺳﺘﻔﺎده ﻛﻨﻴﺪ و ﻳـﺎ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي ﺗﺤﺖ وﻳﻨﺪوز را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻬﺘﺮ اﺳﺖ ﻗﺒﻞ از ﻫﺮ ﭼﻴﺰ درك درﺳﺘﻲ در ﻣﻮرد ﻣﺰاﻳﺎ و ﻧﻴﺰ ﻣﻌﺎﻳﺐ اﻳﻦ دو ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﺑﺪﺳﺖ آورﻳﺪ ﺗﺎ ﺑﺪاﻧﻴﺪ ﻛﻪ در ﭼﻪ ﺷﺮاﻳﻄﻲ ﺑﺎﻳﺪ از ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب و در ﭼﻪ ﺷﺮاﻳﻄﻲ ﺑﺎﻳﺪ از ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز اﺳﺘﻔﺎده ﻛﻨﻴﺪ.
ﻣﺰاﻳﺎي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز: ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز داراي ﻣﺰاﻳﺎي ﺧﺎﺻﻲ ﻫﺴﺘﻨﺪ .ﻋﻤﻮﻣﺎً ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﻧﻴﺎز دارﻧﺪ ﺑﻪ ﺳﺮﻋﺖ ﺑﻪ در ﺧﻮاﺳﺖ ﻛـﺎرﺑﺮ ﭘﺎﺳـﺦ دﻫﻨـﺪ، ﺑﺮاي ﻣﺜﺎل ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﺎي ﻓﺮوﺷﮕﺎه ﻫﺎ اﺟﺮا ﻣﻲ ﺷﻮد ،ﻻزم اﺳﺖ ﻛﻪ از ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز ﺑﺎﺷﻨﺪ .ﻫﻤﭽﻨﻴﻦ در ﺑﻴﺸﺘﺮ ﻣﻮارد ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﭘﺮدازش زﻳﺎدي را از ﭘﺮدازﺷﮕﺮ درﺧﻮاﺳـﺖ ﻣـﻲ ﻛﻨﻨـﺪ ،ﻣﺎﻧﻨـﺪ ﺑـﺎزي ﻫـﺎي ﻛـﺎﻣﭙﻴﻮﺗﺮي و ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي ﮔﺮاﻓﻴﻜﻲ ،ﻻزم اﺳﺖ ﻛﻪ ﺑﻪ ﺻﻮرت ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز ﻧﻮﺷﺘﻪ ﺷﻮﻧﺪ. ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﻣﺰﻳﺖ ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز ،داﺷﺘﻦ اﻋﺘﺒﺎر ﻛﺎﻓﻲ در آﻧﻬﺎ اﺳﺖ .ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛـﺎرﺑﺮي ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ ي ﺗﺤـﺖ وﻳﻨﺪوز را ﻧﺼﺐ ﻣﻲ ﻛﻨﺪ ،ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﺑﻪ اﻧﺪازه ي ﻛﺎﻓﻲ ﺑﻪ آن ﺑﺮﻧﺎﻣﻪ اﻋﺘﻤﺎد دارد ،ﺑﻨﺎﺑﺮاﻳﻦ آن ﺑﺮﻧﺎﻣﻪ اﺟﺎزه دارد ﻛﻪ داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺧﻮد را در ﻗﺴﻤﺘﻬﺎي دﻟﺨﻮاه از ﻛﺎﻣﭙﻴﻮﺗﺮ ذﺧﻴﺮه ﻛﺮده و ﻳﺎ ﺑﻪ ﺗﻌﻴﻴﻦ وﺿﻌﻴﺖ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﭙﺮدازد .در اﻳﻦ ﻣـﻮارد ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﺪ ،ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ رﺟﻴﺴﺘﺮي ﺳﻴﺴﺘﻢ و ﻳﺎ ﻓﺎﻳﻠﻬﺎي ﻣﻮﺟﻮد در دﻳﺴﻚ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ .اﻣﺎ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ،اﻋﺘﺒﺎري ﻛﻪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ داده ﻣﻲ ﺷﻮد ﺑﺴﻴﺎر ﻣﺤﺪودﺗﺮ اﺳﺖ. ﻣﺰﻳﺖ دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز ﻛﻨﺘﺮل ﻛﺎﻣﻞ ﺑﺮ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ اﺳﺖ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑـﺎ راﺑـﻂ ﮔﺮاﻓﻴﻜـﻲ زﻳﺒﺎ و ﻗﺪرﺗﻤﻨﺪ ﻃﺮاﺣﻲ ﻛﻨﻴﺪ .در اداﻣﻪ ي ﻓﺼﻞ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺗﻌﺪاد زﻳﺎدي از ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤـﺖ وﻳﻨـﺪوز وﺟﻮد داﺷﺘﻨﺪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب وﺟﻮد ﻧﺪارﻧﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز ﻣﻲ ﺗﻮان راﺑﻂ ﻛﺎرﺑﺮي ﺑﺴﻴﺎر ﺑﻬﺘﺮي را اﻳﺠﺎد ﻛﺮد.
٦٩٣
ﻫﻤﭽﻨﻴﻦ ﺳﺮﻋﺖ ﻋﻤﻞ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز ﻳﻜﻲ دﻳﮕﺮ از ﻣﺰاﻳﺎي آﻧﻬﺎ ﺑﻪ ﺷﻤﺎر ﻣﻲ رود .در اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜـﻪ ﺗﻤـﺎم ﭘﺮدازش در ﺳﻤﺖ ﻛﻼﻳﻨﺖ اﻧﺠﺎم ﻣﻲ ﺷﻮد ،ﺑﻨﺎﺑﺮاﻳﻦ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ داده ﻫﺎ از ﻃﺮﻳﻖ ﺷﺒﻜﻪ ﺑﻪ ﺳﺮور ﻣﻨﺘﻘﻞ ﺷﻮﻧﺪ و ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ از ﺗﺎﺧﻴﺮي ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺑﻪ اﻳﻦ ﻋﻠﺖ در ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﻪ وﺟﻮد آﻳﺪ ﺟﻠﻮﮔﻴﺮي ﻣﻲ ﺷﻮد .ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻛﻼﻳﻨﺖ اﺟﺮا ﻣـﻲ ﺷﻮﻧﺪ ،ﻣﻌﻤﻮﻻ روﻳﺪاد ﻫﺎﻳﻲ ﻛﻪ رخ ﻣﻲ دﻫﺪ ﺳﺮﻳﻌﺘﺮ درﻳﺎﻓﺖ ﺷﺪه و ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ آﻧﻬﺎ اﺟﺮا ﻣﻲ ﺷﻮد.
ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب: ﻣﺰاﻳﺎي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب اﺣﺘﻤﺎﻻ ﺑﻴﺸﺘﺮ از ﻣﺰاﻳﺎي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز ﺑﻪ ﻧﻈﺮ ﻣﻲ رﺳﻨﺪ .اﻣﺎ اﻳﻦ ﻣﻮرد ﻧﺒﺎﻳﺪ ﺑﺎﻋـﺚ ﺷـﻮد ﻛـﻪ ﺗﻤﺎم ﺗﻤﺮﻛﺰ ﺧﻮد را روي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ﻣﺘﻤﺮﻛﺰ ﻛﻨﻴﺪ و ﺑﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﺗﺤﺖ وب ﺗﻤﺎم وﻗﺖ ﺗﺒﺪﻳﻞ ﺷﻮﻳﺪ .ﻫﻤﻴﺸﻪ ﺷﺮاﻳﻄﻲ وﺟﻮد دارﻧﺪ ﻛﻪ اﺳﺘﻔﺎده از ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز در آﻧﻬﺎ راه ﺣﻞ ﺑﻬﺘﺮي اﺳﺖ. ﻣﻬﻤﺘﺮﻳﻦ ﻣﺰﻳﺖ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ﺳﺎدﮔﻲ ﺗﻮزﻳﻊ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﻴﻦ ﻛﺎرﺑﺮان آن اﺳﺖ .ﺑﺮاي ﺗﻮزﻳﻊ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ در ﺑـﻴﻦ ﻛـﺎرﺑﺮان، ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ آن را روي ﻛﺎﻣﭙﻴﻮﺗﺮ ﺳﺮور ﻧﺼﺐ ﻛﻨﻴﺪ ،ﻫﻤﻴﻦ .ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﺑﺮاي اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ،ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ اﻳﺠﺎد ﻛـﺮده و ﺳﭙﺲ آن را ﺑﻪ وﺳﻴﻠﻪ ي CDو ﻳﺎ ﻫﺮ وﺳﻴﻠﻪ ي دﻳﮕﺮي ﺑﻴﻦ ﻛﺎرﺑﺮان ﺗﻮزﻳﻊ ﻛﻨﻴﺪ .ﻫﻤﭽﻨﻴﻦ زﻣﺎﻧﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺗﻐﻴﻴﺮي در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﻨﻴﺪ ،ﻛﺎﻓﻲ اﺳﺖ آن ﺗﻐﻴﻴﺮ را در ﺑﺮﻧﺎﻣﻪ ي ﻣﻮﺟﻮد در ﺳﺮور اﻋﻤﺎل ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺮﺗﺒﻪ ي ﺑﻌﺪ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺨﻮاﻫﺪ از ﺑﺮﻧﺎﻣﻪ ي ﺷـﻤﺎ در ﺳﺮور اﺳﺘﻔﺎده ﻛﻨﺪ ،ﺑﻪ آﺧﺮﻳﻦ ﻧﺴﺨﻪ از ﺑﺮﻧﺎﻣﻪ دﺳﺘﺮﺳﻲ ﺧﻮاﻫﺪ داﺷﺖ. ﻳﻜﻲ دﻳﮕﺮ از ﻣﺰاﻳﺎي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ،ﻛﻨﺘﺮل ﻧﺴﺨﻪ ي ﺑﺮﻧﺎﻣﻪ اﺳﺖ .ﺑﻪ دﻟﻴﻞ اﻳﻨﻜﻪ ﺗﻤﺎم ﻛﺎرﺑﺮان ﺑﺮﻧﺎﻣﻪ از ﻧﺴﺨﻪ ي ﻛﻪ در ﺳـﺮور وﺟﻮد دارد اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ،اﻳﺠﺎد ﺗﻐﻴﻴﺮ در ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﺑﺮﻧﺎﻣﻪ ﺑﺴﻴﺎر ﺳﺎده ﺧﻮاﻫﺪ ﺑﻮد .زﻳﺮا دﻳﮕﺮ ﻻزم ﻧﻴﺴﺖ ﻧﮕﺮان اﻳﻦ ﺑﺎﺷﻴﺪ ﻛﻪ ﺑﻌﻀﻲ از اﻓﺮاد از ﻧﺴﺨﻪ ي 8و ﺑﻌﻀﻲ دﻳﮕﺮ از ﻧﺴﺨﻪ ي 10ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ .زﻳﺮا ﺗﻤﺎم اﻓﺮاد از ﻧﺴﺨﻪ اي از ﺑﺮﻧﺎﻣﻪ ﻛـﻪ در وب ﺳﺮور ﻗﺮار دارد اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ. 1 آﻳﺎ ﺗﺎﻛﻨﻮن واژه ي ﻣﺴﺘﻘﻞ از ﭘﻠﺖ ﻓﺮم را ﺷﻨﻴﺪه اﻳﺪ؟ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب داراي ﭼﻨﻴﻦ ﺧﺎﺻﻴﺘﻲ ﻫﺴﺘﻨﺪ .دﻳﮕﺮ اﻳﻦ ﻣﻮﺿـﻮع ﻛـﻪ ﻛﺎرﺑﺮ از ﭼﻪ ﻧﻮع ﻛﺎﻣﭙﻴﻮﺗﺮي اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ اﻫﻤﻴﺘﻲ ﻧﺪارد .ﻫﻤﻴﻦ ﻛﻪ ﻓﺮدي ﻳﻚ اﺗﺼﺎل ﺑﻪ ﺷﺒﻜﻪ و ﻧﻴﺰ ﻳﻚ ﻣﺮورﮔـﺮ وب داﺷـﺘﻪ ﺑﺎﺷـﺪ، ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﻋﻨﻮان ﻛﺎرﺑﺮ ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ ﻣﺤﺴﻮب ﺷﻮد .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﻬﻢ ﻧﻴﺴﺖ ﻛﻪ ﻛﺎرﺑﺮ از ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ وﻳﻨﺪوز ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑـﻪ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ و ﻳﺎ از ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻟﻴﻨﻮﻛﺲ و ﻳﺎ .... اﻳﻦ ﻣﺰاﻳﺎ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﺎﻋﺚ ﺻﺮﻓﻪ ﺟﻮﻳﻲ ﺑﻴﺶ از ﻣﻴﻠﻴﻮﻧﻬﺎ دﻻر ﻫﺰﻳﻨﻪ ﻧﺴﺒﺖ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨـﺪوز ﺷـﻮﻧﺪ .ﺗﻮاﻧـﺎﻳﻲ اﻳﺠـﺎد ﺳـﺮﻳﻊ ﺗﻐﻴﻴﺮات و ﻧﻴﺰ ﻧﮕﻬﺪاري و ﻛﻨﺘﺮل ﺳﺎده ي ﻛﺪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ،از ﻣﻬﻤﺘﺮﻳﻦ ﻣﺰاﻳﺎي آﻧﻬﺎ ﺑﻪ ﺷﻤﺎر ﻣﻲ روﻧـﺪ .اﻟﺒﺘـﻪ ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ ﮔﻔـﺘﻢ در ﺷﺮاﻳﻄﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ،اﺟﺎزه ي ﻃﺮاﺣﻲ راﺑﻂ ﻛﺎرﺑﺮي ﻣﻨﺎﺳﺐ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻧﻤﻲ دﻫﻨـﺪ .ﺑﻨـﺎﺑﺮاﻳﻦ ﻗﺒـﻞ از ﻃﺮاﺣـﻲ ﻳـﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ در ﻣﻮرد ﻧﻮع آن ﺗﺼﻤﻴﻢ ﺻﺤﻴﺤﻲ ﮔﺮﻓﺘﻪ ﺷﻮد.
اﺟﺰاي اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب: در ﺳﺎده ﺗﺮﻳﻦ ﺣﺎﻟﺖ ،ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب ﺷﺎﻣﻞ ﭼﻨﺪﻳﻦ ﺻﻔﺤﻪ ي وب اﺳﺖ .ﻫﻤﭽﻨﻴﻦ ﺑﺮاي اﻳﻨﻜﻪ ﻛﺎرﺑﺮان ﺑﺘﻮاﻧﻨﺪ ﺑﻪ اﻳﻦ ﺻﻔﺤﺎت دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ ،ﺑﻪ ﻳﻚ ﺳﺮور و ﻳﻚ ﻣﺮورﮔﺮ اﻳﻨﺘﺮﻧﺘﻲ ﻧﻴﺰ ﻧﻴﺎز دارﻳﻢ .ﻣﻌﻤﻮﻻ ﻣﺮورﮔﺮ درﺧﻮاﺳﺘﻲ را اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ ﻛـﻪ داده ﻫـﺎي ﻳﻜﻲ از ﺻﻔﺤﺎت وب ﻣﻮﺟﻮد در ﺳﺮور را درﻳﺎﻓﺖ ﻛﻨﺪ .ﺳﭙﺲ ﺳﺮور داده ﻫﺎﻳﻲ ﻛﻪ ﺑﺎﻳﺪ در آن ﺻﻔﺤﻪ ﺑﺎﺷﻨﺪ را اﻳﺠﺎد ﻛﺮده و ﻧﺘﻴﺠﻪ را ﺑـﻪ ﺳﻤﺖ ﻣﺮورﮔﺮ ﻣﻲ ﻓﺮﺳﺘﺪ .ﺑﻨﺎﺑﺮاﻳﻦ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ داده ﻫﺎي ﺻﻔﺤﻪ ي درﺧﻮاﺳﺘﻲ را در ﭘﻨﺠﺮه ي ﻣﺮورﮔـﺮ ﻣـﺸﺎﻫﺪه ﻛﻨـﺪ .ﺻـﻔﺤﻪ اي
Platform Independence
1
٦٩٤
ﻛﺎرﺑﺮ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﺪ ﻣﻌﻤﻮﻻ ﺷﺎﻣﻞ ﻛﺪ ﻫﺎي CSS ،HTMLو ﻳﺎ اﺳﻜﺮﻳﭙﺖ ﻫﺎي ﺳﻤﺖ ﻛﻼﻳﻨﺖ اﺳﺖ .در اﻳـﻦ ﻗـﺴﻤﺖ ﺳـﻌﻲ ﻣـﻲ ﻛﻨﻴﻢ ﻛﻪ ﺑﺎ ﻫﺮ ﻳﻚ از اﻳﻦ ﻗﺴﻤﺘﻬﺎي ﻣﻮﺟﻮد در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب آﺷﻨﺎ ﺷﻮﻳﻢ.
ﺳﺮور وب: ﺳﺮور وب ،1ﺑﺮﻧﺎﻣﻪ اي اﺳﺖ ﻛﻪ روي ﻳﻜﻲ از ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﺎي ﻗﻮي ﻛﻪ داﺋﻤﺎ ﺑﻪ اﻳﻨﺘﺮﻧﺖ ﻣﺘﺼﻞ اﺳﺖ ﻧﺼﺐ ﻣﻲ ﺷﻮد و ﻣﺴﺌﻮل ﻛﻨﺘﺮل و ﻣﺪﻳﺮﻳﺖ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﺑﻲ اﺳﺖ ﻛﻪ در آن ﻛﺎﻣﭙﻴﻮﺗﺮ ﻗﺮار دارﻧـﺪ .اﻣـﺮوزه ﺳـﺮور ﻫـﺎي وب ﻣﺨﺘﻠﻔـﻲ در ﺑـﺎزار وﺟـﻮد دارﻧـﺪ ﻛـﻪ از ﻣﻌﺮوﻓﺘﺮﻳﻦ آﻧﻬﺎ ﻣﻲ ﺗﻮان IIS2و ﻳﺎ Apacheرا ﻧﺎم ﺑﺮد .در اﻳﻦ ﻛﺘﺎب ﻓﻘﻂ ﺑﺮ روي وب ﺳﺮور IISﺗﻤﺮﻛﺰ ﺧﻮاﻫﻴﻢ ﻛﺮد.
ﻣﺮورﮔﺮ: ﻫﺮ ﻛﺎرﺑﺮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب ﺑﺎﻳﺴﺘﻲ ﻳﻚ ﻣﺮورﮔﺮ داﺷﺘﻪ ﺑﺎﺷﺪ .ﭼﻬﺎر ﻣﺮورﮔـﺮي ﻛـﻪ اﻣـﺮوزه ﻛـﺎرﺑﺮد ﺑﻴـﺸﺘﺮي دارﻧـﺪ ﻋﺒﺎرﺗﻨـﺪ از: Netscape ،Mozilla FireFox ،Microsoft Internet Explorerو .Opera ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺣﺎل ﻃﺮاﺣﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وب ﻋﻤﻮﻣﻲ ﻫﺴﺘﻴﺪ ﺑﺎﻳﺪ در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷـﻴﺪ ﻛـﻪ ﺻـﻔﺤﺎت اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ ﻣﻤﻜـﻦ اﺳـﺖ در ﻣﺮورﮔﺮﻫﺎي ﻣﺨﺘﻠﻒ ﺑﻪ ﺷﻜﻠﻬﺎي ﻣﺘﻔﺎوت ﻧﻤﺎﻳﺶ داده ﺷﻮد .در ﺗﻤﺮﻳﻨﺎت اﻳﻦ ﻛﺘﺎب ﺑﻴﺸﺘﺮ ﺑـﺮ روي ﻣﺮورﮔـﺮ IEﻧـﺴﺨﻪ ي 6ﺗﻤﺮﻛـﺰ ﺧﻮاﻫﻴﻢ ﻛﺮد.
:HTML HTMLﻳﺎ ،HyperText Markup Languageﻛﺪي اﺳﺖ ﻛﻪ ﻗﺎﻟﺐ ﻧﻤﺎﻳﺶ ﺻﻔﺤﺎت وب را ﻣﺸﺨﺺ ﻣـﻲ ﻛﻨـﺪ. ﻛﺪ ﻫﺎي HTMLﻫﻤﺎﻧﻨﺪ ﻳﻚ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﺗﮓ ﻫﺎي ﻣﺨﺘﻠﻒ ﻣﻲ ﺗﻮاﻧﻨﺪ ﻧﺤﻮه ي ﻧﻤﺎﻳﺶ داده ﻫﺎ در ﻳﻚ ﺻﻔﺤﻪ ي وب را ﻣﺸﺨﺺ ﻛﻨﻨﺪ .ﺑﺮاي ﻣﺜﺎل در HTMLﺑﺮاي اﻳﻨﻜﻪ ﻣﺘﻨﻲ را در ﻳﻚ ﺻﻔﺤﻪ ي وب ﺑﻪ ﺻﻮرت Boldﻧﻤﺎﻳﺶ دﻫﻴﻢ، ﻛﺎﻓﻲ اﺳﺖ از ﺗﮓ >
bold in HTML. اﮔﺮ ﻛﺪ HTMLﻗﺒﻞ ﺑﻪ وﺳﻴﻠﻪ ي ﻳﻚ ﻣﺮورﮔﺮ ﻧﻤﺎﻳﺶ داده ﺷﻮد ،ﻣﺘﻨﻲ ﻣﺸﺎﺑﻪ زﻳﺮ دﻳﺪه ﺧﻮاﻫﺪ ﺷﺪ: This is bold in HTML. ﻣﺮورﮔﺮ ﻫﺎ ﺑﺎﻳﺪ ﻛﺪ HTMLرا ﺗﻔﺴﻴﺮ ﻛﺮده و ﻧﺘﻴﺠﻪ ي آن را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ دﻫﻨﺪ و ﻧﻴﺰ ﺑﺮاي دﺳﺘﻮرات ﻣﻮرد اﺳﺘﻔﺎده ي ﺧﻮد ﻧﻴﺰ ﺑﺎﻳﺪ از اﺳﺘﺎﻧﺪارد W3C3اﺳﺘﻔﺎده ﻛﻨﻨﺪ W3C .در ﺳﺎل 1990ﺑﺮاي اﻳﺠﺎد ﭘﺮوﺗﻜﻠﻬﺎي ﻋﻤﻮﻣﻲ ﺑﺮاي اﺳـﺘﻔﺎده در وب ﺑـﻪ وﺟـﻮد آﻣـﺪ .ﺑـﺮاي اﻃﻼﻋﺎت ﺑﻴﺸﺘﺮ در ﻣﻮرد اﻳﻦ ﺳﺎزﻣﺎن ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺳﺎﻳﺖ آن ﺑﻪ آدرس www.w3.orgﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ. 1
Web Server Microsoft Internet Information Server 3 World Wide Web Consortium 2
٦٩٥
ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﻧﻴﺎزي ﺑﻪ داﻧﺴﺘﻦ HTMLﻧﻴﺴﺖ ،اﻣﺎ در ﻃـﻮل ﺗﻤﺮﻳﻨﺎت اﻳﻦ ﻓﺼﻞ ﺑﺎ ﻛﺪ ﻫﺎي آن ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺧﻮاﻫﻴﺪ ﺷﺪ.
VBScriptو :JavaScript ﻳﻜﻲ از ﺑﺨﺸﻬﺎي ﻋﻤﺪه ي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ،اﺳﻜﺮﻳﭙﺖ ﻫﺎي ﺳﻤﺖ ﻛﻼﻳﻨﺖ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﺳﺖ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔـﺘﻢ در ﺑﺮﻧﺎﻣـﻪ ﻫﺎي ﺗﺤﺖ وب ﻟﺰوﻣﻲ ﻧﺪارد ﻛﻪ ﺗﻤﺎم ﭘﺮدازش در ﺳﻤﺖ ﺳﺮور اﻧﺠﺎم ﮔﻴﺮد و ﻣﻲ ﺗﻮان ﺑﻌﻀﻲ از آﻧﻬﺎ را در ﺳﻤﺖ ﻛﻼﻳﻨﺖ اﻧﺠﺎم داد .ﺑﺮاي اﺟﺮاي ﭘﺮدازﺷﻲ در ﺳﻤﺖ ﻛﻼﻳﻨﺖ ﺑﺎﻳﺪ از اﺳﻜﺮﻳﭙﺖ ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .دو زﺑﺎن اﺳﻜﺮﻳﭙﺖ ﻧﻮﻳﺴﻲ ﻋﻤﻮﻣﻲ ﻛﻪ در ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ ﻋﺒﺎرﺗﻨﺪ از VBScriptو .JavaScriptاﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﻛﺪ اﺳﻜﺮﻳﭙﺖ ﻣﻮﺟـﻮد در ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ ﺑﺘﻮاﻧـﺪ ﺗﻮﺳﻂ ﻫﻤﻪ ي ﻣﺮورﮔﺮ ﻫﺎ اﺟﺮا ﺷﻮد ﺑﺎﻳﺪ از زﺑﺎن JavaScriptاﺳﺘﻔﺎده ﻛﻨﻴﻢ VBScript .زﺑـﺎﻧﻲ اﺳـﺖ ﻛـﻪ ﺳـﺎﺧﺘﺎري ﻣﺸﺎﺑﻪ Visual Basicدارد و ﻓﻘﻂ ﺑﻪ وﺳﻴﻠﻪ ي ﻣﺮورﮔﺮ Internet Explorerﺑﻪ ﺻﻮرت ﻛﺎﻣـﻞ ﭘـﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ ﺷﻮد. ﻛﺪ ﻫﺎي اﺳﻜﺮﻳﭙﺘﻲ ﻛﻪ در ﺳﻤﺖ ﻛﻼﻳﻨﺖ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ ،ﺑﻴﺸﺘﺮ ﺑﺮاي ﺗﺎﻳﻴﺪ داده ﻫﺎي وارد ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي ﻛﻼﻳﻨﺖ و ﻳﺎ ﺗﻮﻟﻴﺪ ﻛﺪ ﻫﺎي HTMLدﻳﻨﺎﻣﻴﻚ 1ﺑﻪ ﻛﺎر ﻣﻲ رود .اﺳﻜﺮﻳﭙﺖ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﺗﺎﻳﻴﺪ ﺻﺤﺖ داده ﻫﺎ اﻳﻦ اﻣﻜﺎن را ﺑﻪ ﻣﺎ ﻣﻲ دﻫﻨـﺪ ﻛـﻪ ﺑﺘـﻮاﻧﻴﻢ ﻛـﺎرﺑﺮ را ﻣﺠﺒﻮر ﻛﻨﻴﻢ ﻗﺒﻞ از اداﻣﻪ ،ﻗﺴﻤﺘﻬﺎي ﺧﺎﺻﻲ از ﺻﻔﺤﻪ را ﺗﻜﻤﻴﻞ ﻛﻨﺪ .ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻛﺎرﺑﺮ در ﺣﺎل ﻛﺎﻣﻞ ﻛﺮدن ﻓﺮﻣﻲ در ﺑﺮﻧﺎﻣـﻪ ﺑﺎﺷـﺪ، ﻣﻲ ﺗﻮاﻧﻴﻢ او را ﻣﺠﺒﻮر ﻛﻨﻴﻢ ﻗﺒﻞ از ﻓﺸﺎر داد دﻛﻤﻪ ي ،Submitﻛﺎدرﻫﺎي ﻻزم در ﻓﺮم را ﻛﺎﻣﻞ ﻛﻨﺪ .اﺳـﻜﺮﻳﭙﺖ ﻫـﺎي ﻣﺮﺑـﻮط ﺑـﻪ ﺗﻮﻟﻴﺪ دﻳﻨﺎﻣﻴﻚ ﻛﺪ HTMLﻧﻴﺰ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮﻧﺪ ﻛﺪ HTMLﻣﻮﺟﻮد در ﺻﻔﺤﻪ ،در زﻣﺎن ﻧﻤﺎﻳﺶ داده ﺷﺪن آن ﺗﻐﻴﻴﺮ ﻛﻨﺪ. ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ وﻳﮋﮔﻲ ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ،ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد ﺑﺮاي ﺗﺎﻳﻴـﺪ ﺻـﺤﺖ داده ﻫـﺎي وارد ﺷﺪه در ﻓﺮم و ﻳﺎ ﻛﻨﺘﺮﻟﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﺣﺮﻛﺖ در ﺑﻴﻦ ﺻﻔﺤﺎت ﺑﺮﻧﺎﻣﻪ اﺳﺖ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ را در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻗﺮار داده و ﺑﺪون اﻳﻨﻜﻪ ﺣﺘﻲ ﻳﻚ ﺧﻂ ﻧﻴﺰ اﺳﻜﺮﻳﭙﺖ ﺑﻨﻮﻳﺴﻴﺪ ،ﺻﺤﺖ داده ﻫﺎي ورودي در ﺑﺮﻧﺎﻣﻪ را در ﺳﻤﺖ ﻛﻼﻳﻨﺖ ﺗﻌﻴـﻴﻦ ﻛﻨﻴـﺪ .ﺑـﺎ وﺟﻮد اﻳﻦ در اداﻣﻪ ي اﻳﻦ ﻓﺼﻞ ﻣﻘﺪاري ﻧﻴﺰ ﺑﺎ ﻧﻮﺷﺘﻦ اﺳﻜﺮﻳﭙﺖ ﻫﺎي ﺳﻤﺖ ﻛﻼﻳﻨﺖ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ.
:CSS CSSﻳﺎ Cascading Style Sheetsاﻳﻦ اﺟﺎزه را در ﺑﺮﻧﺎﻣﻪ ﻣﻲ دﻫﻨﺪ ﻛﻪ ﺑﺘﻮاﻧﻴﻢ اﺳـﺘﻴﻞ و ﻗﺎﻟـﺐ ﺻـﻔﺤﺎت را از ﻣﺤﺘﻮﻳﺎت آﻧﻬﺎ ﺟﺪا ﻛﻨﻴﻢ .ﺑﺎ اﺳﺘﻔﺎده از CSSﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﻪ ﺳﺎدﮔﻲ ﻓﻮﻧﺖ ،رﻧﮓ ،ﻧﺤﻮه ي ﻗﺮار ﮔﻴﺮي ﻣﺘﻨﻬﺎ و ﻳﺎ ﺑـﺴﻴﺎري از وﻳﮋﮔﻴﻬـﺎي دﻳﮕﺮ ﻣﺤﺘﻮﻳﺎت ﺻﻔﺤﺎت وب را ﺗﻐﻴﻴﺮ دﻫﻴﻢ .ﺑﻬﺘﺮﻳﻦ ﺧﺎﺻﻴﺖ CSSاﻳﻦ اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آن ﻣﻲ ﺗﻮاﻧﻴﻢ ﻳـﻚ ﻗﺎﻟـﺐ ﻛﻠـﻲ ﺑـﺮاي ﺻﻔﺤﺎت ﻃﺮاﺣﻲ ﻛﺮده و آن را در ﺳﺮﺗﺎﺳﺮ ﺑﺮﻧﺎﻣﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار دﻫﻴﻢ .ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ ﻣﻲ ﺗـﻮاﻧﻴﻢ ﺑـﻪ ﺳـﺎدﮔﻲ ﺑـﺎ ﺗﻐﻴﻴـﺮ ﻛـﺪ CSS ﻣﻮﺟﻮد ،ﻇﺎﻫﺮ ﺗﻤﺎم ﻗﺴﻤﺘﻬﺎي ﺑﺮﻧﺎﻣﻪ را ﺗﻐﻴﻴﺮ دﻫﻴﻢ .در ﻣﻮرد CSSدر اداﻣﻪ ي اﻳﻦ ﻓﺼﻞ ﺑﻴﺸﺘﺮ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد.
:ASP
Dynamic HTML - DHTML
1
٦٩٦
ASPﻳﻚ ﭘﻠﺖ ﻓﺮم و ﻗﺎﻟﺐ ﻛﺎري ﺑﺮاي اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب اﺳﺖ .ﻫﻤﺮاه ﺑﺎ وﻳﮋوال اﺳﺘﻮدﻳﻮ 2005ﻳﻚ ﻧﺴﺨﻪ ي ﺟﺪﻳﺪ از ASPﺑﻪ ﻧﺎم ASP.NET 2.0ﻣﻌﺮﻓﻲ ﺷﺪ .ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻦ ﻧﺴﺨﻪ ي ﺟﺪﻳﺪ ﺑﻪ ﺳﺎدﮔﻲ ﻣﻲ ﺗﻮان ﺳﺎﻳﺘﻬﺎي دﻳﻨﺎﻣﻴﻚ اﻳﺠﺎد ﻛﺮد. در اﻳﻦ ﻗﺴﻤﺖ ﻣﻔﻬﻮم ASPXو ﻳﺎ ﻫﻤﺎن ﻓﺮﻣﻬﺎي ﺗﺤﺖ وب را ﺗﻮﺿﻴﺢ دﻫﻴﻢ.
ﻣﺰاﻳﺎ: ﺑﺮاي اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ،از ﭼﻨﺪ روش ﻣﺨﺘﻠﻒ ﻣﻲ ﺗﻮاﻧﻴﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ .ﻣﻌﺮوﻓﺘﺮﻳﻦ روﺷﻬﺎي اﻧﺠﺎم اﻳﻦ ﻛـﺎر ﻋﺒـﺎرت اﺳـﺖ از اﻳﺠﺎد ﻓﺎﻳﻠﻬﺎﻳﻲ از ﻳﻜﻲ از اﻧﻮاع زﻳﺮ:
) Active Server Pagesﻓﺎﻳﻠﻬﺎي .aspو ﻳﺎ (.aspx ) Java Server Pagesﻓﺎﻳﻠﻬﺎي (.jsp ) ColdFusion Pagesﻓﺎﻳﻠﻬﺎي (.cfm ﻓﺎﻳﻠﻬﺎﻳﻲ ﺣﺎوي دﺳﺘﻮرات HTMLﺛﺎﺑﺖ )ﻓﺎﻳﻠﻬﺎي .htmlو ﻳﺎ (.htm
در اﻳﻦ ﻓﺼﻞ ﺑﺮ روي اﻳﺠﺎد ﻓﺎﻳﻠﻬﺎﻳﻲ از ﻧﻮع .aspxﺗﻤﺮﻛﺰ ﺧﻮاﻫﻴﻢ ﻛﺮد .اﻳﻦ ﻧﻮع ﻓﺎﻳﻠﻬﺎ ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﺑﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ASP.NET 2اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ .اﻟﺒﺘﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻘﺪاري ﻫﻢ از دﺳﺘﻮرات HTMLاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ. ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﻣﺰاﻳﺎي ﻓﺎﻳﻠﻬﺎﻳﻲ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ASP.NET 2اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ ﻧﺴﺒﺖ ﺑﻪ ﻓﺎﻳﻠﻬﺎي دﻳﮕﺮي ﻛﻪ ﻣﻌﺮﻓـﻲ ﺷـﺪ در اﻳﻦ اﺳﺖ ﻛﻪ ،ﺳﺮﻋﺖ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ASP.NET 2ﻧﺴﺒﺖ ﺑﻪ ﻣﻮارد ﻣﺸﺎﺑﻪ آن ﺑﺎﻻﺗﺮ اﺳﺖ .دﻟﻴﻞ اﻳﻦ اﻣﺮ ﻧﻴﺰ ﺑﻪ ﻋﻠﺖ ﻧﺤﻮه ي ﻛﺎﻣﭙﺎﻳﻞ ﺷﺪن دﺳﺘﻮرات آن در ﺳﺮور اﺳﺖ. ﻫﻤﭽﻨﻴﻦ ﺑﺎ اﺳﺘﻔﺎده از اﻣﻜﺎﻧﺎت وﻳﮋوال اﺳﺘﻮدﻳﻮ ) 2005ﻛﻪ ﺗﺎﻛﻨﻮن ﺑﺎ ﺑﻌﻀﻲ از آﻧﻬﺎ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ وﻳﻨﺪوز آﺷﻨﺎ ﺷﺪه اﻳﺪ( ﺑـﺮاي اﻳﺠـﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ،ﺑﺎﻋﺚ اﻓﺰاﻳﺶ ﺳﺮﻋﺖ در ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ و ﻧﻴﺰ اﻓﺰاﻳﺶ ﻛﺎراﻳﻲ آﻧﻬﺎ ﻣﻲ ﺷﻮد .ﺑﺎ اﺳﺘﻔﺎده از ﺗﻮاﺑـﻊ و ﻛﻼﺳـﻬﺎي زﻳﺎدي ﻛﻪ در ﻓﻀﺎي ﻧﺎﻣﻬﺎي ﻣﺨﺘﻠﻒ .NETوﺟﻮد دارﻧﺪ ﻣﻲ ﺗﻮان ﺑﻪ ﺳﺎدﮔﻲ و ﺑﻪ ﺳﺮﻋﺖ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛـﺎرﺑﺮدي ﻗﺪرﺗﻤﻨـﺪي ﻃﺮاﺣـﻲ ﻛﺮد.
ﻓﺎﻳﻠﻬﺎي ﺧﺎص در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب: ﻫﻨﮕﺎﻣﻲ ﻛﻪ در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺨﻮاﻫﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ASP.NET 2ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب اﻳﺠﺎد ﻛﻨﻴـﺪ ،ﻓﺎﻳﻠﻬـﺎي ﻣﺨـﺼﻮص زﻳﺎدي را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد .اﻳﻦ ﻓﺎﻳﻠﻬﺎ از اﻫﻤﻴﺖ زﻳﺎدي ﺑﺮﺧﻮردارﻧﺪ و ﺗﻮﺿﻴﺢ ﻫﺮ ﻳﻚ از آﻧﻬﺎ ﺑﻪ ﻳـﻚ ﻓـﺼﻞ ﺟﺪاﮔﺎﻧـﻪ ﻧﻴـﺎز دارد .دو ﻓﺎﻳﻠﻲ ﻛﻪ در زﻳﺮ ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﻣﻲ ﺷﻮﻳﻢ ،ﻓﺎﻳﻠﻬﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﻳﺠﺎد ﺗﻐﻴﻴﺮاﺗﻲ در آﻧﻬﺎ در ﺳﺮﺗﺎﺳﺮ ﺑﺮﻧﺎﻣﻪ ﺗﺎﺛﻴﺮ ﺑﮕﺬارﻳـﺪ .ﺑـﺮاي اﻃﻼﻋــﺎت ﺑﻴــﺸﺘﺮ در ﻣــﻮرد اﻳــﻦ ﻓﺎﻳﻠﻬــﺎ ﻣــﻲ ﺗﻮاﻧﻴــﺪ ﺑــﻪ ﺳﻴــﺴﺘﻢ راﻫﻨﻤــﺎي وﻳــﮋوال اﺳــﺘﻮدﻳﻮ ) (MSDNو ﻳــﺎ ﺳــﺎﻳﺖ اﻳﻨﺘﺮﻧﺘــﻲ http://msdn2.microsoft.comﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ.
ﻓﺎﻳﻞ :Global.asax
٦٩٧
ﺑﻪ وﺳﻴﻠﻪ ي اﻳـﻦ ﻓﺎﻳـﻞ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﻛـﺪي را در روﻳـﺪادﻫﺎي ﻣﺮﺑـﻮط ﺑـﻪ ﻛـﻞ ﺑﺮﻧﺎﻣـﻪ اﺟـﺮا ﻛﻨﻴـﺪ .ﻣﻬﻤﺘـﺮﻳﻦ اﻳـﻦ روﻳـﺪادﻫﺎ ﺷـﺎﻣﻞ Session_End ،Session_Start ،Application_End ،Application_Startو ﻧﻴـــــﺰ Application_Errorﻣـــــﻲ ﺷـــــﻮﻧﺪ .روﻳـــــﺪادﻫﺎي Application_Startو ﻧﻴـــــﺰ Application_Endزﻣﺎﻧﻲ رخ ﻣﻲ دﻫﻨﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﻪ وﺳﻴﻠﻪ ي IISﺷﺮوع ﺷﻮد و ﻳﺎ ﺑﺴﺘﻪ ﺷﻮد .ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤـﺖ وب زﻣﺎﻧﻲ ﺷﺮوع ﻣﻲ ﺷﻮد ﻛﻪ اوﻟﻴﻦ ﻛﺎرﺑﺮ ﺑﻪ ﺳﺮور ﻣﺘﺼﻞ ﺷﺪه و ﺑﺨﻮاﻫﺪ از آن اﺳﺘﻔﺎده ﻛﻨﺪ .ﻫﻤﭽﻨﻴﻦ اﻳﻦ ﺑﺮﻧﺎﻣﻪ زﻣﺎﻧﻲ ﺑﺴﺘﻪ ﻣﻲ ﺷـﻮد ﻛﻪ ﻫﻴﭻ ﻛﺎرﺑﺮي در ﺣﺎل اﺳﺘﻔﺎده از آن ﻧﺒﺎﺷﺪ .روﻳﺪادﻫﺎي Session_Startو Session_Endزﻣﺎﻧﻲ رخ ﻣﻲ دﻫﻨﺪ ﻛﻪ ﻳﻚ ﻛﺎرﺑﺮ ﺟﺪﻳﺪ ﺑﺨﻮاﻫﺪ از ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﺪ .ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﻛـﺎرﺑﺮ ﺑـﻪ ﺳـﺮور ﻣﺘـﺼﻞ ﺷـﺪه و ﺑﺨﻮاﻫـﺪ از ﺑﺮﻧﺎﻣـﻪ اﺳﺘﻔﺎده ﻛﻨﺪ ،روﻳﺪاد Session_Startو ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺨﻮاﻫﺪ از ﺑﺮﻧﺎﻣـﻪ ﺧـﺎرج ﺷـﻮد روﻳـﺪاد Session_End ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد .ﺑﻨﺎﺑﺮاﻳﻦ اﻳﻦ روﻳﺪادﻫﺎ در ﻃﻮل اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﭼﻨﺪ ﺑﺎر ﻓﺮاﺧﻮاﻧﻲ ﺷﻮﻧﺪ .اﻟﺒﺘﻪ ﻫﻨﮕﺎم اﺳﺘﻔﺎده از اﻳﻦ روﻳﺪاد ﻫﺎ ﺑﺎﻳﺪ در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﺑﺎزاي ﻫﺮ ﻛﺎرﺑﺮ ﻳﻚ ﺑﺎر اﻳﻦ روﻳﺪاد ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد ،ﻣﻤﻜﻦ اﺳﺖ ﻓـﺸﺎر ﻛـﺎري زﻳـﺎدي را ﺑـﺮ ﺳﺮور ﻣﺘﺤﻤﻞ ﻛﻨﺪ .روﻳﺪاد آﺧﺮ ﻧﻴﺰ روﻳﺪاد Application_Errorاﺳﺖ و زﻣﺎﻧﻲ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد ﻛﻪ ﺧﻄﺎﻳﻲ در ﺑﺮﻧﺎﻣﻪ رخ دﻫﺪ ،اﻣﺎ ﻫﻴﭻ ﻗﺴﻤﺘﻲ ﺑﺮاي ﻛﻨﺘﺮل آن در ﺑﺮﻧﺎﻣﻪ وﺟﻮد ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ .ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺻﻮرت ﻣﺘﻤﺮﻛﺰ ،ﺧﻄﺎﻫﺎي ﻋﻤﻮﻣﻲ را ﻛﻨﺘﺮل ﻛﺮده و ﻛﺎرﺑﺮ را ﺑﻪ ﺻﻔﺤﺎت ﺧﻄﺎي ﻣﻨﺎﺳﺐ ﺑﻔﺮﺳﺘﻴﺪ.
ﻓﺎﻳﻞ :web.config ﻓﺎﻳﻞ web.configﻣﺤﻠﻲ ﺑﺮاي ذﺧﻴﺮه ﺗﻨﻈﻴﻤﺎت و ﭘﻴﻜﺮ ﺑﻨﺪي ﺑﺮﻧﺎﻣﻪ اﺳﺖ ﻛﻪ ﺑﻪ ﺻﻮرت ﻳﻚ ﺳﻨﺪ XMLاﻳﺠﺎد ﻣﻲ ﺷـﻮد .در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﻨﻈﻴﻤﺎت ﻣﺮﺑﻮط ﺑﻪ اﻣﻨﻴﺖ ﺑﺮﻧﺎﻣﻪ ،ﺧﻄﺎﻫﺎي اﺣﺘﻤﺎﻟﻲ در ﺑﺮﻧﺎﻣﻪ و ﺑﺴﻴﺎري دﻳﮕﺮ را ﻣـﺸﺨﺺ ﻛﻨﻴـﺪ .در ﻃـﻲ اﻳـﻦ ﻓﺼﻞ ،ﻓﻘﻂ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ اﺗﺼﺎل ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ) (ConnectionStringرا در اﻳﻦ ﻓﺎﻳﻞ ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﻴﻢ.
اﺳﺘﻔﺎده از ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ: ﺑﺮاي ﻃﺮاﺣﻲ ﻓﺮم در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ،ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻣﺤﻴﻂ ﻃﺮاﺣﻲ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻛـﻪ در ﻫﻨﮕـﺎم ﻃﺮاﺣـﻲ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي ﺗﺤـﺖ وﻳﻨﺪوز ﺑﺎ آن آﺷﻨﺎ ﺷﺪﻳﻢ اﺳﺘﻔﺎده ﻛﻨﻴﻢ .ﻫﻨﮕﺎم اﻳﺠﺎد اﻳﻦ ﻓﺮم ﻫﺎ ،ﻣﻲ ﺗﻮاﻧﻴﻢ ﺻـﻔﺤﺎت را ﺑـﻪ ﮔﻮﻧـﻪ اي ﻛـﻪ ﺑـﺎ ﻧـﺎم code- behindﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮﻧﺪ اﻳﺠﺎد ﻛﻨﻴﻢ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺪ HTMLﺗﺸﻜﻴﻞ دﻫﻨﺪه ﻇﺎﻫﺮ ﻓﺮم )ﻛﻪ ﺑﻪ ﺳﻤﺖ ﻛﻼﻳﻨﺖ ﻓﺮﺳـﺘﺎده ﻣـﻲ ﺷﻮد( ،از ﻛﺪي ﻛﻪ ﺑﺮاي ﻋﻤﻠﻜﺮد ﻗﺴﻤﺘﻬﺎي ﻓﺮم ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد )ﻛﻪ ﻣﻌﻤﻮﻻ از زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺎﻧﻨﺪ C#و ﻳﺎ VBاﺳﺘﻔﺎده ﻣـﻲ ﻛﻨﺪ و در ﺳﻤﺖ ﺳﺮور اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ( ﺟﺪا ﺧﻮاﻫﺪ ﺷﺪ .در ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﻳﻚ ﻓﺮم وب ،ﺳﻪ ﻧﻤـﺎي ﻣﺨﺘﻠـﻒ در ﻣﺤـﻴﻂ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ وﺟﻮد دارد Source ،Design :و .Code Viewاﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﻧﻤﺎﻫﺎي Designو Sourceدر ﻓﺎﻳﻠﻲ ﺑﺎ ﭘﺴﻮﻧﺪ .aspxذﺧﻴﺮه ﺷﺪه و ﺷﺎﻣﻞ ﻛﺪ HTMLﺗﺸﻜﻴﻞ دﻫﻨﺪه ي ﻇﺎﻫﺮ ﻓﺮم و ﻳﺎ ﻛﺪ اﺳﻜﺮﻳﭙﺖ ﻻزم ﺑﺮاي ﺗﺎﻳﻴـﺪ ﺻـﺤﺖ داده ﻫـﺎ اﺳﺖ .ﻧﻤﺎي Code Viewﻧﻴﺰ ﻛﺪ اﺻﻠﻲ ﻓﺮم را ﻛﻪ در ﻓﺎﻳﻞ .csذﺧﻴﺮه ﺷﺪه و ﺑﻪ زﺑﺎن C#اﺳﺖ را ﻧﻤـﺎﻳﺶ ﻣـﻲ دﻫـﺪ .اﻳـﻦ ﻓﺎﻳﻞ ﺣﺎوي ﻛﺪ ﻫﺎﻳﻲ از ﻓﺮم اﺳﺖ ﻛﻪ ﺳﻤﺖ ﺳﺮور اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ و ﭘﺮدازش اﺻﻠﻲ ﺻﻔﺤﻪ را ﺑﺮ ﻋﻬﺪه دارﻧﺪ ،ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻛﺪ ﻣﺮﺑـﻮط ﺑﻪ وﻇﻴﻔﻪ ي اﺻﻠﻲ ﻓﺮم در اﻳﻦ ﻓﺎﻳﻞ وارد ﻣﻲ ﺷﻮد.
ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﺟﻌﺒﻪ اﺑﺰار:
٦٩٨
ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻳﺠﺎد ﻛﻨﻴﺪ ،ﻛﻨﺘﺮﻟﻬﺎي ﻋﻤـﻮﻣﻲ ﻛـﻪ ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﻣـﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ در ﺟﻌﺒﻪ اﺑﺰار ﻧﺸﺎن داده ﺧﻮاﻫﻨﺪ ﺷﺪ .اﮔﺮ ﺟﻌﺒﻪ اﺑـﺰار در ﻣﺤـﻴﻂ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ دﻳـﺪه ﻧﻤـﻲ ﺷـﻮد ،ﻛﻠﻴـﺪﻫﺎي Ctrl+Alt+Xرا ﻓﺸﺎر دﻫﻴﺪ .ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻛﻨﺘﺮل ﻫﺎ در ﮔﺮوﻫﺎي ﻣﺨﺘﻠﻔﻲ دﺳﺘﻪ ﺑﻨﺪي ﺷﺪه اﻧﺪ .در ﺷﻜﻞ 1-17ﻧﺎم اﻳﻦ ﮔﺮوه ﻫﺎ ﺑﻪ ﻫﻤﺮاه ﺗﻌﺪادي از ﻛﻨﺘﺮل ﻫﺎ ﻧﻤﺎﻳﺶ داده ﺷﺪه اﺳﺖ .در ﺳﻤﺖ ﭼﭗ ﮔﺮوه ﻫـﺎي ﻛﻨﺘـﺮل ﻫـﺎ دﻳـﺪه ﻣـﻲ ﺷـﻮد ،در وﺳـﻂ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﮔﺮوه Standardو در ﺳﻤﺖ راﺳﺖ ﻧﻴﺰ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﮔﺮوه Dataﻧﻤﺎﻳﺶ داده ﺷﺪه اﻧﺪ.
ﺷﻜﻞ 1-17 ﺟﻌﺒﻪ اﺑﺰار وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﻪ ﻃﻮر ﻛﺎﻣﻞ ﻗﺎﺑﻞ ﺗﻨﻈﻴﻢ اﺳﺖ و ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻣﻨﻮﻳﻲ ﻛﻪ ﺑﺎ ﻛﻠﻴﻚ راﺳﺖ روي آن ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ،ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮرد ﻧﻈﺮ ﺧﻮد را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﺮده و ﻳﺎ از آن ﺣﺬف ﻛﻨﻴﺪ .ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻗﻄﻌﻪ ﻛـﺪي ﻛـﻪ زﻳـﺎد آن را در ﺑﺮﻧﺎﻣـﻪ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ،در ﺟﻌﺒﻪ اﺑﺰار ﻗﺮار داده و ﺳﭙﺲ ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي آن ،ﻗﻄﻌﻪ ﻛﺪ ﻣﻮرد ﻧﻈﺮ را در ﺑﺮﻧﺎﻣـﻪ ﻗـﺮار دﻫﻴـﺪ .ﺑـﺮاي اﺿـﺎﻓﻪ ﻛﺮدن ﻛﺪ ﺑﻪ ﺟﻌﺒﻪ اﺑﺰار ﻣﻲ ﺗﻮاﻧﻴﺪ آن را اﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ ﺑﺎ ﻣﺎوس آن را ﺑﻜﺸﻴﺪ و در ﺟﻌﺒﻪ اﺑﺰار رﻫﺎ ﻛﻨﻴﺪ .ﺳـﭙﺲ روي آن ﻛﻠﻴـﻚ راﺳﺖ ﻛﺮده و Renameرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ ﺑﺘﻮاﻧﻴﺪ ﻧﺎم آن را ﺑﻪ ﻧﺎم ﺑﺎ ﻣﻔﻬﻮم ﺗﺮي ﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺑﺮاي اﺳﺘﻔﺎده از اﻳﻦ ﻛﺪ در ﺑﺮﻧﺎﻣﻪ ﻧﻴـﺰ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﻣﻜﺎن ﻧﻤﺎ را ﺑﻪ ﺟﺎﻳﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻛﺪ در آن ﻗﺮار ﮔﻴﺮد ﺑﺒﺮﻳﺪ و ﺳﭙﺲ ﺑﺎ ﻣﺎوس روي ﻛﺪ ﻣﻮﺟﻮد در ﺟﻌﺒﻪ اﺑـﺰار دو ﺑـﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ .در ﻃﻲ اﻳﻦ ﻓﺼﻞ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در اﻏﻠـﺐ اﻳـﻦ ﮔـﺮوه ﻫـﺎ را ،ﺑـﻪ ﺟـﺰ ﮔـﺮوه ﻫـﺎي ،Crystal Reports Loginو Web Partsدر ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻛﺎر ﺧﻮاﻫﻴﻢ ﺑﺮد.
اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺗﺤﺖ وب: در اﻳﻦ ﻗﺴﻤﺖ اﺑﺘﺪا ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب ﺳﺎده اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﺗﺎ ﺑﺎ ﺟﻨﺒﻪ ﻫﺎي ﻣﺨﺘﻠﻒ اﻳﻦ ﻛﺎر آﺷﻨﺎ ﺷﻮﻳﻢ.
٦٩٩
اﻳﺠﺎد ﻳﻚ ﻓﺮم وب ﺑﺮاي ﭘﺮدازش ﺳﻤﺖ ﺳﺮور و ﺳﻤﺖ ﻛﻼﻳﻨﺖ: ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ،داراي ﻳﻚ ﻓﺮم وب ﺧﻮاﻫـﺪ ﺑـﻮد ﻛـﻪ در آن از ﻛﻨﺘﺮﻟﻬـﺎي HTMLو ﻧﻴـﺰ ﻛﻨﺘﺮﻟﻬﺎي ﺳﻤﺖ ﺳﺮور اﺳﺘﻔﺎده ﺷﺪه اﺳﺖ .ﻛﻨﺘﺮﻟﻬﺎي HTMLﭘﺮدازش را در ﺳﻤﺖ ﻛﻼﻳﻨﺖ اﻧﺠﺎم ﻣﻲ دﻫﻨﺪ ،اﻣﺎ ﻛﻨﺘﺮﻟﻬﺎي ﺳﻤﺖ ﺳﺮور، ﭘﺮدازش ﺧﻮد را ﺑﻪ ﺳﺮور ﻣﻨﺘﻘﻞ ﻣﻲ ﻛﻨﻨﺪ.
اﻣﺘﺤﺎن ﻛﻨﻴﺪ :ﭘﺮدازش ﺳﻤﺖ ﺳﺮور و ﺳﻤﺖ ﻛﻼﻳﻨﺖ (1ﺑﺎ اﻧﺘﺨﺎب ﮔﺰﻳﻨﻪ ي … File New Web Siteﻳﻚ ﭘﺮوژه ي ﺟﺪﻳﺪ را اﻳﺠـﺎد ﻛﻨﻴـﺪ .در ﻛـﺎدر New Web Siteوﻳــﮋوال C#را ﺑــﻪ ﻋﻨــﻮان زﺑــﺎن اﻧﺘﺨــﺎب ﻛــﺮده و از ﻗــﺴﻤﺖ Templatesﻧﻴــﺰ ﮔﺰﻳﻨــﻪ ي ASP.NET Web Siteرا اﻧﺘﺨﺎب ﻛﻨﻴـﺪ .در ﻗـﺴﻤﺖ Locationﮔﺰﻳﻨـﻪ ي File Systemرا اﻧﺘﺨــﺎب ﻛــﺮده و در ﻛــﺎدر ﻣﻘﺎﺑــﻞ آدرس C:\WebSites\Client_ServerProcessingرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .در اﻳﻦ ﺻﻮرت ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي دﻛﻤﻪ ي OKﻳﻚ وب ﺳﺎﻳﺖ در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﺤﻠﻲ اﻳﺠﺎد ﺧﻮاﻫﺪ ﺷﺪ ﻛـﻪ از وب ﺳﺮور دروﻧﻲ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮاي ﺗﺴﺖ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ .ﻓﺮم اﻳﺠﺎد وب ﺳﺎﻳﺖ ﺟﺪﻳﺪ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 2-17ﺧﻮاﻫﺪ ﺑﻮد. (2وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻓﺎﻳﻠﻬﺎ و ﻓﻮﻟﺪر ﻫﺎي ﭘﻴﺶ ﻓﺮض را ﺑﺮاي ﻳﻚ وب ﺳﺎﻳﺖ اﻳﺠﺎد ﺧﻮاﻫﺪ ﻛـﺮد .ﭘﻨﺠـﺮه ي Solution Explorerرا در اﻳﻦ ﭘﺮوژه ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ .اﻳﻦ ﭘﻨﺠﺮه ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 3-17ﺧﻮاﻫﺪ ﺑﻮد .ﻫﻤﭽﻨﻴﻦ ﺻﻔﺤﻪ ي ﻣﺮﺑﻮط ﺑـﻪ ﻓﺎﻳﻞ default.aspxﻧﻴﺰ در ﻣﺤﻴﻂ ﻃﺮاﺣﻲ ﺑﺎز ﺷﺪه اﺳﺖ. (3ﺣــﺎل ﺑﺎﻳــﺪ ﻛﻨﺘﺮﻟﻬــﺎي ﻻزم را ﺑــﻪ ﻓــﺮم اﺿــﺎﻓﻪ ﻛﻨــﻴﻢ .ﺑــﻪ ﺣﺎﻟــﺖ Designﺑﺮوﻳــﺪ و ﻛﻨﺘﺮﻟﻬــﺎي زﻳــﺮ را ﺑــﻪ ﻓــﺮم Default.aspxاﺿﺎﻓﻪ ﻛﻨﻴﺪ )ﺑﺮاي رﻓﺘﻦ ﺑﻪ ﺣﺎﻟﺖ Designدر ﺣﺎﻟﻲ ﻛﻪ ﻓﺎﻳﻞ Default.aspx را ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،ﻳﺎ از ﭘﺎﻳﻴﻦ ﻣﺤﻴﻂ ﻃﺮاﺣﻲ روي ﻋﺒﺎرت Designﻛﻠﻴﻚ ﻛﻨﻴﺪ و ﻳـﺎ ﻛﻠﻴـﺪﻫﺎي Shift+F7را ﻓﺸﺎر دﻫﻴﺪ( .ﻓﻌـﻼ ﻻزم ﻧﻴـﺴﺖ ﻛـﻪ در ﻣـﻮرد ﻣﻜـﺎن ﻛﻨﺘـﺮل ﻫـﺎ ﻧﮕـﺮان ﺑﺎﺷـﻴﺪ ،اﻣـﺎ ﺣﺘﻤـﺎً ﻛﻨﺘـﺮل ﻫـﺎ را از ﮔـﺮوه ﻫـﺎي Standardو HTMLدر ﺟﻌﺒﻪ اﺑﺰار اﻧﺘﺨﺎب ﻛﻨﻴﺪ.
از ﮔﺮوه Standardﻳﻚ ﻛﻨﺘﺮل Buttonو دو ﻛﻨﺘﺮل Labelرا ﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ. از ﮔﺮوه HTMLﻧﻴﺰ ﻳﻚ ﻛﻨﺘﺮل ) Input(Buttonﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ.
٧٠٠
ﺷﻜﻞ 2-17
ﺷﻜﻞ 3-17 (4ﺣﺎل ﺧﺎﺻﻴﺘﻬﺎي ﻛﻨﺘﺮل ﻫﺎ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ 4-17ﺷﻮد.
ﺧﺎﺻﻴﺖ IDاز ﻛﻨﺘﺮل Standard:Buttonرا ﺑﻪ btnServerو ﺧﺎﺻـﻴﺖ Textآن را ﺑﻪ Serverﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺧﺎﺻـــﻴﺖ IDاز ﻛﻨﺘـــﺮل ) HTML:Input(Buttonرا ﺑـــﻪ btnClientو ﺧﺎﺻـــﻴﺖ Valueآن را ﺑﻪ Clientﺗﻐﻴﻴﺮ دﻫﻴﺪ. ﺧﺎﺻـــﻴﺖ IDاز ﻛﻨﺘـــﺮل Standard:Labelﻛـــﻪ در ﺑـــﺎﻻ ﻗـــﺮار ﮔﺮﻓﺘـــﻪ اﺳـــﺖ را ﺑﺮاﺑـــﺮ ﺑـــﺎ lblServerو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Serverﻗﺮار دﻫﻴﺪ. ٧٠١
ﺧﺎﺻــﻴﺖ IDاز ﻛﻨﺘــﺮل Standard:Labelﻛــﻪ در ﭘــﺎﻳﻴﻦ ﻗــﺮار ﮔﺮﻓﺘــﻪ اﺳــﺖ را ﺑﺮاﺑــﺮ ﺑــﺎ lblClientو ﺧﺎﺻﻴﺖ Textآن را ﺑﺮاﺑﺮ ﺑﺎ Clientﻗﺮار دﻫﻴﺪ.
(5ﺣﺎل ﺑﺎ ﭘﺎﻳﻴﻦ ﻧﮕﻪ داﺷﺘﻦ ﻛﻠﻴﺪ ،Ctrlﭼﻬﺎر ﻛﻨﺘﺮل ﻣﻮﺟﻮد در ﻓﺮم را اﻧﺘﺨﺎب ﻛﺮده ،ﺳﭙﺲ ﮔﺰﻳﻨﻪ ي Layout Position Absoluteرا از ﻧﻮر ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴـﺪ ﻣﻜـﺎن ﻛﻨﺘﺮل ﻫﺎ را ﻫﻤﺎﻧﻨﺪ ﻓﺮم ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ .ﺣﺎل ﻣﻮﻗﻌﻴﺖ ﻛﻨﺘﺮل ﻫﺎ در ﻓـﺮم را ﻫﻤﺎﻧﻨـﺪ ﺷـﻜﻞ 4-17ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ .ﺑﻌﺪ از اﺗﻤﺎم اﻳﻦ ﻛﺎر ﻛﻠﻴﺪﻫﺎي Ctrl+F5را ﻓﺸﺎر دﻫﻴﺪ ﺗﺎ ﺑﺮﻧﺎﻣﻪ ﺑﺪون دﻳﺒﺎگ ﻛـﺮدن اﺟـﺮا ﺷـﻮد و ﻓﺮم ﺑﺮﻧﺎﻣﻪ را در ﻣﺮورﮔﺮ ﺧﻮد ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ.
ﺷﻜﻞ 4-17 (6ﻣﺮورﮔﺮ را ﺑﺒﻨﺪﻳﺪ ﺗﺎ ﻣﺠﺪداً ﺑﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮﮔﺮدﻳﺪ .ﺑﺮ روي دﻛﻤﻪ ي btnServerدو ﺑﺎر ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗـﺎ ﻣﺘـﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد Clickاﻳﻦ ﻛﻨﺘﺮل اﻳﺠﺎد ﺷﻮد .ﺑﺴﺘﻪ ﺑﻪ ﺗﻨﻈﻴﻤﺎﺗﻲ ﻛﻪ اﻧﺠﺎم داده اﻳﺪ ،اﻳﻦ ﻣﺘﺪ ﻳﺎ در ﻳﻚ ﻓﺎﻳﻞ ﻛﺪ ﻣﺠﺰا اﻳﺠﺎد ﺧﻮاﻫﺪ ﺷﺪ )روش (Code-Behindو ﻳﺎ در ﻫﻤﺎن ﻓﺎﻳﻞ .aspxو در ﻛﻨﺎر ﻛﺪ ﻫﺎي HTMLﻣﺮﺑـﻮط ﺑـﻪ ﻇﺎﻫﺮ ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻣﻲ ﺷﻮد .ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ روﻳﺪاد اﺿﺎﻓﻪ ﻛﻨﻴﺪ: )protected void btnServer_Click(object sender, EventArgs e { ;"lblServer.Text = "Changed } ﺑﺎ ﻓﺸﺎر دادن ﻛﻠﻴﺪﻫﺎي Ctrl+F5ﻣﺠﺪداً ﺑﺮﻧﺎﻣﻪ را اﺟـﺮا ﻛـﺮده و ﺳـﭙﺲ روي دﻛﻤـﻪ ي Serverﻛﻠﻴـﻚ ﻛﻨﻴـﺪ. ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻣﺘﻦ درون ﻛﻨﺘﺮل Labelﺑﻪ ﻋﺒﺎرت Changedﺗﻐﻴﻴﺮ ﻣﻲ ﻛﻨﺪ.
٧٠٢
(7ﺧﻮب ،ﺣﺎﻻ ﻫﻤﻴﻦ ﻣﺮاﺣﻞ را ﺑﺮاي ﻛﻨﺘﺮل ) HTML:Input(Buttonاﻧﺠﺎم ﻣﻲ دﻫﻴﻢ و ﻫﻤﭽﻨﻴﻦ ﻋﻨﻮان ﻓﺮم را ﻧﻴﺰ ﻋﻮض ﻣﻲ ﻛﻨﻴﻢ .در ﺣﺎﻟﻲ ﻛﻪ در ﺣﺎﻟﺖ Designﻫﺴﺘﻴﺪ ،از ﻛﺎدر ﺑﺎﻻي ﭘﻨﺠﺮه ي Propertiesﮔﺰﻳﻨـﻪ ي Documentرا اﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ ﺧﺎﺻﻴﺖ Titleرا ﺑﻪ My First Pageﺗﻐﻴﻴﺮ دﻫﻴﺪ .ﺣـﺎل ﺑﺎﻳـﺪ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ دﻛﻤﻪ ي Clientرا وارد ﻛﻨﻴﻢ .ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ ﻧﻴﺰ ﮔﻔﺘﻢ ﺑﻪ ﻋﻠـﺖ اﻳﻨﻜـﻪ اﻳـﻦ ﻛـﺪ ﺑﺎﻳـﺪ در ﺳﻤﺖ ﻛﻼﻳﻨﺖ اﻧﺠﺎم ﺷﻮد ،ﭘﺲ ﺑﺎﻳﺪ ﺑﻪ ﻳﻜﻲ از زﻳﺎﻧﻬﺎي اﺳﻜﺮﻳﭙﺖ ﻧﻮﻳﺴﻲ ﻧﻮﺷﺘﻪ ﺷﻮد .در اﻳﻨﺠﺎ از زﻳـﺎن اﺳـﻜﺮﻳﭙﺖ ﻧﻮﻳـﺴﻲ JavaScriptاﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ،زﻳﺮا ﻫﻢ ﺷﺒﺎﻫﺖ زﻳﺎدي ﺑﻪ C#دارد و ﻫﻢ ﺗﻮﺳﻂ ﻫﻤﻪ ي ﻣﺮورﮔـﺮ ﻫـﺎ ﭘـﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ ﺷﻮد .ﭘﺲ ﺑﻪ ﺣﺎﻟـﺖ Sourceﺑﺮوﻳـﺪ و از ﻛـﺎدر ﺳـﻤﺖ ﭼـﭗ ﺑـﺎﻻي ﻗـﺴﻤﺖ ﻛـﺪ ﻧﻮﻳـﺴﻲ )ﻛـﺎدر Client (Object & Eventsﮔﺰﻳﻨـﻪ ي btnClientو از ﻛـﺎدر ﺳـﻤﺖ راﺳـﺖ ﮔﺰﻳﻨـﻪ ي onclickرا اﻧﺘﺨﺎب ﻛﻨﻴﺪ .ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد onclickﻛﻨﺘﺮل btnClientاﻳﺠﺎد ﻣﻲ ﺷﻮد .ﻛﺪ زﻳـﺮ را در اﻳﻦ روﻳﺪاد وارد ﻛﻨﻴﺪ: { )(function btnClient_onclick = document.getElementById("lblClient").innerText ;""Changed = document.getElementById("lblServer").innerText ;""Server } (8ﺑﺮﻧﺎﻣﻪ را ﺑﺎ ﻓﺸﺎر دادن ﻛﻠﻴﺪ Ctrl+F5اﺟﺮا ﻛﺮده و ﻋﻤﻠﻜﺮد ﻫﺮ دو دﻛﻤﻪ را ﺗﺴﺖ ﻛﻨﻴﺪ.
ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟ ﺧﻮب ،ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ﺷﺒﺎﻫﺖ زﻳﺎدي ﺑﻪ اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤـﺖ وﻳﻨـﺪوز دارد .اﻳـﻦ ﻳﻜـﻲ از ﻣﺰاﻳـﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ .NETﺑﻪ ﺷﻤﺎر ﻣﻲ رود ﻛﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﺗﺤﺖ وب ،ﻣﻲ ﺗﻮاﻧﺪ ﺑﺎ ﺧﻮاﻧﺪن ﻣﻄﺎﻟﺐ ﺑﺴﻴﺎر ﻛﻤﻲ ﺑﻪ ﺑﺮﻧﺎﻣـﻪ ﻧﻮﻳـﺴﻲ ﺗﺤﺖ وﻳﻨﺪوز ﺑﭙﺮدازد و ﻳﺎ ﺑﺮ ﻋﻜﺲ. 1 ﺑﻬﺘﺮ اﺳﺖ ﺑﺮاي ﺑﺮرﺳﻲ ﺑﺮﻧﺎﻣﻪ اﺑﺘﺪا از ﻛﺪ HTMLﻧﻮﺷﺘﻪ ﺷﺪه ﺑﺮاي آن ﺷﺮوع ﻛﻨﻴﻢ .اوﻟﻴﻦ ﺧﻂ اﻳﻦ ﻛـﺪ ،راﻫﻨﻤـﺎي Pageﻧﺎﻣﻴـﺪه ﻣﻲ ﺷﻮد: "<%@ Page Language="C#" AutoEventWireup="true >CodeFile="Default.aspx.cs" Inherits="_Default" % ﺑﺮ ﺣﺴﺐ ﺗﻨﻈﻴﻤﺎﺗﻲ ﻛﻪ ﺑﺮاي ﻧﻮﺷﺘﻦ ﺑﺮﻧﺎﻣﻪ اﻧﺠﺎم ﻣﻲ دﻫﻴﺪ ،وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺧﺼﻴﺼﻪ ﻫﺎي ﻣﺨﺘﻠﻔﻲ را در اﻳﻦ ﻗﺴﻤﺖ ﺗﻨﻈﻴﻢ ﻣـﻲ ﻛﻨـﺪ. راﻫﻨﻤﺎي Pageﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ،داراي ﺑﻴﺶ از 30ﺧﺼﻴﺼﻪ ي ﻣﺨﺘﻠﻒ اﺳﺖ ﻛﻪ ﻣﻲ ﺗـﻮان آﻧﻬـﺎ را ﺑـﺎ ﻣﻘـﺎدﻳﺮ ﮔﻮﻧﺎﮔﻮﻧﻲ ﺗﻨﻈﻴﻢ ﻛﺮد .در اﻳﻦ ﻗﺴﻤﺖ ﻓﻘﻂ درﺑﺎره ي ﺧﺼﻴﺼﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض در اﻳﻦ راﻫﻨﻤﺎ وﺟﻮد دارد ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛــﺮد .ﺑــﺮاي ﻣﻄﺎﻟﻌــﻪ در ﻣــﻮرد ﺑﻘﻴــﻪ ي اﻳــﻦ ﻣــﻮارد ﻣــﻲ ﺗﻮاﻧﻴــﺪ در ﺳﻴــﺴﺘﻢ راﻫﻨﻤــﺎي وﻳــﮋوال اﺳــﺘﻮدﻳﻮ ) (MSDNو ﻳــﺎ در ﺳــﺎﻳﺖ http://msdn2.microsoft.comﻋﺒﺎرت @Pageرا ﺟﺴﺘﺠﻮ ﻛﻨﻴﺪ. اوﻟﻴﻦ ﺧﺼﻴﺼﻪ اي ﻛﻪ در راﻫﻨﻤﺎي @Pageوﺟﻮد دارد ،ﺧﺼﻴﺼﻪ ي Languageاﺳﺖ .در اﻳﻦ ﻗﺴﻤﺖ زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻛـﻪ ﻛﺪ ﻫﺎي ﺳﻤﺖ ﺳﺮور اﻳﻦ ﻓﺎﻳﻞ ﺑﺎ آن ﻧﻮﺷﺘﻪ ﺷﺪه اﻧﺪ را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﺪ .دوﻣﻴﻦ ﺧﺼﻴـﺼﻪ AutoEventWireupاﺳـﺖ و Page Directive
1
٧٠٣
ﻣﻘﺪار ﭘﻴﺶ ﻓﺮض آن ﺑﺮاﺑﺮ ﺑﺎ Falseاﺳﺖ .ﻣﻘﺪار ﭘﻴﺶ ﻓﺮض اﻳﻦ ﺧﺼﻴﺼﻪ ﺑﺮاﺑﺮ ﺑﺎ trueاﺳﺖ و اﮔﺮ آن را ﺑﺮاﺑـﺮ ﺑـﺎ false ﻗﺮار ﻧﺪﻫﻴﺪ ،ﻣﺘﺪﻫﺎي ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ﻫﺎي ﺧﺎﺻﻲ ﻣﻤﻜﻦ اﺳﺖ دو ﺑﺎر ﻓﺮاﺧﻮاﻧﻲ ﺷﻮﻧﺪ .ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﺗﻮﺻﻴﻪ ﻣﻲ ﻛﻨـﺪ ﻛـﻪ ﻫﻤـﻮاره اﻳـﻦ ﺧﺼﻴﺼﻪ را ﺑﺮاﺑﺮ ﺑﺎ trueﻗﺮار دﻫﻴﺪ .ﺧﺼﻴﺼﻪ ي ﺑﻌﺪي CodeFileاﺳﺖ .اﮔﺮ اﻳﻦ ﻓﺎﻳﻞ ﺑﻪ ﺻـﻮرت Code-Behind ﻧﻮﺷﺘﻪ ﺷﻮد ،ﻳﻌﻨﻲ ﻛﺪ ﻫﺎﻳﻲ از آن ﻛﻪ ﺑﺎﻳﺪ در ﺳﻤﺖ ﺳﺮور اﺟﺮا ﺷﻮﻧﺪ در ﻳﻚ ﻓﺎﻳﻞ ﺟﺪاﮔﺎﻧـﻪ ذﺧﻴـﺮه ﺷـﺪه اﺳـﺖ .در اﻳـﻦ ﺻـﻮرت اﻳـﻦ ﺧﺼﻴﺼﻪ ﻧﺎم ﻓﺎﻳﻞ ﺣﺎوي ﻛﺪ ﺳﻤﺖ ﺳﺮور را ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ .آﺧﺮﻳﻦ ﺧﺼﻴﺼﻪ ﻧﻴﺰ ،ﺧﺼﻴﺼﻪ ي Inheritsاﺳﺖ و ﺷـﺎﻣﻞ ﻧـﺎم ﻛﻼﺳﻲ اﺳﺖ ﻛﻪ ﺻﻔﺤﻪ ي وب ﺟﺎري از آن ﻣﺸﺘﻖ ﻣﻲ ﺷﻮد. ﺧﻂ ﺑﻌﺪي ،ﺧﻂ !DOCTYPEاﺳﺖ .اﻳﻦ ﺧﻂ ﺑﻪ ﻣﺮورﮔﺮ IEﻧﺴﺨﻪ ي 6و ﺑﺎﻻﺗﺮ اﻋﻼم ﻣﻲ ﻛﻨﺪ ﻛﻪ اﻳـﻦ ﻓﺎﻳـﻞ ﺑـﺎ XHTML 1.1ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي W3Cﺑﺮاي زﺑﺎن اﻧﮕﻠﻴﺴﻲ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﻫﻤﺎﻫﻨﮕﻲ دارد. "]] // >"