Implementera drag’n drop med en ASP.NET kontroll, del 1
Förord
Jag brukar svepa igenom forumen här på Pellesoft för att få inspiration till nya programmeringsutmaningar. För några dagar sedan dök det upp en fråga om hur man skulle kunna komma åt drag’n drop händelser i ASP.NET. Till min förvåning blev de flesta svaren lika korta som koncisa; ASP.NET är en serverteknologi och du bör använda JavaScript, Flash eller annan klientteknologi. En liten känsla jag fick var att vår frågeställare var mer skolad än så och var väl medveten om att ASP.NET är en serverteknologi. Jag tror att han undrade om man inte kunde använda ASP.NET som bas för att leverera en komplett komponentbaserad drag’n drop lösning. Klart att man kan...
Inledning
Hursomhelst, jag tyckte detta lät hur kul som helst och lösningen blev att skriva en generell ASP.NET kontroll som automatiskt kapslar HTML element inom kontrollen och gör att denna kan draggas och droppas och generera events på serversidan till de som är intresserade. Det enda som skall behöva göras av utvecklaren är att han/hon drar in en drag’n drop kontroll på en ASP.NET sida och lägger in HTML element som underelement i denna. Sedan skall allt skötas automatiskt. Hur svårt kan det vara?Exempel:
En massa HTML
Med bakgrund av de smällar jag åkt på tidigare i projekt där man använt en större mängd JavaScript på klienten, och med min (trots .net) oförändrat stora kärlek till COM, bestämde jag mig för att kapsla in drag’n drop logiken på klienten i en generell DHTML behavior komponent som jag kan koppla till de aktuella HTML elementen.
Detta medför båda för- och nackdelar, fördelarna är att vi får en ren design med en COM baserad DHTML behavior komponent (förpackad i en .htc fil) och vi slipper skräpa ner HTML koden med en massa JavaScript. Nackdelen är att behaviors bara fungerar i Internet Explorer, detta kan jag personligen leva med då jag tänker använda denna kontroll i mitt CMS system där administrationsgränssnittet ändå måste köras i Internet Explorer.
Jag har delat upp denna artikel i två delartiklar där den första behandlar klientdelen. Fokus i denna del läggs på design och programmering av den DHTML behavior komponent som kommer att bidra med generell drag’n drop funktionalitet till HTML element . Serverdelen består av skapandet av den av System.Web.UI.WebControls.WebControl ärvda komponent som kommer att använda klientlogiken från HTC komponenten och snappar upp de events som denna genererar.
Målet med allt detta är enkelt, efter den andra artikeln så ska vi ha en fungerande generell drag’n drop komponent som kan infogas i Visual Studio.NETs toolbox och användas som vilken annan kontroll som helst!
Let the fun begin, enter behaviors
För er som inte tidigare bekantat er med MSIE behaviors kommer här en liten introduktion. Min erfarenhet av klientprogrammering i browsermiljö är klart färgad. Över hälften av de applikationer som jag varit i kontakt med som innehåller större mängder JavaScript har en design som kan skrämma den mest härdade av utvecklare. Microsoft måste ha haft ungefär samma erfarenheter när de för några år sedan tog fram behaviors till Internet Explorer, en teknologi färgad av COM då detta var innan .NET eran. DHTML Behaviors implementeras i grunden som COM komponenter (våra gamla kära IUnknown implementatörer) som kan kopplas till HTML element via dess style attribut. Detta gör att webbläsare som inte stödjer behaviors (läs alla utom MSIE) helt enkelt bara ignorerar detta attribut. Det går att skriva behaviors i C++, VB Script eller JavaScript. För enkelhetens skull kommer jag att skriva logiken i JavaScript.
Hello World
Vad vore en introduktion utan ett ”hello world” exempel? Grunden till alla HTC komponenter består av följande struktur;
Koden ovan skapar en enkel HTC (HTML Control). Den är tämligen ointressant som den ser ut nu så vi kompletterar denna med lite logik. Det givna HelloWorld exemplet för behaviors är givetvis implementation av rollover (när man drar musen över ett element så byter det färg). Här kommer en sådan komponent;
rollover.htc
Detta är den kompletta rollover komponenten. Vi kopplar komponentens Init() metod till window.onload så att vi initierar komponenten med rätt rollover färg (plockas från HTML elementets rollOverColor attribut om det finns, annars röd). Vi har deklarerat en PUBLIC:PROPERTY rollOverColor vilket binds till detta attribut på det aktuella HTML elementet. På detta sätt kan vi läsa egna attribut från HTML elementet och använda dessa i vår komponent, i detta fall som en slags constructorparameter. Vidare har vi kopplat elementets onmouseover och onmouseout händelser till aktuella eventhandlers i komponenten (RollOver() och Restore()).
Hur kopplar vi då detta behavior till HTML elementet? En kakbit!
Hello World!
Nu ser vi tydligt mappningen av rollOverColor attributet som vi läser från komponenten och även hur vi pekar ut rollover.htc filen. Det är viktigt att förstå att det kommer att skapas en ny instans av HTC komponenten för varje HTML element som implementerar detta behavior. Detta gör att vi kan hålla instansdata (state) i komponenten som vi gör med originalColor och originalCursor i exemplet. Från komponenten kan vi alltid nå HTML elementet genom element objektet, element.RuntimeStyle ger oss tillgång till dess style och via denna kan vi enkelt sätta aktuell färg och cursor. Innan jag glömmer det skall jag säga att det givetvis går att koppla fler behaviors till samma element. Detta resulterar ju bara i att ett antal COM objekt (Behavior komponenter) mappas mot samma element. (COM är kärlek, eller hur var det Don Box sa en gång i tiden...)
Det finns även möjlighet till att deklarera events från HTC komponenten som mappas mot events i HTML elementet (som t.ex. onmouseover). Detta kommer vi att använda i drag’n drop komponenten för att aktivera JavaScript som genererar en postback till servern innehållande information om vad som droppades på vad. En demo på detta finns här
0 Kommentarer