Bie nv e nido a l cur so de I nt r oducción a .N ET con Visua l Ba sic 2 0 1 0 En est e cur so podr ás apr ender a desar r ollar aplicaciones Windows con Visual St udio 2 0 1 0 , y t er m inar em os desar r ollando una aplicación r eal con los concept os apr endidos. Al final de cada lección t endr ás disponible un video en el que podr ás ver los concept os ex plicados de for m a pr áct ica sobr e el ent or no de Visual St udio 2010. Est e cur so le enseñar á ent r e ot r as cosas: Las car act er íst icas fundam ent ales del lenguaj e Visual Basic Cóm o cr ear aplicaciones Windows con Visual St udio 2010 Ut ilizar cont r oles en sus aplicaciones Tr abaj ar con im ágenes y gr áficos en 2D y 3D Desplegar las aplicaciones que desar r olle Ut ilizar las clases que se incluyen en la libr er ía de .NET Acceder a dat os pr ovenient es de una base de dat os Conocer en qué consist e LI NQ y com o ut ilizar lo en Visual Basic Cóm o exponer funcionalidad a ot r as aplicaciones m ediant e ser vicios Web. Te r ecom endam os t am bién que v eas la aplicación MSDN Video, que desar r ollar em os al finalizar el cur so y de la que podr ás consult ar su código fuent e y v ideos explicat ivos. Recuer da que si quier es poner en pr áct ica est e cur so t ienes disponible una v er sión sin lim it aciones de Visual Basic 2010 Ex pr ess, que incluye la base de dat os SQL Ser ver 2005 Expr ess. Puedes descar gar la en el ár ea de v er siones Ex pr ess. ¡Disfr ut a del cur so! Ace r ca de los a u t or e s Guiller m o Som Guiller m o Som , m ás conocido com o "el Guille", es Micr osoft MVP ( Most Valuable Pr ofessional) de Visual Basic desde 1997. Mant iene el sit io web www.elguille.info dedicado a la pr ogr am ación con Visual Basic y t odo lo r elacionado con punt o NET. Tam bién es aut or de var ios libr os sobr e Visual Basic .NET y C# , y escr ibe par a r evist as y ot r os m edios especializados en pr ogr am ación. Tam bién es m iem br o de I net a Speaker s Bur eau Lat in Am ér ica y Ment or de Solid Qualit y Ment or s. Unai Zor r illa Llev a 10 años desar r ollando soft war e com o consult or independient e y en diver sas em pr esas pr iv adas, r ealizando las t ar eas de ar quit ect ur a de soft war e baj o la plat afor m a .NET, abar cando desde el desar r ollo con disposit iv os m óviles y ent or nos web, hast a el desar r ollo con Windows For m s. Es Micr osoft MVP de Com pact Fr am ewor k, colabor a act ivam ent e con Micr osoft en event os de for m ación y es aut or de num er osos ar t ículos t écnicos en r evist as especializadas com o MTJ.NET, MSDN Online y Dot Net Manía. Act ualm ent e t r abaj a com o consult or de gr an em pr esa en Plain Concept s em pr esa de la cuál es socio fundador . Jor ge Ser r ano Jor ge Ser r ano es MVP de Visual Basic y t r abaj a act iv am ent e con la com unidad de desar r ollo en España y Andor r a. Mant iene el sit io web www.por t alv b.com y es escr it or de var ios libr os sobr e I nt er net y t ecnologías de desar r ollo Micr osoft adem ás de colabor ador asiduo de las r evist as especializadas del sect or . Est e m ódulo pr esent a con car áct er gener al la plat afor m a .NET y cóm o ést a se difer encia de ot r os sist em as de desar r ollo t r adicionales, com o ASP. Le cción 1 : I n t r odu cción a la pla t a for m a .N ET ¿Qué es la plat afor m a .NET? El ent or no de ej ecución CLR Lección 2 : El lenguaj e int er m edio y el CLS El lenguaj e int er m edio La especificación com ún de los lenguaj es .NET El sist em a de t ipos com unes Lección 3 : La bibliot eca de clases de .N ET La BCL Los espacios de nom br es Lección 4 : Acceso a dat os con AD O.N ET ADO.NET La ar quit ect ur a de ADO.NET Capa conect ada de dat os Capa desconect ada Lección 5 : LI N Q I nt r oducción a LI NQ Lección 6 : Aplicaciones W indow s For m s I nt r oducción WPF Lección 7 : Aplicaciones W eb For m s I nt r oducción Silv er light Sim plificando m ucho las cosas par a poder dar una definición cor t a y com pr ensible, se podr ía decir que la plat afor m a .N ET es un am plio conj unt o de bibliot ecas de desar r ollo que pueden ser ut ilizadas por ot r as aplicaciones par a aceler ar enor m em ent e el desar r ollo y obt ener de m aner a aut om át ica car act er íst icas avanzadas de segur idad, r endim ient o, et c... En r ealidad .NET es m ucho m ás que eso ya que ofr ece un ent or no gest ionado de ej ecución de aplicaciones, nuevos lenguaj es de pr ogr am ación y com pilador es, y per m it e el desar r ollo de t odo t ipo de funcionalidades: desde pr ogr am as de consola o ser vicios Windows hast a aplicaciones par a disposit ivos m óviles, pasando por desar r ollos de escr it or io o par a I nt er net . Son est os últ im os de los que nos ocupar em os en est e cur so. Per o ant es conviene conocer los fundam ent os en los que se basa cualquier aplicación cr eada con .NET, incluyendo las que nos int er esan. El e n t or no de e j e cución CLR .NET ofr ece un ent or no de ej ecución par a sus aplicaciones conocido com o Com m on Language Runt im e o CLR. El CLR es la im plem ent ación de Micr osoft de un est ándar llam ado Com m on Language I nfr ast r uct ur e o CLI . Ést e fue cr eado y pr om ovido por la pr opia Micr osoft per o desde hace años es un est ándar r econocido m undialm ent e por el ECMA. El CLR/ CLI esencialm ent e, define un ent or no de ej ecución vir t ual independient e en el que t r abaj an las aplicaciones escr it as con cualquier lenguaj e .NET. Est e ent or no vir t ual se ocupa de m ult it ud de cosas im por t ant es par a una aplicación: desde la gest ión de la m em or ia y la vida de los obj et os, hast a la segur idad y la gest ión de subpr ocesos. Todos est os ser vicios unidos a su independencia r espect o a ar quit ect ur as com put acionales, convier t en al CLR en una her r am ient a ext r aor dinar iam ent e út il puest o que, en t eor ía, cualquier aplicación escr it a par a funcionar según la CLI puede ej ecut ar se en cualquier t ipo de ar quit ect ur a de har dwar e. Por ej em plo Micr osoft dispone de im plem ent aciones de .NET par a Windows de 32 bit s, Windows de 64 bit s e incluso par a Windows Mobile, cuyo har dwar e no t iene nada que ver con la ar quit ect ur a de un or denador com ún. Al cont r ar io que ot r os ent or nos, la plat afor m a .NET no est á at ada a un det er m inado lenguaj e de pr ogr am ación ni favor ece a uno det er m inado fr ent e a ot r os. En la act ualidad exist en im plem ent aciones par a var ias decenas de lenguaj es que per m it en escr ibir aplicaciones par a la plat afor m a .NET. Los m ás conocidos son Visual Basic .N ET o C# , per o exist en im plem ent aciones de t odo t ipo, com o F# , Pyt hon, For t r an, e incluso COBOL. Lo m ej or de t odo es que cualquier com ponent e cr eado con uno de est os lenguaj es puede ser ut ilizado de for m a t r anspar ent e desde cualquier ot r o lenguaj e .NET. Adem ás, com o ya se ha com ent ado, es posible ej ecut ar el código .NET en difer ent es plat afor m as y sist em as oper at ivos. ¿Cóm o se consigue est a pot ent e capacidad? Dent r o del CLI , exist e un lenguaj e llam ado I L ( I nt er m ediat e Language o Lenguaj e I nt er m edio) que est á pensado de for m a independient e al pr ocesador en el que se vaya a ej ecut ar . Es algo par ecido al código ensam blador per o de m ás alt o nivel y cr eado par a un hipot ét ico pr ocesador vir t ual que no est á at ado a una ar quit ect ur a det er m inada. Cuando se com pila una aplicación escr it a en un lenguaj e .NET cualquier a ( da igual que sea VB, C# u ot r o de los sopor t ados) , el com pilador lo que gener a en r ealidad es un nuevo código escr it o en est e lenguaj e int er m edio. Así, t odos los lenguaj es .NET se usan com o capa de m ás alt o nivel par a pr oducir código I L. Un elem ent o fundam ent al del CLR es el com pilador JI T ( j ust - in- t im e) . Su com et ido es el de com pilar baj o dem anda y de m aner a t r anspar ent e el código escr it o en lenguaj e int er m edio a lenguaj e nat ivo del pr ocesador físico que va a ej ecut ar el código. Al final, lo que se ej ecut a es código nat ivo que ofr ece un elevado r endim ient o. Est o es cier t o t am bién par a las aplicaciones Web escr it as con ASP.NET y cont r ast a con las aplicaciones basadas en ASP clásico que er an int er pr et adas, no com piladas, y que j am ás podr ían llegar al nivel de desem peño que ofr ece ASP.NET. La siguient e figur a m uest r a el aspect o que t iene el código int er m edio de una aplicación sencilla y se puede obt ener usando el desem sam blador que viene con la plat afor m a .NET. Figur a 1.1. Código en lenguaj e int er m edio obt enido con I LDASM.exe La e spe cifica ción com ún de los le ngua j e s y e l sist e m a de t ipos com une s Par a conseguir la int er oper abilidad ent r e lenguaj es, no sólo se llega int er m edio, sino que es necesar io disponer de unas "r eglas del j uego" conj unt o de car act er íst icas que t odos los lenguaj es deben incor por ar y conj unt o r egulador se le denom ina Com m on Language Specificat ion ( CLS) especificación com ún de los lenguaj es. con el lenguaj e que definan un cum plir . A est e o, en cast ellano, Ent r e las cuest iones que r egula el CLS se encuent r an la nom enclat ur a, la for m a de definir los m iem br os de los obj et os, los m et adat os de las aplicaciones, et c... Una de las par t es m ás im por t ant es del CLS es la que se r efier e a los t ipos de dat os. Si alguna vez ha pr ogr am ado la API de Windows o ha t r at ado de llam ar a una DLL escr it a en C+ + desde Visual Basic 6, habr á com pr obado lo difer ent es que son los t ipos de dat os de VB6 y de C+ + . Par a evit ar est e t ipo de pr oblem as y poder gest ionar de for m a eficient e y segur a el acceso a la m em or ia, el CLS define un conj unt o de t ipos de dat os com unes ( Com m on Type Syst em o CTS) que indica qué t ipos de dat os se pueden m anej ar , cóm o se declar an y se ut ilizan ést os, y de qué m aner a se deben gest ionar dur ant e la ej ecución. Si nuest r as bibliot ecas de código ut ilizan en sus int er faces hacia el ext er ior dat os definidos dent r o de la CTS no exist ir án pr oblem as a la hor a de ut ilizar los desde cualquier ot r o código escr it o en la plat afor m a .NET. Cada lenguaj e .NET ut iliza una sint axis difer ent e par a cada t ipo de dat os. Así, por ej em plo, el t ipo com ún cor r espondient e a un núm er o ent er o de 32 bit s ( Syst em .I nt 3 2 ) se denom ina I nt eger en Visual Basic .NET, per o se llam a int en C# . En am bos casos r epr esent an el m ism o t ipo de dat os que es lo que r ealm ent e cuent a ( Syst em .I nt 3 2 ) . N ot a: En ASP 3.0 se suele usar VBScr ipt com o lenguaj e de pr ogr am ación. En est e lenguaj e int er pr et ado, al igual que en VB6, un I nt eger r epr esent aba un ent er o de 16 bit s. Los ent er os de 32 bit s er an de t ipo Long. Es un fallo m uy com ún usar desde Visual Basic .NET el t ipo I nt eger pensando que es de 16 bit s cuando en r ealidad es capaz de alber gar núm er os m ucho m ayor es. Téngalo en cuent a si ust ed est á fam iliar izado con Visual Basic 6 o ant er ior es cuando em piece a pr ogr am ar . Exist en t ipos por valor ( com o los ent er os que hem os m encionado o las enum er aciones) y t ipos por r efer encia ( com o las clases) . En el siguient e m ódulo se pr ofundiza en t odas est as cuest iones. Todo lo que se ha est ado com ent ando hast a ahor a en el cur so const it uye la base de la plat afor m a .NET. Si bien es m uy int er esant e y fundam ent al, por sí m ism o no nos ser vir ía de m ucho par a cr ear pr ogr am as si debiésem os cr ear t oda la funcionalidad desde cer o. Obviam ent e est o no es así, y la plat afor m a .NET nos ofr ece infinidad de funcionalidades "de fábr ica" que se ut ilizan com o punt o de par t ida par a cr ear las aplicaciones. Exist en funcionalidades básicas ( por ej em plo t odo lo r elacionado con la E/ S de dat os o la segur idad) y funcionalidades avanzadas en las que se fundam ent an cat egor ías ent er as de aplicaciones ( acceso a dat os, cr eación de aplicaciones Web...) . Toda est a funcionalidad est á im plem ent ada en for m a de bibliot ecas de funciones que físicam ent e se encuent r an en diver sas DLL ( bibliot ecas de enlazado dinám ico) . A su conj unt o se le denom ina Base Classes Libr ar y ( Bibliot eca de clases base o BCL) , y for m an par t e int egr al de la plat afor m a .NET, es decir , no se t r at a de añadidos que se deban obt ener o adquir ir apar t e. La siguient e figur a ilust r a a vist a de páj ar o la ar quit ect ur a concept ual gener al de la plat afor m a .NET. En ella se pueden obser var los elem ent os que se han m encionado en apar t ados ant er ior es ( lenguaj es, CLR, CLS...) y en qué lugar se ubican las bibliot ecas de clases base: Figur a 1 .2 . D ist int os elem ent os de la plat afor m a .N ET y cóm o se r elacionan ent r e sí. Result a m uy út il par a com pr ender lo explicado hast a ahor a. No se pr eocupe si hay elem ent os que no conoce u ot r os elem ent os que echa en falt a en est e gr áfico, m ás adelant e est udiar em os t odos los elem ent os y algunos que no apar ecen aquí com o por ej em plo LI NQ, y el cual ver em os m ás adelant e. Todo lo que se encuent r a en la BCL for m a par t e de la plat afor m a .NET. De hecho exist e t al cant idad de funcionalidad int egr ada dent r o de est as bibliot ecas ( hay m ás de 4000 clases) que el m ayor esfuer zo que t odo pr ogr am ador que se inicia en .NET debe hacer es el apr endizaj e de las m ás im por t ant es, aum ent ando el conocim ient o del r est o a base de pr áct ica. De t odos m odos Visual St udio ofr ece m ucha ayuda cont ext ual ( docum ent ación, I nt ellisense...) y una vez que se apr enden los r udim ent os r esult a fácil ir avanzando en el conocim ient o de la BCL a m edida que lo vam os necesit ando. Los e spa cios de nom br e s Dada la ingent e cant idad de clases con la que podem os t r abaj ar , debe exist ir alguna for m a de or ganizar las de un m odo coher ent e. Adem ás hay que t ener en cuent a que podem os adquir ir m ás funcionalidades ( que se t r aducen en clases) de ot r os fabr icant es, por no m encionar que cr ear em os cont inuam ent e nuevas clases pr opias. Par a solucionar est e pr oblem a exist en en t odos los lenguaj es .NET los espacios de nom br es o nam espaces. Un espacio de nom br es no es m ás que un ident ificador que per m it e or ganizar de m odo est anco las clases que est én cont enidas en él así com o ot r os espacios de nom br es. Así por ej em plo, t odo lo que t iene que ver con el m anej o de est r uct ur as de dat os XML en la plat afor m a .NET se encuent r a baj o el espacio de nom br es Syst em .Xm l. La funcionalidad fundam ent al par a cr ear aplicaciones Web est á en el espacio de nom br es Syst em .W eb. Ést e a su vez cont iene ot r os espacios de nom br es m ás especializados com o Syst em .W eb.Caching par a la per sist encia t em por al de dat os, Syst em .W eb.UI .W ebCont r ols, que cont iene t oda la funcionalidad de cont r oles Web par a int er faz de usuar io, et c... No obst ant e, en n uest r os desar r ollos int er nos cr ear em os nuest r as pr opias clases dent r o de nom br es de espacio concr et os. Est o nos ayudar á a localizar e int er pr et ar r ápidam ent e la división y subdivisión de nuest r os obj et os. Un aspect o a t ener en cuent a, es t r at ar de evit ar cr ear nuest r os nom br es de espacio de for m a idént ica a la que Micr osoft ha ut ilizado la los nom br es de espacio de .NET Fr am ewor k, per o est o es algo que ir em os solvent ando con pr áct ica y at ención. El acceso a fuent es de dat os es algo indispensable en cualquier lenguaj e o plat afor m a de desar r ollo. La par t e de la BCL que se especializa en el acceso a dat os se denom ina de for m a genér ica com o AD O.N ET. Si ust ed ha pr ogr am ado con Visual Basic 6.0 ó con ASP, ha em pleado en su código con t ot al segur idad la int er faz de acceso a dat os conocida com o ADO ( Act iveX Dat a Obj ect s) , y posiblem ent e lo ha com binado adem ás con ODBC ( Open Dat abase Connect ivit y) . Si adem ás es ust ed de los pr ogr am ador es con soler a y lleva unos cuant os años en est o, es pr obable que haya usado RDO o incluso DAO, t odos ellos m ét odos m ucho m ás ant iguos. ADO.NET ofr ece una funcionalidad com plet am ent e nueva, que t iene poco que ver con lo exist en t e hast a la fecha en el m er cado. Sin em bar go, con el ánim o de r et ir ar bar r er as a su apr endizaj e, Micr osoft denom inó a su nuevo m odelo de acceso a dat os con un nom br e sim ilar y algunas de sus clases r ecuer dan a obj et os de pr opósit o análogo en el vet ust o ADO. ADO.NET es un m odelo de acceso m ucho m ás or ient ado al t r abaj o desconect ado de las fuent es de dat os de lo que nunca fue ADO. Si bien est e últ im o ofr ecía la posibilidad de desconect ar los Recor dset s y ofr ecía una for m a de ser ialización de est os a t r avés de las difer ent es capas de una aplicación, el m ecanism o no es ni de lej os t an pot ent e com o el que nos ofr ece ADO.NET. El obj et o m ás im por t ant e a la hor a de t r abaj ar con el nuevo m odelo de acceso a dat os es el D at aSet . Sin exager ar dem asiado podr íam os calificar lo casi com o un m ot or de dat os r elacionales en m em or ia. Aunque hay quien lo asim ila a los clásicos Recor dset s su funcionalidad va m ucho m ás allá com o se ver á en el cor r espondient e m ódulo. Ar q uit e ct ur a d e AD O.N ET El concept o m ás im por t ant e que hay que t ener clar o sobr e ADO.NET es su m odo de funcionar , que se r evela clar am ent e al analizar su ar quit ect ur a: Figur a 1 .3 .- Ar quit ect ur a de AD O.N ET Exist en dos capas fundam ent ales dent r o de su ar quit ect ur a: la capa conect ada y la desconect ada. Ca pa con e ct a da La pr im er a de ellas cont iene obj et os especializados en la conexión con los or ígenes de dat os. Así, la clase genér ica Connect ion se ut iliza par a est ablecer conexiones a los or ígenes de dat os. La clase Com m and se encar ga de enviar com andos de t oda índole al or igen de dat os. Por fin la clase D at aReader est á especializada en leer los r esult ados de los com andos m ient r as se per m anece conect ado al or igen de dat os. La clase D at aAdapt er hace uso de las t r es ant er ior es par a act uar de puent e ent r e la capa conect ada y la desconect ada. Est as clases son abst r act as, es decir , no t ienen una im plem ent ación r eal de la que se pueda hacer uso dir ect am ent e. Es en est e punt o en donde ent r an en j uego los pr oveedor es de dat os. Cada or igen de dat os t iene un m odo especial de com unicar se con los pr ogr am as que los ut ilizan, adem ás de ot r as par t icular idades que se deben cont em plar . Un pr oveedor de dat os de ADO.NET es una im plem ent ación concr et a de las clases conect adas abst r act as que hem os vist o, que her eda de ést as y que t iene en cuent a ya t odas las par t icular idades del or igen de dat os en cuest ión. Así, por ej em plo, las clases específicas par a acceder a SQL Ser ver se llam an SqlConnect ion, SqlCom m and, SqlD at aReader y SqlD at aAdapt er y se encuent r an baj o el espacio de nom br es Syst em .D at a.SqlClient . Es decir , al cont r ar io que en ADO clásico no hay una única clase Connect ion o Com m and que se use en cada caso, si no que exist en clases especializadas par a conect ar se y r ecuper ar infor m ación de cada t ipo de or igen de dat os. N ot a: El hecho de ut ilizar clases concr et as par a acceso a las fuent es de dat os no significa que no sea posible escr ibir código independient e del or igen de dat os. Todo lo cont r ar io. La plat afor m a .NET ofr ece gr andes facilidades de escr it ur a de código genér ico basadas en el uso de her encia e im plem ent ación de int er faces. De hecho la ver sión 2.0 de .NET ofr ece gr andes novedades específicam ent e en est e ám bit o. Exist en pr oveedor es nat ivos, que son los que se com unican dir ect am ent e con el or igen de dat os ( por ej em plo el de SQL Ser ver o el de Or acle) , y pr oveedor es " puent e" , que se ut ilizan par a acceder a t r avés de ODBC u OLEDB cuando no exist e un pr oveedor nat ivo par a un det er m inado or igen de dat os. N ot a: Est os pr oveedor es puent e, si bien m uy út iles en det er m inadas cir cunst ancias, ofr ecen un r endim ient o m enor debido a la capa int er m edia que est án ut ilizando ( ODBC u OLEDB) . Un pr ogr am ador novel puede sent ir la t ent ación de ut ilizar siem pr e el pr oveedor puent e par a OLEDB y así escr ibir código com pat ible con diver sos gest or es de dat os de for m a m uy sencilla. Se t r at a de un er r or y siem pr e que sea posible es m ej or ut ilizar un pr oveedor nat ivo. Ca pa de scon e ct a da Una vez que ya se han r ecuper ado los dat os desde cualquier or igen de dat os que r equier a una conexión ést a ya no es necesar ia. Sin em bar go sigue siendo necesar io t r abaj ar con los dat os obt enidos de una m aner a flexible. Es aquí cuando la capa de dat os desconect ada ent r a en j uego. Adem ás, en m uchas ocasiones es necesar io t r at ar con dat os que no han sido obt enidos desde un or igen de dat os r elacional con el que se r equier a una conexión. A veces únicam ent e necesit am os un alm acén de dat os t em por al per o que ofr ezca car act er íst icas avanzadas de gest ión y acceso a la infor m ación. Por ot r a par t e las conexiones con las bases de dat os son uno de los r ecur sos m ás escasos con los que cont am os al desar r ollar . Su m ala ut ilización es la causa m ás fr ecuent e de cuellos de bot ella en las aplicaciones y de que ést as no escalen com o es debido. Est a afir m ación es especialm ent e im por t ant e en las aplicaciones Web en las que se pueden r ecibir m uchas solicit udes sim ult áneas de cualquier par t e del m undo. Finalm ent e ot r o m ot ivo por el que es im por t ant e el uso de los dat os desconect ado de su or igen es la t r ansfer encia de infor m ación ent r e capas de una aplicación. Ést as pueden encont r ar se dist r ibuidas por difer ent es equipos, e incluso en difer ent es lugar es del m undo gr acias a I nt er net . Por ello es necesar io disponer de algún m odo genér ico y eficient e de poder t r anspor t ar los dat os ent r e difer ent es lugar es, ut ilizar los en cualquier a de ellos y post er ior m ent e t ener la capacidad de conciliar los cam bios r ealizados sobr e ellos con el or igen de dat os del que pr oceden. Todo est o y m ucho m ás es lo que nos ot or ga el uso de los obj et os D at aSet . Es obvio que no se t r at a de t ar eas t r iviales, per o los obj et os Dat aSet est án pensados y diseñados con est os obj et ivos en m ent e. Com o podr em os com pr obar m ás adelant e en est e cur so es bast ant e sencillo conseguir est as funcionalidades t an avanzadas y algunas ot r as sim plem ent e usando de m aner a adecuada est e t ipo de obj et os. N ot a: Ot r a in t er esant e car act er íst ica de los Dat aSet es que per m it en gest ionar sim ult áneam ent e diver sas t ablas ( r elaciones) de dat os, cada una de un or igen difer ent e si es necesar io, t eniendo en cuent a las r est r icciones y las r elaciones exist ent es ent r e ellas. Los Dat aSet , com o cualquier ot r a clase no sellada de .NET, se pueden ext ender m ediant e her encia. Ello facilit a una t écnica avanzada que consist e en cr ear t ipos nuevos de Dat aSet especializados en la gest ión de una infor m ación concr et a ( por ej em plo un conj unt o de t ablas r elacionadas) . Est as nuevas t ipos clases se denom inan genér icam ent e D at aSet Tipados, y per m it en el acceso m ucho m ás cóm odo a los dat os que r epr esent an, ver ificando r eglas de negocio, y validaciones de t ipos de dat os m ás est r ict as. LI NQ es quizás una de las car act er íst icas m ás novedosas int r oducidas en Micr osoft .NET Fr am ewor k en los últ im os años. No cej ar é en anim ar le a usar LI NQ siem pr e que pueda, no por que sea m ej or que ot r as for m as de t r abaj ar que encont r ar á en Micr osoft .NET Fr am ewor k, sino por que sim plifica el código, acor t a los t iem pos de desar r ollo, y baj o m i par t icular punt o de vist a, per m it e que el desar r ollador desar r olle aplicaciones m ás pr oduct ivas. LI NQ significa Language I N t egr at ed Quer y, o lo que es lo m ism o, lenguaj e int egr ado de consult as. Se t r at a de una de las novedades incluidas en Micr osoft .NET Fr am ewor k 3.5 y cont inuada en Micr osoft .NET Fr am ewor k 4.0, y r epr esent a una for m a nueva de desar r ollo t al y com o la conocíam os hast a ahor a. LI NQ est á pensado desde la or ient ación a obj et os, per o su obj et ivo fundam ent al es la m anipulación y t r abaj o con dat os. Cuando hablam os de dat os siem pr e pensam os en bases de dat os, per o LI NQ t iene una im plicación m ucho m ás gener alist a, de hecho, podem os t r abaj ar con colecciones, m at r ices, et c. Par a que com pr enda m ás aún la im por t ancia de LI NQ, dir em os que la inm ensa m ayor ía de las novedades int r oducidas en Micr osoft .NET Fr am ewor k 3.5 t ienen su r azón de ser gr acias a LI NQ, y que LI NQ j uega un im por t ant e papel en las novedades de Micr osoft .NET Fr am ewor k 4.0 y en las pr óxim as novedades de Micr osoft .NET Fr am ewor k. A la hor a de t r abaj ar con dat os, con LI NQ t enem os la posibilidad de seleccionar , m anipular y filt r ar dat os com o si est uviér am os t r abaj ando con una base de dat os dir ect am ent e. Evident em ent e, podem os usar LI NQ con bases de dat os, per o t am bién con m at r ices, colecciones de dat os, et c com o decíam os ant es. En t odo est o, I nt ellisense j uega un papel m uy im por t ant e evit ando que com et am os er r or es a la hor a de escr ibir nuest r as aplicaciones, er r or es com o por ej em plo seleccionar el dat o er r óneo o el t ipo de dat o inadecuado, ya que el com pilador nos avisar ía de est os y ot r os er r or es. Por lo t ant o, el desar r ollo de aplicaciones con LI NQ, per m it e diseñar aplicaciones m ás segur as a la hor a de t r abaj ar con dat os y sus t ipos. Or íge n e s de da t os Dent r o de LI NQ encont r am os difer ent es or ígenes de dat os dent r o de Micr osoft .NET Fr am ewor k 3.5 ó post er ior . Est os or ígenes de dat os son los siguient es: LI NQ t o Obj ect s: r epr esent a el uso de LI NQ sobr e obj et os. LI NQ t o XML: r epr esent a el uso de LI NQ sobr e docum ent os XML. ADO.NET y LI NQ: dent r o de est e gr upo encont r am os los difer ent es or ígenes de dat os de LI NQ que t ienen r elación dir ect a con dat os r elacionales. Los or ígenes de dat os de LI NQ y ADO.NET son: LI NQ t o Dat aSet : r epr esent a el uso de LI NQ sobr e Dat aSet . LI NQ t o SQL: r epr esent a el uso de LI NQ sobr e or ígenes de dat os de SQL Ser ver . LI NQ t o Ent it ies: r epr esent a el uso de LI NQ sobr e cualquier or igen de dat os, SQL Ser ver , Or acle, MySql, DB2, et c. Com o vem os, LI NQ abar ca m ás que el pr opio t r abaj o con dat os de bases u or ígenes de dat os. Así, con LI NQ podem os m anipular y t r abaj ar con dat os de obj et os o de docum ent os XML. Est e últ im o r epr esent a una im por t ant e vent aj a par a los desar r ollador es de VB r espect o a los desar r ollador es de C# , ya que el equipo de t r abaj o de VB ha hecho especial énfasis al t r abaj o de LI NQ con docum ent os XML m ot ivado por el feedback r ecibido por la Com unidad de desar r ollador es de t odo el m undo. De t odas las m aner as, cabe r ecor dar que no exist en gr andes difer encias ent r e los equipos de Micr osoft encar gados de dot ar de novedades o m ej or as a VB y a C# , ya que Micr osoft ha em peñado sus esfuer zos m ás r ecient es en que los avances de am bos lenguaj es vayan de la m ano. Más adelant e en est e cur so, ver em os com o ut ilizar LI NQ y com o apr ovechar t odas las vent aj as que nos ofr ece. Las aplicaciones de escr it or io son aquellas basadas en vent anas y cont r oles com unes de Windows que se ej ecut an en el sist em a local. Son el m ism o t ipo de aplicaciones que ant es const r uir íam os con Visual Basic 6 u ot r os ent or nos sim ilar es. En la plat afor m a .NET, el espacio de nom br es que ofr ece las clases necesar ias par a const r uir aplicaciones de escr it or io baj o Windows se denom ina W indow s For m s. Est e es t am bién el nom br e genér ico que se le ot or ga ahor a a est e t ipo de pr ogr am as basados en vent anas. Windows For m s est á const it uido por m ult it ud de clases especializadas que ofr ecen funcionalidades par a el t r abaj o con vent anas, bot ones, r ej illas, cam pos de t ext o y t odo est e t ipo de cont r oles habit uales en las aplicaciones de escr it or io. Visual St udio ofr ece t odo lo necesar io par a cr ear visualm ent e est e t ipo de pr ogr am as, de un m odo sim ilar aunque m ás r ico al que ofr ecía el ent or no de desar r ollo int egr ado de Visual Basic. Figur a 1 .4 .- D iseñador de int er faces de aplicaciones de escr it or io con W indow s For m s en Visual St udio. Al cont r ar io que en en VB6, .NET pr opor ciona cont r ol sobr e t odos los aspect os de las vent anas y cont r oles, no dej ando nada fuer a del alcance del pr ogr am ador y ot or gando por lo t ant o la m áxim a flexibilidad. Los for m ular ios ( vent anas) son clases que her edan de la clase base For m , y cuyos cont r oles son m iem br os de ést a. De hecho se t r at a únicam ent e de código y no es necesar io ( aunque sí m uy r ecom endable) em plear el diseñador gr áfico de Visual St udio par a cr ear las. Est e es el aspect o que pr esent a par t e del código que gener a la int er faz m ost r ada en la ant er ior figur a: Figur a 1 .5 .- Código aut ogener ado por Visual St udio par a cr ear la int er faz de la figur a ant er ior . Al cont r ar io que en Visual Basic t r adicional, en donde siem pr e exist ían inst ancias por defect o de los for m ular ios que podíam os usar dir ect am ent e, en .NET es necesar io cr ear un obj et o ant es de poder hacer uso de los for m ular ios: Dim frm As New MiFormulario frm.Show() Todos los cont r oles her edan de una clase Cont r ol por lo que conser van una ser ie de funcionalidades com unes m uy int er esant es, com o la capacidad de gest ionar los en el diseñador ( m oviéndolos, alineándolos...) , de definir m ár genes ent r e ellos o hacer que se adapt en al t am año de su cont enedor . W PF Sin em bar go, en los últ im os años Micr osoft ha est ado t r abaj ando int ensam ent e en lo que se ha denom inado com o WPF, o lo que es lo m ism o, Windows Pr esent at ion Foundat ion. WPF es "ot r a for m a" de cr ear aplicaciones de escr it or io con un enr iquecim ient o en la exper iencia del usuar io. Con la apar ición de Windows Vist a, se hizo m ucho m ás pr esent e que ant es la pr esent ación t r idim ensional de gr áficos, im ágenes, así com o efect os m ult im edia m uy var iados. Windows 7 por su par t e, cont inúa la r ut a m ar cada por Windows Vist a par a la cr eación de aplicaciones Windows r icas. WPF facilit a al desar r ollador la cr eación de aplicaciones de escr it or io m ás r icas, apor t ando al usuar io una exper iencia nunca vist a en las aplicaciones de est e t ipo. El or igen de WPF no obst ant e, hay que buscar lo en Micr osoft .NET Fr am ewor k 3.0, y es a par t ir de Micr osoft .NET Fr am ewor k 3.5 sobr e t odo, cuando est a t ecnología ha em pezando a cr ear se un hueco de r efer encia dent r o del m er cado de desar r ollo de aplicaciones Soft war e. ¿Quier e apr ender W PF? Recuer de que t iene la posibilidad de acceder gr at uit am ent e a un cur so dedicado en exclusiva a WPF. Tr adicionalm ent e las aplicaciones Web se han desar r ollado siguiendo un m odelo m ixt o que int er calaba código HTML y JavaScr ipt pr opio de páginas Web ( par t e client e) , j unt o con código que se ej ecut ar ía en el ser vidor ( par t e ser vidor a) . Est e m odelo cont r ast aba por com plet o con el m odelo or ient ado a event os seguido por las pr incipales her r am ient as de desar r ollo de aplicaciones de escr it or io. En el m odelo or ient ado a event os se define la int er faz de usuar io colocando cont r oles en un cont enedor y se escr ibe el código que act uar á com o r espuest a a las int er acciones de los usuar ios sobr e est os cont r oles. Si conoce el diseñador de VB6 o de Windows For m s m encionado en el apar t ado ant er ior sabe exact am ent e a qué nos r efer im os. Hacer est o en una aplicación de escr it or io no t iene m ayor dificult ad ya que t odo el código se ej ecut a en el m ism o lugar . La pr incipal car act er íst ica de las aplicaciones Web sin em bar go es que se la int er faz de usuar io ( lo que los usuar ios de la aplicación ven) se ej ecut a en un lugar difer ent e al código de la aplicación que r eside en un ser vidor . Par a m ayor desgr acia est as aplicaciones se basan en el uso del pr ot ocolo HTTP que es un pr ot ocolo sin est ado y que no conser va la conexión ent r e dos llam adas consecut ivas. Por ej em plo, el siguient e código ilust r a el código que es necesar io escr ibir en ASP par a disponer de una página que r ellena una list a de selección con unos cuant os nom br es ( podr ían salir de una base de dat os y aún ser ía m ás com plicado) , y que dispone de un bot ón que escr ibe un saludo par a el nom br e que se haya elegido de la list a. Figur a 1 .6 .- Código ASP sencillo que gener a una list a de selección y saluda al pr esionar un bot ón. Obviam ent e se podr ía haber sim plificado sin enviar el for m ular io al ser vidor usando JavaScr ipt en el client e par a m ost r ar el saludo, per o la int ención es ilust r ar la m ezcla de código de client e y de ser vidor que exist e en est e t ipo de aplicaciones. Las pr incipales desvent aj as de est e t ipo de codificación son las siguient es: 1. N o exist e separ ación ent r e el diseño y la lógica de las aplicaciones. Si quer em os cam biar sust ancialm ent e la apar iencia de la aplicación Web lo t endr em os bast ant e com plicado puest o que el código del ser vidor est á m ezclado ent r e el HTML. 2. En ASP clásico no exist e el concept o de cont r ol par a la int er faz de u suar io. Lo único que hay es HTML y JavaScr ipt que se deben gener ar desde el ser vidor . En el ej em plo de la figur a par a gener ar un cont r ol de list a con unos elem ent os no podem os asignar una pr opiedad de la list a ( por que no exist e t al list a) , sino que t enem os que cr ear un bucle que gener e los elem ent os HTML necesar ios par a gener ar la. Tam poco disponem os de un diseñador visual que nos per m it a gest ionar los cont r oles y elem ent os HTML exist ent es, y m enos cuando ést os se encuent r an m ezclados con el código del ser vidor . 3. N o disponem os de for m a de det ect ar en el ser vidor que se ha r ealizado algo en el client e. El client e se encuent r a desconect ado desde el m om ent o en que se t er m ina de devolver la página. Sólo se r ecibe infor m ación en el ser vidor cuando se solicit a una nueva página o cuando se envía un for m ular io t al y com o se hace en el ej em plo, debiéndonos encar gar nosot r os de aver iguar si la pet ición es la pr im er a vez que se hace o no, y de dar la r espuest a adecuada. En cualquier caso es m ucho m enos int uit ivo que el m odelo de r espuest a a event os de una aplicación de escr it or io. 4. N o exist e const ancia del est ado de los cont r oles de cada página ent r e las llam adas. En cada ej ecución de la página t endr em os que r ecr ear com plet am ent e la salida. Por ej em plo si pr esionam os en el bot ón “ Di Hola” t enem os que escr ibir adem ás de la et iquet a “ Hola, nom br e” el r est o de la pant alla, incluyendo la list a con t odos los nom br es dej ando seleccionado el m ism o que hubiese ant es. Si est os nom br es viniesen de una base de dat os est o puede ser t odavía m ás ineficient e y t endr em os que buscar m ét odos alt er nat ivos par a gener ar los ya que en ASP t am poco se deben alm acenar en los obj et os de sesión y/ o aplicación Recor dset s r esult ado de consult as. 5. N o exist e el concept o de Pr opiedad de los cont r oles. En una aplicación Windows asignam os el t ext o de un cam po usando una pr opiedad ( por ej em plo Text 1.Text = "Hola") y ést a se asigna y per m anece en la int er faz sin que t engam os que hacer nada. En una aplicación Web clásica t enem os que alm acenar las en algún sit io ( una var iable de sesión o un cam po ocult o) par a conser var las ent r e difer ent es pet iciones de una m ism a página. 6. Los cont r oles com plej os no t ienen for m a de enviar sus valor es al ser vidor . Si int ent am os cr ear una int er faz avanzada que ut ilice t ablas y ot r os elem ent os que no son cont r oles de ent r ada de dat os de for m ular ios de HTML t endr em os que invent ar nos m ecanism os pr opios par a r ecoger esos dat os y enviar los al ser vidor . La pr incipal apor t ación de ASP.NET al m undo de la pr ogr am ación es que ha llevado a la Web el par adigm a de la pr ogr am ación or ient ada a event os pr opia de aplicaciones de escr it or io, ofr eciendo: Separ ación ent r e diseño y lógica. Com ponent es de int er faz de usuar io, t ant o est ándar com o de t er cer as em pr esas o pr opios. Diseñador es gr áficos. Event os. Est ado. Enlazado a dat os desde la int er faz. Silv e r light Al igual que par a el desar r ollo de aplicaciones de escr it or io o Windows For m s t eníam os la posibilidad de cr ear aplicaciones de escr it or io de una for m a nat ur al o con WPF, en las aplicaciones Web t enem os la posibilidad de abor dar aplicaciones Web de for m a t r adicional ( la que conocem os hast a ahor a) y t am bién con lo que se ha denom inado Silver light . Silver light , conocido en fase de diseño com o WPF/ E o WPF ext endido, es al igual que ocur r ía con WPF, "ot r a for m a" de cr ear aplicaciones Web apor t ando al usuar io un enr iquecim ient o m ucho m ayor en lo que a la exper iencia del usuar io se r efier e. La posibilidad de que el usuar io int er act úe con la aplicación Soft war e apor t ándole una exper iencia de uso y funcionalidad m ucho m ás agr adable y r ica, apor t a vent aj as a las aplicaciones Web de Silver light sobr e las aplicaciones Web t r adicionales, y m ás aún cuando se t r at an aspect os com o por por ej em plo la fam osa Web 2.0 o SOA. El or igen de Silver light es el m ism o que WPF, y hay que encont r ar lo por lo t ant o en Micr osoft .NET Fr am ewor k 3.0. Sin em bar go, al igual que ocur r ía con WPF, es a par t ir de Micr osoft .NET Fr am ewor k 3.5 sobr e t odo cuando Silver light est á em pezando a ser t enida en cuent a. Silver light com o t al ha evolucionado r ápidam ent e en poco t iem po, pasando de Silver light 1.0 a Silver light 1.1, y de Silver light 1.1 a una gr an evolución con Silver light 2.0. Sin em bar go, Micr osoft ha cont inuado evolucionando a Silver light de las car act er íst icas dem andadas por la com unidad de desar r ollo, y así, ha sacado una nueva act ualización con im por t ant es m ej or as, hablam os de Silver light 3.0. ¿Quier e apr ender m ás acer ca de los Ser vicios W eb? Recuer de que exist e un cur so gr at uit o com plem ent ar io a est e, que le enseñar á aspect os r elacionados únicam ent e con los Ser vicios Web y SOA en gener al. Visual Basic 2010 int r oduce una novedad aplicable en t odos los desar r ollos Soft war e que r ealicem os y en cualquier m om ent o, por ese m ot ivo y ant es de em pezar a desar r ollar el cur so, cr eo convenient e que lo t enga en consider ación. Esa novedad, r ecibe el nom br e de cont inuación de línea im plícit a. En el siguient e ej em plo, podem os ver com o usar la ant igua for m a de r ealizar una cont inuación de línea en Visual Basic: Dim sample As String = "Ejemplo con Visual Basic 2010" & _ Environment.NewLine & _ "Con salto de linea" Est a ant igua for m a, que consist e en cont inuar la línea ut ilizando el car act er _ al final de la m ism a, cont inua siendo válido. Sin em bar go, a par t ir de Visual Basic 2010, t am bién podr em os cont inuar la línea sin necesidad de ut ilizar dicho car act er . Un ej em plo de código com pat ible con lo que est am os diciendo, ser ía el siguient e: Dim sample As String = "Ejemplo con Visual Basic 2010" & Environment.NewLine & "Con salto de linea" Com o vem os, la única difer encia r eside en ut ilizar u om it ir el car act er de salt o de línea _ que ha sido usado desde que apar ecier a la pr im er a ver sión de Visual Basic ant es incluso de la plat afor m a .Net . Le cción 1 : El sist e m a de t ipos Tipos pr im it ivos Var iables y const ant es Enum er aciones Ar r ays ( m at r ices) Le cción 2 : Cla se s y e st r u ct u r a s Clases Definir una clase I nst anciar una clase Est r uct ur as Accesibilidad Pr opiedades I nt er faces Le cción 3 : M a n e j o de e x ce pcion e s Manej o de excepciones Le cción 4 : Eve n t os y de le ga dos Event os Definir y pr oducir event os en una clase Delegados Definir un event o bien infor m ado Le cción 5 : At r ibu t os At r ibut os En est a pr im er a lección ver em os los t ipos de dat os que .NET Fr am ewor k pone a nuest r a disposición y cóm o t endr em os que usar los desde Visual Basic 2010. A cont inuación dar em os un r epaso a concept os básicos o elem ent ales sobr e los t ipos de dat os, que si bien nos ser án fam iliar es, es im por t ant e que lo veam os par a poder com pr ender m ej or cóm o est án definidos y or ganizados los t ipos de dat os en .NET. Visual Basic 2010 est á t ot alm ent e int egr ado con .NET Fr am ewor k, por lo t ant o, los t ipos de dat os que podr em os usar con est e lenguaj e ser án los definidos en est e "m ar co de t r abaj o", por est e m ot ivo vam os a em pezar usando algunas de las definiciones que nos encont r ar em os al r ecor r er la docum ent ación que acom paña a est e lenguaj e de pr ogr am ación. Los t ipos de dat os que podem os usar en Visual Basic 2010 son los m ism o t ipos de dat os definidos en .NET Fr am ewor k y por t ant o est án sopor t ados por t odos los lenguaj es que usan est a t ecnología. Est os t ipos com unes se conocen com o el Com m on Type Syst em , ( CTS) , que t r aducido viene a significar el sist em a de t ipos com unes de .NET. El hecho de que los t ipos de dat os usados en t odos los lenguaj es .NET est én definidos por el pr opio Fr am ewor k nos asegur a que independient em ent e del lenguaj e que est em os usando, siem pr e ut ilizar em os el m ism o t ipo int er no de .NET, si bien cada lenguaj e puede usar un nom br e ( o alias) par a r efer ir se a ellos, aunque lo im por t ant e es que siem pr e ser án los m ism os dat os, independient em ent e de cóm o se llam e en cada lenguaj e. Est o es una gr an vent aj a, ya que nos per m it e usar los sin ningún t ipo de pr oblem as par a acceder a ensam blados cr eados con ot r os lenguaj es, siem pr e que esos lenguaj es sean com pat ibles con los t ipos de dat os de .NET. En los siguient es enlaces t enem os los t em as a t r at ar en est a pr im er a lección del m ódulo sobr e las car act er íst icas del lenguaj e Visual Basic 2010. Tipos pr im it ivos Sufij os o car act er es y sím bolos ident ificador es par a los t ipos Tipos por valor y t ipos por r efer encia I nfer encia de t ipos V a r ia ble s y con st a n t e s Consej o par a usar las const ant es Declar ar var iables Declar ar var iables y asignar el valor inicial El t ipo de dat os Char Obligar a declar ar las var iables con el t ipo de dat os Aplicar Opt ion St r ict On a un ficher o en par t icular Aplicar Opt ion St ict On a t odo el pr oyect o Más opciones aplicables a los pr oyect os Tipos Nullables Tipos anónim os Pr opiedades aut oim plem ent adas I nicialización de colecciones En u m e r a cion e s: Con st a n t e s a gr u pa da s El nom br e de los m iem br os de las enum er aciones Los valor es de una enum er ación no son sim ples núm er os Ar r a ys ( m a t r ice s) Declar ar ar r ays Declar ar e inicializar un ar r ay Cam biar el t am año de un ar r ay Elim inar el cont enido de un ar r ay Los ar r ays son t ipos por r efer encia Lit er ales de ar r ays ( o m at r ices) Veam os en la siguient e t abla los t ipos de dat os definidos en .NET Fr am ewor k y los alias ut ilizados en Visual Basic 2010. .N ET Fr a m e w o r k VB 2 0 1 0 Sy st em .Boolean Boolean Sy st em .By t e By t e Sy st em .I n t 1 6 Sh or t Sy st em .I n t 3 2 I n t eger Sy st em .I n t 6 4 Lon g Sy st em .Sin gle Sin gle Sy st em .Dou ble Dou ble Sy st em .Decim al Decim al Sy st em .Ch ar Ch ar Sy st em .St r in g St r in g Sy st em .Obj ect Obj ect Sy st em .Dat eTim e Dat e Sy st em .SBy t e SBy t e Sy st em .UI n t 1 6 USh or t Sy st em .UI n t 3 2 UI n t eger Sy st em .UI n t 6 4 ULon g Tabla 2 .1 . Tipos de dat os y equivalencia ent r e lenguaj es Debem os t ener en cuent a, al m enos si el r endim ient o es una de nuest r a pr ior idades, que las cadenas en .NET son inm ut ables, es decir , una vez que se han cr eado no se pueden m odificar y en caso de que quer am os cam biar el cont enido, .NET se encar ga de desechar la ant er ior y cr ear una nueva cadena, por t ant o si usam os las cadenas par a r ealizar concat enaciones ( unión de cadenas par a cr ear una nueva) , el r endim ient o ser á m uy baj o, si bien exist e una clase en .NET que es ideal par a est os casos y cuyo r endim ient o es super ior al t ipo St r ing: la clase St r ingBuilder . Las últ im as filas m ost r adas en la t abla son t ipos especiales que si bien son par t e del sist em a de t ipos com unes ( CTS) no for m an par t e de la Com m on Language Specificat ion ( CLS) , es decir la especificación com ún par a los lenguaj es "com pat ibles" con .NET, por t ant o, si quer em os cr ear aplicaciones que puedan int er oper ar con t odos los lenguaj es de .NET, esos t ipos no debem os usar los com o valor es de devolución de funciones ni com o t ipo de dat os usado en los ar gum ent os de las funciones, pr opiedades o pr ocedim ient os. Los t ipos m ost r ados en la t abla 2.1 son los t ipos pr im it ivos de .NET y por ext ensión de Visual Basic 2010, es decir son t ipos "elem ent ales" par a los cuales cada lenguaj e define su pr opia palabr a clave equivalent e con el t ipo definido en el CTS de .NET Fr am ewor k. Todos est os t ipos pr im it ivos podem os usar los t ant o por m edio de los t ipos pr opios de Visual Basic, los t ipos definidos en .NET o bien com o lit er ales. Por ej em plo, podem os definir un núm er o ent er o lit er al indicándolo con el sufij o I : 1 2 3 4 5 I o bien asignándolo a un valor de t ipo I nt eger o a un t ipo Syt em .I nt 32 de .NET. La única excepción de los t ipos m ost r ados en la t abla 1 es el t ipo de dat os Obj ect , est e es un caso especial del que nos ocupar em os en la pr óxim a lección. Sufij os o ca r a ct e r e s y sím bolos ide nt ifica dor e s pa r a los t ipos Cuando usam os valor es lit er ales num ér icos en Visual Basic 2010, el t ipo de dat os que le asigna el com pilador es el t ipo Double, por t ant o si nuest r a int ención es indicar un t ipo de dat os difer ent e podem os indicar los añadiendo una let r a com o sufij o al t ipo, est o es algo que los m ás vet er anos de VB6 ya est ar án acost um br ados, e incluso los m ás noveles t am bién, en Visual Basic 2010 algunos de ellos se siguen usando, per o el t ipo asociado es el equivalent e al de est e nuevo lenguaj e ( t al com o se m uest r a en la t abla 1) , por ej em plo par a indicar un valor ent er o podem os usar la let r a I o el signo % , de igual for m a, un valor de t ipo ent er o lar go ( Long) lo podem os indicar usando L o & , en la siguient e t abla podem os ver los car act er es o let r a que podem os usar com o sufij o en un lit er al num ér ico par a que el com pilador lo ident ifique sin ningún lugar a dudas. T ip o d e d a t o s Sh or t Sím b o lo N.A. Ca r á ct e r S I n t eger % I Lon g & L Sin gle ! F Dou ble # R Decim al @ D USh or t N.A. US UI n t eger N.A. UI ULon g N.A. UL Tabla 2 .2 . Sufij os par a ident ificar los t ipos de dat os El uso de est os car act er es nos puede r esult ar de ut ilidad par t icular m ent e par a los t ipos de dat os que no se pueden conver t ir en un valor doble. N ot a: Los sufij os pueden indicar se en m inúsculas, m ayúsculas o cualquier com binación de m ayúscula y m inúscula. Por ej em plo, el sufij o de un t ipo ULong puede ser : UL, Ul, ul, uL, LU, Lu, lU o lu. Par a evit ar confusiones, se r ecom ienda siem pr e indicar los en m ayúsculas, independient em ent e de que Visual Basic no haga ese t ipo de dist inción. Por ej em plo, si quer em os asignar est e valor lit er al a un t ipo Decim al: 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 , t al com o vem os en la figur a 1, el I DE de Visual Basic 2010 nos indicar á que exist e un er r or de desbor dam ient o ( Over flow) ya que esa cifr a es m uy gr ande par a usar lo com o valor Double, per o si le agr egam os el sufij o D o @ ya no habr á dudas de que est am os t r at ando con un valor Decim al. Figur a 2 .1 . Er r or de desbor dam ient o al int ent ar asignar un valor D ouble a una var iable D ecim al Tipos por v a lor y t ipos por r e fe r e ncia Los t ipos de dat os de .NET los podem os definir en dos gr upos: Tipos por valor Tipos por r efer encia Los t ipos por valor son t ipos de dat os cuyo valor se alm acena en la pila o en la m em or ia "cer cana", com o los num ér icos que hem os vist o. Podem os decir que el acceso al valor cont enido en uno de est os t ipos es dir ect o, es decir se alm acena dir ect am ent e en la m em or ia r eser vada par a ese t ipo y cualquier cam bio que hagam os lo har em os dir ect am ent e sobr e dicho valor , de igual for m a cuando copiam os valor es de un t ipo por valor a ot r o, est ar em os haciendo copias independient es. Por ot r o lado, los t ipos por r efer encia se alm acenan en el "m ont o" ( heap) o m em or ia "lej ana", a difer encia de los t ipos por valor , los t ipos por r efer encia lo único que alm acenan es una r efer encia ( o punt er o) al valor asignado. Si hacem os copias de t ipos por r efer encia, r ealm ent e lo que copiam os es la r efer encia pr opiam ent e dicha, per o no el cont enido. Est os dos casos los ver em os en br eve con m ás det alle. I nfe r e ncia de t ipos Una de las car act er íst icas nuevas en Visual Basic 2008 y Visual Basic 2010 es la infer encia de t ipos. Se conoce com o infer encia de t ipos a la car act er íst ica de Visual Basic par a infer ir el t ipo de un dat o al ser inicializado. Par a que la infer encia de t ipos sea efect iva, deber em os act ivar la opción Opt ion I nfer a Tr ue, aunque por defect o, ese es el valor que t iene el com pilador de Visual Basic. Sin em bar go, si se hace una m igr ación de una aplicación de Visual Basic a Visual Basic 2010, el valor de est a opción ser á False. Supongam os por lo t ant o, la siguient e declar ación: Dim datoDeclarado = 2010 En est e ej em plo, la var iable dat oDeclar ado, ser á una var iable de t ipo I nt eger ( I nt 3 2 ) . Si deseam os cam biar el t ipo de dat o a un t ipo I nt 6 4 por ej em plo, el com pilador nos devolver á un er r or . Así, el siguient e ej em plo no ser á válido en Visual Basic 2010 con la opción de infer encia act ivada: Dim datoDeclarado = 2010 datoDeclarado = Int64.MaxValue Ahor a bien, si cam biam os el valor de Opt ion I nfer a False, el m ism o ej em plo ser á cor r ect o. ¿Dónde est á la difer encia?. En est e últ im o caso, el caso de t ener desact ivada la opción de infer encia, la declar ación de la var iable dat oDeclar ado nos indica que es un t ipo de dat o Obj ect en su or igen, y que al dar le un valor I nt eger , ést a funciona com o una var iable ent er a. Al cam biar su valor a Long, est a var iable que es de t ipo Obj ect , cam bia sin pr oblem as a valor Long. En t odo est e pr oceso, hay un pr oblem a clar o de r endim ient o con acciones de boxing y unboxing que no ser ían necesar ias si t ipár am os la var iable con un t ipo concr et o. Eso es j ust am ent e lo que hace la opción Opt ion I nfer por nosot r os. Nos per m it e declar ar una var iable con el t ipo infer ido, y ese t ipo de dat os se m ant iene dent r o de la aplicación, por lo que nos da la segur idad de que ese es su t ipo de dat o, y que ese t ipo de dat o no va a var iar . Var iables y con st an t es Disponer de t odos est os t ipos de dat os no t endr ía ningún sent ido si no pudiér am os usar los de alguna ot r a for m a que de for m a lit er al. Y aquí es donde ent r an en j uego las v ar iables y const ant es, no v am os a cont ar t e qué son y par a que sir v en, salv o en el caso de las const ant es, ya que no t odos los desar r ollador es las ut ilizam os de la for m a adecuada. Conse j o pa r a usa r la s const a nt e s Siem pr e que t engam os que indicar un valor const ant e, ya sea par a indicar el m áxim o o m ínim o per m it ido en un r ango de v alor es o par a com pr obar el t ér m ino de un bucle, deber íam os usar una const ant e en lugar de un valor lit er al, de est a for m a si ese valor lo usam os en var ias par t es de nuest r o código, si en un fut ur o decidim os que dicho v alor debe ser difer ent e, nos r esult ar á m ás fácil r ealizar un solo cam bio que cam biar lo en t odos los sit ios en los que lo hem os usado, adem ás de que de est a for m a nos asegur am os de que el cam bio se r ealiza adecuadam ent e y no t endr em os que pr eocupar nos de las consecuencias der ivadas de no haber hecho el cam bio en t odos los sit ios que deber íam os. Las const ant es se definen ut ilizando la inst r ucción Const seguida del nom br e, opcionalm ent e podem os indicar el t ipo de dat os y por últ im o una asignación con el v alor que t endr á. Com o v er em os en la siguient e sección, podem os obligar a Visual Basic 2010 a que en t odas las const ant es ( y v ar iables) que declar em os, t engam os que indicar el t ipo de dat os. Par a declar ar una const ant e lo har em os de la siguient e for m a: Const maximo As Integer = 12345678 D e cla r a r v a r ia b le s La declar ación de las v ar iables en Visual Basic 2010 se hace por m edio de la inst r ucción Dim seguida del nom br e de la const ant e y del t ipo de dat os que est a cont endr á. Con una m ism a inst r ucción Dim podem os declar ar m ás de una v ar iable, incluso de t ipos difer ent es, t al y com o v er em os a cont inuación. La siguient e línea de código declar a una v ar iable de t ipo ent er o: Dim i As Integer Tal y com o hem os com ent ado, t am bién podem os declar ar en una m ism a línea m ás de una v ar iable: Dim a, b, c As Integer En est e caso, las t r es v ar iables las est am os definiendo del m ism o t ipo, que es el indicado al final de la declar ación. N ot a: Com o hem os com ent ado, en Visual Basic 2010 se pueden declar ar las const ant es y var iables sin necesidad de indicar el t ipo de dat os que cont endr án, per o debido a que eso no es una buena pr áct ica, a lo lar go de est e cur so siem pr e declar ar em os las v ar iables y const ant es con el t ipo de dat os adecuado a su uso. D e cla r a r v a r ia b le s y a sig n a r e l v a lor in icia l En Visual Basic 2010 t am bién podem os inicializar una var iable con un v alor dist int o al pr edet er m inado, que en los t ipos num ér icos es un cer o, en las fechas es el 1 de ener o del año 1 a las doce de la m adr ugada ( # 0 1 / 0 1 / 0 0 0 1 1 2 :0 0 :0 0 AM # ) y en la cadenas es un v alor nulo ( Not hing) , par a hacer lo, sim plem ent e t enem os que indicar ese valor , t al com o v er em os es m uy par ecido a com o se declar an las const ant es. Por ej em plo: Dim a As Integer = 10 En esa m ism a línea podem os declar ar y asignar m ás v ar iables, per o t odas deben est ar indicadas con el t ipo de dat os: Dim a As Integer = 10, b As Integer = 25 Por supuest o, el t ipo de dat os puede ser cualquier a de los t ipos pr im it iv os: Dim a As Integer = 10, b As Integer = 25, s As String = "Hola" Aunque par a que el código sea m ás legible, y fácil de depur ar , no deber íam os m ezclar en una m ism a inst r ucción Dim m ás de un t ipo de dat os. N ot a: Es im por t ant e saber que en las cadenas de Visual Basic 2010 el v alor de una var iable de t ipo St r ing no inicializada NO es una cadena vacía, sino un v alor nulo ( Not hing) . El t ipo de da t os Ch a r En Visual Basic 2010 podem os declar ar v alor es de t ipo Char , est e t ipo de dat os es un car áct er Unicode y podem os declar ar lo y asignar lo a un m ism o t iem po. El pr oblem a con el que nos podem os encon t r ar es a la h or a de in dicar u n car áct er lit er al. Podem os conv er t ir un v alor num ér ico en un car áct er o bien podem os conver t ir un car áct er en su cor r espondient e v alor num ér ico. Dim c = Dim n = c As Char Chr(65) n As Byte Asc(c) En Visual Basic 2010 los t ipos Char se pueden asignar a var iables de t ipo St r ing y se har á una conv er sión aut om át ica sin necesidad de ut ilizar funciones de conver sión. Si nuest r a int ención es asignar un v alor Char a una v ar iable, adem ás de la función Chr , podem os hacer lo con un lit er al, ese v alor lit er al est ar á encer r ado ent r e com illas dobles, ( al igual que una cadena) , aunque par a que r ealm ent e sea un car áct er debem os agr egar le una c j ust o después del cier r e de las com illas dobles: Dim c As Char = "A"c Obliga r a de cla r a r la s v a r ia ble s con e l t ipo de da t os Visual Basic 2010 nos per m it e, ( lam ent ablem ent e de for m a pr edet er m inada) , ut ilizar las var iables y const ant es sin necesidad de indicar el t ipo de dat os de est as, per o, com o com ent ábam os al pr incipio, podem os obligar a que nos avise cuando no lo est am os haciendo, ya que com o decíam os en la not a, es una buena cost um br e indicar siem pr e el t ipo de dat os que t endr án nuest r as v ar iables y const ant es. Esa obligat or iedad la podem os aplicar a t odo el pr oy ect o o a un m ódulo en par t icular , par a ello t enem os que usar la inst r ucción Opt ion St r ict On, una v ez indicado, se aplicar á a t odo el código, no solo a las declar aciones de v ar iables, const ant es o al t ipo de dat os dev uelt o por las funciones y pr opiedades, sino t am bién a las conv er siones y asignaciones ent r e difer ent es t ipos de dat os. No debem os confundir Opt ion St r ict con Opt ion Ex plicit , est e últ im o, sir v e par a que siem pr e t engam os que declar ar t odas las v ar iables, m ient r as que el pr im er o lo que hace es obligar nos a que esas declar aciones t engan un t ipo de dat os. Tant o una com o la ot r a t ienen dos est ados: conect ado o desconect ado dependiendo de que agr eguem os On u Off r espect iv am ent e. I nsist im os en la r ecom endación de que siem pr e debem os "conect ar " est as dos opciones, si bien Opt ion Explicit On y a v iene com o v alor por defect o, cosa que no ocur r e con Opt ion St r ict , que por defect o est á desconect ado. Aplica r Opt ion St r ict On a un fiche r o e n pa r t icula r Cuando agr egábam os un nuev o ficher o a nuest r o pr oyect o de Visual Basic 2010 si y a t enem os pr edefinida las opciones "est r ict as", com o es el caso de Opt ion Ex plicit On, est as no se añadir án a dicho ficher o, ( en un m om ent o v er em os cóm o hacer lo par a que siem pr e est én pr edefinidas) , per o eso no significa que no se aplique, aunque siem pr e podem os escr ibir esas inst r ucciones ( con el v alor On al final) en cada uno de los ficher os de código que agr eguem os a nuest r o pr oy ect o. Si nos decidim os a añadir las a los ficher os, esas líneas de código deben apar ecer al pr incipio del ficher o y solam ent e pueden est ar pr ecedidas de com ent ar ios. En la figur a 2.1 m ost r ada en la lección ant er ior , t enem os una capt ur a del edit or de Visual Basic 2010 en la que hem os indicado que quer em os t ener com pr obación est r ict a. Aplica r Opt ion St ict On a t odo e l pr oy e ct o Tam bién podem os hacer que Opt ion St r ict funcione igual que Opt ion Ex plicit , es decir , que est é act iv ado a t odo el pr oyect o, en est e caso no t endr íam os que indicar lo en cada uno de los ficher os de código que for m en par t e de nuest r o pr oy ect o, si bien solam ent e ser á aplicable a los que no t engan esas inst r ucciones, aclar em os est o últ im o: si Opt ion St r ict ( u Opt ion Ex plicit ) est á definido de for m a global al pr oy ect o, podem os desact iv ar lo en cualquier a de los ficher os, par a ello sim plem ent e habr ía que usar esas declar aciones per o usando Off en lugar de On. De igual for m a, si y a est á definido globalm ent e y lo indicam os ex pr esam ent e, no se pr oducir á ningún er r or . Lo im por t ant e aquí es saber que siem pr e se usar á el est ado indicado en cada ficher o, independient em ent e de cóm o lo t engam os definido a niv el de pr oy ect o. Par a que siem pr e se usen est as asignaciones en t odo el pr oy ect o, vam os a ver cóm o indicar lo en el ent or no de Visual Basic 2010. Abr im os Visual St udio 2010 y una vez que se hay a car gado, ( no hace falt a cr ear ningún nuev o pr oyect o, de est e det alle nos ocupar em os en br ev e) , seleccionam os la opción H er r am ient as> Opcione s... se m ost r ar á un cuadr o de diálogo y del panel izquier do seleccionam os la opción Pr oyect os y soluciones, la ex pandim os y seleccionam os Valor es pr edet er m inados de VB y v er em os cier t as opciones, t al com o podem os com pr obar en la figur a 2.2: Figur a 2 .2 . Opciones de pr oyect os ( opciones m ínim as) De la list a despegable Opt ion St r ict , seleccionam os On. Por defect o y a est ar án seleccionadas las opciones On de Opt ion Explicit y Binar y de Opt ion Com par e, por t ant o no es necesar io r ealizar ningún cam bio m ás, par a acept ar los cam bios y cer r ar el cuadr o de diálogo, pr esionam os en el bot ón Acept ar . Si en la vent ana de opciones no apar ece t oda la configur ación podem os hacer que se m uest r en t odas las disponibles. Par a hacer lo, debem os m ar car la casilla que est á en la par t e infer ior izquier da en la que podem os leer : M ost r ar t odas las configur aciones, al seleccionar esa opción nos m ost r ar á un núm er o m ay or de opciones, t al com o podem os v er en la figur a 2.3 : Figur a 2 .3 . Opciones de pr oyect os ( t odas las opciones) Desde est e m om ent o el com pilador de Visual Basic se volv er á est r ict o en t odo lo r elacionado a las declar aciones de v ar iables y conv er siones, t al com o v em os en la figur a 2.4 al int ent ar declar ar una v ar iable sin indicar el t ipo de dat os. Figur a 2 .4 . Aviso de Opt ion St r ict al declar ar una var iable sin t ipo N ot a: Una de las v ent aj as del I DE ( I nt egr at ed Dev elopm ent Env ir onm ent , ent or no de desar r ollo int egr ado) de Visual Basic 2010 es que nos avisa al m om ent o de cualquier fallo que com et am os al escr ibir el código, est e "pequeño" det alle, aunque alguna veces puede llegar a par ecer fast idioso, nos facilit a la escr it ur a de código, ya que no t enem os que esper ar a r ealizar la com pilación par a que t engam os const ancia de esos fallos. M á s opcione s a plica ble s a los pr oy e ct os Aunque en est os m ódulos no t r at ar em os a fondo el ent or no de desar r ollo, ya que la finalidad de est e cur so online es t r at ar m ás en el código pr opiam ent e dicho, v am os a m ost r ar ot r o de los sit ios en los que podem os indicar dónde indicar que se haga una com pr obación est r ict a de t ipos y , com o v er em os, t am bién podr em os indicar algunas "nuevas peculiar idades" de Visual Basic 2010, t odas ellas r elacionadas con el t em a que est am os t r at ando. Cuando t engam os un pr oy ect o car gado en el I DE de Visual St udio 2010, ( pr ont o v er em os cóm o cr ear uno) , podem os m ost r ar las pr opiedades del pr oy ect o, par a ello seleccionar em os del m enú Pr oyect o la opción Pr opiedades de < N om br eD elPr oyect o> y t endr em os un cuadr o de diálogo com o el m ost r ado en la figur a 2.5. Figur a 2 .5 . Ficha Com pilar de las opciones del pr oyect o act ual Seleccionando la ficha Com pilar , adem ás de las t ípicas opciones de Opt ion St r ict , Opt ion Explicit ,Opt ion Com par e y Opt ion I nfer , ( est as asignaciones solo ser án efect iv as par a el pr oyect o act ual) , t endr em os cóm o quer em os que r eaccione el com pilador si se cum ple algunas de las condiciones indicadas. Ent r e esas condiciones, t enem os algo que m uchos desar r ollador es de Visual Basic siem pr e hem os quer ido t ener : Que nos av ise cuando una var iable la hem os declar ado per o no la ut ilizam os ( Var iable local no ut iliz ada) . Al t ener m ar cada est a opción ( nor m alm ent e com o una Adver t encia) , si hem os declar ado una v ar iable y no la usam os en el código, ( siem pr e que no le hay am os asignado un v alor al declar ar la) , nos av isar á, t al com o podem os ver en la figur a 2.6: Figur a 2 .6 . Aviso de var iable no usada Tip os N ulla ble s Ot r a int er esant ísim a car act er íst ica int r oducida en Visual Basic 2008 y ut ilizable en Visual Basic 2010 que conv iene conocer , es lo que se denom inan t ipos Nullables o anulables. Los t ipos anulables no son nuev os en Visual Basic, de hecho su or igen lo encont r am os en Visual St udio 2005, aunque eso sí, im plem ent ando la clase Nullable( Of T) . Con Visual Basic 2008 y Visual Basic 2010 no es necesar io declar ar ninguna clase par a im plem ent ar t ipos anulables dent r o de nuest r as aplicaciones, y podem os declar ar los de for m a dir ect a. Un t ipo de dat o anulable nos per m it ir á declar ar una v ar iable que podr á t ener un t ipo de dat o nulo. Si hem os est ado at ent os hast a ahor a, hem os podido v er que las var iables num ér icas por ej em plo, se inicializan a 0. Si quisiér am os por la r azón que fuer a, declar ar esa v ar iable com o nula par a saber si en un det er m inado m om ent o ha cam biado de v alor o cualquier ot r a acción, deber íam os ut ilizar los t ipos de dat os anulables, o bien, ut ilizar t écnicas m ás r udim ent ar ias com o una var iable de t ipo Boolean que nos per m it ier a saber si ha habido un cam bio de v alor en una v ar iable, sin em bar go, coincidir á conm igo en que el uso de un t ipo de dat os anulable es m ás nat ur al y dir ect o. De est a for m a, podr íam os t r abaj ar con t ipos de dat os anulables o que los declar ar em os com o nulos. A cont inuación v er em os un ej em plo: Dim valor As Integer? Par a acceder al valor de un t ipo anulable, podr íam os hacer lo de la for m a habit ual, ahor a bien, si no sabem os si el v alor es nulo o no, podr íam os acceder a su v alor pr egunt ando por él m ediant e la pr opiedad HasValue. La pr opiedad Value nos indicar á t am bién, el v alor de esa var iable. Un ej em plo que aclar e est a ex plicación es el que podem os ver a cont inuación: Dim valor As Integer? If Valor.HasValue Then MessageBox.Show(valor.Value) End If Ot r a car act er íst ica de los t ipos anulables es la posibilidad de ut ilizar la función Get ValueOr Default . Est a función nos per m it ir á acceder al v alor de la v ar iable si no es nulo, y al v alor que le indiquem os si es nulo. Un br eve ej em plo de est e uso es el que se indica a cont inuación: Dim valor As Integer? valor = 2010 MessageBox.Show(valor.GetValueOrDefault(2012)) End If En est e ej em plo, el com pilador nos devolv er ía el v alor 2010, y a que Get ValueOr Default sabe que la v ar iable no posee un v alor nulo y que por lo t ant o, debe obt ener el v alor no nulo de la v ar iable anulable. En el caso de que no hubiér am os dado ningún v alor a la var iable, la aplicación obt endr ía el v alor 2012. Tipos a nónim os Est a car act er íst ica de Visual Basic 2008 y Visual Basic 2010, nos per m it e declar ar los t ipos de dat os de for m a im plícit a desde el código de nuest r as aplicaciones. Un ej em plo pr áct ico de declar ación de t ipos anónim os es el siguient e: Dim declaracion = New With {.Nombre = "Carlos", .Edad = 27} MessageBox.Show(String.Format("{0} tiene {1} años", _ declaracion.Nombre, declaracion.Edad)) Com o podem os ver , en el ej em plo ant er ior hem os declar ado un obj et o al que no hem os indicado ningún t ipo de dat o concr et o, per o a la hor a de cr ear ese obj et o, hem os cr eado im plícit am ent e un m iem br o Nom br e y un m iem br o Edad. Pr opie d a d e s a ut oim p le m e nt a da s Est a car act er íst ica de Visual Basic 2010 nos per m it e declar ar pr opiedades y aut oim plem ent ar las con un valor det er m inado. De est a m aner a, podr em os inicializar una pr opiedad con un v alor det er m inado. Un sencillo ej em plo de uso de est a car act er íst ica es el siguient e: Property Id As Integer = 0 Property NamePerson As String = "<sin nombre>" Property AgePerson As Byte = 0 En est e ej em plo, se han cr eado t r es pr opiedades, una de ellas de t ipo I nt 32, ot r a de t ipo St r ing, y una t er cer a de t ipo Byt e. Est as pr opiedades est án inicializadas con valor es por defect o. I nicia liza ción de cole ccione s Ot r a car act er íst ica m uy út il en Visual Basic es la inicialización de colecciones, que nos per m it e inicializar una colección de dat os con v alor es de for m a dir ect a. La m ej or for m a de ent ender est o es viendo un ej em plo. Supongam os la siguient e int er faz en Visual Basic: Interface IPerson Property Id As Integer Property Name As String Property Age As Byte End Interface Ahor a, cr ear em os una clase que im plem ent e la int er faz I Per son: Public Class Estudiante Implements IPerson <DefaultValue("0")> Property Id As Integer Implements IPerson.Id Property Name As String Implements IPerson.Name Property Age As Byte Implements IPerson.Age End Class Ya t enem os la int er faz y la clase que im plem ent a la int er faz, por lo que ahor a, lo t enem os que hacer es consum ir la clase Est udiant e e inicializar los elem ent os de la colección. Un ej em plo pr áct ico de inicialización es el que se indica a cont inuación: Property StudentCollection As New List(Of Estudiante) ... Me.StudentCollection.Add(New Estudiante With {.Id = 1, .Name = "Luisa", .Age = 25}) Me.StudentCollection.Add(New Estudiante With {.Id = 2, .Name = "Antonio", .Age = 27}) Me.StudentCollection.Add(New Estudiante With {.Id = 3, .Name = "Juan", .Age = 26}) Com o podem os apr eciar , al m ism o t iem po que declar am os un nuev o obj et o de t ipo Est udiant e, inicializam os sus pr opiedades con valor es, de for m a que asignam os esos elem ent os a la colección con v alor es dir ect os. Una enum er ación es una ser ie de const ant es que est án r elacionadas ent r e sí. La ut ilidad de las enum er aciones es m ás m anifiest a cuando quer em os m anej ar una ser ie de valor es const ant es con nom br e, es decir , podem os indicar un valor , per o en lugar de usar un lit er al num ér ico, usam os un nom br e, ese nom br e es al fin y al cabo, una const ant e que t iene un valor num ér ico. En Visual Basic 2010 las enum er aciones pueden ser de cualquier t ipo num ér ico int egr al, incluso ent er os sin signo, aunque el valor pr edefinido es el t ipo I nt eger . Podem os declar ar una enum er ación de var ias for m as: 1- Sin indicar el t ipo de dat os, por t ant o ser án de t ipo I nt eger : Enum Colores Rojo Verde Azul End Enum 2- Concr et ando explícit am ent e el t ipo de dat os que r ealm ent e t endr á: Enum Colores As Long Rojo Verde Azul End Enum En est e segundo caso, el valor m áxim o que podem os asignar a los m iem br os de una enum er ación ser á el que pueda cont ener un t ipo de dat os Long. 3- I ndicando el at r ibut o FlagsAt t ibut e, ( r ealm ent e no hace falt a indicar el sufij o At t r ibut e cuando usam os los at r ibut os) de est a for m a podr em os usar los valor es de la enum er ación par a indicar valor es que se pueden "sum ar " o com plem ent ar ent r e sí, per o sin per der el nom br e, en br eve ver em os qué significa est o de "no per der el nom br e". <Flags()> _ Enum Colores As Byte Rojo = 1 Verde = 2 Azul = 4 End Enum N ot a: Los at r ibut os los ver em os con m ás det alle en ot r a lección de est e m ism o m ódulo. El nom br e de los m ie m br os de la s e num e r a cione s Tant o si indicam os o no el at r ibut o Flags a una enum er ación, la podem os usar de est a for m a: Dim c As Colores = Colores.Azul Or Colores.Rojo Es decir , podem os "sum ar " los valor es definidos en la enum er ación. Ant es de explicar con det alle que beneficios nos puede t r aer el uso de est e at r ibut o, veam os una car act er íst ica de las enum er aciones. Com o hem os com ent ado, las enum er aciones son const ant es con nom br es, per o en Visual Basic 2010 est a definición llega m ás lej os, de hecho, podem os saber "el nom br e" de un valor de una enum er ación, par a ello t endr em os que usar el m ét odo ToSt r ing, el cual se usa par a conver t ir en una cadena cualquier valor num ér ico. Por ej em plo, si t enem os la siguient e asignación: Dim s As String = Colores.Azul.ToString La var iable s cont endr á la palabr a " Azul" no el valor 4. Est o es aplicable a cualquier t ipo de enum er ación, se haya o no usado el at r ibut o FlagsAt t r ibut e. Una vez aclar ado est e com por t am ient o de las enum er aciones en Visual Basic 2010, veam os que es lo que ocur r e cuando sum am os valor es de enum er aciones a las que hem os aplicado el at r ibut o Flags y a las que no se lo hem os aplicado. Em pecem os por est e últ im o caso. Si t enem os est e código: Enum Colores As Byte Rojo = 1 Verde = 2 Azul = 4 End Enum Dim c As Colores = Colores.Azul Or Colores.Rojo Dim s As String = c.ToString El cont enido de la var iable s ser á " 5 " , es decir , la r epr esent ación num ér ica del valor cont enido: 4 + 1 , ya que el valor de la const ant e Azul es 4 y el de la const ant e Roj o es 1 . Per o si ese m ism o código lo usam os de est a for m a ( aplicando el at r ibut o Flags a la enum er ación) : <Flags()> _ Enum Colores As Byte Rojo = 1 Verde = 2 Azul = 4 End Enum Dim c As Colores = Colores.Azul Or Colores.Rojo Dim s As String = c.ToString El cont enido de la var iable s ser á: " Roj o, Azul" , es decir , se asignan los nom br es de los m iem br os de la enum er ación que int er vienen en ese valor , no el valor "int er no". Los v a lor e s de una e num e r a ción no son sim ple s núm e r os Com o hem os com ent ado, los m iem br os de las enum er aciones r ealm ent e son valor es de un t ipo de dat os ent er o ( en cualquier a de sus var iedades) t al com o podem os com pr obar en la figur a 2.7: Figur a 2 .7 . Los t ipos subyacent es posibles de una enum er ación Por t ant o, podem os pensar que podem os usar cualquier valor par a asignar a una var iable declar ada com o una enum er ación, al m enos si ese valor est á dent r o del r ango adecuado. En Visual Basic 2010 est o no es posible, al m enos si lo hacem os de for m a "dir ect a" y con Opt ion St r ict conect ado, ya que r ecibir em os un er r or indicándonos que no podem os conver t ir , por ej em plo, un valor ent er o en un valor del t ipo de la enum er ación. En la figur a 2.8 podem os ver ese er r or al int ent ar asignar el valor 3 a una var iable del t ipo Color es ( definida con el t ipo pr edet er m inado I nt eger ) . Figur a 2 .8 . Er r or al asignar un valor " nor m al" a una var iable del t ipo Color es El er r or nos indica que no podem os r ealizar esa asignación, per o el ent or no int egr ado de Visual St udio 2010 t am bién nos ofr ece alt er nat ivas par a que ese er r or no se pr oduzca, esa ayuda se obt iene pr esionando en el signo de adm ir ación que t enem os j ust o donde est á el cur sor del m ouse, per o no solo nos dice cóm o cor r egir lo, sino que t am bién nos da la posibilidad de que el pr opio I DE se encar gue de cor r egir lo, t al com o podem os apr eciar en la figur a 2.9. Figur a 2 .9 . Opciones de cor r ección de er r or es Lo único que t endr íam os que hacer es pr esionar en la suger encia de cor r ección, que en est e caso es la única que hay, per o en ot r os casos pueden ser var ias las opciones y t endr íam os que elegir la que cr eam os adecuada. El código final ( una vez cor r egido) quedar ía de la siguient e for m a: Dim c As Colores = CType(3, Colores) CType es una de las for m as que nos ofr ece Visual Basic 2010 de hacer conver siones ent r e difer ent es t ipos de dat os, en est e caso conver t im os un valor ent er o en uno del t ipo Color es. Si com pilam os y ej ecut am os la aplicación, ést a funcionar á cor r ect am ent e. Aunque sabem os que es posible que usando CType no asignem os un valor dent r o del r ango per m it ido. En est e caso, el valor 3 podr íam os dar lo por bueno, ya que es la sum a de 1 y 2 ( Roj o y Ver de) , per o ¿que pasar ía si el valor asignado es, por ej em plo, 15? En t eor ía no deber íam os per m it ir lo. Est as validaciones podem os hacer las de dos for m as: 1- Con la clásica solución de com pr obar el valor indicado con t odos los valor es posibles. 2- Usando funciones específicas del t ipo Enum . Aunque en est e últ im o caso, solo podr em os com pr obar los valor es definidos en la enum er ación. En el siguient e ej em plo podem os hacer esa com pr obación. Sub mostrarColor(ByVal c As Colores) ' comprobar si el valor indicado es correcto ' si no está¡ definido, usar el valor Azul If [Enum].IsDefined(GetType(Colores), c) = False Then c = Colores.Azul End If Console.WriteLine("El color es {0}", c) End Sub Est e código lo que hace es com pr obar si el t ipo de dat os Color es t iene definido el valor cont enido en la var iable c, en caso de que no sea así, usam os un valor pr edet er m inado. N ot a: La función I sDefined sólo com pr ueba los valor es que se han definido en la enum er ación, no las posibles com binaciones que podem os conseguir sum ando cada uno de sus m iem br os, incluso aunque hayam os usado el at r ibut o FlagsAt t r ibut e. Los ar r ays ( o m at r ices) nos per m it ir án agr u par valor es que de alguna for m a quer em os que est én r elacionados ent r e si. N ot a: Est a es la definición usada en la docum ent ación de Visual St udio sobr e qué es una m at r iz: "Una m at r iz es una est r uct ur a de dat os que cont iene una ser ie de var iables denom inadas elem ent os de la m at r iz." Aclar am os est e punt o, por que la t r aducción en cast ellano de Ar r ay puede var iar dependiendo del país ( ar r eglos, m at r ices, et c) . Aquí ut ilizar em os la usada a lo lar go de la docum ent ación de Visual St udio. D e cla r a r a r r a y s En C# los ar r ays se definen indicando un par de cor chet es en el t ipo de dat os. En Visual Basic 2010 la declar ación de un ar r ay la har em os usando un par de par ént esis en el nom br e de la var iable o del t ipo, en el siguient e ej em plo declar am os un ar r ay de t ipo St r ing llam ado nom br es: Dim nombres() As String Dim nombres As String() Est as dos for m as son equivalent es. Tam bién podem os indicar el núm er o de elem ent os que cont endr á el ar r ay o m at r iz: Dim nombres(10) As String Per o solo podem os hacer lo en el nom br e, si esa cant idad de elem ent os lo indicam os en el t ipo, r ecibir em os un er r or indicándonos que "los lím it es de la m at r iz no pueden apar ecer en los especificador es del t ipo". Al declar ar un ar r ay indicando el núm er o de elem ent os, com o es el caso ant er ior , lo que est am os definiendo es un ar r ay de 11 elem ent os: desde cer o hast a 10, ya que en Visual Basic 2010, al igual que en el r est o de lenguaj es de .NET, t odos los ar r ays deben t ener com o índice infer ior el valor cer o. Par a que quede clar o que el lím it e infer ior debe ser cer o, en Visual Basic 2010 podem os usar la inst r ucción 0 To par a indicar el valor m áxim o del índice super ior , ya que, t al com o podem os com pr obar si vem os 0 To 10, quedar á clar o que nuest r a int ención es declar ar un ar r ay con 11 elem ent os, o al m enos nuest r o código r esult ar á m ás legible: Dim nombres(0 To 10) As String D e cla r a r e inicia liza r un a r r a y En Visual Basic 2010 t am bién podem os inicializar un ar r ay al declar ar lo, par a ello debem os poner los valor es a asignar dent r o de un par de llaves, t al com o vem os en el siguient e ej em plo: Dim nombres() As String = {"Pepe", "Juan", "Luisa"} Con el código ant er ior est am os cr eando un ar r ay de t ipo St r ing con t r es valor es cuyos índices van de cer o a dos. En est e caso, cuando iniciam os el ar r ay al declar ar lo, no debem os indicar el núm er o de elem ent os que t endr á ese ar r ay, ya que ese valor lo aver iguar á el com pilador cuando haga la asignación. Tam poco es válido indicar el núm er o de elem ent os que quer em os que t enga y solo asignar le unos cuant os m enos ( o m ás) , ya que se pr oducir á un er r or en t iem po de com pilación. Si el ar r ay es bidim ensional ( o con m ás dim ensiones) , t am bién podem os inicializar los al declar ar lo, per o en est e caso debem os usar doble j uego de llaves: Dim nombres(,) As String = {{"Juan", "Pepe"}, {"Ana", "Eva"}} En est e código t endr íam os un ar r ay bidim ensional con los siguient es valor es: nom br es( 0,0) = nom br es( 0,1) = nom br es( 1,0) = nom br es( 1,1) = Juan Pepe Ana Eva Com o podem os ver en la declar ación ant er ior , si definim os ar r ays con m ás de una dim ensión, debem os indicar las usando una com a par a separ ar cada dim ensión, o lo que es m ás fácil de r ecor dar : usando una com a m enos del núm er o de dim ensiones que t endr á el ar r ay. En los valor es a asignar , usar em os las llaves encer r adas en ot r as llaves, según el núm er o de dim ensiones. Aunque, la ver dad, es que hay algunas veces hay que hacer un gr an esfuer zo m ent al par a asociar los elem ent os con los índices que t endr án en el ar r ay, por t ant o, algunas veces puede que r esult e m ás legible si indent am os o agr upam os esas asignaciones, t al com o vem os en el siguient e código: Dim nomTri(,,) As String = _ { _ {{"Juan", "Pepe"}, {"Luisa", "Eva"}}, _ {{"A", "B"}, {"C", "D"}} _ } Console.WriteLine(nomTri(0, Console.WriteLine(nomTri(0, Console.WriteLine(nomTri(0, Console.WriteLine(nomTri(0, 0, 0, 1, 1, 0)) 1)) 0)) 1)) ' ' ' ' Juan Pepe Luisa Eva Console.WriteLine(nomTri(1, Console.WriteLine(nomTri(1, Console.WriteLine(nomTri(1, Console.WriteLine(nomTri(1, 0, 0, 1, 1, 0)) 1)) 0)) 1)) ' ' ' ' A B C D Tal com o podem os com pr obar , asi es m ás legible. Por suer t e t enem os el car áct er del guión baj o par a cont inuar líneas de código, aunque est o ya no es necesar io com o hem os podido ver al pr incipio de est e t ut or ial. Ca m bia r e l t a m a ño de un a r r a y Par a cam biar el t am año de un ar r ay, usar em os la inst r ucción ReDim , est a inst r ucción solo la podem os usar par a cam biar el t am año de un ar r ay pr eviam ent e declar ado, no par a declar ar un ar r ay, ya que siem pr e hay que declar ar pr eviam ent e los ar r ays ant es de cam biar les el t am año. Dim nombres() As String ... ReDim nombres(3) nombres(0) = "Juan" nombres(1) = "Pepe" La m ayor ut ilidad de est a inst r ucción, es que podem os cam biar el t am año de un ar r ay y m ant ener los valor es que t uvier a ant er ior m ent e, par a logr ar lo debem os usar ReDim Pr eser ve. ReDim Preserve nombres(3) nombres(2) = "Ana" nombres(3) = "Eva" En est e ej em plo, los valor es que ya t uvier a el ar r ay nom br es, se seguir ían m ant eniendo, y se asignar ían los nuevos. Si bien t ant o ReDim com o ReDim Pr eser ve se pueden usar en ar r ays de cualquier núm er o de dim ensiones, en los ar r ays de m ás de una dim ensión solam ent e podem os cam biar el t am año de la últ im a dim ensión. Elim ina r e l cont e nido de un a r r a y Una vez que hem os declar ado un ar r ay y le hem os asignado valor es, es posible que nos int er ese elim inar esos valor es de la m em or ia, par a logr ar lo, podem os hacer lo de t r es for m as: 1. Redim ensionando el ar r ay indicando que t iene cer o elem ent os, aunque en el m ej or de los casos, si no est am os t r abaj ando con ar r ays de m ás de una dim ensión, t endr íam os un ar r ay de un elem ent o, ya que, com o hem os com ent ado ant er ior m ent e, los ar r ays de .NET el índice infer ior es cer o. 2. Usar la inst r ucción Er ase. La inst r ucción Er ase elim ina t ot alm ent e el ar r ay de la m em or ia. 3. Asignar un valor Not hing al ar r ay. Est o funciona en Visual Basic 2010 por que los ar r ays r ealm ent e son t ipos por r efer encia. Los a r r a y s son t ipos por r e fe r e ncia Com o acabam os de ver , en Visual Basic 2010 los ar r ays son t ipos por r efer encia, y t al com o com ent am os ant er ior m ent e, los t ipos por r efer encia r ealm ent e lo que cont ienen son una r efer encia a los dat os r eales no los dat os pr opiam ent e dichos. ¿Cual es el pr oblem a? Veám oslo con un ej em plo y así lo t endr em os m ás clar o. Dim nombres() As String = {"Juan", "Pepe", "Ana", "Eva"} Dim otros() As String otros = nombres nombres(0) = "Antonio" En est e ej em plo definim os el ar r ay nom br es y le asignam os cuat r o valor es. A cont inuación definim os ot r o ar r ay llam ado ot r os y le asignam os lo que t iene nom br es. Por últ im o asignam os un nuevo valor al elem ent o cer o del ar r ay nom br es. Si m ost r am os el cont enido de am bos ar r ays nos dar em os cuent a de que r ealm ent e solo exist e una copia de los dat os en la m em or ia, y t ant o nom br es( 0 ) com o ot r os( 0 ) cont ienen el nom br e " Ant onio" . ¿Qué ha ocur r ido? Que debido a que los ar r ays son t ipos por r efer encia, solam ent e exist e una copia de los dat os y t ant o la var iable nom br es com o la var iable ot r os lo que cont ienen es una r efer encia ( o punt er o) a los dat os. Si r ealm ent e quer em os t ener copias independient es, debem os hacer una copia del ar r ay nom br es en el ar r ay ot r os, est o es fácil de hacer si usam os el m ét odo CopyTo. Ést e m ét odo exist e en t odos los ar r ays y nos per m it e copiar un ar r ay en ot r o em pezando por el índice que indiquem os. El único r equisit o es que el ar r ay de dest ino debe est ar inicializado y t ener espacio suficient e par a cont ener los elem ent os que quer em os copiar . En el siguient e código de ej em plo hacem os una copia del cont enido del ar r ay nom br es en el ar r ay ot r os, de est a for m a, el cam bio r ealizado en el elem ent o cer o de nom br es no afect a al del ar r ay ot r os. Dim nombres() As String = {"Juan", "Pepe", "Ana", "Eva"} Dim otros() As String ReDim otros(nombres.Length) nombres.CopyTo(otros, 0) nombres(0) = "Antonio" Adem ás del m ét odo CopyTo, los ar r ays t ienen ot r os m iem br os que nos pueden ser de ut ilidad, com o por ej em plo la pr opiedad Lengt h usada en el ej em plo par a saber cuant os elem ent os t iene el ar r ay nom br es. Par a aver iguar el núm er o de elem ent os de un ar r ay, ( r ealm ent e el índice super ior ) , podem os usar la función UBound. Tam bién podem os usar la función LBound, ( que sir ve par a aver iguar el índice infer ior de un ar r ay) , aunque no t iene ningún sent ido en Visual Basic 2010, ya que, com o hem os com ent ado, t odos los ar r ays siem pr e t ienen un valor cer o com o índice infer ior . Par a finalizar est e t em a, solo nos queda por decir , que los ar r ays de Visual Basic 2010 r ealm ent e son t ipos de dat os der ivados de la clase Ar r ay y por t ant o disponen de t odos los m iem br os definidos en esa clase, aunque de est o hablar em os en la pr óxim a lección, en la que t am bién t endr em os la opor t unidad de pr ofundizar un poco m ás en los t ipos por r efer encia y en com o podem os definir nuest r os pr opios t ipos de dat os, t ant o por r efer encia com o por valor . Lit e r a le s de a r r a y s ( o m a t r ice s) Ot r a car act er íst ica de Visual Basic 2010 es la aplicación de los denom inados lit er ales de ar r ays o m at r ices. La idea es que Visual Basic infier a por nosot r os el t ipo de dat o de for m a dir ect a. Est o r epr esent a una buena pr áct ica aunque nos im pide hacer cosas que ant es podíam os hacer sin com plicaciones. Por ej em plo, pensem os en el siguient e ej em plo de Visual Basic 2008: Dim ejemploMatriz() = {2009, 2010, 2011, 2012} En est e ej em plo, habr em os cr eado una m at r iz de 4 elem ent os. Sin em bar go, podr íam os cam biar uno de sus elem ent os a ot r o valor de difer ent e t ipo, com o por ej em plo: ejemploMatriz(1) = "s" De est a m aner a, t endr em os un r esult ado: 2009, "s", 2011, 2012. Est o es así, por que la m at r iz ej em ploMat r iz es de t ipo Obj ect . Sin em bar go, est o ha cam biado. Ahor a, podem os declar ar lit er ales de m at r ices, haciendo que est as m at r ices se declar en de acuer do al t ipo de dat o declar ado, es decir , infir iendo el t ipo de dat o en la declar ación. Un ej em plo de est e uso es el siguient e: Dim ejemploInteger = {2009, 2010, 2011, 2012} En est e ej em plo, si t r at am os de hacer lo que ant es int ent ábam os m ediant e la siguient e int r ucción: ejemploInteger(1) = "s" La aplicación nos devolver á un er r or en t iem po de ej ecución, ya que la m at r iz est ar á infer ida por defect o com o t ipo I nt eger , y est ar em os int ent ado asignar u n valor St r ing a una m at r iz de t ipo I nt eger . En la lección ant er ior vim os los t ipos de dat os pr edefinidos en .NET Fr am ewor k, en est a lección ver em os cóm o podem os cr ear nuest r os pr opios t ipos de dat os, t ant o por valor com o por r efer encia. Tam bién t endr em os ocasión de ver los dist int os niveles de accesibilidad que podem os aplicar a los t ipos, así com o a los dist int os m iem br os de esos t ipos de dat os. De los dist int os m iem br os que podem os definir en nuest r os t ipos, nos cent r ar em os en las pr opiedades par a ver en det alle los cam bios que han sufr ido con r espect o a VB6. Tam bién ver em os t em as r elacionados con la pr ogr am ación or ient ada a obj et os ( POO) en gener al y de for m a par t icular los que at añen a las int er faces. Cla se s y e st r uct ur a s Cla se s: Tipos por r e fe r e n cia de fin idos por e l u su a r io Las clases: El cor azón de .NET Fr am ewor k La her encia: Car act er íst ica pr incipal de la Pr ogr am ación Or ient ada a Obj et os Encapsulación y Polim or fism o Obj ect : La clase base de t odas las clases de .NET De fin ir u n a cla se Una clase especial: Module Los m iem br os de una clase Car act er íst icas de los m ét odos y pr opiedades Accesibilidad, ám bit o y m iem br os com par t idos Par ám et r os y par ám et r os opcionales Ar r ay de par ám et r os opcionales ( Par am Ar r ay) Sobr ecar ga de m ét odos y pr opiedades Par ám et r os por valor y par ám et r os por r efer encia Par ám et r os opcionales de t ipo Nullable I n st a n cia r : Cr e a r u n obj e t o e n la m e m or ia Declar ar pr im er o la var iable y después inst anciar la Declar ar y asignar en un solo paso El const r uct or : El punt o de inicio de una clase Const r uct or es par am et r izados Cuando Visual Basic 2010 no cr ea un const r uct or aut om át icam ent e El dest r uct or : El punt o final de la vida de una clase I nicialización dir ect a de obj et os Est r u ct u r a s: Tipos por va lor de fin idos por e l u su a r io Definir una est r uct ur a Const r uct or es de las est r uct ur as Dest r uct or es de las est r uct ur as Los m iem br os de una est r uct ur a Cóm o usar las est r uct ur as Acce sibilida d y á m bit o Ám bit o Ám bit o de bloque Ám bit o de pr ocedim ient o Ám bit o de m ódulo Ám bit o de espacio de nom br es La palabr a clave Global Accesibilidad Accesibilidad de las var iables en los pr ocedim ient os Las accesibilidades pr edet er m inadas Anidación de t ipos Los t ipos anidables El nom br e com plet o de un t ipo I m por t ación de espacios de nom br es Alias de espacios de nom br es Pr opie da de s Definir una pr opiedad Pr opiedades de solo lect ur a Pr opiedades de solo escr it ur a Difer ent e accesibilidad par a los bloques Get y Set Pr opiedades pr edet er m inadas Sobr ecar ga de pr opiedades pr edet er m inadas I n t e r fa ce s ¿Qué es una int er faz? ¿Qué cont iene una int er faz? Una int er faz es un cont r at o Las int er faces y el polim or fism o Usar una int er faz en una clase Acceder a los m iem br os im plem ent ados Saber si un obj et o im plem ent a una int er faz I m plem ent ación de m últ iples int er faces Múlt iple im plem ent ación de un m ism o m iem br o ¿Dónde podem os im plem ent ar las int er faces? Un ej em plo pr áct ico usando una int er faz de .NET Tal com o vim os en la lección ant er ior , los t ipos de dat os se dividen en dos gr upos: t ipos por valor y t ipos por r efer encia. Los t ipos por r efer encia r ealm ent e son clases, de la cuales debem os cr ear una inst ancia par a poder usar las, esa inst ancia o copia, se cr ea siem pr e en la m em or ia lej ana ( heap) y las var iables lo único que cont ienen es una r efer encia a la dir ección de m em or ia en la que el CLR ( Com m on Language Runt im e, m ot or en t iem po de ej ecución de .NET) , ha alm acenado el obj et o r ecién cr eado. En .NET Fr am ewor k t odo es de una for m a u ot r a una clase, por t ant o Visual Basic 2010 t am bién depende de la cr eación de clases par a su funcionam ient o, ya que t odo el código que escr ibam os debem os hacer lo dent r o de una clase. Ant es de ent r ar en det alles sint áct icos, veam os la im por t ancia que t ienen las clases en .NET Fr am ewor k y com o r eper cut en en las que podam os definir nosot r os usando Visual Basic 2010. La s cla se s: e l cor a zón de .N ET Fr a m e w or k Pr áct icam ent e t odo lo que podem os hacer en .NET Fr am ewor k lo hacem os m ediant e clases. La libr er ía de clases de .NET Fr am ewor k es pr ecisam ent e el cor azón del pr opio .NET, en esa libr er ía de clases est á t odo lo que podem os hacer dent r o de est e m ar co de pr ogr am ación; par a pr áct icam ent e cualquier t ar ea que quer am os r ealizar exist en clases, y si no exist en, las podem os definir nosot r os m ism os, bien am pliando la funcionalidad de alguna clase exist ent e m ediant e la her encia, bien im plem ent ando algún t ipo de funcionalidad pr eviam ent e definida o sim plem ent e cr eándolas desde cer o. La h e r e n cia : Ca r a ct e r íst ica pr in cipa l de la Pr ogr a m a ción Or ie n t a da a Obj e t os El concept o de Pr ogr am ación Or ient ada a Obj et os ( POO) es algo int r ínseco al pr opio .NET Fr am ewor k, por t ant o es una car act er íst ica que t odos los lenguaj es basados en est e "m ar co de t r abaj o" t ienen de for m a pr edet er m inada, ent r e ellos el Visual Basic 2010. De las car act er íst icas pr incipales de la POO t enem os que dest acar la her encia, que en br eve podem os definir com o una car act er íst ica que nos per m it e am pliar la funcionalidad de una clase exist ent e sin per der la que ya t uvier a pr eviam ent e. Gr acias a la her encia, podem os cr ear una nueva clase que se der ive de ot r a, est a nueva clase puede cam biar el com por t am ient o de la clase base y/ o am pliar lo, de est a for m a podem os adapt ar la clase, llam ém osla, or iginal par a adapt ar la a nuest r as necesidades. El t ipo de her encia que .NET Fr am ewor k sopor t a es la her encia sim ple, es decir , solo podem os usar una clase com o base de la nueva, si bien, com o ver em os m ás adelant e, podem os agr egar m últ iple funcionalidad a nuest r a nueva clase. Est a funcionalidad nos ser vir á par a apr ovechar la funcionalidad de m uchas de las clases exist ent es en .NET Fr am ewor k, funcionalidad que solam ent e podr em os aplicar si pr eviam ent e hem os fir m ado un cont r at o que asegur e a la clase de .NET que la nuest r a est á pr epar ada par a sopor t ar esa funcionalidad, est o lo ver em os dent r o de poco con m ás det alle. En ca psu la ción y Polim or fism o La encapsulación y el polim or fism o son ot r as dos car act er íst icas de la pr ogr am ación or ient ada a obj et os. La encapsulación nos per m it e abst r aer la for m a que t iene de act uar una clase sobr e los dat os que cont iene o m anipula, par a poder logr ar lo se exponen com o par t e de la clase los m ét odos y pr opiedades necesar ios par a que podam os m anej ar esos dat os sin t ener que pr eocupar nos cóm o se r ealiza dicha m anipulación. El polim or fism o es una car act er íst ica que nos per m it e r ealizar cier t as acciones o acceder a la infor m ación de los dat os cont enidos en una clase de for m a sem i- anónim a, al m enos en el sent ido de que no t enem os por qué saber sobr e que t ipo obj et o r ealizam os la acción, ya que lo único que nos debe pr eocupar es que podem os hacer lo, por la sencilla r azón de que est am os usando cier t os m ecanism os que siguen unas nor m as que est án adopt adas por la clase. El ej em plo clásico del polim or fism o es que si t engo un obj et o que "sabe" cóm o m or der , da igual que lo aplique a un r at ón o a un dinosaur io, siem pr e y cuando esas dos "clases" expongan un m ét odo que pueda r ealizar esa acción... y com o decía la docum ent ación de Visual Basic 5.0, siem pr e ser á pr efer ible que nos m uer da un r at ón ant es que un dinosaur io. Obj e ct : La cla se ba se de t oda s la s cla se s de .N ET Todas las clases de .NET se der ivan de la clase Obj ect , es decir , lo indiquem os o no, cualquier clase que definam os t endr á el com por t am ient o her edado de esa clase. El uso de la clase Obj ect com o base del r est o de las clases de .NET es la única excepción a la her encia sim ple sopor t ada por .NET, ya que de for m a im plícit a, t odas las clases de .NET se der ivan de la clase Obj ect independient em ent e de que est én der ivadas de cualquier ot r a. Est a car act er íst ica nos asegur a que siem pr e podr em os usar un obj et o del t ipo Obj ect par a acceder a cualquier clase de .NET, aunque no debem os abr um ar nos t odavía, ya que en el t ext o que sigue ver em os con m ás det alle que significado t iene est a afir m ación. De los m iem br os que t iene la clase Obj ect debem os r esalt ar el m ét odo ToSt r ing, el cual ya lo vim os en la lección ant er ior cuando quer íam os conver t ir un t ipo pr im it ivo en una cadena. Est e m ét odo est á pensado par a devolver una r epr esent ación en for m at o cadena de un obj et o. El valor que obt engam os al usar est e m ét odo depender á de cóm o est é definido en cada clase y por defect o lo que devuelve es el nom br e com plet o de la clase, si bien en la m ayor ía de los casos el valor que obt endr em os al usar est e m ét odo deber ía ser m ás int uit ivo, por ej em plo los t ipos de dat os pr im it ivos t ienen definido est e m ét odo par a devuelva el valor que cont ienen, de igual for m a, nuest r as clases t am bién deber ían devolver un valor adecuado al cont enido alm acenado. De cóm o hacer lo, nos ocupar em os en br eve. N ot a: Todos los t ipos de dat os de .NET, ya sean por valor o por r efer encia siem pr e est án der ivados de la clase Obj ect , por t ant o podr em os llam ar a cualquier a de los m ét odos que est án definidos en esa clase. Aunque en el caso de los t ipos de dat os por valor , cuando quer em os acceder a la clase Obj ect que cont ienen, .NET Fr am ewor k pr im er o debe conver t ir la en un obj et o por r efer encia ( boxing) y cuando hem os dej ado de usar la y quer em os volver a asignar el dat o a la var iable por valor , t iene que volver a hacer la conver sión inver sa ( unboxing) . D e f in ir u n a cla se En Visual Basic 2010, t odo el código que quer am os escr ibir , lo t endr em os que hacer en un ficher o con la ext ensión .vb, dent r o de ese ficher o es donde escr ibir em os nuest r o código, el cual, t al com o dij im os ant er ior m ent e siem pr e est ar á incluido dent r o de una clase, aunque un ficher o de código de VB puede cont ener una o m ás clases, es decir , no est á lim it ado a una clase por ficher o. En Visual Basic 2010 las clases se definen usando la palabr a clave Class seguida del nom br e de la clase, esa definición acaba indicándolo con End Class. En el siguient e ej em plo definim os una clase llam ada Client e que t iene dos cam pos públicos. Class Cliente Public Nombre As String Public Apellidos As String End Class Una vez definida la clase podem os agr egar los elem ent os ( o m iem br os) que cr eam os convenient e. En el ej em plo ant er ior , par a sim plificar , hem os agr egado dos cam pos públicos, aunque t am bién podr íam os haber definido cualquier a de los m iem br os per m it idos en las clases. Una cla se e spe cia l: M odule En Visual Basic 2010 t am bién podem os definir una clase especial llam ada Module, est e t ipo de clase, com o ver em os, t iene un t r at am ient o especial. La definición se hace usando la inst r ucción Module seguida del nom br e a usar y acaba con End Module. Cualquier m iem br o definido en un Module siem pr e est ar á accesible en t odo el pr oyect o y par a usar los no t endr em os que cr ear ningún obj et o en m em or ia. Las clases definidas con la palabr a clave Module r ealm ent e equiv alen a las clases en las que t odos los m iem br os est án com par t idos y por t ant o siem pr e disponibles a t oda la aplicación. De t odos est os concept os nos ocupar em os en las siguient es lecciones, per o es necesar io explicar que ex ist e est e t ipo de clase ya que ser á el t ipo de dat os que el I DE de Visual Basic 2010 usar á al cr ear aplicaciones del t ipo consola, ya que ese ser á el t ipo de pr oyect o que cr ear em os par a pr act icar con el código m ost r ado en est e pr im er m ódulo. Los m ie m br os de una cla se Una clase puede cont ener cualquier a de est os elem ent os ( m iem br os) : Enum er aciones Cam pos Mét odos ( funciones o pr ocedim ient os) Pr opiedades Event os Las enum er aciones, com o vim os en la lección ant er ior , podem os usar las par a definir valor es const ant es r elacionados, por ej em plo par a indicar los v alor es posibles de cualquier "car act er íst ica" de la clase. Los cam pos son var iables usadas par a m ant ener los dat os que la clase m anipular á. Los m ét odos son las acciones que la clase puede r ealizar , nor m alm ent e esas acciones ser án sobr e los dat os que cont iene. Dependiendo de que el m ét odo devuelv a o no un valor , podem os usar m ét odos de t ipo Funct ion o de t ipo Sub r espect ivam ent e. Las pr opiedades son las "car act er íst icas" de las clases y la for m a de acceder "públicam ent e" a los dat os que cont iene. Por ej em plo, podem os consider ar que el nom br e y los apellidos de un client e son dos car act er íst icas del client e. Los event os son m ensaj es que la clase puede enviar par a infor m ar que algo est á ocur r iendo en la clase. Ca r a ct e r íst ica s de los m é t od os y pr opie da de s Acce sibilida d, á m bit o y m ie m br os com pa r t idos Aunque est os t em as los ver em os en br eve con m ás det alle, par a poder com pr ender m ej or las car act er íst icas de los m iem br os de una clase ( o cualquier t ipo que definam os) , dar em os un pequeño adelant o sobr e est as car act er íst icas que podem os aplicar a los elem ent os que definam os. Accesibilidad y ám bit o son dos concept os que est án est r echam ent e r elacionados. Aunque en la pr áct ica t ienen el m ism o significado, ya que lo que r epr esent an es la "cober t ur a" o alcance que t ienen los m iem br os de las clases e incluso de las m ism as clases que definam os. Si bien cada uno de ellos t ienen su pr opia "sem ánt ica", t al com o podem os ver a cont inuación: Ám bit o Es el alcance que la definición de un m iem br o o t ipo puede t ener . Es decir , cóm o podem os acceder a ese elem ent o y desde dónde podem os acceder lo. El ám bit o de un elem ent o de código est á r est r ingido por el "sit io" en el que lo hem os declar ado. Est os sit ios pueden ser : Ám bit o Ám bit o Ám bit o Ám bit o de de de de bloque: Disponible únicam ent e en el bloque de código en el que se ha declar ado. pr ocedim ient o: Disponible únicam ent e dent r o del pr ocedim ient o en el que se ha declar ado. m ódulo: Disponible en t odo el código del m ódulo, la clase o la est r uct ur a donde se ha declar ado. espacio de nom br es: Disponible en t odo el código del espacio de nom br es. Accesibilidad A los dist int os elem ent os de nuest r o código ( y a sean clases o m iem br os de las clases) podem os dar le difer ent es t ipos de accesibilidad. Est os t ipos de "acceso" depender án del ám bit o que quer am os que t engan, es decir , desde dónde podr em os acceder los. Los m odificador es de accesibilidad son: Public: Acceso no r est r ingido. Pr ot ect ed: Acceso lim it ado a la clase cont enedor a o a los t ipos der ivados de est a clase. Fr iend: Acceso lim it ado al pr oy ect o act ual. Pr ot ect ed Fr iend: Acceso lim it ado al pr oyect o act ual o a los t ipos der ivados de la clase cont enedor a. Pr ivat e: Acceso lim it ado al t ipo cont enedor . Por ej em plo, podem os declar ar m iem br os pr ivados a una clase, en ese caso, dichos m iem br os solam ent e los podr em os acceder desde la pr opia clase, per o no desde fuer a de ella. N ot a: Al declar ar una var iable con D im , el ám bit o que le est am os aplicando por r egla gen er al, es pr ivado, per o com o v er em os, en Visual Basic 2010 el ám bit o puede ser difer ent e a pr ivado dependiendo del t ipo en el que declar em os esa var iable. M iem br os com par t idos Por ot r o lado, los m iem br os com par t idos de una clase o t ipo, son elem ent os que no per t enecen a una inst ancia o copia en m em or ia par t icular , sino que per t enecen al pr opio t ipo y por t ant o siem pr e est án accesibles o disponibles, dent r o del niv el del ám bit o y accesibilidad que les hayam os aplicado, y su t iem po de vida es el m ism o que el de la aplicación. Del ám bit o, la accesibilidad y los m iem br os com par t idos n os ocupar em os con m ás det alle en una lección post er ior , donde ver em os cier t as peculiar idades, com o puede ser la lim it ación del ám bit o de un m iem br o que apar ent em ent e t iene una accesibilidad no r est r in gida. Pa r á m e t r os e spe cíficos y pa r á m e t r os opcion a le s En Visual Basic 2010, t ant o los m iem br os de una clase, ( funciones y m ét odos Sub) , com o las pr opiedades pueden r ecibir par ám et r os. Esos par ám et r os pueden est ar ex plícit am ent e declar ados, de for m a que podam os indicar cuant os ar gum ent os t endr em os que pasar al m ét odo, t am bién podem os declar ar par ám et r os opcionales, que son par ám et r os que no hace falt a indicar al llam ar a la función o pr opiedad, y que siem pr e t endr án un v alor pr edet er m inado, el cual se usar á en caso de que no lo indiquem os. Adem ás de los par ám et r os específicos y opcionales, podem os usar un ar r ay de par ám et r os opcionales, en los que se puede indicar un núm er o v ar iable de ar gum ent os al llam ar a la función que los define, est o lo v er em os en la siguient e sección. N ot a: Sobr e par ám et r os y ar gum ent os Par a clar ificar las cosas, quer em os decir que los par ám et r os son los definidos en la función, m ient r as que los ar gum ent os son los "par ám et r os" que pasam os a esa función cuando la ut ilizam os desde nuest r o código. Con los par ám et r os opcionales lo que conseguim os es per m it ir que el usuar io no t enga que int r oducir t odos los par ám et r os, sino solo los que r ealm ent e necesit e, del r est o, ( los no especificados) , se usar á el v alor pr edet er m inado que hayam os indicado, por que una de las "r est r icciones" de est e t ipo de par ám et r os, es que siem pr e debem os indicar t am bién el valor por defect o que debem os usar en caso de que no se especifique. Veam os u n os ej em plo par a aclar ar n uest r as ideas: Function Suma(n1 As Integer, Optional n2 As Integer = 15) As Integer Suma = n1 + n2 End Function En est e pr im er ej em plo, el pr im er par ám et r o es obligat or io ( siem pr e debem os indicar lo) y el segundo es opcional, si no se indica al llam ar a est a función, se usar á el valor 15 que es el pr edet er m inado. Par a llam ar a est a función, lo podem os hacer de est as t r es for m as: ' t ' t ' t 1- indicando los dos parámetros (el resultado será 4= 1 + 3) = Suma(1, 3) 2- Indicando solamente el primer parámetro (el resultado será 16= 1 + 15) = Suma(1) 3- Indicando los dos parámetros, pero en el opcional usamos el nombre = Suma(1, n2:= 9) El t er cer ej em plo solam ent e t iene ut ilidad si hay m ás de un par ám et r o opcional. N ot a: Los par ám et r os opcionales deben apar ecer en la list a de par ám et r os del m ét odo, después de los "obligat or ios" N ot a: En el caso hipot ét ico y no r ecom endable de que no est em os usando Opt ion St r ict On, t ant o los par ám et r os nor m ales com o los opcionales los podem os indicar sin el t ipo de dat os, per o si en alguno de ellos especificam os el t ipo, debem os hacer lo en t odos. Ar r a y de pa r á m e t r os opcion a le s ( Pa r a m Ar r a y) En cuant o al uso de Par am Ar r ay, est e t ipo de par ám et r o opcional nos per m it e indicar un núm er o indet er m inado de par ám et r os, en Visual Basic 2010 siem pr e debe ser u na ar r ay e in t er n am en t e se t r at a com o u n ar r ay nor m al y cor r ient e, es decir , dent r o del m ét odo o pr opiedad se accede a él com o si de un ar r ay se t r at ar a... ent r e ot r as cosas, ¡por que es un ar r ay! Si t enem os act iv ado Opt ion St r ict , el ar r ay usado con Par am Ar r ay debe ser de un t ipo en concr et o, si quer em os que acept e cualquier t ipo de dat os, lo podem os declar ar con el t ipo Obj ect . Si por cualquier r azón necesit am os pasar ot r os valor es que no sean de un t ipo en concr et o, por ej em plo, adem ás de valor es "nor m ales" quer em os pasar un ar r ay , podem os desact ivar Opt ion St r ict par a hacer lo fácil. Por ej em plo, si quer em os hacer algo com o est o: Function Suma(ParamArray n() As Object) As Integer Dim total As Integer ' For i As Integer = 0 To n.Length - 1 If IsArray(n(i)) Then For j As Integer = 0 To n(i).Length - 1 total += n(i)(j) Next Else total += n(i) End If Next Return total End Function ' Para usarlo: Dim t As Integer Dim a(2) As Integer = {1, 2, 3} t = Suma(a, 4, 5, 6) Console.WriteLine(t) Tal com o vem os, el pr im er ar gum ent o que pasam os a la función Sum a es un ar r ay, después pasam os t r es v alor es ent er os nor m ales. El r esult ado de ej ecut ar ese código ser á el valor 2 1 , com o es de esper ar . N ot a: Com o Visual Basic 2010 no sabe que t ipo cont iene n( i) , al escr ibir est e código, no nos infor m ar á de que ese "obj et o" t iene una pr opiedad llam ada Lengt h. Per o com o no debem os "acost um br ar nos" a desact ivar Opt ion St r ict , v am os a ver el código que t endr íam os que usar par a que t am bién acept e un ar r ay com o par t e de los ar gum ent os indicados al llam ar a la función. Function Suma(ByVal ParamArray n() As Object) As Integer Dim total As Integer ' For i As Integer = 0 To n.Length - 1 If IsArray(n(i)) Then For j As Integer = 0 To CType(n(i), Integer()).Length - 1 total += CType(n(i), Integer())(j) Next Else total += CInt(n(i)) End If Next Return total End Function ' Para usarlo: Dim t As Integer Dim a(2) As Integer = {1, 2, 3} t = Suma(a, 4, 5, 6) Console.WriteLine(t) Com o podem os com pr obar , al t ener Opt ion St r ict act ivado, debem os hacer una conv er sión explícit a del ar r ay a uno de un t ipo en concr et o, com o es nat ur al, en est e código est am os suponiendo que el ar r ay pasado com o ar gum ent o a la función es de t ipo I nt eger , en caso de que no lo fuer a, r ecibir íam os un er r or en t iem po de ej ecución. Par a com pr obar si el cont enido de n( i) es un ar r ay, hem os usado la función I sAr r ay definida en el espacio de nom br es Micr osoft VisualBasic ( que por defect o ut ilizan t odas las aplicaciones de Visual Basic 2010) , per o t am bién lo podr íam os haber hecho m ás al "est ilo .NET", y a que, com o sabem os t odos los ar r ay s de .NET r ealm ent e se der iv an de la clase Ar r ay: If TypeOf n(i) Is Array Then N ot a: Cuando quer am os usar Par am Ar r ay par a r ecibir un ar r ay de par ám et r os opcionales, est a inst r ucción debe ser la últ im a de la list a de par ám et r os de la función ( m ét odo) . Tam poco se per m it e t ener par ám et r os opcionales y Par am Ar r ay en la m ism a función. Sobr e ca r ga de m é t odos y pr opie da de s La sobr ecar ga de funciones ( r ealm ent e de m ét odos y pr opiedades) , es una car act er íst ica que nos per m it e t ener una m ism a función con difer ent es t ipos de par ám et r os, ya sea en núm er o o en t ipo. Supongam os que quer em os t ener dos funciones ( o m ás) que nos per m it an hacer oper aciones con difer ent es t ipos de dat os, y que, según el t ipo de dat os usado, el valor que devuelva sea de ese m ism o t ipo. En est e ej em plo, t enem os dos funciones que se llam an igual per o una r ecibe v alor es de t ipo ent er o y la ot r a de t ipo decim al: Function Suma(n1 As Integer, n2 As Integer) As Integer Return n1 + n2 End Function Function Suma(n1 As Double, n2 As Double) As Double Return n1 + n2 End Function Com o podem os com pr obar las dos funciones t ienen el m ism o nom br e, per o t ant o una com o ot r a r eciben par ám et r os de t ipos difer ent es. Con Visual Basic 2010 podem os sobr ecar gar funciones, per o lo int er esant e no es que podam os hacer lo, sino cóm o podem os usar esas funciones. En el código ant er ior t enem os dos funciones llam adas Sum a, la pr im er a acept a dos par ám et r os de t ipo I nt eger y la segunda de t ipo Double. Lo int er esant e es que cuando quer am os usar las, no t enem os que pr eocupar nos de cual vam os a usar , ya que ser á el com pilador el que decida la m ás adecuada al código que usem os, por ej em plo: ' En este caso, se usará la que recibe dos valores enteros Console.WriteLine(Suma(10, 22) ) ' En este caso se usará la que recibe valores de tipo Double Console.WriteLine(Suma(10.5, 22) El com pilador de Visual Basic 2010 es el que decide que función usar , esa decisión la t om a a par t ir de los t ipos de par ám et r os que hayam os indicado. En el segundo ej em plo de uso, el que m ej or coincide es el de los dos par ám et r os de t ipo Double. Tam bién podem os t ener sobr ecar ga usando una cant idad difer ent e de par ám et r os, aunque ést os sean del m ism o t ipo. Por ej em plo, podem os añadir est a declar ación al código ant er ior sin que exist a ningún t ipo de er r or , ya que est a nueva función r ecibe t r es par ám et r os en lugar de dos: Function Suma(n1 As Integer, n2 As Integer, n3 As Integer) As Integer Return n1 + n2 + n3 End Function Por t ant o, cuando el com pilador se encuent r e con una llam ada a la función Sum a en la que se usen t r es par ám et r os, int ent ar á usar est a últ im a. N ot a: Par a que ex ist a sobr ecar ga, la difer encia debe est ar en el núm er o o en el t ipo de los par ám et r os, no en el t ipo del valor devuelt o. Cuando, desde el I DE de Visual Basic 2010, quer em os usar los m ét odos sobr ecar gados, nos m ost r ar á una list a de opciones indicán donos las posibilidades de sobr ecar ga que exist en y ent r e las que podem os elegir , t al com o vem os en la figur a 2.10: Figur a 2 .1 0 . List a de par ám et r os sopor t ados por un m ét odo Cuando ut ilicem os par ám et r os opcionales debem os t ener en cuent a que puede que el com pilador nos m uest r e un er r or , ya que es posible que esa función que declar a par ám et r os opcionales ent r e en conflict o con una "sobr ecar gada". Por ej em plo: Function Suma(n1 As Integer, Optional n2 As Integer = 33) As Integer Return n1 + n2 End Function Si t enem os est a declar ación adem ás de las ant er ior es, el pr ogr am a no com pilar á, ya que si hacem os una llam ada a la función Sum a con dos par ám et r os ent er os, el com pilador no sabr á si usar est a últ im a o la pr im er a que declar am os, por t ant o pr oducir á un er r or . Pa r á m e t r os por v a lor y pa r á m e t r os p or r e fe r e ncia Al igual que t enem os dos t ipos de dat os difer ent es, en los par ám et r os de las funciones t am bién podem os t ener los, par a ello t endr em os que usar By Val o By Ref par a indicar al com pilador cóm o debe t r at ar a los par ám et r os. Cuando un par ám et r o es por valor ( ByVal) , el r unt im e ant es de llam ar a la función hace una copia de ese par ám et r o y pasa la copia a la función, por t ant o cualquier cam bio que hagam os a ese par ám et r o dent r o de la función no afect ar á al valor usado "ext er nam ent e". En el caso de que el par ám et r o sea por r efer encia ( ByRef) , el com pilador pasa una r efer encia que apunt a a la dir ección de m em or ia en la que est án los dat os, por t ant o si r ealizam os cam bios dent r o de la función, ese cam bio si que se ver á r eflej ado en el par ám et r o usado al llam ar a la función. N ot a: Hay que t ener en cuent a que si pasam os un obj et o a una función, da igual que lo declar em os por valor o por r efer encia, ya que en am bos casos se pasa una r efer encia a la dir ección de m em or ia en la que est án los dat os, por que, com o sabem os, las var iables de los t ipos por r efer encia siem pr e cont ienen una r efer encia a los dat os, no los dat os en sí. Cuando en Visual Basic 2010 usam os par ám et r os en los que no se indica si es por valor ( ByVal) o por r efer encia ( ByRef) , ser án t r at ados com o par ám et r os por valor . N ot a: Si usam os el I DE de Visual St udio 2010 par a escr ibir el código, no debem os pr eocupar nos de est e det alle, ya que si no indicam os si es por valor o por r efer encia, aut om át icam ent e le añadir á la palabr a clave By Val, par a que no hay a ningún t ipo de dudas. Pa r á m e t r os opciona le s de t ipo N ulla ble En el t r adicional Visual Basic, podíam os cr ear m ét odos y funciones con par ám et r os opcionales. Est a car act er íst ica fue agr egada en Visual Basic, y dem andada por la com unidad de desar r ollador es de C# , ya que en det er m inadas sit uaciones, puede r esult ar r ealm ent e út il. De est a m aner a, hacer lo siguient e en Visual Basic 2008 es com plet am ent e válido: Private Function Sumar(Optional ByVal x As Integer = Nothing, Optional ByVal y As Integer = Nothing)As Integer x = IIf(IsNothing(x), 0, x) y = IIf(IsNothing(y), 0, y) Return x + y End Function Podr íam os ent onces llam ar a esa función de la siguient e m aner a: MessageBox.Show(Sumar(3).ToString()) Fu nción que n os devolver ía el valor 3, siendo la sum a, 3 + 0, y siendo 3 el valor de x . Ahor a bien, en Visual Basic 2010 podem os indicar par ám et r os opcionales, per o de t ipo Nullable. Su funcionam ient o es el m ism o, con la salvedad de ut ilizar la var iable com o var iable de t ipo Nullable ( en el apar t ado de t ipos Nullable se explicaba com o funcionaban) . Un ej em plo pr áct ico de com o funcionan y com o ut ilizar est e t ipo de par ám et r os es el que se indica a cont inuación: Private Function Sumar(Optional ByVal x As Integer? = Nothing, Optional ByVal y As Integer? = Nothing)As Integer x = IIf(IsNothing(x), 0, x) y = IIf(IsNothing(y), 0, y) Return x + y End Function Par a ej ecut ar el m ét odo, lanzar em os el m ism o pr ocedim ient o de ej ecución: MessageBox.Show(Sumar(3).ToString()) El r esult ado que obt enem os en est e caso, ser á el m ism o que vim os ant er ior m ent e, es decir , el v alor 3, per o int ent e pensar que est e es un ej em plo m uy básico, y que los t ipos Nullable nos per m it en indicar v alor es que no est án inicializados y en base a ese valor , r ealizar una u ot r a acción. Una vez que t enem os una clase definida, lo único de lo que disponem os es de una especie de plant illa o m olde a par t ir del cual podem os cr ear obj et os en m em or ia. Par a cr ear esos obj et os en Visual Basic 2010 lo podem os hacer de dos for m as, per o com o ver em os siem pr e ser á m ediant e la inst r ucción New que es la encar gada de cr ear el obj et o en la m em or ia y asignar la dir ección del m ism o a la var iable usada en la par t e izquier da de la asignación. D e cla r a r pr im e r o la v a r ia ble y de spué s inst a ncia r la Lo pr im er o que t enem os que hacer es declar ar una var iable del t ipo que quer em os inst anciar , est o lo hacem os de la m ism a for m a que con cualquier ot r o t ipo de dat os: Dim c As Cliente Con est a línea de código lo que est am os indicando a Visual Basic es que t enem os int ención de usar una var iable llam ada c par a acceder a una clase de t ipo Client e. Esa var iable, cuando llegue el m om ent o de usar la, sabr á t odo lo que hay que saber sobr e una clase Client e, per o hast a que no t enga una "r efer encia" a un obj et o de ese t ipo no podr em os usar la. La asignación de una r efer encia a un obj et o Client e la har em os usando la inst r ucción New seguida del nom br e de la clase: c = New Cliente A par t ir de est e m om ent o, la var iable c t iene acceso a un nuevo obj et o del t ipo Client e, por t ant o podr em os usar la par a asignar le valor es y usar cualquier a de los m iem br os que ese t ipo de dat os cont enga: c.Nombre = "Antonio" c.Apellidos = "Ruiz Rodríguez" D e cla r a r y a signa r e n un solo pa so Con las clases o t ipos por r efer encia t am bién podem os declar ar una var iable y al m ism o t iem po asignar le un nuevo obj et o: Dim c As New Cliente O t am bién: Dim c As Cliente = New Cliente Las dos for m as pr oducen el m ism o r esult ado, por t ant o es r ecom endable usar la pr im er a. El const r uct or : El punt o de inicio de una cla se Cada vez que cr eam os un nuevo obj et o en m em or ia est am os llam ando al const r uct or de la clase. En Visual Basic 2010 el const r uct or es un m ét odo de t ipo Sub llam ado New. En el const r uct or de una clase podem os incluir el código que cr eam os convenient e, per o r ealm ent e solam ent e deber íam os incluir el que r ealice algún t ipo de inicialización, en caso de que no necesit em os r ealizar ningún t ipo de inicialización, no es necesar io definir el const r uct or , ya que el pr opio com pilador lo har á por nosot r os. Est o es así por que t odas las clases deben im plem ent ar un const r uct or , por t ant o si nosot r os no lo definim os, lo har á el com pilador de Visual Basic 2010. Si nuest r a clase Client e t iene un cam po par a alm acenar la fecha de cr eación del obj et o podem os hacer algo com o est o: Class Cliente Public Nombre As String Public Apellidos As String Public FechaCreacion As Date ' Public Sub New() FechaCreacion = Date.Now End Sub End Class De est a for m a podem os cr ear un nuevo Client e y act o seguido com pr obar el valor del cam po FechaCr eacion par a saber la fecha de cr eación del obj et o. En los const r uct or es t am bién podem os hacer las inicializaciones que, por ej em plo per m it an a la clase a conect ar se con una base de dat os, abr ir un ficher o o car gar una im agen gr áfica, et c. Const r uct or e s pa r a m e t r iza dos De la m ism a for m a que podem os t ener m ét odos y pr opiedades sobr ecar gadas, t am bién podem os t ener const r uct or es sobr ecar gados, ya que debem os r ecor dar que en Visual Basic 2010, un const r uct or r ealm ent e es un m ét odo de t ipo Sub, y com o t odos los m ét odos y pr opiedades de Visual Basic 2010, t am bién adm it e la sobr ecar ga. La vent aj a de t ener const r uct or es que adm it an par ám et r os es que podem os cr ear nuevos obj et os indicando algún par ám et r o, por ej em plo un ficher o a abr ir o, en el caso de la clase Client e, podem os indicar el nom br e y apellidos del client e o cualquier ot r o dat o que cr eam os convenient e. Par a com pr obar lo, podem os am pliar la clase definida ant er ior m ent e par a que t am bién acept e la cr eación de nuevos obj et os indicando el nom br e y los apellidos del client e. Class Cliente Public Nombre As String Public Apellidos As String Public FechaCreacion As Date ' Public Sub New() FechaCreacion = Date.Now End Sub ' Public Sub New(elNombre As String, losApellidos As String) Nombre = elNombre Apellidos = losApellidos FechaCreacion = Date.Now End Sub End Class Teniendo est a declar ación de la clase Client e, podem os cr ear nuevos client es de dos for m as: Dim c1 As New Cliente Dim c2 As New Cliente("Jose", "Sánchez") Com o podem os com pr obar , en cier t os casos es m ás int uit iva la segunda for m a de cr ear obj et os del t ipo Client e, adem ás de que así nos ahor r am os de t ener que asignar individualm ent e los cam pos N om br e y Apellidos. Est a declar ación de la clase Client e la podr íam os haber hecho de una for m a difer ent e. Por un lado t enem os un const r uct or "nor m al" ( no r ecibe par ám et r os) en el que asignam os la fecha de cr eación y por ot r o el const r uct or que r ecibe los dat os del nom br e y apellidos. En ese segundo const r uct or t am bién asignam os la fecha de cr eación, ya que, se inst ancie com o se inst ancie la clase, nos int er esa saber siem pr e la fecha de cr eación. En est e ej em plo, por su sim pleza no es r ealm ent e un pr oblem a r epet ir la asignación de la fecha, per o si en lugar de una inicialización necesit ár am os hacer var ias, la ver dad es que nos encont r ar íam os con m ucha "duplicidad" de código. Por t ant o, en lugar de asignar los dat os en dos lugar es difer ent es, podem os hacer est o ot r o: Class Cliente Public Nombre As String Public Apellidos As String Public FechaCreacion As Date ' Public Sub New() FechaCreacion = Date.Now End Sub ' Public Sub New(elNombre As String, losApellidos As String) Nombre = elNombre Apellidos = losApellidos End Sub End Class Es decir , desde el const r uct or con ar gum ent os llam am os al const r uct or que no los t iene, consiguiendo que t am bién se asigne la fecha. Est a declar ación de la clase Client e r ealm ent e no com pilar á. Y no com pila por la r azón t an "sim ple" de que aquí el com pilador de Visual Basic 2010 no sabe cual es nuest r a int ención, ya que New es una palabr a r eser vada que sir ve par a cr ear nuevos obj et os y, siem pr e, una inst r ucción t iene pr efer encia sobr e el nom br e de un m ét odo, por t ant o, podem os r ecur r ir al obj et o especial Me el cual nos sir ve, par a r epr esent ar al obj et o que act ualm ent e est á en la m em or ia, así que, par a que esa declar ación de la clase Client e funcione, debem os usar Me.New( ) par a llam ar al const r uct or sin par ám et r os. N ot a: El I DE de Visual Basic 2010 color ea las inst r ucciones y t ipos pr opios del lenguaj e, en el caso de Me, lo que no debe confundir nos es que cuando declar am os Sub New, t ant o Sub com o New se m uest r an color eadas, cuando solo se deber ía color ear Sub; sin em bar go cuando usam os Me.New, solo se color ea Me y no New que es cor r ect o, t al com o vem os en la figur a 2.11, ya que en est e caso New es el nom br e de un pr ocedim ient o y los pr ocedim ient os no son par t e de las inst r ucciones y t ipos de .NET. Figur a 2 .1 1 . Color eo er r óneo de N ew Cu a n do Visu a l Ba sic 2 0 1 0 n o cr e a u n con st r u ct or a u t om á t ica m e n t e Tal com o hem os com ent ado, si nosot r os no definim os un const r uct or ( Sub New) , lo har á el pr opio com pilador de Visual Basic 2010, y cuando lo hace aut om át icam ent e, siem pr e es un const r uct or sin par ám et r os. Per o hay ocasiones en las que nos puede int er esar que no exist a un const r uct or sin par ám et r os, por ej em plo, podem os cr ear una clase Client e que solo se pueda inst anciar si le pasam os, por ej em plo el núm er o de ident ificación fiscal, ( NI F) , en caso de que no se indique ese dat o, no podr em os cr ear un nuevo obj et o Client e, de est a for m a, nos asegur am os siem pr e de que el NI F siem pr e est é especificado. Segur am ent e por ese m ot ivo, si nosot r os definim os un const r uct or con par ám et r os, Visual Basic 2010 no cr ea uno aut om át icam ent e sin par ám et r os. Por t ant o, si definim os un const r uct or con par ám et r os en una clase y quer em os que t am bién t enga uno sin par ám et r os, lo t enem os que definir nosot r os m ism os. El de st r uct or : El punt o fina l de la v ida de una cla se De la m ism a for m a que una clase t iene su punt o de ent r ada o m om ent o de nacim ient o en el const r uct or , t am bién t ienen un sit io que se ej ecut ar á cuando el obj et o cr eado en la m em or ia ya no sea necesar io, es decir , cuando acabe la vida del obj et o cr eado. El dest r uct or de Visual Basic 2010 es un m ét odo llam ado Fin alize, el cual se her eda de la clase Obj ect , por t ant o no es necesar io que escr ibam os nada en él. El pr opio CLR se encar gar á de llam ar a ese m ét odo cuando el obj et o ya no sea necesar io. La for m a en que se dest r uyen los obj et os pueden ser de dos for m as: Por que los dest r uyam os nosot r os asignando un valor Not hing a la var iable que lo r efer encia, o bien por que el obj et o est é fuer a de ám bit o, es decir , haya salido de su espacio de ej ecución, por ej em plo, si declar am os un obj et o dent r o de un m ét odo, cuando ese m ét odo t er m ina, el obj et o se dest r uye, ( hay algunas excepciones a est a últ im a r egla, com o puede ser que ese m ism o obj et o t am bién est é r efer enciado por ot r a var iable ext er na al m ét odo.) Lo que debem os t ener m uy pr esent e es que en .NET los obj et os no se dest r uyen inm ediat am ent e. Est o es así debido a que en .NET exist e un "sist em a" que se encar ga de r ealizar est a gest ión de lim pieza: El r ecolect or de basur a o de obj et os no usados ( Gar bage Collect or , GC) . Est e r ecolect or de obj et os no usados se encar ga de com pr obar const ant em ent e cuando un obj et o no se est á usando y es el que decide cuando hay que llam ar al dest r u ct or . Debido a est a car act er íst ica de .NET, si nuest r a clase hace uso de r ecur sos ext er nos que necesit en ser elim inados cuando el obj et o ya no se vaya a seguir usando, debem os definir un m ét odo que sea el encar gado de r ealizar esa liber ación, per o ese m ét odo debem os llam ar lo de for m a m anual, ya que, aunque en .NET exist en for m as de hacer que esa llam ada sea aut om át ica, nunca t ender em os la segur idad de que se llam e en el m om ent o opor t uno, y est o es algo que, según que casos, puede ser un inconvenient e. Recom endación: Si nuest r a clase ut iliza r ecur sos ext er nos, por ej em plo un ficher o o una base de dat os, debem os definir un m ét odo que se encar gue de liber ar los y a ese m ét odo debem os encar gar nos de llam ar lo cuando ya no lo necesit em os. Por definición a est e t ipo de m ét odos se les suele dar el nom br e Close o Dispose, aunque est e últ im o t iene un significado especial y por convención solo debem os usar lo siguiendo las indicaciones de la docum ent ación. I nicia liza ción dir e ct a de obj e t os De t odos los m odos, en Visual Basic 2010 se ha agr egado una car act er íst ica adicional que t iene que ver con la inicialización de obj et os. Hast a ahor a hem os vist o com o inst anciar una clase ut ilizando su const r uct or , per o quizás lo que no sabíam os es que en Visual Basic 2010 podem os inicializar la clase a t r avés de su const r uct or e incluso inicializar dir ect am ent e las pr opiedades de la clase. Supongam os por lo t ant o el siguient e código fuent e: Class Cliente Private m_Nombre As String Public Property Nombre() As String Get Return m_Nombre End Get Set(ByVal value As String) m_Nombre = value End Set End Property Public Sub New() End Sub End Class A cont inuación inst anciar em os la clase y con ello, inicializar em os adicionalm ent e la pr opiedad que hem os declar ado. El código quedar á de la siguient e for m a: Dim claseCliente As New Cliente() With {.Nombre = "Pedro"} Est a for m a de inicializar obj et os nos per m it e ser m ás pr oduct ivos y pr áct icos y ahor r ar t iem po y líneas de código en nuest r as aplicaciones. Com o podem os apr eciar , la for m a de inicializar las pr opiedades o las var iables de una clase es ut ilizando la palabr a clave Wit h seguida de llaves, y dent r o de las llaves, un punt o seguido de la pr opiedad o var iable que quer em os inicializar con sus valor de inicialización. Si t enem os m ás de una var iable a inicializar , deber em os separ ar las por com as. I nt ellisense nos ayudar á enor m em ent e a inicializar la pr opiedad o var iable que deseem os, ya que vincula de for m a dir ect a el código de la clase haciéndonos m ás fácil el t r abaj o con los m iem br os de la clase. De la m ism a for m a que podem os definir nuest r os pr opios t ipos de dat os por r efer encia, Visual Basic 2010 nos per m it e cr ear nuest r os pr opios t ipos por valor . Par a cr ear nuest r os t ipos de dat os por r efer encia, usam os la "inst r ucción" Class, por t ant o es de esper ar que t am bién exist a una inst r u cción par a cr ear nuest r os t ipos por valor , y esa inst r ucción es: St r uct ur e, por eso en Visual Basic 2010 a los t ipos por valor definidos por el usuar io se llam an est r uct ur as. Las est r uct ur as pueden cont ener los m ism os m iem br os que las clases, aunque algunos de ellos se com por t en de for m a difer ent e o al m enos t engan algunas r est r icciones, com o que los cam pos definidos en las est r uct ur as no se pueden inicializar al m ism o t iem po que se declar an o no pueden cont ener const r uct or es "sim ples", ya que el pr opio com pilador siem pr e se encar ga de cr ear lo, par a así poder inicializar t odos los cam pos definidos. Ot r a de las car act er íst icas de las est r uct ur as es que no es necesar io cr ear una inst ancia par a poder usar las, ya que es un t ipo por valor y los t ipos por valor no necesit an ser inst anciados par a que exist an. D e finir una e st r uct ur a Las est r uct ur as se definen usando la palabr a St r uct ur e seguida del nom br e y acaba usando las inst r ucciones End St r uct ur e. El siguient e código define una est r uct ur a llam ada Punt o en la que t enem os dos cam pos públicos. Structure Punto Public X As Integer Public Y As Integer End Structure Par a usar la podem os hacer algo com o est o: Dim p As Punto p.X = 100 p.Y = 75 Tam bién podem os usar New al declar ar el obj et o: Dim p As New Punto Aunque en las est r uct ur as, usar New, ser ía algo r edundant e y por t ant o no necesar io. Las est r uct ur as siem pr e se alm acenan en la pila, por t ant o deber íam os t ener la pr ecaución de no cr ear est r uct ur as con m uchos cam pos o con m uchos m iem br os, ya que est o im plicar ía un m ayor consum o del "pr eciado" espacio de la pila. Const r uct or e s de la s e st r uct ur a s Tal y com o hem os com ent ado, las est r uct ur as siem pr e definen un const r uct or sin par ám et r os, est e const r uct or no lo podem os definir nosot r os, es decir , siem pr e exist e y es el que el pr opio com pilador de Visual Basic 2010 define. Por t ant o, si quer em os agr egar algún const r uct or a una est r uct ur a, est e debe t ener par ám et r os y, t al com o ocur r e con cualquier m ét odo o com o ocur r e en las clases, podem os t ener var ias sobr ecar gas de const r uct or es par am et r izados en las est r uct ur as. La for m a de definir esos const r uct or es es com o vim os en las clases: usando dist int as sobr ecar gas de un m ét odo llam ado New, en el caso de las est r uct ur as t am bién podem os usar la palabr a clave Me par a r efer ir nos a la inst ancia act ual. Est o es par t icular m ent e pr áct ico cuando los par ám et r os del const r uct or se llam an de la m ism a for m a que los cam pos declar ados en la est r uct ur a, t al com o ocur r e en el const r uct or m ost r ado en la siguient e definición de la est r uct ur a Punt o. Structure Punto Public X As Integer Public Y As Integer ' Sub New(ByVal x As Integer, ByVal y As Integer) Me.X = x Me.Y = y End Sub End Structure N ot a: Tant o en las est r uct ur as com o en las clases podem os t ener const r uct or es com par t idos, ( Shar ed) , en el caso de las est r uct ur as, est e t ipo de const r uct or es el único que podem os declar ar sin par ám et r os. D e st r uct or e s de la s e st r uct ur a s Debido a que las est r uct ur as son t ipos por valor y por t ant o una var iable declar ada con un t ipo por valor "cont iene el valor en si m ism a", no podem os dest r uir est e t ipo de dat os, lo m ás que conseguir íam os al asignar le un valor nulo ( Not hing) ser ía elim inar el cont enido de la var iable, per o nunca podem os dest r uir ese valor . Por t ant o, en las est r uct ur as no podem os definir dest r uct or es. Los m ie m br os de una e st r uct ur a Com o hem os com ent ado, los m iem br os o elem ent os que podem os definir en una est r uct ur a son los m ism os que ya vim os en las clases. Por t ant o aquí ver em os las difer encias que exist en al usar los en las est r uct ur as. Ca m pos Com o vim os, las var iables declar adas a nivel del t ipo, son los cam pos, la pr incipal difer encia con r espect o a las clases, es que los cam pos de una est r uct ur a no pueden inicialiar se en la declar ación y el valor que t endr án inicialm ent e es un valor "nulo", que en el caso de los cam pos de t ipo num ér icos es un cer o. Por t ant o, si necesit am os que los cam pos t engan algún valor inicial ant es de usar los, deber íam os indicar lo a los usuar ios de nuest r a est r uct ur a y pr oveer un const r uct or que r ealice las inicializaciones cor r espondient es, per o debem os r ecor dar que ese const r uct or debe t ener algún par ám et r o, ya que el pr edet er m inado sin par ám et r os no podem os "r eescr ibir lo". Los únicos cam pos que podem os inicializar al declar ar los son los cam pos com par t idos, per o com o t endr em os opor t unidad de ver , est os cam pos ser án accesibles por cualquier var iable declar ada y cualquier cam bio que r ealicem os en ellos se ver á r eflej ado en el r est o de "inst ancias" de nuest r o t ipo. M é t odos y ot r os e le m e n t os El r est o de los m iem br os de una est r uct ur a se declar an y usan de la m ism a for m a que en las clases, si bien debem os t ener en cuent a que el m odificador de accesibilidad pr edet er m inado par a los m iem br os de una est r uct ur a es Public, ( incluso si son cam pos declar ados con D¡m ) . Ot r o det alle a t ener en cuent a es que en una est r uct ur a siem pr e debe exist ir al m enos un event o o un cam po no com par t ido, no se per m it en est r uct ur as en las que solo t ienen const ant es, m ét odos y/ o pr opiedades, est én o no com par t idos. Cóm o usa r la s e st r uct ur a s Tal com o hem os com ent ado las est r uct ur as son t ipos por valor , par a usar los t ipos por valor no es necesar io inst anciar los explícit am ent e, ya que el m er o hecho de declar ar los indica que est am os cr eando un nuevo obj et o en m em or ia. Por t ant o, a difer encia de las clases o t ipos por r efer encia, cada var iable definida com o un t ipo de est r uct ur a ser á independient e de ot r as var iables declar adas, aunque no las hayam os inst anciado. Est a car act er íst ica de las est r uct ur as nos per m it e hacer copias "r eales" no copia de la r efer encia ( o punt er o) al obj et o en m em or ia com o ocur r e con los t ipos por r efer encia. Veám oslos con un ej em plo. Dim p As New Punto(100, 75) Dim p1 As Punto p1 = p p1.X = 200 ' p.X vale 100 y p1.X vale 200 En est e t r ozo de código definim os e inst anciam os una var iable del t ipo Punt o, a cont inuación declar am os ot r a var iable del m ism o t ipo y le asignam os la pr im er a, si est os t ipos fuesen por r efer encia, t ant o una com o la ot r a est ar ían haciendo r efer encia al m ism o obj et o en m em or ia, y cualquier cam bio r ealizado a cualquier a de las dos var iables afect ar ían al m ism o obj et o, per o en el caso de las est r uct ur as ( y de los t ipos por valor ) , cada cam bio que r ealicem os se har á sobr e un obj et o difer ent e, por t ant o la asignación del valor 2 0 0 al cam po X de la var iable p1 solo afect a a esa var iable, dej ando int act o el valor or iginal de la var iable p. Tal y com o com ent am os ant er ior m ent e, dependiendo de dónde y cóm o est én declar ados los t ipos de dat os y los m iem br os definidos en ellos, t endr em os o no acceso a esos elem ent os. Recor dem os que el ám bit o es el alcance con el que podem os acceder a un elem ent o y depende de dónde est é declar ado, por ot r o lado, la accesibilidad depende de cóm o declar em os cada uno de esos elem ent os. Ám bit o Dependiendo de donde declar em os un m iem br o o un t ipo, ést e t endr á m ayor alcance o cober t ur a, o lo que es lo m ism o, dependiendo del ám bit o en el que usem os un elem ent o, podr em os acceder a él desde ot r os punt os de nuest r o código. A cont inuación ver em os con det alle los ám bit os en los que podem os declar ar los dist int os elem ent os de Visual Basic 2010. Ám bit o de bloque: Disponible únicam ent e en el bloque de código en el que se ha declar ado. Por ej em plo, si declar am os una var iable dent r o de un bucle For o un I f Then, esa var iable solo est ar á accesible dent r o de ese bloque de código. Ám bit o de pr ocedim ient o: Disponible únicam ent e dent r o del pr ocedim ient o en el que se ha declar ado. Cualquier var iable declar ada dent r o de un pr ocedim ient o ( m ét odo o pr opiedad) solo est ar á accesible en ese pr ocedim ient o y en cualquier a de los bloques int er nos a ese pr ocedim ient o. Ám bit o de m ódulo: Disponible en t odo el código del m ódulo, la clase o la est r uct ur a donde se ha declar ado. Las var iables con ám bit o a nivel de m ódulo, t am bién est ar án disponibles en los pr ocedim ient os declar ados en el m ódulo ( clase o est r uct ur a) y por ext ensión a cualquier bloque dent r o de cada pr ocedim ient o. Ám bit o de espacio de nom br es: Disponible en t odo el código del espacio de nom br es. Est e es el nivel m ayor de cober t ur a o alcance, aunque en est e nivel solo podem os declar ar t ipos com o clases, est r uct ur as y enum er aciones, ya que los pr ocedim ient os solam ent e se pueden declar ar dent r o de un t ipo. N ot a: Por r egla gener al, cuando declar am os una var iable en un ám bit o, dicha var iable "ocult ar á" a ot r a que t enga el m ism o nom br e y est é definida en un bloque con m ayor alcance, aunque ver em os que en Visual Basic 2010 exist en cier t as r est r icciones dependiendo de dónde declar em os esas var iables. En Visual Basic 2010 podem os definir una var iable dent r o de un bloque de código, en ese caso dicha var iable solo ser á accesible dent r o de ese bloque. Aunque, com o ver em os a cont inuación, en un pr ocedim ient o solam ent e podr em os definir var iables que no se ocult en ent r e sí, est én o no dent r o de un bloque de código. Ám bit o de bloqu e En los siguient es ej em plos ver em os cóm o podem os definir var iables par a usar solam ent e en el bloque en el que est án definidas. Los bloques de código en los que podem os declar ar var iables son los bucles, ( For , Do, While) , y los bloques condicionales, ( I f, Select ) . Por ej em plo, dent r o de un pr ocedim ient o podem os t ener var ios de est os bloques y por t ant o podem os definir var iables "int er nas" a esos bloques: Dim n As Integer = 3 ' For i As Integer = 1 To 10 Dim j As Integer j += 1 If j < n Then '... End If Next ' If n < 5 Then Dim j As Integer = n * 3 End If ' Do Dim j As Integer For i As Integer = 1 To n j += i Next If j > 10 Then Exit Do Loop La var iable n est ar á disponible en t odo el pr ocedim ient o, por t ant o podem os acceder a ella desde cualquier a de los bloques. En el pr im er bucle For , definim os la var iable i com o la var iable a usar de cont ador , est a var iable solam ent e est ar á accesible dent r o de est e bucle For . Lo m ism o ocur r e con la var iable j . En el pr im er I f definim os ot r a var iable j , per o esa solo ser á accesible dent r o de est e bloque I f y por t ant o no t iene ninguna r elación con la definida en el bucle For ant er ior . En el bucle Do volvem os a definir nuevam ent e una var iable j , a esa var iable la podem os acceder solo desde el pr opio bucle Do y cualquier ot r o bloque de código int er no, com o es el caso del bucle For , en el que nuevam ent e declar am os una var iable llam ada i, que nada t iene que ver con el r est o de var iables declar adas con el m ism o nom br e en los ot r os bloques. Lo único que no podem os hacer en cualquier a de esos bloques, es declar ar una var iable llam ada n, ya que al est ar declar ada en el pr ocedim ient o, el com pilador de Visual Basic 2010 nos indicar á que no podem os ocult ar una var iable pr eviam ent e definida fuer a del bloque, t al com o podem os ver en la figur a 2.12. Figur a 2 .1 2 . Er r or al ocult ar una var iable definida en un pr ocedim ient o Est a r est r icción solo es aplicable a las var iables declar adas en el pr ocedim ient o, ya que si declar am os una var iable a nivel de m ódulo, no habr á ningún pr oblem a par a usar la dent r o de un bloque, est o es así por que en un pr ocedim ient o podem os declar ar var iables que se llam en de la m ism a for m a que las declar adas a nivel de m ódulo, aunque ést as ocult ar án a las del "nivel" super ior . Ám bit o de pr oce dim ie n t o Las var iables declar adas en un pr ocedim ient o t endr án un ám bit o o cober t ur a que ser á el pr ocedim ient o en el que est á declar adas, y com o hem os vist o, ese ám bit o incluye t am bién cualquier bloque de código declar ado dent r o del pr ocedim ient o. Est as var iables ocult ar án a las que se hayan declar ado fuer a del pr ocedim ient o, si bien, dependiendo del t ipo de m ódulo, podr em os acceder a esas var iables "ext er nas" indicando el nom br e com plet o del m ódulo o bien usando la inst r ucción Me, t al com o vim os en el código del const r uct or par am et r izado de la est r uct ur a Punt o. Per o m ej or veám oslo con un ej em plo. En el siguient e código, definim os una clase en la que t enem os un cam po llam ado N om br e, t am bién definim os un m ét odo en el que int er nam ent e se ut iliza una var iable llam ada nom br e, par a acceder a la var iable declar ada en la clase, t endr em os que usar la inst r ucción o palabr a clave Me. Public Class Cliente Public Nombre As String = "Juan" Function Mostrar() As String Dim nombre As String = "Pepita" Return "Externo= " & Me.Nombre & ", interno= " & nombre End Function End Class En est e ej em plo, el hecho de que una var iable est é declar ada con la let r a EN E en m ayúscula o en m inúscula no im plica ninguna difer encia, ya que Visual Basic 2010 no hace dist inciones de est e t ipo; aún así, Visual Basic 2010 r espet ar á el nom br e según lo hem os escr it o y no cam biar á aut om át icam ent e el "case" de las var iables, salvo cuando est án en el m ism o nivel de ám bit o, es decir , si la var iable nom br e que hem os definido en la función M ost r ar la volvem os a usar dent r o de esa función, Visual Basic 2010 la seguir á escr ibiendo en m inúsculas, per o si escr ibim os "nom br e" fuer a de esa función, VB se dar á cuent a de que hay una var iable declar ada con la ENE en m ayúsculas y aut om át icam ent e la cam biar á a N om br e, aunque nosot r os la escr ibam os de ot r a for m a. Ám bit o de m ódu lo Cuando hablam os de m ódulos, nos est am os r efir iendo a un "t ipo" de dat os, ya sea una clase, una est r uct ur a o cualquier ot r o t ipo de dat os que nos per m it a definir .NET. En est os casos, las var iables declar adas dent r o de un t ipo de dat os ser án visibles desde cualquier par t e de ese t ipo, siem pr e t eniendo en cuent a las r est r icciones m encionadas en los casos ant er ior es. Ám bit o de e spa cio de n om br e s Los espacios de nom br es son los cont enedor es de t ipos de dat os de m ayor nivel, y sir ven par a cont ener definiciones de clases, est r uct ur as, enum er aciones y delegados. Cualquier t ipo definido a nivel de espacio de nom br es est ar á disponible par a cualquier ot r o elem ent o definido en el m ism o espacio de nom br es. Al igual que ocur r e en el r est o de ám bit os "infer ior es", si definim os un t ipo en un espacio de nom br es, podem os usar ese m ism o nom br e par a nom br ar a un pr ocedim ient o o a una var iable, en cada caso se aplicar á el ám bit o cor r espondient e y, t al com o vim os ant er ior m ent e, t endr em os que usar nom br es únicos par a poder acceder a los nom br es definidos en niveles difer ent es. La pa la br a cla v e Globa l En Visual Basic 2010 podem os definir espacios de nom br es cuyos nom br es sean los m ism os que los definidos en el pr opio .NET Fr am ewor k, par a evit ar conflict os de ám bit os, podem os usar la palabr a clave Global par a acceder a los que se han definido de for m a "global" en .NET. Por ej em plo, si t enem os el siguient e código en el que definim os una clase dent r o de un espacio de nom br es llam ado Sy st em y quer em os acceder a uno de los t ipos definidos en el espacio de nom br es Syst em de .NET, t endr em os un pr oblem a: Namespace System Class Cliente Public Nombre As String Public Edad As System.Int32 End Class End Namespace El pr oblem a es que el com pilador de Visual Basic 2010 nos indicar á que el t ipo I nt 32 no est á definido, ya que int ent ar á buscar lo dent r o del ám bit o que act ualm ent e t iene, es decir , la declar ación que nosot r os hem os hecho de Syst em , por t ant o par a poder acceder al t ipo I nt 32 definido en el espacio de nom br es "global" Syst em de .NET t endr em os que usar la inst r ucción Global, por suer t e el I DE de Visual St udio 2010 r econoce est e t ipo de er r or y nos ofr ece ayu da par a poder solvent ar el conflict o, t al com o vem os en la figur a 2.13: Figur a 2 .1 3 . Ayuda del I D E en los conflict os de espacios nom br es globales N ot a: Afor t unadam ent e est e conflict o con los espacios de nom br es no ser á m uy habit ual par a los desar r ollador es que usem os el idiom a de Cer vant es, por la sencilla r azón de que los espacios de nom br es de .NET Fr am ewor k suelen est ar definidos usando palabr as en inglés. Acce sibilida d La accesibilidad es la car act er íst ica que podem os aplicar a cualquier a de los elem ent os que definam os en nuest r o código. Dependiendo de la accesibilidad declar ada t endr em os dist int os t ipos de accesos a esos elem ent os. Los m odificador es de accesibilidad que podem os aplicar a los t ipos y elem ent os definidos en nuest r o código pueden ser cualquier a de los m ost r ados en la siguient e list a: Public: Acceso no r est r ingido. Est e es m odificador de accesibilidad con m ayor "cober t ur a", podem os acceder a cualquier m iem br o público desde cualquier par t e de nuest r o código. Aunque, com o ver em os, est e acceso no r est r ingido puede ver se r educido dependiendo de dónde lo usem os. Pr ot ect ed: Acceso lim it ado a la clase cont enedor a o a los t ipos der ivados de est a clase. Est e m odificador solam ent e se usa con clases que se der iven de ot r as. Fr iend: Acceso lim it ado al pr oyect o act ual. Visual Basic 2010 aplica est e m odificador de for m a pr edet er m inada a los pr ocedim ient os declar ados en las clases. Pr ot ect ed Fr iend: Acceso lim it ado al pr oyect o act ual o a los t ipos der ivados de la clase cont enedor a. Una m ezcla de los dos m odificador es ant er ior es. Pr ivat e: Acceso lim it ado al t ipo cont enedor . Es el m ás r est r ict ivos de t odos los m odificador es de accesibilidad y en el caso de los cam pos declar ados en las clases ( Class) equivale a usar Dim . Est os m odificador es de accesibilidad los podem os usar t ant o en clases, est r uct ur as, int er faces, enum er aciones, delegados, event os, m ét odos, pr opiedades y cam pos. Aunque no ser án aplicables en espacios de nom br es ( Nam espace) ni clases de t ipo Module, en est os dos casos siem pr e t endr án cober t ur a pública, si bien no se per m it e el uso de ningún m odificador . Acce sibilida d de la s va r ia ble s e n los pr oce dim ie n t os Las var iables declar adas dent r o de un pr ocedim ient o solo son accesibles dent r o de ese pr ocedim ient o, en est e caso solo se puede aplicar el ám bit o pr ivado, aunque no podr em os usar la inst r ucción Pr ivat e, sino Dim o St at ic. N ot a: La palabr a clave St at ic, nos per m it e definir una var iable pr ivada ( o local) al pr ocedim ient o par a que m ant enga el valor ent r e difer ent es llam adas a ese pr ocedim ient o; est o cont r ast a con el r est o de var iables declar adas en un pr ocedim ient o cuya dur ación es la m ism a que la vida del pr opio pr ocedim ient o, por t ant o, las var iables no est át icas pier den el valor al t er m inar la ej ecución del pr ocedim ient o. La s a cce sibilida de s pr e de t e r m in a da s La accesibilidad de una var iable o pr ocedim ient o en la que no hem os indicado el m odificador de accesibilidad depender á del sit io en el que la hem os declar ado. Por ej em plo, en las est r uct ur as si definim os los cam pos usando Dim , est os t endr án un ám bit o igual que si le hubiésem os aplicado el m odificador Public; sin em bar go, esa m ism a var iable declar ada en una clase ( Class o Module) t endr á una accesibilidad Pr ivat e. Así m ism o, si el elem ent o que declar am os es un pr ocedim ient o y no indicam os el m odificador de ám bit o, ést e t endr á un ám bit o de t ipo Public si lo definim os en una est r uct ur a y si el lugar en el que lo declar am os es una clase ( o Module) , ést e ser á Fr iend. En la siguient e t abla t enem os la accesibilidad pr edet er m inada de cada t ipo ( clase, est r uct ur a, et c.) , así com o de las var iables declar adas con Dim y de los pr ocedim ient os en los que no se indican el m odificador de accesibilidad. Tipo del t ipo de las var iables de los Class Module St r uct ur e Enum Fr iend Fr iend Fr iend Public Fr iend I nt er face Fr iend declar adas con D im Pr ivat e Pr ivat e Public N.A. ( los m iem br os siem pr e son públicos) N.A. ( no se pueden declar ar var iables) pr ocedim ient os Fr iend Fr iend Public N.A. Public ( no se per m it e indicar lo) Tabla 2 .3 . La accesibilidad pr edet er m inada de los t ipos Tal com o podem os ver en la t abla 2.3, la accesibilidad pr edet er m inada, ( la que t ienen cuando no se indica expr esam ent e con un m odificador ) , de t odos los t ipos es Fr iend, es decir , accesible a t odo el pr oyect o, aunque en el caso de las enum er aciones el m odificador depende de dónde se declar e dicha enum er ación, si est á declar ada a nivel de espacio de nom br es ser á Fr iend, en el r est o de los casos ser á Public. En la t er cer a colum na t enem os la accesibilidad pr edet er m inada cuando declar am os las var iables con Dim , aunque en las int er faces y en las enum er aciones no se per m it en declar ar var iables. La últ im a colum na es la cor r espondient e a los pr ocedim ient os, en el caso de las int er faces no se puede aplicar ningún m odificador de accesibilidad y de for m a pr edet er m inada son públicos. En est a ot r a t abla t enem os la accesibilidad per m it ida en cada t ipo así com o las que podem os indicar en los m iem br os de esos t ipos. Tipo Class Module St r uct ur e Enum I nt er face del t ipo Public Fr iend Pr ivat e Pr ot ect ed Pr ot ect ed Fr iend Public Fr iend Public Fr iend Pr ivat e Public Fr iend Pr ivat e Public Fr iend Pr ivat e Pr ot ect ed Pr ot ect ed Fr iend de los m iem br os Public Fr iend Pr ivat e Pr ot ect ed Pr ot ect ed Fr iend Public Fr iend Pr ivat e Public Fr iend Pr ivat e N.A. N.A. Siem pr e son públicos Tabla 2 .4 . Accesibilidades per m it idas en los t ipos Algunos de los m odificador es que podem os indicar en los t ipos dependen de dónde declar em os esos t ipos, por ej em plo, t an solo podr em os indicar el m odificador pr ivado de las enum er aciones cuando est as se declar en dent r o de un t ipo. En el caso de las clases e int er faces, los m odificador es Pr ot ect ed y Pr ot ect ed Fr iend solo podr em os aplicar los cuando est án declar adas dent r o de una clase ( Class) . Anida ción de t ipos Tal com o hem os com ent ado en el pár r afo ant er ior , podem os declar ar t ipos dent r o de ot r os t ipos, por t ant o el ám bit o y accesibilidad de esos t ipos dependen del ám bit o y accesibilidad del t ipo que los cont iene. Por ej em plo, si declar am os una clase con acceso Fr iend, cualquier t ipo que est a clase cont enga siem pr e est ar á supedit ado al ám bit o de esa clase, por t ant o si declar am os ot r o t ipo int er no, aunque lo declar em os com o Public, nunca est ar á m ás accesible que la clase cont enedor a, aunque en est os casos no habr á ningún t ipo de confusión, ya que par a acceder a los t ipos declar ados dent r o de ot r os t ipos siem pr e t endr em os que indicar la clase que los cont iene. En el siguient e código podem os ver cóm o declar ar dos clases "anidadas". Tal com o podem os com pr obar , par a acceder a la clase Salar io debem os indicar la clase Client e, ya que la única for m a de acceder a una clase anidada es m ediant e la clase cont enedor a. Friend Class Cliente Public Nombre As String Public Class Salario Public Importe As Decimal End Class End Class ' Para usar la clase Salario debemos declararla de esta forma: Dim s As New Cliente.Salario s.Importe = 2200 Los t ipos a n ida ble s Cualquier a de los t ipos m ost r ados en la t abla 2.4, except o las enum er aciones, pueden cont ener a su vez ot r os t ipos. La excepción es el t ipo Module que aunque puede cont ener a ot r os t ipos, no puede usar se com o t ipo anidado. Una enum er ación siem pr e puede usar se com o t ipo anidado. N ot a: Los espacios de nom br es t am bién pueden anidar se y cont ener a su vez cualquier a de los t ipos m ost r ados en la t abla 2.4, incluso t ipos Module. El n om br e com ple t o de u n t ipo Tal com o hem os vist o, al poder declar ar t ipos dent r o de ot r os t ipos y est os a su vez pueden est ar definidos en espacios de nom br es, podem os decir que el nom br e "com plet o" de un t ipo cualquier a est ar á for m ado por el/ los espacios de nom br es y el/ los t ipos que los cont iene, por ej em plo si la clase Client e definida ant er ior m ent e est á a su vez dent r o del espacio de nom br es Am bit os, el nom br e com plet o ser á: Am bit os.Client e y el nom br e com plet o de la clase Salar io ser á: Am bit os.Client e.Salar io. Aunque par a acceder a la clase Client e no es necesar io indicar el espacio de nom br es, al m enos si la quer em os usar desde cualquier ot r o t ipo declar ado dent r o de ese espacio de nom br es, per o si nuest r a int ención es usar la desde ot r o espacio de nom br e ext er no a Am bit os, en ese caso si que t endr em os que usar el nom br e com plet o. Por ej em plo, en el siguient e código t enem os dos espacios de nom br es que no est án anidados, cada uno de ellos declar a una clase y desde una de ellas quer em os acceder a la ot r a clase, par a poder hacer lo debem os indicar el nom br e com plet o, ya que en caso cont r ar io, el com pilador de Visual Basic 2010 ser ía incapaz de saber a que clase quer em os acceder . Namespace Uno Public Class Clase1 Public Nombre As String End Class End Namespace Namespace Dos Public Class Clase2 Public Nombre As String Sub Main() Dim c1 As New Uno.Clase1 c1.Nombre = "Pepe" End Sub End Class End Namespace Est o m ism o lo podem os aplicar en el caso de que t engam os dos clases con el m ism o nom br e en espacios de nom br es dist int os. N ot a: En el m ism o pr oyect o podem os t ener m ás de una declar ación de un espacio de nom br es con el m ism o nom br e, en est os casos el com pilador lo t om ar á com o si t odas las clases definidas est uvier an dent r o del m ism o espacio de nom br es, aunque est os est én definidos en ficher os difer ent es. I m por t a ción de e spa cios de n om br e s Tal com o hem os com ent ado, los espacios de nom br es pueden cont ener ot r os espacios de nom br es y est os a su vez t am bién pueden cont ener ot r os espacios de nom br es o clases, y com o hem os vist o, par a poder acceder a una clase que no est é dent r o del m ism o espacio de nom br es debem os indicar el "nom br e com plet o". Par a evit ar est ar escr ibiendo t odos los espacios de nom br es en los que est á la clase que nos int er esa declar ar , podem os usar una especie de acceso dir ect o o par a que lo ent endam os m ej or , podem os cr ear una especie de "Pat h", de for m a que al declar ar una var iable, si est a no est á definida en el espacio de nom br es act ual, el com pilador busque en t odos los espacios de nom br es incluidos en esas r ut as ( pat hs) . Est o lo conseguim os usando la inst r ucción I m por t s seguida del espacio de nom br es que quer em os im por t ar o incluir en el pat h de los espacios de nom br es. Podem os usar t ant as im por t aciones de espacios de nom br es com o necesit em os y est as siem pr e deben apar ecer al pr incipio del ficher o, j ust o después de las inst r ucciones Opt ions. Por ej em plo, si t enem os el código ant er ior y hacem os la im por t ación del espacio de nom br es en el que est á definida la clase Clase1 : Imports Uno podr em os acceder a esa clase de cualquier a de est as dos for m as: Dim c1 As New Uno.Clase1 Dim c1 As New Clase1 Alia s de e spa cios de n om br e s Si hacem os dem asiadas im por t aciones de nom br es, el pr oblem a con el que nos podem os encont r ar es que el I nt elliSense de Visual Basic 2010 no sea de gr an ayuda, ya que m ost r ar á una gr an cant idad de clases, y segur am ent e nos r esult ar á m ás difícil encont r ar la clase a la que quer em os acceder , o t am bién podem os encont r ar nos en ocasiones en las que nos int er ese usar un nom br e cor t o par a acceder a las clases cont enidas en un espacio de nom br es, por ej em plo, si quer em os indicar de for m a explícit a las clases de un espacio de nom br es com o el de Micr osoft .VisualBasic, podem os hacer lo de est a for m a: Imports vb = Microsoft.VisualBasic De est a for m a podem os usar el "alias" vb par a acceder a las clases y dem ás t ipos definidos en ese espacio de nom br es. En las figur as 2.14 2.15 podem os ver las dos for m as de acceder a las clases del espacio de ese espacio de nom br es, en el pr im er caso sin usar un alias y en el segundo usando el alias vb. Figur a 2 .1 4 . Los m iem br os de un espacio de nom br es usando el nom br e com plet o Figur a 2 .1 5 . Acceder a los m iem br os de un espacio de nom br es usando un alias Las pr opiedades son los m iem br os de los t ipos que nos per m it en acceder a los dat os que dicho t ipo m anipula. Nor m alm ent e una pr opiedad est á r elacionada con un cam po, de for m a que el cam po sea el que r ealm ent e cont enga el valor y la pr opiedad sim plem ent e sea una especie de m ét odo a t r avés del cual podem os acceder a ese valor . Debido a que el uso de las pr opiedades r ealm ent e nos per m it e acceder a los valor es de una clase ( o t ipo) , se suelen confundir los cam pos con las pr opiedades, de hecho si definim os una var iable pública en una clase, ést a se com por t a de m aner a sim ilar , per o r ealm ent e un cam po ( o var iable) público no es una pr opiedad, al m enos en el sent ido de que el pr opio .NET Fr am ewor k no lo int er pr et a com o t al, aunque en la pr áct ica nos puede par ecer que es así, ya que se ut ilizan de la m ism a for m a. Per o no debem os dej ar nos llevar por la com odidad y si no quer em os per der funcionalidad, debem os difer enciar en nuest r o código las pr opiedades de los cam pos. Lo pr im er o que debem os t ener pr esent e es que gr acias a est a difer enciación que hace .NET Fr am ewor k, podem os poner en pr áct ica una de las car act er íst icas de la pr ogr am ación or ient ada a obj et os: la encapsulación, de for m a, que la m anipulación de los dat os que una clase cont iene siem pr e se deben hacer de for m a "int er na" o pr ivada a la clase, dej ando a las pr opiedades la posibilidad de que ext er nam ent e se m anipulen, de for m a cont r olada, esos dat os. De est a for m a t endr em os m ayor cont r ol sobr e cóm o se acceden o se asignan los valor es a esos dat os, ya que al definir una pr opiedad, t al com o hem os com ent ado, r ealm ent e est am os definiendo un pr ocedim ient o con el cual podem os cont r olar cóm o se acceden a esos dat os. D e finir una pr opie da d Debido a que una pr opiedad r ealm ent e nos per m it e acceder a un dat o que la clase ( o est r uct ur a) m anipula, siem pr e t endr em os un cam po r elacionado con una pr opiedad. El cam po ser á el que cont enga el valor y la pr opiedad ser á la que nos per m it a m anipular ese valor . En Visual Basic 2010, las pr opiedades las declar am os usando la inst r ucción Pr oper t y y la definición de la m ism a t er m ina con End Pr oper t y, dent r o de ese bloque de código t enem os que definir ot r os dos bloques: uno se usar á a la hor a de leer el valor de la pr opiedad ( bloque Get ) , y el ot r o cuando quer em os asignar un valor a la pr opiedad ( bloque Set ) . El bloque que nos per m it e acceder al valor de la pr opiedad est ar á indicado por la inst r ucción Get y acaba con End Get , por ot r a par t e, el bloque usado par a asignar un valor a la pr opiedad se define m ediant e la inst r ucción Set y acaba con End Set . Veam os com o definir una pr opiedad en Visual Basic 2010: Public Class Cliente Private _nombre As String Public Property Nombre() As String Get Return _nombre End Get Set(ByVal value As String) _nombre = value End Set End Property End Class Com o podem os com pr obar t enem os dos bloques de código, el bloque Get que es el que se usa cuando quer em os acceder al valor de la pr opiedad, por t ant o devolvem os el valor del cam po pr ivado usado par a alm acenar ese dat o. El bloque Set es el usado cuando asignam os un valor a la pr opiedad, est e bloque t iene definido un par ám et r o ( value) que r epr esent a al valor que quer em os asignar a la pr opiedad. Pr opie da de s de solo le ct ur a En Visual Basic 2010 podem os hacer que una pr opiedad sea de solo lect ur a, de for m a que el valor que r epr esent a no pueda ser cam biado. Par a definir est e t ipo de pr opiedades solo debem os indicar el bloque Get de la pr opiedad, adem ás de indicar de for m a expr esa que esa es nuest r a int ención, par a ello debem os usar el m odificador ReadOnly par a que el com pilador de Visual Basic 2010 acept e la declar ación: Public ReadOnly Property Hoy() As Date Get Return Date.Now End Get End Property Pr opie da de s de solo e scr it ur a De igual for m a, si quer em os definir una pr opiedad que sea de solo escr it ur a, solo definir em os el bloque Set , per o al igual que ocur r e con las pr opiedades de solo lect ur a, debem os indicar expr esam ent e que esa es nuest r a int ención, par a ello usar em os la palabr a clave Wr it eOnly : Public WriteOnly Property Password() As String Set(ByVal value As String) If value = "blablabla" Then ' ok End If End Set End Property D ife r e nt e a cce sibilida d pa r a los bloque s Ge t y Se t En las pr opiedades nor m ales ( de lect ur a y escr it ur a) , podem os definir difer ent es niveles de accesibilidad a cada uno de los dos bloques que for m an una pr opiedad. Por ej em plo, podr íam os definir el bloque Get com o público, ( siem pr e accesible) , y el bloque Set com o Pr ivat e, de for m a que solo se puedan r ealizar asignaciones desde dent r o de la pr opia clase. Por ej em plo, el salar io de un em pleado podr íam os declar ar lo par a que desde cualquier punt o se pueda saber el im por t e, per o la asignación de dicho im por t e solo est ar á accesible par a los pr ocedim ient os definidos en la pr opia clase: Public Class Empleado Private _salario As Decimal Public Property Salario() As Decimal Get Return _salario End Get Private Set(ByVal value As Decimal) _salario = value End Set End Property End Class Par a hacer que el bloque Set sea pr ivado, lo indicam os con el m odificador de accesibilidad Pr ivat e, al no indicar ningún m odificador en el bloque Get , ést e ser á el m ism o que el de la pr opiedad. N ot a: El nivel de accesibilidad de los bloques Get o Set debe ser igual o infer ior que el de la pr opiedad, por t ant o si la pr opiedad la declar am os com o Pr ivat e, no podem os definir com o público los bloques Get o Set . Pr opie da de s pr e de t e r m ina da s Las pr opiedades pr edet er m inadas son aquellas en las que no hay que indicar el nom br e de la pr opiedad par a poder acceder a ellas, per o en Visual Basic 2010 no podem os definir com o pr edet er m inada cualquier pr opiedad, ya que debido a com o se r ealizan las asignaciones de obj et os en .NET, siem pr e debem os indicar la pr opiedad a la que quer em os asignar el valor , por que en caso de que no se indique ninguna, el com pilador int er pr et ar á que lo que quer em os asignar es un obj et o y no un valor a una pr opiedad. Par a evit ar conflict os o t ener que usar alguna inst r ucción "ext r a" par a que se sepa si lo que quer em os asignar es un valor o un obj et o, en Visual Basic 2010 las pr opiedades pr edet er m inadas siem pr e deben ser par am et r izadas, es decir , t ener com o m ínim o un par ám et r o. Par a indicar que una pr opiedad es la pr opiedad por defect o lo debem os hacer usando la inst r ucción Default : Default Public ReadOnly Property Item(ByVal index As Integer) As Empleado Get ' ... End Get End Property Com o vem os en est e ej em plo, una pr opiedad por defect o puede ser de solo lect ur a y t am bién de solo escr it ur a o de lect ur a/ escr it ur a. Par a usar est a pr opiedad, al ser la pr opiedad por defect o, no es necesar io indicar el nom br e de la pr opiedad, aunque si así lo deseam os podem os indicar la, aunque en est e caso no t endr ía m ucha ut ilidad el haber la definido com o pr opiedad por defect o: Dim e As New Empleado Dim e1 As Empleado = e(2) ' También podemos usarla indicando el nombre de la propiedad: Dim e2 As Empleado = e.Item(2) Sobr e ca r ga de pr opie da de s pr e de t e r m in a da s Debido a que las pr opiedades pr edet er m inadas de Visual Basic 2010 deben r ecibir un par ám et r o, podem os cr ear sobr ecar gas de una pr opiedad pr edet er m inada, aunque debem os r ecor dar que par a que esa sobr ecar ga pueda ser posible, el t ipo o núm er o de ar gum ent os deben ser dist int os ent r e las dist int as sobr ecar gas, por ej em plo podr íam os t ener una sobr ecar ga que r eciba un par ám et r o de t ipo ent er o y ot r a que lo r eciba de t ipo cadena: Default Public ReadOnly Property Item(ByVal index As Integer) As Empleado Get ' ... End Get End Property Default Public Property Item(ByVal index As String) As Empleado Get ' ... End Get Set(ByVal value As Empleado) ' End Set End Property I ncluso com o vem os en est e código una de las sobr ecar gas puede ser de solo lect ur a y la ot r a de lect ur a/ escr it ur a. Lo que r ealm ent e im por t a es que el núm er o o t ipo de par ám et r os de cada sobr ecar ga sea difer ent e. Las pr opiedades pr edet er m inadas t ienen sent ido en Visual Basic 2010 cuando quer em os que su uso sea par ecido al de un ar r ay. Por t ant o es habit ual que las clases de t ipo colección sean las m ás indicadas par a definir pr opiedades por defect o. Aunque no siem pr e el valor devuelt o debe ser un elem ent o de una colección o ar r ay, ya que podem os usar las pr opiedades pr edet er m inadas par a acceder a los m iem br os de una clase "nor m al", de for m a que se devuelva un valor según el par ám et r o indicado, est o nos per m it ir ía, por ej em plo, acceder a los m iem br os de la clase desde un bucle For . Si definim os una pr opiedad pr edet er m inada com o en el siguient e código: Public Class Articulo Public Descripción As String Public PrecioVenta As Decimal Public Existencias As Decimal Default Public ReadOnly Property Item(ByVal index As Integer) As String Get Select Case index Case 0 Return Descripción Case 1 Return PrecioVenta.ToString Case 2 Return Existencias.ToString Case Else Return "" End Select End Get End Property End Class La podem os usar de est a for m a: For i As Integer = 0 To 2 Console.WriteLine( art(i) ) Next Resum iendo: Las pr opiedades pr edet er m inadas en Visual Basic 2010 siem pr e deben t ener un par ám et r o, par a que su uso se asem ej e a un ar r ay, es decir , se use com o indizador de la clase. Por convención, cuando se usan com o indizador , el nom br e de la pr opiedad pr edet er m inada suele ser I t em . Las int er faces son un elem ent o bast ant e im por t ant e en .NET Fr am ewor k, ya que de hecho se ut iliza con bast ant e fr ecuencia, en est a lección ver em os que son las int er faces y com o ut ilizar las en nuest r os pr oyect os, t am bién ver em os que papel j uegan en .NET y cóm o aplicar algunas de las definidas en la bibliot eca base. ¿Qué e s una int e r fa z? Las int er faces son una for m a especial de una clase, aunque la difer encia pr incipal con las clases es que las int er faces no cont ienen código ej ecut able, solo definen los m iem br os. Las int er faces se ut ilizan par a indicar el "com por t am ient o" que t endr á una clase, o al m enos qué m iem br os debe definir esa clase. Par a definir una int er faz en Visual Basic 2010 t enem os que usar la inst r ucción I nt er face seguida del nom br e de la int er faz y t er m inar la declar ación con End I nt er face: Public Interface IAnimal '... End Interface N ot a: Según las indicaciones de nom enclat ur a de .NET Fr am ewor k, se r ecom ienda que t odas las int er faces em piecen con una I m ayúscula seguida del nom br e al que hacer r efer encia la int er faz. ¿Qué cont ie ne una int e r fa z? Al pr incipio de est a lección hem os com ent ado que las int er faces no cont ienen código, solo define los m iem br os que cont iene. Esa definición la har em os com o cualquier ot r a, con la difer encia de que no incluim os ningún código, solo la "fir m a" o el pr ot ot ipo de cada uno de esos m iem br os. En el siguient e código definim os una int er faz que cont iene los cuat r os t ipos de m iem br os t ípicos de cualquier clase: Public Interface IPrueba Sub Mostrar() Function Saludo(ByVal nombre As String) As String Property Nombre() As String Event DatosCambiados() End Interface El pr im er m iem br o de est a int er faz, es un m ét odo de t ipo Sub que no r ecibe par ám et r os. El siguient e m ét odo es una función que devuelve un valor de t ipo St r ing y r ecibe un par ám et r o t am bién de t ipo cadena. A cont inuación definim os una pr opiedad que devuelve una cadena. Por últ im o, definim os un event o. Com o podem os obser var , lo único que t enem os que hacer es indicar el t ipo de m iem br o y si r ecibe o no algún par ám et r o o ar gum ent o. Dos cosas im por t ant es sobr e las int er faces: 1- No se pueden definir cam pos. 2- Los m iem br os de las int er faces siem pr e son públicos, t al com o indicábam os en la t abla 2.3. Una int e r fa z e s un cont r a t o Siem pr e que leem os sobr e las int er faces, lo pr im er o con lo que nos solem os encont r ar es que una int er faz es un cont r at o. Veam os que nos quier en decir con esa fr ase. Tal com o acabam os de ver , las int er faces solo definen los m iem br os, per o no el código a usar en cada uno de ellos, est o es así pr ecisam ent e por que el papel que j uegan las int er faces es el de solo indicar que es lo que una clase o est r uct ur a puede, o m ej or dicho, debe im plem ent ar . Si en una clase indicam os que quer em os "im plem ent ar " una int er faz, esa clase debe definir cada uno de los m iem br os que la int er faz expone. De est a for m a nos asegur am os de que si una clase im plem ent a una int er faz, t am bién im plem ent a t odos los m iem br os definidos en dicha int er faz. Cuando una clase im plem ent a una int er faz est á fir m ando un cont r at o con el que se com pr om et e a definir t odos los m iem br os que la clase define, de hecho el pr opio com pilador nos obliga a hacer lo. La s int e r fa ce s y e l polim or fism o Com o com ent am os ant er ior m ent e, el polim or fism o es una car act er íst ica que nos per m it e acceder a los m iem br os de un obj et o sin necesidad de t ener un conocim ient o exact o de ese obj et o ( o de la clase a par t ir del que se ha inst anciado) , lo único que t enem os que saber es que ese obj et o t iene cier t os m ét odos ( u ot r os m iem br os) a los que podem os acceder . Tam bién hem os com ent ado que las int er faces r epr esent an un cont r at o ent r e las clases que las im plem ent an, por t ant o las int er faces pueden ser , ( de hecho lo son) , un m edio par a poner en pr áct ica est a car act er íst ica de la pr ogr am ación or ient ada a obj et os. Si una clase im plem ent a una int er faz, esa clase t iene t odos los m iem br os de la int er faz, por t ant o podem os acceder a esa clase, que en pr incipio pude ser nos desconocida, desde un obj et o del m ism o t ipo que la int er faz. Usa r una int e r fa z e n una cla se Par a poder ut ilizar una int er faz en una clase, o dicho de ot r a for m a: par a "im plem ent ar " los m iem br os expuest os por una int er faz en una clase debem os hacer lo m ediant e la inst r ucción I m plem ent s seguida del nom br e de la int er faz: Public Class Prueba Implements IPrueba Y com o com ent ábam os, cualquier clase que im plem ent e una int er faz debe definir cada uno de los m iem br os de esa int er faz, por eso es el pr opio Visual Basic el encar gado de cr ear aut om át icam ent e los m ét odos y pr opiedades que la int er faz im plem ent a, aunque solo inser t a el "pr ot ot ipo" de cada uno de esos m iem br os, dej ando par a nosot r os el t r abaj o de escr ibir el código. Usando la definición de la int er faz I Pr ueba que vim os ant es, el código que añadir á VB ser á el siguient e: Public Class Prueba Implements IPrueba Public Event DatosCambiados() Implements IPrueba.DatosCambiados Public Sub Mostrar() Implements IPrueba.Mostrar End Sub Public Property Nombre() As String Implements IPrueba.Nombre Get End Get Set(ByVal value As String) End Set End Property Public Function Saludo(ByVal nombre As String) As String _ Implements IPrueba.Saludo End Function End Class Com o podem os apr eciar , no solo ha añadido las definiciones de cada m iem br o de la int er faz, sino que t am bién añade código ext r a a cada uno de esos m iem br os: la inst r ucción I m plem ent s seguida del nom br e de la int er faz y el m iem br o al que se har á r efer encia. La ut ilidad de que en cada uno de los m iem br os se indique expr esam ent e el m ét odo al que se hace r efer encia, es que podem os usar nom br es difer ent es al indicado en la int er faz. Por ej em plo, si im plem ent am os est a int er faz en una clase que solo ut ilizar á la im pr esor a, al m ét odo M ost r ar lo podr íam os llam ar I m pr im ir que ser ía m ás adecuado, en ese caso sim plem ent e cam biam os el nom br e del m ét odo de la clase par a que im plem ent e el m ét odo M ost r ar de la int er faz: Public Sub Imprimir() Implements IPrueba.Mostrar End Sub De est a for m a, aunque en la clase se llam e de for m a difer ent e, r ealm ent e hace r efer encia al m ét odo de la int er faz. Acce de r a los m ie m br os im ple m e nt a dos Una vez que t enem os im plem ent ada una int er faz en nuest r a clase, podem os acceder a esos m iem br os de for m a dir ect a, es decir , usando un obj et o cr eado a par t ir de la clase: Dim prueba1 As New Prueba prueba1.Mostrar() O bien de for m a indir ect a, por m edio de una var iable del m ism o t ipo que la int er faz: Dim prueba1 As New Prueba Dim interfaz1 As IPrueba interfaz1 = prueba1 interfaz1.Mostrar() ¿Qué ha ocur r e aquí? Com o ya com ent am os ant er ior m ent e, cuando asign am os var iables por r efer encia, r ealm ent e lo que asignam os son r efer encias a los obj et os cr eados en la m em or ia, por t ant o la var iable int er faz1 est á haciendo r efer encia al m ism o obj et o que pr ueba1 , aunque esa var iable solo t endr á acceso a los m iem br os de la clase Pr ueba que conoce, es decir , los m iem br os definidos en I Pr ueba. Si la clase define ot r os m iem br os que no est án en la int er faz, la var iable int er faz1 no podr á acceder a ellos. Sa be r si un obj e t o im ple m e nt a una int e r fa z Si las int er faces sir ven par a acceder de for m a anónim a a los m ét odos de un obj et o, es nor m al que en Visual Basic t engam os algún m ecanism o par a descubr ir si un obj et o im plem ent a una int er faz. Par a r ealizar est a com pr obación podem os usar en una expr esión I f/ Then la inst r ucción TypeOf... I s, de for m a que si la var iable indicada después de TypeOf cont iene el t ipo especificado después de I s, la condición se cum ple: If TypeOf prueba1 Is IPrueba Then interfaz1 = prueba1 interfaz1.Mostrar() End If De est a for m a nos asegur am os de que el código se ej ecut ar á solam ent e si la var iable pr ueba1 cont iene una definición de la int er faz I Pr ueba. I m ple m e nt a ción de m últ iple s int e r fa ce s En Visual Basic 2010, una m ism a clase puede im plem ent ar m ás de una int er faz. Par a indicar que im plem ent am os m ás de una int er faz podem os hacer lo de dos for m as: 1- Usando nuevam ent e la inst r ucción I m plem ent s seguida del nom br e de la int er faz: Public Class Prueba Implements IPrueba Implements IComparable 2- I ndicando las ot r as int er faces en la m ism a inst r ucción I m plem ent s, per o separ ándolas con com as: Public Class Prueba Implements IPrueba, IComparable De cualquier a de las dos for m as es válido im plem ent ar m ás de una int er faz, aunque en am bos casos siem pr e debem os definir los m iem br os de cada una de esas int er faces. M últ iple im ple m e nt a ción de un m ism o m ie m br o Com o acabam os de com pr obar , una m ism a clase puede im plem ent ar m ás de una int er faz, y est o nos puede causar una duda: ¿Qué ocur r e si dos int er faces definen un m ét odo que es idént ico en am bas? En pr incipio, no habr ía pr oblem as, ya que el pr opio Visual Basic cr ear ía dos m ét odos con nom br es difer ent es y a cada uno le asignar ía la im plem ent ación de ese m ét odo definido en cada int er faz. Por ej em plo, si t enem os ot r a int er faz que define el m ét odo M ost r ar y la im plem ent am os en la clase Pr ueba, la declar ación podr ía quedar de est a for m a: Public Interface IMostrar Sub Mostrar() End Interface Public Sub Mostrar1() Implements IMostrar.Mostrar End Sub Aunque si am bos m ét odos hacen lo m ism o, en est e ej em plo m ost r ar algo, podr íam os hacer que el m ism o m ét odo de la clase sir va par a im plem ent ar el de las dos int er faces: Public Sub Mostrar() Implements IPrueba.Mostrar, IMostrar.Mostrar End Sub Es decir , lo único que t endr íam os que hacer es indicar la ot r a im plem ent ación separ ándola con una com a. ¿D ónde pode m os im ple m e nt a r la s int e r fa ce s? Par a ir acabando est e t em a nos queda por saber , ent r e ot r as cosas, dónde podem os im plem ent ar las int er faces, es decir , en que t ipos de dat os podem os usar I m plem ent s. La im plem ent ación de int er faces la podem os hacer en las clases ( Class) , est r uct ur as ( St r uct ur e) y en ot r as int er faces ( I nt er face) . Debido a que una int er faz puede im plem ent ar ot r as int er faces, si en una clase im plem ent am os una int er faz que a su vez im plem ent a ot r as, esa clase t endr á definidas cada una de las int er faces, lo m ism o ocur r e con una clase que "se der ive" de ot r a clase que im plem ent a alguna int er faz, la nueva clase t am bién incor por ar á esa int er faz. N ot a: Cuando una int er faz im plem ent a ot r as int er faces, ést as no se pueden indicar m ediant e I m plem ent s, en lugar de usar esa inst r ucción debem os usar I nher it s. Public I nt er face I Pr ueba2 I nher it s I Most r ar Si en una clase im plem ent am os una int er faz que a su vez im plem ent a ot r as int er faces, esa clase t endr á definiciones de t odos los m iem br os de t odas las int er faces, por ej em plo, si t enem os la siguient e definición de la int er faz I Pr ueba2 que "im plem ent a" la int er faz I M ost r ar : Public Interface IPrueba2 Inherits IMostrar Function Saludo(ByVal nombre As String) As String Property Nombre() As String Event DatosCambiados() End Interface Y la clase Pr ueba2 im plem ent a I Pr ueba2 , la definición de los m iem br os quedar ía de la siguient e for m a: Public Class Prueba2 Implements IPrueba2 Public Sub Mostrar() Implements IMostrar.Mostrar End Sub Public Event DatosCambiados() Implements IPrueba2.DatosCambiados Public Property Nombre() As String Implements IPrueba2.Nombre Get End Get Set(ByVal value As String) End Set End Property Public Function Saludo(ByVal nombre As String) As String _ Implements IPrueba2.Saludo End Function End Class En est e código, el m ét odo M ost r ar se indica m ediant e la int er faz I M ost r ar , per o t am bién se puede hacer por m edio de I Pr ueba2 .M ost r ar , ya que I Pr ueba2 t am bién lo im plem ent a ( o her eda) . Si dej am os que Visual Basic cr ee los m iem br os, no t endr em os pr oblem as a la hor a de definir los. Per o si lo hacem os m anualm ent e, aunque dent r o del I DE de Visual Basic, ést e nos ayuda indicándonos que int er faces im plem ent am os y qué m iem br os son los que se adecuan a la declar ación que est am os usando, t al com o podem os com pr obar en la figur a 2.16: Figur a 2 .1 6 . I nt elliSense solo m uest r a los m ét odos que m ej or se adecuan a la declar ación Un e j e m plo pr á ct ico usa ndo una int e r fa z de .N ET Tal com o com ent am os al pr incipio, el pr opio .NET est á "plagado" de int er faces, cada una de ellas t iene un fin concr et o, por ej em plo, si quer em os definir una clase que pueda ser clasificada por el pr opio .NET, esa clase debe im plem ent ar la int er faz I Com par able, ya que el m ét odo Sor t , ( de la clase que cont iene los elem ent os del t ipo definido por nosot r os) , que es el encar gado de clasificar los elem ent os, har á una llam ada al m ét odo I Com par able.Com par eTo de cada uno de los obj et os que quer em os clasificar , por t ant o, si la clase no ha definido esa int er faz, no podr em os clasificar los elem ent os que cont enga. En el siguient e código t enem os la definición de una clase llam ada Em pleado que im plem ent a la int er faz I Com par able y en el m ét odo Com par eTo hace la com pr obación de que obj et o es m ayor o m enor , si el de la pr opia clase o el indicado en el par ám et r o de esa función: Public Class Empleado Implements IComparable Public Nombre As String Public Sub New(ByVal nombre As String) Me.Nombre = nombre End Sub ' Si el objeto es del tipo Empleado, comparamos los nombres. ' Si no es del tipo Empleado, devolvemos un cero ' que significa que los dos objetos son iguales. Public Function CompareTo(ByVal obj As Object) As Integer _ Implements System.IComparable.CompareTo If TypeOf obj Is Empleado Then Dim e1 As Empleado = CType(obj, Empleado) Return String.Compare(Me.Nombre, e1.Nombre) Else Return 0 End If End Function End Class En el m ét odo Com par eTo hacem os una com pr obación de que el obj et o con el que debem os r ealizar la com par ación es del t ipo Em pleado, en ese caso conver t im os el obj et o pasado en uno del t ipo Em pleado y com par am os los nom br es. Si el obj et o que r ecibe el m ét odo no es del t ipo Em pleado, devolvem os un cer o, par a indicar que no haga ninguna clasificación, ya que ese valor indica que los dos obj et os son iguales. Est a com par ación no es est r ict am ent e necesar ia, ya que si no indicam os el valor que debe devolver una función, devolver á un valor cer o, al m enos en est e caso, ya que el t ipo a devolver es un núm er o ent er o. Est a clase la podem os usar de est a for m a: ' Una colección de datos del tipo Empleado. Dim empleados As New System.Collections.Generic.List(Of Empleado) ' Añadimos varios empleados.Add(New empleados.Add(New empleados.Add(New empleados.Add(New empleados a la colección. Empleado("Pepe")) Empleado("Bernardo")) Empleado("Juan")) Empleado("Ana")) ' Clasificamos los empleados de la colección. empleados.Sort() ' Mostramos los datos una vez clasificados. For Each e1 As Empleado In empleados Console.WriteLine(e1.Nombre) Next Es indiscut ible que por m ucho que nos lo pr opongam os, nuest r as aplicaciones no est ar án libr es de er r or es, y no nos r efer im os a er r or es sint áct icos, ya que, afor t unadam ent e, el I DE ( I nt egr at ed Developm ent Envir nm ent , ent or no de desar r ollo int egr ado) de Visual Basic 2010 nos avisar á de cualquier er r or sint áct ico e incluso de cualquier asignación no válida ( al m enos si t enem os act ivado Opt ion St r ict On) , per o de lo que no nos avisar á, com o es lógico, ser á de los er r or es que se pr oduzcan en t iem po de ej ecución. Par a est os casos, Visual Basic pone a nuest r a disposición el m anej o de excepcione, veam os pues cóm o ut ilizar lo, sobr e t odo el sist em a de excepciones est r uct ur adas que es el r ecom endable par a cualquier desar r ollo con .NET Fr am ewor k. M a ne j o de e x ce pcione s M a n e j o de e x ce pcion e s Manej o de excepciones no est r uct ur adas Manej o de excepciones est r uct ur adas Bloque Tr y Bloque Cat ch Var ias capt ur as de er r or es en un m ism o bloque Tr y/ Cat ch Evaluación condicional en un bloque Cat ch Bloque Finally Capt ur a de er r or es no cont r olados En Visual Basic 2010 el t r at am ient o de er r or es ( excepciones) podem os hacer lo de dos for m as dist int as, dependiendo de que ut ilicem os el t r at am ient o de er r or es her edado de ver siones ant er ior es o el r ecom endado par a la plat afor m a .NET: el cont r ol de er r or es est r uct ur ado, con idea de hacer lo de una for m a m ás "or denada". En est a lección solam ent e ver em os cóm o t r at ar los er r or es de for m a est r uct ur ada, por que, com o hem os com ent ado es la for m a r ecom endada de hacer lo en .NET Fr am ewor k. M a n e j o de e x ce pcion e s n o e st r u ct u r a da s Com o acabam os de com ent ar , no t r at ar em os o explicar em os cóm o t r abaj ar con el t r at am ient o de er r or es no est r uct ur ados, per o al m enos quer em os hacer una aclar ación par a que no nos llevem os una sor pr esa si nos decidim os a usar lo: No podem os usar los dos sist em as de t r at am ient o de er r or es al m ism o t iem po, por lo m enos en un m ism o m ét odo o pr opiedad, o ut ilizam os On Er r or o ut ilizam os Tr y/ Cat ch. De t odas for m as, si escr ibim os nuest r o código con el I DE ( ent or no int egr ado) de Visual St udio 2010, ést e nos avisar á de que no podem os hacer esa m ezcla. M a ne j o de e x ce pcione s e st r uct ur a da s Las excepciones en Visual Basic 2010 las podem os cont r olar usando las inst r ucciones Tr y / Cat ch / Finally . Est as inst r ucciones r ealm ent e son bloques de inst r ucciones, al est ilo de I f / Else. Cuando quer am os cont r olar una par t e del código que puede pr oducir un er r or lo incluim os dent r o del bloque Tr y. Si se pr oduce un er r or , ést e lo podem os det ect ar en el bloque Cat ch. Por últ im o, independient em ent e de que se pr oduzca o no una excepción, podem os ej ecut ar el código que incluyam os en el bloque Finally, par a indicar el final del bloque de cont r ol de excepciones lo har em os con End Tr y . Cuando cr eam os una est r uct ur a de cont r ol de excepciones no est am os obligados a usar los t r es bloques, aunque el pr im er o: Tr y si es necesar io, ya que es el que le indica al com pilador que t enem os int ención de cont r olar los er r or es que se pr oduzcan . Por t an t o podem os cr ear un "m anej ador " de excepciones usando los t r es bloques, usando Tr y y Cat ch o usando Tr y y Finally . Veam os ahor a con m ás det alle cada uno de est os bloques y que es lo que podem os hacer en cada uno de ellos. Bloqu e Tr y En est e bloque incluir em os el código en el que quer em os com pr obar los er r or es. El código a usar ser á un código nor m al, es decir , no t enem os que hacer nada en especial, ya que en el m om ent o que se pr oduzca el er r or se usar á ( si hay) el código del bloque Cat ch. Bloqu e Ca t ch Si se pr oduce una excepción, ést a la capt ur am os en un bloque Cat ch. En el bloque Cat ch podem os indicar que t ipo de excepción quer em os capt ur ar , par a ello usar em os una var iable de t ipo Except ion, la cual pude ser del t ipo de er r or específico que quer em os cont r olar o de un t ipo genér ico. Por ej em plo, si sabem os que nuest r o código puede pr oducir un er r or al t r abaj ar con ficher os, podem os usar un código com o est e: Try ' código para trabajar con ficheros, etc. Catch ex As System.IO.IOException ' el código a ejecutar cuando se produzca ese error End Try Si nuest r a int ención es capt ur ar t odos los er r or es que se pr oduzcan, es decir , no quer em os hacer un filt r o con er r or es específicos, podem os usar la clase Except ion com o t ipo de excepción a capt ur ar . La clase Except ion es la m ás genér ica de t odas las clases par a m anej o de excepciones, por t ant o capt ur ar á t odas las excepciones que se pr oduzcan. Try ' código que queremos controlar Catch ex As Exception ' el código a ejecutar cuando se produzca cualquier error End Try Aunque si no vam os usar la var iable indicada en el bloque Cat ch, per o quer em os que no se det enga la aplicación cuando se pr oduzca un er r or , podem os hacer lo de est a for m a: Try ' código que queremos controlar Catch ' el código a ejecutar cuando se produzca cualquier error End Try V a r ia s ca pt u r a s de e r r or e s e n u n m ism o bloqu e Tr y/ Ca t ch En un m ism o Tr y podem os capt ur ar difer ent es t ipos de er r or es, par a ello podem os incluir var ios bloques Cat ch, cada uno de ellos con un t ipo de excepción difer ent e. Es im por t ant e t ener en cuent a que cuando se pr oduce un er r or y usam os var ios bloques Cat ch, Visual Basic buscar á la capt ur a que m ej or se adapt e al er r or que se ha pr oducido, per o siem pr e lo har á exam inando los difer ent es bloques Cat ch que hayam os indicado em pezando por el indicado después del bloque Tr y, por t ant o deber íam os poner las m ás genér icas al final, de for m a que siem pr e nos asegur em os de que las capt ur as de er r or es m ás específicas se int er cept en ant es que las genér icas. Eva lu a ción con dicion a l e n u n bloqu e Ca t ch Adem ás de indicar la excepción que quer em os cont r olar , en un bloque Cat ch podem os añadir la cláusula When par a evaluar una expr esión. Si la evaluación de la expr esión indicada después de When devuelve un valor ver dader o, se pr ocesar á el bloque Cat ch, en caso de que devuelva un valor falso, se ignor ar á esa capt ur a de er r or . Est o nos per m it e poder indicar var ios bloques Cat ch que det ect en el m ism o er r or , per o cada una de ellas pueden t ener difer ent es expr esiones indicadas con When. En el siguient e ej em plo, se evalúa el bloque Cat ch solo cuando el valor de la var iable y es cer o, en ot r o caso se ut ilizar á el que no t iene la cláusula When: Dim x, y, r As Integer Try x = CInt(Console.ReadLine()) y = CInt(Console.ReadLine()) r = x \ y Console.WriteLine("El resultado es: {0}", r) Catch ex As Exception When y = 0 Console.WriteLine("No se puede dividir por cero.") Catch ex As Exception Console.WriteLine(ex.Message) End Try Bloqu e Fin a lly En est e bloque podem os indicar las inst r ucciones que quer em os que se ej ecut en, se pr oduzca o no una excepción. De est a for m a nos asegur am os de que siem pr e se ej ecut ar á un código, por ej em plo par a liber ar r ecur sos, se haya pr oducido un er r or o no. N ot a: Hay que t ener en cuent a de que incluso si usam os Exit Tr y par a salir del bloque de cont r ol de er r or es, se ej ecut ar á el código indicado en el bloque Finally. Ca pt ur a de e r r or e s no cont r ola dos Com o es lógico, si no cont r olam os las excepciones que se puedan pr oducir en nuest r as aplicaciones, est as ser án inicialm ent e cont r oladas por el pr opio r unt im e de .NET, en est os casos la aplicación se det iene y se m uest r a el er r or al usuar io. Per o est o es algo que no deber íam os consent ir , por t ant o siem pr e deber íam os det ect ar t odos los er r or es que se pr oduzcan en nuest r as aplicaciones, per o a pesar de que lo int ent em os, es m uy pr obable que no siem pr e podam os conseguir lo. Por suer t e, en Visual Basic 2010 t enem os dos for m as de int er cept ar los er r or es no cont r olados: La pr im er a es iniciando nuest r a aplicación dent r o de un bloque Tr y/ Cat ch, de est a for m a, cuando se pr oduzca el er r or , se capt ur ar á en el bloque Cat ch. La segunda for m a de int er cept ar los er r or es no cont r olados es m ediant e el event o: UnhandledExcept ion, disponible por m edio del obj et o My.Applicat ion. N ot a: De los event os nos ocupar em os en la siguient e lección, per o com o el event o UnhandledExcept ion est á dir ect am ent e r elacionado con la capt ur a de er r or es, lo m ost r am os en est a, aunque r ecom endam os al lect or que est a sección la vuelva a leer después de ver t odo lo r elacionado con los event os. Est e event o se "dispar a" cuando se pr oduce un er r or que no hem os int er cept ado, por t ant o podr íam os usar lo par a pr evenir que nuest r a aplicación se det enga o bien par a guar dar en un ficher o .log la causa de dicho er r or par a post er ior m ent e act ualizar el código y pr evenir lo. Ya que cuando se pr oduce el event o UnhandledExcept ion, podem os aver iguar el er r or que se ha pr oducido e incluso evit ar que la aplicación finalice. Esa infor m ación la obt enem os m ediant e pr opiedades expuest as por el segundo par ám et r o del event o, en par t icular la pr opiedad Except ion nos indicar á el er r or que se ha pr oducido y por m edio de la pr opiedad Exit Applicat ion podem os indicar si t er m inam os o no la aplicación. N ot a: Cuando ej ecut am os una aplicación desde el I DE, los er r or es no cont r olados siem pr e se pr oducen, independient em ent e de que t engam os o no definida la capt ur a de er r or es desde el event o UnhandledExcept ion. Ese event o solo se pr oducir á cuando ej ecut em os la aplicación fuer a del I DE de Visual Basic. La for m a que t ienen nuest r as clases y est r uct ur as de com unicar que algo est á ocur r iendo, es por m edio de event os. Los event os son m ensaj es que se lanzan desde una clase par a infor m ar al "client e" que los ut iliza de que est á pasando algo. Segur am ent e est ar em os acost um br ados a usar los, incluso sin t ener una noción conscient e de que se t r at an de event os, o bien por que es algo t an habit ual que no le pr est am os m ayor at ención, es el caso de las aplicaciones de escr it or io, cada vez que pr esionam os un bot ón, escr ibim os algo o m ovem os el m ouse se est án pr oduciendo event os. El com pilador de Visual Basic 2010 nos facilit a m ucho la cr eación de los event os y "esconde" t odo el pr oceso que .NET r ealm ent e hace "en la som br a". Ese t r abaj o al que nos r efer im os est á r elacionado con los delegados, una palabr a que suele apar ecer en cualquier docum ent ación que t r at e sobr e los event os. Y es que, aunque Visual Basic 2010 nos ocult e, o facilit e, el t r abaj o con los event os, ést os est án est r echam ent e r elacionados con los delegados. En est a lección ver em os que son los delegados y que r elación t ienen con los event os, t am bién ver em os que podem os t ener m ayor cont r ol sobr e cóm o se int er cept an los event os e incluso cóm o y cuando se asocian los event os en la aplicación client e, aunque pr im er o em pezar em os viendo cóm o declar ar y ut ilizar event os en nuest r os t ipos de dat os. Ev e nt os y de le ga dos Eve n t os I nt er cept ar los event os de los cont r oles de un for m ular io I nt er cept ar event os en Visual Basic 2010 Asociar un event o con un cont r ol For m as de asociar los event os con un cont r ol 1- Asociar el event o m anualm ent e por m edio de Handles 2- Asociar el event o desde la vent ana de código 3- Asociar el event o desde el diseñador de for m ular ios Asociar var ios event os a un m ism o pr ocedim ient o Declar ar una var iable par a asociar event os con Handles De fin ir y pr odu cir e ve n t os e n u n a cla se Definir event os en una clase Pr oducir un event o en nuest r a clase Ot r a for m a de asociar los event os de una clase con un m ét odo Asociar event os m ediant e AddHandler Desasociar event os m ediant e Rem oveHandler De le ga dos ¿Qué ocur r e cuando se asigna y se pr oduce un event o? ¿Qué papel j uegan los delegados en t odo est e pr oceso? Definición "for m al" de delegado Ut ilizar un delegado par a acceder a un m ét odo De fin ir u n e ve n t o bie n in for m a do con Cu st om Eve n t Com o hem os com ent ado en la int r oducción, en Visual Basic 2010 podem os usar los event os de una for m a bast ant e sencilla, al m enos si la com par am os con ot r os lenguaj es de la fam ilia .NET. En las secciones que siguen ver em os cóm o ut ilizar los event os que pr oducen las clases de .NET, em pezar em os con ver cóm o ut ilizar los event os de los for m ular ios, que con t oda segur idad ser án los que est am os m ás acost um br ados a usar . Tam bién ver em os las dist int as for m as que t enem os de asociar un m ét odo con el event o pr oducido por un cont r ol ( que al fin y al cabo es una clase) . I nt e r ce pt a r los e v e nt os de los cont r ole s de un for m ula r io Debido a que aún no hem os vist o el m ódulo dedicado a las aplicaciones de Windows, en las que se ut ilizan los "clásicos" for m ular ios, no vam os a ent r ar en det alles sobr e cóm o cr ear un for m ular io ni com o añadir cont r oles, et c., t odo eso lo ver em os en el siguient e m ódulo. Par a sim plificar las cosas, ver em os cóm o se int er cept an en un for m ular io de la nueva ver sión de Visual Basic, aunque sin ent r ar en dem asiados det alles. La for m a m ás sencilla de asociar el event o de un cont r ol con el código que se usar á, es haciendo doble pulsación en el cont r ol cuando est am os en m odo de diseño; por ej em plo, si en nuest r o for m ular io t enem os un bot ón, al hacer doble pulsación sobr e él t endr em os asociado el event o Click del bot ón, ya que ese es el event o pr edet er m inado de los cont r oles But t on, y desde el diseñador de for m ular ios de Windows, al r ealizar esa doble pulsación, siem pr e se m uest r a el event o pr edet er m inado del cont r ol en cuest ión. I n t e r ce pt a r e ve n t os e n V isu a l Ba sic 2 0 1 0 Aunque en Visual Basic 2010 la for m a de asignar los event os pr edet er m inados de los cont r oles es com o hem os com ent ado ant er ior m ent e, es decir , haciendo doble pulsación en el cont r ol, la declar ación del código usado par a int er cept ar el event o es com o el m ost r ado en el siguient e código: Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles Button1.Click End Sub Lo pr im er o que podem os not ar es que en Visual Basic 2010 se ut ilizan dos ar gum ent os, est o siem pr e es así en t odos los event os pr oducidos por los cont r oles. El pr im er o indica el cont r ol que pr oduce el event o, ( en nuest r o ej em plo ser ía una r efer encia al cont r ol But t on1 ) , y el segundo nor m alm ent e cont iene infor m ación sobr e el event o que se pr oduce, si el event o en cuest ión no pr opor ciona infor m ación ext r a, com o es el caso del event o Click, ese par ám et r o ser á del t ipo Event Ar gs. Sin em bar go en ot r os event os, por ej em plo, los r elacionados con el m ouse, el segundo ar gum ent o t endr á infor m ación que nos puede r esult ar út il, por ej em plo par a saber que bot ón se ha usado o cual es la posición del cur sor , en la figur a 2.17 podem os ver las pr opiedades r elacionadas con el event o MouseEvent Ar gs: Figur a 2 .1 7 . Pr opiedades r elacionadas con un event o del m ouse Asocia r un e v e nt o con un cont r ol Siguiendo con el código que int er cept a el event o Click de un bot ón, podem os apr eciar que el I DE de Visual Basic 2010 añade al final de la declar ación del pr ocedim ient o de event o la inst r ucción Handles seguida del cont r ol y el event o que quer em os int er cept ar : H andles But t on1 .Click, est a la for m a habit ual de hacer lo en Visual Basic 2010, aunque t am bién hay ot r as for m as de "ligar " un m ét odo con un event o, com o t endr em os ocasión de com pr obar m ás adelant e. N ot a: En Visual Basic 2010 el nom br e del pr ocedim ient o de event o no t iene por qué est ar r elacionado con el event o, aunque por defect o, el nom br e usado es el que habit ualm ent e se ha ut ilizado por años en ot r os ent or nos de desar r ollo, y que se for m a usando el nom br e del cont r ol seguido de un guión baj o y el nom br e del event o, per o que en cualquier m om ent o lo podem os cam biar , ya que en Visual Basic 2010 no hay ninguna r elación dir ect a ent r e ese nom br e y el event o que quer em os int er cept ar . Tal com o r esalt am os en la not a ant er ior , en Visual Basic 2010, el nom br e asociado a un event o puede ser el que quer am os, lo r ealm ent e im por t ant e es que indiquem os la inst r ucción Handles seguida del event o que quer em os int er cept ar . Aunque, com o ver em os a cont inuación, t am bién hay ot r as for m as de "r elacionar " los event os con el m ét odo usado par a r ecibir la not ificación. For m a s de a socia r los e v e nt os con un cont r ol Cuando est am os t r abaj ando con el diseñador de for m ular ios, t enem os t r es for m as de asociar un event o con el código cor r espondient e: La for m a m ás sencilla es la expuest a ant er ior m ent e, es decir , haciendo doble click en el cont r ol, est o har á que se m uest r e el event o pr edet er m inado del cont r ol. En el caso del cont r ol But t on, el event o pr edet er m inado es el event o Click. Si quer em os escr ibir código par a ot r os event os podem os hacer lo de t r es for m as, aunque la pr im er a que explicar em os no ser á la m ás habit ual, ya que debem os saber exact am ent e qué par ám et r os ut iliza el event o. 1 - Asocia r e l e ve n t o m a n u a lm e n t e por m e dio de Ha n dle s Con est a for m a, sim plem ent e escr ibim os el nom br e del pr ocedim ient o ( puede ser cualquier nom br e) , indicam os los dos ar gum ent os que r ecibe: el pr im er o siem pr e es de t ipo Obj ect y el segundo depender á del t ipo de event o, y finalm ent e por m edio de la cláusula Handles lo asociam os con el cont r ol y el event o en cuest ión. 2 - Asocia r e l e ve n t o de sde la ve n t a n a de código En Visual Basic 2010 t am bién podem os seleccionar los event os disponibles de una list a desplegable. Est o lo har em os desde la vent ana de código. En la par t e super ior der echa t enem os una la list a con los cont r oles que hem os añadido al for m ular io, seleccionam os el cont r ol que nos int er ese y en la list a que hay a su izquier da t enem os los event os que ese cont r ol pr oduce. Por t ant o podem os seleccionar de esa list a de event os el que nos int er ese in t er cept ar , t al com o podem os ver en la figur a 2.18 Figur a 2 .1 8 . List a de event os de un cont r ol De est a for m a el pr opio I DE ser á el que cr ee el "esquelet o" del pr ocedim ient o de event o usando los par ám et r os adecuados. 3 - Asocia r e l e ve n t o de sde e l dise ñ a dor de for m u la r ios La t er cer a for m a de asociar un event o con un cont r ol, es hacer lo desde el diseñador de for m ular ios. En la vent ana de pr opiedades del cont r ol, ( t al com o podem os apr eciar en la figur a 2.19) , t enem os una list a con los event os m ás im por t ant es de cada cont r ol, seleccionando el event o de esa list a y haciendo doble- click en el que nos int er ese, conseguir em os exact am ent e el m ism o r esult ado que con el paso ant er ior . Figur a 2 .1 9 . Vent ana de pr opiedades con los event os del cont r ol seleccionado Asocia r v a r ios e v e nt os a un m ism o pr oce dim ie nt o Cuando ut ilizam os Handles par a asociar event os, podem os indicar que un m ism o pr ocedim ient o sir va par a int er cept ar var ios event os. Veam os un caso pr áct ico en el que t enem os var ios cont r oles de t ipo Text Box y quer em os que cuando r eciban el foco siem pr e se ej ecut e el m ism o código, por ej em plo, que se seleccione t odo el t ext o que cont iene, podem os hacer lo indicando después de la cláusula Handles t odos los cont r oles que quer em os asociar con ese pr ocedim ient o. En el siguient e código indicam os t r es cont r oles Text Box: Private Sub TextBox1_Enter( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles TextBox1.Enter, TextBox2.Enter, TextBox3.Enter End Sub Est a asociación la podem os hacer m anualm ent e, sim plem ent e indicando en la cláusula Handles cada uno de los event os a cont inuación del ant er ior separ ándolos por com as. O bien desde el diseñador de for m ular ios. En est e segundo caso, cuando seleccionam os un cont r ol y desde la vent ana de pr opiedades, seleccionam os un event o, nos m uest r a los pr ocedim ient os que t enem os definidos en nuest r o código que ut ilizan los m ism os par ám et r os que el event o en cuest ión, si seleccionam os uno de esos pr ocedim ient os, el pr opio I DE añadir á ese cont r ol a la list a Handles. Com o vem os en la figur a 2.20 podem os usar el pr ocedim ient o Text Box1 _ Ent er par a asociar lo al event o Ent er del cont r ol Text Box2 : Figur a 2 .2 0 . List a de pr ocedim ient os " com pat ibles" con un event o D e cla r a r una v a r ia ble pa r a a socia r e v e nt os con H a ndle s Par a que podam os usar la inst r ucción Handles par a asociar m anualm ent e un pr ocedim ient o con un event o, o par a que el diseñador de Visual Basic 2010 pueda hacer lo, la var iable del cont r ol o clase que t iene los event os que quer em os int er cept ar t enem os que declar ar la con la inst r ucción Wit hEvent s. De est os det alles se encar ga el pr opio I DE de Visual Basic 2010, por t ant o no debem os pr eocupar nos de cóm o declar ar los cont r oles par a que se pueda usar Handles en el m ét odo del pr ocedim ient o que r ecibe la not ificación del event o, per o com o los cont r oles de .NET r ealm ent e son clases, veam os cóm o declar a el VB los cont r oles, ( en est e caso un cont r ol llam ado But t on1 ) , par a a cont inuación com par ar lo con una clase definida por nosot r os. Friend WithEvents Button1 As System.Windows.Forms.Button Si en lugar de est ar t r abaj ando con for m ular ios y cont r oles, lo hacem os con clases "nor m ales", la for m a de declar ar una var iable que t iene event os es por m edio de la inst r ucción Wit hEv ent s. Por ej em plo, en est a declar ación indicam os que t enem os int ención de usar los event os que la clase Em pleado exponga: Private WithEvents unEmpleado As Empleado Y post er ior m ent e podr em os definir los m ét odos de event os usando la inst r ucción Handles: Private Sub unEmpleado_DatosCambiados() Handles unEmpleado.DatosCambiados End Sub N ot a: Usar Wit hEvent s y Handles es la for m a m ás sencilla de declar ar y usar una var iable que accede a una clase que pr oduce event os, per o com o ya hem os com ent ado, no es la única for m a que t enem os de hacer lo en Visual Basic 2010, t al com o t endr em os opor t unidad de com pr obar . En la lección ant er ior hem os vist o cóm o int er cept ar event os, en est a ver em os cóm o definir los en nuest r as clases y cóm o pr oducir los, par a que el client e que los int er cept e sepa que algo ha ocur r ido en nuest r a clase. D e fin ir e v e n t os e n una cla se Par a definir un event o en una clase usam os la inst r ucción Event seguida del nom br e del event o y opcionalm ent e indicam os los par ám et r os que dicho event o r ecibir á. En el siguient e t r ozo de código definim os un event o llam ado D at osM odificados que no ut iliza ningún ar gum ent o: Public Event DatosModificados() Est o es t odo lo que necesit am os hacer en Visual Basic 2010 par a definir un event o. Com o podem os com pr obar es m uy sencillo, ya que solo t enem os que usar la inst r ucción Event . Aunque det r ás del t elón ocur r en ot r as cosas de las que, al m enos en pr incipio, no debem os pr eocupar nos, ya que es el pr opio com pilador de Visual Basic 2010 el que se encar ga de esos "pequeños det alles". Pr oducir un e v e nt o e n nue st r a cla se Par a pr oducir un event o en nuest r a clase, y de est a for m a not ificar a quién quier a int er cept ar lo, sim plem ent e usar em os la inst r ucción RaiseEvent seguida del event o que quer em os pr oducir . Cuando escr ibim os esa inst r ucción en el I DE de Visual Basic 2010, nos m ost r ar á los dist int os event os que podem os pr oducir , t al com o vem os en la figur a 2.21: Figur a 2 .2 1 . List a de event os que podem os pr oducir Est a es la for m a m ás sencilla de definir y lanzar event os en Visual Basic 2010. Ot r a for m a de a socia r los e v e nt os de una cla se con un m é t odo Tal com o hem os est ado com ent ando, la for m a m ás sencilla de declar ar una var iable par a int er cept ar event os es declar ándola usando Wit hEv ent s y par a in t er cept ar los event os lo hacem os por m edio de la inst r ucción Handles. Est a for m a, es a t odas luces la m ás r ecom endada, no solo por la facilidad de hacer lo, sino por que t am bién t enem os la vent aj a de que t odas las var iables declar adas con Wit hEv ent s se m uest r an en la list a desplegable de la vent ana de código, t al com o podem os apr eciar en la figur a 2.22: Figur a 2 .2 2 . List a de obj et os que pr oducen event os Y de est a for m a podem os seleccionar la var iable y post er ior m ent e elegir el event o a int er cept ar , t al com o vim os en la figur a 2.18. Asocia r e v e nt os m e dia nt e AddH a ndle r Per o Visual Basic 2010 t am bién pr opor ciona ot r a for m a de asociar un pr ocedim ient o con un event o. Aunque en est e caso es algo m ás m anual que t odo lo que hem os vist o y, de alguna for m a est á m ás ligado con los delegados, y com o los delegados los ver em os dent r o de poco, ahor a solam ent e m ost r ar em os la for m a de hacer lo y después ver em os con algo de m ás det alle cóm o funciona. La for m a de de asociar event os con su cor r espondient e m ét odo es por m edio de la inst r ucción AddHandler . A est a inst r ucción le pasam os dos ar gum ent os, el pr im er o es el event o a asociar y el segundo es el pr ocedim ient o que usar em os cuando se pr oduzca dicho event o. Est e últ im o par ám et r o t endr em os que indicar lo m ediant e la inst r ucción Addr essOf, que sir ve par a pasar una r efer encia a una función o pr ocedim ient o, y pr ecisam ent e eso es lo que quer em os hacer : indicar le que pr ocedim ient o debe usar cuando se pr oduzca el event o: AddHandler unEmpleado.DatosCambiados, AddressOf unEmpleado_DatosCambiados En est e caso, el uso de Addr essOf es una for m a "fácil" que t iene Visual Basic 2010 de asociar un pr ocedim ient o de event o con el event o. Aunque por el fondo, ( y sin que nos ent er em os) , r ealm ent e lo que est am os usando es un const r uct or a un delegado. La vent aj a de usar est a for m a de asociar event os con el pr ocedim ient o, es que podem os hacer lo con var iables que no est án declar adas con Wit hEvent s, r ealm ent e est a ser ía la única for m a de asociar un pr ocedim ient o de event o con una var iable que no hem os declar ado con Wit hEv ent s. D e sa socia r e v e nt os m e dia nt e Re m ov e H a ndle r De la m ism a for m a que por m edio de AddHandler podem os asociar un pr ocedim ient o con un event o, usando la inst r ucción Rem oveHandler podem os hacer el pr oceso cont r ar io: desligar un pr ocedim ient o del event o al que pr eviam ent e est aba asociado. Los par ám et r os a usar con Rem oveHandler son los m ism os que con AddHandler . Podem os usar Rem oveHandler t ant o con var iables y event os definidos con AddHandler com o con var iables declar adas con Wit hEvent s y ligadas por m edio de Handles. Est o últ im o es así por que cuando nosot r os definim os los pr ocedim ient os de event os usando la inst r ucción Handles, es el pr opio Visual Basic el que int er nam ent e ut iliza AddHandler par a ligar ese pr ocedim ient o con el event o en cuest ión. Saber est o nos facilit ar á com pr ender m ej or cóm o funciona la declar ación de event os m ediant e la inst r ucción Cust om , aunque de est e det alle nos ocupar em os después de ver que son los delegados. Com o hem os com ent ado ant er ior m ent e, los event os son acciones que una clase puede pr oducir cuando ocur r e algo. De est a for m a podem os not ificar a las aplicaciones que hayan decidido int er cept ar esos m ensaj es par a que t om en las acciones que cr ean convenient e. Visual Basic 2010 esconde al desar r ollador pr áct icam ent e t odo lo que ocur r e cada vez que definim os, lanzam os o int er cept am os un event o, nosot r os solo vem os una pequeña par t e de t odo el t r abaj o que en r ealidad se pr oduce, y el que no lo veam os no quier e decir que no est é ocur r iendo. Tam bién es cier t o que no debe pr eocupar nos dem asiado si no sabem os lo que est á pasando, per o si som os conscient e de que es lo que ocur r e, puede que nos ayude a com pr ender m ej or t odo lo r elacionado con los event os. ¿Qué ocur r e cua ndo se a signa y se pr oduce un e v e nt o? I nt ent em os ver de for m a sencilla lo que ocur r e "por dent r o" cada vez que definim os un m ét odo que int er cept a un event o y cóm o hace el Visual Basic par a com unicar se con el r ecept or de dicho event o. 1. Cuando Visual Basic se encuent r a con el código que le indica que un m ét odo debe int er cept ar un event o, ya sea m ediant e AddHandler o m ediant e el uso de Handles, lo que hace es añadir la dir ección de m em or ia de ese m ét odo a una especie de ar r ay. En la figur a 2.23 podem os ver un diagr am a en el que un m ism o event o lo int er cept an t r es client es, cuando decim os que un client e int er cept a un event o, r ealm ent e nos r efer im os a que hay un m ét odo que lo int er cept a y el event o r ealm ent e guar da la dir ección de m em or ia de ese m ét odo. Figur a 2 .2 3 . El event o guar da la dir ección de m em or ia de cada m ét odo que lo int er ce pt a 2. Cuando usam os la inst r ucción RaiseEvent par a pr oducir el event o, se exam ina esa list a de dir ecciones y se m anda el m ensaj e a cada uno de los m ét odos que t enem os en el "ar r ay". En est e caso, lo que r ealm ent e ocur r e es que se hace una llam ada a cada uno de los m ét odos, de for m a que se ej ecut e el código al que t enem os acceso m ediant e la dir ección de m em or ia alm acenada en la list a. 3. Cuando usam os la inst r ucción Rem oveHandler , le est am os indicando al event o que elim ine de la list a el m ét odo indicado en esa inst r ucción, de est a for m a, la pr óxim a vez que se pr oduzca el event o, solo se llam ar á a los m ét odos que act ualm ent e est én en la list a. Tant o el agr egar nuevos m ét odos a esa list a com o quit ar los, lo podem os hacer en t iem po de ej ecución, por m edio de AddHandler y Rem oveHandler r espect ivam ent e. Ya que la inst r ucción Handles solo la podem os usar en t iem po de diseño. Es m ás, podem os incluso indicar que un m ism o event o pr ocese m ás de un m ét odo en una m ism a aplicación o que un m ism o m ét odo sea llam ado por m ás de un event o. Ya que lo que r ealm ent e necesit a cada event o es que exist a un m ét odo que t enga una "fir m a" concr et a: la indicada al declar ar el event o. ¿Qué pa pe l j ue ga n los de le ga dos e n t odo e st e pr oce so? Veam os pr im er o que papel t ienen los delegados en t odo est e pr oceso y después ver em os con m ás det alle lo que "r ealm ent e" es un delegado. 1. Cuando definim os un event o, r ealm ent e est am os definiendo un delegado, ( que en el fondo es una clase con un t r at am ient o especial) , y un m ét odo del m ism o t ipo que el delegado. 2. Cuando indicam os que un m ét odo int er cept e un event o, r ealm ent e est am os llam ando al const r uct or del delegado, al que le pasam os la dir ección de m em or ia del m ét odo. El delegado alm acena cada una de esas dir ecciones de m em or ia par a post er ior m ent e usar las. 3. Cuando se pr oduce el event o, ( por m edio de RaiseEvent ) , r ealm ent e est am os llam ando al delegado par a que acceda a t odas las "dir ecciones" de m em or ia que t iene alm acenadas y ej ecut e el código que hayam os definido en cada uno de esos m ét odos. Com o podem os com pr obar , y par a decir lo de for m a sim ple, un delegado r ealm ent e es la for m a que t iene .NET par a definir un punt er o. La difer encia pr incipal es que los punt er os, ( no vam os a ent r ar en dem asiados det alles sobr e los punt er os, ya que no est am os en un cur so de C/ C+ + ) , no t ienen for m a de com pr obar si est án accediendo a una dir ección de m em or ia cor r ect a o, par a decir lo de ot r a for m a, a una dir ección de m em or ia "adecuada". En .NET, los "punt er os" solo se pueden usar m ediant e delegados, y ést os solam ent e pueden acceder a dir ecciones de m em or ia que t ienen la m ism a "fir m a" con el que se han definido. Par a que lo ent endam os un poco m ej or , es com o si los delegados solo pudier an acceder a sit ios en la m em or ia que cont ienen un m ét odo con la m ism a "int er faz" que el que ha definido el pr opio delegado. Segur am ent e es difícil de ent ender , y la pr incipal r azón es que hem os em pezado la casa por el t echo. Por t ant o, veam os a cont inuación una definición "for m al" de qué es un delegado y veam os var ios ej em plos par a que lo com pr endam os m ej or . D e finición " for m a l" de de le ga do Veam os que nos dice la docum ent ación de Visual Basic sobr e los delegados: "Un delegado es una clase que puede cont ener una r efer encia a un m ét odo. A difer encia de ot r as clases, los delegados t ienen un pr ot ot ipo ( fir m a) y pueden guar dar r efer encias únicam ent e a los m ét odos que coinciden con su pr ot ot ipo." Est a definición, al m enos en lo que r espect a a su r elación con los event os, viene a decir que los delegados definen la for m a en que debem os declar ar los m ét odos que quer am os usar par a int er cept ar un event o. Si seguim os buscando m ás infor m ación sobr e los delegados en la docum ent ación de Visual Basic, t am bién nos encont r am os con est a definición: "Los delegados habilit an escenar ios que en ot r os lenguaj es se han r esuelt o con punt er os a función. No obst ant e, a difer encia de los punt er os a función, los delegados est án or ient ados a obj et os y pr opor cionan segur idad de t ipos." Que es lo que com ent am os en la sección ant er ior : los delegados nos facilit an el acceso a "punt er os" ( o dir ecciones de m em or ia) de funciones, per o hecho de una for m a "cont r olada", en est e caso por el pr opio .NET fr am ewor k. Por ej em plo, el event o D at osCam biados definido ant er ior m ent e, t am bién lo podem os definir de la siguient e for m a: Public Delegate Sub DatosCambiadosEventHandler() Public Event DatosCambiados As DatosCambiadosEventHandler Es decir , el m ét odo que int er cept e est e event o debe ser del t ipo Sub y no r ecibir ningún par ám et r o. Si nuest r o event o ut iliza, por ej em plo, un par ám et r o de t ipo St r ing, la definición del delegado quedar ía de la siguient e for m a: Public Delegate Sub NombreCambiadoEventHandler(ByVal nuevoNombre As String) Y la definición del event o quedar ía de est a ot r a: Public Event NombreCambiado As NombreCambiadoEventHandler Com o vem os al definir el event o ya no t enem os que indicar si r ecibe o no algún par ám et r o, ya que esa definición la hem os hecho en el delegado. Si nos decidim os a definir est e event o de la for m a "nor m al" de Visual Basic, lo har íam os así: Public Event NombreCambiado(ByVal nuevoNombre As String) Com o podem os com pr obar , Visual Basic nos per m it e definir los event os de dos for m as dist int as: definiendo un delegado y un event o que sea del t ipo de ese delegado o definiendo el event o con los ar gum ent os que debem os usar . Declar em os com o declar em os los event os, los podem os seguir usando de la m ism a for m a, t ant o par a pr oducir lo m ediant e RaiseEvent com o par a definir el m ét odo que r eciba ese event o. Ut iliza r un de le ga do pa r a a cce de r a un m é t odo Ahor a veam os br evem ent e cóm o usar los delegados, en est e caso sin necesidad de que defina un event o. Com o hem os com ent ado, un delegado r ealm ent e es una clase que puede cont ener una r efer encia a un m ét odo, adem ás define el pr ot ot ipo del m ét odo que podem os usar com o r efer encia. Sabiendo est o, podem os declar ar una var iable del t ipo del delegado y por m edio de esa var iable acceder al m ét odo que indiquem os, siem pr e que ese m ét odo t enga la m ism a "fir m a" que el delegado. Par ece com plicado ¿ver dad? Y no solo lo par ece, es que r ealm ent e lo es. Com pr obem os est a "com plicación" por m edio de un ej em plo. En est e código, que ir em os m ost r ando poco a poco, vam os a definir un delegado, un m ét odo con la m ism a fir m a par a que podam os usar lo desde una var iable definida con el m ism o t ipo del delegado. Definim os un delegado de t ipo Sub que r ecibe un valor de t ipo cadena: Delegate Sub Saludo(ByVal nombre As String) Definim os un m ét odo con la m ism a fir m a del delegado: Private Sub mostrarSaludo(ByVal elNombre As String) Console.WriteLine("Hola, " & elNombre) End Sub Ahor a vam os a declar ar una var iable par a que acceda a ese m ét odo. Par a ello debem os declar ar la con el m ism o t ipo del delegado: Dim saludando As Saludo La var iable saludando es del m ism o t ipo que el delegado Saludo. La cuest ión es ¿cóm o o que asignam os a est a var iable? Pr im er int ent o: Com o hem os com ent ado, los delegados r ealm ent e son clases, por t ant o podem os usar N ew Saludo y, según par ece, deber íam os pasar le un nom br e com o ar gum ent o. Algo así: saludando = New Saludo("Pepe") Per o est o no funciona, ent r e ot r as cosas, por que hem os com ent ado que un delegado cont iene ( o puede cont ener ) una r efer encia a un m ét odo, y " Pepe" no es un m ét odo ni una r efer encia a un m ét odo. Segundo int ent o: Por lógica y, sobr e t odo, por sent ido com ún, m áxim e cuando hem os declar ado un m ét odo con la m ism a "fir m a" que el delegado, deber íam os pensar que lo que debem os pasar a esa var iable es el m ét odo, ya que un delegado puede cont ener una r efer encia a un m ét odo. saludando = New Saludo(mostrarSaludo) Est o t am poco funciona, ¿segur am ent e por que le falt a el par ám et r o? saludando = New Saludo(mostrarSaludo("Pepe")) Pues t am poco. Par a usar un delegado debem os indicar le la dir ección de m em or ia de un m ét odo, a eso se r efier e la definición que vim os ant es, una r efer encia a un m ét odo no es ni m ás ni m enos que la dir ección de m em or ia de ese m ét odo. Y en Visual Basic, desde la ver sión 5.0, t enem os una inst r ucción par a obt ener la dir ección de m em or ia de cualquier m ét odo: Addr essOf. Por t ant o, par a indicar le al delegado dónde est á ese m ét odo t endr em os que usar cualquier a de est as dos for m as: saludando = New Saludo(AddressOf mostrarSaludo) Es decir , le pasam os al const r uct or la dir ección de m em or ia del m ét odo que quer em os "asociar " al delegado. En Visual Basic esa m ism a asignación la podem os sim plificar de est a for m a: saludando = AddressOf mostrarSaludo Ya que el com pilador "sabe" que saludando es una var iable de t ipo delegado y lo que esa var iable puede cont ener es una r efer encia a un m ét odo que t enga la m ism a fir m a que la definición del delegado, en nuest r o caso, que sea de t ipo Sub y r eciba una cadena. Si quer em os, t am bién podem os declar ar la var iable y asignar le dir ect am ent e el m ét odo al que har á r efer encia: Dim saludando As New Saludo(AddressOf mostrarSaludo) Y ahor a... ¿cóm o podem os usar esa var iable? La var iable saludando r ealm ent e est á apunt ando a un m ét odo y ese m ét odo r ecibe un valor de t ipo cadena, por t ant o si quer em os llam ar a ese m ét odo ( par a que se ej ecut e el código que cont iene) , t endr em os que indicar le el valor del ar gum ent o, sabiendo est o, la llam ada podr ía ser de est a for m a: saludando("Pepe") Y efect ivam ent e, así se m ost r ar ía por la consola el saludo ( Hola) y el valor indicado com o ar gum ent o. Realm ent e lo que hacem os con esa llam ada es acceder al m ét odo al que apunt a la var iable y com o ese m ét odo r ecibe un par ám et r o, debem os pasár selo, en cuant o lo hacem os, el r unt im e de .NET se encar ga de localizar el m ét odo y pasar le el ar gum ent o, de for m a que se ej ecut e de la m ism a for m a que si lo llam ásem os dir ect am ent e: mostrarSaludo("Pepe") Con la difer encia de que la var iable "saludando" no t iene por qué saber a qué m ét odo est á llam ando, y lo m ás im por t ant e, no sabe dónde est á definido ese m ét odo, solo sabe que el m ét odo r ecibe un par ám et r o de t ipo cadena y apar t e de esa infor m ación, no t iene por qué saber nada m ás. Así es com o funcionan los event os, un event o solo t iene la dir ección de m em or ia de un m ét odo, ese m ét odo r ecibe los m ism os par ám et r os que los definidos por el event o ( r ealm ent e por el delegado) , cuando pr oducim os el event o con RaiseEvent es com o si llam ár am os a cada uno de los m ét odos que se han ido agr egando al delegado, si es que se ha agr egado alguno, ya que en caso de que no haya ningún m ét odo asociado a ese event o, ést e no se pr oducir á, por la sencilla r azón de que no habr á ningún código al que llam ar . Realm ent e es com plicado y, salvo que lo necesit em os par a casos especiales, no ser á m uy habit ual que usem os los delegados de est a for m a, aunque no est á de m ás saber lo, sobr e t odo si de así com pr endem os m ej or cóm o funcionan los event os. Par a t er m inar con est a lección sobr e los event os y los delegados, vam os a ver ot r a for m a de definir un event o. Est a no es exclusiva de Visual Basic, ya que el lenguaj e C# , com pañer o insepar able en los ent or nos de Visual St udio 2010, t am bién t iene est a car act er íst ica, per o aunque pueda par ecer ext r año, es m enos pot ent e que la de Visual Basic; por m edio de est a declar ación, t al com o indicam os en el t ít ulo de la sección, t endr em os m ayor infor m ación sobr e cóm o se declar a el event o, cóm o se dest r uye e incluso cóm o se pr oduce, es lo que la docum ent ación de Visual Basic llam a event o per sonalizado ( Cust om Event ) . Cuando declar am os un event o usando la inst r ucción Cust om est am os definiendo t r es bloques de código que nos per m it e int er cept ar el m om ent o en que se pr oduce cualquier a de las t r es acciones posibles con un event o: 1. Cuando se "liga" el event o con un m ét odo, ya sea por m edio de AddHandler o m ediant e Handles 2. Cuando se desliga el event o de un m ét odo, por m edio de Rem oveHandler 3. Cuando se pr oduce el event o, al llam ar a RaiseEvent Par a declar ar est e t ipo de event o, siem pr e debem os hacer lo por m edio de un delegado. Veam os un ej em plo de una declar ación de un event o usando Cust om Event : Public Delegate Sub ApellidosCambiadosEventHandler(ByVal nuevo As String) Public Custom Event ApellidosCambiados As ApellidosCambiadosEventHandler AddHandler(ByVal value As ApellidosCambiadosEventHandler) ' este bloque se ejecutará cada vez que asignemos un método al evento End AddHandler RemoveHandler(ByVal value As ApellidosCambiadosEventHandler) ' este bloque se ejecutará cuando se desligue el evento de un método End RemoveHandler RaiseEvent(ByVal nuevo As String) ' este bloque se ejecutará cada vez que se produzca el evento End RaiseEvent End Event Com o podem os apr eciar , debem os definir un delegado con la "fir m a" del m ét odo a usar con el event o. Después definim os el event o por m edio de las inst r ucciones Cust om Event , ut ilizando el m ism o for m at o que al definir un event o con un delegado. Dent r o de la definición t enem os t r es bloques, cada uno de los cuales r ealizar á la acción que ya hem os indicado en la list a num er ada. N ot a: Los event os Cust om Event solam ent e podem os definir los e int er cept ar los en el m ism o ensam blado. Est a es la definición que nos da la ayuda de Visual Basic sobr e lo que es un at r ibut o. Los at r ibut os son et iquet as descr ipt ivas que pr opor cionan infor m ación adicional sobr e elem ent os de pr ogr am ación com o t ipos, cam pos, m ét odos y pr opiedades. Ot r as aplicaciones, com o el com pilador de Visual Basic, pueden hacer r efer encia a la infor m ación adicional en at r ibut os par a det er m inar cóm o pueden ut ilizar se est os elem ent os. En est a lección ver em os algunos ej em plos de cóm o usar los en nuest r as pr opias aplicaciones y, aunque sea de for m a gener al, cóm o usar y aplicar algunos de los at r ibut os definidos en el pr opio .NET Fr am ewor k, al m enos los que m ás dir ect am ent e nos pueden int er esar a los desar r ollador es de Visual Basic. At r ibut os At r ibu t os At r ibut os par a r epr esent ar infor m ación de n uest r a aplicación Most r ar los ficher os ocult os del pr oyect o Tipos de at r ibut os que podem os usar en una aplicación At r ibut os globales a la aplicación At r ibut os par t icular es a las clases o m iem br os de las clases At r ibut os per sonalizados Acceder a los at r ibut os per sonalizados en t iem po de ej ecución At r ibut os específicos de Visual Basic Mar car cier t os m iem br os de una clase com o obsolet os Com o hem os com ent ado en la int r oducción, los at r ibut os son et iquet as que podem os aplicar a nuest r o código par a que el com pilador y, por ext ensión, el pr opio .NET Fr am ewor k los pueda usar par a r ealizar cier t as t ar eas o par a obt ener infor m ación ext r a sobr e nuest r o código. De hecho en cualquier aplicación que cr eem os con Visual Basic 2010 est ar em os t r at ando con at r ibut os, aunque nosot r os ni nos ent er em os, ya que el pr opio com pilador los ut iliza par a gener ar los m et adat os del ensam blado, es decir , la infor m ación sobr e t odo lo que cont iene el ej ecut able o libr er ía que hem os cr eado con Visual Basic 2010. Por ot r a par t e, el uso de los at r ibut os nos sir ve par a ofr ecer cier t a funcionalidad ext r a a nuest r o código, por ej em plo, cuando cr eam os nuest r os pr opios cont r oles, m ediant e at r ibut os podem os indicar le al diseñador de for m ular ios si debe m ost r ar cier t os m iem br os del cont r ol en la vent ana de pr opiedades, et c. At r ibut os pa r a r e pr e se nt a r infor m a ción de nue st r a a plica ción De for m a m ás genér ica podem os usar los at r ibut os par a indicar cier t as car act er íst icas de nuest r a aplicación, por ej em plo, el t ít ulo, la ver sión, et c. Todos est os at r ibut os los indicar em os com o "car act er íst icas" de nuest r a aplicación, y lo har em os sin ser dem asiados conscient es de que r ealm ent e est am os usando at r ibut os, ya que el pr opio Visual Basic los cont r ola m ediant e pr opiedades de la aplicación. Por ej em plo, si m ost r am os la vent ana de pr opiedades de nuest r o pr oyect o, ver figur a 2.24: Figur a 2 .2 4 . Pr opiedades de la aplicación Tendr em os acceso a las pr opiedades de la aplicación, com o el nom br e del ensam blado, el espacio de nom br es, et c. Si quer em os agr egar infor m ación ext r a, com o la ver sión, el copyr ight , et c. podem os pr esionar el bot ón "Assem bly I nfor m at ion", al hacer lo, se m ost r ar á una nueva vent ana en la que podem os escr ibir esa infor m ación, t al com o m ost r am os en la figur a 2.25: Figur a 2 .2 5 . I nfor m ación del ensam blado Esa infor m ación r ealm ent e est á definida en un ficher o del pr oyect o llam ado Assem bluI nfo.vb, el cual de for m a pr edet er m inada est á ocult o, si lo m ost r am os, ver em os que esa infor m ación la cont iene en for m at o de at r ibut os. Par t e del código de ese ficher o lo podem os ver en la figur a 2.26: Figur a 2 .2 6 . Cont enido del ficher o Assem blyI nfo En est e código podem os r esalt ar t r es cosas: La pr im er a es que t enem os una im por t ación al espacio de nom br es Syst em .Reflect ion, est e espacio de nom br es cont iene la definición de las clases/ at r ibut os ut ilizados par a indicar los at r ibut os de la aplicación, com o el t ít ulo, et c. La segunda es la for m a de usar los at r ibut os, est os deben ir encer r ados ent r e signos de m enor y m ayor : < Assem bly: Com Visible( False) > . La t er cer a es que, en est e caso, los at r ibut os est án definidos a nivel de ensam blado, par a ellos se añade la inst r ucción Assem bly: al at r ibut o. Com o ver em os a cont inuación, los at r ibut os t am bién pueden definir se a nivel local, es decir , solo aplicable al elem ent o en el que se ut iliza, por ej em plo, una clase o un m ét odo, et c. M ost r a r los fiche r os ocult os de l pr oy e ct o Com o acabam os de com ent ar , el ficher o Assem blyI nfo.vb que es el que cont iene la infor m ación sobr e la aplicación ( o ensam blado) , est á ocult o. Par a m ost r ar los ficher os ocult os, debem os hacer lo siguient e: En la vent ana del explor ador de soluciones, pr esionam os el segundo bot ón, ( si pasam os el cur sor por encim a, m ost r ar á un m ensaj e que indica "Most r ar t odos los ficher os") , de est a for m a t endr em os a la vist a t odos los ficher os de la aplicación, incluso el de los dir ect or ios en el que se cr ea el ej ecut able, t al com o podem os apr eciar en la figur a 2.27: Figur a 2 .2 7 . M ost r ar t odos los ficher os de la solución Tipos de a t r ibut os que pode m os usa r e n una a plica ción Com o hem os com ent ado, exist en at r ibut os que son globales a t oda la aplicación y ot r os que podr em os aplicar a elem ent os par t icular es, com o una clase o un m ét odo. At r ibu t os globa le s a la a plica ción Est os se indican usando Assem bly: en el at r ibut o y los podr em os usar en cualquier par t e de nuest r o código, aunque lo habit ual es usar los en el ficher o Assem blyI nfo.vb. N ot a: La palabr a o inst r ucción Assem bly: lo que indica es que el at r ibut o t iene un ám bit o de ensam blado. At r ibu t os pa r t icu la r e s a la s cla se s o m ie m br os de la s cla se s Est os at r ibut os solo se aplican a la clase o al m iem br o de la clase que cr eam os convenient e, el for m at o es par ecido a los at r ibut os globales, ya que se ut ilizan los signos de m enor y m ayor par a encer r ar lo, con la difer encia de que en est e t ipo de at r ibut os no debem os usar Assem bly: , ya que est a inst r ucción indica que el at r ibut o es a nivel del ensam blado. Cuando aplicam os un at r ibut o "par t icular ", est e debe est ar en la m ism a línea del elem ent o al que se aplica, aunque si quer em os dar le m ayor legibilidad al código podem os usar un guión baj o par a que el código cont inúe en ot r a línea: <Microsoft.VisualBasic.HideModuleName()> _ Module MyResources At r ibut os pe r sona liza dos Adem ás de los at r ibut os que ya est án pr edefinidos en el pr opio .NET o Visual Basic, podem os cr ear nuest r os pr opios at r ibut os, de for m a que en t iem po de ej ecución podam os acceder a ellos m ediant e las clases del espacio de nom br es Reflect ion, aunque debido a que est e t em a se sale un poco de la int ención de est e cur so, sim plem ent e indicar que los at r ibut os per sonalizados son clases que se der ivan de la clase Syst em .At t r ibut e y que podem os definir las pr opiedades que cr eam os convenient e ut ilizar en ese at r ibut o par a indicar cier t a infor m ación a la que podem os acceder en t iem po de ej ecución. En el siguient e código t enem os la declar ación de una clase que se ut ilizar á com o at r ibut o per sonalizado, not am os que, por definición las clases par a usar las com o at r ibut os deben t er m inar con la palabr a At t r ibut e después del nom br e "r eal" de la clase, que com o ver em os en el código que ut iliza ese at r ibut o, esa "ext ensión" al nom br e de la clase no se ut iliza. Veam os pr im er o el código del at r ibut o per sonalizado: <AttributeUsage(AttributeTargets.All)> _ Public Class AutorAttribute Inherits System.Attribute ' Private _ModificadoPor As String Private _Version As String Private _Fecha As String ' Public Property ModificadoPor() As String Get Return _ModificadoPor End Get Set(ByVal value As String) _ModificadoPor = value End Set End Property ' Public Property Version() As String Get Return _Version End Get Set(ByVal value As String) _Version = value End Set End Property ' Public Property Fecha() As String Get Return _Fecha End Get Set(ByVal value As String) _Fecha = value End Set End Property End Class Par a usar est e at r ibut o lo podem os hacer de la siguient e for m a: <Autor(ModificadoPor:="Guillermo 'guille'", _ Version:="1.0.0.0", Fecha:="13/Abr/2005")> _ Public Class PruebaAtributos N ot a: Cuando ut ilizam os el at r ibut o, en el const r uct or que de for m a pr edet er m inada cr ea Visual Basic, los par ám et r os se indican por el or den alfabét ico de las pr opiedades, per o que nosot r os podem os alt er ar usando dir ect am ent e los nom br es de las pr opiedades, t al com o podem os ver en el código de ej em plo ant er ior . Acce de r a los a t r ibu t os pe r son a liza dos e n t ie m po de e j e cu ción Par a acceder a los at r ibut os per sonalizados podem os hacer algo com o est o, ( suponiendo que t enem os la clase Aut or At t r ibut e y una clase llam ada Pr uebaAt r ibut os a la que hem os aplicado ese at r ibut o per sonalizado) : Sub Main() Dim tipo As Type tipo = GetType(PruebaAtributos) Dim atributos() As Attribute atributos = Attribute.GetCustomAttributes(tipo) For Each atr As Attribute In atributos If TypeOf atr Is AutorAttribute Then Dim aut As AutorAttribute aut = CType(atr, AutorAttribute) Console.WriteLine("Modificado por: " & aut.ModificadoPor) Console.WriteLine("Fecha: " & aut.Fecha) Console.WriteLine("Versión: " & aut.Version) End If Next End Sub At r ibut os e spe cíficos de Visua l Ba sic Visual Basic ut iliza una ser ie de at r ibut os par a indicar cier t as car act er íst icas de nuest r o código, en par t icular son t r es: COM ClassAt t r ibut e Est e at r ibut o se ut iliza par a sim plificar la cr eación de com ponent es COM desde Visual Basic. VBFixedSt r ingAt t r ibut e Est e at r ibut o se ut iliza par a cr ear cadenas de longit ud fij a en Visual Basic 2010. Habit ualm ent e se aplica a cam pos o m iem br os de una est r uct ur a, pr incipalm ent e cuando quer em os acceder al API de Windows o cuando quer em os usar esa est r uct ur a par a guar dar infor m ación en un ficher o, per o ut ilizando una cant idad fij a de car act er es. VBFixedAr r ayAt t r ibut e Est e at r ibut o, al igual que el ant er ior , lo podr em os usar par a declar ar ar r ays de t am año fij o, al m enos si las declar am os en una est r uct ur a, ya que por defect o, los ar r ays de Visual Basic son de t am año var iable. M a r ca r cie r t os m ie m br os de u n a cla se com o obsole t os En ocasiones nos encont r ar em os que escr ibim os cier t o código que post er ior m ent e no quer em os que se ut ilice, por ej em plo por que hem os cr eado una ver sión opt im izada. Si ese código lo hem os declar ado en una int er faz, no deber íam os elim inar lo de ella, ya que así r om per íam os el cont r at o cont r aído por las clases que im plem ent an esa int er faz. En est os casos nos puede venir m uy bien el uso del at r ibut o < Obsolet e> , ya que así podem os infor m ar al usuar io de que ese at r ibut o no deber ía usar lo. En el const r uct or de est e at r ibut o podem os indicar la cadena que se m ost r ar á al usuar io. En el siguient e código se declar a un m ét odo con el at r ibut o Obsolet e: Public Interface IPruebaObsoleto <Obsolete("Este método ya está obsoleto, utiliza el método Mostrar")> _ Sub MostrarNombre() Sub Mostrar() End Interface Si t r abaj am os con el I DE de Visual Basic, ese m ensaj e se m ost r ar á al com pilar o ut ilizar los at r ibut os m ar cados com o obsolet os, t al com o podem os apr eciar en la figur a 2.28: Figur a 2 .2 8 . M ensaj e de que un m ét odo e st á obsolet o Módulo 3 - Desarrollo de aplicaciones Windows En este módulo, conoceremos las partes generales y más importantes del entorno de desarrollo rápido Visual Studio 2010 para la programación de aplicaciones con este lenguaje de la familia .NET. Veremos las partes principales del entorno, también veremos como desarrollar nuestros propios controles Windows, aprenderemos a trabajar con imágenes y gráficos con Visual Basic y finalmente, conoceremos como desplegar nuestras aplicaciones desarrolladas en Visual Basic 2010. FAQ: ¿Qué tipo de aplicaciones puedo desarrollar si estoy utilizando Visual Basic 2010 Express? Podr á desar r ollar pr incipalm ent e, Aplicaciones par a W indow s, Bibliot ecas de Clases y Aplicaciones de Consola . Adem ás, podr á añadir sus pr opias plant illas par a obt ener un m ayor r endim ient o en el desar r ollo de aplicaciones. Si su int er és es el desar r ollo de aplicaciones Web, puede ut ilizar Visual W eb D eveloper 2 0 1 0 Expr ess. Productos Visual Studio Express Las partes que forman parte de este módulo son las siguientes: Capítulo 1 ● Uso del diseñador de Visual Studio Capítulo 2 ● Controles de Windows Forms Capítulo 3 ● Desarrollo de controles Capítulo 4 ● Trabajo con imágenes y gráficos Capítulo 5 ● Despliegue de aplicaciones Introducción Cuando nos encontramos con Visual Studio 2010 por primera vez, saltan a la vista, algunos de los cambios más importantes de este novedoso entorno de desarrollo de aplicaciones Windows. Para un desarrollador, familiarizarse con el entorno de Visual Studio 2010 es una tarea que no debe entrañar una complejidad excesivamente grande. Como nos ocurre a todos los que nos encontramos delante de un nuevo entorno de trabajo, lo único que se requiere es constancia y práctica, mucha práctica. Sin embargo, si usted es ya un desarrollador habitual de otros entornos de desarrollo, notará que sus avances van a ser significativos en muy poco tiempo. Sobre Visual Studio 2010, cabe destacar que el entorno de desarrollo ha sido reprogramado por completo utilizando las bondades de WPF (Windows Presentation Foundation). El entorno en sí no ha sufrido grandes cambios salvo las posibilidades de WPF que son mayores de cara al usuario, aunque sus funcionalidades siguen siendo las mismas. N ot a: Si está utilizando Visual Basic 2010 Express para seguir este curso debe saber que este entorno está especializado en desarrollar aplicaciones Windows con Visual Basic 2010, aunque podrá usar controles y librerías escritas en otros lenguajes de la plataforma .NET . Módulo 3 - Capítulo 1 ● 1. Cuadro de herramientas ● 2. Explorador de base de datos ● 3. Explorador de soluciones ● 4. Propiedades ● 5. Menus y barra de botones ● 6. Otras consideraciones Módulo 3 - Capítulo 1 1. Cuadro de herramientas El cuadr o o bar r a de her r am ient as de Visual St udio 2010, nos per m it e ut ilizar los dist int os com ponent es que . NET Fr am ew or k pone a nuest r a disposición. Dent r o de Visual St udio 2010 t enem os una gr an cant idad de cont r oles dispuest os en difer ent es cat egor ías. En la figur a 1 podem os v er la bar r a de her r am ient as de Visual St udio 2010. Visua l St udio 2 0 1 0 Figur a 1 El Cuadro de herramientas, lo localizar á en la par t e izquier da del ent or no Visual Studio 2010. Cuando iniciam os un nuev o pr oy ect o con Visual St udio 2010, el cuadr o de her r am ient as queda r ellenado con los cont r oles que podem os ut ilizar en el pr oy ect o. Si abr im os un for m ular io Window s, los cont r oles quedan habilit ados par a que los podam os inser t ar en el for m ular io Window s. En la figur a 2 se m uest r a la bar r a de her r am ient as con los cont r oles pr epar ados par a ser inser t ados en el for m ular io Window s. Toolbox de Visua l St udio 2 0 1 0 con cont role s W indow s pre pa ra dos pa ra se r inse rt a dos e n e l form ula rio W indow s Figur a 2 N ot a: Par a inser t ar u n cont r ol en un for m u lar io Windows, se r equier e que el for m u lar io Windows sobr e el que deseam os inser t ar un cont r ol, est é abier t o. Una vez que est á abier t o, bast ar á con r ealizar una de las t r es siguient es acciones par a inser t ar un cont r ol al for m ular io: ● Hacer doble clic sobre un control del cuadro de herramientas ● Hacer clic sobre un control del cuadro de herramientas, y sin soltar el botón del mouse, arrastrarlo sobre el formulario ● Hacer clic sobre un control del cuadro de herramientas, y luego hacer clic sobre el formulario y arrastrar para marcar una zona que cubrirá nuestro control y soltar el ratón El cont r ol quedar á ent onces inser t ado dent r o del for m ular io. Módulo 3 - Capítulo 1 2. Explorador de base de datos Si ha sido lo suficient em ent e obser v ador cuando se ex plicaban los det alles del cuadr o o bar r a de her r am ient as, y ha pr est ado especial at ención a las figur as o a las v ent anas del ent or no de desar r ollo de Visual St udio 2010, quizás hay a not ado que en la par t e izquier da adem ás de la solapa cuadr o de her r am ient as, apar ece ot r a solapa de nom br e ex plor ador de base de dat os. Desde est a solapa, un pr ogr am ador puede acceder a difer ent es r ecur sos del sist em a. El pr incipal y m ás im por t ant e r ecur so, es el que t iene que v er con las conex iones con bases de dat os, y a sean Micr osoft Access, Micr osoft SQL Ser v er o cualquier ot r a fuent e de dat os. En la figur a 1 puede obser v ar la solapa Ex plor ador de base de dat os ex t endida con par t e de sus opciones. La sola pa de l Ex plora dor de ba se de da t os de sple ga da de Visua l St udio 2 0 1 0 Figur a 1 Conect ando con una base de dat os M icr osoft Access a t r avés de SQL Ser ver Par a m uest r a un bot ón, y dado el car áct er pr áct ico de est e t ut or ial, apr ender á a cr ear una conex ión con cualquier base de dat os, en nuest r o caso de ej em plo una base de dat os Micr osoft SQL Ser v er , par a poder ut ilizar la fácilm ent e en nuest r a aplicación Window s. Haga clic sobr e el bot ón r epr esent ado por la siguient e im agen v ent ana com o la que se m uest r a en la figur a 2. . En est e inst ant e, se abr ir á una nuev a De est a m aner a se iniciar á un asist ent e par a configur ar el acceso a dat os. La pr im er a pant alla del asist ent e nos per m it e seleccionar la fuent e de dat os, y a sea desde un obj et o de dat os, desde un ser v icio o desde una fuent e de dat os det er m inada, que ser á lo m ás habit ual. En nuest r o caso, seleccionar em os est a opción. La siguient e v ent ana del asist ent e nos indica si quer em os seleccionar los dat os desde un Dat aSet o desde un m odelo de ent idad r elación, algo que se v er á m ás adelant e. Vam os a pr esuponer que obt enem os los dat os desde un Dat aSet . Si cont inuam os con el asist ent e, ést e nos indica en la siguient e v ent ana si quer em os seleccionar una conex ión ex ist ent e en el pr oy ect o, o si quer em os cr ear una nuev a conex ión. Si pulsam os sobr e el bot ón de nuev a conex ión, acceder em os a una v ent ana nuev a par a cr ear una nuev a conex ión. Ve nt a na Agre ga r cone x ión, pa ra e st a ble ce r la s propie da de s de cone x ión con una fue nt e de da t os Figur a 2 Por defect o, la v ent ana Ag r e g a r con e x ión no est á pr epar ada par a est ablecer una conex ión con una fuent e de dat os de or igen de dat os OLE DB o con SQL Ser v er , por lo que si nuest r a int ención es est ablecer una conex ión con est a fuent e de dat os, ent onces deber em os hacer clic sobr e el bot ón Ca m b ia r . . . que se indica en la figur a 3. Bot ón Ca m bia r... pa ra se le cciona r ot ro prov e e dor de orige n de da t os Figur a 3 De est a m aner a, podem os indicar el or igen de acceso a dat os que necesit am os par a est ablecer la conex ión con nuest r a fuent e de dat os, y que en nuest r o ej em plo ser á un pr ov eedor de SQL Ser v er . Una v ez que hem os hecho clic sobr e el bot ón Ca m b ia r . . . , nos asegur am os por lo t ant o, que nuest r o or igen de dat os es base de dat os de Micr osoft SQL Ser v er Dat abase File ( SqlClient ) , com o se indica en la figur a 4. Ve nt a na de se le cción de l prov e e dor u orige n de da t os Figur a 4 FAQ: ¿Puedo ut ilizar el pr oveedor OLE DB en lugar del pr oveedor de SQL Ser ver par a conect ar con una base de dat os SQL Ser ver ? Con OLE DB, puede acceder a fuent es de dat os SQL Ser ver u ot r as fuent es de dat os com o Micr osoft Access, sin em bar go, si ut iliza SQL Ser ver 7.0, SQL Ser ver 2000, SQL Ser ver 2005 ó super ior , se r ecom ienda el uso del pr oveedor de SQL Ser ver , que es un pr oveedor de acceso a dat os nat ivo que aum ent a el r endim ient o de nuest r as aplicaciones con SQL Ser ver . Sólo si ut iliza una ver sión de SQL Ser ver ant er ior a SQL Ser ver 7.0, deber á ut ilizar necesar iam ent e el pr oveedor de acceso a dat os OLE DB. Una v ez que hem os seleccionado el pr ov eedor de acceso a dat os, nos cent r ar em os en la opción N om b r e d e a r ch iv o b a se d e d a t os com o se m uest r a en la figur a 5. En e st e luga r indica re m os e l fiche ro de ba se de da t os con e l que e st a ble ce re m os la cone x ión Figur a 5 Par a agr egar el ficher o de base de dat os a la conex ión, pr esionar em os el bot ón Ex a m in a r . . . y seleccionar em os el ficher o de base de dat os de nuest r o disco dur o. De est a m aner a, la base de dat os quedar á indicada en la conex ión y t an sólo deber em os pr obar nuest r a conex ión pulsando el bot ón Pr ob a r con e x ión com o se indica en la figur a 6. Es re com e nda ble proba r la cone x ión a nt e s de a gre ga rla a l e nt orno Figur a 6 Si la pr ueba de conex ión se ha r ealizado sat isfact or iam ent e, r ecibir em os un m ensaj e en pant alla afir m at iv o com o el que se indica en la figur a 7. Prue ba de la cone x ión re a liz a da con é x it o Figur a 7 A t ener en cuent a: En est e ej em plo, la conexión con la base de dat os SQL Ser ver no t iene ningún t ipo de usuar io y cont r aseña. Tenga en cuent a que en la par t e ident ificada com o Conexión con la base de dat os, podr íam os indicar el usuar io y cont r aseña si fuer a necesar io. En est e punt o, el asist ent e podr ía pedir nos las t ablas, v ist as y obj et os de la fuent e de dat os par a que los seleccionar ám os según nuest r as necesidades. Cuando t er m inem os la selección de t odas las opciones, deber em os pr esionar sobr e el bot ón Ace p t a r par a que la base de dat os con la que hem os est ablecido la conex ión, quede ahor a inser t ada en la v ent ana del Ex p lor a d or d e b a se d e d a t os com o se m uest r a en la figur a 8. Ba se de da t os M icrosoft Acce ss inse rt a da e n la v e nt a na de l Ex plora dor de ba se de da t os Figur a 8 ¡Adver t encia!: Tener dem asiadas conexiones act ivas en el ent or no o configur adas en él, puede incidir negat ivam ent e en el r endim ient o de Visual St udio 2010 cuando se t r abaj a con él. Tenga configur adas solam ent e, aquellas conexiones que va a ut ilizar , o aquellas conexiones de uso m ás habit ual y fr ecuent e. Módulo 3 - Capítulo 1 3. Explorador de soluciones El Ex plor ador de soluciones lo podem os encont r ar en la par t e der echa de nuest r o ent or no de desar r ollo. Una solución se com pone de pr oy ect os y ést os, de r ecur sos y obj et os. Por lo gener al, una solución cont endr á un pr oy ect o, per o podem os encont r ar nos con m ás de un pr oy ect o dent r o de una m ism a solución. Sin em bar go, est os concept os son m uy sencillos de com pr ender y cont r olar , y par a nada debe hacer nos pensar que est o es algo com plej o que nos cost ar á m ucho t iem po dom inar . En la figur a 1, podem os obser v ar el ex plor ador de soluciones de Visual St udio 2010. La opción Ex plora dor de solucione s de sple ga da e n Visua l St udio 2 0 1 0 Figur a 1 Si quer em os añadir un nuev o for m ular io al pr oy ect o, lo har em os pr esionando con el bot ón secundar io en cualquier par t e de la v ent ana del ex plor ador de soluciones, per o si esa pulsación la hacem os en alguno de los obj et os que cont iene el pr oy ect o, no podr em os hacer lo, y a que el I DE de Visual St udio 2010 m uest r a un m enú difer ent e según el obj et o pr esionado, por ej em plo si quer em os añadir un nuev o pr oy ect o, podem os hacer lo pr esionando con el bot ón secundar io del m ouse sobr e la "solución". N ot a: Par a abr ir un r ecur so de la solución, bast a con sit uar nos en el r ecur so det er m inado, por ej em plo un for m ular io Windows de nom br e For m 1.vb y hacer doble clic sobr e él. El r ecur so se abr ir á aut om át icam ent e en Visual St udio 2010. Adem ás, en Visual St udio 2010 sabr em os en t odo m om ent o sobr e qué r ecur so est am os t r abaj ando en un m om ent o dado. Módulo 3 - Capítulo 1 4. Propiedades La v ent ana de pr opiedades la encont r ar em os en la par t e der echa y m ás abaj o de la v ent ana Ex p lor a d or d e solu cion e s en nuest r o ent or no de desar r ollo. Est a v ent ana nos per m it ir á acceder a las pr opiedades de los obj et os inser t ados en nuest r os for m ular ios Window s, com o se m uest r a en la figur a 1. Ve nt a na de Propie da de s de Visua l St udio 2 0 1 0 Figur a 1 Par a acceder a las pr opiedades de un det er m inado cont r ol, deber em os seleccionar el cont r ol en el for m ular io Window s y acudir a la v ent ana Pr op ie d a d e s, o bien, seleccionar el cont r ol en el for m ular io Window s y pr esionar la t ecla F4 . Módulo 3 - Capítulo 1 5. Menús y barra de botones Respect o a los m enús y bar r a de bot ones, son m uchas las opciones que t enem os disponibles, t al com o podem os com pr obar en la figur a 1. Las bar r as de bot ones son configur ables, adem ás de que podem os elegir las que quer em os que se m uest r en de for m a per m anent e en el ent or no de desar r ollo de Visual St udio 2010. Algunas de las bar r as de bot ones se m ost r ar án aut om át icam ent e según las t ar eas que est em os r ealizando, por ej em plo, cuando est am os en m odo depur ación o diseñando las t ablas de una base de dat os. Con el cont enido de los m enús ocur r e lo m ism o, según el elem ent o que t engam os seleccionado se m ost r ar án cier t as opciones que sea r elev ant es par a ese elem ent o del I DE de Visual St udio 2010. Los m e nús y ba rra s de bot one s de Visua l St udio 2 0 1 0 Figur a 1 Algunas de las opciones que t enem os en los m enús t am bién las podem os conseguir usando los m enús cont ex t uales (el m ost r ado al presionar con el bot ón secundar io del m ouse) , y com o es de esper ar , t am bién ser án difer ent es según el elem ent o sobr e el que hem os pr esionado. Por ej em plo, par a configur ar el pr oy ect o act ual, podem os elegir la opción Pr op ie d a d e s del m enú Pr oy e ct o o bien pr esionar con el bot ón secundar io del m ouse sobr e el pr oy ect o m ost r ado en el Ex plor ador de soluciones. Al seleccionar las pr opiedades del pr oy ect o, t endr em os una nuev a v ent ana desde la que podem os configur ar algunas de las car act er íst icas de nuest r o pr oy ect o. En la figur a 2, t enem os esa v ent ana de pr opiedades del pr oy ect o, en la que podem os apr eciar que est á div idida según el t ipo de configur ación que quer em os r ealizar , en est e caso concr et o las opciones de gener ación o com pilación del pr oy ect o. Propie da de s de l proy e ct o sobre la que se t ra ba j a e n Visua l Ba sic 2 0 1 0 Figur a 2 Com o v em os en la figur a 2, ex ist en sin em bar go m ult it ud de opciones y apar t ados difer ent es r elacionados t odos ellos con nuest r a solución. Ot r o de los apar t ados dest acables, es el apar t ado denom inado Pu b lica r . Aún así, ést e es el cor azón o par t e fundam ent al que debem os cont r olar a la hor a de desar r ollar una aplicación o a la hor a de gest ionar una solución, por que dent r o de est a v ent ana, se r esum e buena par t e de los m enús y bar r a de bot ones del ent or no de Visual St udio 2010. De t odos los m odos, t endr em os la opor t unidad de v er m ás adelant e, algunos usos de algunas de las opciones de la bar r a de bot ones del ent or no. Módulo 3 - Capítulo 1 6. Otras consideraciones El desarrollador que haya utilizado previamente otros entornos de desarrollo distinto a los de la familia de Visual Studio .NET, encontrará muy interesantes algunos de los cambios incorporados en Visual St udio 2010. Al principio, quizás se encuentre un poco desorientado, pero rápidamente y gracias a su experiencia en otros entornos de desarrollo, se acostumbrará al cambio. Entre algunos de estos cambios, destacaría los siguientes: ● En Visual St udio 2010, acceder a los objetos de nuestra aplicación es mucho más fácil. Dentro del entorno, observaremos que se van creando diferentes solapas que nos permite acceder y localizar los recursos con los que estamos trabajando de forma rápida. En la figura 1 podemos observar justamente esto que comento. Sola pa s de los obj e t os a bie rt os e n Visua l St udio 2 0 1 0 Figura 1 ● Visual Basic 2010 permite, hacer un St op & Go (editar y continuar), de nuestras aplicaciones, es decir, pausar la ejecución de una aplicación en modo depuración y modificar los valores o propiedades que deseemos y continuar ejecutándola. Esta opción que los programadores de Visual Basic 6 utilizan con mucha frecuencia en el desarrollo de sus aplicaciones, se ha mantenido en Visual Basic 2010, pero no en Visual Studio .NET 2002 y Visual Studio .NET 2003. Si por alguna razón, debe trabajar con alguno de estos entornos, debe saber que esta opción no está disponible para las versiones comentadas. ● Otra característica que debemos conocer de nuestro entorno de desarrollo, es la capacidad de anclar o fijar una ventana de las comentadas anteriormente o de permitir que se haga visible cuando acercamos el puntero del mouse sobre ella. Esta opción es la que puede verse en la figura 2. Opción de ocult a r o m ost ra r la v e nt a na se le cciona da e n Visua l St udio 2 0 1 0 Figura 2 Nótese que al presionar el icono indicado en la figura 2, haremos que esta ventana quede fija en el entorno de desarrollo. Cuando pulsamos este icono, la ventana queda fija y queda representado por un icono como el que se muestra en la figura 3. I cono pa ra ocult a r o m ost ra r la v e nt a na se le cciona da cua ndo se e ncue nt ra e n m odo a ncla do Figura 3 ● Algo que ocult a el entorno de Visual St udio 2010 por defecto, son las denominadas clases par ciales. Se trata de una característica añadida a .NET 2.0, que permite separ ar o par t ir una clase en varias porciones de código. La explicación ruda de esto, es que el programador puede tener dos ficheros de código fuente independientes, que posean el mismo nombre de clase. Para indicar que pertenece a la misma clase, ésta debe tener la palabra clave Pa r t ia l como parte de su definición para indicar que es una clase parcial. Un ejemplo que aclare esto es el siguiente: Public Class Class1 Public Function Accion1() As Integer Return 1 End Function End Class Partial Public Class Class1 Public Function Accion2() As Integer Return 2 End Function End Class El comportamiento de la clase es el de una única clase, por lo que su declaración y uso es como el de cualquier clase normal, tal y como se indica en el siguiente código: Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim MiClase As New Class1 MessageBox.Show(MiClase.Accion2.ToString() & vbCrLf & MiClase.Accion1.ToString()) End Sub End Class De todas las maneras, el entorno nos oculta muchas veces las clases parciales de un aplicación. Para ello, presionaremos la opción M ost r a r t od os los a r ch iv os de la ventana Ex plor ador de soluciones como se indica en la figura 4. I cono u opción pa ra m ost ra r t odos los a rchiv os de l proy e ct o Figura 4 De esta manera, podremos acceder a los archivos y recursos del proyecto, incluidas las clases parciales como se indica en la figura 5. En el archivo Form1.Designer.vb estará el código utilizado por el diseñador de formularios de Windows Forms, en el que se incluye la declaración de todos los controles y controladores de eventos que hemos definido en nuestro proyecto. Cla se pa rcia l m ost ra da e n los a rchiv os de l proy e ct o Figura 5 A t ener en cuent a: Cuando se gener a un pr oy ect o con Visual St udio 2010, el ent or no gener a difer ent es clases par ciales, com o por ej em plo la que se gener a par a un for m ular io. Introducción Dentro del entorno de desarrollo de Visual St udio 2010, nos encontramos un enorme conjunto de librerías y controles que podemos utilizar en nuestras aplicaciones Windows. Dependiendo del tipo de aplicación que llevemos a cabo, el entorno habilitará los controles correspondientes para cada tipo de aplicación. En nuestro caso, nos centraremos en los controles más habituales de Windows, e indicaremos como utilizarlos en nuestros desarrollos. En nuestro entorno de desarrollo, encontraremos diferentes grupos de controles o componentes dispuestos de ser utilizados. En la figura 1 encontraremos los grupos de controles y componentes más habituales. Grupos de cont role s e n Visua l St udio 2 0 1 0 Figura 1 Estos controles se dividen en los grupos representados en la figura anterior. A continuación veremos los más representativos. Módulo 3 - Capítulo 2 ● 1. Datos ● 2. Componentes ● 3. Controles comunes ● 4. General ● 5. Otras consideraciones Módulo 3 - Capítulo 2 1. Datos El gr upo Dat os cor r esponde con el gr upo que t iene r elación dir ect a con los com ponent es de acceso a dat os, com o se m uest r a en la figur a 1. Cont role s de Da t os e n Visua l St udio 2 0 1 0 Figur a 1 Par a m uchos desar r ollador es, los cont r oles, com ponent es y m ét odos de acceso a dat os, cont iene dent r o de sí un especial m ist er io, es com o el Sant o Gr ial de la pr ogr am ación. Casi siem pr e nos at ascam os ahí, siem pr e en el m ism o sit io. Per o no se pr eocupe ni lo m ás m ínim o por ello, apr ender em os a ut ilizar los a base de pr áct ica, y lo que es m ás im por t ant e, los dom inar em os r ápidam ent e. Solo com o cur iosidad y por ahor a, le pr esent ar é uno de los com ponent es m ás dest acables en Visual St udio 2010, por su sem ej anza con ot r o m uy ut ilizado en "ot r os" ent or nos de desar r ollo, est oy hablando del cont r ol y com ponent e Bin d in g N a v ig a t or que usar em os fr ecuent em ent e en nuest r as aplicaciones con acceso a fuent es de dat os. Est e cont r ol inser t ado en un for m ular io Window s, es el que se puede v er en la figur a 2. Cont rol BindingNa v iga t or inse rt a do e n un form ula rio W indow s e n Visua l St udio 2 0 1 0 Figur a 2 Com o puede obser v ar , est e cont r ol, t iene un aspect o m uy sim ilar al del fam oso Recor dset de Visual Basic 6 o al Dat aNav igat or de Bor land. Lógicam ent e, est e cont r ol t iene un aspect o m ucho m ás v ist oso y m oder no, per o es uno de los cont r oles est r ella de Visual Basic 2005 y que t am bién est án incluidos en Visual St udio 2010, y a que en Visual St udio . NET 2002 y Visual St udio . NET 2003 no ex ist ía est e cont r ol en el ent or no. Desde Visual St udio 2005 y por lo t ant o, desde Visual Basic 2005, t enem os la posibilidad de t r abaj ar con el cont r ol Bin d in g N a v ig a t or . Com unidad dot N et : Visual St udio 2010 le pr opor ciona un am plio conj unt o de cont r oles y com ponent es así com o un no m enos com plet o conj unt o de clases que le facilit a al desar r ollador las t ar eas de pr ogr am ación r equer idas. Sin em bar go, exist en cont r ibuciones gr at uit as y ot r as de pago, que el pr ogr am ador puede ut ilizar según lo r equier a. A cont inuación le indico el que a m i m odo de ver es el lugar m ás r epr esent at ivo de est e t ipo de cont r ibuciones a la Com unidad de desar r ollador es .NET. Micro so ft Co dePlex Módulo 3 - Capítulo 2 2. Componentes Window s For m s incluy e un conj unt o de com ponent es m uy nut r ido y v ar iado. Algunos de est os com ponent es, han sido m ej or ados y ot r os am pliados. En la figur a 1 podem os obser v ar est os com ponent es. Com pone nt e s de W indow s Form s Figur a 1 Los com ponent es son com o cont r oles no v isibles, o dicho de ot r a for m a, son cont r oles que r ealizan cier t as t ar eas, per o no t ienen un int er faz que m ost r ar , com o puede ser el caso de un bot ón o una caj a de t ex t os. Por ej em plo, el com ponent e Tim er nos per m it e r ecibir una not ificación cada x t iem po, per o no m uest r a nada al usuar io de nuest r a aplicación. Si hacem os doble clic sobr e el com ponent e Tim er par a inser t ar lo en el for m ular io, ést e quedar á dispuest o en la par t e infer ior del for m ular io com o se indica en la figur a 2. Cont rol Tim e r inse rt a do e n un form ula rio de W indow s Form s Figur a 2 Est e t ipo de com ponent es no son v isibles en t iem po de ej ecución. Módulo 3 - Capítulo 2 3. Controles comunes Con est e nom br e, se aglut inan los cont r oles m ás gener ales y v ar iados que podem os ut ilizar en nuest r as aplicaciones Window s. Ser ía algo así, com o el r est o de cont r oles y com ponent es no cont enidos en ninguna de las secciones que hem os v ist o ant er ior m ent e, aunque est o no es siem pr e así. Por esa r azón, si encuent r a dos cont r oles o com ponent es iguales en dos o m ás secciones, no lo t enga en consider ación. Digam os que en est a solapa se aglut inan por lo t ant o, los cont r oles que ut ilizar em os con m ás fr ecuencia. En la figur a 1 podem os obser v ar los cont r oles y com ponent es cit ados. Cont role s W indow s Form s e n Visua l St udio 2 0 1 0 Figur a 1 Debido a la cant idad de cont r oles y com ponent es de los dist int os gr upos del Cuadr o de her r am ient as, podem os usar el siguient e t r uco par a que nos r esult e m ás fácil su localización. Tr uco: Com o puede obser var , a veces cuest a localizar un cont r ol debido a la enor m e cant idad de cont r oles que hay. Par a or denar los, puede ar r ast r ar y solt ar los cont r oles y com ponent es en la bar r a de her r am ient as o bien, si quier e hacer una or denación por or den alfabét ico, puede hacer clic con el bot ón secundar io del m ouse sobr e una det er m inada sección de cont r oles y seleccionar la opción Or denar elem ent os alfabét icam ent e com o se indica en la siguient e figur a siguient e: Los cont r oles y com ponent es de esa sección quedar án or denados alfabét icam ent e. Lo m ás dest acable par a el desar r ollador habit uado a ot r os ent or nos, es que aquí v er em os una gr an cant idad de cont r oles que nos r esult ar án m uy fam iliar es. Cont r oles com o: La b e l, Pict u r e Box , Te x t Box , Fr a m e que ahor a pasa a llam ar se Gr ou p Box , Com m a n d Bu t t on que ahor a pasa a llam ar se Bu t t on , Ch e ck Box , Op t ion Bu t t on que ahor a pasa a llam ar se Ra d ioBu t t on , Com b oBox , List Box , H Scr ollBa r , V Scr ollBa r , Tim e r , et c. Per o adem ás t enem os m uchos ot r os que no son t an habit uales en t odos los ent or nos de desar r ollo difer ent es de Visual St udio . NET. Cont r oles que pr opor cionan nuev as y v ent aj osas car act er íst icas a la hor a de desar r ollar aplicaciones con Visual Basic 2010. Ent r e est os cont r oles, podem os encont r ar el cont r ol Pr in t D ocu m e n t y Pr in t Pr e v ie w Con t r ol, par a im pr im ir y r ealizar v ist as pr elim inar es, Er r or Pr ov id e r , W e b Br ow se r , Fold e r Br ow se r D ia log , ToolTip par a apor t ar t oolt ips a nuest r os cont r oles, Tr a ck Ba r , N u m e r icU p D ow n , Sp lit Con t a in e r , M on t h Ca le n d a r , D a t e Tim e Pick e r , et c. Cada uno de los cont r oles, t iene unas car act er íst icas y cualidades det er m inadas. Sólo a base de pr áct ica, apr ender em os a ut ilizar los y lo único que debem os saber , es cuál de ellos ut ilizar en un m om ent o dado. El abanico de cont r oles y com ponent es es lo suficient em ent e am plio com o par a poder abor dar con ellos, cualquier t ipo de pr oy ect o y aplicación Window s que nos sea dem andada. Módulo 3 - Capítulo 2 4. General Est a sección es com o el caj ón desast r e, un lugar dónde podem os inser t ar ot r os cont r oles o com ponent es desar r ollados por t er cer os, por ej em plo. Se cción Ge ne ra l e n Visua l St udio 2 0 1 0 Figur a 1 Est a sección de t odos los m odos, la puede ut ilizar un desar r ollador en m uchos casos. Por ej em plo, los desar r ollador es que desean ar r ast r ar y solt ar aquí los cont r oles y com ponent es que m ás ut iliza o los que ut iliza en un det er m inado pr oy ect o. Ot r o caso de ej em plo es cuando se t r abaj a con cont r oles o com ponent es sim ilar es desar r ollados por dos em pr esas difer ent es que quer em os t ener localizados o separ ados par a no m ezclar los. En ot r as cir cunst ancias, t am poco es r ar o encont r ar se con cont r oles o com ponent es con iconos sim ilar es, por lo que aclar ar se cuál es el que nos int er esa puede ser una t ar ea obligada. Aún así, ot r a de las posibilidades con la que nos podem os encont r ar par a ut ilizar est a sección es la de t ener que ut ilizar un cont r ol o com ponent e cir cunst ancialm ent e en un m om ent o dado, y por eso, que no deseem os añadir est e cont r ol o com ponent e a ot r a sección com o la de Cont r oles com unes por ej em plo. Ut ilice por lo t ant o est a sección com o lo consider e opor t uno. Módulo 3 - Capítulo 2 5. Otras consideraciones La sección Gener al nos indica un r eposit or io de ám bit o y car áct er gener al, sin em bar go, el desar r ollador puede quer er or denar su pr opio r eposit or io o sección de cont r oles y com ponent es. M a nipula ndo e l Cua dr o de he r r a m ie nt a s Par a ello, nos posicionar em os en la bar r a de her r am ient as y pr esionar em os el bot ón secundar io del m ouse sobr e la par t e gr is de la bar r a de her r am ient as desplegada y seleccionar em os la opción Agr egar ficha del m enú em er gent e, com o se m uest r a en la figur a 1. Opción de pe rsona liza ción de nue st ros propios grupos de cont role s y com pone nt e s Figur a 1 Cuando seleccionam os est a opción, apar ecer á una caj a de t ex t o en la bar r a de her r am ient as dónde podr em os escr ibir el nom br e que consider em os opor t uno, com o se m uest r a en la figur a 2. Pe rsona liz a ción de un grupo de cont role s y com pone nt e s e n Visua l St udio 2 0 1 0 Figur a 2 Si se hace la siguient e pr egunt a, ¿cóm o cam biar el nom br e de una sección y a cr eada o una ex ist ent e?, sepa que deber á r ealizar los siguient e pasos. Haga clic con el bot ón secundar io del m ouse sobr e la sección sobr e la que desea cam biar el nom br e y seleccione la opción Ca m b ia r n om b r e d e f ich a com o se m uest r a en la figur a 3. Figur a 3 De igual for m a, puede cam biar t am bién el nom br e de los cont r oles o com ponent es inser t ados. Par a hacer eso, haga clic con el bot ón secundar io del m ouse sobr e un cont r ol o com ponent e y seleccione la opción Ca m b ia r n om b r e d e e le m e n t o com o se m uest r a en la figur a 4. Figur a 4 Visual Basic 2010, nos pr opor ciona un am plio conj unt o de opciones de per sonalización del ent or no de t r abaj o, par a que se aj ust e a las ex igencias de los desar r ollador es. FAQ: ¿Qué ocur r e si m e equiv oco per sonalizando m i bar r a de her r am ient as? Visual St udio 2010 nos pr opor ciona la posibilidad de r eset ear o r est aur ar el est ado inicial de la bar r a de her r am ient as en el ent or no de desar r ollo. Par a hacer est o, har em os clic con el bot ón secundar io del m ouse la bar r a de her r am ient as y seleccionar em os la opción Rest ablecer cuadr o de her r am ient as del m enú em er gent e, com o se m uest r a en la siguient e figur a. ¡Oj o!, al seleccionar est a opción, per der em os t odas las m odificaciones que hay am os r ealizado sobr e la bar r a de her r am ient as. Ot r os cont r ole s a t e ne r e n cue nt a Dent r o del ent or no de Visual St udio 2010 y en . NET en gener al, t enem os la posibilidad de ut ilizar difer ent es cont r oles m uy int er esant es que conv iene com ent ar . Uno de est os cont r oles, se llam a WebBr ow ser , t al y com o se indica en la figur a 5. Cont rol W e bBrow se r e n e l Cua dro de he rra m ie nt a s Figur a 5 Est e cont r ol es la r epr esent ación de un cont r ol específico par a m ost r ar cont enido XML o cont enido HTML, com o si de una página Web se t r at ar a. Sir v a el siguient e ej em plo de código fuent e par a dem ost r ar com o usar el cont r ol y com o se m uest r a dicho cont r ol en una aplicación Window s. El código de la aplicación quedar ía com o se det alla a cont inuación: Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.webBrowser1.Navigate("http://localhost/Bienvenido.aspx") End Sub End Class Form1 Nuest r o ej em plo en ej ecución es el que se m uest r a en la figur a 6. Cont rol W e bBrow se r e n e j e cución Figur a 6 Hay m ás cont r oles que r epr esent an una nov edad par a el desar r ollador de . NET, com o puede ser por ej em plo, el cont r ol M a sk e d Te x t Box , com o se m uest r a en la figur a 7. Cont rol M a sk e dTe x t Box e n Visua l Ba sic 2 0 1 0 Figur a 7 Sin em bar go, hay ot r os cont r oles clásicam ent e dem andados por los desar r ollador es, com o los cont r oles de accesos a puer t os COM y puer t os ser ie, com o es el caso del cont r ol Se r ia lPor t que se m uest r a en la figur a 8. Cont rol Se ria lPort e n Visua l Ba sic 2 0 1 0 Figur a 8 No es cuest ión de r epasar cada uno de los cont r oles que el pr ogr am ador puede encont r ar en Visual St udio 2010, sin em bar go, no m e gust ar ía dej ar de com ent ar , uno de los cont r oles m ás usados y út iles par a las aplicaciones Window s, que t iene a su v ez su equiv alent e par a el desar r ollo de aplicaciones Web en ASP. NET. Me r efier o al cont r ol M on t h Ca le n d a r que se m uest r a en la figur a 9. Cont rol M ont hCa le nda r e n Visua l Ba sic 2 0 1 0 Figur a 9 Est e cont r ol, que se m uest r a en la figur a 10 cuando lo inser t am os en un for m ular io, es un cont r ol que nos facilit a la ent r ada de fechas en el sist em a y per m it e asegur ar nos, que la fecha seleccionada es una fecha v álida. Cont rol M ont hCa le nda r inse rt a do e n un form ula rio W indow s Figur a 10 Ot r os cont r oles añadidos en Visual St udio 2010 y en concr et o par a Visual Basic 2010, son los cont r oles del Pow er Pack . Est os cont r oles diseñados por el equipo de t r abaj o de Visual Basic, se podían descar gar e inst alar de for m a independient e en el sist em a, sin em bar go, en Visual St udio 2010 est os cont r oles se han incor por ado dir ect am ent e sin necesidad de descar gar los de for m a separ ada. Cont role s Pow e rPa ck de W indow s e n Visua l Ba sic Figur a 11 Introducción Hasta ahora, hemos aprendido a identificar las partes más importantes del entorno de desarrollo de Visual St udio 2010, hemos visto igualmente como se separan los controles y componentes, y hemos visto también que existe un grupo de solapas donde podemos añadir nuestros propios controles y componentes, incluso hemos aprendido a crear nuestro propio grupo o sección de controles y componentes, en el que podemos también incluir los controles y componentes que por ejemplo hayamos desarrollado nosotros mismos, sin embargo, para poder insertar ahí un control o componente desarrollado por nosotros, deberíamos aprender a crearlos. Eso es justamente lo que veremos a continuación además de ver otras técnicas que conviene repasar antes de aprender a desarrollar nuestros propios controles y componentes. Por eso, lo primero que haremos será aprender a desenvolvernos adecuadamente en el entorno de desarrollo con los controles que ya conocemos. Módulo 3 - Capítulo 3 ● 1. Dominando los controles en el entorno de trabajo ● 2. Creación de controles en tiempo de ejecución ● 3. Creación de una matriz de controles ● 4. Creación de controles nuevos ● 5. Otras consideraciones Módulo 3 - Capítulo 3 1. Dominando los controles en el entorno de trabajo Si quer em os apr ender a cr ear nuest r os pr opios cont r oles par a poder dist r ibuir los y ut ilizar los en nuest r o ent or no, lo m ej or es dom inar el uso de los cont r oles en nuest r o ent or no de desar r ollo. Ya hem os v ist o ant er ior m ent e com o inser t ar un cont r ol a nuest r o for m ular io, per o quizás no sepam os com o m anej ar los de for m a eficient e en ese for m ular io. I nser t e en un for m ular io Window s por ej em plo, t r es cont r oles Bu t t on com o se m uest r a en la figur a 1. Cont role s But t on inse rt a dos e n un form ula rio W indow s Figur a 1 Com o podem os obser v ar , los cont r oles est án dispuest os de una for m a desor denada, y a que al inser t ar los por ej em plo haciendo doble clic t r es v eces sobr e un cont r ol Bu t t on , ést os quedan dispuest os anár quicam ent e en el for m ular io. Separ e los cont r oles Bu t t on de for m a que queden ahor a espar cidos en el for m ular io de alguna m aner a t al y com o se m uest r a en la figur a 2. Cont role s But t on se pa ra dos e n e l form ula rio Figur a 2 Seleccione t odos los cont r oles Bu t t on com o se m ost r aba en la figur a 2 y seleccione del m enú las opciones For m a t o > Alin e a r > La d os iz q u ie r d os com o se indica en la figur a 3. Los cont role s But t on que da rá n orde na dos corre ct a m e nt e de nt ro de l form ula rio Figur a 3 Sin em bar go, podem os ex t ender el uso de las pr opiedades especiales par a alinear los cont r oles en un for m ular io. Por ej em plo, ahor a que t enem os los cont r oles Bu t t on alienados cor r ect am ent e, podem os hacer uso de la opción de m enú For m a t o > Esp a cia d o v e r t ica l > Qu it a r com o se indica en la figur a 4. Ot ra s opcione s e spe cia le s, nos pe rm it e n a line a r o t ra ba j a r con los cont role s de form a rá pida y se gura Figur a 4 En est e caso, los cont r oles quedar án dispuest os en el for m ular io com o se indica en la figur a 5. Cont role s a line a dos y e spa cia dos se gún la e le cción de opcione s de l e nt orno Figur a 5 Com o podem os apr eciar , alinear los cont r oles en el ent or no es r ealm ent e sencillo. Visual St udio 2010 nos pr opor ciona una gr an cant idad de opciones par a llev ar a cabo est e t ipo de t ar eas. I ncluso si nos encont r am os con un cont r oles de difer ent e t am año ent r e sí com o se m uest r a en la figur a 6, podem os hacer uso de la opción del m enú For m a t o > I g u a la r t a m a ñ o per m it iéndonos cam biar el t am año de los cont r oles seleccionados dent r o del for m ular io Window s. Cont role s de dife re nt e s t a m a ños dispue st os e n e l form ula rio W indow s Figur a 6 El m enú que nos per m it e cam biar los t am años de los cont r oles inser t ados en un for m ular io posee difer ent es posibilidades. En nuest r o caso, seleccionar em os del m enú, la opción For m a t o > I g u a la r t a m a ñ o > Am b os t al y com o se m uest r a en la figur a 7. Ca m bia ndo los t a m a ños a ncho y a lt o de los cont role s se le cciona dos de un form ula rio Figur a 7 Una v ez seleccionada est a opción, los cont r oles se m odificar án con el m ism o t am año t al y com o se m uest r a en la figur a 8. Cont role s de l form ula rio con su t a m a ño m odifica do Figur a 8 Una v ez seleccionada est a opción, los cont r oles se m odificar án con el m ism o t am año t al y com o se m uest r a en la figur a 8. Tr uco: Suponiendo que t engam os t r es cont r oles But t on de difer ent es t am años y que quer am os que t odos t engan el m ism o t am año que el segundo de sus cont r oles, seleccionar em os siem pr e com o pr im er cont r ol, el cont r ol que quer em os com o base de t am año par a el r est o de cont r oles, y post er ior m ent e con la t ecla Ct r l seleccionar em os uno a uno el r est o de cont r oles. Sin em bar go, par a alinear los cont r oles en un for m ular io t enem os m ás opciones. Hem os v ist o algunas de ellas, quizás las m ás habit uales, per o com o podem os deducir del m enú For m a t o, podr em os alinear los cont r oles, espaciar los ent r e sí hor izont al o v er t icalm ent e, m odificar su t am año, cent r ar los en el for m ular io hor izont al o v er t icalm ent e, et c. Por ot r o lado, Visual St udio 2010, nos pr opor ciona una ut ilidad en t iem po de diseño m uy út il. Se t r at a de las guías de r epr esent ación que v er em os en t ono azul clar o, y que apar ecen cuando m ov em os un cont r ol en el for m ular io. Est as guías indican la sit uación y posición de un cont r ol r espect o a ot r o pr óx im o. La r epr esent ación de est as guías que se m uest r an en la figur a 9, nos facilit a enor m em ent e la disposición de los cont r oles en un for m ular io. Guía s o re gla s de dire cción o se pa ra ción e nt re cont role s Figur a 9 Módulo 3 - Capítulo 3 2. Creación de controles en tiempo de ejecución Pr áct icam ent e t odo en . NET son obj et os. Los cont r oles t am bién, así que par a añadir un cont r ol a un for m ular io en t iem po de ej ecución, deber em os hacer lo t r at ándolo com o un obj et o. La declar ación pr incipal de un obj et o, se r ealiza con la inst r ucción N e w . El siguient e ej em plo de código, cr ea un cont r ol Bu t t on en t iem po de ej ecución. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Declaramos el objeto Button Dim MiControl As New Button ' Declaramos un nombre al control (si queremos) MiControl.Name = "btn1" ' Cambiamos algunas de sus propiedades MiControl.Text = "Ejemplo de Botón" MiControl.Top = 50 MiControl.Left = 50 MiControl.Width = 200 MiControl.Height = 50 ' Añadimos el control al Formulario Me.Controls.Add(MiControl) End Sub En la figur a 1 podem os v er el r esult ado en ej ecución del código escr it o ant er ior m ent e. Par a ej ecut ar nuest r a aplicación, pr esionar em os el bot ón F5 , que es la for m a habit ual de ej ecut ar una aplicación. Cre a ción de un cont rol e n t ie m po de e j e cución e n Visua l Ba sic 2 0 1 0 Figur a 1 Ot r a de las car act er íst icas de los cont r oles, es la posibilidad de m anipular los cont r oles en t iem po de ej ecución. Sin em bar go, en nuest r o caso, v am os a m odificar la pr opiedad Te x t del cont r ol Bu t t on que hem os inser t ado en t iem po de ej ecución. Par a hacer est o, lo m ás habit ual es poner el nom br e del cont r ol, su pr opiedad y el v alor cor r espondient e. En nuest r o caso, el código quedar ía com o el que se indica a cont inuación: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Declaramos el objeto Button Dim MiControl As New Button ' Declaramos un nombre al control (si queremos) MiControl.Name = "btn1" ' Cambiamos algunas de sus propiedades MiControl.Text = "Ejemplo de Botón" MiControl.Top = 50 MiControl.Left = 50 MiControl.Width = 200 MiControl.Height = 50 ' Añadimos el control al Formulario Me.Controls.Add(MiControl) ' Modificamos la propiedad Text del control insertado btn1.Text = "Otro texto" End Sub Analizando est e código, par ece est ar bien escr it o, per o al pr esionar F5 par a ej ecut ar nuest r o pr oy ect o, nos encont r am os con que Visual Basic 2010 nos m uest r a un er r or . Nos indica que b t n 1 no est á declar ado. ¿Qué ocur r e?. Al buscar la clase de ensam blados de la aplicación, el cont r ol Bu t t on de nom br e b t n 1 no ex ist e, por lo que Visual Basic 2010 det ect a que debem os declar ar el cont r ol, sin em bar go y en nuest r o caso, est a declar ación la hacem os en t iem po de ej ecución. ¿Cóm o acceder a la pr opiedad Te x t del cont r ol Bu t t on cr eado en t iem po de ej ecución?. El siguient e código r esuelv e est a duda: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Declaramos el objeto Button Dim MiControl As New Button ' Declaramos un nombre al control (si queremos) MiControl.Name = "btn1" ' Cambiamos algunas de sus propiedades MiControl.Text = "Ejemplo de Botón" MiControl.Top = 50 MiControl.Left = 50 MiControl.Width = 200 MiControl.Height = 50 ' Añadimos el control al Formulario Me.Controls.Add(MiControl) ' Modificamos la propiedad Text del control insertado CType(Me.FindForm.Controls("btn1"), Button).Text = "Otro texto" End Sub Básicam ent e, ut ilizam os una conv er sión ex plícit a del obj et o dev uelt o por la búsqueda r ealizada en los cont r oles del for m ular io pr incipal, que ser á un cont r ol Bu t t on de nom br e b t n 1 , par a poder así, cam biar la pr opiedad Te x t de est e cont r ol. Aún así, t am bién podr íam os haber accedido a la pr opiedad Te x t del cont r ol m ediant e ot r a acción com plem ent ar ia, com o se m uest r a en el siguient e código: ' Declaramos el objeto Button Dim MiControl As New Button Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Declaramos un nombre al control MiControl.Name = "btn1" ' Cambiamos algunas de sus propiedades MiControl.Text = "Ejemplo de Botón" MiControl.Location = New Point(50, 50) MiControl.Size = New Size(200, 50) ' Añadimos el control al Formulario Me.Controls.Add(MiControl) End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click MiControl.Text = "Otro texto" End Sub ¡Oj o!: Tenga en cuent a que est a acción se puede r ealizar si la declar ación del obj et o But t on est á dent r o del m ism o ám bit o de llam ada de la pr opiedad Text . Por esa r azón, hem os sacado la declar ación MiCont r ol del obj et o But t on fuer a del pr ocedim ient o de cr eación dinám ica del cont r ol, per o t enga en cuent a t am bién, que en est e caso, t endr em os declar ada siem pr e en m em or ia la var iable MiCont r ol. El uso de la conver sión ( But t on) es siem pr e m ás segur o. El caso ant er ior ut ilizando únicam ent e la conv er sión ex plícit a, ( But t on) , quedar ía com o se det alla a cont inuación ( par a est os dos ej em plos, he añadido adem ás un cont r ol Bu t t on al for m ular io Window s, desde el cuál cam biar em os la pr opiedad Te x t del cont r ol Bu t t on cr eado en t iem po de ej ecución) : Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Declaramos el objeto Button Dim MiControl As New Button ' Declaramos un nombre al control (si queremos) MiControl.Name = "btn1" ' Cambiamos algunas de sus propiedades MiControl.Text = "Ejemplo de Botón" MiControl.Location = New Point(50, 50) MiControl.Size = New Size(200, 50) ' Añadimos el control al Formulario Me.Controls.Add(MiControl) End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click CType(Me.FindForm.Controls("btn1"), Button).Text = "Otro texto" End Sub Est e ej em plo en ej ecución es el que se m uest r a en la figur a 2. Ej e cución de l e j e m plo a nt e rior e n Visua l Ba sic 2 0 1 0 Figur a 2 Ant es de cont inuar con el siguient e apar t ado en el que apr ender em os a cr ear un ar r ay de cont r oles, com ent ar é que a la hor a de posicionar un det er m inado cont r ol en un for m ular io Window s, lo podem os hacer con las pr opiedades Top y Le f t , o bien, ut ilizando la pr opiedad Loca t ion . Lo m ism o ocur r e con las pr opiedades W id t h y H e ig h t que pueden ser sust it uidas por la pr opiedad Siz e . El m ism o ej em plo de cr eación de cont r oles en t iem po de ej ecución ut ilizando el m ét odo Loca t ion y Siz e , quedar ía com o se det alla a cont inuación: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Declaramos el objeto Button Dim MiControl As New Button ' Declaramos un nombre al control (si queremos) MiControl.Name = "btn1" ' Cambiamos algunas de sus propiedades MiControl.Text = "Ejemplo de Botón" ' Propiedad Location MiControl.Location = New Point(50, 50) ' Propiedad Size MiControl.Size = New Size(200, 50) ' Añadimos el control al Formulario Me.Controls.Add(MiControl) End Sub Hast a ahor a hem os v ist o com o cr ear cont r oles en t iem po de ej ecución, per o en m uchas ocasiones, nos es út il no sólo cr ear un cont r ol en t iem po de ej ecución, sino r elacionar lo con un ev ent o. En nuest r o ej em plo del cont r ol Bu t t on , cuando hacem os clic sobr e el cont r ol, no ocur r e nada, y ser ía int er esant e m ost r ar un m ensaj e o r ealizar una acción det er m inada. Par a hacer est o, deber em os ut ilizar el m ét odo Ad d H a n d le r par a asignar un ev ent o al cont r ol cr eado dinám icam ent e. El código de nuest r o ej em plo m ej or ado es el que se det alla a cont inuación: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Declaramos el objeto Button Dim MiControl As New Button ' Declaramos un nombre al control (si queremos) MiControl.Name = "btn1" ' Cambiamos algunas de sus propiedades MiControl.Text = "Ejemplo de Botón" MiControl.Location = New Point(50, 50) MiControl.Size = New Size(200, 50) ' Añadimos el control al Formulario Me.Controls.Add(MiControl) ' Añadimos el evento Click al control creado dinámicamente AddHandler MiControl.Click, AddressOf btn1Click End Sub Public Sub btn1Click(ByVal Sender As Object, ByVal e As System.EventArgs) ' Mostramos un Mensaje MessageBox.Show("Soy el Control Button con texto: '" + CType(CType(Sender, Button).Text, String) + "'") End Sub Nuest r o ej em plo en ej ecución es el que se m uest r a en la figur a 3. Ej e cución de l e j e m plo con a socia ción de e v e nt o de sa rrolla do e n Visua l Ba sic 2 0 1 0 Figur a 3 Módulo 3 - Capítulo 3 3. Creación de una matriz de controles En el capít ulo ant er ior , hem os v ist o com o cr ear cont r oles en t iem po de ej ecución e incluso com o asociar un ev ent o a un cont r ol cr eado dinám icam ent e en Visual Basic 2010, per o, ¿qué ocur r e si quer em os cr ear un ar r ay o m at r iz de cont r oles?. Podem os sim ular una m at r iz de cont r oles de m uchas for m as. Yo en est e ej em plo, aplicar é la siguient e for m a de llev ar a cabo est a t ar ea: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Declaramos la variable contador del bucle Para Dim I As Byte ' Declaramos la variable contador del número de controles a crear Dim intNumControles As Byte = 5 ' Iniciamos el bucle Para For I = 0 To CByte(intNumControles - 1) ' Declaramos el objeto TextBox Dim MiControl As New TextBox ' Le asignamos un nombre al control MiControl.Name = "txt1" ' Utilizamos la propiedad Tag para almacenar ahí el valor del control de la matriz virtual MiControl.Tag = I ' Le asignamos un tamaño en el Formulario Windows MiControl.Size = New Size(100, 20) ' Le asignamos una posición en el formulario Windows MiControl.Location = New Point(50, 22 * (I + 1)) ' Le cambiamos la propiedad Text MiControl.Text = MiControl.Name + "(" + I.ToString() + ")" ' Añadimos el control al Formulario Me.Controls.Add(MiControl) ' Añadimos el evento Click al control creado dinámicamente AddHandler MiControl.Click, AddressOf txt1Click Next End Sub Public Sub txt1Click(ByVal Sender As Object, ByVal e As System.EventArgs) ' Mostramos un Mensaje MessageBox.Show("Control " + CType(Sender, TextBox).Tag.ToString()) End Sub Nuest r o ej em plo de dem ost r ación en ej ecución es el que se puede v er en la figur a 1. Ej e cución de la sim ula ción de una m a t riz de cont role s Figur a 1 Obv iam ent e, ex ist en difer ent es for m as y t écnicas de sim ular un ar r ay o m at r iz de cont r oles. Sir v a est a que hem os v ist o, com o ej em plo de lo que se puede hacer , per o par a nada se t r at a de una nor m a o r egla fij a. Debem os dest acar que en . NET no ex ist e el concept o de ar r ay o m at r iz de cont r oles y a que ést a, es una car act er íst ica no pr opia del lenguaj e, per o que par a cier t as ocasiones conv iene conocer . Módulo 3 - Capítulo 3 4. Creación de controles nuevos Ya hem os v ist o la difer encia m ás genér ica ent r e un com ponent e y un cont r ol, per o aún no sabem os com o desar r ollar nuest r os pr opios cont r oles en Visual Basic 2010. En pr im er lugar y ant es de adent r ar nos en la cr eación de nuest r os pr opios cont r oles con Visual Basic 2010, debo indicar le que debem os obv iar t odo lo r elacionado con los Act iv eX OCX y Act iv eX en gener al. En Visual Basic 2010, la palabr a Act iv eX y a no ex ist e. El m odelo de pr ogr am ación ha cam biado y por eso, los com ponent es y cont roles se gener an ahor a siguiendo ot r as nor m as que apr ender em os a ut ilizar de for m a inm ediat a. I niciar em os Visual St udio 2010 y seleccionar em os un pr oy ect o de t ipo Bib liot e ca d e cla se s. En el nom br e de pr oy ect o, podem os indicar le el nom br e que deseem os t al y com o se m uest r a en la figur a 1, y a cont inuación pr esionar em os el bot ón OK. Se le cción de nue v o proy e ct o Bibliot e ca de cla se s e n Visua l Ba sic 2 0 1 0 Figur a 1 La difer encia m ay or que r eside ent r e el desar r ollo de com ponent es y cont r oles en . NET, es que en lugar de her edar de la clase Com p on e n t com o en el caso de la cr eación de los com ponent es, se ha de her edar de la clase Con t r ol o Sy st e m . W in d ow s. For m s. U se r Con t r ol. El t ipo de pr oy ect o seleccionado no posee por defect o com o ocur r e con los cont r oles Act iv eX, de la super ficie cont enedor a sobr e la cuál podr em os inser t ar ot r os cont r oles o r ealizar las acciones que consider em os per t inent es par a cr ear así nuest r o cont r ol per sonalizado. En est e caso, la super ficie cont enedor a la deber em os cr ear añadiendo las r efer encias necesar ias a nuest r o pr ogr am a. Haga clic con el bot ón secundar io del r at ón sobr e el pr oy ect o o solución de la v ent ana Ex p lor a d or d e solu cion e s y a cont inuación, seleccione la opción Pr op ie d a d e s del m enú em er gent e. A cont inuación, agr egue las r efer encias a las libr er ías de clases Sy st e m . D r a w in g y Sy st e m . W in d ow s. For m s. Por últ im o, escr iba las siguient es inst r ucciones básicas. Imports System.ComponentModel Imports System.Windows.Forms Imports System.Drawing Public Class Class1 Inherits UserControl End Class En est e punt o, nuest r a clase habr á sido t r ansfor m ada en la clase cont enedor a de un cont r ol que es la que puede v er se en la figur a 2. Supe rficie cont e ne dora por de fe ct o de un cont rol Figur a 2 Aún así, sino quier e r ealizar est a acción, ot r a for m a de t ener list a la super ficie cont enedor a del cont r ol, es la de elim inar la clase del pr oy ect o y pr esionar el bot ón secundar io del r at ón sobr e la v ent ana del Ex plor ador de soluciones y seleccionar la opción de Ag r e g a r > N u e v o e le m e n t o. . . del m enú em er gent e. De las opciones que salen, ( v er figur a 2B) , deber íam os seleccionar ent onces la plant illa Con t r ol d e u su a r io. Se le cciona r un cont rol de usua rio Figur a 2B Sin m ás dilación, añadir em os sobr e la super ficie del cont r ol cont enedor , ( al que habr em os cam biado el nom br e a M iCon t r ol) , dos cont r oles Label y dos cont r oles Tex t Box . Debido a que al añadir le los cont r oles t endr em os m ucho código que sim plem ent e sir v e par a el diseño del int er faz de usuar io, podem os hacer lo que el pr opio diseñador hace: div idir la clase en dos par t es o clases par ciales, de est a for m a conseguir em os el pr opósit o de las clases par ciales, ( al m enos en cuant o al diseño de for m ular ios y cont r oles de usuar io se r efier e) , que es, com o y a com ent am os ant er ior m ent e, separ ar el código de diseño del código que nosot r os v am os a escr ibir . Par a ello, añadir em os un nuev o elem ent o del t ipo Class, al que le dar em os el nom br e M iCon t r ol. D e sig n e r . v b , y en esa clase pegar em os el código que act ualm ent e hay en la clase, per o añadiendo la par t ícula Par t ial ant es de Class, con idea de que el com pilador de Visual Basic 2010 sepa que nuest r a int ención es cr ear una clase par cial. Realm ent e es casi lo m ism o que t enem os act ualm ent e, t an solo t endr em os que añadir la inst r ucción par t ial, ( no hace falt a que est é declar ada com o public, y a que en el ot r o "t r ozo" t endr em os declar ada est a clase com o pública) , adem ás del const r uct or de la clase, desde el que llam ar em os al m ét odo que se encar ga de t oda la inicialización: I n it ia liz e Com p on e n t ( ) . A cont inuación, escr ibir em os el siguient e código, en el ar chiv o que t eníam os or iginalm ent e ( MiCont r ol. v b) : Imports System.ComponentModel Imports System.Windows.Forms Public Class MiControl Private _Acceso As Boolean <Category("Acceso"), Description("Indica si se permite o no el acceso"), DefaultValue("False"), [ReadOnly](True)> _ Public Property Acceso() As Boolean Get Return _Acceso End Get Set(ByVal Val As Boolean) _Acceso = Val End Set End Property Private Sub UserControl1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load _Acceso = False End Sub Public Sub Validar() If TextBox1.Text = "ejemplo" And TextBox2.Text = "ejemplo" Then _Acceso = True Else _Acceso = False End If End Sub End Class Obser v ando el código, v em os que hem os cr eado una pr opiedad Acce so que nos per m it ir á saber si un usuar io y cont r aseña han sido v alidadas o no. Ahor a nuest r o cont r ol, est á list o y a par a ser com pilado y pr obado en una aplicación Window s. Par a com pilar nuest r o cont r ol, haga clic en el m enú Ge n e r a r > Ge n e r a r Solu ción com o se m uest r a en la figur a 3. Opción pa ra com pila r nue st ro cont rol Figur a 3 A cont inuación añada un nuev o pr oy ect o Ap lica ción p a r a W in d ow s a la solución. Par a añadir un pr oy ect o a la solución act ual, t endr em os que ir al m enú Ar ch iv o y seleccionar N u e v o p r oy e ct o, cuando nos m uest r e el cuadr o de diálogo, indicar em os que lo añada a la m ism a solución. Est ablézcalo com o pr oy ect o inicial de la solución. Acuda a la bar r a de her r am ient as y busque el cont r ol que hem os cr eado y com pilado par a inser t ar lo en el for m ular io Window s. Sino apar ece en la bar r a de her r am ient as, ( que deber ía apar ecer en el gr upo Cla ssLib r a r y 1 ) , deber á añadir lo de la siguient e m aner a. Haga clic sobr e la bar r a de her r am ient as y seleccione la opción Ele g ir Ele m e n t os. . . del m enú em er gent e que apar ece en la figur a 4. Opción pa ra a ña dir un cont rol o com pone nt e a la ba rra de he rra m ie nt a s Figur a 4 Apar ecer á una v ent ana par a buscar el cont r ol y a com pilado en el disco dur o. pr esionar em os el bot ón Ex a m in a r . . . y buscar em os nuest r o cont r ol par a seleccionar lo. Una v ez hecho est o, t al y com o se indica en la figur a 5, har em os clic sobr e el bot ón OK. Se le cción de l cont rol com pila do a nt e riorm e nt e Figur a 5 Nuest r o cont r ol quedar á inser t ado en en la bar r a de her r am ient as com o se m uest r a en la figur a 6. Cont rol inse rt a do e n la ba rra de he rra m ie nt a s Figur a 6 Par a inser t ar el cont r ol en el for m ular io, har em os doble clic sobr e él. Est e quedar á dispuest o en el for m ular io Window s com o se indica en la figur a 7. Cont rol inse rt a do e n e l form ula rio W indow s de prue ba Figur a 7 Nuest r o for m ular io Window s de pr ueba en ej ecución con el cont r ol inser t ado en él, es el que puede v er se en la figur a 8. Form ula rio W indow s de prue ba e n e j e cución con e l cont rol inse rt a do Figur a 8 Com o ha podido com pr obar , la cr eación de cont r oles en Visual Basic 2010, t am poco r equier e de una gr an habilidad o dest r eza, y su sim ilit ud con la cr eación de com ponent es es enor m e. De hecho, t odo se r educe en el uso y pr ogr am ación de una clase con la salv edad de que dent r o de esa clase, indicam os si se t r at a de una clase com o t al, la clase de un com ponent e o la clase de un cont r ol. Módulo 3 - Capítulo 3 5. Otras consideraciones Cont r oles cont enedor es Cuando t r abaj am os con cont r oles, sur gen m uchas v eces m uchas dudas de car áct er habit ual. Definam os que hay dos t ipos de cont r oles, los cont r oles cont enedor es y los cont r oles no cont enedor es. La difer encia ent r e am bos es que los cont r oles cont enedor es, pueden com o su pr opia palabr a dice, cont ener ot r os cont r oles dent ro de ést e. Los cont r oles no cont enedor es no pueden. Un clar o ej em plo de cont r ol cont enedor , es el cont r ol Ta b Con t r ol, el cuál per m it e incluir dent r o de él ot r os cont r oles, incluso cont r oles cont enedor es a su v ez. Un ej em plo de cont r ol no cont enedor es el cont r ol Bu t t on por ej em plo. Si int ent a poner un cont r ol Te x t Box encim a de un cont r ol Bu t t on , obser v ar á que no puede. Cuando un cont r ol se inser t a dent r o de un cont enedor ( no olv idem os que el for m ular o Window s es ot r o cont enedor ) , ést e cont r ol queda aloj ado dent r o de su cont enedor , de t al m aner a que si m ov em os el cont endor , est ar em os m ov iendo t am bién el cont enido de ést e. El pr oblem a sin em bar go cuando t r abaj am os con cont r oles, v iene cuando deseam os r ecor r er los cont r oles de un for m ular io. Est o es m uy habit ual cuando deseam os bor r ar el cont en do de t odos los cont r oles Te x t Box de un for m ular io Window s por ej em plo. Dent r o de un for m ular o y supuest o que t engam os 4 cont r oles Te x t Box inser t ados dent r o de él, y luego un bot ón que nos per m it a elim inar el cont enido de cada caj a de t ex t o, t al y com o se ind ca en la figur a 1, deber íam os escr ibir un código sim ilar al que v er em os a cont inuación: Form ula rio W indow s de e j e m plo con sus cont role s inse rt a dos Figur a 1 Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim obj As Object For Each obj In Controls If TypeOf obj Is TextBox Then CType(obj, TextBox).Text = "" End If Next End Sub End Class Obser v ando est e código, v em os que lo que hacem os no es ot r a cosa que r ecor r er los obj et os com o cont r oles dent r o del for m ular o y m ir am os si se t r at a de un cont r ol de t ipo Te x t Box . En est e caso, m odificam os la pr opiedad Te x t par a dej ar la en blanco. Ej ecut e est e ej em plo con la t ecla de función F5 , escr iba algo en las caj as de t ex t o y pulse el bot ón. Obser v ar á que logr am os conseguir nuest r o obj et iv o de bor r ar el cont enido de t odos los cont r oles Te x t Box . A cont inuación, lo que har em os ser á añadir un cont r ol Ta b Con t r ol a nuest r o for m ular io Window s, y dent r o de él, añadir em os los cuat r o cont r oles Te x t Box y el cont r ol Bu t t on ant er ior m ent e com ent ados, t al y com o se m uest r a en la figur a 2. Cont role s inse rt a dos de nt ro de un cont rol cont e ne dor com o e l cont rol Ta bCont rol Figur a 2 El código ant er ior no har á falt a m odif car lo, por lo que ej ecut ar em os la aplicación nuev am ent e pr esionando el bot ón F5 , escr ibir em os algo de t ex t o en las caj as de t ex t o y pulsar em os el bot ón com o hicim os ant es. Obser v ar em os que en est e caso, los cont r oles Te x t Box no se han quedado en blanco com o ant es. El cont enedor no es el for m ular io Window s, sino el cont r ol Ta b Con t r ol. Dicho cont r ol es t r at ado en el bucle ant er ior del cont r ol com o cont r ol dependient e del for m ular io Window s, per o los cont r oles Te x t Box y el pr opio cont r ol Bu t t on , quedan encer r ados dent r o de un ám bit o cont enedor difer ent e. Par a solv ent ar est e pr oblem a, deber em os r ecor r er los cont r oles del cont enedor . Una for m a de solv ent ar est o es de la siguient e m aner a: Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click For I As Byte = 0 To TabControl1.TabPages.Count - 1 For Each obj As Object In TabControl1.TabPages(I).Controls If TypeOf obj Is TextBox Then CType(obj, TextBox).Text = "" End If Next Next End Sub End Class De est a m aner a, r ecor r er em os t odos los cont r oles que r es den en las páginas de un cont r ol Ta b Con t r ol y si se t r at a de un cont r ol Te x t Box , m odificar em os la pr opiedad Te x t cor r espondient e. Por est a r azón, cuando t r abaj am os con cont r oles dent r o de un for m ular io y quer em os act uar sobr e un conj unt o de cont r oles det er m inado, debem os t ener en cuent a ent r e ot r as cosas, si se t r at a de un conj unt o de cont r oles o un cont r ol sim plem ent e, se encuent r a dent r o de un cont r ol cont enedor o fuer a de él. Sin em bar go, par a r esolv er el pr oblem a de r ecor r er t odos los cont r oles de un for m ular o, est én o no dent r o de un cont r ol cont enedor , lo m ej or es am pliar la función ant er ior y hacer la r ecur siv a, de m odo que per m t a r ecor r er t odos los cont r oles del for m ular o, est én o no dent r o de un cont enedor . El siguient e código, r eflej a un ej em plo de com o hacer est o posible. En el m ism o pr oy ect o, podem os añadir nuev os Te x t Box a la ot r a ficha del Ta b Con t r ol, adem ás uno en el pr op o for m ular o, ( par a que no est é dent r o del Ta b Con t r ol) . Rellene algo de cont en do en los cont r oles Te x t Box y ej ecut e el código: Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click VaciarTextBox(Me) End Sub Private Sub VaciarTextBox(ByVal Parent As Control) For Each obj As Control In Parent.Controls If obj.Controls.Count > 0 Then VaciarTextBox(obj) End If If TypeOf obj Is TextBox Then CType(obj, TextBox).Text = "" End If Next End Sub End Class Sm ar t Tags Ot r as de las nov edades del diseñador de for m ular ios de Visual St udio 2010, es el hecho de poder utilizar las denom inadas Sm ar t Tags. Si ust ed es usuar o de Office en sus últ im as v er siones, sabr á a que m e r efier o. Las Sm a r t Ta g s nos indican t r ucos y consej os dir ect a a la cuál se puede acceder desde Visual Basic 2010 de for m a r ápida, ahor r ándonos t iem po y apor t ándonos pr oduct iv idad en nuest r os desar r ollos. Las Sm a r t Ta g s apar ecen en Visual St udio 2010 t ant o en el lado del diseño del for m ular io Window s com o en la par t e cor r espondient e del código fuent e escr it o. En el caso de los cont r oles inser t ados en un for m ular io Window s, est as Sm a r t Ta g s apar ecer án por lo gener al en el bor de super ior der echo del cont r ol y se r epr esent ar á con un cono par ec do a est e . Si hacem os clic sobr e ese icono, apar ecer á una ay uda gr áfica con v ar ias opciones que per m it e r ealizar las acciones m ás com unes sobr e el cont r ol seleccionado, t al y com o se ind ca en la figur a 3 par a el caso del cont r ol Ta b Con t r ol. Cont role s inse rt a dos de nt ro de un cont rol cont e ne dor com o e l cont rol Ta bCont rol Figur a 3 En el caso del código, las Sm a r t Ta g s poseen un com por t am ient o liger am ent e difer ent e dependiendo del caso. Un ej em plo habit ual es el hecho de declar ar una v ar iable incor r ect a t r at ando de t r abaj ar con ella. Cuando ej ecut am os nuest r a aplicación, el depur ador se det iene en la declar ac ón incor r ect a y nos m uest r a una v ent ana de depur ación, com o se indica en la figur a 4. Ve nt a na de de pura ción de t a lla da Figur a 4 La v ent ana em er gent e de depur ac ón nos ind ca no sólo el t ipo de er r or encont r ado, sino que adem ás, nos ind ca las posibles soluciones par a solv ent ar el pr oblem a. Est os consej os, suger encias o Tips, nos ofr ecen una v ent aj a sobr e nuest r os desar r ollos, pr opor cionándonos una r ápida solución a un pr oblem a y per m t iéndonos ahor r ar m ucho t iem po r esolv iendo el por qué del pr oblem a. Si en la v ent ana de depur ación em er gent e pr esionam os sobr e la opción V e r d e t a lle . . . , obt endr em os una nuev a v ent ana com o la que se m uest r a en la figur a 5. Ve nt a na de de t a lle s de l e rror Figur a 5 De est a m aner a, conocer em os los det alles del pr oblem a det ect ado por St udio 2010 per m it iéndonos cor r egir lo cóm odam ent e. Ot r a posibilidad de las Sm a r t Ta g s es la det ección de una declar ac ón de v ar iable o cualquier par t e de código, no esper ada. Com o ej em plo, declar ar em os una v ar iable de la for m a: Dim I As intger Quer íam os decir I nt eger , per o con las pr isas he escr it o int ger . En ese inst ant e, Visual St udio 2010 se ha per cat ado de que la declar ación no es cor r ect a y ant es de que m e pueda dar cuent a de que lo he escr it o incor r ect am ent e, el ent or no m e indica el er r or m ar cándolo con un subr ay ado car act er íst ico com o se ind ca en la figur a 6. Subra y a do de Visua l St udio 2 0 1 0 indica ndo un e rror e n la inst rucción de código e scrit a Figur a 6 Cuando acer cam os el punt er o del m ouse sobr e el r ecuadr o de color r oj o de la declar ación er r ónea, apar ece una infor m ac ón adic onal j unt o a un cono par ec do a est e y una infor m ación em er gent e que se m uest r a en la figur a 7. I nform a ción sobre e l de t a lle de l e rror e ncont ra do Figur a 7 Si hacem os clic sobr e el icono , acceder em os a una infor m ación adicional que nos m uest r a un conj unt o de suger encias. En nuest r o caso es la pr im er a de ellas com o se ind ca en la figur a 8, por lo que al hacer clic sobr e ella, la declar ación se act ualiza dir ect am ent e por la declar ación cor r ect a: Opcione s o suge re ncia s de re solución de l e rror Figur a 8 Dim I As Integer Gener ación de código r ápido Ot r a consider ación a t ener en cuent a a la hor a de t r abaj ar con código y a la hor a por lo t ant o, de desar r ollar nuest r os pr opios cont r oles, com ponent es, clases, et c. , es la ay uda que nos pr opor ciona el ent or no cuando deseam os escr ibir det er m inadas funciones r ápidas de código que son bast ant e hab t uales. Pos c ónese sobr e el código de Visual Basic 2010 y haga clic con el bot ón secundar io del m ouse y seleccione la opción I n se r t a r f r a g m e n t o d e cód ig o. . . com o se indica en la figur a 9. Opción de re cort e s de código de Visua l St udio 2 0 1 0 Figur a 9 Apar ecer á una v ent ana em er gent e com o la que se m uest r a en la figur a 10 dent r o de la cuál, podr em os seleccionar la car pet a que cont iene un am plio conj unt o de func ones, par a inser t ar la r áp dam ent e a nuest r o código. Ve nt a na e m e rge nt e de ca rpe t a s de re cort e s de código Figur a 10 Com o ej em plo, s t úese con los cur sor es sobr e M a t h , pulse Ent er , selecc one a cont inuación Get a Random Num ber using t he Random class com o se indica en la figur a 11 y v uelv a a pr es onar Ent er . El código quedar á inser t ado a nuest r o pr oy ect o de Visual Basic 2010 com o se m uest r a a cont inuación: Se le cción de un re cort e de código Figur a 11 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim generator As New Random Dim randomValue As Integer ' Generates numbers between 1 and 5, inclusive. randomValue = generator.Next(1, 6) End Sub Est os at aj os, aum ent an la pr oduct iv idad en el desar r ollo de aplicaciones de for m a abism al. Tengam os en cuent a, que m uchas de las oper aciones que r ealizam os los desar r ollador es, son acciones r epet it iv as, funciones gener ales o funciones hab t uales que r educen nuest r o r endim ient o y pr oduct iv dad y nos per m t e com et er er r or es. Con est as acc ones, ev it am os t odo est o. FAQ: ¿Cóm o añadir nuest r os pr opios r ecor t es o Snippet s? I ndudablem ent e, una cosa es usar los r ecor t es que nos pr opor ciona Visual Basic 2010 y ot r a m uy difer ent e añadir los nuest r os al ent or no Par a hacer est o últ im o, pr im er o debem os escr ibir nuest r os r ecor t es de código, la m ej or for m a es fij ar se cóm o est án hechos los que se incluyen con Visual St udio 2010, par a localizar los, abr a una vent ana de Windows y sit úese sobr e la car pet a de inst alación del ent or no de Visual St udio 2010 y concr et am ent e en la car pet a de Snippet s En m i caso, la r ut a es C: \ Ar chivos de pr ogr am a\ Micr osoft Visual St udio 10 0\ VB\ Snippet s\ 3082 Par a añadir nuevos r ecor t es, lo podem os hacer desde el m enú Her r am ient as > Adm inist r ador de fr agm ent os de código Introducción En este capítulo veremos las partes más generales en el uso y generación de imágenes y gráficos con Visual Basic 2010. Pasaremos de puntillas sobre el uso de DirectX para la generación de gráficos 3D y nos adentraremos un poco más profundamente, en el desarrollo de gráficos e imágenes 2D con GDI+. Módulo 3 - Capítulo 4 ● 1. Gráficos 3D ● 2. Gráficos 2D ● 3. Dibujando líneas con GDI+ ● 4. Dibujando curvas con GDI+ ● 5. Dibujando cadenas de texto con GDI+ ● 6. Otras consideraciones Módulo 3 - Capítulo 4 1. Gráficos 3D Par a t r abaj ar con im ágenes y gr áficos en 3D, deber em os ut ilizar Dir ect X, y a que dent r o de la plat afor m a . NET de Micr osoft , no tenem os la posibilidad de cr ear r epr esent aciones 3D. Est o significa por ot r a par t e, que si desar r ollam os una aplicación con r epr esent ación 3D con Dir ect X, deber em os dist r ibuir t am bién las libr er ías Dir ect X en la m áquina en la que se ej ecut e nuest r a aplicación. Es decir , no bast ar á con dist r ibuir Micr osoft . NET Fr am ew or k . Per o Dir ect X no nos per m it e sólo cr ear gr áficos e im ágenes en 3D, t am bién podem os cr ear im ágenes en 2D, per o lo m ás nor m al en est e últ im o caso y salv o que no r equer am os un uso cont inuado de Dir ect X, ser á ut ilizar en su lugar GDI + , com o v er em os m ás adelant e. Par a t r abaj ar con Dir ect X en Visual Basic 2010, deber em os añadir una r efer encia al pr oy ect o con la libr er ía o libr er ías COM de Dir ect X, eso si t r abaj am os con Dir ect X 8 o ant er ior , y a que a par t ir de Dir ect X 9, Micr osoft ha pr opor cionado un conj unt o de clases y libr erías que int er act úan con . NET dir ect am ent e, per m it iéndonos ej ecut ar aplicaciones . NET con Dir ect X adm inist r ado. En nuest r o caso, lo m ej or es r ealizar un ej em plo, no sin ant es r ecor dar , que deber ía descar gar Micr osoft Dir ect X SDK 9 e inst alar lo en su sist em a. El SDK cont iene ficher os de ay uda y docum ent ación que le enseñar á a cr ear aplicaciones con Dir ect X 9 en Visual Basic 2010. FAQ: ¿Dónde puedo descar gar Micr osoft Dir ect X 9.0 SDK? La últ im a ver sión de Dir ect X SDK la encont r ar á en la página Web de MSDN de Dir ect X, especialm ent e cr eada par a desar r ollador es de aplicaciones y j uegos. Descargas de M cro so ft Direct X Sobr e el sopor t e de D ir ect X y .N ET: Desde la ver sión de Dir ect X 10.0 no exist e sopor t e dir ect o par a Micr osoft .NET. Es de esper ar que Micr osoft pr opor cione libr er ías con sopor t e en .NET en un fut ur o. Los ej em plos que aquí apar ecen, son adecuados par a Dir ect X 9.0. Una v ez que t enem os inst alado en nuest r o sist em a las libr er ías de desar r ollo de Dir ect X par a NET, iniciar em os una nuev a aplicación Window s, añadir em os las r efer encias a las libr er ías Micr osoft Dir ect X y Micr osoft Dir ect X Dir ect 3D t al y com o se m uest r a en la figur a 1 y las cuáles encont r ar em os nor m alm ent e en el dir ect or io c: \ w indow s\ sy st em 32\ Re fe re ncia s a Dire ct X a ña dida s a nue st ro proy e ct o Figur a 1 A cont inuación, escr ibir em os el siguient e código: Imports Microsoft.DirectX Imports Microsoft.DirectX.Direct3D Public Class Form1 Public Sub CreateDevice() Dim pp As New PresentParameters() pp.Windowed = True pp.SwapEffect = SwapEffect.Discard Dim dv As New Device(0, DeviceType.Hardware, Me, CreateFlags.SoftwareVertexProcessing, pp) Dim vertices(6) As CustomVertex.TransformedColored vertices(0).Position = New Vector4(Me.Width / 2.0F, 70.0F, 0.5F, 1.0F)) vertices(1).Position = New Vector4(Me.Width - (Me.Width / 5.0F), Me.Height - (Me.Height / 5.0F), 0.5F, 1.0F)) vertices(2).Position = New Vector4(Me.Width / 5.0F, Me.Height - (Me.Height / 5.0F), 0.5F, 1.0F)) vertices(3).Position = New Vector4(Me.Width / 2.0F, 50.0F, 0.5F, 1.0F)) vertices(4).Position = New Vector4(Me.Width - (Me.Width / 5.0F), Me.Height - (Me.Height / 5.0F), 0.5F, 1.0F)) vertices(5).Position = New Vector4(Me.Width / 5.0F, Me.Height - (Me.Height / 5.0F), 0.5F, 1.0F)) dv.Clear(ClearFlags.Target, System.Drawing.Color.BlueViolet, 2.0F, 0) dv.BeginScene() dv.VertexFormat = VertexFormats.Transformed dv.DrawUserPrimitives(PrimitiveType.TriangleList, 2, vertices) dv.EndScene() dv.Present() End Sub Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) CreateDevice() End Sub End Class Est e pequeño ej em plo dem ost r at iv o en ej ecución del uso de Dir ect X desde nuest r as aplicaciones Visual Basic 2010, es el que puede v er se en la figur a 2 Ej e m plo de Dire ct X con Visua l Ba sic 2 0 1 0 e n e j e cución Figur a 2 Módulo 3 - Capítulo 4 2. Gráficos 2D Las API s de GDI + cor r esponden a la ev olución nat ur al de las API s y libr er ías GDI que se ut ilizaban en ot r os lenguaj es de desar r ollo. GDI + no es ot r a cosa que un conj unt o de clases desar r olladas par a el ent or no . NET y por esa r azón, podem os ent onces dibuj ar y cr ear r epr esent aciones gr áficas en Visual Basic 2010. Todas las clases GDI + , pueden ser localizadas a t r av és del nom br e de espacio Sy st e m . D r a w in g . Así, podem os acceder a t odas las posibilidades que nos ofr ece GDI + y las cuales v er em os m ás adelant e. GDI + , no accede al har dw ar e dir ect am ent e, int er act úa con los dr iv er s de los disposit iv os gr áficos. Com o par t icular idad, debem os saber que GDI + est á sopor t ado por Win32 y Win64. Respect o a los sist em as oper at iv os y el sopor t e de est os par a GDI + , Window s XP cont iene la libr er ía g d ip lu s. d ll que encont r ar em os nor m alm ent e en c: \ w indow s\ sy st em 32\ y la cuál nos per m it e t r abaj ar con GDI + . Micr osoft . NET por ot r a par t e, nos pr opor ciona el acceso dir ect o a est a libr er ía par a poder desar r ollar nuest r as aplicaciones de for m a m ucho m ás cóm oda y sencilla. FAQ: ¿Dispone m i sist em a oper at ivo de GDI + ? Micr osoft .NET Fr am ewor k inst ala aut om át icam ent e en su sist em a las libr er ías GDI + par a que las pueda ut ilizar en sus aplicaciones. Módulo 3 - Capítulo 4 3. Dibujando líneas con GDI+ Lo pr im er o que apr ender em os a r epr esent ar con GDI + y Visual Basic 2010, son líneas m uy sencillas. Líneas sim ples Cuando r epr esent am os líneas, debem os t ener en cuent a v ar ios aspect os. Una línea est á r epr esent ada por dos punt os. Cuando la r epr esent am os en un plano, La r epr esent ación de una línea t iene dos par es de punt os ( est o m e r ecuer da a m is t iem pos de est udiant e con el álgebr a y el cálculo) . Par a r epr esent ar una línea por lo t ant o, debem os indicar un par de punt os ( x , y ) cuy as coor denadas ( hor izont al, v er t ical) , r epr esent a en est e or den, el lugar o punt o de inicio indicado por el m ar gen super ior del for m ular io o super ficie sobr e la cuál deseam os dibuj ar nuest r a línea, y un segundo par de punt os que r epr esent an la dir ección final de nuest r a línea. Un ej em plo pr áct ico de est e t ipo de r epr esent ación es la que se det alla en el siguient e código fuent e de ej em plo: Imports System.Drawing Public Class Form1 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) e.Graphics.DrawLine(New System.Drawing.Pen(Color.DarkBlue, 2), 1, 1, 50, 50) End Sub End Class At endiendo al código, obser v am os que hem os r epr esent ado la gr áfica indicando que quer em os dibuj ar una línea e. Gr aphics. Dr aw Line indicando post er ior m ent e una ser ie de at r ibut os com o el color del lápiz y t am año o gr osor de ést e Pen( Color . Dar k Blue, 2) y un conj unt o de par ám et r os ( x , y ) que r epr esent an las coor denadas de la línea ( 1, 1) y ( 50, 50) . Ot r a r epr esent ación sim ilar ser ía e. Gr aphics. Dr aw Line( Pens. Dar k Blue, 1, 1, 50, 50) , con la salv edad de que en est e caso, el gr osor del lápiz es el gr osor por defect o, que es 1. De t odos los m odos, la declar ación e. Gr aphics. Dr aw Line( New Sy st em . Dr aw ing. Pen( Color . Dar k Blue, 2) , 1, 1, 50, 50) y e. Gr aphics. Dr aw Line( New Sy st em . Dr aw ing. Pen( Color . Dar k Blue, 2) , 50, 50, 1, 1) en el caso de la r epr esent ación de líneas es igualm ent e com pat ible. Est e ej em plo de pr ueba en ej ecución es el que se puede v er en la figur a 1. Ej e m plo de dibuj o con GDI + de una líne a re ct a e n un form ula rio W indow s Figur a 1 Líneas per sonalizadas Sin em bar go, la r epr esent ación de líneas con GDI + t iene difer ent es par t icular idades que nos per m it en sacar un alt o gr ado de per sonalización a la hor a de pint ar o r epr esent ar las im ágenes y gr áficos en nuest r as aplicaciones. La r epr esent ación de líneas con GDI + , nos per m it e ent r e ot r as cosas, per sonalizar no sólo el color y el gr osor de una línea, sino ot r as car act er íst icas de ést a com o por ej em plo los ex t r em os a dibuj ar . Así, podem os dibuj ar unos ex t r em os m ás o m enos r edondeados, punt iagudos, o per sonalizados. Est o lo conseguim os hacer m ediant e las pr opiedades St a r t Ca p y En d Ca p de la clase Pe n que es lo que v ulgar m ent e he denom inado com o lápiz. A est as pr opiedades, las podem os dar difer ent es v alor es. Sir v a el siguient e ej em plo de m uest r a de lo que podem os llegar a hacer . Imports System.Drawing Public Class Form1 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) Dim Lapiz As New Pen(Color.DarkBlue, 10) Lapiz.StartCap = Drawing2D.LineCap.DiamondAnchor Lapiz.EndCap = Drawing2D.LineCap.ArrowAnchor e.Graphics.DrawLine(Lapiz, 10, 10, 140, 140) End Sub End Class De m ost ra ción de com o re pre se nt a r dife re nt e s e x t re m os e n una líne a con GDI + Figur a 2 Tr azando cam inos o r ut as de líneas Ot r a posibilidad de GDI + es la de cr ear líneas ent r elazadas sin llegar a cer r ar las. Est o se hace con el m ét odo Ad d Lin e . De est a m aner a, podem os dibuj ar difer ent es líneas par a r epr esent ar las en el m ar co de t r abaj o. El siguient e ej em plo, nos enseña a ut ilizar el m ét odo Ad d Lin e . Imports System.Drawing Public Class Form1 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) Dim Ruta As New Drawing2D.GraphicsPath() Ruta.StartFigure() Ruta.AddLine(New PointF(10, 10), New PointF(100, 10)) Ruta.AddLine(New PointF(10, 10), New PointF(170, 100)) Ruta.AddLine(New PointF(170, 100), New PointF(130, 50)) Dim Lapiz As New Pen(Color.DarkBlue, 4) e.Graphics.DrawPath(Lapiz, Ruta) End Sub End Class En la figur a 3 podem os v er el r esult ado de cr ear difer ent es líneas en Visual Basic 2010 con GDI + . Ej e cución de l e j e m plo de uso de l m é t odo AddLine con Visua l Ba sic 2 0 1 0 Figur a 3 Obser v ando el código, v em os que hem os declar ado el m ét odo St a r t Fig u r e y el m ét odo Ad d Lin e de la clase Gr a p h icsPa t h . Finalm ent e y par a r epr esent ar la gr áfica cor r espondient e, hem os llam ado al m ét odo D r a w Pa t h . Líneas con t ext ur as Ot r a de las car act er íst icas de la r epr esent ación gr áfica de líneas con Visual Basic 2010 y GDI + , es la posibilidad de r epr esent ar líneas aplicando a esas líneas una det er m inada t ex t ur a. El siguient e ej em plo, aplica una t ex t ur a de la bander a de la Com unidad Económ ica Eur opea a un cam ino de líneas. Imports System.Drawing Public Class Form1 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) Dim Imagen As New Bitmap("c:\Flag.bmp") Dim Cepillo As New TextureBrush(Imagen) Dim TexturaPincel As New Pen(Cepillo, 20) Dim Ruta As New Drawing2D.GraphicsPath() Ruta.StartFigure() Ruta.AddLine(New PointF(10, 10), New PointF(180, 50)) Ruta.AddLine(New PointF(10, 100), New PointF(180, 140)) e.Graphics.DrawPath(TexturaPincel, Ruta) End Sub End Class Com o podem os obser v ar , lo pr im er o que hacem os es car gar una im agen que ser á la t ex t ur a que ut ilizar em os, dent r o de un obj et o Bit m a p , par a post er ior m ent e, pr epar ar el t r azo con su t ex t ur a y t am año. Luego cr eam os una r ut a o cam ino que m ar car em os par a dibuj ar la en el for m ular io Window s en nuest r o caso, t al y com o puede v er se en la figur a 4. Ej e m plo de un t ra z o de líne a a plica ndo t e x t ura s Figur a 4 Módulo 3 - Capítulo 4 4. Dibujando curvas con GDI+ La r epr esent ación de cur v as con GDI + t iene cier t a sim ilit ud con la r epr esent ación de líneas. A cont inuación v er em os las par t es m ás dest acables en la cr eación de t r azos cur v os con Visual Basic 2010 y GDI + . Tr azando cur vas sim ples Lo m ás sencillo de t odo es siem pr e el t r azo de una línea cur v a genér ica con Visual Basic 2010. Est o lo conseguir em os con el siguient e código: Imports System.Drawing Public Class Form1 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) Dim Puntos As PointF() = {New PointF(10, Convert.ToSingle(Math.Sin(1) * 100)), _ New PointF(60, Convert.ToSingle(Math.Sin(0) * 100)), _ New PointF(110, Convert.ToSingle(Math.Sin(1) * 100)), _ New PointF(160, Convert.ToSingle(Math.Sin(0) * 100)), _ New PointF(210, Convert.ToSingle(Math.Sin(1) * 100))} e.Graphics.DrawCurve(New Pen(Color.DarkOrange, 4), Puntos, 2.0F) End Sub End Class Si obser v am os est e código, v er em os que lo que hacem os es cr ear un conj unt o de punt os par a r epr esent ar los t r azos o líneas r ect ar que unan los punt os. Est o lo conseguim os ut ilizando la clase Poin t F. Post er ior m ent e ut ilizam os el m ét odo D r a w Cu r v e con la salv edad de que el t er cer par ám et r o, indica la t ensión de la cur v a. Si est e v alor r ecibe un 0. 0F, la cur v a no t endr á t ensión y por lo t ant o, la r epr esent ación ser á en t r azos r ect os, m ient r as que si ese v alor aum ent a, la t ensión aum ent a pr oduciéndose el efect o cur v o que deseam os conseguir . El ej em plo ant er ior en ej ecución es el que se m uest r a en la figur a 1 Ej e m plo e n e j e cución de la re pre se nt a ción grá fica de t ra zos curv os Figur a 1 Cur vas de Bézier Ot r a posibilidad que nos ofr ece GDI + es la r epr esent ación de cur v as de Bézier , algo que conseguir em os gr acias al m ét odo D r a w Be z ie r de GDI + . La r epr esent ación de las cur v as de Bézier pueden hacer se m ediant e dos par es de punt os ( x , y ) o m ediant e cuat r o coor denadas de punt os que definen la asignación de las cur v as a r epr esent ar . El siguient e ej em plo nos m uest r a com o r epr esent ar una cur v a de Bézier con Visual Basic 2010 y GDI + . Imports System.Drawing Public Class Form1 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) e.Graphics.DrawBezier(New Pen(Color.DarkBlue, 3), _ New PointF(10, 10), _ New PointF(110, 70), _ New PointF(160, 30), _ New PointF(210, 110)) End Sub End Class Est e código en ej ecución es el que puede v er se en la figur a 2. Re pre se nt a ción de la s curv a s de Bé zie r con GDI + e n Visua l Ba sic 2 0 1 0 Figur a 2 Rellenando cur vas En algunas ocasiones, nos podem os v er con la necesidad de cr ear cur v as y de r ellenar su int er ior par a dest acar lo de alguna m aner a. Est o es lo que v er em os a cont inuación. El m ét odo Ad d Ar c nos per m it e añadir una ser ie de punt os par a r epr esent ar una cir cunfer encia. En r ealidad, se r epr esent an punt os, los cuales son el punt o ( x , y ) inicial, el ancho y el alt o de la r epr esent ación, el ángulo de com ienzo de r epr esent ación, y el ángulo final de la r epr esent ación. En ej em plo que v er em os a cont inuación, ut ilizar em os t am bién los m ét odos FillPa t h y D r a w Pa t h , par a r epr esent ar la cur v a en el for m ular io. El código del ej em plo es el que se det alla a cont inuación: Imports System.Drawing Public Class Form1 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) Me.BackColor = Color.LightBlue Dim Camino As New Drawing2D.GraphicsPath() Camino.AddArc(50, 0, 150, 150, 0, 180) e.Graphics.FillPath(Brushes.White, Camino) e.Graphics.DrawPath(Pens.Black, Camino) End Sub End Class En la figur a 3, podem os v er el ej em plo en ej ecución. Ej e m plo de un dibuj o de curv a s ce rra da s re lle na ndo su int e rior Figur a 3 D ibuj ando t ar t as Ot r a posibilidad que nos ofr ece GDI + es la r epr esent ación de las conocidas t ar t as. Todas est as r epr esent aciones son r epr esent aciones 2D, per o siem pr e se puede em ular una r epr esent ación 3D, super poniendo t ar t as una encim a de ot r a. El siguient e ej em plo, ut iliza los m ét odos FillPie y D r a w Pie par a gener ar un gr áfico de t ar t a y r ellenar lo de un det er m inado color . El código de nuest r o ej em plo, quedar ía de la siguient e m aner a: Imports System.Drawing Public Class Form1 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) e.Graphics.FillPie(Brushes.LightBlue, 50, 20, 120.0F, 120.0F, 115.0F, 180.0F) e.Graphics.DrawPie(Pens.DarkBlue, 50, 20, 120.0F, 120.0F, 115.0F, 180.0F) e.Graphics.FillPie(Brushes.White, 50, 20, 120.0F, 120.0F, 0.0F, 115.0F) e.Graphics.DrawPie(Pens.DarkOrange, 50, 20, 120.0F, 120.0F, 0.0F, 115.0F) End Sub End Class Nuest r o ej em plo en ej ecución, es el que se m uest r a en la figur a 4. De m ost ra ción de cóm o cre a r grá ficos de t a rt a s y com o re lle na r su int e rior Figur a 4 Consej o: Cuando r epr esent e gr áficas de t ar t as por ej em plo y desee r ellenar una par t e de est a de un color y m ar car el bor de en ot r o color , use pr im er o el m ét odo FillPie y después el m ét odo Dr awPie, en caso cont r ar io, la r epr esent ación gr áfica per der á nit idez com o se indica en la siguient e im agen: Módulo 3 - Capítulo 4 5. Dibujando cadenas de texto con GDI+ Com o hem os v ist o y a en el capít ulo r efer ent e a la cr eación de nuest r os pr opios cont r oles, desde Visual Basic 2010, podem os ut ilizar GDI + par a cr ear cadenas de t ex t o y m anipular las com o deseem os. En los siguient es apar t ados v er em os com o r epr esent ar cadenas de t ex t o desde Visual Basic 2010 D ibuj ando cadenas de t ext o El m ét odo D r a w St r in g nos per m it e r epr esent ar cadenas de t ex t o de for m a gr áfica. El funcionam ient o en Visual Basic 2010 de est as inst r ucciones es r ealm ent e sim ple. El siguient e ej em plo, ilust r a en cóm o abor dar un pequeño pr oy ect o par a r epr esent ar una cadena de t ex t o en pant alla. Imports System.Drawing Public Class Form1 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) Dim MiFuente As New Font("Verdana", 24, FontStyle.Bold) Dim Brocha As New SolidBrush(Color.BurlyWood) e.Graphics.DrawString("Ejemplo GDI+", MiFuente, Brocha, 10, 10) End Sub End Class Est e ej em plo en ej ecución es el que puede v er se en la figur a 1. Ej e m plo de cóm o inse rt a r una ca de na de t e x t o grá fica m e nt e e n un form ula rio Figur a 1 D ibuj ando cadenas de t ex t o con t ext ur a Ot r a par t icular idad que a est as alt ur as y a no lo es t ant o, es la posibilidad de t r abaj ar con t ex t ur as dent r o de cadenas de t ex t o. Com o si est uv iér am os dibuj ando una cadena de t ex t o, la única v ar iación es que asignam os com o br ocha de dibuj o, una t ex t ur a det er m inada. El siguient e código, aclar ar á suficient em ent e est o que com ent o. Imports System.Drawing Public Class Form1 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) Dim Imagen As New Bitmap("c:\Flag.bmp") Dim TexturaDeFondo As New TextureBrush(Imagen) Dim MiFuente As New Font("Arial", 30, FontStyle.Bold) e.Graphics.DrawString("Ejemplo GDI+", MiFuente, TexturaDeFondo, 4, 10) End Sub End Class El r esult ado de est e ej em plo, es el que puede v er se en la figur a 2. De m ost ra ción de l e fe ct o de a ña dir una t e x t ura a la re pre se nt a ción de una ca de na de t e x t o Figur a 2 Módulo 3 - Capítulo 4 6. Otras consideraciones Uso de degr adados con GD I + GDI + pr opor ciona un v ar iadísim o j uego de br ochas que nos per m it en dibuj ar degr adados en un for m ular io o cont r ol que per m it a el t r abaj o con gr áficos. El siguient e ej em plo de código, nos m uest r a com o dibuj ar un degr adado en un for m ular io Window s. Imports System.Drawing Public Class Form1 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) Dim Forma As New Rectangle(New Point(0, 0), Me.ClientSize) Dim Gradiente As New Drawing2D.LinearGradientBrush(Forma, _ Color.Cyan, _ Color.DarkBlue, _ Drawing2D.LinearGradientMode.ForwardDiagonal) e.Graphics.FillRegion(Gradiente, New Region(Forma)) End Sub End Class La figur a 1 r epr esent a el ej em plo ant er ior en ej ecución Re pre se nt a ción grá fica de un de gra da do e n una v e nt a na W indow s Figur a 1 Ev ident em ent e, podem os j ugar con la clase Lin e a r Gr a d ie n t Br u sh y con la list a enum er ada Lin e a r Gr a d ie n t M od e par a dar una aspect o o un t oque liger am ent e difer ent e al degr adado, com o el que se indica en la figur a 2. Ot ro e j e m plo de re pre se nt a ción de gra da da e n un form ula rio W indow s Figur a 2 I nser t ando y t r abaj ando con im ágenes con Syst em .D r aw ing Sir v a com o det alle gener al, que GDI + nos per m it e t am bién, t r abaj ar con im ágenes. Par a car gar una im agen en un for m ular io con GDI + , ut ilizar em os el m ét odo D r a w I m a g e . Un ej em plo del uso de est e m ét odo par a car gar una im agen en un for m ular io es el siguient e: Imports System.Drawing Public Class Form1 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) e.Graphics.DrawImage(New Bitmap("c:\159.jpg"), 1, 1) End Sub End Class La figur a 3 nos m uest r a el r esult ado final de inser t ar una im agen en el for m ular io Window s. I m a ge n inse rt a da con GDI + de nt ro de l form ula rio W indow s Figur a 3 Aplicando t r anspar encias a una im agen Ot r a de las car act er íst icas que nos ofr ece GDI + , es el t r abaj o con im ágenes aplicando t r anspar encias. Par a r ealizar est o, deber em os indicar el color o color es que quer em os ut ilizar par a pr ov ocar en él un efect o t r anspar ent e. El siguient e ej em plo, nos m uest r a com o hacer est o ut ilizando par a ello el m ét odo M a k e Tr a n sp a r e n t . Imports System.Drawing Public Class Form1 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) Dim Imagen As New Bitmap("c:\Flag.bmp") e.Graphics.DrawImage(New Bitmap(Imagen), 1, 1) Imagen.MakeTransparent(Color.FromArgb(255, 0, 51, 153)) e.Graphics.DrawImage(New Bitmap(Imagen), 100, 1) End Sub End Class I m a ge n inse rt a da con GDI + de nt ro de l form ula rio W indow s Figur a 4 Introducción En este capítulo, aprenderemos lo que son los ensamblados o assem blies, un término completamente nuevo para los desarrolladores de otros entornos distintos de .NET, y aprenderemos a desplegar o instalar nuestras aplicaciones. Siempre que terminamos de desarrollar un proyecto, nos aborda la duda y pregunta casi obligada de ¿y ahor a qué?. Eso es lo que veremos en este capítulo... el qué. Módulo 3 - Capítulo 5 ● 1. Desmitificando los ensamblados ● 2. Desplegando con XCOPY ● 3. GAC y Strong Names ● 4. Creando un paquete de instalación ● 5. Otras consideraciones Módulo 3 - Capítulo 5 1. Desmitificando los ensamblados Un concept o com plet am ent e nuev o par a los que nunca han desar r ollado con . NET, es la palabr a Asse m b ly , denom inada ensam blado. Los ensam blados, son par a ent ender lo m uy r ápidam ent e, com o los ej ecut ables de una aplicación. La única difer encia not able, es que en . NET, un pr oy ect o o aplicación, se com pila en código int er m edio, el conocido com o I nt er m ediat e Language o lenguaj e int er m edio, que luego int er pr et ar á el CLR o Com m on Language Runt im e par a ej ecut ar la en el sist em a oper at iv o cor r espondient e. Ese código int er m edio, es el ensam blado de nuest r a aplicación que a su v ez puede cont ener uno o m ás ficher os, y a su v ez, un pr oy ect o, puede est ar cont enido por uno o m ás ensam blados. Por lo t ant o, dent r o de un ensam blado, se encier r an algunas par t es im por t ant es que debem os conocer . Lo m ej or par a ent ender bien lo que hay en un ensam blado y que cont iene es que abr am os Visual St udio 2010 y seleccionem os una plant illa de pr oy ect o de t ipo Con sole Ap p lica t ion com o se m uest r a en la figur a 1. Se le cciona ndo un proy e ct o de t ipo Console Applica t ion Figur a 1 A cont inuación, escr ibir em os un ej em plo sim ple de consola, par a que est udiem os el r esult ado de ést e. El código fuent e de nuest r a pequeña aplicación de ej em plo, es el que se det alla a cont inuación: Module Module1 Sub Main() Console.WriteLine("Ejemplo de consola") Console.WriteLine("") Console.Write("<Pulse Enter para terminar>") Console.ReadLine() End Sub End Module Nuest r o ej em plo de pr ueba en ej ecución, es el que puede v er se en la figur a 2. Ej e cución de l e j e m plo de Consola Figur a 2 Ahor a bien, lo que t enem os una v ez com pilam os nuest r a aplicación de consola, no es un ej ecut able com o t al o com o lo ent ender íam os en ot r os com pilador es, por ej em plo en Visual C+ + . En Visual C+ + , gener ábam os un ej ecut able nat iv o al sist em a en el cuál com pilábam os el pr oy ect o y si ese ej ecut able lo llev ábam os a ot r a m áquina con ot r o sist em a oper at iv o difer ent e a Window s, ese pr ogr am a no iba a funcionar . Con . NET y en nuest r o caso con Visual Basic 2010, est e concept o ha cam biado. El pr oy ect o que hem os desar r ollado no se com pila a un ej ecut able nat iv o, sino que el sist em a . NET lo com pila a un lenguaj e int er m edio, que luego el CLR de la m áquina en la cuál lanzam os nuest r a aplicación, ser á capaz de int er pr et ar adecuadam ent e. Puede que est os concept os le puedan desor ient ar un poco, per o es m uy fácil de com pr ender . Adicionalm ent e a est o, lo suy o es dest r ipar un poco lo que hay dent r o del ensam blado que hem os conv er t ido a código int er m edio. Par a llev ar a cabo nuest r a t ar ea, har em os uso de una her r am ient a ex t er na de Micr osoft y del ent or no Visual St udio 2010, que nos per m it e analizar el ensam blado de un pr oy ect o conv er t ido a código int er m edio. Aclar ación: Un ensam blado o el código int er m edio, ( I L a par t ir de ahor a) , no es ni el código fuent e de nuest r a aplicación ni el pr ogr am a ej ecut able. El I L se puede analizar con una her r am ient a de Micr osoft denom inada ildasm . Si est á usando una ver sión Ex pr ess de Visual St udio debe saber que est a her r am ient a no se incluy e con est as v er siones, sólo for m a par t e del SDK de .NET Fr am ewor k que se incluy e con las v er siones de Visual St udio 2010. Cuando abr im os el ficher o ej ecut able de nuest r a aplicación con la her r am ient a ildasm . ex e, obser v am os que est a t iene una gr an cant idad de infor m ación, com o se indica en la figur a 3. ilda sm con e l fiche ro e j e cut a ble de nue st ra a plica ción de e j e m plo a bie rt o Figur a 3 Ant es de adent r ar nos m ás en los ent r esij os de un ensam blado, piense en él com o si fuer a una colección de elem ent os. Esos elem ent os, pueden ser r ecur sos, t ipos, funcionalidades, que t odas j unt as, for m an nuest r a aplicación. Así, lo pr im er o que v em os en la figur a 3, es la palabr a M AN I FI EST. Refer encias a las libr er ías ut ilizadas que el CLR deber á int er pr et ar post er ior m ent e. Luego encont r am os ot r as el ám bit o de la aplicación y las clases de ést a, con sus m ét odo t ant o est át icos com o no est át icos. No es cuest ión de ent r ar m ucho m ás en det alle del código I L que cont iene un pr oy ect o com pilado en . NET com o ést e, per o es conv enient e a v er lo par a ent ender los concept os que est am os t r at ando. En la figur a 4, t enem os el código I L del m ét odo M a in . El código I L de l m é t odo Ma in de la a plica ción de e j e m plo Figur a 4 Los ensam blados com o podem os v er , cont iene m ás infor m ación de la que pr opiam ent e t endr ía un ej ecut able "nor m al". Un ensam blado en . NET, cont iene t am bién com o hem os podido v er , dat os e infor m ación que encont r ar íam os en cualquier t ipo de libr er ía, lo cuál r epr esent a adem ás, t oda la infor m ación necesar ia del CLR en cualquier m om ent o. Con t odo est o, podem os r esum ir por lo t ant o, que un ensam blado cont iene código, r ecur sos y m et adat os. El código en I L es el código que ser á ej ecut ado por el CLR. Adem ás, cualquier r ecur so ( im ágenes, m et adat os, et c. ) son accesibles en el ensam blado. Los m et adat os por su par t e, cont iene infor m ación sobr e las clases, int er fases, m ét odos y pr opiedades, que posibilit an t oda la infor m ación necesar ia por el CLR par a poder ej ecut ar nuest r a aplicación cor r ect am ent e. Módulo 3 - Capítulo 5 2. Desplegando con XCOPY N ot as pr evias Todas las aplicaciones desar r olladas con . NET est án aisladas, no com o ocur r e con los com pilados pr e- . NET, de m aner a t al que los conflict os con las DLL se han v ist o r educidos enor m em ent e, por no decir que han desapar ecido. El fam oso infier no de las DLLs que t ant o hem os sufr ido los desar r ollador es, ha pasado y a a la hist or ia. Tam bién podem os usar com ponent es pr iv ados. Bast a con copiar los al m ism o dir ect or io en el que se encuent r a nuest r a aplicación ej ecut able. Adem ás, . NET nos per m it e t ener m ás de un com ponent e v er sionado ( difer ent es v er siones de un m ism o com ponent es) dent r o de un m ism o or denador , por lo que los pr oblem as de com pat ibilidad est ar ían r esuelt os. Con est os det alles, r epasam os algunas de las m ej or as a la hor a de desplegar o inst alar una aplicación desar r ollada con Visual Basic 2010 en un sist em a. A cont inuación, v er em os algunas anot aciones adicionales que nos ay udar án a r ealizar est as y ot r as acciones. XCOPY Lo que nos ofr ece X COPY a los desar r ollador es e ingenier os, es la posibilidad de inst alar e im plem ent ar nuest r a solución y pr oy ect o a un sist em a de una m aner a r ápida, fiable y sin apenas im pact o. El m ét odo X COPY par a desplegar aplicaciones, pasa por alt o la posibilidad de im plem ent ar los ensam blados en la GAC, algo que según det er m inadas cir cunst ancias, r esult a m ás que pr ov echoso. Hay que t ener en cuent a, que si hacem os un m al uso de la GAC, ést a puede conv er t ir se en un desv án difícil de gest ionar . Ut ilice la GAC con cr it er io y si no quier e com plicaciones, despliegue sus aplicaciones con X COPY. Com o habr á podido y a obser v ar , dent r o de un pr oy ect o de Visual Basic 2010, nos podem os encont r ar con una ex t ensa est r uct ur a de dir ect or ios. Est a est r uct ur a, lej os de ser una m olest ia, const it uy e las car act er íst icas m ás im por t ant es a la hor a de desplegar nuest r as aplicaciones a t r av és de X COPY. Com o v em os, t odo en . NET t iene su sent ido y t iene un por qué. Par a inst alar nuest r a aplicación desar r ollada en Visual Basic 2010 en un sist em a client e, bast ar á por lo t ant o, con r ealizar una acción sim ilar al X COPY de DOS, es decir , copiar em os en el or denador client e, los ficher os o ensam blados necesar ios ( ej ecut ables, r ecur sos, dlls, et c. ) de la est r uct ur a de nuest r o pr oy ect o. Debem os t ener en cuent a, que en ot r os lenguaj es basados en COM, com o Visual Basic 6, podíam os hacer est o igualm ent e, per o debíam os adem ás r egist r ar las DLL con aquel fam osísim o com ando r egsv r 32 par a que no hubier a pr oblem as, aún así, algunas v eces nos encont r ábam os con algunos cont r at iem pos, sin em bar go, con Visual Basic 2010, est a for m a de t r abaj ar ha desapar ecido y ahor a el despliegue de una aplicación es m ucho m ás sencilla. ¡Oj o! Cuando desar r ollem os una aplicación, t enga en cuent a ot r os r ecur sos que ut iliza en la m ism a. Cr yst al Repor t s, bases de dat os SQL Ser ver , que la m áquina client e disponga de .NET Fr am ewor k o de la ver sión m ínim a de MDAC necesar ia, et c. En caso cont r ar io, la ej ecución de nuest r a aplicación, podr ía no funcionar o pr ovocar algún t ipo de excepción o er r or . Por últ im o, y aunque par ezca de per ogr ullo, no olvide que debe t ener los per m isos necesar ios par a inst alar y ej ecut ar los ensam blados y ot r as par t es de Soft war e, necesar ios par a ej ecut ar su aplicación. Módulo 3 - Capítulo 5 3. GAC y Strong Names GAC El GAC o Global Assem bly Cache no es ot r a cosa que un r eposit or io de ensam blados globales. I m aginem os que ust ed t odos los días cuando llega a casa de t r abaj ar , lo pr im er o que hace es quit ar se los zapat os y poner se una zapat illas cóm odas par a est ar por casa. Lo lógico en est e caso, ser á sit uar un zapat er o o un pequeño ar m ar it o par a que ponga ahí las zapat illas, y a que t odos los días, hace r epet it iv am ent e est a oper ación. Obv iam ent e, las zapat illas deben de est ar ahí y no en la ot r a punt a de la casa, per o par a est ar en ese zapat er o, deber á cum plir una ser ie de r equisit os que ust ed m ism o ex ige, por lo que no t odos los zapat os o zapat illas deber ían est ar ahí. El GAC funciona de una m aner a r ealm ent e sem ej ant e. En el GAC se incluy en aquellas libr er ías o ensam blados que son ut ilizados fr ecuent em ent e. Si ust ed v a a desar r ollar y dist r ibuir su pr opio ensam blado, conv endr ía poner lo en el GAC. Una aplicación . NET, lo pr im er o que hace cuando se ej ecut a, es r ev isar los ensam blados que v a a necesit ar , y el pr im er sit io dónde v a a ir a buscar lo es en el GAC. Sino lo encuent r a, se pondr á a buscar lo en el dir ect or io en el que se encuent r a el ficher o ej ecut able, per o est o r eper cut e en el r endim ient o. Si nuest r as aplicaciones ut ilizan fr ecuent em ent e unos ensam blados, ser ía lógico y conv enient e poner los en el GAC. ¿Y cóm o se añade un ensam blado al GAC?. La t ar ea no es sencilla, y a que par a añadir lo debem os r ealizar algunos pasos, ent r e los que est á el cr ear un nom br e fuer t e o St r on g N a m e . St r ong N am es Con los St r on g N a m e s, asegur am os un uso segur o de los com ponent es cont enidos en el ensam blado. Hay que t ener en cuent a que un ensam blado declar ado en la GAC que es llam ado por v ar ias aplicaciones, cr ea una única inst ancia. De ahí, que cr ear un St r on g N a m e par a el ensam blado, est á m ás que j ust ificado. Un St r on g N a m e , nos asegur a por ot r o lado, que el nom br e de un ensam blado es único y que por lo t ant o, al ser único, no puede ser ut ilizado por ot r os ensam blados. Los St r on g N a m e s se gener an con un par de clav es, una de ellas de car áct er público y ot r a de car áct er pr iv ado, clav es que se int r oducen en ficher o de ensam blado de la aplicación, y que luego al com pilar nuest r a aplicación, queda r egist r ada con ese St r on g N a m e . Par a indicar un St r on g N a m e s a un ensam blado, debe cr ear pr im er o el par de clav es ( clav e pública y clav e pr iv ada) , que se gener ar á en un ficher o con ex t ensión sn k , y m odificar post er ior m ent e el ficher o Assem bly I nfo. v b de su pr oy ect o. En ese ar chiv o, debe añadir una inst r ucción sim ilar a la siguient e: < Assem bly: Assem blyKeyFile( "KeyFile.snk") > Módulo 3 - Capítulo 5 4. Creando un paquete de instalación Set up Pr oj ect Ot r a acción habit ual, es que cuando desar r ollem os nuest r as aplicaciones, gener em os difer ent es dependencias con ot r os ensam blados o com ponent es, par a lo cuál, la for m a m ás sencilla de desplegar nuest r a aplicación, es gener ando un paquet e de dist r ibución que cont enga esas dependencias y r elaciones. N ot a: Si est á ut ilizando Visual Basic 2010 Expr ess no t endr á disponible la opción de pr oyect o Set up. Con la plant illa Set up Pr oj ect cr ear em os un nuev o pr oy ect o par a gener ar el paquet e de dist r ibución e inst alación de nuest r a aplicación y pr oy ect o. Cuando gener am os el paquet e de inst alación, debem os t ener en cuent a que se gener an dos ar chiv os que por lo gener al t endr án los nom br es de Set up. ex e y Set up. m si. La difer encia ent r e am bos ficher os es que el ficher o con ex t ensión e x e inst alar á Window s I nst aller si es necesar io, m ient r as que el ficher o con ex t ensión m si, no inst alar á Window s I nst aller , por lo que si Window s I nst aller no est á pr esent e en la m áquina en la que se ej ecut a el pr ogr am a de inst alación, dar á un er r or . Ot r a consider ación a t ener en cuent a cuando gener am os el paquet e de inst alación, es en el m om ent o de la dist r ibución, el asegur ar que el sist em a dest ino t enga el . NET Fr am ew or k cor r espondient e. Suger encia: ¿Cóm o usar Visual St udio 2010 par a dist r ibuir Micr osoft .NET Fr am ewor k? Más que int er esant e ar t ículo dónde obt endr á infor m ación adicional sobr e cóm o gener ar un paquet e de inst alación par a dist r ibuir .NET Fr am ewor k. Using Visual St udio .NET t o Redist ribut e t he .NET Fram ew o rk ( en inglés) Respect o al com por t am ient o de Window s I nst aller sobr e aplicaciones y a inst aladas que deseam os desinst alar , el ent or no se com por t a de m aner a t al, que si det ect a com ponent es com par t idos, est os no son desinst alados del sist em a. Ot r o com por t am ient o de Window s I nst aller es el que nos per m it e echar m ar cha at r ás si el pr oceso de inst alación se cancela o falla por algún m ot iv o. Window s I nst aller dej ar á el sist em a en el m ism o est ado que t enía j ust o ant es de r ealizar la inst alación. Tipos de despliegues de pr oyect os Cuando gener am os un paquet e de inst alación t enem os dent r o del ent or no de desar r ollo Visual St udio v ar ias opciones, com o se indica en la im agen 1. Así, nos podem os encont r ar por lo gener al con difer ent es t ipos de despliegues de pr oy ect os. Tipos de de splie gue de proy e ct os e n Visua l St udio Figur a 1 La plant illa Ca b Pr oj e ct El ficher o con ex t ensión CAB es un ficher o com pr im ido que cont iene t odos los ficher os y r ecur sos necesar ios par a inst alar nuest r a aplicación. Por lo gener al, est e t ipo de ficher os son usados par a descar gar los de Ser v idor es Web. Por lo gener al y en nuest r o caso, cr ear em os aplicaciones Window s, y deber íam os ent onces ut ilizar la plant illa Se t u p Pr oj e ct . Si ut ilizam os la plant illa, M e r g e M od u le Pr oj e ct , cr ear em os un paquet e inst alación par a com ponent es com par t idos. El uso de la plant illa, W e b Se t u p Pr oj e ct por su par t e, nos per m it ir á gener ar un paquet e de inst alación par a aplicaciones basadas en I nt er net o aplicaciones Web. La plant illa, Se t u p W iz a r d gener a un asist ent e par a gener ar uno de los cuat r o ant er ior es t ipos de pr oy ect os de despliegue. Es una for m a r ápida de gener ar el pr oy ect o de despliegue. Módulo 3 - Capítulo 5 5. Otras consideraciones Set up Pr oj ect Ya lo hem os com ent ado por encim a en los capít ulos ant er ior es sobr e el Despliegue de aplicaciones, per o cuando se pr ocede a inst alar y dist r ibuir una aplicación en ot r os sist em as, se deben t ener en cuent a difer ent es aspect os que no podem os pasar por alt o. Debem os conocer en pr im er lugar , la nat ur aleza del sist em a o sist em as dest ino dónde v am os a im plant ar nuest r o pr ogr am a. Ent endiendo y conociendo bien est o, podr em os saber qué aplicaciones Soft w ar e adicionales necesit ar em os par a abor dar nuest r o t r abaj o adecuadam ent e. Ent r e ot r os, debem os t ener en cuent a que el sist em a dest ino dónde se v a a ej ecut ar nuest r a aplicación dispone de los dr iv er s de acceso a dat os adecuados, MDAC ( v er sión 2. 6 ó super ior ) , y por supuest o de Micr osoft . NET Fr am ew or k . FAQ: ¿Cuando inst alar con Windows I nst aller y cuando a t r av és de XCOPY? I nt er esant e ar t ículo que debat e sobr e cuando inst alar con Windows I nst aller y cuando con XCOPY. Det erm ining When t o Use Windo w s Inst aller Versus XCOPY ( en inglés) El ant er ior ar t ículo, nos da un enfoque sobr e qué t ipo de inst alación o despliegue est ablecer de nuest r a aplicación desar r ollada con Visual Basic 2010. El concept o ClickOnce En Visual St udio 2010 se int r oduce un concept o nuev o denom inado Click Once. Est e concept o r epr esent a la t ecnología que per m it e inst alar y ej ecut ar aplicaciones Window s desde un ser v idor Web con una escasa acción por par t e del usuar io. I nicie un nuev o pr oy ect o Window s. Dent r o del for m ular io Window s inser t e un cont r ol But t on dent r o del cuál, inser t e un t ex t o ident ificat iv o com o el que se m uest r a en la figur a 1. Aplica ción W indow s de e j e m plo pa ra e x plica r e l conce pt o de Click Once Figur a 1 A cont inuación, escr iba el siguient e código fuent e: Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click MessageBox.Show("Ejemplo ClickOnce ejecutado a las:" & vbCrLf & Date.Now.ToLongTimeString) End Sub End Class Una v ez que ha escr it o el código fuent e de la aplicación, ej ecút ela y com pr uebe que funciona com o se esper a. Si lo desea, abr a el ficher o Assem bly I nfo v b e indique la v er sión de la aplicación que desee. En m i caso he dej ado la v er sión 1 0 0 0 que es la v er sión que apar ece por defect o. Después de est o, gener e la aplicación com o se indica en la figur a 2. Ge ne ra m os la a plica ción pa ra com proba r e nt re ot ra s cosa s que t odo e st á pre pa ra do Figur a 2 Por últ im o, pulse el bot ón secundar io del m ouse sobr e el pr oy ect o y seleccione la opción Pu b lica r . . . com o se indica en la figur a 3. Opción de Publica r la a plica ción pa ra e j e cut a r la t e cnología de dist ribución Click Once Figur a 3 Al ej ecut ar la opción Pu b lica r . . . , el ent or no nos m uest r a una v ent ana sim ilar a la que se m uest r a en la figur a 4. Asist e nt e de la publica ción de la a plica ción Figur a 4 Seleccione una ubicación par a publicar la aplicación y haga clic en el bot ón Sig u ie n t e . Apar ecer á en el asist ent e ent onces, una v ent ana sim ilar a la que se pr esent a en la figur a 5. Ve nt a na de l a sist e nt e pa ra indica r dónde e st a rá disponible la a plica ción Figur a 5 Pulse el bot ón Sig u ie n t e . Nuev am ent e, el asist ent e m ost r ar á una últ im a v ent ana sim ilar a la que se m uest r a en la figur a 6. Ve nt a na fina l de l a sist e nt e con un re sum e n de la s opcione s se le cciona da s Figur a 6 El asist ent e m uest r a en est e caso, una infor m ación de r esum en. Lo que har em os a cont inuación, ser á pr esionar el bot ón Fin a liz a r . Con est a acción, nuest r a aplicación est á y a publicada en el ser v idor Web, por lo que si abr im os una v ent ana de nuest r o ex plor ador Web y escr ibim os la dir ección en la cuál hem os publicado nuest r a aplicación, ést a se ej ecut ar á de for m a cor r ect a com o se indica en la figur a 7. Aplica ción W e b de l la nz a m ie nt o de la a plica ción W indow s a t ra v é s de l Se rv idor W e b Figur a 7 Si pr esionam os sobr e el bot ón I n st a la r del nav egador Web, obser v ar em os que el Ser v idor Web r ealiza difer ent es acciones de v er ificación. La pr im er a acción es una acción de conex ión com o la que se m uest r a en la figur a 8. La prim e ra a cción que se re a liza e s una a cción de cone x ión con e l Se rv idor W e b Figur a 8 Post er ior m ent e, puede apar ecer una v ent ana de segur idad com o la que se indica en la figur a 9, siem pr e y cuando no hay am os r ealizado un pr oceso de gener ación segur a o confiable de la aplicación, com o ha sido el caso. La a plica ción W indow s e j e cut a da a t ra v é s de l Se rv idor W e b, de be se r confia ble y se gura Figur a 9 En nuest r o caso, com o sabem os que no hay pr oblem a en ej ecut ar la aplicación, pr esionar em os el bot ón I n st a la r . Nuest r a aplicación en ej ecución es la que se m uest r a en la figur a 10. Aplica ción W indow s e n e j e cución Figur a 10 Cuando hacem os est o, siem pr e que ej ecut em os la aplicación, el sist em a det ect ar á que acept am os una v ez su segur idad, por lo que siem pr e se ej ecut ar á sin indicar nos ningún m ensaj e de segur idad. Ahor a bien, supongam os que decidim os m odificar par t e del código de nuest r a aplicación y que por supuest o, cam biam os la v er sión de la m ism a. Acuda ant es a la v ent ana del Ex plor ador de soluciones y obser v e que se ha añadido en la v ent ana un ficher o de nom br e Window sApplicat ion1_Tem por ar y Key pfx que cor r esponde a una llav e o clav e t em por al r elacionada con el pr oy ect o publicado. Est o es lo que se m uest r a en la figur a 11. Ve nt a na de l Ex plora dor de solucione s con e l fiche ro W indow sApplica t ion1 _ Te m pora ry Ke y .pfx a ña dido a é l Figur a 11 Vam os a act ualizar nuest r a aplicación y la v am os a cam biar la v er sión, por lo que ahor a escr ibir em os el siguient e código: Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click MessageBox.Show("Ejemplo ClickOnce ejecutado a las:" & vbCrLf & _ Date.Now.ToShortDateString & vbCrLf & _ Date.Now.ToLongTimeString) End Sub End Class La v er sión de la aplicación, no t iene r elación con la v er sión de publicación, por ej em plo, la v er sión de la aplicación la he m odificado a 1 1 0 0, per o el inst alador aut ogener a su pr opio núm er o de v er sión, el cual podem os cam biar en las pr opiedades del pr oy ect o, ficha Pu b lish . En la figur a 12 podem os v er la ficha Pu b lish de las pr opiedades del pr oy ect o. Ve nt a na W e b pa ra e j e cut a r la a plica ción Figur a 12 El siguient e paso que he hecho es com pilar la aplicación y publicar la nuev am ent e. Una v ez hecho est o, acudim os a la página Web de la aplicación y pr esionam os nuev am ent e el bot ón I n st a la r com o se indica en la figur a 13. Ve nt a na W e b pa ra e j e cut a r la a plica ción Figur a 13 La ej ecución de la aplicación se r ealizar á sin pr oblem as de m aner a sencilla y cont r olada. Com o v em os, la publicación de aplicaciones Window s a t r av és de un Ser v idor Web, lo que se denom ina t ecnología de publicación Click Once, es un pr oceso de publicación r ápido y sencillo, que apor t a gr andes v ent aj as y que en ot r as v er siones de . NET t r ae consigo algunos inconv enient es super ados en est a v er sión de . NET. Com unidad dot N et : Si quier e saber m ás sobr e Click Once, le r ecom iendo la lect ur a del siguient e ar t ículo, escr it o en español que com plem ent ar á y am pliar á la infor m ación de est e t ut or ial. ( D ciem bre 2 0 0 4 ) Im plem ent ac ó n de apl cac o nes de Windo w s Fo rm s co n ClickOnce Le cción 1 : Cole ccion e s de da t os Los t ipos de colecciones de .NET Las clases base par a cr ear colecciones Colecciones de t ipo gener ic ( en br eve) Le cción 2 : St r e a m s e n .N ET Las clases basadas en St r eam Manej ar un ficher o usando FileSt r eam Manej ar ficher os con St r eam Reader y St r eam Wr it er Cifr ar y descifr ar un ficher o Le cción 3 : Acce so a l sist e m a de a r ch ivos Las clases de Syst em .I O Clases par a m anipular unidades, dir ect or ios y ficher os Clases par a leer o escr ibir en st r eam s El obj et o My: My.Com put er .FileSyst em Le cción 4 : Acce so a I n t e r n e t Las clases de Syst em .Net Acceder a una página Web Acceder a un ser vidor FTP Acceso r ápido a la r ed con My.Com put er .Net wor k Obt ener infor m ación de la r ed con las clases de .NET Cuando necesit am os agr upar una ser ie de dat os que de alguna for m a est án r elacionados, en .NET ( y en ot r os "m ar cos" de desar r ollo) t enem os dos for m as de hacer lo: usando los ar r ays ( m at r ices) o usando las colecciones. De los ar r ays ya nos ocupam os ant er ior m ent e, así que en est a lección ( o capít ulo) vam os a ver cóm o usar las colecciones que .NET nos ofr ece. Tam bién ver em os, aunque sea de una m aner a m ás "sut il", el nuevo t ipo de colecciones que la ver sión 2.0 de .NET Fr am ewor k int r oduce y que ha sido ar r ast r ado a las difer ent es ver siones de .NET Fr am ewor k: las colecciones gener ic, t am bién conocidas com o colecciones genér icas. Cole ccione s de da t os Los t ipos de colecciones de .NET Las colecciones basadas en I Collect ion Las colecciones basadas en I List La colección Ar r ayList El t ipo de dat os de alm acenam ient o de las colecciones Las colecciones basadas en I Dict ionar y Alm acenar valor es en una colección t ipo I Dict ionar y Cóm o se alm acenan los elem ent os de las colecciones I Dict ionar y Obt ener t odas las claves y valor es de una colección I Dict ionar y Las clases base par a cr ear colecciones per sonalizadas Cr ear una colección basada en Collect ionBase Cr ear una colección basada en Dict ionar yBase Cr ear colecciones per sonalizadas usando colecciones gener ic La colección Client es en ver sión gener ic La colección Ar t iculos en ver sión gener ic Colecciones de t ipo gener ic Rest r icciones en los t ipos gener ic En la ver sión 2010 de Visual Basic, t enem os un am plio abanico de t ipos de colecciones, desde colecciones genér icas ( o de uso com ún, par a no confundir el t ér m ino con las colecciones "gener ic") , hast a colecciones especializadas, es decir , colecciones que est án pensadas par a usar las de for m a m uy concr et a y que por t ant o no nos sir ven par a usar las en la m ayor ía de las ocasiones. Em pecem os viendo los t r es t ipos básicos de colecciones que podem os ut ilizar en nuest r as aplicaciones de .NET. N ot a: Las colecciones que vam os a ver a cont inuación son las colecciones "clásicas" de .NET, ( cuyo t ipo int er no es Obj ect ) , per o debem os saber que t am bién exist en colecciones casi con las m ism as car act er íst icas per o que est án definidas en el espacio de nom br es Syst em .Collect ions.Gener ic, las cuales ut ilizan la nueva "t ecnología" de los t ipos genér icos ( gener ic) par a alm acenar los elem ent os, ( cuyo t ipo int er no puede ser de cualquier t ipo) . Los t ipos de cole ccione s de .N ET En .NET Fr am ewor k exist en t r es t ipos pr incipales de colecciones, ést as dependen del t ipo de int er faz que im plem ent an: Las colecciones basadas en I Collect ion Las colecciones basadas en la int er faz I List Las colecciones basadas en la int er faz I Dict ionar y Com o podem os im aginar , dependiendo del "cont r at o" fir m ado por cada una de est os t ipos de colecciones, podr em os hacer cier t as oper aciones con ellas. A cont inuación ver em os con m ás det alle est os t ipos de colecciones y cuales son las que podem os usar dependiendo del int er faz que cada una de ellas im plem ent e. N ot a: La difer encia básica ent r e est os t ipos de colecciones es cóm o est án alm acenados los elem ent os que cont ienen, por ej em plo, las colecciones de t ipo I List ( y las dir ect am ent e der ivadas de I Collect ion) solo alm acenan un valor , m ient r as que las colecciones de t ipo I Dict ionar y guar dan un valor y una clave r elacionada con dicho valor . Tam bién ver em os unas clases base que im plem ent an cada una de est as dos int er faces, las cuales las podem os usar com o base de nuest r as pr opias colecciones per sonalizadas. La s cole ccion e s ba sa da s e n I Colle ct ion La int er faz I Collect ion es un caso apar t e, ya que r ealm ent e t odas las colecciones de .NET im plem ent an est a int er faz, de hecho, est a int er faz se der iva de I Enum er able que es la que n os per m it e r ecor r er las colecciones usando bucles For Each. Est a int er faz no la t endr em os que usar de for m a habit ual, ya que r ealm ent e el r est o de colecciones ( e int er faces) út iles ya se der ivan de ella, por t ant o vam os a cent r ar nos en las ot r as dos. Aunque es im por t ant e que t engam os en cuent a que el r est o de colecciones im plem ent an I Collect ion, por t ant o siem pr e podr em os usar un obj et o de est e t ipo par a acceder a cualquier colección. I ndependient em ent e de que t odas las colecciones de .NET est én basadas en est a int er faz, hay cier t os t ipos de colecciones que solo im plem ent an est a int er faz, por ej em plo las colecciones de t ipo Queue, St ack o Bit Ar r ay, por t ant o esas colecciones est ar án lim it adas a los m ét odos expuest os por la int er faz I Collect ion y los que esas colecciones im plem ent en de for m a independient e. Por r egla gener al, los t ipos que solo se basan en I Collect ion suelen ser colecciones que no necesit an de las car act er íst icas que pr opor cionan las ot r as int er faces y, por r egla gener al, nos per m it en la m anipulación de los dat os de una for m a básica o elem ent al, de for m a que su uso sea par a casos m uy concr et os. Por ej em plo, la clase Queue nos per m it e cr ear fácilm ent e una colección de t ipo FI FO ( pr im er o en ent r ar , pr im er o en salir ) ; por ot r a par t e, con la clase St ack podem os cr ear colecciones del t ipo LI FO ( últ im o en ent r ar , el pr im er o en salir ) , de for m a que sean m uy út iles par a cr ear "pilas" de dat os. El caso de la ot r a clase que hem os com ent ado: Bit Ar r ay, nos sir ve par a alm acenar valor es de t ipo "bit ", en el que cada valor se alm acena com o un cer o o un uno, de for m a que podam os t ener una colección m uy com pact a, per o, t am bién m uy específica y no de uso gener al, ya que en est e caso par t icular , los m ét odos que im plem ent a est a clase est án enfocados en la m anipulación de valor es de t ipo Boolean, ( False y Tr ue) , aunque int er nam ent e se alm acenen com o valor es cer o y uno r espect ivam ent e. N ot a: Realm ent e la clase Bit Ar r ay no se com por t a com o una colección "nor m al", ya que el t am año de la m ism a debem os cont r olar lo nosot r os, al igual que ocur r e con los ar r ays, aunque de for m a m ás "fácil", m ediant e la pr opiedad Lengt h. La s cole ccion e s ba sa da s e n I List La int er faz I List se ut iliza en las colecciones a las que quer em os acceder m ediant e un índice, por ej em plo, los ar r ays r ealm ent e est á basados en est a int er faz, y t al com o pudim os com pr obar , la única for m a que t enem os de acceder a los elem ent os de un ar r ay, ( y por ext ensión a los elem ent os de las colecciones basadas en I List ) , es m ediant e un índice num ér ico. Exist en t r es t ipos pr incipales de colecciones que im plem ent an est a int er faz: Las de solo lect ur a, colecciones que no se pueden m odificar . Est e t ipo de colecciones suelen basar se en la clase abst r act a ReadOnlyCollect ionBase. Las colecciones de t am año fij o, no se pueden quit ar ni añadir elem ent os, per o si m odificar los. Por ej em plo, las colecciones basadas en Ar r ay son de t am año fij o. Las de t am año var iable per m it en cualquier t ipo de adición, elim inación y m odificación. La m ayor ía de las colecciones suelen ser de est e t ipo, es decir , nos per m it en dinám icam ent e añadir o elim inar elem ent os. Exist e un gr an núm er o de colecciones en .NET que im plem ent an est a int er faz, ( sobr e t odo las colecciones basadas en cont r oles) , ent r e las que podem os dest acar las siguient es: Ar r ayList , la colección "clásica" par a est e t ipo de int er faz. Cont iene t odos los m iem br os habit uales en est e t ipo de colecciones. Collect ionBase, una clase abst r act a par a poder cr ear nuest r as pr opias colecciones basadas en I List . St r ingCollect ion, una colección especializada que solo puede cont ener valor es de t ipo cadena. La colección Ar r ayList Tal com o hem os com ent ado, el t ipo de colección que se usa com o r efer encia a la hor a de hablar de las colecciones basadas en la int er faz I List , es Ar r ayList . Est a colección per m it e añadir , elim inar y m odificar fácilm ent e los elem ent os que cont iene. Tam bién podem os r ecor r er los m ediant e un bucle For accediendo a los elem ent os por m edio de un índice e incluso m ediant e un bucle del t ipo For Each. Al igual que ocur r e con los ar r ays, el índice infer ior es siem pr e el cer o y los elem ent os se alm acenan de for m a consecut iva, es decir , si añadim os dos elem ent os a una colección de t ipo Ar r ayList ( y a las que im plem ent en la int er faz I List ) , el pr im er o ocupar á la posición cer o y el segundo la posición uno. La vent aj a de t r abaj ar con las colecciones es que no debem os pr eocupar nos de r eser var m em or ia cada vez que vayam os a añadir un nuevo elem ent o, sim plem ent e usam os el m ét odo Add y asunt o ar r eglado. Lo m ism o ocur r e a la hor a de quit ar elem ent os de una colección, no t enem os que pr eocupar nos dem asiado por el espacio dej ado al quit ar elem ent os, de eso se encar ga el pr opio .NET, nosot r os sim plem ent e debem os llam ar al m ét odo Rem ove o Rem oveAt indicando r espect ivam ent e el elem ent o a elim inar o el índice en el que se encuent r a alm acenado. Tr uco: Si decidim os elim inar var ios elem ent os de una colección de t ipo I List ( o de un ar r ay) , lo nor m al es que lo hagam os usando un bucle For ; si est e es el caso, par a evit ar una posible excepción, ( r ealm ent e no es posible, sino con t oda cer t eza segur a) , debem os r ecor r er el bucle desde el final hacia adelant e, con idea de que al cam biar el núm er o de elem ent os no falle al int ent ar a acceder a un elem ent o que ya no exist e. El t ipo de dat os de alm acenam ient o de las colecciones Est os elem ent os int er nam ent e est án alm acenados com o obj et os del t ipo Obj ect , por t ant o podem os añadir cualquier t ipo de dat os a una colección de est e t ipo, ya que t odos los t ipos de dat os de .NET est án basado en la clase Obj ect . El pr oblem a con est e t ipo de colecciones es que siem pr e que quer am os acceder a uno de los elem ent os que cont iene, debem os hacer una conver sión al t ipo adecuado, es decir , si en una colección de est e t ipo guar dam os obj et os de t ipo Client e y quer em os acceder a uno de ellos, debem os hacer una conver sión ( cast ) del t ipo Obj ect al t ipo Client e, ya que si no lo hacem os y t enem os act ivada Opt ion St r ict ( la opción par a las com pr obaciones est r ict as) , se pr oducir á un er r or si hacem os algo com o est o: Dim lista As New ArrayList lista.Add(New Cliente("Pepe")) lista.Add(New Cliente("Lola")) Dim unCliente As Cliente ' ¡Error! unCliente = lista(0) ... Por t ant o, la últ im a línea deber íam os escr ibir la de una de est as dos for m as: ' Usando CType para hacer la conversión unCliente = CType(lista(0), Cliente) ... ' Usando DirectCast para hacer la conversión (más recomendable) unCliente = DirectCast(lista(0), Cliente) Ot r o de los pr oblem as que t ienen las colecciones "nor m ales" es que en algunos casos, par t icular m ent e cuando alm acenam os t ipos por valor , el r endim ient o se ve bast ant e m er m ado, ya que el r unt im e de .NET ( el CLR) debe hacer lo que en inglés se conoce com o boxing/ unboxing, es decir , conver t ir un t ipo por valor en uno por r efer encia cuando va a guar dar lo en la colección ( boxing) , y el pr oceso inver so cuando lo quer em os r ecuper ar ( unboxing) . N ot a: Por suer t e, en Visual Basic 2010 t enem os ot r a for m a de m ej or ar el r endim ient o de las colecciones, y es m ediant e las colecciones "gener ic", de est o, nos ocupar em os m ás adelant e. Ot r as de las vent aj as de las colecciones de .NET, no solo las basadas en la int er faz I List , es que pr opor cionan una gr an cant idad de m ét odos que nos facilit an la m anipulación de ese t ipo de dat os. Por ej em plo, t enem os m ét odos par a clasificar el cont enido de las colecciones, ( aunque esos obj et os deben im plem ent ar la int er faz I Com par able, t al com o vim os en el últ im o ej em plo del capít ulo de las int er faces) , adem ás t ienen m ét odos par a hacer copias, buscar elem ent os y m uchos et cét er as m ás. La s cole ccion e s ba sa da s e n I Dict ion a r y El ot r o gr upo de colecciones que podem os encont r ar en .NET son las colecciones basadas en la int er faz I Dict ionar y. Ést as, a difer encia de las colecciones I List , siem pr e m ant ienen el par clave/ valor , ya que la for m a de acceder a los elem ent os es m ediant e una clave única. Por t ant o, cada vez que añadim os un elem ent o a una colección de est e t ipo t endr em os que indicar una clave y un valor . Cada valor est ar á r elacionado con su cor r espondient e clave. Sabiendo est o, es fácil adivinar que si quer em os acceder a un elem ent o, lo nor m al es que lo hagam os usando la clave indicada al añadir lo. Los que hayan t r abaj ado ant er ior m ent e con Visual Basic 6.0, ( o lo est én haciendo act ualm ent e) , puede que piensen que t am bién se podr á acceder a cada elem ent o m ediant e un índice num ér ico, ya que el obj et o Collect ion de VB6, ( que aún sigue exist iendo en Visual Basic 2010) , nos per m it e indicar una clave par a cada elem ent o, y adem ás de acceder a esos elem ent os m ediant e la clave, podem os hacer lo m ediant e un valor num ér ico ( índice) . Per o en las colecciones basadas en I Dict ionar y , salvo casos m uy especiales, siem pr e acceder em os a los valor es cont enidos m ediant e la clave y "nunca" m ediant e un índice que haga r efer encia a la posición dent r o de la colección, ent r e ot r as cosas por que cuando alm acenam os valor es en est e t ipo de colecciones, ést os no se guar dan en el m ism o or den en que fuer on añadidos. N ot a: Si bien la clase Collect ion est á disponible en la nueva ver sión de Visual Basic, ést a t iene algunas m ej or as con r espect o a la que t iene VB6, ent r e esas m ej or as est án dos nuevos m ét odos que nos facilit ar án su uso: el m ét odo Clear con el que podem os elim inar t odos los elem ent os de la colección y el m ét odo Cont ains, con el que podem os aver iguar si un det er m inado elem ent o est á en la colección. Ent r e las colecciones basadas en la int er faz I Dict ionar y podem os dest acar : Hasht able, es la colección por excelencia de las basadas en I Dict ionar y . Los elem ent os se or ganizan basándose en el código hash de las claves. Dict ionar yBase, es una clase abst r act a que podem os usar com o base de nuest r as pr opias colecciones de t ipo diccionar io. List Dict ionar y, es una colección con m ayor r endim ient o que Hasht able pensada par a t r abaj ar con 10 o m enos elem ent os. Hybr idDict ionar y , es una colección especial en la que si hay 10 o m enos elem ent os, se ut iliza una colección List Dict ionar y y si cont iene m ás elem ent os se ut iliza una colección Hasht able. Sor t edList , es una colección en la que los elem ent os est án clasificados por las claves. I nt er nam ent e ut iliza una m ezcla ent r e Hasht able y Ar r ay, según la for m a en que se accedan a esos elem ent os. Alm acenar valor es en una colección t ipo I D ict ionar y Par a añadir nuevos elem ent os a una colección de t ipo I Dict ionar y siem pr e t endr em os que indicar la clave y el valor , la clave no puede ser un valor nulo, ( Not hing) , per o puede ser de cualquier t ipo. El valor t am bién puede ser de cualquier t ipo y en est e caso si que se adm it en valor es nulos. Los elem ent os los añadir em os usando el m ét odo Add, al que habr á que indicar pr im er o la clave y después el valor : Dim valores() As String = {"uno", "dos", "tres"} Dim dic As New System.Collections.Hashtable For i As Integer = 0 To valores.Length - 1 dic.Add(valores(i), "El valor de " & valores(i)) Next Cóm o se alm acenan los elem ent os de las colecciones I D ict ionar y Tal com o hem os com ent ado, las colecciones que im plem ent an la int er faz I Dict ionar y siem pr e alm acenan un par de dat os: la clave y el valor pr opiam ent e dicho, por t ant o cada vez que quer am os acceder a un valor , debem os usar la clave asociada con dicho valor . Al m enos esa es la for m a habit ual, ya que com o ver em os, t am bién podr em os acceder a esos valor es dir ect am ent e. Debido a est a car act er íst ica, par a acceder a los elem ent os de est e t ipo de colecciones por m edio de un bucle del t ipo For Each, debem os usar una clase llam ada Dict ionar yEnt r y , est a clase t iene dos pr opiedades, una cont iene la clave y ot r a el valor . Por t ant o, cuando usem os un bucle For Each, el t ipo de obj et o usado par a acceder a los elem ent os de la colección ser á Dict ionar yEnt r y , t al com o vem os en el siguient e código: For Each de As DictionaryEntry In dic Console.WriteLine("{0} = {1}", de.Key, de.Value) Next Obt ener t odas las claves y valor es de una colección I D ict ionar y I ndependient em ent e de que podam os r ecor r er los valor es cont enidos en una colección de t ipo I Dict ionar y usando un obj et o de t ipo Dict ionar yEnt r y , habr á ocasiones en las que r ealm ent e nos int er esen t ener solo los valor es e incluso solo las claves, en est os casos, podem os usar dos pr opiedades que la int er faz I Dict ionar y define: Keys y Values. Est as pr opiedades devuelven un obj et o del t ipo I Collect ion con las claves y valor es r espect ivam ent e. Al ser obj et os I Collect ion, solo podr em os usar los par a r ecor r er los por m edio de un bucle For Each, ya que las colecciones I Collect ion no t ienen ningún m ét odo que nos per m it a acceder a los elem ent os que cont iene usando un índice. En el siguient e código m ost r am os t odas las claves de la colección cr eada en el ej em plo ant er ior : For Each clave As String In dic.Keys Console.WriteLine(clave) Next N ot a: Siem pr e que usem os un bucle For Each par a r ecor r er los elem ent os ( o dat os) de una colección, solo t endr em os acceso de solo lect ur a a esos dat os, es decir , no podr em os m odificar los usando la var iable por m edio de la que accedem os a ellos. Tal com o hem os vist o, en el espacio de nom br es Syst em .Collect ions t enem os dos clases abst r act as que podem os usar com o clases base par a cr ear nuest r as pr opias colecciones. Dependiendo que quer am os cr ear una colección basada en I List , por ej em plo par a acceder a los elem ent os m ediant e un índice num ér ico, o bien una colección basada en I Dict ionar y , par a alm acenar los elem ent os usando el par clave/ valor , t endr em os que usar la clase Collect ionBase o Dict ionar yBase. Est as clases ya t ienen cier t a funcionalidad que podr em os apr ovechar par a no t ener que r einvent ar la r ueda, ( ésa es la "gr acia" de la her encia) , y lo único que t endr em os que hacer es definir nuest r os pr opios m ét odos o pr opiedades par a que la colección act úe com o nosot r os decidam os y, lo m ás im por t ant e, par a que solo acept e los t ipos de dat os que r ealm ent e quer am os. Por ej em plo, si quer em os alm acenar dat os de t ipo Client e y quer em os acceder a esos dat os solo por un índice num ér ico, podr íam os basar nuest r a colección en Collect ionBase, per o si lo que necesit am os es una colección que cont enga, por ej em plo, obj et os de t ipo Ar t ículo, nos podr ía int er esar cr ear una colección basada en Dict ionar yBase par a que de est a for m a podam os acceder a cada uno de los elem ent os por m edio del código del ar t ículo. A cont inuación ver em os el código ( r educido) par a cr ear est os dos t ipos de colecciones per sonalizadas. N ot a: En las definiciones de las colecciones que vam os a m ost r ar , no hem os añadido ninguna funcionalidad ext r a, sino que hem os cr eado las clases/ colecciones par a que t engan un funcionam ient o par ecido al de las colecciones "nor m ales". La difer encia pr incipal con esas colecciones "nor m ales" es que est as dos clases/ colecciones que vam os a m ost r ar , solo adm it ir án elem ent os de un t ipo concr et o. Est o lo hem os hecho así par a que podam os com par ar y com pr obar la facilidad que ahor a t enem os si usam os colecciones del espacio de nom br es Syst em .Collect ion.Gener ic. Cr e a r una cole cción ba sa da e n Colle ct ionBa se A cont inuación vam os a ver un ej em plo de una colección per sonalizada basada en Collect ionBase y cóm o usar la. Est a colección alm acenar á elem ent os de un t ipo definido por nosot r os: Client e. Pr im er o veam os una clase Client e m uy sim ple, per o que im plem ent a la int er faz I Com par able, de for m a que se puedan clasificar sus elem ent os por el cam po Apellidos. Tam bién define el m ét odo ToSt r ing, ya que est a es una r ecom endación que siem pr e deber íam os seguir , ya que m uchas de las clases de punt o NET ut ilizan est e m ét odo par a m ost r ar el cont enido de los obj et os. ''' <summary> ''' Clase Cliente ''' </summary> ''' <remarks> ''' Esta clase se puede clasificar por el campo Apellidos ''' </remarks> Public Class Cliente Implements System.IComparable ' Public Nombre As String Public Apellidos As String ' Public Sub New(ByVal nombre As String, ByVal apellidos As String) Me.Nombre = nombre Me.Apellidos = apellidos End Sub ' Public Overrides Function ToString() As String Return Apellidos & ", " & Nombre End Function ' Public Function CompareTo(ByVal obj As Object) As Integer _ Implements System.IComparable.CompareTo If TypeOf obj Is Cliente Then Dim cli As Cliente = DirectCast(obj, Cliente) Return String.Compare(Me.Apellidos, cli.Apellidos) Else Return 0 End If End Function End Class En el siguient e código t enem os la definición de la clase/ colección Client es, que al est ar der ivada de Collect ionBase t endr á t odos los m iem br os definidos en esa clase abst r act a, ( que solo se puede usar par a cr ear clases der ivadas) ; y en la que hem os definido los m ét odos m ás habit uales, así com o una pr opiedad por defect o que nos per m it e acceder a los elem ent os m ediant e un índice num ér ico. Com o podem os com pr obar , en los m ét odos que hem os definido, r ealm ent e no t enem os que hacer dem asiadas cosas, ya que en el código que hem os escr it o en esos nuevos m iem br os nos apoyam os en las colecciones int er nas pr opor cionadas por la clase base: List , que es una colección basada en I List que cont iene los elem ent os, e I nner List que es una colección de t ipo Ar r ayList que t am bién hace r efer encia a la colección List . En la pr opiedad I t em , que es la pr opiedad pr edet er m inada o indizador , cuando devolvem os el valor indicado por el índice num ér ico, t enem os que hacer una conver sión par a que se devuelva un obj et o de t ipo Client e en lugar de uno de t ipo Obj ect que es com o r ealm ent e se alm acena en la colección. ''' <summary> ''' Colección de tipo Cliente basada en IList ''' </summary> ''' <remarks></remarks> Public Class Clientes Inherits System.Collections.CollectionBase Public Function Add(ByVal value As Cliente) As Integer Return List.Add(value) End Function Public Function Contains(ByVal value As Cliente) As Boolean Return List.Contains(value) End Function Public Function IndexOf(ByVal value As Cliente) As Integer Return List.IndexOf(value) End Function Public Sub Insert(ByVal index As Integer, ByVal value As Cliente) List.Insert(index, value) End Sub Default Public Property Item(ByVal index As Integer) As Cliente Get Return DirectCast(List(index), Cliente) End Get Set(ByVal value As Cliente) List(index) = value End Set End Property Public Sub Remove(ByVal value As Cliente) List.Remove(value) End Sub Public Sub Sort() InnerList.Sort() End Sub End Class Par a usar est a colección, lo har em os com o es cost um br e en las colecciones de t ipo I List : Sub Main() Dim col As New Clientes col.Add(New col.Add(New col.Add(New col.Add(New col.Add(New Cliente("Pepe", "López")) Cliente("Loli", "Pérez")) Cliente("Eva", "Kelo")) Cliente("Juan", "Salvador")) Cliente("Miguel", "Andrade")) col.Sort() For i As Integer = 0 To col.Count - 1 Console.WriteLine(col(i).Apellidos) Next col.RemoveAt(2) For Each cli As Cliente In col Console.WriteLine(cli.ToString) Next End Sub Cr e a r u n a cole cción ba sa da e n Dict ion a r yBa se En el siguient e código ver em os cóm o definir una colección per sonalizada basada en la clase abst r act a Dict ionar yBase. Est a colección alm acenar á obj et os del t ipo Ar t ículo. Esos obj et os se alm acenar án indicando com o clave el código del ar t ículo. Veam os el código y com ent ar em os las cosas dignas de r esalt ar . La clase Ar t iculo no t iene nada que r esalt ar , es una clase "nor m alit a". ''' <summary> ''' Clase artículo ''' </summary> ''' <remarks> ''' Clase para el ejemplo de colección derivada de DictionaryBase ''' </remarks> Public Class Articulo Public Codigo As String Public Descripcion As String Public PVP As Decimal Sub New( ByVal codigo As String, _ ByVal descripcion As String, _ ByVal precio As Decimal) Me.Codigo = codigo Me.Descripcion = descripcion Me.PVP = precio End Sub Public Overrides Function ToString() As String Return Codigo & ", " & Descripcion End Function End Class La clase/ colección la der ivam os de Dict ionar yBase par a que t enga t odas las "car act er íst icas" expuest as por esa clase abst r act a, a la que le añadim os nuevos m ét odos y pr opiedades par a dar le funcionalidad. Tal com o hicim os en la colección Client es, nos apoyam os en las colecciones int er nas de la clase base par a r ealizar el t r abaj o de esos nuevos m iem br os. ''' <summary> ''' Colección Clientes basada en IDictionary ''' </summary> ''' <remarks> ''' </remarks> Public Class Articulos Inherits System.Collections.DictionaryBase Default Public Property Item(ByVal key As String) As Articulo Get Return DirectCast(Dictionary(key), Articulo) End Get Set(ByVal value As Articulo) Dictionary(key) = value End Set End Property Public ReadOnly Property Keys() As ICollection Get Return Dictionary.Keys End Get End Property Public ReadOnly Property Values() As ICollection Get Return Dictionary.Values End Get End Property Public Sub Add(ByVal key As String, ByVal value As Articulo) Dictionary.Add(key, value) End Sub Public Function Contains(ByVal key As String) As Boolean Return Dictionary.Contains(key) End Function Public Sub Remove(ByVal key As String) Dictionary.Remove(key) End Sub End Class La for m a de usar est a colección es la m ism a que cualquier colección basada en I Dict ionar y. Dim col As New Articulos col.Add("uno", New Articulo("Uno", "Art. Uno", 10.6D)) col.Add("dos", New Articulo("Dos", "Art. Dos", 22)) col.Add("tres", New Articulo("Tres", "Art. Tres", 45.55D)) For Each de As DictionaryEntry In col Dim art As Articulo art = DirectCast(de.Value, Articulo) Console.WriteLine("{0}, {1}, {2}", de.Key, art.Descripcion, art.PVP) Next col.Remove("dos") For Each s As String In col.Keys Console.WriteLine("{0}, {1}", s, col(s).Descripcion) Next Cr e a r cole ccione s pe r sona liza da s usa ndo cole ccione s ge ne r ic Hast a est a ver sión de Visual Basic, si quer íam os cr ear colecciones "fuer t em ent e t ipadas", es decir , colecciones que solo adm it ier an dat os del t ipo que nosot r os quisiér am os, t eníam os que hacer lo con un código par ecido al que hem os vist o. Per o si nuest r a int ención es cr ear colecciones que "sim plem ent e" cont engan elem ent os de un t ipo det er m inado, por ej em plo obj et os de t ipo Client e o Ar t iculo, per o que no t engan ninguna funcionalidad ext r a a las que de for m a pr edet er m inada t ienen las clases base par a cr ear colecciones, no es necesar io que cr eem os nuest r os pr opias clases/ colección, ya que Visual Basic 2010 puede cr ear colecciones con esas car act er íst icas sin necesidad de cr ear un clase específica. Veam os pr im er o el código equivalent e usando colecciones del espacio de nom br es Gener ic con r espect o a los dos t ipos de colecciones ant er ior es, y después explicar em os un poco de que va t odo est o de los gener ics. La cole cción Clie n t e s e n ve r sión ge n e r ic La colección Client es es una colección que solo acept a elem ent os del t ipo Client e y a la que podem os acceder m ediant e un índice num ér ico, por t ant o debem os buscar una colección del espacio de nom br es Syst em .Collect ions.Gener ic que nos ofr ezca esa m ism a funcionalidad, y esa colección es: List . Debido a que las colecciones gener ic necesit an saber el t ipo de dat os que van a alm acenar , no necesit am os cr ear una clase/ colección par a alm acenar los elem ent os del t ipo Client e, sim plem ent e t endr em os que indicar en el const r uct or de esa colección que t ipo debe cont ener . En el siguient e código t enem os la for m a de declar ar la colección de t ipo List y cóm o acceder a los elem ent os que t ienen, com o podr á com pr obar es pr áct icam ent e el m ism o que el m ost r ado en el ej em plo de la colección basada en Collect ionBase. ' Colección generic equivalente a ArrayList Console.WriteLine("Ejemplo usando Generic.List") Dim colCli As New System.Collections.Generic.List(Of Cliente) colCli.Add(New Cliente("Pepe", "López")) colCli.Add(New colCli.Add(New colCli.Add(New colCli.Add(New Cliente("Loli", "Pérez")) Cliente("Eva", "Kelo")) Cliente("Juan", "Salvador")) Cliente("Miguel", "Andrade")) colCli.Sort() For i As Integer = 0 To colCli.Count - 1 Console.WriteLine(colCli(i).Apellidos) Next Console.WriteLine() ' Elimina el elemento de la posición 3 ' (pero después de haberlo clasificado) colCli.RemoveAt(2) For Each cli As Cliente In colCli Console.WriteLine(cli.ToString) Next El "quid" de la cuest ión est á en la for m a de declar ar la var iable colCli, en la que le indicam os que el t ipo de dat os que cont endr á la colección es "de" Client e: Dim colCli As New List(Of Cliente) Por lo dem ás, el código a usar par a acceder a los elem ent os, elim inar los, et c., es el m ism o que con cualquier ot r a colección basada en I List , per o con el "det alle" de que dicha colección "sepa" m anej ar elem ent os del t ipo Client e. Si no fuer a así, est a línea pr oducir ía un er r or , ya que est am os accediendo a un t ipo de dat os que define una pr opiedad llam ada Apellidos: Console.WriteLine(colCli(i).Apellidos) La cole cción Ar t icu los e n ve r sión ge n e r ic Com o vim os, la colección Ar t iculos solo acept a elem ent os del t ipo Ar t iculo, per o com o es una colección de t ipo I Dict ionar y cada vez que añadim os algún elem ent o o quer em os acceder a cualquier a de los cont enidos en ella, debem os indicar t am bién una clave. Por t ant o necesit am os una colección gener ic que t enga esas m ism as "car act er íst icas" y la que nos puede ser vir es la clase Syst em .Collect ions.Gener ic.Dict ionar y . A cont inuación t enem os el código par a m anej ar obj et os de t ipo Ar t iculo en una colección t ipo I Dict ionar y, per o com o ver em os, en est e caso hay que usar ot r a de las clases del espacio de nom br es Gener ic que nos sea út il par a hacer el bucle For Each, ya que par a usar la clase Gener ic.Dict ionar y debem os indicar t ant o el t ipo del valor a alm acenar com o el de la clave. Veam os el código y después ent r ar em os en m ás det alles: ' Colección generic equivalente a Hashtable (IDictionary) Console.WriteLine("Ejemplo usando Generic.Dictionary") Dim colArt As New System.Collections.Generic.Dictionary(Of String, Articulo) colArt.Add("uno", New Articulo("Uno", "Art. Uno", 10.6D)) colArt.Add("dos", New Articulo("Dos", "Art. Dos", 22)) colArt.Add("tres", New Articulo("Tres", "Art. Tres", 45.55D)) For Each de As KeyValuePair(Of String, Articulo) In colArt Dim art As Articulo = de.Value Console.WriteLine("{0}, {1}, {2}", de.Key, art.Descripcion, art.PVP) Next Console.WriteLine() colArt.Remove("dos") For Each s As String In colArt.Keys Console.WriteLine("{0}, {1}", s, colArt(s).Descripcion) Next Nuevam ent e "el t r uco" est á en la for m a de declar ar la var iable colAr t , en la que le decim os que la colección Dict ionar y usar á claves de t ipo St r ing y valor es del t ipo Ar t iculo: Dim colArt As New Dictionary(Of String, Articulo) Par a acceder a los elem ent os de est a colección por m edio de un bucle For Each, en lugar de usar una var iable de t ipo Dict ionar yEnt r y debem os usar una del t ipo gener ic KeyValuePair en la que debem os especificar los t ipos de dat os que cont iene la colección: For Each de As KeyValuePair(Of String, Articulo) In colArt Podem os com pr obar que los t ipos de dat os que est a colección cont iene son de t ipo St r ing par a las claves y de t ipo Ar t iculo par a los valor es. Dent r o del bucle hacem os una asignación a la var iable ar t , per o en est e caso, a difer encia de cuando usam os la colección "Ar t iculos" basada en Dict ionar yBase, no es necesar io hacer una conver sión explícit a del t ipo que t iene de.Value a un t ipo Ar t iculo, ya que de.Value es del t ipo Ar t iculo. Est o m ism o lo podem os com pr obar al acceder a un elem ent o dent r o del segundo bucle, esos son los t ipos de dat os que deben t ener , ya que de lo cont r ar io, no podr íam os acceder a la pr opiedad D escr ipcion del obj et o alm acenado: Console.WriteLine("{0}, {1}", s, colArt(s).Descripcion) En los ej em plos que acabam os de ver podem os apr eciar que las colecciones del espacio de nom br es Gener ic son bast ant es "pot ent es" o al m enos nos pueden facilit ar la t ar ea de cr ear colecciones fuer t em ent e t ipadas, ya que podr em os indicar que t ipo de dat os son los que quer em os que cont enga. En la siguient e im agen podem os ver cóm o al declar ar una colección Gener ic.Dict ionar y nos pide t ant o el t ipo de dat os de la clave com o del valor : Figur a 4 .1 . I nt elliSense en las colecciones gener ics La pr incipal vent aj a de est as colecciones es que debem os indicar siem pr e el t ipo de dat os que va a cont ener y en el caso de las colecciones Dict ionar y t am bién t enem os que indicar el t ipo de dat os par a las claves. Est os t ipos de dat os pueden ser cualquier a de los hay definidos en el pr opio .NET Fr am ewor k o los que hayam os definido nosot r os. Com o podem os com pr obar , siem pr e que vam os a declar ar una colección Gener ic vem os la "palabr a clave" Of, est a inst r ucción lo que hace es indicar cual ser á el t ipo de dat os que cont endr á la colección. Y ese ser á el único t ipo de dat os que la colección podr á cont ener . Re st r iccione s e n los t ipos ge ne r ic La vent aj a de est e t ipo de "r est r icción" del t ipo que puede cont ener una colección de t ipo Gener ic es que en lugar de indicar un t ipo concr et o, podem os indicar t am bién un t ipo algo m ás "genér ico", ( genér ico en el sent ido de no t an est r ict o) , por ej em plo, si t enem os un t ipo de dat os que im plem ent a una int er faz o que se der iva de una clase, podem os indicar ese t ipo después de Of y en ese caso solam ent e se adm it ir án obj et os que im plem ent e o se der ive de ese t ipo. N ot a: Par a facilit ar la lect ur a de los t ipos gener ics, se r ecom ienda leer las declar aciones genér icas usando "de" y el t ipo cuando nos encont r em os con un t ipo después de Of. Por ej em plo: List ( Of Client e) lo leer em os com o una colección List de Client e. Pr ecisam ent e esa es la r azón de que en Visual Basic 2010 se haya opt ado por el uso de la inst r ucción Of par a los t ipos gener ics. Por ej em plo, si t enem os una clase de t ipo Per sona y la ut ilizam os com o clase base de un t ipo Client e y ot r o de t ipo Em pleado, podr íam os cr ear una colección Gener ic.List que adm it a solo elem ent os del t ipo Per sona, con lo cual podem os añadir t ant o elem ent os de t ipo Client e y/ o de t ipo Em pleado, ya que est as dos clases se der ivan de la clase Per sona. En el siguient e código t enem os las definiciones de est as t r es clases y el código par a cr ear la colección gener ic: La clase Per sona: Public Class Persona Private _Nombre As String Public Property Nombre() As String Get Return _Nombre End Get Set(ByVal value As String) _Nombre = value End Set End Property Private _Apellidos As String Public Property Apellidos() As String Get Return _Apellidos End Get Set(ByVal value As String) _Apellidos = value End Set End Property End Class La clase Client e Public Class Cliente Inherits Persona Public Sub New(ByVal empresa As String) Me.Nombre = empresa End Sub Public Overrides Function ToString() As String Return Nombre End Function End Class La clase Em pleado Public Class Empleado Inherits Persona Public Sub New(ByVal nombre As String, ByVal apellidos As String) Me.Nombre = nombre Me.Apellidos = apellidos End Sub Public Overrides Function ToString() As String Return Apellidos & ", " & Nombre End Function End Class El código par a usar est as clases Dim col As New System.Collections.Generic.List(Of Persona) col.Add(New Cliente("Construcciones Pepe")) col.Add(New Empleado("Juan", "Pérez")) For Each p As Persona In col Console.WriteLine(p.Nombre) Next Las colecciones y clases gener ic son bast ant e "pot ent es" y en pr incipio fáciles de ut ilizar , con el valor añadido ( o vent aj a) es que nosot r os t am bién podem os cr ear nuest r os pr opios t ipos de dat os que ut ilicen est a nueva "t ecnología", per o su t r at am ient o en pr ofundidad sobr epasa el obj et ivo de est e cur so, aunque con lo aquí expuest o cr eem os que el lect or est á pr epar ado par a invest igar por su cuent a, con la ayuda de la docum ent ación de Visual St udio 2010 y de los m uchos r ecur sos que est án disponibles t ant o en for m at o "ar t ículo Web" y en libr os especializados en las novedades de Visual Basic 2010. Al em pezar a t r abaj ar con .NET, uno de los "gr andes" cam bios que not ar em os los que est am os habit uados a desar r ollar con ot r os lenguaj es es t odo lo r elacionado con el acceso al cont enido de los ficher os. En .NET, y por t ant o en Visual Basic 2010, el acceso a ficher os se r ealiza por m edio de los st r eam s ( o usando la t r aducción de la docum ent ación: las secuencias) . Con los st r eam s no solo podem os acceder a los ficher os de disco, sino que t am bién podem os acceder a ot r os t ipos de "secuencias" o fluj os de dat os, desde st r eam s de m em or ia a st r eam s par a enviar infor m ación a t r avés de I nt er net . Toda est a t r ansm isión o fluj o de infor m ación se r ealiza m ediant e una ser ie de m ét odos de lect ur a y escr it ur a que est án básicam ent e encapsulados en la clase abst r act a St r eam . Est a clase ser á la clase base de t odas aquellas que de alguna for m an t ienen que t r ansm it ir cier t a infor m ación ent r e la fuent e de dat os y nuest r a aplicación. En est e capít ulo t r at ar em os de las clases basadas en St r eam que con m ás fr ecuencia ut ilizar em os, sobr e t odo en lo r elacionado con el acceso a ficher os, que es al fin y al cabo la ut ilidad pr incipal de est e t ipo de "secuencias". St r e a m s e n .N ET St r e a m s e n .N ET La s cla se s ba sa da s e n St r e a m Manej ar un ficher o usando FileSt r eam Manej ar un ficher o usando St r eam Reader y St r eam Wr it er Asegur ar nos que el ficher o se cier r a Liber ar r ecur sos: Using... End Using Ej em plo de par a cifr ar y descifr ar un ficher o Según hem os com ent ado en la int r oducción, los st r eam s ( o secuencias o fluj os) nos per m it en abst r aer nos de la for m a en que est án im plem ent ados los pr ocesos de acceso a los ficher os u ot r os r ecur sos. Todas las clases que m anej an est e t ipo de fluj os de dat os est án basadas ( dir ect a o indir ect am ent e) en la clase St r eam , la cual nos ofr ece cier t os m ét odos que nos per m it en, ent r e ot r as cosas, leer y escr ibir en esos fluj os de infor m ación. Adem ás de poder leer o escr ibir , t am bién podem os r ealizar búsquedas o, dicho de ot r o m odo, podem os m over nos a t r avés de esa secuencia de dat os. Per o debido a que no t odos los fluj os de dat os nos per m it en r ealizar t odas las oper aciones de la clase St r eam , exist en cier t as pr opiedades por m edio de las cuales podem os saber si se per m it en t odas las oper aciones "básicas" que nor m alm ent e podr em os hacer con los st r eam s. Por ej em plo, es posible que no podam os leer o escr ibir en una secuencia o que no podam os cam biar la posición del "punt er o" de lect ur a o escr it ur a. Par a t odas est as com pr obaciones podr em os usar las pr opiedades CanRead, CanWr it e o CanSeek, per o cr eo que ant es de ent r ar en det alles, deber íam os ver algunos de las clases que .NET pone a nuest r a disposición par a poder r ealizar est e t ipo de oper aciones con "las secuencias" de dat os. Ent r e las clases que est án basadas en est a clase abst r act a t enem os las siguient es: Buffer edSt r eam , clase abst r act a que r epr esent a un buffer de alm acenam ient o par a oper aciones de lect ur a y escr it ur a de ot r o st r eam . Deflat eSt r eam , per m it e la com pr esión y descom pr esión de st r eam s usando el algor it m o Deflat . GZipSt r eam , usada par a com pr im ir y descom pr im ir st r eam s. FileSt r eam , nos per m it e una for m a básica de acceder y m anipular ficher os. Mem or ySt r eam , cr ear un st r eam que se alm acena en la m em or ia com o una secuencia de byt es. Net wor kSt r eam , pr opor ciona una secuencia de dat os par a el acceso a la r ed. Cr ypt oSt r eam , un st r eam usado par a encr ipt ar ot r os st r eam s. N ot a: Las clases Deflat eSt r eam y GZipSt eam est án incluidas en el espacio de nom br es Syst em .I O.Com pr ession. La clase Cr ypt oSt r eam est á incluida en el espacio de nom br es Syst em .Secur it y.Cr ypt ogr aphy. La clase Net wor kSt r eam est á incluida en el espacio de nom br es Syst em .Net .Socket s. Adem ás de est as clases que se der ivan dir ect am ent e de la clase St r eam , y que nor m alm ent e se usan com o "secuencias" a usar por ot r as clases de ent r ada/ salida, t enem os ot r as que nos per m it ir án acceder a esas secuencias de dat os de una for m a m ás dir ect a, ( algunas de est as las ver em os con algo de m ás det alle en el pr óxim o capít ulo dedicado al sist em a de ar chivos de .NET) , por ej em plo: Binar yReader / Binar yWr it er , lee o escr ibe t ipos pr im it ivos com o valor es binar ios ut ilizando una codificación específica. St r eam Reader / St r eam Wr it er , clases par a leer y escr ibir car act er es en ficher os ut ilizando una codificación det er m inada. St r ingReader / St r ingWr it er , im plem ent a Text Reader o Text Wr it er par a leer o escr ibir en una cadena. Text Reader / Text Wr it er , clases abst r act as par a leer o escr ibir en una secuencia de car act er es. Cuando t r abaj am os con los st r eam s debem os olvidar nos de las "cosas sim ples" y debem os t ener en cuent a que t r at ar em os casi siem pr e con secuencias de byt es, ya que al fin y al cabo esa es la for m a de alm acenar la infor m ación en los st r eam s. Por t ant o cuando veam os los ej em plos que la docum ent ación de Visual Basic 2010 nos pr opor ciona no debem os ext r añar nos de que haya que hacer t ant as "cosas" par a acceder o m anipular la infor m ación alm acenada en esas "secuencias" de dat os. Si bien, esa "com plicación" nos da m ayor cont r ol sor be el for m at o de la infor m ación cont enida en los st r eam s. Por suer t e, par a los que nos gust an las cosas "sim ples" las clases específicas nos facilit an m ucho las cosas. A cont inuación ver em os un par de ej em plos en los que m anipular em os cier t a infor m ación t ant o en la m em or ia usando un obj et o del t ipo Mem or ySt r eam , com o en un ficher o de disco usando FileSt r eam y las clases que casi con segur idad usar em os habit ualm ent e par a acceder al cont enido de los ficher os: St r eam Reader y St r eam Wr it er . M a ne j a r un fiche r o usa ndo File St r e a m En est e pr im er ej em plo ver em os lo com plicado que pude par ecer acceder a un ficher o usando la clase FileSt r eam y por ext ensión cualquier m ét odo de ot r as clases que devuelvan est e t ipo de secuencia, com o por ej em plo los m ét odos OpenRead, OpenWr it e, et c. de la clase File. La "com plej idad" de est a clase es que r ealm ent e obt iene o guar da la infor m ación por m edio de un ar r ay de t ipo Byt e, cuando a lo que est am os acost um br ados es a usar cadenas. N ot a: Realm ent e, est a for m a "binar ia" de acceder a la infor m ación de un ficher o no la t enem os que ver com o un inconvenient e, ya que nos puede ser vir par a acceder de for m a "binar ia" a ese ficher o, en caso de que nuest r a int ención sea acceder de for m a "nor m al" par a, por ej em plo, leer solo t ext o, deber íam os usar ot r as clases m ás especializadas par a esa t ar ea, com o lo es St r eam Reader . En el siguient e código t enem os dos m ét odos, uno que guar da una cadena en el ficher o indicado: Private Sub guardarDatos(ByVal fichero As String, ByVal cadena As String) ' Abrimos o creamos el fichero, para escribir en él Dim fs As New System.IO.FileStream(fichero, _ System.IO.FileMode.OpenOrCreate, _ System.IO.FileAccess.Write) ' Escribimos algunas cadenas, ' el problema es que solo podemos escribir arrays de bytes, ' por tanto debemos convertir la cadena en un array de bytes Dim datos() As Byte ' pero usando la codificación que creamos conveniente ' de forma predeterminada es UTF-8, ' aunque la codificación de Windows es ANSI (Encoding.Default) Dim enc As New System.Text.UTF8Encoding ' convertimos la cadena en un array de bytes datos = enc.GetBytes(cadena) ' lo escribimos en el stream fs.Write(datos, 0, datos.Length) ' nos aseguramos que se escriben todos los datos fs.Flush() ' cerramos el stream fs.Close() End Sub En el const r uct or de la clase FileSt r eam indicam os el ficher o en el que quer em os guar dar la infor m ación, t am bién le indicam os que quer em os cr ear lo o abr ir lo, es decir , si ya exist e lo abr e y si no exist e lo cr ea, de cualquier a de las for m as, en el siguient e par ám et r o del const r uct or le indicam os que nuest r a int ención es escr ibir en ese ficher o. Com o hem os com ent ado, la clase FileSt r eam ( y en gener al t odos los st r eam s) t r abaj a con byt es, por t ant o par a poder alm acenar algo en ese ficher o debem os hacer lo m ediant e un ar r ay de t ipo Byt e. En el caso de las cadenas, ést as siem pr e deben est ar codificadas, es decir , deben usar el j uego de car act er es que cr eam os convenient e, en el m undo de .NET ese j uego de car act er es es Unicode, m ás concr et am ent e usando la codificación UTF- 8, la cual per m it e t r abaj ar con cualquier car áct er de cualquier cult ur a. Com o lo que nos int er esa es conver t ir una cadena en un ar r ay de byt es, usam os el m ét odo Get Byt es de un obj et o UTF8Encoding, el cual convier t e la cadena en una "r ist r a" de byt es con el for m at o adecuado, en est e caso UTF- 8. Si en lugar de usar UTF- 8 quisiér am os usar ot r o "codificador ", por ej em plo el pr edet er m inado de Windows, con idea de que los ficher os sean com pat ibles con ot r as aplicaciones que ut ilizan el for m at o pr edet er m inado de Windows, t endr em os que declar ar la var iable enc de la siguient e for m a: Dim enc As System.Text.Encoding = System.Text.Encoding.Default A cont inuación, sim plem ent e le pasam os el ar r ay de byt es al m ét odo Wr it e del FileSt r eam indicando desde que posición de dicho ar r ay debe escr ibir y cuant os byt es. Por últ im o nos asegur am os de que t odos los byt es del "buffer " se guar den en el ficher o y lo cer r am os. Y ot r a función que devuelve el cont enido de un ficher o en for m at o cadena: Private Function leerDatos(ByVal fichero As String) As String ' Los bloques leídos los almacenaremos en un StringBuilder Dim res As New System.Text.StringBuilder ' Abrimos el fichero para leer de él Dim fs As New System.IO.FileStream(fichero, _ System.IO.FileMode.Open, _ System.IO.FileAccess.Read) ' los datos se leerán en bloques de 1024 bytes (1 KB) Dim datos(1024) As Byte Dim enc As New System.Text.UTF8Encoding() ' leemos mientras hay algo en el fichero While fs.Read(datos, 0, 1024) > 0 ' agregamos al stringBuilder los bytes leídos ' (convertidos en una cadena) res.Append(enc.GetString(datos)) End While ' cerramos el buffer fs.Close() ' devolvemos todo lo leído Return res.ToString End Function En est a función vam os a leer los dat os del ficher o indicado, com o ya hem os vist os, la clase FileSt r eam t r abaj a con byt es y esos byt es los conver t im os a car act er es por m edio de las clases de codificación especializadas. Por r egla gener al, esas lect ur as las h ar em os de for m a par cial, es decir leyen do bloques de byt es y com o t enem os que conver t ir esos byt es en car act er es, y puede ser que el ficher o sea m uy gr ande, en lugar de concat enar una cadena par a alm acenar las lect ur as par ciales, vam os a usar un obj et o del t ipo St r ingBuilder en el que ir em os "agr egando" cada t r ozo leído, de for m a que el r endim ient o no se vea penalizado por la for m a de ser de las cadenas, ya que cada vez que hacem os una concat enación en una var iable de t ipo St r ing, r ealm ent e est am os cr eando nuevos obj et os en la m em or ia y si son m uchos, pues la ver dad es que t endr em os al r ecolect or de basur a ( GC) t r abaj ando a t ope, y si usam os un obj et o St r ingBuilder el r endim ient o m ej or a una bar bar idad. La lect ur a de cada bloque de byt es lo hacem os en un bucle While, t am bién podr íam os haber lo hecho en un bucle Do While, per o en est os casos, el r endim ient o de While es un "poquit ín" m ayor . Los dat os leídos los agr egam os al obj et o St r ingBuilder por m edio del m ét odo Append que se encar ga de agr egar lo a la cadena int er na. Finalm ent e cer r am os el st r eam y devolvem os la cadena leída. Par a usar est as dos funciones lo podem os hacer de la siguient e for m a: ' un fichero de ejemplo (el directorio debe existir) Const fichero As String = "E:\Pruebas\prueba.txt" ' guardamos una cadena en el fichero guardarDatos(fichero, "Hola, Mundo de FileStream") ' ' Leemos el contenido del fichero y lo mostramos Console.WriteLine(leerDatos(fichero)) Est e código no necesit a m ayor explicación. M a ne j a r un fiche r o usa ndo St r e a m Re a de r y St r e a m W r it e r A cont inuación ver em os cóm o cr ear las dos funciones del ej em plo ant er ior par a que ut ilicen las clases "especializadas" par a leer y escr ibir cadenas en un ficher o. Com o podr em os com pr obar , est a es una for m a m uchísim o m ás sim ple y, por t ant o r ecom endada par a est e t ipo de acceso a los ficher os. Aunque debem os r ecor dar que solo ser vir á par a leer la infor m ación de for m a secuencial y en for m at o cadena. N ot a: El código par a usar est as dos funciones ser á el m ism o que el usado par a las funciones que ut ilizan la clase FileSt r eam . La función par a guar dar una cadena en un ficher o: Private Sub guardarDatos(ByVal fichero As String, ByVal cadena As String) ' Abrimos el fichero para escribir, (no añadir), ' usando la codificación predeterminada: UTF-8 Dim sw As New System.IO.StreamWriter(fichero, False) ' guardamos toda la cadena sw.WriteLine(cadena) ' Cerramos el fichero sw.Close() End Sub Com o podem os apr eciar , est a es una for m a m ucho m ás "com pact a" que la ant er ior , ya que solo t enem os que indicar en el const r uct or lo que quer em os hacer y usar el m ét odo Wr it e o Wr it eLine par a guar dar lo que quer am os en el ficher o. Par a guar dar lo usando la codificación pr edet er m inada del Sist em a Oper at ivo en el que se ut ilice la aplicación, ( en Windows ser á ANSI ) , sim plem ent e usam os est e const r uct or : Dim sw As New System.IO.StreamWriter(fichero, False, System.Text.Encoding.Default) Par a leer los dat os podem os hacer lo de dos for m as: línea a línea o t odo el cont enido de una sola vez. En el código siguient e se m uest r a línea a línea, y al final, ( com ent ado) , cóm o hacer lo en una sola pasada. Private Function leerDatos(ByVal fichero As String) As String ' Abrimos el fichero para leer ' usando la codificación UTF-8 (la predeterminada de .NET) Dim sr As New System.IO.StreamReader(fichero, True) ' si queremos usar la predeterminada de Windows 'Dim sr As New System.IO.StreamReader(fichero, System.Text.Encoding.Default) ' Podemos leer cada una de las líneas del fichero o todo el contenido ' Forma larga: ' si vamos a leer el fichero línea por línea, mejor usar un StringBuilder Dim ret As New System.Text.StringBuilder ' recorremos el fichero hasta que no haya nada que leer While sr.Peek <> -1 ret.Append(sr.ReadLine) End While ' cerramos el fichero sr.Close() ' devolvemos lo leído Return ret.ToString ' '' Forma corta: '' leemos todo el contenido del fichero 'Dim ret As String = sr.ReadToEnd() '' lo cerramos 'sr.Close() '' devolvemos lo leído 'Return ret End Function Si nos decidim os a leer el cont enido del ficher o línea a línea, podem os usar el m ét odo Peek, el cual devolver á el siguient e car áct er del buffer del st r eam , o - 1 si no hay nada que leer . Peek no "consum e" el car áct er , sim plem ent e com pr ueba si hay algo que leer . Si hay algo que leer , leem os la línea com plet a y la añadim os al obj et o St r ingBuilder , el bucle se r epet ir á m ient r as haya infor m ación pendient e de leer . Per o si opt am os por la vía r ápida, por que r ealm ent e no nos int er ese pr ocesar cada línea, podem os usar el m ét odo ReadToEnd, que en nuest r o ej em plo, el valor devuelt o ser á t odo el cont enido del ficher o, el cual asignam os a una var iable de t ipo St r ing par a usar la com o valor devuelt o por la función, después de cer r ar el ficher o. Ase gu r a r n os qu e e l fich e r o se cie r r a Si quer em os ahor r ar nos el paso int er m edio de asignar el valor en una var iable y después devolver lo, t am bién podem os hacer lo de est a for m a: Try Return sr.ReadToEnd() Finally sr.Close() End Try Ya que el bloque Finally siem pr e se ej ecut ar á, se pr oduzca o no un er r or , por t ant o nos asegur am os de que el ficher o se cier r a. Libe r a r r e cu r sos: Usin g... En d Usin g O si lo pr efer im os, podem os usar la nueva for m a de asegur ar nos de que los r ecur sos usados se liber an: ' Podemos usar Using para asegurarnos de que el recurso se libera Private Function leerDatos(ByVal fichero As String) As String Dim sr As New System.IO.StreamReader(fichero, True) Using sr Return sr.ReadToEnd() End Using End Function En est e código, cuando usam os Using sr , al ej ecut ar se End Using, el CLR se encar gar á de llam ar al m ét odo Dispose de la clase, de for m a que se liber en los r ecur sos que est em os usando, en est e ej em plo: el ficher o abier t o. Est os dos últ im os ej em plos ser ían equivalent es a los ant er ior es, m ás segur os, per o t am bién con m ás "t r abaj o" par a el CLR. N ot a: Using... End Using solo se puede usar con clases que im plem ent en la int er faz I Disposable, que es la que asegur a que el obj et o im plem ent a el m ét odo Dispose. Por t ant o, si im plem ent am os el m ét odo I Disposable.Dispose en nuest r as clases, en ese m ét odo nos t enem os que asegur ar que liber am os los r ecur sos que nuest r a clase est é ut ilizando. Ej e m plo de pa r a cifr a r y de scifr a r un fiche r o En el siguient e ej em plo ( adapt ado de uno de la docum ent ación) , ver em os cóm o usar algunas de las clases basadas en St r eam , par t icular m ent e las clase Mem or ySt r eam , FileSt r eam , Cr ypt oSt r eam adem ás de las clases St r eam Reader y St r eam Wr it er . Est e código t iene dos funciones: La pr im er a encr ipt a ( cifr a) una cadena y la guar da en un ficher o. La segunda desencr ipt a ( descifr a) el cont enido de un ficher o y lo guar da en ot r o. Am bas funciones devuelven la cadena cifr ada o descifr ada r espect ivam ent e. Imports Imports Imports Imports System System.IO System.Text System.Security.Cryptography Module Module1 Const fic1 As String = "E:\Pruebas\Prueba CryptoStream.txt" Const fic3 As String = "E:\Pruebas\Prueba CryptoStream des.txt" Const sKey As String = "El password a usar" ' Sub Main() Dim ret As String ' ret = cifrarFichero("Hola, Mundo encriptado", fic1) Console.WriteLine("Cadena encriptada : {0}", ret) ' ret = descifrarFichero(fic1, fic3) Console.WriteLine("Cadena desencriptada: {0}", ret) ' Console.ReadLine() End Sub Function cifrarFichero( _ ByVal texto As String, _ ByVal ficSalida As String) As String ' Creamos un MemorySream con el texto a cifrar Dim enc As New UTF8Encoding Dim datos() As Byte = enc.GetBytes(texto) Dim ms As New MemoryStream(datos) ' El fichero de salida Dim fs As New FileStream(ficSalida, FileMode.Create, FileAccess.Write) ' El proveedor criptográfico Dim r As New DESCryptoServiceProvider ' ' Establecer la clave secreta r.Key = Encoding.Default.GetBytes(sKey.Substring(0, 8)) r.IV = Encoding.Default.GetBytes(sKey.Substring(0, 8)) ' ' Crear una secuencia de cifrado Dim cs As New CryptoStream(fs, _ r.CreateEncryptor(), _ CryptoStreamMode.Write) ' ' Escribir el fichero cifrado cs.Write(datos, 0, datos.Length) cs.Close() ' ' devolver el texto cifrado Return Convert.ToBase64String(ms.ToArray()) End Function Function descifrarFichero( _ ByVal fichero As String, _ ByVal ficSalida As String) As String ' el proveedor del cifrado y las claves usadas para cifrar Dim r As New DESCryptoServiceProvider r.Key() = Encoding.Default.GetBytes(sKey.Substring(0, 8)) r.IV = Encoding.Default.GetBytes(sKey.Substring(0, 8)) ' ' crear la secuencia para leer el fichero cifrado Dim fs As New FileStream(fichero, FileMode.Open, FileAccess.Read) ' Dim cs As New CryptoStream(fs, _ r.CreateDecryptor(), _ CryptoStreamMode.Read) ' ' guardar el contenido de fichero descifrado Dim sw As New StreamWriter(ficSalida) Dim sr As New StreamReader(cs) sw.Write(sr.ReadToEnd) sw.Flush() sw.Close() ' ' devolver el texto sr = New StreamReader(fic3) Dim ret As String = sr.ReadToEnd() sr.Close() ' Return ret End Function End Module En la lección ant er ior vim os cóm o podem os acceder al cont enido de los ficher os, es decir , cóm o leer lo que hay dent r o de un ficher o, e incluso cóm o har em os par a escr ibir en ellos. En est a lección t r at ar em os del acceso al sist em a de ar chivos, es decir , ver em os las clases que .NET pone a nuest r a disposición par a que podam os m anej ar t ant o los ficher os ( ar chivos) com o los dir ect or ios. Los que hayan ut ilizado el obj et o File Syst em Obj ect s desde Visual Basic 6.0 segur am ent e encont r ar án m uchas sim ilit udes con lo que .NET ofr ece, per o, com o com pr obar em os, en .NET t enem os m ás var iedad de clases y, por supuest o, podem os hacer m uchas m ás cosas, y de for m a m ás fácil, que desde VB6. Acce so a l sist e m a de a r chiv os La s cla se s de l e spa cio de n om br e s Syst e m .I O Clases par a m anipular unidades, dir ect or ios y ficher os Las clases par a cr ear st r eam s Las clases par a leer o escr ibir en los st r eam s Cla se s pa r a m a n ipu la r u n ida de s, dir e ct or ios y fich e r os Las clases Dir ect or y y Dir ect or yI nfo Los m ét odos de las clases Dir ect or y y Dir ect or yI nfo Las clases File y FileI nfo Cifr ar y descifr ar un ficher o usando File o FileI nfo Abr ir ficher os par a agr egar o leer el cont enido Manipular cadenas r elacionadas con ficher os y dir ect or ios usando Pat h La s cla se s pa r a le e r o e scr ibir e n los st r e a m s Las clases St r eam Reader y St r eam Wr it er La codificación de los ficher os de .NET El obj e t o M y El obj et o My.Com put er .FileSyst em Buscar t ext o en ficher os con FindI nFiles Exam inar el cont enido de un ficher o con for m at o con OpenText FieldPar se Em pezar em os viendo las las clases elem ent ales o m ás usadas par a m anej ar el sist em a de ar chivos desde .NET. El espacio de nom br es Sy st em .I O es el que cont iene t odas las clases r elacionadas con los ficher os y dir ect or ios, en ese m ism o espacio de nom br es est án las que vim os en la lección ant er ior dedicada a los st r eam s de .NET, ya que al fin y al cabo, cuando t r at am os con los ficher os, est ar em os t r at ando con una secuencia de car act er es o byt es, secuencia a la que acceder em os con las clases especializadas que ya vim os. Aquí nos cent r ar em os pr incipalm ent e en la for m a de acceder a esos ficher os, a copiar los, a com pr obar si exist en, et c., en definit iva: a m anipular los. La s cla se s de l e spa cio de n om br e s Sy st e m .I O Ent r e las clases que nos podem os encont r ar en est e espacio de nom br es, t enem os clases que podem os agr upar dependiendo de las t ar eas que podem os hacer con ellas en: Las clases par a m anipular las unidades, dir ect or ios y ficher os Las clases par a cr ear st r eam s Las clases par a leer o escr ibir en los st r eam s Veam os pr im er o una r elación de esas clases y enum er aciones y después ver em os algunas de ellas con m ás det alle. Cla se s pa r a m a n ipu la r u n ida de s, dir e ct or ios y fich e r os Ent r e las clases que nos per m it en t r abaj ar con los ficher os, dir ect or ios y las unidades de disco, podem os dest acar las siguient es: Dir ect or y, pr opor ciona m ét odos est át icos par a cr ear , m over y enum er ar los ficher os de dir ect or ios y subdir ect or ios. Dir ect or yI nfo, al igual que la clase Dir ect or y, per o los m ét odos son de inst ancia, dicha inst ancia se cr ear á a par t ir de un dir ect or io det er m inado. Dr iveI nfo, pr opor ciona m ét odos de inst ancia par a cr ear , m over y enum er ar el cont enido de unidades. File, pr opor ciona m ét odos est át icos par a cr ear , copiar , elim inar , m over y abr ir ficher os, adem ás de ayudar a la cr eación de obj et os FileSt r eam . FileI nfo, igual que la clase File, per o los m ét odos son de inst ancia, dicha inst ancia se cr ear á a par t ir de un ficher o det er m inado. Pat h, pr opor ciona m ét odos y pr opiedades par a pr ocesar cadenas r elacionadas con los dir ect or ios. Tam bién t enem os las siguient es enum er aciones: FileAccess, define const ant es par a el t ipo de acceso a los ficher os: lect ur a, escr it ur a o lect ur a/ escr it ur a. FileAt t r ibut es, define const ant es par a el at r ibut o de los ficher os y dir ect or ios: ar chivo, ocult o, solo lect ur a, et c. FileMode, define las const ant es que podem os usar par a cont r olar com o abr im os un ficher o. FileShar e, define las const ant es par a cont r olar el t ipo de acceso que ot r os obj et os FileSt r eam pueden t ener al m ism o ficher o. La s cla se s pa r a cr e a r st r e a m s La siguient e r elación son clases que nos per m it en la cr eación de st r eam s, las cuales ya vim os en la lección ant er ior , por t ant o solo las m encionar em os. Buffer edSt r eam , clase abst r act a que r epr esent a un buffer de alm acenam ient o par a oper aciones de lect ur a y escr it ur a de ot r o st r eam . Deflat eSt r eam , per m it e la com pr esión y descom pr esión de st r eam s usando el algor it m o Deflat . GZipSt r eam , usada par a com pr im ir y descom pr im ir st r eam s. FileSt r eam , nos per m it e una for m a básica de acceder y m anipular ficher os. Mem or ySt r eam , cr ear un st r eam que se alm acena en la m em or ia com o una secuencia de byt es. Net wor kSt r eam , pr opor ciona una secuencia de dat os par a el acceso a la r ed. Cr ypt oSt r eam , un st r eam usado par a encr ipt ar ot r os st r eam s. La s cla se s pa r a le e r o e scr ibir e n los st r e a m s Binar yReader , lee t ipos pr im it ivos o cadenas codificadas desde un FileSt r eam . Binar yWr it er , escr ibe t ipos pr im it ivos o cadenas codificadas en un FileSt r eam . St r eam Reader , lee car act er es desde un FileSt r eam , usando codificación par a conver t ir los car act er es a/ desde byt es. St r eam Wr it er , escr ibe car act er es a un FileSt r eam , usando codificación par a conver t ir los car act er es en byt es. St r ingReader , lee car act er es desde un St r ing. La salida puede ser a un st r eam en cualquier codificación o a una cadena. St r ingWr it er , escr ibe car act er es a un St r ing. Al igual que St r ingReader , la salida puede ser a un st r eam usando cualquier codificación o a una cadena. Text Reader , es la clase abst r act a base par a St r eam Reader y St r ingReader . Text Wr it er , es la case abst r act a base par a St r eam Wr it er y St r ingWr it er . N ot a: La clase abst r act a St r eam est á diseñada par a ent r ada y salida de byt es, las clases abst r act as Text Reader y Text Wr it er est án diseñadas par a la ent r ada/ salida de car act er es Unicode. Ent r e las clases que nos per m it en t r abaj ar con los ficher os, dir ect or ios y las unidades de disco, podem os dest acar las siguient es: Dir ect or y, pr opor ciona m ét odos est át icos par a cr ear , m over y enum er ar los ficher os de dir ect or ios y subdir ect or ios. Dir ect or yI nfo, al igual que la clase Dir ect or y, per o los m ét odos son de inst ancia, dicha inst ancia se cr ear á a par t ir de un dir ect or io det er m inado. Dr iv eI nfo, pr opor ciona m ét odos de inst ancia par a cr ear , m over y enum er ar el cont enido de unidades. File, pr opor ciona m ét odos est át icos par a cr ear , copiar , elim in ar , m over y abr ir ficher os, adem ás de ay udar a la cr eación de obj et os FileSt r eam . FileI nfo, igual que la clase File, per o los m ét odos son de inst ancia, dicha inst ancia se cr ear á a par t ir de un ficher o det er m inado. Pat h, pr opor ciona m ét odos y pr opiedades par a pr ocesar cadenas r elacionadas con los dir ect or ios. Tam bién t enem os las siguient es enum er aciones: FileAccess, define const ant es par a el t ipo de acceso a los ficher os: lect ur a, escr it ur a o lect ur a/ escr it ur a. FileAt t r ibut es, define const ant es par a el at r ibut o de los ficher os y dir ect or ios: ar chivo, ocult o, solo lect ur a, et c. FileMode, define las const ant es que podem os usar par a cont r olar com o abr im os un ficher o. FileShar e, define las const ant es par a cont r olar el t ipo de acceso que ot r os obj et os FileSt r eam pueden t ener al m ism o ficher o. La s cla se s D ir e ct or y y D ir e ct or y I nfo Cuando necesit em os acceder a un dir ect or io, por ej em plo, par a saber que subdir ect or ios y ficher os cont iene o par a obt en er ot r o t ipo de in for m ación , incluso par a saber si exist e o n o, en esos casos podem os ut ilizar las clases Dir ect or y o Dir ect or y I nfo. La pr im er a de ellas: Dir ect or y, pr opor ciona m ét odos est át icos, es decir , los m ét odos que cont ienen siem pr e est ar án disponibles sin necesidad de cr ear una nueva inst ancia de la clase. Por t ant o, podr em os usar esos m ét odos sim plem ent e usando la pr opia clase. La segunda: Dir ect or yI nfo, pr opor ciona los m ism os m ét odos que Dir ect or y, per o en lugar de ser m ét odos est át icos, son m ét odos de inst ancia, es decir , esos m ét odos solam ent e se podr án usar después de haber cr eado una inst ancia ( u obj et o en m em or ia) de est a clase. Cada una de las inst ancias de Dir ect or y I nfo, har á r efer en cia a un dir ect or io en par t icular , ese dir ect or io se indicar á al cr ear el obj et o, aun que t am bién puede ser que est é r efer en ciado al obt ener lo m ediant e ot r os m ét odos que dev uelven est e t ipo de obj et os. N ot a: El dir ect or io asignado al cr ear la inst ancia de Dir ect or yI nfo no t iene por qué ex ist ir . De esa for m a podem os com pr obar si exist e, y en caso de que no exist a, cr ear lo, et c. Por ej em plo, si quer em os saber si un dir ect or io exist e, ut ilizar em os el m ét odo Exist s, en el caso de la clase Dir ect or y, com o par ám et r o le indicar em os el dir ect or io del que quer em os com pr obar su exist encia, sin em bar go, si usam os un obj et o del t ipo Dir ect or yI nfo, no necesit am os indicar ningún par ám et r o, ya que el dir ect or io que est á asociado con esa clase lo habr em os indicado al cr ear el obj et o. En el siguient e código vem os cóm o usar est as dos clases: Const dir1 As String = "E:\Pruebas" Const dir2 As String = "E:\Pruebas2" Sub Main() claseDirectory() Console.WriteLine() claseDirectoryInfo() Console.WriteLine() ' Console.ReadLine() End Sub Sub claseDirectory() ' Los métodos de la clase Directory son estáticos, ' por tanto no necesitamos crear una instancia de esta clase ' ' Comprobar si existe un directorio: If System.IO.Directory.Exists(dir1) Then Console.WriteLine("El directorio '{0}' SI existe", dir1) Else Console.WriteLine("El directorio '{0}' NO existe", dir1) End If End Sub Sub claseDirectoryInfo() ' Los métodos de la clase DirectoryInfo son de instancia, ' por tanto tenemos que crear una instancia de la clase ' para poder usarla ' Dim di As New System.IO.DirectoryInfo(dir2) ' ' Comprobar si existe un directorio: If di.Exists Then Console.WriteLine("El directorio '{0}' SI existe", dir2) Else Console.WriteLine("El directorio '{0}' NO existe", dir2) End If End Sub El r est o de m ét odos de est as dos clases funcionan de for m a sim ilar , al m enos en el sent ido de que si usam os la clase Dir ect or y , siem pr e habr á un par ám et r o que haga r efer encia al dir ect or io que quer em os usar , m ient r as que con Dir ect or yI nfo siem pr e est ar á haciendo r efer encia al dir ect or io usado al cr ear la inst ancia. N ot a: No quer em os par ecer r epet it ivos, per o nos int er esa que quede cla r o com o funcionan est e t ipo de clases, que por ot r o lado, ser á sim ilar al de las clases File y FileI nfo, al m enos en el sent ido de que la clase con los m ét odos est át icos siem pr e necesit ar á saber a que elem ent o del sist em a de ar chiv os est am os r efir iéndonos, m ient r as que las clases que debem os inst anciar , siem pr e sabr án con que elem ent o t r abaj ar án. Los m é t odos de la s cla se s Dir e ct or y y Dir e ct or yI n fo Est as clases siem pr e m anej ar án dir ect or ios y ent r e los m ét odos que podem os ut ilizar , dest acam os los siguient es, em pezam os por la clase Dir ect or y : Cr eat eDir ect or y , cr ear los dir ect or ios indicados en el par ám et r o. Si algunos de los dir ect or ios int er m edios no exist en, los cr ear á. Exist s, com pr ueba si el dir ect or io indicado ex ist e. Get Cr eat ionTim e, devuelve la fecha y hor a de cr eación del dir ect or io indicado. Get Cr eat ionTim eUt c, devuelve la fecha y hor a univer sal ( UTC/ GMT) de cr eación del dir ect or io. Get Cur r ent Dir ect or y, dev uelve el dir ect or io de t r abaj o de la aplicación. Get Dir ect or ies, dev uelve un ar r ay de St r ing con t odos los subdir ect or ios del dir ect or io indicado. Se puede indicar un "pat t er n" de búsqueda y si quer em os incluir los subdir ect or ios que t enga el dir ect or io indicado. Get Dir ect or yRoot , devuelv e el dir ect or io r aíz del dir ect or io indicado. Get Files, dev uelve un ar r ay de t ipo St r ing con los ficher os del dir ect or io indicado. Se puede indicar un filt r o de búsqueda. Get Last AccessTim e, devuelv e la fecha y hor a del últ im o acceso al dir ect or io. Get Last AccessTim eUt c, ídem que el ant er ior , per o la fecha y hor a en for m at o UTC. Get Last Wr it eTim e, dev uelve la fecha y hor a de la últ im a escr it ur a r ealizada en el dir ect or io. Get Last Wr it eTim eUt c, com o el ant er ior , per o usando fechas UTC. Get LogicalDr ives, devuelve un ar r ay con los nom br es de las unidades lógicas en el for m at o: "< let r a> : \ ". Get Par ent , devuelv e el dir ect or io de nivel super ior del indicado. Mov e, m ueve un ficher o o dir ect or io y su cont enido a una nueva localización. Set Cr eat ionTim e, asigna la fecha y hor a de cr eación de un ficher o o dir ect or io. Set Cr eat ionTim eUt c, com o el ant er ior , per o la fecha/ h or a es UTC. Set Cur r ent Dir ect or y , indica el dir ect or io de t r abaj o de la aplicación. Set Last AccessTim e, asigna la fecha y hor a del últ im o acceso. Set Last AccessTim eUt c, com o el ant er ior , per o la fecha/ hor a en for m at o UTC. Set Last Wr it eTim e, asigna la fecha y hor a de la últ im a escr it ur a. Set Last Wr it eTim eUt c, com o el ant er ior , per o usando la fecha y hor a UTC. Com o hem os com ent ado, la clase Dir ect or y I nfo siem pr e har á r efer en cia al dir ect or io ut ilizado par a inst anciar la, por t ant o algunos de los m ét odos de la clase Dir ect or y se conv ier t en en pr opiedades de est a clase y ot r os cam bian de nom br e par a adecuar los m ej or a la acción a r ealizar con ellos. Por ej em plo, en la clase Dir ect or y t enem os el m ét odo Exist s, que en Dir ect or y I nfo es una pr opiedad. De igual for m a, el m ét odo Mov e de la clase Dir ect or y es el m ét odo Mov eTo de Dir ect or yI nfo. En cuant o a los m ét odos de Dir ect or y par a obt ener o asignar la fecha de cr eación, acceso, et c., en Dir ect or yI nfo son pr opiedades de lect ur a/ escr it ur a. Dicho est o, no v am os a r elacionar t odos est os m iem br os de Dir ect or yI nfo, ya que en la docum ent ación est án bien det allados y no nos r esult ar á difícil de saber cóm o usar los. Lo que si quer em os r esalt ar es que algunos de los m ét odos de la clase Dir ect or yI nfo, concr et am ent e Get Dir ect or ies y Get Files, no dev uelven un ar r ay de t ipo St r ing, sino un ar r ay de obj et os Dir ect or yI nfo o FileI nfo r espect ivam ent e. Tam bién debem os indicar que la clase Dir ect or yI nfo t iene cier t as pr opiedades, com o FullNam e o Nam e, que nos dan infor m ación del nom br e de la r ut a com plet a o del nom br e del dir ect or io. Y com o not a final sobr e Dir ect or y y Dir ect or yI nfo, aclar ar que el "filt r o" ( o pat t er n) que podem os usar par a filt r ar los dir ect or ios o ficher os obt enidos con Get Dir ect or ies o Get Files solo pueden t ener un filt r o o especificación, quer em os aclar ar est e punt o, ya que en Visual Basic 6.0, si indicábam os un filt r o en los cont r oles File o Dir ect or y, podíam os indicar var ios filt r os separ ados por punt o y com a ( ; ) , en las clases de .NET est o no se puede hacer . Par a dej ar clar o est os punt os, ver em os un ej em plo de cóm o usar Get Dir ect or ies y Get Files, con est as dos clases. Imports System Imports System.IO Module Module Const dir1 As String = "E:\Pruebas" Sub Main() Console.WriteLine("Ejemplo de la clase Directory:") claseDirectory() Console.WriteLine() Console.WriteLine("Ejemplo de la clase DirectoryInfo:") claseDirectoryInfo() Console.WriteLine() ' Console.ReadLine() End Sub Sub claseDirectory() ' Recorrer los subdirectorios de un directorio Dim dirs() As String dirs = Directory.GetDirectories(dir1) mostrarFicheros(dir1, "*.txt") ' recorrer los ficheros de cada uno de estos directorios For Each dir As String In dirs mostrarFicheros(dir, "*.txt") Next End Sub Sub mostrarFicheros(ByVal dir As String, ByVal filtro As String) Console.WriteLine("Los ficheros {0} del directorio: {1}", _ filtro, dir) Dim fics() As String fics = Directory.GetFiles(dir, filtro) For Each fic As String In fics Console.WriteLine(" Fichero: {0}", fic) Next End Sub Sub claseDirectoryInfo() Dim di As New DirectoryInfo(dir1) Dim dirs() As DirectoryInfo dirs = di.GetDirectories mostrarFicheros(di, "*.*") For Each dir As DirectoryInfo In dirs mostrarFicheros(dir, "*.*") Next End Sub Sub mostrarFicheros(ByVal dir As DirectoryInfo, ByVal filtro As String) Console.WriteLine("Los ficheros {0} del directorio: {1}", _ filtro, dir.FullName) Dim fics() As FileInfo fics = dir.GetFiles(filtro) For Each fic As FileInfo In fics Console.WriteLine(" Fichero: {0}", fic.Name) Next End Sub End Module La s cla se s File y File I nfo Al igual que ocur r e con las clases par a m anej ar los dir ect or ios, t enem os dos clases difer ent es par a m anej ar los ficher os, una de ellas ( File) t odos los m ét odos que t iene son est át icos, por t ant o podem os usar los dir ect am ent e, sin cr ear una nueva inst ancia de la clase. Por ot r o lado la clase FileI nfo es una clase de la que t enem os que cr ear un nuevo obj et o par a poder usar la, al cr ear ese obj et o ( o inst ancia) , t enem os que indicar el ficher o al que har á r efer encia, ese ficher o no t iene por qué exist ir pr eviam ent e. En el siguient e código podem os ver cóm o usar est as dos clases. Imports System Imports System.IO Module Module1 Const fic1 As String = "E:\Pruebas\Prueba.txt" Const fic2 As String = "E:\Pruebas\SubDir\Prueba3.txt" Sub Main() Console.WriteLine("Ejemplo de la clase File:") claseFile() Console.WriteLine() Console.WriteLine("Ejemplo de la clase FileInfo:") claseFileInfo() Console.WriteLine() ' Console.ReadLine() End Sub Sub claseFile() ' comprobar si el fichero existe If File.Exists(fic1) Then Console.WriteLine("El fichero '{0}' SI existe", fic1) Console.WriteLine("Fecha creación: {0}", File.GetCreationTime(fic1)) Else Console.WriteLine("El fichero '{0}' NO existe", fic1) End If End Sub Sub claseFileInfo() Dim fi As New FileInfo(fic2) ' ' Comprobar si existe el fichero: If fi.Exists Then Console.WriteLine("El fichero '{0}' SI existe", fic2) Console.WriteLine("Fecha creación: {0}", fi.CreationTime) agregarTexto(fi) Else Console.WriteLine("El fichero '{0}' NO existe", fic2) ' lo creamos fi.Create() End If End Sub Sub agregarTexto(ByVal fi As FileInfo) Dim fs As StreamWriter fs = fi.CreateText fs.WriteLine("Hola, Mundo") fs.Flush() fs.Close() ' fi.Refresh() Console.WriteLine("Tamaño : {0}", fi.Length) End Sub End Module Cifr a r y de scifr a r u n fich e r o u sa n do File o File I n fo En los sist em as oper at iv os Windows XP y Windows 2003, al m ost r ar el cuadr o de diálogo de las pr opiedades av anzadas de un ficher o, nos per m it e cifr ar lo, de for m a que el usuar io act ual sólo t enga acceso al cont enido del m ism o. Figur a 4 .2 . W indow s XP/ 2 0 0 3 nos per m it e cifr ar un ficher o Tant o la clase File com o FileI nfo t ienen m ét odos par a r ealizar est a oper ación, así com o la inver sa: descifr ar lo. Cuando cifr am os un ficher o, solo el usuar io act ual podr á acceder a su cont enido ( y el r est o de adm inist r ador es) , la for m a de hacer lo es bien sim ple: solo t enem os que llam ar al m ét odo Encr y pt o Decr ypt par a cifr ar lo o descifr ar lo. Cuando est á cifr ado, el nom br e del ficher o se m ost r ar á en un color difer ent e al del r est o de ficher os ( de for m a pr edet er m inada en ver de) . Est a for m a de cifr ado es difer ent e a la que vim os en la lección ant er ior , ya que si cifr am os el cont enido de un ficher o de for m a "m anual", siem pr e est ar á cifr ado, independient em ent e de quién acceda al ficher o. Cuando ut ilizam os los m ét odos par a cifr ar o descifr ar un ficher o, no r ecibir em os ninguna excepción si aplicam os el m ét odo de cifr ar sobr e un ficher o y a cifr ado. Per o si quer em os saber si un det er m inado ficher o est á o no cifr ado, lo podem os aver iguar m ediant e la pr opiedad At t r ibut e de la clase FileI nfo, par t icular m ent e com pr obando si t iene act ivado el at r ibut o FileAt t r ibut es.Encr y pt ed. En el siguient e código t enem os ej em plos de cóm o usar las clases File y FileI nfo par a com pr obar si un ficher o y a est á cifr ado, en cuy o caso lo descifr am os, y si r esult a que no est á cifr ado, lo cifr am os. Imports System Imports System.IO Module Module1 Const fic1 As String = "E:\Pruebas\Prueba.txt" Sub Main() cifradoFile(fic1) Console.WriteLine() cifradoFileInfo(fic2) Console.WriteLine() ' Console.ReadLine() End Sub ' Cifrar / Descifrar ficheros ' y comprobar si ya están cifrados... Sub cifradoFile(ByVal fichero As String) ' comprobar si está cifrado, Dim atrib As FileAttributes atrib = File.GetAttributes(fichero) If (atrib And FileAttributes.Encrypted) = FileAttributes.Encrypted Then Console.WriteLine("El fichero {0} ya estaba cifrado.", fichero) File.Decrypt(fichero) Else File.Encrypt(fichero) Console.WriteLine("El fichero {0} no estaba cifrado.", fichero) End If End Sub Sub cifradoFileInfo(ByVal fichero As String) ' comprobar si está cifrado, Dim fi As New FileInfo(fichero) Dim atrib As FileAttributes atrib = fi.Attributes If (atrib And FileAttributes.Encrypted) = FileAttributes.Encrypted Then Console.WriteLine("El fichero {0} ya estaba cifrado.", fi.FullName) fi.Decrypt() Else fi.Encrypt() Console.WriteLine("El fichero {0} no estaba cifrado.", fi.FullName) End If End Sub End Module Abr ir fich e r os pa r a a gr e ga r o le e r e l con t e n ido Est as dos clases de m anipulación de ficher os exponen una ser ie de m ét odos que nos per m it en abr ir el ficher o al que hace r efer encia la clase par a leer el cont enido del m ism o o par a escr ibir en él. Dependiendo del m ét odo usado, ést e dev olver á un obj et o de t ipo FileSt r eam o St r eam Reader o St r eam Wr it er . Est o nos per m it e de una for m a fácil poder acceder al cont enido que t iene sin necesidad de usar ot r os const r uct or es. Lo que si debem os t ener en cuent a es que en el caso de que leam os o escr ibam os t ext o, ést e se guar dar á usando la codificación UTF- 8, por t ant o si quer em os usar ot r o t ipo de codificación, t endr em os que abr ir los usando los const r uct or es cor r espondient es, nor m alm ent e los de las clases St r eam Reader y St r eam Wr it er . De est as dos clases nos ocupar em os en el siguient e capít ulo. Veam os un par de ej em plos que nos per m it an leer el cont enido o agr egar nuevo t ext o a los ficher os. Imports System Imports System.IO Module Module1 Const fic3 As String = "E:\Pruebas\Prueba4.txt" Const fic4 As String = "E:\Pruebas\SubDir\Prueba4.txt" Sub Main() abrirFile(fic3) Console.WriteLine() abrirFileInfo(fic4) Console.WriteLine() ' Console.ReadLine() End Sub ' Abrir ficheros para leer el contenido o escribir en él Sub abrirFile(ByVal fichero As String) If File.Exists(fichero) Then Dim fs As FileStream = File.OpenRead(fichero) Dim enc As New System.Text.UTF8Encoding() Dim datos(1024) As Byte fs.Read(datos, 0, datos.Length) fs.Close() Dim s As String = enc.GetString(datos, 0, datos.Length) Console.WriteLine("El contenido de: {0}{2} es:{2}{1}", _ fichero, s, vbCrLf) Else Console.WriteLine("Guardando algo en el fichero {0}", fichero) Dim fs As FileStream = File.OpenWrite(fichero) Dim enc As New System.Text.UTF8Encoding() Dim datos() As Byte = enc.GetBytes("¡Hola bytes!") fs.Write(datos, 0, datos.Length) fs.Close() End If End Sub Sub abrirFileInfo(ByVal fichero As String) Dim fi As New FileInfo(fichero) If fi.Exists Then ' abrir el fichero como texto y leemos el contenido Dim sr As StreamReader = fi.OpenText Dim s As String = sr.ReadToEnd Console.WriteLine("El contenido de: {0}{2} es:{2}{1}", _ fichero, s, vbCrLf) Else Console.WriteLine("Guardando algo en el fichero {0}", fichero) Dim sw As New StreamWriter(fi.OpenWrite) sw.WriteLine("Hello bytes!") sw.Close() End If End Sub End Module En el m ét odo abr ir File ut ilizam os la clase File par a abr ir , leer y escr ibir en un ficher o. En est e caso est am os usando un obj et o del t ipo FileSt r eam par a acceder al cont enido de dicho ficher o, com o sabem os, est a clase solo t r abaj a con byt es, por t ant o si quer em os leer el cont enido del m ism o, debem os h acer lo m ediant e u n ar r ay de by t es y par a m ost r ar en for m at o t ex t o ese cont enido, t enem os que aplicar le la codificación cor r espondient e par a ext r aer el cont enido en for m a de una cadena. Lo m ism o hacem os par a guar dar una cadena en el ficher o, ( en caso de que no ex ist a pr ev iam ent e) . En el m ét odo abr ir FileI nfo, en lugar de cr ear u n obj et o FileSt r eam par a acceder al cont enido, usam os uno del t ipo St r eam Reader , ya que est a clase si que nos dev olver á una cadena sin necesidad de hacer conver siones ex t r as. Lo m ism o ocur r e a la hor a de escr ibir algo en el ficher o, aunque en est a ocasión ut ilizam os un obj et o del t ipo St r eam Wr it er . En el pr im er caso, cuando leem os el cont enido, ut ilizam os el m ét odo OpenText , el cual dev uelve un obj et o del t ipo St r eam Reader . Por ot r a par t e, cuando quer em os guar dar t ext o, lo que hacem os es pasar le al const r uct or de la clase St r eam Wr it er el obj et o FileSt r eam devuelt o por el m ét odo OpenWr it e. N ot a: Com o hem os podido com pr obar , cuando t r at am os con las clases Dir ect or yI nfo o FileI nfo, siem pr e est am os t r at ando con inst ancias que pueden ser difer ent es y por t ant o m últ iples, esas inst ancias siem pr e m anej an el dir ect or io o ficher o usado en el const r uct or , por t ant o, ser á pr efer ible usar est as clases cuando t engam os que hacer v ar ias oper aciones sobr e el m ism o dir ect or io o ficher o. Por ot r o lado, si solo quer em os hacer pocas oper aciones, podem os usar las clases Dir ect or y o File, ya que no necesit ar em os cr ear un obj et o en m em or ia par a hacer las t ar eas que necesit em os hacer . M a n ipu la r ca de n a s r e la cion a da s con fich e r os y dir e ct or ios u sa n do Pa t h La clase Pat h es una clase especial, en la que t odos los m ét odos son est át icos, por t ant o par a usar la no necesit am os cr ear una inst ancia. Lo de "especial" es por que est a clase r ealm ent e no r ealiza ninguna acción "física" sobr e los dir ect or ios ( o ficher os) , sim plem ent e nos per m it e m anipular los nom br es de esos dir ect or ios o ficher os. Por ej em plo, podem os usar est a clase par a obt ener infor m ación sobr e un ficher o, com o el nom br e com plet o, el nom br e del dir ect or io o la ex t ensión. En el siguient e código vem os cóm o usar algunos de esos m ét odos: Const fic1 As String = "E:\Pruebas\Prueba.txt" Sub clasePath() Console.WriteLine("Nombre completo: {0}", fic1) Console.WriteLine("El nombre: {0}", Path.GetFileName(fic1)) Console.WriteLine("Sin extensión: {0}", Path.GetFileNameWithoutExtension(fic1)) Console.WriteLine("La extensión: {0}", Path.GetExtension(fic1)) Console.WriteLine("El directorio: {0}", Path.GetDirectoryName(fic1)) End Sub N ot a: Debido a que la clase Pat h solo m anej a cadenas, podem os usar los m ét odos de est a clase con nom br es de ficher os o dir ect or ios que no exist en, y por t ant o, cualquier cam bio que hagam os en esos par ám et r os, no afect ar án a ningún ficher o ni dir ect or io. Debido a que los ensam blados de .NET podem os usar los con difer ent es sist em as oper at ivos ( al m enos en t eor ía) , est a clase pr opor ciona cier t as pr opiedades que nos per m it en aver iguar los car act er es especiales de cada sist em a, por ej em plo par a saber el separ ador usado por los dir ect or ios. Con est a clase t am bién podem os cr ear ficher os con nom br es t em por ales, de for m a que nos asegur em os de que no habr á ot r o ficher o "t em por al" con el m ism o nom br e. I gualm ent e, por m edio del m ét odo Get Tem pPat h podem os aver iguar el dir ect or io t em por al del sist em a. I ncluso podem os gener ar nom br es aleat or ios "segu r os" par a ficher os o dir ect or ios m ediant e el m ét odo Get Random FileNam e. Veam os un ej em plo par a gener ar est os nom br es t em por ales y aleat or ios: Dim dir As String dir = Path.GetTempPath() Console.WriteLine("Directorio temporal: {0}", dir) Dim fic As String fic = Path.GetTempFileName() Console.WriteLine("Fichero temporal: {0}", fic) ' fic = Path.GetRandomFileName() Console.WriteLine("Fichero random: {0}", fic) En los dos pr im er os casos, se usa el dir ect or io % TEM P% del sist em a. Y en el caso del ficher o t em por al, la ex t ensión es .t m p En el n om br e aleat or io, t ant o el n om br e com o la ex t ensión est án for m ados por car act er es "im pr im ibles" aleat or ios. Est a ser ía una "posible" salida par a un usuar io llam ado Alguien: Directorio temporal: C:\Documents and Settings\Alguien\Local Settings\Temp\ Fichero temporal: C:\Documents and Settings\Alguien\Local Settings\Temp\tmp257.tmp Fichero random: rmbpgxv1.14g Las clases que podem os usar par a leer o escr ibir en los st r eam s, ( y por ex t ensión en los ficher os a los que apunt an esos st r eam s) , son: Binar yReader , lee t ipos pr im it iv os o cadenas codificadas desde un FileSt r eam . Binar yWr it er , escr ibe t ipos pr im it iv os o cadenas codificadas en un FileSt r eam . St r eam Reader , lee car act er es desde un FileSt r eam , usando codificación par a conv er t ir los car act er es a/ desde byt es. St r eam Wr it er , escr ibe car act er es a un FileSt r eam , usando codificación par a conv er t ir los car act er es en by t es. St r ingReader , lee car act er es desde un St r ing. La salida puede ser a un st r eam en cualquier codificación o a una cadena. St r ingWr it er , escr ibe car act er es a un St r ing. Al igual que St r ingReader , la salida puede ser a un st r eam usando cualquier codificación o a una cadena. Text Reader , es la clase abst r act a base par a St r eam Reader y St r ingReader . Text Wr it er , es la case abst r act a base par a St r eam Wr it er y St r ingWr it er . La s cla se s St r e a m Re a de r y St r e a m W r it e r Aunque ya hem os ut ilizado algunas de est as clases en los ej em plos que hem os est ado viendo, nos vam os a cent r ar en las dos que con m ás asiduidad usar em os: St r eam Reader y St r eam Wr it er , aunque solo t r at ar em os algunos t em as, ya que en líneas gener ales, ya "deber íam os" saber cóm o usar las. Est as dos clases las podem os cr ear dir ect am ent e, indicando el ficher o al que acceder em os o bien, podem os usar el v alor dev uelt o por alguna ot r a clase o m ét odo de las clases File o FileI nfo. La codifica ción de los fich e r os de .N ET En lo que r est a de est e capít ulo nos cent r ar em os en los for m at os de codificación usados con est as dos clases, y por r egla gener al con los ficher os de .NET. La pr incipal v ent aj a de est as clases es que nos per m it en acceder al cont enido de los ficher os en m odo t ex t o, que es lo que necesit ar em os en la m ay or ía de los casos. Tam bién podr em os indicar en el const r uct or de est as clases la codificación a usar . Com o ya hem os com ent ado en ot r as ocasiones, por defect o esa codificación es UTF- 8, es decir car act er es Unicode de 8 bit s. Per o si quer em os leer y escr ibir ficher os que sean com pat ibles con ot r as aplicaciones de Windows, por ej em plo, nuest r as aplicaciones de Visual Basic 6.0, deber íam os usar la codificación ANSI , que es la pr edet er m inada de los sist em as Windows. De est a for m a podr em os leer y escr ibir car act er es "r ar os" com o la let r a eñe o las vocales con t ildes. Par a indicar la codificación a usar , lo t endr em os que indicar com o par ám et r o del const r uct or , por ej em plo, par a abr ir un ficher o con la codificación pr edet er m inada de Windows, lo har em os de est a for m a: Dim sr As New StreamReader(fic1, Encoding.Default) Es decir , usam os la codificación Default , que es la pr edet er m inada de Windows. N ot a: Si no indicam os la codificación que quer em os usar , ést a ser á UTF- 8. Per o debem os t ener en cuent a que est a codificación solam ent e leer á cor r ect am ent e los ficher os que se hayan guar dado pr eviam ent e usando esa m ism a codificación, por t ant o, si quer em os leer ficher os cr eados con VB6, no deber íam os usar UTF- 8, ( Encoding.UTF8) , sino Encoding.Default . Algunos t ipos de ficher os ( según la codificación usada) , guar dar án al pr incipio del m ism o una m ar ca: BOM ( By t e Or der Mar k) indicando la codificación usada par a escr ibir en ellos. El pr opio .NET puede usar dicha m ar ca a la hor a de leer en los ficher os, par a que así lo haga, podem os indicar lo en el const r uct or de la clase St r eam Reader : Figur a 4 .3 . D et ect ar aut om át icam ent e la codificación usada Aunque est a det ección aut om át ica solo funcionar á con los t ipos de ficher os que guar dan dicha infor m ación, que son los t ipos: UTF- 8, UTF- 16 y UTF- 32, de est os dos últ im os exist en dos m ar cas según se ut ilice "big- endian" o "lit t le- endian", es decir , si el byt e m ás significat iv o est á al pr incipio o al final r espect ivam ent e. Est as m ar cas, conocidas en .NET com o "pr eám bulos", se pueden av er iguar t am bién por m edio del m ét odo Get Pr eam ble de la clase Encoding. En la siguient e t abla podem os v er los valor es hex adecim ales de las m ar cas usadas en los ficher os. Codificación Núm er o de byt es Secuencia de byt es ( hex) UTF- 8 3 EF BB BF UTF- 16 Lit t le- Endian 2 FF FE UTF- 16 Big- Endian 2 FE FF UTF- 32 Lit t le- Endian 4 00 00 FF FE UTF- 32 Big- Endian 4 00 00 FE FF Tabla 4 .1 . M ar cas ( BOM ) de los ficher os UTF Cuando leem os la infor m ación de un ficher o abier t o por m edio de St r eam Reader , podem os hacer lo línea a línea o bien t odo el cont enido de una sola vez. Com o vim os en la lección de los st r eam s, podem os usar el m ét odo ReadLine o ReadToEnd par a r ealizar est as dos oper aciones de lect ur a. Al usar la clase St r eam Wr it er , t am bién podem os indicar la codificación a usar par a guar dar el t ex t o del ficher o: Dim sw As New StreamWriter(fic2, False, Encoding.Default) El segundo par ám et r o del const r uct or lo usar em os par a indicar si quer em os añadir t ext o al cont enido del ficher o ( Tr ue) o sim plem ent e quer em os sobr escr ibir lo, ( False) , de for m a que cualquier cont enido ant er ior desapar ezca. Com o r ecom endación final, y siguiendo con el t em a de la codificación, ( que aunque par ezca algo "t r ivial" a m uchos usuar ios les da algún que ot r o dolor de cabeza) , decir que debem os t ener pr ecaución a la hor a de elegir la m ás adecuada. Si quer em os que los ficher os que m anej em os con nuest r a aplicación de Visual Basic 2010 sean "com pat ibles", por ej em plo, con los de VB6, deber íam os usar la codificación Encoding.Default . Si los ficher os solo se usar án desde aplicaciones de .NET, podem os usar la codificación pr edet er m inada, es decir : UTF- 8. Si v am os a guar dar ficher os XML, deber íam os usar siem pr e codificación UTF- 8, que es la pr edet er m inada par a ese for m at o de ficher os. Ent r e los obj et ivos de est e cur so no est á hablar del obj et o My y de los obj et os que cont iene, los cuales nos facilit an un acceso r ápido a la m ayor ía de r ecur sos con los que habit ualm ent e t r abaj ar em os en nuest r as aplicaciones. Per o no nos gust ar ía dej ar un "m al sabor de boca", el cual se quedar ía si no hablár am os, aunque sea un poco de est e obj et o. Tam bién es cier t o que el obj et o My ( y el r est o de obj et os que lo com pone) ser á uno de los que con m ás fr ecuencia encont r ar em os docum ent ación y ej em plos, t ant o en la Web com o en la pr opia docum ent ación de Visual Basic 2010, por t ant o quisiér am os que el lect or no dej e de leer sobr e est e obj et o, ya que en m uchas ocasiones nos ayudar á a hacer m uchas de las t ar eas habit uales en cualquier aplicación, e incluso los desar r ollador es de VB6 encont r ar án m uchos de los obj et os a los que est án acost um br ados a ut ilizar , com o el obj et o App o la for m a de acceder a la colección de los for m ular ios car gados en la m em or ia. El obj e t o M y .Com p ut e r .File Sy st e m En cuant o a lo que r espect a al sist em a de ar chivos, la m ayor ía de la funcionalidad est á incluida en el obj et o My.Com put er .FileSyst em . Si bien, debem os aclar ar que esos obj et os o pr opiedades, r ealm ent e son una especie de acceso dir ect o a las clases del pr opio .NET Fr am ewor k, y esa es la excusa de no haber t r at ado est e obj et o con m ás pr ofundidad, ya que si sabem os m anej ar el r est o de clases de .NET, sabr em os t r abaj ar con el obj et o My. Ent r e las pr opiedades del obj et o My.Com put er .FileSyst em , podem os encont r ar m uchos de los m ét odos que exponen las clases File y Dir ect or y, aunque est os m ét odos t endr án nom br es difer ent es, por ej em plo, en lugar de t ener un m ét odo Exist s, nos encont r am os con uno par a aver iguar si exist e un dir ect or io: Dir ect or yExist s, y ot r o par a aver iguar si exist e un ficher o: FileExist s. Tam bién quisiér am os r esalt ar dos m ét odos que pueden ser nos de bast ant e ut ilidad cuando est em os buscando t ext o en los ficher os o cuando quer am os abr ir un ficher o con una est r uct ur a det er m inada, nos est am os r efir iendo a los m ét odos: FindI nFiles y OpenText FieldPar se r espect ivam ent e. Bu sca r t e x t o e n fich e r os con Fin dI n File s FindI nFiles devuelve una colección "gener ic" de t ipo St r ing y de solo lect ur a con los ficher os que cont ienen el t ext o indicado. En el siguient e ej em plo buscam os ficher os que cont enga el t ext o "hola", se ignor e las m ayúsculas y m inúsculas y se haga la búsqueda t am bién en los subdir ect or ios: Dim list As System.Collections.ObjectModel.ReadOnlyCollection(Of String) ' Buscar texto en los ficheros. list = My.Computer.FileSystem.FindInFiles( _ "E:\Pruebas", "hola", _ True, FileIO.SearchOption.SearchAllSubDirectories) ' Mostrar los ficheros con el texto indicado. For Each name As String In list Console.WriteLine(name) Next Ex a m in a r e l con t e n ido de u n fich e r o con for m a t o con Ope n Te x t Fie ldPa r se En el siguient e ej em plo vam os a abr ir un ficher o con una est r uct ur a, r ealm ent e delim it ado con t abulador es, leer em os el cont enido y lo m ost r ar em os exam inando cada uno de los cam pos. En est e ej em plo, podr íam os llam ar al m ét odo Text Par ser de la siguient e for m a: textParser("E:\Pruebas\Prueba parse.txt", vbTab) Sub textParser(ByVal fic As String, ByVal sep As String) ' Creamos el "parser". Dim reader As FileIO.TextFieldParser reader = My.Computer.FileSystem.OpenTextFieldParser(fic) ' Le indicamos que buscaremos delimitadores. reader.TextFieldType = FileIO.FieldType.Delimited ' Un array con los delimitadores. reader.Delimiters = New String() {sep} Dim fila() As String ' Mientras haya datos... While Not reader.EndOfData Try ' Leemos todos los campos. fila = reader.ReadFields() Console.WriteLine("Los campos de la fila son:") ' Los mostramos. For Each campo As String In fila Console.Write("{0}, ", campo) Next Console.WriteLine() Catch ex As Exception Console.WriteLine("Error: " & ex.Message) End Try End While End Sub Est a es ot r a de las ár eas con la que los desar r ollador es de VB6 se ver án beneficiados, al m enos si nuest r a int ención es la acceder a la r ed de r edes: I nt er net . Aunque t am bién t endr em os clases par a int er act uar con nuest r a r ed local o em pr esar ial, adem ás de clases par a com unicación por "socket s" y acceso a FTP, et c. Las m ayor ía de las clases que necesit em os par a acceder a la r ed, las encont r ar em os en el espacio de nom br es Syst em .Net . Acce so a I nt e r ne t Syst e m .N e t : La s cla se s pa r a a cce de r a la r e d Las clases de Syst em .Net Acceder a una página Web Acceder a un ser vidor FTP Acceso r ápido a la r ed con My.Com put er .Net wor k Aver iguar si t enem os r ed disponible Hacer Ping a un equipo Baj ar un ficher o desde una dir ección Web Obt ener infor m ación de la r ed con las clases de .NET Sy st em .N et : Las clase s par a acce der a la r e d En el espacio de nom br es Syst em .Net t enem os t odo lo que necesit am os par a acceder a I nt er net y / o a ot r os r ecur sos que est én en una r ed local ( int r anet ) . Debido a que son m uchas las clases, y algunas solo las necesit ar em os en m uy cont adas ocasiones, vam os a int ent ar cent r ar nos en las que consider am os m ás im por t ant es. La s cla se s de Sy st e m .N e t En est e espacio de nom br es t enem os una gr an cant idad de clases, ent r e las que podem os dest acar las siguient es. Aut hent icat ionManager , adm inist r a los m ódulos de aut ent icación dur ant e el pr oceso de aut ent icación del client e. Aut hor izat ion, cont iene un m ensaj e de aut ent icación de un ser v idor de I nt er net . Cook ie, pr opor ciona m ét odos y pr opiedades par a adm inist r ar los cook ies. Cr edent ialCache, pr opor ciona alm acenam ient o par a m últ iples cr edenciales. Dns, pr opor ciona funcionalidad sim ple par a r esolución de nom br es de dom inios. DnsPer m ission, cont r ola los per m isos de acceso a ser v idor es DNS en la r ed. EndPoint , clase abst r act a que ident ifica una dir ección de r ed. FileWebRequest , pr opor ciona una im plem ent ación del sist em a de ar chiv os de la clase WebRequest . FileWebResponse, pr opor ciona una im plem ent ación del sist em a de ar chivos de la clase WebResponse. Ft pWebRequest , im plem ent a un client e FTP. Ft pWebResponse, encapsula una r espuest a desde una pet ición a un ser v idor FTP. Ht t pList ener , pr opor ciona un pr ot ocolo de escucha HTTP sim ple. Ht t pList ener BasicI dent it y, pr opor ciona la ident idad par a la clase Ht t pList ener . Ht t pList ener Cont ext , pr opor ciona acceso a las pet iciones y r espuest as ut ilizadas por la clase Ht t pList ener . Ht t pList ener Request , descr ibe una pet ición HTTP a un obj et o Ht t pList ener . Ht t pList ener Response, r epr esent a una r espuest a a una pet ición adm inist r ada por un obj et o Ht t pList ener . Ht t pVer sion, define las v er siones HTTP sopor t adas por las clases Ht t pWebRequest y Ht t pWebResponse. Ht t pWebRequest , pr opor ciona una im plem ent ación HTTP específica de la clase WebRequest . Ht t pWebResponse, pr opor ciona una im plem ent ación HTTP específica de la clase WebResponse. I PAddr ess, pr opor ciona una dir ección I P ( I nt er net Pr ot ocol) . I PEndPoint , r epr esent a un punt o final de r ed com o una dir ección I P y un núm er o de puer t o. I PHost Ent r y, pr opor ciona una clase cont enedor a par a la infor m ación de dir ección de host de I nt er net . Net wor kCr edent ial, pr opor ciona cr edenciales par a aut ent icación basada en cont r aseña. Ser vicePoint , pr opor ciona adm inist r ación de conexiones par a las conexiones HTTP. Ser vicePoint Manager , adm inist r a la colección de obj et os Ser vicePoint . Socket Addr ess, alm acena infor m ación ser ializada de las clases der iv adas de EndPoint . Sock et Per m ission, cont r ola los der echos par a r ealizar o acept ar conex iones en una dir ección de t r anspor t e. WebClient , pr opor ciona m ét odos com unes par a env iar o r ecibir dat os desde un r ecur so ident ificado por una URI ( Unifor m Resour ce I dent ifier ) . WebPer m ission, cont r ola los der echos de acceso a un r ecur so HTTP de I nt er net . WebPr ox y, cont iene la configur ación del pr ox y HTTP de la clase WebRequest . WebRequest , r ealiza una pet ición a una URI . WebRequest Met hods, clase cont enedor a par a las clases WebRequest Met hods.Ft p, WebRequest Met hods.File, y WebRequest Met hods.Ht t p. WebRequest Met hods.File, r epr esent a los t ipos del pr ot ocolo de ficher o que se pueden usar con una pet ición FI LE. WebRequest Met hods.Ft p, r epr esent a los t ipos del pr ot ocolo FTP que se pueden usar con una pet ición FTP. WebRequest Met hods.Ht t p, r epr esent a los t ipos del pr ot ocolo HTTP que se pueden usar con una pet ición HTTP. WebResponse, pr opor ciona una r espuest a desde una URI . Acce de r a u na pá gina W e b Em pezar em os v iendo cóm o acceder a una página Web. Par a est e t ipo de acceso v am os a usar la clase abst r act a WebRequest y de paso algunas ot r as clases com o WebResponse y ot r as par a m anej ar el st r eam r ecibido con el cont enido de la página solicit ada. Veam os un pequeño ej em plo, ( basado y sim plificado de uno de la docum ent ación) , par a hacer lo: Sub leerPaginaWeb(ByVal laUrl As String) ' Cear la solicitud de la URL. Dim request As WebRequest = WebRequest.Create(laUrl) ' Obtener la respuesta. Dim response As WebResponse = request.GetResponse() ' Abrir el stream de la respuesta recibida. Dim reader As New StreamReader(response.GetResponseStream()) ' Leer el contenido. Dim res As String = reader.ReadToEnd() ' Mostrarlo. Console.WriteLine(res) ' Cerrar los streams abiertos. reader.Close() response.Close() End Sub Si la dir ección que est am os solicit ando es una página "act iva", el valor que r ecibir em os es el código "client e", es decir , el código que se env iar á al nav egador . Si necesit am os hacer algunas pet iciones m ás específicas o necesit am os obt ener alguna ot r a infor m ación podem os usar un obj et o del t ipo Ht t pWebRequest el cual est á basado en la clase WebRequest , per o que la am plía par a ofr ecer ot r os t ipos de infor m ación y acciones m ás adecuadas a una pet ición HTTP. La for m a de usar est a clase ser ía igual que WebRequest , adem ás de que la docum ent ación r ecom ienda usar el m ét odo Cr eat e de WebRequest par a cr ear una nuev a inst ancia de Ht t pWebr equest . En el siguient e ej em plo, le indicam os que est am os usando un navegador desde un "Sm ar t phone": Sub leerPaginaWeb2(ByVal laUrl As String) ' Cear la solicitud de la URL. Dim hRequest As HttpWebRequest = _ CType(WebRequest.Create(laUrl), HttpWebRequest) ' para que lo devuelva como si accediéramos con un Smartphone hRequest.UserAgent = _ "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; Smartphone; 176x220)" ' Obtener la respuesta y abrir el stream de la respuesta recibida. Dim reader As New StreamReader(hRequest.GetResponse.GetResponseStream) Dim res As String = reader.ReadToEnd() ' Mostrarlo. Console.WriteLine(res) ' Cerrar el stream abierto. reader.Close() End Sub Acce de r a un se r v idor FTP Por m edio de la clase Ft pWebRequest podem os acceder a una dir ección FTP de for m a bast ant e fácil, com o es habit ual en est e t ipo de clases, est e obj et o se cr ea m ediant e el m ét odo com par t ido Cr eat e, al que le debem os pasar la dir ección FTP a la que quer em os acceder . Debido a que los sit ios FTP pueden est ar pr ot egidos por cont r aseña, es posible que necesit em os asignar la pr opiedad Cr edent ials de est e obj et o, est o lo podem os hacer asignando el obj et o cr eado a par t ir de la clase Net wor k Cr edent ial. Los dist int os com andos que necesit em os env iar al FTP lo har em os m ediant e la pr opiedad Met hod. En el siguient e ej em plo ut ilizam os la clase Ft pWebRequest par a list ar el cont enido de un dir ect or io FTP público. Sub Main() listarFTP("ftp:"//ftp.rediris.es", "[email protected]", "") ' Console.ReadLine() End Sub Sub listarFTP(ByVal dir As String, ByVal user As String, ByVal pass As String) Dim dirFtp As FtpWebRequest = CType(FtpWebRequest.Create(dir), FtpWebRequest) Dim cr As New NetworkCredential(user, pass) dirFtp.Credentials = cr dirFtp.Method = "LIST" Dim reader As New StreamReader(dirFtp.GetResponse().GetResponseStream()) Dim res As String = reader.ReadToEnd() ' Mostrarlo. Console.WriteLine(res) ' Cerrar el stream abierto. reader.Close() End Sub Acce so r á pido a la r e d con M y .Com put e r .N e t w or k El obj et o My t am bién cont iene obj et os con los que podem os acceder a cier t as car act er íst icas de la r ed, en par t icular m ediant e el obj et o My .Com put er .Net wor k t enem os acceso a una pr opiedad y t r es m ét odos con los que podem os hacer lo siguient e: I sAv aillable, est a pr opiedad nos per m it e saber si la r ed est á disponible. Ping, con est e m ét odo podem os hacer un "ping" a un equipo r em ot o. DownloadFile, nos per m it e baj ar un ficher o desde una dir ección Web. UploadFile, nos per m it e env iar un ficher o a una dir ección Web. En el siguient e código t enem os ej em plos de est os m ét odos y pr opiedades: If My.Computer.Network.IsAvailable = True Then Console.WriteLine("El ordenador está conectado.") Else Console.WriteLine("El ordenador no está conectado.") End If ' If My.Computer.Network.Ping("192.168.1.26") Then Console.WriteLine("El equipo está activo.") Else Console.WriteLine("Se ha sobrepasado el tiempo de espera.") End If ' Dim ficDest As String = "E:\Pruebas\robots.txt" My.Computer.Network.DownloadFile( _ "http:"//www.elguille.info/robots.txt", _ ficDest) ' If My.Computer.FileSystem.FileExists(ficDest) Then Console.WriteLine("El fichero se ha bajado") Else Console.WriteLine("El fichero no se ha bajado") End If Obt e ne r infor m a ción de la r e d con la s cla se s de .N ET Com o acabam os de ver , el espacio de nom br es Sy st em .Net incluy e algunas clases y ot r os espacios de nom br es que son par t e de las novedades de .NET Fr am ewor k 2.0, que es al fin y al cabo el ent or no que pr opor ciona la libr er ía de clases en las que se apoy a Visual Basic 2010 par a obt ener funcionalidad; ent r e ellos t enem os Net wor k I nfor m at ion, el cual incluy e clases que nos per m it ir án com pr obar si t enem os conex ión a la r ed, hacer un ping, obt ener la dir ección MAC del adapt ador de r ed y algunos et cét er as m ás, de esas clases es la que se sir v e el obj et o My.Com put er .Net wor k par a obt ener la funcionalidad, ya que en r ealidad t odos los obj et os de My se basan en clases ex ist ent es en .NET. En el siguient e ej em plo, podem os v er algunas de esas "cosillas" que podem os hacer ahor a sin necesidad de "r ebuscar " en la funcionalidad del API de Windows. Imports Imports Imports Imports Microsoft.VisualBasic System System.Net System.Net.NetworkInformation Module Module1 Sub Main() probarConexionARed() Console.WriteLine() realizarPing() Console.WriteLine() adaptadoresRed() Console.ReadLine() End Sub ' Realizar un ping Sub realizarPing() Console.WriteLine("Loopback: {0}{1}", IPAddress.Loopback, vbCrLf) Dim ip As IPAddress = IPAddress.Parse("127.0.0.1") Dim ping As Ping = New Ping For i As Integer = 0 To 3 Dim pr As PingReply = ping.Send(ip) Console.Write("Respuesta desde {0}: bytes: {1}, ", pr.Address, pr.Buffer.Length) Console.WriteLine("tiempo= {0} ({1})", pr.RoundtripTime, pr.Status) Next End Sub ' Comprobar si tenemos conexión de red Sub probarConexionARed() If NetworkInterface.GetIsNetworkAvailable Then Console.WriteLine("Conexion disponible") Else Console.WriteLine("Conexion NO disponible") End If End Sub ' Muestra información de los adaptadores de red que tenemos Sub adaptadoresRed() For Each ni As NetworkInterface In NetworkInterface.GetAllNetworkInterfaces() Console.WriteLine("Descripción: {0}", ni.Description) Console.WriteLine("Estado: {0}", ni.OperationalStatus) Console.WriteLine("Velocidad: {0:n} bps", ni.Speed) Console.WriteLine("Dirección MAC: {0}{1}", ni.GetPhysicalAddress, vbCrLf) Next End Sub End Module Módulo 5 - Acceso a datos En este módulo, aprenderemos a trabajar con datos y fuentes de datos en Visual Basic 2010. ADO.NET es la tecnología principal para conectarse a una base de datos , nos ofrece un alto nivel de abstracción, ocultando los detalles de bajo nivel de la implementación de la base de datos de un fabricante. En este tutorial, encontrará las cosas más importantes que debe saber, para trabajar con fuentes de datos con Visual Basic 2010. De esta manera, aprenderá en poco tiempo, a encontrarse cómodo en el entorno de clases de ADO.NET y podrá así, sacar el máximo provecho a sus desarrollos. Las partes que forman parte de este módulo son las siguientes: Capítulo 1 ● Descripción de ADO.NET Capítulo 2 ● Acceso conectado a bases de datos Capítulo 3 ● Acceso desconectado: DataSets y DataAdapters Capítulo 4 ● DataSets tipados Capítulo 5 ● Enlace a formularios Introducción A continuación veremos todo lo que debe saber sobre ADO.NET para crear aplicaciones que accedan a fuentes de datos desde Visual Basic 2010. Comprobará que ahora, es incluso mucho más fácil y rápido, si bien, es necesario conocer el modelo con el que se trabaja para poder saber lo que deberemos hacer en un momento dado. Módulo 5 - Capítulo 1 ● 1. Acercándonos a ADO.NET ● 2. System.Data ● 3. Los proveedores de acceso a datos ● 4. El concepto DataBinding ● 5. Otras consideraciones Módulo 5 - Capítulo 1 1. Acercándonos a ADO.NET ADO. NET ha sufr ido a lo lar go de los últ im os años difer ent es m ej or as y act ualizaciones, desde que . NET apar eció. El r esum en de las difer ent es v er siones de ADO. NET podr ía quedar de la siguient e for m a. ADO. NET 1. 0 apar eció con Micr osoft . NET Fr am ew or k 1. 0. Post er ior m ent e, ADO. NET 1. 1 sufr ió una pequeñas y casi inapr eciables act ualizaciones con la apar ición de Micr osoft . NET Fr am ew or k 1. 1. En el caso del ent or no Visual St udio 2010, ést e t r abaj a con el CLR de Micr osoft . NET Fr am ew or k 2. 0 y por lo t ant o, ut iliza ADO. NET 2. 0, el cuál añade algunas car act er íst icas nuev as adicionales. En nuest r o caso, nos cent r ar em os única y ex clusiv am ent e en ADO. NET com o m odelo de obj et os de acceso a dat os par a la plat afor m a . NET de Micr osoft , y a que es el m ism o par a cualquier t ipo de v er sión de ADO. NET. ¿Qué es AD O.N ET? ADO. NET es la t ecnología pr incipal par a conect ar se aun gest or de bases de dat os, con un alt o niv el de abst r acción, lo que nos per m it e olv idear nos de los det alles de baj o niev el de las bases de dat os. Adem ás ADO. NET es una t ecnología int er oper at iv a. Aper t e del alm acenam ient o y r ecuper ación de dat s, ADO. NET int r oduce la posibilidad de int egr ar se con el est ándar XML, los dat os pueden 'Ser ializar se' dir ect am ent e a y desde XML lo que fav or ece el int er cam bio de infor m acion. ADO. NET pr opor ciona difer ent es clases del nom br e de espacio Sy st e m . D a t a dent r o de las cuáles, dest acar em os por encim a de t odas, la clase D a t a V ie w , la clase D a t a Se t y la clase D a t a Ta b le . Est e conj unt o de clases de car áct er ar m ónico, funcionan de igual for m a con la capa infer ior que es la que cor r esponde a los pr ov eedor es de acceso a dat os con los que podem os t r abaj ar . Est o facilit a el t r abaj o en n- capas y la posible m igr ación de aplicaciones que ut ilicen una det er m inada fuent e de dat os y deseem os en un m om ent o dado, hacer uso de ot r a fuent e de dat os. ¿Qué capas o qué par t es hay dent r o de AD O.N ET? Dent r o de ADO. NET t enem os dos par t es im por t ant es. La pr im er a de ellas es la que cor r esponde con el nom br e de espacio Sy st e m . D a t a y que const it uy e los obj et os y clases globales de ADO. NET. La ot r a par t e es la que cor r esponde con los obj et os que per m it en el acceso a dat os a una det er m inada fuent e de dat os desde ADO. NET y que ut ilizan así m ism o, las clases del nom br e de espacio Sy st e m . D a t a . Est a últ im a par t e, queda const it uida por las clases y obj et os de los difer ent es pr ov eedor es de acceso a dat os com o se m uest r a en la figur a 1. Visión ge ne ra l de la s cla se s de ADO.NET Figur a 1 Par a r esum ir de alguna for m a lo que est am os com ent ando, dir em os que el t r abaj o de conex ión con la base de dat os, la ej ecución de una inst r ucción SQL det er m inada, una v ist a, et c. , la r ealiza el pr ov eedor de acceso a dat os. Recuper ar esos dat os par a t r at ar los, m anipular los o v olcar los a un det er m inado cont r ol o disposit iv o, es acción de la capa super ior que cor r esponde con el nom br e de espacio Sy st e m . D a t a . A cont inuación v er em os t odo est o con m ás det alle y com pr ender em os de una for m a m ás clar a cada una de las par t es que com ponen el m odelo de t r abaj o con ADO. NET. ¿Qué nos per m it e r ealm ent e AD O.N ET cuando t r abaj am os con XM L? El ent or no de Micr osoft . NET Fr am ew or k nos pr opor ciona el t r abaj o con est ándar es y con ello, la posibilidad de t r abaj ar con difer ent es t ipos de aplicaciones, ent or nos, sist em as oper at iv os y lenguaj es sin necesidad de conocer lo que hay al ot r o lado de nuest r a aplicación. XML es sin lugar a dudas, el lenguaj e de et iquet as por ex celencia, v álido par a llev ar a cabo est a t ar ea sin t ener un im pact o r elev ant e cuando t r abaj am os con difer ent es soluciones en ent or nos dispar es. Tant o la posibilidad de t r abaj ar con Ser v icios Web XML com o con docum ent os e infor m ación en XML, sobr e t odo al t r abaj ar con fuent es de dat os en ADO. NET, nos pr opor ciona a los desar r ollador es las posibilidades necesar ias que nos per m it e hacer que la infor m ación con la que t r abaj am os, pueda ser t r at ada ent r e difer ent es sist em as o ent or nos, sin que por ello nos pr eocupem os de lo que hay al ot r o lado. Módulo 5 - Capítulo 1 2. System.Data Las clases del nom br e de espacio Sy st e m . D a t a son bast ant es ex t ensas y v ar iadas. Quizás las clases m ás im por t ant es son la clase D a t a V ie w , la clase D a t a Se t y la clase D a t a Ta b le . La clase D at aSet El Dat aSet es una r epr esent ación de dat os r esident e en m em or ia que pr opor ciona una m odelo de pr ogr am ación r elacional coher ent e independient em ent e del or igen de dat os que cont iene. El Dat aSet cont iene en sí, un conj unt o de dat os que han sido v olcados desde el pr ov eedor de dat os. Debem os t ener en cuent a que cuando t r abaj am os con Dat aSet s, el or igen de dat os no es lo m ás im por t ant e, y a que ést e, puede ser cualquier t ipo de or igen de dat os. No t iene por qué ser una base de dat os. Un Dat aSet cont iene colecciones de Dat aTables y Dat aRelat ions. El Dat aTable cont iene una t abla o t ablas, m ient r as que la Dat aRelat ion cont iene las r elaciones ent r e las Dat aTables. Sin em bar go, no es necesar io especificar t odo est o hast a el últ im o det alle com o v er em os m ás adelant e. La cla se D at aView Est e obj et o nos per m it e cr ear m últ iples v ist as de nuest r os dat os, adem ás de per m it ir nos pr esent ar los dat os. Es la clase que nos per m it e r epr esent ar los dat os de la clase Dat aTable, per m it iéndonos edit ar , or denar y filt r ar , buscar y nav egar por un conj unt o de dat os det er m inado. La clase D at aTable Est e obj et o nos per m it e r epr esent ar una det er m inada t abla en m em or ia, de m odo que podam os int er act uar con ella. A la hor a de t r abaj ar con est e obj et o, debem os t ener en cuent a el nom br e con el cuál definam os una det er m inada t abla, y a que los obj et os declar ados en en el Dat aTable es sensit iv o a m ay úsculas y m inúsculas. Un pequeño ej em plo pr áct ico El siguient e ej em plo pr áct ico, nos enseña a ut ilizar un Dat aSet y nos m uest r a com o podem os acceder a los obj et os que dependen de un Dat aSet par a r ecuper ar por ej em plo, los cam pos y pr opiedades de una det er m inada t abla o t ablas. Imports System.Data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim Conexion As String = "server=.;uid=sa;password=VisualBasic;database=MSDNVideo" Dim MiTabla As DataTable Dim MiColumna As DataColumn Dim MiDataSet As New DataSet() Dim Comando As New SqlDataAdapter("SELECT * FROM ALQUILERES", Conexion) Comando.Fill(MiDataSet, "ALQUILERES") ' Recorremos las tablas For Each MiTabla In MiDataSet.Tables TextBox1.Text += "Tabla: " & MiTabla.TableName & vbCrLf & vbCrLf ' Recorremos las Columnas de cada Tabla For Each MiColumna In MiTabla.Columns TextBox1.Text += MiColumna.ColumnName & vbTab & _ "(" & MiColumna.DataType.Name & ")" & vbCrLf Next Next Comando = Nothing End Sub End Class Nuest r o ej em plo en ej ecución es el que se m uest r a en la figur a 1. Ej e m plo e n e j e cución de l uso de Da t a Se t , Da t a Ta ble y Da t a Colum n Figur a 1 Módulo 5 - Capítulo 1 3. Los proveedores de acceso a datos Los proveedores de acceso a datos es la capa inferior de la parte correspondiente al acceso de datos y es la responsable de establecer la comunicación con las fuentes de datos. En este conjunto de nombres de espacio, encontraremos casi siempre las clases Con n e ct ion , Com m a n d , D a t a Ad a p t e r y D a t a Re a d e r como las clases más generales, las cuales nos permiten establecer la conexión con la fuente de datos. Pr oveedor es de acceso a dat os de .N ET Fr am ew or k Dentro del entorno .NET Framework, encontramos un nutrido conjunto de proveedores de acceso a datos. Estos son los siguientes: ● ODBC . NET Dat a Pr ov ider ● OLE DB . NET Dat a Pr ov ider ● Or acle Client . NET Dat a Pr ov ider ● SQL Ser v er . NET Dat a Pr ov ider Estos proveedores de acceso a datos incluidos en Microsoft .NET Framework, los podemos encontrar en los nombres de espacio: ● Sy st em . Dat a. Odbc ● Sy st em . Dat a. OleDb ● Sy st em . Dat a. Or acleClient ● Sy st em . Dat a. SqlClient El proveedor ODBC .NET permite conectar nuestras aplicaciones a fuentes de datos a través de ODBC. El proveedor OLE DB .NET permite conectar nuestras aplicaciones a fuentes de datos a través de OLE DB. El proveedor Oracle Client .NET es un proveedor de acceso a datos especialmente diseñado para bases de datos Oracle. Por último, el proveedor SQL Server .NET es un proveedor de acceso a datos nativo, que nos permite conectar nuestras aplicaciones a fuentes de datos Microsoft SQL Server 7 o posterior. Se trata de un proveedor específico para bases de datos Microsoft SQL Server 7.0, Microsoft SQL Server 2000 y Microsoft SQL Server 2005 ó superior. Consej o: Siem pr e que pueda, ut ilice par a acceder a fuent es de dat os, un pr oveedor de acceso a dat os nat ivo. Est o le per m it ir á aum ent ar consider ablem ent e el r endim ient o a la hor a de est ablecer la conexión con una det er m inada fuent e de dat os Los proveedores de acceso a datos que distribuye Microsoft en ADO.NET y algunos desarrollados por otras empresas o terceros, contienen los mismos objetos, aunque los nombres de éstos, sus propiedades y métodos, pueden ser diferentes. Más adelante veremos algún ejemplo, y observará en la práctica cuáles son estas diferencias más destacables. Ot r os pr oveedor es de acceso a dat os Si bien el proveedor de acceso a datos es el m ecanism o a través del cuál podemos establecer una comunicación nativa con una determinada fuente de datos, y dado que Microsoft proporciona los proveedores de acceso a datos más corrientes, es cierto que no los proporciona todos, si bien, con OLE DB y ODBC, podemos acceder a la inmensa totalidad de ellos. Sin embargo, hay muchos motores de bases de datos de igual importancia como Oracle, MySql, AS/400, etc. En estos casos, si queremos utilizar un proveedor de acceso a datos nativo, deberemos acudir al fabricante o a empresas o iniciativas particulares para que nos proporcionen el conjunto de clases necesarias que nos permitan abordar esta acción. El obj et o Connect ion Este objeto es el encargado de establecer una conexión física con una base de datos determinada. Para establecer la conexión con una determinada fuente de datos, no sólo debemos establecer la cadena de conexión correctamente, sino que además deberemos usar los parámetros de conexión y el proveedor de acceso a datos adecuado. Con este objeto, podremos además abrir y cerrar una conexión. El obj et o Com m and Este objeto es el que representa una determinada sentencia SQL o un Stored Procedure. Aunque no es obligatorio su uso, en caso de necesitarlo, lo utilizaremos conjuntamente con el objeto Dat aAdapt er que es el encargado de ejecutar la instrucción indicada. El obj et o D at aAdapt e r Este objeto es quizás el objeto más complejo y a la vez complicado de todos los que forman parte de un proveedor de acceso a datos en .NET. Cuando deseamos establecer una comunicación entre una fuente de datos y un Dat aSet , utilizamos como int er m ediar io a un objeto Dat aAdapt er . A su vez, un Dat aAdapt er contiene 4 objetos que debemos conocer: ● Select Com m and es el objeto encargado de realizar los trabajos de selección de datos con una fuente de datos dada. En sí, es el que se encarga de devolver y rellenar los datos de una fuente de datos a un Dat aSet . ● Delet eCom m and es el objeto encargado de realizar las acciones de borrado de datos. ● I nser t Com m and es el objeto encargado de realizar las acciones de inserción de datos. ● Updat eCom m and es el objeto encargado de realizar las acciones de actualización de datos. Los objetos Delet eCom m and, I nser t Com m and y Updat eCom m and son los objetos que se utilizan para manipular y transmitir datos de una fuente de datos determinada, al contrario del objeto Select Com m and que tan sólo interactúa con la fuente de datos para recuperar una porción o todos los datos indicados en el objeto Com m and anteriormente comentado. El obj et o D at aReader Este objeto es el utilizado en una sola dirección de datos. Se trata de un objeto de acceso a datos muy rápido. Este objeto puede usar a su vez el objeto Com m and o el método Ex ecut eReader . Módulo 5 - Capítulo 1 4. El concepto DataBinding Dat aBinding es una ex pr esión de enlace a dat os. Com o v er em os a cont inuación es una for m a r ápida y sencilla de m anej ar la fuent es de dat os m ediant e su enlace con cont r oles o clases. . El uso de D at aBind El m ét odo Dat aBind se ut iliza par a r ellenar de dat os un det er m inado cont r ol o clase. Muchos cont r oles y clases, posee est e m ét odo al que le asignar em os un conj unt o de dat os par a que se r ellene con ellos, pudiendo después int er act uar con los dat os de for m a dir ect a. En sí, un Dat aBinding es un enlace a dat os que se encar ga de r ellenar de dat os a un det er m inado cont r ol o clase. Com o ej em plo de est o, v er em os com o r ellenar un cont r ol Te x t Box con un dat o ut ilizando est e m ét odo. I niciar em os una nuev a aplicación Window s y escr ibir em os el siguient e código fuent e: Imports System.Data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim Conexion As String = "server=.;uid=sa;password=VisualBasic;database=MSDNVideo" Dim MiDataSet As New DataSet() Dim Comando As New SqlDataAdapter("SELECT TITULO FROM ALQUILERES, PELICULAS WHERE PELICULACODBARRAS = CODBARRAS AND SOCIONIF = '111111'", Conexion) ' Rellenamos el DataSet con el contenido ' de la sentencia SELECT Comando.Fill(MiDataSet, "PELIS") ' Rellenamos el control TextBox1 con el ' dato correspondiente a la primera fila ' de la sentencia SELECT ejecutada TextBox1.DataBindings.Add("Text", MiDataSet, "PELIS.TITULO") Comando = Nothing End Sub End Class Nuest r o ej em plo en ej ecución es el que se m uest r a en la figur a 1. Ej e m plo e n e j e cución de l uso de Da t a Binding Figur a 1 Módulo 5 - Capítulo 1 5. Otras consideraciones Dentro de las conexiones a fuentes de datos, hay algunas partes de éstas que permanecen a veces en el olvido y su importancia sin embargo, es bastante grande. La acción más pesada cuando realizamos un acceso a una fuente de datos, se encuentra en la conexión con la fuente de datos. Esa tarea, simple tarea, es la que más recursos del sistema consume cuando accedemos a fuentes de datos. Esto lo debemos tener en cuenta, y por lo tanto, variante de esto que comentamos son las siguientes premisas: ● La conexión debe realizarse siempre que se pueda, con los proveedores de acceso a datos nativos, que por lo general salvo raras excepciones, serán más rápidos que los accesos a fuentes de datos a través de proveedores del tipo OLE DB y ODBC. ● La conexión con la fuente de datos (apertura de la conexión), debe realizarse lo más tarde posible. Es recomendable definir todas las variables que podamos, antes de realizar la conexión. ● La conexión debe cerrarse lo antes posible, siempre y cuando no tengamos la necesidad de utilizar la conexión previamente abierta. Hay más particularidades a tener en cuenta cuando trabajamos con fuentes de datos. El hecho de que con un Dat aSet podamos trabajar con datos desconectados, no significa que dentro de él, podamos abrir una tabla con una cantidad de registros enormes, y trabajemos sobre ella creyendo que esto nos beneficiará. Todo lo contrario. Introducción Ahora que ya tenemos un poco más clara la estructura del modelo de acceso a datos ADO.NET, podemos adentrarnos en todo lo que rodea al acceso conectado de base de datos y la manipulación y trabajo de datos conectados. A continuación, encontrará el índice detallado de este capítulo. Módulo 5 - Capítulo 2 ● 1. El paradigma de la conexión ● 2. Conociendo el objeto DataReader ● 3. Un primer contacto con el objeto DataReader ● 4. ¿Trabaja DataReader en un ambiente conectado realmente? ● 5. Usando DataSource con DataReader ● 6. Usando los componentes de acceso a datos de .NET Módulo 5 - Capítulo 2 1. El paradigma de la conexión Cuando abor dam os un pr oy ect o de acceso a fuent es de dat os, siem pr e nos encont r am os con una duda ex ist encial. ¿Debem os cr ear una conex ión con la base de dat os al pr incipio de nuest r a aplicación y cer r ar la cuando la aplicación se cier r e?, ¿o debem os cr ear una conex ión con la base de dat os sólo cuando v ay am os a t r abaj ar con la fuent e de dat os?. ¿Y si est am os t r abaj ando cont inuam ent e con una fuent e de dat os?, ¿cóm o penalizar ían t odas est as acciones?. Es difícil de asum ir que acción t om ar en cada caso, y es que dependiendo de lo que v ay am os a r ealizar , a v eces es m ás efect iv a una acción que ot r a, y en ot r as ocasiones, no est á del t odo clar o, y a que no ex ist e en sí una r egla clar a que especifique qué acción t om ar en un m om ent o dado. Lo que sí est á clar o es que el m odelo de dat os de ADO. NET que hem os v ist o, quedar ía r esum ido en cuant o a la conect iv idad de la m aner a en la que se r epr esent a en la figur a 1. Visión ge ne ra l de ADO.NET re spe ct o a la cone ct iv ida d con ba se s de da t os Figur a 1 El obj et o Dat aSet nos ofr ece la posibilidad de alm acenar dat os, t ablas y bases de dat os de una det er m inada fuent e de dat os. De est a m aner a, podem os t r abaj ar con las aplicaciones est ando desconect ados de la fuent e de dat os. Sin em bar go, a v eces necesit am os t r abaj ar con la fuent e de dat os est ando conect ados a ella. El obj et o Dat aReader nos ofr ece pr ecisam ent e la posibilidad de t r abaj ar con fuent es de dat os conect adas. Por ot r o lado, el obj et o Dat aReader t iene algunas par t icular idades que conv iene conocer y que v er em os a cont inuación. Módulo 5 - Capítulo 2 2. Conociendo el objeto DataReader El objeto Dat aReader nos permite como hemos indicado anteriormente, establecer una conexión con una fuente de datos y trabajar con esta fuente de datos sin desconectarnos de ella, sin embargo, hay diferentes cualidades y particularidades que conviene conocer. D at aReader es de solo lect ur a Lo que hemos dicho anteriormente, requiere sin embargo, que esta conexión se establezca en un modo de sólo lect ur a, al contrario de lo que se puede hacer con el objeto Dat aSet , con el que podemos interactuar con la fuente de datos en modo lectura y modo escritura. D at aReader se m anej a en una sola dir ección El objeto Dat aReader sólo permite que nos desplacemos por los datos en una sola dirección, sin vuelta atrás. Por el contrario, el objeto Dat aSet nos permite movernos por los registros para adelante y para atrás. Además, sólo podemos utilizar el objeto Dat aReader con conexiones establecidas en una sentencia SQL por ejemplo, pero no podemos variar esta. Para hacerlo, debemos entonces modificar la conexión con el comando establecido. D at aReader es r ápido Debido a su naturaleza y características, este objeto es bastante rápido a la hora de trabajar con datos. Como es lógico, consume además menos memoria y recursos que un objeto Dat aSet por ejemplo. Sin embargo, dependiendo de las necesidades con las que nos encontremos, puede que este método de acceso y trabajo no sea el más idóneo. Analiz ando el fluj o de t r abaj o de D at aReader Cuando trabajamos con fuentes de datos conectadas, trabajaremos con el objeto Dat aReader . Para trabajar con este objeto, utilizaremos los objetos siguientes del proveedor de acceso a datos: ● Connect ion ● Com m and ● Dat aReader Un resumen gráfico de esto es lo que podemos ver en la figura 1. El fluj o de cone ct iv ida d de Da t a Re a de r Figura 1 Módulo 5 - Capítulo 2 3. Un primer contacto con el objeto DataReader A cont inuación v er em os un ej em plo sencillo sobr e la for m a de t r abaj ar con Dat aReader Un e j em plo sim ple par a ent ender lo m ej or Tenga en cuent a que en el siguient e ej em plo nos conect ar em os a Micr osoft SQL Ser v er y r ecor r er em os los r egist r os uno a uno en un am bient e conect ado y v olcar em os est os r egist r os en un cont r ol Te x t Box . Imports System.Data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim Conexion As String = "server=.;uid=sa;password=VisualBasic;database=MSDNVideo" Dim MiConexion As New SqlConnection(Conexion) Dim MiDataReader As SqlDataReader Dim Comando As New SqlCommand("SELECT TITULO FROM ALQUILERES, PELICULAS WHERE PELICULACODBARRAS = CODBARRAS AND SOCIONIF = '111111'", MiConexion) MiConexion.Open() MiDataReader = Comando.ExecuteReader() While MiDataReader.Read() TextBox1.Text += MiDataReader("TITULO").ToString() & vbCrLf End While Comando = Nothing MiConexion.Close() End Sub End Class El código de ej em plo en ej ecución es el que se m uest r a en la figur a 1. Ej e m plo e n e j e cución de l uso sim ple de Da t a Re a de r Figur a 1 Est e es un ej em plo sim ple del uso de Dat aReader . Sin em bar go, el obj et o Dat aReader cont iene un conj unt o de pr opiedades y m ét odos que nos pr opor cionan acc ones det er m inadas. Por ej em plo, en el ej em plo ant er ior , hem os dado por hecho que la ej ecuc ón de la inst r ucción Select nos dev olv er á uno o m ás v alor es, per o podr íam os t am bién saber ant es de m anipular y t r abaj ar con los posibles dat os, si hay o no infor m ac ón. Est o lo conseguim os con el m ét odo HasRow s. Módulo 5 - Capítulo 2 4. ¿Trabaja DataReader en un ambiente conectado realmente? Pese a t odo est o, ¿que ocur r e si t r abaj ando en un am bient e conect ado se desconect a el ser v idor de acceso a dat os?. I m aginem os por un inst ant e, que la conex ión con SQL Ser v er se est ablece cor r ect am ent e y que en un m om ent o dado se det iene el ser v icio del ser v idor de base de dat os. Est o es lo que v er em os en el siguient e ej em plo. D esenchufando la fuent e de dat os usando D at aReader I nicie un nuev o pr oy ect o, inser t e en el for m ular io de la aplicación un cont r ol Te x t Box y un cont r ol Bu t t on , y escr iba el código que se det alla a cont inuación: Imports System.Data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Private Private Private Private Private Private Conexion As String = "server=.;uid=sa;password=VisualBasic;database=MSDNVideo" strSQL As String = "SELECT TITULO FROM ALQUILERES, PELICULAS WHERE PELICULACODBARRAS = CODBARRAS AND MiConexion As New SqlConnection(Conexion) MiDataReader As SqlDataReader Contador As Long = 0 Posicion As Long = 0 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Establecemos la Conexión con la base de datos Establecer_Conexion(True) ' Si hay datos los mostramos, sino deshabilitamos ' la opción (botón) para recorrerlos If Not MiDataReader.HasRows Then Button1.Enabled = False Else Button1_Click(sender, e) End If End Sub Private Sub Establecer_Conexion(ByVal bolAccion As Boolean) Dim Comando As SqlCommand If bolAccion Then ' True => Establecemos la conexión Comando = New SqlCommand(strSQL, MiConexion) ' Abrimos la Conexión MiConexion.Open() ' Ejecutamos la sentencia SQL MiDataReader = Comando.ExecuteReader() ' Obtenemos la cantidad de registros obtenidos Contador = MiDataReader.VisibleFieldCount() + 1 Else ' False => Finalizamos la conexión Button1.Enabled = False ' Cerramos la Conexión Comando = Nothing MiConexion.Close() End If End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Recorremos los registros y los mostramos Posicion += 1 MiDataReader.Read() TextBox1.Text = MiDataReader("TITULO") ' Si hemos recorrido el objeto por completo, ' finalizamos la Conexión y deshabilitamos el control ' Button que nos permite recuperar los registros If Posicion = Contador Then Establecer_Conexion(False) End If End Sub End Class Suponiendo que t enem os en nuest r a base de dat os v ar ios r egist r os, ej ecut e la aplicación. Si t odo ha ido com o se esper aba, obser v ar em os que nuest r a aplicación t iene un aspect o com o el que se m uest r a en la figur a 1. Ej e m plo e n e j e cución de l uso de Da t a Re a de r e n un a m bie nt e cone ct a do, forza ndo la de scone x ión de la fue nt e de da t os Figur a 1 En est e punt o, det enga el ser v icio de SQL Ser v er y pulse el bot ón Sig u ie n t e > > . Obser v ar á que la aplicación sigue funcionando. En est e punt o se har á la pr egunt a que t odos nos hem os hecho, ¿no es el obj et o Dat aReader un obj et o conect ado?, ¿cóm o es posible que funcione si hem os det enido el ser v icio de SQL Ser v er ?. La r espuest a es sencilla. El obj et o Dat aReader r ecuper a un nut r ido conj unt o de v alor es llenando un pequeño buffer de dat os e infor m ación. Si el núm er o de r egist r os que hay en el buffer se acaban, el obj et o Dat aReader r egr esar á a la fuent e de dat os par a r ecuper ar m ás r egist r os. Si el ser v icio de SQL Ser v er est á det enido en ese m om ent o o en su caso, la fuent e de dat os est á par ada, la aplicación gener ar á un er r or a la hor a de leer el siguient e r egist r o. En sí, Dat aReader es un obj et o conect ado, per o t r abaj a en back gr ound con un conj unt o de dat os, por lo que a v eces nos puede r esult ar chocant e su com por t am ient o com o el ej em plo que com ent o. Módulo 5 - Capítulo 2 5. Usando DataSource con DataReader ¿Podem os usar el m ét odo Dat aSour ce con el obj et o Dat aReader ?. D em ost r ación del uso de D at aSour ce con D at aRe ader La r espuest a es sí, en ADO. NET 2. 0, se ha incor por ado un nuev o m ét odo al obj et o Dat aTable que le per m t e t ener m ay or independencia r espect o al m odo en el que nos conect em os y r ecuper em os dat os de una fuent e de dat os. Recuer de que podem os r ecuper ar dat os en m odo conect ado Dat aReader o en m odo desconect ado Dat aSet . Est e m ét odo que se ha incor por ado a ADO. NET y que t iene por nom br e Loa d , nos per m it e car gar un Dat aReader par a v olcar lo a cont inuación dent r o de un cont r ol com o por ej em plo el cont r ol Dat aGr idView . Lo m ej or es que v eam os com o funciona est o con un ej em plo que nos ay ude a com pr ender m ej or la t eor ía. I nser t e en un for m ular io un cont r ol Dat aGr idView y escr iba el siguient e código: Imports System.Data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Declaramos las variables a utilizar Dim Conexion As String = "server=.;uid=sa;password=VisualBasic;database=MSDNVideo" Dim strSQL As String = "SELECT TITULO FROM ALQUILERES, PELICULAS WHERE PELICULACODBARRAS = CODBARRAS AND SOCIONIF = '111111'" Dim MiConexion As New SqlConnection(Conexion) Dim MiDataReader As SqlDataReader Dim MiDataTable As New DataTable Dim Comando As SqlCommand ' Establecemos la Conexión con la base de datos Comando = New SqlCommand(strSQL, MiConexion) ' Abrimos la Conexión MiConexion.Open() ' Ejecutamos la sentencia SQL MiDataReader = Comando.ExecuteReader() ' Cargamos los resultados en el objeto DataTable MiDataTable.Load(MiDataReader, LoadOption.OverwriteChanges) ' Volcamos los datos en el control DataGridView DataGridView1.DataSource = MiDataTable ' Cerramos la Conexión Comando = Nothing MiConexion.Close() End Sub End Class Nuest r o ej em plo en ej ecución es el que podem os v er en la figur a 1. Ej e m plo e n e j e cución de l uso de Da t a Re a de r y Da t a Source e n un cont rol Da t a GridVie w Figur a 1 Con t odo y con est o, lo que r ealm ent e es cur oso, es que hem os olv idado por un inst ant e que el obj et o Dat aReader es un obj et o de sólo lect ur a que funciona en una única dir ección, hacia delant e. ¿Qué signif ca est o o com o puede influir o com o podem os apr ov echar est a cir cunst ancia en nuest r os desar r ollos?. Car ga segm ent ada de dat os con D at aSour ce y D at aReader Si r ecuper am os los dat os de una fuent e de dat os con Dat aReader y leem os algunos de sus dat os y post er or m ent e, ej ecut am os el m ét odo Dat aSour ce, el r est o de dat os, aquellos dat os que quedan en el Dat aReader , ser án los que se v uelquen en el cont r ol que definam os com o dest ino de los dat os. I m aginem os el ej em plo ant er ior , y el siguient e código fuent e. Imports System.Data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Declaramos las variables a utilizar Dim Conexion As String = "server=.;uid=sa;password=VisualBasic;database=MSDNVideo" Dim strSQL As String = "SELECT TITULO FROM ALQUILERES, PELICULAS WHERE PELICULACODBARRAS = CODBARRAS AND SOCIONIF = '111111'" Dim MiConexion As New SqlConnection(Conexion) Dim MiDataReader As SqlDataReader Dim MiDataTable As New DataTable Dim Comando As SqlCommand ' Establecemos la Conexión con la base de datos Comando = New SqlCommand(strSQL, MiConexion) ' Abrimos la Conexión MiConexion.Open() ' Ejecutamos la sentencia SQL MiDataReader = Comando.ExecuteReader() ' Leemos el primer registro y así nos posicionamos ' a partir del segundo de ellos MiDataReader.Read() ' Cargamos los resultados en el objeto DataTable MiDataTable.Load(MiDataReader, LoadOption.OverwriteChanges) ' Volcamos los datos en el control DataGridView DataGridView1.DataSource = MiDataTable ' Cerramos la Conexión Comando = Nothing MiConexion.Close() End Sub End Class En est e caso, lo que ocur r e com o y a hem os com ent ado, es que los dat os que se car gan son los que aún no han sido leídos en el obj et o Dat aReader , por lo que se m ost r ar án t odos los dat os desde el últ im o leído hast a llegar al final del obj et o. Módulo 5 - Capítulo 2 6. Usando los componentes de acceso a datos de .NET Los com ponent es del ent or no . NET nos pr opor cionan las car act er íst icas necesar ias par a poder acceder a fuent es de dat os de for m a r ápida y sencilla. El m ej or ej em plo de est o que com ent o es el que v er em os a cont inuación. D em ost r ación del uso de BindingSour ce y BindingN avigat or Par a ello, cr ear em os un pr oy ect o nuev o e inser t ar em os un cont r ol BindingSour ce y un cont r ol BindingNav igat or dent r o del for m ular io. Tam bién inser t ar em os un cont r ol Tex t Box al for m ular io, dónde pr esent ar em os la infor m ación sobr e la que nav egar em os. Nuest r o for m ular io con los cont r oles inser t ados en él, t endr á un aspect o sim ilar al que se pr esent a en la figur a 1. Cont role s de na v e ga ción y a cce so a da t os dispue st os e n e l form ula rio Figur a 1 Una v ez llegado a est e punt o, lo que t endr em os que hacer a cont inuación ser á escr ibir el código fuent e necesar io par a poder r epr esent ar los dat os de la sent encia SQL en el cont r ol BingindNav igat or , par a que a su v ez los pr esent e en el cont r ol Tex t Box . A cont inuación se indica el código fuent e de est a par t e de dem ost r ación de la apl cac ón. Imports System.Data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Declaramos las variables a utilizar Dim Conexion As String = "server=.;uid=sa;password=VisualBasic;database=MSDNVideo" Dim strSQL As String = "SELECT TITULO FROM ALQUILERES, PELICULAS WHERE PELICULACODBARRAS = CODBARRAS AND SOCIONIF = '111111'" Dim MiConexion As New SqlConnection(Conexion) Dim MiDataReader As SqlDataReader Dim MiDataTable As New DataTable Dim Comando As SqlCommand ' Establecemos la Conexión con la base de datos Comando = New SqlCommand(strSQL, MiConexion) ' Abrimos la Conexión MiConexion.Open() ' Ejecutamos la sentencia SQL MiDataReader = Comando.ExecuteReader() ' Cargamos los resultados en el objeto DataTable MiDataTable.Load(MiDataReader, LoadOption.OverwriteChanges) ' Volcamos los datos en el control TextBox BindingSource1.DataSource = MiDataTable BindingNavigator1.BindingSource = BindingSource1 TextBox1.DataBindings.Add(New Binding("Text", BindingSource1, "TITULO", True)) ' Cerramos la Conexión Comando = Nothing MiConexion.Close() End Sub End Class Ej e m plo a nt e rior e n e j e cución Figur a 1 Introducción Ya tenemos claro el funcionamiento con fuentes de datos conectadas, sin embargo, trabajar con datos conectados sólo es necesario en algunos ámbitos, lo más habitual, será que nos encontremos trabajando con ambientes y accesos a datos desconectados, como ocurrirá en la inmensa mayoría de la veces. A continuación, aprenderá a utilizar el Dat aSet y Dat aAdapt er para sacar el máximo provecho a un ambiente desconectado de datos. El índice detallado de este capítulo es el que se indica a continuación. Módulo 5 - Capítulo 3 ● 1. Esquema general de la estructura desconectada de acceso a datos ● 2. Conociendo el objeto DataAdapter ● 3. Insertando datos a través del objeto DataAdapter ● 4. Actualizando datos a través del objeto DataAdapter ● 5. Eliminando datos a través del objeto DataAdapter Módulo 5 - Capítulo 3 1. Esquema general de la estructura desconectada de acceso a datos En los capít ulos ant er ior es de est e m ódulo, hem os v ist o y a el uso de la clase Dat aSet . I ncluso lo hem os v ist o con algún ej em plo. La clase Dat aSet est á pensada y diseñada par a t r abaj ar con fuent es de dat os desconect adas. I ndudablem ent e, en est e punt o, debem os t ener clar a la est r uct ur a gener al de cóm o funciona el acceso desconect ado con fuent es de dat os. En la figur a 1, podem os obser v ar el diagr am a gener al de est a par t e Est ruct ura ge ne ra l de l uso de Da t a Se t e n e l a cce so de scone ct a do a da t os Figur a 1 Connect ion, D at aAdapt er y D at aSet Com o podem os obser v ar en la figur a 1, par a com unicar nos con una fuent e de dat os, siem pr e deber em os est ablecer una conex ión, independient em ent e de si la conex ión con la fuent e de dat os v a a per m anecer a lo lar go del t iem po o no. El obj et o Connect ion nos per m it e por lo t ant o, est ablecer la conex ión con la fuent e de dat os. El obj et o Dat aSet nos per m it e por ot r o lado, r ecoger los dat os de la fuent e de dat os y m andár selos a la aplicación. Ent r e m edias de est os dos obj et os, encont r am os el obj et o Dat aAdapt er que hace las funciones de puent e o nex o de unión ent r e la conex ión y el obj et o Dat aSet . Est o es lo que v er em os a cont inuación, com o funciona el obj et o Dat aAdapt er , y com o encaj a t odo est o en el acceso a fuent es de dat os desconect adas. Módulo 5 - Capítulo 3 2. Conociendo el objeto DataAdapter El obj et o Dat aAdapt er for m a par t e del pr ov eedor de acceso a dat os, t al y com o se m uest r a en la figur a 1. Visión ge ne ra l de la s cla se s de ADO.NET Figur a 1 Cada pr ov eedor de acceso a dat os posee su pr opio obj et o Dat aAdapt er . Cuando r ealizam os alguna m odificación o acción sobr e la fuent e de dat os, ut ilizar em os siem pr e el obj et o Dat aAdapt er a caballo ent r e el obj et o Dat aSet y la fuent e de dat os est ablecida a t r av és de la conex ión con el obj et o Connect ion. Con el obj et o Dat aAdapt er , podr em os adem ás r ealizar difer ent es acciones sobr e nuest r as bases de dat os, acciones com o la ej ecución gener al de sent encias de SQL no sólo par a seleccionar un conj unt o de dat os, sino par a alt er ar el cont enido de una base de dat os o de sus t ablas. Connect ion, D at aAdapt er y D at aSet Ant es de ent r ar en m at er ia m ás pr ofundam ent e, dir em os que en lo que r espect a a los pr ov eedor es de acceso a dat os que v ienen int egr ados con . NET, encont r am os dos for m as de usar un Dat aAdapt er . La pr im er a de ellas es ut ilizando los com ponent es del pr ov eedor de acceso a dat os. La segunda de ellas es ut ilizando las clases del nom br e de espacio del pr ov eedor de acceso a dat os. La m ej or for m a de ent ender t odo est o que com ent am os, es t r abaj ando con un ej em plo pr áct ico que nos enseñe a usar el obj et o Dat aAdapt er en Visual St udio 2010. Ut iliz ando las clases de .N ET En est e pr im er ej em plo de dem ost r ación del uso de Dat aAdapt er a t r av és de código usando par a ello las clases de . NET, est ablecer em os una conex ión con SQL Ser v er y m ost r ar em os los dat os r ecogidos en un cont r ol Tex t Box . I niciar em os Visual St udio 2010 y seleccionar em os un pr oy ect o de for m ular io de Window s. Dent r o del for m ular io, inser t ar em os un cont r ol Tex t Box y añadir em os dos r efer encias al pr oy ect o. Las r efer encias añadidas ser án a las libr er ías Sy st em . Dat a y Sy st em . XML, com o se m uest r a en la figur a 2. Re fe re ncia s a la s cla se s de a cce so a da t os de .NET Figur a 2 Una v ez que hem os añadido las r efer encias necesar ias par a ut ilizar las clases que quer em os en nuest r o pr oy ect o, ir em os al código y escr ibir em os las siguient es inst r ucciones: Imports System.Data Imports System.Data.SqlClient Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Establecemos la cadena de conexión con la BBDD Dim Conexion As String = "server=.;uid=sa;password=VisualBasic;database=MSDNVideo" ' Declaramos el DataSet dónde volcaremos los datos Dim MiDataSet As New DataSet() ' Declaramos el DataAdapter estableciendo ' la conexión con la fuente de datos Dim Comando As New SqlDataAdapter("SELECT SocioNIF, FechaAlquiler FROM ALQUILERES", Conexion) ' Rellenamos el DataSet con el contenido de la instrucción SQL Comando.Fill(MiDataSet) ' Cerramos la conexión con la BBDD Comando = Nothing ' Declaramos la propiedad Row para recorrer ' las filas contenidas en el DataSet Dim Row As DataRow ' Recorremos todas las filas y las tratamos For Each Row In MiDataSet.Tables(0).Rows TextBox1.Text += Row("Socio").ToString() & vbTab & Row("FechaAlquiler").ToString() & vbCrLf Next ' Vaciamos el DataSet para liberar memoria MiDataSet = Nothing End Sub End Class El ej em plo en ej ecución del uso de Dat aAdapt er j unt o con las clases de . NET es el que se m uest r a en la figur a 3. Ej e m plo de l a cce so a da t os con Da t a Ada pt e r a t ra v é s de la s cla se s de .NET Figur a 3 Ut iliz ando los com ponent es de .N ET Sin em bar go y com o y a hem os com ent ado, ex ist e ot r o m ét odo de acceso a fuent es de dat os difer ent e a las clases de . NET, el acceso a t r av és de com ponent es que nos facilit en esa t ar ea. Sin em bar go, los com ponent es de acceso a dat os, ut ilizan por det r ás las clases de . NET que hem os v ist o, lo que ocur r e, es que sim plifica enor m em ent e el t r abaj o y ahor r a t iem po a la hor a de desar r ollar aplicaciones. De t odos los m odos, t odo depende de la ut ilidad o necesidades con las que nos encont r em os en un m om ent o dado. I niciar em os un pr oy ect o Window s nuev am ent e, e inser t ar em os en él un cont r ol Tex t Box com o hicim os en el caso ant er ior . A cont inuación, añadir em os los com ponent es de acceso a fuent es de dat os SQL Ser v er que es la fuent e de dat os or igen. Com o hem os v ist o, par a conect ar a fuent es de dat os SQL Ser v er , hem os ut ilizado el nom br e de espacio Sy st em . Dat a y hem os im por t ado en el pr oy ect o los nom br es de espacio Sy st em . Dat a y Sy st em . Dat a. SqlClient . Los com ponent es . NET de acceso a fuent es de dat os de SQL Ser v er , se ident ifican por el nom br e Sqlx x x , siendo x x x el t ipo de com ponent e a ut ilizar . Par a poder ut ilizar los, deber em os añadir lo a la bar r a de her r am ient as. Par a añadir los com ponent es a nuest r o pr oy ect o, har em os soble clic sobr e el for m ular io y post er ior m ent e har em os clic con el bot ón secundar io del m ouse sobr e la bar r a de her r am ient as y seleccionar em os la opción Elegir elem ent os. . . com o se m uest r a en la figur a 4. Opción de la ba rra de he rra m ie nt a s pa ra a ña dir com pone nt e s a l e nt orno Figur a 4 Una v ez que hem os hecho est o, seleccionar em os los com ponent es SqlCom m and, SqlCom m andBuilder , SqlConnect ion, SqlDat aAdapt er y SqlDat aSour ce, t al y com o se m uest r a en la figur a 5. Com pone nt e s a a ña dir a l e nt orno Figur a 5 Una v ez que hem os añadido los com ponent es al ent or no, est os quedar án dispuest os dent r o de la bar r a de her r am ient as com o se indica en la figur a 6. Com pone nt e s a ña didos e n la ba rra de he rra m ie nt a s Figur a 6 Lo pr im er o que har em os ser á inser t ar un com ponent e SqlConnect ion dent r o del for m ular io. Acudir em os a la v ent ana de pr opiedades del com ponent e y m odificar em os la pr opiedad Con n e ct ion St r in g dent r o de la cuál escr ibir em os la inst r ucción: ser v er = . ; uid= sa; passw or d= VisualBasic; dat abase= MSDNVideo ent endiendo que ést a, es la cadena de conex ión v álida con nuest r a base de dat os. A cont inuación añadir em os el com ponent e SqlDat aAdapt er a nuest r o for m ular io. Si se abr e alguna v ent ana, ciér r ela. Vam os a configur ar el cont r ol con la v ent ana Pr opiedades. Podr íam os haber lo hecho desde el asist ent e que se nos ha abier t o, per o lo v am os a hacer de ot r a for m a m enos sencilla. Sit úese sobr e la pr opiedad Select Com m and, y dent r o de ést a, en la pr opiedad Connect ion. Lo que v am os a hacer , es asignar al com ponent e SqlDat aAdapt er el com ponent e de conex ión que v am os a usar par a est ablecer la com unicación ent r e la fuent e de dat os y nuest r a aplicación. Despliegue la pr opiedad Connect ion indicada, y seleccione el com ponent e de conex ión SqlConnect ion1 ant er ior m ent e configur ado, t al y com o se m uest r a en la figur a 7. Com pone nt e SqlDa t a Ada pt e r con la cone x ión e st a ble cida pa ra se r usa da e n la e j e cución de nue st ra a plica ción Figur a 7 Por últ im o, inser t e un com ponent e Dat aSet al for m ular io. Todos los com ponent es quedar án por lo t ant o inser t ados, t al y com o se indica en la figur a 8. Com pone nt e s a ña didos e n e l form ula rio de nue st ra a plica ción Figur a 8 Una v ez que t enem os t odo pr epar ado, t an sólo nos queda escr ibir la par t e de código fuent e necesar io par a poder r ealizar t odas las oper aciones y acciones que necesit am os. A cont inuación, se ex pone el código fuent e de nuest r a aplicación de dem ost r ación: Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Establecemos la cadena SQL a utilizar SqlDataAdapter1.SelectCommand.CommandText = "SELECT SocioNIF, FechaAlquiler FROM ALQUILERES" ' Abrimos la Conexión SqlConnection1.Open() ' Rellenamos el DataSet con el contenido de la instrucción SQL SqlDataAdapter1.Fill(DataSet1) ' Cerramos la Conexión SqlConnection1.Close() ' Declaramos la propiedad Row para recorrer ' las filas contenidas en el DataSet Dim Row As DataRow ' Recorremos todas las filas y las tratamos For Each Row In DataSet1.Tables(0).Rows TextBox1.Text += Row("SocioNIF").ToString() & vbTab & Row("FechaAlquiler").ToString() & vbCrLf Next End Sub End Class Ahor a nos queda únicam ent e ej ecut ar nuest r a aplicación par a est udiar el r esult ado final. Est e es el que se puede v er en la figur a 9. Ej e m plo e n e j e cución de l uso de com pone nt e s Figur a 9 Pese a t odo lo que hem os v ist o, quizás se pr egunt e com o es que en el caso del pr im er ej em plo que hem os v ist o y en el que hem os declar ado el uso de un Dat aAdapt er sin usar com ponent es, hem os t enido la obligat or iedad de añadir las r efer encias a los nom br es de espacio Sy st em . Dat a y Sy st em . Xm l, m ient r as que en est e segundo ej em plo, no hem os hecho r efer encia a ellos. En r ealidad nosot r os no hem os hecho r efer encia a ellos, per o al inser t ar los com ponent es dent r o del for m ular io, el ent or no Visual St udio 2010 se ha encar gado por nosot r os de añadir esas r efer encias al pr oy ect o, t al y com o puede v er se en la figur a 10. Re fe re ncia s a ña dida s a ut om á t ica m e nt e a l t ra ba j a r con com pone nt e s de a cce so a da t os Figur a 10 Módulo 5 - Capítulo 3 3. Insertando datos a través del objeto DataAdapter Hast a ahor a, t odos los ej em plos que hem os v ist o del obj et o Dat aAdapt er , han sido ej em plos del uso de selección de dat os, per o aún no hem os v ist o com o debem os t r abaj ar cuando r ealicem os ot r as acciones sobr e la fuent e de dat os. A cont inuación, v er em os com o r ealizar acciones de act ualización de dat os, ut ilizando par a ello el obj et o Dat aAdapt er . Recue r de: El Dat aSet per m an ece desconect ado de la fu en t e de dat os y si r ealizam os u na m odificación o alt er ación de los dat os de u n Dat aSet , est os no son pr opagados a la fu en t e de dat os. Par a ello, el Dat aAdapt er debe r ecibir la or den qu e qu er am os ej ecut ar . ¿Cóm o se inse r t a n da t os con el obj e t o D at aAda pt er Suponiendo que hem os r ecogido un conj unt o de dat os y que t r abaj ando con el obj et o Dat aSet hem os r ealizado una inser ción de dat os y que a cont inuación, quer em os pr opagar dicha inser ción a la base de dat os, deber em os hacer uso del m ét odo I nser t del obj et o Dat aAdapt er . El obj et o Dat aAdapt er se encar gar á de llam ar al com ando apr opiado par a cada una de las filas que han sido m odificadas en un det er m inado Dat aSet . Est o lo r ealizar á siem pr e a t r av és del m ét odo Updat e. Tr aba j ando con un ej em plo La m ej or m aner a de v er est o es con un ej em plo que nos ay ude a ent ender m ej or com o funciona la inser ción de dat os a t r av és del obj et o Dat aAdapt er . Tenga en cuent a adem ás, que la act ualización y el bor r ado de dat os funciona de la m ism a m aner a. I niciar em os un nuev o pr oy ect o de for m ular io Window s y en él inser t am os los com ponent es SqlConnect ion, SqlDat aAdapt er , Dat aSet y SqlCom m and. Par a el com ponent e SqlConnect ion, est ablecer em os la pr opiedad Connect ionSt r ing con el v alor : ser v er = . ; uid= sa; passw or d= VisualBasic; dat abase= MSDNVideo A cont inuación seleccionar em os el com ponent e SqlDat aAdapt er y m odificar em os la pr opiedad Se le ct Com m a n d > Con n e ct ion com o v im os en el capít ulo ant er ior . De la list a de posibles conex iones que le apar ezca, seleccione la conex ión SqlConnect ion1. Finalm ent e, inser t e un cont r ol But t on y un cont r ol Dat aGr idView en el for m ular io. Ést e quedar á com o se indica en la figur a 1. Form ula rio con los com pone nt e s y cont role s inse rt a dos e n é l Figur a 1 Finalm ent e, escr ibir em os el código necesar io par a ej ecut ar nuest r a aplicación t al y com o quer em os. Est e es el que se det alla a cont inuación: Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Establecemos la cadena SQL a utilizar SqlDataAdapter1.SelectCommand.CommandText = "SELECT NIF, Nombre, Apellido1, Apellido2, Telefono, Email, Direccion, Ciudad, Provincia, CP FROM SOCIOS" ' Abrimos la Conexión SqlConnection1.Open() ' Rellenamos el DataSet con el contenido de la instrucción SQL SqlDataAdapter1.Fill(DataSet1, "Ejemplo") ' Cerramos la Conexión SqlConnection1.Close() ' Asociamos el control DataGridView al DataSet DataGridView1.DataSource = DataSet1.Tables("Ejemplo") End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Declaramos un objeto DataRow para ' insertar en él los nuevos datos Dim MiDataRow As Data.DataRow ' Creamos una nueva fila en el DataSet MiDataRow = DataSet1.Tables("Ejemplo").NewRow() ' Insertamos los datos en el DataSet MiDataRow("NIF") = "222222" MiDataRow("Nombre") = "María" MiDataRow("Apellido1") = "Juárez" MiDataRow("Apellido2") = "Fernández" MiDataRow("Telefono") = "1112233" MiDataRow("Email") = "marí[email protected]" MiDataRow("Direccion") = "C\ Fernández de los Ríos, 77" MiDataRow("Ciudad") = "Valladolid" MiDataRow("Provincia") = "Valladolid" MiDataRow("CP") = "11111" DataSet1.Tables("Ejemplo").Rows.Add(MiDataRow) ' Si el DataSet tiene cambios ? If DataSet1.HasChanges Then ' Indicamos la instrucción SQL correspondiente SqlCommand1.CommandText = "INSERT INTO SOCIOS(NIF, Nombre, Apellido1, Apellido2, Telefono, Email, Direccion, Ciudad, Provincia, CP) VALUES(@NIF, @Nom ' Establecemos para el comando, ' la (conexión) que utilizaremos SqlCommand1.Connection = SqlConnection1 ' Le indicamos al DataAdapter, cuál es el ' comando de inserción que usaremos SqlDataAdapter1.InsertCommand = SqlCommand1 ' Añadimos los parámetros y comandos correspondientes ' para cada campo a añadir en la base de datos SqlCommand1.Parameters.Add("@NIF", Data.SqlDbType.NChar, 10, "NIF") SqlCommand1.Parameters.Add("@Nombre", Data.SqlDbType.NVarChar, 50, "Nombre") SqlCommand1.Parameters.Add("@Apellido1", Data.SqlDbType.NVarChar, 50, "Apellido1") SqlCommand1.Parameters.Add("@Apellido2", Data.SqlDbType.NVarChar, 50, "Apellido2") SqlCommand1.Parameters.Add("@Telefono", Data.SqlDbType.NVarChar, 13, "Telefono") SqlCommand1.Parameters.Add("@Email", Data.SqlDbType.NVarChar, 50, "Email") SqlCommand1.Parameters.Add("@Direccion", Data.SqlDbType.NVarChar, 100, "Direccion") SqlCommand1.Parameters.Add("@Ciudad", Data.SqlDbType.NVarChar, 50, "Ciudad") SqlCommand1.Parameters.Add("@Provincia", Data.SqlDbType.NVarChar, 50, "Provincia") SqlCommand1.Parameters.Add("@CP", Data.SqlDbType.NChar, 5, "CP") ' Abrimos la conexión SqlConnection1.Open() ' Realizamos la inserción de datos desde el DataSet ' a través del DataAdapter SqlDataAdapter1.Update(DataSet1, "Ejemplo") ' Cerramos la conexión SqlConnection1.Close() ' Indicamos con un mensaje que la inserción ' de datos se ha realizado con éxito MessageBox.Show("Datos insertados correctamente") End If End Sub End Class Por últ im o, ej ecut e la aplicación. Si t odo ha ido cor r ect am ent e, los dat os habr án quedado cor r ect am ent e inser t ados en la base de dat os. Un ej em plo de nuest r a aplicación en ej ecución es la que puede v er se en la figur a 2. Aplica ción e n e j e cución Figur a 2 Aplica ción de e j e m plo de inse rción de da t os con Da t a Ada pt e r y Da t a Se t e n e j e cución Figur a 2 Com o v em os, el uso de Dat aAdapt er en el caso de m anipular dat os, v ar ía liger am ent e. Sin em bar go, no es m ucho m ás com plicado con la act ualización y bor r ado de dat os. De hecho, la for m a de act uar es la m ism a com o v er em os a cont inuación. Módulo 5 - Capítulo 3 4. Actualizando datos a través del objeto DataAdapter De la m ism a m aner a que hem os inser t ado dat os en nuest r a base de dat os, debem os hacer a la hor a de act ualizar los m ism os. Sobr e la base del ej em plo ant er ior ( com ponent es y cont r oles) , escr iba o m odifique el siguient e código: Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ' Establecemos la cadena SQL a utilizar SqlDataAdapter1.SelectCommand.CommandText = "SELECT NIF, Nombre, Apellido1, Apellido2, ' Abrimos la Conexión SqlConnection1.Open() ' Rellenamos el DataSet con el contenido de la instrucción SQL SqlDataAdapter1.Fill(DataSet1, "Ejemplo") ' Cerramos la Conexión SqlConnection1.Close() ' Asociamos el control DataGridView al DataSet DataGridView1.DataSource = DataSet1.Tables("Ejemplo") End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Hand ' En nuestro ejemplo, sabemos que queremos modificar ' la fila 2, columna 4 (todos los elementos empiezan por 0) DataSet1.Tables("Ejemplo").Rows(1)(4) = "1112234" ' Si el DataSet tiene cambios ? If DataSet1.HasChanges Then ' Indicamos la instrucción SQL correspondiente SqlCommand1.CommandText = "UPDATE SOCIOS SET Telefono=@Telefono WHERE NIF=@NIF" ' Establecemos para el comando, ' la (conexión) que utilizaremos SqlCommand1.Connection = SqlConnection1 ' Le indicamos al DataAdapter, cuál es el ' comando de actualización que usaremos SqlDataAdapter1.UpdateCommand = SqlCommand1 ' Añadimos los parámetros y comandos correspondientes ' para cada campo a actualizar en la base de datos SqlCommand1.Parameters.Add("@NIF", Data.SqlDbType.NChar, 10, "NIF") SqlCommand1.Parameters.Add("@Nombre", Data.SqlDbType.NVarChar, 50, "Nombre") SqlCommand1.Parameters.Add("@Apellido1", Data.SqlDbType.NVarChar, 50, "Apellido1") SqlCommand1.Parameters.Add("@Apellido2", Data.SqlDbType.NVarChar, 50, "Apellido2") SqlCommand1.Parameters.Add("@Telefono", Data.SqlDbType.NVarChar, 13, "Telefono") SqlCommand1.Parameters.Add("@Email", Data.SqlDbType.NVarChar, 50, "Email") SqlCommand1.Parameters.Add("@Direccion", Data.SqlDbType.NVarChar, 100, "Direccion") SqlCommand1.Parameters.Add("@Ciudad", Data.SqlDbType.NVarChar, 50, "Ciudad") SqlCommand1.Parameters.Add("@Provincia", Data.SqlDbType.NVarChar, 50, "Provincia") SqlCommand1.Parameters.Add("@CP", Data.SqlDbType.NChar, 5, "CP") ' Abrimos la conexión SqlConnection1.Open() ' Realizamos la actualización de datos desde ' el DataSet a través del DataAdapter SqlDataAdapter1.Update(DataSet1, "Ejemplo") ' Cerramos la conexión SqlConnection1.Close() ' Indicamos con un mensaje que la actualización ' de datos se ha realizado con éxito MessageBox.Show("Datos actualizados correctamente") End If End Sub End Class Nuest r o ej em plo en ej ecución es el que se puede v er en la figur a 1. Aplica ción de e j e m plo de a ct ua liza ción de da t os con Da t a Ada pt e r y Da t a Se t Figur a 1 Módulo 5 - Capítulo 3 5. Eliminando datos a través del objeto DataAdapter De igual for m a sucede con la elim inación de dat os ut ilizando par a ello el obj et o Dat aAdapt er j unt o al obj et o Dat aSet . Ut ilizar em os nuev am ent e en est e caso, la base del ej em plo ant er ior ( com ponent es y cont r oles) , y escr ibir em os el siguient e código: Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ' Establecemos la cadena SQL a utilizar SqlDataAdapter1.SelectCommand.CommandText = "SELECT NIF, Nombre, Apellido1, Apellido2, ' Abrimos la Conexión SqlConnection1.Open() ' Rellenamos el DataSet con el contenido de la instrucción SQL SqlDataAdapter1.Fill(DataSet1, "Ejemplo") ' Cerramos la Conexión SqlConnection1.Close() ' Asociamos el control DataGridView al DataSet DataGridView1.DataSource = DataSet1.Tables("Ejemplo") End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Hand ' En nuestro ejemplo, sabemos que queremos eliminar ' la fila 2 (todos los elementos empiezan por 0) ' por lo que la fila 2 es aquí la 1 DataSet1.Tables("Ejemplo").Rows(1).Delete() ' Si el DataSet tiene cambios ? If DataSet1.HasChanges Then ' Indicamos la instrucción SQL correspondiente SqlCommand1.CommandText = "DELETE SOCIOS WHERE NIF=@NIF" ' Establecemos para el comando, ' la (conexión) que utilizaremos SqlCommand1.Connection = SqlConnection1 ' Le indicamos al DataAdapter, cuál es el ' comando de eliminación que usaremos SqlDataAdapter1.DeleteCommand = SqlCommand1 ' Añadimos los parámetros y comandos correspondientes ' para cada campo a actualizar en la base de datos SqlCommand1.Parameters.Add("@NIF", Data.SqlDbType.NChar, 10, "NIF") SqlCommand1.Parameters.Add("@Nombre", Data.SqlDbType.NVarChar, 50, "Nombre") SqlCommand1.Parameters.Add("@Apellido1", Data.SqlDbType.NVarChar, 50, "Apellido1") SqlCommand1.Parameters.Add("@Apellido2", Data.SqlDbType.NVarChar, 50, "Apellido2") SqlCommand1.Parameters.Add("@Telefono", Data.SqlDbType.NVarChar, 13, "Telefono") SqlCommand1.Parameters.Add("@Email", Data.SqlDbType.NVarChar, 50, "Email") SqlCommand1.Parameters.Add("@Direccion", Data.SqlDbType.NVarChar, 100, "Direccion") SqlCommand1.Parameters.Add("@Ciudad", Data.SqlDbType.NVarChar, 50, "Ciudad") SqlCommand1.Parameters.Add("@Provincia", Data.SqlDbType.NVarChar, 50, "Provincia") SqlCommand1.Parameters.Add("@CP", Data.SqlDbType.NChar, 5, "CP") ' Abrimos la conexión SqlConnection1.Open() ' Realizamos la eliminación de datos desde ' el DataSet a través del DataAdapter SqlDataAdapter1.Update(DataSet1, "Ejemplo") ' Cerramos la conexión SqlConnection1.Close() ' Indicamos con un mensaje que la eliminación ' de datos se ha realizado con éxito MessageBox.Show("Datos eliminados correctamente") End If End Sub End Class Nuest r o ej em plo en ej ecución es el que se puede v er en la figur a 1. Aplica ción de e j e m plo de e lim ina ción de da t os con Da t a Ada pt e r y Da t a Se t Figur a 1 Introducción Otra particularidad de .NET a la hora de trabajar con fuentes de datos y con los componentes y controles que nos permiten acceder a ellas, es el trabajo con dos tipos de Dat aSet s. Sin quererlo ya hemos visto como trabajar con uno de ellos, me refiero a los Dat aSet s no t ipados, sin embargo, hay otro tipo de Dat aSet diferente denominado así, Dat aSet tipado. En qué consiste un Dat aSet tipado y como utilizarlos, es lo que vamos a ver a continuación. Módulo 5 - Capítulo 4 ● 1. ¿Qué son los DataSets tipados? ● 2. Generando nuestros DataSets tipados ● 3. Generando un DataSet tipado con Visual Studio ● 4. Generando un DataSet tipado con la línea de comandos ● 5. Usando los DataSets tipados Módulo 5 - Capítulo 4 1. ¿Qué son los DataSets tipados? De for m a genér ica, podem os definir com o Dat aSet t ipado, a aquel Dat aSet que posee un esquem a de dat os, a difer encia del Dat aSet no t ipado, que no necesit a de ese esquem a. Respect o a los Dat aSet t ipados, dir em os que en el ent or no de desar r ollo, encont r am os m uchas ut ilidades y her r am ient as que nos facilit an el t r abaj o de est e t ipo de Dat aSet s. I nclusiv e, el pr opio SDK posee her r am ient as de com andos que nos per m it e y nos facilit a la pr epar ación par a t r abaj ar con Dat aSet s t ipados. El esquem a al que un Dat aSet t ipado hace r efer encia, es un docum ent o XML. Se t r at a de un docum ent o XML con ex t ensión . x sd. Tr abaj ar con un esquem a en lugar de t r abaj ar con una t abla dir ect am ent e, es m ucho m ás ágil, fácil, r ápido y segur o, com o v er em os m ás adelant e. Cóm o t r abaj ar con un D at aSet t ipado Ev ident em ent e, lo que t enem os que t ener clar o y t om ar lo así, com o punt o de par t ida, es que si quer em os t r abaj ar con un Dat aSet t ipado, t enem os que cr ear su cor r espondient e esquem a XML. Est o lo podem os hacer con una her r am ient a ex t er na, m anualm ent e, o con las her r am ient as que el ent or no de desar r ollo de Visual St udio 2010 o el pr opio SDK nos ofr ece. En nuest r o caso, ser á est as últ im as acciones lo que usar em os. Obv iam ent e, hacer lo m anualm ent e es en m i opinión par a fr ik is, m áx im e cuando sabem os que t enem os her r am ient as que nos facilit an su cr eación y nos ahor r an m ucho t iem po y r ecur sos. Cuando t engam os y a cr eado el esquem a XML, deber íam os gener ar la clase del Dat aSet , algo que a est as alt ur as, y a lo t enem os dom inado. En uno de los m ét odos de cr eación del esquem a, el ent or no hace ese t r abaj o por nosot r os, en el ot r o, que es un pr oceso m ás m anual com o v er em os, deber íam os cr ear esa clase con post er ior idad, per o aún así, est o últ im o no lo v er em os con ex cesiv a pr ofundidad. ¿Qué vent aj as nos apor t an los D at aSet s t ipados? Ya hem os enum er ado algunas de ellas, r apidez, segur idad, agilidad, facilidad de t r abaj o, t odo ello aplicable a los dat os. Aún así, ex ist en m uchas m ás r azones par a int er esar nos por los Dat aSet s t ipados. A t r av és de los Dat aSet s t ipados, podem os r ealizar acciones que com únm ent e son cost osas, de m aner a r ápida y sencilla. Acciones com o act ualización de dat os, m odificación, inser ción o elim inación de dat os, o búsquedas de dat os, son algunas de las acciones que en apenas un par de líneas de código, est ar án r esuelt as gr acias al uso de Dat aSet t ipados. Est o lo v er em os m ás adelant e con los ej em plos de est e capít ulo. Ot r as acciones adicionales v inculadas con los Dat aSet s t ipados son la posibilidad de filt r ar dat os, or denar los dat os, y t r abaj ar con dat os j er ár quicos y r elaciones de dat os. Una difer encia not able ent r e los Dat aSet s no t ipados y los Dat aSet s t ipados, es que los pr im er os no saben ni t ienen conocim ient o alguno de lo que alm acenan. Los segundos t ienen cier t a dosis de int eligencia y conocen el t ipo de dat os que alm acena dent r o. Adem ás de t odo est o, el acceso a los dat os que guar da un Dat aSet t ipado, así com o la m anipulación de los m ism os, es m ucho m ás sim ple y r equier e m enos código, haciendo que el acceso a los dat os y el m ant enim ient o de la aplicación sea m ás cóm oda y sencilla. Módulo 5 - Capítulo 4 2. Generando nuestros DataSets tipados Dent r o de Visual St udio 2010 y de . NET en gener al, t enem os v ar ias for m as de gener ar nuest r os pr opios Dat aSet s t ipados. Una de las for m as de gener ar Dat aSet s t ipados es ut ilizando el ent or no de desar r ollo r ápido Visual St udio 2010. La ot r a es ut ilizando la her r am ient a X SD . e x e que encont r ar em os en el dir ect or io SDK del ent or no. Am bas for m as, las v er em os a cont inuación. D iagr am a de dat os Ant es de cont inuar , r epasar em os el diagr am a de dat os con el cuál v am os a t r abaj ar . Est e es el que se m uest r a en la figur a 1. Dia gra m a de da t os con e l que v a m os a t ra ba j a r Figur a 1 Est e diagr am a nos ay udar á a int er pr et ar los dat os y a t r abaj ar con ellos, en los ej em plos que v er em os a cont inuación. A cont inuación, v er em os com o gener ar Dat aSet s t ipados desde el ent or no de t r abaj o r ápido, es decir Visual St udio 2010, y desde la línea de com andos. Módulo 5 - Capítulo 4 3. Generando un DataSet tipado con Visual Studio 2010 La for m a m ás r ápida par a gener ar Dat aSet s t ipados es ut ilizando las her r am ient as aut om át icas del ent or no Visual St udio 2010. A cont inuación v er em os com o hacer est o de m aner a r ápida y sencilla. Usando el ent or no de desar r ollo r ápido Visual St udio 2 0 1 0 Cr ee un nuev o pr oy ect o de Aplicación par a Window s y haga clic con el bot ón secundar io del m ouse sobr e la v ent ana Ex plor ador de soluciones, y del m enú em er gent e, seleccione la opción Ag r e g a r > N u e v o e le m e n t o. . . , t al y com o se m uest r a en la figur a 1. Me nú pa ra a gre ga r un e le m e nt o a l proy e ct o Figur a 1 Apar ecer á ent onces una v ent ana de Agr egar nuev o elem ent o, dent r o de la cuál seleccionar em os la plant illa de Con j u n t o d e d a t os, t al y com o se m uest r a en la figur a 2. Ve nt a na pa ra a gre ga r un nue v o e le m e nt o a l proy e ct o Figur a 2 Haga clic en el bot ón Ag r e g a r . La plant illa del esquem a del Dat aSet , t endr á un aspect o sim ilar al que se m uest r a en la figur a 3. Esque m a por de fe ct o de l Da t a Se t e n Visua l St udio 2 0 1 0 Figur a 3 El siguient e paso que deber em os abor dar , ser á la de añadir al esquem a, las t ablas que quer em os que for m en par t e del Dat aSet t ipado. Par a hacer est o, abr a la v ent ana Ex p lor a d or d e b a se d e d a t os y seleccione la base de dat os de pr ueba. Pulse sobr e la t abla Socios y ar r ást r ela sobr e el esquem a del Dat aSet com o se indica en la figur a 4. Arra st ra m os la t a bla Socios sobre e l e sque m a de l Da t a Se t Figur a 4 El esquem a de la t abla quedar á ent onces añadido a la aplicación, t al y com o se indica en la figur a 5. Esque m a de la t a bla Socios a ña dido a l ent orno de t ra ba j o Figur a 5 En est e punt o, t endr em os list o nuest r o Dat aSet t ipado, per o aún no t endr em os una clase o código asociado al Dat aSet t ipado. Aún no lo hem os dicho, per o en est e punt o, Visual St udio 2010 ha gener ado par a nosot r os, el código r elacionado con el Dat aSet t ipado cr eado. Est e código, est á dent r o del dir ect or io de la aplicación, y puede ser accedido a él pr esionando el bot ón de la v ent ana Ex p lor a d or d e solu cion e s y r epr esent ado por el siguient e icono Est o es lo que se r epr esent a en la figur a 6. Opción de m ost ra r t odos los a rchiv os Figur a 6 En est e punt o, v er em os que los ar chiv os r elacionados con nuest r o pr oy ect o y en el caso del elem ent o Dat aSet 1 x sd, son los que se det allan en la figur a 7. Archiv os de l proy e ct o Figur a 7 Obser v am os que el ar chiv o Dat aSet 1 Designer cs depende del ar chiv o Dat aSet 1 x sd, y es el que cont iene el código necesar io par a ut ilizar el Dat aSet t ipado. De hecho, si v em os el código gener ado por Visual St udio 2010, obser v ar em os que coincide con el que se det alla a cont inuación: '-----------------------------------------------------------------------------' <auto-generated> ' Una herramienta generó este código. ' Versión del motor en tiempo de ejecución:2.0.50215.44 ' ' Los cambios en este archivo podrían causar un comportamiento incorrecto y se perderán si ' el código se vuelve a generar. ' </auto-generated> '-----------------------------------------------------------------------------Option Strict Off Option Explicit On Imports System <Serializable(), _ System.ComponentModel.DesignerCategoryAttribute("code"), _ System.ComponentModel.ToolboxItem(true), _ System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedDataSetSchema"), _ System.Xml.Serialization.XmlRootAttribute("DataSet1"), _ System.ComponentModel.Design.HelpKeywordAttribute("vs.data.DataSet"), _ System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Usage", "CA2240:ImplementISerializableCorre Partial Public Class DataSet1 Inherits System.Data.DataSet Private tableSocios As SociosDataTable Private _schemaSerializationMode As System.Data.SchemaSerializationMode = System.Data.SchemaSerializationMode <System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Usage", "CA2214:DoNotCallOverridableMeth Public Sub New() MyBase.New Me.BeginInit Me.InitClass Dim schemaChangedHandler As System.ComponentModel.CollectionChangeEventHandler = AddressOf Me.SchemaChange AddHandler MyBase.Tables.CollectionChanged, schemaChangedHandler AddHandler MyBase.Relations.CollectionChanged, schemaChangedHandler Me.EndInit End Sub <System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Usage", "CA2214:DoNotCallOverridableMeth Protected Sub New(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runti MyBase.New(info, context) If (Me.IsBinarySerialized(info, context) = true) Then Me.InitVars(false) Dim schemaChangedHandler1 As System.ComponentModel.CollectionChangeEventHandler = AddressOf Me.SchemaCh AddHandler Me.Tables.CollectionChanged, schemaChangedHandler1 AddHandler Me.Relations.CollectionChanged, schemaChangedHandler1 Return End If Dim strSchema As String = CType(info.GetValue("XmlSchema", GetType(String)),String) If (Me.DetermineSchemaSerializationMode(info, context) = System.Data.SchemaSerializationMode.IncludeSchema Dim ds As System.Data.DataSet = New System.Data.DataSet ds.ReadXmlSchema(New System.Xml.XmlTextReader(New System.IO.StringReader(strSchema))) If (Not (ds.Tables("Socios")) Is Nothing) Then MyBase.Tables.Add(New SociosDataTable(ds.Tables("Socios"))) End If Me.DataSetName = ds.DataSetName Me.Prefix = ds.Prefix Me.Namespace = ds.Namespace Me.Locale = ds.Locale Me.CaseSensitive = ds.CaseSensitive Me.EnforceConstraints = ds.EnforceConstraints Me.Merge(ds, false, System.Data.MissingSchemaAction.Add) Me.InitVars Else Me.ReadXmlSchema(New System.Xml.XmlTextReader(New System.IO.StringReader(strSchema))) End If Me.GetSerializationData(info, context) Dim schemaChangedHandler As System.ComponentModel.CollectionChangeEventHandler = AddressOf Me.SchemaChange AddHandler MyBase.Tables.CollectionChanged, schemaChangedHandler AddHandler Me.Relations.CollectionChanged, schemaChangedHandler End Sub <System.ComponentModel.Browsable(false), _ System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility. Public ReadOnly Property Socios() As SociosDataTable Get Return Me.tableSocios End Get End Property Public Overrides Property SchemaSerializationMode() As System.Data.SchemaSerializationMode Get Return Me._schemaSerializationMode End Get Set Me._schemaSerializationMode = value End Set End Property <System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVi Public Shadows ReadOnly Property Tables() As System.Data.DataTableCollection Get Return MyBase.Tables End Get End Property <System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVi Public Shadows ReadOnly Property Relations() As System.Data.DataRelationCollection Get Return MyBase.Relations End Get End Property <System.ComponentModel.DefaultValueAttribute(true)> _ Public Shadows Property EnforceConstraints() As Boolean Get Return MyBase.EnforceConstraints End Get Set MyBase.EnforceConstraints = value End Set End Property Protected Overrides Sub InitializeDerivedDataSet() Me.BeginInit Me.InitClass Me.EndInit End Sub Public Overrides Function Clone() As System.Data.DataSet Dim cln As DataSet1 = CType(MyBase.Clone,DataSet1) cln.InitVars Return cln End Function Protected Overrides Function ShouldSerializeTables() As Boolean Return false End Function Protected Overrides Function ShouldSerializeRelations() As Boolean Return false End Function Protected Overrides Sub ReadXmlSerializable(ByVal reader As System.Xml.XmlReader) If (Me.DetermineSchemaSerializationMode(reader) = System.Data.SchemaSerializationMode.IncludeSchema) Then Me.Reset Dim ds As System.Data.DataSet = New System.Data.DataSet ds.ReadXml(reader) If (Not (ds.Tables("Socios")) Is Nothing) Then MyBase.Tables.Add(New SociosDataTable(ds.Tables("Socios"))) End If Me.DataSetName = ds.DataSetName Me.Prefix = ds.Prefix Me.Namespace = ds.Namespace Me.Locale = ds.Locale Me.CaseSensitive = ds.CaseSensitive Me.EnforceConstraints = ds.EnforceConstraints Me.Merge(ds, false, System.Data.MissingSchemaAction.Add) Me.InitVars Else Me.ReadXml(reader) Me.InitVars End If End Sub Protected Overrides Function GetSchemaSerializable() As System.Xml.Schema.XmlSchema Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream Me.WriteXmlSchema(New System.Xml.XmlTextWriter(stream, Nothing)) stream.Position = 0 Return System.Xml.Schema.XmlSchema.Read(New System.Xml.XmlTextReader(stream), Nothing) End Function Friend Overloads Sub InitVars() Me.InitVars(true) End Sub Friend Overloads Sub InitVars(ByVal initTable As Boolean) Me.tableSocios = CType(MyBase.Tables("Socios"),SociosDataTable) If (initTable = true) Then If (Not (Me.tableSocios) Is Nothing) Then Me.tableSocios.InitVars End If End If End Sub Private Sub InitClass() Me.DataSetName = "DataSet1" Me.Prefix = "" Me.Namespace = "http:"//tempuri.org/DataSet1.xsd" Me.EnforceConstraints = true Me.tableSocios = New SociosDataTable MyBase.Tables.Add(Me.tableSocios) End Sub Private Function ShouldSerializeSocios() As Boolean Return false End Function Private Sub SchemaChanged(ByVal sender As Object, ByVal e As System.ComponentModel.CollectionChangeEventArgs) If (e.Action = System.ComponentModel.CollectionChangeAction.Remove) Then Me.InitVars End If End Sub Public Shared Function GetTypedDataSetSchema(ByVal xs As System.Xml.Schema.XmlSchemaSet) As System.Xml.Schema Dim ds As DataSet1 = New DataSet1 Dim type As System.Xml.Schema.XmlSchemaComplexType = New System.Xml.Schema.XmlSchemaComplexType Dim sequence As System.Xml.Schema.XmlSchemaSequence = New System.Xml.Schema.XmlSchemaSequence xs.Add(ds.GetSchemaSerializable) Dim any As System.Xml.Schema.XmlSchemaAny = New System.Xml.Schema.XmlSchemaAny any.Namespace = ds.Namespace sequence.Items.Add(any) type.Particle = sequence Return type End Function Public Delegate Sub SociosRowChangeEventHandler(ByVal sender As Object, ByVal e As SociosRowChangeEvent) <System.Serializable(), _ System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedTableSchema")> Partial Public Class SociosDataTable Inherits System.Data.DataTable Implements System.Collections.IEnumerable Private columnNIF As System.Data.DataColumn Private columnNombre As System.Data.DataColumn _ Private columnApellido1 As System.Data.DataColumn Private columnApellido2 As System.Data.DataColumn Private columnTelefono As System.Data.DataColumn Private columnEmail As System.Data.DataColumn Private columnDireccion As System.Data.DataColumn Private columnCiudad As System.Data.DataColumn Private columnProvincia As System.Data.DataColumn Private columnCP As System.Data.DataColumn Public Sub New() MyBase.New Me.TableName = "Socios" Me.BeginInit Me.InitClass Me.EndInit End Sub Friend Sub New(ByVal table As System.Data.DataTable) MyBase.New Me.TableName = table.TableName If (table.CaseSensitive <> table.DataSet.CaseSensitive) Then Me.CaseSensitive = table.CaseSensitive End If If (table.Locale.ToString <> table.DataSet.Locale.ToString) Then Me.Locale = table.Locale End If If (table.Namespace <> table.DataSet.Namespace) Then Me.Namespace = table.Namespace End If Me.Prefix = table.Prefix Me.MinimumCapacity = table.MinimumCapacity End Sub Protected Sub New(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Ru MyBase.New(info, context) Me.InitVars End Sub Public ReadOnly Property NIFColumn() As System.Data.DataColumn Get Return Me.columnNIF End Get End Property Public ReadOnly Property NombreColumn() As System.Data.DataColumn Get Return Me.columnNombre End Get End Property Public ReadOnly Property Apellido1Column() As System.Data.DataColumn Get Return Me.columnApellido1 End Get End Property Public ReadOnly Property Apellido2Column() As System.Data.DataColumn Get Return Me.columnApellido2 End Get End Property Public ReadOnly Property TelefonoColumn() As System.Data.DataColumn Get Return Me.columnTelefono End Get End Property Public ReadOnly Property EmailColumn() As System.Data.DataColumn Get Return Me.columnEmail End Get End Property Public ReadOnly Property DireccionColumn() As System.Data.DataColumn Get Return Me.columnDireccion End Get End Property Public ReadOnly Property CiudadColumn() As System.Data.DataColumn Get Return Me.columnCiudad End Get End Property Public ReadOnly Property ProvinciaColumn() As System.Data.DataColumn Get Return Me.columnProvincia End Get End Property Public ReadOnly Property CPColumn() As System.Data.DataColumn Get Return Me.columnCP End Get End Property <System.ComponentModel.Browsable(false)> _ Public ReadOnly Property Count() As Integer Get Return Me.Rows.Count End Get End Property Public Default ReadOnly Property Item(ByVal index As Integer) As SociosRow Get Return CType(Me.Rows(index),SociosRow) End Get End Property Public Event SociosRowChanged As SociosRowChangeEventHandler Public Event SociosRowChanging As SociosRowChangeEventHandler Public Event SociosRowDeleted As SociosRowChangeEventHandler Public Event SociosRowDeleting As SociosRowChangeEventHandler Public Overloads Sub AddSociosRow(ByVal row As SociosRow) Me.Rows.Add(row) End Sub Public Overloads Function AddSociosRow(ByVal NIF As String, ByVal Nombre As String, ByVal Apellido1 As Str Dim rowSociosRow As SociosRow = CType(Me.NewRow,SociosRow) rowSociosRow.ItemArray = New Object() {NIF, Nombre, Apellido1, Apellido2, Telefono, Email, Direccion, C Me.Rows.Add(rowSociosRow) Return rowSociosRow End Function Public Function FindByNIF(ByVal NIF As String) As SociosRow Return CType(Me.Rows.Find(New Object() {NIF}),SociosRow) End Function Public Overridable Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collection Return Me.Rows.GetEnumerator End Function Public Overrides Function Clone() As System.Data.DataTable Dim cln As SociosDataTable = CType(MyBase.Clone,SociosDataTable) cln.InitVars Return cln End Function Protected Overrides Function CreateInstance() As System.Data.DataTable Return New SociosDataTable End Function Friend Sub InitVars() Me.columnNIF = MyBase.Columns("NIF") Me.columnNombre = MyBase.Columns("Nombre") Me.columnApellido1 = MyBase.Columns("Apellido1") Me.columnApellido2 = MyBase.Columns("Apellido2") Me.columnTelefono = MyBase.Columns("Telefono") Me.columnEmail = MyBase.Columns("Email") Me.columnDireccion = MyBase.Columns("Direccion") Me.columnCiudad = MyBase.Columns("Ciudad") Me.columnProvincia = MyBase.Columns("Provincia") Me.columnCP = MyBase.Columns("CP") End Sub Private Sub InitClass() Me.columnNIF = New System.Data.DataColumn("NIF", GetType(String), Nothing, System.Data.MappingType.Elem MyBase.Columns.Add(Me.columnNIF) Me.columnNombre = New System.Data.DataColumn("Nombre", GetType(String), Nothing, System.Data.MappingTyp MyBase.Columns.Add(Me.columnNombre) Me.columnApellido1 = New System.Data.DataColumn("Apellido1", GetType(String), Nothing, System.Data.Mapp MyBase.Columns.Add(Me.columnApellido1) Me.columnApellido2 = New System.Data.DataColumn("Apellido2", GetType(String), Nothing, System.Data.Mapp MyBase.Columns.Add(Me.columnApellido2) Me.columnTelefono = New System.Data.DataColumn("Telefono", GetType(String), Nothing, System.Data.Mappin MyBase.Columns.Add(Me.columnTelefono) Me.columnEmail = New System.Data.DataColumn("Email", GetType(String), Nothing, System.Data.MappingType. MyBase.Columns.Add(Me.columnEmail) Me.columnDireccion = New System.Data.DataColumn("Direccion", GetType(String), Nothing, System.Data.Mapp MyBase.Columns.Add(Me.columnDireccion) Me.columnCiudad = New System.Data.DataColumn("Ciudad", GetType(String), Nothing, System.Data.MappingTyp MyBase.Columns.Add(Me.columnCiudad) Me.columnProvincia = New System.Data.DataColumn("Provincia", GetType(String), Nothing, System.Data.Mapp MyBase.Columns.Add(Me.columnProvincia) Me.columnCP = New System.Data.DataColumn("CP", GetType(String), Nothing, System.Data.MappingType.Elemen MyBase.Columns.Add(Me.columnCP) Me.Constraints.Add(New System.Data.UniqueConstraint("Constraint1", New System.Data.DataColumn() {Me.col Me.columnNIF.AllowDBNull = false Me.columnNIF.Unique = true Me.columnNIF.MaxLength = 10 Me.columnNombre.MaxLength = 50 Me.columnApellido1.MaxLength = 50 Me.columnApellido2.MaxLength = 50 Me.columnTelefono.MaxLength = 13 Me.columnEmail.MaxLength = 50 Me.columnDireccion.MaxLength = 100 Me.columnCiudad.MaxLength = 50 Me.columnProvincia.MaxLength = 50 Me.columnCP.MaxLength = 5 Me.Locale = New System.Globalization.CultureInfo("es-ES") End Sub Public Function NewSociosRow() As SociosRow Return CType(Me.NewRow,SociosRow) End Function Protected Overrides Function NewRowFromBuilder(ByVal builder As System.Data.DataRowBuilder) As System.Data Return New SociosRow(builder) End Function Protected Overrides Function GetRowType() As System.Type Return GetType(SociosRow) End Function Protected Overrides Sub OnRowChanged(ByVal e As System.Data.DataRowChangeEventArgs) MyBase.OnRowChanged(e) If (Not (Me.SociosRowChangedEvent) Is Nothing) Then RaiseEvent SociosRowChanged(Me, New SociosRowChangeEvent(CType(e.Row,SociosRow), e.Action)) End If End Sub Protected Overrides Sub OnRowChanging(ByVal e As System.Data.DataRowChangeEventArgs) MyBase.OnRowChanging(e) If (Not (Me.SociosRowChangingEvent) Is Nothing) Then RaiseEvent SociosRowChanging(Me, New SociosRowChangeEvent(CType(e.Row,SociosRow), e.Action)) End If End Sub Protected Overrides Sub OnRowDeleted(ByVal e As System.Data.DataRowChangeEventArgs) MyBase.OnRowDeleted(e) If (Not (Me.SociosRowDeletedEvent) Is Nothing) Then RaiseEvent SociosRowDeleted(Me, New SociosRowChangeEvent(CType(e.Row,SociosRow), e.Action)) End If End Sub Protected Overrides Sub OnRowDeleting(ByVal e As System.Data.DataRowChangeEventArgs) MyBase.OnRowDeleting(e) If (Not (Me.SociosRowDeletingEvent) Is Nothing) Then RaiseEvent SociosRowDeleting(Me, New SociosRowChangeEvent(CType(e.Row,SociosRow), e.Action)) End If End Sub Public Sub RemoveSociosRow(ByVal row As SociosRow) Me.Rows.Remove(row) End Sub Public Shared Function GetTypedTableSchema(ByVal xs As System.Xml.Schema.XmlSchemaSet) As System.Xml.Schem Dim type As System.Xml.Schema.XmlSchemaComplexType = New System.Xml.Schema.XmlSchemaComplexType Dim sequence As System.Xml.Schema.XmlSchemaSequence = New System.Xml.Schema.XmlSchemaSequence Dim ds As DataSet1 = New DataSet1 xs.Add(ds.GetSchemaSerializable) Dim any1 As System.Xml.Schema.XmlSchemaAny = New System.Xml.Schema.XmlSchemaAny any1.Namespace = "http:"//www.w3.org/2001/XMLSchema" any1.MinOccurs = New Decimal(0) any1.MaxOccurs = Decimal.MaxValue any1.ProcessContents = System.Xml.Schema.XmlSchemaContentProcessing.Lax sequence.Items.Add(any1) Dim any2 As System.Xml.Schema.XmlSchemaAny = New System.Xml.Schema.XmlSchemaAny any2.Namespace = "urn:schemas-microsoft-com:xml-diffgram-v1" any2.MinOccurs = New Decimal(1) any2.ProcessContents = System.Xml.Schema.XmlSchemaContentProcessing.Lax sequence.Items.Add(any2) Dim attribute1 As System.Xml.Schema.XmlSchemaAttribute = New System.Xml.Schema.XmlSchemaAttribute attribute1.Name = "namespace" attribute1.FixedValue = ds.Namespace type.Attributes.Add(attribute1) Dim attribute2 As System.Xml.Schema.XmlSchemaAttribute = New System.Xml.Schema.XmlSchemaAttribute attribute2.Name = "tableTypeName" attribute2.FixedValue = "SociosDataTable" type.Attributes.Add(attribute2) type.Particle = sequence Return type End Function End Class Partial Public Class SociosRow Inherits System.Data.DataRow Private tableSocios As SociosDataTable Friend Sub New(ByVal rb As System.Data.DataRowBuilder) MyBase.New(rb) Me.tableSocios = CType(Me.Table,SociosDataTable) End Sub Public Property NIF() As String Get Return CType(Me(Me.tableSocios.NIFColumn),String) End Get Set Me(Me.tableSocios.NIFColumn) = value End Set End Property Public Property Nombre() As String Get Try Return CType(Me(Me.tableSocios.NombreColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Nombre' de la tabla 'Socios' End Try End Get Set Me(Me.tableSocios.NombreColumn) = value End Set End Property Public Property Apellido1() As String Get Try Return CType(Me(Me.tableSocios.Apellido1Column),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Apellido1' de la tabla 'Soci End Try End Get Set Me(Me.tableSocios.Apellido1Column) = value End Set End Property Public Property Apellido2() As String Get Try Return CType(Me(Me.tableSocios.Apellido2Column),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Apellido2' de la tabla 'Soci End Try End Get Set Me(Me.tableSocios.Apellido2Column) = value End Set End Property Public Property Telefono() As String Get Try Return CType(Me(Me.tableSocios.TelefonoColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Telefono' de la tabla 'Socio End Try End Get Set Me(Me.tableSocios.TelefonoColumn) = value End Set End Property Public Property Email() As String Get Try Return CType(Me(Me.tableSocios.EmailColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Email' de la tabla 'Socios' End Try End Get Set Me(Me.tableSocios.EmailColumn) = value End Set End Property Public Property Direccion() As String Get Try Return CType(Me(Me.tableSocios.DireccionColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Direccion' de la tabla 'Soci End Try End Get Set Me(Me.tableSocios.DireccionColumn) = value End Set End Property Public Property Ciudad() As String Get Try Return CType(Me(Me.tableSocios.CiudadColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Ciudad' de la tabla 'Socios' End Try End Get Set Me(Me.tableSocios.CiudadColumn) = value End Set End Property Public Property Provincia() As String Get Try Return CType(Me(Me.tableSocios.ProvinciaColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Provincia' de la tabla 'Soci End Try End Get Set Me(Me.tableSocios.ProvinciaColumn) = value End Set End Property Public Property CP() As String Get Try Return CType(Me(Me.tableSocios.CPColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'CP' de la tabla 'Socios' es End Try End Get Set Me(Me.tableSocios.CPColumn) = value End Set End Property Public Function IsNombreNull() As Boolean Return Me.IsNull(Me.tableSocios.NombreColumn) End Function Public Sub SetNombreNull() Me(Me.tableSocios.NombreColumn) = System.Convert.DBNull End Sub Public Function IsApellido1Null() As Boolean Return Me.IsNull(Me.tableSocios.Apellido1Column) End Function Public Sub SetApellido1Null() Me(Me.tableSocios.Apellido1Column) = System.Convert.DBNull End Sub Public Function IsApellido2Null() As Boolean Return Me.IsNull(Me.tableSocios.Apellido2Column) End Function Public Sub SetApellido2Null() Me(Me.tableSocios.Apellido2Column) = System.Convert.DBNull End Sub Public Function IsTelefonoNull() As Boolean Return Me.IsNull(Me.tableSocios.TelefonoColumn) End Function Public Sub SetTelefonoNull() Me(Me.tableSocios.TelefonoColumn) = System.Convert.DBNull End Sub Public Function IsEmailNull() As Boolean Return Me.IsNull(Me.tableSocios.EmailColumn) End Function Public Sub SetEmailNull() Me(Me.tableSocios.EmailColumn) = System.Convert.DBNull End Sub Public Function IsDireccionNull() As Boolean Return Me.IsNull(Me.tableSocios.DireccionColumn) End Function Public Sub SetDireccionNull() Me(Me.tableSocios.DireccionColumn) = System.Convert.DBNull End Sub Public Function IsCiudadNull() As Boolean Return Me.IsNull(Me.tableSocios.CiudadColumn) End Function Public Sub SetCiudadNull() Me(Me.tableSocios.CiudadColumn) = System.Convert.DBNull End Sub Public Function IsProvinciaNull() As Boolean Return Me.IsNull(Me.tableSocios.ProvinciaColumn) End Function Public Sub SetProvinciaNull() Me(Me.tableSocios.ProvinciaColumn) = System.Convert.DBNull End Sub Public Function IsCPNull() As Boolean Return Me.IsNull(Me.tableSocios.CPColumn) End Function Public Sub SetCPNull() Me(Me.tableSocios.CPColumn) = System.Convert.DBNull End Sub End Class Public Class SociosRowChangeEvent Inherits System.EventArgs Private eventRow As SociosRow Private eventAction As System.Data.DataRowAction Public Sub New(ByVal row As SociosRow, ByVal action As System.Data.DataRowAction) MyBase.New Me.eventRow = row Me.eventAction = action End Sub Public ReadOnly Property Row() As SociosRow Get Return Me.eventRow End Get End Property Public ReadOnly Property Action() As System.Data.DataRowAction Get Return Me.eventAction End Get End Property End Class End Class Namespace DataSet1TableAdapters <System.ComponentModel.DesignerCategoryAttribute("code"), _ System.ComponentModel.ToolboxItem(true), _ System.ComponentModel.DataObjectAttribute(true), _ System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.DataSource.Design.TableAdapterDesigner, Micros ", Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), _ System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")> Partial Public Class SociosTableAdapter Inherits System.ComponentModel.Component _ Private WithEvents m_adapter As System.Data.SqlClient.SqlDataAdapter Private m_connection As System.Data.SqlClient.SqlConnection Private m_commandCollection() As System.Data.SqlClient.SqlCommand Private m_clearBeforeFill As Boolean Public Sub New() MyBase.New Me.m_clearBeforeFill = true End Sub Private ReadOnly Property Adapter() As System.Data.SqlClient.SqlDataAdapter Get If (Me.m_adapter Is Nothing) Then Me.InitAdapter End If Return Me.m_adapter End Get End Property Friend Property Connection() As System.Data.SqlClient.SqlConnection Get If (Me.m_connection Is Nothing) Then Me.InitConnection End If Return Me.m_connection End Get Set Me.m_connection = value If (Not (Me.Adapter.InsertCommand) Is Nothing) Then Me.Adapter.InsertCommand.Connection = value End If If (Not (Me.Adapter.DeleteCommand) Is Nothing) Then Me.Adapter.DeleteCommand.Connection = value End If If (Not (Me.Adapter.UpdateCommand) Is Nothing) Then Me.Adapter.UpdateCommand.Connection = value End If Dim i As Integer = 0 Do While (i < Me.CommandCollection.Length) If (Not (Me.CommandCollection(i)) Is Nothing) Then CType(Me.CommandCollection(i),System.Data.SqlClient.SqlCommand).Connection = value End If i = (i + 1) Loop End Set End Property Protected ReadOnly Property CommandCollection() As System.Data.SqlClient.SqlCommand() Get If (Me.m_commandCollection Is Nothing) Then Me.InitCommandCollection End If Return Me.m_commandCollection End Get End Property Public Property ClearBeforeFill() As Boolean Get Return Me.m_clearBeforeFill End Get Set Me.m_clearBeforeFill = value End Set End Property Private Sub InitAdapter() Me.m_adapter = New System.Data.SqlClient.SqlDataAdapter Dim tableMapping As System.Data.Common.DataTableMapping = New System.Data.Common.DataTableMapping tableMapping.SourceTable = "Table" tableMapping.DataSetTable = "Socios" tableMapping.ColumnMappings.Add("NIF", "NIF") tableMapping.ColumnMappings.Add("Nombre", "Nombre") tableMapping.ColumnMappings.Add("Apellido1", "Apellido1") tableMapping.ColumnMappings.Add("Apellido2", "Apellido2") tableMapping.ColumnMappings.Add("Telefono", "Telefono") tableMapping.ColumnMappings.Add("Email", "Email") tableMapping.ColumnMappings.Add("Direccion", "Direccion") tableMapping.ColumnMappings.Add("Ciudad", "Ciudad") tableMapping.ColumnMappings.Add("Provincia", "Provincia") tableMapping.ColumnMappings.Add("CP", "CP") Me.m_adapter.TableMappings.Add(tableMapping) Me.m_adapter.DeleteCommand = New System.Data.SqlClient.SqlCommand Me.m_adapter.DeleteCommand.Connection = Me.Connection Me.m_adapter.DeleteCommand.CommandText = "DELETE FROM [dbo].[Socios] WHERE (([NIF] = @Original_NIF) AND "1 AND [Nombre] IS NULL) OR ([Nombre] = @Original_Nombre)) AND ((@IsNull_Apellido"& _ "1 = 1 AND [Apellido1] IS NULL) OR ([Apellido1] = @Original_Apellido1)) AND ((@Is"& _ "Null_Apellido2 = 1 AND [Apellido2] IS NULL) OR ([Apellido2] = @Original_Apellido"& _ "2)) AND ((@IsNull_Telefono = 1 AND [Telefono] IS NULL) OR ([Telefono] = @Origina"& _ "l_Telefono)) AND ((@IsNull_Email = 1 AND [Email] IS NULL) OR ([Email] = @Origina"& _ "l_Email)) AND ((@IsNull_Direccion = 1 AND [Direccion] IS NULL) OR ([Direccion] ="& _ " @Original_Direccion)) AND ((@IsNull_Ciudad = 1 AND [Ciudad] IS NULL) OR ([Ciuda"& _ "d] = @Original_Ciudad)) AND ((@IsNull_Provincia = 1 AND [Provincia] IS NULL) OR "& _ "([Provincia] = @Original_Provincia)) AND ((@IsNull_CP = 1 AND [CP] IS NULL) OR ("& _ "[CP] = @Original_CP)))" Me.m_adapter.DeleteCommand.CommandType = System.Data.CommandType.Text Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_NIF", Syste Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@IsNull_Nombre", Syst Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_Nombre", Sy Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@IsNull_Apellido1", S Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_Apellido1", Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@IsNull_Apellido2", S Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_Apellido2", Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@IsNull_Telefono", Sy Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_Telefono", Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@IsNull_Email", Syste Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_Email", Sys Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@IsNull_Direccion", S Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_Direccion", Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@IsNull_Ciudad", Syst Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_Ciudad", Sy Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@IsNull_Provincia", S Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_Provincia", Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@IsNull_CP", System.D Me.m_adapter.DeleteCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_CP", System Me.m_adapter.InsertCommand = New System.Data.SqlClient.SqlCommand Me.m_adapter.InsertCommand.Connection = Me.Connection Me.m_adapter.InsertCommand.CommandText = "INSERT INTO [dbo].[Socios] ([NIF], [Nombre], [Apellido1], [Ap ", [Email], [Direccion], [Ciudad], [Provincia], [CP]) VALUES (@NIF, @Nombre, @Ape"& _ "llido1, @Apellido2, @Telefono, @Email, @Direccion, @Ciudad, @Provincia, @CP);"&Global.Microsoft.Vis "ELECT NIF, Nombre, Apellido1, Apellido2, Telefono, Email, Direccion, Ciudad, Pro"& _ "vincia, CP FROM Socios WHERE (NIF = @NIF)" Me.m_adapter.InsertCommand.CommandType = System.Data.CommandType.Text Me.m_adapter.InsertCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@NIF", System.Data.Sq Me.m_adapter.InsertCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Nombre", System.Data Me.m_adapter.InsertCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Apellido1", System.D Me.m_adapter.InsertCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Apellido2", System.D Me.m_adapter.InsertCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Telefono", System.Da Me.m_adapter.InsertCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Email", System.Data. Me.m_adapter.InsertCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Direccion", System.D Me.m_adapter.InsertCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Ciudad", System.Data Me.m_adapter.InsertCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Provincia", System.D Me.m_adapter.InsertCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@CP", System.Data.Sql Me.m_adapter.UpdateCommand = New System.Data.SqlClient.SqlCommand Me.m_adapter.UpdateCommand.Connection = Me.Connection Me.m_adapter.UpdateCommand.CommandText = "UPDATE [dbo].[Socios] SET [NIF] = @NIF, [Nombre] = @Nombre, [ "do1, [Apellido2] = @Apellido2, [Telefono] = @Telefono, [Email] = @Email, [Direcc"& _ "ion] = @Direccion, [Ciudad] = @Ciudad, [Provincia] = @Provincia, [CP] = @CP WHER"& _ "E (([NIF] = @Original_NIF) AND ((@IsNull_Nombre = 1 AND [Nombre] IS NULL) OR ([N"& _ "ombre] = @Original_Nombre)) AND ((@IsNull_Apellido1 = 1 AND [Apellido1] IS NULL)"& _ " OR ([Apellido1] = @Original_Apellido1)) AND ((@IsNull_Apellido2 = 1 AND [Apelli"& _ "do2] IS NULL) OR ([Apellido2] = @Original_Apellido2)) AND ((@IsNull_Telefono = 1"& _ " AND [Telefono] IS NULL) OR ([Telefono] = @Original_Telefono)) AND ((@IsNull_Ema"& _ "il = 1 AND [Email] IS NULL) OR ([Email] = @Original_Email)) AND ((@IsNull_Direcc"& _ "ion = 1 AND [Direccion] IS NULL) OR ([Direccion] = @Original_Direccion)) AND ((@"& _ "IsNull_Ciudad = 1 AND [Ciudad] IS NULL) OR ([Ciudad] = @Original_Ciudad)) AND (("& _ "@IsNull_Provincia = 1 AND [Provincia] IS NULL) OR ([Provincia] = @Original_Provi"& _ "ncia)) AND ((@IsNull_CP = 1 AND [CP] IS NULL) OR ([CP] = @Original_CP)));"&Global.Microsoft.VisualB "T NIF, Nombre, Apellido1, Apellido2, Telefono, Email, Direccion, Ciudad, Provinc"& _ "ia, CP FROM Socios WHERE (NIF = @NIF)" Me.m_adapter.UpdateCommand.CommandType = System.Data.CommandType.Text Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@NIF", System.Data.Sq Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Nombre", System.Data Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Apellido1", System.D Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Apellido2", System.D Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Telefono", System.Da Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Email", System.Data. Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Direccion", System.D Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Ciudad", System.Data Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Provincia", System.D Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@CP", System.Data.Sql Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_NIF", Syste Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@IsNull_Nombre", Syst Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_Nombre", Sy Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@IsNull_Apellido1", S Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_Apellido1", Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@IsNull_Apellido2", S Me.m_adapter.UpdateCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_Apellido2", Me.m_adapter.UpdateCommand.Parameters.Add(New Me.m_adapter.UpdateCommand.Parameters.Add(New Me.m_adapter.UpdateCommand.Parameters.Add(New Me.m_adapter.UpdateCommand.Parameters.Add(New Me.m_adapter.UpdateCommand.Parameters.Add(New Me.m_adapter.UpdateCommand.Parameters.Add(New Me.m_adapter.UpdateCommand.Parameters.Add(New Me.m_adapter.UpdateCommand.Parameters.Add(New Me.m_adapter.UpdateCommand.Parameters.Add(New Me.m_adapter.UpdateCommand.Parameters.Add(New Me.m_adapter.UpdateCommand.Parameters.Add(New Me.m_adapter.UpdateCommand.Parameters.Add(New End Sub System.Data.SqlClient.SqlParameter("@IsNull_Telefono", Sy System.Data.SqlClient.SqlParameter("@Original_Telefono", System.Data.SqlClient.SqlParameter("@IsNull_Email", Syste System.Data.SqlClient.SqlParameter("@Original_Email", Sys System.Data.SqlClient.SqlParameter("@IsNull_Direccion", S System.Data.SqlClient.SqlParameter("@Original_Direccion", System.Data.SqlClient.SqlParameter("@IsNull_Ciudad", Syst System.Data.SqlClient.SqlParameter("@Original_Ciudad", Sy System.Data.SqlClient.SqlParameter("@IsNull_Provincia", S System.Data.SqlClient.SqlParameter("@Original_Provincia", System.Data.SqlClient.SqlParameter("@IsNull_CP", System.D System.Data.SqlClient.SqlParameter("@Original_CP", System Private Sub InitConnection() Me.m_connection = New System.Data.SqlClient.SqlConnection Me.m_connection.ConnectionString = WindowsApplication3.Settings.Default.MSDNVideoConnectionString1 End Sub Private Sub InitCommandCollection() Me.m_commandCollection = New System.Data.SqlClient.SqlCommand(0) {} Me.m_commandCollection(0) = New System.Data.SqlClient.SqlCommand Me.m_commandCollection(0).Connection = Me.Connection Me.m_commandCollection(0).CommandText = "SELECT NIF, Nombre, Apellido1, Apellido2, Telefono, Email, Dir "vincia, CP FROM dbo.Socios" Me.m_commandCollection(0).CommandType = System.Data.CommandType.Text End Sub <System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Fill, true)> Public Overloads Overridable Function Fill(ByVal dataTable As DataSet1.SociosDataTable) As Integer Me.Adapter.SelectCommand = Me.CommandCollection(0) If (Me.m_clearBeforeFill = true) Then dataTable.Clear End If Dim returnValue As Integer = Me.Adapter.Fill(dataTable) Return returnValue End Function <System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.[Select], true Public Overloads Overridable Function GetData() As DataSet1.SociosDataTable Me.Adapter.SelectCommand = Me.CommandCollection(0) Dim dataTable As DataSet1.SociosDataTable = New DataSet1.SociosDataTable Me.Adapter.Fill(dataTable) Return dataTable End Function Public Overloads Overridable Function Update(ByVal dataTable As DataSet1.SociosDataTable) As Integer Return Me.Adapter.Update(dataTable) End Function Public Overloads Overridable Function Update(ByVal dataSet As DataSet1) As Integer Return Me.Adapter.Update(dataSet, "Socios") End Function Public Overloads Overridable Function Update(ByVal dataRow As System.Data.DataRow) As Integer Return Me.Adapter.Update(New System.Data.DataRow() {dataRow}) End Function Public Overloads Overridable Function Update(ByVal dataRows() As System.Data.DataRow) As Integer Return Me.Adapter.Update(dataRows) End Function <System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Delete, true)> Public Overloads Overridable Function Delete(ByVal Original_NIF As String, ByVal Original_Nombre As String If (Original_NIF Is Nothing) Then Throw New System.ArgumentNullException("Original_NIF") Else Me.Adapter.DeleteCommand.Parameters(0).Value = CType(Original_NIF,String) End If If (Original_Nombre Is Nothing) Then Me.Adapter.DeleteCommand.Parameters(1).Value = CType(1,Integer) Me.Adapter.DeleteCommand.Parameters(2).Value = System.DBNull.Value Else Me.Adapter.DeleteCommand.Parameters(1).Value = CType(0,Integer) Me.Adapter.DeleteCommand.Parameters(2).Value = CType(Original_Nombre,String) End If If (Original_Apellido1 Is Nothing) Then Me.Adapter.DeleteCommand.Parameters(3).Value = CType(1,Integer) Me.Adapter.DeleteCommand.Parameters(4).Value = System.DBNull.Value Else Me.Adapter.DeleteCommand.Parameters(3).Value = CType(0,Integer) Me.Adapter.DeleteCommand.Parameters(4).Value = CType(Original_Apellido1,String) End If If (Original_Apellido2 Is Nothing) Then Me.Adapter.DeleteCommand.Parameters(5).Value = CType(1,Integer) Me.Adapter.DeleteCommand.Parameters(6).Value = System.DBNull.Value Else Me.Adapter.DeleteCommand.Parameters(5).Value = CType(0,Integer) Me.Adapter.DeleteCommand.Parameters(6).Value = CType(Original_Apellido2,String) End If If (Original_Telefono Is Nothing) Then Me.Adapter.DeleteCommand.Parameters(7).Value = CType(1,Integer) Me.Adapter.DeleteCommand.Parameters(8).Value = System.DBNull.Value Else Me.Adapter.DeleteCommand.Parameters(7).Value = CType(0,Integer) Me.Adapter.DeleteCommand.Parameters(8).Value = CType(Original_Telefono,String) End If If (Original_Email Is Nothing) Then Me.Adapter.DeleteCommand.Parameters(9).Value = CType(1,Integer) Me.Adapter.DeleteCommand.Parameters(10).Value = System.DBNull.Value Else Me.Adapter.DeleteCommand.Parameters(9).Value = CType(0,Integer) Me.Adapter.DeleteCommand.Parameters(10).Value = CType(Original_Email,String) End If If (Original_Direccion Is Nothing) Then Me.Adapter.DeleteCommand.Parameters(11).Value = CType(1,Integer) Me.Adapter.DeleteCommand.Parameters(12).Value = System.DBNull.Value Else Me.Adapter.DeleteCommand.Parameters(11).Value = CType(0,Integer) Me.Adapter.DeleteCommand.Parameters(12).Value = CType(Original_Direccion,String) End If If (Original_Ciudad Is Nothing) Then Me.Adapter.DeleteCommand.Parameters(13).Value = CType(1,Integer) Me.Adapter.DeleteCommand.Parameters(14).Value = System.DBNull.Value Else Me.Adapter.DeleteCommand.Parameters(13).Value = CType(0,Integer) Me.Adapter.DeleteCommand.Parameters(14).Value = CType(Original_Ciudad,String) End If If (Original_Provincia Is Nothing) Then Me.Adapter.DeleteCommand.Parameters(15).Value = CType(1,Integer) Me.Adapter.DeleteCommand.Parameters(16).Value = System.DBNull.Value Else Me.Adapter.DeleteCommand.Parameters(15).Value = CType(0,Integer) Me.Adapter.DeleteCommand.Parameters(16).Value = CType(Original_Provincia,String) End If If (Original_CP Is Nothing) Then Me.Adapter.DeleteCommand.Parameters(17).Value = CType(1,Integer) Me.Adapter.DeleteCommand.Parameters(18).Value = System.DBNull.Value Else Me.Adapter.DeleteCommand.Parameters(17).Value = CType(0,Integer) Me.Adapter.DeleteCommand.Parameters(18).Value = CType(Original_CP,String) End If Dim previousConnectionState As System.Data.ConnectionState = Me.Adapter.DeleteCommand.Connection.State Me.Adapter.DeleteCommand.Connection.Open Try Return Me.Adapter.DeleteCommand.ExecuteNonQuery Finally If (previousConnectionState = System.Data.ConnectionState.Closed) Then Me.Adapter.DeleteCommand.Connection.Close End If End Try End Function <System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Insert, true)> Public Overloads Overridable Function Insert(ByVal NIF As String, ByVal Nombre As String, ByVal Apellido1 If (NIF Is Nothing) Then Throw New System.ArgumentNullException("NIF") Else Me.Adapter.InsertCommand.Parameters(0).Value = CType(NIF,String) End If If (Nombre Is Nothing) Then Me.Adapter.InsertCommand.Parameters(1).Value = System.DBNull.Value Else Me.Adapter.InsertCommand.Parameters(1).Value = CType(Nombre,String) End If If (Apellido1 Is Nothing) Then Me.Adapter.InsertCommand.Parameters(2).Value = System.DBNull.Value Else Me.Adapter.InsertCommand.Parameters(2).Value = CType(Apellido1,String) End If If (Apellido2 Is Nothing) Then Me.Adapter.InsertCommand.Parameters(3).Value = System.DBNull.Value Else Me.Adapter.InsertCommand.Parameters(3).Value = CType(Apellido2,String) End If If (Telefono Is Nothing) Then Me.Adapter.InsertCommand.Parameters(4).Value = System.DBNull.Value Else Me.Adapter.InsertCommand.Parameters(4).Value = CType(Telefono,String) End If If (Email Is Nothing) Then Me.Adapter.InsertCommand.Parameters(5).Value = System.DBNull.Value Else Me.Adapter.InsertCommand.Parameters(5).Value = CType(Email,String) End If If (Direccion Is Nothing) Then Me.Adapter.InsertCommand.Parameters(6).Value = System.DBNull.Value Else Me.Adapter.InsertCommand.Parameters(6).Value = CType(Direccion,String) End If If (Ciudad Is Nothing) Then Me.Adapter.InsertCommand.Parameters(7).Value = System.DBNull.Value Else Me.Adapter.InsertCommand.Parameters(7).Value = CType(Ciudad,String) End If If (Provincia Is Nothing) Then Me.Adapter.InsertCommand.Parameters(8).Value = System.DBNull.Value Else Me.Adapter.InsertCommand.Parameters(8).Value = CType(Provincia,String) End If If (CP Is Nothing) Then Me.Adapter.InsertCommand.Parameters(9).Value = System.DBNull.Value Else Me.Adapter.InsertCommand.Parameters(9).Value = CType(CP,String) End If Dim previousConnectionState As System.Data.ConnectionState = Me.Adapter.InsertCommand.Connection.State Me.Adapter.InsertCommand.Connection.Open Try Return Me.Adapter.InsertCommand.ExecuteNonQuery Finally If (previousConnectionState = System.Data.ConnectionState.Closed) Then Me.Adapter.InsertCommand.Connection.Close End If End Try End Function <System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, true)> Public Overloads Overridable Function Update( _ ByVal NIF As String, _ ByVal Nombre As String, _ ByVal Apellido1 As String, _ ByVal Apellido2 As String, _ ByVal Telefono As String, _ ByVal Email As String, _ ByVal Direccion As String, _ ByVal Ciudad As String, _ ByVal Provincia As String, _ ByVal CP As String, _ ByVal Original_NIF As String, _ ByVal Original_Nombre As String, _ ByVal Original_Apellido1 As String, _ ByVal Original_Apellido2 As String, _ ByVal Original_Telefono As String, _ ByVal Original_Email As String, _ ByVal Original_Direccion As String, _ ByVal Original_Ciudad As String, _ ByVal Original_Provincia As String, _ ByVal Original_CP As String) As Integer If (NIF Is Nothing) Then Throw New System.ArgumentNullException("NIF") Else Me.Adapter.UpdateCommand.Parameters(0).Value = CType(NIF,String) End If If (Nombre Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(1).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(1).Value = CType(Nombre,String) End If If (Apellido1 Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(2).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(2).Value = CType(Apellido1,String) End If If (Apellido2 Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(3).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(3).Value = CType(Apellido2,String) End If If (Telefono Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(4).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(4).Value = CType(Telefono,String) End If If (Email Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(5).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(5).Value = CType(Email,String) End If If (Direccion Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(6).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(6).Value = CType(Direccion,String) End If If (Ciudad Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(7).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(7).Value = CType(Ciudad,String) End If If (Provincia Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(8).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(8).Value = CType(Provincia,String) End If If (CP Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(9).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(9).Value = CType(CP,String) End If If (Original_NIF Is Nothing) Then Throw New System.ArgumentNullException("Original_NIF") Else Me.Adapter.UpdateCommand.Parameters(10).Value = CType(Original_NIF,String) End If If (Original_Nombre Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(11).Value = CType(1,Integer) Me.Adapter.UpdateCommand.Parameters(12).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(11).Value = CType(0,Integer) Me.Adapter.UpdateCommand.Parameters(12).Value = CType(Original_Nombre,String) End If If (Original_Apellido1 Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(13).Value = CType(1,Integer) Me.Adapter.UpdateCommand.Parameters(14).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(13).Value = CType(0,Integer) Me.Adapter.UpdateCommand.Parameters(14).Value = CType(Original_Apellido1,String) End If If (Original_Apellido2 Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(15).Value = CType(1,Integer) Me.Adapter.UpdateCommand.Parameters(16).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(15).Value = CType(0,Integer) Me.Adapter.UpdateCommand.Parameters(16).Value = CType(Original_Apellido2,String) End If If (Original_Telefono Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(17).Value = CType(1,Integer) Me.Adapter.UpdateCommand.Parameters(18).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(17).Value = CType(0,Integer) Me.Adapter.UpdateCommand.Parameters(18).Value = CType(Original_Telefono,String) End If If (Original_Email Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(19).Value = CType(1,Integer) Me.Adapter.UpdateCommand.Parameters(20).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(19).Value = CType(0,Integer) Me.Adapter.UpdateCommand.Parameters(20).Value = CType(Original_Email,String) End If If (Original_Direccion Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(21).Value = CType(1,Integer) Me.Adapter.UpdateCommand.Parameters(22).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(21).Value = CType(0,Integer) Me.Adapter.UpdateCommand.Parameters(22).Value = CType(Original_Direccion,String) End If If (Original_Ciudad Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(23).Value = CType(1,Integer) Me.Adapter.UpdateCommand.Parameters(24).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(23).Value = CType(0,Integer) Me.Adapter.UpdateCommand.Parameters(24).Value = CType(Original_Ciudad,String) End If If (Original_Provincia Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(25).Value = CType(1,Integer) Me.Adapter.UpdateCommand.Parameters(26).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(25).Value = CType(0,Integer) Me.Adapter.UpdateCommand.Parameters(26).Value = CType(Original_Provincia,String) End If If (Original_CP Is Nothing) Then Me.Adapter.UpdateCommand.Parameters(27).Value = CType(1,Integer) Me.Adapter.UpdateCommand.Parameters(28).Value = System.DBNull.Value Else Me.Adapter.UpdateCommand.Parameters(27).Value = CType(0,Integer) Me.Adapter.UpdateCommand.Parameters(28).Value = CType(Original_CP,String) End If Dim previousConnectionState As System.Data.ConnectionState = Me.Adapter.UpdateCommand.Connection.State Me.Adapter.UpdateCommand.Connection.Open Try Return Me.Adapter.UpdateCommand.ExecuteNonQuery Finally If (previousConnectionState = System.Data.ConnectionState.Closed) Then Me.Adapter.UpdateCommand.Connection.Close End If End Try End Function End Class End Namespace Más adelant e v er em os com o usar lo, per o ant es v er em os ot r a for m a de cr ear nuest r o Dat aSet t ipado. Est a que hem os v ist o, es la for m a m ás sencilla y habit ual de cr ear lo, per o ex ist e ot r a m aner a que es un pr ocedim ient o m anual que a m odo gener al, conv iene que la conozcam os. Módulo 5 - Capítulo 4 4. Generando un DataSet tipado con la línea de comandos Ot r a m aner a de gener ar nuest r os pr opios Dat aSet s t ipados es m ediant e la línea de com andos de MS- DOS con el uso de la her r am ient a x sd . e x e . A cont inuación v er em os com o r ealizar est a t ar ea con est e com ando. Usando la her r am ient a XSD .exe XSD no es ot r a cosa que un ficher o ej ecut able, que encont r ar em os en el SDK de . NET y que nos per m t ir á cr ear nuest r os Dat aSet t ipados de m aner a r ápida y sencilla. Par a llev ar a cabo nuest r a t ar ea, abr a una v ent ana MS- DOS y s t úese en el dir ect or io en el cuál t enem os inst alado nuest r o ent orno Visual St udio 2010, com o se ind ca en la figur a 1. Ve nt a na de M S- DOS sit ua da e n e l dire ct orio de Visua l St udio 2 0 1 0 Figur a 1 Una v ez sit uados sobr e est e dir ect or io, nos m ov er em os al subdir ect or io SD K\ v 2 . 0 \ Bin t al y com o se ind ca en la figur a 2. Ve nt a na de M S- DOS sit ua da e n e l subdire ct orio Bin de Visua l St udio 2 0 1 0 Figur a 2 A cont inuación, lo que deber em os hacer es el ficher o x sd cor r espondient e. Par a eso, deber em os hacer lo m ediant e un edit or de t ex t os o bien, desde una pequeña aplicación Window s que gener ar em os par a t al pr opós t o. En nuest r o caso lo har em os con una apl cación Window s, par a lo cuál, in ciar em os un nuev o pr oy ect o de Ap lica ción p a r a W in d ow s. En el for m ular io Window s, inser t ar em os un cont r ol Bu t t on t al y com o se m uest r a en la figur a 3. Cont rol But t on inse rt a do e n e l form ula rio de ge ne ra ción de l e sque m a Figur a 3 A cont inuación, escr ibir em os el siguient e código que lo que nos per m it ir á, ser á cr ear el f cher o o docum ent o XML de ex t ensión x sd cor r espondient e, el cuál cont iene la infor m ación par a gener ar el Dat aSet t ipado. El código de la aplicación de gener ación del esquem a es el que se det alla a cont inuación: Imports System.Data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Establecemos los parámetros de la conexión Dim MiSqlConnection As New SqlConnection("server=.;uid=sa;password=VisualBasic;database=MSDNVideo") ' Indicamos la sentencia SELECT para la conexión anterior Dim MiSqlDataAdapter As New SqlDataAdapter("SELECT TOP 1 * FROM SOCIOS", MiSqlConnection) ' Declaramos un objeto DataSet para almacenar el contenido Dim MiDataSet As New DataSet() ' Rellenamos el DataSet MiSqlDataAdapter.Fill(MiDataSet, "SOCIOS") ' Declaramos un objeto DataTable Dim MiDataTable As DataTable = MiDataSet.Tables("SOCIOS") ' Completamos algunos parámetros de los campos de la tabla MiDataTable.Columns("NIF").Unique = True MiDataTable.Columns("Nombre").MaxLength = 50 MiDataTable.Columns("Apellido1").MaxLength = 50 MiDataTable.Columns("Apellido2").MaxLength = 50 MiDataTable.Columns("Telefono").MaxLength = 13 MiDataTable.Columns("Email").MaxLength = 50 MiDataTable.Columns("Direccion").MaxLength = 100 MiDataTable.Columns("Ciudad").MaxLength = 50 MiDataTable.Columns("Provincia").MaxLength = 50 MiDataTable.Columns("CP").MaxLength = 50 ' Escribimos el esquema de la tabla al disco duro del PC MiDataSet.WriteXmlSchema("c:\MiEsquema.xsd") ' Cerramos la conexión MiSqlConnection.Close() ' Mostramos un mensaje de esquema creado correctamente MessageBox.Show("Esquema creado correctamente") End Sub End Class Una v ez que hem os escr it o el código fuent e necesar io par a gener ar el esquem a, ej ecut ar em os nuest r a aplicac ón, obt eniendo una ej ecución afir m at iv a com o la que se ind ca en la figur a 4. Ej e cución de l progra m a de ge ne ra ción de l e sque m a Figur a 4 El código de nuest r o esquem a, ser á una v ez que se ha cr eado, com o se indica en el siguient e código: <?xml version="1.0" standalone="yes"?> <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="SOCIOS"> <xs:complexType> <xs:sequence> <xs:element name="NIF" type="xs:string" minOccurs="0" /> <xs:element name="Nombre" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="50" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="Apellido1" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="50" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="Apellido2" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="50" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="Telefono" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="13" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="Email" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="50" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="Direccion" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="100" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="Ciudad" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="50" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="Provincia" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="50" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="CP" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="50" /> </xs:restriction> </xs:simpleType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> <xs:unique name="Constraint1"> <xs:selector xpath=".//SOCIOS" /> <xs:field xpath="NIF" /> </xs:unique> </xs:element> </xs:schema> Lo que har em os a cont inuación, ser á ut ilizar la her r am ient a x sd . e x e que est á dent r o del dir ect or io SD K\ v 2 . 0 \ Bin . Con la her r am ient a x sd . e x e , gener ar em os la clase que podr em os usar par a el Dat aSet t ipados. Una v ez por lo t ant o, que est am os s t uados en la línea de com andos de MS- DOS, escr ibir em os la inst r ucción: x sd c:\ M iEsq u e m a . x sd / d / l:V B / n :M iD a t a Se t . D STy p e d Socios / o:c:\ Est o lo har em os t al y com o se indica en la figur a 5. Com a ndos de cre a ción de la cla se de l e sque m a cre a do Figur a 5 Si t odo ha do cor r ect am ent e, la clase par a usar el Dat aSet t ipado, se habr á cr eado com o se indica en la figur a 6. Cla se de Da t a Se t t ipa do cre a da con la a plica ción x sd.e x e Figur a 6 El código de nuest r a clase t endr á un aspect o sim ilar al que se ind ca en el siguient e código fuent e: '-----------------------------------------------------------------------------' <auto-generated> ' Una herramienta generó este código. ' Versión del motor en tiempo de ejecución:2.0.50215.44 ' ' Los cambios en este archivo podrían causar un comportamiento incorrecto y se perderán si ' el código se vuelve a generar. ' </auto-generated> '-----------------------------------------------------------------------------Option Strict Off Option Explicit On Imports System ' 'Este código fuente fue generado automáticamente por xsd, Versión=2.0.50215.44. ' Namespace MiDataSet.DSTypedSocios <Serializable(), _ System.ComponentModel.DesignerCategoryAttribute("code"), _ System.ComponentModel.ToolboxItem(true), _ System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedDataSetSchema"), _ System.Xml.Serialization.XmlRootAttribute("NewDataSet"), _ System.ComponentModel.Design.HelpKeywordAttribute("vs.data.DataSet"), _ System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Usage", "CA2240:ImplementISerializableCorrectly")> Partial Public Class NewDataSet Inherits System.Data.DataSet _ Private tableSOCIOS As SOCIOSDataTable Private _schemaSerializationMode As System.Data.SchemaSerializationMode = System.Data.SchemaSerializationMode.IncludeSchema <System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")> Public Sub New() MyBase.New Me.BeginInit Me.InitClass Dim schemaChangedHandler As System.ComponentModel.CollectionChangeEventHandler = AddressOf Me.SchemaChanged AddHandler MyBase.Tables.CollectionChanged, schemaChangedHandler AddHandler MyBase.Relations.CollectionChanged, schemaChangedHandler Me.EndInit End Sub <System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")> Protected Sub New(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.Str MyBase.New(info, context) If (Me.IsBinarySerialized(info, context) = true) Then Me.InitVars(false) Dim schemaChangedHandler1 As System.ComponentModel.CollectionChangeEventHandler = AddressOf Me.SchemaChanged AddHandler Me.Tables.CollectionChanged, schemaChangedHandler1 AddHandler Me.Relations.CollectionChanged, schemaChangedHandler1 Return End If Dim strSchema As String = CType(info.GetValue("XmlSchema", GetType(String)),String) If (Me.DetermineSchemaSerializationMode(info, context) = System.Data.SchemaSerializationMode.IncludeSchema) Then Dim ds As System.Data.DataSet = New System.Data.DataSet ds.ReadXmlSchema(New System.Xml.XmlTextReader(New System.IO.StringReader(strSchema))) If (Not (ds.Tables("SOCIOS")) Is Nothing) Then MyBase.Tables.Add(New SOCIOSDataTable(ds.Tables("SOCIOS"))) End If Me.DataSetName = ds.DataSetName Me.Prefix = ds.Prefix Me.Namespace = ds.Namespace Me.Locale = ds.Locale Me.CaseSensitive = ds.CaseSensitive Me.EnforceConstraints = ds.EnforceConstraints Me.Merge(ds, false, System.Data.MissingSchemaAction.Add) Me.InitVars Else Me.ReadXmlSchema(New System.Xml.XmlTextReader(New System.IO.StringReader(strSchema))) End If Me.GetSerializationData(info, context) Dim schemaChangedHandler As System.ComponentModel.CollectionChangeEventHandler = AddressOf Me.SchemaChanged AddHandler MyBase.Tables.CollectionChanged, schemaChangedHandler AddHandler Me.Relations.CollectionChanged, schemaChangedHandler End Sub <System.ComponentModel.Browsable(false), _ System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content)> Public ReadOnly Property SOCIOS() As SOCIOSDataTable Get Return Me.tableSOCIOS End Get End Property _ Public Overrides Property SchemaSerializationMode() As System.Data.SchemaSerializationMode Get Return Me._schemaSerializationMode End Get Set Me._schemaSerializationMode = value End Set End Property <System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)> Public Shadows ReadOnly Property Tables() As System.Data.DataTableCollection Get Return MyBase.Tables End Get End Property _ <System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)> Public Shadows ReadOnly Property Relations() As System.Data.DataRelationCollection Get Return MyBase.Relations End Get End Property _ <System.ComponentModel.DefaultValueAttribute(true)> _ Public Shadows Property EnforceConstraints() As Boolean Get Return MyBase.EnforceConstraints End Get Set MyBase.EnforceConstraints = value End Set End Property Protected Overrides Sub InitializeDerivedDataSet() Me.BeginInit Me.InitClass Me.EndInit End Sub Public Overrides Function Clone() As System.Data.DataSet Dim cln As NewDataSet = CType(MyBase.Clone,NewDataSet) cln.InitVars Return cln End Function Protected Overrides Function ShouldSerializeTables() As Boolean Return false End Function Protected Overrides Function ShouldSerializeRelations() As Boolean Return false End Function Protected Overrides Sub ReadXmlSerializable(ByVal reader As System.Xml.XmlReader) If (Me.DetermineSchemaSerializationMode(reader) = System.Data.SchemaSerializationMode.IncludeSchema) Then Me.Reset Dim ds As System.Data.DataSet = New System.Data.DataSet ds.ReadXml(reader) If (Not (ds.Tables("SOCIOS")) Is Nothing) Then MyBase.Tables.Add(New SOCIOSDataTable(ds.Tables("SOCIOS"))) End If Me.DataSetName = ds.DataSetName Me.Prefix = ds.Prefix Me.Namespace = ds.Namespace Me.Locale = ds.Locale Me.CaseSensitive = ds.CaseSensitive Me.EnforceConstraints = ds.EnforceConstraints Me.Merge(ds, false, System.Data.MissingSchemaAction.Add) Me.InitVars Else Me.ReadXml(reader) Me.InitVars End If End Sub Protected Overrides Function GetSchemaSerializable() As System.Xml.Schema.XmlSchema Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream Me.WriteXmlSchema(New System.Xml.XmlTextWriter(stream, Nothing)) stream.Position = 0 Return System.Xml.Schema.XmlSchema.Read(New System.Xml.XmlTextReader(stream), Nothing) End Function Friend Overloads Sub InitVars() Me.InitVars(true) End Sub Friend Overloads Sub InitVars(ByVal initTable As Boolean) Me.tableSOCIOS = CType(MyBase.Tables("SOCIOS"),SOCIOSDataTable) If (initTable = true) Then If (Not (Me.tableSOCIOS) Is Nothing) Then Me.tableSOCIOS.InitVars End If End If End Sub Private Sub InitClass() Me.DataSetName = "NewDataSet" Me.Prefix = "" Me.EnforceConstraints = true Me.tableSOCIOS = New SOCIOSDataTable MyBase.Tables.Add(Me.tableSOCIOS) End Sub Private Function ShouldSerializeSOCIOS() As Boolean Return false End Function Private Sub SchemaChanged(ByVal sender As Object, ByVal e As System.ComponentModel.CollectionChangeEventArgs) If (e.Action = System.ComponentModel.CollectionChangeAction.Remove) Then Me.InitVars End If End Sub Public Shared Function GetTypedDataSetSchema(ByVal xs As System.Xml.Schema.XmlSchemaSet) As System.Xml.Schema.XmlSchemaComplexTyp Dim ds As NewDataSet = New NewDataSet Dim type As System.Xml.Schema.XmlSchemaComplexType = New System.Xml.Schema.XmlSchemaComplexType Dim sequence As System.Xml.Schema.XmlSchemaSequence = New System.Xml.Schema.XmlSchemaSequence xs.Add(ds.GetSchemaSerializable) Dim any As System.Xml.Schema.XmlSchemaAny = New System.Xml.Schema.XmlSchemaAny any.Namespace = ds.Namespace sequence.Items.Add(any) type.Particle = sequence Return type End Function Public Delegate Sub SOCIOSRowChangeEventHandler(ByVal sender As Object, ByVal e As SOCIOSRowChangeEvent) <System.Serializable(), _ System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedTableSchema")> Partial Public Class SOCIOSDataTable Inherits System.Data.DataTable Implements System.Collections.IEnumerable Private columnNIF As System.Data.DataColumn Private columnNombre As System.Data.DataColumn Private columnApellido1 As System.Data.DataColumn _ Private columnApellido2 As System.Data.DataColumn Private columnTelefono As System.Data.DataColumn Private columnEmail As System.Data.DataColumn Private columnDireccion As System.Data.DataColumn Private columnCiudad As System.Data.DataColumn Private columnProvincia As System.Data.DataColumn Private columnCP As System.Data.DataColumn Public Sub New() MyBase.New Me.TableName = "SOCIOS" Me.BeginInit Me.InitClass Me.EndInit End Sub Friend Sub New(ByVal table As System.Data.DataTable) MyBase.New Me.TableName = table.TableName If (table.CaseSensitive <> table.DataSet.CaseSensitive) Then Me.CaseSensitive = table.CaseSensitive End If If (table.Locale.ToString <> table.DataSet.Locale.ToString) Then Me.Locale = table.Locale End If If (table.Namespace <> table.DataSet.Namespace) Then Me.Namespace = table.Namespace End If Me.Prefix = table.Prefix Me.MinimumCapacity = table.MinimumCapacity End Sub Protected Sub New(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization. MyBase.New(info, context) Me.InitVars End Sub Public ReadOnly Property NIFColumn() As System.Data.DataColumn Get Return Me.columnNIF End Get End Property Public ReadOnly Property NombreColumn() As System.Data.DataColumn Get Return Me.columnNombre End Get End Property Public ReadOnly Property Apellido1Column() As System.Data.DataColumn Get Return Me.columnApellido1 End Get End Property Public ReadOnly Property Apellido2Column() As System.Data.DataColumn Get Return Me.columnApellido2 End Get End Property Public ReadOnly Property TelefonoColumn() As System.Data.DataColumn Get Return Me.columnTelefono End Get End Property Public ReadOnly Property EmailColumn() As System.Data.DataColumn Get Return Me.columnEmail End Get End Property Public ReadOnly Property DireccionColumn() As System.Data.DataColumn Get Return Me.columnDireccion End Get End Property Public ReadOnly Property CiudadColumn() As System.Data.DataColumn Get Return Me.columnCiudad End Get End Property Public ReadOnly Property ProvinciaColumn() As System.Data.DataColumn Get Return Me.columnProvincia End Get End Property Public ReadOnly Property CPColumn() As System.Data.DataColumn Get Return Me.columnCP End Get End Property <System.ComponentModel.Browsable(false)> _ Public ReadOnly Property Count() As Integer Get Return Me.Rows.Count End Get End Property Public Default ReadOnly Property Item(ByVal index As Integer) As SOCIOSRow Get Return CType(Me.Rows(index),SOCIOSRow) End Get End Property Public Event SOCIOSRowChanged As SOCIOSRowChangeEventHandler Public Event SOCIOSRowChanging As SOCIOSRowChangeEventHandler Public Event SOCIOSRowDeleted As SOCIOSRowChangeEventHandler Public Event SOCIOSRowDeleting As SOCIOSRowChangeEventHandler Public Overloads Sub AddSOCIOSRow(ByVal row As SOCIOSRow) Me.Rows.Add(row) End Sub Public Overloads Function AddSOCIOSRow(ByVal NIF As String, ByVal Nombre As String, ByVal Apellido1 As String, ByVal Apellido2 Dim rowSOCIOSRow As SOCIOSRow = CType(Me.NewRow,SOCIOSRow) rowSOCIOSRow.ItemArray = New Object() {NIF, Nombre, Apellido1, Apellido2, Telefono, Email, Direccion, Ciudad, Provincia, CP Me.Rows.Add(rowSOCIOSRow) Return rowSOCIOSRow End Function Public Overridable Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnu Return Me.Rows.GetEnumerator End Function Public Overrides Function Clone() As System.Data.DataTable Dim cln As SOCIOSDataTable = CType(MyBase.Clone,SOCIOSDataTable) cln.InitVars Return cln End Function Protected Overrides Function CreateInstance() As System.Data.DataTable Return New SOCIOSDataTable End Function Friend Sub InitVars() Me.columnNIF = MyBase.Columns("NIF") Me.columnNombre = MyBase.Columns("Nombre") Me.columnApellido1 = MyBase.Columns("Apellido1") Me.columnApellido2 = MyBase.Columns("Apellido2") Me.columnTelefono = MyBase.Columns("Telefono") Me.columnEmail = MyBase.Columns("Email") Me.columnDireccion = MyBase.Columns("Direccion") Me.columnCiudad = MyBase.Columns("Ciudad") Me.columnProvincia = MyBase.Columns("Provincia") Me.columnCP = MyBase.Columns("CP") End Sub Private Sub InitClass() Me.columnNIF = New System.Data.DataColumn("NIF", GetType(String), Nothing, System.Data.MappingType.Element) MyBase.Columns.Add(Me.columnNIF) Me.columnNombre = New System.Data.DataColumn("Nombre", GetType(String), Nothing, System.Data.MappingType.Element) MyBase.Columns.Add(Me.columnNombre) Me.columnApellido1 = New System.Data.DataColumn("Apellido1", GetType(String), Nothing, System.Data.MappingType.Element) MyBase.Columns.Add(Me.columnApellido1) Me.columnApellido2 = New System.Data.DataColumn("Apellido2", GetType(String), Nothing, System.Data.MappingType.Element) MyBase.Columns.Add(Me.columnApellido2) Me.columnTelefono = New System.Data.DataColumn("Telefono", GetType(String), Nothing, System.Data.MappingType.Element) MyBase.Columns.Add(Me.columnTelefono) Me.columnEmail = New System.Data.DataColumn("Email", GetType(String), Nothing, System.Data.MappingType.Element) MyBase.Columns.Add(Me.columnEmail) Me.columnDireccion = New System.Data.DataColumn("Direccion", GetType(String), Nothing, System.Data.MappingType.Element) MyBase.Columns.Add(Me.columnDireccion) Me.columnCiudad = New System.Data.DataColumn("Ciudad", GetType(String), Nothing, System.Data.MappingType.Element) MyBase.Columns.Add(Me.columnCiudad) Me.columnProvincia = New System.Data.DataColumn("Provincia", GetType(String), Nothing, System.Data.MappingType.Element) MyBase.Columns.Add(Me.columnProvincia) Me.columnCP = New System.Data.DataColumn("CP", GetType(String), Nothing, System.Data.MappingType.Element) MyBase.Columns.Add(Me.columnCP) Me.Constraints.Add(New System.Data.UniqueConstraint("Constraint1", New System.Data.DataColumn() {Me.columnNIF}, false)) Me.columnNIF.Unique = true Me.columnNombre.MaxLength = 50 Me.columnApellido1.MaxLength = 50 Me.columnApellido2.MaxLength = 50 Me.columnTelefono.MaxLength = 13 Me.columnEmail.MaxLength = 50 Me.columnDireccion.MaxLength = 100 Me.columnCiudad.MaxLength = 50 Me.columnProvincia.MaxLength = 50 Me.columnCP.MaxLength = 50 End Sub Public Function NewSOCIOSRow() As SOCIOSRow Return CType(Me.NewRow,SOCIOSRow) End Function Protected Overrides Function NewRowFromBuilder(ByVal builder As System.Data.DataRowBuilder) As System.Data.DataRow Return New SOCIOSRow(builder) End Function Protected Overrides Function GetRowType() As System.Type Return GetType(SOCIOSRow) End Function Protected Overrides Sub OnRowChanged(ByVal e As System.Data.DataRowChangeEventArgs) MyBase.OnRowChanged(e) If (Not (Me.SOCIOSRowChangedEvent) Is Nothing) Then RaiseEvent SOCIOSRowChanged(Me, New SOCIOSRowChangeEvent(CType(e.Row,SOCIOSRow), e.Action)) End If End Sub Protected Overrides Sub OnRowChanging(ByVal e As System.Data.DataRowChangeEventArgs) MyBase.OnRowChanging(e) If (Not (Me.SOCIOSRowChangingEvent) Is Nothing) Then RaiseEvent SOCIOSRowChanging(Me, New SOCIOSRowChangeEvent(CType(e.Row,SOCIOSRow), e.Action)) End If End Sub Protected Overrides Sub OnRowDeleted(ByVal e As System.Data.DataRowChangeEventArgs) MyBase.OnRowDeleted(e) If (Not (Me.SOCIOSRowDeletedEvent) Is Nothing) Then RaiseEvent SOCIOSRowDeleted(Me, New SOCIOSRowChangeEvent(CType(e.Row,SOCIOSRow), e.Action)) End If End Sub Protected Overrides Sub OnRowDeleting(ByVal e As System.Data.DataRowChangeEventArgs) MyBase.OnRowDeleting(e) If (Not (Me.SOCIOSRowDeletingEvent) Is Nothing) Then RaiseEvent SOCIOSRowDeleting(Me, New SOCIOSRowChangeEvent(CType(e.Row,SOCIOSRow), e.Action)) End If End Sub Public Sub RemoveSOCIOSRow(ByVal row As SOCIOSRow) Me.Rows.Remove(row) End Sub Public Shared Function GetTypedTableSchema(ByVal xs As System.Xml.Schema.XmlSchemaSet) As System.Xml.Schema.XmlSchemaComplexTy Dim type As System.Xml.Schema.XmlSchemaComplexType = New System.Xml.Schema.XmlSchemaComplexType Dim sequence As System.Xml.Schema.XmlSchemaSequence = New System.Xml.Schema.XmlSchemaSequence Dim ds As NewDataSet = New NewDataSet xs.Add(ds.GetSchemaSerializable) Dim any1 As System.Xml.Schema.XmlSchemaAny = New System.Xml.Schema.XmlSchemaAny any1.Namespace = "http:"//www.w3.org/2001/XMLSchema" any1.MinOccurs = New Decimal(0) any1.MaxOccurs = Decimal.MaxValue any1.ProcessContents = System.Xml.Schema.XmlSchemaContentProcessing.Lax sequence.Items.Add(any1) Dim any2 As System.Xml.Schema.XmlSchemaAny = New System.Xml.Schema.XmlSchemaAny any2.Namespace = "urn:schemas-microsoft-com:xml-diffgram-v1" any2.MinOccurs = New Decimal(1) any2.ProcessContents = System.Xml.Schema.XmlSchemaContentProcessing.Lax sequence.Items.Add(any2) Dim attribute1 As System.Xml.Schema.XmlSchemaAttribute = New System.Xml.Schema.XmlSchemaAttribute attribute1.Name = "namespace" attribute1.FixedValue = ds.Namespace type.Attributes.Add(attribute1) Dim attribute2 As System.Xml.Schema.XmlSchemaAttribute = New System.Xml.Schema.XmlSchemaAttribute attribute2.Name = "tableTypeName" attribute2.FixedValue = "SOCIOSDataTable" type.Attributes.Add(attribute2) type.Particle = sequence Return type End Function End Class Partial Public Class SOCIOSRow Inherits System.Data.DataRow Private tableSOCIOS As SOCIOSDataTable Friend Sub New(ByVal rb As System.Data.DataRowBuilder) MyBase.New(rb) Me.tableSOCIOS = CType(Me.Table,SOCIOSDataTable) End Sub Public Property NIF() As String Get Try Return CType(Me(Me.tableSOCIOS.NIFColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'NIF' de la tabla 'SOCIOS' es DBNull.", e) End Try End Get Set Me(Me.tableSOCIOS.NIFColumn) = value End Set End Property Public Property Nombre() As String Get Try Return CType(Me(Me.tableSOCIOS.NombreColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Nombre' de la tabla 'SOCIOS' es DBNull.", e) End Try End Get Set Me(Me.tableSOCIOS.NombreColumn) = value End Set End Property Public Property Apellido1() As String Get Try Return CType(Me(Me.tableSOCIOS.Apellido1Column),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Apellido1' de la tabla 'SOCIOS' es DBNull.", e) End Try End Get Set Me(Me.tableSOCIOS.Apellido1Column) = value End Set End Property Public Property Apellido2() As String Get Try Return CType(Me(Me.tableSOCIOS.Apellido2Column),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Apellido2' de la tabla 'SOCIOS' es DBNull.", e) End Try End Get Set Me(Me.tableSOCIOS.Apellido2Column) = value End Set End Property Public Property Telefono() As String Get Try Return CType(Me(Me.tableSOCIOS.TelefonoColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Telefono' de la tabla 'SOCIOS' es DBNull.", e) End Try End Get Set Me(Me.tableSOCIOS.TelefonoColumn) = value End Set End Property Public Property Email() As String Get Try Return CType(Me(Me.tableSOCIOS.EmailColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Email' de la tabla 'SOCIOS' es DBNull.", e) End Try End Get Set Me(Me.tableSOCIOS.EmailColumn) = value End Set End Property Public Property Direccion() As String Get Try Return CType(Me(Me.tableSOCIOS.DireccionColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Direccion' de la tabla 'SOCIOS' es DBNull.", e) End Try End Get Set Me(Me.tableSOCIOS.DireccionColumn) = value End Set End Property Public Property Ciudad() As String Get Try Return CType(Me(Me.tableSOCIOS.CiudadColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Ciudad' de la tabla 'SOCIOS' es DBNull.", e) End Try End Get Set Me(Me.tableSOCIOS.CiudadColumn) = value End Set End Property Public Property Provincia() As String Get Try Return CType(Me(Me.tableSOCIOS.ProvinciaColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'Provincia' de la tabla 'SOCIOS' es DBNull.", e) End Try End Get Set Me(Me.tableSOCIOS.ProvinciaColumn) = value End Set End Property Public Property CP() As String Get Try Return CType(Me(Me.tableSOCIOS.CPColumn),String) Catch e As System.InvalidCastException Throw New System.Data.StrongTypingException("El valor de la columna 'CP' de la tabla 'SOCIOS' es DBNull.", e) End Try End Get Set Me(Me.tableSOCIOS.CPColumn) = value End Set End Property Public Function IsNIFNull() As Boolean Return Me.IsNull(Me.tableSOCIOS.NIFColumn) End Function Public Sub SetNIFNull() Me(Me.tableSOCIOS.NIFColumn) = System.Convert.DBNull End Sub Public Function IsNombreNull() As Boolean Return Me.IsNull(Me.tableSOCIOS.NombreColumn) End Function Public Sub SetNombreNull() Me(Me.tableSOCIOS.NombreColumn) = System.Convert.DBNull End Sub Public Function IsApellido1Null() As Boolean Return Me.IsNull(Me.tableSOCIOS.Apellido1Column) End Function Public Sub SetApellido1Null() Me(Me.tableSOCIOS.Apellido1Column) = System.Convert.DBNull End Sub Public Function IsApellido2Null() As Boolean Return Me.IsNull(Me.tableSOCIOS.Apellido2Column) End Function Public Sub SetApellido2Null() Me(Me.tableSOCIOS.Apellido2Column) = System.Convert.DBNull End Sub Public Function IsTelefonoNull() As Boolean Return Me.IsNull(Me.tableSOCIOS.TelefonoColumn) End Function Public Sub SetTelefonoNull() Me(Me.tableSOCIOS.TelefonoColumn) = System.Convert.DBNull End Sub Public Function IsEmailNull() As Boolean Return Me.IsNull(Me.tableSOCIOS.EmailColumn) End Function Public Sub SetEmailNull() Me(Me.tableSOCIOS.EmailColumn) = System.Convert.DBNull End Sub Public Function IsDireccionNull() As Boolean Return Me.IsNull(Me.tableSOCIOS.DireccionColumn) End Function Public Sub SetDireccionNull() Me(Me.tableSOCIOS.DireccionColumn) = System.Convert.DBNull End Sub Public Function IsCiudadNull() As Boolean Return Me.IsNull(Me.tableSOCIOS.CiudadColumn) End Function Public Sub SetCiudadNull() Me(Me.tableSOCIOS.CiudadColumn) = System.Convert.DBNull End Sub Public Function IsProvinciaNull() As Boolean Return Me.IsNull(Me.tableSOCIOS.ProvinciaColumn) End Function Public Sub SetProvinciaNull() Me(Me.tableSOCIOS.ProvinciaColumn) = System.Convert.DBNull End Sub Public Function IsCPNull() As Boolean Return Me.IsNull(Me.tableSOCIOS.CPColumn) End Function Public Sub SetCPNull() Me(Me.tableSOCIOS.CPColumn) = System.Convert.DBNull End Sub End Class Public Class SOCIOSRowChangeEvent Inherits System.EventArgs Private eventRow As SOCIOSRow Private eventAction As System.Data.DataRowAction Public Sub New(ByVal row As SOCIOSRow, ByVal action As System.Data.DataRowAction) MyBase.New Me.eventRow = row Me.eventAction = action End Sub Public ReadOnly Property Row() As SOCIOSRow Get Return Me.eventRow End Get End Property Public ReadOnly Property Action() As System.Data.DataRowAction Get Return Me.eventAction End Get End Property End Class End Class End Namespace En est e punt o, podem os incluir el ar chiv o MiEsquem a. v b a nuest r o pr oy ect o, o bien com pilar lo desde la línea de com andos o desde el ent or no de desar r ollo. Sin em bar go, no r ealizar em os esa acción. Tan solo com ent ar é que si quisiér am os com pilar desde la línea de com andos el ficher o con el com pilador de Visual Bas c, ut ilizar íam os el f cher o ej ecut able v b c. e x e , que cor r esponde con las iniciales de V isual Basic Com piler , y que por defect o est ar á en la car pet a C: \ WI NDOWS \ Micr osoft . NET\ Fr am ew or k \ v 4. 0. Ahor a que y a sabem os com o gener ar nuest r os Dat aSet t ipados, apr ender em os a usar los en nuest r as apl caciones. Módulo 5 - Capítulo 4 5. Usando los DataSets tipados A cont inuación v er em os un ej em plo del uso de Dat aSet s t ipados ut ilizando Visual St udio 2010. Par a est o nos ser v ir á lo que y a hem os v ist o en la gener ación de un Dat aSet t ipado con Visual St udio 2010. Recor dem os que y a habíam os añadido un elem ent o Dat aSet 1. x sd a nuest r o pr oy ect o, t al y com o se m uest r a en la figur a 1. Da t a Se t 1 .x sd de e j e m plo, a ña dido a l form ula rio, pa ra ut iliza rlo com o Da t a Se t t ipa do Figur a 1 Uso r á pido de nuest r o D a t aSet t ipado El uso de un Dat aSet t ipado, no t iene m uchas difer encias r espect o a un Dat aSet no t ipado. Est e últ im o y a lo hem os v ist o, y el Dat aSet t ipado lo v er em os a cont inuación de for m a pr áct ica. Est e pr im er ej em plo, m uest r a de for m a sencilla, com o t r abaj ar con el esquem a que hem os cr eado y com o hacer lo r ápidam ent e a t r avés de nuest r a aplicación de pr ueba. El código de ej em plo que nos sir v e de t om a de cont act o, es el que se indica a cont inuación: Imports system.data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Establecemos la conexión Dim MiSqlConnection As New SqlConnection("server=.;uid=sa;password=VisualBasic;database=MSDNVideo") ' Declaramos un objeto DataAdapter y le indicamos la conexión Dim MiSqlDataAdapter As New SqlDataAdapter("SELECT * FROM SOCIOS", MiSqlConnection) ' Declaramos un objeto DataSet con el esquema del DataSet tipado Dim MiDtTyped As New DataSet1 ' Rellenamos el DataSet tipado con la información de la tabla del SELECT MiSqlDataAdapter.Fill(MiDtTyped, "SOCIOS") ' Declaramos un objeto para recorrer los datos del DataSet Dim MisDatos As DataSet1.SociosRow ' Recorremos los datos del DataSet tipado y los mostramos For Each MisDatos In MiDtTyped.Socios MessageBox.Show(MisDatos.Nombre & " " & MisDatos.Apellido1 & " " & MisDatos.Apellido2) Next End Sub End Class Nuest r o ej em plo en ej ecución, es el que se puede v er en la figur a 2. Ej e m plo e n e j e cución de l uso se ncillo de Da t a Se t s t ipa dos Figur a 2 A cont inuación v er em os ot r os t ipos de ej ecución de Dat aSet s t ipados m ucho m ás com plej os. At ención e specia l a l Cuadr o de he r r am ie nt as Cuando t r abaj am os con Dat aSet s t ipados com o lo hem os hecho hast a ahor a, habr em os not ado que ent r e ot r as cosas, t enem os las capacidades o posibilidades de t r abaj ar con el Dat aSet com o obj et os. Obv iam ent e, est os obj et os est án incluidos en el Cuadr o de her r am ient as, t al y com o puede v er se en la figur a 3. Com pone nt e s cre a dos por e l e nt orno pa ra t ra ba j a r con Da t a Se t s t ipa dos Figur a 3 Par a t r abaj ar con ellos, podem os ar r ast r ar los sobr e el for m ular io com o hacem os con cualquier cont r ol o com ponent e. Usa ndo las her r a m ient a s aut om át ica s pa r a t r aba j ar con D at aSet s t ipados Aún así, v am os a ar r ast r ar sobr e el for m ular io, un com ponent e Dat aSet com o se indica en la figur a 4. Se le cción de un cont rol Da t a Se t de l Cua dro de he rra m ie nt a s Figur a 4 En est e punt o, r ecor dem os que t enem os nuest r o Dat aSet t ipado o esquem a y a cr eado y que par a usar est e esquem a desde nuest r o obj et o Dat aSet , podem os ut ilizar las her r am ient as del ent or no . NET. Cuando ar r ast r am os el com ponent e Dat aSet sobr e el for m ular io, apar ecer á una v ent ana com o que se m uest r a en la figur a 5, y que nos per m it ir á indicar si se t r at a de un Dat aSet t ipado o un Dat aSet no t ipado. Ve nt a na pa ra a gre ga r un conj unt o de da t os Figur a 5 Por defect o, apar ecer á seleccionada la opción de Conj unt o de dat os con t ipo y el Dat aSet o esquem a que hem os cr eado. Pr esionar em os el bot ón Ace p t a r y de est a m aner a, nuest r o obj et o Dat aSet habr á quedado inser t ado y pr epar ado en el for m ular io, par a ut ilizar el esquem a del Dat aSet indicado. Par a no com plicar lo, he decidido r enom br ar el cont r ol Dat aSet com o dt Set . El Dat aSet quedar á inser t ado en nuest r o ent or no com o se indica en la figur a 6. Cont rol Da t a Se t ( dt Se t ) inse rt a do e n e l form ula rio de e j e m plo Figur a 6 Par a usar el obj et o Dat aSet inser t ado, deber em os acceder a él a t r av és de código, de for m a m uy par ecida a lo que lo hacíam os ant er ior m ent e. Imports system.data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Establecemos la conexión Dim MiSqlConnection As New SqlConnection("server=.;uid=sa;password=VisualBasic;database=MSDNVideo") ' Declaramos un objeto DataAdapter y le indicamos la conexión Dim MiSqlDataAdapter As New SqlDataAdapter("SELECT * FROM SOCIOS", MiSqlConnection) ' Rellenamos el DataSet tipado con la información de la tabla del SELECT MiSqlDataAdapter.Fill(dtSet, "SOCIOS") ' Declaramos un objeto para recorrer los datos del DataSet Dim MisDatos As DataSet1.SociosRow ' Recorremos los datos del DataSet tipado y los mostramos For Each MisDatos In dtSet.Socios MessageBox.Show(MisDatos.Nombre & " " & MisDatos.Apellido1 & " " & MisDatos.Apellido2) Next End Sub End Class El funcionam ient o de nuest r a aplicación de ej em plo, es igual al que hem os v ist o en la figur a 2. Usa ndo D a t a Ada pt er con D at a Set s t ipados Escr ibir em os a cont inuación una pequeña aplicación Window s com o la hem os hecho ant er ior m ent e. Cr ear em os nuest r o esquem a com o lo hem os hecho hast a ahor a y añadir em os dos bot ones com o se indica en la figur a 7.Dat aSet com o se indica en la figur a 4. Bot one s de l e j e m plo a ña didos a la v e nt a na W indow s Figur a 7 A cont inuación añadir em os un Dat aSet al cuál le asignar em os el nom br e del Dat aSet t ipado cor r espondient e al esquem a cr eado, t al y com o se indica en la figur a 8. Da t a Se t t ipa do de l e sque m a a signa do a l obj e t o Da t a Se t Figur a 8 A est e obj et o Dat aSet , le he llam ado dt Set . A cont inuación, añadir em os un com ponent e SqlDat aAdapt er al for m ular io Window s. En est e punt o, apar ecer á una v ent ana com o la que se m uest r a en la figur a 9. Asist e nt e de l SqlDa t a Ada pt e r Figur a 9 Elegir em os la conex ión adecuada y pr esionar em os el bot ón Sig u ie n t e . A cont inuación, el asist ent e nos m ost r ar á una infor m ación com o la que se indica en la figur a 10. Opción pa ra e le gir e l t ipo de com a ndo a ut iliz a r Figur a 10 Elegir em os la pr im er a de las opciones que es la que se indica en la figur a 10, y pr esionar em os nuev am ent e el bot ón Sig u ie n t e . El asist ent e cont inuar á pr esent ándonos v ent anas de infor m ación par a configur ar nuest r o com ponent e SqlDat aAdapt er . Dent r o de est a v ent ana y dent r o de los dat os que deseam os car gar , escr ibir em os la inst r ucción SQL SELECT * FROM SOCI OS com o se indica en la figur a 11. O pción de ge ne ra ción de la s inst ruccione s SQ L Figur a 11 A cont inuación, pr esionar em os el bot ón Sig u ie n t e . De est a m aner a, el asist ent e t er m inar á de cr ear las inst r ucciones necesar ias par a t r abaj ar con el com ponent e SqlDat aAdapt er . Si t odo ha ido cor r ect am ent e, apar ecer á una v ent ana com o la que se indica en la figur a 12. Re sult a dos de la configura ción de l com pone nt e SqlDa t a Ada pt e r Figur a 12 Par a concluir , har em os clic sobr e el bot ón Fin a liz a r . Aut om át icam ent e, en Visual St udio 2010, apar ecer á añadido al for m ular io Window s el com ponent e SqlConnect ion, com o v em os en la figur a 13. Com pone nt e s a ña didos a l form ula rio W indow s Figur a 13 A cont inuación, escr ibir em os el código fuent e de la aplicación, que se encar ga de r ecoger los dat os de la base de dat os, inser tar los en un Dat aSet , par a m odificar los y act ualizar las m odificaciones en la base de dat os. El código fuent e de la aplicación, quedar á com o se det alla a cont inuación: Imports system.data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Dim MiSqlConnection As SqlConnection Dim MiSqlDataAdapter As SqlDataAdapter Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Rellenamos el DataSet tipado con la información de la tabla del SELECT SqlDataAdapter1.Fill(dtSet, "SOCIOS") End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Declaramos un objeto para trabajar con los datos del DataSet Dim MisDatos As DataSet1.SociosRow ' Almacenamos en él, la información del DataSet para ' el NIF = "111111" MisDatos = dtSet.Socios.FindByNIF("111111") ' Modificaremos el campo CP MisDatos.CP = "28022" ' Deshabilitamos como medida de seguridad el botón Button1.Enabled = False End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click If dtSet.HasChanges Then ' El DataSet tiene cambios ' Declaramos un objeto DataSet Dim dtSetModificado As DataSet ' Le pasamos los datos modificados en el DataSet original dtSetModificado = dtSet.GetChanges ' Actualizamos el DataSet que ha cambiado a través del DataAdapter SqlDataAdapter1.Update(dtSetModificado) ' Aceptamos los cambios en el DataSet para ' seguir trabajando con él por ejemplo dtSet.AcceptChanges() ' Mostramos un mensaje en pantalla indicando que ' se han modificado los datos MessageBox.Show("Los cambios del DataSet han sido" & VbCrLf & "actualizados en la base de datos") ' Deshabilitamos como medida de seguridad el botón Button2.Enabled = False Else ' El DataSet no tiene cambios MessageBox.Show("No hay cambios en el DataSet") End If End Sub End Class Nuest r o ej em plo en ej ecución, es el que puede v er se en la figur a 14. Ej e m plo de l Da t a Ada pt e r y Da t a Se t t ipa do e n e j e cución Figur a 14 N ot a: Cuando t r abaj am os con u n com pon en t e Dat aAdapt er , apar ece u n asist en t e. En el caso de elegir la opción de gen er ación de sen t encias SELECT, UPDATE, DELETE e I NSERT, el asist en t e cr ear á a par t ir de la SELECT, esas inst r u ccion es por nosot r os. Dent r o de est e m ism o ej em plo, añada ot r os dos bot ones com o se m uest r a en la figur a 15. Ej e m plo de l Da t a Ada pt e r y Da t a Se t t ipa do e n e j e cución Figur a 15 Est os bot ones nos ser v ir án par a añadir una fila nuev a a nuest r a base de dat os y par a elim inar una fila ex ist ent e ( en nuest r o caso la nuev a fila añadida) . El código fuent e de nuest r a aplicación de ej em plo, es el que se det alla a cont inuación: Imports system.data Imports System.Data.SqlClient Imports System.Xml Public Class Form1 Dim MiSqlConnection As SqlConnection Dim MiSqlDataAdapter As SqlDataAdapter Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Deshabilitamos el botón de Borrar registro, ' porque hasta que no se cree no lo borraremos Button4.Enabled = False ' Rellenamos el DataSet tipado con la información de la tabla del SELECT SqlDataAdapter1.Fill(dtSet, "SOCIOS") End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Declaramos un objeto para trabajar con los datos del DataSet Dim MisDatos As DataSet1.SociosRow ' Almacenamos en él, la información del DataSet para ' el NIF = "111111" MisDatos = dtSet.Socios.FindByNIF("111111") ' Modificaremos el campo CP MisDatos.CP = "28022" ' Deshabilitamos como medida de seguridad el botón Button1.Enabled = False End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click If dtSet.HasChanges Then ' El DataSet tiene cambios ' Declaramos un objeto DataSet Dim dtSetModificado As DataSet ' Le pasamos los datos modificados en el DataSet original dtSetModificado = dtSet.GetChanges ' Actualizamos el DataSet que ha cambiado a través del DataAdapter SqlDataAdapter1.Update(dtSetModificado) ' Aceptamos los cambios en el DataSet para ' seguir trabajando con él por ejemplo dtSet.AcceptChanges() ' Mostramos un mensaje en pantalla indicando que ' se han modificado los datos MessageBox.Show("Los cambios del DataSet han sido" & vbCrLf & "actualizados en la base de datos") ' Deshabilitamos como medida de seguridad el botón Button2.Enabled = False Else ' El DataSet no tiene cambios MessageBox.Show("No hay cambios en el DataSet") End If End Sub Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click ' Añadimos una nueva fila con datos al DataSet tipado dtSet.Socios.AddSociosRow("111112", "María", "Sánchez", "Rodríguez", "1231234", "[email protected]", "C\ San Fernando, 13", "Barcelona", "Barcelo ' Actualizamos los datos a través del DataAdapter SqlDataAdapter1.Update(dtSet) ' Deshabilitamos el botón de añadir datos Button3.Enabled = False ' Habilitamos el botón de eliminar datos Button4.Enabled = True ' Mostramos un mensaje indicando que la ' acción se ha realizado correctamente MessageBox.Show("Registro añadido correctamente") End Sub Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click ' Borramos la fila añadida dtSet.Socios.FindByNIF("111112").Delete() ' Actualizamos los datos a través del DataAdapter SqlDataAdapter1.Update(dtSet) ' Mostramos un mensaje indicando que la ' acción se ha realizado correctamente MessageBox.Show("Registro eliminado correctamente") ' Deshabilitamos el botón de eliminar Button4.Enabled = False End Sub End Class Nuest r o ej em plo en ej ecución es el que se m uest r a en la figur a 16. Ej e m plo de l uso de Da t a Ada pt e r y Da t a Se t t ipa do con t oda s la s a ccione s de inse rción y e lim ina ción de da t os incluida s Figur a 16 Com o v em os, el uso del Dat aSet t ipado, posee gr andes v ent aj as sobr e los Dat aSet s no t ipados, per m it iéndonos t r abaj ar con dat os de for m a m uy r ápida y sencilla. La par t e m ás com plej a quizás, es la pr epar ación del esquem a de dat os, per o una v ez r ealizada est a t ar ea, el t r abaj o con los dat os es asom br osam ent e r ápida y segur a. Introducción Visual Studio 2010 proporciona a los desarrolladores un conjunto de herramientas y asistentes que facilitan enormemente el trabajo y ahorran grandes cantidades de tiempo en el desarrollo de diferentes aplicaciones. De los asistentes o herramientas que nos proporcionan mayor rendimiento en el entorno de desarrollo rápido de Microsoft, está la que nos permite trabajar con fuentes de datos como los datos de una aplicación típica maestro detalle. Entre otras cosas, nos centraremos en esta acción, que será la que veremos en detalle a continuación. Módulo 5 - Capítulo 5 ● 1. ¿Que son los datos maestro detalle? ● 2. Configurando la fuente de datos ● 3. Preparando el origen de datos ● 4. Incrustando los datos maestro detalle ● 5. Manipulando los datos maestro detalle Módulo 5 - Capítulo 5 1. ¿Qué son los datos Maestro Detalle? El desar r ollador de aplicaciones que debe t r abaj ar con dat os y fuent es de dat os r elacionadas ent r e sí, encuent r a con fr ecuencia pr oblem as de desar r ollo en aplicaciones con dat os int er r elacionados. Adem ás, est e t ipo de aplicaciones, consum en gr an par t e del t iem po de desar r ollo y son por lo gener al, acciones r epet it iv as. Supongam os com o ej em plo gener al, la t abla Socios de un v ideoclub. Adem ás, r elacionem os los socios del v ideoclub, con una t abla Alquiler es, par a saber si un socio det er m inado t iene películas alquiladas, y en ese caso, saber cuáles. Est e sencillo ej em plo, es un clar o ex ponent e de una aplicación que r elaciona dat os m aest r o det alle. Am bas t ablas deben est ar r elacionadas par a r ecopilar la infor m ación que se necesit e en un m om ent o dado. Los dat os m aest r os ser ían ex puest os por los socios del v ideoclub, m ient r as que los dat os det alle est ar ían r elacionados con los dat os de los alquiler es de los socios. En nuest r o caso, v am os a cam biar las palabr as m aest r o y det alle por padr e e hij o, y a par t ir de ahor a, nos r efer ir em os a padr e com o la t abla Socios, e hij o com o la t abla Alquiler es. De est a for m a, ubicar em os sin pr oblem as am bos concept os dent r o del ent or no de Visual St udio 2010, y a que ést e t iene alguna liger a connot ación que podr ía infundir nos a er r or com o obser v ar á m ás adelant e. Por suer t e, Visual St udio 2010 nos pr opor ciona un conj unt o de her r am ient as, que hace que r ealizar una aplicación Window s con t odas las car act er íst icas de una aplicación m aest r o det alle, sea un aut ént ico j uego de niños, que nos llev ar á apr ox im adam ent e un m inut o de nuest r o t iem po com o m ucho. ¿No m e cr ee?. Cont inúe el capít ulo, y se sor pr ender á de lo que Visual St udio 2010 puede hacer por ust ed. Módulo 5 - Capítulo 5 2. Configurando la fuente de datos Tr abaj ar con fuent es de dat os r equier e com o t ar ea inicial, que t engam os list o y pr epar ado un or igen de fuent es de dat os v álido. Par a est a t ar ea, deber em os configur ar la fuent e de dat os que v am os a ut ilizar , algo que v am os a apr ender a hacer a cont inuación. Configur ando el or igen de la fuent e de dat os I niciar em os una nuev a aplicación Window s con Visual St udio 2010 y seleccionar em os el m enú D a t os > M ost r a r or íg e n e s d e d a t os com o se indica en la figur a 1. M e nú pa ra m ost ra r los oríge ne s de da t os Figur a 1 En est e punt o, apar ecer á una v ent ana com o la que se m uest r a en la figur a 2. Ve nt a na de oríge ne s de da t os Figur a 2 Com o podem os apr eciar , la v ent ana no t iene por defect o ningún or igen de dat os asignado, adem ás, est a v ent ana inicialm ent e, no est á anclada a ningún sit io del ent or no. Par a sit uar la en un lugar específico del ent or no, haga clic sobr e la v ent ana y ar r ást r ela sobr e la par t e en la que desee sit uar la, com o se indica por ej em plo, en la figur a 3. La v e nt a na oríge ne s de da t os pode m os sit ua rla dónde de se e m os de nt ro de Visua l St udio 2 0 1 0 Figur a 3 En est e punt o, la v ent ana de or ígenes de dat os, quedar á anclada en el ent or no de desar r ollo, com o se m uest r a en la figur a 4. La v e nt a na oríge ne s de da t os a ncla da e n Visua l St udio 2 0 1 0 Figur a 4 Cada uno, puede sit uar est a v ent ana dónde consider e opor t uno. En m i caso la he sit uado ent r e las v ent anas del Ex plor ador de soluciones y de Pr opiedades, per o podem os sit uar la dónde consider em os opor t uno. Sobr e la configur ación del or igen de dat os, haga clic sobr e la opción Agr egar nuev o or igen de dat os. . . com o se indica en la figur a 5. Opción pa ra a gre ga r un nue v o orige n de da t os Figur a 5 Apar ecer á una v ent ana com o la que se m uest r a en la figur a 6 en la cuál indicar em os el lugar de dónde la aplicación obt endr á los dat os, y que en nuest r o caso ser á de una Base de dat os. Com o t ipo de orige n de da t os e le gire m os una Ba se de da t os Figur a 6 Una v ez seleccionado la opción de Base de dat os com o t ipo de or igen de dat os, pr esionar em os el bot ón Sig u ie n t e . En la siguient e v ent ana, elegir em os la conex ión de la base de dat os que v am os a ut ilizar , o pr esionar em os sobr e el bot ón N u e v a con e x ión . . . sino t enem os seleccionada la conex ión que quer em os ut ilizar . En la figur a 7, podem os v er com o hem os est ablecido la conex ión con nuest r a fuent e de dat os, que ut ilizar em os en nuest r o ej em plo de cr eación de la aplicación de acceso a dat os m aest r o det alle. Ve nt a na dónde e le gim os la cone x ión de da t os Figur a 7 A cont inuación, har em os clic en el bot ón Sig u ie n t e . En la nuev a v ent ana que apar ece ahor a dent r o del asist ent e par a la cr eación del or igen de dat os, indicar em os el nom br e de la cadena de conex ión que cr ear em os. En nuest r o caso, no m odificar em os el nom br e de la cadena de conex ión, dej ándola por defect o com o se m uest r a en la figur a 8. Asigna m os un nom bre pa ra e l nom bre de la ca de na de cone x ión Figur a 8 A cont inuación, har em os clic sobr e el bot ón Sig u ie n t e . En est e punt o, el asist ent e se conect a a la base de dat os par a r ecuper ar la infor m ación de la base de dat os y m ost r ar la en la v ent ana del asist ent e com o se m uest r a en la figur a 9. Ve nt a na con los obj e t os de la ba se de da t os se le cciona da Figur a 9 A cont inuación, despliegue el obj et o Ta b la s y seleccione las t ablas Alquiler es y Socios com o se indica en la figur a 10. Se le cción de los obj e t os de la ba se de da t os se le cciona da Figur a 10 Una v ez que hem os seleccionado los obj et os de la base de dat os, har em os clic sobr e el bot ón Fin a liz a r par a que el asist ent e concluy a las opciones añadidas al asist ent e. La v ent ana del or igen de dat os, quedar á ahor a configur ado de una for m a sim ilar a la que se pr esent a en la figur a 11. Ve nt a na de orige n de da t os con la configura ción a ña dida Figur a 11 A par t ir de aquí, deber em os pr epar ar las t ablas del or igen de dat os par a que se com por t en com o aut ént icos dat os e infor m aciones m aest r o det alle. Est o es lo que v er em os en el siguient e m ódulo. Módulo 5 - Capítulo 5 3. Preparando el origen de datos Ya hem os apr endido a añadir nuest r o or igen de dat os, y ahor a apr ender em os a pr epar ar lo par a poder ut ilizar lo post er ior m ent e en la aplicación Window s. La pr epar ación del or igen de dat os, nos per m it ir á seleccionar que t abla o dat os quer em os que act úen com o m aest r o y cuales com o det alle, o dicho de ot r a for m a, que dat os quer em os que sean padr e y cuales hij o. Nuest r o obj et iv o pr incipal es m ost r ar la t abla Alquiler es com o t abla hij o y la t abla Socios com o padr e de la t abla ant er ior . Pr epar ar em os e incr ust ar em os pr im er o la t abla Socios dent r o del for m ular io Window s com o Det alle de la infor m ación, y post er ior m ent e inser t ar em os la t abla Alquiler es dent r o del for m ular io. Por últ im o, asignar em os alguna r elación que per m it a t r abaj ar con las dos t ablas en nuest r o for m ular io Window s sin per der la conex ión ent r e am bas t ablas y per m it iéndonos acceder a la infor m ación que nos pr opor ciona dicha r elación. Pr epar ando la t abla padr e Lo pr im er o que har em os ser á pr epar ar la t abla padr e par a poder la añadir al for m ular io Window s. Por esa r azón, har em os clic sobr e la t abla Socios de la v ent ana de Or ígenes de dat os com o se indica en la figur a 1. Ta bla Socios de la v e nt a na de oríge ne s de da t os Figur a 1 En la v ent ana de Or ígenes de dat os y en concr et o con la t abla Socios desplegada, cent r ar em os nuest r a at ención en el cam po N I F com o se indica en la figur a 2. Ca m po NI F de la t a bla Socios Figur a 2 Pulse sobr e la list a desplegable que apar ece a la der echa del cam po N I F y seleccione la opción Label com o se indica en la figur a 3. List a de sple ga ble con la opción La be l se le cciona da com o ca m po de la t a bla de sple ga da Figur a 3 En est e caso, la v ent ana de Or ígenes de dat os quedar á infor m ada t al y com o se indica en la figur a 4. Ca m po NI F m odifica do e n la v e nt a na de Oríge ne s de da t os Figur a 4 A cont inuación, har em os clic sobr e la t abla Socios com o se indica en la figur a 5, y post er ior m ent e pr esionar em os sobr e la list a desplegable que apar ece a la der echa de la t abla. Ta bla Socios se le cciona da e n la v e nt a na de Oríge ne s de da t os Figur a 5 Si hacem os clic sobr e la list a desplegable, apar ecer á una list a de opciones o posibilidades, par a indicar cóm o quer em os que sean los cam pos de la t abla seleccionada con r espect o a que t ipo de cont r oles quer em os que sean. Est o es lo que se indica en la figur a 6. List a de sple ga ble de la t a bla Socios de la v e nt a na de Oríge ne s de da t os Figur a 6 Por defect o, una t abla queda det er m inada con un icono que r epr esent a el cont r ol Dat aGr idView , aunque se puede m odificar la r epr esent ación que deseam os t engan los dat os dent r o de un for m ular io seleccionando cualquier a de las opciones que t enem os de la list a desplegable. Est as opciones pueden ser cualquier a de las siguient es: Repr esent a los dat os v olcados dent r o de un cont r ol Dat aGr idView Repr esent a los dat os v olcados dent r o de cont r oles est ándar com o Tex t Box u ot r os cont r oles par a r eflej ar la com o Det alle de la infor m ación No r epr esent a ningún cont r ol com o t ipo de cont r ol de v olcado de dat os En el caso de la t abla Socios que usar em os com o t abla padr e, cam biar em os la r epr esent ación por defect o de Dat aGr idView par a indicar le que nos r epr esent e la infor m ación en cont r oles, t al y com o se indica en la figur a 7. Ta bla Socios se le cciona da e n la v e nt a na de Oríge ne s de da t os com o De t a lle Figur a 7 Ahor a que t enem os la t abla m aest r a y a pr epar ada, pasar em os a pr epar ar la t abla hij a. Pr epar ando la t abla hij a Ahor a que y a t enem os pr epar ada la t abla t abla padr e, pr epar ar em os la t abla hij a de los alquiler es de las películas de v ideo, par a poder usar su infor m ación dent r o del for m ular io Window s. Por esa r azón, haga clic sobr e la t abla Alquiler es de la v ent ana de Or ígenes de dat os com o se indica en la figur a 8. Ta bla Alquile re s de la v e nt a na de oríge ne s de da t os Figur a 8 Dent r o de la v ent ana de Or ígenes de dat os y en concr et o de la t abla Alquiler es desplegada, cent r ar em os nuest r a at ención en el cam po Alq u ile r I D y SocioN I F com o se indica en la figur a 9. Ca m pos Alquile rI D y SocioNI F de la t a bla Alquile re s Figur a 9 Sobr e el cam po Alq u ile r I D y SocioN I F, har em os una pequeña m odificación. Pulse sobr e la list a desplegable que apar ece a la der echa del cam po Alq u ile r I D y SocioN I F y seleccione la opción Label com o se indica en la figur a 10. List a de sple ga ble de opcione s de un ca m po de la t a bla de sple ga da Figur a 10 De est a m aner a, el cam po Alq u ile r I D y SocioN I F quedar án m odificados en la v ent ana Or ígenes de dat os com o se indica en la figur a 11. Ca m po Alquile rI D y SocioNI F m odifica dos e n la v e nt a na de Oríge ne s de da t os Figur a 11 A cont inuación, har em os clic sobr e la t abla Alquiler es com o se indica en la figur a 12, y post er ior m ent e pr esionar em os sobr e la list a desplegable que apar ece a la der echa de la t abla. Ta bla Alquile re s se le cciona da e n la v e nt a na de Oríge ne s de da t os Figur a 12 Nos asegur ar em os que est á seleccionada la opción Dat aGr idView que es la que apar ece por defect o. Est o es lo que se indica en la figur a 13. En la t a bla Alquile re s, nos a se gura re m os de se le cciona r la opción Da t a GridVie w Figur a 13 Una v ez que t enem os las t abla m aest r a y det alle pr epar adas par a ut ilizar las, las añadir em os al for m ular io Window s par a que t engan el funcionam ient o esper ado. Módulo 5 - Capítulo 5 4. Incrustando los datos maestro detalle Ya sabem os com o cr ear un or igen de dat os, t am bién sabem os com o pr epar ar los dat os m aest r o y det alle, y por últ im o, lo que nos queda es inser t ar esos dat os en el for m ular io, y r elacionar t odos sus dat os par a que funcionen de la for m a esper ada. A cont inuación, v er em os com o llev ar a cabo est a t ar ea y apr ender em os a hacer lo posible de for m a m uy r ápida y sencilla. I ncr ust ando la t abla padr e en el for m ular io Nuest r a pr im er a acción, ser á incr ust ar en el for m ular io los dat os o t abla padr e, que en nuest r o caso es la for m ada por la t abla Socios. Par a sit uar los dat os de la t abla Socios dent r o de un for m ular io y en concr et o com o una infor m ación de det alle, bast ar á con ar r ast r ar y solt ar la t abla Socios sobr e el for m ular io com o se indica en la figur a 1. Pa ra pre se nt a r la inform a ción com o de t a lle , a rra st ra re m os la t a bla Socios de la v e nt a na Oríge ne s de da t os sobre e l form ula rio W indow s Figur a 1 Obser v ar em os que Visual St udio 2010, gener ar á por nosot r os un conj unt o de com ponent es y cont r oles, que por defect o t endr á una apar iencia sim ilar a la que se pr esent a en la figur a 2. Cont role s y Com pone nt e s de la t a bla m a e st ra a ña didos a l form ula rio W indow s Figur a 2 Obser v e por un m om ent o, que el cam po N I F que declar am os com o Label en la v ent ana de Or ígenes de dat os, apar ece com o t al en el for m ular io, t al y com o se indica en la figur a 3. Ca m po NI F de la t a bla , re pre se nt a do com o un cont rol La be l e n e l form ula rio W indow s Figur a 3 Si ej ecut am os nuest r a aplicación, obser v ar em os que est a act úa com o una t ípica aplicación de acceso a dat os que nos per m it e nav egar a t r av és de los cam pos de la t abla Socios, t al y com o se indica en la figur a 4. Aplica ción e n e j e cución de la t a bla de de t a lle incrust a da e n e l form ula rio W indow s Figur a 4 A cont inuación, inser t ar em os en el for m ular io la t abla Alquiler es y r elacionar em os am bas t ablas par a que se m uest r en los dat os r elacionados, dent r o del for m ular io Window s. I ncr ust ando la t abla hij a en el for m ular io Ya t enem os la t abla padr e inser t ada en nuest r o for m ular io Window s. Nuest r a segunda acción, ser á la de incr ust ar en el for m ular io los dat os o t abla hoj a, que en nuest r o caso es la for m ada por la t abla Alquiler es, la cuál adem ás, posee una r elación ent r e cam pos con la t abla Socios inser t ada ant er ior m ent e. Par a llev ar a cabo est a acción ar r ast r ar em os y solt ar em os la t abla Alquiler es sobr e el for m ular io com o se indica en la figur a 5. Pa ra pre se nt a r la inform a ción de la t a bla Alquile re s, a rra st ra re m os la t a bla de la v e nt a na Oríge ne s de da t os sobre e l form ula rio W indow s Figur a 5 Obser v e que Visual St udio 2010, gener a por nosot r os m ás com ponent es y cont r oles, que por defect o t endr á una apar iencia sim ilar a la que se pr esent a en la figur a 6. Cont role s y Com pone nt e s de la t a bla m a e st ra y de t a lle a ña didos a l form ula rio W indow s Figur a 6 Com o podem os obser v ar , el ent or no de t r abaj o ha hecho por nosot r os el t r abaj o m ás com plej o par a r epr esent ar los dat os de for m a r ápida y sencilla. El esquem a de dat os t ipados, apar ecía y a en nuest r o pr oy ect o cuando asignam os el cor r espondient e or igen de dat os. Ahor a lo que ha ocur r ido, es que al ar r ast r ar y solt ar la t abla padr e Socios de la v ent ana de Or ígenes de dat os, en el ent or no se ha añadido un com ponent e de nom br e MSDNVideoDat aSet que es el que per m it ir á r elacionar el Dat aSet t ipado con nuest r os dat os. Est e com ponent e ser á usado por la r elación m aest r o det alle de las dos t ablas añadidas al for m ular io. En la figur a 7, podem os v er el esquem a añadido a nuest r o pr oy ect o, y el com ponent e del que est am os hablando. Esque m a de l Da t a Se t t ipa do a ña dido a l proy e ct o y su com pone nt e de re la ción Figur a 7 Ej ecut e la aplicación y obser v e el com por t am ient o de la m ism a. Obser v ar á por lo t ant o, que los dat os ent r e det alle y m aest r a, no est án r elacionados. Si nav egam os a t r av és de los dat os de det alle a t r av és del obj et o SociosBindingNav igat or , el cont r ol Dat aGr idView no r epr esent a la r elación de los dat os seleccionados. Est o es lo que se m uest r a en la figur a 8. Ej e cución de la a plica ción confirm a ndo que los da t os m ost ra dos no e st á n re la ciona dos Figur a 8 A cont inuación, la t ar ea que nos queda par a com plet ar el cor r ect o funcionam ient o de nuest r a aplicación, es la de r elacionar la t abla det alle y la t abla m aest r a ent r e sí, par a que los dat os que se m uest r an en la aplicación, est én r elacionados ent r e sí. Relacionando la t abla padr e con la t abla hij a La t ar ea m ás sencilla es la de r elacionar la t abla det alle con la t abla m aest r a. Es una t ar ea sencilla, por que Visual St udio 2010 nos pr opor ciona las her r am ient as necesar ias par a sim plificar al m áx im o est a t ar ea. Par a llev ar a cabo est a t ar ea, haga clic sobr e el cont r ol Dat aGr idView que cor r esponde a los dat os de la t abla m aest r a, y acceda a la v ent ana de Pr opiedades. Dent r o de la v ent ana de Pr opiedades, acceda a la pr opiedad Dat aSour ce com o se indica en la figur a 9. Propie da d Da t a Source de l cont rol Da t a GridVie w de la inform a ción m a e st ra Figur a 9 Despliegue est a pr opiedad, y de la list a desplegable que apar ece, seleccione la opción FK_ Alq u ile r e s_ Socios com o se indica en la figur a 10. Asigna ción de la cla v e de re la ción e nt re la s t a bla s Figur a 10 Cuando se asigna el cam po de r elación de las t ablas, dent r o de la aplicación se añade est a r elación par a que cuando nav eguem os ent r e los dat os de la t abla Socios apar ezca t oda la infor m ación de la t abla Alquiler es r elacionada con la t abla Socios. Est o de lo que hablam os, est á supedit ado por el com ponent e FK_Alquiler es_SociosBindingSour ce que es lo que se indica en la figur a 11. Cont role s y com pone nt e s incluido e l de re la ción e nt re t a bla s, a ña didos a l form ula rio W indow s Figur a 11 Par a finalizar , ej ecut ar em os nuest r a aplicación y com pr obar em os que el funcionam ient o de est a, incluida la r elación ent r e t ablas, funciona com o esper ábam os. En la figur a 12, podem os obser v ar el com por t am ient o de nuest r a aplicación en ej ecución. Aplica ción e n e j e cución, m ost ra ndo la corre ct a re la ción e nt re la s t a bla s Figur a 12 Módulo 5 - Capítulo 5 5. Manipulando los datos maestro detalle Obv iam ent e, los dat os m aest r o det alle no nos sir v e únicam ent e par a inser t ar las t ablas de dat os en un for m ular io, m ost r ar los y nav egar por ellos. Adem ás de est o, podem os t am bién m anipular los dat os m aest r o det alle, m odificar los, act ualizar los, bor r ar los, sin hacer ninguna acción adicional. El cont r ol BindingNav igat or y a pr opor ciona t odas las car act er íst icas necesar ias par a r ealizar est as acciones. Podem os per sonalizar el cont r ol par a per m it ir o denegar est as acciones. Adem ás, dent r o de la v ent ana de Or ígenes de dat os, podem os seleccionar difer ent es cam pos de las t ablas y cam biar el t ipo de cont r ol en el que quer em os r epr esent ar sus dat os. A cont inuación v er em os un br ev e ej em plo de com o m anipular dat os par a que nos sir v a de apr endizaj e de cóm o hacer est o posible. M odificando dat os Ej ecut e la aplicación de ej em plo que hem os diseñado hast a ahor a y sit úese en alguno de sus cam pos. Cent r ándonos en la infor m ación de la t abla Socios, cam biar em os un cam po det er m inado, com o el que se m uest r a en la figur a 1. M odifica re m os e l v a lor de un ca m po pa ra que nos sirv a de e j e m plo Figur a 1 Act o seguido, cuando hay am os r ealizado la m odificación, har em os clic sobr e la opción de Guar dar dat os, t al y com o se m uest r a en la figur a 1. Opción de l cont rol BindingNa v iga t or pa ra gua rda r los da t os m odifica dos Figur a 2 Com o v em os, la m anipulación de dat os es r ealm ent e sencilla y en la r elación de dat os m ost r ada, no t iene por qué pr esent ar nos ninguna dificult ad. I nser t ando y elim inando dat os Si quer em os agr egar dat os, deber em os hacer clic sobr e la opción Agr egar nuev o del cont r ol BindingNav igat or com o se m uest r a en la figur a 3. Aña dir un re gist ro nue v o e s re a lm e nt e se ncillo Figur a 3 De la m ism a m aner a funciona el m ecanism o par a elim inar un r egist r o, t al y com o se m uest r a en la figur a 4. Elim ina r un re gist ro de form a rá pida Figur a 4 Recuer de pr esionar el icono si quier e que los cam bios y m odificaciones r ealizadas se m ant engan. Pulsando sobr e ese icono, la acción de m anipulación de dat os se lanza cont r a la base de dat os. Est e m ódulo pr esent a al alum no los fundam ent os de los Ser vicios Web y las Ar quit ect ur as Or ient adas a Ser vicios ( SOA) . Tr as una int r oducción a los ser vicios Web y sus concept os asociados se ve la for m a de cr ear y consum ir ser vicios Web. Par a la cr eación de un ser vicio ut ilizar em os Visual St udio 2010. Si desea m ás infor m ación sobr e est a her r am ient a puede dir igir se al cur so de Desar r ollo de Aplicaciones Web con ASP.NET. Le cción 1 : I n t r odu cción a los se r vicios W e b ¿Qué son los ser vicios Web? Com unicación ent r e com ponent es SOAP Br eve hist or ia de SOAP Las bases t ecnológicas de SOAP Descubr im ient o de ser vicios: WSDL y UDDI Le cción 2 : Cr e a ción de se r vicios W e b Nuest r o pr im er ser vicio Web Cr ear un pr oyect o de t ipo ser vicio Web con Visual St udio 2010 Cr ear un ser vicio Web usando un solo ficher o Elim inar ficher os de un pr oyect o Analizando el cont enido de un ser vicio Web At r ibut os aplicables a los ser vicios Web Definición de la clase a usar en el ser vicio Web Añadir m ét odos par a usar los en el ser vicio Web Pr obar nuest r o ser vicio Web Le cción 3 : Con su m o de se r vicios W e b Desde una aplicación de Windows Aloj ar el ser vicio Web en un ser vidor local Act ivar el ser vidor Web par a usar con un dir ect or io local Cr ear un pr oyect o Windows par a usar el ser vicio Web Añadir una r efer encia par a acceder al ser vicio Web Acceder al ser vicio Web desde el código ¿Que es lo que puede fallar ? Veam os lo que nos dice la docum ent ación de Visual St udio sobr e los ser vicios Web ( o ser vicios Web XML que es com o los denom ina Micr osoft ) : "Un ser vicio Web XML es una ent idad pr ogr am able que pr opor ciona un elem ent o de funcionalidad det er m inado, com o lógica de aplicación, al que se puede t ener acceso desde diver sos sist em as pot encialm ent e dist int os m ediant e est ándar es de I nt er net m uy ext endidos, com o XML y HTTP." Un poco m ás clar o queda lo que cont inúa en el siguient e pár r afo de la m encionada ayuda: "Un ser vicio Web XML puede ser ut ilizado int er nam ent e por una aplicación o bien ser expuest o de for m a ext er na en I nt er net por var ias aplicaciones. Dado que a t r avés de una int er faz est ándar es posible el acceso a un ser vicio Web XML, ést e per m it e el funcionam ient o de una ser ie de sist em as het er ogéneos com o un conj unt o int egr ado." ¿Mej or ? Sim plificando, y siendo algo m ás pr áct icos, podem os definir un ser vicio Web XML com o una clase a la que podem os acceder ut ilizando est ándar es de I nt er net . Com o es de suponer , el t ener que ut ilizar esos est ándar es de com unicación de I nt er net es por que esa "clase" est á aloj ada en un ser vidor de I nt er net , es decir , un ser vicio Web es una clase que est á aloj ada en la Web y que podem os acceder a ella m ediant e cier t os est ándar es com o XML, que a su vez ut iliza ot r o est ándar : SOAP, ( Sim ple Obj ect Access Pr ot ocol) , que es el lenguaj e que define cóm o nos com unicar em os con el ser vicio Web. Ant es de pasar a ver ej em plos pr áct icos sobr e cóm o cr ear y ut ilizar ser vicios Web ut ilizando Visual St udio 2010, veam os un poco la hist or ia de por qué finalm ent e los ser vicios Web son lo que son y cóm o nos facilit an t oda la com unicación a t r avés de la r ed, ya sea local o global. ¿Qu é son los se r vicios W e b? Un poco de hist or ia: m odelos de desar r ollo Com u n ica ción e n t r e com pon e n t e s SOAP Br eve hist or ia de SOAP Las bases t ecnológicas de SOAP Descubr im ient o de ser vicios: WSDL y UDDI La expr esión "Ser vicio Web" se oye con fuer za desde hace unos años en el ám bit o del desar r ollo de aplicaciones e incluso en am bient es poco t écnicos y de dir ección. Lo cier t o es que no se t r at a de un concept o t an novedoso com o cabr ía esper ar y las innovaciones que conlleva no son t ant o t ecnológicas, com o concept uales. En est a lección explicar em os desde un punt o de vist a no- t écnico los concept os r elacionados con los Ser vicios Web, cóm o funcionan, de dónde vienen y a dónde van. Un poco de hist or ia : m ode los de de sa r r ollo El hecho de poder com unicar com ponent es de soft war e ent r e sí t iene una enor m e im por t ancia. Hast a no hace t ant os años er a m uy t ípico hacer aplicaciones de una sola pieza, "m onolít icas": Figur a 6 .1 . Aplicación " m onolít ica" aunque dist r ibuida Est os pr ogr am as podían acceder a un sist em a gest or de dat os a t r avés de la r ed, per o t oda la lógica del fluj o de dat os, la segur idad y las int er acciones con las per sonas se encont r aban en el or denador del usuar io en for m a de un gr an ej ecut able. Se suelen conocer t am bién com o "fat client s". La sit uación descr it a no es la ideal ya que im plica pr oblem as de t oda índole a la hor a de inst alar las aplicaciones y sobr e t odo cuando se m odifican o act ualizan ( m ant enim ient o com plej o y engor r oso) . Una m et odología de desar r ollo m ucho m ej or aunque m ás labor iosa a la hor a de pr ogr am ar es el m odelo Client e- Ser vidor en t r es capas: Figur a 6 .2 . Aplicación Client e Ser vidor en t r es capas En est e m odelo t oda la lógica de los dat os, su validación, los per m isos, et c., r esiden en un ser vidor int er m edio y son ut ilizados por t odos los client es a t r avés de una r ed. En est e caso en el or denador del usuar io lo único que hay es una capa de pr esent ación que se ocupa básicam ent e de r ecoger y r ecibir dat os, es decir , act úa de int er m ediar io ent r e el usuar io y las r eglas de negocio r esident es en la capa int er m edia. Est e m odelo es m ás eficient e y est á m uy evolucionado r espect o al ant er ior per o aún se puede ir m ás allá. La ar quit ect ur a de desar r ollo en n- capas ( n- t ier que dicen los anglosaj ones) lleva el concept o client e- ser vidor un paso hacia adelant e, dividiendo la capa int er m edia en m uchas ot r as capas especializadas cada una de las cuales puede r esidir en un ser vidor difer ent e: Figur a 6 .3 . Ar quit ect ur a de desar r ollo basada en com ponent es En est e m odelo exist e una gr an var iedad de com ponent es especializados en t ar eas específicas com o la validación de dat os, la aut ent icación y segur idad o el acceso a dat os. Dichos com ponent es deben t r abaj ar unos con ot r os com o piezas de un m ecanism o, gest ionando la infor m ación que cir cula ent r e el usuar io y el ser vidor de dat os. La belleza de est e m odelo r adica en que cada uno de ellos ( o cada gr upo de ellos) puede r esidir en un ser vidor difer ent e, siendo t r anspar ent e su ubicación par a los client es que los ut ilizan. Ello aum ent a m ucho la escalabilidad de las aplicaciones, pues bast a con añadir nuevos ser vidor es e inst alar los com ponent es en ellos par a poder at ender m ás pet iciones. Por ot r a par t e, y est o es m uy int er esant e t am bién, m ient r as sus int er faces de pr ogr am ación sean las m ism as, es posible sust it uir cualquier com ponent e por ot r o act ualizado o que act úe de m aner a dist int a par a cor r egir er r or es o cam biar el m odo de t r abaj o de la aplicación global, y t odo ello sin que los client es sean conscient es de ello. Obviam ent e est o ofr ece m ás vent aj as aún ya que, por ej em plo, no es necesar io r einst alar la aplicación en cada client e, sino que bast a con sust it uir un com ponent e en un único lugar y aut om át icam ent e t odos los usuar ios t endr án su aplicación act ualizada. El concept o de Ar quit ect ur a Or ient ada a Ser vicios o SOA se basa en el uso de est e t ipo de com ponent es que suplen las necesidades de una o var ias aplicaciones, son independient es ent r e sí y t r abaj an independient em ent e del sist em a oper at ivo o la plat afor m a. Aunque m uchos pr ogr am ador es piensan que SOA est á r elacionado únicam ent e con los Ser vicios Web lo cier t o es que se pueden conseguir ar quit ect ur as SOA con ot r as t ecnologías com o ver em os. Exist en diver sas dificult ades t écnicas a la hor a de llevar a la pr áct ica las ar quit ect ur as or ient adas a ser vicios. Ent r e ést as est án la com unicación ent r e las dist int as capas y com ponent es que const it uyen la aplicación, la gest ión de pet iciones y el balanceado de car ga ent r e ser vidor es cuando un m ism o com ponent e r eside en var ios de ellos ( par a aplicaciones m uy gr andes con m uchos client es) , la gest ión de t r ansacciones ent r e com ponent es y algunas ot r as cosas m ás. Exist e la posibilidad de escr ibir un pr ot ocolo de com unicaciones pr opio que se ocupe de t odas est as cuest iones, per o por supuest o se t r at a de una opción m uy poco r ealist a dada la com plej idad que conllevar ía. Par a r esponder a est as necesidades de los pr ogr am ador es, diver sos fabr icant es y asociaciones de la indust r ia cr ear on ser vicios y pr ot ocolos específicos or ient ados a la int er acción dist r ibuida de com ponent es. Aunque exist e una gr an var iedad, de t odos ellos los m ás im por t ant es sin duda son: • D COM ( Dist r ibut ed Com m on Obj ect Model) , la pr opuest a de Micr osoft , ligada a sus sist em as Windows. Se t r at a de algo m ás que un pr ot ocolo de invocación r em ot a de pr ocedim ient os ( RPC) ya que su últ im a encar nación, COM+ , incluye ser vicios avanzados par a balanceado de car ga, gest ión de t r ansacciones o llam adas asíncr onas. Los par ám et r os son t r ansm it idos a t r avés de la r ed m ediant e un for m at o binar io pr opio llam ado NDR ( Net wor k Dat a Repr esent at ion) . • RM I ( Rem ot e Met hod I nvocat ion) , es la m et odología de llam ada r em ot a a pr ocedim ient os de Java. No se cent r a en la definición de int er faces par a com pat ibilidad binar ia de com ponent es, ni en ot r os concept os avanzados, y se basa en la exist encia de un client e y un ser vidor que act úan de int er m ediar ios ent r e los com ponent es que se quier en com unicar . Es una t ecnología bast ant e sim ple que es fácil de ut ilizar par a aplicaciones básicas. • CORBA ( Com m on Obj ect Request Br oker Ar chit ect ur e) . Se t r at a de una ser ie de convenciones que descr iben cóm o deben com unicar se los dist int os com ponent es, cóm o deben t r ansfer ir los dat os de las llam adas y sus r esult ados o cóm o se descr iben las int er faces de pr ogr am ación de los com ponent es par a que los dem ás sepan cóm o ut ilizar los. Fue desar r ollado por el OMG ( Obj ect Managem ent Gr oup) en la segunda m it ad de la década de los '90 y es el m odelo que m ás éxit o ha t enido en el m undo UNI X. Su m ét odo de em paquet ado y t r ansm isión de dat os a t r avés de la r ed se llam a CDR (Com m on Dat a r epr esent at ion) . Exist en diver sas im plem ent aciones de dist int os fabr icant es. Est os m odelos son buenos y m uy eficient es, cum pliendo bien su t r abaj o per o t ienen algunas lim it aciones im por t ant es siendo las pr incipales las siguient es: Es difícil la com unicación ent r e los dist int os m odelos Est án ligados a plat afor m as de desar r ollo específicas, lo que dificult a la com unicación ent r e ellas Su ut ilización a t r avés de I nt er net se com plica debido a cuest iones de segur idad de las que enseguida hablar em os. Exist en en el m er cado puent es CORBA/ DCOM que per m it en la com unicación ent r e com ponent es COM y com ponent es CORBA, per o su ut ilización es difícil y añaden una nueva capa de com plej idad a las aplicaciones adem ás de dism inuir su r endim ient o. Las expect at ivas act uales r espect o a los com ponent es han aum ent ado. Al igual que podem os usar un navegador web par a acceder a cualquier página independient em ent e del sist em a oper at ivo del ser vidor en que r esida, ¿por qué no podr íam os invocar m ét odos de com ponent es a t r avés de la r ed independient em ent e de dónde se encuent r en, del lenguaj e en el que est én escr it os y de la plat afor m a de com put ación en la que se ej ecut en?. Est o es pr ecisam ent e lo que ofr ecen los Ser vicios Web. Gr acias a ellos se der r iban la ant iguas divisiones r esult ant es de los m odelos de com ponent es descr it os, y la int egr ación de las aplicaciones, la ubicuidad de sus com ponent es y su r eut ilización a t r avés de la r ed se convier t en en una r ealidad. La t ecnología que est á det r ás de t odo ello se llam a SOAP ( j abón en inglés) . Est e acr ónim o ( Sim ple Obj ect Access Pr ot ocol) descr ibe un concept o t ecnológico basado en la sencillez y la flexibilidad que hace uso de t ecnologías y est ándar es com unes par a conseguir las pr om esas de la ubicuidad de los ser vicios, la t r anspar encia de los dat os y la independencia de la plat afor m a que según hem os vist o, se hacen necesar ios en las aplicaciones act uales. Br e v e hist or ia de SOAP SOAP em pezó com o un pr ot ocolo de invocación r em ot a basado en XML diseñado por Dave Winer de User Land, llam ado XML- RPC. A par t ir de ést e se obt uvo en Sept iem br e de 1999 la ver sión 1.0 de SOAP, en la que par t icipo act ivam ent e Micr osoft y el ar chiconocido exper t o en pr ogr am ación Don Box. Est a pr im er a ver sión fue m ás o m enos despr eciada por los pr incipales fabr icant es de soft war e que en esa época t enían en m ar cha un pr oyect o m ás am bicioso llam ado ebXML. Est o puso en peligr o en su nacim ient o la exist encia de SOAP ya que si los gr andes no lo apoyaban poco se podía hacer . Por for t una uno de est os gr andes fabr icant es, I BM, decidió apoyar lo y en la act ualidad no sólo acept a SOAP sino que es uno de lo m ot or es det r ás de su desar r ollo ( dos im por t ant es per sonas de I BM y su filial Lot us, David Ehnebuske y Noah Mendelsohn, son aut or es de la especificación 1.1 de SOAP) . Sun Micr osyst em s t am bién anunció oficialm ent e en Junio de 2000 que sopor t aba el est ándar . El hecho de que los t r es gigant es del soft war e ( Micr osoft , I BM y Sun) apoyen SOAP ha hecho que m uchos fabr icant es de Middlewar e y puent es CORBA- DCOM ( com o Roguewave o I ONA) ofr ezcan pr oduct os par a SOAP, así com o ot r as m uchas pequeñas em pr esas de soft war e. El paso definit ivo par a asegur ar el éxit o de SOAP y los ser vicios web es su envío al W3C ( Wor ld Wide Web Consor t ium ) par a pr oponer lo com o est ándar . La últ im a ver sión de la especificación se puede encont r ar en www.w3.or g/ TR/ SOAP/ . Est e sopor t e m ayor it ar io hace que su éxit o y per vivencia est én asegur ados y hoy t odas las her r am ient as de desar r ollo del m er cado ofr ecen en m enor o m ayor m edida sopor t e par a SOAP. Por supuest o .NET y Visual St udio son los ent or nos m ás avanzados en la adopción de SOAP. La ba se t e cnológica de SOAP Lo int er esant e de SOAP es que ut iliza par a su im plem ent ación t ecnologías y est ándar es m uy conocidos y accesibles com o son XML o el pr ot ocolo HTTP. Dado que los m ensaj es ent r e com ponent es y los dat os de los par ám et r os par a llam adas a m ét odos r em ot os se envían en for m at o XML basado en t ext o plano, SOAP se puede ut ilizar par a com unicar se con cualquier plat afor m a de com put ación, consiguiendo la ansiada ubicuidad de los com ponent es. El uso de HTTP com o pr ot ocolo pr incipal de com unicación hace que cualquier ser vidor web del m er cado pueda act uar com o ser vidor SOAP, r educiendo la cant idad de soft war e a desar r ollar y haciendo la t ecnología disponible inm ediat am ent e. Adem ás en la m ayor ía de los casos se puede hacer uso de SOAP a t r avés de los cor t afuegos que defienden las r edes, ya que no suelen t ener bloqueadas las pet iciones a t r avés del puer t o 80, el puer t o por defect o de HTTP ( de ahí la ubicuidad, aunque se pueden usar ot r os puer t os dist int os al 80, por supuest o) . La segur idad se puede conseguir a t r avés de los m ét odos habit uales en los ser vidor es web y por t ant o se dispone de aut ent icación de usuar ios y cifr ado de infor m ación de for m a t r anspar ent e al pr ogr am ador , usando pr ot ocolos y t écnicas com o I PSec o SSL, am pliam ent e conocidos y usados en el m undo web. Por ot r a par t e la escalabilidad se obt iene a t r avés del pr opio ser vidor web o incluso del sist em a oper at ivo, ya que la m ayor ía de ellos ( por ej em plo I I S) poseen capacidades de am pliación m ediant e clust er s de ser vidor es, enr ut ador es que discr im inan las pet iciones y ot r as t écnicas par a cr ear Web Far m s, o conj unt os de ser vidor es web que t r abaj an com o si fuer an uno solo par a así poder at ender a m ás client es sim ult áneam ent e. N ot a: Exist en am pliaciones al pr ot ocolo SOAP base que definen pr ot ocolos y convenciones par a t ar eas específicas com o las m ecionadas de segur idad, enr ut ado de m ensaj es, los event os y m uchas ot r as cuest iones avanzadas. En .NET se im plem ent an m ediant e los concidos Web Ser vices Enhancem ent s ( WSE) act ualm ent e por su ver sión 3.0, y en un fut ur o inm ediat o con Windows Com m unicat ion Foundat ion, la nueva plat afor m a de ser vicios de com unicaciones de Windows. El est udio de ést os se sale del ám bit o de est e cur so. Com o vem os, las t ecnologías ut ilizadas son conocidas y la especificación SOAP se r efier e m ás bien a la m aner a de usar las. De est e m odo las ár eas cubier t as por la especificación se r efier en a cóm o se codifican los m ensaj es XML que cont ienen las llam adas a pr ocedim ient os y sus r espuest as, y a la m aner a en que HTTP debe int er cam biar est os m ensaj es. Si nos r efer im os a la esencia del est ándar , SOAP t r at a de sust it uir a los difer ent es for m at os pr opiet ar ios de em paquet am ient o de dat os que ut ilizan ot r as t ecnologías ( com o DCOM o CORBA con NDR y CDR r espect ivam ent e) , así com o los pr ot ocolos pr opiet ar ios em pleados par a t r ansm it ir est os dat os em paquet ados. HTTP es el único pr ot ocolo definido en el est ándar par a SOAP per o ést e es lo suficient em ent e abier t o com o par a per m it ir que se em pleen ot r os pr ot ocolos dist int os par a t r ansm it ir m ensaj es SOAP. Por cit ar unos pocos, se podr ía ut ilizar SMTP ( cor r eo elect r ónico) , MSMQ ( Micr osoft Messaging Queue) par a enviar de m aner a asíncr ona las llam adas a pr ocedim ient os con SOAP, et c... D e scubr im ie nt o de se r v icios: W SD L y UD D I Ot r o de los est ándar es que se definen en SOAP es W SD L ( Web Ser vice Definit ion Language) . Se t r at a de u n for m at o est ándar par a descr ibir las int er faces de los ser vicios web. WSDL descr ibe qué m ét odos est án disponibles a t r avés de un ser vicio Web y cuáles son los par ám et r os y valor es devuelt os por ést os. Ant es de usar un com ponent e que act úa com o ser vicio web se debe leer su ar chivo WSDL par a aver iguar cóm o ut ilizar lo. N ot a: Par a aquellos pr ogr am ador es que conocen ot r as ar quit ect ur as podem os decir que WSDL es el equivalent e en XML a los lenguaj es I DL ( I nt er face Descr ipt ion Language) de DCOM y CORBA. Se ha definido t am bién un for m at o est ándar par a publicación de infor m ación de ser vicios web llam ado UDDI ( Univer sal Descr ipt ion Discover y and I nt egr at ion) . Est a especificación per m it e la cr eación de dir ect or ios de ser vicios web, donde se definen m ét odos que per m it en consu lt ar los par a encont r ar fácilm ent e aquel ser vicio que se necesit e. Windows Ser ver 2003 incluye gr at uit am ent e un ser vidor par a im plem ent ar dir ect or ios UDDI en or ganizaciones. ASP.NET 2.0 nos facilit a gr andem ent e la cr eación de ser vicios Web XML, y si nos apoyam os en una her r am ient a com o lo es Visual St udio 2010, incluso en la ver sión Expr ess, nos dar em os cuent a de que no necesit am os ser exper t os en los pr ot ocolos ut ilizados por los ser vicios Web par a poder cr ear los y ut ilizar los. Tal com o com ent am os en la int r oducción de la lección ant er ior , los ser vicios Web r ealm ent e son clases, clases que exponen unos m ét odos y son esos m ét odos los que podr em os ut ilizar par a acceder a lo que el ser vicio Web nos ofr ece. En est a lección ver em os de for m a sim ple y pr áct ica, cóm o cr ear un ser vicio Web ut ilizando ASP.NET 2.0 y Visual St udio 2010. N ot a: Si est á ut ilizando Visual Basic 2010 Expr ess debe saber que no per m it e la cr eación de ser vicios web. Si desea cr ear un ser vicio puede ut ilizar la her r am ient a Visual Web Developer Expr ess o cualquier edición super ior de Visual St udio 2010. Si desea pr ofundizar en est a her r am ient a puede consult ar el cur so "Desar r ollo de Aplicaciones Web con ASP.NET". N u e st r o pr im e r se r vicio W e b Cr ear un pr oyect o de t ipo ser vicio Web con Visual St udio 2010 Cr ear un ser vicio Web usando un solo ficher o Elim inar ficher os de un pr oyect o Analizando el cont enido de un ser vicio Web At r ibut os aplicables a los ser vicios Web Definición de la clase a usar en el ser vicio Web Añadir m ét odos par a usar los en el ser vicio Web Pr obar nuest r o ser vicio Web Es y a un clásico en el m undillo de la pr ogr am ación m ost r ar el m ensaj e "Hola, Mundo" al cr ear la pr im er a aplicación y eso es lo que vam os a h acer en nuest r o pr im er ser v icio Web, cr ear uno que t enga un m ét odo que devuelva una cadena con la fr ase: "Hola, Mundo". Cr e a r un pr oy e ct o de t ipo se r v icio W e b con Visua l St udio 2 0 1 0 Par a cr ear u n nuev o pr oy ect o con Visual St udio 2010 podem os hacer lo de v ar ias for m as, per o si nos gust a decidir dónde se alm acenar á nuest r o código, la m ej or for m a de hacer lo es m ediant e el m enú de ar chivos, seleccionando la opción N uevo sit io W eb... Al hacer lo t endr em os un cuadr o de diálogo com o el m ost r ado en la figur a 6.4: Figur a 6 .4 . Cuadr o de diálogo par a cr ear un ser vicio W eb Visual St udio 2010, nos per m it e cr ear las aplicaciones y ser vicios Web, en var ias ubicaciones, ent r e ellas el sist em a de ar chiv os local o de r ed local, aunque t am bién podem os indicar una dir ección HTTP o FTP, esas opciones las t enem os en la list a desplegable que hay j unt o a la et iquet a Ubicación, indicar em os el dir ect or io en el que quer em os aloj ar nuest r o código y el lenguaj e que ut ilizar em os, en est e caso concr et o lo har em os con Visual Basic. N ot a: Si ut iliza una v er sión Ex pr ess de Visual St udio, debe saber que sólo puede desar r ollador Ser v icios Web con Visual Web Developer . En los ej em plos ut ilizar em os est a v er sión, aunque t odas las v er siones super ior es de Visual St udio 2010 t ienen un funcionam ient o sim ilar . El pr oy ect o cr eado añade una nueva clase y un ficher o con ext ensión .asm x que es la u t ilizada par a los ser v icios Web. En la clase incluir em os t odo el código n ecesar io par a cr ear la "clase" que usar em os par a com unicar nos con las aplicaciones client e. El ficher o con ex t ensión .asm x sim plem ent e cont iene el código de ASP.NET 2.0 que ser vir á al r unt im e de .NET par a saber que est am os t r at ando con un ser v icio Web, adem ás de indicar le dónde est á aloj ado el código que cont iene la clase y cóm o se llam a est a, y cual es el lenguaj e que u t ilizar em os, t al com o podem os ver en el siguient e código: <%@ WebService Language="vb" CodeBehind="~/App_Code/Service.vb" Class="Service" %> La par t e im por t ant e de esa línea de código ASP.NET es < % @ W ebSer vice, con ella est am os indicando que nuest r a int ención es definir un ser v icio Web. Por ot r a par t e, el at r ibut o CodeBehind le infor m a a ASP.NET 2.0 que el código no est á incluido en el ficher o .asm x , sino en uno independient e. Est e es el t r at am ient o pr edet er m inado al cr ear un nuevo ser v icio Web. Cr e a r u n se r vicio W e b u sa n do u n solo fich e r o Per o si quer em os añadir ot r o ser vicio Web a nuest r o pr oyect o, seleccionando la opción Agr egar nuevo elem ent o del m enú Sit io W eb, el cuadr o de diálogo que nos m uest r a los dist int os t ipos de ficher os que podem os agr egar , t al com o podem os ver en la figur a 6.5: Figur a 6 .5 . Al agr egar un nuevo elem ent o, podem os indicar dónde aloj ar el código Si seleccionam os est a for m a de hacer lo, t ant o la dir ect iv a de ASP.NET com o el código del lenguaj e seleccionado est ar á en el m ism o ficher o, en nuest r o ej em plo H olaM undoSW .a sm x. Com o podem os apr eciar en la figur a 6.6, al cr ear el ser v icio Web de est a for m a, t enem os t odo el código necesar io en un solo ficher o, est a ser á la for m a r ecom endada de hacer lo, al m enos si el ser v icio Web es sim ple, com o es el caso act ual. Figur a 6 .6 . Un solo ficher o par a cont ener el ser vicio W eb Tal com o podem os apr eciar el código de ASP.NET 2.0 se sim plifica un poco, por que y a no t enem os que indicar le al r unt im e de .NET dónde se encuent r a nuest r o código, lo que si t enem os que seguir indicando es que est e ficher o r ealm ent e es un ser vicio Web, cóm o se llam a la clase y que lenguaj e vam os a ut ilizar par a escr ibir el código. Elim in a r fich e r os de u n pr oye ct o Par a est e ej em plo, vam os a quedar nos con est e ficher o en nuest r o pr oyect o, por t ant o el r est o de los ficher os que t enem os cr eados podem os elim inar los, est o lo har em os desde el pr opio explor ador de soluciones, del cual podem os elim inar t odos los ficher os salv o el que v am os a usar en el ej em plo, por t ant o dej ar em os el ficher o H olaM undoSW .a sm x. En la figur a 6.7 podem os v er el cont enido act ual de nuest r o pr oyect o y en la figur a 6.8 el que debem os dej ar después de elim inar el r est o de elem ent os. Figur a 6 .7 . El explor ador de soluciones ant es de elim inar los ficher os Figur a 6 .8 . El explor ador de soluciones con nuest r o ser vicio W eb N ot a: Cuando elim inam os ficher os o car pet as del explor ador de soluciones, est os se elim inan físicam ent e. An a liza n do e l con t e n ido de u n se r vicio W e b Com o podem os com pr obar en la figur a 6.6, una vez que h em os cer r ado la dir ect iv a de ASP.NET 2.0 que indica que el cont enido de ese ficher o es un ser vicio Web, lo que sigue es el código en el lenguaj e de nuest r a pr efer encia, en est e caso Visual Basic ( VB) . Después de las t ípicas im por t aciones de espacios de nom br es v iene el código que har á que est a clase r ealm ent e se conv ier t a en un ser v icio Web. At r ibu t os a plica ble s a los se r vicios W e b Con lo pr im er o que nos encont r am os es con un at r ibut o llam ado WebSer v ice, est e at r ibut o no t iene nada que ver con la dir ect iv a de ASP.NET y r ealm ent e es opcional, es decir , no es necesar io par a conver t ir nuest r a clase en un ser v icio Web. El at r ibut o WebSer v ice es t ot alm ent e opcional, per o siem pr e deber íam os incluir lo en nuest r os ser vicios Web, por dos r azones: 1. Nos ser vir á par a in dicar el espacio de n om br es en el que est ar á n uest r o ser v icio Web. Est e espacio de nom br es no t iene r elación dir ect a con los espacios de nom br es de nuest r as clases, ya que solo se ut iliza par a ident ificar los ser vicios Web. Aunque al igual que los espacios de nom br es declar ados con la inst r ucción Nam espace de Visual Basic, ser vir á par a difer enciar los de ot r os ser v icios Web aloj ados en n u est r o m ism o ser vidor Web o en ot r os difer ent es, de est a for m a evit ar em os conflict os si en una m ism a aplicación client e quer em os t ener dos ser vicios Web difer ent es per o que ut ilizan el m ism o nom br e. 2. La segunda r azón es por que en ese m ism o at r ibut o podem os indicar una descr ipción de nuest r o ser vicio Web. Esa descr ipción ser á la que se m uest r e cuando "descubr am os" un ser vicio Web u t ilizando UDDI . La r ecom endación par a el espacio de nom br es a usar en los ser vicios Web, al m enos par a evit ar posibles con flict os, es dar le el m ism o n om br e de la ubicación de nuest r o ser v idor , y a que así nos asegur am os que no exist ir á ot r o sit io Web que se llam e igual que el nuest r o. N ot a: Si no indicam os un espacio de nom br es par a nuest r o ser v icio Web, ASP.NET ut ilizar á por defect o ht t p: / / t em pur i.or g/ que es el que VWD ut iliza de for m a pr edet er m inada. Por t ant o vam os a cam biar el valor asignado a la pr opiedad N am espace, par a que apunt e a n u est r o "hipot ét ico" ser vidor Web: ht t p:/ / m iSer vidor W eb.com / Ser viciosW eb/ , quedando el at r ibut o de la siguient e for m a: <WebService(Namespace:="http://miServidorWeb.com/ServiciosWeb/")> Par a añadir el v alor que la pr opiedad D escr ipt ion t endr á, lo har em os com o con el r est o de at r ibut os: separ ándola con una com a del cont enido del espacio de nom br es, t al com o podem os apr eciar en el siguient e código: <WebService(Namespace:="http://miServidorWeb.com/ServiciosWeb/", _ Description:="¡Mi primer servicio Web para saludar al mundo!")> D e fin ición de la cla se a u sa r e n e l se r vicio W e b La definición de la clase que ser á el cor azón del ser v icio Web, ( r ecor dem os que un ser vicio Web en el fondo es una clase que ut ilizam os desde un sit io de I nt er net ) , la har em os com o es habit ual en Visual Basic, aunque si quer em os ut ilizar cier t as car act er íst icas pr opias de las aplicaciones ASP.NET com o es acceder a obj et os Session o Applicat ion, podem os der iv ar la a par t ir de la clase WebSer v ice, aunque est o es t ot alm ent e opcional y no influy e en la cr eación de nuest r o ser vicio Web. Public Class HolaMundoSW Inherits System.Web.Services.WebService Lo que si es im por t ant e es que el nom br e de la clase coincida con la indicada en el at r ibut o de la dir ect iv a de ASP.NET. Añ a dir m é t odos pa r a u sa r los e n e l se r vicio W e b Ahor a viene la par t e int er esant e, aunque t odos los pr epar at iv os pr elim inar es t am bién lo son, per o si no definim os ningún m ét odo en nuest r a clase, de poco nos ser v ir á el ser v icio Web, ya que esos m ét odos ser án los que ut ilicem os par a com unicar nos con él. Los m ét odos los declar ar em os de la for m a habit ual, per o si quer em os que sean expuest os com o par t e del ser vicio Web, debem os ut ilizar el at r ibut o WebMet hod. Con est e at r ibut o le est am os indicando a la "infr aest r uct ur a" que hay det r ás de los ser vicios Web, que t enga en cuent a ese m ét odo par a ut ilizar lo desde nuest r a clase. No vam os a ent r ar en det alles de que es lo que ocur r e t r as el t elón, per o debem os saber que sin ese at r ibut o, nuest r o m ét odo ser á t ot alm ent e invisible al m undo ext er ior , aunque aún así lo podr íam os seguir usando desde nuest r a clase o desde cualquier ot r a clase que t engam os en nuest r o pr oyect o, ya que al fin y al cabo es "sólo" un m ét odo m ás. Est e at r ibut o lo ut ilizar em os com o de cost um br e: indicándolo ant es de la declar ación del m ét odo. En el siguient e código vem os la declar ación de un m ét odo que se incluye com o plant illa de los ser vicios Web que cr eem os con Visual St udio 2010, y que nos puede ser vir par a nuest r os pr opósit os, aun qu e lo "cast ellanizar em os" par a que sea m ás fácilm ent e com pr en sible par a los que hablam os el idiom a de Cer vant es: <WebMethod()> _ Public Function HolaMundo() As String Return "¡Hola, Mundo!" End Function El at r ibut o WebMet hod t am bién cont iene pr opiedades, ent r e ellas una que nos ser vir á par a aclar ar que es lo que h ace: Descr ipt ion. Al igual que ocur r e con el at r ibut o WebSer v ice, la pr opiedad D escr ipt ion nos ser v ir á par a explicar le a los que "descubr an" nuest r o ser vicio Web que es lo que hace ese m ét odo. Est o es par t icu lar m en t e út il si n u est r o ser vicio Web t iene var ios m ét odos Web y los n om br es ut ilizados no son m uy "aclar at or ios". Por t ant o, m odificar em os el código par a que t enga el siguient e aspect o: <WebMethod(Description:="Método para saludar al mundo")> _ Public Function HolaMundo() As String N ot a: El at r ibut o WebMet hod t am bién incluye una pr opiedad llam ada MessageNam e, la cual podem os ut ilizar par a evit ar conflict os de sobr ecar ga de m ét odos, y a que los pr ot ocolos usados act ualm ent e con los ser vicios Web r equier en un ident ificador único par a cada m ét odo Web. Pr oba r nue st r o se r v icio W e b Ya t enem os cr eado nuest r o pr im er ser v icio Web, ahor a solo nos queda com pr obar que t odo fun ciona a la per fección. La for m a m ás fácil de hacer lo es m ost r án dolo en el navegador . De est a for m a sabr em os si funciona e incluso podem os v er lo en "acción". Par a m ost r ar el ser vicio Web en el navegador , lo seleccionam os en el Explor ador de soluciones, pr esionam os con el bot ón secundar io del m ouse y del m enú desplegable que nos m uest r a, seleccionam os Ver en el ex plor ador , t al com o nos m uest r a la figur a 6.9: Figur a 6 .9 . M ost ar el ser vicio W eb en el navegador Cuando lo m ost r am os en el I nt er n et Explor er , podem os v er cier t a in for m ación del ser vicio Web, pr incipalm ent e las descr ipciones que hem os usado, adem ás de un par de link s, que nos m ost r ar án in for m ación ext r a de n uest r o ser vicio Web y del m ét odo. En las siguient es im ágenes ( 6.10 y 6.11) vem os lo que nos m uest r a el navegador : Figur a 6 .1 0 . El ser vicio W eb al ut iliz ar lo desde I nt er net Explor er Figur a 6 .1 1 . I nfor m ación sobr e el m ét odo W eb H olaM undo Adem ás de dar nos la opor t unidad de pr obar el m ét odo, pr esionando el bot ón I nvocar , t am bién podem os ver el código que se ut iliza par a com unicar nuest r o ser v icio Web con el r est o de las aplicaciones. Per o com o com pr obar em os en la siguient e lección es t ot alm ent e t r anspar ent e par a nosot r os, y a que es el pr opio Visual St udio 2010, por m edio de ASP.NET, el que se encar ga de t odo el "t r abaj o sucio", dej ándonos a nosot r os solo con el código que t enem os que escr ibir . En est a lección ver em os cóm o "consum ir " el ser vicio Web cr eado ant er ior m ent e desde una aplicación de Windows For m s ut ilizando el ent or no de desar r ollo ( I DE) de Visual St udio 2010. Com o com pr obar em os, el pr opio com pilador de Visual Basic se encar gar á de t odos los por m enor es par a que podam os ut ilizar la clase incluida en el ser vicio Web com o si de una clase nor m al y cor r ient e se t r at ar a, ya que, esa es una de las vent aj as de apoyar se en un ent or no int egr ado de la calidad de Visual St udio 2010, que sólo debem os pr eocupar nos de escr ibir el código y del r est o... ¡nos olvidam os! ( o casi) . Ut iliza r los se r vicios W e b de sde u n a a plica ción de W in dow s Ut ilizar los ser vicios Web desde una aplicación de Windows Aloj ar el ser vicio Web en un ser vidor local Act ivar el ser vidor Web par a usar con un dir ect or io local Cr ear un pr oyect o Windows par a usar el ser vicio Web Añadir una r efer encia par a acceder al ser vicio Web ¿Dónde est án las r efer encias en Visual Basic 2010? Acceder al ser vicio Web desde el código ¿Que es lo que puede fallar ? Ut iliza r los se r vicios W e b de sde u n a a plicación de W in dow s Ahor a v am os a v er cóm o podem os "consum ir " un ser v icio Web desde una aplicación de Windows. Aloj a r e l se r v icio W e b e n un se r v idor loca l Par a que nuest r o ej em plo funcione, t enem os que copiar el ser v icio Web que cr eam os en la lección ant er ior en el dir ect or io al que hace r efer encia el Web local de nuest r o equipo ( localhost ) . Si no hem os cam biado la ubicación que t iene de for m a pr edet er m inada, est ar á en la car pet a C:\ I net put \ w w w r oot , est o si es que t enem os el I I S ( I nt er net I nfor m at ion Ser ver ) inst alado en nuest r o equipo. Si no hem os inst alado el I I S, ( con las ver siones ant er ior es de Visual St udio .NET er a un r equisit o par a poder cr ear cualquier t ipo de pr oy ect o Web con ASP.NET) , no debem os pr eocupar nos, y a que la ver sión 2.0 de .NET Fr am ewor k incluye su pr opio ser vidor Web, y con est os sencillos pasos vam os a poner lo en m ar cha par a pr obar nuest r os ser vicios Web. N ot a: Si quier e m ay or div er sión y no copiar ningún ser v icio web en su m áquina, acceda a cualquier ser v icio web público de I nt er net . Ex ist en de t odo t ipo, desde ser v idor es de hor a hast a com plej os sist em as de m apas. Le pr oponem os algunos ej em plos: - List a de ser vicios web gr at uit os: ht t p: / / www.webser v icex .net / WS/ wscat list .aspx - Fot os por sat élit e: ht t p: / / t er r aser v ice.net / webser v ices.aspx - MapPoint ( ev aluación) : ht t ps: / / m appoint css.par t ner s.ex t r anet .m icr osoft .com / MwsSignup/ Ev al.aspx - Ser vicios web de Am azon: ht t p: / / www.am azon.co.uk / exec/ obidos/ t g/ br owse / - / 3242161/ 026- 5630606- 4874040 Act iva r e l se r vidor W e b pa r a u sa r con u n dir e ct or io loca l Si no dispone de I I S y quier e aloj ar un ser vicio web en su m áquina, ést os son los pasos que debem os dar act iv ar el ser v idor Web incluido con .NET Fr am ewor k 2.0: 1. Lo pr im er o que debem os hacer es cr ear un dir ect or io en cualquier unidad de nuest r o equipo, en est os ej em plos vam os a ut ilizar el dir ect or io E:\ VS2 0 0 8 B2 \ sit ioW eb, per o puede ser cualquier ot r o, lo im por t ant e es que est e ser á el que ut ilizar em os en est os pasos. 2. En ese dir ect or io copiar em os nuest r o ser v icio Web, en concr et o el ficher o .asm x cr eado en la lección ant er ior . 3. Abr im os una v ent ana de com andos y nos cam biam os al dir ect or io C:\ W I N D OW S \ M icr osoft .N ET\ Fr am ew or k\ v2 .0 .5 0 2 1 5 , que es en el que est án los ej ecut ables de .NET Fr am ewor k 2.0. 4. Escr ibim os lo siguient e: W ebD ev.W ebSer ver .EXE / por t :8 0 8 0 / pat h:" E:\ VS2 0 0 8 B2 \ sit ioW eb" / vpat h:" / " Est o har á que se inicie el ser vidor Web de .NET per m it iéndonos acceder a nuest r o ser vicio Web usando la siguient e dir ección: ht t p:/ / localhost :8 0 8 0 / H olaM undoSW .asm x 5. De est a for m a, hast a que no desconect em os el ser v idor Web, est e est ar á en ese puer t o, t al com o podem os v er en la figur a 6.12. Par a no per der la conex ión, debem os dej ar abier t a la v ent ana de com andos. Figur a 6 .1 2 . Ser vidor W eb local act ivado en el puer t o 8 0 8 0 N ot a: Est os pasos solo son necesar ios si no t enem os inst alado y en ej ecución el I SS, en cuy o caso t endr íam os que copia el ser v icio Web en el dir ect or io C: \ I net put \ wwwr oot y usar ht t p: / / localhost / HolaMundoSW.asm x par a acceder al ser v icio Web. En ot r o or den de cosas, Visual St udio 2010 lanza un Ser v idor Web v ir t ual, conocido com o Cassini, que per m it e ej ecut ar aplicaciones Web en ent or nos de desar r ollo sin I I S. No obst ant e, si accedem os a las pr opiedades del pr oy ect o, podr em os indicar igualm ent e el puer t o específico que quer em os usar , t al y com o se m uest r a en la siguient e im agen: Cr e a r un pr oy e ct o W indow s pa r a usa r e l se r v icio W e b Lo siguient e que t enem os que hacer es abr ir el Visual St udio 2010 y cr ear un nuev o pr oy ect o de Windows, al que le dar em os el nom br e Client eW indow s. De for m a aut om át ica se cr ear á un for m ular io, al que le añadim os una et iquet a a la que asignar em os a la pr opiedad Font una fuent e de 16 punt os en negr it a, par a que se v ea bien el t ex t o, y le cam biam os el nom br e a: labelSaludo. Tam bién añadir em os un bot ón al que le dar em os el nom br e bt nUsar Ser vicioW eb, en el t ext o pondr em os: Saludo desde ser vicio W eb, com o es nat ur al, t endr em os que cam biar el t am año par a que v eam os el t ex t o com plet o. Añ a dir u n a r e fe r e n cia pa r a a cce de r a l se r vicio W e b Al igual que ocur r e con el r est o de ensam blados de .NET, si quer em os acceder a la clase que t iene el ser v icio Web, debem os cr ear una r efer encia en nuest r o pr oy ect o, con idea de que t engam os a nuest r a disposición las clases que cont iene, en nuest r o caso la clase H olaM undoSW . Per o com o es un ser vicio Web, que t eór icam ent e est á aloj ado en algún ser vidor de I nt er net , en lugar de agr egar una r efer encia nor m al, añadir em os una r efer encia Web. Par a hacer lo, nos ir em os al Explor ador de soluciones / Refer ences, pr esionar em os con el bot ón secundar io del m ouse par a que se m uest r e el m enú cont ext ual, del que elegir em os la opción Agr egar r efer encia W eb, t al com o v em os en la figur a 6.13: Figur a 6 .1 3 . Agr egar una r efer encia W eb N ot a: ¿D ónde est án las r efer encias en Visual Basic 2 0 1 0 ? En Visual Basic 2010, hay cier t os elem ent os que se ocult an al usuar io, ent r e ellos las r efer encias que t enem os en nuest r o pr oyect o. Ent r e ellos algunos de los que se incluyen en el Explor ador de soluciones. Par a m ost r ar t odas las opciones de nuest r o pr oyect o, debem os "obligar " al I DE de Visual Basic 2010 a que nos m uest r e esos ficher os y opciones ocult as, par a hacer lo pr esionar em os el segundo bot ón de la bar r a de her r am ient as del Ex plor ador de soluciones, t al com o com ent am os en la lección 5 del m ódulo 1. Act o seguido apar ecer á un cuadr o de diálogo que nos ser v ir á par a indicar dónde est á aloj ado el ser v icio Web, si hem os seguido los pasos indicados ant er ior m ent e, el ser vicio Web est ar á aloj ado en ht t p:/ / localhost :8 0 8 0 / H olaM undoSW .asm x , por t ant o ser á eso lo que escr ibir em os en el com bo que hay j unt o a URL, una v ez "descubier t o" el ser v icio Web, se m ost r ar á la infor m ación, t al com o lo hacía el I nt er net Ex plor er , y y a est ar em os list os par a agr egar la r efer encia Web, par a ello t endr em os que pr esionar en el bot ón Agr egar r efer encia, t al com o vem os en la figur a 6.14. N ot a: Si est á ut ilizando un ser v icio web público, int r oduzca la URL del ser v icio en lugar de ht t p: / / localhost : 8080/ HolaMundoSW.asm x. La dir ección de los ser v icios suele venir indicada en la docum ent ación de ay uda del ser vicio y cor r esponde al ar chiv o WSDL que define el int er faz del m ism o. Figur a 6 .1 4 . Agr egar una r efer encia W eb a nuest r o pr oyect oo Una vez hecho est o, t endr em os nuest r a clase en un espacio de nom br es que se llam ar á t al com o se indica en la caj a de t ext os que hay baj o N om br e de r efer encia W eb. N ot a: Los ser vicios Web que podem os ut ilizar en nuest r os pr oyect os, no t ienen por qué est ar hechos con el m ism o lenguaj e de pr ogr am ación que el ut ilizado en el client e. Ya que a lo que est am os accediendo, aunque no nos per cat em os, y por sim plificar , es a un ensam blado de .NET, por t ant o, los ser v icios Web pueden est ar escr it os por cualquier lenguaj e de .NET que per m it a la cr eación de los m ism os. Acce de r a l se r vicio W e b de sde e l código Ya solo nos queda escr ibir el código par a acceder a la clase, par a ello declar ar em os una v ar iable cuy o t ipo de dat os ser á la clase H olaM undoSW , la inst anciar em os y acceder em os al m ét odo H olaM undo, el cual, com o sabem os, dev uelv e una cadena, que asignar em os a la et iquet a labelSaludo. Lo pr im er o que t enem os que hacer es cr ear el m ét odo que det ect ar á la pulsación en el bot ón, a est as alt ur as no cr eo que hay a que decir cóm o hacer lo.. Private Sub btnUsarServicioWeb_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles btnUsarServicioWeb.Click Dim hsw As New localhost.HolaMundoSW labelSaludo.Text = hsw.HolaMundo() End Sub Y ya podem os pr obar a ver si funciona, par a ello, pr esionam os F5 y si t odo va bien, se ej ecut ar á la aplicación y podr em os pr esionar el bot ón par a obt ener el r esult ado m ost r ado en la figur a 6.15: Figur a 6 .1 5 . El m ensaj e devuelt o por el ser vicio W eb ¿Qu é e s lo qu e pu e de fa lla r ? Si ha seguido cor r ect am ent e est os pasos el ser v icio web debe funcionar sin pr oblem as. En caso de er r or asegúr ese de que el ser v icio web est á funcionando cor r ect am ent e. Par a ello puede usar su nav egador de I nt er net y acceder dir ect am ent e a la dir ección del ser v icio. Si no le funciona y es un ser v idor r em ot o de I nt er net , el er r or puede v enir de su conect iv idad con I nt er net o la dir ección que consiguió del ser vicio. Si es un ser vicio local y no puede acceder a él, asegúr ese de que el ser v idor web est á ar r ancado, bien sea I I S o el pr opio ser v idor incluido con el Fr am ewor k .NET 2.0. En est e m ódulo ver em os los aspect os gener ales y par t icular es de LI NQ A cont inuación se exponen los apar t ados que se ver án en est e m ódulo. Pa r a qu é LI N Q LI N Q t o Obj e ct s LI N Q t o X M L LI N Q y ADO.N ET LI N Q t o Da t a Se t LI N Q t o SQL LI N Q t o En t it ie s LI NQ o Language I N t egr at ed Quer y es una de las novedades m ás im por t ant es de Micr osoft .NET Fr am ewor k 3.5 y que afect a por lo t ant o a Visual St udio 2010 y con ello a Visual Basic 2010. N ot a: LI NQ no est á disponible en Visual St udio 2005 ni ver siones ant er ior es. LI NQ const it uye ant e t odo una r evolución a la hor a de desar r ollar aplicaciones Soft war e. Mucha gent e no lo ve así, per o es dem asiado pr ont o com o par a que el fenóm enos LI NQ t er m ine de calar ent r e los desar r ollador es, si bien, quienes lo ut ilizan, quedan pr endados de él. La m isión fundam ent al de LI NQ es la de enlazar los dat os con la pr ogr am ación y los lenguaj es de pr ogr am ación t r at ando de elim inar las bar r er as que separ aban a los dat os de la pr ogr am ación, y dot ando por ot r o lado a la aplicación, de m ás segur idad a los pr ogr am ador es a la hor a de t r abaj ar con dat os. LI NQ ent r e ot r as cosas, nos per m it e com pr obar los t ipos de dat os con los que est am os oper ando en t iem po de com pilación, por lo que r educim os en gr an m edida los r iesgos que solem os ar r ast r ar los pr ogr am ador es en m uchos pr oyect os Soft war e. Per o t odo est o no t endr ía lugar sino fuer a por los it er ador es y las colecciones, aspect os t odos ellos, que t om an una especial im por t ancia a la hor a de t r abaj ar con LI NQ. Par a t r abaj ar con LI NQ, ut ilizar em os en m uchas sit uaciones la int er faz I Quer yable y I Enum er able que se encuent r a en el nom br e de espacio Syst em .Linq del ensam blado Syst em .Cor e.dll. Por defect o, al iniciar un pr oyect o con Visual St udio 2010, el ent or no gener ar á la est r uct ur a base de la aplicación y agr egar á las r efer encias necesar ias par a t r abaj ar con LI NQ. ¿Y qué es lo que nos per m it e LI NQ?. LI NQ nos per m it e por lo t ant o, t r abaj ar con dat os, colecciones y elem ent os de una for m a m uy pr ecisa, ut ilizando par a ello sent encias int egr adas m uy sim ilar es al lenguaj e SQL. Or íge n e s de da t os LI N Q Par a t r abaj ar con colecciones, dat os y elem ent os con LI NQ, Micr osoft nos ha pr opor cionado una ser ie de obj et os o ext ensiones que nos per m it ir án int er act uar con los dat os adecuados y LI NQ. De acuer do a la Ar quit ect ur a de LI NQ, ést a se puede asem ej ar a la que se indica en la siguient e im agen: Figur a 7 .1 .- Ar quit ect ur a de LI N Q En est a ar quit ect ur a, podem os ver a los lenguaj es de pr ogr am ación en la capa m ás alt a, y a cont inuación LI NQ com o lenguaj e int egr ado de consult as, y debaj o de ést e, los or ígenes de dat os o ext ensiones que podr em os ut ilizar con LI NQ. Respect o a las ext ensiones, debem os dest acar las que per t enecen a los obj et os de dat os r elaciones, las que t ienen r elación con los obj et os pr opiam ent e dichos, y las que per m it en t r abaj ar con XML. Todos est os ext ensor es, nos per m it en t r abaj ar con LI NQ de una for m a m uy par ecida. Podr ía haber m ás ext ensor es, incluso podr íam os cr ear el nuest r o pr opio. De hecho, en I nt er net hay difer ent es pr oyect os, m uchos de ellos de car áct er código abier t o, que t ienen por m isión cr ear ext ensor es de LI NQ par a ut ilizar con .NET Fr am ewor k 3.5. Muchos de esos pr oyect os, pueden encont r ar se en CodePlex. Así por lo t ant o, t enem os dent r o de .NET Fr am ewor k 3.5 los siguient es ext ensor es: Si quer em os t r abaj ar con obj et os, lo r azonable es que t r abaj em os con LI NQ t o Obj ect s. Si lo que quer em os es t r abaj ar con docum ent os XML, ut ilizar em os LI NQ t o XML. Per o si quer em os acceder y m anipular dat os, ent onces podr em os t r abaj ar con t r es difer ent es ext ensor es dependiendo de nuest r as necesidades. Est os ext ensor es son LI NQ t o Dat aSet , t am bién conocido com o LI NQ sobr e conj unt o de dat os ( r ecor dem os el capít ulo de dat os donde se hablaba de Dat aSet s) , LI NQ t o SQL par a t r abaj ar con bases de dat os SQL Ser ver , y LI NQ t o Ent it ies par a t r abaj ar con ent idades, o lo que es lo m ism o, con cualquier fuent e de dat os, no solo con SQL Ser ver . A cont inuación ver em os com o usar cada uno de los ext ensor es de LI NQ en Visual Basic 2010. LI N Q t o Obj ect s Con LI NQ t o Obj ect s t r abaj ar em os con obj et os, m at r ices y colecciones de dat os que est án en m em or ia, desde n uest r as aplicaciones escr it as en Visual Basic 201 0. Con LI NQ t o Obj ect s, podem os t r abaj ar con LI NQ siem pr e y cuando los obj et os con los que quer em os t r abaj ar , im plem ent en las int er faces I Enum er a ble e I Enum er a ble< T> . N ot a aclar at or ia: r ecu er de que si una clase em pieza por I seguida del nom br e de la clase, suele indicar según la nom enclat ur a r ecom endada por Micr osoft , que se t r at a de una int er faz. Tam bién es posible que encu ent r e en difer ent es docum ent os, I Enum er able< T> com o I Enum er able( Of T) . Am bas significan lo m ism o, y t ienen r elación dir ect a con los dat os t ipados de la int er faz, o dicho de ot r a for m a, t iene r elación con los dat os genér icos. En la docum ent ación gener al de MSDN, lo encont r ar á siem pr e com o I Enum er able< T> . Par a r ecor r er los elem ent os de una colección , ut ilizar em os nor m alm ent e el bucle For Each. El ensam blado Syst em .Linq que se incluye por defect o en cu alquier aplicación de Visual St udio 2010 y que r eside en Syst em .Cor e.dll, nos per m it e ut ilizar dir ect am en t e LI NQ dent r o de nu est r as aplicaciones. Si elim inam os la r efer encia a est e ensam blado, no podr em os ut ilizar LI NQ en nuest r as aplicaciones. Gr acias a LI NQ, podem os ut ilizar ot r a nom enclat ur a difer ent e par a acceder a los elem ent os de un obj et o o colección que est án en m em or ia, algo que ver em os en el siguient e apar t ado. Pr a ct ica ndo con LI N Q t o Obj e ct s En est e pr im er ej em plo, m ost r ar em os com o t r abaj ar con una m at r iz de dat os. Es u n sencillo ej em plo que nos per m it ir á com pr ender m ej or com o fu nciona LI NQ t o Obj ect s. Lo pr im er o que har em os es iniciar con Visual St udio 20 10 un nuev o pr oy ect o de Visual Basic 201 0 y de t ipo aplicación Windows. Dent r o del for m ular io Windows inser t ar em os un cont r ol But t on, y a cont inu ación, escr ibir em os el sigu ient e código fuent e par a nuest r a aplicación. Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Declaramos la matriz y la inicializamos con valores Dim material() As String = {"mesa", "reloj", "libro", "pluma", "borrador", "pelota", "botella"} ' Ejecutamos LINQ para obtener los datos buscados ' Concretamente, buscamos los materiales que empiezan por "b" Dim materialBuscado = From busqueda In material _ Where busqueda.StartsWith("b") _ Select busqueda ' En materialBuscado tendremos toda la seleccirealizada, por lo ' que deberemos recorrerla para extraer los elementos encontrados Dim resultado As String = "" For Each elementos In materialBuscado resultado &= elementos & vbCrLf Next ' Mostramos la información MessageBox.Show(resultado) End Sub End Class En el ej em plo que acabam os de pr epar ar , podem os v er com o con LI NQ, com o lenguaj e in t egr ado de consult as, hem os accedido a los elem ent os de la m at r iz que est án en la m em or ia. Com o habr á podido com pr obar , LI NQ es en su est r uct ur a, m uy sim ilar a SQL. Conv iene dest acar , que la for m a de apr ender a ut ilizar y m anej ar LI NQ adecu adam ent e, es a base de pr áct ica. Tam bién es int er esant e r ecalcar , que LI NQ r epr esent a una r evolución par a el pr ogr am ador , y qu e Micr osoft est á haciendo gr an des esfuer zos por dar a con ocer y ext ender LI NQ com o un nu ev o par adigm a en el desar r ollo de aplicaciones Soft war e. Si analizam os un poco el ej em plo que hem os r ealizado, ver em os que dent r o del código de Visual Basic podem os ut ilizar claúsulas com o Fr om , Wher e o Select , m ás pr opias de SQL que de u n lenguaj e de pr ogr am ación com o Visual Basic. LI NQ por lo t ant o, n os pr opor ciona o nos acer ca el lenguaj e nat ur al de SQL par a t r abaj ar dir ect am en t e con él en n uest r as aplicaciones, seleccionan do los elem ent os que quer em os, pr opor cionando claúsulas de condición, u or denando los elem ent os par a obt en er los en su salida dir ect am ent e t al y com o los quer em os. Dent r o del ej em plo de LI NQ, podem os com pr obar que par a seleccionar un subconj unt o de elem ent os de un conj unt o pr incipal, ut ilizam os una ser ie de oper andos difer ent es. En pr im er lugar la claúsula u oper ando Fr om en la que indicam os un alias dent r o del conj unt o de elem ent os Fr om < alias> I n < conj un t o_ de_elem ent os> . Post er ior m ent e y den t r o de la m ism a claúsula, ut ilizam os la claú sula u oper ando W her e que nos per m it e indicar la condición o condiciones que quer em os ut ilizar . Finalm ent e y en el ej em plo r ealizado, ut ilizam os la claúsula u oper ando Select que t iene por m isión seleccionar el elem ent o o conj unt o de elem ent os que quer em os ext r aer . A cont inuación, ex pondr em os un ej em plo un poco m ás com plet o del uso de LI NQ t o Obj ect . Apr ovechando la base del ej em plo an t er ior , escr ibir em os una clase Em pleado y lu ego, consum ir em os esa clase par a t r abaj ar con ella desde LI NQ t o Obj ect s. Ver em os lo sum am ent e fácil, r ápido e int u it ivo que r esu lt a t r abaj ar con LI NQ t o Obj ect s en Visu al Basic 2 010. Class Empleado ' Nombre del empleado Private m_Nombre As String Public Property Nombre() As String Get Return m_Nombre End Get Set(ByVal value As String) m_Nombre = value End Set End Property ' NIF del empleado Private m_NIF As String Public Property NIF() As String Get Return m_NIF End Get Set(ByVal value As String) m_NIF = value End Set End Property ' Edad del empleado Private m_Edad As Byte Public Property Edad() As Byte Get Return m_Edad End Get Set(ByVal value As Byte) m_Edad = value End Set End Property End Class Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Declaramos la matriz y la inicializamos con valores Dim personal() As Empleado = {New Empleado() With {.Nombre = "Juan", .NIF = "111A", .Edad = 32}, _ New Empleado() With {.Nombre = "María", .NIF = "222C", .Edad = 43}, _ New Empleado() With {.Nombre = "José", .NIF = "333R", .Edad = 45}, _ New Empleado() With {.Nombre = "Rosa", .NIF = "333F", .Edad = 33}, _ New Empleado() With {.Nombre = "Javier", .NIF = "444G", .Edad = 41}} ' Ejecutamos LINQ para obtener los datos buscados ' Concretamente, buscamos los empleados cuya edad es mayor de 40 años Dim empleadosBuscados = From busqueda In personal _ Where busqueda.Edad > 40 _ Select busqueda.Nombre, busqueda.Edad _ Order By Edad Descending ' En empleadosBuscados tendremos toda la seleccirealizada, por lo ' que deberemos recorrerla para extraer los elementos encontrados Dim resultado As String = "" For Each elementos In empleadosBuscados resultado &= String.Format("{0} tiene {1} años", elementos.Nombre, elementos.Edad) & vbCrLf Next ' Mostramos la información MessageBox.Show(resultado) End Sub End Class N uevo en Visual Basic 2 0 1 0 : Una nuev a car act er íst ica de Visu al Basic 2 010, es la que per m it e inicializar la clase y sus pr opiedades dir ect am ent e. Par a ello, u t ilizar em os la claúsula W it h t al y com o podem os ver en el ej em plo ant er ior . Analizando el ej em plo que acabam os de v er , vem os que en est e caso est am os t r abaj ando con obj et os Em pleado que est án en m em or ia, y con sus dat os inicializados en la aplicación. Dent r o de la sent encia LI NQ que est am os ut ilizando, hem os seleccionado dos elem ent os de los dat os con los que est am os t r abaj ando, y hem os r ealizado la or denación de sus dat os de acu er do al oper ando o cláusula Or der By. I ncluso le hem os indicado el or den de or denación m ediant e el uso de la palabr a r eser v ada D e scending, indicando así que quer em os or denar los elem ent os por el cam po Eda d y en or den descendient e. Por defect o, la or denación es en sent ido ascendent e y no hace falt a in dicar lo. A la hor a de t r abaj ar con el ent or no de desar r ollo, I nt ellisense const it uye par a nosot r os una her r am ient a de pr oduct iv idad enor m e, y a que es capaz de indicar nos dir ect am ent e en LI NQ los cam pos disponibles, per m it iéndonos así, seleccionar el cam po o cam pos que deseam os ut ilizar . LI N Q t o XM L Con LI NQ t o XML t r abaj ar em os con docum ent os XML desde nuest r as aplicaciones escr it as en Visual Basic 2010. LI NQ t o XML en Visual St udio 2010, posee difer encias not ables y v ent aj osas con r espect o a C# 3.0. Muchos son los pr ogr am ador es de C# que desean incluir algunas de las car act er íst icas que est án incluidas en LI NQ t o XML par a Visual Basic 2010. Visual Basic 2010 pr opor ciona por lo t ant o, una int egr ación t ot al con XML, que per m it e m anipular los docum ent os XML dir ect am ent e. Pr uebe est o: copie al por t apapeles de Windows el cont enido de un docum ent o XML y escr iba en Visual St udio 2010, y dent r o de su código de Visual Basic 2010 la siguient e inst r ucción: D im var iable = y a cont inuación peque ahí el cont enido del docum ent o XML que t endr á en el por t apapeles de Windows. Obser v ar á que Visual Basic 2010 es capaz de t r at ar el docum ent o XML de for m a dir ect a. Par a t r abaj ar con LI NQ t o XML, Micr osoft nos ha pr opor cionado un nuev o ensam blado de nom br e Syst em .Linq.Xm l.dll. A t r avés de Visual Basic 2010, podem os ut ilizar los lit er ales XML de for m a dir ect a, per m it iéndonos ex plot ar los docum ent os XML de una for m a m ucho m ás ágil y t r anspar ent e, aum ent ando enor m em ent e así la pr oduct iv idad de nuest r os desar r ollos. Pr a ct ica ndo con LI N Q t o XM L A cont inuación, r ealizar em os un ej em plo de com o t r abaj ar con LI NQ t o XML. Par a r ealizar el siguient e ej em plo, nos apoy ar em os en el siguient e docum ent o XML: <?xml version='1.0'?> <!-- Este documento XML representa el inventario de coches --> <coches> <coche marca="BMW"> <modelo>520</modelo> <potencia>125CV</potencia> </coche> <coche marca="BMW"> <modelo>525</modelo> <potencia>135CV</potencia> </coche> <coche marca="Citroen"> <modelo>C3</modelo> <potencia>75CV</potencia> </coche> <coche marca="Citroen"> <modelo>C4</modelo> <potencia>115CV</potencia> </coche> <coche marca="Citroen"> <modelo>C5</modelo> <potencia>135CV</potencia> </coche> </coches> I nser t ar em os el docum ent o XML ant er ior dent r o del código de nuest r a aplicación par a ut ilizar lo de for m a dir ect a. Basándonos en la base del ej em plo ant er ior , escr ibir em os un ej em plo que ut ilice el docum ent o XML ant er ior en br ut o. El código de nuest r o ej em plo, quedar á por lo t ant o de la siguient e for m a: Public Class Form1 Private Dim Dim For Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click datos = SelectXML(120) resultado As String = "" Each dato In datos resultado &= String.Format("{0} tiene un coche {1}", dato.marcaCoche, dato.modeloCoche) & vbCrLf Next MessageBox.Show(resultado) End Sub Private Function SelectXML(ByVal potencia As Byte) As Object Dim documentoXML = <?xml version='1.0'?> <!-- Este documento XML representa el inventario de coches --> <coches> <coche marca="BMW"> <modelo>520</modelo> <potencia>125</potencia> </coche> <coche marca="BMW"> <modelo>525</modelo> <potencia>135</potencia> </coche> <coche marca="Citroen"> <modelo>C3</modelo> <potencia>75</potencia> </coche> <coche marca="Citroen"> <modelo>C4</modelo> <potencia>115</potencia> </coche> <coche marca="Citroen"> <modelo>C5</modelo> <potencia>135</potencia> </coche> </coches> Return From datos In documentoXML...<coche> _ Where datos.<potencia>.Value > potencia _ Select marcaCoche = datos.@marca, modeloCoche = datos.<modelo>.Value End Function End Class En est e ej em plo, podem os ver cosas m uy cur iosas. Por un lado, la for m a en la que accedem os a los bloques del docum ent o XML lo hacem os m ediant e la inst r ucción docum ent oXM L.... El uso de ... nos per m it e sit uar nos en cada bloque de dat os del docum ent o XML, o lo que es lo m ism o, en cada bloque de coche. Por ot r o lado, par a ex t r aer el v alor de un cam po hij o en el bloque det er m inado, lo har em os ut ilizando su et iquet a ent r e los caract er es < y > , y usando el t ér m ino Value, com o por ej em plo dat os..Value. Finalm ent e, par a ut ilizar el valor de una et iquet a padr e, ut ilizar em os el car áct er @, com o en el caso de dat os.@m ar ca. Ahor a bien, ¿que pasar ía si el docum ent o XML en lugar de est ar incr ust ado dent r o del código est uv ier a en una car pet a del disco dur o?. En ese caso, podr em os car gar el docum ent o XML en m em or ia par a ut ilizar lo adecuadam ent e. A cont inuación, v er em os un ej em plo de com o usar est a car act er íst ica: Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim documentoXML As XDocument = XDocument.Load("C:\DesarrollaConMSDN.xml") Dim datosSeleccionados = From datos In documentoXML...<coche> _ Where [email protected]() = "BMW" _ Select modeloCoche = datos.<modelo>.Value, potenciaCoche = datos.<potencia>.Value Dim resultado As String = "" For Each dato In datosSeleccionados resultado &= String.Format("{0} tiene un coche {1} de {2}CV", "BMW", dato.modeloCoche, dato.potenciaCoche) & vbCrLf Next MessageBox.Show(resultado) End Sub End Class Al ej ecut ar est e ej em plo, ver em os que el com por t am ient o no cam bia dem asiado, de hecho, el funcionam ient o es exact am ent e el m ism o, con la salv edad de que en un caso el docum ent o XML se ha car gado en br ut o, y en est e últ im o caso, se ha car gado desde una unidad de disco dur o. Tr a ba j a n do con lit e r a le s y LI N Q t o XM L Sin em bar go, dent r o del uso de docum ent o XML y Visual Basic 2010, hay algo que r esult a r ealm ent e at r act ivo par a el pr ogr am ador . Est oy hablando del uso de lit er ales. A cont inuación, ver em os un ej em plo del uso de lit er ales, que es a m i j uicio, la m ej or for m a de ent ender en qué consist e est a car act er íst ica agr egada a Visual Basic 2010. Basándonos una vez m ás en la base de los ej em plos ant er ior es, es decir , un for m ular io Windows con un cont r ol But t on, vam os a desar r ollar un ej em plo que nos m uest r e el uso de lit er ales. Par a llev ar a cabo nuest r a t ar ea, v am os a agr egar nuest r o for m ular io un cont r ol W ebBr ow ser . En m i caso, y par a dar le una est ét ica m ás v isual, he decidido agr egar t am bién dos cont r oles Panel y he j ugado con la pr opiedad D ock de los cont r oles inser t ados en el for m ular io. Una vez hecho est o, vam os a escr ibir el código de nuest r o ej em plo que quedar á de la siguient e for m a: Public Structure Vehiculo Public Enum TipoVehiculo camion coche moto End Enum Public Tipo As TipoVehiculo Public Matricula As String Public Velocidad As Integer End Structure Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim listaVehiculos As New List(Of Vehiculo) Dim vehiculoUno As New Vehiculo With {.Matricula = "0000AAA", .Tipo = Vehiculo.TipoVehiculo.coche, .Velocidad = 235} listaVehiculos.Add(vehiculoUno) Dim vehiculoDos As New Vehiculo With {.Matricula = "1111AAA", .Tipo = Vehiculo.TipoVehiculo.moto, .Velocidad = 265} listaVehiculos.Add(vehiculoDos) Dim vehiculoTres As New Vehiculo With {.Matricula = "2222AAA", .Tipo = Vehiculo.TipoVehiculo.coche, .Velocidad = 190} listaVehiculos.Add(vehiculoTres) Dim vehiculoCuatro As New Vehiculo With {.Matricula = "3333AAA", .Tipo = Vehiculo.TipoVehiculo.camion, .Velocidad = 160} listaVehiculos.Add(vehiculoCuatro) Dim vehiculos = <?xml version='1.0'?> <vehiculos> <%= From datos In listaVehiculos _ Select <vehiculo> <tipo><%= datos.Tipo.ToString() %></tipo> <matricula><%= datos.Matricula %></matricula> <velocidad><%= datos.Velocidad %></velocidad> </vehiculo> %> </vehiculos> vehiculos.Save("C:\vehiculos.xml") Me.WebBrowser1.Navigate("C:\vehiculos.xml") MessageBox.Show("Datos guardados") End Sub End Class Obser v ando con det enim ient o est e ej em plo, podem os v er que por un lado hem os cr eado una est r uct ur a de dat os, que ut ilizar em os m ás adelant e par a cr ear los obj et os que ut ilizar em os par a cr ear al air e nuest r o docum ent o XML. Dent r o del código del ev ent o Click del cont r ol But t on, cr ear em os obj et os de t ipo Vehiculo, que cor r esponde con la est r uct ur a ant er ior m ent e cr eada, y const r uir em os un docum ent o XML con los dat os de los obj et os cr eados. Finalm ent e, guar dar em os el docum ent o XML cr eado en m em or ia al disco dur o, y m ost r ar em os su cont enido en el cont r ol W ebBr ow ser . El r esult ado final obt enido, es el que se puede ver en la siguient e im agen: Figur a 7 .2 .- Ej em plo en ej ecución del uso de lit er ales en LI N Q t o XM L Com o podem os apr eciar , el t r abaj o con docum ent os XML en Visual Basic 2010 es r ealm ent e sencillo y pr oduct ivo gr acias a LI NQ. Hast a el m om ent o, hem os vist o com o t r abaj ar con LI NQ t o Obj ect s y LI NQ t o XML, sin em bar go, aún no hem os vist o com o t r abaj ar con fuent es de dat os y LI NQ. Com o r ecor dar á, al pr incipio del capít ulo dedicado a LI NQ, vim os un r esum en de los pr oveedor es exist ent es de LI NQ. Vim os en una im agen, ese r esum en. La im agen de r ecor dat or io, es la siguient e: Figur a 7 .3 .- Ar quit ect ur a de LI N Q Com o puede obser var en la im agen, la par t e que cor r esponde al t r abaj o con LI NQ y ADO.NET, est á const it uida por t r es pr oveedor es que nos per m it en t r abaj ar con dat os. Est o son LI NQ t o Dat aSet , LI NQ t o SQL y LI NQ t o Ent it ies. A cont inuación, ver em os cada uno de ellos y com o se ut iliza en Visual Basic 2010. LI N Q t o D a t a Se t Com o t odos sabem os a est as alt u r as, los Dat aSet con st t u y en la base par a t r abaj ar con dat os en m em or ia, descon ect ados de la fu en t e de dat os. LI NQ t o Dat aSet n os ofr ece la posiblidad de t r abaj ar con LI NQ y fuen t es de dat os desconect adas, o lo qu e es lo m ism o, usar LI NQ par a m an ipu lar y t r abaj ar con los dat os de un Dat aSet . Par a t r abaj ar con LI NQ y Dat aSet , n o debem os pen sar en nu evo par adigm a de t r abaj o y m an ipu lac ón de los dat os, sin o de pensar en LI NQ com o u n ser v ic o m ás que se ofr ece par a t r abaj ar con Dat aSet . Es decir , podr em os t r abaj ar con los Dat aSet t al y com o lo hacem os h ast a ah or a, y aplicar LI NQ par a t r at ar de sacar t odo el pr ov ech o posible. La ú n ica r egla de or o n o obst ant e, es qu e los Dat aSet con los qu e t r abaj ar em os, ser án Dat aSet t ipados, es decir , Dat aSet qu e poseen u n os t ipos de dat os est ablecidos. Pr a ct ica n do con LI N Q t o D a t a Se t En el siguient e ej em plo, v er em os com o ut ilizar LI NQ en Dat aSet s. Par a ello, cr ear em os u na est r uct u r a a la qu e ir em os dando u n a ser ie de valor es y cr ear em os así, un a list a de est r u ct u r as par a cr ear post er ior m en t e u n Dat aSet y su cor r espondien t e Dat aTable, e ir agr egan do los elem en t os de la est r u ct u r a al Dat aTable de ese Dat aSet . Post er ior m ent e, u t ilizar em os LI NQ par a acceder a los dat os del Dat aSet . El ej em plo, qu edar á de la sigu ien t e for m a: Public Structure Persona Public Enum SexoPersona hombre mujer End Enum Public Nombre As String Public Sexo As SexoPersona Public Edad As Byte End Structure Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Creamos una lista de tipo Persona Dim listaPersonas As New List(Of Persona) Dim PersonaUno As New Persona With {.Nombre = "Daniel", .Edad = 27, .Sexo = Persona.SexoPersona.hombre} listaPersonas.Add(PersonaUno) Dim PersonaDos As New Persona With {.Nombre = "Jimena", .Edad = 29, .Sexo = Persona.SexoPersona.mujer} listaPersonas.Add(PersonaDos) Dim PersonaTres As New Persona With {.Nombre = "Alberto", .Edad = 24, .Sexo = Persona.SexoPersona.hombre} listaPersonas.Add(PersonaTres) ' Creamos el DataSet Dim personasDataSet As New DataSet() ' Agregamos una tabla al DataSet personasDataSet.Tables.Add("TablaPersonas") ' Agregamos tres columnas a la tabla personasDataSet.Tables("TablaPersonas").Columns.Add("Nombre") personasDataSet.Tables("TablaPersonas").Columns.Add("Edad") personasDataSet.Tables("TablaPersonas").Columns.Add("Sexo") ' Recorremos los elementos de la lista Persona ' y vamos agregando esos elementos al DataSet For Each empleado In listaPersonas ' Creamos una nueva fila Dim fila As DataRow = personasDataSet.Tables("TablaPersonas").NewRow() fila("Nombre") = empleado.Nombre fila("Edad") = empleado.Edad fila("Sexo") = empleado.Sexo ' Agregamos la fila personasDataSet.Tables("TablaPersonas").Rows.Add(fila) Next ' Buscamos datos dentro del DataSet Dim datosBuscados = From datos In personasDataSet.Tables("TablaPersonas") _ Where datos.Item("Edad") > 25 _ Select nombre = datos.Item("Nombre"), flagSexo = If(datos.Item("Sexo") = "hombre", True, False), sexo = datos.Item("Sexo") ' Mostramos los datos Dim resultado As String = "" For Each dato In datosBuscados resultado &= String.Format("{0} es {1} {2}", dato.nombre, If(dato.flagSexo, "un", "una"), dato.sexo) & vbCrLf Next MessageBox.Show(resultado) End Sub End Class N ov eda d e n Visual Basic 2 0 1 0 : u n a de las n ov edades de Visu al Basic 20 1 0, es que ah or a, I f puede fu ncion ar de la m ism a for m a a com o lo h acía I if. En n uest r os desar r ollos podr em os segu ir u t ilizando I if, per o I f, t am bién fu nciona desde Visu al Basic 2 0 10 de la m ism a for m a. En el ej em plo ant er ior , podem os ver qu e bu en a par t e del código la h em os ded cado a cr ear el obj et o Dat aSet y su obj et o Dat aTable, alim en t ar ese Dat aTable con elem en t os, y post er ior m en t e, cr ear la in st r u cción LI NQ cor r espon dien t e par a ex t r aer los elem en t os r esu lt an t es. Com o podem os apr eciar , la for m a de t r abaj ar es siem pr e la m ism a. Algo qu e aú n n o h em os m en cion ado cu ando t r abaj am os con LI NQ es t odo lo r elat iv o a la eficiencia, pr oduct iv dad e in m ediat ez a la h or a de t r abaj ar con LI NQ y los dat os. El u so de LI NQ es r ealm en t e r ápido, m u cho m ás de lo qu e m u ch a gen t e pu ede cr eer en u n pr im er m om ent o. A con t in uación , ver em os com o t r abaj ar con LI NQ y ot r os m odelos o fuen t es de dat os. LI N Q t o SQL Ant er ior m ent e, h em os v ist o com o t r abaj ar con LI NQ t o Dat aSet par a t r abaj ar con fu ent es de dat os descon ect adas, per o, ¿y si quer em os t r abaj ar con fuen t es de dat os conect adas?. En ese caso, podr em os ut ilizar LI NQ t o SQL o LI NQ t o Ent it ies. ¿Cuál de ellos debem os u t ilizar ?. LI NQ t o Ent it ies est á pr epar ado par a t r abaj ar con cualquier fu ent e de dat os conect ada, m ient r as que LI NQ t o SQL est á pr epar ada par a t r abaj ar ún icam en t e con fuent es de dat os Micr osoft SQL Ser v er , por lo qu e par ece clar o, que si t enem os u n m ot or de base de dat os com o Micr osoft SQL Ser v er , podem os t r abaj ar t ant o con LI NQ t o SQL com o con LI NQ t o Ent it ies, aunque si el m ot or de base de dat os con el que est am os t r abaj ando es Or acle, LI NQ t o SQL no nos ser v ir á. Aún y así, LI NQ t o Ent it ies es liger am ent e difer ent e a LI NQ t o SQL y ofr ece unas car act er íst icas m ás av anzadas. ¿Se nt e ncia s LI N Q o se nt e ncia s SQL? LI NQ t o SQL dest aca por per m it ir n os t r abaj ar con obj et os r elacion ales ( O/ R) a t r av és del diseñ ador qu e ha sido inclu ido en Visual St udio 201 0. Adicion alm ent e, LI NQ t o SQL t iene la h abilidad de con st r uir la in st r u cción SQL cor r espondien t e. El pr ogr am ador debe olv idar se de com o const r uir esa sent encia SQL, y a que es el pr opio com pilador y el m ot or de ej ecución de .NET Fr am ewor k , el que se en car ga de cr ear y lanzar por nosot r os la sen t en cia SQL cor r espondient e. Com o com ent ábam os ant es, LI NQ t o SQL t r abaj a con Micr osoft SQL Ser v er , por lo que las sent encias SQL cr eadas por LI NQ t o SQL ser án par a ese m ot or de base de dat os. De for m a difer ent e a la que m ucha gent e piensa, esas sent encias gener adas por LI NQ son sent encias opt im izadas en r endim ient o, así que debem os est ar t r anquilos a la hor a de ut ilizar LI NQ. Pr a ct ica n do con LI N Q t o SQL Par a pr act icar con LI NQ t o SQL deber em os in iciar Visual St udio 20 10 . En con cr et o, in iciar em os un pr oy ect o de for m u lar io Windows e inser t ar em os un cont r ol But t on y un cont r ol D at a Gr idVie w dent r o del for m u lar io. Un a vez h echo est o, har em os clic sobr e el pr oy ect o con el bot ón der echo del r at ón, y apar ecer á una ven t an a dent r o de la cu al, deber em os seleccionar la plant illa Cla ses de LI N Q t o SQL per t en ecien t e al gr u po D at os. Est o es lo que se puede ver en la siguient e im agen: Figur a 7 .4 .- Sele cción de la pla nt illa Cla ses de LI N Q t o SQL Una v ez seleccionada est a plan t illa, el pr oy ect o m ost r ar á una nuev a v ent ana que cor r esponde con el diseñador del m odelo r elacion al, donde deber em os indicar qu e par t es del m odelo de dat os de SQL Ser v er qu er em os incluir en la plant illa. A cont inuación, deber em os r ealizar la siguient e t ar ea, que consist e en cr ear una conex ión con la base de dat os de SQL Ser v er . Par a ello, podem os ut ilizar el Explor ador de se r vidor es y agr egar en él la conexión qu e quer em os ut ilizar en LI NQ t o SQL. Cuan do hay am os agr egado la conex ión con la base de dat os, y dent r o de la v ent ana del Ex plor a dor de ser v idor es, podr em os ar r ast r ar y solt ar sobr e el diseñador , los obj et os del m odelo de dat os que qu er am os ut ilizar en LI NQ t o SQL. En el ej em plo con el que v am os a t r abaj ar , los obj et os que hem os ar r ast r ado y solt ado sobr e el diseñador , son los que se m u est r an en la siguien t e figur a: Figur a 7 .5 .- Obj et os de la base de dat os en el diseñador de LI N Q t o SQL A obser v ar : la ex t en sión del diseñador del m odelo r elacional de LI NQ t o SQL es dbm l, que cor r esponde con la plant illa de LI NQ t o SQL que hem os seleccionado en la figur a 7.4 . Com o podem os v er en la figur a ant er ior , el diseñador del m odelo r elacion al de LI NQ t o SQL, m uest r a en est e caso, dos t ablas y su posible r elación. Las t ablas cont ienen adem ás, dat os con los qu e podr em os oper ar o t r abaj ar . Aquí es donde en t r a LI NQ y don de usán dolo, obt en dr em os una gr an pr odu ct iv idad en n uest r os desar r ollos. Par a fin alizar nu est r o ej em plo, escr ibir em os el sigu ient e código fu ent e: Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Declaramos el contexto Dim contexto As New DataClasses1DataContext() ' Ejecutamos la sentencia LINQ correspondiente Dim datos = From tablaPropietario In contexto.Propietarios, _ tablaVehiculos In contexto.Vehiculos _ Where tablaPropietario.Matricula = tablaVehiculos.Matricula _ Group tablaVehiculos By tablaPropietario.NIF Into Group _ Select NIF, Cantidad = NIF.Count() ' Mostramos el resultado final Me.DataGridView1.DataSource = datos End Sub End Class Nu est r o ej em plo en ej ecución, es el que se m uest r a en la figur a siguien t e: Figur a 7 .6 .- Ej em plo de l uso de LI N Q t o SQL en e j ecución Com o podem os apr eciar en el código fuent e de la aplicación que hem os escr it o, la cant idad de código fuent e que hem os agr egado es r ealm ent e pequeña. Analizando nuest r o código fuent e, v em os que por un lado, h em os declar ado el cont ex t o, o lo que es lo m ism o, la clase del m odelo r elacional que hem os const r uido ( el ficher o de ex t ensión dbm l) . Si abr im os est e ficher o, obser v ar em os qu e t iene un código fu ent e asociado qu e cor r espon de con el m odelo r elacional pasado a u na clase, conser v an do en él cada u no de los cam pos de la t abla o de las t ablas, con sus t ipos de dat os ( fuer t em en t e t ipada) y sus r elaciones si las hay. De est a m aner a, est am os t r abaj ando sobr e una clase y sus pr opiedades, que cor r esponden con los cam pos de las t ablas, por lo que r esult a m uy difícil equ iv ocar se. Ot r a par t icular idad del m odelo r elacion al cr eado en Visual St udio 20 10 , es qu e el m odelo r elacion al se conect a con SQL Ser v er cuando es ut ilizado, y est o es pr áct icam ent e t r aspar ent e par a el pr ogr am ador , ya que t odo est e pr oceso de con ect ar se, ej ecu t ar la in st r u cción cor r espondient e, obt en er los dat os y desconect ase nu ev am ent e de la fuent e de dat os, la r ealiza el sist em a dent r o de la clase del m odelo r elacional ( ficher o dbm l) , per o la pr egunt a que podr íam os hacer nos ahor a es... ¿dónde se encuent r a por lo t ant o la necesar ia cadena de conex ión par a conect ar se a la fuent e de dat os?. La cadena de conex ión la encont r ar em os en la configur ación de la aplicación. Par a acceder a ella, deber em os hacer clic con el bot ón der ech o del r at ón sobr e el pr oy ect o, y seleccionar la opción Pr opie da des del m enú em er gent e. Finalm ent e, acceder em os a la solapa Configur ación par a acceder al v alor de la cadena de conex ión qu e ut iliza LI NQ t o SQL par a conect ar se. Est o es lo que se puede ver en la sigu ien t e im agen : Figur a 7 .7 .- Solapa de Configur ación del pr oyect o, con la cadena de conexión del ej em plo de LI N Q t o SQL LI N Q t o En t it ie s A est as alt ur as, t endr á clar o algunas de las v ent aj as de t r abaj ar con LI NQ, sin em bar go, LI NQ dent r o de Micr osoft .NET Fr am ewor k 3.5 no pr opor ciona un acceso dir ect o a cualquier t ipo de obj et o, solam ent e a aquellos que est én pr epar ados par a t r abaj ar con LI NQ. Dent r o de los pr oveedor es de LI NQ, Micr osoft pr opor ciona uno m uy especial, m uy par ecido a LI NQ t o SQL, per o con not ables difer encias. Est e pr oveedor se llam a LI NQ t o Ent it ies, y es un pr ov eedor pr epar ado par a t r abaj ar con cualquier gest or de base de dat os, pr opor cionando algunas vent aj as que no pr opor ciona LI NQ t o SQL. Aún y así, t am bién LI NQ t o Ent it ies posee algunas difer encias con r espect o a LI NQ t o SQL que le per j udican, com o por ej em plo que LI NQ t o SQL sí est á pr epar ado par a t r abaj ar con pr ocedim ient os alm acenados, m ient r as que la pr im er a ver sión de LI NQ t o Ent it ies no lo est á. De hecho, ést a es una de las car act er íst icas m ás dem andadas por la com unidad de desar r ollador es y que el equipo de Micr osoft de LI NQ t o Ent it ies, t iene encim a de la m esa par a poner se con ella cuant o ant es. Recor dem os adem ás, que m ient r as LI NQ t o SQL solo est á pr epar ado par a t r abaj ar con Micr osoft SQL Ser ver , LI NQ t o Ent it ies est á pr epar ado par a t r abaj ar con cualquier m ot or de base de dat os. Solo ser á necesar io t ener inst alados los com ponent es adecuados par a llev ar a buen t ér m ino nuest r as necesidades. De hecho, en I nt er net puede encont r ar ya algunos de est os pr ov eedor es list os par a ser usados en m ot or es de bases de dat os com o Or acle, DB2 o My Sql. Con LI NQ t o Ent it ies, podem os t r abaj ar por lo t ant o, con m ot or es de bases de dat os y con EDM ( Ent it y Dat a Model) , o lo que es lo m ism o, una r epr esent ación lógica de un m odelo de dat os. LI NQ t o SQL nos ofr ecía un m apeo de dat os m uy sencillo, y par a m uchos desar r ollos Soft war e, ser á el pr ov eedor adecuado, per o en ot r as cir cunst ancias, necesit am os algo m ás. Ese "algo m ás" nos lo pr opor ciona LI NQ t o Ent it ies, que se encar ga de m apear los dat os con m ecanism os m ás com plej os y pot ent es a lo que lo hace LI NQ t o SQL. Finalm ent e, y par a que no se lleve a engaños, debem os indicar que t ant o LI NQ t o SQL com o LI NQ t o Ent it ies, no est án pr epar ados par a sopor t ar r elaciones de m uchos a m uchos con car ga út il ( Pay load r elat ionship) . El obj et iv o del equipo de t r abaj o de LI NQ t o Ent it ies, es t ener est a car act er íst ica list a par a la pr óx im a ver sión de LI NQ t o Ent it ies. Per o par a ut ilizar LI NQ t o Ent it ies, necesit ar em os no obst ant e, inst alar un par de agr egados a nuest r a inst alación de Visual St udio 2010. Pr e pa r a ndo Visua l St udio 2 0 1 0 pa r a t r a ba j a r con LI N Q t o Ent it ie s Par a t r abaj ar con LI NQ t o Ent it ies, deber em os pr epar ar adecuadam ent e nuest r o ent or no de t r abaj o, Visual St udio 2010. Deber em os descar gar e inst alar Micr osoft .NET Fr am ewor k 3.5 SP1 ( Ser v ice Pack 1) en pr im er lugar , r einiciar el sist em a ( r ecom endado) , e inst alar Visual St udio 2010 SP 1 post er ior m ent e. Es posible que ent r e la inst alación de Micr osoft .NET Fr am ewor k 3.5 SP1 y de Visual St udio 2010 SP1, el sist em a le pida inst alar algún paquet e de Soft war e necesar io par a llev ar a buen t ér m ino la inst alación. Esos posibles av isos le apar ecer án en la vent ana de inst alación, y lo único que t endr á que hacer es seguir las inst r ucciones. Tenga a m ano t am bién, los CD o DVD or iginales de la inst alación, por que es m uy posible que el pr oceso de act ualización le pida esa infor m ación. Pr a ct ica ndo con LI N Q t o Ent it ie s En est e punt o, deber íam os est ar list os par a t r abaj ar con LI NQ t o Ent it ies, y es eso j ust am ent e, lo que vam os a hacer ahor a. I niciar em os un nuev o pr oy ect o de t ipo aplicación Windows con Visual St udio 2010, e inser t ar em os en el for m ular io un cont r ol But t on y un cont r ol D at aGr idView . La siguient e acción que r ealizar em os, ser á la de agr egar un elem ent o de t ipo LI NQ t o Ent it ies, que nos per m it ir á t r abaj ar con la fuent e de dat os que elij am os. Par a agr egar un nuev o elem ent o al pr oyect o, har em os clic dent r o de la vent ana del Explor ador de soluciones sobr e el pr oy ect o con el bot ón der echo del r at ón, y seleccionar em os la opción Agr egar > N uevo elem ent o del m enú em er gent e. Apar ecer á una v ent ana dent r o de la cual, deber em os encont r ar la plant illa AD O.N ET Ent it y D at a M odel, la cual localizar em os r ápidam ent e en el gr upo de plant illas de t ipo D at os. Est a es la vent ana que se m uest r a a cont inuación: Figur a 7 .8 .- Selección de la plant illa AD O.N ET Ent it y D at a M odel Har em os doble clic sobr e la plant illa y ést a se nos incor por ar á al pr oy ect o. Al incor por ar se est a plant illa al pr oy ect o, Visual St udio 2010 lanzar á un asist ent e, cuya pr im er a v ent ana, consist e en seleccionar el cont enido del m odelo. Dent r o de la selección, podem os elegir ent r e gener ar el m odelo desde la base de dat os, o gener ar el m odelo par t iendo de un m odelo v acío. Nuest r a int ención es seleccionar t odas las t ablas en el m odelo, por lo que seleccionar em os la pr im er a opción. Est o es lo que se puede ver en la siguient e im agen: Figur a 7 .9 .- Vent ana pr incipal del asist ent e par a el ED M - Ent it y D at a M odel A cont inuación, har em os clic sobr e el bot ón Siguient e. De est a for m a, apar ecer á una v ent ana dent r o de la cual, podr em os elegir la conex ión de dat os que quer em os ut ilizar . Nos asegur ar em os de que t enem os la conexión de dat os adecuada, y en caso cont r ar io, cr ear em os una. En est a m ism a vent ana, podr em os cr ear un nom br e par a el nom br e de la conexión que ser á ut ilizado en el ar chiv o de configur ación de la aplicación App.config. Podr íam os de t odas las m aner as, no seleccionar est a opción que apar ece seleccionada por defect o. En nuest r o, hem os dej ado las opciones t al y com o apar ecen en la im agen. Par a est e ej em plo, ut ilizar é una conex ión de dat os de Micr osoft SQL Ser ver . En m i caso, la vent ana con la configur ación cr eada es la que se indica en la siguient e im agen: Figur a 7 .1 0 .- Vent ana de selección de la conexión de dat os Una v ez r ealizado est os pasos, har em os clic en el asist ent e sobr e el bot ón Siguient e. Apar ecer á ent onces una vent ana en el asist ent e, dent r o de la cual podr em os seleccionar los obj et os de la base de dat os que quer em os ut ilizar . Com o podr em os ver en esa vent ana, podr em os indicar no solo las t ablas que quer em os agr egar al m odelo, sino t am bién las v ist as y los pr ocedim ient os alm acenados. Par a est e ej em plo, solo seleccionar em os las t ablas de nuest r o m odelo, que es exact am ent e el m ism o que ut ilizam os en el capít ulo de LI NQ t o SQL. Est a selección es la que se m uest r a en la siguient e im agen: Figur a 7 .1 1 .- Obj et os de la base de dat os seleccionados en LI N Q t o Ent it ies Par a concluir con el asist ent e, har em os clic sobr e el bot ón Finalizar . De est a m aner a, se gener ar á la configur ación del m odelo t al y com o lo hem os indicado en el asist ent e, y se gener ar án las siguient es par t es: La pr im er a cosa que nos llam ar á la at ención es el m odelo de dat os que se habr á dibuj ado en Visual St udio 2010, y que en nuest r o ej em plo cor r esponder á con el siguient e: Figur a 7 .1 2 .- ED M r epr esent ado en Visual St udio 2 0 1 0 después de ej ecut ar el asist ent e de LI N Q t o Ent it ies En nuest r o diagr am a, podem os localizar la ent idad Vehiculo y la ent idad Pr opiet ar io. Com o podem os obser v ar en el diagr am a del EDM, el sist em a ha det er m inado por nosot r os una r elación de t ipo 1 a m uchos ent r e la ent idad Vehiculo y la ent idad Pr opiet ar io, por lo que podr íam os decir r ápidam ent e v iendo el diagr am a, que una per sona puede ser pr opiet ar io de m ás de un vehículo. En la par t e infer ior de Visual St udio 2010, podr em os encont r ar t am bién, una v ent ana que cont iene los det alles de asignación de cada una de las ent idades. Un ej em plo de los det alles de asignación de la t abla Vehiculo es la que se indica en la siguient e im agen: Figur a 7 .1 3 .- D et alles de asignación de la ent idad Vehiculo de nuest r o ED M en LI N Q t o Ent it ies Si obser v am os det enidam ent e la vent ana con los det alles de asignación, v er em os que los cam pos de la t abla se han conv er t ido en pr opiedades, y que los cam pos clave de la t abla, est án así indicados en el EDM. En sí, el EDM r epr esent a fielm ent e el m odelo de dat os r elacional, per m it iéndonos t r abaj ar con él de una for m a r ápida y dir ect a, ev it ando er r or es de asignación y asegur ándonos una fiabilidad adecuada. Per o hast a aquí, la pr epar ación del EDM y algunos com ent ar ios que hem os hecho par a que se fam iliar ice con él. ¿Cuál es nuest r a siguient e t ar ea?. Desar r ollar un ej em plo pr áct ico que nos m uest r e com o ut ilizar LI NQ t o Ent it ies en nuest r os desar r ollos. Eso es j ust am ent e lo que har em os a cont inuación. Ya t enem os pr epar ado nuest r o for m ular io Windows con los cont r oles que quer em os ut ilizar . Eso ya lo indicam os al pr incipio de est e capít ulo. A cont inuación, deber em os escr ibir el código de nuest r a aplicación, que quedar á de la siguient e m aner a: Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Declaramos el contexto Dim contexto As New PruebasEntities() ' La conexila abre y cierra el contexto por nosotros ' Indicamos la instrucciLINQ que vamos a ejecutar Dim datos = From tablaPropietario In contexto.Propietario, _ tablaVehiculo In contexto.Vehiculo _ Where tablaPropietario.Matricula = tablaVehiculo.Matricula _ Order By tablaPropietario.Nombre _ Select tablaPropietario.Nombre, tablaPropietario.NIF, tablaVehiculo.Marca, tablaVehiculo.Modelo ' Mostramos los datos en el control DataGridView Me.DataGridView1.DataSource = datos ' Ajustamos el tamadel control DataGridView ' al tamade los datos de las filas y columnas Me.DataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells) Me.DataGridView1.AutoResizeRows(DataGridViewAutoSizeRowsMode.AllCells) End Sub End Class Nuest r o ej em plo en ej ecución, es el que se m uest r a en la figur a siguient e: Figur a 7 .1 4 .- Ej em plo del uso de LI N Q t o Ent it ies en ej ecución Com o podem os apr eciar en el código fuent e de la aplicación que hem os escr it o, hem os declar ado el cont ext o par a ut ilizar lo en el pr oceso de obt ención de los dat os. Post er ior m ent e hem os declar ado la inst r ucción LI NQ a ej ecut ar . Com o podem os ver , no hem os abier t o ni cer r ado nignuna conex ión con la base de dat os. Est o lo r ealiza LI NQ t o Ent it ies por nosot r os de for m a t r anspar ent e. Finalm ent e, hem os m ost r ado los dat os obt enidos en la ej ecución de la inst r ucción LI NQ, dent r o del cont r ol D at aGr idView . Ahor a bien, ¿dónde se encuent r a la cadena de conexión?. Si accedem os al ficher o App.Config, v er em os un apar t ado que en nuest r o caso es de la siguient e for m a: <connectionStrings> <add name="PruebasEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl; provider=System.Data.SqlClient;provider connection string=&quot;Data Source=.;Initial Catalog=Pruebas; Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" /> </connectionStrings> Si nos fij am os en lo que aquí se indica, podem os obser var que LI NQ t o Ent it ies est á com puest o por el m odelo de ent idades ( EDM) , que consist e en un ficher o de ex t ensión ( edm x) , y t r es ficher os que por defect o est ar án incr ust ados en el ensam blado com o ar chivo de r ecur sos, y que cont ienen la ext ensión ( csdl) , ( ssdl) y ( m sl) . En est a par t e del docum ent o XML, podem os v er t am bién el pr ov eedor de acceso a dat os que vam os a ut ilizar , la cadena de conex ión con la fuent e de dat os, y el nom br e del pr ov eedor de LI NQ ( Syst em .D at a.Ent it yClient ) . Est a par t e de la aplicación es la que cont iene infor m ación r elat iva a la pr opia conect ividad con la fuent e de dat os y a los par ám et r os de configur ación necesar ios par a acceder y m anipular eficient em ent e los dat os. En est e m ódulo ver em os com o t r abaj ar con I r onPyt hon desde Visual Basic par a ej ecut ar dinám icam ent e difer ent es inst r ucciones de código. V B e I r on Pyt h on V B e I r on Pyt h on VB e I r on Py t h on I r onPyt hon es una im plem ent ación del lenguaj e de pr ogr am ación Pyt hon par a la plat afor m a .NET y Silv er light . N ot a: I r onPyt hon debe ser descar gado independient em ent e. En CodePlex hay un pr oyect o dedicado en exclusiva a I r onPyt hon. Est e pr oyect o puede ser localizado en est a dir ección web. El obj et iv o de I r onPy t hon es el de pr opor cionar un m ecanism o par a que podam os ej ecut ar código Py t hon desde nuest r as aplicaciones .NET. De hecho, I r onPy t hon es un int ér pr et e de Pyt hon, es decir , que podem os coger cualquier código de Py t hon y ej ecut ar lo con I r onPy t hon sin pr oblem as. Las v ent aj as por lo t ant o de usar I r onPy t hon es que podem os adem ás int egr ar lo con nuest r as aplicaciones .NET, de hecho, la idea pr incipal es la de ej ecut ar al v uelo o dinám icam ent e código Py t hon. A cont inuación v er em os com o llev ar a cabo est a t ar ea. No hace falt a com ent ar que lo pr im er o que debem os hacer es descar gar e inst alar I r onPy t hon. Ej e m p lo p r á ct ico de l uso de I r onPy t hon A cont inuación iniciar em os Visual St udio 2010 y con él una aplicación de Windows con Visual Basic 2010. Agr egar em os una r efer encias al pr oy ect o a los ensam blados: I r onPy t hon I r onPy t hon.Modules Micr osoft .Scr ipt ing Micr osoft .Scr ipt ing.Cor e Dent r o del pr oyect o, agr egar em os r efer encias a los siguient es nom br es de espacio: I m por t s I r onPyt hon.Host ing I m por t s Micr osoft .Scr ipt ing.Host ing Una vez hecho est o, agr egar em os la car pet a Lib de I r onPyt hon y que encont r ar em os en la car pet a de inst alación de I r onPyt hon a la car pet a Debug de nuest r o pr oyect o. Finalm ent e, har em os doble clic sobr e el for m ular io y escr ibir em os el siguient e código: Dim engine As ScriptEngine = Python.CreateEngine() Dim code As String = "(2 * 2) + (8 / 3)" Dim source As ScriptSource = engine.CreateScriptSourceFromString(code, Microsoft.Scripting.SourceCodeKind.Expression) Dim result As Integer = source.Execute(Of Int32)() MessageBox.Show(result.ToString()) En est a ej em plo, hem os vist o com o ej ecut ar una aplicación que lanza en t iem po de ej ecución una inst r ucción Py t hon. Ahor a bien, quizás t engam os la idea de lanzar una inst r ucción Pyt hon con par ám et r o incluido, en cuy o caso deber em os indicar pr ev iam ent e el par ám et r o y su v alor . En el siguient e ej em plo, v er em os com o llevar a cabo est a t ar ea. La for m a de r ealizar el ej em plo es la m ism a que en el caso ant er ior , var iando únicam ent e las líneas de código que quer em os lanzar . En pr im er lugar escr ibir em os una clase que ut ilizar em os par a lanzar la cont r a Py t hon: Public Class Employee Public Property Id As Integer Public Property Name As String Public Property Salary As Integer Public Sub Employee(ByVal id As Integer, ByVal name As String, ByVal salary As Integer) Me.Id = id Me.Name = name Me.Salary = salary End Sub End Class Una vez definida nuest r a clase, ej ecut ar em os el siguient e código par a consum ir los v alor es de la clase y obt ener el r esult ado cor r espondient e: Dim engine As ScriptEngine = Python.CreateEngine() Dim runtime As ScriptRuntime = engine.Runtime Dim scope As ScriptScope = runtime.CreateScope() Dim code As String = "emp.Salary * 0.3" Dim source As ScriptSource = engine.CreateScriptSourceFromString(code, Microsoft.Scripting.SourceCodeKind.Expression) Dim empleado = New Employee With { .Id = 1, .Name = "Francisco", .Salary = 1000} scope.SetVariable("emp", empleado) Dim result = Convert.ToDouble(source.Execute(scope)) MessageBox.Show(result.ToString()) Com o podem os apr eciar , el uso de I r onPy t hon nos per m it e cr ear aplicaciones m ucho m ás r icas que nos per m it ir á ej ecut ar código en t iem po de ej ecución apor t ando m uchas m ás posibilidades a nuest r as aplicaciones. VB e I r on Ru by I r onRuby es una im plem ent ación del lenguaj e de pr ogr am ación Ruby par a la plat afor m a .NET y Silv er light . N ot a: I r onRuby debe ser descar gado independient em ent e. En CodePlex hay un pr oy ect o dedicado en ex clusiv a a I r onRuby . Est e pr oyect o puede ser localizado en est a dir ección web. El obj et iv o de I r onRuby es el de pr opor cionar un m ecanism o par a que podam os ej ecut ar código Ruby desde nuest r as aplicaciones .NET. De hecho, I r onRuby es un int &ecuat e; r pr et e de Ruby, es decir , que podem os coger cualquier código de Ruby y ej ecut ar lo con I r onRuby sin pr oblem as. Al igual que con I r onPyt hon, con I r onRuby podem os int egr ar lo con nuest r as aplicaciones .NET, de hecho, la idea pr incipal es la de ej ecut ar al vuelo o dinám icam ent e código Ruby , est é o no en un ficher o ext er no o dir ect am ent e inv ocar lo desde nuest r a aplicación. A cont inuación v er em os com o llev ar a cabo est a t ar ea. No hace falt a com ent ar que lo pr im er o que debem os hacer es descar gar e inst alar I r onRuby . Ej e m p lo p r á ct ico de l uso de I r onRub y A cont inuación iniciar em os Visual St udio 2010 y con él una aplicación de Windows con Visual Basic 2010. Agr egar em os una r efer encias al pr oy ect o a los ensam blados: I r onRuby I r onRuby .Libr ar ies Micr osoft .Scr ipt ing Micr osoft .Scr ipt ing.Cor e Dent r o del pr oyect o, agr egar em os r efer encias a los siguient es nom br es de espacio: I m por t s I r onRuby .Host ing I m por t s Micr osoft .Scr ipt ing.Host ing Finalm ent e, har em os doble clic sobr e el for m ular io y escr ibir em os el siguient e código: Dim engine As ScriptEngine = IronRuby.Ruby.CreateEngine() Dim code As String = "(2 * 2) + (8 / 3)" Dim source As ScriptSource = engine.CreateScriptSourceFromString(code, Microsoft.Scripting.SourceCodeKind.Expression) Dim result As Integer = source.Execute(Of Int32)() MessageBox.Show(result.ToString()) En est a ej em plo, hem os vist o com o ej ecut ar una aplicación que lanza en t iem po de ej ecución una inst r ucción Ruby . Ahor a bien, quizás t engam os la idea de lanzar una inst r ucción Ruby con par ám et r o incluido, en cuyo caso deber em os indicar pr ev iam ent e el par ám et r o y su v alor . En el siguient e ej em plo, v er em os com o llevar a cabo est a t ar ea. La for m a de r ealizar el ej em plo es la m ism a que en el caso ant er ior , var iando únicam ent e las líneas de código que quer em os lanzar . En pr im er lugar escr ibir em os una clase que ut ilizar em os par a lanzar la cont r a Ruby : Public Class Employee Private Property Id As Integer Private Property Name As String Private Property Salary As Integer Public Sub Employee(ByVal id As Integer, ByVal name As String, ByVal salary As Integer) Me.Id = id Me.Name = name Me.Salary = salary End Sub End Class Una vez definida nuest r a clase, ej ecut ar em os el siguient e código par a consum ir los v alor es de la clase y obt ener el r esult ado cor r espondient e: Dim engine As ScriptEngine = IronRuby.Ruby.CreateEngine() Dim runtime As ScriptRuntime = engine.Runtime Dim scope As ScriptScope = runtime.CreateScope() Dim code As String = "emp.Salary * 0.3" Dim source As ScriptSource = engine.CreateScriptSourceFromString(code, Microsoft.Scripting.SourceCodeKind.Expression) Dim empleado = New Employee With { .Id = 1, .Name = "Francisco", .Salary = 1000} scope.SetVariable("emp", empleado) Dim result = Convert.ToDouble(source.Execute(scope)) MessageBox.Show(result.ToString()) Com o podem os apr eciar , el uso de I r onRuby nos per m it e cr ear aplicaciones m ucho m ás r icas que nos per m it ir á ej ecut ar código en t iem po de ej ecución apor t ando m uchas m ás posibilidades a nuest r as aplicaciones. Ot r a par t icular idad es la r elación de inst r ucciones de ej ecución que exist e ent r e I r onPyt hon e I r onRuby. Si com par am os dos ej em plos sim ilar es, ver em os que son pr áct icam ent e idént icos, lo cual nos facilit a m ucho las cosas. Ev ident em ent e, Py t hon posee una nom enclat ur a de código difer ent e a la de Ruby , algo que se r ecom ienda conocer en el caso de ut ilizar am bos lenguaj es en nuest r as aplicaciones. Aplica ción de e j e m plo M SD N Vide o A cont inuación vam os a desar r ollar una aplicación que nos per m it a explor ar las pr incipales car act er íst icas de Visual St udio. Puede descar gar el código fuent e en su m áquina y explor ar lo o m odificar lo par a conocer de for m a pr áct ica cóm o usar Visual Basic par a desar r ollar aplicaciones r eales. Tam bién puede explor ar los videos donde const r uim os est a aplicación paso a paso. La a plica ción M SD N Video es una aplicación de ej em plo em pr esar ial desar r ollada en España por la com unidad de desar r ollo y Micr osoft . Puede ut ilizar se par a com pr obar las m ej or es pr áct icas en la const r ucción aplicaciones dist r ibuidas, escalables y con dist int os t ipos de client es ( Windows, Web y m óviles) . La aplicación que desar r ollar em os en est e t ut or ial es una ver sión r educida de MSDN Video donde podr á ver Visual St udio en acción en un escenar io client e / ser vidor sencillo. Cód ig o f u e n t e d e M SD N V id e o Puede descar gar el código fuent e de MSDN Video y v isionar lo o edit ar lo en su m áquina. N ot a: MSDN Video ut iliza una base de dat os par a alm acenar su est ado. Si desea ej ecut ar la aplicación en su m áquina necesit ar á SQL Ser ver 2005 Expr ess o super ior inst alado. Vide os e x plica t iv os Si desea v er cóm o se hizo est a aplicación puede v isionar est os v ideos donde desar r ollam os la aplicación paso a paso: Video 1. Cr eación de la base de dat os y el acceso a dat os Video 2. Esquelet o de for m ular ios Video 3. For m ular io Nuev o Socio Video 4. For m ular io Alquilar Video 5. For m ular io Dev olv er Video 6. Conclusiones M SD N Vide o e m pr e sa r ia l Puede descar gar la v er sión em pr esar ial de MSDN Video y v er cóm o podem os conv er t ir la aplicación que hem os desar r ollado aquí en un sist em a dist r ibuido com plet o, con acceso a t r av és de ser v icios w eb desde client es Window s, Web y disposit iv os m óv iles. W e b d e M SD N V id e o Código fuent e, t ut or iales y v ideos ex plicat iv os de la v er sión com plet a de MSDN Video. D e sa r r olla con M SD N Puedes colabor ar con MSDN Video, t e pr opor cionam os m at er iales de for m ación, v ideos y ev ent os par a que apr endas las t ecnologías ut ilizadas en la aplicación.