Learnvisualc#farsi

  • Uploaded by: Ali Behzadian Nejad
  • 0
  • 0
  • April 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Learnvisualc#farsi as PDF for free.

More details

  • Words: 309,918
  • Pages: 951
‫ﺑﺴﻢ اﷲ اﻟﺮﺣﻤﻦ اﻟﺮﺣﻴﻢ‬

‫آﻣﻮزش وﻳﮋوال ‪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‬ﺑﺮاي زﺑﺎن اﻧﮕﻠﻴﺴﻲ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﻫﻤﺎﻫﻨﮕﻲ دارد‪.‬‬ ‫‪"‪transitional.dtd‬‬ ‫ﺧﻂ ﺑﻌﺪي اوﻟﻴﻦ ﺧﻄﻲ اﺳﺖ ﻛﻪ ﺷﺎﻣﻞ دﺳﺘﻮر ‪ HTML‬اﺳﺖ‪ .‬در ﺑﻴﺸﺘﺮ ﻣﻮاﻗﻊ ﺧﺼﻴﺼﻪ ي ﺧﺎﺻﻲ درون اﻳﻦ دﺳﺘﻮر ﺗﻨﻈﻴﻢ ﻧﻤﻲ ﺷﻮد‪ .‬در‬ ‫اﻳﻨﺠﺎ وﻳﮋوال اﺳﺘﻮدﻳﻮ درون اﻳﻦ دﺳﺘﻮر ﺧﺼﻴﺼﻪ اي را ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﻨﺪ ﺗﺎ ﻣﺸﺨﺺ ﻛﻨﺪ ﻛﻪ ﻓﻀﺎي ﻧﺎم ﻣﺮﺑﻮط ﺑﻪ ﺗﮕﻬﺎي اﻳﺠﺎد ﺷـﺪه ﺑـﻪ‬ ‫وﺳﻴﻠﻪ ي ﻛﺎرﺑﺮ ﺑﺮاﺑﺮ ﺑﺎ "‪ "http://www.w3.org/1999/xhtml‬اﺳﺖ‪ .‬اﮔﺮ ﺑﻪ اﻳﻦ ﺳﺎﻳﺖ ﺑﺮوﻳﺪ‪ ،‬ﻓـﻀﺎي ﻧـﺎم‬ ‫ﺗﻌﺮﻳﻒ ﺷﺪه ي ‪ XHTML‬ﺑﻪ وﺳﻴﻠﻪ ي ‪ W3C‬را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد‪.‬‬ ‫> "‪]] ‪//‬‬ ‫>‪‪‪"‪
‪top: 70px" id="btnServer" /‬‬ ‫ﺑﻨﺎﺑﺮاﻳﻦ ﻣﺮورﮔﺮ ﻣﺘﻮﺟﻪ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﻨﺘﺮل ‪ ،btnServer‬ﻳﻚ دﻛﻤـﻪ از ﻧـﻮع ‪ Submit‬اﺳـﺖ‪ .‬در ﻛـﺪ ‪ HTML‬وﻇﻴﻔـﻪ ي‬ ‫دﻛﻤﻪ ي ‪ Submit‬اﻳﻦ اﺳﺖ ﻛﻪ اﻃﻼﻋﺎت ﻣﻮﺟﻮد در ﻓـﺮم را ﺑـﻪ ﺳـﻤﺖ ﺳـﺮور وب ﺑﺮﮔﺮداﻧـﺪ‪ .‬اﻃﻼﻋـﺎت ﻣـﺸﺨﺺ ﺷـﺪه در ﺗـﮓ‬ ‫‪ Form‬ﻧﻴﺰ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ اﻳﻦ ﻓﺮم ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ‪ post‬اﻃﻼﻋﺎت ﺧﻮد را ﺑﻪ ﺻـﻔﺤﻪ ي ‪Default.aspx‬‬ ‫در ﺳﺮور ﺑﻔﺮﺳﺘﺪ‪.‬‬ ‫ﺧﻮب‪ ،‬ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ ﺑﻪ اداﻣﻪ ي ﻛﺪ ﻣﻮﺟﻮد در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﭙﺮدازﻳﻢ‪ .‬ﻗﺴﻤﺖ آﺧﺮ ﻛﺪي ﻛﻪ در ﻧﻤﺎي ‪ Source‬دﻳـﺪه ﻣـﻲ ﺷـﻮد‪،‬‬ ‫ﺗﮓ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ در ﻓﺮم ﻗﺮار دادﻳﻢ‪:‬‬ ‫>‪‪Text="Server" /‬‬ ‫‪‪top: 79px" Text="Server">‪top: 116px" Text="Client">
‫‪٧٠٦‬‬

‫>‪
‪‪‪" +‬‬ ‫‪"Your email address is " +‬‬ ‫;‪this.txtEmail.Text‬‬ ‫}‬ ‫}‬ ‫‪ (6‬ﺣﺎل ﺑﺎﻳﺪ از ﺻﺤﺖ داده ﻫﺎي ورودي ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺎرﺑﺮ ﻣﻄﻤﺌﻦ ﺷﻮﻳﻢ‪ .‬در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﺑﺮاي اﻳﻦ ﻛﺎر وﺟﻮد‬ ‫دارد‪ .‬ﺑﺮاي ﻣﺸﺎﻫﺪه ي اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﺑﺎ ﻓﺸﺎر دادن ﻣﺠﺪد ﻛﻠﻴﺪ ‪ F7‬ﺑﻪ ﻧﻤﺎي ‪ Design‬ﺑﺮﮔﺮدﻳﺪ و ﺳﭙﺲ در ﺟﻌﺒـﻪ اﺑـﺰار‬ ‫روي ﮔﺮوه ‪ Validation‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻗﺮار دارﻧﺪ ﺑـﺮاي ﻛﻨﺘـﺮل ﺻـﺤﺖ داده ﻫـﺎي‬ ‫وارد ﺷــﺪه ﺑــﻪ وﺳــﻴﻠﻪ ي ﻛــﺎرﺑﺮ در ﻧﻈــﺮ ﮔﺮﻓﺘــﻪ ﺷــﺪه اﻧــﺪ‪ .‬ﺑــﺎ اﺳــﺘﻔﺎده از اﻳــﻦ ﻗــﺴﻤﺖ از ﺟﻌﺒــﻪ اﺑــﺰار‪ ،‬دو ﻛﻨﺘــﺮل‬ ‫‪ RequiredFieldValidator‬و ﻳﻚ ﻛﻨﺘـﺮل ‪ ValidationSummary‬را ﺑـﻪ ﻓـﺮم اﺿـﺎﻓﻪ‬ ‫ﻛﺮده و ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻣﻨﻮي ‪ Layout‬ﻧﺤﻮه ي ﻗﺮار ﮔﻴﺮي آﻧﻬﺎ را در ﻓﺮم ﺑﻪ ‪ Absolute‬ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪.‬‬ ‫ﺧﺎﺻﻴﺖ ﻛﻨﺘﺮل ‪ RequiredFieldValidator‬اول را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪.‬‬ ‫ ﺧﺎﺻﻴﺖ ‪ ID‬را ﺑﺮاﺑﺮ ﺑﺎ ‪ rfvFirstName‬ﻗﺮار دﻫﻴﺪ‪.‬‬ ‫ ﺧﺎﺻﻴﺖ ‪ Display‬را ﺑﻪ ‪ None‬ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪.‬‬ ‫ ﺧﺎﺻﻴﺖ ‪ ControlToValidate‬را ﺑﻪ ‪ txtFirstName‬ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪.‬‬ ‫ ﺧﺎﺻﻴﺖ ‪ ErrorMessage‬را ﺑﻪ ‪ First name is required‬ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪.‬‬ ‫ﺧﺎﺻﻴﺖ دوﻣﻴﻦ ﻛﻨﺘﺮل ‪ RequiredFieldValidator‬را ﻧﻴﺰ ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪:‬‬ ‫ ﺧﺎﺻﻴﺖ ‪ ID‬را ﺑﻪ ‪ rfvEmail‬ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪.‬‬ ‫ ﺧﺎﺻﻴﺖ ‪ Display‬را ﺑﻪ ‪ None‬ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪.‬‬ ‫ ﺧﺎﺻﻴﺖ ‪ ControlToValidate‬را ﺑﻪ ‪ txtLastName‬ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪.‬‬ ‫ ﺧﺎﺻﻴﺖ ‪ ErrorMessage‬را ﺑﻪ ‪ Email is required‬ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪.‬‬ ‫ﺧﺎﺻﻴﺖ ‪ ID‬ﻛﻨﺘﺮل ‪ ValidationSummary‬را ﻧﻴﺰ ﺑـﻪ ‪ ValidationSummary‬ﺗﻐﻴﻴـﺮ دﻫﻴـﺪ‪.‬‬ ‫ﻓﺮم ﺗﻜﻤﻴﻞ ﺷﺪه ي ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ ‪ 7-17‬ﺑﺎﺷﺪ‪.‬‬

‫‪٧١٠‬‬

‫ﺷﻜﻞ ‪7-17‬‬ ‫‪ (7‬ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺑـﺪون اﻳﻨﻜـﻪ در ﻛﺎدرﻫـﺎي ‪ FirstName‬و ‪ Email‬ﻋﺒـﺎرﺗﻲ را وارد ﻛﻨﻴـﺪ‪ ،‬روي دﻛﻤـﻪ ي‬ ‫‪ Complete‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﭘﻴﻐﺎم ﺧﻄﺎﻳﻲ ﻣﺸﺎﺑﻪ ﺷﻜﻞ ‪ 8-17‬ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬ ‫ﻧﻜﺘﻪ‪ :‬اﻳﻦ ﻣﺜﺎل ﻧﺸﺎن ﻣﻲ دﻫﺪ ﻛﻪ ﺗﺎﻳﻴﺪ ﺻﺤﺖ داده ﻫﺎي ورودي در ‪ ASP.NET 2‬ﭼﻘﺪر ﺳﺎده و ﺳﺮﻳﻊ ﻣﻲ ﺗﻮاﻧـﺪ اﻧﺠـﺎم ﺷـﻮد‪.‬‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ در ﮔﺮوه ‪ Validation‬در ﺟﻌﺒﻪ اﺑﺰار ﻛﻨﺘﺮﻟﻬﺎي دﻳﮕﺮي ﻧﻴﺰ ﺑﺮاي اﻳﻦ ﻛﺎر وﺟﻮد دارﻧﺪ‪ .‬ﺑـﺮاي ﻣﺜـﺎل‬ ‫ﻛﻨﺘﺮل ‪ CompareValidator‬ﺑﺮاي ﺑﺮرﺳﻲ اﻳﻦ ﻣﻮرد اﺳﺖ ﻛﻪ ﻋﺒﺎرت وارد ﺷﺪه در ﻳﻚ ﻛﺎدر ﺣﺘﻤﺎً ﺑﺎ ﻋﺒﺎرت ﺧﺎﺻﻲ ﺑﺮاﺑـﺮ‬ ‫ﺑﺎﺷﺪ‪ .‬اﻳﻦ ﻋﺒﺎرت ﺧﺎص ﻣﻲ ﺗﻮاﻧﺪ ﺷﺎﻣﻞ ﻳﻚ ﻣﻘﺪار ﺛﺎﺑﺖ‪ ،‬ﻣﻘﺪار وارد ﺷﺪه در ﻳﻚ ﻛﻨﺘﺮل دﻳﮕﺮ و ﻳﺎ ﺣﺘﻲ ﻣﻘﺪاري از ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ‬ ‫ﺑﺎﺷﺪ‪ .‬ﻛﻨﺘﺮل ‪ RangeValidator‬ﺑﺮاي ﺑﺮرﺳﻲ اﻳﻦ ﻣﻮرد ﺑﻪ ﻛﺎر ﻣﻲ رود ﻛﻪ داده ي وارد ﺷﺪه ﺣﺘﻤﺎً در ﺑﺎزه ي ﺧﺎﺻﻲ ﺑﺎﺷﺪ‪.‬‬ ‫ﺑﺮاي ﻣﺜﺎل ﺣﺘﻤﺎً ﺳﻨﻲ ﻛﻪ ﻛﺎرﺑﺮ وارد ﻛﺮده اﺳﺖ ﺑﻴﻦ ‪ 18‬ﺗﺎ ‪ 35‬ﺑﺎﺷﺪ‪.‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﺑﺪون اﻳﻨﻜﻪ ﻛﺪي را وارد ﻛﻨﻴﺪ‪ ،‬ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻛﺎرﺑﺮ ﺑﺨﻮاﻫﻴﺪ ﻛﻪ ﻗﺒﻞ از ارﺳﺎل ﻓﺮم ﺑﻪ ﺳﺮور ﻛﺎدرﻫﺎي ﻻزم را ﺗﻜﻤﻴﻞ ﻛﻨﺪ‪.‬‬ ‫ﺑﺮاي اﻃﻤﻴﻨﺎن از اﻳﻦ ﻛﻪ ﻛﺎرﺑﺮ ﻛﺎدري را ﺗﻜﻤﻴﻞ ﻛﺮده اﺳﺖ ﻳﺎ ﻧﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻛﻨﺘﺮل ‪RequiredFieldValidator‬‬ ‫اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ .‬ﺗﻨﻈﻴﻢ اﻳﻦ ﻛﻨﺘﺮل ﻫﻢ ﺑﺴﻴﺎر ﺳﺎده اﺳﺖ‪ .‬ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﺧﺎﺻﻴﺖ ‪ ErrorMessage‬آن را ﺑﺮاﺑﺮ ﺑﺎ ﭘﻴﻐـﺎم ﺧﻄـﺎﻳﻲ‬ ‫ﻗﺮار دﻫﻴﻢ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻧﻤﺎﻳﺶ داده ﺷﻮد‪ .‬اﻳﻦ ﭘﻴﻐﺎم ﺧﻄﺎ در دو ﻣﻜﺎن ﻣﺨﺘﻠﻒ ﻣﻲ ﺗﻮاﻧﺪ ﻧﻤﺎﻳﺶ داده ﺷﻮد‪ :‬ﻳﻜﻲ در ﻫﻤﺎن ﻣﻜﺎﻧﻲ ﻛـﻪ‬ ‫ﻛﻨﺘﺮل ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ و دﻳﮕﺮي در ﻛﻨﺘﺮل ‪ .ValidationSummary‬در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎ ﺗﻨﻈﻴﻢ ﺧﺎﺻﻴﺖ ‪ Display‬ﺑﺎ‬ ‫‪ None‬از ﻧﻤﺎﻳﺶ داده ﺷﺪن ﭘﻴﻐﺎم ﺧﻄﺎ ﺑﻪ وﺳﻴﻠﻪ ي ‪ RequiredFieldValidator‬ﺟﻠﻮﮔﻴﺮي ﻛﺮده و ﻓﻘـﻂ آن را‬

‫‪٧١١‬‬

‫در ‪ ValidationSummary‬ﻧﻤﺎﻳﺶ داده اﻳﻢ‪ .‬ﺧﺎﺻﻴﺖ ‪ ControlToValidate‬ﻧﻴﺰ ﺑﺎﻳﺪ ﺑﺮاﺑﺮ ﺑﺎ ﻧﺎم ﻛﻨﺘﺮﻟـﻲ‬ ‫ﻗﺮار ﮔﻴﺮد ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺣﺘﻤﺎً ﻛﺎرﺑﺮ آن را ﻛﺎﻣﻞ ﻛﻨﺪ‪.‬‬

‫ﺷﻜﻞ ‪8-17‬‬ ‫"‪"‪top: 251px‬‬ ‫>‪‪top: 251px" runat="server" /‬‬ ‫ﺗﻨﻬﺎ ﻛﺪي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ وارد ﻛـﺮدﻳﻢ‪ ،‬ﻛـﺪ ﻣﺮﺑـﻮط ﺑـﻪ ﻣﺘـﺪ ‪ Form_Load‬ﺑـﻮد‪ .‬در اﻳـﻦ ﻛـﺪ اﺑﺘـﺪا ﺑـﺎ اﺳـﺘﻔﺎده از ﺧﺎﺻـﻴﺖ‬ ‫‪ PostBack‬ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ آﻳﺎ ﻓﺮم ﺑﺮاي اوﻟﻴﻦ ﺑﺎر اﺳﺖ ﻛﻪ در اﻳﻦ ﻣﺮورﮔﺮ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﻳـﺎ ﻧـﻪ؟ ﻣﺘـﺪ ‪ Load‬در‬ ‫ﻓﺮم ﻫﺎي وب ﺑﺎ ﻓﺮﻣﻬﺎي وﻳﻨﺪوزي از ﭼﻨﺪ ﺟﻬﺖ ﺗﻔﺎوت دارد‪ .‬ﻳﻜﻲ از اﻳﻦ ﻣﻮارد اﻳﻦ اﺳﺖ ﻛﻪ اﻳﻦ ﻣﺘﺪ در ﻓﺮﻣﻬﺎي وب ﻣﻌﻤﻮﻻ ﭼﻨﺪﻳﻦ ﺑﺎر‬ ‫ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد‪ ،‬در ﺻﻮرﺗﻲ ﻛﻪ در ﻓﺮﻣﻬﺎي وﻳﻨﺪوزي اﻳﻦ ﻣﺘﺪ ﻓﻘﻂ ﻳﻚ ﺑﺎر ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﺪ و آن ﻧﻴﺰ زﻣﺎﻧﻲ ﺑـﻮد ﻛـﻪ ﻓـﺮم در ﺣـﺎل‬ ‫‪ Load‬ﺷﺪن در ﺣﺎﻓﻈﻪ ﺑﻮد‪.‬‬ ‫در ﻓﺮﻣﻬﺎي وب ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ ﺗﻘﺎﺿﺎي ﻣﺸﺎﻫﺪه ي ﻓﺮﻣﻲ را ﻣﻲ ﻛﻨﺪ‪ ،‬ﻣﺘﺪ ‪ Load‬ﻓﺮم ﺑﺮاي اوﻟﻴﻦ ﺑـﺎر ﻓﺮاﺧـﻮاﻧﻲ ﺷـﺪه و ﻓـﺮم در‬ ‫ﻣﺮورﮔﺮ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد‪ .‬ﺳﭙﺲ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ ﺑﻪ ﻫﺮ روﺷﻲ )ﺑﺮاي ﻣﺜﺎل ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي ﻳﻜﻲ از دﻛﻤﻪ ﻫـﺎي ﻓـﺮم(‪،‬‬ ‫ﻓﺮم را ﺑﻪ ﺳﻤﺖ ﺳﺮور ﻓﺮﺳﺘﺎد‪ ،‬ﻣﺘﺪ ‪ Load‬ﻣﺠﺪداً ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد‪ .‬اﻣﺎ اﻳﻦ ﺑـﺎر ﺧﺎﺻـﻴﺖ ‪ IsPostBack‬ﺑﺮاﺑـﺮ ﺑـﺎ ‪True‬‬ ‫ﺷــﺪه اﺳــﺖ‪ .‬ﺑﻨــﺎﺑﺮاﻳﻦ اﮔــﺮ ﺑﺨــﻮاﻫﻴﻢ ﻋﻤﻠــﻲ ﻓﻘــﻂ در اوﻟــﻴﻦ ﺑــﺎر رخ دادن روﻳــﺪاد ‪ Load‬اﺟــﺮا ﺷــﻮد‪ ،‬ﻣــﻲ ﺗــﻮاﻧﻴﻢ آن را در ﺷــﺮط‬ ‫‪ IsPostBack == False‬ﻗﺮار دﻫﻴﻢ‪ .‬اﻣﺎ در اﻳﻨﺠﺎ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻫﻨﮕﺎﻣﻲ ﻣﺘﻦ داﺧﻞ ﻛﻨﺘﺮل ‪ lblWelcome‬ﺗﻐﻴﻴﺮ‬ ‫ﻛﻨﺪ ﻛﻪ ﻛﺎرﺑﺮ روي دﻛﻤﻪ ي ‪ Complete‬ﻛﻠﻴﻚ ﻛﺮده ﺑﺎﺷﺪ‪ .‬ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻣﻲ ﺧﻮاﻫﻴﻢ زﻣﺎﻧﻲ اﻳـﻦ ﻣـﺘﻦ ﺗﻐﻴﻴـﺮ ﻛﻨـﺪ ﻛـﻪ ﻣﺘـﺪ‬ ‫‪ Load‬ﺑﻪ ﻋﻠﺖ ﻛﻠﻴﻚ ﻛﺮدن ﻛﺎرﺑﺮ روي ﻳﻜﻲ از دﻛﻤﻪ ﻫﺎي ﻓﺮم ﻓﺮاﺧﻮاﻧﻲ ﺷﻮد‪ .‬ﭘﺲ آن را در ﺷـﺮط == ‪IsPostBack‬‬ ‫‪ True‬ﻗﺮار ﻣﻲ دﻫﻴﻢ‪:‬‬ ‫)‪if (Page.IsPostBack‬‬ ‫{‬ ‫‪// If this is a postback and not the initial page‬‬ ‫‪// load Display the data to the user‬‬ ‫‪this.lblWelcome.Text = "Hello " +‬‬ ‫‪this.txtFirstName.Text + " " +‬‬ ‫‪this.txtLastName.Text + "
" +‬‬ ‫‪"Your email address is " +‬‬ ‫;‪this.txtEmail.Text‬‬ ‫}‬

‫ﻃﺮاﺣﻲ ﻇﺎﻫﺮ ﺳﺎﻳﺖ‪:‬‬ ‫در ﮔﺬﺷﺘﻪ ﻳﻜﻲ از ﻋﻤﺪه ﺗﺮﻳﻦ ﻣﺸﻜﻼت ﻃﺮاﺣﻲ ﺳﺎﻳﺖ‪ ،‬اﻳﺠﺎد ﻇﺎﻫﺮي ﺛﺎﺑﺖ و ﭘﺎﻳﺪار ﺑﺮاي آن در ﺗﻤﺎم ﺻﻔﺤﺎت ﺗﺸﻜﻴﻞ دﻫﻨﺪه ي ﺳﺎﻳﺖ‬ ‫ﺑﻮد‪ ،‬ﺑﻪ ﮔﻮﻧﻪ اي ﻛﻪ ﺑﺘﻮان ﺑﻪ ﺳﺎدﮔﻲ آن را ﻛﻨﺘﺮل ﻛﺮد و ﻳﺎ ﺗﻐﻴﻴﺮ داد‪ .‬ﻃﺮاﺣﺎن ﺳﺎﻳﺖ ﺑﺎ اﻳﺠﺎد ﻛﻨﺘﺮﻟﻬﺎي ﺳﻔﺎرﺷـﻲ و ﻗـﺮار دادن آﻧﻬـﺎ در‬ ‫ﺗﻤﺎﻣﻲ ﺻﻔﺤﺎت و ﻳﺎ اﺳﺘﻔﺎده از ﭼﻨﺪﻳﻦ روش دﻳﮕﺮ ﺳﻌﻲ ﻣﻲ ﻛﺮدﻧﺪ ﺑﻪ ﭼﻨﻴﻦ ﻫﺪﻓﻲ دﺳﺖ ﭘﻴﺪا ﻛﻨﻨﺪ‪ .‬اﺳـﺘﻔﺎده از اﻳـﻦ روﺷـﻬﺎ در اﻏﻠـﺐ‬ ‫ﻣﻮارد ﺟﻮاﺑﮕﻮ ﺑﻮد‪ ،‬اﻣﺎ ﻣﺸﻜﻞ ﻋﻤﺪه اي ﻛﻪ اﻳﺠﺎد ﻣﻲ ﻛﺮد اﻳﻦ ﺑﻮد ﻛﻪ ﻃﺮاح ﺳﺎﻳﺖ ﻧﻤﻲ ﺗﻮاﻧﺴﺖ ﻣﻄﻤﺌﻦ ﺷـﻮد ﻛـﻪ ﺗﻤـﺎم ﻛﻨﺘـﺮل ﻫـﺎي‬ ‫ﺳﻔﺎرﺷﻲ ﻛﻪ اﻳﺠﺎد ﺷﺪه اﻧﺪ در ﻣﻜﺎن ﺧﻮد ﻗﺮار دارﻧﺪ‪ .‬ﺑﺮاي اﻧﺠﺎم اﻳﻦ ﻛﺎر زﻣﺎن زﻳﺎدي ﺑﺎﻳﺪ ﺻﺮف ﻣﻲ ﺷﺪ و ﺑﺎ ﻛﻮﭼﻜﺘﺮﻳﻦ ﺗﻐﻴﻴﺮي ﻛﻪ در‬ ‫ﻣﺤﺘﻮي ﺳﺎﻳﺖ ﺑﻪ وﺟﻮد ﻣﻲ آﻣﺪ‪ ،‬ﻳﻚ ﻧﻔﺮ ﺑﺎﻳﺪ ﻣﺴﺌﻮل ﻣﻲ ﺷﺪ ﺗﺎ ﺗﻤﺎم ﻗﺴﻤﺘﻬﺎي ﺳﺎﻳﺖ را ﺑﺮرﺳﻲ ﻛﺮده و از درﺳـﺖ ﺑـﻮدن ﻃـﺎﻫﺮ آﻧﻬـﺎ‬ ‫ﻣﻄﻤﺌﻦ ﺷﻮد‪.‬‬ ‫در وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬ﺑﺎ اﺳﺘﻔﺎده از اﺑﺰارﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ ‪Theme‬ﻫﺎ‪ ،‬ﻓﺮﻣﻬﺎي اﺻﻠﻲ و ﻳﺎ ﺑﺴﻴﺎر ي از اﺑﺰارﻫﺎي دﻳﮕﺮ ﻣﻲ ﺗﻮان ﻇـﺎﻫﺮي‬ ‫ﺛﺎﺑﺖ ‪ .‬ﭘﺎﻳﺪار را ﺑﺮاي ﺗﻤﺎم ﻗﺴﻤﺘﻬﺎي ﺳﺎﻳﺖ اﻳﺠﺎد ﻛﺮد‪ .‬در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ‪ ،‬ﺑﺎ ﺗﻌﺪادي از اﻳﻦ اﺑﺰارﻫﺎ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ‪.‬‬

‫‪٧١٣‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﻳﺠﺎد اوﻟﻴﻦ وب ﺳﺎﻳﺖ‬ ‫‪ (1‬ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﻚ وب ﺳﺎﻳﺖ ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم ‪ SiteLookAndFeel‬اﻳﺠﺎد ﻛﻨﻴﺪ‪.‬‬ ‫‪ (2‬ﺑﺮاي ﺷﺮوع ﺑﺮﻧﺎﻣﻪ‪ ،‬ﺑﺎﻳﺪ ﭼﻨﺪﻳﻦ ﻓﺎﻳﻞ و ﻳﺎ ﻓﻮﻟﺪر را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪ .‬اﺑﺘﺪا روي ﻧﺎم ﭘﺮوژه در ﭘﻨﺠﺮه ي ‪Solution‬‬ ‫‪ Explorer‬ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ ي ‪ Add New Item‬را اﻧﺘﺨﺎب ﻛﻨﻴـﺪ‪ .‬از ﻛـﺎدري‬ ‫ﻛﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﮔﺰﻳﻨﻪ ي ‪ Master Page‬را اﻧﺘﺨﺎب ﻛﺮده و روي ﮔﺰﻳﻨﻪ ي ‪ Add‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪.‬‬ ‫‪ (3‬راﻫﻨﻤﺎي ‪ Page‬در ﻓﺮم ‪ Default.aspx‬را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ از ‪ MasterPage‬اﻳﺠﺎد ﺷـﺪه‬ ‫اﺳﺘﻔﺎده ﻛﻨﺪ‪:‬‬ ‫"‪<%@ Page Language="C#" MasterPageFile="~/MasterPage.master‬‬ ‫"‪AutoEventWireup="true" CodeFile="Default.aspx.cs‬‬ ‫>‪Inherits="_Default" %‬‬ ‫‪ (4‬ﻓﺎﻳﻠﻬﺎ و ﻓﻮﻟﺪرﻫﺎي ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪.‬‬ ‫‬

‫‬

‫ﻳﻚ ﻓﻮﻟﺪر ‪ Theme‬ﺑﻪ ﻓﻮﻟﺪر اﺻﻠﻲ ﺳﺎﻳﺖ اﺿﺎﻓﻪ ﻛﺮده و ﻧﺎم آن را ﺑﺮاﺑﺮ ﺑﺎ ‪ Red‬ﻗﺮار دﻫﻴﺪ‪ .‬ﺑﺮاي اﻳﻦ ﻛـﺎر در‬ ‫ﭘﻨﺠﺮه ي ‪ Solution Explorer‬روي ﻧﺎم ﺑﺮﻧﺎﻣﻪ ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨﻮي ﺑﺎز ﺷـﺪه‪ ،‬ﮔﺰﻳﻨـﻪ‬ ‫ي ‪ Add ASP.NET Folder  Theme‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻳﻚ ﻓﻮﻟﺪر اﺻـﻠﻲ‬ ‫ﺑﻪ ﻧﺎم ‪ App_Theme‬ﺑﻪ ﺳﺎﻳﺖ اﺿﺎﻓﻪ ﺷﺪه و ﻳﻚ زﻳﺮ ﻓﻮﻟﺪر ﻧﻴﺰ ﺑﻪ در آن اﻳﺠﺎد ﻣﻲ ﺷﻮد‪ .‬ﻧﺎم ﻓﻮﻟـﺪري ﻛـﻪ‬ ‫درون ﻓﻮﻟﺪر ‪ App_Theme‬اﻳﺠﺎد ﺷﺪه اﺳـﺖ را ﺑـﻪ ‪ Red‬ﺗﻐﻴﻴـﺮ دﻫﻴـﺪ‪ .‬ﺳـﭙﺲ ﻓﻮﻟـﺪر دﻳﮕـﺮي ﺑـﻪ ﻧـﺎم‬ ‫‪ Brown‬ﺑﻪ ‪ App_Theme‬اﺿﺎﻓﻪ ﻛﻨﻴﺪ و ﺑﻌﺪ از اﻳﻦ ﻛﺎر ﻳـﻚ ﻓﺎﻳـﻞ ﺑـﻪ ﻧـﺎم ‪ brown.skin‬در‬ ‫ﻓﻮﻟـﺪر ‪ Brown‬اﻳﺠـﺎد ﻛﻨﻴـﺪ‪ .‬روي ﻓﻮﻟـﺪر ‪ Brown‬ﻛﻠﻴـﻚ راﺳـﺖ ﻛـﺮده و ﮔﺰﻳﻨـﻪ ي ‪Add New‬‬ ‫…‪ Item‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻛﺎدر ﺑﺎز ﺷﺪه ﻳﻚ ﻓﺎﻳﻞ از ﻧﻮع ‪ Style Sheet‬ﺑـﻪ ﻧـﺎم‬ ‫‪ Brown.css‬را ﺑــﻪ ﻓﻮﻟــﺪر ‪ Brown‬اﺿــﺎﻓﻪ ﻛﻨﻴــﺪ‪ .‬در ﻓﻮﻟــﺪر ‪ Red‬ﻧﻴــﺰ ﺳــﻪ ﻓﺎﻳــﻞ ﺑــﻪ ﻧﺎﻣﻬــﺎي‬ ‫‪ Button.skin ،Red.skin‬و ‪ TextBox.skin‬اﺿﺎﻓﻪ ﻛﻨﻴﺪ )ﺑﺮاي اﺿﺎﻓﻪ ﻛـﺮدن اﻳـﻦ‬ ‫ﻓﺎﻳﻠﻬﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ روي ﻓﻮﻟﺪر ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨﻮي ﺑـﺎز ﺷـﺪه ﮔﺰﻳﻨـﻪ ي …‪ Add New Item‬را‬ ‫اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻛﺎدر ﺑﺎز ﺷﺪه ﻳﻚ ﻓﺎﻳﻞ از ﻧﻮع ‪ Skin File‬ﺑﺎ ﻧﺎﻣﻬﺎي ﻣﺸﺨﺺ ﺷـﺪه را‬ ‫ﺑﻪ ﻓﻮﻟﺪر اﺿﺎﻓﻪ ﻛﻨﻴﺪ(‪.‬‬ ‫ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي ﻧﺎم ﺑﺮﻧﺎﻣﻪ در ﭘﻨﺠﺮه ي ‪ Solution Explorer‬و اﻧﺘﺨﺎب ﮔﺰﻳﻨﻪ ي ‪Add‬‬ ‫‪ New‬ﭘــــــﻨﺞ ﻓــــــﺮم وب ﺟﺪﻳــــــﺪ ﺑــــــﻪ ﻧﺎﻣﻬــــــﺎي ‪،News.aspx‬‬ ‫…‪Item‬‬ ‫‪ Events.aspx ،NewsToday.aspx ،NewsYesterday.aspx‬و‬ ‫‪ Contacts.aspx‬را ﺑﻪ ﺳﺎﻳﺖ ﺧﻮد اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪ .‬ﻫﻨﮕﺎم اﺿﺎﻓﻪ ﻛﺮدن اﻳﻦ ﻓﺮم ﻫﺎ‪ ،‬در ﭘﻨﺠﺮه ي ‪Add‬‬ ‫‪ New Item‬ﮔﺰﻳﻨﻪ ي ‪ Select master page‬را اﻧﺘﺨﺎب ﻛﻨﻴـﺪ‪ .‬ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﻗﺒـﻞ از‬ ‫اﻳﺠﺎد ﻓﺮم ﻛﺎدر ‪ Select a Master Page‬ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و ﺑﻪ ﺷﻤﺎ اﻳـﻦ اﺟـﺎزه را ﻣـﻲ‬ ‫دﻫﺪ ﺗﺎ ﻳﻚ ‪ Master Page‬ﺑﺮاي ﻓﺮم ﺧﻮد اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬در اﻳﻦ ﻛﺎدر ﻧﻴـﺰ ‪ Master Page‬اي‬ ‫ﻛﻪ در اﺑﺘﺪاي اﻳﻦ ﻗﺴﻤﺖ اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﻢ را اﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤﻪ ي ‪ OK‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻓﺮم وب ﻣـﻮرد‬ ‫ﻧﻈﺮ اﻳﺠﺎد ﺷﻮد‪.‬‬

‫‪٧١٤‬‬

‫ ﺑﺮاي اﻳﻦ ﻛﺎر روي ﻧﺎم ﭘﺮوژه در ﭘﻨﺠﺮه‬.‫ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ‬Site Map ‫در آﺧﺮ ﻧﻴﺰ ﺑﺎﻳﺪ ﻳﻚ ﻓﺎﻳﻞ از ﻧﻮع‬ ‫ را‬Add New Item… ‫ ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﺳﭙﺲ ﮔﺰﻳﻨﻪ ي‬Solution Explorer ‫ي‬ ‫ را اﻧﺘﺨﺎب ﻛـﺮده و روي دﻛﻤـﻪ ي‬Site Map ‫ ﮔﺰﻳﻨﻪ ي‬Add New Item ‫ از ﻛﺎدر‬.‫اﻧﺘﺨﺎب ﻛﻨﻴﺪ‬ 9-17 ‫ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷـﻜﻞ‬Solution Explorer ‫ ﺑﻌﺪ از اﺗﻤﺎم اﻳﻦ ﻛﺎر ﭘﻨﺠﺮه ي‬.‫ ﻛﻠﻴﻚ ﻛﻨﻴﺪ‬OK .‫ﺑﺎﺷﺪ‬



9-17 ‫ﺷﻜﻞ‬ :‫ را ﺑﺎز ﻛﺮده و ﻛﺪ درون آن را ﺑﻪ ﺻﻮرت ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ‬Web.sitemap ‫( ﻓﺎﻳﻞ‬5 <siteMap xmlns= "http://schemas.microsoft.com/AspNet/SiteMap-File-1.0"> <siteMapNode url="Default.aspx" title="Home" description="Back to the main page" roles="" > <siteMapNode url="News.aspx" title="News" description="Your front page news." roles=""> <siteMapNode url="NewsToday.aspx" title="Today’s News" description="Today’s top stories" roles="" /> <siteMapNode url="NewsYesterday.aspx" title="Yesterday’s News" description="Yesterday’s top stories" roles="" /> <siteMapNode url="Events.aspx" title="Upcoming Events" description="Today’s top stories" roles="" /> ٧١٥

‫"‪<siteMapNode url="Contact.aspx" title="Contact Us‬‬ ‫>‪description="Today’s top stories" roles="" /‬‬ ‫>‪‪ آن را ﺑﻪ ﻗﺴﻤﺖ ‪ Style Rule Hierarchy‬اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪ .‬ﺣﺎل اﮔﺮ روي دﻛﻤﻪ ي‬ ‫‪ OK‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ ،‬ﻳﻚ ﻗﺴﻤﺖ ﻣﺸﺨﺼﺎت ﺧﺎﻟﻲ ﺑﺮاي ﻋﻨﺼﺮ ‪ HR‬ﺑﻪ ﻓﺎﻳﻞ اﺿﺎﻓﻪ ﺷﺪه اﺳﺖ‪.‬‬

‫ﺷﻜﻞ ‪10-17‬‬ ‫ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن اﻳﻦ ﻗﺴﻤﺖ‪ ،‬در ﺣﻘﻴﻘﺖ ﻣﺸﺨﺺ ﻛﺮده اﻳﺪ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻇﺎﻫﺮ ﺗﻤﺎم ﺗﮕﻬـﺎي ‪ HR1‬در ﻓﺎﻳـﻞ وﺑـﻲ ﻛـﻪ از اﻳـﻦ ﻓﺎﻳـﻞ‬ ‫‪ CSS‬اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﺑﻪ ﺻﻮرﺗﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﺑﺎﺷﺪ‪ .‬ﺧﻮب‪ ،‬ﭘﺲ ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺎﻳﺪ در اﻳﻦ ﻗـﺴﻤﺖ ﻇـﺎﻫﺮ‬ ‫ﺗﮕﻬﺎي ‪ HR‬را ﻣﺸﺨﺺ ﻛﻨﻴﻢ‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر ﻫﻢ ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻛﻪ ﺑﺮاي اﻳﻦ ﻗﺴﻤﺖ وﺟﻮد دارد اﺳﺘﻔﺎده ﻛﻨـﻴﻢ ﻫـﻢ ﻣـﻲ‬ ‫ﺗﻮاﻧﻴﻢ ﻛﺪ آن را وارد ﻛﻨﻴﻢ‪ .‬ﺑﺮاي اﺳﺘﻔﺎده از اﺑﺰار ﻃﺮاﺣﻲ‪ ،‬ﻣﻜﺎن ﻧﻤﺎ را ﺑﻪ ﺑﻴﻦ دو ﻋﻼﻣﺖ { ﺑﻌﺪ از ‪ HR‬ﺑـﺮده و در آﻧﺠـﺎ ﻛﻠﻴـﻚ راﺳـﺖ‬ ‫ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ از ﻣﻨﻮﻳﻲ ﻛﻪ ﺑﺎز ﻣﻲ ﺷﻮد ﮔﺰﻳﻨﻪ ي ‪ Build Style‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗـﺎ ﻛـﺎدر ‪Build Style – HR‬‬ ‫ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪ 11-17‬ﻧﻤﺎﻳﺶ داده ﺷﻮد‪ .‬ﺑﺮاي وارد ﻛﺮدن ﻛﺪ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻇﺎﻫﺮ ﻣﻮرد ﻧﻈﺮ ﺧﻮد را در ﺑﻴﻦ دو ﻋﻼﻣﺖ آﻛﻮﻻد وارد ﻛﻨﻴﺪ‪.‬‬ ‫‪ 1‬اﻳﻦ ﺗﮓ در زﺑﺎن ‪ HTML‬ﺑﺮاي اﻳﺠﺎد ﺧﻄﻮط اﻓﻘﻲ ﺑﻪ ﻛﺎر ﻣﻲ رود‪.‬‬

‫‪٧١٦‬‬

‫ﻫﻤﭽﻨﻴﻦ ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺳﻴﺴﺘﻢ ﺗﻜﻤﻴﻞ ﻫﻮﺷﻤﻨﺪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ .‬در اﻳﻨﺠﺎ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑـﻪ‬ ‫ﺑﻼك ‪ HR‬اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪:‬‬ ‫‪HR‬‬ ‫{‬ ‫;‪color:#CC0000‬‬ ‫;‪height:12px‬‬ ‫}‬

‫ﺷﻜﻞ ‪11-17‬‬ ‫‪ (7‬ﺣﺎل ﺑﺎﻳﺪ ﻇﺎﻫﺮ ‪ MasterPage‬را ﺗﻌﻴﻴﻦ ﻛﻨﻴﻢ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻗﺎﻟﺐ ﺗﻤﺎم ﺻﻔﺤﺎﺗﻲ ﻛﻪ از اﻳـﻦ ‪MasterPage‬‬ ‫اﺳــﺘﻔﺎده ﻣــﻲ ﻛﻨﻨــﺪ ﺑــﻪ اﻳــﻦ ﺷــﻜﻞ در ﺧﻮاﻫــﺪ آﻣــﺪ‪ .‬در ﭘﻨﺠــﺮه ي ‪ Solution Explorer‬روي ﻓﺎﻳــﻞ‬ ‫‪ MasterPage.master‬دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑﺎز ﺷﻮد‪ .‬ﺳﭙﺲ ﺑﻪ ﻧﻤﺎي ‪ Source‬ﺑﺮوﻳﺪ و ﻛﺪ ‪ HTML‬آن‬ ‫را ﺑﻪ ﺻﻮرت ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪:‬‬ ‫"‪<%@ Master Language="C#" AutoEventWireup="true‬‬ ‫>‪CodeFile="MasterPage.master.cs" Inherits="MasterPage" %‬‬

‫‪٧١٧‬‬

Untitled Page <Style type="text/css"> .TableLayout { width: 700px; background-color:#ffcc66; } .border { border-style:solid; border-color:black; border-width:thin; }

٧١٨

NavigateUrl="Contact.aspx" rel="nofollow">

‫ ﻣﻮﺟـﻮد در آن را ﺑـﺎ‬HTML ‫ ﺳﭙﺲ ﻛﺪ‬.‫ در آن ﺑﺮوﻳﺪ‬Source ‫ را ﺑﺎز ﻛﺮده و ﺑﻪ ﻧﻤﺎي‬Default.aspx ‫( ﻓﺎﻳﻞ‬8 :‫ﻛﺪ زﻳﺮ ﺟﺎﻳﮕﺰﻳﻦ ﻛﻨﻴﺪ‬

٧١٩

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Theme="Red" %> Just some text

:‫ را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ‬News.aspx ‫ ﻣﻮﺟﻮد در ﻓﺎﻳﻞ‬HTML ‫( ﺣﺎل ﻛﺪ‬9 <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="News.aspx.cs" Inherits="News" Title="Untitled Page" Theme="Brown"%> Just some text ‫ را ﺑﺎز ﻛﺮده و ﻛـﺪ زﻳـﺮ را ﺑـﻪ آن اﺿـﺎﻓﻪ‬Button.skin ‫ ﻓﺎﻳﻞ‬Solution Explorer ‫( ﺑﺎ اﺳﺘﻔﺎده از‬10 :‫ﻛﻨﻴﺪ‬ :‫ را ﺑﺎز ﻛﺮده و ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬Red ‫ در ﻓﻮﻟﺪر‬TextBox.skin ‫( ﻓﺎﻳﻞ‬11 :‫ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬Brown ‫ در ﻓﻮﻟﺪر‬Brown.skin ‫( ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ ﻓﺎﻳﻞ‬12

٧٢٠

‫"‪‪Font-Weight="Bold" /‬‬ ‫‪ (13‬در ﻓﺮﻣﻬـــﺎي دﻳﮕـــﺮ‪ ،‬ﻛـــﺎﻓﻲ اﺳـــﺖ ﻛـــﻪ ﻋﺒـــﺎرت ‪ ContentPlaceHolderID‬را ﺑـــﺎ ﻋﺒـــﺎرت‬ ‫‪ cphPageCpntent‬ﺗﻌﻮﻳﺾ ﻛﻨﻴﺪ‪ .‬دﻟﻴﻞ اﻳﻦ ﻛﺎر ﻧﻴﺰ در اﻳﻦ اﺳﺖ ﻛﻪ ﺑﻌﺪ از اﺿﺎﻓﻪ ﻛﺮدن اﻳﻦ ﻓﺮم ﻫﺎ ﺑﻪ ﺑﺮﻧﺎﻣـﻪ‪،‬‬ ‫ﻓﺎﻳـــــﻞ ‪ MasterPage‬را ﺗﻐﻴﻴـــــﺮ دادﻳـــــﻢ‪ .‬ﺑﻨـــــﺎﺑﺮاﻳﻦ ﺧـــــﻂ دوم ﻓﺎﻳﻠﻬـــــﺎي ‪،Events.aspx‬‬ ‫‪ NewsToday.aspx ،Contacts.aspx‬و ‪ NewsYesterday.aspx‬ﺑــﻪ ﺻــﻮرت زﻳــﺮ‬ ‫ﺧﻮاﻫﺪ ﺑﻮد‪:‬‬ ‫"‪"‪ContentPlaceHolderID="cphPageContent‬‬ ‫‪ (14‬ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ و ﻟﻴﻨﻚ ﻫﺎي ﻣﺨﺘﻠﻔﻲ ﻛﻪ در ﺳﺎﻳﺖ اﻳﺠﺎد ﺷﺪه اﻧﺪ را اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ .‬ﺑﻪ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي ﺟﺎ ﺑﻪ ﺟـﺎﻳﻲ‬ ‫در ﺑﻴﻦ ﻓﺮﻣﻬﺎي ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﺷﺪه اﻧﺪ ﺗﻮﺟﻪ ﻛﻨﻴﺪ‪ .‬ﺳﺎﻳﺖ ﺷﻤﺎ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪ 12-17‬ﺧﻮاﻫﺪ ﺑﻮد‪.‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ اﻳﻦ ﻗﺴﻤﺖ‪ ،‬از ﺑﻌﻀﻲ از ﺟﺪﻳﺪﺗﺮﻳﻦ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ‪ ASP.NET 2‬اﺿﺎﻓﻪ ﺷﺪه ﺑﻮدﻧﺪ اﺳـﺘﻔﺎده ﻛـﺮدﻳﻢ‪.‬‬ ‫ﺗﺮﻛﻴﺐ اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ اﻳﻦ اﻣﻜﺎن را ﺑﻪ ﻣﺎ داد ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﺑﻪ ﺳﺎدﮔﻲ ﺳﺎﻳﺘﻬﺎﻳﻲ ﺑﺎ ﻇﺎﻫﺮ ﻗﺪرﺗﻤﻨﺪ و زﻳﺒﺎ ﻃﺮاﺣﻲ ﻛﻨﻴﻢ‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻃﻮل‬ ‫اﻳﻦ ﻣﺜﺎل ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از ‪ MasterPage‬ﻫﺎ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻛﻪ ﻇﺎﻫﺮي ﭘﺎﻳﺪار را ﺑﺮاي ﺗﻤﺎم ﺻﻔﺤﺎت ﺳﺎﻳﺖ اﻳﺠﺎد ﻛﻨﻴﻢ‪.‬‬ ‫ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻗﺴﻤﺘﻬﺎﻳﻲ را ﻛﻪ ﺑﺎﻳﺪ در ﭼﻨﺪﻳﻦ ﺻﻔﺤﻪ از ﺳﺎﻳﺖ وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﻨﺪ را در ﻳﻚ ‪ MasterPage‬ﻗﺮار داده و ﺳـﭙﺲ‬ ‫از آن در ﺻﻔﺤﺎت ﻣﻮرد ﻧﻈﺮ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺨﺸﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﺟﺎ ب ﺟﺎ ﺷﺪن ﺑﻴﻦ ﺻﻔﺤﺎت ﻣﺨﺘﻠﻒ ﺳﺎﻳﺖ و‬ ‫ﻳﺎ ﻧﻘﺸﻪ ي ﺳﺎﻳﺖ را در اﻳﻦ ﻗﺴﻤﺘﻬﺎ ﻗﺮار دﻫﻴﻢ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ در ﺻﻮرت ﻟﺰوم اﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﻛﻪ ﻳﻜﻲ از اﻳﻦ ﻗﺴﻤﺘﻬﺎ را ﺗﻐﻴﻴﺮ دﻫﻴﻢ‪ ،‬ﻛﺎﻓﻲ‬ ‫اﺳﺖ ﻛﻪ اﻳﻦ ﺗﻐﻴﻴﺮ را در ‪ MasterPage‬اﻋﻤﺎل ﻛﻨﻴﻢ ﺗﺎ ﺗﻤﺎم ﺻﻔﺤﺎت ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ آن را درﻳﺎﻓﺖ ﻛﻨﻨﺪ‪.‬‬ ‫ﻛﺪي ﻛﻪ در ‪ MasterPage‬وارد ﻛﺮدﻳﻢ ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﺑﺴﻴﺎر ﻃﻮﻻﻧﻲ ﺑﻮد‪ ،‬اﻣﺎ ﻫﻴﭻ ﻗﺴﻤﺖ ﭘﻴﭽﻴﺪه و ﻣﺒﻬﻤﻲ ﻧﺪاﺷـﺖ و ﺗﻤـﺎم آن‬ ‫را ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺴﺘﻴﻢ اﻳﺠﺎد ﻛﻨﻴﻢ‪ .‬ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ‪ MasterPage‬ﺑﺮوﻳﺪ و ﻧﻤﺎي آن را ﺑﻪ ‪ Design‬ﺗﻐﻴﻴـﺮ‬ ‫دﻫﻴﺪ ﺗﺎ ﻛﻨﺘﺮل ﻫﺎﻳﻲ را ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺪ ‪ HTML‬در ﻓﺮم ﻗﺮار داده اﻳﻢ ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ‪ .‬در ﻓﺎﻳﻞ ‪ MasterPage‬ﻳﻚ ﻛﻨﺘﺮل ﺑﻪ‬ ‫ﻧﺎم ‪ ContentPalceHolder‬ﻗﺮار داده اﻳﻢ‪ .‬اﻳﻦ ﻛﻨﺘﺮل ﻗﺴﻤﺘﻲ را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ اﻃﻼﻋﺎت ﺻﻔﺤﻪ ﻫﺎي دﻳﮕﺮ ﻣﻲ‬ ‫ﺗﻮاﻧﻨﺪ در آن ﻗﺮار ﺑﮕﻴﺮﻧﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ از اﻳﻦ ‪ MasterPage‬در ﺻﻔﺤﺎت ﺳﺎﻳﺖ ﺧﻮد اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ‪ ،‬ﻓﻘـﻂ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﻗـﺴﻤﺖ‬ ‫ﻣﺸﺨﺺ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي ‪ ContentPlaceHolder‬را ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪.‬‬

‫‪٧٢١‬‬

12-17 ‫ﺷﻜﻞ‬ ‫ از ﻳﻚ ﺟﺪول اﺳﺘﻔﺎده ﻛﺮده اﻳﻢ ﺗﺎ ﻋﻨﺎﺻﺮي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ در ﺗﻤﺎم ﻓﺮﻣﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻗﺮار ﺑﮕﻴﺮﻧـﺪ را‬MasterPage ‫ﻫﻤﭽﻨﻴﻦ در‬ ‫ ﺷﺎﻣﻞ ﭼﻨﺪ ﻛﻨﺘﺮل ﺳﺎده و ﻧﻴﺰ ﭼﻨﺪ ﻛﻨﺘﺮل دﻳﮕﺮ اﺳﺖ ﻛﻪ اﺣﺘﻤﺎﻻ ﺗـﺎ‬،‫ ﻋﻨﺎﺻﺮي ﻫﻢ ﻛﻪ در آن ﻗﺮار داده اﻳﻢ‬.‫ﺑﻪ وﺳﻴﻠﻪ ي آن ﻣﺮﺗﺐ ﻛﻨﻴﻢ‬ .SiteMapPath ‫ و ﻳﺎ‬Menu ‫ ﻣﺎﻧﻨﺪ‬،‫ﻛﻨﻮن از آﻧﻬﺎ اﺳﺘﻔﺎده ﻧﻜﺮده اﻳﺪ‬ Untitled Page <Style type="text/css"> .TableLayout {width: 700px; background-color:#ffcc66;} .border {border-style:solid; border-color:black; border-width:thin;}
٧٢٢



٧٢٣

‫>‪




٧٥٣



٧٥٤


User: Guest, Please log in



‫ ﺳـﭙﺲ ﻛـﺪ‬.‫ در ﻓﻮﻟﺪر اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ را ﺑﺎز ﻛﺮده و ﺗﻤﺎم ﻛـﺪ ﻫـﺎي درون آن را ﺣـﺬف ﻛﻨﻴـﺪ‬Default.aspx ‫( ﻓﺎﻳﻞ‬2 :‫ ﺷﻮد‬11-18 ‫ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در آن وارد ﻛﻨﻴﺪ ﺗﺎ اﻳﻦ ﻓﺮم ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ‬ <%@ Page Language="C#" MasterPageFile="~/Main.master" Title="Home" %>

11-18 ‫ﺷﻜﻞ‬ ‫ ﻧﻴﺰ ﺗﻤﺎم ﻛﺪ ﻫﺎي ﻣﻮﺟﻮد را ﺣﺬف ﻛﻨﻴﺪ و ﺳـﭙﺲ ﻛـﺪ ﻣـﺸﺨﺺ ﺷـﺪه در زﻳـﺮ را در آن وارد‬Login.aspx ‫( در ﻓﺎﻳﻞ‬3 :‫ﻛﻨﻴﺪ‬ <%@ Page Language="C#" MasterPageFile="~/Main.master" Title="Login" %>

‫ ﺑـﻪ اﻳـﻦ‬.‫ را ﻧﻴﺰ ﺣﺬف ﻛﺮده و آن را ﺑﺎ ﻛﺪ زﻳﺮ ﺟﺎﻳﮕﺰﻳﻦ ﻛﻨﻴﺪ‬ChangePassword.aspx ‫( ﻛﺪ ﻣﻮﺟﻮد در ﻓﺎﻳﻞ‬4 :‫ ﺧﻮاﻫﺪ ﺑﻮد‬13-18 ‫ ﻣﺸﺎﺑﻪ ﺷﻜﻞ‬ChangePassword.aspx ‫ﺗﺮﺗﻴﺐ ﻓﺮم‬ <%@ Page Language="C#" MasterPageFile="~/Main.master"

٧٥٥

Title="Change Password" %>

14-18 ‫ ﻣﺸﺎﺑﻪ ﺷﻜﻞ‬،‫ ﻛﺪ داﺧﻞ ﻓﺮم را ﺑﺎ ﻛﺪ زﻳﺮ ﺟﺎﻳﮕﺰﻳﻦ ﻛﻨﻴﺪ ﺗﺎ ﻓﺮم‬،‫ ﻧﻴﺰ‬CerateNewUser.aspx ‫( در ﻓﺮم‬5 :‫ﺷﻮد‬ <%@ Page Language="C#" MasterPageFile="~/Main.master" Title="Create New Account" %>

12-18 ‫ﺷﻜﻞ‬ :‫ را ﻧﻴﺰ ﺑﺎ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ ﺟﺎﻳﮕﺰﻳﻦ ﻛﻨﻴﺪ‬ViewAuthors.aspx ‫( ﻛﺪ ﻣﻮﺟﻮد در ﻓﺎﻳﻞ‬6 <%@ Page Language="C#" MasterPageFile="~/Main.master" Title="View Authors" %>

٧٥٦

‫ﺷﻜﻞ ‪13-18‬‬

‫ﺷﻜﻞ ‪14-18‬‬

‫‪٧٥٧‬‬

‫‪ (7‬ﻛﺪ ﻣﻮﺟﻮد در ﻓﺎﻳﻞ ‪ ViewTitles.aspx‬را ﺣﺬف ﻛﺮده و ﻛﺪ زﻳﺮ را ﺑﻪ ﺟﺎي آن ﻗﺮار دﻫﻴﺪ‪:‬‬ ‫"‪<%@ Page Language="C#" MasterPageFile="~/Main.master‬‬ ‫>‪Title="View Titles" %‬‬ ‫"‪"‪Runat="server‬‬ ‫"‪"‪Text="Add Code to View Title Info Later‬‬ ‫>‪‪
‫‪ (8‬در ﻓﺎﻳﻞ ‪ ،ViewUsers.aspx‬ﻛﺪي ﻛﻪ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض وارد ﺷﺪه اﺳﺖ را ﺣﺬف ﻛﻨﻴﺪ و ﺑـﻪ ﺟـﺎي آن ﻛـﺪ‬ ‫زﻳﺮ را ﻗﺮار دﻫﻴﺪ‪:‬‬ ‫"‪<%@ Page Language="C#" MasterPageFile="~/Main.master‬‬ ‫>‪Title="View Users" %‬‬ ‫>"‪"‪Text="Add Code to View User Info Later‬‬ ‫>‪‪
‫‪ (9‬ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ ﺗﺎ ﻋﻤﻠﻜﺮد آن را ﺗﺴﺖ ﻛﻨﻴﻢ‪ .‬در اﻳﻦ ﺳﺎﻳﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ اﻛﺎﻧـﺖ ﺟﺪﻳـﺪ اﻳﺠـﺎد ﻛـﺮده و ﺳـﭙﺲ ﺑـﺎ‬ ‫اﺳﺘﻔﺎده از آن وارد ﺳﻴﺴﺘﻢ ﺷﻮﻳﺪ‪ .‬ﺗﻤﺎم ﻣﻮارد ﻣﺮﺑﻮط ﺑﻪ ﺗﻌﻴﻴﻦ ﻫﻮﻳﺖ اﻓﺮاد و ﻧﻴﺰ ﺟﻠﻮﮔﻴﺮي از دﺳﺘﺮﺳﻲ ﻏﻴﺮ ﻣﺠﺎز‪،‬ﺑﻪ وﺳﻴﻠﻪ ي‬ ‫ﻫﻤﻴﻦ ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﺮدﻳﻢ ﻣﺪﻳﺮﻳﺖ ﻣﻲ ﺷﻮد‪ .‬اﻟﺒﺘﻪ در ﺣﺎل ﻛﺎر ﺑﺎ اﻳﻦ ﺳـﺎﻳﺖ ﻣﻤﻜـﻦ اﺳـﺖ ﺑـﻪ‬ ‫ﺻﻔﺤﺎت ﺧﻄﺎﻳﻲ ﻧﻴﺰ ﺑﺮﺧﻮرد ﻛﻨﻴﺪ ﻛﻪ در ﻣﻮرد رﻓﻊ آﻧﻬﺎ در اﻳﻦ ﻛﺘﺎب ﺻﺤﺒﺘﻲ ﻧﺨﻮاﻫﻴﻢ ﻛﺮد‪.‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫اﺣﺘﻤﺎﻻً ﺑﻌﺪ از اﺗﻤﺎم اﻳﻦ ﺳﺎﻳﺖ‪ ،‬ﺑﺎ ﻣﺸﺎﻫﺪه ي ﻋﻤﻠﻜﺮد آن ﻛﺎﻣﻼً ﺷﮕﻔﺖ زده ﻣﻲ ﺷﻮﻳﺪ‪ .‬در ﺗﻜﻨﻮﻟﻮژي ﻫﺎي ﻗﺪﻳﻤﻲ ﺗﺮ ﭘﻴﺎده ﺳﺎزي ﭼﻨﻴﻦ‬ ‫ﺳﻴﺴﺘﻤﻲ‪ ،‬روزﻫﺎ ﻃﻮل ﻣﻲ ﻛﺸﻴﺪ‪.‬‬ ‫در اﻳﻦ ﺳﺎﻳﺖ ﻧﻴﺰ ﺗﻤﺎم ﻗﺴﻤﺘﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﻃﺮاﺣﻲ ﻇﺎﻫﺮ ﺻﻔﺤﺎت در ‪ MasterPage‬اﻧﺠﺎم ﺷﺪ‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻬﺘـﺮ اﺳـﺖ اﺑﺘـﺪا ﻛـﺪ‬ ‫ﻫﺎي اﻳﻦ ﻗﺴﻤﺖ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ‪ .‬ﻗﺒﻞ از ﻫﺮ ﭼﻴﺰ رﻧﮓ ﺻﻔﺤﺎت را ﺑﻪ ﺳﻴﺎه ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻴﻢ‪:‬‬ ‫>"‪"‪Font-Size="24px‬‬ ‫>‪‪"‪‪Runat="server" /‬‬ ‫>‪‪‪"‪‪‪"‪‪
‫‪٧٥٩‬‬

Guest, Please log in


‫ در‬،‫ ﻣﺎﻧﻨـﺪ ﻓـﺼﻞ ﻫﻔـﺪﻫﻢ‬.‫ ﻣﻨﻮ ﻫﺎ اﺳﺖ‬،‫ ﻗﺮار دﻫﻴﻢ ﺗﺎ در ﻫﻤﻪ ي ﺻﻔﺤﻪ ﻫﺎ ﻗﺮار ﮔﻴﺮد‬MasterPage ‫ﻗﺴﻤﺖ ﺑﻌﺪي ﻛﻪ ﺑﺎﻳﺪ در‬ ‫ ﺗﻨﻬﺎ ﺗﻔﺎوﺗﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ وﺟﻮد دارد اﻳـﻦ اﺳـﺖ ﻛـﻪ در‬.‫اﻳﻨﺠﺎ ﻧﻴﺰ از ﻣﻨﻮ ﻫﺎ ﺑﺮاي ﺣﺮﻛﺖ در ﺑﻴﻦ ﺻﻔﺤﺎت ﺳﺎﻳﺖ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ‬ ‫ ﻛﻨﺘـﺮل‬.‫اﻳﻦ ﺟﺎ ﭼﻨﺪ ﻛﻨﺘﺮل ﻣﻨﻮ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ و ﺑﺮ ﺣﺴﺐ اﻳﻨﻜﻪ ﻛﺎرﺑﺮ ﺗﻌﻴﻴﻦ ﻫﻮﻳﺖ ﺷﺪه اﺳﺖ ﻳﺎ ﻧﻪ ﻳﻜﻲ از آﻧﻬﺎ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫـﻴﻢ‬ ‫ ﻧﺤﻮه ي ﻧﻤﺎﻳﺶ آن را ﺗﻐﻴﻴـﺮ‬،‫ اﻳﻦ اﻣﻜﺎن را ﻣﻲ دﻫﺪ ﺗﺎ ﺑﺮ ﺣﺴﺐ ﻧﻮع ﻛﺎرﺑﺮي ﻛﻪ در ﺣﺎل ﻣﺸﺎﻫﺪه ي ﺻﻔﺤﻪ اﺳﺖ‬LoginView ‫ و اﮔﺮ ﻛﺎرﺑﺮ ﻳﻜﻲ از اﻋـﻀﺎي ﺳـﺎﻳﺖ‬Create Account ‫ ﻣﻨﻮﻳﻲ ﺑﺎ ﮔﺰﻳﻨﻪ ي‬،‫ ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﻛﺎرﺑﺮ ﻓﺮدي ﻧﺎﺷﻨﺎس ﺑﻮد‬.‫دﻫﻴﻢ‬ .‫ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد‬Change Password ‫ ﻣﻨﻮﻳﻲ ﺑﺎ ﮔﺰﻳﻨﻪ ي‬،‫ﺑﻮد‬


٧٦٠





:‫ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ‬Label ‫ از ﻳﻚ ﻛﻨﺘﺮل‬،‫ﺑﺮاي ﻋﻨﻮان ﻓﺮم‬

‫ در اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ‬.‫ ﻗﺴﻤﺘﻲ را ﻗﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﻧﺎم ﻛﺎرﺑﺮي ﻓﺮدي ﻛﻪ وارد ﺳﻴﺴﺘﻢ ﺷﺪه اﺳﺖ را ﻧﻤﺎﻳﺶ دﻫﻴﻢ‬،‫در زﻳﺮ ﻋﻨﻮان ﻓﺮم‬ ‫ و اﮔﺮ ﻓـﺮدي‬،‫ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ اﮔﺮ ﻛﺎرﺑﺮي در ﺳﺎﻳﺖ وارد ﺷﺪه ﺑﻮد ﻧﺎم ﻛﺎرﺑﺮي او را ﻧﻤﺎﻳﺶ دﻫﺪ‬LoginView ‫از ﻳﻚ ﻛﻨﺘﺮل‬ .‫" را ﻧﻤﺎﻳﺶ دﻫﺪ‬Guest, Please Log in" ‫ﻧﺎﺷﻨﺎس وارد ﺳﻴﺴﺘﻢ ﺷﺪه ﺑﻮد‬ User: Guest, Please log in

‫ اﻳﻦ ﻛﻨﺘﺮل ﻣﻜﺎﻧﻲ را ﻣـﺸﺨﺺ ﻣـﻲ ﻛﻨـﺪ ﺗـﺎ‬.‫ در ﺳﺎﻳﺖ ﻗﺮار ﻣﻲ دﻫﻴﻢ‬ContentPlaceHolder ‫در آﺧﺮ ﻧﻴﺰ ﻳﻚ ﻛﻨﺘﺮل‬ .‫ داده ﻫﺎي ﺧﻮد را در آن ﻗﺮار دﻫﻨﺪ‬،‫ ﺧﻮد اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ‬MasterPage ‫ﺻﻔﺤﺎﺗﻲ ﻛﻪ از اﻳﻦ ﻓﺎﻳﻞ ﺑﻪ ﻋﻨﻮان‬

٧٦١

‫در ﻓﺮم ‪ ،Login‬ﺑﺎ اﺳﺘﻔﺎده از راﻫﻨﻤﺎي ‪ Page‬ﻋﻨﻮان ﺻﻔﺤﻪ را ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻴﻢ و ﻫﻤﭽﻨـﻴﻦ ﻳـﻚ ﻛﻨﺘـﺮل ‪ Content‬اﻳﺠـﺎد‬ ‫ﻛﺮده و آن را ﺑﻪ ﻛﻨﺘﺮل ‪ ContentPlaceHolder‬در ﻓﺎﻳﻞ ‪ MasterPage‬ﻣﺘﺼﻞ ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻜﺎﻧﻲ‬ ‫ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻛﻨﺘﺮل ‪ ContentPlaceHolder‬در ‪ MasterPage‬ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ‪ ،‬ﺗﻮﺳﻂ اﻳﻦ ﻛﻨﺘﺮل ﻧﻴـﺰ‬ ‫ﺗﻌﻴﻴﻦ ﻣﻲ ﺷﻮد و ﻣﻲ ﺗﻮاﻧﻴﻢ ﻣﺤﺘﻮﻳﺎت ﺻﻔﺤﻪ ي ‪ Login‬را در اﻳﻦ ﻗﺴﻤﺖ ﻗﺮار دﻫﻴﻢ‪.‬‬ ‫ﺑﺮاي ﺗﻜﻤﻴﻞ ﺻﻔﺤﻪ ي ‪ Login‬ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ درون اﻳﻦ ﻗﺴﻤﺖ‪ ،‬ﻓﻘﻂ ﻳﻚ ﻛﻨﺘﺮل ‪ Login‬ﻗﺮار دﻫﻴﻢ‪ .‬اﻳﻦ ﻛﻨﺘـﺮل ﺧـﻮد ﺗﻤـﺎم‬ ‫ﻛﺎرﻫﺎي ﻻزم ﺑﺮاي ﻛﻨﺘﺮل ورود ﻛﺎرﺑﺮ را اﻧﺠﺎم ﻣﻲ دﻫﺪ‪:‬‬ ‫>‪<%@ Page Language="C#" MasterPageFile="~/Main.master" Title="Login" %‬‬ ‫>"‪"‪‪‪
‫ﺑﺮاي ﺻﻔﺤﻪ ي ‪ ChangePassword.aspx‬ﻧﻴﺰ ﺑﺎ اﺳﺘﻔﺎده از راﻫﻨﻤﺎي ‪ Page‬ﻋﻨﻮان ﺻﻔﺤﻪ را ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﻴﻢ‪ .‬ﺳﭙﺲ‬ ‫ﻳــﻚ ﻛﻨﺘــﺮل از ﻧــﻮع ‪ Content‬در ﺻــﻔﺤﻪ اﻳﺠــﺎد ﻛــﺮده و آن را ﺑــﻪ ﻛﻨﺘــﺮل ‪ ContentPlaceHolder‬در ﻓﺎﻳــﻞ‬ ‫‪ MasterPage‬ﻣﺘﺼﻞ ﻣﻲ ﻛﻨﻴﻢ‪.‬‬ ‫درون اﻳﻦ ﻛﻨﺘﺮل ‪ Content‬ﻧﻴﺰ ﻓﻘﻂ ﻳﻚ ﻛﻨﺘﺮل از ﻧﻮع ‪ ChangePassword‬ﻗﺮار ﻣﻲ دﻫـﻴﻢ‪ .‬اﻳـﻦ ﻛﻨﺘـﺮل ﻧﻴـﺰ ﺗﻤـﺎم‬ ‫ﻛﺎرﻫﺎي ﻻزم ﺑﺮاي ﺗﻐﻴﻴﺮ ﻛﻠﻤﻪ ي ﻋﺒﻮر ﻳﻚ ﻛﺎرﺑﺮ را اﻧﺠﺎم ﻣﻲ دﻫﺪ‪:‬‬ ‫"‪<%@ Page Language="C#" MasterPageFile="~/Main.master‬‬ ‫>‪Title="Change Password" %‬‬ ‫>"‪"‪‪‪
‫ﻫﻤﻴﻦ ﻣﺮاﺣﻞ را در ﺻﻔﺤﻪ ي ‪ CreateNewUser.aspx‬ﻧﻴﺰ ﺗﻜﺮار ﻣﻲ ﻛﻨـﻴﻢ ﺗـﺎ ﻳـﻚ ﻛﻨﺘـﺮل ‪ Content‬در اﻳـﻦ‬ ‫ﺻﻔﺤﻪ ﻧﻴﺰ اﻳﺠﺎد ﺷﻮد‪ .‬ﺳﭙﺲ درون اﻳـﻦ ﻛﻨﺘـﺮل‪ ،‬ﻳـﻚ ﻛﻨﺘـﺮل از ﻧـﻮع ‪ CreateUserWizard‬ﻗـﺮار ﻣـﻲ دﻫـﻴﻢ‪ .‬ﻛﻨﺘـﺮل‬ ‫‪ CreateUserWizard‬ﺗﻤﺎم ﻛﺎرﻫﺎي ﻻزم ﺑﺮاي اﻳﺠﺎد ﻳﻚ اﻛﺎﻧﺖ ﺟﺪﻳﺪ را اﻧﺠﺎم ﻣﻲ دﻫﺪ‪:‬‬ ‫"‪<%@ Page Language="C#" MasterPageFile="~/Main.master‬‬ ‫>‪Title="Create New Account" %‬‬ ‫>"‪"‪‪‪
‫در ﺳﻪ ﺻﻔﺤﻪ ي دروﻧﻲ ﺑﺮﻧﺎﻣﻪ ﻛﻪ ﻓﻘﻂ اﻋﻀﺎي ﺳﺎﻳﺖ ﺑﻪ آن دﺳﺘﺮﺳﻲ دارﻧﺪ‪ ،‬ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﻛﻨﺘﺮل ﺧﺎﺻﻲ را ﻗﺮار دﻫﻴﻢ‪ .‬ﻓﻘﻂ ﻛـﺎﻓﻲ‬ ‫اﺳﺖ ﻣﺘﻨﻲ را ﻧﻤﺎﻳﺶ دﻫﻴﻢ ﺗﺎ ﻣﺸﺨﺺ ﻛﻨﺪ ﻛﺎرﺑﺮ در ﺣﺎل ﻣﺸﺎﻫﺪه ي ﭼﻪ ﺻـﻔﺤﻪ اي اﺳـﺖ‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ‪ ،‬در اﻳـﻦ ﺻـﻔﺤﺎت ﻧﻴـﺰ ﻫﻤﺎﻧﻨـﺪ‬ ‫ﺻﻔﺤﺎت ﻗﺒﻠﻲ‪ ،‬ﺑﻌﺪ از ﺗﻐﻴﻴﺮ ﻋﻨﻮان ﺻﻔﺤﻪ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺼﻴﺼﻪ ي ‪ title‬در راﻫﻨﻤﺎي ‪ Page‬ﻳـﻚ ﻛﻨﺘـﺮل ‪ Content‬در‬ ‫ﻓﺮم اﻳﺠﺎد ﻛﺮده و آن را ﺑﻪ ﻛﻨﺘﺮل ‪ ContentPlaceHolder‬در ﻓﺎﻳﻞ ‪ MasterPage‬ﻣﺘﺼﻞ ﻣـﻲ ﻛﻨـﻴﻢ‪ .‬ﺳـﭙﺲ‬ ‫ﻳﻚ ﻛﻨﺘﺮل ‪ Label‬در اﻳﻦ ﻛﻨﺘﺮل ‪ Content‬ﻗﺮار ﻣﻲ دﻫﻴﻢ و ﻣﺘﻨﻲ را در آ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ ﺗﺎ ﻣﺸﺨﺺ ﻛﻨﺪ ﻛـﺎرﺑﺮ در ﺣـﺎل‬ ‫ﻣﺸﺎﻫﺪه ي ﭼﻪ ﺻﻔﺤﻪ اي اﺳﺖ‪.‬‬

‫‪٧٦٢‬‬

‫"‪<%@ Page Language="C#" MasterPageFile="~/Main.master‬‬ ‫>‪Title="View Authors" %‬‬ ‫"‪"‪Runat="server‬‬ ‫"‪"‪Text="Add Code to View Author Info Later‬‬ ‫>‪‪"‪Runat="server‬‬ ‫"‪"‪Text="Add Code to View Title Info Later‬‬ ‫>‪‪"‪"‪Text="Add Code to View User Info Later‬‬ ‫>‪‪
‫اﻟﺒﺘﻪ اﺣﺘﻤﺎﻻً ﻣﺘﻮﺟﻪ ﺷﺪه اﻳﺪ ﻛﻪ ﻫﻨﻮز ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺻﻔﺤﻪ ي ‪ ViewUsers.aspx‬دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ و در ﺻﻮرﺗﻲ ﻛـﻪ‬ ‫ﺳﻌﻲ ﻛﻨﻴﺪ وارد اﻳﻦ ﺻﻔﺤﻪ ﺷﻮﻳﺪ‪ ،‬ﻣﺠﺪداً ﺑﻪ ﻓﺮم ‪ Login.aspx‬ﻫﺪاﻳﺖ ﺧﻮاﻫﻴﺪ ﺷﺪ‪ .‬دﻟﻴﻞ اﻳﻦ ﻣﻮرد ﻧﻴﺰ در اﻳـﻦ اﺳـﺖ ﻛـﻪ‪ ،‬در‬ ‫ﻗﺴﻤﺖ ﻗﺒﻠﻲ ﺗﻤﺎم ﺻﻔﺤﺎت ﻣﻮﺟﻮد در ﻓﻮﻟﺪر ‪ Admin‬را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻨﻈﻴﻢ ﻛﺮدﻳﻢ ﻛﻪ ﻓﻘﻂ ﺑـﺮاي ﮔـﺮوه ‪ Admin‬ﻗﺎﺑـﻞ ﻣـﺸﺎﻫﺪه‬ ‫ﺑﺎﺷﺪ‪ .‬اﻛﺎﻧﺖ ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ﺻﻮرت ﻋﺎدي اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ ﻋﻀﻮي از ﮔﺮوه ‪ Admin‬ﻧﻴﺴﺘﻨﺪ و ﺑﺎﻳﺪ آﻧﻬﺎ را ﺑﻪ اﻳﻦ ﮔـﺮوه اﺿـﺎﻓﻪ ﻛـﺮد ﺗـﺎ‬ ‫ﺑﺘﻮاﻧﻨﺪ وارد ﺻﻔﺤﻪ ي ‪ ViewUsers.aspx‬ﺷﻮﻧﺪ‪ .‬در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ‪ ،‬ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧـﻪ ﻣـﻲ ﺗـﻮان‬ ‫ﻳﻜﻲ از اﻛﺎﻧﺖ ﻫﺎي اﻳﺠﺎد ﺷﺪه را ﺑﻪ ﮔﺮوه ‪ Admin‬اﺿﺎﻓﻪ ﻛﺮد‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬ﻣﺪﻳﺮﻳﺖ ﮔﺮوه ﻫﺎ‬ ‫‪ (1‬ﺑﺮاي ﻣﺪﻳﺮﻳﺖ ﮔﺮوه ﻫﺎ و اﻛﺎﻧﺖ ﻫﺎﻳﻲ ﻛﻪ در ﻫﺮ ﻳﻚ از آﻧﻬﺎ ﻗﺮار دارد ﺑﺎﻳﺪ از اﺑﺰار ‪ WAT‬اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑـﺎ اﻧﺘﺨـﺎب‬ ‫ﮔﺰﻳﻨﻪ ي ‪ Website  ASP.NET Configuration‬از ﻧﻮار ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ‪ ،‬ﺻـﻔﺤﻪ ي‬ ‫ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ اﺑﺰار را ﺑﺎز ﻛﻨﻴﺪ‪ .‬در ﺻﻔﺤﻪ ي اوﻟﻴﻪ ي اﻳﻦ اﺑﺰار‪ ،‬روي ﻗـﺴﻤﺖ ‪ Security‬ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ‪ .‬در ﻧﻴﻤـﻪ ي‬ ‫ﭘﺎﻳﻴﻦ اﻳﻦ ﺻﻔﺤﻪ ﺟﺪوﻟﻲ را ﺑﺎ ﻋﻨﻮان ‪ Roles‬ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد‪ .‬در اﻳﻦ ﺟﺪول روي ﮔﺰﻳﻨﻪ ي ‪Create or‬‬ ‫‪ Manage Roles‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ )ﺷﻜﻞ ‪(15-18‬‬

‫‪٧٦٣‬‬

‫ﺷﻜﻞ ‪15-18‬‬ ‫‪ (2‬در ﺻﻔﺤﻪ ي ﺑﻌﺪ‪ ،‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ ‪ 16-18‬ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻟﻴﺴﺘﻲ از ﮔﺮوه ﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ ﺑﺮﻧﺎﻣـﻪ ﻧﻤـﺎﻳﺶ داده‬ ‫ﻣﻲ ﺷﻮد و ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ ﮔﺮوه ﻫﺎي ﺟﺪﻳﺪي اﻳﺠﺎد ﻛﻨﻴﺪ‪ .‬روي ﻟﻴﻨﻚ ‪ Manage‬ﻣﻘﺎﺑﻞ ﮔﺮوه ‪ Admin‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪.‬‬

‫ﺷﻜﻞ ‪16-18‬‬ ‫‪ (3‬روي ﻟﻴﻨﻚ ‪ All‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻧﺎم ﺗﻤﺎم ﻛﺎرﺑﺮان ﻣﻮﺟﻮد در ﺳﻴـﺴﺘﻢ ﻧﻤـﺎﻳﺶ داده ﺷـﻮد‪ .‬در ﻣﻘﺎﺑـﻞ ﻧـﺎم ﻫـﺮ ﻛـﺎرﺑﺮ ﻳـﻚ‬ ‫‪ CheckBox‬وﺟﻮد دارد ﻛﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ آﻳﺎ اﻳﻦ ﻛﺎرﺑﺮ ﻋﻀﻮي از اﻳﻦ ﮔﺮوه ﻫﺴﺖ ﻳﺎ ﻧﻪ؟ ﺑـﺎ اﻧﺘﺨـﺎب اﻳـﻦ ﮔﺰﻳﻨـﻪ‬ ‫ﻛﺎرﺑﺮ ﻋﻀﻮي از اﻳﻦ ﮔﺮوه ﺧﻮاﻫﺪ ﺑﻮد و ﺑﺎ ﺧﺎرج ﻛﺮدن اﻳﻦ ﮔﺰﻳﻨﻪ از ﺣﺎﻟﺖ اﻧﺘﺨﺎب‪ ،‬ﻛﺎرﺑﺮ از اﻳﻦ ﮔﺮوه ﺧﺎرج ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬

‫‪٧٦٤‬‬

‫ﺷﻜﻞ ‪17-18‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﺑﺎ ﺗﻐﻴﻴﺮاﺗﻲ ﻛﻪ در ﻣﺮﺣﻠﻪ ي ﻗﺒﻞ در ﻓﻮﻟﺪر ‪ Admin‬اﻳﺠﺎد ﻛﺮدﻳﻢ‪ ،‬ﻓﻘﻂ اﻓﺮادي ﻛﻪ ﻋـﻀﻮ ﮔـﺮوه ‪ Admin‬ﺑﻮدﻧـﺪ ﻣـﻲ ﺗﻮاﻧـﺴﺘﺪ ﺑـﻪ‬ ‫ﺻﻔﺤﺎت اﻳﻦ ﻓﻮﻟﺪر دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ‪ .‬ﻛﺎرﺑﺮاﻧﻲ ﻧﻴﺰ ﻛﻪ ﺑﻪ ﺻﻮرت ﻋﺎدي اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ ﻋﻀﻮ اﻳﻦ ﮔﺮوه ﻧﺨﻮاﻫﻨﺪ ﺑﻮد‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳـﺪ‬ ‫ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ اﺑﺰار‪ ،‬ﻛﺎرﺑﺮان ﻣﻮرد ﻧﻈﺮ را در اﻳﻦ ﮔﺮوه ﻗﺮار داد و ﻳﺎ از اﻳﻦ ﮔﺮوه ﺧﺎرج ﻛﺮد‪ .‬ﻫﻨﮕﺎﻣﻲ ﻛﻪ در اﻳﻦ ﻗـﺴﻤﺖ ﻧـﺎم ﻛـﺎرﺑﺮي‬ ‫ﺧﻮد را ﺑﻪ ﻋﻨﻮان ﻋﻀﻮي از ﮔﺮوه ‪ Admin‬ﻣﺸﺨﺺ ﻛﺮدﻳﺪ‪ ،‬ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻣﺤﺘﻮﻳﺎت ﻓﻮﻟﺪر ‪ Admin‬دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ‪.‬‬

‫ﻧﺘﻴﺠﻪ‪:‬‬ ‫در اﻳﻦ ﻓﺼﻞ ﺳﻌﻲ ﻛﺮدﻳﻢ ﺑﺎ ﺳﺎﺧﺘﺎر وب ﺳﺎﻳﺘﻬﺎي اﻣﻦ و ﻧﻴﺰ ﻛﺎرﺑﺮدي آﺷﻨﺎ ﺷﻮﻳﻢ‪ .‬در ﺑﺮﻧﺎﻣﻪ ﻫﺎي اﻳﻦ ﻓﺼﻞ ﻧﻴﺰ ﺑﺎ اﺳﺘﻔﺎده از ﻣﻄﺎﻟﺒﻲ ﻛﻪ‬ ‫در ﻓﺼﻞ ﻫﻔﺪﻫﻢ آﻣﻮﺧﺘﻪ ﺑﻮدﻳﻢ و ﻧﻴﺰ ﺗﻌﺪادي از ﻛﻨﺘﺮﻟﻬﺎي دروﻧﻲ ‪ ASP.NET 2‬ﺗﻮاﻧﺴﺘﻴﻢ ﺑﺪون ﻧﻮﺷﺘﻦ ﺣﺘﻲ ﻳﻚ ﺧـﻂ ﻛـﺪ ﻳـﻚ‬ ‫ﺳﺎﻳﺖ وب ﻛﺎرﺑﺮدي اﻳﺠﺎد ﻛﻨﻴﻢ‪ .‬اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ ﺣﺘﻲ ﻧﻴﺎز ﺑﻪ ﺗﻨﻈﻴﻢ ﺧﺼﻮﺻﻴﺖ ﺧﺎﺻﻲ ﻧﻴﺰ ﻧﺪاﺷﺘﻨﺪ و ﻣﻘﺎدﻳﺮ ﭘﻴﺶ ﻓﺮض آﻧﻬﺎ ﺑـﻪ ﺧـﻮﺑﻲ‬ ‫ﻋﻤﻞ ﻣﻲ ﻛﺮد‪.‬‬ ‫در اﺑﺘﺪاي ﻓﺼﻞ ﺑﺎ اﻧﻮاع ﻣﺨﺘﻠﻒ ﺗﻌﻴﻴﻦ ﻫﻮﻳﺖ ﻛﺎرﺑﺮان آﺷﻨﺎ ﺷﺪﻳﻢ و ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ ﻛﻪ ﻫﺮ ﻳﻚ از آﻧﻬـﺎ در ﭼـﻪ ﺷـﺮاﻳﻄﻲ ﻛـﺎرﺑﺮد دارﻧـﺪ‪.‬‬ ‫ﺳﭙﺲ ﺑﺎ اﺑﺰار ‪ WAT‬و ﻧﺤﻮه ي اﺳﺘﻔﺎده از آن آﺷﻨﺎ ﺷﺪﻳﻢ و ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از آن اﻣﻨﻴﺖ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠـﻒ‬ ‫ﻳﻚ ﺳﺎﻳﺖ را‪ ،‬ﭼﻪ ﺑﺎ اﺳﺘﻔﺎده از روش ﺗﻌﻴﻴﻦ ﻫﻮﻳﺖ ﺑﻪ وﺳﻴﻠﻪ ي وﻳﻨﺪوز و ﭼﻪ ﺑﺎ اﺳﺘﻔﺎده از روش ﺗﻌﻴﻴﻦ ﻫﻮﻳﺖ ﺑﻪ وﺳـﻴﻠﻪ ي ﻓـﺮم ﻫـﺎي‬ ‫وب ﺗﺎﻣﻴﻦ ﻛﺮد‪.‬‬ ‫در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ‪:‬‬ ‫‬ ‫‬

‫از اﺑﺰار ﻣﺪﻳﺮﻳﺖ وب ﺳﺎﻳﺖ )‪ (WAT‬اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬ ‫ﻗﺎﻟﺐ و اﺳﺘﻴﻞ ﺻﻔﺤﺎت وب ﻣﺮﺑﻮط ﺑﻪ ﺳﺎﻳﺖ را ﺑﺎ اﺳﺘﻔﺎده از ‪ MasterPage‬ﻫﺎ اﻳﺠﺎد ﻛﻨﻴﺪ‪.‬‬

‫‪٧٦٥‬‬

‫‬ ‫‬ ‫‬

‫ﺑﺎ اﺳﺘﻔﺎده از روش ﺗﻌﻴﻴﻦ ﻫﻮﻳﺖ ﺑﻪ وﺳﻴﻠﻪ ي ﻓﺮﻣﻬﺎي وﻳﻨﺪوزي‪ ،‬اﻣﻨﻴﺖ ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﻳﻚ ﺳﺎﻳﺖ را ﺗﺎﻣﻴﻦ ﻛﻨﻴﺪ‪.‬‬ ‫ﺑﺎ ﺗﻌﺮﻳﻒ ﮔﺮوه ﻫﺎي ﻣﺨﺘﻠﻒ در ﺳﺎﻳﺖ‪ ،‬ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻛﻪ اﻋﻀﺎي ﻫﺮ ﮔﺮوه ﺑﻪ ﭼﻪ ﻗﺴﻤﺘﻬﺎﻳﻲ از ﺳﺎﻳﺖ دﺳﺘﺮﺳﻲ دارﻧﺪ‪.‬‬ ‫از ﻛﻨﺘﺮﻟﻬﺎي دروﻧﻲ ‪ ASP.NET 2‬ﺑﺮاي ‪ Login‬اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬

‫ﺗﻤﺮﻳﻦ‪:‬‬

‫ﺗﻤﺮﻳﻦ ‪:1‬‬ ‫ﺑﺎ اﺳﺘﻔﺎده از ﻓﺎﻳﻞ ‪ ،Main.skin‬رﻧﮓ ﻓﻮﻧﺖ ﺗﻤﺎم ﻛﻨﺘﺮﻟﻬﺎي ‪ Label‬اي ﻛﻪ در ﺻﻔﺤﺎت ﻓﻮﻟﺪر ‪ Members‬ﻗﺮار دارﻧـﺪ را‬ ‫ﺑﺮاﺑــﺮ ﺑــﺎ ﻗﺮﻣــﺰ ﻗــﺮار دﻫﻴــﺪ‪ .‬ﺑــﺮاي اﻳــﻦ ﻛــﺎر ﻣــﻲ ﺗﻮاﻧﻴــﺪ ﺧﺎﺻــﻴﺖ ‪ Theme‬در ﺗﻤــﺎم ﺻــﻔﺤﺎت را ﺗﻐﻴﻴــﺮ دﻫﻴــﺪ و ﻳــﺎ از ﻓﺎﻳــﻞ‬ ‫‪ web.config‬ﻛــﻪ در ﻓﻮﻟــﺪر ‪ Members‬ﻗــﺮار دارد اﺳــﺘﻔﺎده ﻛﻨﻴــﺪ‪ .‬ﺑــﺮاي اﻳــﻦ ﺗﻤــﺮﻳﻦ ﺑﻬﺘــﺮ اﺳــﺖ ﻛــﻪ از ﻓﺎﻳــﻞ‬ ‫‪ Web.config‬اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ .‬ﺑﻪ ﻋﻨﻮان راﻫﻨﻤﺎﻳﻲ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻌﺪ از ﺑﺎز ﻛﺮدن ﻓﺎﻳﻞ‪ ،‬داﺧﻞ آن را ﺑﻪ ﺻﻮرﺗﻲ ﻛﻪ در ﻛﺪ ‪ XML‬زﻳﺮ‬ ‫ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪:‬‬ ‫>?"‪"‪xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0‬‬ ‫>‪<system.web‬‬ ‫>‪<pages theme="MainTheme"/‬‬ ‫>‪‪<deny users="?" /‬‬ ‫>‪‪‪
‫ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ‪ ،‬ﻇﺎﻫﺮ اﻳﻦ ﺻﻔﺤﺎت ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ ‪ 18-18‬ﺷﻮد‪:‬‬

‫ﺷﻜﻞ ‪18-18‬‬ ‫‪٧٦٦‬‬

‫ﻓﺼﻞ ﻧﻮزدﻫﻢ‪ XML :‬و وﻳﮋوال ‪2005 C#‬‬ ‫اﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﺑﻪ زﺑﺎن ﺳﺎده ﺗﻌﺮﻳﻔﻲ از ‪ XML‬ﻋﻨﻮان ﻛﻨﻴﻢ‪ ،‬ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﮕـﻮﻳﻴﻢ ﻛـﻪ ‪ XML‬ﻳـﺎ ‪Extensible Markup‬‬ ‫‪Language‬ﺑﺮاي اﻧﺘﻘﺎل اﻃﻼﻋﺎت ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد‪ .‬اﮔﺮ ﭼﻪ ﻣﻤﻜﻦ اﺳﺖ در آﻳﻨﺪه اﻳﻦ اﺗﻔﺎق رخ دﻫﺪ‪ ،‬اﻣـﺎ‬ ‫ﻓﻌﻼ ‪ XML‬ﺑﻪ ﺻﻮرت ﻏﻴﺮ رﺳﻤﻲ ﺑﻪ ﻋﻨﻮان اﺳﺘﺎﻧﺪاردي ﺑﺮاي اﻧﺘﻘﺎل اﻃﻼﻋﺎت ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴـﺮد‪.‬‬ ‫اﻣﺮوزه ﻧﻪ ﺗﻨﻬﺎ ‪ XML‬ﺑﺮاي اﻧﺘﻘﺎل اﻃﻼﻋﺎت ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد‪ ،‬ﺑﻠﻜﻪ ﺑﺮاي اﻧﺘﻘﺎل داده ﻫﺎ ﺑﻴﻦ ﭘﻠـﺖ‬ ‫ﻓﺮم ﻫﺎ و ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻫﺎي ﻣﺨﺘﻠﻒ ﻧﻴﺰ از آن اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد‪.‬‬ ‫در اﻳﻦ ﻓﺼﻞ ﻧﻤﻲ ﺧﻮاﻫﻴﻢ وارد ﺟﺰﺋﻴﺎت و ﻣﺒﺎﺣﺚ ﭘﻴﭽﻴﺪه ي زﺑﺎن ‪ XML‬ﺷﻮﻳﻢ و ﻓﻘﻂ ﺑﻪ ﻣﻌﺮﻓﻲ ﻛﻠﻲ آن و ﺑﻴﺎن راﺑﻄﻪ ي اﻳﻦ زﺑﺎن ﺑـﺎ‬ ‫وﻳﮋوال ‪ 2005 C#‬اﻛﺘﻔﺎ ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﺑﻌﺪ از آن ﻧﻴﺰ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﻧﺤﻮه ي اﺳﺘﻔﺎده از ‪ XML‬در ﺑﺮﻧﺎﻣﻪ ﻫﺎ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ‪.‬‬ ‫در اﻳﻦ ﻓﺼﻞ‪:‬‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬

‫ﺑﺎ ﻣﻔﻬﻮم ‪ XML‬آﺷﻨﺎ ﻣﻲ ﺷﻮﻳﻢ‪.‬‬ ‫ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻓﺎﻳﻠﻬﺎي ‪ XML‬را ﺧﻮاﻧﺪ و ﻳﺎ ﻧﻮﺷﺖ‪.‬‬ ‫ﻧﺤﻮه ي ﺳﺮﻳﺎﻻﻳﺰ ﻛﺮدن و دي ﺳﺮﻳﺎﻻﻳﺰ ﻛﺮدن ﻓﺎﻳﻠﻬﺎي ‪ XML‬را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد‪.‬‬ ‫ﺑﺎ ﭼﮕﻮﻧﮕﻲ ﺣﺮﻛﺖ در ﺑﻴﻦ ﻳﻚ ﻓﺎﻳﻞ ‪ XML‬آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ‪.‬‬ ‫ﺑﺎ ﻧﺤﻮه ي ﺗﻐﻴﻴﺮ داده ﻫﺎي ‪ XML‬ﻣﻮﺟﻮد و ﻳﺎ اﺿﺎﻓﻪ ﻛﺮدن داده اي ﺑﻪ ﻳﻚ ﻓﺎﻳﻞ ‪ XML‬آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ‪.‬‬

‫درك ‪:XML‬‬ ‫دﻟﻴﻞ اﻳﻨﻜﻪ ﭼﺮا ﺑﻪ ‪ XML‬ﻧﻴﺎز دارﻳﻢ ﺑﺴﻴﺎر ﺳﺎده اﺳﺖ‪ .‬در ﻣﺤﻴﻂ ﻫﺎي ﺗﺠﺎري‪ ،‬ﺑﺮاي اﻳﻨﻜﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﺘﻮاﻧﻨﺪ ﺑﺎ ﻳﻜﺪﻳﮕﺮ راﺑﻄﻪ ﺑﺮﻗﺮار ﻛﻨﻨﺪ‬ ‫ﻻزم اﺳﺖ ﻛﻪ ﺑﺘﻮاﻧﻨﺪ داده ﻫﺎ را ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﻣﺒﺎدﻟﻪ ﻛﻨﻨﺪ‪ .‬اﻳﻦ ﺑﺮﻗﺮاري ارﺗﺒﺎط ﺑﻴﻦ ﻧﺮم اﻓﺰارﻫﺎ و ﻳﻜﭙﺎرﭼﮕﻲ ﺑﻴﻦ آﻧﻬﺎ‪ ،‬ﺑﻴﺸﺘﺮ در ﻣﻮرد ﺑﺮﻧﺎﻣﻪ‬ ‫ﻫﺎي ﺗﺠﺎري آن ﺷﺮﻛﺖ ﻣﻮرد ﻧﻈﺮ اﺳﺖ ﻧﻪ ﻧﺮم اﻓﺰارﻫﺎي ﻣﻌﻤﻮﻟﻲ ﻛﻪ در آﻧﺠﺎ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد ﻣﺎﻧﻨﺪ آﻓﻴﺲ و ﻳـﺎ …‪ .‬ﺑـﺮاي ﻣﺜـﺎل ﻳـﻚ‬ ‫ﺷﺮﻛﺖ ﻣﻤﻜﻦ اﺳﺖ ﻧﺮم اﻓﺰاري داﺷﺘﻪ ﺑﺎﺷﺪ ﻛﻪ ﺗﻌﺪاد ﻛﺎﻻﻫﺎﻳﻲ ﻛﻪ در اﻧﺒﺎر وﺟﻮد دارﻧﺪ را ﻛﻨﺘﺮل ﻣﻲ ﻛﻨﺪ‪ .‬اﻳﻦ ﻧﺮم اﻓـﺰار ﻳـﻚ ﻧﻤﻮﻧـﻪ از‬ ‫ﻧﺮم اﻓﺰارﻫﺎي ﺗﺠﺎري اﺳﺖ ﻛﻪ در آن ﺷﺮﻛﺖ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد‪.‬‬ ‫اﻳﺠﺎد ﻳﻜﭙﺎرﭼﮕﻲ ﺑﻴﻦ ﻧﺮم اﻓﺰارﻫﺎي ﺗﺠﺎري ﺷﺮﻛﺘﻬﺎي ﻣﺨﺘﻠﻒ اﻣﺮ ﺑﺴﻴﺎر ﻣﺸﻜﻠﻲ اﺳﺖ‪ ،‬و ‪ XML‬ﺑﻪ ﻫﻤﺮاه ﺗﻜﻨﻮﻟـﻮژي دﻳﮕـﺮي ﺑـﻪ ﻧـﺎم‬ ‫ﺳﺮوﻳﺴﻬﺎي وب )ﻛﻪ در ﻓﺼﻞ ﺑﻴﺴﺘﻢ در راﺑﻄﻪ ﺑﺎ آﻧﻬﺎ ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد( ﺑﻪ اﻳﻦ ﻣﻨﻈﻮر ﻃﺮاﺣﻲ ﺷﺪه اﻧﺪ ﻛﻪ ﻫﺰﻳﻨـﻪ و ﻧﻴـﺰ ﻣـﺸﻜﻼت‬ ‫ﺑﺮﻗﺮاري ﻳﻜﭙﺎرﭼﮕﻲ ﺑﻴﻦ اﻳﻦ ﻧﺮم اﻓﺰارﻫﺎ را رﻓﻊ ﻛﻨﻨﺪ‪ .‬ﺑﺮاي ﻛﺎﻫﺶ ﻫﺰﻳﻨﻪ و ﻣﺸﻜﻼت اﻳﻦ ﻛﺎر ﻧﻴﺰ‪ ،‬اول ﺑﺎﻳﺪ ﻛـﺎري ﻛـﺮد ﻛـﻪ داده ﻫـﺎ و‬ ‫اﻃﻼﻋﺎت ﺑﺘﻮاﻧﻨﺪ ﺑﻪ ﺳﺎدﮔﻲ ﺑﻴﻦ اﻳﻦ ﻧﺮم اﻓﺰارﻫﺎ ﻣﻨﺘﻘﻞ ﺷﻮﻧﺪ‪.‬‬ ‫ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﺷﻤﺎ ﻳﻚ ﻓﺮوﺷﻨﺪه ي ﺟﺰﺋﻲ ﻗﻬﻮه ﻫﺴﺘﻴﺪ و ﻣﻲ ﺧﻮاﻫﻴﺪ اﺟﻨﺎس ﻣﻮرد ﻧﻴﺎز ﺧﻮد را ﺑﻪ ﻳـﻚ ﻓﺮوﺷـﻨﺪه ي ﻛﻠـﻲ‬ ‫ﺳﻔﺎرش دﻫﻴﺪ‪ .‬ﻳﻚ روش ﻗﺪﻳﻤﻲ ﺑﺮاي اﻧﺠﺎم اﻳﻦ ﻛﺎر اﻳﻦ اﺳﺖ ﻛﻪ از ﺗﻠﻔﻦ و ﻳﺎ ﻓﻜﺲ ﺑﺮاي ﺳﻔﺎرش ﺧـﻮد اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ‪ .‬اﻣـﺎ در اﻳـﻦ‬ ‫روش‪ ،‬ﺣﺘﻤﺎً ﺑﺎﻳﺪ اﻧﺴﺎن دﺧﺎﻟﺖ داﺷﺘﻪ ﺑﺎﺷﺪ‪ .‬ﻣﻤﻜﻦ اﺳﺖ ﻧﺮم اﻓﺰاري ﻛﻪ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ ﺑﺘﻮاﻧﺪ زﻣﺎن ﺗﻤﺎم ﺷﺪن ﻳﻚ ﻣﺤﺼﻮل را اﻋﻼم‬ ‫ﻛﻨﺪ و ﺑﻪ ﺷﻤﺎ ﭘﻴﺸﻨﻬﺎد ﺑﺪﻫﺪ ﻛﻪ آن ﻣﺤﺼﻮل را ﺳﻔﺎرش دﻫﻴﺪ‪ .‬ﺣﺘﻲ ﻣﻤﻜﻦ اﺳﺖ ﻳﻚ ﻓﺮم ﺳﻔﺎرش ﺑﺮاي ﺷﻤﺎ آﻣﺎده ﻛﻨﺪ و ﻓﻘﻂ ﺷـﻤﺎ آن‬ ‫را ﺑﻪ ﻓﺮوﺷﻨﺪه ي ﻛﻠﻲ ﻣﺤﺼﻮﻻت ارﺳﺎل ﻛﻨﻴﺪ‪ .‬در اﻳﻦ ﺣﺎﻟﺖ‪ ،‬در دﻓﺘﺮ ﻓﺮوﺷﻨﺪه ي ﻛﻠﻲ ﻧﻴﺰ ﺑﺎﻳـﺪ ﻓـﺮدي ﻗـﺮار داﺷـﺘﻪ ﺑﺎﺷـﺪ ﺗـﺎ ﺑﺘﻮاﻧـﺪ‬ ‫درﺧﻮاﺳﺖ ﺷﻤﺎ را درﻳﺎﻓﺖ ﻛﺮده و آن را ﺑﻪ ﻧﺮم اﻓﺰار ﻣﻮرد اﺳﺘﻔﺎده ي ﺧﻮدﺷﺎن ﺑﺪﻫﺪ ﺗﺎ ﻛﺎﻻي ﻣﻮرد ﻧﻈﺮ ﺑﺮاي ﺷﻤﺎ ارﺳﺎل ﺷﻮد‪.‬‬ ‫ﻳﻚ راه دﻳﮕﺮ ﺑﺮاي اﻧﺠﺎم اﻳﻦ ﻛﺎر ﺑﻪ اﻳﻦ ﺻﻮرت ﺳﺖ ﻛﻪ زﻣﺎﻧﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ي ﺗﺠﺎري ﺷﻤﺎ ﻛﺎﻫﺶ ﻣﺤﺼﻮﻟﻲ را در اﻧﺒـﺎر ﺗـﺸﺨﻴﺺ داد‪،‬‬ ‫درﺧﻮاﺳﺘﻲ را آﻣﺎده ﻛﺮده و آن را ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﺑﻪ ﻧﺮم اﻓﺰار ﻓﺮوﺷﻨﺪه ي ﻛﻠﻲ ارﺳﺎل ﻛﻨﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎر ﻫﻢ ﺑﺮاي ﺷﻤﺎ و ﻫـﻢ‬ ‫ﺑﺮاي ﻓﺮوﺷﻨﺪه ﺳﺎده ﺗﺮ و ﻛﺎرآﻣﺪ ﺗﺮ ﺧﻮاﻫﺪ ﺷﺪ‪ .‬اﻣﺎ ﺑﺮاي اﻧﺠﺎم اﻳﻦ ﻛﺎر ﻧﻴﺰ ﻻزم اﺳﺖ ﻛﻪ ﺷﻤﺎ ﺑﺎ ﺷﺮﻛﺖ ﻓﺮوﺷـﻨﺪه ي ﻛﻠـﻲ ﻣـﺬاﻛﺮات و‬

‫‪٧٦٧‬‬

‫ﻫﻤﺎﻫﻨﮕﻲ ﻫﺎي ﻻزم را اﻧﺠﺎم دﻫﺪ و ﻧﻴﺰ ﻫﺰﻳﻨﻪ ﻫﺎﻳﻲ را در اﻳﻦ ﻣﻴﺎن ﻣﺘﺤﻤﻞ ﺷﻮﻳﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ اﻳﻦ ﻣﻮرد ﻓﻘﻂ ﺑـﺮاي ﺷـﺮﻛﺘﻬﺎﻳﻲ ﻣﻨﺎﺳـﺐ‬ ‫اﺳﺖ ﻛﻪ ﺗﻌﺎﻣﻞ زﻳﺎدي ﺑﺎ ﻳﻜﺪﻳﮕﺮ دارﻧﺪ‪.‬‬ ‫اﻟﺒﺘﻪ اﻳﻦ ﻣﻮرد ﻧﻴﺰ ﻗﺒﻞ از اﻳﻨﺘﺮﻧﺖ ﺻﺎدق ﺑﻮد‪ .‬در آن زﻣﺎن ﺑﺮاي اﻳﻨﻜﻪ دو ﺷﺮﻛﺖ ﺑﺘﻮاﻧﻨﺪ از اﻳﻦ روش ﺑﺎ ﻳﻜـﺪﻳﮕﺮ ﺗﻌﺎﻣـﻞ داﺷـﺘﻪ ﺑﺎﺷـﻨﺪ‪،‬‬ ‫ﻻزم ﺑﻮد ﻛﻪ ﻣﺬاﻛﺮات زﻳﺎدي را اﻧﺠﺎم ﻣﻲ دادﻧﺪ و ﺑﻌﺪ از ﻣﺸﺨﺺ ﻛﺮدن ﺗﻤﺎم ﺷﺮاﻳﻂ ﻳﻚ اﺗﺼﺎل اﺧﺘﺼﺎﺻﻲ ﺑﻴﻦ اﻳﻦ دو ﺷﺮﻛﺖ ﺑﺮﻗـﺮار‬ ‫ﻣﻲ ﻛﺮدﻧﺪ‪ .‬ﺑﻌﺪ از اﻳﻨﻜﻪ اﻳﻦ اﺗﺼﺎل ﺑﻴﻦ اﻳﻦ دو ﺷﺮﻛﺖ ﺑﺮﻗﺮار ﻣﻲ ﺷﺪ‪ ،‬ﻧـﻪ ﺗﻨﻬـﺎ ﺷـﺮﻛﺖ ﺧﺮﻳـﺪار ﻣـﻲ ﺗﻮاﻧـﺴﺖ داده ﻫـﺎي ﻣﺮﺑـﻮط ﺑـﻪ‬ ‫ﺳﻔﺎرﺷﺎت ﺧﻮد را ﺑﻪ ﺷﺮﻛﺖ ﻓﺮوﺷﻨﺪه ﺑﻔﺮﺳﺘﺪ‪ ،‬ﺑﻠﻜﻪ ﺷﺮﻛﺖ ﻓﺮوﺷﻨﺪه ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺴﺖ ﻛﻪ ﮔﺰارﺷﺎت ﻣﺮﺑﻮط ﺑـﻪ وﺿـﻌﻴﺖ ﺳـﻔﺎرش را ﺑـﻪ‬ ‫ﺧﺮﻳﺪار ارﺳﺎل ﻛﻨﺪ‪ .‬اﻣﺮوزه ﺑﺎ اﺳﺘﻔﺎده از اﻳﻨﺘﺮﻧﺖ ﻣﺸﻜﻞ ﺑﺮﻗﺮاري اﺗﺼﺎل اﺧﺘﺼﺎﺻﻲ ﺑﻴﻦ دو ﺷﺮﻛﺖ رﻓﻊ ﺷﺪه اﺳﺖ‪ ،‬زﻳﺮا اﮔﺮ ﻫﺮ دوي آﻧﻬﺎ‬ ‫ﺑﻪ اﻳﻨﺘﺮﻧﺖ ﻣﺘﺼﻞ ﺑﺎﺷﻨﺪ ﻣﻲ ﺗﻮاﻧﻨﺪ داده ﻫﺎي ﻻزم را ﺑﻪ ﻳﻜﺪﻳﮕﺮ ﻣﻨﺘﻘﻞ ﻛﻨﻨﺪ‪.‬‬ ‫اﻟﺒﺘﻪ اﻳﻦ ﻓﻘﻂ ﻧﻴﻤﻲ از ﻣﺸﻜﻞ ﺑﻮد‪ .‬ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ زﺑﺎن ﻋﻤﻮﻣﻲ ﺑﺮاي اﻧﺘﻘﺎل داده ﻫﺎ ﺑﻴﻦ ﻧﺮم اﻓﺰارﻫﺎي ﻣﺨﺘﻠﻒ ﻧﺒﺎﺷﺪ‪ ،‬ﻫﻨـﻮز ﻧﻴﻤـﻪ ي‬ ‫دﻳﮕﺮ ﻣﺸﻜﻞ ﺣﻞ ﻧﺸﺪه ﺑﺎﻗﻲ ﻣﻲ ﻣﺎﻧﺪ‪ .‬اﻳﻦ زﺑﺎن ﻋﻤﻮﻣﻲ ‪ XML‬اﺳﺖ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺷﺮﻛﺖ ﺧﺮﻳﺪار‪ ،‬ﻳـﻚ ﺳـﻨﺪ ‪ XML‬اﻳﺠـﺎد ﻛـﺮده و‬ ‫اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﺳﻔﺎرش ﺧﻮد را در آن ﻗﺮار ﻣﻲ دﻫﺪ‪ .‬ﺳﭙﺲ اﻳﻦ ﺷﺮﻛﺖ ﻣﻲ ﺗﻮاﻧﺪ ﺳﻨﺪ ‪ XML‬ﺧﻮد را ﺑﻪ وﺳـﻴﻠﻪ ي اﻳﻤﻴـﻞ و ﻳـﺎ ﺑـﻪ‬ ‫وﺳﻴﻠﻪ ي ﻳﻚ ﺳﺮوﻳﺲ وب از ﻃﺮﻳﻖ اﻳﻨﺘﺮﻧﺖ ﺑﻪ ﻧﺮم اﻓﺰاري ﻛﻪ در ﺷﺮﻛﺖ ﻓﺮوﺷﻨﺪه ﻗﺮار دارد ﺑﺪﻫﺪ‪ .‬ﺳﭙﺲ ﺷـﺮﻛﺖ ﺧﺮﻳـﺪار اﻳـﻦ ﻓﺎﻳـﻞ‬ ‫‪ XML‬را درﻳﺎﻓﺖ ﻛﺮده‪ ،‬داده ﻫﺎي آن را اﺳﺘﺨﺮاج ﻣﻲ ﻛﻨﺪ و ﻛﺎﻻﻫﺎي ﺳﻔﺎرش داده ﺷﺪه را ارﺳﺎل ﻣﻲ ﻛﻨﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ اﮔﺮ ﻻزم ﺑﺎﺷﺪ ﻛﻪ‬ ‫ﺷﺮﻛﺖ ﻓﺮوﺷﻨﺪه‪ ،‬ﮔﺰارﺷﻲ را ﺑﻪ ﺷﺮﻛﺖ ﺧﺮﻳﺪار ارﺳﺎل ﻛﻨﺪ ﻳﻚ ﺳﻨﺪ ‪ XML‬دﻳﮕﺮ اﻳﺠﺎد ﻛﺮده‪ ،‬داده ﻫﺎي ﻻزم را در آن ﻗﺮار ﻣﻲ دﻫـﺪ و‬ ‫ﻣﺠﺪداً ﺑﺎ اﺳﺘﻔﺎده از اﻳﻨﺘﺮﻧﺖ آن را ﺑﻪ ﻧﺮم اﻓﺰار ﻣﻮﺟﻮد در ﺷﺮﻛﺖ ﺧﺮﻳﺪار ارﺳﺎل ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﺳﺎﺧﺘﺎر و اﻟﮕﻮﻳﻲ ﻛﻪ ﺑﺎﻳﺪ ﺑﺮاي اﻳﺠﺎد ﻓﺎﻳﻠﻬﺎي ‪ ،XML‬ﺑﻴﻦ ﺧﺮﻳﺪار و ﻓﺮوﺷﻨﺪه ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد ﺑـﻪ ﺧـﻮد آﻧﻬـﺎ ﺑـﺴﺘﮕﻲ دارد‪ .‬ﺑـﻪ‬ ‫ﻋﺒﺎرت دﻳﮕﺮ اﻳﻦ ﺷﺮﻛﺖ ﺧﻮد ﻣﻲ ﺗﻮاﻧﻨﺪ ﺗﺼﻤﻴﻢ ﺑﮕﻴﺮﻧﺪ ﻛﻪ داده ﻫﺎ را ﺑﻪ ﭼﻪ ﺻﻮرت در ﻳﻚ ﻓﺎﻳﻞ ‪ XML‬ﻗﺮار دﻫﻨﺪ ﺗﺎ ﻧﺮم اﻓﺰارﻫﺎي ﻫﺮ‬ ‫دو ﺷﺮﻛﺖ آن را درك ﻛﻨﺪ‪ .1‬ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ اﺳﺖ ﻛﻪ زﺑﺎن ‪ XML‬ﺑﻪ ﻋﻨﻮان ﻳﻚ زﺑـﺎن ﺗﻮﺳـﻌﻪ ﭘـﺬﻳﺮ )‪ (eXtensible‬ﺷـﻨﺎﺧﺘﻪ‬ ‫ﺷﺪه اﺳﺖ‪ .‬ﻫﺮ دو ﺷﺮﻛﺘﻲ ﻛﻪ ﺑﺨﻮاﻫﻨﺪ داده ﻫﺎﻳﻲ را ﺑﺎ اﺳﺘﻔﺎده از ‪ XML‬ﺑﻴﻦ ﺧﻮد ﻣﺒﺎدﻟﻪ ﻛﻨﻨﺪ‪ ،‬در ﻣـﻮرد اﻟﮕـﻮي ﻗـﺮار دادن داده ﻫـﺎ در‬ ‫ﻓﺎﻳﻞ ‪ XML‬و اﻳﻨﻜﻪ ﻣﻲ ﺧﻮاﻫﻨﺪ ﻓﺎﻳﻞ ‪ XML‬آﻧﻬﺎ ﺑﻪ ﭼﻪ ﺻﻮرﺗﻲ ﺑﺎﺷﺪ ﻛﺎﻣﻼً ﻣﺨﺘﺎر ﻫﺴﺘﻨﺪ‪.‬‬ ‫اﻟﺒﺘﻪ اﻳﻦ ﻣﻮرد زﻳﺎد ﺷﮕﻔﺖ اﻧﮕﻴﺰ ﻧﻴﺴﺖ‪ ،‬ﺷﺮﻛﺘﻬﺎي ﺑﺴﻴﺎري در ﮔﺬﺷﺘﻪ و ﺣﺘﻲ اﻣﺮوز ﻧﻴﺰ ﺑﺮاي اﻧﺘﻘﺎل اﻃﻼﻋﺎت ﺑﻴﻦ ﺧﻮد از ﻓﺎﻳﻠﻬﺎي ﻣﺘﻨﻲ‬ ‫اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ‪ .‬ﻧﺤﻮه ي ﻗﺮار ﮔﻴﺮي اﻃﻼﻋﺎت در اﻳﻦ ﻓﺎﻳﻠﻬﺎي ﻣﺘﻨﻲ ﻧﻴﺰ ﺑﻪ ﺧﻮد اﻳﻦ ﺷﺮﻛﺘﻬﺎ ﺑﺴﺘﮕﻲ دارد‪.‬اﻣﺎ ﻣﻤﻜﻦ اﺳﺖ در اﻳﻨﺠﺎ اﻳﻦ‬ ‫ﺳﻮال ﻣﻄﺮح ﺷﻮد ﻛﻪ ﭘﺲ ‪ XML‬ﭼﻪ ﺧﺎﺻﻴﺘﻲ دارد ﻛﻪ ﻓﺎﻳﻠﻬﺎي ﻣﺘﻨﻲ ﻗﺒﻠﻲ ﻧﺪارﻧﺪ؟‬ ‫ﺧﻮب ‪ XML‬ﺑﺴﻴﺎر ﺗﺸﺮﻳﺤﻲ ﺗﺮ اﺳﺖ و ﺑﻪ راﺣﺘﻲ ﻣﻲ ﺗﻮان ﺗﺸﺤﻴﺺ داد ﻛﻪ آﻳﺎ ﻳﻚ ﻓﺎﻳﻞ ‪ XML‬ﺑﺮ اﺳﺎس ﻳﻚ اﻟﮕـﻮي ﺧـﺎص اﻳﺠـﺎد‬ ‫ﺷﺪه اﺳﺖ ﻳﺎ ﻧﻪ؟ ﻳﻚ اﻟﮕﻮي ‪ XML2‬ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻇﺎﻫﺮ ﻳﻚ ﺳﻨﺪ ‪ XML‬ﺑﺎﻳﺪ ﭼﮕﻮﻧﻪ ﺑﺎﺷﺪ‪ .‬اﻟﺒﺘﻪ ﺑﻮدن ﻳﻚ اﻟﮕـﻮ ﻧﻴـﺰ‪ ،‬ﻳـﻚ‬ ‫ﺳﻨﺪ ‪ XML‬ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ اﻧﺪازه ي ﻛﺎﻓﻲ داده ﻫﺎي درون ﺧﻮد را ﺗﻮﺻﻴﻒ ﻛﻨﺪ ﺗﺎ ﺑﺘﻮان ﺗﺸﺨﻴﺺ داد ﻛﻪ ﭼﻪ اﻃﻼﻋﺎﺗﻲ در آن ﻗﺮار دارﻧـﺪ‪.‬‬ ‫ﻫﻤﭽﻨﻴﻦ ﻓﺎﻳﻠﻬﺎي ‪ ،XML‬ﻣﺎﻧﻨﺪ ﻓﺎﻳﻠﻬﺎﻳﻲ ﻛﻪ در ﮔﺬﺷﺘﻪ اﺳﺘﻔﺎده ﻣﻲ ﺷﺪ از ﻓﺮﻣﺖ ﻣﺘﻨﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻲ ﺗﻮان ﺑـﻪ ﺳـﺎدﮔﻲ‬ ‫ﺑﺮاي اﻧﺘﻘﺎل ﻓﺎﻳﻠﻬﺎي ‪ XML‬ﺑﻴﻦ ﭘﻠﺖ ﻓﺮم ﻫﺎي ﮔﻮﻧﺎﮔﻮن‪ ،‬از ﺗﻜﻨﻮﻟﻮژي ﻫﺎي اﻳﻨﺘﺮﻧﺘﻲ ﻣﺎﻧﻨﺪ اﻳﻤﻴﻞ‪ ،‬وب‪ FTP ،‬و ﻳـﺎ … اﺳـﺘﻔﺎده ﻛـﺮد‪.‬‬ ‫اﺑﺰارﻫﺎﻳﻲ ﻛﻪ در ﮔﺬﺷﺘﻪ ﺑﺮاي اﻳﺠﺎد ﻳﻜﭙﺎرﭼﮕﻲ ﺑﻴﻦ ﻧﺮم اﻓﺰارﻫﺎي ﺗﺠﺎري ﻣﺨﺘﻠﻒ اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻧﺪ‪ ،‬ﻧﻤﻲ ﺗﻮاﻧﺴﺖ ﺑﻪ ﺳﺎدﮔﻲ داده ﻫﺎي‬ ‫ﺑﺎﻳﻨﺮي را ﺑﻴﻦ ﭘﻠﺖ ﻓﺮم ﻫﺎي ﮔﻮﻧﺎﮔﻮن ﻣﺎﻧﻨﺪ ﻟﻴﻨﻮﻛﺲ‪ ،‬وﻳﻨﺪوز‪ ،‬ﻣﻜﻴﻨﺘﺎش‪ OS/390 ،AS/400 ،‬و ﻳﺎ ﺑﺴﻴﺎري از ﭘﻠـﺖ ﻓـﺮم ﻫـﺎي‬ ‫دﻳﮕﺮ ﻣﻨﺘﻘﻞ ﻛﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ اﻳﻦ وﻳﮋﮔﻲ ﻛﻪ اﻃﻼﻋﺎت و داده ﻫﺎي ذﺧﻴﺮه ﺷﺪه در ‪ XML‬در ﻗﺎﻟﺐ ﻣﺘﻦ ﻫﺴﺘﻨﺪ‪ ،‬اﻧﺘﻘﺎل اﻃﻼﻋﺎت ﺑﻴﻦ ﭘﻠـﺖ‬ ‫ﻓﺮم اي ﮔﻮﻧﺎﮔﻮن را ﺑﺴﻴﺎر ﺳﺎده ﺗﺮ ﻣﻲ ﻛﻨﺪ‪.‬‬

‫‪ XML‬ﺷﺒﻴﻪ ﺑﻪ ﭼﻴﺴﺖ؟‬

‫‪ 1‬اﻟﺒﺘﻪ ﺷﺮﻛﺖ ﻓﺮوﺷﻨﺪه اﻟﮕﻮ و ﻣﺪل ﻓﺎﻳﻞ را ﻣﺸﺨﺺ ﻛﺮده و ﺷﺮﻛﺖ ﺧﺮﻳﺪار ﻧﻴﺰ از آن ﭘﻴﺮوي ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫‪XML Schema‬‬

‫‪2‬‬

‫‪٧٦٨‬‬

‫اﮔﺮ ﻗﺒﻼ ﺗﺠﺮﺑﻪ ي اﺳﺘﻔﺎده از ‪ HTML‬را داﺷﺘﻪ ﺑﺎﺷﻴﺪ‪ ،‬اﺣﺘﻤﺎﻻ زﺑﺎن ‪ XML‬ﻧﻴﺰ ﺑﺮاي ﺗﺎن ﺑﺴﻴﺎر آﺷﻨﺎ ﺧﻮاﻫﺪ ﺑﻮد‪ .‬در ﺣﻘﻴﻘﺖ اﻳﻦ دو زﺑﺎن‬ ‫ﻫﺮ دو از ﻳﻚ زﺑﺎن ﺑﻪ ﻧﺎم ‪ SGML1‬ﺑﻪ وﺟﻮد آﻣﺪه اﻧﺪ‪ .‬از ﺑﺴﻴﺎر ي ﺟﻬﺎت ‪ XML‬ﻳـﻚ زﺑـﺎن ﺑـﻪ ﺷـﻤﺎر ﻧﻤـﻲ رود‪ ،‬ﺑﻠﻜـﻪ ﺷـﺎﻣﻞ ﻳـﻚ‬ ‫ﻣﺠﻤﻮﻋﻪ از ﻗﻮاﻋﺪ اﺳﺖ ﻛﻪ ﻧﺤﻮه ي اﻳﺠﺎد ﻳﻚ ﻓﺎﻳﻞ ﺧﺎص ﺑﺮاي اﻧﺘﻘﺎل اﻃﻼﻋﺎت و داده ﻫﺎ را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ ‪ XML‬ﻳـﻚ‬ ‫ﺗﻜﻨﻮﻟﻮژي ﻣﺴﺘﻘﻞ ﻧﻴﺴﺖ‪ ،‬ﺑﻠﻜﻪ ﺑﺴﻴﺎري از ﺗﻜﻨﻮﻟﻮژي ﻫﺎي دﻳﮕﺮ ﻧﻴﺰ ﻫﺴﺘﻨﺪ ﻛﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻨـﺪ ﺷـﻤﺎ ﭼﮕﻮﻧـﻪ ﻣـﻲ ﺗﻮاﻧﻴـﺪ از ‪XML‬‬ ‫اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ .‬ﺑﻌﻀﻲ از آﻧﻬﺎ در ﻟﻴﺴﺖ زﻳﺮ ﻧﺎم ﺑﺮده ﺷﺪه اﻧﺪ )اﻟﺒﺘﻪ اﮔﺮ ﻛﺘﺎب را ﺑﻪ ﺻﻮرت ﮔﺬرا ﻣﻲ ﺧﻮاﻧﻴﺪ اﻳﻦ ﻧﺎﻣﻬﺎ اﻫﻤﻴﺘﻲ ﻧﺪارﻧﺪ‪ ،‬وﻟـﻲ‬ ‫اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﺎ دﻗﺖ از ﻫﻤﻪ ﭼﻴﺰ ﻣﻄﻠﻊ ﺷﻮﻳﺪ ﻣﻤﻜﻦ اﺳﺖ ﻣﻔﻴﺪ ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﻨﺪ(‪:‬‬ ‫‪URI (Uniform Resource Identifiers):‬‬ ‫‪www.ietf.org/rfc/rfc2396.txt‬‬ ‫‪UTF-8 (Uniform Transformation Format):‬‬ ‫‪www.utf-8.com‬‬ ‫‪XML (eXtensible Markup Language):‬‬ ‫‪www.w3.org/TR/REC-xml‬‬ ‫‪XML Schema:‬‬ ‫‪www.w3.org/XML/Schema‬‬ ‫‪XML Information Set:‬‬ ‫‪www.w3.org/TR/xml-infoset‬‬

‫‬ ‫‬ ‫‬ ‫‬ ‫‬

‫اﻟﺒﺘﻪ درﺑﺎره ي ﻣﻮاردي ﻛﻪ در ﺑﺎﻻ ﻋﻨﻮان ﺷﺪ‪ ،‬ﻛﺘﺎﺑﻬﺎي زﻳﺎدي ﻛﻪ ﺑﺘﻮان ﺑﻪ ﺳﺎدﮔﻲ آﻧﻬﺎ را درك ﻛﺮد‪ ،‬ﺑﺎ ﻗﺎﻟﺐ و ﻓﺮﻣﺖ آﻧﻬـﺎ آﺷـﻨﺎ ﺷـﺪ و‬ ‫ﻧﺤﻮه ي اﺳﺘﻔﺎده از آﻧﻬﺎ را ﻣﺸﺎﻫﺪه ﻛﺮد وﺟﻮد ﻧﺪارد‪ .‬اﻣﺎ اﮔﺮ ﺗﻤﺎﻳﻞ دارﻳﺪ ﻛﻪ ﺑﺎ اﻳﻦ ﻣﻮارد ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺷﻮﻳﺪ‪ ،‬ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻌـﺪ از اﺗﻤـﺎم اﻳـﻦ‬ ‫ﻓﺼﻞ از ﻣﻨﺎﺑﻊ اﻳﻨﺘﺮﻧﺘﻲ ﻣﻮﺟﻮد اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬ ‫زﺑﺎن ‪ XML‬ﻧﻴﺰ ﻣﺒﺘﻨﻲ ﺑﺮ ﺗﮓ ﻫﺎ اﺳﺖ‪ ،‬ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ ﻛﻪ اﺳﻨﺎد ‪ XML‬ﻧﻴﺰ ﺷﺎﻣﻞ ﺗﮓ ﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ داده ﻫﺎ در آن ﻗـﺮار ﻣـﻲ ﮔﻴـﺮد‪.‬‬ ‫ﺑﺮاي ﻣﺜﺎل اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛﺘﺎب را ﻣﻲ ﺗﻮان ﺑﻪ ﺻﻮرت زﻳﺮ در ﻗﺎﻟﺐ ‪ XML‬ﻧﻤﺎﻳﺶ داد‪:‬‬ ‫>‪‪<Title>Learning Visual C# 2005‪XXXX-XX-XXX‪<Subject>Programming‪
‫در ‪ XML‬ﻧﻴﺰ ﻣﺎﻧﻨﺪ ‪ HTML‬ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﺗﮓ از ﻋﻼﻣﺖ ﻫﺎي < و > اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ‪ .‬دو ﻧﻮع ﺗﮓ ﻛﻠـﻲ ﻧﻴـﺰ وﺟـﻮد دارﻧـﺪ ﻛـﻪ‬ ‫ﻋﺒﺎرﺗﻨﺪ از ﺗﮓ ﻫﺎي ﺷﺮوع ﻣﺎﻧﻨﺪ >‪ <Title‬و ﺗﮕﻬﺎي ﭘﺎﻳﺎن ﻣﺎﻧﻨﺪ >‪ .
‫‪2‬‬

‫>‪<Title>Learning Visual C# 2005
‫ﻋﻨﺼﺮ ‪ ISBN‬ﻧﻴﺰ ﻣﺸﺎﺑﻪ زﻳﺮ اﺳﺖ‪:‬‬ ‫>‪XXXX-XX-XXX
‫‪Standard Generalized Markup Language‬‬ ‫‪Element‬‬

‫‪1‬‬ ‫‪2‬‬

‫‪٧٦٩‬‬

‫و ﻋﻨﺼﺮ آﺧﺮ ﻧﻴﺰ ﻋﻨﺼﺮ ‪ Subject‬اﺳﺖ‪:‬‬ ‫>‪<Subject>Programming
‫دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻳﻚ ﻋﻨﺼﺮ ﺧﻮد ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺪ ﺷﺎﻣﻞ ﭼﻨﺪ ﻋﻨﺼﺮ ﺑﺎﺷﺪ‪ .‬ﺑﺮاي ﻧﻤﻮﻧﻪ در ﻣﺜﺎل ﻗﺒﻞ ﻋﻨـﺼﺮ ‪ Book‬ﺷـﺎﻣﻞ ﺳـﻪ ﻋﻨـﺼﺮ ﺑـﻪ‬ ‫ﺻﻮرت زﻳﺮ اﺳﺖ‪:‬‬ ‫>‪‪<Title>Learning Visual C# 2005‪XXXX-XX-XXX‪<Subject>Programming‪
‫ﻧﻜﺘﻪ‪ :‬ﻣﻌﻤﻮﻻ ﻋﻨﺎﺻﺮي ﻛﻪ درون ﻳﻚ ﻋﻨﺼﺮ ﻗﺮار ﻣﻲ ﮔﻴﺮد را ﺑﻪ ﺻﻮرت ﻧﻤﺎي درﺧﺘﻲ ﻧﻴﺰ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻨﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل در ﻛـﺪ ‪XML‬‬ ‫ﻗﺒﻠﻲ‪ ،‬ﻋﻨﺎﺻﺮ ‪ ISBN ،Title‬و ‪ ،Subject‬ﺷﺎﺧﻪ ﻫﺎﻳﻲ از ﻋﻨﺼﺮ ‪ Book‬ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﻪ ﻋﻨﻮان رﻳﺸﻪ در ﻧﻈـﺮ ﮔﺮﻓﺘـﻪ ﻣـﻲ‬ ‫ﺷﻮد‪ .‬ﻫﻤﭽﻨﻴﻦ در اﻳﻦ زﺑﺎن از اﺻﻄﻼﺣﺎت زﻳﺎدي ﻣﺎﻧﻨﺪ ﮔﺮه‪ ،‬ﻋﻨﺼﺮ ﻓﺮزﻧﺪ‪ ،‬ﻋﻨﺼﺮ واﻟﺪ و ﻳﺎ … ﻣﻤﻜﻦ اﺳﺖ اﺳﺘﻔﺎده ﺷﻮد ﻛﻪ ﻫﻤﻪ از اﻳـﻦ‬ ‫ﺳﺎﺧﺘﺎر ﻧﺸﺎت ﻣﻲ ﮔﻴﺮﻧﺪ‪.‬‬ ‫اﮔﺮ ﺑﺨﻮاﻫﻴﺪ از اﻳﻦ ﺳﻨﺪ ‪ XML‬اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ ،‬اﺑﺘﺪا ﺑﺎﻳﺪ ﺳﺎﺧﺘﺎر داده ﻫﺎﻳﻲ ﻛﻪ در آن ﻗﺮار ﮔﺮﻓﺘﻪ اﻧﺪ را درك ﻛﻨﻴﺪ‪ .‬ﻣﻌﻤـﻮﻻ ﺷـﺮﻛﺘﻲ ﻛـﻪ‬ ‫اﻳﻞ ‪ XML‬را اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ‪ ،‬در ﻣﻮرد ﺳﺎﺧﺘﺎر داده ﻫﺎي درون آن ﻧﻴﺰ ﺑﻪ ﺷﻤﺎ ﺗﻮﺿﻴﺢ ﺧﻮاﻫﺪ داد‪ .‬ﺑﺮاي ﻧﻤﻮﻧﻪ در ﻣﺜﺎل ﻗﺒﻞ‪ ،‬ﺷﺮﻛﺘﻲ ﻛـﻪ‬ ‫داده ﻫﺎي ﺑﺎﻻ را ﺗﻨﻈﻴﻢ ﻛﺮده اﺳﺖ ﺑﻪ ﺷﻤﺎ ﻣﻲ ﮔﻮﻳﺪ ﻛﻪ ﺑﺮاي ﻣﺸﺎﻫﺪه ي ﻋﻨﻮان ﻳﻚ ﻛﺘﺎب اﺑﺘﺪا وارد ﻋﻨﺼﺮ ‪ Book‬ﺷﺪه و از آﻧﺠﺎ ﺑﻪ‬ ‫ﻋﻨﺼﺮ ‪ Title‬ﻣﻲ روﻳﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻘﺪاري ﻛﻪ درون ﺗﮓ ﺷﺮوع >‪ ‪ ‪‪<Title ISBN="XXXX-XX-XXX">Learning Visual C# 2005‪<Subject>Programming‪
‫ﻳﻜﻲ از ﺧﺼﻮﺻﻴﺖ ﻫﺎﻳﻲ ﻛﻪ ﺑﺎﻋﺚ ﮔﺴﺘﺮش ﻓﺮاوان ‪ XML‬ﺷﺪه اﺳﺖ‪ ،‬اﻳﻦ اﺳﺖ ﻛﻪ داده ﻫﺎي درون آن ﺑﻪ ﺳﺎدﮔﻲ ﻣـﻲ ﺗﻮاﻧﻨـﺪ ﺗﻮﺳـﻂ‬ ‫ﻫﻤﻪ ي اﻓﺮاد درك ﺷﻮﻧﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل‪ ،‬ﻓﻜﺮ ﻛﻨﻢ ﺑﻪ ﺳﺎدﮔﻲ ﺑﺘﻮاﻧﻴﺪ داده ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻛﺪ ‪ XML‬ﻗﺮار ﮔﺮﻓﺘﻪ اﻧﺪ را درك ﻛﻨﻴﺪ‪:‬‬ ‫>‪‪<Title>Learning Visual C# 2005‪XXXX-XX-XXX‪<Subject>Programming‪
‫‪Attribute‬‬

‫‪1‬‬

‫‪٧٧٠‬‬

‫>‪<Title>Learning Visual Basic 2005‪XXXX-XX-XXX‪<Subject>Programming‪

‫‪ XML‬ﺑﺮاي اﻓﺮاد ﻣﺒﺘﺪي‪:‬‬ ‫ﺑﻪ ﻋﻨﻮان ﻓﺮدي ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ و ﻧﻴﺰ وﻳﮋوال ‪ C#‬ﻣﺒﺘﺪي ﻫﺴﺘﻴﺪ‪ ،‬اﺣﺘﻤﺎﻻ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ﺻـﻮرت ﭘﻴﭽﻴـﺪه درﮔﻴـﺮ‬ ‫ﻣﻮارد ﭘﻴﭽﻴﺪه ي ﻳﻜﭙﺎرﭼﻪ ﺳﺎزي ﻣﻲ ﺷﻮﻧﺪ را درك ﻛﻨﻴﺪ‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻠﻲ ﻧﻴـﺰ ﮔﻔـﺘﻢ‪ ،‬ﻳﻜـﻲ از دﻻﻳﻠـﻲ ﻛـﻪ ‪ XML‬ﺑـﺴﻴﺎر‬ ‫ﻓﺮاﮔﻴﺮ و ﮔﺴﺘﺮده ﺷﺪه اﺳﺖ ﺳﺎدﮔﻲ آن در ﺑﺮﻗﺮاري ﻳﻜﭙﺎرﭼﮕﻲ ﺑﻴﻦ ﻧﺮم اﻓﺰارﻫﺎي ﺗﺠﺎري اﺳﺖ‪ .‬اﻣﺎ اﻳﻦ ﻣﺴﺌﻠﻪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﻣﺒﺘﺪي‬ ‫ﭼﻪ ارﺗﺒﺎﻃﻲ دارد؟ ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﻣﺒﺘﺪي ﭼﻪ اﺳﺘﻔﺎده اي ﻣﻲ ﺗﻮاﻧﻨﺪ از ‪ XML‬داﺷﺘﻪ ﺑﺎﺷﻨﺪ؟‬ ‫ﺟﻮاب اﻳﻦ ﺳﻮال اﻳﻦ اﺳﺖ ﻛﻪ ‪ XML‬ﻧﻪ ﺗﻨﻬﺎ ﻳﻚ وﺳﻴﻠﻪ ﺑﺮاي ﻳﻜﭙﺎرﭼﻪ ﺳﺎزي ﺑﻴﻦ ﻧﺮم اﻓﺰارﻫﺎي ﺗﺠﺎري ﺑﻪ ﺷﻤﺎر ﻣﻲ رود‪ ،‬ﺑﻠﻜـﻪ ﻳـﻚ‬ ‫اﺑﺰار ﻋﺎﻟﻲ ﺑﺮاي ذﺧﻴﺮه ﺳﺎزي اﻃﻼﻋﺎت و ﻧﻴﺰ ﺳﺎزﻣﺎﻧﺪﻫﻲ داده ﻫﺎ اﺳﺖ‪ .‬ﻗﺒﻞ از ‪ ،XML‬ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻲ ﺗﻮاﻧﺴﺘﻨﺪ از دو روش ﺑﺮاي ذﺧﻴـﺮه‬ ‫ي داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﻨﺪ‪ :‬ﻳﺎ از ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺘﻔﺎده ﻛﻨﻨﺪ و ﻳﺎ داده ﻫﺎي ﺧﻮد را در ﻳﻚ ﻓﺎﻳﻞ ﺑـﺎ ﻓﺮﻣـﺖ ﺧـﺎص‬ ‫ﺧﻮد ﻗﺮار دﻫﻨﺪ و ﺳﭙﺲ ﻛﺪي را ﺑﻨﻮﻳﺴﻨﺪ ﻛﻪ ﺑﺘﻮاﻧﺪ داده ﻫﺎ را از آن ﻓﺎﻳﻠﻬﺎ ﺧﻮاﻧﺪه و ﻧﻴﺰ در آﻧﻬﺎ ﺑﻨﻮﻳﺴﺪ‪.‬‬ ‫در ﺑﺴﻴﺎر ي از ﻣﻮارد اﺳﺘﻔﺎده از ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﻬﺘﺮﻳﻦ ﮔﺰﻳﻨﻪ ﺑﺮاي اﻧﺠﺎم اﻳﻦ ﻛﺎر ﺑﻪ ﺷﻤﺎر ﻣﻲ رود‪ ،‬زﻳﺮا ﺑـﺎ اﺳـﺘﻔﺎده از آن ﺑﺮﻧﺎﻣـﻪ‬ ‫ﻫﺎي ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ ﺳﺮﻋﺖ ﺑﻪ داده ﻫﺎ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ و ﻧﻴﺰ از اﻣﻜﺎﻧﺎﺗﻲ ﻛﻪ آن ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ )ﻣﺎﻧﻨـﺪ ‪ Access‬و ﻳـﺎ‬ ‫‪ (Sql Server‬اراﺋﻪ ﻣﻲ دﻫﺪ اﺳﺘﻔﺎده ﻛﻨﻨﺪ‪ .‬در ﺑﻌﻀﻲ ﺷﺮاﻳﻂ ﻧﻴﺰ‪ ،‬ﻣﺎﻧﻨﺪ ﻧﻮﺷﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﮔﺮاﻓﻴﻜﻲ‪ ،‬ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ داده ﻫـﺎ‬ ‫در ﻳﻚ ﻓﺎﻳﻞ ﺑﺎ ﻓﺮﻣﺖ ﺧﺎص آن ﺑﺮﻧﺎﻣﻪ ذﺧﻴﺮه ﺷﻮﻧﺪ‪ .‬دﻟﻴﻞ اﻳﻦ ﻣﻮرد ﻧﻴﺰ اﻳﻦ ﺑﻮد ﻛﻪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﻏﻠﺐ ﺗﻤﺎﻳﻞ داﺷﺘﻨﺪ ﻛﻪ ﺳﺎده ﺑﺎﺷﻨﺪ و‬ ‫ﻧﻤﻲ ﺧﻮاﺳﺘﻨﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ‪ ،‬ﻛﺎرﺑﺮان ﺧﻮد را درﮔﻴﺮ ﻣﺴﺎﺋﻞ ﻣﺮﺑﻮط ﺑﻪ آن ﺑﻜﻨﻨﺪ‪.‬‬ ‫در اﻳﻦ ﮔﻮﻧﻪ ﻣﻮارد‪ XML ،‬روش ﺟﺪﻳﺪي را ﺑﺮاي ذﺧﻴﺮه ي اﻃﻼﻋﺎت ﺑﺮﻧﺎﻣﻪ اراﺋﻪ ﻣﻲ دﻫﺪ ﻛﻪ اﻟﺒﺘﻪ ﻗﺎﻟﺐ آن ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺪ ﻣﺨﺼﻮص آن‬ ‫ﺑﺮﻧﺎﻣﻪ ﺑﺎﺷﺪ‪ .‬ﺗﻔﺎوﺗﻲ ﻛﻪ اﻳﻦ روش ﺑﺎ روش ذﺧﻴﺮه ﻛﺮدن داده ﻫﺎ در ﻳﻚ ﻓﺎﻳﻞ ﻣﺘﻨﻲ ﻣﺎﻧﻨﺪ ‪ .doc‬دارد در اﻳﻦ اﺳﺖ ﻛﻪ داده ﻫﺎﻳﻲ ﻛـﻪ‬ ‫در ‪ XML‬ذﺧﻴﺮه ﻣﻲ ﺷﻮﻧﺪ ﺑﻪ ﺻﻮرت اﺳﺘﺎﻧﺪارد ﻫﺴﺘﻨﺪ‪.‬‬

‫ﭘﺮوژه ي دﻓﺘﺮ ﺗﻠﻔﻦ‪:‬‬ ‫در اﻳﻦ ﻗﺴﻤﺖ ﺑﺮاي اﻳﻨﻜﻪ ﺑﺎ ﻣﺒﺎﺣﺚ ﺗﺌﻮري ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ ﻣﺮور ﻛﺮدﻳﻢ در ﻋﻤﻞ ﻧﻴﺰ آﺷﻨﺎ ﺷﻮﻳﻢ‪ ،‬ﻳﻚ ﺑﺮﻧﺎﻣـﻪ ي دﻓﺘـﺮ ﺗﻠـﻒ اﻳﺠـﺎد‬ ‫ﺧﻮاﻫﻴﻢ ﻛﺮد و ﺑﺮاي ذﺧﻴﺮه ي اﻃﻼﻋﺎت آن از ﻳﻚ ﻓﺎﻳﻞ ‪ XML‬اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣـﻲ ﺗـﻮاﻧﻴﻢ ﻟﻴـﺴﺘﻲ از رﻛـﻮرد ﻫـﺎي‬ ‫اﻃﻼﻋﺎﺗﻲ ﻛﻪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ وارد ﻣﻲ ﺷﻮد را در ﻳﻚ ﻓﺎﻳﻞ ‪ XML‬ذﺧﻴﺮه ﻛﺮده و ﻳﺎ اﻃﻼﻋﺎت داﺧـﻞ ﻳـﻚ ﻓﺎﻳـﻞ ‪ XML‬را ﺧﻮاﻧـﺪه و در‬ ‫ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ دﻫﻴﻢ‪.‬‬

‫اﻳﺠﺎد ﭘﺮوژه‪:‬‬ ‫ﻣﺜﻞ ﻫﻤﻴﺸﻪ‪ ،‬اوﻟﻴﻦ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﻢ اﻳﻦ اﺳﺖ ﻛﻪ ﻳﻚ ﭘﺮوژه ي ﺟﺪﻳﺪ اﻳﺠﺎد ﻛﻨﻴﻢ‪.‬‬

‫‪٧٧١‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﻳﺠﺎد ﭘﺮوژه‬ ‫‪ (1‬وﻳﮋوال اﺳﺘﻮدﻳﻮ را ﺑﺎز ﻛﺮده و ﮔﺰﻳﻨﻪ ي ‪ File  New Project‬را از ﻧﻮار ﻣﻨـﻮ اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ‪ .‬ﺳـﭙﺲ ﺑـﺎ‬ ‫اﺳﺘﻔﺎده از ﻛﺎدر ‪ New Project‬ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وﻳﻨﺪوز ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم ‪ Address Book‬اﻳﺠﺎد ﻛﻨﻴﺪ‪.‬‬ ‫‪ (2‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ ‪ Form1‬ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ‪ .‬اﺑﺘـﺪا ﺧﺎﺻـﻴﺖ ‪ Text‬ﻓـﺮم را ﺑﺮاﺑـﺮ ﺑـﺎ‬ ‫‪ Address Book‬ﻗﺮار دﻫﻴﺪ‪ .‬ﺣﺎل ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار‪ ،‬ده ﻛﻨﺘﺮل ‪ ،TextBox‬دوازده ﻛﻨﺘـﺮل ‪ Label‬و‬ ‫ﻳﻚ ﻛﻨﺘﺮل ‪ Button‬را ﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮده و آﻧﻬﺎ را ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪ 1-19‬در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻣﺮﺗﺐ ﻛﻨﻴﺪ‪ .‬ﺑﺮاي ﺗﻨﻈﻴﻢ‬ ‫ﻣﻜﺎن ﻛﻨﺘﺮل ﻫﺎ ﻫﻢ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺧﻄﻮط ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛﺎر در ﻓﺮم اﺳﺘﻔﺎده ﻛﻨﻴﺪ و ﻫﻢ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﮔﺰﻳﻨـﻪ ﻫـﺎي ﻣﻮﺟـﻮد در‬ ‫ﻣﻨﻮي ‪ Format‬را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ‪.‬‬

‫ﺷﻜﻞ ‪1-19‬‬ ‫‪ (3‬ﺧﺎﺻﻴﺖ ‪ Name‬ﻛﻨﺘﺮﻟﻬﺎي ‪ TextBox‬ﻣﻮﺟﻮد در ﻓﺮم را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪:‬‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬

‫‪txtFirstName‬‬ ‫‪txtLastName‬‬ ‫‪txtCompanyName‬‬ ‫‪txtAddress1‬‬ ‫‪txtAddress2‬‬ ‫‪txtCity‬‬ ‫‪txtRegion‬‬ ‫‪txtPostalCode‬‬ ‫‪txtCountry‬‬

‫‪٧٧٢‬‬

‫‬

‫‪txtEmail‬‬

‫‪ (4‬ﻫﻤﭽﻨﻴﻦ ﺧﺎﺻﻴﺖ ‪ Text‬ﻛﻨﺘﺮﻟﻬﺎي ‪ Label‬و ‪ Button‬ﺑﺮﻧﺎﻣﻪ را ﻧﻴﺰ ﻣﺎﻧﻨﺪ ﺷﻜﻞ ‪ 1-19‬ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ‪.‬‬ ‫‪ (5‬ﺳﭙﺲ ﺧﺎﺻﻴﺖ ‪ Name‬ﻛﻨﺘﺮل ‪ Button‬را ﺑﺮاﺑﺮ ﺑﺎ ‪ btnSave‬ﻗﺮار دﻫﻴﺪ‪ .‬در آﺧﺮ ﻧﻴـﺰ ﺧﺎﺻـﻴﺖ ‪ Name‬ﻛﻨﺘـﺮل‬ ‫‪Label‬اي ﻛﻪ ﺑﺎ ﻋﺒﺎرت )‪ (Number‬ﻣﺸﺨﺺ ﺷـﺪه اﺳـﺖ را ﺑﺮاﺑـﺮ ﺑـﺎ ‪ lblAddressNumber‬ﻗـﺮار‬ ‫دﻫﻴﺪ‪.‬‬ ‫ﺗﻤﺎم ﻛﺎرﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي ﻃﺮاﺣﻲ ﻇﺎﻫﺮ ﻓﺮم اﻧﺠﺎم ﻣﻲ دادﻳﻢ ﻫﻤﻴﻦ ﺑﻮد‪ .‬ﺧﻮب ﺑﻬﺘﺮ اﺳﺖ ﻛﻪ در اداﻣﻪ ﻧﺤﻮه ي ذﺧﻴﺮه ي داده ﻫﺎ در ﻓﺎﻳـﻞ‬ ‫‪ XML‬را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ‪.‬‬

‫ﻛﻼس ‪:SerializableData‬‬ ‫در اﻳﻦ ﺑﺮﻧﺎﻣﻪ از دو ﻛﻼس اﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد‪ :‬ﻛـﻼس ‪ Address‬و ﻛﺘـﺎب ‪ .AddressBook‬ﻛـﻼس ‪Address‬‬ ‫ﺑﺮاي ﻧﮕﻬﺪاري ﻳﻚ رﻛﻮرد از اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﺑﺎﻳﺪ در دﻓﺘﺮ ﺗﻠﻔﻦ ذﺧﻴﺮه ﺷﻮﻧﺪ ﺑﻪ ﻛﺎر ﻣﻲ رود‪ .‬ﻛﻼس ‪ AddressBook‬ﻧﻴـﺰ ﺷـﺎﻣﻞ‬ ‫ﻳﻚ آراﻳﻪ از اﺷﻴﺎﻳﻲ از ﻛﻼس ‪ Address‬اﺳﺖ و ﺗﻤﺎم رﻛﻮرد ﻫﺎي ﻣﻮﺟﻮد در دﻓﺘﺮ ﺗﻠﻔﻦ را ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ اﻳﻦ ﻛﻼس‬ ‫داراي ﻣﺘﺪ ﻫﺎﻳﻲ ﺑﺮاي ﺣﺮﻛﺖ در ﺑﻴﻦ داده ﻫﺎي ﻣﻮﺟﻮد در دﻓﺘﺮ ﺗﻠﻔﻦ ﺧﻮاﻫﺪ ﺑﻮد‪.‬‬ ‫ﻫﺮ دو ﻛﻼﺳﻲ ﻛﻪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد از ﻳﻚ ﻛﻼس ﭘﺎﻳﻪ ﺑﻪ ﻧﺎم ‪ SerializableData‬ﻣـﺸﺘﻖ ﻣـﻲ ﺷـﻮﻧﺪ‪.‬‬ ‫ﻛﻼس ‪ SerializableData‬ﺷﺎﻣﻞ ﺗﻮاﺑﻌﻲ اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آﻧﻬﺎ ﻣﻲ ﺗﻮان داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ را در دﻳﺴﻚ‬ ‫ذﺧﻴﺮه ﻛﺮده و ﻳﺎ داده ﻫﺎﻳﻲ ﻛﻪ در دﻳﺴﻚ وﺟﻮد دارﻧﺪ را در ﺑﺮﻧﺎﻣﻪ ﻗﺮار داد‪ .‬در ‪ ،XML‬ﭘﺮوﺳﻪ ي ﻣﺮﺑﻮط ﺑﻪ ذﺧﻴﺮه ﻛﺮدن اﻃﻼﻋﺎت ﻳﻚ‬ ‫ﺷﻴﺊ از ﻛﻼس در دﻳﺴﻚ ﺑﻪ ﻋﻨﻮان ﺳﺮﻳﺎﻻﻳﺰ ﻛﺮدن‪ 1‬و ﭘﺮوﺳﻪ ي ﻣﺮﺑﻮط ﺑﻪ اﻳﺠﺎد ﺷﻴﺊ اوﻟﻴﻪ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ اﻃﻼﻋﺎت ﻣﻮﺟﻮد در دﻳﺴﻚ‬ ‫ﺑـــﻪ ﻋﻨـــﻮان دي ﺳـــﺮﻳﺎﻻﻳﺰ ﻛـــﺮدن‪ 2‬ﺷـــﻨﺎﺧﺘﻪ ﻣـــﻲ ﺷـــﻮد‪ .‬در ﻗـــﺴﻤﺖ اﻣﺘﺤـــﺎن ﻛﻨﻴـــﺪ ﺑﻌـــﺪ‪ ،‬ﺑـــﺎ اﻳﺠـــﺎد ﻛﻼﺳـــﻬﺎي‬ ‫‪ SerializableData‬و ﻧﻴﺰ ‪ ،Address‬از روش ﺟﺪﻳﺪي ﺑﺮاي ذﺧﻴﺮه ي داده ﻫﺎي ﻣﻮﺟﻮد در دﻓﺘﺮ ﺗﻠﻔﻦ در دﻳﺴﻚ‬ ‫اﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﻳﺠﺎد ﻛﻼس ‪SerializableData‬‬ ‫‪ (1‬اوﻟــﻴﻦ ﻛﻼﺳــﻲ ﻛــﻪ ﺑﺎﻳــﺪ اﻳﺠــﺎد ﻛﻨــﻴﻢ‪ ،‬ﻛــﻼس ‪ SerializableData‬اﺳــﺖ‪ .‬ﺑــﺎ اﺳــﺘﻔﺎده از ﭘﻨﺠــﺮه ي‬ ‫‪ ،Solution Explorer‬ﺑﺮ روي ﻧﺎم ﭘﺮوژه ﻛﻠﻴﻚ ﻛﺮده و ﮔﺰﻳﻨـﻪ ي …‪ Add  Class‬را اﻧﺘﺨـﺎب‬ ‫ﻛﻨﻴﺪ‪ .‬در ﻛﺎدر ‪ Name‬ﻋﺒﺎرت ‪ SerializableData‬را وارد ﻛﺮده و روي دﻛﻤﻪ ي ‪ Add‬ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗـﺎ‬ ‫ﻛﻼﺳﻲ ﺑﻪ اﻳﻦ ﻧﺎم ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﻮد‪.‬‬ ‫‪ (2‬ﻣﺠﺪداً در ﭘﻨﺠﺮه ي ‪ Solution Explorer‬روي ﻧﺎم ﭘﺮوژه ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨـﻪ ي‬ ‫…‪ Add Reference‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬در ﻗﺴﻤﺖ ‪ .NET‬از ﭘﻨﺠـﺮه ي ‪ Add Reference‬ﮔﺰﻳﻨـﻪ ي‬ ‫‪ System.XML‬را اﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤﻪ ي ‪ OK‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر ‪ using‬دو ﻓـﻀﺎي‬ ‫ﻧﺎم ﻣﺸﺨﺺ ﺷﺪه را ﺑﻪ ﻛﻼس ‪ SerializableData‬اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪:‬‬ ‫‪Serialization‬‬ ‫‪Deserialization‬‬

‫‪1‬‬ ‫‪2‬‬

‫‪٧٧٣‬‬

using System.IO; using System.Xml.Serialization; namespace Address_Book { public class SerializableData

:‫( ﺳﭙﺲ دو ﻣﺘﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬3 // Save - serialize the object to disk... public void Save(String filename) { // make a temporary filename... String tempFilename; tempFilename = filename + ".tmp"; // does the file exist? FileInfo tempFileInfo = new FileInfo(tempFilename); if (tempFileInfo.Exists) tempFileInfo.Delete(); // open the file... FileStream stream = new FileStream(tempFilename, FileMode.Create); // save the object... Save(stream); // close the file... stream.Close(); // remove the existing data file and // rename the temp file... tempFileInfo.CopyTo(filename, true); tempFileInfo.Delete(); } // Save - actually perform the serialization... public void Save(Stream stream) { // create a serializer... XmlSerializer serializer = new XmlSerializer(this.GetType); // save the file... serializer.Serialize(stream, this); }

‫ را ﻣﺎﻧﻨﺪ زﻳـﺮ ﺑـﻪ‬SerializableData ‫ ﺑﻪ ﭘﺮوژه اﺿﺎﻓﻪ ﻛﺮده و ﻛﻼس‬Address ‫( ﻛﻼس ﺟﺪﻳﺪي ﺑﻪ ﻧﺎم‬4 :‫ﻋﻨﻮان ﻛﻼس ﭘﺎﻳﻪ ي آن ﻣﺸﺨﺺ ﻛﻨﻴﺪ‬ public class Address : SerializableData { }

‫ اﻳﻦ ﻓﻴﻠـﺪ ﻫـﺎ ﺑـﺮاي ﻧﮕﻬـﺪاري داده ﻫـﺎي ﻳـﻚ رﻛـﻮرد از‬.‫( ﺳﭙﺲ ﻓﻴﻠﺪ ﻫﺎي ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬5 :‫اﻃﻼﻋﺎت ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ‬

٧٧٤

public class Address : SerializableData { // Members... public String FirstName; public String LastName; public String CompanyName; public String Address1; public String Address2; public String City; public String Region; public String PostalCode; public String Country; public String Email; }

‫ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗـﺎ ﻣﺘـﺪ ﻣﺮﺑـﻮط ﺑـﻪ‬btnSave ‫ ﺑﺮﮔﺸﺘﻪ و روي ﻛﻨﺘﺮل‬Form1 ‫( ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ‬6 :‫ ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬.‫ آن ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﺷﻮد‬Click ‫روﻳﺪاد‬ private void btnSave_Click(object sender, EventArgs e) { // create a new address object... Address address = new Address(); // copy the values from the form into the address... PopulateAddressFromForm(address); // save the address... String filename = DataFileName; address.Save(filename); // tell the user... MessageBox.Show("The address was saved to " + filename); }

‫ و ﻳـﺎ‬DataFileName ‫( ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن اﻳﻦ ﻛﺪ وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻋﻼم ﻣﻲ ﻛﻨﺪ ﻛـﻪ ﺧﺎﺻـﻴﺖ و ﻳـﺎ ﻣﺘـﺪي ﺑـﻪ ﻧـﺎم‬7 ‫ ﺑﺮاي رﻓﻊ اﻳﻦ ﻣﺸﻜﻞ اﺑﺘﺪا ﺧﺎﺻﻴﺘﻲ‬.‫ وﺟﻮد ﻧﺪارد‬Form1 ‫ در ﻛﻼس‬PopulateAddressFromForm .‫ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ‬Form1 ‫ ﻣﺎﻧﻨﺪ زﻳﺮ ﺑﻪ ﻛﻼس‬DataFileName ‫ﺑﻪ ﻧﺎم‬ // DataFilename - where should we store our data? public String DataFileName { get { // get our working folder... String folder; folder = Environment.CurrentDirectory; // return the folder with the name "Addressbook.xml"... return folder + "\\AddressBook.xml"; } }

.‫ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻓﺼﻞ ﭼﻬﺎرم ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ‬،‫ در ﻣﻮرد دﻟﻴﻞ اﺳﺘﻔﺎده از دو ﻛﺎراﻛﺘﺮ \ ﺑﻪ ﺟﺎي ﻳﻚ \ در ﻋﺒﺎرت ﺑﺎﻻ‬:‫ﻧﻜﺘﻪ‬

٧٧٥

‫ ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﻛـﺪ زﻳـﺮ را ﺑـﻪ ﻛـﻼس‬.‫ را اﻳﺠﺎد ﻛﻨـﻴﻢ‬PopulateAddressFromForm ‫( ﺣﺎل ﺑﺎﻳﺪ ﻣﺘﺪ‬8 :‫ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬Form1 // PopulateAddressFromForm - populates Address from the form fields... public void PopulateAddressFromForm(Address address) { // copy the values... address.FirstName = txtFirstName.Text; address.LastName = txtLastName.Text; address.CompanyName = txtCompanyName.Text; address.Address1 = txtAddress1.Text; address.Address2 = txtAddress2.Text; address.City = txtCity.Text; address.Region = txtRegion.Text; address.PostalCode = txtPostalCode.Text; address.Country = txtCountry.Text; address.Email = txtEmail.Text; }

.‫( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﻛﺎدر ﻫﺎي ﻣﻮﺟﻮد در ﻓﺮم را ﺗﻜﻤﻴﻞ ﻛﻨﻴﺪ‬9 ‫ ﻛﺎدر ﭘﻴﻐﺎﻣﻲ ﻧﻤﺎﻳﺶ داده ﺷﺪه و ﻣﺤﻞ ذﺧﻴﺮه ي ﻓﺎﻳﻞ ﻣﺮﺑﻮط ﺑﻪ داده ﻫﺎ را اﻋﻼم ﻣـﻲ‬.‫ ﻛﻠﻴﻚ ﻛﻨﻴﺪ‬Save ‫( روي دﻛﻤﻪ ي‬10 .‫ﻛﻨﺪ‬ ‫ روي آن‬.‫ در آﻧﺠﺎ ذﺧﻴﺮه ﺷﺪه اﺳﺖ ﺑﺮوﻳـﺪ‬XML ‫ ﺑﻪ ﻓﻮﻟﺪري ﻛﻪ اﻳﻦ ﻓﺎﻳﻞ‬Windows Explorer ‫( ﺑﺎ اﺳﺘﻔﺎده از‬11 ‫ ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ داده ﻫﺎﻳﻲ را ﻣﺸﺎﺑﻪ زﻳـﺮ‬.‫ﻓﺎﻳﻞ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﺑﺎز ﺷﺪه و ﻣﺤﺘﻮﻳﺎت آن را ﻧﻤﺎﻳﺶ دﻫﺪ‬ .‫در اﻳﻦ ﻓﺎﻳﻞ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد‬
Muhammad Hashemian MyCompany 11 First Avenue No Where North 28222 Iran <Email>[email protected]


‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ ﻣﺤﺘﻮﻳﺎت ﺧﻂ اول در اﻳـﻦ ﻗـﺴﻤﺖ زﻳـﺎد ﻣﻬـﻢ‬.‫ اي ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﺷﺪه اﺳﺖ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ‬XML ‫اﺑﺘﺪا ﺑﻬﺘﺮ اﺳﺖ ﻛﺪ‬ ‫ در ﺧﻂ دوم و ﺳﻮم ﻫﻢ‬xmlns ‫ ﻫﻤﭽﻨﻴﻦ ﺧﺼﻴﺼﻪ‬.‫ اﺳﺖ‬1 ‫ ﻧﺴﺨﻪ ي‬XML ‫ اﻳﻦ ﺧﻂ ﺑﻴﺎن ﻣﻲ ﻛﻨﺪ ﻛﻪ اﻳﻦ ﻓﺎﻳﻞ ﺷﺎﻣﻞ ﻛﺪ‬.‫ﻧﻴﺴﺘﻨﺪ‬

٧٧٦

‫در اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﻫﻤﻴﺖ ﻧﺪارﻧﺪ‪ ،‬زﻳﺮا اﻳﻦ ﺧﺼﻴﺼﻪ ﻧﻴﺰ ﻓﻘﻂ اﻃﻼﻋﺎﺗﻲ را در ﻣﻮرد اﻳﻦ ﻓﺎﻳﻞ ﺑﻴﺎن ﻣﻲ ﻛﻨﺪ و در اﻳـﻦ ﻣﺮﺣﻠـﻪ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﻪ‬ ‫‪ .NET‬اﺟﺎزه دﻫﻴﺪ اﻳﻦ اﻃﻼﻋﺎت را ﺑﺮاي ﺷﻤﺎ در ﻓﺎﻳﻞ ﺗﻨﻈﻴﻢ ﻛﻨﺪ‪ .‬ﺑﺎ ﺣﺬف اﻳﻦ ﻣﻮارد‪ ،‬ﻛﺪي ﻛﻪ ﺑﺎﻗﻲ ﻣﻲ ﻣﺎﻧﺪ ﺑﻪ ﺻﻮرت زﻳﺮ ﺧﻮاﻫـﺪ‬ ‫ﺑﻮد‪:‬‬ ‫>‪Muhammad‪Hashemian‪MyCompany‪11 First Avenue‪No Where‪North‪28222‪Iran‪<Email>[email protected]
‫ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ ﻛﺪ ﺑﺴﻴﺎر ﺷﺒﻴﻪ ﻛﺪي اﺳﺖ ﻛﻪ در اﺑﺘﺪاي اﻳﻦ ﻓﺼﻞ ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ‪ ،‬داراي ﺗﮓ ﻫﺎي ﺷﺮوع و ﺗﮓ ﻫﺎي ﭘﺎﻳـﺎن‬ ‫اﺳﺖ ﻛﻪ ﻋﻨﺎﺻﺮ آن را ﺗﺸﻜﻴﻞ ﻣﻲ دﻫﻨﺪ‪ .‬ﻫﺮ ﻋﻨﺼﺮ در اﻳﻦ ﻓﺎﻳﻞ داده اي را ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ و از ﻧﺎم ﻋﻨﺎﺻﺮ ﻣﻲ ﺗﻮان ﻓﻬﻤﻴﺪ ﻛـﻪ ﭼـﻪ‬ ‫داده اي در آن ذﺧﻴﺮه ﺷﺪه اﺳﺖ‪ .‬ﺑﺮاي ﻣﺜﺎل در ﻋﻨﺼﺮ ‪ CompanyName‬ﻧﺎم ﺷﺮﻛﺘﻲ ﻛﻪ ﻓﺮد در آن ﻛﺎر ﻣﻲ ﻛﻨﺪ ﻣـﺸﺨﺺ ﺷـﺪه‬ ‫اﺳﺖ‪.‬‬ ‫دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻓﺎﻳﻞ ﺑﺎ ﺗﮓ ‪ Address‬ﺷﺮوع ﻣﻲ ﺷﻮد و ﺑﺎ ﻫﻤﻴﻦ ﺗﮓ ﻧﻴﺰ ﺗﻤﺎم ﻣﻲ ﺷﻮد و ﺗﻤﺎم ﻋﻨﺎﺻﺮ دﻳﮕـﺮي ﻛـﻪ در آن وﺟـﻮد‬ ‫دارﻧﺪ در اﻳﻦ ﺗﮓ ﻗﺮار ﮔﺮﻓﺘﻪ اﻧﺪ‪ .‬اﻳﻦ ﻣﻮرد ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﺗﻤﺎم اﻳﻦ ﻋﻨﺎﺻﺮي ﻋﻀﻮي از ﻋﻨـﺼﺮ ‪ Address‬ﻫـﺴﺘﻨﺪ‪ .‬ﻋﻨـﺼﺮ‬ ‫‪ Address‬در اﻳﻦ ﻓﺎﻳﻞ اوﻟﻴﻦ ﻋﻨﺼﺮ اﺳﺖ‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻪ ﻋﻨﻮان ﻋﻨﺼﺮ رﻳﺸﻪ‪ 1‬ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮد‪.‬‬ ‫ﺑﻪ ﺧﻄﻲ ﻛﻪ دوﻣﻴﻦ آدرس در آن ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ ﺗﻮﺟﻪ ﻛﻨﻴﺪ‪ :‬ﺑﺎ ﻗـﺮار دادن ﻳـﻚ ﻛـﺎراﻛﺘﺮ ‪ /‬در اﻧﺘﻬـﺎي ﺗـﮓ‬ ‫ﺷﺮوع‪ ،‬ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ اﻳﻦ ﻋﻨﺼﺮ ﺧﺎﻟﻲ اﺳﺖ و داده اي در آن ﻗﺮار ﻧﺪارد‪ .‬اﻟﺒﺘﻪ اﻳﻦ ﺧﻂ را ﺑﻪ اﻳﻦ ﺻﻮرت ﻧﻴﺰ ﻣﻲ ﺗﻮان ﻧﻮﺷﺖ‪:‬‬ ‫>‪
‫اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ‪ ،‬اﻳﻦ ﻧﻮع ﻧﻮﺷﺘﻦ ﻣﻜﺎن ﺑﻴﺸﺘﺮي را ﺑﺮاي ذﺧﻴﺮه ﺳﺎزي اﺷﻐﺎل ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﺧﻮب‪ ،‬ﺗﺎ اﻳﻨﺠﺎ ﻣﺘﻮﺟﻪ ﺷﺪﻳﻢ ﻛﻪ ﭼﻪ ﻓﺎﻳﻠﻲ ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ ﺗﻮﻟﻴﺪ ﺷﺪه اﺳﺖ‪ .‬اﻣﺎ ﺳﻮال اﻳﻨﺠﺎﺳﺖ ﻛﻪ اﻳﻦ ﻓﺎﻳﻞ ﭼﮕﻮﻧـﻪ اﻳﺠـﺎد ﺷـﺪه اﺳـﺖ؟‬ ‫ﺑﻨﺎﺑﺮاﻳﻦ از ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ روي دﻛﻤﻪ ي ‪ Save‬ﻛﻠﻴﻚ ﻣﻲ ﻛﻨﺪ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ را دﻧﺒﺎل ﻣﻲ ﻛﻨﻴﻢ‪.‬‬ ‫اﺑﺘــــﺪا در اﻳــــﻦ ﻣﺘــــﺪ ﻳــــﻚ ﺷــــﻴﺊ از ﻧــــﻮع ‪ Address‬اﻳﺠــــﺎد ﻛــــﺮده و ﺳــــﭙﺲ ﺑــــﺎ ﻓﺮاﺧــــﻮاﻧﻲ ﻣﺘــــﺪ‬ ‫‪ PopulateAddressFromForm‬ﺷﻴﺊ اﻳﺠﺎد ﺷﺪه را ﺑﻪ اﻳﻦ ﻣﺘﺪ ارﺳﺎل ﻣﻲ ﻛﻨﻴﻢ‪ .‬اﻳﻦ ﻣﺘﺪ ﻧﻴﺰ ﻓﻘﻂ داده ﻫـﺎي درون‬ ‫ﻛﺎدرﻫﺎي روي ﻓﺮم را ﻣﻲ ﺧﻮاﻧﺪ و آﻧﻬﺎ را در ﻓﻴﻠﺪ ﻫﺎي ﻣﺨﺘﻠﻒ ﻛﻼس ‪ Address‬ﻗﺮار ﻣﻲ دﻫﺪ‪.‬‬ ‫)‪private void btnSave_Click(object sender, EventArgs e‬‬ ‫{‬ ‫‪// create a new address object...‬‬ ‫;)(‪Address address = new Address‬‬ ‫‪// copy the values from the form into the address...‬‬ ‫;)‪PopulateAddressFromForm(address‬‬

‫‪Root Element‬‬

‫‪1‬‬

‫‪٧٧٧‬‬

‫ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ‪ DataFileName‬ﻧﺎم ﻓﺎﻳﻠﻲ ﻛﻪ ﺑﺎﻳﺪ داده ﻫﺎ در ﻗﺎﻟﺐ ‪ XML‬در آن ذﺧﻴﺮه ﺷـﻮﻧﺪ را درﻳﺎﻓـﺖ ﻣـﻲ‬ ‫ﻛﻨﻴﻢ‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ‪ CurrentDirectory‬از ﻛﻼس ‪ ،Environment‬ﻣـﺴﻴﺮي ﻛـﻪ ﻓﺎﻳـﻞ‬ ‫اﺟﺮاﻳﻲ ﺑﺮﻧﺎﻣﻪ در آن ﻗﺮار دارد را ﺑﻪ دﺳﺖ آورده و ﻧﺎم ﻓﺎﻳﻞ ”‪ “\AddressBook.xml‬را ﺑﻪ اﻧﺘﻬﺎي اﻳﻦ ﻣﺴﻴﺮ اﺿﺎﻓﻪ ﻣـﻲ‬ ‫ﻛﻨﻴﻢ ﺗﺎ ﻣﺸﺨﺺ ﺷﻮد داده ﻫﺎ ﺑﺎﻳﺪ در ﭼﻪ ﻓﺎﻳﻠﻲ ﻗﺮار ﮔﻴﺮﻧﺪ‪ .‬در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻗﺮارداد ﻣﻲ ﻛﻨﻴﻢ ﻛـﻪ ﺑـﺮاي ذﺧﻴـﺮه و ﻳـﺎ ﺑﺎزﻳـﺎﺑﻲ داده ﻫـﺎي‬ ‫ﺑﺮﻧﺎﻣﻪ‪ ،‬از ﻓﺎﻳﻞ ‪XML‬اي ﻛﻪ در ﺑﺎﻻ اﻳﺠﺎد ﻛﺮدﻳﻢ اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪.‬‬ ‫‪// save the address...‬‬ ‫;‪String filename = DataFileName‬‬

‫ﺳﭙﺲ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ‪ Save‬از ﻛﻼس ‪ ،Address‬داده ﻫﺎ را در ﻓﺎﻳﻞ ﻣﺸﺨﺺ ﺷﺪه ذﺧﻴـﺮه ﻣـﻲ ﻛﻨـﻴﻢ‪ .‬اﻳـﻦ ﻣﺘـﺪ از ﻛـﻼس‬ ‫‪ SerializableData‬ﺑﻪ ﻛﻼس ‪ Address‬ﺑﻪ ارث رﺳﻴﺪه اﺳﺖ و در اداﻣﻪ ﺑﺎ ﻧﺤـﻮه ي ﻋﻤﻠﻜـﺮد آن آﺷـﻨﺎ ﺧـﻮاﻫﻴﻢ‬ ‫ﺷﺪ‪ .‬ﺑﻌﺪ از اﻳﻨﻜﻪ ﻓﺎﻳﻞ را ذﺧﻴﺮه ﻛﺮدﻳﻢ ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﻛﺎدر ﭘﻴﻐﺎم‪ ،‬ﻣﻜﺎن آن را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ‪:‬‬ ‫;)‪address.Save(filename‬‬ ‫‪// tell the user...‬‬ ‫;)‪MessageBox.Show("The address was saved to " + filename‬‬ ‫}‬

‫در ﻛﻼس ‪ SerializableData‬دو ﻧﺴﺨﻪ از ﻣﺘﺪ ‪ Save‬وﺟﻮد دارﻧﺪ ﻛﻪ ﺟﺎﻟﺐ ﺗﺮﻳﻦ ﻗﺴﻤﺘﻬﺎي اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ ﻣﺤـﺴﻮب‬ ‫ﻣﻲ ﺷﻮﻧﺪ‪ .‬ﻳﻚ ﻧﺴﺨﻪ آدرس ﻓﺎﻳﻞ را ﺑﻪ ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻛﺮده و ﺷﻴﺊ از ﻧﻮع ‪ Stream‬را ﺑﺎ اﺳـﺘﻔﺎده از آن اﻳﺠـﺎد ﻣـﻲ ﻛﻨـﺪ‪.‬‬ ‫ﺳﭙﺲ اﻳﻦ ﺷﻴﺊ را ﺑﻪ ﻧﺴﺨﻪ ي دوم ﻣﺘﺪ ‪ Save‬ﻣﻲ ﻓﺮﺳﺘﺪ ﺗﺎ ﺑﻪ وﺳﻴﻠﻪ ي آن داده ﻫﺎ ذﺧﻴﺮه ﺷﻮﻧﺪ‪ .‬ﻧﺴﺨﻪ ي دوم ﻧﻴﺰ ﺑـﺎ اﺳـﺘﻔﺎده از‬ ‫ﻛﻼس ‪ System.Xml.Serialization.XmlSerializer‬ﻛﻪ در اداﻣﻪ ﺑﺎ آن آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ و ﻧﻴـﺰ‬ ‫ﺷﻴﺊ ‪ Stream‬ﻛﻪ ﺑﻪ آن ﻓﺮﺳﺘﺎده ﺷﺪه اﺳﺖ داده ﻫﺎ را در ﻗﺎﻟﺐ ‪ XML‬ذﺧﻴﺮه ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫در ﻫﻨﮕﺎم ذﺧﻴﺮه ي داده ﻫﺎ در ﻓﺎﻳﻞ ﺑﺎﻳﺪ ﺑﻪ ﻳﻚ ﻣﺴﺌﻠﻪ دﻗﺖ ﻛﻨﻴﺪ‪ .‬ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﻢ ﻳﻚ رﻛﻮرد را ذﺧﻴﺮه ﻛﻨـﻴﻢ‪ ،‬داده ﻫـﺎي آن در‬ ‫ﻓﺎﻳﻠﻲ ﺑﺎ ﻫﻤﺎن ﻧﺎم ﻓﺎﻳﻞ ﻗﺒﻠﻲ ذﺧﻴﺮه ﻣﻲ ﺷﻮﻧﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻓﺎﻳﻞ ﻣﺮﺑﻮط ﺑﻪ اﻃﻼﻋﺎت رﻛﻮرد ﻗﺒﻠﻲ از ﺑﻴﻦ ﻣﻲ رود‪ .‬اﻣﺎ ﺑﺎﻳﺪ دﻗﺖ ﻛﻨـﻴﻢ ﻓﺎﻳـﻞ‬ ‫ﺟﺪﻳﺪ را ﺑﻪ ﮔﻮﻧﻪ اي اﻳﺠﺎد ﺷﻮد ﻛﻪ اﮔﺮ ﺑﻪ ﻫﺮ دﻟﻴﻠﻲ در اﻳﺠﺎد آن ﺑﺎ ﺷﻜﺴﺖ ﻣﻮاﺟﻪ ﺷﺪﻳﻢ‪ ،‬اﻃﻼﻋﺎت رﻛﻮرد ﻗﺒﻠﻲ از ﺑـﻴﻦ ﻧﺮوﻧـﺪ و ﻛـﺎرﺑﺮ‬ ‫ﺑﺘﻮاﻧﺪ ﺑﻪ آﻧﻬﺎ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ‪ .‬روش اﻧﺠﺎم اﻳﻦ ﻛﺎر ﻧﻴﺰ ﺳﺎده اﺳﺖ‪ .‬اﺑﺘﺪا داده ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ رﻛﻮرد ﺟﺎري را در ﻳﻚ ﻓﺎﻳـﻞ ﺑـﺎ ﻧـﺎم‬ ‫دﻳﮕﺮي ذﺧﻴﺮه ﻣﻲ ﻛﻨﻴﻢ‪ .‬زﻣﺎﻧﻲ ﻛﻪ ﻫﻤﻪ ﭼﻴﺰ ﺑﺎ ﻣﻮﻓﻘﻴﺖ ﺑﻪ اﺗﻤﺎم رﺳﻴﺪ‪ ،‬ﻓﺎﻳﻞ اﻳﺠﺎد ﺷﺪه را ﺑﺎ ﻓﺎﻳﻞ ﻣﺮﺑـﻮط ﺑـﻪ اﻃﻼﻋـﺎت رﻛـﻮرد ﻗﺒﻠـﻲ‬ ‫ﺟﺎﻳﮕﺰﻳﻦ ﻣﻲ ﻛﻨﻴﻢ‪.‬‬ ‫ﺑﺮاي ﻧﺎم ﻓﺎﻳﻠﻲ ﻛﻪ ﺑﺎﻳﺪ داده ﻫﺎي رﻛﻮرد ﺟﺪﻳﺪ ﺑﻪ ﺻﻮرت ﻣﻮﻗﺖ در آن ﻧﮕﻬﺪاري ﺷﻮﻧﺪ‪ ،‬ﺑﻪ ﻧﺎم ﻓﺎﻳﻞ اﺻﻠﻲ ﭘﺴﻮﻧﺪ ‪ .tmp‬اﺿـﺎﻓﻪ ﻣـﻲ‬ ‫ﻛﻨﻴﻢ‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ اﮔـﺮ ﻧـﺎم ﻓـﺎﻳﻠﻲ ﻛـﻪ داده ﻫـﺎ ﺑﺎﻳـﺪ در آن ذﺧﻴـﺮه ﺷـﻮﻧﺪ ﺑﺮاﺑـﺮ ﺑـﺎ ‪C:\MyProgramms\Address‬‬ ‫‪ Book\AddressBook.xml‬ﺑﺎﺷﺪ‪ ،‬اﺑﺘﺪا داده ﻫـﺎ در ﻓـﺎﻳﻠﻲ ﺑـﻪ ﻧـﺎم ‪C:\MyPrograms\Address‬‬ ‫‪ Book\AddressBook.xml.tmp‬ذﺧﻴﺮه ﻣﻲ ﺷﻮد‪ .‬ﺧﻮب‪ ،‬اﺑﺘﺪا ﻗﺒﻞ از اﻳﺠﺎد ﻓﺎﻳﻞ‪ ،‬ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ ﻛـﻪ ﻓـﺎﻳﻠﻲ ﺑـﺎ‬ ‫اﻳﻦ ﻧﺎم وﺟﻮد ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ‪ .‬وﻟﻲ اﮔﺮ ﭼﻨﻴﻦ ﻓﺎﻳﻠﻲ اﻳﺠﺎد ﺷﺪه ﺑﺎﺷﺪ آن را ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ‪ Delete‬ﺣﺬف ﻣﻲ ﻛﻨﻴﻢ‪:‬‬ ‫‪// Save - serialize the object to disk...‬‬ ‫)‪public void Save(String filename‬‬ ‫{‬ ‫‪// make a temporary filename...‬‬ ‫;‪String tempFilename‬‬ ‫;"‪tempFilename = filename + ".tmp‬‬ ‫?‪// does the file exist‬‬

‫‪٧٧٨‬‬

‫;)‪FileInfo tempFileInfo = new FileInfo(tempFilename‬‬ ‫)‪if (tempFileInfo.Exists‬‬ ‫;)(‪tempFileInfo.Delete‬‬

‫در ﻣﺮﺣﻠﻪ ي ﺑﻌﺪ ﻳﻚ ﻓﺎﻳﻞ ﺑﺎ ﻧﺎم ﻣﺸﺨﺺ ﺷـﺪه و ﭘـﺴﻮﻧﺪ ‪ .tmp‬اﻳﺠـﺎد ﻣـﻲ ﻛﻨـﻴﻢ‪ .‬ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﺑﺎﻳـﺪ ﻳـﻚ ﺷـﻴﺊ از ﻛـﻼس‬ ‫‪ FileStream‬ﻧﻤﻮﻧﻪ ﺳﺎزي ﻛﺮده و آدرس ﻓﺎﻳﻞ و ﻧﻴﺰ ﻧﻮع دﺳﺘﺮﺳﻲ ﺑﻪ آن را در ﻣﺘﺪ ﺳﺎزﻧﺪه ي ﻛﻼس ﻣﺸﺨﺺ ﻛﻨﻴﻢ‪.‬‬ ‫‪// open the file...‬‬ ‫‪FileStream stream = new FileStream(tempFilename,‬‬ ‫;)‪FileMode.Create‬‬

‫ﺳﭙﺲ اﻳﻦ ﺷﻴﺊ را ﺑﻪ ﻧﺴﺨﻪ ي دوم ﻣﺘﺪ ‪ Save‬ارﺳﺎل ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﻧﺤﻮه ي ﻋﻤﻠﻜﺮد اﻳﻦ ﻣﺘﺪ در اداﻣﻪ ﺗﻮﺿﻴﺢ داده ﺷﺪه اﺳﺖ‪ ،‬اﻣﺎ ﻓﻌﻼ‬ ‫ﺑﺪاﻧﻴﺪ ﻛﻪ ﻗﺴﻤﺖ اﺻﻠﻲ ﻋﻤﻞ ﺳﺮﻳﺎﻻﻳﺰ ﻛﺮدن درون اﻳﻦ ﻣﺘﺪ اﻧﺠﺎم ﻣﻲ ﺷﻮد‪.‬‬ ‫ﺳﭙﺲ ﻓﺎﻳﻞ را ﻣﻲ ﺑﻨﺪﻳﻢ‪:‬‬ ‫‪// close the file...‬‬ ‫;)(‪stream.Close‬‬

‫در ﻣﺮﺣﻠﻪ ي آﺧﺮ ﻧﻴﺰ اﺑﺘﺪا ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ‪ CopyTo‬ﻓﺎﻳﻞ را در ﻓﺎﻳﻞ ﺟﺪﻳﺪ ﺑﺎ ﻧﺎم اﺻﻠﻲ ﻛﭙﻲ ﻣﻲ ﻛﻨﻴﻢ )ﭘﺎراﻣﺘﺮ ‪ true‬ﻣـﺸﺨﺺ‬ ‫ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻫﻨﮕﺎم ﻛﭙﻲ ﻛﺮدن اﻳﻦ ﻓﺎﻳﻞ‪ ،‬اﮔﺮ ﻓﺎﻳﻠﻲ ﺑﺎ اﻳﻦ ﻧﺎم وﺟﻮد داﺷﺖ آن را ﺣﺬف ﻛﻦ(‪ ،‬ﺳﭙﺲ ﻓﺎﻳﻞ ﻣـﻮﻗﺘﻲ را ﺑـﺎ اﺳـﺘﻔﺎده از ﻣﺘـﺪ‬ ‫‪ Delete‬ﭘﺎك ﻣﻲ ﻛﻨﻴﻢ‪.‬‬ ‫‪// remove the existing data file and‬‬ ‫‪// rename the temp file...‬‬ ‫;)‪tempFileInfo.CopyTo(filename, true‬‬ ‫;)(‪tempFileInfo.Delete‬‬ ‫}‬

‫ﻧﺴﺨﻪ ي دوم ﻣﺘﺪ ‪ Save‬ﺑﻪ ﺟﺎي ﻳﻚ رﺷﺘﻪ‪ ،‬ﻳﻚ ﺷﻴﺊ از ﻛﻼس ‪ Stream‬و ﻳﺎ ﻳﻜـﻲ از ﻛﻼﺳـﻬﺎي ﻣـﺸﺘﻖ ﺷـﺪه از آن را ﺑـﻪ‬ ‫ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ و ﻣﺸﺎﺑﻪ زﻳﺮ اﺳﺖ‪:‬‬ ‫‪// Save - actually perform the serialization...‬‬ ‫)‪public void Save(Stream stream‬‬ ‫{‬ ‫‪// create a serializer...‬‬ ‫;)‪XmlSerializer serializer = new XmlSerializer(this.GetType‬‬ ‫‪// save the file...‬‬ ‫;)‪serializer.Serialize(stream, this‬‬ ‫}‬

‫ﻧﻜﺘﻪ‪ :‬ﺗﻤﺎم ﻣﻮارد ﻣﺮﺑﻮط ﺑﻪ ورودي و ﺧﺮوﺟﻲ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻛﻼﺳﻬﺎي ﻣﺸﺘﻖ ﺷﺪه از ﻛـﻼس ‪ Stream‬اﻧﺠـﺎم ﻣـﻲ‬ ‫ﺷﻮﻧﺪ‪ ،‬ﺑﺮاي ﻣﺜﺎل ﺧﻮاﻧﺪن و ﻧﻮﺷﺘﻦ در ﻳﻚ ﻓﺎﻳﻞ‪ ،‬ﺧﻮاﻧﺪن و ﻧﻮﺷﺘﻦ در ﺣﺎﻓﻈﻪ و …‪ .‬اﻳﻦ ﻛﻼس ﺑﻪ ﻫﻤﺮاه ﻛﻼﺳﻬﺎي دﻳﮕـﺮي در راﺑﻄـﻪ‬ ‫ﺑﺎ ﻫﻤﻴﻦ ﻣﻮﺿﻮع در ﻓﻀﺎي ﻧﺎم ‪ System.IO‬ﻗﺮار دارد‪.‬‬

‫‪٧٧٩‬‬

‫ﻛﻼس ‪ ،System.Xml.Srialization.XmlSerializer‬ﻛﻼﺳﻲ اﺳﺖ ﻛـﻪ در اﻳـﻦ ﻗـﺴﻤﺖ ﺑـﺮاي‬ ‫ﺳﺮﻳﺎﻻﻳﺰ ﻛﺮدن ﺷﻴﺊ اﻳﺠﺎد ﺷﺪه و ﻧﻮﺷﺘﻦ آن در ﺧﺮوﺟﻲ اي ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﭘﺎراﻣﺘﺮ ‪ stream‬ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﺑﻪ ﻛﺎر ﻣﻲ رود‪.‬‬ ‫در اﻳﻦ ﻗﺴﻤﺖ‪ ،‬از ﻳﻚ ﺧﺮوﺟﻲ اﺳﺘﻔﺎده ﻛﺮدﻳﻢ ﻛﻪ داده ﻫﺎ را در ﻳﻚ ﻓﺎﻳﻞ ﻗﺮار ﻣﻲ دﻫﺪ‪ ،‬اﻣﺎ در اداﻣـﻪ ي اﻳـﻦ ﻓـﺼﻞ از ﺧﺮوﺟـﻲ ﻫـﺎي‬ ‫دﻳﮕﺮي ﻧﻴﺰ اﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد‪.‬‬ ‫ﻛﻼس ‪ XmlSerializer‬ﺑﺎﻳﺪ ﺑﺪاﻧﺪ ﻛﻪ ﺑﺮاي ﺳﺮﻳﺎﻻﻳﺰ ﻛﺮدن ﭼﻪ ﻧﻮع ﺷﻴﺊ ﻣﻮرد اﺳﺘﻔﺎده ﻗـﺮار ﻣـﻲ ﮔﻴـﺮد‪ ،‬ﺑﻨـﺎﺑﺮاﻳﻦ ﻫﻨﮕـﺎم‬ ‫اﻳﺠﺎد ﺷﻴﺊ اي از اﻳﻦ ﻛﻼس‪ ،‬ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ‪ GetType‬ﻧﻮع ﺷـﻴﺊ را ﺑـﺮاي آن ﻣـﺸﺨﺺ ﻣـﻲ ﻛﻨـﻴﻢ‪ .‬ﻣﺘـﺪ ‪ GetType‬در‬ ‫ﻛﻼس ‪ Object‬ﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ و ﺷﻴﺊ ا ي را از ﻧﻮع ‪ System.Type‬ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﻣﻲ ﮔﺮداﻧﺪ ﻛـﻪ ﻧـﻮع ﻛﻼﺳـﻲ‬ ‫ﻛﻪ ﻫﻢ اﻛﻨﻮن ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ را ﻣﺸﺨﺺ ﻣـﻲ ﻛﻨـﺪ )ﻛـﻼس ‪ .(Address‬دﻟﻴـﻞ اﻳﻨﻜـﻪ ﺷـﻴﺊ اي ﻛـﻪ از ﻛـﻼس‬ ‫‪ XmlSerializer‬اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﻧﻴﺎز دارد ﺑﺪاﻧﺪ ﭼﻪ ﺷﻴﺊ را ﺑﺎﻳﺪ ﺳﺮﻳﺎﻻﻳﺰ ﻛﻨـﺪ در ﻧﺤـﻮه ي ﻋﻤﻠﻜـﺮد اﻳـﻦ ﻛـﻼس ﺑـﺮاي‬ ‫ﺳﺮﻳﺎﻻﻳﺰ ﻛﺮدن اﺳﺖ‪ .‬اﻳﻦ ﻛﻼس در ﺑﻴﻦ ﺧﺎﺻﻴﺘﻬﺎي ﻳﻚ ﺷﻴﺊ ﺣﺮﻛﺖ ﻣﻲ ﻛﻨﺪ و ﻣﻘﺪار ﺧﺎﺻﻴﺖ ﻫـﺎﻳﻲ را ﻛـﻪ ﺑـﻪ ﺻـﻮرت ﺧﻮاﻧـﺪﻧﻲ‪-‬‬ ‫ﻧﻮﺷﺘﻨﻲ ﺑﺎﺷﻨﺪ را )داراي ﻫﺮ دو ﻗﺴﻤﺖ ‪ get‬و ‪ set‬ﺑﺎﺷﻨﺪ( ﺑﻪ وﺳﻴﻠﻪ ي ﺷﻴﺊ ‪ stream‬ﻛﻪ ﺑﺮاي آن ﻣـﺸﺨﺺ ﺷـﺪه اﺳـﺖ در‬ ‫ﻓﺎﻳﻞ ‪ XML‬ﻗﺮار ﻣﻲ دﻫﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻨﺠﺎ‪ ،‬اﻳﻦ ﻛﻼس ﻣﻘﺪار ﺗﻤﺎم ﻓﻴﻠﺪ ﻫﺎي ﻣﻮﺟﻮد در ﻛﻼس ‪ Address‬را درﻳﺎﻓﺖ ﻛﺮده و آﻧﻬﺎ‬ ‫را ﺑﻪ ﺻﻮرت ‪ XML‬در ﻓﺎﻳﻞ ‪ AddressBook.xml‬ﻣﻲ ﻧﻮﻳﺴﺪ‪.‬‬ ‫ﻛﻼس ‪ XmlSerializer‬ﺑﺮاي ﻧﺎم ﻫﺮ ﻋﻨﺼﺮ در ﻓﺎﻳﻞ ‪ ،XML‬از ﻧﺎم ﺧﺎﺻﻴﺖ ﻳﺎ ﻓﻴﻠﺪ ﻣﺮﺑﻮط ﺑﻪ آن در ﻛﻼس اﺳـﺘﻔﺎده ﻣـﻲ‬ ‫ﻛﻨﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻋﻨﺼﺮ ‪ FirstName‬داراي داده ﻫﺎي ﻣﻮﺟﻮد در ﻋﻨﺼﺮ ﻓﻴﻠﺪ ‪ FirstName‬اﺳـﺖ‪ .‬ﻫﻤﭽﻨـﻴﻦ‬ ‫ﺑﺮاي ﻧﺎم ﻋﻨﺼﺮ رﻳﺸﻪ ﻧﻴﺰ از ﻧﺎم ﻛﻼس اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد‪ .‬ﺑﺮاي ﻣﺜﺎل در اﻳﻨﺠﺎ ﻧﺎم ﻋﻨﺼﺮ رﻳﺸﻪ ﺑﺮاﺑﺮ ﺑﺎ ‪ ،Address‬ﻳﻌﻨﻲ ﻧﺎم ﻛﻼس‬ ‫اﺳﺖ‪.‬‬ ‫ﻛﻼس ‪ XmlSerializer‬ﻳﻚ راه ﻣﻨﺎﺳﺐ ﺑﺮاي اﺳﺘﻔﺎده از ﻣﺰاﻳﺎي ‪ XML‬در ﺑﺮﻧﺎﻣﻪ اﺳﺖ‪ .‬زﻳﺮا ﺑﺎ اﺳﺘﻔﺎده از آن دﻳﮕﺮ ﻣﺠﺒﻮر‬ ‫ﻧﻴﺴﺘﻴﺪ ﺧﻮد را درﮔﻴﺮ ﺧﻮاﻧﺪن و ﻳﺎ ﻧﻮﺷﺘﻦ ﻓﺎﻳﻠﻬﺎي ‪ XML‬ﻛﻨﻴﺪ‪ ،‬ﺗﻤﺎم ﻛﺎرﻫﺎي ﻻزم را اﻳﻦ ﻛﻼس اﻧﺠﺎم ﻣﻲ دﻫﺪ‪.‬‬

‫درﻳﺎﻓﺖ داده ﻫﺎ از ﻳﻚ ﻓﺎﻳﻞ ‪:XML‬‬ ‫در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ‪ ،‬ﻗﺎﺑﻠﻴﺘﻲ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛﺮد ﺗﺎ ﺑﺘﻮاﻧﺪ داده ﻫﺎ را از ﻳﻚ ﻓﺎﻳﻞ ‪ XML‬ﺧﻮاﻧـﺪه و آﻧﻬـﺎ را در ﺑﺮﻧﺎﻣـﻪ‬ ‫ﻗﺮار دﻫﺪ‪ ،‬ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ داده ﻫﺎي ﻣﻮﺟﻮد در دﻳﺴﻚ را دي ﺳﺮﻳﺎﻻﻳﺰ ﺧﻮاﻫﻴﻢ ﻛﺮد‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬درﻳﺎﻓﺖ داده ﻫﺎ از ﻓﺎﻳﻞ ‪XML‬‬ ‫‪ (1‬وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس ‪ SerializableData‬را ﺑﺎز ﻛﺮده و دو ﻣﺘﺪ ﻣـﺸﺨﺺ ﺷـﺪه در زﻳـﺮ را ﺑـﻪ آن‬ ‫اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪:‬‬ ‫‪// Load - deserialize from disk...‬‬ ‫)‪public static Object Load(String filename, Type newType‬‬ ‫{‬ ‫?‪// does the file exist‬‬ ‫;)‪FileInfo fileInfo = new FileInfo(filename‬‬ ‫)‪if(!fileInfo.Exists‬‬ ‫{‬ ‫‪// create a blank version of the object and return that...‬‬ ‫;)‪return System.Activator.CreateInstance(newType‬‬

‫‪٧٨٠‬‬

} // open the file... FileStream stream = new FileStream(filename, FileMode.Open); // load the object from the stream... Object newObject = Load(stream, newType); // close the stream... stream.Close(); // return the object... return newObject; } public static Object Load(Stream stream,Type newType) { // create a serializer and load the object.... XmlSerializer serializer = new XmlSerializer(newType); Object newObject = serializer.Deserialize(stream); // return the new object... return newObject; }

‫ دﻳﮕـﺮ را ﺑـﻪ ﻓـﺮم‬Button ‫ ﻳﻚ ﻛﻨﺘﺮل‬،‫ ﺑﺮﮔﺸﺘﻪ و ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار‬Form1 ‫( ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ‬2 ‫& ﻗـﺮار‬Load ‫ آن را ﺑﺮاﺑـﺮ ﺑـﺎ‬Text ‫ و ﺧﺎﺻـﻴﺖ‬btnLoad ‫ اﻳﻦ ﻛﻨﺘﺮل را ﺑﺮاﺑﺮ ﺑﺎ‬Name ‫ ﺧﺎﺻﻴﺖ‬.‫اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬ .‫دﻫﻴﺪ‬ ‫ ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در‬.‫ آن اﻳﺠﺎد ﺷﻮد‬Click ‫( روي اﻳﻦ دﻛﻤﻪ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﺮده ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد‬3 :‫اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ‬ private void btnLoad_Click(object sender, EventArgs e) { // load the address using a shared method on SerializableData... Address newAddress = (Address)SerializableData.Load(DataFileName, typeof(Address) ); // update the display... PopulateFormFromAddress(newAddress); }

:‫ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬Form1 ‫( ﻫﻤﭽﻨﻴﻦ ﻻزم اﺳﺖ ﻛﻪ ﻣﺘﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﻧﻴﺰ ﺑﻪ ﻛﻼس‬4 // PopulateFormFromAddress - populates the form from an // address object... public void PopulateFormFromAddress(Address address) // copy the values... { txtFirstName.Text = address.FirstName; txtLastName.Text = address.LastName; txtCompanyName.Text = address.CompanyName; txtAddress1.Text = address.Address1; txtAddress2.Text = address.Address2; txtCity.Text = address.City; txtRegion.Text = address.Region; txtPostalCode.Text = address.PostalCode; txtCountry.Text = address.Country; txtEmail.Text = address.Email; }

٧٨١

‫‪ (5‬ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و روي دﻛﻤﻪ ي ‪ Load‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﻳﺎ دﻛﻤﻪ ﻫﺎي ‪ Alt+L‬را ﻓﺸﺎر دﻫﻴﺪ‪ .‬اﻃﻼﻋﺎﺗﻲ ﻛﻪ در ﻗﺴﻤﺖ‬ ‫ﻗﺒﻞ وارد ﻛﺮده ﺑﻮدﻳﺪ‪ ،‬ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪ 2-19‬در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﻨﺪ ﺷﺪ‪.‬‬

‫ﺷﻜﻞ ‪2-19‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫دي ﺳﺮﻳﺎﻻﻳﺰ ﻛﺮدن‪ ,‬ﻋﻤﻞ ﻋﻜﺲ ﺳﺮﻳﺎﻻﻳﺰ ﻛﺮدن اﺳﺖ‪ .‬ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﺪ داده ﻫﺎﻳﻲ را ﻛﻪ در ﻳﻚ ﻓﺎﻳﻞ ﺑﺎ ﻗﺎﻟـﺐ ‪XML‬‬ ‫ذﺧﻴــﺮه ﺷــﺪه اﻧــﺪ را اﺳــﺘﺨﺮاج ﻛــﺮده و در ﺑﺮﻧﺎﻣــﻪ ﻗــﺮار دﻫﻴــﺪ‪ .‬ﺑــﺮاي دي ﺳــﺮﻳﺎﻻﻳﺰ ﻛــﺮدن ﻳــﻚ ﺷــﻴﺊ ﻧﻴــﺰ ﻣــﻲ ﺗﻮاﻧﻴــﺪ از ﻛــﻼس‬ ‫‪ XmlSerializer‬اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬ ‫ﺑﺮاي اﻳﻦ ﻛﺎر ﻧﻴﺰ ﻣﺎﻧﻨﺪ ﻗﺒﻞ دو ﻧﺴﺨﻪ ي ﮔﻮﻧﺎﮔﻮن از ﻣﺘﺪ ‪ Load‬اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﻧﺴﺨﻪ ي اول دو ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨـﺪ‪ :‬ﭘـﺎراﻣﺘﺮ‬ ‫اول از ﻧــﻮع ‪ String‬اﺳــﺖ و آدرس ﻓــﺎﻳﻠﻲ را ﻣــﺸﺨﺺ ﻣــﻲ ﻛﻨــﺪ ﻛــﻪ داده ﻫــﺎ در آن ﻗــﺮار دارد‪ ،‬ﭘــﺎراﻣﺘﺮ دوم ﻧﻴــﺰ از ﻧــﻮع‬ ‫‪ System.Type‬اﺳﺖ و ﻧﻮع ﻛﻼﺳﻲ را درﺑﺮ دارد ﻛﻪ ﺑﺎﻳﺪ داده ﻫﺎ ﺑﻪ ﺷﻴﺊ اي از آن ﻧﻮع ﺗﺒﺪﻳﻞ ﺷﻮﻧﺪ‪ .‬ﺑﺮاي ﻓﺮاﺧﻮاﻧﻲ اﻳﻦ ﺗـﺎﺑﻊ‬ ‫ﭘﺎراﻣﺘﺮ دوم ﺑﻪ اﻳﻦ دﻟﻴﻞ ﻣﻮرد ﻧﻴﺎز اﺳﺖ ﻛﻪ ﻛﻼس ‪ XmlSerializer‬ﺑﺎ ﺗﻮﺟـﻪ ﺑـﻪ آن ﺑﺘﻮاﻧـﺪ ﺗـﺸﺨﻴﺺ دﻫـﺪ ﻣﻘـﺎدﻳﺮ ﭼـﻪ‬ ‫ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﺑﺎﻳﺪ در ﻓﺎﻳﻞ وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﻨﺪ ﺗﺎ ﺑﺘﻮاﻧﺪ آﻧﻬﺎ را از ﻓﺎﻳﻞ اﺳﺘﺨﺮاج ﻛﻨﺪ؟‬ ‫دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﻛﻼس ‪ XmlSerializer‬ﻫﻴﭻ اﻃﻼﻋﺎﺗﻲ در ﻣﻮرد ﻓﻀﺎي ﻧﺎم و ﻳﺎ ﻓﺎﻳﻞ اﺳﻤﺒﻠﻲ ﻛﻪ ﺷﻴﺊ ﺑـﻪ آن ﺗﻌﻠـﻖ دارد را‬ ‫در ﻓﺎﻳﻞ ‪ XML‬ذﺧﻴﺮه ﻧﻤﻲ ﻛﻨﺪ‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎم دي ﺳﺮﻳﺎﻻﻳﺰ ﻛﺮدن ﻓﻘﻂ ﺑﺮ اﺳﺎس ﮔﻔﺘﻪ ي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ در ﻣﻮرد ﻧﻮع ﺷﻴﺊ داده ﻫﺎي‬ ‫درون ﻓﺎﻳــﻞ را ﺑﺮرﺳــﻲ ﻣــﻲ ﻛﻨــﺪ و ﺳــﻌﻲ ﻣــﻲ ﻛﻨــﺪ ﺷــﻴﺊ اي از ﻧــﻮع ﻛــﻼس ﻣــﺸﺨﺺ ﺷــﺪه را اﻳﺠــﺎد ﻛﻨــﺪ )ﻛــﻼس‬ ‫‪ XmlSerializer‬ﻓﻘﻂ ﻧﺎم ﻛﻼﺳﻲ ﻛﻪ ﺳﺮﻳﺎﻻﻳﺰ ﻛﺮده اﺳﺖ را ﺑﻪ ﻋﻨﻮان ﻧﺎم ﻋﻨﺼﺮ رﻳﺸﻪ ﻗﺮار ﻣﻲ دﻫﺪ‪ ،‬وﻟﻲ ﺑﺎ اﺳﺘﻔﺎده از آن‬

‫‪٧٨٢‬‬

‫ﻫﻢ ﻧﻤﻲ ﺗﻮاﻧﺪ ﻧﻮع واﻗﻌﻲ ﻛـﻼس را ﺗـﺸﺨﻴﺺ دﻫـﺪ‪ .‬زﻳـﺮا ﺑـﺮاي ﻧﻤﻮﻧـﻪ در ﻣﺜـﺎل ﺑـﺎﻻ ﻣﻤﻜـﻦ اﺳـﺖ ﺷـﻤﺎ ﭼﻨـﺪﻳﻦ ﻛـﻼس ﺑـﻪ ﻧـﺎم‬ ‫‪ Address‬در ﻓﻀﺎي ﻧﺎﻣﻬﺎي ﮔﻮﻧﺎﮔﻮن داﺷﺘﻪ ﺑﺎﺷﻴﺪ(‪.‬‬ ‫ﻣﺴﻠﻤﺎً در ﻧﺴﺨﻪ ي اول ﻣﺘﺪ ‪ Save‬اوﻟﻴﻦ ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ اﻧﺠﺎم دﻫﻴﻢ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺒﻴﻨﻴﻢ آﻳﺎ ﻓﺎﻳﻞ ﻣﺸﺨﺺ ﺷﺪه وﺟﻮد دارد ﻳﺎ ﻧﻪ؟ اﮔﺮ‬ ‫ﻓﺎﻳﻞ وﺟﻮد ﻧﺪاﺷﺖ ﻳﻚ ﺷﻴﺊ ﺧﺎﻟﻲ از ﻧﻮع ‪ Address‬اﻳﺠﺎد ﻛﺮده و آن را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﻣﻲ ﮔﺮداﻧﻴﻢ‪:‬‬ ‫‪// Load - deserialize from disk...‬‬ ‫)‪public static Object Load(String filename, Type newType‬‬ ‫{‬ ‫?‪// does the file exist‬‬ ‫;)‪FileInfo fileInfo = new FileInfo(filename‬‬ ‫)‪if(!fileInfo.Exists‬‬ ‫{‬ ‫‪// create a blank version of the object and return that...‬‬ ‫;)‪return System.Activator.CreateInstance(newType‬‬ ‫}‬

‫اﻣﺎ اﮔﺮ ﻓﺎﻳﻞ وﺟﻮد داﺷﺖ‪ ،‬ﻣﺎﻧﻨﺪ ﻣﺘﺪ ‪ Save‬آن را ﺑﺎز ﻣﻲ ﻛﻨﻴﺪ و ﺳﭙﺲ ﺑﻪ ﻧﺴﺨﻪ ي دوم ﻣﺘﺪ ‪ Load‬ﻣﻲ ﻓﺮﺳـﺘﻴﺪ‪ .‬ﺳـﭙﺲ ﻓﺎﻳـﻞ را‬ ‫ﻣﻲ ﺑﻨﺪﻳﺪ و ﺷﻴﺊ اي ﻛﻪ از ﻧﺴﺨﻪ ي دوم ﻣﺘﺪ ‪ Load‬ﺑﺮﮔﺸﺘﻪ اﺳﺖ را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﻣﻲ ﮔﺮداﻧﻴﺪ‪:‬‬ ‫‪// open the file...‬‬ ‫;)‪FileStream stream = new FileStream(filename, FileMode.Open‬‬ ‫‪// load the object from the stream...‬‬ ‫;)‪Object newObject = Load(stream, newType‬‬ ‫‪// close the stream...‬‬ ‫;)(‪stream.Close‬‬ ‫‪// return the object...‬‬ ‫;‪return newObject‬‬ ‫}‬

‫ﻧﺴﺨﻪ ي دوم ﻣﺘﺪ ‪ Load‬ﻧﻴﺰ دوم ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ‪ :‬ﭘﺎراﻣﺘﺮ اول ﻳﻚ ﺷﻴﺊ از ﻧﻮع ‪ Stream‬اﺳﺖ ﻛـﻪ ﺣـﺎوي اﺗـﺼﺎﻟﻲ ﺑـﻪ‬ ‫ﻓﺎﻳﻞ ‪ XML‬ﻣﻮرد ﻧﻈﺮ اﺳﺖ‪ .‬ﭘﺎراﻣﺘﺮ دوم ﻧﻴﺰ ﻳﻚ ﺷﻴﺊ از ﻛﻼس ‪ System.Type‬اﺳﺖ و ﻧﻮع ﺷﻴﺊ را ﻣﺸﺨﺺ ﻣـﻲ ﻛﻨـﺪ ﻛـﻪ‬ ‫ﺑﺎﻳﺪ ﺑﻪ وﺳﻴﻠﻪ ي ﻛﻼس ‪ XmlSerializer‬اﻳﺠﺎد ﺷﻮد‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ اﻳﻦ ﻣﺘﺪ ﺑﺴﻴﺎر ﻣـﺸﺎﺑﻪ ﻣﺘـﺪ ‪Save‬‬ ‫اﺳﺖ ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ ﺗﻮﺿﻴﺢ دادﻳﻢ و ﻧﻜﺘﻪ ي ﺧﺎﺻﻲ ﻧﺪارد‪ .‬ﻓﻘﻂ در اﻳﻦ ﻣﺘﺪ ﺑﺎ اﺳـﺘﻔﺎده از ﻣﺘـﺪ ‪ Deserialize‬از ﻛـﻼس‬ ‫‪ XmlSerializer‬ﺷﻴﺊ ﻣﻮرد ﻧﻈﺮ را ﺑﺮ اﺳﺎس داده ﻫﺎي ﻣﻮﺟﻮد در ﻓﺎﻳﻞ ‪ XML‬اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ‪:‬‬ ‫)‪public static Object Load(Stream stream,Type newType‬‬ ‫{‬ ‫‪// create a serializer and load the object....‬‬ ‫;)‪XmlSerializer serializer = new XmlSerializer(newType‬‬ ‫;)‪Object newObject = serializer.Deserialize(stream‬‬ ‫‪// return the new object...‬‬ ‫;‪return newObject‬‬ ‫}‬

‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺘﺪ ‪ Deserialize‬را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢ‪ ،‬ﺑﺎﻳﺪ ﻧﻮع ﺷﻴﺊ اي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ اﻳﺠﺎد ﻛﻨـﻴﻢ را ﺑـﺮاي آن ﻣـﺸﺨﺺ‬ ‫ﻛﻨﻴﻢ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﻳﻦ ﻣﺘﺪ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻴﻦ ﺗﻤﺎم ﺧﺎﺻﻴﺖ ﻫﺎي آن ﺷﻴﺊ ﺣﺮﻛﺖ ﻛﺮده و ﺑﻪ دﻧﺒﺎل آﻧﻬﺎﻳﻲ ﺑﮕﺮدد ﻛـﻪ از ﻧـﻮع ﺧﻮاﻧـﺪﻧﻲ‪-‬‬ ‫ﻧﻮﺷﺘﻨﻲ ﺑﺎﺷﻨﺪ‪ .‬ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﭼﻨﻴﻦ ﺧﺎﺻﻴﺘﻲ را ﭘﻴﺪا ﻛﺮد‪ ،‬ﺑﻪ داﺧﻞ ﻓﺎﻳﻞ ‪ XML‬ﻣﻲ رود و ﺳﻌﻲ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻣﻘﺪار آن ﺧﺎﺻﻴﺖ را از داﺧﻞ‬

‫‪٧٨٣‬‬

‫آن ﻓﺎﻳﻞ اﺳﺘﺨﺮاج ﻛﻨﺪ و ﺑﻨﺎﺑﺮاﻳﻦ ﺷﻴﺊ را اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ ﻛﻪ ﻣﻘﺎدﻳﺮ درون ﺧﺎﺻﻴﺖ ﻫﺎ و ﻓﻴﻠﺪ ﻫﺎي آن دﻗﻴﻘﺎً ﺑﺮاﺑﺮ ﺑﺎ ﻣﻘﺎدﻳﺮي اﺳﺖ ﻛﻪ در‬ ‫ﻓﺎﻳﻞ ‪ XML‬ﻗﺮار داده ﺑﻮدﻳﻢ‪.‬‬ ‫در ﻓﺮم اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺘﺪ ‪ btnLoad_Click‬ﻓﺮاﺧﻮاﻧﻲ ﺷﺪ‪ ،‬ﻣﺘﺪ ‪ Load‬را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﺑـﺮاي ﻣـﺸﺨﺺ‬ ‫ﻛﺮدن ﻣﻘﺪار ﭘﺎراﻣﺘﺮ دوم اﻳﻦ ﻣﺘﺪ‪ ،‬از ﻋﻤﻠﮕﺮ ‪ typeof‬اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻧﻮع ﺷﻴﺊ ﻣﻮرد ﻧﻴﺎز را ﺑﺪﺳﺖ آورﻳﻢ‪ .‬اﻳﻦ ﻋﻤﻠﮕﺮ ﻳﻚ ﺷﻴﺊ‬ ‫از ﻛﻼس ‪ System.Type‬را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ ﻛﻪ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ي ﻧﻮع ﻛﻼﺳﻲ اﺳﺖ ﻛﻪ ﺑﻪ آن ﻓﺮﺳﺘﺎده ﺷﺪه‪ .‬ﻣﺘﺪ ‪ Load‬ﻧﻴـﺰ‬ ‫ﻳﻚ ﺷﻴﺊ از ﻛﻼس ‪ Object‬ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﻣﻲ ﮔﺮداﻧﺪ‪ ،‬ﭘﺲ آن را اﺑﺘﺪا ﺑﻪ ﺷﻴﺊ اي از ﻛﻼس ‪ Address‬ﺗﺒﺪﻳﻞ ﻛـﺮده و‬ ‫ﻧﺘﻴﺠﻪ را در ‪ newAddress‬ﻗﺮار ﻣﻲ دﻫﻴﻢ‪ .‬ﺳﭙﺲ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ‪ ،PopulateFormFromAddres‬داده ﻫﺎي‬ ‫ﺷﻴﺊ ﺟﺪﻳﺪ را در ﻓﺮم ﻗﺮار ﻣﻲ دﻫﻴﻢ‪.‬‬ ‫)‪private void btnLoad_Click(object sender, EventArgs e‬‬ ‫{‬ ‫‪// load the address using a shared method on SerializableData...‬‬ ‫‪Address newAddress = (Address)SerializableData.Load(DataFileName,‬‬ ‫;) )‪typeof(Address‬‬ ‫‪// update the display...‬‬ ‫;)‪PopulateFormFromAddress(newAddress‬‬ ‫}‬

‫ﺗﻐﻴﻴﺮ در داده ﻫﺎ‪:‬‬ ‫ﺑﺮاي اﻳﻨﻜﻪ ﺛﺎﺑﺖ ﻛﻨﻴﻢ در اﻳﻦ ﻣﺮاﺣﻞ ﻫﻴﭻ ﭼﻴﺰ ﻋﺠﻴﺐ و ﺧﺎﺻﻲ رخ ﻧﻤﻲ دﻫﺪ‪ ،‬در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ داده ﻫﺎ را ﺑﺎ اﺳﺘﻔﺎده از ﻳـﻚ‬ ‫وﻳﺮاﻳﺸﮕﺮ ﻣﺘﻨﻲ ﻣﺎﻧﻨﺪ ‪ notepad‬ﺗﻐﻴﻴﺮ داده و ﻧﺘﻴﺠﻪ را در ﺑﺮﻧﺎﻣﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﻢ‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﻳﺠﺎد ﺗﻐﻴﻴﺮ در داده ﻫﺎ‬ ‫‪ (1‬ﺑﺎ اﺳﺘﻔﺎده از ‪ Notepad‬ﻓﺎﻳﻞ ‪XML‬اي ﻛـﻪ در ﺑﺮﻧﺎﻣـﻪ اﻳﺠـﺎد ﻛـﺮده ﺑـﻮدﻳﻢ را ﺑـﺎز ﻛـﺮده و ﻣﻘـﺪار ﻣﻮﺟـﻮد در ﻋﻨـﺼﺮ‬ ‫‪ FirstName‬را ﺑﻪ ﻧﺎم دﻳﮕﺮي ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪ .‬ﺳﭙﺲ ﻓﺎﻳﻞ را ذﺧﻴﺮه ﻛﺮده و از ‪ Notepad‬ﺧﺎرج ﺷﻮﻳﺪ‪.‬‬ ‫‪ (2‬ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و روي دﻛﻤﻪ ي ‪ Load‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛـﺮد ﻛـﻪ ﻧـﺎم ﺟﺪﻳـﺪ در ﻗـﺴﻤﺖ ‪First‬‬ ‫‪ Name‬ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد‪.‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﻫــﺪف از اﻳــﻦ ﻣﺜــﺎل اﻳــﻦ ﺑــﻮد ﻛــﻪ ﺛﺎﺑــﺖ ﻛﻨــﻴﻢ ﻛــﻼس ‪ XmlSerializer‬ﻓﻘــﻂ از اﻃﻼﻋــﺎت داﺧــﻞ ﻓﺎﻳــﻞ‬ ‫‪ AddressBook.xml‬ﺑﺮاي اﻳﺠﺎد ﺷﻴﺊ ﻣﻮرد ﻧﻈﺮ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻫﺮ ﺗﻐﻴﻴﺮي ﻛﻪ در داده ﻫﺎي اﻳـﻦ ﻓﺎﻳـﻞ اﻳﺠـﺎد‬ ‫ﻛﻨﻴﺪ‪ ،‬ﻓﻴﻠﺪ ﻫﺎي ﻣﺘﻨﺎﻇﺮ در ﺷﻴﺊ ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﺗﻐﻴﻴﺮ ﺧﻮاﻫﻨﺪ ﻛﺮد‪.‬‬

‫‪٧٨٤‬‬

‫ﻓﺮﺳﺘﺎدن اﻳﻤﻴﻞ‪:‬‬ ‫در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ‪ ،‬ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ارﺳﺎل اﻳﻤﻴﻞ ﻣﺎﻧﻨـﺪ ‪Outlook‬‬ ‫ﺑﻪ آدرس اﻳﻤﻴﻞ ﻛﻪ در رﻛﻮرد ﻫﺎي اﻳﻦ دﻓﺘﺮ ﺗﻠﻔﻦ وارد ﻣﻲ ﺷﻮد ﻧﺎﻣﻪ ﻓﺮﺳﺘﺎد‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎ اﺳﺘﻔﺎده از ﻛﻼس ‪ ،Process‬ﺑﺮﻧﺎﻣﻪ‬ ‫ي ﻣﺮﺑﻮط ﺑﻪ ارﺳﺎل اﻳﻤﻴﻞ را اﺟﺮا ﻛﺮده و ﻧﺎﻣﻪ ي را ارﺳﺎل ﺧﻮاﻫﻴﻢ ﻛﺮد‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬ارﺳﺎل اﻳﻤﻴﻞ در ﺑﺮﻧﺎﻣﻪ‬ ‫‪ (1‬ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻣﺮﺑﻮط ﺑﻪ ‪ Form1‬ﺑﺮوﻳﺪ و ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل ‪ LinkLabel‬را در ﭘـﺎﻳﻴﻦ ﻟﻴﺒـﻞ‬ ‫‪ Email‬ﻗﺮار دﻫﻴﺪ‪ .‬ﺧﺎﺻﻴﺖ ‪ Name‬اﻳﻦ ﻛﻨﺘﺮل را ﺑﺮاﺑﺮ ﺑﺎ ‪ lnkSendEmail‬ﺧﺎﺻﻴﺖ ‪ Text‬آن را ﺑﺮاﺑﺮ ﺑـﺎ‬ ‫‪ Send Email‬ﻗﺮار دﻫﻴﺪ )ﺷﻜﻞ ‪.(3-19‬‬

‫ﺷﻜﻞ ‪3-19‬‬ ‫‪ (2‬روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ‪ LinkClicked‬آن ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴـﻚ اﻳﺠـﺎد ﺷـﻮد‪.‬‬ ‫ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ‪:‬‬ ‫‪private void lnkSendEmail_LinkClicked(object sender,‬‬ ‫)‪LinkLabelLinkClickedEventArgs e‬‬ ‫{‬ ‫‪// Start the email client...‬‬ ‫;)‪System.Diagnostics.Process.Start("mailto: " + txtEmail.Text‬‬ ‫}‬

‫‪٧٨٥‬‬

‫‪ (3‬ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و روي دﻛﻤﻪ ي ‪ Load‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ داده ﻫﺎ از ﻓﺎﻳﻞ اﺳﺘﺨﺮاج ﺷﻮﻧﺪ و در ﺑﺮﻧﺎﻣـﻪ ﻗـﺮار ﮔﻴﺮﻧـﺪ‪ .‬اﺑﺘـﺪا‬ ‫ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ ﻛﻪ آدرس اﻳﻤﻴﻞ ﻣﻮرد ﻧﻈﺮ ﺷﻤﺎ در ﻛﺎدر ‪ Email‬وارد ﺷﺪه اﺳﺖ‪ ،‬ﺳﭙﺲ روي ﻟﻴﻨﻚ ‪Send Email‬‬ ‫ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ي ﻛﻨﺘﺮل اﻳﻤﻴﻞ ﺷﻤﺎ ﺑﺎز ﺷﺪه و ﺑﻪ ﻗﺴﻤﺖ ﻣﺮﺑﻮط ﺑـﻪ ارﺳـﺎل اﻳﻤﻴـﻞ ﻣـﻲ رود‪ ،‬در‬ ‫ﺣﺎﻟﻲ ﻛﻪ ﻛﺎدر ‪ To:‬در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺎ آدرس اﻳﻤﻴﻠﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ وارد ﻛﺮده ﺑﻮدﻳﺪ ﻛﺎﻣﻞ ﺷﺪه اﺳﺖ‪.‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﻳﻜﻲ از ﻗﺎﺑﻠﻴﺘﻬﺎي دروﻧﻲ وﻳﻨﺪوز اﻳﻦ اﺳﺖ ﻛﻪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ آدرس اﻳﻨﺘﺮﻧﺘﻲ در آن وارد ﺷﺪ‪ ،‬ﺑﺘﻮاﻧﺪ ﻧﻮع آن را ﺗﺸﺨﻴﺺ دﻫﺪ و ﺑﺮﻧﺎﻣﻪ‬ ‫ي ﻣﺮﺑﻮط ﺑﻪ آن را اﺟﺮا ﻛﻨﺪ‪.‬‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل اﻳﻤﻴﻞ را در ﺳﻴﺴﺘﻢ ﺧﻮد ﻧﺼﺐ ﻣﻲ ﻛﻨﻴﺪ‪ ،‬اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻳﻚ ﭘﺮوﺗﻜﻞ ﺑـﻪ ﻧـﺎم ‪ mailto‬را‬ ‫در وﻳﻨﺪوز ﺛﺒﺖ ﻣﻲ ﻛﻨﺪ‪ ،‬دﻗﻴﻘﺎً ﻣﺎﻧﻨﺪ ﭘﺮوﺗﻜﻞ ‪ HTTP‬ﻛﻪ ﻫﻨﮕﺎم ﻧﺼﺐ ﻳﻚ ﻣﺮورﮔﺮ در وﻳﻨﺪوز ﺛﺒﺖ ﻣﻲ ﺷﻮد ﺗﺎ ﺗﻤﺎم آدرس ﻫﺎﻳﻲ ﻛﻪ ﺑﺎ‬ ‫آن ﺷﺮوع ﻣﻲ ﺷﻮﻧﺪ ﺑﻪ ﻣﺮورﮔﺮ ﻓﺮﺳﺘﺎده ﺷﻮﻧﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻤﺎم آدرس ﻫﺎﻳﻲ ﻛﻪ ﺑﺎ ‪ mailto‬ﺷﺮوع ﻣﻲ ﺷﻮﻧﺪ ﻧﻴﺰ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴـﻚ‬ ‫ﺑﻪ وﺳﻴﻠﻪ ي وﻳﻨﺪوز ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﻣﺮﺑﻮط ﺑﻪ ﻣﺪﻳﺮﻳﺖ اﻳﻤﻴﻞ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮﻧﺪ‪.‬‬ ‫ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﻧﺎﻣﻪ اي را در وﻳﻨﺪوز ارﺳﺎل ﻛﻨﻴﺪ‪ ،‬ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻣﻨﻮي اﺳﺘﺎرت ﮔﺰﻳﻨﻪ ي ‪ Run‬را اﻧﺘﺨـﺎب ﻛـﺮده و در آن ﻋﺒـﺎرت‬ ‫‪ mailto‬ﺑﻪ ﻫﻤﺮاه آدرس اﻳﻤﻴﻞ ﻣﻮرد ﻧﻈﺮ ﺧﻮد را وارد ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ روي دﻛﻤﻪ ي ‪ OK‬ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ‪ .‬ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﺑﺮﻧﺎﻣـﻪ ي‬ ‫ارﺳﺎل اﻳﻤﻴﻞ ﺑﺎز ﻣﻲ ﺷﻮد و ﻣﻲ ﺗﻮاﻧﻴﺪ ﻧﺎﻣﻪ ي ﻣﻮرد ﻧﻈﺮ ﺧﻮد را ﭘﺴﺖ ﻛﻨﻴﺪ‪.‬‬ ‫در ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ از روﺷﻲ ﻣﺸﺎﺑﻪ اﺳﺘﻔﺎده ﻣـﻲ ﻛﻨـﻴﻢ‪ ،‬ﻳﻌﻨـﻲ ﻣﻘـﺪار درون ﻓﻴﻠـﺪ ‪ txtEmail‬را ﺑﺪﺳـﺖ آورده و آن را ﺑﻌـﺪ از ﻋﺒـﺎرت‬ ‫‪ mailto‬ﻗــﺮار ﻣــﻲ دﻫــﻴﻢ ﺗــﺎ آدرس ﻣــﻮرد ﻧﻈــﺮ را اﻳﺠــﺎد ﻛﻨــﻴﻢ‪ .‬ﺳــﭙﺲ آدرس اﻳﺠــﺎد ﺷــﺪه را ﺑــﻪ ﻣﺘــﺪ ‪ Start‬از ﻛــﻼس‬ ‫‪ Process‬ارﺳﺎل ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﺮﻧﺎﻣﻪ ي ﻣﺮﺑﻮط ﺑﻪ ﻣﺪﻳﺮﻳﺖ اﻳﻤﻴﻞ را ﺑﺎز ﻛﻨﺪ‪:‬‬ ‫‪private void lnkSendEmail_LinkClicked(object sender,‬‬ ‫)‪LinkLabelLinkClickedEventArgs e‬‬ ‫{‬ ‫‪// Start the email client...‬‬ ‫;)‪System.Diagnostics.Process.Start("mailto: " + txtEmail.Text‬‬ ‫}‬

‫ﻣﺘﺪ ‪ Start‬ﻧﻴﺰ دﻗﻴﻘﺎً ﻣﺸﺎﺑﻪ ﭘﻨﺠﺮه ي ‪ Run‬در وﻳﻨﺪوز ﻋﻤﻞ ﻣﻲ ﻛﻨﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﺑﻪ ﺟﺎي ﻋﺒﺎرت ‪ mailto‬در ﻛﺪ ﺑـﺎﻻ از‬ ‫ﻋﺒﺎرت ‪ http‬اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ‪ ،‬آدرس وارد ﺷﺪه در ﻳﻚ ﺻﻔﺤﻪ ي وب در اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ اﮔﺮ در‬ ‫ﭘﺎراﻣﺘﺮ اﻳﻦ ﻣﺘﺪ ﻧﺎم ﻳﻚ ﻓﺎﻳﻞ ‪ Word‬و ﻳﺎ ﻳﻚ ﺻﻔﺤﻪ ﮔﺴﺘﺮده ي ‪ Excel‬را وارد ﻛﻨﻴﺪ‪ ،‬ﺑﺮﻧﺎﻣﻪ ﻫﺎي ‪ Word‬و ﻳﺎ ‪ Excel‬ﺑﺎز‬ ‫ﺷﺪه و ﻓﺎﻳﻞ ﻣﻮرد ﻧﻈﺮ ﺷﻤﺎ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ‪ .‬اﻟﺒﺘـﻪ اﮔـﺮ ﺑﺨﻮاﻫﻴـﺪ ﻳـﻚ ﻓﺎﻳـﻞ را اﺟـﺮا ﻛﻨﻴـﺪ ﻧﻴـﺎزي ﻧﻴـﺴﺖ ﻛـﻪ از ﭘﺮوﺗﻜﻠـﻲ ﻣﺎﻧﻨـﺪ‬ ‫‪ mailto‬و ﻳﺎ ‪ http‬اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ ،‬ﺑﻠﻜﻪ ﻛﺎﻓﻲ اﺳﺖ ﻧﺎم ﻓﺎﻳﻞ را ﺑﻪ ﻣﺘﺪ ‪ Start‬ارﺳﺎل ﻛﻨﻴﺪ ﻣﺎﻧﻨﺪ‪:‬‬ ‫‪C:\My Files\My Budgets.xls‬‬

‫اﻳﺠﺎد ﻟﻴﺴﺘﻲ از آدرﺳﻬﺎ‪:‬‬

‫‪٧٨٦‬‬

‫در اﻳﻦ ﻗﺴﻤﺖ از اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﺪ ﻟﻴﺴﺘﻲ از آدرﺳﻬﺎ را در ﻓﺎﻳﻞ ‪ XML‬ذﺧﻴﺮه ﻛﻨﺪ‪ .‬ﺗﺎ‬ ‫اﻳﻨﺠﺎ ﺑﺮﻧﺎﻣﻪ ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺪ ﻳﻚ آدرس را ﺑﻪ درﺳﺘﻲ در ﺧﻮد ﻧﮕﻬﺪاري ﻛﻨﺪ‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ از اﻳﻨﺠﺎ ﺑﻪ ﺑﻌﺪ ﺗﻮﺟﻪ ﺧﻮد را روي اﻳﺠﺎد ﻟﻴـﺴﺘﻲ‬ ‫از آدرﺳـــﻬﺎ ﻣﺘﻤﺮﻛـــﺰ ﻛﻨـــﻴﻢ‪ .‬ﺑـــﺮاي اﻳـــﻦ ﻛـــﺎر ﻛﻼﺳـــﻲ ﺑـــﻪ ﻧـــﺎم ‪ AddressBook‬اﻳﺠـــﺎد ﻛـــﺮده و آن را از ﻛـــﻼس‬ ‫‪ SerializableData‬ﻣﺸﺘﻖ ﻣﻲ ﻛﻨﻴﻢ‪ .‬زﻳﺮا در آﺧﺮ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻛﻼس ‪ AddressBook‬را ﺑـﻪ ﮔﻮﻧـﻪ اي اﻳﺠـﺎد‬ ‫ﻛﻨﻴﻢ ﻛﻪ ﺑﺘﻮاﻧﺪ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻳﻚ ﻣﺘﺪ داده ﻫﺎي درون ﺧﻮد را در دﻳﺴﻚ ذﺧﻴﺮه ﻛﺮده و ﻳﺎ داده ﻫﺎي ذﺧﻴﺮه ﺷﺪه در دﻳﺴﻚ را در ﺣﺎﻓﻈـﻪ‬ ‫ﻗﺮار دﻫﺪ‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﻳﺠﺎد ﻛﻼس ‪AddressBook‬‬ ‫‪ (1‬ﺑﺎ اﺳﺘﻔﺎده از ‪ Solution Explorer‬ﻳﻚ ﻛﻼس ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم ‪ AddressBook‬ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪.‬‬ ‫‪ (2‬اﺑﺘﺪا ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر ‪ using‬ﻓﻀﺎي ﻧﺎم زﻳﺮ را ﺑﻪ ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪:‬‬ ‫;‪using System.Xml.Serialization‬‬ ‫;‪using System.Collections‬‬ ‫‪namespace Address_Book‬‬ ‫{‬ ‫‪class AddressBook‬‬ ‫{‬

‫‪ (3‬ﺳﭙﺲ ﺗﻌﺮﻳﻒ ﻛﻼس را ﻣﺎﻧﻨﺪ زﻳﺮ ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ از ﻛﻼس ‪ SerializableData‬ﻣﺸﺘﻖ ﺷﻮد‪:‬‬ ‫‪namespace Address_Book‬‬ ‫{‬ ‫‪class AddressBook : SerializableData‬‬ ‫{‬

‫‪ (4‬ﺑﺮاي ذﺧﻴﺮه ﻛﺮدن آدرﺳﻬﺎ‪ ،‬از ﻛﻼس ‪ ArrayList‬در ﻓﻀﺎي ﻧـﺎم ‪ System.Collections‬اﺳـﺘﻔﺎده‬ ‫ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﭘﺲ در اﻳﻦ ﻛﻼس اﺑﺘﺪا ﺑﻪ ﻣﺘﺪي ﻧﻴﺎز دارﻳﻢ ﻛﻪ ﺑﺘﻮاﻧﺪ ﻳﻚ رﻛﻮرد ﺟﺪﻳﺪ را اﻳﺠﺎد ﻛﺮده و آن را ﺑـﻪ ﻟﻴـﺴﺖ رﻛـﻮرد‬ ‫ﻫﺎي ﻣﻮﺟﻮد اﺿﺎﻓﻪ ﻛﻨﺪ‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﺘﺪ زﻳﺮ را ﺑﻪ ﻛﻼس ‪ AddressBook‬اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪:‬‬ ‫‪class AddressBook : SerializableData‬‬ ‫{‬ ‫‪// members...‬‬ ‫;)(‪public ArrayList Items = new ArrayList‬‬ ‫‪// AddAddress - add a new address to the book...‬‬ ‫)(‪public Address AddAddress‬‬ ‫{‬ ‫‪// create one...‬‬ ‫;)(‪Address newAddress = new Address‬‬ ‫‪// add it to the list...‬‬ ‫;)‪Items.Add(newAddress‬‬ ‫‪// return the address...‬‬ ‫‪return newAddress‬‬ ‫}‬ ‫}‬

‫‪٧٨٧‬‬

:‫ را ﺑﺎز ﻛﺮده و ﺳﭙﺲ ﻛﺪ زﻳﺮ را ﺑﻪ اﺑﺘﺪاي ﻛﻼس اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬Form1 ‫( وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس‬5 public partial class Form1 : Form { // members... public AddressBook Addresses; private int _currentAddressIndex;

:‫ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬Form1 ‫( ﺳﭙﺲ ﺧﺎﺻﻴﺖ زﻳﺮ را ﺑﻪ‬6 // CurrentAddress - property for the current address... Address CurrentAddress { get { return AddressBook.Items[CurrentAddressIndex - 1]; } }

:‫ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬Form1 ‫( ﻫﻤﭽﻨﻴﻦ ﺧﺎﺻﻴﺖ زﻳﺮ را ﻧﻴﺰ ﺑﻪ ﻛﻼس‬7 // CurrentAddressIndex - property for the current address... int CurrentAddressIndex { get { return _currentAddressIndex; } set { // set the address... _currentAddressIndex = Value; // update the display... PopulateFormFromAddress(CurrentAddress); // set the label... lblAddressNumber.Text = _currentAddressIndex + " of " + AddressBook.Items.Count; } }

‫ آن‬Click ‫ رﻓﺘﻪ و روي ﻗﺴﻤﺘﻲ ﺧﺎﻟﻲ از ﻓﺮم دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑـﻪ روﻳـﺪاد‬Form1 ‫( ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ‬8 :‫ ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬.‫ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﺷﻮد‬ private void Form1_Load(object sender, EventArgs e) { // load the address book... Addresses = (AddressBook)SerializableData.Load(DataFileName, typeof(AddressBook)); // if the address book contains no item, add a new one... if (Addresses.Items.Count == 0) Addresses.AddAddress();

٧٨٨

‫‪// select the first item in the list...‬‬ ‫;‪CurrentAddressIndex = 1‬‬ ‫}‬

‫‪ (9‬ﺗﺎ اﻳﻨﺠﺎ ﺑﺮﻧﺎﻣﻪ ي ﺗﻮاﻧﺪ رﻛﻮرد ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ را ﻟﻮد ﻛﻨﺪ‪ .‬ﺣﺎل ﺑﺎﻳﺪ ﻗﺎﺑﻠﻴﺖ ذﺧﻴﺮه ﻛﺮدن را ﻧﻴﺰ اﺿﺎﻓﻪ ﻛﻨﻴﻢ‪ .‬ﺑﺮاي اﻳـﻦ‬ ‫ﻛﺎر در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ‪ ،Form1‬ﻓﺮم را اﻧﺘﺨﺎب ﻛﺮده و در ﭘﻨﺠـﺮه ي ‪ Properties‬روي آﻳﻜـﻮن ‪Events‬‬ ‫ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬در ﻟﻴﺴﺖ روﻳﺪادﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻓﺮم‪ ،‬روﻳﺪاد ‪ FormClosed‬را اﻧﺘﺨﺎب ﻛـﺮده و روي آن دو ﺑـﺎر ﻛﻠﻴـﻚ‬ ‫ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ آن اﻳﺠﺎد ﺷﻮد‪ .‬ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪:‬‬ ‫)‪private void Form1_FormClosed(object sender, FormClosedEventArgs e‬‬ ‫{‬ ‫‪// save the changes...‬‬ ‫;)(‪UpdateCurrentAddress‬‬ ‫;)(‪SaveChanges‬‬ ‫}‬

‫‪ (10‬در اﻧﺘﻬﺎ ﻧﻴﺰ دو ﻣﺘﺪ زﻳﺮ را ﻧﻴﺰ در ﻛﻼس ‪ Form1‬اﻳﺠﺎد ﻛﻨﻴﺪ‪:‬‬ ‫‪// SaveChanges - save the address book to an XML file...‬‬ ‫)(‪public void SaveChanges‬‬ ‫{‬ ‫‪// tell the address book to save itself...‬‬ ‫;)‪Addresses.Save(DataFileName‬‬ ‫}‬ ‫‪// UpdateCurrentAddress - make sure the book has the current‬‬ ‫‪// values currently entered into the form...‬‬ ‫)(‪private void UpdateCurrentAddress‬‬ ‫{‬ ‫;)‪PopulateAddressFromForm(CurrentAddress‬‬ ‫}‬

‫ﻧﻜﺘﻪ‪ :‬ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ‪ ،‬ﺑﺎﻳﺪ ﻓﺎﻳﻞ ‪ AddressBook.xml‬ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻠﻲ اﻳﺠﺎد ﺷﺪه ﺑﻮد را ﺣﺬف ﻛﻨﻴـﺪ‪.‬‬ ‫اﮔﺮ اﻳﻦ ﻛﺎر را اﻧﺠﺎم ﻧﺪﻫﻴﺪ‪ ،‬ﻛﻼس ‪ XmlSerializer‬ﺳﻌﻲ ﺧﻮاﻫﺪ رد ﻳﻚ ﺷﻴﺊ ‪ AddressBook‬را ﺑـﺎ اﺳـﺘﻔﺎده از‬ ‫داده ﻫﺎي ﻓﺎﻳﻞ ‪ XML‬ﻗﺒﻠﻲ اﻳﺠﺎد ﻛﻨﺪ ﻛﻪ ﺣﺎوي ﻳﻚ ﺷﻴﺊ از ﻧﻮع ‪ Address‬اﺳﺖ و ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ ﻳﻚ اﺳﺘﺜﻨﺎ رخ ﺧﻮاﻫﺪ داد‪.‬‬ ‫‪ (11‬ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ‪ ،‬اﻣﺎ ﻻزم ﻧﻴﺴﺖ ﺑﻪ ﺧﻮد زﺣﻤﺖ دﻫﻴﺪ و داده اي را در ﻓﺮم وارد ﻛﻨﻴﺪ زﻳﺮا ﻣﺘﺪ ‪ Save‬ﻛﺎر ﻧﻤﻲ ﻛﻨـﺪ‪ .‬ﺑـﺎ‬ ‫ﺑﺴﺘﻦ ﻓﺮم ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺧﻄﺎﻳﻲ ﻣﺸﺎﺑﻪ ﺷﻜﻞ ‪ 4-19‬رخ ﻣﻲ دﻫﺪ‪.‬‬

‫‪٧٨٩‬‬

‫ﺷﻜﻞ ‪4-19‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ )ﻳﺎ ﭼﮕﻮﻧﻪ ﻛﺎر ﻧﻤﻲ ﻛﻨﺪ(؟‬ ‫ﻫﻨﮕـــﺎﻣﻲ ﻛـــﻪ ﺑﺮﻧﺎﻣـــﻪ اﺟـــﺮا ﺷـــﺪه و ﻣﺘـــﺪ ‪ Form_Load‬ﻓﺮاﺧـــﻮاﻧﻲ ﻣـــﻲ ﺷـــﻮد‪ ،‬اﺑﺘـــﺪا اﻳـــﻦ ﻣﺘـــﺪ از ﻛـــﻼس‬ ‫‪ SerializableData‬ﻣﻲ ﺧﻮاﻫﺪ ﺗﺎ داده ﻫﺎي ﻣﻮﺟﻮد در ﻓﺎﻳﻞ ‪ AddressBook.xml‬را اﺳﺘﺨﺮاج ﻛـﺮده و در‬ ‫ﺑﺮﻧﺎﻣﻪ ﻗﺮار دﻫﺪ‪ ،‬اﻣﺎ ﭼﻮن ﻗﺒﻞ از اﺟﺮاي ﺑﺮﻧﺎﻣﻪ اﻳﻦ ﻓﺎﻳﻞ را ﭘﺎك ﻛﺮده اﻳﺪ‪ ،‬ﻛﻼس ‪ SerializableData‬ﻧﻤـﻲ ﺗﻮاﻧـﺪ ﺑـﻪ‬ ‫داده ﻫﺎي درون آن دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻣﺘﺪ ‪ Load‬ﻳﻚ ﻧﻤﻮﻧﻪ ي ﺟﺪﻳﺪ از ﻛﻼﺳﻲ ﻛﻪ ﻧﻮع آن را ﺑﺎ اﺳﺘﻔﺎده از ﭘـﺎراﻣﺘﺮ دوم‬ ‫ﺑﻪ آن ﻓﺮﺳﺘﺎده ﺑﻮدﻳﺪ اﻳﺠﺎد ﻛﺮده و آن را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ‪ .‬در اﻳﻦ ﺣﺎﻟﺖ‪ ،‬ﻳﻚ ﻧﻤﻮﻧﻪ از ﻛﻼس ‪ AddressBook‬ﺑﻪ وﺳـﻴﻠﻪ ي اﻳـﻦ‬ ‫ﻣﺘﺪ ﺑﺮﮔﺸﺘﻪ ﻣﻲ ﺷﻮد‪:‬‬ ‫)‪private void Form1_Load(object sender, EventArgs e‬‬ ‫{‬ ‫‪// load the address book...‬‬ ‫‪Addresses = (AddressBook)SerializableData.Load(DataFileName,‬‬ ‫;))‪typeof(AddressBook‬‬

‫اﻣﺎ ﺷﻴﺊ اي ﻛﻪ در ‪ Addresses‬ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ ﺷﺎﻣﻞ ﻫﻴﭻ آدرﺳﻲ ﻧﻤﻲ ﺷﻮد و ﺧﺎﻟﻲ اﺳﺖ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ در ﻳﻚ ﺷﺮط ﺑﺮرﺳﻲ ﻣﻲ‬ ‫ﻛﻨﻴﻢ ﺗﺎ اﮔﺮ ﻫﻴﭻ رﻛﻮردي در ﺷﻴﺊ ﻗﺮار ﻧﺪاﺷﺖ‪ ،‬ﻳﻚ رﻛﻮرد ﺧﺎﻟﻲ اﻳﺠﺎد ﻛﺮده و آن را ﺑﻪ ﻟﻴﺴﺖ آدرﺳﻬﺎ اﺿﺎﻓﻪ ﻛﻨﻴﻢ‪:‬‬ ‫‪// if the address book contains no item on it, add a new one...‬‬ ‫)‪if (Addresses.Items.Count == 0‬‬ ‫;)(‪Addresses.AddAddress‬‬

‫ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻌﺪ از اﺟﺮاي اﻳﻦ ﺧﻂ‪ ،‬ﻳﺎ ﻟﻴﺴﺖ ‪ Addresses‬ﺣﺎوي آدرس ﻫﺎي ﻣﻮﺟﻮد در ﻓﺎﻳﻞ ‪ XML‬اي اﺳﺖ ﻛﻪ ﻗﺒﻼ اﻳﺠـﺎد ﺷـﺪه‬ ‫ﺑﻮد‪ ،‬و ﻳﺎ اﻳﻦ ﻟﻴﺴﺖ ﻓﻘﻂ ﺷﺎﻣﻞ ﻳﻚ رﻛﻮرد ﺧﺎﻟﻲ ﻣﻲ ﺷﻮد ﻛﻪ آن را در دﺳﺘﻮر ‪ if‬اﻳﺠﺎد ﻛﺮده اﻳﻢ‪ .‬ﭘﺲ در ﻫـﺮ ﺻـﻮرت ﺣـﺪاﻗﻞ ﻳـﻚ‬ ‫رﻛﻮرد در اﻳﻦ ﻟﻴﺴﺖ وﺟﻮد ﺧﻮاﻫﺪ داﺷﺖ‪ .‬ﭘﺲ ﺧﺎﺻﻴﺖ ‪ CurrentAddressIndex‬را ﺑﺮاﺑﺮ ﺑﺎ ‪ 1‬ﻗﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ رﻛـﻮرد‬ ‫اول را در ﻛﺎدرﻫﺎي ﻣﻮﺟﻮد در ﻓﺮم ﻧﻤﺎﻳﺶ دﻫﺪ‪:‬‬ ‫‪// select the first item in the list...‬‬

‫‪٧٩٠‬‬

‫;‪CurrentAddressIndex = 1‬‬ ‫}‬

‫ﺧﺎﺻﻴﺖ ‪ CurrentAddressIndex‬ﻫﻨﮕﺎم ﺗﻨﻈﻴﻢ اﻧﺪﻳﺲ ﻳﻚ رﻛﻮرد ﭼﻨﺪﻳﻦ ﻛﺎر را اﻧﺠﺎم ﻣﻲ دﻫـﺪ‪ .‬اﺑﺘـﺪا ﻣﻘـﺪار ﻓﻴﻠـﺪ‬ ‫‪ _currentAddressIndex‬ﻛﻪ از ﻧﻮع ‪ private‬ﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ را ﺑﺮاﺑﺮ ﺑﺎ ﺷﻤﺎره رﻛﻮرد ﺟﺪﻳﺪ ﻗﺮار ﻣﻲ دﻫﺪ‪:‬‬ ‫‪// CurrentAddressIndex - property for the current address...‬‬ ‫‪int CurrentAddressIndex‬‬ ‫{‬ ‫‪get‬‬ ‫{‬ ‫;‪return _currentAddressIndex‬‬ ‫}‬ ‫‪set‬‬ ‫{‬ ‫‪// set the address...‬‬ ‫;‪_currentAddressIndex = value‬‬

‫ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ‪ CurrentAddress‬ﺷﻴﺊ ‪ Address‬ﻣﺮﺑﻮط ﺑﻪ رﻛﻮرد ﻛﻨﻮﻧﻲ را ﺑﺪﺳـﺖ آورده و آن را ﺑـﻪ‬ ‫ﻣﺘﺪ ‪ PopulateFormFromAddress‬را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ ﺗﺎ داده ﻫﺎي آن در ﻛﺎدرﻫﺎي ﻣﻮﺟﻮد در ﻓﺮم ﻧﻤـﺎﻳﺶ داده‬ ‫ﺷﻮد‪:‬‬ ‫‪// update the display...‬‬ ‫;)‪PopulateFormFromAddress(CurrentAddress‬‬

‫در آﺧﺮ ﻧﻴﺰ ﻣﺘﻦ ﻣﻮﺟﻮد در ﻛﻨﺘﺮل ‪ lblAddressNumber‬را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ ﻣﻲ دﻫﺪ ﺗﺎ ﺷﻤﺎره رﻛـﻮرد ﺟﺪﻳـﺪ را ﻧﻤـﺎﻳﺶ‬ ‫دﻫﺪ‪:‬‬ ‫‪// set the label...‬‬ ‫‪lblAddressNumber.Text = _currentAddressIndex + " of " +‬‬ ‫;‪Addresses.Items.Count‬‬ ‫}‬ ‫}‬

‫در اﻳﻦ ﺧﺎﺻﻴﺖ از ﺧﺎﺻﻴﺖ ‪ CurrentAddress‬اﺳﺘﻔﺎده ﻛﺮدﻳﻢ ﺗﺎ ﺑﻪ ﺳﺎدﮔﻲ ﺑـﻪ ﺷـﻴﺊ ‪ Address‬ﻣﺮﺑـﻮط ﺑـﻪ رﻛـﻮرد‬ ‫ﺟﺎري دﺳﺘﺮﺳـﻲ ﭘﻴـﺪا ﻛﻨـﻴﻢ‪ .‬وﻇﻴﻔـﻪ ي اﻳـﻦ ﺧﺎﺻـﻴﺖ ﺑـﻪ اﻳـﻦ ﺻـﻮرت اﺳـﺖ ﻛـﻪ ﺑـﺎ اﺳـﺘﻔﺎده از ﺷـﻤﺎره ي رﻛـﻮرد ﺟـﺎري ﻛـﻪ در‬ ‫‪ _currentAddressIndex‬ذﺧﻴــﺮه ﻣــﻲ ﺷــﻮد‪ ،‬ﺷــﻴﺊ ‪ Address‬ﻣﺮﺑــﻮط ﺑــﻪ اﻳــﻦ رﻛــﻮرد را از داﺧــﻞ ﻟﻴــﺴﺖ‬ ‫‪ Addresses‬اﺳﺘﺨﺮاج ﻛﺮده و آن را ﺑﺮﮔﺮداﻧﺪ‪ .‬اﻣـﺎ ﺑـﻪ ﺧـﺎﻃﺮ اﻳﻨﻜـﻪ ﻟﻴـﺴﺖ ‪ Addresses‬ﻫﻤﺎﻧﻨـﺪ ‪ArrayList‬‬ ‫ﻋﻨﺎﺻﺮ درون ﺧﻮد را از ﺻﻔﺮ ﺷﻤﺎره ﮔﺬاري ﻣﻲ ﻛﻨﺪ اﻣﺎ ﻋﻨﺎﺻﺮ ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ از ﻳﻚ ﺷﻤﺎره ﮔﺬاري ﻣﻲ ﺷﻮﻧﺪ‪ ،‬ﻻزم اﺳﺖ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ‬ ‫از ﺷﻤﺎره اﻧﺪﻳﺲ رﻛﻮرد ﺟﺎري ﻳﻚ واﺣﺪ ﻛﻢ ﻛﺮده ﺗﺎ ﺑﻪ رﻛﻮرد ﻣﻮرد ﻧﻈﺮ دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﻴﻢ‪:‬‬ ‫‪// CurrentAddress - property for the current address...‬‬ ‫‪Address CurrentAddress‬‬ ‫{‬ ‫‪get‬‬ ‫{‬ ‫;]‪return (Address)Addresses.Items[CurrentAddressIndex - 1‬‬

‫‪٧٩١‬‬

‫}‬ ‫}‬

‫ﺗﺎ اﻳﻨﺠﺎ ﻛﻪ ﻫﻤﻪ ﭼﻴﺰ ﺧﻮب ﭘﻴﺶ ﻣﻲ رود‪ .‬ﭘﺲ ﭼﺮا ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟﻪ ﺷﺪه اﺳﺖ؟ ﺧﻮب‪ ،‬ﻣﺸﻜﻞ زﻣﺎﻧﻲ ﺑﻪ وﺟﻮد ﻣﻲ آﻳﺪ ﻛﻪ ﺑﺨـﻮاﻫﻴﻢ‬ ‫از ﺑﺮﻧﺎﻣــﻪ ﺧــﺎرج ﺷــﻮﻳﻢ‪ .‬در اﻳــﻦ زﻣــﺎن ﻣﺘــﺪ ‪ FormClosed‬ﻓﺮاﺧــﻮاﻧﻲ ﺷــﺪه و اﻳــﻦ ﻣﺘــﺪ ﻧﻴــﺰ‪ ،‬ﻣﺘــﺪ ‪ Save‬از ﻛــﻼس‬ ‫‪ AddressBook‬را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ ﺗﺎ داده ﻫﺎ را ذﺧﻴﺮه ﻛﻨﺪ‪.‬‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﻛﻼس ‪ XmlSerializer‬ﺑﺮاي ﺳﺮﻳﺎﻻﻳﺰ ﻛﺮدن ﻳﻚ ﺷﻴﺊ در ﺑﻴﻦ ﺗﻤﺎم ﺧﺎﺻـﻴﺘﻬﺎي آن ﺣﺮﻛـﺖ ﻣـﻲ‬ ‫ﻛﻨﺪ ﺗﺎ ﺑﻪ ﻳﻚ ﺧﺎﺻﻴﺖ ﺧﻮاﻧﺪﻧﻲ‪-‬ﻧﻮﺷﺘﻨﻲ ﺑﺮﺳﺪ و ﺳﭙﺲ ﺳﻌﻲ ﻣﻲ ﻛﻨﺪ ﺗﺎ ﻣﻘﺪار آن ﺧﺎﺻﻴﺖ را در ﻓﺎﻳﻞ ‪ XML‬وارد ﻛﻨﺪ‪ .‬اﻣﺎ اﻳﻦ ﻛـﻼس‬ ‫ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺪ ﻣﻘﺎدﻳﺮ ﻣﺮﺑﻮط ﺑﻪ ﻧﻮع ﻫﺎي داده اي ﺳﺎده ﻣﺎﻧﻨﺪ ‪ System.String‬و ﻳﺎ ‪ System.Int32‬را در ﻓﺎﻳﻞ‬ ‫‪ XML‬ﺑﻨﻮﻳﺴﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ در ﺑﻴﻦ ﺧﺎﺻﻴﺘﻬﺎي ﻳﻚ ﻛﻼس ﺑﻪ ﻳﻚ ﺷﻴﺊ ﭘﻴﭽﻴﺪه ﺑﺮﺧﻮرد ﻛﺮد‪ ،‬وارد آن ﺷﻴﺊ ﭘﻴﭽﻴﺪه ﻣﻲ ﺷـﻮد و ﻫﻤـﻴﻦ‬ ‫ﻣﺮاﺣﻞ را ﺑﺮاي آن ﺷﻴﺊ ﻧﻴﺰ ﺗﻜﺮار ﻣﻲ ﻛﻨﺪ‪ .‬ﻳﻌﻨﻲ در ﺑﻴﻦ ﺧﺎﺻﻴﺘﻬﺎي آن ﺣﺮﻛﺖ ﻣﻲ ﻛﻨﺪ ﺗﺎ ﺑﻪ ﻳﻚ ﺧﺎﺻﻴﺖ ﺧﻮاﻧﺪﻧﻲ‪-‬ﻧﻮﺷﺘﻨﻲ ﻛﻪ از ﻧﻮع‬ ‫داده اي ﺳﺎده ﺑﺎﺷﺪ ﺑﺮﺳﺪ‪ .‬ﺳﭙﺲ ﻣﻘﺪار آن را در ﻓﺎﻳﻞ ‪ XML‬ﻣﻲ ﻧﻮﻳﺴﺪ‪ .‬اﮔﺮ در ﺷﻴﺊ دوم ﻧﻴﺰ ﺑﻪ ﻳﻚ ﺧﺎﺻﻴﺖ ﭘﻴﭽﻴﺪه ي دﻳﮕﺮ ﺑﺮﺧـﻮرد‬ ‫ﻛﺮد ﻫﻤﻴﻦ ﻣﺮاﺣﻞ را ﺗﻜﺮار ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫اﻣﺎ ﺧﻮب ﺑﻌﻀﻲ از ﻛﻼﺳﻬﺎ داراي ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﻛﻼس ‪ XmlSerializer‬ﻧﻤﻲ ﺗﻮاﻧﺪ آﻧﻬﺎ را ﺑﻪ ﻣﺘﻦ ﺗﺒﺪﻳﻞ ﻛـﺮده‬ ‫و در ﻓﺎﻳﻞ ‪ XML‬ﺑﻨﻮﻳﺴﺪ‪ ،‬و در اﻳﻨﺠﺎﺳﺖ ﻛﻪ اﻳﻦ ﻛﻼس ﺑﺎ ﺑﻦ ﺑﺴﺖ ﻣﻮاﺟﻪ ﻣﻲ ﺷﻮد‪ .‬ﻛﻼس ‪ ArrayList‬ﻳﻜﻲ از اﻳﻦ ﻛﻼﺳـﻬﺎ‬ ‫ﺑﻪ ﺷﻤﺎر ﻣﻲ رود‪ ،‬ﻳﻌﻨﻲ اﻳﻦ ﻛﻼس داراي ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﻧﻤﻲ ﺗﻮاﻧﻨﺪ ﺑـﻪ ﻣـﺘﻦ ﺗﺒـﺪﻳﻞ ﺷـﻮﻧﺪ ﺑﻨـﺎﺑﺮاﻳﻦ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻛـﻼس‬ ‫‪ XmlSerializer‬ﺑﻪ اﻳﻦ ﺧﺎﺻﻴﺖ ﻫﺎ ﺑﺮﺳﺪ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟﻪ ﺧﻮاﻫﺪ ﺷﺪ‪ .‬ﻛﺎري ﻛﻪ ﺑﺎﻳﺪ در اﻳﻨﺠﺎ اﻧﺠﺎم دﻫﻴﻢ‪ ،‬اﻳـﻦ اﺳـﺖ‬ ‫ﻛﻪ ﻳﻚ ﺧﺎﺻﻴﺖ دﻳﮕﺮ را ﺑﻪ ﮔﻮﻧﻪ اي اﻳﺠﺎد ﻛﺮده ﻛﻪ ﻛﻼس ‪ XmlSerializer‬ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ آدرس ﻫـﺎ از آن اﺳـﺘﻔﺎده‬ ‫ﻛﻨﺪ و ﻧﺨﻮاﻫﺪ ﻛﻪ از ﻛﻼس ‪ ArrayList‬اﺳﺘﻔﺎده ﻛﻨﺪ‪.‬‬

‫در ﻧﻈﺮ ﻧﮕﺮﻓﺘﻦ اﻋﻀﺎ‪:‬‬ ‫ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻛﻼس ‪ XmlSerializer‬ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻌﻀﻲ از ﻧﻮع ﻫﺎي داده اي را ﺑﻪ رﺷﺘﻪ ﺗﺒﺪﻳﻞ ﻛﺮده و ذﺧﻴﺮه ﻛﻨﺪ‪ ،‬اﻣﺎ اﻳﻦ‬ ‫ﻛﻼس ﺑﺎ ذﺧﻴﺮه ﻛﺮدن آراﻳﻪ ﻫﺎ ﻫﻴﭻ ﻣﺸﻜﻠﻲ ﻧﺪارد‪ .‬ﻫﻤﭽﻨﻴﻦ در ﻗﺴﻤﺖ ﻗﺒﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﻛﻼس ‪ XmlSerializer‬ﺑﺎ‬ ‫ﻛﻼس ‪ Address‬ﻫﻢ ﻫﻴﭻ ﻣﺸﻜﻠﻲ ﻧﺪارد و ﻣﻲ ﺗﻮاﻧﺪ ﺗﻤﺎم ﻓﻴﻠﺪ ﻫﺎ و ﺧﺎﺻﻴﺘﻬﺎي آن را ﺑﻪ ﻣﺘﻦ ﺗﺒﺪﻳﻞ ﻛﺮده و ذﺧﻴﺮه ﻛﻨﺪ‪ .‬در ﺑﺨﺶ‬ ‫اﻣﺘﺤــﺎن ﻛﻨﻴــﺪ ﺑﻌــﺪ‪ ،‬ﺧﺎﺻــﻴﺘﻲ را اﻳﺠــﺎد ﺧــﻮاﻫﻴﻢ ﻛــﺮد ﻛــﻪ ﻳــﻚ آراﻳــﻪ از ﻧــﻮع ‪ Address‬را ﺑﺮﮔﺮداﻧــﺪ و ﺳــﭙﺲ ﻛــﻼس‬ ‫‪ XmlSerializer‬را ﻣﺠﺒﻮر ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﺑﻪ ﺟﺎي اﺳﺘﻔﺎده از ‪ ،ArrayList‬داده ﻫﺎي ﻣﻮﺟﻮد در اﻳـﻦ ﺧﺎﺻـﻴﺖ را‬ ‫ذﺧﻴﺮه ﻛﻨﺪ‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬در ﻧﻈﺮ ﻧﮕﺮﻓﺘﻦ اﻋﻀﺎ‬ ‫‪ (1‬وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس ‪ AddressBook.cs‬را ﺑﺎز ﻛﻨﻴﺪ و ﺑﻪ ﺧﻄﻲ ﺑﺮوﻳـﺪ ﻛـﻪ ﻓﻴﻠـﺪ ‪ Items‬ﺗﻌﺮﻳـﻒ‬ ‫ﺷﺪه اﺳﺖ‪ .‬ﺳﭙﺲ ﺗﻌﺮﻳﻒ اﻳﻦ ﻓﻴﻠﺪ را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪:‬‬ ‫‪// members...‬‬ ‫])(‪[XmlIgnore‬‬ ‫;)(‪public ArrayList Items = new ArrayList‬‬

‫‪٧٩٢‬‬

:‫ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬AddressBook ‫( ﺣﺎل ﺧﺎﺻﻴﺖ زﻳﺮ را ﺑﻪ ﻛﻼس‬2 // Addresses - property that works with the items // collection as an array... public Address[] Addresses { get { // create a new array... Address[] addressArray = new Address[Items.Count]; Items.CopyTo(addressArray); return addressArray; } set { // reset the arraylist... Items.Clear(); // did you get anything? if (value != null) { // go through the array and populate items... foreach (Address address in value) { Items.Add(address); } } } }

‫ ﻣﺠﺪداً ﺑﺮﻧﺎﻣﻪ را اﺟـﺮا‬.‫ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻫﻤﻪ ﭼﻴﺰ ﺑﻪ درﺳﺘﻲ ﻋﻤﻞ ﻣﻲ ﻛﻨﺪ‬.‫( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺳﭙﺲ آن را ﺑﺒﻨﺪﻳﺪ‬3 ‫ ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ داده ﻫـﺎﻳﻲ ﻛـﻪ در‬.‫ﻛﺮده و اﻳﻦ ﻣﺮﺗﺒﻪ داده ﻫﺎﻳﻲ را در ﻓﻴﻠﺪ ﻫﺎي ﺑﺮﻧﺎﻣﻪ وارد ﻛﻨﻴﺪ و ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ را ﺑﺒﻨﺪﻳﺪ‬ ‫ ﻗﺮار ﺧﻮاﻫﻨﺪ ﮔﺮﻓـﺖ )ﺧﻄﻬـﺎي اﺿـﺎﻓﻲ ﺑـﺮاي‬AddressBook.xml ‫ﺑﺮﻧﺎﻣﻪ ﻧﻮﺷﺘﻪ ﺑﻮدﻳﺪ ﻣﺸﺎﺑﻪ ﻛﺪ زﻳﺮ در ﻓﺎﻳﻞ‬ (‫وﺿﻮح ﺑﻴﺸﺘﺮ ﺣﺬف ﺷﺪه اﻧﺪ‬
Muhammad Hashemian MyCompany 11 First Avenue No Where North 28222 Iran <Email>[email protected]


٧٩٣

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫داده ﻫﺎي ‪ XML‬اي ﻛﻪ درون ﻓﺎﻳﻞ وﺟﻮد دارﻧﺪ ﺛﺎﺑﺖ ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ اﻳﻦ ﻣﺮﺗﺒﻪ دﻳﮕﺮ درﺳـﺖ ﻛـﺎر ﻣـﻲ ﻛﻨـﺪ )ﭘـﺲ اﺣﺘﻤـﺎﻻ ﻻزم‬ ‫ﻧﺨﻮاﻫﺪ ﺑﻮد ﻋﻨﻮان ﺑﺨﺶ را ﺑﻪ ﭼﮕﻮﻧﻪ ﻛﺎر ﻧﻤﻲ ﻛﻨﺪ ﺗﻐﻴﻴﺮ دﻫﻴﻢ(‪ .‬اﻣﺎ ﺳﻮال اﻳﻨﺠﺎﺳﺖ ﻛﻪ ﭼﺮا اﻳﻦ ﻣﺮﺗﺒﻪ ﺑﺮﻧﺎﻣﻪ درﺳﺖ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫در اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ داراي دو ﺧﺎﺻﻴﺖ ﺧﻮاﻫﺪ ﺑﻮد‪ ،‬ﻳﻜﻲ ﺧﺎﺻﻴﺖ ‪ Items‬و دﻳﮕﺮي ﺧﺎﺻﻴﺖ ‪ .Addresses‬ﻫﺮ دوي‬ ‫اﻳﻦ ﺧﺎﺻﻴﺖ ﻫﺎ ﺧﻮاﻧﺪﻧﻲ‪-‬ﻧﻮﺷﺘﻨﻲ ﻫﺴﺘﻨﺪ‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ ﻛﻼس ‪ XmlSerializer‬ﻫﺮ دوي آﻧﻬﺎ را ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨـﺪ ﺗـﺎ ﺑﺘﻮاﻧـﺪ در‬ ‫ﻓﺎﻳﻞ ‪ XML‬ذﺧﻴﺮه ﻛﻨﺪ‪ .‬ﺧﺎﺻﻴﺖ ‪ Items‬ﻳﻚ ﺷﻴﺊ از ﻧﻮع ‪ ArrayList‬ﺑﺮﻣﻲ ﮔﺮداﻧﺪ و ﺧﺎﺻـﻴﺖ ‪ Addresses‬ﻧﻴـﺰ‬ ‫ﻳﻚ آراﻳﻪ از اﺷﻴﺎﻳﻲ از ﻧﻮع ‪.Address‬‬ ‫اﻣﺎ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻗﺒﻞ از ﺧﺎﺻﻴﺖ ‪ Items‬ﻛﺪي را درون ﻛﺮوﺷﻪ اﺿﺎﻓﻪ ﻛﺮدﻳﻢ ﻛﻪ ﻫﻤﺎﻧﻨﺪ ﺗﻌﺮﻳﻒ ﻛﻼﺳﻬﺎ در ﺑﺮﻧﺎﻣﻪ اﺳـﺖ‪ .‬اﻣـﺎ ﻣـﻲ‬ ‫داﻧﻴﺪ ﻛﻪ ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﺷﻴﺊ از ﻛﻼس ﻛﺪ را ﺑﻪ اﻳﻦ ﺻﻮرت ﻧﻤﻲ ﻧﻮﻳﺴﻨﺪ‪ .‬ﭘﺲ ﺳﻮاﻟﻲ ﻛﻪ ﭘﻴﺶ ﻣﻲ آﻳﺪ اﻳﻦ اﺳﺖ ﻛﻪ اﻳﻦ ﻛﺪ ﭼﻴﺴﺖ؟‬ ‫ﺑﺎ ﺧﺼﻴﺼﻪ ﻫﺎ در زﺑﺎن ‪ HTML‬و ﺣﺘﻲ ‪ XML‬ﻧﺴﺒﺘﺎ در ﻃﻮل ﻓﺼﻠﻬﺎي ﻗﺒﻞ آﺷﻨﺎ ﺷﺪﻳﻢ‪ .‬اﻣﺎ ﺑﺎﻳﺪ ﺑﺪاﻧﻴﺪ ﻛﻪ ﻛﺪ ﻫﺎﻳﻲ ﻛﻪ ﺑـﻪ زﺑـﺎن ‪C#‬‬ ‫ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮﻧﺪ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺷﺎﻣﻞ ﺧﺼﻴﺼﻪ ﺑﺎﺷﻨﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل ﻫﺮ ﻛﻼس‪ ،‬ﻫﺮ ﻣﺘﺪ‪ ،‬ﻫﺮ ﺧﺎﺻﻴﺖ و ﻳﺎ … در زﺑﺎن ‪ C#‬ﻣﻲ ﺗﻮاﻧﻨﺪ داراي‬ ‫ﺧﺼﻴﺼﻪ ﻫﺎي ﺧﺎص ﺧﻮد ﺑﺎﺷﻨﺪ ﻛﻪ اﻃﻼﻋﺎت ﺧﺎﺻﻲ را درﺑﺎره ي آن ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ‪ .‬ﺑﺮاي ﺗﻌﺮﻳﻒ ﻳﻚ ﺧﺼﻴﺼﻪ‪ ،‬ﺑﺎﻳﺪ آن را در ﺧـﻂ‬ ‫ﻗﺒﻞ از ﻋﻀﻮ ﻣﻮرد ﻧﻈﺮ در داﺧﻞ ﻛﺮوﺷﻪ ﺑﻨﻮﻳﺴﻴﻢ‪ .‬در اﻳﻦ ﻛﺪ ﻧﻴﺰ اﻳﻦ ﺧﻂ ﺧﺼﻴﺼﻪ اي را ﺑﺮاي ﻓﻴﻠﺪ ‪ Items‬ﺗﻌﺮﻳﻒ ﻣـﻲ ﻛﻨـﺪ‪ .‬اﻳـﻦ‬ ‫ﺧﺼﻴﺼﻪ ﻣﺸﺨﺺ ﻛﻨﻨﺪه ي اﻳﻦ ﻣﻮرد اﺳﺖ ﻛﻪ اﻳﻦ ﻓﻴﻠﺪ ﻧﺒﺎﻳﺪ ﺑﻪ وﺳـﻴﻠﻪ ي ﻛـﻼس ‪ XmlSerializer‬ﻣـﻮرد ﺑﺮرﺳـﻲ ﻗـﺮار‬ ‫ﺑﮕﻴﺮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ زﻣﺎﻧﻲ ﻛﻪ اﻳﻦ ﻛﻼس ﺑﻪ اﻳﻦ ﻓﻴﻠﺪ ﺑﺮﺳﺪ و ﺑﺨﻮاﻫﺪ ﻣﻘﺪار آن را در ﻓﺎﻳﻞ ‪ XML‬وارد ﻛﻨﺪ‪ ،‬ﺑﺎ دﻳﺪن اﻳـﻦ ﺧﺼﻴـﺼﻪ از روي‬ ‫اﻳﻦ ﻓﻴﻠﺪ ﻋﺒﻮر ﻛﺮده و ﺑﻪ ﺳﺮاغ ﺧﺎﺻﻴﺖ ﺑﻌﺪي‪ ،‬ﻳﻌﻨﻲ ‪ Addresses‬ﻣﻲ رود‪.‬‬ ‫ﻗﺴﻤﺖ ‪ get‬از ﺧﺎﺻﻴﺖ ‪ Addresses‬ﻗﺴﻤﺘﻲ اﺳﺖ ﻛﻪ در اﻳﻦ ﻛﺪ ﺑﺎﻳﺪ ﺑﻪ آن ﺗﻮﺟﻪ ﻛﻨﻴﻢ‪ .‬ﺗﻤﺎم ﻛﺎري ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﻧﺠﺎم‬ ‫ﻣـﻲ دﻫــﻴﻢ اﻳــﻦ اﺳــﺖ ﻛــﻪ ﻳــﻚ آراﻳــﻪ از ﻧــﻮع ‪ Address‬اﻳﺠــﺎد ﻛــﺮده و ﺳــﭙﺲ ﺑــﺎ اﺳــﺘﻔﺎده از ﻣﺘــﺪ ‪ CopyTo‬از ﻛــﻼس‬ ‫‪ ،ArrayList‬ﻓﻴﻠﺪ ﻫﺎي ﻣﻮﺟﻮد در ‪ ArrayList‬ر ا در اﻳﻦ آراﻳﻪ ﻗﺮار ﻣﻲ دﻫﻴﻢ‪:‬‬ ‫‪// Addresses - property that works with the items‬‬ ‫‪// collection as an array...‬‬ ‫‪public Address[] Addresses‬‬ ‫{‬ ‫‪get‬‬ ‫{‬ ‫‪// create a new array...‬‬ ‫;]‪Address[] addressArray = new Address[Items.Count‬‬ ‫;)‪Items.CopyTo(addressArray‬‬ ‫;‪return addressArray‬‬ ‫}‬ ‫‪set‬‬ ‫{‬ ‫…‬ ‫}‬ ‫}‬

‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﻼس ‪ XmlSerializer‬ﺑﻪ اﻳﻦ آراﻳﻪ رﺳﻴﺪ‪ ،‬ﺑﻴﻦ ﺗﻚ ﺗﻚ ﻋﻨﺎﺻﺮ آن ﺣﺮﻛﺖ ﻛﺮده و آﻧﻬﺎ را ﺳﺮﻳﺎﻻﻳﺰ ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫اﻳﻦ ﻣﻮرد را در ﻓﺎﻳﻞ ‪XML‬اي ﻛﻪ ﺗﻮﻟﻴﺪ ﺷﺪه اﺳﺖ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ‪ .‬اﺑﺘـﺪا ﻛـﻼس ‪ XmlSerializer‬وارد ﺷـﻴﺊ‬ ‫اﻳﺠﺎد ﺷﺪه از ﻛﻼس ‪ AddressBook‬ﻣﻲ ﺷﻮد‪ ،‬ﺳﭙﺲ ﺑﻪ اوﻟﻴﻦ ﺧﺎﺻﻴﺖ ﺧﻮاﻧﺪﻧﻲ‪-‬ﻧﻮﺷﺘﻨﻲ ﻣﻲ رﺳﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ داده ﻫﺎي آن‬ ‫را ذﺧﻴﺮه ﻛﻨﺪ‪ ،‬ﻳﻌﻨﻲ ﺧﺎﺻﻴﺖ ‪ .Addresses‬اﻳﻦ ﺧﺎﺻﻴﺖ ﺑﻪ ﺻﻮرت ﻳﻚ آراﻳﻪ اﺳﺖ‪ ،‬ﭘﺲ ﻛﻼس ﺳﻌﻲ ﻣﻲ ﻛﻨﺪ در ﺑﻴﻦ ﻋﻨﺎﺻﺮ آن‬

‫‪٧٩٤‬‬

‫ﺣﺮﻣﺖ ﻛﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ از ﻋﻨﺼﺮ اول ﺷﺮوع ﻣﻲ ﻛﻨﺪ و داده ﻫﺎي آن را در ﻋﻨﺼﺮ ‪ Address‬از ﻓﺎﻳﻞ ‪ XML‬ﻗﺮار ﻣﻲ دﻫـﺪ‪ .‬اﻣـﺎ اﻳـﻦ‬ ‫آراﻳﻪ ﻓﻘﻂ ﻳﻚ ﻋﻨﺼﺮ دارد‪ .‬ﭘﺲ در اﻳﻨﺠﺎ ﻛﺎر ﻛﻼس ‪ XmlSerializer‬ﺗﻤﺎم ﺷﺪه اﺳﺖ و ﺧﺮوﺟﻲ آن ﻣﺸﺎﺑﻪ زﻳﺮ ﺧﻮاﻫﺪ ﺑﻮد‪:‬‬ ‫>‪Muhammad‪Hashemian‪MyCompany‪11 First Avenue‪No Where‪North‪28222‪Iran‪<Email>[email protected]
‫اﺳﺘﺨﺮاج رﻛﻮرد ﻫﺎ از ﻓﺎﻳﻞ ‪:XML‬‬ ‫اﮔﺮ ﻣﻘﺪاري ﺷﺎﻧﺲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ‪ ،‬ﺑﺮﻧﺎﻣﻪ ﻫﻢ اﻛﻨﻮن ﺑﺎﻳﺪ ﺑﺘﻮاﻧﺪ ﻫﻨﮕﺎم اﺟﺮا ﺷﺪن داده ﻫﺎي ﻣﻮﺟﻮد در ﻓﺎﻳﻞ ‪ XML‬ﻗﺒﻠﻲ را اﺳﺘﺨﺮاج ﻛﺮده‬ ‫و در ﻓﺮم ﻧﻤﺎﻳﺶ دﻫﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ ﺑﺴﺘﻦ ﺑﺮﻧﺎﻣﻪ و اﺟﺮاي ﻣﺠﺪد آن ﺑﺎﻳﺪ ﺑﺎ ﻓﺮﻣﻲ ﻣﺸﺎﺑﻪ ﺷﻜﻞ ‪ 5-19‬ﻣﻮاﺟﻪ ﺷﻮﻳﺪ‪.‬‬ ‫دﻟﻴﻞ اﻳﻦ ﻣﻮرد در اﻳﻦ اﺳﺖ ﻛﻪ زﻣﺎﻧﻲ ﻛﻪ در ﺣﺎل ﻧﻮﺷﺘﻦ ﻛﻼس ‪ AddressBook‬ﺑﻮدﻳﺪ‪ ،‬ﻗﺴﻤﺖ ﻣﺮﺑـﻮط ﺑـﻪ ﻟـﻮد ﻛـﺮدن داده‬ ‫ﻫﺎي دﻓﺘﺮ ﺗﻠﻔﻦ ﻫﻨﮕﺎم اﺟﺮاي ﺑﺮﻧﺎﻣﻪ را ﻧﻴﺰ ﻛﺎﻣﻞ ﻛﺮدﻳﺪ‪ .‬اﻳﻦ ﻣﺮﺗﺒﻪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻣﻲ ﻛﻨﻴﺪ‪ ،‬ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ ﻣﺘـﺪ ‪ Load‬از ﻛـﻼس‬ ‫‪ SerializableData‬ﻓﺮاﺧﻮاﻧﻲ ﺷﻮد ﻓﺎﻳﻞ ‪ AddressBook.xml‬را در دﻳﺴﻚ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ‪ ،‬ﺑﻨـﺎﺑﺮاﻳﻦ دﻳﮕـﺮ‬ ‫ﻳﻚ ﺷﻴﺊ ﺧﺎﻟﻲ را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﻧﻤﻲ ﮔﺮداﻧﺪ ﺑﻠﻜﻪ ﺳﻌﻲ ﻣﻲ ﻛﻨﺪ داده ﻫﺎي ﻣﻮﺟﻮد در ﻓﺎﻳﻞ را دي ﺳﺮﻳﺎﻻﻳﺰ ﻛﻨـﺪ‪ .‬ﺧـﻮب ﺑـﻪ ﺧـﺎﻃﺮ‬ ‫اﻳﻨﻜﻪ ﻛﻼس ‪ XmlSerializer‬در ﻧﻮﺷﺘﻦ آراﻳﻪ ﻫﺎ ﻫﻴﭻ ﻣﺸﻜﻠﻲ ﻧﺪارد ﻣﻲ ﺗﻮان ﺣﺪس زد ﻛﻪ اﻳﻦ ﻛـﻼس در ﺧﻮاﻧـﺪن آﻧﻬـﺎ‬ ‫ﻧﻴﺰ ﻣﺸﻜﻠﻲ ﻧﺨﻮاﻫﺪ داﺷﺖ و ﻣﺘﺪ ‪ Deserialize‬از اﻳﻦ ﻛﻼس ﺑﺘﻮاﻧﺪ ﺑﻪ درﺳﻲ ﻛﺎر ﻛﻨﺪ‪.‬‬ ‫اﻳﻦ ﻣﺮﺗﺒﻪ دﻳﮕﺮ ﻗﺴﻤﺖ ‪ set‬از ﺧﺎﺻﻴﺖ ‪ Addresses‬ﺑﺴﻴﺎر ﻣﻬﻢ اﺳﺖ‪ .‬ﺗﻨﻬﺎ ﭼﻴﺰي ﻛﻪ در ﻛﺎر ﺑﺎ اﻳﻦ ﺧﺎﺻـﻴﺖ ﺑﺎﻳـﺪ ﻣـﺪ ﻧﻈـﺮ‬ ‫داﺷﺘﻪ ﺑﺎﺷﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ اﮔﺮ ﻳﻚ آراﻳﻪ ي ﺧﺎﻟﻲ را ﺑﻪ آن ارﺳﺎل ﻛﻨﻴﺪ )ﻣﻘﺪار ‪ null‬را ﺑـﻪ آن ﺑﻔﺮﺳـﺘﻴﺪ(‪ ،‬ﺧﺎﺻـﻴﺖ ﺑـﺎ ﺧﻄـﺎ ﻣﻮاﺟـﻪ‬ ‫ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬ ‫‪// Addresses - property that works with the items‬‬ ‫‪// collection as an array...‬‬ ‫‪public Address[] Addresses‬‬ ‫{‬ ‫‪get‬‬ ‫{‬ ‫…‬ ‫}‬ ‫‪set‬‬ ‫{‬ ‫‪// reset the arraylist...‬‬ ‫;)(‪Items.Clear‬‬ ‫?‪// did you get anything‬‬

‫‪٧٩٥‬‬

‫)‪if (value != null‬‬ ‫{‬ ‫‪// go through the array and populate items...‬‬ ‫)‪foreach (Address address in value‬‬ ‫{‬ ‫;)‪Items.Add(address‬‬ ‫}‬ ‫}‬ ‫}‬ ‫}‬

‫در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ ﻫﺮ ﻋﻀﻮ از اﻳﻦ آراﻳﻪ را ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ‪ Add‬ﺑﻪ ﺷﻴﺊ ‪ Items‬از ﻛﻼس ‪ ArrayList‬اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪.‬‬

‫ﺷﻜﻞ ‪5-19‬‬

‫اﺿﺎﻓﻪ ﻛﺮدن رﻛﻮرد ﻫﺎي ﺟﺪﻳﺪ‪:‬‬ ‫ﺧﻮب‪ ،‬در اﻳﻦ ﻗﺴﻤﺖ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان رﻛﻮرد ﻫﺎي ﺑﻴﺸﺘﺮي را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮد‪ .‬در ﻗﺴﻤﺖ اﻣﺘﺤـﺎن ﻛﻨﻴـﺪ‬ ‫ﺑﻌﺪ‪ ،‬ﭼﻬﺎر ﻛﻨﺘﺮل ‪ Button‬ﺟﺪﻳﺪ ﺑﻪ ﻓﺮم اﺿﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛﺮد‪ :‬دو ﻛﻨﺘﺮل ‪ Button‬ﺑﺮاي ﺣﺮﻛـﺖ در ﺑـﻴﻦ داده ﻫـﺎي ﻣﻮﺟـﻮد در‬ ‫ﺑﺮﻧﺎﻣﻪ و دو ﻛﻨﺘﺮل ‪ Button‬ﻧﻴﺰ ﺑﺮاي ﺣﺬف و ﻳﺎ اﺿﺎﻓﻪ ﻛﺮدن رﻛﻮرد ﻫﺎي ﺟﺪﻳﺪ‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﺿﺎﻓﻪ ﻛﺮدن رﻛﻮرد ﻫﺎي ﺟﺪﻳﺪ‬

‫‪٧٩٦‬‬

.‫ را ﻏﻴـﺮ ﻓﻌـﺎل ﻛﻨﻴـﺪ‬btnLoad ‫ و‬btnSave ‫ را ﺑﺎز ﻛﺮده و دو ﻛﻨﺘـﺮل‬Form1 ‫( ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ‬1 :‫ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬6-19 ‫ ﺟﺪﻳﺪ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ‬Button ‫ﺳﭙﺲ ﭼﻬﺎر ﻛﻨﺘﺮل‬

6-19 ‫ﺷﻜﻞ‬ ‫ و‬btnNew ،btnNext ،btnPrevious ‫ اﻳــﻦ ﭼﻬــﺎر ﻛﻨﺘــﺮل را ﺑــﻪ ﺗﺮﺗﻴــﺐ ﺑﺮاﺑــﺮ ﺑــﺎ‬Name ‫( ﺧﺎﺻــﻴﺖ‬2 ‫ و‬New ،Next ،Previous ‫ آﻧﻬﺎ را ﻧﻴﺰ ﺑـﻪ ﺗﺮﺗﻴـﺐ ﺑـﺎ ﻣﻘـﺎدﻳﺮ‬Text ‫ ﺧﺎﺻﻴﺖ‬.‫ ﻗﺮار دﻫﻴﺪ‬btnDelete ‫ ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ‬Delete .‫ آن ﺑﻪ ﺻـﻮرت اﺗﻮﻣﺎﺗﻴـﻚ اﻳﺠـﺎد ﺷـﻮد‬Click ‫ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد‬btnNew ‫( روي دﻛﻤﻪ ي‬3 ‫ را ﻧﻴـﺰ ﺑـﻪ ﻛـﻼس‬AddNewAddress ‫ ﻫﻤﭽﻨـﻴﻦ ﻣﺘـﺪ‬.‫ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬ :‫ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬Form1 private void btnNew_Click(object sender, EventArgs e) { AddNewAddress(); } public Address AddNewAddress() { // save the current address... UpdateCurrentAddress(); // create a new address... Address newAddress = Addresses.AddAddress(); // update the display... CurrentAddressIndex = Addresses.Items.Count; // return the new address...

٧٩٧

‫;‪return newAddress‬‬ ‫}‬

‫‪ (4‬ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ‪ .‬ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي دﻛﻤﻪ ي ‪ New‬ﻳﻚ رﻛﻮرد ﺟﺪﻳﺪ اﻳﺠﺎد ﺧﻮاﻫﺪ ﺷﺪ و ﻣﻲ ﺗﻮاﻧﻴﺪ داده ﻫﺎي ﺧـﻮد را‬ ‫در آن وارد ﻛﻨﻴﺪ‪ .‬در ﻛﺎدرﻫﺎي روي ﻓﺮم ﻳﻚ رﻛﻮرد ﺟﺪﻳﺪ را وارد ﻛﻨﻴﺪ و ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ را ﺑﺒﻨﺪﻳﺪ ﺗﺎ ﺗﻐﻴﻴﺮات ذﺧﻴﺮه ﺷﻮﻧﺪ‪.‬‬ ‫‪ (5‬ﺑﻪ ﻣﺤﻠﻲ ﻛﻪ ﻓﺎﻳﻞ ‪ AddressBook.xml‬در آﻧﺠﺎ ذﺧﻴﺮه ﺷﺪه ﺑﻮد ﺑﺮوﻳﺪ و ﻓﺎﻳـﻞ را ﺑـﺎز ﻛﻨﻴـﺪ ﺗـﺎ داده ﻫـﺎي آن‬ ‫ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ‪ .‬ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ رﻛﻮرد ﺟﺪﻳﺪ ﻧﻴﺰ در ﻓﺎﻳﻞ ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ‪.‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﺗﻜﻤﻴﻞ اﻳﻦ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ ﺑﺴﻴﺎر ﺳﺎده ﺑﻮد و ﻧﻜﺘﻪ ي ﺧﺎﺻﻲ ﻧﺪاﺷﺖ‪ .‬ﺗﻤﺎم ﻛﺎر ي ﻛﻪ ﺑﺎﻳﺪ اﻧﺠﺎم ﻣﻲ دادﻳﻢ اﻳﻦ ﺑﻮد ﻛﻪ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ‬ ‫‪ AddAddress‬از ﻛﻼس ‪ AddressBook‬ﻳﻚ ﺷﻴﺊ ﺟﺪﻳﺪ از ﻛﻼس ‪ Address‬اﻳﺠـﺎد ﻛـﺮده و ﺳـﭙﺲ ﺧﺎﺻـﻴﺖ‬ ‫‪ CurrentAddressIndex‬را ﺑﺮاﺑﺮ ﺑﺎ اﻧﺪﻳﺲ آن ﺷﻴﺊ ﻳﻌﻨﻲ اﻧﺪﻳﺲ آﺧﺮﻳﻦ ﻋﻨﺼﺮ ﻣﻮﺟﻮد در آراﻳﻪ ﻗـﺮار دﻫـﻴﻢ‪ .‬ﺑـﻪ اﻳـﻦ‬ ‫ﺗﺮﺗﻴﺐ ﻣﺘﻦ ﻧﻤﺎﻳﺶ داده ﺷﺪه در ﻛﻨﺘﺮل ‪ lblAddressNumber‬ﻧﻴﺰ ﺗﺼﺤﻴﺢ ﻣﻲ ﺷﻮد‪ ،‬ﺷﻤﺎره ي رﻛﻮرد را ﺑﻪ ﺻـﻮرت ‪2‬‬ ‫‪ of 2‬ﻧﻤﺎﻳﺶ داده و اﺟﺎزه ﻣﻲ دﻫﺪ ﻛﻪ داده ﻫﺎي آن را وارد ﻛﻨﻴﻢ‪.‬‬ ‫اﻟﺒﺘﻪ ﺑﻬﺘﺮ اﺳﺖ ﻗﺒﻞ از اﻳﺠﺎد رﻛﻮرد ﺟﺪﻳﺪ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ‪ UpdateCurrentAddress‬ﺗﻐﻴﻴﺮاﺗﻲ را ﻛـﻪ ﻛـﺎرﺑﺮ ﺗـﺎ اﻳـﻦ‬ ‫ﻟﺤﻈﻪ در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﺮده اﺳﺖ را ذﺧﻴﺮه ﻛﻨﻴﻢ‪ .‬ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ اﻳﻦ ﻣﺘﺪ‪ ،‬زﻣﺎﻧﻲ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺨﻮاﻫﺪ از ﺑﺮﻧﺎﻣﻪ ﺧـﺎرج ﺷـﻮد‪ ،‬ﺑـﻴﻦ رﻛـﻮرد ﻫـﺎ‬ ‫ﺣﺮﻛﺖ ﻛﻨﺪ و ﻳﺎ رﻛﻮرد ﺟﺪﻳﺪي را اﻳﺠﺎد ﻛﻨﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ ﻛﻪ ﺗﻤﺎم ﺗﻐﻴﻴﺮاﺗﻲ ﻛﻪ در داده ﻫﺎي درون ﻛﺎدر ﻫﺎ ﺑـﻪ وﺟـﻮد آورده‬ ‫اﺳﺖ در ﻓﺎﻳﻞ ‪ XML‬ذﺧﻴﺮه ﺧﻮاﻫﻨﺪ ﺷﺪ‪.‬‬ ‫)(‪public Address AddNewAddress‬‬ ‫{‬ ‫‪// save the current address...‬‬ ‫;)(‪UpdateCurrentAddress‬‬

‫ﺑﻌﺪ از اﻳﻨﻜﻪ ﺗﻐﻴﻴﺮات ذﺧﻴﺮه ﺷﺪ‪ ،‬ﻣﻲ ﺗﻮاﻧﻴﻢ ﻳﻚ رﻛﻮرد ﺟﺪﻳﺪ اﻳﺠﺎد ﻛﺮده و داده ﻫﺎي آن را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ دﻫﻴﻢ )ﻛﻪ اﻟﺒﺘـﻪ ﻫـﻴﭻ داده‬ ‫اي در آن وﺟﻮد ﻧﺪارد‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻤﺎم ﻛﺎدر ﻫﺎ در ﻓﺮم ﺧﺎﻟﻲ ﺧﻮاﻫﺪ ﺷﺪ( ﺗﺎ ﺗﻐﻴﻴﺮات ﻣﻮرد ﻧﻈﺮ ﺧﻮد را در آن اﻳﺠﺎد ﻛﻨﺪ‪:‬‬ ‫‪// create a new address...‬‬ ‫;)(‪Address newAddress = Addresses.AddAddress‬‬ ‫‪// update the display...‬‬ ‫;‪CurrentAddressIndex = Addresses.Items.Count‬‬ ‫‪// return the new address...‬‬ ‫;‪return newAddress‬‬ ‫}‬

‫ﺣﺮﻛﺖ در ﺑﻴﻦ داده ﻫﺎ‪:‬‬ ‫ﺣﺎل ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ داده ﻫﺎي ﺟﺪﻳﺪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪ ،‬ﻻزم اﺳﺖ ﻛﻪ دﻛﻤﻪ ﻫﺎي ‪ Next‬و ‪ Previous‬را ﻧﻴﺰ در ﻓﺮم ﻛﺎﻣـﻞ‬ ‫ﻛﻨﻴﺪ ﺗﺎ ﺑﺘﻮاﻧﻴﺪ ﺑﻴﻦ داده ﻫﺎي ﻣﻮﺟﻮد ﺣﺮﻛﺖ ﻛﺮده و آﻧﻬﺎ را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ‪ .‬در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ ﺧﻮاﻫﻴﻢ‬

‫‪٧٩٨‬‬

‫ اﻟﺒﺘﻪ در اﻳﻨﺠﺎ ﻧﻴﺰ ﻗﺒـﻞ‬.‫ ﺣﺮﻛﺖ ﻛﻨﻴﺪ‬Addresses ‫داد ﺗﺎ ﺑﺘﻮاﻧﻴﺪ ﺑﻴﻦ داده ﻫﺎي ﺑﻌﺪي و ﻳﺎ ﻗﺒﻠﻲ ﻣﻮﺟﻮد در اﻳﺴﺖ آدرﺳﻬﺎ در ﺷﻴﺊ‬ ‫از اﻳﻨﻜﻪ ﺑﻪ رﻛﻮرد ﺑﻌﺪي و ﻳﺎ رﻛﻮرد ﻗﺒﻠﻲ ﺑﺮوﻳﻢ ﺑﺎﻳﺪ داده ﻫﺎي رﻛﻮرد ﺟﺎري را ذﺧﻴﺮه ﻛﻨﻴﻢ ﺗﺎ اﮔﺮ ﻛﺎرﺑﺮ ﺗﻐﻴﻴﺮاﺗﻲ را در آن اﻳﺠـﺎد ﻛـﺮده‬ .‫ اﻳﻦ ﺗﻐﻴﻴﺮات از ﺑﻴﻦ ﻧﺮوﻧﺪ‬،‫ﺑﻮد‬

‫ ﺣﺮﻛﺖ در ﺑﻴﻦ داده ﻫﺎ‬:‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‬ ‫ آن ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ‬Click ‫ در ﻓﺮم ﺑﺮﻧﺎﻣﻪ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد‬btnNext ‫( روي دﻛﻤﻪ ي‬1 ‫ را ﻧﻴﺰ ﺑﻪ ﺻﻮرت زﻳﺮ در ﻛﻼس ﻣﺮﺑﻮط‬MoveNext ‫ ﻫﻤﭽﻨﻴﻦ ﻣﺘﺪ‬.‫ ﺳﭙﺲ ﻛﺪ زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬.‫اﻳﺠﺎد ﺷﻮد‬ :‫ اﻳﺠﺎد ﻛﻨﻴﺪ‬Form1 ‫ﺑﻪ‬ private void btnNext_Click(object sender, EventArgs e) { MoveNext(); } private void MoveNext() { // get the next index... int newIndex = CurrentAddressIndex + 1; if( newIndex > Addresses.Items.Count) newIndex = 1; // save any changes... UpdateCurrentAddress(); // move the record... CurrentAddressIndex = newIndex; }

.‫ دو ﺑـﺎر ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ‬btnPrevious ‫ ﺑﺮﮔﺸﺘﻪ و روي ﻛﻨﺘـﺮل‬Form1 ‫( ﻣﺠﺪداً ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ‬2 :‫ﺳﭙﺲ ﻛﺪ زﻳﺮ را در ﻣﺘﺪ اﻳﺠﺎد ﺷﺪه وارد ﻛﻨﻴﺪ‬ private void btnPrevious_Click(object sender, EventArgs e) { MovePrevious(); } private void MovePrevious() { // get the previous index... int newIndex = CurrentAddressIndex - 1; if( newIndex == 0) newIndex = Addresses.Items.Count; // save changes... UpdateCurrentAddress(); // move the record... CurrentAddressIndex = newIndex; }

٧٩٩

‫‪ (3‬ﺣﺎل ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و روي دﻛﻤﻪ ﻫﺎي ‪ Previous‬و ‪ Next‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ ﺑﺘﻮاﻧﻴﺪ ﺑـﻴﻦ داده‬ ‫ﻫﺎي ﻣﻮﺟﻮد در ﻓﺮم ﺣﺮﻛﺖ ﻛﻨﻴﺪ‪.‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﺗﻤﺎم ﻛﺎري ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﻧﺠﺎم دادﻳﻢ اﻳﻦ ﺑﻮد ﻛﻪ ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن و ﻳﺎ ﻛﻢ ﻛﺮدن ﻣﻘـﺪار ‪CurrentAddressIndex‬‬ ‫ﺑﻪ ﺟﻠﻮ و ﻳﺎ ﺑﻪ ﻋﻘﺐ ﺣﺮﻛﺖ ﻛﺮدﻳﻢ‪ .‬ﺑﺮاي ﺣﺮﻛﺖ ﻛﺮدن ﺑﻪ ﺟﻠﻮ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ ﻳﻚ واﺣﺪ اﻓﺰاﻳﺶ داده و ﺑﺮاي ﺣﺮﻛﺖ‬ ‫ﺑﻪ ﻋﻘﺐ ﻧﻴﺰ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﻣﻘﺪار اﻳﻦ ﺧﺎﺻﻴﺖ را ﻳﻚ واﺣﺪ ﻛﺎﻫﺶ دﻫﻴﻢ‪.‬‬ ‫اﻟﺒﺘﻪ ﺑﺎﻳﺪ دﻗﺖ داﺷﺘﻪ ﺑﺎﺷﻴﻢ ﻛﻪ ﻫﻨﮕﺎم ﻛﻢ ﻛﺮدن و ﻳﺎ اﺿﺎﻓﻪ ﻛﺮدن اﻧﺪﻳﺲ‪ ،‬از ﻣﺤﺪوده ﻫﺎ ﺗﺠﺎوز ﻧﻜﻨﻴﻢ )ﻳﻌﻨﻲ ﺳﻌﻲ ﻧﻜﻨﻴﻢ ﻛـﻪ از اوﻟـﻴﻦ‬ ‫رﻛﻮرد ﻧﻴﺰ ﻋﻘﺒﺘﺮ ﺑﺮوﻳﻢ و ﻳﺎ ﺑﻪ رﻛﻮرد ﺑﻌﺪ از آﺧﺮﻳﻦ رﻛﻮرد ﺑﺮوﻳﻢ(‪ .‬ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ اﺳﺖ ﻛﻪ ﺑﻌﺪ از ﺗﻨﻈﻴﻢ ﻛﺮدن ﻣﻘﺪار اﻧﺪﻳﺲ‪ ،‬ﺻﺤﺖ آن‬ ‫را در ﻳﻚ ﺷﺮط ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﻪ ﺟﻠﻮ ﺣﺮﻛﺖ ﻣﻲ ﻛﻨﻴﻢ‪ ،‬اﮔﺮ ﺑﻪ آﺧﺮ ﻟﻴﺴﺖ رﺳﻴﺪه ﺑﺎﺷﻴﻢ ﻣﺠﺪداً ﺑﻪ اﺑﺘﺪاي آن ﺑﺮ ﺧﻮاﻫﻴﻢ‬ ‫ﮔﺸﺖ و ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﻪ ﻋﻘﺐ ﺣﺮﻛﺖ ﻣﻲ ﻛﻨﻴﻢ اﮔﺮ ﺑﻪ اول ﻟﻴﺴﺖ ﺑﺮﺳﻴﻢ‪ ،‬ﺑﻪ اﻧﺘﻬﺎي آن ﻣﻨﺘﻘﻞ ﺧﻮاﻫﻴﻢ ﺷﺪ‪.‬‬ ‫در ﻫﺮ دو ﺣﺎﻟﺖ ﻧﻴﺰ ﻗﺒﻞ از اﻳﻨﻜﻪ اﻧﺪﻳﺲ را ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ‪ ،‬ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ‪ UpdateCurrentAddress‬ﺗﻐﻴﻴـﺮات اﻋﻤـﺎل‬ ‫ﺷﺪه را در ﻓﺎﻳﻞ ذﺧﻴﺮه ﻣﻲ ﻛﻨﻴﻢ‪:‬‬ ‫)(‪private void MoveNext‬‬ ‫{‬ ‫‪// get the next index...‬‬ ‫;‪int newIndex = CurrentAddressIndex + 1‬‬ ‫)‪if( newIndex > Addresses.Items.Count‬‬ ‫;‪newIndex = 1‬‬ ‫‪// save any changes...‬‬ ‫;)(‪UpdateCurrentAddress‬‬ ‫‪// move the record...‬‬ ‫;‪CurrentAddressIndex = newIndex‬‬ ‫}‬

‫ﺣﺬف ﻛﺮدن داده ﻫﺎ از ﺑﺮﻧﺎﻣﻪ‪:‬‬ ‫ﺑﺮاي ﺗﻜﻤﻴﻞ ﻛﺮدن اﻳﻦ ﺑﺮﻧﺎﻣﻪ‪ ،‬ﻓﻘﻂ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﻗﺎﺑﻠﻴﺖ ﺣﺬف داده ﻫﺎ را ﻧﻴﺰ ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﻢ‪ .‬اﻟﺒﺘﻪ ﻫﻨﮕﺎم ﺣﺬف ﻳﻚ رﻛـﻮرد ﺑﺎﻳـﺪ‬ ‫در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﻢ ﻛﻪ اﮔﺮ رﻛﻮردي ﻛﻪ ﺑﺎﻳﺪ ﺣﺬف ﺷﻮد آﺧﺮﻳﻦ رﻛﻮرد ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ ﺑﺎﺷﺪ‪ ،‬ﻳﻚ رﻛﻮرد ﺧﺎﻟﻲ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﻢ ﺗﺎ‬ ‫ﻟﻴﺴﺖ ﺧﺎﻟﻲ ﻧﻤﺎﻧﺪ‪ .‬در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ‪ ،‬ﻛﺪي را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛﺮد ﺗﺎ ﻋﻤﻞ ﺣﺬف را ﻧﻴﺰ ﺑﻪ درﺳﺘﻲ اﻧﺠﺎم دﻫﺪ‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬ﺣﺬف ﻳﻚ رﻛﻮرد از ﺑﺮﻧﺎﻣﻪ‬ ‫‪ (1‬ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ ‪ Form1‬ﺑﺮوﻳﺪ و روي دﻛﻤﻪ ي ‪ btnDelete‬دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ ﻛﺪ زﻳـﺮ‬ ‫را ﺑﻪ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ‪ Click‬آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ ﻣﺘﺪ ‪ DeleteAddress‬را ﻧﻴﺰ ﺑﻪ ﺻﻮرت زﻳﺮ ﺑـﻪ‬ ‫ﻛﻼس ﻣﺮﺑﻮط ﺑﻪ ‪ Form1‬اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪:‬‬

‫‪٨٠٠‬‬

private void btnDelete_Click(object sender, EventArgs e) { // ask the user if they are ok with this? if( MessageBox.Show( "Are you sure you want to delete this address?", "Address Book", MessageBoxButtons.YesNo,MessageBoxIcon.Question) == DialogResult.Yes ) { DeleteAddress(CurrentAddressIndex); } } // DeleteAddress - delete an address from the list... public void DeleteAddress(int index) { // delete the item from the list... Addresses.Items.RemoveAt(index - 1); // was that the last address? if (Addresses.Items.Count == 0) // add a new address? Addresses.AddAddress(); else // make sure you have something to show... if (index > Addresses.Items.Count) index = Addresses.Items.Count; // display the record... CurrentAddressIndex = index; }

.‫ رﻛﻮرد ﻫﺎي ﻣﻮرد ﻧﻈﺮ ﺧﻮد را از ﺑﺮﻧﺎﻣﻪ ﺣﺬف ﻛﻨﻴﺪ‬Delete ‫ ﺣﺎل ﺑﺎﻳﺪ ﺑﺘﻮاﻧﻴﺪ ﺑﺎ ﻓﺸﺎر دادن دﻛﻤﻪ ي‬.‫( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ‬2 ‫ ﻳﻚ رﻛﻮرد ﺧﺎﻟﻲ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﺷﺪه و ﺑﻪ ﻟﻴـﺴﺖ اﺿـﺎﻓﻪ‬،‫ اﮔﺮ ﺑﺨﻮاﻫﻴﺪ آﺧﺮﻳﻦ رﻛﻮرد ﻣﻮﺟﻮد را ﺣﺬف ﻛﻨﻴﺪ‬،‫اﻟﺒﺘﻪ‬ .‫ﺧﻮاﻫﺪ ﺷﺪ‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ ﺑـﻪ ﻫﻤـﻴﻦ‬.‫ ﺑﻪ ﮔﻮﻧﻪ اي ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ ﻛﻪ ﻫﻤﻮاره ﺑﺎﻳﺪ اﻃﻼﻋﺎﺗﻲ را ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤـﺎﻳﺶ دﻫـﺪ‬،‫ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در اﻳﻦ ﻓﺼﻞ اﻳﺠﺎد ﻛﺮدﻳﻢ‬ ،‫ اي در دﻳﺴﻚ وﺟﻮد ﻧـﺪارد‬AddressBook.xml ‫دﻟﻴﻞ اﺳﺖ زﻣﺎﻧﻲ ﻛﻪ ﺑﺮاي اوﻟﻴﻦ ﺑﺎر ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻣﻲ ﻛﻨﻴﺪ و ﻫﻴﭻ ﻓﺎﻳﻞ‬ ،‫ ﻫﻤﭽﻨﻴﻦ اﮔﺮ ﻛﺎرﺑﺮ ﺗﻤﺎم رﻛﻮرد ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣـﻪ را ﺣـﺬف ﻛﻨﻴـﺪ‬.‫ﻳﻚ رﻛﻮرد ﺧﺎﻟﻲ اﻳﺠﺎد ﻛﺮده و آن را در ﻓﺮم ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ‬ .‫ﺑﺎﻳﺪ ﺑﻪ ﻧﺤﻮي ﭼﻴﺰي را ﺑﺮاي ﻧﻤﺎﻳﺶ دادن در ﻓﺮم اﻳﺠﺎد ﻛﻨﻴﻢ‬ ‫ اﻳـﻦ ﻣﺘـﺪ‬.‫ اﺳـﺘﻔﺎده ﻣـﻲ ﻛﻨـﻴﻢ‬ArrayList ‫ در ﻛﻼس‬RemoveAt ‫ از ﻣﺘﺪ‬،‫ﺑﺮاي اﻳﻨﻜﻪ رﻛﻮردي را از دﻳﺴﻚ ﺣﺬف ﻛﻨﻴﻢ‬ .‫ ﺣﺬف ﻣﻲ ﻛﻨﺪ‬ArrayList ‫ﻋﻨﺼﺮي ﻛﻪ اﻧﺪﻳﺲ آن را ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ درﻳﺎﻓﺖ ﻛﺮده اﺳﺖ را از‬ // DeleteAddress - delete an address from the list... public void DeleteAddress(int index) { // delete the item from the list... Addresses.Items.RemoveAt(index - 1);

٨٠١

‫ﻫﻤﭽﻨﻴﻦ دﻗﺖ ﻛﻨﻴﺪ ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ‪ ArrayList‬ﺑﺮ ﻣﺒﻨﺎي اﻧﺪﻳﺲ ﺻﻔﺮ ﻛﺎر ﻣﻲ ﻛﻨﺪ‪ ،‬ﭘﺲ ﺑﺮاي ﻣﺜـﺎل ﻻزم اﺳـﺖ ﺑـﺮاي ﺣـﺬف‬ ‫ﻋﻨﺼﺮ ﺳﻮم از ﻟﻴﺴﺖ‪ ،‬ﭘﺎراﻣﺘﺮ ‪ 2‬را ﺑﻪ ﻣﺘﺪ ‪ RemoveAt‬ارﺳﺎل ﻛﻨﻴﻢ‪.‬‬ ‫ﻣﺸﻜﻞ زﻣﺎﻧﻲ اﻳﺠﺎد ﻣﻲ ﺷﻮد ﻛﻪ ﻋﻨﺼﺮي ﻛﻪ ﺣﺬف ﻛﺮده ﺑﺎﺷﻴﻢ آﺧﺮﻳﻦ ﻋﻨﺼﺮ ﻣﻮﺟﻮد در ﻟﻴﺴﺖ ﺑﻮده ﺑﺎﺷـﺪ و ﭼـﻮن ﺑﺎﻳـﺪ ﻫﻤـﻮاره ﻳـﻚ‬ ‫ﻋﻨﺼﺮ در ﻟﻴﺴﺖ ﺑﺎﺷﺪ ﺗﺎ ﺑﻪ ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ دﻫﻴﻢ‪ ،‬ﻳﻚ ﺷﻴﺊ ﺟﺪﻳﺪ از ﻛﻼس ‪ Address‬اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ‪:‬‬ ‫?‪// was that the last address‬‬ ‫)‪if (Addresses.Items.Count == 0‬‬ ‫?‪// add a new address‬‬ ‫;)(‪Addresses.AddAddress‬‬

‫ﻫﻤﭽﻨﻴﻦ اﮔﺮ رﻛﻮرد ﺣﺬف ﺷﺪه آﺧﺮﻳﻦ رﻛﻮرد ﻟﻴﺴﺖ ﻧﺒﺎﺷﺪ و رﻛﻮرد ﻫﺎي دﻳﮕﺮي ﻧﻴﺰ در ﻟﻴﺴﺖ وﺟﻮد داﺷﺘﻪ ﺑﺎﺷـﻨﺪ‪ ،‬ﺑﺎﻳـﺪ ﺑﻌـﺪ از ﺣـﺬف‬ ‫رﻛﻮرد اﻧﺪﻳﺲ رﻛﻮرد ﺟﺎري را ﺗﺼﺤﻴﺢ ﻛﻨﻴﻢ‪ .‬اﻟﺒﺘﻪ در ﻣﻮاردي اﻳﻦ اﻧﺪﻳﺲ ﺻﺤﻴﺢ اﺳﺖ و ﻧﻴﺎزي ﺑﻪ ﺗﻐﻴﻴﺮ آن وﺟﻮد ﻧﺪارد‪ .‬ﺑﺮاي ﻣﺜﺎل اﮔـﺮ‬ ‫ﭘـــﻨﺞ ﻋـــﻀﻮ در ﻟﻴـــﺴﺖ وﺟـــﻮد داﺷـــﺘﻪ ﺑﺎﺷـــﻨﺪ و ﻋـــﻀﻮ ﺳـــﻮم در ﺣـــﺎل ﻧﻤـــﺎﻳﺶ داده ﺷـــﺪن ﺑﺎﺷـــﺪ‪ ،‬ﻣﻘـــﺪار ﻓﻴﻠـــﺪ‬ ‫‪ _currentAddressIndex‬ﺑﺮاﺑﺮ ﺑﺎ ‪ 3‬ﺧﻮاﻫﺪ ﺑﻮد‪ .‬ﺣﺎل اﮔﺮ ﻛﺎرﺑﺮ ﺑﺎ ﻓﺸﺎر دادن دﻛﻤﻪ ي ‪ Delete‬اﻳـﻦ رﻛـﻮرد را‬ ‫ﺣﺬف ﻛﻨﺪ‪ ،‬ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ‪ _currentAddressIndex‬را ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ‪ .‬زﻳﺮا ﻫﻤﭽﻨﺎن ﻋﻀﻮي ﺑـﺎ اﻧـﺪﻳﺲ ‪ 3‬در ﻓـﺮم‬ ‫وﺟــﻮد دارد ﺗــﺎ داده ﻫــﺎي آن ﻧﻤــﺎﻳﺶ داده ﺷـﻮد و اﻣــﺎ اﮔــﺮ ﺑــﺮاي ﻣﺜــﺎل ﻓﻘــﻂ ﺳــﻪ ﻋــﻀﻮ در ﻟﻴــﺴﺖ وﺟــﻮد داﺷــﺘﻪ ﺑﺎﺷــﺪ و ﻣﻘــﺪار‬ ‫‪ _currentAddressIndex‬ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎ ‪ 3‬ﺑﺎﺷﺪ‪ ،‬ﺣﺬف اﻳﻦ ﻋﻨﺼﺮ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ اﻧﺪﻳﺲ رﻛـﻮرد ﺟـﺎري ﻧـﺎ ﻣﻌﺘﺒـﺮ‬ ‫ﺷﻮد و ﻣﺠﺒﻮر ﺷﻮﻳﻢ ﻛﻪ آن را ﺗﺼﺤﻴﺢ ﻛﻨﻴﻢ‪ .‬اﻳﻦ ﺣﺎﻟﺖ زﻣﺎﻧﻲ رخ ﻣﻲ دﻫﺪ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺨﻮاﻫـﺪ آﺧـﺮﻳﻦ ﻋـﻀﻮ از ﻟﻴـﺴﺖ را ﺣـﺬف ﻛﻨـﺪ‪.‬‬ ‫ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﺷﺮط ‪ if‬اﻳﻦ ﻣﻮرد را ﻧﻴﺰ ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد‪:‬‬ ‫‪else‬‬ ‫‪// make sure you have something to show...‬‬ ‫)‪if (index > Addresses.Items.Count‬‬ ‫;‪index = Addresses.Items.Count‬‬

‫ﺣﺎل ﻛﻪ ﺑﻌﺪ از ﺑﺮرﺳﻲ ﺷﺮاﻳﻂ ﻣﺨﺘﻠﻒ اﻧﺪﻳﺲ ﻋﻀﻮي ﻛﻪ ﺑﺎﻳـﺪ داده ﻫـﺎي آن در ﻓـﺮم ﻧﻤـﺎﻳﺶ داده ﺷـﻮد را ﺑﺪﺳـﺖ آوردﻳـﻢ‪ ،‬آن را در‬ ‫ﺧﺎﺻﻴﺖ ‪ CurrentAddressIndex‬ﻗﺮار ﻣﻲ دﻫﻴﻢ‪:‬‬ ‫‪// display the record...‬‬ ‫;‪CurrentAddressIndex = index‬‬ ‫}‬

‫ﺑﺮرﺳﻲ ﻟﺒﻪ ﻫﺎ‪:‬‬ ‫در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻳﻜﻲ از ﺗﻜﻨﻴﻜﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ را ﻫﻨﮕﺎم ﺗﺴﺖ ﻋﻤﻠﻜﺮد ﻳﻚ ﻧﺮم اﻓﺰار ﺑﺮرﺳﻲ ﻛﻨﻴﻢ‪ .‬ﻫﻨﮕﺎم ﻧﻮﺷﺘﻦ ﻳﻚ ﻧﺮم‬ ‫اﻓﺰار‪ ،‬ﻣﻌﻤﻮﻻ ﻛﺎرﻫﺎي ﻣﻮرد ﻧﻈﺮ ﻣﺎ در ﻣﺮزﻫﺎ ﺑﻪ درﺳﺘﻲ اﻧﺠﺎم ﻧﺨﻮاﻫﻨﺪ ﺷﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد ﻣﺘـﺪي دارﻳـﺪ ﻛـﻪ‬ ‫ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ را ﺑﻪ ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ‪ ،‬اﻣﺎ ﺑﺮاي اﻳﻨﻜﻪ اﻳﻦ ﻣﺘﺪ ﺑﻪ درﺳﺘﻲ ﻋﻤﻞ ﻛﻨﺪ اﻳﻦ ﻋﺪد ﺑﺎﻳﺪ ﺑـﻴﻦ اﻋـﺪاد ‪ 0‬ﺗـﺎ ‪99‬‬ ‫ﺑﺎﺷﺪ‪.‬‬ ‫در اﻳﻦ ﻣﻮارد ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻟﮕﻮرﻳﺘﻢ ﻣﺘﺪ ﺧﻮد را ﻧﻮﺷﺘﻴﺪ و آن را ﺑﺮاي ﺑﻌﻀﻲ از اﻋﺪاد در ﺑﺎزه ي ﻣﺸﺨﺺ ﺷﺪه ﺗﺴﺖ ﻛﺮدﻳـﺪ‪ ،‬ﺑﻬﺘـﺮ اﺳـﺖ‬ ‫آن را ﺑﺮاي اﻋﺪاد ﻣﻮﺟﻮد در ﻣﺮز ﺑﺎزه ﻧﻴﺰ ﺗﺴﺖ ﻛﻨﻴﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل اﻋﺪادي ﻣﺎﻧﻨﺪ ‪ 99 ،-1 ،0‬و ﻳﺎ ‪ 100‬را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﺑﺪﻫﻴﺪ و ﻣـﺸﺎﻫﺪه ﻛﻨﻴـﺪ‬

‫‪٨٠٢‬‬

‫ﻛﻪ آﻳﺎ اﻟﮕﻮرﻳﺘﻢ ﺷﻤﺎ ﺑﺮاي اﻳﻦ اﻋﺪاد ﻧﻴﺰ درﺳﺖ ﻛﺎر ﻣﻲ ﻛﻨﺪ ﻳﺎ ﻧﻪ؟ ﻣﻌﻤﻮﻻ اﮔﺮ ﻣﺘﺪ ﺑﺮاي ﻳﻜﻲ ﻳﺎ دو ﺗﺎ از اﻳﻦ اﻋﺪاد ﺑﻪ درﺳﺘﻲ ﺟﻮاب داد‪،‬‬ ‫ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ ﻛﻪ اﻳﻦ اﻟﮕﻮرﻳﺘﻢ ﺑﺮاي ﺗﻤﺎم اﻋﺪاد ﻣﻮﺟﻮد در آن ﺑﺎزه ﺑﻪ درﺳﺘﻲ ﻛﺎر ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫اﻳﻦ ﻣﺸﻜﻞ در ﻣﺘﺪﻫﺎي ‪ MoveNext‬و ﻳﺎ ‪ MovePrevious‬ﻛﻪ در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﻢ ﻧﻴﺰ ﻣﻤﻜﻦ اﺳـﺖ ﺑـﻪ وﺟـﻮد‬ ‫آﻳﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد ‪ 100‬رﻛﻮرد اﻃﻼﻋﺎت دارﻳﺪ و ﺑﻌﺪ از اﻳﺠﺎد اﻳـﻦ دو ﻣﺘـﺪ‪ ،‬آن را ﺑـﺮاي ﺣﺮﻛـﺖ در ﺑـﻴﻦ‬ ‫رﻛﻮرد ﻫﺎي ‪ 10‬ﺗﺎ ‪ 20‬ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﺪ و ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ درﺳﺖ ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ‪ .‬ﺑﻪ اﻳﻦ ﺻﻮرت ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﻄﻤﺌﻦ ﺷﻮﻳﺪ ﻛﻪ ﺑﺮﻧﺎﻣـﻪ‬ ‫ﺑﺮاي ﺣﺮﻛﺖ ﺑﻴﻦ رﻛﻮرد ﻫﺎي ‪ 2‬ﺗﺎ ‪ 99‬ﺑﻪ درﺳﺘﻲ ﻋﻤﻞ ﻣﻲ ﻛﻨﺪ‪ ،‬اﻣﺎ اﮔﺮ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﺘﺪ ﺑﻪ رﻛﻮرد ‪ 100‬رﺳﻴﺪ و ﻛﺎرﺑﺮ ﻣﺠﺪداً ﺧﻮاﺳﺖ ﺑﻪ‬ ‫رﻛﻮرد ﺑﻌﺪي ﺑﺮود اﺣﺘﻤﺎﻻ ﺑﺎ ﻣﺸﻜﻞ ﻣﻮاﺟﻪ ﺧﻮاﻫﻴﺪ ﺷﺪ‪.‬‬

‫اﻳﺠﺎد ﻳﻜﭙﺎرﭼﮕﻲ ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ي دﻓﺘﺮ ﺗﻠﻔﻦ و دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ‪:‬‬ ‫ﺗﺎ اﻳﻨﺠﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ اﻳﺠﺎد ﻛﺮدﻳﻢ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺴﺘﻨﺪ داده ﻫﺎي ﺧﻮد را در ﻓﺎﻳﻞ ‪ XML‬ذﺧﻴﺮه ﻛﺮده و ﻳﺎ از آن اﺳﺘﺨﺮاج ﻛﻨﻨﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ در‬ ‫ﻃﻮل اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎ‪ ،‬ﺗﻐﻴﻴﺮاﺗﻲ ﻛﻪ در ﻓﺎﻳﻞ ‪ XML‬ﺣﺎﺻﻞ اﻳﺠﺎد ﻣﻲ ﺷﺪ را ﻧﻴﺰ ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ ﺗـﺎﻛﻨﻮن ﺑﺎﻳـﺪ درك ﺧـﻮﺑﻲ از‬ ‫ﻣﻔﻬﻮم ‪ XML‬ﺑﺪﺳﺖ آورده ﺑﺎﺷﻴﺪ و ﺑﺪاﻧﻴﺪ ﻛﻪ ‪ XML‬ﭼﮕﻮﻧﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد‪.‬‬ ‫در اﺑﺘﺪاي ﻓﺼﻞ ﮔﻔﺘﻴﻢ ﻛﻪ ‪ XML‬وﺳﻴﻠﻪ اي اﺳﺖ ﻛﻪ ﺑﺮاي اﻳﺠﺎد ﻳﻜﭙﺎرﭼﮕﻲ در ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺠﺎري ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣـﻲ ﮔﻴـﺮد‪،‬‬ ‫اﻣﺎ ﺑﺮاي اﻓﺮادي ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺗﺎزه ﻛﺎر ﻫﺴﺘﻨﺪ ﺗﻮﻗﻊ ﻧﺎ ﺑﻪ ﺟﺎﻳﻲ اﺳﺖ ﻛﻪ اﻧﺘﻈﺎر داﺷﺘﻪ ﺑﺎﺷﻴﻢ ‪ XML‬را ﺑﻪ اﻳﻦ ﻣﻔﻬﻮم درك ﻛـﺮده‬ ‫و ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار دﻫﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ‪ XML‬ﺑﺮاي اﻳﻦ اﻓﺮاد ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﻋﻨﻮان وﺳﻴﻠﻪ اي ﺑﺮاي ذﺧﻴـﺮه ي داده ﻫـﺎي ﺑﺮﻧﺎﻣـﻪ ﻣـﻮرد‬ ‫اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد‪ .‬در اداﻣﻪ ي اﻳﻦ ﻓﺼﻞ ﺳﻌﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد دﻟﻴﻞ اﻳﻨﻜﻪ ‪ XML‬ﻣﻲ ﺗﻮاﻧﺪ ﻳﻚ اﺑﺰار ﺧﻮب ﺑﺮاي ﻳﻜﭙﺎرﭼﮕﻲ ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ‬ ‫ﺑﺎﺷﺪ را ﺗﻮﺿﻴﺢ دﻫﻴﻢ‪ .‬ﺑﻪ اﻳﻦ ﻣﻨﻈﻮر ﺑﺮﻧﺎﻣﻪ اي اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﺑﺘﻮاﻧﺪ ﺳﺎﺧﺘﺎر ﻓﺎﻳﻞ ‪ XML‬ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻠﻲ را درك ﻛﺮده‬ ‫و ﺑﻪ ﺳﺎدﮔﻲ از داده ﻫﺎي درون آن اﺳﺘﻔﺎده ﻛﻨﺪ‪.‬‬ ‫ﻛﺎرﺑﺮدﻫﺎي ‪ XML‬و ﻧﺤﻮه ي اﺳﺘﻔﺎده از آن ﻳﻜﻲ از ﻣﺒﺎﺣﺚ ﭘﻴﺸﺮﻓﺘﻪ اﺳﺖ‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي ﻳﺎدﮔﻴﺮي ﺑﻴﺸﺘﺮ در اﻳﻦ ﻣـﻮرد ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﻪ‬ ‫ﻛﺘﺎﺑﻬﺎﻳﻲ ﻛﻪ در اﻳﻦ زﻣﻴﻨﻪ ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ رﺟﻮع ﻛﻨﻴﺪ‪.‬‬

‫ﺗﻮﺿﻴﺢ اﺻﻮل ﻳﻜﭙﺎرﭼﻪ ﺳﺎزي‪:‬‬ ‫ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﺑﺮﻧﺎﻣﻪ اي اﻳﺠﺎد ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﺪ ﺑﺎ ﺑﺮﻧﺎﻣﻪ ي دﻓﺘﺮ ﺗﻠﻔﻦ ﺗﻌﺎﻣﻞ داﺷﺘﻪ ﺑﺎﺷﺪ‪ ،‬ﺑﻬﺘﺮ اﺳﺖ ﺑﺎ اﺻـﻮل ﻳﻜﭙﺎرﭼـﻪ ﺳـﺎزي در‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎ آﺷﻨﺎ ﺷﻮﻳﻢ‪ .‬اﺳﺎﺳﺎ زﺑﺎن ‪ XML‬ﺑﻬﺘﺮﻳﻦ روش ﺑﺮاي اﻳﺠﺎد ﻳﻜﭙﺎرﭼﮕﻲ ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﺳﺖ‪ ،‬زﻳﺮا ﻛﺪ ﻫـﺎي آن ﺑـﻪ ﺳـﺎدﮔﻲ ﻣـﻲ‬ ‫ﺗﻮاﻧﻨﺪ ﺗﻮﺳﻂ اﻓﺮاد و ﻳﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕﺮ ﺧﻮاﻧﺪه ﺷﺪه‪ ،‬درك ﺷﻮﻧﺪ و ﻳﺎ ﺗﻐﻴﻴﺮ داده ﺷﻮﻧﺪ‪ .‬روﺷﻬﺎي ﻗﺪﻳﻤﻲ ﻛـﻪ ﺑـﺮاي اﻳـﻦ ﻣﻨﻈـﻮر ﻣـﻮرد‬ ‫اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﺮﻓﺖ ﻋﻤﺪﺗﺎ ﻧﻴﺎز داﺷﺘﻨﺪ ﻛﻪ ﻣﺘﻨﻲ ﻧﻴﺰ ﻫﻤﺮاه ﺑﺎ آﻧﻬﺎ ﻓﺮﺳـﺘﺎده ﺷـﻮد ﺗـﺎ ﺳـﺎﺧﺘﺎر داده ﻫـﺎي درون آن را ﺗﻮﺿـﻴﺢ دﻫـﺪ‪.‬‬ ‫ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺳﺎﺧﺘﺎر ﻓﺎﻳﻞ ﺣﺎوي داده ﻫﺎ ﺗﻐﻴﻴﺮ ﻣﻲ ﻛﺮد‪ ،‬ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺒﻠﻲ دﻳﮕﺮ ﻧﻤﻲ ﺗﻮاﻧﺴﺘﺪ از ﻓﺎﻳﻠﻬﺎي ﺟﺪﻳﺪ اﺳﺘﻔﺎده ﻛﻨﻨﺪ‪.‬‬ ‫ﻓﺎﻳﻠﻬﺎي ‪ XML‬ﺑﻪ ﺳﺎدﮔﻲ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺗﻮﺳﻂ اﻓﺮاد درك ﺷﻮﻧﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﺗﺎﻛﻨﻮن ﺣﺘﻲ در راﺑﻄﻪ ﺑﺎ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ در اﻳـﻦ‬ ‫ﻓﺼﻞ اﻳﺠﺎد ﻛﺮده ﺑﺎﺷﻴﻢ ﻧﻴﺰ ﭼﻴﺰي ﻧﺸﻨﻴﺪه ﺑﺎﺷﻴﺪ و ﻓﺎﻳﻞ ‪ XML‬زﻳﺮ را ﺑﻪ ﺷﻤﺎ ﻧﺸﺎن دﻫﻨﺪ‪:‬‬ ‫>‪Muhammad‪Hashemian‪MyCompany‪11 First Avenue
‫‪٨٠٣‬‬

‫>‪No Where‪North‪28222‪Iran‪<Email>[email protected]

‫ﺑﻪ راﺣﺘﻲ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﺘﻮﺟﻪ ﺷﺪ ﻛﻪ اﻳﻦ ﻓﺎﻳﻞ ﺣﺎوي ﭼﻪ داده ﻫﺎﻳﻲ اﺳﺖ‪ .‬ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺗﻮاﻧﻴﺪ از اﺑﺰارﻫﺎي زﻳﺎدي ﻛﻪ در ‪ .NET‬وﺟـﻮد‬ ‫دارد ﺑﺮاي ﻣﺸﺎﻫﺪه‪ ،‬ﺗﻐﻴﻴﺮ و ﻳﺎ ﻛﺎر ﺑﺎ اﻳﻦ ﻓﺎﻳﻞ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ .‬اﻟﺒﺘﻪ ﺑﺎ اﻳﻦ ﺣﺎل ﻧﻴﺰ ﻣﻤﻜﻦ اﺳﺖ در ﺑﻌﻀﻲ ﺷﺮاﻳﻂ ﻣﺠﺒﻮر ﺷﻮﻳﺪ ﻛﻪ ﺳـﺎﺧﺘﺎر‬ ‫ﻓﺎﻳﻞ را از ﻓﺮدي ﻛﻪ آن را ﻃﺮاﺣﻲ ﻛﺮده اﺳﺖ درﺧﻮاﺳﺖ ﻛﻨﻴﺪ‪ ،‬ﻣﺨﺼﻮﺻﺎ در ﻣﻮاردي ﻛﻪ داده ﻫﺎي ﻣﻬﻤﺘﺮي در ﻓﺎﻳـﻞ ‪ XML‬ﻗـﺮار ﻣـﻲ‬ ‫ﮔﻴﺮﻧﺪ‪ ،‬اﻣﺎ ﺑﺎ اﻳﻦ وﺟﻮد اﺳﺘﻔﺎده از ﻓﺎﻳﻠﻬﺎي ‪ XML‬ﺑﺴﻴﺎر ﺑﺎ ﻣﻌﻨﻲ ﺗﺮ از ﺳﻴﺴﺘﻢ ﻫﺎي ﻗﺪﻳﻤﻲ اﺳﺖ‪.‬‬ ‫ﺑﻌﺪ از اﻳﻦ ﻛﻪ ﺳﺎﺧﺘﺎر ﻳﻚ ﻓﺎﻳﻞ ‪ XML‬را ﻣﺘﻮﺟﻪ ﺷﺪﻳﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ داده ﻫﺎي ﻣﻮرد ﻧﻈﺮ ﺧﻮد را ﺑﻪ ﻓﺎﻳﻞ اﺿﺎﻓﻪ ﻛﻨﻴﺪ و ﻳـﺎ ﺣﺘـﻲ ﻓﺎﻳﻠﻬـﺎي‬ ‫ﺧﻮدﺗﺎن را ﺑﺮ اﺳﺎس آن ﺳﺎﺧﺘﺎر اﻳﺠﺎد ﻛﻨﻴﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل در ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻠﻲ ﺑﻌﺪ از اﻳﻨﻜﻪ ﻣﺘﻮﺟﻪ ﺷﺪﻳﺪ ﻋﻨـﺼﺮ ‪ Addresses‬ﺣـﺎوي‬ ‫ﭼﻨﺪﻳﻦ ﻋﻨﺼﺮ از ﻧﻮع ‪ Address‬اﺳﺖ ﻛﻪ ﻫﺮ ﻳﻚ داده ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﻓﺮد را در دﻓﺘﺮ ﺗﻠﻔﻦ ﻧﮕﻬﺪاري ﻣـﻲ ﻛﻨﻨـﺪ‪ ،‬ﻣـﻲ ﺗﻮاﻧﻴـﺪ‬ ‫داده ﻫﺎي اﻓﺮاد ﺟﺪﻳﺪ را ﺧﻮد ﺑﻪ ﻓﺎﻳﻞ اﺿﺎﻓﻪ ﻛﻨﻴﺪ و ﻳﺎ ﺑﺮﻧﺎﻣﻪ اي ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ ﺑﺘﻮاﻧﺪ ﺑﺮ اﺳﺎس ﺳﺎﺧﺘﺎر اﻳﻦ ﻓﺎﻳﻞ ﻛﺎر ﻛﻨﺪ و داده ﻫـﺎ را ﺑـﻪ‬ ‫وﺳﻴﻠﻪ ي آن ﺑﺮﻧﺎﻣﻪ ﻛﻨﺘﺮل ﻛﻨﻴﺪ‪.‬‬ ‫ﺑﺮاي ﻣﺜﺎل ﻓﺎﻳﻞ ﻗﺒﻞ را ﺑﺎز ﻛﻨﻴﺪ و ﻋﻨﺼﺮ ‪ Address‬را ﺑﻪ ﻫﻤﺮاه ﺗﻤﺎم ﻋﻨﺎﺻﺮ زﻳﺮ ﻣﺠﻤﻮﻋﻪ ي آن ﻛﭙﻲ ﻛﺮده و ﻳﻚ ﻧﺴﺨﻪ از آن را‬ ‫ﺑﻼﻓﺎﺻﻠﻪ ﺑﻌﺪ از اﺗﻤﺎم ﺗﮓ >‪ ‪Muhammad‪Hashemian‪MyCompany‪11 First Avenue‪No Where‪North‪28222‪Iran‪<Email>[email protected]Somebody‪Else‪12 First Avenue‪Big City‪SE‪28582‪Iran‪<Email>[email protected]
‫‪٨٠٤‬‬

‫ﺣﺎل اﮔﺮ ﺑﺮﻧﺎﻣﻪ را ﺑﺎز ﻛﻨﻴﺪ‪ ،‬ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ دو رﻛﻮرد اﻃﻼﻋﺎت در ﺑﺮﻧﺎﻣﻪ وﺟﻮد دارﻧﺪ‪ :‬ﻳﻚ رﻛﻮرد ﻛﻪ از اﺑﺘـﺪا در ﺑﺮﻧﺎﻣـﻪ اﻳﺠـﺎد‬ ‫ﺷﺪه ﺑﻮد و رﻛﻮرد دﻳﮕﺮ ﻧﻴﺰ داده ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ﺻﻮرت دﺳﺘﻲ در ﻓﺎﻟﻲ وارد ﻛﺮدﻳﻢ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﺑﺎ درك ﺳﺎﺧﺘﺎر ﻳـﻚ ﻓﺎﻳـﻞ‬ ‫‪ XML‬ﻛﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﻮﻟﻴﺪ ﻣﻲ ﻛﻨﺪ‪ ،‬ﻣﻲ ﺗﻮان ﺑﻪ ﺳﺎدﮔﻲ ﺗﻐﻴﻴﺮات ﻣﻮرد ﻧﻈﺮ را در آن اﻳﺠﺎد ﻛﺮد‪.‬‬

‫ﺧﻮاﻧﺪن اﻃﻼﻋﺎت ﺑﺮﻧﺎﻣﻪ ي دﻓﺘﺮ ﺗﻠﻔﻦ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي دﻳﮕﺮ‪:‬‬ ‫ﺑــﺮاي ﺗﻜﻤﻴــﻞ ﺗﻮﺿــﻴﺤﺎت اﻳــﻦ ﻓــﺼﻞ‪ ،‬در ﺑﺨــﺶ اﻣﺘﺤــﺎن ﻛﻨﻴــﺪ ﺑﻌــﺪ ﺑﺮﻧﺎﻣــﻪ اي اﻳﺠــﺎد ﺧــﻮاﻫﻴﻢ ﻛــﺮد ﻛــﻪ ﻛــﺎﻣﻼً از ﭘــﺮوژه ي‬ ‫‪ AddressBook‬ﺟﺪا ﺑﺎﺷﺪ اﻣﺎ ﺑﺘﻮاﻧﺪ از داده ﻫﺎي درون ﻓﺎﻳﻞ ‪ AddressBook.xml‬اﺳﺘﻔﺎده ﻛﻨﺪ‪ .‬اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻟﻴـﺴﺖ‬ ‫اﻓﺮادي ﻛﻪ در اﻳﻦ ﻓﺎﻳﻞ ﻫﺴﺘﻨﺪ را اﺳﺘﺨﺮاج ﻛﺮده و ﺑﻪ ﻫﻤﺮاه آدرس اﻳﻤﻴﻞ آﻧﻬﺎ در ﻓﺮم ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬ﺧﻮاﻧﺪن داده ﻫﺎي ﺑﺮﻧﺎﻣﻪ ي ‪AddressBook‬‬ ‫‪ (1‬ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وﻳﻨﺪوز ﺑﻪ ﻧﺎم ‪ Address List‬اﻳﺠﺎد ﻛﻨﻴﺪ‪.‬‬ ‫‪ (2‬ﺑﺎ اﺳﺘﻔﺎده ز ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل ‪ ListBox‬در ﻓﺮم ﻗﺮار دﻫﻴﺪ‪ .‬ﺧﺎﺻﻴﺖ ‪ IntegralHeight‬اﻳـﻦ ﻛﻨﺘـﺮل‬ ‫را ﺑﺮاﺑﺮ ﺑﺎ ‪ ،False‬ﺧﺎﺻﻴﺖ ‪ Dock‬آن را ﺑﺮاﺑﺮ ﺑﺎ ‪ Fill‬و ﺧﺎﺻﻴﺖ ‪ Name‬را ﺑﺮاﺑﺮ ﺑﺎ ‪ lstMails‬ﻗﺮار دﻫﻴﺪ‬ ‫)ﺷﻜﻞ ‪.(7-19‬‬

‫ﺷﻜﻞ ‪7-19‬‬ ‫‪ (3‬در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ ‪ Form1‬روي ﻧﻮار ﻋﻨﻮان ﻓﺮم دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ‪ Load‬ﻓـﺮم‬ ‫ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠـﺎد ﺷـﻮد‪ .‬ﺳـﭙﺲ ﻛـﺪ ﻣـﺸﺨﺺ ﺷـﺪه در زﻳـﺮ را در اﻳـﻦ ﻣﺘـﺪ وارد ﻛﻨﻴـﺪ‪ .‬ﻫﻤﭽﻨـﻴﻦ ﻓـﻀﺎي ﻧـﺎم‬ ‫‪ System.Xml‬را ﻧﻴﺰ ﺑﻪ اﺑﺘﺪاي ﻛﻼس ‪ Form1‬اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ در ﺑﺮﻧﺎﻣﻪ از ﻛﻼﺳﻬﺎي آن اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪:‬‬

‫‪٨٠٥‬‬

using System.Xml; using System.Collections; private void Form1_Load(object sender, EventArgs e) { // where do we want to get the XML from... String filename = @"E:\Documents and Settings\Mohammad\My " + "Documents\Visual Studio 2005\Projects\" + "Address Book\Address Book\bin\" + "Debug\AddressBook.xml"; // open the document... XmlTextReader reader = new XmlTextReader(filename); // move to the start of the document... reader.MoveToContent(); // start working through the document... Hashtable addressData = null; String elementName = null; while(reader.Read()) { // what kind of node to we have? switch(reader.NodeType) { // is it the start of an element? case XmlNodeType.Element: // if it’s an element start, is it “Address”? if (reader.Name == "Address" ) // if so, create a new collection... addressData = new Hashtable(); else // if not, record the name of the element... elementName = reader.Name; break; // if we have some text, try storing it in the // collection... case XmlNodeType.Text: // do we have an address? if (addressData != null) addressData.Add(elementName, reader.Value); break; // is it the end of an element? case XmlNodeType.EndElement: // if it is, // we should have an entire address stored... if( reader.Name == "Address") { // try to create a new listview item... String item = null; try { item = addressData["FirstName"] + " " + addressData["LastName"] + " (" +

٨٠٦

‫;")" ‪addressData["Email"] +‬‬ ‫}‬ ‫‪catch‬‬ ‫{‬ ‫}‬ ‫‪// add the item to the list...‬‬ ‫;)‪lstEmails.Items.Add(item‬‬ ‫‪// reset...‬‬ ‫;‪addressData = null‬‬ ‫}‬ ‫;‪break‬‬ ‫}‬ ‫}‬ ‫}‬

‫ﻧﻜﺘﻪ‪ :‬ﻗﺒﻞ از اﺟﺮا اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﺴﻴﺮي ﻛﻪ ﺑﺮاي ﻓﺎﻳﻞ ‪ AddressBook.xml‬در اﺑﺘﺪاي ﻣﺘﺪ ‪ Form1_Load‬وارد ﺷﺪه‬ ‫اﺳﺖ را ﺑﺎ ﻣﺴﻴﺮ ﺻﺤﻴﺢ آن ﺟﺎﻳﮕﺰﻳﻦ ﻛﻨﻴﺪ‪.‬‬ ‫‪ (4‬ﺑﺎ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﻓﺮﻣﻲ ﻣﺸﺎﺑﻪ ﻓﺮم ‪ 8-19‬ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ اﮔﺮ رﻛﻮردي داراي آدرس اﻳﻤﻴﻞ ﻧﺒﺎﺷﻨﺪ ﻧﻴﺰ ﺑﺮﻧﺎﻣـﻪ ﺑـﻪ‬ ‫درﺳﺘﻲ آن را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ زﻳﺮا در اﻳﻦ ﺻﻮرت ﻳﻚ رﺷﺘﻪ ي ﺗﻬﻲ در ﻓﺎﻳﻞ ‪ XML‬ذﺧﻴﺮه ﻣﻲ ﺷﻮد و ﻫﻨﮕﺎم ﺧﻮاﻧـﺪن داده‬ ‫ﻫﺎ ﻧﻴﺰ ﻳﻚ رﺷﺘﻪ ي ﺗﻬﻲ ﺑﻪ وﺳﻴﻠﻪ ي ‪ ListView‬ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد‪.‬‬

‫ﺷﻜﻞ ‪8-19‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﻗﺒﻞ از اﻳﻨﻜﻪ درﺑﺎره ي ﻣﺰاﻳﺎي اﻳﻦ ﺑﺮﻧﺎﻣﻪ )و ﻳﺎ ﻣﺰاﻳﺎي ‪ (XML‬ﺻﺤﺒﺖ ﻛﻨﻴﻢ‪ ،‬ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﻗﺒﻞ از ﻧﻮﺷـﺘﻦ اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ اﺻـﻼ ﻓﺎﻳـﻞ‬ ‫‪ XML‬اي ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﭘﺮوژه ي ‪ AddressBook‬اﻳﺠﺎد ﻣﻲ ﺷﺪ را ﻧﺪﻳﺪه ﺑﻮدﻳﺪ و ﺑﺎ ﺳﺎﺧﺘﺎر آن آﺷﻨﺎﻳﻲ ﻧﺪاﺷﺘﻴﺪ‪ ،‬ﻓﻘـﻂ ﻣـﻲ‬

‫‪٨٠٧‬‬

‫ﺧﻮاﺳﺘﻴﺪ ﺑﺮ اﺳﺎس اﻃﻼﻋﺎت داﺧﻞ اﻳﻦ ﻓﺎﻳﻞ ﺑﺮﻧﺎﻣﻪ اي ﺑﻨﻮﻳﺴﻴﺪ ﻛﻪ ﻧﺎم و آدرس اﻳﻤﻴﻞ اﻓﺮاد را ﻧﻤﺎﻳﺶ دﻫﺪ‪ .‬در اﻳﻦ ﺻﻮرت ﺑﺎ ﺗﻮﺟـﻪ ﺑـﻪ‬ ‫اﻳﻨﻜﻪ ‪ XML‬ﺑﻪ ﺻﻮرت ﻳﻚ ﻓﺎﻳﻞ ﻣﺘﻨﻲ ذﺧﻴﺮه ﻣﻲ ﺷﻮد‪ ،‬ﻣﻲ ﺗﻮاﻧﺴﺘﻴﺪ آن را ﺑﺎ ﻳﻚ وﻳﺮاﻳﺸﮕﺮ ﻣﺘﻦ ﻣﻌﻤﻮﻟﻲ ﺑﺎز ﻛﺮده و آن را ﺑﺨﻮاﻧﻴﺪ‪ .‬ﺑﻪ‬ ‫اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﻮﺟﻪ ﻣﻲ ﺷﻮﻳﺪ ﻛﻪ اﻳﻦ ﻓﺎﻳﻞ ﺣﺎوي ﻋﻨﺎﺻﺮي از ﻧﻮع ‪ Address‬اﺳﺖ ﻛﻪ ﻫﺮ ﻛﺪام از اﻳﻦ ﻋﻨﺼﺮ ﻫﺎ داراي ﻋﻨـﺼﺮﻫﺎي‬ ‫دﻳﮕﺮي اﺳﺖ ﻛﻪ داده ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﻓﺮد را ذﺧﻴﺮه ﻣﻲ ﻛﻨﻨﺪ‪ .‬ﺳﻪ ﻋﻨﺼﺮ ‪ FirstName ،Email‬و ‪ LastName‬ﻧﻴﺰ‬ ‫در ﺑﻴﻦ اﻳﻦ داده ﻫﺎ وﺟﻮد دارﻧﺪ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ي ‪ Address List‬ﺑﻪ آﻧﻬﺎ ﻧﻴﺰ دارﻳﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻨﻬﺎ ﭼﻴﺰي ﻛـﻪ ﺑـﺎﻗﻲ ﻣـﻲ ﻣﺎﻧـﺪ‬ ‫ﺧﺎرج ﻛﺮدن اﻃﻼﻋﺎت داﺧﻞ ﻋﻨﺎﺻﺮ از اﻳﻦ ﻓﺎﻳﻞ اﺳﺖ‪.‬‬ ‫ﻫﻨﮕﺎم ﻣﻌﺮﻓﻲ ‪ .NET‬ﻳﻜﻲ از ﻋﺠﻴﺐ ﺗﺮﻳﻦ ﻛﺎرﻫﺎﻳﻲ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ اﻧﺠﺎم ﮔﺮﻓﺖ‪ ،‬ﭘﺸﺘﻴﺒﺎﻧﻲ ﺷﺪﻳﺪ ﭼﺎرﭼﻮب ‪.NET‬از‬ ‫‪ XML‬ﺑﻮد‪ .‬در ﭼﺎرﭼﻮب ‪ .NET‬ﺗﻌﺪاد ﭼﺸﻤﮕﻴﺮي ﻛﻼس ﺑﺮاي ﺧﻮاﻧﺪن و ﻳﺎ ﻧﻮﺷﺘﻦ ﻓﺎﻳﻠﻬﺎي ‪ XML‬وﺟﻮد داﺷﺖ‪ .‬در ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻠـﻲ‬ ‫ﻓﻘﻂ از ﻛﻼس ‪ XmlSerializer‬اﺳﺘﻔﺎده ﻛﺮدﻳﻢ ﻛﻪ ﻳﻜﻲ از ﺳﺎده ﺗﺮﻳﻦ ﻛﻼﺳﻬﺎي ‪ .NET‬ﺑﺮاي ﻛﺎر ﺑﺎ ‪ XML‬ﺑﻮد‪ .‬وﻳﮋﮔﻲ‬ ‫اﻳﻦ ﻛﻼس در اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺮاي ﺗﻮﻟﻴﺪ ﻓﺎﻳﻞ ‪ XML‬ﻓﻘﻂ ﺑﻪ ﺳﺎﺧﺘﺎر ﻛﻼس ﺷﻤﺎ اﺳﺘﻨﺎد ﻣﻲ ﻛﻨﺪ‪ .‬اﻣﺎ اﮔـﺮ ﻳـﻚ ﻓﺎﻳـﻞ ‪ XML‬را از ﻳـﻚ‬ ‫ﺑﺮﻧﺎﻣﻪ ي دﻳﮕﺮ درﻳﺎﻓﺖ ﻛﻨﻴﺪ و ﺑﺨﻮاﻫﻴﺪ از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ ،‬ﻧﻤﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ ﻛﻼس را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ زﻳﺮا ﻛﻼﺳﻲ در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد ﻧﺪارﻳﺪ‬ ‫ﻛﻪ ﺳﺎﺧﺘﺎر آن ﻣﺸﺎﺑﻪ ﺳﺎﺧﺘﺎر ﻓﺎﻳﻞ ‪ XML‬ﻣﻮرد ﻧﻈﺮ ﺷﻤﺎ ﺑﺎﺷﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ از ﻛﻼس دﻳﮕﺮي ﺑﺮاي ﺧﻮاﻧﺪن و ﻧﻮﺷﺘﻦ داده ﻫﺎي ‪XML‬‬ ‫در اﻳﻦ ﮔﻮﻧﻪ ﻓﺎﻳﻠﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬ ‫در ﺑﺮﻧﺎﻣﻪ ي ‪ Address List‬ﻧﻴﺰ ﺷـﺮاﻳﻂ ﻣـﺸﺎﺑﻪ ي ﺑﺮﻗـﺮار اﺳـﺖ‪ .‬در اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ ﻛﻼﺳـﻲ ﺑـﻪ ﻧـﺎم ‪ Address‬و ﻳـﺎ‬ ‫‪ AddressBook‬ﻧﺪارﻳﻢ ﻛﻪ از ﻛﻼس ‪ XmlSerializer‬ﺑﺨﻮاﻫﻴﻢ داده ﻫﺎ را در اﺷﻴﺎﻳﻲ از اﻳﻦ ﻛﻼﺳـﻬﺎ ﻗـﺮار دﻫـﺪ‪.‬‬ ‫ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻼﺳﻬﺎي دﻳﮕﺮي‪ ،‬ﻓﺎﻳﻞ ‪ XML‬را ﺑﻪ ﺻﻮرت ﺧﻂ ﺑﻪ ﺧﻂ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ‪ .‬ﻳﻜﻲ از ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ ﻣـﻲ ﺗـﻮاﻧﻴﻢ‬ ‫ﺑﺮاي اﻳﻦ ﻣﻮرد اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪ ،‬ﻛﻼس ‪ System.Xml.XmlTextReader‬اﺳﺖ‪ .‬اﻳﻦ ﻛﻼس ﻳﻚ ﻓﺎﻳﻞ ‪ XML‬را ﺑـﺎز‬ ‫ﻛﺮده و ﺑﻪ اﺑﺘﺪاي آن اﺷﺎره ﻣﻲ ﻛﻨﺪ‪ .‬ﺳﭙﺲ ﻣﻲ ﺗﻮاﻧﻴﻢ از آن ﺑﺨﻮاﻫﻴﻢ ﻛﻪ ﻗﺴﻤﺖ ﻗﺴﻤﺖ در ﻓﺎﻳﻞ ﺣﺮﻛﺖ ﻛﻨﺪ )ﻫﺮ ﻗﺴﻤﺖ ﻳـﻚ ﮔـﺮه ﻳـﺎ‬ ‫‪ node‬ﻧﺎﻣﻴﺪه ﻣﻲ ﺷﻮد(‪ .‬اﻳﻦ ﻛﻼس در ﻓﺎﻳﻞ ﺣﺮﻛﺖ ﻛﺮده و در اﺑﺘﺪاي ﻫﺮ ﻗﺴﻤﺖ ﺗﻮﻗﻒ ﻣﻲ ﻛﻨـﺪ‪ ،‬ﺑـﺮاي ﻣﺜـﺎل در اﺑﺘـﺪاي ﺗﮕﻬـﺎي‬ ‫ﺷﺮوع‪ ،‬در اﺑﺘﺪاي ﺗﮕﻬﺎي ﭘﺎﻳﺎن‪ ،‬در اﺑﺘﺪاي داده ﻫﺎي درون ﻋﻨﺎﺻﺮ‪ ،‬در اﺑﺘﺪاي ﺧﺼﻴﺼﻪ ﻫﺎ و ‪....‬‬ ‫ﺑﻨﺎﺑﺮاﻳﻦ زﻣﺎﻧﻲ ﻛﻪ از اﻳﻦ ﻛﻼس ﻣﻲ ﺧﻮاﻫﻴﺪ ﻛﻪ در ﻓﺎﻳﻞ ﺣﺮﻛﺖ ﻛﻨﺪ‪ ،‬اﺑﺘﺪا ﮔﺮه ي زﻳﺮ را ﺑﻪ ﺷﻤﺎ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ‪:‬‬ ‫>?"‪
‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ از او ﺑﺨﻮاﻫﻴﺪ ﺑﻪ ﺧﻂ ﺑﻌﺪي ﺑﺮود‪ ،‬ﻛﻼس ﺑﻪ اﻳﻦ ﺧﻂ از ﻓﺎﻳﻞ ﻣﻲ رﺳﺪ‪:‬‬ ‫"‪"‪xmlns:xsd="http://www.w3.org/2001/XMLSchema‬‬

‫ﺳﭙﺲ‪ ،‬ﻣﺠﺪداً از ﻛﻼس ﻣﻲ ﺧﻮاﻫﻴﺪ ﻛﻪ ﺑﻪ ﺧﻂ ﺑﻌﺪي ﺑﺮود و ﻛﻼس ﻧﻴﺰ در اﺑﺘﺪاي اﻳﻦ ﺧﻂ ﺗﻮﻗﻒ ﻣﻲ ﻛﻨﺪ‪:‬‬ ‫>‪
‫ﺑـــــﻪ ﻫﻤـــــﻴﻦ ﺗﺮﺗﻴـــــﺐ ﻛـــــﻼس ‪ XmlTextReader‬اﻃﻼﻋـــــﺎﺗﻲ را در راﺑﻄـــــﻪ ﺑـــــﺎ rel="nofollow">‪، ،Muhammad
‫ﻧﻴﺰ ﺷﻴﺊ ﻳﻚ ﮔﺮه درون ﻓﺎﻳﻞ ﺑﻪ ﺟﻠﻮ ﺣﺮﻛﺖ ﺧﻮاﻫﺪ ﻛﺮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ‪ Read‬را درون ﻳﻚ ﺣﻠﻘﻪ ي ‪ while‬ﻗـﺮار ﻣـﻲ‬ ‫دﻫﻴﻢ ﺗﺎ ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ ﺑﻴﻦ ﺗﻚ ﺗﻚ ﮔﺮه ﻫﺎي ﻣﻮﺟﻮد در ﻓﺎﻳﻞ ﺣﺮﻛﺖ ﻛﺮده و آﻧﻬﺎ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ‪.‬‬ ‫)‪private void Form1_Load(object sender, EventArgs e‬‬ ‫{‬ ‫‪// where do we want to get the XML from...‬‬ ‫= ‪String filename‬‬ ‫‪@"E:\Documents and Settings\Mohammad\My " +‬‬ ‫‪"Documents\Visual Studio 2005\Projects\" +‬‬ ‫‪"Address Book\Address Book\bin\" +‬‬ ‫;"‪"Debug\AddressBook.xml‬‬ ‫‪// open the document...‬‬ ‫;)‪XmlTextReader reader = new XmlTextReader(filename‬‬ ‫‪// move to the start of the document...‬‬ ‫;)(‪reader.MoveToContent‬‬ ‫‪// start working through the document...‬‬ ‫;‪Hashtable addressData = null‬‬ ‫;‪String elementName = null‬‬ ‫))(‪while(reader.Read‬‬ ‫{‬

‫ﺑﺮاي اﻳﻨﻜﻪ ﺑﻔﻬﻤﻴﻢ ﮔﺮه اي ﻛﻪ ﻫﻢ اﻛﻨﻮن در اﺑﺘﺪاي آن ﻗﺮار دارﻳﻢ ﭼﻪ ﻧﻮع ﮔﺮه اي اﺳﺖ‪ ،‬ﻣﻲ ﺗـﻮاﻧﻴﻢ از ﺧﺎﺻـﻴﺖ ‪ NodeType‬از‬ ‫ﻛﻼس ‪ XmlTextReader‬اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪ .‬اﮔﺮ ﻧﻮع ﮔﺮه ﺑﺮاﺑﺮ ﺑﺎ ‪ Element‬ﺑﻮد ﺑﻪ اﻳﻦ ﻣﻌﻨـﻲ اﺳـﺖ ﻛـﻪ در اﺑﺘـﺪاي ﺗـﮓ‬ ‫ﺷﺮوع ﻳﻚ ﻋﻨﺼﺮ ﻗﺮار دارﻳﻢ‪ .‬ﺑﺮاي اﻳﻨﻜﻪ ﻧﺎم ﻋﻨﺼﺮي ﻛﻪ در اﺑﺘﺪاي آن ﻗﺮار دارﻳـﻢ را ﻧﻴـﺰ ﺑﺪﺳـﺖ آورﻳـﻢ ﻧﻴـﺰ ﻣـﻲ ﺗـﻮاﻧﻴﻢ از ﺧﺎﺻـﻴﺖ‬ ‫‪ Name‬اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﮔﺮ ﻧﺎم ﻋﻨﺼﺮي ﻛﻪ ﺑﻪ آن رﺳﻴﺪﻳﻢ ﺑﺮاﺑﺮ ﺑﺎ ‪ Address‬ﺑﻮد‪ ،‬ﻳﻌﻨﻲ در اﺑﺘﺪاي اﻃﻼﻋﺎت ﻣﺮﺑﻮط‬ ‫ﺑﻪ ﻳﻚ ﻓﺮد ﺟﺪﻳﺪ ﻫﺴﺘﻴﻢ‪ .‬ﭘﺲ ﻳﻚ ﺷﻴﺊ از ﻧﻮع ‪ HashTable‬اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز از اﻳﻦ ﻓـﺮد ﺟﺪﻳـﺪ را در آن‬ ‫ﻗﺮار دﻫﻴﻢ‪ .‬در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻧﻴﺰ ﻧﺎم ﻋﻨﺼﺮ را در ﻳﻚ ﻣﺘﻐﻴﻴﺮ ذﺧﻴﺮه ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﻌﺪﻫﺎ از آن اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪:‬‬ ‫?‪// what kind of node to we have‬‬ ‫)‪switch(reader.NodeType‬‬ ‫{‬ ‫?‪// is it the start of an element‬‬ ‫‪case XmlNodeType.Element:‬‬ ‫?”‪// if it’s an element start, is it “Address‬‬ ‫) "‪if (reader.Name == "Address‬‬ ‫‪// if so, create a new collection...‬‬ ‫;)(‪addressData = new Hashtable‬‬ ‫‪else‬‬ ‫‪// if not, record the name of the element...‬‬ ‫;‪elementName = reader.Name‬‬ ‫;‪break‬‬

‫ﻫﻤﭽﻨﻴﻦ ﻣﻤﻜﻦ اﺳﺖ ﻋﻨﺼﺮي ﻛﻪ در آن ﻗﺮار دارﻳﻢ ﺷﺎﻣﻞ ﻣﻘﺪاري ﻣـﺘﻦ ﺑﺎﺷـﺪ‪ .‬در اﻳـﻦ ﺻـﻮرت ﺑﺮرﺳـﻲ ﻣـﻲ ﻛﻨـﻴﻢ ﻛـﻪ آﻳـﺎ ﻣﺘﻐﻴﻴـﺮ‬ ‫‪ addressData‬ﻣﻘﺪار دﻫﻲ ﺷﺪه اﺳﺖ ﻳﺎ ﻧﻪ )داراي ﻳﻚ ﺷﻴﺊ از ﻧﻮع ‪ HashTable‬اﺳﺖ ﻳﺎ ﻧﻪ(؟ در ﺻﻮرﺗﻲ ﻛـﻪ ﻣﻘـﺪار‬ ‫دﻫﻲ ﺷﺪه ﺑﻮد‪ ،‬ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻫﻢ اﻛﻨﻮن درون داده ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﻓﺮد )در ﻋﻨﺎﺻﺮ دروﻧﻲ ﻋﻨﺼﺮ ‪ (address‬ﻫﺴﺘﻴﻢ‪.‬‬ ‫ﻫﻤﭽﻨﻴﻦ ﺑﻪ ﺧﺎﻃﺮ دارﻳﻢ ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ‪ ،‬ﻧﺎم ﻋﻨﺼﺮي ﻛﻪ درون آن ﻫﺴﺘﻴﻢ را ﻧﻴﺰ در ﻣﺘﻐﻴﻴﺮ ‪ elementName‬ذﺧﻴﺮه ﻛـﺮدﻳﻢ‪.‬‬ ‫ﭘﺲ اﮔﺮ ﺑﺮاي ﻣﺜﺎل ﻋﻨﺼﺮ ‪ elementName‬ﺑﺮاﺑﺮ ﺑﺎ ‪ FirstName‬ﺑﺎﺷﺪ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻣﺘﻨـﻲ ﻛـﻪ در اﺑﺘـﺪاي آن‬

‫‪٨٠٩‬‬

‫ﻗﺮار دارﻳﻢ‪ ،‬ﻣﺮﺑﻮط ﺑﻪ ﺧﺎﺻﻴﺖ ‪ FirstName‬ﻳﻜﻲ از رﻛﻮرد ﻫﺎي اﻳﻦ ﻓﺎﻳﻞ اﺳﺖ‪ .‬ﺳﭙﺲ اﻳﻦ اﻃﻼﻋﺎت را ﺑـﻪ ‪HashTable‬‬ ‫اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ در اﻧﺘﻬﺎ ﻛﻪ ﻟﻴﺴﺖ داده ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ رﻛﻮرد ﺟﺎري ﺗﻜﻤﻴﻞ ﺷﺪ از آن اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪.‬‬ ‫‪// if we have some text, try storing it in the‬‬ ‫‪// collection...‬‬ ‫‪case XmlNodeType.Text:‬‬ ‫?‪// do we have an address‬‬ ‫)‪if (addressData != null‬‬ ‫;)‪addressData.Add(elementName, reader.Value‬‬ ‫;‪break‬‬

‫ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴﺐ ﻛﻪ ﺣﻠﻘﻪ ي ‪ while‬اﺟﺮا ﺷﺪه و ﻛﻼس ‪ XmlTextReader‬در ﺑﻴﻦ داده ﻫﺎي درون ﻓﺎﻳـﻞ ﺣﺮﻛـﺖ ﻣـﻲ‬ ‫ﻛﻨﺪ‪ ،‬داده ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ رﻛﻮرد ﻧﻴﺰ درون ‪ HashTable‬ﻗﺮار ﻣﻲ ﮔﻴﺮد ﺗﺎ ﺑﻪ اﻧﺘﻬﺎي رﻛـﻮرد ﺟـﺎري‪ ،‬ﻳﻌﻨـﻲ ﺑـﻪ ﺗـﮓ ﭘﺎﻳـﺎﻧﻲ‬ ‫ﻣﺮﺑﻮط ﺑﻪ ‪ address‬ﺑﺮﺳﻴﻢ‪.‬‬ ‫ﺑﺮاي اﻳﻨﻜﻪ ﺑﺪاﻧﻴﻢ آﻳﺎ ﺑﻪ ﺗﮓ >‪
‫اﮔﺮ ﻧﻮع ﮔﺮه اي ﻛﻪ ﺑﻪ آن رﺳﻴﺪه اﻳﻢ از ﻧﻮع ﺗﮓ ﭘﺎﻳﺎﻧﻲ و ﻧﺎم آن ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎ ‪ Address‬ﺑـﻮد‪ ،‬ﺑـﻪ اﻳـﻦ ﻣﻌﻨـﻲ اﺳـﺖ ﻛـﻪ ﺑـﻪ ﺗـﮓ‬ ‫>‪
‫ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﺑﻼك ‪ catch‬ﻛﻪ ﺑﻌﺪ از ﺑﻼك ‪ try‬ﻗﺮار ﮔﻔﺘﻪ اﺳﺖ‪ ،‬در ﺻﻮرت رخ دادن ﺧﻄﺎ ﻫﻴﭻ ﻋﻤـﻞ ﺧﺎﺻـﻲ را اﻧﺠـﺎم ﻧﻤـﻲ‬ ‫دﻫﺪ‪ .‬در اﻳﻦ ﻣﺜﺎل ﺑﺮاي اﻳﻨﻜﻪ درﮔﻴﺮ ﺧﻄﺎ ﻳﺎﺑﻲ ﻧﺸﻮﻳﻢ‪ ،‬ﻫﺮ ﮔﻮﻧﻪ ﺧﻄﺎﻳﻲ ﻛﻪ رخ دﻫﺪ را در ﻧﻈﺮ ﻧﺨﻮاﻫﻴﻢ ﮔﺮﻓﺖ‪ .‬ﺑﺮاي ﻣﺜـﺎل اﮔـﺮ ﻋﻨـﺼﺮ‬

‫‪٨١٠‬‬

‫دروﻧﻲ ﻛﻪ در ﺣﺎل ﺑﺮرﺳﻲ آن ﻫﺴﺘﻴﻢ ﺑﻌﻀﻲ از ﺗﮓ ﻫﺎ را ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ‪ ،‬ﺑﺮاي ﻣﺜﺎل داراي ﺗﮓ ‪ email‬ﻧﺒﺎﺷﺪ‪ ،‬ﺧﻄﺎﻳﻲ رخ ﺧﻮاﻫـﺪ داد‬ ‫ﻛﻪ از آن ﺻﺮﻓﻨﻈﺮ ﻣﻲ ﻛﻨﻴﻢ‪.‬‬ ‫ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴﺐ ﺣﻠﻘﻪ اداﻣﻪ ﭘﻴﺪا ﻛﺮده و ﺑﻴﻦ ﺗﻤﺎم ﮔﺮه ﻫﺎﻳﻲ ﻛﻪ در ﻓﺎﻳﻞ وﺟﻮد دارﻧﺪ ﺣﺮﻛﺖ ﻣﻲ ﻛﻨﺪ ﺗﺎ ﺑﻪ اﻧﺘﻬﺎي ﻓﺎﻳـﻞ ﺑﺮﺳـﺪ‪ .‬در اﻳـﻦ‬ ‫زﻣﺎن ﺗﻤﺎم داده ﻫﺎي ﻓﺎﻳﻞ ﺑﺮرﺳﻲ ﺷﺪه اﻧﺪ و ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ‪ Read‬ﻧﻴﺰ ﻣﻘﺪار ‪ false‬را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ ﻛـﻪ از اﺟـﺮاي ﻣﺠـﺪد ﺣﻠﻘـﻪ‬ ‫ﺟﻠﻮﮔﻴﺮي ﻣﻲ ﻛﻨﺪ و ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﺟﺮاي ﺣﻠﻘﻪ ﻣﺘﻮﻗﻒ ﻣﻲ ﺷﻮد‪.‬‬ ‫اﻣﻴﺪوارم ﻛﻪ اﻳﻦ ﻣﺜﺎل ﺑﻪ اﻧﺪازه ي ﻛﺎﻓﻲ ﺗﻮاﻧﺴﺘﻪ ﺑﺎﺷﺪ ﻗﺪرت ‪ XML‬در ﻳﻜﭙﺎرﭼﻪ ﺳﺎزي ﺑﺮﻧﺎﻣﻪ ﻫﺎ را ﺗﻮﺿﻴﺢ دﻫﺪ‪ .‬اﮔـﺮ ﻣـﻲ ﺧﻮاﻫﻴـﺪ ﺑـﺎ‬ ‫ﺗﻤﺮﻳﻦ ﺑﻴﺸﺘﺮ روي اﻳﻦ ﻣﺜﺎل‪ ،‬ﺗﺠﺮﺑﻪ ي ﺧﻮد را در ﻛﺎر ﺑﺎ ‪ XML‬اﻓﺰاﻳﺶ دﻫﻴﺪ‪ ،‬ﺳﻌﻲ ﻛﻨﻴﺪ ﻗﺎﺑﻠﻴﺖ ﺣﺬف و ﻳـﺎ اﺿـﺎﻓﻪ ﻛـﺮدن داده ﻫـﺎي‬ ‫ﺟﺪﻳﺪ را ﻧﻴﺰ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ‪ Address List‬اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪.‬‬

‫ﻧﺘﻴﺠﻪ‪:‬‬ ‫در اﻳﻦ ﻓﺼﻞ ﺑﺎ ﻣﻔﺎﻫﻴﻢ ‪ XML‬آﺷﻨﺎ ﺷﺪﻳﻢ‪ XML .‬زﺑﺎﻧﻲ اﺳﺖ ﻛﻪ ﺑﻴﺸﺘﺮ ﺑﺮاي اﻳﺠﺎد ﻳﻜﭙﺎرﭼﮕﻲ ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ و ﻧﺮم اﻓﺰارﻫﺎي ﺗﺠـﺎري‬ ‫ﻣﻮﺟﻮد ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد‪ .‬در ﻳﻚ ﺳﺎزﻣﺎن ﻣﻲ ﺗﻮان از ‪ XML‬ﺑﺮاي ﺗﺒﺎدل و اﻧﺘﻘﺎل داده ﻫﺎ در ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺨﺘﻠﻒ اﺳﺘﻔﺎده‬ ‫ﻛﺮد‪ .‬در ﺑﻴﻦ ﭼﻨﺪ ﺳﺎزﻣﺎن ﻣﺨﺘﻠﻒ ﻧﻴﺰ ﻣﻲ ﺗﻮان ﻳﻚ ﻓﺮﻣﺖ ﺧﺎص ‪ XML‬را ﺗﻌﺮﻳﻒ ﻛﺮده و ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻨﻈﻴﻢ ﻛﺮد ﺗﺎ‬ ‫ﺑﺘﻮاﻧﻨﺪ داده ﻫﺎي ﺧﻮد را ﺑﺮ اﺳﺎس اﻳﻦ ﻓﺮﻣﺖ اﻧﺘﻘﺎل دﻫﻨﺪ و ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺮﻧﺎﻣﻪ ﻫﺎي اﻳﻦ ﭼﻨﺪ ﺳﺎزﻣﺎن ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﺗﻌﺎﻣﻞ داﺷﺘﻪ ﺑﺎﺷـﻨﺪ‪.‬‬ ‫ﻫﻤﭽﻨﻴﻦ ﺑﻪ دﻟﻴﻞ اﻳﻨﻜﻪ ﻓﺎﻳﻠﻬﺎي ‪ XML‬ﺑﻪ ﺻﻮرت ﻣﺘﻦ ذﺧﻴﺮه ﻣﻲ ﺷﻮﻧﺪ‪ ،‬ﻣﻲ ﺗﻮان آﻧﻬﺎ را ﺑﻪ ﺳﺎدﮔﻲ از ﻃﺮﻳﻖ اﻳﻨﺘﺮﻧﺖ و ﺑـﺎ اﺳـﺘﻔﺎده از‬ ‫ﺗﻜﻨﻮﻟﻮژي ﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ ‪ Email ،FTP ،HTTP‬و ‪ ...‬ﻣﻨﺘﻘﻞ ﻛﺮد و دﻳﮕﺮ ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﭼﻨﺪ ﺳﺎزﻣﺎﻧﻲ ﻛﻪ ﻣـﻲ ﺧﻮاﻫﻨـﺪ ﺑـﻪ اﻳـﻦ‬ ‫روش ﺑﺎ ﻫﻢ ﺗﺒﺎدل اﻃﻼﻋﺎت داﺷﺘﻪ ﺑﺎﺷﻨﺪ از ﺑﺮﻗﺮاري اﺗﺼﺎﻻت اﺧﺘﺼﺎﺻﻲ اﺳﺘﻔﺎده ﻛﻨﻨﺪ‪.‬‬ ‫‪ XML‬ﻋﻤﺪﺗﺎ ﺑﺮاي ﺑﺮﻗﺮاري ﻳﻜﭙﺎرﭼﮕﻲ ﺑﻴﻦ ﻧﺮم اﻓﺰارﻫﺎي ﺗﺠﺎري ﻛﻪ روي ﭘﻠﺖ ﻓﺮم ﻫﺎي ﮔﻮﻧﺎﮔﻮن ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ اﻳﺠﺎد ﺷﺪه اﺳـﺖ‪ ،‬اﻣـﺎ‬ ‫ﺑﺮاي اﻓﺮاد ﺗﺎزه ﻛﺎر ‪ XML‬ﻋﻤﺪﺗﺎ ﺑﺮاي ذﺧﻴﺮه ي داده ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد‪ .‬در اﻳﻦ ﻓﺼﻞ ﻧﻴﺰ ﺑﺎ ﻧﺤـﻮه ي اﺳـﺘﻔﺎده از‬ ‫‪ XML‬ﺑﺮاي ذﺧﻴﺮه ي داده ﻫﺎ آﺷﻨﺎ ﺷﺪﻳﻢ و ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان داده ﻫﺎي ﻳﻚ ﻛﻼس را ﺳﺮﻳﺎﻻﻳﺰ ﻛـﺮده و ﺳـﭙﺲ در‬ ‫ﻳﻚ ﻓﺎﻳﻞ در دﻳﺴﻚ ذﺧﻴﺮه ﻛﺮد و ﻳﺎ داده ﻫﺎي ﻳﻚ ﻛﻼس ﻛﻪ در دﻳﺴﻚ ذﺧﻴﺮه ﺷﺪه اﺳﺖ را دي ﺳﺮﻳﺎﻻﻳﺰ ﻛﺮده و ﻛﻼس ﻣﺘﻨـﺎﻇﺮ آن‬ ‫را در ﺑﺮﻧﺎﻣــــﻪ اﻳﺠــــﺎد ﻛــــﺮد‪ .‬ﺑــــﻪ اﻳــــﻦ ﺗﺮﺗﻴــــﺐ ﺑــــﺎ اﺳــــﺘﻔﺎده از ﻫﻤــــﻴﻦ ﻣــــﻮارد ﺑﺮﻧﺎﻣــــﻪ اي ﺑــــﻪ ﻧــــﺎم‬ ‫‪ Address Book‬اﻳﺠﺎد ﻛﺮدﻳﻢ ﻛﻪ از ﻓﺎﻳﻞ ‪ XML‬ﺑﻪ ﻋﻨﻮان ﻣﻨﺒﻊ اﺻﻠﻲ ﺑﺮاي ﻧﮕﻬﺪاري داده ﻫﺎي ﺧﻮد اﺳﺘﻔﺎده ﻣﻲ ﻛﺮد‪.‬‬ ‫در آﺧﺮ ﻓﺼﻞ ﻧﻴﺰ‪ ،‬ﺑﺮاي اﻳﻨﻜﻪ ﻣﺸﺎﻫﺪه ﻛﻨﻴﻢ ﭼﮕﻮﻧﻪ ‪ XML‬ﻣﻲ ﺗﻮاﻧﺪ در ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻳﻜﭙﺎرﭼﮕﻲ اﻳﺠﺎد ﻛﻨﺪ‪ ،‬ﺑﺮﻧﺎﻣﻪ اي ﻧﻮﺷـﺘﻴﻢ ﻛـﻪ از‬ ‫ﻓﺎﻳﻞ ‪ XML‬ﺗﻮﻟﻴﺪ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي ‪ Address Book‬اﺳﺘﻔﺎده ﻣﻲ ﻛﺮد و داده ﻫﺎي آن را در ﻓﺮم ﻧﻤﺎﻳﺶ ﻣﻲ داد‪.‬‬ ‫در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ‪:‬‬ ‫‬ ‫‬ ‫‬ ‫‬

‫درك ﺑﻬﺘﺮي از ‪ XML‬ﺑﺪﺳﺖ آورده ﺑﺎﺷﻴﺪ و ﺑﺪاﻧﻴﺪ ﻛﻪ اﻳﻦ ﺗﻜﻨﻮﻟﻮژي در ﭼﻪ ﻣﻮاردي اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد‪.‬‬ ‫ﺑﺘﻮاﻧﻴﺪ داده ﻫﺎي ﻳﻚ ﻛﻼس را ﺳﺮﻳﺎﻻﻳﺰ و دي ﺳﺮﻳﺎﻻﻳﺰ ﻛﻨﻴﺪ‪.‬‬ ‫ﺑﺘﻮاﻧﻴﺪ داده ﻫﺎي ‪ XML‬را در ﺑﺮﻧﺎﻣﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار دﻫﻴﺪ‪.‬‬ ‫ﺑﺘﻮاﻧﻴﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻛﻼس ‪ XmlTextReader‬در ﻳﻚ ﻓﺎﻳﻞ ‪ XML‬ﺣﺮﻛﺖ ﻛﺮده و داده ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺧـﻮد را از‬ ‫آن اﺳﺘﺨﺮاج ﻛﻨﻴﺪ‪.‬‬

‫ﺗﻤﺮﻳﻦ‪:‬‬

‫‪٨١١‬‬

‫ﺗﻤﺮﻳﻦ ‪:1‬‬ ‫ﻳﻚ ﻓﺎﻳﻞ ‪ XML‬اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ ﻳﻚ ﻻﻣﭗ را ﺗﻮﺻﻴﻒ ﻛﻨﺪ‪ .‬ﺑﺮاي ﺗﻮﺻﻴﻒ ﻳﻚ ﻻﻣﭗ ﻣﻲ ﺗﻮاﻧﻴﺪ از ﭼﻨﺪﻳﻦ روش ﻣﺨﺘﻠﻒ اﺳﺘﻔﺎده ﻛﻨﻴـﺪ‪.‬‬ ‫ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﻋﻨﺎﺻﺮ ﻣﺮﺑﻮط ﺑﻪ ﻇﺎﻫﺮ ﺣﺒﺎب ﻻﻣﭗ‪ ،‬اﻃﻼﻋﺎت ﻓﻨﻲ ﻻﻣﭗ و ﻧﻴﺰ ﻣﺸﺨﺼﺎت ﺧﻮد ﻻﻣﭗ ﻣﺎﻧﻨﺪ ﻗﻴﻤـﺖ و … اﺳـﺘﻔﺎده‬ ‫ﻛﻨﻴﺪ‪ .‬ﺑﺮاي ﺑﺮرﺳﻲ ﺻﺤﺖ ﻓﺎﻳﻞ ‪ XML‬اي ﻛﻪ اﻳﺠﺎد ﻛﺮده اﻳـﺪ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﻪ ﻧﻤﻮﻧـﻪ ﻫـﺎﻳﻲ ﻛـﻪ در اﻳﻨﺘﺮﻧـﺖ و در ﺳـﺎﻳﺘﻬﺎﻳﻲ ﻣﺎﻧﻨـﺪ‬ ‫‪ http://www.w3schools.com/dom/dom_validate.asp‬وﺟﻮد دارد رﺟﻮع ﻛﻨﻴﺪ‪.‬‬

‫ﺗﻤﺮﻳﻦ ‪:2‬‬ ‫ﺑﺮاي اﻳﻦ ﺗﻤﺮﻳﻦ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻣﻄﺎﻟﺒﻲ را ﻛﻪ در ﻃﻮل ﻓﺼﻞ آﻣﻮﺧﺘﻴﻢ‪ ،‬ﺑﺎ ﻳـﺎدﮔﻴﺮي ﻧﺤـﻮه ي ﻗـﺮار دادن ﺗﻮﺿـﻴﺤﺎت در ﻓﺎﻳﻠﻬـﺎي ‪XML‬‬ ‫اﻓﺰاﻳﺶ دﻫﻴﻢ‪ .‬ﺑﻪ ﻋﻨﻮان ﻛﺴﻲ ﻛﻪ ﺑﻪ ﺗﺎزﮔﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ را آﻏﺎز ﻛﺮده اﺳﺖ‪ ،‬ﻣﻬﻤﺘﺮﻳﻦ ﺗﻮاﻧﺎﻳﻲ ﻛﻪ ﺑﺎﻳﺪ ﺑﺪﺳﺖ آورﻳﺪ ﻧﺤﻮه ي ﺟـﺴﺘﺠﻮ‬ ‫در اﻳﻨﺘﺮﻧﺖ و ﻳﺎﻓﺘﻦ ﭘﺎﺳﺨﻬﺎي ﻣﻮرد ﻧﻴﺎزﺗﺎن اﺳﺖ‪ .‬در اﻳﻦ ﺗﻤﺮﻳﻦ ﺑﺎ اﺳﺘﻔﺎده از ﻣﻮﺗﻮر ﺟﺴﺘﺠﻮي ﻣﻮرد ﻧﻈﺮ ﺧﻮد اﻳﻨﺘﺮﻧﺖ را ﺟﺴﺘﺠﻮ ﻛـﺮده‬ ‫و ﻧﺤﻮه ي ﻗﺮار دادن ﺗﻮﺿﻴﺤﺎت در ﻓﺎﻳﻞ ‪ XML‬را ﭘﻴﺪا ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ ﺗﻮﺿﻴﺤﺎت ﻻزم ﺑﺮاي ﻓﺎﻳﻞ ‪ XML‬اي ﻛﻪ در ﻗـﺴﻤﺖ ﻗﺒـﻞ اﻳﺠـﺎد‬ ‫ﻛﺮده ﺑﻮدﻳﻢ را در آن ﺑﻨﻮﻳﺴﻴﺪ‪.‬‬

‫‪٨١٢‬‬

‫ﻓﺼﻞ ﺑﻴﺴﺘﻢ‪ :‬وب ﺳﺮوﻳﺲ ﻫﺎ و ‪.NET Remoting‬‬ ‫ﺻﺎﺣﺒﻨﻈﺮان ﺻﻨﻌﺘﻲ ﭘﻴﺸﺒﻴﻨﻲ ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ وب ﺳﺮوﻳﺲ ﻫﺎ رﺧﺪاد ﻋﻈﻴﻢ ﺑﻌﺪي ﺧﻮاﻫﺪ ﺑﻮد ﻛﻪ در اﻳﻨﺘﺮﻧﺖ ﺑﻪ وﺟﻮد ﺧﻮاﻫﺪ آﻣـﺪ‪ .‬در اﻳـﻦ‬ ‫ﻓﺼﻞ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ اﺑﺘﺪا وب ﺳﺮوﻳﺲ ﻫﺎ را ﻣﻌﺮﻓﻲ ﻛﺮده و ﺳﭙﺲ ﻧﺤﻮه ي اﻳﺠﺎد آﻧﻬﺎ را ﺑﺮرﺳﻲ ﻛﻨﻴﻢ‪ .‬ﻫﻤﭽﻨـﻴﻦ ﺳـﻌﻲ ﻣـﻲ ﻛﻨـﻴﻢ در‬ ‫ﻃﻮل ﻓﺼﻞ ﺑﺎ ‪ .NET Remoting‬ﻧﻴﺰ آﺷﻨﺎ ﺷﻮﻳﻢ و ﻧﻜﺎﺗﻲ را در ﻣﻮرد اﻳﻨﻜﻪ در ﭼﻪ ﺷﺮاﻳﻄﻲ ﺑﺎﻳﺪ از وب ﺳﺮوﻳﺲ ﻫـﺎ و در ﭼـﻪ‬ ‫ﺷﺮاﻳﻄﻲ ﺑﺎﻳﺪ از ‪ .NET Remoting‬اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪.‬‬ ‫در اﻳﻦ ﻓﺼﻞ‪:‬‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬

‫ﺑﺎ ‪ SOAP‬آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ‪ ،‬روﺷﻲ ﻛﻪ ﺑﺮاي اﻧﺘﻘﺎل اﻃﻼﻋﺎت در وب ﺳﺮوﻳﺲ ﻫﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد‪.‬‬ ‫ﭼﻨﺪﻳﻦ وب ﺳﺮوﻳﺲ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد‪.‬‬ ‫ﻋﻤﻠﻜﺮد وب ﺳﺮوﻳﺲ ﻫﺎ را ﺗﺴﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد‪.‬‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ از وب ﺳﺮوﻳﺲ ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻨﺪ‪.‬‬ ‫ﻧﮕﺎه ﻣﺨﺘﺼﺮي ﺑﺮ ‪ .NET Remoting‬و ﻣﻮارد اﺳﺘﻔﺎده ي آن ﺧﻮاﻫﻴﻢ داﺷﺖ‪.‬‬

‫وب ﺳﺮوﻳﺲ ﭼﻴﺴﺖ؟‬ ‫ﻣﻌﻤﻮﻻ ﺑﻴﺸﺘﺮ اﺳﺘﻔﺎده اي ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ از اﻳﻨﺘﺮﻧﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ‪ ،‬ارﺳﺎل و درﻳﺎﻓﺖ اﻳﻤﻴﻞ و ﻳـﺎ ﮔـﺮدش ﻛـﺮدن در وب اﺳـﺖ‪ .‬اﻳـﻦ دو‬ ‫ﻛﺎرﺑﺮد ﻣﻌﻤﻮﻻ ﺑﻴﺸﺘﺮﻳﻦ دﻟﻴﻠﻲ اﺳﺖ ﻛﻪ اﻓﺮاد ﺑﺮاي آن ﺑﻪ اﻳﻨﺘﺮﻧﺖ ﻣﺘﺼﻞ ﻣﻲ ﺷﻮﻧﺪ‪ .‬اﻣﺎ ﺑﺎ رﺷﺪ اﻳﻨﺘﺮﻧـﺖ‪ ،‬ﻧﺤـﻮه ي اﺳـﺘﻔﺎده ي اﻓـﺮاد از‬ ‫اﻳﻨﺘﺮﻧﺖ ﻧﻴﺰ در ﺣﺎل ﺗﻐﻴﻴﺮ ﻛﺮدن اﺳﺖ‪.‬‬ ‫ﺑﺎ رﺷﺪ اﻳﻨﺘﺮﻧﺖ‪ ،‬ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي اﻧﺠﺎم ﻛﺎرﻫﺎي ﺧﻮد ﺑﻪ اﺗﺼﺎل ﺑﻪ اﻳﻨﺘﺮﻧﺖ ﻧﻴﺎز دارﻧﺪ ﻧﻴﺰ در ﺣﺎل اﻓﺰاﻳﺶ اﺳﺖ‪ .‬ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي‬ ‫اﻣﺮوزي ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻨﺪ داده ﻫﺎﻳﻲ را ﺑﻪ ﺳﺮور ﺧﻮد ﺑﻔﺮﺳﺘﻨﺪ و ﻳﺎ اﻃﻼﻋﺎت ﺟﺪﻳﺪ را از ﺳﺮور درﻳﺎﻓﺖ ﻛﻨﻨﺪ ﻧﻴﺎز دارﻧﺪ ﻛـﻪ ﺑـﻪ اﻳﻨﺘﺮﻧـﺖ‬ ‫ﻣﺘﺼﻞ ﺑﺎﺷﻨﺪ‪ .‬ﻫﻤﻴﻦ ﻣﻮرد ﻣﻮﺟﺐ ﺷﺪه اﺳﺖ ﻛﻪ وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﻪ ﻳﻜﻲ از ﺑﺰرﮔﺘﺮﻳﻦ ﺗﺤﻮﻻت اﺧﻴﺮ در زﻣﻴﻨﻪ ي اﻳﻨﺘﺮﻧﺖ ﺗﺒﺪﻳﻞ ﺷـﻮﻧﺪ‪.‬‬ ‫ﺣﺘﻲ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ ﺑﻪ ﻫﻤﺎن اﻧﺪازه ﻛﻪ وب و ﺻﻔﺤﺎت وب در ﻣﺪت اﺧﻴﺮ رﺷﺪ داﺷﺘﻪ اﻧﺪ‪ ،‬وب ﺳﺮوﻳﺲ ﻫﺎ ﻧﻴﺰ رﺷـﺪ ﺧﻮاﻫﻨـﺪ ﻛـﺮد و‬ ‫ﻓﺮاﮔﻴﺮ ﺧﻮاﻫﻨﺪ ﺷﺪ‪ .‬اﻣﺎ ﺧﻮب ﻣﻤﻜﻦ اﺳﺖ ﺳﻮال ﻛﻨﻴﺪ ﻛﻪ ﭼﺮا وب ﺳﺮوﻳﺲ ﻫﺎ ﺗﺎ اﻳﻦ ﺣﺪ از اﻫﻤﻴﺖ ﺑﺮﺧﻮردار اﻧﺪ؟‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ ﺻﻔﺤﺎت وب ﻳﻜﻲ از ﺑﻬﺘﺮﻳﻦ راﻫﻬﺎ ﺑﺮاي ﺑﻪ اﺷﺘﺮاك ﮔﺬاﺷﺘﻦ اﻃﻼﻋﺎت اﺳﺖ‪ .‬ﻣﺎ ﻣﺸﻜﻠﻲ ﻛﻪ ﺻﻔﺤﺎت وب دارﻧﺪ و‬ ‫ﻳﺎ ﺑﻪ ﻋﺒﺎرت ﺑﻬﺘﺮ ﻣﻲ ﺗﻮان ﮔﻔﺖ ﻣﺤﺪودﻳﺘﻲ ﻛﻪ اﻳﻦ ﺻﻔﺤﺎت دارﻧﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﻓﻘﻂ اﻧﺴﺎﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻨﺪ از آن اﺳﺘﻔﺎده ﻛﻨﻨـﺪ! ﺻـﻔﺤﺎت‬ ‫وب ﺣﺘﻤﺎً ﺑﺎﻳﺪ ﺑﻪ وﺳﻴﻠﻪ ي اﻧﺴﺎﻧﻬﺎ ﺧﻮاﻧﺪه ﺷﻮد و اﻃﻼﻋﺎت درون آن ﻧﻴﺰ ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ وﺳﻴﻠﻪ ي ذﻫـﻦ اﻧـﺴﺎن درك ﺷـﻮد‪ .‬اﻣـﺎ وب‬ ‫ﺳﺮوﻳﺲ ﻫﺎ‪ ،‬از اﺑﺘﺪا ﺑﺮاي ﺧﻮاﻧﺪه ﺷﺪن و ﺗﻔﺴﻴﺮ ﺷﺪن ﺑﻪ وﺳﻴﻠﻪ ي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﺎﻣﭙﻴﻮﺗﺮي اﻳﺠﺎد ﺷﺪه اﻧﺪ و ﻧﻤـﻲ ﺗﻮاﻧﻨـﺪ ﺑـﻪ وﺳـﻴﻠﻪ ي‬ ‫اﻧﺴﺎﻧﻬﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮﻧﺪ‪ .‬در ﺣﻘﻴﻘﺖ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ ﻛﻪ وب ﺳﺮوﻳﺲ ﻫﺎ‪ ،‬ﺳﺎﻳﺘﻬﺎي وﺑﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﻓﻘﻂ ﺑﻪ وﺳﻴﻠﻪ ي ﺑﺮﻧﺎﻣـﻪ‬ ‫ﻫﺎي ﻛﺎﻣﭙﻴﻮﺗﺮي ﻣﻲ ﺗﻮاﻧﻨﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮﻧﺪ‪ .‬وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﻪ ﻃﻮر ذاﺗﻲ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ ﺻﻮرت دﻳﻨﺎﻣﻴﻚ ﺗﻐﻴﻴﺮ ﻛﻨﻨﺪ‪ ،‬ﺑﻨـﺎﺑﺮاﻳﻦ‬ ‫ﻻزم ﻧﻴﺴﺖ ﻛﻪ ﺣﺎوي اﻃﻼﻋﺎت ﺛﺎﺑﺖ و ﺗﻐﻴﻴﺮ ﻧﺎﭘﺬﻳﺮي ﺑﺎﺷﻨﺪ‪ ،‬ﺑﻠﻜﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﺎ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ ﺗﻌﺎﻣﻞ داﺷﺘﻪ ﺑﺎﺷﻨﺪ‬ ‫و ارﺗﺒﺎط ﺑﺮﻗﺮار ﻛﻨﻨﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل ﻣﻦ ﻣﻲ ﺗﻮاﻧﻢ در ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ ﻣﻲ ﻧﻮﻳﺴﻢ از ﻳﻚ وب ﺳﺮوﻳﺲ اﺳﺘﻔﺎده ﻛﻨﻢ ﻛـﻪ در ﻣﻮاﻗـﻊ ﻣـﻮرد ﻧﻴـﺎز‬ ‫ﻛﻤﻴﺘﻲ را ﺑﻪ واﺣﺪ دﻻر از ﺑﺮﻧﺎﻣﻪ ي ﻣﻦ درﻳﺎﻓﺖ ﻛﺮده و ﻣﻘﺪار ﻣﻌﺎدل آن را ﺑﻪ واﺣﺪ ﻳﻮرو ﺑﺮﮔﺮداﻧﺪ‪.‬‬ ‫ﺧﻮب ﻣﻤﻜﻦ اﺳﺖ ﺳﻮال ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ ﻣﻮرد ﭼﻪ ﻓﺎﻳﺪه اي دارد و ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮاﻧﺪ ﻣﻔﻴﺪ واﻗﻊ ﺷﻮد؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻓﺼﻞ ﻗﺒﻞ ﻧﻴﺰ در اﻳﻦ‬ ‫ﺑﺎره ﺻﺤﺒﺖ ﻛﺮدﻳﻢ‪ ،‬ﻳﻜﻲ از ﭘﺮﻫﺰﻳﻨﻪ ﺗﺮﻳﻦ ﻣﻮارد در ﻳﻚ ﺳﻴﺴﺘﻢ ﺗﺠﺎري‪ ،‬ﺑﺮﻗﺮاري ﻳﻜﭙﺎرﭼﮕﻲ ﺑﻴﻦ ﻧﺮم اﻓﺰارﻫﺎي ﺗﺠﺎري ﻣﻮﺟـﻮد اﺳـﺖ‪.‬‬ ‫ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﺷﺮﻛﺖ ﺗﺠﺎري ﺷﻤﺎ داراي ﻧﺮم اﻓﺰاري ﺑﺮاي ﻛﻨﺘﺮل ﻣﻮﺟﻮدي ﻛﺎﻻﻫﺎ در اﻧﺒﺎر و ﻧﺮم اﻓﺰار دﻳﮕﺮي ﺑﺮاي درﻳﺎﻓﺖ‬

‫‪٨١٣‬‬

‫ﺳﻔﺎرﺷﺎت ﻣﺨﺘﻠﻒ از ﻣﺸﺘﺮﻳﺎن اﺳﺖ‪ .‬اﻳﻦ دو ﻧﺮم اﻓﺰار از دو ﺷﺮﻛﺖ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺨﺘﻠﻒ در دو زﻣﺎن ﺟﺪا از ﻫﻢ ﺧﺮﻳـﺪاري ﺷـﺪه اﻧـﺪ و‬ ‫ﻫﺮ ﻛﺪام از آﻧﻬﺎ ﻧﻴﺰ ﺑﺮ روي ﻳﻚ ﭘﻠﺖ ﻓﺮم ﺧﺎص ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ‪ .‬اﻣﺎ زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﺳﻔﺎرش ﺑﻪ وﺳﻴﻠﻪ ي ﻳﻚ ﺧﺮﻳـﺪار در ﻧـﺮم اﻓـﺰار دوم‬ ‫ﺛﺒﺖ ﻣﻲ ﺷﻮد‪ ،‬اﻳﻦ ﻧﺮم اﻓﺰار ﺑﺎﻳﺪ ﺑﻪ ﻧﺮم اﻓﺰاري ﻛﻪ ﻣﺴﺌﻮل ﻛﻨﺘﺮل ﻣﻮﺟﻮدي اﻧﺒﺎر اﺳﺖ اﻃﻼع دﻫﺪ ﻛﻪ ﭼﻪ ﻣﻘﺪار و از ﭼﻪ ﻛﺎﻻﻳﻲ ﻓﺮوﺧﺘﻪ‬ ‫ﺷﺪه اﺳﺖ‪ .‬ﺳﭙﺲ ﻧﺮم اﻓﺰار اول ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺮ اﺳﺎس اﻳﻦ اﻃﻼﻋﺎت ﻛﺎرﻫﺎي ﺧﺎﺻﻲ را ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻧﺠﺎم دﻫﺪ‪ .‬ﺑـﺮاي ﻣﺜـﺎل در‬ ‫ﺻﻮرﺗﻲ ﻛﻪ ﻣﻮﺟﻮدي آن ﻛﺎﻻ ﻛﺎﻫﺶ زﻳﺎدي ﭘﻴﺪا ﻛﺮده ﺑﻮد‪ ،‬ﻣﺠﺪداً از آن ﻛﺎﻻ ﺳﻔﺎرش دﻫﺪ و ﻳﺎ ﺑﻪ ﻓﺮد ﺧﺎﺻﻲ اﻃﻼع دﻫﺪ ﻛـﻪ ﻛـﺎﻻي‬ ‫ﻓﺮوﺧﺘﻪ ﺷﺪه را ﺑﻪ آدرس ﺧﺮﻳﺪار ارﺳﺎل ﻛﻨﺪ‪.‬‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ اﻳﻦ دو ﻧﺮم اﻓﺰار ﺑﻪ اﻳﻦ ﺻﻮرت ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﻛﺎر ﻛﻨﻨﺪ و ﺗﻌﺎﻣﻞ داﺷﺘﻪ ﺑﺎﺷﻨﺪ‪ ،‬ﻣﻲ ﮔﻮﻳﻴﻢ ﻛﻪ اﻳﻦ دو ﻧﺮم اﻓﺰار ﻳﻜﭙﺎرﭼﻪ ﺷﺪه اﻧﺪ‪.‬‬ ‫ﻳﻜﭙﺎرﭼﻪ ﺳﺎزي ﺑﻪ ﻧﺪرت ﺑﻪ ﺳﺎدﮔﻲ اﻧﺠﺎم ﻣﻲ ﺷﻮد و ﻣﺨﺼﻮﺻﺎ در ﻣﻮرد ﺷﺮﻛﺘﻬﺎي ﺑﺰرگ ﻧﻴﺎز اﺳﺖ ﻛﻪ ﺗﻴﻤﻲ از ﻣﺸﺎوران و ﻣﺘﺨﺼـﺼﺎن‬ ‫اﺳﺘﺨﺪام ﺷﻮﻧﺪ و ﺑﻌﺪ از ﺻﺮف ﭼﻨﺪﻳﻦ ﻫﺰار دﻻر‪ ،‬ﻧﺮم اﻓﺰاري ﺑﺮاي ﺑﺮﻗﺮاري ﻳﻜﭙﺎرﭼﮕﻲ ﺑﻴﻦ ﻧﺮم اﻓﺰارﻫﺎ ﻧﻮﺷﺘﻪ ﺷﻮد‪.‬‬ ‫ﺣﺎل اﮔﺮ ﻧﺨﻮاﻫﻴﻢ زﻳﺎد وارد ﺟﺰﺋﻴﺎت اﻳﻦ ﺣﺎﻟﺘﻬﺎ ﺷﻮﻳﻢ‪ ،‬وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﻳﻜﭙﺎرﭼﮕﻲ ﺑﺴﻴﺎر ﺑﺴﻴﺎر ﺳﺎده ﺗﺮ اﻧﺠﺎم ﺷﻮد و‬ ‫ﺑﻨﺎﺑﺮاﻳﻦ ﻫﺰﻳﻨﻪ اي ﻛﻪ ﺑﺮاي اﻳﻦ ﻛﺎر ﺻﺮف ﻣﻲ ﺷﻮد ﻧﻴﺰ ﺑﺴﻴﺎر ﺑﺴﻴﺎر ﻛﻤﺘﺮ از ﻗﺒﻞ ﺧﻮاﻫﺪ ﺑﻮد‪ .‬ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ اﺳﺖ ﻛﻪ ﭘـﻴﺶ ﺑﻴﻨـﻲ ﻣـﻲ‬ ‫ﻛﻨﻨﺪ وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﺰرﮔﺘﺮﻳﻦ ﺗﺤﻮل اﻳﻨﺘﺮﻧﺘﻲ در ﻣﺪت اﺧﻴﺮ ﺧﻮاﻫﺪ ﺑﻮد‪ .‬ﺑﺎ اﺳﺘﻔﺎده از وب ﺳﺮوﻳﺲ ﻫـﺎ ﻧـﻪ ﺗﻨﻬـﺎ ﺷـﺮﻛﺘﻬﺎﻳﻲ ﻛـﻪ ﻣـﻲ‬ ‫ﺧﻮاﻫﻨﺪ در ﻧﺮم اﻓﺰارﻫﺎي ﺧﻮد ﻳﻜﭙﺎرﭼﮕﻲ اﻳﺠﺎد ﻛﻨﻨﺪ راﻫﻬﺎي ﺑﺴﻴﺎر ﺳﺎده ﺗﺮ و ارزان ﺗﺮي را در اﺧﺘﻴﺎر ﺧﻮاﻫﻨﺪ داﺷﺖ‪ ،‬ﺑﻠﻜﻪ ﻧﺮم اﻓﺰارﻫﺎي‬ ‫ﻣﻮﺟﻮد در ﺷﺮﻛﺘﻬﺎي ﺗﺠﺎري ﻛﻮﭼﻚ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ ﺳﺎدﮔﻲ ﺑﺎ ﻳﻜﺪﻳﮕﺮ راﺑﻄﻪ داﺷﺘﻪ ﺑﺎﺷﻨﺪ‪.‬‬ ‫ﺗﻮﺿﻴﺢ در ﻣﻮرد ﻣﺰاﻳﺎ و ﻣﻌﺎﻳﺐ وب ﺳﺮوﻳﺲ ﻫﺎ و ﻧﻴﺰ ﺻﺤﺒﺖ درﺑﺎره ي اﻓﺮادي ﻛﻪ اﻳﻦ ﺗﻜﻨﻮﻟﻮژي را ﮔﺴﺘﺮش ﻣﻲ دﻫﻨﺪ از اﻫـﺪاف اﻳـﻦ‬ ‫ﻛﺘﺎب ﺧﺎرج اﺳﺖ‪ .‬اﻣﺎ ﺑﺮاي اﻃﻼﻋﺎت ﺑﻴﺸﺘﺮ در اﻳﻦ زﻣﻴﻨﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ آدرس‬ ‫‪http://msdn.microsoft.com/webservices‬‬ ‫ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ‪.‬‬

‫ﻧﺤﻮه ي ﻋﻤﻠﻜﺮد وب ﺳﺮوﻳﺲ ﻫﺎ‪:‬‬ ‫اول از ﻫﻤﻪ ﺑﺎﻳﺪ ﺑﮕﻮﻳﻢ ﻛﻪ اﺳﺎس وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﻪ ﻃﻮر ﻛﻠﻲ روي اﺳﺘﺎﻧﺪاردﻫﺎي آزاد اﺳﺖ و ﺑﻪ ﻫﻴﭻ ﭘﻠﺖ ﻓﺮم و ﻳـﺎ ﺷـﺮﻛﺖ ﺧﺎﺻـﻲ‬ ‫ﺗﻌﻠﻖ ﻧﺪارد‪ .‬ﻳﻜﻲ از ﺟﺬاﺑﻴﺖ ﻫﺎ و دﻻﻳﻞ ﻣﻮﻓﻘﻴﺖ وب ﺳﺮوﻳﺲ ﻫﺎ ﻧﻴﺰ در اﻳﻦ ﻣﻮرد اﺳﺖ ﻛﻪ ﺗﻔﺎوﺗﻲ ﻧﻤﻲ ﻛﻨﺪ ﻛﻪ ﺷﻤﺎ وب ﺳﺮوﻳﺲ ﺧﻮد‬ ‫را روي ﭼﻪ ﭘﻠﺖ ﻓﺮﻣﻲ اراﺋﻪ ﻣﻲ ﻛﻨﻴﺪ‪ ،‬وﻳﻨﺪوز‪ ،‬ﻣﻜﻴﻨﺘﺎش‪ ،‬ﻟﻴﻨﻮﻛﺲ‪ ،‬ﺳﻮﻻرﻳﺲ‪ ،‬ﻳﻮﻧﻴﻜﺲ و … در ﻫﺮ ﺣﺎﻟﺖ ﻫﻤﻪ ي اﻓﺮاد ﻣـﻲ ﺗﻮاﻧﻨـﺪ ﺑـﻪ‬ ‫ﺳﺮور ﺷﻤﺎ ﻣﺘﺼﻞ ﺷﺪه و از وب ﺳﺮوﻳﺴﻲ ﻛﻪ اراﺋﻪ ﻣﻲ دﻫﻴﺪ اﺳﺘﻔﺎده ﻛﻨﻨﺪ‪ .‬اﻳـﻦ ﻣـﻮرد دﻗﻴﻘـﺎً ﻣـﺸﺎﺑﻪ ﻋﻤﻠﻜـﺮد ﺳـﺎﻳﺘﻬﺎي وب اﺳـﺖ‪ .‬در‬ ‫ﺳﺎﻳﺘﻬﺎي وب ﻧﻴﺰ ﺗﻔﺎوﺗﻲ ﻧﺪارد ﻛﻪ ﺳﺮوري ﻛﻪ اﻳﻦ ﺳﺎﻳﺖ روي آن ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ و ﻳﺎ ﭘﻠﺖ ﻓﺮﻣﻲ ﻛﻪ ﺑـﻪ وﺳـﻴﻠﻪ ي آن ﻧﻮﺷـﺘﻪ ﺷـﺪه‬ ‫اﺳﺖ ﭼﻴﺴﺖ و ﻳﺎ ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ‪ .‬در ﻫﺮ ﺻﻮرت ﺷﻤﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺳﺎدﮔﻲ ﺑﻪ آن ﺳﺎﻳﺖ ﻣﺘﺼﻞ ﺷﺪه و از اﻃﻼﻋﺎت آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬ ‫دوﻣﻴﻦ ﻧﻜﺘﻪ اي ﻛﻪ ﺑﺎﻳﺪ ﺑﺪاﻧﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ وب ﺳﺮوﻳﺴﻲ ﻛﻪ در ‪ .NET‬اﺳﺘﻔﺎده ﺷﺪه و ﺑﻪ ﻛﺎر ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮد ﺗﻤﺎﻣﺎ ﺑﺮ اﺳـﺎس ﻣـﺪل‬ ‫ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﺳﺖ ﻛﻪ اﻏﻠﺐ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﺑﻪ اﺳﺘﻔﺎده از آن ﻋﻼﻗﻪ ي زﻳﺎدي دارﻧﺪ‪ :‬ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺷﻴﺊ ﮔـﺮا‪ .‬اﮔـﺮ ﺷـﻤﺎ ﻧﻴـﺰ در اﻏﻠـﺐ‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد از اﺷﻴﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ )ﻛﻪ اﻟﺒﺘﻪ ﺗﺎ ﻓﺼﻞ ﺑﻴﺴﺘﻢ اﻳﻦ ﻛﺘﺎب‪ ،‬دﻳﮕﺮ ﺑﺎﻳﺪ ﺑﺘﻮاﻧﻴﺪ اﻳﻦ ﻛﺎر را اﻧﺠﺎم دﻫﻴﺪ( در ‪ .NET‬ﻧﻴﺰ‬ ‫ﺑﻪ ﺳﺎدﮔﻲ ﻣﻲ ﺗﻮاﻧﻴﺪ وب ﺳﺮوﻳﺲ ﻫﺎ را ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار دﻫﻴﺪ‪.‬‬ ‫اﺻﻠﻲ ﻛﻪ ﺑﺮاي اﻳﺠﺎد ﻳﻚ وب ﺳﺮوﻳﺲ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد ﺑﻪ اﻳﻦ ﺻﻮرت اﺳﺖ ﻛﻪ ﻳﻚ ﻛـﻼس اﻳﺠـﺎد ﻣـﻲ ﻛﻨﻴـﺪ ﻛـﻪ داراي‬ ‫ﻣﺘﺪﻫﺎي ﻣﺨﺘﻠﻔﻲ اﺳﺖ‪ .‬اﻟﺒﺘﻪ ﻧﺤﻮه ي ﺗﻮزﻳﻊ و اﺳﺘﻔﺎده از اﻳﻦ ﻛﻼس ﻣﺎﻧﻨﺪ ﻛﻼﺳﻬﺎي ﻗﺒﻠﻲ ﻧﻴﺴﺖ و ﺗﻔـﺎوت دارد‪ .‬در راﺑﻄـﻪ ﺑـﺎ ﻛـﻼس‬ ‫ﻫﺎﻳﻲ ﻛﻪ ﺗﺎ اﻳﻨﺠﺎ اﻳﺠﺎد ﻛﺮده اﻳﻢ‪ ،‬ﻧﺤﻮه ي اﺳﺘﻔﺎده از ﻳﻚ ﻛﻼس ﺑﻪ ﺻﻮرت زﻳﺮ ﺑﻮد‪:‬‬ ‫‬ ‫‬

‫ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ‪ ،‬ﻳﻚ ﻛﻼس را اﻳﺠﺎد ﻣﻲ ﻛﺮد‪.‬‬ ‫اﻳﻦ ﻛﻼس در ﺟﺎﻳﻲ ﻧﺼﺐ ﻣﻲ ﺷﺪ )در ﻛﺎﻣﭙﻴﻮﺗﺮي ﻛﻪ ﻣﻲ ﺧﻮاﺳﺖ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد ﻛﭙﻲ ﻣﻲ ﺷﺪ(‪.‬‬

‫‪٨١٤‬‬

‫‬ ‫‬ ‫‬ ‫‬

‫ﻗﺴﻤﺘﻲ از ﻳﻚ ﻧﺮم اﻓﺰار در ﻫﻤﺎن ﻛﺎﻣﭙﻴﻮﺗﺮ ﻛﻪ ﻣﻲ ﺧﻮاﺳﺖ از اﻳﻦ ﻛﻼس اﺳﺘﻔﺎده ﻛﻨﺪ‪ ،‬ﻳﻚ ﻧﻤﻮﻧﻪ از اﻳـﻦ ﻛـﻼس را اﻳﺠـﺎد‬ ‫ﻣﻲ ﻛﺮد )ﻳﻚ "ﺷﻴﺊ" اﻳﺠﺎد ﻣﻲ ﻛﺮد(‪.‬‬ ‫آن ﻗﺴﻤﺖ از ﻧﺮم اﻓﺰار ﻛﻪ اﻳﻦ ﺷﻴﺊ را اﻳﺠﺎد ﻛﺮده ﺑﻮد‪ ،‬ﻣﺘﺪ ﻣﻮرد ﻧﻈﺮ ﺧﻮد را از اﻳﻦ ﻛﻼس ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﺮد‪.‬‬ ‫آن ﻣﺘﺪ از ﺷﻴﺊ‪ ،‬ﻛﺎرﻫﺎي ﺧﺎﺻﻲ را اﻧﺠﺎم ﻣﻲ داد و ﻣﻘﺪاري را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﻣﻲ ﮔﺮداﻧﺪ‪.‬‬ ‫آن ﻗﺴﻤﺖ از ﻧﺮم اﻓﺰار ﻛﻪ ﻣﺘﺪ را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده ﺑﻮد‪ ،‬ﻧﺘﻴﺠﻪ را درﻳﺎﻓﺖ ﻛﺮده و از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﺮد‪.‬‬

‫اﻣﺎ در وب ﺳﺮوﻳﺲ ﻫﺎ ﻳﻚ ﻛﻼس ﺑﻪ ﺻﻮرت زﻳﺮ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد‪:‬‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬

‫ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻳﻚ ﻛﻼس را اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫آن ﻛﻼس روي ﻳﻚ ﺳﺮور ﻛﻪ داراي ﻳﻚ وب ﺳﺮور ﻣﺎﻧﻨﺪ ‪ IIS‬و ﻳﺎ ﻫﺮ وب ﺳﺮور دﻳﮕﺮي اﺳﺖ ﻛﭙﻲ ﻣﻲ ﺷﻮد‪.‬‬ ‫ﻗﺴﻤﺘﻲ از ﻳﻚ ﻧﺮم اﻓﺰار ﻛﻪ در ﻳﻚ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﺘﻔﺎوت و ﺑﺎ ﻓﺎﺻﻠﻪ از ﻛﺎﻣﭙﻴﻮﺗﺮي ﻛﻪ ﻛﻼس در آن ﻗﺮار دارد‪) ،‬ﻣﻌﻤﻮﻻ در ﺟﺎﻳﻲ‬ ‫در اﻳﻨﺘﺮﻧﺖ( از وب ﺳﺮور ﻣﻲ ﺧﻮاﻫﺪ ﻛﻪ ﻳﻜﻲ از ﻣﺘﺪﻫﺎي ﻣﻮﺟﻮد در ﻛﻼس را اﺟﺮا ﻛﻨﺪ‪.‬‬ ‫ﺳﺮور ﻳﻚ ﻧﻤﻮﻧﻪ از ﻛﻼس )ﻳﻚ ﺷﻴﺊ( را اﻳﺠﺎد ﻛﺮده و ﻣﺘﺪ درﺧﻮاﺳﺖ ﺷﺪه را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﺳﺮور ﻧﺘﻴﺠﻪ ي اﺟﺮاي ﻣﺘﺪ را ﺑﻪ ﻛﺎﻣﭙﻴﻮﺗﺮي ﻛﻪ آن را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده ﺑﻮد ﺑﺮﻣﻲ ﮔﺮداﻧﺪ‪.‬‬ ‫آن ﻗﺴﻤﺖ از ﻧﺮم اﻓﺰار در ﻛﺎﻣﭙﻴﻮﺗﺮ دوردﺳﺖ ﻛﻪ درﺧﻮاﺳﺖ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ را اﻳﺠﺎد ﻛﺮده ﺑﻮد‪ ،‬ﻧﺘﻴﺠﻪ را درﻳﺎﻓﺖ ﻛـﺮده و از آن‬ ‫اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ‪.‬‬

‫ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ روش ﻛﺎر در ﻫﺮ دو ﻣﻮرد ﻣﺸﺎﺑﻪ اﺳﺖ‪ ،‬اﻣﺎ در ﻣﻮرد دوم ﻳﻚ ﮔﺴﺴﺘﮕﻲ ﺑﻴﻦ ﻛﺎﻣﭙﻴﻮﺗﺮي ﻛﻪ ﻛﻼس ﺑﻪ ﻃـﻮر واﻗﻌـﻲ‬ ‫در آن ﻗﺮار دارد و ﻛﺎﻣﭙﻴﻮﺗﺮي ﻛﻪ ﻣﻲ ﺧﻮاﻫﺪ از ﻛﻼس اﺳﺘﻔﺎده ﻛﻨﺪ وﺟﻮد دارد‪ .‬در ﺣﻘﻴﻘﺖ ﺑﺎ اﺳﺘﻔﺎده از وب ﺳﺮوﻳﺲ ﻫﺎ ﻳـﻚ ﻓﺎﺻـﻠﻪ ي‬ ‫ﭘﺮدازﺷﻲ زﻳﺎدي )ﺑﻪ اﻧﺪازه ي وﺳﻌﺖ اﻳﻨﺘﺮﻧﺖ(‪ ،‬ﺑﻴﻦ ﻧﺮم اﻓﺰاري ﻛﻪ ﻣﻲ ﺧﻮاﻫﺪ از ﻛﻼس اﺳﺘﻔﺎده ﻛﻨﺪ و ﺧﻮد ﻛﻼس ﺑﻪ وﺟـﻮد ﻣـﻲ آﻳـﺪ‪.‬‬ ‫ﺑﺮاي ﺣﻞ ﻣﺸﻜﻞ اﻳﻦ ﮔﺴﺴﺘﮕﻲ و ﻛﻨﺘﺮل ﻓﺎﺻﻠﻪ اي ﻛﻪ در اﻳﻨﺠﺎ وﺟﻮد دارد‪ ،‬از ﺗﻜﻨﻮﻟﻮژﻳﻬﺎ و اﺳﺘﺎﻧﺪارد ﻫـﺎﻳﻲ ﻛـﻪ در وب ﺳـﺮوﻳﺲ ﻫـﺎ‬ ‫ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ )و ﻳﺎ ﺣﺘﻲ در اﺻﻞ ﺑﺮاي اﺳﺘﻔﺎده ﺑﻪ وﺳﻴﻠﻪ ي وب ﺳﺮوﻳﺲ ﻫﺎ اﻳﺠﺎد ﺷﺪه اﻧﺪ( اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ‪.‬‬

‫‪:SOAP‬‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ در اﺑﺘﺪاي ﻓﺼﻞ ﮔﻔﺘﻢ "وب ﺳﺮوﻳﺲ ﻫﺎ در ﺣﻘﻴﻘﺖ وب ﺳﺎﻳﺘﻬﺎﻳﻲ ﺑﺮاي اﺳﺘﻔﺎده ﺑﻪ وﺳﻴﻠﻪ ي ﻧﺮم اﻓﺰارﻫﺎ ﻫﺴﺘﻨﺪ"‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ‬ ‫از ﻫﻤﺎن ﺗﻜﻨﻮﻟﻮژي اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ ﺑﺎﻋﺚ ﺷﺪه اﺳﺖ ﺳﺎﻳﺘﻬﺎي وب ﺗﺎ اﻳﻦ ﺣﺪ ﻋﻤﻮﻣﻲ ﺷـﻮﻧﺪ‪ .‬وب ﺳـﺮوﻳﺲ ﻫـﺎ ﻧﻴـﺰ ﻣﺎﻧﻨـﺪ وب از‬ ‫اﺳﺘﺎﻧﺪارد ‪ HTTP1‬اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ ﺗﻮﺳﻂ ﻫﻤﻪ ي ﺳﺮورﻫﺎي وب ﺑﻪ ﻛﺎر ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ‪.‬‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺎ "اﻳﺠﺎد ﺳﺎﻳﺘﻬﺎﻳﻲ ﺑﺮاي اﻧﺴﺎﻧﻬﺎ" ﺳﺮوﻛﺎر دارﻳﻢ‪ ،‬ﻣﻌﻤﻮﻻ ﻛﻼﻳﻨﺖ )ﻣﺮورﮔﺮ( و ﺳﺮور ﻓﺎﻳﻠﻬﺎي ﻣﺨﺘﻠﻔﻲ را ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﻣﺒﺎدﻟـﻪ‬ ‫ﻣﻲ ﻛﻨﻨﺪ‪ :‬ﻓﺎﻳﻠﻬﺎﻳﻲ ﻣﺘﻨﻲ ﺣﺎوي ﻛﺪ ‪ JavaScript ،DHTML ،HTML‬و … ﻛﻪ ﻇﺎﻫﺮ و ﻣﺘﻨﻬﺎي ﻣﻮﺟﻮد در ﺻﻔﺤﻪ را ﺷـﺎﻣﻞ‬ ‫ﻣﻲ ﺷﻮﻧﺪ‪ ،‬ﻓﺎﻳﻠﻬﺎي ﺗﺼﻮﻳﺮ و ﻳﺎ ﺻﺪا ﺑﺎ ﻓﺮﻣﺖ ﻫﺎي ‪ GIF ،JPEG‬و ﻳﺎ … ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﺻﻔﺤﻪ ﻣﻮرد اﺳـﺘﻔﺎده ﻗـﺮار ﻣـﻲ‬ ‫ﮔﻴﺮد و ﻏﻴﺮه‪.‬‬ ‫اﻣﺎ زﻣﺎﻧﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺑﺮاي ﻧﺮم اﻓﺰارﻫﺎ و ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﺎﻣﭙﻴﻮﺗﺮي ﺳﺎﻳﺘﻲ را اﻳﺠﺎد ﻛﻨﻴﺪ‪ ،‬ﻓﻘﻂ ﺑﺎ ﻳﻚ ﻧﻮع ﻓﺎﻳـﻞ در ارﺗﺒـﺎط ﻫـﺴﺘﻴﺪ‪ .‬اﻳـﻦ‬ ‫ﻓﺎﻳﻠﻬﺎ ﺑﻪ ﻧﺎم ﻓﺎﻳﻠﻬﺎي ‪ SOAP‬ﻣﻌﺮوف ﻫﺴﺘﻨﺪ‪.‬‬

‫‪Hyper Text Markup Language‬‬

‫‪1‬‬

‫‪٨١٥‬‬

‫ﻧﻜﺘﻪ‪ SOAP :‬در اﺻﻞ ﺳﺮ ﻧﺎم ﻛﻠﻤﺎت ‪ Simple Object Access Protocol‬اﺳﺖ‪ ،‬اﻣﺎ اﺳـﺘﺎﻧﺪارد ﻛﻨـﻮﻧﻲ‬ ‫ﻛﻪ در ‪ W3C‬وﺟﻮد دارد اﻳﻦ اﺻﻄﻼح را ﺣﺬف ﻛﺮده اﺳﺖ‪.‬‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺨﻮاﻫﺪ از ﻳﻚ ﺳﺮوﻳﺲ وب ﺗﻘﺎﺿﺎي درﻳﺎﻓﺖ اﻃﻼﻋﺎﺗﻲ را ﺑﻜﻨﺪ‪ ،‬ﺑﺮاي ﻣﺜﺎل ﺑﺨﻮاﻫﺪ ﻣﻮﺟﻮدي ﻳﻚ ﻛﺎﻻ در اﻧﺒﺎر‬ ‫را ﺑﺪاﻧﺪ‪ ،‬ﻳﺎ ﺑﺨﻮاﻫﺪ وﺿﻌﻴﺖ ﻛﻨﻮﻧﻲ ﻳﻚ ﺳﻔﺎرش را درﻳﺎﻓﺖ ﻛﻨﺪ‪ ،‬و ﻳﺎ از ﻛﺎﻣﭙﻴﻮﺗﺮ ﺳﺮور ﺑﺨﻮاﻫﺪ ﺗﺎ ﻛﺎر ﺧﺎﺻﻲ را ﻣﺜﻞ ﻳـﻚ ﺗﺒـﺪﻳﻞ واﺣـﺪ‬ ‫ﺑﺮاي او اﻧﺠﺎم دﻫﺪ‪ ،‬ﺑﺮﻧﺎﻣﻪ ﻳﻚ ﻓﺎﻳﻞ درﺧﻮاﺳﺖ ﺑﺎ ﻗﺎﻟﺐ ‪ SOAP‬اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ‪ .‬ﺳﭙﺲ اﻳﻦ ﻓﺎﻳـﻞ ﺑـﺎ اﺳـﺘﻔﺎده از ‪ HTTP‬و از ﻃﺮﻳـﻖ‬ ‫اﻳﻨﺘﺮﻧﺖ ﺑﻪ ﺳﺮوري ﻛﻪ وب ﺳﺮوﻳﺲ در آن ﻗﺮار دارد ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد‪ .‬اﻳﻦ ﻓﺎﻳﻞ ﺣﺎوي ﺗﻤﺎم اﻃﻼﻋﺎﺗﻲ اﺳﺖ ﻛﻪ وب ﺳﺮوﻳﺲ ﻧﻴﺎز دارد‬ ‫ﺗﺎ ﺑﺪاﻧﺪ ﭼﻪ ﻛﺎري از او ﺧﻮاﺳﺘﻪ ﺷﺪه اﺳﺖ‪ .‬ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ اﻳﻨﻜﻪ وب ﺳﺮوﻳﺲ ﻫﺎ ﻣﺎﻧﻨﺪ روش ﻛﻼس‪/‬ﻣﺘﺪ ﻣﻌﻤﻮﻟﻲ ﻛﺎر ﻣﻲ ﻛﻨﻨـﺪ‪ ،‬اﻳـﻦ ﻓﺎﻳـﻞ‬ ‫‪ SOAP‬ﻣﻌﻤﻮﻻ ﺣﺎوي ﻧﺎم ﻣﺘﺪي اﺳﺖ ﻛﻪ ﺑﺎﻳﺪ اﺟﺮا ﺷﻮد و ﻧﻴﺰ ﭘﺎراﻣﺘﺮﻫﺎﻳﻲ ﻛﻪ اﻳﻦ ﻣﺘﺪ ﺑﻪ ﻋﻨﻮان ورودي ﺑﺎﻳﺪ درﻳﺎﻓﺖ ﻛﻨﺪ‪.‬‬ ‫در ﺳﻤﺖ ﺳﺮور‪ ،‬اﻳﻦ ﺗﻘﺎﺿﺎ ﺑﻪ وﺳﻴﻠﻪ ي وب ﺳﺮوﻳﺲ درﻳﺎﻓﺖ ﺷﺪه و ﺑﻌﺪ از اﻳﻨﻜﻪ در ﺧﻮاﺳﺖ ﻛﺎرﺑﺮ از آن اﺳﺘﺨﺮاج ﺷﺪ‪ ،‬ﻣﺘﺪ ﻣـﻮرد ﻧﻈـﺮ‬ ‫ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد )در اداﻣﻪ ي ﻓﺼﻞ ﭼﻨﻴﻦ ﻛﻼس ﻫﺎﻳﻲ را اﻳﺠﺎد ﻛﺮده و از آﻧﻬﺎ در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ(‪ .‬ﺑﻌﺪ از اﻳﻨﻜـﻪ ﻣﺘـﺪ ﻣـﻮرد‬ ‫ﻧﻈﺮ اﺟﺮا ﺷﺪه و ﻧﺘﻴﺠﻪ آﻣﺎده ﺷﺪ‪ ،‬وب ﺳﺮوﻳﺲ ﻳﻚ ﻓﺎﻳﻞ ‪ SOAP‬اﻳﺠﺎد ﻛﺮده و ﻧﺘﻴﺠﻪ ي درﺧﻮاﺳﺖ ﺑﺮﻧﺎﻣﻪ را در آن ﻗﺮار ﻣـﻲ دﻫـﺪ و‬ ‫ﺑﻪ ﺳﻤﺖ ﻛﺎﻣﭙﻴﻮﺗﺮ درﺧﻮاﺳﺖ ﻛﻨﻨﺪه ارﺳﺎل ﻣﻲ ﻛﻨﺪ‪ .‬ﻫﻤﺎﻧﻨﺪ ﻓﺎﻳﻠﻲ ﻛﻪ ﺣﺎوي ﺗﻘﺎﺿﺎ ﺑﻮد‪ ،‬اﻳﻦ ﻓﺎﻳﻞ ﻧﻴﺰ ﻛﻪ ﻧﺘﻴﺠﻪ را ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨـﺪ ﺑـﺎ‬ ‫اﺳﺘﻔﺎده از ‪ HTTP‬و ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻨﺘﺮﻧﺖ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي اول ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد‪.‬‬ ‫اﺳﻨﺎد و ﻓﺎﻳﻠﻬﺎي ‪ SOAP‬ﺑﺎ اﺳﺘﻔﺎده از ‪ XML‬اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ‪ .‬ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻓﺎﻳﻠﻬﺎي ‪SOAP‬اي ﻛﻪ ﺑﺮاي اﻳﻦ ﻣﻨﻈﻮر ﻣﻮرد اﺳﺘﻔﺎده‬ ‫ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ ﺑﺴﻴﺎر ﺷﺒﻴﻪ ﻓﺎﻳﻠﻬﺎي ‪ XML‬اي ﻫﺴﺘﻨﺪ ﻛﻪ در ﻓﺼﻞ ﻗﺒﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ‪ .‬اﻟﺒﺘـﻪ در اﻳـﻦ ﺳـﻄﺢ ﻛـﻪ در اﻳـﻦ ﻛﺘـﺎب وب‬ ‫ﺳﺮوﻳﺲ ﻫﺎ را ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﻴﻢ‪ ،‬ﻧﻴﺎزي ﺑﻪ ﻣﺸﺎﻫﺪه ي ﻓﺎﻳﻠﻬﺎي ‪ SOAP‬ﻧﺨﻮاﻫﻴﻢ داﺷﺖ‪ .‬ﺑﺎ وﺟﻮد اﻳﻦ در ﻃﻲ اﻳﻦ ﻓـﺼﻞ ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ‬ ‫ﺑﺨﻮاﻫﻴﻢ از وب ﺳﺮوﻳﺲ ﻫﺎ اﺳﺘﻔﺎده ﻛﺮده و ﻧﺘﺎﻳﺠﻲ را از آﻧﻬﺎ درﻳﺎﻓﺖ ﻛﻨﻴﻢ‪ ،‬ﻧﻤﻮﻧﻪ ﻫﺎﻳﻲ از ‪ SOAP‬را ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﺳﺮور ﺑﺮﮔـﺸﺖ‬ ‫داده ﻣﻲ ﺷﻮد ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد‪ ،‬اﻣﺎ ﻛﺎري ﺑﺎ ﻓﺎﻳﻠﻬﺎي ‪ SOAP‬ﺣﺎوي ﺗﻘﺎﺿﺎ ﻫﺎ ﻧﺨﻮاﻫﻴﻢ داﺷﺖ‪.‬‬ ‫ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ اﻳﻨﻜﻪ اﺳﺘﻔﺎده از وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﻪ ﭘﻠﺖ ﻓﺮم ﺧﺎﺻﻲ واﺑﺴﺘﻪ ﻧﻴﺴﺖ و ﻫﺮ ﻧﺮم اﻓﺰاري ﻛﻪ در ﻫﺮ ﭘﻠﺖ ﻓﺮﻣﻲ ﻃﺮاﺣﻲ ﺷﺪه ﺑﺎﺷﺪ‬ ‫ﻣﻲ ﺗﻮاﻧﺪ از ﻫﺮ وب ﺳﺮوﻳﺲ ﻛﻪ ﺑﻪ ﻫﺮ ﻧﺤﻮي اﻳﺠﺎد ﺷﺪه ﺑﺎﺷﺪ اﺳﺘﻔﺎده ﻛﻨﺪ‪ ،‬ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﻣﻌﻤﻮﻻ ﺑﺮاي اﻧﺘﺨﺎب ﻳﻚ ﭘﻠﺖ ﻓﺮم ﺑـﻪ اﻳـﻦ‬ ‫ﻧﻜﺘﻪ دﻗﺖ ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ در ﻫﺮ ﭘﻠﺖ ﻓﺮم ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻓﺎﻳﻠﻬﺎي ‪ SOAP‬ﻣﺮﺑﻮط ﺑﻪ اﺳﺘﻔﺎده از ﻳﻚ وب ﺳﺮوﻳﺲ را اﻳﺠﺎد ﻛﺮد و ﻳـﺎ از‬ ‫ﻓﺎﻳﻠﻬﺎي ﺣﺎوي ﻧﺘﻴﺠﻪ اﺳﺘﻔﺎده ﻛﺮد‪ ،‬و ﻳﺎ اﻳﻦ ﻧﻜﺘﻪ را در ﻧﻈﺮ ﻣﻲ ﮔﻴﺮﻧﺪ ﻛﻪ در ﻫﺮ ﭘﻠﺖ ﻓﺮم ﭼﻪ اﺑﺰارﻫﺎﻳﻲ ﺑﺮاي ﻃﺮاﺣﻲ وب ﺳﺮوﻳﺲ ﻣﻮرد‬ ‫ﻧﻈﺮﺷﺎن وﺟﻮد دارد‪ .NET .‬در ﻫﺮ دو زﻣﻴﻨﻪ ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﺳﺎدﮔﻲ و ﻗﺪرت را ﺑﺮاي ﻃﺮاﺣﻲ و ﻳﺎ اﺳﺘﻔﺎده از ﻳـﻚ وب ﺳـﺮوﻳﺲ ﻓـﺮاﻫﻢ‬ ‫ﻛﺮده اﺳﺖ؛ ﺑﺎ اﺳﺘﻔﺎده از ‪ .NET‬ﻣﻲ ﺗﻮان ﺑﺪون اﻳﻨﻜﻪ درﮔﻴﺮ ﻓﺎﻳﻠﻬﺎي ‪ SOAP‬ﺷﺪ از وب ﺳﺮوﻳﺲ ﻫﺎ اﺳﺘﻔﺎده ﻛﺮد و آﻧﻬﺎ را در ﺑﺮﻧﺎﻣﻪ‬ ‫ﺑﻪ ﻛﺎر ﺑﺮد )ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ اﺳﺖ ﻛﻪ در اﻳﻦ ﻓﺼﻞ زﻳﺎد وارد ﺟﺰﺋﻴﺎت ‪ SOAP‬ﻧﻤﻲ ﺷـﻮﻳﻢ‪ ،‬زﻳـﺮا ﺑـﺎ وﺟـﻮد اﻳﻨﻜـﻪ ﻫـﻴﭻ ﻛـﺎري در وب‬ ‫ﺳﺮوﻳﺲ ﻫﺎ ﺑﺪون اﺳﺘﻔﺎده از ‪ SOAP‬ﻣﻤﻜﻦ ﻧﻴﺴﺖ در اﻳﻦ ﻓﺼﻞ ﺑﺪون درﮔﻴﺮ ﺷﺪن در ‪ SOAP‬ﺗﻤﺎم ﻛﺎرﻫﺎي ﻻزم را اﻧﺠـﺎم ﺧـﻮاﻫﻴﻢ‬ ‫داد(‪.‬‬ ‫ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﻪ ﻫﻴﭻ ﭘﻠﺖ ﻓﺮم ﺧﺎﺻﻲ واﺑﺴﺘﻪ ﻧﻴﺴﺘﻨﺪ‪ ،‬اﻣﺎ در اﻳﻦ ﻓﺼﻞ روي ﻧﺤﻮه ي اﻳﺠﺎد وب ﺳﺮوﻳﺲ ﻫـﺎ در ﭘﻠـﺖ‬ ‫ﻓﺮم ‪ .NET‬ﺻﺤﺒﺖ ﺧﻮاﻫﻴﻢ ﻛﺮد‪ .‬اﻟﺒﺘﻪ اﺑﺘﺪا ﺑﻬﺘﺮ اﺳﺖ ﺑﻪ ﺷﻜﻞ ‪ 1-20‬ﻧﮕﺎﻫﻲ ﺑﻴﻨﺪازﻳﺪ ﻛـﻪ ﻣﻌﻤـﺎري ﻋﻤﻠﻜـﺮد ﻳـﻚ وب ﺳـﺮوﻳﺲ را‬ ‫ﺗﻮﺿﻴﺢ ﻣﻲ دﻫﺪ‪.‬‬

‫ﺷﻜﻞ ‪1-20‬‬

‫اﻳﺠﺎد ﻳﻚ وب ﺳﺮوﻳﺲ‪:‬‬

‫‪٨١٦‬‬

‫ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻣﻤﻜﻦ اﺳﺖ وب ﺳﺮوﻳﺲ ﻫﺎ در اﺑﺘﺪا ﻣﺒﺤﺜﻲ ﭘﻴﭽﻴﺪه ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﻨﺪ‪ ،‬اﻣﺎ اﻳﺠﺎد ﻳـﻚ وب ﺳـﺮوﻳﺲ ﺑـﺎ اﺳـﺘﻔﺎده از وﻳـﮋوال‬ ‫اﺳﺘﻮدﻳﻮ ‪ 2005‬ﺑﺴﻴﺎر ﺳﺎده اﺳﺖ‪ .‬در اﻳﻦ ﻗﺴﻤﺖ ﻳﻚ وب ﺳﺮوﻳﺲ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد و ﺑﺎ ﻣﻔﺎﻫﻴﻢ ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛـﺎر ﻧﻴـﺰ ﺑﻴـﺸﺘﺮ آﺷـﻨﺎ‬ ‫ﺧﻮاﻫﻴﻢ ﺷﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺑﺮاي اﻳﻨﻜﻪ ﻳﻚ ﻣﺘﺪ را ﺑﻪ ﮔﻮﻧﻪ اي اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ ﺑﺘﻮاﻧـﺪ در ﻳـﻚ وب ﺳـﺮوﻳﺲ ﻣـﻮرد‬ ‫اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد از ﭼﻪ ﺧﺼﻴﺼﻪ ﻫﺎﻳﻲ ﺑﺎﻳﺪ اﺳﺘﻔﺎده ﻛﺮد‪ .‬ﻫﻤﭽﻨﻴﻦ ﺑﺎ روش ﺑﺮرﺳﻲ ﻋﻤﻠﻜﺮد ﻳﻚ ﻣﺘﺪ را در ﻳﻚ وب ﺳﺮوﻳﺲ ﻧﻴﺰ آﺷـﻨﺎ‬ ‫ﺧﻮاﻫﻴﻢ ﺷﺪ‪.‬‬

‫اﻳﺠﺎد ﻳﻚ وب ﺳﺮوﻳﺲ ﺳﺎده‪:‬‬ ‫ﻳﻚ وب ﺳﺮوﻳﺲ در ﺣﻘﻴﻘﺖ ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﻛﻼس اﺳﺖ ﻛﻪ در ﺳﺮور ﻗﺮار ﻣﻲ ﮔﻴﺮد‪ .‬ﺑﻌﻀﻲ از ﻣﺘﺪﻫﺎي اﻳﻦ ﻛـﻼس ﺑـﻪ ﮔﻮﻧـﻪ ي ﺧﺎﺻـﻲ‬ ‫ﺗﻌﺮﻳﻒ ﻣﻲ ﺷﻮﻧﺪ و ‪ .NET‬ﻧﻴﺰ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻨﺪ از اﻳﻦ ﻛﻼس اﺳﺘﻔﺎده ﻛﻨﻨﺪ‪ ،‬ﻓﻘﻂ اﺟﺎزه ي دﺳﺘﺮﺳﻲ ﺑﻪ اﻳﻦ ﻣﺘـﺪ ﻫـﺎ را‬ ‫ﻣﻲ دﻫﺪ‪ .‬در اوﻟﻴﻦ ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﺎ ﻧﺤﻮه ي اﻳﺠﺎد اﻳﻦ ﻣﺘﺪ ﻫﺎ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﺮ ﻓﺮدي ﻛﻪ ﺑﺨﻮاﻫـﺪ از اﻳـﻦ وب‬ ‫ﺳﺮوﻳﺲ در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد اﺳﺘﻔﺎده ﻛﻨﺪ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ آن ﻣﺘﺼﻞ ﺷﺪه و ﻣﺘﺪ ﻣﻮرد ﻧﻈﺮ ﺧﻮد را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﺪ‪ ،‬دﻗﻴﻘﺎً ﻫﻤﺎﻧﻨﺪ اﻳﻨﻜـﻪ ﻛـﻼس‬ ‫در ﻛﺎﻣﭙﻴﻮﺗﺮي ﻗﺮار دارد ﻛﻪ ﺑﺮﻧﺎﻣﻪ در آن اﺟﺮا ﺷﺪه اﺳﺖ‪ .‬ﻫﻤﭽﻨﻴﻦ ﻣﺘﺪي اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﺗﺎ ﺑـﻪ وﺳـﻴﻠﻪ ي آن ﺑﺘـﻮاﻧﻴﻢ ﻋﻤﻠﻜـﺮد وب‬ ‫ﺳﺮوﻳﺲ را در اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﺑﺮرﺳﻲ ﻛﻨﻴﻢ‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﻳﺠﺎد ﻳﻚ وب ﺳﺮوﻳﺲ ﺳﺎده‬ ‫‪ (1‬وﻳﮋوال اﺳﺘﻮدﻳﻮ را ﺑﺎز ﻛﺮده و ﮔﺰﻳﻨﻪ ي ‪ File  New Web Site‬را از ﻧﻮار ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻧﺘﺨﺎب‬ ‫ﻛﻨﻴﺪ‪.‬‬ ‫‪ (2‬در ﭘﻨﺠــﺮه ي ‪ ،New Web Site‬از ﻛــﺎدر ‪ Language‬ﮔﺰﻳﻨــﻪ ي ‪ Visual C#‬و از ﻛــﺎدر‬ ‫‪ Location‬ﻧﻴﺰ ﮔﺰﻳﻨﻪ ي ‪ HTTP‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ ﻋﺒﺎرﺗﻲ را ﻣﺎﻧﻨﺪ‬ ‫‪http://localhost/DemoService‬‬ ‫در ﻛﺎدر ﻣﻘﺎﺑﻞ ‪ Location‬وارد ﻛﺮده و روي دﻛﻤﻪ ي ‪ OK‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ )ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪.(2-20‬‬

‫‪٨١٧‬‬

‫ﺷﻜﻞ ‪2-20‬‬ ‫اﺳﺎس اﻳﺠﺎد وب ﺳﺮوﻳﺲ ﻫﺎ ﻫﻤﺎﻧﻨﺪ اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب اﺳﺖ ﻛﻪ در ﻓﺼﻞ ﻫﻔﺪﻫﻢ ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﺷﺪﻳﻢ‪ ،‬ﺑﻨـﺎﺑﺮاﻳﻦ‬ ‫اﻳﺠﺎد ﭘﺮوژه ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ وب ﺳﺮوﻳﺲ ﻫﺎ ﻧﻴﺰ ﻣﺸﺎﺑﻪ اﻳﺠﺎد ﭘﺮوژه ﻫﺎي ﺗﺤﺖ وب اﺳﺖ‪ .‬اﮔﺮ در اﻳﺠﺎد ﭘﺮوژه ﻫﺎي اﻳﻦ ﻓﺼﻞ‬ ‫ﻣﺸﻜﻠﻲ دارﻳﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻓﺼﻞ ﻫﻔﺪﻫﻢ و ﻣﻄﺎﻟﺒﻲ ﻛﻪ در آﻧﺠﺎ ﺑﻴﺎن ﺷﺪ ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ‪.‬‬ ‫ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﻚ ﭘﺮوژه ي وب ﺳﺮوﻳﺲ اﻳﺠﺎد ﻛﺮده و ﻳﻚ ﻓﺎﻳﻞ ﺑﻪ ﻧﺎم ‪ service.asmx‬را ﻧﻴـﺰ‬ ‫ﺑﻪ آن اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ‪ .‬ﭘﺴﻮﻧﺪ ‪ .asmx‬ﻣﺮﺑﻮط ﺑﻪ ﻓﺎﻳﻠﻬﺎي وب ﺳﺮوﻳﺲ اﺳﺖ و از ﻛﻠﻤﺎت ‪Active Server‬‬ ‫‪ Methods‬ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ )ﺣﺮف ‪ x‬ﻧﻴﺰ ﺑﻪ ﻣﻨﻈﻮر ﻣﺸﺨﺺ ﻛﺮدن ‪ ASP.NET‬ﻳﺎ ﻫﻤـﺎن ‪ ASP+‬ﺑـﻪ ﻛـﺎر ﻣـﻲ‬ ‫رود‪ .‬ﺣﺮف ‪ x‬ﻣﻌﺎدل ‪ +‬اﺳﺖ ﻛﻪ ‪ 45‬درﺟﻪ ﭼﺮﺧﻴﺪه ﺑﺎﺷﺪ(‪ .‬اﻳﻦ ﺻﻔﺤﻪ ﻳﻚ ﺳﺮوﻳﺲ را ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ‪ ،‬اﻟﺒﺘـﻪ اﻳـﻦ ﭘـﺮوژه‬ ‫ﻣﻲ ﺗﻮاﻧﺪ ﺷﺎﻣﻞ ﭼﻨﺪ ﺳﺮوﻳﺲ ﺑﺎﺷﺪ‪.‬‬ ‫‪1‬‬ ‫‪ (3‬اﮔﺮ ﻓﺎﻳﻞ ‪ service.cs‬ﻛـﻪ ﺣـﺎوي ﻛـﺪ ﻣﺮﺑـﻮط ﺑـﻪ اﻳـﻦ وب ﺳـﺮوﻳﺲ اﺳـﺖ ﺑـﺎز ﻧـﺸﺪه اﺳـﺖ‪ ،‬ﺑـﺎ اﺳـﺘﻔﺎده از‬ ‫‪ Solution Explorer‬آن را ﺑﺎز ﻛﻨﻴﺪ‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺎﻓﻲ اﺳـﺖ روي ﻓﺎﻳـﻞ ‪ Service.asmx‬در‬ ‫‪ Solution Explorer‬ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﮔﺰﻳﻨﻪ ي ‪ View Code‬را اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ‪ .‬ﻫﻨﮕـﺎﻣﻲ ﻛـﻪ‬ ‫وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻳﻦ ﻓﺎﻳﻞ را اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ‪ ،‬ﻳﻚ ﻣﺘﺪ ﺑﻪ ﻧﺎم ‪ HelloWorld‬ﻧﻴﺰ ﺑﺮاي ﻧﻤﻮﻧﻪ در آن ﻗﺮار ﻣﻲ دﻫـﺪ‪.‬ﻛـﺪ‬ ‫ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻣﺘﺪ ﻣﺸﺎﺑﻪ زﻳﺮ اﺳﺖ‪:‬‬ ‫]‪[WebMethod‬‬ ‫)(‪public string HelloWorld‬‬ ‫{‬ ‫;"‪return "Hello World‬‬ ‫}‬

‫ﺑﺎ اﻧﺘﺨﺎب ﮔﺰﻳﻨﻪ ي ‪ Debug  Start Debugging‬از ﻧﻮار ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴـﺪ‪.‬‬ ‫در اﻳﻦ ﻣﺮﺣﻠﻪ ﺻﻔﺤﻪ اي ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و از ﺷﻤﺎ ﻣﻲ ﭘﺮﺳﺪ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﺮﻧﺎﻣﻪ را ﺑـﺪون ﻓﻌـﺎل ﻛـﺮدن ﻗﺎﺑﻠﻴﺘﻬـﺎي‬ ‫ﻣﺮﺑﻮط ﺑﻪ دﻳﺒﺎگ اﺟﺮا ﻛﻨﻴﺪ و ﻳﺎ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻛﻪ ﻳﻚ ﻓﺎﻳﻞ ‪ config‬ﺑﻪ ﭘﺮوژه اﺿﺎﻓﻪ ﻛﺮده و ﺳﭙﺲ در آن ﻓﺎﻳﻞ ﻗﺎﺑﻠﻴﺘﻬﺎي‬ ‫ﻣﺮﺑﻮط ﺑﻪ دﻳﺒﺎگ را ﻓﻌﺎل ﻛﻨﻴـﺪ؟ از اﻳـﻦ ﻛـﺎدر ﮔﺰﻳﻨـﻪ ي ‪Add new Web.config file with‬‬ ‫‪ 1‬اﻳﻦ ﻓﺎﻳﻠﻬﺎ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض ﺑﻪ ﺻﻮرت ‪ Code-Behind‬ﻫﺴﺘﻨﺪ‪ ،‬ﻳﻌﻨﻲ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ آﻧﻬﺎ در ﻓﺎﻳﻠﻲ ﻣﺠﺰا ذﺧﻴﺮه ﻣﻲ ﺷﻮد‪.‬‬

‫‪٨١٨‬‬

‫‪ debugging enabled‬را اﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤﻪ ي ‪ OK‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﺑﻪ دﻻﻳﻞ اﻣﻨﻴﺘﻲ ﺑﻬﺘﺮ اﺳﺖ ﻗﺒـﻞ‬ ‫از اﻳﻨﻜﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب را در اﻳﻨﺘﺮﻧﺖ ﻗﺮار دﻫﻴﺪ‪ ،‬ﻗﺎﺑﻠﻴﺘﻬﺎي ﻣﺮﺑﻮط ﺑﻪ دﻳﺒﺎگ را در آن ﻏﻴﺮ ﻓﻌﺎل ﻛﻨﻴـﺪ‪ .‬ﺑـﺎ ﻛﻠﻴـﻚ‬ ‫روي دﻛﻤﻪ ي ‪ OK‬اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﺑﺎز ﺷﺪه و ﺻﻔﺤﻪ ي ‪ service.asmx‬را ﻧﻤﺎﻳﺶ ﺧﻮاﻫﺪ داد‪ .‬ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ‬ ‫ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻟﻴﺴﺘﻲ از ﻣﺘﺪ ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﺳﺮوﻳﺲ وﺟﻮد دارﻧﺪ در اﻳﻦ ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﻣـﻲ ﺷـﻮﻧﺪ‪ .‬اﻳـﻦ ﺻـﻔﺤﻪ‬ ‫ﺑﺮاي ﺗﺴﺖ ﻛﺮدن ﻧﺤﻮه ي ﻛﺎرﻛﺮد وب ﺳﺮوﻳﺲ ﺑﻪ ﻛﺎر ﻣﻲ رود‪.‬‬ ‫ﻧﻜﺘﻪ‪ :‬در ﺑﺮﻧﺎﻣﻪ ﻫﺎي واﻗﻌﻲ‪ ،‬ﻓﺎﻳﻞ ‪ web.config‬ﺑﺮاي ﺗﻨﻈﻴﻢ ﻛﺮدن ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻒ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب ﻣﻮرد اﺳﺘﻔﺎده‬ ‫ﻗﺮار ﻣﻲ ﮔﻴﺮد‪ .‬در اﻳﻦ ﻓﺼﻞ ﻧﻤﻲ ﺧﻮاﻫﻴﻢ وارد ﺟﺰﺋﻴﺎت اﻳﻦ ﺳﺎﻳﺖ ﺷﻮﻳﻢ‪ ،‬اﻣﺎ ﻫﻤﻴﻦ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﺑﺪاﻧﻴﺪ اﻳﻦ ﻓﺎﻳﻞ ﺑﺮاي اﻳﺠﺎد ﺗﻐﻴﻴـﺮات‬ ‫ﻛﻠﻲ در ﻣﻮرد ﻗﺴﻤﺘﻬﺎي اﻣﻨﻴﺘﻲ‪ ،‬ﻗﺴﻤﺘﻬﺎي ﻣﺮﺑﻮط ﺑﻪ دﻳﺒﺎگ‪ ،‬ﻗﺴﻤﺖ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل ﻛﺎرﺑﺮان و … ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣـﻲ ﮔﻴـﺮد‪.‬‬ ‫ﺑﺮاي ﻣﻄﺎﻟﻌﻪ ي ﺑﻴﺸﺘﺮ در ﻣﻮرد ﻓﺎﻳﻞ ‪ web.config‬ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺳﻴﺴﺘﻢ راﻫﻨﻤﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ )‪ (MSDN‬ﻣﺮاﺟﻊ ﻛﻨﻴﺪ و ﻳﺎ‬ ‫در آدرس ‪ http://msdn2.microsoft.com‬ﺑﻪ دﻧﺒﺎل ﻋﺒﺎرت ‪ web.config‬ﺑﮕﺮدﻳﺪ‪.‬‬ ‫‪ (4‬روي ﻟﻴﻨﻚ ‪ HelloWorld‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬اﻳﻦ ﻟﻴﻨﻚ ﺷﻤﺎ را ﺑﻪ ﺻﻔﺤﻪ ي دﻳﮕﺮي ﺧﻮاﻫﺪ ﺑﺮد ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آن ﻣـﻲ‬ ‫ﺗﻮاﻧﻴﺪ ﻋﻤﻠﻜﺮد اﻳﻦ ﻣﺘﺪ را ﺗﺴﺖ ﻛﻨﻴﺪ‪ .‬اﻳﻦ ﺻﻔﺤﻪ ﺷﺎﻣﻞ ﻧﺎم ﻣﺘﺪ‪ ،‬دﻛﻤﻪ اي ﺑﺮاي ﻓﺮاﺧـﻮاﻧﻲ ﻣﺘـﺪ و ﺗـﺴﺖ ﻛـﺮدن آن‪ ،‬و ﻧﻴـﺰ‬ ‫ﭘﺮوﺗﻜﻞ ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﺑﺮاي اﻳﻦ ﻣﺘﺪ ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ ﺷﻮﻧﺪ‪ .‬ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻧﺎم دو ﭘﺮوﺗﻜﻞ ﻋﻨﻮان ﺷﺪه اﺳﺖ‪ :‬دو‬ ‫ﻧﺴﺨﻪ از ﭘﺮوﺗﻜﻞ ‪ SOAP‬و ﻳﻚ ﻧﺴﺨﻪ از ﭘﺮوﺗﻜﻞ ‪.HTTP POST‬‬ ‫‪ (5‬ﺑﺎ ﻛﻠﻴﻚ روي دﻛﻤﻪ ي ‪ Invoke‬ﺻﻔﺤﻪ ي دﻳﮕﺮي در ﻳﻚ ﭘﻨﺠﺮه ي ﺟﺪﻳﺪ از اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﺑﺎز ﺷـﺪه و ﻣﺤﺘﻮﻳـﺎت‬ ‫ﻳﻚ ﻓﺎﻳﻞ ‪ XML‬را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ‪ .‬اﻳﻦ ﻓﺎﻳﻞ ﻛﻪ ﻫﻤﺎﻧﻨﺪ زﻳﺮ اﺳﺖ‪ ،‬ﭘﺎﺳﺦ وب ﺳﺮوﻳﺲ اﺳﺖ ﻛﻪ ﺑـﻪ ﺻـﻮرت ‪ SOAP‬ﺑـﻪ‬ ‫ﺑﺮﻧﺎﻣﻪ ي ﻓﺮا ﺧﻮاﻧﻨﺪه ﺑﺮﮔﺸﺖ داده ﻣﻲ ﺷﻮد‪.‬‬ ‫>? "‪‪<string xmlns="http://tempuri.org/">Hello World
‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﻫﻤﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ﻛﻪ ﺑﺮاي ﻫﺮ ﻓﺎﻳﻞ ‪ .aspx‬ﻳﻚ ﻛﻼس وﺟﻮد داﺷﺖ ﻛﻪ ﺷﺎﻣﻞ ﻛﺪ ﻣﺮﺑـﻮط ﺑـﻪ آن ﻓﺎﻳـﻞ ﺑـﻮد‪ ،‬در وب‬ ‫ﺳﺮوﻳﺲ ﻫﺎ ﻧﻴﺰ ﺑﺮاي ﻫﺮ ﻓﺎﻳﻞ ‪ .asmx‬ﻳﻚ ﻛﻼس وﺟﻮد دارد ﻛﻪ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض در ﻳﻚ ﻓﺎﻳﻞ ﻣﺠﺰا ﻗـﺮار ﻣـﻲ ﮔﻴـﺮد‪ .‬ﻣﺘـﺪ‬ ‫‪ HelloWorld‬ﻧﻴﺰ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ وﺳﻴﻠﻪ ي وب ﺳﺮوﻳﺲ از آن اﺳﺘﻔﺎده ﻛﺮدﻳﻢ ﻧﻴﺰ در اﻳﻦ ﻛﻼس ﻗﺮار دارد‪ .‬اﮔﺮ ﺑﻪ ﺗﻌﺮﻳﻒ‬ ‫‪System.Web.‬‬ ‫اﻳـــﻦ ﻛـــﻼس دﻗـــﺖ ﻛﻨﻴـــﺪ‪ ،‬ﻣـــﺸﺎﻫﺪه ﺧﻮاﻫﻴـــﺪ ﻛـــﺮد ﻛـــﻪ اﻳـــﻦ ﻛـــﻼس از ﻛـــﻼس‬ ‫‪ Services.WebService‬ﻣﺸﺘﻖ ﺷﺪه اﺳﺖ‪:‬‬ ‫‪public class Service : System.Web.Services.WebService‬‬ ‫{‬

‫ﻛﻼس ‪ WebService‬ﻣﺴﺌﻮل اﻳﺠﺎد ﺻـﻔﺤﺎﺗﻲ اﺳـﺖ ﻛـﻪ در ﺑﺮﻧﺎﻣـﻪ ي ﻗﺒﻠـﻲ در اﻳﻨﺘﺮﻧـﺖ اﻛـﺴﭙﻠﻮرر ﻣـﺸﺎﻫﺪه ﻛـﺮده و ﻣﺘـﺪ‬ ‫‪ HelloWorld‬را از داﺧﻞ آن ﻓﺮاﺧﻮاﻧﻲ ﻛﺮدﻳﺪ )ﺑﺮاي ﺗﺴﺖ ﻛﺮدن وب ﺳﺮوﻳﺲ ﻣﻲ ﺗﻮاﻧﻴـﺪ از ﻣﺮورﮔﺮﻫـﺎي دﻳﮕـﺮ ﻧﻴـﺰ اﺳـﺘﻔﺎده‬ ‫ﻛﻨﻴﺪ‪ ،‬اﻣﺎ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض از اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ(‪ .‬اﻳﻦ ﺻﻔﺤﺎت ﺑﻪ ﻧﺎم راﺑﻂ ﺗﺴﺖ‪ 1‬ﺷﻨﺎﺧﺘﻪ ﻣـﻲ‬ ‫‪Test Interface‬‬

‫‪1‬‬

‫‪٨١٩‬‬

‫ﺷﻮﻧﺪ‪ .‬ﻫﻨﮕﺎم اﻳﺠﺎد ﻳﻚ ﻛﻼس‪ ،‬ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻛﻪ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﻛﺪاﻣﻴﻚ از ﻣﺘﺪﻫﺎي آن دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ‪ .‬ﻣﺘﺪ ﻫﺎﻳﻲ ﻛـﻪ‬ ‫ﻣﻲ ﺧﻮاﻫﺪ در وب ﺳﺮوﻳﺲ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮﻧﺪ را ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺼﻴﺼﻪ ي )(‪ WebMethod‬ﻣـﺸﺨﺺ ﻛﻨﻴـﺪ‪ .‬ﺑـﺮاي‬ ‫ﻣﺜﺎل ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ ﺧﺼﻴﺼﻪ در ﺧﻂ ﻗﺒﻞ از ﺗﻌﺮﻳﻒ ﻣﺘﺪ ‪ HelloWorld‬در ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻠﻲ ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ‪.‬‬ ‫]‪[WebMethod‬‬ ‫)(‪public string HelloWorld‬‬ ‫{‬ ‫;"‪return "Hello World‬‬ ‫}‬

‫ﻗﺒﻞ از اﻳﻨﻜﻪ ﺻﻔﺤﻪ ي ﺗﺴﺖ وب ﺳﺮوﻳﺲ ﺑﺎز ﺷﻮد‪ ،‬ﻛﺎدري ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ و از ﺷﻤﺎ ﻣﻲ ﭘﺮﺳﺪ ﻛﻪ آﻳﺎ ﻣﻲ ﺧﻮاﻫﻴـﺪ ﻳـﻚ ﻓﺎﻳـﻞ‬ ‫‪ config‬را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮده و ﺳﭙﺲ ﻗﺎﺑﻠﻴﺘﻬﺎي دﻳﺒﺎگ را در آن ﻓﻌﺎل ﻛﻨﻴﺪ و ﻳﺎ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﺪون ﻓﻌﺎل ﻛﺮدن اﻳﻦ ﻗﺎﺑﻠﻴﺖ ﻫـﺎ‬ ‫وب ﺳﺮوﻳﺲ را اﺟﺮا ﻛﻨﻴﺪ؟ اﮔﺮ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻧﺤﻮه ي ﻋﻤﻠﻜﺮد ﻣﺘﺪﻫﺎي اﻳﻦ وب ﺳﺮوﻳﺲ را ﺗﺴﺖ ﻛﻨﻴﺪ ﺑﺎﻳﺪ ﮔﺰﻳﻨﻪ ي ﻣﺮﺑـﻮط ﺑـﻪ اﺿـﺎﻓﻪ‬ ‫ﻛﺮدن ﻓﺎﻳﻞ ‪ web.config‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻓﺎﻳﻠﻲ ﺑﻪ ﻧﺎم ‪ web.config‬ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ اﺿـﺎﻓﻪ ﺷـﺪه و‬ ‫ﻗﺎﺑﻠﻴﺖ ﻫﺎي دﻳﺒﺎگ ﻛﺮدن ﻧﻴﺰ ﺑﻪ وﺳﻴﻠﻪ ي آن ﻓﺎﻳﻞ ﻓﻌﺎل ﻣﻲ ﺷﻮﻧﺪ‪ .‬اﻟﺒﺘﻪ دﻗﺖ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻫﻤﻮاره ﻗﺒﻞ از اﻳﻨﻜـﻪ ﺳـﺎﻳﺖ و ﻳـﺎ وب‬ ‫ﺳﺮوﻳﺲ ﺧﻮد را روي ﺳﺮور ﻗﺮار دﻫﻴﺪ ﺗﺎ اﻓﺮاد از آن اﺳﺘﻔﺎده ﻛﻨﺪ‪ ،‬ﻗﺎﺑﻠﻴﺘﻬﺎي دﻳﺒﺎگ را در آن ﻏﻴﺮ ﻓﻌﺎل ﻛﻨﻴﺪ‪ .‬ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺻﻔﺤﻪ ﺑﺎز ﺷﺪه‬ ‫و راﺑﻂ ﺗﺴﺖ ﻧﻤﺎﻳﺶ داده ﺷﺪ‪ ،‬ﻟﻴﺴﺘﻲ از ﻣﺘﺪ ﻫﺎﻳﻲ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺼﻴﺼﻪ ي ‪ WebMethod‬در ﻛﻼس ﻣﺸﺨﺺ ﺷﺪه ﺑﻮدﻧـﺪ در‬ ‫ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮﻧﺪ‪ .‬اﮔﺮ روي ﻧﺎم ﻫﺮ ﻳﻚ از اﻳﻦ ﻣﺘﺪ ﻫﺎ ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ ،‬ﺻﻔﺤﻪ اي ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ ﻛﻪ ﺑﻪ وﺳـﻴﻠﻪ ي آن‬ ‫ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﺘﺪ را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده و ﻋﻤﻠﻜﺮد آن را ﺗﺴﺖ ﻛﻨﻴﺪ‪.‬‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻚ ﻣﺘﺪ از وب ﺳﺮوﻳﺲ را ﺑﻪ اﻳﻦ ﺻﻮرت ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ‪ ،‬دﻗﻴﻘﺎً ﻣﺸﺎﺑﻪ اﻳﻦ اﺳﺖ ﻛﻪ در ﺣـﺎل ﻓﺮاﺧـﻮاﻧﻲ ﻳـﻚ ﻣﺘـﺪ ﻋـﺎدي‬ ‫ﻫﺴﺘﻴﺪ‪ .‬ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﺮاي اﻳﻦ ﻛﺎر ﻫﻴﭻ ﭼﻴﺰ ﺧﺎص و ﻳﺎ ﻧﺎﺷﻨﺎﺳﻲ را ﻣﺸﺎﻫﺪه ﻧﻤﻲ ﻛﻨﻴﺪ و ﺗﻤﺎم ﺗﺠﺮﺑﻴﺎت ﻗﺒﻠﻲ ﺷﻤﺎ در ﻣﻮرد ﻣﺘﺪ ﻫﺎ در‬ ‫اﻳﻦ ﻗﺴﻤﺖ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد‪.‬‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻲ داﻧﻴﺪ وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﺎ اﺳﺘﻔﺎده از ‪ SOAP‬ﻓﺮاﺧﻮاﻧﻲ ﺷﺪه و ﻳﺎ ﭘﺎﺳﺦ را ارﺳﺎل ﻣـﻲ ﻛﻨﻨـﺪ‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ زﻣـﺎﻧﻲ ﻛـﻪ روي‬ ‫دﻛﻤﻪ ي ‪ Invoke‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ ،‬ﻧﺘﻴﺠﻪ ي اﺟﺮاي ﻣﺘﺪ در ﻗﺎﻟﺐ ﻳﻚ ﭘﻴﻐﺎم ‪ SOAP‬ﺑﻪ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ ﻣﺘـﺪ را ﻓﺮاﺧـﻮاﻧﻲ ﻛـﺮده اﺳـﺖ‬ ‫)اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر( ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﭘﺎﺳﺨﻲ ﻛﻪ ﺑﻪ اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﻓﺮﺳﺘﺎده ﺷﺪه اﺳﺖ‪ ،‬دﻗﻴﻘﺎً ﻫﻤـﺎن‬ ‫ﻋﺒﺎرﺗﻲ اﺳﺖ ﻛﻪ در ﻣﺘﺪ ﺑﻪ ﻋﻨﻮان ﺧﺮوﺟﻲ ﺑﺮﮔﺮداﻧﺪه ﺑﻮدﻳﻢ ﻛﻪ در ﻳﻚ ﺗﮓ ‪ XML‬ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ‪:‬‬ ‫>? "‪‪<string xmlns="http://tempuri.org/">Hello World
‫در اﻳﻦ ﻓﺼﻞ ﺳﺎﺧﺘﺎر ‪ XML‬اي ﻛﻪ ﻳﻚ ﭘﻴﻐﺎم ‪ SOAP‬را ﺗﺸﻜﻴﻞ ﻣﻲ دﻫﺪ اﻫﻤﻴﺘﻲ ﻧﺪارد‪ .‬ﺑﺎ وﺟﻮد اﻳﻦ ﻫﺮ ﭼﻪ ﺑﻴﺸﺘﺮ ﺑﺎ اﻳﻦ ﻓﺎﻳﻠﻬﺎ ﻛـﺎر‬ ‫ﻛﻨﻴﻢ‪ ،‬ﺑﻬﺘﺮ ﻣﺘﻮﺟﻪ ﺧﻮاﻫﻴﺪ ﺷﺪ ﻛﻪ ﺟﻮاب ﻧﻬﺎﻳﻲ را در ﻛﺪام ﻗﺴﻤﺖ از اﻳﻦ ﻓﺎﻳﻠﻬﺎ ﻣﻲ ﺗﻮان ﭘﻴﺪا ﻛﺮد‪.‬‬

‫اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪﻫﺎي دﻳﮕﺮ‪:‬‬ ‫در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﻣﻲ ﺧﻮاﻫﻴﻢ وب ﺳﺮوﻳﺲ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ دﻫﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﺪ ﻛﺎري را اﻧﺠﺎم دﻫﺪ‪ .‬ﺑﻪ ﻫﻤﻴﻦ دﻟﻴـﻞ ﻣﺘـﺪي را‬ ‫ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛﺮد ﺗﺎ ﺑﺘﻮاﻧﺪ ﺟﺬر ﻋﺪدي ﻛﻪ ﺑﻪ آن ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد را ﻣﺤﺎﺳﺒﻪ ﻛﻨﺪ‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﺿﺎﻓﻪ ﻛﺮدن ﻣﺘﺪ ‪SquareRoot‬‬ ‫‪٨٢٠‬‬

‫‪ (1‬ﻓﺎﻳﻞ ‪ service.cs‬را ﺑﻪ وﺳﻴﻠﻪ ي وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﺑـﺎز ﻛـﺮده و ﻛـﺪ زﻳـﺮ را در ﻛـﻼس ‪ Service‬ﺑﻌـﺪ از ﻣﺘـﺪ‬ ‫‪ HelloWorld‬وارد ﻛﻨﻴﺪ‪:‬‬ ‫)‪public Double GetSquareRoot(Double number‬‬ ‫{‬ ‫;)‪return Math.Sqrt(number‬‬ ‫}‬

‫اﮔﺮ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ در ﻗﺴﻤﺖ ﻛﺪ ﻧﻮﻳﺴﻲ ﻣﺘﻨﻲ را وارد ﻛﻨﻴﺪ‪ ،‬ﻣﻤﻜﻦ اﺳﺖ ﺑﻪ اﻳﻦ ﻋﻠﺖ ﺑﺎﺷﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻠﻲ ﻫﻨﻮز در ﺣﺎل اﺟﺮا‬ ‫اﺳﺖ‪ .‬در اﻳﻦ ﺻﻮرت ﺻﻔﺤﻪ ي ﻣﺮﺑﻮط ﺑﻪ راﺑﻂ ﺗﺴﺖ و ﻫﺮ ﭘﻨﺠﺮه ي دﻳﮕﺮي ﻛﻪ ﭘﺎﺳﺦ ‪ SOAP‬ﺑﺮﮔﺸﺘﻪ ﺷﺪه ﺑﻪ وﺳـﻴﻠﻪ ي‬ ‫وب ﺳﺮوﻳﺲ را ﻧﺸﺎن ﻣﻲ دﻫﺪ را ﺑﺒﻨﺪﻳﺪ و ﺳﭙﺲ ﻛﺪ را وارد ﻛﻨﻴﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ ﺑﺮاي ﻣﺘﻮﻗﻒ ﻛﺮدن ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﻴـﺪ ﮔﺰﻳﻨـﻪ ي‬ ‫‪ Debug  Stop Debugging‬را از ﻧﻮار ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪.‬‬ ‫‪ (2‬ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ‪ .‬ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻣﺘﺪي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﺿﺎﻓﻪ ﻛﺮده ﺑﻮدﻳﺪ‪ ،‬در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﻧﻤـﻲ ﺷـﻮد‪ .‬در‬ ‫واﻗﻊ ﺻﻔﺤﻪ اي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ‪ ،‬ﻫﻴﭻ ﺗﻔﺎوﺗﻲ ﺑﺎ ﺻﻔﺤﻪ اي ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ دﻳﺪه ﺑﻮدﻳﺪ ﻧـﺪارد‪ .‬دﻟﻴـﻞ‬ ‫اﻳﻦ ﻣﻮرد در اﻳﻦ اﺳﺖ ﻛﻪ ﻣﺘﺪي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﺿﺎﻓﻪ ﻛﺮدﻳﻦ را ﺑﺎ ﺧﺼﻴـﺼﻪ ي ])(‪ [WebMethod‬ﻋﻼﻣـﺖ‬ ‫ﮔﺬاري ﻧﻜﺮدﻳﻢ‪ .‬دﻟﻴﻞ اﻳﻨﻜﻪ اﻳﻦ ﻣﺘﺪ را اﺑﺘﺪا ﺑﻪ اﻳﻦ ﺻﻮرت ﺗﻌﺮﻳﻒ ﻛﺮدﻳﻢ در اﻳﻦ ﺑﻮد ﻛﻪ ﺑﻪ ﺷﻤﺎ ﻧﺸﺎن دﻫـﻢ ﻣـﻲ ﺗـﻮاﻧﻴﻢ در‬ ‫ﻛﻼس ﻣﺮﺑﻮط ﺑﻪ وب ﺳﺮوﻳﺲ ﻣﺘﺪي داﺷﺘﻪ ﺑﺎﺷﻴﻢ ﻛﻪ ﺣﺘﻲ ﺑﻪ ﺻﻮرت ‪ public‬ﺑﺎﺷﺪ‪ ،‬اﻣـﺎ در ﻟﻴـﺴﺖ ﻣﺘـﺪﻫﺎي آن وب‬ ‫ﺳﺮوﻳﺲ ﻧﻤﺎﻳﺶ داده ﻧﺸﻮد‪ .‬ﻣﺮورﮔﺮ را ﺑﺒﻨﺪﻳﺪ و ﻣﺘﺪ را ﺑﺎ اﺳﺘﻔﺎده از ﺧﺼﻴﺼﻪ ي ‪ WebMethod‬ﺑﻪ ﺻﻮرت زﻳﺮ ﻋﻼﻣـﺖ‬ ‫ﮔﺬاري ﻛﻨﻴﺪ‪:‬‬ ‫])(‪[WebMethod‬‬ ‫)‪public Double GetSquareRoot(Double number‬‬ ‫{‬ ‫;)‪return Math.Sqrt(number‬‬ ‫}‬

‫‪(3‬‬ ‫‪(4‬‬

‫‪(5‬‬

‫‪(6‬‬

‫ﻣﺠﺪداً ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ‪ .‬اﻳﻦ ﻣﺮﺗﺒﻪ ﻣﺘﺪ را در اﺑﺘﺪاي ﺻﻔﺤﻪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد‪.‬‬ ‫ﻗﺒﻞ از اﻳﻨﻜﻪ ﻣﺘﺪ را ﺗﺴﺖ ﻛﻨﻴﻢ ﺑﺎﻳﺪ اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻨﻈﻴﻢ ﻛﻨﻴﻢ ﺗﺎ در ﺻﻮرت رخ دادن ﺧﻄﺎ ﺑﻬﺠﺎي اﻳﻨﻜـﻪ‬ ‫ﭘﻴﻐﺎم ﻛﻠﻲ ﺧﻄﺎ را ﻧﻤﺎﻳﺶ دﻫﺪ‪ ،‬ﭘﻴﻐﺎم ﺧﻄﺎي ﻛﺎﻣﻠﻲ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ‪ HTTP‬ﺑﺮﮔﺸﺘﻪ ﻣﻲ ﺷﻮد را ﺑﻨﻮﻳﺴﺪ‪ .‬ﺑﺮاي اﻳـﻦ ﻛـﺎر از‬ ‫ﻧﻮرا ﻣﻨﻮي اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﮔﺰﻳﻨﻪ ي ‪ Tools  Internet Options‬را اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ‪ .‬ﺳـﭙﺲ در‬ ‫ﻗـﺴﻤﺖ ‪ Advanced‬ﮔﺰﻳﻨـﻪ ي ”‪ “Show friendly HTTP error message‬را از‬ ‫ﺣﺎﻟﺖ اﻧﺘﺨﺎب ﺧﺎرج ﻛﻨﻴﺪ‪.‬‬ ‫روي ﻧﺎم ﻣﺘﺪ ‪ GetSquareRoot‬در ﺻﻔﺤﻪ ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺻﻔﺤﻪ ي ﻣﺮﺑﻮط ﺑﻪ ﺗﺴﺖ اﻳﻦ ﻣﺘﺪ ﻧﻤﺎﻳﺶ‬ ‫داده ﻣﻲ ﺷﻮد‪ .‬ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﻛﺎدري در اﻳﻦ ﺻﻔﺤﻪ ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ و ﺑﻪ ﺷﻤﺎ اﻳﻦ اﺟﺎزه را ﻣـﻲ دﻫـﺪ ﺗـﺎ داده ﻫـﺎي‬ ‫ﻣﻮرد ﻧﻴﺎز ﻣﺘﺪ را در آن وارد ﻛﻨﻴﺪ‪ .‬اﻣﺎ ﺑﺪون اﻳﻨﻜﻪ ﻋﺪدي را در اﻳﻦ ﻛﺎدر وارد ﻛﻨﻴﺪ‪ ،‬روي دﻛﻤﻪ ي ‪ Invoke‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪.‬‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺻﻔﺤﻪ ي ﻣﺮﺑﻮط ﺑﻪ ﭘﺎﺳﺦ ﻧﻤﺎﻳﺶ داده ﺷﺪ‪ ،‬ﻣﺎﻧﻨﺪ ﻗﺴﻤﺖ ﻗﺒﻞ ﭘﻴﻐﺎم ‪ SOAP‬را ﻣﺸﺎﻫﺪه ﻧﻤﻲ ﻛﻨﻴﺪ‪ .‬ﺑﻠﻜﻪ ﻣﺘﻨـﻲ‬ ‫ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻧﺸﺎن داده ﻣﻲ ﺷﻮد ﻣﺸﺎﺑﻪ زﻳﺮ ﺧﻮاﻫﺪ ﺑﻮد‪:‬‬

‫‪System.ArgumentException: Cannot convert to System.Double.‬‬ ‫‪Parameter name: type ---> System.FormatException: Input string was not‬‬ ‫‪in a correct format.‬‬

‫‪٨٢١‬‬

‫اﻳﻦ ﺻﻔﺤﻪ ﻣﻌﻤﻮﻻ زﻣﺎﻧﻲ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﻛﻪ اﺟﺮاي ﻣﺘﺪ ﺑﻪ ﻫﺮ دﻟﻴﻠﻲ ﻧﺘﻮاﻧﺪ ﺑﻪ درﺳﺘﻲ ﺗﻤﺎم ﺷﻮد و ﺑﺮﻧﺎﻣـﻪ ﺑـﺎ ﺧﻄـﺎﻳﻲ‬ ‫ﻣﻮاﺟﻪ ﺷﻮد‪ .‬ﺑﺮاي ﻣﺜﺎل در اﻳﻨﺠﺎ ﻣﻘﺪاري را ﻛﻪ ﺑﺮاي ﭘﺎراﻣﺘﺮ اﻳﻦ ﻣﺘﺪ ارﺳﺎل ﻛﺮدﻳﻢ ﻳﻚ رﺷﺘﻪ ي ﺗﻬﻲ ﺑﻮد‪ .‬ﻣﺘﺪ ﻧﻴﺰ ﻧﺘﻮاﻧـﺴﺖ‬ ‫رﺷﺘﻪ ي ﺗﻬﻲ را ﺑﻪ ﻳﻚ ﻣﻘﺪار از ﻧﻮع ‪ System.Double‬ﺗﺒﺪﻳﻞ ﻛﻨﺪ‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟﻪ ﺷﺪ ﻛﻪ ﺗﻮﺿﻴﺢ ﺧﻄﺎي‬ ‫رخ داده را ﻧﻴﺰ در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داد‪.‬‬ ‫‪ (7‬ﺻﻔﺤﻪ ي ﻣﺮورﮔﺮ ﻣﺮﺑﻮط ﺑﻪ ﭘﺎﺳﺦ وب ﺳﺮوﻳﺲ را ﺑﺒﻨﺪﻳﺪ و در ﺻﻔﺤﻪ ي ﻗﺒﻠﻲ‪ ،‬ﻋﺪد ‪ 2‬را در ﻛﺎدر ﻣﺮﺑﻮط ﺑﻪ ﭘﺎراﻣﺘﺮ اﻳﻦ ﻣﺘﺪ‬ ‫وارد ﻛﻨﻴﺪ‪ .‬ﺑﺎ ﻓﺸﺎر دادن دﻛﻤﻪ ي ‪ Invoke‬ﻣﺘﻨﻲ ﻫﻤﺎﻧﻨﺪ زﻳﺮ در ﭘﻨﺠﺮه ي اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد‪.‬‬ ‫>? "‪‪<double xmlns="http://tempuri.org/">1.4142135623730952
‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫اﮔﺮ ﺑﻪ ﭘﻴﻐﺎﻣﻲ ‪ SOAP‬اي ﻛﻪ ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﮔﺸﺖ داده ﺷﺪه اﺳﺖ ﻧﮕﺎه ﻛﻨﻴﺪ‪ ،‬ﻣﺘﻮﺟﻪ ﺧﻮاﻫﻴﺪ ﺷﺪ ﻋﺪدي ﻛﻪ در ﺗـﮓ ‪double‬‬ ‫اﻳﻦ ﭘﻴﻐﺎم ﻗﺮار دارد‪ ،‬ﺑﺴﻴﺎر ﻧﺰدﻳﻚ ﺑﻪ ﺟﺬر ﻋﺪد دو اﺳﺖ‪:‬‬ ‫>? "‪‪<double xmlns="http://tempuri.org/">1.4142135623730952
‫ﺧﻮب ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﻮﺟﻪ ﺷﺪﻳﺪ ﻛﻪ ﻣﺘﺪ ﺑﻪ درﺳﺘﻲ ﻛﺎر ﻣﻲ ﻛﻨﺪ‪ .‬ﺗﺎﻛﻨﻮن ﺑﺎﻳﺪ ﻓﻬﻤﻴﺪه ﺑﺎﺷﻴﺪ ﻛﻪ اﻳﺠﺎد ﻳﻚ وب ﺳﺮوﻳﺲ در ‪.NET‬ﺗـﺎ‬ ‫ﭼﻪ اﻧﺪازه راﺣﺖ اﺳﺖ و اﻳﻦ ﻣﻮرد ﻧﻴﺰ ﺑﻪ دﻟﻴﻞ ﭘﺸﺘﻴﺒﺎﻧﻲ زﻳﺎدي اﺳﺖ ﻛﻪ ‪ .NET‬از وب ﺳﺮوﻳﺲ ﻫﺎ ﻣﻲ ﻛﻨﺪ‪ .‬در ﻛﻞ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﮕﻮﻳﻴﻢ‬ ‫ﻛﻪ ﻫﺮ ﭼﻴﺰ ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ در ﻣﻮرد ﻛﻼﺳﻬﺎ‪ ،‬ﻣﺘﺪ ﻫﺎ‪ ،‬ﭘﺎراﻣﺘﺮﻫﺎي ورودي و ﻳﺎ ﻣﻘﺎدﻳﺮ ﺑﺎزﮔﺸﺘﻲ ﻳﺎد ﮔﺮﻓﺘـﻪ ﺑـﻮدﻳﻢ‪ ،‬ﻣـﻲ ﺗﻮاﻧـﺪ ﺑـﻪ‬ ‫ﺳﺎدﮔﻲ در وب ﺳﺮوﻳﺲ ﻫﺎ ﻧﻴﺰ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد‪ .‬ﻣﻲ ﺗﻮاﻧﻴﺪ ﻛﻼس ﻣﻮرد ﻧﻈﺮ ﺧﻮد را ﻃﺮاﺣﻲ ﻛﻨﻴﺪ و در اﻧﺘﻬﺎ ﺑـﺎ اﻳﺠـﺎد ﺗﻐﻴﻴـﺮات‬ ‫ﻛﻮﭼﻜﻲ در آن‪ ،‬از آن ﻛﻼس ﻫﻤﺎﻧﻨﺪ ﻳﻚ وب ﺳﺮوﻳﺲ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬

‫اﻳﺠﺎد ﺳﺮور ﭘﺮوژه ي ‪:Picture Service‬‬ ‫ﺑﻪ ﺧﺎﻃﺮ اﻳﻨﻜﻪ اﻳﺠﺎد ﻳﻚ وب ﺳﺮوﻳﺲ اﺑﺘﺪاﻳﻲ ﺑﺴﻴﺎر ﺳﺎده اﺳﺖ‪ ،‬ﺑﻪ ﺳﺮﻋﺖ ﺑﻪ ﺳﺮاغ اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻛﺎﻣﻞ ﻣﻲ روﻳﻢ ﺗـﺎ ﺑﺘﻮاﻧـﺪ ﺑـﺎ‬ ‫اﺳﺘﻔﺎده از وب ﺳﺮوﻳﺲ ﻫﺎ ﻳﻚ ﻛﺎر ﻫﺪﻓﻤﻨﺪ را اﻧﺠﺎم دﻫﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ وﻳﻨﺪوزي ﻧﻴﺰ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﺗﺎ ﺑﺘﻮاﻧـﺪ از‬ ‫اﻳﻦ وب ﺳﺮوﻳﺲ اﺳﺘﻔﺎده ﻛﻨﺪ‪ ،‬زﻳﺮا ﺗﺎ ﻛﻨﻮن ﺑﺮاي ﺗﺴﺖ ﻳﻚ وب ﺳﺮوﻳﺲ ﻓﻘﻂ از راﺑﻂ ﺗﺴﺖ و ﻣﺮورﮔﺮ اﻳﻨﺘﺮﻧﺘﻲ اﺳـﺘﻔﺎده ﻣـﻲ ﻛـﺮدﻳﻢ‪.‬‬ ‫وب ﺳﺮوﻳﺴﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﺟﺎزه ﻣﻲ دﻫﺪ ﺑﻪ ﻟﻴﺴﺘﻲ از ﺗﺼﺎوﻳﺮ ﻣﻮﺟﻮد در ﺳﺮور دﺳﺘﺮﺳﻲ داﺷـﺘﻪ‬ ‫ﺑﺎﺷﻨﺪ‪.‬‬

‫اﻳﺠﺎد ﭘﺮوژه‪:‬‬ ‫در اﻳﻦ ﻗﺴﻤﺖ‪:‬‬

‫‪٨٢٢‬‬

‫‬

‫‬ ‫‬ ‫‬

‫ﻓﻮﻟﺪري را ﺑﺮاي ﺳﺮور ﻣﺮﺑﻮط ﺑﻪ وب ﺳﺮوﻳﺲ ﺧﻮد اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ )اﻳﻦ ﻓﻮﻟﺪر ﻣﻲ ﺗﻮاﻧﺪ در ﻫﻤﺎن ﻛﺎﻣﭙﻴﻮﺗﺮي ﺑﺎﺷﺪ ﻛﻪ از آن‬ ‫اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ و ﻫﻢ ﻣﻲ ﺗﻮاﻧﺪ در ﻛﺎﻣﭙﻴﻮﺗﺮي در اﻳﻨﺘﺮﻧﺖ ﺑﺎﺷﺪ( ﺗﺎ ﺗﺼﺎوﻳﺮ ﻣـﻮرد ﻧﻈـﺮ در آن ﻧﮕﻬـﺪاري ﺷـﻮﻧﺪ‪ .‬ﻫﻤﭽﻨـﻴﻦ‬ ‫ﻋﻜﺴﻬﺎي داﺧﻞ اﻳﻦ ﻓﻮﻟﺪر را ﻧﻴﺰ دﺳﺘﻪ ﺑﻨﺪي ﺧﻮاﻫﻴﻢ ﻛﺮد و در زﻳﺮ ﻓﻮﻟﺪرﻫﺎي ﻣﺮﺗﺒﻂ ﺑﻪ ﻫﻢ ﻗﺮار ﺧﻮاﻫﻴﻢ داد‪.‬‬ ‫وب ﺳﺮوﻳﺴﻲ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﺑﺘﻮاﻧﺪ ﻓﻮﻟﺪر را ﺑﺮرﺳﻲ ﻛﺮده و ﻧﺎم ﺗﻤﺎم زﻳﺮ ﻓﻮﻟﺪر ﻫﺎي آن را اﺳـﺘﺨﺮاج ﻛﻨـﺪ‪ .‬ﻫﻤﭽﻨـﻴﻦ‬ ‫اﻳﻦ وب ﺳﺮوﻳﺲ ﺑﺎﻳﺪ ﺑﺘﻮاﻧﺪ ﻧﺎم ﻓﺎﻳﻠﻬﺎي داﺧﻞ ﻫﺮ ﻓﻮﻟﺪر را ﻧﻴﺰ ﺑﺪﺳﺖ آورد‪.‬‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ وب ﺳﺮوﻳﺲ ﻧﺎم ﻳﻚ ﻓﺎﻳﻞ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ‪ ،‬ﺑﺎﻳﺪ ﺑﺘﻮاﻧﺪ اﻃﻼﻋﺎت دﻳﮕﺮ ﻓﺎﻳﻞ را ﻧﻴـﺰ از ﻗﺒﻴـﻞ ﻓﺮﻣـﺖ‬ ‫ﻓﺎﻳﻞ‪ ،‬ﻃﻮل و ﻋﺮض ﻓﺎﻳﻞ و ﻏﻴﺮه را ﻧﻴﺰ ﺑﺪﺳﺖ آورده و در ﺑﺮﻧﺎﻣﻪ ﻗﺮار دﻫﺪ‪.‬‬ ‫ﻳﻚ ﺳﺎﻳﺖ وب اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﺗﺼﺎوﻳﺮي ﻛﻪ در اﻳﻦ ﻓﻮﻟﺪر ﻫﺎ ﻗﺮار دارﻧﺪ را در اﻳﻦ ﺳﺎﻳﺖ ﻣﺸﺎﻫﺪه ﻛﻨﻴﻢ‪.‬‬

‫ﺑﻪ ﻧﻈﺮ ﻣﻲ رﺳﺪ ﻛﻪ ﺗﻤﺎم ﻣﻮاردي ﻛﻪ در ﺑﺎﻻ ﮔﻔﺘﻪ ﺷﺪ را ﺑﺎ ﻳﻚ ﺳﺎﻳﺖ ﻣﻌﻤﻮﻟﻲ ﻛﻪ ﺑﺎ ‪ ASP.NET‬ﻃﺮاﺣﻲ ﺷﺪه ﺑﺎﺷﺪ ﻧﻴـﺰ ﻣـﻲ ﺗـﻮان‬ ‫اﻧﺠﺎم داد‪ .‬ﺑﺎ اﻳﻦ وﺟﻮد ﻛﺎري ﻛﻪ ﺑﺎ ﻳﻚ وب ﺳﺮوﻳﺲ ﻣﻲ ﺗﻮان اﻧﺠﺎم داد وﻟﻲ اﻧﺠﺎم آن ﺑﺎ ﻳﻚ ﺳﺎﻳﺖ ‪ ASP.NET‬ﻏﻴﺮ ﻣﻤﻜﻦ اﺳـﺖ‬ ‫اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از وب ﺳﺮوﻳﺲ ﻫﺎ ﻣﻲ ﺗﻮان ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وﻳﻨﺪوز ﻃﺮاﺣﻲ ﻛﺮد ﻛﻪ ﺑﺘﻮاﻧﺪ از اﻃﻼﻋﺎت اﻳﻦ ﺳـﺮور اﺳـﺘﻔﺎده‬ ‫ﻛﻨﺪ‪ .‬ﺑﺎ ﻃﺮاﺣﻲ ﻳﻚ وب ﺳﺎﻳﺖ ﺷﻤﺎ ﻣﺠﺒﻮر ﺧﻮاﻫﻴﺪ ﺑﻮد ﻛﻪ ﺣﺘﻤﺎً از ‪ HTML‬و ﻳﻚ ﻣﺮورﮔﺮ وب ﺑﺮاي ﻧﻤﺎﻳﺶ داده ﻫـﺎي ﺧـﻮد اﺳـﺘﻔﺎده‬ ‫ﻛﻨﻴﺪ‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﻳﺠﺎد ﭘﺮوژه‬ ‫‪(1‬‬

‫‪(2‬‬

‫‪(3‬‬

‫‪(4‬‬

‫‪(5‬‬

‫ﺑﺎ اﻧﺘﺨﺎب ﮔﺰﻳﻨﻪ ي …‪ File  New Web Site‬از ﻧﻮار ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ‪ ،‬ﭘﻨﺠﺮه ي ‪New Web‬‬ ‫‪ Site‬را ﺑﺎز ﻛﺮده و ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻦ ﭘﻨﺠﺮه‪ ،‬ﻳـﻚ ﭘـﺮوژه از ﻧـﻮع ‪ ASP.NET Web Services‬ﺑـﻪ ﻧـﺎم‬ ‫‪ PictureService‬اﻳﺠﺎد ﻛﻨﻴﺪ‪ .‬ﻣﻲ ﺗﻮاﻧﻴﺪ ﻓﻮﻟﺪر ﻣﺮﺑﻮط ﺑﻪ ﭘﺮوژه را در ﻫﺮ ﻗﺴﻤﺘﻲ از دﻳﺴﻚ ﻛﻪ ﻣﺪ ﻧﻈﺮ داﺷـﺘﻪ‬ ‫ﺑﺎﺷﻴﺪ ﻗﺮار دﻫﻴﺪ‪ .‬ﺑﺎ اﺳﺘﻔﺎده از وب ﺳﺮور دروﻧﻲ ﻛﻪ در وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬وﺟﻮد دارد دﻳﮕﺮ ﻻزم ﻧﻴﺴﺖ ﻧﮕـﺮان ﺗﻨﻈﻴﻤـﺎت‬ ‫ﻣﺮﺑﻮط ﺑﻪ ‪ IIS‬ﺑﺎﺷﻴﺪ‪.‬‬ ‫در اﻳﻦ ﭘﺮوژه ﻧﻤﻲ ﺧﻮاﻫﻴﻢ از ﻓﺎﻳﻠﻬﺎي ‪ service.asmx‬و ‪ Service.cs‬اﺳﺘﻔﺎده ﻛﻨـﻴﻢ‪ ،‬ﺑﻨـﺎﺑﺮاﻳﻦ آﻧﻬـﺎ را‬ ‫ﺣﺬف ﻛﺮده و ﻓﺎﻳﻠﻬﺎي ﻣﻮرد ﻧﻈﺮ ﺧﻮد را اﺿﺎﻓﻪ ﺧﻮاﻫﻴﻢ ﻛﺮد‪ .‬ﺑﺎ اﺳـﺘﻔﺎده از ﭘﻨﺠـﺮه ي ‪Solution Explorer‬‬ ‫روي ﻧﺎم اﻳﻦ ﻓﺎﻳﻠﻬﺎ ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﮔﺰﻳﻨﻪ ي ‪ Delete‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ در ﻛﺎدر ﺗﺎﻳﻴﺪي ﻛﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ‬ ‫ﺷﻮد روي دﻛﻤﻪ ي ‪ OK‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ اﻳﻦ ﻓﺎﻳﻠﻬﺎ ﺣﺬف ﺷﻮﻧﺪ‪.‬‬ ‫ﻣﺠﺪداً ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي ‪ Solution Explorer‬روي ﻧﺎم ﭘﺮوژه ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﮔﺰﻳﻨﻪ ي ‪Add‬‬ ‫‪ New Item‬را اﻧﺘﺨﺎب ﻛﻨﻴـﺪ‪ .‬در ﻛـﺎدر ‪ Add New Item‬ﮔﺰﻳﻨـﻪ ي ‪ Web Service‬را از ﻗـﺴﻤﺖ‬ ‫‪ Templates‬اﻧﺘﺨﺎب ﻛﺮده و ﺳﭙﺲ ﻧﺎم ‪ Service‬را در ﻛﺎدر ‪ Name‬وارد ﻛﻨﻴﺪ‪ .‬ﺑﺎ ﻛﻠﻴﻚ ﻛـﺮدن روي دﻛﻤـﻪ‬ ‫ي ‪ Add‬اﻳــﻦ ﻓﺎﻳــﻞ ﺑــﻪ ﭘــﺮوژه اﺿــﺎﻓﻪ ﺧﻮاﻫــﺪ ﺷــﺪ‪ .‬ﺑﻨــﺎﺑﺮاﻳﻦ ﻫــﻢ اﻛﻨــﻮن ﭘــﺮوژه ﺑﺎﻳــﺪ ﺷــﺎﻣﻞ ﻳــﻚ ﻓﺎﻳــﻞ ﺑــﻪ ﻧــﺎم‬ ‫‪ Service.asmx‬ﺑﺎﺷﺪ‪.‬‬ ‫ﺣﺎل ﻛﻪ ﻓﺎﻳﻞ ‪ .asmx‬ﺟﺪﻳﺪ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮدﻳﻢ‪ ،‬ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ ﻛﻪ ﻫﻨﮕﺎم اﺟﺮا ﺷﺪن ﺑﺮﻧﺎﻣﻪ اﻳـﻦ ﻓﺎﻳـﻞ ﺑﺎﻳـﺪ‬ ‫ﺗﻮﺳﻂ ﻣﺮورﮔﺮ اﻳﻨﺘﺮﻧﺘﻲ ﻧﻤـﺎﻳﺶ داده ﺷـﻮد‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ ﺑـﺎ اﺳـﺘﻔﺎده از ﻛـﺎدر ‪ Solution Explorer‬روي ﻧـﺎم‬ ‫‪ Service.asmx‬ﻛﻠﻴﻚ ﻛﺮده و ﮔﺰﻳﻨﻪ ي ‪ Set as start page‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪.‬‬ ‫ﺣﺎل ﺑﺎﻳﺪ ﻳﻚ ﻓﻮﻟﺪر ﻧﻴﺰ ﺑﻪ وب ﺳﺎﻳﺖ اﺿﺎﻓﻪ ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﻓﺎﻳﻠﻬﺎي ﺗﺼﻮﻳﺮ را در آن ﻗﺮار دﻫﻴﻢ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ اﻳـﻦ ﻓﺎﻳﻠﻬـﺎ‬ ‫ﻣﻲ ﺗﻮاﻧﻨﺪ از ﻃﺮﻳﻖ وب ﻧﻴﺰ در دﺳﺘﺮس ﻗﺮار ﮔﻴﺮﻧﺪ‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر روي ﻧﺎم ﭘـﺮوژه در ‪Solution Explorer‬‬

‫‪٨٢٣‬‬

‫ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨﻮي ﺑﺎز ﺷﺪه ﮔﺰﻳﻨﻪ ي ‪ New Folder‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ ﻳﻚ ﻓﻮﻟﺪر ﺟﺪﻳﺪ ﺑﻪ ﭘﺮوژه اﺿـﺎﻓﻪ‬ ‫ﺷﻮد‪ .‬ﻧﺎم اﻳﻦ ﻓﻮﻟﺪر را ﻧﻴﺰ ‪ Pictures‬ﻗﺮار دﻫﻴﺪ‪.‬‬ ‫‪ (6‬ﺣﺎل روي ﻓﺎﻳﻞ ‪ Service.asmx‬ﻛﻠﻴﻚ راﺳﺖ ﻛـﺮده و ﮔﺰﻳﻨـﻪ ي ‪ View Code‬را اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ ﺗـﺎ ﻛـﺪ‬ ‫ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس ‪ Service‬ﻧﻤﺎﻳﺶ داده ﺷﻮد‪ .‬ﺳﭙﺲ ﻛﺪ درون ﻣﺘﺪ ‪ HelloWorld‬را ﺑـﻪ ﺻـﻮرت زﻳـﺮ ﺗﻐﻴﻴـﺮ‬ ‫دﻫﻴﺪ‪:‬‬ ‫]‪[WebMethod‬‬ ‫)(‪public string HelloWorld‬‬ ‫{‬ ‫(‪return Server.MapPath‬‬ ‫;)]"‪Context.Request.ServerVariables["script_name‬‬ ‫}‬

‫‪ (7‬ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﻣﺎﻧﻨﺪ ﻗﺒﻞ روي ﻟﻴﻨﻚ ﻣﺮﺑﻮط ﺑﻪ ﻣﺘﺪ ‪ HelloWorld‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ راﺑﻂ ﺗﺴﺖ آن ﻧﻤـﺎﻳﺶ داده‬ ‫ﺷــﻮد‪ .‬در اﻳــﻦ ﺻــﻔﺤﻪ روي دﻛﻤــﻪ ي ‪ Invoke‬ﻛﻠﻴــﻚ ﻛﻨﻴــﺪ‪ .‬ﺑــﻪ اﻳــﻦ ﺗﺮﺗﻴــﺐ وب ﺳــﺮوﻳﺲ ﻣــﺴﻴﺮي ﻛــﻪ ﻓﺎﻳــﻞ‬ ‫‪ Service.asmx‬از آن اﺟﺮا ﻣﻲ ﺷﻮد را ﻧﻤﺎﻳﺶ ﺧﻮاﻫﺪ داد‪.‬‬ ‫>? "‪"‪<string xmlns="http://tempuri.org/‬‬ ‫‪C:\WebSites\PictureService\Service.asmx‬‬ ‫>‪
‫‪ (8‬ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ در ﻛﺎﻣﭙﻴﻮﺗﺮي ﻛﻪ اﻳﻦ ﺳﺮوﻳﺲ در آن اﺟﺮا ﺷـﺪه اﺳـﺖ‪ ،‬ﻓﻮﻟـﺪر …‪ C:\WebSites‬ﺣـﺎوي ﻓﺎﻳـﻞ‬ ‫‪ Service.asmx‬اﺳﺖ‪ .‬اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺑﻌﺪ ﺑﻪ اﻳﻦ ﻓﻮﻟﺪر‪ ،‬ﻓﻮﻟﺪر اﺻﻠﻲ ﺳﺮوﻳﺲ ﻣﻲ ﮔﻮﻳﻴﻢ‪ .‬ﻓﻮﻟﺪر اﺻﻠﻲ ﺳﺮوﻳﺲ در‬ ‫ﺑﺮﻧﺎﻣﻪ ي ﻗﺒﻞ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ ‪ 3-20‬ﺑﺎﺷﺪ‪.‬‬ ‫‪ (9‬ﺣﺎل ﺑﺎﻳﺪ ﺗﻌﺪادي ﻋﻜﺲ ﭘﻴﺪا ﻛﺮده و آﻧﻬﺎ را در ﻓﻮﻟﺪر ‪ Pictures‬ﻛﻪ در ﻓﻮﻟﺪر اﺻﻠﻲ ﺳﺮوﻳﺲ ﻗـﺮار دارد ﻛﭙـﻲ ﻛﻨـﻴﻢ‪.‬‬ ‫ﺑــﺮاي اﻳــﻦ ﻛــﺎر ﺗﻌــﺪادي ﻋﻜــﺲ ﺑــﺎ ﻓﺮﻣــﺖ ﻫــﺎي ‪ JPEG‬و ﻳــﺎ ‪ GIF‬از ﻛــﺎﻣﭙﻴﻮﺗﺮ ﺧــﻮد اﻧﺘﺨــﺎب ﻛــﺮده و در ﻓﻮﻟــﺪر‬ ‫‪ pictures‬ﻗﺮار دﻫﻴﺪ‪.‬‬ ‫‪ (10‬اﻳﻦ ﺗﺼﺎوﻳﺮ را ﺑﻪ ﺳﻪ ﻗﺴﻤﺖ ﺗﻘﺴﻴﻢ ﻛﺮده و ﻫﺮ ﻳﻚ را در ﻳﻚ ﻓﻮﻟﺪر ﻣﺠﺰا درون ‪ Pictures‬ﻗﺮار دﻫﻴﺪ‪ .‬ﻧﺎم اﻳﻦ ﺳـﻪ‬ ‫ﻓﻮﻟﺪر را ﺑﻪ دﻟﺨﻮاه ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ‪ .‬در اﻳﻦ ﻣﺜﺎل ﺳﻪ ﻓﻮﻟـﺪر ﺑـﻪ ﻧـﺎم ‪ Mountains ،Beach‬و ‪ Remodel‬اﻳﺠـﺎد‬ ‫ﻛﺮدﻳﻢ و ﺗﺼﺎوﻳﺮ را در آﻧﻬﺎ ﻗﺮار دادﻳﻢ‪.‬‬

‫‪٨٢٤‬‬

‫ﺷﻜﻞ ‪3-20‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﺗﺎ اﻳﻨﺠﺎ ﺑﺮﻧﺎﻣﻪ ﺷﺎﻣﻞ ﻳﻚ وب ﺳﺮوﻳﺲ و ﻧﻴﺰ ﺗﻌﺪادي ﻋﻜﺲ ﻣﻲ ﺷﻮد ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﻢ داﺧﻞ وب ﺳﺮوﻳﺲ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪ .‬ﺗﻨﻬﺎ ﻛﺪي‬ ‫ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻧﻮﺷﺘﻴﻢ‪ ،‬ﻛﺪي ﺑﻮد ﻛﻪ درون ﻣﺘﺪ ‪ HelloWorld‬از ﻛﻼس ‪ Service‬وارد ﻛﺮدﻳﻢ‪:‬‬ ‫]‪[WebMethod‬‬ ‫)(‪public string HelloWorld‬‬ ‫{‬ ‫(‪return Server.MapPath‬‬ ‫;)]"‪Context.Request.ServerVariables["script_name‬‬ ‫}‬

‫ﻣﺘﺪي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ از آن اﺳﺘﻔﺎده ﻛﺮدﻳﻢ ﻳﻜﻲ از ﻣﺘﺪﻫﺎي ‪ ASP.NET‬اﺳﺖ )ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﺮ اﺳﺎس‬ ‫ﺗﻜﻨﻮﻟﻮژي ‪ ASP.NET‬ﻫﺴﺘﻨﺪ( و ﺗﻮﺿﻴﺢ آن ﻓﺮاﺗﺮ از اﻫﺪاف اﻳﻦ ﻛﺘﺎب اﺳﺖ‪ .‬در ﻣﻮرد اﻳﻦ ﻣﺘﺪ ﻓﻘﻂ ﻣـﻲ ﺗـﻮاﻧﻢ اﻳـﻦ را ﺑﮕـﻮﻳﻢ ﻛـﻪ‬ ‫ﺻﻔﺤﺎت وب در ‪ ASP.NET‬ﺑﻪ روﺷﻬﺎي ﺧﺎﺻﻲ ﻣﻲ ﺗﻮاﻧﻨﺪ در ﻣﻮرد ﻣﺤﻴﻄﻲ ﻛﻪ در آن ﻗﺮار ﮔﺮﻓﺘﻪ اﻧﺪ اﻃﻼﻋـﺎﺗﻲ را ﺑﺪﺳـﺖ آورﻧـﺪ‪.‬‬ ‫اﻳﻦ ﻣﺘﺪ ﻧﻴﺰ ﺑﺮاي ﺑﺪﺳﺖ آوردن ﻣﺴﻴﺮ ﻓﻴﺰﻳﻜﻲ اﺳﺖ ﻛﻪ ﻓﺎﻳﻞ ﻣﺮﺑﻮط ﺑﻪ وب ﺳﺮوﻳﺲ در آن ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ‪.‬‬

‫ﺑﺮﮔﺮداﻧﺪن آراﻳﻪ ﻫﺎ ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ي ﻣﺘﺪ‪:‬‬ ‫در اﺑﺘﺪاي اﻳﻦ ﻓﺼﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﻳﻚ ﻣﺘﺪ از ﻳﻚ وب ﺳﺮوﻳﺲ ﻣﻲ ﺗﻮاﻧﺪ ﻳﻚ ﻣﻘﺪار را ﺑﻪ ﻋﻨـﻮان ﻧﺘﻴﺠـﻪ ﺑﺮﮔﺮداﻧـﺪ‪ ،‬ﺑـﺮاي‬ ‫ﻣﺜﺎل ﻳﻚ ﻋﺪد ﺻﺤﻴﺢ‪ ،‬ﻳﻚ رﺷﺘﻪ و ﻳﺎ …‪.‬‬ ‫در ﺷﺮاﻳﻄﻲ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ ﻛﻪ ﻟﻴﺴﺘﻲ از ﻣﺘﻐﻴﻴﺮ ﻫﺎ را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ از ﻣﺘﺪ ﺑﺮﮔﺮداﻧﻴﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل زﻣﺎﻧﻲ ﻛﻪ ﻛﺎرﺑﺮ درﺧﻮاﺳﺖ ﻣﻲ‬ ‫ﻛﻨﺪ ﻛﻪ ﻟﻴﺴﺖ ﻓﻮﻟﺪرﻫﺎي ﺣﺎوي ﻋﻜﺲ را درﻳﺎﻓﺖ ﻛﻨﺪ‪ ،‬ﺑﺎﻳﺪ آراﻳﻪ اي از رﺷﺘﻪ ﻫﺎ اﺳﺖ ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﮔﺸﺘﻪ ﺷﻮد ﻛﻪ ﻫﺮ ﻳﻚ از آﻧﻬـﺎ‬

‫‪٨٢٥‬‬

‫ﺷﺎﻣﻞ ﻧﺎم ﻳﻜﻲ از ﻓﻮﻟﺪرﻫﺎي درون ‪ Pictures‬اﺳﺖ‪ .‬در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ اﻳﻦ آراﻳﻪ را ﺑﻪ ﻋﻨﻮان ﺧﺮوﺟﻲ ﻳﻜﻲ از ﻣﺘﺪﻫﺎي‬ ‫وب ﺳﺮوﻳﺲ ﺑﺮ ﺧﻮاﻫﻴﻢ ﮔﺮداﻧﺪ‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬ﺑﺮﮔﺮداﻧﺪن ﻳﻚ آراﻳﻪ از وب ﺳﺮوﻳﺲ‬ ‫‪ (1‬ﻓﺎﻳﻞ ‪ Service.cs‬را در وﻳﺮاﻳﺸﮕﺮ ﻛﺪ ﺑﺎز ﻛﺮده و ﻣﺘﺪ ‪ HelloWorld‬را از ﻛـﻼس ‪ Service‬در آن‬ ‫ﺣﺬف ﻛﻨﻴﺪ‪.‬‬ ‫‪ (2‬ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر ‪ using‬ﻫﻤﺎﻧﻨﺪ زﻳﺮ ﻓﻀﺎي ﻧﺎم ‪ System.IO‬را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪:‬‬ ‫;‪using System.IO‬‬

‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ در ﺣﺎل اﻳﺠﺎد ﻣﺘﺪﻫﺎي اﻳﻦ وب ﺳﺮوﻳﺲ ﻫﺴﺘﻴﺪ‪ ،‬ﻻزم اﺳﺖ ﻛـﻪ ﺑـﺎ آدرس ﻓﻮﻟـﺪر ‪ Pictures‬دﺳﺘﺮﺳـﻲ‬ ‫داﺷﺘﻪ ﺑﺎﺷﻴﺪ‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر ﺑﺎﻳﺪ از ﻛﺪي ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ ﺑﺮاي ﺑﺪﺳﺖ آوردن ﻣﺴﻴﺮ ﻓﻴﺰﻳﻜﻲ ﻓﻮﻟﺪر اﺻﻠﻲ ﺳﺮوﻳﺲ اﺳـﺘﻔﺎده‬ ‫ﻛﺮدﻳﻢ‪ ،‬اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺧﺎﺻﻴﺖ زﻳﺮ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪:‬‬ ‫‪// PictureFolderPath - read-only property to return the picture‬‬ ‫‪// folder...‬‬ ‫‪public String PictureFolderPath‬‬ ‫{‬ ‫‪get‬‬ ‫{‬ ‫‪// get the full path of this asmx page...‬‬ ‫;‪String strAsmxPath, strPicturePath‬‬ ‫(‪strAsmxPath = Server.MapPath‬‬ ‫;)]"‪Context.Request.ServerVariables["script_name‬‬ ‫‪// get the service path - everything up to and including‬‬ ‫"\" ‪// the‬‬ ‫‪String strServicePath = strAsmxPath.Substring(0,‬‬ ‫;)‪strAsmxPath.LastIndexOf("\\") + 1‬‬ ‫‪// append the word “Pictures” to the end of the path...‬‬ ‫"‪strPicturePath = strServicePath + "Pictures‬‬ ‫‪// return the path...‬‬ ‫;‪return strPicturePath‬‬ ‫}‬ ‫}‬

‫‪ (3‬ﺑﺎ ﺑﺪﺳﺖ آوردن ﻧﺎم ﻓﻮﻟﺪر‪ ،‬ﻓﻘﻂ ﻧﻴﻤﻲ از ﻣﺸﻜﻞ ﺣﻞ ﺷﺪه اﺳﺖ‪ .‬ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ ﻛﺎرﻫﺎي ﻣﻮرد ﻧﻈﺮ ﺧﻮد را در اﻳـﻦ ﻓﻮﻟـﺪر‬ ‫اﻧﺠﺎم دﻫﻴﻢ‪ ،‬ﺑﻪ ﺷﻴﺊ اي ﻧﻴﺎز دارﻳﻢ ﺗﺎ ﺑﻪ ﻣﺎ اﺟﺎزه دﻫﺪ در ﻓﻮﻟﺪر ﺗﺼﺎوﻳﺮ ﺟﺴﺘﺠﻮ ﻛـﺮده و ﻓﻮﻟـﺪر ﻫـﺎ و ﻓﺎﻳﻠﻬـﺎي درون آن را‬ ‫ﺑﺪﺳﺖ آورﻳﻢ‪ .‬ﺑﺮاي ان ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻛﻼس ‪ System.IO.DirectoryInfo‬اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ‬ ‫ﻛﺪ زﻳﺮ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪:‬‬ ‫‪// PictureFolder - property to the DirectoryInfo containing‬‬ ‫‪// the pictures...‬‬ ‫‪public DirectoryInfo PictureFolder‬‬ ‫{‬ ‫‪get‬‬

‫‪٨٢٦‬‬

{ return new DirectoryInfo(PictureFolderPath); } }

:‫ را اﻳﺠﺎد ﻛﻨﻴﻢ‬GetPictureFolders ‫( ﺣﺎل ﻣﻲ ﺗﻮاﻧﻴﻢ ﻣﺘﺪ‬4 // GetPictureFolders - return an array of the picture folders... [WebMethod(Description = "Return an array of the picture folders")] public String[] GetPictureFolders() { // get hold of the picture folder... DirectoryInfo pictureFolder = this.PictureFolder; // get the array of subfolders... DirectoryInfo[] objPictureSubFolder = pictureFolder.GetDirectories(); // create a string array to accommodate the names... String[] arrFolderNames = new String[objPictureSubFolder.Length]; // now, loop through the folders... int intIndex = 0; foreach (DirectoryInfo pictureSubFolder in objPictureSubFolder) { // add the name... arrFolderNames[intIndex] = pictureSubFolder.Name; // next... intIndex += 1; } // finally, return the list of names... return arrFolderNames; }

‫ در ﺻﻔﺤﻪ ي ﻣﺮﺑﻮط ﺑـﻪ‬.‫ ﻛﻠﻴﻚ ﻛﻨﻴﺪ‬GetPictureFolders ‫( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و روي ﻟﻴﻨﻚ ﻣﺮﺑﻮط ﺑﻪ ﻣﺘﺪ‬5 XML ‫ ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻧﺎم ﻓﻮﻟﺪر ﻫﺎﻳﻲ را ﻛﻪ اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﺪ در ﻗﺎﻟـﺐ‬.‫ را ﻓﺸﺎر دﻫﻴﺪ‬Invoke ‫ﺗﺴﺖ اﻳﻦ ﻣﺘﺪ دﻛﻤﻪ ي‬ .‫ﻫﻤﺎﻧﻨﺪ زﻳﺮ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد‬ <string>Beach <string>Mountains <string>Remodel

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ زﻳـﺮا اوﻻ‬.‫ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺒﻴﻨﻴﺪ ﻛﻪ واﻗﻌﺎً ﻣﺘﺪ ﺷﻤﺎ آراﻳﻪ اي از رﺷﺘﻪ ﻫﺎ را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﻣـﻲ ﮔﺮداﻧـﺪ‬،‫ ﻣﺘﺪ‬SOAP ‫ﺑﺎ ﻣﺸﺎﻫﺪه ي ﭘﺎﺳﺦ‬ ‫ دارﻳﻢ ﻛﻪ ﻧﺎم‬string ‫ ﻗﺮار ﮔﺮﻓﺘﻪ اﻧﺪ و دوم ﻧﻴﺰ در اﻳﻨﺠﺎ ﻣﺎ ﺳﻪ ﺗﮓ ﺑﺎ ﻧﺎم‬ArrayOfStrings ‫رﺷﺘﻪ ﻫﺎ در ﺗﮕﻲ ﺑﻪ ﻧﺎم‬ .‫ﻓﻮﻟﺪر ﻫﺎﻳﻲ ﻛﻪ اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﻢ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻨﺪ‬

٨٢٧

<string>Beach <string>Mountains <string>Remodel

‫ زﻳﺮا در ﻃﻮل ﻧﻮﺷﺘﻦ ﻣﺘﺪﻫﺎي اﻳﻦ ﺑﺮﻧﺎﻣـﻪ از آن ﺑـﺴﻴﺎر‬،‫ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺴﻴﺎر ﻣﻬﻢ اﺳﺖ‬PictureFolderPath ‫ﺧﺎﺻﻴﺖ‬ ‫ در آن ﻗﺮار دارد را ﺑﺎ اﺳﺘﻔﺎده از ﻛـﺪي ﻛـﻪ در ﺗﻤـﺮﻳﻦ‬service.asmx ‫ در اﻳﻨﺠﺎ اﺑﺘﺪا ﻣﺴﻴﺮي ﻛﻪ ﻓﺎﻳﻞ‬.‫اﺳﺘﻔﺎده ﺧﻮاﻫﻴﻢ ﻛﺮد‬ :‫ﻗﺒﻠﻲ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﺑﺪﺳﺖ ﻣﻲ آورﻳﻢ‬ // PictureFolderPath - read-only property to return the picture // folder... public String PictureFolderPath { get { // get the full path of this asmx page... String strAsmxPath, strPicturePath; strAsmxPath = Server.MapPath( Context.Request.ServerVariables["script_name"]);

:‫ ﻗﺮار ﺧﻮاﻫﺪ ﮔﺮﻓﺖ‬strAsmxPath ‫ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﻨﻲ ﻣﺸﺎﺑﻪ زﻳﺮ در ﻣﺘﻐﻴﻴﺮ‬ C:\WebSites\PictureService\Service.asmx :‫و ﻣﺎ ﻣﻲ ﺧﻮاﻫﻴﻢ اﻳﻦ ﻣﺘﻦ را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﻢ‬ C:\WebSites\PictureService\Pictures ‫ ﺑﺮاي اﻳـﻦ‬.‫ ﺟﺎﻳﮕﺰﻳﻦ ﻛﻨﻴﻢ‬pictures ‫ از اﻳﻦ رﺷﺘﻪ را ﺣﺬف ﻛﺮده و آن را ﺑﺎ ﻧﺎم‬service.asmx ‫ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ ﻗﺴﻤﺖ‬ ‫ ﻗﺴﻤﺘﻲ از رﺷﺘﻪ ﻛﻪ ﺑـﻪ آن ﻧﻴـﺎز دارﻳـﻢ را ﺟـﺪا ﻛـﺮده و در ﻣﺘﻐﻴﻴـﺮ‬،String ‫ از ﻛﻼس‬Substring ‫ﻛﺎر ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ‬ ‫ اﻳﻦ ﻗﺴﻤﺖ ﻛﻪ ﺑﺎﻳﺪ ﺟﺪا ﺷﻮد از اوﻟﻴﻦ ﻛﺎراﻛﺘﺮ ﺷﺮوع ﺷﺪه )ﻛﺎراﻛﺘﺮ ﺑﺎ اﻧﺪﻳﺲ ﺻﻔﺮ( و ﺗـﺎ‬.‫ ﻗﺮار ﻣﻲ دﻫﻴﻢ‬strServicePath ‫ از‬LastIndexOf ‫ ﺑﺮاي ﺑﺪﺳﺖ آوردن اﻧﺪﻳﺲ آﺧـﺮﻳﻦ ﻛـﺎراﻛﺘﺮ \ ﻧﻴـﺰ از ﻣﺘـﺪ‬.‫آﺧﺮﻳﻦ ﻛﺎراﻛﺘﺮ \ در رﺷﺘﻪ اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ‬ ‫ ﻫﻤﭽﻨﻴﻦ اﻧﺪﻳﺲ آﺧﺮ را ﺑﺎ ﻋﺪد ﻳﻚ ﺟﻤﻊ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻣﻄﻤﺌﻦ ﺷﻮﻳﻢ ﻛﻪ ﺧﻮد ﻛﺎراﻛﺘﺮ \ آﺧﺮ ﻧﻴﺰ‬.‫ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ‬String ‫ﻛﻼس‬ .‫ﺑﻪ رﺷﺘﻪ اﺿﺎﻓﻪ ﻣﻲ ﺷﻮد‬ // get the service path - everything up to and including // the "\" String strServicePath = strAsmxPath.Substring(0, strAsmxPath.LastIndexOf("\\") + 1);

٨٢٨

‫ﺳﭙﺲ ﻧﺎم ‪ Pictures‬را ﺑﻪ اﻧﺘﻬﺎي ﻣﺘﻐﻴﻴﺮ ‪ strServicePath‬اﺿﺎﻓﻪ ﻛﺮده و رﺷﺘﻪ ي ﻧﻬﺎﻳﻲ را ﺑـﻪ ﻋﻨـﻮان ﻧﺘﻴﺠـﻪ از‬ ‫ﺧﺎﺻﻴﺖ ﺑﺮﻣﻲ ﮔﺮداﻧﻴﻢ‪:‬‬ ‫‪// append the word “Pictures” to the end of the path...‬‬ ‫"‪strPicturePath = strServicePath + "Pictures‬‬ ‫‪// return the path...‬‬ ‫;‪return strPicturePath‬‬ ‫}‬ ‫}‬

‫ﻛﻼس ‪ System.IO.DirectoryInfo‬ﺑﺮاي ﺑﺪﺳﺖ آوردن اﻃﻼﻋﺎت ﺑﻴﺸﺘﺮ در ﻣﻮرد ﻳـﻚ ﻓﻮﻟـﺪر در دﻳـﺴﻚ و ﻳـﺎ‬ ‫ﺷﺒﻜﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻳﻚ ﺧﺎﺻﻴﺖ ﺑﻪ ﻧﺎم ‪ PictureFolder‬اﻳﺠـﺎد ﻣـﻲ ﻛﻨـﻴﻢ ﺗـﺎ ﺑـﺮ اﺳـﺎس ﻣﻘـﺪار‬ ‫ﺧﺎﺻﻴﺖ ‪ ،PictureFolderPath‬ﺷﻴﺊ اي را از ﻛﻼس ‪ DirectoryInfo‬اﻳﺠﺎد ﻛﺮده و آن را ﺑﺮﮔﺮداﻧﺪ‪:‬‬ ‫‪// PictureFolder - property to the DirectoryInfo containing‬‬ ‫‪// the pictures...‬‬ ‫‪public DirectoryInfo PictureFolder‬‬ ‫{‬ ‫‪get‬‬ ‫{‬ ‫;)‪return new DirectoryInfo(PictureFolderPath‬‬ ‫}‬ ‫}‬

‫ﻫﻨﮕــﺎﻣﻲ ﻛــﻪ ﺗﻮاﻧــﺴﺘﻴﻢ ﺑــﻪ ﺷــﻴﺊ ‪ DirectoryInfo‬ﻣــﻮرد ﻧﻈــﺮ ﺧــﻮد دﺳﺘﺮﺳــﻲ ﭘﻴــﺪا ﻛﻨــﻴﻢ‪ ،‬ﻣــﻲ ﺗــﻮاﻧﻴﻢ ﻣﺘــﺪ‬ ‫‪ GetPictureFolders‬را اﻳﺠﺎد ﻛﻨﻴﻢ‪ .‬ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ در ﺧﺼﻴﺼﻪ ي ‪ WebMethod‬ﻛﻪ در اﻳـﻦ ﻗـﺴﻤﺖ اﺳـﺘﻔﺎده‬ ‫ﻛﺮده اﻳﻢ‪ ،‬ﺗﻮﺿﻴﺤﺎﺗﻲ را ﻧﻴﺰ درﺑﺎره ي اﻳﻦ ﻣﺘﺪ وارد ﻛﺮدﻳﻢ‪ .‬اﻳﻦ ﺗﻮﺿﻴﺤﺎت در ﺻﻔﺤﻪ ي ‪ Service‬در زﻳﺮ ﻟﻴﻨﻚ ﻣﺮﺑـﻮط ﺑـﻪ ﻣﺘـﺪ‬ ‫‪ GetPictureFolders‬ﻧﻤﺎﻳﺶ داده ﺷﺪه و ﻣﻮﺟﺐ ﻣﻲ ﺷﻮد ﻛﻪ اﻓﺮادي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻨﺪ از اﻳﻦ ﺳـﺮوﻳﺲ اﺳـﺘﻔﺎده ﻛﻨﻨـﺪ‪،‬‬ ‫ﺑﻬﺘﺮ ﺑﺘﻮاﻧﻨﺪ ﻛﺎرﺑﺮد ﻣﺘﺪ ﻫﺎﻳﻲ ﻛﻪ در آن ﻗﺮار داده اﻳﺪ را ﻣﺘﻮﺟﻪ ﺷﻮﻧﺪ‪ .‬اوﻟـﻴﻦ ﻛـﺎري ﻛـﻪ در ﻣﺘـﺪ ‪GetPictureFolders‬‬ ‫اﻧﺠﺎم ﻣﻲ دﻫﻴﻢ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ ‪ PictureFolder‬ﻳﻚ ﺷﻴﺊ از ﻧﻮع ‪ DirectoryInfo‬ﺑﺪﺳﺖ‬ ‫آورﻳﻢ ﻛﻪ ﺑﻪ ﻓﻮﻟﺪر ‪ C:\Websites\PictureService\ Pictures‬اﺷﺎره ﻛﻨﺪ‪:‬‬ ‫‪// GetPictureFolders - return an array of the picture folders...‬‬ ‫])"‪[WebMethod(Description = "Return an array of the picture folders‬‬ ‫)(‪public String[] GetPictureFolders‬‬ ‫{‬ ‫‪// get hold of the picture folder...‬‬ ‫;‪DirectoryInfo pictureFolder = this.PictureFolder‬‬

‫ﺳﭙﺲ ﺑﺮاي ﺑﺪﺳﺖ آوردن ﻓﻮﻟﺪر ﻫﺎﻳﻲ ﻛﻪ درون ‪ Pictures‬ﻗﺮار دارﻧﺪ از ﻣﺘﺪ ‪ GetDirectories‬اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ‪.‬‬ ‫اﻳـﻦ ﻣﺘــﺪ آراﻳــﻪ اي از ﻧـﻮع ‪ DirectoryInfo‬ﺑﺮﻣــﻲ ﮔــﺮدان ﻛـﻪ ﻫــﺮ ﻳــﻚ از اﻋـﻀﺎي آن ﺑــﻪ ﻳﻜــﻲ از ﻓﻮﻟــﺪرﻫﺎي درون‬ ‫‪ Pictures‬اﺷﺎره ﻣﻲ ﻛﻨﺪ‪:‬‬ ‫‪// get the array of subfolders...‬‬ ‫= ‪DirectoryInfo[] objPictureSubFolder‬‬ ‫;)(‪pictureFolder.GetDirectories‬‬

‫‪٨٢٩‬‬

‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﭼﻨﻴﻦ آراﻳﻪ اي را اﻳﺠﺎد ﻛﺮدﻳﻢ‪ ،‬ﻣﻲ ﺗﻮاﻧﻴﻢ از ﺧﺎﺻﻴﺖ ‪ Length‬آن اﺳﺘﻔﺎده ﻛﺮده و ﺑﻔﻬﻤﻴﻢ ﻛـﻪ ﭼﻨـﺪ ﻓﻮﻟـﺪر در ﻓﻮﻟـﺪر‬ ‫‪ Pictures‬وﺟﻮد دارﻧﺪ‪ .‬ﺳﭙﺲ ﻳﻚ آراﻳﻪ ي رﺷﺘﻪ اي ﺑﻪ ﻫﻤﺎن ﻃﻮل اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﻧـﺎم ﻓﻮﻟـﺪر ﻫـﺎ را در آن ﻗـﺮار‬ ‫دﻫﻴﻢ‪:‬‬ ‫‪// create a string array to accommodate the names...‬‬ ‫;]‪String[] arrFolderNames = new String[objPictureSubFolder.Length‬‬

‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ آراﻳﻪ اﻳﺠﺎد ﺷﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﺣﻠﻘﻪ درون اﺷﻴﺎي ‪ DirectoryInfo‬ﻣﻮﺟﻮد در ﻟﻴﺴﺖ ﺣﺮﻛﺖ ﻛﺮده و ﻧﺎم ﻫـﺮ‬ ‫ﻛﺪام از آﻧﻬﺎ را در آراﻳﻪ ﻗﺮار ﻣﻲ دﻫﻴﻢ‪:‬‬ ‫‪// now, loop through the folders...‬‬ ‫;‪int intIndex = 0‬‬ ‫)‪foreach (DirectoryInfo pictureSubFolder in objPictureSubFolder‬‬ ‫{‬ ‫‪// add the name...‬‬ ‫;‪arrFolderNames[intIndex] = pictureSubFolder.Name‬‬ ‫‪// next...‬‬ ‫;‪intIndex += 1‬‬ ‫}‬

‫در آﺧﺮ ﻧﻴﺰ آراﻳﻪ اي ﻛﻪ ﺷﺎﻣﻞ ﻧﺎم ﻓﻮﻟﺪر ﻫﺎ ﺑﻮد را ﺑﺮﻣﻲ ﮔﺮداﻧﻴﻢ‪:‬‬ ‫‪// finally, return the list of names...‬‬ ‫;‪return arrFolderNames‬‬ ‫}‬

‫ﻧﻜﺘﻪ‪ :‬ﻣﻤﻜﻦ اﺳﺖ در ﺻﺤﺒﺘﻬﺎﻳﻲ ﻛﻪ ﺗﺎﻛﻨﻮن ﻛﺮده اﻳـﻢ‪ ،‬ﻣﺘﻮﺟـﻪ دو ﻧـﺎم ﻣﺘﻔـﺎوت ﺷـﺪه ﺑﺎﺷـﻴﺪ ﻛـﻪ ﻣﻔﻬـﻮم ﻳﻜـﺴﺎﻧﻲ دارﻧـﺪ‪ :‬ﻓﻮﻟـﺪر و‬ ‫داﻳﺮﻛﺘﻮري‪ .‬زﻣﺎﻧﻲ ﻛﻪ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ وﻳﻨﺪوز ‪ 95‬را ﻣﻌﺮﻓﻲ ﻛﺮد‪ ،‬ﺗﺼﻤﻴﻢ ﮔﺮﻓﺖ ﻣﻔﻬﻮﻣﻲ ﻛﻪ ﺣﺪود ﻳﻚ دﻫﻪ ﺑﺎ ﻧﺎم داﻳﺮﻛﺘﻮري ﺷﻨﺎﺧﺘﻪ ﻣﻲ‬ ‫ﺷﺪ را ﺑﺎ ﻧﺎم ﻓﻮﻟﺪر ﻋﻮض ﻛﻨﺪ‪ .‬اﻣﺎ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ در ‪ .NET‬ﻫﻤﻮاره از ﻧﺎم ‪ Directory‬اﺳﺘﻔﺎده ﻣﻲ ﺷﺪه اﺳﺖ ﻧﻪ از ﻧﺎم‬ ‫ﻓﻮﻟﺪر‪ .‬ﻣﻤﻜﻦ اﺳﺖ دﻟﻴﻞ اﻳﻦ ﻣﻮرد ﻣﻤﻜﻦ اﺳﺖ اﻳﻦ ﺑﺎﺷﺪ ﻛﻪ ﻃﺮاﺣﺎﻧﻲ ﻛﻪ در ﺗﻴﻢ ‪ .NET‬ﻓﻌﺎﻟﻴﺖ ﻣﻲ ﻛﻨﻨﺪ ﻋﻘﻴـﺪه داﺷـﺘﻪ ﺑﺎﺷـﻨﺪ ﻧـﺎم‬ ‫‪ Directory‬ﺑﻬﺘﺮ از ﻧﺎم ‪ Folder‬اﺳﺖ‪.‬‬

‫ﺑﺮﮔﺮداﻧﺪن ﻳﻚ ﺳﺎﺧﺘﺎر ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ي ﻳﻚ ﻣﺘﺪ در وب ﺳﺮوﻳﺲ‪:‬‬ ‫ﺗﺎﻛﻨﻮن ﻧﺘﻴﺠﻪ ﻫﺎﻳﻲ ﻛﻪ از ﻣﺘﺪﻫﺎي ﻳﻚ وب ﺳﺮوﻳﺲ ﺑﺮﮔﺮداﻧﺪه اﻳﻢ ﻫﻤﻪ ﺑﻪ ﺻﻮرت ﻣﺘﻐﻴﺮﻫﺎي ﺳﺎده ﻣﺎﻧﻨﺪ ﻋﺪد ﺻـﺤﻴﺢ‪ ،‬رﺷـﺘﻪ و ﻳـﺎ ‪...‬‬ ‫ﺑﻮدﻧﺪ‪ .‬اﻟﺒﺘﻪ ﻧﺤﻮه ي ﺑﺮﮔﺮداﻧﺪن آراﻳﻪ اي از اﻳﻦ ﻧﻮع ﻣﺘﻐﻴﻴﺮ ﻫﺎ را ﻧﻴﺰ در ﻗﺴﻤﺖ ﻗﺒﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ‪ .‬اﻣـﺎ در اﻳـﻦ ﻗـﺴﻤﺖ ﻣـﻲ ﺧـﻮاﻫﻴﻢ‬ ‫ﺑﺒﻴﻨﻴﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻳﻚ ﺳﺎﺧﺘﺎر داده اي را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ي ﻳﻚ ﻣﺘﺪ از وب ﺳﺮوﻳﺲ ﺑﺮﮔﺮداﻧﺪ‪.‬‬ ‫در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺧﻮاﻫﻴﻢ آراﻳﻪ اي از ﻧﺎم ﺗﺼﺎوﻳﺮي ﻛﻪ در ﻳﻚ ﻓﻮﻟﺪر وﺟﻮد دارﻧﺪ را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ از ﻳﻚ ﻣﺘﺪ ﺑﺮﮔﺮداﻧﻴﻢ‪ .‬ﺗﻔﺎوت اﻳـﻦ‬ ‫ﻣﺘﺪ ﺑﺎ ﻣﺘﺪ ﻗﺒﻠﻲ ﻛﻪ ﻧﺎم ﻓﻮﻟﺪر ﻫﺎ را ﺑﺮﻣﻲ ﮔﺮداﻧـﺪ در اﻳـﻦ اﺳـﺖ ﻛـﻪ در ﻗـﺴﻤﺖ ﻗﺒـﻞ ﻓﻘـﻂ ﻻزم ﺑـﻮد ﻛـﻪ ﻧـﺎم ﻓﻮﻟـﺪر ﻫـﺎﻳﻲ ﻛـﻪ در‬ ‫‪ Pictures‬وﺟﻮد داﺷﺘﻨﺪ را ﺑﺮﮔﺮداﻧﻴﻢ‪ ،‬اﻣﺎ در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻋﻼوه ﺑﺮ ﻧﺎم ﺗﺼﺎوﻳﺮ‪ ،‬اﻃﻼﻋﺎت زﻳـﺮ را ﻧﻴـﺰ در ﻣـﻮرد آﻧﻬـﺎ‬ ‫ﺑﺮﮔﺮداﻧﻴﻢ‪:‬‬ ‫‪٨٣٠‬‬

‫‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬

‫ﻧﺎم ﻓﺎﻳﻞ ﺗﺼﻮﻳﺮ )ﻣﺎﻧﻨﺪ ‪.(PIC00001.JPG‬‬ ‫\‪C:\Websites‬‬ ‫آدرس ﻛــﺎﻣﻠﻲ ﻛــﻪ ﺑــﻪ ﻓﺎﻳــﻞ ﻣﺮﺑــﻮط ﺑــﻪ اﻳــﻦ ﺗــﺼﻮﻳﺮ اﺷــﺎره ﻣــﻲ ﻛﻨــﺪ )ﻣﺎﻧﻨــﺪ‬ ‫‪.(PictureService\Pictures\Beach\PIC00001.JPG‬‬ ‫ﻧﺎم ﻓﻮﻟﺪري ﻛﻪ ﺣﺎوي ﺗﺼﻮﻳﺮ اﺳﺖ )ﻣﺎﻧﻨﺪ ‪.(Beach‬‬ ‫ﺣﺠﻢ ﺗﺼﻮﻳﺮ )ﻣﺎﻧﻨﺪ ‪ 26775‬ﺑﺎﻳﺖ(‪.‬‬ ‫ﺗﺎرﻳﺨﻲ ﻛﻪ ﺗﺼﻮﻳﺮ اﻳﺠﺎد ﺷﺪه اﺳﺖ )ﻣﺎﻧﻨﺪ ‪.(2006/6/26‬‬ ‫ﻓﺮﻣﺖ ﺗﺼﻮﻳﺮ )ﻣﺎﻧﻨﺪ ‪.(JPG‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬ﺑﺮﮔﺮداﻧﺪن ﻳﻚ ﺳﺎﺧﺘﺎر از ﻣﺘﺪ‬ ‫‪ (1‬ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ اﻃﻼﻋﺎت ﻻزم را ﺑﺮﮔﺮداﻧﻴﻢ‪ ،‬ﻻزم اﺳﺖ ﺳﺎﺧﺘﺎري را اﻳﺠﺎد ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ اﻃﻼﻋـﺎت ﻣـﻮرد ﻧﻈـﺮ را در آن‬ ‫ﻗﺮار دﻫﻴﻢ‪ .‬ﺑﺮاي ان ﻛﺎر ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي ‪ Solution Explorer‬روي ﻓﻮﻟﺪر ‪ App_Code‬ﻛﻠﻴـﻚ‬ ‫راﺳﺖ ﻛﺮده و از ﻣﻨﻮي ﻧﻤﺎﻳﺶ داده ﺷﺪه ﮔﺰﻳﻨﻪ ي …‪ Add New Item‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ ﺑﺎ اﺳـﺘﻔﺎده از ﻛـﺎدر‬ ‫‪ Add New Item‬ﻳﻚ ﻛﻼس ﺑﻪ ﻧﺎم ‪ PictureInfo‬ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪ .‬دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ اﻳﻦ ﻛﻼس در‬ ‫ﻓﻮﻟﺪر ‪ App_Code‬ﻗﺮار ﮔﻴـﺮد‪ .‬در اﻳـﻦ ﻗـﺴﻤﺖ ﻣـﻲ ﺧـﻮاﻫﻴﻢ ﻳـﻚ ﺳـﺎﺧﺘﺎر اﻳﺠـﺎد ﻛﻨـﻴﻢ‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ ﺗﻌﺮﻳـﻒ ﻛـﻼس‬ ‫‪ PictureInfo‬را ﻛﻪ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ وارد ﺷﺪه اﺳﺖ ﺣﺬف ﻛﺮده و آن را ﺑﺎ ﻛﺪ زﻳﺮ ﺟﺎﻳﮕﺰﻳﻦ ﻛﻨﻴﺪ‪:‬‬ ‫‪public struct PictureInfo‬‬ ‫{‬ ‫‪// members...‬‬ ‫;‪public String Name‬‬ ‫;‪public String Url‬‬ ‫;‪public String FolderName‬‬ ‫;‪public long FileSize‬‬ ‫;‪public DateTime FileDate‬‬ ‫;‪public String ImageFormat‬‬ ‫}‬

‫‪ (2‬ﺑﺮاي اﻳﻨﻜﻪ ﺑﻪ ﺗﺼﺎوﻳﺮي ﻛﻪ در ﻳﻚ ﻓﻮﻟﺪر وﺟﻮد دارﻧﺪ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ‪ ،‬ﻣﺘﺪي اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﻧﺎم ﻓﻮﻟـﺪر را ﺑـﻪ‬ ‫ﻋﻨﻮان ورودي درﻳﺎﻓﺖ ﻛﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻛﺪ زﻳﺮ را ﺑﻪ ﻛﻼس ‪ Service‬در ﻓﺎﻳﻞ ‪ Service.cs‬اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪:‬‬ ‫‪// GetPicturesInFolder - return an array of pictures from the folder...‬‬ ‫= ‪[WebMethod(Description‬‬ ‫])"‪"Return an array of pictures from the folder‬‬ ‫)‪public PictureInfo[] GetPicturesInFolder(String folderName‬‬ ‫{‬ ‫‪// get hold of the folder that we want...‬‬ ‫(‪DirectoryInfo pictureSubFolder = new DirectoryInfo‬‬ ‫;)‪PictureFolderPath + "\\" + folderName‬‬ ‫‪// we need to get the URL of the picture folder...‬‬ ‫;]"‪String pictureFolderUrl = Context.Request.ServerVariables["URL‬‬ ‫‪// manipulate the URL‬‬ ‫‪// to return an absolute URL to the Pictures folder‬‬ ‫‪pictureFolderUrl = "http://" +‬‬

‫‪٨٣١‬‬

Context.Request.ServerVariables["SERVER_NAME"] + ":" + Context.Request.ServerVariables["SERVER_PORT"] + pictureFolderUrl.Substring(0, pictureFolderUrl.LastIndexOf("/") + 1) + "Pictures"; // get the list of files in the subfolder... FileInfo[] pictureFiles = pictureSubFolder.GetFiles(); // create somewhere to put the picture infos... PictureInfo[] pictureList = new PictureInfo[pictureFiles.Length]; // loop through each picture... int intIndex = 0; foreach (FileInfo pictureFile in pictureFiles) { // create a new pictureinfo object... PictureInfo pictureInfo = new PictureInfo(); pictureInfo.Name = pictureFile.Name; pictureInfo.FolderName = folderName; pictureInfo.Url = pictureFolderUrl + "/" + folderName + "/" + pictureFile.Name; pictureInfo.FileSize = pictureFile.Length; pictureInfo.FileDate = pictureFile.LastWriteTime; pictureInfo.ImageFormat = pictureFile.Extension.Substring(1).ToUpper(); // add it to the array... pictureList[intIndex] = pictureInfo; intIndex += 1; } // return the list of pictures... return pictureList; }

‫ در اﻳــﻦ ﺻــﻔﺤﻪ روي ﻟﻴﻨــﻚ ﻣﺮﺑــﻮط ﺑــﻪ ﻣﺘــﺪ‬.‫ ﻧﻤــﺎﻳﺶ داده ﺷــﻮد‬Service ‫( ﺑﺮﻧﺎﻣــﻪ را اﺟــﺮا ﻛﻨﻴــﺪ ﺗــﺎ ﺻــﻔﺤﻪ ي‬3 ‫ ﻧﺎم ﻳﻜﻲ از ﻓﻮﻟﺪر ﻫﺎﻳﻲ ﻛﻪ‬،‫ ﻛﻠﻴﻚ ﻛﺮده و در ﺻﻔﺤﻪ ي ﻣﺮﺑﻮط ﺑﻪ ﺗﺴﺖ اﻳﻦ ﻣﺘﺪ‬GetPicturesInFolder .Beach ‫ ﻣﺎﻧﻨﺪ‬،‫اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﺪ را وارد ﻛﻨﻴﺪ‬ ‫ ﻧﻤـﺎﻳﺶ داده‬XML ‫ اﻃﻼﻋﺎﺗﻲ در ﻣﻮرد ﻧﺎم ﻓﺎﻳﻠﻬﺎي ﻣﻮﺟﻮد در ﻗﺎﻟـﺐ‬،‫ ﻛﻠﻴﻚ ﻛﻨﻴﺪ‬Invoke ‫( ﻫﻨﮕﺎﻣﻲ ﻛﻪ روي دﻛﻤﻪ ي‬4 ‫ ﺑﻨﺎﺑﺮاﻳﻦ اﻃﻼﻋﺎﺗﻲ ﻛﻪ از اﻳﻦ ﻣﺘﺪ ﺑﺮﺧﻮاﻫﺪ ﮔﺸﺖ ﻣـﺸﺎﺑﻪ‬.‫ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺣﺎوي ﺷﺶ ﻋﻜﺲ اﺳﺖ‬Beach ‫ ﻓﻮﻟﺪر‬.‫ﻣﻲ ﺷﻮد‬ :‫ اﻟﺒﺘﻪ ﻛﺪ زﻳﺮ ﺧﻼﺻﻪ ﺷﺪه ي اﻃﻼﻋﺎت ﺑﺮﮔﺸﺘﻲ اﺳﺖ‬.‫زﻳﺮ ﺧﻮاﻫﺪ ﺑﻮد‬ No (1).jpg http://localhost:2459//PictureService/Pictures/Beach/No (1).jpg Beach 63678 2004-03-20T15:27:21.620875+04:30 JPG

٨٣٢

‫>‪No (2).JPG‪Beach‪32768‪1999-11-13T12:18:46+03:30‪JPG‪
‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻧﺎم ﻓﻮﻟﺪر ﻣﻮرد ﻧﻈﺮ را ﺑﺪﺳﺖ آوردﻳﺪ‪ ،‬ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﺷﻴﺊ از ﻧﻮع ‪ DirectoryInfo‬اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ ﺑﻪ اﻳﻦ ﻓﻮﻟﺪر‬ ‫اﺷﺎره ﻛﻨﺪ‪ .‬ﺳﭙﺲ ﻣﺘﺪ ‪ GetFiles‬از اﻳﻦ ﺷﻴﺊ را ﻓﺮاﺧﻮاﻧﻲ ﻛﻨﻴﺪ ﺗﺎ ﻟﻴﺴﺘﻲ از ﻓﺎﻳﻠﻬﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻓﻮﻟﺪر را در ﻗﺎﻟﺐ ﻳﻚ آراﻳﻪ از‬ ‫اﺷــــﻴﺎﻳﻲ از ﻧــــﻮع ‪ System.IO.FileInfo‬ﺑﺮﮔﺮداﻧــــﺪ‪ .‬ﻛــــﻼس ‪ FileInfo‬ﻧﻴــــﺰ ﻫﻤﺎﻧﻨــــﺪ ﻛــــﻼس‬ ‫‪ DirectoryInfo‬اﺳﺖ‪ ،‬اﻣﺎ ﺑﻪ ﺟﺎي اﺷﺎره ﻛﺮدن ﺑﻪ ﻳﻚ ﻓﻮﻟﺪر ﺑﻪ ﻳﻚ ﻓﺎﻳﻞ اﺷﺎره ﻣﻲ ﻛﻨﺪ و اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ آن ﻓﺎﻳﻞ را‬ ‫ﺑﺮﻣﻲ ﮔﺮداﻧﺪ‪ .‬اﻟﺒﺘﻪ ﭘﺎراﻣﺘﺮي ﻛﻪ ﺑﻪ ﻣﺘﺪ ارﺳﺎل ﻣﻲ ﺷﻮد ﻣﺴﻴﺮ ﻛﺎﻣﻞ ﻓﻮﻟﺪر ﻧﻴﺴﺖ‪ ،‬ﺑﻠﻜﻪ ﻧﺎم ﻓﻮﻟﺪر اﺳﺖ و ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺴﻴﺮي ﻛﻪ ﺑﻪ‬ ‫وﺳﻴﻠﻪ ي ﺧﺎﺻﻴﺖ ‪ PictureFolderPath‬ﺑﺮﻣﻴﮕﺮدد‪ ،‬ﻣﺴﻴﺮ ﻛﺎﻣﻞ ﻓﻮﻟﺪر را اﻳﺠﺎد ﻛﺮد‪:‬‬ ‫‪// GetPicturesInFolder - return an array of pictures from the folder...‬‬ ‫= ‪[WebMethod(Description‬‬ ‫])"‪"Return an array of pictures from the folder‬‬ ‫)‪public PictureInfo[] GetPicturesInFolder(String folderName‬‬ ‫{‬ ‫‪// get hold of the folder that we want...‬‬ ‫(‪DirectoryInfo pictureSubFolder = new DirectoryInfo‬‬ ‫;)‪PictureFolderPath + "\\" + folderName‬‬

‫زﻣﺎﻧﻲ ﻛﻪ ﻛﺎرﺑﺮ ﺗﺼﺎوﻳﺮ ﺧﻮد را در اﻳﻦ ﺳﺮور ذﺧﻴﺮه ﻛﻨﺪ‪ ،‬اﻧﺘﻈﺎر ﺧﻮاﻫﺪ داﺷﺖ ﺗﺎ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ وب ﺳﺮوﻳﺲ ﺑﺘﻮاﻧﺪ آدرس اﻳﻨﺘﺮﻧﺘﻲ ﻫﺮ‬ ‫ﺗﺼﻮﻳﺮ را ﻧﻴﺰ ﺑﺪﺳﺖ آورد ﺗﺎ ﺑﺘﻮاﻧﺪ آن را ﺑﻪ وﺳﻴﻠﻪ ي ﻣﺮورﮔﺮ وب ﻣﺸﺎﻫﺪه ﻛﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻳﻜﻲ از ﻣﻘﺎدﻳﺮي ﻛﻪ ﺑﺎﻳﺪ در اﻳﻦ وب ﺳـﺮوﻳﺲ‬ ‫ﺑﺮاي ﻫﺮ ﺗﺼﻮﻳﺮ ﺑﺮﮔﺮداﻧﻴﻢ‪ ،‬آدرس ‪ URL‬ﻣﺮﺑﻮط ﺑﻪ ﻫﺮ ﺗﺼﻮﻳﺮ اﺳﺖ ﻛﻪ ﺷﺎﻣﻞ ﻧﺎم ﺳﺮور و ﻋﺒﺎرت ‪ http://‬ﻧﻴـﺰ ﺑﺎﺷـﺪ‪ .‬اﮔـﺮ ﺑـﻪ‬ ‫ﺻﻮرت ﻋﺎدي ﺑﺎ اﺳﺘﻔﺎده از ﻛﺪ زﻳﺮ از وب ﺳﺮوﻳﺲ ﺑﺨﻮاﻫﻴﻢ ﻛﻪ آدرس ﻓﺎﻳﻞ ‪ .asmx‬ﻣﺮﺑﻮط ﺑﻪ ﺧﻮد را ﺑﺮﮔﺮداﻧﺪ‪ ،‬ﻳـﻚ آدرس ‪URL‬‬ ‫ﻧﺴﺒﻲ ﻣﺎﻧﻨﺪ ‪ /PictureService/Service.asmx‬را ﺑﺮﺧﻮاﻫﺪ ﮔﺮداﻧﺪ‪:‬‬ ‫‪// we need to get the URL of the picture folder...‬‬ ‫;]"‪String pictureFolderUrl = Context.Request.ServerVariables["URL‬‬

‫ﺣﺎل ﺑﺎﻳﺪ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ آدرس ‪ URL‬ﻧـﺴﺒﻲ ﻛـﻪ در ‪ pictureFolderUrl‬وﺟـﻮد دارد‪ ،‬آدرس ‪ URL‬ﻛﺎﻣـﻞ ﻓﻮﻟـﺪر‬ ‫‪ Pictures‬را ﺑﺪﺳﺖ آورﻳﻢ‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر اﺑﺘﺪا ﻋﺒﺎرت ”‪ “http://‬را ﺑﻪ ﻫﻤﺮاه ﻧﺎم ﺳﺮوري ﻛﻪ وب ﺳﺮوﻳﺲ در آن ﻗﺮار‬ ‫دارد ﺑﻪ ﻣﺘﻐﻴﻴﺮ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ‪ Substring‬از ﻛﻼس ‪ ،String‬ﻓﻘﻂ ﻧﺎم ﻓﻮﻟﺪر اﺻﻠﻲ ﺳـﺮوﻳﺲ را‬ ‫ﺑﺪﺳﺖ آورده و ﺳﭙﺲ ﻧﺎم ﻓﻮﻟﺪر ‪ Pictures‬را در اﻧﺘﻬﺎي آن ﻗﺮار ﻣﻲ دﻫﻴﻢ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ رﺷﺘﻪ اي ﻣﺎﻧﻨﺪ زﻳﺮ اﻳﺠﺎد ﺧﻮاﻫﺪ ﺷﺪ‪:‬‬

‫‪٨٣٣‬‬

http://localhost/PictureService/Pictures // manipulate the URL // to return an absolute URL to the Pictures folder pictureFolderUrl = "http://" + Context.Request.ServerVariables["SERVER_NAME"] + ":" + Context.Request.ServerVariables["SERVER_PORT"] + pictureFolderUrl.Substring(0, pictureFolderUrl.LastIndexOf("/") + 1) + "Pictures";

:‫ ﻟﻴﺴﺘﻲ از ﻓﺎﻳﻠﻬﺎﻳﻲ اﺳﺖ ﻛﻪ ﻓﻮﻟﺪر ﻣﻮرد ﻧﻈﺮ وﺟﻮد دارد‬،‫ﻣﻮرد ﺑﻌﻀﻲ ﻛﻪ در اﻳﻦ ﻣﺘﺪ ﺑﻪ آن ﻧﻴﺎز دارﻳﻢ‬ // get the list of files in the subfolder... FileInfo[] pictureFiles = pictureSubFolder.GetFiles();

‫ اﻟﺒﺘﻪ ﺑـﻪ‬.‫ اﻳﺠﺎد ﻛﺮده و اﻃﻼﻋﺎت ﻣﻮرد ﻧﻈﺮ را در آن ﻗﺮار ﻣﻲ دﻫﻴﻢ‬PictureInfo ‫ﺳﭙﺲ ﺑﺎزاي ﻫﺮ ﻓﺎﻳﻞ ﻳﻚ ﻧﻤﻮﻧﻪ از ﺳﺎﺧﺘﺎر‬ ‫ ﻧﻴﺰ اﻳﺠﺎد ﺧﻮاﻫﺪ ﺷﺪ ﻛﻪ ﺑﺎﻳـﺪ‬PictureInfo ‫ ﭘﺲ ﭼﻨﺪﻳﻦ ﻧﻤﻮﻧﻪ از ﺳﺎﺧﺘﺎر‬،‫ﻋﻠﺖ اﻳﻨﻜﻪ ﭼﻨﺪﻳﻦ ﻓﺎﻳﻞ در اﻳﻦ ﻓﻮﻟﺪر وﺟﻮد دارﻧﺪ‬ :‫آﻧﻬﺎ را در ﻳﻚ آراﻳﻪ ﻗﺮار دﻫﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ در اﻧﺘﻬﺎ آن را از ﻣﺘﺪ ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﮔﺮداﻧﻴﻢ‬ // create somewhere to put the picture infos... PictureInfo[] pictureList = new PictureInfo[pictureFiles.Length]; // loop through each picture... int intIndex = 0; foreach (FileInfo pictureFile in pictureFiles) { // create a new pictureinfo object... PictureInfo pictureInfo = new PictureInfo(); pictureInfo.Name = pictureFile.Name; pictureInfo.FolderName = folderName; pictureInfo.Url = pictureFolderUrl + "/" + folderName + "/" + pictureFile.Name; pictureInfo.FileSize = pictureFile.Length; pictureInfo.FileDate = pictureFile.LastWriteTime; pictureInfo.ImageFormat = pictureFile.Extension.Substring(1).ToUpper();

‫ آن را در ﻣﻜﺎن ﻣﺮﺑﻮط ﺑﻪ ﺧﻮد در آراﻳﻪ ﻗﺮار ﻣـﻲ‬intIndex ‫ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﻐﻴﻴﺮ‬،‫ﻫﺮ ﺑﺎر ﻛﻪ ﻳﻚ ﺳﺎﺧﺘﺎر اﻳﺠﺎد ﺷﺪه و ﺗﻜﻤﻴﻞ ﺷﺪ‬ :‫دﻫﻴﻢ‬ // add it to the array... pictureList[intIndex] = pictureInfo; intIndex += 1; }

:‫در آﺧﺮ ﻧﻴﺰ آراﻳﻪ ي اﻳﺠﺎد ﺷﺪه را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ﺑﺮﻣﻲ ﮔﺮداﻧﻴﻢ‬ // return the list of pictures... return pictureList;

٨٣٤

‫}‬

‫ﺑﺎ اﺗﻤﺎم اﻳﻦ ﻣﺘﺪ وب ﺳﺮوﻳﺲ ﻣﻮرد ﻧﻈﺮ ﻣﺎ ﻧﻴﺰ ﻛﺎﻣﻞ ﻣﻲ ﺷﻮد‪ .‬ﺣﺎل ﺑﻬﺘﺮ اﺳﺖ ﺑﺮﻧﺎﻣﻪ اي وﻳﻨﺪوزي اﻳﺠﺎد ﻛﻨﻴﻢ و از اﻳﻦ وب ﺳﺮوﻳﺲ در‬ ‫آن ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪.‬‬

‫اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ‪:‬‬ ‫ﺗﺎﻛﻨﻮن در اﻳﻦ ﻓﺼﻞ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻳﻚ ﺻﻔﺤﻪ ي اﻳﻨﺘﺮﻧﺘﻲ را اﻳﺠﺎد ﻛﺮده و ﺑـﺎ اﺳـﺘﻔﺎده از ﺻـﻔﺤﻪ ي وﺑـﻲ ﻛـﻪ‬ ‫ﭼﺎرﭼﻮب ‪ .NET‬اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ‪ ،‬ﻋﻤﻠﻜﺮد ﻣﺘﺪﻫﺎي آن را ﺗﺴﺖ ﻛﻨﻴﻢ‪ .‬اﻣﺎ اﻳﻦ ﺻﻔﺤﻪ ي وب در ﺣﻘﻴﻘﺖ ﻳﻚ راﺑﻂ ﺗـﺴﺖ اﺳـﺖ و ﻧـﻴﻢ‬ ‫ﺗﻮان اﻧﺘﻈﺎر داﺷﺖ اﻓﺮادي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻨﺪ از اﻳﻦ ﺳﺮوﻳﺲ اﺳﺘﻔﺎده ﻛﻨﻨﺪ ﻧﻴﺰ اﻳﻦ ﺻﻔﺤﻪ را ﺑﻪ ﻛﺎر ﺑﺒﺮﻧﺪ‪.‬‬ ‫ﻫﺪف اﺻﻠﻲ وب ﺳﺮوﻳﺲ ﻫﺎ در اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺘﻮاﻧﻨﺪ ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻳﻜﭙﺎرﭼﮕﻲ اﻳﺠﺎد ﻛﻨﻨﺪ؛ ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﺮدي ﺑﺨﻮاﻫـﺪ از ﻳـﻚ‬ ‫وب ﺳﺮوﻳﺲ اﺳﺘﻔﺎده ﻛﻨﺪ‪ ،‬ﺑﺎﻳﺪ ﺑﺘﻮاﻧﺪ ﻣﺘﺪ ﻫﺎﻳﻲ ﻛﻪ در آن اﻳﺠﺎد ﺷﺪه اﻧﺪ را در ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد ﺑﻪ ﻛﺎر ﺑﺒﺮد‪.‬‬ ‫در اﻳﻦ ﻗﺴﻤﺖ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وﻳﻨﺪوز اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد ﺗﺎ ﺑﺘﻮاﻧﺪ ﻟﻴﺴﺘﻲ از ﻓﻮﻟﺪر ﻫﺎي ﻣﻮﺟﻮد در ﺳﺮور ﻛﻪ ﺣﺎوي ﺗﺼﻮﻳﺮ ﻫﺴﺘﻨﺪ را‬ ‫ﻧﻤﺎﻳﺶ دﻫﺪ‪ .‬ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي ﻫﺮ ﻛﺪام از اﻳﻦ ﻓﻮﻟﺪر ﻫﺎ‪ ،‬ﻧﺎم ﺗﻤﺎم ﺗﺼﺎوﻳﺮ ﻣﻮﺟﻮد در آن را ﻣﺸﺎﻫﺪه ﻛﻨﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ ﺑـﺎ‬ ‫ﻛﻠﻴﻚ روي ﻫﺮ ﻛﺪام از اﻳﻦ ﺗﺼﺎوﻳﺮ‪ ،‬اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﺑﺎز ﻣﻲ ﺷﻮد و ﺗﺼﻮﻳﺮ اﻧﺘﺨﺎب ﺷﺪه را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ‪.‬‬

‫‪:WSDL‬‬ ‫ﺑﺮاي اﺳﺘﻔﺎده از ﻳﻚ وب ﺳﺮوﻳﺲ‪ ،‬ﺑﺎﻳﺪ از ﺳﻨﺪي ﺑﻪ ﻧﺎم ‪ WSDL1‬اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ .‬ﺳﻨﺪ ‪ WSDL‬ﻳﻚ ﺳﻨﺪ از ﻧﻮع ‪ XML‬اﺳﺖ ﻛﻪ ﺷﺎﻣﻞ‬ ‫ﻧﺎم ﺗﻤﺎم ﻣﺘﺪﻫﺎي ﻣﻲ ﺷﻮد ﻛﻪ در وب ﺳﺮوﻳﺲ وﺟﻮد دارﻧﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﺳﻨﺪ ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ ﻛﻪ ﻫﺮ ﻣﺘﺪ ﺑﻪ ﭼـﻪ ﭘﺎراﻣﺘﺮﻫـﺎﻳﻲ و از‬ ‫ﭼﻪ ﻧﻮع اﺣﺘﻴﺎج دارد و ﻳﺎ ﻣﻘﺪاري ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﻫﺮ ﻣﺘﺪ ﺑﺮﮔﺸﺘﻪ ﻣﻲ ﺷﻮد از ﭼـﻪ ﻧـﻮﻋﻲ اﺳـﺖ‪ .‬ﺳـﻨﺪ ‪ WSDL‬ﻣـﻮرد ﻧﻴـﺎز ﺑـﺮاي وب‬ ‫ﺳﺮوﻳﺴﻲ ﻛﻪ اﻳﺠﺎد ﻛﺮده اﻳﻢ ﺑﻪ وﺳﻴﻠﻪ ي ﻛﻼس ‪ WebService‬اﻳﺠﺎد ﻣﻲ ﺷﻮد‪.‬‬

‫اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ‪:‬‬ ‫در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ﻛﻪ ﺑﺘﻮاﻧﺪ از وب ﺳﺮوﻳﺲ ﻗﺒﻠﻲ اﺳﺘﻔﺎده ﻛﻨﺪ را اﻳﺠﺎد ﻛﻨـﻴﻢ‪ .‬اﻟﺒﺘـﻪ در اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ ﺑـﺮاي‬ ‫ﻧﻤﺎﻳﺶ ﺗﺼﺎوﻳﺮ از اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﻋﺎدي )ﻫﻤﺎﻧﻨﺪ آﻧﻜﻪ در ﻓﺼﻞ دﻫﻢ‪ ،‬در ﺑﺮﻧﺎﻣﻪ ي ‪ FavoritesViewer‬ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ(‬ ‫اﺳﺘﻔﺎده ﻧﺨﻮاﻫﻴﻢ ﻛـﺮد‪ .‬ﺑﻠﻜـﻪ اﻳﻨﺘﺮﻧـﺖ اﻛـﺴﭙﻠﻮرر را ﺑـﻪ ﺧـﻮد ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ ﻣـﻲ ﻛﻨـﻴﻢ! ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﻻزم اﺳـﺖ ﻛـﻪ از ﻛﻨﺘـﺮل‬ ‫‪ Microsoft Web Browser‬در ﺟﻌﺒﻪ اﺑﺰار اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ‬ ‫‪ (1‬ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬ﻳﻚ ﭘﺮوژه ي وﻳﻨﺪوزي ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم ‪ PictureClient‬اﻳﺠﺎد ﻛﻨﻴﺪ‪.‬‬ ‫‪Web Services Description Language‬‬

‫‪1‬‬

‫‪٨٣٥‬‬

‫‪ (2‬در ﺟﻌﺒﻪ اﺑﺰار ﺑﻪ ﻗﺴﻤﺖ ‪ Common Controls‬ﺑﺮوﻳﺪ‪ .‬در آﺧﺮ اﻳﻦ ﻗﺴﻤﺖ ﻛﻨﺘﺮﻟﻲ ﺑﻪ ﻧـﺎم ‪WebBrowser‬‬ ‫وﺟﻮد دارد ﻛﻪ در ﺷﻜﻞ ‪ 4-20‬ﻧﻴﺰ ﻧﺸﺎن داده ﺷﺪه اﺳﺖ‪.‬‬

‫ﺷﻜﻞ ‪4-20‬‬ ‫‪ (3‬ﺑﺮ روي اﻳﻦ ﻛﻨﺘﺮل دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻳﻚ ﻧﻤﻮﻧﻪ از آن ﻫﻤﺎﻧﻨﺪ ﺷـﻜﻞ ‪ 5-20‬در ﻓـﺮم ﻗـﺮار ﮔﻴـﺮد‪ .‬اﻟﺒﺘـﻪ ﻻزم اﺳـﺖ ﻛـﻪ‬ ‫ﺧﺎﺻﻴﺖ ‪ Dock‬آن را ﺑﺮاﺑﺮ ‪ None‬ﻗﺮار دﻫﻴﺪ‪.‬‬ ‫‪ (4‬ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي ‪ Properties‬ﺧﺎﺻﻴﺖ ‪ Name‬اﻳـﻦ ﻛﻨﺘـﺮل را ﺑﺮاﺑـﺮ ﺑـﺎ ‪ iePicture‬ﻗـﺮار دﻫﻴـﺪ‪.‬‬ ‫ﻫﻤﭽﻨﻴﻦ ﺧﺎﺻﻴﺖ ‪ Anchor‬آن را ﻧﻴﺰ ﺑﺎ ﻣﻘﺪار ‪ Top,Right,Bottom,Left‬ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ‪.‬‬ ‫‪ (5‬در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﻨﺘﺮل‪ ،‬ﺗﺼﺎوﻳﺮي ﻛﻪ در وب ﺳﺮور وﺟﻮد دارﻧﺪ را ﻧﻤﺎﻳﺶ دﻫﻴﻢ‪ .‬اﻣﺎ ﻗﺒﻞ از اداﻣـﻪ‬ ‫ﺑﻬﺘﺮ اﺳﺖ ﻧﺤﻮه ي ﻋﻤﻠﻜﺮد اﻳﻦ ﻛﻨﺘﺮل را ﻣﺸﺎﻫﺪه ﻛﻨﻴﻢ و ﺑﺒﻴﻨﻴﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﻪ وﺳـﻴﻠﻪ ي آن از اﻣﻜﺎﻧـﺎت اﻳﻨﺘﺮﻧـﺖ‬ ‫اﻛﺴﭙﻠﻮرر در ﻳﻚ ﻓﺮم وﻳﻨﺪوزي اﺳﺘﻔﺎده ﻛﺮد‪ .‬در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑـﻮط ﺑـﻪ ‪ Form1‬روي ﻧـﻮار ﻋﻨـﻮان ﻓـﺮم دو ﺑـﺎر‬ ‫ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ‪ Load‬آن ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﺷﻮد‪ .‬ﺳﭙﺲ ﻛﺪ زﻳﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪:‬‬ ‫)‪private void Form1_Load(object sender, EventArgs e‬‬ ‫{‬ ‫‪// Set the browser to a default page...‬‬ ‫;)"‪this.iePicture.Navigate("http://www.google.com‬‬ ‫}‬

‫‪٨٣٦‬‬

‫ﺷﻜﻞ ‪5-20‬‬ ‫‪ (6‬ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ‪ .‬ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺻﻔﺤﻪ ي آﻏﺎزﻳﻦ ﮔﻮﮔﻞ در ﻓﺮم ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷـﺪ‪ .‬ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﻣﺘﻨـﻲ را‬ ‫وارد ﻛﺮده و در اﻳﻨﺘﺮﻧﺖ آن را ﺟﺴﺘﺠﻮ ﻛﻨﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺘﻮﺟﻪ ﺧﻮاﻫﻴﺪ ﺷﺪ ﻛﻪ اﻳﻦ ﻛﻨﺘﺮل ﻫﻤﺎﻧﻨﺪ اﻳﻨﺘﺮﻧـﺖ اﻛـﺴﭙﻠﻮرر ﺑـﻪ‬ ‫درﺳﺘﻲ ﻛﺎر ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﻧﻜﺘﻪ‪ :‬اﺣﺘﻤﺎﻻ ﻣﺘﻮﺟﻪ ﺷﺪه اﻳﺪ ﻛﻪ اﻳﻦ ﻛﻨﺘﺮل داراي ﻧﻮار اﺑﺰار ﻧﻴﺴﺖ و ﺑﻨﺎﺑﺮاﻳﻦ ﻧﻤﻲ ﺗﻮاﻧﻴﺪ ﺑﺴﻴﺎري از ﻛﺎرﻫﺎ را ﻣﺎﻧﻨـﺪ رﻓـﺘﻦ ﺑـﻪ ﺳـﺎﻳﺖ‬ ‫ﻗﺒﻠﻲ در آن اﻧﺠﺎم دﻫﻴﺪ‪ .‬ﺑﺮاي اﻧﺠﺎم ﻳﻚ ﺳﺮي از ﻛﺎرﻫﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮ روي ﺻﻔﺤﻪ ﻛﻠﻴﻚ ﻛﺮده و از ﻣﻨﻮﻳﻲ ﻛـﻪ ﺑـﺎز ﻣـﻲ ﺷـﻮد اﺳـﺘﻔﺎده‬ ‫ﻛﻨﻴﺪ‪.‬‬

‫اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ وب ﺳﺮوﻳﺲ ﺑﻪ ﺑﺮﻧﺎﻣﻪ‪:‬‬ ‫ﺑﺮاي اﺳﺘﻔﺎده از ﻳﻚ وب ﺳﺮوﻳﺲ ﺑﺎﻳﺪ آن را ﺑﻪ ﺻﻮرت ﻳﻚ ارﺟﺎع وب ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪ .‬در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ‪ ،‬ﺑﺎ اﻧﺠﺎم اﻳـﻦ‬ ‫ﻛﺎر از وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻛﻪ ﻳﻚ ﻛﻼس ﺑﺮاي ﻣﺎ اﻳﺠﺎد ﻛﻨﺪ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﺑﻪ وﺳـﻴﻠﻪ ي آن ﺑـﻪ ﻣﺘـﺪﻫﺎي درون وب ﺳـﺮوﻳﺲ در‬ ‫ﺑﺮﻧﺎﻣﻪ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ‪ .‬دو ﻛﻼﺳﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ اﻳﺠﺎد ﺧﻮاﻫﻨﺪ ﺷﺪ ﻋﺒﺎرﺗﻨﺪ از‪ Service :‬و ‪.PictureInfo‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ وب ﺳﺮوﻳﺲ ﺑﻪ ﺑﺮﻧﺎﻣﻪ‬ ‫‪ (1‬ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي ‪ Solution Explorer‬روي ﻧﺎم ﭘـﺮوژه ﻛﻠﻴـﻚ راﺳـﺖ ﻛـﺮده و ﮔﺰﻳﻨـﻪ ي ‪Add‬‬ ‫…‪ Web Reference‬را از ﻣﻨﻮي ﺑﺎز ﺷﺪه اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎدر ‪Add Web Reference‬‬ ‫ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪ 6-20‬ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ‪ .‬در ﻛﺎدر ﻣﻘﺎﺑﻞ ﻋﺒﺎرت ‪ URL‬آدرس وب ﺳﺮوﻳﺴﻲ ﻛﻪ در ﻗـﺴﻤﺖ ﻗﺒـﻞ اﻳﺠـﺎد‬ ‫ﻛﺮده ﺑﻮدﻳﻢ را وارد ﻛﻨﻴﺪ‪ .‬اﻳﻦ آدرس ﻣﺸﺎﺑﻪ زﻳﺮ ﺧﻮاﻫﺪ ﺑﻮد‪ .‬اﻟﺒﺘﻪ ﺑﺎﻳـﺪ ﻧـﺎم ‪ localhost‬را ﺑـﺎ ﻧـﺎم وب ﺳـﺮور ﻣـﻮرد‬ ‫اﺳﺘﻔﺎده ي ﺧﻮد و ﺷﻤﺎره ي ﭘﻮرت را ﻧﻴﺰ ﺑﺎ ﭘﻮرت ﻣﻮرد اﺳﺘﻔﺎده ﺟﺎﻳﮕﺰﻳﻦ ﻛﻨﻴﺪ‪:‬‬

‫‪٨٣٧‬‬

‫‪http://localhost:2459/PictureService/Service.asmx‬‬

‫ﺷﻜﻞ ‪6-20‬‬ ‫ﻧﻜﺘﻪ‪ :‬ﺑﺮاي اﺳﺘﻔﺎده از وب ﺳﺮوﻳﺴﻲ ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﻢ‪ ،‬ﭘﺮوژه ي آن را در ﻳﻚ ﭘﻨﺠﺮه ي ﺟﺪﻳﺪ از وﻳـﮋوال اﺳـﺘﻮدﻳﻮ‬ ‫ﺑﺎز ﻛﺮده و آن را اﺟﺮا ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ آدرﺳﻲ ﻛﻪ در ﻧﻮار آدرس اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﺑﺮاي ﺻﻔﺤﻪ ي راﺑﻂ ﺗـﺴﺖ ‪ Service‬ﻧـﺸﺎن داده‬ ‫ﻣﻲ ﺷﻮد را در ﻗﺴﻤﺖ ‪ URL‬در ﻛﺎدر ‪) Add Web Reference‬در وﻳﮋوال اﺳﺘﻮدﻳﻮ اي ﻛـﻪ ﺣـﺎوي ﭘـﺮوژه ي وﻳﻨـﺪوزي‬ ‫اﺳﺖ( وارد ﻛﻨﻴﺪ ﺗﺎ ﺻﻔﺤﻪ ي ‪ Service‬در آن ﻧﻴﺰ ﻧﻤﺎﻳﺶ داده ﺷﻮد‪.‬‬ ‫‪ (2‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺻﻔﺤﻪ ي آﻏﺎزﻳﻦ وب ﺳﺮوﻳﺲ ﺑﻪ ﻫﻤﺮاه ﻟﻴﺴﺖ ﻣﺘﺪ ﻫﺎﻳﻲ ﻛﻪ در آن ﻗـﺮار دارﻧـﺪ ﻧﻤـﺎﻳﺶ داده ﺧﻮاﻫﻨـﺪ ﺷـﺪ‪.‬‬ ‫ﺳﭙﺲ در ﻛﺎدر ‪ Web Reference Name‬ﻧﺎم ‪ PictureService‬را وارد ﻛـﺮده و روي دﻛﻤـﻪ ي‬ ‫‪ Add Reference‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪.‬‬ ‫‪ (3‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻳﻚ ارﺟﺎع ﺑﻪ ﻳﻚ وب ﺳﺮوﻳﺲ ﺑﻪ ﭘﺮوژه اﺿﺎﻓﻪ ﺧﻮاﻫﺪ ﺷﺪ و ﻣﻲ ﺗﻮاﻧﻴﺪ آن را ﻫﻤﺎﻧﻨﺪ ﺷـﻜﻞ ‪ 7-20‬در ﭘﻨﺠـﺮه‬ ‫ي ‪ Solution Explorer‬ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ‪.‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬ﻳﻚ ارﺟﺎع را ﺑﻪ ﺳﺮور ﺷـﺎﻣﻞ وب ﺳـﺮوﻳﺲ اﺿـﺎﻓﻪ ﻣـﻲ ﻛﻨـﺪ‪ .‬ﻫﻤﭽﻨـﻴﻦ ﻳـﻚ ﻛـﻼس ﺑـﻪ ﻧـﺎم‬ ‫‪ PictureService.Service‬ﻧﻴﺰ اﻳﺠﺎد ﻣﻲ ﺷﻮد ﻛﻪ ﺣﺎوي ﻣﺘﺪﻫﺎي ﻣﻮﺟﻮد در وب ﺳﺮوﻳﺲ اﺳﺖ‪ .‬ﺑﺎ اﻳﺠﺎد اﺷـﻴﺎﻳﻲ‬ ‫از ﻧﻮع اﻳﻦ ﻛﻼس ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﺘﺪ ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ وب ﺳﺮوﻳﺲ وﺟﻮد دارﻧﺪ را ﻓﺮاﺧـﻮاﻧﻲ ﻛﻨﻴـﺪ‪ .‬ﻧـﺎﻣﻲ ﻛـﻪ در ﻛـﺎدر ‪Add Web‬‬ ‫‪ Reference‬ﺑﺮاي اﻳﻦ ارﺟﺎع وارد ﻛﺮدﻳﻢ‪ ،‬در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﻋﻨﻮان ﻧﺎم ﻓﻀﺎي ﻧﺎﻣﻲ ﻛﻪ ﻛﻼس در آن ﻗﺮار ﻣﻲ ﮔﻴﺮد اﺳﺘﻔﺎده ﻣﻲ‬ ‫ﺷﻮد‪.‬‬

‫‪٨٣٨‬‬

‫ﺷﻜﻞ ‪7-20‬‬

‫ﻧﻤﺎﻳﺶ ﻟﻴﺴﺖ ﻓﻮﻟﺪر ﻫﺎ در ﺑﺮﻧﺎﻣﻪ‪:‬‬ ‫ﺗﺎ اﻳﻨﺠﺎ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺗﻤﺎم ﻣﺘﺪﻫﺎي درون وب ﺳﺮوﻳﺲ را ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده و در ﺑﺮﻧﺎﻣﻪ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪ .‬در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌـﺪ‪ ،‬ﺑـﺎ‬ ‫اﺳﺘﻔﺎده از ﻳﻚ ﻛﻨﺘﺮل ‪ ،ComboBox‬ﻟﻴﺴﺘﻲ از ﻓﻮﻟﺪرﻫﺎي ﺣﺎوي ﺗﺼﻮﻳﺮ را در ﻓﺮم ﻧﻤﺎﻳﺶ ﻣﻲ دﻫـﻴﻢ‪ .‬ﺑـﺮاي دﺳﺘﺮﺳـﻲ ﺑـﻪ ﻟﻴـﺴﺖ‬ ‫ﻓﻮﻟﺪرﻫﺎي ﻣﻮﺟﻮد ﻣﻲ ﺗﻮاﻧﻴﻢ از ﻣﺘﺪ ‪ GetPicturesFolders‬اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬ﻧﻤﺎﻳﺶ ﻟﻴﺴﺖ ﻓﻮﻟﺪرﻫﺎي ﻣﻮﺟﻮد‬ ‫‪ (1‬ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ ‪ Form1‬را ﺑﺎز ﻛﺮده و ﺳﭙﺲ ﺑﺎ اﺳـﺘﻔﺎده از ﺟﻌﺒـﻪ اﺑـﺰار ﻳـﻚ ﻛﻨﺘـﺮل ‪ ComboBox‬را‬ ‫ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪ 8-20‬در اﻳﻦ ﻓﺮم ﻗﺮار دﻫﻴﺪ‪.‬‬ ‫‪ (2‬ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي ‪ Properties‬ﺧﺎﺻﻴﺘﻬﺎي اﻳﻦ ﻛﻨﺘﺮل را ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪:‬‬ ‫‬ ‫‬ ‫‬

‫ﺧﺎﺻﻴﺖ ‪ Name‬را ﺑﺮاﺑﺮ ﺑﺎ ‪ cboFolders‬ﻗﺮار دﻫﻴﺪ‪.‬‬ ‫ﺧﺎﺻﻴﺖ ‪ DropDownStyle‬را ﺑﺮاﺑﺮ ﺑﺎ ‪ DropDownList‬ﻗﺮار دﻫﻴﺪ‪.‬‬ ‫ﺧﺎﺻﻴﺖ ‪ Anchor‬را ﺑﺮاﺑﺮ ﺑﺎ ‪ Top,Left,Right‬ﻗﺮار دﻫﻴﺪ‪.‬‬

‫‪ (3‬ﺑﺮ روي ﻧﻮار ﻋﻨﻮان ﻓﺮم دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑﻪ ﻗﺴﻤﺖ ﻣﺮﺑﻮط ﺑﻪ ﻣﺘﺪ ‪ Form1_Load‬ﺑﺮوﻳﺪ‪ .‬ﻣﻲ ﺧﻮاﻫﻴﻢ زﻣﺎﻧﻲ ﻛـﻪ‬ ‫ﺑﺮﻧﺎﻣﻪ اﺟﺮا ﻣﻲ ﺷﻮد‪ ،‬ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ‪ GetPicturesFolders‬ﻟﻴﺴﺘﻲ از ﻧﺎم ﻓﻮﻟﺪر ﻫﺎ درﻳﺎﻓﺖ ﺷﺪه و در ﻛﺎدر‬ ‫‪ cboFolders‬ﻧﻤﺎﻳﺶ داده ﺷﻮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در ﻣﺘﺪ ‪ Form1_Load‬وارد ﻛﻨﻴﺪ‪:‬‬

‫‪٨٣٩‬‬

8-20 ‫ﺷﻜﻞ‬ private void Form1_Load(object sender, EventArgs e) { // get the pictures... try { // create a connection to the service... PictureService.Service service = new PictureService.Service(); // get a list of the folders... String[] arrFolderNames; arrFolderNames = service.GetPictureFolders(); // go through the list and add each name... foreach (String strFolderName in arrFolderNames) { cboFolders.Items.Add(strFolderName); } } catch (Exception ex) { // loop through the inner exceptions... while (ex.InnerException != null) ex = ex.InnerException; // report the problem... MessageBox.Show("An exception occurred.\n" + ex.Message); } }

‫ زﻳـﺮا اوﻟـﻴﻦ ﺑـﺎر ﻓﺮاﺧـﻮاﻧﻲ‬،‫ ﺑﺮاي ﻣﺮﺗﺒﻪ ي اول ﻣﻤﻜﻦ اﺳﺖ ﻧﻤﺎﻳﺶ داده ﺷﺪن ﻓﺮم ﻣﻘﺪاري ﻃﻮل ﺑﻜﺸﺪ‬.‫( ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ‬4 ‫ اﻣﺎ ﺑﻌﺪ از اﻳﻨﻜﻪ ﻣﺘﺪ اﺟﺮا ﺷﺪ ﻣـﻲ‬.‫ﻳﻜﻲ از ﻣﺘﺪﻫﺎي ﻳﻚ وب ﺳﺮوﻳﺲ ﻣﻌﻤﻮﻻ از ﻓﺮاﺧﻮاﻧﻲ دﻓﻌﺎت ﺑﻌﺪ ﻛﻨﺪﺗﺮ ﺻﻮرت ﻣﻲ ﮔﻴﺮد‬ .‫ﺗﻮاﻧﻴﺪ ﻟﻴﺴﺘﻲ از ﻓﻮﻟﺪرﻫﺎي ﻣﻮﺟﻮد در ﺳﺮور را در ﺑﺮﻧﺎﻣﻪ ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ‬

٨٤٠

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫اﺣﺘﻤﺎﻻً ﺑﺮ ﺧﻼف ﭼﻴﺰي ﻛﻪ ﺗﺼﻮر ﻣﻲ ﻛﺮدﻳﺪ‪ ،‬زﻳﺎد ﭘﻴﭽﻴﺪه ﻧﺒﻮد! ﭼﺎرﭼﻮب ‪ .NET‬ﺑﺴﻴﺎري از ﭘﻴﭽﻴﺪﮔﻲ ﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي اﺳﺘﻔﺎده از ﻳﻚ‬ ‫وب ﺳﺮوﻳﺲ وﺟﻮد داﺷﺖ را رﻓﻊ ﻛﺮده اﺳﺖ‪.‬‬ ‫ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ‪ Load‬را ﺑﺎ اﻳﺠﺎد ﻳﻚ ﺑﻼك ‪ try…catch‬ﺷﺮوع ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﺧﻄﺎﻫﺎي اﺣﺘﻤﺎﻟﻲ را ﻛﻨﺘﺮل ﻛﻨﻴﻢ‪:‬‬ ‫)‪private void Form1_Load(object sender, EventArgs e‬‬ ‫{‬ ‫‪// get the pictures...‬‬ ‫‪try‬‬ ‫{‬

‫ﺑﻬﺘﺮ اﺳﺖ ﺣﺘﻤﺎً ﻫﻨﮕﺎم اﺳﺘﻔﺎده از ﻳﻚ وب ﺳﺮوﻳﺲ ﻛﺪ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل ﺧﻄﺎ را ﻧﻴﺰ وارد ﻛﻨﻴﺪ‪ ،‬زﻳـﺮا ﻣـﻮارد زﻳـﺎدي ﻣﻤﻜـﻦ اﺳـﺖ‬ ‫ﺑﺎﻋﺚ ﺷﻮﻧﺪ ﻛﻪ اﺳﺘﻔﺎده از ﻳﻚ وب ﺳﺮوﻳﺲ ﺑﺎ ﻣﺸﻜﻞ ﻣﻮاﺟﻪ ﺷﺪه و ﺑﺮﻧﺎﻣﻪ ﻣﺘﻮﻗﻒ ﺷﻮد‪ .‬اﮔﺮ ﻫﺮ ﻳﻚ از ﻣﺮاﺣﻞ ﻣﺘﺼﻞ ﺷﺪن ﺑﻪ ﻳﻚ وب‬ ‫ﺳﺮوﻳﺲ و ارﺳﺎل ﭘﺎراﻣﺘﺮﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺎ ﻣﺸﻜﻞ ﻣﻮاﺟﻪ ﺷﻮد‪ ،‬اﺳﺘﺜﻨﺎﻳﻲ در ﺑﺮﻧﺎﻣﻪ رخ ﻣﻲ دﻫﺪ ﻛﻪ ﺑﺎﻳﺪ آن را ﻛﻨﺘﺮل ﻛﺮد‪.‬‬ ‫در اﺑﺘﺪاي ﺑﻼك ‪ try‬ﻳﻚ ﺷﻴﺊ از ﻧﻮع ‪ PictureService.Service‬اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﻪ وﺳﻴﻠﻪ ي آن ﺑﺘـﻮاﻧﻴﻢ‬ ‫ﺑﻪ وب ﺳﺮوﻳﺲ ﻣﺘﺼﻞ ﺷﺪه و ﻣﺘﺪﻫﺎي آن را اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪ .‬اﻟﺒﺘﻪ دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﻟﺤﻈﻪ ﻫﻨﻮز ﺑﺮﻧﺎﻣﻪ ﺑﻪ وب ﺳﺮوﻳﺲ ﻣﺘﺼﻞ ﻧﺸﺪه‬ ‫اﺳﺖ‪ ،‬ﺑﻠﻜﻪ در ﺣﺎل آﻣﺎده ﺳﺎزي ﺷﺮاﻳﻂ ﺑﺮاي اﺗﺼﺎل ﺑﻪ وب ﺳﺮوﻳﺲ اﺳﺖ‪:‬‬ ‫‪// create a connection to the service...‬‬ ‫‪PictureService.Service service = new‬‬ ‫;)(‪PictureService.Service‬‬

‫زﻳﺒﺎﻳﻲ اﺳﺘﻔﺎده از وب ﺳﺮوﻳﺲ ﻫﺎ در ‪ .NET‬ﺑﻪ اﻳﻦ دﻟﻴﻞ اﺳﺖ ﻛﻪ ﻓﺮاﺧﻮاﻧﻲ ﻳﻚ ﻣﺘﺪ از وب ﺳﺮوﻳﺲ ﻫﻴﭻ ﺗﻔﺎوﺗﻲ ﺑﺎ ﻓﺮاﺧـﻮاﻧﻲ ﻳـﻚ‬ ‫ﻣﺘﺪ از ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ ﻧﺪارد‪ .‬در اﻳﻨﺠﺎ ﺑﻪ ﺳﺎدﮔﻲ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻣﺘﺪ ‪ GetPictureFolders‬را ﻓﺮاﺧﻮاﻧﻲ ﻛـﺮده و‬ ‫ﻳﻚ آراﻳﻪ از ﻧﻮع ‪ String‬را ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ درﻳﺎﻓﺖ ﻛﻨﻴﻢ‪.‬‬ ‫‪// get a list of the folders...‬‬ ‫;‪String[] arrFolderNames‬‬ ‫;)(‪arrFolderNames = service.GetPictureFolders‬‬

‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ آراﻳﻪ را از وب ﺳﺮوﻳﺲ ﺑﺪﺳﺖ آوردﻳﻢ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ اﺳـﺘﻔﺎده از ﻳـﻚ ﺣﻠﻘـﻪ ﺑـﻴﻦ ﻋﻨﺎﺻـﺮ آن ﺣﺮﻛـﺖ ﻛـﺮده و آﻧﻬـﺎ را ﺑـﻪ‬ ‫‪ ComboBox‬اﺿﺎﻓﻪ ﻛﻨﻴﻢ‪:‬‬ ‫‪// go through the list and add each name...‬‬ ‫)‪foreach (String strFolderName in arrFolderNames‬‬ ‫{‬ ‫;)‪cboFolders.Items.Add(strFolderName‬‬ ‫}‬ ‫}‬

‫اﮔﺮ ﺧﻄﺎﻳﻲ در ﺳﺮور رخ دﻫﺪ‪ .NET ،‬ﺧﻄﺎﻳﻲ را از ﻧﻮﻋﻲ ﺧﺎص ﺑﺮﻣﻲ ﮔﺮداﻧﺪ ﻛﻪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ در ﺳﺮور اﺳﺘﺜﻨﺎﻳﻲ ﺑﻪ وﺟـﻮد آﻣـﺪه‬ ‫اﺳﺖ‪ .‬ﺷﻴﺊ ﻣﺮﺑﻮط ﺑﻪ ﺧﻄﺎي اﺻﻠﻲ ﻛﻪ ﺑﺎﻳﺪ از آن اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪ ،‬در ﺧﺎﺻـﻴﺖ ‪ InnerException‬ﻗـﺮار دارد‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ اﺑﺘـﺪا‬

‫‪٨٤١‬‬

‫ﺑﺮاي ﺑﺪﺳﺖ آوردن ﺧﻄﺎي اﺻﻠﻲ‪ ،‬آﻧﻘﺪر در ﺑﻴﻦ ﺧﺎﺻﻴﺘﻬﺎي ‪ InnerException‬ﺣﺮﻛﺖ ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﻣﻘﺪار اﻳـﻦ ﺧﺎﺻـﻴﺖ در‬ ‫ﺷﻴﺊ ﺧﻄﺎﻳﻲ ﻛﻪ ﺑﺪﺳﺖ ﻣﻲ آورﻳﻢ ﺑﺮاﺑﺮ ﺑﺎ ‪ null‬ﺑﺎﺷﺪ‪ .‬ﺳﭙﺲ ﭘﻴﻐﺎم اﻳﻦ ﺧﻄﺎ را در ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻴﻢ‪.‬‬ ‫)‪catch (Exception ex‬‬ ‫{‬ ‫‪// loop through the inner exceptions...‬‬ ‫)‪while (ex.InnerException != null‬‬ ‫;‪ex = ex.InnerException‬‬ ‫‪// report the problem...‬‬ ‫;)‪MessageBox.Show("An exception occurred.\n" + ex.Message‬‬ ‫}‬ ‫}‬

‫ﻣﻲ ﺗﻮاﻧﻴﺪ ﻗﺴﻤﺖ ﻛﻨﺘﺮل ﺧﻄﺎي ﺑﺮﻧﺎﻣﻪ را ﺑﺎ ﻣﺘﻮﻗﻒ ﻛﺮدن اﺟﺮاي وب ﺳﺮوﻳﺲ ﺗﺴﺖ ﻛﻨﻴﺪ‪ .‬ﻫﻨﮕﺎﻣﻲ ﻛـﻪ اﺟـﺮاي وب ﺳـﺮوﻳﺲ ﻣﺘﻮﻗـﻒ‬ ‫ﺷﻮد ﺑﺮﻧﺎﻣﻪ ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻪ ﻣﺘﺪﻫﺎي آن دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ و ﺑﺎ ﺧﻄﺎ ﻣﻮاﺟﻪ ﻣﻲ ﺷﻮد‪ .‬ﺑﺮاي ﻣﺘﻮﻗﻒ ﻛﺮدن وب ﺳـﺮوﻳﺲ‪ ،‬اﮔـﺮ از ‪IIS‬‬ ‫اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ )ﻫﻨﮕﺎم اﻳﺠﺎد ﭘﺮوژه ﻗﺴﻤﺖ ‪ Location‬را ﺑﺮاﺑـﺮ ﺑـﺎ ‪ HTTP‬ﻗـﺮار داده اﻳـﺪ( از ﻣﻨـﻮي ‪ Start‬ﮔﺰﻳﻨـﻪ ي‬ ‫‪ Run‬را اﻧﺘﺨﺎب ﻛﺮده و در آن دﺳﺘﻮر زﻳﺮ را وارد ﻛﻨﻴﺪ‪:‬‬ ‫‪net stop iisadmin‬‬ ‫در اﻳﻦ ﺣﺎﻟﺖ ﺗﻮﺿﻴﺤﺎﺗﻲ در ﻳﻚ ﭘﻨﺠﺮه ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و در اﻧﺘﻬﺎ از ﺷﻤﺎ ﭘﺮﺳﻴﺪه ﻣﻲ ﺷﻮد ﻛﻪ آﻳﺎ ﻣﻄﻤﺌﻦ ﻫﺴﺘﻴﺪ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴـﺪ‬ ‫‪ IIS‬را ﻏﻴﺮ ﻓﻌﺎل ﻛﻨﻴﺪ؟ دﻛﻤﻪ ي ‪ Y‬و ﺳﭙﺲ ‪ Enter‬را ﻓﺸﺎر دﻫﻴﺪ ﺗﺎ ‪ IIS‬ﺧﺎﻣﻮش ﺷﻮد‪ .‬اﻣﺎ اﮔﺮ از وب ﺳـﺮور دروﻧـﻲ وﻳـﮋوال‬ ‫اﺳﺘﻮدﻳﻮ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ‪ ،‬ﺑﺮ روي آﻳﻜﻮن آن در ﻛﻨﺎر ﺳﺎﻋﺖ ﺳﻴﺴﺘﻢ ﻛﻠﻴﻚ ﻛـﺮده و در ﭘﻨﺠـﺮه اي ﻛـﻪ ﺑـﺎز ﻣـﻲ ﺷـﻮد روي دﻛﻤـﻪ ي‬ ‫‪ Stop‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﺣﺎل ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي را اﺟﺮا ﻛﻨﻴﺪ‪ .‬در اﻳﻦ ﺣﺎﻟﺖ ﭘﻴﻐﺎﻣﻲ ﻣﺸﺎﺑﻪ ﺷﻜﻞ ‪ 9-20‬ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬

‫ﺷﻜﻞ ‪9-20‬‬ ‫ﺑﺮاي ﺷﺮوع ﻣﺠﺪد ‪ IIS‬در ﭘﻨﺠﺮه ي ‪ Run‬دﺳﺘﻮر زﻳﺮ را وارد ﻛﻨﻴﺪ‪:‬‬ ‫‪net start iisadmin‬‬ ‫ﺑﺮاي اﻳﻨﻜﻪ ‪ IIS‬را ﺑﻪ ﻫﺮ دﻟﻴﻠﻲ ﻣﺠﺪداً راه اﻧﺪازي ﻛﻨﻴﺪ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ از دﺳﺘﻮر زﻳﺮ در ﭘﻨﺠﺮه ي ‪ Run‬اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪:‬‬ ‫‪iireset‬‬

‫‪٨٤٢‬‬

‫ﻧﻤﺎﻳﺶ ﻟﻴﺴﺖ ﻓﺎﻳﻠﻬﺎي ﻣﻮﺟﻮد و اﻧﺘﺨﺎب آﻧﻬﺎ‪:‬‬ ‫ﺗﺎ اﻳﻨﺠﺎ ﺗﻮاﻧﺴﺘﻴﻢ ﻛﻪ ﻟﻴﺴﺘﻲ از ﻓﻮﻟﺪرﻫﺎي ﻣﻮﺟﻮد را از ﺳﺮور درﻳﺎﻓﺖ ﻛﺮده و آﻧﻬﺎ را ﻧﻤﺎﻳﺶ دﻫﻴﻢ‪ .‬اﻣﺎ ﻻزم اﺳﺖ در ﺻﻮرﺗﻲ ﻛﻪ ﻛﺎرﺑﺮ ﻧﺎم‬ ‫ﻳﻚ ﻓﻮﻟﺪر را از اﻳﻦ ﻟﻴﺴﺖ اﻧﺘﺨﺎب ﻛﺮد‪ ،‬ﻣﺠﺪداً ﺑﻪ ﺳﺮور ﻣﺘﺼﻞ ﺷﺪه و ﻟﻴﺴﺘﻲ از ﻓﺎﻳﻠﻬﺎي درون آن ﻓﻮﻟﺪر را ﺑﺪﺳﺖ آورﻳﻢ ﺗـﺎ آﻧﻬـﺎ را در‬ ‫ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ دﻫﻴﻢ‪ .‬در ﻗﺴﻤﺖ ﺑﻌﺪ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻐﻴﻴﺮ ﺧﻮاﻫﻴﻢ داد ﺗﺎ ﺑﺘﻮاﻧﺪ ﻧﺎم ﻓﻮﻟﺪر اﻧﺘﺨـﺎب ﺷـﺪه ﺑـﻪ وﺳـﻴﻠﻪ ي ﻛـﺎرﺑﺮ را از‬ ‫‪ ComboBox‬ﺑﺪﺳﺖ آورده و ﺳﭙﺲ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ‪ GetPicturesInFolder‬از وب ﺳـﺮوﻳﺲ‪ ،‬ﻟﻴـﺴﺖ ﺗـﺼﺎوﻳﺮ‬ ‫ﻣﻮﺟﻮد در آن ﻓﻮﻟﺪر را ﺑﺪﺳﺖ آورد‪ .‬ﺳﭙﺲ اﻳﻦ ﻟﻴﺴﺖ را در ﻓﺮم ﻧﻤﺎﻳﺶ دﻫﺪ ﺗﺎ ﻛﺎرﺑﺮ ﺑﺘﻮاﻧﺪ ﺗﺼﻮﻳﺮ ﻣـﻮرد ﻧﻈـﺮ ﺧـﻮد را اﻧﺘﺨـﺎب ﻛـﺮده و‬ ‫ﻣﺸﺎﻫﺪه ﻛﻨﺪ‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬ﻧﻤﺎﻳﺶ ﻟﻴﺴﺖ ﻓﺎﻳﻠﻬﺎي ﻣﻮﺟﻮد‬ ‫‪ (1‬ﺑﺮاي ﻧﻤﺎﻳﺶ ﻟﻴﺴﺖ ﻓﺎﻳﻠﻬﺎي ﻣﻮﺟﻮد‪ ،‬ﺑﺎﻳﺪ ﺳﺎﺧﺘﺎري را ﻣﺸﺎﺑﻪ ‪ PictureInfo‬اﻳﺠﺎد ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ داده ﻫﺎﻳﻲ ﻛﻪ از‬ ‫ﻃﺮف وب ﺳﺮوﻳﺲ ﻣﻲ رﺳﻨﺪ را در اﻳﻦ ﺳﺎﺧﺘﺎر ﻗـﺮار دﻫـﻴﻢ‪.‬ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﺑـﺎ اﺳـﺘﻔﺎده از ﭘﻨﺠـﺮه ي ‪Solution‬‬ ‫‪ Explorer‬ﻛﻼس ﺟﺪﻳﺪي ﺑﻪ ﻧﺎم ‪ PictureItem‬ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را‬ ‫در اﻳﻦ ﻛﻼس وارد ﻛﻨﻴﺪ‪:‬‬ ‫‪public class PictureItem‬‬ ‫{‬ ‫;‪public PictureService.PictureInfo PicInfo‬‬ ‫‪// Constructor...‬‬ ‫)‪public PictureItem(PictureService.PictureInfo info‬‬ ‫{‬ ‫;‪PicInfo = info‬‬ ‫}‬ ‫‪// ToString - provide a better representation of the object...‬‬ ‫)(‪public override String ToString‬‬ ‫{‬ ‫;‪return PicInfo.Name‬‬ ‫}‬ ‫}‬

‫‪ (2‬ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻣﺮﺑﻮط ﺑﻪ ‪ Form1‬ﺑﺮوﻳﺪ و ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل ‪ ListBox‬ﺑﻪ ﻓـﺮم ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ‬ ‫ﻛﻨﻴــﺪ‪ .‬ﺧﺎﺻــﻴﺖ ‪ Name‬اﻳــﻦ ﻛﻨﺘــﺮل را ﺑﺮاﺑــﺮ ﺑــﺎ ‪ ،lstFiles‬ﺧﺎﺻــﻴﺖ ‪ IntegralHeight‬آن را ﺑــﻪ‬ ‫‪ False‬و ﺧﺎﺻﻴﺖ ‪ Anchor‬را ﻧﻴﺰ ﺑﻪ ‪ Top, Bottom, Left‬ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻓﺮم ﺑﺮﻧﺎﻣـﻪ‬ ‫ي ﺷﻤﺎ ﻣﺸﺎﺑﻪ ﺷﻜﻞ ‪ 10-20‬ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬ ‫‪ (3‬روي ﻛﻨﺘــــﺮل ‪ cboFolders‬در ﻓــــﺮم دو ﺑــــﺎر ﻛﻠﻴــــﻚ ﻛﻨﻴــــﺪ ﺗــــﺎ ﻣﺘــــﺪ ﻣﺮﺑــــﻮط ﺑــــﻪ روﻳــــﺪاد‬ ‫‪ SelectedIndexChanged‬اﻳﻦ ﻛﻨﺘﺮل ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﺷﻮد‪ .‬ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را‬ ‫در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ‪:‬‬

‫‪٨٤٣‬‬

10-20 ‫ﺷﻜﻞ‬ private void cboFolders_SelectedIndexChanged(object sender, EventArgs e) { // what folder did we select? String folderName = cboFolders.Items[cboFolders.SelectedIndex].ToString(); // clear the files list... lstFiles.Items.Clear(); // connect to the service again and get the files back... try { // connect... PictureService.Service service = new PictureService.Service(); // get the files back... PictureService.PictureInfo[] pictureList; pictureList = service.GetPicturesInFolder(folderName); // add the pictures to the list... foreach(PictureService.PictureInfo pictureInfo in pictureList) { // just add the name... lstFiles.Items.Add(new PictureItem(pictureInfo)); } } catch(Exception ex) { // loop through the inner exceptions... while (ex.InnerException != null) ex = ex.InnerException; // report the problem... MessageBox.Show("An exception occurred.\n" + ex.Message); }

٨٤٤

‫}‬

‫‪ (4‬ﺑﻌﺪ از اﺗﻤﺎم اﻳﻦ ﻣﺘﺪ‪ ،‬ﻣﺠﺪداً ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ ‪ Form1‬ﺑﺮﮔﺸﺘﻪ و روي ﻛﻨﺘـﺮل ‪ lstFiles‬دو ﺑـﺎر‬ ‫ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد ‪ SelectedIndexChanged‬اﻳﻦ ﻛﻨﺘﺮل ﻧﻴﺰ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد‬ ‫ﺷﻮد‪ .‬ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ‪:‬‬ ‫)‪private void lstFiles_SelectedIndexChanged(object sender, EventArgs e‬‬ ‫{‬ ‫‪// get the pictureitem...‬‬ ‫= ‪PictureItem item‬‬ ‫;]‪(PictureItem)lstFiles.Items[lstFiles.SelectedIndex‬‬ ‫)‪if (item != null‬‬ ‫{‬ ‫‪// tell ie to show the picture...‬‬ ‫;)‪iePicture.Navigate(item.PicInfo.Url‬‬ ‫}‬ ‫}‬

‫‪ (5‬ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و ﺑﻌﺪ از اﻧﺘﺨﺎب ﻳﻚ ﻓﻮﻟﺪر از ﻟﻴﺴﺖ‪ ،‬ﻓﺎﻳﻠﻲ را از ﻟﻴﺴﺖ ﺳﻤﺖ ﭼﭗ اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ در ﻓـﺮم ﻧﻤـﺎﻳﺶ داده‬ ‫ﺷﻮد‪.‬‬ ‫ﻧﻜﺘﻪ‪ :‬ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﺪ ﻓﺎﻳﻞ اﻧﺘﺨﺎب ﺷﺪه را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ‪ ،‬اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر ﻧﺒﺎﻳﺪ در ﺣﺎﻟﺖ ‪ Offline‬ﺑﺎﺷﺪ‪ .‬ﺑﺮاي ﺑﺮرﺳﻲ اﻳـﻦ‬ ‫ﻣﻮرد اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر را ﺑﺎز ﻛﺮده و از ﻣﻨﻮي ‪ File‬ﮔﺰﻳﻨﻪ ي ‪ Work Offline‬را از ﺣﺎﻟﺖ اﻧﺘﺨﺎب ﺧﺎرج ﻛﻨﻴﺪ‪ .‬ﻫﻤﭽﻨـﻴﻦ‬ ‫از ﻧـﻮار ﻣﻨـﻮي اﻳﻨﺘﺮﻧـﺖ اﻛـﺴﭙﻠﻮرر ﮔﺰﻳﻨـﻪ ي …‪ Tools  Internet Options‬را اﻧﺘﺨـﺎب ﻛـﺮده و در ﻛـﺎدر‬ ‫‪ Internet Options‬ﺑﻪ ﻗﺴﻤﺖ ‪ Connections‬ﺑﺮوﻳﺪ‪ .‬در اﻳﻦ ﻗﺴﻤﺖ ﮔﺰﻳﻨﻪ ي ‪Never dial a‬‬ ‫‪ connection‬را اﻧﺘﺨﺎب ﻛﺮده و دﻛﻤﻪ ي ‪OK‬را ﻓﺸﺎر دﻫﻴﺪ‪.‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﻛﻨﺘﺮل ‪ ListBox‬داراي ﺧﺎﺻﻴﺘﻲ ﺑﻪ ﻧﺎم ‪ Items‬اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ ﻟﻴﺴﺘﻲ از اﺷﻴﺎ از ﻧـﻮع ‪ Object‬را در ﺧـﻮد ﻧﮕﻬـﺪاري‬ ‫ﻛﻨﺪ‪ .‬اﻳﻦ ﻛﻨﺘﺮل ﺑﺮاي ﻧﻤﺎﻳﺶ آﻳﺘﻢ ﻫﺎﻳﻲ ﻛﻪ ﺑﺎﻳﺪ در ﻟﻴﺴﺖ ﻗﺮار ﺑﮕﻴﺮﻧﺪ‪ ،‬ﻣﺘﺪ ‪ ToSrting‬اﺷﻴﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻟﻴﺴﺖ وﺟﻮد دارﻧـﺪ را‬ ‫ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ‪ .‬در اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﺑﺘﺪا ﻛﻼﺳﻲ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻫﺮ ﺷﻴﺊ آن ﺑﺮاي ﻳﻜﻲ از ﺗﺼﺎوﻳﺮ ﻣﻮﺟﻮد در وب ﺳﺮور در ﻧﻈﺮ ﮔﺮﻓﺘـﻪ‬ ‫ﺷﻮد‪ .‬اﻳﻦ ﻛﻼس ﺣﺎوي ﻳﻚ ﻧﻤﻮﻧﻪ از ﺳﺎﺧﺘﺎر ‪ PictureInfo‬ﻣﻲ ﺑﺎﺷـﺪ ﻛـﻪ اﻃﻼﻋـﺎت آن ﺗـﺼﻮﻳﺮ در آن ذﺧﻴـﺮه ﻣـﻲ ﺷـﻮد‪.‬‬ ‫ﻫﻤﭽﻨﻴﻦ ﻣﺘﺪ ‪ ToString‬را ﻧﻴﺰ در اﻳﻦ ﻛﻼس ﺑﻪ ﺻﻮرﺗﻲ ‪ override‬ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻧﺎم ﻓﺎﻳﻞ ﻣﻮرد اﺳﺘﻔﺎده را ﺑﺮﮔﺮداﻧﺪ‪:‬‬ ‫‪public class PictureItem‬‬ ‫{‬ ‫;‪public PictureService.PictureInfo PicInfo‬‬ ‫‪// Constructor...‬‬ ‫)‪public PictureItem(PictureService.PictureInfo info‬‬ ‫{‬ ‫;‪PicInfo = info‬‬ ‫}‬ ‫‪// ToString - provide a better representation of the object...‬‬

‫‪٨٤٥‬‬

‫)(‪public override String ToString‬‬ ‫{‬ ‫;‪return PicInfo.Name‬‬ ‫}‬ ‫}‬

‫ﺳﭙﺲ ﺑﺎزاي ﻫﺮ ﻳﻚ ﻓﺎﻳﻠﻲ ﻛﻪ در ﺳﺮور وﺟﻮد داﺷﺘﻪ ﺑﺎﺷﺪ‪ ،‬ﻳﻚ ﺷﻴﺊ از اﻳﻦ ﻛﻼس اﻳﺠﺎد ﻛﺮده و آن را ﺑـﻪ ﻟﻴـﺴﺖ اﺿـﺎﻓﻪ ﻣـﻲ ﻛﻨـﻴﻢ‪.‬‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﻨﺘﺮل ‪ ListBox‬ﺑﺨﻮاﻫﺪ آﻳﺘﻢ ﻫﺎي درون ﺧﻮد را ﻧﻤﺎﻳﺶ دﻫﺪ‪ ،‬ﻣﺘﺪ ‪ ToString‬اﻳﻦ اﺷﻴﺎ را ﻓﺮاﺧـﻮاﻧﻲ ﻛـﺮده و‬ ‫اﻳﻦ ﻣﺘﺪ ﻫﻢ ﻧﺎم ﻓﺎﻳﻞ را ﺑﺮﻣﻲ ﮔﺮداﻧﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴـﺐ ﻧـﺎم ﻓﺎﻳﻠﻬـﺎ در ﻟﻴـﺴﺖ ﻧﻤـﺎﻳﺶ داده ﻣـﻲ ﺷـﻮد‪ .‬ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﺎ ﺗﻐﻴﻴـﺮ دادن ﻣﺘـﺪ‬ ‫‪ ،ToString‬ﻋﻼوه ﺑﺮ ﻧﺎم آدرس ﻓﺎﻳﻠﻬﺎ را ﻧﻴﺰ در ﻟﻴﺴﺖ ﻧﻤﺎﻳﺶ دﻫﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻟﻴﺴﺖ ﺷﺎﻣﻞ ﻧﺎم و ‪ URL‬ﺗﺼﺎوﻳﺮ ﻣﻮﺟﻮد در‬ ‫وب ﺳﺮور ﺧﻮاﻫﺪ ﺑﻮد‪.‬‬ ‫دﻗﺖ ﻛﻨﻴﺪ اﺷﻴﺎي ‪ PictureInfo‬اي ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ وﺟـﻮد دارﻧـﺪ‪ ،‬ﺑـﺎ اﺷـﻴﺎي ‪ PictureInfo‬اي ﻛـﻪ در‬ ‫ﺳﺮور وﺟﻮد دارﻧﺪ ﺑﺮاﺑﺮ ﻧﻴﺴﺘﻨﺪ‪ .‬وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬ﺑـﺮ اﺳـﺎس اﻃﻼﻋـﺎﺗﻲ ﻛـﻪ در ﻓﺎﻳـﻞ ‪ WSDL‬وﺟـﻮد داﺷـﺖ‪ ،‬ﻛﻼﺳـﻲ ﺑـﻪ ﻧـﺎم‬ ‫‪ PictureInfo‬در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﺮده اﺳﺖ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ از آن اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪ ،‬دﻗﻴﻘﺎً ﻣﺸﺎﺑﻪ ﻛﻼس ‪ Service‬ﻛﻪ ﺑـﻪ ﺻـﻮرت‬ ‫اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﻛﺮده اﺳﺖ‪ .‬ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ اﺳﺖ ﻛﻪ ‪ PictureInfo‬در ﺳﺮور ﻳﻚ ﺳﺎﺧﺘﺎر اﺳﺖ‪ ،‬اﻣﺎ در ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨـﺖ ﺑـﻪ‬ ‫ﺻﻮرت ﻳﻚ ﻛﻼس ﺗﻌﺮﻳﻒ ﺷﺪه اﺳﺖ‪.‬‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎرﺑﺮ ﻓﻮﻟﺪر اﻧﺘﺨﺎﺑﻲ ﺧﻮد را در ‪ ComboBox‬ﺗﻐﻴﻴﺮ داد‪ ،‬اﺑﺘﺪا ﻧﺎم آﻳﺘﻤﻲ ﻛﻪ اﻧﺘﺨﺎب ﻛﺮده اﺳﺖ را ﺑﺪﺳﺖ آورده و ﺳـﭙﺲ‬ ‫ﻟﻴﺴﺖ ﻣﻮﺟﻮد در ‪ ListBox‬را ﭘﺎك ﻣﻲ ﻛﻨﻴﻢ‪:‬‬ ‫‪private void cboFolders_SelectedIndexChanged(object sender,‬‬ ‫)‪EventArgs e‬‬ ‫{‬ ‫?‪// what folder did we select‬‬ ‫= ‪String folderName‬‬ ‫;)(‪cboFolders.Items[cboFolders.SelectedIndex].ToString‬‬ ‫‪// clear the files list...‬‬ ‫;)(‪lstFiles.Items.Clear‬‬

‫ﺳﭙﺲ ﻳﻚ ﺑﻼك ‪ try…catch‬اﻳﺠﺎد ﻛﺮده و ﺑﻘﻴﻪ ي ﻛﺪﻫﺎ را در آن ﻗﺮار ﻣﻲ دﻫﻴﻢ ﺗﺎ در ﺻﻮرت ﺑﺮوز ﺧﻄﺎ ﺑﺘﻮاﻧﻴﻢ آن را ﻛﻨﺘـﺮل‬ ‫ﻛﻨﻴﻢ‪:‬‬ ‫‪// connect to the service again and get the files back...‬‬ ‫‪try‬‬ ‫{‬

‫ﺑﺮاي ﻣﺘﺼﻞ ﺷﺪن ﺑﻪ ﺳﺮور و اﺳﺘﻔﺎده از ﻣﺘﺪﻫﺎي آن ﻛﺎﻓﻲ اﺳﺖ ﻳﻚ ﻧﻤﻮﻧﻪ از ﻛﻼس ‪ Service‬اﻳﺠﺎد ﻛﻨﻴﻢ‪:‬‬ ‫‪// connect...‬‬ ‫‪PictureService.Service service = new‬‬ ‫;)(‪PictureService.Service‬‬

‫ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ ‪ GetPicturesInFolder‬و ارﺳﺎل ﻧﺎم ﻓﻮﻟﺪري ﻛﻪ ﻛﺎرﺑﺮ اﻧﺘﺨﺎب ﻛﺮده اﺳﺖ ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ‪ ،‬ﻟﻴـﺴﺘﻲ‬ ‫از ﺗﺼﺎوﻳﺮي ﻛﻪ در آن ﻓﻮﻟﺪر وﺟﻮد دارد را ﺑﻪ ﺻﻮرت آراﻳﻪ اي از ﻧﻮع ‪ PictureInfo‬درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﻴﻢ‪ .‬اﮔـﺮ ﻓﻮﻟـﺪر در ﺳـﺮور‬

‫‪٨٤٦‬‬

‫ اﻳﻦ اﺳﺘﺜﻨﺎ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ﻣﻲ آﻳﺪ و در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ‬.‫ ﺳﺮوﻳﺲ ﻳﻚ اﺳﺘﺜﻨﺎ اﻳﺠﺎد ﻛﺮده و آن را ﭘﺮﺗﺎب ﻣﻲ ﻛﻨﺪ‬،‫وﺟﻮد ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ‬ :‫ درﻳﺎﻓﺖ ﺷﺪه و ﭘﻴﻐﺎم ﻣﻨﺎﺳﺒﻲ ﺑﺮاي آن ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد‬catch ‫وﺳﻴﻠﻪ ي ﺑﻼك‬ // get the files back... PictureService.PictureInfo[] pictureList; pictureList = service.GetPicturesInFolder(folderName);

‫ در ﺑﻴﻦ ﺗﻤﺎم ﻋﻨﺎﺻﺮ‬for ‫ را ﺑﺪﺳﺖ آوردﻳﻢ ﻣﻲ ﺗﻮاﻧﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﺣﻠﻘﻪ ي‬PictureInfo ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ آراﻳﻪ ي ﺷﺎﻣﻞ‬ .‫ ﻗﺮار دﻫﻴﻢ‬ListBox ‫ اﻳﺠﺎد ﻛﻨﻴﻢ و در‬PictureItem ‫ ﺑﺎزاي ﻫﺮ ﻳﻚ ﺗﺼﻮﻳﺮ ﻳﻚ ﺷﻴﺊ از ﻧﻮع‬،‫آن ﺣﺮﻛﺖ ﻛﺮده‬ 

// add the pictures to the list... foreach(PictureService.PictureInfo pictureInfo in pictureList) { // just add the name... lstFiles.Items.Add(new PictureItem(pictureInfo)); } } catch(Exception ex) { // loop through the inner exceptions... while (ex.InnerException != null) ex = ex.InnerException; // report the problem... MessageBox.Show("An exception occurred.\n" + ex.Message); }

}

‫ ﺧﻮاﻫـﺪ‬PictureItem ‫ اﻳﻦ آﻳﺘﻢ ﺣﺎوي ﻳﻚ ﺷﻴﺊ از ﻛﻼس‬،‫ را ﺗﻐﻴﻴﺮ دادﻳﻢ‬ListBox ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ آﻳﺘﻢ اﻧﺘﺨﺎب ﺷﺪه در‬ ‫اﻳﻲ ﻛﻪ از ﻃـﺮف ﺳـﺮور ﺑـﺮاي‬PictureInfo ‫ اﻳﻦ ﺷﻴﺊ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ ﺗﺎ ﺑﻪ ﺷﻴﺊ‬PicInfo ‫ ﺑﻨﺎﺑﺮاﻳﻦ از ﺧﺎﺻﻴﺖ‬.‫ﺑﻮد‬ ‫ آدرس ﺗـﺼﻮﻳﺮ در ﺳـﺮور را ﺑﺪﺳـﺖ‬،‫ اﻳﻦ ﺷﻴﺊ‬Url ‫ ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺎﺻﻴﺖ‬.‫اﻳﻦ ﺗﺼﻮﻳﺮ ﻓﺮﺳﺘﺎده ﺷﺪه ﺑﻮد دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ‬ ‫ اﻟﺒﺘﻪ ﻗﺒﻞ از ﻫﺮ ﭼﻴﺰ ﺑﺮرﺳﻲ‬.‫اي ﻛﻪ در ﻓﺮم ﻗﺮار داده اﻳﻢ ﻧﻤﺎﻳﺶ ﺧﻮاﻫﻴﻢ داد‬Web Browser ‫آورده و آن را ﺑﺎ اﺳﺘﻔﺎده از ﻛﻨﺘﺮل‬ :‫ زﻳﺮا در اﻳﻦ ﺻﻮرت ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﻳﻚ اﺳﺘﺜﻨﺎ ﻣﻮاﺟﻪ ﺧﻮاﻫﺪ ﺷﺪ‬،‫ ﻧﺒﺎﺷﺪ‬null ‫ ﺑﺮاﺑﺮ ﺑﺎ‬item ‫ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ ﻣﻘﺪار‬ private void lstFiles_SelectedIndexChanged(object sender, EventArgs e) { // get the pictureitem... PictureItem item = (PictureItem)lstFiles.Items[lstFiles.SelectedIndex]; if (item != null) { // tell ie to show the picture... iePicture.Navigate(item.PicInfo.Url); } }

٨٤٧

‫‪:.NET Remoting‬‬ ‫‪ .NET Remoting‬ﻧﻴﺰ ﻣﺎﻧﻨﺪ وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﺮاي اﺗـﺼﺎل ﺑـﻪ ﻳـﻚ ﺳـﺮوﻳﺲ در ﻣﺤﻠـﻲ دﻳﮕـﺮ )در ﻫﻤـﺎن ﻛـﺎﻣﭙﻴﻮﺗﺮ و ﻳـﺎ‬ ‫ﻛﺎﻣﭙﻴﻮﺗﺮي دﻳﮕﺮ( ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد‪ .‬ﻫﻤﭽﻨﻴﻦ ‪ .NET Remoting‬از ﭘﺮوﺗﻜـﻞ اﺳـﺘﺎﻧﺪارد ‪ SOAP‬ﺑـﺮاي ﺑﺮﻗـﺮاري‬ ‫ارﺗﺒﺎط اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ ﻛﻪ ﭘﺮوﺗﻜﻞ اﺳﺘﺎﻧﺪارد ﻣﻮرد اﺳﺘﻔﺎده ﺑﻪ وﺳﻴﻠﻪ ي وب ﺳﺮوﻳﺲ ﻫـﺎ ﻧﻴـﺰ ﺑـﻪ ﺷـﻤﺎر ﻣـﻲ رود‪ .‬از اﻳـﻦ ﭼﻨـﺪ ﺟﻨﺒـﻪ‪،‬‬ ‫‪ .NET Remoting‬و وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﺴﻴﺎر ﻣﺸﺎﺑﻪ ﻳﻜﺪﻳﮕﺮ ﻫﺴﺘﻨﺪ‪.‬‬ ‫ﺗﻔﺎوت ‪ .NET Remoting‬ﺑﺎ وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﻪ ﺻﻮرت ﻋﻤﺪه ﺑﻪ اﻳﻦ دﻟﻴﻞ اﺳـﺖ ﻛـﻪ در ‪ .NET Remoting‬ﻣـﻲ‬ ‫ﺗﻮاﻧﻴﺪ از ﻛﺎﻧﺎﻟﻬﺎي ‪ TCP1‬ﻧﻴﺰ ﺑﺮاي اﻧﺘﻘﺎل اﻃﻼﻋﺎت اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ .‬ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻛﺎﻧﺎﻟﻬﺎ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺮ اﻳﻨﻜﻪ ﭼﻪ داده ﻫﺎي ﻣﻨﺘﻘﻞ‬ ‫ﻣﻲ ﺷﻮﻧﺪ و ﻳﺎ ﭼﮕﻮﻧﻪ ﻣﻨﺘﻘﻞ ﻣﻲ ﺷﻮﻧﺪ‪ ،‬ﻛﻨﺘﺮل ﻛﺎﻣﻞ داﺷﺘﻪ ﺑﺎﺷﻴﺪ‪ .‬ﻫﻤﭽﻨـﻴﻦ داده ﻫـﺎ در ‪ .NET Remoting‬ﻣـﻲ ﺗﻮاﻧﻨـﺪ ﺑـﻪ‬ ‫ﺻﻮرت ﺑﺎﻳﻨﺮي ﺑﺎﺷﻨﺪ و ﻣﺎﻧﻨﺪ وب ﺳﺮوﻳﺲ ﻫﺎ ﻻزم ﻧﻴﺴﺖ ﻛﻪ ﺣﺘﻤﺎً در ﻗﺎﻟﺐ ﻣﺘﻦ ﺑﺎﺷﻨﺪ‪ .‬از ﺑﻌﻀﻲ ﺟﻨﺒﻪ ﻫﺎ ‪.NET Remoting‬‬ ‫ﺑﺴﻴﺎر اﻧﻌﻄﺎف ﭘﺬﻳﺮ ﺗﺮ از وب ﺳﺮوﻳﺲ ﻫﺎ ﻋﻤﻞ ﻣﻲ ﻛﻨﺪ‪ ،‬اﻣﺎ ﻫﻴﭽﮕﺎه ﻧﻤﻲ ﺗﻮاﻧﺪ ﺟﺎي وب ﺳﺮوﻳﺲ ﻫﺎ را ﺑﮕﻴﺮد‪ .‬زﻳﺮا ﻫﻤﺎﻧﻄﻮر ﻛـﻪ ﮔﻔـﺘﻢ‬ ‫وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﺮ ﭘﺎﻳﻪ ي اﺳﺘﺎﻧﺪاردﻫﺎي آزاد ﻫﺴﺘﻨﺪ و ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي ﺑﺮﻗﺮاري ارﺗﺒﺎط ﺑﻴﻦ ﻧﺮم اﻓﺰارﻫﺎي ﻃﺮاﺣﻲ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي ﭘﻠـﺖ‬ ‫ﻓﺮﻣﻬﺎي ﮔﻮﻧﺎﮔﻮن ﺑﻪ ﻛﺎر ﻣﻲ روﻧﺪ‪ .NET Remoting .‬ﺑﻴﺸﺘﺮ در ﭘﻠﺖ ﻓﺮم ‪ .NET‬ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣـﻲ ﮔﻴـﺮد‪ ،‬اﻣـﺎ داراي‬ ‫اﻧﻌﻄﺎف ﭘﺬﻳﺮي ﺑﻴﺸﺘﺮي ﻧﺴﺒﺖ ﺑﻪ وب ﺳﺮوﻳﺲ ﻫﺎ اﺳﺖ‪.‬‬ ‫ﺑﻪ دﻟﻴﻞ اﻳﻨﻜﻪ اﻳﻦ ﻛﺘﺎب‪ ،‬ﻳﻚ ﻛﺘﺎب ﻣﺒﺘﺪي اﺳﺖ‪ ،‬ﻧﻤﻲ ﺧﻮاﻫﻴﻢ وارد ﺟﺰﺋﻴﺎت اﺳﺘﻔﺎده و ﻛﺎرﻛﺮد ‪ .NET Remoting‬ﺷﻮﻳﻢ‪ ،‬اﻣﺎ‬ ‫در ﻫﺮ ﺻﻮرت ﺑﺎﻳﺪ ﭼﻨﺪ ﻧﻜﺘﻪ را در اﻳﻦ ﻣﻮرد ﺑﺪاﻧﻴﺪ‪.‬‬ ‫‪2‬‬ ‫ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﻣﻔﺎﻫﻴﻢ ﻣﻮﺟﻮد در ‪ .NET Remoting‬ﻫﺪاﻳﺖ ﻛﺮدن اﺷﻴﺎ از ﻳﻚ ﭘﺮدازش )ﺑﺮﻧﺎﻣـﻪ( ﺑـﻪ ﭘـﺮدازش دﻳﮕـﺮ ﻳـﺎ‬ ‫ﻣﺎرﺷﺎﻟﻴﻨﮓ اﺳﺖ‪ .‬ﻫﻤﭽﻨﻴﻦ ﻳﻚ ﺷﻴﺊ ﻣﻲ ﺗﻮاﻧﺪ از ﻳﻚ ﺑﺮﻧﺎﻣﻪ در ﻳﻚ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ در ﻳـﻚ ﻛـﺎﻣﭙﻴﻮﺗﺮ دﻳﮕـﺮ ﻣﻨﺘﻘـﻞ ﺷـﻮد‪.‬‬ ‫ﻣﺎرﺷﺎﻟﻴﻨﮓ در ‪ .NET Remoting‬از ﭼﻨﺎن اﻫﻤﻴﺘﻲ ﺑﺮﺧﻮردار اﺳﺖ ﻛﻪ ﻫﺮ ﺷﻴﺊ اي ﻛﻪ ﺑﺨﻮاﻫﺪ در ﺑﻴﻦ ﭘﺮدازش ﻫﺎ ﺟﺎ ﺑـﻪ ﺟـﺎ‬ ‫ﺷــﻮد )ﺑــﺮاي ﻣﺜــﺎل از ﻳــﻚ ﺑﺮﻧﺎﻣــﻪ در ﻳــﻚ ﻛــﺎﻣﭙﻴﻮﺗﺮ‪ ،‬ﺑــﻪ ﺑﺮﻧﺎﻣــﻪ اي دﻳﮕــﺮ در ﻛــﺎﻣﭙﻴﻮﺗﺮي دﻳﮕــﺮ ﻣﻨﺘﻘــﻞ ﺷــﻮد( ﺑﺎﻳــﺪ از ﻛــﻼس‬ ‫‪ MarshByRefObject‬ﻣﺸﺘﻖ ﺷﺪه ﺑﺎﺷﺪ‪.‬‬ ‫ﻣﻔﻬﻮم ﻣﻬﻢ دﻳﮕﺮي ﻛﻪ ﺑﺎﻳﺪ ﺑﺎ آن آﺷﻨﺎ ﺷﻮﻳﺪ‪ ،‬ﺗﻔﺎوﺗﻲ اﺳﺖ ﻛﻪ ﺑﻴﻦ ﺳﺮور و ﻛﻼﻳﻨﺖ در ‪ .NET Remoting‬وﺟـﻮد دارد‪ .‬ﻳـﻚ‬ ‫ﺳﺮور ﻣﻌﻤﻮﻻً ﺑﻪ ﺑﺮﻧﺎﻣﻪ اي ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد ﻛﻪ ﻳﻚ ﻛﻼس را در ﻳﻚ ﻛﺎﻧﺎل و ﻳﻚ ﭘﻮرت ﺧﺎص ﺛﺒﺖ ﻣﻲ ﻛﻨﺪ‪ .‬ﻛﻼﻳﻨﺖ ﻧﻴﺰ ﺑﺮﻧﺎﻣـﻪ اي‬ ‫اﺳﺖ ﻛﻪ ﺗﻘﺎﺿﺎﻳﻲ را ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﻧﻤﻮﻧﻪ از آن ﺷﻴﺊ‪ ،‬ﺑﻪ آن ﻛﺎﻧﺎل و آن ﭘﻮرت ﻣﻲ ﻓﺮﺳﺘﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺳﺮور ﻳﻚ ﻧﻤﻮﻧﻪ از ﻛﻼﺳـﻲ‬ ‫ﻛﻪ در آن ﻛﺎﻧﺎل و ﭘﻮرت ﺛﺒﺖ ﺷﺪه اﺳﺖ را اﻳﺠﺎد ﻛﺮده و آن را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ارﺳﺎل ﻣﻲ ﻛﻨﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﻌﺪ از اﻳﻨﻜـﻪ ﺑﺮﻧﺎﻣـﻪ‬ ‫ي ﻛﻼﻳﻨﺖ ﻣﺘﻮﺟﻪ ﺷﺪ ﻛﻪ ﻛﻼس ﻣﻮرد ﻧﻈﺮ او در ﭼﻪ ﻛﺎﻧﺎل و ﭼﻪ ﭘﻮرﺗﻲ ﻗﺮار دارد‪ ،‬ﺗﻘﺎﺿﺎﻳﻲ را اﻳﺠﺎد ﻛـﺮده و آن را ﺑـﻪ آن ﻛﺎﻧـﺎل و آن‬ ‫ﭘﻮرت ارﺳﺎل ﻣﻲ ﻛﻨﺪ‪ .‬ﺑﺮﻧﺎﻣﻪ ي ﺳﺮور ﻧﻴﺰ ﺑﺮ ﺣﺴﺐ اﻳﻨﻜﻪ ﺗﻘﺎﺿﺎ ﺑﻪ ﭼﻪ ﻛﺎﻧﺎل و ﭼﻪ ﭘﻮرﺗﻲ ارﺳﺎل ﺷﺪه اﺳﺖ‪ ،‬ﻳـﻚ ﺷـﻴﺊ از آن ﻛـﻼس‬ ‫اﻳﺠﺎد ﻛﺮده و آن را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ﻣﻲ ﻓﺮﺳﺘﺪ‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ از اﻳﻦ ﺗﻮﺿﻴﺤﺎت ﻧﻴﺰ ﻣﺸﺨﺺ اﺳﺖ‪ ،‬در اﻳﻦ روش ﺳـﺮور و ﻛﻼﻳﻨـﺖ‬ ‫ﺑﺎﻳﺪ از ﻳﻚ ﻛﺎﻧﺎل و ﻳﻚ ﭘﻮرت ﺑﺎ ﻳﻜﺪﻳﮕﺮ ارﺗﺒﺎط داﺷﺘﻪ ﺑﺎﺷﻨﺪ‪ .‬در ‪ .NET Remoting‬ﺑـﺮاي اﻧﺠـﺎم اﻳـﻦ ﻛـﺎر از ‪ URI3‬ﺑـﻪ‬ ‫ﺻﻮرت زﻳﺮ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد‪:‬‬ ‫>‪://<machine>:<portnumber>/
‫‪Transmission Control Protocol‬‬ ‫‪Process‬‬ ‫‪3‬‬ ‫‪Uniform Resource Identifier‬‬ ‫‪2‬‬

‫‪٨٤٨‬‬

‫‪tcp://maincpu:8000/MyPongEngine‬‬ ‫اﻣﺎ اﮔﺮ ﺑﺨﻮاﻫﻴﻢ ﺑﺮاي اﻧﺘﻘﺎل اﻃﻼﻋﺎت از ‪ HTTP‬اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪ ،‬ﻣﻲ ﺗﻮاﻧﻴﻢ ‪ URI‬زﻳﺮ را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﻢ‪:‬‬ ‫‪http://maincpu:8000/MyPongEngine‬‬ ‫ﺷﻤﺎره ي ﭘﻮرﺗﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد ﻣﻲ ﺗﻮاﻧﺪ ﻫﺮ ﭼﻴﺰي ﺑﺎﺷﺪ‪ ،‬ﻓﻘﻂ ﺳﺮور و ﻛﻼﻳﻨﺖ ﻫﺮ دو ﺑﺎﻳﺪ آن را ﺑﺪاﻧﻨﺪ‬ ‫ﺗﺎ ﺑﺘﻮاﻧﻨﺪ از ﻃﺮﻳﻖ آن ﭘﻮرت ﺑﺎ ﻳﻜﺪﻳﮕﺮ ارﺗﺒﺎط داﺷﺘﻪ ﺑﺎﺷﻨﺪ‪.‬‬ ‫ﻧﺤﻮه ي اﺳﺘﻔﺎده از اﻳﻦ ﻣﻮارد را ﺑﻪ زودي در ﻋﻤﻞ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد‪ .‬ﺑﺪون اﻳﻨﻜﻪ ﺑﻴﺸﺘﺮ از اﻳﻦ وارد ﻣﺒﺎﺣﺚ ﺗﺌﻮري در ﻣﻮرد ‪.NET‬‬ ‫‪ Remoting‬ﺷﻮﻳﻢ‪ ،‬در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﺳﻌﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد ﻛﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺳﺎده ﻛﻪ از آن اﺳﺘﻔﺎده ﻛﻨﺪ را اﻳﺠـﺎد ﻛﻨـﻴﻢ‪.‬‬ ‫در ﺷﻜﻞ ‪ 11-20‬ﻣﻌﻤﺎري ﻛﻠﻲ ‪ .NET Remoting‬ﻧﻤﺎﻳﺶ داده ﺷﺪه اﺳﺖ‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ در اﻳﻦ ﺷـﻜﻞ ﻧﻴـﺰ ﻣـﺸﺨﺺ اﺳـﺖ‪،‬‬ ‫‪ .NET Remoting‬ﺑﻪ ﻳﻚ ﺳﺮور و ﻳﻚ ﻛﻼﻳﻨﺖ ﻧﻴﺎز دارد‪ ،‬ﻛﻪ در اﻳﻦ ﻣﺜﺎل اﺑﺘﺪا ﺑﺮﻧﺎﻣﻪ ي ﺳﺮور را اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد‪.‬‬

‫ﺷﻜﻞ ‪11-20‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﻳﺠﺎد ﺳﺮور ‪ Pong‬و ﺑﺮﻧﺎﻣﻪ ي ‪PongEngine‬‬ ‫‪(1‬‬ ‫‪(2‬‬ ‫‪(3‬‬

‫‪(4‬‬

‫ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﻚ ﭘﺮوژه ي ﺟﺪﻳﺪ از ﻧﻮع ‪ Class Library‬ﺑﻪ ﻧـﺎم ‪ PongEngine‬اﻳﺠـﺎد‬ ‫ﻛﻨﻴﺪ‪.‬‬ ‫ﻧﺎم ﻓﺎﻳﻞ ‪ Class1.cs‬ﻛﻪ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ اﻳﺠﺎد ﻣﻲ ﺷﻮد را ﺑﻪ ﻓﺎﻳﻞ ‪ Pinger.cs‬ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪.‬‬ ‫ﺑﺮﻧﺎﻣـﻪ را ذﺧﻴـﺮه ﻛﻨﻴـﺪ و ﺳـﭙﺲ ﻳـﻚ ﭘـﺮوژه ي دﻳﮕـﺮ ﻧﻴـﺰ از ﻧـﻮع ‪ Console Application‬ﺑـﻪ ﻧـﺎم‬ ‫‪ PongServer‬ﺑــﻪ اﻳــﻦ ‪ Solution‬اﺿــﺎﻓﻪ ﻛﻨﻴــﺪ‪ .‬ﺑــﺮاي اﺿــﺎﻓﻪ ﻛــﺮدن ﻳــﻚ ﭘــﺮوژه ي ﺟﺪﻳــﺪ ﺑــﻪ ﻫﻤــﻴﻦ‬ ‫‪ Solution‬ﻣـﻲ ﺗﻮاﻧﻴـﺪ از ﻧـﻮار ﻣﻨـﻮي وﻳـﮋوال اﺳـﺘﻮدﻳﻮ ﮔﺰﻳﻨـﻪ ي ‪File  Add  New‬‬ ‫…‪ Project‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪.‬‬ ‫ﺣﺎل ﺑﺎﻳﺪ دو ارﺟﺎع ﺑﻪ ﭘﺮوژه ي ‪ PongServer‬اﻳﺠﺎد ﻛﻨﻴﺪ )دﻳﺎﮔﺮام ﺷﻜﻞ ‪ 12-20‬را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ(‪ .‬ﺑﺮاي اﻳـﻦ ﻛـﺎر‬ ‫در ﭘﻨﺠﺮه ي ‪ Solution Explorer‬روي ﭘﺮوژه ي ‪ PongServer‬ﻛﻠﻴﻚ راﺳﺖ ﻛـﺮده و از ﻣﻨـﻮﻳﻲ‬ ‫ﻛﻪ ﺑﺎز ﻣﻲ ﺷﻮد ﮔﺰﻳﻨﻪ ي ‪ Add Reference‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪.‬‬ ‫‬ ‫‬

‫ﻳﻚ ارﺟﺎع ﺑﻪ ﭘﺮوژه ي ‪ PongEngine‬ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪.‬‬ ‫ﻳﻚ ارﺟﺎع ﻧﻴﺰ ﺑﻪ ﻓﻀﺎي ﻧﺎم ‪ System.Runtime.Remoting‬ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ‪ .‬اﻳـﻦ‬ ‫ﻓﻀﺎي ﻧﺎم در ﻗﺴﻤﺖ ‪ .NET‬از ﻛﺎدر وﺟﻮد دارد‪.‬‬

‫‪ (5‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻗﺴﻤﺖ ارﺟﺎﻋﺎت ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷـﻜﻞ ‪ 12-20‬ﺑﺎﺷـﺪ‪ .‬ﺑـﺮاي ﻣـﺸﺎﻫﺪه ي اﻳـﻦ ﻗـﺴﻤﺖ روي ﻧـﺎم‬ ‫‪ References‬در ‪ Solution Explorer‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ارﺟﺎﻋﺎت ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ‪.‬‬

‫‪٨٤٩‬‬

12-20 ‫ﺷﻜﻞ‬ Add ‫ ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﮔﺰﻳﻨﻪ ي‬Solution Explorer ‫ در‬PongEngine ‫( روي ﻧﺎم ﭘﺮوژه ي‬6 ‫ ﻓﻀﺎي ﻧـﺎم‬Add Reference ‫ از ﻛﺎدر‬.NET ‫ ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻗﺴﻤﺖ‬.‫ را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‬Reference .‫ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬System.Windows.Forms ‫ ﺑﺎز ﻛﺮده و ﻛﺪ ﻣﻮﺟﻮد در آن را ﺑﻪ ﺻﻮرت زﻳـﺮ ﺗﻐﻴﻴـﺮ‬PongEngine ‫ را در ﭘﺮوژه ي‬Pinger.cs ‫( ﺣﺎل ﻓﺎﻳﻞ‬7 :‫دﻫﻴﺪ‬ public class Pinger : MarshalByRefObject { public String Name { get { return System.Windows.Forms.SystemInformation.ComputerName; } } }

:‫ را ﺑﺎز ﻛﺮده و ﺗﻐﻴﻴﺮات زﻳﺮ را در آن اﻳﺠﺎد ﻛﻨﻴﺪ‬PongServer ‫ از ﭘﺮوژه ي‬Program.cs ‫( ﻓﺎﻳﻞ‬8 using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; namespace PongServer { class Program { static void Main(string[] args) {

٨٥٠

‫;)‪TcpChannel channel = new TcpChannel(8000‬‬ ‫;)‪ChannelServices.RegisterChannel(channel‬‬ ‫(‪RemotingConfiguration.RegisterWellKnownServiceType‬‬ ‫‪typeof(PongEngine.Pinger),‬‬ ‫‪"MyPongEngine",‬‬ ‫;)‪WellKnownObjectMode.SingleCall‬‬ ‫‪Console.Write("PongEngine Registered." +‬‬ ‫;)‪Environment.NewLine‬‬ ‫;)"‪Console.Write("Server Active . . .‬‬ ‫;)(‪Console.Read‬‬ ‫}‬ ‫}‬ ‫}‬

‫‪ (9‬ﺣﺎل روي ﭘﺮوژه ي ‪ PongServer‬ﻛﻠﻴﻚ راﺳﺖ ﻛـﺮده و از ﻣﻨـﻮﻳﻲ ﻛـﻪ ﺑـﺎز ﻣـﻲ ﺷـﻮد ﮔﺰﻳﻨـﻪ ي ‪Set as‬‬ ‫‪ start project‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪.‬‬ ‫‪ (10‬ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﻨﺠﺮه اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ ‪ 13-20‬ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ‪ .‬اﮔﺮ ﻓﺎﻳﺮ وال و ﻳﺎ ﻫـﺮ ﻧـﺮم اﻓـﺰار‬ ‫اﻣﻨﻴﺘﻲ دﻳﮕﺮي در ﺳﻴﺴﺘﻢ ﺷﻤﺎ ﻧﺼﺐ ﺷﺪه ﺑﺎﺷﺪ‪ ،‬اﻳﻦ ﻧﻮع ﺳﺮور را ﻣﺤﺪود ﺧﻮاﻫﺪ ﻛﺮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ آن ﻧـﺮم اﻓـﺰار ﺳـﻮاﻟﻲ در‬ ‫ﻣﻮرد ﻣﺤﺪود ﻛﺮدن اﻳﻦ ﺑﺮﻧﺎﻣﻪ از ﺷﻤﺎ ﭘﺮﺳﻴﺪ‪ ،‬ﺑﻪ آن ﭘﺎﺳﺦ ﻣﻨﻔﻲ دﻫﻴﺪ و ﻳﺎ ﺑﺮﻧﺎﻣﻪ را ﻏﻴﺮ ﻓﻌﺎل ﻛﻨﻴﺪ‪.‬‬

‫ﺷﻜﻞ ‪13-20‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﺗﺎ اﻳﻨﺠﺎ ﻓﻘﻂ ﻳﻚ ﭘﺮوژه ي ﻛﺘﺎﺑﺨﺎﻧﻪ ي ﻛﻼس و ﻧﻴﺰ ﻳﻚ ﭘﺮوژه ي ﺗﺤﺖ ﻛﻨﺴﻮل اﻳﺠﺎد ﻛﺮده اﻳﻢ‪ .‬ﻛﺪي ﻫﻢ ﻛـﻪ ﺑـﺮاي اﺿـﺎﻓﻪ ﻛـﺮدن‬ ‫ﻓﻀﺎي ﻧﺎﻣﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ‪ Remoting‬وﺟﻮد دارد زﻳﺎد ﻧﻴﺴﺖ‪ .‬اﮔﺮ ﺑﻪ ﭘﻨﺠﺮه ي ﻛﻨﺴﻮﻟﻲ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﺑﺮﻧﺎﻣﻪ ﻧﻤـﺎﻳﺶ داده ﻣـﻲ‬ ‫ﺷﻮد )ﺷﻜﻞ ‪ (13-20‬دﻗﺖ ﻛﻨﻴﺪ ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﻪ درﺳﺘﻲ ﻛﺎر ﻣﻲ ﻛﻨﺪ‪ .‬اﻣﺎ ﺧﻮب اﻳﻦ ﺳﻮال ﭘﻴﺶ ﻣﻲ آﻳﺪ ﻛﻪ ﺗـﺎ اﻳﻨﺠـﺎ‬ ‫ﺑﺮﻧﺎﻣﻪ ﭼﻪ ﻛﺎري اﻧﺠﺎم داده اﺳﺖ؟‬ ‫اﺑﺘﺪا ﺳﺮور ﻳﻚ ﻛﺎﻧﺎل را در ﭘﻮرت ‪ 8000‬ﺛﺒﺖ ﻣﻲ ﻛﻨﺪ ﺗﺎ ﺑﺘﻮاﻧﺪ ﺑﺮاي ارﺗﺒﺎﻃﺎت ﺧﻮد از اﻳﻦ ﻛﺎﻧﺎل اﺳﺘﻔﺎده ﻛﻨﺪ‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﮔﻔـﺘﻢ ﺑـﺮاي‬ ‫اﻳﻨﻜﻪ ﺑﺮﻧﺎﻣﻪ ي ﺳﺮور و ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ﺑﺘﻮاﻧﻨﺪ ﺑﺎ ﻫﻢ در ارﺗﺒﺎط ﺑﺎﺷﻨﺪ ﺑﺎﻳﺪ از ﻳﻚ ﭘﻮرت اﺳﺘﻔﺎده ﻛﻨﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺷﻤﺎره ﭘـﻮرﺗﻲ ﻛـﻪ در‬ ‫اﻳﻦ ﻗﺴﻤﺖ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ ﺑﻪ وﺳﻴﻠﻪ ي ﻫﺮ دو ﺑﺮﻧﺎﻣﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺧﻮاﻫﺪ ﮔﺮﻓﺖ‪:‬‬ ‫;)‪TcpChannel channel = new TcpChannel(8000‬‬ ‫;)‪ChannelServices.RegisterChannel(channel‬‬

‫ﺳﭙﺲ ﺑﺎﻳﺪ ﻛﻼس ‪ Pinger‬را در اﻳﻦ ﭘﻮرت ﺛﺒﺖ ﻛﻨﻴﻢ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ‪ .NET Remoting‬ﻣﻲ داﻧﺪ زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﺗﻘﺎﺿﺎ‬ ‫از ﻃﺮف ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ﺑﻪ اﻳﻦ ﭘﻮرت رﺳﻴﺪ‪ ،‬ﭼﻪ ﻧﻮع ﺷﻴﺊ اي را ﺑﺎﻳﺪ اﻳﺠﺎد ﻛﺮده و ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ارﺳﺎل ﻛﻨﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ‬ ‫‪ .NET Remoting‬ﺑﺮاي ارﺳﺎل اﻳﻦ ﺷﻴﺊ از ﭘﺮوﺗﻜﻞ ‪ TCP‬و اﻟﺒﺘﻪ ﭘﻮرت ‪ 8000‬اﺳﺘﻔﺎده ﺧﻮاﻫﺪ ﻛﺮد‪:‬‬ ‫‪٨٥١‬‬

‫(‪RemotingConfiguration.RegisterWellKnownServiceType‬‬ ‫‪typeof(PongEngine.Pinger),‬‬ ‫‪"MyPongEngine",‬‬ ‫;)‪WellKnownObjectMode.SingleCall‬‬

‫ﺷﻤﺎرﻧﺪه ي ‪ WellKnownObjectMode.SingleCall‬ﻛﻪ در اﻳﻦ ﻣﺘﺪ ﺑﻪ ﻛﺎر رﻓﺘﻪ اﺳﺖ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ‬ ‫ﻫﺮ ﺷﻴﺊ ﺑﻌﺪ از اﻳﺠﺎد ﺷﺪن و ﻓﺮﺳﺘﺎده ﺷﺪن ﺑﻪ ﺳﻤﺖ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ﺑﺎﻳﺪ ﻧﺎﺑﻮد ﺷﻮد‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺎزاي ﻫﺮ ﻳﻚ درﺧﻮاﺳـﺘﻲ ﻛـﻪ از‬ ‫ﻃﺮف ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ﺑﻪ اﻳﻦ ﭘﻮرت ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد‪ ،‬ﻳﻚ ﺷﻴﺊ ﺟﺪﻳﺪ اﻳﺠﺎد ﺷﺪه و ﺑﻪ ﺳﻤﺖ ﻛﻼﻳﻨﺖ ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮد‪ .‬ﺳـﭙﺲ‬ ‫ﺷﻴﺊ اﻳﺠﺎد ﺷﺪه ﻧﺎﺑﻮد ﺧﻮاﻫﺪ ﺷﺪ‪.1‬‬ ‫ﺣﺎل ﺑﺎﻳﺪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﻨﻴﻢ ﺗﺎ ﺑﺘﻮاﻧﺪ از ‪ PongServer‬اﺳﺘﻔﺎده ﻛﻨﺪ‪ .‬اﻣﺎ ﻗﺒﻞ از آن ﺑﺎﻳﺪ ﻳﻚ ﭘﺮوﻛﺴﻲ اﻳﺠﺎد ﻛﻨﻴﻢ‪.‬‬

‫اﻳﺠﺎد ﭘﺮوﻛﺴﻲ‪:‬‬ ‫ﻳﻚ ﭘﺮوﻛﺴﻲ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد و وﻇﻴﻔﻪ دارد ﻛﻪ راﺑﻂ و ﻇﺎﻫﺮ ﻛﻼس ‪ PongEngine‬را ﺑﺮاي‬ ‫ﺑﺮﻧﺎﻣـــﻪ ي ﻛﻼﻳﻨـــﺖ اﻳﺠـــﺎد ﻛﻨـــﺪ‪ .‬ﺑـــﺮاي اﺳـــﺘﻔﺎده از ﻛـــﻼس ‪ PongEngine‬ﻣـــﻲ ﺗﻮاﻧﻴـــﺪ ﻳـــﻚ ارﺟـــﺎع ﺑـــﻪ ﻓﺎﻳـــﻞ‬ ‫‪ PongEngine.dll‬در ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ اﻳﺠﺎد ﻛﺮده و از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ .‬اﻣﺎ دﻟﻴﻠـﻲ ﺑـﺮاي اﻳـﻦ ﻛـﺎر وﺟـﻮد ﻧـﺪارد‪ ،‬زﻳـﺮا‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﺗﻮﺿﻴﺢ داده ﺷﺪ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ﻫﻴﭽﮕﺎه ﻳﻚ ﻧﻤﻮﻧﻪ از ﺷـﻴﺊ ‪ PongEngine‬را اﻳﺠـﺎد ﻧﻤـﻲ ﻛﻨـﺪ و اﻳـﻦ ﺷـﻴﺊ‬ ‫ﻫﻤﻮاره در ﺑﺮﻧﺎﻣﻪ ي ﺳﺮور اﻳﺠﺎد ﻣﻲ ﺷﻮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻻزم ﻧﻴﺴﺖ ﻛﻪ ﻛﺪ اﻳﻦ ﻛﻼس ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ اﺿﺎﻓﻪ ﺷﻮد‪ .‬ﺗﻨﻬﺎ ﭼﻴﺰي ﻛـﻪ در‬ ‫ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ﻧﻴﺎز اﺳﺖ راﺑﻂ و ﻇﺎﻫﺮ ﻛﻼس اﺳﺖ‪ .‬ﺑﻪ ﻋﺒﺎرت دﻳﮕـﺮ در ﺑﺮﻧﺎﻣـﻪ ي ﻛﻼﻳﻨـﺖ ﻓﻘـﻂ ﻻزم اﺳـﺖ ﻛـﻪ ﻧـﺎم ﻣﺘـﺪ ﻫـﺎ و‬ ‫ﺧﺎﺻﻴﺘﻬﺎي ‪ ،public‬ﻧﺎم ﻓﻴﻠﺪ ﻫﺎي ﻋﻤﻮﻣﻲ و ﻣﻮارد دﻳﮕﺮ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ﻣﻮرد اﺳﺘﻔﺎده ﻗـﺮار ﺑﮕﻴـﺮد وﺟـﻮد‬ ‫داﺷﺘﻪ ﺑﺎﺷﺪ‪ .‬ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﻛﺪ اﻳﻦ ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺖ ﻫﺎ ﻧﻴﺰ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ﻓﺮﺳﺘﺎده ﺷﻮد‪ .‬ﭘﺮوﻛﺴﻲ ﻧﻴﺰ در اﻳﻨﺠﺎ ﻫﻤﻴﻦ وﻇﻴﻔﻪ را‬ ‫دارد‪ .‬ﻳﻚ ﭘﺮوﻛﺴﻲ در واﻗﻊ راﺑﻂ و ﻇﺎﻫﺮ ﻳﻚ ﻛﻼس واﻗﻌﻲ ﺑﻪ ﺷﻤﺎر ﻣﻲ رود‪ .‬در واﻗﻊ ﭘﺮوﻛﺴﻲ ﻣﺸﺎﺑﻪ ﻳﻚ ﻛﻼس واﻗﻌﻲ اﺳﺖ‪ ،‬اﻣﺎ ﻫﻴﭻ‬ ‫ﻛﺪي در آن وﺟﻮد ﻧﺪارد و ﻓﻘﻂ ﺷﺎﻣﻞ ﺗﻌﺮﻳﻒ ﻣﺘﺪ ﻫﺎ و ﺧﺎﺻﻴﺘﻬﺎي و … از ﻛﻼس اﺳﺖ و اﻟﺒﺘﻪ ﻛﺪي ﻛﻪ ﺧﻮد ﭘﺮوﻛﺴﻲ را اﻳﺠﺎد ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ﺑﻪ ﺟﺎي اﻳﻨﻜﻪ از ﻛﻼس واﻗﻌﻲ در ﺑﺮﻧﺎﻣﻪ ي ﺳﺮور اﺳﺘﻔﺎده ﻛﻨﺪ‪ ،‬از ﻛﻼس اﻳﺠﺎد ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي ﭘﺮوﻛـﺴﻲ اﺳـﺘﻔﺎده‬ ‫ﻣﻲ ﻛﻨﺪ‪ ،‬اﻣﺎ ﺷﻴﺊ واﻗﻌﻲ ﻫﻤﻮاره در ﺳﺮور اﻳﺠﺎد ﻣﻲ ﺷﻮد‪.‬‬ ‫در ﺑﺨﺶ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ ﻳﻚ ﭘﺮوﻛﺴﻲ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﻳﺠﺎد ﭘﺮوﻛﺴﻲ‬ ‫‪ (1‬ﺑﺮاي اﻳﻨﻜﻪ ﺑﺮاي ‪ PngEngine.dll‬ﻳﻚ ﭘﺮوﻛﺴﻲ اﻳﺠﺎد ﻛﻨﻴﻢ‪ ،‬ﺑﺎﻳﺪ از ﺧﻂ ﻓﺮﻣﺎن وﻳﮋوال اﺳﺘﻮدﻳﻮ اﺳﺘﻔﺎده ﻛﻨـﻴﻢ‪.‬‬ ‫ﺑﺮاي اﻳﻦ ﻛﺎر ﮔﺰﻳﻨﻪ ي زﻳﺮ را از ﻣﻨﻮي ‪ Start‬در وﻳﻨﺪوز اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪:‬‬ ‫ ‪Start  All Programs  Microsoft Visual Studio 2005‬‬ ‫‪Visual Studio Tools  Visual Studio 2005 Command Prompt‬‬

‫‪ 1‬اﻳﻦ ﻧﻮع رﻓﺘﺎر ﻣﻌﻤﻮﻻ ﺑﻪ ﺣﺎﻟﺖ ‪ stateless‬ﻣﻌﺮوف اﺳﺖ‪.‬‬

‫‪٨٥٢‬‬

‫‪ (2‬ﺣﺎل ﻣﺴﻴﺮ ﺧﻮد را ﺑﻪ ﻣﻜﺎﻧﻲ ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﻛﻪ ﻓﺎﻳﻞ ‪ PongEngine.dll‬ﻗﺮار دارد‪ .‬ﺑـﺮاي ﻣﺜـﺎل ﺑـﻪ ﺷـﻜﻞ ‪14-20‬‬ ‫ﻧﮕﺎه ﻛﻨﻴﺪ‪:‬‬

‫ﺷﻜﻞ ‪14-20‬‬ ‫‪ (3‬ﺳﭙﺲ دﺳﺘﻮر زﻳﺮ را وارد ﻛﻨﻴﺪ‪:‬‬ ‫‪soapsads –ia:PongEngine –oa:PongEngine_Proxy.dll‬‬ ‫ﺑﺎ اﺟﺮاي اﻳﻦ دﺳﺘﻮر ﻳﻚ ﻓﺎﻳﻞ ‪ DLL‬ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم ‪ PongEngine_Proxy.dll‬اﻳﺠﺎد ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬ ‫‪ (4‬ﺑﺮاي اﻳﻨﻜﻪ ﻣﺘﻮﺟﻪ ﺗﻔﺎوت ﺑﻴﻦ اﻳﻦ اﺳﻤﺒﻠﻲ و اﺳﻤﺒﻠﻲ ﻗﺒﻠﻲ ﺑﺸﻮﻳﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ از اﺑﺰار ‪ ILDasm‬اﺳﺘﻔﺎده ﻛﻨﻴـﺪ‪ .‬اﻳـﻦ اﺑـﺰار‬ ‫ﻣﻲ ﺗﻮاﻧﺪ ﻛﺪ ‪ IL‬ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺗﺤﺖ ‪ .NET‬ﻧﻮﺷﺘﻪ ﺷﺪه اﻧﺪ را ﻧﻤﺎﻳﺶ دﻫﺪ‪ .‬در ﺧﻂ ﻓﺮﻣﺎن ﻣﺮﺑﻮط ﺑﻪ وﻳﮋوال اﺳـﺘﻮدﻳﻮ‬ ‫دﺳﺘﻮر ‪ ildasm‬را وارد ﻛﻨﻴﺪ ﺗﺎ اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﺟﺮا ﺷﻮد‪.‬‬ ‫‪ (5‬ﻓﺎﻳﻞ ‪ PongEngine_Proxy.dll‬را ﺑﺎ اﺳﺘﻔﺎده از ﻣﺎوس روي اﻳﻦ ﺑﺮﻧﺎﻣﻪ آورده و رﻫﺎ ﻛﻨﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴـﺐ‬ ‫ﺑﺮﻧﺎﻣﻪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ ‪ 15-20‬ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬ ‫ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ﻧﺴﺨﻪ ي دﻳﮕﺮ از ‪ ildasm‬را ﺑﺎز ﻛﺮده و ﻓﺎﻳﻞ ‪ PongEngine.dll‬را در آن ﻗﺮار دﻫﻴﺪ ﺗﺎ ﻛﺪ‬ ‫‪ IL‬آن را ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﻪ ﺳﺮﻋﺖ ﻣﺘﻮﺟﻪ ﺗﻔﺎوﺗﻬﺎي ﺑﻴﻦ ﻓﺎﻳﻠﻬﺎي ﻣﻮﺟﻮد ﺧﻮاﻫﻴﺪ ﺷﺪ‪.‬‬ ‫در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ‪ ،‬ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ را اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ‬ ‫‪ (1‬در ﻳﻚ ﭘﻨﺠﺮه ي ﺟﺪﻳﺪ از وﻳﮋوال اﺳﺘﻮدﻳﻮ‪ ،‬ﻳﻚ ﭘﺮوژه ي ﺟﺪﻳﺪ از ﻧـﻮع ‪ Console Application‬ﺑـﻪ ﻧـﺎم‬ ‫‪ PongClient‬اﻳﺠﺎد ﻛﻨﻴﺪ‪.‬‬ ‫‪ (2‬ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي ‪ Solution Explorer‬روي ﻧﺎم ﭘـﺮوژه ﻛﻠﻴـﻚ راﺳـﺖ ﻛـﺮده و ﮔﺰﻳﻨـﻪ ي ‪Add‬‬ ‫‪ Reference‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺳـﭙﺲ ارﺟـﺎﻋﻲ ﺑـﻪ ﻓﺎﻳـﻞ ‪ System.Runtime.Remoting‬را ﺑـﻪ‬ ‫ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪.‬‬

‫‪٨٥٣‬‬

‫ﺷﻜﻞ ‪15-20‬‬ ‫‪ (3‬ﺣﺎل ﺑﺎﻳﺪ ﻳﻚ ارﺟﺎع ﺑﻪ ﻓﺎﻳﻞ ‪ PongEngine_Proxy.dll‬ﻛﻪ در ﻣﺮﺣﻠﻪ ي ﻗﺒﻞ اﻳﺠﺎد ﻛـﺮده ﺑـﻮدﻳﻢ را ﺑـﻪ‬ ‫ﺑﺮﻧﺎﻣﻪ اﺿـﺎﻓﻪ ﻛﻨـﻴﻢ‪ .‬ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﺑـﺎ اﺳـﺘﻔﺎده از ﻗـﺴﻤﺖ ‪ Browse‬در ﻛـﺎدر ‪ ،Add Reference‬ﻓﺎﻳـﻞ‬ ‫‪ PongEngine_Proxy.dll‬را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪.‬‬ ‫‪ Add‬ﻧﻴــﺰ ﻳــﻚ ارﺟــﺎع ﺑــﻪ اﺳــﻤﺒﻠﻲ‬ ‫‪ (4‬ﻫﻤﭽﻨــﻴﻦ ﺑــﺎ اﺳــﺘﻔﺎده از ﻗــﺴﻤﺖ ‪ .NET‬در ﻛــﺎدر ‪Reference‬‬ ‫‪ System.Runtime.Remoting‬ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪.‬‬ ‫‪ (5‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻗﺴﻤﺖ ‪ References‬در ﭘﻨﺠﺮه ي ‪ Solution Explorer‬از ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ‬ ‫‪ 16-20‬ﺑﺎﺷﺪ‪.‬‬

‫ﺷﻜﻞ ‪16-20‬‬ ‫‪ (6‬ﺣﺎل ﺑﺎﻳﺪ ﻳﻚ ﻧﻤﻮﻧﻪ از ﻛﻼس ‪ PongEngine.Pinger‬را اﻳﺠﺎد ﻛﺮده و در ﺑﺮﻧﺎﻣﻪ از آن اﺳﺘﻔﺎده ﻛﻨـﻴﻢ‪ .‬ﺑـﺮاي‬ ‫اﻳﻦ ﻛﺎر ﻛﺪ زﻳﺮ را ﺑﻪ ﻓﺎﻳﻞ ‪ Program.cs‬اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪ .‬اﻟﺒﺘﻪ ﻓﺮاﻣﻮش ﻧﻜﻨﻴﺪ ﻛﻪ ﻧﺎم ‪ maincpu‬را ﺑﺎ ﻧﺎم ﻛﺎﻣﭙﻴﻮﺗﺮ‬

‫‪٨٥٤‬‬

‫ﺧــﻮد ﺟــﺎﻳﮕﺰﻳﻦ ﻛﻨﻴــﺪ )ﺑــﺮاي ﺑﺪﺳــﺖ آوردن ﻧــﺎم ﻛــﺎﻣﭙﻴﻮﺗﺮ ﻣــﻲ ﺗﻮاﻧﻴــﺪ از ﻣﻘــﺪاري ﻛــﻪ ﺑــﻪ وﺳــﻴﻠﻪ ي ﺧﺎﺻــﻴﺖ‬ ‫‪ ComputerName‬از ﻛﻼس ‪System.Windows.Forms.SystemInformation‬‬ ‫ﺑﺮﻣﻲ ﮔﺮدد اﺳﺘﻔﺎده ﻛﻨﻴﺪ(‪.‬‬ ‫‪class Program‬‬ ‫{‬ ‫)‪static void Main(string[] args‬‬ ‫{‬ ‫;‪PongEngine.Pinger client‬‬ ‫‪Console.Write("Trying to obtain Type from Server . . ." +‬‬ ‫;)‪Environment.NewLine‬‬ ‫(‪client = (PongEngine.Pinger)Activator.GetObject‬‬ ‫‪typeof(PongEngine.Pinger),‬‬ ‫;)"‪"tcp://Maincpu:8000/MyPongEngine‬‬ ‫‪Console.Write("Type Created and returned" +‬‬ ‫;)‪Environment.NewLine‬‬ ‫‪Console.Write("The object returned:" + client.Name +‬‬ ‫;)‪Environment.NewLine‬‬ ‫;)(‪Console.Read‬‬ ‫}‬ ‫}‬

‫‪ (7‬ﺧﻮب‪ ،‬ﺑﺮاي ﺗـﺴﺖ ﺑﺮﻧﺎﻣـﻪ اﺑﺘـﺪا ﺑﺎﻳـﺪ ﺳـﺮور را اﺟـﺮا ﻛﻨـﻴﻢ‪ .‬ﺑـﺮاي اﻳـﻦ ﻛـﺎر ﺑـﻪ ﻓﻮﻟـﺪر ‪ bin\debug‬از ﭘـﺮوژه ي‬ ‫‪ PongServer‬ﺑﺮوﻳﺪ و ﻓﺎﻳﻞ ‪ PongServer.exe‬را اﺟﺮا ﻛﻨﻴﺪ‪.‬‬ ‫‪ (8‬ﺣﺎل ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ را ﺑﻪ وﺳﻴﻠﻪ ي وﻳﮋوال اﺳﺘﻮدﻳﻮ اﺟﺮا ﻛﻨﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﻨﺠﺮه اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ ‪ 17-20‬ﻧﻤﺎﻳﺶ داده‬ ‫ﺧﻮاﻫﺪ ﺷﺪ ﻛﻪ ﻧﺎم ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﻮرد اﺳﺘﻔﺎده ي ﺷﻤﺎ ﻧﻴﺰ در اﻧﺘﻬﺎي آن ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ‪.‬‬

‫ﺷﻜﻞ ‪17-20‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫اﮔﺮ ﻓﺎﻳﻠﻬﺎي ‪ PongClient.exe‬و ﻧﻴﺰ ‪ PongEngine_Proxy.dll‬را ﺑﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ دﻳﮕﺮي ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از‬ ‫ﺷﺒﻜﻪ ﺑﻪ اﻳﻦ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﺘﺼﻞ اﺳﺖ ﻣﻨﺘﻘﻞ ﻛﻨﻴﺪ و ﭼﺎرﭼﻮب ‪ .NET‬را ﻧﻴﺰ در آن ﻛﺎﻣﭙﻴﻮﺗﺮ ﻧﺼﺐ ﻛﻨﻴﺪ‪ ،‬ﺑﺎز ﻫﻢ در ﭘﻨﺠﺮه ﻧﺎم ﻛﺎﻣﭙﻴﻮﺗﺮي‬ ‫ﻛﻪ ﺑﺮﻧﺎﻣﻪ ي ﺳﺮور در آن اﺟﺮا ﺷﺪه اﺳﺖ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد‪ .‬دﻟﻴﻞ اﻳﻦ ﻣﻮرد در اﻳـﻦ اﺳـﺖ ﻛـﻪ ‪ .NET Remoting‬ﺷـﻴﺊ‬ ‫ﻣﻮرد ﻧﻈﺮ ﻣﺎ را اﻳﺠﺎد ﻛﺮده و ﻣﻘﺎدﻳﺮ ﺧﺎﺻﻴﺖ ﻫﺎ را در آن ﻗﺮار ﻣﻲ دﻫﺪ‪ .‬ﺑﻪ ﻛﺪ زﻳﺮ ﻧﮕﺎه ﻛﻨﻴﺪ‪:‬‬ ‫;‪PongEngine.Pinger client‬‬ ‫(‪client = (PongEngine.Pinger)Activator.GetObject‬‬ ‫‪typeof(PongEngine.Pinger),‬‬

‫‪٨٥٥‬‬

‫;)"‪"tcp://Maincpu:8000/MyPongEngine‬‬

‫اﻳﻦ ﻛﺪ اﺑﺘﺪا ﻳﻚ ﻣﺘﻐﻴﻴﺮ از ﻧﻮع ‪ PongEngine.Pinger‬اﻳﺠﺎد ﻛﺮده و ﺳﭙﺲ ﺑـﺎ اﺳـﺘﻔﺎده از ﻛـﻼس ‪Activator‬‬ ‫ﻳﻚ ﻧﻤﻮﻧﻪ از ﺷﻴﺊ را در آن ﻗﺮار ﻣﻲ دﻫﺪ‪ .‬ﺑﺮاي اﺳﺘﻔﺎده از ﻛﻼس ‪ Activator‬دو ﭘﺎراﻣﺘﺮ را ﺑﺎﻳﺪ ﻣﺸﺨﺺ ﻛﻨﻴﻢ‪ :‬اول ﻧﻮع ﺷـﻴﺊ‬ ‫اي ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ اﻳﺠﺎد ﻛﻨﻴﻢ و دوم ﻧﻴﺰ ‪ URI‬ﻣﺮﺑﻮط ﺑﻪ ﻣﻜﺎﻧﻲ ﻛﻪ آن ﻧﻮع در آﻧﺠﺎ ﻗﺮار دارد‪.‬‬ ‫ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﻼس ‪ Activator‬ﺑﻪ ‪ URI‬ﻣﺸﺨﺺ ﺷﺪه ﻳﻚ ﺗﻘﺎﺿﺎ ارﺳﺎل ﻣﻲ ﻛﻨﺪ و ﻳﻚ ﻧﻤﻮﻧﻪ از ﺷـﻴﺊ اي ﻛـﻪ ﻣـﺸﺨﺺ‬ ‫ﻛﺮده ﺑﻮدﻳﻢ را ﺑﻪ اﻳﻦ وﺳﻴﻠﻪ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ‪ .‬اﻟﺒﺘﻪ اﻳﻦ ﺷﻴﺊ ﺑﻪ ﺻﻮرت ‪ System.Object‬ﺑﺮﮔﺸﺘﻪ ﻣﻲ ﺷـﻮد و ﺑﺎﻳـﺪ ﻗﺒـﻞ از‬ ‫اﺳﺘﻔﺎده آن را ﺑﻪ ﻧﻮع ﻣﻮرد ﻧﻈﺮ ﺧﻮد ﺗﺒﺪﻳﻞ ﻛﻨﻴﻢ‪.‬‬

‫ﻧﺘﻴﺠﻪ‪:‬‬ ‫در اﻳﻦ ﻓﺼﻞ ﺑﺎ وب ﺳﺮوﻳﺲ ﻫﺎ و ﻧﻴﺰ ‪ .NET Remoting‬آﺷﻨﺎ ﺷﺪﻳﻢ‪ .‬وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ اﺟﺎزه ﻣﻲ دﻫﻨـﺪ‬ ‫ﺗﺎ ﺑﻪ ﺷﻴﺊ اي ﻛﻪ در ﻳﻚ وب ﺳﺮور ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ‪ .‬وب ﺳـﺮوﻳﺲ ﻫـﺎ ﺑـﺮ اﺳـﺎس اﺳـﺘﺎﻧﺪاردﻫﺎي آزادي ﻣﺎﻧﻨـﺪ‬ ‫‪ SOAP‬و ‪ WSDL‬اﻳﺠﺎد ﺷﺪه اﻧﺪ و ﺑﻪ وﺳﻴﻠﻪ ي ﺗﻜﻨﻮﻟﻮژﻳﻬﺎﻳﻲ ﻣﺎﻧﻨﺪ ‪ XML‬و ﻳﺎ ‪ HTTP‬ﻧﻴﺰ ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ ﺷﻮﻧﺪ‪.‬‬ ‫ﻓﺼﻞ را ﺑﺎ اﻳﺠﺎد ﻳﻚ وب ﺳﺮوﻳﺲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺴﺖ اﻃﻼﻋﺎﺗﻲ را ﺑﺮﮔﺮداﻧﺪ و ﻫﻤﭽﻨﻴﻦ ﻛﺎري را اﻧﺠﺎم دﻫﺪ ﺷـﺮوع ﻛـﺮدﻳﻢ‪ ،‬اﻟﺒﺘـﻪ آن وب‬ ‫ﺳﺮوﻳﺲ ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺴﺖ ﺟﺬر ﻳﻚ ﻋﺪد را ﻣﺤﺎﺳﺒﻪ ﻛﻨﺪ‪ .‬ﺳﭙﺲ ﺑﻪ ﻋﻨﻮان ﻳﻚ ﻣﺜﺎل ﺑﻬﺘﺮ‪ ،‬وب ﺳﺮوﻳﺴﻲ اﻳﺠﺎد ﻛﺮدﻳﻢ ﻛﻪ ﻣـﻲ ﺗﻮاﻧـﺴﺖ‬ ‫ﻟﻴﺴﺖ ﻓﺎﻳﻠﻬﺎي ﺗﺼﻮﻳﺮ ﻣﻮﺟﻮد در وب ﺳﺮور را ﺑﺮﮔﺮداﻧﺪ‪ .‬ﺑﺮاي اﺳﺘﻔﺎده از اﻳﻦ وب ﺳﺮوﻳﺲ ﻧﻴﺰ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨـﺖ وﻳﻨـﺪوزي اﻳﺠـﺎد‬ ‫ﻛﺮدﻳﻢ ﻛﻪ ﺑﻪ وب ﺳﺮوﻳﺲ ﻣﺘﺼﻞ ﻣﻲ ﺷﺪ و ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪﻫﺎي آن ﻟﻴﺴﺖ ﺗﺼﺎوﻳﺮ ﻣﻮﺟﻮد در ﺳﺮوﻳﺲ را ﺑﺪﺳﺖ ﻣﻲ آورد‪ .‬ﻫﻤﭽﻨﻴﻦ در‬ ‫اﻳﻦ ﻣﺜﺎل از ﻫﻤﺎﻫﻨﮕﻲ ﺑﻴﻦ ﻻﻳﻪ ﻫﺎي ‪ COM‬و ‪ .NET‬ﻧﻴﺰ ﺑﺮاي اﺳﺘﻔﺎده از ﻗﺎﺑﻠﻴﺘﻬﺎي اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﺮدﻳﻢ‪.‬‬ ‫در آﺧﺮ ﻧﻴﺰ ﺑﻪ اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﺮور و ﻛﻼﻳﻨﺖ ﺑﺎ اﺳﺘﻔﺎده از ‪ .NET Remoting‬ﭘﺮداﺧﺘﻴﻢ و ﺑﻌﺪ از اﻳﺠﺎد ﻳﻚ ﻛﻼس در ﻳﻚ‬ ‫ﻛﺎﻣﭙﻴﻮﺗﺮ‪ ،‬از آن در ﻳﻚ ﺑﺮﻧﺎﻣﻪ در ﻛﺎﻣﭙﻴﻮﺗﺮ دﻳﮕﺮي اﺳﺘﻔﺎده ﻛﺮدﻳﻢ‪ .NET Remoting .‬ﺑﻬﺘﺮﻳﻦ روش ﺑﺮاي ارﺗﺒﺎط ﺑﻴﻦ ﺑﺮﻧﺎﻣـﻪ‬ ‫ﻫﺎ ﺑﺎ اﺳﺘﻔﺎده از ﭘﺮوﺗﻜﻞ ﻫﺎﻳﻲ ﻣﺎﻧﻨﺪ ‪ TCP‬اﺳﺖ‪.‬‬ ‫در ﭘﺎﻳﺎن اﻳﻦ ﻓﺼﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ‪:‬‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬

‫وب ﺳﺮوﻳﺲ ﭼﻴﺴﺖ و ﭼﮕﻮﻧﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد‪.‬‬ ‫ﭼﮕﻮﻧﻪ ﻣﺘﺪ ﻫﺎﻳﻲ را اﻳﺠﺎد ﻛﺮده ﺗﺎ ﺑﺎ اﺳﺘﻔﺎده از وب ﺳﺮوﻳﺲ ﻗﺎﺑﻞ دﺳﺘﺮس ﺑﺎﺷﻨﺪ و ﺳﭙﺲ ﺑﺎ اﺳـﺘﻔﺎده از اﻳﻨﺘﺮﻧـﺖ اﻛـﺴﭙﻠﻮرر‪،‬‬ ‫ﻋﻤﻠﻜﺮد اﻳﻦ ﻣﺘﺪ ﻫﺎ را ﺗﺴﺖ ﻛﻨﻴﻢ‪.‬‬ ‫ﭼﮕﻮﻧﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ اﻳﺠﺎد ﻛﻨﻴﻢ ﻛﻪ از وب ﺳﺮوﻳﺲ ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﺪ‪.‬‬ ‫‪ .NET Remoting‬ﭼﻴﺴﺖ و ﻛﻼً ﺑﺮاي ﭼﻪ ﻣﻮاردي ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد‪.‬‬ ‫ﺗﻔﺎوت ﺑﻴﻦ ﭘﺮوﺗﻜﻞ ﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي ‪ .NET Remoting‬و وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﻪ ﻛﺎر ﻣﻲ رود ﭼﻴﺴﺖ‪.‬‬

‫ﺗﻤﺮﻳﻦ‪:‬‬

‫ﺗﻤﺮﻳﻦ ‪:1‬‬

‫‪٨٥٦‬‬

‫ﻳﻚ وب ﺳﺮوﻳﺲ اﻳﺠﺎد ﻛﻨﻴﺪ ﺗﺎ ﺑﺘﻮاﻧﺪ اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ وب ﺳﺮور را ﺑﺮﮔﺮداﻧﺪ‪ .‬در اﻳﻦ وب ﺳﺮوﻳﺲ ﺳﻪ ﻣﺘﺪ ﺑﻪ ﺻﻮرت زﻳﺮ ﻗﺮار دﻫﻴﺪ‪:‬‬ ‫ﻣﺘﺪ اول زﻣﺎن وب ﺳﺮور را ﺑﺮﮔﺮداﻧﺪ‪ ،‬ﻣﺘﺪ دوم ﺗﺎرﻳﺦ وب ﺳﺮور را ﺑﺮﮔﺮداﻧﺪ و ﻣﺘﺪ ﺳﻮم ﻧﻴﺰ ﻧﺎم وب ﺳﺮور را ﺑﺮﮔﺮداﻧﺪ‪ .‬ﺳﭙﺲ ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ‬ ‫ي ﻛﻼﻳﻨﺖ اﻳﺠﺎد ﻛﺮده و ﺑﻪ وﺳﻴﻠﻪ ي آن وب ﺳﺮوﻳﺲ را ﺗﺴﺖ ﻛﻨﻴﺪ‪.‬‬

‫ﺗﻤﺮﻳﻦ ‪:2‬‬ ‫ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺳﺮور و ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ اﻳﺠﺎد ﻛﻨﻴﺪ ﻛﻪ ﻫﻤﺎﻧﻨﺪ وب ﺳﺮوﻳﺲ ﺗﻤﺮﻳﻦ اول ﻋﻤﻞ ﻛﻨﺪ‪ .‬ﺳﺮور ﺑﺎﻳﺪ دو ﻣﺘﺪ داﺷﺘﻪ ﺑﺎﺷﺪ‪:‬‬ ‫ﻳﻜﻲ ﺑﺮاي ﺑﺪﺳﺖ آوردن زﻣﺎن وب ﺳﺮور و دﻳﮕﺮي ﺑﺮاي ﺑﺪﺳﺖ آوردن ﺗﺎرﻳﺦ وب ﺳﺮور‪ .‬ﺳﭙﺲ در ﺑﺮﻧﺎﻣﻪ ي ﻛﻼﻳﻨﺖ ﻋﻤﻠﻜﺮد ﻣﺘـﺪﻫﺎي‬ ‫ﺳﺮور را ﺗﺴﺖ ﻛﻨﻴﺪ‪ .‬اﻟﺒﺘﻪ ﺑﻪ دﻟﻴﻞ اﻳﻨﻜﻪ ﺑﻪ ﺻﻮرت ﻣﺤﻠﻲ از ﺳﺮور اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ )ﺳﺮور و ﻛﻼﻳﻨﺖ در ﻳﻚ ﻛﺎﻣﭙﻴﻮﺗﺮ واﻗـﻊ ﺷـﺪه اﻧـﺪ(‬ ‫ﻧﻴﺎزي ﻧﻴﺴﺖ ﻛﻪ ﭘﺮوﻛﺴﻲ اﻳﺠﺎد ﻛﻨﻴﺪ‪.‬‬

‫‪٨٥٧‬‬

‫ﻓﺼﻞ ﺑﻴﺴﺖ و ﻳﻜﻢ‪ :‬ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﺎرﺑﺮدي‬ ‫ﻳﻜﻲ از ﻣﺴﺎﺋﻞ ﻣﻬﻢ و ﻧﺴﺒﺘﺎً ﭘﻴﭽﻴﺪه‪ ،‬ﻣﺨﺼﻮﺻﺎً زﻣﺎﻧﻲ ﻛﻪ در ﺣﺎل اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺑﺰرگ ﻫﺴﺘﻴﺪ‪ ،‬ﻣﺴﺌﻠﻪ ي ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﺑﻴﻦ ﻛـﺎرﺑﺮان‬ ‫اﺳﺖ‪ .‬ﻳﻜﻲ از ﻋﻤﻮﻣﻲ ﺗﺮﻳﻦ روﺷﻬﺎ ﺑﺮاي اﻳﻦ ﻛﺎر‪ ،‬اﻳﺠﺎد ﻳﻚ ﻗﺴﻤﺖ ﻧﺼﺐ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ و ﺳـﭙﺲ ﺗﻮزﻳـﻊ آن در ﺑـﻴﻦ اﻓـﺮادي ﻛـﻪ ﻣـﻲ‬ ‫ﺧﻮاﻫﻨﺪ از ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻨﺪ اﺳﺖ‪ .‬ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﺪ ﻗﺴﻤﺖ ﻧﺼﺐ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ﻧﺴﺒﺘﺎً ﺑﺰرگ را اﻳﺠﺎد ﻛﻨﻴـﺪ ﺑﺎﻳـﺪ ﺑﺘﻮاﻧﻴـﺪ‬ ‫اﻃﻼﻋﺎﺗﻲ را از رﺟﻴﺴﺘﺮي ﺑﺨﻮاﻧﻴﺪ و ﻳﺎ در آن ﺑﻨﻮﻳﺴﻴﺪ‪ ،‬ﺑﺎ ﻧﻮع ﻫـﺎي ‪ MIME‬ﻛـﺎر ﻛﻨﻴـﺪ‪ ،‬ﻓﺎﻳﻠﻬـﺎي ﭘﻴﻜـﺮ ﺑﻨـﺪي ﻣﺮﺑـﻮط ﺑـﻪ ﺑﺎﻧﻜﻬـﺎي‬ ‫اﻃﻼﻋﺎﺗﻲ را ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ و ‪ ....‬اﻟﺒﺘﻪ ﺷﺮﻛﺘﻬﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از اﻓﺮاد ﻣﺘﺨﺼﺺ در اﻳﻦ زﻣﻴﻨﻪ ﻫﺎ‪ ،‬ﻣﺴﺌﻮﻟﻴﺖ اﻳﺠﺎد ﻗـﺴﻤﺖ ﻧـﺼﺐ‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺑﺰرگ را ﺑﺮ ﻋﻬﺪه ﻣﻲ ﮔﻴﺮﻧﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬ﻧﻴﺰ داراي ﻗﺎﺑﻠﻴﺖ ﻫﺎﻳﻲ ﺑﺮاي اﻳﺠﺎد ﻗﺴﻤﺖ ﻧﺼﺐ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎ‬ ‫اﺳﺖ ﻛﻪ ﺑﻴﺸﺘﺮ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﻮﭼﻚ و ﻳﺎ ﻣﺘﻮﺳﻂ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد‪.‬‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﺗﺎ ﻛﻨﻮن در اﻳﻦ ﻛﺘﺎب ﻣﺸﺎﻫﺪه ﻛﺮده اﻳﺪ‪ ،‬ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬ﻣﻲ ﺗﻮان ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺨﺘﻠﻔﻲ را اﻳﺠـﺎد ﻛـﺮد‬ ‫ﻣﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز‪ ،‬ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب‪ ،‬وب ﺳﺮوﻳﺲ ﻫﺎ و ‪ ....‬ﻫﺮ ﻛﺪام از اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ‪ ،‬ﻫﻨﮕـﺎم اﻳﺠـﺎد ﻗـﺴﻤﺖ ﻧـﺼﺐ‬ ‫داراي ﭘﻴﭽﻴﺪﮔﻲ ﻫﺎ و ﻧﻜﺎت ﻣﺨﺼﻮص ﺑﻪ ﺧﻮد ﻫﺴﺘﻨﺪ ﻛﻪ ﺗﻮﺿﻴﺢ ﺗﻤﺎم آﻧﻬﺎ ﺑﻪ ﭼﻨﺪﻳﻦ ﻓﺼﻞ ﻧﻴﺎز دارد‪ .‬ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ در اﻳﻦ ﻓﺼﻞ ﺗﻤﺎم‬ ‫ﻗﺴﻤﺘﻬﺎ و اﺑﺰارﻫﺎي ﻣﻮﺟﻮد ﺑﺮاي اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ در وﻳﮋوال اﺳﺘﻮدﻳﻮ را ﺑﺮرﺳﻲ ﻧﻤﻲ ﻛﻨﻴﻢ‪ ،‬ﺑﻠﻜﻪ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﻧﮕﺎه ﻣﺨﺘﺼﺮي ﺑـﺮ‬ ‫ﭘﺮوﺳﻪ ي ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎ و ﻧﺤﻮه ي اﻧﺠﺎم آن داﺷﺘﻪ ﺑﺎﺷﻴﻢ‪.‬‬ ‫در اﻳﻦ ﻓﺼﻞ‪:‬‬ ‫‬ ‫‬ ‫‬ ‫‬

‫ﺑﺎ ﻣﻔﺎﻫﻴﻢ و اﺻﻄﻼﺣﺎت ﻣﻮﺟﻮد در اﻳﻦ زﻣﻴﻨﻪ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ‪.‬‬ ‫ﺑﺎ ﻧﺤﻮه ي ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﺪون ﻧﻴﺎز ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ‪.‬‬ ‫ﺑﺎ ﭼﮕﻮﻧﮕﻲ اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ‪.‬‬ ‫ﻧﺤﻮه ي ﺗﻐﻴﻴﺮ ﻇﺎﻫﺮ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﻢ ﻛﺮد‪.‬‬

‫ﻣﻨﻈﻮر از ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﭼﻴﺴﺖ؟‬ ‫ﻣﻨﻈﻮر از ﺗﻮزﻳﻊ‪ 1‬ﻳﻚ ﺑﺮﻧﺎﻣﻪ‪ ،‬ﻋﻤﻞ اﻧﺘﻘﺎل ﻧﺴﺨﻪ ﻫﺎي ﻛﭙﻲ از ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﺎي دﻳﮕﺮ اﺳﺖ ﺑﻪ ﻧﺤﻮي ﻛﻪ ﺑﺮﻧﺎﻣـﻪ ﺑﺘﻮاﻧـﺪ در‬ ‫ﻣﺤﻴﻂ ﺟﺪﻳﺪ ﻧﻴﺰ ﻛﺎر ﻛﻨﺪ‪ .‬ﺗﻮزﻳﻊ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﭼﻴﺰي ﻛﻪ ﺷﻤﺎ ﺑﺎ ﻧﺎم ﻧﺼﺐ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺷﻨﺎﺳﻴﺪ ﻣﺘﻔﺎوت اﺳﺖ‪ .‬ﻣﻨﻈـﻮر از ﺗﻮزﻳـﻊ ﻳـﻚ‬ ‫ﺑﺮﻧﺎﻣﻪ‪ ،‬ﻧﺤﻮي ﭘﺨﺶ ﻛﺮدن آن ﺑﺮﻧﺎﻣﻪ در ﺑﻴﻦ اﻓﺮادي اﺳﺖ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻨﺪ از آن اﺳﺘﻔﺎده ﻛﻨﻨﺪ‪ .‬در ﺗﻮزﻳﻊ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻴﺸﺘﺮ ﺑﺎ اﻳﻦ ﻣـﻮرد‬ ‫درﮔﻴﺮ ﻫﺴﺘﻴﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﻳﻚ ﺑﺮﻧﺎﻣﻪ را در اﺧﺘﻴﺎر ﻛﺎرﺑﺮان ﻗﺮار داد و ﻳﺎ ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان آن را ﺑﻪ ﻗﺴﻤﺘﻬﺎﻳﻲ ﻛﻪ‬ ‫ﻣﻲ ﺧﻮاﻫﻴﻢ‪ ،‬ﻣﻨﺘﻘﻞ ﻛﻨﻴﻢ‪.‬‬ ‫اﻣﺎ ﻣﻨﻈﻮر از ﻧﺼﺐ‪ 2‬ﻳﻚ ﺑﺮﻧﺎﻣﻪ‪ ،‬ﭘﺮوﺳﻪ ي ﺑﺎرﮔﺬاري ﺑﺮﻧﺎﻣﻪ در ﺣﺎﻓﻈﻪ‪ ،‬ﭘﻴﻜﺮ ﺑﻨﺪي و ﺳﭙﺲ ﻧﺼﺐ آن اﺳﺖ‪ .‬ﻣﻨﻈﻮر از ﻧـﺼﺐ ﻳـﻚ ﻧـﺮم‬ ‫اﻓﺰار ﻛﺎرﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﺑﺮاي ﭘﻴﻜﺮ ﺑﻨﺪي ﺑﺮﻧﺎﻣﻪ اﻧﺠﺎم ﻣﻲ دﻫﻴﻢ و ﻣﻨﻈﻮر از ﺗﻮزﻳﻊ ﻳﻚ ﻧﺮم اﻓﺰار روﺷﻲ اﺳﺖ ﻛﻪ ﺑﺮاي اﻧﺘﻘﺎل ﻳﻚ ﺑﺮﻧﺎﻣﻪ‬ ‫ﺑﻴﻦ ﻛﺎرﺑﺮان ﺑﻪ ﻛﺎر ﻣﻲ ﺑﺮﻳﻢ‪.‬‬ ‫ﺑﺎ اﻳﻦ ﺗﻮﺿﻴﺤﺎت اﺣﺘﻤﺎﻻً ﺣﺪس زده اﻳﺪ ﻛﻪ ﻳﻜﻲ از روﺷﻬﺎي ﺗﻮزﻳﻊ ﻳﻚ ﻧﺮم اﻓﺰار‪ ،‬اﺳﺘﻔﺎده از ‪ CD‬اﺳﺖ‪ .‬ﻫﻤﭽﻨـﻴﻦ اﻳﻨﺘﺮﻧـﺖ ﻧﻴـﺰ ﻳﻜـﻲ‬ ‫دﻳﮕﺮ از روﺷﻬﺎي ﺗﻮزﻳﻊ ﺑﻪ ﺷﻤﺎر ﻣﻲ رود‪ .‬اﻳﻦ دو روش ﺗﻮزﻳﻊ‪ ،‬ﻣﻤﻜﻦ اﺳﺖ ﻣﺮاﺣﻞ ﻧﺼﺐ ﻣﺘﻔﺎوﺗﻲ را ﻧﻴﺰ اﺣﺘﻴﺎج داﺷﺘﻪ ﺑﺎﺷﻨﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل‬

‫‪Deployment‬‬ ‫‪Setup - Installation‬‬

‫‪1‬‬ ‫‪2‬‬

‫‪٨٥٨‬‬

‫اﮔﺮ از ‪ CD‬ﺑﺮاي ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﺪ‪ ،‬ﺑﺎﻳﺪ ﺗﻤﺎم ﻗﺴﻤﺘﻬﺎي اﺿﺎﻓﻲ ﺑﺮﻧﺎﻣﻪ را ﻧﻴﺰ در آن ﻗﺮار داده و ﺑﻪ ﻣﺮﺣﻠﻪ ي ﻧـﺼﺐ‬ ‫اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪ .‬اﻣﺎ اﻧﺠﺎم اﻳﻦ ﻛﺎر زﻣﺎﻧﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﺑﺮﻧﺎﻣﻪ را از ﻃﺮﻳﻖ اﻳﻨﺘﺮﻧﺖ ﻣﻨﺘﺸﺮ ﻛﻨﻴﺪ ﻣﻨﻄﻘﻲ ﺑﻪ ﻧﻈـﺮ ﻧﻤـﻲ رﺳـﺪ‪ ،‬زﻳـﺮا ﺑـﻪ اﻳـﻦ‬ ‫ﺗﺮﺗﻴﺐ ﺣﺠﻢ ﺑﺮﻧﺎﻣﻪ زﻳﺎد ﺷﺪه و اﻧﺘﻘﺎل آن از ﻃﺮﻳﻖ اﻳﻨﺘﺮﻧﺖ ﻣﺸﻜﻞ ﺧﻮاﻫﺪ ﺷﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﺑﺮﻧﺎﻣـﻪ ي ﺧـﻮد را ﺑـﺎ اﺳـﺘﻔﺎده از‬ ‫‪ CD‬ﺗﻮزﻳﻊ ﻛﻨﻴﺪ ﻣﻲ ﺗﻮاﻧﻴﺪ در ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ از اﺳﻜﺮﻳﭙﺖ ﻫﺎي ﺟﺎوا ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ ،‬زﻳﺮا ﻣﻌﻤﻮﻻً ﻓﺮدي ﻛﻪ از آن ‪ CD‬اﺳـﺘﻔﺎده ﻣـﻲ‬ ‫ﻛﻨﺪ اﺟﺎزه ي اﺟﺮا ﻛﺮدن اﻳﻦ اﺳﻜﺮﻳﭙﺖ ﻫﺎ را ﻧﻴﺰ دارد‪ .‬اﻣﺎ اﮔﺮ ﺑﺨﻮاﻫﻴﺪ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد را ﺑﺎ اﺳـﺘﻔﺎده از اﻳﻨﺘﺮﻧـﺖ ﺗﻮزﻳـﻊ ﻛﻨﻴـﺪ اﺳـﺘﻔﺎده از‬ ‫اﺳﻜﺮﻳﭙﺖ ﻫﺎي ﺟﺎوا ﭼﻨﺪان ﺻﻼح ﻧﻴﺴﺖ زﻳﺮا ﻣﻤﻜﻦ اﺳﺖ اﻳﻨﺘﺮﻧﺖ اﻛﺴﭙﻠﻮرر اﺟﺎزه ي اﺟﺮاي آﻧﻬﺎ را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﺪﻫـﺪ و ﺑﻨـﺎﺑﺮاﻳﻦ ﺑﺮﻧﺎﻣـﻪ‬ ‫ﺑﺮاي ﻧﺼﺐ ﺑﺎ ﻣﺸﻜﻞ ﻣﻮاﺟﻪ ﺷﻮد‪ .‬اﻳﻦ ﻧﻮع ﻣﻼﺣﻈﺎت‪ ،‬ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ روش ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد را اﻧﺘﺨﺎب ﻛﻨﻴـﺪ و ﻳـﺎ ﺑﺨﻮاﻫﻴـﺪ‬ ‫ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ اﻳﺠﺎد ﻛﻨﻴﺪ از اﻫﻤﻴﺖ زﻳﺎدي ﺑﺮﺧﻮردار ﻫﺴﺘﻨﺪ‪.‬‬ ‫ﺣﺎل ﻛﻪ ﺑﺎ اﺻﻄﻼﺣﺎت ﻣﻮﺟﻮد در اﻳﻦ زﻣﻴﻨﻪ آﺷﻨﺎ ﺷﺪﻳﻢ‪ ،‬ﺑﻬﺘﺮ اﺳﺖ ﻧﺤﻮه ي ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎي اﻳﺠﺎد ﺷـﺪه ﺑـﺎ وﻳـﮋوال اﺳـﺘﻮدﻳﻮ را ﻧﻴـﺰ‬ ‫ﺑﺮرﺳﻲ ﻛﻨﻴﻢ‪ .‬در زﻳﺮ ﺑﺎ دو روش ﺳﺎده ي ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ‪.‬‬

‫ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از روش ‪:ClickOnce‬‬ ‫ﻣﻨﻈﻮر از روش ‪ ،ClickOnce‬ارﺳﺎل ﺑﺮﻧﺎﻣﻪ و ﻫﻤﭽﻨﻴﻦ اﺳﻤﺒﻠﻲ ﻫﺎي ﻣﻮرد ﻧﻴﺎز آن ﺑﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻛﺎرﺑﺮ اﺳﺖ ﺑـﻪ ﮔﻮﻧـﻪ اي ﻛـﻪ در‬ ‫ﻣﻮاﻗﻊ ﻣﻮرد ﻧﻴﺎز‪ ،‬ﺑﺮﻧﺎﻣﻪ ﺑﺘﻮاﻧﺪ ﺑﻪ ﺳﺎدﮔﻲ ﺧﻮد را ﺑﻪ روز ﻛﻨﺪ‪ .‬ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ روش‪ ،‬ﺳﻪ راه ﺑﺮاي ﺗﻮزﻳـﻊ ﺑﺮﻧﺎﻣـﻪ وﺟـﻮد دارد‪ :‬اﺳـﺘﻔﺎده از‬ ‫ﻓﺎﻳﻠﻬﺎي ﺑﻪ اﺷﺘﺮاك ﮔﺬاﺷﺘﻪ ﺷﺪه در ﺷﺒﻜﻪ‪ ،‬اﺳﺘﻔﺎده از ﺻﻔﺤﺎت وب و اﺳﺘﻔﺎده از دﻳﺴﻚ ﻫﺎي ﻣﺨﺘﻠﻒ ﻣﺎﻧﻨﺪ ‪ CD‬و ﻳﺎ ‪ .DVD‬اﻟﺒﺘﻪ اﻳـﻦ‬ ‫روش ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﻮﭼﻚ و ﻳﺎ ﻣﺘﻮﺳﻂ ﻣﻨﺎﺳﺐ اﺳﺖ و ﻧﻤﻲ ﺗﻮان از آن ﺑﺮاي ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺑﺰرگ اﺳﺘﻔﺎده ﻛﺮد‪.‬‬ ‫اﺳﺘﻔﺎده از روش ‪ ClickOnce‬ﺑﺮاي ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎ داراي ﺳﻪ ﻣﺰﻳﺖ ﻋﻤﺪه اﺳﺖ‪ .‬ﻣﺰﻳﺖ اول اﻳﻦ اﺳﺖ ﻛـﻪ ﺑـﺎ اﺳـﺘﻔﺎده از اﻳـﻦ‬ ‫روش‪ ،‬ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ﺑﻪ ﺳﺎدﮔﻲ ﻣﻲ ﺗﻮاﻧﺪ ﺧﻮد را ﺑﻪ روز ﻛﻨﺪ‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر ﻛﺎﻓﻲ اﺳﺖ ﻛـﻪ آﺧـﺮﻳﻦ ﻧـﺴﺨﻪ ي ﺑﺮﻧﺎﻣـﻪ را ﺑـﻪ‬ ‫ﺻﻮرت ﻗﺒﻠﻲ ﺑﻴﻦ ﻛﺎرﺑﺮان ﺗﻮزﻳﻊ ﻛﻨﻴﺪ )در ﺷﺒﻜﻪ ﻗﺮار دﻫﻴﺪ‪ ،‬ﺑﺮ روي ﺻﻔﺤﺎت وب ﺑﮕﺬارﻳﺪ و ﻳﺎ ﺑﺎ اﺳﺘﻔﺎده از ‪ CD‬ﺑﻪ ﻛـﺎرﺑﺮان ﺑﺮﺳـﺎﻧﻴﺪ(‪.‬‬ ‫ﺳﭙﺲ ﻣﺮﺗﺒﻪ ي ﺑﻌﺪ ﻛﻪ ﻛﺎرﺑﺮ ﺑﺨﻮاﻫﺪ از ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﺪ‪ ،‬آﺧﺮﻳﻦ ﻧﺴﺨﻪ از ﺑﺮﻧﺎﻣﻪ اﺟﺮا ﺧﻮاﻫﺪ ﺷﺪ‪ .‬ﻣﺰﻳﺖ دوم اﺳﺘﻔﺎده از اﻳﻦ روش در‬ ‫اﻳﻦ اﺳﺖ ﻛﻪ ﻛﺎرﺑﺮان ﺑﺎ ﺣﺪاﻗﻞ ﺳﻄﺢ دﺳﺘﺮﺳﻲ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻨﺪ از ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ اﻳﻦ روش ﺗﻮزﻳﻊ ﻣﻲ ﺷﻮﻧﺪ اﺳـﺘﻔﺎده ﻛﻨﻨـﺪ‪ ،‬در‬ ‫ﺻﻮرﺗﻲ ﻛﻪ در روﺷﻬﺎي دﻳﮕﺮ ﻛﺎرﺑﺮان ﺑﺮاي اﺳﺘﻔﺎده از ﺑﺮﻧﺎﻣﻪ ﻧﻴﺎز دارﻧﺪ ﻛﻪ از ﻣﺪﻳﺮ ﺳﻴﺴﺘﻢ ﺧﻮد اﺟﺎزه درﻳﺎﻓﺖ ﻛﻨﻨﺪ‪ .1‬ﻣﺰﻳـﺖ ﺳـﻮم اﻳـﻦ‬ ‫روش ﻧﻴﺰ در اﻳﻦ اﺳﺖ ﻛﻪ اﺳﺘﻔﺎده از آن ﻛﻤﺘﺮﻳﻦ ﺗﺎﺛﻴﺮ را در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻛﺎرﺑﺮ ﺧﻮاﻫﺪ داﺷﺖ‪ .‬ﺑﺮﻧﺎﻣﻪ ﻓﻘﻂ در ﻓﻮﻟﺪر ﻣﺸﺨﺺ ﺷﺪه ﺑـﺮاي آن‬ ‫ﻗﺮار ﺧﻮاﻫﺪ ﮔﺮﻓﺖ و ﮔﺰﻳﻨﻪ ﻫﺎﻳﻲ را ﺑﻪ ﻣﻨﻮي اﺳﺘﺎرت و ﻗﺴﻤﺖ ‪ Add/Remove Programs‬اﺿﺎﻓﻪ ﺧﻮاﻫﺪ ﻛﺮد‪.‬‬ ‫در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ زﻳﺮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي را ﺑﺎ اﺳﺘﻔﺎده از روش ‪ ClickOnce‬ﺑﻪ وﺳﻴﻠﻪ ي وب ﺗﻮزﻳﻊ ﺧﻮاﻫﻴﻢ ﻛﺮد‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬ﺗﻮزﻳﻊ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ‪ ClickOnce‬ﺑﺎ اﺳﺘﻔﺎده از وب‬ ‫‪ (1‬ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم ‪ ClickOnce‬اﻳﺠﺎد ﻛﻨﻴﺪ‪.‬‬ ‫‪ (2‬ﺑﺎ اﺳﺘﻔﺎده از ﺟﻌﺒﻪ اﺑﺰار ﻳﻚ ﻛﻨﺘﺮل ‪ Button‬و ﻳﻚ ﻛﻨﺘﺮل ‪ Label‬ﺑﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ‪ .‬ﺧﺎﺻـﻴﺖ ‪Name‬‬ ‫ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل ‪ Button‬را ﺑﺮاﺑﺮ ﺑﺎ ‪ btnVersion‬و ﺧﺎﺻﻴﺖ ‪ Text‬آن را ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎ ‪ Version‬ﻗـﺮار‬ ‫دﻫﻴﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ ﺧﺎﺻﻴﺖ ‪ Name‬ﻛﻨﺘﺮل ‪ Label‬را ﻧﻴﺰ ﺑﺎ ﻣﻘﺪار ‪ lblVersion‬ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ‪.‬‬ ‫‪ 1‬ﻣﻨﻈﻮر از اﻳﻦ ﻗﺴﻤﺖ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺮاي اﻳﺠـﺎد ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي ‪ ClickOnce‬ﻻزم ﻧﻴـﺴﺖ ﻛـﻪ ﺣﺘﻤـﺎً اﻛﺎﻧـﺖ ﻣـﻮرد اﺳـﺘﻔﺎده ﺑـﻪ وﺳـﻴﻠﻪ ي ﻛـﺎرﺑﺮ از ﻧـﻮع‬ ‫‪ PowerUser ،Administrator‬و ﻳﺎ اﻛﺎﻧﺖ ﻫﺎﻳﻲ ﺑﺎ ﺳﻄﺢ دﺳﺘﺮﺳﻲ ﺑﺎﻻ ﺑﺎﺷﺪ‪ .‬ﺑﻠﻜﻪ اﻓﺮاد ﺑﺎ اﻛﺎﻧﺖ ﻫﺎي ﻋﺎدي ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻨﺪ اﻳﻦ ﻧـﻮع ﺑﺮﻧﺎﻣـﻪ ﻫـﺎ‬ ‫را اﺟﺮا ﻛﻨﻨﺪ‪.‬‬

‫‪٨٥٩‬‬

‫‪ (3‬روي ﻛﻨﺘﺮل ‪ Button‬دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ‪ btnVersion_Click‬اﻳﺠﺎد ﺷﻮد‪ .‬ﺳـﭙﺲ ﻛـﺪ ﻣـﺸﺨﺺ‬ ‫ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪:‬‬ ‫)‪private void btnVersion_Click(object sender, EventArgs e‬‬ ‫{‬ ‫;"‪lblVersion.Text = "Version 1.0‬‬ ‫}‬

‫‪ (4‬ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﺪ ﺗﺎ ﻋﻤﻠﻜﺮد آن را ﺗﺴﺖ ﻛﻨﻴﻢ‪ .‬ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي دﻛﻤﻪ ي ‪ Version‬ﻋﺒﺎرت ‪“Version‬‬ ‫”‪ 1.0‬ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪ 1-21‬در ﻛﻨﺘﺮل ‪ Label‬ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ‪ .‬ﺣـﺎل ﺑﺮﻧﺎﻣـﻪ را ﺑﺒﻨﺪﻳـﺪ و ﺑـﻪ ﻣﺤـﻴﻂ وﻳـﮋوال‬ ‫اﺳﺘﻮدﻳﻮ ﺑﺮﮔﺮدﻳﺪ‪ .‬ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﻧﻮاي ﻣﻨﻮ ﮔﺰﻳﻨـﻪ ي ‪ Build  Build ClickOnce‬را اﻧﺘﺨـﺎب‬ ‫ﻛﻨﻴﺪ ﺗﺎ ﺑﺮﻧﺎﻣﻪ ﻛﺎﻣﭙﺎﻳﻞ ﺷﻮد‪.‬‬

‫ﺷﻜﻞ ‪1-21‬‬ ‫‪ (5‬ﺣﺎل ﺑﺎﻳﺪ اﺳﻤﺒﻠﻲ اﻳﺠﺎد ﺷﺪه را ﺑﺎ اﺳﺘﻔﺎده از وب ﺗﻮزﻳﻊ ﻛﻨﻴﻢ‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر از ‪ IIS‬ﻣﺤﻠﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨـﻴﻢ‪ .‬اﮔـﺮ ‪IIS‬‬ ‫در ﻛﺎﻣﭙﻴﻮﺗﺮ ﺷﻤﺎ ﭘﻴﻜﺮ ﺑﻨﺪي ﻧﺸﺪه اﺳﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ از روﺷﻬﺎي دﻳﮕﺮ ﺑﺮاي ﺗﻮزﻳﻊ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬ ‫ﻧﻜﺘـﻪ‪ :‬ﺑـﺮاي راه اﻧـﺪازي اوﻟﻴـﻪ ي ‪ IIS‬ﺑـﺎ اﺳـﺘﻔﺎده از ‪ Control Panel‬ﺑـﻪ ﻗـﺴﻤﺖ ‪Add Or Remove‬‬ ‫‪ Programs‬ﺑﺮوﻳﺪ و از ﺳﻤﺖ ﭼﭗ ﺻﻔﺤﻪ‪ ،‬ﮔﺰﻳﻨﻪ ي ‪ Add/Remove Windows Components‬را اﻧﺘﺨﺎب‬ ‫ﻛﻨﻴـﺪ‪ .‬در ﻛـﺎدر ‪ ،Windows Component Wizard‬ﮔﺰﻳﻨـﻪ ي ‪Internet Information‬‬ ‫)‪ Services (IIS‬را از ﻗﺴﻤﺖ ‪ components‬اﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤﻪ ي ‪ Next‬ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ ﺗـﺎ ‪IIS‬‬ ‫ﻧﺼﺐ ﺷﻮد‪.‬‬ ‫‪ (6‬ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي ‪ Solution Explorer‬روي ﻧﺎم ﭘﺮوژه ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨﻮي ﺑﺎز ﺷـﺪه ﮔﺰﻳﻨـﻪ‬ ‫ي …‪ Publish‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎدر ‪ Publish Wizard‬ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪ 2-21‬ﻧﻤـﺎﻳﺶ داده‬ ‫ﺧﻮاﻫﺪ ﺷﺪ‪ .‬در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻣﻜﺎﻧﻲ را ﺑﺮاي ﺗﻮزﻳﻊ ﻓﺎﻳﻠﻬﺎي ﺑﺮﻧﺎﻣﻪ اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬در اﻳﻦ ﻣﺜﺎل ﻣﻜﺎن ﭘـﻴﺶ ﻓـﺮض را‬ ‫ﻗﺒﻮل ﻣﻲ ﻛﻨﻴﻢ‪.‬‬

‫‪٨٦٠‬‬

‫ﺷﻜﻞ ‪2-21‬‬ ‫‪ (7‬روي دﻛﻤﻪ ي ‪ Next‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﺑﻪ ﻣﺮﺣﻠﻪ ي دوم وﻳﺰارد ﺑﺮوﻳﺪ‪ .‬در اﻳﻦ ﻗﺴﻤﺖ ﻣﻲ ﺗﻮاﻧﻴﺪ اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﻛﻪ آﻳﺎ ﺑﺮﻧﺎﻣـﻪ‬ ‫ﺷﻮرت ﻛﺎت ﺧﻮد را در ﻣﻨﻮي اﺳﺘﺎرت و ﻗﺴﻤﺖ ‪ Add or Remove Programs‬ﻗﺮار دﻫﺪ ﻳـﺎ ﻧـﻪ؟ ﻫﻤﺎﻧﻨـﺪ‬ ‫ﺷﻜﻞ ‪ 3-21‬ﮔﺰﻳﻨﻪ ي ‪ Yes‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪.‬‬

‫ﺷﻜﻞ ‪3-21‬‬ ‫‪ (8‬ﺑﺎ ﻛﻠﻴﻚ روي دﻛﻤﻪ ي ‪ Next‬اﻃﻼﻋﺎﺗﻲ در ﻣﻮرد ﺗﻨﻈﻴﻤﺎت اﻧﺠﺎم ﺷﺪه ﻃﻲ اﻳﻦ وﻳﺰارد ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ‪ .‬رﻳﻮ دﻛﻤﻪ‬ ‫ي ‪ Finish‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ وﻳﺰارد ﺑﺴﺘﻪ ﺷﻮد‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺻﻔﺤﻪ ي وﺑﻲ ﻛﻪ ﻛﺎرﺑﺮان ﺑـﺮاي ﻧـﺼﺐ ﺑﺮﻧﺎﻣـﻪ ﻣـﺸﺎﻫﺪه‬ ‫ﺧﻮاﻫﻨﺪ ﻛﺮد ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ )ﺷﻜﻞ ‪ .(4-21‬روي ﻟﻴﻨﻚ ‪ Install‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻧﺼﺐ ﺑﺮﻧﺎﻣﻪ ﺷﺮوع ﺷﻮد‪.‬‬

‫‪٨٦١‬‬

‫ﺷﻜﻞ ‪4-21‬‬ ‫‪ (9‬ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻟﻴﻨﻚ ‪ Install‬را در اﻳﻦ ﺻﻔﺤﻪ ﻓﺸﺎر دﻫﻴﺪ‪ ،‬ﻣﻤﻜﻦ اﺳﺖ ﻳﻚ ﻫﺸﺪار اﻣﻨﻴﺘﻲ ﺑﻪ وﺳﻴﻠﻪ ي وﻳﻨﺪوز ﻫﻤﺎﻧﻨﺪ‬ ‫ﺷﻜﻞ ‪ 5-21‬ﻧﻤﺎﻳﺶ داده ﺷﻮد‪ .‬اﮔﺮ ﭼﻨﻴﻦ ﭘﻨﺠﺮه اي ﻧﻤﺎﻳﺶ داده ﺷﺪ‪ ،‬روي دﻛﻤﻪ ي ‪ Install‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗـﺎ ﻧـﺼﺐ‬ ‫ﺑﺮﻧﺎﻣﻪ اداﻣﻪ ﭘﻴﺪا ﻛﻨﺪ و ﺳﭙﺲ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ داده ﺷﻮد‪ .‬در ﺑﺮﻧﺎﻣﻪ‪ ،‬روي دﻛﻤﻪ ي ‪ Version‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﻣـﺸﺎﻫﺪه‬ ‫ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻋﺒﺎرت ‪ Version 1.0‬در ﻓﺮم ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮد‪.‬‬ ‫‪ (10‬ﺑﻪ ﻓﻮﻟﺪر ﻣﺮﺑﻮط ﺑﻪ ‪ Program Files‬ﺑﺮوﻳﺪ‪ .‬ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ ﻫﻴﭻ ﻓﺎﻳﻠﻲ ﻣﺮﺑﻮط ﺑﻪ اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ در اﻳـﻦ‬ ‫ﻓﻮﻟﺪر ﻗﺮار ﻧﮕﺮﻓﺘﻪ اﺳﺖ‪ ،‬اﻣﺎ ﺷﻮرت ﻛﺎﺗﻲ ﺑﺮاي اﺟﺮاي اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑـﻪ ﻗـﺴﻤﺖ ‪ All Programs‬از ﻣﻨـﻮي اﺳـﺘﺎرت‬ ‫اﺿﺎﻓﻪ ﺷﺪه اﺳﺖ‪ .‬ﺣﺎل ﺑﺮﻧﺎﻣﻪ را ﺗﻐﻴﻴﺮ ﺧﻮاﻫﻴﻢ داد‪ ،‬ﺗﺎ ﻧﺤﻮه ي ﺑﻪ روز ﺷﺪن آن را ﻧﻴﺰ ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ‪.‬‬ ‫‪ (11‬ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ‪ ClickOnce‬در وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺮﮔﺮدﻳﺪ و ﻛﺪ ﻣﻮﺟﻮد در ﻣﺘﺪ ‪ btnVersion_Click‬را ﺑﻪ‬ ‫ﺻﻮرت زﻳﺮ ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺗﺎ ﻋﺒﺎرت ‪ Version 1.1‬را در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ دﻫﺪ‪:‬‬ ‫)‪private void btnVersion_Click(object sender, EventArgs e‬‬ ‫{‬ ‫;"‪lblVersion.Text = "Version 1.1‬‬ ‫}‬

‫‪٨٦٢‬‬

‫ﺷﻜﻞ ‪5-21‬‬ ‫‪(12‬‬ ‫‪(13‬‬

‫‪(14‬‬

‫‪(15‬‬ ‫‪(16‬‬

‫ﻋﻤﻠﻜﺮد ﺑﺮﻧﺎﻣﻪ را ﺗﺴﺖ ﻛﺮده و ﺳﭙﺲ آن را ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﻴﺪ‪.‬‬ ‫در ﭘﻨﺠﺮه ي ‪ Solution Explorer‬روي ﻧﺎم ﭘﺮوژه ﻛﻠﻴـﻚ راﺳـﺖ ﻛـﺮده و از ﻣﻨـﻮي ﺑـﺎز ﺷـﺪه ﮔﺰﻳﻨـﻪ ي‬ ‫‪ Properties‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ در ﭘﻨﺠﺮه اي ﻛﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد روي ﻟﺒﻪ ي ‪ Publish‬در ﺳﻤﺖ‬ ‫ﭼﭗ ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪.‬‬ ‫ﺑﻪ ﮔﺰﻳﻨﻪ ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ وﺟﻮد دارد ﻧﮕﺎه ﻛﻨﻴﺪ‪ .‬ﺗﻤﺎم ﺗﻨﻈﻴﻤﺎﺗﻲ ﻛﻪ در وﻳﺰارد اﻧﺠﺎم دادﻳﻢ‪ ،‬در اﻳﻦ ﺻﻔﺤﻪ وﺟﻮد دارﻧﺪ‬ ‫و ﻣﻲ ﺗﻮاﻧﻴﻢ آﻧﻬﺎ را ﺗﻐﻴﻴﺮ دﻫﻴﻢ‪ .‬ﺑﻌﺪ از اﻳﺠﺎد ﺗﻐﻴﻴﺮات ﻣﻮرد ﻧﻈﺮ ﺧﻮد در اﻳﻦ ﻗﺴﻤﺖ ﻛﺎﻓﻲ اﺳﺖ ﻛـﻪ در ﭘـﺎﻳﻴﻦ ﺻـﻔﺤﻪ روي‬ ‫دﻛﻤﻪ ي ‪ Publish Now‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪.‬‬ ‫ﻣﺠﺪداً ﺻﻔﺤﻪ ي ﻧﺼﺐ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد‪ ،‬اﻣﺎ در اﻳﻦ ﻗﺴﻤﺖ ﻻزم ﻧﻴﺴﺖ ﻛﻪ روي ﻟﻴﻨﻚ ‪ Install‬ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ‪.‬‬ ‫ﻣﻲ ﺗﻮاﻧﻴﺪ اﻳﻦ ﻓﺮم را ﺑﺒﻨﺪﻳﺪ‪.‬‬ ‫ﺣﺎل ﺑﺎ اﺳﺘﻔﺎده از ﻣﻨﻮي ‪ Start‬ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﺮده و روي دﻛﻤﻪ ي ‪ Version‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﭘﻴﻐـﺎﻣﻲ ﻧﻤـﺎﻳﺶ داده‬ ‫ﺷﺪه و اﻋﻼم ﻣﻲ ﻛﻨﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺗﻐﻴﻴﺮ ﻛﺮده اﺳﺖ‪ .‬آﻳﺎ ﻣﻲ ﺧﻮاﻫﻴﺪ آن را ﺑﻪ روز ﻛﻨﻴﺪ )ﺷـﻜﻞ ‪(6-21‬؟ روي دﻛﻤـﻪ ي ‪Yes‬‬ ‫ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﺑﻌﺪ از اﻳﻨﻜﻪ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﺑﺎز ﺷﺪ‪ ،‬روي دﻛﻤﻪ ي ‪ Version‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛـﺮد ﻛـﻪ ﻋﺒـﺎرت‬ ‫‪ Version 1.1‬در ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ روش ﺑﺴﻴﺎر ﺳﺎده ﺑﻮد‪ .‬ﺑﻌﺪ از ﭼﻨﺪ ﺑـﺎر ﻛﻠﻴـﻚ ﻛـﺮدن‪ ،‬ﺗﻮاﻧـﺴﺘﻴﺪ ﻛـﻪ ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ ي‬ ‫وﻳﻨﺪوزي را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻮزﻳﻊ ﻛﻨﻴﺪ ﺗﺎ ﺑﺘﻮاﻧﺪ در ﻣﻮاﻗﻊ ﺿﺮوري ﺧﻮد را ﺑﻪ روز ﻛﻨﺪ‪ .‬وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺎ اﻧﺠﺎم دادن ﻛﺎرﻫﺎي زﻳـﺎدي ﺳـﻌﻲ‬ ‫ﻛﺮده اﺳﺖ ﻛﻪ ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﺎرﺑﺮدي ﺑﺎ اﻳﻦ روش را ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﺳﺎده ﻧﮕﻪ دارد‪.‬‬ ‫اﺑﺘﺪا ﻣﻜﺎﻧﻲ را در وب ﺳﺮور ﻣﺸﺨﺺ ﻛﺮدﻳﻢ ﺗﺎ ﻓﺎﻳﻠﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﻧﺼﺐ ﺑﺮﻧﺎﻣﻪ در آن ﻗﺮار ﮔﻴﺮﻧﺪ و اﻓﺮاد دﻳﮕـﺮ ﺑﺘﻮاﻧﻨـﺪ ﺑـﻪ اﻳـﻦ ﻓﺎﻳﻠﻬـﺎ‬ ‫دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻨﺪ‪ .‬ﺑﺮاي ﻣﺸﺎﻫﺪه ي ﻓﺎﻳﻠﻬﺎﻳﻲ ﻛﻪ در ﻓﻮﻟﺪر ﻣﺠﺎزي ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ در وب ﺳـﺮور ﻗـﺮار ﮔﺮﻓﺘـﻪ اﻧـﺪ‪IIS ،‬‬

‫‪٨٦٣‬‬

‫‪ MMC‬را ﺑﺎز ﻛﻨﻴﺪ‪ .1‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﻨﺠﺮه اي ﻣﺸﺎﺑﻪ ﺷﻜﻞ ‪ 7-21‬ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ‪ .‬ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﻫﺮ ﻧﺴﺨﻪ از ﺑﺮﻧﺎﻣﻪ داراي ﻳـﻚ‬ ‫ﻓﻮﻟﺪر ﻣﺨﺼﻮص ﺑﻪ ﺧﻮد اﺳﺖ‪ .‬ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض اﮔﺮ ﭼﺎرﭼﻮب ‪ .NET‬در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻛﺎرﺑﺮ ﻧﺼﺐ ﻧﺸﺪه ﺑﺎﺷﺪ‪ ،‬ﺑﺎ اﺳـﺘﻔﺎده از ﺳـﺎﻳﺖ‬ ‫ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺻﻮرت اﺗﻮﻣﺎﺗﻴﻚ ﻧﺼﺐ ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬

‫ﺷﻜﻞ ‪6-21‬‬

‫ﺷﻜﻞ ‪7-21‬‬ ‫در ﻣﺮﺣﻠﻪ ي ﺑﻌﺪ از وﻳﺰارد ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ ﻛﻪ آﻳﺎ ﺑﺮﻧﺎﻣﻪ ﺑﺪون اﺗﺼﺎل ﺑﻪ اﻳﻨﺘﺮﻧﺖ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﺪ ﻗﺎﺑـﻞ دﺳﺘﺮﺳـﻲ ﺑﺎﺷـﺪ ﻳـﺎ ﻧـﻪ؟ در‬ ‫ﺻﻮرﺗﻲ ﻛﻪ ﺑﺨﻮاﻫﻴﺪ ﺑﺮﻧﺎﻣﻪ ﺑﺪون اﺗﺼﺎل ﺑﻪ اﻳﻨﺘﺮﻧﺖ ﻧﻴﺰ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﺑﺎﺷﺪ‪ ،‬ﻳﻚ ﻧﺴﺨﻪ از آن در ﻗﺴﻤﺘﻲ از ﻛﺎﻣﭙﻴﻮﺗﺮ ﺷﻤﺎ ﻗـﺮار ﺧﻮاﻫـﺪ‬ ‫ﮔﺮﻓـﺖ و ﻫﻤﭽﻨـﻴﻦ ﺷـﻮرت ﻛـﺎت ﻣﺮﺑـﻮط ﺑـﻪ اﺟـﺮاي آن ﻧﻴـﺰ ﺑـﻪ ﻣﻨـﻮي ‪ Start‬و ﻗـﺴﻤﺖ ‪Add or Remove‬‬ ‫‪ 1‬ﺑﺮاي ﻣﺸﺎﻫﺪه ي اﻳﻦ ﻗﺴﻤﺖ ﺣﺘﻤﺎً ﺑﺎﻳﺪ اﺑﺘﺪا ‪ IIS‬را در ﻛﺎﻣﭙﻴﻮﺗﺮ ﺧﻮد ﻧﺼﺐ ﻛﻨﻴﺪ‪ .‬ﺳـﭙﺲ ﻣـﻲ ﺗﻮاﻧﻴـﺪ از ﻗـﺴﻤﺖ ‪Administrative Tools‬‬ ‫ﮔﺰﻳﻨﻪ ي ‪ Internet Information Services‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ ﭘﻨﺠﺮه ي ﻣﺮﺑﻮط ﺑﻪ ‪ IIS MMC‬ﻧﻤﺎﻳﺶ داده ﺷﻮد‪.‬‬

‫‪٨٦٤‬‬

‫‪ Programs‬اﺿﺎﻓﻪ ﺧﻮاﻫﺪ ﺷﺪ‪ .‬در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﻛﺎرﺑﺮ ﻫﺮ ﺑﺎر ﻛﻪ ﺑﺨﻮاﻫﺪ ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﺪ ﺑﺎﻳﺪ ﺑﻪ وب ﺳﺮور ﻣﺮﺑﻮﻃـﻪ ﻣﺘـﺼﻞ‬ ‫ﺷﻮد‪.‬‬ ‫ﻫﻤﻴﻦ ﺑﻮد‪ .‬ﻫﻨﮕﺎﻣﻲ ﻛﻪ روي دﻛﻤﻪ ي ‪ Finish‬ﻛﻠﻴﻚ ﻣﻲ ﻛﻨﻴﺪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺗﻤﺎم ﻛﺎرﻫﺎي ﻻزم را اﻧﺠﺎم ﻣﻲ دﻫﺪ‪ .‬اﻟﺒﺘـﻪ ﻫـﻴﭻ‬ ‫ﻛﺎر ﺟﺎدوﻳﻲ و ﻳﺎ ﻋﺠﻴﺒﻲ در اﻳﻦ ﻗﺴﻤﺖ رخ ﻧﻤﻲ دﻫﺪ و ﺧﻮدﺗﺎن ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺻﻮرت دﺳﺘﻲ و ﺑـﺪون وﻳـﮋوال اﺳـﺘﻮدﻳﻮ اﻳـﻦ ﻛـﺎر را‬ ‫اﻧﺠﺎم دﻫﻴﺪ‪.‬‬ ‫‪1‬‬ ‫ﺑﻪ ﺷﻜﻞ ‪ 7-21‬ﻧﮕﺎه ﻛﻨﻴﺪ ﺗﺎ ﺗﻮﺿﻴﺢ دﻫﻢ در اﻳﻦ ﻗﺴﻤﺖ ﭼﻪ اﺗﻔﺎﻗﻲ رخ داده اﺳﺖ‪ .‬ﺑﺮاي اﻳﻦ ﻛـﺎر اﺑﺘـﺪا ﻳـﻚ داﻳﺮﻛﺘـﻮري ﻣﺠـﺎزي در‬ ‫‪ IIS‬اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ‪ .‬اﻳﻦ ﻓﻮﻟﺪر ﻣﻜﺎﻧﻲ اﺳﺖ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﻪ وﺳﻴﻠﻪ ي آن ﺗﻮزﻳﻊ ﻣﻲ ﺷـﻮد‪ .‬ﺳـﭙﺲ ﺑـﺎزاي ﻫـﺮ ﻧـﺴﺨﻪ از ﺑﺮﻧﺎﻣـﻪ‪ ،‬ﻳـﻚ‬ ‫داﻳﺮﻛﺘﻮري ﺟﺪﻳﺪ اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد و ﻓﺎﻳﻠﻬﺎي ﻣﺮﺑﻮط ﺑﻪ آن ﻧﺴﺨﻪ را در داﻳﺮﻛﺘﻮري اﻳﺠﺎد ﺷﺪه ﻗﺮار ﻣﻲ دﻫﻴﻢ‪.‬‬ ‫ﺑﻘﻴﻪ ي ﻓﺎﻳﻠﻬﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ در داﻳﺮﻛﺘﻮري اﺻﻠﻲ ﻗﺮار ﺧﻮاﻫﻨﺪ ﮔﺮﻓﺖ‪ .‬اﻳﻦ ﻓﺎﻳﻠﻬﺎ ﺷـﺎﻣﻞ ﻳـﻚ ﺻـﻔﺤﻪ ي وب ﺑـﻪ ﻧـﺎم‬ ‫‪ Publish.htm‬و ﻳﻚ ﻓﺎﻳﻞ اﺟﺮاﻳﻲ ﺑﺮاي ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻧﺎم ‪ setup.exe‬و ‪...‬اﺳﺖ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﺮ ﺑﺎر ﻛﻪ ﺑﺨﻮاﻫﻴﻢ‬ ‫ﺑﺮﻧﺎﻣﻪ را اﺟﺮا ﻛﻨﻴﻢ‪ ،‬اﺑﺘﺪا ﺑﻪ ﺻﻔﺤﻪ ي ‪ publish.htm‬ﻣﺘﺼﻞ ﺧﻮاﻫﻴﻢ ﺷﺪ‪ .‬ﺳﭙﺲ ﻳﻚ ﺑﺮرﺳﻲ اﻧﺠﺎم ﻣﻲ ﺷﻮد ﺗﺎ ﻣﺸﺨﺺ ﺷﻮد‬ ‫ﻧﺴﺨﻪ اي از ﺑﺮﻧﺎﻣﻪ ﻛﻪ در ﺣﺎل اﺳﺘﻔﺎده از آن ﻫﺴﺘﻴﻢ‪ ،‬آﺧﺮﻳﻦ ﻧﺴﺨﻪ اﺳﺖ و ﻳﺎ ﻧﺴﺨﻪ ي ﺟﺪﻳﺪ ﺗـﺮ از آن ﻧﻴـﺰ در ﺳـﺮور ﻗـﺮار داده ﺷـﺪه‬ ‫اﺳﺖ؟ اﮔﺮ ﻧﺴﺨﻪ ي ﺟﺪﻳﺪ ﺗﺮي در ﺳﺮور ﻗﺮار داﺷﺘﻪ ﺑﺎﺷﺪ‪ ،‬ﭘﻴﻐﺎﻣﻲ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد و اﻳﻦ اﺟﺎزه را ﻣﻲ دﻫﺪ ﺗﺎ ﺑﺘﻮاﻧﻴﻢ ﺑﺮﻧﺎﻣـﻪ را ﺑـﻪ‬ ‫روز ﻛﻨﻴﻢ‪.‬‬

‫ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از روش ‪:XCOPY‬‬ ‫در ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ‪ DOS‬دﺳﺘﻮري ﺑﻪ ﻧﺎم ‪ XCOPY‬وﺟﻮد داﺷﺖ ﻛﻪ ﻳﻚ ﻓﻮﻟﺪر و ﺗﻤﺎم ﻣﺤﺘﻮﻳﺎت درون آن را ﺑﻪ ﻣﻜـﺎن دﻳﮕـﺮي ﻛﭙـﻲ‬ ‫ﻣﻲ ﻛﺮد‪ .‬ﻧﺎم اﻳﻦ روش ﻧﻴﺰ از اﻳﻦ دﺳﺘﻮر ﮔﺮﻓﺘﻪ ﺷﺪه اﺳﺖ‪ ،‬زﻳﺮا ﻋﻤﻠﻜﺮد ﻫﺮ دو ﻧﺴﺒﺘﺎً ﻣﺸﺎﺑﻪ اﺳﺖ‪ .‬اﻳﻦ روش ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﻏﻠﺐ ﺑﺮاي‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب ﺑﻪ ﻛﺎر ﻣﻲ رﻓﺖ‪ ،‬اﻣﺎ ﺑﺎ اﺳﺘﻔﺎده از ‪ .NET‬ﻣﻲ ﺗﻮان ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي را ﻧﻴﺰ ﺑﻪ ﻫﻤﻴﻦ روش ﺗﻮزﻳﻊ ﻛﺮد‪.‬‬ ‫ﻣﻲ داﻧﻴﺪ ﻛﻪ ﻳﻚ اﺳﻤﺒﻠﻲ در ‪ .NET‬ﻣﻲ ﺗﻮاﻧﺪ ﺑﺪون ﺛﺒﺖ ﺷﺪن در رﺟﻴﺴﺘﺮي و ﻳﺎ اﻧﺠﺎم ﻛﺎرﻫﺎﻳﻲ از اﻳﻦ ﻗﺒﻴﻞ اﺟﺮا ﺷـﻮد و ﻓﻘـﻂ ﻻزم‬ ‫اﺳﺖ ﻛﻪ ﻓﺎﻳﻠﻬﺎي ﻣﻮرد ﻧﻴﺎز آن در ﻓﻮﻟﺪري ﻛﻪ اﺳﻤﺒﻠﻲ در آن ﻗﺮار دارد ﻛﭙﻲ ﺷﻮد‪ .‬اﻳﻦ ﻣـﻮرد ﺷـﺎﻣﻞ ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ ي وﻳﻨـﺪوزي ﺗﺤـﺖ‬ ‫‪ .NET‬ﻧﻴﺰ ﻣﻲ ﺷﻮد‪ .‬ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻓﺎﻳﻞ اﺟﺮاﻳﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ ‪ .NET‬ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﺪ در ﻳﻚ ﺳﻴﺴﺘﻢ دﻳﮕﺮ اﺟـﺮا ﺷـﻮد‪،‬‬ ‫ﻓﻘﻂ ﺑﻪ ﻓﺎﻳﻠﻬﺎﻳﻲ ﻧﻴﺎز دارد ﻛﻪ در ﻓﻮﻟﺪر آن ﻗﺮار دارد‪ .2‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ اﻧﺘﻘﺎل ﻓﻮﻟﺪر ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﺑـﻪ ﻫﻤـﺮاه ﺗﻤـﺎم ﻣﺤﺘﻮﻳـﺎت آن )ﻫﻤﺎﻧﻨـﺪ‬ ‫دﺳﺘﻮر ‪ (XCOPY‬ﻣﻲ ﺗﻮان ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﺳﻴﺴﺘﻢ دﻳﮕﺮي اﻧﺘﻘﺎل داد‪ .‬اﻟﺒﺘﻪ دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ در اﻳﻦ ﺻﻮرت ﺑﺮﻧﺎﻣـﻪ ﻧﺒﺎﻳـﺪ از اﺳـﻤﺒﻠﻲ ﻫـﺎي‬ ‫ﻣﺸﺘﺮك ﻛﻪ در ‪ GAC‬ﻧﺼﺐ ﻣﻲ ﺷﻮﻧﺪ اﺳﺘﻔﺎده ﻛﻨﺪ و ﻓﻘﻂ ﻣﻲ ﺗﻮاﻧﺪ اﺳﻤﺒﻠﻲ ﻫﺎي ﻣﻮﺟﻮد در ‪ .NET‬و ﻳﺎ اﺳﻤﺒﻠﻲ ﻫﺎﻳﻲ ﻛﻪ در ﻓﻮﻟـﺪر‬ ‫ﺑﺮﻧﺎﻣﻪ ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ را ﺑﻪ ﻛﺎر ﺑﺮد‪.‬‬

‫اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪:2005‬‬

‫‪ 1‬ﻣﻨﻈﻮر از داﻳﺮﻛﺘﻮري ﻣﺠﺎزي‪ ،‬ﻓﻮﻟﺪري در وب ﺳﺮور اﺳﺖ ﻛﻪ اﻓﺮاد ﺧﺎرج از وب ﺳﺮور ﺑﺎ اﺳﺘﻔﺎده از ﻧﺎﻣﻲ ﺧﺎص ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ اﻃﻼﻋﺎت درون آن دﺳﺘﺮﺳـﻲ داﺷـﺘﻪ‬ ‫ﺑﺎﺷﻨﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل در اﻳﻨﺠﺎ ﻳﻚ ﻓﻮﻟﺪر ﺑﻪ ﻧﺎم ‪ ClickOnce‬در ﻛﺎﻣﭙﻴﻮﺗﺮ وب ﺳﺮور اﻳﺠﺎد ﻛﺮده و ﺳﭙﺲ ﻧـﺎم ‪ /ClickOnce‬را ﺑـﻪ آن اﺧﺘـﺼﺎص ﻣـﻲ‬ ‫دﻫﻴﻢ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎرﺑﺮ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺎ ﻣﺸﺨﺺ ﻛﺮدن ﻧﺎم وب ﺳﺮور و ﺳﭙﺲ ﻣﺸﺨﺺ ﻛﺮدن ﻧـﺎم داﻳﺮﻛﺘـﻮري ﻣﺠـﺎزي ﻣـﻮرد ﻧﻈـﺮ ﺧـﻮد‪ ،‬ﺑـﻪ اﻃﻼﻋـﺎت درون آن‬ ‫دﺳﺘﺮﺳـــﻲ داﺷـــﺘﻪ ﺑﺎﺷـــﺪ‪ .‬ﺑـــﺮاي ﻣﺜـــﺎل در اﻳﻨﺠـــﺎ ﺑـــﺮاي دﺳﺘﺮﺳـــﻲ ﺑـــﻪ اﻃﻼﻋـــﺎت اﻳـــﻦ داﻳﺮﻛﺘـــﻮري ﻣﺠـــﺎزي ﻣـــﻲ ﺗـــﻮاﻧﻴﻢ از آدرس‬ ‫‪ http://localhost/ClickOnce‬اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪.‬‬ ‫‪ 2‬اﻟﺒﺘﻪ ‪ .NET Framework‬ﻧﻴﺰ ﺑﺎﻳﺪ در ﺳﻴﺴﺘﻢ ﻣﻘﺼﺪ ﻧﺼﺐ ﺷﺪه ﺑﺎﺷﺪ‪.‬‬

‫‪٨٦٥‬‬

‫وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬ﺑﺮاي اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻧﺼﺐ از ﻧﺼﺐ ﻛﻨﻨﺪه ي وﻳﻨﺪوز اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ‪ .‬ﺳﺮوﻳﺲ ﻧﺼﺐ ﻛﻨﻨﺪه ي وﻳﻨﺪوز‪ ،‬ﻳـﻚ‬ ‫ﭘﺎﻳﮕﺎه ﻛﻠﻲ ﺑﺮاي ﻧﺼﺐ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﮔﻮﻧﺎﮔﻮن در ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ وﻳﻨﺪوز اﺳﺖ‪ .‬اﻳﻦ ﺳﺮوﻳﺲ ﻗﺎﺑﻠﻴﺘﻬﺎي زﻳﺎدي از ﻗﺒﻴﻞ ﻗﺎﺑﻠﻴﺖ ﺣﺬف ﺑﺮﻧﺎﻣﻪ‬ ‫ﻫﺎي ﻧﺼﺐ ﺷﺪه‪ ،‬ﻗﺎﺑﻠﻴﺖ ﻧﺼﺐ ﺗﺮاﻛﻨﺸﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ )ﺣﺬف ﺑﺮﻧﺎﻣﻪ از ﻛﺎﻣﭙﻴﻮﺗﺮ‪ ،‬در ﺻﻮرﺗﻲ ﻛـﻪ ﻋﻤـﻞ ﻧـﺼﺐ آن در ﻫـﺮ ﻣﺮﺣﻠـﻪ اي ﺑـﺎ‬ ‫ﺷﻜﺴﺖ ﻣﻮاﺟﻪ ﺷﻮد( و ﺑﺴﻴﺎري دﻳﮕﺮ را ﻓﺮاﻫﻢ ﻣﻲ ﻛﻨﺪ‪ .‬ﺑﺴﻴﺎري از اﻳﻦ ﻗﺎﺑﻠﻴﺖ ﻫﺎ ﺑﻪ ﺻﻮرت دروﻧﻲ ﻗﺎﺑﻞ دﺳﺘﺮس ﻫﺴﺘﻨﺪ و ﻻزم ﻧﻴﺴﺖ‬ ‫ﺑﺮاي اﺳﺘﻔﺎده از آﻧﻬﺎ ﺗﻨﻈﻴﻢ ﺧﺎﺻﻲ را اﻧﺠﺎم دﻫﻴﺪ‪ .‬ﺑﺮاي اﺳﺘﻔﺎده از ﻗﺎﺑﻠﻴﺘﻬﺎي دﻳﮕﺮ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻧﺼﺐ ﻛﻨﻨﺪه ي وﻳﻨـﺪوز را ﺑـﻪ ﺻـﻮرت‬ ‫ﻣﻮرد ﻧﻈﺮ ﺧﻮد ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ‪.‬‬ ‫ﭘﺸﺘﻴﺒﺎﻧﻲ وﻳﮋوال اﺳﺘﻮدﻳﻮ از ﻧﺼﺐ ﻛﻨﻨﺪه ي وﻳﻨﺪوز ﺑﺎﻋﺚ ﺷﺪه اﺳﺖ ﻛﻪ ﺑﻪ ﺳﺎدﮔﻲ ﺑﺘﻮان ﺑﺎ اﺳﺘﻔﺎده از ﻛﺎدر ‪ New Project‬در‬ ‫وﻳﮋوال اﺳﺘﻮدﻳﻮ‪ ،‬ﺑﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي اﻳﺠﺎد ﺷﺪه در ‪ .NET‬ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ اﻳﺠﺎد ﻛﺮده و از آن اﺳﺘﻔﺎده ﻛﺮد‪.‬‬ ‫ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﭘﺮوژه ي ﻧﺼﺐ ﺑﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ‪ ،‬وﻳﮋوال اﺳﺘﻮدﻳﻮ داراي ﭘﻨﺞ ﻗﺎﻟﺐ ﻛﻠﻲ در ﻛﺎدر ‪ New Project‬اﺳﺖ‪:‬‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬

‫‪ Setup Project‬ﺑﺮاي اﻳﺠﺎد ﻧﺼﺐ ﻛﻨﻨﺪه ي ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي و ﻳﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻋﻤﻮﻣﻲ‪.‬‬ ‫‪ Web Setup Project‬ﺑﺮاي اﻳﺠﺎد ﻧﺼﺐ ﻛﻨﻨﺪه ي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب و ﻳﺎ وب ﺳﺮوﻳﺲ ﻫﺎ‪.‬‬ ‫‪ Merge Module‬ﺑﺮاي اﻳﺠﺎد ﺑﺴﺘﻪ اي ﻛﻪ ﻓﻘﻂ ﺑﺘﻮاﻧﺪ در ﻳﻚ ﭘﺮوژه ي ﻧﺼﺐ ﻛﻨﻨﺪه ي دﻳﮕﺮ ﺗﺮﻛﻴﺐ ﺷﻮد‪.‬‬ ‫‪ Cab Project‬ﺑﺮاي اﻳﺠﺎد ﻳﻚ ﺑﺴﺘﻪ ي ﺧﺎص ﻛﻪ ﺑﻪ ﻋﻨﻮان ﻧﻮﻋﻲ از ﻧﺼﺐ ﻛﻨﻨﺪه ﻣﻲ ﺗﻮاﻧـﺪ ﻣـﻮرد اﺳـﺘﻔﺎده ﻗـﺮار‬ ‫ﮔﻴﺮد‪.‬‬ ‫‪ Smart Device Cab Project‬ﺑﺮاي اﻳﺠﺎد ﻧﺼﺐ ﻛﻨﻨﺪه ي ﺑﺮﻧﺎﻣﻪ ﻫـﺎي ﻣﺮﺑـﻮط ﺑـﻪ دﺳـﺘﮕﺎه ﻫـﺎي‬ ‫ﻫﻮﺷﻤﻨﺪ‪ ،‬ﻣﺎﻧﻨﺪ ‪ PDA‬ﻫﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد‪.‬‬

‫ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﻛﺎدر‪ ،‬ﻗﺎﻟﺒﻲ ﺑﻪ ﻧﺎم ‪ Setup Project Wizard‬ﻗﺮار دارد ﻛﻪ ﻣـﻲ ﺗﻮاﻧـﺪ در اﻳﺠـﺎد ﻣـﺪﻟﻬﺎي ﻣﺨﺘﻠـﻒ‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻧﺼﺐ ﻛﻪ در ﺑﺎﻻ ﻋﻨﻮان ﺷﺪ ﺑﻪ ﺷﻤﺎ ﻛﻤﻚ ﻛﻨﺪ‪.‬‬

‫اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه‪:‬‬ ‫ﻫﻨﮕﺎم اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻧﺼﺐ ﻛﻨﻨﺪه‪ ،‬ﺑﺎﻳﺪ ﻫﻤﻮاره ﻛﺎرﺑﺮ ﻧﻬﺎﻳﻲ را در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ‪ .‬ﺗﻤﺎم ﺑﺮﻧﺎﻣـﻪ ﻫـﺎﻳﻲ ﻛـﻪ ﺑـﺎ اﺳـﺘﻔﺎده از وﻳـﮋوال‬ ‫اﺳﺘﻮدﻳﻮ ‪ 2005‬اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ‪ ،‬ﺑﺮاي اﻳﻨﻜﻪ در ﺳﻴﺴﺘﻢ دﻳﮕﺮي اﺟﺮا ﺷﻮﻧﺪ ﺑﻪ ﭘﻴﺶ ﻧﻴﺎزﻫﺎﻳﻲ در ﺳﻴﺴﺘﻢ ﻣﻘـﺼﺪ ﻧﻴـﺎز دارﻧـﺪ‪ .‬اﻳـﻦ ﭘـﻴﺶ‬ ‫ﻧﻴﺎزﻫﺎ ﺑﺮ اﺳﺎس ﻧﻮع ﺑﺮﻧﺎﻣﻪ و اﻳﻨﻜﻪ در ﻃﺮاﺣﻲ آن از ﭼﻪ اﺑﺰارﻫﺎﻳﻲ اﺳﺘﻔﺎده ﺷﺪه اﺳﺖ ﺗﻔﺎوت دارد‪ .‬ﻳﻜﻲ از اﻳﻦ ﭘﻴﺶ ﻧﻴﺎزﻫﺎ )و ﻣﻬﻤﺘـﺮﻳﻦ‬ ‫آﻧﻬﺎ( ‪ .NET Framework‬ﻧﺴﺨﻪ ي ‪ 2.0‬اﺳﺖ ﻛﻪ ﺑﺎﻳﺪ در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﻘﺼﺪ ﻧﺼﺐ ﺷﺪه ﺑﺎﺷﺪ‪.‬‬ ‫ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ﺻﻮرت دروﻧﻲ و در ﺑﻴﻦ ﻛﺎرﺑﺮان ﻣﻮﺟﻮد در ﻣﻜﺎﻧﻲ ﺧﺎص ﺗﻮزﻳﻊ ﻣﻲ ﻛﻨﻴﺪ‪ ،‬ﻣﻌﻤﻮﻻً ﻣﻲ داﻧﻴﺪ ﻛﻪ ﭼـﻪ ﻗـﺴﻤﺘﻬﺎي‬ ‫ﭘﻴﺶ ﻧﻴﺎزي در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﺎي ﻛﺎرﺑﺮان ﻧﺼﺐ ﺷﺪه اﺳﺖ و ﭼﻪ ﻗﺴﻤﺘﻬﺎﻳﻲ ﺑﺎﻳﺪ ﻫﻤﺮاه ﺑﺎ ﺑﺮﻧﺎﻣﻪ ي اﺻﻠﻲ ﻧـﺼﺐ ﺷـﻮد‪ .‬اﻣـﺎ در ﺑـﺴﻴﺎري از‬ ‫ﺷﺮاﻳﻂ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﺻﻮرت ﻋﻤﻮﻣﻲ ﺗﻮزﻳﻊ ﻛﻨﻴﺪ‪ ،‬از ﺳﻴﺴﺘﻢ ﻛﺎرﺑﺮ ﻣﻘﺼﺪ و اﻳﻨﻜﻪ ﭼﻪ ﻗـﺴﻤﺘﻬﺎﻳﻲ در آن ﻧـﺼﺐ ﺷـﺪه‬ ‫اﺳﺖ اﻃﻼﻋﻲ ﻧﺪارﻳﺪ‪ .‬در اﻳﻦ ﻣﻮاﻗﻊ اﻳﻦ ﻣﻮرد ﺑﻪ ﺷﻤﺎ ﺑﺴﺘﮕﻲ دارد ﻛﻪ ﭼﮕﻮﻧﻪ ﻫﻤﻪ ي ﻗﺴﻤﺘﻬﺎي ﻣﻮرد ﻧﻴﺎز در ﺑﺮﻧﺎﻣﻪ را در دﺳﺘﺮس ﻛﺎرﺑﺮ‬ ‫ﻗﺮار دﻫﻴﺪ‪.‬‬ ‫وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬ﭘﺮوﺳﻪ ي اﺿﺎﻓﻪ ﻛﺮدن ﭘﻴﺶ ﻧﻴﺎزﻫﺎي ﻻزم در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻧﺼﺐ ﻛﻨﻨﺪه ي آن را ﺗﺎ ﺣـﺪ ﻣﻤﻜـﻦ ﺳـﺎده ﻛـﺮده‬ ‫اﺳﺖ‪ .‬ﺑﻴﺸﺘﺮ اﻳﻦ ﭘﻴﺶ ﻧﻴﺎزﻫﺎ را ﻣﻲ ﺗﻮان ﺑﺎ ﺗﻴﻚ زدن ﻧﺎم آﻧﻬﺎ اﻧﺘﺨﺎب ﻛﺮد‪ .‬ﻳﻜﻲ از اﻳﻦ ﭘﻴﺶ ﻧﻴﺎزﻫﺎ ﻛﻪ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض اﻧﺘﺨـﺎب‬ ‫ﺷﺪه اﺳﺖ‪ .NET Framework ،‬ﻧﺴﺨﻪ ي ‪ 2.0‬اﺳﺖ‪ .‬از آﻧﺠﺎ ﻛﻪ ﺗﺎ اﻳﻦ ﺑﺮﻧﺎﻣﻪ در ﺳﻴﺴﺘﻤﻲ ﻧﺼﺐ ﻧﺸﺪه ﺑﺎﺷﺪ‪ ،‬ﺑﺮﻧﺎﻣﻪ ﻫﺎي‬ ‫ﻧﻮﺷﺘﻪ ﺷﺪه در ‪ .NET‬ﻧﻤﻲ ﺗﻮاﻧﻨﺪ در آن ﺳﻴﺴﺘﻢ اﺟﺮا ﺷﻮﻧﺪ‪ ،‬وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬اﻳﻦ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﺻـﻮرت ﭘـﻴﺶ ﻓـﺮض ﺑـﻪ ﻧـﺼﺐ‬ ‫ﻛﻨﻨﺪه اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ ﺗﺎ در زﻣﺎن ﻧﺼﺐ‪ ،‬در ﺻﻮرت ﻟﺰوم ‪ .NET Framework‬ﻧﻴﺰ ﻧﺼﺐ ﺷﻮد‪.‬‬

‫‪٨٦٦‬‬

‫در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ‪ ،‬ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه را ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬اﻳﺠﺎد ﺧﻮاﻫﻴﻢ ﻛﺮد‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه‬ ‫‪ (1‬ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي وﻳﻨﺪوزي ﺟﺪﻳﺪ ﺑﻪ ﻧﺎم ‪ Prerequisite‬اﻳﺠﺎد ﻛﻨﻴﺪ‪ .‬ﻻزم ﻧﻴﺴﺖ‬ ‫در ﻛﺪ و ﻳﺎ ﻇﺎﻫﺮ ﻓﺮم اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺗﻐﻴﻴﺮي اﻳﺠﺎد ﻛﻨﻴﺪ‪.‬‬ ‫‪ (2‬ﺑﺮﻧﺎﻣﻪ را ذﺧﻴﺮه ﻛﺮده و ﺳﭙﺲ آن را ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﻴﺪ‪.‬‬ ‫‪ (3‬ﺑﺎ اﺳﺘﻔﺎده از ﻧﻮار ﻣﻨﻮي وﻳﮋوال اﺳـﺘﻮدﻳﻮ ﮔﺰﻳﻨـﻪ ي …‪ File  Add  New Project‬را اﻧﺘﺨـﺎب‬ ‫ﻛﺮده ﺗﺎ ﻛﺎدر ‪ Add New Project‬ﻧﺸﺎن داده ﺷﻮد‪ .‬در ﻗﺴﻤﺖ ‪ Project Type‬از اﻳﻦ ﻛـﺎدر‪ ،‬ﮔﺰﻳﻨـﻪ‬ ‫ي ‪ Setup And Deployment‬در ‪ Other Project Types‬را اﻧﺘﺨﺎب ﻛﻨﻴـﺪ‪ .‬از ﻗـﺴﻤﺖ‬ ‫‪ Setup‬را اﻧﺘﺨــﺎب ﻛــﺮده و ﻧــﺎم ﭘــﺮوژه را ﻧﻴــﺰ ﺑﺮاﺑــﺮ ﺑــﺎ‬ ‫‪ Templates‬ﻧﻴــﺰ ﮔﺰﻳﻨــﻪ ي ‪Project‬‬ ‫‪ Installer‬ﻗﺮار دﻫﻴﺪ )ﺷﻜﻞ ‪.(8-21‬‬

‫ﺷﻜﻞ ‪8-21‬‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻳﻦ ﭘﺮوژه را اﻳﺠﺎد ﻛﺮد‪ ،‬ﻳﻚ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪ 9-21‬ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﻨﺪ ﺷﺪ‪ .‬در ﺳـﻤﺖ ﭼـﭗ‬ ‫اﻳـﻦ ﻗـﺴﻤﺖ ﺳـﻪ ﻓﻮﻟـﺪر اﺻـﻠﻲ ﻧـﺸﺎن داده ﺷـﺪه اﺳـﺖ‪ User’s Desktop ،Application Folder :‬و‬ ‫‪.User’s Program Menu‬‬

‫‪٨٦٧‬‬

‫ﺷﻜﻞ ‪9-21‬‬ ‫‪(4‬‬ ‫‪(5‬‬

‫‪(6‬‬

‫‪(7‬‬ ‫‪(8‬‬ ‫‪(9‬‬

‫‪(10‬‬ ‫‪(11‬‬

‫در ﭘﻨﺠﺮه ي ‪ Solution Explorer‬روي ﻧﺎم ﭘﺮوژه ي ‪ Installer‬ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨـﻮﻳﻲ‬ ‫ﻛﻪ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد ﮔﺰﻳﻨﻪ ي ‪ Properties‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪.‬‬ ‫در ﻛــﺎدر ﻣﺮﺑــﻮط ﺑــﻪ ‪ ،Properties‬روي دﻛﻤــﻪ ي …‪ Prerequisites‬ﻛﻠﻴــﻚ ﻛﻨﻴــﺪ ﺗــﺎ ﻛــﺎدر‬ ‫‪ Prerequisites‬ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪ 10-21‬ﻧـﺸﺎن داده ﺷـﻮد‪ .‬ﺗﻮﺟـﻪ ﻛﻨﻴـﺪ ﻛـﻪ ‪.NET Framework‬‬ ‫‪ 2.0‬ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ‪.‬‬ ‫در اﻳﻦ ﻛﺎدر ﮔﺰﻳﻨﻪ ي ‪ Microsoft Data Access Components 2.8‬را اﻧﺘﺨـﺎب ﻛـﺮده و‬ ‫در ﻫﺮ دو ﻛﺎدر روي دﻛﻤﻪ ي ‪ OK‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓـﺮض‪ ،‬ﻣﺆﻟﻔـﻪ ﻫـﺎﻳﻲ ﻛـﻪ در اﻳـﻦ ﻗـﺴﻤﺖ‬ ‫اﻧﺘﺨﺎب ﻣﻲ ﺷﻮﻧﺪ از ﺳﺎﻳﺖ ﺷﺮﻛﺖ ﺗﻮﻟﻴﺪ ﻛﻨﻨﺪه ي آﻧﻬﺎ داﻧﻠﻮد ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬ ‫در ﺳﻤﺖ ﭼﭗ ﺑﺨﺶ ﻃﺮاﺣﻲ روي ﮔﺰﻳﻨﻪ ي ‪ Application Folder‬ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﮔﺰﻳﻨﻪ ي ‪Add‬‬ ‫‪  Project Output‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ ﻓﺮﻣﻲ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪ 11-21‬ﻧﺸﺎن داده ﺷﻮد‪.‬‬ ‫ﺳﭙﺲ در ﻛﺎدر ‪ Add Project Output Group‬ﮔﺰﻳﻨـﻪ ي ‪ Primary Output‬را اﻧﺘﺨـﺎب‬ ‫ﻛﺮده و روي دﻛﻤﻪ ي ‪ OK‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪.‬‬ ‫ﺣﺎل روي ‪ Primary output from prerequisite‬ﻛﻪ ﺑﻪ ﻗﺴﻤﺖ ﺳﻤﺖ راﺳﺖ اﺿﺎﻓﻪ ﺷـﺪه‬ ‫اﺳـﺖ‪ ،‬ﻛﻠﻴـﻚ راﺳـﺖ ﻛـﺮده و از ﻣﻨـﻮﻳﻲ ﻛـﻪ ﺑـﺎز ﻣـﻲ ﺷـﻮد ﮔﺰﻳﻨـﻪ ي ‪Create a Shortcut to‬‬ ‫‪ Primary output from prerequisite‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﻧﺎم ﮔﺰﻳﻨﻪ اي ﻛﻪ اﺿﺎﻓﻪ ﻣﻲ ﺷـﻮد‬ ‫را ﺑﺮاﺑﺮ ﺑﺎ ‪ Prerequisite‬ﻗﺮار دﻫﻴﺪ و ﺳﭙﺲ روي آن ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﮔﺰﻳﻨـﻪ ي ‪ Cut‬را اﻧﺘﺨـﺎب ﻛﻨﻴـﺪ‪.‬‬ ‫ﺳﭙﺲ در ﻗﺴﻤﺖ ﭼﭗ روي ﮔﺰﻳﻨﻪ ي ‪ User’s Program Menu‬ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﮔﺰﻳﻨﻪ ي ‪Paste‬‬ ‫را اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ ﺷﻮرت ﻛﺎت اﻳﺠﺎد ﺷﺪه در اﻳﻦ ﻗﺴﻤﺖ ﻗﺮار ﮔﻴﺮد‪.‬‬ ‫ﭘﺮوژه ي ‪ Installer‬را ذﺧﻴﺮه ﻛﺮده و ﺳﭙﺲ آن را ﻛﺎﻣﭙﺎﻳﻞ ﻛﻨﻴﺪ‪.‬‬ ‫ﺑﺎ اﺳﺘﻔﺎده از ﭘﻨﺠﺮه ي ‪ Solution Explorer‬روي ﭘـﺮوژه ي ‪ Installer‬ﻛﻠﻴـﻚ راﺳـﺖ ﻛـﺮده و‬ ‫ﮔﺰﻳﻨﻪ ي ‪ Install‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺒﻲ ﻛﻪ رد اﻳﻦ ﻗﺴﻤﺖ اﻳﺠﺎد ﻛﺮدﻳﻢ‪ ،‬اﺟﺮا ﺧﻮاﻫﺪ ﺷـﺪ‪.‬‬ ‫ﺑﺎ اﺗﻤﺎم ﻧﺼﺐ آن‪ ،‬ﻓﺎﻳﻠﻬﺎي ﻻزم ﺑﻪ ﻗﺴﻤﺘﻬﺎﻳﻲ ﻛﻪ ﻣﺸﺨﺺ ﻛﺮده ﺑﻮدﻳﺪ اﺿﺎﻓﻪ ﺧﻮاﻫﻨﺪ ﺷﺪ‪.‬‬

‫‪٨٦٨‬‬

‫ﺷﻜﻞ ‪10-21‬‬

‫ﺷﻜﻞ ‪11-21‬‬

‫‪٨٦٩‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ اﻳﺠﺎد ﻛﻨﻴﺪ‪ ،‬وﻳﮋوال اﺳـﺘﻮدﻳﻮ ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ از ﻧـﻮع ‪Windows Installer‬‬ ‫اﻳﺠﺎد ﺧﻮاﻫﺪ ﻛﺮد‪ .‬در اﻳﻦ ﻣﺜﺎل ﻓﻘﻂ ﻓﺎﻳﻞ اﺟﺮاﻳﻲ ﺑﺮﻧﺎﻣﻪ را در ﻧﺼﺐ ﻛﻨﻨﺪه ﻗﺮار دادﻳﻢ‪ ،‬ﺗﺎ در ﺳﻴﺴﺘﻢ ﻣﻘـﺼﺪ ﻛﭙـﻲ ﻛﻨـﺪ‪ ،‬اﻣـﺎ ﻣـﻲ ﺗـﻮان‬ ‫ﻓﺎﻳﻠﻬﺎي دﻳﮕﺮي را ﻧﻴﺰ از ﻗﺒﻴﻞ ﻓﺎﻳﻠﻬﺎي راﻫﻨﻤﺎ‪ ،‬ﻓﺎﻳﻠﻬﺎي ﻣﺘﻨﻲ‪ ،‬ﻓﺎﻳﻠﻬﺎي اﺳﻤﺒﻠﻲ ﻫﺎي ﻣﻮرد اﺳﺘﻔﺎده و ‪ ...‬را ﻧﻴﺰ ﺑﻪ اﻳﻦ ﻗﺴﻤﺖ اﺿﺎﻓﻪ ﻛﺮد‪.‬‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﭘﺮوژه ي ﻧﺼﺐ را ﻛﺎﻣﭙﺎﻳﻞ ﻣﻲ ﻛﻨﻴﺪ‪ ،‬دو ﻧﻮع ﻓﺎﻳﻞ اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ‪:‬‬ ‫‬ ‫‬

‫ﻳﻚ ﻓﺎﻳﻞ ﺑﺎ ﭘﺴﻮﻧﺪ ‪ msi‬ﻛﻪ ﺣﺎوي ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه اﺳﺖ‪.‬‬ ‫ﻳﻚ ﻓﺎﻳﻞ ﺑﺮاي ﺑﺎرﮔﺬاري ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه ﺑﻪ ﻧﺎم ‪setup.exe‬‬

‫اﻳﻦ دو ﻓﺎﻳﻞ در ﻓﻮﻟﺪر ‪ <solution directory>\Installer\Release‬ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ‪ .‬ﺑﺮاي ﭘﻴـﺪا‬ ‫ﻛﺮدن آدرس ﻣﺮﺑﻮط ﺑﻪ ‪ solution‬ﻧﻴﺰ ﻣـﻲ ﺗﻮاﻧﻴـﺪ آن را از ﭘﻨﺠـﺮه ي ‪ Solution Explorer‬اﻧﺘﺨـﺎب ﻛـﺮده و‬ ‫ﺳﭙﺲ ﺧﺎﺻﻴﺖ ‪ Path‬را در ﻛﺎدر ‪ Properties‬ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ‪.‬‬ ‫ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن دو ﭘﻴﺶ ﻧﻴﺎز ﻧﺼﺐ در اﻳﻦ ﭘﺮوژه‪ ،‬ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﺮﻧﺎﻣﻪ ﻧﺼﺐ ﺷﻮد ﺑﺮرﺳﻲ ﻣﻲ ﺷﻮد ﻛﻪ آﻳﺎ اﻳﻦ دو ﻣﻮرد در ﺳﻴﺴﺘﻢ ﻣﻘـﺼﺪ‬ ‫وﺟﻮد دارﻧﺪ ﻳﺎ ﻧﻪ؟ در ﺻﻮرﺗﻲ ﻛﻪ وﺟﻮد ﻧﺪاﺷﺘﻪ ﺑﺎﺷﻨﺪ‪ ،‬ﻓﺎﻳﻠﻬﺎي ﻣﺮﺑﻮط ﺑﻪ آﻧﻬﺎ از ﺳﺎﻳﺖ ﺳﺎزﻧﺪه درﻳﺎﻓﺖ ﺷﺪه و ﻧﺼﺐ ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬

‫وﻳﺮاﻳﺸﮕﺮ راﺑﻂ ﻛﺎرﺑﺮي ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ‪:‬‬ ‫ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه اي ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻳﺠﺎد ﻣﻲ ﺷﻮد‪ ،‬ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﮔﻮﻧﻪ اي ﭘﻴﻜﺮ ﺑﻨﺪي ﺷـﻮد ﺗـﺎ دﻗﻴﻘـﺎً ﺑﺮﻧﺎﻣـﻪ ي‬ ‫ﻧﺼﺐ ﻣﻮرد ﻧﻈﺮ ﺷﻤﺎ را اﻳﺠﺎد ﻛﻨﺪ‪ .‬ﻳﻜﻲ از ﺳﺎده ﺗﺮﻳﻦ راﻫﻬﺎ ﺑﺮاي اﻳﺠﺎد ﺗﻐﻴﻴﺮ در ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ‪ ،‬اﻳﻦ اﺳـﺖ ﻛـﻪ ﺻـﻔﺤﺎت ﻣﺮﺑـﻮط ﺑـﻪ‬ ‫ﻧﺼﺐ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺻﻮرت ﻣﻮرد ﻧﻈﺮ ﺧﻮد ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺒﻲ ﻛﻪ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ ﺣﺮﻓﻪ اي ﺗﺮ ﺑﻪ ﻧﻈﺮ ﺧﻮاﻫﺪ رﺳـﻴﺪ‪.‬‬ ‫ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﻲ ﺗﻮاﻧﻴﺪ از اﺑﺰار ﻣﺮﺑﻮط ﺑﻪ وﻳﺮاﻳﺶ راﺑﻂ ﻛﺎرﺑﺮي ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬ ‫ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ اﺑﺰار ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﻌﻴﻴﻦ ﻛﻨﻴﺪ ﻛﻪ ﭼﻪ ﺻﻔﺤﺎﺗﻲ ﺑﺮاي اﻧﺠﺎم ﭘﺮوﺳﻪ ي ﻧﺼﺐ ﺑﺎد ﻧﻤﺎﻳﺶ داده ﺷﻮﻧﺪ‪ .‬ﺑﺮاي اﻧﺘﺨﺎب ﺻﻔﺤﺎت‬ ‫ﻣﻲ ﺗﻮاﻧﻴﺪ از ﻓﺮﻣﻬﺎي ﭘﻴﺶ ﺳﺎﺧﺘﻪ ي ﻣﻮﺟﻮد در وﻳﮋوال اﺳﺘﻮدﻳﻮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ )ﻣﺎﻧﻨﺪ ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ ﺣﻖ ﺗﺎﻟﻴﻒ ﻧﺮم اﻓﺰار( و ﻳـﺎ ﻓﺮﻣﻬـﺎي‬ ‫ﻗﺎﺑﻞ ﺗﻨﻈﻴﻢ را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل ﻣﻲ ﺗﻮاﻧﻴﺪ ﻓﺮﻣﻲ را اﺿﺎﻓﻪ ﻛﻨﻴﺪ ﺗﺎ در ﻫﻨﮕﺎم ﻧﺼﺐ‪ ،‬ﺷﻤﺎره ﺳﺮﻳﺎل ﻧﺮم اﻓﺰار را از ﻛﺎرﺑﺮ ﺑﭙﺮﺳﺪ و در‬ ‫ﺻﻮرت ﺻﺤﻴﺢ ﺑﻮدن آن‪ ،‬ﻧﺼﺐ را اداﻣﻪ دﻫﺪ‪.‬‬ ‫در ﻗﺴﻤﺖ اﻣﺘﺤﺎن ﻛﻨﻴﺪ ﺑﻌﺪ‪ ،‬راﺑﻂ ﻛﺎرﺑﺮي ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺒﻲ ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﻢ را ﺗﻐﻴﻴﺮ ﺧﻮاﻫﻴﻢ داد‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬ﺗﻨﻈﻴﻢ راﺑﻂ ﻛﺎرﺑﺮي‬ ‫‪ Setup‬ﺑـــﻪ ﻧـــﺎم‬

‫‪ (1‬ﺑـــﺎ اﺳـــﺘﻔﺎده از وﻳـــﮋوال اﺳـــﺘﻮدﻳﻮ ‪ 2005‬ﺑﺮﻧﺎﻣـــﻪ ي ﺟﺪﻳـــﺪ از ﻧـــﻮع ‪Project‬‬ ‫‪ UserInterface‬اﻳﺠﺎد ﻛﻨﻴﺪ‪.‬‬ ‫‪ (2‬ﺑﺎ اﺳﺘﻔﺎده از ﻧﻮار ﻣﻨﻮي وﻳﮋوال اﺳﺘﻮدﻳﻮ ﮔﺰﻳﻨﻪ ي ‪ View  Editor  User Interface‬را‬ ‫اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪.‬‬

‫‪٨٧٠‬‬

‫‪ (3‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ وﻳﺮاﻳﺸﮕﺮ ﻣﺮﺑﻮط ﺑﻪ راﺑﻂ ﻛﺎرﺑﺮي ﻧﺼﺐ ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪ 12-21‬ﻧﺸﺎن داده ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬

‫ﺷﻜﻞ ‪12-21‬‬ ‫‪(4‬‬

‫‪(5‬‬ ‫‪(6‬‬

‫‪(7‬‬

‫‪(8‬‬

‫در اﻳﻦ ﻛﺎدر‪ ،‬دو ﻗﺴﻤﺖ ﻋﻤﺪه را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد‪ :‬ﻗﺴﻤﺖ ‪ Install‬و ﻗـﺴﻤﺖ ‪Administrative‬‬ ‫‪ Install‬ﻛﻪ ﻇﺎﻫﺮ ﻫﺮ دوي آﻧﻬﺎ را ﻣﻲ ﺗﻮاﻧﻴﺪ ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪ .‬ﻗـﺴﻤﺖ ‪Administrative Install‬‬ ‫ﺑﺮاي ﻧﻮع ﺧﺎﺻﻲ از ﻧﺼﺐ اﺳﺖ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ در ﻣﻮرد آن ﺻﺤﺒﺘﻲ ﻧﺨﻮاﻫﻴﻢ ﻛﺮد‪ .‬اﻳﻦ ﻗﺴﻤﺖ زﻣﺎﻧﻲ ﺑﻪ ﻛﺎر ﻣﻲ رود ﻛـﻪ‬ ‫ﻳﻚ ﻣﺪﻳﺮ ﺷﺒﻜﻪ ﺑﺨﻮاﻫﺪ ﺑﺮﻧﺎﻣﻪ را ﺑﺮاي ﺗﻤﺎم ﻛﺎرﺑﺮان در ﺷﺒﻜﻪ ﻧﺼﺐ ﻛﻨﺪ‪.‬‬ ‫در ﻗﺴﻤﺖ ‪ Install‬روي ﮔﺰﻳﻨﻪ ي ‪ Start‬ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و از ﻣﻨﻮﻳﻲ ﻛﻪ ﺑﺎز ﻣـﻲ ﺷـﻮد ﮔﺰﻳﻨـﻪ ي ‪Add‬‬ ‫‪ Dialog‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎدري ﻣﺸﺎﺑﻪ ﺷﻜﻞ ‪ 13-21‬ﻧﺸﺎن داده ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬ ‫از اﻳﻦ ﻛﺎدر ﮔﺰﻳﻨﻪ ي ‪ License Agreement‬را اﻧﺘﺨﺎب ﻛﺮده و روي دﻛﻤﻪ ي ‪ OK‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﺑﻪ ﺻـﻮرت‬ ‫ﭘﻴﺶ ﻓﺮض اﻳﻦ ﻛﺎدر ﺑﻌﺪ از آﺧﺮﻳﻦ ﻛﺎدر ﻣﻮﺟﻮد در ﻗﺴﻤﺖ ‪ Start‬اﺿﺎﻓﻪ ﺧﻮاﻫﺪ ﺷﺪ‪ ،‬اﻣﺎ ﻣﻲ ﺧﻮاﻫﻴﻢ ﻛﻪ اﻳـﻦ ﻛـﺎدر ﺑـﻪ‬ ‫ﻋﻨﻮان دوﻣﻴﻦ ﻛﺎدر در زﻣﺎن ﻧﺼﺐ ﻧﻤﺎﻳﺶ داده ﺷﻮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ روي آن ﻛﻠﻴـﻚ راﺳـﺖ ﻛـﺮده و ﮔﺰﻳﻨـﻪ ي ‪ Move Up‬را‬ ‫اﻧﺘﺨﺎب ﻛﻨﻴﺪ ﺗﺎ ﺑﻪ ﻋﻨﻮان دوﻣﻴﻦ ﻛﺎدر ﻗﺮار ﺑﮕﻴﺮد‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻗﺴﻤﺖ ‪ User Interface‬ﻫﻤﺎﻧﻨﺪ ﺷـﻜﻞ ‪-21‬‬ ‫‪ 14‬ﺧﻮاﻫﺪ ﺑﻮد‪.‬‬ ‫در اﻳﻦ ﻓﺮم ﻣﻲ ﺗﻮاﻧﻴﺪ ﺣﻘﻮق ﻣﺮﺑﻮط ﺑﻪ ﺗﻮزﻳﻊ و اﻧﺘﺸﺎر اﻳﻦ ﺑﺮﻧﺎﻣﻪ و ﻛﭙﻲ راﻳﺖ آن را ﺑﻨﻮﻳﺴﻴﺪ‪ .‬ﺑﺮاي اﻳـﻦ ﻛـﺎر ﻣـﻲ ﺗﻮاﻧﻴـﺪ از‬ ‫ﺧﺎﺻﻴﺖ ‪ LicenseFile‬اﺳﺘﻔﺎده ﻛﺮده و ﻳﻚ ﻓﺎﻳﻞ ﻣﺘﻨﻲ را ﺑﺮاي آن ﺑﻪ ﻋﻨﻮان ﺣﻘﻮق ﻛﭙﻲ راﻳﺖ ﺑﺮﻧﺎﻣـﻪ ﻣـﺸﺨﺺ‬ ‫ﻛﻨﻴﺪ‪ .‬در اﻳﻦ ﻣﺜﺎل‪ ،‬اﻳﻦ ﺧﺎﺻﻴﺖ را ﺗﻨﻈﻴﻢ ﻧﺨﻮاﻫﻴﻢ ﻛﺮد‪.‬‬ ‫ﺣﺎل ﺑﺎﻳﺪ ﻳﻚ ﻛﺎدر ‪ Customer Information‬را ﺑﻪ ﻗﺴﻤﺖ ‪ Start‬اﺿﺎﻓﻪ ﻛﻨﻴﻢ ﺑﻪ ﮔﻮﻧﻪ اي ﻛـﻪ ﺑـﻪ‬ ‫ﻋﻨﻮان ﻛﺎدر ﺳﻮم در ﻓﺮم ﻧﻤﺎﻳﺶ داده ﺷﻮد‪ .‬ﺑﻌﺪ از اﻳﻦ ﻛﺎر ﺧﺎﺻﻴﺖ ‪ SerialNumberTemplate‬را ﺑﺮاﺑـﺮ ﺑـﺎ‬ ‫‪ %%-###-%%%‬و ﺧﺎﺻﻴﺖ ‪ ShowSerialNumber‬را ﺑﺮاﺑﺮ ﺑﺎ ‪ True‬ﻗﺮار دﻫﻴﺪ‪.‬‬

‫‪٨٧١‬‬

‫ﺷﻜﻞ ‪13-21‬‬

‫ﺷﻜﻞ ‪14-21‬‬ ‫‪ (9‬ﺧﻮب‪ ،‬ﺣﺎل ﺑﺮﻧﺎﻣﻪ را ﻛﺎﻣﭙﺎﻳﻞ ﻛﺮده و ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي ﭘﺮوژه ي آن در ‪ Solution Explorer‬و اﻧﺘﺨﺎب‬ ‫ﮔﺰﻳﻨﻪ ي ‪ Install‬آن را اﺟﺮا ﻛﻨﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎدر ﻣﺮﺑﻮط ﺑﻪ ﻗﺎﻧﻮن ﻛﭙﻲ راﻳﺖ ﺑﺮﻧﺎﻣﻪ را در ﻣﺮﺣﻠﻪ ي دوم ﻧـﺼﺐ‬ ‫ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد‪ .‬ﻣﺮﺣﻠﻪ ي ﺳﻮم ﻧﻴﺰ ﻣﺮﺑﻮط ﺑﻪ اﻃﻼﻋﺎت ﻓﺮدي اﺳﺖ ﻛﻪ از ﻛﺎرﺑﺮ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ‪.‬‬

‫‪٨٧٢‬‬

‫‪ (10‬در اﻳﻦ ﻣﺮﺣﻠﻪ‪ ،‬ﻋﺒﺎرت ‪ 77-000-777‬را ﺑﻪ ﻋﻨﻮان ﺷﻤﺎره ﺳﺮﻳﺎل ﺑﺮﻧﺎﻣﻪ وارد ﻛﺮده و روي دﻛﻤﻪ ي ‪ Next‬ﻛﻠﻴـﻚ‬ ‫ﻛﻨﻴﺪ )ﺷﻜﻞ ‪.(15-21‬‬ ‫‪ (11‬ﺣﺎل ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن ﻣﺘﻮاﻟﻲ روي دﻛﻤﻪ ي ‪ Next‬ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ را ﺑﻪ اﺗﻤﺎم ﺑﺮﺳﺎﻧﻴﺪ‪.‬‬

‫ﺷﻜﻞ ‪15-21‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ اﻳﺠﺎد ﺗﻐﻴﻴﺮ در ﻣﺮاﺣﻞ ﻧﺼﺐ ﻧﻴﺰ‪ ،‬ﻣﺎﻧﻨﺪ ﺗﻤﺎم ﻛﺎرﻫﺎي دﻳﮕﺮي ﻛﻪ در اﻳﻦ ﻓﺼﻞ اﻧﺠﺎم دادﻳﻢ‪ ،‬ﺑﻪ ﺳﺎدﮔﻲ ﺻﻮرت ﮔﺮﻓﺖ‪.‬‬ ‫ﺑﻌﺪ از اﺿﺎﻓﻪ ﻛﺮدن ﻓﺮم ﻣﺮﺑﻮط ﺑﻪ ﺣﻘﻮق ﺗﺎﻟﻴﻒ ﺑﺮﻧﺎﻣﻪ‪ ،‬آن را ﺑﻪ ﻋﻨﻮان دوﻣﻴﻦ ﻓﺮﻣﻲ ﻛﻪ ﺑﺎﻳﺪ در ﻫﻨﮕﺎم ﻧـﺼﺐ ﻧـﺸﺎن داده ﺷـﻮد ﺗﻌﻴـﻴﻦ‬ ‫ﻛﺮدﻳﻢ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ در ﻣﺮﺣﻠﻪ ي دوم ﺣﻖ ﺗﺎﻟﻴﻒ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻛﺎرﺑﺮ ﻧﺸﺎن داده ﻣﻲ ﺷﻮد و ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻛﺎرﺑﺮ آﻧﻬﺎ را ﻗﺒـﻮل ﻧﻜـﺮده اﺳـﺖ‬ ‫ﻧﻤﻲ ﺗﻮاﻧﺪ وارد ﻣﺮﺣﻠﻪ ي ﺑﻌﺪ ﺷﻮد‪.‬‬ ‫در ﻣﺮﺣﻠﻪ ي ﺳﻮم اﻃﻼﻋﺎت ﻛﺎرﺑﺮ و ﺷﻤﺎره ﺳﺮﻳﺎل ﺑﺮﻧﺎﻣﻪ را درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻛـﺎرﺑﺮ ﻳـﻚ ﺷـﻤﺎره ي ﺳـﺮﻳﺎل ﻣﻌﺘﺒـﺮ را در‬ ‫ﺑﺮﻧﺎﻣـــﻪ وارد ﻧﻜﻨـــﺪ‪ ،‬ﻧـــﺼﺐ ﺑﺮﻧﺎﻣـــﻪ اداﻣـــﻪ ﭘﻴـــﺪا ﻧﺨﻮاﻫـــﺪ ﻛـــﺮد‪ .‬ﺑـــﺮاي اﻳﺠـــﺎد ﺷـــﻤﺎره ﺳـــﺮﻳﺎل ﺑﺮﻧﺎﻣـــﻪ از ﺧﺎﺻـــﻴﺖ‬ ‫‪ SerialNumberTemplate‬اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ و آن را ﺑـﻪ ‪ %%-###-%%%‬ﺗﻐﻴﻴـﺮ ﻣـﻲ دﻫـﻴﻢ‪ .‬در اﻳـﻦ ﻋﺒـﺎرت‬ ‫ﻛﺎراﻛﺘﺮ ‪ %‬ﻧﺸﺎن دﻫﻨﺪه ي ﻋﺪدي اﺳﺖ ﻛﻪ در اﻟﮕﻮرﻳﺘﻢ ﺷﻤﺎره ﺳﺮﻳﺎل در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮد و ﻛﺎراﻛﺘﺮ ‪ #‬ﻧﺸﺎن دﻫﻨﺪه ي ﻋﺪدي اﺳﺖ‬ ‫ﻛﻪ در اﻟﮕﻮرﻳﺘﻢ ﻗﺮار ﻧﺨﻮاﻫﺪ ﮔﺮﻓﺖ‪ .‬ﻧﺤﻮه ي ﺗﺸﺨﻴﺺ ﺻﺤﺖ ﺷﻤﺎره ﺳﺮﻳﺎل ﺑﻪ اﻳﻦ ﺻﻮرت اﺳﺖ ﻛﻪ ﺣﺎﺻﻞ ﺟﻤﻊ ﻋـﺪد ﻫـﺎﻳﻲ ﻛـﻪ ﺑـﺎ‬ ‫ﻛﺎراﻛﺘﺮ ‪ %‬ﻣﺸﺨﺺ ﺷﺪه اﻧﺪ ﺑﺮ ‪ 7‬ﺗﻘﺴﻴﻢ ﻣﻲ ﺷﻮد‪ .‬در ﺻﻮرﺗﻲ ﺷﻤﺎره ﺳﺮﻳﺎل ﻣﻌﺘﺒﺮ ﺗﺸﺨﻴﺺ داده ﻣﻲ ﺷﻮد ﻛﻪ ﺑﺎﻗﻴﻤﺎﻧﺪه ي اﻳﻦ ﺗﻘـﺴﻴﻢ‬

‫‪٨٧٣‬‬

‫ﺑﺮاﺑﺮ ﺑﺎ ‪ 0‬ﺑﺎﺷﺪ‪ .‬در اﻳﻦ ﻣﺜﺎل ‪ 5‬ﻋﺪد در ﺷﻤﺎره ﺳﺮﻳﺎل ﺑﺎ ﻛﺎراﻛﺘﺮ ‪ %‬ﻣﺸﺨﺺ ﺷﺪه اﻧﺪ ﻛﻪ ﻫﻤﻪ ي آﻧﻬﺎ را ﺑﺮاﺑﺮ ﺑﺎ ‪ 7‬ﻗـﺮار داده اﻳـﻢ‪ .‬ﭘـﺲ‬ ‫ﺣﺎﺻﻞ ﺟﻤﻊ آﻧﻬﺎ ﺑﺮاﺑﺮ ﺑﺎ ‪ 35‬ﺧﻮاﻫﺪ ﺑﻮد ﻛﻪ اﮔﺮ ﺑﺮ ‪ 7‬ﺗﻘﺴﻴﻢ ﺷﻮد‪ ،‬ﺑﺎﻗﻴﻤﺎﻧﺪه ﺻﻔﺮ ﻣﻲ ﺷﻮد‪.‬‬

‫ﺗﻮزﻳﻊ راه ﺣﻠﻬﺎي ﮔﻮﻧﺎﮔﻮن‪:‬‬ ‫ﺗﻮزﻳﻊ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﻌﻤﻮﻻ ﻛﺎر ﺑﺴﻴﺎر ﻣﺸﻜﻠﻲ اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي اﺑﺰارﻫﺎي ﮔﻮﻧﺎﮔﻮن ﺳﻌﻲ ﺷﺪه اﺳﺖ ﻣﻘﺪاري ﺳﺎده ﺗﺮ ﺷﻮد‪ .‬اﻣـﺎ ﺑـﺮاي‬ ‫ﭼﻨﺪ ﻟﺤﻈﻪ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺑﺰرﮔﻲ ﻣﺎﻧﻨﺪ ‪ Office‬ﻓﻜﺮ ﻛﻨﻴﺪ‪ .‬در اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺗﻌﺪاد زﻳﺎدي ﻓﺎﻳﻞ ﺑﺎ ﻧﻮع ﻫﺎي ﻣﺨﺘﻠﻒ وﺟﻮد دارﻧﺪ‬ ‫ﻛﻪ ﻫﺮ ﻳﻚ از آﻧﻬﺎ ﺑﺎﻳﺪ در ﻣﻜﺎن ﻣﺨﺼﻮﺻﻲ ﻗﺮار ﮔﻴﺮد و ﻳﺎ در ﻛﻠﻴﺪ ﺧﺎﺻﻲ در رﺟﻴﺴﺘﺮي ﺛﺒﺖ ﺷﻮد‪ .‬ﻓﻘﻂ زﻣـﺎﻧﻲ ﺑﺮﻧﺎﻣـﻪ ﻣـﻲ ﺗﻮاﻧـﺪ ﺑـﻪ‬ ‫درﺳﺘﻲ ﻛﺎر ﻛﻨﺪ ﻛﻪ ﺗﻤﺎم اﻳﻦ ﺗﻨﻈﻴﻤﺎت ﺑﻪ دﻗﺖ اﻧﺠﺎم ﺷﻮﻧﺪ‪ .‬در اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﺎ ﭘﻴﭽﻴﺪﮔﻲ ﻫﺎي دﻳﮕﺮي ﻧﻴـﺰ درﮔﻴـﺮ ﺧـﻮاﻫﻴﻢ ﺑـﻮد‪،‬‬ ‫ﻣﺎﻧﻨﺪ ﭘﻴﭽﻴﺪﮔﻲ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ اﻳﺠﺎد ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ ﻣﻮرد ﻧﻴﺎز‪ .‬ﺑﺮاي ﻣﺜﺎل اﮔﺮ ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ در ﺣـﺎل ﺣﺎﺿـﺮ در ﺳﻴـﺴﺘﻢ وﺟـﻮد‬ ‫داﺷﺖ ﭼﻪ ﺑﺎﻳﺪ ﻛﺮد؟ آﻳﺎ داده ﻫﺎﻳﻲ ﻛﻪ ﻫﻢ اﻛﻨﻮن در آن ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ وﺟﻮد دارﻧﺪ‪ ،‬از ﺑﻴﻦ ﺧﻮاﻫﻨﺪ رﻓﺖ؟ اﻳﻦ ﻧﻮع ﻣﺴﺎﺋﻞ و ﻣـﺸﻜﻼت‬ ‫ﻛﻪ ﺑﻪ ﻧﺎم اﻧﺘﻘﺎل‪ 1‬ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮﻧﺪ‪ ،‬ﻣﻌﻤﻮﻻً ﻧﻴﺎز دارﻧﺪ ﻛﻪ ﻳﻚ ﻣﺘﺨﺼﺺ در اﻳﻦ زﻣﻴﻨﻪ ﻫﺎ زﻣﺎن زﻳﺎدي را ﺑﺮاي ﺣﻞ آﻧﻬﺎ ﺻﺮف ﻛﻨﺪ‪.‬‬ ‫ﻳﻜﻲ درﮔﻴﺮ از ﻣﺴﺎﺋﻠﻲ ﻛﻪ ﭘﺮوﺳﻪ ي ﻧﺼﺐ را ﭘﻴﭽﻴﺪه ﻣﻲ ﻛﻨﺪ‪ ،‬درﮔﻴﺮ ﺑﻮدن ﺑﺎ ﭼﻨﺪ ﻧﻮع ﺑﺮﻧﺎﻣﻪ در ﻳﻚ ﭘﺮوژه اﺳﺖ‪ .‬ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﻢ در‬ ‫اﻳﻦ ﺷﺮاﻳﻂ ﻧﺼﺐ ﻛﺎﻣﻞ و ﻣﻮﻓﻘﻲ داﺷﺘﻪ ﺑﺎﺷﻴﻢ‪ ،‬ﺑﻪ درك ﺻﺤﻴﺤﻲ از ﺟﺰﺋﻴﺎت اﻳﻦ ﭘﺮوژه ﻫﺎ ﻧﻴﺎز دارﻳﻢ‪ .‬در اﻳﻦ ﻗﺴﻤﺖ ﺳـﻌﻲ ﻣـﻲ ﻛﻨـﻴﻢ‬ ‫آﻳﺘﻢ ﻫﺎ و ﻣﻮارد ﮔﻮﻧﺎﮔﻮن راﺟﻊ ﺑﻪ اﻧﻮاع ﻣﺨﺘﻠﻒ ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﮔﻮﻧﺎﮔﻮﻧﻲ ﻛﻪ ﻣﻲ ﺗﻮان ﺑﺎ وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬اﻳﺠﺎد ﻛﺮد را ﺑﺮرﺳﻲ‬ ‫ﻛﻨﻴﻢ‪.‬‬

‫اﺳﻤﺒﻠﻲ ﻫﺎي ﺧﺼﻮﺻﻲ‪:‬‬ ‫در ﻣﻮرد ﻣﻔﻬﻮم اﺳﻤﺒﻠﻲ در ﻓﺼﻠﻬﺎي ﻗﺒﻠﻲ ﺻﺤﺒﺖ ﻛﺮدﻳﻢ‪ .‬اﺳﻤﺒﻠﻲ ﻫﺎ ﺧﻮد داراي دو ﻧﻮع ﻫﺴﺘﻨﺪ‪ :‬اﺳـﻤﺒﻠﻲ ﻫـﺎي ﺧـﺼﻮﺻﻲ و اﺳـﻤﺒﻠﻲ‬ ‫ﻫﺎي ﻋﻤﻮﻣﻲ‪ .2‬اﺳﻤﺒﻠﻲ ﻫﺎي ﺧﺼﻮﺻﻲ ﻣﻌﻤﻮﻻً در ﻳﻚ داﻳﺮﻛﺘﻮري ﺑﻪ ﻧﺎم ‪ bin‬درون داﻳﺮﻛﺘﻮري اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ ﻗـﺮار ﻣـﻲ ﮔﻴﺮﻧـﺪ‪ .‬اﻳـﻦ‬ ‫اﺳﻤﺒﻠﻲ ﻫﺎ ﻣﺨﺼﻮص ﺑﺮﻧﺎﻣﻪ ﻫﺴﺘﻨﺪ و ﻧﻤﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ وﺳﻴﻠﻪ ي دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮﻧﺪ‪ .‬ﻣﺰﻳﺖ ﻫﺎي اﻳﻦ ﻧﻮع اﺳﻤﺒﻠﻲ ﻫﺎ‬ ‫ﻋﺒﺎرﺗﻨﺪ از‪:‬‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬

‫اﻳﻦ ﻧﻮع اﺳﻤﺒﻠﻲ ﻫﺎ ﺑﻪ داﺷﺘﻦ ﻧﺴﺨﻪ ي دﻗﻴﻖ ﻧﻴﺎزي ﻧﺪارﻧﺪ‪ ،‬زﻳﺮا ﻫﻤﺎن اﺳﻤﺒﻠﻲ ﻛﻪ ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ ﺑﺮﻧﺎﻣﻪ ﻣﻮرد ﺑﻪ ﻛﺎر رﻓﺘـﻪ‬ ‫اﺳﺖ در ﻓﻮﻟﺪر ‪ bin‬ﻧﻴﺰ وﺟﻮد دارد و ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﺪ از آن اﺳﺘﻔﺎده ﻛﻨﺪ‪.‬‬ ‫ﻳﻚ اﺳﻤﺒﻠﻲ ﺧﺼﻮﺻﻲ ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺻﻮرت ﻋﻤﻮﻣﻲ ﺗﻮﺳﻂ دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴـﺮد‪ ،‬ﺑﻨـﺎﺑﺮاﻳﻦ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي‬ ‫دﻳﮕﺮ ﻧﻤﻲ ﺗﻮاﻧﻨﺪ آن را ﺗﻐﻴﻴﺮ دﻫﻨﺪ و ﻳﺎ ﺑﻪ روز ﻛﻨﻨﺪ‪.‬‬ ‫ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ ﻓﻘﻂ از اﺳﻤﺒﻠﻲ ﻫﺎي ﺧﺼﻮﺻﻲ اﺳﺘﻔﺎده ﻛﺮده ﺑﺎﺷﺪ را ﻣﻲ ﺗﻮان ﺑﻪ ﺳـﺎدﮔﻲ و ﺑـﺎ اﺳـﺘﻔﺎده از روش ‪XCOPY‬‬ ‫ﺗﻮزﻳﻊ ﻛﺮد‪.‬‬ ‫اﺳﺘﻔﺎده از اﻳﻦ اﺳﻤﺒﻠﻲ ﻫﺎ ﺑﻪ ﻫﻴﭻ ﭘﻴﻜﺮ ﺑﻨﺪي و ﻳﺎ ﺗﻨﻈﻴﻤﺎت ﺧﺎﺻﻲ ﻧﻴﺎز ﻧﺪارد‪ .‬اﻳﻦ اﺳﻤﺒﻠﻲ ﻫﺎ ﺑﻪ ﺳﺎدﮔﻲ ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ‪.‬‬ ‫اﮔﺮ از ﻳﻚ اﺳﻤﺒﻠﻲ در دو ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ ،‬ﭼﻮن دو ﻧﺴﺨﻪ از آن وﺟﻮد دارد و ﻫﺮ ﻧﺴﺨﻪ ﻧﻴﺰ در ﻓﻮﻟﺪر ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي‬ ‫ﺧﻮد ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ‪ ،‬ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻜﻲ از آﻧﻬﺎ را ﺗﻐﻴﻴﺮ دﻫﻴﺪ ﺑﺪون آﻧﻜﻪ در دﻳﮕﺮي ﺗﻐﻴﻴﺮي ﺑﻪ وﺟﻮد آﻳﺪ‪.‬‬ ‫‪1‬‬

‫‪Migration‬‬ ‫‪ 2‬اﻳﻦ دو ﻧﻮع اﺳﻤﺒﻠﻲ در ﻧﺤﻮه ي اﻳﺠﺎد و ﻳﺎ اﺳﺘﻔﺎده ﻫﻴﭻ ﺗﻔﺎوﺗﻲ ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﻧﺪارﻧﺪ و ﺗﻨﻬﺎ در ﺳﻄﺢ دﺳﺘﺮﺳﻲ و ﻣﺤﻞ ﻗﺮار ﮔﻴﺮي آﻧﻬﺎ اﺳـﺖ ﻛـﻪ از ﻳﻜـﺪﻳﮕﺮ ﻣﺘﻤـﺎﻳﺰ‬ ‫ﻣﻲ ﺷﻮﻧﺪ‪.‬‬

‫‪٨٧٤‬‬

‫‬

‫اﻳﻦ ﻧﻮع اﺳﻤﺒﻠﻲ ﻫﺎ ﺑﺮاي ﻗﺮار دادن ﻛﻼﺳﻬﺎي ﻣﺨﺼﻮص ﺑﺮﻧﺎﻣﻪ و ﻳﺎ اﺑﺰارﻫﺎي ﻛﻮﭼﻚ ﻋﻤﻮﻣﻲ ﺑﺴﻴﺎر ﻣﻨﺎﺳﺐ ﻫﺴﺘﻨﺪ‪.‬‬

‫ﻣﻌﺎﻳﺐ اﺳﺘﻔﺎده از اﺳﻤﺒﻠﻲ ﻫﺎي ﺧﺼﻮﺻﻲ ﻧﻴﺰ ﻋﺒﺎرﺗﻨﺪ از‪:‬‬ ‫‬ ‫‬ ‫‬

‫اﮔﺮ ﺑﺨﻮاﻫﻴﺪ از آﻧﻬﺎ در ﭼﻨﺪ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ ،‬ﻣﺠﺒﻮر ﺧﻮاﻫﻴﺪ ﺑﻮد ﻛﻪ اﺳﻤﺒﻠﻲ ﻣﻮرد ﻧﻈﺮ ﺧﻮد را در ﻓﻮﻟﺪر ‪ bin‬ﻫﺮ ﻳﻚ از‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻛﭙﻲ ﻛﻨﻴﺪ ﺗﺎ ﺑﺘﻮاﻧﺪ در آن ﺑﺮﻧﺎﻣﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد‪.‬‬ ‫ﻣﺠﺒﻮر ﺧﻮاﻫﻴﺪ ﺑﻮد ﻛﻪ اﺳﻤﺒﻠﻲ را در ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻣﺮﺑﻮط ﺑﻪ ﺗﻤﺎم ﭘﺮوژه ﻫﺎﻳﻲ ﻛﻪ از آن اﺳﺘﻔﺎده ﻛﺮده اﻧـﺪ ﻗـﺮار دﻫﻴـﺪ ﺗـﺎ‬ ‫ﻫﻨﮕﺎم ﻧﺼﺐ در ﺳﻴﺴﺘﻢ ﻣﻘﺼﺪ ﻛﭙﻲ ﺷﻮد‪.‬‬ ‫اﺳﻤﺒﻠﻲ ﺷﻤﺎ ﺑﻪ ﺻﻮرت ﻗﻮي ﻧﺎﻣﮕﺬاري ﻧﺨﻮاﻫﺪ ﺷﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻤﻜﻦ اﺳﺖ ﻓﺮدي از آن ﺳﻮءاﺳﺘﻔﺎده ﻛﻨﺪ‪.‬‬

‫ﻧﻜﺘﻪ‪ :‬ﻣﻨﻈﻮر از ﺳﻮءاﺳﺘﻔﺎده از اﺳﻤﺒﻠﻲ ﺷﻤﺎ اﻳﻦ اﺳﺖ ﻛﻪ‪ ،‬ﻣﻤﻜﻦ اﺳﺖ ﻓﺮدي ﻳﻚ اﺳﻤﺒﻠﻲ اﻳﺠﺎد ﻛﻨﺪ ﻛﻪ ﻇـﺎﻫﺮاً ﻣـﺸﺎﺑﻪ اﺳـﻤﺒﻠﻲ ﺷـﻤﺎ‬ ‫ﺑﺎﺷﺪ‪ ،‬اﻣﺎ ﻣﺤﺘﻮﻳﺎت و ﻛﺪ داﺧﻞ آن را ﺑﻪ ﺻﻮرت ﻣﻮرد ﻧﻈﺮ ﺧﻮد ﺗﻐﻴﻴﺮ دﻫﺪ‪ .‬ﺳﭙﺲ در آن ﻛﺪ‪ ،‬ﻛﺎرﻫﺎﻳﻲ را ﻛﻪ در ﻧﻈﺮ دارد اﻧﺠﺎم دﻫﺪ‪.‬‬

‫اﺳﻤﺒﻠﻲ ﻫﺎي ﻋﻤﻮﻣﻲ‪:‬‬ ‫اﺳﻤﺒﻠﻲ ﻫﺎي ﻋﻤﻮﻣﻲ ﻣﻌﻤﻮﻻً ﭘﺎﻳﺪار ﺗﺮ از اﺳﻤﺒﻠﻲ ﻫﺎي ﺧﺼﻮﺻﻲ ﻫﺴﺘﻨﺪ‪ .‬اﻳﻦ ﻧﻮع اﺳﻤﺒﻠﻲ ﻫﺎ ﻣـﻲ ﺗﻮاﻧﻨـﺪ دﻗﻴﻘـﺎً ﻣﺎﻧﻨـﺪ اﺳـﻤﺒﻠﻲ ﻫـﺎي‬ ‫ﺧﺼﻮﺻﻲ رﻓﺘﺎر ﻛﻨﻨﺪ‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻤﺎم ﻣﺰاﻳﺎﻳﻲ ﻛﻪ اﺳﻤﺒﻠﻲ ﻫﺎي ﺧﺼﻮﺻﻲ دارﻧﺪ را ﻧﻴﺰ ﺷﺎﻣﻞ ﻣﻲ ﺷﻮﻧﺪ‪ .‬اﻣﺎ ﻋﻼوه ﺑﺮ اﻳﻦ‪ ،‬اﻳﻦ ﻧﻮع اﺳـﻤﺒﻠﻲ‬ ‫ﻫﺎ ﺑﻪ ﮔﻮﻧﻪ اي دﻳﮕﺮ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ ﻛﺎر ﮔﺮﻓﺘﻪ ﺷﻮﻧﺪ ﻛﻪ ﻣﺸﺎﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺒﻞ از ‪ .NET‬اﺳﺖ‪.‬‬ ‫اﺳﺘﻔﺎده از اﺳﻤﺒﻠﻲ ﻫﺎي ﻋﻤﻮﻣﻲ ﻫﻤﺎﻧﻨﺪ روﺷﻲ اﺳﺖ ﻛﻪ در ﺳﻴﺴﺘﻢ ﻫﺎي ﻗﺪﻳﻤﻲ ﺑﻪ ﻛﺎر ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﺪ‪ .‬در وﻳﻨﺪوز ‪ 3.1‬ﻓﻮﻟﺪري ﺑﻪ ﻧﺎم‬ ‫‪ Windows\System‬وﺟﻮد داﺷﺖ و ﻫﺮ ﺑﺮﻧﺎﻣﻪ ﻛﻪ ﻣﻲ ﺧﻮاﺳﺖ از ‪ DLL‬ﺧﺎﺻﻲ اﺳﺘﻔﺎده ﻛﻨﺪ‪ ،‬ﻣﺠﺒﻮر ﺑﻮد ﻛﻪ ﺑﻌﺪ از ﺛﺒﺖ اﻳـﻦ‬ ‫‪ ،DLL‬آن را در اﻳﻦ ﻓﻮﻟﺪر ﻛﭙﻲ ﻛﺮده و آن را ﺑﻪ ﻛﺎر ﺑﺒﺮد‪ .‬روش ﻛﺎر اﺳﻤﺒﻠﻲ ﻫﺎي ﻋﻤﻮﻣﻲ ﻧﻴﺰ ﺑﻪ ﻫﻤﻴﻦ ﺻﻮرت اﺳـﺖ‪ ،‬وﻟـﻲ ﺑـﻪ ﺟـﺎي‬ ‫اﺳﺘﻔﺎده از ﻓﻮﻟﺪر ‪ System‬از ﻓﻮﻟﺪر دﻳﮕﺮي ﺑﻪ ﻧﺎم ‪ Global Assembly Cache‬ﻳﺎ ‪ GAC‬اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد‪ .‬اﻟﺒﺘﻪ‬ ‫ﺑﺴﻴﺎري از ﻣﺸﻜﻼﺗﻲ ﻛﻪ در ﺳﻴﺴﺘﻢ ﻗﺒﻠﻲ وﺟﻮد داﺷﺖ در اﻳﻦ روش رﻓﻊ ﺷﺪه اﺳﺖ ﻛﻪ درﺑﺎره ي آﻧﻬﺎ در اﻳﻦ ﻗﺴﻤﺖ ﺻﺤﺒﺘﻲ ﻧﺨـﻮاﻫﻴﻢ‬ ‫ﻛﺮد‪.‬‬ ‫ﺑﺮاي اﻳﻨﻜﻪ ﻳﻚ اﺳﻤﺒﻠﻲ ﻋﻤﻮﻣﻲ را در ﺳﻴﺴﺘﻢ ﻣﻘﺼﺪ ﻧﺼﺐ ﻛﻨﻴﺪ‪ ،‬ﺑﺎﻳﺪ آن را در ﻓﻮﻟﺪر ‪ GAC‬ﻛﭙﻲ ﻛﻨﻴﺪ‪ .‬اﻳﻦ ﻓﻮﻟﺪر در ﭘـﺮوژه ي ﻧـﺼﺐ‬ ‫ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﺪ‪ ،‬ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض دﻳﺪه ﻧﻤﻲ ﺷﻮد‪ .‬ﺑﺮاي ﻣﺸﺎﻫﺪه ي آن ﺑﺎﻳﺪ در ﻗﺴﻤﺖ ‪File‬‬ ‫‪ System on Target Machine‬در ﺑﺨﺶ ‪ File System‬ﻛﻠﻴﻚ راﺳﺖ ﻛﺮده و ﺳﭙﺲ از ﻣﻨﻮي ‪Add‬‬ ‫‪ Special Folder‬ﮔﺰﻳﻨﻪ ي ‪ Global Assembly Cache Folder‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪.‬‬ ‫ﻟﻴﺴﺖ زﻳﺮ ﺷﺎﻣﻞ ﺑﻌﻀﻲ از ﻣﺰاﻳﺎي اﺳﻤﺒﻠﻲ ﻫﺎي ﻋﻤﻮﻣﻲ اﺳﺖ‪:‬‬ ‫‬ ‫‬ ‫‬ ‫‬

‫اﻳﻦ اﺳﻤﺒﻠﻲ ﺑﻪ وﺳﻴﻠﻪ ي ﺷﻤﺎ اﻣﻀﺎ ﻣﻲ ﺷﻮد‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ ﻧﻤﻲ ﺗﻮان از آن ﺳﻮءاﺳﺘﻔﺎده ﻛﺮد‪.‬‬ ‫ﻧﺴﺨﻪ ي اﻳﻦ اﺳﻤﺒﻠﻲ ﺑﻪ ﺻﻮرت دﻗﻴﻖ ﻣﺸﺨﺺ ﺷﺪه اﺳﺖ‪.‬‬ ‫اﻳﻦ اﺳﻤﺒﻠﻲ در ﻳﻚ ﻓﻮﻟﺪر ﻣﺸﺨﺺ )‪ (GAC‬ﻛﭙﻲ ﻣﻲ ﺷﻮد و ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ وﺳﻴﻠﻪ ي ﻫﻤﻪ ي ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣـﻮرد اﺳـﺘﻔﺎده ﻗـﺮار‬ ‫ﮔﻴﺮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻻزم ﻧﻴﺴﺖ ﻛﻪ در ﻓﻮﻟﺪر ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻨﺪ از آن اﺳﺘﻔﺎده ﻛﻨﻨﺪ ﻛﭙﻲ ﺷﻮد‪.‬‬ ‫در ﻫﺮ ﻟﺤﻈﻪ‪ ،‬ﭼﻨﺪﻳﻦ ﻧﺴﺨﻪ از اﻳﻦ اﺳﻤﺒﻠﻲ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ ﻃﻮر ﻫﻤﺰﻣﺎن ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮﻧﺪ‪.‬‬

‫‪٨٧٥‬‬

‫ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي‪:‬‬ ‫در ﺑﺮﻧﺎﻣﻪ ي دوﻣﻲ ﻛﻪ در اﻳﻦ ﻓﺼﻞ ﺗﻤﺮﻳﻦ ﻛﺮدﻳﻢ‪ ،‬ﺑﺎ ﻳﻚ ﻧﻤﻮﻧﻪ از ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي آﺷﻨﺎ ﺷﺪﻳﻢ‪ .‬اﻟﺒﺘﻪ ﺑﺮﻧﺎﻣـﻪ اي ﻛـﻪ در آن‬ ‫ﻗﺴﻤﺖ ﺑﻪ ﻛﺎر ﺑﺮدﻳﻢ ﺑﺴﻴﺎر ﺳـﺎده ﺑـﻮد و ﻓﻘـﻂ از ﻳـﻚ ﻓﺎﻳـﻞ اﺟﺮاﻳـﻲ ﺗـﺸﻜﻴﻞ ﻣـﻲ ﺷـﺪ‪ ،‬ﺑﻨـﺎﺑﺮاﻳﻦ اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ ﻓﻘـﻂ ﺑـﻪ ‪.NET‬‬ ‫‪ Framework‬ﻧﻴﺎز داﺷﺖ و ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض در ﻗﺴﻤﺖ ﭘﻴﺶ ﻧﻴﺎزﻫﺎ اﻧﺘﺨﺎب ﺷـﺪه ﺑـﻮد‪ .‬اﻣـﺎ در‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎي واﻗﻌﻲ ﻣﻌﻤﻮﻻً از ﻛﻨﺘﺮﻟﻬﺎي وﻳﻨﺪوزي‪ ،‬ﻓﺎﻳﻠﻬﺎي اﺳﻤﺒﻠﻲ ﺣﺎوي ﻛﻼﺳﻬﺎي ﻣﻮرد ﻧﻴﺎز‪ ،‬ﻓﺎﻳﻠﻬﺎي راﻫﻨﻤﺎي ﺑﺮﻧﺎﻣﻪ و ﻳﺎ ﺑـﺴﻴﺎري از‬ ‫ﻓﺎﻳﻠﻬﺎي دﻳﮕﺮ در ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﭘﺲ ﺑﺎﺷﺪ ﻫﻨﮕﺎم اﻳﺠﺎد ﻧﺼﺐ ﻛﻨﻨﺪه‪ ،‬آﻧﻬﺎ را ﻧﻴﺰ اﺿﺎﻓﻪ ﻛﻨﻴﻢ‪ .‬ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ اﺳـﻤﺒﻠﻲ‬ ‫ﺧﺼﻮﺻﻲ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ آن را در ﻓﻮﻟﺪر اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ ﻛﭙﻲ ﻛﻨﻴﻢ‪ .‬ﺑﺮاي اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ اﺳﻤﺒﻠﻲ ﻋﻤﻮﻣﻲ ﻧﻴﺰ ﻛﺎﻓﻲ اﺳـﺖ ﻛـﻪ‬ ‫آن را در ‪ GAC‬ﻗﺮار دﻫﻴﻢ‪.‬‬

‫ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب‪:‬‬ ‫اﮔﺮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب ﻓﻘﻂ از اﺳﻤﺒﻠﻲ ﻫﺎي ﺧﺼﻮﺻﻲ اﺳﺘﻔﺎده ﻛﺮده ﺑﺎﺷﺪ‪ ،‬ﺗﻮزﻳﻊ آن ﺑﺴﻴﺎر ﺳﺎده ﺧﻮاﻫﺪ ﺑﻮد‪ .‬ﺑﺮاي اﻳـﻦ ﻛـﺎر ﻣـﻲ‬ ‫ﺗﻮاﻧﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬ﻳﻚ ﭘﺮوژه از ﻧﻮع ‪ Web Setup‬اﻳﺠﺎد ﻛﻨﻴﻢ ﺗﺎ ﺑﻪ وﺳـﻴﻠﻪ ي آن ﺑﺮﻧﺎﻣـﻪ ي ﺗﺤـﺖ وب‬ ‫ﺧﻮد را ﻧﺼﺐ ﻛﻨﻴﻢ‪ .‬ﭘﺮوژه ﻫﺎي ‪ Web Setup‬ﺑﺮاي ﻧﺼﺐ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب‪ ،‬اﺑﺘﺪا ﻳﻚ داﻳﺮﻛﺘﻮري ﻣﺠـﺎزي در وب ﺳـﺮور‬ ‫اﻳﺠﺎد ﻣﻲ ﻛﻨﻨﺪ و ﺳﭙﺲ ﻓﺎﻳﻠﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﭘﺮوژه را در داﻳﺮﻛﺘﻮري ﻓﻴﺰﻳﻜﻲ ﻣﻌﺎدل آن در ﻫﺎرد دﻳﺴﻚ وب ﺳﺮور ﻛﭙﻲ ﻣﻲ ﻛﻨﻨﺪ‪.‬‬ ‫ﻧﻜﺘﻪ‪ :‬ﺑﺮاي ﺗﻮزﻳﻊ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻣﺒﺘﻨﻲ ﺑﺮ وب ﻻزم ﻧﻴﺴﺖ ﻛﻪ ﻓﺎﻳﻠﻬﺎي ‪ CS‬ﻛﻪ ﺣﺎوي ﻛﺪ ‪ C#‬ﻫﺴﺘﻨﺪ را ﻧﻴﺰ در وب ﺳﺮور ﻗﺮار دﻫﻴﺪ‪،‬‬ ‫زﻳﺮا ﻛﺪ ﻣﻮﺟﻮد در اﻳﻦ ﻓﺎﻳﻠﻬﺎ در ﻳﻚ اﺳﻤﺒﻠﻲ در ﻓﻮﻟﺪر ‪ bin‬ﻛﺎﻣﭙﺎﻳﻞ ﻣﻲ ﺷـﻮد‪ .‬در اﻳـﻦ ﻧـﻮع ﺑﺮﻧﺎﻣـﻪ ﻫـﺎ ﻛـﺎﻓﻲ اﺳـﺖ ﻛـﻪ ﻓﺎﻳﻠﻬـﺎي‬ ‫‪ HTML ،css ،js ،ascx ،aspx‬و ﻳﺎ دﻳﮕﺮ ﻓﺎﻳﻠﻬﺎي اﺳﻜﺮﻳﭙﺘﻲ را در وب ﺳﺮور ﻗﺮار دﻫﻴﺪ‪.‬‬

‫ﺗﻮزﻳﻊ وب ﺳﺮوﻳﺲ ﻫﺎ‪:‬‬ ‫ﺗﻮزﻳﻊ وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﺴﻴﺎر ﻣﺸﺎﺑﻪ ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎي وب اﺳﺖ‪ .‬در ﺗﻮزﻳﻊ وب ﺳﺮوﻳﺲ ﻫﺎ ﻧﻴﺰ ﺑﺎﻳـﺪ ﻳـﻚ داﻳﺮﻛﺘـﻮري ﻣﺠـﺎزي در وب‬ ‫ﺳﺮور اﻳﺠﺎد ﻛﺮده و ﻓﺎﻳﻠﻬﺎي ﻣﻮرد ﻧﻴﺎز را در آن ﻛﭙﻲ ﻛﻨﻴﺪ‪ .‬اﻟﺒﺘﻪ اﻳﻦ ﻓﺎﻳﻠﻬﺎ ﺑﺎ ﻓﺎﻳﻠﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ﺗﻔﺎوت دارﻧﺪ‪ .‬ﺑـﺮاي ﺗﻮزﻳـﻊ‬ ‫وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﺎﻳﺪ ﻓﺎﻳﻠﻬﺎي ‪ asmx‬و ‪ discovery‬را ﺑﻪ ﻫﻤﺮاه اﺳﻤﺒﻠﻲ ﻣﺮﺑﻮط ﺑﻪ وب ﺳﺮوﻳﺲ‪ ،‬در ﺳﺮور ﻗﺮار دﻫﻴﺪ‪.‬‬

‫اﺑﺰارﻫﺎي ﻣﻔﻴﺪ‪:‬‬ ‫در اﻳﻦ ﻗﺴﻤﺖ ﺑﻌﻀﻲ از اﺑﺰارﻫﺎي ﻣﻔﻴﺪي ﻛﻪ ﺑﻪ ﻫﻤﺮاه ‪ .NET‬ﻋﺮﺿﻪ ﻣﻲ ﺷﻮﻧﺪ و ﻳﺎ ﺑﻪ ﺻﻮرت دروﻧﻲ در وﻳﻨﺪوز وﺟـﻮد دارﻧـﺪ و ﻣـﻲ‬ ‫ﺗﻮاﻧﻴﺪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ را ﻣﻌﺮﻓﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد‪ .‬ﻫﻨﮕﺎم اﻳﺠـﺎد ﺑﺮﻧﺎﻣـﻪ ي ﻧـﺼﺐ‪ ،‬ﺑﺎﻳـﺪ آن را در ﭼﻨـﺪﻳﻦ ﺳﻴـﺴﺘﻢ‬ ‫ﻣﺨﺘﻠﻒ ﺗﺴﺖ ﻛﺮد ﺗﺎ ﻣﺸﺨﺺ ﺷﻮد اﻳﻦ ﺑﺮﻧﺎﻣﻪ در ﺷﺮاﻳﻂ ﮔﻮﻧﺎﮔﻮن ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ‪ .‬در اﻳﻦ ﻣﻮاﻗﻊ اﮔﺮ اوﺿﺎع ﺑﻪ آن ﺻﻮرت ﻛﻪ اﻧﺘﻈﺎر‬ ‫دارﻳﺪ ﭘﻴﺶ ﻧﺮود‪ ،‬ﺑﺎﻳﺪ ﺑﻪ ﺻﻮرت دﺳﺘﻲ ﻫﻤﻪ ي ﻣﻮارد را ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ﺗﺎ ﻣﺸﺨﺺ ﻛﻨﻴﺪ ﻛﻪ ﻛﺪام ﻗﺴﻤﺖ از ﻛـﺎر ﺑـﺎ ﻣـﺸﻜﻞ ﻣﻮاﺟـﻪ ﺷـﺪه‬ ‫اﺳﺖ‪ .‬ﺑﺮاي ﻣﺜﺎل ﻓﺮض ﻛﻨﻴﺪ در ﻫﻨﮕﺎم ﺗﺴﺖ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﺗﺤﺖ وب‪ ،‬ﭘﺮوﺳﻪ ي ‪ ASPNET_WP.DLL‬ﺑﺎ ﻣﺸﻜﻞ ﻣﻮاﺟـﻪ ﻣـﻲ‬ ‫ﺷﻮد و از ﻛﺎر ﻣﻲ اﻓﺘﺪ‪ .‬در اﻳﻦ ﺷﺮاﻳﻂ ﺑﺎﻳﺪ ﺑﺘﻮاﻧﻴﺪ وب ﺳﺮور را ﻣﺠﺪداً راه اﻧﺪازي ﻛﺮده و ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ را دوﺑﺎره ﺗﺴﺖ ﻛﻨﻴﺪ‪ .‬در ﺷـﺮاﻳﻄﻲ‬ ‫‪٨٧٦‬‬

‫ﻣﺸﺎﺑﻪ ﻣﻤﻜﻦ اﺳﺖ ﻳﻚ اﺳﻤﺒﻠﻲ را در ‪ GAC‬ﺛﺒﺖ ﻛﻨﻴﺪ‪ ،‬اﻣﺎ ﺑﺮﻧﺎﻣﻪ ﻧﺘﻮاﻧﺪ ﺑﻪ آن دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷـﺪ‪ .‬در اﻳـﻦ ﻣﻮاﻗـﻊ ﺑﺎﻳـﺪ ﺑﺘﻮاﻧﻴـﺪ ﺑـﻪ‬ ‫ﺻﻮرت دﺳﺘﻲ اﺳﻤﺒﻠﻲ را ﻧﺼﺐ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﻮﺟﻪ ﺷﻮﻳﺪ در ﻛﺪام ﻣﺮﺣﻠﻪ از ﻧﺼﺐ اﺳﻤﺒﻠﻲ‪ ،‬ﻣﺸﻜﻞ ﺑﻪ وﺟﻮد ﻣﻲ آﻳﺪ‪ .‬ﻟﻴﺴﺖ زﻳـﺮ ﺑـﻪ ﺻـﻮرت‬ ‫ﻣﺨﺘﺼﺮ ﺑﻌﻀﻲ از اﻳﻦ اﺑﺰارﻫﺎ را ﺗﻮﺿﻴﺢ ﻣﻲ دﻫﺪ‪ .‬اﻟﺒﺘﻪ دﻗﺖ ﻛﻨﻴﺪ ﻛﻪ ﺗﻤﺎم اﻳﻦ اﺑﺰارﻫﺎ ﺑﻪ ﺻﻮرت دﺳﺘﻮرات ﺧﻂ ﻓﺮﻣـﺎن ﻫـﺴﺘﻨﺪ و ﺑـﺮاي‬ ‫اﺳﺘﻔﺎده از آن ﺑﺎﻳﺪ از ﺧﻂ ﻓﺮﻣﺎن وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻳﺎ ‪ Visual Studio 2005 Command Prompt‬اﺳـﺘﻔﺎده‬ ‫ﻛﻨﻴﺪ‪:‬‬ ‫‬

‫‬ ‫‬

‫‬

‫‬

‫‪ :ASPNET_RegIIS.exe‬ﻣﻌﻤﻮﻻً اﮔﺮ ‪ ASP.NET‬را اﺑﺘﺪا ﻧﺼﺐ ﻛﺮده ﺑﺎﺷﻴﺪ و ﺳﭙﺲ ‪ IIS‬را در ﺳﻴـﺴﺘﻢ‬ ‫ﺧﻮد ﻧﺼﺐ ﻛﻨﻴﺪ‪ IIS ،‬ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻪ درﺳﺘﻲ از ‪ ASP.NET‬اﺳﺘﻔﺎده ﻛﻨﺪ‪ .‬ﺑﺮاي رﻓﻊ اﻳﻦ ﻣﺸﻜﻞ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﺎ اﺳـﺘﻔﺎده از‬ ‫اﻳﻦ اﺑﺰار ﻣﺠﺪداً ‪ ASP.NET‬را ﻧﺼﺐ ﻛﻨﻴﺪ ﺗﺎ ﺑﺘﻮاﻧﺪ ﺧﻮد را ﺑﺎ وب ﺳﺮور )‪ (IIS‬ﺗﻄﺒﻴﻖ دﻫﺪ‪.‬‬ ‫‪ :IISReset‬اﻳﻦ دﺳﺘﻮر ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ وب ﺳﺮور راه اﻧﺪازي ﺷﻮد‪ .‬ﺑﺎ اﺳﺘﻔﺎده از آن ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﺪون اﻳﻨﻜـﻪ ﺑـﻪ‬ ‫ﻗﺴﻤﺖ ‪ IIS‬در ‪ MMC‬ﺑﺮوﻳﺪ‪ ،‬آن را ﻣﺠﺪداً راه اﻧﺪازي ﻛﻨﻴﺪ‪.‬‬ ‫‪ :ILDasm‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻠﻲ ﻧﻴﺰ در اﻳﻦ راﺑﻄﻪ ﺻﺤﺒﺖ ﺷﺪ‪ ،‬ﻳـﻚ ﻓﺎﻳـﻞ اﻳﺠـﺎد ﺷـﺪه ﺑـﺎ ‪ .NET‬ﺑﻌـﺪ از‬ ‫ﻛﺎﻣﭙﺎﻳﻞ ﺷﺪن ﺑﻪ ﻛﺪ ‪ IL‬ﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮد‪ .‬ﺑﺮاي ﻣﺸﺎده ي ﻛﺪ ‪IL‬اي ﻛﻪ در ﻳﻚ ﻓﺎﻳﻞ ﻗـﺮار دارد ﻣـﻲ ﺗﻮاﻧﻴـﺪ از اﻳـﻦ اﺑـﺰار‬ ‫اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ اﻳﻦ اﺑﺰار اﻃﻼﻋﺎت دﻳﮕﺮ ﻣﻮﺟﻮد در ﻓﺎﻳﻠﻬﺎ از ﻗﺒﻴـﻞ ‪ Manifest ،Metadata‬و ‪ ...‬را ﻧﻴـﺰ‬ ‫ﻧﺸﺎن ﻣﻲ دﻫﺪ‪.‬‬ ‫‪ :GACUtil‬اﻳﻦ اﺑـﺰار ﺑـﺮاي ﻧـﺼﺐ ﻛـﺮدن و ﻳـﺎ ﺣـﺬف ﻛـﺮدن ﻳـﻚ اﺳـﻤﺒﻠﻲ از ‪Global Assembly‬‬ ‫‪ Cache‬ﺑﻪ ﻛﺎر ﻣﻲ رود‪ .‬ﺑﺮاي ﻧﺼﺐ ﻳﻚ اﺳﻤﺒﻠﻲ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ دﺳﺘﻮر در ‪ GAC‬ﻣﻲ ﺗﻮاﻧﻴـﺪ از ﺳـﻮﻳﻴﭻ ‪ /I‬و ﺑـﺮاي‬ ‫ﺣﺬف آن ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺳﻮﻳﻴﭻ ‪ /u‬اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬ ‫‪1‬‬ ‫‪ :RegAsm‬اﻳﻦ دﺳﺘﻮر ﻣﻲ ﺗﻮاﻧﺪ ﻳﻚ اﺳﻤﺒﻠﻲ اﻳﺠﺎد ﺷﺪه ﺑﻪ وﺳـﻴﻠﻪ ي ‪ .NET‬را ﺑـﻪ ﺻـﻮرت ﻳـﻚ ﺷـﻴﺊ ‪ COM‬در‬ ‫ﺳﻴﺴﺘﻢ ﺛﺒﺖ ﻛﻨﺪ و ﻣﻌﻤﻮﻻً زﻣﺎﻧﻲ ﺑﻪ ﻛﺎر ﻣﻲ رود ﻛﻪ ﺑﺨﻮاﻫﻴﻢ ﺑﻴﻦ اﺷﻴﺎي ‪ COM‬و ‪ .NET‬ﻫﻤـﺎﻫﻨﮕﻲ اﻳﺠـﺎد ﻛﻨـﻴﻢ‪ .‬اﻳـﻦ‬ ‫دﺳﺘﻮر ﻧﻴﺰ داراي دو ﺳﻮﻳﻴﭻ ‪ /I‬و ‪ /u‬اﺳﺖ ﻛﻪ ﺑﺮاي ﻧﺼﺐ ﻛﺮدن و ﻳﺎ ﺣﺬف ﻛﺮدن ﻳﻚ ﻛﻼس ﺑﻪ ﻛﺎر ﻣﻲ رود‪.‬‬

‫ﻧﺘﻴﺠﻪ‪:‬‬ ‫ﺧﻮب‪ ،‬اﻣﻴﺪوارم از ﺑﺮرﺳﻲ روﺷﻬﺎي ﻣﺨﺘﻠﻒ ﺗﻮزﻳﻊ ﻳﻚ ﻧﺮم اﻓﺰار ﻟﺬت ﺑﺮده ﺑﺎﺷﻴﺪ‪ .‬در ﻗﺴﻤﺖ اول ﻓﺼﻞ‪ ،‬اﺑﺘﺪا ﺑﺎ اﺻﻄﻼﺣﺎﺗﻲ ﻛـﻪ در اﻳـﻦ‬ ‫زﻣﻴﻨﻪ وﺟﻮد دارﻧﺪ آﺷﻨﺎ ﺷﺪﻳﻢ‪ ،‬ﺳﭙﺲ دﻳﺪﻳﻢ ﻛﻪ ﭼﮕﻮﻧﻪ ﻣﻲ ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از روش ‪ ClickOnce‬ﺑﻪ ﺳﺎدﮔﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﺗﻮزﻳﻊ‬ ‫ﻛﺮد‪ .‬ﺑﻌﺪ از آن ﺑﺎ روش ‪ XCOPY‬آﺷﻨﺎ ﺷﺪﻳﻢ و ﻫﻤﭽﻨﻴﻦ ﻧﺤﻮه ي اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه را ﺑﺎ اﺳﺘﻔﺎده از وﻳـﮋوال اﺳـﺘﻮدﻳﻮ‬ ‫‪ 2005‬ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ‪ .‬در ﺑﺨﺶ ﺑﻌﺪي ﻓﺼﻞ ﺑﺎ اﺳﻤﺒﻠﻲ ﻫﺎي ﺧﺼﻮﺻﻲ و ﻋﻤﻮﻣﻲ ﻧﻴﺰ ﻣﺰاﻳﺎ و ﻣﻌﺎﻳﺐ ﻫﺮ ﻛﺪام آﺷﻨﺎ ﺷﺪﻳﻢ‪ .‬ﻫﺪف از اﻳـﻦ‬ ‫ﻓﺼﻞ اﻳﻦ ﻧﺒﻮد ﻛﻪ ﺗﻤﺎم اﻳﻦ ﻣﻮارد را ﺑﻪ ﺷﻤﺎ آﻣﻮزش دﻫﻢ‪ ،‬ﺑﻠﻜﻪ در اﻳﻦ ﻓﺼﻞ ﺳﻌﻲ ﻛﺮده ﺑﺎ ﻣﻌﺮﻓﻲ اﺟﻤﺎﻟﻲ آﻧﻬﺎ ﺑﻪ ﺷﻤﺎ ﻧﺸﺎن دﻫـﻢ ﻛـﻪ‬ ‫ﻣﻄﺎﻟﺐ زﻳﺎدي در اﻳﻦ زﻣﻴﻨﻪ وﺟﻮد دارد ﻛﻪ ﻣﻲ ﺗﻮان در ﻣﻮرد آﻧﻬﺎ ﻣﻄﺎﻟﻌﻪ ﻛﺮد‪.‬‬ ‫در ﭘﺎﻳﺎن اﻳﻦ ﻓﻴﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ‪:‬‬ ‫‬ ‫‬ ‫‬

‫ﭼﮕﻮﻧﮕﻲ ﺗﻮزﻳﻊ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از روش ‪.ClickOnce‬‬ ‫اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪.2005‬‬ ‫اﺳﺘﻔﺎده از روﺷﻬﺎي ﺗﻮزﻳﻊ ﺳﺎده ي ﺑﺮﻧﺎﻣﻪ ﻫﺎ در ﺷﺮاﻳﻂ ﻣﻤﻜﻦ ﻣﺎﻧﻨﺪ ‪.XCOPY‬‬ ‫‪Component Object Model‬‬

‫‪1‬‬

‫‪٨٧٧‬‬

‫‬

‫وﻳﺮاﻳﺶ راﺑﻂ ﻛﺎرﺑﺮي ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه‪.‬‬

‫ﺗﻤﺮﻳﻦ‪:‬‬

‫ﺗﻤﺮﻳﻦ ‪:1‬‬ ‫ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه ﺑـﺮاي ﺑﺮﻧﺎﻣـﻪ ي ‪ Notepad‬اﻳﺠـﺎد ﻛﻨﻴـﺪ‪ .‬ﺑـﺮاي اﻳـﻦ ﻛـﺎر اﺑﺘـﺪا ﺑﺎﻳـﺪ ﻓﺎﻳـﻞ اﺟﺮاﻳـﻲ ﺑﺮﻧﺎﻣـﻪ‪ ،‬ﻳﻌﻨـﻲ‬ ‫‪ notepad.exe‬را در ﻓﻮﻟﺪر وﻳﻨﺪوز ﺧﻮد ﭘﻴﺪا ﻛﺮده و ﺳﭙﺲ آن را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪ .‬ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه‬ ‫را ﺑﻪ ﮔﻮﻧﻪ اي ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ﺗﺎ ﻳﻚ ﺷﻮرت ﻛﺎت از ‪ notepad‬را در ﻣﻨﻮي ‪ Start‬ﻗﺮار دﻫﺪ و ﻓﺎﻳﻞ اﺟﺮاﻳﻲ اﺻﻠﻲ را ﻧﻴﺰ در ﻓﻮﻟﺪر‬ ‫‪ Program Files‬ﻛﭙﻲ ﻛﻨﺪ‪ .‬ﻣﻲ ﺗﻮاﻧﻴﺪ ﻧﺎم ﺷﺮﻛﺖ ﺳﺎزﻧﺪه و ﻧﺎم ﻧﻮﻳﺴﻨﺪه ي ﺑﺮﻧﺎﻣﻪ را ﻧﻴﺰ ﺑﻪ دﻟﺨﻮاه ﺧﻮد ﺗﻐﻴﻴﺮ دﻫﻴﺪ‪.‬‬

‫ﺗﻤﺮﻳﻦ ‪:2‬‬ ‫در ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه اي ﻛﻪ در ﺗﻤﺮﻳﻦ اول اﻳﺠﺎد ﻛﺮدﻳﺪ‪ ،‬ﻳﻚ ﻛﺎدر ‪ Splash Screen‬ﻧﻴـﺰ اﺿـﺎﻓﻪ ﻛﻨﻴـﺪ ﺗـﺎ در اﺑﺘـﺪاي‬ ‫ﻧﺼﺐ ﻧﻤﺎﻳﺶ داده ﺷﻮد‪ .‬ﺳﭙﺲ ﻳﻚ ﻋﻜﺲ ﺑﺎ اﻧﺪازه ي در ﺣﺪود ‪ 320*480‬را از ﻛﺎﻣﭙﻴﻮﺗﺮ ﺧﻮد ﭘﻴﺪا ﻛﺮده و آن را در اﻳﻦ ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ‬ ‫دﻫﻴﺪ‪ .‬دﻗﺖ ﻛﻨﻴﺪ ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﺪ ﻋﻜﺲ را در ﻓﺮم ﻧﻤﺎﻳﺶ دﻫﻴﺪ‪ ،‬ﺑﺎﻳﺪ آن را ﺑﻪ ﭘﺮوژه ي ﻧﺼﺐ ﻛﻨﻨﺪه اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪.‬‬

‫‪٨٧٨‬‬

‫ﻓﺼﻞ ﺑﻴﺴﺖ و دوم‪ :‬اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﻮﺑﺎﻳﻞ‬ ‫اﻣﺮوزه اﺳﺘﻔﺎده از دﺳﺘﮕﺎه ﻫﺎي ﻣﻮﺑﺎﻳﻞ‪ ،‬ﺑﻪ وﻳﮋه دﺳﺘﻴﺎر ﻫﺎي دﻳﺠﻴﺘﺎل ﺷﺨﺼﻲ ﻳﺎ ‪PAD1‬ﻫﺎ ﺑﻪ ﺷﺪت در ﺑـﻴﻦ ﻣـﺮدم در ﺣـﺎل اﻓـﺰاﻳﺶ‬ ‫اﺳﺖ‪ .‬ﺑﺎزاري ﻛﻪ در ﮔﺬﺷﺘﻪ ﺑﻪ وﺳﻴﻠﻪ ي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ‪ Palm‬ﺗﺴﺨﻴﺮ ﺷﺪه ﺑﻮد‪ ،‬اﻣﺮوزه در دﺳـﺖ ﺳﻴـﺴﺘﻢ ﻋﺎﻣـﻞ وﻳﻨـﺪوز ‪ CE‬ﻗـﺮار‬ ‫ﮔﺮﻓﺘﻪ اﺳﺖ‪ .‬ﺑﺮ اﺳﺎس ﮔﺰارﺷﻲ ﻛﻪ در ‪ 12‬ﻧﻮاﻣﺒﺮ ‪ 2004‬ﺑﻪ وﺳﻴﻠﻪ ي ‪ Associated Press‬ﺑﻪ ﭼﺎپ رﺳﻴﺪ‪ ،‬در ﺑﻴﻦ دﺳﺘﮕﺎه‬ ‫ﻫﺎي ‪ PDA‬اي ﻛﻪ در ﻧﻴﻤﻪ ي دوم ﺳﺎل ‪ 2004‬ﺑﻪ ﻓﺮوش رﺳﻴﺪه اﻧﺪ‪ ،‬ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ وﻳﻨﺪوز ‪ CE‬در رﺗﺒﻪ ي اول ﻗـﺮار ﮔﺮﻓﺘـﻪ اﺳـﺖ‪ .‬از‬ ‫ﺑﻴﻦ ‪ 2/8‬ﻣﻴﻠﻴﻮن دﺳﺘﮕﺎه ‪ PAD‬ﻛﻪ در اﻳﻦ ﻣﺪت در ﺳﺮاﺳﺮ ﺟﻬﺎن ﺑﻪ ﻓﺮوش رﺳﻴﺪه اﺳـﺖ‪ ،‬وﻳﻨـﺪوز ‪ CE‬ﺑـﺎ ‪ 48/1‬درﺻـﺪ‪ ،‬ﺑـﻪ ﻋﻨـﻮان‬ ‫ﭘﺮﻓﺮوش ﺗﺮﻳﻦ ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻣﻌﺮﻓﻲ ﺷﺪه اﺳﺖ‪ .‬ﺑﻪ ﻫﻤﻴﻦ اﻧﺪازه ﻛﻪ ﻓﺮوش دﺳﺘﮕﺎه ﻫﺎي ‪ PDA‬و ﻧﻴﺰ ﺳﻴـﺴﺘﻢ ﻋﺎﻣـﻞ وﻳﻨـﺪوز ‪ CE‬در‬ ‫ﺣﺎل اﻓﺰاﻳﺶ اﺳﺖ‪ ،‬درﺧﻮاﺳﺖ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﺘﻮاﻧﻨﺪ در اﻳﻦ دﺳﺘﮕﺎه ﻫﺎ و ﺑﺎ اﻳﻦ ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻛﺎر ﻛﻨﻨﺪ ﻧﻴﺰ روز ﺑـﻪ روز در ﺣـﺎل رﺷـﺪ‬ ‫اﺳﺖ‪.‬‬ ‫ﺑﻪ ﻫﻤﻴﻦ ﻋﻠﺖ در وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬ﺳﻌﻲ ﺷﺪه اﺳﺖ ﻛﻪ ﻃﺮاﺣﻲ اﻳﻦ ﻧـﻮع ﺑﺮﻧﺎﻣـﻪ ﻫـﺎ ﺑـﺮاي ﺳﻴـﺴﺘﻢ ﻋﺎﻣـﻞ ﻫـﺎي وﻳﻨـﺪوز ‪،CE‬‬ ‫‪ Pocket PC 2003‬و ‪ SmartPhone 2003‬ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﺳﺎده ﺷﻮد‪ .‬در ﻃﻲ اﻳﻦ ﻓﺼﻞ ﻧﺤﻮه ي اﻳﺠﺎد ﺑﺮﻧﺎﻣـﻪ‬ ‫ﻫﺎﻳﻲ ﻛﻪ ﺑﺘﻮاﻧﻨﺪ در دﺳﺘﮕﺎه ﻫﺎي ‪ PDA‬و ﺑﺎ ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ وﻳﻨﺪوز ‪ Pocket PC‬اﺟﺮا ﺷﻮﻧﺪ را ﺑﺮرﺳﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد‪.‬‬

‫درك ﻣﺤﻴﻂ‪:‬‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ اﺣﺘﻤﺎﻻً ﺗﺎ ﻛﻨﻮن ﻣﺸﺎﻫﺪه ﻛﺮده اﻳﺪ‪ PDA ،‬دﺳﺘﮕﺎﻫﻲ اﺳﺖ ﻫﻤﺎﻧﻨﺪ ﻳـﻚ ﻛـﺎﻣﭙﻴﻮﺗﺮ ﻛـﻪ ﺑـﺴﻴﺎر ﻛـﻮﭼﻜﺘﺮ اﺳـﺖ و اﻣﻜﺎﻧـﺎت‬ ‫ﻛﻤﺘﺮي ﻧﻴﺰ دارد‪ .‬ﻳﻚ دﺳﺘﮕﺎه ‪ PDA‬ﻣﻌﻤﻮﻟﻲ در ﺳﺎل ‪ 2002‬داراي ‪ 64‬ﻣﮕﺎ ﺑﺎﻳﺖ رم داﺧﻠﻲ و ﻳﻚ ﭘﺮدازﻧﺪه ي ‪ 206‬ﻣﮕﺎ ﻫﺮﺗﺰي اﺳﺖ‪.‬‬ ‫وزن اﻳﻦ دﺳﺘﮕﺎه در ﺣﺪود ﻧﻴﻢ ﻛﻴﻠﻮﮔﺮم اﺳﺖ و داراي ﻳﻚ ﺻﻔﺤﻪ ﻧﻤـﺎﻳﺶ ‪ 3,5‬اﻳﻨﭽـﻲ اﺳـﺖ ﻛـﻪ ﻣـﻲ ﺗﻮاﻧـﺪ ﺻـﻔﺤﻪ اي را ﺑـﺎ دﻗـﺖ‬ ‫‪ 320*240‬ﭘﻴﻜﺴﻞ و ‪ 65‬ﻫﺰار رﻧﮓ ﻧﺸﺎن دﻫﺪ‪ .‬ﺣﺎل اﻳﻦ دﺳﺘﮕﺎه را ﺑﺎ ﻳﻚ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻋﺎدي ﻣﻘﺎﻳﺴﻪ ﻛﻨﻴﺪ‪ .‬ﻳـﻚ ﻛـﺎﻣﭙﻴﻮﺗﺮ ﻋـﺎدي داراي‬ ‫ﻳﻚ ﭘﺮدازﻧﺪه ي ‪ 3‬ﮔﻴﮕﺎﻫﺮﺗﺰي‪ 120 ،‬ﮔﻴﮕﺎﺑﺎﻳﺖ ﻫﺎرد دﻳﺴﻚ‪ 512 ،‬ﻣﮕﺎ ﺑﺎﻳﺖ رم و ﻳﻚ ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ ‪ 19‬اﻳﻨﭽﻲ اﺳﺖ ﻛـﻪ ﻣـﻲ ﺗﻮاﻧـﺪ‬ ‫ﺗﺼﻮﻳﺮي را ﺑﺎ دﻗﺖ ‪ 1200*1600‬و ﺑﻴﺶ از ‪ 4‬ﺑﻴﻠﻴﻮن رﻧﮓ ﻧﻤﺎﻳﺶ دﻫﺪ‪ .‬ﺗﻔﺎوت ﻋﻤﺪه ي دﻳﮕـﺮي ﻛـﻪ ﺑـﻴﻦ اﻳـﻦ ﻧـﻮع دﺳـﺘﮕﺎه ﻫـﺎ و‬ ‫ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﺎي ﻋﺎدي وﺟﻮد دارد در اﻳﻦ اﺳﺖ ﻛﻪ ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ دﺳﺘﮕﺎه ﻫﺎي ‪ PDA‬ﻛﺸﻴﺪه اﺳﺖ اﻣﺎ ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫـﺎي‬ ‫ﻋﺎدي ﭘﻬﻦ و وﺳﻴﻊ اﺳﺖ‪ .‬ﻫﻤﭽﻨﻴﻦ ﺑﺎﻳﺪ در ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ در دﺳﺘﮕﺎه ﻫﺎي ‪ PDA‬زﻣﺎﻧﻲ ﻛـﻪ ﺑـﺎﺗﺮي ﺗﻤـﺎم ﻣـﻲ ﺷـﻮد‪ ،‬ﻫﻤـﻪ ي‬ ‫اﻃﻼﻋﺎت ﺑﺮﻧﺎﻣﻪ ﻛﻪ در رم ﻗﺮار دارﻧﺪ از ﺑﻴﻦ ﻣﻲ روﻧﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎﻳﺪ ﺑﺎ در ﻧﻈﺮ ﮔﺮﻓﺘﻦ ﺗﻤﺎم اﻳﻦ ﻧﻜﺎت و ﻣﻮارد ﺑﻪ ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﺑﺮاي اﻳـﻦ‬ ‫ﻧﻮع وﺳﺎﻳﻞ ﺑﭙﺮدازﻳﺪ‪.‬‬ ‫ﺣﺎل ﻛﻪ ﺑﺎ ﻣﺤﻴﻂ ﻛﺎر آﺷﻨﺎ ﺷﺪﻳﺪ‪ ،‬ﺳﻌﻲ ﻣﻲ ﻛﻨﻢ اﻣﻜﺎﻧﺎﺗﻲ ﻛﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ در اﺧﺘﻴﺎر ﺷﻤﺎ ﻗﺮار ﻣﻲ دﻫﺪ ﺗﺎ ﺳﺎده ﺗﺮ ﺑﺘﻮاﻧﻴﺪ ﺑـﺮاي اﻳـﻦ‬ ‫دﺳﺘﮕﺎه ﻫﺎ ﺑﺮﻧﺎﻣﻪ ﺑﻨﻮﻳﺴﻴﺪ را ﺧﻼﺻﻪ ﻛﻨﻢ‪ .‬ﺑﺮاي ﺷﺮوع ‪ .NET Compact Framework‬ﻳﺎ ‪ CF‬در اﺧﺘﻴـﺎر ﺷـﻤﺎ ﻗـﺮار‬ ‫ﻣﻲ ﮔﻴﺮد‪ .‬ﭼﺎرﭼﻮب ‪ CF‬ﻳﻚ زﻳﺮ ﻣﺠﻤﻮﻋﻪ از ﭼﺎرﭼﻮب ‪.NET‬اﺳﺖ ﻛﻪ در ﻓﺼﻠﻬﺎي ﻗﺒﻠﻲ ﺑﺎ آن آﺷﻨﺎ ﺷﺪﻳﺪ‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ ﻫـﻢ اﻛﻨـﻮن ﺑـﺎ‬ ‫ﺑﻴﺸﺘﺮ ﺑﺨﺸﻬﺎي آن آﺷﻨﺎ ﻫﺴﺘﻴﺪ )زﻳﺮا دﻗﻴﻘﺎً ﻣﺸﺎﺑﻪ ﭼﺎرﭼﻮب ‪ .NET‬اﺳﺖ( و ﺑﻪ ﺳﺎدﮔﻲ و ﺑﺎ ﻛﻤﺘﺮﻳﻦ ﻣﻘﺪار ﻳﺎدﮔﻴﺮي ﻣـﻲ ﺗﻮاﻧﻴـﺪ از آن‬ ‫ﺑﺮاي ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ .‬دﻗﻴﻘﺎً ﻣﺸﺎﺑﻪ ﭼﺎرﭼﻮب ‪ CF ،.NET‬ﻧﻴﺰ از ‪ CLR‬ﺑﺮاي اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨـﺪ و ﻛـﺪ‬ ‫ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ي آن ﺗﻮﻟﻴﺪ ﻣﻲ ﺷﻮﻧﺪ ﺑﻪ زﺑﺎن ‪ MSIL‬ﻫﺴﺘﻨﺪ ﺗﺎ ﺑﺘﻮاﻧﺪ ﺑﻪ ﺻﻮرت ﻣﺴﺘﻘﻞ از ﭘﻠﺖ ﻓﺮم ﻋﻤﻞ ﻛﻨﺪ‪ .‬ﻣﻬﻤﺘﺮﻳﻦ ﻧﻜﺘﻪ اي‬ ‫ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﻫﻨﮕﺎم ﻛﺎر ﺑﺎ ‪ CF‬ﺗﻮﺟﻪ ﺷﻤﺎ را ﺟﻠﺐ ﻛﻨﺪ در اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺴﻴﺎري از ﻛﻨﺘﺮل ﻫﺎﻳﻲ ﻛﻪ در ﻗﺴﻤﺘﻬﺎي ﻗﺒﻞ از آﻧﻬﺎ اﺳﺘﻔﺎده‬ ‫ﻣﻲ ﻛﺮدﻳﺪ ﻫﻢ اﻛﻨﻮن وﺟﻮد ﻧﺪارﻧﺪ و ﻳﺎ ﺑﺴﻴﺎري از ﻣﺘﺪ ﻫﺎ و ﻳﺎ ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺒﻠﻲ ﺑﺎ آﻧﻬﺎ ﻛـﺎر ﻣـﻲ ﻛﺮدﻳـﺪ‪ ،‬در ‪CF‬‬

‫‪Personal Digital Assistant‬‬

‫‪1‬‬

‫‪٨٧٩‬‬

‫ﺣﺬف ﺷﺪه اﻧﺪ‪ .‬ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﺎ ‪ CF‬ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮﻧﺪ ﻧﻴﺰ ﻣﺘﻔﺎوت اﺳﺖ‪ .‬ﺑﺮاي ﺗﻮزﻳﻊ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻧﻤﻲ ﺗﻮاﻧﻴـﺪ ﻫﻤﺎﻧﻨـﺪ ﺑﺮﻧﺎﻣـﻪ‬ ‫ﻫﺎي ﻗﺒﻠﻲ از ‪ CD‬و ﻳﺎ ﻓﻼﭘﻲ دﻳﺴﻚ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ ،‬ﺑﻠﻜﻪ ﺑﺎﻳﺪ اﺑﺰاري ﺑﻪ ﻧﺎم ‪ ActiveSync‬را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ ﺗﺎ ﺑﺘﻮاﻧﻴﺪ ﺑﻪ ﺳـﺎدﮔﻲ‬ ‫ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد را در ﺑﻴﻦ دﺳﺘﮕﺎه ﻫﺎي ‪ PDA‬ﺗﻮزﻳﻊ ﻛﻨﻴﺪ‪ .‬در اﻳﻦ ﻗﺴﻤﺖ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﻣﻮاردي ﻛﻪ ﻻزم اﺳﺖ ﺑـﺮاي ﻃﺮاﺣـﻲ ﺑﺮﻧﺎﻣـﻪ‬ ‫ﻫﺎي ﻣﻮﺑﺎﻳﻞ ﺑﺪاﻧﻴﻢ را ﺑﺎ ﺟﺰﺋﻴﺎت دﻗﻴﻖ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ‪.‬‬

‫‪:Common Language Runtime‬‬ ‫ﻳﻜﻲ از اﻫﺪاف ‪ CLR‬ﻛﻪ ﺑﻪ ﻋﻨﻮان ﻣﻮﺗﻮر اﺟﺮاﻳﻲ‪ 1‬ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮد‪ ،‬اﻳﻦ اﺳﺖ ﻛﻪ اﺟﺎزه ﻣﻲ دﻫﺪ ﭼﻨﺪ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺻـﻮرت ﻫﻤﺰﻣـﺎن و‬ ‫ﻣﻮازي ﺑﺎ ﻳﻜﺪﻳﮕﺮ اﺟﺮا ﺷﻮﻧﺪ‪ .‬ﻣﻌﻤﻮﻻ ‪ CLR‬ﻣﻮارد زﻳﺮ را در اﺟﺮاي ﻫﺮ ﺑﺮﻧﺎﻣﻪ ﻛﻨﺘﺮل و ﻣﺪﻳﺮﻳﺖ ﻣﻲ ﻛﻨﺪ‪:‬‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬

‫ﻣﺪﻳﺮﻳﺖ ﺣﺎﻓﻈﻪ ﺑﺎ اﺳﺘﻔﺎده از ﺳﻴﺴﺘﻤﻲ ﺑﻪ ﻧﺎم ‪GC2‬‬ ‫رﻓﻊ واﺑﺴﺘﮕﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﻪ ﭘﻠﺖ ﻓﺮم ﺑﺎ اﺳﺘﻔﺎده از ﻛﺪ ﻫﺎي ‪.MSIL‬‬ ‫ﺳﻴﺴﺘﻢ ﻧﻮع داده اي ﻋﻤﻮﻣﻲ‪.‬‬ ‫ﺳﻴﺴﺘﻢ ﻛﻨﺘﺮل ﺧﻄﺎﻫﺎ و اﺳﺘﺜﻨﺎ ﻫﺎ‪.‬‬ ‫ﻛﺎﻣﭙﺎﻳﻞ ﺑﺮﻧﺎﻣﻪ ﻫﺎ در ﻣﻮاﻗﻊ ﻣﻮرد ﻧﻴﺎز ﺑﺎ اﺳﺘﻔﺎده از ‪.JIT‬‬

‫‪:ActiveSync‬‬ ‫ﺑﺮاي اﻳﻨﻜﻪ ﺑﺘﻮاﻧﻴﺪ ‪ PDA‬ﺧﻮد را ﺑﻪ ‪PC‬ﺗﺎن ﻣﺘﺼﻞ ﻛﻨﻴﺪ‪ ،‬ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺑﺮﻧﺎﻣﻪ ي ‪ ActiveSync‬اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ .‬ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ‬ ‫ﺑﺮﻧﺎﻣﻪ‪ PDA ،‬ﺷﻤﺎ ﺑﻪ ﺳﺮﻋﺖ ﺑﻪ ‪ PC‬ﻣﺘﺼﻞ ﻣﻲ ﺷﻮد و ﻣﻲ ﺗﻮاﻧﺪ ﻋﻼوه ﺑﺮ اﺳﺘﻔﺎده از ‪ ،PC‬از ﻣﻨﺎﺑﻊ ﺷﺒﻜﻪ اي آن و ﻳﺎ ﺣﺘﻲ از اﺗـﺼﺎل‬ ‫اﻳﻨﺘﺮﻧﺖ آن ﻧﻴﺰ ﺑﺮاي ﻣﺘﺼﻞ ﺷﺪن ﺑﻪ اﻳﻨﺘﺮﻧﺖ اﺳﺘﻔﺎده ﻛﻨﺪ‪ .‬ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ داده ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ ﻫـﺎي ﺧـﻮد را‬ ‫ﺑﻴﻦ ‪ PDA‬و ‪ PC‬ﻫﻤﺎﻫﻨﮓ ﻛﻨﻴﺪ‪ ،3‬ﺑﻪ ﻳﻚ وب ﺳﺮوﻳﺲ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ‪ ،‬و ﻳﺎ ﺣﺘﻲ از داده ﻫﺎي ﻣﻮﺟﻮد در ﻳﻚ ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ‬ ‫‪ SQL Server‬اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬ ‫از آﻧﺠﺎﻳﻲ ﻛﻪ ﻣﻌﻤﻮﻻ اﻏﻠﺐ ﺷﻤﺎ از دﺳﺘﮕﺎه ‪ Pocket PC‬اﺳﺘﻔﺎده ﻧﻤﻲ ﻛﻨﻴﺪ‪ ،‬ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ در اﻳﻦ ﻗﺴﻤﺖ ﻓﻘﻂ ﺑﻪ اﺧﺘـﺼﺎر ﻧـﻮ‪.‬ه‬ ‫ي ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎ در اﻳﻦ ﻧﻮع دﺳﺘﮕﺎه ﻫﺎ را ﺗﻮﺿﻴﺢ ﻣﻲ دﻫﻢ‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻓﺼﻞ ﻗﺒﻞ ﻫﻨﮕﺎم اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ي ﻧﺼﺐ ﻛﻨﻨﺪه ﺑﺎ اﺳﺘﻔﺎده‬ ‫از وﻳﮋوال اﺳﺘﻮدﻳﻮ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﻢ‪ ،‬ﻳﻜﻲ از اﻧﻮاع اﻳـﻦ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎ ﻛـﻪ در ﻛـﺎدر ‪ New Project‬وﺟـﻮد داﺷـﺖ‪Smart ،‬‬ ‫‪ Device Cab Project‬ﺑﻮد‪ .‬ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﻧﻮع ﭘﺮوژه ﻣﻲ ﺗﻮاﻧﻴﺪ از ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد ﻳﻚ ﺧﺮوﺟﻲ ﺑـﺎ ﭘـﺴﻮﻧﺪ ‪.cab‬‬ ‫درﻳﺎﻓﺖ ﻛﺮده و ﺳﭙﺲ آن را ﺑﺎ اﺳﺘﻔﺎده از ‪ ActiveSync‬ﺑﻪ دﺳﺘﮕﺎه ‪ PDA‬ﺧﻮد اﻧﺘﻘﺎل دﻫﻴﺪ‪ .‬ﺳﭙﺲ ﻣـﻲ ﺗﻮاﻧﻴـﺪ ﺑـﺎ اﺳـﺘﻔﺎده از‬ ‫‪ Pocket PC‬روي اﻳﻦ ﻓﺎﻳﻞ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻧﺼﺐ ﺷﻮد و ﺑﺘﻮاﻧﻴﺪ از آن اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬ ‫ﺑﺮاي درﻳﺎﻓﺖ ﻧﺮم اﻓﺰار ‪ ActiveSync‬ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﻗﺴﻤﺖ ‪ Download‬از ﺳﺎﻳﺖ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ‪ .‬ﻓﺎﻳﻞ اﺟﺮاﻳﻲ‬ ‫اﻳﻦ ﻧﺮم اﻓﺰار در ﺣﺪود ‪ 4‬ﻣﮕﺎ ﺑﺎﻳﺖ ﺣﺞ دارد و ﻣﻲ ﺗﻮاﻧﻴﺪ از آدرس زﻳﺮ آن را درﻳﺎﻓﺖ ﻛﻨﻴﺪ‪:‬‬ ‫‪http://www.microsoft.com/downlaods/‬‬

‫‪1‬‬

‫‪Execution Engine‬‬ ‫‪Garbage Collection‬‬ ‫‪3‬‬ ‫‪Synchronization‬‬ ‫‪2‬‬

‫‪٨٨٠‬‬

‫ﻧﻮع ﻫﺎي داده اي در ‪:CF‬‬ ‫ﻣﻌﻤﻮﻻً زﻣﺎﻧﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺮاي دﺳﺘﮕﺎه ﻫﺎي ﻫﻮﺷﻤﻨﺪ را ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪ 2005‬ﺷﺮوع ﻣﻲ ﻛﻨﻴﺪ‪ ،‬ﻧـﻮع ﻫـﺎي داده اي‬ ‫ﻛﻪ ﺑﺮاي آﻧﻬﺎ وﺟﻮد دارﻧﺪ ﺑﺮاي ﺷﻤﺎ آﺷﻨﺎ ﺧﻮاﻫﺪ ﺑﻮد‪ .‬ﺟﺪول زﻳﺮ ﻟﻴﺴﺘﻲ از ﻧﻮع ﻫﺎي داده اي ﻛﻪ در ‪ CF‬وﺟﻮد دارﻧﺪ را ﺑﻪ ﻫﻤﺮاه ﻓـﻀﺎﻳﻲ‬ ‫ﻛﻪ اﺷﻐﺎل ﻣﻲ ﻛﻨﻨﺪ و ﻫﻤﭽﻨﻴﻦ ﺑﺎزه ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ داﺷﺘﻪ ﺑﺎﺷﻨﺪ را ﻧﺸﺎن ﻣﻲ دﻫﺪ‪ .‬اﻟﺒﺘﻪ در ﻫﻨﮕﺎم ﻧﻮﺷـﺘﻦ ﺑﺮﻧﺎﻣـﻪ ﺑـﺮاي اﻳـﻦ ﻧـﻮع‬ ‫دﺳﺘﮕﺎه ﻫﺎ ﺑﺎﻳﺪ ﻣﺪ ﻧﻈﺮ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﻣﻨﺎﺑﻊ آﻧﻬﺎ ﺑﺴﻴﺎر ﻣﺤﺪود اﺳﺖ و ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﺑﺎﻳﺪ از آﻧﻬﺎ ﺑﻪ ﺻﻮرت ﺑﻬﻴﻨﻪ اﺳﺘﻔﺎده ﻛﺮد‪.‬‬

‫ﻧﻮع داده در ‪C#‬‬

‫ﻧﻮع داده ي‬ ‫ﻋﻤﻮﻣﻲ در‬ ‫‪CLR‬‬

‫ﺑﺎزه ي ﻣﻘﺎدﻳﺮ‬

‫اﻧﺪازه‬

‫‪bool‬‬

‫‪Boolean‬‬

‫ﺑــﺴﺘﮕﻲ‬ ‫دارد‬

‫‪ True‬و ﻳﺎ ‪) False‬درﺳﺖ ﻳﺎ ﻏﻠﻂ(‬

‫‪byte‬‬

‫‪Byte‬‬

‫‪ 1‬ﺑﺎﻳﺖ‬

‫‪ 0‬ﺗﺎ ‪ 255‬ﺑﺪون ﻋﻼﻣﺖ‬

‫‪char‬‬

‫‪Char‬‬

‫‪ 2‬ﺑﺎﻳﺖ‬

‫ﻛﺎراﻛﺘﺮ ﻫﺎي ﻳﻮﻧﻴﻜﺪ‬

‫‪DateTime‬‬

‫‪DateTime‬‬

‫‪ 8‬ﺑﺎﻳﺖ‬

‫از ﺳــﺎﻋﺖ ‪ 0:00:00‬روز ‪ 1‬ژاﻧﻮﻳــﻪ ﺳــﺎل ‪ 0001‬ﺗــﺎ ﺳــﺎﻋﺖ‬ ‫‪ 11:59:59‬روز ‪ 31‬دﺳﺎﻣﺒﺮ ﺳﺎل ‪9999‬‬

‫‪decimal‬‬

‫‪Decimal‬‬

‫‪ 16‬ﺑﺎﻳﺖ‬

‫از ‪ 0‬ﺗــﺎ ‪) 79228162514264337593543950335‬ﻣﺜﺒــﺖ و‬ ‫ﻣﻨﻔــــــﻲ( ﺑــــــﺪون رﻗــــــﻢ اﻋــــــﺸﺎر؛ از ‪ 0‬ﺗــــــﺎ‬ ‫‪ 7/9228162514264337593543950335‬ﺑﺎ ﺑﻴﺴﺖ و ﻫﺸﺖ‬ ‫رﻗﻢ اﻋﺸﺎر‪ .‬ﻛﻮﭼﻜﺘﺮﻳﻦ ﻋـﺪدي ﻛـﻪ ﻣـﻲ ﺗﻮاﻧـﺪ ﻧﻤـﺎﻳﺶ دﻫـﺪ‬ ‫‪ +) 0/0000000000000000000000000001‬و ‪ (-‬اﺳﺖ‪.‬‬

‫‪double‬‬

‫‪Double‬‬

‫‪ 8‬ﺑﺎﻳﺖ‬

‫از ‪ -1/79769313486231570*E308‬ﺗﺎ‬

‫‪int‬‬

‫‪Int32‬‬

‫‪ 4‬ﺑﺎﻳﺖ‬

‫‪ -2147483648‬ﺗﺎ ‪2147483648‬‬

‫‪long‬‬

‫‪Int64‬‬

‫‪ 8‬ﺑﺎﻳﺖ‬

‫‪ -9223372036854775808‬ﺗﺎ ‪9223372036854775807‬‬

‫‪Object‬‬

‫‪Object‬‬

‫‪ 4‬ﺑﺎﻳﺖ‬

‫ﻫﺮ ﻧﻮع داده اي ﻛﻪ ﺑﺘﻮاﻧـﺪ در ﺷـﻴﺊ اي از ﻧـﻮع ‪Object‬‬ ‫ذﺧﻴﺮه ﺷﻮد‪.‬‬

‫‪sbyte‬‬

‫‪Sbyte‬‬

‫‪ 1‬ﺑﺎﻳﺖ‬

‫‪ -128‬ﺗﺎ ‪128‬‬

‫‪short‬‬

‫‪Int16‬‬

‫‪ 2‬ﺑﺎﻳﺖ‬

‫‪ -32768‬ﺗﺎ ‪32767‬‬

‫‪string‬‬

‫‪String‬‬

‫ﺑــﺴﺘﮕﻲ‬ ‫دارد‬

‫از ‪ 0‬ﺗﺎ ﺗﻘﺮﻳﺒﺎً ‪ 2‬ﺑﻴﻠﻴﻮن ﻛﺎراﻛﺘﺮ ﻳﻮﻧﻴﻜﺪ‬

‫‪ 4/94065645841246544*E-324‬ﺑﺮاي اﻋﺪاد ﻣﻨﻔﻲ و‬ ‫‪ 4/94065645841246544*E-324‬ﺗﺎ‬ ‫‪ 1/79769313486231570*E308‬ﺑﺮاي اﻋﺪاد ﻣﺜﺒﺖ‪.‬‬

‫‪٨٨١‬‬

‫‪uint‬‬

‫‪UInt32‬‬

‫‪ 4‬ﺑﺎﻳﺖ‬

‫‪ 0‬ﺗﺎ ‪ 4294967295‬ﺑﺪون ﻋﻼﻣﺖ‬

‫‪ulong‬‬

‫‪UInt64‬‬

‫‪ 8‬ﺑﺎﻳﺖ‬

‫‪ 0‬ﺗﺎ ‪ 18446744073709551615‬ﺑﺪون ﻋﻼﻣﺖ‬

‫‪ushort‬‬

‫‪UInt16‬‬

‫‪ 2‬ﺑﺎﻳﺖ‬

‫‪ 0‬ﺗﺎ ‪ 65535‬ﺑﺪون ﻋﻼﻣﺖ‬

‫ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ‪:Compact Framework‬‬ ‫ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ در ‪ CF‬وﺟﻮد دارﻧﺪ‪ ،‬زﻳﺮ ﻣﺠﻤﻮﻋﻪ اي از ﻛﻼس ﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ در ﭼﺎرﭼﻮب ‪ .NET‬ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﺷـﺪﻳﻢ ﺑـﻪ ﻫﻤـﺮاه‬ ‫ﺗﻌﺪادي ﻛﻼس دﻳﮕﺮ ﻛﻪ ﻣﻌﻤﻮﻻً در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﺎي ﻋﺎدي از آﻧﻬﺎ اﺳﺘﻔﺎده ﻧﻤﻲ ﺷﻮد‪.‬‬ ‫ﭼﺎرﭼﻮب ‪ CF‬در ﺣﺪود ‪ 12‬درﺻﺪ ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ﭼﺎرﭼﻮب ‪ .NET‬را ﺷﺎﻣﻞ ﻣﻲ ﺷﻮد‪ .‬اﺣﺘﻤﺎﻻً ﺑﺎ ﻫﻤﻴﻦ ﺟﻤﻠﻪ ﻣﺘﻮﺟﻪ ﺷﺪه اﻳﺪ ﻛﻪ‬ ‫ﺗﺎ ﭼﻪ اﻧﺪازه از ﻛﺎراﻳﻲ ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ در ‪ .NET‬وﺟﻮد دارد در ‪ CF‬ﺣﺬف ﺷـﺪه اﺳـﺖ‪ .‬ﺑـﻪ ﺷـﻜﻞ ‪ 1-22‬ﻧﮕـﺎه ﻛﻨﻴـﺪ‪ .‬اﻳـﻦ ﺷـﻜﻞ‬ ‫ﺧﺎﺻﻴﺘﻬﺎي ﻣﺮﺑﻮط ﺑﻪ ﻛﻨﺘﺮل ‪ Label‬در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻣﻌﻤﻮﻟﻲ را ﺑﻪ ﻫﻤﺮاه ﺧﺎﺻﻴﺖ ﻫﺎي ﻣﺮﺑـﻮط ﺑـﻪ ﻛﻨﺘـﺮل ‪ Label‬در ﻳـﻚ‬ ‫ﺑﺮﻧﺎﻣﻪ ي دﺳﺘﮕﺎه ﻫﺎي ﻫﻮﺷﻤﻨﺪ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ‪ .‬ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﻪ ﺑﺴﻴﺎري از ﺧﺎﺻﻴﺖ ﻫﺎي ﻣﻮﺟﻮد ﺣﺬف ﺷﺪه اﻧﺪ و ﻗﺎﺑﻞ اﺳـﺘﻔﺎده‬ ‫ﻧﻴﺴﺘﻨﺪ‪.‬‬

‫‪٨٨٢‬‬

‫ﺷﻜﻞ ‪1-22‬‬ ‫دو ﻗﺴﻤﺖ دﻳﮕﺮ ﻛﻪ در ﻛﻼﺳﻬﺎي ‪ CF‬ﺑﻪ ﺷﺪت ﻛﺎﻫﺶ ﭘﻴﺪا ﻛﺮده اﻧﺪ ﻧﺴﺨﻪ ﻫﺎي ﺳﺮﺑﺎر ﮔﺬاري ﺷﺪه از ﻣﺘﺪ ﻫﺎ و ﻫﻤﭽﻨﻴﻦ روﻳﺪاد ﻫﺎي‬ ‫ﻣﻮﺟﻮد ﺑﺮاي ﻛﻨﺘﺮل ﻫﺎ اﺳﺖ‪ .‬ﺷﻜﻞ ‪ 2-22‬ﻟﻴﺴﺖ روﻳﺪاد ﻫﺎي ﻣﻮﺟﻮد ﺑﺮاي ﻛﻨﺘﺮل ‪ Button‬در ﻫﺮ دو ﻧﻮع ﺑﺮﻧﺎﻣﻪ را ﻧﺸﺎن ﻣﻲ دﻫﺪ‪.‬‬ ‫در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻋﺎدي ﻛﻪ در ﺳﻤﺖ راﺳﺖ ﻧﺸﺎن داده ﺷﺪه اﺳﺖ‪ ،‬ﺗﻌﺪاد روﻳﺪاد ﻫﺎ ﺑﻪ ﺣﺪي اﺳﺖ ﻛﻪ ﻧﻤﻲ ﺗﻮان ﻫﻤﻪ ي آﻧﻬﺎ را در ﻳـﻚ‬ ‫ﺻﻔﺤﻪ ﻣﺸﺎﻫﺪه ﻛﺮد‪ .‬اﻣﺎ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ‪ CF‬ﻛﻪ در ﺳﻤﺖ ﭼﭗ ﻧﺸﺎن داده ﺷﺪه اﺳﺖ ﺗﻌﺪاد روﻳﺪادﻫﺎ ﺑﺴﻴﺎر ﻛﻤﺘﺮ اﺳﺖ‪.‬‬

‫‪٨٨٣‬‬

‫ﺷﻜﻞ ‪2-22‬‬ ‫ﺑﺮ اﺳﺎس اﻧﺪازه ي ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در ‪ CF‬ﻣﻲ ﺗﻮان ﺣﺪس زد ﻛﻪ ﭼﻴﺰي در ﺣﺪود ‪ 75‬درﺻـﺪ ﻧـﺴﺨﻪ ﻫـﺎي ﺳـﺮﺑﺎر ﮔـﺬاري ﺷـﺪه از‬ ‫ﻣﺘﺪﻫﺎي ﻣﺨﺘﻠﻒ ﻧﻴﺰ ﺣﺬف ﺷﺪه اﻧﺪ‪ .‬ﺑﻪ ﻋﻨﻮان ﻣﺜﺎل ﻛـﻼس ‪ System.IO.FileStream‬در ﭼـﺎرﭼﻮب ‪ .NET‬داراي‬ ‫‪ 14‬ﻣﺘﺪ ﺳﺎزﻧﺪه اﺳﺖ‪ ،‬اﻣﺎ اﻳﻦ ﻛﻼس در ‪ CF‬ﻓﻘﻂ ‪ 5‬ﻣﺘﺪ ﺳﺎزﻧﺪه دارد‪.‬‬ ‫در ﻟﻴﺴﺖ زﻳﺮ ﻧﺎم ﺑﻌﻀﻲ از ﻛﻨﺘﺮل ﻫﺎ ﻛﻪ ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض در ‪ CF‬وﺟﻮد دارﻧﺪ و ﻣﻲ ﺗﻮان ﺑﺮاي ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﺳﺘﮕﺎه ﻫـﺎي‬ ‫ﻫﻮﺷﻤﻨﺪ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﺮد را ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ‪:‬‬ ‫ﻧﺎم‬

‫ﻧﺎم‬

‫ﻧﺎم‬

‫ﻧﺎم‬

‫‪Button‬‬

‫‪CheckBox‬‬

‫‪ComboBox‬‬

‫‪ContextMenu‬‬

‫‪DataConnect‬‬ ‫‪or‬‬

‫‪DataGrid‬‬

‫‪DateTimePick‬‬ ‫‪er‬‬

‫‪DocumentList‬‬

‫‪Spiltter‬‬

‫‪DomainUpDown‬‬

‫‪HScrollBar‬‬

‫‪ImageList‬‬

‫‪٨٨٤‬‬

‫‪InputPanel‬‬

‫‪Label‬‬

‫‪LinkLabel‬‬

‫‪ListBox‬‬

‫‪ListView‬‬

‫‪MainMenu‬‬

‫‪MonthCalenda‬‬ ‫‪r‬‬

‫‪Notification‬‬

‫‪NumericUpDo‬‬ ‫‪wn‬‬

‫‪OpenFileDial‬‬ ‫‪og‬‬

‫‪Panel‬‬

‫‪PicturePox‬‬

‫‪ProgressBar‬‬

‫‪RadioButton‬‬

‫‪RichInk‬‬

‫‪SaveFileDial‬‬ ‫‪og‬‬

‫‪StatusBar‬‬

‫‪TabControl‬‬

‫‪TextBox‬‬

‫‪Timer‬‬

‫‪ToolBar‬‬

‫‪TrackBar‬‬

‫‪TreeView‬‬

‫‪VScrollBar‬‬

‫‪WebBrowser‬‬

‫اﻳﺠﺎد ﻳﻚ ﺑﺎزي ﺑﺮاي ‪:Pocket PC‬‬ ‫ﺑﻪ ﻋﻨﻮان اوﻟﻴﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺮاي دﺳﺘﮕﺎه ﻫﺎي ﻫﻮﺷﻤﻨﺪ‪ ،‬در اﻳﻦ ﻗﺴﻤﺖ ﻳﻚ ﺑﺎزي ﺳﺎده ﻃﺮاﺣﻲ ﺧﻮاﻫﻴﻢ ﻛﺮد و ﺳﻌﻲ ﺧـﻮاﻫﻴﻢ ﻛـﺮد در ﻃـﻲ‬ ‫اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﻣﺤﻴﻂ اﻳﻦ ﻧﻮع دﺳﺘﮕﺎه ﻫﺎ و ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ آﻧﻬﺎ ﺑﻴﺸﺘﺮ آﺷﻨﺎ ﺷﻮﻳﻢ‪.‬‬

‫اﻣﺘﺤﺎن ﻛﻨﻴﺪ‪ :‬اﻳﺠﺎد ﻳﻚ ﺑﺎزي‬ ‫‪(1‬‬ ‫‪(2‬‬

‫‪(3‬‬

‫‪(4‬‬

‫در ﻣﺤﻴﻂ وﻳﮋوال اﺳﺘﻮدﻳﻮ ﺑﺎ اﺳﺘﻔﺎده از ﻧﻮار اﺑﺰار ﮔﺰﻳﻨﻪ ي …‪ File  New Project‬را اﻧﺘﺨﺎب ﻛﻨﻴـﺪ‪ .‬ﺑـﻪ‬ ‫اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎدر ‪ New Project‬ﻧﻤﺎﻳﺶ داده ﺧﻮاﻫﺪ ﺷﺪ‪.‬‬ ‫از ﻗـﺴﻤﺖ ﺳـﻤﺖ ﭼـﭗ ﮔﺰﻳﻨـﻪ ي ‪Visual C#  Smart Device  Pocket PC‬‬ ‫‪ 2003‬را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ در ﻗﺴﻤﺖ ﺳﻤﺖ راﺳﺖ روي ﻧﺎم ‪ Device Application‬ﻛﻠﻴﻚ ﻛﻨﻴﺪ‪ .‬ﻧﺎم‬ ‫ﭘﺮوژه را ﺑﺮاﺑﺮ ﺑـﺎ ‪ PocketPC_TicTacToe‬وارد ﻛـﺮده و روي دﻛﻤـﻪ ي ‪ OK‬ﻛﻠﻴـﻚ ﻛﻨﻴـﺪ‪ .‬ﻛـﺎدر ‪New‬‬ ‫‪ Project‬ﺑﺎﻳﺪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ ‪ 3-22‬ﺑﺎﺷﺪ‪.‬‬ ‫ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي دﻛﻤﻪ ي ‪ OK‬ﭘﺮوژه اﻳﺠﺎد ﺷﺪه و ﺻﻔﺤﻪ ي ﻫﻤﺎﻧﻨﺪ ﻳﻚ ‪ Pocket PC‬ﻫﻤﺎﻧﻄﻮر ﻛـﻪ در ﺷـﻜﻞ‬ ‫‪ 6-22‬ﻧﺸﺎن داده ﺷﺪه اﺳﺖ ﻧﻤﺎﻳﺶ داده ﻣﻲ ﺷﻮد‪ .‬اﻳﻦ ﻗﺴﻤﺖ ﻣﺤﻴﻂ ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ اﺳﺖ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ زﻣﺎﻧﻲ ﻛﻪ در ﺣـﺎل‬ ‫اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺴﺘﻴﺪ‪ ،‬ﻣﻲ ﺗﻮاﻧﻴﺪ ﻇﺎﻫﺮ و راﺑﻂ ﮔﺮاﻓﻴﻜﻲ ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد را در ﻣﺤﻴﻄﻲ ﻛﺎﻣﻼً ﻣﺸﺎﺑﻪ ﻣﺸﺎﻫﺪه ﻛﻨﻴـﺪ‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ ﺑـﺎ‬ ‫اﺳﺘﻔﺎده از اﻳﻦ ﻣﺤﻴﻂ ﻣﻲ ﺗﻮاﻧﻴﺪ در ﻫﺮ ﻟﺤﻈﻪ ﻣﺸﺎﻫﺪه ﻛﻨﻴﺪ ﻛﻪ ﻛﺎرﺑﺮ ﭼﻪ ﻣﺤﻴﻄﻲ را ﻣﺸﺎﻫﺪه ﺧﻮاﻫﺪ ﻛﺮد‪.‬‬ ‫ﺑﺮاي اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ اﺑﺘﺪا ﺑﺎﻳﺪ ﻇﺎﻫﺮ آن را ﻃﺮاﺣﻲ ﻛﻨﻴﻢ‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر ‪ 10‬ﻛﻨﺘﺮل ‪ Button‬را ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪ 5-22‬ﺑﻪ ﻓـﺮم‬ ‫ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‪ .‬ﺳﻪ ﺳﻄﺮ ﻛﻪ در ﻫﺮ ﻳﻚ از آﻧﻬﺎ ﺳﻪ ﻛﻨﺘﺮل ‪ Button‬ﻗﺮار دارد‪ ،‬ﻗﺴﻤﺖ اﺻﻠﻲ ﺑـﺎزي را ﺗـﺸﻜﻴﻞ ﻣـﻲ‬ ‫دﻫﻨﺪ‪ .‬ﺧﺎﺻﻴﺖ ‪ Size‬اﻳﻦ ‪ 9‬ﻛﻨﺘﺮل ‪ Button‬را ﺑﺮاﺑﺮ ﺑﺎ ‪ 40;40‬ﻗﺮار دﻫﻴﺪ ﺗﺎ ﻓﺮم ﺑﺮﻧﺎﻣﻪ اﻳﺠـﺎد ﺷـﻮد‪ .‬ﺑـﺮاي ﻧـﺎم‬ ‫ﮔﺬاري ﻛﻨﺘﺮل ﻫﺎ از ﺑﺎﻻ ﺳﻤﺖ ﭼﭗ ﺷﺮوع ﻛﺮده و ﺑﻪ ﺳﻤﺖ راﺳﺖ ﺣﺮﻛﺖ ﻛﻨﻴﺪ ﺗﺎ ردﻳﻒ ﺗﻤﺎم ﺷﻮد‪ .‬ﺳﭙﺲ ﺑـﻪ ردﻳـﻒ ﺑﻌـﺪي‬ ‫ﺑﺮوﻳﺪ و ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴﺐ ردﻳﻒ ﺳﻮم را ﻧﻴـﺰ ﻃـﻲ ﻛﻨﻴـﺪ و ﻧـﺎم ﻛﻨﺘـﺮل ﻫـﺎ را ﺑـﻪ ﺗﺮﺗﻴـﺐ ﺑﺮاﺑـﺮ ﺑـﺎ ‪،btn01 ،btn00‬‬ ‫‪ btn22 ،btn21 ،btn20 ،btn12 ،btn11 ،btn10 ،btn02‬ﻗﺮار دﻫﻴﺪ‪ .‬ﻧـﺎم ﻫـﺎ ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ‬ ‫ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ از ﺳﻪ ﻗﺴﻤﺖ ﺗـﺸﻜﻴﻞ ﺷـﺪه اﺳـﺖ‪ :‬ﻗـﺴﻤﺖ ‪ btn‬ﻛـﻪ ﻣـﺸﺨﺺ ﻣـﻲ ﻛﻨـﺪ ﻛﻨﺘـﺮل ﻣـﻮرد ﻧﻈـﺮ ﻳـﻚ‬

‫‪٨٨٥‬‬

‫‪ Button‬اﺳﺖ‪ ،‬ﻗﺴﻤﺖ ﺷﻤﺎره ردﻳﻒ )‪ 1 ،0‬ﺑﺎ ‪ (2‬و ﻗﺴﻤﺖ ﺷﻤﺎره ﺳـﺘﻮن )‪ 1 ،0‬ﻳـﺎ ‪ .(2‬ﺑﻨـﺎﺑﺮاﻳﻦ ﻛﻨﺘـﺮل ‪ btn02‬در‬ ‫ردﻳﻒ اول )ردﻳﻒ ﺻﻔﺮم( و ﺳﺘﻮن ﺳﻮم )دوﻣﻴﻦ ﺳﺘﻮن( ﻗﺮار دارد‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ زﻣﺎﻧﻲ ﻛﻪ از اﻳﻦ ﻧﺎﻣﻬﺎ در ﻛﺪ ﺑﺮﻧﺎﻣﻪ اﺳـﺘﻔﺎده‬ ‫ﻛﻨﻴﺪ‪ ،‬ﻣﻲ داﻧﻴﺪ ﻛﻪ در ﺣﺎل ﻛﺎر ﺑﺎ ﻛﺪام ﻛﻨﺘﺮل ‪ Button‬در ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﻫﺴﺘﻴﺪ‪.‬‬

‫ﺷﻜﻞ ‪3-22‬‬ ‫ﺳﭙﺲ ﺧﺎﺻﻴﺖ ‪ Font‬ﺗﻤﺎم اﻳﻦ ﻛﻨﺘﺮل ﻫﺎ را ﺑﺮاﺑﺮ ﺑـﺎ ‪ Tahoma, 24PT, Bold‬ﻗـﺮار دﻫﻴـﺪ‪ .‬در آﺧـﺮ ﻧﻴـﺰ‬ ‫ﺧﺎﺻﻴﺖ ‪ Text‬ﺗﻤﺎم آﻧﻬﺎ را ﺑﺮاﺑﺮ ﺑﺎ ‪ X‬و ﺧﺎﺻﻴﺖ ‪ Anchor‬را ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑـﺎ ‪ None‬ﻗـﺮار دﻫﻴـﺪ‪ .‬دﻛﻤـﻪ ي آﺧـﺮ در‬ ‫ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﻣﺮﺑﻮط ﺑﻪ ‪ New Game‬اﺳﺖ‪ .‬ﺧﺎﺻﻴﺖ ‪ Name‬اﻳﻦ ﻛﻨﺘـﺮل را ﺑﺮاﺑـﺮ ﺑـﺎ ‪ btnNewGame‬و ﺧﺎﺻـﻴﺖ‬ ‫‪ Text‬آن را ﺑﺮاﺑﺮ ﺑﺎ ‪ &New Game‬ﻗﺮار دﻫﻴﺪ‪ .‬در ﭘﺎﻳﻴﻦ ‪ 9‬دﻛﻤﻪ ي ﻣﺮﺑﻮط ﺑﻪ ﺑﺎزي ﻧﻴﺰ ﻳﻚ ﻛﻨﺘﺮل ‪ Label‬ﻗﺮار‬ ‫داده و ﺧﺎﺻﻴﺖ ‪ Name‬آن را ﺑﺎ ﻣﻘﺪار ‪ lblMessage‬ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ‪ .‬اﻧﺪازه ي ﻛﻨﺘﺮل ‪ Label‬را ﻧﻴﺰ ﺑـﻪ ﮔﻮﻧـﻪ اي‬ ‫ﺗﻨﻈﻴﻢ ﻛﻨﻴﺪ ﺗﺎ ﺑﺘﻮاﻧﺪ دو ﺧﻂ ﻣﺘﻦ را ﻧﻤﺎﻳﺶ دﻫﺪ‪ .‬ﺣﺎل ﺑﺮاي ﺗﻜﻤﻴﻞ ﻇﺎﻫﺮ ﺑﺮﻧﺎﻣـﻪ‪ ،‬ﺧﺎﺻـﻴﺖ ‪ Text‬ﻓـﺮم را ﻧﻴـﺰ ﺑﺮاﺑـﺮ ﺑـﺎ‬ ‫‪ Tic Tac Toe‬ﻗﺮار دﻫﻴﺪ‪.‬‬ ‫‪ (5‬ﺑﺮ روي ﻛﻨﺘﺮل ‪ btn00‬دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑـﻪ روﻳـﺪاد ‪ Click‬اﻳـﻦ ﻛﻨﺘـﺮل اﻳﺠـﺎد ﺷـﻮد‪ .‬ﺳـﭙﺲ ﻛـﺪ‬ ‫ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳﻦ ﻣﺘﺪ وارد ﻛﻨﻴﺪ‪:‬‬ ‫)‪private void btn00_Click(object sender, EventArgs e‬‬ ‫{‬ ‫;)‪CorrectEnabledState(false‬‬ ‫‪Application.DoEvents(); // Allows the screen to refresh‬‬ ‫;"‪((Button)sender).Text = "X‬‬

‫‪٨٨٦‬‬

if(IsGameOver()) MessageBox.Show("Game Over"); else { lblMessage.Text = "Computer selecting ..."; Application.DoEvents(); // Allows the screen to refresh ComputerPlay(); if(IsGameOver()) MessageBox.Show("Game Over"); else { lblMessage.Text = "Select your next position ..."; CorrectEnabledState(); } } }

4-22 ‫ﺷﻜﻞ‬

٨٨٧

‫ﺷﻜﻞ ‪5-22‬‬ ‫‪ (6‬ﻛﻨﺘﺮل ‪ btn01‬را از ﻓﺮم اﻧﺘﺨﺎب ﻛﺮده و در ﭘﻨﺠﺮه ي ‪ Properties‬روي آﻳﻜﻮن ‪ Events‬ﻛﻠﻴﻚ ﻛﺮده ﺗـﺎ‬ ‫ﻟﻴﺴﺖ روﻳﺪادﻫﺎي ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻛﻨﺘﺮل ﻧﻤﺎﻳﺶ داده ﺷﻮد‪ .‬ﺳﭙﺲ از اﻳﻦ ﻟﻴﺴﺖ روﻳـﺪاد ‪ Click‬را اﻧﺘﺨـﺎب ﻛـﺮده و روي‬ ‫ﻣﺜﻠﺚ آﺑﻲ رﻧﮓ ﻣﻘﺎﺑﻞ آن ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻟﻴﺴﺖ ﻣﺘﺪ ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﺮاي اﻳﻦ روﻳﺪاد اﻧﺘﺨﺎب ﺷـﻮﻧﺪ ﻧﻤـﺎﻳﺶ داده ﺷـﻮد‪.‬‬ ‫ﻣﺸﺎﻫﺪه ﺧﻮاﻫﻴﺪ ﻛﺮد ﻛﻪ اﻳﻦ ﻟﻴﺴﺖ ﻓﻘﻂ ﺷﺎﻣﻞ ﻳﻚ ﻣﺘﺪ ﺑﻪ ﻧﺎم ‪ btn00_Click‬اﺳـﺖ ﻛـﻪ در ﻗـﺴﻤﺖ ﻗﺒـﻞ ﺑـﺮاي‬ ‫روﻳﺪاد ‪ Click‬ﻛﻨﺘﺮل ‪ btn00‬اﻳﺠﺎد ﻛﺮده ﺑﻮدﻳﻢ‪ .‬اﻳﻦ ﻣﺘﺪ را اﻧﺘﺨﺎب ﻛﻨﻴﺪ‪ .‬ﺳﭙﺲ ﻫﻤﻴﻦ ﻣﺮاﺣﻞ را ﺑﺮاي ﻫﻔﺖ ﻛﻨﺘﺮل‬ ‫‪ Button‬ﺑﺎﻗﻲ ﻣﺎﻧﺪه )ﻛﻨﺘﺮﻟﻬﺎي ‪ btn02‬ﺗﺎ ‪ (btn22‬ﺗﻜﺮار ﻛﻨﻴﺪ‪.‬‬ ‫‪ (7‬در ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﻧﺎﻣﻪ دﻛﻤﻪ ي ‪ F7‬را ﻓﺸﺎر داده ﺗﺎ وارد ﻗﺴﻤﺖ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻛﻼس ‪ Form1‬ﺷﻮﻳﺪ‪ .‬ﺳﭙﺲ ﻛـﺪ‬ ‫ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را در اﻳﻦ ﻛﻼس وارد ﻛﻨﻴﺪ‪:‬‬ ‫‪// Get the game ready to start again‬‬ ‫)(‪void ResetGame‬‬ ‫{‬ ‫"" ‪// Loop through the board controls and set them to‬‬

‫‪٨٨٨‬‬

foreach(Control ctrl in this.Controls) { if(ctrl.GetType() == typeof(Button) && ctrl.Name != "btnNewGame") { ctrl.Text = String.Empty; } } lblMessage.Text = String.Empty; //Enable the board buttons CorrectEnabledState(true); } private void CorrectEnabledState(Boolean ButtonEnabledState) { foreach(Control ctrl in this.Controls) { if(ctrl.GetType() == typeof(Button) && ctrl.Name != "btnNewGame") { ctrl.Enabled = ButtonEnabledState; } } } private void CorrectEnabledState() { foreach(Control ctrl in this.Controls) { if(ctrl.GetType() == typeof(Button) && ctrl.Name != "btnNewGame") { if(ctrl.Text == String.Empty) ctrl.Enabled = true; else ctrl.Enabled = false; } } } void ComputerPlay() { Random RandomGenerator = new Random(); int intRandom; int intCount = 0; intRandom = RandomGenerator.Next(20, 100); while (intCount < intRandom) { foreach (Control ctrl in this.Controls) { if (ctrl.GetType() == typeof(Button) && ctrl.Name != "btnNewGame") { if (ctrl.Text == String.Empty) {

٨٨٩

intCount += 1; if (intCount == intRandom) { ctrl.Text = "O"; ctrl.Enabled = false; break; } } } } } } void Winner(String strWinner) { String strMessage; if(strWinner == "X") strMessage = "You win!!"; else if(strWinner == "O") strMessage = "Computer wins!!"; else strMessage = strWinner; lblMessage.Text = strMessage; } Boolean IsGameOver() { if(btn00.Text == btn01.Text && btn01.Text btn02.Text != String.Empty ) { // Winner on top Row Winner(btn00.Text); return true; } if(btn10.Text == btn11.Text && btn11.Text btn12.Text != String.Empty ) { // Winner on middle Row Winner(btn10.Text); return true; } if(btn20.Text == btn21.Text && btn21.Text btn22.Text != String.Empty) { // Winner on bottom Row Winner(btn20.Text); return true; } if(btn00.Text == btn10.Text && btn10.Text btn20.Text != String.Empty) { // Winner on first column Winner(btn00.Text); return true; } if(btn01.Text == btn11.Text && btn11.Text

٨٩٠

== btn02.Text &&

== btn12.Text &&

== btn22.Text &&

== btn20.Text &&

== btn21.Text &&

btn21.Text != String.Empty) { // Winner on second column Winner(btn01.Text); return true; } if(btn02.Text == btn12.Text && btn12.Text == btn22.Text && btn22.Text != String.Empty) { // Winner on third column Winner(btn02.Text); return true; } if(btn00.Text == btn11.Text && btn11.Text == btn22.Text && btn22.Text != String.Empty) { // Winner on diagonal top left to bottom right Winner(btn00.Text); return true; } if(btn20.Text == btn11.Text && btn11.Text == btn02.Text && btn02.Text != String.Empty) { // Winner on diagonal bottom left to top right Winner(btn20.Text); return true; } // Test for a tie, all square full int intOpenings = 0; foreach(Control ctrl in this.Controls) { if(ctrl.GetType() == typeof(Button) && ctrl.Name != "btnNewGame") if(ctrl.Text == String.Empty) intOpenings = intOpenings + 1; } if(intOpenings == 0) { Winner("It’s a tie."); return true; } return false; }

‫ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗـﺎ ﻣﺘـﺪ ﻣﺮﺑـﻮط ﺑـﻪ روﻳـﺪاد‬btnNewGame ‫( ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﻧﺎﻣﻪ ﺑﺮﮔﺸﺘﻪ و روي ﻛﻨﺘﺮل‬8 :‫ ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ آن اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬.‫ اﻳﻦ ﻛﻨﺘﺮل اﻳﺠﺎد ﺷﻮد‬Click private void btnNewGame_Click(object sender, EventArgs e) { ResetGame(); }

.‫ آن اﻳﺠﺎد ﺷﻮد‬Load ‫( ﻣﺠﺪداً ﺑﻪ ﻗﺴﻤﺖ ﻃﺮاﺣﻲ ﻓﺮم ﺑﺮﮔﺸﺘﻪ و روي ﻓﺮم ﺑﺮﻧﺎﻣﻪ دو ﺑﺎر ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺗﺎ ﻣﺘﺪ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد‬9 :‫ﺳﭙﺲ ﻛﺪ ﻣﺸﺨﺺ ﺷﺪه در زﻳﺮ را ﺑﻪ اﻳﻦ ﻣﺘﺪ اﺿﺎﻓﻪ ﻛﻨﻴﺪ‬

٨٩١

‫)‪private void Form1_Load(object sender, EventArgs e‬‬ ‫{‬ ‫;)‪CorrectEnabledState(false‬‬ ‫;"‪lblMessage.Text = "Click new game to begin.‬‬ ‫}‬

‫‪ (10‬ﻛﻠﻴﺪ ‪ F5‬را ﻓﺸﺎر دﻫﻴﺪ ﺗﺎ ﺑﺮﻧﺎﻣﻪ اﺟﺮا ﺷﻮد و ﺑﺘﻮاﻧﻴﻢ ﻋﻤﻠﻜﺮد آن را ﺗﺴﺖ ﻛﻨـﻴﻢ‪ .‬ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ اﺑﺘـﺪا ﻛـﺎدر ‪Deploy‬‬ ‫ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ ‪ 6-22‬ﻧﺸﺎن داده ﻣﻲ ﺷﻮد و از ﺷﻤﺎ ﻣﻲ ﺧﻮاﻫﺪ ﻛﻪ ﭼﮕﻮﻧﮕﻲ ﺗﻮزﻳﻊ اﻳﻦ ﺑﺮﻧﺎﻣﻪ را ﻣﺸﺨﺺ ﻛﻨﻴﺪ‪ .‬از اﻳﻦ ﻟﻴـﺴﺖ‬ ‫‪ Pocket PC 2003 SE Emulator‬را ﻣﺸﺨﺺ ﻛﺮده و دﻛﻤﻪ ي ‪ Deploy‬را ﻓﺸﺎر دﻫﻴـﺪ‪ .‬ﺑﺎﻳـﺪ‬ ‫ﻣﻘﺪاري ﺻﺒﺮ ﻛﻨﻴﺪ ﺗﺎ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ آﻏﺎز ﺷﻮد‪.‬‬

‫ﺷﻜﻞ ‪6-22‬‬ ‫‪ (11‬ﺑﺎ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻳﻚ ﺷﺒﻴﻪ ﺳﺎز ‪ Pocket PC‬ﻧﺸﺎن داده ﺷﺪه و ﺑﺮﻧﺎﻣﻪ ي ﺷﻤﺎ ﻧﻴﺰ در آن اﺟﺮا ﻣـﻲ ﺷـﻮد‪ .‬ﺑـﺮاي آﻏـﺎز‬ ‫ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﻣﻘﺪاري ﺻﺒﺮ ﻛﻨﻴﺪ‪.‬‬ ‫‪ (12‬ﺑﺎ اﺟﺮا ﺷﺪن ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ روي دﻛﻤﻪ ي ‪ New Game‬ﻛﻠﻴﻚ ﻛﺮده و در ﻣﻘﺎﺑﻞ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﺎزي ﻛﻨﻴﺪ‪ .‬اﻟﺒﺘـﻪ ﺷﻜـﺴﺖ‬ ‫دادن اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﺴﻴﺎر ﺳﺎده اﺳﺖ‪ ،‬زﻳﺮا اﻋﺪاد ﺧﻮد را ﺑﻪ ﺻﻮرت ﺗﺼﺎدﻓﻲ اﻧﺘﺨﺎب ﻣﻲ ﻛﻨﺪ‪.‬‬

‫ﭼﮕﻮﻧﻪ ﻛﺎر ﻣﻲ ﻛﻨﺪ؟‬ ‫ﺑﺎ ﺗﻜﻤﻴﻞ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﻘﺪاري ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺮاي دﺳﺘﮕﺎه ﻫﺎي ﻫﻮﺷﻤﻨﺪ آﺷﻨﺎ ﺷﺪﻳﺪ و ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻧﻴﺰ ﺗﻔﺎوت‬ ‫ﭼﻨﺪاﻧﻲ ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ در ﻓﺼﻮل ﻗﺒﻠﻲ ﻣﻲ ﻧﻮﺷﺘﻴﻢ ﻧﺪارد‪ .‬اوﻟﻴﻦ ﻣﻮردي ﻛﻪ در اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻤﻜﻦ اﺳـﺖ ﺗﻮﺟـﻪ ﺷـﻤﺎ را ﺟﻠـﺐ‬ ‫ﻛﺮده ﺑﺎﺷﺪ‪ ،‬اﻧﺪازه ي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ اﺳﺖ‪ .‬ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ اﻳﻦ دﺳﺘﮕﺎه ﻫﺎ ﺑﺴﻴﺎر ﻣﺤﺪود اﺳﺖ‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎ در آن ﻛﻤـﻲ‬ ‫ﻣﺸﻜﻞ ﺗﺮ از ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﻌﻤﻮﻟﻲ اﺳﺖ‪.‬‬ ‫در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻋﺎدي دﻳﮕﺮ‪ ،‬از ﻃﺮاﺣﻲ ﻇﺎﻫﺮ و راﺑﻂ ﺑﺮﻧﺎﻣﻪ ﺷﺮوع ﻛﺮده و ﻛﻨﺘﺮﻟﻬـﺎي ﻣـﻮرد ﻧﻴـﺎز را در ﻓـﺮم ﻗـﺮار‬ ‫دادﻳﻢ‪ .‬ﺑﺎ ﺗﻤﺎم ﺧﺎﺻﻴﺖ ﻫﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﺮدﻳﻢ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي وﻳﻨﺪوزي ﻗﺒﻠﻲ آﺷﻨﺎ ﺷﺪه اﻳـﺪ‪ ،‬ﺑﻨـﺎﺑﺮاﻳﻦ ﻧﺒﺎﻳـﺪ در‬ ‫ﻃﺮاﺣﻲ راﺑﻂ ﮔﺮاﻓﻴﻜﻲ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻣﺸﻜﻠﻲ داﺷﺘﻪ ﺑﺎﺷﻴﺪ‪.‬‬

‫‪٨٩٢‬‬

‫در اﻳﻦ ﺑﺮﻧﺎﻣﻪ اﻏﻠﺐ ﻛﺎرﻫﺎ ﺑﻪ وﺳﻴﻠﻪ ي ﻛﺪ اﻧﺠﺎم ﻣﻲ ﺷﻮد و ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ ﻛﺪي ﻫﻢ ﻛﻪ ﺑﺮاي اﻳﻦ ﻛﺎرﻫـﺎ ﻧﻮﺷـﺘﻪ اﻳـﻢ‪،‬‬ ‫ﻣﺸﺎﺑﻪ ﻛﺪي اﺳﺖ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺒﻠﻲ در اﻳﻦ ﻛﺘﺎب اﺳﺘﻔﺎده ﻣﻲ ﻛﺮدﻳﻢ‪ .‬اﻳﻦ ﻛﺪ از ﭼﻨﺪﻳﻦ ﺗﺎﺑﻊ و ﭼﻨﺪﻳﻦ زﻳﺮ ﺑﺮﻧﺎﻣـﻪ ﺗـﺸﻜﻴﻞ ﺷـﺪه‬ ‫اﺳﺖ ﻛﻪ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻳﻜﺪﻳﮕﺮ در ﻣﻮاﻗﻊ ﻟﺰوم‪ ،‬ﻛﺎرﻫﺎي ﻻزم را در ﺑﺮﻧﺎﻣﻪ اﻧﺠﺎم ﻧﻤﻲ دﻫﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ در ﻓﻬﻢ ﻛﺪ ﺑﺮﻧﺎﻣﻪ ﻧﻴـﺰ ﻧﺒﺎﻳـﺪ ﻣـﺸﻜﻠﻲ‬ ‫داﺷﺘﻪ ﺑﺎﺷﻴﺪ‪ .‬در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺰ ﻣﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻗﺒﻠﻲ از اﺑﺘﺪا ﺷﺮوع ﻛﺮده و ﻣﺘﺪ ﻫﺎ را ﻳﻜﻲ ﻳﻜـﻲ ﺑﺮرﺳـﻲ ﻣـﻲ ﻛﻨـﻴﻢ ﺗـﺎ ﺑـﺎ ﻧﺤـﻮه ي‬ ‫ﻋﻤﻠﻜﺮد ﺑﺮﻧﺎﻣﻪ ﺑﻬﺘﺮ آﺷﻨﺎ ﺷﻮﻳﻢ‪.‬‬ ‫ﻗﺒﻞ از ﺷﺮوع ﻫﺮ ﺑﺎزي و ﻳﺎ ﺑﻌﺪ از اﻳﻨﻜﻪ ﻫﺮ ﺑﺎزي ﺑﻪ اﺗﻤﺎم رﺳﻴﺪ‪ ،‬ﺑﻪ روﺷﻲ ﻧﻴﺎز دارﻳﺪ ﻛﻪ ﺑﺘﻮاﻧﻴﺪ ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻓﺮم را ﺑﺮاي ﻣﺮﺗﺒـﻪ‬ ‫ي ﺑﻌﺪي آﻣﺎده ﻛﻨﻴﺪ‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر ﻣﺘﺪي ﺑﻪ ﻧﺎم ‪ ResetGame‬اﻳﺠﺎد ﻣـﻲ ﻛﻨـﻴﻢ‪ .‬وﻇﻴﻔـﻪ ي اﻳـﻦ ﻣﺘـﺪ اﻳـﻦ اﺳـﺖ ﻛـﻪ در ﺑـﻴﻦ‬ ‫ﻛﻨﺘﺮﻟﻬﺎي ﻣﻮﺟﻮد در ﻓﺮم ﺣﺮﻛﺖ ﻛﺮده و اﮔﺮ ﻧﻮع ﻛﻨﺘﺮل ﺑﺮاﺑﺮ ﺑﺎ ‪ Button‬ﺑﻮده و ﻧﻴﺰ ﺟﺰﺋﻲ از دﻛﻤـﻪ ﻫـﺎي ﻣﺮﺑـﻮط ﺑـﻪ ﺑـﺎزي ﺑـﻮد‪،‬‬ ‫ﺧﺎﺻﻴﺖ ‪ Text‬آن را ﺑﺮاﺑﺮ ﺑﺎ رﺷﺘﻪ ي ﺗﻬﻲ )‪ (String.Empty‬ﻗـﺮار دﻫـﺪ‪ .‬ﺑﻌـﺪ از اﻳﻨﻜـﻪ ﻣـﺘﻦ روي ﺗﻤـﺎم ﻛﻨﺘـﺮل ﻫـﺎي‬ ‫‪ Button‬را ﺗﻨﻈﻴﻢ ﻛﺮد‪ ،‬ﺧﺎﺻﻴﺖ ‪ Text‬ﻛﻨﺘﺮل ‪ Label‬را ﻧﻴﺰ ﭘﺎك ﻛﺮده و ﺳﭙﺲ ﺗﻤـﺎم ﻛﻨﺘﺮﻟﻬـﺎي ‪ Button‬ﻣﻮﺟـﻮد در‬ ‫ﻓﺮم را ﻓﻌﺎل ﻛﻨﺪ‪.‬‬ ‫‪// Get the game ready to start again‬‬ ‫)(‪void ResetGame‬‬ ‫{‬ ‫"" ‪// Loop through the board controls and set them to‬‬ ‫)‪foreach(Control ctrl in this.Controls‬‬ ‫{‬ ‫&& )‪if(ctrl.GetType() == typeof(Button‬‬ ‫)"‪ctrl.Name != "btnNewGame‬‬ ‫{‬ ‫;‪ctrl.Text = String.Empty‬‬ ‫}‬ ‫}‬ ‫;‪lblMessage.Text = String.Empty‬‬ ‫‪//Enable the board buttons‬‬ ‫;)‪CorrectEnabledState(true‬‬ ‫}‬

‫ﺳﭙﺲ دو ﻧﺴﺨﻪ ي ﻣﺨﺘﻠﻒ از ﻣﺘﺪ ‪ CorrectEnabledState‬اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﺑﺮاي ﻓﺮاﺧﻮاﻧﻲ اﻳـﻦ ﻣﺘـﺪ از‬ ‫ﻳﻚ ﭘﺎراﻣﺘﺮ ‪ Boolean‬اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ ،‬اﻳﻦ ﻣﺘﺪ ﺧﺎﺻﻴﺖ ‪ Enabled‬ﺗﻤﺎم ‪ 9‬ﻛﻨﺘﺮل ‪ Button‬ﻣﺮﺑﻮط ﺑـﻪ ﺑـﺎزي را ﺑﺮاﺑـﺮ ﺑـﺎ‬ ‫ﭘﺎراﻣﺘﺮ ﻣﺸﺨﺺ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي ﺷﻤﺎ ﻗﺮار ﻣﻲ دﻫﺪ‪ .‬ﻣﺘﺪ دﻳﮕﺮ ﭘﺎراﻣﺘﺮي درﻳﺎﻓﺖ ﻧﻤﻲ ﻛﻨﺪ‪ ،‬ﺑﻠﻜﻪ در ﺑﻴﻦ دﻛﻤﻪ ﻫﺎي ﻣﺮﺑـﻮط ﺑـﻪ ﺑـﺎزي‬ ‫ﺣﺮﻛﺖ ﻣﻲ ﻛﻨﺪ‪ .‬اﮔﺮ ﺧﺎﺻﻴﺖ ‪ Text‬اﻳﻦ دﻛﻤﻪ ﻫـﺎ ﺑﺮاﺑـﺮ ﺑـﺎ ‪ String.Empty‬ﺑـﻮد ﻣﻘـﺪار ‪ Enabled‬آن را ﺑﺮاﺑـﺮ ﺑـﺎ‬ ‫‪ true‬ﻗﺮار داده‪ ،‬در ﻏﻴﺮ اﻳﻦ ﺻﻮرت اﻳﻦ ﻣﻘﺪار را ﺑﺮاﺑﺮ ﺑﺎ ‪ False‬ﻗﺮار ﻣﻲ دﻫﺪ‪.‬‬ ‫)‪private void CorrectEnabledState(Boolean ButtonEnabledState‬‬ ‫{‬ ‫)‪foreach(Control ctrl in this.Controls‬‬ ‫{‬ ‫&& )‪if(ctrl.GetType() == typeof(Button‬‬ ‫)"‪ctrl.Name != "btnNewGame‬‬ ‫{‬ ‫;‪ctrl.Enabled = ButtonEnabledState‬‬ ‫}‬ ‫}‬ ‫}‬

‫‪٨٩٣‬‬

‫)(‪private void CorrectEnabledState‬‬ ‫{‬ ‫)‪foreach(Control ctrl in this.Controls‬‬ ‫{‬ ‫&& )‪if(ctrl.GetType() == typeof(Button‬‬ ‫)"‪ctrl.Name != "btnNewGame‬‬ ‫{‬ ‫)‪if(ctrl.Text == String.Empty‬‬ ‫;‪ctrl.Enabled = true‬‬ ‫‪else‬‬ ‫;‪ctrl.Enabled = false‬‬ ‫}‬ ‫}‬ ‫}‬

‫ﻳﻚ ﻣﺘﺪ دﻳﮕﺮ ﻧﻴﺰ ﺑﻪ ﻧﺎم ‪ ComputerPlay‬در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻣﻲ ﻛﻨﻴﻢ‪ .‬اﻳﻦ ﻣﺘﺪ وﻇﻴﻔﻪ دارد ﺗﺎ ﺑﻪ ﻋﻨﻮان ﻛﺎﻣﭙﻴﻮﺗﺮ در ﻣﻘﺎﺑﻞ ﺷﻤﺎ‬ ‫ﺑﺎزي ﻛﻨﺪ‪ .‬در اﺑﺘﺪاي اﻳﻦ ﻣﺘﺪ ﻣﺘﻐﻴﺮﻫﺎي ﻻزم را ﺗﻌﺮﻳﻒ ﻣﻲ ﻛﻨﻴﻢ‪ ،‬اﻣﺎ ﻋﻤﻠﻜﺮد اﺻﻠﻲ ﻣﺘﺪ از ﺧﻂ ﻗﺒﻞ از ﺣﻠﻘﻪ ي ‪ while‬ﺷﺮوع ﻣـﻲ‬ ‫ﺷﻮد‪ .‬در اﻳﻦ ﺧﻂ ﺑﺎ اﺳﺘﻔﺎده از ﻣﺘﺪ ‪ Next‬در ﻛﻼس ‪ Random‬ﻳﻚ ﻋﺪد ﺗﺼﺎدﻓﻲ ﺑﻴﻦ ‪ 20‬ﺗﺎ ‪ 100‬ﺗﻮﻟﻴﺪ ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ ﺑﺎ‬ ‫اﺳﺘﻔﺎده از ﻳﻚ ﺣﻠﻘﻪ در ﺑﻴﻦ ﻣﺮﺑﻊ ﻫﺎي ﺧﺎﻟﻲ ﺻﻔﺤﻪ ﺣﺮﻛﺖ ﻣﻲ ﻛﻨﺪ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﺑﻪ اﻧﺪازه ي ﻋﺪد ﺗﺼﺎدﻓﻲ ﺗﻮﻟﻴـﺪ ﺷـﺪه از روي ﻣﺮﺑـﻊ‬ ‫ﻫﺎي ﺧﺎﻟﻲ ﻋﺒﻮر ﻛﻨﺪ‪ .‬ﺑﻌﺪ از اﻳﻦ ﻛﺎر اوﻟﻴﻦ ﻣﺮﺑﻊ ﺧﺎﻟﻲ را ﺑﺎ ﻋﻼﻣﺖ ‪ O‬ﭘﺮ ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫)(‪void ComputerPlay‬‬ ‫{‬ ‫;)(‪Random RandomGenerator = new Random‬‬ ‫;‪int intRandom‬‬ ‫;‪int intCount = 0‬‬ ‫;)‪intRandom = RandomGenerator.Next(20, 100‬‬ ‫)‪while (intCount < intRandom‬‬ ‫{‬ ‫)‪foreach (Control ctrl in this.Controls‬‬ ‫{‬ ‫&& )‪if (ctrl.GetType() == typeof(Button‬‬ ‫)"‪ctrl.Name != "btnNewGame‬‬ ‫{‬ ‫)‪if (ctrl.Text == String.Empty‬‬ ‫{‬ ‫;‪intCount += 1‬‬ ‫)‪if (intCount == intRandom‬‬ ‫{‬ ‫;"‪ctrl.Text = "O‬‬ ‫;‪ctrl.Enabled = false‬‬ ‫;‪break‬‬ ‫}‬ ‫}‬ ‫}‬ ‫}‬ ‫}‬ ‫}‬

‫ﺑﺎ ﻛﻠﻴﻚ روي ﻫﺮ ﻳﻚ از ﻣﺮﺑﻊ ﻫﺎي ﻣﻮﺟﻮد در ﺻﻔﺤﻪ‪ ،‬ﻣﺘﺪ ‪ btn00_Click‬ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد‪ ،‬زﻳﺮا ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﻓﺮم روﻳﺪاد‬ ‫‪ Click‬دﻳﮕﺮ ﻛﻨﺘﺮل ﻫﺎ را ﻧﻴﺰ ﺑﺮاﺑﺮ ﺑﺎ اﻳﻦ ﻣﺘﺪ ﻗﺮار دادﻳﻢ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ ﻛﻠﻴﻚ ﻛﺮدن روي ﻫﺮ ﻛﺪام از اﻳﻦ ﻣﺮﺑﻊ ﻫﺎ در ﻓﺮم ﻫﻤﻴﻦ ﻣﺘـﺪ‬

‫‪٨٩٤‬‬

‫ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد‪ .‬اﻳﻦ ﻣﺘﺪ اﺑﺘﺪا ﺗﻤﺎم ﻣﺮﺑـﻊ ﻫـﺎي درون ﺑـﺎزي را ﻏﻴـﺮ ﻓﻌـﺎل ﻣـﻲ ﻛـﺮده و ﺳـﭙﺲ ﻣﺘـﺪ ‪ DoEvents‬از ﻛـﻼس‬ ‫‪ Application‬را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ ﺗﺎ ﺑﺮﻧﺎﻣﻪ ﺑﺘﻮاﻧﺪ ﺗﻤﺎم روﻳﺪادﻫﺎي ﻓﺮاﺧﻮاﻧﻲ ﺷﺪه را ﺑﻪ اﺗﻤﺎم ﺑﺮﺳﺎﻧﺪ‪ .‬ﺑـﺎ اﻧﺠـﺎم اﻳـﻦ ﻛـﺎر از‬ ‫ﻛﻠﻴﻚ ﻛﺮدن ﻛﺎرﺑﺮ روي دو دﻛﻤﻪ‪ ،‬ﻗﺒﻞ از اﻳﻨﻜﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺣﺮﻛﺘﻲ را اﻧﺠﺎم دﻫﺪ ﺟﻠﻮﮔﻴﺮي ﺧﻮاﻫﻴﻢ ﻛﺮد‪ .‬اﮔﺮ اﻳﻦ ﺧﻄﻮط را ﺣـﺬف ﻛﻨﻴـﺪ‪،‬‬ ‫ﻫﻨﮕﺎم ﺑﺎزي ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻪ ﺳﺮﻋﺖ روي ﺳﻪ دﻛﻤﻪ ﻛﻠﻴﻚ ﻛﻨﻴﺪ ﺑﺪون اﻳﻨﻜﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﺘﻮاﻧﺪ اﻧﺘﺨﺎﺑﻲ را اﻧﺠﺎم دﻫـﺪ و ﺑـﻪ اﻳـﻦ ﺗﺮﺗﻴـﺐ ﺑـﻪ‬ ‫ﺳﺎدﮔﻲ ﺑﺎزي را ﺑﺒﺮﻳﺪ‪ .‬ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﭘﺎراﻣﺘﺮ ‪ sender‬ﻛﻨﺘﺮﻟﻲ ﻛﻪ ﺑﺎﻋﺚ ﺷﺪه اﺳﺖ اﻳﻦ ﻣﺘﺪ ﻓﺮاﺧـﻮاﻧﻲ ﺷـﻮد را ﺑﺪﺳـﺖ آورده و‬ ‫آن را ﺑﻪ ﺷﻴﺊ اي از ﻧﻮع ‪ Button‬ﺗﺒﺪﻳﻞ ﻣﻲ ﻛﻨﻴﻢ‪ ،‬زﻳﺮا ﻫﻢ اﻛﻨﻮن اﻳﻦ ﺷﻴﺊ از ﻧﻮع ‪ Object‬اﺳﺖ‪ .‬ﺳﭙﺲ ﺧﺎﺻـﻴﺖ ‪Text‬‬ ‫اﻳﻦ ﻛﻨﺘﺮل را ﺑﺎ ﻣﻘﺪار ‪ X‬ﺗﻨﻈﻴﻢ ﻣﻲ ﻛﻨﻴﻢ‪ .‬ﺑﻌﺪ از اﻳﻨﻜﻪ اﻧﺘﺨﺎب ﺷﻤﺎ ﺻﻮرت ﮔﺮﻓﺖ‪ ،‬ﺻﻔﺤﻪ ﺑﺮاي اﻳﻨﻜﻪ ﻣﺸﺨﺺ ﺷﻮد آﻳﺎ ﺑﺮﻧﺪه اي وﺟﻮد‬ ‫دارد ﻳﺎ ﻧﻪ ﺑﺮرﺳﻲ ﺧﻮاﻫﺪ ﺷﺪ‪ .‬اﮔﺮ ﺑﺮﻧﺪه اي وﺟﻮد ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ‪ ،‬ﻛﺎﻣﭙﻴﻮﺗﺮ اﻧﺘﺨﺎﺑﻲ را اﻧﺠﺎم ﺧﻮاﻫﺪ داد و ﻣﺠـﺪداً ﺻـﻔﺤﻪ ﺑـﺮاي ﻣـﺸﺨﺺ‬ ‫ﺷﺪن ﺑﺮﻧﺪه ﺑﺮرﺳﻲ ﻣﻲ ﺷﻮد‪ .‬در ﺻﻮرت ﻛﻪ ﺑﺎز ﻫﻢ ﺑﺮﻧﺪه اي ﻧﺪاﺷﺘﻪ ﺑﺎﺷﻴﻢ‪ ،‬ﺑﻪ ﺷﻤﺎ اﺟﺎزه داده ﻣﻲ ﺷﻮد ﺗﺎ روي دﻛﻤﻪ اي دﻳﮕـﺮ ﻛﻠﻴـﻚ‬ ‫ﻛﻨﻴﺪ‪:‬‬ ‫)‪private void btn00_Click(object sender, EventArgs e‬‬ ‫{‬ ‫;)‪CorrectEnabledState(false‬‬ ‫‪Application.DoEvents(); // Allows the screen to refresh‬‬ ‫;"‪((Button)sender).Text = "X‬‬ ‫))(‪if(IsGameOver‬‬ ‫;)"‪MessageBox.Show("Game Over‬‬ ‫‪else‬‬ ‫{‬ ‫;"‪lblMessage.Text = "Computer selecting ...‬‬ ‫‪Application.DoEvents(); // Allows the screen to refresh‬‬ ‫;)(‪ComputerPlay‬‬ ‫))(‪if(IsGameOver‬‬ ‫;)"‪MessageBox.Show("Game Over‬‬ ‫‪else‬‬ ‫{‬ ‫;"‪lblMessage.Text = "Select your next position ...‬‬ ‫;)(‪CorrectEnabledState‬‬ ‫}‬ ‫}‬ ‫}‬

‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻳﻜﻲ از ﻃﺮﻓﻴﻦ ﺑﻪ ﻋﻨﻮان ﺑﺮﻧﺪه ﻣﺸﺨﺺ ﺷﺪ‪ ،‬ﻣﺘﺪ ‪ Winner‬ﻓﺮاﺧﻮاﻧﻲ ﺷﺪه و ﻣﺘﻦ ﻣﻨﺎﺳﺒﻲ در ﺻﻔﺤﻪ ﻧﻤـﺎﻳﺶ داده ﻣـﻲ‬ ‫ﺷﻮد‪:‬‬ ‫)‪void Winner(String strWinner‬‬ ‫{‬ ‫;‪String strMessage‬‬ ‫)"‪if(strWinner == "X‬‬ ‫;"!!‪strMessage = "You win‬‬ ‫)"‪else if(strWinner == "O‬‬ ‫;"!!‪strMessage = "Computer wins‬‬ ‫‪else‬‬ ‫;‪strMessage = strWinner‬‬ ‫;‪lblMessage.Text = strMessage‬‬ ‫}‬

‫‪٨٩٥‬‬

‫ ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد ﺗﺎ ﻣﺸﺨﺺ ﺷﻮد ﻛﻪ آﻳﺎ ﺑﺮﻧﺪه اي ﺑﻪ وﺟـﻮد آﻣـﺪه‬IsGameOver ‫ ﻣﺘﺪ‬،‫ﺑﻌﺪ از اﻳﻨﻜﻪ ﻫﺮ ﺣﺮﻛﺖ ﺻﻮرت ﮔﺮﻓﺖ‬ ‫ اﮔـﺮ ﺳـﻪ ﻣﺮﺑـﻊ‬.‫ در اﻳﻦ ﻣﺘﺪ ﺗﻤﺎم ﺣﺎﻟﺘﻬﺎﻳﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺎﻋﺚ ﺑﺮﻧﺪه ﺷﺪن ﻫﺮ ﻳﻚ از ﺑﺎزي ﻛﻨﻨﺪﮔﺎن ﺷﻮد ﺑﺮرﺳﻲ ﻣﻲ ﺷـﻮد‬.‫اﺳﺖ ﻳﺎ ﻧﻪ‬ ‫ ﺑﻪ ﻋﻨﻮان ﻧﺘﻴﺠﻪ ي ﺗـﺎﺑﻊ ﺑﺮﮔـﺸﺘﻪ‬true ‫ ﻓﺮاﺧﻮاﻧﻲ ﺷﺪه و ﻣﻘﺪار‬Winner ‫ ﻣﺘﺪ‬،‫ﻣﺘﻮاﻟﻲ ﺑﻪ دﻧﺒﺎل ﻫﻢ ﺑﺮاي ﻳﻚ ﻃﺮف ﺑﺎزي ﺑﺎﺷﻨﺪ‬ ‫ ﻣﺘﺪ ﻣﺮﺑﻊ ﻫﺎي ﻣﻮﺟﻮد در ﺑﺎزي را ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﺪ ﺗﺎ ﻣﺸﺨﺺ ﺷﻮد آﻳﺎ ﺑﺎزي ﺗﻤﺎم ﺷﺪه اﺳـﺖ ﻳـﺎ‬،‫ اﮔﺮ ﻫﻴﭻ ﺑﺮﻧﺪه اي ﭘﻴﺪا ﻧﺸﻮد‬.‫ﻣﻲ ﺷﻮد‬ .‫ ﺑﺎزي ﻣﺴﺎوي اﻋﻼم ﻣﻲ ﺷﻮد‬،‫ اﮔﺮ ﺗﻤﺎم ﻣﺮﺑﻊ ﻫﺎ ﭘﺮ ﺷﺪه ﺑﻮد‬.‫ﻧﻪ‬ Boolean IsGameOver() { if(btn00.Text == btn01.Text && btn01.Text == btn02.Text btn02.Text != String.Empty ) { // Winner on top Row Winner(btn00.Text); return true; } if(btn10.Text == btn11.Text && btn11.Text == btn12.Text btn12.Text != String.Empty ) { // Winner on middle Row Winner(btn10.Text); return true; } if(btn20.Text == btn21.Text && btn21.Text == btn22.Text btn22.Text != String.Empty) { // Winner on bottom Row Winner(btn20.Text); return true; } if(btn00.Text == btn10.Text && btn10.Text == btn20.Text btn20.Text != String.Empty) { // Winner on first column Winner(btn00.Text); return true; } if(btn01.Text == btn11.Text && btn11.Text == btn21.Text btn21.Text != String.Empty) { // Winner on second column Winner(btn01.Text); return true; } if(btn02.Text == btn12.Text && btn12.Text == btn22.Text btn22.Text != String.Empty) { // Winner on third column Winner(btn02.Text); return true; } if(btn00.Text == btn11.Text && btn11.Text == btn22.Text btn22.Text != String.Empty) { // Winner on diagonal top left to bottom right

٨٩٦

&&

&&

&&

&&

&&

&&

&&

Winner(btn00.Text); return true; } if(btn20.Text == btn11.Text && btn11.Text == btn02.Text && btn02.Text != String.Empty) { // Winner on diagonal bottom left to top right Winner(btn20.Text); return true; } // Test for a tie, all square full int intOpenings = 0; foreach(Control ctrl in this.Controls) { if(ctrl.GetType() == typeof(Button) && ctrl.Name != "btnNewGame") if(ctrl.Text == String.Empty) intOpenings = intOpenings + 1; } if(intOpenings == 0) { Winner("It’s a tie."); return true; } return false; }

btnNewGame ‫ ﻛﻨﺘـﺮل‬Click ‫ ﻓـﺮم و روﻳـﺪاد‬Load ‫ﺑﻘﻴﻪ ي ﻛﺪي ﻛﻪ در اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻮﺷﺘﻪ ﺷﺪه اﺳﺖ ﻣﺮﺑﻮط ﺑﻪ روﻳﺪاد‬ ‫ ﺗﻤﺎم دﻛﻤﻪ ﻫﺎي ﺑـﺎزي را ﻏﻴـﺮ‬CorrectEnabledState ‫ ﺑﺎ ﻓﺮاﺧﻮاﻧﻲ ﻣﺘﺪ‬،‫ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﺮم ﺑﺎر ﮔﺬاري ﻣﻲ ﺷﻮد‬.‫اﺳﺖ‬ ‫ اﻳـﻦ دﻛﻤـﻪ ﻧﻴـﺰ ﻣﺘـﺪ‬.‫ ﻛﻠﻴﻚ ﻛﻨﺪ‬New Game ‫ ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺎرﺑﺮ ﺑﺮاي ﺷﺮوع ﺑﺎزي ﻣﺠﺒﻮر اﺳﺖ روي دﻛﻤﻪ ي‬.‫ﻓﻌﺎل ﻣﻲ ﻛﻨﻴﻢ‬ .‫ را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ ﺗﺎ ﺑﺎزي آﻏﺎز ﺷﻮد‬ResetGame private void btnNewGame_Click(object sender, EventArgs e) { ResetGame(); } private void Form1_Load(object sender, EventArgs e) { CorrectEnabledState(false); lblMessage.Text = "Click new game to begin."; }

:‫ﻧﺘﻴﺠﻪ‬ ‫ ﺑﺎﻋﺚ ﺷﺪه اﺳﺖ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺮاي دﺳﺘﮕﺎه ﻫﺎي ﻫﻮﺷـﻤﻨﺪ‬Compact Framework ‫ ﺑﻪ ﻫﻤﺮاه‬2005 ‫وﻳﮋوال اﺳﺘﻮدﻳﻮ‬ ‫ ﻳﻜﻲ از دﻻﻳﻠﻲ ﻫﻢ ﻛﻪ ﺑﺎﻋﺚ ﺷﺪه اﺳـﺖ ﺳﻴـﺴﺘﻢ ﻋﺎﻣـﻞ وﻳﻨـﺪوز ﺑـﻴﺶ از دﻳﮕـﺮ‬.‫ﺗﺎ ﺣﺪ زﻳﺎدي ﻣﺸﺎﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺗﺤﺖ وﻳﻨﺪوز ﺑﺎﺷﺪ‬ ‫ اﺳﺘﻔﺎده ﺷﻮد در اﻳﻦ اﺳﺖ ﻛﻪ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﺮاي اﻳﻦ ﺳﻴﺴﺘﻢ‬PDA ‫ﺳﻴﺴﺘﻢ ﻋﺎﻣﻠﻬﺎ ﺑﺮاي دﺳﺘﮕﺎه ﻫﺎي‬ .‫ﻋﺎﻣﻞ ﺑﺴﻴﺎر ﺳﺎده اﺳﺖ‬

٨٩٧

‫ﺑﻪ ﻋﻼوه ﮔﺴﺘﺮش روز اﻓﺰون اﺳﺘﻔﺎده از اﻳﻦ ﻧﻮع دﺳﺘﮕﺎه ﻫﺎ ﺑﻪ ﻫﻤﺮاه ﺳﺎدﮔﻲ ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﺑﺮاي آﻧﻬﺎ ﺑﺎﻋﺚ ﺷﺪه اﺳﺖ ﻛـﻪ ﺷـﺮﻛﺘﻬﺎي‬ ‫ﻧﺮم اﻓﺰاري روز ﺑﻪ روز ﺑﻴﺸﺘﺮ ﺗﻤﺎﻳﻞ داﺷﺘﻪ ﺑﺎﺷﻨﺪ ﻛﻪ از اﻓﺮادي ﻣﺴﻠﻂ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﻮﺑﺎﻳﻞ اﺳـﺘﻔﺎده ﻛﻨﻨـﺪ‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ ﺑﻬﺘـﺮ اﺳـﺖ ﺑـﺎ‬ ‫ﻳﺎدﮔﻴﺮي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﻮﺑﺎﻳﻞ‪ ،‬از ﺗﻮاﻧﺎﻳﻲ ﻫﺎي ﺧﻮد را در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ روز ﺑﻪ روز ﺑﻴﺸﺘﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬ ‫در اﻳﻦ ﻓﺼﻞ ﺑﺎ ﻣﺒﺎﻧﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﻮﺑﺎﻳﻞ آﺷﻨﺎ ﺷﺪﻳﻢ‪ .‬ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ در اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ از ﭼﻪ ﭼﺎرﭼﻮﺑﻲ اﺳﺘﻔﺎده ﻣﻲ ﺷـﻮد‬ ‫و ﺗﻔﺎوت و ﺷﺒﺎﻫﺖ اﻳﻦ ﭼﺎرﭼﻮب ﺑﺎ ﭼﺎرﭼﻮب ‪ .NET‬در ﭼﻴﺴﺖ؟ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻛﻪ ﭼﻪ ﻛﻼﺳﻬﺎ و ﻣﺘﺪ ﻫﺎي در ‪ CF‬ﺣﺬف ﺷﺪه اﻧﺪ ﺗﺎ‬ ‫اﻳﻦ ﭼﺎرﭼﻮب ﺗﻮاﻧﺴﺘﻪ اﺳﺖ ﺑﺎ ﺣﺠﻤﻲ در ﺣﺪود ‪ 20‬درﺻﺪ ﭼﺎرﭼﻮب ‪ .NET‬ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد‪ .‬در اﻧﺘﻬﺎي ﻓـﺼﻞ ﻧﻴـﺰ ﺑـﻪ ﻋﻨـﻮان‬ ‫ﺗﻤﺮﻳﻦ ﻳﻚ ﺑﺎزي ﺑﺮاي ﻣﻮﺑﺎﻳﻞ اﻳﺠﺎد ﻛﺮدﻳﻢ‪.‬‬ ‫در ﭘﺎﻳﺎن اﻳﻦ ﻓﻴﻞ ﺑﺎﻳﺪ ﺑﺎ ﻣﻮارد زﻳﺮ آﺷﻨﺎ ﺷﺪه ﺑﺎﺷﻴﺪ‪:‬‬ ‫‬ ‫‬ ‫‬ ‫‬

‫ﺗﻔﺎوت ﻫﺎي ﺑﻴﻦ ﻧﺴﺨﻪ ي ﻛﺎﻣﻞ ﭼـﺎرﭼﻮب ‪ .NET‬و ﻧﻴـﺰ ﭼـﺎرﭼﻮب ‪ .NET Compact Framework‬را‬ ‫درك ﻛﻨﻴﺪ‪.‬‬ ‫ﺑﺎ اﺳﺘﻔﺎده از ‪ ActiveSync‬ﻳﻚ دﺳﺘﮕﺎه ‪ PDA‬را ﺑﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺷﺨﺼﻲ ﺧﻮد ﻣﺘﺼﻞ ﻛﻨﻴﺪ‪.‬‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﺑﺮاي دﺳﺘﮕﺎه ﻫﺎي ﻣﻮﺑﺎﻳﻞ و ﻫﻮﺷﻤﻨﺪ ﻃﺮاﺣﻲ ﻛﻨﻴﺪ‪.‬‬ ‫ﺑﺎ اﺳﺘﻔﺎده از ﺷﺒﻴﻪ ﺳﺎز دروﻧﻲ وﻳﮋوال اﺳﺘﻮدﻳﻮ‪ ،‬ﻋﻤﻠﻜﺮد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺧﻮد را ﺗﺴﺖ ﻛﻨﻴﺪ‪.‬‬

‫ﺗﻤﺮﻳﻦ‪:‬‬ ‫در ﺑﺎزي ﻛﻪ در اﻳﻦ ﻓﺼﻞ اﻳﺠﺎد ﻛﺮدﻳﻢ‪ ،‬ﻛﺎﻣﭙﻴﻮﺗﺮ ﻳﻚ ﺧﺎﻧﻪ ي ﺗﺼﺎدﻓﻲ را اﻧﺘﺨﺎب ﻛﺮده و آن را ﭘﺮ ﻣـﻲ ﻛﻨـﺪ‪ .‬ﺑـﺮاي اﻳـﻦ ﺗﻤـﺮﻳﻦ ﻣـﻲ‬ ‫ﺧـــﻮاﻫﻴﻢ ﺑﺮﻧﺎﻣـــﻪ را ﺑـــﻪ ﮔﻮﻧـــﻪ اي ﺗﻐﻴﻴـــﺮ دﻫـــﻴﻢ ﺗـــﺎ ﻛـــﺎﻣﭙﻴﻮﺗﺮ ﻣﻘـــﺪاري ﻫﻮﺷـــﻤﻨﺪاﻧﻪ ﺗـــﺮ ﻋﻤـــﻞ ﻛﻨـــﺪ‪ .‬ﻣﺘـــﺪي ﺑـــﻪ ﻧـــﺎم‬ ‫‪ ComputerPlayToWin‬را ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻛﺮده و زﻣﺎﻧﻲ ﻛﻪ ﻧﻮﺑﺖ ﺣﺮﻛﺖ ﺑﻪ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﻲ رﺳـﺪ‪ ،‬آن را ﻓﺮاﺧـﻮاﻧﻲ ﻛﻨﻴـﺪ‪.‬‬ ‫اﻳﻦ ﻣﺘﺪ را ﺑﻪ ﮔﻮﻧﻪ اي ﺑﻨﻮﻳﺴﻴﺪ ﺗﺎ ﻛﺎﻣﭙﻴﻮﺗﺮ ﺑﺘﻮاﻧﺪ ﺑﺎ اﺳﺘﻔﺎده از آن در ﺑﺎزي ﭘﻴﺮوز ﺷﻮد‪.‬‬

‫‪٨٩٨‬‬

‫ﺿﻤﻴﻤﻪ ي ‪ :1‬اداﻣﻪ ي ﻣﺴﻴﺮ‬ ‫ﺣﺎل ﻛﻪ ﺗﻮاﻧﺴﺘﻪ اﻳﺪ ﻣﻄﺎﻟﺐ اﻳﻦ ﻛﺘﺎب را ﺑﺎ ﻣﻮﻓﻘﻴﺖ ﭘﺸﺖ ﺳﺮ ﺑﮕﺬارﻳﺪ‪ ،‬ﺑﺎﻳﺪ درك ﺧﻮﺑﻲ از ﻧﺤﻮه ي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺎ اﺳﺘﻔﺎده از وﻳـﮋوال‬ ‫‪ C#‬ﺑﺪﺳﺖ آورده ﺑﺎﺷﻴﺪ‪ .‬در ﺗﻤﺎم ﻣﺜﺎل ﻫﺎ‪ ،‬ﺑﺮﻧﺎﻣﻪ ﻫﺎ و ﺗﻤﺮﻳﻦ ﻫﺎﻳﻲ ﻛﻪ در ﻃﻲ اﻳﻦ ﻛﺘﺎب ﺑﺮرﺳﻲ ﻛﺮدﻳﻢ ﺳﻌﻲ داﺷﺘﻴﻢ ﻛﻪ ﺑﺘﻮاﻧﻴﻢ ﭘﺎﻳـﻪ‬ ‫اي ﻗﻮي در ﻣﻮرد ﻧﺤﻮه ي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ در ﺷﻤﺎ اﻳﺠﺎد ﻛﻨﻴﻢ‪ ،‬اﻣﺎ ﺗﻤﺎم اﻳﻦ ﻣﻮارد ﻛﻪ ﻣﺸﺎﻫﺪه ﻛﺮدﻳﺪ ﻓﻘﻂ آﻏﺎز ﻣﺴﻴﺮ ﺑﻮدﻧـﺪ‪ .‬در ﺣﻘﻴﻘـﺖ‬ ‫اﻳﻦ ﻛﺘﺎب ﻳﻜﻲ از ﭼﻨﺪﻳﻦ ﻛﺘﺎﺑﻲ اﺳﺖ ﻛﻪ ﺑﺎﻳﺪ ﻣﻄﺎﻟﻌﻪ ﻛﻨﻴﺪ ﺗﺎ ﺑﺘﻮاﻧﻴﺪ ﺑﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻣﺴﻠﻂ در وﻳﮋوال ‪ C#‬ﺗﺒﺪﻳﻞ ﺷﻮﻳﺪ‪ .‬ﺑﺎ وﺟـﻮد‬ ‫اﻳﻨﻜﻪ ﺗﺎﻛﻨﻮن راه زﻳﺎدي را ﻃﻲ ﻛﺮده اﻳﺪ‪ ،‬اﻣﺎ ﻫﻨﻮز ﻣﺴﻴﺮ ﺑﺴﻴﺎر ﻃﻮﻻﻧﻲ را در ﭘﻴﺶ دارﻳﺪ‪ ،‬و اﺣﺘﻤﺎﻻً ﺑﺎﻳﺪ در اﻳـﻦ ﻣـﺴﻴﺮ ﭘﺎﺳـﺦ ﺳـﻮاﻻت‬ ‫زﻳﺎدي را درك ﻛﻨﻴﺪ‪.‬‬ ‫اﻣﺎ ﻣﻬﻤﺘﺮﻳﻦ ﺳﻮاﻟﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎ آن ﻣﻮاﺟﻪ ﻫﺴﺘﻴﺪ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﻌﺪ از اﻳﻦ ﻛﺘﺎب ﭼﮕﻮﻧﻪ ﺑﺎﻳﺪ ﻣﺴﻴﺮ ﺧﻮد را اداﻣﻪ دﻫﻴﺪ‪ ،‬و ﻳـﺎ ﺑـﻪ‬ ‫ﺑﻴﺎن ﺳﺎده ﺗﺮ "ﺑﻌﺪ از اﺗﻤﺎم اﻳﻦ ﻛﺘﺎب ﭼﻪ ﻛﺎر ﺑﺎﻳﺪ ﻛﺮد؟"‪.‬‬ ‫در اﻳﻦ ﺿﻤﻴﻤﻪ ﺳﻌﻲ ﻣﻲ ﻛﻨﻢ ﻣﺴﻴﺮ ﻫﺎﻳﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ ﺑﻌﺪ از اﺗﻤﺎم اﻳﻦ ﻛﺘﺎب اداﻣﻪ دﻫﻴﺪ را ﺑﻴﺎن ﻛﻨﻢ‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺣﺪس‬ ‫زده ﺑﺎﺷﻴﺪ ﺑﻌﺪ از اﻳﻦ ﻛﺘﺎب ﻣﺴﻴﺮ ﻫﺎي ﮔﻮﻧﺎﮔﻮﻧﻲ وﺟﻮد دارﻧﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ در آﻧﻬﺎ ﺑﻪ ﻣﻄﺎﻟﻌﻪ ﺑﭙﺮدازﻳﺪ‪ ،‬و اﻳﻦ ﻛﻪ ﭼـﻪ ﻣـﺴﻴﺮي را اداﻣـﻪ‬ ‫دﻫﻴﺪ ﺑﻪ ﺷﻤﺎ ﺑﺴﺘﮕﻲ دارد و اﻳﻨﻜﻪ ﺑﺨﻮاﻫﻴﺪ در آﻳﻨﺪه ﺑﺎ ﺗﺨﺼﺺ در ﭼﻪ زﻣﻴﻨﻪ اي ﺑﻪ ﻛﺎر ﻣﺸﻐﻮل ﺷـﻮﻳﺪ‪ .‬ﻣﻤﻜـﻦ اﺳـﺖ ﺑﻌـﻀﻲ از اﻓـﺮاد‬ ‫ﺑﺨﻮاﻫﻨﺪ در زﻣﻴﻨﻪ ي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ وﻳﮋوال ‪ C#‬ﺗﺨﺼﺺ ﺑﻴﺸﺘﺮي ﻛﺴﺐ ﻛﻨﻨﺪ و اﻃﻼﻋﺎت ﻣﺨﺘﺼﺮي ﻫﻢ در زﻣﻴﻨﻪ ﻫﺎي دﻳﮕـﺮ ﺑﺪﺳـﺖ‬ ‫آورﻧﺪ‪ ،‬ﺑﻌﻀﻲ دﻳﮕﺮ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻨﺪ در زﻣﻴﻨﻪ ي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺗﺤﺖ ﺷﺒﻜﻪ و اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺒﺘﻨﻲ ﺑﺮ وب ﻓﻌﺎﻟﻴﺖ ﻛﻨﻨﺪ‪ ،‬ﺑﻌﻀﻲ‬ ‫از اﻓﺮاد ﺑﺨﻮاﻫﻨﺪ ﺑﺮ روي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﮔﺮاﻓﻴﻜﻲ ﺗﻤﺮﻛﺰ ﻛﻨﻨﺪ و ‪....‬‬ ‫ﺧﻮب‪ ،‬اوﻟﻴﻦ ﻧﻜﺘﻪ و ﻣﻬﻤﺘﺮﻳﻦ ﻧﻜﺘﻪ ي ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎﻳﺪ ﺗﻮﺟﻪ داﺷﺖ در اﻳﻦ اﺳﺖ ﻛﻪ ﺑﻌﺪ از اﺗﻤﺎم اﻳﻦ ﻛﺘﺎب‪ ،‬زﻳﺎد ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ‬ ‫ﻓﺎﺻﻠﻪ ﻧﮕﻴﺮﻳﺪ‪ .‬اﮔﺮ ﻣﺪت زﻣﺎن ﻃﻮﻻﻧﻲ ﺑﮕﺬرد و از وﻳﮋوال ‪ C#‬اﺳﺘﻔﺎده ﻧﻜﻨﻴﺪ‪ ،‬ﺑﻪ زودي ﺗﻤﺎم ﻣﻄﺎﻟﺒﻲ ﻛﻪ در اﻳﻦ ﻛﺘـﺎب آﻣﻮﺧﺘـﻪ اﻳـﺪ را‬ ‫ﻓﺮاﻣﻮش ﺧﻮاﻫﻴﺪ ﻛﺮد‪ .‬ﺗﻨﻬﺎ راه ﺟﻠﻮﮔﻴﺮي از اﻳﻦ ﻓﺮاﻣﻮﺷﻲ ﺗﻤﺮﻳﻦ در ﻣﻮرد ﻣﻄﺎﻟﺒﻲ اﺳﺖ ﻛﻪ ﺧﻮاﻧﺪه اﻳﺪ‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر ﭼﻨﺪﻳﻦ روش وﺟﻮد‬ ‫دارد‪:‬‬ ‫‬

‫‬ ‫‬

‫‬ ‫‬

‫‬

‫ﻣﺜﺎﻟﻬﺎ و ﺗﻤﺮﻳﻦ ﻫﺎﻳﻲ ﻛﻪ در ﻃﻲ ﻓﺼﻠﻬﺎي اﻳﻦ ﻛﺘﺎب ﺑﺮرﺳﻲ ﺷﺪﻧﺪ را اداﻣﻪ دﻫﻴﺪ‪ .‬ﺳﻌﻲ ﻛﻨﻴﺪ وﻳﮋﮔﻲ ﻫﺎي ﺑﻴﺸﺘﺮي را ﺑﻪ اﻳـﻦ‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﺿﺎﻓﻪ ﻛﻨﻴﺪ و آﻧﻬﺎ را ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﮔﺴﺘﺮش دﻫﻴﺪ‪ .‬ﺣﺘﻲ در ﺻﻮرت اﻣﻜﺎن ﺳﻌﻲ ﻛﻨﻴﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻓـﺼﻮل ﻣﺨﺘﻠـﻒ‬ ‫اﻳﻦ ﻛﺘﺎب را ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﺗﺮﻛﻴﺐ ﻛﺮده و ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻛﺎﻣﻠﺘﺮ اﻳﺠﺎد ﻛﻨﻴﺪ‪.‬‬ ‫ﻣﻤﻜﻦ اﺳﺖ اﻳﺪه ي ﺟﺪﻳﺪي در ﻣﻮرد ﻧﺤﻮه ي ﻧﻮﺷﺘﻦ ﻳﻜﻲ از ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛﺘﺎب داﺷﺘﻪ ﺑﺎﺷﻴﺪ‪ .‬ﺧﻮب‪ ،‬ﺑﺮوﻳﺪ و آن ﺑﺮﻧﺎﻣﻪ را ﺑﻪ‬ ‫ﺻﻮرﺗﻲ ﻛﻪ در ﻧﻈﺮ دارﻳﺪ ﺑﻨﻮﻳﺴﻴﺪ‪.‬‬ ‫ﺳﻌﻲ ﻛﻨﻴﺪ اﺻﻄﻼﺣﺎت و ﻣﻔﺎﻫﻴﻤﻲ ﻛﻪ در ﻃﻲ ﻛﺘﺎب ﺑﺎ آﻧﻬﺎ آﺷﻨﺎ ﺷﺪﻳﻢ را ﺑﻪ دﻗﺖ درك ﻛﻨﻴﺪ‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر ﺣﺘـﻲ اﮔـﺮ ﻻزم‬ ‫اﺳﺖ‪ ،‬ﻳﻚ ﺑﺎر دﻳﮕﺮ ﻛﺘﺎب را از اﺑﺘﺪا ﺑﺨﻮاﻧﻴﺪ‪ .‬اﻳﻦ ﻛﺎر ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﺗﺎ ﻗﺴﻤﺘﻬﺎﻳﻲ از ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ در اﺑﺘﺪاي ﻛﺘﺎب اﻳﺠـﺎد‬ ‫ﻣﻲ ﻛﺮدﻳﻢ و در آن زﻣﺎن درك درﺳﺘﻲ از آﻧﻬﺎ ﻧﺪاﺷﺘﻴﺪ را ﺑﻬﺘﺮ ﻣﺘﻮﺟﻪ ﺷﻮﻳﺪ‪.‬‬ ‫ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ ﺑﻪ ﺧﻮاﻧﺪن ﻣﻘﺎﻻت ﻣﺨﺘﻠﻒ در اﻳﻦ زﻣﻴﻨﻪ ﺑﭙﺮدازﻳﺪ‪ ،‬ﺣﺘﻲ اﮔﺮ در اﺑﺘﺪا ﻣﻄﺎﻟﺐ زﻳﺎدي از آﻧﻬﺎ ﻣﺘﻮﺟﻪ ﻧﻤﻲ ﺷﻮﻳﺪ‪ .‬اﻣﺎ‬ ‫ﺑﻌﺪ از ﻣﺪﺗﻲ ﻣﻔﻬﻮم اﻏﻠﺐ آﻧﻬﺎ را درك ﺧﻮاﻫﻴﺪ ﻛﺮد‪.‬‬ ‫ﺳﻌﻲ ﻛﻨﻴﺪ در ﻣﻮرد ﻣﻄﺎﻟﺒﻲ ﻛﻪ ﺧﻮاﻧﺪه اﻳﺪ ﺑﺎ اﻓﺮاد دﻳﮕﺮ ﺻﺤﺒﺖ ﻛﻨﻴﺪ‪ .‬اﮔﺮ دوﺳﺘﺎﻧﻲ دارﻳﺪ ﻛﻪ در اﻳﻦ زﻣﻴﻨﻪ ﻓﻌﺎﻟﻴﺖ ﻣﻲ ﻛﻨﻨﺪ‪،‬‬ ‫ﺑﺎ آﻧﻬﺎ ﺻﺤﺒﺖ ﻛﺮده و ﺳﻮاﻻت ﺧﻮد را از آﻧﻬﺎ ﺑﭙﺮﺳﻴﺪ‪ .‬اﮔﺮ ﻫﻢ ﻓﺮدي را در اﻳﻦ زﻣﻴﻨﻪ ﻧﻤﻲ ﺷﻨﺎﺳـﻴﺪ‪ ،‬ﺳـﻌﻲ ﻛﻨﻴـﺪ از ﺻـﺤﺒﺖ‬ ‫ﻛﺮدن ﺑﺎ اﻓﺮادي ﻛﻪ در اﻳﻨﺘﺮﻧﺖ ﻫﺴﺘﻨﺪ و در اﻳﻦ زﻣﻴﻨﻪ ﻓﻌﺎﻟﻴﺖ ﻣﻲ ﻛﻨﻨـﺪ اﺳـﺘﻔﺎده ﻛﻨﻴـﺪ‪ .‬ﻓـﻮروم ﻫـﺎ و ﺳـﺎﻳﺘﻬﺎي ﻓﺎرﺳـﻲ و‬ ‫اﻧﮕﻠﻴﺴﻲ ﺑﺴﻴﺎري در اﻳﻦ ﻣﻮرد وﺟﻮد دارﻧﺪ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻴﺪ از آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬ ‫از ﺳﺎﻳﺘﻬﺎﻳﻲ ﻛﻪ در اداﻣﻪ ي اﻳﻦ ﺑﺨﺶ ﻧﺎم ﺑﺮده ﺷﺪه اﻧﺪ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪.‬‬

‫‪٨٩٩‬‬

‫در اداﻣﻪ ي اﻳﻦ ﺿﻤﻴﻤﻪ ﺑﻪ ﻣﻌﺮﻓﻲ ﻣﻨﺎﺑﻊ آﻧﻼﻳﻦ و آﻓﻼﻳﻦ ﻣﻮﺟﻮد در اﻳﻦ زﻣﻴﻨﻪ ﺧﻮاﻫﻴﻢ ﭘﺮداﺧﺖ ﺗﺎ راﺣﺖ ﺗﺮ ﺑﺘﻮاﻧﻴﺪ ﺗﺼﻤﻴﻢ ﺑﮕﻴﺮﻳـﺪ ﻛـﻪ‬ ‫ﺑﻌﺪ از اﺗﻤﺎم اﻳﻦ ﻛﺘﺎب ﭼﮕﻮﻧﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ را اداﻣﻪ دﻫﻴﺪ‪.‬‬

‫ﻣﻨﺎﺑﻊ آﻧﻼﻳﻦ‪:‬‬ ‫اﺳﺎﺳﺎ ﭼﻨﺪﻳﻦ ﻫﺰار ﺳﺎﻳﺖ در اﻳﻨﺘﺮﻧﺖ وﺟﻮد دارﻧﺪ ﻛﻪ در اﻳﻦ زﻣﻴﻨﻪ ﻣﻄﺎﻟﺒﻲ را اراﻳﻪ ﻣﻲ دﻫﻨﺪ و ﻣﻲ ﺗﻮاﻧﻴﺪ از آﻧﻬﺎ ﺑﺮاي رﻓﻊ ﻣﺸﻜﻼت ﺧﻮد‬ ‫اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪ .‬ﻫﺮ زﻣﺎن ﻛﻪ ﺑﻪ ﻣﺸﻜﻠﻲ در اﻳﻦ زﻣﻴﻨﻪ ﺑﺮﺧﻮرد ﻛﺮدﻳﺪ‪ ،‬ﻣﻄﻤﺌﻦ ﺑﺎﺷﻴﺪ اﻓﺮاد ﺑﺴﻴﺎري در اﻳﻨﺘﺮﻧﺖ وﺟﻮد دارﻧﺪ ﻛﻪ ﺑﻪ ﺷﻤﺎ ﺑﺮاي‬ ‫ﺣﻞ ﻣﺸﻜﻠﺘﺎن ﻛﻤﻚ ﺧﻮاﻫﻨﺪ ﻛﺮد‪ .‬اﻳﻦ اﻓﺮاد ﻧﺎﺷﻨﺎﺧﺘﻪ ﻣﻤﻜﻦ اﺳﺖ اﻓﺮاد ﻣﺒﺘﺪي ﻣﺎﻧﻨﺪ ﺷﻤﺎ ﺑﺎﺷﻨﺪ ﻛﻪ ﺑـﺎ ﻣـﺸﻜﻠﻲ ﻫﻤﺎﻧﻨـﺪ ﻣـﺸﻜﻞ ﺷـﻤﺎ‬ ‫ﺑﺮﺧﻮرد ﻛﺮده ﺑﺎﺷﻨﺪ‪ ،‬و ﻳﺎ اﻓﺮاد ﺣﺮﻓﻪ اي و ﻣﺘﺨﺼﺼﻲ ﺑﺎﺷﻨﺪ ﻛﻪ از ﺳﻄﺢ اﻃﻼﻋﺎت ﺑﺎﻻﻳﻲ ﺑﺮﺧـﻮردار ﺑﺎﺷـﻨﺪ‪ .‬اﻳـﻦ ﻣـﺴﺌﻠﻪ ﭼﻴـﺰ ﻋﺠﻴﺒـﻲ‬ ‫ﻧﻴﺴﺖ‪ .‬ﻛﺎﻓﻲ اﺳﺖ درك ﻛﻨﻴﺪ ﻛﻪ ﻫﺮ ﻓﺮدي در ﻫﺮ ﻣﺮﺣﻠﻪ اي ﻣﻲ ﺗﻮاﻧﺪ ﻳﻚ ﻣﺒﺘﺪي ﺑﺮاي ﻣﺮاﺣﻞ ﺑﺎﻻﺗﺮ ﺑـﻪ ﺷـﻤﺎر رود و ﻫﻤﭽﻨـﻴﻦ ﻫـﺮ‬ ‫ﻓﺮدي ﻣﻲ ﺗﻮاﻧﺪ ﺑﺮاي ﻣﺮاﺣﻞ ﻗﺒﻞ از ﺧﻮد ﺑﻪ ﻋﻨﻮان ﻳﻚ ﻣﺘﺨﺼﺺ ﺟﻠﻮه ﻛﻨﺪ‪ .‬ﺣﺘﻲ ﺧﻮد ﺷﻤﺎ ﻧﻴﺰ ﻣﻲ ﺗﻮاﻧﻴﺪ در اﻳﻦ ﻧﻮع ﺳﺎﻳﺘﻬﺎ ﺑﻪ ﻛﻤـﻚ‬ ‫اﻓﺮادي ﻛﻪ ﺗﺨﺼﺺ ﻛﻤﺘﺮي ﻧﺴﺒﺖ ﺑﻪ ﺷﻤﺎ دارﻧﺪ ﺑﭙﺮدازﻳﺪ و ﻣﺸﻜﻼت )ﻫﺮ ﭼﻨﺪ ﺳﺎده ي( آﻧﻬﺎ را ﺑﺮ ﻃﺮف ﻛﻨﻴﺪ‪ .‬در ﻟﻴﺴﺖ زﻳﺮ ﺳﻌﻲ ﻣـﻲ‬ ‫ﻛﻨﻴﻢ ﻣﻬﻤﺘﺮﻳﻦ ﻣﻨﺎﺑﻊ و ﺳﺎﻳﺘﻬﺎي اﻳﻨﺘﺮﻧﺘﻲ ﻣﻮﺟﻮد را ﻣﻌﺮﻓﻲ ﻛﻨﻴﻢ‪ .‬اﮔﺮ در اﻳﻦ ﺳﺎﻳﺘﻬﺎ ﻫﻢ ﻧﺘﻮاﻧﺴﺘﻴﺪ ﻣﺸﻜﻼت ﺧﻮد را ﺑﺮﻃﺮف ﻛﻨﻴﺪ‪ ،‬ﻛﺎﻓﻲ‬ ‫اﺳﺖ ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﻣﻮﺗﻮر ﺟﺴﺘﺠﻮ ﺑﻪ دﻧﺒﺎل ﭘﺎﺳﺦ ﺧﻮد ﺑﮕﺮدﻳﺪ‪ .‬ﻗﻄﻌﺎ ﺑﻪ ﺳﺮﻋﺖ ﺟﻮاب ﺧﻮد را ﺧﻮاﻫﻴﺪ ﻳﺎﻓﺖ‪.‬‬

‫ﻣﻨﺎﺑﻊ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ‪:‬‬ ‫اﺣﺘﻤﺎﻻً ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﺳﺎﻳﺘﻬﺎﻳﻲ ﻛﻪ ﺑﻪ آن ﻣﺮاﺟﻌﻪ ﺧﻮاﻫﻴﺪ ﻛﺮد‪ ،‬وب ﺳﺎﻳﺖ ﺷﺮﻛﺖ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﺧﻮاﻫﺪ ﺑﻮد‪ .‬اﻳﻦ ﺳﺎﻳﺖ ﺷﺎﻣﻞ ﻣﻨـﺎﺑﻊ‬ ‫و اﻃﻼﻋﺎت زﻳﺎدي در ﻣﻮرد ‪ .NET‬اﺳﺖ‪ .‬ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﺳﺎﻳﺖ ﮔﺮوه ﻫﺎي ﺧﺒﺮي زﻳﺎدي در ﻣﻮرد ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺎ اﺳﺘﻔﺎده از وﻳﮋوال‬ ‫‪ 2005 C#‬وﺟﻮد دارد‪ .‬ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ اﻳﻦ ﮔﺮوه ﻫﺎي ﺧﺒﺮي ﻣﻲ ﺗﻮاﻧﻴﺪ از آدرس زﻳﺮ اﺳﺘﻔﺎده ﻛﻨﻴﺪ‪:‬‬ ‫‪http://communities2.microsoft.com/communities/newsgroups/en‬‬ ‫‪-us/default.aspx‬‬ ‫ﻫﻤﭽﻨﻴﻦ در اﻳﻦ زﻣﻴﻨﻪ ﭼﻨﺪﻳﻦ ﺳﺎﻳﺖ دﻳﮕﺮ ﻛﻪ زﻳﺮ ﻣﺠﻤﻮﻋﻪ ي ﺳﺎﻳﺖ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﻫﺴﺘﻨﺪ ﻧﻴﺰ وﺟﻮد دارﻧﺪ ﻛﻪ ﻣﻄﻤﺌﻨﺎ اﻃﻼﻋﺎت ﻣﻔﻴﺪي‬ ‫ﺑﺮاي ﺷﻤﺎ ﺧﻮاﻫﻨﺪ داﺷﺖ‪ .‬ﻟﻴﺴﺖ زﻳﺮ ﺗﻌﺪادي از آﻧﻬﺎ را ﻣﻌﺮﻓﻲ ﻣﻲ ﻛﻨﺪ‪:‬‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬

‫ﺳﺎﻳﺖ وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪:2005‬‬ ‫‪http://lab.msdn.microsoft.com/vs2005/‬‬ ‫ﻣﺴﺘﻨﺪات ﻣﺮﺑﻮط ﺑﻪ وﻳﮋوال اﺳﺘﻮدﻳﻮ ‪:2005‬‬ ‫‪http://lab.msdn.microsoft.com/library/‬‬ ‫ﻛﺘﺎﺑﺨﺎﻧﻪ ي ‪:MSDN‬‬ ‫‪http://msdn.microsoft.com/library/‬‬ ‫ﺳﺎﻳﺖ ‪:MSDN‬‬ ‫‪http://msdn.microsoft.com‬‬ ‫ﺳﺎﻳﺖ ﻣﻨﺎﺑﻊ ﻗﺎﺑﻞ داﻧﻠﻮد ﺑﺮاي ‪:.NET‬‬ ‫‪http://msdn.microsoft.com/netframework/downloads/‬‬

‫‪٩٠٠‬‬

‫ﻣﻨﺎﺑﻊ دﻳﮕﺮ‪:‬‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻞ ﻧﻴﺰ ﮔﻔﺘﻢ‪ ،‬ﭼﻨﺪﻳﻦ ﻫﺰار ﺳﺎﻳﺖ در ﻣﻮرد وﻳﮋوال ‪ C# .NET‬و وﻳﮋوال ‪ 2005 C#‬در اﻳﻨﺘﺮﻧﺖ وﺟﻮد دارد‪.‬‬ ‫اﻳﻦ ﺳﺎﻳﺘﻬﺎ ﺷﺎﻣﻞ اﻃﻼﻋﺎﺗﻲ در ﻣﻮرد ﺳﻤﻴﻨﺎرﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ زﻣﻴﻨﻪ در ﺳﺮﺗﺎﺳﺮ دﻧﻴﺎ‪ ،‬ﺧﺒﺮﻫﺎي ﺟﺪﻳﺪ در ﻣﻮرد ‪ .NET‬و وﻳﮋوال ‪،C#‬‬ ‫ﻣﻘﺎﻻت ﻣﺨﺘﻠﻒ در اﻳﻦ زﻣﻴﻨﻪ و ‪ ...‬ﻣﻲ ﺷﻮﻧﺪ‪ .‬اﮔﺮ در اﻳﻦ ﻣﻮرد در اﻳﻨﺘﺮﻧﺖ ﺑﻪ ﺟﺴﺘﺠﻮ ﺑﭙﺮدازﻳﺪ‪ ،‬ﺗﻌﺪاد زﻳﺎدي از ﺳﺎﻳﺘﻬﺎﻳﻲ را ﭘﻴﺪا ﺧﻮاﻫﻴـﺪ‬ ‫ﻛﺮد ﻛﻪ در اﻳﻦ ﺑﺎزه ﻓﻌﺎﻟﻴﺖ ﻣﻲ ﻛﻨﻨﺪ‪ .‬در اﻳﻦ ﻗﺴﻤﺖ ﺑﺎ ﺳﻪ ﺳﺎﻳﺖ اﻧﮕﻠﻴﺴﻲ ﻣﻬﻢ و ﻫﻤﭽﻨﻴﻦ ﻳﻚ ﺳﺎﻳﺖ ﻓﺎرﺳﻲ آﺷﻨﺎ ﺧﻮاﻫﻴﻢ ﺷﺪ‪.‬‬ ‫اوﻟﻴﻦ و ﻣﻬﻤﺘﺮﻳﻦ ﺳﺎﻳﺘﻲ ﻛﻪ در اﻳﻦ ﺑﺎره وﺟﻮد دارد‪ ،‬ﺳﺎﻳﺖ ‪ www.gotdotnet.com‬اﺳﺖ ﻛﻪ ﻳﻜﻲ از زﻳﺮ ﻣﺠﻤﻮﻋﻪ ﻫـﺎي‬ ‫ﺳﺎﻳﺖ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﺑﻪ ﺷﻤﺎر ﻣﻲ رود‪ .‬اﻳﻦ ﺳﺎﻳﺖ داراي ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻔﻲ ﺑﺮاي ارﺳﺎل ﻣﻘﺎﻻت در ﻣﻮرد ‪ .NET‬و زﻣﻴﻨﻪ ﻫﺎي ﻣـﺮﺗﺒﻂ‬ ‫ﺑﻪ آن اﺳﺖ‪ .‬ﻫﻤﭽﻨﻴﻦ اﻳﻦ ﺳﺎﻳﺖ داراي ﻗﺴﻤﺖ ﻓﻮروم و ﮔﻔﺘﮕﻮ در ﻣﻮرد ﻣﺴﺎﺋﻞ ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ در اﻳﻦ ﭘﻠﺖ ﻓﺮم اﺳـﺖ‪ .‬اﮔـﺮ در‬ ‫زﻣﻴﻨﻪ ي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺸﻜﻠﻲ داﺷﺘﻴﺪ‪ ،‬ﻫﻤﻮاره اﻓﺮادي در اﻳﻦ ﺳﺎﻳﺖ وﺟﻮد دارﻧﺪ ﻛﻪ ﺑﻪ ﺷﻤﺎ ﻛﻤﻚ ﻛﻨﻨﺪ ﺗﺎ ﻣﺸﻜﻞ ﺧﻮد را ﺑﺮﻃﺮف ﻛﻨﻴﺪ‪.‬‬ ‫ﺣﺘﻲ ﻣﻤﻜﻦ اﺳﺖ ﻣﺸﻜﻞ ﺷﻤﺎ ﻗﺒﻞ از اﻳﻦ ﺑﺮاي ﻓﺮد دﻳﮕﺮي ﻧﻴﺰ ﺑﻪ وﺟﻮد آﻣﺪه ﺷﺪه و ﺑﻪ وﺳﻴﻠﻪ ي اﻓﺮادي رﻓﻊ ﺷﺪه ﺑﺎﺷﺪ‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ ﻣـﻲ‬ ‫ﺗﻮاﻧﻴﺪ ﺑﺎ ﺟﺴﺘﺠﻮ در ﻣﻄﺎﻟﺐ اﻳﻦ ﺳﺎﻳﺖ‪ ،‬اﻃﻼﻋﺎت ﻣﻮرد ﻧﻴﺎز ﺧﻮد را ﺑﺪﺳﺖ آورﻳﺪ‪.‬‬ ‫ﺳﺎﻳﺖ دﻳﮕﺮي ﻛﻪ در زﻣﻴﻨﻪ ي ‪ C#‬وﺟﻮد دارد‪ ،‬وب ﺳـﺎﻳﺖ ‪ www.csharp-corner.com‬اﺳـﺖ‪ .‬اﻳـﻦ ﺳـﺎﻳﺖ داراي‬ ‫ﻣﻘﺎﻻت و ﻧﻤﻮﻧﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ارزﻧﺪه اي در ﻣﻮرد ﻣﺴﺎﺋﻞ و ﺟﻨﺒﻪ ﻫﺎي ﻣﺨﺘﻠﻒ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻪ زﺑﺎن ‪ C#‬اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺗﺎﺛﻴﺮ زﻳﺎدي‬ ‫در ﻳﺎدﮔﻴﺮي ﺷﻤﺎ داﺷﺘﻪ ﺑﺎﺷﺪ‪.‬‬ ‫وب ﺳﺎﻳﺖ ﻣﻬﻢ و ﻣﻔﻴﺪ دﻳﮕﺮي ﻛﻪ در اﻳﻦ زﻣﻴﻨﻪ وﺟﻮد دارد‪ ،‬ﺳـﺎﻳﺖ ‪ www.codeproject.com‬اﺳـﺖ‪ .‬در اﻳـﻦ ﺳـﺎﻳﺖ‬ ‫داراي ﺑﺎﻟﻎ ﺑﺮ ﻳﺎزده ﻫﺰار ﻣﻘﺎﻟﻪ‪ ،‬ﻧﻤﻮﻧﻪ ﺑﺮﻧﺎﻣﻪ‪ ،‬اﺧﺒﺎر و ‪ ...‬اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ﺷﻤﺎ در ﻳـﺎدﮔﻴﺮي ﻣﻄﺎﻟـﺐ ﺟﺪﻳـﺪ در ﺑﺮﻧﺎﻣـﻪ ﻧﻮﻳـﺴﻲ ‪C#‬‬ ‫ﻛﻤﻚ ﻛﻨﺪ‪.‬‬ ‫وب ﺳﺎﻳﺖ ﻓﺎرﺳﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ )‪ ، (www.barnamenevis.org‬ﻳﻜﻲ از ﺳﺎﻳﺘﻬﺎي ﺗﺨﺼﺼﻲ در زﻣﻴﻨﻪ ي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ‬ ‫اﺳﺖ‪ .‬اﻳﻦ ﺳﺎﻳﺖ ﺑﺎ ﺗﺎﻻرﻫﺎي ﮔﻔﺘﮕﻮ ﺑﺮاي زﻣﻴﻨﻪ ﻫﺎي ﻣﺨﺘﻠﻒ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ و داﺷـﺘﻦ ﺣـﺪود ﻧـﻮزده ﻫـﺰار ﻛـﺎرﺑﺮ‪ ،‬ﻳﻜـﻲ از ﺑﺰرﮔﺘـﺮﻳﻦ‬ ‫ﺳﺎﻳﺘﻬﺎي ﺗﺨﺼﺼﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻪ زﺑﺎن ﻓﺎرﺳﻲ ﺑﻪ ﺷﻤﺎر ﻣﻲ رود‪ .‬اﮔﺮ در اﺳﺘﻔﺎده از ﺳﺎﻳﺘﻬﺎي ﻗﺒﻠﻲ ﺑﻪ ﻋﻠﺖ زﺑﺎن آﻧﻬﺎ ﺑﺎ ﻣﺸﻜﻞ ﻣﻮاﺟﻪ‬ ‫ﺷﺪﻳﺪ‪ ،‬اﻳﻦ ﺳﺎﻳﺖ و اﻓﺮادي ﻛﻪ در آن وﺟﻮد دارﻧﺪ ﻳﻜﻲ از ﺑﻬﺘﺮﻳﻦ ﮔﺰﻳﻨﻪ ﻫﺎ ﺑﺮاي ﺣﻞ ﻣﺸﻜﻞ ﺷﻤﺎ ﻣﺤﺴﻮب ﻣﻲ ﺷﻮﻧﺪ‪.‬‬ ‫اﻟﺒﺘﻪ ﺳﺎﻳﺘﻬﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻗﺴﻤﺖ ﻣﻌﺮﻓﻲ ﺷﺪ ﻓﻘﻂ ﺑﺨﺸﻲ از ﺳﺎﻳﺘﻬﺎﻳﻲ ﺑﻮدﻧﺪ ﻛﻪ در اﻳﻦ زﻣﻴﻨﻪ وﺟﻮد دارﻧﺪ‪ .‬ﺑﻌﻀﻲ از ﺷﻤﺎ ﻣﻤﻜـﻦ اﺳـﺖ‬ ‫ﺗﺮﺟﻴﺢ دﻫﻴﺪ ﻓﻘﻂ از اﻳﻦ ﭼﻨﺪ ﺳﺎﻳﺖ اﺳﺘﻔﺎده ﻛﻨﻴﺪ و ﺑﺮﺧﻲ دﻳﮕﺮ ﻧﻴﺰ ﻣﻤﻜﻦ اﺳﺖ ﺑﺨﻮاﻫﻴﺪ در اﻳﻨﺘﺮﻧﺖ ﺑﻪ دﻧﺒﺎل ﺳﺎﻳﺘﻬﺎي دﻳﮕﺮي ﮔﺸﺘﻪ و‬ ‫آﻧﻬﺎ را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﺪ‪ .‬اﻧﺘﺨﺎب اﻳﻦ ﻣﻮرد ﻛﻪ از ﭼﻪ ﺳﺎﻳﺘﻲ اﺳﺘﻔﺎده ﻛﻨﻴﺪ ﻓﻘﻂ ﺑﻪ ﺷﻤﺎ ﺑﺴﺘﮕﻲ دارد‪ ،‬اﻣﺎ ﻣﻬﻢ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺪاﻧﻴﺪ اﻳﻨﺘﺮﻧﺖ ﻣﻲ‬ ‫ﺗﻮاﻧﺪ ﻧﻘﺶ ﺑﻪ ﺳﺰاﻳﻲ در ﺳﻄﺢ ﻳﺎدﮔﻴﺮي ﻣﻄﺎﻟﺐ و ﻫﻤﭽﻨﻴﻦ ﺗﻨﻮع آﻧﻬﺎ داﺷﺘﻪ ﺑﺎﺷﺪ‪.‬‬

‫‪٩٠١‬‬

‫ﺿﻤﻴﻤﻪ ‪ :2‬ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺗﺠﺎري و ﭼﻨﺪ ﻻﻳﻪ در ‪.NET‬‬ ‫در ﻣﻌﺮﻓﻲ ‪ .NET‬ﻣﻲ ﺗﻮان ﮔﻔﺖ ﻛﻪ ‪ .NET‬ﺷﺎﻣﻞ ﻳﻚ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ از ﺗﻜﻨﻮﻟﻮژي ﻫﺎ و ﻧﻴﺰ ﻳﻚ ﻧﻤﻮﻧـﻪ ﺟﺪﻳـﺪ ﺑـﺮاي ﻃﺮاﺣـﻲ و‬ ‫ﺗﻮﺳﻌﻪ ﻧﺮم اﻓﺰار ﻣﻲ ﺷﻮد‪ .NET .‬ﻓﻘﻂ ﻳﻚ ﻣﺤﻴﻂ ﻃﺮاﺣﻲ و ﺗﻮﺳﻌﻪ ﺟﺪﻳﺪ ﻧﻴﺴﺖ‪ ،‬ﺑﻠﻜﻪ ﻳﻚ دﻧﺒﺎﻟﻪ ي ﻛﺎﻣﻞ از ﺳﺮور ﻫﺎ و ﺳﺮوﻳﺲ ﻫﺎ‬ ‫اﺳﺖ ﻛﻪ ﺑﺮاي ﺣﻞ ﻣﺸﻜﻼت ﺗﺠﺎري اﻣﺮوزه ﺑﻪ ﺻﻮرت ﻣﻮازي ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﻛﺎر ﻣﻲ ﻛﻨﻨﺪ‪ .‬در ﻃﻲ ﻓﺼﻮل اﻳﻦ ﻛﺘﺎب‪ ،‬ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺗﺤﺖ‬ ‫‪ .NET‬و ﻧﻴﺰ ﺗﻌﺪادي از ﺗﻜﻨﻮﻟﻮژي ﻫﺎﻳﻲ ﻛﻪ در آن ﺑﻪ ﻛﺎر رﻓﺘﻪ اﺳﺖ آﺷﻨﺎ ﺷﺪﻳﻢ و آﻧﻬﺎ را ﺑﻪ ﻃﻮر ﻋﻤﻠﻲ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار دادﻳـﻢ‪ .‬اﻣـﺎ‬ ‫در اﻳﻦ ﺿﻤﻴﻤﻪ ﺳﻌﻲ ﻣﻲ ﻛﻨﻢ ﺑﺎ ﻧﮕﺮﺷﻲ ﻣﺘﻔﺎوت ‪ .NET‬را ﺑﺮرﺳﻲ ﻛﺮده و ﺑﻌﺪ از ﻣﻌﺮﻓﻲ آن‪ ،‬دﻟﻴﻞ اﻳﺠﺎد و اﺑـﺪاع ‪ .NET‬را ﺑﺮرﺳـﻲ‬ ‫ﻛﻨﻢ‪.‬‬ ‫ﺑﻪ راﺣﺘﻲ ﻣﻲ ﺗﻮان درﻳﺎﻓﺖ ﻛﻪ ﭘﻮﺷﺶ دادن ﺗﻤﺎم ﺗﻜﻨﻮﻟﻮژي ﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي اراﺋﻪ ﻳﻚ ﻣﺪل و راه ﺣﻞ در ‪ .NET‬ﻣﻮرد ﻧﻴﺎز اﺳﺖ ﺣﺘـﻲ‬ ‫در ﻳﻚ ﻛﺘﺎب ﻧﻴﺰ ﻗﺎﺑﻞ ﮔﻨﺠﺎﻳﺶ ﻧﻴﺴﺖ‪ .NET .‬ﻋﻼوه ﺑﺮ در ﺑﺮ داﺷﺘﻦ ﻧﺴﺨﻪ ﻫﺎي ﺟﺪﻳﺪ از ﺗﻜﻨﻮﻟﻮژي ﻫﺎي ﻗﺒﻠﻲ‪ ،‬ﭼﻨﺪﻳﻦ ﺗﻜﻨﻮﻟـﻮژي‬ ‫ﺟﺪﻳﺪ را ﻧﻴﺰ ﺷـﺎﻣﻞ ﻣـﻲ ﺷـﻮد‪ .‬اﻳـﻦ ﻣﺠﻤﻮﻋـﻪ ﺗﻜﻨﻮﻟـﻮژي ﻫـﺎ ﻋﺒﺎرﺗﻨـﺪ از ‪.NET ،Windows XP ،SQL Server‬‬ ‫‪ Enterprise Services‬و ﻫﻤﭽﻨﻴﻦ ﺗﻜﻨﻮﻟﻮژي ﻫﺎي اﺳﺘﺎﻧﺪارد ﻣﺜﻞ ‪ SOAP‬و ‪.XML‬‬

‫ﭼﺮا ‪ .NET‬؟‬ ‫ﻫﻤﺎﻧﻨﺪ ﻫﺮ ﺗﻜﻨﻮﻟﻮژي دﻳﮕﺮي‪ .NET ،‬ﻧﻴﺰ ﺑﺎﻳﺪ ﻗﺒﻞ از اﻳﻨﻜﻪ ﺑﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد ﺑﻪ ﺻﻮرت ﻛﺎﻣﻞ ﺑﺮرﺳﻲ ﺷﻮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ در اﻳـﻦ‬ ‫ﻗﺴﻤﺖ ﺳﻌﻲ ﻣﻲ ﻛﻨﻴﻢ ﺑﺎ ﻣﺰاﻳﺎي اﺳﺘﻔﺎده از ‪.NET‬آﺷﻨﺎ ﺷﻮﻳﻢ‪ .‬در اﺑﺘﺪا ﻧﮕﺎه ﻛﻮﺗﺎﻫﻲ ﺑﺮ ﻣﺸﻜﻼﺗﻲ ﺧﻮاﻫﻴﻢ داﺷـﺖ ﻛـﻪ ﻣـﻲ ﺗـﻮان ﺑـﺎ‬ ‫‪ .NET‬ﺑﻪ اراﺋﻪ راه ﺣﻞ ﺑﺮاي آﻧﻬﺎ ﭘﺮداﺧﺖ‪.‬‬

‫ﻣﺸﻜﻼت ﺗﺠﺎري رﻓﻊ ﺷﺪه ﺗﻮﺳﻂ ‪.NET‬‬ ‫از ﺑﺴﻴﺎري ﺟﻬﺎت دﻧﻴﺎي ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎي ﺷﺨﺼﻲ ﺑﺎ ﺣﺮﻛﺖ از ﺣﺎﻟﺖ ﻣﺤﺎﺳﺒﻪ ﺑﻪ ﺻﻮرت ﻣﺠﺰا و ﻧﻴﺰ اﻳﺴﺘﮕﺎه ﻫﺎي ﻛـﺎري ﻏﻴـﺮ ﻣـﺮﺗﺒﻂ ﺑـﻪ‬ ‫ﺳﻮي ﺷﺒﻜﻪ ﻫﺎي ﻛﺎﻣﭙﻴﻮﺗﺮي و ﻧﻴﺰ راﺑﻄﻪ ﻫﺎي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه‪ /‬ﺳﺮوﻳﺲ دﻫﻨﺪه دﭼﺎر ﺗﻐﻴﻴﺮاﺗﻲ ﺷﺪه اﺳﺖ‪ .‬ﺷﺒﻜﻪ ﻫﺎي ﺳﺮوﻳﺲ دﻫﻨـﺪه‬ ‫ﻓﺎﻳﻞ و ﻳﺎ ﭼﺎﭘﮕﺮ راﻫﻲ را ﺑﺮاي ﺑﻪ اﺷﺘﺮاك ﮔـﺬاري اﻃﻼﻋـﺎت ﺑـﺎ ﻣـﺪﻳﺮﻳﺖ ﻣﺮﻛـﺰي ﻓـﺮاﻫﻢ ﻣـﻲ ﻛﻨـﺪ‪ .‬ﺗﻮﻟـﺪ ﺳﻴـﺴﺘﻢ ﻫـﺎي ﺳـﺮوﻳﺲ‬ ‫ﮔﻴﺮﻧﺪه‪/‬ﺳﺮوﻳﺲ دﻫﻨﺪه ﺑﻪ ﻛﺎﻫﺶ ﺣﺠﻢ ﻛﺎر از روي ﺳﻴﺴﺘﻢ ﻫﺎي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه و اﻧﺘﻘﺎل آن ﺑﻪ ﺳـﺮور ﻫـﺎ‪ ،‬و ﻧﻴـﺰ اﻓـﺰاﻳﺶ ﻛـﺎراﻳﻲ و‬ ‫ﻗﺎﺑﻠﻴﺖ اﻋﺘﻤﺎد در ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻛﻤﻚ ﻗﺎﺑﻞ ﺗﻮﺟﻬﻲ ﻛﺮد‪ .‬در اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﺪﻳﺮان ﺳﻴﺴﺘﻢ ﻧﻤﻲ ﺗﻮاﻧﺴﺘﻨﺪ ﺑـﻪ ﻛـﺎﻣﭙﻴﻮﺗﺮ ﻫـﺎي ﺳـﺮوﻳﺲ‬ ‫ﮔﻴﺮﻧﺪه ﺑﺮاي ﻣﺪﻳﺮﻳﺖ و اداره ﻓﺎﻳﻠﻬﺎي ﻣﻮﺟﻮد اﻋﺘﻤﺎد ﻛﻨﻨﺪ‪ ،‬زﻳﺮا ﻣﻤﻜﻦ ﺑﻮد اﻳﻦ ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﺎ ﺑﻪ ﻫﺮ دﻟﻴﻠﻲ از ﻛﺎر ﺑﺎﻳﺴﺘﻨﺪ و ﺑﺎﻋـﺚ ﺧﺮاﺑـﻲ‬ ‫داده ﻫﺎي ﻣﻮﺟﻮد ﺷﻮﻧﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺎ اﺳﺘﻔﺎده از اﻳﻦ ﺳﺮوﻳﺲ ﻫﺎ اﻳﻦ اﻃﻤﻴﻨﺎن اﻳﺠﺎد ﻣﻲ ﺷﺪ ﻛﻪ ﺳـﺮوﻳﺲ ﮔﻴﺮﻧـﺪه ﻣﺤـﺪود ﺑـﻪ درﻳﺎﻓـﺖ و‬ ‫ﻣﺸﺎﻫﺪه ي ﻓﺎﻳﻠﻬﺎ و اﺳﺘﻔﺎده از آﻧﻬﺎ اﺳﺖ و ﺳﺮور ﻫﺎ ﻛﺎرﻫﺎي اﺻﻠﻲ را اﻧﺠﺎم ﻣﻲ دﻫﻨﺪ‪ .‬اﻳﻦ ﻣﻮرد ﺑﺎﻋﺚ اﻓﺰاﻳﺶ ﻗﺎﺑﻠﻴﺖ اﻋﺘﻤﺎد ﺑﻪ ﺑﺮﻧﺎﻣـﻪ‬ ‫ﻫﺎ ﻣﻲ ﺷﺪ‪ ،‬زﻳﺮا اﺣﺘﻤﺎل رخ دادن ﺧﺮاﺑﻲ در آﻧﻬﺎ ﺑﻪ ﺷﺪت ﻛﺎﻫﺶ ﭘﻴﺪا ﻣﻲ ﻛﺮد‪.‬‬ ‫اوﻟﻴﻦ ﺷﺒﻜﻪ ﻫﺎي ﻛﺎﻣﭙﻴﻮﺗﺮي ﺷﺎﻣﻞ ﺳﺮورﻫﺎي ﻓﺎﻳﻞ و ﭼﺎﭘﮕﺮ ﺑﻪ ﻫﻤﺮاه ﻳﻚ ﺳﻴﺴﺘﻢ ﻣﺘﻤﺮﻛﺰ ﺑـﺮاي اﺷـﺘﺮاك اﻃﻼﻋـﺎت و ﻧﻴـﺰ ﻣـﺪﻳﺮﻳﺖ‬ ‫ﺷﺒﻜﻪ ﺑﻮد ) ﻫﻤﺎﻧﻨﺪ ﺷﻜﻞ زﻳﺮ(‪ .‬اﻣﺎ اﻳﻦ ﻣﺪل ﻓﻘﻂ ﺷﺎﻣﻞ اﺷﺘﺮاك ﻓﺎﻳﻞ و ﭼﺎﭘﮕﺮ از ﻃﺮﻳﻖ ﺷـﺒﻜﻪ ﺑـﻮد‪ .‬ﺑﺮﻧﺎﻣـﻪ ي اﺻـﻠﻲ در ﺣﻘﻴﻘـﺖ ﺑـﻪ‬ ‫ﺻﻮرت ﻛﺎﻣﻞ در ﻗﺴﻤﺖ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﻋﻤﻞ ﻛـﺮد و ﻓﻘـﻂ از ﻣﺰاﻳـﺎي ﻣﺸﺨـﺼﻲ از ﺳـﺮوﻳﺲ ﻫـﺎي ﻣﻮﺟـﻮد در ﻣـﺪل‬ ‫ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه‪/‬ﺳﺮوﻳﺲ دﻫﻨﺪه اﺳﺘﻔﺎده ﻣﻲ ﻛﺮد‪.‬‬

‫‪٩٠٢‬‬

‫ﻣﺪل ﻗﺪﻳﻤﻲ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه‪/‬ﺳﺮوﻳﺲ دﻫﻨﺪه – در اﻳﻦ ﻣﺪل ﻓﻘﻂ داده ﻫﺎ از ﺳﺮور درﻳﺎﻓﺖ ﻣﻲ ﺷﺪ‪ ،‬اﻣﺎ ﺑﺮﻧﺎﻣﻪ ي اﺻﻠﻲ ﺑﻪ وﺳﻴﻠﻪ‬ ‫ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﻛﻨﺘﺮل ﻣﻲ ﺷﺪ‬ ‫ﻣﺸﻜﻼت اﻳﻦ ﻧﻮع ﺳﻴﺴﺘﻢ ﻫﺎي ﻣﺘﻤﺮﻛﺰ ﺷﺎﻣﻞ ﻣﻮاردي از ﻗﺒﻴﻞ ﻓﻘﺪان ﻛﺎراﻳﻲ و ﻳﺎ ﺧﺮاﺑﻲ و از دﺳﺖ رﻓﺘﻦ اﻃﻼﻋﺎت ﻣﻲ ﺷـﻮﻧﺪ‪ .‬ﻓﻘـﺪان‬ ‫ﻛﺎراﻳﻲ ﺑﻪ اﻳﻦ دﻟﻴﻞ ﺑﻮد ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﻤﺖ ﻛﺎرﺑﺮ ﺑﺎﻳﺴﺘﻲ ﺗﻤﺎﻣﻲ ﻣﺤﺎﺳﺒﺎت ﻣﻮرد ﻧﻴﺎز را اﻧﺠﺎم ﻣﻲ دادﻧـﺪ‪ .‬ﺑـﻪ ﻋﻠـﺖ رﻳـﺴﻚ ﺛﺎﺑـﺖ و‬ ‫ﻫﻤﻴﺸﻪ ﻣﻮﺟﻮد ﻧﺎ ﭘﺎﻳﺪاري ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه‪ ,1‬ﭘﺘﺎﻧﺴﻴﻞ ﺧﺮاﺑﻲ اﻃﻼﻋﺎت ﻧﻴﺰ ﺑﺎﻻ ﺑﻮد‪ .‬اﮔﺮ ﻣﻮﻗﻊ دﺳﺘﻜﺎري ﻓﺎﻳـﻞ ﺑـﺮ روي ﺳـﺮور ارﺗﺒـﺎط‬ ‫ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه از ﺷﺒﻜﻪ ﻗﻄﻊ ﻣﻲ ﺷﺪ ﺑﺮﻧﺎﻣﻪ ﻳﺎ اﻃﻼﻋﺎت ﻓﺎﻳﻞ ﺑﻪ راﺣﺘﻲ ﺗﺨﺮﻳﺐ ﻣﻲ ﺷﺪﻧﺪ‪.‬‬ ‫ﺑﻨﺎﺑﺮاﻳﻦ ﻣﺪل ﻗﺪﻳﻤﻲ را ﺗﺼﺤﻴﺢ ﻛﺮدﻧﺪ و ﻣﺪﻟﻲ ﻣﺎﻧﻨﺪ ﺷﻜﻞ زﻳﺮ را اراﺋﻪ دادﻧﺪ‪ .‬ﻣﺪل ﺗﺼﺤﻴﺢ ﺷﺪه ي ﺳﺮوﻳﺲ ﮔﻴﺮﻧـﺪه‪/‬ﺳـﺮوﻳﺲ دﻫﻨـﺪه‬ ‫ﻫﺮﮔﺰ ﺑﻪ ﻛﺎرﺑﺮ اﺟﺎزه ﻧﻤﻲ داد ﻛﻪ ﺑﻪ ﺻﻮرت واﻗﻌﻲ ﺑﻪ اﻃﻼﻋﺎت ﻳﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ‪ .‬ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﻫﻴﭻ ﺗﻤﺎﺳﻲ ﺑﺎ ﻓﺎﻳـﻞ‬ ‫ﻳﺎ ﺑﺮﻧﺎﻣﻪ ي ﻣﻮرد اﺳﺘﻔﺎده ﻧﺪاﺷﺖ و اﻳﻦ ﻣﻮﺟﺐ ﻛﺎﻫﺶ ﻗﺎﺑﻞ ﺗﻮﺟﻪ رﻳﺴﻚ از دﺳﺖ رﻓﺘﻦ اﻃﻼﻋﺎت ﻣﻲ ﺷﺪ‪.‬‬

‫اﻳﻦ ﺷﻜﻞ ﻣﺪل ﺗﺼﺤﻴﺢ ﺷﺪه ي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه‪/‬ﺳﺮوﻳﺲ دﻫﻨﺪه را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ‬ ‫اﻣﺮوزه ﻳﻚ ﺳﺮور ﺗﻤﺎﻣﻲ ﺳﺮوﻳﺴﻬﺎي اﻳﻨﺘﺮﻧﺘﻲ ﻣﺮﺑﻮط ﺑﻪ ﺑﺮﻧﺎﻣﻪ از اﺣﺮاز ﻫﻮﻳﺖ ﻛﺎرﺑﺮ ﺗﺎ دﺳﺘﺮﺳﻲ ﺑﻪ داده ﻫﺎ را اﻧﺠﺎم ﻣﻲ دﻫﺪ‪ .‬اﻳـﻦ اﻣـﺮ‬ ‫ﻣﺸﻜﻼت ﻗﺎﺑﻞ ﺗﻮﺟﻬﻲ را در ﻣﻘﻴﺎس ﻫﺎي ﻛﻮﭼﻚ اﻳﺠﺎد ﻧﻤﻲ ﻛﻨﺪ‪ ،‬اﻣﺎ وﻗﺘﻲ ﻓﺮاواﻧﻲ درﺧﻮاﺳﺖ داده ﻫﺎ از ﺗﻮاﻧﺎﻳﻲ ﺳﺮور ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ‬ ‫ﺗﺠﺎوز ﻛﺮد و ﺳﺮور ﺑﺮﻧﺎﻣﻪ ﺗﻘﺎﺿﺎ ﻫﺎﻳﻲ ﺑﻴﺸﺘﺮ از آﻧﭽﻪ ﺗﻮاﻧﺎﻳﻲ ﭘﺎﺳﺦ ﮔﻮﻳﻲ ﺑﻪ آﻧﻬﺎ دارد را درﻳﺎﻓﺖ ﻛﺮد‪ ،‬ﻣـﺸﻜﻼت ﻋﻤـﺪه اي اﻳﺠـﺎد ﻣـﻲ‬ ‫ﺷﻮد‪ .‬ﭘﺲ اﻳﻦ ﻣﺪل ﻧﻴﺰ داراي ﺿﻌﻒ ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ در ﻣﺪﻟﻬﺎي ﺑﻌﺪي رﻓﻊ ﺧﻮاﻫﻨﺪ ﺷﺪ‪.‬‬ ‫و اﻣﺎ در ﻣﻮرد ﻗﺎﺑﻠﻴﺖ اﻃﻤﻴﻨﺎن‪ .2‬اﮔﺮ ﻫﺮ ﺑﺨﺸﻲ از ﺑﺮﻧﺎﻣﻪ ﻛﻪ در ﺑﻴﺸﺘﺮ ﺣﺎﻟﺘﻬﺎ ﺑﺮ روي ﺳﺮور ﻗﺮار ﻣﻲ ﮔﻴﺮد دﭼﺎر ﻧﻘﺺ ﺷﻮد‪ ،‬ﺑﺮﻧﺎﻣﻪ از ﻛـﺎر‬ ‫اﻓﺘﺎده و ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ در ﺣﺎل ﻛﺎر ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻣﺬﻛﻮر ﻫﺴﺘﻨﺪ آﺳﻴﺐ ﻣﻲ ﺑﻴﻨﺪ‪ .‬ﭘﺲ اﻳﻦ ﻣﺪل از ﻧﻈﺮ ﭘﺎﻳﺪاري ﻧﻴﺰ داراي ﻣﺸﻜﻼﺗﻲ اﺳﺖ‪.‬‬ ‫ﻣﺠﻤﻮﻋﻪ ﺗﻜﻨﻮﻟﻮژي ﻫﺎﻳﻲ ﻛﻪ در ‪ .NET‬وﺟﻮد دارﻧﺪ ﺷﺎﻣﻞ ﺗﻤﺎم ﻋﻮاﻣﻞ ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﭘﻴﺎده ﺳﺎزي راه ﺣﻠﻬﺎي ﺗﺠـﺎري‪ ،‬از اﺑﺰارﻫـﺎي‬ ‫ﻃﺮاﺣﻲ ﮔﺮﻓﺘﻪ ﺗﺎ ﺳﺮوﻳﺴﻬﺎي ﺗﺤﺖ وب ﻣﻲ ﺷﻮد‪ .‬اﻳﻦ ﻣﺠﻤﻮﻋﻪ ﻛﻪ ﺑﺎﻋﺚ اﻓﺰاﻳﺶ ﭘﺎﻳﺪاري‪ ،‬ﻗﺎﺑﻠﻴﺖ اﻋﺘﻤـﺎد ‪ ،‬اﻧﻌﻄـﺎف ﭘـﺬﻳﺮي و ﻗـﺪرت‬ ‫ﻣﺪﻳﺮﻳﺖ ﻣﻴﺸﻮد‪ ،‬ﺗﻤﺎم ﻣﺸﻜﻼت ﻣﺬﻛﻮر در ﻣﺪل ﻗﺒﻠﻲ را رﻓﻊ ﻣﻲ ﻛﻨﺪ‪ .‬ﺑﺮاي ﻧﻤﻮﻧﻪ ‪ .NET‬ﺳﺮور ﻫﺎ را از اﻳﻦ ﻣﺤـﺪودﻳﺖ ﻛـﻪ ﻓﻘـﻂ ﺑـﺎ‬ ‫ﻛﺎرﺑﺮان در ارﺗﺒﺎط ﺑﺎﺷﻨﺪ رﻫﺎ ﻣﻲ ﻛﻨﺪ و ﺑﻪ آﻧﻬﺎ اﺟﺎزه ﻣﻲ دﻫﺪ ﻛﻪ ﻋﻼوه ﺑﺮ ارﺗﺒﺎط ﺑﺎ ﻛﺎرﺑﺮان‪ ،‬ﺑﺎ دﻳﮕﺮ ﺳﺮور ﻫﺎ ﻧﻴﺰ در ﭘﺸﺖ ﭘﺮده ارﺗﺒـﺎط‬ ‫داﺷﺘﻪ ﺑﺎﺷﺪ‪ .‬ﺗﻌﺎﻣﻞ ﺳﺮور ﻫﺎ از ﻃﺮﻳﻖ وب ﺳﺮوﻳﺲ ﻫﺎي اراﺋﻪ ﺷﺪه‪ ،‬ﻧﻤﻮﻧﻪ ﺧﻮﺑﻲ از اﻳﻦ زﻣﻴﻨﻪ ﻣﻲ ﺑﺎﺷﻨﺪ‪.‬‬

‫‪ 1‬ﻣﻤﻜﻦ ﺑﻮد ﺑﻪ ﻫﺮ دﻟﻴﻠﻲ ﺳﺮوﻳﺲ ﮔﻴﻨﺪه اي ﻛﻪ ﻛﺎرﺑﺮ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ از ﺷﺒﻜﻪ ﻗﻄﻊ ﺷﺪه و ﻳﺎ ﻣﺘﻮﻗﻒ ﺷﻮد‪.‬‬ ‫‪Reliability‬‬

‫‪2‬‬

‫‪٩٠٣‬‬

‫ﺳﺮوري ﻛﻪ در ﻛﻨﺎر ﻛﺎر ﺑﺎ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﺑﺎ دﻳﮕﺮ وب ﺳﺮوﻳﺲ ﻫﺎ ﻧﻴﺰ ﺗﻌﺎﻣﻞ دارد و از آﻧﻬﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ‬

‫ﻛﺎراﻳﻲ و ﻣﻘﻴﺎس ﭘﺬﻳﺮي‪:‬‬ ‫اﮔﺮ ﻳﻚ ﺳﻴﺴﺘﻢ ﻗﺪرت ﻣﻘﻴﺎس ﭘﺬﻳﺮي‪ 1‬ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ‪ ،‬ﻫﻴﭻ راﻫﻲ ﺑﺮاي ﺗﻬﻴﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ﺗﻌﺪاد زﻳﺎدي ﻛﺎرﺑﺮ ﺑﻪ ﻃﻮر ﻫﻤﺰﻣﺎن ﭘﺎﺳﺦ‬ ‫دﻫﺪ ﻧﺨﻮاﻫﺪ ﺑﻮد‪ .‬در ﺣﻘﻴﻘﺖ‪ ،‬در ﺳﻴﺴﺘﻢ ﻫﺎي ﺳﺎزﻣﺎن ﻣﻘﻴﺎس ﻫﺮ ﭼﻪ ﻛﺎراﻳﻲ ﺳﻴﺴﺘﻢ ﻣﻬﻢ ﺑﺎﺷﺪ‪ ،‬ﭘﺎﻳﺪاري و ﻣﻘﻴﺎس ﭘﺬﻳﺮي آن از اﻫﻤﻴﺖ‬ ‫ﺑﻴﺸﺘﺮي ﺑﺮﺧﻮردار ﺧﻮاﻫﺪ ﺑﻮد‪.‬‬ ‫در ﺗﻌﺮﻳﻒ ﻛﺎراﻳﻲ‪ 2‬ﺳﻴﺴﺘﻢ ﻣﻴﺘﻮان ﮔﻔﺖ ﻛﻪ اﻳﻦ ﻋﺒﺎرت ﺑﻪ ﺗﻌﺪاد ﺳﻴﻜﻞ ﻫﺎﻳﻲ ﻛﻪ ﻳﻚ ﭘﺮدازﻧﺪه ﻧﻴﺎز دارد ﺗﺎ اﺟﺮاي ﻳﻚ ﻣﺘﺪ را ﺑـﻪ ﭘﺎﻳـﺎن‬ ‫ﺑﺮﺳﺎﻧﺪ اﻃﻼق ﻣﻲ ﺷﻮد‪ .‬اﻣﺎ ﻣﻨﻈﻮر از ﻣﻘﻴﺎس ﭘﺬﻳﺮي ﺗﻌﺪاد ﻛﺎرﺑﺮاﻧﻲ اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ ﺻـﻮرت ﻫﻤﺰﻣـﺎن ﻳـﻚ وﻇﻴﻔـﻪ ﺧـﺎص را در‬ ‫ﺳﺮور اﺟﺮا ﻛﻨﻨﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﻳﻚ ﻣﺘﺪ از ﺑﺮﻧﺎﻣﻪ‪ ،‬اﻃﻼﻋﺎت ﺧﻮاﺳﺘﻪ ﺷﺪه را ﺑﺎ ﺳﺮﻋﺘﻲ ﺷﮕﻔﺖ اﻧﮕﻴﺰ ﺑﺎز ﻣﻴﮕﺮداﻧﺪ‪ .‬ارزش اﻳﻦ‬ ‫ﻣﺘﺪ ﺑﻪ ﻋﻠﺖ ﺑﻪ ﻛﺎرﮔﻴﺮي ﺻﺪ درﺻﺪ ﭘﺮدازﻧﺪه اﺳﺖ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ در ﺣﺎﻟﻲ ﻛﻪ ﻛﺎراﻳﻲ ﭼﻨﻴﻦ ﺳﻴﺴﺘﻤﻲ ﺧـﻮب اﺳـﺖ اﻣـﺎ ﻣﻘﻴـﺎس ﭘـﺬﻳﺮي آن‬ ‫ﺿﻌﻴﻒ اﺳﺖ‪ ،‬زﻳﺮا ﭘﺮدازﻧﺪه ﺗﻨﻬﺎ ﻳﻚ ﻳﺎ دو ﻛﺎرﺑﺮ ﻫﻤﺰﻣﺎن ﻛﻪ درﺧﻮاﺳﺖ اﺟﺮاي ﻣﺘﺪ ﻣﺬﻛﻮر را دارﻧﺪ را ﻣﻲ ﺗﻮاﻧﺪ ﭘـﺸﺘﻴﺒﺎﻧﻲ ﻛﻨـﺪ‪ .‬ﻣﻘﻴـﺎس‬ ‫ﭘﺬﻳﺮي ﻳﻚ ﺳﻴﺴﺘﻢ ﻛﺎﻣﻼً ﺑﻪ ﻣﻌﻤﺎري دروﻧﻲ ﺑﺮﻧﺎﻣﻪ واﺑﺴﺘﻪ اﺳﺖ‪.‬‬

‫ﻣﺰاﻳﺎي ‪: .NET‬‬ ‫ﺑــﺮاي ﺗﻮﺳــﻌﻪ دﻫﻨــﺪﮔﺎن ﭘﺎﺳــﺦ ﺑــﻪ ﺳــﻮال "ﭼــﺮا ‪.NET‬؟" در دو ﮔــﺮوه ﻣﺰاﻳــﺎي ﻣﻮﺟــﻮد در ‪ 3IDE‬ﻣﺮﺑــﻮط ﺑــﻪ ‪ .NET‬و ﻧﻴــﺰ‬ ‫ﻣﻔﻬﻮم ‪ .NET‬ﻗﺮار ﻣﻲ ﮔﻴﺮد‪.‬‬ ‫ﻳﻚ ﺳﺮي از ﺗﻜﻨﻮﻟﻮژي ﻫﺎي ﻣﻮﺟﻮد در ‪ .NET‬ﺷﺎﻣﻞ ﻣﺠﻤﻮﻋﻪ اي از ﺗﻜﻨﻮﻟﻮژﻳﻬﺎﻳﻲ اﺳﺖ ﻛﻪ در ﺑﺮﻗﺮاري ارﺗﺒﺎط ﺑﻴﻦ ﭘﻠﺖ ﻓﺮم ﻫـﺎي‬ ‫ﮔﻮﻧﺎﮔﻮن ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد ﻣﺎﻧﻨﺪ ﭘﺮوﺗﻜﻠﻬﺎي اﺳﺘﺎﻧﺪاردي ﻣﺜﻞ ‪ ،HTTP‬و ﻧﻴﺰ ﺗﻜﻨﻮﻟﻮژﻳﻬﺎﻳﻲ ﻛﻪ ﺑﻪ ﭘﻠﺖ ﻓـﺮم ﺧﺎﺻـﻲ واﺑـﺴﺘﻪ‬ ‫‪4‬‬ ‫ﻧﻴﺴﺘﻨﺪ ﻣﺜﻞ ‪ .XML‬اﻳﻦ ﺗﻜﻨﻮﻟﻮژﻳﻬﺎ ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﺳﻴﺴﺘﻢ ﻫﺎي اﻳﺠﺎد ﺷﺪه ﺑﺎ ‪ .NET‬ﺑﺘﻮاﻧﻨﺪ ﺑﺎ ﺳﻴﺴﺘﻢ ﻫﺎي ﻗﺒﻠﻲ ﻣﺎﻧﻨـﺪ ‪COM‬‬ ‫و ‪ 5CORBA‬از ﻃﺮﻳﻖ وب ﺗﻌﺎﻣﻞ داﺷﺘﻪ ﺑﺎﺷﻨﺪ‪ .‬ﺑﻪ ﻋﻼوه ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﺗﻮﺟﻪ ﺑﻪ ﭘﻠﺖ ﻓﺮﻣﻬﺎي ﻣﻘﺼﺪ ﻧﻴﺰ ﻫﻢ اﻛﻨﻮن رﻓـﻊ ﺷـﺪه اﺳـﺖ‪،‬‬ ‫ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﻣﻲ ﺗﻮاﻧﻨﺪ از آن ﻟﺤﺎظ ﻧﮕﺮاﻧﻲ ﻧﺪاﺷﺘﻪ ﺑﺎﺷﻨﺪ و روي ﻧﻴﺎزﻫﺎي ﺗﺠﺎري ﺑﺮﻧﺎﻣﻪ ﺗﻤﺮﻛﺰ ﻛﻨﻨﺪ‪.‬‬

‫‪1‬‬

‫‪Scalability‬‬ ‫‪Performance‬‬ ‫‪3‬‬ ‫‪Integrated Development Environment‬‬ ‫‪4‬‬ ‫‪Component Object Model‬‬ ‫‪5‬‬ ‫‪Common Object Request Broker Architecture‬‬ ‫‪2‬‬

‫‪٩٠٤‬‬

‫اﻟﺒﺘﻪ ﺑﺎﻳﺪ ﺗﻮﺟﻪ داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ‪ .NET‬ﻳﻚ ﻫﺪف در ﺣﺎل ﺗﻐﻴﻴﺮ اﺳﺖ‪ .‬اﮔﺮ ﭼﻪ ﺑﺴﻴﺎري از ﻣﻮاردي ﻛـﻪ اﻣـﺮوزه ﻣـﺎ از اﻳـﻦ ﺗﻜﻨﻮﻟـﻮژي‬ ‫ﻣﻴﺪاﻧﻴﻢ ﺗﻐﻴﻴﺮ ﻧﺨﻮاﻫﺪ ﻛﺮد‪ ،‬اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ روز ﺑﻪ روز ﺗﻜﻨﻮﻟﻮژﻳﻬﺎي ﺟﺪﻳﺪ ﺗﺮي در ﺣﺎل ﺗﻮﺳﻌﻪ ﻫﺴﺘﻨﺪ‪ ،‬ﺑﻪ ﻳﻘﻴﻦ اﻳﻦ ﻣﻮارد ﺑﻪ ‪.NET‬‬ ‫اﺿﺎﻓﻪ ﺷﺪه و ﻳﺎ ﻣﻮاردي از آن ﺣﺬف ﺧﻮاﻫﻨﺪ ﺷﺪ‪.‬‬ ‫ﻗﺒﻞ از ﭘﻴﺪاﻳﺶ اﻳﻨﺘﺮﻧﺖ ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﺒﺘﻨﻲ ﺑﺮ ﭼﻨﺪ ﻓﺮم وﻳﻨﺪوزي و ﺑﺪون ارﺗﺒﺎط ﺑﺎ ﺟﻬﺎن ﺧﺎرج ﺑﻮد‪ .‬اﻣﺎ ﺑـﺎ ﭘﻴـﺪاﻳﺶ اﻳﻨﺘﺮﻧـﺖ ﺷـﺎﻫﺪ‬ ‫ﮔﺴﺘﺮش روزاﻓﺰون ﻧﺮم اﻓﺰارﻫﺎي ﺗﺤﺖ وب و ﻧﻴﺰ ﺗﺤﺖ ﺷﺒﻜﻪ ﻫﺴﺘﻴﻢ ﻛﻪ ﻣﻮﺟﺐ ﺗﻐﻴﻴﺮات ﺑﺴﻴﺎري در دﻧﻴﺎي اﻣﺮوزه ﺷﺪه اﻧﺪ‪.‬‬ ‫در ﮔﺬﺷﺘﻪ ﺑﻴﺸﺘﺮ ﺳﺎﻳﺘﻬﺎي وب ﺷﺎﻣﻞ ﺻﻔﺤﺎت اﻳﺴﺘﺎ ﺑﻮدﻧﺪ ﻛﻪ ﺑﺎ اراﺋﻪ ي ﭼﻨﺪﻳﻦ ﺻﻔﺤﻪ اﻃﻼﻋﺎت ﻛﻪ ﺑﻪ ﻳﻜـﺪﻳﮕﺮ ﻟﻴﻨـﻚ ﺷـﺪه ﺑﻮدﻧـﺪ‪،‬‬ ‫ﻧﻴﺎزﻫﺎي ﻛﺎرﺑﺮان را ﺑﺮﻃﺮف ﻣﻲ ﻛﺮدﻧﺪ‪ .‬اﻣﺎ ﺑﺎ ﮔﺴﺘﺮش روز اﻓﺰون اﻳﻨﺘﺮﻧﺖ ﻛﺎرﺑﺮان ﻧﻴﺎز ﺑﻪ ﺻﻔﺤﺎت ﭘﻮﻳﺎﻳﻲ ﻛﻪ اﻃﻼﻋﺎت ﺧﺎص ﺧﻮدﺷـﺎن‬ ‫را ﻧﻤﺎﻳﺶ دﻫﺪ را روز ﺑﻪ روز ﺑﻴﺸﺘﺮ اﺣﺴﺎس ﻣﻲ ﻛﺮدﻧﺪ‪.‬‬

‫ﭘﺬﻳﺮش اﺳﺘﺎﻧﺪاردﻫﺎي ﻫﻤﮕﺎﻧﻲ‪:‬‬ ‫ﻳﻜﻲ ار ﻣﻬﻤﺘﺮﻳﻦ ﺟﻨﺒﻪ ﻫﺎي ‪ .NET‬ﭘﺬﻳﺮش اﺳﺘﺎﻧﺪاردﻫﺎي ﺻﻨﻌﺘﻲ ﻫﻤﮕﺎﻧﻲ ﺗﻮﺳﻂ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ اﺳﺖ ﻛﻪ ‪ XML‬ﻳﻜـﻲ از ﻣﻬﻤﺘـﺮﻳﻦ‬ ‫آﻧﻬﺎ اﺳﺖ‪ .‬ﺗﺼﻮر ﺑﺮﺧﻲ از اﻓﺮاد از اﻳﻦ ﻣﻮرد اﻳﻦ اﺳﺖ ﻛﻪ ‪ XML‬ﭘﻴﺸﺮﻓﺘﻪ ﺗﺮﻳﻦ ﺗﻜﻨﻮﻟﻮژي ﻋﺼﺮ ﺣﺎﺿﺮ اﺳﺖ‪ ،‬ﻛﻪ ﻗﻄﻌﺎ اﻳﻦ اﻣﺮ ﺑﺮداﺷـﺘﻲ‬ ‫ﻧﺎدرﺳﺖ اﺳﺖ‪ .‬اﻣﺎ ‪ XML‬ﻳﻜﻲ از ﺑﻬﺘﺮﻳﻦ راﻫﻬﺎي ﻣﻮﺟﻮد ﺑﺮاي ﻳﻜﭙﺎرﭼﻪ ﺳﺎزي ﺳﻴﺴﺘﻤﻬﺎي ﻧﺎ ﻣﺘﺠﺎﻧﺲ ﻣﺤﺴﻮب ﻣﻴﺸﻮد‪.‬‬ ‫ﺑﺰودي ﺗﻤﺎﻣﻲ ﺳﺮورﻫﺎي ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﺑﻪ ﻳﻚ ﺳﺮور ‪ .NET‬ﺗﺒﺪﻳﻞ ﺧﻮاﻫﻨﺪ ﺷﺪ ﻛﻪ ‪ XML‬و ﭘﻠﺖ ﻓﺮم ‪ .NET‬را ﻛﺎﻣﻼً ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ‬ ‫ﻛﻨﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﻪ وﺳﻴﻠﻪ ﭘﻴﺎده ﺳﺎزي ﭘﺮوﺗﻜﻠﻬﺎي اﺳﺘﺎﻧﺪارد ﺗﻮﺳﻂ اﻳﻦ ﺳﺮور ﻫﺎ‪ ،‬ﺑﺮﻧﺎﻣﻪ ﻫﺎي اراﺋﻪ ﺷﺪه ﻣﺒﺘﻨﻲ ﺑﺮ ﺳﺮورﻫﺎي ﻣﺎﻳﻜﺮوﺳـﺎﻓﺖ‬ ‫ﻗﺪرت ﺗﻌﺎﻣﻞ ﺑﺎ ﭘﻠﺖ ﻓﺮﻣﻬﺎي دﻳﮕﺮ را ﻧﻴﺰ ﺧﻮاﻫﻨﺪ داﺷﺖ‪ .‬در ﺟﺪول زﻳﺮ ﻟﻴﺴﺘﻲ از ﺳﺮور ﻫﺎي ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ و ﻫﻤﭽﻨﻴﻦ ﺗﻮﺿﻴﺢ ﻛﺎرﺑﺮد آﻧﻬﺎ‬ ‫ذﻛﺮ ﺷﺪه اﺳﺖ‪.‬‬ ‫ﺳﺮور‬ ‫‪Microsoft Application Center Server 2000‬‬

‫‪Microsoft BizTalk Server 2000‬‬

‫‪Microsoft Commerce Server 2000‬‬

‫‪Microsoft Exchange Server 2000‬‬

‫‪Microsoft Host Integration 2000‬‬ ‫‪Internet Security And Acceleration 2000‬‬ ‫‪Microsoft SQL Server 2000‬‬

‫ﺷﺮح‬ ‫اﻳﻦ ﺳﺮور ﺑﺮﻧﺎﻣﻪ ﻫـﺎي ﻣﺒﺘﻨـﻲ ﺑـﺮ وب را ﺗﻮزﻳـﻊ‬ ‫ﻛﺮده و ﻫﻤﭽﻨﻴﻦ ﺳﺮور ﻫﺎ را ﺑﻪ ﺻﻮرت ﮔﺮوﻫـﻲ‬ ‫ﻣﺪﻳﺮﻳﺖ ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﭘﺮدازش ﻫﺎي ﺗﺠﺎري را ﭘﻴﺎده ﺳﺎزي ﻣـﻲ ﻛﻨـﺪ و‬ ‫اﻃﻼﻋﺎت را ﺑـﻪ وﺳـﻴﻠﻪ ﻳـﻚ راﺑـﻂ اﺳـﺘﺎﻧﺪارد و‬ ‫ﭘﺬﻳﺮﻓﺘﻪ ﺷﺪه اراﺋﻪ ﻣﻲ دﻫﺪ‪.‬‬ ‫ﺑـﺮاي اﻳﺠــﺎد ﺑﺮﻧﺎﻣــﻪ ﻫـﺎي ﺗﺠــﺎرت اﻟﻜﺘﺮوﻧﻴــﻚ‬ ‫اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد‪.‬‬ ‫ﻗﺎﺑﻠﻴﺖ اﻧﺠﺎم ﻣﺒﺎدﻻت از ﻃﺮﻳﻖ اﻳﻨﺘﺮﻧﺖ را ﻓﺮاﻫﻢ‬ ‫ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﺗﻌﺎﻣﻞ ﺑﺎ ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎي ﺑﺰرگ را ﺑﺮﻗﺮار ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﺑﻪ ﻋﻨﻮان ﻳﻚ دﻳﻮار آﺗﺶ ﻋﻤﻞ ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﺳﺮوﻳﺴﻬﺎي ﺗﺠﺰﻳـﻪ و ﺗﺤﻠﻴـﻞ و ﻧﻴـﺰ ﻧﮕـﻪ داري‬ ‫ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را اراﺋﻪ ﻣﻲ دﻫﺪ‪.‬‬

‫‪٩٠٥‬‬

‫ﺳﺮوﻳﺲ ﻫﺎي وب‪:‬‬ ‫ﻳﻜﻲ از ﻋﻮاﻣﻠﻲ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﻛﺎﻣﻼً ﺟﺪﻳﺪ ﺑﻪ ﻧﻈﺮ ﺑﺮﺳﺪ وب ﺳﺮوﻳﺲ ﻫﺎ ﻫﺴﺘﻨﺪ‪ .‬وب ﺳـﺮوﻳﺲ ﻫـﺎ در ﺣﻘﻴﻘـﺖ اﺻـﻮﻟﻲ ﻫـﺴﺘﻨﺪ ﻛـﻪ‬ ‫زﻳﺮﺳﺎﺧﺖ ﺑﻴﺸﺘﺮ اﺳﺘﺮاﺗﮋي ﻫﺎي ‪ .NET‬را ﺗﺸﻜﻴﻞ ﻣﻲ دﻫﻨﺪ و ﺑﻪ ﺟﺮات ﻣﻲ ﺗﻮان ﮔﻔﺖ ﻛﻪ ﻫﺪف اﺻﻠﻲ از اﻳﺠﺎد ‪ .NET‬ﺑـﻪ ﺷـﻤﺎر‬ ‫ﻣﻲ روﻧﺪ‪ .‬وب ﺳﺮوﻳﺲ ﻫﺎ ﺳﺮوﻳﺲ ﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﺤﺖ اﻳﻨﺘﺮﻧﺖ اراﺋﻪ ﺷﺪه و ﺗﻮﺳﻂ دﻳﮕﺮ وب ﺳـﺮوﻳﺲ ﻫـﺎ ﻳـﺎ‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه اﺳﺘﻔﺎده ﻣﻲ ﺷﻮﻧﺪ‪ .‬وب ﺳﺮوﻳﺲ ﻫﺎ ﺑﺮﭘﺎﻳﻪ اﺑﺰارﻫﺎي اﺳﺘﺎﻧﺪارد ﻣﺜـﻞ ‪ XML‬و ‪ HTTP‬ﺗﻮﻟﻴـﺪ ﻣـﻲ ﺷـﻮﻧﺪ و‬ ‫ﻣﺴﺘﻘﻞ از ﭘﻠﺖ ﻓﺮم و ﻣﺤﻴﻂ ﺗﻮﻟﻴﺪ آﻧﻬﺎ ﻣﻲ ﺑﺎﺷﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي اﺳﺘﻔﺎده از آﻧﻬﺎ ﻧﻴﺎزي ﺑﻪ ‪ .NET‬ﻧﻴﺴﺖ‪.‬‬ ‫ﺑﺎ ﺗﺮﻛﻴﺐ ‪ HTTP‬و ‪ XML‬و ﺗﻮﻟﻴﺪ ‪ .NET,SOAP‬ﻳﻚ راه ﺣﻞ ﻗﺎﺑﻞ اﻋﺘﻤﺎد را ﺑﺮاي ﺗﻮﺳﻌﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب اراﺋﻪ ﻣﻲ دﻫﺪ‪.‬‬ ‫اﺳﺘﺎﻧﺪارد ‪ SOAP‬ﻛﻪ در ﺣﻘﻴﻘﺖ اﻧﺘﻘﺎل داده ﻫﺎي ‪ XML‬ﺑﻪ وﺳﻴﻠﻪ ‪ HTTP‬اﺳﺖ‪ ،‬ﭘﺎﻳﻪ و اﺳﺎس ﺳـﺮوﻳﺲ ﻫـﺎي وب ﻣﺤـﺴﻮب ﻣـﻲ‬ ‫ﺷﻮد‪ .‬ﻧﻪ ﺗﻨﻬﺎ ‪ SOAP‬ﻣﻲ ﺗﻮاﻧﺪ از اﻣﻜﺎﻧﺎت ‪ COM‬ﺑﻬﺮﻣﻨﺪ ﺷﻮد ﺑﻠﻜﻪ ﻗﺪرت ﺗﻌﺎﻣﻞ و اﺳـﺘﻔﺎده از ﻣﺰاﻳـﺎي اﺳـﺘﺎﻧﺪاردﻫﺎي دﻳﮕـﺮي ﻣﺜـﻞ‬ ‫‪ CORBA‬را ﻧﻴﺰ دارد‪.‬‬

‫وﻳﮋﮔﻲ ﻫﺎي ﻣﺤﻴﻂ ﺗﻮﺳﻌﻪ ‪: Visual Stadio.NET‬‬ ‫ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻇﺎﻫﺮ ‪ VS.NET‬ﻧﺴﺒﺖ ﺑﻪ ﻗﺒﻞ ﺗﻐﻴﻴﺮات ﻗﺎﺑﻞ ﻣﻼﺣﻈﻪ اي ﻛﺮده اﺳﺖ‪ ،‬ﭘﻴﺸﺮﻓﺖ اﺻﻠﻲ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻋﻠـﺖ ﺗﻜﻨﻮﻟـﻮژي‬ ‫ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﻣﺤﻴﻂ ﺗﻮﺳﻌﻪ ي ‪ .NET‬ﺑﺮ ﭘﺎﻳﻪ آﻧﻬﺎ اﺳﺘﻮار اﺳﺖ‪ .‬در ﺣﻘﻴﻘﺖ اﻳﻦ ﺗﻜﻨﻮﻟﻮژي ﻫﺎ اﺳﺖ ﻛـﻪ ﺑﺎﻋـﺚ ﺗﻮﻟﻴـﺪ ﺳـﺮﻳﻊ ﺑﺮﻧﺎﻣـﻪ‬ ‫ﻫﻤﺮاه ﺑﺎ ﭘﺎﻳﺪاري و ﻗﺎﺑﻠﻴﺖ اﻋﺘﻤﺎد ﻣﺤﻴﻂ ﻫﺎي ﺗﻮﺳﻌﻪ ﻛﻼﺳﻴﻚ ﻣﺎﻧﻨﺪ ‪ C++‬ﻣﻲ ﺷﻮد‪.‬‬

‫‪:Common Language Runtime‬‬ ‫ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﭘﻴﺸﺮﻓﺖ ﻫﺎي وﻳﮋوال اﺳﺘﻮدﻳﻮ اﺿﺎﻓﻪ ﺷﺪن ﻳﻚ ﻣﺤﻴﻂ ﻣﺪﻳﺮﻳﺖ زﻣﺎن اﺟﺮاي ﻣﺴﺘﻘﻞ از زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﺳﺖ ﻛـﻪ‬ ‫‪ Common Language Runtime‬ﻳﺎ ‪ CLR‬ﻧﺎﻣﻴﺪه ﻣﻲ ﺷﻮد‪ CLR .‬ﻗﺪرت ﻃﺮاﺣﻲ ﺑﻪ ﻫـﺮ زﺑـﺎﻧﻲ را در ﻳـﻚ ﻣﺤـﻴﻂ‬ ‫ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﻣﻲ دﻫﺪ ﻛﻪ ﻛﻤﺘﺮ دﭼﺎر ﻧﺸﺴﺖ ﺣﺎﻓﻈﻪ ﻣﻲ ﺷﻮد و ﻳﺎ ﺑﺎ ﻓﺮاﻫﻢ آوردن ‪ metadata‬ﺑﺮاي ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎ ﺑﻪ آﻧﻬـﺎ اﺟـﺎزه‬ ‫ﺧﻄﺎ ﻳﺎﺑﻲ و ﻳﺎ اﻣﻮر دﻳﮕﺮ را ﻣﻲ دﻫﺪ‪.‬‬ ‫وﻳﮋﮔﻲ ﻫﺎي ﻛﻨﺘﺮل ﻧﺴﺨﻪ ي ﺑﺮﻧﺎﻣﻪ ﻫﺎ و ﻳﺎ اﻣﻨﻴﺖ آﻧﻬﺎ در ‪ ،CLR‬ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﺻﻮرت ﻳﻚ ﺳﺮوﻳﺲ ﺑﺴﻴﺎر ﺳـﺎده ﺗـﺮ ﻣـﻲ ﻛﻨـﺪ‪.‬‬ ‫ﻫﻤﭽﻨﻴﻦ ‪ CLR‬ﺑﺎﻋﺚ ﺳﺎدﮔﻲ و ﻧﻴﺰ ﺗﺴﺮﻳﻊ ﺗﻮﻟﻴﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ﻧﺴﺒﺖ ﺑﻪ ﻧﺴﺨﻪ ﻫﺎي ﻗﺒﻠﻲ ﻣﻲ ﺷﻮد‪ .‬در ﺑﺎره ي اﻳﻦ ﻗﺴﻤﺖ از‬ ‫‪ .NET Framework‬در ﺿﻤﻴﻤﻪ ي ﺑﻌﺪ ﺻﺤﺒﺖ ﺷﺪه اﺳﺖ‪.‬‬

‫زﺑﺎن ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ‪:.NET‬‬ ‫ﺑﺎ ﻇﻬﻮر ‪ .NET‬ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ زﺑﺎن ‪ C#‬را ﻛﻪ ﺗﺮﻛﻴﺒﻲ از ﻗﺪرت ‪ C++‬و راﺣﺘﻲ وﻳﮋوال ﺑﻴﺴﻴﻚ ﺑﻮد ﻣﻌﺮﻓﻲ ﻛﺮد اﻣﺎ ﺣﻘﻴﻘﺖ در ﻣـﻮرد‬ ‫دو زﺑﺎن اﺻﻠﻲ ‪ .NET‬ﺑﺪﻳﻦ ﺻﻮرت اﺳﺖ ﻛﻪ ‪ C#‬و وﻳﮋوال ﺑﻴﺴﻴﻚ از ﻟﺤﺎظ اﻣﻜﺎﻧﺎت ﺑﺴﻴﺎر ﻣﺸﺎﺑﻪ اﻧﺪ‪.‬‬

‫‪٩٠٦‬‬

‫ﺗﻤﺎﻣﻲ زﺑﺎن ﻫﺎي ‪ .NET‬ﻳﻚ زﻳﺮ ﻣﺠﻤﻮﻋﻪ از اﻣﻜﺎﻧﺎت ‪ CLR‬را اراﺋﻪ ﻣﻲ دﻫﻨﺪ‪ ،‬اﻣﺎ ﺳﻄﺢ ﭘﺸﺘﻴﺒﺎﻧﻲ آﻧﻬﺎ از ‪ CLR‬ﻣﺘﻔـﺎوت اﺳـﺖ‪.1‬‬ ‫ﺑﺮاي ﻃﺮاﺣﻲ ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﻧﺘﺨﺎب زﺑﺎن ﺗﻔﺎوت ﭼﻨﺪاﻧﻲ ﻧﺪارد‪ .‬اﻣﺎ ﺑﺎ وﺟﻮد ﻗﺎﺑﻠﻴﺖ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺎ ﺑﻴﺶ از ‪ 20‬زﺑﺎن در ‪ .NET‬ﻣـﻲ‬ ‫ﺗﻮان ﺑﺎ در ﻧﻈﺮ ﮔﺮﻓﺘﻦ اﻳﻨﻜﻪ ﺑﻌﻀﻲ از آﻧﻬﺎ ﺑﺮاي ﻣﺤﺎﺳﺒﺎت ﻋﻠﻤﻲ ﺑﺴﻴﺎر ﻣﻨﺎﺳﺐ اﻧﺪ و ﺑﻌﻀﻲ دﻳﮕﺮ ﺑﺮاي ﭘـﺮدازش ورودي‪/‬ﺧﺮوﺟـﻲ اﻳـﺪه‬ ‫آل ﻫﺴﺘﻨﺪ زﺑﺎن ﻣﻨﺎﺳﺒﻲ را ﺑﺮاي ﻧﻮﺷﺘﻦ ﻳﻚ ﺑﺮﻧﺎﻣﻪ اﻧﺘﺨﺎب ﻛﺮد‪.‬‬ ‫ﻧﻜﺘﻪ‪ :‬ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ‪ C#‬و ‪ VB‬ﻛﺎﻣﻼ ﺷﻲ ﮔﺮا ﻫﺴﺘﻨﺪ اﻣﺎ ﻣﻤﻜﻦ اﺳﺖ در ﺷﺮاﻳﻄﻲ ‪ VC++‬ﻛﺎراﻳﻲ ﺑﻴﺸﺘﺮي را اراﺋﻪ دﻫﺪ‪.‬‬

‫‪:Intermediate Language‬‬ ‫اﻳﻦ زﺑﺎن ﻛﻪ در ‪ .NET‬ﻳﻚ زﺑﺎن ﺳﻄﺢ ﻣﻴﺎﻧﻲ ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد‪ ،‬ﻣﺴﺘﻘﻞ از ﺳﺎﺧﺘﺎر دروﻧﻲ ﭘﺮدازﻧﺪه اﺳﺖ‪ .‬ﺗﻤﺎم ﻛﺪ ﻫﺎي ‪ .NET‬در‬ ‫اﺑﺘﺪا ﺑﻪ اﻳﻦ زﺑﺎن ﻛﺎﻣﭙﺎﻳﻞ ﻣﻲ ﺷﻮﻧﺪ و ﺑﻪ ﻋﻠﺖ ﻣﺴﺘﻘﻞ ﺑﻮدن اﻳﻦ زﺑﺎن از ﭘﺮدازﻧﺪه‪ ،‬ﻛﺎﻣﭙﻮﻧﻨﺖ ﺗﻮﻟﻴﺪي ﻣﻲ ﺗﻮاﻧﺪ ﻣﺴﺘﻘﻞ از ﭘﻠﺖ ﻓﺮم ﻋﻤﻞ‬ ‫ﻛﻨﺪ‪ .‬از آﻧﺠﺎ ﻛﻪ ‪ IL‬ﻧﻴﺰ دﺳﺘﻮراﻟﻌﻤﻞ ﻫﺎي ﺧﻮد را دارد‪ ،‬ﻛﺪ ﻫﺎي ‪ IL‬ﻗﺒﻞ از اﺟﺮا در ﻫﺮ ﭘﻠﺖ ﻓﺮﻣﻲ ﺑﺎﻳﺪ ﺑـﺎ اﺳـﺘﻔﺎده از ﻛﺎﻣﭙـﺎﻳﻠﺮ ﻫـﺎي‬ ‫ﻣﺨﺼﻮص آن ﭘﻠﺖ ﻓﺮم ﺑﻪ ﺻﻮرت دﺳﺘﻮرﻫﺎي ﭘﺮدازﻧﺪه ي ﻣﺤﻠﻲ در آﻳﺪ ﻛﻪ اﻳﻦ اﻣﺮ ﺗﻮﺳﻂ ‪ JIT‬ﺻﻮرت ﻣﻲ ﮔﻴﺮد‪.‬‬

‫ﺗﻜﺎﻣﻞ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻻﻳﻪ اي‪:‬‬ ‫ﻳﻜﻲ از ﻣﺰاﻳﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺒﺘﻨﻲ ﺑﺮ ﻛﺎﻣﭙﻮﻧﻨﺖ‪ ،‬ﺗﻮاﻧﺎﻳﻲ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﺑﺮاي ﺗﻘﺴﻴﻢ ﻋﻤﻠﻜﺮد ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﭼﻨﺪ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻗﺎﺑـﻞ ﻣـﺪﻳﺮﻳﺖ و‬ ‫ﻋﻤﻮﻣﻲ اﺳﺖ‪ .‬اﻳﻦ اﻣﺮ ﺑﺎﻋﺚ اﺳﺘﻔﺎده ﻣﺠﺪد از ﻛﺪ و اﻧﻌﻄﺎف ﭘﺬﻳﺮي ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺷﻮد‪ .‬ﻫﻤﭽﻨﻴﻦ ﻳﻜﻲ از ﻣﺰاﻳﺎي اﺻـﻠﻲ اﻳـﻦ ﻣـﺪل ﻗـﺪرت‬ ‫ﺗﻘﺴﻴﻢ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﭼﻨﺪ ﻻﻳﻪ ﻣﻮازي اﺳﺖ ﺑﻪ ﮔﻮﻧﻪ اي ﻛﻪ ﺑﺮﻧﺎﻣﻪ را ﺑﺮ اﺳﺎس ﺳﺮوﻳﺲ ﻫﺎي آن ﺑﻪ ﭼﻨﺪ ﺑﺨﺶ ﻣﻨﻄﻘﻲ ﺗﻘﺴﻴﻢ ﻣﻲ ﻛﻨﺪ‪.‬‬

‫ﺗﻌﺮﻳﻒ‪:‬‬ ‫ﻳﻚ ﻻﻳﻪ ﺑﺮﻧﺎﻣﻪ‪ 2‬ﺑﻪ ﻳﻚ ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ ﻛﻪ ﺑﻪ ﺻﻮرت ﻣﻮازي ﺑﺎ دﻳﮕﺮ ﻗﺴﻤﺖ ﻫﺎ در ﺣﺎل ﺗﻌﺎﻣﻞ اﺳﺖ ﮔﻔﺘﻪ ﻣﻲ ﺷﻮد‪ .‬ﻫﺮ ﻻﻳﻪ ي در‬ ‫ﺣﺎل ﻛﺎر در ﺑﺮﻧﺎﻣﻪ‪ ،‬وﻇﻴﻔﻪ ﺧﺎﺻﻲ را اﻧﺠﺎم ﻣﻲ دﻫﺪ‪ .‬ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﭘﻴﺎده ﺳﺎزي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﭼﻨﺪ ﻻﻳﻪ ﻋﺒﺎرت اﺳﺖ از ﺗﻘـﺴﻴﻢ ﻓﻴﺰﻳﻜـﻲ‬ ‫ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﭼﻨﺪ ﻗﺴﻤﺖ و ﺗﻮزﻳﻊ ﻫﺮ ﻗﺴﻤﺖ ﺑﺮ روي ﻳﻚ ﺳﺮور‪.‬‬ ‫ﻣﺪل ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻻﻳﻪ اي در ﺣﻘﻴﻘﺖ ﺑﺮاي ﺣﻞ ﺑﺴﻴﺎري از ﻣﺸﻜﻼت ﺑﺮﻧﺎﻣﻪ ﻫﺎي اﻣﺮوزي اﻳﺠﺎد ﺷﺪه اﺳﺖ‪ .‬از اﻳﻦ دﺳﺘﻪ ﻣﺸﻜﻼت ﻣﻲ‬ ‫ﺗﻮان از ﻣﺪﻳﺮﻳﺖ ﻣﺘﻤﺮﻛﺰ‪ ،‬ﻣﺤﺎﺳﺒﺎت ﺗﻮزﻳﻊ ﺷﺪه‪ ،‬ﻛﺎراﻳﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎ و ﻣﻘﻴﺎس ﭘﺬﻳﺮي آﻧﻬﺎ ﻧﺎم ﺑﺮد‪.‬‬

‫ﻣﺪﻳﺮﻳﺖ ﻣﺘﻤﺮﻛﺰ‪:‬‬ ‫در ﻳﻚ ﻣﺤﻴﻂ ﻛﻪ ﺑﻪ ﺻﻮرت ﻣﺘﻤﺮﻛﺰ ﻣﺪﻳﺮﻳﺖ ﻣﻲ ﺷﻮد‪ ،‬ﺗﻐﻴﻴﺮات ﻣﻮردﻧﻈﺮ در ﻳﻚ ﻗﺴﻤﺖ ﻣﺮﻛﺰي ﺻﻮرت ﻣﻲ ﮔﻴﺮﻧﺪ و اﻳﻦ ﺗﻐﻴﻴـﺮات ﺑـﻪ‬ ‫ﺳﺮﺗﺎﺳﺮ ﺳﻴﺴﺘﻢ ﺗﻮزﻳﻊ ﻣﻲ ﺷﻮﻧﺪ‪ .‬ﻳﻚ ﺳﻴﺴﺘﻢ ﺑﺎ ﻣﺪﻳﺮﻳﺖ ﻣﺮﻛﺰي از ﺗﻌﺪاد ﻧﻘﺎط ﻣﺤﺪودﻳﺖ ﻗﺎﺑﻞ ﻣﺪﻳﺮﻳﺖ اﺳﺖ‪.‬‬ ‫‪ 1‬ﺑﺮاي اﻃﻼﻋﺎت ﺑﻴﺸﺘﺮ در اﻳﻦ ﻣﻮرد ﺑﻪ ﺑﺨﺶ "ﺧﺼﻮﺻﻴﺎت ﻋﻤﻮﻣﻲ زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ" در ﺿﻤﻴﻤﻪ ي ﺑﻌﺪ ﻣﺮاﺟﻌﻪ ﻛﻨﻴﺪ‪.‬‬ ‫‪Application Tier‬‬

‫‪2‬‬

‫‪٩٠٧‬‬

‫ﺑﺮاي ﻧﻤﻮﻧﻪ ‪ ،MS Application Center 2000‬ﻳﻚ اﺑﺰار ﺑﺮاي ﺗﻮزﻳﻊ و ﻣﺪﻳﺮﻳﺖ ﺑﺮﻧﺎﻣﻪ ﻫﺎ‪ ،‬ﺳﻴﺴﺘﻤﻲ اﺳﺖ ﻛـﻪ‬ ‫از ﻣﺪﻳﺮﻳﺖ ﻣﺘﻤﺮﻛﺰ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ‪ Application Center .‬ﺑﻪ ﻋﻠﺖ ﻣﺪﻳﺮﻳﺖ ﮔﺮوﻫﻲ ﺳﺮور ﻫﺎ ﺑﺎﻋﺚ اﻓﺰاﻳﺶ ﻣﻘﻴﺎس‬ ‫ﭘﺬﻳﺮي و ﻗﺎﺑﻠﻴﺖ اﻋﺘﻤﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﻲ ﺷﻮد‪ .‬ﻗﺎﺑﻠﻴﺖ ﻣﻬﻤﺘﺮ اﻳﻦ ﺳﻴﺴﺘﻢ در اﻳﻦ اﺳﺖ ﻛﻪ اﮔﺮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ در ﭼﻨﺪ ﺳﺮور اﺟـﺮا ﺷـﻮد و ﺗﻤـﺎم‬ ‫آن ﺳﺮور ﻫﺎ ﺑﻪ وﺳﻴﻠﻪ ي اﻳﻦ ﺳﻴﺴﺘﻢ ﺑﻪ ﺻﻮرت ﮔﺮوﻫﻲ ﻣﺪﻳﺮﻳﺖ ﺷﻮد‪ ،‬ﻣﻲ ﺗﻮان از اﻳﻦ ﺳﻴـﺴﺘﻢ ﺑـﺮاي ﻣـﺪﻳﺮﻳﺖ ﻣﺮﻛـﺰي ﺑﺮﻧﺎﻣـﻪ ﻧﻴـﺰ‬ ‫اﺳﺘﻔﺎده ﻛﺮد‪.‬‬ ‫ﺳﻴﺴﺘﻢ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﻣﺘﻤﺮﻛﺰ‪ ،‬ﻋﻤﻮﻣﺎً ﻣﺪﻳﺮﻳﺖ ﻳﻚ ﮔﺮوه از ﺳﺮور ﻫﺎ را ﺑﻪ ﺳﺎدﮔﻲ ﻛﻨﺘﺮل ﻳﻚ ﺳﺮور ﻣﺴﺘﻘﻞ اﻧﺠﺎم ﻣﻲ دﻫﻨـﺪ و زﻣـﺎﻧﻲ‬ ‫ﻛﻪ ﻳﻜﻲ از ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﺗﻐﻴﻴﺮ ﻛﻨﺪ ﻳﺎ ﺑﻪ روز ﺷﻮد‪ ،‬اﻳﻦ ﺗﻐﻴﻴﺮات ﺑﻴﻦ ﺗﻤﺎم ﺳﺮور ﻫﺎﻳﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻣﺬﻛﻮر را ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣـﻲ ﻛﻨﻨـﺪ‬ ‫ﺗﻮزﻳﻊ ﻣﻲ ﺷﻮد‪.‬‬

‫ﻣﺤﺎﺳﺒﺎت ﺗﻮزﻳﻊ ﺷﺪه‪:‬‬ ‫در ﻳﻚ ﻣﺤﻴﻂ ﻣﺤﺎﺳﺒﺎت ﺗﻮزﻳﻊ ﺷﺪه‪ ،‬ﭘﺮدازش ﻫﺎ ﺑﻴﻦ ﭼﻨﺪ ﺳﻴﺴﺘﻢ و ﺣﺘﻲ در ﺻﻮرت ﻧﻴﺎز ﺑﻴﻦ ﭼﻨﺪ ﻣﻨﻄﻘﻪ ﺗﻘﺴﻴﻢ ﻣﻲ ﺷﻮد‪ .‬ﻫﺪف اﺻـﻠﻲ‬ ‫اﻳﻦ اﻣﺮ اﻓﺰاﻳﺶ ﻣﻘﻴﺎس ﭘﺬﻳﺮي و ﻛﺎراﻳﻲ ﺷﺒﻜﻪ‪ ،‬اﻓﺰاﻳﺶ ﻗﺪرت و ﺗﺤﻤﻞ ﻧﻘﺺ اﺳﺖ‪.‬‬

‫ﻛﺎراﻳﻲ‪:‬‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ ذﻛﺮ ﺷﺪ ﻣﻨﻈﻮر از ﻛﺎراﻳﻲ ﺗﻌﺪاد ﺳﻴﻜﻞ ﻫﺎي ﻣﺼﺮﻓﻲ ﺑﺮاي اﻧﺠﺎم ﻳﻚ وﻇﻴﻔﻪ ﺧﺎص اﺳﺖ‪ .‬ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻳﻚ وﻇﻴﻔﻪ ﻣﻤﻜﻦ‬ ‫اﺳﺖ ﺑﻪ ﺳﺮﻋﺖ اﻧﺠﺎم ﺷﻮد ﻛﻪ اﻳﻦ اﻣﺮ ﺣﺎﻛﻲ از ﻛﺎراﻳﻲ ﻗﺎﺑﻞ ﻗﺒﻮل ﺑﺮﻧﺎﻣﻪ اﺳﺖ‪ ،‬اﻣﺎ اﻳﻦ ﻛﺎراﻳﻲ ﺑﺎﻋﺚ ﻣﻘﻴﺎس ﭘﺬﻳﺮي ﺧﻮب ﺑﺮﻧﺎﻣﻪ ﻧﻤـﻲ‬ ‫ﺷﻮد‪ .‬ﻛﺎرﺑﺮان ﻫﻤﻴﺸﻪ ﻛﺎراﻳﻲ ﺑﺮﻧﺎﻣﻪ را در زﻣﺎن ﭘﺎﺳﺦ ﮔﻮﻳﻲ آن ﻣﻲ داﻧﻨﺪ‪ .‬زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺧﻮﺑﻲ ﻣﻘﻴﺎس ﭘﺬﻳﺮ ﻧﺒﺎﺷﺪ ﻛﺎرﺑﺮ ﺗﺼﻮر‬ ‫ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻛﺎراﻳﻲ ﺧﻮﺑﻲ ﻧﺪارد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ درك ﺗﻔﺎوت ﺑﻴﻦ ﻛﺎراﻳﻲ و ﻣﻘﻴﺎس ﭘﺬﻳﺮي از اﻫﻤﻴـﺖ ﺑـﺴﺰاﻳﻲ‬ ‫ﺑﺮﺧﻮردار اﺳﺖ‪.‬‬

‫ﻣﻘﻴﺎس ﭘﺬﻳﺮي‪:‬‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ ذﻛﺮ ﺷﺪ ﻣﻨﻈﻮر از ﻣﻘﻴﺎس ﭘﺬﻳﺮي ﺗﻌﺪاد ﻛﺎرﺑﺮاﻧﻲ اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﻳﻚ وﻇﻴﻔﻪ ﺧﺎص را ﺑـﻪ ﺻـﻮرت ﻫﻤﺰﻣـﺎن از ﺳﻴـﺴﺘﻢ‬ ‫درﺧﻮاﺳﺖ ﻛﻨﻨﺪ‪ .‬ﻧﻜﺘﻪ اﺻﻠﻲ در ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﻘﻴﺎس ﭘﺬﻳﺮ‪ ،‬ﻃﺮاﺣﻲ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎ ﺑﻪ ﺻﻮرﺗﻲ اﺳﺖ ﻛﻪ ﺑﺎ ﻛﻤﺘﺮﻳﻦ ﻣﻘﺪار اﺳـﺘﻔﺎده از‬ ‫ﻣﻨﺎﺑﻊ‪ ،‬ﻳﻚ وﻇﻴﻔﻪ ﺧﺎص را اﺟﺮا ﻛﻨﺪ‪ .‬ﻧﺘﻴﺠﻪ ي ﻣﻄﻠﻮب ﺑﺮﻧﺎﻣﻪ اي ﺧﻮاﻫﺪ ﺑﻮد ﻛﻪ ﺑﻪ ﺗﻌﺪاد ﻣﻮردﻧﻈﺮ از ﻛﺎرﺑﺮان‪ ،‬ﺑﻪ ﺻﻮرت ﻫﻤﺰﻣـﺎن و در‬ ‫ﻳﻚ زﻣﺎن ﻗﺎﺑﻞ ﻗﺒﻮل ﭘﺎﺳﺦ دﻫﺪ‪.‬‬

‫ﻗﻮاﻋﺪ و دﺳﺘﻮرات ﺗﺠﺎري‪:‬‬ ‫ﻣﻨﻈﻮر از ﻗﻮاﻋﺪ ﺗﺠﺎري در ﺣﻘﻴﻘﺖ ﻣﺤﺪودﻳﺖ ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﺗﺠﺎرت ﻣﻮردﻧﻈﺮ ﺑﺮ روي ﻳﻚ ﺑﺮﻧﺎﻣﻪ اﻋﻤﺎل ﻣﻲ ﻛﻨـﺪ‪ .‬ﻛـﺎرﺑﺮد اﻳـﻦ ﻗﻮاﻋـﺪ‬ ‫ﺗﺠﺎري ﺑﺮ روي ﺟﺎﻣﻌﻴﺖ و ﻳﻜﭙﺎرﭼﮕﻲ اﻃﻼﻋﺎت ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺗﺎﺛﻴﺮ ﻣﻲ ﮔﺬارد و ﻋﺪم اﺟﺮاي ﻛﺎﻓﻲ اﻳﻦ ﻗﻮاﻋﺪ ﻣﻮﺟﺐ ﺗﺎﺛﻴﺮات ﻣﻨﻔﻲ ﺑﺮﻧﺎﻣـﻪ‬

‫‪٩٠٨‬‬

‫ﻣﻲ ﺷﻮد‪ .‬ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻣﻤﻜﻦ اﺳﺖ ﻳﻚ راه دﻗﻴﻖ ﺑﺮاي ﭘﻴﺎده ﺳﺎزي اﻳﻦ ﻗﻮاﻋﺪ وﺟﻮد ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ‪ ،‬اﻣﺎ ﻫﻤـﻮاره راﻫﻬـﺎي ﻗﺎﺑـﻞ ﻗﺒـﻮﻟﻲ‬ ‫ﺑﺮاي اﺟﺮاي اﻳﻦ ﻗﻮاﻋﺪ ﺑﻪ ﺣﺪ ﻛﺎﻓﻲ وﺟﻮد دارد‪.‬‬

‫راﺣﺘﻲ ﻛﺎرﺑﺮ‪:‬‬ ‫در دﻧﻴﺎﻳﻲ ﻛﻪ درك ﺑﺼﺮي ﻳﻚ واﻗﻌﻴﺖ اﺳﺖ‪ ،‬ﺻﺮف زﻣﺎن و ﻫﺰﻳﻨﻪ ﺑﺮ روي ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﻣﻌﻤﺎري و ﻗﺪرت ﺧﻮﺑﻲ دارﻧﺪ اﻣﺎ اﺳﺘﻔﺎده از‬ ‫آﻧﻬﺎ ﻣﺸﻜﻞ اﺳﺖ ﺑﻲ ﺛﻤﺮ اﺳﺖ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺣﺘﻲ اﮔﺮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻛﺎراﻳﻲ ﺑﺴﻴﺎر ﺑﺎﻻﻳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ و ﺑﺘﻮاﻧﺪ ﺑـﻪ ﻃـﻮر ﻫﻤﺰﻣـﺎن ﺑـﻪ ‪100000‬‬ ‫ﻛﺎرﺑﺮ ﭘﺎﺳﺦ دﻫﺪ‪ ،‬اﻣﺎ ﻛﺎرﺑﺮان از اﺳﺘﻔﺎده از آن ﺑﺮﻧﺎﻣﻪ ﻧﻔﺮت داﺷﺘﻪ ﺑﺎﺷﻨﺪ‪ ،‬ﻧﻤﻲ ﺗﻮان آن را ﻳﻚ ﺑﺮﻧﺎﻣﻪ ي ﻗﺎﺑـﻞ ﻗﺒـﻮل داﻧـﺴﺖ‪ .‬ﺑـﺎ وﺟـﻮد‬ ‫اﻳﻨﻜﻪ اﻳﻦ ﻣﻄﺎﻟﺐ در اﻳﻦ ﻗﺴﻤﺖ ﺑﺮرﺳﻲ ﻧﻤﻲ ﺷﻮد‪ ،‬اﻣﺎ ﻣﺤﻴﻂ ﻫﺎي ﻃﺮاﺣﻲ ‪ .NET‬اﻳﺠﺎد ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﺑﺎ ﻇﺎﻫﺮ ﺑـﺴﻴﺎر زﻳﺒـﺎ را ﺗـﺎ ﺣـﺪ‬ ‫ﻣﻤﻜﻦ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﺳﺎده ﻛﺮده اﻧﺪ‪.‬‬

‫ﺑﺮﻧﺎﻣﻪ ﻫﺎي دو ﻻﻳﻪ‪:‬‬ ‫ﻣﺪل ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ دو ﻻﻳﻪ ﻋﻤﻮﻣﺎً ﺑﻪ ﻋﻨﻮان ﻣﺪل ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه‪ /‬ﺳﺮوﻳﺲ دﻫﻨﺪه ﻳﺎد ﻣﻲ ﺷﻮد و اﻳﻦ دو واژه ﺑﺎ ﻳﻜﺪﻳﮕﺮ ﻣﻌﺎدل اﻧﺪ‪ .‬در‬ ‫ﻣﺪل دو ﻻﻳﻪ‪ ،‬ﺑﺮﻧﺎﻣﻪ ي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﺗﻘﺎﺿﺎي اﻃﻼﻋﺎت ﻳﺎ ﺧﺪﻣﺎت را ﻣﺎﻧﻨﺪ ﭘﺴﺖ اﻟﻜﺘﺮوﻧﻴﻜﻲ‪ ،‬ﺑﻪ ﻳﻚ ﺳﺮور ﻳﺎ ﺳﺮوﻳﺲ ﻣﻲ دﻫﺪ‪.‬‬ ‫در ﻣﺤﻴﻂ ﻫﺎي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه‪ /‬ﺳﺮوﻳﺲ دﻫﻨﺪه ﻣﻌﻤﻮﻻ ﭘﺮدازش ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﻴﻦ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه و ﺳﺮوﻳﺲ دﻫﻨـﺪه ﺗﻘـﺴﻴﻢ ﻣـﻲ ﺷـﻮد‪.‬‬ ‫ﺑﺮﻧﺎﻣﻪ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه راﺑﻂ ﻛﺎرﺑﺮ را ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ و اﻃﻼﻋﺎت ﻻزم را از ﻛﺎرﺑﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ‪ .‬ﺑﺮﻧﺎﻣﻪ ﺳﺮور ﻫﻢ ﻣﻌﻤﻮﻻً ﺑـﺮ اﺳـﺎس‬ ‫اﻃﻼﻋﺎت درﻳﺎﻓﺖ ﺷﺪه از ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﺧﺪﻣﺎت ﻣﻨﺎﺳﺒﻲ را اراﺋﻪ ﻣﻲ دﻫﺪ‪.‬‬ ‫ﺷﻜﻞ زﻳﺮ ﻳﻚ ﻧﻤﻮﻧﻪ از اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ را ﻧﺸﺎن ﻣﻲ دﻫﺪ‪ .‬ﺑﺎ اﻳﻦ ﻛﻪ ﻣﺪل ﻧﻤﺎﻳﺶ داده ﺷﺪه در ﺷﻜﻞ ﻛـﺎﻣﻼً درﺳـﺖ اﺳـﺖ اﻣـﺎ در ﺣﺎﻟـﺖ‬ ‫واﻗﻌﻲ ﺗﻌﺪاد ﻛﺎرﺑﺮاﻧﻲ ﻛﻪ از ﻳﻚ ﺳﺮور اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﺑﻴﺸﺘﺮ از ﭼﻴﺰي اﺳﺖ ﻛﻪ در ﺷﻜﻞ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ‪.‬‬

‫ﻣﺪل دو ﻻﻳﻪ )ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه‪/‬ﺳﺮوﻳﺲ دﻫﻨﺪه(‬

‫ﻣﺪﻳﺮﻳﺖ ﻛﺪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي دو ﻻﻳﻪ‪:‬‬ ‫دو ﺟﻨﺒﻪ ي ﻣﺨﺘﻠﻒ در ﻣﺪﻳﺮﻳﺖ ﻛﺪ ﺑﺮاي ﻣﺤﻴﻂ ﻫﺎي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه‪ /‬ﺳﺮوﻳﺲ دﻫﻨﺪه وﺟﻮد دارد ﻛـﻪ ﻋﺒـﺎرت اﻧـﺪ از ﻣـﺪﻳﺮﻳﺖ ﻛـﺪ در‬ ‫ﻗﺴﻤﺖ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه و ﻣﺪﻳﺮﻳﺖ ﻛﺪ در ﻗﺴﻤﺖ ﺳﺮوﻳﺲ دﻫﻨﺪه‪.‬‬ ‫ﻣﺪﻳﺮﻳﺖ ﻛﺪ در ﻗﺴﻤﺖ ﺳﺮور ﻫﺎ ﻋﻤﻮﻣﺎً واﺿﺢ و روﺷﻦ اﺳﺖ‪ .‬ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﺳﺮور ﻣﻮرد ﻧﻈﺮ ﻋﻀﻮ ﻳﻚ ﮔﺮوه از ﺳـﺮور ﻫـﺎ ﻧﻴـﺴﺖ‪ ،‬ﺗﻮزﻳـﻊ‬ ‫ﺗﻐﻴﻴﺮات اﻋﻤﺎل ﺷﺪه ﺑﺮ روي ﻛﺪ ﻓﻘﻂ در ﻳﻚ ﻗﺴﻤﺖ اﻧﺠﺎم ﻣﻲ ﺷﻮد‪ .‬اﻣﺎ اﮔﺮ ﺳﺮور ﻋﻀﻮ ﻳﻚ ﮔﺮوه از ﺳﺮور ﻫﺎ ﺑﺎﺷﺪ‪ ،‬ﺗﻐﻴﻴﺮات ﺑـﻪ وﺟـﻮد‬ ‫‪٩٠٩‬‬

‫آﻣﺪه در ﻛﺪ ﺑﺎﻳﺪ ﺑﻪ ﺻﻮرت دﺳﺘﻲ ﻳﺎ اﺗﻮﻣﺎﺗﻴﻚ ﺑﻪ ﺗﻤﺎم ﺳﺮور ﻫﺎ اﻋﻤﺎل ﺷﻮد ﻛﻪ ﻣﻌﻤﻮﻻ اﻳـﻦ اﻣـﺮ ﺑـﻪ وﺳـﻴﻠﻪ ﻧـﺮم اﻓﺰارﻫـﺎي ﻣـﺪﻳﺮﻳﺘﻲ‬ ‫ﻛﻼﺳﺘﺮي ﺳﺮور ﻫﺎ ﻣﺎﻧﻨﺪ ‪ MS Application Center 2000‬اﻧﺠﺎم ﻣﻲ ﺷﻮد‪.‬‬ ‫از ﺳﻮي دﻳﮕﺮ ﻣﺪﻳﺮﻳﺖ ﻛﺪ در ﺑﺨﺶ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﻋﻤﻮﻣﺎً ﻣﺸﻜﻞ ﺗﺮ از ﻣﺪﻳﺮﻳﺖ ﻛﺪ در ﺳﺮور ﻫﺎ اﺳﺖ‪ .‬ﺗﻤـﺎم ﺗﻐﻴﻴﺮاﺗـﻲ ﻛـﻪ در ﺑﺮﻧﺎﻣـﻪ‬ ‫اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ ﺑﺎﻳﺪ ﺑﻪ ﺗﻤﺎم ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه اﻋﻤﺎل ﺷﻮد‪ .‬ﭼﻨﻴﻦ ﺗﻮزﻳﻊ ﻫﺎﻳﻲ ﻛﻪ ﺑﺎﻳﺴﺘﻲ ﺑﻪ ﺻﻮرت ﻫﻤﺰﻣﺎن ﺻﻮرت ﮔﻴﺮﻧﺪ‬ ‫ﻣﻌﻤﻮﻻً ﺑﻪ ﺳﻄﺢ ﺑﺎﻻﻳﻲ از ﻫﻤﺎﻫﻨﮕﻲ و ﺑﺮ اﺳﺎس ﻛﺎﻣﭙﻴﻮﺗﺮ ﻫﺎﻳﻲ ﻛﻪ ﺗﻐﻴﻴﺮات را درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ ﺑـﻪ ﻳـﻚ ﺑـﺴﺘﻪ ي ﻗﺎﺑـﻞ ﺗﻮزﻳـﻊ ﻣـﻮرد‬ ‫اﻃﻤﻴﻨﺎن ﻧﻴﺎز دارﻧﺪ‪.‬‬ ‫ﺗﻮزﻳﻊ ﻛﺪ در ﺑﺨﺶ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﺑﺎ ﻣﺸﻜﻼت دﻳﮕﺮي ﻧﻴﺰ از ﻗﺒﻴﻞ ﻫﻤﺎﻫﻨﮕﻲ ﺑﺎ ﺳﺮور روﺑﺮو اﺳﺖ‪ .‬ﺑﺮاي ﻣﺜﺎل ﺗﻐﻴﻴﺮاﺗﻲ ﻛـﻪ در ﺑﺮﻧﺎﻣـﻪ‬ ‫ي ﺳﺮور اﻋﻤﺎل ﻣﻲ ﺷﻮد ﻧﻴﺎز ﺑﻪ ﺑﺮوز رﺳﺎﻧﻲ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه دارد و ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ ﻫـﺎي ﺳـﺮوﻳﺲ ﮔﻴﺮﻧـﺪه ﺑـﺮوز‬ ‫ﻧﺸﻮد ﺑﺮﻧﺎﻣﻪ ﺳﺮور ﺑﺪون اﺳﺘﻔﺎده ﻣﻲ ﻣﺎﻧﺪ‪.‬‬

‫ﻛﺎراﻳﻲ‪:‬‬ ‫اﺳﺘﻔﺎده از ﻣﺪل ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه‪/‬ﺳﺮوﻳﺲ دﻫﻨﺪه ﺑﺮ روي ﻛﺎراﻳﻲ ﺷﺒﻜﻪ ﻧﻴﺰ ﺗﺎﺛﻴﺮ ﻣﻲ ﮔﺬارد‪ .‬در اﻳﻦ ﻣـﺪل ﺗﻤـﺎم ﺗﻘﺎﺿـﺎﻫﺎي اﻃﻼﻋـﺎت و‬ ‫ﺧﺪﻣﺎت ﺑﺎﻳﺴﺘﻲ از ﻃﺮﻳﻖ ﺷﺒﻜﻪ ﺑﻴﻦ ﺳﺮوﻳﺲ دﻫﻨﺪه و ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﺟﺎ ﺑﻪ ﺟﺎ ﺷﻮد و اﻳﻦ اﻣﺮ ﺑﺎﻋﺚ ﻣﺤﺪودﻳﺖ در ﺷﺒﻜﻪ ﻣﻲ ﺷﻮد‪ .‬اﻳﻦ‬ ‫ﻣﺸﻜﻞ زﻣﺎﻧﻲ ﻛﻪ ﻛﺎرﺑﺮان زﻳﺎدي در ﺣﺎل اﺳﺘﻔﺎده از ﺳﻴﺴﺘﻢ ﺑﺎﺷﻨﺪ ﺑﻴﺸﺘﺮ ﻣﺸﻬﻮد ﺧﻮاﻫﺪ ﺑﻮد‪.‬‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎراﻳﻲ ﺷﺒﻜﻪ ﻧﺰول ﻛﻨﺪ‪ ،‬ﺗﻘﺎﺿﺎﻫﺎي درﻳﺎﻓﺘﻲ ﺑﺮاي ﺧﺪﻣﺎت ﺻﻒ ﻣﻲ ﺷﻮﻧﺪ و وﻗﺘﻲ ﺗﻘﺎﺿﺎﻫﺎي در ﺣﺎل اﻧﺘﻈﺎر اﻓـﺰاﻳﺶ ﻳﺎﺑـﺪ‬ ‫ﺳﻴﺴﺘﻢ از ﻛﺎر ﻣﻲ اﻓﺘﺪ‪ .‬در اﻳﻦ ﺣﺎل ﺗﻨﻬﺎ راه ﺣﻞ ﻗﻄﻊ ﻛﺮدن ﺗﻤﺎم ﻛﺎرﺑﺮان از ﺷﺒﻜﻪ‪ ،‬ﺑﺎزﮔﺮداﻧﺪن ﺗﻤﺎم ﺗﺮاﻛﻨﺶ ﻫﺎ ﺑـﻪ ﺣﺎﻟـﺖ ﻗﺒﻠـﻲ و در‬ ‫ﺑﻌﻀﻲ ﻣﻮاﻗﻊ راه اﻧﺪازي ﻣﺠﺪد ﺳﺮور اﺳﺖ‪.‬‬ ‫ﺑﺮﺣﺴﺐ ﭘﺮوﺗﻜﻞ ﻣﻮرد اﺳﺘﻔﺎده در ﺷﺒﻜﻪ‪ ،‬ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه‪/‬ﺳﺮوﻳﺲ دﻫﻨﺪه در ﺳﻄﺢ ﺟﻬﺎﻧﻲ ﻏﻴـﺮ ﻣﻤﻜـﻦ اﺳـﺖ‪ .‬زﻳـﺮا‬ ‫ﻣﻤﻜﻦ اﺳﺖ ﺑﺮﻧﺎﻣﻪ ي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﺪ در ﻫﻤﺎن ﺷﺒﻜﻪ اي ﻗﺮار ﮔﻴﺮد ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺳﺮور ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ‪.‬‬

‫دﺳﺘﺮﺳﻲ داده ﻫﺎ‪:‬‬ ‫ﻫﻨﮕﺎم ارزﻳﺎﺑﻲ ﻛﺎراﻳﻲ‪ ،‬دﺳﺘﺮﺳﻲ ﺑﻪ داده ﻫﺎ ﻧﻴﺰ ﺑﺎﻳﺪ ﻣﺪﻧﻈﺮ ﻗﺮار ﮔﻴﺮﻧﺪ‪ .‬ﻧﻪ ﺗﻨﻬﺎ ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﻧﻤﻲ داﻧﻨﺪ ﻛﻪ ﭼﮕﻮﻧـﻪ‬ ‫ﺑﻪ ﺳﺮور ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ وﺻﻞ ﺷﻮﻧﺪ‪ ،‬ﺑﻠﻜﻪ ﺑﻴﺸﺘﺮ آﻧﻬﺎ اﺣﺘﻴﺎج ﺑﻪ ﻳﻚ ارﺗﺒﺎط اﺧﺘﺼﺎﺻﻲ ﺑﺎ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ دارﻧﺪ‪ .‬اﻳـﻦ ﻣـﻮرد ﻛـﻪ ﺑـﺎزاي‬ ‫ﺗﻤﺎم ﻛﺎرﺑﺮان در ﺣﺎل ارﺗﺒﺎط ﺑﺎ ﺳﺮور ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﺎﻳﺪ ﻳﻚ اﺗﺼﺎل ﻓﻌﺎل ﺑﺮﻗﺮار ﺑﺎﺷﺪ‪ ،‬ﭼﻪ از ﻧﻈﺮ ﻫﺰﻳﻨﻪ ﭘﺮداﺧﺘﻲ ﺑﺮاي ارﺗﺒﺎط ﺑﺎ ﺳﺮور‬ ‫ﭼﻪ از ﻧﻈﺮ ﻣﺪﻳﺮﻳﺖ ﻣﺮﺑﻮط ﺑﻪ اﺗﺼﺎﻻت ﭘﺮﻫﺰﻳﻨﻪ اﺳﺖ‪ .‬ﻫﻤﭽﻨﻴﻦ اﻳﻦ اﺗﺼﺎﻻت ﻗﺎﺑﻠﻴﺖ ﺑﻪ اﺷﺘﺮاك ﮔﺬاﺷﺘﻪ ﺷﺪن ﺑﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻫـﺎ را ﻧﺪارﻧـﺪ‬ ‫ﻛﻪ اﻳﻦ اﻣﺮ ﺗﺎﺛﻴﺮ ﻣﻨﻔﻲ ﺑﺮ ﻣﻘﻴﺎس ﭘﺬﻳﺮي ﺑﺮﻧﺎﻣﻪ دارد‪.‬‬

‫‪٩١٠‬‬

‫ﻫﺮ ﺳﻪ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﺑﻪ اﺗﺼﺎل اﺧﺘﺼﺎﺻﻲ ﺑﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻧﻴﺎز دارﻧﺪ‪.‬‬

‫ﻗﻮاﻋﺪ ﺗﺠﺎري‪:‬‬ ‫در ﻣﺪل دو ﻻﻳﻪ ﻳﺎ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه‪/‬ﺳﺮوﻳﺲ دﻫﻨﺪه ﻓﻘﻂ دو ﻗﺴﻤﺖ ﺑﺮاي اﻳﺠﺎد و اﺟﺮاي ﻗﻮاﻋﺪ ﺗﺠـﺎري وﺟـﻮد دارد‪ :‬ﻗـﺴﻤﺖ ﺳـﺮوﻳﺲ‬ ‫ﮔﻴﺮﻧﺪه و ﻗﺴﻤﺖ ﺳﺮور ﻛﻪ ﺧﺪﻣﺎت ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را اراﺋﻪ ﻣﻲ دﻫﺪ‪ .‬اﻟﺒﺘﻪ اﺟﺮاي اﻳﻦ ﻗﻮاﻋﺪ در ﺳﻤﺖ ﺳﺮور ﻣﻨﻄﻘﻲ ﺗﺮ اﺳﺖ زﻳﺮا اﻳﻦ اﻣﺮ‬ ‫اﻣﻜﺎن اﻳﻨﻜﻪ ﻳﻚ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﺗﻐﻴﻴﺮات ﺟﺪﻳﺪ را درﻳﺎﻓﺖ ﻧﻜﻨﺪ را رﻓﻊ ﻣﻲ ﻛﻨﺪ‪.‬‬

‫ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﻪ ﻻﻳﻪ‪:‬‬ ‫ﻣﺪل ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺳﻪ ﻻﻳﻪ ﺑﺎ ﺗﻘﺴﻴﻢ ﺑﺮﻧﺎﻣﻪ ﻫﺎي دو ﻻﻳﻪ ﺑﻪ ﺳﻪ ﻗﺴﻤﺖ‪ :‬ﺳﺮوﻳﺲ ﻫﺎي ﻛﺎرﺑﺮان‪ ،‬ﺳـﺮوﻳﺲ ﻫـﺎي ﺗﺠـﺎري و ﺳـﺮوﻳﺲ‬ ‫ﻫﺎي اﻃﻼﻋﺎﺗﻲ ﺑﺎﻋﺚ ﺑﻬﺒﻮد ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه‪/‬ﺳﺮوﻳﺲ دﻫﻨﺪه ﻣﻲ ﺷﻮد‪ .‬اﻳﻦ ﺗﻘﺴﻴﻢ ﻣﻮﺟﺐ اﻓﺰاﻳﺶ ﻣﻘﻴﺎس ﭘﺬﻳﺮي و ﻗﺎﺑﻠﻴـﺖ‬ ‫اﻋﺘﻤﺎد ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺷﻮد‪.‬‬

‫ﻣﺪل ﻣﻨﻄﻘﻲ ﻣﻌﻤﺎري ﺳﻪ ﻻﻳﻪ‬

‫ﺳﺮوﻳﺲ ﻫﺎي ﻛﺎرﺑﺮان‪:‬‬

‫‪٩١١‬‬

‫ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﻛﺎرﺑﺮان ﻛﻪ ﻫﻤﭽﻨﻴﻦ ﻻﻳﻪ اراﺋﻪ دﻫﻨﺪه‪ 1‬ﻧﻴﺰ ﻧﺎﻣﻴﺪه ﻣﻲ ﺷﻮد از ﻓﺎﻳـﻞ ﻫـﺎي اﺟﺮاﻳـﻲ وﻳﻨـﺪوز ﻳـﺎ ﺻـﻔﺤﺎت وب ﻣﺜـﻞ‬ ‫‪HTML‬ﻫﺎي دﻳﻨﺎﻣﻴﻚ و ﻳﺎ ﺻﻔﺤﺎت ‪ ASP‬ﺗﺸﻜﻴﻞ ﺷﺪه اﻧﺪ‪ .‬ﻻﻳﻪ ﺧﺪﻣﺎت ﻛﺎرﺑﺮان در ﺣﻘﻴﻘﺖ ﻻﻳﻪ اي اﺳﺖ ﻛﻪ اﻃﻼﻋﺎت ﺳﺮور را ﺑـﻪ‬ ‫ﻛﺎرﺑﺮ ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﺪ و اﻃﻼﻋﺎت ﻣﻮرد ﻧﻴﺎز ﺳﺮور را از ﻛﺎرﺑﺮ درﻳﺎﻓﺖ ﻣﻲ ﻛﻨﺪ‪ .‬در ﻣﺪل ﺳﻪ ﻻﻳﻪ‪ ،‬ﻻﻳﻪ اراﺋﻪ دﻫﻨﺪه ﺑـﻪ داﻧـﺴﺘﻦ ﺳـﺎﺧﺘﺎر‬ ‫ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ و ﻳﺎ ﻫﺮ ﺳﺮوﻳﺲ دﻳﮕﺮي ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي اﻃﻼﻋﺎﺗﻲ اراﺋﻪ ﻣﻲ ﺷﻮد اﺣﺘﻴﺎج ﻧﺪارد‪.‬‬

‫ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري‪:‬‬ ‫ﻻﻳﻪ دوم‪ ،‬ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري اﺳﺖ‪ .‬در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﻪ ﻻﻳﻪ‪ ،‬در ﺣﻘﻴﻘﺖ اﻳﻦ ﻻﻳﻪ ﻣﺴﺌﻮل ﭼﮕﻮﻧﮕﻲ دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت اﺳﺖ‪.‬‬ ‫اﻳﻦ ﻣﺴﺌﻮﻟﻴﺖ ﺷﺎﻣﻞ درﻳﺎﻓﺖ ﺗﻘﺎﺿﺎي اﻃﻼﻋﺎت ﻣﻮردﻧﻴﺎز از ﻃـﺮف ﻻﻳـﻪ ﺳـﺮوﻳﺲ ﻫـﺎي ﻛـﺎرﺑﺮ‪ ،‬ﻓﺮﺳـﺘﺎدن آن ﺑـﻪ ﻻﻳـﻪ ي داده اي و‬ ‫ﺑﺎزﮔﺮداﻧﺪن ﻧﺘﺎﻳﺞ درﺧﻮاﺳﺖ ﻫﺎ ﺑﻪ ﻛﺎرﺑﺮ اﺳﺖ‪ .‬اﻳﻦ ﻻﻳﻪ ﻣﻲ ﺗﻮاﻧﺪ‪ ،‬و در ﺑﻴﺸﺘﺮ ﺷـﺮاﻳﻂ ﺑﺎﻳـﺪ‪ ،‬ﻗﻮاﻋـﺪ ﺗﺠـﺎري اﻋﻤـﺎل ﺷـﺪه در ﺑﺮﻧﺎﻣـﻪ را‬ ‫ﻧﮕﻬﺪاري و اﺟﺮا ﻛﻨﺪ‪.‬‬ ‫ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري ﻗﺎدر ﺑﻪ اﻧﺠﺎم ﺗﻤﺎم ﻣﻮاردي اﺳﺖ ﻛﻪ ﻻﻳﻪ اراﺋﻪ دﻫﻨﺪه درﺧﻮاﺳﺖ ﻣﻲ ﻛﻨﺪ‪ .‬ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻳﻜـﻲ از ﻣﻬﻤﺘـﺮﻳﻦ‬ ‫اﻫﺪاف اﻳﻦ ﻻﻳﻪ‪ ،‬ﺟﺪاﺳﺎزي ﻻﻳﻪ اراﺋﻪ دﻫﻨﺪه از ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي اﻃﻼﻋﺎﺗﻲ اﺳﺖ اﻣﺎ اﻳﻦ ﻻﻳﻪ ﻛﺎرﻫﺎي ﺑـﺴﻴﺎر ﺑﻴـﺸﺘﺮي را اﻧﺠـﺎم ﻣـﻲ‬ ‫دﻫﺪ‪ .‬ﺗﻤﺎم ﺗﻮاﺑﻊ‪ ،‬اﻋﻢ از ﻣﺤﺎﺳﺒﺎﺗﻲ و ﻳﺎ وﻇﺎﻳﻒ وﻳﮋه ﺑﺮﻧﺎﻣﻪ‪ ،‬ﺑﻮﺳﻴﻠﻪ اﻳﻦ ﻻﻳﻪ اراﺋﻪ ﻣﻲ ﺷﻮﻧﺪ‪ .‬ﺗﻤﺎم ﻛﺎرﺑﺮان ﺑﻪ واﺳﻄﻪ ﻻﻳﻪ اراﺋﻪ دﻫﻨﺪه ﺑﻪ‬ ‫اﻣﻜﺎﻧﺎت اﻳﻦ ﻻﻳﻪ دﺳﺘﺮﺳﻲ دارﻧﺪ‪ .‬اﻳﻦ ﻻﻳﻪ ﺑﻪ ﺻﻮرت ﻓﻴﺰﻳﻜﻲ در ﻳﻜﻲ از ﺳﺮورﻫﺎي ﻣﻮﺟﻮد در ﺷﺒﻜﻪ ﻗﺮار ﻣﻲ ﮔﻴﺮد‪ .‬ﺗﻤﺎم ﻗﻮاﻋﺪ ﺗﺠﺎري‬ ‫ﺟﺪﻳﺪ و ﻳﺎ ﺗﻐﻴﻴﺮات اﻋﻤﺎل ﺷﺪه در آﻧﻬﺎ ﻓﻘﻂ ﺑﺎﻳﺪ در اﻳﻦ ﻻﻳﻪ ﺗﻮزﻳﻊ ﺷﻮﻧﺪ‪ ،‬ﻛﻪ اﻳﻦ اﻣﺮ ﻣﻮﺟﺐ ﺣـﺬف ﻧﻴـﺎز ﺑـﻪ اﻧﺘـﺸﺎر اﻳـﻦ ﻗﻮاﻋـﺪ ﺑـﻴﻦ‬ ‫ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﻣﻲ ﺷﻮد‪.‬‬

‫ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي ﻻﻳﻪ ﺳﺮوﻳﺴﻬﺎي ﺗﺠﺎري ﺑﻪ وﺳﻴﻠﻪ ﺗﻤﺎم ﺳﺮوﻳﺴﻬﺎي ﻛﺎرﺑﺮ اﺳﺘﻔﺎده ﻣﻴﺸﻮﻧﺪ‬

‫ﺳﺮوﻳﺲ ﻫﺎي اﻃﻼﻋﺎﺗﻲ‪:‬‬

‫‪Presentation Layer‬‬

‫‪1‬‬

‫‪٩١٢‬‬

‫ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي اﻃﻼﻋﺎﺗﻲ اﻣﻜﺎن دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت را ﺑﺮاي ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠـﺎري ﻓـﺮاﻫﻢ ﻣـﻲ ﻛﻨـﺪ ﻛـﻪ اﻳـﻦ ﻻﻳـﻪ ﻧﻴـﺰ‬ ‫اﻃﻼﻋﺎت را در اﺧﺘﻴﺎر ﻛﺎرﺑﺮان ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه در ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﻛﺎرﺑﺮ ﻗﺮار ﻣـﻲ دﻫـﺪ‪ ADO.NET.‬و ﺳﻴـﺴﺘﻢ ﻣـﺪﻳﺮﻳﺖ ﺑﺎﻧـﻚ‬ ‫اﻃﻼﻋﺎﺗﻲ)‪ (DBMS‬ﻫﺮ دو در اﻳﻦ ﻻﻳﻪ ﻧﮕﻬﺪاري ﻣﻲ ﺷﻮﻧﺪ‪ ADO.NET .‬راه ﺣـﻞ ﻣﺎﻳﻜﺮوﺳـﺎﻓﺖ ﺑـﺮاي دﺳﺘﺮﺳـﻲ اﻃﻼﻋـﺎت در‬ ‫ﺷﺒﻜﻪ و ‪ MS SQL Server‬ﻧﻴﺰ راه ﺣﻞ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﺑﺮاي ﺳﻴﺴﺘﻢ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳـﺖ‪ .‬ﻫـﺮ دو اﻳـﻦ ﻣـﻮارد‬ ‫دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت را ﻓﺮاﻫﻢ ﻣﻲ ﻛﻨﺪ‪ ADO.NET .‬روﺷﻲ را ﺑﺮاي درﻳﺎﻓـﺖ اﻃﻼﻋـﺎت اراﺋـﻪ ﻣـﻲ دﻫـﺪ و ‪SQL Server‬‬ ‫ﻣﻮﺗﻮر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺳﺖ ﻛﻪ ﺑﺮاي ﻧﮕﻬﺪاري ﺧﻮد اﻃﻼﻋﺎت ﺑﻪ ﻛﺎر ﻣﻲ رود‪.‬‬

‫ﻣﺪﻳﺮﻳﺖ ﻛﺪ‪:‬‬ ‫ﻣﺪﻳﺮﻳﺖ ﻛﺪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﻪ ﻻﻳﻪ ﺑﺴﻴﺎر راﺣﺖ ﺗﺮ از ﺑﺮﻧﺎﻣﻪ ﻫﺎي دو ﻻﻳﻪ اﺳﺖ و دﭼﺎر ﻣﺸﻜﻼت ﻛﻤﺘﺮي ﻣﻲ ﺷﻮد‪ .‬ﺑﻪ دﻟﻴﻞ ﺟﺪاﺳﺎزي‬ ‫ﻣﻨﻄﻘﻲ و ﻓﻴﺰﻳﻜﻲ ﺑﺮﻧﺎﻣﻪ دﻳﮕﺮ ﻧﻴﺎزي ﺑﻪ ﻳﻚ ﺗﻴﻢ ﺗﻮﺳﻌﻪ ﺑﺮاي ﻛﻞ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺴﺖ‪ .‬ﻃﺮاﺣﺎن ﻻﻳﻪ اراﺋﻪ دﻫﻨﺪه ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﺪون دﺳﺘﺮﺳﻲ ﺑـﻪ‬ ‫ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﺑﻪ ﻃﺮاﺣﻲ اﻳﻦ ﻻﻳﻪ ﺑﭙﺮدازﻧﺪ‪ .‬ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري ﻣﻲ ﺗﻮاﻧﺪ از درﮔﻴﺮي ﺑﺎ ﻻﻳـﻪ اراﺋـﻪ دﻫﻨـﺪه آزاد‬ ‫ﺷﻮﻧﺪ و ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﺮ روي راﺑﻄﻪ اﻃﻼﻋﺎت و ﻳﺎ ﭘﻴﺎده ﺳﺎزي ﻗﻮاﻋﺪ ﺗﺠﺎري ﺗﻤﺮﻛﺰ ﻛﻨﻨﺪ‪ .‬ﺑﻮاﺳﻄﻪ اﻳﻦ اﻣـﺮ‬ ‫ﻛﻪ اﻳﻦ ﻻﻳﻪ ﻫﺎ ﺑﻪ ﻃﻮر ﻣﻨﻄﻘﻲ ﻣﺠﺰا از ﻳﻜﺪﻳﮕﺮ ﻫﺴﺘﻨﺪ‪ ،‬ﻫﺮ ﻛﺪام از آﻧﻬﺎ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ ﻃﻮر ﻣﺠﺰا ﻛﺎﻣﭙﺎﻳﻞ ﺷﺪه و ﻳﺎ ﻣﺠﺪداً ﭘﻴﻜـﺮ ﺑﻨـﺪي‬ ‫ﺷﻮﻧﺪ ﺑﺪون اﻳﻨﻜﻪ ﺑﺮ ﻻﻳﻪ ﻫﺎي دﻳﮕﺮ ﺗﺎﺛﻴﺮ ﺑﮕﺬارﻧﺪ‪.‬‬

‫ﻣﻘﻴﺎس ﭘﺬﻳﺮي‪:‬‬ ‫در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﻪ ﻻﻳﻪ ﻣﻘﻴﺎس ﭘﺬﻳﺮي ﺑﺴﻴﺎر ﺑﻬﺒﻮد ﻣﻲ ﻳﺎﺑﺪ‪ ،‬زﻳﺮا اﺗﺼﺎﻻت ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻣﻲ ﺗﻮاﻧﺪ ﺑﺪون آﻧﻜﻪ ﻗﻄﻊ ﺷـﻮد از ﻛـﺎرﺑﺮي‬ ‫ﻛﻪ ﺑﻪ آن ﻧﻴﺎز ﻧﺪارد ﮔﺮﻓﺘﻪ ﺷﺪه و ﺑﺮاي دﻳﮕﺮ ﻛﺎرﺑﺮان ﻧﮕﻪ داﺷﺘﻪ ﺷﻮد‪ .‬اﻳﻦ اﻣﺮ ﺗﻌﺪاد ﻛﺎرﺑﺮاﻧﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ از ﻃﺮﻳﻖ ﻻﻳﻪ ﻣﻴﺎﻧﻲ) ﻻﻳـﻪ‬ ‫ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري( ﺑﺎ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ در ﺗﻤﺎس ﺑﺎﺷﻨﺪ را اﻓﺰاﻳﺶ ﻣﻲ دﻫﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﻧﻮع ﻣﻌﻤﺎري ﭘﺮدازش از ﺳﻤﺖ ﺳﺮوﻳﺲ‬ ‫ﮔﻴﺮﻧﺪه ﺑﻪ ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري اﻧﺘﻘﺎل ﻣﻲ ﻳﺎﺑﺪ‪ .‬ﻛﺎراﻳﻲ ﺷﺒﻜﻪ ﺑﻪ ﻋﻠﺖ ارﺗﺒﺎط ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري ﺑﺎ ﻻﻳﻪ ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ‬ ‫ﺑﻪ ﺟﺎي ارﺗﺒﺎط ﻻﻳﻪ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﺑﺎ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻧﻴﺰ اﻓﺰاﻳﺶ ﻣﻲ ﻳﺎﺑﺪ‪ .‬در ﻛﻞ ﻣﻘﻴﺎس ﭘﺬﻳﺮي در اﻳﻦ ﺳﻴـﺴﺘﻢ ﻫـﺎ ﺑـﻪ واﺳـﻄﻪ ي‬ ‫دﺳﺘﻪ ﺑﻨﺪي ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري و ﺳﺮورﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﻓﺰاﻳﺶ ﻣﻲ ﻳﺎﺑﺪ‪.‬‬ ‫ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي ﺗﺠﺎري ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ وﺳﻴﻠﻪ اﺑﺰارﻫـﺎي اراﺋـﻪ ﺷـﺪه ﺗﻮﺳـﻂ ‪ COM+‬و ﻳـﺎ‪ Enterprise Services‬در‬ ‫ﺣﺎﻓﻈﻪ ﺑﺎرﮔﺬاري ﺷﻮﻧﺪ و ﺗﺎ ﻣﻮﻗﻊ ﻧﻴﺎز در آﻧﺠﺎ ﺑﺎﻗﻲ ﺑﻤﺎﻧﻨﺪ‪ .‬اﻳﻦ اﻣﺮ ﻣﻮﺟﺐ اﻓﺰاﻳﺶ ﺗﻌﺪاد ﻛﺎرﺑﺮاﻧﻲ ﻣـﻲ ﺷـﻮد ﻛـﻪ ﻻﻳـﻪ ﺳـﺮوﻳﺲ ﻫـﺎي‬ ‫ﺗﺠﺎري ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ آﻧﻬﺎ ﭘﺎﺳﺦ دﻫﺪ زﻳﺮا زﻣﺎن ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﺑﺎرﮔﺬاري ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي ﻻزم ﺣﺬف ﻣﻲ ﺷﻮد‪.‬‬

‫ﻗﻮاﻋﺪ ﺗﺠﺎري‪:‬‬ ‫در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﻪ ﻻﻳﻪ ﻗﻮاﻋﺪ ﺗﺠﺎري ﻧﺒﺎﻳﺪ در ﻻﻳﻪ اراﺋﻪ دﻫﻨﺪه)ﻻﻳﻪ ﻛﺎرﺑﺮ( اﻋﻤﺎل ﺷﻮﻧﺪ‪ .‬زﻳﺮا در اﻳﻦ ﺻﻮرت ﻛﺎرﺑﺮ‪ ،‬ﺑﻪ راﺣﺘﻲ ﻣﻲ ﺗﻮاﻧـﺪ‬ ‫از اﻳﻦ ﻗﻮاﻋﺪ ﻋﺒﻮر ﻛﻨﺪ‪ .‬ﻋﻼوه ﺑﺮ اﻳﻦ ﺑﺎ ﻗﺮار دادن ﻳﻚ ﻗﺎﻋﺪه ﺗﺠﺎري در ﺳﻤﺖ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه اﻳﻦ ﻋﻤﻞ ﺑﺎﻳﺪ ﺑﺮاي ﺗﻤﺎﻣﻲ ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎي‬ ‫اﻳﻦ ﻻﻳﻪ ﺗﻜﺮار ﺷﻮد‪.‬‬ ‫اﻳﻦ ﻗﻮاﻋﺪ ﻣﻲ ﺗﻮاﻧﻨﺪ در ﻫﺮ ﻳﻚ از ﻻﻳﻪ ﻫﺎي ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري و ﻳﺎ ﺳﺮوﻳﺲ ﻫﺎي اﻃﻼﻋﺎﺗﻲ ﻗﺮار داده ﺷﻮﻧﺪ‪ .‬زﻣﺎﻧﻲ ﻛﻪ اﻳﻦ ﻗﻮاﻋـﺪ‬ ‫در ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ‪ ،‬ﺑﺎﻳﺴﺘﻲ اﻃﻤﻴﻨﺎن ﺣﺎﺻﻞ ﺷﻮد ﻛﻪ ﻛﺎرﺑﺮان ﻓﻘﻂ از ﻃﺮﻳﻖ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي اﻳﻦ ﻻﻳﻪ ﺑﻪ ﻻﻳﻪ‬

‫‪٩١٣‬‬

‫ﺳﻮم دﺳﺘﺮﺳﻲ دارﻧﺪ و ﻧﻤﻲ ﺗﻮاﻧﻨﺪ از اﻳﻦ ﻻﻳﻪ ﻋﺒﻮر ﻛﺮده و ﺑﻪ ﻻﻳﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﻨﺪ‪ .‬زﻳﺮا در ﻏﻴـﺮ اﻳـﻦ ﺻـﻮرت اﻳـﻦ‬ ‫ﻗﻮاﻋﺪ ﺑﻪ درﺳﺘﻲ اﺟﺮا ﻧﻤﻲ ﺷﻮﻧﺪ‪ ،‬اﻣﺎ زﻣﺎﻧﻲ ﻛﻪ اﻳﻦ ﻗﻮاﻋﺪ در ﻻﻳﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ اﺟﺮا ﺷـﺪﻧﺪ دﻳﮕـﺮ ﻛـﺎرﺑﺮان ﺗﻮاﻧـﺎﻳﻲ ﻋﺒـﻮر از آﻧﻬـﺎ را‬ ‫ﻧﺨﻮاﻫﻨﺪ داﺷﺖ‪.‬‬ ‫زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ از ﻗﺒﻴﻞ‪ VB.NET ، VC++‬و ﻳﺎ ‪ C#‬ﺑﺮاي ﭘﻴﺎده ﺳﺎزي اﻳﻦ ﻗﻮاﻋﺪ ﺑﻬﻴﻨﻪ ﺷﺪه اﻧﺪ‪ .‬ﺑﺎ وﺟﻮد اﻳﻦ‪ ،‬ﻣﻲ‬ ‫ﺗﻮان ﺑﺎ اﺳﺘﻔﺎده از اﻣﻜﺎﻧﺎﺗﻲ ﻛﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ از ﻗﺒﻴﻞ ‪ SQL Server‬وﺟﻮد دارد اﻳﻦ ﻗﻮاﻋﺪ را در ﻻﻳﻪ ﺑﺎﻧـﻚ اﻃﻼﻋـﺎﺗﻲ ﭘﻴـﺎده‬ ‫ﺳﺎزي ﻛﺮد‪.‬‬

‫ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﭼﻨﺪ ﻻﻳﻪ‪:‬‬ ‫ﺗﻘﺴﻴﻢ ﺑﻨﺪي ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﭼﻨﺪ ﻻﻳﻪ‪ ،‬ﺑﻪ ﺻﻮرت اﺳﺘﺮاﺗﮋﻳﻚ‪ ،‬ﻣﻲ ﺗﻮاﻧﺪ ﺑﺎﻋﺚ اﻓﺰاﻳﺶ ﻣﻘﻴﺎس ﭘﺬﻳﺮي‪ ،‬ﻛﺎراﻳﻲ‪ ،‬اﻧﻌﻄﺎف ﭘـﺬﻳﺮي و ﻗـﺪرت‬ ‫ﻣﺪﻳﺮﻳﺖ ﺷﻮد‪ ،‬اﻳﻦ ﻣﻮرد ﻛﻪ ﺑﻪ ﻫﺮ ﻻﻳﻪ ﻳﻚ وﻇﻴﻔﻪ ﺧﺎص داده ﺷﻮد ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﻃﺮاﺣﺎن آن ﻻﻳﻪ‪ ،‬ﺑﺮ روي ﺗﻮﺳﻌﻪ و ﭘﻴﻜـﺮ ﺑﻨـﺪي‬ ‫وﻇﻴﻔﻪ ﻣﺸﺨﺺ ﺷﺪه ﻋﻤﻞ ﻛﻨﻨﺪ‪.‬‬ ‫ﻫﺮ ﺑﺮﻧﺎﻣﻪ اي ﻛﻪ ﺷﺎﻣﻞ ﺑﻴﺶ از ﺳﻪ ﻻﻳﻪ ﺷﻮد‪ ،‬ﺟﺰء ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﭼﻨﺪ ﻻﻳﻪ ﻗﺮار ﻣﻲ ﮔﻴﺮد‪ .‬اﻣﺎ در اﻳﻦ ﺑﺨﺶ ﻣﻨﻈﻮر از ﺑﺮﻧﺎﻣﻪ ﻫـﺎي ﭼﻨـﺪ‬ ‫ﻻﻳﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﭘﻨﺞ ﻻﻳﻪ اﺳﺖ‪ .‬اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻣﺸﺎﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﻪ ﻻﻳﻪ ﻫﺴﺘﻨﺪ وﻟﻲ در آﻧﻬﺎ ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري ﺑﻪ ﺳﻪ ﻻﻳـﻪ‬ ‫ﻳﺎ ﺳﻪ ﻛﻼس دﻳﮕﺮ ﺗﻘﺴﻴﻢ ﻣﻲ ﺷﻮد ﻛﻪ ﻋﺒﺎرت اﻧﺪ از‪ :‬ﻛﻼس ﺧﺎرﺟﻲ‪ ،‬ﻛﻼس اﺻﻠﻲ ﺗﺠﺎري و ﻛﻼس دﺳﺘﺮﺳﻲ اﻃﻼﻋﺎت‪.‬‬

‫ﻛﻼﺳﻬﺎي ﻻﻳﻪ ﺗﺠﺎري ﺑﻪ ﭼﻨﺪ ﻛﻼس ﺟﺪﻳﺪ ﺗﻘﺴﻴﻢ ﻣﻴﺸﻮﻧﺪ‬

‫ﻛﻼس ﺧﺎرﺟﻲ‪:‬‬ ‫ﻛﻼس ﺧﺎرﺟﻲ‪ 1‬در ﺣﻘﻴﻘﺖ ﺑﻪ ﻋﻨﻮان ﻳﻚ ﺑﺎﻓﺮ ﺑﻴﻦ ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﻛﺎرﺑﺮ و اﻣﻜﺎﻧﺎت اراﺋﻪ ﺷﺪه ﺗﻮﺳﻂ ﻻﻳـﻪ ﺳـﺮوﻳﺲ ﻫـﺎي ﺗﺠـﺎري‬ ‫ﺑﺮﻧﺎﻣﻪ ﻋﻤﻞ ﻣﻲ ﻛﻨﺪ‪ .‬ﻳﻜﻲ از ﻣﺰاﻳﺎي اﺳﺘﻔﺎده از اﻳﻦ ﻛﻼس ﻫﺎ اﻳﻦ اﺳﺖ ﻛﻪ ﻣﻲ ﺗﻮان ﭼﻨﺪﻳﻦ ﻛﻼس ﺑﺮاي اﻳﻦ ﻗﺴﻤﺖ ﺗﻌﺮﻳﻒ ﻛﺮد و ﺑـﺎ‬ ‫اﺳﺘﻔﺎده از آﻧﻬﺎ اﻃﻼﻋﺎت اﻳﺴﺘﺎ را ﺑﻪ اﻃﻼﻋﺎﺗﻲ ﻛﻪ ﺑﻪ ﺳﻤﺖ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﻓﺮﺳﺘﺎده ﻣﻲ ﺷﻮﻧﺪ اﺿﺎﻓﻪ ﻛﺮد و ﺑﺪﻳﻦ وﺳﻴﻠﻪ ﺑـﻪ ﻃﺮاﺣـﺎن و‬ ‫ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري در ﺗﺴﺮﻳﻊ ﻃﺮاﺣﻲ و ﺗﻮﺳﻌﻪ ﻛﻤﻚ ﻛﺮد‪.‬‬

‫‪Facades Layer‬‬

‫‪1‬‬

‫‪٩١٤‬‬

‫ﻻﻳﻪ ﺧﺎرﺟﻲ ﺑﻪ ﻋﻨﻮان ﻳﻚ ﺑﺎﻓﺮ ﺑﺮاي ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎ ﻋﻤﻞ ﻣﻴﻜﻨﺪ‬ ‫ﻳﻜﻲ دﻳﮕﺮ از ﻣﺰاﻳﺎي اﺳﺘﻔﺎده از اﻳﻦ ﻛﻼﺳﻬﺎي ﺧﺎرﺟﻲ‪ ،‬ﺗﻮاﻧﺎﻳﻲ از ﺑﻴﻦ ﺑﺮدن ﭘﻴﭽﻴﺪﮔﻲ ﻣﻮﺟﻮد در ﺗﻮاﺑﻊ ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري اﺳﺖ‪.‬‬ ‫ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي ﻣﻮﺟﻮد در ﻻﻳﻪ ﺳﺮوﻳﺲ ﻫﺎي ﺗﺠﺎري اﻏﻠﺐ ﺑﻪ ﮔﻮﻧﻪ اي ﻃﺮاﺣﻲ ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﺑﺘﻮاﻧﻨﺪ ﺑﻪ ﻃﻮر ﻋﻤـﻮﻣﻲ ﺑـﻪ وﺳـﻴﻠﻪ ﭼﻨـﺪ‬ ‫ﺑﺮﻧﺎﻣﻪ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮﻧﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ ﻫﺮ ﻛﺎرﺑﺮ و ﻳﺎ ﺳﺮوﻳﺴﻲ از ﺳﻮي ﺻﻔﺤﺎت وب‪ ،‬ﻧﻴﺎز ﺑﻪ ﻧﻤﻮﻧـﻪ ﺳـﺎزي و ﻳـﺎ ﺑﺎرﮔـﺬاري ﭼﻨـﺪﻳﻦ‬ ‫ﻛﺎﻣﭙﻮﻧﻨﺖ ﺑﺮاي اﺟﺮاي ﻳﻚ وﻇﻴﻔﻪ ﺧﺎص دارد‪ .‬ﺑﻪ وﺳﻴﻠﻪ ﻛﻼس ﻫﺎي ﺧﺎرﺟﻲ‪ ،‬ﻛﺎرﺑﺮ ﻻﻳﻪ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﻓﻘﻂ ﻧﻴﺎز دارد ﻳـﻚ ﻧﻤﻮﻧـﻪ از‬ ‫ﻛﻼس ﺧﺎرﺟﻲ را ﺷﺒﻴﻪ ﺳﺎزي ﻛﺮده و از ﭘﻴﭽﻴﺪﮔﻲ ﻛﺎر در ﻻﻳﻪ ﻣﻴﺎﻧﻲ ﺟﺪا ﻣﻲ ﻣﺎﻧﺪ‪.‬‬

‫ﻛﻼس اﺻﻠﻲ ﺗﺠﺎري‪:‬‬ ‫ﻛﻼس اﺻﻠﻲ ﺗﺠﺎري ﻳﺎ ﻻﻳﻪ ﻣﺮﺣﻠﻪ ﺗﺠﺎري‪ ،1‬در ﺣﻘﻴﻘﺖ ﻓﺮاﻫﻢ ﻛﻨﻨﺪه وﻇﺎﻳﻒ اﺻﻠﻲ ﺗﺠﺎري ﺑﺮﻧﺎﻣﻪ اﺳﺖ ﻛﻪ ﻋﺒﺎرت اﻧﺪ از‪ :‬اﺟﺮاي ﻗﻮاﻋﺪ‬ ‫ﺗﺠﺎري‪ ،‬ﺗﻀﻤﻴﻦ ﻛﺮدن ﻛﺎراﻳﻲ ﻣﻨﻄﻖ ﺗﺠﺎري و ﻓﺮاﻫﻢ ﻛﺮدن دﺳﺘﺮﺳﻲ ﺑﻪ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي اﻃﻼﻋـﺎﺗﻲ‪ .‬ﺑـﻪ ﻋﺒـﺎرت دﻳﮕـﺮ اﻳـﻦ ﻛـﻼس‪،‬‬ ‫ﻫﻮﺷﻤﻨﺪي واﻗﻌﻲ ﺑﺮﻧﺎﻣﻪ را اراﺋﻪ ﻣﻲ دﻫﺪ‪ .‬ﻛﻼﺳﻬﺎي ﺧﺎرﺟﻲ ﻧﻴﺰ ﺑﺎ اﺳﺘﻔﺎده از ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي اﻳﻦ ﻻﻳﻪ وﻇﻴﻔﻪ ﻣﻮردﻧﻈﺮ ﺧﻮد را اﻧﺠﺎم ﻣﻲ‬ ‫دﻫﻨﺪ‪.‬‬

‫راﺑﻄﻪ ﺑﻴﻦ ﻛﻼس اﺻﻠﻲ ﺗﺠﺎري ﺑﺎ ﻛﻼﺳﻬﺎي ﺧﺎرﺟﻲ و ﻛﻼﺳﻬﺎي دﺳﺘﺮﺳﻲ اﻃﻼﻋﺎت‬

‫‪Business Level Layer‬‬

‫‪1‬‬

‫‪٩١٥‬‬

‫ﻛﻼﺳﻬﺎي دﺳﺘﺮﺳﻲ اﻃﻼﻋﺎت‪:‬‬ ‫ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت ﻳﺎ ﻻﻳﻪ دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت‪ 1‬اﻣﻜﺎن اﺳﺘﻔﺎده از اﻃﻼﻋﺎت را ﺑﺮاي ﻻﻳﻪ اﺻﻠﻲ ﺗﺠﺎري ﻓﺮاﻫﻢ ﻣـﻲ‬ ‫ﻛﻨﺪ‪ .‬در ﻣﺪل ﭘﻨﺞ ﻻﻳﻪ ﻓﻘﻂ اﻳﻦ ﻻﻳﻪ ﺑﻪ ﺳﺎﺧﺘﺎر ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ دﺳﺘﺮﺳﻲ دارد ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻐﻴﻴﺮات در ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻓﻘﻂ ﻧﻴﺎز ﺑـﻪ اﻳﺠـﺎد‬ ‫ﺗﻐﻴﻴﺮات در اﻳﻦ ﻻﻳﻪ دارد‪ .‬ﻗﺴﻤﺖ ﻫﺎي دﻳﮕﺮ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻴﺎزي ﺑﻪ اﻃﻼع از زﻳﺮ ﺳﺎﺧﺖ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻧﺪارﻧﺪ‪.‬‬ ‫ﺑﺪون ﺗﻮﺟﻪ ﺑﻪ ﻧﻮع ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﺷﺪه در ﻻﻳﻪ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ‪ ADO.NET ،‬روش ﭘﻴﺸﻨﻬﺎدي ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﺑﺮاي اﻳﻦ ﻻﻳﻪ ﻣﺤﺴﻮب‬ ‫ﻣـﻲ ﺷـﻮد‪ ADO.NET .‬ﺗﻮاﻧـﺎﻳﻲ ﺑﺮﻗـﺮاري ارﺗﺒـﺎط ﺑـﺎ اﻧـﻮاع ﻣﻨـﺎﺑﻊ اﻃﻼﻋـﺎﺗﻲ را از ﻗﺒﻴـﻞ ‪Oracle ،SQL Server‬‬ ‫‪ Excel ، Word ،Access ،Sybase،‬و‪ ...‬را دارد‪ .‬در ﻃﺮاﺣﻲ ﻻﻳﻪ اي ﻣﻌﻤﻮﻻ ﻣﻨﺒﻊ اﻃﻼﻋﺎﺗﻲ‪ ،‬ﻳﻚ ﺳﻴـﺴﺘﻢ ﻣـﺪﻳﺮﻳﺖ‬ ‫ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ )‪ (DBMS‬اﺳﺖ ﻛﻪ دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت را ﻓﺮاﻫﻢ ﻣﻲ ﻛﻨﺪ‪ .‬ﻫﻨﮕﺎم اﺳﺘﻔﺎده از ‪ ADO.NET‬ﻃﺮاﺣﺎن ﻣـﻲ ﺗﻮاﻧﻨـﺪ از‬ ‫ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي اﻳﻦ ﻛﻼس ﺑﺮاي اﻳﺠﺎد ﭘﺮس و ﺟﻮ ﻫﺎي ﻣﺨﺘﻠﻒ اﺳﺘﻔﺎده ﻛﻨﻨﺪ‪ .‬ﻋﻼوه ﺑﺮ اﻳﻦ اﺳﺘﻔﺎده از روش ﻫﺎي داﺧﻠﻲ ﺳﻴﺴﺘﻢ ﻫﺎي‬ ‫ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ ﻧﻴﺰ اﻣﻜﺎن ﭘﺬﻳﺮ اﺳﺖ‪ .‬ﻣﺜﻼ در ‪ SQL Server‬ﻣﻲ ﺗﻮان از ﭘﺮوﺳﻴﺠﺮ ﻫﺎي آﻣﺎده‪ 2‬اﺳﺘﻔﺎده ﻛﺮد ﻛـﻪ ﺣـﺪود ‪ 40‬در‬ ‫ﺻﺪ ﺳﺮﻳﻌﺘﺮ از روش ﻫﺎي دﻳﮕﺮ اﺳﺖ‪.‬‬

‫ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي دﺳﺘﺮﺳﻲ اﻃﻼﻋﺎت ﺑﺮاي درﻳﺎﻓﺖ و ارﺳﺎل اﻃﻼﻋﺎت از ﻻﻳﻪ ﺳﺮوﻳﺴﻬﺎي اﻃﻼﻋﺎﺗﻲ ﺑﻪ ﻻﻳﻪ ﺳﺮوﻳﺴﻬﺎي ﺗﺠﺎري آﻣﺎده‬ ‫ﻫﺴﺘﻨﺪ‬

‫ﺳﺮوﻳﺲ ﻫﺎي وب‪:‬‬ ‫ﻳﻚ ﺳﺮوﻳﺲ وب‪ ،‬ﻳﻚ ﺗﺎﺑﻊ ﻳﺎ ﻣﺠﻤﻮﻋﻪ اي از ﺗﻮاﺑﻊ اﺳﺖ ﻛﻪ از ﻃﺮﻳﻖ اﻳﻨﺘﺮﻧﺖ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ اﺳﺖ و از ﺗﺮﻛﻴﺐ ‪ XML‬ﺑﺮاي اراﺋـﻪ داده‬ ‫ﻫﺎ و ‪ HTTP‬ﺑﺮاي اﻧﺘﻘﺎل داده ﻫﺎ ﺑﻬﺮه ﻣﻲ ﺑﺮد‪ .‬وب ﺳﺮوﻳﺲ ﻫﺎ ﻧﻴﺰ ﻣﺎﻧﻨﺪ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎي ‪ COM‬و ﻳـﺎ ‪ .NET‬ﺗﻮاﺑـﻊ ﺧـﻮد را ﺑـﺮاي‬ ‫ﻛﺎرﺑﺮان ﻋﺮﺿﻪ ﻣﻲ ﻛﻨﻨﺪ‪ .‬اﺳﺘﻔﺎده ﻛﻨﻨﺪﮔﺎن اﻳﻦ ﺗﻮاﺑﻊ ﻋﻤﻮﻣﺎً ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﻫﺴﺘﻨﺪ‪ .‬در ﻧﺘﻴﺠﻪ وب ﺳﺮوﻳﺲ ﻫـﺎ در ﻃﺮاﺣـﻲ‬ ‫ﻻﻳﻪ اي‪ ،‬ﺑﻪ راﺣﺘﻲ ﺑﻪ ﻋﻨﻮان ﻳﻚ ﻻﻳﻪ اﻟﺤﺎﻗﻲ ﻗﺎﺑﻞ اﺳﺘﻔﺎده اﻧﺪ‪.‬‬ ‫‪3‬‬ ‫وب ﺳﺮوﻳﺲ ﻫﺎ اﻳﻦ اﻣﻜﺎن را ﺑﻪ ﻳﻚ ﺗﻮﺳﻌﻪ ﮔﺮ ﻣﻲ دﻫﻨﺪ ﻛﻪ ﺑﺪون ﻃﺮاﺣﻲ ﻛﺎﻣﻞ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ‪ ،‬ﺗﻮاﺑـﻊ و وﻇـﺎﻳﻒ ﻳـﻚ ﺑﺮﻧﺎﻣـﻪ را ﺑـﺮاي‬ ‫ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه اراﺋﻪ دﻫﺪ‪ .‬ﻳﻚ ﻃﺮاح ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﻣﻲ ﺗﻮاﻧﺪ در ﺳﺎﺧﺖ ﺑﺮﻧﺎﻣﻪ ﺧﻮد از اﻣﻜﺎﻧـﺎت ﻳـﻚ ﻳـﺎ ﭼﻨـﺪ ﺳـﺮوﻳﺲ‬ ‫ﻣﺒﺘﻨﻲ ﺑﺮ وب ﺑﻬﺮه ﻣﻨﺪ ﺷﻮد‪.‬‬ ‫‪Data Access Layer‬‬ ‫‪Stored Procedures‬‬

‫‪1‬‬ ‫‪2‬‬

‫‪ 3‬زﻳﺮا اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻧﻴﺎزي ﺑﻪ ﻃﺮاﺣﻲ راﺑﻂ ﻛﺎرﺑﺮي ﻧﺪارﻧﺪ‪.‬‬

‫‪٩١٦‬‬

‫ﻣﺪل ﻻﻳﻪ وب ﺳﺮوﻳﺲ ﻫﺎ‪:‬‬ ‫ﻫﻤﺎﻧﻨﺪ ﻻﻳﻪ ﺧﺎرﺟﻲ)ﻛﻼﺳﻬﺎي ﺧﺎرﺟﻲ ﻛﻪ ﭘﻴﺸﺘﺮ ﺗﻮﺿﻴﺢ داده ﺷﺪ(‪ ،‬وب ﺳﺮوﻳﺲ ﻫـﺎ ﺑﺎﻋـﺚ ﺳـﺎدﮔﻲ اﺳـﺘﻔﺎده از ﺗﻮاﺑـﻊ و ﻧﻴـﺰ ﻛـﺎﻫﺶ‬ ‫ﭘﻴﭽﻴﺪﮔﻲ ﻫﺎي ﻻﻳﻪ ﻣﻴﺎﻧﻲ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎي در ﺣﺎل اﺳﺘﻔﺎده ﻣﻲ ﺷﻮد‪ .‬ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﺮاي اﺳﺘﻔﺎده از ﻳﻚ وب ﺳﺮوﻳﺲ در ﻳﻚ ﺑﺮﻧﺎﻣﻪ‬ ‫ي ﭼﻨﺪ ﻻﻳﻪ ﻛﻪ داراي ﻻﻳﻪ ﻫﺎي دﺳﺘﺮﺳﻲ اﻃﻼﻋﺎت‪ ،‬ﻻﻳﻪ اﺻﻠﻲ ﺗﺠﺎري و ﻻﻳﻪ ﺧﺎرﺟﻲ اﺳﺖ‪ ،‬ﺗﻨﻬﺎ ﻛﺎﻓﻲ اﺳﺖ ﻛﻪ ﺗﻮاﺑﻊ ﻣﺪﻧﻈﺮ از ﻻﻳـﻪ‬ ‫ﺧﺎرﺟﻲ ﮔﺮﻓﺘﻪ ﺷﺪه و ﺗﻮﺳﻂ وب ﺳﺮوﻳﺲ ﻋﺮﺿﻪ ﺷﻮﻧﺪ و ﻣﺎﺑﻘﻲ ﺗﻮاﺑﻊ ﺗﻮﺳﻂ ﻻﻳﻪ ﺧﺎرﺟﻲ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﺑﺎﺷﻨﺪ‪ .‬ﺷـﻜﻞ زﻳـﺮ ﻳـﻚ ﻣـﺪل‬ ‫ﻣﻨﻄﻘﻲ از ﻳﻚ وب ﺳﺮوﻳﺲ را اراﺋﻪ ﻣﻲ دﻫﺪ ﻛﻪ در آن ﺗﻮاﺑﻌﻲ ﻛﻪ ﺗﻮﺳﻂ ﻻﻳﻪ ﺧﺎرﺟﻲ ﻓﺮاﻫﻢ ﻧﺸﺪه اﻧﺪ‪ ،‬ﺑﻪ وﺳﻴﻠﻪ اﻳﻦ وب ﺳﺮوﻳﺲ ﻗﺎﺑﻞ‬ ‫دﺳﺘﺮﺳﻲ ﻫﺴﺘﻨﺪ‪.‬‬

‫ﻳﻚ وب ﺳﺮوﻳﺲ ﻣﻴﺘﻮاﻧﺪ ﻋﻼوه ﺑﺮ ﺗﻮاﺑﻌﻲ ﻛﻪ در ﻻﻳﻪ ﺧﺎرﺟﻲ اراﻳﻪ ﻣﻴﺸﻮﻧﺪ‪ ،‬ﺗﻮاﺑﻊ ﻣﻜﻤﻞ را ﻧﻴﺰ ﺑﻪ ﻻﻳﻪ ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه اراﻳﻪ ﻛﻨﺪ‬

‫ﭼﺮا وب ﺳﺮوﻳﺲ ﻫﺎ؟‬ ‫ﻳﻜﻲ از اﺻﻠﻲ ﺗﺮﻳﻦ ﺳﻮاﻻﺗﻲ ﻛﻪ در اﻳﻦ ﺑﺨﺶ ﺑﺎ آن روﺑﺮو ﻫﺴﺘﻴﻢ اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻣﻲ ﺗﻮان از ﺗﻜﻨﻮﻟﻮژي ﻫـﺎي ﻗﺒﻠـﻲ و راه‬ ‫ﺣﻞ ﻫﺎي ﭘﻴﺸﻴﻦ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﻫﻤﺎﻧﻨﺪ ‪ DCOM‬ﺑﺮاي دﺳﺘﺮﺳﻲ از راه دور اﺳﺘﻔﺎده ﻛﺮد ﭼﻪ ﻧﻴﺎزي ﺑﻪ وب ﺳﺮوﻳﺲ ﻫﺎ اﺳﺖ؟‬

‫‪٩١٧‬‬

‫دﻟﻴﻞ اﺻﻠﻲ اﻳﻦ اﻣﺮ ﻣﺴﺘﻘﻞ ﺑﻮدن وب ﺳﺮوﻳﺲ ﻫﺎ از ﭘﻠﺖ ﻓﺮم اﺳﺖ‪ .‬ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ‪ DCOM‬ﺑﺴﻴﺎري از ﻣﺸﻜﻼت ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎ و ﻧﻴﺰ‬ ‫ﻣﻘﻴﺎس ﭘﺬﻳﺮي آﻧﻬﺎ را ﺣﻞ ﻣﻲ ﻛﻨﺪ‪ ،‬اﻣﺎ واﺑﺴﺘﻪ ﺑﻪ ﭘﻠﺖ ﻓﺮم اﺳﺖ‪ .‬ﺑﺎ اﺳﺘﻔﺎده از وب ﺳﺮوﻳﺲ ﻫﺎ و ﺗﻜﻨﻮﻟﻮژي ﻫـﺎي اﺳـﺘﺎﻧﺪارد ﺻـﻨﻌﺘﻲ از‬ ‫ﻗﺒﻴﻞ ‪ XML،HTTP‬و ‪ SOAP‬ﻣﻲ ﺗﻮان ﻋﻼوه ﺑﺮ ﺑﻬﺮه ﻣﻨﺪ ﺷﺪن از ﺗﻤﺎم اﻣﻜﺎﻧﺎت ﺳﻴﺴﺘﻢ ﻫﺎي ﻗﺒﻠﻲ‪ ،‬از ﻗﺎﺑﻠﻴﺖ ﺳﺎزﮔﺎري ﺑﻴﻦ ﭘﻠﺖ‬ ‫ﻓﺮم ﻫﺎي ﮔﻮﻧﺎﮔﻮن ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﺮد‪.‬‬ ‫ﺳﻴﺴﺘﻢ ﻫﺎي ﻗﺪﻳﻤﻲ ﻣﺎﻧﻨﺪ ‪ DCOM،RPC‬و ‪ MSMQ‬و ‪ ...‬ﻫﻤﮕﻲ ﺳﻌﻲ ﺑﺮ اﻳﻦ دارﻧﺪ ﻛﻪ ﭘﻠﻲ را ﺑﺮاي ارﺗﺒﺎﻃﺎت اﻳﻨﺘﺮﻧﺘﻲ اﻳﺠﺎد ﻛﻨﻨـﺪ و‬ ‫ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ اﻳﻦ ﻣﻮارد در داﺧﻞ ﭘﻠﺖ ﻓﺮم ﻫﺎي ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﻣﻮﻓﻖ ﺑﻮده اﻧﺪ اﻣﺎ در ارﺗﺒﺎط ﺑﺎ دﻳﮕﺮ ﭘﻠﺖ ﻓﺮم ﻫﺎ )ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷـﻜﻞ‬ ‫ﻧﺸﺎن داده ﺷﺪه اﺳﺖ( ﺑﺎ ﻣﺸﻜﻼت زﻳﺎدي روﺑﺮو ﺑﻮدﻧﺪ‪ .‬ﺑﺎ اﺳـﺘﻔﺎده از وب ﺳـﺮوﻳﺲ ﻫـﺎ ﺳـﻌﻲ ﺷـﺪه اﺳـﺖ ﻛـﻪ ﻋﻤـﺪه ﻣـﺸﻜﻼت اﻳـﻦ‬ ‫ﻧﺎﻫﻤﺎﻫﻨﮕﻲ رﻓﻊ ﺷﻮد‪.‬‬

‫ﻧﺎﺳﺎزﮔﺎري ﻗﺎﺑﻠﻴﺖ اﺳﺘﻔﺎده از راه دور ﺑﺪون ﭘﺮوﺗﻜﻞ اﺳﺘﺎﻧﺪارد‬

‫‪٩١٨‬‬

‫ﺿﻤﻴﻤﻪ ي ‪ :3‬ﻣﻌﻤﺎري ﭘﻠﺖ ﻓﺮم ‪.NET Framework‬‬ ‫در اﻳﻦ ﺿﻤﻴﻤﻪ ﺳﻌﻲ ﺷﺪه اﺳﺖ ﻛﻪ ﻣﻌﻤﺎري دروﻧﻲ ﭘﻠﺖ ﻓﺮم ‪ .NET‬ﺑﻪ ﺻﻮرﺗﻲ ﮔﺬرا ﻣﻮرد ﺑﺮرﺳﻲ و ﺗﺤﻠﻴﻞ ﻗﺮار ﮔﻴﺮد‪ .‬ﻫـﺪف از اﻳـﻦ‬ ‫ﺑﺨﺶ ﻧﮕﺎﻫﻲ ﺳﻄﺤﻲ ﺑﻪ ﻣﻌﻤﺎري داﺧﻠﻲ ‪ .NET Framework‬و ﻧﻴﺰ ﻣﻌﺮﻓﻲ ﺗﻜﻨﻮﻟﻮژي ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ اﻳـﻦ ﭘﻠـﺖ ﻓـﺮم درﺑـﺮ‬ ‫دارد‪ .‬ﻫﻤﭽﻨﻴﻦ در اﻳﻦ ﺑﺨﺶ ﭘﺮوﺳﻪ ﺗﺒﺪﻳﻞ ﻳﻚ ﺳﻮرس ﻛﺪ ﺑﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻗﺎﺑﻞ ﺗﻮزﻳﻊ و روش اﺟﺮاي آن در ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ ﻣﻮرد ﺑﺮرﺳﻲ‬ ‫ﻗﺮار ﻣﻲ ﮔﻴﺮد‪.‬‬

‫ﻛﺎﻣﭙﺎﻳﻞ ﺳﻮرس ﻛﺪ ﺑﻪ ﻣﺎژول ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه‪:‬‬ ‫در ﻃﺮاﺣﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ‪ ،‬اوﻟﻴﻦ ﻣﺮﺣﻠﻪ ﺗﻌﻴﻴﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ اي اﺳﺖ ﻛﻪ ﻗﺼﺪ اﻳﺠﺎد آن را دارﻳﻢ‪ ،‬ﺑﺮاي ﻣﺜﺎل ﺑﺮﻧﺎﻣﻪ ي ﺗﺤـﺖ وب‪ ،‬ﺑﺮﻧﺎﻣـﻪ ي‬ ‫ﺗﺤﺖ وﻳﻨﺪوز‪ ،‬وب ﺳﺮوﻳﺲ و ﻳﺎ اﻧﻮاع ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕﺮي ﻛﻪ در ‪ .NET‬ﻣﻲ ﺗﻮان اﻳﺠﺎد ﻛﺮد‪ .‬ﻓﺮض ﻣﻴﻜﻨﻴﻢ ﻛﻪ اﻳﻦ ﻗـﺴﻤﺖ ﻣﻬـﻢ از‬ ‫ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﭘﺎﻳﺎن رﺳﻴﺪه اﺳﺖ و ﻣﺪل ﻛﻠﻲ ﺑﺮﻧﺎﻣﻪ و وﻳﮋﮔﻲ ﻫﺎي آن ﺑﺎ ﺟﺰﺋﻴﺎت ﻛﺎﻣﻞ ﻣﺸﺨﺺ ﺷﺪه اﻧﺪ‪.‬‬ ‫در ﻣﺮﺣﻠﻪ ي ﺑﻌﺪ ﺑﺎﻳﺴﺘﻲ زﺑﺎﻧﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﺎ آن ﻧﻮﺷﺘﻪ ﺧﻮاﻫﺪ ﺷﺪ اﻧﺘﺨﺎب ﺷﻮد‪ .‬اﻳﻦ ﻣﺮﺣﻠﻪ از اﻫﻤﻴﺖ ﺑﺎﻻﻳﻲ ﺑﺮﺧﻮردار اﺳﺖ‪ ،‬زﻳﺮا زﺑﺎﻧﻬﺎي‬ ‫ﻣﺨﺘﻠﻒ اﻣﻜﺎﻧﺎت ﻣﺘﻔﺎوﺗﻲ را اراﺋﻪ ﻣﻲ دﻫﻨﺪ‪ .‬ﺑﺮاي ﻧﻤﻮﻧﻪ در ‪) C‬ﻳﺎ زﺑﺎﻧﻬﺎي واﺑﺴﺘﻪ ﺑﻪ آن ﻣﺎﻧﻨﺪ ‪ C++‬و ‪ (...‬ﻛﻪ ﻳﻚ زﺑـﺎن ﻧـﺴﺒﺘﺎ ﺳـﻄﺢ‬ ‫ﭘﺎﻳﻴﻦ اﺳﺖ ﻃﺮاح ﺑﺮﻧﺎﻣﻪ ﻗﺪرت ﻛﻨﺘﺮل ﻛﺎﻣﻞ ﺑﺮ روي ﺳﻴﺴﺘﻢ را دارد‪ ،‬ﻣﻴﺘﻮاﻧﺪ ﺑﻪ روش دﻟﺨﻮاه ﺣﺎﻓﻈﻪ را ﻣﺪﻳﺮﻳﺖ ﻛﻨﺪ و ﻳﺎ ﺑﻪ راﺣﺘﻲ ﺗـﺮد‬ ‫ﻫﺎي‪ 1‬ﺟﺪﻳﺪ در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﻛﻨﺪ‪ .‬از ﺳﻮي دﻳﮕﺮ زﺑﺎﻧﻬﺎﻳﻲ ﻣﺜﻞ وﻳﮋوال ﺑﻴﺴﻴﻚ‪ ،‬ﺑﻪ ﻃـﺮاح ﺑﺮﻧﺎﻣـﻪ ﻗـﺪرت اﻳﺠـﺎد ﺳـﺮﻳﻊ راﺑﻄﻬـﺎي ﻗـﻮي‬ ‫ﮔﺮاﻓﻴﻜﻲ ﻛﺎرﺑﺮ را ﻣﻴﺪﻫﺪ‪ .‬ﺑﻪ ﻋﻼوه اﻳﻦ زﺑﺎﻧﻬﺎ ﺑﻪ راﺣﺘﻲ ﻣﻴﺘﻮاﻧﻨﺪ ﺑﺎ اﺷﻴﺎي ‪ COM‬و ﻳﺎ ﺑﺎﻧﻜﻬﺎي اﻃﻼﻋﺎﺗﻲ راﺑﻄﻪ ﺑﺮﻗﺮار ﻛﻨﻨﺪ‪.‬‬ ‫اﻟﺒﺘﻪ در ‪ .NET‬ﺑﺎ ﺗﻐﻴﻴﺮاﺗﻲ ﻛﻪ ﻧﺴﺒﺖ ﺑﻪ ﺳﻴﺴﺘﻢ ﻫﺎي ﻗﺒﻠﻲ ﺑﻪ وﺟﻮد آﻣﺪه اﺳﺖ‪ ،‬ﺗﺎ ﺣﺪ ﻣﻤﻜﻦ زﺑﺎﻧﻬﺎي ﻣﺨﺘﻠﻒ ﺑﻪ ﻳﻜﺪﻳﮕﺮ ﺷﺒﻴﻪ ﺷـﺪه‬ ‫اﻧﺪ و از ﻗﺎﺑﻠﻴﺘﻬﺎي ﻧﺴﺒﺘﺎً ﻳﻜﺴﺎﻧﻲ ﺑﺮﺧﻮردار ﻫﺴﺘﻨﺪ‪ .‬دﻟﻴﻞ اﻳﻦ ﻣﻮرد ﻧﻴﺰ در اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻧﻮﺷﺘﻪ ﺷﺪه در اﻳﻦ زﺑﺎﻧﻬﺎ‪ ،‬ﻫﻨﮕﺎم اﺟﺮا‬ ‫از ﻳﻚ ﻣﺤﻴﻂ ﻣﺨﺼﻮص ﺑﻪ ﻧﺎم ‪ CLR‬اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ‪ CLR .‬ﻳﺎ ‪ Common Language Runtime‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ از‬ ‫اﺳﻢ آن ﻧﻴﺰ ﻣﺸﺨﺺ اﺳﺖ ﻳﻚ ﻣﺤﻴﻂ زﻣﺎن اﺟﺮا ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﺗﺤـﺖ ‪ .NET‬ﻧﻮﺷـﺘﻪ ﻣـﻲ ﺷـﻮﻧﺪ‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ وﻳﮋﮔﻴﻬـﺎ و‬ ‫ﻗﺎﺑﻠﻴﺘﻬﺎي ﻣﻮﺟﻮد در ‪ CLR‬ﺑﺮاي ﺗﻤﺎم زﺑﺎﻧﻬﺎﻳﻲ ﻛﻪ از آن اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﻗﺎﺑﻞ اﺳﺘﻔﺎده اﺳﺖ‪ .‬ﺑﺮاي ﻣﺜﺎل اﮔﺮ ‪ CLR‬ﺗﻮاﻧﺎﻳﻲ اﻳﺠﺎد ﺗﺮد‬ ‫ﻫﺎ را داﺷﺘﻪ ﺑﺎﺷﺪ‪ ،‬ﺗﻤﺎم زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻛﻪ از آن اﺳﺘﻔﺎده ﻣـﻲ ﻛﻨﻨـﺪ ﻧﻴـﺰ ﻗﺎﺑﻠﻴـﺖ اﻳﺠـﺎد ﺗـﺮد ﻫـﺎ را دارﻧـﺪ‪ .‬اﮔـﺮ اﻳـﻦ ﻣﺤـﻴﻂ از‬ ‫‪Exception‬ﻫﺎ ﺑﺮاي ﭘﻴﮕﻴﺮي اﺳﺘﺜﻨﺎ ﻫﺎي ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻛﻨﺪ‪ ،‬ﺗﻤﺎم زﺑﺎﻧﻬﺎ ﻧﻴﺰ ﻫﻤﻴﻦ روش را دﻧﺒﺎل ﺧﻮاﻫﻨﺪ ﻛﺮد‪.‬‬ ‫در ﺣﻘﻴﻘﺖ در زﻣﺎن اﺟﺮا اﻳﻦ ﻣﻮرد ﻛﻪ در ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ از ﭼﻪ زﺑﺎﻧﻲ اﺳﺘﻔﺎده ﺷﺪه اﺳﺖ ﺗﻔﺎوﺗﻲ ﻧﺪارد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎم اﻧﺘﺨﺎب زﺑﺎن ﺑﺮﻧﺎﻣﻪ‬ ‫ﻧﻮﻳﺴﻲ ﻣﻬﻤﺘﺮﻳﻦ ﻣﻮﺿﻮﻋﻲ ﻛﻪ ﺑﺎﻳﺪ ﻣﺪﻧﻈﺮ ﻗﺮار ﮔﻴﺮد اﻳﻦ اﺳﺖ ﻛﻪ ﺑﺎ اﺳﺘﻔﺎده از ﭼﻪ زﺑﺎﻧﻲ ﻣﻲ ﺗﻮان ﺑﺮﻧﺎﻣﻪ را ﺳـﺎده ﺗـﺮ و ﺳـﺮﻳﻌﺘﺮ ﭘﻴـﺎده‬ ‫ﺳﺎزي ﻛﺮد‪.‬‬ ‫ﺳﻮاﻟﻲ ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ در اﻳﻦ ﻗﺴﻤﺖ اﻳﺠﺎد ﺷﻮد اﻳﻦ اﺳﺖ ﻛﻪ اﮔﺮ اﺳﺘﻔﺎده از زﺑﺎﻧﻬﺎي ﻣﺨﺘﻠﻒ ﺗﻔﺎوﺗﻲ ﻧﺪارد‪ ،‬ﭘﺲ دﻟﻴﻞ وﺟﻮد ﭼﻨﺪ زﺑﺎن‬ ‫ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﭼﻴﺴﺖ؟ در ﭘﺎﺳﺦ ﺑﻪ اﻳﻦ ﺳﻮال ﻣﻴﺘﻮان ﮔﻔﺖ ﻛﻪ زﺑﺎﻧﻬﺎي ﻣﺨﺘﻠﻒ ﮔﺮاﻣﺮ و ﺳﻴﻨﺘﻜﺲ ﻫﺎي ﻣﺘﻔﺎوﺗﻲ دارﻧﺪ‪ .‬اﻫﻤﻴﺖ اﻳﻦ‬ ‫ﻣﻮرد را ﻧﺒﺎﻳﺪ ﻧﺎﭼﻴﺰ در ﻧﻈﺮ ﮔﺮﻓﺖ‪ .‬ﺑﺮاي ﻣﺜﺎل ﻃﺮاﺣﻲ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺮاي اﺳﺘﻔﺎده در اﻣﻮر اﻗﺘﺼﺎدي‪ ،‬ﺑﺎ اﺳﺘﻔﺎده از ﮔﺮاﻣﺮ ﻣﻮﺟﻮد در زﺑﺎﻧﻬﺎﻳﻲ‬ ‫ﻣﺜﻞ ‪ APL‬ﻧﺴﺒﺖ ﺑﻪ ‪ Perl‬ﻣﻮﺟﺐ ﭼﻨﺪﻳﻦ روز ﺻﺮﻓﻪ ﺟﻮﻳﻲ در زﻣﺎن ﭘﻴﺎده ﺳﺎزي ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺷﻮد‪.‬‬ ‫ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﭼﻨﺪﻳﻦ ﻛﺎﻣﭙﺎﻳﻠﺮ ﺑﺮاي اﺳﺘﻔﺎده از ‪ CLR‬ﺑﺮاي زﺑﺎﻧﻬﺎي ﻣﺨﺘﻠﻒ اراﺋﻪ داده اﺳﺖ ﻛﻪ در ﻣﺠﻤﻮﻋﻪ اي ﺑﻪ ﻧـﺎم ‪Visual‬‬ ‫‪ Studio‬ﻗﺮار دارﻧﺪ‪ .‬اﻳﻦ زﺑﺎﻧﻬﺎ ﻋﺒﺎرﺗﻨﺪ از‪:‬‬

‫‪Thread‬‬

‫‪1‬‬

‫‪٩١٩‬‬

‫‬ ‫‬ ‫‬ ‫‬ ‫‬ ‫‬

‫‪Visual C++ with Managed Extensions‬‬ ‫‪C#‬‬ ‫‪Visual Basic‬‬ ‫‪Jscript‬‬ ‫‪J#‬‬ ‫‪ IL‬ﻛﻪ ﻳﻚ اﺳﻤﺒﻠﺮ ﺳﻄﺢ ﻣﻴﺎﻧﻲ ﺑﻪ ﺷﻤﺎر ﻣﻲ رود‪.‬‬

‫ﻋﻼوه ﺑﺮ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﺷﺮﻛﺘﻬﺎي دﻳﮕﺮ ﻧﻴﺰ ﺑﺮاي زﺑﺎﻧﻬﺎي ﺧﻮد ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎﻳﻲ را ﻋﺮﺿﻪ ﻛﺮده اﻧﺪ ﻛﻪ ‪ CLR‬را ﺑـﻪ ﻋﻨـﻮان ﻣﺤـﻴﻂ زﻣـﺎن‬ ‫اﺟﺮاي ﻧﻬﺎﻳﻲ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار داده اﻧﺪ‪ .‬ﺗﺎﻛﻨﻮن ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎﻳﻲ ﺑـﺮاي زﺑﺎﻧﻬـﺎي زﻳـﺮ اراﻳـﻪ ﺷـﺪه اﻧـﺪ‪،Cobol ،APL ،Alice:‬‬ ‫‪،Mondrian ،ML ،Mercury ،Haskell ،Fortran ،Eiffel ،Component‬‬ ‫‪Pascal‬‬ ‫‪ Scheme ،RPG ،Python ،Perl ،Oberon‬و ‪.Smalltalk‬‬ ‫ﺷﻜﻞ زﻳﺮ ﭘﺮوﺳﻪ ي ﻛﺎﻣﭙﺎﻳﻞ ﻓﺎﻳﻠﻬﺎي ﺳﻮرس ﻛﺪ را ﻧﻤﺎﻳﺶ ﻣﻴﺪﻫﺪ‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ ﻣﺸﺨﺺ اﺳﺖ‪ ،‬ﺑﺪون ﺗﻮﺟﻪ ﺑﻪ ﻛﺎﻣﭙﺎﻳﻠﺮي ﻛﻪ‬ ‫‪2‬‬ ‫ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد ﺧﺮوﺟﻲ ﺗﻤﺎم آﻧﻬﺎ ﻳﻚ ﻣﺎژول ﻣﺪﻳﺮﻳﺖ ﺷﺪه‪ 1‬اﺳﺖ‪ .‬ﻣﺎژول ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه در ﺣﻘﻴﻘﺖ ﻓﺎﻳﻠﻬـﺎي اﺟﺮاﻳـﻲ‬ ‫اﺳﺘﺎﻧﺪارد وﻳﻨﺪوز ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﺮاي اﺟﺮا ﺷﺪن ﺑﻪ ‪ CLR‬ﻧﻴﺎز دارﻧﺪ‪.‬‬

‫ﻛﺎﻣﭙﺎﻳﻞ ﺳﻮرس ﻛﺪﻫﺎ ﺑﻪ ﻣﺎژول ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه‬ ‫ﻳﻚ ﻣﺎژول ﻣﺪﻳﺮﻳﺖ ﺷﺪه از ﻗﺴﻤﺘﻬﺎي ﻣﺨﺘﻠﻔﻲ ﺗﺸﻜﻴﻞ ﺷﺪه اﺳﺖ ﻛﻪ در ﺟﺪول زﻳﺮ ﺗﻮﺿﻴﺢ داده ﺷﺪه اﺳﺖ‪:‬‬ ‫ﺑﺨﺶ‬ ‫‪PE Header‬‬

‫ﺗﻮﺿﻴﺢ‬ ‫در اﻳــــﻦ ﻫــــﺪر ﻣــــﻮاردي از ﻗﺒﻴــــﻞ ﻧــــﻮع ﻓﺎﻳــــﻞ‬ ‫)‪ (GUI,CUI,DLL‬و ﻳﺎ ﺗﺎرﻳﺦ ﻫﺎي ﻣﺮﺑـﻮط ﺑـﻪ اﻳﺠـﺎد‬ ‫ﻓﺎﻳﻞ‪ ،‬آﺧﺮﻳﻦ ﺗﻐﻴﻴﺮات و ‪ ...‬ﻗﺮار دارﻧﺪ‪ .‬ﺑﺮاي ﻓﺎﻳﻠﻬﺎﻳﻲ ﻛـﻪ ﻓﻘـﻂ‬ ‫ﺷﺎﻣﻞ ﻛﺪ ‪ IL‬ﻫﺴﺘﻨﺪ اﻳﻦ ﻗﺴﻤﺖ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻧﻤﻲ ﺷﻮد اﻣـﺎ‬

‫‪ – Managed Module 1‬ﻣﻨﻈﻮر ﻛﺪ ﻫﺎﻳﻲ ﻫﺴﺘﻨﺪ ﻛﻪ در زﻣﺎن اﺟﺮا ﺷﺪن ﺑﻪ وﺳﻴﻠﻪ ي ‪ CLR‬ﻣﺪﻳﺮﻳﺖ ﻣﻲ ﺷﻮﻧﺪ‪ .‬در ﻣﻘﺎﺑﻞ ﻣﺎژول ﻫﺎي ﻣـﺪﻳﺮﻳﺖ ﺷـﺪه‪،‬‬ ‫ﻣﺎژول ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه وﺟﻮد دارﻧﺪ ﻛﻪ ﺑﻪ ﺻﻮرت ﻋﺎدي و ﺑﺪون ﻧﻈﺎرت ﻳﻚ ﻣﺤﻴﻂ زﻣﺎن اﺟﺮا ﻣﺎﻧﻨﺪ ‪ ،CLR‬ﺑﻪ وﺳﻴﻠﻪ ي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ اﺟـﺮا ﻣـﻲ ﺷـﻮﻧﺪ‪ .‬ﻧﻤﻮﻧـﻪ‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه‪ ،‬ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﺑﻪ ﺻﻮرت ﻋﺎدي ﺑﻪ وﺳﻴﻠﻪ ي ‪ .NET‬اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ‪ .‬ﻧﻤﻮﻧﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣـﺪﻳﺮﻳﺖ ﻧـﺸﺪه ﻧﻴـﺰ‪ ،‬ﻓﺎﻳﻠﻬـﺎي اﺟﺮاﻳـﻲ‬ ‫ﻣﻌﻤﻮﻟﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺧﺎرج از ﻣﺤﻴﻂ ‪ .NET‬اﻳﺠﺎد ﺷﺪه اﻧﺪ‪.‬‬ ‫‪2‬‬ ‫)‪Portable Executable Files (PE Files‬‬

‫‪٩٢٠‬‬

‫ﺑﺮاي ﻓﺎﻳﻠﻬﺎﻳﻲ ﻛﻪ ﺷﺎﻣﻞ ﻛﺪ زﺑﺎن ﻣﺎﺷﻴﻦ ﻫﺴﺘﻨﺪ اﻳـﻦ ﻗـﺴﻤﺖ‬ ‫ﻣﺤﺘﻮي اﻃﻼﻋﺎﺗﻲ راﺟﻊ ﺑﻪ ﻛﺪ ﻧﻴﺰ ﻫﺴﺖ‪.‬‬ ‫‪CLR header‬‬ ‫اﻳﻦ ﻗﺴﻤﺖ ﺷﺎﻣﻞ اﻃﻼﻋﺎﺗﻲ اﺳﺖ ﻛﻪ ﻓﺎﻳﻞ ﻣﻮرد ﻧﻈﺮ را ﺑﻪ ﻳﻚ‬ ‫ﻣﺎژول ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﺗﺒﺪﻳﻞ ﻣﻴﻜﻨـﺪ )اﻳـﻦ ﻗـﺴﻤﺖ از ﻓﺎﻳـﻞ ﺑـﻪ‬ ‫وﺳﻴﻠﻪ ‪ CLR‬و ﻳﺎ ﺑﺮﻧﺎﻣﻪ ﻫـﺎي واﺑـﺴﺘﻪ ﺗﻔـﺴﻴﺮ ﻣﻴـﺸﻮد(‪ .‬اﻳـﻦ‬ ‫ﻗﺴﻤﺖ ﺷﺎﻣﻞ ﻧﺴﺨﻪ ‪ CLR‬ﻣﻮرد اﺳﺘﻔﺎده ﺑﺮاي ﻓﺎﻳﻞ‪ ،‬ﻣﻜـﺎن و‬ ‫اﻧﺪازه ‪ metadata‬در ﻓﺎﻳﻞ‪ ،‬ﻣﻨﺎﺑﻊ‪ ،‬ﺗﻌﺪادي ﻓﻠﮓ ﺧﺎص و‬ ‫آدرس ورودي ﻣﺮﺑـــﻮط ﺑـــﻪ ﻓﺎﻳـــﻞ آﻏـــﺎزﻳﻦ ﺑﺮﻧﺎﻣـــﻪ در‬ ‫‪ metadata‬اﺳﺖ‪.‬‬ ‫‪Metadata‬‬ ‫ﻫﺮ ﻣﺎژول ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﺷﺎﻣﻞ ﺟﺪول ﻫﺎﻳﻲ اﺳﺖ ﻛـﻪ ﺑـﻪ ﻧـﺎم‬ ‫‪ metadata‬ﺷﻨﺎﺧﺘﻪ ﻣﻲ ﺷﻮﻧﺪ‪ .‬دو ﻧـﻮع ﺟـﺪول ﻛﻠـﻲ در‬ ‫اﻳﻦ ﻗﺴﻤﺖ وﺟﻮد دارﻧـﺪ‪ .‬ﻧـﻮع اول ﺷـﺎﻣﻞ ﺟـﺪاوﻟﻲ اﺳـﺖ ﻛـﻪ‬ ‫اﻃﻼﻋﺎت ﻣﺮﺑﻮط ﺑﻪ ﻛـﻼس ﻫـﺎ و ﺗﻮاﺑـﻊ ﻣﻮﺟـﻮد در ﺑﺮﻧﺎﻣـﻪ را‬ ‫ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ‪ .‬ﻧﻮع دوم ﺷﺎﻣﻞ ﺟﺪاوﻟﻲ اﺳـﺖ ﻛـﻪ ﻣﺤﺘـﻮي‬ ‫ﻛﻼس ﻫﺎ و ﺗﻮاﺑﻊ ﺧﺎرﺟﻲ اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ اﻳـﻦ ﻓﺎﻳـﻞ ﻣـﻮرد‬ ‫اﺳﺘﻔﺎده ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ‪.‬‬ ‫ﻛـﺪ ﻫـﺎي ‪ Intermediate Language‬ﻛﺪي اﺳﺖ ﻛﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻣﻮﻗﻊ ﻛﺎﻣﭙﺎﻳﻞ ﺳﻮرس ﻛـﺪ ﺗﻮﻟﻴـﺪ ﻣـﻲ‬ ‫)‪(IL‬‬ ‫ﻛﻨﺪ‪ .‬ﻣﻮﻗﻊ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ‪ CLR ،‬اﻳﻦ ﻛﺪ را ﺑﻪ وﺳﻴﻠﻪ ي ‪JIT‬‬ ‫ﺑﻪ ﻛﺪ زﺑﺎن ﻣﺎﺷﻴﻦ ﺗﺒﺪﻳﻞ ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﺑﻴﺸﺘﺮ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎي ﻗﺒﻠﻲ‪ ،‬ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﻣﻌﻤﺎري ﺧﺎص از ﭘﺮدازﻧﺪه را ﺗﻮﻟﻴﺪ ﻣﻴﻜﺮدﻧﺪ‪ .‬ﺑـﺮاي ﻣﺜـﺎل ﻛـﺪ ﻫـﺎﻳﻲ ﻣﺮﺑـﻮط ﺑـﻪ ‪،x86‬‬ ‫‪ Alpha ،IA64‬و ﻳﺎ ‪ .PowerPC‬اﻣﺎ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎي ﺳﺎزﮔﺎر ﺑﺎ ‪ CLR‬ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ ﺳﻮرس ﺑﺮﻧﺎﻣﻪ ﻛﺪ ﻫﺎي ‪ IL‬ﺗﻮﻟﻴﺪ ﻣـﻲ‬ ‫ﻛﻨﻨﺪ‪ .‬در ﺣﻘﻴﻘﺖ اﻳﻦ ﻛﺪ ﻫﺎي ‪ IL‬ﻫﺴﺘﻨﺪ ﻛﻪ از آﻧﻬﺎ ﺑﻪ ﻋﻨﻮان ﻣﺎژول ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﻳﺎد ﻣﻲ ﺷﻮد‪ ،‬زﻳـﺮا ‪ CLR‬ﻣـﺴﺌﻮل ﻣـﺪﻳﺮﻳﺖ‬ ‫اﻳﻦ ﻛﺪﻫﺎ در زﻣﺎن اﺟﺮا اﺳﺖ‪.‬‬ ‫ﻋﻼوه ﺑﺮ ﺗﻮﻟﻴﺪ ﻛﺪ ‪ ،IL‬ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎي ﺳﺎزﮔﺎر ﺑﺎ ‪ CLR‬وﻇﻴﻔﻪ دارﻧﺪ ﻛﻪ اﻃﻼﻋﺎت ﻛﺎﻣﻞ ‪ metadata‬را ﻧﻴﺰ در ﻓﺎﻳﻞ ﻗﺮار دﻫﻨﺪ‪ .‬ﺑﻪ‬ ‫ﺑﻴﺎن ﺳﺎده‪ metadata ،‬ﺟﺪوﻟﻲ دروﻧﻲ در ﻓﺎﻳﻞ اﺳﺖ ﻛﻪ ﺗﻮﺿﻴﺤﺎﺗﻲ راﺟﻊ ﺑﻪ ﻛﻼس ﻫﺎ و ﺗﻮاﺑﻊ اﺳﺘﻔﺎده ﺷﺪه در ﺑﺮﻧﺎﻣـﻪ را ﺷـﺎﻣﻞ‬ ‫ﻣﻲ ﺷﻮد‪ .‬ﺑﻪ ﻋﻼوه‪ metadata ،‬ﺷﺎﻣﻞ ﺟﺪوﻟﻲ اﺳﺖ ﻛﻪ ﻣﺤﺘـﻮي ﻛـﻼس ﻫـﺎي ﺧـﺎرﺟﻲ اﺳـﺖ ﻛـﻪ ﺑﺮﻧﺎﻣـﻪ اﺳـﺘﻔﺎده ﻣـﻲ ﻛﻨـﺪ‪.‬‬ ‫‪ Metadata‬در ﺣﻘﻴﻘﺖ ﻧﺴﺨﻪ ﺟﺪﻳﺪ ﺗﻜﻨﻮﻟﻮژي ﻫﺎﻳﻲ ﻣﺜﻞ ‪ Type Library‬و ﻳﺎ ﻓﺎﻳﻠﻬﺎي ‪ 1IDL‬اﺳﺖ‪ .‬اﻣﺎ ﻧﻜﺘﻪ ﻣﻬـﻢ‬ ‫اﻳﻦ اﺳﺖ ﻛﻪ ‪ metadata‬ﻧﺴﺒﺖ ﺑﻪ اﻳﻦ ﺗﻜﻨﻮﻟﻮژي ﻫﺎ ﺑﺴﻴﺎر ﻛﺎﻣﻠﺘﺮ اﺳﺖ و ﺑﺮ ﺧﻼف ﻣـﻮارد ذﻛـﺮ ﺷـﺪه‪metadata ،‬ﻫـﺎ در‬ ‫ﻓﺎﻳﻠﻲ ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ ﻛﻪ ﻣﺤﺘﻮي ﻛﺪ ‪ IL‬اﺳﺖ‪ .‬ﺑﻪ دﻟﻴﻞ اﻳﻨﻜﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ اﻳﻦ اﻃﻼﻋﺎت را ﻫﻨﮕـﺎم اﺟـﺮاي ﻛـﺪ ﺗﻮﻟﻴـﺪ ﻣـﻲ ﻛﻨـﺪ‪ ،‬اﻣﻜـﺎن‬ ‫ﻧﺎﻫﻤﺎﻫﻨﮕﻲ ﺑﻴﻦ اﻳﻦ اﻃﻼﻋﺎت و ﻛﺪ اﺻﻠﻲ ﻧﻴﺰ از ﺑﻴﻦ ﺧﻮاﻫﺪ رﻓﺖ‪.‬‬ ‫ﺑﻌﻀﻲ از ﻣﻮارد اﺳﺘﻔﺎده ‪metadata‬ﻋﺒﺎرت اﻧﺪ از‪:‬‬ ‫‪(1‬‬

‫‪ Metadata‬ﻧﻴﺎز ﺑﻪ ﻓﺎﻳﻞ ﻫﺎي ﻫﺪر و ﻳﺎ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎ را ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ ﺣﺬف ﻣﻲ ﻛﻨﺪ‪ ،‬زﻳﺮا ﺗﻤﺎم اﻃﻼﻋﺎت‬ ‫ﻣﻮرد ﻧﻴﺎز در ﻣﻮرد ﺗﻮاﺑﻊ و ﻛﻼﺳﻬﺎي اﺳﺘﻔﺎده ﺷﺪه در ﻓﺎﻳﻞ ﺣﺎوي ﻛﺪ ‪ IL‬در ﺧﻮد ﻓﺎﻳﻞ ﻗﺮار دارﻧﺪ‪ .‬ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫـﺎ‬ ‫ﻣﻲ ﺗﻮاﻧﻨﺪ اﻃﻼﻋﺎت ‪ metadata‬را ﺑﻪ ﺻﻮرت ﻣﺴﺘﻘﻴﻢ از داﺧﻞ ﻓﺎﻳﻠﻬﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه اﺳﺘﺨﺮاج ﻛﺮده و از‬ ‫آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﻨﻨﺪ‪.‬‬ ‫‪Interface Definition Language‬‬

‫‪1‬‬

‫‪٩٢١‬‬

‫‪(2‬‬

‫‪(3‬‬

‫‪(4‬‬ ‫‪(5‬‬

‫ﻣﺤﻴﻂ ﻫﺎي ﻃﺮاﺣﻲ از ﻗﺒﻴﻞ وﻳﮋوال اﺳﺘﻮدﻳﻮ‪ ،‬از اﻳﻦ اﻃﻼﻋﺎت ﺑﺮاي ﻛﻤﻚ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻫﻨﮕـﺎم ﻧﻮﺷـﺘﻦ ﻛـﺪ‬ ‫اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ‪ .‬در ﺣﻘﻴﻘﺖ وﻳﮋﮔﻲ ﻫﻮﺷﻴﺎري در وﻳﮋوال اﺳﺘﻮدﻳﻮ )‪ (IntelliSense‬ﻛﻪ ﺑﺮاي ﻛﺎﻣﻞ‬ ‫ﻛﺮدن ﻛﺪﻫﺎ و ﻧﻤﺎﻳﺶ اﻃﻼﻋﺎت ﻻزم در ﻣﻮرد ﺗﻮاﺑﻊ ﻣﻮرد اﺳﺘﻔﺎده در ﻛﺪ ﺑﻪ ﻛﺎر ﻣـﻲ رود‪ ،‬ﺑـﺎ اﺳـﺘﻔﺎده از ﺗﺤﻠﻴـﻞ‬ ‫اﻃﻼﻋﺎت ﻣﻮﺟﻮد در ‪ metadata‬اﻧﺠﺎم ﻣﻲ ﺷﻮد‪.‬‬ ‫وﻳﮋﮔﻲ ﺑﺮرﺳﻲ و ﺗﺎﻳﻴﺪ اﻣﻨﻴﺖ ﻛﺪ‪ ،‬ﺑﺎ اﺳﺘﻔﺎده از اﻃﻼﻋﺎت ﻣﻮﺟـﻮد در ‪ metadata‬ﺻـﻮرت ﻣـﻲ ﮔﻴـﺮد‪ .‬ﺑـﻪ‬ ‫ﻛﻤﻚ اﻳﻦ وﻳﮋﮔﻲ ‪ CLR‬ﻣﻮﺟﺐ ﻣﻲ ﺷﻮد ﻛﻪ ﻓﻘﻂ ﻛﺪ ﻫﺎﻳﻲ ﻛﻪ داراي دﺳﺘﻮرات ﺗﺒﺪﻳﻞ ﻣﺘﻐﻴﻴﺮ ﺑﻪ ﺻﻮرت اﻣـﻦ‬ ‫)‪ (Safe‬ﻫﺴﺘﻨﺪ ﺻﻮرت ﮔﻴﺮﻧﺪ )‪.(Verification‬‬ ‫‪1‬‬ ‫‪ Metadata‬ﺑﻪ ﻳﻚ ﺷﻴﺊ اﺟﺎزه ﻣﻲ دﻫﺪ ﻛﻪ ﺳﺮﻳﺎﻻﻳﺰ ﺷﺪه و در ﺣﺎﻓﻈﻪ ﻗﺮار ﮔﻴﺮد ‪ ،‬ﺑﻪ وﺳـﻴﻠﻪ ﺷـﺒﻜﻪ ﺑـﻪ‬ ‫ﻳﻚ وﺳﻴﻠﻪ دﻳﮕﺮ ﻣﻨﺘﻘﻞ ﺷﻮد و در آﻧﺠﺎ ﻣﺠﺪداً ﺑﻪ ﺣﺎﻟﺖ اوﻟﻴﻪ ﺗﺒﺪﻳﻞ ﺷﻮد‪.‬‬ ‫‪ Metadata‬ﺑﻪ ‪ 2GC‬اﻳﻦ اﻣﻜﺎن را ﻣﻲ دﻫﺪ ﻛﻪ ﻃﻮل ﻋﻤﺮ اﺷﻴﺎ را ﻛﻨﺘﺮل ﻛﻨـﺪ‪ ،‬در ﺻـﻮرت ﻟـﺰوم آﻧﻬـﺎ را‬ ‫ﺣﺬف ﻛﺮده و ﺣﺎﻓﻈﻪ ﺗﺨﺼﻴﺺ داده ﺷﺪه ﺑﻪ آﻧﻬﺎ را آزاد ﻛﻨﺪ‪ .‬ﺑﺮاي ﺗﻤﺎم اﻧﻮاع اﺷﻴﺎ‪ GC ،‬ﻣﻲ ﺗﻮاﻧﺪ ﻧـﻮع ﺷـﻴﺊ را‬ ‫ﺗﺸﺨﻴﺺ دﻫﺪ و ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ‪ metadata‬ﺗﺮﺗﻴﺐ اﺷﺎره اﺷﻴﺎ ﺑﻪ ﻳﻜﺪﻳﮕﺮ را ﺗﺸﺨﻴﺺ دﻫﺪ‪.‬‬

‫ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎي زﺑﺎن ﻫﺎي ‪ J# ،Jscript ،Visual Basic ،C#‬و ﻧﻴﺰ اﺳﻤﺒﻠﺮ ‪ IL‬ﻫﻤﻮاره ﻣﺎژول ﻫﺎي ﻣﺪﻳﺮﻳﺖ‬ ‫ﺷﺪه اي ﺗﻮﻟﻴﺪ ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ ﺑﺮاي اﺟﺮا ﺑﻪ ‪ CLR‬اﺣﺘﻴﺎج دارﻧﺪ‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﺑﺮاي اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ‪ VB 6‬و ﻳـﺎ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي‬ ‫‪ MFC‬در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﻘﺼﺪ‪ ،‬ﺑﻪ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ‪ Visual Basic‬و ﻳﺎ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ‪ 3MFC‬ﻧﻴﺎز اﺳﺖ‪ ،‬اﺟﺮاي ﻓﺎﻳﻞ ﻫﺎي‬ ‫ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﻛﻪ ﺗﻮﺳﻂ اﻳﻦ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎ ﺗﻮﻟﻴﺪ ﻣﻲ ﺷﻮﻧﺪ ﻧﻴﺰ ﺑﻪ ‪ CLR‬اﺣﺘﻴﺎج دارﻧﺪ‪.‬‬ ‫ﻛﺎﻣﭙﺎﻳﻠﺮ ‪ C++‬ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﺑﺮ ﺧﻼف دﻳﮕﺮ زﺑﺎن ﻫﺎ‪ ،‬ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه )ﻛﺪ ﻫﺎي ﻋﺎدي ‪ EXE‬و ﻳﺎ ‪ DLL‬ﻛﻪ ﻫﻢ اﻛﻨـﻮن‬ ‫وﺟﻮد دارﻧﺪ( ﺗﻮﻟﻴﺪ ﻣﻲ ﻛﻨﺪ‪ .‬اﻳﻦ ﻓﺎﻳﻠﻬﺎ ﺑﺮاي اﺟﺮا ﺑﻪ ‪ CLR‬ﻧﻴﺎز ﻧﺪارﻧﺪ‪ .‬ﺑﺮاي ﺗﻮﻟﻴﺪ ﻛﺪ ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﺗﻮﺳﻂ اﻳﻦ ﻛﺎﻣﭙﺎﻳﻠﺮ ﺑﺎﻳﺪ ﻫﻨﮕﺎم‬ ‫ﻛﺎﻣﭙﺎﻳﻞ از ﻳﻜﻲ از ﺳﻮﻳﻴﭻ ﻫﺎي ﺧﻂ ﻓﺮﻣﺎن اﺳﺘﻔﺎده ﻛﺮد‪ .‬ﺑﻴﻦ ﺗﻤﺎم ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎﻳﻲ ﻛﻪ ذﻛﺮ ﺷﺪ ﻓﻘﻂ ﻛﺎﻣﭙﺎﻳﻠﺮ ‪ C++‬ﻣﺎﻳﻜﺮوﺳـﺎﻓﺖ‬ ‫اﻳﻦ اﻣﻜﺎن را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻣﻲ دﻫﺪ ﻛﻪ در ﻳﻚ ﻣﺎژول از ﻫﺮ دو ﻧﻮع ﻛﺪ ﻣﺪﻳﺮﻳﺖ ﺷـﺪه و ﻣـﺪﻳﺮﻳﺖ ﻧـﺸﺪه اﺳـﺘﻔﺎده ﻛﻨـﺪ‪ .‬اﻳـﻦ‬ ‫ﻣﻮﺿﻮع ﻫﻨﮕﺎم ﻃﺮاﺣﻲ ﻛﺪ اﻳﻦ اﻣﻜﺎن را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻣﻲ دﻫﺪ ﻛﻪ ﻛﻼﺳﻬﺎي ﺟﺪﻳﺪ ﺧﻮد را ﺑﻪ ﺻـﻮرت ﻣـﺪﻳﺮﻳﺖ ﺷـﺪه اﻳﺠـﺎد‬ ‫ﻛﺮده‪ ،‬وﻟﻲ ﻫﻤﭽﻨﺎن از ﻛﻼﺳﻬﺎي ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه ﻗﺒﻠﻲ ﻧﻴﺰ اﺳﺘﻔﺎده ﻛﻨﺪ‪.‬‬

‫ﺗﺮﻛﻴﺐ ﻣﺎژول ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه در اﺳﻤﺒﻠﻲ ﻫﺎ‪:‬‬ ‫در واﻗﻌﻴﺖ ‪ CLR‬ﺑﺎ ﻣﺎژول ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﻛﺎر ﻧﻤﻲ ﻛﻨﺪ‪ ،‬ﺑﻠﻜﻪ ﺑﺎ اﺳﻤﺒﻠﻲ ﻫﺎ ﻛﺎر ﻣﻲ ﻛﻨﺪ‪ .‬اﺳﻤﺒﻠﻲ‪ ،‬ﻣﻔﻬﻮﻣﻲ اﻧﺘﺰاﻋﻲ اﺳﺖ ﻛـﻪ‬ ‫درك آن ﻣﻤﻜﻦ اﺳﺖ اﺑﺘﺪا ﻣﺸﻜﻞ ﺑﻪ ﻧﻈﺮ رﺳﺪ‪ .‬در ﺗﻌﺮﻳﻒ اول‪ ،‬اﺳﻤﺒﻠﻲ ﻳﻚ ﺗﺮﻛﻴﺐ ﻣﻨﻄﻘﻲ از ﻳﻚ ﻳﺎ ﭼﻨﺪ ﻣـﺎژول ﻣـﺪﻳﺮﻳﺖ ﺷـﺪه‬ ‫اﺳﺖ‪ .‬در ﺗﻌﺮﻳﻒ دوم ﻣﻴﺘﻮان ﮔﻔﺖ ﻛﻪ اﺳﻤﺒﻠﻲ ﻛﻮﭼﻜﺘﺮﻳﻦ واﺣﺪي اﺳﺖ ﻛﻪ ﻗﺎﺑﻠﻴﺖ اﺳﺘﻔﺎده ﻣﺠـﺪد‪ ،4‬ﺗﻌﻴـﻴﻦ ﺳـﻄﻮح اﻣﻨﻴﺘـﻲ و ﻳـﺎ‬ ‫ﺗﻌﻴﻴﻦ ﻧﺴﺨﻪ‪ 5‬را دارد‪ .‬ﺑﺴﺘﻪ ﺑﻪ اﻧﺘﺨﺎب ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻣﻲ ﺗﻮان ﺑﻪ وﺳﻴﻠﻪ اﺑﺰارﻫﺎي ﻣﻮرد اﺳـﺘﻔﺎده ﺑـﺮاي ﻛﺎﻣﭙﺎﻳـﻞ ﺑﺮﻧﺎﻣـﻪ‪ ،‬ﻓﺎﻳﻠﻬـﺎي‬ ‫اﺳﻤﺒﻠﻲ ﻳﺎ ﻣﺎژول ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﺗﻮﻟﻴﺪ ﻛﺮد‪.‬‬ ‫ﺷﻜﻞ زﻳﺮ ﺑﻪ درك ﻣﻔﻬﻮم اﺳﻤﺒﻠﻲ ﻛﻤﻚ ﻣﻲ ﻛﻨﺪ‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ در اﻳﻦ ﺷﻜﻞ ﻣﺸﺎﻫﺪه ﻣﻲ ﻛﻨﻴﺪ‪ ،‬ﺑﻌﻀﻲ ﻣﺎژول ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷـﺪه‬ ‫و ﻣﻨﺎﺑﻊ ﺑﺮﻧﺎﻣﻪ ﺑﻪ وﺳﻴﻠﻪ ﻳﻚ اﺑﺰار ﺗﺤﺖ ﭘﺮدازش ﻗﺮار ﮔﺮﻓﺘﻪ اﻧﺪ‪ .‬اﻳﻦ اﺑﺰار ﻳﻚ ﻓﺎﻳﻞ اﺟﺮاﻳﻲ ﺗﻮﻟﻴﺪ ﻣﻲ ﻛﻨﺪ ﻛﻪ ﮔﺮوه ﺑﻨﺪي ﻣﻨﻄﻘـﻲ‬ ‫‪1‬‬

‫‪Serialization‬‬ ‫‪Garbage Collector‬‬ ‫‪3‬‬ ‫‪Microsoft Foundation Class‬‬ ‫‪4‬‬ ‫‪Reusability‬‬ ‫‪5‬‬ ‫‪Versioning‬‬ ‫‪2‬‬

‫‪٩٢٢‬‬

‫ﭼﻨﺪ ﻓﺎﻳﻞ را ﺑﻴـﺎن ﻣـﻲ ﻛﻨـﺪ‪ .‬ﻓﺎﻳـﻞ ﺗﻮﻟﻴـﺪ ﺷـﺪه ﺷـﺎﻣﻞ ﻳـﻚ ﺑـﻼك داده اي اﺳـﺖ ﻛـﻪ ‪ manifest‬ﻧﺎﻣﻴـﺪه ﻣـﻲ ﺷـﻮد‪.‬‬ ‫‪ Manifest‬ﻛﻪ در واﻗﻊ ﺑﻪ ﺗﻌﺪادي از ﺟﺪول ﻫﺎي ﻣﻮﺟﻮد در ‪ metadata‬اﻃﻼق ﻣﻲ ﺷﻮد‪ ،‬ﺷﺎﻣﻞ اﻃﻼﻋﺎﺗﻲ در راﺑﻄـﻪ‬ ‫ﺑﺎ ﻓﺎﻳﻞ ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ اﺳﻤﺒﻠﻲ را ﺗﺸﻜﻴﻞ ﻣﻲ دﻫﺪ‪ .‬ﺑﻪ ﻋﻼوه اﻃﻼﻋﺎﺗﻲ راﺟﻊ ﺑﻪ ﺗﻮاﺑﻊ و ﻛﻼس ﻫﺎﻳﻲ از اﻳﻦ اﺳﻤﺒﻠﻲ ﻛﻪ ﻣﻲ ﺗﻮاﻧﺪ‬ ‫ﺑﻪ وﺳﻴﻠﻪ ي دﻳﮕﺮ اﺳﻤﺒﻠﻲ ﻫﺎ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮد )ﻣﺎﻧﻨﺪ ﻛﻼﺳﻬﺎي ‪ ،(public‬و ﻧﻴﺰ ﻣﻨﺎﺑﻊ و ﻳﺎ ﻓﺎﻳﻠﻬﺎي اﻃﻼﻋﺎﺗﻲ ﻛـﻪ ﺑـﺎ‬ ‫اﻳﻦ اﺳﻤﺒﻠﻲ در ارﺗﺒﺎط ﻫﺴﺘﻨﺪ ﻧﻴﺰ در ‪ manifest‬ﻗﺮار داده ﻣﻲ ﺷﻮد‪.‬‬ ‫ﺑﻪ ﺻﻮرت ﭘﻴﺶ ﻓﺮض ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎ ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ‪ ،‬ﻣﺎژول ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه را ﺑﻪ ﻓﺎﻳﻠﻬﺎي اﺳﻤﺒﻠﻲ ﺗﺒﺪﻳﻞ ﻣﻲ ﻛﻨﻨﺪ‪ .‬ﺑﻪ ﻃﻮر ﻣﺜﺎل‪،‬‬ ‫ﻛﺎﻣﭙﺎﻳﻠﺮ ‪ C#‬ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ‪ ،‬ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ‪ manifest‬ﺑﻪ ﻣﺎژول ﻣﺪﻳﺮﻳﺖ ﺷـﺪه و اﻧﺠـﺎم ﻛﺎرﻫـﺎﻳﻲ از اﻳـﻦ ﻗﺒﻴـﻞ ﻳـﻚ‬ ‫اﺳﻤﺒﻠﻲ ﺗﻮﻟﻴﺪ ﻣﻲ ﻛﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎم اﺳﺘﻔﺎده از اﻳﻦ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎ‪ ،‬ﺑﺮاي ﺗﻮﻟﻴﺪ ﻳﻚ اﺳﻤﺒﻠﻲ ﻧﻴـﺎزي ﺑـﻪ اﺳـﺘﻔﺎده از ﺳـﻮﻳﻴﭻ ﺧﺎﺻـﻲ‬ ‫ﻧﻴﺴﺖ‪ .‬اﻣﺎ در ﺷﺮاﻳﻄﻲ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﻢ ﺑﺎ اﺳﺘﻔﺎده از ﭼﻨﺪ ﻣﺎژول ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﻛﻪ ﻫﺮ ﻳﻚ در ﻓﺎﻳﻞ ﻣﺨﺼﻮص ﺑﻪ ﺧﻮد ﻗـﺮار دارﻧـﺪ‪،‬‬ ‫ﻳﻚ اﺳﻤﺒﻠﻲ اﻳﺠﺎد ﻛﻨﻴﻢ ﺑﺎﻳﺪ اﺑﺰارﻫﺎي دﻳﮕﺮي ﻣﺜﻞ ﻟﻴﻨﻜﺮ ﻫﺎ‪ 1‬را ﺑﻪ ﻛﺎر ﺑﺒﺮﻳﻢ‪.‬‬

‫ﺗﺮﻛﻴﺐ ﻣﺎژول ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه در اﺳﻤﺒﻠﻲ ﻫﺎ‬ ‫اﻳﻦ اﻣﺮ ﻛﻪ ﻳﻚ اﺳﻤﺒﻠﻲ از ﭼﻨﺪ ﻓﺎﻳﻞ ﺗﺸﻜﻴﻞ ﺷﺪه و ﻫﺮ ﻛﻼس در ﻳﻚ ﻓﺎﻳﻞ ﻗﺮار داده ﺷﻮد و ﻳﺎ اﻳﻨﻜﻪ ﺗﻤﺎم ﻛﻼﺳﻬﺎي ﻣﻮﺟـﻮد در‬ ‫اﺳﻤﺒﻠﻲ‪ ،‬ﻫﻤﻪ در ﻳﻚ ﻓﺎﻳﻞ ﻗﺮار ﮔﻴﺮﻧﺪ ﻛﺎﻣﻼ ﺑﻪ ﻃﺮاح ﺑﺮﻧﺎﻣﻪ و ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﺑﺴﺘﮕﻲ دارد‪ .‬ﺑﻪ ﻃﻮر ﻣﺜﺎل ﺗﺼﻮر ﻛﻨﻴﺪ ﻛﻪ ﻣﻲ ﺧﻮاﻫﻴﺪ‬ ‫ﺑﺮﻧﺎﻣﻪ ي ﺧﻮد را از ﻃﺮﻳﻖ وب ﺗﻮزﻳﻊ ﻛﻨﻴﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻣﻲ ﺗﻮاﻧﻴﻢ ﻛﻼس ﻫﺎﻳﻲ از اﺳﻤﺒﻠﻲ ﻣﺮﺑﻮط ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ ﻛـﻪ ﻛﻤﺘـﺮ ﻣـﻮرد‬ ‫اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ ﮔﻴﺮد را در ﻳﻚ ﻓﺎﻳﻞ و ﻛﻼﺳﻬﺎي ﻣﻬﻢ و ﭘﺮ ﻛﺎرﺑﺮد را در ﻓﺎﻳـﻞ دﻳﮕـﺮ ﻗـﺮار دﻫـﻴﻢ‪ .‬ﺑـﺪﻳﻦ وﺳـﻴﻠﻪ ﻓﺎﻳـﻞ ﺣـﺎوي‬ ‫ﻗﺴﻤﺘﻬﺎي ﻏﻴﺮ ﺿﺮوري ﻓﻘﻂ زﻣﺎﻧﻲ از اﻳﻨﺘﺮﻧﺖ درﻳﺎﻓﺖ ﻣﻲ ﺷﻮد ﻛﻪ ﺑﻪ آﻧﻬﺎ ﻧﻴﺎز اﺳﺖ‪ .‬اﻳﻦ ﻋﻤﻞ ﻣﻮﺟﺐ اﻓﺰاﻳﺶ ﺳﺮﻋﺖ ﺑﺎرﮔـﺬاري‬ ‫ﺑﺮﻧﺎﻣﻪ از وب ﻣﻲ ﺷﻮد و ﻧﻴﺰ ﻓﻀﺎي ﻛﻤﺘﺮي را در دﻳﺴﻚ اﺷﻐﺎل ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﻳﻜﻲ دﻳﮕﺮ از وﻳﮋﮔﻲ ﻫﺎي ﻳﻚ اﺳﻤﺒﻠﻲ اﻳﻦ اﺳﺖ ﻛﻪ اﻃﻼﻋﺎت ﻛﺎﻓﻲ درﺑﺎره ﻣﻨﺎﺑﻊ و اﺳﻤﺒﻠﻲ ﻫﺎي دﻳﮕﺮي ﻛﻪ از آﻧﻬﺎ اﺳـﺘﻔﺎده ﻣـﻲ‬ ‫ﻛﻨﺪ )ﺑﺮاي ﻣﺜﺎل ﺷﻤﺎره ﻧﺴﺨﻪ آﻧﻬﺎ( را ﻧﻴﺰ در ﺧﻮد ﻧﮕﻬﺪاري ﻣﻲ ﻛﻨﺪ‪ .‬اﻳﻦ اﻣﺮ ﻣﻮﺟﺐ ﻣﻴﺸﻮد ﻛﻪ ‪ CLR‬ﺑﺮاي اﺟـﺮاي اﺳـﻤﺒﻠﻲ ﺑـﻪ‬ ‫ﻣﻮارد اﺿﺎﻓﻲ ﻧﻴﺎز ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ‪ .‬ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ اﺟﺮاي اﻳﻦ اﺳـﻤﺒﻠﻲ ﻫـﺎ ﺑـﻪ اﻳﺠـﺎد ﺗﻐﻴﻴـﺮات در رﺟﻴـﺴﺘﺮي و ﻳـﺎ ‪Active‬‬ ‫‪ Directory‬ﻧﺪارد‪ .‬ﺑﻪ ﻫﻤﻴﻦ دﻟﻴﻞ ﺗﻮزﻳﻊ اﻳﻦ اﺳﻤﺒﻠﻲ ﻫﺎ ﺑﺴﻴﺎر ﺳﺎده ﺗﺮ از ﺗﻮزﻳﻊ ﻛﺎﻣﭙﻮﻧﻨـﺖ ﻫـﺎي ﻣـﺪﻳﺮﻳﺖ ﻧـﺸﺪه اﺳـﺖ‪.‬‬ ‫ﺧﺎﺻﻴﺖ اﺳﺘﻔﺎده از روش ‪ XCOPY‬ﺑﺮاي ﺗﻮزﻳﻊ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻧﻮﺷﺘﻪ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ي ‪ .NET‬ﻧﻴﺰ ﺑـﻪ ﻫﻤـﻴﻦ دﻟﻴـﻞ اﺳـﺖ ﻛـﻪ‬ ‫اﺳﻤﺒﻠﻲ ﻫﺎي ﻣﻮرد اﺳﺘﻔﺎده در ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺗﻮاﻧﻨﺪ ﺑﻪ ﺻﻮرت ﻛﺎﻣﻞ ﺧﻮد و ﻫﻤﭽﻨﻴﻦ ﻓﺎﻳﻠﻬﺎي ﻣﻮرد ﻧﻴﺎزﺷﺎن را ﺗﻮﺻﻴﻒ ﻛﻨﻨﺪ‪.‬‬

‫)‪Assembly Linker (al.exe‬‬

‫‪1‬‬

‫‪٩٢٣‬‬

‫ﺑﺎرﮔﺬاري ‪:Common Language Runtime‬‬ ‫ﻫﺮ اﺳﻤﺒﻠﻲ ﻛﻪ اﻳﺠﺎد ﻣﻲ ﺷﻮد ﻣﻲ ﺗﻮاﻧﺪ ﻳﺎ ﻳﻚ ﻓﺎﻳﻞ اﺟﺮاﻳﻲ ﺑﺎﺷﺪ و ﻳﺎ ﻳﻚ ﻓﺎﻳﻞ ‪ DLL‬ﻛﻪ ﺷـﺎﻣﻞ ﭼﻨـﺪ ﻛـﻼس ﺑـﺮاي اﺳـﺘﻔﺎده‬ ‫ﺗﻮﺳﻂ ﻓﺎﻳﻠﻬﺎي اﺟﺮاﻳﻲ اﺳﺖ‪ .‬در ﻫﺮ ﺻﻮرت ‪ CLR‬ﻣﺴﺌﻮل اﺟﺮاي ﻛﺪ ﻫﺎي داﺧﻞ اﻳﻦ اﺳﻤﺒﻠﻲ اﺳﺖ‪ .‬اﻳﻦ اﻣﺮ ﺑﺪﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ‬ ‫ﺑﺮاي اﺟﺮاي اﻳﻦ ﻓﺎﻳﻠﻬﺎ ﺑﺎﻳﺪ اﺑﺘﺪا ‪ .NET Framework‬در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻣﻘﺼﺪ ﻧﺼﺐ ﺷﻮد‪ .‬اﻟﺒﺘﻪ در ﻧﺴﺨﻪ ﻫﺎي ﺟﺪﻳﺪ وﻳﻨﺪوز‬ ‫ﺑﻪ ﺻﻮرت دروﻧﻲ ‪ .NET Framework‬وﺟﻮد دارد و ﻧﻴﺎزي ﺑﻪ ﻧﺼﺐ آن ﻧﻴﺴﺖ‪.‬‬ ‫ﻫﻨﮕﺎم اﻳﺠﺎد ﻳﻚ اﺳﻤﺒﻠﻲ اﺟﺮاﻳﻲ )‪ ،(EXE‬ﻛﺎﻣﭙﺎﻳﻠﺮ ﻣﻘﺪاري اﻃﻼﻋﺎت ﺧﺎص را ﺑﻪ ﺑﺨﺶ ‪ .text‬در ﻗﺴﻤﺖ ﻫـﺪر اﻳـﻦ ﻓﺎﻳـﻞ‬ ‫اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ‪ .‬اﻳﻦ اﻃﻼﻋﺎت زﻣﺎن اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﻮﺟﺐ اﺟﺮاي ‪ CLR‬ﻣﻲ ﺷﻮﻧﺪ‪ .‬ﺳﭙﺲ ‪ CLR‬ﺑﺎ ﺗﺸﺨﻴﺺ ﻧﻘﻄﻪ ورودي ﺑﺮﻧﺎﻣﻪ‪،‬‬ ‫ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺟﺎزه ﻣﻲ دﻫﺪ ﻛﻪ آﻏﺎز ﺑﻪ ﻛﺎر ﻛﻨﺪ‪.‬‬ ‫ﺑﻪ ﻃﻮر ﻣﺸﺎﺑﻪ اﮔﺮ ﻳﻚ ﻓﺎﻳﻞ اﺟﺮاﻳﻲ ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه‪ ،‬ﺑﺎ اﺳﺘﻔﺎده از ‪ LoadLibrary‬ﺳﻌﻲ در ﺑﺎرﮔـﺬاري و اﺳـﺘﻔﺎده از ﻳـﻚ‬ ‫اﺳﻤﺒﻠﻲ ﻣﺪﻳﺮﻳﺖ ﺷﺪه را داﺷﺘﻪ ﺑﺎﺷﺪ‪ ،‬ﻗﺒﻞ از اﺟﺮاي ﻓﺎﻳﻞ ﺑﺮﻧﺎﻣﻪ‪ CLR ،‬اﺟﺮا ﺷﺪه و ﻛﻨﺘﺮل ﻓﺎﻳﻞ ﻣﺪﻳﺮﻳﺖ ﺷـﺪه را در دﺳـﺖ ﻣـﻲ‬ ‫ﮔﻴﺮد‪.‬‬

‫ﺑﺎرﮔﺬاري و ﻣﻘﺪار دﻫﻲ اوﻟﻴﻪ ﺑﻪ ‪CLR‬‬ ‫ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻳﻚ ﻓﺎﻳﻞ اﺟﺮاﻳﻲ را اﻳﺠﺎد ﻣﻴﻜﻨﺪ‪ ،‬ﻋﺒﺎرت زﻳﺮ را ﺑﻪ ﺑﺨﺶ ‪ .text‬در ﻫﺪر ﻣﺮﺑﻮط ﺑﻪ ﻓﺎﻳﻞ اﺿﺎﻓﻪ ﻣﻴﻜﻨﺪ‪:‬‬ ‫‪JMP _CorExeMain‬‬ ‫اﻳﻦ دﺳﺘﻮر‪ ،‬ﻳﻚ دﺳﺘﻮر ﺑﻪ زﺑﺎن اﺳﻤﺒﻠﻲ اﺳﺖ ﻛﻪ زﻳﺮ ﺑﺮﻧﺎﻣﻪ اي ﺑﻪ ﻧﺎم ‪ _CorExeMain‬را ﻓﺮاﺧﻮاﻧﻲ ﻣـﻲ ﻛﻨـﺪ‪ .‬ﺑـﻪ دﻟﻴـﻞ‬ ‫اﻳﻨﻜﻪ زﻳﺮ ﺑﺮﻧﺎﻣﻪ ي ‪ _CorExeMain‬در ﻓﺎﻳﻞ ‪ 1MSCorEE.dll‬ﻗﺮار دارد‪ ،‬ﭘﺲ اﺳﻢ ‪ MSCorEE.dll‬ﻧﻴﺰ‬ ‫ﺑﻪ ﻋﻨﻮان ﻳﻜﻲ از ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼﺳﻲ ﻛﻪ ﺗﻮﺳﻂ ﻓﺎﻳﻞ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ در ﺑﺨﺶ ‪ .idata‬اﺿﺎﻓﻪ ﻣـﻲ ﺷـﻮد‪.‬‬ ‫زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﻓﺎﻳﻞ اﺟﺮاﻳﻲ ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد‪ ،‬وﻳﻨﺪوز ﺑﺎ آن ﺑﻪ ﺻﻮرت ﻳﻚ ﻓﺎﻳﻞ ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه و ﻣﻌﻤﻮﻟﻲ ﺑﺮﺧـﻮرد‬ ‫ﻣــﻲ ﻛﻨــﺪ‪ .‬ﺑﺮﻧﺎﻣــﻪ ي ﻣﺨــﺼﻮص ﺑﺎرﮔــﺬاري در وﻳﻨــﺪوز‪ ،‬ﺑــﺎ ﺑﺮرﺳــﻲ ﻗــﺴﻤﺖ ‪ .idata‬ﺷــﺮوع ﺑــﻪ ﺑﺎرﮔــﺬاري ﻓﺎﻳــﻞ‬ ‫‪ MSCorEE.dll‬در ﺣﺎﻓﻈﻪ ﻣﻲ ﻛﻨـﺪ و آن را در ﺣﺎﻓﻈـﻪ ﻗـﺮار ﻣـﻲ دﻫـﺪ‪ .‬ﺳـﭙﺲ ﺑﺮﻧﺎﻣـﻪ ﺑـﺎ ﺑﺪﺳـﺖ آوردن آدرس ﺗـﺎﺑﻊ‬ ‫‪ _CorExeMain‬اﻳﻦ ﻣﺘﺪ را اﺟﺮا ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫‪Microsoft Component Object Runtime Execution Engine‬‬

‫‪1‬‬

‫‪٩٢٤‬‬

‫ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﭘﺮوﺳﻪ اﺻﻠﻲ ﻛﻪ ﻣﺮﺑﻮط ﺑﻪ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ اﺳﺖ ﺑﻪ اﺟﺮاي ﺗﺎﺑﻊ ‪ _CorExeMain‬ﻣﻲ ﭘﺮدازد‪ .‬اﺟﺮاي اﻳﻦ ﺗـﺎﺑﻊ‬ ‫ﻣﻨﺠﺮ ﺑﻪ اﺟﺮا ﺷﺪن ‪ CLR‬و ﺑﺎرﮔﺬاري آن در ﺣﺎﻓﻈﻪ ﺧﻮاﻫﺪ ﺷﺪ‪ .‬ﺑﺎ اﺟﺮا ﺷﺪن ‪ ،CLR‬ﻛﻨﺘﺮل ﺑﺮﻧﺎﻣﻪ در اﺧﺘﻴﺎر آن ﻗﺮار ﻣـﻲ ﮔﻴـﺮد‪.‬‬ ‫‪ CLR‬ﻧﻴﺰ اﺑﺘﺪا ﺑﺎ ﺑﺮرﺳﻲ ﺑﺨﺶ ﻫﺪر ‪ CLR‬ﻣﺮﺑﻮط ﺑﻪ ﻓﺎﻳﻞ‪ ،‬ﻧﻘﻄﻪ آﻏﺎزﻳﻦ ﺑﺮﻧﺎﻣﻪ را ﻣﺸﺨﺺ ﻣـﻲ ﻛﻨـﺪ‪ .‬ﺳـﭙﺲ ‪ CLR‬ﻛـﺪ ‪IL‬‬ ‫ﻣﺮﺑﻮط ﺑﻪ ﺗﺎﺑﻊ ﻓﺮاﺧﻮاﻧﻲ ﺷﺪه را ﺑﻪ وﺳﻴﻠﻪ ي ‪ JIT‬ﺑﻪ ﻛﺪ زﺑﺎن ﻣﺎﺷﻴﻦ ﺗﺒﺪﻳﻞ ﻛﺮده و آن را اﺟـﺮا ﻣﻴﻜﻨـﺪ )اﻳـﻦ ﻋﻤـﻞ در ﭘﺮوﺳـﻪ‬ ‫اﺻﻠﻲ ﺑﺮﻧﺎﻣﻪ ﺻﻮرت ﻣﻲ ﮔﻴﺮد(‪ .‬در اﻳﻦ ﻣﺮﺣﻠﻪ اﺟﺮاي ﻛﺪ ﻣﺪﻳﺮﻳﺖ ﺷﺪه آﻏﺎز ﻣﻲ ﺷﻮد‪.‬‬ ‫ﻫﻤﻴﻦ ﺷﺮاﻳﻂ ﺑﺮاي اﻳﺠﺎد ‪DLL‬ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﻧﻴﺰ ﺻﺎدق اﺳﺖ‪ .‬اﮔﺮ اﻳـﻦ ‪ DLL‬ﺑـﻪ وﺳـﻴﻠﻪ ي ﻳـﻚ ﻓﺎﻳـﻞ اﺟﺮاﻳـﻲ ﻛـﻪ ﺑـﺎ‬ ‫‪ .NET‬اﻳﺠﺎد ﺷﺪه اﺳﺖ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﺑﮕﻴﺮد‪ ،‬ﭘﺲ ﺣﺘﻤﺎً ﺗﺎﻛﻨﻮن ‪ CLR‬اﺟﺮا ﺷﺪه اﺳﺖ و ﻣﻲ ﺗﻮاﻧﺪ ﻛﻨﺘﺮل اﻳﻦ ‪ DLL‬را ﻧﻴﺰ‬ ‫در دﺳﺖ ﺑﮕﻴﺮد‪ .‬اﻣﺎ ﺗﺼﻮر ﻣﻲ ﻛﻨﻴﻢ ﻛﻪ اﻳﻦ ‪ DLL‬ﻣـﻲ ﺧﻮاﻫـﺪ ﺑـﻪ وﺳـﻴﻠﻪ ي ﻳـﻚ ﻓﺎﻳـﻞ اﺟﺮاﻳـﻲ ﻋـﺎدي‪ ،‬ﺑـﺎ اﺳـﺘﻔﺎده از ﺗـﺎﺑﻊ‬ ‫‪ LoadLibrary‬اﺳﺘﻔﺎده ﺷﻮد‪ .‬در اﻳﻦ ﺷﺮاﻳﻂ ﻗﺒﻞ از اﻳﻨﻜﻪ ‪ DLL‬اﺟﺮا ﺷﻮد‪ ،‬ﺑﺎﻳﺪ ‪ CLR‬در ﺣﺎﻓﻈﻪ ﻗﺮار ﮔﻴﺮد ﺗﺎ ﺑﺘﻮاﻧﺪ ﻛﺪ‬ ‫ﻫﺎي ﻣﻮﺟﻮد در ‪ DLL‬را ﻛﻨﺘﺮل ﻛﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻦ ﺷﺮاﻳﻂ ﻧﻴﺰ اﺗﻔﺎﻗﺎﺗﻲ ﻫﻤﺎﻧﻨﺪ اﺟﺮا ﺷﺪن ﻳـﻚ ﻓﺎﻳـﻞ ‪ EXE‬ﻛـﻪ ﺑـﺎ ‪.NET‬‬ ‫اﻳﺠﺎد ﺷﺪه اﺳﺖ رخ ﻣﻲ دﻫﺪ‪ .‬ﻳﻌﻨﻲ ﻫﻨﮕﺎم ﺳﺎﺧﺘﻦ ‪DLL‬ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه‪ ،‬ﻛﺎﻣﭙﺎﻳﻠﺮ دﺳﺘﻮر زﻳﺮ را ﺑـﻪ ﺑﺨـﺶ ‪ .text‬ﻫـﺪر‬ ‫ﻣﺮﺑﻮط ﺑﻪ اﺳﻤﺒﻠﻲ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ‪:‬‬ ‫‪JMP _CorDllMain‬‬ ‫زﻳﺮ ﺑﺮﻧﺎﻣﻪ ي ‪ _CorDllMain‬ﻧﻴﺰ در ﻓﺎﻳﻞ ‪ MSCorEE.dll‬ﻗﺮار داده ﺷﺪه اﺳﺖ و اﻳﻦ اﻣﺮ ﻣﻮﺟﺐ ﻣﻲ ﺷـﻮد ﻛـﻪ‬ ‫ﻧﺎم اﻳﻦ ﻓﺎﻳﻞ ﺑﻪ ﺑﺨﺶ ‪ .idata‬اﺿﺎﻓﻪ ﺷﻮد‪ .‬ﻫﻨﮕﺎﻣﻲ ﻛﻪ وﻳﻨﺪوز ﻓﺎﻳﻞ ﻣﺮﺑﻮط ﺑﻪ ‪ DLL‬را ﺑﺎرﮔـﺬاري ﻣـﻲ ﻛﻨـﺪ‪ ،‬اﺑﺘـﺪا ﻓﺎﻳـﻞ‬ ‫‪ MSCorEE.dll‬را در ﺣﺎﻓﻈﻪ ﻗﺮار ﻣﻲ دﻫﺪ )اﻟﺒﺘﻪ اﮔﺮ ﺗﺎﻛﻨﻮن ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ ي دﻳﮕﺮي ﺑﺎرﮔـﺬاري ﻧـﺸﺪه ﺑﺎﺷـﺪ( و ﺳـﭙﺲ‬ ‫آدرس ﺗﺎﺑﻊ ﻣﺬﻛﻮر را در ﺣﺎﻓﻈﻪ ﺑﺪﺳﺖ ﻣﻲ آورد‪ .‬ﭘﺮوﺳﻪ اي ﻛﻪ ﺗﺎﺑﻊ ‪ LoadLibrary‬را در اﺑﺘﺪا ﻓﺮاﺧﻮاﻧﻲ ﻛﺮده ﺑﻮد ﺗﺎ ﻛـﺪ‬ ‫ﻫﺎي درون ‪ DLL‬را اﺟﺮا ﻛﻨﺪ‪ ،‬ﺗﺎﺑﻊ ‪ _CorDllMain‬را از ﻓﺎﻳﻞ ‪ MSCorEE.dll‬اﺟﺮا ﻣﻲ ﻛﻨﺪ‪ .‬اﺟﺮاي اﻳـﻦ ﺗـﺎﺑﻊ‬ ‫ﻧﻴﺰ ﻣﻮﺟﺐ راه اﻧﺪازي ‪ CLR‬ﺷﺪه و ﺑﺪﻳﻦ ﺗﺮﺗﻴﺐ ﻛﺪ ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﻣﻴﺘﻮاﻧﺪ ﺑﻪ ﺻﻮرت ﻋﺎدي اﺟﺮا ﺷﻮد‪..‬‬ ‫ﻣﻮاردي ﻛﻪ ﺑﺮاي اﺟﺮاي ﻓﺎﻳﻠﻬﺎي ﻣﺤﺘﻮي ﻛﺪ ﻣﺪﻳﺮﻳﺖ ﺷﺪه ذﻛﺮ ﺷـﺪ ﻓﻘـﻂ در وﻳﻨـﺪوز ﻫـﺎي ‪ NT 4 ،ME ،98 SE ،98‬و‬ ‫‪ 2000‬ﻻزم اﺳﺖ زﻳﺮا اﻳﻦ ﺳﻴﺴﺘﻢ ﻋﺎﻣﻠﻬﺎ ﻗﺒﻞ از ﻋﺮﺿﻪ ‪ CLR‬ﺑﻪ وﺟﻮد آﻣﺪه اﻧﺪ‪ .‬وﻳﻨﺪوز ‪ XP‬و وﻳﻨﺪوز ﺳﺮور ‪ 2003‬ﺑﻪ ﺻﻮرت‬ ‫دروﻧﻲ اﺟﺮاي ﻓﺎﻳﻠﻬﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه را ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ ﻛﻨﻨﺪ و ﻧﻴﺎزي ﺑﻪ ﻣﻮارد ذﻛﺮ ﺷﺪه ﻧﻴﺴﺖ‪ .‬ﻧﻜﺘﻪ دﻳﮕﺮ اﻳﻦ اﺳﺖ ﻛﻪ اﻳـﻦ ﺗﻮاﺑـﻊ‬ ‫ﻣﺨﺼﻮص دﺳﺘﮕﺎﻫﻬﺎي ‪ x86‬ﻫﺴﺘﻨﺪ و در ﻣﺪل ﻫﺎ و ﺳﺎﺧﺘﺎرﻫﺎي دﻳﮕﺮ ﭘﺮدازﻧﺪه درﺳﺖ ﻋﻤﻞ ﻧﻤﻲ ﻛﻨﻨﺪ‪.‬‬

‫اﺟﺮاي ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه‪:‬‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ ذﻛﺮ ﺷﺪ ﻓﺎﻳﻠﻬﺎي اﺳﻤﺒﻠﻲ ﻣﺤﺘﻮي ‪ metadata‬و ﻛﺪ ﻫﺎي ‪ IL‬ﻫﺴﺘﻨﺪ‪ IL .‬ﻳﻚ زﺑﺎن ﺳﻄﺢ ﻣﻴﺎﻧﻲ اﺳـﺖ ﻛـﻪ‬ ‫ﺗﻮﺳﻂ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ اﻳﺠﺎد ﺷﺪه اﺳﺖ‪ .‬اﻳﻦ زﺑﺎن ﻧﺴﺒﺖ ﺑﻪ زﺑﺎن ﻣﺎﺷﻴﻦ ﺑﺴﻴﺎر ﺳﻄﺢ ﺑﺎﻻﺗﺮ اﺳﺖ‪ .‬ﺗـﺸﺨﻴﺺ اﺷـﻴﺎي اﻳﺠـﺎد ﺷـﺪه از‬ ‫ﻛﻼﺳﻬﺎ و دﺳﺘﻮراﺗﻲ ﺑﺮاي اﻳﺠﺎد و ﻣﻘﺪار دﻫﻲ اوﻟﻴﻪ آﻧﻬﺎ‪ ،‬ﺗﻮاﻧﺎﻳﻲ ﻓﺮاﺧﻮاﻧﻲ ﺗﻮاﺑﻊ داﺧﻞ اﺷﻴﺎ‪ ،‬ﻗﺎﺑﻠﻴﺖ ﺧﻄﺎ ﻳﺎﺑﻲ در داﺧﻞ ﺑﺮﻧﺎﻣﻪ ﻫﺎ و‬ ‫ﻧﮕﻬﺪاري ﻋﻨﺎﺻﺮ در ﻳﻚ آراﻳﻪ ﺑﻪ ﺻﻮرت ﻣﺴﺘﻘﻴﻢ از ﺗﻮاﻧﺎﻳﻲ ﻫﺎي اﻳﻦ زﺑﺎن ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد‪ .‬در ﺣﻘﻴﻘﺖ اﻳﻦ زﺑـﺎن ﻳـﻚ ﻧـﺴﺨﻪ‬ ‫ﺷﻴﺊ ﮔﺮا از زﺑﺎن ﻣﺎﺷﻴﻦ ﺑﻪ ﺷﻤﺎر ﻣﻲ رود‪.‬‬ ‫ﻣﻌﻤﻮﻻ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﺑﺮاي ﻃﺮاﺣﻲ ﺑﺮﻧﺎﻣﻪ از زﻳﺎﻧﻬﺎي ﺳﻄﺢ ﺑﺎﻻ ﻣﺎﻧﻨﺪ ‪ C#‬و ﻳﺎ ‪ Visual Basic‬اﺳـﺘﻔﺎده ﻣـﻲ ﻛﻨﻨـﺪ‪.‬‬ ‫ﺳﭙﺲ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻛﺪ اﻳﻦ زﺑﺎﻧﻬﺎ را ﺑﻪ ‪ IL‬ﺗﺒﺪﻳﻞ ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﺑﻌﻀﻲ از ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن ﻋﻘﻴﺪه دارﻧﺪ ﻛﻪ زﺑﺎن ‪ IL‬ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﻪ ﻃﻮر ﻛﺎﻣﻞ از اﻟﮕﻮرﻳﺘﻢ ﻫﺎﻳﻲ ﻛﻪ آﻧﻬﺎ اﺳﺘﻔﺎده ﻛﺮده اﻧـﺪ ﻣﺤﺎﻓﻈـﺖ‬ ‫ﻛﻨﺪ‪ .‬ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ‪ ،‬ﺑﻪ ﻧﻈﺮ آﻧﻬﺎ ﻣﻲ ﺗﻮان ﻳﻚ ﻓﺎﻳﻞ ﺣﺎوي ﻛﺪ ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﺗﻮﻟﻴﺪ ﻛﺮده و ﺳﭙﺲ ﺑﺎ اﺳﺘﻔﺎده از ﺑﺮﻧﺎﻣـﻪ ﻫـﺎﻳﻲ ﻛـﻪ‬ ‫ﻣﻲ ﺗﻮاﻧﻨﺪ ﻛﺪ ‪ IL‬را ﻧﻤﺎﻳﺶ دﻫﻨﺪ )ﻣﺎﻧﻨﺪ ‪ (1ildasm‬و ﻣﺸﺎﻫﺪه ﻛﺪ ‪ IL‬ﻳﻚ ﺑﺮﻧﺎﻣﻪ‪ ،‬ﺑﻪ اﻟﮕﻮرﻳﺘﻢ اﺻﻠﻲ آن دﺳﺖ ﭘﻴﺪا ﻛﻨﻨﺪ‪.‬‬ ‫‪IL Disassembler‬‬

‫‪1‬‬

‫‪٩٢٥‬‬

‫اﻳﻦ اﻣﺮ ﻛﺎﻣﻼً درﺳﺖ اﺳﺖ و ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ ﻛﺪ ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮﻧﺪ از اﻣﻨﻴﺖ ﻛﺪ ﭘﺎﻳﻴﻦ ﺗﺮي ﻧﺴﺒﺖ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫـﺎي‬ ‫ﻣﺤﺘﻮي ﻛﺪ زﺑﺎن ﻣﺎﺷﻴﻦ دارﻧﺪ‪ .‬اﻟﺒﺘﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب و ﻳﺎ وب ﺳﺮوﻳﺲ ﻫﺎ و ﺑﻪ ﻃﻮر ﻛﻠﻲ ﺑﺮﻧﺎﻣﻪ ﻫـﺎﻳﻲ ﻛـﻪ در ﻳـﻚ ﺳـﺮور‬ ‫ﻣﺮﻛﺰي اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ ﻛﻤﺘﺮ از اﻳﻦ ﻟﺤﺎظ در ﺧﻄﺮ ﻫﺴﺘﻨﺪ‪ ،‬زﻳﺮا ﻓﻘﻂ ﺗﻌﺪاد ﻣﺤﺪودي از اﻓـﺮاد ﺑـﻪ ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي ﻣﻮﺟـﻮد در ﺳـﺮور‬ ‫دﺳﺘﺮﺳﻲ دارﻧﺪ و ﺑﻨﺎﺑﺮاﻳﻦ ﻛﺪﻫﺎ ﻛﺎﻣﻼً اﻳﻤﻦ ﺧﻮاﻫﻨﺪ ﻣﺎﻧﺪ‪.‬‬ ‫اﻣﺎ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﻛﻪ ﺑﺎﻳﺴﺘﻲ ﺑﻪ ﺻﻮرت ﻋﻤﻮﻣﻲ ﺗﻮزﻳﻊ ﺷﻮﻧﺪ‪ ،‬ﻣﻴﺘﻮان از ﻧﺮم اﻓﺰارﻫﺎي ﺷﺮﻛﺘﻬﺎي دﻳﮕـﺮ ﻛـﻪ ﻛـﺪ ﻫـﺎي ‪ IL‬را‬ ‫ﮔﻨﮓ و ﻧﺎﻣﻔﻬﻮم ﻣﻴﻜﻨﻨﺪ اﺳﺘﻔﺎده ﻛﺮد‪ .‬اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺗﻤﺎﻣﻲ ﻧﺎﻣﻬﺎي ﺑﻪ ﻛﺎر رﻓﺘﻪ در ﻛﺪ )ﻣﺎﻧﻨﺪ ﻧﺎم ﺗﻮاﺑﻊ‪ ،‬ﻣﺘﻐﻴﻴﺮ ﻫﺎ و ‪ (...‬را ﺗﻐﻴﻴﺮ ﻣﻲ‬ ‫دﻫﻨﺪ و آﻧﻬﺎ را ﺑﺎ ﻧﺎﻣﻬﺎي ﺑﺪون ﻣﻌﻨﻲ ﺟﺎﻳﮕﺰﻳﻦ ﻣﻲ ﻛﻨﻨﺪ‪ .‬ﺑﻪ اﻳﻦ ﺗﺮﺗﻴﺐ ﻫﺪف و وﻇﻴﻔﻪ ﻫﺮ ﺗـﺎﺑﻊ از روي ﻧـﺎم آن ﻗﺎﺑـﻞ ﺗـﺸﺨﻴﺺ‬ ‫ﻧﺨﻮاﻫﺪ ﺑﻮد و ﻓﺮد ﻧﻤﻲ ﺗﻮاﻧﺪ ﺑﺎ ﻣﺸﺎﻫﺪه ي ﻛﺪ ‪ IL‬ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺳﺎدﮔﻲ از اﻟﮕﻮرﻳﺘﻢ آن ﻣﻄﻠﻊ ﺷﻮد‪ .‬ﺷﺎﻳﺎن ذﻛﺮ اﺳﺖ ﻛﻪ ﻗـﺪرت‬ ‫اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ در ﻧﺎﻣﻔﻬﻮم ﻛﺮدن ﻛﺪ ‪ IL‬ﺗﻮﻟﻴﺪ ﺷﺪه ﻣﺤﺪود اﺳﺖ‪ ،‬زﻳﺮا اﮔﺮ ﻛﺪ ﺑﻴﺶ از ﺣﺪ ﺗﻐﻴﻴﺮ ﻛﻨﺪ ‪ CLR‬ﺗﻮاﻧﺎﻳﻲ ﭘﺮدازش آن را‬ ‫ﻧﺨﻮاﻫﺪ داﺷﺖ‪.‬‬ ‫اﮔﺮ اﻫﻤﻴﺖ ﻛﺪ ﺑﻪ ﺣﺪي ﺑﺎﻻ اﺳﺖ ﻛﻪ ﻧﺘﻮان ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻧﺎﻣﻔﻬﻮم ﻛﻨﻨﺪه اﻃﻤﻴﻨﺎن ﻛﺮد‪ ،‬ﻣﻴﺘﻮان ﻛﺪ ﻫﺎي ﻣﻬـﻢ ﺑﺮﻧﺎﻣـﻪ را در ﻳـﻚ‬ ‫ﻛﻼس ﻣﺠﺰا ﻗﺮار داد و آن را ﺑﻪ ﺻﻮرت ﻛﺪ زﺑﺎن ﻣﺎﺷﻴﻦ ﻛﺎﻣﭙﺎﻳﻞ ﻛﺮد‪ .‬ﺳﭙﺲ از وﻳﮋﮔﻲ ‪ CLR‬ﺑﺮاي ارﺗﺒﺎط ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه‬ ‫و ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻣﺎﺑﻘﻲ ﻛﺪ اﺳﺘﻔﺎده ﻛﺮد‪.‬‬ ‫ﺑﺎﻳﺪ در ﻧﻈﺮ داﺷﺖ ﻛﻪ ﻓﻘﻂ زﺑﺎن ‪ IL‬ﺗﻤﺎم اﻣﻜﺎﻧﺎت ﻣﻮﺟﻮد در ‪ CLR‬را اراﺋﻪ ﻣﻲ دﻫﺪ‪ .‬ﺗﻤﺎم زﺑﺎﻧﻬـﺎي دﻳﮕـﺮ ﻗـﺴﻤﺘﻲ از اﻣﻜﺎﻧـﺎت‬ ‫اراﺋﻪ ﺷﺪه ﺗﻮﺳﻂ ‪ CLR‬را ﺷﺎﻣﻞ ﻣﻲ ﺷﻮﻧﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎم اﻧﺘﺨﺎب زﺑﺎن ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺎﻳﺴﺘﻲ اﻳﻦ ﻧﻜﺘﻪ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﻮد و اﮔﺮ‬ ‫ﻧﻴﺎز ﺑﻪ اﻣﻜﺎﻧﺎﺗﻲ از ‪ CLR‬ﺑﻪ وﺟﻮد آﻣﺪ ﻛﻪ در زﺑﺎن ﻣﻮرد اﺳﺘﻔﺎده وﺟﻮد ﻧﺪاﺷﺖ ﻣﻲ ﺗﻮان آن ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ را ﺑﻪ ﺻﻮرت ﻛﺪ ‪IL‬‬ ‫ﻧﻮﺷﺖ و ﻳﺎ از زﺑﺎﻧﻬﺎي دﻳﮕﺮ ﻛﻪ آن وﻳﮋﮔﻲ را اراﺋﻪ ﻣﻲ دﻫﻨﺪ اﺳﺘﻔﺎده ﻛﺮد‪.‬‬ ‫ﻧﻜﺘﻪ ﻣﻬﻢ دﻳﮕﺮ اﻳﻦ اﺳﺖ ﻛﻪ زﺑﺎن ‪ IL‬ﺑﻪ ﻫﻴﭻ ﭘﺮدازﻧﺪه اي واﺑﺴﺘﻪ ﻧﻴﺴﺖ‪ .‬اﻳﻦ اﻣﺮ ﺑﺪﻳﻦ ﻣﻌﻨﺎ اﺳﺖ ﻛﻪ ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه در‬ ‫ﻫﺮ ﭘﻠﺖ ﻓﺮﻣﻲ ﻛﻪ ‪ CLR‬ﺑﺮاي آن اراﺋﻪ ﺷﺪه ﺑﺎﺷﺪ اﺟﺮا ﻣﻲ ﺷﻮد‪ .‬اﻟﺒﺘﻪ ﻧﺴﺨﻪ اوﻟﻴﻪ ي ‪ CLR‬ﺑﺮاي وﻳﻨﺪوز ﻫـﺎي ‪32‬ﺑﻴﺘـﻲ ﻋﺮﺿـﻪ‬ ‫ﺷﺪه اﺳﺖ‪ ،‬اﻣﺎ در ﻫﺮ ﺻﻮرت اﻳﻦ ﻣﻮﺿﻮع ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎن را از ﺗﻮﺟﻪ ﺑﻪ ﭘﺮدازﻧﺪه اي ﻛﻪ ﺗﻮﺳﻂ ﻛﺎرﺑﺮ ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﺮﻓﺘﻪ اﺳـﺖ‬ ‫آزاد ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﺑﺮاي اﺟﺮاي ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﻛﻪ ﺑﻪ زﺑﺎن ‪ IL‬در ﻓﺎﻳﻞ ذﺧﻴﺮه ﺷﺪه اﻧﺪ اﺑﺘﺪا ﺑﺎﻳﺪ آﻧﻬﺎ را ﺑﻪ ﻛﺪ ﻫﺎي زﺑﺎن ﻣﺎﺷﻴﻦ ﺗﺒﺪﻳﻞ ﻛﺮد‪.‬‬ ‫اﻳﻦ اﻣﺮ وﻇﻴﻔﻪ ي ﺑﺨﺸﻲ از ‪ CLR‬ﺑﻪ ﻧﺎم ‪ 1JIT‬اﺳﺖ‪ .‬ﺷﻜﻞ زﻳﺮ ﻣﺮاﺣﻠﻲ ﻛﻪ ﻫﻨﮕﺎم اﺟﺮاي ﻳﻚ ﺗﺎﺑﻊ ﺑـﺮاي اوﻟـﻴﻦ ﺑـﺎر رخ ﻣـﻲ‬ ‫دﻫﺪ را ﻧﺸﺎن ﻣﻲ دﻫﺪ‪.‬‬ ‫درﺳﺖ ﻗﺒﻞ از اﻳﻨﻜﻪ ﺗﺎﺑﻊ ‪ Main‬اﺟﺮا ﺷﻮد‪ CLR ،‬ﻧﻮع ﺗﻤﺎم اﺷﻴﺎﻳﻲ ﻛﻪ ﺗﻮﺳﻂ اﻳﻦ ﺗﺎﺑﻊ اﺳﺘﻔﺎده ﺷﺪه اﻧﺪ را ﺗﺸﺨﻴﺺ ﻣـﻲ دﻫـﺪ‪.‬‬ ‫اﻳﻦ اﻣﺮ ﺑﺎﻋﺚ ﻣﻴﺸﻮد ﻛﻪ ‪ CLR‬ﻳﻚ ﺟﺪول داده اي داﺧﻠﻲ ﺑﺮاي ﻣﺪﻳﺮﻳﺖ دﺳﺘﺮﺳﻲ ﺑﻪ ﻧﻮع ﻫﺎي ارﺟﺎﻋﻲ ﺗﺸﻜﻴﻞ دﻫﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل‬ ‫در ﺷﻜﻞ ﺑﺎﻻ ﺗﺎﺑﻊ ‪ Main‬از ﻛﻼس ارﺟﺎﻋﻲ ‪ Console‬اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ ﻛﻪ اﻳـﻦ ﻣـﻮرد ﺗﻮﺳـﻂ ‪ CLR‬در ﺟـﺪول داده اي‬ ‫ﻗﺮار ﻣﻲ ﮔﻴﺮد‪ .‬ﺳﺎﺧﺘﺎر ﻣﺬﻛﻮر ﺑﺎزاي ﻫﺮ ﺗﺎﺑﻊ ﻛﻪ در ﻛﻼس اﺳﺘﻔﺎده ﺷﺪه‪ ،‬ﻳﻚ ردﻳﻒ اﻃﻼﻋﺎت را در ﺟـﺪول اﻳﺠـﺎد ﻣـﻲ ﻛﻨـﺪ‪ .‬ﻫـﺮ‬ ‫ردﻳﻒ ﺷﺎﻣﻞ آدرس ﻣﻜﺎﻧﻲ از ﺣﺎﻓﻈﻪ اﺳﺖ ﻛﻪ ﭘﻴﺎده ﺳﺎزي ﺗﺎﺑﻊ در آن ﻗﺮار دارد‪ .‬ﻫﻨﮕﺎم ﻣﻘﺪار دﻫـﻲ اوﻟﻴـﻪ ي اﻳـﻦ ﺳـﺎﺧﺘﺎر‪ ،‬ﺗﻤـﺎم‬ ‫ردﻳﻔﻬﺎي آن ﺑﻪ ﻳﻜﻲ از ﺗﻮاﺑﻊ دروﻧﻲ ‪ CLR‬ﺑﻪ ﻧﺎم ‪ JITCompiler‬اﺷﺎره ﻣﻲ ﻛﻨﻨﺪ‪.‬‬ ‫زﻣﺎﻧﻲ ﻛﻪ ﺗﺎﺑﻊ ‪ Main‬ﺑﺮاي اوﻟﻴﻦ ﻣﺮﺗﺒﻪ ﺗﺎﺑﻊ ‪ WriteLine‬را ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﻛﻨﺪ‪ CLR ،‬ﺑـﻪ ﺟـﺪول داده اي ﻛـﻪ اﻳﺠـﺎد‬ ‫ﺷﺪه ﺑﻮد ﻧﮕﺎه ﻣﻲ ﻛﻨﺪ ﺗﺎ ﺗﺸﺨﻴﺺ دﻫﺪ ﺗﺎﺑﻌﻲ ﻛﻪ ﺑﺎﻳﺪ اﺣﻀﺎر ﻛﻨﺪ در ﻛﺪام ﻗﺴﻤﺖ از ﺣﺎﻓﻈـﻪ ﻗـﺮار دارد‪ .‬اﻣـﺎ ﻫﻤـﺎﻧﻄﻮر ﻛـﻪ ﮔﻔـﺘﻢ‬ ‫ﻫﻨﮕﺎم اﻳﺠـﺎد ﺟـﺪول‪ ،‬ﻣﻘـﺪار اوﻟﻴـﻪ ي ﻫـﺮ ﺗـﺎﺑﻊ ﺑـﻪ ﺟـﺎي اﻳﻨﻜـﻪ ﺑـﻪ آدرس ﺧـﻮد ﺗـﺎﺑﻊ اﺷـﺎره ﻛﻨـﺪ ﺑـﻪ آدرس ﺗـﺎﺑﻌﻲ ﺑـﻪ ﻧـﺎم‬ ‫‪ JITCompiler‬اﺷﺎره ﻣﻲ ﻛﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺟﺎي ﺗﺎﺑﻊ ‪ ،WriteLine‬ﺗﺎﺑﻊ ‪JITCompiler‬‬ ‫ﺑﻪ وﺳﻴﻠﻪ ي ‪ CLR‬اﺣﻀﺎر ﻣﻲ ﺷﻮد‪ .‬اﻳﻦ ﺗﺎﺑﻊ وﻇﻴﻔﻪ ﺗﺒﺪﻳﻞ ﻛﺪ ‪ IL‬ﺑﻪ ﻛﺪ زﺑﺎن ﻣﺎﺷﻴﻦ را ﺑﺮ ﻋﻬﺪه دارد‪ .‬ﺑﻪ دﻟﻴﻞ اﻳﻦ ﻛﻪ ﻛﺪ ﻫﺎي‬ ‫‪ IL‬ﻓﻘﻂ زﻣﺎﻧﻲ ﻛﻪ ﺑﻪ آﻧﻬﺎ ﻧﻴﺎز اﺳﺖ ﺑﻪ ﻛﺪ زﺑﺎن ﻣﺎﺷﻴﻦ ﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮﻧﺪ‪ ،‬از اﻳﻦ ﻗﺴﻤﺖ از ‪ CLR‬ﻋﻤﻮﻣﺎً ﺑﻪ ﻋﻨﻮان ‪JITter‬‬ ‫و ﻳﺎ ‪ JIT Compiler‬ﻳﺎد ﻣﻲ ﺷﻮد‪.‬‬ ‫‪Just-In-Time Compiler‬‬

‫‪1‬‬

‫‪٩٢٦‬‬

‫ﻓﺮاﺧﻮاﻧﻲ ﺗﺎﺑﻊ ﺑﺮاي اوﻟﻴﻦ ﺑﺎر‬ ‫ﻫﻨﮕﺎم اﺣﻀﺎر ﺗﺎﺑﻊ ‪ ،JITCompiler‬اﻳﻦ ﺗﺎﺑﻊ ﻣﻲ داﻧﺪ ﻛﻪ ﭼﻪ ﺗﺎﺑﻌﻲ در اﺻﻞ ﻓﺮاﺧـﻮاﻧﻲ ﺷـﺪه اﺳـﺖ و اﻳـﻦ ﺗـﺎﺑﻊ در ﭼـﻪ‬ ‫ﻛﻼﺳﻲ ﻗﺮار دارد‪ .‬ﭘﺲ ‪ JITCompiler‬ﻛﺪ ‪ IL‬ﻣﺮﺑﻮط ﺑﻪ ﺗﺎﺑﻊ ﻓﺮاﺧﻮاﻧﻲ ﺷﺪه را ﺑﺪﺳﺖ آورده و آن را ﺑﻪ ﻛﺪ زﺑﺎن ﻣﺎﺷﻴﻦ‬ ‫ﺗﺒﺪﻳﻞ ﻣﻲ ﻛﻨﺪ‪ .‬ﻛﺪ ﺗﻮﻟﻴﺪ ﺷﺪه در اﻳﻦ ﻣﺮﺣﻠﻪ در ﻳﻚ ﺑﻼك از ﺣﺎﻓﻈﻪ ﻛﻪ ﺑﻪ ﺻﻮرت دﻳﻨﺎﻣﻴﻚ ﺗﻌﻴﻴﻦ ﺷﺪه اﺳﺖ ﻗﺮار ﻣـﻲ ﮔﻴـﺮد‪ .‬در‬ ‫ﻣﺮﺣﻠﻪ ﺑﻌﺪ‪ JITCompiler ،‬ﺑﺎ ﺗﻐﻴﻴﺮ ردﻳﻒ ﻣﺮﺗﺒﻂ ﺑﺎ ﺗﺎﺑﻊ ﻣﺬﻛﻮر در ﺟﺪول داده اي داﺧﻠﻲ ﻛﻪ ﺗﻮﺳﻂ ‪ CLR‬اﻳﺠـﺎد ﺷـﺪه‬ ‫ﺑﻮد‪ ،‬آدرس ﻣﻮﺟﻮد در ردﻳﻒ را ﺑﺎ آدرس ﻛﺪ زﺑﺎن ﻣﺎﺷﻴﻦ ﺗﻮﻟﻴﺪ ﺷﺪه ﺟـﺎﻳﮕﺰﻳﻦ ﻣـﻲ ﻛﻨـﺪ‪ .‬در ﻧﻬﺎﻳـﺖ ‪ JITCompiler‬ﺑـﻪ‬ ‫آدرس ﻣﻮﺟﻮد در ﺣﺎﻓﻈﻪ ﻛﻪ ﻣﺤﺘﻮي ﻛﺪ ﺗﻮﻟﻴﺪ ﺷﺪه اﺳﺖ رﻓﺘﻪ و ﻛﺪ را اﺟﺮا ﻣﻲ ﻛﻨﺪ‪ .‬در ﭘﺎﻳﺎن اﻳـﻦ ﺗـﺎﺑﻊ اﺟـﺮاي ﺑﺮﻧﺎﻣـﻪ ﺑـﻪ ﺗـﺎﺑﻊ‬ ‫‪ Main‬ﺑﺎز ﮔﺸﺘﻪ و اﺟﺮاي ﺑﺮﻧﺎﻣﻪ اداﻣﻪ ﭘﻴﺪا ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﺑﺎ ﺑﺎزﮔﺸﺖ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻣﺘﺪ ‪ ،Main‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ ﻣﺸﺨﺺ اﺳﺖ ﺗـﺎﺑﻊ ‪ WriteLine‬ﺑـﺮاي دوﻣـﻴﻦ ﻣﺮﺗﺒـﻪ‬ ‫ﻓﺮاﺧﻮاﻧﻲ ﻣﻲ ﺷﻮد‪ .‬در اﻳﻦ ﻣﺮﺗﺒﻪ‪ ،‬ﻛﺪ ‪ IL‬ﻣﺮﺑﻮط ﺑﻪ ﺗﺎﺑﻊ اﺣﻀﺎر ﺷﺪه ﻗﺒﻼ ﺗﻮﺳﻂ ‪ JITCompiler‬ﺑﻪ ﻛـﺪ زﺑـﺎن ﻣﺎﺷـﻴﻦ‬ ‫ﺗﺒﺪﻳﻞ ﺷﺪه و در ﺣﺎﻓﻈﻪ ﻗﺮار ﮔﺮﻓﺘﻪ اﺳﺖ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ در اﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺑﻼك ﺣﺎﻓﻈﻪ اي ﻣﻲ رود ﻛﻪ ﻛﺪ ﻣﺮﺑﻮط ﺑﻪ ﺗﺎﺑﻊ‬ ‫ﻗﺮار دارد و ‪ JITCompiler‬اﺟﺮا ﻧﻤﻲ ﺷﻮد‪.‬‬

‫‪٩٢٧‬‬

‫ﻓﺮاﺧﻮاﻧﻲ ﺗﺎﺑﻊ ﺑﺮاي ﻣﺮﺗﺒﻪ دوم‬ ‫اﻳﻦ ﻣﻮرد در ﻣﺮﺗﺒﻪ اول ﻓﺮاﺧﻮاﻧﻲ ﻳﻚ ﺗﺎﺑﻊ ﺑﺎﻋﺚ اﻳﺠﺎد ﻳﻚ ﻣﻜﺚ ﻛﻮﺗﺎه در ﺑﺮﻧﺎﻣﻪ ﻣﻲ ﺷﻮد اﻣﺎ در ﻣﺮﺗﺒﻪ ﻫﺎي ﺑﻌﺪي اﺣـﻀﺎر ﺗـﺎﺑﻊ‪،‬‬ ‫ﺗﺎﺑﻊ ﺑﺎ ﺳﺮﻋﺘﻲ ﺑﺮاﺑﺮ ﻛﺪ ﻫﺎي زﺑﺎن ﻣﺎﺷﻴﻦ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ‪ .‬در ﺣﻘﻴﻘﺖ اﻳﻦ ﻛﺎﻣﭙﺎﻳﻞ ﻓﻘﻂ ﻳﻚ ﺑﺎر در ﻃﻮل ﺑﺮﻧﺎﻣﻪ رخ ﻣﻲ دﻫﺪ‪.‬‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ ذﻛﺮ ﺷﺪ ﻛﺪ زﺑﺎن ﻣﺎﺷﻴﻦ ﺗﺎﺑﻊ ﻓﺮاﺧﻮاﻧﻲ ﺷﺪه در ﻳﻚ ﺑﻼك ﺣﺎﻓﻈﻪ دﻳﻨﺎﻣﻴﻚ ﻗﺮار ﻣﻴﮕﻴﺮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﻫﻨﮕﺎم ﺧﺎﺗﻤﻪ ﺑﺮﻧﺎﻣﻪ‬ ‫ﻛﺪ ﻣﻮرد ﻧﻈـﺮ از ﺣﺎﻓﻈـﻪ ﭘـﺎك ﻣـﻲ ﺷـﻮد‪ .‬در ﻣﺮاﺗـﺐ ﺑﻌـﺪي ﻛـﻪ ﺑﺮﻧﺎﻣـﻪ اﺟـﺮا ﻣـﻲ ﺷـﻮد ﻫﻨﮕـﺎم ﻓﺮاﺧـﻮاﻧﻲ ﺗـﺎﺑﻊ ﻣـﻮرد ﻧﻈـﺮ‪،‬‬ ‫‪ JITCompiler‬ﻣﺠﺪداً اﺣﻀﺎر ﺷﺪه و ﺗﺎﺑﻊ را ﺑﻪ زﺑﺎن ﻣﺎﺷﻴﻦ ﺗﺒﺪﻳﻞ ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﻃﺮاﺣﺎﻧﻲ ﺑﺎ ﭘﻴﺶ زﻣﻴﻨﻪ از ﻣﺤﻴﻄﻬﺎﻳﻲ ﻣﺎﻧﻨﺪ ‪ C++‬ﻣﻤﻜﻦ اﺳﺖ ﻋﻘﻴﺪه داﺷﺘﻪ ﺑﺎﺷﻨﺪ ﻛﻪ اﻳﻦ ﻋﻤﻞ ﺗﺎﺛﻴﺮ ﻣﻨﻔـﻲ ﺑـﺮ ﻛـﺎراﻳﻲ ﺑﺮﻧﺎﻣـﻪ‬ ‫ﺧﻮاﻫﺪ داﺷﺖ‪ .‬ﺑﺎ وﺟﻮد اﻳﻨﻜﻪ ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه ﺑﺮاي ﻳﻚ ﺳﺎﺧﺘﺎر ﭘﺮدازﻧﺪه ﺧﺎص ﺗﻮﻟﻴﺪ ﻣﻲ ﺷﻮﻧﺪ‪ ،‬اﻣﺎ ﻫﻨﮕﺎم اﺟﺮا اﻳـﻦ ﻛـﺪﻫﺎ‬ ‫ﺑﻪ راﺣﺘﻲ اﺟﺮا ﻣﻲ ﺷﻮﻧﺪ‪ .‬اﻣﺎ اﺟﺮاي ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﺷﺎﻣﻞ دو ﻣﺮﺣﻠﻪ ﻣﻲ ﺷﻮد‪ .‬در ﻣﺮﺣﻠﻪ اول ﺳﻮرس ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺴﺘﻲ ﺑﻪ ﻛـﺪ‬ ‫‪ IL‬ﺗﺒﺪﻳﻞ ﺷﻮد و ﺳﭙﺲ در ﻣﺮﺣﻠﻪ ﺑﻌﺪ در ﻫﺮ ﺑﺎر اﺟﺮاي ﺑﺮﻧﺎﻣﻪ‪ ،‬ﻛﺪ ﺑﺎﻳﺴﺘﻲ ﺑﻪ زﺑﺎن ﻣﺎﺷﻴﻦ ﺗﺒﺪﻳﻞ ﺷﺪه و در ﺣﺎﻓﻈﻪ ذﺧﻴﺮه ﺷـﻮد‪.‬‬ ‫اﻳﻦ ﻋﻤﻞ ﻣﻮﺟﺐ ﺻﺮف ﺑﻴﺸﺘﺮ ﺣﺎﻓﻈﻪ و زﻣﺎن ﭘﺮدازﻧﺪه ﻣﻲ ﺷﻮد‪.‬‬ ‫در ﻧﮕﺎه اول ﻣﻤﻜﻦ اﺳﺖ ﻧﻈﺮ اﻳﻦ اﻓﺮاد درﺳﺖ ﺟﻠﻮه ﻛﻨﺪ اﻣﺎ ﺣﻘﻴﻘﺖ اﻳﻦ اﺳﺖ ﻛﻪ اﻳﻦ اﻋﻤﺎل ﺗﺎﺛﻴﺮ ﭼﻨﺪاﻧﻲ ﺑﺮ ﻛﺎراﻳﻲ ﺑﺮﻧﺎﻣﻪ ﻧﺪارد و‬ ‫ﺑﺮرﺳﻲ ﻫﺎي اﻧﺠﺎم ﺷﺪه در اﻳﻦ زﻣﻴﻨﻪ ﻧﺸﺎن ﻣﻴﺪﻫﺪ ﻛﻪ ﺗﺎﺛﻴﺮي ﻛﻪ اﻧﺠﺎم اﻣﻮر ذﻛﺮ ﺷﺪه ﺑﺮاي اﺟﺮاي ﻛﺪ ﻫـﺎي ﻣـﺪﻳﺮﻳﺖ ﺷـﺪه ﺑـﺮ‬ ‫ﺳﺮﻋﺖ ﺑﺮﻧﺎﻣﻪ ﻣﻴﮕﺬارد اﺻﻼ ﻣﺸﻬﻮد و ﻗﺎﺑﻞ ﺗﻮﺟﻪ ﻧﻴﺴﺖ‪.‬‬

‫‪٩٢٨‬‬

‫ﺣﺘﻲ در ﺑﻌﻀﻲ از ﺷﺮاﻳﻂ اﺟﺮاي ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﺳﺮﻳﻌﺘﺮ از ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه اﻧﺠﺎم ﻣﻲ ﺷﻮد‪ .‬اﻳﻦ اﻣﺮ ﺑـﻪ اﻳـﻦ دﻟﻴـﻞ‬ ‫اﺳﺖ ﻛﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ‪ JIT‬ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻧﺴﺒﺖ ﺑﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه اﻃﻼﻋـﺎت ﺑﻴـﺸﺘﺮي از ﻣﺤـﻴﻂ اﺟـﺮا در‬ ‫دﺳﺖ دارد‪ .‬ﺑﻪ ﻃﻮر ﻣﺜﺎل در ﺷﺮاﻳﻂ زﻳﺮ ﻛﺎﻣﭙﺎﻳﻠﺮ ‪ JIT‬ﺳﺮﻳﻌﺘﺮ از دﻳﮕﺮ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎ ﻋﻤﻞ ﻣﻲ ﻛﻨﺪ‪:‬‬ ‫‪ (1‬ﻳﻚ ﻛﺎﻣﭙﺎﻳﻠﺮ ‪ JIT‬از ﻧﻮع ﺳﺎﺧﺘﺎر ﭘﺮدازﻧﺪه ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺑﺮ روي آن اﺟﺮا ﻣﻲ ﺷﻮد اﻃﻼع دارد و ﻣﻲ ﺗﻮاﻧﺪ از دﺳﺘﻮرات وﻳﮋه اي‬ ‫ﻛﻪ آن ﻧﻮع ﭘﺮدازﻧﺪه اراﺋﻪ ﻣﻲ دﻫﺪ ﺣﺪاﻛﺜﺮ اﺳﺘﻔﺎده را داﺷﺘﻪ ﺑﺎﺷﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل اﻳﻦ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻣﻴﺘﻮاﻧـﺪ ﺑﺮﻧﺎﻣـﻪ را ﺑـﺮاي ﭘﺮدازﻧـﺪه‬ ‫ﻫﺎي ‪ Pentium4‬ﺑﻬﻴﻨﻪ ﻛﻨﺪ‪ .‬اﻣﺎ ﻣﻌﻤﻮﻻ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه ﺑﻪ ﺻﻮرﺗﻲ ﻛﺎﻣﭙﺎﻳﻞ ﻣﻲ ﺷﻮﻧﺪ ﻛـﻪ ﺑـﺎ ﺗﻤـﺎم اﻧـﻮاع‬ ‫ﭘﺮدازﻧﺪه ﻫﺎ ﺳﺎزﮔﺎر ﺑﺎﺷﻨﺪ‪ .‬اﻳﻦ اﻣﺮ از ﺑﻬﺮه وري از اﻣﻜﺎﻧﺎت وﻳﮋه ي ﭘﺮدازﻧﺪه ﺟﻠﻮﮔﻴﺮي ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫‪ (2‬ﻳﻚ ﻛﺎﻣﭙﺎﻳﻠﺮ ‪ JIT‬ﻣﻲ ﺗﻮاﻧﺪ ﺷﺮاﻳﻄﻲ را ﻛﻪ ﻫﻤﻮاره ﻧﺎدرﺳﺖ ﻫﺴﺘﻨﺪ ﺗﺸﺨﻴﺺ دﻫﺪ و آﻧﻬﺎ را ﻛﺎﻣﭙﺎﻳﻞ ﻧﻜﻨﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل ﻳﻚ‬ ‫دﺳﺘﻮر ﻣﺸﺎﺑﻪ زﻳﺮ در ﻳﻚ ﺗﺎﺑﻊ ﻫﺮﮔﺰ ﻛﺎﻣﭙﺎﻳﻞ ﻧﻤﻲ ﺷﻮد و اﻳﻦ اﻣﺮ ﻣﻮﺟﺐ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﺪ ﻣﻮرد ﻧﻈﺮ ﺑﺮاي ﻣﺤﻴﻄﻲ ﻛﻪ ﺑﺎﻳﺪ در‬ ‫آن اﺟﺮا ﺷﻮد ﺑﻬﻴﻨﻪ ﺷﻮد‬ ‫)‪if (numberOfCPUs > 1‬‬ ‫{‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫}‬ ‫اﻳﻨﻬﺎ ﺗﻨﻬﺎ ﺗﻌﺪاد ﻣﺤﺪودي از دﻻﻳﻠﻲ ﺑﻮدﻧﺪ ﻛﻪ ﻧﺸﺎن دﻫﻨﺪه اﺟﺮاي ﺑﻬﺘﺮ ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﻧﺴﺒﺖ ﺑﻪ ﻛﺪ ﻫﺎي ﻣـﺪﻳﺮﻳﺖ ﻧـﺸﺪه‬ ‫ﻫﺴﺘﻨﺪ‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ ذﻛﺮ ﺷﺪ ﺳﺮﻋﺖ اﻳﻦ ﻛﺪﻫﺎ ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻛﺎﻣﻼً ﻣﻨﺎﺳﺐ اﺳﺖ‪ .‬اﻣﺎ ﺑﺎ وﺟﻮد اﻳﻦ اﮔـﺮ ﻫﻤﭽﻨـﺎن اﻳـﻦ اﺣـﺴﺎس‬ ‫وﺟﻮد دارد ﻛﻪ اﻳﻦ ﻛﺪﻫﺎ ﺳﺮﻋﺖ ﻣﻄﻠﻮب را اراﺋﻪ ﻧﻤﻲ دﻫﻨﺪ ﻣﻲ ﺗﻮان از اﺑﺰارﻫﺎﻳﻲ ﻛﻪ ﺑﺮاي ﺗﺒﺪﻳﻞ ﻛﺪ ‪ IL‬ﺑﻪ ﻛﺪ زﺑـﺎن ﻣﺎﺷـﻴﻦ در‬ ‫‪ .NET Framework SDK‬وﺟﻮد دارد اﺳﺘﻔﺎده ﻛﺮد‪ .‬ﺑﺮاي ﻣﺜﺎل اﺑﺰاري ﺑﻪ ﻧﺎم ‪ ngen.exe‬وﺟﻮد دارد ﻛـﻪ ﻛـﺪ‬ ‫زﺑﺎن ﻣﺎﺷﻴﻦ ﻣﺮﺑﻮط ﺑﻪ ﻳﻚ ﻓﺎﻳﻞ ﻣﺤﺘﻮي ﻛﺪ ‪ IL‬را در دﻳﺴﻚ ذﺧﻴﺮه ﻣﻲ ﻛﻨﺪ‪ .‬ﻫﻨﮕﺎﻣﻲ ﻛﻪ ‪ CLR‬ﻣﺸﺎﻫﺪه ﻛﻨـﺪ ﻛـﻪ ﻛـﺪ زﺑـﺎن‬ ‫ﻣﺎﺷﻴﻦ ﻓﺎﻳﻠﻲ ﻛﻪ ﻗﺼﺪ اﺟﺮاي آن را دارد در دﻳﺴﻚ ﻣﻮﺟﻮد اﺳﺖ از آن ﻛﺪ ﺑﻪ ﺟﺎي ﻛﺪ ‪ IL‬اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ‪.‬‬

‫ﻣﺠﻤﻮﻋﻪ ﻛﺘﺎﺑﺨﺎﻧﻪ ﻛﻼس ‪:.NET Framework‬‬ ‫ﻋﻼوه ﺑﺮ ‪ ،CLR‬در ﻣﺠﻤﻮﻋﻪ ‪ .NET Framework‬ﺑﺨﺶ دﻳﮕﺮي ﻧﻴﺰ وﺟﻮد دارد ﻛﻪ ﺷﺎﻣﻞ ﻳـﻚ ﻛﺘﺎﺑﺨﺎﻧـﻪ ي ﻛـﻼس‬ ‫ﻣﻲ ﺷﻮد‪ .‬اﻳﻦ ﺑﺨﺶ ﻛﻪ ‪ 1FCL‬ﻧﺎم دارد ﺷﺎﻣﻞ ﭼﻨﺪﻳﻦ ﻫﺰار ﻛﻼس اﺳﺖ ﻛﻪ ﻫﺮ ﻛﺪام وﻇﻴﻔﻪ ﺧﺎﺻـﻲ را اﻧﺠـﺎم ﻣـﻲ دﻫﻨـﺪ‪ .‬اﻳـﻦ‬ ‫ﻣﺠﻤﻮﻋﻪ ﺑﺎ ﻫﻢ‪ ،‬ﻳﻌﻨﻲ ‪ CLR‬و ‪ ،FCL‬ﺑﻪ ﻃﺮاﺣﺎن اﺟﺎزه ﻣﻲ دﻫﻨﺪ ﻛﻪ ﭼﻨﺪﻳﻦ ﻣﺪل ﺑﺮﻧﺎﻣﻪ را ﻃﺮاﺣﻲ ﻛﻨﻨﺪ ﻛﻪ ﻋﺒﺎرت اﻧﺪ از‪:‬‬ ‫‪ (1‬وب ﺳﺮوﻳﺴﻬﺎي ﻣﺒﺘﻨﻲ ﺑﺮ ‪ :XML‬وب ﺳﺮوﻳﺲ ﻫﺎ ﺗﻮاﺑﻌﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﺑﻪ راﺣﺘﻲ از ﻃﺮﻳﻖ ﺷﺒﻜﻪ وب ﻗﺎﺑـﻞ دﺳﺘﺮﺳـﻲ و‬ ‫ﻓﺮاﺧﻮاﻧﻲ ﻫﺴﺘﻨﺪ‪ .‬اﻳﻦ ﻗﺴﻤﺖ در ﺣﻘﻴﻘﺖ اﺻﻠﻲ ﺗﺮﻳﻦ ﻓﻠﺴﻔﻪ ي ﻇﻬﻮر و اﺑﺪاع ‪ .NET‬ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد‪.‬‬ ‫‪ (2‬ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب‪ :‬اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻫﺎ‪ ،‬ﺑﺮﻧﺎﻣﻪ ﻫﺎ و ﻳﺎ وب ﺳﺎﻳﺖ ﻫﺎﻳﻲ ﻣﺒﺘﻨﻲ ﺑﺮ ﺻﻔﺤﺎت ‪ HTML‬ﻫﺴﺘﻨﺪ‪ .‬ﻋﻤﻮﻣـﺎً اﻳـﻦ‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﺎ اﺳﺘﻔﺎده از درﺧﻮاﺳﺖ اﻃﻼﻋﺎت از ﺳﺮورﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋـﺎﺗﻲ و ﭼﻨـﺪﻳﻦ وب ﺳـﺮوﻳﺲ‪ ،‬اﻃﻼﻋـﺎت ﻣـﻮرد ﻧﻴـﺎز را‬ ‫درﻳﺎﻓﺖ ﻛﺮده و ﺑﻌﺪ از ﺗﺤﻠﻴﻞ و اﻧﺠﺎم ﭘﺮدازش روي آﻧﻬﺎ‪ ،‬ﺻﻔﺤﺎت ‪ HTML‬ﻣﺒﻨـﻲ ﺑـﺮ درﺧﻮاﺳـﺖ ﻛـﺎرﺑﺮ را ﺗـﺸﻜﻴﻞ داده و‬

‫‪Framework Class Library‬‬

‫‪1‬‬

‫‪٩٢٩‬‬

‫‪(3‬‬

‫‪(4‬‬

‫‪(5‬‬

‫‪(6‬‬

‫اﻃﻼﻋﺎت ﺧﻮاﺳﺘﻪ ﺷﺪه را از ﻃﺮﻳﻖ ﻣﺮورﮔﺮ ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎي ﺳﺮوﻳﺲ ﮔﻴﺮﻧﺪه ﻧﻤﺎﻳﺶ ﻣﻲ دﻫﻨﺪ‪ .‬اﻳـﻦ ﻗـﺴﻤﺖ در ﺣﻘﻴﻘـﺖ ﻻﻳـﻪ‬ ‫ﻣﻴﺎﻧﻲ ﻳﺎ ﻻﻳﻪ ﻣﻨﻄﻖ ﺗﺠﺎري در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﭼﻨﺪ ﻻﻳﻪ ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد‪.‬‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وﻳﻨﺪوز‪ :‬ﺑﺮﻧﺎﻣﻪ ﻫﺎﻳﻲ ﺑﺎ راﺑﻂ ﮔﺮاﻓﻴﻜﻲ ﺑﺮاي ﺳﻴﺴﺘﻢ ﻋﺎﻣﻞ وﻳﻨﺪوز‪ .‬ﻫﻤﺎﻧﻨﺪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب‪ ،‬اﻳﻦ‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﻧﻴﺰ ﻗﺪرت ﺑﺮﻗﺮاري ارﺗﺒﺎط ﺑﺎ ﺳﺮورﻫﺎي ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ را داﺷﺘﻪ و ﻣﻴﺘﻮاﻧـﺪ از وب ﺳﺮوﻳـﺴﻬﺎي ﻣﺒﺘﻨـﻲ ﺑـﺮ ‪XML‬‬ ‫اﺳﺘﻔﺎده ﻛﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ در ﻣﻮاﻗﻌﻲ ﻛﻪ ﻧﻴﺎز ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ وب ﻧﺒﺎﺷﺪ ﻣﻴﺘﻮان از اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ ﺑﺎ اﻣﻜﺎﻧﺎت ﺷﺒﻜﻪ و ﻧﻴـﺰ‬ ‫ﻗﺪرت ﺑﻴﺸﺘﺮ در ﻃﺮاﺣﻲ راﺑﻂ ﮔﺮاﻓﻴﻜﻲ اﺳﺘﻔﺎده ﻛﺮد‪.‬‬ ‫ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ ﻛﻨﺴﻮل در وﻳﻨﺪوز‪ :‬در ﻣﻮاﻗﻌﻲ ﻛﻪ ﻧﻴﺎزي ﺑﻪ راﺑﻂ ﮔﺮاﻓﻴﻜﻲ ﻛﺎرﺑﺮ ﻧﻴﺴﺖ و ﻳﺎ ﻳﻚ راﺑﻂ ﺳﺎده ﻛـﺎﻓﻲ‬ ‫اﺳﺖ ﻣﻲ ﺗﻮان از اﻳﻦ ﻧﻮع ﺑﺮﻧﺎﻣﻪ ﻫﺎ اﺳﺘﻔﺎده ﻛﺮد‪ .‬ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﺎ و ﺑﻌﻀﻲ از ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻛـﺎرﺑﺮدي و ﻧﻴـﺰ اﺑﺰارﻫـﺎ از اﻳـﻦ دﺳـﺘﻪ‬ ‫ﻫﺴﺘﻨﺪ‪.‬‬ ‫ﺳﺮوﻳﺴﻬﺎي وﻳﻨﺪوز‪ :‬ﻳﻜﻲ دﻳﮕﺮ از اﻧﻮاع ﺑﺮﻧﺎﻣـﻪ ﻫـﺎﻳﻲ ﻛـﻪ ﻗﺎﺑﻠﻴـﺖ ﻃﺮاﺣـﻲ آن ﺑـﺎ ‪ .NET‬وﺟـﻮد دارد‪ ،‬ﺳﺮوﻳـﺴﻬﺎي‬ ‫وﻳﻨﺪوزي اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﻣﺮﻛﺰ ﻛﻨﺘﺮل ﺳـﺮوﻳﺲ وﻳﻨـﺪوز )‪ 1(SCM‬و ﻧﻴـﺰ ‪ .NET Framework‬ﻗﺎﺑـﻞ ﻛﻨﺘـﺮل‬ ‫ﻫﺴﺘﻨﺪ‪.‬‬ ‫ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫﺎ و ﻛﺘﺎﺑﺨﺎﻧﻪ ﻫﺎي ﻛﻼس‪ :‬ﺑﻪ وﺳﻴﻠﻪ ‪ .NET Framework‬ﻣﻲ ﺗﻮان ﺑﻪ ﻃﺮاﺣﻲ ﻛﺎﻣﭙﻮﻧﻨﺖ ﻫـﺎﻳﻲ‬ ‫ﭘﺮداﺧﺖ ﻛﻪ ﺑﻪ راﺣﺘﻲ ﻗﺎﺑﻞ ﺗﻮزﻳﻊ و ﻧﻴﺰ ﻗﺎﺑﻞ اﺳﺘﻔﺎده در ﻣﺤﻴﻄﻬﺎي دﻳﮕﺮ ﺑﺎﺷﺪ‪.‬‬

‫ﺑﻪ دﻟﻴﻞ اﻳﻨﻜﻪ ‪ FCL‬ﺷﺎﻣﻞ ﭼﻨﺪﻳﻦ ﻫﺰار ﻛﻼس ﻣﻲ ﺷﻮد‪ ،‬ﺗﻤﺎم ﻛﻼﺳﻬﺎي ﻣﺮﺗﺒﻂ ﺑﻪ ﻳﻜﺪﻳﮕﺮ در ﻳﻚ ﻓﻀﺎي ﻧﺎم ﮔـﺮدآوري ﺷـﺪه‬ ‫اﻧﺪ‪ .‬اﺻﻠﻲ ﺗﺮﻳﻦ ﻓﻀﺎي ﻧﺎم‪ ،‬ﻓﻀﺎي ﻧﺎم ‪ System‬اﺳﺖ ﻛﻪ ﻣﺤﺘﻮي ﻛـﻼس ‪ Object‬و ﺗﻌـﺪادي ﻛـﻼس ﭘﺎﻳـﻪ اي دﻳﮕـﺮ‬ ‫اﺳﺖ‪ .‬ﻛﻼس ‪ Object‬ﻳﻚ ﻛﻼس ﭘﺎﻳﻪ اﺳﺖ ﻛﻪ ﺗﻤﺎم ﻛﻼﺳﻬﺎي ‪ FCL‬از اﻳﻦ ﻛﻼس ﻣﺸﺘﻖ ﻣﻲ ﺷﻮﻧﺪ‪ .‬ﻻزم ﺑﻪ ذﻛﺮ اﺳـﺖ‬ ‫ﻛﻪ ﺗﻤﺎم ﻗﻮاﻋﺪ ﺷﻴﺊ ﮔﺮاﻳﻲ در ﻛﻼﺳﻬﺎي ‪ FCL‬رﻋﺎﻳﺖ ﺷﺪه اﻧﺪ و ﺑﺪﻳﻦ ﺗﺮﺗﻴﺐ اﻳﻦ اﻣﻜﺎن را ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ داده اﻧﺪ ﻛﻪ در ﻫـﺮ‬ ‫ﻣﺮﺣﻠﻪ ﺑﺘﻮاﻧﺪ اﻣﻜﺎﻧﺎت و ﻳﺎ ﺗﻮاﺑﻊ ﺑﺮﻧﺎﻣﻪ را ﻣﻄﺎﺑﻖ ﻧﻴﺎزﻫﺎي ﺧﻮد ﺗﻐﻴﻴﺮ دﻫﺪ و ﻛﻼﺳﻬﺎي ﺟﺪﻳﺪي ﻃﺮاﺣﻲ ﻛﻨﺪ ﻛﻪ ﻋﻼوه ﺑـﺮ اﻣﻜﺎﻧـﺎت‬ ‫ﻛﻼﺳﻬﺎي ﻗﺒﻠﻲ‪ ،‬ﻧﻴﺎزﻫﺎي ﻃﺮاح و ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ را ﻧﻴﺰ ﺑﻪ ﻃﻮر ﻛﺎﻣﻞ ﺑﺮﻃﺮف ﻛﻨﺪ‪.‬‬ ‫ﺟﺪول زﻳﺮ ﺑﻌﻀﻲ از ﻓﻀﺎي ﻧﺎم ﻫﺎي ﭘﺮ ﻛﺎرﺑﺮد در ‪ FCL‬را ﻣﻌﺮﻓﻲ ﻛﺮده و ﺑﻪ ﻃﻮر ﻣﺨﺘﺼﺮ راﺟﻊ ﺑﻪ آﻧﻬﺎ ﺗﻮﺿﻴﺢ ﻣﻴﺪﻫﺪ‪.‬‬ ‫ﻓﻀﺎي ﻧﺎم‬ ‫‪System‬‬

‫‪System.Collections‬‬

‫‪System.Diagnostics‬‬

‫‪System.Drawing‬‬

‫‪System.EnterpriseServices‬‬

‫ﺷﺮح‬ ‫ﻣﺤﺘﻮي ﺗﻤﺎم ﻛﻼﺳﻬﺎي ﭘﺎﻳﻪ اي اﺳﺖ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﺗﻤﺎم ﺑﺮﻧﺎﻣﻪ‬ ‫ﻫﺎ اﺳﺘﻔﺎده ﻣﻲ ﺷﻮﻧﺪ‪.‬‬ ‫ﻣﺠﻤﻮﻋﻪ اي اﺳﺖ از ﻛﻼﺳﻬﺎ ﻛﻪ ﺑﺮاي ﻧﮕﻬﺪاري آراﻳﻪ ﻫـﺎﻳﻲ از‬ ‫اﺷﻴﺎ ﻛﻪ ﺷﺎﻣﻞ آراﻳﻪ ﻫﺎي ﻋﻤـﻮﻣﻲ ﻣﺜـﻞ ﺻـﻒ‪ ،‬ﭘـﺸﺘﻪ‪ ،‬ﻟﻴـﺴﺖ‬ ‫ﭘﻴﻮﻧﺪي و ‪ ...‬ﻣﻲ ﺷﻮد ﺑﻪ ﻛﺎر ﻣﻲ رود‪.‬‬ ‫ﻣﺤﺘﻮي ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي ﻣﺴﺘﻨﺪ ﺳﺎزي و ﻧﻴـﺰ ﺧﻄـﺎ ﻳـﺎﺑﻲ در‬ ‫ﺑﺮﻧﺎﻣﻪ اﺳﺖ‪.‬‬ ‫ﺷﺎﻣﻞ ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي ﻧﮕﻬﺪاري اﺷﻴﺎي ﻣﺮﺑﻮط ﺑـﻪ ﮔﺮاﻓﻴـﻚ‬ ‫دو ﺑﻌﺪي اﺳﺖ‪ .‬اﻳﻦ ﻣﺠﻤﻮﻋﻪ ﺑﻴﺸﺘﺮ ﺑﺮاي ﺑﺮﻧﺎﻣـﻪ ﻫـﺎي ﺗﺤـﺖ‬ ‫وﻳﻨﺪوز و ﻧﻴﺰ ﻧﻤﺎﻳﺶ ﻋﻜﺲ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤـﺖ وب ﺑـﻪ ﻛـﺎر‬ ‫ﻣﻲ رود‪.‬‬ ‫اﻳﻦ ﻓﻀﺎي ﻧﺎم ﺷﺎﻣﻞ ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي ﻣﺪﻳﺮﻳﺖ ﺗﺮاﻛﻨﺶ ﻫـﺎ‪،‬‬

‫‪Windows Service Control Manager‬‬

‫‪1‬‬

‫‪٩٣٠‬‬

‫‪System.Globalization‬‬

‫‪System.IO‬‬

‫‪System.Management‬‬

‫‪System.Net‬‬ ‫‪System.Reflection‬‬

‫‪System.Resources‬‬

‫‪System.Runtime.InteropServices‬‬

‫‪System.Runtime.Remoting‬‬

‫‪System.Runtime.Serialization‬‬

‫‪System.Security‬‬ ‫‪System.Text‬‬

‫‪System.Threading‬‬

‫‪System.Xml‬‬

‫ﻓﻌﺎل ﺳﺎزي ‪ ،JIT‬اﻣﻨﻴﺖ و ‪ ...‬اﺳﺖ ﻛﻪ ﻣﻮﺟﺐ ﻛﺎراﻳﻲ ﺑﻴـﺸﺘﺮ‬ ‫ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه در ﺳﺮور ﻣﻲ ﺷﻮﻧﺪ‪.‬‬ ‫اﻳﻦ ﻗﺴﻤﺖ ﺷﺎﻣﻞ ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي ﭘﺸﺘﻴﺒﺎﻧﻲ زﺑﺎﻧﻬﺎي دﻳﮕﺮ از‬ ‫ﻗﺒﻴﻞ ﺣﺮوف آن زﺑﺎﻧﻬﺎ‪ ،‬ﻧﺤﻮه ي ﻧﻤﺎﻳﺶ ﺗﺎرﻳﺦ و ﻗﺎﻟﺐ ﺑﻨﺪي در‬ ‫آن و ‪ ...‬ﻣﻲ ﺷﻮد‪.‬‬ ‫ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي اﻧﺠﺎم ﻋﻤﻠﻴـﺎت ورودي و ﺧﺮوﺟـﻲ از ﻗﺒﻴـﻞ‬ ‫ﻛﺎر ﺑﺎ ﻓﺎﻳﻠﻬﺎ و داﻳﺮﻛﺘﻮري ﻫﺎ را درﺑﺮ دارد‪.‬‬ ‫ﺷﺎﻣﻞ ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي ﻣﺪﻳﺮﻳﺖ دﻳﮕﺮ ﻛﺎﻣﭙﻴﻮﺗﺮﻫﺎ ﺑـﻪ وﺳـﻴﻠﻪ‬ ‫دﺳﺘﮕﺎه ﻫﺎي ﻣﺪﻳﺮﻳﺘﻲ وﻳﻨﺪوز ﻳﺎ ‪ WMI‬اﺳﺖ‪.‬‬ ‫ﺷﺎﻣﻞ ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي ﺑﺮﻗﺮاري ارﺗﺒﺎﻃﺎت ﺷﺒﻜﻪ اي اﺳﺖ‪.‬‬ ‫ﺷﺎﻣﻞ ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي ﺑﺮرﺳﻲ و اﺳﺘﻔﺎده از اﻃﻼﻋﺎت داﺧـﻞ‬ ‫‪ metadata‬اﺳﺖ‪.‬‬ ‫ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي ﻣـﺪﻳﺮﻳﺖ ﻣﻨـﺎﺑﻊ ﺧـﺎرﺟﻲ اﺳـﺘﻔﺎده ﺷـﺪه در‬ ‫ﺑﺮﻧﺎﻣﻪ را ﺷﺎﻣﻞ ﻣﻲ ﺷﻮد‪.‬‬ ‫ﻛﻼس ﻫﺎي اﻳﻦ ﻓﻀﺎي ﻧﺎم ﺑﻪ ﻛـﺪ ﻫـﺎي ﻣـﺪﻳﺮﻳﺖ ﺷـﺪه اﻳـﻦ‬ ‫اﻣﻜــﺎن را ﻣــﻲ دﻫــﺪ ﻛــﻪ از اﻣﻜﺎﻧــﺎت ﻗﺒﻠــﻲ وﻳﻨــﺪوز از ﻗﺒﻴــﻞ‬ ‫ﻛﺎﻣﭙﻮﻧﻨــﺖ ﻫــﺎي ‪ COM‬و ﻳــﺎ ﺗﻮاﺑــﻊ ﻣﻮﺟــﻮد در ﻓﺎﻳﻠﻬــﺎي‬ ‫‪ Win32‬اﺳﺘﻔﺎده ﻛﻨﻨﺪ‪.‬‬ ‫ﻛﻼس ﻫﺎﻳﻲ را ﺷﺎﻣﻞ ﻣﻲ ﺷﻮد ﻛـﻪ ﺑـﻪ دﻳﮕـﺮ ﻛﻼﺳـﻬﺎ اﺟـﺎزه‬ ‫ﻣﻴﺪﻫﻨﺪ از را دور ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﮔﻴﺮﻧﺪ‪.‬‬ ‫ﻛﻼس ﻫﺎﻳﻲ را در ﺑﺮ دارد ﻛﻪ ﺑﻪ اﺷﻴﺎ اﻳﻦ اﻣﻜﺎن را ﻣـﻲ دﻫﻨـﺪ‬ ‫ﺑﻪ رﺷﺘﻪ اي ﺗﺒﺪﻳﻞ ﺷﻮﻧﺪ ﻛﻪ ﻣﻌﺮف آﻧﻬﺎ ﺑﺎﺷﺪ و از رﺷﺘﻪ اي ﻛﻪ‬ ‫ﻣﻌﺮف آﻧﻬﺎ اﺳﺖ ﺑﻪ ﻳﻚ ﺷﻴﺊ ﺗﺒﺪﻳﻞ ﺷﻮﻧﺪ‪.‬‬ ‫ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي ﻣﺤﺎﻓﻈﺖ از اﻃﻼﻋﺎت و ﻣﻨﺎﺑﻊ ﺑﺮﻧﺎﻣﻪ‪.‬‬ ‫ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي ﻛﺎر ﺑـﺎ ﻣـﺘﻦ در ﻗﺎﻟﺒﻬـﺎي ﻣﺨﺘﻠـﻒ از ﻗﺒﻴـﻞ‬ ‫‪ ASCII‬و ﻳﺎ ‪.Unicode‬‬ ‫ﺷﺎﻣﻞ ﻛﻼس ﻫﺎﻳﻲ اﺳﺖ ﻛﻪ ﺑﺮاي اﺟﺮاي ﻫﻤﺰﻣﺎن ﭘﺮدازش ﻫـﺎ‬ ‫و ﻧﻴﺰ ﻫﻤﺎﻫﻨﮕﻲ در دﺳﺘﺮﺳﻲ ﺑﻪ اﻃﻼﻋﺎت ﻣﻮرد اﺳﺘﻔﺎده ﻗﺮار ﻣﻲ‬ ‫ﮔﻴﺮد‪.‬‬ ‫ﻛﻼس ﻫﺎﻳﻲ ﺑﺮاي ﺑﺮرﺳﻲ و ﭘﺮدازش داده ﻫﺎ در ﻗﺎﻟـﺐ ‪XML‬‬ ‫را درﺑﺮ دارد‪.‬‬

‫ﺳﻴﺴﺘﻢ ﻧﻮع داده اي ﻋﻤﻮﻣﻲ‪:‬‬ ‫اﺣﺘﻤﺎﻻً ﺗﺎ ﻛﻨﻮن ﻣﺘﻮﺟﻪ اﻳﻦ ﻧﻜﺘﻪ ﺷﺪه اﻳﺪ ﻛﻪ ﻳﻜﻲ از ﻣﻬﻤﺘﺮﻳﻦ ﻗﺴﻤﺘﻬﺎي ‪ CLR‬درﺑﺎره ي ﻛﺎر ﺑﺎ ﻛﻼﺳـﻬﺎ اﺳـﺖ‪ .‬اﻳـﻦ ﻛﻼﺳـﻬﺎ‬ ‫ﻛﺎراﻳﻲ ﻻزم را ﺑﻪ ﺑﺮﻧﺎﻣﻪ و ﻳﺎ ﻛﺎﻣﭙﻮﻧﻨﺖ در ﺣﺎل ﻃﺮاﺣﻲ اراﺋﻪ ﻣﻲ دﻫﻨﺪ‪ .‬ﻛﻼﺳﻬﺎ ﻣﻮﺟﺐ ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﻛﺪ ﻫﺎي ﻃﺮاﺣﻲ ﺷﺪه در ﻳﻚ‬ ‫زﺑﺎن در زﺑﺎﻧﻬﺎي دﻳﮕﺮ ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﺑﺎﺷﺪ‪ .‬ﺑﻪ ﻋﻠﺖ اﻳﻨﻜﻪ ﻫﺴﺘﻪ اﺻﻠﻲ ‪ CLR‬را ﻛﻼﺳﻬﺎ ﺗﺸﻜﻴﻞ ﻣـﻲ دﻫﻨـﺪ‪ ،‬ﻣﺎﻳﻜﺮوﺳـﺎﻓﺖ ﻳـﻚ‬

‫‪٩٣١‬‬

‫ﺳﺮي ﺧﺼﻮﺻﻴﺎت ﻋﻤﻮﻣﻲ در ﻣﻮرد ﻛﻼﺳﻬﺎ در ‪ .NET‬را ﺗﺤﺖ ﻋﻨﻮان ‪ 1CTS‬ﻋﻨﻮان ﻛﺮد ﻛﻪ ﺷﺎﻣﻞ ﭼﮕﻮﻧﮕﻲ ﺗﻌﺮﻳﻒ ﻛﻼﺳﻬﺎ و‬ ‫ﭼﮕﻮﻧﮕﻲ رﻓﺘﺎر آﻧﻬﺎ ﻣﻲ ﺷﻮد‪.‬‬ ‫ﻃﺒﻖ ﺧﺼﻮﺻﻴﺎت ‪ CTS‬ﻫﺮ ﻛﻼس ﻣﻴﺘﻮاﻧﺪ ﺷﺎﻣﻞ ﭼﻨﺪ ﻋﻀﻮ ﺑﺎﺷﺪ و ﻳﺎ ﺷﺎﻣﻞ ﻫﻴﭻ ﻋﻀﻮي ﻧﺒﺎﺷﺪ‪ .‬اﻋﻀﺎي ﻗﺎﺑﻞ ﺗﻌﺮﻳﻒ در ﻛﻼس‬ ‫ﻋﺒﺎرت اﻧﺪ از‪:‬‬ ‫ﻓﻴﻠﺪ ﻫﺎ‪ :‬ﻳﻚ ﻣﺘﻐﻴﺮ داده اي اﺳﺖ ﻛﻪ ﻣﻌﺮف وﺿﻌﻴﺖ ﻛﻨﻮﻧﻲ ﺷﻴﺊ اﺳﺖ‪ .‬ﻓﻴﻠﺪ ﻫﺎ ﺑﻪ وﺳﻴﻠﻪ ﻧﺎم و ﻧﻮع داده اي آﻧﻬﺎ ﻣـﺸﺨﺺ‬ ‫ﻣﻴﺸﻮﻧﺪ‪.‬‬ ‫ﻣﺘﺪ ﻫﺎ‪ :‬ﺗﺎﺑﻌﻲ اﺳﺖ ﻛﻪ ﭘﺮدازش ﺧﺎﺻﻲ را ﺑﺮ روي ﺷﻴﺊ اﻧﺠﺎم ﻣﻲ دﻫﺪ‪ .‬اﻳﻦ ﭘﺮدازش ﻣﻌﻤﻮﻻ ﺷﺎﻣﻞ ﺗﻐﻴﻴﺮ وﺿـﻌﻴﺖ آن ﻣـﻲ‬ ‫ﺷﻮد‪ .‬ﻣﺘﺪ ﻫﺎ ﻣﻌﻤﻮﻻ ﺷﺎﻣﻞ ﻳﻚ ﻧﺎم‪ ،‬ﻟﻴﺴﺖ ﻣﻘﺎدﻳﺮ ورودي‪ ،‬ﻟﻴﺴﺖ ﻣﻘﺎدﻳﺮ ﺧﺮوﺟﻲ و ﻧﻴﺰ ﻋﺒـﺎرت ﻫـﺎﻳﻲ ﺑـﺮاي ﺗﻌﻴـﻴﻦ ﺳـﻄﺢ‬ ‫دﺳﺘﺮﺳﻲ ﺑﻪ آن ﻫﺴﺘﻨﺪ‪.‬‬ ‫ﻣﺸﺨﺼﺎت‪ :2‬ﺑﺮاي ﻛﺎرﺑﺮ ﻛﻼس اﻳﻦ ﻋﻀﻮ ﻫﻤﺎﻧﻨﺪ ﻳﻚ ﻓﻴﻠﺪ اﺳﺖ اﻣﺎ ﺑﺮاي ﻃﺮاح ﻛﻼس اﻳﻦ ﻋﻀﻮ ﻫﻤﺎﻧﻨﺪ ﻳﻚ )ﻳﺎ دو( ﻣﺘﺪ‬ ‫اﺳﺖ‪ .‬اﻳﻦ ﻧﻮع ﻋﻀﻮ ﻫﺎي ﻛﻼس ﺑﻪ ﻃﺮاح و ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ اﻳﻦ اﻣﻜﺎن را ﻣﻲ دﻫﻨﺪ ﻛـﻪ ﻗﺒـﻞ از ﻗـﺮار دادن ورودي ﻛـﺎرﺑﺮ در‬ ‫ﻣﺘﻐﻴﺮ ﻣﺮﺑﻮﻃﻪ‪ ،‬ﺑﻪ ﺑﺮرﺳﻲ ﺻﺤﺖ آن ﺑﭙﺮدازد و ﻳﺎ ﭘﺮدازش ﻫﺎي ﻣﻮرد ﻧﻴﺎز دﻳﮕﺮ را ﻗﺒﻞ از ﻗﺮار دادن ﻣﻘﺪار اﻧﺠﺎم دﻫـﺪ‪ .‬ﻋـﻼوه‬ ‫ﺑﺮ اﻳﻦ‪ ،‬اﻳﻦ ﻧﻮع ﻋﻀﻮﻫﺎ ﺑﻪ ﻃﺮاﺣﺎن اﺟﺎزه اﻳﺠﺎد ﻓﻴﻠﺪ ﻫﺎي ﻓﻘﻂ ﺧﻮاﻧﺪﻧﻲ ﻳﺎ ﻓﻘﻂ ﻧﻮﺷﺘﻨﻲ را ﻣﻲ دﻫﻨﺪ‪.‬‬ ‫روﻳﺪادﻫﺎ‪ :‬روﻳﺪادﻫﺎ ﻣﻜﺎﻧﻴﺴﻤﻲ ﺑﺮاي اﻃﻼع دﻳﮕﺮ اﺷﻴﺎ از ﻳﻚ رﺧﺪاد ﺧﺎص در ﺷﻴﺊ ﻣﺤﺴﻮب ﻣﻲ ﺷﻮﻧﺪ‪ .‬ﺑـﺮاي ﻣﺜـﺎل ﻳـﻚ‬ ‫دﻛﻤﻪ ﻣﻲ ﺗﻮاﻧﺪ ﻫﻨﮕﺎﻣﻲ ﻛﻪ ﻓﺸﺮده ﺷﺪ اﺷﻴﺎي دﻳﮕﺮ را از اﻳﻦ اﺗﻔﺎق ﻣﻄﻠﻊ ﻛﻨﺪ‪.‬‬

‫‪(1‬‬ ‫‪(2‬‬

‫‪(3‬‬

‫‪(4‬‬

‫‪ CTS‬ﻋﻼوه ﺑﺮ اﻳﻦ ﻣﻮارد اﻣﻜﺎﻧﺎﺗﻲ را ﺑﺮاي ﺗﻌﻴﻴﻦ ﺳﻄﺢ دﺳﺘﺮﺳﻲ ﺑﻪ اﻋﻀﺎ اراﺋﻪ ﻣﻲ دﻫـﺪ‪ .‬ﺑـﺮاي ﻣﺜـﺎل اﺷـﻴﺎﻳﻲ ﻛـﻪ ﺑـﻪ ﻋﻨـﻮان‬ ‫‪ public‬در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮﻧﺪ ﺗﻮﺳﻂ ﻛﻼﺳﻬﺎي دﻳﮕﺮ‪ ،‬ﭼﻪ در داﺧﻞ و ﭼﻪ در ﺧـﺎرج اﺳـﻤﺒﻠﻲ ﻗﺎﺑـﻞ دﺳﺘﺮﺳـﻲ ﻫـﺴﺘﻨﺪ‪ .‬از‬ ‫ﺳﻮي دﻳﮕﺮ ﺗﻌﻴﻴﻦ ﻳﻚ ﻋﻀﻮ داده اي ﺑﻪ ﻋﻨﻮان ‪ ) Assembly‬در ‪ internal ،C#‬ﻧﺎﻣﻴﺪه ﻣﻲ ﺷﻮد( ﺑﺎﻋﺚ ﻣﻴﺸﻮد آن‬ ‫ﻋﻀﻮ ﻓﻘﻂ در ﻛﻼﺳﻬﺎي ﻣﻮﺟﻮد در داﺧﻞ اﺳﻤﺒﻠﻲ ﻗﺎﺑﻞ دﺳﺘﺮس ﺑﺎﺷﺪ‪.‬‬ ‫ﻟﻴﺴﺖ زﻳﺮ ﺳﻄﺢ دﺳﺘﺮﺳﻲ ﻫﺎي ﻣﺨﺘﻠﻒ را ﺑﺮاي اﻋﻀﺎي داده اي ﻛﻼس ﺗﻌﺮﻳﻒ ﻣﻴﻜﻨﺪ‪.‬‬ ‫‪(1‬‬

‫‪ :Private‬ﻣﺘﺪ ﻣﻮرد ﻧﻈﺮ ﻓﻘﻂ ﺑﻪ وﺳﻴﻠﻪ دﻳﮕﺮ ﻣﺘﺪﻫﺎي ﻫﻤﺎن ﻛﻼس ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ اﺳﺖ‪.‬‬

‫‪(2‬‬

‫‪ :Family‬ﻣﺘﺪ ﻣﻮرد ﻧﻈﺮ ﻓﻘﻂ ﺑﻪ وﺳﻴﻠﻪ ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ از آن ﻛﻼس ﻣﺸﺘﻖ ﺷﺪه اﻧﺪ‪ ،‬ﺑﺪون ﺗﻮﺟـﻪ ﺑـﻪ اﻳﻨﻜـﻪ در‬ ‫ﻫﻤﺎن اﺳﻤﺒﻠﻲ ﻗﺮار دارد ﻳﺎ ﻧﻪ‪ ،‬ﻗﺎﺑﻞ اﺳﺘﻔﺎده اﺳﺖ‪.‬‬ ‫‪ :Family and Assembly‬ﻣﺘﺪ ﻣﻮرد ﻧﻈﺮ ﻓﻘﻂ در ﺗﻮاﺑﻌﻲ از ﻫﻤﺎن اﺳﻤﺒﻠﻲ ﻛﻪ ﻋﻼوه ﺑﺮ آن از ﻛﻼس‬ ‫ﻣﻮرد ﻧﻈﺮ ﻧﻴﺰ ﻣﺸﺘﻖ ﺷﺪه اﻧﺪ ﻗﺎﺑﻞ اﺳﺘﻔﺎده اﺳﺖ‪ .‬ﺑﺴﻴﺎري از زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣـﻪ ﻧﻮﻳـﺴﻲ از ﻗﺒﻴـﻞ ‪ C#‬و ‪Visual‬‬ ‫‪ Basic‬اﻳﻦ ﻧﻮع ﺳﻄﺢ دﺳﺘﺮﺳﻲ را اراﺋﻪ ﻧﻤﻲ دﻫﻨﺪ‪.‬‬ ‫‪ :Assembly‬ﻣﺘﺪ ﻣﻮرد ﻧﻈﺮ ﻓﻘﻂ ﺑﻪ وﺳﻴﻠﻪ ﻛﻼﺳﻬﺎي داﺧﻞ ﻫﻤﺎن اﺳﻤﺒﻠﻲ ﻗﺎﺑﻞ اﺳﺘﻔﺎده اﺳﺖ‪.‬‬

‫‪(3‬‬

‫‪(4‬‬ ‫‪(5‬‬

‫‪(6‬‬

‫‪ :Family or Assembly‬ﻣﺘﺪ ﻣﻮرد ﻧﻈﺮ ﺑﻪ وﺳﻴﻠﻪ ﺗﻤﺎم ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ از اﻳـﻦ ﻛـﻼس ﻣـﺸﺘﻖ ﻣـﻲ‬ ‫ﺷﻮﻧﺪ‪ ،‬در ﻫﻤﻪ اﺳﻤﺒﻠﻲ ﻫﺎ‪ ،‬ﻗﺎﺑﻞ اﺳﺘﻔﺎده اﺳﺖ‪ .‬ﻋﻼوه ﺑﺮ اﻳـﻦ‪ ،‬اﻳـﻦ ﻣﺘـﺪ در ﻫﻤـﻪ ﻛﻼﺳـﻬﺎي آن اﺳـﻤﺒﻠﻲ ﻧﻴـﺰ ﻗﺎﺑـﻞ‬ ‫دﺳﺘﺮﺳﻲ اﺳﺖ‪.‬‬ ‫‪ :Public‬ﻣﺘﺪ ﻣﻮرد ﻧﻈﺮ د ﻫﻤﻪ ﻛﻼﺳﻬﺎ ﺻﺮف ﻧﻈﺮ از اﻳﻨﻜﻪ در ﭼﻪ اﺳﻤﺒﻠﻲ ﻗﺮار دارد‪ ،‬ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ اﺳﺖ‪.‬‬

‫‪Common Type System‬‬ ‫‪Properties‬‬

‫‪1‬‬ ‫‪2‬‬

‫‪٩٣٢‬‬

‫ﻋﻼوه ﺑﺮ اﻳﻦ‪ CTS ،‬ﻗﻮاﻋﺪي را ﺑﺮاي وراﺛﺖ‪ ،‬ﻃﻮل ﻋﻤﺮ اﺷﻴﺎ‪ ،‬ﺗﻮاﺑﻊ ﻣﺠﺎزي و ﻏﻴﺮه ﻧﻴﺰ ﺑﻴﺎن ﻣﻲ ﻛﻨﺪ‪.‬‬

‫ﺧﺼﻮﺻﻴﺎت ﻋﻤﻮﻣﻲ زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ‪:‬‬ ‫ﻳﻜﻲ از اﻣﻜﺎﻧﺎﺗﻲ ﻛﻪ ﻫﻤﺮاه ﺑﺎ ‪ COM‬ﻋﺮﺿﻪ ﺷﺪ‪ ،‬اﺳﺘﻔﺎده از ﻛﺪ ﻫﺎي ﻧﻮﺷﺘﻪ ﺷﺪه در ﻳﻚ زﺑﺎن ﺑـﻪ وﺳـﻴﻠﻪ زﺑـﺎﻧﻲ دﻳﮕـﺮ ﺑـﻮد‪ .‬اﻳـﻦ‬ ‫اﻣﻜﺎن ﺑﻪ وﺳﻴﻠﻪ ي ‪ CLR‬ﻧﻴﺰ ﺑﻪ ﻧﺤﻮي ﺑﺴﻴﺎر ﻛﺎﻣﻞ ﺗﺮ اراﺋﻪ ﺷﺪه اﺳﺖ‪ .‬از ﺳﻮي دﻳﮕﺮ‪ CLR ،‬ﺑﺎ ﻳﻜﻲ ﻛـﺮدن ﺗﻤـﺎم زﺑﺎﻧﻬـﺎ اﻳـﻦ‬ ‫اﻣﻜﺎن را ﻣﻲ دﻫﺪ ﻛﻪ اﺷﻴﺎي ﺗﻮﻟﻴﺪ ﺷﺪه در ﻳﻚ زﺑﺎن در زﺑﺎﻧﻬﺎي دﻳﮕﺮ ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﺑﺎﺷﺪ‪ .‬اﻳﻦ ﻗﺎﺑﻠﻴﺖ ﺑـﺎ ﺗﻮﺟـﻪ ﺑـﻪ ﻧـﻮع داده اي‬ ‫ﻋﻤﻮﻣﻲ ﻣﺸﺘﺮك ﺑﻴﻦ ﻫﻤﻪ ي زﺑﺎﻧﻬﺎ‪ ،‬اﺳﺘﻔﺎده از ‪metadata‬ﻫﺎ ﺑﺮاي ﺷﺮح اﻃﻼﻋﺎت ﻛﻼس و ﻣﺤﻴﻂ اﺟﺮاي ﻋﻤﻮﻣﻲ ﺑﻪ وﺟﻮد‬ ‫آﻣﺪه اﺳﺖ‪.‬‬ ‫ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ اﻳﻨﻜﻪ زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﻣﻜﺎﻧﺎت ﻛﺎﻣﻼ ﻣﺘﻔﺎوﺗﻲ را ﻋﺮﺿﻪ ﻣﻲ ﻛﻨﻨﺪ‪ ،‬اﻳﻦ ﻗﺎﺑﻠﻴﺖ ﺑﺴﻴﺎر ﺷﮕﻔﺖ اﻧﮕﻴﺰ ﺑـﻪ ﻧﻈـﺮ ﻣـﻲ‬ ‫رﺳﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل ﺑﻌﻀﻲ از زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺣﺴﺎس ﺑﻪ ﺑﺰرﮔﻲ و ﻛﻮﭼﻜﻲ ﺣﺮوف ﻫﺴﺘﻨﺪ‪ ،‬ﺑﻌﻀﻲ ﺳﺮﺑﺎر ﮔـﺬاري ﻋﻤﻠﮕـﺮ ﻫـﺎ را‬ ‫ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ ﻛﻨﻨﺪ و ﻳﺎ ﺑﻌﻀﻲ اﻳﻦ اﻣﻜﺎن را ﻣﻲ دﻫﻨﺪ ﺗﺎ ﻣﺘﺪﻫﺎي ﺑﺎ ﺗﻌﺪاد ﭘﺎراﻣﺘﺮﻫﺎي ﻧﺎﻣﺤﺪود اﻳﺠﺎد ﻛﻨﻴﻢ‪.‬‬ ‫اﮔﺮ در اﻳﺠﺎد ﻳﻚ ﺑﺮﻧﺎﻣﻪ از اﻣﻜﺎﻧﺎت ﺧﺎﺻﻲ ﻳﻚ زﺑﺎن اﺳﺘﻔﺎده ﻛﻨﻴﻢ‪ ،‬اﺳﺘﻔﺎده از آن ﺑﺮﻧﺎﻣﻪ در ﺑﺮﻧﺎﻣﻪ ﻫﺎي دﻳﮕﺮ ﺑﺴﻴﺎر ﻣﺸﻜﻞ ﺧﻮاﻫﺪ‬ ‫ﺑﻮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺑﺮاي ﻃﺮاﺣﻲ ﻛﻼس ﻫﺎﻳﻲ ﻛﻪ ﺑﻪ راﺣﺘﻲ در ﺗﻤﺎم زﺑﺎﻧﻬﺎي دﻳﮕﺮ ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﺑﺎﺷـﻨﺪ ﺑﺎﻳـﺴﺘﻲ از اﻣﻜﺎﻧـﺎﺗﻲ در ﺑﺮﻧﺎﻣـﻪ‬ ‫اﺳﺘﻔﺎده ﻛﺮد ﻛﻪ ﺗﻀﻤﻴﻦ ﺑﺸﻮد در ﻫﻤﻪ زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ دﻳﮕﺮ وﺟﻮد دارﻧﺪ‪ .‬ﺑﺮاي ﻣﺸﺨﺺ ﺗﺮ ﻛﺮدن اﻳﻦ اﻣﻜﺎﻧﺎت ﻛﻪ در ﺑـﻴﻦ‬ ‫ﻫﻤﻪ ي زﺑﺎﻧﻬﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺸﺘﺮك اﺳﺖ‪ ،‬ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﻳﻚ ﻣﺠﻤﻮﻋﻪ از ﺧﺼﻮﺻﻴﺎت ﻋﻤﻮﻣﻲ را ﻣﻌﻴﻦ ﻛﺮده ﻛـﻪ ‪ 1CLS‬ﻧـﺎم‬ ‫دارد‪.‬‬ ‫ﻣﺠﻤﻮﻋﻪ ي ‪ CLR‬و ‪ ،CTS‬اﻣﻜﺎﻧﺎﺗﻲ ﺑﺴﻴﺎر ﺑﻴﺸﺘﺮ از آﻧﭽﻪ ‪ CLS‬ﺗﻌﻴﻴﻦ ﻛﺮده اﺳﺖ را اراﺋﻪ ﻣﻲ دﻫﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﻛﻼس ﺗﺤﺖ‬ ‫ﻃﺮاﺣﻲ ﻧﺒﺎﻳﺪ در زﺑﺎﻧﻬﺎي دﻳﮕﺮ اﺳﺘﻔﺎده ﺷﻮد ﻣﻲ ﺗﻮان از ﺗﻤﺎم اﻣﻜﺎﻧﺎت ‪ CTS‬و ‪ CLR‬اﺳﺘﻔﺎده ﻛﺮد‪ .‬ﺷﻜﻞ زﻳﺮ ﺳﻌﻲ ﻣﻔﻬـﻮم ذﻛـﺮ‬ ‫ﺷﺪه را ﺑﻴﺎن ﻣﻲ ﻛﻨﺪ‪.‬‬

‫ﺗﻤﺎم زﺑﺎﻧﻬﺎ زﻳﺮ ﻣﺠﻤﻮﻋﻪ اي از ﺗﻮاﻧﺎﻳﻴﻬﺎي ‪ CLR‬و ﺗﻤﺎم اﻣﻜﺎﻧﺎت ‪ CLS‬را اراﻳﻪ ﻣﻲ دﻫﻨﺪ‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ ﻣﺸﺨﺺ اﺳﺖ ﻫﻴﭻ زﺑﺎﻧﻲ ﺗﻤﺎﻣﻲ اﻣﻜﺎﻧﺎت ‪ CLR‬را اراﺋﻪ ﻧﻤﻲ ﻛﻨـﺪ‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ ﺑـﺮاي اﺳـﺘﻔﺎده از ﺗﻤـﺎم اﻳـﻦ‬ ‫اﻣﻜﺎﻧـﺎت ﺑﺎﻳـﺴﺘﻲ از زﺑـﺎن ‪ IL‬ﻛﻤـﻚ ﮔﺮﻓـﺖ‪ .‬ﺑـﻪ ﺟـﺰ زﺑـﺎن ‪ ،IL‬دﻳﮕـﺮ زﺑﺎﻧﻬـﺎ از ﻗﺒﻴـﻞ ‪،Visual Basic ،C#‬‬ ‫‪ Fortran‬و ﻏﻴﺮه ﻓﻘﻂ ﻗﺴﻤﺘﻲ از اﻣﻜﺎﻧﺎت ‪ CLR‬و ‪ CTS‬را اراﻳﻪ ﻣﻲ دﻫﻨﺪ‪.‬‬ ‫‪Common Language Specifications‬‬

‫‪1‬‬

‫‪٩٣٣‬‬

‫اﮔﺮ ﻛﻼﺳﻲ ﺑﻪ ﻣﻨﻈﻮر اﺳﺘﻔﺎده در دﻳﮕﺮ زﺑﺎﻧﻬﺎ ﻃﺮاﺣﻲ ﻣﻲ ﺷﻮد‪ ،‬ﺑﺎﻳﺴﺘﻲ اﻳﻦ ﻧﻜﺘﻪ را ﻣﺪ ﻧﻈـﺮ ﻗـﺮار داد ﻛـﻪ در آن ﻛـﻼس ﻧﺒﺎﻳـﺪ از‬ ‫اﻣﻜﺎﻧﺎﺗﻲ ﻛﻪ ﺧﺎرج از ﻣﺤﺪوده ‪ CLS‬ﻫﺴﺘﻨﺪ اﺳﺘﻔﺎده ﻛﺮد‪ .‬در ﻏﻴﺮ اﻳﻦ ﺻﻮرت آن ﻗﺴﻤﺖ از ﺑﺮﻧﺎﻣﻪ در زﺑﺎﻧﻬﺎي دﻳﮕـﺮ ﻛـﻪ وﻳﮋﮔـﻲ‬ ‫ﻣﻮرد اﺳﺘﻔﺎده را ﭘﺸﺘﻴﺒﺎﻧﻲ ﻧﻤﻲ ﻛﻨﻨﺪ ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﻧﺨﻮاﻫﺪ ﺑﻮد‪.‬‬ ‫ﺑﺮاي ﻣﺜﺎل در ﻛﺪ زﻳﺮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﺑﺎ اﺳﺘﻔﺎده از ﺧﺼﻴﺼﻪ ي ‪ ،CLSCompliant‬ﺑﻪ ﺻﻮرت ﺳﺎزﮔﺎر ﺑﺎ ‪ CLS‬ﺗﻌﺮﻳـﻒ ﺷـﺪه‬ ‫اﺳﺖ‪ .‬اﻣﺎ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﺸﺨﺺ اﺳﺖ‪ ،‬ﺗﻌﺪادي از وﻳﮋﮔﻲ ﻫﺎي ﺑﻪ ﻛﺎر رﻓﺘﻪ در آن ﻗﻮاﻋﺪ ‪ CLS‬را ﻧﻘﺾ ﻣﻴﻜﻨﻨﺪ‪ .‬اﻳﻦ ﻣـﻮارد ﺑﺎﻋـﺚ‬ ‫ﻣﻲ ﺷﻮﻧﺪ ﻛﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ ﻛﺪ ﺑﺎ ﺧﻄﺎ روﺑﺮو ﺷﻮد‪.‬‬ ‫‪// Tell the compiler for check the CLS compliance‬‬ ‫])‪[CLSCompliant(true‬‬ ‫‪// Errors appear because the class is public‬‬ ‫‪public class App‬‬ ‫{‬ ‫‪// Error: Return type of 'App.Abc' is not CLS-Compliant‬‬ ‫)(‪public UInt32 Abc‬‬ ‫{‬ ‫;‪return 0‬‬ ‫}‬ ‫‪// Error: Identifier 'App.abc' differing only in case is not‬‬ ‫‪// CLS-Compliant‬‬ ‫)(‪public void abc‬‬ ‫} {‬ ‫‪// No error: method is private‬‬ ‫)(‪private UInt32 ABC‬‬ ‫{‬ ‫;‪return 0‬‬ ‫}‬ ‫}‬

‫در اﻳﻦ ﻛﻼس‪ ،‬ﻋﺒﺎرت])‪ [CLSCompliant(true‬ﺑﺎﻋﺚ ﻣﻲ ﺷﻮد ﻛﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ﻛﺪ ﻫﺎﻳﻲ از ﺑﺮﻧﺎﻣﻪ ﻛﻪ ﺑﻪ ﺻـﻮرت‬ ‫‪ public‬ﻫﺴﺘﻨﺪ را ﺑﺮاي ﻫﻤﺎﻫﻨﮓ ﺑﻮدن ﺑﺎ ‪ CLS‬ﺑﺮرﺳﻲ ﻛﻨﺪ‪ .‬ﻫﻨﮕﺎم ﻛﺎﻣﭙﺎﻳﻞ اﻳﻦ ﻛﺪ‪ ،‬ﻛﺎﻣﭙﺎﻳﻠﺮ در دو ﻗﺴﻤﺖ ﺑﺮﻧﺎﻣﻪ ﺑﺎ ﺧﻄـﺎ‬ ‫ﻣﻮاﺟﻪ ﻣﻲ ﺷﻮد‪ .‬ﺧﻄﺎي اول ﺑﻪ ﻋﻠﺖ ﻧﻮع داده ﺑﺎزﮔﺸﺘﻲ ﺗﺎﺑﻊ ‪ Abc‬اﺳﺖ ﻛﻪ در ﺑﻌﻀﻲ از زﺑﺎﻧﻬﺎ ﻣﺎﻧﻨـﺪ ‪Visual Basic‬‬ ‫ﭘﺸﺘﻴﺒﺎﻧﻲ ﻧﻤﻲ ﺷﻮد‪ .‬ﺧﻄﺎي دوم ﻧﻴﺰ ﻣﺮﺑﻮط ﺑﻪ ﻫﻢ ﻧﺎم ﺑﻮدن ﺗﻮاﺑﻊ ‪ Abc‬و ‪ abc‬اﺳﺖ‪ .‬اﻳـﻦ ﺗﻮاﺑـﻊ ﻓﻘـﻂ در ﺣـﺴﺎس ﺑـﻮدن ﺑـﻪ‬ ‫ﺣﺮوف ﺗﻔﺎوت دارﻧﺪ ﻛﻪ ﺗﻤﺎم زﺑﺎﻧﻬﺎ ﺑﻪ اﻧﺪازه ﺣﺮوف ﺣﺴﺎس ﻧﻴﺴﺘﻨﺪ‪.‬‬ ‫اﻟﺒﺘﻪ ﺗﻤﺎم اﻳﻦ ﺧﻄﺎﻫﺎ ﺑﻪ اﻳﻦ ﻋﻠﺖ اﻳﺠﺎد ﻣﻲ ﺷﻮد ﻛﻪ ﺳﻄﺢ دﺳﺘﺮﺳﻲ ﻛﻼس از ﻧﻮع ﻋﻤﻮﻣﻲ اﺳﺖ‪ .‬اﮔﺮ ﺳﻄﺢ دﺳﺘﺮﺳـﻲ ﻛـﻼس و‬ ‫ﻳﺎ ﻫﺮ ﻛﺪام از ﺗﻮاﺑﻊ از ‪ public‬ﺑﻪ ‪ private‬ﺗﻐﻴﻴﺮ ﻛﻨﺪ ﺧﻄﺎي ﻣﺮﺑﻮط ﺑﻪ آن ﻧﻴﺰ از ﺑﻴﻦ ﺧﻮاﻫﺪ رﻓﺖ‪.‬‬

‫‪٩٣٤‬‬

‫ﺿﻤﻴﻤﻪ ‪ :4‬ﻣﺪﻳﺮﻳﺖ ﺣﺎﻓﻈﻪ در ‪.NET‬‬ ‫در ﺑﺨﺶ ﻗﺒﻠﻲ‪ CLR ،‬ﻛﻪ ﺑﻪ ﻋﻨﻮان ﻫﺴﺘﻪ اﺻﻠﻲ ‪ .NET Framework‬در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻴﺸﻮد‪ ،‬ﺑﺮرﺳﻲ ﺷﺪ‪ .‬ﺑﻪ ﻋﻨﻮان دو‬ ‫وﻳﮋﮔﻲ ﻣﻬﻢ ‪ ،CLR‬ﻣﻴﺘﻮان از ﺗﻮاﻧﺎﻳﻲ ﺑﺮﻗﺮاري ارﺗﺒﺎط آن ﺑﻴﻦ زﺑﺎﻧﻬﺎي ﻣﺨﺘﻠﻒ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ و ﻧﻴﺰ ﻣﺪﻳﺮﻳﺖ ﺣﺎﻓﻈﻪ ﻗﻮي آن ﻳﺎد ﻛﺮد‪.‬‬ ‫در ﺗﻮﺿﻴﺢ وﻳﮋﮔﻲ اول‪ ،‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﻗﺴﻤﺖ ﻗﺒﻠﻲ ذﻛﺮ ﺷﺪ‪ CLR ،‬ﺑﺎ اﺳﺘﻔﺎده از ﻳﻚ ﺳﺮي ﺧﺼﻮﺻﻴﺎت ﻋﻤﻮﻣﻲ ﻛﻪ ﺑﻪ وﺳﻴﻠﻪ ﺗﻤﺎم‬ ‫زﺑﺎﻧﻬﺎ ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻴﺸﻮد)‪ ،(CLS‬اﻣﻜﺎن اﺳﺘﻔﺎده از ﻛﻼس ﻧﻮﺷﺘﻪ ﺷﺪه در ﻳﻚ زﺑﺎن را‪ ،‬در زﺑﺎﻧﻬﺎي دﻳﮕﺮ ﻓﺮاﻫﻢ ﻣﻴﻜﻨﺪ‪.‬‬ ‫وﻳﮋﮔﻲ ﻣﻬﻢ دﻳﮕﺮ ‪ CLR‬ﻛﻪ ﻣﻮﺟﺐ اﻓﺰاﻳﺶ ﻛﺎراﻳﻲ ﺑﺮﻧﺎﻣﻪ در آن ﻣﻴﺸﻮد‪ ،‬ﻣﺪﻳﺮﻳﺖ ﺣﺎﻓﻈﻪ آن اﺳﺖ‪ .‬اﻳﻦ ﺑﺨﺶ در ‪ CLR‬ﺑﺮ ﻋﻬﺪه‬ ‫‪ Garbage Collector‬اﺳﺖ ﻛﻪ ﺑﻪ ﻋﻠﺖ اﻫﻤﻴﺖ اﻳﻦ ﻣﻮﺿﻮع در اﻳﻦ ﻗﺴﻤﺖ ﻛﺎﻣﻼ ﺗﻮﺿﻴﺢ داده ﻣﻴﺸﻮد‪.‬‬

‫درك ﻣﺒﺎﻧﻲ ﻛﺎر ‪:Garbage Collector‬‬ ‫ﻫﺮ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻧﺤﻮي از ﻣﻨﺎﺑﻊ ﻣﺸﺨﺼﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ‪ .‬اﻳﻦ ﻣﻨﺎﺑﻊ ﻣﻲ ﺗﻮاﻧﻨﺪ ﻓﺎﻳﻠﻬﺎ‪ ،‬ﺑﺎﻓﺮ ﻫﺎي ﺣﺎﻓﻈﻪ‪ ،‬ﻓﻀﺎ ﻫﺎي ﺻﻔﺤﻪ ﻧﻤﺎﻳﺶ‪،‬‬ ‫ارﺗﺒﺎﻃﺎت ﺷﺒﻜﻪ اي‪ ،‬ﻣﻨﺎﺑﻊ ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ و ﻣﺎﻧﻨﺪ اﻳﻨﻬﺎ ﺑﺎﺷﻨﺪ‪ .‬در ﺣﻘﻴﻘﺖ در ﻳﻚ ﻣﺤﻴﻂ ﺷﻴﺊ ﮔﺮا ﻫﺮ ﻧﻮع داده ﺗﻌﺮﻳﻒ ﺷﺪه در ﺑﺮﻧﺎﻣﻪ‬ ‫ﺑﻌﻀﻲ از ﻣﻨﺎﺑﻊ ﻣﻮﺟﻮد ﺑﺮاي ﺑﺮﻧﺎﻣﻪ را اراﺋﻪ ﻣﻲ دﻫﺪ‪ .‬ﺑﺮاي اﺳﺘﻔﺎده از ﻫﺮ ﻧﻮع از اﻳﻦ داده ﻫﺎ ﻻزم اﺳﺖ ﻛﻪ ﺑﺮاي اراﺋﻪ آن ﻧﻮع ﻣﻘﺪاري‬ ‫ﺣﺎﻓﻈﻪ ﺗﺨﺼﻴﺺ داده ﺷﻮد‪ .‬ﻣﻮارد زﻳﺮ ﺑﺮاي دﺳﺘﺮﺳﻲ ﺑﻪ ﻳﻚ ﻣﻨﺒﻊ ﻣﻮرد ﻧﻴﺎز اﺳﺖ‪:‬‬ ‫‪(1‬‬

‫‪(2‬‬ ‫‪(3‬‬ ‫‪(4‬‬ ‫‪(5‬‬

‫ﺗﺨﺼﻴﺺ ﺣﺎﻓﻈﻪ ﺑﺮاي ﻧﻮع داده اي ﻛﻪ ﻣﻨﺒﻊ ﻣﻮرد ﻧﻈﺮ را اراﺋﻪ ﻣﻲ دﻫﺪ‪ .‬اﻳﻦ ﺗﺨﺼﻴﺺ ﺣﺎﻓﻈﻪ ﺑﺎ اﺳﺘﻔﺎده از دﺳﺘﻮر‬ ‫‪ newobj‬در زﺑﺎن ‪ IL1‬ﺻﻮرت ﻣﻲ ﮔﻴﺮد ﻛﻪ اﻳﻦ دﺳﺘﻮر از ﺗﺮﺟﻤﻪ دﺳﺘﻮر ‪ new‬در زﺑﺎن ﻫﺎﻳﻲ ﻣﺜﻞ ‪ C#‬و‬ ‫‪ Visual Basic‬و دﻳﮕﺮ زﺑﺎن ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ اﻳﺠﺎد ﻣﻲ ﺷﻮد‪.‬‬ ‫ﻣﻘﺪار دﻫﻲ اوﻟﻴﻪ ﺣﺎﻓﻈﻪ ﺑﺮاي ﺗﻨﻈﻴﻢ ﺣﺎﻟﺖ آﻏﺎزﻳﻦ‪ 2‬ﻣﻨﺎﺑﻊ و ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﻛﺮدن آن‪ .‬ﺗﻮاﺑﻊ ‪ Constructor‬در اﻳﻦ‬ ‫ﻧﻮع داده ﻫﺎ ﻣﺴﺌﻮل اﻳﻦ ﺗﻨﻈﻴﻤﺎت ﺑﺮاي اﻳﺠﺎد اﻳﻦ ﺣﺎﻟﺖ آﻏﺎزﻳﻦ ﻫﺴﺘﻨﺪ‪.‬‬ ‫اﺳﺘﻔﺎده از ﻣﻨﺎﺑﻊ ﺑﺎ دﺳﺘﺮﺳﻲ ﺑﻪ اﻋﻀﺎي ﻣﻮﺟﻮد در ﻧﻮع داده‪.‬‬ ‫از ﺑﻴﻦ ﺑﺮدن ﺣﺎﻟﺖ ﻛﻠﻲ ﻣﻨﺎﺑﻊ ﺑﺮاي ﭘﺎك ﻛﺮدن آن‪.‬‬ ‫آزاد ﺳﺎزي ﺣﺎﻓﻈﻪ‪ Garbage Collector .‬ﻣﺴﺌﻮل ﻣﻄﻠﻖ اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﻪ ﺷﻤﺎر ﻣﻲ رود‪.‬‬

‫اﻳﻦ ﻧﻤﻮﻧﻪ ﺑﻪ ﻇﺎﻫﺮ ﺳﺎده ﻳﻜﻲ از رﻳﺸﻪ ﻫﺎي اﺻﻠﻲ ﺧﻄﺎﻫﺎي اﻳﺠﺎد ﺷﺪه در ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﻪ ﺷﻤﺎر ﻣﻲ رود‪ .‬ﻣﻮاﻗﻊ زﻳﺎدي ﭘﻴﺶ ﻣﻲ آﻳﺪ‬ ‫ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ آزادﺳﺎزي ﻳﻚ ﺣﺎﻓﻈﻪ را وﻗﺘﻲ دﻳﮕﺮ ﻣﻮرد ﻧﻴﺎز ﻧﻴﺴﺖ ﻓﺮاﻣﻮش ﻣﻲ ﻛﻨﺪ‪ .‬ﻣﻮاﻗﻊ زﻳﺎدي ﭘﻴﺶ ﻣﻲ آﻳﺪ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ از‬ ‫ﻳﻚ ﺣﺎﻓﻈﻪ ﻛﻪ ﻗﺒﻼ آزاد ﺷﺪه اﺳﺘﻔﺎده ﻛﻨﺪ‪.‬‬ ‫اﻳﻦ دو ﺑﺎگ ﺑﺮﻧﺎﻣﻪ ﻫﺎ از اﻛﺜﺮ آﻧﻬﺎ ﺑﺪﺗﺮ اﻧﺪ زﻳﺮا ﻣﻌﻤﻮﻻ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻧﻤﻴﺘﻮاﻧﺪ ﺗﺮﺗﻴﺐ ﻳﺎ زﻣﺎن ﺑﻪ وﺟﻮد آﻣﺪن اﻳﻦ ﺧﻄﺎﻫﺎ را ﭘﻴﺶ ﺑﻴﻨﻲ‬ ‫ﻛﻨﺪ‪ .‬ﺑﺮاي دﻳﮕﺮ ﺑﺎگ ﻫﺎ ﺷﻤﺎ ﻣﻴﺘﻮاﻧﻴﺪ ﺑﺎ ﻣﺸﺎﻫﺪه رﻓﺘﺎر اﺷﺘﺒﺎه ﻳﻚ ﺑﺮﻧﺎﻣﻪ آن را ﺑﻪ ﺳﺎدﮔﻲ ﺗﺼﺤﻴﺢ ﻛﻨﻴﺪ‪ .‬اﻣﺎ اﻳﻦ دو ﺑﺎگ ﻣﻮﺟﺐ ﻧﺸﺖ‬ ‫ﻣﻨﺎﺑﻊ‪) 3‬ﻣﺼﺮف ﺑﻲ ﺟﺎي ﺣﺎﻓﻈﻪ( و از ﺑﻴﻦ رﻓﺘﻦ ﭘﺎﻳﺪاري اﺷﻴﺎ ﻣﻴﺸﻮﻧﺪ ﻛﻪ ﻛﺎراﻳﻲ ﺑﺮﻧﺎﻣﻪ را در زﻣﺎﻧﻬﺎي ﻣﺨﺘﻠﻒ ﺗﻐﻴﻴﺮ ﻣﻴﺪﻫﺪ‪ .‬ﺑﺮاي ﻛﻤﻚ‬ ‫ﺑﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﺑﺮاي ﺗﺸﺨﻴﺺ اﻳﻦ ﻧﻮع ﺧﻄﺎﻫﺎ اﺑﺰارﻫﺎي وﻳﮋه اي ﻣﺎﻧﻨﺪ ‪ Windows Task Manager‬و‬ ‫‪ System Monitor ActiveX Control‬و ‪ NuMega Bounds Checker‬و ‪ ...‬ﻃﺮاﺣﻲ‬ ‫ﺷﺪه اﻧﺪ‪.‬‬ ‫‪1‬‬

‫‪Intermediate Language‬‬ ‫‪Initial State‬‬ ‫‪3‬‬ ‫‪Resource leaks‬‬ ‫‪2‬‬

‫‪٩٣٥‬‬

‫ﻳﻚ ﻣﺪﻳﺮﻳﺖ ﻣﻨﺒﻊ ﻣﻨﺎﺳﺐ ﺑﺴﻴﺎر ﻣﺸﻜﻞ و ﺧﺴﺘﻪ ﻛﻨﻨﺪه اﺳﺖ‪ .‬اﻳﻦ ﻣﻮرد ﺗﻤﺮﻛﺰ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ را ﺑﺮ روي ﻣﻄﻠﺐ اﺻﻠﻲ از ﺑﻴﻦ ﻣﻴﺒﺮد‪ .‬ﺑﻪ‬ ‫ﻫﻤﻴﻦ دﻟﻴﻞ ﻧﻴﺎز ﺑﻪ ﻳﻚ ﻣﻜﺎﻧﻴﺴﻢ ﻛﻪ ﻣﺪﻳﺮﻳﺖ ﺣﺎﻓﻈﻪ را ﺑﻪ ﺑﻬﺘﺮﻳﻦ ﻧﺤﻮ اﻧﺠﺎم دﻫﺪ در اﻳﻦ زﻣﻴﻨﻪ ﺑﻪ وﺿﻮح اﺣﺴﺎس ﻣﻴﺸﺪ‪ .‬در ﭘﻠﺖ ﻓﺮم‬ ‫‪ .NET‬اﻳﻦ اﻣﺮ ﺗﻮﺳﻂ ‪ Garbage Collector‬اﻧﺠﺎم ﻣﻴﺸﻮد‪.‬‬ ‫‪ Garbage Collection‬ﻛﺎﻣﻼ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ را از ﻛﻨﺘﺮل اﺳﺘﻔﺎده از ﺣﺎﻓﻈﻪ و ﺑﺮرﺳﻲ زﻣﺎن آزادﺳﺎزي آن راﺣﺖ ﻣﻴﻜﻨﺪ‪.‬‬ ‫اﮔﺮﭼﻪ ‪ Garbage Collector‬درﻣﻮرد ﻣﻨﺎﺑﻊ اراﺋﻪ ﺷﺪه ﺗﻮﺳﻂ ﻧﻮع داده در ﺣﺎﻓﻈﻪ ﻫﻴﭻ ﭼﻴﺰ ﻧﻤﻴﺪاﻧﺪ‪ ،‬ﻳﻌﻨﻲ‬ ‫‪ Garbage Collector‬ﻧﻤﻴﺪاﻧﺪ ﭼﻪ ﻃﻮر ﻣﻴﺘﻮاﻧﺪ ﻣﺮﺣﻠﻪ ‪ 4‬از ﻣﻮارد ﺑﺎﻻ را اﻧﺠﺎم دﻫﺪ‪ :‬از ﺑﻴﻦ ﺑﺮدن ﺣﺎﻟﺖ ﻛﻠﻲ ﻣﻨﺎﺑﻊ ﺑﺮاي‬ ‫ﭘﺎك ﻛﺮدن آن‪ .‬ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﺑﺎﻳﺪ ﻛﺪ ﻫﺎي ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ ﻗﺴﻤﺖ را اﻧﺠﺎم دﻫﺪ ﭼﻮن او ﻣﻴﺪاﻧﺪ ﺑﺎﻳﺪ ﭼﻪ ﮔﻮﻧﻪ ﺣﺎﻓﻈﻪ را ﺑﻪ درﺳﺘﻲ و‬ ‫ﻛﺎﻣﻼ آزاد ﻛﻨﺪ‪ .‬اﻟﺒﺘﻪ ‪ Garbage Collector‬ﻣﻴﺘﻮاﻧﺪ در اﻳﻦ زﻣﻴﻨﻪ ﻧﻴﺰ ﻗﺴﻤﺘﻬﺎﻳﻲ از ﻛﺎر را ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ اﻧﺠﺎم دﻫﺪ‪.‬‬ ‫اﻟﺒﺘﻪ‪ ،‬ﺑﻴﺸﺘﺮ ﻧﻮع داده ﻫﺎ‪ ،‬ﻣﺎﻧﻨﺪ‪ ArrayList، String ، Rectangle ، Point ، Int32‬و‬ ‫‪ SerializationInfo‬از ﻣﻨﺎﺑﻌﻲ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ اﺣﺘﻴﺎﺟﻲ ﺑﻪ ﻧﻮع وﻳﮋه اي از آزادﺳﺎزي ﺣﺎﻓﻈﻪ ﻧﺪارﻧﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل‬ ‫ﻣﻨﺎﺑﻊ ﻳﻚ ﺷﻴﺊ از ﻧﻮع ‪ Point‬ﺑﻪ راﺣﺘﻲ و ﺑﺎ ﻧﺎﺑﻮد ﻛﺮدن ﻓﻴﻠﺪ ﻫﺎي ‪ X‬و ‪ Y‬در ﺣﺎﻓﻈﻪ ﺷﻴﺊ آزاد ﻣﻴﺸﻮد‪.‬‬ ‫از ﻃﺮف دﻳﮕﺮ‪ ،‬ﻳﻚ ﻧﻮع داده ﻛﻪ ﻣﻨﺎﺑﻊ ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه اي را اراﺋﻪ ﻣﻴﺪﻫﺪ‪ ،‬ﻣﺎﻧﻨﺪ ﻳﻚ ﻓﺎﻳﻞ‪ ،‬ﻳﻚ ارﺗﺒﺎط ﺑﺎﻧﻚ اﻃﻼﻋﺎﺗﻲ‪ ،‬ﻳﻚ ﺳﻮﻛﺖ‪ ،‬ﻳﻚ‬ ‫‪ ،Bitmap‬ﻳﻚ آﻳﻜﻮن و ﻣﺎﻧﻨﺪ اﻳﻨﻬﺎ ﻫﻤﻴﺸﻪ ﺑﻪ اﺟﺮاي ﻣﻘﺪاري ﻛﺪ وﻳﮋه ﺑﺮاي آزاد ﻛﺮدن ﺣﺎﻓﻈﻪ ﮔﺮﻓﺘﻪ ﺷﺪه ﻧﻴﺎز دارﻧﺪ‪.‬‬ ‫‪ CLR1‬ﻧﻴﺎز دارد ﻛﻪ ﺣﺎﻓﻈﻪ ﺗﻤﺎم ﻣﻨﺎﺑﻊ از ﻳﻚ ‪ heap‬ﻣﺨﺼﻮص ﻛﻪ ‪ managed heap‬ﻧﺎﻣﻴﺪه ﻣﻴﺸﻮد ﺗﺨﺼﻴﺺ داده ﺷﻮد‪.‬‬ ‫اﻳﻦ ‪ heap‬ﺷﺒﻴﻪ ‪ heap‬زﻣﺎن اﺟﺮاي ‪ C‬اﺳﺖ و ﻓﻘﻂ از ﻳﻚ ﻟﺤﺎظ ﻣﺘﻔﺎوت اﺳﺖ و آن اﻳﻦ اﺳﺖ ﻛﻪ در اﻳﻦ ‪ heap‬ﺷﻤﺎ ﻫﻴﭻ‬ ‫وﻗﺖ ﺣﺎﻓﻈﻪ ﺗﺨﺼﻴﺺ داده ﺷﺪه را آزاد ﻧﻤﻴﻜﻨﻴﺪ‪ .‬در ﺣﻘﻴﻘﺖ اﺷﻴﺎ ﻣﻮﺟﻮد در اﻳﻦ ‪ heap‬وﻗﺘﻲ دﻳﮕﺮ ﻧﻴﺎزي ﺑﻪ آﻧﻬﺎ ﻧﺒﺎﺷﺪ آزاد ﻣﻴﺸﻮﻧﺪ‪.‬‬ ‫اﻳﻦ ﻣﻮرد اﻳﻦ ﺳﻮال را اﻳﺠﺎد ﻣﻴﻜﻨﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ‪ managed heap‬ﻣﺘﻮﺟﻪ ﻣﻴﺸﻮد ﻛﻪ دﻳﮕﺮ ﻧﻴﺎزي ﺑﻪ ﻳﻚ ﺷﻴﺊ ﺧﺎص ﻧﻴﺴﺖ؟‬ ‫ﭼﻨﺪﻳﻦ اﻟﮕﻮرﻳﺘﻢ از ‪ Garbage Collector‬در ﺣﺎل ﺣﺎﺿﺮ در ﻣﺮﺣﻠﻪ آزﻣﺎﻳﺶ ﻫﺴﺘﻨﺪ و ﻫﺮ ﻛﺪام از اﻳﻦ اﻟﮕﻮرﻳﺘﻢ ﻫﺎ ﺑﺮاي‬ ‫ﻳﻚ ﻣﺤﻴﻂ ﺧﺎص و ﻧﻴﺰ ﺑﺮاي ﻛﺴﺐ ﺑﻬﺘﺮﻳﻦ راﻧﺪﻣﺎن ﺑﻬﻴﻨﻪ ﺳﺎزي ﺷﺪه اﻧﺪ‪ .‬در اﻳﻦ ﻣﻘﺎﻟﻪ روي اﻟﮕﻮرﻳﺘﻢ ‪Garbage‬‬ ‫‪ Collector‬اﺳﺘﻔﺎده ﺷﺪه در ‪ Microsoft .NET Framework CLR‬ﻣﺘﻤﺮﻛﺰ ﺷﺪه اﺳﺖ‪.‬‬ ‫زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﭘﺮوﺳﻪ ﻣﻘﺪار دﻫﻲ اوﻟﻴﻪ‪ 2‬ﻣﻴﺸﻮد‪ CLR ،‬ﻳﻚ ﻗﺴﻤﺖ ﭘﻴﻮﺳﺘﻪ از آدرس ﺣﺎﻓﻈﻪ را ﺑﺮاي آن اﺧﺘﺼﺎص ﻣﻴﺪﻫﺪ اﻳﻦ آدرس‬ ‫ﻓﻀﺎي ﺣﺎﻓﻈﻪ ‪ managed heap‬ﻧﺎﻣﻴﺪه ﻣﻴﺸﻮد‪ .‬اﻳﻦ ‪ heap‬ﻫﻤﭽﻨﻴﻦ ﻳﻚ اﺷﺎره ﮔﺮ ﻣﺨﺼﻮص ﻫﻢ دارد ﻛﻪ ﻣﺎ از اﻳﻦ ﺑﻪ ﺑﻌﺪ‬ ‫آن را ‪ NextObjPtr‬ﻣﻲ ﻧﺎﻣﻴﻢ‪ .‬اﻳﻦ اﺷﺎره ﮔﺮ ﻣﻜﺎن ﻗﺮار ﮔﻴﺮي ﺷﻴﺊ ﺑﻌﺪي را در ‪ heap‬ﻣﺸﺨﺺ ﻣﻴﻜﻨﺪ‪ .‬در اﺑﺘﺪا اﻳﻦ اﺷﺎره‬ ‫ﮔﺮ ﺑﻪ آدرس اﺑﺘﺪاي ﻓﻀﺎي ﮔﺮﻓﺘﻪ ﺷﺪه ﺑﺮاي ‪ managed heap‬اﺷﺎره ﻣﻴﻜﻨﺪ‪.‬‬ ‫دﺳﺘﻮر ‪ newobj‬در زﺑﺎن ‪ IL‬ﺑﺎﻋﺚ اﻳﺠﺎد ﻳﻚ ﺷﻴﺊ ﺟﺪﻳﺪ ﻣﻴﺸﻮد‪ .‬ﺑﻴﺸﺘﺮ زﺑﺎﻧﻬﺎ از ﺟﻤﻠﻪ ‪ C#‬و ‪ Visual Basic‬ﺑﺮاي‬ ‫درج اﻳﻦ دﺳﺘﻮر در ﻛﺪ ‪ IL‬ﻋﻤﻠﮕﺮ ‪ new‬را در ﺑﺮﻧﺎﻣﻪ اراﺋﻪ ﻣﻴﺪﻫﻨﺪ‪ .‬اﻳﻦ دﺳﺘﻮر ‪ IL‬ﺑﺎﻋﺚ ﻣﻴﺸﻮد ﻛﻪ ‪ CLR‬ﻣﺮاﺣﻞ زﻳﺮ را اﻧﺠﺎم دﻫﺪ‪:‬‬ ‫‪ (1‬ﻣﺤﺎﺳﺒﻪ ﺗﻌﺪاد ﺑﺎﻳﺖ ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺮاي اﻳﻦ ﻧﻮع داده‬ ‫‪ (2‬اﺿﺎﻓﻪ ﻛﺮدن ﺑﺎﻳﺖ ﻫﺎي ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ‪ overhead‬ﺷﻴﺊ‪ .‬ﻫﺮ ﺷﻴﺊ دو ﻓﻴﻠﺪ ‪ overhead‬دارد‪ :‬ﻳﻚ اﺷﺎره ﮔﺮ ﺑﻪ‬ ‫ﺟﺪول ﺗﺎﺑﻊ و ﻳﻚ ‪SyncBlockIndex‬ه‪ .‬در ﺳﻴﺴﺘﻤﻬﺎي ‪32‬ﺑﻴﺘﻲ‪ ،‬ﻫﺮ ﻛﺪام از اﻳﻦ ﻓﻴﻠﺪ ﻫﺎ ‪ 32‬ﺑﻴﺖ ﻫﺴﺘﻨﺪ‪ ،‬ﻛﻪ ‪8‬‬ ‫ﺑﺎﻳﺖ را ﺑﻪ ﻫﺮ ﺷﻴﺊ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ‪ .‬در ﺳﻴﺴﺘﻢ ﻫﺎي ‪ 64‬ﺑﻴﺘﻲ‪ ،‬ﻫﺮ ﻛﺪام از اﻳﻦ ﻓﻴﻠﺪ ﻫﺎ ‪ 64‬ﺑﻴﺖ اﺳﺖ ﻛﻪ ‪ 16‬ﺑﺎﻳﺖ را ﺑﺮاي‬ ‫ﻫﺮ ﺷﻴﺊ اﺿﺎﻓﻪ ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫‪ (3‬ﺳﭙﺲ ‪ CLR‬ﭼﻚ ﻣﻴﻜﻨﺪ ﻛﻪ ﺣﺎﻓﻈﻪ ﻣﻮرد ﻧﻴﺎز ﺑﺮاي ﺷﻴﺊ ﺟﺪﻳﺪ در ‪ managed heap‬ﻣﻮﺟﻮد ﺑﺎﺷﺪ‪ .‬اﮔﺮ ﻓﻀﺎي‬ ‫ﻛﺎﻓﻲ ﻣﻮﺟﻮد ﺑﺎﺷﺪ اﻳﻦ ﺷﻴﺊ در آدرﺳﻲ ﻛﻪ ‪ NextObjPtr‬ﺑﻪ آن اﺷﺎره ﻣﻴﻜﻨﺪ اﻳﺠﺎد ﻣﻴﺸﻮد‪ .‬ﺗﺎﺑﻊ‬ ‫‪ constructor‬ﺷﻴﺊ ﻣﺬﻛﻮر ﻓﺮاﺧﻮاﻧﻲ ﻣﻴﺸﻮد )اﺷﺎره ﮔﺮ ‪ NextObjPtr‬ﺑﻪ ﻋﻨﻮان ﭘﺎراﻣﺘﺮ‪ this‬ﺑﻪ‬ ‫‪ constructor‬ﻓﺮﺳﺘﺎده ﻣﻴﺸﻮد( و دﺳﺘﻮر ‪ newobj‬آدرس ﺷﻴﺊ اﻳﺠﺎد ﺷﺪه را ﺑﺮﻣﻴﮕﺮداﻧﺪ‪ .‬درﺳﺖ ﻗﺒﻞ از اﻳﻨﻜﻪ‬ ‫‪Common Language Runtime‬‬ ‫‪Initialize‬‬

‫‪1‬‬ ‫‪2‬‬

‫‪٩٣٦‬‬

‫آدرس ﺑﺮﮔﺮداﻧﺪه ﺷﻮد‪ NextObjPtr ،‬ﺑﻪ ﺑﻌﺪ از ﺷﻴﺊ اﻳﺠﺎد ﺷﺪه ﭘﻴﺸﺮوي ﻣﻴﻜﻨﺪ و ﻣﺜﻞ ﻗﺒﻞ آدرﺳﻲ ﻛﻪ ﺑﺎﻳﺪ ﺷﻴﺊ‬ ‫ﺑﻌﺪي در آن ﻗﺮار ﮔﻴﺮد را در ﺧﻮد ﻧﮕﻪ ﻣﻴﺪارد‪.‬‬ ‫ﺷﻜﻞ زﻳﺮ ﻳﻚ ‪ managed heap‬را ﻛﻪ ﺳﻪ ﺷﻴﺊ ‪ A‬و ‪ B‬و ‪ C‬را درﺧﻮد ﻧﮕﻪ ﻣﻴﺪارد را ﻧﺸﺎن ﻣﻴﺪﻫﺪ‪ .‬اﮔﺮ ﻳﻚ ﺷﻴﺊ ﺟﺪﻳﺪ‬ ‫اﻳﺠﺎد ﺷﻮد اﻳﻦ ﺷﻴﺊ دﻗﻴﻘﺎ در ﺟﺎﻳﻲ ﻛﻪ ‪ NextObjPtr‬ﺑﻪ آن اﺷﺎره ﻣﻴﻜﻨﺪ ﻗﺮار ﻣﻴﮕﻴﺮد )درﺳﺖ ﺑﻌﺪ از ﺷﻴﺊ ‪.(C‬‬

‫در ﻋﻮض اﺟﺎزه دﻫﻴﺪ ﺗﺨﺼﻴﺺ ﺣﺎﻓﻈﻪ را در ‪ heap‬زﻣﺎن اﺟﺮاي ‪ C‬ﺑﺮرﺳﻲ ﻛﻨﻴﻢ‪ .‬در ﻳﻚ ‪ heap‬زﻣﺎن اﺟﺮاي ‪ C‬ﺗﺨﺼﻴﺺ ﺣﺎﻓﻈﻪ‬ ‫ﺑﺮاي ﻳﻚ ﺷﻲ ﺑﻪ ﺣﺮﻛﺖ در ﻣﻴﺎن ﺳﺎﺧﺘﺎرﻫﺎي داده از ﻳﻚ ﻟﻴﺴﺖ ﭘﻴﻮﻧﺪي ﻧﻴﺎز دارد‪ .‬زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﺑﻼك ﺣﺎﻓﻈﻪ ﺑﺎ اﻧﺪازه ﻻزم ﭘﻴﺪا ﺷﺪ‬ ‫اﻳﻦ ﺑﻼك ﺣﺎﻓﻈﻪ ﺗﻘﺴﻴﻢ ﻣﻴﺸﻮد و ﺷﻴﺊ ﻣﺬﻛﻮر در آن اﻳﺠﺎد ﻣﻴﺸﻮد و اﺷﺎره ﮔﺮﻫﺎي ﻣﻮﺟﻮد در ﻟﻴﺴﺖ ﭘﻴﻮﻧﺪي ﺑﺮاي ﻧﮕﻪ داري در آن‬ ‫ﺷﻴﺊ ﺗﻐﻴﻴﺮ داده ﻣﻴﺸﻮﻧﺪ‪ .‬ﺑﺮاي ‪ managed heap‬ﺗﺨﺼﻴﺺ ﺣﺎﻓﻈﻪ ﺑﺮاي ﻳﻚ ﺷﻴﺊ ﺑﻪ ﻣﻌﻨﺎي اﺿﺎﻓﻪ ﻛﺮدن ﻳﻚ ﻣﻘﺪار ﺑﻪ اﺷﺎره‬ ‫ﮔﺮ اﺳﺖ‪ .‬در ﺣﻘﻴﻘﺖ ﺗﺨﺼﻴﺺ ﺣﺎﻓﻈﻪ ﺑﻪ ﻳﻚ ﺷﻴﺊ در ‪ managed heap‬ﺗﻘﺮﻳﺒﺎ ﺑﻪ ﺳﺮﻋﺖ اﻳﺠﺎد ﻳﻚ ﻣﺘﻐﻴﻴﺮ در ‪stack‬‬ ‫اﺳﺖ! ﺑﻪ ﻋﻼوه در ﺑﻴﺸﺘﺮ ‪heap‬ﻫﺎ ﻣﺎﻧﻨﺪ ‪ heap‬زﻣﺎن اﺟﺮاي ‪ C‬ﺣﺎﻓﻈﻪ در ﺟﺎﻳﻲ اﺧﺘﺼﺎص داده ﻣﻴﺸﻮد ﻛﻪ ﻓﻀﺎي ﺧﺎﻟﻲ ﻛﺎﻓﻲ‬ ‫ﻳﺎﻓﺖ ﺷﻮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﭼﻨﺪ ﺷﻴﺊ ﺑﻼﻓﺎﺻﻠﻪ ﺑﻌﺪ از ﻫﻢ در ﺑﺮﻧﺎﻣﻪ اﻳﺠﺎد ﺷﻮﻧﺪ‪ ،‬ﻣﻤﻜﻦ اﺳﺖ اﻳﻦ اﺷﻴﺎ ﭼﻨﺪﻳﻦ ﻣﮕﺎ ﺑﺎﻳﺖ آدرس ﺣﺎﻓﻈﻪ ﺑﺎ‬ ‫ﻫﻢ ﻓﺎﺻﻠﻪ داﺷﺘﻪ ﺑﺎﺷﻨﺪ وﻟﻲ در ‪ managed heap‬اﻳﺠﺎد ﭼﻨﺪ ﺷﻴﺊ ﺑﻼﻓﺎﺻﻠﻪ ﺑﻌﺪ از ﻫﻢ ﺑﺎﻋﺚ ﻗﺮار ﮔﺮﻓﺘﻦ ﺗﺮﺗﻴﺒﻲ اﻳﻦ اﺷﻴﺎ در‬ ‫ﺣﺎﻓﻈﻪ ﻣﻴﺸﻮد‪.‬‬ ‫در ﺑﻴﺸﺘﺮ ﺑﺮﻧﺎﻣﻪ ﻫﺎ وﻗﺘﻲ ﺑﺮاي ﻳﻚ ﺷﻴﺊ ﺣﺎﻓﻈﻪ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻴﺸﻮد ﻛﻪ ﻳﺎ ﺑﺨﻮاﻫﺪ ﺑﺎ ﻳﻚ ﺷﻴﺊ دﻳﮕﺮ ارﺗﺒﺎط ﻗﻮي داﺷﺘﻪ ﺑﺎﺷﺪ ﻳﺎ‬ ‫ﺑﺨﻮاﻫﺪ ﭼﻨﺪﻳﻦ ﺑﺎر در ﻳﻚ ﻗﻄﻌﻪ ﻛﺪ اﺳﺘﻔﺎده ﺷﻮد‪ .‬ﺑﺮاي ﻣﺜﺎل ﻣﻌﻤﻮﻻ وﻗﺘﻲ ﻳﻚ ﺣﺎﻓﻈﻪ ﺑﺮاي ﺷﻴﺊ ‪ BinaryWriter‬اﻳﺠﺎد‬ ‫ﺷﺪ ﺑﻼﻓﺎﺻﻠﻪ ﺑﻌﺪ از آن ﻳﻚ ﺣﺎﻓﻈﻪ ﺑﺮاي ‪ FileStream‬ﮔﺮﻓﺘﻪ ﺷﻮد‪ .‬ﺳﭙﺲ ﺑﺮﻧﺎﻣﻪ از ‪ BinaryWriter‬اﺳﺘﻔﺎده ﻣﻴﻜﻨﺪ‬ ‫ﻛﻪ در ﺣﻘﻴﻘﺖ ﺑﻪ ﺻﻮرت دروﻧﻲ از ﺷﻴﺊ ‪ FileStream‬ﻫﻢ اﺳﺘﻔﺎده ﻣﻴﻜﻨﺪ‪ .‬در ﻳﻚ ﻣﺤﻴﻂ ﻛﻨﺘﺮل ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ‬ ‫‪ Garbage Collector‬ﺑﺮاي اﺷﻴﺎي ﺟﺪﻳﺪ ﺑﻪ ﺻﻮرت ﻣﺘﻮاﻟﻲ ﻓﻀﺎ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻴﺸﻮد ﻛﻪ اﻳﻦ ﻋﻤﻞ ﻣﻮﺟﺐ اﻓﺰاﻳﺶ‬ ‫راﻧﺪﻣﺎن ﺑﻪ دﻟﻴﻞ ﻣﻮﻗﻌﻴﺖ ارﺟﺎع ﻫﺎ ﻣﻴﺸﻮد‪ .‬ﺑﻪ وﻳﮋه اﻳﻦ ﻣﻮرد ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻣﺠﻤﻮﻋﻪ ﻛﺎرﻫﺎي ﭘﺮوﺳﻪ ﺷﻤﺎ ﻛﻤﺘﺮ ﺷﺪه و اﻳﻦ ﻧﻴﺰ‬ ‫ﻣﺘﺸﺎﺑﻪ ﻗﺮار ﮔﺮﻓﺘﻦ اﺷﻴﺎي ﻣﻮرد اﺳﺘﻔﺎده ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ در ‪ CPU Cache‬اﺳﺖ‪.‬‬ ‫ﺗﺎ ﻛﻨﻮن اﻳﻨﮕﻮﻧﻪ ﺑﻪ ﻧﻈﺮ ﻣﻴﺮﺳﻴﺪ ﻛﻪ ‪ managed heap‬ﺑﺴﻴﺎر ﺑﺮﺗﺮ از ‪ heap‬زﻣﺎن اﺟﺮاي ‪ C‬اﺳﺖ و اﻳﻦ ﻧﻴﺰ ﺑﻪ دﻟﻴﻞ ﺳﺎدﮔﻲ‬ ‫ﭘﻴﺎده ﺳﺎزي و ﺳﺮﻋﺖ آن اﺳﺖ‪ .‬اﻣﺎ ﻧﻜﺘﻪ دﻳﮕﺮي ﻛﻪ اﻳﻨﺠﺎ ﺑﺎﻳﺪ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﻮد اﻳﻦ اﺳﺖ ﻛﻪ ‪ managed heap‬اﻳﻦ ﺗﻮاﻧﺎﻳﻲ‬ ‫ﻫﺎ را ﺑﻪ اﻳﻦ دﻟﻴﻞ ﺑﻪ دﺳﺖ ﻣﻲ آورد ﻛﻪ ﻳﻚ ﻓﺮض ﺑﺰرگ اﻧﺠﺎم ﻣﻴﺪﻫﺪ و آن ﻓﺮض اﻳﻦ اﺳﺖ ﻛﻪ ﻓﻀﺎي آدرس و ﺣﺎﻓﻈﻪ ﺑﻴﻨﻬﺎﻳﺖ‬ ‫ﻫﺴﺘﻨﺪ‪ .‬ﺑﻪ وﺿﻮح اﻳﻦ ﻓﺮض ﻛﻤﻲ ﺧﻨﺪه دار ﺑﻪ ﻧﻈﺮ ﻣﻴﺮﺳﺪ و ﻣﺴﻠﻤﺎ ‪ managed heap‬ﺑﺎﻳﺪ ﻳﻚ ﻣﻜﺎﻧﻴﺴﻢ وﻳﮋه اي را ﺑﻪ ﻛﺎر‬ ‫ﺑﺮد ﺗﺎ ﺑﺘﻮاﻧﺪ اﻳﻦ ﻓﺮض را اﻧﺠﺎم دﻫﺪ‪ .‬اﻳﻦ ﻣﻜﺎﻧﻴﺴﻢ ‪ Garbage Collector‬ﻧﺎﻣﻴﺪه ﻣﻴﺸﻮد ‪ ،‬ﻛﻪ در اداﻣﻪ ﻃﺮز ﻛﺎر آن‬ ‫ﺷﺮح داده ﻣﻴﺸﻮد‪.‬‬ ‫زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻋﻤﻠﮕﺮ ‪ new‬را ﻓﺮاﺧﻮاﻧﻲ ﻣﻴﻜﻨﺪ ﻣﻤﻜﻦ اﺳﺖ ﻓﻀﺎي ﺧﺎﻟﻲ ﻛﺎﻓﻲ ﺑﺮاي ﺷﻴﺊ ﻣﻮرد ﻧﻈﺮ وﺟﻮد ﻧﺪاﺷﺘﻪ ﺑﺎﺷﺪ‪.‬‬ ‫‪ heap‬اﻳﻦ ﻣﻮﺿﻮع را ﺑﺎ اﺿﺎﻓﻪ ﻛﺮدن ﺣﺠﻢ ﻣﻮرد ﻧﻴﺎز ﺑﻪ آدرس ﻣﻮﺟﻮد در ‪ NextObjPtr‬ﻣﺘﻮﺟﻪ ﻣﻴﺸﻮد‪ .‬اﮔﺮ ﻧﺘﻴﺠﻪ از ﻓﻀﺎي‬ ‫در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﺷﺪه ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﺗﺠﺎوز ﻛﺮد ‪ heap‬ﭘﺮ ﺷﺪه اﺳﺖ و ‪ Garbage Collector‬ﺑﺎﻳﺪ آﻏﺎز ﺑﻪ ﻛﺎر ﻛﻨﺪ‪.‬‬

‫‪٩٣٧‬‬

‫ﻣﻬﻢ‪ :‬ﻣﻄﺎﻟﺒﻲ ﻛﻪ ذﻛﺮ ﺷﺪ در ﺣﻘﻴﻘﻴﺖ ﺻﻮرت ﺳﺎده ﺷﺪه ﻣﺴﺌﻠﻪ ﺑﻮد‪ .‬در واﻗﻌﻴﺖ ﻳﻚ ‪ Garbage Collection‬زﻣﺎﻧﻲ‬ ‫رخ ﻣﻲ دﻫﺪ ﻛﻪ ﻧﺴﻞ ﺻﻔﺮ ﻛﺎﻣﻞ ﺷﻮد‪ .‬ﺑﻌﻀﻲ ‪ Garbage Collector‬ﻫﺎ از ﻧﺴﻞ ﻫﺎ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﻨﺪ ﻛﻪ ﻳﻚ ﻣﻜﺎﻧﻴﺴﻢ‬ ‫ﺑﻪ ﺷﻤﺎر ﻣﻲ رود و ﻫﺪف اﺻﻠﻲ آن اﻓﺰاﻳﺶ ﻛﺎراﻳﻲ اﺳﺖ‪ .‬اﻳﺪه اﺻﻠﻲ ﺑﻪ اﻳﻦ ﺻﻮرت اﺳﺖ ﻛﻪ اﺷﻴﺎي ﺗﺎزه اﻳﺠﺎد ﺷﺪه ﻧﺴﻞ ﺻﻔﺮ ﺑﻪ ﺷﻤﺎر‬ ‫ﻣﻲ روﻧﺪ و اﺷﻴﺎﻳﻲ ﻗﺪﻳﻤﻲ ﺗﺮ در ﻃﻮل ﻋﻤﺮ ﺑﺮﻧﺎﻣﻪ در ﻧﺴﻞ ﻫﺎي ﺑﺎﻻﺗﺮ ﻗﺮار ﻣﻲ ﮔﻴﺮﻧﺪ‪ .‬ﺟﺪاﺳﺎزي اﺷﻴﺎ و دﺳﺘﻪ ﺑﻨﺪي آﻧﻬﺎ ﺑﻪ ﻧﺴﻞ ﻫﺎي‬ ‫ﻣﺨﺘﻠﻒ ﻣﻲ ﺗﻮاﻧﺪ ﺑﻪ ‪ Garbage Collector‬اﺟﺎزه دﻫﺪ اﺷﻴﺎﻳﻲ ﻣﻮﺟﻮد در ﻧﺴﻞ ﺧﺎﺻﻲ را ﺑﻪ ﺟﺎي ﺗﻤﺎم اﺷﻴﺎ ﻣﻮرد ﺑﺮرﺳﻲ‬ ‫ﻗﺮار دﻫﺪ‪ .‬در ﺑﺨﺶ ﻫﺎي ﺑﻌﺪي ﻧﺴﻞ ﻫﺎ ﺑﺎ ﺟﺰﺋﻴﺎت ﺗﻤﺎم ﺷﺮح داده ﻣﻲ ﺷﻮﻧﺪ‪ .‬اﻣﺎ ﺗﺎ ان ﻣﺮﺣﻠﻪ ﻓﺮض ﻣﻲ ﺷﻮد ﻛﻪ ‪Garbage‬‬ ‫‪ collector‬وﻗﺘﻲ رخ ﻣﻲ دﻫﺪ ﻛﻪ ‪ heap‬ﭘﺮ ﺷﻮد‪.‬‬

‫اﻟﮕﻮرﻳﺘﻢ ‪:Garbage Collection‬‬ ‫‪ Garbage Collection‬ﺑﺮرﺳﻲ ﻣﻲ ﻛﻨﺪ ﻛﻪ آﻳﺎ در ‪ heap‬ﺷﻴﺊ وﺟﻮد دارد ﻛﻪ دﻳﮕﺮ ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده ﻧﺸﻮد‪ .‬اﮔﺮ‬ ‫ﭼﻨﻴﻦ اﺷﻴﺎي در ﺑﺮﻧﺎﻣﻪ ﻣﻮﺟﻮد ﺑﺎﺷﻨﺪ ﺣﺎﻓﻈﻪ ﮔﺮﻓﺘﻪ ﺷﺪه ﺗﻮﺳﻂ اﻳﻦ اﺷﻴﺎ آزاد ﻣﻴﺸﻮد )اﮔﺮ ﻫﻴﭻ ﺣﺎﻓﻈﻪ اي ﺑﺮاي اﺷﻴﺎي ﺟﺪﻳﺪ در ‪heap‬‬ ‫ﻣﻮﺟﻮد ﻧﺒﺎﺷﺪ ﺧﻄﺎي ‪ OutOfMemoryException‬ﺗﻮﺳﻂ ﻋﻤﻠﮕﺮ ‪ new‬رخ ﻣﻴﺪﻫﺪ(‪ .‬اﻣﺎ ﭼﮕﻮﻧﻪ ‪Garbage‬‬ ‫‪ Collector‬ﺗﺸﺨﻴﺺ ﻣﻴﺪﻫﺪ ﻛﻪ آﻳﺎ ﺑﺮﻧﺎﻣﻪ ﻳﻚ ﻣﺘﻐﻴﺮ را ﻧﻴﺎز دارد ﻳﺎ ﺧﻴﺮ؟ ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻤﻜﻦ اﺳﺖ ﺗﺼﻮر ﻛﻨﻴﺪ اﻳﻦ ﺳﻮال ﭘﺎﺳﺦ‬ ‫ﺳﺎده اي ﻧﺪارد‪.‬‬ ‫ﻫﺮ ﺑﺮﻧﺎﻣﻪ داراي ﻳﻚ ﻣﺠﻤﻮﻋﻪ از ‪root‬ﻫﺎ اﺳﺖ‪ .‬ﻳﻚ ‪ root‬اﺷﺎره ﮔﺮي اﺳﺖ ﺑﻪ ﻳﻚ ﻧﻮع داده ارﺟﺎﻋﻲ‪ .‬اﻳﻦ اﺷﺎره ﮔﺮ ﻳﺎ ﺑﻪ ﻳﻚ‬ ‫ﻧﻮع داده ارﺟﺎﻋﻲ در ‪ managed heap‬اﺷﺎره ﻣﻴﻜﻨﺪ ﻳﺎ ﺑﺎ ﻣﻘﺪار ‪ null‬ﻣﻘﺪار دﻫﻲ ﺷﺪه اﺳﺖ‪.‬ﺑﺮاي ﻣﺜﺎل ﺗﻤﺎم ﻣﺘﻐﻴﻴﺮ ﻫﺎي‬ ‫اﺳﺘﺎﺗﻴﻚ و ﻳﺎ ﻋﻤﻮﻣﻲ‪ 1‬ﻳﻚ ‪ root‬ﺑﻪ ﺷﻤﺎر ﻣﻴﺮوﻧﺪ ‪ .‬ﺑﻪ ﻋﻼوه ﻫﺮ ﻣﺘﻐﻴﺮ ﻣﺤﻠﻲ ﻛﻪ از ﻧﻮع ارﺟﺎع ﺑﺎﺷﺪ و ﻳﺎ ﭘﺎراﻣﺘﺮﻫﺎي ﺗﻮاﺑﻊ در‬ ‫‪ stack‬ﻧﻴﺰ ﻳﻚ ‪ root‬ﺑﻪ ﺷﻤﺎر ﻣﻴﺮوﻧﺪ‪ .‬در ﻧﻬﺎﻳﺖ‪ ،‬درون ﻳﻚ ﺗﺎﺑﻊ‪ ،‬ﻳﻚ ﺛﺒﺎت ‪ CPU‬ﻛﻪ ﺑﻪ ﻳﻚ ﺷﻴﺊ از ﻧﻮع ارﺟﺎع اﺷﺎره ﻛﻨﺪ‬ ‫ﻧﻴﺰ ﻳﻚ ‪ root‬ﺑﻪ ﺷﻤﺎر ﻣﻴﺮود‪.‬‬ ‫زﻣﺎﻧﻲ ﻛﻪ ﻛﺎﻣﭙﺎﻳﻠﺮ ‪ JIT‬ﻳﻚ ﻛﺪ‪ IL‬را ﻛﺎﻣﭙﺎﻳﻞ ﻣﻴﻜﻨﺪ ﻋﻼوه ﺑﺮ ﺗﻮﻟﻴﺪ ﻛﺪ ﻫﺎي ‪ Native‬ﻳﻚ ﺟﺪول داﺧﻠﻲ ﻧﻴﺰ ﺗﺸﻜﻴﻞ‬ ‫ﻣﻴﺪﻫﺪ‪ .‬ﻣﻨﻄﻘﺎ ﻫﺮ ردﻳﻒ از اﻳﻦ ﺟﺪول ﻳﻚ ﻣﺤﺪوده از ﺑﺎﻳﺖ ﻫﺎي آﻓﺴﺖ را در دﺳﺘﻮرات ﻣﺤﻠﻲ ‪ CPU‬ﺑﺮاي ﺗﺎﺑﻊ ﻧﺸﺎن ﻣﻴﺪﻫﻨﺪ و ﺑﺮاي‬ ‫ﻫﺮ ﻛﺪام از اﻳﻦ ﻣﺤﺪوده ﻫﺎ ﻳﻚ ﻣﺠﻤﻮﻋﻪ از آدرس ﻫﺎي ﺣﺎﻓﻈﻪ ﻳﺎ ﺛﺒﺎت ﻫﺎي ‪ CPU‬را ﻛﻪ ﻣﺤﺘﻮي ‪root‬ﻫﺎ ﻫﺴﺘﻨﺪ ﻣﺸﺨﺺ‬ ‫ﻣﻴﻜﻨﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل ﺟﺪول ﻣﻤﻜﻦ اﺳﺖ ﻣﺎﻧﻨﺪ ﺟﺪول زﻳﺮ ﺑﺎﺷﺪ‪:‬‬ ‫‪Sample of a JIT compiler-produced table showing mapping of‬‬ ‫‪native code offsets to a method's roots‬‬ ‫‪Starting‬‬ ‫‪Byte‬‬ ‫‪Ending‬‬ ‫‪Byte‬‬ ‫‪Roots‬‬ ‫‪Offset‬‬ ‫‪Offset‬‬ ‫‪0x00000000‬‬ ‫‪0x00000020‬‬ ‫‪this,‬‬ ‫‪arg1,‬‬ ‫‪arg2,‬‬ ‫‪ECX,‬‬ ‫‪EDX‬‬ ‫‪0x00000021‬‬ ‫‪0x00000122‬‬ ‫‪this,‬‬ ‫‪arg2,‬‬ ‫‪fs, EBX‬‬ ‫‪0x00000123‬‬ ‫‪0x00000145‬‬ ‫‪Fs‬‬

‫‪Global Variables‬‬

‫‪1‬‬

‫‪٩٣٨‬‬

‫اﮔﺮ ﻳﻚ ‪ Garbage Collector‬زﻣﺎﻧﻲ ﻛﻪ ﻛﺪي ﺑﻴﻦ آﻓﺴﺖ ‪ 0x00000021‬و ‪ 0x00000122‬در ﺣﺎل‬ ‫اﺟﺮا اﺳﺖ آﻏﺎز ﺷﻮد‪ Garbage Collector ،‬ﻣﻴﺪاﻧﺪ ﻛﻪ ﭘﺎراﻣﺘﺮﻫﺎي ‪this‬و ‪ arg2‬و ﻣﺘﻐﻴﻴﺮ ﻫﺎي ﻣﺤﻠﻲ ‪ fs‬و‬ ‫ﺛﺒﺎت ‪ EBX‬ﻫﻤﻪ ‪ root‬ﻫﺴﺘﻨﺪ و ﺑﻪ اﺷﻴﺎﻳﻲ درون ‪ heap‬اﺷﺎره ﻣﻴﻜﻨﻨﺪ ﻛﻪ ﻧﺒﺎﻳﺪ زﺑﺎﻟﻪ ﺗﻠﻘﻲ ﺷﻮﻧﺪ‪ .‬ﺑﻪ ﻋﻼوه ‪Garbage‬‬ ‫‪ Collector‬ﻣﻴﺘﻮاﻧﺪ ﺑﻴﻦ ‪ stack‬ﺣﺮﻛﺖ ﻛﻨﺪ و ‪root‬ﻫﺎ را ﺑﺮاي ﺗﻤﺎم ﺗﻮاﺑﻊ ﻓﺮاﺧﻮاﻧﻲ ﺷﺪه ﺑﺎ اﻣﺘﺤﺎن ﻛﺮدن ﺟﺪول داﺧﻠﻲ‬ ‫ﻫﺮ ﻛﺪام از اﻳﻦ ﺗﻮاﺑﻊ ﻣﺸﺨﺺ ﻛﻨﺪ‪ Garbage Collector .‬وﺳﻴﻠﻪ دﻳﮕﺮي را ﺑﺮاي ﺑﺪﺳﺖ آوردن ﻣﺠﻤﻮﻋﻪ‬ ‫‪root‬ﻫﺎي ﻧﮕﻪ داري ﺷﺪه ﺗﻮﺳﻂ ﻣﺘﻐﻴﺮﻫﺎي ارﺟﺎﻋﻲ اﺳﺘﺎﺗﻴﻚ و ﻋﻤﻮﻣﻲ ﺑﻪ ﻛﺎر ﻣﻴﺒﺮد‪.‬‬ ‫ﻧﻜﺘﻪ‪ :‬در ﺟﺪول ﺑﺎﻻ ﺗﻮﺟﻪ ﻛﻨﻴﺪ ﻛﻪ آرﮔﻮﻣﺎن ‪ arg1‬ﺗﺎﺑﻊ ﺑﻌﺪ از دﺳﺘﻮرات ‪ CPU‬در آﻓﺴﺖ ‪ 0x00000020‬دﻳﮕﺮ ﺑﻪ ﭼﻴﺰي‬ ‫اﺷﺎره ﻧﻤﻴﻜﻨﺪ و اﻳﻦ اﻣﺮ ﺑﺪﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﺷﻴﺌﻲ ﻛﻪ ‪ arg1‬ﺑﻪ آن اﺷﺎره ﻣﻴﻜﻨﺪ ﻫﺮ زﻣﺎن ﺑﻌﺪ از اﺟﺮاي اﻳﻦ دﺳﺘﻮرات ﻣﻴﺘﻮاﻧﺪ ﺗﻮﺳﻂ‬ ‫‪ Garbage Collector‬ﺟﻤﻊ آوري ﺷﻮد )اﻟﺒﺘﻪ ﻓﺮض ﺑﺮ اﻳﻨﻜﻪ ﻫﻴﭻ ﺷﻴﺊ دﻳﮕﺮي در ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺷﻴﺊ ﻣﻮرد ارﺟﺎع ﺗﻮﺳﻂ‬ ‫‪ arg1‬اﺷﺎره ﻧﻤﻴﻜﻨﺪ(‪ .‬ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﻪ ﻣﺤﺾ اﻳﻨﻜﻪ ﻳﻚ ﺷﻴﺊ ﻏﻴﺮ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﺑﺎﺷﺪ ﺑﺮاي ﺟﻤﻊ آوري ﺷﺪن ﺗﻮﺳﻂ‬ ‫‪ Garbage Collector‬داوﻃﻠﺐ ﻣﻴﺸﻮد و ﺑﻪ ﻫﻤﻴﻦ ﻋﻠﺖ ﺑﺎﻗﻲ ﻣﺎﻧﺪن اﺷﻴﺎ ﺗﺎ ﭘﺎﻳﺎن ﻳﻚ ﻣﺘﺪ ﺗﻮﺳﻂ ‪Garbage‬‬ ‫‪ Collector‬ﺗﻀﻤﻴﻦ ﻧﻤﻴﺸﻮد‪.‬‬ ‫ﺑﺎ وﺟﻮد اﻳﻦ زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﺑﺮﻧﺎﻣﻪ زﻣﺎﻧﻲ ﻛﻪ در ﺣﺎﻟﺖ ‪ debug‬اﺟﺮا ﺷﺪه ﺑﺎﺷﺪ و ﻳﺎ وﻳﮋﮔﻲ‬ ‫‪ System.Diagnostics.DebuggableAttribute‬ﺑﻪ اﺳﻤﺒﻠﻲ ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﺷﺪه ﺑﺎﺷﺪ و ﻳﺎ اﻳﻨﻜﻪ‬ ‫ﭘﺎراﻣﺘﺮ ‪ isJITOptimizeDisabled‬ﺑﺎ ﻣﻘﺪار ‪ true‬در ‪ constructor‬ﺑﺮﻧﺎﻣﻪ ﺗﻨﻈﻴﻢ ﺷﺪه ﺑﺎﺷﺪ‪ ،‬ﻛﺎﻣﭙﺎﻳﻠﺮ‬ ‫‪ JIT‬ﻃﻮل ﻋﻤﺮ ﺗﻤﺎم ﻣﺘﻐﻴﺮ ﻫﺎ را‪ ،‬ﭼﻪ از ﻧﻮع ارﺟﺎﻋﻲ و ﭼﻪ از ﻧﻮع ﻣﻘﺪار‪ ،‬ﺗﺎ ﭘﺎﻳﺎن ﻣﺤﺪوده ﺷﺎن اﻓﺰاﻳﺶ ﻣﻴﺪﻫﺪ ﻛﻪ ﻣﻌﻤﻮﻻ ﻫﻤﺎن ﭘﺎﻳﺎن‬ ‫ﺗﺎﺑﻊ اﺳﺖ) ﻛﺎﻣﭙﺎﻳﻠﺮ ‪ C#‬ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﻳﻚ ﺳﻮﻳﻴﭻ ﺧﻂ ﻓﺮﻣﺎن ﺑﻪ ﻧﺎم ‪ /debug‬را اراﺋﻪ ﻣﻴﺪﻫﺪ ﻛﻪ ﺑﺎﻋﺚ اﺿﺎﻓﻪ ﺷﺪن‬ ‫‪ DebuggableAttribute‬ﺑﻪ اﺳﻤﺒﻠﻲ اﺿﺎﻓﻪ ﻣﻴﺸﻮد و ﻧﻴﺰ ﭘﺎراﻣﺘﺮ ‪ isJITOptimizeDisabled‬را ﻧﻴﺰ‬ ‫‪ true‬ﻣﻴﻜﻨﺪ(‪ .‬اﻳﻦ اﻓﺰاﻳﺶ ﻃﻮل ﻋﻤﺮ از ﺟﻤﻊ آوري ﺷﺪن ﻣﺘﻐﻴﺮ ﻫﺎ ﺗﻮﺳﻂ ‪ Garbage Collector‬در ﻣﺤﺪوده اﺟﺮاﻳﻲ‬ ‫آﻧﻬﺎ در ﻃﻮل ﺑﺮﻧﺎﻣﻪ ﺟﻠﻮﮔﻴﺮي ﻣﻴﻜﻨﺪ و اﻳﻦ ﻋﻤﻞ ﻓﻘﻂ در زﻣﺎن ‪ debug‬ﻳﻚ ﺑﺮﻧﺎﻣﻪ ﻣﻔﻴﺪ واﻗﻊ ﻣﻴﺸﻮد‪.‬‬ ‫زﻣﺎﻧﻲ ﻛﻪ ‪ Garbage Collector‬ﺷﺮوع ﺑﻪ ﻛﺎر ﻣﻴﻜﻨﺪ‪ ،‬ﻓﺮض ﻣﻴﻜﻨﺪ ﻛﻪ ﺗﻤﺎم اﺷﻴﺎي ﻣﻮﺟﻮد در ‪ heap‬زﺑﺎﻟﻪ ﻫﺴﺘﻨﺪ‪.‬‬ ‫ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﻓﺮض ﻣﻴﻜﻨﺪ ﻛﻪ ﻫﻴﭻ ﻛﺪام از ‪root‬ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻫﻴﭻ ﺷﻴﺊ در ‪ heap‬اﺷﺎره ﻧﻤﻴﻜﻨﺪ‪ .‬ﺳﭙﺲ ‪Garbage‬‬ ‫‪ Collector‬ﺷﺮوع ﺑﻪ ﺣﺮﻛﺖ در ﻣﻴﺎن ‪root‬ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﻣﻴﻜﻨﺪ و ﻳﻚ ﮔﺮاف از ﺗﻤﺎم ‪root‬ﻫﺎي ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﺗﺸﻜﻴﻞ‬ ‫ﻣﻴﺪﻫﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل ‪ Garbage Collector‬ﻣﻤﻜﻦ اﺳﺖ ﻳﻚ ﻣﺘﻐﻴﺮ ﻋﻤﻮﻣﻲ را ﻛﻪ ﺑﻪ ﻳﻚ ﺷﻴﺊ در ‪ heap‬اﺷﺎره ﻣﻴﻜﻨﺪ‬ ‫ﻣﻮﻗﻌﻴﺖ ﻳﺎﺑﻲ ﻛﻨﺪ‪ .‬ﺷﻜﻞ زﻳﺮ ﻳﻚ ‪ heap‬را ﺑﺎ ﭼﻨﺪﻳﻦ ﺷﻴﺊ ﺗﺨﺼﻴﺺ داده ﺷﺪه ﻧﺸﺎن ﻣﻴﺪﻫﺪ‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ ﻣﺸﺨﺺ اﺳﺖ‬ ‫‪root‬ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﻓﻘﻂ ﺑﻪ اﺷﻴﺎي ‪ A‬و ‪ C‬و ‪ D‬و ‪ F‬ﺑﻪ ﻃﻮر ﻣﺴﺘﻘﻴﻢ اﺷﺎره ﻣﻴﻜﻨﻨﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺗﻤﺎم اﻳﻦ اﺷﻴﺎ از اﻋﻀﺎي ﮔﺮاف ﻣﺤﺴﻮب‬ ‫ﻣﻴﺸﻮﻧﺪ‪ .‬زﻣﺎن اﺿﺎﻓﻪ ﻛﺮدن ﺷﻴﺊ ‪ Garbage Collector،D‬ﻣﺘﻮﺟﻪ ﻣﻴﺸﻮد ﻛﻪ اﻳﻦ ﺷﻴﺊ ﺑﻪ ﺷﻴﺊ ‪ H‬اﺷﺎره ﻣﻴﻜﻨﺪ‪،‬‬ ‫ﺑﻨﺎﺑﺮاﻳﻦ ﺷﻴﺊ ‪ H‬ﻧﻴﺰ ﺑﻪ ﮔﺮاف ﺑﺮﻧﺎﻣﻪ اﺿﺎﻓﻪ ﻣﻴﺸﻮد و ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴﺐ ‪ Garbage Collector‬ﺗﻤﺎم اﺷﻴﺎي ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ‬ ‫در ‪ heap‬را ﻣﺸﺨﺺ ﻣﻴﻜﻨﺪ‪.‬‬

‫‪٩٣٩‬‬

‫زﻣﺎﻧﻲ ﻛﻪ اﻳﻦ ﺑﺨﺶ از ﮔﺮاف ﻛﺎﻣﻞ ﺷﺪ ‪root ،Garbage Collector‬ﻫﺎي ﺑﻌﺪي را ﭼﻚ ﻣﻴﻜﻨﺪ و ﻣﺠﺪدا اﺷﻴﺎ را‬ ‫ﺑﺮرﺳﻲ ﻣﻴﻜﻨﺪ‪ .‬در ﻃﻮل اﻳﻨﻜﻪ ‪ Garbage Collector‬از ﻳﻚ ﺷﻴﺊ ﺑﻪ ﻳﻚ ﺷﻴﺊ دﻳﮕﺮ ﻣﻨﺘﻘﻞ ﻣﻴﺸﻮد‪ ،‬اﮔﺮ ﺳﻌﻲ ﻛﻨﺪ ﻛﻪ‬ ‫ﻳﻚ ﺷﻴﺊ ﺗﻜﺮاري را ﺑﻪ ﮔﺮاف اﺿﺎﻓﻪ ﻛﻨﺪ‪ Garbage Collector،‬ﺣﺮﻛﺖ در آن ﻣﺴﻴﺮ را ﻣﺘﻮﻗﻒ ﻣﻴﻜﻨﺪ‪ .‬اﻳﻦ ﻧﻮع رﻓﺘﺎر‬ ‫دو ﻫﺪف را دﻧﺒﺎل ﻣﻴﻜﻨﺪ‪ :‬اول اﻳﻨﻜﻪ ﭼﻮن ‪ Garbage Collector‬از ﻫﻴﭻ ﺷﻴﺊ دو ﺑﺎر ﻋﺒﻮر ﻧﻤﻴﻜﻨﺪ راﻧﺪﻣﺎن ﺑﺮﻧﺎﻣﻪ را ﺑﻪ‬ ‫ﺷﻜﻞ ﻗﺎﺑﻞ ﺗﻮﺟﻬﻲ اﻓﺰاﻳﺶ ﻣﻴﺪﻫﺪ‪ .‬دوم اﻳﻨﻜﻪ ﻫﺮ ﻗﺪر ﻫﻢ در ﺑﺮﻧﺎﻣﻪ ﻟﻴﺴﺖ ﻫﺎي ﭘﻴﻮﻧﺪي داﻳﺮه اي از اﺷﻴﺎ ﻣﻮﺟﻮد ﺑﺎﺷﻨﺪ ‪،‬‬ ‫‪ Garbage Collector‬در ﺣﻠﻘﻪ ﻫﺎي ﺑﻴﻨﻬﺎﻳﺖ ﻧﻤﻲ ﻣﺎﻧﺪ‪.‬‬ ‫زﻣﺎﻧﻲ ﻛﻪ ﺗﻤﺎم ‪root‬ﻫﺎ ﺑﺮرﺳﻲ ﺷﺪﻧﺪ‪ ،‬ﮔﺮاف ‪ Garbage Collector‬ﻣﺤﺘﻮي ﺗﻤﺎم اﺷﻴﺎﻳﻲ اﺳﺖ ﻛﻪ ﺑﻪ ﻧﺤﻮي از‬ ‫ﻃﺮﻳﻖ ‪root‬ﻫﺎي ﺑﺮﻧﺎﻣﻪ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﻣﻲ ﺑﺎﺷﻨﺪ و ﻫﺮ ﺷﻴﺊ ﻛﻪ در ﮔﺮاف ﻧﺒﺎﺷﺪ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﺗﻮﺳﻂ ﺑﺮﻧﺎﻣﻪ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ‬ ‫ﻧﻴﺴﺖ و ﻳﻚ زﺑﺎﻟﻪ ﻣﺤﺴﻮب ﻣﻴﺸﻮد‪ .‬ﺑﻌﺪ از اﻳﻦ ‪ Garbage Collector‬ﺑﻪ ﺻﻮرت ﺧﻄﻲ ‪ heap‬را ﻃﻲ ﻣﻴﻜﻨﺪ و دﻧﺒﺎل‬ ‫ﺑﻼك ﻫﺎي ﭘﻴﻮﺳﺘﻪ از زﺑﺎﻟﻪ ﻫﺎي ﻣﺸﺨﺺ ﺷﺪه ﺗﻮﺳﻂ ﮔﺮاف ﻣﻴﮕﺮدد )ﻛﻪ ﻫﻢ اﻛﻨﻮن ﻓﻀﺎي ﺧﺎﻟﻲ ﻣﺤﺴﻮب ﻣﻴﺸﻮﻧﺪ(‪ .‬اﮔﺮ ﺑﻼك ﻫﺎي‬ ‫ﻛﻮﭼﻜﻲ ﭘﻴﺪا ﺷﻮﻧﺪ ‪ Garbage Collector‬اﻳﻦ ﺑﻼك ﻫﺎ را ﺑﻪ ﻫﻤﺎن ﺣﺎل ﻗﺒﻠﻲ رﻫﺎ ﻣﻴﻜﻨﺪ‪.‬‬ ‫‪Garbage‬‬ ‫اﮔﺮ ﻳﻚ ﺑﻼك ﭘﻴﻮﺳﺘﻪ وﺳﻴﻊ ﺗﻮﺳﻂ ‪ Garbage Collector‬ﻳﺎﻓﺖ ﺷﺪ‪ ،‬در اﻳﻦ ﺣﺎل‪،‬‬ ‫‪ Collector‬اﺷﻴﺎي ﻏﻴﺮ زﺑﺎﻟﻪ را ﺑﻪ ﺳﻤﺖ ﭘﺎﻳﻴﻦ ﺣﺎﻓﻈﻪ ‪ heap‬ﺷﻴﻔﺖ ﻣﻴﺪﻫﺪ )و اﻳﻦ ﻛﺎر ﺑﺎ ﺗﺎﺑﻊ اﺳﺘﺎﻧﺪارد ‪memcopy‬‬ ‫اﻧﺠﺎم ﻣﻴﺸﻮد( و ﺑﻪ اﻳﻦ ﻃﺮﻳﻖ ‪ heap‬را ﻓﺸﺮده ﻣﻴﻜﻨﺪ‪ .‬ﻃﺒﻴﻌﺘﺎً ﺣﺮﻛﺖ دادن اﺷﻴﺎ ﺑﻪ ﺳﻤﺖ ﭘﺎﻳﻴﻦ در ‪ heap‬ﺑﺎﻋﺚ ﻧﺎ ﻣﻌﺘﺒﺮ ﺷﺪن‬ ‫ﺗﻤﺎم اﺷﺎره ﮔﺮﻫﺎي ﻣﻮﺟﻮد ﺑﺮاي آن اﺷﻴﺎ ﻣﻴﺸﻮد‪ .‬ﺑﻪ ﻋﻼوه‪ ،‬اﮔﺮ ﺷﻴﺊ ﻣﺤﺘﻮي اﺷﺎره ﮔﺮي ﺑﻪ ﺷﻴﺊ دﻳﮕﺮي ﺑﻮد ‪Garbage‬‬ ‫‪ Collector‬ﻣﺴﺌﻮل ﺗﺼﺤﻴﺢ اﻳﻦ اﺷﺎره ﮔﺮﻫﺎ ﻣﻴﺸﻮد‪ .‬ﺑﻌﺪ از اﻳﻦ ﻛﻪ اﻳﻦ ﻋﻤﻞ ﻓﺸﺮده ﺳﺎزي روي ‪ heap‬اﻧﺠﺎم ﺷﺪ‬ ‫‪ NextObjPtr‬ﺑﻪ آﺧﺮﻳﻦ ﺷﻴﺊ ﻏﻴﺮ زﺑﺎﻟﻪ اﺷﺎره ﻣﻴﻜﻨﺪ‪ .‬ﺷﻜﻞ زﻳﺮ ﻳﻚ ‪ managed heap‬را ﺑﻌﺪ از اﺗﻤﺎم ﻛﺎر‬ ‫‪ Garbage Collector‬ﻧﺸﺎن ﻣﻴﺪﻫﺪ‪.‬‬

‫‪٩٤٠‬‬

‫ اﻣﺎ ﺑﻪ ﻳﺎد‬.‫ ﻳﻚ اﻓﺰاﻳﺶ ﺑﺎزدﻫﻲ ﻗﺎﺑﻞ ﺗﻮﺟﻬﻲ را اﻳﺠﺎد ﻣﻴﻜﻨﺪ‬Garbage Collector،‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ در ﺷﻜﻞ ﻣﻲ ﺑﻴﻨﻴﺪ‬ managed ‫ ﺷﺮوع ﺑﻪ ﻛﺎر ﻣﻴﻜﻨﺪ ﻛﻪ ﻧﺴﻞ ﺻﻔﺮ ﻛﺎﻣﻞ ﺷﻮد و ﺗﺎ آن زﻣﺎن‬Garbage Collector ‫داﺷﺘﻪ ﺑﺎﺷﻴﺪ زﻣﺎﻧﻲ‬ ‫ ﻣﺮﺑﻮط‬Garbage Collector ‫ در ﻧﻬﺎﻳﺖ‬.‫ اﺳﺖ‬C ‫ زﻣﺎن اﺟﺮاي‬heap ‫ ﺑﻪ ﺻﻮرت ﻗﺎﺑﻞ ﺗﻮﺟﻬﻲ ﺳﺮﻳﻌﺘﺮ از‬heap ‫ را ﻣﻘﺪار زﻳﺎدي اﻓﺰاﻳﺶ ﻣﻲ‬Garbage Collector ‫ روش ﺑﻬﻴﻨﻪ ﺳﺎزي را اراﺋﻪ ﻣﻲ دﻫﺪ ﻛﻪ راﻧﺪﻣﺎن ﻛﺎري‬CLR ‫ﺑﻪ‬ .‫دﻫﺪ‬ :‫ﻛﺪ زﻳﺮ ﻧﺸﺎن ﻣﻴﺪﻫﺪ ﻛﻪ ﭼﮕﻮﻧﻪ ﺑﻪ اﺷﻴﺎ ﺣﺎﻓﻈﻪ ﺗﺨﺼﻴﺺ داده ﻣﻴﺸﻮد و آﻧﻬﺎ ﻣﺪﻳﺮﻳﺖ ﻣﻴﺸﻮﻧﺪ‬ Class App { static void Main() { // ArrayList object created in heap, a is now a root ArrayList a = new ArrayList(); // Create 10000 objects in the heap for(Int32 x=0;x<10000;x++ { a.Add(new Object()); // Object created in heap } //Right now, a is a root (on the thread's stack). So a is // reachable and the 10000 objects it refers to // are reachable. Console.WriteLine(a.Length); //After a.Length returns, a isn't referred to in the code //andis no longer a root. If another thread were to start //a garbage collection before the result of a.Length were //passed to WriteLine, the 10001 objects would have their // memory reclaimed. Console.WriteLine("End Of Method"); } }

‫ ﻣﻤﻜﻦ اﺳﺖ ﺗﻌﺠﺐ ﻛﻨﻴﺪ‬،‫ ﻳﻚ ﺗﻜﻨﻮﻟﻮژي ﺑﺎ ارزش ﻣﺤﺴﻮب ﻣﻴﺸﻮد‬Garbage Collector ‫ اﮔﺮ ﻓﻜﺮ ﻣﻴﻜﻨﻴﺪ ﻛﻪ‬:‫ﻧﻜﺘﻪ‬ ‫ اﺣﺘﻴﺎج دارد ﻛﻪ‬Garbage Collector ‫ دﻟﻴﻞ اﻳﻦ ﻣﻮرد اﻳﻦ اﺳﺖ ﻛﻪ‬.‫ ﻗﺮار ﻧﻤﻲ ﮔﻴﺮد‬ANSI C++ ‫ﻛﻪ ﭼﺮا در‬

٩٤١

‫‪root‬ﻫﺎي ﻣﻮﺟﻮد در ﺑﺮﻧﺎﻣﻪ را ﺗﻌﻴﻴﻦ ﻫﻮﻳﺖ ﻛﻨﺪ و ﻧﻴﺰ ﺑﺎﻳﺪ ﺑﺘﻮاﻧﺪ ﺗﻤﺎم اﺷﺎره ﮔﺮﻫﺎي اﺷﻴﺎ را ﭘﻴﺪا ﻛﻨﺪ‪ .‬ﻣﺸﻜﻞ ﺑﺎ ‪ C++‬ﻣﺪﻳﺮﻳﺖ‬ ‫ﻧﺸﺪه اﻳﻦ اﺳﺖ ﻛﻪ اﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺗﻐﻴﻴﺮ ﻧﻮع ﻳﻚ اﺷﺎره ﮔﺮ را از ﻳﻚ ﻧﻮع ﺑﻪ ﻳﻚ ﻧﻮع دﻳﮕﺮ ﻣﺠﺎز ﻣﻴﺪاﻧﺪ و ﻫﻴﭻ راﻫﻲ ﺑﺮاي ﻓﻬﻤﻴﺪن اﻳﻦ ﻛﻪ‬ ‫اﻳﻦ اﺷﺎره ﮔﺮ ﺑﻪ ﭼﻪ ﭼﻴﺰ اﺷﺎره ﻣﻴﻜﻨﺪ وﺟﻮد ﻧﺪارد‪ .‬در ‪ managed heap ،CLR‬ﻫﻤﻴﺸﻪ ﻣﻴﺪاﻧﺪ ﻛﻪ ﻧﻮع واﻗﻌﻲ ﻳﻚ ﺷﻴﺊ‬ ‫ﭼﻴﺴﺖ و از اﻃﻼﻋﺎت ‪ metadata‬ﺑﺮاي ﻣﺸﺨﺺ ﻛﺮدن اﻳﻨﻜﻪ ﻛﺪام ﻋﻀﻮﻫﺎ از ﻳﻚ ﺷﻲ ﺑﻪ اﺷﻴﺎي دﻳﮕﺮ اﺷﺎره ﻣﻲ ﻛﻨﻨﺪ اﺳﺘﻔﺎده‬ ‫ﻣﻲ ﻛﻨﺪ‪.‬‬

‫ارﺟﺎع ﻫﺎي ﺿﻌﻴﻒ‪:‬‬ ‫زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ‪ root‬ﺑﻪ ﻳﻚ ﺷﻴﺊ اﺷﺎره ﻣﻴﻜﻨﺪ ﺷﻴﺊ ﻧﻤﻴﺘﻮاﻧﺪ ﺗﻮﺳﻂ ‪ Garbage Collector‬ﺟﻤﻊ آوري ﺷﻮد ﭼﻮن‬ ‫ﻣﻤﻜﻦ اﺳﺖ ﺑﺮﻧﺎﻣﻪ ﺑﻪ آن دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﺪ‪ .‬زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ‪ root‬ﺑﻪ ﻳﻚ ﺷﻴﺊ اﺷﺎره ﻣﻴﻜﻨﺪ‪ ،‬اﺻﻄﻼﺣﺎ ﮔﻔﺘﻪ ﻣﻴﺸﻮد ﻛﻪ ﻳﻚ ارﺟﺎع‬ ‫ﻗﻮي ﺑﻪ آن ﺷﻴﺊ ﻣﻮﺟﻮد اﺳﺖ‪ .‬ﺑﺎ اﻳﻦ وﺟﻮد ‪ Garbage Collector‬ﻫﻤﭽﻨﻴﻦ از ارﺟﺎﻋﺎت ﺿﻌﻴﻒ ﻫﻢ ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻴﻜﻨﺪ‪.‬‬ ‫ارﺟﺎﻋﺎت ﺿﻌﻴﻒ ﺑﻪ ‪ Garbage Collector‬اﺟﺎزه ﻣﻲ دﻫﻨﺪ ﻛﻪ ﺷﻴﺊ را ﺟﻤﻊ آوري ﻛﻨﺪ و ﻫﻤﭽﻨﻴﻦ ﺑﻪ ﺑﺮﻧﺎﻣﻪ اﺟﺎزه دﻫﺪ‬ ‫ﻛﻪ ﺑﻪ آن ﺷﻴﺊ دﺳﺘﺮﺳﻲ داﺷﺘﻪ ﺑﺎﺷﺪ‪.‬‬ ‫اﮔﺮ ﻓﻘﻂ ارﺟﺎﻋﺎت ﺿﻌﻴﻒ ﺑﻪ ﻳﻚ ﺷﻴﺊ ﻣﻮﺟﻮد ﺑﺎﺷﻨﺪ و ‪ Garbage Collector‬آﻏﺎز ﺑﻪ ﻛﺎر ﻛﻨﺪ آن ﺷﻴﺊ از ‪heap‬‬ ‫ﭘﺎك ﻣﻴﺸﻮد و ﺳﭙﺲ زﻣﺎﻧﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺳﻌﻲ ﻛﻨﺪ ﺑﻪ آن دﺳﺘﺮﺳﻲ ﭘﻴﺪا ﻛﻨﺪ اﻳﻦ ﻋﻤﻞ ﺑﺎ ﺷﻜﺴﺖ ﻣﻮاﺟﻪ ﻣﻴﺸﻮد‪ .‬ﺑﻪ ﻋﺒﺎرت دﻳﮕﺮ ﺑﺮاي‬ ‫دﺳﺘﺮﺳﻲ ﺑﻪ ﻳﻚ ارﺟﺎع ﺿﻌﻴﻒ ﺑﺮﻧﺎﻣﻪ ﺑﺎﻳﺪ ﻳﻚ ارﺟﺎع ﻗﻮي ﺑﻪ آن داﺷﺘﻪ ﺑﺎﺷﺪ‪ .‬اﮔﺮ ﺑﺮﻧﺎﻣﻪ ﻗﺒﻞ از اﻳﻨﻜﻪ ‪Garbage‬‬ ‫‪ Collector‬آن را ﺟﻤﻊ آوري ﻛﻨﺪ ﻳﻚ ارﺟﺎع ﻗﻮي ﺑﻪ آن ﺷﻴﺊ ﺗﺸﻜﻴﻞ دﻫﺪ‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ ‪Garbage Collector‬‬ ‫ﻧﻤﻲ ﺗﻮاﻧﺪ اﻳﻦ ﺷﻴﺊ را ﺣﺬف ﻛﻨﺪ ﭼﻮن ﻳﻚ ارﺟﺎع ﻗﻮي ﺑﻪ آن ﺷﻴﺊ ﻣﻮﺟﻮد اﺳﺖ‪.‬‬ ‫اﺟﺎزه دﻫﻴﺪ ﻣﻌﻨﻲ واﻗﻌﻲ ﻣﻮﺿﻮع را در ﻛﺪ ﺑﺮرﺳﻲ ﻛﻨﻴﻢ‪:‬‬ ‫)(‪Void SomeMethod‬‬ ‫{‬ ‫‪// Create a string reference to a new Object.‬‬ ‫;)(‪Object o = new Object‬‬ ‫‪// Create a strong reference to a short WeakReference object.‬‬ ‫‪// The WeakReference object tracks the Object's lifetime.‬‬ ‫;)‪WeakReference wr = new WeakReference(o‬‬ ‫‪o = null; // Remove the strong reference to the object.‬‬ ‫;‪O = wr.Target‬‬ ‫)‪if(o==null‬‬ ‫{‬ ‫‪// A garbage collection occurred and Object's memory was‬‬ ‫‪// reclaimed.‬‬ ‫}‬ ‫‪else‬‬ ‫{‬ ‫‪//A garbage collection didn't occur and I can successfully‬‬ ‫‪// access the Object using o.‬‬ ‫}‬ ‫}‬

‫ﻣﻤﻜﻦ اﺳﺖ اﻳﻦ ﺳﻮال اﻳﺠﺎد ﺷﻮد ﻛﻪ اﺳﺘﻔﺎده از ارﺟﺎﻋﺎت ﺿﻌﻴﻒ ﭼﻪ ﻣﺰﻳﺘﻲ را اﻳﺠﺎد ﻣﻴﻜﻨﺪ؟ ﺧﻮب ﺑﻌﻀﻲ از ﺳﺎﺧﺘﺎر داده ﻫﺎ ﺑﻪ ﺳﺎدﮔﻲ‬ ‫اﻳﺠﺎد ﻣﻴﺸﻮﻧﺪ اﻣﺎ ﻣﻘﺪار زﻳﺎدي ﺣﺎﻓﻈﻪ را اﺷﻐﺎل ﻣﻲ ﻛﻨﻨﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل ﻣﻤﻜﻦ اﺳﺖ ﺷﻤﺎ ﺑﺮﻧﺎﻣﻪ اي داﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻛﻪ ﺑﻪ ﻟﻴﺴﺘﻲ از ﺗﻤﺎم‬

‫‪٩٤٢‬‬

‫داﻳﺮﻛﺘﻮري ﻫﺎ و ﻓﺎﻳﻠﻬﺎي ﻣﻮﺟﻮد در ﻛﺎﻣﭙﻴﻮﺗﺮ ﻧﻴﺎز داﺷﺘﻪ ﺑﺎﺷﺪ‪ .‬ﺷﻤﺎ ﺑﻪ ﺳﺎدﮔﻲ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ درﺧﺖ از ﺗﻤﺎم اﻳﻦ اﻃﻼﻋﺎت ﺗﺸﻜﻴﻞ دﻫﻴﺪ‬ ‫و ﺑﻪ ﻣﺤﺾ اﻳﻨﻜﻪ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ اﺟﺮا ﺷﺪ ﺑﻪ ﺟﺎي ﻣﺮاﺟﻌﻪ ﺑﻪ ﻫﺎرد ﺑﻪ اﻳﻦ درﺧﺖ در ﺣﺎﻓﻈﻪ ﻣﺮاﺟﻌﻪ ﻛﻨﺪ اﻳﻦ اﻣﺮ ﺳﺮﻋﺖ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ را‬ ‫اﻓﺰاﻳﺶ ﻣﻴﺪﻫﺪ‪.‬‬ ‫اﻣﺎ ﻣﺸﻜﻞ اﻳﻦ اﺳﺖ ﻛﻪ اﻳﻦ ﺳﺎﺧﺘﺎر داده ﺣﺠﻢ ﺑﺴﻴﺎر زﻳﺎدي را از ﺣﺎﻓﻈﻪ اﺷﻐﺎل ﻣﻲ ﻛﻨﺪ‪ .‬اﮔﺮ ﻛﺎرﺑﺮ ﺑﺨﺶ دﻳﮕﺮي از ﺑﺮﻧﺎﻣﻪ را آﻏﺎز ﻛﻨﺪ‪،‬‬ ‫اﻳﻦ درﺧﺖ ﻣﻤﻜﻦ اﺳﺖ دﻳﮕﺮ ﻣﻮرد ﻧﻴﺎز ﻧﺒﺎﺷﺪ اﻣﺎ ﻣﻘﺪار زﻳﺎدي از ﺣﺎﻓﻈﻪ را اﺷﻐﺎل ﻛﺮده اﺳﺖ‪ .‬ﺷﻤﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ارﺟﺎع اﺻﻠﻲ ﺑﻪ اﻳﻦ درﺧﺖ‬ ‫در ﺣﺎﻓﻈﻪ را رﻫﺎ ﻛﻨﻴﺪ‪ .‬اﻣﺎ اﮔﺮ ﻛﺎرﺑﺮ ﺑﻪ ﻗﺴﻤﺖ اول ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺑﺮﮔﺸﺖ‪ ،‬ﺷﻤﺎ ﻣﺠﺪدا ﻧﻴﺎز ﺑﻪ ﺑﺎزﺳﺎزي اﻳﻦ درﺧﺖ ﺧﻮاﻫﻴﺪ داﺷﺖ‪ .‬ارﺟﺎﻋﺎت‬ ‫ﺿﻌﻴﻒ اﻳﻦ اﻣﻜﺎن ار ﺑﻪ ﺷﻤﺎ ﻣﻴﺪﻫﺪ ﻛﻪ ﺑﻪ ﺑﻬﺘﺮﻳﻦ ﻧﺤﻮ اﻳﻦ ﻣﻮﻗﻌﻴﺖ را ﻛﻨﺘﺮل ﻛﻨﻴﺪ‪.‬‬ ‫زﻣﺎﻧﻲ ﻛﻪ ﻛﺎرﺑﺮ از ﻗﺴﻤﺖ اول ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺧﺎرج ﺷﻮد‪ ،‬ﺷﻤﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ ﻳﻚ ارﺟﺎع ﺿﻌﻴﻒ ﺑﻪ ‪ root‬ﻣﺮﺑﻮط ﺑﻪ اﻳﻦ درﺧﺖ در ﺣﺎﻓﻈﻪ‬ ‫اﻳﺠﺎد ﻛﻨﻴﺪ و ﺗﻤﺎم ارﺟﺎﻋﺎت ﻗﻮي ﺑﻪ آن را از ﺑﻴﻦ ﺑﺒﺮﻳﺪ‪ .‬اﮔﺮ ﺣﺎﻓﻈﻪ ﺑﺮاي ﺑﺨﺸﻬﺎي دﻳﮕﺮ ﺑﺮﻧﺎﻣﻪ ﻛﻢ ﺷﺪ‪Garbage ،‬‬ ‫‪ Collector‬ﺣﺎﻓﻈﻪ ﮔﺮﻓﺘﻪ ﺷﺪه ﺗﻮﺳﻂ درﺧﺖ ﻣﺬﻛﻮر را ﻣﻲ ﮔﻴﺮد و زﻣﺎﻧﻲ ﻛﻪ ﻛﺎرﺑﺮ ﻣﺠﺪدا ﺑﻪ ﻗﺴﻤﺖ اول ﺑﺮﻧﺎﻣﻪ ﺑﺮﮔﺸﺖ و‬ ‫ﺑﺮﻧﺎﻣﻪ ﺳﻌﻲ ﻛﺮد از ارﺟﺎع ﺿﻌﻴﻒ ﻳﻚ ارﺟﺎع ﻗﻮي ﺑﺪﺳﺖ آورد‪ ،‬اﻳﻦ ﺗﻼش ﺷﻜﺴﺖ ﻣﻲ ﺧﻮرد و ﺑﺮﻧﺎﻣﻪ ﻣﺠﺪدا درﺧﺖ را ﺗﺸﻜﻴﻞ ﻣﻴﺪﻫﺪ‪.‬‬ ‫در ﻏﻴﺮ اﻳﻦ ﺻﻮرت ﺑﺮﻧﺎﻣﻪ از ﻫﻤﺎن درﺧﺖ ﻗﺒﻠﻲ ﻣﻮﺟﻮد در ﺣﺎﻓﻈﻪ اﺳﺘﻔﺎده ﻣﻲ ﻛﻨﺪ‪.‬‬ ‫ﻧﻮع داده ‪ System.WeakReference‬دو ‪ Constructor‬ﻋﻤﻮﻣﻲ را اراﺋﻪ ﻣﻴﺪﻫﺪ‪:‬‬ ‫;)‪public WeakReference(Object target‬‬ ‫;)‪public WeakReference(Object target, Boolean trackResurrection‬‬

‫ﭘﺎراﻣﺘﺮ ‪ target‬ﺷﻴﺊ را ﻛﻪ ‪ WeakReference‬ﺑﺎﻳﺪ ﻧﮕﻪ داري ﻛﻨﺪ ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ‪ .‬ﭘﺎراﻣﺘﺮ‬ ‫‪ trackResurrection‬ﻣﺸﺨﺺ ﻣﻲ ﻛﻨﺪ ﻛﻪ آﻳﺎ ‪ WeakReference‬ﺑﺎﻳﺪ ﺷﻴﺊ را ﺣﺘﻲ ﺑﻌﺪ از‬ ‫‪ finalize‬ﺷﺪن ﻫﻢ ﻧﮕﻪ داري ﻛﻨﺪ ﻳﺎ ﺧﻴﺮ ﻛﻪ ﻣﻌﻤﻮﻻ ﻣﻘﺪار اﻳﻦ ﭘﺎراﻣﺘﺮ ‪ false‬اﺳﺖ‪.‬‬ ‫ﺑﺮاي راﺣﺘﻲ ﻳﻚ ارﺟﺎع ﺿﻌﻴﻒ را ﻛﻪ ﺑﻌﺪ از اﺣﻴﺎي ﺷﻴﺊ ﻫﻢ آن را ﻧﮕﻪ داري ﻣﻴﻜﻨﺪ ارﺟﺎع ﺿﻌﻴﻒ ﺑﻠﻨﺪ و ارﺟﺎع ﺿﻌﻴﻔﻲ را ﻛﻪ ﺑﻌﺪ از‬ ‫اﺣﻴﺎي ﺷﻴﺊ آن را ﻧﮕﻪ داري ﻧﻤﻲ ﻛﻨﺪ را ارﺟﺎع ﺿﻌﻴﻒ ﻛﻮﺗﺎه ﻣﻲ ﻧﺎﻣﻴﻢ‪ .‬اﮔﺮ ﻧﻮع داده ﺷﻴﺊ ﺗﺎﺑﻊ ‪ finalize‬را ارﺋﻪ ﻧﺪﻫﺪ ارﺟﺎع‬ ‫ﺿﻌﻴﻒ ﻛﻮﺗﺎه و ﺑﻠﻨﺪ ﻣﺎﻧﻨﺪ ﻫﻢ ﻋﻤﻞ ﻣﻲ ﻛﻨﻨﺪ‪ .‬اﻣﺎ ﺑﻪ ﺷﺪت ﺗﻮﺻﻴﻪ ﻣﻲ ﺷﻮد ﻛﻪ از ﺑﻪ ﻛﺎر ﺑﺮدن ارﺟﺎﻋﺎت ﺿﻌﻴﻒ ﺧﻮدداري ﻛﻨﻴﺪ‪ ،‬زﻳﺮا اﻳﻦ‬ ‫ﻧﻮع ارﺟﺎﻋﺎت ﺑﻪ ﺷﻤﺎ اﺟﺎزه ﻣﻴﺪﻫﻨﺪ ﻛﻪ ﻳﻚ ﺷﻴﺊ را ﺣﺘﻲ ﺑﻌﺪ از ‪ finalize‬ﺷﺪن ﻫﻢ اﺣﻴﺎ ﻛﻨﻴﺪ ﻛﻪ ﻣﻮﺟﺐ ﺑﻪ وﺟﻮد آﻣﺪن ﻳﻚ‬ ‫ﻣﻮﻗﻌﻴﺖ ﻏﻴﺮ ﻗﺎﺑﻞ ﭘﻴﺶ ﺑﻴﻨﻲ ﺑﺮاي ﺷﻴﺊ ﻣﻲ ﺷﻮد‪.‬‬ ‫ﻳﻚ ﺑﺎر ﻛﻪ ﺷﻤﺎ ﻳﻚ ارﺟﺎع ﺿﻌﻴﻒ را ﺑﺮاي ﻳﻚ ﺷﻴﺊ اﻳﺠﺎد ﻛﺮدﻳﺪ ﻋﻤﻮﻣﺎ ﺑﺎﻳﺪ ﺗﻤﺎم ارﺟﺎﻋﺎت ﻗﻮي ﺑﻪ آن را ﺑﺮاﺑﺮ ‪ null‬ﻗﺮار دﻫﻴﺪ‪ ،‬در‬ ‫ﻏﻴﺮ اﻳﻦ ﺻﻮرت ‪ Garbage Collector‬ﺗﻮاﻧﺎﻳﻲ ﺟﻤﻊ آوري اﻳﻦ ﺷﻴﺊ را در ﻣﻮاﻗﻊ ﺿﺮوري ﻧﺨﻮاﻫﺪ داﺷﺖ‪.‬‬ ‫ﺑﺮاي اﺳﺘﻔﺎده ﻣﺠﺪد ﺷﻴﺊ ﺷﻤﺎ ﺑﺎﻳﺪ ارﺟﺎع ﺿﻌﻴﻒ را ﺑﻪ ﻳﻚ ارﺟﺎع ﻗﻮي ﺗﺒﺪﻳﻞ ﻛﻨﻴﺪ‪ .‬ﺑﺮاي اﻳﻦ ﻛﺎر ﺷﻤﺎ ﻣﻲ ﺗﻮاﻧﻴﺪ از‬ ‫‪ WeakReference.Target‬اﺳﺘﻔﺎده ﻛﻨﻴﺪ و اﻳﻦ ﺷﻴﺊ را ﺑﻪ ﻳﻜﻲ از ‪ root‬ﻫﺎي ﺑﺮﻧﺎﻣﻪ اﺧﺘﺼﺎص دﻫﻴﺪ‪ .‬اﮔﺮ اﻳﻦ‬ ‫ﻋﺒﺎرت ﻣﻘﺪار ‪ null‬را ﺑﺮﮔﺮداﻧﺪ‪ ،‬ﻳﻌﻨﻲ ﺷﻴﺊ ﻣﺬﻛﻮر ﺗﻮﺳﻂ ‪ Garbage Collector‬ﺟﻤﻊ آوري ﺷﺪه اﺳﺖ‪ ،‬در ﻏﻴﺮ اﻳﻦ‬ ‫ﺻﻮرت ‪ root‬ﺣﺎوي آدرس ﻳﻚ ارﺟﺎع ﻗﻮي ﺑﻪ اﻳﻦ ﻣﻘﺪار ﻣﺤﺴﻮب ﻣﻲ ﺷﻮد و ﺑﺮﻧﺎﻣﻪ از اﻳﻦ ﻃﺮﻳﻖ ﻣﻲ ﺗﻮاﻧﺪ ﺷﻴﺊ ﻣﺬﻛﻮر را ﻛﻨﺘﺮل‬ ‫ﻛﻨﺪ‪.‬‬

‫‪٩٤٣‬‬

‫ﻧﺴﻠﻬﺎ‪:1‬‬ ‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﭘﻴﺸﺘﺮ ذﻛﺮ ﺷﺪ ﻧﺴﻠﻬﺎ ﻣﻜﺎﻧﻴﺴﻤﻲ درون ‪ CLR Garbage Collector‬ﺑﻪ ﺷﻤﺎر ﻣﻴﺮود ﻛﻪ ﻫﺪف اﺻﻠﻲ آن‬ ‫ﺑﻬﺒﻮد ﻛﺎراﻳﻲ ﺑﺮﻧﺎﻣﻪ اﺳـﺖ‪ .‬ﻳـﻚ ‪ Garbage Collector‬ﻛـﻪ ﺑـﺎ ﻣﻜﺎﻧﻴـﺴﻢ ﻧـﺴﻠﻬﺎ ﻛـﺎر ﻣﻴﻜﻨـﺪ )ﻫﻤﭽﻨـﻴﻦ ﺑـﻪ ﻋﻨـﻮان‬ ‫‪ Garbage Collector‬زودﮔﺬر‪ 2‬ﻫﻢ ﻧﺎﻣﻴﺪه ﻣﻴﺸﻮد( ﻓﺮﺿﻬﺎي زﻳﺮ را ﺑﺮاي ﻛﺎر ﺧﻮد در ﻧﻈﺮ ﻣﻴﮕﻴﺮد‪:‬‬ ‫‪ (1‬ﻫﺮ ﭼﻪ ﻳﻚ ﺷﻴﺊ ﺟﺪﻳﺪﺗﺮ اﻳﺠﺎد ﺷﺪه ﺑﺎﺷﺪ ﻃﻮل ﻋﻤﺮ ﻛﻮﺗﺎﻫﺘﺮي ﻫﻢ ﺧﻮاﻫﺪ داﺷﺖ‪.‬‬ ‫‪ (2‬ﻫﺮ ﭼﻪ ﻳﻚ ﺷﻴﺊ ﻗﺪﻳﻤﻴﺘﺮ ﺑﺎﺷﺪ ﻃﻮل ﻋﻤﺮ ﺑﻠﻨﺪﺗﺮي ﻫﻢ ﺧﻮاﻫﺪ داﺷﺖ‪.‬‬ ‫‪ (3‬ﺟﻤﻊ آوري ﻗﺴﻤﺘﻲ از ‪ heap‬ﺳﺮﻳﻌﺘﺮ از ﺟﻤﻊ آوري ﻛﻞ آن اﺳﺖ‪.‬‬ ‫ﻣﻄﺎﻟﻌﺎت زﻳﺎدي ﻣﻌﺘﺒﺮ ﺑﻮدن اﻳﻦ ﻓﺮﺿﻴﺎت را ﺑﺮاي ﻣﺠﻤﻮﻋﻪ ﺑﺰرﮔﻲ از ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﻣﻮﺟﻮد ﺗﺎﻳﻴﺪ ﻛﺮده اﻧﺪ و اﻳﻦ ﻓﺮﺿﻴﺎت ﺑـﺮ ﻃـﺮز ﭘﻴـﺎده‬ ‫ﺳﺎزي ‪ Garbage Collector‬ﺗﺎﺛﻴﺮ داﺷﺘﻪ اﻧﺪ‪ .‬در اﻳﻦ ﻗﺴﻤﺖ ﻃﺮز ﻛﺎر اﻳﻦ ﻣﻜﺎﻧﻴﺴﻢ ﺷﺮح داده ﺷﺪه اﺳﺖ‪.‬‬ ‫زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ‪ managed heap‬ﺑﺮاي ﺑﺎر اول اﻳﺠﺎد ﻣﻴﺸﻮد داراي ﻫﻴﭻ ﺷﻴﺊ ﻧﻴﺴﺖ‪ .‬اﺷﻴﺎﻳﻲ ﻛﻪ ﺑﻪ ‪ heap‬اﺿـﺎﻓﻪ ﺷـﻮﻧﺪ در‬ ‫ﻧﺴﻞ ﺻﻔﺮ ﻗﺮار ﻣﻴﮕﻴﺮﻧﺪ‪ .‬اﺷﻴﺎي ﻣﻮﺟﻮد در ﻧﺴﻞ ﺻـﻔﺮ اﺷـﻴﺎي ﺗـﺎزه اﻳﺠـﺎد ﺷـﺪه اي ﻫـﺴﺘﻨﺪ ﻛـﻪ ﺗـﺎ ﻛﻨـﻮن ﺗﻮﺳـﻂ ‪Garbage‬‬ ‫‪ Collector‬ﺑﺮرﺳﻲ ﻧﺸﺪه اﻧﺪ‪ .‬ﺗﺼﻮﻳﺮ زﻳﺮ ﻳﻚ ﺑﺮﻧﺎﻣﻪ را ﻛﻪ ﺗﺎزه آﻏﺎز ﺑﻪ ﻛﺎر ﻛـﺮده اﺳـﺖ ﻧـﺸﺎن ﻣﻴﺪﻫـﺪ ﻛـﻪ داراي ﭘـﻨﺞ ﺷـﻴﺊ‬ ‫اﺳﺖ)از ‪ A‬ﺗﺎ ‪ .( E‬ﺑﻌﺪ از ﻣﺪﺗﻲ اﺷﻴﺎي ‪ C‬و ‪ E‬ﻏﻴﺮ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﻣﻴﺸﻮﻧﺪ‪.‬‬

‫زﻣﺎﻧﻲ ﻛﻪ ‪ CLR‬آﻏﺎز ﺑﻪ ﻛﺎر ﻣﻴﻜﻨﺪ ﻳﻚ ﻣﻘﺪار ﻧﻬﺎﻳﻲ را ﺑﺮاي ﻧﺴﻞ ﺻﻔﺮ در ﻧﻈﺮ ﻣﻴﮕﻴﺮد ﻛـﻪ ﺑـﻪ ﻃـﻮر ﭘـﻴﺶ ﻓـﺮض ‪ 256‬ﻛﻴﻠـﻮ ﺑﺎﻳـﺖ‬ ‫اﺳﺖ)اﻟﺒﺘﻪ اﻳﻦ ﻣﻘﺪار ﻣﻮرد ﺗﻐﻴﻴﺮ ﻗﺮار ﻣﻴﮕﻴﺮد(‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ﺷﻴﺊ ﺑﺨﻮاﻫﺪ اﻳﺠﺎد ﺷﻮد و در ﻧﺴﻞ ﺻﻔﺮ ﻓﻀﺎي ﻛـﺎﻓﻲ وﺟـﻮد ﻧﺪاﺷـﺘﻪ ﺑﺎﺷـﺪ‬ ‫‪ Garbage Collector‬آﻏﺰ ﺑﻪ ﻛﺎر ﻣﻴﻜﻨﺪ‪ .‬اﺟﺎزه دﻫﻴﺪ ﺗﺼﻮر ﻛﻨﻴﻢ ﻛﻪ اﺷﻴﺎي ‪ A‬ﺗﺎ ‪ 256 E‬ﻛﻴﻠﻮ ﺑﺎﻳﺖ ﻓﻀﺎ اﺷﻐﺎل ﻛـﺮده‬ ‫اﻧـﺪ زﻣـﺎﻧﻲ ﻛـﻪ ﺷـﻴﺊ ‪ F‬ﺑﺨﻮاﻫـﺪ ﺗـﺸﻜﻴﻞ ﺷـﻮد ‪ Garbage Collector‬ﺑﺎﻳـﺪ آﻏـﺎز ﺑـﻪ ﻛـﺎر ﻛﻨـﺪ‪Garbage .‬‬ ‫‪ Collector‬ﺗﺸﺨﻴﺺ ﻣﻴﺪﻫﺪ ﻛﻪ اﺷﻴﺎي‪ C‬و ‪ E‬زﺑﺎﻟﻪ ﻣﺤﺴﻮب ﻣﻴﺸﻮﻧﺪ و ﺑﻨﺎﺑﺮاﻳﻦ ﺷﻴﺊ ‪ D‬ﺑﺎﻳﺪ ﻓﺸﺮده ﺷﻮد ﺑﻨﺎﺑﺮاﻳﻦ اﻳﻦ ﺷﻴﺊ‬ ‫ﺑﻪ ﻛﻨﺎر ﺷﻴﺊ ‪ B‬ﻣﻴﺮود‪ .‬اﺷﻴﺎﻳﻲ ﻛﻪ ﺑﻌﺪ از اﻳﻦ ﻣﺮﺣﻠﻪ ﺑﺎﻗﻲ ﻣﻴﻤﺎﻧﻨﺪ )اﺷﻴﺎي ‪ A‬و ‪ B‬و ‪ (D‬وارد ﻧﺴﻞ ﻳﻚ ﻣﻴﺸﻮﻧﺪ‪ .‬اﺷﻴﺎي ﻣﻮﺟﻮد در ﻧـﺴﻞ‬ ‫ﻳﻚ ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ ﻫﺴﺘﻨﺪ ﻛﻪ ﻳﻚ ﺑﺎر ﺗﻮﺳﻂ ‪ Garbage Collector‬ﺑﺮرﺳﻲ ﺷﺪه اﻧﺪ‪ Heap .‬ﺑﺮﻧﺎﻣـﻪ ﻣﻔـﺮوض ﺑﻌـﺪ از‬ ‫اوﻟﻴﻦ ﻣﺮﺣﻠﻪ ﺑﻪ ﺻﻮرت ﺗﺼﻮﻳﺮ زﻳﺮ در ﻣﻲ آﻳﻨﺪ‪.‬‬

‫‪Generations‬‬ ‫‪Ephemeral Garbage Collector‬‬

‫‪1‬‬ ‫‪2‬‬

‫‪٩٤٤‬‬

‫ﺑﻌﺪ از ﻳﻚ ﺑﺎر اﺟﺮاي ‪ Garbage Collector‬ﻫﻴﭻ ﺷﻴﺊ در ﻧﺴﻞ ﺻﻔﺮ ﺑﺎﻗﻲ ﻧﻤﻲ ﻣﺎﻧﺪ‪ .‬ﻣﺜﻞ ﻫﻤﻴﺸﻪ اﺷﻴﺎﻳﻲ ﻛﻪ ﺑﻌﺪ از اﻳﻦ‬ ‫اﻳﺠﺎد ﻣﻲ ﺷﻮﻧﺪ ﺑﻪ ﻧﺴﻞ ﺻﻔﺮ اﺿﺎﻓﻪ ﻣﻴﺸﻮﻧﺪ‪ .‬ﺷﻜﻞ زﻳﺮ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ و ﺑﻪ وﺟﻮد آﻣﺪن اﺷﻴﺎي ‪ F‬ﺗﺎ ‪ K‬را ﻧـﺸﺎن ﻣﻴﺪﻫـﺪ‪ .‬ﺑـﻪ ﻋـﻼوه در‬ ‫ﻃﻮل اﺟﺮاي ﺑﺮﻧﺎﻣﻪ اﺷﻴﺎي‪ B‬و ‪ H‬و ‪ J‬ﻏﻴﺮ ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﺷﺪه اﻧﺪ و ﺣﺎﻓﻈﻪ ﮔﺮﻓﺘﻪ ﺷﺪه ﺗﻮﺳﻂ آﻧﻬﺎ ﺑﺎﻳﺪ آزاد ﺷﻮد‪.‬‬

‫ﺣﺎل ﻓﺮض ﻛﻨﻴﻢ ﺑﺎ ﺗﺨﺼﻴﺺ ﺣﺎﻓﻈﻪ ﺑﺮاي ﺷﻲ‪ L‬در ﻧﺴﻞ ﺻﻔﺮ ﻣﻘﺪار داده ﻫﺎي ﻣﻮﺟﻮد در اﻳﻦ ﻧﺴﻞ از ‪256‬ﻛﻴﻠﻮﺑﺎﻳﺖ ﻓﺮاﺗﺮ رود‪ .‬ﭼﻮن‬ ‫ﻧﺴﻞ ﺻﻔﺮ ﺑﻪ ﺳﺮ ﺣﺪ ﺧﻮد رﺳﻴﺪه اﺳﺖ ‪ Garbage Collector‬ﺑﺎﻳﺪ آﻏﺎز ﺑﻪ ﻛﺎر ﻛﻨﺪ‪ .‬زﻣﺎﻧﻲ ﻛﻪ ﻋﻤـﻞ ‪Garbage‬‬ ‫‪ Collection‬آﻏﺎز ﻣﻴﺸﻮد ‪ Garbage Collector‬ﺑﺎﻳﺪ ﺗﺼﻤﻴﻢ ﺑﮕﻴﺮد ﻛﻪ ﻛﺪام ﻧـﺴﻞ ﺑﺎﻳـﺪ ﻣـﻮرد ﺑﺮرﺳـﻲ ﻗـﺮار‬ ‫ﮔﻴﺮد‪ .‬ﭘﻴﺸﺘﺮ ذﻛﺮ ﺷﺪ ﻛﻪ زﻣﺎﻧﻲ ﻛﻪ ‪ CLR‬آﻏﺎز ﺑﻪ ﻛﺎر ﻣﻴﻜﻨﺪ ﺑﺮاي ﻧﺴﻞ ﺻﻔﺮ ‪ 256‬ﻛﻴﻠﻮ ﺑﺎﻳﺖ ﻓﻀﺎ اﺧﺘﺼﺎص ﻣﻴﺪﻫﺪ‪ .‬ﻫﻤﭽﻨﻴﻦ ‪CLR‬‬ ‫ﻳﻚ ﺳﺮ ﺣﺪ ﻧﻴﺰ ﺑﺮاي ﻧﺴﻞ ﻳﻚ در ﻧﻈﺮ ﻣﻴﮕﻴﺮد‪ .‬ﻓﺮض ﻣﻴﻜﻨﻴﻢ اﻳﻦ ﻣﻘﺪار ﻓﻀﺎ ﺷﺎﻣﻞ ‪ 2‬ﻣﮕﺎ ﺑﺎﻳﺖ ﺑﺎﺷﺪ‪.‬‬ ‫زﻣﺎﻧﻲ ﻛﻪ ﻋﻤﻞ ‪ Garbage Collection‬اﻧﺠﺎم ﻣﻴﺸﻮد‪ Garbage Collector،‬ﻫﻤﭽﻨﻴﻦ ﺑﺮرﺳﻲ ﻣﻴﻜﻨﺪ‬ ‫ﻛﻪ ﭼﻪ ﻣﻘﺪار ﻓﻀﺎ ﺗﻮﺳﻂ ﻧﺴﻞ ﻳﻚ اﺷﻐﺎل ﺷﺪه اﺳﺖ‪ .‬در اﻳﻦ ﺣﺎﻟﺖ ﻧﺴﻞ ﻳﻚ ﻓﻀﺎﻳﻲ ﻛﻤﺘﺮ از ‪ 2‬ﻣﮕﺎ ﺑﺎﻳﺖ را اﺷﻐﺎل ﻛﺮده اﺳﺖ ﺑﻨـﺎﺑﺮاﻳﻦ‬ ‫‪ Garbage Collector‬ﻓﻘﻂ ﻧﺴﻞ ﺻـﻔﺮ را ﻣـﻮرد ﺑﺮرﺳـﻲ ﻗـﺮار ﻣﻴﺪﻫـﺪ‪ .‬ﻳـﻚ ﺑـﺎر دﻳﮕـﺮ ﻓﺮﺿـﻴﺎت ‪Garbage‬‬ ‫‪ Collector‬را ﻛﻪ در اﺑﺘﺪا ذﻛﺮ ﺷﺪ ﻣﺮور ﻛﻨﻴﺪ‪ .‬اوﻟﻴﻦ ﻓﺮض اﻳﻦ ﺑﻮد ﻛﻪ اﺷﻴﺎي ﺗﺎزه اﻳﺠﺎد ﺷﺪه داراي ﻋﻤﺮ ﻛﻮﺗﺎه ﺗـﺮي ﻫـﺴﺘﻨﺪ‪.‬‬ ‫ﺑﻨﺎﺑﺮاﻳﻦ اﻳﻦ ﮔﻮﻧﻪ ﺑﻪ ﻧﻈﺮ ﻣﻴﺮﺳﺪ ﻛﻪ ﻧﺴﻞ ﺻﻔﺮ داراي ﺑﻴﺸﺘﺮﻳﻦ ﻣﻘﺪار زﺑﺎﻟﻪ ﺑﺎﺷﺪ و ﺟﻤﻊ آوري ﺣﺎﻓﻈﻪ از اﻳﻦ ﻧـﺴﻞ ﻣﻮﺟـﺐ آزاد ﺳـﺎزي‬ ‫ﻣﻘﺪار زﻳﺎدي ﺣﺎﻓﻈﻪ ﻣﻴﺸﻮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ‪ Garbage Collector‬ﻧﺴﻞ ﻳﻚ را رﻫﺎ ﻣﻴﻜﻨﺪ و ﻓﻘﻂ ﺑﻪ ﺟﻤـﻊ آوري ﻧـﺴﻞ ﺻـﻔﺮ‬ ‫ﻣﻴﭙﺮدازد ﻛﻪ اﻳﻦ ﻋﻤﻞ ﻣﻮﺟﺐ اﻓﺰاﻳﺶ ﺳﺮﻋﺖ ﻛﺎرﻛﺮد ﭘﺮوﺳﻪ ‪ Garbage Collector‬ﻣﻴﺸﻮد‪.‬‬ ‫ﺑﻪ وﺿﻮح‪ ،‬رﻫﺎ ﺳﺎزي اﺷﻴﺎي ﻧﺴﻞ ﻳﻚ وﺟﺐ اﻓﺰاﻳﺶ ﺳﺮﻋﺖ و ﻛـﺎراﻳﻲ ‪ Garbage Collector‬ﻣﻴـﺸﻮد‪ .‬ﺑـﺎ وﺟـﻮد اﻳـﻦ‬ ‫ﻛﺎراﻳﻲ ‪ Garbage Collector‬ﺑﻴﺸﺘﺮ اﻓﺰاﻳﺶ ﭘﻴﺪا ﻣﻴﻜﻨﺪ ﭼـﻮن ﺗﻤـﺎم اﺷـﻴﺎي ﻣﻮﺟـﻮد در ‪ Managed Heap‬را‬ ‫ﺑﺮرﺳـﻲ ﻧﻤﻴﻜﻨـﺪ‪ .‬اﮔـﺮ ﻳـﻚ ‪ root‬ﻳـﺎ ﻳـﻚ ﺷـﻴﺊ از اﻳـﻦ ﻧـﺴﻞ ﺑـﻪ ﺷـﻴﺊ از ﻧـﺴﻞ ﻗـﺪﻳﻤﻲ ﺗـﺮ اﺷـﺎره ﻛﻨـﺪ‪Garbage ،‬‬ ‫‪ Collector‬ﻣﻴﺘﻮاﻧﺪ ارﺟﺎﻋﺎت داﺧﻠﻲ اﺷﻴﺎي ﻗﺪﻳﻤﻲ ﺗﺮ را در ﻧﻈﺮ ﻧﮕﻴﺮد‪ ،‬و ﺑﺪﻳﻦ وﺳﻴﻠﻪ زﻣﺎن ﻣﻮرد ﻧﻴﺎز را ﺑﺮاي ﺗﺸﻜﻴﻞ ﮔﺮاﻓﻲ از‬ ‫اﺷﻴﺎي ﻗﺎﺑﻞ دﺳﺘﺮس ﻛﺎﻫﺶ ﻣﻴﺪﻫﺪ‪ .‬اﻟﺒﺘﻪ اﻳﻦ اﻣﺮ ﻣﻤﻜﻦ اﺳﺖ ﻛﻪ ﻳﻚ ﺷﻴﺊ ﻗﺪﻳﻤﻲ ﺑﻪ ﻳﻚ ﺷﻴﺊ ﺟﺪﻳﺪ اﺷﺎره ﻛﻨـﺪ‪ .‬ﺑـﺮاي اﻃﻤﻴﻨـﺎن از‬ ‫اﻳﻦ ﻛﻪ اﻳﻦ ﺷﻴﺊ ﻗﺪﻳﻤﻲ ﻧﻴﺰ ﻣﻮرد ﺑﺮرﺳﻲ ﻗﺮار ﻣﻴﮕﻴﺮد ‪ Garbage Collector‬از ﻳﻚ ﻣﻜﺎﻧﻴﺴﻢ داﺧﻠـﻲ ‪ JIT‬اﺳـﺘﻔﺎده‬ ‫ﻣﻴﻜﻨﺪ ﺑﻪ اﻳﻦ ﻧﺤﻮ ﻛﻪ زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﻓﻴﻠﺪ ارﺟﺎع ﻳﻚ ﺷﻴﺊ ﺗﻐﻴﻴﺮ ﻛﺮد ﻳﻚ ﺑﻴﺖ را ﺗﻨﻈﻴﻢ ﻣﻴﻜﻨـﺪ‪ .‬اﻳـﻦ ﭘـﺸﺘﻴﺒﺎﻧﻲ ﺗﻮﺳـﻂ ‪ JIT‬ﺑﺎﻋـﺚ‬ ‫ﻣﻴﺸﻮد ﻛﻪ ‪ Garbage Collector‬ﺑﺘﻮاﻧﺪ ﺗﺸﺨﻴﺺ دﻫﺪ ﻛﺪام از اﺷﻴﺎي ﻗﺪﻳﻤﻲ از زﻣﺎن آﺧﺮﻳﻦ ﻋﻤﻞ ﺟﻤﻊ آوري ﺗﺎ ﻛﻨﻮن‬ ‫ﺗﻐﻴﻴﺮ ﻛﺮده اﻧﺪ‪ .‬ﻓﻘﻂ اﺷﻴﺎي ﻗﺪﻳﻤﻲ ﻛﻪ داراي ﻓﻴﻠﺪ ﻫﺎي ﺗﻐﻴﻴﺮ ﻛﺮده ﻫﺴﺘﻨﺪ اﺣﺘﻴﺎج ﺑﻪ ﺑﺮرﺳﻲ ﺷﺪن ﺑﺮاي اﻳﻨﻜﻪ آﻳﺎ ﺑﻪ ﺷﻴﺌﻲ از ﻧﺴﻞ ﺻﻔﺮ‬ ‫اﺷﺎره ﻣﻴﻜﻨﻨﺪ اﺣﺘﻴﺎج دارﻧﺪ‪.‬‬

‫‪٩٤٥‬‬

‫ﻧﻜﺘﻪ‪ :‬ﺗﺴﺘﻬﺎي ﻛﺎراﻳﻲ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﻧﺸﺎن ﻣﻴﺪﻫﻨﺪ ﻛﻪ ﻋﻤﻞ ‪ Garbage Collection‬در ﻧﺴﻞ ﺻﻔﺮ ﻛﻤﺘﺮ از ﻳﻚ ﻣﻴﻠﻲ‬ ‫ﺛﺎﻧﻴﻪ در ﻳﻚ ﻛﺎﻣﭙﻴﻮﺗﺮ ﭘﻨﺘﻴﻮم ﺑﺎ ﺳﺮﻋﺖ ‪ 200‬ﻣﮕﺎ ﻫﺮﺗﺰ زﻣﺎن ﻣﻴﺒﺮد‪.‬‬ ‫ﻳﻚ ‪ Garbage Collector‬ﻛﻪ از ﻧﺴﻠﻬﺎ اﺳﺘﻔﺎده ﻣﻴﻜﻨﺪ ﻫﻤﭽﻨﻴﻦ ﺗﺼﻮر ﻣﻴﻜﻨﺪ ﻛﻪ اﺷﻴﺎﻳﻲ ﻛﻪ ﻣﺪت زﻳﺎدي اﺳـﺖ ﻛـﻪ در‬ ‫ﺣﺎﻓﻈﻪ ﻣﺎﻧﺪه اﻧﺪ ﺑﻪ زودي ﻧﻴﺰ از ﺣﺎﻓﻈﻪ ﺧﺎرج ﻧﻤﻴﺸﻮﻧﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ اﻳﻦ اﺣﺘﻤﺎل ﻣﻴﺮود ﻛﻪ اﺷﻴﺎي ﻣﻮﺟﻮد در ﻧﺴﻞ ﻳـﻚ ﻫﻤﭽﻨـﺎن در ﻃـﻮل‬ ‫ﺑﺮﻧﺎﻣﻪ ﻗﺎﺑﻞ دﺳﺘﺮس ﺧﻮاﻫﻨﺪ ﺑﻮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ اﮔﺮ ‪ Garbage Collector‬اﺷﻴﺎي ﻣﻮﺟﻮد در ﻧﺴﻞ ﻳﻚ را ﺑﺮرﺳﻲ ﻛﻨﺪ اﺣﺘﻤﺎﻻ‬ ‫ﻣﻘﺪار زﻳﺎدي ﻣﺘﻐﻴﻴﺮ ﻏﻴﺮ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ در ﺑﺮﻧﺎﻣﻪ ﻧﺨﻮاﻫﺪ ﻳﺎﻓﺖ و اﺣﺘﻤﺎﻻ ﺣﺎﻓﻈﻪ زﻳﺎدي را آزاد ﻧﺨﻮاﻫﺪ ﻛﺮد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ آزاد ﺳـﺎزي ﻧـﺴﻞ‬ ‫ﻳﻚ ﭼﻴﺰي ﺟﺰ اﺗﻼف وﻗﺖ ﻧﺨﻮاﻫﺪ ﺑﻮد‪ .‬اﮔﺮ ﻫﺮ زﺑﺎﻟﻪ اي در ﻧﺴﻞ ﻳﻚ ﺑﻪ وﺟﻮد ﺑﻴﺎﻳﺪ در ﻫﻤﺎن ﻧﺴﻞ ﺑﺎﻗﻲ ﺧﻮاﻫـﺪ ﻣﺎﻧـﺪ‪ .‬ﺑﻌـﺪ از اﺟـﺮاي‬ ‫ﻋﻤﻠﻴﺎت ذﻛﺮ ﺷﺪه ﺷﻜﻞ ‪ heap‬ﺑﻪ ﺻﻮرت زﻳﺮ در ﻣﻲ آﻳﻨﺪ‪.‬‬

‫ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﻣﻴﺒﻴﻨﻴﺪ ﺗﻤﺎم اﺷﻴﺎي ﻛﻪ از ﻧﺴﻞ ﺻﻔﺮ ﺑﺎﻗﻲ ﻣﺎﻧﺪه اﻧﺪ وارد ﻧﺴﻞ ﻳﻚ ﺷﺪه اﻧـﺪ‪ .‬ﭼـﻮن ‪Garbage Collector‬‬ ‫ﻧﺴﻞ ﻳﻚ را ﺑﺮرﺳﻲ ﻧﻤﻴﻜﻨﺪ ﺷﻴﺊ‪ B‬ﺣﺎﻓﻈﻪ اي را ﻛﻪ ﮔﺮﻓﺘﻪ اﺳـﺖ آزاد ﻧﻤﻴﻜﻨـﺪ ﺑـﺎ وﺟـﻮد اﻳﻨﻜـﻪ از آﺧـﺮﻳﻦ ﻋﻤـﻞ ‪Garbage‬‬ ‫‪ Collector‬ﺗﺎ ﻛﻨﻮن اﻳﻦ ﻣﺘﻐﻴﻴﺮ در ﺑﺮﻧﺎﻣﻪ ﻗﺎﺑﻞ اﺳﺘﻔﺎده ﻧﺒﻮده اﺳﺖ‪ .‬ﻣﺠﺪدا ﺑﻌـﺪ از ﺟﻤـﻊ آوري ﻧـﺴﻞ ﺻـﻔﺮ داراي ﻫـﻴﭻ ﺷـﻴﺊ‬ ‫ﻧﺨﻮاﻫﺪ ﺑﻮد و ﺑﻨﺎﺑﺮاﻳﻦ ﻣﻜﺎﻧﻲ ﺑﺮاي ﻗﺮارﮔﻴﺮي اﺷﻴﺎي ﺟﺪﻳﺪ ﻣﺤﺴﻮب ﻣﻴﺸﻮد‪ .‬در اداﻣﻪ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﻛﺎر ﺧﻮد اداﻣﻪ ﻣﻴﺪﻫﺪ و اﺷـﻴﺎي ‪ L‬ﺗـﺎ ‪O‬‬ ‫را اﻳﺠﺎد ﻣﻴﻜﻨﺪ‪ .‬و در ﺣﺎل اﺟﺮا ﺑﺮﻧﺎﻣﻪ اﺳﺘﻔﺎده از اﺷﻴﺎي ‪ G‬و ‪ L‬و ‪ M‬را ﭘﺎﻳﺎن ﻣﻴﺪﻫـﺪ و آﻧﻬـﺎ را ﻏﻴـﺮ ﻗﺎﺑـﻞ دﺳـﺘﺮس ﻣﻴﻜﻨـﺪ‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ‬ ‫‪ heap‬ﺑﻪ ﺻﻮرت زﻳﺮ ﺗﺒﺪﻳﻞ ﻣﻴﺸﻮد‪.‬‬

‫اﺟﺎزه دﻫﻴﺪ ﻓﻜﺮ ﻛﻨﻴﻢ ﻛﻪ ﺗﺨﺼﻴﺺ ﺣﺎﻓﻈﻪ ﺑﺮاي ﺷﻴﺊ ‪ P‬ﺑﺎﻋﺚ ﺗﺠﺎوز ﻧﺴﻞ ﺻﻔﺮ از ﺳﺮ ﺣﺪ ﺧﻮد ﺷﻮد و اﻳﻦ ﻋﻤﻞ ﻣﻮﺟﺐ اﺟﺮاي ﻣﺠﺪد‬ ‫‪ Garbage Collector‬ﺷﻮد‪ .‬ﭼﻮن ﺗﻤﺎم اﺷﻴﺎي ﻣﻮﺟـﻮد در ﻧـﺴﻞ ﻳـﻚ ﻛﻤﺘـﺮ از ‪ 2‬ﻣﮕـﺎ ﺑﺎﻳـﺖ اﺳـﺖ ‪Garbage‬‬ ‫‪ Collector‬ﻣﺠﺪدا ﺗﺼﻤﻴﻢ ﻣﻴﮕﻴﺮد ﻛﻪ ﻓﻘﻂ ﻧﺴﻞ ﺻﻔﺮ را ﺑﺮرﺳﻲ ﻛﻨﺪ و از اﺷﻴﺎي ﻏﻴﺮ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ در ﻧﺴﻞ ﻳﻚ ﭼﺸﻢ ﭘﻮﺷﻲ‬ ‫ﻛﻨﺪ)اﺷﻴﺎي ‪ B‬و ‪ .(G‬ﺑﻌﺪ از ﻋﻤﻞ ﺟﻤﻊ آوري ‪ heap‬ﺑﻪ ﺻﻮرت زﻳﺮ در ﻣﻲ آﻳﺪ‪.‬‬

‫‪٩٤٦‬‬

‫در ﺗﺼﻮﻳﺮ ﺑﺎﻻ‪ ،‬ﻣﺸﺎﻫﺪه ﻣﻴﻜﻨﻴﺪ ﻛﻪ ﻧﺴﻞ ﻳﻚ ﺑﻪ ﻣﺮور در ﺣﺎل رﺷﺪ و اﻓﺰاﻳﺶ ﺣﺠﻢ اﺳﺖ‪ .‬اﺟﺎزه دﻫﻴﺪ ﺗﺼﻮر ﻛﻨﻴﻢ ﻛﻪ اﺷﻴﺎي ﻣﻮﺟـﻮد در‬ ‫ﻧﺴﻞ ﻳﻚ ﺗﺎ ﺳﺮ ﺣﺪ ‪ 2‬ﻣﮕﺎ ﺑﺎﻳﺖ ﻓﻀﺎي ﻗﺎﺑﻞ اﺳﺘﻔﺎده در ﻧﺴﻞ ﻳﻚ را اﺷﻐﺎل ﻛﺮده اﻧﺪ‪ .‬در اﻳـﻦ ﻣﺮﺣﻠـﻪ‪ ،‬ﺑﺮﻧﺎﻣـﻪ ﻣﺮاﺣـﻞ اﺟـﺮاي ﺧـﻮد را‬ ‫ﻫﻤﭽﻨﺎن اداﻣﻪ ﻣﻴﺪﻫﺪ و در اﻳﻦ ﻣﺮﺣﻠﻪ اﺷﻴﺎي ‪ P‬ﺗﺎ ‪ S‬ﺗﻮﻟﻴﺪ ﻣﻴﺸﻮﻧﺪ ﻛﻪ اﻳﻦ اﺷﻴﺎ ﻧﺴﻞ ﺻﻔﺮ را ﻧﻴﺰ ﺗﺎ ﺳﺮ ﺣﺪ ﺧﻮد ﭘﺮ ﻣﻴﻜﻨﻨﺪ‪Heap .‬‬ ‫در اﻳﻦ ﻣﺮﺣﻠﻪ ﻣﺸﺎﺑﻪ ﺷﻜﻞ زﻳﺮ ﻣﻴﺸﻮد‪.‬‬

‫زﻣﺎﻧﻲ ﻛﻪ ﺑﺮﻧﺎﻣﻪ ﺳﻌﻲ در ﺗﺨﺼﻴﺺ ﺣﺎﻓﻈﻪ ﺑﺮاي ﺷﻴﺊ ‪ T‬دارد ﻧﺴﻞ ﺻﻔﺮ ﻛﺎﻣﻼ ﭘﺮ اﺳﺖ و ‪ Garbage Collector‬ﺑﺎﻳـﺪ‬ ‫آﻏﺎز ﺑﻪ ﻛﺎر ﻛﻨﺪ‪ .‬اﻳﻦ ﻣﺮﺗﺒﻪ‪ ،‬اﺷﻴﺎي ﻣﻮﺟﻮد در ﻧﺴﻞ ﻳﻚ ﻫﺮ ‪ 2‬ﻣﮕﺎ ﺑﺎﻳﺖ ﻓﻀﺎي ﺧﻮد را ﺗﺎ ﺳﺮ ﺣﺪ ﻓﻀﺎي ﻧـﺴﻞ ﻳـﻚ اﺷـﻐﺎل ﻛـﺮده اﻧـﺪ‪.‬‬ ‫ﻋﻼوه ﺑﺮ اﺷﻴﺎي ﻣﻮﺟﻮد در ﻧﺴﻞ ﺻﻔﺮ‪ ،‬ﺗﺼﻮر ﻣﻴﺸﻮد ﻛﻪ ﺑﻌﻀﻲ از اﺷﻴﺎي ﻣﻮﺟﻮد در ﻧﺴﻞ ﻳﻚ ﻫﻢ ﺑﻪ ﺻﻮرت ﻏﻴﺮ ﻗﺎﺑﻞ اﺳـﺘﻔﺎده در آﻣـﺪه‬ ‫اﻧﺪ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ اﻳﻦ ﻣﺮﺗﺒﻪ‪ Garbage Collector ،‬ﺗﺼﻤﻴﻢ ﻣﻴﮕﻴﺮد ﻛﻪ ﺗﻤﺎم اﺷﻴﺎي ﻣﻮﺟﻮد در ﻧﺴﻞ ﻳﻚ و ﻧﺴﻞ ﺻﻔﺮ را ﻣﻮرد‬ ‫ﺑﺮرﺳﻲ ﻗﺮار دﻫﺪ‪ .‬ﺑﻌﺪ از اﻳﻨﻜﻪ ﻫﺮ دو ﻧﺴﻞ ﺑﻪ ﻃـﻮر ﻛﺎﻣـﻞ ﺗﻮﺳـﻂ ‪ Garbage Collector‬ﻣـﻮرد ﺑﺮرﺳـﻲ ﻗـﺮار ﮔﺮﻓﺘﻨـﺪ‪،‬‬ ‫‪ heap‬ﺑﻪ ﺻﻮرت ﺷﻜﻞ زﻳﺮ در ﻣﻲ آﻳﺪ‪.‬‬

‫ﻣﺎﻧﻨﺪ ﻗﺒﻞ‪ ،‬اﺷﻴﺎﻳﻲ ﻛﻪ در اﻳﻦ ﻣﺮﺣﻠﻪ از ﺟﻤﻊ آوري از ﻧﺴﻞ ﺻﻔﺮ ﺑﺎﻗﻲ ﻣﺎﻧﺪﻧﺪ وارد ﻧﺴﻞ ﻳﻚ ﻣﻴﺸﻮﻧﺪ و ﻧﻴﺰ اﺷﻴﺎﻳﻲ ﻛﻪ در اﻳـﻦ ﻣﺮﺣﻠـﻪ از‬ ‫ﻧﺴﻞ ﻳﻚ ﺑﺎﻗﻲ ﻣﺎﻧﺪﻧﺪ وارد ﻧﺴﻞ دو ﻣﻴﺸﻮﻧﺪ‪ .‬ﻣﺜﻞ ﻫﻤﻴﺸﻪ‪ ،‬ﺑﻼﻓﺎﺻﻠﻪ ﻧﺴﻞ ﺻﻔﺮ از اﺷﻴﺎ ﺧﺎﻟﻲ ﻣﻴـﺸﻮد و اﺷـﻴﺎي ﺟﺪﻳـﺪ ﻣﻴﺘﻮاﻧﻨـﺪ در اﻳـﻦ‬ ‫ﻗﺴﻤﺖ ﻗﺮار ﮔﻴﺮﻧﺪ‪ .‬اﺷﻴﺎي ﻣﻮﺟﻮد در ﻧﺴﻞ دو اﺷﻴﺎي ﻫـﺴﺘﻨﺪ ﻛـﻪ ﺣـﺪاﻗﻞ دو ﺑـﺎر ﺗﻮﺳـﻂ ‪ Garbage Collector‬ﻣـﻮرد‬ ‫ﺑﺮرﺳﻲ ﻗﺮار ﮔﺮﻓﺘﻪ اﻧﺪ‪ .‬ﻣﻤﻜﻦ اﺳﺖ ﺑﻌﺪ از ﻳﻚ ﻳﺎ دو ﺑﺎر ﺟﻤﻊ آوري ﻧﺴﻞ ﺻﻔﺮ‪ ،‬ﺑﺎ اﻧﺠﺎم اﻳﻦ ﻋﻤﻞ در ﻧـﺴﻞ ﻳـﻚ ﻣﻘـﺪاري ﺣﺎﻓﻈـﻪ آزاد‬ ‫ﺷﻮد‪ ،‬اﻣﺎ اﻳﻦ ﻋﻤﻞ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ﻧﺴﻞ ﻳﻚ ﺑﻪ ﺳﺮ ﺣﺪ ﺧﻮد ﻧﺮﺳﺪ اﻧﺠﺎم ﻧﻤﻴﺸﻮد ﻛﻪ اﻳﻦ ﻛﺎر ﻣﻤﻜﻦ اﺳﺖ ﻧﻴﺎز ﺑﻪ ﭼﻨﺪﻳﻦ ﺑـﺎر اﺟـﺮاي ﺟﻤـﻊ‬ ‫آوري در ﻧﺴﻞ ﺻﻔﺮ ﺑﺎﺷﺪ‪.‬‬ ‫‪ Managed heap‬ﻓﻘﻂ ﺳﻪ ﻧﺴﻞ را ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻴﻜﻨﺪ‪ :‬ﻧﺴﻞ ﺻﻔﺮ‪ ،‬ﻧﺴﻞ ﻳﻚ و ﻧﺴﻞ دو‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﭼﻴﺰي ﺑﻪ ﻧﺎم ﻧـﺴﻞ ﺳـﻪ وﺟـﻮد‬ ‫ﻧﺪارد‪ .‬زﻣﺎﻧﻲ ﻛﻪ ‪ CLR‬آﻏﺎز ﺑﻪ ﻛﺎر ﻣﻴﻜﻨﺪ‪ ،‬ﺳﺮ ﺣﺪ ﻫﺎﻳﻲ را ﺑﺮاي ﻫﺮ ﺳﻪ ﻧﺴﻞ در ﻧﻈﺮ ﻣﻴﮕﻴﺮد‪ .‬ﻫﻤﺎﻧﻄﻮر ﻛﻪ ﭘﻴـﺸﺘﺮ ذﻛـﺮ ﺷـﺪ‪ ،‬ﺳـﺮ ﺣـﺪ‬ ‫ﺑﺮاي ﻧﺴﻞ ﺻﻔﺮ ﺣﺪود ‪256‬ﻛﻴﻠﻮﺑﺎﻳﺖ اﺳﺖ‪ ،‬ﺳﺮ ﺣﺪ ﺑﺮاي ﻧﺴﻞ ﻳﻚ ﺣﺪوداً ‪ 2‬ﻣﮕﺎ ﺑﺎﻳﺖ اﺳﺖ و ﺳﺮ ﺣﺪ ﺑﺮاي ﻧﺴﻞ دو ﺣﺪود ‪ 10‬ﻣﮕﺎ ﺑﺎﻳﺖ‬ ‫اﺳﺖ‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ ﺳﺮ ﺣﺪ ﻧﺴﻠﻬﺎ ﺑﻪ ﮔﻮﻧﻪ اي اﻧﺘﺨﺎب ﺷﺪه اﺳﺖ ﻛﻪ ﻣﻮﺟﺐ اﻓﺰاﻳﺶ ﺑﺎزدﻫﻲ و راﻧﺪﻣﺎن ﺑﺮﻧﺎﻣﻪ ﺷﻮد‪ .‬ﻫﺮﭼﻪ ﺳﺮ ﺣﺪ ﻳـﻚ ﻧـﺴﻞ‬ ‫ﺑﻴﺸﺘﺮ ﺑﺎﺷﺪ ﻋﻤﻞ ‪ Garbage Collection‬ﻛﻤﺘﺮ روي آن ﻧﺴﻞ ﺻﻮرت ﻣﻴﮕﻴﺮد‪ .‬و دوﺑﺎره‪ ،‬ﺑﻬﺒﻮد ﻛﺎراﻳﻲ ﺑﻪ وﺟﻮد ﻣﻲ آﻳﺪ‬ ‫ﻛﻪ ﺑﻪ دﻟﻴﻞ ﻓﺮﺿﻴﺎت اوﻟﻴﻪ اﺳﺖ‪ :‬اﺷﻴﺎي ﺟﺪﻳﺪ داراي ﻃﻮل ﻋﻤﺮ ﻛﻮﺗﺎﻫﺘﺮي ﻫﺴﺘﻨﺪ‪ ،‬اﺷﻴﺎي ﻗﺪﻳﻤﻲ ﻃﻮل ﻋﻤﺮ ﺑﻴﺸﺘﺮي دارﻧﺪ‪.‬‬ ‫‪ Garbage Collector‬ﻣﻮﺟﻮد در ‪ CLR‬ﻳﻚ ﺟﻤﻊ آوري ﻛﻨﻨﺪه ﺑﺎ ﺗﻨﻈﻴﻢ ﻛﻨﻨﺪه ﺧﻮدﻛﺎر اﺳﺖ‪ .‬اﻳﻦ ﺑﺪﻳﻦ ﻣﻌﻨﺎ اﺳـﺖ ﻛـﻪ‬ ‫‪ Garbage Collector‬از رﻓﺘﺎر ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﻣﻲ آﻣﻮزد ﻛﻪ ﭼﻪ زﻣﺎﻧﻲ ﺑﺎﻳﺪ ﻋﻤﻞ ﺟﻤﻊ آوري را اﻧﺠﺎم دﻫﺪ‪ .‬ﺑﺮاي ﻣﺜﺎل اﮔـﺮ‬

‫‪٩٤٧‬‬

‫ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ اﺷﻴﺎي زﻳﺎدي را اﻳﺠﺎد ﻛﻨﺪ و از آﻧﻬﺎ ﺑﺮاي ﻣﺪت زﻣﺎن ﻛﻮﺗﺎﻫﻲ اﺳﺘﻔﺎده ﻛﻨﺪ‪ ،‬اﻳﻦ اﻣﺮ ﻣﻤﻜﻦ اﺳﺖ ﻛـﻪ آزاد ﺳـﺎزي ﺣﺎﻓﻈـﻪ در‬ ‫ﻧﺴﻞ ﺻﻔﺮ ﻣﻘﺪار زﻳﺎدي ﺣﺎﻓﻈﻪ را آزاد ﻛﻨﺪ‪.‬ﺣﺘﻲ ﻣﻤﻜﻦ اﺳﺖ ﺗﻤﺎم ﺣﺎﻓﻈﻪ ﮔﺮﻓﺘﻪ ﺷﺪه در ﻧﺴﻞ ﺻﻔﺮ آزاد ﺷﻮد‪.‬‬ ‫اﮔﺮ ‪ Garbage Collector‬ﻣﺸﺎﻫﺪه ﻛﻨﺪ ﻛﻪ ﺑﻌﺪ از اﻧﺠﺎم ﺟﻤﻊ آوري ﻧﺴﻞ ﻳﻚ ﺗﻌـﺪاد ﻣﺤـﺪودي از اﺷـﻴﺎ ﺑـﺎﻗﻲ ﻣﺎﻧﺪﻧـﺪ‪،‬‬ ‫ﻣﻤﻜﻦ اﺳﺖ ﻛﻪ ﺗﺼﻤﻴﻢ ﺑﮕﻴﺮد ﻛﻪ ﺳﺮ ﺣﺪ ﻧﺴﻞ ﺻﻔﺮ را از ‪ 256‬ﻛﻴﻠﻮ ﺑﺎﻳﺖ ﺑﻪ ‪ 128‬ﻛﻴﻠﻮ ﺑﺎﻳﺖ ﻛﺎﻫﺶ دﻫﺪ‪ .‬اﻳﻦ ﻛﺎﻫﺶ در ﻓﻀﺎي ﻣﻌـﻴﻦ‬ ‫ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ اﺳﺖ ﻛﻪ ﻋﻤﻞ ﺟﻤﻊ آوري ﺑﺎﻳﺪ در ﻓﻮاﺻﻞ زﻣﺎﻧﻲ ﻛﻮﺗﺎه ﺗﺮي رخ دﻫﺪ اﻣﺎ ﻓﻀﺎي ﻛﻤﺘﺮي را ﺑﺮرﺳﻲ ﻛﻨﺪ‪ .‬ﺑﻨـﺎﺑﺮاﻳﻦ ﻛﺎرﻫـﺎي‬ ‫ﭘﺮوﺳﻪ ﺷﻤﺎ ﺑﻪ ﺻﻮرت ﻗﺎﺑﻞ ﺗﻮﺟﻬﻲ اﻓﺰاﻳﺶ ﻧﻤﻲ ﻳﺎﺑﺪ‪ .‬اﮔﺮ ﺗﻤﺎم اﺷﻴﺎي ﻣﻮﺟﻮد در ﻧﺴﻞ ﺻﻔﺮ زﺑﺎﻟﻪ ﻣﺤـﺴﻮب ﺷـﻮﻧﺪ دﻳﮕـﺮ اﺣﺘﻴـﺎﺟﻲ ﺑـﻪ‬ ‫ﻓـﺸﺮده ﺳـﺎزي ﺣﺎﻓﻈـﻪ ﺗﻮﺳـﻂ ‪ Garbage Collector‬ﻧﻴـﺴﺖ‪ .‬اﻳـﻦ ﻋﻤـﻞ ﻣﻴﺘﻮاﻧـﺪ ﺑـﻪ ﺳـﺎدﮔﻲ ﺑـﺎ آوردن اﺷـﺎره ﮔـﺮ‬ ‫‪ NextObjPtr‬ﺑﻪ اﺑﺘﺪاي ﺣﺎﻓﻈﻪ ﻣﻮرد ﻧﻈﺮ ﺑﺮاي ﻧﺴﻞ ﺻﻔﺮ اﻧﺠﺎم ﺷﻮد‪ .‬اﻳﻦ ﻋﻤﻞ ﺑﻪ ﺳﺮﻋﺖ ﺣﺎﻓﻈﻪ را آزاد ﻣﻴﻜﻨﺪ!‬ ‫ﻧﻜﺘﻪ‪ Garbage Collector:‬ﺑﻪ ﺑﻬﺘﺮﻳﻦ ﻧﺤﻮ ﺑﺎ ﺑﺮﻧﺎﻣﻪ ﻫﺎي ‪ ASP.NET‬و ﺳﺮوﻳﺴﻬﺎي وب ﻣﺒﺘﻨـﻲ ﺑـﺮ ‪ XML‬ﻛـﺎر‬ ‫ﻣﻴﻜﻨﺪ‪ .‬ﺑﺮاي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ ‪ ،ASP.NET‬ﻳﻚ ﺗﻘﺎﺿﺎ از ﻃﺮف ﻛﻼﻳﻨﺖ ﻣﻴﺮﺳﺪ‪ ،‬ﻳﻚ ﺟﻌﺒﻪ از اﺷﻴﺎي ﺟﺪﻳﺪ ﺗﺸﻜﻴﻞ ﻣﻴﺸﻮد‪ ،‬اﺷـﻴﺎ‬ ‫ﻛﺎرﻫﺎي ﺗﻌﻴﻴﻦ ﺷﺪه ﺗﻮﺳﻂ ﻛﻼﻳﻨﺖ را اﻧﺠﺎم ﻣﻴﺪﻫﻨﺪ‪ ،‬و ﻧﺘﻴﺠﻪ ﺑﻪ ﺳﻤﺖ ﻛﻼﻳﻨﺖ ﺑﺮ ﻣﻴﮕﺮدد‪ .‬در اﻳﻦ ﻣﺮﺣﻠﻪ ﺗﻤـﺎم اﺷـﻴﺎي ﻣﻮﺟـﻮد ﺑـﺮاي‬ ‫اﻧﺠﺎم ﺗﻘﺎﺿﺎي ﻛﻼﻳﻨﺖ زﺑﺎﻟﻪ ﺗﻠﻘﻲ ﻣﻴﺸﻮﻧﺪ‪ .‬ﺑﻪ ﺑﻴﺎن دﻳﮕﺮ‪ ،‬ﻫﺮ ﺗﻘﺎﺿﺎي ﺑﺮﻧﺎﻣﻪ ﻫﺎي ﺗﺤﺖ ‪ ASP.NET‬ﺑﺎﻋﺚ اﻳﺠﺎد ﺣﺠـﻢ زﻳـﺎدي از‬ ‫زﺑﺎﻟﻪ ﻣﻴﺸﻮﻧﺪ‪ .‬ﭼﻮن اﻳﻦ اﺷﻴﺎ اﻏﻠﺐ ﺑﻼﻓﺎﺻﻠﻪ ﺑﻌﺪ از اﻳﺠﺎد دﻳﮕﺮ ﻗﺎﺑﻞ دﺳﺘﺮﺳﻲ ﻧﻴﺴﺘﻨﺪ ﻫﺮ ﻋﻤﻞ ﺟﻤـﻊ آوري ﻣﻮﺟـﺐ آزاد ﺳـﺎزي ﻣﻘـﺪار‬ ‫‪Garbage‬‬ ‫زﻳ ـﺎدي از ﺣﺎﻓﻈــﻪ ﻣﻴ ـﺸﻮد‪ .‬اﻳ ـﻦ ﻛــﺎر ﻣﺠﻤﻮﻋــﻪ ﻛﺎرﻫــﺎي ﭘﺮوﺳــﻪ را ﺑــﺴﻴﺎر ﻛــﺎﻫﺶ ﻣﻴﺪﻫــﺪ ﺑﻨــﺎﺑﺮاﻳﻦ راﻧــﺪﻣﺎن‬ ‫‪ Collector‬ﻣﺤﺴﻮس ﺧﻮاﻫﺪ ﺑﻮد‪.‬‬ ‫ﺑﻪ ﺑﻴﺎن دﻳﮕﺮ‪ ،‬اﮔﺮ ‪ Garbage Collector‬ﻧﺴﻞ ﺻﻔﺮ را ﻣﻮرد ﺑﺮرﺳﻲ ﻗﺮار دﻫﺪ و ﻣﺸﺎﻫﺪه ﻛﻨﺪ ﻛﻪ ﻣﻘـﺪار زﻳـﺎدي از اﺷـﻴﺎ‬ ‫وارد ﻧﺴﻞ ﻳﻚ ﺷﺪﻧﺪ‪ ،‬ﻣﻘﺪار زﻳﺎدي از ﺣﺎﻓﻈﻪ ﺗﻮﺳﻂ ‪ Garbage Collection‬آزاد ﻧﻤﻴـﺸﻮد‪ ،‬ﺑﻨـﺎﺑﺮاﻳﻦ ‪Garbage‬‬ ‫‪ Collector‬ﺳﺮ ﺣﺪ ﻧﺴﻞ ﺻﻔﺮ را ﺗﺎ ‪ 512‬ﻛﻴﻠﻮ ﺑﺎﻳﺖ اﻓﺰاﻳﺶ ﻣﻴﺪﻫﺪ‪ .‬در اﻳﻦ ﻣﺮﺣﻠﻪ ﻛﻤﺘﺮ اﻧﺠﺎم ﻣﻴﺸﻮد اﻣﺎ ﺑﺎ ﻫﺮ ﺑﺎر اﻧﺠـﺎم اﻳـﻦ‬ ‫ﻋﻤﻞ ﻣﻘﺪار زﻳﺎدي ﺣﺎﻓﻈﻪ آزاد ﻣﻴﺸﻮد‪.‬‬ ‫در ﻃﻮل اﻳﻦ ﻗﺴﻤﺖ ﭼﮕﻮﻧﮕﻲ ﺗﻐﻴﻴﺮ دﻳﻨﺎﻣﻴﻚ ﺳﺮ ﺣﺪ ﻧﺴﻞ ﺻﻔﺮ ﺷﺮح داده ﺷﺪ‪ .‬اﻣﺎ ﻋﻼوه ﺑﺮ ﺳﺮ ﺣﺪ ﻧﺴﻞ ﺻﻔﺮ ﺳﺮ ﺣﺪ ﻧـﺴﻠﻬﺎي ﻳـﻚ و‬ ‫دو ﻧﻴﺰ ﺑﺮ اﺳﺎس ﻫﻤﻴﻦ اﻟﮕﻮرﻳﺘﻢ ﺗﻐﻴﻴﺮ ﻣﻴﻜﻨﻨـﺪ‪ .‬ﺑـﻪ اﻳـﻦ ﻣﻌﻨـﻲ ﻛـﻪ زﻣـﺎﻧﻲ ﻛـﻪ اﻳـﻦ ﻧـﺴﻠﻬﺎ ﻣـﻮرد ﻋﻤـﻞ ﺟﻤـﻊ آوري ﻗـﺮار ﻣﻴﮕﻴﺮﻧـﺪ‬ ‫‪ Garbage Collector‬ﺑﺮرﺳﻲ ﻣﻴﻜﻨﺪ ﻛﻪ ﭼﻪ ﻣﻘﺪار ﻓﻀﺎ آزاد ﺷﺪه اﺳﺖ و ﭼﻪ ﻣﻘﺪار از اﺷﻴﺎ ﺑﻪ ﻧـﺴﻞ ﺑﻌـﺪ رﻓﺘـﻪ اﻧـﺪ‪ .‬ﺑـﺮ‬ ‫اﺳﺎس ﻧﺘﺎﻳﺞ اﻳﻦ ﺑﺮرﺳﻴﻬﺎ ‪ Garbage Collector‬ﻣﻤﻜﻦ اﺳﺖ ﻇﺮﻓﻴﺖ اﻳﻦ ﻧﺴﻠﻬﺎ را ﻛﺎﻫﺶ ﻳﺎ اﻓﺰاﻳﺶ دﻫـﺪ ﻛـﻪ ﺑﺎﻋـﺚ‬ ‫اﻓﺰاﻳﺶ ﺳﺮﻋﺖ اﺟﺮاي ﺑﺮﻧﺎﻣﻪ ﻣﻴﺸﻮد‪.‬‬

‫دﻳﮕﺮ ﻧﺘﺎﻳﺞ ﻛﺎراﻳﻲ ‪:Garbage Collector‬‬ ‫ﭘﻴﺸﺘﺮ در اﻳﻦ ﻣﻘﺎﻟﻪ اﻟﮕﻮرﻳﺘﻢ ﻛﺎر ‪ Garbage Collector‬ﺷﺮح داده ﺷﺪ‪ .‬ﺑﺎ اﻳﻦ وﺟﻮد در ﻃﻮل اﻳﻦ ﺗﻮﺿﻴﺤﺎت ﻳﻚ ﻓﺮض‬ ‫ﺑﺰرگ ﺻﻮرت ﮔﺮﻓﺘﻪ ﺑﻮد‪ :‬اﻳﻨﻜﻪ ﻓﻘﻂ ﻳﻚ ﺗﺮد‪ 1‬در ﺣﺎل اﺟـﺮا اﺳـﺖ‪ .‬اﻣـﺎ در ﻣـﺪل واﻗﻌـﻲ ﭼﻨـﺪﻳﻦ ﺗـﺮد ﺑـﻪ ‪managed heap‬‬ ‫دﺳﺘﺮﺳﻲ دارﻧﺪ و ﻳﺎ ﺣﺪاﻗﻞ اﺷﻴﺎي ﻗﺮار ﮔﺮﻓﺘﻪ در ‪ managed heap‬رو ﺗﻐﻴﻴﺮ ﻣﻴﺪﻫﻨﺪ‪ .‬زﻣﺎﻧﻲ ﻛﻪ ﻳﻚ ﺗﺮد ﻣﻮﺟﺐ اﺟـﺮاي ﻋﻤـﻞ‬ ‫ﺟﻤﻊ آوري ﺗﻮﺳﻂ ‪ Garbage Collector‬ﻣﻴﺸﻮد‪ ،‬دﻳﮕﺮ ﺗﺮد ﻫﺎ ﺣﻖ دﺳﺘﺮﺳﻲ ﺑـﻪ اﺷـﻴﺎي ﻣﻮﺟـﻮد در ‪managed‬‬ ‫‪ heap‬را ﻧﺪارﻧﺪ)اﻳﻦ ﻣﻮرد ﺷﺎﻣﻞ ارﺟﺎع ﻫﺎي اﺷﻴﺎي ﻣﻮﺟﻮد در ‪ stack‬ﻫـﻢ ﻣﻴـﺸﻮد( زﻳـﺮا ‪Garbage Collector‬‬ ‫ﻣﻤﻜﻦ اﺳﺖ ﻣﻜﺎن اﻳﻦ اﺷﻴﺎ را ﺗﻐﻴﻴﺮ دﻫﺪ‪.‬‬

‫‪Thread‬‬

‫‪1‬‬

‫‪٩٤٨‬‬

‫ﺑﻨﺎﺑﺮاﻳﻦ وﻗﺘﻲ ‪ Garbage Collector‬ﺑﺨﻮاﻫﺪ ﻋﻤﻞ ﺟﻤﻊ آوري را آﻏﺎز ﻛﻨﺪ‪ ،‬ﺗﻤﺎم ﺗﺮد ﻫﺎﻳﻲ ﻛﻪ در ﺣﺎل اﺟﺮاي ﻛﺪ ﻫـﺎي‬ ‫ﻣﺪﻳﺮﻳﺖ ﺷﺪه‪ 1‬ﻫﺴﺘﻨﺪ ﺑﻪ ﺣﺎل ﺗﻌﻠﻴﻖ در ﻣﻲ آﻳﻨﺪ‪ CLR.‬داراي ﭼﻨﺪﻳﻦ ﻣﻜﺎﻧﻴﺴﻢ ﻧﺴﺒﺘﺎً ﻣﺘﻔﺎوت اﺳﺖ ﻛﻪ ﻣﻴﺘﻮاﻧﺪ ﺗﺮد ﻫﺎ را ﺑﻪ ﺣﺎﻟﺖ ﺗﻌﻠﻴﻖ‬ ‫در آورد ﺑﻨﺎﺑﺮاﻳﻦ ﻋﻤﻞ ﺟﻤﻊ آوري ﻣﻴﺘﻮاﻧﺪ ﺑﻪ درﺳﺘﻲ اﺟﺮا ﺷﻮد‪ .‬دﻟﻴﻞ اﻳﻨﻜﻪ ‪ CLR‬از ﭼﻨﺪﻳﻦ ﻣﻜﺎﻧﻴﺴﻢ اﺳﺘﻔﺎده ﻣﻴﻜﻨﺪ ﺑﻪ ﺣﺎﻟﺖ اﺟﺮا ﻧﮕـﺎه‬ ‫داﺷﺘﻦ ﺗﺮد ﻫﺎ ﺗﺎ ﺣﺪاﻛﺜﺮ زﻣﺎن ﻣﻤﻜﻦ و ﻛﺎﻫﺶ ﺳﺮﺑﺎر ﻛﺮدن آﻧﻬﺎ در ﺣﺎﻓﻈﻪ ﺗﺎ ﺣﺪاﻗﻞ زﻣﺎن ﻣﻤﻜﻦ اﺳﺖ‪ .‬ﺗـﺸﺮﻳﺢ اﻳـﻦ ﻣﻜﺎﻧﻴـﺴﻢ ﻫـﺎ از‬ ‫اﻫﺪاف اﻳﻦ ﻣﻘﺎﻟﻪ ﺧﺎرج اﺳﺖ اﻣﺎ ﺗﺎ اﻳﻦ ﺣﺪ ﻻزم اﺳﺖ ذﻛﺮ ﺷﻮد ﻛﻪ ﻣﺎﻳﻜﺮوﺳﺎﻓﺖ ﻓﻌﺎﻟﻴﺘﻬﺎي زﻳﺎدي را ﺑﺮاي ﻛﺎﻫﺶ ﻓﺸﺎر ﭘﺮدازﺷﻲ ﻧﺎﺷـﻲ‬ ‫از ‪ Garbage Collector‬اﻧﺠﺎم داده اﺳﺖ‪ .‬و ﻧﻴﺰ اﻳﻦ ﻣﻜﺎﻧﻴﺴﻢ ﻫﺎ ﺑﻪ ﺳﺮﻋﺖ در ﺣﺎل ﺗﻐﻴﻴﺮ ﻫﺴﺘﻨﺪ ﺗﺎ ﺑﻪ ﺑﻬﺘﺮﻳﻦ ﻛـﺎراﻳﻲ‬ ‫ﺧﻮد ﺑﺮﺳﻨﺪ‪.‬‬ ‫زﻣﺎﻧﻲ ﻛﻪ ‪ CLR‬ﻣﻴﺨﻮاﻫﺪ ‪ Garbage Collector‬را اﺟﺮا ﻛﻨﺪ‪ ،‬اﺑﺘﺪا ﺗﻤﺎم ﺗـﺮد ﻫـﺎ در ﭘﺮوﺳـﻪ ﺟـﺎري را ﻛـﻪ در ﺣـﺎل‬ ‫اﺟﺮاي ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﻫﺴﺘﻨﺪ ﺑﻪ ﺣﺎل ﺗﻌﻠﻴﻖ در ﻣﻲ آورد‪ .‬ﺳﭙﺲ ‪ CLR‬ﺑـﺮاي ﺗﻌﻴـﻴﻦ ﻣﻮﻗﻌﻴـﺖ ﻫـﺮ ﺗـﺮد ﺗﻤـﺎم اﺷـﺎره ﮔﺮﻫـﺎي‬ ‫دﺳﺘﻮرات در ﺣﺎل اﺟﺮا ﺗﻮﺳﻂ ﺗﺮد ﻫﺎ را ﺑﺮرﺳﻲ ﻣﻴﻜﻨﺪ‪ .‬ﺳﭙﺲ ﺑﺮاي ﺗﻌﻴﻴﻦ اﻳﻨﻜﻪ ﭼﻪ ﻛﺪي ﺗﻮﺳﻂ ﺗﺮد در ﺣﺎل اﺟﺮا ﺑﻮده آدرس اﺷـﺎره ﮔـﺮ‬ ‫دﺳﺘﻮر ﺑﺎ ﺟﺪول اﻳﺠﺎد ﺷﺪه ﺗﻮﺳﻂ ﻛﺎﻣﭙﺎﻳﻠﺮ‪ JIT‬ﻣﻘﺎﻳﺴﻪ ﻣﻴﺸﻮد‪.‬‬ ‫اﮔﺮ دﺳﺘﻮر درﺣﺎل اﺟﺮا ﺗﻮﺳﻂ ﺗﺮد در ﻳﻚ آﻓﺴﺖ ﻣﺸﺨﺺ ﺷﺪه ﺑﻪ وﺳﻴﻠﻪ ﺟﺪول ﻣﺬﻛﻮر ﺑﺎﺷﺪ ﮔﻔﺘﻪ ﻣﻴﺸﻮد ﻛﻪ ﺗﺮد ﺑـﻪ ﻳـﻚ ﻧﻘﻄـﻪ اﻣـﻦ‬ ‫دﺳﺘﺮﺳﻲ دارد‪ .‬ﻳﻚ ﻧﻘﻄﻪ اﻣﻦ ﻧﻘﻄﻪ اي اﺳﺖ ﻛﻪ در آﻧﺠﺎ ﻣﻴﺘﻮان ﺑﺪون ﻫﻴﭻ ﻣﺸﻜﻠﻲ ﺗﺮد را ﺑﻪ ﺣﺎل ﺗﻌﻠﻴﻖ در آورد ﺗـﺎ ‪Garbage‬‬ ‫‪ Collector‬ﻛﺎر ﺧﻮد را آﻏﺎز ﻛﻨﺪ‪.‬اﮔﺮ اﺷﺎره ﮔﺮ دﺳﺘﻮر در ﺣﺎل اﺟﺮاي ﺗﺮد در روي ﻳﻚ آﻓـﺴﺖ ﻣـﺸﺨﺺ ﺷـﺪه ﺗﻮﺳـﻂ ﺟـﺪول‬ ‫دروﻧﻲ ﺗﺎﺑﻊ ﻗﺮار ﻧﺪاﺷﺖ‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ ﺗﺮد در ﻳﻚ ﻧﻘﻄﻪ اﻣﻦ ﻗﺮار ﻧﺪارد و ‪ CLR‬ﻧﻤﻴﺘﻮاﻧﺪ ‪ Garbage Collector‬را اﺟﺮا ﻛﻨـﺪ‪.‬‬ ‫در اﻳﻦ ﺣﺎﻟﺖ‪ CLR‬ﺗﺮد را ﻫﺎﻳﺠﻚ‪ 2‬ﻣﻴﻜﻨﺪ‪ :‬ﺑﻪ اﻳﻦ ﻣﻌﻨﻲ ﻛﻪ ‪ CLR‬اﺳﺘﻚ ﻣﺮﺑﻮط ﺑـﻪ ﺗـﺮد را ﺑـﻪ ﮔﻮﻧـﻪ اي ﺗﻐﻴﻴـﺮ ﻣﻴﺪﻫـﺪ ﻛـﻪ آدرس‬ ‫ﺑﺎزﮔﺸﺖ ﺑﻪ ﻳﻚ ﺗﺎﺑﻊ ﺧﺎص ﭘﻴﺎده ﺳﺎزي ﺷﺪه درون ‪ CLR‬اﺷﺎره ﻛﻨﺪ‪ .‬ﺳﭙﺲ ﺗﺮد ﺑﻪ اداﻣﻪ ﻛﺎر ﺧﻮد ﺑﺎزﻣﻴﮕﺮدد‪ .‬زﻣﺎﻧﻲ ﻛـﻪ ﻣﺘـﺪ در ﺣـﺎل‬ ‫اﺟﺮا ﺗﻮﺳﻂ ﺗﺮد اداﻣﻪ ﭘﻴﺪا ﻛﻨﺪ‪ ،‬اﻳﻦ ﺗﺎﺑﻊ وﻳﮋه اﺟﺮا ﺧﻮاﻫﺪ ﺷﺪ و ﺗﺮد ﺑﻪ ﺣﺎﻟﺖ ﺗﻌﻠﻖ درﺧﻮاﻫﺪ آﻣﺪ‪.‬‬ ‫ﺑﺎ وﺟﻮد اﻳﻦ ﻣﻤﻜﻦ اﺳﺖ در ﺑﻌﻀﻲ ﻣﻮاﻗﻊ ﺗﺮد از ﻣﺘﺪ ﺧﻮد ﺑﺎز ﻧﮕﺮدد‪ .‬ﺑﻨﺎﺑﺮاﻳﻦ زﻣـﺎﻧﻲ ﻛـﻪ ﺗـﺮد ﺑـﻪ اﺟـﺮاي ﺧـﻮد اداﻣـﻪ ﻣﻴﺪﻫـﺪ‪CLR ،‬‬ ‫‪250‬ﻣﻴﻠﻲ ﺛﺎﻧﻴﻪ ﺻﺒﺮ ﻣﻴﻜﻨﺪ‪ .‬ﺳﭙﺲ دوﺑﺎره ﺑﺮرﺳﻲ ﻣﻴﻜﻨﺪ ﻛﻪ آﻳﺎ ﺗﺮد ﺑﻪ ﻳﻚ ﻧﻘﻄﻪ اﻣﻦ ﻃﺒﻖ ﺟﺪول ‪ JIT‬رﺳﻴﺪه اﺳﺖ ﻳﺎ ﻧﻪ‪ .‬اﮔﺮ ﺗﺮد ﺑـﻪ‬ ‫ﻳﻚ ﻧﻘﻄﻪ اﻣﻦ رﺳﻴﺪه ﺑﻮد ‪ CLR‬ﺗﺮد را ﺑﻪ ﺣﺎﻟﺖ ﺗﻌﻠﻴﻖ درﻣﻲ آورد و ‪ Garbage Collector‬را اﺟﺮا ﻣﻴﻜﻨﺪ در ﻏﻴﺮ اﻳـﻦ‬ ‫ﺻﻮرت ﻣﺠﺪدا ﺳﻌﻲ ﻣﻴﻜﻨﺪ ﺑﺎ ﺗﻐﻴﻴﺮ ‪ Stack‬ﻣﺮﺑﻮط ﺑﻪ ﺗﺮد اﺟﺮاي آن را ﺑﻪ ﺗﺎﺑﻊ دﻳﮕﺮي اﻧﺘﻘﺎل دﻫﺪ در ﺻﻮرت ﺷﻜﺴﺖ ﻣﺠﺪدا ‪CLR‬‬ ‫ﺑﺮاي ﭼﻨﺪ ﻣﻴﻠﻲ ﺛﺎﻧﻴﻪ دﻳﮕﺮ ﻧﻴﺰ ﺻﺒﺮ ﻣﻴﻜﻨﺪ‪ .‬زﻣﺎﻧﻲ ﻛﻪ ﺗﻤﺎم ﺗﺮد ﻫﺎ ﺑﻪ ﻳﻚ ﻧﻘﻄﻪ اﻣـﻦ رﺳـﻴﺪﻧﺪ ﻳـﺎ اﻳﻨﻜـﻪ ﺑـﺎ ﻣﻮﻓﻘﻴـﺖ ﻫﺎﻳﺠـﻚ ﺷـﺪﻧﺪ‪،‬‬ ‫‪ Garbage Collector‬ﻣﻴﺘﻮاﻧﺪ ﻛﺎر ﺧﻮد را آﻏﺎز ﻛﻨﺪ‪ .‬زﻣﺎﻧﻲ ﻛﻪ ﻋﻤﻞ ﺟﻤﻊ آوري اﻧﺠﺎم ﺷﺪ ﺗﻤﺎم ﺗﺮد ﻫﺎ ﺑﻪ وﺿﻌﻴﺖ ﻗﺒﻠﻲ‬ ‫ﺧﻮد ﺑﺮ ﻣﻴﮕﺮدﻧﺪ و اﺟﺮاي ﺑﺮﻧﺎﻣﻪ اداﻣﻪ ﭘﻴﺪا ﻣﻴﻜﻨﺪ‪ .‬ﺗﺮد ﻫﺎي ﻫﺎﻳﺠﻚ ﺷﺪه ﻫﻢ ﺑﻪ ﻣﺘﺪﻫﺎي اوﻟﻴﻪ ﺧﻮد ﺑﺎزﻣﻴﮕﺮدﻧﺪ‪.‬‬ ‫ﻧﻜﺘﻪ‪ :‬اﻳﻦ اﻟﮕﻮرﻳﺘﻢ ﻳﻚ ﭘﻴﭻ ﺧﻮردﮔﻲ ﻛﻮﭼﻚ دارد‪ .‬اﮔﺮ ‪ CLR‬ﻳﻚ ﺗﺮد را ﺑﻪ ﺣﺎﻟﺖ ﺗﻌﻮﻳﻖ درآورد و درﻳﺎﺑﺪ ﻛﻪ ﺗﺮد در ﺣﺎل اﺟﺮاي ﻳﻚ‬ ‫ﻛﺪ ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه‪ 3‬ﺑﻮد آدرس ﺑﺎزﮔﺸﺖ ﺗﺮد ﻫﺎﻳﺠﻚ ﻣﻴﺸﻮد و ﺑﻪ ﺗﺮد اﺟﺎزه داده ﻣﻴﺸﻮد ﻛﻪ ﺑﻪ اﺟﺮاي ﺧﻮد اداﻣﻪ دﻫﺪ‪ .‬ﺑﺎ اﻳﻦ وﺟﻮد در اﻳﻦ‬ ‫ﺣﺎﻟﺖ ﺑﻪ ‪ Garbage Collector‬اﺟﺎزه داده ﻣﻴﺸﻮد ﻛﻪ اﺟﺮا ﺷﻮد در ﺣﺎﻟﻲ ﻛﻪ ﺗﺮد ﻣﺬﻛﻮر در ﺣﺎل اﺟﺮا اﺳـﺖ‪ .‬اﻳـﻦ ﻣـﻮرد‬ ‫ﻫﻴﭻ اﺷﻜﺎﻟﻲ را ﺑﻪ وﺟﻮد ﻧﻤﻲ آورد زﻳﺮا ﻛﺪ ﻫﺎي ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه ﺑﻪ اﺷـﻴﺎي ﻣﻮﺟـﻮد در ‪ managed heap‬دﺳﺘﺮﺳـﻲ ﻧﺪارﻧـﺪ ﺗـﺎ‬ ‫زﻣﺎﻧﻲ ﻛﻪ آن اﺷﻴﺎ ﭘﻴﻦ‪ 4‬ﺷﻮﻧﺪ‪ .‬ﻳﻚ ﺷﻴﺊ ﭘﻴﻦ ﺷﺪه ﺷـﻲ اﺳـﺖ ﻛـﻪ ‪ Garbage Collector‬ﺣـﻖ ﺣﺮﻛـﺖ دادن آن را در‬ ‫‪ managed heap‬ﻧﺪارد‪ .‬اﮔﺮ ﺗﺮدي ﻛﻪ در ﺣﺎل ﺣﺎﺿﺮ در ﺣﺎل اﺟﺮاي ﻳﻚ ﻛﺪ ﻣﺪﻳﺮﻳﺖ ﻧﺸﺪه ﺑﻮد‪ ،‬ﺷﺮوع ﺑـﻪ اﺟـﺮاي ﻳـﻚ ﻛـﺪ‬ ‫ﻣﺪﻳﺮﻳﺖ ﺷﺪه ﻛﻨﺪ‪ ،‬ﺗﺮد ﻫﺎﻳﺠﻚ ﻣﻴﺸﻮد و ﺑﻪ ﺣﺎﻟﺖ ﺗﻌﻠﻴﻖ درﻣﻲ آﻳﺪ ﺗﺎ زﻣﺎﻧﻲ ﻛﻪ ‪ Garbage Collection‬ﺑﻪ درﺳﺘﻲ ﺑـﻪ‬ ‫اﺗﻤﺎم ﺑﺮﺳﺪ‪.‬‬

‫‪Managed Code‬‬ ‫‪Hijack‬‬ ‫‪Unmanaged Code‬‬ ‫‪Pin‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬ ‫‪4‬‬

‫‪٩٤٩‬‬

‫ﻋﻼوه ﺑﺮ ﻣﻜﺎﻧﻴﺴﻤﻬﺎي ذﻛﺮ ﺷﺪه)ﻧﺴﻠﻬﺎ‪ ،‬ﻧﻘﺎط اﻣﻦ‪ ،‬و ﻫﺎﻳﺠﻚ ﻛﺮدن(‪ Garbage Collector ،‬از ﺑﻌﻀﻲ از ﻣﻜﺎﻧﻴـﺴﻤﻬﺎي‬ ‫اﺿﺎﻓﻲ دﻳﮕﺮي ﻧﻴﺰ اﺳﺘﻔﺎده ﻣﻴﻜﻨﺪ ﻛﻪ ﺑﺎﻋﺚ اﻓﺰاﻳﺶ ﺑﺎزدﻫﻲ آن ﻣﻴﺸﻮد‪.‬‬

‫اﺷﻴﺎي ﺑﺰرگ‪:‬‬ ‫ﻓﻘﻂ ﻳﻚ ﻧﻜﺘﻪ ﻗﺎﺑﻞ ذﻛﺮ دﻳﮕﺮ ﻛﻪ ﺑﺎﻋﺚ اﻓﺰاﻳﺶ ﺳﺮﻋﺖ و ﺑﺎزدﻫﻲ ﺑﻬﺘﺮ ﻣﻴﺸﻮد ﺑﺎﻗﻲ ﻣﺎﻧﺪه اﺳﺖ‪ .‬ﻫﺮ ﺷﻴﺊ ﻛﻪ ‪ 85000‬ﺑﺎﻳـﺖ ﻳـﺎ ﺑﻴـﺸﺘﺮ‬ ‫ﻓﻀﺎي ﺣﺎﻓﻈﻪ را اﺷﻐﺎل ﻛﻨﺪ ﻳﻚ ﺷﻴﺊ ﺑﺰرگ در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻴﺸﻮد‪ .‬اﺷﻴﺎي ﺑﺰرگ در ﻳﻚ ‪ heap‬وﻳﮋه اﺷـﻴﺎي ﺑـﺰرگ ﻗـﺮار ﻣﻴﮕﻴﺮﻧـﺪ‪.‬‬ ‫اﺷﻴﺎي درون اﻳﻦ ‪ heap‬ﻣﺎﻧﻨﺪ اﺷﻴﺎي ﻛﻮﭼﻚ )ﻛﻪ راﺟﻊ ﺑﻪ آﻧﻬﺎ ﺻﺤﺒﺖ ﺷﺪ( ‪ finalize‬و آزاد ﻣﻴﺸﻮﻧﺪ‪ .‬ﺑﺎ اﻳﻦ وﺟﻮد اﻳﻦ اﺷـﻴﺎ‬ ‫ﻫﻴﭻ وﻗﺖ ﺗﺤﺖ ﻓﺸﺮده ﺳﺎزي ﻗﺮار ﻧﻤﻲ ﮔﻴﺮﻧﺪ زﻳﺮا ﺷﻴﻔﺖ دادن ‪ 85000‬ﺑﺎﻳـﺖ ﺑـﻼك ﺣﺎﻓﻈـﻪ درون ‪ heap‬ﻣﻘـﺪار زﻳـﺎدي از زﻣـﺎن‬ ‫‪ CPU‬را ﻫﺪر ﻣﻴﺪﻫﺪ‪.‬‬ ‫اﺷﻴﺎي ﺑﺰرگ ﻫﻤﻮاره ﺑﻪ ﻋﻨﻮان ﻧﺴﻞ دو در ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻴﺸﻮﻧﺪ‪ ،‬ﺑﻨﺎﺑﺮاﻳﻦ اﻳﻦ اﺷﻴﺎ ﺑﺎﻳﺪ ﻓﻘﻂ ﺑﺮاي ﻣﻨﺎﺑﻌﻲ ﻛﻪ ﻣﺪت زﻣﺎن زﻳﺎدي در ﺣﺎﻓﻈﻪ‬ ‫ﻣﻲ ﻣﺎﻧﻨﺪ اﻳﺠﺎد ﺷﻮﻧﺪ‪ .‬ﺗﺨﺼﻴﺺ اﺷﻴﺎﻳﻲ ﻛﻪ داراي ﻃﻮل ﻋﻤﺮ ﻛﻮﺗﺎه ﻫﺴﺘﻨﺪ در ﻗﺴﻤﺖ اﺷﻴﺎي ﺑﺰرگ ﺑﺎﻋﺚ ﻣﻴﺸﻮد ﻛﻪ ﻋﻤﻞ ﺟﻤـﻊ آوري‬ ‫ﻧﺴﻞ دو ﺳﺮﻳﻌﺘﺮ اﻧﺠﺎم ﺷﻮد و اﻳﻦ ﻣﻮرد ﻧﻴﺰ ﺑﻪ ﺑﺎزدﻫﻲ و ﻛﺎراﻳﻲ ﺑﺮﻧﺎﻣﻪ ﺻﺪﻣﻪ وارد ﻣﻴﻜﻨﺪ‪.‬‬

‫‪٩٥٠‬‬

:‫ﻣﻨﺎﺑﻊ‬ 1) 2) 3) 4) 5) 6) 7)

٩٥١

Wrox Press – Beginning Visual C# 2005 Worx Press – Beginnign Visual Basic .NET 2005 O'Reilly Press – C# Essentials Second Edition Microsoft Press – Microsoft Visual C# .NET Step By Step O'Reilly Press – Learning C# William Pollock – The Book Of Visual Studio .NET Micorosft Press – Applied Microsoft .NET Framework Programming

More Documents from "Ali Behzadian Nejad"

1388-02-20-01
May 2020 3
Learnvisualc#farsi
April 2020 5
1388-02-21-01
May 2020 2
1388-02-27-01
May 2020 3
1388-02-24-01
May 2020 2