torsdag den 29. januar 2015
Ændre ID i ASP.NET Webforms i Repeater ødelægger ViewState
Jeg vidste det faktisk godt, men tænkte mig ikke om og nu er det for sent fordi der er lavet så meget baseret på denne model så det kan ikke ændres.
Husk for guds skyld ikke at ændre ID'er på ting fra din repeater når det kommer ud, for så smadrer du alt logik for ASP.NET Webforms når du skal klikke på en knap og få alt tilbage - for så ved den pludseligt ikke hvilke kontroller der er hvad.
Den kan ikke selv mappe det tilbage fordi ID'erne har ændret sig i forhold til hvad den ville give dem, så den mapper dem ikke ind i ASP.NET og det kan give dig en masse problemer.
Så hvis du har brug for fx at vide hvilket nummer, version, udgave, årstal noget er knyttet til, så lav en attribut på elementet som du ved hvad hedder og send det så afsted. Så sikrer du dig at du ikke laver ændringer i det som ASP.NET Webforms forsøger at lave så smart.
Hvis man bare undgår at ændre de ting som ASP.NET selv laver om så er du sikker, og blot tænker over hvordan det kan løses uden at være knyttet op på ID, så kan du lave din egen attribut med MyID="53154" og finde den på det.
Repeater vil ikke opdatere til ny værdi liste med DataBind (ASP.NET Webforms)
Jeg har en side (ASP.NET Webforms) hvor den sætter en liste med data til en repeater.
I _ItemDataBound() ændres navnene fordi de skal have specielle værdier i. Jeg burde faktisk gøre det anderledes, men mere om det i et andet indlæg.
Når man så forsøger at registrere en ydelse med pris 0 skal den returnere et script der giver en popup der spørg om du vil opdatere med 0 fordi de vil blive automatisk fjernet.
Problemet er så at fordi jeg ændrer navnene på kontrollerne så virker viewstate ikke når den kommer tilbage (den kan ikke mappe chkBox_53152, til Mine_priser_Form1_PageHeaderControl_pnlMinePriser_Checkbox53152 - det lange navn ASP.NET selv laver for alt - så den kommer ikke tilbage i repeateren).
Så i Load sættes der ALTID default listen (med det der er gemt før), fordi ellers kan den ikke finde noget i Repeateren fordi så har den ikke nogle item (Nok fordi den ikke kan mappe dem tilbage). Der laves både Datasource = liste og DataBind() for at Click kan finde forskelle i repeateren.
Efter load udføres Click hvori den finder ud af hvilke elementer der har forskelle. Disse ligges ind i listen så listen nu er med de opdaterede værdier fra repeateren og der sættes igen Datasource = liste og DataBind() på samme repeater.
Når man så kommer til _ItemDataBound() så finder den de oprindelige værdier (fordi de er binded første gang), selvom jeg senere har lavet en anden DataBind() med en anden Datasource.
Det var jo et stort problem, men viste sig at jeg kunne "cleare" det som er DataBind'et.
Ved at sige
repeater = new Repeater()
repeater.Datasource = newList
repeater.DataBind()
så kan man få den nye liste igennem.
For mig er det underligt at den ikke overskriver det som er databinded tidligere, fordi du er jo ikke kommet til render endnu og derfor kan nå at ændre tingene, men åbenbart kun hvis man "clearer" det som er DataBind'et.
Så husk at du kan sætte din repeater til at være en ny, og den vil dermed glemme alt du har binded (VB.NET) på den, og så sætte den til det nye så virker det.
tirsdag den 27. januar 2015
Få alt i dit netværk til at snakke sammen
Jeg må indrømme at jeg er ikke ret stærk i netværk.
I øjeblikket har vi fullrate som leverandør og det kan godt give lidt udfordringer for netværket, fordi de har deres egen router som skal være den første som alt går igennem. Denne router har ikke særligt god dækning, plus har ikke porte nok til alt det jeg har brug for.
Det optimale i dette scenarie er at uanset om du sidder på dit tv, eller din mobil, eller tablet, eller bærbare så kan alle få fat i det du har delt på netværket - såsom filer fra din NAS (netværksharddisk), eller printere fx. Det giver dig nogle helt unikke arbejdsmetoder fordi du kan sidde ved din stationære i kontoret, gemme et dokument på din NAS, og så gå ind på din tablet og arbejde videre i sofaen. Eller du har mulighed for at uanset om det er på din mobil, tablet eller tv eller medie afspiller så vil du kunne få vist jeres feriebilleder nemt og overskueligt.
Din musik kan afspilles af alle enheder på netværket, nemt og effektivt.
Jeg har haft problemer med at få enhederne til at enten kunne snakke sammen og dele data og tilgå hinandens delte data, eller også at få forskellige enheder på nettet. Havde oplevet at der var nogle gange hvor jeg kunne søge efter data på Google og få en liste, men kunne ikke få vist de sider og links jeg valgte. Så søgeresultatet kunne google vise, men siderne jeg ville se og klikkede på fik bare et null response som om der ikke kom noget data igennem.
Nu har jeg endeligt fået det til at virke med min ASUS AC87U router.
Første punkt ind er min Zyxel VMG8928-B10A.
- Port 1 --> NUC (Kablet forbindelse for hastighed og stabilitet) [Hvid]
- Port 2 --> Synology NAS [Blå]
- Port 3 --> Zyxel switch (Metal) [Grå]
- Port 4 (LAN/WAN) --> ASUS AC87U router (Til dens gule port1 som hedder teaming port) [Gul]
I min ASUS AC87U er der ikke forbundet andet, men den sørger så for at give ordentlig trådløs dækning og sørge for at enheder på netværket kan snakke med alle de enheder der er sat i Zyxel routeren. Fx kan jeg via min mobil se det jeg har min NAS via deres apps. Så den kan gå via det fælles netværk til NAS'en.
I min Zyxel switch (Metal) har jeg:
- Port 1 --> Zyxel router (Kablet fra Zyxel routeren) [Grå]
- Port 2 --> Forlænger kabel der ikke længere bruges til noget. [Hvid hvor tappen er knækket af så kan ikke sidde fast ved at klikke sig fast]
Dette gør at NUC'en kan gå på nettet og kan snakke sammen med NAS'en om delte filer, min bærbare kan gå på det trådløse og lave forbindelse til et netværksdrev til at vise fotos fra NAS'en. Mobilerne kan få adgang til NAS'en via de apps Synology giver, fordi de kan få adgang igennem netværket. Jeg kan endda via min mobil få adgang til Kodi (XBMC) via Yatse (En app til at vise medier fra Kodi (XBMC)), og Kodi (XBMC) er placeret på NUC'en. Så mobilen kan gå til ASUS-routeren via det trådløse, som går til Zyxel routeren, som går via kablet forbindelse til NUC'en, som kan fortælle hvilke medier vi har på der.
fredag den 23. januar 2015
Langsom router kan give langsomt internet
Her fik jeg fortalt det var den bedste router de havde, og det endte med jeg gik ud selv og købte en bedre for at forbinde den til den eksisterende, som nu giver god dækning overalt.
Desværre for mig kan jeg ikke bruge denne som den første router ind i huset, fordi så kræver det en fast ip ifølge Fullrate som koster noget ekstra hver måned - det er jeg ikke interesseret i.
Så i forrige weekend gik nettet, selvfølgelig en søndag hvor man ikke kan ringe til dem.
De kunne ikke se der var noget problem, og de ville sende en tekniker og en ny router i tilfælde af der var problemer med den gamle.
Jeg påpeger at hvis han kommer om to dage og han sender det med pestDK, så kommer den jo nok ikke inden han kommer.
Jo jo for han skal komme imellem 8 og 17, og give lyd 45 minutter inden han kommer så jeg kan nå hjem til ham fra arbejde. Det fine er jo så at han mener også jeg kan nå at tage på posthuset og hente den - hvor man ikke kan afhente den samme dag som den er forsøgt leveret.
Så den kommer til mit arbejde hvor jeg har mulighed for at få den og tage med hjem.
Dagen oprinder og manden kommer.. FRA MORGENSTUNDEN! Vi var faktisk på vej ud af døren, så var lidt af en overraskelse og faktisk ret fint og flot.
Desværre kunne han jo så konstatere min router var død fordi han kunne få forbindelse, men han kunne ikke sætte den op og teste den fordi den var ikke engang forsøgt leveret endnu.
Samme dag på mit arbejde kan jeg så hente den router han skulle ha brugt, og hjem kommer jeg med stor skuffelse. Det er en router fra Fullrate de påstår er deres bedste router - nemlig en Zyxel P-2601HN-F1, til min store skuffelse. Jeg har haft routeren i noget der ligner 2 år.
Nu brænder den af, alt for hurtigt - en router skal kunne holde mere end 2 år.
Snakker så med en kollega som siger dem har han haft 2-3 af, og han har fået en bedre med ac-dækning og det hele. DET ER MEGET BEDRE og den havde han ikke haft problemer med, plus han faktisk kunne mærke og se en forskel i båndbredden den fik igennem.
Den sidste del var jeg lidt skeptisk med fordi jeg tænkte enhver router kan klare de 10-13 mbit jeg kører med for det er så lavt.
Nu har jeg fået den bedste de har som er en Zyxel VMG8924-B10A.
Jeg er SÅ overrasket for det er som om den er 10 gange så god! Kan rent faktisk se en reel forskel i det leverede på trods af det trådløse kører igennem en anden end denne router og hele tiden har gjort det. Så selve routeren får bare mere igennem hurtigere.
Kan se hvis jeg skal se ting på netværket såsom musik, film, billeder, backups etc så går der ikke 5-6 sekunder med at finde ud af hvad der er på netværket - nej det kommer efter 1 sekundt ca.
Det samme med websider - de kommer pling med det samme som de bør med den hastighed hvor de før var lidt halvsløve.
Så hvis du kører med en hurtigere router FÅR du faktisk i nogle tilfælde mere ud af dit internet.
torsdag den 22. januar 2015
Fejlhåndtering i C#.NET (ASP.NET)
Der er rigtigt mange måder at lave fejlhåndtering på, og skrevet tons af bøger og teorier om hvornår det er godt at bruge try-catch, null-returnering som identifier, eller state koder og meget meget mere.
Nogle mener at try-catch er effektivt fordi du kan pakke exceptions ind i hinanden, og andre mener det er skidt fordi det er "dyrt" at lave det.
Jeg personligt har fundet et system jeg synes fungerer rigtigt godt, som involverer man altid har et ResponseObject til ALLE metoder. Det vil sige du har et base object med response kodes, succes-property, eller hvad du nu ønsker at have til at identificere dine kald.
Personligt bruger jeg en Succes-property, og en ErrorCode-property som kan sættes til en enumerator. Hvis man så sender denne enumerator til et fejlmodul finder den teksten for den så du kan returnere den.
Så skal man selvfølgelig lave forskellige objekter alt efter hvad man ønsker at returnere, så du får et object af den type med tilbage du ønsker. Skal det være et array, en boolean, en liste, et objekt eller hvad du nu har behov for.
Fordelen for mig er helt klart at du kan ændre dit base-response object som du ønsker - så du kan have fx i dit fejl modul have en GetSystemErrorMessage (fx en MSSQL fejl), og en GetUserErrorMessage (fx "Der skete en fejl da regninger skulle hentes. Kontakt venligst West Inc. på 87 56 43 21").
Således kan du skrive en sigende besked i din log når der sker en fejl, hvor du kan se der ikke er forbindelse til databasen, og til brugeren kan du give en passende fejlbesked de forstår som ikke er så teknisk.
Der kan jo være mange forskellige typer fejl med filen er låst, du har ikke adgang til netværksdrevet, og meget meget mere - og dermed nemmere at skelne imellem hvad skal du gøre nu - skal du forsøge igen, eller ved du at der ikke er mere at gøre? Det er også nemmere at fortælle brugeren noget mere sigende.
tirsdag den 6. januar 2015
Visual studio kan ikke finde ny property eller metode
Dette er et meget velkendt problem, at du i en klasse laver en ny property eller metode, og går over hvor den skal bruges men din intellisense i Visual Studio vil ikke lade dig bruge den, for den mener ikke objektet har denne property eller metode.
Nogle gange hjælper en byg, men ikke altid - hvilket kan være frustrerende fordi man kan se den virkeligt er der.
Der er to ting der kan afhjælpe:
- Lukke begge filer, åbne den med property/metode i, bygge hele projektet, åbne filen hvor du skal bruge det objekt med den nye property/metode, og bygger igen. Dette kan være fordi at intellisense til tider ikke opdateres før du lukker en fil.
- Gå ind under "Temporary ASP.NET Files", og slette de midlertidige byg filer. Dette er fordi at der kan ligge en tidligere udgave af den fil du har lavet en ny property/metode i, som Visual Studio mener den skal bruge i stedet for. Stien dertil er ofte: C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files
Det har hjulpet mig, og kan være nogle underlige scenarier man kommer ud i at en clean og byg ikke er nok, men ovenstående to har hjulpet mig med problematikken før.
torsdag den 27. november 2014
Porada - Giolo : Lækkert spejl til væggen (Vægspejl)
Fandt dette lækre spejl til væggen (vægspejl) som jeg virkeligt godt kunne tænke mig.
Det var et man godt kunne bruge ude i gangen, som et fedt anderledes spejl som ikke så mange lige har. De fleste har et kedeligt almindeligt et som ligner en billedramme med et spejl, eller noget ikea eller et som er meget ordinært. Dette er specielt og fedt så overvejer jeg kraftigt om det ikke skal op i gangen.
tirsdag den 25. november 2014
ASYNC med store filer - fil kopiering
Når man skal kopiere store filer (fx 1-2-3 gb data), så kan du ikke bruge File.Copy, men skal ud i at flytte dem selv. Her benyttes original filestream og den nye filestream.
Ulempen ved denne er at der skal læses lidt fra orignal filestream, put det i en buffer, kopier ind i den nye filestream. Det er der en kerne der gør, hvilket gør at sådan en kopiering kan tage op imod en time for 1,5 gb data.
Fordi den ikke kan udnytte at læse og skrive samtidigt, gør det processen langsom.
Hvis man derimod benytter ASYNC, så sker det asynkront, og vil sige den kan fortsætte med næste stykke arbejde når den har kopieret data imens den skriver.
Ved at det er asynkront kan der kopieres imens der skrives, så den hele tiden har en buffer klar.
Det gjorde at den kom fra en time ned til et par minutter.
INDSÆT KODE
tirsdag den 11. november 2014
F9 til opdatering af referencer i Word
Når man laver referencer i word er det utroligt lækkert at lave referencer (krydshenvisning) til andre afsnit med nummer og tekst og eventuelt sidenummer.
Problemet er så bare at når du kommer videre så ændrer tekster sig, numre ændrer sig, sidetal opdateres, MEN word opdaterer dem ikke automatisk for dig.
Derfor skal du selv opdatere dem for ellers står der de forkerte afsnitsnumre, tekster og sidetal i dine henvisninger, hvilket altid kan blive et problem.
Det man gør er:
at markere alt tekst med Ctrl + A.
at opdatere referencer med F9
at vælge "opdater alt" og trykke OK.
Nu er dit dokument opdateret til den virkelighed som du har i hele dokumentet.
Kabelrod er no-go! Cordlets hjælper
Cordlets er et dejligt produkt!
Synes altid mine kabler ligger og flyder og nu kan man få dejligt styr på dem.
Om du så har til dine høretelefoner, til dine ladere eller andet så er der plads til at kunne fastgøre dem, og hvis nødvendigt er der plads til oprulning på enhederne også.
søndag den 9. november 2014
CSS3 Animations - Gør simple ting mere spændende
Med introduktionen af HTML5, fulgte CSS3 heldigvis med som en stor del af pakken for en webudvikler til at gøre hverdagen med at gøre web og webudvikling for webudviklere mere spændende, uanset platform. Du er helt uafhængig af at have plugins, eller javascript biblioteker såsom jquery lagt ind på din side.
To af de spændende ting som CSS3 bragte med sig var; CSS3 animations, og CSS3 transitions.
CSS3 Transitions er overgange fra en state til den næste.
Det vil sige at hvis fx at du på en hover effekt flytter et element 50px til højre, så vil din transition bestemme overgangen fra state A (startposition) til state B (50px til højre for start position).
CSS3 Animations er at du har mulighed for at lave en animation der afspilles.
Du kan opbygge en animation i punkter og så automatisk laves der "ruter" imellem dem.
Så fx hvis du har en animation med 6 punkter (0%, 20%, 40%, 60%, 80%, 100%), så vil den automatisk finde ud af hvordan den laver transitions fra state A til state B til state C osv.
Så hvis fx du i 0% har sagt at et element har opacity: 0 og i 20% har opacity: 1 så på den tid dette tager så laves en overgang fra 0 til 1.0. Hvis du så bagefter ændrer farven fra sort til rød, laves igen en automatisk overgang fra sort til rød.
Så du kan få et element til at flytte sig lidt til højre (20%), så flytte sig lidt op imens teksten ændrer sig til rød (40%), så flytte sig til venstre imens tekststørrelsen vokser (60%), og til sidst få baggrundsfarven til at skifte til en grøn baggrundsfarve (80%), for at afslutte ved at gå tilbage til sin første state (100%).
Her kan man bestemme hvor lang tid denne overgang (0-100%) skal tage, og hvordan den skal afvikles (start langsomt og afslut hurtigt, eller modsat, og mange andre muligheder.
Så kan man også sætte forskellige animationer på forskellige states - så du kunne sætte ovenstående animation på når der gås fra normal til :hover-state, og når man så går tilbage til normal så afspilles det hele igen baglæns fra en anden animation. Det giver en så ufatteligt mange muligheder.
Det er noget der gør at du nemt med lidt fodarbejde kan lave simple ting meget mere interessante ved at der er aktivitet på dine sider.
Billeder kan fade frem, elementer kan vokse når du peger på dem, tekster kan forstørres når du peger på dem, ikoner kan bevæge sig når du ser dem, menu'er kan danse når du åbner dem.
Alt sammen ting der gør en side lidt mere sjov og spændende (hvis man beherske sig), men nu heldigvis er relativt nemt fordi du har så mange muligheder og variationer der kan gøre dine sider mere spændende.
Fordi du kan bestemme flere punkter der udføres så gør det at dine muligheder er ret mange, fordi du kan få lavet så mange forskellige fede overgange så du vil tro det er løgn.
Da jeg er en meget passioneret og nysgerrig systemudvikler, så har jeg igennem noget tid rodet med både CSS3 transitions, men også med CSS3 animations, og begge er gode til hver sine ting.
Men efter jeg nu er blevet relativt god til dem, så er jeg helt vild med at gøre små bitte ting mere interessante med de muligheder CSS3 har givet mig.
Det skal ikke ligne min side er opbygget i Flash med et hav af effekter, men vil gerne have at der er lidt spil og ting der sker når man ser på min side for gør den interaktiv og dermed spændende.
fredag den 24. oktober 2014
ConnectionString "SqlConnection" - Brug et sigende navn! Udvikleren kan se fordelen
Vi har et projekt som viser en masse takst data og efter en rettelse sidste år er der opbygget ufatteligt meget forretningslogik. Derfor er dette projekt ret essentielt og logikken begynder nu at smitte af på andre projekter.
Det i sig selv er godt, MEN i et andet projekt skal vi så præsentere noget af de samme data som er i det første. For ikke at skulle opbygge samme struktur som der er lavet ovre i det andet projekt, så nu vil vi bruge dll'erne fra det første projekt så vi kan genbruge strukturen og objekterne.
DESVÆRRE for os er det så at disse dll'er pudsigt nok bruger "SqlConnection" som default, som også er den som vores nye projekt bruger. Derfor skal du vi nu lave vores eksisterende løsning om til at bruge noget andet end sqlconnection, så vi kan bruge sqlconnection til vores andre dll'er.
Jeg har altid været stor fortaler for at dine connection strings altid hedder noget unikt og noget sigende, for så støder du aldrig (eller meget sjældnere) på sådanne fejl ved at du giver dine connections strings unikke navne.
fredag den 17. oktober 2014
CSS Selectors forskellige til Chrome og IE (Avancerede jQuery)
Man skal være opmærksom på at når man laver CSS selectors der er lidt avancerede så er der forskellig syntaks der virker til Chrome og Internet Explorer (IE).
Vi havde et problem med at en selector ikke blev udført i Chrome, og det viste sig at være noget så simpelt som et MELLEMRUM!
Oprindeligt så vores script ud som følger:
$('td[style*="top: 200px"]').css({ 'top': '0px', 'left': '410px' });
Det virkede bare ikke i Chrome, og da vi så tilføjede følgende linie virkede det som det skulle:
$('td[style*="top:200px"]').css({ 'top': '0px', 'left': '410px' });
Så koden endte med at være:
$('td[style*="top: 200px"]').css({ 'top': '0px', 'left': '410px' }); //Works for IE
$('td[style*="top:200px"]').css({ 'top': '0px', 'left': '410px' }); //Works for Chrome
Så i DOM'en i Chrome der er ikke mellemrum, men i IE er der. Hvis du laver den uden mellemrum så virker den ikke i IE, og med mellemrum virker den ikke i Chrome. Så derfor bliver man nødt til at have forskellig kode til Chrome og til IE, som er STORT set identisk!
Som udvikler, så løber det en koldt ned af ryggen at det er lavet sådan, og man behøver at lave noget så ÅNDSVAGT! Problemet er ikke JQuery som vi har brugt, for det mellemrum KUNNE jo være noget der faktisk skulle søges på, hvor den i dette tilfælde er lige meget. Derfor kan man ikke bare sige til jQuery at den skal ignorere det mellemrum i midten, fordi den ved ikke at det er nødvendigt.
Derimod er det åndsvagt at de to implementeringer af udviklere fra team Chrome, og udvikler fra team Internet Explorer (IE) ikke er blevet enige om samme udførsel. Det i sig selv kan man til dels også forstå, men at det ER NØDVENDIGT med sådan en gang lortekode med dublet i en sådan skala får det til at krible over hele kroppen på mig fordi jeg er udvikler, og derfor synes det er ineffektivt kode der er grim og forfærdelig.
onsdag den 15. oktober 2014
Fejl i dansk sortering (Danish Dropdown globalization culture)
Hvis man har listen:
Så vil en almindelig sortering gøre at listen kommer med 12 måneder, så År, og så almindelig sortering for resten. Det er fordi at oftest vil den ikke vide at "Å" skal til sidst, og derfor kommer det før de almindelige bogstaver fordi den tager det som specieltegn på samme måde som fx tal.
Så nu kan din dropdown håndtere ÆØÅ og stadig sortere korrekt. Det er altid et problem med sortering i dansk i ASP.NET eller dropdowns, eller i lister. Dette hjælper.
Det kan løses ved at fortælle hvilken culture din comparer skal sammenligne i:
- 12 måneder
- År
- Støvle
- Stativ
- Tå
- Tiger
Så vil en almindelig sortering gøre at listen kommer med 12 måneder, så År, og så almindelig sortering for resten. Det er fordi at oftest vil den ikke vide at "Å" skal til sidst, og derfor kommer det før de almindelige bogstaver fordi den tager det som specieltegn på samme måde som fx tal.
Så nu kan din dropdown håndtere ÆØÅ og stadig sortere korrekt. Det er altid et problem med sortering i dansk i ASP.NET eller dropdowns, eller i lister. Dette hjælper.
Det kan løses ved at fortælle hvilken culture din comparer skal sammenligne i:
Public Function Compare(ByVal o1 As Object, ByVal o2 As Object) As Integer Implements
System.Collections.IComparer.Compare
Dim cb1 As ListItem = CType(o1, ListItem)
Dim cb2 As ListItem = CType(o2, ListItem)
Dim sp As StringComparer = StringComparer.Create(New
Globalization.CultureInfo("da-DK"), True)
Return sp.Compare(cb1.Text,
cb2.Text) * _modifier
'Return
cb1.Text.CompareTo(cb2.Text) * _modifier
End Function
torsdag den 2. oktober 2014
Design til grundejer foreningen
Hvis man som udvikler vil lave en seriøs side kommer man ikke udenom at det gerne må se lidt godt ud, og desværre er der bare ret mange grundejer foreningers hjemmesider der ikke ser helt så godt ud.
Denne statistik vil vores grundejerforening ikke være med på, og vil levere en gennemarbejdet pæn grundejer forenings side. Dette skyldes nok mest at jeg som bestyrelsesmedlem er ASP.NET Webudvikler (C#), og derfor kan levere noget lidt større resultat fra en udvikler.
Da vi nuværende ikke har nogen hjemmeside, skal den starte webside (ASP.NET) vi får, have grundlæggende funktioner, såsom referater og andet information som kan være nyttigt for interesserede. Det kan være nye beboere eller ejendomsmæglere der har behov for informationen, som de derefter selv kan hente derinde.
Den skal opbygges pæn med rene linier så den fremstår tiltalende og ikke så "trist" som ret mange af de eksisterende eksempler der allerede er derude.
Første udkast er afgivet til bestyrelsen og var meget imponeret over mine udvikler kompetencer.
Abonner på:
Opslag (Atom)


