WPF - de første overvejelser, irritationsmomenter og features
Lad det være sagt med det samme. Der er så mange ting, hvor WPF er Windows Forms overlegen, at der ikke er nogen tvivl om hvilken jeg ville vælge til et nyt projekt. Den helt store er at man nu kan lave ‘platform’-uafhængig kode (det er en tilsnigelse af de større, men der er alligevel lidt om snakken). Når jeg siger platform her, mener jeg det ikke i bredest mulige forstand. Indtil videre har mine forsøg kun henvendt sig til Windows platformen, men til gengæld kan den samme kode (med små modifkationer - og nogle begrænsninger) afvikles både som windows applikation, web-applikation i både IE og FF.
Formatet til web’en er noget de kalder XBAP. Det svarer til en .exe-fil for en browser. Den bliver afviklet i en ’sandkasse’ lokalt på maskinen, hvilket vil sige at der ikke er adgang direkte til systemresourcer, men stadig fuld adgang til grafik-api’et i Direct X/windows. Derved er det muligt bl.a. at lave 3d-acceleret grafik og eftersom det er en ’sandkasse’, er der heller ikke de samme sikkerhedsproblemer, som Active-X komponenter o.lign. Desværre lægger det meget store begrænsninger på anvendelsen af reflektion mv., som gør at vi i praksis er tvunget ud i at lave ekstra ‘tynd’ web-klient til brugere uden for LAN (indenfor kører vi så ‘fuld trust’, når den skal køre i en browser).
Nå, et kort overblik over mine værste oplevelser. Halvfærdig dokumentation og non-uniform navngivning! Hvor svært kan det være at kalde grafiske elementer enten Items eller Children gennemgribende i API’et? Derudover mangler der fyldestgørende forklaringer på hvad forskellige properties gør, og hvilke der skal bruges i det givne tilfælde. WPF kan rigtig… rigtig, rigtig meget - og meget kan laves rigtig, rigtig smart - men hvorfor hulen har de valgt lavest mulige fællesnævner for debugging og fejlfinding? At min main-tråd er væltet havde jeg gættet - og at det var dens skyld vidste jeg også godt… det der måske var interessant for mig, var hvilket komponent, der fejlede - og måske endda hvilke kodelinjer…
Alt grafisk (og en del kode) i WPF kan laves vha. XAML-sproget, som er et temmelig avanceret XML-sprog, som det er meningen at grafiske designere og deciderede programmører skal anvende som fælles sprog. Det er så meningen at det skal være så let-tilgængeligt at ikke-programmører kan bruge det og samtidig så avanceret og kraftfuldt at programmører ikke vender tommelfingeren nedad. Lad os sige det til dels er lykkedes… XAML er, når man vænner sig til det, fantastisk at lave almindeligt statisk layout i - og hvis man kender noget til CSS, giver opbygningen rigtig meget mening. Der hvor filmen knækker er den kodemæssige del af sagen. Det er i praksis ikke særlig tilrådeligt at bruge komponenter/funktioner med parametre i constructor’en. Og så debugging - det er en frustrerende oplevelse at skulle debugge sig vej igennem 800 linjer XML-kode 100% manuelt (ud-kommentering af afsnit/komponenter et efter et) for at finde ud af, at det er fordi man har givet en data-template til en funktion, der kun accepterer control-templates.
Hvis man har prøvet at lave en design-template til et CMS-system i CSS ved man hvor vanskelligt det er at finde en god opdeling og praktisk navngivning, så man undgår overlap, undgår dubletter og samtidig får et bare nogenlunde rimeligt layout. I WPF er alt hierakisk opbygget - det vil sige at der er mulighed for at angive en given parameter rigtig mange steder. Lad os sige, at jeg gerne vil anvende farven sort til min border på en tekstbox indeni en user-control, som ligger i en særskilt DLL, som jeg loader i mit main window (altså… almindelig nogenlunde fornuftig opbygning i fx et login-billede). Det kan jeg definere et af følgende steder:
- Direkte på tekst-boksen (Border = “#000000″.
- På usercontrolen i dens resourcer som en style … (TargetType={x:typeof(TextBox)} … <Setter Property=”Border” Value = “#000000″ /> …
- Ved hjælp af en content template/data tempalte defineret enten i UserControl’en eller main window.
- Ved hjælp af et MergedResourceDictionairy, som kan ligge både i .exe-filen og DLL’en.
- Et vilkårligt sted i koden i .cs-filen for window eller user-control’en.
Og det her er bare et simpelt eksempel… Hvis man ikke har lagt sig en klar strategi fra starten, bliver man hurtigt fanget i inkonsekvens og overlappende styles/properties. For der er nemlig en catch-22 - eftersom alt er hierakisk opbygget, vil en given property blive sat efter den første, der påvirker den - målt fra kontrollen og op-efter. Det vil sige, at en property bliver sat på kontrollen, en anden på stylen… osv.
Og så den store… der er ingen grid-kontrol. Den tager vi lige igen… De har ikke inkluderet en grid… og den kommer heller ikke med i SP1, som skulle være på trapperne. Hvem der har taget den beslutning, kunne jeg godt tænke mig at tage en laaang kop kaffe med. Det er fuldstændig vanvittigt, ikke at have en grid i et bare nogenlunde proffesionelt kodesprog - især hvis man forventer at proffesionelle virksomheder skal anvende WPF. Det er godt nok ikke mange applikationer, som kan klare sig uden tabulær visning af data. Vi har løst den hurdle ved at anvende et 3dje parts produkt (www.infragistics.com) - vi overvejde Xceed’s, men syntes at performance var uhyggelig tung på den, samtidig med at deres kopisikring var til at lukke op at… den var ikke så heldig.
Indtil videre har jeg holdt mig til statiske skærmbilleder, og kun i begrænset omfang kastet mig ud i animationer og andet gejl. Det jeg egentlig er mest imponeret over, er at skalering og den slags bare virker nu. Skift af skærmopløsning er irrelevant (i hvert fald i teorien) i forhold hvordan layoutet ser ud - alting skalerer blot. Der er stadig lidt med wide-screen formater, men ikke noget, der ikke kan løses. Derudover har jeg koncentreret mig om styles og indlejrede kontroller - jeg kan kun sige, at det spiller for mig.
Så - mit samlede indtryk er, at der er rigtig mange muligheder og meget få begrænsninger i WPF. Men det er samtidig meget mere komplekst end det fremgår af den lille indlægsseddel. Hvis man ikke er dygtig til at kode (og især meget påpasselig med at lave sin struktur tilpas fast fra starten) løber man meget hurtigt panden mod en mur af irritation og frustration. Jeg glæder mig til SP1 til VS 2008/.Net 3.5 - ikke så meget pga. nye features, men snarere pga. performanceforbedringer.
Jeg har fundet en detalje som har gjort det udholdeligt at ‘bygge’ projekter i VS 2008 - luk alle billeder med XAML-kode imens. Af en eller anden årsag opdaterer de imens man bygger, hvilket gør at hver gang en reference bliver opdateret, som har (eller kunne have) indflydelse på den grafiske repræsentation af din kontrol, gennemløbes koden og opdateres… hvilket mildt sagt er fjollet midtvejs i en kompilering.