Ahogy az előző részben láttuk, a content control-ok vagy más néven a structured document tags szolgáltatás az Office dokumentumokban lehetővé teszi a formázás és az adatok elkülönítését. Két korlátozó körülményt azonban mindenképpen meg kell említenünk:
- Ez a szolgáltatás egyelőre csak a Word 2007-ben érhető el, az Office család más termékeiben nincs ilyen lehetőség.
- Elég fájó, de sajnos nincs táblázat vezérlő, sőt az ismétlődéseket (pl. felsorolásokban) sem tudja kezelni ez a funkció. Mivel ez sokaknak fáj, ezért várhatóan az Office 14-ben vagy talán már egy javítócsomagban megkapjuk ezt is.
Nem beszéltünk még arról, hogy hol tárolódnak az adatok és hogyan kapcsoljuk azokat a vezérlőkhöz. Az adatok a DOCX állományon belül egy önálló XML fájlban tárolódnak, alapértelmezés szerint a \customXml mappában.Itt nyers XML-t kell elképzelni, semmi Open XML specifikus elem nincs benne, az viszont praktikus, ha van egy önálló, egyedi névtere. Ha például a dokumentumunk egy levél, amelyben a címzett és a feladó adatait programozottan akarjuk kitölteni, akkor a szükséges adatokat betehetjük a \customXml\item1.xml fájlba az alábbi formában:
<?xml version="1.0" encoding="utf-16"?>
<Contact xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.msdnkk.hu/samples/Contact">
<FirstName>György</FirstName>
<LastName>Balássy</LastName>
<Company>MSDN Kompetencia Központ</Company>
<City>Budapest</City>
<Zip>1117</Zip>
<Address>Magyar Tudósok krt. 2.</Address>
<Sender>Feladó Ferenc</Sender>
</Contact>
Ennek az XML fájlnak az írása és olvasása megoldható a korábban már említetett Packaging API segítségével, hiszen ez is egy Open XML document part.
Hogyan kapcsoljuk ezt a fájlt a csomag többi részéhez? A \word\_rels\document.xml.rels fájlt kell kiegészítenünk az alábbiakkal:
<?xml version="1.0" encoding="utf-8"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<!-- Sok Relationship elem van itt már... -->
<Relationship
Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml"
Target="../customXml/item1.xml"
Id="R0fbcbf7dffdc49b6" />
</Relationships>
A [Content_Types].xml fájlhoz nem kell nyúlnunk, mert abban már szerepel egy definíció, amely magában foglal minden XML kiterjesztésű állományt. Kiegészíthetjük viszont egy XML properties résszel:
<?xml version="1.0" encoding="utf-8" ?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="xml" ContentType="application/xml" />
<!-- A dokumentum többi része itt Override elemekben -->
<Override
PartName="/customXml/itemProps1.xml"
ContentType="application/vnd.openxmlformats-officedocument.customXmlProperties+xml" />
</Types>
Az XML properties fájlban további tulajdonságokat adhatunk meg, például egy ún. data store ID-t:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<ds:datastoreItem
ds:itemID="{70372b4c-0b6e-4f5d-9fa2-39118fe7a889}"
xmlns:ds="http://schemas.openxmlformats.org/officeDocument/2006/customXml" />
Ha több customXml partunk is van, akkor még egy ds:schemaRefs elem segítségével összekapcsolhatjuk a data store-t egy adott XML sémával. Ennek akkor van jelentősége, ha egyébként a dokumentumban több azonos sémájú XML part is van, mert így meg tudjuk adni, hogy pontosan melyikhez kívánunk kapcsolódni.
A tárolást tehát megoldottuk, következő probléma, hogy az egyes vezérlőket hogyan kapcsoljuk az XML fájlban lévő elemek valamelyikéhez. A megoldás a cikksorozat címében oly sokszor említett adatkötés. Nem is akármilyen, hanem kétirányú! Tehát akár kódból módosítjuk az XML állományt, akár a felhasználó ad Wordben új értéket valamelyik vezérlőnek, a másik automatikusan frissül, ezzel semmilyen további munkánk nincsen!
Az adatkötés megadása a word\document.xml fájlban történik az egyes w:sdtPr elemekbe ágyazott w:dataBinding elemekkel. Itt két dolgot kell megadnunk:
- Egy névtér aliast a w:prefixMappings attribútumban.
- A névtér aliast használó és az XML dokumentumban egy elemet azonosító XPath kifejezést a w:xpath attribútumban.
- Ha több azonos névterű XML partunk is van, akkor még egy data store ID-t, ami alapján a Word megtalálja majd az XML partot. Ezt a w:storeItemID attribútumban lehet megadni.
Végül például egy Keresztnév értéket bekérő vezérlő, amely a fent bemutatott XML dokumentum FistName mezőjéhez van kötve így festhet:
<w:sdt>
<w:sdtPr>
<w:dataBinding
w:prefixMappings="xmlns:ns0='http://www.msdnkk.hu/samples/Contact'"
w:xpath="/ns0:Contact[1]/ns0:FirstName[1]"
w:storeItemID="{70372b4c-0b6e-4f5d-9fa2-39118fe7a889}" />
<w:rPr>
<w:i />
</w:rPr>
<w:alias w:val="Keresztnév" />
<w:tag w:val="Keresztnev" />
<w:id w:val="370331103" />
<w:placeholder>
<w:docPart w:val="DefaultPlaceholder_22675703" />
</w:placeholder>
<w:text />
</w:sdtPr>
<w:sdtContent>
<w:r w:rsidR="00136851" w:rsidRPr="00136851">
<w:rPr>
<w:i />
</w:rPr>
<w:t>Keresztnév</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
A jó hír az, hogy mindezt nem kell kézzel odaheggesztenünk minden egyes vezérlőhöz. Bár sem a Wordben, sem pedig a Visual Studioban nincs erre eszköz, szerencsére a CodePlexről letölthetjük a Word 2007 Content Control Toolkitet, ami sokat segíthet a munkában. Egyetlen képernyős alkalmazásról van szó és mivel Windows Formsban készült, kiválóan olvasható Reflectorral (megjegyzem tanulni is lehet belőle, például nagyon érdekes, hogyan vezérli ez a külső alkalmazás a Word kurzorát):
Az alkalmazás használata nagyon egyszerű:
- Készítsük el Wordben a sablon dokumentumot és tegyük bele a vezérlőket a Developer fülről.
- Töltsük be a Word dokumentumot a Content Control Toolkit (CCT) eszközbe, ami után bal oldalon megjelennek a vezérlők.
- A jobb alsó Create a new Custom XML Part linkre kattintva adjunk új XML partot a dokumentumhoz.
- Készítsük el azt az XML dokumentumot például Visual Studioban, amit egyszerűen elő tudunk állítani később kódból, és amilyen formátumú fájlt majd a DOCX állományba szeretnénk helyezni.
- Másoljuk be az XML tartalmát az Edit View fülön lévő mezőbe.
- Váltsunk vissza Bind View nézetre, ahol megjelenik az XML hierarchia.
- Jelöljük ki a bal oldali listában valamelyik vezérlőnket (ez kell), majd a jobb oldali hierarchiában fogjuk meg a hozzá illő XML elemet és dobjuk rá a vezérlőre. Ekkor elkészül az adatkötés. Ha inkább kézzel szerkesztenénk a paramétereken, akkor kattintsunk duplán bármelyik vezérlő sorára és a felbukkanó ablakban adjuk meg az adatokat.
- Végül ne felejtsük el menteni a dokumentumot.
Ezzel még csak az adatkötés paraméterezése készült el, illetve az eszköz megoldja azt is, hogy a DOCX állományban létrejöjjön egy XML part. Ami még hátra van, az a DOCX állományban lévő XML tartalmának módosítása kódból. De ezt majd legközelebb, addig is ezt érdemes kipróbálni!
(folytatjuk)