Professional Documents
Culture Documents
Második kötet
Andrew Troelsen
A C# 2008
és a . N ET 3.5
Második kötet (20-33. fejezet)
Andrew Troelsen
200 9
A C# 2008 és a .NET 3.5 - Második kötet (20-33. fejezet és két függelék)
A negyedik kiadás magyarul, két kötetben
Pro C#2008 and the .NET 3.5 Platform, Fourth Edition
Andrew Troelsen
ISBN 978-963-9863-10-1
Minden jog fenntartva. Jelen könyvet, illetve annak részeit a kiadó engedélye
nélkül tilos reprodukálni, adatrögzítő rendszerben tárolni, bármilyen formában
vagy eszközzel elektronikus úton vagy más módon közölni.
viii
Tartalomjegyzék
ix
Tartalomjegyzék
x
Tartalomjegyzék
xi
Tartalomjegyzék
xii
Tartalomjegyzék
xiii
Tartalomjegyzék
xiv
Tartalomjegyzék
XV
Tartalomjegyzék
xvi
Tartalomjegyzék
xvii
Tartalomjegyzék
xviii
Tartalomjegyzék
xix
Tartalomjegyzék
XX
Tartalomjegyzék
xxi
Tartalomjegyzék
xxii
Tartalomjegyzék
31. ASP. NET-weboldalak készitése ........... . .... . .... ... ... . 685
xxiii
Tartalomjegyzék
A klasszikus ASP problémái . . .......................... . ...... . ... . . .. ................ . .... . .... . 705
Az ASP.NET 1.x főbb előnyei . .. .. .. .. .. . .. ... . .... .. . .................. .. ... . .... . ......... 705
Az ASP.NET legfőbb újdonságai ......................................................... 706
A .NET 3.5 legfőbb webes újdonságai . .. .... . ...... . .... . .... . ... . ....... . .... . ....... 707
Az ASP.NET-névterek ................................................................................ 707
Az ASP.NET weboldal-kódolási modellje . . ................... . ............. .. .
. .. ...... 709
Adatközpontú egyfájlas tesztoldal készítése .......... . .... ..
. .... . ... ........... 710
Az AutoLotDAL.dll fájl manuális hivatkozása .. .. .............. . .... . . 710
.. .
xxiv
Tartalomjegyzék
Az AciRotator használata ...... ....... ...... .. ....... .. . . .... . .. . . ... . ... 767 . . . . . . . . . . . . . . . .
XXV
Tartalomjegyzék
xxvi
Tartalomjegyzék
8. rész: Függelékek
xxvii
Tartalomjegyzék
A szerzőről.......................................................... 928
xxviii
Köszönetnyi Ivánitás
xxxii
A könyv áttekintése
A könyv áttekintése
A Pro C# 2008 and the .NET 3.5 Platform (A C# és a Mícrosoft .NET 3.5.) negyedik
kiadása logikailag nyolc különálló részből áll, s ezek mindegyike további feje
zeteket tartalmaz. Jó néhány témakör, például az alapvető C#-szerkezetek, az
Megjegyzés A magyar változat kiadásának előkészítése során a SZAK Kiadó úgy döntött, hogy
az eredeti könyv tartalmát két kötetben jelenteti meg. Ezt a viszonylag nagy terjedelem indo·
kolja. Az alábbiakban mind a két kötet tartalmát ismertetjük, így biztosítva, hogy az is képet
kapjon a mű egészéről, akinek csak az egyik kötet kerül a kezébe. (Ezt a Bevezetést változat
lan formában mind a két kötetben szerepeltetjük.)
Első kötet
xxxiii
Bevezetés
xxxiv
A könyv áttekintése
Ez a fejezet elsősorban azt mutatja be, mit kell tenni a strukturális kivételke
zelés segítségével a futási időben keletkezett anomáliákkal. Nemcsak az ilyen
jellegű problémák megoldására szolgáló C#-kulcsszavakat ismerjük itt meg
(try, catch, throw és fi nal l y) , hanem az alkalmazásszintű és a rendszerszintű
kivételek közötti különbséget is. Megismerhetünk továbbá többféle, a Visual
Studio 2008-ban található eszközt, amelyek segítségével hibakeresést végez
hetünk a figyelmen kívül hagyott kivételek között.
Ennek a résznek az utolsó fejezete azt tárgyalja, hogy hogyan kezeli a CLR a
memóriát a .NET szemétgyűjtőjének a segítségéveL Megérthe�ük az alkal
mazásgyökerek, az objektumnemzedékek és a system. GCType szerepét. Az
alapok megismerése után, a fejezet további része az eldobható objektumokkal
(az ro i sposab l e intedészen keresztül) és a véglegesítő folyamattal (a sys
tem. obj ect. Fi nal i ze O metóduson keresztül) foglalkozik.
XXXV
Bevezetés
xxxvi
A könyv áttekintése
xxxvii
Bevezetés
Első megközelítésben a szerelvény nem más, mint egy felügyelt *.dll vagy
* . ex e bináris fájl leírására szolgáló kifejezés. Ám a .NET -szerelvények törté
nete sokkal több ennél. Ebben a fejezetben megtudjuk, mi az egyfájlos és a
többfájlos szerelvények közötti különbség, és, hogy ezeket hogyan kell készí
teni és telepíteni. Megvizsgáljuk, hogyan kell privát és megosztott szerelvé
nyeket konfigurálni XML-alapú *. confi g fájlokkal és kibocsátó házirenddel
rendelkező szerelvényekkel. Mindeközben megtudhatjuk, hogy milyen a
GAC (Global Assembly Cache - globális szerelvénytár) belső struktúrája, és
mi a .NET keretrendszer konfigurációs segédprogramjainak a szerepe.
Ez a fejezet azt mutatja be, hogy hogyan kell többszálú alkalmazásokat készí
teni, és szárnos olyan technikát ismertet, amelyeket a szálbiztos kód készítésé
hez alkalmazhatunk. A fejezet elején átismételjük a .NET rnetódusreferencia
típusait, hogy megértsük, valójában hogyan támogatják a metódusreferenciák
xxxviii
A könyv áttekintése
Második kötet
xxxix
Bevezetés
x l
A könyv áttekintése
x li
Bevezetés
A .NET 3.0 teljesen új grafikus felhasználói felületet vezetett be, amelyet WPF
nek nevezett el. Röviden, a WPF kimagaslóan interaktív és médiában gazdag
front endek készítését teszi lehetővé asztali alkalmazásokhoz (és indirekt mó
don webalkalmazásokhoz). A Windows Forrnsszal ellentétben, ez a túltelített
felhasználóifelület-keretrendszer számos kulcsfontosságú szolgáltatást (2D-s és
3D-s grafika, animációk, gazdag dokumentumok stb.) integrál egyetlen egysé
gesített objektummodellbe. Ebben a fejezetben megkezdjük az ismerkedést a
WPF-fel és a kiterjeszthető alkalmazásjelölő nyelvvel (Extendable Application
Markup Language- XAML). Megtanuljuk, hogyan kell XAML-mentes, csak
XAML-t használó és a kettő kombinációjából felépülő WPF-programokat létre
hozni. A fejezet végén készítünk egy egyedi XAML-nézegetőt, amelyet a to
vábbi WPF-fel foglalkozó fejezetekben is használni fogunk.
xlii
A könyv áttekintése
xliii
Bevezetés
8. rész: Függelékek
A könyv utolsó része két fontos témát vizsgál meg, amelyek valójában nem il
leszkedtek szervesen a könyv felépítésébe, ezért a függelékbe kerültek. A füg
gelék kiteljesíti a C#-pal és .NET platformmal kapcsolatos ismereteinket,
megvizsgáljuk ugyanis, hogyan kell régebbi kódokat integráini a .NET-alkal
mazásainkba, valamint hogyan kell a .NET-fejlesztést a Windows operációs
rendszer családján kívül használni.
xliv
Öt szabadon Letölthető fejezet - még több információ
http:j/apress.com/book/view/1590598849.
xlv
Bevezetés
A lehetséges javftások
Elérhetőségern
Ha bármilyen kérdés merül fel a könyvhöz tartozó forráskódokkal kapcso
latban, vagy szükség van valamelyik példa tisztázására, vagy egyszerűen
csak véleményt szeretne nyilvánítani a .NET platformról, nyugodtan küldjön
levelet a következő e-mail címre (hogy biztosak legyünk benne, hogy a levele
nem kerül a kéretlen levelek közé, kérem, tegye a tárgymezőbe a "C#FE"
szöveget): atroelsen@Intertech.com.
Annak ellenére, hogy megpróbálak minden levélre lehetőség szerint vála
szolni, sajnos, ahogy mindnyájan, időnként nagyon elfoglalt vagyok. Ha nem
válaszolak egy-két héten belül, akkor ez nem jelenti azt, hogy nem akarok
foglalkozni a problémával, csak épp nagyon nem érek rá (vagy ha szeren
esém van, valahol épp nyaralok).
Nos, akkor, köszönöm, hogy megvásáralta a könyvemet (vagy legalábbis,
hogy belenéz a könyvesboltban, miközben azon gondolkodik, hogy megve
gye-e). Remélem, élvezni fogja a kedves Olvasó a tanulmányozását, és hasz
nosítani tudja az újonnan szerzett ismereteket.
Minden jót!
Andrew Troelsen
xlvi
5. rész
Bevezetés
a .NET
alap osztály
könyvtáraiba
HUSZADIK FEJEZET
Fájlműveletek és elszigetelt
tárolás
A System.IO névtér
. .
. .. . .- . . .' . . '�:� ';' . � .. ���
��
. - ' . �
. . . ' '. . �-.
mációt.
4
A Directory(lnfo) és File(lnfo) típusok
r:�y��:,_: �-.
StringWriter,
;·.-. . ·-·� ' . .. . -- - .· -, ... ..
·lobj<!ct &J
�355
® ®
·-;;�-s;;;;;,;,;--·· ®'1 Fle
Abstroct Class i' Class
·��,.....------�--·-!'·1\·-·-=-·-····�--·'
5
20. fejezet: Fájlműveletek és elszigetelt tárolás
Info osztály tagjait, hogy lekérdezzük egy fájl vagy egy könyvtár általános tu
lajdonságait (pl. a létrehozás idejét, s különböző attribútumokat stb). A 20.2.
táblázat felsorolja az érdekesebb alaptulajdonságokat
A Fil e systeminfo osztály definiálja a Del ete() metódust is. Ezt a származta
tott típusok valósítják meg azért, hogy egy adott fájlt vagy könyvtárat törölni
lehessen a merevlemezről. Az attribútumok lekérdezése előtt továbbá meg
hívhatjuk a Refresh O metódust, amely biztosítja, hogy az aktuális fájira
(vagy könyvtárra) vonatkozó statisztikák ne legyenek elavultak.
6
A Directoryinfo típus használata
'�}i::l>���Új�0·���:i����t����;rr:���:i>t.·'. ·.:ó�:,·,::;:·"�.:��f�{�ii����:;��
Create(), Egy könyvtár (vagy több alkönyvtár) létrehozása a
Createsubdirectory() megadott útvonalon.
7
20. fejezet: Fájlműveletek és elszigetelt tárolás
class Program
{
static void Main(string[] args)
{
console.writeL ine("*''**'' Fun with Directory(Info) ****''\n");
ShowwindowsDirectoryinfo();
console.ReadLine();
}
8
A Directoryinfo típus használata
ll M ennyit találtunk?
Console.writeLine("Found {O} ''.jpg files\n", imageFiles.Length);
9
20. fejezet: Fájlműveletek és elszigetelt tárolás
10
A Directory típus használata
• •y N r_s,�"'" Pl
11
20. fejezet: Fájlműveletek és elszigetelt tárolás
class Program
{
static void Main(string[] args)
{
Console.writeLine("***** Fun with Driveinfo *****\n");
12
A Driveinfo osztálytípus ha sználata
Forráskód A DrivelnfoApp proje ktet a forrás k ódkönyvtárban a 20. fejezet a lkönyvtára tar·
talmazz a . A forráskódkönyvtárró l lásd a Be vezetés xlv. oldalát.
13
20. fejezet: Fájlmüveletek és elszigetelt tárolás
App endText() Egy Streamwri ter típust hoz létre (lásd később), amelynek se
gítségéve! szöveget fűzhetünk a fájlhoz.
c reat e () Új fájlt hoz létre, és egy Fi l eStream típussal (lásd később) tér
vissza, amellyel az újonnan létrehozott fájlt kezelhetjük
openText O Egy StreamReader típust hoz létre (lásd később), amellyel egy
létező szövegfájlból olvashatunk.
14
A Fileinfo osztály használata
A Filelnfo.Create() metódus
ll zárjuk le a fájlfolyamot.
fs.Close();
}
15
20. fejezet: Fájlműveletek és elszigetelt tárolás
A Filelnfo.Open() metódus
16
A Fileinfo osztály használata
: 0i�t.·:.��>i:;��,-:�:,I·:�:;�--��:�;;;:�$..4;�i
,,.,
_., ,_ : .
Truncate Megnyitja és O byte méretűre vágja le a fájlt
A Filelnfo.OpenRead() és a Filelnfo.OpenWrite()
metódusok
17
20. fejezet: Fájlműveletek és elszigetelt tárolás
A Filelnfo.OpenText() metódus
A Filelnfo.CreateText() és a Filelnfo.AppendText()
metódusok
18
A File típus használata
19
20. fejezet: Fájlműveletek és elszigetelt tárolás
using(Streamwriter swriterAppend =
File.AppendText(@"C:\FinalTest.txt"))
{
}
}
A File típus rendelkezik néhány egyedi taggal is (lásd 20.6. táblázat), ame
20
A File típus használata
using System;
using system.IO;
class Program
{
static void Main(string[] args)
{
console.writeLine("***** simple IO with the File Type *****\n");
string[] myTasks {=
Forráskód A SimpleFilelO proje kt megtalálható a 20. feje zet alkönyvtár ában. A forrásk ó d
könyvtárr óllásd a Be v ezetés xlv. oldalát.
21
20. fejezet: Fájlmüveletek és elszigetelt tárolás
11----������-�-, �- 1 � .. ! �l 1511
.." ®{:J Extension Members
•
.
��---���--- ..:;;-;,;,J ' BeginRead(byte( ], in� int System.AsyncCallbaclc. objec-'-.
� ·� � � BegínWrite(byte( ], int, int System.Async(allbaclc. objec 1 E:
·
P CloseO
·· '·
CreateWaitHandleO
::iJ...'i$ SulferedStream DisposeO
$··'-1: CryptoStream
·.$ Dispose(bool}
$···'1$ DeflateStream
� EndRead(System.!AsyncResu�)
$··� FileStream
·� EndWrite(SystemlAsyncResu�)
· ·•
�l ·'-1: GZipStream
'" Equals(object)
·
ffiAt MemoryStream ·
m At PrintQueueStream
rB ·'\: UnmanagedMemoryStream Summary:
C:. Provictes a generic view of a sequence of b)1es.
22
Az absztrakt Stream osztály
��-
��.
CanRead, Megadja, hogy az aktuális adatfolyarn támoga�a-e az olva-
Canwrite, canseek sást, a keresést és/vagy az írást.
A Fil est re a m osztály úgy valósí�a meg az absztrakt stre am típus tagjait,
23
20. fejezet: Fájlmüveletek és elszigetelt tárolás
Console.writ:e(byt:esFromFile[i]);
}
24
A StreamWriter és StreamReader típusok használata
Bár a fenti példa valóban feltölti a fájlt adatokkal, kiderül a Fil estream típus
közvetlen használatának legnagyobb hátránya is: nyers byte-okkal kell dol
goznunk. Más stream-leszármazott típusok is hasonlóképpen működnek. Ha
például egy byte-sorozatot szeretnénk egy adott memóriaterületre kiimi, lefog
lalhatunk egy Memorystream objektumot. Hasonlóképp, ha egy byte-tömböt egy
hálózati kapcsolaton keresztül kell továbbítanunk, a Networkstream típus lesz a
segítségünkre.
A system. ro névtér tartalmaz számos "olvasó" és "író" típust, amelyek
magukba foglalják a streamből származó típusok működésének részleteit.
A StreamWriter és StreamReader
tipusok használata
25
20. fejezet: Fájlműveletek és elszigetelt tárolás
Megjegyzés A Textwriter osztály utolsó két tagja ismerős lehet. A system. cons o l e típusnak
is van write O és writeLi ne O tagja, amelyek az alapértelmezett kimeneti eszközre írnak szö
veges adatot. Valójában a Console.In tulajdonság egy Textwriter, a Console.out tulajdon
ság pedig egy TextReader objektum.
Szövegfájl irása
26
A StreamWriter és StreamReader típusok használata
'
·ll Megkapjuk a streamwritert, majd kiírjuk a sztringadatot.
using(Streamwriter writer = File.CreateText("reminders.txt"))
{
writer.writeLine("Don't forget Mother's oay this year...");
writer.writeLine("Don't forget Father's oay this year...");
writer.WriteLine("Don't forget these numbers:");
for(int i = O; i < 10; i++)
writer.write(i + " ");
ll új sort szúrunk b e.
writer.write(writer.NewLine);
}
con sole.wri teL ine("created file and wrot e some thoughts.... ");
console.ReadLine();
}
< '
Lnl,Coll ..
cionalitást nyújtja.
27
20. fejezet: Fájlműveletek és elszigetelt tárolás
- '
.o
1. '
: '
' ·
{
string input = null;
while ((input = sr.ReadLine()) != null)
{
console.writeLine (input);
}
}
Console.ReadLine();
}
28
A StringWriter és StringReader típusok használata
}
}
29
20. fejezet: Fájlmüveletek és elszigetelt tárolás
hetünk le:
30
A BinaryWriter és BinaryReader osztályok használata
A BinaryWriter és BinaryReader
osztályok használata
31
20. fejezet: Fájlműveletek és elszigetelt tárolás
32
A BinaryWriter és BinaryReader osztályok használata
ll Az adatok írása.
bw.write(aDouble);
bw.write(anrnt);
bw.write(astring);
}
console.ReadLine();
}
33
20. fejezet: Fájlmüveletek és elszigetelt tárolás
34
Fájlok programozott "figyelése"
ll Hozzáadjuk az eseménykezelőket.
watcher.changed += new FilesystemEventHandler(onchanged);
watcher.created += new FilesystemEventHandler(onchanged);
watcher.Deleted += new FilesystemEventHandler(onchanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
ll Megfigyeljük a könyvtárat.
watcher,EnableRaisingEvents = true;
35
20. fejezet: Fájlműveletek és elszigetelt tárolás
36
Aszinkron fájlolvasás és -írás
class Program
{
static void Main(string[] args)
{
console.writeLine("***** Fun with Async File IlO *****\n");
stream s = (Stream)ar.Asyncstate;
s.Endwrite(ar);
s.close();
}
}
A fenti példa egyetlen érdekessége az, hogy a Filestream típus aszinkron visel
37
20. fejezet: Fájlmüveletek és elszigetelt tárolás
Bizalom kérdése
38
Az elszigetelt tároló szerepe
39
20. fejezet: Fájlműveletek és elszigetelt tárolás
Megjegyzés A CAS teljes bemutatása legalább egy (vagy két) teljes fejezetet igényeine,
ezért a CAS működését kizárólag olyan szinten tekintjük át, hogy megérthessük az elszigetelt
tároló-API szerepének alapjait. A CAS működésének további részleteit a .NET Framework 3.5
SDK tartalmazza.
Bevezetés a kóderedet-alapú
biztonságba
40
Bevezetés a kóderedet-alapú biztonságba
Alkalmazástartomány
Házirend beállítások
(Enterprise, Machine, User)
MyAsm.exe
rBizonyilék.,l Kód-
csoport
� Biztosflott
engedélyek
r-?
20. 9. ábra: A CAS építőelemei
A bizonyftékok szerepe
41
20. fejezet: Fájlmüveletek és elszigetelt tárolás
class Program
{
static void Main(string[] args)
{
bool isuserDone = false;
st ring userOption = '"' ;
Assembly asm = null;
42
Bevezetés a kóderedet-alapú biztonságba
case "q":
isuserDone = true;
break;
default:
Console.writeLine("I have no idea what you want!");
break;
}
} while (!isuserDone);
}
}
43
20. fejezet: Fájlmüveletek és elszigetelt tárolás
ll A bizonyíték kiírása.
while (itfEnum.MoveNext())
{
console.WriteLine(" '"''** Press Enter to continue ****");
console.ReadLine();
console.writeLine(itfEnum.current);
}
}
44
Bevezetés a kóderedet-alapú biztonságba
A kódcsoportok szerepe
Jelentés
A .NET keretrendszer 3.5 SDK egy olyan grafikus felügyeleti eszközt biztosít,
amellyel a rendszergazdák megnézhetik és módosítha�ák a meglévő kód
csoportokat, vagy szükség szerint újat hozhatnak létre. Az eszköz segítségé
vel beállítha�uk például, hogy a CLR minden, adott címről (pl. http:/ j www .
intertech.com) letöltött külső szerelvényt egy testre szabott biztonsági kör
nyezetben futtasson.
Megjegyzés A .NET Framework 3.5 SDK egy c aspol.exe nevü parancssori programot is tar
talmaz, amellyel ugyanezeket a beállításokat érhetjük el.
45
20. fejezet: Fájlmüveletek és elszigetelt tárolás
(@ Configur�d Assemblies
8: Remeting S�rvices
� � Runtime Security Policy
r> � Enterprise
• l!!!! Mach·i,;-e
" .ctJ Code Groups
• � AII_Code
� � My_Computer_Zone
t> � Locallntranet_Zone
� � Jnternet_Zone
� Restricted_Zone
� � Trusted_Zone
� � Permission Sets
®J FuiiTrust
ú!J SkipVerification
� Execution
®J Nothing
� localintranet
@] Internet
®J Everything
4i Policy Assemblies
p fl User
� Applications
20. 11. ábra: A CAS-központú számítógépházirend
46
Bevezetés a kóderedet-alapú biztonságba
--
My_Computer_Zone Properties
r��. !jrjf3i
Gene!al LMent>ersllp Úlndlion l.Pesnission Setl
Code group name:
M)._a.;;;,;;;_�------------------.
' -
Code group description:
Code g:oup grants fuitrust to al code O!iginating on the local """'")!Íer
l
l OK
ll Cancel
IG71
20.12. ábra: A My_Computer_Zone kódcsoport részletei
My_Computer_Zone Properties �
,l Geu•ral )[:�-�§:]\�P���
-�
- iSIIOil Set? ..J.j
enti _____ ---,
The membership condition specifies the condition that an assembly
must meet in order to be a member ol a code group,
[Zone ;l
The Zone .-nbership condition is true for ali assemblies that originate
from the zone listed below. Assembliesthat meet this membership
condition will be granted the permissioos associalt!d wilh this code
group,
�one:
[My Ú>n1><Je< ·l
This zone containsaU applications installed on ycur C<XJ1>U!er.
QK ll �ancel l �-bPPiQ
20.13. ábra: A My_Computer_Zone kódcsoport tagsági feltételei
47
20. fejezet: Fájlműveletek és elszigetelt tárolás
My_Computer_Zone Properties
Asserr' .blies that meet this code group's mernbership condition -�.
�-··
;--!
receive the permissions in the per�ssion set spedfied bela�t·. !
Pennission set:
I
l lnATrust �l
l
The selected perrnission set has the folla.�aing permissions:
ll! l
l
'l
ljl
l
ll___
.
-- _____
-·-· --'-·--
jl
, 1]e.•.· �ermission
· - ·
: ll
��.
Internet_Zone Properties ·, �
l Generel l � Conckion j Pe<mission Set l
l
l
Assembliesthat meet this code groop·s membership condition Yoill
receive the pemVssions in the pennission set specified below.
Pennission set:
!�-temet �J l
ll
l ��
The selected permission set has the folloYoing permissions:
Rle Dialog
Isolated Storage Fde
� Sectrty
� Userl-teriace l
� Prtnting
r --�------,
c-2..r:.v Perrnf� l
l OK
ll Cancel
l! ,\p;Jfy l
20.15. ábra: A külső URL-ről betöltött szerelvények az alapértelmezés szerint nem kapják meg
a Full Trust engedélykész/etet
48
Bevezetés a kóderedet-alapú biztonságba
Az engedélykészletek szerepe
Az itt látható ikonok (File Dialog, Isolated Storage File, Security stb.) rnind a
készlet egy-egy specifikus engedélyét képviselik, amelyeket még részleteseb
ben beállíthatunk, ha duplán kattintunk rájuk. Ha például kétszer kattintunk
a Security engedélyre (amely az általános biztonsági beállítások gyűjtőenge
délye), azt látha�uk, hogy az Intemet_Zone alatt futó szerelvény (amelyet
49
20. fejezet: Fájlműveletek és elszigetelt tárolás
Pemlission j Granted J
l Clooe
l
20.17. ábra: Az engedélykészlet egtjes engedélyeinek megtekintése
A CAS müködése
50
Bevezetés a kóderedet-alapú biztonságba
Pennission set:
lirtemet ·l
The selected pennission set has the folla...ing permissioos:
'@j FJ!e Dialog l
@l Isolated Starage Fle
® Secuity
® User Irtefface
@) Pmting
--------
t V��N_Permi:�!�;
[ OK
ll Cancel
ll Apply l
20.18. ábra: A My_Computer_Zone kódcsoport engedélykészletének módosítása
51
20. fejezet: Fájlműveletek és elszigetelt tárolás
A fenti rövid leírás nem adhat teljes áttekintést erről a rendkívül sokoldalú
API-ról, de ez alapján jobban megérthetjük az elszigetelt tároló szerepének a
fontosságát.
Az elszigetelt tároló
52
Az elszigetelt tároló
Megjegyzés A .NET titkosító API-jának használata nem témája ennek a könyvnek. Erről rész
letes információval szolgál a .NET Framework 3.5 SDK dokumentációjának Cryptographic Servi
ces című része.
53
20. fejezet: Fájlműveletek és elszigetelt tárolás
Felhasználó: Horner
A alkalmaz6startomány B allcalmaaástart
MyAsm.exe MyAsm.exe
Elszigetelt tároló
1. tár
54
Az elszigetelt tároló
Felhasználó: Horner
A alkalmadstartom Baladi.-Astao....,
l MyAsm.exe
F'
l l MyAsm.exe
l
rének erre a célra szánt része, vagyis nem különbözik a C:\Windows, C:\Prog
ram Files vagy bármely más, a merevlemezen lévő könyvtártóL Mindazonáltal
az elszigetelt tároló pontos helye az operációs rendszertől is függ. Egy adott tá
roló gyökerének a helye egy Vistát futtató számítógépen:
55
20. fejezet: Fájlmüveletek és elszigetelt tárolás
• Kibocsátó tanúsítványa
• Erős név
• URL
• Hely
• Zóna
Folders vc
Users
Andre--v Troelsen
atrcelsen
.netbeans
AppData
" . local
Adobe
Apple Computer
:-- j Apps
assembly
�eployment
-
lsolatedStorage
hjphpkzn.lp2
Ocxcyjqm.vej
StrongName.vynmtjls31cezx2wwudolgtjg40jp530
• . Ur12tv.<>4ubjvbndio5xymfhzxpyjowojfrg
AssemFiles
Url221c2tyliqli0yoyzaa5gjr1it0jmqlx5
Url.lc2udjuowrvo40dz5ghjnw4oc0o0hw0ac
Url.u0gpakojhfxvdn4g4os10pklltpqgf5s
56
Az elszigetelt tároló
A .NET Framework 3.5 SDK tartalmaz egy storeadm. exe nevű parancssori
eszközt is, amellyel a számítógép aktuális tárolórendszerét kezelhe�ük. Az
eszköz segítségével megtekinthe�ük az éppen bejelentkezett felhasználó tá
rolóit (a /l i st paraméterrel), és törölhe�ük az aktuális felhasználó tárolóit (a
/remove argumentummal). A 20.23. ábrán a /l i st kapcsaló kimenete látható.
Mint azt az előző ábra is muta�a, ez az eszköz megjeleníti az izoláció
szin�ét (szerelvény, alkalmazástartomány) és a tároló létrehozásához hasz
nált bizonyítékokat is. De nem muta�a meg az egyes tárolókban található fáj
lok tartalmát. Ehhez meg kell keresnünk a létrehozott tárolóhelyeket a Win
dows Intézővel, vagy programozottan kell beolvasnunk az adatokat.
A System.IO.IsolatedStorage tipusa
57
20. fejezet: Fájlműveletek és elszigetelt tárolás
Tároló létrehozása az
lsolatedStorageFi le objektummal
IsolatedstorageFile.GetuserStoreForoomain();
58
Tároló létrehozása az lsolatedStorageFile objektummal
rsolatedstorageFile.Getstore(Isolatedstoragescope.user
Isolatedstoragescope.Domain, null, null);
}
IsolatedstorageFile.GetuserstoreForAssembly();
IsolatedStorageFile.Getstore(Isolatedstoragescope.user
Isolatedstoragescope.Assembly, null, null);
}
-,JI';�
�-
�� ; , ·�...
currentsize, Ezek az írásvédett tulajdonságok visszaadják az el
Maximumsize szigetelt tároló méretével kapcsolatos adatokat.
59
20. fejezet: Fájlmüveletek és elszigetelt tárolás
IsolatedstorageFile.GetuserstoreForAssembly())
{
ll Létrehozzuk az IsolatedstorageFilestream típust.
using (IsolatedstorageFilestream isstream =
new IsolatedStorageFilestream("MyData.txt",
FileMode.openorcreate, store))
{
ll Az adatfolyamot "becsomagoljuk" egy streamwriter
ll objektumba, és kiírunk valamilyen szöveget.
using (Streamwriter sw = new Streamwriter(isstream))
{
sw.writeLine("This is my data.");
sw.writeLine("cool, huh?");
}
}
}
}
60
Tároló létrehozása az lsolatedStorageFile objektummal
l l @l lii40j
o
Folders i l
_. Ocxcyjqm.vej
StrongName.vynmtjls3lcezx2,.'f\•Judolgtjg40jp530
. Ur12p40Sz3bq'lwzyqf2altoe55rq2slu>Qg
. AssemFiles
L_�lx�•cl>t_j
Ur1.2tv-.04ubjvbndio5xymfhzxpyjewojfrg c
Ud22k2tyl;qli0yoyzaa5gjrl;!Ojmqbó
Url.k2udjuowrv�Odz5ghjny,4oc0o0h\\Oac
Url.u0gpakejhfxvdn4g4osl0pklltpqgf5s
t..t:..-... -...4., ··�-=��=·····�
MyData.txt Date me difi d 9/3/2007 9,13 PM DatE: crt:ated: 9/3/2007 9� PM
Ted Documl!:nt Si.:e: 30 bytes
61
20. fejezet: Fájlműveletek és elszigetelt tárolás
IsolatedstorageFile.GetuserstoreForAssembly())
{
using (IsolatedstorageFilestream isstream =
new IsolatedstorageFilestream("MyData.txt",
FileMode.open, FileAccess.Read, store))
{
ll "Becsomagoljuk" streamReaderbe.
using (StreamReader sr = new StreamReader(isstream))
{
string allTheoata = sr.ReadToEnd();
Console.writeLine(allTheoata);
}
}
}
}
fel, és törli a kódot futtató felhasználó összes tárolóját. A következő kód pél
dául törli az aktív tárolót, és megsemmisíti annak tartalmát:
IsolatedStorageFile.GetuserstoreForAssembly();
store.Remove();
62
Tároló létrehozása az lsolatedStorageFile objektummal
rsolatedstorageFile.GetuserstoreForAssembly())
{
store.CreateDirectory(@"MyDir\XmlData");
store.createDirectory("MyDir\\BinaryData");
store.CreateDirectory("MyDiriTextData");
}
}
� Gl [S<a:ch
Mcr� >>
Folders:
lsolatedStorage
hjphpkzn.lpl
4 � Ocxcyjqm.vej
MyDir MyData.txt
StrongName.vynmtjls31cezxlwwudolgtjg40jp530
_ UrL2p405z3bq0wzyqf2altoe55rq2sllMlg
f.J
� . AssemFiles
MyDir
BinaryData
TextData
'. XmlData
63
20. fejezet: Fájlműveletek és elszigetelt tárolás
A második gomb ugyanazt az adatot egy elszigetelt tárolóban lévő fájlba írja
ki. A cli ck eseménykezelő megvalósítása a korábbi projektben már megírt
writeTextTorsostorage() metódushoz hasonlít:
rsolatedStorageFile.GetuserStoreForAssembly())
{
ll Létrehozzuk az rsolatedstorageFilestream típust.
using (IsolatedStorageFileStream isstream =
new rsolatedStorageFilestream("MyData.txt",
FileMode.openorcreate, store))
{
ll Az adatfolyamot "becsomagoljuk" egy Streamwriter
ll objektumba, és kiírunk valamilyen szöveget.
64
Az elszigetelt tároló működés közben: ClickOnce-telepítés
Az lsolatedStorageFilePermission attribútum
using System.Security.Permissions;
[assembly:
IsolatedstorageFilePermission(SecurityAc tion.RequestMinimum,
usageAllowed = rsolatedstoragecontainment.AssemblyrsolationByuser)]
65
20. fejezet: Fájlműveletek és elszigetelt tárolás
Először nyissuk meg a projekt Properties lapját úgy, hogy a Solution Explo
rerben duplán kattintunk a Properties ikoma. Majd kattintsunk a Security
fülre. Az alapértelmezés szerint a ClickOnce alkalmazások Full Trust enge
déllyel települnek, ezért ugyanolyan biztonsági jogosultságokkal rendelkez
nek, mint a hagyományosan telepített prograrnak
Olyan telepítőszkriptet kell írnunk, amely arra kényszeríti a programot,
hogy az Internet zónában fusson, amely nem enged hozzáférést a merevle
mezhez hagyományos IO-műveletek felhasználásával.
A ppl ication
Bu ild
i
Refere nce P�ths
li�
Permís�i on e tt i n..:
g ncluded
_:_
l
-;--r
Environme.ntPermission : e_f.-u-
(Z_0 n_ e 0 l t)
[���;�_-·· r
_ _ _ _ ___ 1
·
Fi·t; ;;-I- - �
r o -----------· ·-· ----- - l[•IZ- - _ _ f- au- lt)- + • -i - c; :
;
---:-� :-i:
Pubi
l sh D ogPer i ssi n ( one De
-
Fi e
l lOPerrns
i i
s on t(Zone: Default) •
l
l
_m_�.o ��BI_I_I_II_I_I•
����!��=":�=�-�=�:z-isso _ _•__I_I_••••,t:
_
_
: �
l
j Advanced... j
66
Az elszigetelt tároló müködés közben: ClickOnce-telepítés
http://localhost/MyrsolatedstorageApp/
Az eredmény megtekintése
67
20. fejezet: Fájlműveletek és elszigetelt tárolás
File 10 lIsoStorage
Cormue
l !c__.;:.:.a..
·__ _J
20.27. ábra: Biztonsági veszély. Nem lehet hozzáférni a helyi fájlrendszerhez az Internet zónából
Összefoglalás
68
Összefoglalás
69
HUSZONEGYEDIK FEJEZET
Bevezetés az objektum
sorositás világába
Az objektumsorositás
Tételezzük fel például, hogy egy grafikus asztali alkalmazást hoztunk létre,
és lehetővé szeretnénk tenni, hogy a felhasználók elmenthessék a beállításaikat
(ablak színe, betűméret stb.). Ehhez definiálhatunk egy userPrefs nevű osz
tályt, amely körülbelül 20 adatmezőt foglal magába. Ha a system. ro. B i nary
writer típust használnánk, a userPrefs objektum núnden egyes mezőjét manu
[seri alizable]
public class userPrefs
{
ll Különböző adatok...
}
72
Az objektumsorosítás
Az objektumgráfok szerepe
73
21. fejezet: Bevezetés az objektumsorosítás világába
Car Radio
21. 1 ábra:
. Egtjszerű objektumgráf
Megjegyzés Az. xmlserializer típus (lásd később) nem az objektumgráfokkal menti el az ál
lapotot, hanem továbbra is prediktív módon sorosítja és állítja vissza a kapcsolódó objektumokat.
74
Objektumok konfigurálása sorosításhoz
[Serializable]
public class Radio
{
public bool hasTweeters;
public bool hassubwoofers;
public double[] stationPresets;
[Nonserialized]
public string radiolD = "XF-552RR6";
}
Ezt követően adjunk hozzá két osztályt (J amesBondcar és a car), lássuk el őket
a [Seriali zab le] attribútummal, és definiáljuk az alábbi tagokat:
[Serializable]
public class Car
{
public Radio theRadio = new Radio();
public bool isHatchBack;
}
75
21. fejezet: Bevezetés az objektumsorosítás világába
[Serializable]
public class JamesBondcar car
{
public b ool canFly;
public bool cansubmerge;
}
76
A sorosító formázó kiválasztása
[Seriali zable]
public class Person
{
ll Nyilvános mező.
public bool isAlive = true;
ll Privát mező.
private int personAge = 21;
}
}
• BinaryFormatter
• SoapFormatter
• XmlSerializer
77
21. fejezet: Bevezetés az objektumsorosítás világába
netbe szeretnénk sorosítani először a Visual Studio 2008 Add Reference párbe
szédpaneljével hivatkozzunk a system. Runtime. Se rialization. Formatters.
ll Kötelező referencia
ll a system.Runtime.serialization.Formatters.soap.dll szerelvényre.
using System.Runtime. serialization. Formatters. soap;
Az IFormatter és az IRemotingFormatter
interfészek
78
A sorosító formázó kiválasztása
79
21. fejezet: Bevezetés az objektumsorosítás világába
<7xml version="l.O"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<isAlive>true</isAlive>
<PersonAge>21</PersonAge>
<FirstName />
</Person>
80
Objektumok sorosítása a BinaryFormatterrel
Objektumok sorositása
a BinaryFormatterrel
ll Feltétlenül importáljuk
ll a system.Runtime.serialization.Formatters.Binary
ll és a system.ro névtereket.
static void Main(string[] args)
{
Console.writeLine("***** Fun with object serialization *****\n");
81
21. fejezet: Bevezetés az objektumsorosítás világába
jbc.cansubmerge = false;
jbc.theRadio.stationPresets = new doubl e [] { 89. 3, 105.1, 97.1};
jbc.theRadio .hasTweeters = true;
. ..... FSi�pleSer
ialize. Version=
1.0.0.0, Culture
=neutral, Public
OB 63
52 61
6B 00
72 69
00 Ol
03 00 00 00 .. Si
6C 69 7A 65 mpleSerialize.Ra
61 73 54 77 65 dio ..... hasTweet
75 62 57 6F 6F 66 ers.hasSubYoofer
6E 50 72 65 73 65 s.stationPresets
00 00 Ol 00 09 04
00 00 06 33 33 33 . . .... 33333
46 SA 40 66 66 66 SV@fffffFZ@f ffff
FX@
82
Objektumok sorosítása a SoapFormatterrel
(JamesBondcar)binFormat.Deserialize(fstream);
console.writeLine("can this car fly? : {O}",
carFromDisk.canFly);
}
}
Objektumok sorositása
a SoapFormatterrel
83
21. fejezet: Bevezetés az objektumsorosítás világába
ll Feltétlenül importáljuk
ll a System.Runtime.serialization.Formatters.Soap névteret,
ll és állítsunk fel referenciát a
ll System.Runtime.serialization.Formatters.Soap.dll szerelvényre.
static void saveAsSoapFormat (object objGraph, string fileName)
{
ll Mentsük az objektumot SOAP-formátumban egy Caroata.soap
ll nevű fájlba.
SoapFormatter soapFormat new soapFormatter();
<canfly>true</canfly>
��
,:�: <canS'..l.bmerqe>false</canSutrr.erqe>
<theRadio href-"Jret-3" l>
<isHatct;.Back>false</i3HatchBack>
</al: Jarr.e!IBondCa:=>
9:- <al: Radio id'"'""ref-3" xmln.s: al="http: //;�cPema.s .rnicrosoft.com/clr/n;�as:sem/SiJl'nleSer
<hasTweeter�>true</hasTweeter�>
<ha�Sub�Voofer�>fal�e</ha�Su:t;Wooter�>
<.!St.ationPre!fets hr ef'""" fref - 4 "l>
</al: Radio>
<SOAP-E11C :A.!:ray id="ref-4" SOAP-ENC: arrayType="xsd: double [3]">
.16� <iten:>lOS.l</item>
17� <item>97 .1</ite�r;>
.!.Si </SCAP-ENC:Array>
</SOAP-EWY:E�velope>
84
Objektumok sorosítása az XmlSerializerrel
Objektumok sorositása
az XmlSerializerrel
85
21. fejezet: Bevezetés az objektumsorosítás világába
�x
l� <?xml version="l.O"?>
�
2 j <Jar.r esBondCar xm.l!'ls :x�i="http: lbr,;w.w3. org/2001/XHLSchema-ínst.ance" ..:.1
3� xrr.J.ns: xsd="http: II'N"W'II'I. w3. orq/2001/Xl-!LSchei'!'.a">
�-.� <t
��=:��:= te�s>true</hasTweete�s>
€� l <hasSubNoofers>false</hasSubWoofers>
<stationPresets>
8; <double>89.3</double>
9[ <double>l05 .l</double>
: o' <double>97.1</double>
l:!.�
::.2i
</statio�Presets>
<radioiD>XF-552RR6</:::adio!D>
l
l
�3' </theRadio>
:�i <isHatchBack>fal.se</isHatchBack>
:5 <canFly>true</canFly>
:6 <canSubrr.erge>false</ canSt.:l:::rr.erc;e>
</Jarr.es3ondCar>
-l
l
21.4. ábra: A XmlSerializer l1asználatával sorosított JamesBondCar
Megjegyzés Az xmlseriali zer típus egyik feltétele, hogy minden, az objektumgráfban ta
lálható sorosított típus támogasson egy alapértelmezett konstruktort (tehát mindenképpen ad
juk hozzá az egyedi konstruktorok meghatározásakor). Ha ez nem történik meg, futásidőben
InvalidoperationException jelenik meg.
86
Objektumok sorosítása az XmlSerializerrel
· . .·�:r;;,�f.:�: ..
· :· ··
·. : . �- -...
<canFly>true</canFly>
<cansubmerge>false</cansubmerge>
</JamesBondcar>
[Serializable,
xmlRoot(Namespace = "http://www.intertech.com")]
public class JamesBondcar : Car
{
[xmlAttri bute]
p ub lic bool canFly;
[XmlAttri bute]
public bool cansubmerge;
}
87
21. fejezet: Bevezetés az objektumsorosítás világába
<?xml version="l.O"""?>
<JamesBondcar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
canFly="true" cansubmerge="false"
xmlns="http://www.intertechtraining.com">
</JamesBondcar>
Objektumgyűjtemények sorositása
88
Objektumgyűjtemények sorositása
[Serial izable,
XmlRoot(Namespace "http:llwww.intertech.com")]
=
Így most már az alábbiak szerint akárhány JamesBondcar osztályt menthetünk el:
new xmlserializer(typeof(List<JamesBondcar>),
new Type[] { typeof(JamesBondcar), typeof(car),
typeof(Radio) });
xmlFormat.serialize(fstream, mycars);
}
console.writeLine("=> Saved list of cars!");
}
89
21. fejezet: Bevezetés az objektumsorosítás világába
90
A sorosítási folyamat testreszabása
��-
;-"·j,·
���-:.
.w:�:.��
;.';;;-�;�,.,::_�:'.,..,... ..;..
:t'��l;·_.�;"��, ....,
...." h..,;�i..;,r.-' �-.-;-''<�..;
�-e-".�-��")�.r.-�....
. ���":01>��-�f'·
-,.; __;.'
;__ ; ..;:.w ,-·i:•·;.� 1!,-
..�.,.., __ .. en...
•
·;
"c<'W•,'
··"""'!.
'·;,-;',·�'c:;
�·�-::- ��.lll
[OnDeserialized] Ez az attribútum teszi lehetövé, hogy specifikáljuk azt a
metódust, amelyet közvetlenül az objektum visszaállí
tása után hívunk.
Az objektumsorositás háttérrészletei
91
21. fejezet: Bevezetés az objektumsorosítás világába
Azon túl, hogy a szükséges adatokat a folyamba helyezik, illetve onnan kive
szik, a formázák az alábbi infrastrukturális adatok szempon�ából elemzik is
az objektumgráfban található tagokat:
92
A sorosítási folyamat testreszabása
93
21. fejezet: Bevezetés az objektumsorosítás világába
[serializable]
class StringData : ISerializable
{
public string datartemone = "First data black";
public string datartemTwo= "More data";
94
A sorosítási folyamat testreszabása
public StringData(){}
protected StringData(serializationinfo si, Streamingcontext ctx)
{
ll Töltsük fel újra a tagváltozókat a folyamból.
datartemone = si.GetString("First_Item").ToLower();
dataitemTwo = si. GetString("dataitemTwo").ToLower();
}
95
21. fejezet: Bevezetés az objektumsorosítás világába
/ MYI5ata:soipl}��Dita.� 1 ·Pro �
� ... x
r 1'EJ <SOAP-ENv: Envelope xmln s : xs i="htto: //�.7-:--:;;-3.--z;ga·ooi/"XMr:sct;:�;;;-:1
i 2f;:l <SOAP-ENV:Body> ,--o
[Serializable]
class MoreData
{
public string datartemone = "First data block";
public string dataitemTwo= "More data";
96
Összefoglalás
[onserializi ng]
private void onserializing(Streamingcontext context)
{
ll Hívás a sorosítási folyamat alatt.
dataiternOne = dataitemOne.ToUpper();
dataitemTwo = dataitemTwo.ToUpper();
}
[onoeserialized]
private void OnDeserialized(Streamingcontext context)
{'
ll Hívás a visszaállítási folyamat befejezését követően.
datartemone = dataitemone.ToLower();
dataitemTwo = dataitemTwo.ToLower();
}
}
Összefoglalás
97
21. fejezet: Bevezetés az objektumsorosítás világába
98
HUSZONKETTEDIK FEJEZET
ADO.NET, 1. rész:
Az élő kapcsolat
ADO-típus (rnint pl. a Recordset) már nem létezik. Továbbá számos olyan
ADO.NET-típus van, amelyhez nem találunk a klasszikus ADO-ban megfe
leltethető párt (ilyen pl. az adatillesztő).
Ellentétben a klasszikus ADO-val, amelyet a szorosan kapcsolódó kli
ens/ szerver rendszerekre hoztak létre, az ADO.NET a kapcsolat nélküli vilá
got szem előtt tartva készült el a Datasetek használatávaL A típus tetszőleges
számú kapcsolódó adatbázistáblák helyi másolatát reprezentálja, amelyeknek
rnindegyike sorok és oszlopok gyűjteménye. A Dataset segítségével a hívó
szerelvény (pl. egy weboldal vagy egy asztali végrehajtható fájl) kezelheti és
módosíthatja a Dataset tartalmát, mialatt a kapcsolata az adatforrással bontva
van, és a megfelelő adatillesztőn keresztül bármilyen módosított adatot visz
szaküldhet további feldolgozásra.
További lényeges különbség a klasszikus ADO és az ADO.NET között az,
hogy az ADO.NET messzemenően támogatja az XML-adatok megjelenítését.
Tulajdonképpen az adattárolóból kinyert adatot (az alapértelmezés szerint)
XML-formátumban sorosítja a rendszer. Mivel az XML-adatokat gyakran
szabványos HTTP protokollon keresztül továbbítjuk a rétegek között, így az
ADO.NET nem ütközik semmilyen tűzfal által okozott korlátozásba.
Talán a legalapvetőbb különbség a klasszikus ADO és az ADO.NET között
az, hogy az ADO.NET nem más, rnint egy felügyelt kódkönyvtár, így pontosan
a felügyelt könyvtárak szabályai szerint működik. Az ADO.NET-et alkotó ti
pusok a CLR memóriakezelési protokollját használják, ugyanazokat a típus
rendszereket alkalmazzák (osztályokat, interfészeket, felsorolásokat, struktú
rákat és metódusreferenciákat), és bármely .NET-nyelv által elérhetők.
Programozási szemszögből nézve az ADO.NET lényegét egy alapvető sze
relvény képviseli, amelynek System. Data. dll a neve. A bináris fájlban jó né
hány névtér megtalálható (lásd 22.1. ábra), ezek közül sok az elérhető
ADO.NET-adatszolgáltató (ennek definícióját lásd alább) típusait reprezentálja.
éJ....o kffi@•li
: $··· (} Microsoft.Sq!Server.Server 0
�··· (} System.Data
�... {} fJ
lJ
System.Data.Common
$ .. (} System.Data.Odbc
@ .. {} System.Data.OieDb
@ .. {} System.Data.Sql
f éJ.. (} System.Data.Sq!Ciient
! $.. (} System.Data.SqfTypes
! IÍI· (} System.Xml
G
;c "'
.l
22. 1. ábra: A System.Data.dll a legalapvetőbb ADO.NET szerelvény
100
Az ADO.NET magas szintű meghatározása
namespace MyApp
{
class Program
{
static void Main(string[] args)
{
}
}
}
101
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
Az ADO.NET-adatszolgáltatók müködése
102
Az ADO. NIT-adatszolgáltatók müködése
�--
i.>:.
··'
.
&!>.�:�'.'·. �-.•'.
'
·'
,.
D at aAd apter DbD a taAd a pter IDa t aAdapter , Dataseteket szállít a hívó és
lObD ataAd a pter az adattároló között. Az adat-
illesztő egy kapcsolatobjek-
turnot és négy belső parancs-
objektumot tartalmaz a lekér-
dezés, beszúrás, rnódosítás és
törlés rnűveleteihez.
103
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
Beszúró utasítás
Kapcsolat objektum
l Paraméter gyűjtemény
Módosító utasítás
104
Az ADO.NET-adatszolgáltatók müködése
�.�'f'�::'.:
·�\'.,
Server
Megjegyzés Nincsen olyan adatszolgáltató, amelyet kifejezetten a Jet motorhoz lehetne le
képezni (és ilyenformán a Microsoft Accesshez). Ha egy Access adatbázisfájt szeretnénk kezel
ni, akkor ezt az OLE DB vagy az ODBC adatszolgáltatóin keresztül tudjuk megtenni.
Megjegyzés Egy olyan eset van, amikor a system.Data. oleD b névtér típusainak a használa
tára van szükség: ha a Microsoft SQL Server 6.5 vagy valamelyik régebbi verziójával kell dol
goznunk. A system.Data.Sqlclient névtér ugyanis csak a Microsoft SQL Server 7.0 vagy en
nél magasabb verziójával tud kommunikálni.
105
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
106
További ADO.NET-névterek
További ADO.NET-névterek
107
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
108
A System. Data névtér típusai
109
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
tosítanak hozzáférést.
Az lObDataParameter és az IDataParameter
interfészek szerepe
110
A System. Data névtér típusai
Az lObDataAdapter és az IDataAdapter
interfészek szerepe
111
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
Az IDataReader és az IDataRecord
interfészek szerepe
112
Adatszolgáltatók absztrahálása interfészekkel
Adatszolgáltatók absztrahálása
interfészekkel
113
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
Ugyanez igaz a tagok visszatérési értékeire is. Nézzük meg például a követ
kező egyszerű Cit-konzolalkalmazást (MyconnectionFactory névvel), amely
egyedi felsorolt típus alapján lehetővé teszi egy adott kapcsolatobjektum
megszerzését. Diagnosztikai célokból egyszerűen csak kiírjuk az alatta talál
ható kapcsolatobjektumot a reflexiós szolgáltatás segítségéve!:
namespace MyConnectionFactory
{
ll A lehetséges szolgáltatók listája.
enum DataProvider
{ sqlserver, oleDb, odbc, oracle, None }
class Program
{
static void Main(string[] args)
{
console.writeLine("*** very simple Connection Factory ***\n");
114
Adatszolgáltatók absztrahálása interfészekkel
case DataProvider.OleDb:
conn = new oleDbConnection();
break;
case DataProvider.odbc:
conn = new odbcconnection();
break;
case DataProvider.oracle:
conn = new oracleconnection();
break;
}
return conn;
}
}
}
<configuration>
<appSettings>
<!-- Ez a kulcsérték a felsorolt típusunk valamely értékével
egyezik meg -->
115
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
ConfigurationManager.Appsettings["provider"];
if(mycn != null)
console.writeLine("Your connection is a {O}",
mycn.GetType().Name);
console.ReadLine();
}
116
AzAutoLot adatbázis létrehozása
Ebben a fejezetben mindig egy egyszerű, AutaLot nevű SQL Server teszt
adatbázison hajtunk végre lekérdezéseket Kapcsolódva az eddigi autós té
mához, ez az adatbázis három egymással kapcsolatban álló táblát tartalmaz
(lnventory - raktár, Orders - megrendelések és Customers - vásárlók). Ezek
a táblák különböző jellegű adatokat tartalmaznak, amelyekben egy kitalált
autókereskedés megrendelési információi találhatók.
Tételezzük fel, hogy van egy Microsoft SQL Server (7.0 vagy magasabb
verziójú) vagy egy Microsoft SQL Server 2005 Express Edition adatbáziske
zelő szaftverünk (http://msdn.microsoft.comjvstudiojexpress/sql). Ez az
adatbázisszerVer tökéletesen megfelel a céljainkra, hiszen egyrészt ingyenes,
másrészt olyan grafikus felületet biztosít (az SQL Server Management Tool
eszközt), amelynek segitségével létrehozhatjuk és felügyelhetjük az adatbázi
sainkat, és harmadrészt a Visual Studio 2008/Visual C# Express Edition vál
tozattal integrálható.
Ez utóbbi előnyének illusztrálására megnézzük, hogy hogyan kell létre
hozni az AutaLot adatbázist a Visual Studio 2008 segítségéveL Ha Visual C#
Express verziónk van, hasonló műveleteket hajthatunk rajta végre, mint ame
lyeket itt részletezünk a Database Explorer ablak segítségével (amelyet a
View> Other Windows menüpont használatával lehet betöltetni).
117
ZZ. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
Setver name::
JNTERUBER\SQLEXPRESS
User name:
- P:aH'tf/Ord:
O Save my password
Autolot
OK lL Cancel
22. 3. ábra: Egy új SQL ServerExpress adatbázis létrehozása Visual Studio 2008 használatával
118
Az Autalot adatbázis létrehozása
0�it\11
l�l- (J] Data Connectíons
8- _iJ, ínteruber\sqlexpress.Autolot.dbo
ffi Ciii Database Díagrams
ffi-
Ciii!![
-
NewQuery
Relresh
!
Properties
j
' ttl-- Cil Assembhes
B �Servers
lil- 8 InterUber
/dbo.lnventory: TL.Jexpress.Autolot)t1iiijijiijjil � X
Column Properties l
�U lS
IGenenD
-
- -
8
(Name) CarlO o
Allow Nulls No
DataType int
Default Value or Sinding
l
T
GenenD
I
l
22. 5. ábra: Az Inventory tábla teroezése
119
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
8 vw Tan Sal
... . .
·� � ll of8 l � �l �;o l® l
22. 6. ábra: Az Invrntory tábla feltöltése
Megjegyzés A tárolt eljárásoknak nem kell kimeneti paraméterrel visszatérniük (mint ahogy
itt látható). A fejezet "Tárolt eljárások futtatása" című részében lesz stó az Sql Parameter
Di recti on tulajdonságának vizsgálatáróL
120
Az AutoLot adatbázis létrehozása
02:11�·
;J-� [j) Data Connections
á- ll interuber\sql.,.press.Autolot.dbo
ffi··· � Database Diagrams
8 �Tables
tB·· ff!l lnventory
IH· �Views
8-·�
MM•++
. 8 CJ GetPetName
·
! @il @carlO
··
L � @petName
..
l:
..
8-- "!!!Servers
. ffi
tB· SInterUber
� S.rver Explorer�Toolbox
22.7. ábra: A GetPetName tárolt eljárás
/dbo.CustCJ�J�en: Tólo...lexpress.Autolot)l ; X
[..
�c...uD-
Column Name DataType Allow Nulis
· - - ----- -- - --- - ----- - - - - - - -- - - --- ------- - ---
int ro
FirstName nchar(lO) fO
LastName nchar(lO) fO
El
Column Properties
'------,
•f·Jame1 Cust!D
AllowNulls No
[(Nome)
22.8. ábra: A Customers tábla tervezése
121
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
i lloBil o- lln!nner
l
Matt Wa�on
Pat Wa�on
Jim White
� OrdedD int EJ
Cust!D int
: Z?�� :
· -- -.
.
·IEJ
CarlO
-
int .
:\;">·· • ·lLl
El
Column Properties
'-------,
OrderiD
No
Töltsük fel adatokkal az Orders táblát. Tegyük fel, hogy az OrdedD értéke
1000-rel kezdődik. Válasszunk egy egyedi CadD értéket minden egyes
CustiD értékhez (lásd a 22.11. ábrát).
IfillliDO 'l 2
l
1001
1003 7
1010 8
·� � ll of4 l � �·�"l® l
22.11. ábra: Az Orders tábla feltöltése
122
Az AutaLot adatbázis létrehozása
Ha a könyvbeli adatokat vittük be, akkor láthatjuk, hogy Dave Banner (Cust
ID = l) a piros Volkswagent szeretné megvenni (CariD = 2) , míg Pat Walton
(CustiD =3) a rozsdabarna Volkswagenre (CariD = 8) vetett szemet.
/dbo.Autolot oa,..Jexpreu.Autolot)rjijiijjjjjirjl � x
:::J
Orders Customers
'll OrderiD _'t CustlD
FK Orders_Custorners
CustiD FirstName
CarlO LastName
FK_Orders_Inventory
Inventorv
.! Car!D
Make
Color
PetName
.iJ �
22. 12. ábra: Az összekapcsolt Orders, Inventory és Customers táblák
123
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
A .NET data provider factory minta egyszerű kódbázis létrehozását teszi le
hetövé általánosított adatelérési típusok alkalmazásával. Továbbá alkalma
záskonfigurációs fájlok (és a <connect ienstrings> elem) használatával dekla
ratív módon kaphatunk szolgáltatókat és kapcsolatsztringeket anélkül, hogy
újra kellene fordítani és telepíteni a szerelvényt.
A data provider factory implementációjának megértéséhez emlékezzünk
vissza a 22.1. táblában foglaltakra: egy adatszolgáltatóban az objektumok
ugyanabból az ősosztályból származnak, amelyet a system. Data. common név
tér definiál:
mára.
mára.
mára.
124
Az ADO.NET data provider factory modell
public virtual
DbCommand CreateCommand();
public virtual
obcommandBuilder createCommandBuilder();
public virtual
obconnection Createconnection();
public virtual
obconnectionstringBuilder
createconnectionstringBuilder();
public virtual DbDataAdapter createDataAdapter();
public virtual DbDatasourceEnumerator
CreateDataSourceEnumerator();
public virtual DbParameter createParameter();
}
DbProviderFactories.GetFactory("System.Data.SqlClient");
DbProviderFactories.GetFactory('' system.Data.oracleclient");
125
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
<system.data>
<DbProviderFactories>
<add name="Odbc Data Provider" invariant="System.Data.odbc"
description=".Net Framework Data Provider for odbc"
type="System.Data.odbc.odbcFactory,
system.Data, version=2.0.0.0, culture=neutral,
PublicKeyToken=b77a5c561934e089" />
<add name="OleDb Data Provider" invariant="System.oata.oleDb"
description=".Net Framework Data Provider for oleDb"
type="System.Data.OleDb.OleDbFactory,
System.Data, version=2.0.0.0, culture=neutral,
PublicKeyToken=b77a5c561934e089" />
<add name="Oracleclient Data Provider"
invariant="System.Data.oracleclient"
description=".Net Framework Data Provider for oracle"
type="System.Data.oracleclient.oracleclientFactory,
System.Data.Oracleclient,
version=2.0.0.0, culture=neutral,
PublicKeyToken=b77a5c561934e089" />
<add name="Sqlclient Data Provider"
invariant="System.Data.Sqlclient"
description=".Net Framework Data Provider for sqlServer"
type="System.Data.sqlclient.sqlclientFactory, system.Data,
version=2.0.0.0, culture=neutral,
PublicKeyToken=b77a5c561934e089" />
</DbProviderFactories>
</system.data>
Megjegyzés Ha olyan data provider factory mintát szeretnénk használni, amelyhez a kapcso
lódó adatbáziskezelőt a machine.con fi g fájl nem tartalmazza, akkor technikailag lehetőség
van arra, hogy olyan új invariáns értékeket adjunk hozzá, amelyek a globális szerelvénytár
megosztott szerelvényeire mutatnak. Meg kell bizonyosadnunk arról, hogy az adatszolgáltató
ADO. NIT 2.0 kompatibilis, és együtt tud működni a data provider factory modellel.
126
Az ADO.NET data provider factory modell
127
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
ll Beolvassuk a factoryszolgáltatót.
DbProviderFactory df = DbProviderFactories.GetFactory(dp);
cmd.ExecuteReader(CommandBehavior.CloseConnection);
console.writeLine("Your data reader object is a: {O}",
dr.GetType().FullName);
Console.WriteLine("\n***** current Inventory *****");
while (dr.Read())
console.writeLine("-> Car #{O} is a {1}.",
dr ["cariD"], dr ["Make"] . ToString(). Trim());
dr.close();
Console.ReadLine();
}
<configuration>
<appSettings>
<!-- Melyik szolgáltató? -->
128
Az ADO.NET data provider factory modell
129
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
A <connectionStrings> elem
<configuration>
<appsettings>
<!-- Melyik szolgáltató? -->
<add key="provider" value="System.Data.sqlclient" />
</appSettings>
130
Az ADO. NET kapcsolatalapú modellje
Megjegyzés A könyv további példái expliciten használják a system. D a ta.Sq l cl i ent névtér
típusait, hogy a továbbiakban a lényegre tudjunk összpontosítani. Ha más adatbáziskezelő rend
szert szeretnénk használni (pl. Oracle-t), akkor ennek megfelelően módosítani kell a kódot.
131
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
class Program
{
static void Main(string[] args)
{
Console.writeLine("***** Fun with Data Readers *****\n");
"Initial catalog=AutoLot";
cn.Open();
132
Az ADO.NET kapcsolatalapú modellje
A kapcsolatobjektumok használata
Cl oc a l) adatforrást).
133
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
134
Az ADO.NET kapcsolatalapú modellje
135
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
A ConnectionStringBuilder objektumok
new SqlconnectionstringBuilder();
cnStrBuilder.InitialCatalog = "AutoLot";
cnstrBuilder.DataSource = @"(local)\SQLEXPRESS";
cnstrBuilder.connectTimeout = 30;
cnStrBuilder.Integratedsecurity = true;
sqlconnection cn = new sqlconnection();
cn.connectionstring = cnstrBuilder.connectionstring;
cn.Open();
showconnectionstatus(cn);
136
Az ADO.NET kapcsolatalapú modellje
A parancsobjektumok
137
22. fejezet: ADO.NET, 1. rész: Az élő kapcsotat
138
Az adatol vasók
Megjegyzés Ahogy azt maj d a fejezet későbbi részében l áthatjuk, az Sql command objektum
további tagokat tartal maz, amelyek az adatbázis-kezelés aszinkron módj át teszik lehetövé.
Az adatolvasók
139
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
SqlDataReader myoataReader;
myDataReader =
mycommand.ExecuteReader(CommandBehavior.Closeconnection);
ll Lépkedjünk végig az eredményen egy ciklus segítségével.
while (myoataReader.Read())
{
console.writeLine("-> Make: {O}, PetName: {1}, color: {2}.",
myDataReader["Make"]. ToString().Trim(),
myDataReader["PetName"] .ToString().Trim(),
myDataReader ["color"].ToString().Trim());
}
myDataReader.Close();
console.ReadLine();
}
Megjegyzés Asztringadatok csonkítását csak azért hajtjuk végre, hogy leszedjük a szóközöket az
adatbázis·bejegyzésekből; ezek nem kapcsolódnak közvetlenül az ADO.NET-hez. Az, hogy szükség
van-e erre a lépésre, attól függ, hogy hogyan definiáltuk az oszlopot, és milyen adatot szúrtunk be a
táblába. Így erre a müveletre természetesen nem minden egyes esetben van szükség.
while (myDataReader.Read())
{
console.WriteLine("***** Record *****");
for (int i O; i < myDataReader.Fieldcount; i++)
=
{
console.writeLine("{O} {l} ",
=
myDataReader.GetName(i),
myDataReader.Getvalue(i).ToString().Trim());
}
console.writeLine();
}
140
Az adatolvasók
do
{
while (myDataReader.Read())
{
Consol e.writeL ine("***** Record '""'***");
141
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
Egy adatolvasó csak egy SQL select utasítást tud feldolgozni, és nem hasz
nálható létező adatbázistábla adatainak a módosítására beszúrással, törléssei
vagy frissítéssel. Egy létező adatbázis módosításának megértéséhez a pa
rancsobjektum további vizsgálatára van szükség.
Újrafelhasználható adatelérési
könyvtár készítése
Megjegyzés Technikai szempontból a nonquery egy olyan SQL-utasítás, amely nem tér vissza
eredményhalmazzaL Tehát a select utasítások lekérdezések, míg az Insert, az Update és a
Delete utasítások nem. Ezért az ExecuteNonQuery() metódus egy integertípussal tér vissza,
amely az érintett sarok számát adja vissza, nem pedig a rekordok egy új halmazát.
142
Újrafelhasználható adatelérési könyvtár készítése
using System;
using System.collections.Generic;
using system.Text;
namespace AutoLotConnectedLayer
{
public class InventoryDAL
{
}
}
143
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
Megjegyzés Ha olyan típusokat használunk, amelyek natív erőforrásokat kezelnek (pl. az adat
bázis-kapcsolatot), érdemes implementálni az IDisposabl e interfészt és elkészíteni a megfelelő
véglegesítőt (vö. az előző kötet 8. fejezetét). Termékszintű környezetben az olyan osztályokkal,
mint az rnventoryDAL, ezt a gyakorlatot követnénk; ezt azonban most elhagyjuk, hogy az
ADO.NET lényegére koncentrálj unk.
A kapcsolatlogika létrehozása
Először definiálnunk kell néhány metódust, amely lehetövé teszi a hívó szá
mára, hogy egy érvényes kapcsolatsztring segítségével kapcsolódjori, és
bontsa a kapcsolatot az adatforrássaL Mivel az AutaLotDAL _dll szerelvényünk
bedrótozottan használja a sy stem. Data. sql cl i e nt típusait, definiáljunk egy
sqlconnection privát tagváltozót, amelyet a rendszer akkor foglal le, arnikor
az rnventoryDAL objektumot létrehozzuk Készítsünk egy openconnection() és
egy closeconnection() metódust, amelyek ezzel a tagváltozóval működnek
együtt a következőképpen:
}
}
144
Újrafelhasználható adatelérési könyvtár készítése
SQL-utasítást:
amely azt az esetet kezeli, amikor megrendelés alatt álló autót próbálunk tö
rölni a Customers táblából. Adjuk a következő metódust az InventoryDAL
osztálytípushoz:
'{0}'", id);
145
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
146
Újrafelhasználható adatelérési könyvtár készítése
147
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
A paraméterezett parancsobjektumok
148
Újrafelhasználható adatelérési könyvtár készítése
149
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
cmd.ExecuteNonQuery();
}
}
150
Újrafelhasználható adatelérési könyvtár készítése
ll Bemeneti paraméter.
SqlParameter pararn = new SqlParameter();
param.ParameterName = "@cariD";
param.sqlDbType = SqlDbType.Int;
param.value = cariD;
param.Direction = ParameterDirection.Input;
cmd.Parameters.Add(param);
ll Kimeneti paraméter.
pararn = new SqlParameter();
param.ParameterName = "@petName";
param.sqlDbType = SqlDbType.Char;
param.size = 10;
param.Direction = ParameterDirection.Output;
cmd.Parameters.Add(param);
151
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
ll Bemeneti paraméter.
sqlParameter param = new SqlParameter();
·param.ParameterName = "@cariD";
pa.ram.sqlDbType = sqlDbType.rnt;
param.value = cariD;
param.Direction = ParameterDirection.Input;
cmd.Parameters.Add(param);
152
Parancssoros front end létrehozása
using AutoLotConnectedLayer;
using system.configuration;
using System.Data;
<configuration>
<connectionstrings>
<add name ="AutoLotSqlProvider" connectionString =
"Data source=(local)\SQLEXPRESS;" +
• Q: Kilép a programból.
Az összes lehetőséget a Program osztály egyik statikus metódusa kezeli. Itt ta
lálható a Main() teljes implementációja. Figyeljük meg, hogy a do/whil e cik
lusból meghívott metódusok (a sh owinstruction() metódus kivételével) egy
InventoryDAL objektumot kapnak egyetlen paraméterként:
153
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
ll Az InventoryDAL <:lbjektumunk
,
létrehozása.
InventoryDAL invDAL = new InventoryDAL();
invDAL.OpenConnection(cnStr);
showinstructions();
break;
case "P":
LookUpPetName(invDAL);
break;
case "Q":
userDone true;
break;
default:
Console.writeLine("Bad data! Try again");
break;
}
} while (!userDone);
}
154
Parancssoros front end létrehozása
155
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
ll A DataTable kiírása.
for (int curRow O; curRow
= < dt.Rows.count; curRow++)
{
for (int curcol= O; curcol < dt.Columns.count; curcol++)
{
Console.write(dt.Rows[curRow][curcol].ToString().Trim() +
"\t");
}
console.writeLine();
}
}
Létező autó törlésekor meg kell kérdezni a felhasználótól a törölni kívánt au
tó azonosítóját és az értéket átadni az rnventoryDAL típus DeletecarO metó
dusának:
156
Parancssoros front end létrehozása
157
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
158
Aszinkron adatelérés az SqlCommand használatával
Ezzel a parancssati front end elkészült. A 22.16. ábra egy tesztfuttatást mutat be.
Minden jelenlegi adatelérési logikánk egyetlen szálon fut. A .NET 2.0 megje
lenése óta az SQL-adatszolgáltató fejlődött, és támogatja az aszinkron adatbá
ziskezelést az sqlcommand újabb tagjainak a segitségével:
• BeginExecuteReader()/EndExecuteReader()
• BeginExecuteNonQuery()/EndExecuteNonQuery()
• BeginExecutexmlReader()/EndExecuteXmlReader()
159
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
160
Az adatbázis-tranzakciók
Az adatbázis-tranzakciók
161
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
Az ADO.NET-tranzakcióobjektum
kulcsfontosságú tagjai
162
Az adatbázis-tranzakciók
típus még a save() tagot definiálja, amely mentési pontok elhelyezését teszi le
hetővé a tranzakción belül. Ez a megközelítés megoldja, hogy hiba esetén
csak a megnevezett pontig kelljen visszagörgetni a tranzakciót ahelyett, hogy
a rendszer az egész tranzakciót visszagörgetné. Amikor az sqlTransacti on
163
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
ügyfeleket:
164
Az adatbázis-tranzakciók
ll A parancsok futtatása.
cmdinsert.ExecuteNonQuery();
cmdRemove.ExecuteNonQuery();
ll Hiba szimulálása.
if (throwEx)
{
throw new ApplicationException("Sorry! Database error!
Tx failed ...");
}
ll véglegesítsünk.
tx.CommitO;
}
catch (Exception ex)
{
console.writeLine(ex.Message);
ll Bármilyen hiba visszagörgeti a tranzakciót.
tx. RollbackO;
}
}
Ebben az esetben bool típusú bemeneti paraméterben jelöljük meg azt, hogy
szeretnénk tetszőleges kivételt kiváltani, ha megpróbáljuk a megbízhatatlan
vásárlót kezelni. Így könnyedén szimulálhatunk egy olyan előre nem látható
körülményt, amely miatt az adatbázis-tranzakció végrehajtása sikertelen lesz.
Természetesen ezt most csak a bemutató kedvéért tesszük, egy valós adatbá
zis-tranzakciós metódus nem engedi a hívónak, hogy tetszés szerint meghiú
sítsorr egy logikát.
Miután megkerestük a vásárló vezeték- és keresztnevét a bemeneti custiD
paraméter alapján, két sqlcommand objektumot használunk, amelyek a tranz
akció lépéseit képviselik, és a kapcsolatobjektumtól a BeginTransactionO me
tódus segítségével érvényes SqlTransacti on objektumot kapunk. Következő
fontos lépés, hogy minden parancsobjektumnak állítsuk be a Transaction tulaj
donságát: mégpedig a BeginTransacti onO eredményeként kapott tranzakció
objektumra. Ha ezt nem tesszük meg, a beszúrás/törlés logika nem lesz ben
ne a tranzakciós kontextusban.
165
22. fejezet: ADO.NET, 1. rész: Az élő kapcsolat
kivételt jelzünk akkor (és csak akkor), ha a bool paraméter értéke igaz. Ebben
az esetben a rendszer minden függő adatbázis-roűveletet visszagörget. Ha
nem jelzünk kivételt, a rendszer mindkét lépést jóváhagyja az adatbázistáb
lákban a commit() metódus meghívásakor. Fordítsuk le a módosított Auto
LotDAL projektünket, hogy elkerüljük a gépelési hibákat.
Az adatbázis-tranzakciónk tesztelése
• CustiD: 333
• FirstName: Horner
• LastName: Simpson
166
Összefoglalás
l� � ll ofll� �Ih!@!
22.17. ábra: Az adatbázis-tranzakciónk eredménye
Összefogla lás
167
HUSZONHARMADIK FEJEZET
ADO.NET, 2. rész:
A bontott kapcsolat
170
A DataSet szerepe
A DataSet szerepe
DataRelationCollection
171
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
Először nézzük meg a Dataset néhány fő tagját. A Tab l es, a Re l ati ons és az
ExtendedProperties tulajdonságok mellett a 23.1. táblázat ismertet néhány
további érdekes tulajdonságot.
Enforceconstraints Olyan értéket ad meg vagy vesz fel, amely jelzi, hogy va
lamilyen frissítési művelet végrehajtása során követni kell
a korlátozási szabályokat.
Has Erra r s Felvesz egy értéket, amely jelzi, hogy vannak-e hibák a
DataSet bármelyik DataTab l es objektumának bármelyik
sorában.
172
A DataSet szerepe
látozást.
összes módosítást.
173
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
DataSet létrehozása
tem.Data névteret):
carsrnventoryDS.ExtendedProperties["TimeStamp"] = DateTime.Now;
carsrnventoryDS.ExtendedProperties["DataSetiD"] = Guid.NewGuid();
carsrnventoryDS.ExtendedProperties["company"]
"rntertech Training";
console.ReadLine();
}
174
DataColumn típusok használata
175
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
A DataColumn létrehozása
176
DataColumn típusok használata
kezdőértékét, rníg a step érték határozza meg azt a számot, amelyet hozzá
kell adni a növeléskor. Nézzük meg a következő módosítást a carmcolumn
Datacolumn szerkezetében:
177
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
A Datacolumn típus általában nem önálló entitás, hanem egy kapcsolódó Data
Table objektumba illeszkedik. Ennek bemutatásához hozzunk létre új Data
Table típust, majd szúrjuk be az oszlopgyűjteményben található összes Data
column objektumot a columns tulajdonság alkalmazásával:
178
DataRow típusok használata
A D ataRow típusokkal egy kicsit másképp kell dolgozni, mint a Datac ol umn tí
Ehelyett be kell szereznünk egy DataRow referenciát egy adott DataTabl e ob
jektumból. Tegyük fel, hogy szeretnénk beszúrni két sort az Inventory táblába.
A DataTab l e. NewRow() metódus lehetövé teszi a táblázat következő "rekeszé-
179
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
carRow = invent:oryTable.NewRow();
A RowState tulajdonság
nunk egy táblában az összes olyan sort, amelynek az eredeti értéke megvál
tozott, amely újonnan lett beszúrva, és így tovább. Ehhez a tulajdonsághoz
hozzárendelhetünk bármilyen értéket a Dat:aRowst:at:e felsorolásból, amely a
23.5. táblázatban látható.
180
DataRow típusok használata
Deleted A sor törlésre ki lett jelölve a DataRow Dele te() metódusa révén.
ll Rowstate = Detached.
DataRow row = temp.NewRow();
Console.writeLine("After calling NewRow(): {O}", row.Rowstate);
ll Rowstate = Added.
temp.Rows.Add(row);
console.writeLine(''After calling Rows.Add(): {O}", row.Rowstate);
ll Rowstate = Added.
row["Tempcolumn"] = 10;
console.writeLine("After first assignment: {O}", row.Rowstate);
ll Rowstate = unchanged.
temp.Acceptchanges();
console.writeLine("After calling Acceptchanges: {O}",
row.Rowstate);
ll Rowstate = Modified.
row["Tempcolumn"] = ll;
console.writeLine("After first assignment: {O}", row.Rowstate);
181
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
ll Rowstate = oeleted.
temp.Rows[O].Delete();
Console.writeLine("After calling Delete: {O}", row.Rowstate);
}
A DataRowVersion tulajdonság
Amellett, hogy a Rowstate tulajdonsággal számon tar�a egy sor aktuális álla
potát, a DataRow objektum a DataRowversi on tulajdonság révén megőrzi az ál
tala tartalmazott adatok három lehetséges verzióját. Egy DataRow objektum
létrehozásakor csak az adatok egyetlen másolatát tartalmazza, amely "aktuá
lis változatként" van jelen. Ahogy azonban programozottan dolgozunk a
DataRow objektummal (a különböző metódushívások segítségéve!), további
current Egy sor aktuális értékét jelzi még a módosítások után is.
Proposed A sor értéke jelenleg szerkesztés alatt áll a B egin Edit() meghívá
sának köszönhetően.
182
DataTable típusok használata
Ez így egy kissé bonyolult- különösen amiatt, hogy egy DataRow rendelkez
het is meg nem is az összes változattal egy adott pillanatban (futásidejű kivé
teleket kapunk, ha olyan sorváltozatot próbálunk megszerezni, amelyet jelen
leg nem követünk nyomon). Az összetettségétől függetlenül, mivel a DataRow
három adatmásolatot tart karban, nagyon egyszerű lesz olyan front endet lét
rehozni, amely lehetövé teszi a végfelhasználó számára az értékek módosítá
sát, illetve azt, hogy meggondolhassa magát, és visszaállítsa az értékeket,
vagy végérvényesen jóváhagyjon értékeket. A továbbiakban különböző pél
dákat fogunk látni ezeknek a metódusoknak a kezelésére.
183
casesensitive Azt jelzi, hogy a sztring-összehasonlítások a táblákban
kis- vagy nagybetűérzékenyek-e (vagy sem). Az alapér
telmezett érték: fa l se.
184
DataTable típusok használata
ll A Dataset kiíratása.
PrintDataset(carsrnventoryDS);
console.ReadLine();
}
indexelőkkel:
ll Kiírja a DataTable-t.
for (int curRow = O; curRow < dt.Rows.count; curRow++)
{
185
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
186
DataTable típusok használata
187
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
A DataTable/DataSet objektumok
sorositása XML-ként
ll A Dataset kiürítése.
carsrnventoryDs.clear();
188
DataTable típusok használata
<Inventory>
<CariD>l<ICariD>
<Make>Saab<IMake>
<Color>Red<IColor>
<PetName>Sea Breeze<IPetName>
<IInventory>
<1Car_x0020_Inventory>
ter típust (lásd a 21. fejezetet), ahogy azt elvárha�uk. Vizsgáljuk meg a
ll A Dataset kiürítése.
carsinventoryDS.Clear();
189
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
•X
O 00 00 FF FF FF FF Ol 00 00 00 00 00 00
2 00 00 00 4E 53 79 73 74 65 60 2E 44 61 ...... NSyste�.Oa [J
C 20 56 65 72 73 69 6F 6E 3032 2E 30 2E ta. Version=2.0.
O 2C 20 43 75 6C 74 75 72 65 30 6E 65 75 0.0. Culture=neu
l 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 tra!. PublicKeyT
5 6E 3062 37 37 61 35 63 35 36 31 39 33 oken=b77a5c56193
O 38 39 05 Ol 00 00 00 13 53 79 73 74 65 4e089. .... Syste
4 61 74 61 2E 44 61 74 61 53 65 74 18 00 a.Oata.DataSet.
7 44 61 74 61 53 65 74 2E 52 65 606F 74 ...OataSet.Re�ot
7 56 65 72 73 69 6F 6E 16 44 61 74 61 53 ingVersion.OataS
E 52 65 606F 74 69 6E 67 46 6F 72 60 61 et.ReaotingFor�a
4 61 74 61 53 65 74 2E 44 61 74 61 53 65 t.DataSet.DataSe
l 6065 ll 44 61 74 61 53 65 74 2E 4E 61 tNaae.DataSet.Na
3 70 61 63 65 OE 44 61 74 61 53 65 74 2E •espace.OataSet.
5 66 69 78 15 44 61 74 61 53 65 74 2E 43 Prefix.DataSet.C
5 53 65 6E 73 69 74 69 76 65 12 44 61 74 aseSensitive.Oat
� 74 2E 4C 6F 3 61 6C 6 43 49 a t . ocale
�= ��_
t.. ::
_;_
:_� �- ..:
'�4
'::.-�
� - 5e
___ l ___ LC
_.-J
I� f > �
190
DataTable objektumok kötése felhasználói felületekhez
Megjegyzés Ez a példa azt feltételezi, hogy van némi tapasztalatunk a Windows Forms gra
fikus felhasználói felületek Létrehozásában_ Ellenkező esetben egyszerűen nyissuk meg a kész
példát, és kövessük azt figyelemmel, vagy térjünk vissza ehhez a részhez a 27_ fejezet elolva
sása után, amelyben formálisan megvizsgáljuk a Windows Forms API-L
--- _,.-
--
x
New Project
�
�_:· :��lL���----
froj<ct types: Iomplates: [.NET fr.,.,._,.x 3.5 �]m�
VtSuaiBasic Visual Studio installed tempiates
Vi5űaiC# � Reports Application �ASP.NET Wob Application
Windows
.. ASP.NET W� �rvice Application i'!ASP.NET AJAX S.rvor Control
Wob
DASP.NET AJAX Servor Control Extondor �Class Library
Office
Smart Device
� Console Application i'!Wob Control Library
lelWindows FormsApplic� i!� Windows Forms Controllibrary
Database
Tost i)iWPF AppiiOltion �WPFBrowser Application
WCF illWPF Custom Controllibrary �WPF User Controllibraty
Workflow MyTemplat� ------ ------------
A proj� for creating an application with a Windows Fonns user interface (.NET Framework 35)
Name: WindowsFormsOataTableViewer
Ol( l[ Cancol
•X
ír�
��:.,- .-;��-x-''
The Ctmrt Uo! r:J '"-tory
191
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
toryGridview nevet kapja) a tervezői felületre. Ekkor előugrik egy helyi menü,
class car
{
ll A C# automatikus tulajdonságok használata.
public string carPetName { get; set; }
public string carMake { get; set; }
public string carcolor { get; set; }
192
DataTable objektumok kötése felhasználói felületekhez
void createDataTable()
{
ll A táblázatséma létrehozása.
Datacolumn carMakecolumn = new Datacolumn("Make", typeof(string));
Datacolumn carcolorcolumn =
new Datacolumn("color", typeof(string));
Datacolumn carPetNamecolumn =
new DataColumn("PetName", typeof(string));
carPetNamecolumn.caption = "Pet Name";·
inventoryTable.columns.AddRange(new Datacolumn[] { carMakecolumn,
carcolorcolumn, carPetNamecolumn });
193
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
194
DataTable objektumok kötése felhasználói felületekhez
/'CM.Cs YMainForm.c.<Y �x
�. �
�-- ---�--·- -�
• ,::;�:.- --
;:-·-_ ___ _ _ _:.,:- • r
inventoryTable.Rows[(int.Parse(txtRemove.Text))].Delete();
195
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
196
DataTable objektumok kötése felhasználói felületekhez
{
DataRow temp makes[i];
=
tar.csl"MainForm.cs�!�� • x
l
l
lL=----��
Erter row rUIDer to delele Erter make To view
Rernove
·�-=��-'��;��]
197
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
� DataTable Voewer
Chucky
Frod
Sidd
OK
BMW
198
DataTable objektumok kötése fel használói felületekhez
Sorok módositása
199
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
200
DataTable objektumok kötése felhasználói felületekhez
public MainForm()
{
ll Adattáblázat létrehozása.
createDataTable();
ll Nézet létrehozása.
CreateDataview();
}
201
23. fejezet: ADO.NET, 2. rész: A bo n tott kapcsolat
í!lil DataTableV�ewer
202
DataSet/DataTable objektumok feltöltése adatillesztökkel
e.RowBounds.Location.Y + 4);
}
}
DataSet/DataTable objektumok
feltöltése adatillesztökkel
203
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
204
DataSet/DataTable objektumok feltöltése adatillesztökkel
@"Data source=(local)\SQLEXPRESS";
205
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
Megjegyzés A Fi ll() metódus olyan egész számot ad vissza, amely az SQL-lekérdezés által
visszaadott sorok számát jelképezi.
A Main() metóduson belül explicit módon sehol nem nyitunk meg vagy zá
runk be adatbázis-kapcsolatot. Egy adott adatillesztő Fill O metódusa auto
matikusan megnyitja, majd bezárja a kapcsolatot, mielőtt visszatérne a metó
dusból. Ezért, amikor átadjuk a Dataset objektumot a PrintDataset() metó
dusnak (a fejezet korábbi részében megvalósítottuk), akkor az adatok helyi
másolatán dolgozunk, és az adatokat nem kérjük le feleslegesen.
206
Az AutolotDAL.dll ismételt vizsgálata
207
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
ll AZ SqlDataAdapter konfigurálása.
configureAdapter(out dAdapt);
}
}
Insertcommand tulajdonságához.
208
Az AutoLotDAL. dll ismételt vizsgálata
209
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
A GetAlllnventory() implementálása
Az Updatelnventory() implementálása
háttérben.
210
Az AutolotDAL dll ismételt vizsgálata
.
using AutoLotDisconnectedLayer;
public MainForm()
{
rnitializecomponent();
ll Tételezzük fel, hogy van egy App.config fájlunk, amely
ll a kapcsolatsztringet tárolja.
string cnstr =
configurationManager.connectionstrings[
"AutoLotsqlProvider"].connectionstring;
211
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
Ez a példa azt feltételezi, hogy létezik egy App. con fig fájl, amely tárolja a
kapcsolatsztringadatokat a <connect:ionst:rin gs> részben. A confi gurat:ionMa
nager típus connect:i on st:rin gs indexelőjének használatához győződjünk meg,
hogy referenciát adtunk a syst:em. configu rat: ion. dll szerelvényre. Miután
létrehoztuk az rnvent:oryDALDisLayer objektumot, kössük hozzá a Get:Allrn
vent:ory() metódusból visszaadott Dat:aTabl e típust a Dat:aGri dview objek
tumhoz. Amikor a felhasználó az updat:e gombra kattint, kiszedjük a módosí
tott Dat:aTable típust a táblázatból (a Dat:asource tulajdonsággal), és átadjuk
az updat:ernvent:ory() metódusunknak.
Ha futtatjuk az alkalmazást, adjunk hozzá új sorokat a táblázathoz, és
módosítsunk/ töröljünk néhány másikat. Ha a gombra kattintunk, látni fog
juk, hogy a módosításokat az AutaLot adatbázis rögzítette.
Megjegyzés Ahelyett, hogy ismét módosítanánk az Aut:oLotDAL. dll szerelvényt, hogy hasz·
nálja a Customers és Orders táblákat, ez a példa új Windows Forms-projektben különít el minden
adatelérési logikát. Mindazonáltal kifejezetten ellenjavallt összekeverni a felhasználóifelület· és
az adatlogikát egy termékszintü alkalmazásban. A fejezet utolsó példái kihasználják a különbözö
adatbázistervező eszközöket, hogy elkülönítsék a felhasználóifelület-és adatlogikakódokat.
212
Navigálás a többtáblázatos DataSet objektumokban
ainForm:C:SV'........,.,.� •X
.11
lR Cars Database M.tnipulator t_gj(JID@
l
�l
23.13. ábra: A kezdeti felhasználói felület megjeleníti az A utoLot adatbázis tábláinak adatait
y�j
Az adatillesztök előkészitése.
213
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
Relationship() t, a következőképpen:
-
public MainForm()
{
Initializecomponent();
ll rllesztők létrehozása.
invTableAdapter = new sqloataAdapter("Select *from Inventory",
cnstr);
custTableAdapter = new sqlDataAdapter("select *from customers",
cnstr);
ordersTableAdapter = new SqlDataAdapter("select *from orders",
cnStr);
214
Navigálás a többtáblázatos DataSet objektumokban
ll Hozzákötés a táblázatokhoz.
dataGridviewinventory.Datasource = autoLotDS.Tables["Inventory"];
dataGridviewcustomers.DataSource = autoLotDS.Tables["customers"];
dataGridvieworders.Datasource = autoLotDS.Tables["orders"];
}
Az adatbázistáblák módositása
215
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
• x
Cuotomer ID:
9
6=-�==��--o==�-�
l Get Qdor Del* l l
23. 14. ábra: A módosított felhasználói felület lehetővé teszi a felhasználó számára,
hogy utánanézzen az ügyfelek megrendeléseinek
216
Navigálás a többtáblázatos DataSet objektumokban
217
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
218
Navigálás a többtáblázatos DataSet objektumokban
� CustomerOrder
Customer ID: 2 OK
219
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
Megjegyzés Nyilvánvalóan nem hihetjük azt, hogy soha nem kell manuálisan létrehoznunk
ADO.NET·logikát, vagy a varázsló által generált kód mindig tökéletesen megfelelő lesz az ak
tuális projektünk számára. Noha ezek az eszközök rengeteg időt megtakaríthatnak, mégis ér
demes minél többet tudunk az ADO.NET programozási modelljéről, ugyanis ezáltal egyedi igé·
nyeinkhez alakíthatjuk a létrehozott kódot.
220
A Visual Studio 2008 adatelérési eszközei
l
�
l
(EJ[§[)(}[] l
The Autalot lnventoryTable
' l
l'
l
ll
l
i
l
il!
!
ll
i
'link to l l
23. 1 6. ábra: A DataGridView szerkesztő
lm you connect to a database and choose th� database objK!s for your application. This option crmes a dataset.
Megjegyzés Ebben a lépésben arra is lehetőségünk nyílik, hogy egy külső XML-webszolgálta
tásból vagy külön .NET-szerelvényben lévő egyedi üzleti objektumból származó adatokat csat
lakoztassunk.
221
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
A második lépés (amely az első lépés választása alapján némileg eltérő lehet)
lehetővé teszi az adatbázis-kapcsolat konfigurálását. Ha van adatbázisunk,
amelyet hozzáadtunk a Server Explorerhez, az automatikusan megjelenik a
legördülő listában. Ha nincsen (vagy ha bármikor szükségünk van arra, hogy
olyan adatbázishoz csatlakozzunk, amelyet korábban nem adtunk hozzá a
Server Explorerhez), kattintsunk a New Connection gombra. A 23.18. ábra
muta�a az AutaLot helyi példányának kiválasztását.
Which �tit <onnection sbould your �lion use to connect to the �titböe?
Ll
int
_ eru
_ _:_,_
ber\sq ..:___ol
lexpr5s.Aut _ dbo
ot._______________ • ll
_, � ConnK!ion... J
Thi� connectlen !tri n g appe�rs to contain sf.nsitive data (for exsmple, a password}. wh!ch Í5" required tc ccnned to th�
d:3taba>;e. Hc-.ve-.•er, �tc ring �n�itive data m the connection string can be a security risk. Do you w;; nt to !ndude thi�
stmitiv� data in the connectien string?
_..,' No, e.;.;d ude !:l!:n:;ítive data from the ccnnecticn string. i will se:t this inform:ltietn in my application cc é e.
222
A Visual Studio 2008 adatelérési eszközei
0 1]] PetName
·--
DataSet name:
lnventoryDataSet
_ __ j
!1
a--·--·--·-··-·----·---·------·---·..1 .
23.20. ábra: A Windows Forms-projektünk a Data Source Configuration Wizard futtatása után
223
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
jvw
BMW Pri< Sidd
-· í
t
2 Red ZwY
3
iFonJ Black j Me!
4 j BMW Siver Hervy
5
jYugo JPri< Saly
6 jSaab J Blue Sven
l l
�
224
A Visual Studio 2008 adatelérési eszközei
new global::System.Data.sqlclient.Sqlconnection();
this._connection.connectionstring =global::
VisualoataGridviewApp.Properties.settings.Default.
AutoLotconnectionString;
}
:,.�- -
'fltutz Roede."s .NET R..fledw ��.;__,__ �T.;;,j@iif3il
; filo Y- Tools Help
� ó OT� i.if�1i _p-�:T�nOnn-
nn ���-�
111 .O Pr6enbtionCOt'e •ll�
ffi .Q Pr�ntationFramework
{CompilerG�e.rated. Gener;,tedCoderMicrosoft.VisuaiStudio.Editors.SettingsDesigner.SettingsSing
�
8 .Q AutalotDAl
internal sf!aled class Sdtings: ApplicationSettingsBase
8 1\ AutolotDAL.dll {
m � Rderences ll Field.s:
0{). private static Settings defiiUftlnsUnc�
00 {} AutolotConnectedlayer
ll ��1ethod!>
1iJ O AutolotDAL static Sett:in9sű;
(il {} AutolotOAL.AutolotDataSetTa : public Settings();
8 {} AutolotDAL.Properties
ID�I!m B!!m!
[DefauftSgtingValue(@�Data Source:::(locai)\SQLEXPRESS;Initial Catalog:::Autolot;lntegrated Sec
ffi {) AutolotOisconnectedlayer
1-, L: 1
public string AutolotConnectionString ( get; }
public static Srltings Oef.ault:{ get; }
� J
internal sealed class Settings : Applicatiorc"l Expond ethods
M
Nii1lme: AutolotOAL.Propert.i�ings •
·-
-�
225
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
lnventoryOataSet ®
Class
.. Datas.!
13 Fields
:;P _schemaSeríali;:ationMcde : Schen;aSeri.1li ...
8 Properties
fff inventory {get: } : lnventoryDataTab! e
!!il Relaticns {get; } : DataRelationCollet:tion
� SchemaSeriali:::ationt'-.,1ode { get; set; } : Sch. . .
"ffi' Tables (get; i: DataTableCcllecticn
13 Melhods
23.23. ábra: A Data Source Configuration Wizard létrehozott egtj erősen típusos DataSet típust
226
A Visual Studio 2008 adatelérési eszközei
this.rnitclass();
}
227
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
228
A Visual Studio 2008 adatelérési eszközei
(lnvent�Table ®l
Class
l
l -+ TypedTableBase<lnvento�
lii Fields
lit) Properties
!
1:! Methods
-=\il AdólnventoryP.c-.�,;(ínt CariD, string Make_, string Color, string PetName) : Inventor;Row
:(; AddfnventcryRow(InventoryRow rov.·) ,;oíd
:
-� Clone(): DataTab/e
j'l Createlnstance(}: D:1taTable
._, FindByCarlD{int <2 riO) lnve:ntcryRc\''
:
l lnventoryRow ®
Class
-+OataRow
8 Fields
# �ableinventol)': !nventcryOataiable
�Properties
8 Methods
229
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
A generált adatillesztő
lnventc><ylableAdapter ®
Class
.. comporoert
8 Fields
ji _adapter: SqiDataAdapter
9 Properti<S
ifj} Adapter { get; } : SqiDataAdapter
tfJ ClearBeforeFill { get; set; i : boci
�· CommandCollection {get: } : SqlCommandO
\;'g Connection {ge� set: } : SqiConnection
� Transaction {get; set;}: SqiTrans.action
13 Methods
230
A Visual Studio 2008 adatelérési eszközei
231
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
;x
r����-p,;·;;; --0------------------------y
i
CarlO
Make
� l
o
o 6
l
L_: :--_���=····=·--·=··=--�-=---=-=·-�-��-- -�-0:-_---�---_-_-·-=�����-··-··-· - _Ó_' ��--��[J,
____ _
_
__
l < lr:::::;��==�c:===::;:::�:::=::J
l � inventoryDataSet rrJSl inventoryBindingSource 'm inventoryTableAdapter
l
l 'L
23.27. ábra: Egtjszerű frissítés az !Írlap típusához
inventoryDataSet.Inventory.NewinventoryRow();
newRow.cariD = int.Parse(txtcariD.Text);
newRow.Make = txtMake.Text;
newRow.color = txtcolor.Text;
newRow.PetName = txtPetName.Text;
inventoryDataset.Inventory.AddinventoryRow(newRow);
232
A:z. automatikusan generált kód elválasztása a felhasználóifelület-rétegéről
Végül mutassunk rá, hogy míg a DataGridView által elindított Data Source
Configuration Wizard elvégezte a munkát helyettünk rengeteg kód létrehozá
sával, az előző példa az adatelérési logikát közvetlenül a felhasználóifelület-ré
tegbe illesztette be - ez pedig súlyos tervezési hiba. Ideális esetben ez a kód az
AutaLotDAL. dll szerelvényünkhöz (vagy más egyéb adatelérési könyvtárhoz)
tartozik. Elgondolkozhatunk azon, hogy hogyan hasznosíthatjuk a DataGrid
View varázslójában generált kódot egy osztálykönyvtár-projektben, hiszen az
alapértelmezés szerint nem áll rendelkezésünkre űrlaptervező.
A Visual Studio 2008 adattervezői eszközeit bármilyen típusú projektből
elérhetjük (legyen az felhasználóifelület-alapú vagy másmilyen) anélkül,
hogy óriási mennyiségű kódot kellene átmásolnunk egyik projektből a má
sikba. A lehetőségek bemutatásához még egyszer nyissuk meg az AutaLot
DAL projektet, és illesszünk be új Dataset típust (AutoLotDataset) a Project >
� � �
lü- l
�
ADO.NET Web About Box Application Application Bitmap File
Entity Da... Configurat... Configurat... Manifest File
�
Class
�Class
�
CodeFile
�
Component
�
CursorFile
JE'
Custom
u
Diagram Class Control
�
DataSet
�
Oebugger HTMLPage
[il .
�
IconFile
�
lnstaller Class
�
Interface
Vlsualizer
..
� . .....
lJ l
�
.....� .. -
�
" _. _
u �
· · ·-· ·- - - - - ---
A OataSg for using data in your application
--------
Name AutolotDataSt.t.xsd
Add JI Cancel l
233
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
Ekkor megnyílik egy üres Dataset Designer felület. A Server Explorer segít
ségével kapcsolódjunk egy adott adatbázishoz (elvileg már kapcsolódunk az
AutoLothoz), és húzzunk át minden adatbázis-objektumot (most ne törőd
jünk a CreditRisk táblával), amelyet a felületen szeretnénk generálni. A 23.29.
ábrán láthatjuk az AutoLot minden olyan egyedi aspektusát, amelyről most
gondoskodunk.
r,.. lnventory
@
f CarlO
Make
Color
l
!l
l l
�==�====�=====J·�
23.29. ábra: Az egyedi erősen típusos típusaink, ezúttal egy osztálykönyvtár-projekten belül
'l
234
Az automatikusan generált kód elválasztása a felhasználóifelület-rétegéről
AutotottlataSet ®
Class
+Datas.t
8 Fields
.JI _sc:hernaSerializationMode
:JI relationFK_Orders_Customers.
:.fl relatlonFK_OrdersJnventcry
.'!J� tab!eCustomers.
# table!nvento1y
;fi tableürders
8 Properties
� Cus.tcmers
� Inventcry
'fft Order;
f8 Relations
1ft SchemaSericlizationMcde
1ft Tables
lil Methods
JnventorylableAdapter @J TableAdapterManager ®
aass Class
,.. componert :+ Componert
-
8 Fields
QuerleslableAdapter ®
Class t/' _ba.:kupOataSetSefcreUpda�e
+ Componert :;{1 _ccnnection
- - - -·
/
# _custcmersTzobleA.dapter
CustomerslableAdapter ® # _inventoryTableAdapter
Clan .# _ordersTableAdapter
[
+ Componert
ir J' _updateOrder
'-.- - - -- 8 Properties
OrderslableAdapter @} � BackupDataSetBefcreUpdate
Class
'ff! Conne:::tíon
+ Componert
l fff Custom�rsTableAdapt�r
-......- �- --
- --
� InventoryTableAdapter
:f!i' Order>TableAdapter
� TableAdapterinstance(cunt
� UpdateOrder
8 Methods
},� GetReaiUpdatedRO>.'.'S
.fQI MatchTableAdapt�r(onnecti ..
,�tV SortSelfReferenceRo'ss
,._ UpdateAli
;;,• UpdateDeletedRows
�'W UpdateinsertedRows
},._ UpdateUpdatedRows
235
23. fejezet: ADO.NET, 2. rész: A bontott kapcsolat
Bár most nem foglalkozunk azzal, hogy megnézzük a teljes kódot (mivel töb
bé-kevésbé ugyanaz, mint a projekt első iterációja), néhány fontos megjegy
zést azonban érdemes tenni:
Az utolsó ponttal kapcsolatban figyelni kell arra, hogy a Dataset Designer ál
tal a táblakapcsolatoknak adott nevek különböznek azoktól, amelyeket mi ad
tunk a projekt első iterációjában. Ezért a btnGetOrderrnfo_cli ck() metódust
módosítani kell, hogy a helyes kapcsolatneveket (amelyeket a Dataset Desig
ner tervezői felületén láthatunk) használja, például:
drscust[O].GetchildRows(
autoLotDS.Relations["FK_Orders_customers"));
236
Összefoglalás
drsorder[O].GetParentRows(
autoLotDS.Relations["FK_Orders_Inventory"]);
Összefoglalás
237
HUSZONNEGYEDIK FEJEZET
Megjegyzés Ez a fejezet az első kötet14. fejezetében leírt LINQ programozási modellben való
jártasságat feltételezi.
A LINQ programozási modell (lásd az előző kötet 14. fejezetét is) lehetővé teszi a
programozók számára, hogy olyan erősen típusos lekérdezéskifejezéseket hoz
zanak létre, amelyeket az adattárolók széles körére lehet a1kahnazni (tömbök,
gyűjtemények, adatbázisok, XML-dokumentumok). Függetlenül attól, hogy mi
lyen objektumon haj�uk végre a LINQ-lekérdezést, mindig lehet ugyanazokat a
lekérdezésoperátorokat használni, és a LINQ to ADO.NET API néhány további
típust és infrastruktúrát is biztosít a UNQ-adatbázis integrációjához.
A LINQ to ADO.NET olyan gyűjtőfogalom, amely a LINQ két adatbázis
központú szempon�át írja le. Az egyik a LINQ to DataSet. Ez az API lényegé
ben bővítménykészlet a szabványos ADO.NET DataSet programozási modell
hez, amely lehetővé teszi, hogy a Dataset, a DataTab l e és a DataRow típusokon is
lehessen UNQ-lekérdezéskifejezéseket végrehajtani. A system. cor e. dll típusa
inak használatán túl a LINQ to DataSet megköveteli, hogy a projekt használja a
system. Data. DataSetExtensi ons. dll szerelvény kiegészítőtípusai t.
24. fejezet: A UNQ API programozása
Megjegyzés A .NET 3.5 óta a LINQ to SQL nem támogatja az data provider factory modellt
(lásd a 22. fejezetet). Ezért amikor ezt az API-t használjuk, az adatoknak a Microsoft SQL Ser
veren kell lenniük. Ezzel szemben a LINQ to DataSet API természete "szabadosabb", ugyanis a
kezelt Dataset bármilyen relációs adatbázisból származhat.
• indexelőkkel,
• adattáblázat-olvasókkal,
240
Programozás a LINQ to DataSettel
console.writeline();
}
}
tést kínál, amely szerínt a Dataset adatait úgy kezelhe�ük, mínt sorok lineáris
készletének szekvenciális feldolgozását:
while (dtReader.Read())
{
for (int i = O; i < dtReader.Fieldcount; i++)
{
console.write("{O}\t'', dtReader.Getvalue(i));
}
Console.writeLine();
}
dtReader.close();
}
Ezen túlmenően a LINQ to DataSet még egy lehetőséget biztosít a tárolt ada
tok kezelésére a LINQ-lekérdezéskifejezések használatávaL Az ADO.NET
DataSetbe (és az olyan kapcsolódó típusokba, mínt a DataTable és Dataview)
alapvetően nincsen integrálva a szükséges infrastruktúra ahhoz, hogy köz
vetlenül végrehajtsunk rajta egy LINQ-lekérdezést. A következő metódus
például fordítási idejű hibát eredményezne:
241
24. fejezet: A LINQ API programozása
1 �s-
·�-
- �
y sol ion
._
M _ _ m_ _ ____________ 8:� ·
··��1_
•
�
�
• 1�
�� , =�·----�----------�--���
� [@� l
j
<Search>
Ja -?;
...
l
• . • . . l�'
J
B·· O System.Data
[!J
<i: DataRowComparer
8 '1$ DataRowExtenSions
J i'
l±J � DataTableExt�nsions
ffi '\$ EnumerableRowColl«tion
ffi- <1$ EnumerableRowColleet•on<TRow> i!
LiJ <1:$: EnumerableRowCollect1onExtens1ons :======================JI
8- <1$ OrderedEnumerableRowCollectton< TR Assembly System.Data.DataSetExtensions
.
�··� TypedTableBase<T> C:\Program Flles\Reference Assembhes\Mlcrosoft
242
Programozás a LINQ to DataSettel
using System.Data;
using AutoLotDisconnectedLayer;
namespace LinqOverDataSet
{
class Program
{
static void Main(string[] args)
{
console.WriteLine("***** LINQ over DataSet *****\n");
ll Beolvassuk az AutoLot adatbázis aktuális Inventory
ll táblájának DataTable típusát.
rnventoryDALDisLayer dal = new rnventoryDALDisLayer(
@''Data Source=(local)\SQLEXPRESS;Initial
catalog=AutoLot;" + "Integrated Security=True");
DataTable data = dal.GetAllrnventory();
console.ReadLine();
}
}
}
243
24. fejezet: A LINQ API programozása
244
Programozás a LINQ to DataSettel
245
24. fejezet: A LINQ API programozása
ll Kiírja a DataTable-t.
for (int curRow = O; curRow < newTable.Rows.Count; curRow++)
{
for (int curcol = O; curcol < neWTable.Columns.count; curcol++)
{
console.write(
newTable.Rows [eurRow] [eu rcol J .ToString().Trim() + "\t");
}
Console.writeLine();
}
}
where
car.Field<int>("CariD") > 5
select car).CopyToDataTable();
246
Programozás a LINQ to SQL használatával
A LINQ to SQL olyan API, amely lehetövé teszi jól megformázott LINQ-lekérde
zéskifejezések alkalmazását relációs adatbázisokban lévő adatokra. A LINQ to
SQL több olyan típust kínál (a system. Data. Linq. dll szerelvényben), amelyek
megkönnyítik a kommunikációt a kód és a fizikaiadatbázis-mator között.
A LINQ to SQL legfőbb célja az, hogy konzisztenciát biztosítson a relációs
adatbázisok és a velük folytatott munkára használt programozási logika
számára. Ahelyett például, hogy az adatbázis-lekérdezéseket nagy sztringek
kel jelképeznénk, használhatunk erősen típusos LINQ-lekérdezéseket. To
vábbá ahelyett, hogy a relációs adatokat rekordok folyamaként kellene ke
zelnünk, dolgozhatunk az adatokkal szabványos objektumorientált progra
mozási módszerekkel. Mivel a LINQ to SQL lehetövé teszi az adatelérés in
tegrálását közvetlenül a C#-forráskódba, nagymértékben csökken annak a
szükségessége, hogy manuálisan hozzuk létre egyedi osztályok tucatjait, va
lamint azokat az adatelérési könyvtárakat, amelyek elrejtik szem elől az
ADO.NET csúnya kódjait.
Amikor LINQ to SQL felhasználatásával programozunk, nyoma sincs az
olyan megszakott ADO.NET-típusoknak, mint az sqlConnection, az sqlCom
mand vagy az SqlDataAdapter. A LINQ-lekérdezéskifejezések, a (hamarosan
ismertetendő) entitásosztályok és a Datacontext típus segítségével végrehajt
hatjuk a kívánt adatbázis-roűveleteket (létrehozás, eltávolítás, módosítás és
törlés), valamint definiálhatunk tranzakciós kontextusokat, létrehozhatunk új
adatbázis-entitásokat (vagy egész adatbázisokat), meghívhatunk tárolt eljárá
sokat, és elvégezhetünk egyéb adatbázis-centrikus tevékenységeket.
Ezenfelül a LINQ to SQL típusok (példaként megint a Datacontextet em
líthetjük) feladata, hogy megvalósítsák a standard ADO.NET-adattípusok in
tegrációját. A Datacontext egyik túlterhelt konstruktora bemenetként például
egy robconnection objektumot vár, amely az összes ADO.NET-kapcsolatob
jektum által támogatott közös interfész. Ilyen módon a már meglévő
ADO.NET adatelérési könyvtárak integrálhaták a C# 2008 LINQ-lekérdezés
kifejezésekbe (és fordítva). Valójában - ami a Microsoftot illeti - a LINQ to
SQL egyszerűen az ADO.NET-család egyik új tagja.
247
24. fejezet: A LINQAPI programozása
Az entitásosztályok szerepe
eo System.Oata.Lmq.Mapp•ng
.
éJ-<\: AssociationAttribute
éJ.··<\: AttributeMappingSource
ID-cií-.1 AutoSync
$--� ColumnAttribute
éJ.-� DataAttribute
ffi.·<\: DatabaseAttribute
$-�� FunctionAttríbute
éJ...<\: lnheritanceMappingAttribute
tD ·� MappingSource
dJ..'if MetaAccessor
éJ.. � MetaAccessor<TEntity,TMember>
fil. .� MetaAssociation
$--� M�aDataM�mber
éJ 'if MetaFunction
éJ..c;íll MetaFunctionType
dJ ..<if MetaModel
$-·<is MetaParameter
@..� MetaTable
éJ.<if MetaType
dJ.."'$ ParameterAttribute
$---� ProviderAttribut�
$ . � Resu�TypeAttribute
!$J.·� TableAttribute
$ � UpdateCheck
24. 2. ábra: A System.Data.Linq.Mapp ing névt érszámos LINQ to SQLattribútumot definiál
248
Programozás a LINQ to SQL használatával
[Table]
public class rnventory
{
[Column]
public string Make;
[Column]
public string color;
[Column]
public string PetName;
249
24. fejezet: A Ll NQ API programozása
class Program
{
const string cnstr =
"Integrated security=True";
static void Main(string[] args)
{
console.writeLine("***** LINQ to SQL sample App *****\n");
250
Programozás a LINQ to SQL használatával
251
24. fejezet: A LINQ API programozása
ll Megkapjuk a BMW-ket.
var bimmers = from s in db.Inventory
where s.Make == "BMW"
orderby s.CariD
select s;
252
Programozás a LINQ to SQL használatával
253
24. fejezet: A LINQ API programozása
Entitásosztályok generálása az
SqlMetal.exe használatával
254
Entitásosztályok generálása az SqlMetal.exe has ználatával
adatbázisfüggvények megfelelőit.
255
24. fejezet: A LINQAPI programozása
Q
Autalot ® lnventory ®
Class Class
-t DataContel
13 Fields
8 Fields
# _CartD
s{l mappingSourc�
.# _Color
B Properties i' _Make
iif CreditRisks # _Orders
iif Cus1omers ;;P _PetName
'fff lnventory &fl emptyChangin ...
iif Orders B Properties
8 Methods iif CartD
il"' Autalot (+4 ov... iif Color
}}� Del e�eCredítRís .. . �Make
�"# Dele!eC'ustcmers iif Orders
Ji._ Delete!nventory 1ft PetName
:},� DeleteOrder< 1±l Methods
•(; GetPetName
1±l Events
},(; InsertCreditRisks
2 InsertCus1omers
�., Inserdnventory
�· InsertOrders
j,.;; OnCre•ted
Sp_alterdiagram
,.;; Sp_creatediagr ...
;(; Sp_dropdiagram
Sp_helpdiagra ...
•(; Sp_helpdiagrams
S p_renamediag . ..
2.;; UpdateCreditRi .. .
.;} UpdateCustom .. .
},.;; Updatelnventory
·:},li; UpdateOrders
Van tehát egy új, a Datacontextet kibővítő típusunk, amely tartalmazza a tu
lajdonságokat a megadott adatbázisban lévő összes adattábla számára (továb
bá a GetPetName O tárolt eljárást a megegyező névvel rendelkező nyilvános me
tódus képviseli). Mielőtt elkezdenénk használni ezeket az új típusokat, vizsgál
juk meg egy kicsit alaposabban ezt az automatikusan generált kódot.
256
Entitásosztályok generálása az SqlMetal.exe használatával
A generált entitásosztályok
namespace System.Data.Linq
{
public interface INotifyPropertychanging
{
ll Az esemény akkor következik be, mielőtt egy tulajdonság
ll értéke megváltozik.
event PropertychangedEventHandler Propertychanging;
}
}
namespace system.componentModel
{
public interface INotifyPropertychanged
{
ll Az esemény akkor következik be, amikor egy tulajdonság értéke
ll megváltozott.
event PropertychangedEventHandler Propertychanged;
}
}
[Table(Name="Inventory")]
public partial class rnventory : INotifyPropertychanging,
INotifyPropertyChanged
{
public event PropertychangedEventHandler Propertychanging;
public event PropertychangedEventHandler Propertychanged;
257
24. fejezet: A LINQ API programozása
[Column(Storage="_PetName", DbType="Varchar(50)")]
public string PetName
{
get
{
return this._PetName;
}
set
{
if ((this._PetName != value))
{
this.OnPetNamechanging(value);
this.sendPropertychanging();
this._PetName = value;
this.sendPropertychanged("PetName");
this.OnPetNamechanged();
}
}
}
258
Entitásosztályok generálása az SqlMetal.exe használatával
[Table(Name="Customers")]
public partial class customers
INotifyPropertychanging, INotifyPropertyChanged
{
private Entityset<Orders> _orders;
[Association(Name="FK_Orders_customers", Storage="_orders",
OtherKey="CustiD"', Del eteRul e="NO ACTION")]
public Entityset<Orders> Orders
{
get { return this._orders; }
set { this._orders.Assign(value); }
}
Az sq l meta l . exe által generált kód utolsó figyelemre rnéltó eleme a Datacon
textből származtatott típus. Az előző példában létrehozott AutaLotDatabase
osztályhoz hasonlóan rninden táblát Tab l e<T>-kornpatibilis tulajdonság jel
képez. Ez az osztály ernellett rendelkezik olyan konstruktorokkal, amelyek
egyike paraméterként várja az I Dbean n ection osztályt megvalósító objektu
mot, amely egy ADO.NET-kapcsolatobjekturnot jelképez (a LINQ to SQL és
az ADONET-típusok keverhetők egyetlen alkalmazásorr belül).
Emellett ez a Datacontextből származó osztály rnuta�a, hogyan dolgozha
tunk az adatbázisban meghatározott tárolt eljárásokkal. Mivel megadtuk az
/sprocs kapcsolót a sqlmetal.exe-nek, találunk egy GetPetName O nevű rnetódust:
259
24. fejezet: A LINQAPI programozása
[Function(Name="dbo.GetPetName")]
[return: Parameter(DbType="Int")]
public int GetPetName([Parameter(DbType="Int")]
system.Nullable<int> cariD,
[Parameter(DbType="Char(lO)")]
ref string petName)
{
IExecuteResult result = this.ExecuteMethodcall(this,
((Methodinfo)(Methodinfo.GetcurrentMethod())),
cariD, petName);
petName = ((string)(result.GetParametervalue(l)));
return ((int)(result.Returnvalue));
}
class Program
{
const string cnstr =
@"Data source=(local)\SQLEXPRESS;rnitial catalog=AutoLot;" +
"Integrated security=True";
260
Entitásosztályok generálása az SqlMetal.exe használatával
A LINQ to SQL teljes méctékben elrejti előlünk az alapul szolgáló tárolt eljá
rás logikáját. Itt nem kell manuálisan sqlcommand objektumot létrehozni, fel
tölteni a paramétergyűjteményt vagy meghívni az ExecuteNonQuery() metó
dust. Ehelyett egyszerűen meghívjuk a Datacontextből származtatott típus
GetPetName() metódusát. A kimeneti paraméterek referenciaparaméterként
jelennek meg, ezért a C# ref kulcsszó használatával kell meghívni őket.
Tételezzük fel, hogy van egy másik segédfüggvényünk (amelyet szintén a
Main() metódusból hívunk meg), ennek neve PrintOrderForcustomer(). Ez a
metódus kiír néhány megrendelésinformációt a megadott ügyféllel kapcso
latban, valamint az ügyfél kereszt- és vezetéknevét
var customerorders =
261
24. fejezet: A Ll NQ API programozása
262
Entitásosztályok létrehozása a Visual Studio 2008 használatával
�attgori� Iemplate:s: �G
Visual C# Jtems Diagram Cli!�ss Control
Code
Data
e r
G ne al
�
DataSet
�
Debugger
�
HTML Page
li
leon File
�
Installeretass
�
Interiace
Web Visualizer
Windows Forms
n
�� �ld ll tre1. � �
�
WPF
! local
JS<:ript File
L �UNQto SQ
Clas�
local
Database Databa...
MDJ Parent
Form
Report
.
t]1 '�
Report
� ;,_ (j
Resources Servicewba...
[ii1
Settings File
�
Style Sheet
[i1
Text File
Wizard File Database
ll- � i)
. ..... ... ,.. [ji
.
"''
ti]
- li
--
UNQto SQl dasses mapped to retatíonal obj�.
t!ame: AutolotObjects.dbml
1\dd J[ Cancol
24.6. ábra: A LINQ to SQL Classes elem ugt;anazokat a feladatokat végzi el, mint az sqlmetal.exe
Nyissuk meg a Server Explorert, és győződjünk meg róla, hogy van aktív
kapcsolatunk az AutoLot adatbázissal (ha nincs, akkor jobb gombbal kattint
sunk a Data Connections ikoma, és válasszuk az Add Connectiont). Jelöljük
ki az összes táblát, és húzzuk át őket a LINQ to SQL tervezőfelületre. Ekkor a
képernyő a 24. 7. ábrához hasonlít.
Cml- @ IIIW!IItory @
8 Properties 13 Properties
� PetName
CUstomer @ •
Onkr @
8 Properties
� 13 Properties
·l 'fff CustiD
'fff' FirstName
':ji' Order!D
'fff' LastName
'fff' Cust!D
- �CarlO
263
24. fejezet: A LINQ API programozása
Class Vi""'
t=·,
l <Search>
,_
l±l·D Proj.ct R.terencos
.
G·O
.
LinqToSqiCrud
!±J � AutolotObjectsDataContext
@. <1$ CreditRisk
éJ· � Customer .
·
$�llllll!lm
!±J·� Order
, ffi . � Program
1'1 ..
�J
@ {) LinqToSqiCrud.Propertios
.
i ·{J� OnPetNameChangedO
L IJY OnPetNameChanging(string)
C::,
! ,;l OnValidaleO
· l
i . ,$ 11
,·-;jY SendPropertyChanged(string)
SendPropertyChangingO
1l i: ·'ffi'
·!5' Car!D
�
Color
� •.. fT Make --
_
i i -!5' Orders
! L'ffj' PetName
l
l ·. ;fi _CarlO 1
( ·� emptyChangingEventArgs
; :;fi _Color
===='�
View l
-- ---:::
-r =
Új elemek beszúrása
Ahhoz, hogy új elemet szúrjunk be egy relációs adatbázisba, csak annyit kell
tennünk, hogy létrehozzuk az adott entitásosztály egy új példányát, majd
hozzáadjuk a oatacontext által fenntartott Tabl e<T> típushoz, és meghívjuk
rajta a submitchanges() metódust. Az alábbi InsertNewcars() metódus hoz
záad két elemet az Inventory táblához. Az első megközelítés közvetlenül be
állí�a az rnventory entitásosztály minden mezőjét, míg a második a tömörebb
objektuminicializáló szintaxist használja:
264
Entitásosztályok létrehozása a Visual Studio 2008 használatával
ctx.lnventories.lnsertönsubmit(newcar);
ctx.submitchanges();
}
265
24. fejezet: A LINQ API programozása
select c).First());
ctx.submitchanges();
}
"Integrated Security=True";
AutoLotobjectsDatacontext ctx =
new AutoLotObjectsDatacontext(cnstr);
InsertNewcars(ctx);
Updatecar(ctx);
Deletecar(ctx);
console.ReadLine();
}
266
XML-dokumentumok kezelése a LINQ to XML használatával
Végezetül bemutatjuk a LINQ to XML szerepét, amely azt lehetővé teszi, hogy
LINQ-lekérdezéskifejezéseket alkalmazzunk XML-dokumentumokon. Az
XML-adatok reprezentációja mélyen beágyazódott a .NET keretrendszerébe.
Az alkalmazások és a webalapú konfigurációs fájlok XML-ként tárolják az
adatokat. Az ADO.NET Datasetek könnyedén elmentik (vagy betöltik) XML
ként az adatokat. A Windows Presentation Foundation egy XML-alapú nyelv
tant (XAML) használ az asztali felhasználói felületek ábrázolására, a Windows
Communication Foundation (valamint a .NET-remoting API) szintén számos
beállítást tárol olyan jól formázott sztringként, amelyet XML-nek lúvunk.
Noha az XML valóban mindenhol jelen van, programozása mindig is
unalmas, terjengős és összetett volt, ha valaki nem volt tisztában számos
XML-technológiával (XPath, XQuery, XSLT, DOM, SAX stb.). A .NET plat
form kezdetei óta a Microsoft egy olyan speciális szerelvényt biztosít az
XML-dokumentumok programozásához, amelynek system.xml.dll a neve.
Ezen a bináris fájion belül számos névtér és típus található a különböző XML
programozási módszerekhez, valamint néhány .NET-specifikus XML API,
mint például az xml Reader/Xmlwri ter modellek.
Ahogy a LINQ to SQL célja az, hogy a relációs adatbázisok kezelését közvet
lenül a .NET programozási nyelvekbe integrálja, úgy a LINQ to XML is ezt a
célt tűzi ki az XML-adatok feldolgozása terén. Nemcsak olyan eszközként
használhatjuk a LINQ to XML-t, amellyel LINQ-lekérdezésekkel megszerez
hetünk adatrészhalmazokat egy meglévő XML-dokumentumból, hanem
ugyanezt az API-t használhatjuk XML-adatok létrehozására, módosítására és
elemzésére is. Emiatt a LINQ to XML-re gondolhatunk úgy is, mint egy "jobb
DOM" programozási modellre. Emellett, ahogy a LINQ to SQL együttműköd
het az ADO.NET-típusokkal, a LINQ to XML is dolgozhat a system.xml .dll
szerelvények számos tagjával.
267
24. fejezet: A LINQAPI programozása
A System.Xml.Xlinq névtér
El·.O System.Xmi.Linq G
éJ.-O System.Xmi.Linq
. � Extensions
$-· LoadOptions
GJ·-� SaveOptions
$··'1: XAttribute
Gr·'1: XCData
$-� XComment
ffi . � XContainer
. .
$··'\$ XDeclaration
$···'!$ XDocument
@ ·'1$ XDocumentType
$ '1$ XE!ement
·
@.� XName
S··"it XNamespace
é··'!$ XNode
$--� XNode:DocumentOrderComparer
$-'1: XNodeEqualityComparer
S· '1$ XObject
�h,jll XObjectChange
rB·· 'I$ XObjectChangeEventArgs
. tiJ·dil XObjectChangeEventHandler
j ffi-··'i: XProcessinglnstruction
: @ � XStreamingEiement
...
: s-01: xrext
8.-ol§§fi!Jffili'D
. rB···'I$ Extensions
EJ·O System.Xmi.XPath
@... t Extensions
13
24. 9. ábra: A System.Xml.Linq.dll névterei
. . . ' . . .
{. �·. '
·. :
268
XML-dokumentumok kezelése a LINQ to XML használatával
Ennek (és más) típusoknak a vizsgálatához hozzunk létre egy parancssori kon
zolalkalmazást LinqToxmlBas i cs névvel, majd importáljuk a system. xml. L i nq
névteret a kezdeti kódfájlba.
valósítással:
new XElement("Inventory",
new XElement("car", new XAttribute("ID", "1"),
new XElement("Color", "Green"),
new XElement("Ma k e", "BMW"),
new XElement("PetName", "stan")
)
);
ll A ToString() meghívása az XElementünkön.
console.WriteLine(inventory);
}
269
24. fejezet: A LINQ API programozása
new XDocument(
new xoeclaration("l.O", "utf-8", "yes"),
new xcomment("current Inventory of AutoLot"),
new XElement("Inventory",
new XElement("car", new XAttribute("ro", "1"),
new XElement("color", "Green"),
new XElement("Make", "BMW"),
new XElement("PetName", "stan")
) '
270
XML-dokumentumok kezelése a LINQ to XML használatával
�x
�:1.
3�8 <!nventory>
4 'é <Car ID="l ">
sj <Color>Green</Color>
6' <Hake>BMW</Hake> '
7! <PetName>Stan</PetName> '
3! </Car>
l
2;- <Car !!)>=>:"2">
10' <Color>Piok</Color>
ll· <Make>Yugo</Make>
12� <PetName>Melvin</PetName>
13' </Car>
1"3[ </In�tentory>
Ami az utolsó pontot illeti, tételezzük fel, hogy van egy névtelen típusokból
álló névtelen tömbünk, amely egy egyszerű car osztályt képvisel. Készíthe
tünk egy UNQ-lekérdezést, amely kiválogat minden név j érték párt a tömb
ből, hogy dinamikusan létrehozhassunk egy új XElement típust:
new XElement("Inventory",
from c in data
271
24. fejezet: A LINQAPI programozása
272
Navigálás egy memóriában lévő dokumentumban
273
24. fejezet: A LINQ API programozása
274
Navigálás egy memóriában lévő dokumentumban
(vagy xoocument) típushoz csak annyiból áll, hogy az Add() metódust meghív
juk, amely hozzáadja az adatot az elem/ dokumentum végéhez. Ennek alterna
tívájaként meghívha�uk az AddFirst() metódust, hogy az adatot az elem/do
kumentum elejéhez adja, illetve az AddAfterThis ()l AddBeforeThisO metódust,
hogy az adatot egy meghatározott helyre szúrja be.
A tartalom módosítása vagy törlése elég egyértelmű. Miután létrehoztunk
egy LINQ-lekérdezéskifejezést a manipulálni kívánt elem (vagy elemek) azo
nosítására, egyszerűen hívjuk meg a R ep lacecontentO metódust (módosítás
hoz) vagy a RemoveOIRemovecontentO metódust (adatok törléséhez). Egyszerű
példaként vizsgáljuk meg a következő kódot, amely hozzáad néhány új <Car>
elemet a bejövő XElement paraméterhez:
275
24. fejezet: A LINQAPI programozása
Összefoglalás
276
HUSZONÖTÖDIK FEJEZET
AWCF
Megjegyzés Jóllehet ez a fejezet kellő alapot nyújt a WCF-fejlesztéshez, a téma átfogó le
írását azonban lásd Chris Peiris és Dennis Mulder Pro WCF: Practical Microsoft SOA Imp/emen
tation című könyvében (Apress 2007).
A rendszert csak "házon belül" használják majd, vagy külső felhasználóknak is hoz
záférést kell biztosítanunk az alkalmazás funkcionalitásához?
25. fejezet: A WCF
Megjegyzés A WCF·nek (és az azt körülvevő technológiáknak) semmi köze a HTML·alapú we·
bes alkalmazások fejlesztéséhez. Igaz, hogy a webes alkalmazásokat is "elosztottnak" tekint·
hetjük olyan értelemben, hogy az adatforgalomban tipikusan két számítógép vesz részt, de a
WCF célja az, hogy számítógépekkel létesítsen kapcsolatot a távoli komponensek funkcionali·
tásának megosztásához - nem pedig HTML megjelenítése a böngészőben. (A 31. fejezet fog·
lalkozik a .NET platforrnon a webhelyek fejlesztésének vizsgálatávaLJ
A DCOM szerepe
278
Néhány elosztott API
279
25. fejezet: A WCF
Az MSMQ szerepe
280
Néhány elosztott API
A .NET-remoting szerepe
281
Z5. fejezet: A WCF
Az XML-webszolgáltatás szerepe
A korábban említett elosztott API-k egyike sem nyújtott sok támogatást (ha
egyáltalán nyújtott) ahhoz, hogy külső hívók agnosztikus módon hozzáférjenek
a program funkcionalitásához. Ha arra van szükségünk, hogy a távoli objek
tumok szolgáltatásait felajánljuk bármilyen operációs rendszernek vagy bár
milyen programozási modellnek, az XML-webszolgáltatások biztosítják eh
hez a legegyszerűbb utat.
A hagyományos böngészőalapú webes alkalmazásokkal ellentétben a
webszolgáltatásokkal egyszerűen felajánlhatjuk távoli komponensek funkci
onalitását szabványos webprotokollokon keresztül. A .NET kezdeti kiadása
óta a programozók kiváló támogatást kapnak XML-webszolgáltatások készí
téséhez és felhasználásához a system. web. servi ces névtéren keresztül. Tulaj
donképpen a teljes funkciójú webszolgáltatás készítése sokszor nem több,
mint a [webMethod] attribútum hozzárendelése minden olyan nyilvános me
tódushoz, amelyhez hozzáférést szeretnénk biztosítani Továbbá a Visual
Studio 2008 azt is lehetővé teszi, hogy egy (vagy két) gombnyomással távoli
webszolgáltatáshoz kapcsolódjunk.
A webszolgáltatások segítségével olyan .NET-szerelvényeket lehet fejlesz
teni, amelyek egyszerű HTTP-n keresztül elérhető típusokat tartalmaznak,
ráadásul a webszolgáltatás egyszerű XML-ként kódolja az adatait. Mivel a
webszolgáltatások nyílt ipari szabványokon alapulnak (HTTP, XML, SOAP
stb.), és nem védjeggyel rendelkező típusrendszereken vagy szabadalmazta
tott műveletformátumokon (mint a DCOM vagy a .NET-remoting esetében),
nagymértékű együttműködést és adatforgaimat tesznek lehetővé. A 25.1. áb
ra mutatja az XML-webszolgáltatások agnosztikus természetét.
Persze nincs tökéletes elosztott API. A webszolgáltatások egyik lehetséges
hátránya teljesítménybeli hiányosságuk (mivel HITP-t és XML-adatábrázolást
használnak), így nem igazán ideálisak házon belüli alkalmazásokhoz, ahol a
TCP-alapú protokoll és a bináris kódolás probléma nélkül használható lenne.
ZBZ
Néhány elosztott API
'!.NET....- .
HTIPésXML r-:-
ws � __. '
A
.
�
· · . Proxy
-
- ' (;) .
XML
rJava alkaknazés webszol-
N
U IX-on� HTIPésXML
gá Itatás
� ...
-
y
©
JaiJa (vagy .HET)"'
/.•
'
HTIPésXML
�
. . Proxy
�® .
- HTIPé
: XML
l . .,. � .... .._.._.. .
HTIPésXML +
� �
(l8tsidfllgaa . . . . . ..
� _. B.web-©
� Proxy
-
' �.
L....- -- ·· -···
·_ .':__ ..:..�---
_
.
Egy rövid példa kedvéért tételezzük fel, hogy a következő programrészt ké
szítettük el a Hellowebservice. asmx fájlban ( * . asmx a .NET-es XML webszol
gáltatás-fájlok alapértelmezett kiterjesztése). Ha készen vagyunk, mentsük a
C:\ HelloWebService könyvtárba.
283
25. fejezet: A WCF
284
Néhány elosztott API
Webszolgáltatási szabványok
285
25. fejezet: A WCF
A WCF szerepe
kiválasztását. Ezt még tovább bonyolí�a, hogy ezek közül több technológia szal
gáitatásai átfedik egymást (legfőképpen a tranzakciók és a biztonság területén).
Még ha a .NET-fejlesztő kiválasztotta is a feladathoz megfelelőnek tűnő
technológiát, az ilyen alkalmazás elkészítése, karbantartása és konfigurálása
a legenyhébb kifejezéssel is összetett. Minden API-nak megvan a maga prog
ramozási modellje, egyéni konfigurációs segédprogramjai és így tovább.
286
A WCF szerepe
Emiatt a .NET 3.0 előtt nehéz volt elosztott API-kat egyszerűen csatlakoz
tatni (plug and play) anélkül, hogy tekintélyes mennyiségű egyedi infra
struktúrát ne kellett volna létrehozni. Ha például .NET-remoting-API-kal ké
szí�ük a rendszerünket, és később úgy döntünk, hogy az XML-webszolgálta
tások megfelelőbbek lennének, újra kell írni a kódalapot
A WCF a .NET 3.0-ban bevezetett egy elosztott eszközrendszert, amely in
tegrálja ezeket a korábban független elosztott technológiákat egy áramvonalas
API-ban, amelyet elsősorban a system.serviceModel névtér képvisel. A WCF
révén a szolgáltatásokat a legkülönfélébb technikák segítségével elérhetővé le
het tenni a hívók számára. Ha például olyan házon belüli alkalmazást készí
tünk, ahol minden kapcsolódó számítógép Windows-alapú, többféle TCP pro
tokoll használata biztosítha�a a lehető legjobb teljesítményt. Ugyanezt a szol
gáltatást XML-webszolgáltatás-alapú protokollal elérhetővé tehe�ük úgy, hogy
külső hívók is birtokba vehessék a funkcióit a programozási nyelvtől vagy az
operációs rendszertől függetlenül.
Mivel a WCF lehetövé teszi a feladatnak megfelelő protokoll kiválasztását
(egy közös programozási modellel), elég könnyű lesz az elosztott alkalmazá
sunk alapjául szolgáló összeköttetéseket beállítani. Legtöbb esetben ezt a kli
ens/ szerver szaftver újraindítása vagy újratelepítése nélkül meg lehet tenni,
ugyanis a "piszkos" részleteket gyakran az alkalmazás konfigurációs fájljai
veszik át (úgy, mint a régebbi .NET-remoting-API-knál).
A WCF-funkciók áttekintése
287
25. fejezet: A WCF
288
A WCF szerepe
289
25. fejezet: A WCF
WCF: A lényeg
Az alapvető WCF-szerelvények
290
Az alapvető WCF-szerelvények
291
25. fejezet: A WCF
Ap p. con fi g fájlt is, ez pedig furcsának tűnhet, hiszen .NET *.dll fájlt készí
Megjegyzés A WCF Service Library projekt App. con fi g fájlja hasznos abból a szempontból
is, hogy megmutatja a WCF-hoszt-alkalmazás konfigurálásához szükséges alapbeállításokat
Igazából ennek a kódnak nagy részét bernásolhatjuk a saját hasztunk konfigurációs fájljába.
292
A Visual Studio WCF projektsablonok
Workflow
Visual (+•
_j]
Search
Other Project Typ�
Online Te...
Test Projects
�o------------------------··
A project for creating a WCF service class library (.dll} (.NET Framework 35)
Name: WdServicelibraryl
OK J[ Cancel
293
25. fejezet: A WCF
szükséges *.svc fájlt (az *.svc fájlokról a későbbiekben szálunk). Erről az oldal
ról nézve a webalapú WCF Service projekt egyszerűen időmegtakarítás, mivel az
IDE automatikusan elkészíti a szükséges IlS-infrastruktúrát.
NewW�bSite
�.....;- �
Templates:
�
'.!c# l� @l ,_l iEJ
ASP.NET ASP.NET EmptyWeb WCF Setvice ASP.NET
WebSite Web Service Site
� ReportsW,..
Sei!!rch
Online Te...
language �v
� ;=.
, ,.=I=
C#===�� �
OK ll Cancd
tünk:
294
A WCF-alkalmazás alapösszeállítása
.t WCF-amlgéllalésj
·.
l J
.
Praty_
. r· , ;:
.
l Konfigurációs állomány
l l Konfigurációs állomány l
25 .4. ábra: Egy tipikus WCF-alkalmazás szerkezetének áttekintése
295
25. fejezet: A WCF
A WCF ABC-je
• Cím: A szolgáltatás helye. A kódban ezt egy system. uri típus jelképezi,
az értéket azonban általában * .con fi g fájlok tárolják.
Az ABC rövidítés nem azt jelenti, hogy a fejlesztőnek először a címet, majd a
kötést és végül a szerződést kell definiálnia. A WCF-fejlesztő sokszor a szal
gáltatás szerződésének definiálásával kezd, majd megadja a címet és a köté
seket (de bármilyen sorrend jó, ha mindháromról gondoskodunk). Az első
WCF-alkalmazás elkészítése előtt nézzük meg részletesebben az ABC-ket.
296
A WCF ABC-je
A WCF -szerződések
8-�o System.Runtime.Serialization G
· so System.Runtime.Serialozatton
i±l·'1t CollectionDataContractAttribute
$---Vit ContractNamespaceAttribute
$---'1$ D�taContractAttribute
$··'-is DataContractSerializer
@ -'1:: OataMemberAttribute
@·-"it EnumMemberAttribute
$ 'it ExportOptions
�--"it ExtensionDataObject
ffi- ....o IOataContractSurrogate
$--·.,..() IExtensibleOataObject
tfj--""ft ImportOptions
@--� lnvalidDataContractException
� ·"t KnownTypeAttribute
&l '1$ NetDataContractSerializer
$---� XmiObjectSerializer
ffi---<1:$ XmiSerializableServices
@ ·'it XsdDataContractExporter
ffi-'it XsdDataContractlmporter
rtJ -- {} System.Runtime.Seríalization.Configuration G
25. 5. ábra: A System.Runtime.Serialization számos attribútumai definiál WCF-adatszerződések
készítése során
297
25. fejezet: A WCF
A WCF -kötések
298
A WCF ABC-je
HITP-alapú kötések
299
25. fejezet: A WCF
TCP-alapú kötések
300
A WCF ABC-je
MSMQ-alapú kötések
301
25. fejezet: A WCF
pusokat használnak.
A WCF-cimek
például a 80-as.
302
A WCF ABC-je
scheme://<MachineName>[:Port]/Path
http://localhost:8080/MyWCFService
Megjegyzés Ha SSL-t (Secure Sockets Layer) használunk, csak írjuk át a http-t https-re.
net.tcp://localhost:8080/MyWCFService
net.msmq://localhost/private$/MyPrivateQ
net.pipe://localhost/MyWCFService
Bár lehet, hogy egyetlen WCF-szolgáltatás csak egy címet tesz elérhetővé
(egyetlen kötésre alapozva), lehetőség van egyedi címek gyűjteményének a
definiálására is (különböző kötésekkel). Ezt több <endpoint> elem definiálá
sával tehe�ük meg a *.con fig fájlban. Itt tetszőleges számú ABC-t megadha
tunk ugyanahhoz a szolgáltatáshoz. Ez a megközelítés hasznos lehet, ha meg
akarjuk engedni a hívóknak, hogy kiválaszthassák a használni kívánt proto
kollt, amikor a szolgáltatással kommunikálnak.
303
25. fejezet: A WCF
using system;
using system.collections.Generic;
using System.Linq;
using System.Text;
ll A fő WCF-névtér.
using System.ServiceModel;
namespace MagicEightBallserviceLib
{
public class MagicEightBallservice
{
}
}
304
WCF-szolgáltatás készítése
[Servicecontract]
public interface IEightBall
{
ll Kérdezz, hogy választ kapj!
[operationcontract]
string obtainAnswerToQuestion(string userQuestion);
}
305
25. fejezet: A WCF
A [ServiceContract] attribútum
[Servicecontract(Namespace = "http://Intertech.com")]
public interface IEightBall
{
306
WCF-szolgáltatás készítése
... ,·.:-'•
!...•'_:: �
Az [OperationContract] attribútum
307
25. fejezet: A WCF
ll csak illusztráció,
//az aktuális példában nem szerepel.
[Servicecontract(Namespace "http://Intertech.com")]
=
A WCF-szolgáltatás hasztolása
308
A WCF-szolgáltatás hasztolása
using System;
using system.collections.Generic;
using system.Linq;
using System.Text;
using system.serviceModel;
using MagicEightBallserviceLib;
namespace MagicEightBallserviceHost
{
class Program
{
static void Main(string[] args)
{
Console.writeLine("***** Console Based WCF Host *****");
console.ReadLine();
}
}
}
309
25. fejezet: A WCF
3. Győződjünk meg róla, hogy a hoszt még fut azért, hogy kiszolgálja a
sítsük a*. config fájlt, és adjunk meg egy végpontot (a 8080-as porton keresztül
érhető el), amelyet ezen a haszton teszünk elérhetővé:
310
A WCF-szolgáltatás hasztolása
new serviceHostCtypeofCMagicEightBallservice)))
{
ll Megnyitja a hosztot, és figyelni kezdi a bejövő üzeneteket.
serviceHost.OpenC);
i! C:\Windows\system32\cmd.exe
a
i
�
new serviceHostCtypeofCMagicEightBallservice),
new uri[]{new
uriC'' http:lllocalhost:8080IMagicEightBallservice")}))
{
311
25. fejezet: A WCF
A hoszt *.config fájlok létrehozásának egyik (kissé zavaró) vonása az, hogy
az XML-leírókat többféleképpen összeállíthatjuk a programban levő forrás
kód mennyiségétől függően (ahogyan éppen az előbb láttuk az opcionális
URI-tömb esetében). Hogy megmutassuk a *.config fájlok létrehozásának
egy másik módját, gondoljuk át a következő újrafeldolgozást:
312
A WCF-szolgáltatás hasztolása
Ebben az esetben az <end po i nt:> elem address attribútuma még üres, és füg
getlenül attól, hogy a serviceHost: létrehozásakor a kódban nem adjuk meg
az URI-objektumok tömbjét, az alkalmazás ugyanúgy fut, rnint az előbb,
mert az értéket a baseAddresses hatóköréből veszi. Az alapcím tárolásának
előnye a <host:> <baseAddresses> területén az, hogy a*. confi g fájlnak (mint a
MEX, lásd később) ismernie kell a szaigáitatás végpontjának címét is. Így
ahelyett, hogy egyetlen *.confi g fájlba kellene másolni és abban küldeni a
címértékeket, a bemutatott módon elkülöníthetjük az egyetlen értéket.
A ServiceHost tipus
313
25. fejezet: A WCF
console.WriteLine("Name: {O}",
host.Description.ConfigurationName);
console.writeline("Port: {O}",
host.BaseAddresses[O].Port);
console.writeLine("LocalPath: {O}",
host.BaseAddresses[O].LocalPath);
console.writeline("uri: {O}",
host.BaseAddresses[O].Absoluteuri);
Console.WriteLine("scheme: {O}",
host.BaseAddresses[O].scheme);
console. writeLine("**********************");
Console.WriteLine();
}
314
A WCF-szolgáltatás hasztolása
Tételezzük fel, hogy a hoszt megnyitása után ezt az új metódust lúvjuk a Main()
metódusból:
<system.serviceModel>
<behaviors>
<lbehaviors>
<client>
<lclient>
<commonBehaviors>
<lcommonBehaviors>
<diagnostics>
<ldiagnostics>
<serviceHostingEnvironment>
<lserviceHostingEnvironment>
315
25. fejezet: A WCF
<comcontracts>
</comcontracts>
<services>
</services>
<bindings>
</bindings>
</system.serviceModel>
commonBehaviors Ezt az elemet csak a mach ine. con fig fájlban lehet al
kalmazni. Segítségével lehet beállítani minden olyan
viselkedést, amelyet az egyes WCF-szolgáltatások egy
adott gépen használnak.
316
A WCF-szolgáltatás hasztolása
317
25. fejezet: A WCF
Nézzük meg a következő módosított hoszt *.con fig fájlt, amely egyedi
<behavior> elemet definiál (a neve EightBallMEXBehavior) , amely a <service>
definícióban szereplő behaviorconfiguration attribútum révén kapcsolódik a
szolgáltatáshoz:
http://localhost:8080/MagicEightBallservice
318
A WCF-szolgáltatás hosztolása
To test this service, you will need to create a dient and use it to call the service. You can do this using the
svcutil.exe tool from the command line with the follawing syntax:
l
l
�l
svcutil.exe http://localbosc:B080/MagicEigbtBallService?wsdl
This will generate a configuration file and a code file that contains the client class. Add the two files to your client !
application and use the generated client class to call the Service. for example:
i
C#
clas:s Test
{
Eiqht3a11Cl1e�t client = new Eighc3al1Client();
u
ll üse the 'client' variable �o call operations o� �he service.
319
25. fejezet: A WCF
Most, hogy a hoszt készen áll, már csak a szaftver egy részét kell elkészíte
nünk, hogy a WCF-szolgáltatástípussal kommunikáljon. Bár választhatnánk
a szükséges infrastruktúra manuális felépítését (megvalósítható, de munka
igényes feladat), a .NET Framework 3.5 SDK több módszert kínál ügyfélolda
li proxy gyors generálására. Először hozzunk létre új parancssori alkalmazást
MagicEightBallServiceClient névvel.
svcutil http://localhost:8080/MagicEightBallservice
/out:myProxy.cs /config:app.config
[System.Diagnostics.DebuggerstepThroughAttribute()]
[System.CodeDom.compiler.GeneratedcodeAttribute(
"System.serviceModel", "3.0.0.0")]
public partial class EightBallclient :
System.serviceModel.clientBase<IEightBall>, IEightBall
{
320
WCF-ügyfélalkalmazás készítése
<client>
<endpoint
address="http://localhost:8080/MagicEightBallservice"
binding="basicHttpBinding"
bindingconfiguration="BasicHttpBinding_IEightBall"
contract="ServiceReference.IEightBall"
name="BasicHttpBinding_IEightBall" />
</client>
321
25. fejezet: A WCF
T o see a lirt of available services on a specific server, enter a service URL and click Go. To browse for available
services. click Oiscover.
Address:
http://localhost8080/MagicEightBa11Service
• � ll Discover l ·l
Services: Operations-:
Namespace;
ServiceRe:fen�nce
[ Advanced... J c..._ oK _
__
_,ll Cancel
ll Aproxy helye.
using MagicEightBallserviceclient.ServiceReference;
namespace MagicEightBallserviceclient
{
class Program
{
static void Main(string[] args)
{
Console.writeLine("***** Ask the Magic 8 Ball *****\n");
using (EightBallclient ball = new EightBallclient())
{
console.write("Your question: ");
string question = console.ReadLine();
string answer =
ball.obtainAnswerToQuestion(question);
322
WCF-ügyfélalkalmazás készítése
tli C:\Windows\system32\cmd.exe
a
l
•
323
25. fejezet:· A WCF
binding="netTcpBinding"
contract="MagicEightBallserviceLib.IEightBall"/>
<host>
<baseAddresses>
<add baseAddress
"net.tcp://localhost:8080/MagicEightBallservice"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
324
A WCF Service Library projektsablon használata
325
25. fejezet: A WCF
namespace MathserviceLibrary
{
[Servicecontract(Namespace="www.Intertech.com")]
public interface IBasicMath
{
[Operationcontract]
int Add(int x, int y);
}
}
Módosítsuk a Servicel.cs fájl nevét Math service. cs-re, majd (újra) töröljük ki
az összes példakódot a MathserviceL i brary névtérből, és a következőképpen
implementáljuk a szolgáltatássszerződésünket:
namespace MathserviceLibrary
{
public class Mathservice : IBasicMath
{
public int Add(int x, int y)
{
ll Hogy hosszú kérést szimuláljunk.
System.Threading.Thread.Sleep(5000);
return x + y;
}
}
}
326
A WCF Service Library projektsablon használata
wcftestclient http://localhost:8080/MagicEightBallservice
8 �MySeMco�. =l�
--
8··� rttp :/Aoc.t>Ost :8080/Mah$eMco/mex
,.. ·-·
-- -· 1
Response �
Nome Va!ue Type
l. fettm) 26 System.lrt32
327
25. fejezet: A WCF
T"
Solution Explorer @l
����ri!I.G '-�<--
�--
l
� MathServicelibrary l
ffi. � Properties
i
ffi-·· 3I R�ferences
' . íj} . .. . .
l
. . � 'iB.:M.':h [j' l Open
'!,) MathServi l
il
·· OpenWith ...
- -_J._________ -- -· . . -
l{
�l
l Exdude From Project
Cut
ll
l
- l
l
� Copy
l XI
Delete
Rename
l
�i Properties
j� c\my books\c# and the .net platform 4th od\code\chapter �thservice\mathservi<elibrary\app:config - Micros... =+sliiii3iill
File Help
Sincing
ló... ..
Delete Endpoint
·""" ..":.. ��
,.
l Wllnt to
This setting lets you choose the type of the hinding you use for this endpoint
You can use one of the system-denned h'CF bindi119 types. or register your <MTI in the
<bindingExtensioos> section.
ll
l
Create � Ne·,o,· Service...
l J
25.14. ábra: A WCF Service Configuration Editor használata
328
WCF-szolgáltatás hasztolása Windows-szolgáltatásként
Megjegyzés Az svcconfi gEdi tor. exe eszközzel akkor is szerkeszthetünk (vagy létrehozha
tunk) konfigurációs fájlokat, ha nem választunk kezdeti WCF Service Library projektet. A Visual
Studio 2008 parancssorából indítsuk el az eszközt, és a File>Open menüponttal töltsünk be szer·
kesztésre egy létező *.con fi g fájlt.
Megjegyzés Bár igaz, hogy az asztali Windows-alkalmazásnak nem kell feltétlenül mutatnia
a főablakot, egy tipikus *.exe-nek szüksége van felhasználói beavatkozásra a végrehajtható
fájl betöltéséhez. Egy Windows-szolgáltatás (lásd a következő részben) úgy is konfigurálható,
hogy akkor is fusson, ha pillanatnyilag egy felhasználó sem jelentkezett be a munkaállomásra.
329
25. fejezet: A WCF
Search
Online Te...
Name: MathWindowsServict:Hort
location: C:\My Books\C# and the .NET Platform 4th ed\Codc\Chapter 26\MathService • l Browse...
OK ll Cancel
330
WCF-szolgáltatás hasztolása Windows-szolgáltatásként
public Mathwinservice()
{
Initializecomponent();
}
ll Hoszt létrehozása.
myHost = new serviceHost(typeof(Mathservice));
ll ABC-k a kódban!
uri address =
new uri("http:/llocalhost:8080/MathserviceLibrary");
WSHttpBinding binding = new WSHttpBinding();
Type contract = typeof(IBasicMath);
ll Végpont hozzáadása.
myHost.AddserviceEndpoint(contract, binding, address);
ll Hoszt megnyitása.
myHost.open();
}
Bár semmi nem gátol meg abban, hogy konfigurációs fájlt használjunk Win
dows szolgáltatási hoszt készítésekor a WCF-szolgáltatáshoz, a *.config fájl
helyett programozottan hozzuk létre a végpontot az uri, WSHttpBinding és
Type osztályok segítségéveL Ha készen van az ABC minden összetevője, a
331
25. fejezet: A WCF
A MEX engedélyezése
Windows-szolgáltatástelepitő létrehozása
332
WCF-szolgáltatás hasztolása Windows-szolgáltatásként
Moi!lJI'or&V;.;O.�-:;gy-Mot(lw�g)'-M.thWonSetvkr.cs(DesignJL �x
--,1
ll
ll
l
l,
1
,---,---
fi] ! View Code
. 1---
,,
ii
. ��Up--
1 � \1 �Lon• ---
llii To add components to your class, drag !hem fr( kons
li
he Properties window to set their properties_ To ·l
enj ! Show�ge�� re to switch to code view.
1,l'
create methods and ev
q ! ---Addlnrtaller
�
il
l! ll -BI' ;;;�;-;;;�----�
il ll
ll l _ji l
A Windows-szctgáltatás telepítése
installutil MathwindowsserviceHost.exe
333
25. fejezet: A WCF
.
Math Order Service Name D�cription Status Startup Type log On As
?!QQ the service ;-' KtmRm for Oistrib... Coordinates... Started Automatic (D... NetworkS ...
ClM.rth Order Strw:e Thas IS the h... Started Autom.1bc local Syste.
(Ó6 Message Queuing Providesa ... Started Automatic NetworkS...
This is the host for the -:·� Microsoft .NET Fr... Microsoft .... Manual local Syste...
334
Szolgáltatás aszinkron hívása
To see a list of available seMe5 on a specitic se.rver, enter a service URL and cikk Go. To browse for available
services, click Oiscover.
Addres�
Names�
pa __
c e_______________ __ _
ServiceReference
[.������;::1 l OK JI Cancel
25. 18. ábra: Referencia beállítása az ourMathService-re
0 .. Q mscorlib
o .a system
[J·OSystem.Core
D ·OSystem.Data
D •O System.Data.Datas.tExtensions
O •OSystem.Xml
[J·ClSystem.Xmi.Linq
Compatibility
Add a WebReference instead of a ServiceReference. This will g�e.rate code bas� on .NET Frame:work 2.0
Web Services technology.
Add WebRefe<ence...
�� Cancel
335
25. fejezet: A WCF
using System;
using Mathclient.ServiceReference;
using system.Threading;
namespace Mathclient
{
class Program
{
static void Main(string[] args)
{
console. Writeline("***'"� The Async Math client *;«'*'''\n");
{
console.writeLine("2 + 5 {O}", proxy.EndAdd(ar));
}, null);
while (!result.rscompleted)
{
Thread.sleep(200);
Console.writeLine("client work ing ...");
}
}
Console.ReadLine();
}
}
}
336
WCF-adatszerződések tervezése
337
25. fejezet: A WCF
NewWebSite
,3 '� c� ,it �
ASP.NET ASP.NET EmptyWeb WCFService ASP.NET
Web Sit!! Web Service: Site: Re:portsW...
�
MyTemplates------.----�----·--· --- ··
Search
Online Te
...
location:
lHTTP •l http://localhost/AutolotWCF�rvice: • l Browse.. l
language: �V� os=ua=I C#=== ====�. �
OK ll Cancel l
[Servicecontract]
public interface IAutoLotService
{
[Operationcontract]
void InsertCar(int id, string make, string color, string petname);
[Operationcontract]
void Insertcar(InventoryRecord car);
338
WCF-adatszerződések tervezése
[Operationcontract]
InventoryRecord[] Getinventory();
}
[Datacontract]
public class InventoryRecord
{
[DataMember]
public int ro;
[DataMember]
public string Make;
[DataMember J
public string color;
[DataMember]
public string PetName;
}
339
25. fejezet: A WCF
[Operationcontract(Name= "InsertcarwithDetails")]
void Insertcar(InventoryRecord car);
}
Szolgáltatásszerződés implementálása
using AutoLotconnectedLayer;
using system.Data;
340
WCF-adatszerződések tervezése
*
A .svc fájl szerepe
341
25. fejezet: A WCF
<system.serviceModel>
<services>
<service name="AutoLotService"
behaviorconfiguration="ServiceBehavior">
<endpoint address="" binding="wsHttpBinding"
contract="IAutoLotservice"/>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailinFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
A szolgáltatás tesztelése
wcfTestclient http://localhost/AutoLotWCFService/Service.svc
342
Összefoglalás
8
Fil� Help
i!l My SoMce Project• � c..wt��=�t.Det.isc�--
�--;:: l Getlnv...ooy l
=ll
�-
2�;;,o==olaiWCFs.Mce
.. .,...� l
.._ n..rtCaoWihDetaioO N""" v.-", T",.
.. �
t} Cori;gfie
Reoponoe �
N""" v.-", T",.
8 ...'-"1) lef9h•13 kw...ooyRe<:oolO
E!IOJ
Ü"
. lnvertoryRecord
Color "Pn<"' SyotemSimg
u"
Syotem.kt32
·Make "BMW" SyotemSimg
PetName "Sidd" SyotemSimg
a 111 kwmooyRe<:ool
-- Color "Red" SyotemSimg
:..•o S,.tem.kt32
--· 'VW" SyotemSimg
· PetName "2lppy "
Syotem.Simg
B !21 kw...ooyRe<:ool
.. "Eladt"
.
Color
·
Syotem.Simg
·ID Syotem.kt32
·
-·Make "Ford" SyotemSimg
PetName "Mel" Syotem.Simg
s 131 lnv...ooyRe<:ool �
- Color "Siver" SyotemStmg
--------
.�
l (i. lll
' JlL=�r�Il --=
=
· "--- ----- ·-·
�- �
- �� --���-�-
· ---
JI
S.rvice invocatioo completed.
Összefogla l ás
343
25. fejezet: A WCF
344
HUSZONHATODIK FEJEZET
A Windows Workflow
Foundation - Bevezetés
Bármelyik életszerű alkalmazás képes kell, hogy legyen különböző üzleti fo
lyamatok modellezésére. Tulajdonképpen az üzleti folyamatok azoknak a felada
toknak a csopor�a, amelyek logikailag kollektív egészként működnek. Tételez
zük fel például, hogy olyan alkalmazást készítünk, amely lehetővé teszi a fel
használó számára, hogy egy gépjárművet online megvásároljon. Arnikor a fel-
26. fejezet: A Windows Workflow Foundation - Bevezetés
objektumot, maga a forráskód nagyon messze áll egy olyan élethű dokurnen
tumtól, amely a tevékenység teljes folyamatát kifejti. Noha a fejlesztőcsapat lét
rehozhat külső dokurnentációt és munkafolyamat-ábrákat, ismét beleütközünk
ugyanannak a folyamatnak a többszörös megjelenítési problémájába.
346
A WF építőkockái
A WF szerepe
A WF építőkockái
347
26. fejezet: A Windows Workflow Foundation - Bevezetés
orldlowl.a (Design) TX
Sequentia! Workflow
�
l
Drop Activities to E'
crea.te a
Sequential
Workflow
+
[!]
A WF futtatókörnyezete
348
A WF építőkockái
A WF alapvető szolgáltatásai
f+�-. :�:
. �ú"
[.•>!'.'···'
Rögzítés Ez a szolgáltatás lehetővé teszi WF-példány külső forrásba
(pl. adatbázisba) történő mentését. Ez akkor nagyon hasz
nos, ha egy hosszú futásidejű üzleti folyamat hosszú ideig
tétlen.
349
26. fejezet: A Windows Workflow Foundation - Bevezetés
A WF célja az, hogy deklaratív módon tegye lehetővé egy üzleti folyamat model
lezését, amelyet majd a WF-futtatómotor hajt végre. A WF tekintetében egy üzle
ti folyamat tetszőleges számú tevékenységbó1 áll. A WF-tevékenység a teljes fo
lyamat egy elemi "lépése". Amikor egy új WF-alkalmazást hozunk létre a Visual
Studio 2008-cal, az eszköztárban egy Windows Workflow területet találunk,
amely a beépített tevékenységek ikonjait tartalmazza (lásd a 26.2. ábrát).
Toolbox
_8 WondowsiN�v3.0
� Pointer
Cll CaiiExternaiMethod
$;J Code
·:,. Compensate
� CompensatableSequence
@ ConditionedActivityGroup
Q Delay
:l!J EventOriven
[E EventHandlingScope
,P FaultHandJer
ctJ HandleExternaiEvent
}� IfEise
(!t InvokeWebService
� lnvokeWorlcflow
� listen
�Server Explo;��)l;' Toolbox j
350
A WF építőkockái
Megjegyzés A Visual Studio 2008 a tevékenységek eszköztárát .NET 3.0-s és .NET 3.5-ös te
vékenységkategóriákra osztja. A Windows Workflow csomópont alatti tevékenységek lehetövé
teszik, hogy együttmüködjünk a Windows Communication Foundtaion (WCF-) szolgáltatásokkal.
A .NET 3.5 több olyan beépített tevékenységet nyújt, amelyekkel üzleti fo
lyamatainkat modellezhetjük, ezek mindegyikét valós típusokra képezhetjük
le a system.workflow.Activities névtérben, és így megjelenítésük és irányítá
suk kóddal történik. A fejezetben több ilyen a beépített tevékenységeket al
kalmazunk. A 26.2. táblázat a kapcsolódó működés szerint csoportosítva is
merteti néhány hasznos tevékenység magas szintű működését.
351
26. fejezet: A Windows Workflow Foundation - Bevezetés
Bár nagyon sok, minden WF-alkalmazáshoz biztos alapot nyújtó beépített te
vékenység létezik már most is, lehetőségünk van olyan újabb egyedi tevé
kenységek létrehozására is, amelyek zökkenőmentesen illeszkednek a Visual
Studio integrált fejlesztői környezetébe és a WF-futtatómotorba.
Szekvenciális és állapotgép-munkafolyamatok
352
A WF építőkockái
Sequentia! Wortcflow
"
�
l
13-lfCllrlslnStock
�·�
l
l l
HaveCar DontH•veCar
!ID !ID
l
Ci-· HaveCustomerEmail
.�
l • l
HaveErneit DootH&•.<eEmail
(g� )
!ID IID
1
l
[g�) rr( Jt
--·
• ! .
hlU>JEmr
L
l ' l
t
I �;
[!l
�·
� �
Ell
26. 3. ábra: A szekvenciális munkafolyamatok egyértelmű kezdő- és végponttal rendelkeznek
353
26. fejezet: A Windows Workflow Foundation - Bevezetés
�/SampleWorkflow.cs [ Design]•je...__
.. _
4J OnOrderCreate<l +-
ü Order()penSiale ll
i;l OnOrderUpdate<l o--W
-1 ------ ---.,
:l±l OnOrderProcesse<l -----
l
U Orderf'rocessedStale
i;l On0rderUpdate<l2 ..._
:4J OnOrderShippe<l +
i;J OnOrderCancele<l
[lilor�
354
WF-szerelvények, -névterek és -projektek
WF-szerelvények, -névterek és
-projektek
355
26. fejezet: A Windows Workflow Foundation - Bevezetés
A N ET 3.5 WF-támogatása
.
WCF-integrációt.
Megjegyzés Amikor WF-képes Visual Studio 2008-as projektet készítünk, az IDE minden egyes
Windows Workflow Foundation szerelvényhez automatikusan beállítja a referenciákat.
New Proj.ct
Tt:mplates:
Name: WorkflowProje:ctl
OK ll Cancol
356
WF-szerelvények, -névterek és -projektek
A munkafolyamat menete
357
26. fejezet: A Windows Workflow Foundation - Bevezetés
Egyszerű munkafolyamat-alkalmazás
létrehozása
Megjegyzés A WF-fejlesztés egyik elve, hogy a munkafolyamatok önálló elemi részek. Ennek
a ténynek köszönhetően a munkafolyamat-osztálytípusok explicit módon lezártak, így megaka
dályozzuk, hogy a leszármazott típusok számára szülőosztályként működjenek.
358
Egyszerű munkafolyamat-alkalmazás létrehozása
Sequentia! Workflow
�
o--· ···· L. -
\ •::<' Showlnstructions
i """ Activity
' - ·····
m j' l·
L_�
�tn!
-�
26. 6. ábra: Egtj (nem egészen tökéletes) Code tevékenység
359
26. fejezet: A Windows Workflow Foundation - Bevezetés
A tervező éppen hibát jelez, amelyet a Code tevékenység tetején található piros
felkiáltójelre kattintva nézhetünk meg. A hiba arról tájékoztat, hogy az Exe
cutecode értéket nem adtuk meg, pedig ez egy kötelező lépés minden Code te
vékenység típushoz. Az Executecode adja meg annak a metódusnak a nevét,
amelyet a rendszer végrehajt, amikor a feladat a WF-futtatómotorral találkozik.
A Properties ablakban az Executecode értékét állítsuk a showrnstructions
metódusra. Amikor megnyomjuk az Enter billentyüt, az IDE a következő kód
csonkkal egészíti az elsődleges * . cs fájlt:
-::-.':*"
console.writel ine C'********')':****************-.'r************ );
console.writeLine("**** welcome to the first WF Example ****");
"
Console.WriteLine(''*****************************************\n );
console.writeLine("I will now ask for your name and validate
the data... \n");
Console.Foregroundcolor = previouscolor;
}
360
Egyszerű munkafolyamat-alkalmazás létrehozása
361
26. fejezet: A Windows Workflow Foundation - Bevezetés
Properties
l AskforNameloopActivity System.Workflow.Activities.WhileActivity • [
! �:�[Dl ::J l
(Name) AskforNameloopActivity l
El Cond�1on Code Condition
El
Condition
Description
O GetAndValidateUmName
l
Enabled True
Condition
Please specify the When condition which causes the content activities of while
activity to e<e<ute.
362
Egyszerű munkafolyamat-alkalmazás létrehozása
Sequentia! Workflow
@
l
'�
""
Showlnstructions
Activíty
i
t
S J,5,kFcr'l.,tr:�!..ccpt..c�l·il�;
j�l
NameNo�!
�· ············· ···· ·· ·······
t ;;$
! r
!l
tiVIly
..
l
s
363
26. fejezet: A Windows Workflow Foundation - Bevezetés
364
A WF-motor hosztolási kódja
workflowRuntime.createworkflow(
typeof(userDataWFApp.Processusernameworkflow));
instance.start();
waitHandle.waitone();
}
}
bejövő paramétertípussal).
365
26. fejezet: A Windows Workflow Foundation - Bevezetés
elemet, amely két adatelemet tartalmaz. Az első elem sztring, amely a túl hosszú
név esetében megjelenített hibaüzenetet muta�a, a második elem numerikus vál
tozó, amelyet a felhasználónév maximális hosszának meghatározására haszná
lunk. Regisztráljuk a paramétereket a WF-futtatómotorban, ehhez második pa
raméterként adjuk át a oictionary objektumunkat a createworkflow() metódus
nak. A releváns módosítások a következők:
workflowRuntime.Createworkflow(
typeof(useroataWFApp.Processusernameworkflow), parameters);
instance.Start();
waitHandle.waitOne();
}
366
A WF-motor hosztolási kódja
367
26. fejezet: A Windows Workflow Foundation - Bevezetés
Webszolgáltatások hivása a
munkafolyamatunkban
Megjegyzés Mivel a WCF a preferált API a szotgáttatások tétrehozásánát, így nem részletez
zük az XML-webszolgáltatások létrehozását (a 25. fejezet érinti a témát); ezért az általunk itt
meghívott webszolgáltatások szándékosan egyszerűek.
368
Webszolgáltatások hívása a munkafolyamatunkban
..,.,
Add New Web Site �'
A Web site for creating XML Web servic6 (.NET Framework 35)
locatiore lHTTP
•l http,//localhost/MathWebService ��-------:; l Browse...
Language: [Visual(# - ·l
�� Cancel
[Webservice(Namespace "http://intertech.com/")]
=
[webserviceBinding(ConformsTo wsiProfiles.BasicProfilel_l)] =
return O;
else
return x l y;
}
}
369
26. fejezet: A Windows Workflow Foundation - Bevezetés
o Add
• Divide
• Multioly
• Subtract
A WF -webszolgáltatás-fogyasztó létrehozása
370
Webszolgáltatások hívása a munkafolyamatunkban
public MathWF()
{
Initializecomponent();
val adjunk hozzá egy új GetNumerical Input nevű code tevékenységet, amely a
GetNumbrnput() nevű metódusra képzünk le. Ebben a metódusban a felhasz
}
}
371
26. fejezet: A Windows Workflow Foundation - Bevezetés
switch (option.ToUpper())
{
case "A":
Operatien= Mathoperation.Add;
break;
case "s":
operatien= Mathoperation.subtract;
break;
case "M":
Operatien= Mathoperation.Multiply;
break;
case "D":
Operatien= Mathoperation.Divide;
break;
default:
numericalap = Mathoperation.Add;
break;
}
}
372
Webszolgáltatások hívása a munkafolyamatunkban
t:his.Operat:ion == Mat:hoperat:ion.Add
,wF.a (DesigAJ" • x
Sequentia! Wor1<flow
@
l
(g�u�)
:t
(g�� +
"
B ifEiseMathOpActivity
...
o o+ o r-�------t-----------------,
AddBranch SubtractBranch MultiplyBranch Divid�Branch
t t t l__ , t
______ ____ _______ j
T
C!l
<i
�
<i
26.13. ábra: Egy többelágazásos IfElse tevékenység
373
26. fejezet: A Windows Workflow Foundation - Bevezetés
Condition:
this.Operation == WFMathCiiont.MathOp..ration j
��o;f�'·!·!!H····;]
Divide O
-:�Equals
l óQOM-'
Solution Explorer
eJWF�t
$- � Prop..rties
ffi... 1:.1 References
B- eiD MathWF.cs
J L:\r.1 � IHffltAMfd
"•r.cs
..
L. . Program.cs
26.15. ábra: A *.rules fájl tartalmaz minden deklaratív szabályt, amelyet a WF számára létrehoztunk
Ha megnyitnánk ezt a fájlt, rengeteg <Ru l eExpressi oneondi ti on> elemet talál
nánk benne, amelyek az általunk létrehozott feltételeket írják le.
374
Webszolgáltatások hívása a munkafolyamatunkban
AddWeb�e��
Navigate to a web service URL and click Add Reference to add ali the available services.
0Back ojlil � �
URL: : http://localhost/MathWebService/Service.asmx TJ C]Go
-Service
The following operations a re supported. For a formal
definition, please review the Service Description.
• Add
• Divide
Web rd�ence name
• Multiply
localhost
• Subtract
Add Ref«ence
; '
375
26. fejezet: A Windows Workflow Foundation - Bevezetés
Properties íl
invokeWebServiceActivityl System.Workflow.ActivitiosJnvokeWebSe!vic •i
��:!!!JI@!] ;r l ':J
(Name) invokeWebServiceActivityl
BI@Mfflf!iil@Mi ActMty:::MathWF, Path=R�utt Q
Name MiothWF
Path Resuli
Description
Enabled True
Jnvoked G
lnvoking �
MothodName Add
ProxyCiass WFMathCient.Joa�Mst.MiothService
l Sossionld
URL http:/
/loQihost/MiothWebService/Service.-nx
Bx � Activity=MathWF, Path= firstNumber
Name MiothWF
l Path F'
ontHumber
By O Activi(y=MathWF, Path=SecondNumber
Name MiothWF
Path SecondNumber
376
Webszolgáltatások hívása a munkafolyamatunkban
,thWF.cs [Oe5igf>JatiiiP, YX
Sequentia! Worl<flow
[g�Nu��J
+
(g�� J +
...
8 ifEiseMllthOpActivity
!!ll
l
Qu -- *---- ---
i(g�.��� ]i
. --- ··--r--- ---�
[!] irJI
�
(ii
377
26. fejezet: A Windows Workflow Foundation - Bevezetés
namespace MathserviceLibrary
{
[Servicecontract(Namespace "www.intertech.com")]
public interface IBasicMath
{
[Operationcontract]
int Add(int x, int y);
}
}
http://localhost:8080/Mathservice
To see a list of available services on a specitic server, enter a service URL and cliclc. Go. To browse for available
services. dick Discover.
Address:
http://localhost8080/MathService
Services: Operations:
B-0 il MathService
L� IIIll!l.llD
Narnespace:
ServkeReference
l Advanced-. j oK
.__ _ _
_ _.II Cancel
378
Webszolgáltatások hívása a munkafolyamatunkban
TypeName WFMathCiíe:nt.5e:rviceRderenc�JBasicMath
00--..Q System.Servic�odel
OK l[ Cancet
379
26. fejezet: A Windows Workflow Foundation - Bevezetés
<client>
<endpoint address="http://localhost:8080/MathServiceLibrary"
binding="wsHttpBinding"
bindingconfiguration="WSHttpBinding_IBasicMath"
contract="WFMathclient.ServiceReference.IBasicMath"
name="WSHttpBinding_IBasicMath"
>
<identity>
<servicePrincipalName value=
"host/Interuber.intertech-inc.com" />
</identity>
</endpoint>
</client>
t§ WFMathCiient.ServiceReferenceJBasicMath
--
c. �:� Ad� � -� ��-� --=�-:- ��--- .. ==�=-�: ___ .. _ ·=--·-= -� -_ ..
Name Dirertion
----- __ T�--- ·· ·---- --- --------- ...
ln!32 ln
y lnt32 ln
Ol( ll Cancel
380
Webszolgáltatások hívása a munkafolyamatunkban
Properties
WCFSendAddActivity System.Worlcflow.Activities.SendActivity
, �l' [f]II!J ., ! !:
(Name) WCFSendAddActivity
GJ (ReturnValue) ll Activity=MathWF, Path=Result
AfterResponse o l
BeforeSend o
�
i
El ChanneiToken - WSHttpBincling_I�M.ith
El
l l
EndpointName WSHttpBinding_I�M.ith
OwnerActivityName WCFSendAddActivity
CustomAddress l)
li
l
Description
1, Enabled Tru�
ServiceOperationlnfo WF�hOient.SenriceReferenceJ�M.ith.Add l
Glx O Activity=MathWF, Path=FirstNumber
O Activity=MathWF. Path=SecondNumbor
iGJ y
Generate Handlers Promote Bindable Properties Bind Prcrerty 'Name' ... Show activities with
same ooe@tion Show activities with same contract
!
ChonneiToken
l Represents the channel that will be usedto send the message.
381
26. fejezet: A Windows Workflow Foundation - Bevezetés
Újrafelhasználható WF-kódkönytár
létrehozása
382
Újrafelhasználható WF-kódkönytár létrehozása
Nam� CreclitCheclcWFlib
OK J[ Cancel
namespace creditcheckWFLib
{
383
26. fejezet: A Windows Workflow Foundation - Bevezetés
Hitelellenőrzés végrehajtása
folyamatnak:
384
Újrafelhasználható WF-kódkönytár létrehozása
this.creditOK == true
"Initial catalog=AutoLot");
try
{
dal.ProcesscreditRisk(false, ID);
}
finally
{
dal.closeconnection();
}
}
385
26. fejezet: A Windows Workflow Foundation - Bevezetés
CreditO>eckWF.cs [Designr�� �x
Af.� ,c:;,*
�
-
l
Sequentia! Workflow
@
l ,· l
[g ��) �
d
l
-t
l 8 CreditCheckPassedActivity
=l
�
l • l
!�:l
CreditCheckOK CreditCheckFailed
ffil ffil
l
l l �j
(g�u��j f :C��) -t
l (g�) l c....
l l .
'
l �
[;] Mt
�
26.26. ábra: A kész Sequentia! Workjlow Library projekt
386
Újrafelhasználható WF-kódkönytár létrehozása
·- · --
N.w Project �l l 'll••
A projKt for creating an application with a Windows Forms user interface (.NET Framework 35)
Name: Cred�CheclrApp
.l.ocation: C:\My Books\C# and the .NET Platform 4th ed\Code\Final Numbuing\Chapter 26 .
l �,l
· Solution Name: J CreditCh�ckAPp ___j O Create ,directory for solution
EJ Add to Soyrce Control
l OK
ll ._Concel
l
26.27. ábra: Windows Forms-alkalmazásprojekt létrehozása a munkafolyamat-könyvtárunk tesztelésére
Ezután nevezzük át a kezdeti Forml. cs fájlt a találó Mai n Form. cs névre, ezért
jobb gombbal kattintsunk a Forml.cs ikonra a Solution Explorerben, és vá
lasszuk a Rename opciót. Ezután adjunk referenciát az alábbi .NET-szerelvé
nyek mindegyikéhez:
387
26. fejezet: A Windows Workflow Foundation - Bevezetés
• creditcheckWFLib.dll
• System.Workflow.Runtime.dll
• System.Workflow.Activities.dll
• System.workflow.componentModel.dll
namespace winFormsWFClient
{
public partial class MainForm Form
{
388
Újrafelhasználható WF-kódkönytár létrehozása
public MainForm()
{
Initializ�Component();
}
ll Indítsuk el.
myworkflow.Start();
}
}
}
389
26. fejezet: A Windows Workflow Foundation - Bevezetés
Az egyedi tevékenységek
..,
_
Fi�ered by.
(unfiltered}
1!1-- o�elopment Toots and Languages
$-· Enterprise �rvers and Development n
390
Összefoglalás
Összefogla l ás
A Windows Workflow Foundation (WF) egy olyan API, amely a .NET 3.0
391
6. rész
Felhasználói
felületek
HUSZONHETEDIK FEJEZET
Windows Forms-programozás
A Windows Forms-névterek
A Windows Forms API több száz típust (osztályt, interfészt, struktúrát, felsorolt
típust és metódusreferenciát) tartalmaz, amelyek a System. windows. Forms. dll
szerelvény különböző névtereibe rendeződnek A 27.1. ábra ezen névtereket áb
rázolja a Visual Studio 2008 objektumböngészőn keresztül.
l Browse:
���·--�
���
P�
·� L-------------------��x
.NET Framew ork ... ! 4o1 ..
I
• .>:.:J 1 t:iJ •
<Search>
J
1
@ -o System.Web. obile
M
@ -o System.Web.RegularExp ressions
@·O System.Web.Services
s-o System.Winde>ws.Fe>rms
é-·O System.Resources
0 O System.Windows.Forms
l :.•' �
o nent ode. o m nte o
-· -.�; ��=::.:�::::.::;::.�:7gpn M i C 2J r p 1 Assembl C : \
y System.Windows.Forms
Windows\Mi crosoft.NET
�
Í
é-{} System.Windows.Forms.Lay out
ffi_ --O System.Windows.Forms.PropertyGridinternal
f ffi {} System.Windows.Forms.Visua iStyles
·
�:
\Framework\v2.0.S0727
\System.Windows.Forms.dll
é_- -_o_s _ yst_ •_m_.x_m_l .
_,_j Attrlbutes:
L _______
__ _________ _____ _
396
Egyszerű Windows Forms-alkalmazás (IDE-mentes) létrehozása
Mivel a system.windows. Forms által kínált típusok teljes száma jóval megha
ladja a százat, felesleges volna a Windows Forros-család listájához tartozó va
lamennyi tagot felsorolni. A fejezet áttanulmányozása után olyan szilárd ala
pot kapunk, amelyre később nyugodtan építhetünk További információkért
lapozzuk fel a .NET Framework 3.5 SDK dokumentációját.
397
27. fejezet: Windows Forms pr ogramozás
{
static void Main()
{
Application.Run(new Mainwindow());
}
}
ll Ez a főablak.
class Mainwindow Form {}
}
398
Egyszerű Windows Forms-alkalmazás (IDE-mentes) létrehozása
ll Ez a főablak.
class Mainwindow : Form
{
public Mainwindow(string title, int height, int width)
{
ll Határozzunk meg néhány tulajdonságot a szülőosztályból.
Text = title;
width = width;
Height = height;
399
27. fejezet: Windows Forms programozás
400
Egyszerű Windows Forms-alkalmazás (IDE-mentes) létrehozása
new System.EventHandler(this.mnuFileExit_Click);
Megjegyzés Korábban a Mai nMenu típus tetszőleges számú Me nurtern objektum tartására szol
gált. A Menustri p vezérlőelem (amelyet a .NET 2.0-ben ismerhettünk meg) hasonló a Mai nMenu
típushoz, de a Menustri p "normál menüelemeken" kívüli vezérlőelemeket (legördülő listadobo
zokat, szövegdobozokat stb.) is tartalmazhat.
401
27. fejezet: Windows Forms programozás
� MyWindow
�
�
402
Egyszerű Windows Forms-alkalmazás (IDE-mentes) létrehozása
403
27. fejezet: Windows Forms programozás
New Project �
Project typ<s: Templ.nes: ,.NfT F,_rl:3.5 ·rn!ID[B
Visual Basic . Visual Studio installed templat� -·
iJ
-·-
Windows
Database
�-- - Q l
.....
4!c# � �
Test Windows Classlibrary ASP.NET ASP.NET WPF WPF Browser
WCF Fomls W•bAppl... W<b s.rv;... Application Application
W•b p on
A ';;
Workflow
VrsuaiC#
'(!.lll � �
Console WCF Service Windows
=
Test
WCF SJ "
·Workflow Search
Online Te...
VtSuaiC++
Othor Project Typos .
a
A project for creating an application with a Windows Forms user interfi!tce (.NET Fr mcwork 35)
Name: SimpleVSWinFormsApp
location: C:\MyCod• .
l Browse..•
l
Solution Nami!:: l SímpleVSWinFormsApp l O Create dirffiory for solution
l Ol(
ll Concol
l
27.4. ábra: A Visual Studio 2008 Windows Forms-projektsablona
A vizuális tervezőfelület
404
A Visual Studio Windows Forms-projektsablona
•X
Properties
Forml System.Windows.Forms.Form
�l� [ll] l� ,1 ! Q
11±1 {ApplicationSettings) ��
" 1±1 {DataBindings) @
(Name. Form l
li AcceptButton {none)
AccessibleDescription
AccessihleName
AccessíbleRole Default
AllowDrop False
AutoScaleMode Font
(lUme)
l Indicates the name used in code to identify the object.
Megjegyzés A Properties ablakot a legördülő listamező alatti első két gomb segítségével
aszerint is konfigurálhatjuk, hogy a tartalom kategóriánként vagy alfabetikus sorrendben je
lenjen meg. Érdemes az elemeket ábécésorrendbe rendezni, hogy könnyen megtaláljunk egy
adott tulajdonságot vagy eseményt.
405
27. fejezet: Windows Forms programozás
Solution Explorer
eJ SimpleVSW..FormsApp
�- � Properties
liJ.. r:iil References
�-· rrm '3M2!1.tJiJ
: ; � MaínWindow.Designer.cs
! L... � MainWindow.resx
L. '!J Program.cs
A kezdeti űrlap
namespace simplevswinFormsApp
{
public partial class Mainwindow Form
{
public Mainwindow()
{
Initializecomponent();
}
}
}
406
A Visual Studio Windows Forms-projektsablona
lap konstruktora hívja meg ezt a metódust futási időben, hanem tervezési
időben a Visual Studio is ugyanezt a metódust használja annak érdekében,
hogy a Forms-tervezőben megfelelően jelenítse meg a felhasználói felületet.
Ennek illusztrálására módosítsuk az ablakban található Text tulajdonsághoz
rendelt értéket a következőre: "My Main Window". A tervező aktiválásakor
az űrlap címe ennek megfelelően frissül.
Ha pedig a vizuális tervezőeszközöket (pl. a Properties ablak) használjuk,
az IDE automatikusan frissíti az Initial izecomponentO metódust. Ennek il
lusztrálására a Forms-tervező legyen az IDE aktív ablaka, és keressük meg a
Properties ablakban található opacity tulajdonságot. Az értéket írjuk át 0,8-ra
(80%), ennek hatására az ablak enyhén átlátszóvá válik, amikor legközelebb
lefordítjuk és futtatjuk a programot. Ha elvégeztük ezt a módosítást, vizsgál
juk meg ismét az InitializecomponentO implementációját:
407
27. fejezet: Windows Forms programozás
tikailag (vagy logikailag) helytelen forráskódot állítunk össze az Initi ali ze
component() metóduson belül, az a tervező összeomlásához vezethet. A Visu
A Program osztály
408
A Visual Studio Windows Forms-projektsablona
Toolbox
-- ··-
ii
!±l Al W"IAdows Forms
ffi úxnmon Controls
3
1'
�
!±l Containers
El Menus & Tooloars
' 1\ Pointer -�·- . ..• ��· l
flí Conteot!MenuStrip l
�� MenuStrip l :i
i 6:: StatusStrip
'
ill Too1Sttip
'
l 0 TooiStripContainer i
�---�
l !±l Dato
l oo Components l
1±1 Printing Ld,
1±1 Diologs
l
1±1 CrysUI Reports
El Geneni
�
!
�Server Explorer )(< Toolbox j
27.8. ábra: A Toolbox ablak megjeleníti a tervezőfelülethez adható Windows Forms-vezérlóelemeket
409
27. fejezet: Windows Forms programozás
Ir. rt tanda ms
t Dock lTop
r;]
[iJJ
i GripStyle l Hidden Bi
Edithems...
i r_
9·---------------,
l � menuStripl 1i
�-------------------------------
;x
� menuStripl
410
A Visual Studio Windows Forms-projektsablona
Properties
if
exitTooiStripMenultem System.Windows.Forms.TooiStripMenuhem .
�)�[W:� [I] l SJ
BackColorChanged
·l
E.
CheckedChanged
-
CheckStateChanged
DoubleCiick
DropDownCiosed
DropDownltemCiicked
.:
Click
Occurs when the jtem is dicked.
411
27. fejezet: Windows Forms programozás
this.exitToolstripMenuitem.click +=
new System.EventHandler(this.exitToolstripMenuitem_click);
Az ürlapok anatómiája
�· ,�Y�Br��
aa
t�� P�
-.lu_ __________
_ _____________ _____________ ���x
Browse .NET Framework .. . l "" • l :b i f§J • •
<Search>
... D <x r·'!. ActivateO
--� 1 !·-·i• ActivateMdiChild(System.Windows.Forms.Form)
· .'.-.
.. - �
i---s..,..-,
'� .------------------ G ,,.... •t AddOwnedForm(System.Windows.Forms.Form)
I?.'IP.'ll
.-
' B "e- Base Types
!·. ... �t
,. Ad;ustFormScrollbars(booO
'J
. j 8--:� ContainerControl
',:.. . ... CenterloParentQ
' .<>•
8 �ontro1
.-.. Scroll•bi-r
é-� Control
f··'f• CenterToScreenO
·
·
. . .4: Componeni
'
8
f· ·•• CloseQ
•
·
412
Az űrlapok anatómiája
Ahogy azt a 27.12. ábra is muta�a, a Form típus nagy mennyiségű funkcionali
tást örököl az ősosztályoktól, valamint az általa implementált, nagyszámú in
terfésztől.
A 27.2. táblázat a Form származtatási láncában található szülőosztályokba
nyújt betekintést.
,,'
·�::�
System.Object Ahogy a .NET többi osztálya is, a Fonn
"
"az egy object.
413
27. fejezet: Windows Forms programozás
cursor
Right
Bounds
clientRectangle
Height
width
414
Az ürlapok anatómiája
MauseLeave
Mouseoown
Mouseup
MouseMove
MouseHover
Mousewheel
415
27. fejezet: Windows Forms programozás
416
Az ürlapok anatómiája
re állítja.
tékre állítja.
417
27. fejezet: Windows Forms programozás
27.6. táblázat néhány, a Form típus által meghatározott, alapvető metódus lis
táját tartalmazza.
418
Az űrlapok anatómiája
Végül pedig a Form osztály számos olyan eseményt határoz meg, amelyek
közül sok az űrlap élettartama alatt sül el. A 27.7. táblázat a legfontosabbakat
tartalmazza.
419
27. fejezet: Windows Forms programozás
public Mainwindow()
{
Initializecomponent();
Megjegyzés Azért kezeljük manuálisan ezeket az eseményeket, mert a Properties ablak (vala·
mi különleges okból kifolyólag) nem listázza a clos i ng és a cl osed eseményt. A Load, Act iva
ted és Deactivate eseményeket azonban tervezésidejű eszköz segítségével is kezelhetjük.
420
Az űrlapok anatómiája
melyik gombot választotta. Olyan üzenetdobozt hoztunk létre, amely egy Yes
és egy No gombot tartalmaz; tehát az érdekel bennünket, hogy a show() metó
dus a DialogResult. No értéket adja-e vissza, vagy sem.
421
27. fejezet: Windows Forms programozás
load event
Activate �ent
Deactivate event
Activate event
Closing event
Deactivate event
Activate �ent
Closing event
Oeactivate event
Activate event
Closed event
OK
422
Reagálás az egér eseményeire
�c'• ., <
�j�
.. -.-;.-.;..... -4
423
27. fejezet: Windows Forms programozás
Az egérgombkattintás meghatározása
424
Reagálás a billentyűzet eseményeire
MessageBox.show("Left click!");
if(e.Button MouseButtons.Right)
==
MessageBox.Show("Right click!");
if (e.Button MouseButtons.Middle)
==
MessageBox.show("Middle click!");
}
public class
. KeyEventArgs : EventArgs
{
private bool handled;
private readonly Keys keyData;
private bool suppressKeyPress;
425
27. fejezet: Windows Forms programozás
Ennek bemutatására tételezzük fel, hogy van egy új, a Keyup eseményt az alábbi
módon kezelő, KeyboardEventApp nevű Windows Applicaton-projektünk
426
Párbeszédablakok tervezése
li-
Párbeszédablakok tervezése
427
27. fejezet: Windows Forms programozás
�Wmdow.cs [Design]*'------•_.:.X;_
· ;:;· CarOnlor�
l File Tools J! T)
_P <' Here _ _!
_
l
Order Automobile...
TvP"= �ere
� menuStripl
T�mplates:
� r- � .�
· - ��
Flow
;,_j
Page(WPF)
'�_J '�:.J ��
PageFunct... ResourceOi... User Control
yw
Window
�
Class
�
Class
�
Interface
Docume... (WPF) (WPF) (WPF) (WPF)
tJ �jLJ .,
#.,. [j �
. � -� -m
•
Code File Custom WCF Service User Control Web Custom Inherited lnherited
Centr ... Configurat... Control Form User Control
.
g
Web Curtom Component
� �
HTMLPage SQL
�
DataSet
�
XMLFile
�.
XMLScherna
� �
XSLT File
[i1.
HTML Page
Control Class Database
�- li � � � � i @ @-
A blank Windows Form
---------------------------·
Name: OrderAutoDialog.cs
Add ll C•ncel
428
Párbeszédablakok tervezése
A DialogResult tulajdonság
•X
·ro;d;AutoDialog �l;
Make
Color
Price
�l Cancel
429
27. fejezet: Windows Forms programozás
A tabulátorsorrend konfigurálása
A tabulátorsorrend-varázsló
:�iaii
430
Párbeszédablakok tervezése
ablakban is elvégezhető):
Párbeszédablakok megjelenitése
431
27. fejezet: Windows Forms programozás
432
Párbeszédablakok tervezése
Az űrlapok származtatása
433
27. fejezet: Windows Forms programozás
Templates: �G
Visual Studio installed tanpiates -·
�-u �
l'!- ' ,;;;j
\ v. r5U �
.. 'i � � � nl
Flow Page (WPF) Pagefunct... ResourcdJi... Us�r Control Window Class Class Interface �
Oocume... (WPF) ( WPF ) (WPF)
:f:·
(WPF )
�
Code File
,.,
Custom
Contr...
i
WCFService
[il .
Windows
Form
ll
User Control
�-
Web
Configurat...
�
Custom
Control
•
�
-�
Inherited
.
User Control
u
[fl �
Web Custom Component
[i1
HTMLPage SQL
jfl
DataSet
fil
XMLFile
IDl.
XMLScherna
�
XSLT F ile
�
HTMLPage
Control Class Database
� -
[i1 � � � l � @
A n� form based on an existing Windows Form
Name: ImageOrderAutoOialog.cs
Add JI Cancd
Inheritance Picker
lll
lNew�name:lmage(JnlerJIUoOialog
&-... JI OK jj Ciw1cel
434
Párbeszédablakok tervezése
Megjegyzés A projektet legalább egyszer le kell fordítani annak érdekében, hogy az űrlapok
láthatók legyenek az lnheritance Picker párbeszédablakban, hiszen ez az eszköz olvassa a sze
relvény-metaadatokat a lehetőségeink megjelenítéséhez.
�eOrderAutoi>Wog.cs [Designrj • x
!Soke �
·1�,
·"·""'"""•""--'Jilr
!SJicr � b
�
� 1'8
��'"""'""�u�-" ="''". 1
� OK l f!l Cancel
435
27. fejezet: Windows Forms programozás
Object Browser
..
MainWindow.cs • x
<Search> ll
�s-o�·!J;. =------:il
{) l
Sy<tem.Drawing
0 O Sy<tem.Orawing.Design
{)
!
Sy<tem.Orawing.Orawing20
{) Sy<tem.Orawing.Imaging Assembly System.Dr•wing �l
() Sy<tem.Orawing.Printíng C:\Wrndows\Mrcrosott.NET\Frameworl::\v2.0.50727
O
"'
Sy<tem.Orawing.Text _ \System.Drawing.dll
436
GDI+-alapú grafikus adatok renderetése
437
27. fejezet: Windows Forms programozás
438
GDI+-alapú grafikus adatok renderetése
DrawiconO
DrawLineO
DrawlinesO
DrawPieO
DrawPathO
DrawRectangle 0
DrawRectangles()
DrawstringO
FillPath 0
439
27. fejezet: Windows Forms programozás
440
GDI+·alapú grafikus adatok renderetése
típust is igényel, mert ami a GDI+-t illeti, a "Hello GDI+" a képernyőn kitöl
tendő geometrikus minták egyszerű gyűjteményét jelenti. Végül pedig egy
egyedi Pen típust használó, 10 képpontnyi széles vonal rendereléséhez hívjuk
meg a DrawL i ne() metódust. A 27.24. ábra ennek az renderelési logikának a
kimenetét ábrázolja.
Hello GDI+
441
27. fejezet: Windows Forms programozás
442
Teljes Windows Forms-alkalmazás létrehozása
A főmenürendszer készítése
�x
�
� menuStripl
Ezt követően hozzuk létre a második felső menüt, a Tools menüt, amelynek
segítségével kiválasztható a rendereléshez használatos alakzat és szín, vala
mint törölhetök a grafikus adatok az űrlapról (lásd a 27.26. ábrát).
443
27. fejezet: Windows Forms programozás
1lli! menuStripl
ll Az alakzat típusa.
public selectedshape shapeType { get; set; }
}
444
Teljes Windows Forms-alkalmazás létrehozása
. Select
Shape
o (ide o Redqle
445
27. fejezet: Windows Forms programozás
446
Teljes Windows Forms-alkalmazás létrehozása
447
27. fejezet: Windows Forms programozás
Color
Basic colars:
rrr:;r•
.,, ...
•• • • •••
••• • • • ••
••• • • • ••
..... . ,
Custom colors:
rrrrrrrr
rrrrrrrr
l Define Custom Co:on; » J CokxlSolid Lun: 179 llue: 141
448
Teljes Windows Forms-alkalmazás létrehozása
449
27. fejezet: Windows Forms programozás
•
•
• •
• •
•
•
•
A projekt utolsó fázisában implementáljuk a File > Save... és a File > Load...
menüelemek kattintásiesemény-kezelőjét. Mivel a shapeData rendelkezik a [Se
rialization] attribútummal (és mivel maga a L ist<T> sorosítható), a Windows
ll A bináris formázóhoz.
using system.Runtime.serialization.Formatters.Binary;
using system.ro;
450
Teljes Windows Forms-alkalmazás létrehozása
if (openDlg.ShowDialog() == DialogResult.OK)
{
Stream mystream = openDlg.OpenFile();
if ((mystream != null))
{
ll vegyük az alakzatokat.
BinaryFormatter myBinaryFormat = new BinaryFormatter();
shapes =
(List<ShapeData>)myBinaryFormat.Deserialize(mystream);
mystream.close();
rnvalidate();
}
}
}
}
451
27. fejezet: Windows Forms programozás
Összefoglalás
452
HUSZONNYOLCADIK FEJEZET
A WPF és az XAML
nyeket és -névtereket.
A fejezet további részében egy vadonatúj XML-alapú nyelvet tanulmá
nyozunk: a XAML-t (Extensible Application Markup Language - bővíthető
alkalmazás jelölőnyelv). Láljuk majd, hogy a XAML a WPF-fejlesztők számá
ra lehetövé teszi a felhasználói felület definícióinak elkülönítését az őket ve
zérlő logikától. A fejezetben rendkívül fontos témaköröket vizsgálunk, pél
dául a csatolt tulajdonság szintaxist, a típusátalakítókat, a markup bővítőket,
és megtanuljuk, hogyan elemezzünk futásidőben XAML-kódot. A fejezet vé
gén különböző WPF-specifikus eszközökkel ismerkedünk meg, amelyeket a
Visual Studio 2008 IDE foglal magában, és betekintést nyerünk a Microsoft
Expression Blend szerepébe is.
A WPF mozgatórugója
Az évek alatt a Microsoft több grafikus felhasználói felület eszközrendszert
készített (nyers C/C++/Win32 API fejlesztés, VB6, MFC stb.) asztali alkal
mazások fejlesztéséhez. Az API-k a grafikus felülettel rendelkező alkalmazá
sok alapelemeinek - például a főablakok, a párbeszédablakok, a vezérlőele-
28. fejezet: A WPF és az XAM L
454
A WPF mozgatórugója
455
28. fejezet: A WPF és az XAML
Megjegyzés Ismét fontos kiemelni: a WPF nem korlátozódik a Windows Vista operációs rend
szerre! Noha a Vista operációs rendszerben már a telepítőben rendelkezésünkre állnak a .NET
3.0 könyvtárak (a WPF is), a .NET Framework 3.5 SOK (fejlesztők számára) és a .NET 3.5 futta
tórendszer (végfelhasználók számára) telepítését követően XP és Windows Server 2003 rend
szerekben is készíthetünk és futtathatunk WPF-alkalmazásokat.
456
A WPF mozgatórugója
457
28. fejezet: A WPF és az XAML
458
A WPF-alkalmazások különbözőtípusai
1l Name
Startup
Date:mo
--· - - - ... - ···-·-··--
Administrative Tools
� LJ ! (]l PUB5_LOG.LDF
Aceesseries
l � ReadMe_SQL2000SampleDbScripts.htm
Programs:
Start Menu
...- l • ! lll
.J
PUBS.MDF Date mcdified: 12/13/2004 5:14 PM
SQL Setver Database Pri mary Data File Size: 1.25 MB
Date created: 12/13/2004 5:14 PM
XBAP-alkalmazások
459
28. fejezet: A WPF és az XAML
=@l
"'
Mexican Lunch U
60 l
----'-----
����'MY7.-•";a{,.�".-;F.�:P"�'-l"
' · · ·· · · ·
...-"':-�
·
·
Total Expenses: $ 277
460
A WPF-szerelvények vizsgálata
Silverlight-alkalmazások
A WPF-szerelvények vizsgálata
461
28. fejezet: A WPF és az XAML
462
A WPF-szerelvények vizsgálata
463
28. fejezet: A WPF és az XAML
ll A WPF-program globális
ll alkalmazásobjektumának definíciója.
class MyApp : Application
{
[STA Thread]
static void Main()
{
ll Események kezelése, az alkalmazás futtatása,
ll a főablak indítása stb.
}
}
464
A WPF-szerelvények vizsgálata
Az egyik következő példában egy teljes típust készítünk, amely az Appl i ca
ti on típusból származik. Addig is tanulmányozzuk a window típus alapvető
'
�_I!"OidiiOl�:Xi!irtP!iYObj«tBrowse<
�X
. ... � l b<�.,.
1
Browse MySolution .. 1
465
28. fejezet: A WPF és az XAML
466
A WPF-szerelvények vizsgálata
Ez első pillantásra erősen korlátozónak tűnhet (képzeljük el, hogy egy párbe
szédablak egyetlen gombbal milyen működésképtelen lenne!). A panelek se
gítségéve! szerencsére több elemet is hozzáadhatunk a contentcontrol alap
osztályból származó típusokhoz. Ehhez a tartalom minden egyes részét a
WPF-paneltípusok egyikébe kell rendezni, és ezt követően a panel válik azon
egyetlen értékké, amelyet a Content tulajdonsághoz rendelünk A WPF-tarta
lommodellel, valamint a különböző paneltípusokkal (és a típusok vezérlő-
/
elemeivel) a 29. fejezetben ismerkedünk meg.
467
28. fejezet: A WPF és az XAML
verticalcontentAlignment
468
A WPF-szerelvények vizsgálata
Height, width
469
28. fejezet: A WPF és az XAML
A System.Windows.Media.Visual szerepe
A Visual osztálytípus a WPF alapvető renderelési támogatását biztosítja. A tá
mogatás magában foglalja a rendereit adatok találattesztelését, a koordináta
transzformációkat és a határolódoboz-számításokat Valójában ez a típus jelenti
a kapcsolódási pontot a felügyelt WPF-szerelvény verem és a nem felügyelt
milcore. dll bináris között, amely a DirectX alrendszerrel kommunikál.
470
(XAML-mentes) WPF-alkalmazás készítése
(XAML-mentes) WPF-alkalmazás
készitése
471
28. fejezet: A WPF és az XAML
namespace simpleWPFApp
{
ll Az első példában egyetlen osztálytípust definiálunk, amely
ll magát az alkalmazást és a főablakot képviseli.
class MyWPFApp : Application
{
[STAThread]
static void Main()
{
ll A Startup és az Exit események kezelése, az alkalmazás
ll futtatása.
MyWPFApp app = new MyWPFApp();
app.startup += AppStartup;
app.Exit += AppExit;
app.Run(); ll Fires the Startup event.
}
Vegyük észre, hogy a MyWPFApp osztály kibővíti a system. windows .Appl ication
típust. A Main() metódusban létrehozzuk az alkalmazásobjektum egy példá
nyát, és a metóduscsoportátalakítás-szintaxis segítségével kezeljük a startup
472
(XAML-mentes) WPF-alkalmazás készítése
[STAThread]
static void Main()
{
ll Ezúttal meghatározzuk a mögöttes metódusreferenciákat.
MyWPFApp app = new MyWPFApp();
app.Startup += new StartupEventHandler(AppstartUp);
app.Exit += new ExitEventHandler(AppExit);
app.Run(); ll Kiváltja a Startup eseményt.
}
kalmazást leállítjuk
A C#-kód végrehajtható WPF-alkalmazásra fordítása során tételezzük fel,
hogy létrehoztuk a b uild.rsp C#-reakciófájlt, amely hivatkozik az összes
WPF-szerelvényre. Vegyük észre, hogy az egyes szerelvények elérési útvona
lát egy sorban kell meghatároznunk (a reakciófájlokkal és a parancssoros
fordító használatával kapcsolatos bővebb információkat lásd a 2. fejezetben):
# build.rsp
#
ltarget:winexe
lout:SimpleWPFApp.exe
lr:"C:\Program Files\Reference
Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll"
lr:"C:\Program Files\Reference Assemblies\Microsoft\Framework
\v3.0\Presentationcore.dll"
lr:"C:\Program Files\Reference Assemblies\Microsoft\Framework
\v3.0\PresentationFramework.dll"
*.cs
473
28. fejezet: A WPF és az XAML
esc @build.rsp
474
(XAML-mentes) WPF-alkalmazás készítése
funkcionalitását!
vezérlőt!
475
28. fejezet: A WPF és az XAML
ll Az ablak beállítása.
this.Title = windowTitle;
this.windowstartupLocation = windowstartupLocation.centerScreen;
this.Height = height;
this.Width = width;
this.Show();
}
476
Az Application típus további jellemzői
l Exit Application l
477
28. fejezet: A WPF és az XAML
478
Az Application típus további jellemzői
simpleWPFApp.exe /godmode
479
28. fejezet: A WPF és az XAML
480
A Window típus további jellemzöi
}
}
Megjegyzés Emlékezzünk rá, hogy az Appl i cati on. Ac ti vated és az Appl i cati on. Deacti
vated eseményekkel az összes ablak alkalmazásszintű aktivátását és deaktiválását kezelhetjük.
481
28. fejezet: A WPF és az XAML
l Az eredeti szövegbe itt az igaz érték szerepel (Cance!EventArgs.Cancel can be set to true), ezt
azonban javítottuk, lévén nyilvánvaló tévedés, ami az alábbi kódrészlettel támasztható alá:
ll Ha a felhasználó nem akarja bezárni az ablakot, a zárási kérelmet töröljük.
e. Cancel = true - a kiadó.
482
A Window típus további jellemzői
Tételezzük fel, hogy a Mainwindow típus kezeli ezt a két eseményt, és vizs
gáljuk meg az utolsó eseménykezelőket
l OK
l
28. 5. ábra: A System.Windows.Window élete
483
28. fejezet: A WPF és az XAML
484
A Window típus további jellemzöi
485
28. fejezet: A WPF és az XAML
(XAML-központú) WPF-alkalmazás
készitése
486
(XAML-központú) WPF-alkalmazás készítése
<Window x:clas$="Simplexam1App.Mainwindow"
xmlns="http://schemas.microsoft:.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft:.com/winfx/2006/xaml"
Title="My xaml App" Height="200" width="300"
windowstartupLocation ="Centerscreen">
<x:code>
<![CDATA[
private void btnExitApp_Clicked(object sender, RoutedEventArgs e)
{
ll Az aktuális alkalmazás leírójának megszerzése és az
ll alkalmazás leállítása. ·
Application.current.Shutdown();
}
] ]>
</x:code>
</Window>
487
28. fejezet: A WPF és az XAML
488
(XAML-központú) WPF-alkalmazás készítése
<Application x:class="SimplexamlApp.MyApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startupuri="Mainwindow.xaml" Exit ="AppExit">
<x:code>
<! [CDATA[
private void AppExit(object sender, ExitEventArgs e)
{
MessageBox.Show("App has exited");
}
JJ>
</x:code>
</Application>
489
28. fejezet: A WPF és az XAML
<Project DetaultTargets="Build"
xmlns="http://schemas.microsott.com/developer/msbuild/2003">
<PropertyGroup>
<RootNamespace>SimplexamlApp</RootNamespace>
<AssemblyName>SimplexamlApp</AssemblyName>
<OutputType>winexe</OutputType>
</PropertyGroup>
<ItemGroup>
<Reterence Include="System" />
<Reterence Include="Windowssase" />
<Reterence Include="Presentationcore" />
<Reterence Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDetinition Include="MyApp.xaml" />
<Page Include="Mainwindow.xaml" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsott.csharp.targets" />
<Import Project="$(MSBuilds inPath)\Mi erosott.Wi nFX. targets" />
</Project>
rozza meg, amelyre hivatkoznunk kell. Látha�uk, hogy ezek azok a kulcsfontos
ságú WPF-szerelvények, amelyeket a fejezet korábbi részében megvizsgáltunk
A második <ItemGroup> sokkal érdekesebb. Vegyük észre, hogy az <Application
oetinition> elem Include aUribúturnát ahhoz az *. xaml fájlhoz rendeltük, amely
490
(XAML-központú) WPF-alkalmazás készítése
msbuild simplexamlApp.csproj
l:
l{"'sernl:*y SimpleXarnlApp
491
28. fejezet: A WPF és az XAML
492
Markup átalakítása .NET-szerelvénnyé
void system.Windows.Markup.IComponentconnector.connect(
int connectionrd, object target)
{
switch (connectionrd)
{
case 1:
this.btnExitApp = ((System.windows.Controls.Button)(target));
this.btnExitApp.Click += new
system.windows.RoutedEventHandler(
this.btnExitApp_clicked);
return;
}
this._contentLoaded = true;
}
493
Z8. fejezet: A WPF és az XAML
A BAML szerepe
0 .O System
Name Value.
@ ·O System.Data
&J ·O System.Orawíng
maonwmdow.baml Oc 00 00 00 4d 00 53 00 . (767 bytes)
l!) ·Cl System.Web
00 ·O System.Windows.Forms
l!) .O System.Xml
8 ·Cl Simpi.Xam!App
G ll\ Simpi.Xam!App.exe
00@i Referenc�
{)
!!l o
0 {) Simpi.Xam!App
EJ W Resources
;;;J Simpi.XamiApp.g.resources
T 'L "'
Z 8. 7. ábra: A beágJ;azott *.baml erőforrás megtekintése Lutz Roeder .NET Rejleetor programjával
494
Markup átalakítása .NET-szerelvénnyé
�x
6.x.http
://schemas.micro
soft.com/winfx/2
006/xaml. . .5 .
. . .T
.My Xa.-.1
.$
. $.
�
00
00 00 03 C9 FF 00 20 Ol 00 00 00 35 00 .5.
00 00 00 00 24 10 CA FF OA 62 74 6E 45 . $ . . . btnExit
41 70 70 99 FD 35 09 00 00 00 23 00 00 App . . 5. . l . .. $.
C7 FF 03 31 33 33 A4 FE 36 OB 00 00 00 24 08 Dl .. 133 . . 6 . . .. $ ..
FF 02 32 34 A4 FE 36 17 00 00 00 2E F2 FF 36 51 .24 .6.. . .60
10 45 78 69 74 20 41 70 70 6C 69 .. Exi t Aooli
namespace simplexarnlApp
{
public partial class MyApp : system.windows.Application
{
void AppExit(object sender, ExitEventArgs e)
{
MessageBox.Show("App has exited");
}
[System.Diagnostics.DebuggerNonusercodeAttribute()]
public void Initializecomponent() {
this.Exit +=
new system.windows.ExitEventHandler(this.AppExit);
;
this. startupuri = new System.uri("Mainwindow. xaml , ,
system.uriKind.Relative);
}
[System.STAThreadAttribute()]
[system.Diagnostics.DebuggerNonuserCodeAttribute()]
public static void Main() {
simplexamlApp.MyApp app = new SimplexamlApp.MyApp();
app.Initializecomponent();
app.Run();
}
}
}
495
28. fejezet: A WPF és a z XAML
MainWindow.xaml MainWindow.g.cs
MyApp.xmal My App.g.cs
*.cspro
MainWindow.baml
SimpleXamiApp.g.resources
SimpleXamiApp.exe
496
A kapcsolatok elkülönítése mögöttes kódfájlokkal
ll Mainwindow.xaml.cs
using System;
using System.windows;
using system.Windows.Controls;
namespace SimplexarnlApp
{
public partial class Mainwindow : window
{
public Mainwindow()
{
ll Jegyezzük meg! A metódust a
//generált Mainwindow.g.cs fájl definiálja.
Initializecomponent();
}
497
28. fejezet: A WPF és az XAML
ll MyApp.xaml.cs
using System;
using System.windows;
using System.windows.controls;
namespace SimplexarnlApp
{
public partial class MyApp : Application
{
private void AppExit(object sender, ExitEventArgs e)
{
MessageBox.show("App has exited");
}
}
}
498
A XAML-szintaxis
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.csharp.targets" />
<Import Project="$(MSBuildBinPath)\Microsoft.winFX.targets" />
</Project>
A XAML-szintaxis
Mint azt a fejezet korábbi részében említettük, rendkívül kicsi az esélye annak,
hogy WPF-alkalmazásainkban kézzel kellene több oldalnyi XAML-markupot
megírnunk, hiszen ezt a feladatot a megfelelő eszközök (Visual Studio 2008,
Microsoft Expression Blend stb.) elvégzik helyettünk. Azonban minél többet
megtanulunk a jól formázott *. xaml fájlok szintaxisáról, annál felkészültebbek
leszünk az automatikusan generált markup beállítására és módosítására, va
lamint mélyebb ismereteket szerzünk magáról a WPF-ről. Most pedig ássunk a
XAML-alapszintaxis mélyére (a következő fejezetekben- ahol szükség lesz rá
további XAML-szintaxis példákkal találkozunk).
Megjegyzés Érdekes módon sem a .NET Framework 3.5 SDK, sem a Visual Studio 2008 nem
tartalmazza a xaml pad. exe programot. A Windows SDK letöltésével juthatunk hozzá ehhez az
eszközhöz, a fejezet legutolsó példájában C# segítségével elkészítjük a xaml pad. exe lecsupa
szított verzióját.
499
28. fejezet: A WPF és az XAML
i3 Xam!Pad
:� Hefresh "-' ,g, � j CourierNew • 12 100%
L - '"---
- ��U '
-- --- --
�""
- l Visual Tree Explorer
A :Page
.. :Border
1 (Ml#t!;,wt1§
Name
c.
! base Framew
f· Content Grid
<PaQe
.. .
:ct.ln:�:c:: ht'tp: // ,!!:Che-r.a.s.micro-'o!t. co�.f'..;infx/2006/xar.tl/pr�.!�n't-a:.icn"'
..
�ln.s: X"" h;;;'tp: 1 /3chen:a.s. o.icro3oft. cc:n/•.:infx/2006/xa!:'U.
. H>
<Grid>
</G:=id>
</Pag-e>
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<!-- Ide írhatjuk a XAML-markupot! -- >
</Grid>
</Page>
Noha a xaml Pad nem teszi lehetővé, hogy a xaml Pad nézet ablakában közvet
lenül megtekintsük egy <Window> elem markupját, a <Page> elemet <Window>
elemre módosíthatjuk, és az F5 funkciógombbal egy különálló ablakban meg
jeleníthetjük a tartalmát. Ne feledjük továbbá, hogy a <Page> és a <Window>
elem markupja megegyezik!
500
A XAML-szintaxis
Megjegyzés A x am lPad nem teszi lehetövé, hogy olyan markupot készítsünk, amely a kód for
dítását vonja maga után. Ez magában foglalja a class attribútum definiálását (kódfájl meghatá
rozásához), a <Code> elemek használatát, illetve bármely XAML-kulcsszó alkalmazását, amely a
forráskód fordítását vonja maga után (mint például a FieldModifier vagy a classModifier ) .
Bármilyen erre irányuló próbálkozás markuphibához vezet.
XAML-névterek és -kulcsszavak
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microso ft.com/winfx/2006/xaml">
<Grid>
</Grid>
</Page>
501
28. fejezet: A WPF és az XAML
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:
xamlspecificstuff="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
</Grid>
</Page>
502
A XAML-szintaxis
<Application xamlSpecificStuff:class="SimplexamlApp.MyApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:xamlspecificstuff =
"http://schemas.microsoft.com/winfx/2006/xaml"
Startupuri="Mainwindow.xaml" Exit ="AppExit">
< xamlspecificstuff:code>
<! [CDATA[
private void AppExit(object sender, ExitEventArgs e)
{
MessageBox.show("App has exited");
}
J J>
</Xamlspecificstuff:code>
</Application>
503
28. fejezet: A WPF és az XAML
Több említett kulcsszót látunk majd működés közben. Egy egyszerű példán
keresztül vizsgáljuk meg a következő XAML <WindoW> definíciót, amely a
classModifier és a FieldModifier, valamint a Name és a class kulcsszavakat al
kalmazza (emlékezzünk rá, hogy a xamlpad.ex e nem teszi lehetővé, hogy olyan
XAML-kulcsszót használjuk, amelynek alkalmazása a kód fordítását vonja
maga után, mint például a code, a FieldModifier vagy a classModifier) :
504
A XAML-szintaxis
XAML-elemek és -attribútumok
505
28. fejezet: A WPF és az XAML
506
A XAML-szintaxis
�\ XamiPad l l @l lii:iiil
=
�
LlJ
I'7Paqe
I
xmlns=""ht:.t.p: l /.sche:cas .m.icrosof�. coc./winfx/2006/xar.ü/presentation"
..
xnüns: x:c ht:.t.p: l /3che:nas. micro.soft:. co:!!/wl.D'%.x/2006/xaml"'>
<Button x:Name ,.,.•myBut:ton"' Hel.Qht ='"too· Wideh ='"100'">
<Butt.on.Content.>
�
E
<ScrollBar F.eigh� = "50" Width = "20"' l>
</But.t.on.Content.>
<IBut.�on>
</Paqe>
28. 12. ábra: A tulajdonságelem szintaxis lehetővé teszi, hog�} összetett tulajdonságokat
rendeljünk a tulajdonságokhoz
507
28. fejezet: A WPF és az XAML
508
A XAML-szintaxis
<Page
xmlns=''http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DockPanel LastchildFill ="True">
<!-- Elemek dokkolása a panelhez csatolt tulajdonságok
használatával -->
<Label DockPanel.Dock ="Top" Name="lblrnstruction"
Fontsize="15">Enter car Information</Label>
<Label DockPanel.Dock ="Left" Name="lblMake">Make</Label>
<Label DockPanel.Dock ="Right" Name="lblcolor">Color</Label>
<Label DockPanel.Dock ="Bottom"
Name="lblPetName">Pet Name</Label>
<Button Name="btnOK">OK</Button>
</DockPanel>
</Page>
509
28. fejezet: A WPF és az XAML
<Button.Background>
Pi nk
</Button.Background>
</Button>
XAML-tipusátalakitók
510
A XAML-szintaxis
ll A System.Windows.controls.control.Background tulajdonság.
pub lic B r ush B a c k g r o u nd
{
" Pink értéket olyan tulajdonsághoz rendeljük, amely prototípusa szerint ecset
típusokkal dolgozik, a rendszer a colorconverter és a Brushconverter típusokat
alkalmazza. Több átalakító létezik: a si z eco nv ert e r (az előző El li pse típus
width és Height tulajdonságainak beállítására), a Rectconverter, a ve c to rco n
511
28. fejezet: A WPF és az XAML
A XAML markupbővitményei
használják).
Vizsgáljuk meg működés közben a markupbővítőket! Tételezzük fel, hogy
a Label típusok készletéhez beállí�uk a content tulajdonságot, és a system.
Environment statikus tagjaival így jelenítünk meg információkat arról a számí
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:corLib="clr-namespace:System;assembly=mscorlib">
<StackPanel>
<Label content ="{x:Static corLib:Environment.MachineName}"/>
<Label content ="{x:static corLib:Environment.osversion}"/>
<Label content =''{x:Static corLib:Environment.Processorcount}"/>
</StackPanel>
</Page>
512
A XAML-szintaxis
Íme, egy másik példa. Tételezzük fel, hogy a különböző típusok teljesen meg
határozott nevét szeretnénk megszerezni, hogy aztán az értékeket Label típu
sok content tulajdonságaihoz rendeljük. Ebben az esetben a Type jelölő kiter
jesztést alkalmazhatjuk:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http:jjschemas.microsoft.com/winfx/2006/xaml"
xmlns:corLib="clr-namespace:System;assembly=mscorlib">
<StackPanel>
<Label content ="{x:Static corLib:Environment.MachineName}"/>
<Label content ="{x:Static CorLib:Environment.OSVersion}"/>
<Label content ="{x:Static corLib:Environment.Processorcount}"/>
<Label content ="{x:Type Label}" />
<Label Content ="{x:Type Page}" />
<Label content ="{x:Type corLib:Boolean}" />
<Label Content ="{x:Type x:TypeExtension}" />
</StackPanel>
</Page>
513
28. fejezet: A WPF és az XAML
MVDELLXPS
System,Windows.Controls.label
System,Windows.Controls.Page
System.Boolean
System.Windows.Markup.TypeExtension
<Page
xmln.s=..http: l/�chel'lB.s .:nicrosof't:. comt•,;infx/2006/xaol/pre��nta'tion"
xm.ln�: x="ht.tp: 1 /3cher::as .ru.cro�oft. co:n/TA•infx/2006/xa:ol'"
..
xmlns: CorLib= clr-nan:.�space: System; asse.mbly=t'!l..ecorlib">
<StackPanel>
t.
<Label Content ="{x: Si: a ic CorLib: Environr..�nt: .Hachine!la::te} "/>
<Label Content. =.. {x:Stat.ic CorLib:E.nvironr.:ent.OS""Ver3ion}"/>
n
<Label Conte t. ="{x: Sta.:.ic CorLib: Envirorur:em:. Proces.sorCcunt} "l>
<Label Con'tem: ="{x:Type Lab el} " l>
<Label Conten':. ..,•{x:Type Page}" l>
<Label Content """ {x:Type Corlib:Boolean}" l>
<Label Cont:e:l.'t ="{x:Type x:T:y-peE.xten"ion}" />
<IStackPan�l>
</Paoe>
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:CorLib="clr-namespace:system;assembly=mscorlib">
<StackPanel>
<Label content ="{x:Array Type corLib:string}"/>
</StackPanel>
</Page>
514
A XAML-szintaxis
<x:Array Type="CorLib:string">
<CorLib:String>Sun Kil Moon</CorLib:string>
<CorLib:String>Red House Painters</CorLib:string>
<CorLib:String>Besnard Lakes</CorLib:String>
</x:Array>
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:CorLib="clr-namespace:System;assembly=mscorlib">
<!-- Hmm, éppen most állítottuk be a content tulajdonságot! -->
<x:Array Type="CorLib:String">
<CorLib:String>Sun Kil Moon</CorLib:string>
<CorLib:String>Red House Painters</CorLib:string>
<CorLib:String>Besnard Lakes</CorLib:String>
</x:Array>
</Page>
515
28. fejezet: A WPF és az XAML
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:CorLib="clr-namespace:System;assembly=mscorlib">
<StackPanel>
<StackPanel.Resources>
<x:Array Type="CorLib:string" x:Key = "GoodMusic">
<CorLib:String>Sun Kil Moon</CorLib:String>
<CorLib:String>Red House Painters</CorLib:string>
<CorLib:String>Besnard Lakes</CorLib:String>
</x:Array>
</StackPanel.Resources>
516
WPF-alkalmazások készítése a Visual Studio 2008 segítségével
3 XamiPad
�t:acjc?e.:lel.•Re�ource;->------
---
lJ
<J:..: :Ar::-ay>
LJ
= ..
517
28. fejezet: A WPF és az XAML
WPF -projektsablonok
�Windows Service
- WPF Custom Controllibrary
ii2J Empty Projoct
Tost
WCF
j � WPF User Controllibrary iilJ Windows Forms Controllibrary
Woricflow � Reports Application
Visual C++ MyTemplat6 -�-·------------------
�ame: MyWPFApp
l OK
ll Concol
l
28.16. ábra: A Visual Studio 2008 WPF projektsablonjai
518
WPF·alkalmazások készítése a Visual Studio 2008 segítségével
Solution Explorer
· References
·O PresentationCore
�o PresentationFrameworlc
·O System
·O System.Core
·O System.Data
·O System.Data.DataSetExtensions
· O System.Xml
· O System.Xmi.Linq
�o WindowsBase
8- � App.xaml
j i ':: � App.xaml.cs
i 8-- � •m••
;i ' � Windowl.xaml.cs
·l
!i
Ic,� Solution Explorer
28.17. ábra: A WPF Application projekt típus kezdeti fájljai
519
28. fejezet: A WPF és az XAML
<Window x:
Class="MyWPFApplication.Mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Windowl" Height="300" Width="300">
<Grid>
</Grid>
</Window>
<Application x:Class="MyWPFApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startupuri="Mainwindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
A WPF -tervező
520
WPF-alkalmazások készítése a Visual Studio 2008 segítségével
WindöWt.x.mll;W-indowl.xoml.csr�:obieStlkow>er)
/
- y x
l
l
. ;··�;c,·....
------
1-·
l
�·
--- ---·
-:'ji
2·-.i\ xmlns="http: //schemas .mic�osoft.
com/win�x/20 0 6/xaml/present r
3i xmlns: x="http: //schemas .mlcrosoft. com/wlnfx/2006/xarol "
4! Title="Windowl" Height="300" Width="300"> IE
5' - <Grid>
6!
T </Grid>
8; </Window>
9i
l litw-..iow��d� l>
521
28. fejezet: A WPF és az XAML
[ !=l l
5 <Grid>
6i <Button Background="
l 7! � .;fi AliceBlue i
Dii .
.Jil·A�tiq;;;wt;i!;;--
�'
8:
.til' Aqua
</Window> 1
l
iif Aquamarine ;
l .l
9;
l
l _&l Azure
iiflBeige
ilf Bisque
;
.J
1, d' Bla k
c l l
�Jl�� c::�::d :_l
l __ _ ___
l
l Th_�;�l_�ú·��-(/ �' Wonclow Win ow f>
d
-�,J
mi� l
28.19. ábra: A XAML IntelliSense
'1
1
ii
�
3
l
/w..-��;:-=::;��::-=. Wlndowl"
xmlns="http; l/schemas .rnicrosoft . corn/ wwfx/2006/xaml/presentation"
xmlns;x="http;//schemas.rnlcrosoft.com/wjnfx/2006/xaml" (1
- ·-���'l'
J
4 Tltle="Windowl" Helght="300" Width="300">
1
,
s.
61
<Grld>
<Button Background="AllceBlue" Cllck=" l:
L' 1
r
{[uJ<�ewEv�nt�ndler> �}
l 7L
,�GrJ.d>
i
'
8: </Window> ,;,:;;_ ·
l
9 i
l
522
XAML feldolgozása futásidőben: a SimpleXamlPad.exe
523
28. fejezet: A WPF és az XAML
<Window x:class="SimplexamlPad.Mainwindow"
xmlns="http://schema's.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Simple XAMl viewer" Height="338" width="1041"
Loaded="Window_Loaded" Closed="Window_closed"
windowstartupLocation="Centerscreen">
<DockPanel LastchildFill="True" >
Először is vegyük észre, hogy a kezdeti <G rid> típust <DockPanel> típusra cse
réltük, amely egy Button (btnViewXaml névvel) és egy TextBox (txtXamlData
néven) típust foglal magában, és a kód kezeli a Button típus kattintási esemé
nyét. Azt is figyeljük meg, hogy a window Loaded és closed eseményeit a nyitó
<Window> elem kezeli. Ha a tervező segítségével kezeltük eseményeinket, a
524
XAML feldolgozása futásidöben: a SimpleXamlPad.exe
using System.ro;
using System.windows.Markup;
Megjegyzés Az XML-névteret képviselő, éppen készülö sztringet nem könnyű feladat beírni a
beágyazott idézőjelekhez szükséges vezérlőkarakterek miatt (gépeljünk körültekintöen!).
525
28. fejezet: A WPF és az XAML
526
XAML feldolgozása futásidőben: a SimpleXamlPad.exe
Vegyük észre, hogy a logika jelentős részét try/catch blokkba csomagoljuk lly
módon, ha a vourxaml.xaml fájl helytelen markupot tartalmaz, az eredmény
ként kapott üzenetdobozban láthatjuk a hibákat, amelyeket okoztunk
Az alkalmazás tesztelése
<StackPanel>
<Rectangle Fill = "Green" Height = "40" width = "200" />
<Button Content = "OK!" Height = "40" Width = "100" />
<Label content ="{x:Type Label}" />
</StackPanel>
527
28. fejezet: A WPF és az XAML
528
A Microsoft Expression Blend szerepe
529
28. fejezet: A WPF és az XAML
Összefoglalás
530
HUSZONKILENCEDIK FEJEZET
Programozás WPF
vezérlőelemekkel
Tabcontrol, TextBox,
RepeatButton,
RichTextBox, Label
Reader stb.), valamint (a Tablet PC fejlesztésekhez hasznos) Ink API-t támogató tí
pusokat és különböző rögzített párbeszédablakokat (PasswordBox, PrintDialog,
Megjegyzés A Fil eDialog, az OpenFi leDi alog és a save Fi l eDial og típusokat a Presen
tationFramework.dll szerelvény Microsoft. Win32 névtere definiálja.
532
A WPF vezérlőelem-könyvtár vizsgálata
Megjegyzés A könyv jelen kiadása nem tér ki az egyedi WPF felhasználói vezérlőelemekre és
WPF vezérlőelem-könyvtárakra. Ha szeretnénk többet megtudni a témakörről, további infor
mációért lapozzuk fel a .NET Framework 3.5 SDK dokumentációját.
l�
Toolbox
r - ·- -- - ......,....,... i
=,
· III Common CA>ntrols
i III CommonCA>ntllinen
;i[EJ MenuundTooiNors ' - 1
11 It Poínter
li' �.l- ContextMenu 1
� Menu t·:
l= StatusBar
� ToolBar
�{l
'
ToolSarTrwy
f
El Al CA>ntrols
It t
@
Poíntor
Button
!'
�
0 Checlc8ox
l
� ComboBox
l
ll& ComboBoxltom í
Ili!, ContentControl !
00 ContextMenu
�n �
�
�
29.1. ábra: A Visual Studio 2008 Toolbox mutatja a beépített WPF-vezérlőelemeket
533
29. fejezet: Programozás WPF·vezérlőelemekkel
Contents
j(nofoltor)
l .
i IfJ· Gett.ng Started
j B-- .NET Framework Development
l . 0 Microsoft .NET Framework 3.0 Programming Model
IfJ· .NET Framework Technologies
l : :��� Forms
á- Windows Presentation Foundation
r.)J· Getting Started
$. Application Development
ffi· WPF Fundamentals
ffi. Accessibility
B- Controls
�}-l§§ifi@
0--Border-
�)-- SuiletDecorator
0 -Button
�- Canvas
ffi-- CheckBox
ffi.ComboBox
29.2. ábra: Az egyes WPF-vezérlőelemek részletes leírása csak egtj gombnyomásnyira található (Fl)
534
Vezérlőelemek deklarálása a XAML ben -
</Expander>
<Expander Name="MakeExpander" Header = "Make">
<!-- Tételezzük fel, hogy itt szerepelnek az elemek . . . -->
</Expander>
<Expander Name="paymentExpander" Header = "Payment Plan">
<!-- Tételezzük fel, hogy itt szerepelnek az elemek . . . -->
</Expander>
535
29. fejezet: Programozás WPF-vezérlőelemekkel
</StackPanel>
</StackPanel>
</Button>
Együttműködés a vezérlőelemekkel
a forráskódfájlokban
536
Vezérlőelemek deklarálása a XAML-ben
<Button Name="btnPurchaseOptions"
Click="btnPurchaseOptions_click"
Height="lOO" Width = "300">
<IButton>
537
29. fejezet: Programozás WPF·vezérlőelemekkel
public Mainwindow()
{
Initializecomponent();
538
A függőségi tulajdonságok szerepe
539
29. fejezet: Programozás WPF-vezérlőelemekkel
A teljes igazsághoz hozzátartozik, hogy elég kicsi annak az esélye, hogy manu
álisan kelljen függőségi tulajdonságot létrehoznunk WPF-projektjeink során.
Valójában kizárólag akkor kell ezt megtennünk, ha olyan egyedi WPF-vezérlő
elemet hozunk létre, amelyhez alosztályként már létező vezérlőelemet adunk,
és így akarjuk annak viselkedését módosítani. Ebben az esetben, ha olyan tu
lajdonságot hozunk létre, amelynek WPF adatkötő motorral, térnamatorral
540
A függőségi tulajdonságok szerepe
541
29. fejezet: Programozás WPF-vezérlőelemekkel
HeightProperty = DependencyProperty.Register(
"Height",
typeof(double),
typeof(FrameworkElement),
new FrameworkPropertyMetadata((double) 1.0 l (do u ble) 0.0,
Framework PropertyMetadataoptions.AffectsMeasure,
new Propertychangedcallback(
FrameworkElement.OnTransformDirty)),
new va lidatevalu ecallback(
FrameworkElement.IsWidthHeightvalid));
Megjegyzés Emlékezzünk vissza, hogy a C# 2008 bővít ő metódusai ( lásd a 13. fejezetet) le·
hetövé teszik új tagok hozzáadását a lezárt típusokhoz. A bővítő metódusok jelentik a legköz
vetlenebb módszert a típusok bővitésére olyan új funkcionalitásokkal, amelyeknek nem kell WPF
központú szolgáltatásokban részt venniük (pl. animáció).
542
A függőségi tulajdonságok szerepe
Most, hogy már láttuk, hogy a függőségi tulajdonságok hogyan épülnek fel a
felszín alatt, tartsuk észben, hogy teljességgel lehetséges normál CLR-tulaj
donságok használata, amelyek ugyanazokat a szolgáltatásokat támogatják,
mint a WPF függőségi tulajdonságok (értesítések, statikus memóriafoglalás
stb.). Viszont ehhez nem kevés háttérkódolás szükséges, amelyet manuálisan
kell létrehoznunk, és sok helyen megismételnünk. A beépített DependencyPro
perty típus (és további infrastruktúradarabok) alkalmazásával ugyanezeknek
a szolgáltatásoknak a készen elérhető megvalósítását kapjuk.
543
29. fejezet: Programozás WPF-vezérlőelemekkel
DependencyProperty.Register("MyProperty", typeof(int),
typeof(ownerclass), new UIPropertyMetadata(O));
Továbbitott események
544
Továbbított események
Fancy Button!
c::>-
------
..
B
l OK
l
545
29. fejezet: Programozás WPF·vezérlőelemekkel
546
Továbbított események
Ezzel most már különböző műveletek történnek attól függően, hogy a vég
felhasználó hova kattintott (ami lényegében a külső ellipszis és a gomb ható
körén belül minden más hely).
gika megáll (ezért nem látha�uk, hogy a rendszer végrehaj�a a Button típus
kattintási eseménykezelőjét). Legtöbbször ez a kívánt hatás; azonban, ha arra
547
29. fejezet: Programozás WPF-vezérlőelemekkel
548
Továbbított események
public Mainwindow()
{
Initializecomponent();
}
� A végsősztring megjelenítése.
mouseActivity
+= "Button click event fired!\n";
MessageBox.Show(mouseActivity);
ll A "bugyborékolás" folytatódik!
e.Handled = false;
}
ll A "bugyborékolás" folytatódik!
e.Handled = false;
}
}
549
29. fejezet: Programozás WPF-vezérlőelemekkel
OK
550
A Button típusok használata
A ButtonBase tipus
551
29. fejezet: Programozás WPF·vezérlőelemekkel
Tételezzük fel például, hogy a következő XAML-kóddal írunk le egy Button tí
pust, melynek a clickMode tulajdonságát clickMode. Haver értékűre állitottuk
járás egy tipikus nyomógomb esetében, a "lebegés" (hover) mód hasznos le
het egyedi stílusok, sablonok vagy animációk készítésekor.
A Button tipus
Az első leszármazott típus, a Button, két azonnali érdeklődésre számot tartó tu
lajdonságot biztosít számunkra: az rscancel és az rsoefault tulajdonságot,
amelyek nagyon hasznosak, ha OK és Mégse gombokat tartalmazó párbeszéd
ablakokat hozunk létre. Amikor az rscancel értéke true, a gomb kattintási
eseménye elsül, ha a felhasználó megnyomja az Esc billentyűt. Ha az rsoefault
értéke true, a gomb kattintási eseménye elsül, ha a felhasználó megnyomja az
Enter billentyűt. Tekintsük meg a két Button típus következő XAML-leírását:
552
A Button típusok használata
A ToggleButton tipus
553
29. fejezet: Programozás WPF·vezérlőelemekkel
A RepeatButton tipus
554
A Button típusok használata
.<Window x:class="CustomspinButtonApp.Mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CustomSpinButtonApp" Height="300" width="300">
<StackPanel>
<!-- A "Fel" gomb -->
<RepeatButton Height ="25" Width = "25"
Name ="repeatAddvalueButton"
Delay ="200" Interval ="l"
click ="repeatAddvalueButton_click"
content = "+"/>
555
29. fejezet: Programozás WPF-vezérlőelemekkel
public Mainwindow()
{
Initializecomponent();
lblcurrentvalue.Content = currvalue;
}
protected void repeatAddvalueButton_click(object sender,
RoutedEventArgs e)
{
ll Hozzáad egyet az aktuális értékhez, és megmutatja a címkében.
currvalue++;
lblcurrentvalue.Content = currvalue;
}
�
l
l o
8
ll
29.6. ábra: Léptetőgomb készítése, kezdőpontként a RepeatButton használatával
A jelölőnégyzetek és a rádiógembek
használata
"
Ahogy korábban említettük, a CheckBox "az-egy ToggleButton, "az-egy
ButtonBase, ami elég különösnek tűnhet, mivel egy gomb felhasználói felülete
meglehetősen különbözik egy jelölőnégyzetétőL Azonban, ha a ch e ckB ox tí-
556
A jelölőnégyzetek és a rádiógombok használata
<StackPanel>
<!-- checkBox típusok -->
<CheckBox Name ="checkrnfo" >Send me more information</CheckBox>
<CheckBox Name ="checkPhonecontact" >Contact me over the
phone</CheckBox>
</StackPanel>
<StackPanel>
<!-- R�dioButton típusok zeneválasztáshoz -->
<Label Fontsize = "15" Content = "select Your Music Media"/>
<RadioButton>CD Player</RadioButton>
<RadioButton>MP3 Player</RadioButton>
<RadioButton>8-Track</RadioButton>
557
29. fejezet: Programozás WPF·vezérlőelemekkel
<StackPanel>
<!-- A zene csoport -->
<Label Fontsize = "15" content "select Your Music Media"/>
<RadioButton GroupName "Music" >CD Player</RadioButton>
<RadioButton GroupName "Music" >MP3 Player</RadioButton>
<RadioButton GroupName "Music" >8-Track</RadioButton>
558
A jelölőnégyzetek és a rádiógombok használata
<StackPanel>
<GroupBox Header = "select vour Music Media" BorderBrush ="Black">
<StackPanel>
<RadioButton GroupName "Music" >CD Player</RadioButton>
<RadioButton GroupName "Music" >MP3 Player</RadioButton>
<RadioButton GroupName "Music" >8-Track</RadioButton>
</StackPanel>
</GroupBOX>
<StackPanel>
<Expander Header = "select Your Music Media" BorderBrush ="Black">
<StackPanel>
<RadioButton GroupName "Music" >CD Player</RadioButton>
<RadioButton GroupName "Music" >MP3 Player</RadioButton>
559
29. fejezet: Programozás WPF-vezérlőelemekkel
560
A ListBox és a ComboBox típusok használata
a következő XAML-kódot:
Sony PSP It
Niniendo DS
561
29. fejezet: Programozás WPF-vezérlőelemekkel
<Window x:class="Listcontrols.Mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Listcontrols" Height="300" Width="300" >
<StackPanel>
<!-- Ezt kód segítségével töltjük fel -->
<ListBox Name = "lstvideoGameconsoles">
</ListBOX>
</StackPanel>
</Window>
562
A ListBox és a ComboBox típusok használata
<StackPanel>
<!-- Egy ListBox tartalommal -->
<ListBox Name = "lstcolors">
<StackPanel Orientation ="Horizontal">
<Ellipse Fill ="Yellow" Height ="50" Width ="50"/>
<Label Fontsize ="20" HorizontalAlignment="Center"
verticalAlignment="Center">Yellow</Label>
</StackPanel>
<StackPanel Orientation ="Horizontal">
563
29. fejezet: Programozás WPF-vezérlőelemekkel
j} ListControl<
Pick a Color
Yellow
dés az, hogy futásidőben hogyan lehet eldönteni, melyik elemet választotta
ki a felhasználó. Mint látni fogjuk, erre három módszer létezik. Ha a kiválasz
tott elem numerikus indexének a kiclerítése érdekel bennünket, akkor hasz
nálhatjuk a selectedindex tulajdonságot (amely nulla alapú; a -1 érték azt
mutatja, hogy nincs kijelölés). Ha a listában a kiválasztott objektumot szeret
nénk megszerezni, arra a selecteditem tulajdonság való. Végül, a selected
value lehetővé teszi, hogy a kiválasztott objektum értékét megkapjuk (több
564
A ListBox és a ComboBox típusok használata
Selectedlndex = 2
Selecteditem = Niniendo Woi
Select�alue = Nintendo Wii
OK
565
29. fejezet: Programozás WPF-vezérlőelemekkel
Solectedlnd<>< = O
S..lectedltem = S ystem.Windows.Controls.StackPanel
S..lectedValue = S ystom.Windows.Controls.StackPanel
OK
((Label)(selectedStack.Children[l])).Content.ToString();
string data string.Empty;
=
lstcolors.selectedrndex);
data += string. Format("Col or {O}", color); =
566
A ListBox és a ComboBox típusok használata
</StackPanel>
<StackPanel orientation ="Horizontal" Tag ="Blue">
</StackPanel>
<StackPanel Orientation ="Horizontal" Tag ="Green">
</StackPanel>
</ListBOX>
567
29. fejezet: Programozás WPF-vezérlőelemekkel
A WPF TextBox típusának egyik nagyon egyedi jellemzője, hogy beépített képes
sége révén ellenőrizheti a bevitt adatok helyesírását, ha a spellcheck.rsEnabled
tulajdonság értéke true. llyen esetekben látni fogjuk, hogy- a Microsoft Office
hoz hasonlóan - a helytelenül írt szavakat az alkalmazás vörös hullámos vonallal
aláhúzza. Ennél még jobb, hogy az alapul szolgáló programozási modell segítsé
gével hozzáférhetünk a helyesírásellenőrző-motorhoz, ezáltal megkapha�uk a
helytelenül írt szavakra vonatkozó javaslatok listáját.
Az alábbiak szerint módosítsuk az aktuális ablak XAML-definícióját, hogy
használhassuk a Label, a TextBox és a Button típusokat (figyeljük meg, hogy a
TextBox többsoros szövegeket támogat, és engedélyezi a helyesírás-ellenőrzést):
<Window x:class="Textcontrols.Mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Textcontrols" Height="204" width="292" >
<StackPanel>
<Label Fontsize ="15">Is this word spelled correctly?</Label>
568
A többsoros szövegbeviteli mezők használata
569
29. fejezet: Programozás WPF-vezérlőelemekkel
l
l OK
l
�
<StackPanel>
<Label Fontsize ="15">Is this word spelled correctly?</Label>
<TextBox Spellcheck.IsEnabled ="True" AcceptsReturn ="True"
Name ="txtFavoritecolor" Fontsize ="14"
BorderBrush ="Blue" Height ="100">
</TextBOX>
<StackPanel orientation ="Horizontal">
<PasswordBox Name ="pwdText" BorderBrush ="Black"
Width ="100"></PasswordBox>
<Button Name ="btnOK" content ="Get selections"
width = "100" click ="btnOK_Click"/>
</StackPanel>
</StackPanel>
570
A többsoros szövegbeviteli mezök használata
571
29. fejezet: Programozás WPF·vezérlőelemekkel
<Window x:class="MyWPFApp.Mainwindow"
xmlns="ht:t:p://schemas.microsoft:.com/winfx/2006/xaml/present:at:ion"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Fun with Panels!" Height="285" Width="325">
<Button Name="btnOK" Height = "100" Width="80">0K</Button>
</WindoW>
572
A tartalomelrendezés kezelése panelek használatával
Nyilvánvaló, hogy nem sok haszna van egy olyan ablaknak, amely csak egy
elemet tartalmazhat. Ha arra van szükség, hogy egy ablak több elemet tartal
mazzon, akkor azokat tetszőleges számú panelbe kell rendeznünk. A panel tar
talmazza az ablakot képviselő felhasználóifelület-elemeket, amely után a pa
nelt magát csak a content tulajdonsághoz rendelt objektumként használjuk.
573
29. fejezet: Programozás WPF-vezérlőelemekkel
canvas "
"Klasszikus mód a tartalom elhelyezésére. Az elemek pontosan
ugyanott maradnak, ahová a tervezéskor tettük őket.
D ockP anel Zárolja a tartalmat a panel megadott oldalára (Top, Bottom, Left
vagy Ri ght).
l � FunWithPa�ls
574
A tartalomelrendezés kezelése panelek használatával
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Fun with Panels!" Height="285" width="325">
<Canvas Background="LightsteelBlue">
<Button canvas.Left="212" canvas.Top="203" Name="btnOK"
width="80">0K</Button>
<Label Canvas.Left="17" canvas.Top="14" Name="lblinstructions"
width="328" Height="27"
Fontsi ze="15">Enter car Information</Label>
<Label canvas.Left="17" canvas.Top="60"
Name="lblMake">Make</Label>
<TextBox Canvas.Left="94" canvas.Top="60" Name="txtMake"
width="193" Height="25"/>
<Label canvas.Left="17" canvas.Top="109"
Name="lblcolor">Color</Label>
<TextBox canvas.Left="94" Canvas.Top="107" Name="txtcolor"
width="193" Height="25"/>
<Label canvas.Left="17" canvas.Top="155"
Name="lblPetName">Pet Name</Label>
<TextBox canvas.Left="94" Canvas.Top="153" Name="txtPetName"
width="193" Height="25"/>
</Canvas>
</Window>
Ebben a példában a <Canvas> hatókörén belül lévő összes elemet egy canvas.Left
és egy canvas. Top érték rninősít, amelyek a tartalom felső és bal oldali elhelyez
kedését vezérlik a panelen belül, a csatolt tulajdonságszintaxis használatával
Qásd a 28. fejezetet). Ahogy kitalálhattuk, a függőleges elhelyezkedést a Top, il
letve a Bottom tulajdonság, rníg a vízszintes elhelyezkedést a Left, illetve a Right
tulajdonság vezérli.
575
29. fejezet: Programozás WPF-vezérlőelemekkel
Mivel minden vezérlőt a <Canvas> elemen belül helyeztünk el, látni fog
juk, hogy az ablak átméretezésekor a rendszer eltakarja a vezérlőket, ha a tá
roló területe kisebb lesz, mint a tartalom (lásd a 29.17. ábrát).
29. 17. ábra : A Canvas panel tartalma lehetővé teszi az abszolút pozícionálást
<Canvas Background="Light:St:eelBlue">
<Text:Box Canvas.Left:="94" Canvas.Top="153" Name="t:xtcolor"
widt:h="193" Height:="25"/>
<TextBox canvas.Left="94" canvas.Top="60" Name="txtPetName"
width="193" Height:="25"/>
<TextBox Canvas.Left="94" Canvas.Top="107" Name="txtMake"
width="193" Height="25"/>
<Label canvas.Left="17" canvas.Top="14" Name="lblinstructions"
widt:h="328" Height:="27"
Fontsize="lS">Enter car Informat:ion</Label>
<Label Canvas.Left="17" Canvas.Top="109"
Name="lblcolor">Color</Label>
<Label canvas.Left="17" canvas.Top="155"
Name="lblMake">Pet: Name</Label>
<Label canvas.Left="17" canvas.Top="60"
Name="lblPet:Name">Make</Label>
Megjegyzés Ha egy canvas típuson belüli részelemek nem határoznak meg adott helyet a
csatolt tulajdonságszintaxis révén, akkor azok automatikusan a bal felső sarokba kerülnek.
576
A tartalomel rendezés kezelése panelek használatával
<WrapPanel Background="LightsteelBlue">
<Label Name="lblinstruction" Width="328"
Height="27" Fontsize="15">Enter car rnformation</Label>
<Label Name="lblMake">Make</Label>
<TextBox Name="txtMake" width="193" Height="25"/>
<Label Name="lblcolor">Color</Label>
<TextBox Name="txtcolor" width="193" Height="25"/>
<Label Name="lblPetName">Pet Name</Label>
<TextBox Name="txtPetName" width="193" Height="25"/>
<Button Name="btnOK" width="80">0K</Button>
</WrapPanel>
577
29. fejezet: Programozás WPF-vezérlöelemekkel
fj FunWithPanels l= l @íiflij
&Iter Car Information .......
JColor� l
PetHamel l OK
r
29.18. ábra: Eí51J WrapPanel panelben a tartalom Úí51J viselkedik, mint eí51J közönséges HTML-oldal
.
!J FunWithPanels ,-... l= l (ID ...
· c;m;. 1
Enler Car Jnrurmation ...
l
Color
J �Pet,._
l [ OK
l
29. 19. ábra: A WrapPanel megállapíthatja eí51J adott elem szélességét és magasságát
578
A tar talomelrendezés kezelése panelek használatával
fi FunWithPanels
<StackPanel Background="Lightsteelslue">
<Label Name="lblrnstruction"
Fontsize="15">Enter car rnformation</Label>
<Label Name="lblMake">Mak e</Label>
<TextBox Name="txtMake"/>
<Label Name="lblcolor">Color</Label>
<Textsox Name="txtcolor"/>
579
29. fejezet: Programozás WPF·vezérlöelemekkel
l
] FunWithPanels
580
A tartalomelrendezés kezelése panelek használatával
Megjegyzés Ha nem határozunk meg sorokat vagy oszlopokat, akkor a <G ri d> alapértelme
zés szerint egyetlen cella, amely kitölti az ablak teljes felületét. Továbbá, ha nem rendelünk
hozzá cellaértéket egy részelemhez a <G ri d> típuson belül, akkor az automatikusan a O. osz
lop O. sorába kerül.
<Grid.columnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.columnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Rec tan gle Fill ="LightGreen" Grid.column ="l" Grid.Row ="l" />
<Label Name="lblPetName" Grid.column ="l"
Grid.Row ="l" >Pet Name</Label>
<TextBox Name="txtPetName" Grid.Column ="l" Grid.Row ="l"
width="l93" Height="25"/>
</Grid>
581
29. fejezet: Programozás WPF-vezérlőelemekkel
Íl FunWrthPanels r= 1 @J liiiEiiil.
E"' -"'
1--' n
e
t"--
r .::e;
Ca",_r..!:Jn"'-fo"_,r_,_,m: .:::a_"_
t
io::-.:"__
n
:
_--i M_a_
k_e
________ .
OK
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FunwithPanels" Height="191" Width="436">
<Grid Background ="AliceBlue">
<!-- Az oszlopok meghatározása -->
<Grid.columnDefinitions>
<ColumnDefinition width ="Auto"/>
<ColumnDefinition/>
</Grid.columnDefinitions>
582
A tartalomelrendezés kezelése panelek használatával
Left! Ríght!
()=()
583
29. fejezet: Programozás WPF-vezérlőelemekkel
Make Color
OK ---
Pet Name
Megjegyzés Ha több elemet adunk hozzá egy DockPanel ugyanazon oldalához, azokat a
megadott oldal mellett a deklaráció sorrendjében halmozza fel a rendszer.
<Scrollviewer>
<St:ackPanel>
<But:t:on content: ="First" Background = "Green" Height: ="40"/>
<But:t:on content: ="Second" Background = "Red" Height: ="40"/>
<But:t:on Content: ="Third" Background = "Pink" Height: ="40"/>
<But:t:on content: ="Fourt:h" Background = "Yellow" Height: ="40"/>
<But:t:on Content ="Fift:h" Background = "Blue" Height: ="40"/>
</St:ackPanel>
</Scrollviewer>
584
Ablak kereteinek készítése beágyazott panelek használatával
l :. ..
Ahogy várhaljuk, minden panel több tagot biztosít, amelyek lehetővé teszik a
tartalom elhelyezésének finomhangolását. Ehhez kapcsolódó megjegyzés, hogy
a WPF-vezérlőelemek mindegyike két érdekes tulajdonságot ( Padding és Margin)
támogat, amelyek segítségével maga a vezérlőelem tájékoztathalja a panelt arról,
hogy rnilyen bánásmódot igényel. Pontosabban a Padding tulajdonság szabá
lyozza, hogy mekkora plusz hely vegye körül a belső vezérlőelemet, míg a
Margin szabályazza a vezérlőelem külső részét körülvevő extra helyet.
585
29. fejezet: Programozás WPF-vezérlőelemekkel
i]MySpeiiChecke< Tc::ri§Jii:iir
File Tools
i Exti !�
The previous chapter provided
Spelling Hints
a foundation for the lrY.fE
programming model.
0Tryth6e!
induding an examination of
CALM the Window and Application
AXEL
types as weil as several
UXMAL
details regarding the
BALM
PALM Extendable Application Markup
AM Language�.
AMYL
EXAM
CAMEL
DAM
- -- -- ·---------- � - - - �- --·
29.26. ábra: Beágyazott panelek használata egtj ablak felhasználói felületének létrehozásához
Figyeljük meg, hogy a két eszköztárgombunk nem egy várt képet, hanem egy
egyszerű szöveges értéket jelenít meg. Noha ez nem lenne elegendő egy termék
szintü alkalmazáshoz, képek hozzárendelése az eszköztár gombjaihoz általában
beágyazott erőforrások használatát igényli, amelynek témakörét a 30. fejezetben
fogjuk megvizsgálni (tehát most megteszi a szöveges adat). Azt is vegyük észre,
hogy amikor az egér a Check button fölé kerül, a kurzor megváltozik, az állapot
sáv egyetlen panele hasznos felhasználóifelület-üzenetet jelenít meg.
A felület készítésének megkezdéséhez módosítsuk a window típusunk kez
deti XAML-definícióját, hogy <DockPanel> gyermekelemet használjon <Grid>
helyett:
<Window x:class="MySpellchecker.Mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Myspellchecker" Height="331" width="508"
WindowstartupLocation ="Centerscreen" >
<DockPanel>
</DockPanel>
</WindoW>
586
Ablak kereteinek készítése beágyazott panelek használatával
A menürendszer készítése
587
29. fejezet: Programozás WPF-vezérlőelemekkel
588
Ablak kereteinek készítése beágyazott panelek használatával
A <Too lBar> típusunk két Bu tton típust tartalmaz, amelyek történetesen ugyan
azokat az eseményeket kezelik, és a kódfájlunk ugyanazon metódusai kezelik
őket. A módszer segítségével összerakhaljuk az eseménykezelőinket, hogy ki
szolgálják núnd a menüelemeket, núnd az eszköztárgombokat Noha ez az esz
köztár tipikus nyomógombokat használ, tudnunk kell, hogy a ToolBar típus "az
egy" contentcontra l, ezért nyugodtan beágyazhatunk bármilyen típust a felüle
tébe (legördülő listákat, képeket, grafikákat stb.). Az egyetlen érdekes pont az,
hogy a Check gomb egyedi egérkurzot támogat a cursor tulajdonság révén.
Megjegyzés A Too l Bar típus tetszés szerint becsomagolható <Too l BarTray> elembe, amely
Too l Bar objektumok esetében szabályazza az elrendezést, a dokkolást és a húzd·és-dobd müve
leteket. További részletekért forduljunk a .NET Framework 3.5 SDK dokumentációjához.
Ezen a ponton a Visual Studio tervezőjének valahogy úgy kell kinéznie, núnt
a 29.27. ábrán látható képnek.
589
29. fejezet: Programozás WPF-vezérlöelemekkel
n
!
'
. ,,
i1
l
m""
--= "'·= ·:ll
a=
·n_� Design ./�t.,..•-/..".= t
== =
XA --
�
M �
.. - - - -- -
- --·- ---- ----------
s oo
--------------------�� 1
: �-
1 3: I t-e
- � -:- � -
- -· d --- 7 . � -7
,.- - �
<M u�
n_
e_
L_ m Hea er Ex i t
..
.t�i�oi·�
_
1 9: -
.
-
..
</Henuitem>
<l'1en"üi't'eiii Header="_Tools">
<Menuitem Header ="_Spelling Hints"
• t'
.. _""�
-- - ------"'
- -
· "--
""� ' ;---��--��-- -·r--
...
590
Ablak kereteinek készítése beágyazott panelek használatával
A megvalósitás véglegesitése
591
29. fejezet: Programozás WPF·vezérlőelemekkel
if (error != null)
{
ll Készítsük el a helyesírási javaslatok sztringjét.
foreach (string s in error.Suggestions)
{
sp ell i n gH ints += string.Format(" { O } \n", s) ;
}
ll Bontsuk ki a bővítőt.
expanderspelling.IsExpanded tru e;
}
}
protected void MouseEnterExitArea(object sender,
RoutedEventArgs args)
{
statBarText.Text = "Exit the Application";
}
protected void Mous eEnt erToo l s H intsAre a(object sender,
RoutedEventArgs args)
{
statBarText.Text = "Show spelling Suggestions";
}
protected void MouseL e aveAr e a(ob ject sender, Rout edEventAr gs args)
{
statBarText.Text = "Re ady";
}
}
Készen vagyunk! Mindössze néhány sornyi imperatív kóddal (és egy egészsé
ges adag XAML-lel) elkészültek egy működő szövegszerkesztő alapjai. Ahhoz,
hogy még érdekesebbé tegyük, meg kell ismerkednünk a vezérlő utasításokkal.
A WPF vezérlőutasításai
592
A WPF vezérlőutasításai
593
29. fejezet: Programozás WPF-vezérlöelemekkel
594
A WPF vezérlőutasításai
<Menurtem Header="_Tools">
<Menurtem Header ="_Spelling Hints"
MouseEnter ="MouseEnterToolsHintsArea"
MauseLeave ="MouseLeaveArea"
click ="ToolsSpellingHints_click"/>
</Menurtem>
</Menu>
595
29. fejezet: Programozás WPF-vezérlőelemekkel
�l
File EditJ Toals
: Exit Copy Ctri+C
0Tryth.S.!
Ready
new CommandBinding(Applicationcommands.Help);
helpBinding.canExecute += CanHelpExecute;
helpBinding.Executed += HelpExecuted;
commandBindings.Add(helpBinding);
}
596
A WPF vezérlőutasításai
l
IL Q� -j
___ __
Ready
597
29. fejezet: Programozás WPF-vezérlőelemekkel
ságának alapján.
A belső WPF adatkötési motor használata során tisztában kell lennünk a kötési
művelet forrása és célja közötti különbséggel. Ahogyan várha�uk, egy adatköté
si művelet forrása maga az adat (egy Boolean tulajdonság, relációs adat stb.),
núg a cél (vagy célpont) az a felhasználói felületi vezérlőelem-tulajdonság,
amely az adattartalmat használja majd (egy checkBox, egy TextBox stb.).
598
A WPF adatkötési modell
Ismerkedés az adatkötéssel
<Window x:class="SimpleDataBinding.Mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Simple Data Binding" Height="152" width="300"
WindowstartupLocation="CenterScreen">
<StackPanel width="250">
<Label Content="Move the scroll bar to see the current value"/>
599
29. fejezet: Programozás WPF·vezérlőelemekkel
A DataContext tulajdonság
600
A WPF adatkötési modell
70
--EI-i·c·k--
A Mode tulajdonság
601
29. fejezet: Programozás WPF·vezérlőelemekkel
Adatátalakitás az IValueConverter
segitségével
terfész két olyan tagot definiál, amelyek lehetővé teszik a kétirányú konverzió
elvégzését a célpont és a cél között. Amint meghatároztuk ezt az osztályt, se
gítségéve! tovább minősíthetjük az adatkötési műveletünk feldolgozását.
Megjegyzés Noha bármely adatkötési művelet megvalósítható pusztán imperatív kód haszná·
latával, a következő példák a XAML segítségével konvertálják az adattípusokat. Ehhez szükség
van egyedi erőforrások bevonására, amelyeket részletesen a 30. fejezetben vizsgálunk meg.
Ne nyugtalankodjunk, ha a markup egy része nem tűnik ismerősnek.
602
Adatátalakítás az IValueConverter segítségével
603
29. fejezet: Programozás WPF-vezérlőelemekkel
<Window x:Class="SimpleDat:aBinding.Mainwindow"
xmlns="ht:t:p://schemas.microsoft:.com/winfx/2006/xaml/present:at:ion"
xmlns:x="ht:t:p://schemas.microsoft:.com/winfx/2006/xaml"
<Window.Resources>
<myConvert:ers:MyDoubleconvert:er x:Key="Doubleconvert:er"/>
</Window.Resources>
</St:ackPanel>
</Window>
604
Adatátalakítás az IValueConverter segítségével
<Window.Resources>
<myconverters:MyDoubleconverter x:Key="DoubleConverter"l>
<myconverters:Mycolorconverter x:Key="Colorconverter"l>
<IWindow.Resources>
605
29. fejezet: Programozás WPF-vezérlöelemekkel
<Window x:Class="CarviewerApp.Mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Car Viewer Application" Height="294" width="502"
ResizeMode="NoResize" WindowstartupLocation="CenterScreen"
Loaded="Window_Loaded">
<Grid>
<Grid.columnoefinitions>
<Columnoefinition Width="200"/>
<Columnoefinition width="*"/>
</Grid.columnoefinitions>
<Grid.RowDefinitions>
<Rowoefinition Height="Auto"/>
<Rowoefinition Height="*"/>
</Grid.Rowoefinitions>
</Grid>
</Window>
606
Kötés egyedi objektumokhoz
A <Grid> első sora tartalmaz egy menürendszert File menüvel, amelyben két
almenü van (Add New Car és Exit). Vegyük észre, hogy kezeljük minden
almenü kattintási eseményét, és hozzárendelünk egy "beviteli mozdulatot" az
Exit menühöz, lehetővé téve az elem aktiválását, ha a felhasználó megnyomja az
Alt+ F4 billentyűkombinációt. Végül figyeljük meg, hogy a Grid.columnspan ér
téke 2, amely lehetővé teszi a menürendszer elhelyezését az első sor celláiban.
A <Grid> fennmaradó bal oldali része egy ListBox típust tartalmazó <Dock
Panel>, míg a jobb oldali rész egyetlen TextBlack típust foglal magában.
A ListBox típus lesz végül az egyedi objektumok gyűjteményét magába fog
laló adatkötési művelet célja, úgyhogy állítsuk be az Itemssource tulajdonsá
got a {Binding} jelölő kiterjesztésre (a kötés forrását hamarosan kódban adjuk
meg). Ahogy a felhasználó kiválaszt egy elemet a ListBox típusból, rögzítjük
a se l ectionchanged eseményt, hogy frissíthessük a tartalmat a TextBlock tí
pusban. Itt van a fennmaradó típusok definíciója:
607
29. fejezet: Programozás WPF-vezérlőelemekkel
p;'
using System;
using System.Collections.objectModel;
namespace carviewerApp
{
public class carList observablecollection<Car>
{
608
Kötés egyedi objektumokhoz
public carListO
{
ll Néhány bejegyzés hozzáadása a listához.
Add(new Car(40, "BMW", "Black", "sidd"));
Add(new car(SS, "'vw", "Black", "Mary"));
Add(new car(lOO, "Ford", "Tan", "Mel"));
Add(new car(O, "Yugo", "Green", "clunker"));
}
}
609
29. fejezet: Programozás WPF·vezérlőelemekkel
·L __
lll l •
<Lis-t:Box Grid.column="O"
Grid.Row="2" Name="allcars"
selectionchanged="Listrtemselected"
Background="LightBlue" Itemssource="{Binding}">
<ListBox.rtemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse Height="lO" width="lO" Fill="Blue"/>
<TextBlock Fontstyle="rtalic" Fontsize="14"
Text="{Binding Path=PetName}"/>
</StackPanel>
</DataTemplate>
</ListBox.rtemTemplate>
</ListBOX>
610
A felhasználói felület elemeinek kötése XML-dokumentumokhoz
611
29. fejezet: Programozás WPF-vezérlőelemekkel
<Window x:class="CarviewerApp.AddNewcaroialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AddNewcarDialog" Height="234" width="529"
ResizeMode="NoResize" windowstartupLocation="CenterScreen" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="144" />
<RowDefinition Height="51" />
</Grid.RowDefinitions>
612
A felhasználói felület elemeinek kötése XML-dokumentumokhoz
</Gridview>
</Listview.view>
</Listview>
<WrapPanel Grid.Row="l">
<Label content="Select a Row to Add to your car collection"
Margin="lO" />
<Button Name="btnOK" Content="OK" width="80" Height="25"
Margin="lO" IsDefault="True" Tabrndex="l"
click="btnOK_Click"/>
<Button Name="btncancel" content="Cancel" width="80"
Height="25" Margin="lO" IsCancel="True" Tabrndex="2"/>
</WrapPanel>
</Grid>
</Window>
613
29. fejezet: Programozás WPF-vezérlöelemekkel
614
A felhasználói felület elemeinek kötése XML-dokumentumokhoz
Vegyük észre, hogy xmlEl ement: típusra kasztoltuk a sel ect:edrt:em tulajdonság
(amely syst:em.object: típusú) visszatérési értékét. Ez azért lehetséges, mert a
List:view típusunk valóban kapcsolódik az rnvent:ory.xml fájlhoz az adatkötési
műveletünk révén. Amint elcsíptük az aktuális xmlEl emen t: típust, hozzáfér
hetünk a Make, a color és a PetName elemekhez (a típusindexelő használatá
val), és kibonthatjuk az értékeket az Innenext meghívásával.
Megjegyzés Ha soha nem dolgoztunk a system.Xml névtér típusaival, akkor elég azt tud
nunk, hogy az Innenext tulajdonság m�gszerzi az értéket egy XML-csomópont nyitó és záró
elemei között. Például a <Make>Ford</Make> belső szövege Ford lenne.
615
29. fejezet: Programozás WPF-vezérlőelemekkel
WI/ Silver
616
Összefoglalás
Összefoglalás
617
HARMINCADIK FEJEZET
Megjegyzés A 28. fejezetből emlékezhetünk arra, hogy a WPF széles körű támogatást bizto·
sít a háromdimenziós programozás számára. Ez a téma azonban e könyv hatókörén kívül esik,
ha a WPF ezen funkciójával kapcsolatban további részletekre lenne szükségünk, érdemes elol·
vasnunk Matthew MacDonald Pro WPF in C# 2008: Windows Presentation Foundation with .NET
3.5, Second Edition (Apress, 2008) című könyvét.
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
620
A WPF grafikus renderetési szolgáltatásának filozófiája
<Window x:class="WPFGraphicsoptions.Mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPFGraphicsOptions" Height="300" width="300" >
<StackPanel>
</StackPanel>
</Window>
621
30. fejezet: WPF 2D grafikus renderelés, erőforrá sok és témák
A System. windows. shapes névtér tagjai (Ellipse, L i ne, Path, Pol ygon, Po l y l i ne
á� Shape
é-D Base Types
éJ. ..� FramoworkEiement
$...-o lFramework:InputEiement
: ·· -<> llnputEiement
!···'"" ISupportlnitialize
á'!$ U!Element
.
L . _., IAnimatable
: .. ...." DnputEiement
G·� Visual
B·� DependencyObject
á··"!$ DispatcherObject
L.� Object
30. 1. ábra: A Shape leszármazott típusai átfogó funkcionalitást örökölnek szülótípusaiktól
622
A WPF grafikus renderetési szolgáltatásának filozófiája
$-�DDJ
i 8 Q Base Types
. Ó·<1$ Anímatable
G··� Freezable
. 9 ..� OependencyObject
8-·<1$ DíspatcherObject
L� Object
L._._" lAnímatable
30. 2. ábra: A Drawing leszármazott típusai jóval egyszerűbbek, mint a Shape leszármazott típusai
623
30. fejezet: WPF 2D grafikus renderelés, erőforrások és témák
624
A WPF grafikus renderetési szolgáltatá sának filozófiája
$'t:-
' EH:::l Base Types
ÉJ·'f: DependencyObject
8-� DispatcherObject
L� Object
/*
public partial class Mainwindow : System.windows.window
{
public Mainwindow()
{
In itializecompon ent();
}
}
*/
625
30. fejezet: WPF 2D grafikus renderelés, erőforrások és témák
public Mainwindow()
{
Initializecomponent();
{
ll A téglalap felső, bal oldali, alsó és jobb oldali
ll pozíciója.
Rect rect = new Rect(50, 50, 105, 55);
drawctx.DrawRectangle(Brushes.AliceBlue,
new Pen(Brushes.Blue, 5), rect);
}
626
A WPF grafikus renderetési szolgáltatásának filozófiája
627
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
628
A WPF grafikus renderetési szolgáltatásának filozófiája
!] WPFGraphicsOptions l=·1-§--.:tilf
629
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
<Window x:class="Someshapes.Mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" width="300" >
630
A Shape leszármazott típusainak felfedezése
líthatjuk be.
631
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
<StackPanel>
<!-- A sor ellenőrzi, hogy az alakzat területére húztuk-e
az egeret -->
<Line Name ="SimpleLine" X1 ="0" X2 ="50" Y1 ="0" Y2 ="50"
Stroke ="DarkoliveGreen" StrokeThickness ="5"
ToolTip ="This is a line!"
MouseEnter ="SimpleLine_MouseEnter"/>
632
A WPF-ecsettípusok használata
Z\
30. 5. ábra: Renderell Shape-leszármazott típusok
A WPF-ecsettipusok használata
Brush osztályt bővíti ki. A Brush absztrakt osztály, azonban a 30.2. táblázatban
ismertetett leszármazottainak a segítségével egy területet az összes rendelkezé
sünkre álló opció felhasználásával kitölthetünk
egy területet.
633
30. fejezet: WPF 2D grafikus renderelés, erőforrások és témák
:
.. ' . ' -,.. ' .. '� '
�' . '�
rületet
Megjegyzés Mivel nem kezelnek eseményeket, a következő példákat közvetlenül a 28. feje·
zetben elkészített XAML·nézegetőbe írhatjuk, és nem kell új Visual Studio 2008 WPF projekt·
munkaterületeket létrehoznunk az alkalmazásban.
634
A WPF-ecsettípusok használata
lehetővé teszi, hogy két (vagy több) szín átmenetével töltsünk ki egy terüle
tet. A két típus között annyi a különbség, hogy amíg a LinearGradi entBrush
635
30. fejezet : WPF 2D grafikus renderelés, erőforrások és témák
Az lmageBrush tipus
Mint a neve is sugallja, a típus lehetővé teszi, hogy külső képfájlt (vagy beágya
zott képerőforrást) töltsünk be az ecsettípus alapjaként Ahhoz, hogy egy külső
fájlt rendeljünk az rmageBrush típushoz, az egyik lehetőség az, ha az rmagesource
636
A WPF-tollak használata
A WPF-tollak használata
637
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
638
A Drawing leszármazott típusainak vizsgálata
639
30. fejezet: WPF 2D grafikus renderelés, erőforrások és témák
ti cBeziersegment és QuadraticBeziersegment.
640
A Drawing leszármazott típusainak vizsgálata
641
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
<Image>
<Image.source>
<Drawingimage>
<Drawingimage.Drawing>
<GeometryDrawing Brush ="LightBlue">
</GeometryDrawing>
</Drawingimage.Drawing>
</Drawingimage>
</Image.source>
</Image>
<Window x:class="FunwithDrawingAndGeometries.Mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FunwithDrawingAndGeometries" Height="190" Width="224">
642
A Drawing leszármazott típusainak vizsgálata
<Image> ,
<Image.Source>
<Drawingimage>
<Drawingimage.Drawing>
<!-- Különböző geometriák csoportja -->
<DrawingGroup>
<Geometryorawing>
<Geometryorawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0,0,20,20" />
<RectangleGeometry Rect="160,120,20,20" />
<EllipseGeometry center="75,75" RadiusX="50"
RadiusY="50" />
<LineGeometry startPoint="75,75"
EndPoint="lBO,O" />
</GeometryGroup>
</GeometryDrawing.Geometry>
<!-- Egyedi toll, amellyel megrajzoljuk a
határvonalakat -->
<Geometryorawing.Pen>
<Pen Thickness="lO" LineJoin="Round"
EndLinecap="Triangle" StartLinecap="Round">
<Pen.Brush>
<LinearGradientBrush>
<GradientStop offset="O.O" Color="Red" />
<Gradientstop offset="l.O" color="Green" />
</LinearGradientBrush>
</Pen.Brush>
</Pen>
</Geometryorawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</Drawingimage.Drawing>
</Drawingimage>
</Image.source>
</Image>
643
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
a
30.7. ábra: DrawingGroup típust tartalmazó kép
Ahhoz, hogy a Pen típus Dashstyl e típust - például a (korábban látott) Dash
Styles.DashDotDot típust - alkalmazzon, a kódot a következőképpen kell
módosítani:
•
-=-.
•
2
•• 4I'
.�
l , l
• •
• •
7 7
-=-
30.8. ábra: Pen típus, amely vonás-pont-pont beállítással rendelkező DashStyle típussal dolgozik
644
A felhaszná lóifelület-transzformációk szerepe
A felhasználóifelü let-transzformációk
szerepe
A Transform-leszármazott tipusok
·:_,.
�\-��-;��·J�_ .
MatrixTransform Tetszőleges mátrixtranszformációt hoz létre, amellyel két
dimenziós síkban objektumokat vagy koordináta
rendszereket kezelhetünk
645
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
Transzformációk alkalmazása
Tételezzük fel, hogy a <Grid> típusunk egyetlen sort tartalmaz négy oszlop
pal. Minden egyes cellában elforgatunk, ferdítünk és átméretezünk különböző
UI Element: típusokat, például a következőképpen:
646
A WPF animációs szolgáltatásai
, \�
"--��\.
�- - · - - ·· - -...:)
647
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
Megjegyzés Fontos ismételten kiemelni, hogy az Ani mati on utótaggal rendelkező típusok
csak a függőségi tulajdonságokkal, és nem a CLR-tulajdonságokkal működnek együtt (lásd a 29.
fejezetet). Ha animációs objektumokat próbálunk alkalmazni CLR-tulajdonságokon, fordítási
idejű hibát kapunk.
648
A WPF animációs szolgáltatásai
649
30. fejezet: WPF 2D grafikus renderelés, erőforrások és témák
650
A WPF animációs szolgáltatásai
dblAnim.From =40;
dblAnim.To = 60;
lblHeight.BeginAnimation(Label.HeightProperty, dblAnim);
}
�
u .::.,,j:·,�;:;:�:!L:-�:::
,.- - ------------·---:;::·;-·--------------.,..---- --:;;;:- ..
;j
---------.- ·---·----------- -- - ----
- .&: • - - ---- --
ft
.
- --- -
-� -
651
30. fejezet: WPF 2D grafikus renderelés, erőforrások és témák
-
Megjegyzés Az Animation utótaggal rendelkező típusok Begi'nTi me tulajdonsága szintén
Timespan objektumot vesz fel. Emlékezzünk rá, hogy ezzel a tulajdonsággal beállíthatjuk az
animációsorozat elindítása előtti várakozási időt.
652
A WPF animációs szolgáltatásai
ll Habefejeződött a sorozat,"az
- animációt visszafelé játsszuk le.
dblAnim.AutoReverse = true;
ll végtelen ciklus.
dblAnim.RepeatBehavior = RepeatBehavior.Forever;
ll Ismétlés háromszor.
dblAnim.RepeatBehavior = new RepeatBehavior(3);
ll Ismétlés 30 másodpercig.
dblAnim.RepeatBehavior =
new RepeatBehavior(TimeSpan.Fromseconds(30));
653
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
654
A WPF animációs szolgáltatásai
Az <EventTrigger> használata
A kulcsképkocka-animáció szerepe
655
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
656
A WPF animációs szolgáltatásai
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Button Name="myButton" Height="40"
Fontsize="16pt" FontFamily="Verdana" width = "100">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Loaded">
<Beginstoryboard>
<Storyboard>
<StringAnimationusingKeyFrames
RepeatBehavior = "Forever"
Storyboard.TargetName="myButton"
storyboard.TargetProperty="Content"
Duration="O:O: 3" FillBe
- havior="HoldEnd">
<DiscreteStringKeyFrame value="" KeyTime="O:O:O" />
<DiscreteStringKeyFrame value="O" KeyTime="O:O:l" />
<DiscretestringKeyFrame value="OK"
KeyTime="O:O:l.S" />
<DiscreteStringKeyFrame value="OK!"
KeyTime="0:0:2" />
</StringAnimationusingKeyFrames>
</Storyboard>
</Beginstoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
</Grid>
</Window>
657
30. fejezet: WPF 2D grafikus renderelés, erőforrások és témák
<Button.RenderTransform>
<RotateTransform Angle="O"/>
</Button.RenderTransform>
Transform> tag segítségével (vegyük észre, hogy a kezdeti szög nulla). Végül
eseménytriggert definiálunk, amely biztosí�a, hogy a rendszer végrehajtsa a
forgatókönyvet, ha a felhasználó a gombra kattint.
658
A WPF animációs szolgáltatásai
<DoubleAnimationusingKeyFrames
Storyboard.TargetName="myAnimatedButton"
storyboard.TargetProperty=
"(Button.RenderTransform).(RotateTransform.Angle)"
Duration="0:0:2" FillBehavior="Stop">
659
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
A WPF erőforrásrendszere
<Window x:Class="FunwithResources.Mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FunwithResources" Height="207" width="612"
windowstartupLocation="Centerscreen">
<Grid>
<Grid.columnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.columnDefinitions>
<Image Grid.column ="0" Name ="companyLogo"/>
</Grid>
</Window>
660
A WPF erőforrásrendszere
Properties @)
IJntertechlllue.gif File Properties"
�·· ÍATl l """
��! � • .
Bu•ld ActJon Resource
CustomToolNamespace Content
BuldAction
How the file rolates to the build and deployment processes.
661
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
..,. • l
A kapcsolódó külső fájl Build Action elemét Resource helyett Content értékre
is állítha�uk. Ebben az esetben a rendszer a fordítás során értesíti a szerel
vényt a külső fájl relatív elérési ú�áról, de nem foglalja a szerelvénybe a biná
ris adatokat. A beállítás segítségünkre lehet olyan alkalmazás telepítése során,
amely időről időre lecserélt külső erőforrásokat tároló alkönyvtárat (vagy al
könyvtárakat) tartalmaz, illetve ha a külső erőforrás hálózati megosztási pon
ton helyezkedik el.
ilyenkor a WPF-erőforráskezelőrendszer az egyszerű fájlnéven kívül további
URI-kat (a külső szerelvénybe ágyazott erőforrások betöltéséhez szükséges szin
taxist is beleértve) definiál. Ha az olyan helyi erőforrásokkal alkalmazható URI
formátumokat szeretnénk vizsgálni, amelyeket nem fordítunk le az aktuális sze
relvénybe, ezzel kapcsolatban a .NET Framework 3.5 SDK dokumentáció "Pack
URis in WPF" című részében találunk részletes információkat.
662
Stílusok készítése és alkalmazása WPF-vezérlőelemeken
663
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
<Window x:class="FunwithResources.Mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FunwithResources" Height="207" width="612"
windowstartupLocation="CenterScreen">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.columnDefinitions>
<Image Grid.column ="0" Name ="companyLogo"
Source ="IntertechBlue.gif"/>
664
Stílusok készítése és alkalmazása WPF-vezérlőelemeken
Click Me
EJ
30.13. ábra: Az inline stt1usok ahhoz a vez�rlóelemhez kapcsolódnak, amelyek definiálták őket
665
30. fejezet: WPF 2D grafikus renderelés, erőforrások és témák
<Window x:class="FunwithResources.Mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FunWithResources" Height="207"
Width="612" windowstartupLocation="Centerscreen">
666
Stílusok készítése és alkalmazása WPF-vezérlöelemeken
�j] FunWithResources
Click Me Me Too
Stílusbeállítások felülbírálása
667
30. fejezet: WPF 2D grafikus renderelés, erőforrások és témák
A stilusok kiterjesztése
<Window.Resources>
<Style x:Key ="MyFunkyStyle">
<Setter Property ="Control.Fontsize" value ="20"/>
<Setter Property ="Control.Background">
<Setter.value>
<LinearGradientBrush StartPoint="O,O" EndPoint="l,l">
<GradientStop Color="Green" Offset="O" />
<Gradientstop color="Yellow" offset="0.25" />
<Gradientst:op color="Pink" offset="0.75" />
<GradientStop Color ="Red" offset="l" />
</LinearGradientBrush>
</Setter.value>
</Setter>
</Style>
</Window. Resources>
668
Stílusok készítése és alkalmazása WPF-vezérlőelemeken
lehetővé teszi számunkra, hogy a MyFun ky sty l e stílust TextBox típusokon, il
letve Button típusokon (vagy a control osztályból származó bármely elemen)
alkalmazzuk. Tételezzük f el, hogy a következő, új felhasználóifelület-elemet
adtuk az aktuális <Grid> elem új oszlopához:
Megjegyzés Ha olyan stílust készítünk, amely ősosztálytípust alkalmaz, nem kell aggódnunk,
hogy a leszármazott típusok által nem támogatott értéket rendelünk a függőségi tulajdonság
hoz. Ha a leszármazott típus nem támogatja az adott függőségi tulajdonságot, a rendszer fi
gyelmen kívül hagyja.
A stilusok korlátozása
</Style>
</S ty l e>
669
30. fejezet: WPF 2D grafikus renderelés, erőforrások és témák
terjesztést:
</Style>
sem a Button, sem a TextBox típus nem alkalmazná a stílust! Ez annak kö
szönhető, hogy a stílusunk ezen iterációja a control ősosztályt célozza meg.
Soha ne feledjük, hogy az osztályt vagy valamely leszármazottat képviselő
stílus fogalma csak a megnevezett stílusok esetén alkalmazható.
670
Stílusok készítése és alkalmazása WPF-vezérlőelemeken
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resources>
<Style x:Key ="TextBoxstyle" TargetType = "{x:Type TextBox}">
<Setter Property = "Foreground" value = "Black"/>
<Setter Property = "Background" value = "LightGray"/>
<Setter Property = "Height" value = "30"/>
<Setter Property = "Width" value = "100"/>
<StackPanel>
<TextBox Name = "txtone"
Style = "{StaticResource TextBoxstyle}" />
<TextBox Name = "txtTwo"
Style = "{staticResource TextBoxstyle}" />
<TextBox Name = "txtThree"
Style = "{staticResource TextBoxstyle}" />
</StackPanel>
</Window>
671
30. fejezet: WPF 2D grafikus renderelés, erőforrások és témák
<Window. Resources>
<Style x:Key ="TextBoxstyle" TargetType "{x:Type TextBox}">
<Setter Property "Foreground" value "Black"/>
<Setter Property "Background" value "LightGray"/>
<Setter Property "Height" value = "30"/>
<Setter Property "width" value = "100"/>
<!-- A következő <Setter> elemet csak akkor alkalmazza
a rendszer, ha a szövegdoboz az alkalmazás fókuszában van,
és az egeret a doboz fölé húzzuk -->
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property = "IsFocused" value = "True"/>
<Condition Property = "IsMouseover" value = "True"/>
</MultiTrigger.Conditions>
<Setter Property = "Background" value = "Yellow"/>
</MultiTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
672
Stílusok készítése és alkalmazása WPF-vezérlőelemeken
<Window-Resources>
<!-- A stílus 10 fokos szögben megdönti a gombokat -->
<Style x:Key ="Tiltstyle" TargetType = "{x:Type Button}">
<Setter Property = "RenderTransform">
<Setter.value>
<RotateTransform Angle = "10"/>
</Setter.value>
</Setter>
</Style>
<Grid>
<Grid.columnoefinitions>
<Columnoefinition />
<ColumnDefinition />
</Grid.columnDefinitions>
<StackPanel Grid.column="O">
<TextBlock Textwrapping ="Wrap" Fontsize ="20"
Padding="5,5,5,5">
Please select a style for the button on the left.
</TextBlock>
<ListBox Name ="lststyles" Height ="60" Background = "Yellow"
selectionchanged ="combostyles_changed" />
</StackPanel>
<Button Name="btnMouseoverstyle" Grid.Column="1"
Height="40" width="100">My Button</Button>
</Grid>
673
30. fejezet: WPF 2D grafikus renderelés, erőforrások és témák
674
Vezérlőelem felhasználói felületének módosítása sablonok segítségével
675
30. fejezet: WPF ZD grafikus renderelés, erőforrások és témák
<Window x:class="ControlTemplates.Mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Fun with control Templates" Height="162" width="281" >
<Grid>
<Grid.Resources>
<!-- A kerek gomb egyszerű sablonja a rács elemei számára -->
676
Vezérlőelem felhasználói felületének módosítása sablonok segítségével
Azt is vegyük észre, hogy a Button típus kezeli a kattintási eseményt (tételez
zük fel, hogy a kattintási esemény kezelője tájékoztató üzenetet jelenít meg a
MessageBox. show() metódus segítségéve!). Ennek azért van jelentősége, mert
e
30.17. ábra: Egyszerű sablon a Button típus számára
<Grid.Resources>
<!-- Egyszerű sablon a kerek gomb szamara -->
677
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
<Grid>
<Ellipse Name ="OuterRing" width ="75"
Height ="75" Fill ="DarkGreen"/>
<Ellipse Name ="InnerRing" width ="60"
Height ="60" Fill ="Mintcream"/>
<ContentPresenter HorizontalAlignment="Center"
verticalAlignment="Center"/>
</Grid>
<!-- Triggerekkel váltjuk ki a "kattintási" effektust -->
<ControlTemplate.Triggers>
<Trigger Property ="IsMouseover" value ="True">
<Setter TargetName ="OuterRing" Property ="Fill"
value ="MediumseaGreen"/>
</Trigger>
<Trigger Property ="IsPressed" value ="True">
<Setter TargetName ="OuterRing" Property ="Height"
value ="90"/>
<Setter TargetName ="OuterRing" Property ="Width"
value ="90"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Grid.Resources>
;f.: ControiTemplates l = l @l �
678
Vezérlőelem felhasználói felületének módosítása sablonok segítségével
<Gríd.Resources>
<!-- A stílus a Button típus alapvető beállításait definiálja -->
<Style x:Key ="roundButtonTemplate" TargetType ="{x:Type Button}">
<Setter Property ="Foreground" value ="Black"/>
<Setter Property ="Fontsíze" value ="20"/>
<Setter Property ="Fontweight" value ="Bold"/>
679
30. fejezet: WPF 20 grafikus renderelés, erőforrások és témák
680
Összefoglalás
Összefoglalás
681
7. rész
Webes
alkalmazások
fejlesztése
ASP.NET
segítségével
HARMINCEGYEDIK FEJEZET
A HTTP szerepe
A HTTP kérés/válasz-ciklus
Webldazolgéló
l<li8ns oldal bilrtgé6l6 Bejövő
HTTP-kérés Webalkalmazás
A HTTP válaszból ki nyert �··
HTML megjelenitése Kimenő (Tetszőleges számú kiszol-
gáló oldali erőforrás, pl:
.. HTTP-válasz
" *.aspx, *.asp, és *.htm fájlok)
686
Webes alkalmazások és webkiszolgálók
687
31. fejezet: ASP.NET-weboldalak készítése
Megjegyzés A legjobb, ha az liS telepítését a Visual Studio 2008 telepítése előtt elvégezzük.
Ha a Visual Studio 2008 telepítését követően telepítjük az liS-t, az ASP.NET-webalkalmazásaink
nem fognak megfelelően működni (csak egy üres lapot kapunk). Szerencsére az liS-t újrakonfigu
rálhatjuk, hogy hasztolja a .NIT-alkalmazásokat, az asp ne t _ r egi is. exe parancssori eszköz
futtatásával, és az /i opció megadásával.
� ��� @,
� -� AutoWdiServic.e EditSite
�-� C•rOrdetSavicd.ib .-J.J
t·-�� Chtddnventol)' Appiiettion Connection P;�ges1nd SesKm St.te SMTP E·m1il
l D��":���
Providus
:r'-�-------___j ��cOfll�tv-
688
Webes alkalmazások és webkiszolgálók
��
.......
®J Cars Home
......
M.nogeVIrtuol Directory
o.-·:J
;> -{J
CarOrderSc:rvicelib
Ched:In�ntory
Group by. Area � .. ... j.Qi Explore
__
�
,) MSMQ � �
.NETProfile
� Edit Virt... Directory
O·� MyApp .NEl .NET .NETTrust [J Basóc s.ttiniJS...
Compilation Globalization
MyCiickOnceApp
l�els
;, . :} Advanc� Settings...
�-� MyTedEditor --�
t'-.� MyWebService
r<-:'1
LEJ
Application
lZ�l
Conm�ction
�
P�tg6 and
......
Providers
8 Help
t>--:} RfPorts
� -:} Report�rver Settings Strings Conttols
689
31. fejezet: ASP.NET·weboldalak készítése
Az ASP.NET fejlesztőkiszolgálója
weboev.webserver.exe -7
690
A HTML szerepe
http://localhost:12345/Carswebsite/Default.aspx
Ebben és a következő fejezetben látható legtöbb példa a Visual Studio 2008 ré
vén használja a webDev.webse rver. ex e kiszolgálót, ahelyett, hogy liS-beli vir
tuális könyvtárban hosztolná a webtartalmat Miközben ez a megközelítés egy
szerűsítheti a webalkalmazások fejlesztését, ne feledjük, hogy ezt a webkiszol
gálót nem termékszintű webalkalmazások hasztolására hozták létre. Tisztán fej
lesztési és tesztelési célokra alkalmas. Ha elkészültünk a webalkalmazással, a
webhelyet be kell másolnunk egy IlS-beli virtuális könyvtárba.
A HTML szerepe
691
31. fejezet: ASP. NET-weboldalak készítése
Annak ellenére, hogy ez a rész nem dolgozza fel teljes körűen a HTML-t, ve
gyük át az alapokat, és hozzunk létre egyszerű webalkalmazásokat HTML,
klasszikus (COM-alapú) ASP, illetve liS segítségéveL Ez majd útmutatóul
szolgál azoknak, akik hagyományos asztali alkalmazásfejlesztési háttérrel
térnek át az ASP.NET-re.
HTML-dokumentumstruktúrák
A HTML-fájlok olyan tagekből épülnek fel, amelyek egy adott weboldal megje
lenését és működését írják le. Ahogy várhattuk, a HTML-dokumentumok
alapstruktúrája ugyanolyan marad. Például a *. htm fájlok (vagy a *. html fáj
</body>
</html>
692
A HTML szerepe
<head>
<title>This Is the Cars web site</title>
</head>
HTML-űrlapok fejlesztése
693
31. fejezet: ASP.NET-weboldalak készítése
Toolbox
.. Ji
[8-ifTML l �-l
� Pointer
D Input (Button) i
� Input (Reset)
� Input (Submit) i
l
� Input (Text) l
0 Input (Checkbox) l
;
® Input (Radio) i
i�ti: Input (Hidden) l
ii:lll Textarea
B:) Table
Gil Image
g Select
B Horizantal Rule
�'"""'
§ Div
. Fl Geo�_.".. ..
.•
. _ - - ... �
694
A HTML szerepe
.;-�
fo�autt.iit.D1:_si�,te-J • x
form#defaultPaoel
ll �)
[-
Q Design l o Split
---
ls Source l GJI<html>ll<body>! l<t
orrn#defou�Poge>l [B
31. 5. ábra: A Visual Studio 2008 HTML-szerkesztője megjeleníti a maprkupot és
a felhasználói felületi elrendezést
695
31. fejezet: ASP. NET-weboldalak készítése
ProJl"rties
DOCUMENT
· ll
'
Sackground
l
BgColor
Q
Charsot l
Class
ld
Link
Styl•
Text
Trtlo This ls the C;ars Web site
Vlink
IIgColor
Documont background color.
�Properties Dynamic :.
,
31.6. ábra: HTML-dokumentum szerkesztése a Visual Studio 2008 Properties ablaka segítségivel
696
A HTML szerepe
/clebult.htm• rsa.tp....]. �x
Client Objects & Events • {No Events)
l Si l O� er Name: -
16� <inpuc id-"t:xtU:serName" cype-"t:ext:" nare.e-"'txtU:serName"></p>
<p aliqn"'""center">
Password:
<input name-"'txtPassword" type•"password" id-"txtPassword"'></p>
E
<p aliqnu"'center">
<input na:r:;.e-"btnSubmi.t" type•"submit" value-"Submi.t" id.,."btnSubm.i.t">
22; �� �.!bt�e�e�•�·�-�e�• valqe••áe��-b��·1
23:
-
</p>
2�� </f.orm>
;
25
UserNamc:f
Password: l - -
697
31. fejezet: ASP.NET·weboldalak készítése
Megjegyzés Tudni kell, hogy még ügyféloldali ellenőrzés alkalmazásakor (amit a válaszidő
csökkentése érdekében teszünk) is előfordulhat ellenőrzés magán a webkiszolgálón. Ezzel biz
tosíthatjuk, hogy az adatok nem változtak meg az adatátvitel során. Ahogy azt a következő fe·
jezet bővebben tárgyalja, az ASP.NET ellenőrző vezérlőelemek automatikusan végrehajtják az
ügyfél- és kiszolgálóoldali ellenőrzésekeL
698
Az ügyféloldali szkriptírás szerepe
Megjegyzés Hogy tovább bonyolítsuk a dolgot, emlékezzünk vissza arra, hogy a JScript.NET
olyan felügyelt nyelv, amellyel érvényes .NET·szerelvényeket készíthetünk egy szkriptszerű
szintaxissal.
699
31. fejezet: ASP. NET-weboldalak készítése
A Visual Studio 2008 szintén létrehoz egy üres JavaScript függvényt, amelyet
a rendszer akkor hív meg amikor a felhasználó a gombra kattint. Ebben az
üres rutinban az alert() metódust használjuk ügyféloldali üzenetdoboz
megjelenítésére:
700
Az űrlapadatok továbbítása (a GET és a POST )
function btnsubmit_onclick(){
ll Ha az egyik elemről megfeledkeztek, jelenitsünk meg egy
ll üzenetdobozt.
if((defaultPage.txtuserName.value " ) l l
== "
(defaultPage.txtPassword.value == "" ))
{
alert("You must su p p ly a user name and password!");
return false;
}
return true;
}
http://localhost/Cars/default.htm
Az űrlapadatok továbbitása
(a GET és a POST )
Most, hogy már van egy egyszerű HIML-oldalunk, vizsgáljuk meg, hogyan kell
az űrlapadatokat visszaküldeni a webkiszolgálónak feldolgozásra. Arnikor
HTML-űrlapot készítünk, általában elhelyezünk egy műveletattribútumot a
nyitó <form> címkében a bemeneti űrlapadatok címzettjének meghatározásához.
A lehetséges címzettek levélkiszolgálók, más HIML-fájlok, egy Active Server
Pages (ASP-) fájl és egyéb objektumok lehetnek. Ebben a példában a classieAsp
Page.asp nevű, klasszikus ASP-fájlt használjUk. Módosítsuk a default.htm fájlt a
</form>
701
31. fejezet: ASP. NET- weboldalak készítése
ht:t:p://localhost:/Cars/ClassicAspPage.asp?t:xt:UserName=
Andrew&t:xt:Password=Foo$&bt:nsubmit:=Submit:
</form>
702
Klasszikus ASP-oldal készítése
<"h
Dim pwd
pwd = Request.QueryString("txtPassword")
Response.write(pwd)
%>
Megjegyzés Ezek a COM-objektumok az ASP.NET alatt hivatalosan már nem léteznek. Azon·
ban látjuk majd, hogy a system. web. ur. Page ösosztály azonos nevű tulajdonságokat definiál,
amelyek hasonló működésű objektumokat foglalnak magukban.
703
31. fejezet: ASP.NET-weboldalak készítése
Á
---
<body>
<hl align="center">Here is what you sent me:</hl>
<P align="center">
<b>User Name: </b>
<%= Request.Form("txtuserName") %> <br>
<b>Password: </b>
4'o= Request.Form("txtPassword") %> <br>
</P>
</body>
704
A klasszikus ASP problémái
Noha sok sikeres webhelyet a klasszikus ASP-vel hoztak létre, ennek az ar
chitektúrának is megvannak a maga hátrányai. A klasszikus ASP legnagyobb
hátránya talán ugyanaz, mint ami hatékony platformmá teszi: a kiszolgálóol
dali szkriptnyelvek. A szkriptnyelvek, mint a VBScript és a JavaScript interp
retált, típus nélküli entitások, amelyek nem alkalmasak robusztus 00 prog
ramozási módszerekre.
A klasszikus ASP másik problémája, hogy egy * .as p oldal nem szolgál mo
dularizált kóddal. Mivel az ASP HTML és szkript keveréke egyetlen oldalon, a
legtöbb ASP-webalkalmazás két különböző programozási módszer zavaros
elegye. Amíg igaz, hogy a klasszikus ASP révén az újrafelhasználható kódokat
különálló fájlokra osztha�uk, az alapul szolgáló objektummodell nem támogat
ja a kapcsolatok valódi szétválasztását. Az ideális az lenne, ha a webes keret
rendszerek lehetövé tennék, hogy a megjelenítő logika (például a HTML
címkék) az üzleti logikától (például a funkcionális kódtól) függetlenül létezzen.
Szintén megfontolandó probléma, hogy a klasszikus ASP túl sok sablon
szöveget és redundáns szkriptkódot igényel, amelyek a projektek között is
métlődnek. Szinte az összes webalkalmazásnak ellenőriznie kell a felhaszná
lói bemeneteket, újra fel kell töltenie a HTML-vezérlők állapotát a HTTP-vá
lasz kiadása előtt, generálnia kell egy HTML-adattáblát, és így tovább.
705
31. fejezet: ASP.NET·weboldalak készítése
706
Az ASP.NET-névterek
A N ET 3.5
. legfőbb webes újdonságai
Mivel a könyv nem kizárólag a webes fejlesztésre összpontosít, az itt nem emlí
tett témákkal kapcsolatos további részletekért forduljunk a .NET Framework 3.5
dokumentációjához. Az igazság az, hogy ha minden szempontból megvizsgál
nánk az ASP.NET-et, a könyv akár kétszer ilyen hosszú is lehetne. Biztosak lehe
tünk benne, hogy mire a könyv ezen szakaszának a végére érünk, szilárd
ASP.NET-alapokkal rendelkezünk.
Az ASP.NET-névterek
A .NET 3.5 megjelenése óta jóval több mint 30 webközpontú névtér létezik az
alaposztály-könyvtárakban. Ezek a névterek az alábbi főbb kategóriába so
rolhatók:
707
31. fejezet: ASP.NET-weboldalak készítése
• Silverlight-fejlesztés,
• Ajax-fejlesztés,
• XML-webszolgáltatások.
708
Az ASP.NET weboldal·kódolási modellje
709
31. fejezet: ASP.NET-weboldalak készítése
Függetlenül attól, hogy melyik módszert válasz�uk, jó, ha tudjuk, hogy telje
sítmény szempon�ából nincs közöttük különbség. Valójában sok ASP.NET
webalkalmazás előnyére válik, ha olyan oldalakat készítünk, amelyek mind
két módszert alkalmazzák
Először is, vizsgáljuk meg az egyfájlas oldal modellt. A célunk, hogy olyan
*. aspx fájlt készítsünk, amely a 22. fejezetben létrehozott AutoLot adatbázis
Inventory tábláját jeleníti meg. Amíg ezt az oldalt kizárólag Jegyzettömb se
gítségéve! is elkészíthetnénk, a Visual Studio 2008 egyszerűsítheti a dolgokat
az IntelliSense, a kód kiegészítés és egy vizuális laptervező segítségéveL
Kezdésként nyissuk meg a Visual Studio 2008-at, és hozzunk létre új Web
Forrnot a File >- New>- File menüpont segítségével (lásd a 31.9. ábrát). Ha
ezzel elkészültünk, mentsük a fájlt Default.aspx néven a merevlemezre, egy
új C:\CodeTests\SinglePageModel könyvtárba.
Newfi5e
. 'rHiil:tiii
Categori5: T emplat:es:
Gen�al Visual Studio insta\led tempiates
Web mfw.;b-1'�.;;; LJMaster Plige
Visual Basic
ltJ WebUs;,. Control @ HTMLPage
ci
�WebS.<Vice �Class
Visual C++
� Style Sheet Q Global Application Class
Script
�Web Configuration File � XMLFile
1!1 TextFile �ResourceFíle
� Generic Handler !ms�eMap
lUJScript File
710
Az ASP.NET weboldal-kódolási modellje
Megjegyzés Ahogy az a fejezet későbbi részéből kiderül, amikor a Visual Studio 2008 segítségével
hozunk létre teljes ASP.NET-webalkalmazást, a \bin mappát az IDE tartja karban helyettünk.
�·�
•X
�
l Lill'!l ___ _ ___'"
___ _______ _....... ___________..•..•...·--··--·-·····--·--·-···---,
�
�o[�·�-1����
·[abc -;abc - j
��-- �
+-·---->------
1l
abc l
1;;t;;;··· ---t•
abc·---r'�
�- l
!
!
'
j
�-;;iii-c3ri;·l --·-·-···------···-.. --·----------··--·--·---_j
� '( ..
Most keressük meg az oldal <form> szakaszát. Figyeljük meg, hogyan defini
áltuk az egyes webes vezérlőelemeket egy <as p:> címke segítségéveL A lezáró
címke előtt egy névj érték pár sorozatot találunk, amely a Properties ablak
beállításaival áll összhangban:
711
31. fejezet: ASP. NET-weboldalak készítése
lakának " villám ikonjával, vagy a tervezőablak felső részén található legördülő
listák segítségéveL Ezzel a gomb definícióját kiegészítettük egy onelick attribú
tummal, amelyet a click esemény kezelőjének nevéhez rendeltünk hozzá:
<script runat="server">
void btnFillData_Click(object sender, EventArgs args)
{
}
</script>
712
Az ASP.NET weboldal-kódolási modellje
<script runat="server">
void btnFillData_click(object sender, EventArgs args)
{
InventoryDAL dal = new InventoryDAL();
dal.Openconnection(@"Data source=(local)\SQLEXPRESS;" +
</html>
webdev.webserver.exe
/port:12345 /path:"C:\CodeTests\SinglePageModel"
http://localhost:12345/
713
31. fejezet: ASP. NET- weboldalak készítése
@O [� http://localhost50'; l +,._(iJ§
� �
714
Az ASP.NET weboldal·kódolási modellje
Az ASP.NET-direktivák szerepe
Az első dolog, amellyel tisztában kell lennünk, hogy az *.aspx fájlok általában
Enab l evi ews tat e Ez az attribútum jelzi, hogy a nézet állapotot (view
state-et) a rendszer az oldalkérések között megőrzi (a
tulajdonságról a 33. fejezetben találhatunk további rész
leteket).
715
31. fejezet: ASP. NET-weboldalak készítése
Egy adott *. aspx fájl a <%@Page%> direktíván kívül különféle <%@Import%> di
<pages>
<namespaces>
<add namespace="System"/>
<add namespace="System.coll ecti ons"/>
<add namespace="System.Collections.Specialized"/>
<add namespace="System.configuration"/>
<add namespace="System.Text"/>
<add namespace="System.Text.RegularExpressions"/>
<add namespace="System.web"/>
<add namespace="System.web.Caching"/>
<add namespace="System.web.sessionstate"/>
<add namespace="System.web.security"/>
<add namespace="System.web.Profile"/>
<add namespace="System.web.ur"/>
<add namespace="System.web.ur.webcontrols"/>
<add namespace="System.web.ul:.webcontrols.webParts"/>
<add namespace="System.web.UI.Htmlcontrols"/>
</namespaces>
</pages>
A szkriptblokk elemzése
716
Az ASP.NET weboldal-kódolási modellje
<script runat="server">
void btnFilloata_Click(object sender, EventArgs args)
{
InventoryDAL dal = new InventoryDAL();
dal.openconnection(@"Data Source=(local)\SQLEXPRESS;" +
717
31. fejezet: ASP.NET-weboldalak készítése
A mögötteskód-modell használata
Templat6:
location:
language:
OK ll Cancel l
31. 12. ábra: A Visual Studio 2008 ASP.NET Web Site sablonja
718
Az ASP.NET weboldal-kódolási modellje
A cod eFi le attribútummal azt a kapcsolódó külső fájlt adjuk meg, amely az
oldal forráskódját tartalmazza. Alapértelmezés szerint ezek a mögöttes kód
fájlok úgy kapnak nevet, hogy a .cs utótagot adjuk az *. aspx fájl nevéhez Ge
len esetben Default.aspx. cs) . Ha megnézzük a Solution Explorert, észrevesz
szük, hogy ez a mögöttes kódfájl a Web Form ikon egyik alcsomópontján lát
ható (lásd a 31.13. ábrát).
Solution Explorer li
l li � l [ID li]l !21 811 llt!] lt il
. ,
f� C:\-\CodellehindPageModel\ ,
!- E:ij App_Data
l $· · �·�IIM1'M
l i 'e;1 Default.aspx.cs
L.. � web.config
719
31. fejezet: ASP.NET-weboldalak készítése
Solution Explorer
� C:\...\CodeBehindP;ogeModel\
;.. L:;j App_Data
é- lliiD -
:... B web.config
� Solution Explorer �Class View_!
A kódfájl módositása
using AutoLotconnectedLayer;
720
Az ASP.NET weboldal-kódolási modellje
<compilation debug="true"/>
721
31. fejezet: ASP.NET-weboldalak készítése
' �
aspx.page Begin Preinit
aspx.page End Preinit 2.45841301059213E-05 0.000025
aspx.page Begin Init 4.63746090634424E-05 0.000022
aspx.page End Init 7.6546041466164E-05 0.000030
aspx.page
aspx.page
Begin InitComplete
End InitComplete
9.30285832417249E-05 0.000016
0.000108952394787606 0.000016
8
aspx.page Begin LoadState O .OOO124317476103806 O.000015
aspx.page End LoadState 0.000215949233771331 0.000092
aspx.page Begin ProcessPostData 0.000234946061580452 0.000019
aspx.page End ProcessPostData 0.0002620444777199340.000027
aspx.page Begin PreLoad 0.000278527019495495 0.000016
aspx.page End Preload o .000305346070520136 0.000027
aspx.page Begin Load o .000322387342525377 0.000017
aspx.page End Load o.000343619091253218 o .000021
aspx.page Begin ProcessPostData Second Try0.000359822267913939 0.000016
aspx.page End ProcessPostData Second Try 0.0003749079841153 0.000015
aspx.page Begin Raise ChangedEvents 0.00039055243054634 0.000016
aspx.page End Raise ChangedEvents 0.000406476242092221 0.000016
=ocnv n=on• Beqin Raise n ;.". cc. 0.000422679418752942 0.000016
0.0016295367148618 0.001207
aspx.page End Raise PostBackEvent 0.00610440712436916 0.004475
aspx.page Begin LoadComplete 0.00626867381189509 0.000164
aspx.page End LoadComplete 0.00628850873504873 0.000020
aspx.page Begin PreRender 0.00630471191170945 0.000016 .Y
. -=-= ... _ ... "-- ""' - • < � ��,�-��-��-�Ann-� ... ,.,..,...........
r
.- lll '
722
ASP. NET -webhely könyvtárszerkezetének részletei
723
31. fejezet: ASP. NET-weboldalak készítése
Hivatkozás szerelvényekre
<assemblies>
<add assembly="System.Data.oracleclient, version=2.0.0.0,
cuhure=neutral, PublicKeyToken=B77A5C561934E089"/>
</assembli es>
724
ASP. NET- webhely könyvtárszerkezetének részletei
Tételezzük fel például, hogy hozzáadtunk egy App_Code mappát egy web
hely gyökérkönyvtárához, amely két almappát (MyCSharpCode és MyVbNet
Code) tartalmaz, és az almappák nyelvspecifikus fájlokat tárolnak. Ha ezt meg
tettük, módosítsuk a web. config fájlt, és meghatározha�uk az alkönyvtárakat a
<configuration> elembe ágyazott <codesuboirectories> elem segítségéve!:
725
31. fejezet: ASP.NET·weboldalak készítése
726
Az ASP.NET-oldal fordítási ciklusa
Megjegyzés Mivel ezek az automatikusan generált szerelvények igazi .NET bináris fájlok, ha
megnyitnánk a webalkalmazásunkhoz kapcsolódó *.dll-t az i l dasm. exe vagy a refl ector. exe
segítségéve!, csakugyan köztes nyelvi kódot, metaadatokat és egy szerelvényszintű manifesztu
mokat találnánk ott.
l
assembly
J.\ hosh
i
.j tomp
wcfwebservice
websrte_formsbasedauthentication
� ----·------J�
--�
wr:bsite_w i dowsauthwebsite
:
nr
727
31. fejezet: ASP.NET-weboldalak készítése
A futtató
környezet System.We. U l.Page
fordítója (Minden *._aspx osztály ösosztálya)
MyPage.aspx.cs
(Részleges osztálydefiníció
.
a
Megjegyzés Az ASP.NET alatt lehetőségünk nyílik, hogy a webhelyek összes oldalát (vagy
azok közül néhányat) előfordítsunk az aspnet_compi l er. exe parancssori eszköz segítségéveL
További részletekért forduljunk a .NET Framework 3.5 SDK dokumentációjához.
728
A Page típus származtatási lánca
Ahogy az imént láthattuk, az utolsó generált osztály, amely az *.aspx fájlt kép
viseli a system. web. UI. Page osztályból származik. Mint minden ősosztály, ez a
típus is polimorf interfészt biztosít az összes származtatott típus számára.
A Page típus azonban nem az egyetlen tagja a származtatási hierarchiának. Ha
megkeresnénk a Page típust (a system.web. dll szerelvényben) a Visual Studio
2008 objektumböngészője segítségéve!, azt látnánk, hogy a Page "az-egy"
Templatecontrol, "az-egy" control és "az-egy" object (lásd a 31.19. ábrát).
Ahogy már rájöhettünk, ezek az ősosztályok rengeteg funkcionalitással ru
házzák fel az* .aspx fájlokat A projek�eink többségében a Page és a control
szülőosztályokban definiált tagokat alkalmazzuk majd. A system. web. UI. Temp
latecontrol osztályból nyert funkcionalitással lényegében csak az egyedi Web
Form vezérlőelemek létrehozásakor vagy a renderelési folyamattal folytatott
együttműködés közben foglalkozunk.
Az első lényeges szülőosztály maga a Page. Ebben több olyan tulajdon
sággal találkozhatunk, amelyek révén különféle webprimitívekkel dolgozha
tunk, mint például az alkalmazás- és munkamenet-változókkal, a HTIP ké
résekkelfválaszokkal, a tématámogatással és így tovább. A 31.4. táblázat né
hány (de közel sem az összes) alapvető tulajdonságot mutat be.
�x
l'
· - I'M
-
-- �ll;
-� t·'
•
j·-·,.
AddOnPreRenderCompleteAsync(System.Web.BeginEventHa
AddOnPreRenderCompleteAsync(System.Web.BeginEventHar
r[J1.
Base Types
éJ--� TemplateControl hi• AddWrappedFileDependencies(object)
' B·"!: Control
!··4• AspCompatBeginProcessRequest(System.Web.HttpContext, SJ
. $.. ><> !Component i···>j· AspCcmpatEndProcessRequest(System.!AsyncResult)
GJ-.-o IControiBuilderAccessor !·-·-f• AsyncPageBeginProcessRequest(System.Web.HttpContext. Sy:
�..--<1- IControiDesigne:rAccessor f·�· AsyncPageEndProcessRequest(System.JAsyncResult)
$-·� IDataBindingsAccessor t·<J• CreateHtmiToxtWriter(SystemJO.TextWritor)
�.. -o !Disposable
t···,. CreateHtmiToxtWriterFromType(SystemJO.ToxtWriter, System �
i .... !"
$�·....0 IExpressionsAccessor '"
729
31. fejezet: ASP.NET-weboldalak készítése
730
Együttműködés a bejövö HTTP-kérésekkel
utasítás nyitó címkéje megad egy act i on és egy method attribútumot, amelyek
arra a fájira mutatnak a webkiszolgálón, amely megkapja a különböző HTML
vezérlők adatait, valamint az adatok küldésének módját (GET vagy POST):
</form>
731
31. fejezet: ASP.NET-weboldalak készítése
Böngészőstatisztikák
732
Együttműködés a bejövő HTTP-kérésekkel
733
31. fejezet: ASP.NET-weboldalak készítése
Az lsPostBack tulajdonság
fel, hogy az *. aspx fájlunk kezelte az oldal Load eseményét (erre a fejezet ké
734
Együttműködés a kimenő HTIP-válaszokkal
Most, hogy már jobban átlátjuk, a Page típus hogyan teszi lehetővé a bejövő
HITP-kérésekkel folytatott együttműködést, a következő lépés a kimenő
HITP-válaszok együttműködésének vizsgálata. Az ASP.NET alatt a Page osz
tály Response tulajdonsága biztosít hozzáférést a HttpResponse típus példá
nyához. Ez a típus több olyan tulajdonságot definiál, amelyek révén formáz
hatjuk a kliensböngészőnek visszaküldött HITP-válaszokat A 31.6. táblázat
néhány alapvető tulajdonságot sorol fel.
735
31. fejezet: ASP.NET-weboldalak készítése
HTML-tartalom kibocsátása
736
Együttműködés a kimenő HITP-válaszokkal
Felhasználók átirányítása
737
31. fejezet: ASP.NET-weboldalak készítése
Megjegyzés A HttpResponse. Redi rect() metódus mindig igényel egy újabb kört a kliens
böngésző felé. Ha egyszerűen csak szeretnénk átadni a vezérlést ugyanazon virtuális könyvtár
egy másik *.aspx fájljának, az a Httpserveruti l i ty. Transfer() metódus (az öröklött ser
ver tulajdonság révén érhető el) használata sokkal hatékonyabb.
Ennyit a syst em. web. UI. Page működésének vizsgálatáróL A system. web. UI.
Az ASP.NET-weboldalak életciklusa
A Page típusok a Load eseményen kívül képesek elkapni bármely, a 31.8. táb
lázatban kiváltódási sorrendben felsorolt eseményt (az oldalak életciklusa
alatt felmerülő eseményekkel kapcsolatos további információkért lapozzuk
fel a .NET Framework 3.5 SDK dokumentációját).
738
Az ASP.NET-weboldalak életciklusa
. ·:�J��!�\'t�t::t�:1.-
�-���•,..., ���-!•·>>'1-�iMk.��,X:�
�'-·i7.;�.l.-�lt,��r:;��rL; _.·:k:���J.;i�1�i/�:;;ritt;:�tt;�i)[�3'f�
-�"·•'·---·>·���� w"''��-.Ao>�� , "'""'�J
...
739
31. fejezet: ASP.NET·weboldalak készítése
publ i c _Default()
{
ll Explicit módon kapcsolódjunk a Load és az unload eseményekhez.
this.Load += new EventHandler(Page_Load);
this.unload += new EventHandler(Page_Unload);
}
740
Az ASP.NET-weboldalak életciklusa
Az Error esemény
741
31. fejezet: ASP.NET-weboldalak készítése
@0 TiJ·h����-"!-����--:I!!L� @ocgt•
· ·- ________________ �:._
fi r$1 l� r l �. fill •
»
742
A Web.config fájl szerepe
solutiont), azt a Web Site> Add New ltem menüpont segítségével tehe�ük meg.
Mindkét esetben hozzáadhatunk beállításokat a web. config fájl hatókörén belül,
amelyekkel a webalkalmazás futási idejű működését szabályozha�uk.
743
31. fejezet: ASP.NET-weboldalak készítése
it! ASP.NET Configufllltion �ttlngs · Microsoft Visual Studio Codena� Orcas Documentation- MKrosoft Document Expk>rer {Administrator)
Back.., ll A; !j:HowOol ·Q. Search u; tnde:x e: contents G'J Helpfavont� ('V � MSDNForums v
Contents____ • I,l X �P.NET cónfiguution Settings Surc ... X
""-::od_.b)".:-
r'"- .: ---------------; l URL: ms-help://MS.VSCC.\'90/MS.MSONQTR.v90.mtdv_aspnetgenref/htmV1166C ·l
(unfiltc:red)
G eneral Reference
.NET Framework
b ASP.NEl Ref6ence ASP.NET Configuration Settings
Browsf'r Definition Filf' Scht>ma {browsf':rs E!c:mt>:n(
lt.J Client Reference �
0 Configuration F•l� Syntax s Collapse Ali
- t}iall!i!tfr.Wi@ifl·M·b
:+� <syst�m.w�b>
.. <system.web.e:xtenSions>
ft; < system.�bServtr>
<system.servtceModel> ASP.NET configuration files a re XML f�es. The .NET
General Configuratton Settings
•
Framework defines a set of elements that implement
.. Global.asax Syntax configuration settings, and the ASP.NET configurabon
HTML �er Contfels schema contatns elements that control how ASP.NET
�� Page Syntax Web applications beha ve.
744
A Web.config fájl szerepe
Application:/WebSite 1
Current User Name:INTERTECH\ATROELSEN
Enables you to set up and edit users, roles, �nd �ccess permiSSions for
your site.
Site is using windows authentíaltion for user management.
Applicatton
Enables you to manage your application's configuration settings.
Configuration
Enables you to specify where and how to store administration data used
Provider Configu ration
by your Web site.
745
31. fejezet: ASP. NET- weboldalak készítése
Összefogla l ás
746
HARMINCKETTEDIK FEJEZET
webcontrols névtér egyik tagváltozója lesz (az előző fejezetben tárgyalt, di
namikus fordítási ciklus révén), képesek vagyunk ennek a típusnak a tagjai
val kommunikálni a kiszolgálóoldali <script> blokkon keresztül vagy az ol
dal mögöttes kódfájljának a segítségéveL Ha például egy adott Button típus
nak implementáltuk a click eseményét, a TextBox háttérszínét a következő
képpen módosítha�uk:
748
A webes vezérlőelemek viselkedésének megértése
Megjegyzés A Visual Studio 2008 esetében ugyanúgy kezelhetjük egy adott webes vezérlő
elem eseményét, mint egy Windows Forms vezérlőelemét. Válasszuk ki a tervezőben a vezér
lőelemet, .majd kattintsunk a "villám" ikonra a Properties ablakban.
Az AutoPostBack tulajdonság
749
32. fejezet: ASP.NET-vezérlöelemek, -témák és -mesteroldalak
<asp:TextBox ID="txtAutoPostback"
runat="server" AutoPostBack="true">
</asp:TextBox>
750
A System. Web. UI.Control típus
visible Ez a tulajdonság azt kérdezi le, vagy állítja be, hogy a kiszolgá
ló-vezérlőelem felhasználóifelület-elemeként megjelenik-e az
oldalon.
751
32. fejezet : ASP NET vezérlőelemek
. - , · témák és mesteroldalak
·
Vezérlőelemek felsorolása
Ezután helyezzünk egy lblcontrol Info nevű címkét a panel hatókörén kívülre,
amelyben megjelenik a kimenet. Tételezzük fel, hogy a Page_Load() esemény
ben a panel összes vezérlőelemének listáját szeretnénk megkapni, az ered
ményt pedig hozzá szeretnénk rendelni a lblcontrol Info nevű címkéhez:
752
A System.Web. UI.Control típus
if (!object.ReferenceEquals(c.GetType(),
typeof(System.web.UI.Literalcontrol)))
{
theinfo +=
"*********************":*****<br/>";
- -
A
Dyoamic Controls
l Button l
HyperLink
l
Has coolrols? True
•••••••••••••••••••••••••••
l
' local intranet l Proleeted Mode: Off 6llOO%
� . ..
753
32. fejezet: ASP.NET-vezérlőelemek, -témák és -mesteroldalak
Mit kell tenni, ha futás közben szeretnénk rnódosítani a Panel tartalrnát? Ad
junk az aktuális oldalhoz egy btnAddwidgets nevű gombot, amellyel három új
szövegdobozt adunk hozzá dinamikusarr a panelhez, valarnint egy másik,
btnRemovePanelIt ems nevű gombot, amely törli az összes vezérlőelemet a pa
754
A System. Web. Ul. WebControls. WebControl típus
755
32. fejezet: ASP.NET·vezérlöelemek, ·témák és ·mesteroldalak
• egyszerű vezérlőelemek,
• sokoldalú vezérlőelemek,
• adatközpontú vezérlőelemek,
756
Az ASP.NET webes vezérlőelemeinek főbb kategóriái
• webkijelzők,
• biztonsági vezérlőelemek
Toolbox
�ro-s�
.. -
"" Pointer
� RequiredFieldValidator
Q RangeValidater
� RegularExpressionValidator
� CompareValidator
� CustomValidator
757
32. fejezet: ASP.NET-vezérlőelemek, -témák és -mesterofdalak
Toolbox
ils HTML
\ Pointer
D Input (Sutto n)
� Input (Reset)
f!tJ Input (Submit) .,
@Input (Tex!) l
@Input (File)
j @ Input (Password)
! 0 Input (Checkbox)
l 0 Input (Radio)
1 ,.it!' Input (Hidden)
! \im Textarea
i Table
l�
ill
i Gil Image
i, �
- Select
i B Horizental Rule
l [lj] Div
li - 9 Geaenl
l
�� SeiVer Explore� )(- Tcolboxj
32. 3. ábra: A HTML-vezérlőelemek
758
Sokoldalú ASP.NET-webhely készítése
• mesteroldalak használata,
759
32. fejezet: ASP.NET-vezérlöelemek, -témák és -mesteroldalak
Mesteroldalak használata
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<asp:ContentPlaceHolder id="head" runat="server">
760
Sokoldalú ASP.NET·webhely készítése
</asp:ContentPlaceHolder>
</head>
<body>
<form id="forml" runat="server">
<div>
<asp:ContentPlaceHolder id="ContentPlaceHolderl" runat="server">
</asp:contentPlaceHolder>
</div>
</form>
</body>
</html>
Templatos: tri1IDG
Ví�ual Studio install�d tempiates .
@j ' D � � [i li u g Q
-
i
Web Form ; �aster �age WebUser AJAXCiient AJAXClient AJA)( Client AJAXMaster AJ!>;!. Web AJAX·enab...
Control Be.havior Control Library Page Form WCFService
;;
fl
Browser File
�
Class
�
Class
�
DataSet
.
�
Generic
�
Global
[iJ
HTM L Page
ri
JS<:riptFile
r&\
UNQtoSQL
Diagram Handter Applicati•.. Classes
� � . ill
- � � (j � [i �
Report Report Resource: File SiteMap Skin File SQL StyleSheet Text File WCFSf:rvice
WIZard Database
� -
... . .. .
�
, ..
�..... .
B1J
> ' & 0 0 ... l
rll
......... �.
�
Name MasterPage.master
f LanglUlgc IV'ISUal C# --
�i li] Place code in �parate file
EJ Select master page
761
32. fejezet: ASP.NET-vezérlöelemek, ·témák és -mesteroldalak
T X
�11 �1
t::
:;::�:"'""'"'",....,""''
< l.-··- - lll .l
ContentPtaceHolde'l
l l
l'
Q Design � @l Source l 0�j<asp:ContentPiaceHolder#C... >j [!]
32. 5. ábra: EgJJ •. master fájl <asp:ContentPlaceHolder> címkéi teroezés közben
762
Sokoldalú ASP.NET·webhely készítése
--- --- --
<:ént Objects & Evftlts � (No Ev..nts) �
22\ </asp:contentplaceholder>
25i form>
c__ lll
'-'
763
32. fejezet: ASP.NET-vezérlőelemek, -témák és -mesteroldalak
Templates: ll§] LB
VisualStudio instatled tempiates -· �
o = LJ � � � � Lj g =
il
WebForm Master Page WebUser AJAX Client AJAX Client AJAXCii�t AJAX Master AJAXW•b AJAX�enab...
Control BehoMor Control Library Page Form WCF S.rvie<
5
� � m � . i) i) [il � �
Browser File Class Class DataSet Geneóc Global HTM L Page JScript File UNQtoSQL
Diagram Handle:r Applicati... Classes
--------·
-
� @ � � � -
tli�
[i1 \i1
Report Repert Resource File Site M�p _ Skin File SQL StyloShoot Ted: File WCF Service
WtZard Database
�-
....
il
.... ....
ti
,$.01 �· .
&m
.. .. ,. .
� o
.,�,T�o
�
-
A file used to create a site map
Narrn:: Web.sitemap
language: jvisual c• --
·l O Plilcll! code in separate file
O Select marter page
l Add
ll Cancel
l
32. 7. ábra: Új Web.sitemap fájl beszúrása
A kezdeti web. sitemap fájl egy gyökérelemet és annak két alcsomópontját de
finiálja:
764
Sokoldalú ASP.NET·webhely készítése
Ebben az esetben nem csatoljuk közvetlenül a web. siternap fájlt egy Menu vagy
egy Treeview vezérlőelemhez egy adott tulajdorrág segítségéveL Ehelyett a
we b . siternap fájlt megjelenítő, felhasználóifelület-elemet tartalmazó *.master
vagy * .aspx fájlnak kell magában foglalnia egy siteMapDatasource kompo
nenst. Ez a típus automatikusan betölti a we b . siternap fájlt az objektummo
delljébe, amikor lekérjük az oldalt. Ezután a Menu és a Treeview típus Data
sourceiD tulajdonsága a siteMapDatasource példányára mutat. Az indirekció
oka, hogy így olyan egyedi szolgáltatót hozhatunk létre, amely másik forrás
ból tölti be a webhely struktúráját (pl. egy adatbázistáblából, egy meglévő
XML-fájlból stb.). A 32.8. ábra a we b sitemap, a siteMapDatasource és a külön
.
765
32. fejezet: ASP.NET-vezérlőelemek, -témák és - meste roldalal{
*aspx
SiteMapData.Source
Egyedi
SiteMapDataSource
'Root <
-
Roon f-A�u ma
or �
lo �F- 1...��---��--
-�
�-
Root
Choose Dala Source: j (None)
Root
-� _ Views: I<Newdata source l
... >
· ·· ·
Edit Ternpiales
766
Sokoldalú ASP.NET·webhely készítése
Az AdRotator használata
<Advert:isement:s>
<Ad>
<Imageurl>SlugBug.jpg</ImageUrl>
<Target:Url>ht:t:p://www.cars.com</Target:url>
<Alt:ernat:eText:>Your new car?</Alt:ernat:eText:>
<Impressions>80</Impressions>
</Ad>
<Ad>
<Imageurl>car.gif</Imageurl>
<Target:url>ht:t:p://www.carsupersit:e.com</Target:url>
<Alt:ernat:eText:>Like t:his car?</Alt:ernat:eText:>
<Impressions>80</Impressions>
</Ad>
</Advert:isement:s>
767
'
Jelen esetben két képfájlt adtunk meg ( car.gif és slugbug.jpg) , ezért biztosí
tanunk kell, hogy ezek a fájlok a webhely gyökerében legyenek (a fájlok a
könyvhöz tartozó letölthető forráskód mellett találhatóak.) Ahhoz, hogy a fáj
lokat az aktuális projekthez adjuk, válasszuk a Web Site> Add Existing Item
menüpontot. Ekkor társítha�uk az XML-fájlunkat az ActRotator vezérlőele
mekkel az AdvertisementFile tulajdonság révén (a Properties ablakban):
� �eb.sitemao/' �
Mast�·erl'�age
�.mast��er:ht�����- ��
Start p�l========== �
�oCar sRUs�
�
� ;
x ,
l, asti":Menu#Menul
JW�ome! •IJJ
·1
'
Sit��o��e- SiteMapDataSour�el � _
�ll
l
l Q Design l o Split l 8 Source l G]l<html>lJ<body>ll<form#fonn2>ll<div>ll<asp:Menu#Menul> l
32.1 O. ábra: Amesteroldal végső megjelenése
768
Sokoldalú ASP.NET-webhely készítése
fájlt generáltunk:
� ".:YDefault..spxi;'AdsJ!mi!'W���Si.liffiiQC] • x
�i�
•
</a�p:Content>
<a���
IIF="Contentl" ContentPlaceHolderiD="head" Run at="s
:
;l
i
.
9 </p>
10 </asp:Content>
lll
!2 l
lll
. [. .... :J
_ Ma���age.m_� �
�-Sit<MapDetaSourW l
ContentPtaceHolaerJ.tt... usrormllr-\
• - �-
Dl
. •
1\'Telcome to our site. Here you can purcbase a new car or build your drearn car. L?J
�: pa....,t!!ocle: Current Node
u
·011
'<
Q Design l o Split l @l Sourc� \ 8] l<asp:Content#Content2 j� >
769
32. fejezet: ASP.NET-vezérlőelemek, -témák és -mesteroldalak
Welcome to C ars R Us
Want a RED slug bug?
Come to CarSuperSite.com
Welcome! �
Welcome to our site. Here you can purchase a new car or build your dream car.
Welcome! : Home
Megjegyzés Egy oldal mesteroldalát programozottan egy Page osztályból származtatott típus
Preini t eseményén belül rendelhetjük hozzá az oldalhoz a Master tulajdonság segítségéveL
770
Sokoldalú ASP. NET-webhely készítése
Megjegyzés Neve ellenére az sqloatasource kanfigurálható úgy, hogy képes legyen bár
mely ADO.NET-adatszolgáltatóval (ODBC, Oracle stb.) kommunikálni, amelyet a Microsoft .NET
platform tartalmaz; nem korlátozódik a Microsoft SQL Serverre. A kívánt DBMS-t a Provider
tulajdonság segítségével állíthatjuk be.
l. A web. con fi g fájlt egy új <con necti onstri n gs> elemmel egészíti ki.
771
32. fejezet: ASP.NET-vezérlőelemek, -témák és -mesteroldalak
</asp:Gridview>
772
Sokoldalú ASP. NET-webhely készítése
<InsertParameters>
<asp:Parameter Name="CariD" Type="Int32" />
<asp:Parameter Name="Make" Type="String" />
<asp:Parameter Name="Color" Type="String" />
<asp:Parameter Name="PetName" Type="String" />
</InsertParameters>
</asp:SqlDataSource>
Welcome! �
8 VW Tan Sal
lO MB Silver MB
"'
773
32. fejezet: ASP.NET-vezérlőelemek, -témák és -mesteroldalak
aí
• x
.. HasterPage.m
rt
Welcome toCars R UseP
Wdcome! •
Edit Columns...
Remove Column
l
IQ Design l O Split l @l Source l EJI<asp:Content#Content2>ll<asp:GridView#GridViowl>l
774
Sokoldalú ASP.NET·webhely készítése
·----�J
Tools •
10 MB Si!Yer ;vm
A példa utolsó lépése a Bui l dcar. aspx tartalomlap megtervezése. Szúrjuk be ezt
a fájlt az aktuális projektbe (a Web Site> Add Content Page menüponton keresz
tül). Ez az új oldal az ASP.NET Wizard webes vezérlőeleme révén egyszeruen
végigkíséri a felhasználót egy sor kapcsolódó lépésen. A szóban forgó lépések je
len esetben egy beszerzendő autó összeszerelési folyamatát szemléltetik.
775
32. fejezet: ASP.NET-vezérlöelemek, -témák és ·mesteroldalak
o ..
..!. PickYourColor G .�::�!j_
--- --
Appear;once
..;. Name Your Car G
El
Title Pkk Your Model
,.l Delivery Oate
El Bet.av;or
AllowReturn True
EnableTheming True
EnableViewState True
StepType Auto
.EJ Misc
(ID)
l Add
·ll Remove
l
l OK
ll Cancel
l
32.16. ábra: A varázsló konfigurálása
A lépések meghatározása után azt lá�uk, hogy a Wizard egy üres tartalom
tartományt definiál, amelyre ráhúzha�uk az aktuálisan kijelölt lépés vezérlő
elemeit. Jelen esetben minden lépéshez adjuk hozzá a következő felhaszná
lóifelület-elemet (ügyeljünk rá, hogy minden elemhez csökkenő azonosító ér
téket adjunk a Properties ablak használatával):
776
Sokoldalú ASP.NET·webhely készítése
777
32. fejezet: ASP.NET-vezérlöelemek, -témák és -mesteroldalak
\\"ekomel >
Pr�voOut; Fon:sh
778
Az ellenőrzö vezérlőelemek szerepe
Requi red Fi el dval i dator Biztosítja, hogy egy adott bemeneti vezérlőelem tar
talmazzon értéket (azaz ne legyen üres).
TaJ Jelentés
779
32. fejezet: ASP.NET·vezérlöelemek, -témák és -mesteroldalak
, Defau
Ha nnár van egy felhasználói felületünk, nézzük végig az egyes tagok konfi
gurálásának folyannatát
A RequiredFieldValidator vezérlőelem
<asp:RequiredFieldvalidator ID="RequiredFieldvalidatorl"
runat="server" controlTovalidate="txtRequiredField"
ErrorMessage="Oops! Need to enter data.">
</asp:RequiredFieldvalidator>
780
Az ellenőrzö vezérlőelemek szerepe
<asp:RequiredFieldvalidator ID="RequiredFieldvalidatorl"
runat="server" controlToValidate="txtRequiredField"
ErrorMessage="Oops! Need to enter data."
Initialvalue="Please enter your name">
</asp:RequiredFieldvalidator>
A RegularExpressionValidator vezérlőelem
<asp:RegularExpressionvalidator ID="RegularExpressionvalidatorl"
runat="server" ControlTovalidate="txtRegExp"
ErrorMessage="Please enter a valid us SSN."
validationExpression="\d{3}-\d{2}-\d{4}">
</asp:RegularExpressionvalidator>
781
32. fejezet: ASP.NET-vezérlőelemek, -témák és -mesteroldalak
Megjegyzés A . NET platform két olyan névteret tartalmaz (System. Text. RegularExpressi ons és
system.web. Regul arExpressions), amely az ilyen minták programozott kezelésével foglalkozik.
A RangeValidater vezérlőelem
<asp:Rangevalidator ID="Rangevalidatorl"
runat="server" controlTovalidate="txtRange"
ErrorMessage="Please enter value between O and 100."
Maximumvalue="lOO" Minimumvalue="O" Type="Integer">
</asp:Rangevalidator>
A CompareValidator vezérlőelem
782
Az ellenőrzö vezérlőelemek szerepe
783
32. fejezet: ASP.NET-vezérlőelemek, -témák és -mesteroldalak
<asp:validat:ionsummary id="Validat:ionsummaryl"
runat:="server" Widt:h="353px"
HeaderText:="Here are t:he t:hings you must: correct:. ">
</asp:validat:ionsummary>
<(j <:SI
-
r jJ Untitled Page n�·�·�· - "
111-11-1111 �
Valae<20
2
�
l Post back l
Here. are the things you must correct.
784
Az ellenőrzö vezérlőelemek szerepe
/\'�roups..ll5pl<"tOefty�t.aopLQt:Oetau�t.ase�l ,., x
l
!
.�:;:d tie;�,! �
,....,
aSD!Piiú�I#Pariel2
���=;SSN j Vali�� l ;
i!.o::�-:o=-::�::.�=:·::::::t:!�.�-==-:-:.�.-::: :�.�:·::.-:.�·=:-=:�.�::·.�::.��"!.�:.'!�=-':"::.��
785
32. fejezet: ASP.NET-vezérlőelemek, -témák és -mesteroldalak
</form>
786
Témák használata
Témák használata
787
32. fejezet: ASP.NET-vezérlőelemek, -témák és -mesteroldalak
A* .skin fájlok
Az egyetlen fájl, amelyet rninden témaalkönyvtár biztosan tartalmaz, a *.ski n
fájl. Ezek a fájlok határozzák meg különféle webes vezérlőelemek megjelenését
és működését. Ennek szemléltetésére hozzunk létre egy új, FunWithThemes
nevű webhelyet Ezután szúrjunk be egy új, BasicGreen.skin nevű *.ski n fájlt (a
Web Site >Add New Item menüpont segítségéve!), a 32.22. ábrán látható módon.
Add New !tom - C:\My Books\C# and u,., .NET Platform 4th ed\Code\Chapter 33\funWilhThomes\ 'i}_.,
Templates:
(§IDG
� LJ e::J � � � LJ �§_;§ � .
W�b Form Mast�Page: WebUser AJAXCiient AJAXClient AJAXCiient AJAX Master AJAXW•b AJAX·enab...
Control Behavior Control library Page Form WCFServlee
<tl
Browser Fill!:
�
Class
�
Class
[ffJ
Data$g
�
Generic
jJ
Global
li]
.
HTML Pag•
i
JScriptFiJe:
�
UNQ to SQL
Olagram Handfer Applicati... Classes
"
�
-
W&>
i1 il
XML Fil•
[ffJo
XMLSch•ma
�
XSLT Fil•
W�Service:
Configurat...
�
Name BasicGreen.skin
l Add
ll Cancol
l
32.22. ábra: A •.skin fájlok beszúrása
788
Témák használata
A Visual Studio 2008 figyelmeztet, hogy hagyjuk jóvá a fájl hozzáadását egy
App_Theme mappához (ez pontosan az, mint amit szeretnénk). Ekkor az
App_Theme mappa valóban tartalmaz egy BasicGreen nevű almappát, és
benne az új BasicGreen.skin fájlt.
A *.skin fájlokban nyílik lehetőség a különféle vezérlőelemek megjelenésé
nek és működésének meghatározására az ASP.NET-vezérlőelem deklarációs
szintaxisa révén. Az IDE sajnos nem támogatja a *.skin fájlok tervezését. Úgy
csökkenthetjük a gépelési időt, ha beszúrunk egy ideiglenes *.aspx fájlt a prog
ramunkba (pl. temp.aspx) , amelyben elkészíthetjük a vezérlőelemek felhaszná
lói felületét a Visual Studio laptervezője segítségéveL
Az eredményül kapott markupot bemásolhatjuk a *.sk in fájlba. Ekkor
azonban el kell távolítanunk az összes webes vezérlőelem azonosítóattribútu
mát. Erre azért van szükség, mert nem egy adott, például gomb megjelenését
és működését szeretnénk megadni, hanem az összes gombét.
A BasicGreen.skin alapértelmezett megjelenést és működést definiál a Button,
a TextBox és a calendar típusok számára:
789
32. fejezet: ASP.NET-vezérlöelemek, -témák és -mesteroldalak
Solution Explorer
.-..
l ., C:\.-\FooWrthlbemes\
; ; ... � App_Data
�-- � @i,IJ"I§
! $· · � BasicGreen
� j �--�· tJ} BasicGreen.slcin
: EJ···
.. ,·. CrazyOrange
L. f.W' CrazyOrange.skín
d;J..
i@ Default.aspx
L. (!} web.config
790
Témák használata
<configuration>
<system.web>
<pages theme="BasicGreen">
</pages>
</system.web>
</configuration>
A SkiniD tulajdonság
791
32. fejezet: ASP.NET-vezérlöelemek, -témák és -mesteroldalak
Erre mutat példát a 32.24. ábra, amelyen egy CrazyOrange témát használó
oldal látható. A legfelső gombhoz a névtelen arculatot rendeltük hozzá, míg
az oldal alján található gomb sk i n ID tulajdonsága a B i gFontButton értéket
vette fel.
su .... Tu We Th Fr Sa
� 2Q .ll l J. d !!
� 2 z § 2 1.Q ll
li ll ll ll 12 !Z .!§ :
12 lQ il ll n Z!! �
2.2 ll � 2Q .ll l
2 1 !! � § z §
792
Témák használata
jNo:rh;;;;-II"G;;e�1h;;;;] r--thto;;;;;;n;;,;;-1
793
32. fejezet: ASP.NET-vezérlőelemek, ·témák és -mesteroldalak
'
}
}
}
794
Vezérlőelemek elhelyezése HTML-táblákkal
<body MS_POSITIONING="GridLayout">
<form id="Form2" method="post" runat="server">
795
32. fejezet: ASP.NET-vezérlőelemek, -témák és -mesteroldalak
'l>mult:uspx·v� �x
" - "" , . . .. .. , . __ ,
.
..
ít'ábie) ..
'
. _,
·_:.c
- --·
� Cut
·c •
[Q Copy
:""""'
� Paste
Paste Altemate
:
· ····-··
)( Deiete
NowStyle...
Insert •
Delete •
Select •
. � ---------·
--- --
t '-
Modify
•
l� . �:�;9;;- · c:;.��- -�
..
-
-
Editimage SplitTable
• •
Megjegyzés A könyv példái nem igénylik, hogy HTML-táblák segítségével tervezzünk oldala
kat, ám nem haszontalan, ha tisztában vagyunk ezek hasznosságával a webes fejlesztésben.
796
Összefoglalás
Összefoglalás
797
HARMINCHARMADIK FEJEZET
Az állapot
}
}
rr,s:;��L�at
•
e Examplel
-
r Set Faw;i;; Ca;- l
,·---·----------
. --- 1
i Get Fawnte Car _ [lbiFavCar
J
l_i<
il Q Design j o Split IB Sourco l EJ�§]<form#forml>j�j<asp:Labei#Lobell>j G
33.1. ábra: Az egt;szerű állapotlap felhasználói felülete
800
Az állapot
801
33. fejezet: ASP. NIT állapotkezelési technikák
}
}
Állapotkezelési módszerek
az ASP. NET-ben
• ASP.NET-nézetállapot használata,
• a gyorsítótár-objektum használata,
• süti használata.
802
Az ASP.NET-nézetállapot szerepe
Az ASP.NET-nézetállapot szerepe
803
33. fejezet: ASP.NET állapotkezelési technikák
A nézetállapot bemutatása
Vegyük észre, hogy a ListBox elemeket közvetlenül az* .aspx fájlba drótoz
zuk. Mint azt már tudjuk, a HTML-űrlapon található összes <asp:> definíció
automatikusan kirendereli a HTML megjelenítését a végső HITP-válasz előtt
(feltéve, hogy rendelkeznek a runat="server" attribútummal).
A <%@Page%> direktíva rendelkezik az opcionális Enableviewstate attribú
tummal, amelynek értéke alapértelmezés szerint true. A viselkedés letiltásá
hoz a következőképpen módosítsuk a <%@Page%> direktivát:
804
Az ASP.NET-nézetállapot szerepe
Pontosan mit jelent a nézetállapot letiltása? A válasz az, hogy attól függ. Ha a
kifejezés előző definícióját nézzük, úgy gondolhatnánk, hogy ha letil�uk az
*. aspx fájl nézetállapotát, akkor a webkiszolgálóhoz irányított visszaküldé
sek között elvesznének a ListBox értékei. Ezzel szemben, ha így futta�uk az
alkalmazást, meglepve tapasztaljuk, hogy a ListBox értéke attól függetlenül
megmarad, hogy hányszor küldünk vissza adatot.
Sőt, ha megnézzük a böngészőnek küldött forrás-HTML-t (a böngészőben
az oldalon kattintsunk a jobb gombbal, majd válasszuk a View Source menü
pontot), azt lá�uk, hogy a rejtett _VIEWSTATE mező még mindig jelen van:
805
33. fejezet: ASP.NET állapotkezelési technikák
806
Az ASP.NET·nézetállapot szerepe
807
33. fejezet: ASP.NET állapotkezelési technikák
Add New !tem • C:\My Books\C# and the .NET Platfenn 4th ed\Code\Chapter 34W.-5tateApp\
Templates:
ü LJ � -
li � li LJ ®j �
Webform Master Pagi!! WBJUser AJAXC!i�t AJAX Client AJAX Client AJAXMaster AJ� Web AJAX·enab...
Control Behavior Control library Page Fenn WCF Service
�---
ü
Browser File
�
Cl ass
l)
Class
�
DataSt:t
-�
Generic
� -
Global
[!J
�HTML Page
�
JScript File
m
UNQto SQL
u
Diagram Handlex Appiielition Classes
Class
� l
� � � � - �
l:5. i �
Report Report R�ource Fill!: Site Map Skin File SQL StyleSheet Text File WCF Service
W11ard Database
-·
� -
il
· -· · · -· · ·
� � '
� .
�
Name: Globc!li.asax
Add jj Cancel
<script runat="server">
void Application_Start(object sender, EventArgs e)
808
A Global.asax fájl szerepe
{
ll Az alkalmazás indulásakor lefuttatott kód.
}
r::..;
. .. ,, ..,:,,.,:,:. , ,��i;:.·�.������;;.-�L·:<:{.;:;.·
.. -,<:I,<:i:.i�h ·r:� · ; ., , ,,
809
33. fejezet: ASP.NET állapotkezelési technikák
810
A Global.asax fájl szerepe
A HttpApplication ősosztály
ugyanazt a funkcionalitást biztosí�a, mint a system. web. ur. Page típus (a látható
felhasználói felület nélkül). A 33.2. táblázat bemuta�a a kulcsfontosságú tagokat.
� x
�8 <�cr1.pt r!..l�at:.=".server">
{
Code t!:a:. ru!'!.s o:: apt:l.:..catl.o:: s:.art:.:p
thl..s. r ei
l PreRequestHandlerEx.cute
l PreSendRequest(ontent
VOl. d
l PreSendRequestHeaders
1 -J Profile
l ReleaseRequestState
Request · • •·
VOl. d
"'
33.3. ábra: Ne feledjük, ilogy a Global.asax fájlban rejtőzködő tagok sziilője a HtipApplication osztály
811
33. fejezet: ASP.NET állapotkezelési technikák
Mivel a Gl obal . asax fájl explicit módon nem dokumentálja, hogy alapjául a
HttpApplication ősosztály szolgál, fontos megjegyeznünk, hogy az "az egy"
812
Az alkalmazás és a munkamenet közötti különbség
Webalkalmazás (HttpApplication)
A munkamenet n munkamenet
(HttpSessionState) (HttpSessionState)
B munkamenet
(HttpSessionState)
813
33. fejezet: ASP.NET állapotkezelési techniká k
. ·, ' .
.
� .
' : .,, � . •,
. �
' .
" .
Application["currentcaronsale"] = "colt";
Application["MostPopularcolorOnLot"] = "Black";
}
814
Az alkalmazás és a munkamenet közötti különbség
815
33. fejezet: ASP.NET állapotkezelési technikák
((CarLotrnfo)Application["carsiternfo"]).currentcaronsale);
}
éi·
.
.
Fun with Application State
n
l
l
l
Get Car On Sale
l
·l l
• Car on sale: Coh u
• Most popular color: Black
• Big shot SalesPerson: Chucky
.
y
Alkalmazásadatok módosftása
816
Az alkalmazás és a munkamenet közötti különbség
Application("SalesPersonofTheMonth");
Application.unlock();
817
33. fejezet: ASP.NET állapotkezelési technikák
Az alkalmazás-gyorsítótár használata
818
Az alkalmazás-gyorsítótár használata
Adatok gyorsitótárazása
819
33. fejezet: ASP.NET állapotkezelési technikák
<script runat="server">
ll Definiáljunk statikus szintű gyorsítótár-tagváltozót.
static cache thecache;
ll A gyorsítótárban tároljuk.
thecache.Insert("AppDataTable",
thecars, null,
DateTime.Now.Addseconds(15),
cache.NoSlidingExpiration,
cacheitemPriority.Default,
new cacheitemRemovedcallback(updatecarinventory));
}
</script>
820
Az alkalmazás-gyorsítótár használata
Először vegyük észre, hogy a G loba l típus definiálta a statikus cache tagvál
tozót. Ennek az az oka, hogy két olyan megosztott tagot definiáltunk, amely
nek hozzá kell férnie a cache objektumhoz. Emlékezzünk rá, hogy a statikus
tagoknak nincs hozzáférése az örökölt tagokhoz, ezért nem használha�uk a
context tulajdonságot.
thecache.Add("AppDataTable",
ll Név, amellyel a gyorsítótárban elhelyezett
ll elemet azonosítjuk.
thecars, ll A gyorsítótárban elhelyezni kívánt objektum.
null, ll van függőségi kapcsolata az objektumnak?
DateTime.Now.Addseconds(lS),
ll Az elem meddig legyen a gyorsítótárban?
cache.NoslidingExpiration,
ll Rögzített vagy csúszó lejárati idő?
cacheitemPriority.Default,
ll A gyorsítótárelem prioritásszintje.
ll A CacheitemRemove esemény metódusreferenciája.
new CachertemRemovedcallback(updateCarrnventory));
Az első két paraméter az elem névj érték párját alko�a. A harmadik paraméterrel
definiálha�uk a cacheDependency típust (amely jelen esetben null, mivel nincs
más olyan entitás a gyorsítótárban, amely a DataTable objektumtól függene).
821
33. fejezet: ASP. NET állapotkezelési technikák
AutoLotConnectedLayer névteret):
822
Az alkalmazás-gyorsítótár használata
dal-OpenConnection(@"Data Source=(local)\SQLEXPRESS;" +
carsGridview.Datasource = thecars;
carsGridView.DataBind();
}
Make
Color
l.
l Q Design l o Splít l Ei! Source l EJ l<asp;Button#btnAddCar>l [8
33.6. ábra: A gyorsítótár-alkalmazás grafikus felülete
823
33. fejezet: ASP.NET állapotkezelési technikák
Munkamenetadatok kezelése
824
Munkamenetadatok kezelése
A Ht:t:pAppli cat:i on-leszármazott típus lehetövé teszi, hogy kezeljük egy mun
kamenet indítását és leállítását a session_St:art:() és a session_End() ese
ménykezelők segítségéveL A session_St:art:() metódusban szabadon létre
hozhatunk tetszőleges felhasználónkénti adatelemet, míg a session_End()
biztosí�a azon feladatok végrehajtását, amelyeket a munkamenet lezárásakor
kell elvégeznünk:
825
33. fejezet: ASP.NET állapotkezelési t echnikák
826
Munkamenetadatok kezelése
/i:>efau�t.aspxt��:J.� � x
.
Fun with Session State
. Which Make,
Down PaymenL
lasp:Ched<Box#chklsLeasi1gl
[r teasej
Delivery Date:
l\LHJUSt 2 UO l :;-
.... Se
30 31 l 2 3 4
5 6 7 8 9 10 ll
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 . 29 30 31
ls;;-�
[lbiUseriD]
[lb1User1nfo]
i 4
827
33. fejezet: ASP.NET állapotkezelési technikák
Session.Remove["someitemweoontNeedAnymore");
Megjegyzés Ha nem kell minden felhasználó Ti meout: értékét módosítani, a web. c onfi g
fájlban (amelyet a fejezet végén megvizsgálunk j a <sessi on state> elem Timeout attribú·
tumával az összes felhasználó számára módosíthatjuk az alapértelmezett 20 perces értéket.
828
A sütikről
A sütikről
Megjegyzés A sütifájlok pontos helye attól függ, hogy milyen böngészőt és milyen operációs
rendszert használunk.
829
33. fejezet: ASP.NET állapotkezelési technikák
Sütik létrehozása
Megjegyzés A legtöbb böngésző legfeljebb 4096 bájtos sütifájlok használatát támogatja. A mé
retkorlát miatt a sütikben leginkább kis adatmennyiséget, például felhasználói azonosítót célsze
rű tárolni, amelynek segítségével azonosíthatjuk a felhasználót, és lekérdezhetjük az adatait az
adatbázisbóL
830
A sütikről
new HttpCookie(txtCookieName.Text,
txtcookievalue.Text);
Response.Cookies.Add(thecookie);
}
_/l)ebu�Uspxl x
1
�
-
run with cookies
·---- ---·- ---- .
llCookie Name
! �------
[Cookie Value
i
l
'
Write This Cookie
·
_
. ··-·- ·-- -·-·-----· · ----,
tr- ---
Show Cookie Data -,
l l
!�<:;��P��L--.---.-·. .----···--·-- .. . . .J
·-- ··-----·-----�----- -·-··----·------ ----..··-·-··-·--
A következő metódus állandó sütit hoz létre, amely 2009. március 24-én jár le:
new HttpCookie(txtcookieName.Text,
txtcookievalue.Text);
thecookie.Expires = DateTime.Parse("03I24I2009");
Response.cookies.Add(thecookie);
}
831
33. fejezet: ASP.NET állapotkezelési technikák
1:1 <Jil l�
li�·
»
Untitled Page
832
A <sessionState> elem szerepe
<sessionstate
mode="InProc"
stateconnectionstring="tcpip=127.0.0.1:42626"
sqlConnectionstring="data source=127.0.0.1;Trusted_connection=yes"
cookieless="false"
timeout="20"
/>
833
33. fejezet: ASP.NET ál lapotkezelési technikák
More n
Folders fl
• Desktop Data Sources Event Viewer Intemett Intemet
(ODBC) Jnformatio... Informatio ...
, Andr� Troelsen
,M Public
Computer
� Network
11!1 Control Panel Local Memory Microsoft Print
� ·Ad�-i�istrat�e T�ls Securi... Oiagnosti... .NIT Fram... Management
/!ij AutoPiay
\1.t Baclc:up and R6tore Center
't Bitloeker Drive Encryption
Defau� Programs Reliabilíty
Q Ease of Access Center and Perfor...
Fonts
�·_ tJ.P.twnd-_ ;m tS.hMinnLI!'!ntP.r -'---
r __ _•
<sessionstate
mode="Stateserver"
stateconnectionstring="tcpip=127.0.0.1:42626"
sqlconnectionstring="data source=127.0.0.l;Trusted_connection=yes"
cookieless="false"
timeout=" 20"
/>
834
A <sessionState> elem szerepe
cím érték (127.0.0.1) a helyi gépre mutat. Ha azt szeretnénk, hogy a .NET
futtatórendszer másik hálózati gépen található aspnet_state. ex e szolgáltatást
használjon (gondoljunk a webfarmokra), az értéket nyugodtan módosíthatjuk.
<sessionstate
mode="SQLServer"
stateconnectionstring="tcpip=127.0.0.1:42626"
sqlconnectionstring="data source=127.0.0.l;Trusted_Connection=yes"
cookieless="false"
timeout=" 20"
/>
835
33. fejezet: ASP.NET átlapotkezelési technikák
Az ASPNETDB.mdf adatbázis
létezett.
836
Az ASP.NET profil·API·ja
aspnet_regsql
<configuration>
<connectionstrings>
<add name="Sqlservices"
connectionstring ="Data Source=Productionserver;Integrated
security=SSPI;Initial catalog=aspnetdb;"
providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<profile defaultProvider ="SqlProvider">
<providers>
<clear/>
<add name="AspNetSqlProfileProvider"
connectionstringName="Localsqlserver"
applicationName="ShoppingCart"
type="System.web.Profile.sqlProfileProvider,
System.web,
version=2.0.0.0,
culture=neutral, PublicKeyToken=b03f5f7flld50a3a" />
</providers>
</profile>
</system.web>
</configuration>
837
33. fejezet: ASP.NIT állapotkezelési technikák
Amint azt már korábban említettük, a felhasználói profilt a web . config fájl
ban definiáljuk Igazán tetszetős ebben a megközelítésben, hogy a profilt az
örökölt Profile tulajdonság segítségével erősen típusos módon kezelhetjük
Ennek bemutatására hozzuk létre a FunWithProfiles új webhelyet, és nyissuk
meg we b . config fájlját szerkesztésre.
Az a célunk, hogy létrehozzunk egy profilt, amely a bejelentkezett felhasz
nálők otthoni címét és az általuk kezdeményezett adatküldések számát tartja
nyilván. Nem meglepő, hogy a profil adatait a <P rofile> elemben kell megadni
névj érték típus párok formájában. Nézzük a következő profilt, amelyet a
<system.web> elem hatókörében hoztunk létre:
<profil e>
<properties>
<add name="StreetAddress" type="System.String" />
<add name="City" type="System.string" />
<add name="State" type="System.string" />
<add name="TotalPost" type="System.Int32" />
</properties>
</profil e>
838
Az ASP.NET profil·API·ja
839
33. fejezet: ASP.NET állapotkezelési technikák
•X
F un
_
_ _w
__.tl__
h_P_r_
o_fi_I_
es _____________ ·�
=·l!i
Street Addres . 'i
City l :1
1
State l
asp:Button#btnSt.brJj;:
1:Subnit Data -�
[Jb!UserData]
l •
·
<\:.Defauk j"'btnSubmit.Ciick(object sender, Ev< l
-:'
• •
..:.�;
Profile.City- txtCity.Text;
Profile.StreetAddre�s
�
= txtStreetAddress.� r .
'
l:;! lastUpdatedDate
2{ Prorile.
zs!
26! J
•
5' Properties
27;
'fff PropertyValues l
5' Providers
•'> Save !
·���
'V SetPropertyValue r:' '-
!Tli'·"
StreetAddress
"!ft -!
-��-�---·.!
·�ToString
840
Az ASP.NET profii·API·ja
l l!:!' C:\...\FunWrthProfiles\
8- b App_Data
l rfl... [] t·$1Q�IaUl:IXI•1j
) $ .. @] �efault.aspx
j \ :.... � Defau�.aspx.cs
l L. [!} web.config
�
"
� Solution Explorer§Ct�
841
33. fejezet: ASP.NET állapotkezelési technikák
'Ci � l�
»
[]_�. §'!
Untitled Page ... �.
�-
State Minnesota
l Submit Data l
You live here: 123 Happy Lane, Grand Marais, Minnesota
842
Az ASP.NET profil-APl-ja
A fejezet végén szót kell ejtenünk arról, hogy a profiladatokat hogyan defini
álhatjuk a web. con fig fájlban. A jelenlegi profil egyszerűen négy adatot hatá
rozott meg, amelyeket közvetlenül a profiltípusból érhetünk el. Bonyolultabb
profilok készítése során segítséget jelenthet, ha az összetartozó adatokat
egyedi néven csoportosítjuk. Nézzük meg a következőt módosítást:
<profile>
<properties>
<group name ="Address">
<add name="StreetAddress" type="String" />
<add name="City" type="String" />
<add name="State" type="String" />
</group>
<add name="TotalPost" type="Integer" />
</properties>
</profile>
843
33. fejezet: ASP.NET állapotkezelési technikák
[Serializable]
public class userAddress
{
public string Street = string.Empty;
public string city = string.Empty;
public string State = string.Empty;
}
<profile>
<properties>
<add name="Addressrnfo"
type="UserAddress"
serializeAs ="Binary"/>
<add name="TotalPost" type="Integer" />
</properties>
</profile>
A profil jóval többet tud annál, rnint amit ebben a fejezetben bemutathatunk.
A Profile tulajdonság például valójában a Profilecommon típust foglalja magá
ban. A típus segítségével programozottan lekérdezhetünk információt adott fel
használóról, törölhetünk (vagy felvehetünk új) profilokat az ASPNETDB.mdf adat
bázisból, frissíthetjük a profilt, stb.
844
Összefoglalás
Összefogla lás
845
8. rész
Függelékek
A FÜGGELÉK
A COM és a .NET
együttműködése
A könyv célja az, hogy a C# nyelvhez és a .NET platforrn által nyújtott alap
vető szolgáltatásokhoz szilárd alapot biztosítson. Ha szernbeállí�uk egymás
sal a .NET által biztosított objekturnrnodellt és a Microsoft korábbi kompo
nensarchitektúráját (COM), nyilvánvalóvá válik, hogy két teljesen egyedi
rendszerről van szó. Függetlenül attól, hogy a COM már hagyományos ke
retrendszemek tekinthető, lehetnek olyan COM-alapú rendszereink, amelye
ket szeretnénk az új .NET-alkalrnazásainkba integrálni.
A .NET platforrn szerencsére olyan különböző típusokat, eszközöket és
névtereket biztosít, amelyek meglehetősen egyszerűvé teszik a COM és a .NET
együttműködését. Az A függelék a .NET és a COM együttműködési folyama
tának, valarnint a kapcsolódó RCW-nek (Runtirne Callable Wrapper -futási
időben hívható burkoló) a vizsgálatával kezdődik. A második rész az ezzel el
lentétes szituációt vizsgálja: COM-típus kommunikál .NET-típussal a CCW
(COM Callable Wrapper-COM-ból hívható burkoló) segítségéve!.
A .NET Framework 3.5 SDK és a Visual Studio 2008 több olyan eszközt biz
tosít, amelyek segítenek áthidaini a szakadékat a két egyedi architektúra kö
zött. A .NET-alaposztálykönyvtár emellett meghatároz egy olyan névteret
(system.Runtime.Interopservices) , amelyet egyedül az együttműködés tá
mogatásának szenteltek. Nézzük meg először egy egyszerű példát arra, ami
kor egy .NET-osztály COM-kiszolgálóval kommunikál.
850
A .NET és a COM együttműködésének egyszerű példája
Ebben a részben egy Visual Basic 6.0 ActiveX *.dll kiszolgálót készítünk,
amelyet aztán egy C#-alkalmazás fog felhasználni.
Megjegyzés Sok COM keretrendszer létezik a VB6-on kívül (pl. az Active Template Library
[ATL] és a Microsoft Foundation Classes [MFC]). A függelékben a VB6-ot használjuk a COM-ki
szolgáló létrehozására, ez ugyanis rendkívül felhasználóbarát szintaxist biztosít a COM-alkal
mazások készítéséhez. Ám nyugodtan használjuk akár az ATL-t, akár az MFC-t.
End Function
851
A függelék: A COM és a .NET együttműködési képessége
A C#-ügyfélalkalmazás elkészítése
párbeszédablakot.
� Add Reference
OK ll Cancel
852
A .NET és a COM együttmüködésének egyszerü példája
Solution Explorer ii
j � � ��
ii&J CSiworpComCi ient
li, Eh-·
ffi � Properties
a;. References
. : i�-n ·O dH§iJdiji
i : ··· System
.a
· \··- System.Data
·O
, :_ -o System.Xml
f.•- {il Program.cs
Solution Explorer
�����
ii! CSiworpComCiient
$-· §j Properties
EJ.. e;, References
. :.....
SimpleComServer
.O
System
: ... ·O
i-- ·O System.Data
L .a System.Xml
..
ciJ... Qbin
. B-� [C) D�bug
D CSharpComCiient.exe
u CSharpComCiient.pdb
D CSharpComCiient.vshost.exe
. D Interop Stmple-CcmServer.dll
ffi Dobj
L. '.!ol Program.cs
..
853
A függelék: A COM és a .NET együttműködési képessége
using system;
using simplecomserver;
namespace csharpcomclient
{
class Program
{
static void Main(string[] args)
{
console.writeLine("***** The .NET COM Client App *****");
Comcalc comobj = new comcalc();
console.writeLine("coM server says 10 +832 is { O}",
comobj.Add(lO, 832));
Console.ReadLine();
}
}
}
iij C:\Windows\system32\cmd.exe
a -
a
a-�•
854
Egy .NET együttműködési szerelvény vizsgálata
855
A függelék: A COM és a .NET együttműködési képessége
�,:1
�
r:.�B·� ·�--------
MySolution
-
--
---
... i •
--------
at i � l tm ·
-----
�
� x
�J
h>
l$ ;l!J CSharpComCiient -
liJ ·.O Interop.SimpleComServer
i El-· o MWiAH§I
·
856
A futási időben hívható burkoló
857
A függelék: A COM és a .NET együttmüködési képessége
Megjegyzés COM-objektumonként mindig egyetlen RCW lesz, függetlenül attól, hogy a .NIT
kliens hány interfészt kapott a COM-típustól (a többinterfészes VB6 COM-objektumokat a függelék
későbbi részében vizsgáljuk). Ezzel a módszerrel az RCW karbantarthatja a COM-objektum meg
felelő COM-azonosítóját {és referenciaszámlálóját).
858
A futási időben hívható burkoló
single system.single
DECIMAL system.Decimal
DATE System.DateTime
GUID System.Guid
CURRENCY system.Decimal
859
A függelék: A COM és a .NET együttműködési képessége
860
A COM lDL szerepe
861
A függelék: A COM és a .NET együttműködési képessége
�-�_!lrtfile _
� ! _TYf'<'lib :
o.. {000020 0 -0 0000-0010-8000-00AA006D2EA4}
� • - {000020 0 1-0000-0010-8000- 00AA006D2EA4J
� -� {000020 05-0000 -0010-8000-00AA006D2EA4J
o. � {00000206-0000-0010-8000 -00AA006D2EA4J
o .. � {00000 30-0 0000-0010-8000 -00AA006D2EA4J Q
� ·· .� {00000600- 0000-0010-8000 -00AA006D2EA4J
o- � {00020430-0000-0000-C000-0J00046 ?
• l. • "'lll
or l • 0'---;:..;------,
Computei\HKEY.ClASSES.ROOl\Typelib
A. 8. ábra: A HKCR l TypeLib felsorolja az adott gépen található összes regisztrált típuskönyvtárat
. . .. ••y
--- - . ..
-- ,,
--L..
862
A COM lDL szerepe
lc1asses
1ri!' CompareEnum
i'm Connect•on -
ri!' ConnectModeEnum D
ri!' ConnectOptionEnun
ri!' ConnectPromptEnw
'ri!' CopyRecordOplions
lleni>er of A!lQl!!!
,�..<:"'/"'_'!"" """---
---------------- 1
���!!]
.·::rSENS Mntslyp<tlibfary (VEt l,. A:.,�N-1.01
L$f�l.OTypeLibntoi)'{Va-l � tDrnM4M'Ef0-.41�77013S100o\l
�t' Setup KRmtll.OlYJ)41' l.ibQiy ('1.
i j f'Sctuputl.OTypel.ibnry(VI'O'l _,
: i-P SHGJNA 1.0 Type.Libtary (Ver 1. Typdib
i [--t" Shoc:kw-�sh(V�l.o) i- (D724MU-FEFD-U6B-BAEC·B8(77088ADOAI
: i-r;w • '-l.O=�ont.Sawf
l "- -f' SlCCl.DType.l.iM!y{Verl.O) i--O
. ��o"'�\lkm\AndrewTrocbcn\M)'Boob\C#•ndlM.NfTP!..tformCthed\Cod�A\SOmpleeomSuwt\SirnpleC�.dll
J-
!-r suJJALibl.OTypt:Libr•.ytverO
l :.-f' SlUll.OTypeUbrM)'(Vtrl.O)
l-t' SNAGITl.OTypelib.-..y(VerlJ L HELPOIR::: C:\Uscn\AndftwTroelsen\My Boola\C# llnd tM .NfT Pt.tform 4th ed\Co.M\Ap� A\SimplrCom�r
.�
\
.; Adöinl.Ollll)el'tb'IMV.rl• !_:_-------'
;....,
A.11. ábra: A SimpleComServer keresése az OLE/COM objektummegjelenítő segítségével
863
A függelék: A COM és a .NET együttműködési képessége
[uuid(8AED93CB-7832-4699-A2FC-CAE08693E720), version(l.O)]
library simplecomserver
{
importlib("stdole2.tlb");
interface _comcalc;
[uuid(012B1485-6834-47FF-8E53-3090FE85050C), version(l.O)]
coelass comcalc {
[default] interface _comcalc;
};
};
Az IDL-attribútumok
864
A COM lDL szerepe
Az lDL-könyvtár-utasitás
[uuid(012B1485-6834-47FF-8E53-3090FE85050C), version(l.O)]
coelass Comcalc {
[default] interface _comcalc;
};
865
A függelék: A COM és a .NET együttműködési képessége
Az IDispatch szerepe
IDL-paraméterattribútumok
Az lDL-lel kapcsolatosan még tudni kell, hogy a VB6 paraméterei hogyan je
lennek meg a háttérben. A VB6 alatt az összes paramétert referenciaként ad
juk át, hacsak nem használjuk explicit módon a syva l kulcsszót, amelyet az
lDL [i n] attribútumával ábrázolunk. Egy függvény visszatérési értékét az
[out, retvalJ attribútumokkal jelöljük. Ezért az alábbi VB6 függvény:
' VB függvény
Public Function Add(Byval x as Integer, ByVal y as Integer) as
Integer
Add = x + y
End Function
866
Típuskönyvtár használata együttműködési szerelvény készítéséhez
867
A függelék: A COM és a .NET együttműködési képessége
868
Típuskönyvtár használata együttműködési szerelvény készítéséhez
[id(Ox60030000)]
HRESULT Add( [in] short x, [in] short y, [out, retval] short* ) ;
Type.GetTypeFromProgiD("SimpleCOMServer.comcalc");
object calcDisp Activator.creaternstance(calcobj);
=
869
A függelék: A COM és a .NET együttműködési képessége
ll Az eredmények megjelenítése.
console.writeLine("Late bound adding: 100 +24 is: {0}'', sum);
console.ReadLine();
}
Option Explicit
' Tagváltozók.
Private currsp As Integer
Private maxsp As Integer
Private Make As carType
870
Bonyolultabb COM-kiszolgáló készítése
Option Explicit:
871
A függelék: A COM és a .NET együttműködési képessége
A VB6 (és maga a COM) alatt nem áll rendelkezésünkre a kényelmes klasszi
kus megvalósítási származtatás. Ehelyett kénytelenek vagyunk a tartalma
zás/delegálás modellt (a "van egy" kapcsolatot) használni. Tesztelési célból
adjunk egy utolsó 1'. cls fájlt az aktuális Engine nevű VB6-projektünkhöz, és
állítsuk az rnstancing tulajdonságát Publi cNotcreatable értékre (rnivel sze
retnénk azt megakadályozni, hogy a felhasználó közvetlenül létrehozhasson
egy Engine objektumot).
Az Engine alapértelmezett nyilvános interfésze rövid és egyszerű. Defini
áljunk egy függvényt, amely sztringtömböt ad vissza, és ez képviseli a motor
rninden egyes hengerének becenevét (igaz, nem szokás barátságos nevet adni
a hengereknek, de hát... ) :
Option Explicit
872
Az együttműködési szerelvény
Van tehát egy ActiveX szerverünk, amely két interfészt támogató COM
osztályt foglal magában. Emellett visszaadhatunk egy belső COM-típust a
cocar [default] interfészének használatával, valamint együttműködhetünk
néhány alapvető programozási szerkezettel (felsorolt típusokkal és COM
tömbökkel). Folytassuk a kiszolgáló lefordításával (és ha ezzel készen va
gyunk, állítsuk be a bináris kompatibilitást), majd zárjuk le az aktuális VB6-
munkaterületet.
Az együttműködési szerelvény
873
A függelék: A COM és a .NET együttműködési képessége
�oqectBr� t�
'P
� �
�� ·a
�--------�---- ---------------- ----
·�X
Browse: My Solution • ... J • q l !b l � •
<Search>
• li] .).
!±l&J CSharpCarCiient
$--a lnterop.Vb6ComCarServer
� B···<.> ri!'§MGJ.YJI
�--c(ill CarType
1!1--�_CoCar
$-�_CoCar
$···>-O CoCar
EiJ"'"" CoCar_vO
lfl··· _CoCar_BiewUpEventHandler
ffi---� _CoCar_Event
$--<1$ _CoCar_SinkHelper namespace Vb6ComCar5erver
Member of Interop.Vb6ComCarServer
$-� CoearClass
Eil->oO _Engine
_j
$· �Engine
..
$--� EngineClass
$--� _IOriverlnfo
ffi--..o !Oriverlnfo
w____rn_- -� oriv__
-_ _I_ re _nI _fo _cla_ _ss________ �L- ----- -----�
A. 13. ábra: Az lnterop. VbComCarServer.dll szerelvény
874
Az együttműködési szerelvény
tagjaiból áll:
875
A függelék: A COM és a .NET együttműködési képessége
Ahhoz, hogy választ kapjunk arra a kérdésre, hogy ez az egy típus pontosan
hogyan muta�a meg az összes megvalósított interfész tagjait, a Visual Studio
2008 Objektum böngészőjében nézzük át a cocarel ass implementált interfé
szeinek és ősosztályainak listáját (lásd az A. l4. ábrát).
Ez a típus megvalósí�a a _cocar és _IDriverrnfo interfészeket, és "normá
lis" nyilvános tagként teszi hozzáférhetővé őket.
876
Az együttműködési szerelvény
$ ...o
. CoCar_vO
$· .· � _CoCar_BiewUpEventHandler
,
l ' l \. . •Q GetEngineQ
j . . •..· .·9 SpeedUpQ
ffi- . .-o _CoCar_Event
�· '1$ _CoCar_SmkHelper
'
l-·· �
· DriverName
'i
l
. i : .. f BlewUp
;..... ....o CoCar
@ . . -o CoCar j"1•�-==--==-
- �-�--"7.- =�-=�7-':..'.u·'1··---
CoCarCiass
l
_, _CoCar_Event
J
public class
.
COM-események elfogása
877
A függelék: A COM és a .NET együttműködési képessége
�
.-,�
t-"'�'-, "'. �-..
_ �� .---�- - �...-- . -.·-- "'...�l!/:
�t �
-l'
...
�• • •
.. '!...
{ ' • "
_,,..\.. � .
- �
. . '' - ' -- .;t:· . - ..•,
class Program
{
static void Main(string[] args)
{
console.writeLine(";'**** cocar client App **''**");
cocar mycar = new cocar();
878
A COM és a .NIT együttműködési képessége
879
A függelék: A COM és a .NET együttműködési képessége
A System.Runtime.lnteropServices attribútumai
-� ·.· . '
' ' . ·-.· �·-·:.:;�7.}.���:-���1;.:;:�: -�-.-� �·: '·: '._- i
.
.
• . ·.,t'.. ::.".. :,,.v ...'.. . . ' .
880
A CCW szerepe
A CCW szerepe
COM
alkalmazás
881
A függelék: A COM és a .NET együttműködési képessége
A .NET-osztályinterfész szerepe
882
A .NET-osztályinterfész szerepe
Osztályinterfész definiálása
883
A függelék: A COM és a .NET együttműködési képessége
namespace ComcallableDotNetserver
{
[Classinterface(ClassinterfaceType.AutoDual)]
public class DotNetcalc
{
public int Add(int x, int y)
{ return x + y; }
884
Saját .NET-típusok készítése
CreateGUID ld ®liliif3íli
Choose the desired for!Mt below. then select '"Copy'" to
copy the results to the cfiptxwd (the results can then be l� l
pasled in!o )'OU! SOU<ce code� Choos e '"E><it'" when
l t!ewGUIO
done. l
GUID F011Mt l
EJ!Íl l
6!. IMPLEMENT_OLECREATE(.. )
0� DEFINE_GUIO(... )
0;). sl�ic const struct GUIO { ... )
•
@�J!��[���.:::rc.��''''!:�:::�Ji
Resuli
{4137CFAB·5300-4667·ADF2·8E2CD63CB462}
[Classinterface(ClassinterfaceType.AutoDual)]
[Guid("4137CFAB-530B-4667-ADF2-8E2CD63CB462")]
public class DotNetcalc
{
public int Add(int x, int y)
{ return x + y; }
885
A függelék: A COM és a .NET együttműködési képessége
gacutil -i ComcallableDotNetserver.dll
A tipuskönyvtár létrehozása és
a .NET-tipusok regisztrálása
Megjegyzés A .NET Framework 3.5 SDK a t l bexp. exe nevű eszköz biztosítja. A regasm. exe
segédprogramhoz hasonlóan ez az eszköz .NET-szerelvényből hoz létre típuskönyvtárakat, vi
szont nem adja hozzá a szükséges bejegyzéseket a rendszerleíró adatbázishoz. Emiatt általá
ban a regasm. exe-t használjuk az összes szükséges lépés végrehajtásához.
886
Az exportált típus adatainak a vizsgálata
/�DotNetserverr��csrQbject� • x
Application
Configuration: lActíve (Oebug)
·l
Build
Platform: lActíve (Any CPU)
·l
Build Ev�nts
[l
.c
A. 17. ábra: Szerelvény regisztrálása COM-mal való együttműködésre a Visual Studio 2008 használatával
887
A függelék: A COM és a .NET együttműködési képessége
888
Visual Basic 6.0 tesztkliens készítése
References - Project! ..
Avaiable Refurenc:es:
l OK
l
DCmí20
DColeaguein1:>0rt 1.0 Type Lilrory
A <:ancel
l
D colaader 1.0 Type Lilrary o
D colaader 8.0 Type Lilrary
DCOM + l.O Aam Type Lilrary
Browse.••
l
��i���.l� ��ari ..!J
D Common L� Ru:ltime Execution Engine 2.0 Lb Priocity
DC<>mpat!Jl 1.0 Type Lilrary
D ComPkJs 1.0 Catalog Repiicalion Type Lilrary
�
l
D COI!"(lOrlentelrle VSf1exGrld 8.0 (lig1t) �
D Comect to a Networl: Projector l. O Type Lilrary
D eRDesigner 9 Type Lilrary �
nrrvntpyt 1.0TvnP l iv;vv
•L�--'� •
-CotnCalableOotNetServer
l
l Location:
L�:
C:"tlsers\Andrew Troe!lsen.,...y Bool<s�# ..-.d the .!ET Platfon
St..-.dard
Ami a GUI front endet illeti, legyen teljesen egyszerű. Egyszerűen egy gomb
bal kezeljük a DotNetcalc .NET-típust. A kód a következő (figyeljük meg, hogy
meghívjuk az _obj ect interfész által definiált ToSt ring() metódust):
889
A függelék: A COM és a .NET együttműködési képessége
Összefoglalás
A felügyelt és nem felügyelt kódnak a jövőben meg kell tanulnia időről időre
együtt dolgozni. Emiatt a .NET platform különböző módszereket kínál a két
világ összeolvasztására.
A függelék nagyobbik része a korábbi COM-komponenseket alkalmazó
.NET -tipusok részleteire összpontosított. A folyamat egy szerelvényproxy
készítésével kezdődik a COM-típusok számára. Az RCW továbbítja a híváso
kat az alapul szolgáló COM-binárisnak, és felügyeli a COM-típusok leképe
zését .NET -ekvivalensükre.
Ezután azt vizsgáltuk, hogy a COM-típusok hogyan hívhatják az újabb .NET
típusok szolgáltatásait. Ehhez arra van szükség, hogy a .NET-szerelvényben lét
rehozható típusokat regisztráljuk a COM számára, és a .NET -típusokat leírja egy
COM-típuskönyvtár.
890
B FÜGGELÉK
{llatformfüggetlen .NET
fejlesztés a Manóval
Megjegyzés Azt azonban ne feledjük, hogy ha csak Windows operációs rendszer alá szeret
nénk programokat írni, akkor erre aMicrosoft .NET Framework 3.5 SDK és a Visual Studio 2008
a legjobb megoldás.
A Cll szerepe
892
A .NET platformfüggetlen természete
�:�c'-':j�;':'f�,ji'l�>;.�·"fl#f•t;;"�;'�
···.'-".1f·.;:.. t." '''L·'" � l�l
��'Y.�"f:��·"·,,·�.�".D};t':r·
�'f.Pii,;-_,�·v.•i�!: ,.;�'.fi1"•';);' ,_;_!
l, •
893
B függelék: Platformfüggetlen .NET-fejlesztés aMONO-val
Megjegyzés Még ha nem is vagyunk kíváncsiak a .NET platforrnak közötti lehetőségeire, ta
nácsos elolvasni az ECMA-334 és az ECMA-335 specifikációkat, mivel alapos betekintést en
gednek a C# nyelv és a .NET platform belső működésébe.
A népszerű CIL-disztribúciók
894
A .NET platformfüggetlen természete
Megjegyzés A Portable .NET-et nem vizsgáljuk meg ebben a függelékben. Azt azonban fon
tos tudni, hogy nem a Mono az egyetlen pillanatnyilag elérhető platformfüggetlen .NET·disztri
búció. Érdemes rászánni az időt, és a Mono platform mellett kipróbálni a Portable .NET·et is.
A Mono hatóköre
• LINQAPI-k
895
B függelék: Platformfüggetlen .NIT-fejlesztés aMONO-val
Abban biztosak lehetünk, hogy a Novell Mono csapata már dolgozik azon,
hogy átültesse ezeket az API-kat és C# 2008 programozási szolgáltatásokat a
Mono-projektbe. Valójában több C# 2008 nyelvi funkció már része a Mono
legutolsó verziójának (1.2.5), köztük az implicit típus hozzárendelés, az ob
jektuminicializáló szintaxis és a névtelen tipusok.
Megjegyzés A Mono webhelyén található egy oldal, amely leírja a Mono működésének álta
lános struktúráját és a jövőbeli verziók terveit (http:/ /www.mono-project.com/plans).
896
A Mono beszerzése és telepítése
[i
Select�s
wtlch componerts shoUd be i1staled?
Select the �s you want to i1st.. : clearthe componerts you do not wart to
nst.. . Click Nelll when you are ready to cortnx!.
lhj ilOlotion TI
0 Mono Ries 1261 �lB �
"''"'�
L. 0 Gtk#2.10.2 Plles 26.5MB
!-0 Monodoc 9.2MB _
l <Back
ll Noolt >
ll Cancel _J
897
B függelék: Platformfüggetlen .NIT-fejlesztés aMONO-val
-- _ _ _ _ _::_b]§�- - ----
t
More
Folders
>,
v i . �ji� Feldor
fli�
etc
File Fold�r
Mono·ll.S
indu de
f"" -·
j info
j; bin file Folder File Fcld�r
----·
�.i. gc
[• Jt; include libexec
j., info File Folder
mon
File Foldet
share
File Folder
B. 2. ábra: A Mono-könyvtárstruktúra
mono -version
898
AMono-fejlesztőeszközök
!ijj ..
. w:� Pro l l€1!ííiniíííl
=
8
!.'or1c �·er·s�or� . 2 . 5 Cliilrl
Ci :;ab l ed:
:..r
nen�
.. ·ch itecture : :.;(.G
0 L!I_...
6.3. ábra. A Mono futtató környezet
A Mana-fejlesztőeszközök
• mcs/gmcs: C#-fordítók,
899
B függelék: Platformfüggetlen .NET·fejlesztés a MONO·val
A C#-forditók használata
mcs -?
A "generikus rnono C#-fordító" vagy gmcs az mcs egy olyan verziója, amely
- rnint ahogy azt a neve sugallja - tárnagalja a .NET 2.0-specifikus C# nyelvi
funkciókat (generikus tipusok, kovariancia/kontravariancia, nullázható típu
sok, részleges tipusok, névtelen rnetódusok stb.) és rendelkezik a .NET 2.0
alapú alaposztálykönyvtárak referenciáival. A gmcs parancssori beállításai
ugyanazok, rnint az mcs hasonló beállításai, és ezeket a következő paranccsal
ellenőrizheljük
gmcs -?
Mivel két C#-fordító van, joggal feltételezheljük, hogy csak a gmcs használható
olyan .NET-alkalmazások készítésére, amelyek kihasználják a C# 2.0 nyelv le
hetőségeit. Valójában a két fordító közül először az mcs támogatta a 2.0 funkció
it, amelyeket aztán tökéletesítettek és áthelyeztek a gmcs-be is. A függelékben
található példakódok rnindkét C#-fordító segítségével lefordíthatók
900
A Mana-fejlesztőeszközök
.i ·"· �.�.:�t'..-:��..i:
���
.. �
Mono-specifikus fejlesztőeszközök
901
B függelék: Platformfüggetlen .NET·fejlesztés a MONO·val
�us
Jelenté
fejteszt&iszköz
SQL A Mono-projekt tartalmaz egy grafikus front endet
(SQL), amelynek segítségével relációs adatbázisokkal
dolgozhatunk, különböző ADO.NET-adatszolgáltatók
használatávaL
Megjegyzés Az SQL·t és a Glade·et a Start menü Applications mappáján, azon belül pedig a
Mono telepítési könyvtárán keresztül is elindíthatjuk. Ezt mindenképpen próbáljuk ki, mert így
világosan láthatjuk, milyen tartalmassá vált a Mono platform.
A monop(2) használata
monop2 system.object
902
.NIT-alkalmazások készítése Monóval
Mono-kódkönyvtár készitése
ll coreLiboumper.cs
using System;
using System.Reflection;
using System.ro;
903
B függelék: Platformfüggetlen .NEr-fejlesztés aMONO-val
File.createText(string.Format("{O}.txt",
theType.FullName)))
{
ll Típ u s kiírása a fáj lba.
sw.writeLine("Type Name: {O}", theType.FullName);
sw.writeLine("Members:");
foreach(Memberrnfo mi in theType.GetMembers())
sw.writeLine("\t-> {O}", mi.Tostring());
}
return true;
}
}
}
ltarget:library
lout:CoreLiboumper.dll
coreLiboumper.cs
gmcs @LibraryBuild.rsp
sn -k myTestKeyPair.snk
904
.NIT-alkalmazások készítése Monóval
/target: library
/out:coreLiboumper.dll
/keyfile:myTestKeyPair.snk
coreLibDumper.cs
gmcs @LibraryBuild.rsp
B.5. ábra: Amanadis lehetóvé teszi, hogy megtekintsük egr} szerelvény köztes nyelvi kódját,
metaadatát és önleírását
905
B függelék: Platformfüggetlen .NEr-fejlesztés aMONO-val
Most, hogy a coreL i bournper. dll szerelvényünk erős névvel rendelkezik, tele
pítsük a Mono GAC-ba, a gacutil használatával. A Microsoft azonos nevű
eszközéhez hasonlóan a Mono gacutil segédprogramja támoga�a a telepítést,
az eltávolítást és a C:\Program Files\Mono-<version>\ lib\mono\gac könyv
tárba telepített aktuális szerelvények listázását. Az alábbi parancs aGAC-ba te
lepíti a coreL i bournper. dll fájlt, és beállí�a azt megosztott szerelvényként.
.. � mono
• ;j 1.0
..
. 2.0
-i.boo
Megjegyzés A -l opcióval a gacutil listázza aMana GAC-ban található összes szerel vényt.
906
.NET-alkalmazások készítése Manóval
namespace consoleclientApp
{
public class Program
{
public static void Main()
{
console.writeLine(
" ***** The Type Dumper App *****\n");
ltarget:exe
lout:ConsoleclientApp.exe
lreference:coreLiboumper.dll
consoleclientApp.cs
907
B függelék: Platformfüggetlen .NET-fejlesztés aMONO-val
gmcs @ClientBuild.rsp
mana ConsoleclientApp.exe
1 �- Notepad++ - C:\My Books\C# and the .NET Platform 4th ed\Code\Appendix 8\CorelibDumper\Syst...l = l lEl lii&liil
File Edit Search View Forrnat Language Settings Mac:ro Run TextFX Plugins Window ? X
�-- � -�- -"c--
.
·-·
- - --- - � - -� ---�- � �--
-· =-
· - -- --·--
· -
· ��---- ---=--:
.o G Et Ci -� ''ro l "' .. lt:ll :» --c
--l •-
bs
-
l ->t Ili Eii l ::;."
t--------------- OOo-
l c
�
-----
@ r� litl
---· -----
l
BSyotem�Tive��-�
!ype N"""': System.Threading .Thread
Hembers:
->Void .cwr(lhreadStart)
->Void .ctor(!hreadS�art., Int32)
->Void . c tor (Parairtet.erizedThreadStart)
-> Void .c'tor(Parameterizedihread.Start, Int32)
-> Sys-cem.Runtime .Remotinq.Contexts .Contex"t qet._Current.Context ()
-> IPrincipal qet_CurrentPrincipal O
-> Void se't_CUrrent:Principal (IPrincipal)
10 -> Sy�'te!tl. Threading. Thread get_Curren'tihread ()
i l. -> Syst:em.LocalDat:aStoreSlot AllocateNa.med.DataSlot (System. String)
12 ->Void freeNamedDataSlot{Sy�'tem.St:ring)
13 -> Sy� tem.LocalDataSt.oreSlot AllocateDa'taSlot: ()
l-i -> System.Object GetData(Sy�t:em.LocalDa'taStoreSlot)
15 -> Void Set:Dat.a (Sys'tem. LocalDataS'toreSlot, Sy3tem.Object)
ló -> Syor;em.AppDomain Ger; Domain()
P -> Int32 GetDomainiD(I
19 -> System.LocalDataStoreSlot. GetNamedDataSlot {System.St:ring)
1� ->Void Reset.Abort{)
� �
�-�i.:__.=� --�:r-- .. �·
Nermal text file nbchar:4124 Ln:l Col:l Sei:O Dos\Windows ANSI INS
908
.NET·alkalmazások készítése Monóval
using System;
using System.windows.Forms;
using CoreLiboumper;
using System.orawing;
namespace winFormsClientApp
{
ll Alkalmazásobjektum.
public static class Program
{
public static void Main()
{
Application.Run(new Mainwindow());
}
}
ll Az egyszerű ablakunk.
public class Mainwindow : Form
{
private Button btnoumpToFile = new Button();
909
B függelék: Platformfüggetlen .NIT-fejlesztés aMONO-val
ll Kanfiguráljuk a gombot.
btnDumpToFile.Text ="Dump";
btnDumpToFile.Location new system.Drawing.Point(13, 40);
ll Kanfiguráljuk a szövegdobozt.
txtTypeName.Location = new System.Drawing.Point(l3, 13);
txtTypeName.size = new System.Drawing.Size(341, 20);
Controls.Add(txtTypeName);
}
}
}
ltarget:winexe
lout:winFormsclientApp.exe
lr:coreLiboumper.dll
lr:System.windows.Forms.dll
lr:System.Drawing.dll
WinFormsclientApp.cs
910
.NIT-alkalmazások készítése Manóval
mono WinFormsClientApp.exe
[System.Mailt
lc:=���::JI
911
B függelék: Platformfüggetlen .NIT-fejlesztés aMONO-val
Megjegyzés Ne feledjük, hogy aMono 1.2.5 csak korlátozott módon támogatja a C# 2008 nyelvi
szolgáltatásait, úgyhogy néhány példa a 13. fejezetből csak úgy-ahogy müködik.
"
"Mono IDEs: Going Beyond the Command Line : Mono-kompatibilis
•
IDE-ket vizsgál.
"
"Building Robust Uls in Mono with Gtk# : Asztali alkalmazások ké
•
Megjegyzés A Mono online dokumentációs webhelyét a közösség tartja fenn, ezért ne le
gyünk meglepődve, ha néhány befejezetlen dokumentáció linkjére bukkanunk! Mivel a Mono a
Microsoft .NET ECMA-kompatibilis disztribúciója, ezért használhatjuk a sokoldalú MSDN online
dokumentációt is aMono felfedezésekor.
912
Összefoglalás
�
jc-;;,tents l
----' ---
l�A·
l l
t:rmt
. •t� .!,li..IJ.ifflffltii
l Class Libran.
' Mono Libraries
=j
=l
-i
G-class Library nnm<> ibrari<>�
ffi-Mono Libraries czilla Libraries
ov<>ll Lihr=>ri<>c
,j
ffi-Gnome Libraries
�
J
onoDevelon IDE Libraries
- lÍJ-Mozilla Libraries Mnnnlinht/<;jlv<>rlinht
[$r Novetl Libraries
[3--MonoDevelop IDE Libraries
éJ Mocnlight/Silverlight
l # Lannuane Snecificatinn
C# omnil<>r Error R<>fer<>nce
Mono Dev<>lonment Tools
Mono Embeddinn
8-C# Language Specification
GJ-c# Compiler Error Reference �
" Internet l Proleeted Mode: Off �100% •
Összefoglalás
A függelék célja az volt, hogy bemutassa a C# programozási nyelv és a .NET
platform közötti programozás jellegzetességeit a Mana-keretrendszer haszná
latávaL Ahogy láthattuk, a Mono több parancssori eszközzel rendelkezik, ame
lyek lehetővé teszik különböző .NET-szerelvények - beleértve aGAC-ba tele
pített, erős névvel ellátott szerelvényeket, a Windows Forms alkalmazásokat és
a .NET-kódkönyvtárakat- készítését.
A Mono nem teljesen kompatibilis a .NET 3.0 és a .NET 3.5 programozási
API-kkal (WPF, WCF, WF és LINQ), illetve a C# 2008 nyelvi funkcióival (bár
a Mono 1.2.5 korlátozott módon tárnagalja a C# 2008 nyelvet). A munkála
tok már zajlanak (Olive-projekt), hogy a Microsoft .NET platformjának ezen
jellemzői bekerüljenek a Manóba. Bárhogyan is, ha olyan .NET-alkalmazást
szeretnénk készíteni, amelyet különböző operációs rendszerek alatt is lehet
futtatni, a Mana-projekt remek választás e célra.
913
Tárgymutató
B C# typeof operátor,504
C#-definíció,87,902
barátságos név,49,172,207,310,333,513, C#-fordító,489,490,893,896, 899,900,904,
872 905
base kulcsszó,812 C#-forrás,247,502,621, 639,648,650,670,
beágyazott,40,150,158,225,257,310,401, 681,722,902,911
466,492,493,494,498,506,516,521, C#-kulcsszó,859
525,535,546,566,570,584-587,636, C#-metódus,339
658,662,681,721,796,861 CAS,3,38,40,41,46,50,52,69
beágyazott erőforrás,493,586, 662,681, 861 CAS-beállítás,46,52
beépített,162,190,345,349-352,355,390, ccw, 849, 881,882
391,395,482,531,533,535,543,568, CCW által megvalósított interfész,882
593,699 CIL,849,855,873,893,894,899,901
beépített támogatás,699 címke,505,599,649,650,651,652,653,655,
beépülő modul, 699 694,711,717,755,777,801,842
befejezetlen dokumentáció,912 címkézés,329
bejövő adat,374 ClassinterfaceType felsorolás,883
bejövő paraméter,339,341,365,375, 603, CLI,143,891,892,893,894,899,912
712 Click esemény, 64, 194,196,211,215,217,
bejövő parancssori paraméterek,367,477, 231,388,402,411,427,444,446,505,
478 545,712,748,783
916
Tárgymutató
917
Tárgymutató
G
F
generikus gyűjtemény, 461
F1,329,534,596,597 generikus Ust<T>, 147,192,446,449
fejlesztőeszköz,901 generikus osztály,320
fejlesztői nyelv,891 generikus tipusok, 649,900
fejlesztői platform,691 globális szerelvénytár,126,290,855,867,
felhasználóbarát,112,175,206,329,333, 879,886,894,898,906
851 globális szerelvénytár (GAC),894
felhasználóbarát szintaxis,851 GNU General Public Ucense,894
felhasználói felület eleme,190,455,457, grafikai alkalmazás,902
470,572,594,601,611,663,667 grafikus asztali alkalmazás, 72
felhasználónkénti,825 grafikus felhasználói felület,152, 191,395,
felsorolás,6,"58,134,137,182,418,457,543, 427,453,517,531
551,870
918
Tárgymutató
325,329,331,355,391,401 743,760,764,768,788,808
hosztoló ablak,572
hosztoló alkalmazás,41,329,834 J
hosztolt,313, 341,378,726,728
li�L,278,578,580,685,686,691-696,698- J2EE,81,278,279,281,287
709,711,712,714,717,718,722,726, Java,419,531,699,733,801,892
730,733,736,737,746-748,754,757-760, jelölőnégyzet,67,280,334,336,556,557,
768,770,778,783,795,796,803-805,845 686,693,749,886
919
Tárgymutató
K kódhozzáférés-szabályozás,40
kódol,337
kapcsolat nélküli,100,101,107,109, 143, kódolás,24,25,312,357,620
147,167,169-171,186,190,212,230, kódrészlet,539
236,237,240 kódsor,190
kapcsolat nélküli réteg, 147 kód-újrafelhasználás,143
kapcsolatsztring, 105,127,129,130,134,136, komponenstálca,224
144,154,160,205,214,225,341,771 konfiguráció,391,688,739
kapcsolódó működés,351,414,415,468,531 konfigurációs fájl, 115,267,281,291,292,
kapcsolódó objektum,71,73, 74, 97 306,309,310,313,320,321,323,325,
kapcsolódó típusinformáció, 903 327,329,331,332,344,706,743
kapcsos zárójel, 513, 885 konstans adat,539
karakterek sorozata,175 konstans érték,778
karbantartható,130 konstruktor, 94,98,132,151, 214,227,480
kattintási esemény kezelője,431,565,677, konzol,24,28,61,274,347,565,685
732 koordináta,625,645
képpont,441,449,583,653 korai kötés, 868,882, 883
keretrendszer,3, 36,45,81,416,419,452, kovariancia, 900
453,461,468,738,739,850,851,913 könyvtár,6,7, 8,9,10, 14,39,142,152,284,
késői kötés,861,866,868,869,880,883,888 341,367,531,688,689,690
késői kötés folyamata,869 könyvtárstruktúra,4,5,62,282,724,898
kétoperandusú operátor,782 kötés,7, 190,194,285,287,296, 298-303,
keyfile kapcsoló,867 307,323,380,516,600,601,603,607,
kezdeti érték,507 611,613,868,874
kezdeti indítás, 687 Kötéselem,299,301,302
kezdeti méret,404 Kötési osztály,299,301,302
kezdőérték,178 közös funkció,99,113
kezeletlen kivétel, 810 közös interfész, 107,108, 114,247
kezelő,64,99,106,134,143,148,162,196,426, közös nyelvi infrastruktúra,891,893
478,492,497,587,708,712,740,836 közös típusrendszer,281, 893
kiinduló állapot, 659 köztes nyelvi kód,727,855,901,905,911
kiinduló kód, 220 közvetlen hozzáférés,537, 812,875
kimenet8,188,307,449,474,490,531,536, közvetlen létrehozás,29
559,580,624,635,647,681,736,752,854 közvetlen objekturnreferencia,866
kimeneti folyam, 737 közvetlen ősosztály,417
kis- és nagybetü érzékeny,172 kulcsszó,133,198,439,501,502,503,877
kis gyűjtemény, 93,273,702 kurzor,103,147,569,586,591,756
kisalkalmazás,688,834 külön sor,702
kisbetüs,97 külön szál,352
kisebb teljesítmény,883 különálló fájl,5,705
kiszolgálóoldali szkriptkód,702,716 különálló szerelvény,78
kivétel,67,144 - különböző névtér,268,396
klasszikus ActiveX,861 külső fájl,4,272,523,562,636,661,662,719,
klasszikus ASP-, 687,701,702,705,709,717, 763,821
733,801,866 külső felhasználó,39,277,278,460
klasszikus COM, 105, 409, 861, 868,882 külső függőség, 900
külső gyártótól származó,487
920
Tárgymutató
M
N
MAC,279,461
megadott metódus,96,361 nagybetűs,97
megfelelő együttműködési szerelvény,867 napló, 722
megfelelő mód,688 nem absztrakt,4,486,488,517
megjegyzés,240,585,629 nem statikus metódus,489
nemfelügyelt kód,461
921
Tárgymutató
Ny p
nyilvános adat,77,86,92,815 parancssor,308,898,908
nyilvános konstruktor,179 parancssori alkalmazás, 159, 166,174, 205,
nyilvános mező,76,250 320,329,330,334,852,892,895
nyilvános osztály,207,298,883 parancssori fejlesztőeszköz,894,898
nyilvános tag,298,366,369, 865,870,875, parancssori fordító, 490
876,883 parancssori paraméter, 255,690
nyilvános tulajdonság,76,77,250,366,367, parancssoros fordító,397,473,517,898,900
423,433,485 párbeszédablak,293,325,334,336,357,
nyilvánvaló probléma, 116,346 373-379,428,429,431-435, 442,445, 447,
448,450,460,467,611,612,613,616,
760,804
o,ó
példány, 14,349, 350,364,365,366,367,
Objektum böngésző,855,863,873,876 488,751,817
objektum sorositás, 91 platform,3,38,83, 90,97, 99,162, 167,190,
objektuminicializáló szintaxis, 264,265,896 267,276,278,279,281,286,395,436,
objektumrnodell,170,193,272,273,278, 440,453,454,511,685,705,716,771,
454,471,705 782,849,851,890,892,893,894,913
objektumok gyűjteménye, 170,178,192 platforrnfelismerő OL,850
objektumreferencia,4,25,365,865 platforr.nfüggetlen,4,891,892,893,895,911
objektumváltozó,83 platforr.nfüggő,850
OLE,104,105,106,129,850,863,869,887 platforrnfüggő gépi kód,850
OLE View eszköz,863,869 platformközi,461
OLE View segédprogram, 863,887 Pocket PC,106, 462,469
00, 73,76,734,746 polimorf,5,551,729,755
OOP,699 polimorf interfész,5,551,729,755
opció,293,294,320,361,633,662, 688,732, polimorfizmus, 79,113,298,308
867 prefix,488,502
opcionális szerelvényszintű információ,861 prefixumos,441,550
operációs rendszer,16,26,38,50,55,73,81, privát adat,76,77
277-285,287,299,300,332,456,457, privát mező,76,250
461,540,687,691,829,851,891,892, privát szerelvény,711,720,723,724,855
894,895,896,897,911,913 privát sztringváltozó,481, 871
operátor,376 privát tag,77, 144,433, 492,873
optimalizált, 301,456,589 privát tagváltozó, 144,433,492,873
osztálydefiníció,250,542 Pro ASP.NET 3.5 in C# 2008, Second
osztálykönyvtár,233,234,295,893 Edition, 707
osztálykönyvtár tervezési útmutató,893 Pro WPF in C# 2008
osztálykönyvtár-projekt,233,234 Windows Presentation Foundation with
.NET 3.5,Second Edition,619
922
Tárgymutató
923
Tárgymutató
T U,Ú
tábla,l18-123,132,141,145,159,163,171, Ul elem,647
174,175,176,178,195,200,205,206, újrafelhasználás,'220,456,533
210,223,224,228,237,251,774,795, újrafelhasználható, 382,387,705,746
796,806,8'22 Unicode,25
tagváltozó,192,227,331,407,446,448,449, Unix,279,891,894,895,899
799,800 tnRI,38,303,306,312,313,321,338,464,662
tárolt eljárás,103,ll O, lll,118,120,121, lnRL,39,42,45,56,66,67,106,318,374,
137,150,151,152,158,161,162,167, 459,686,688,691,694,702,713,731,
170,247,255,256,259,260,261,276, 732,736,737,764,765,767,824,827,
771,835,836 829,901
tartalmazás, 872 utasítás,120,142,145,153,255,551,594,
távoli alkalmazás,66 597,672,731,865
távoli hely,38,83 utasításkészlet,320, 903,905
távoli kiszolgáló,686 utolsó argumentum,543,869
távoli webkiszolgáló,65,67,458 utolsó feladat,123,342,374,543,674
távoli webszolgáltatás,282
telepítés,125,333,836, 898
telepítő,687,897
ü,ű
teljes COM lDL gyakorlat, 861 ügyfélalkalmazás, 852,907,908,909
teljes definíció,625 ügyfélalkalmazás könyvtár, 909
teljes elérési útvonal,6,44 ügyfélkonfigurációs fájl,324
teljes implementáció,153 ügyféloldali proxy, 284,317,320,321,335,
teljes kód,132,236, 446,841 379
teljes leírás,147,534 üres érték, 700
teljes megvalósítás,874 üres sztring,793
teljesen működőképes C#-fordító,894
924
Tárgymutató
v w
vágólap,381,617,824,885 WCF,104,152,162,277,278,280,281,285-
valódi COM,857,881 334,337,338,339,341,342,343,344,
valós típus,348,351 348,351,356,357,368,377,378,379,
változónév,488 380,382,895,896,913
van egy,24,38,64,73,117,127,198,199, WCF-ügyfél,289,295,317,320,323
207,211,243,246,249,261,271,303, web,706,747,748,771,772,790,791,799,
361,398,426,475,505,573,598,599, 837,838
602,701,780,825,826,856,860,865, webes alkalmazás,278,282,458,459,461,
867,872 464,685,687
\TB,143,255,531,862,863,865,866 webhely,106,280,390,687,688,689,691,
\TB6,453,851,852,854,855,857,858,859, 708,716,719,721,723,725,730,737,
860,861,862,863,864,865,866,867, 745,759-790,797,803,808,812,815,
869,870,871,872,873,875,879,883, 818,829,837,845,912
888,889,891 webszolgáltatás,282,283,284,285,290,
\TB6 fordító,852,867 293,298,300,301,306,319,337,368,
\TB6 kód,865,871 370,374,377,461
végfelhasználó,53,65,183,360,443,444, WF,162,345,347-353,355,356,357,358,360,
445,546,547,553,554,570,572,573, 364,365,366,368-374,377,379,382,384,
575,577,582,587,596,602,741,742, 388,389,390,391,895,896,913
752,767,770 while ciklus, 153, 186
végrehajtható,38,50,99,100,277,295,309, While tevékenység, 361, 362, 363
310,313,329,342,343,347,351,382, Win32 API,419,453
398,458,459,464,473,489,491,496, Windows Communication Foundation,71,
499,593,686,721,743,799,855,908 162,267,277,278,343,351,357,895
végrehajtható alkalmazás,459,491 Windows Forms ügyfélprogram,909
végrehajtható fájl,38,50,100,277,295,309, Windows Forrns-alkalmazás, 64,104,190,
310,313,329,342,343,382,398,464, 191,211,212,220,295,382,387,395,
489,496,686,743,799,908 397,398,406,408,420,436,442,443,
végrehajtható szerel vény,458,459,499, 452,752,799,801
721,799 Windows Forrns-vezérlőelem,52,391,395,
végső engedélykészlet,67 409
végső kivételkezelő,810 Windows Intéző,10,36,57,323,710,908,909
verem,470 Windows Presentation Foundation,190,
veremalapú,649 267,348,395,453,457,530,534,539,
vesszővel elválasztott, 133,864 592,617,619,681,895
'View Type Library menüpont,887 Windows Workflow,162,164,293,345,
virtuális könyvtár,66,67,337,688-691,701, 347,350,351,355,356,359,361,391,
703,738 455,895
virtuális metódus,416,511,536,625 WindowsXJP,55,81,300,456,687,690
virtuális tag,416,456,557,649 windowsos,749
'Visual Basic,699,709,851,882,888,896,899 Workflow,293,347,351,355,356,357,358,
'Visual C#,117,518,692 370,383,386,388,390
'Visual Studio IDE,292,336,896 workspace,862,870
'Visual Web Developer,692
visszaküldés,698,734,737,739,755,778,
x
783,801,803,806,812
visszatérési érték,10,88,113,114,120,140, X509 digitális aláírás,39
148,244,281,284,289,337,361,370, X509-es digitális tanúsítvány,42
375,381,512,542,615,616,839,875 x86,897
vizuális tervező,220,224,355,404,407, XAML böngésző,52,463,490
435,520,521,522,533,771 XBAP,52,459,460,461,463,500,518
925
Tárgymutató
XML-adatok,80,85,86,100,173,189,267,
269,284,329
XML-alapú konfiguráció, 281,290,743
X11L-dokumenhln1,78,86,87,88,175,188,
239,267-273,275,276,486,496,502,
600,606,611,613,614,616,617
X11L-elem,85,86,87,188,268,269, 315,
337,488
XML-fájl,52,85,188,611,721,723,763, 765,
767,768
XML-megjegyzés, 268
XML-névtér,80,306,488,501-503,513,516,
563,693
XML-tartalom,272,275
XML-webszolgáltatás,71,221,277,282,
283,285,287,298,299,302,306,337,
346,348,351,368,369,370,372,375,
377,690,708,892,901
XSD, 188,725,901
926
A szakmai lektorról