SlideShare a Scribd company logo
Advanced Silverlight Jeff Blankenburg Developer Evangelist [email_address] http://www.jeffblankenburg.com
Who's Even Using Silverlight 1.0?
What are we going to see today?
Why HTML elements? Silverlight user controls are coming with the 2.0 release. 3 rd  party vendors are creating control suites as we speak. No effective way to generate a Silverlight 1.0 user control currently We are actually laying HTML <div> tags over the Silverlight content, and communicating via Javascript.
Overlaying HTML Elements <div style=“position:awesome;”></div>
What about using actual data? It’s as easy as using AJAX was, because that’s exactly what you’re doing. Silverlight is not meant to replace AJAX, it’s a presentation layer.  They’re meant to be complimentary. We’re actually using AJAX to call our web service, and then rewriting the XAML on the server.  This updates our Silverlight presentation.
Using Web Services getMeSomeData();
Where's the cool user interactions? Have you ever tried to do Drag & Drop using <div> elements and Javascript? Let’s compare straight Javascript to Silverlight.
// iMouseDown represents the current mouse button state: up or down /* lMouseState represents the previous mouse button state so that we can check for button clicks and button releases: if(iMouseDown && !lMouseState) // button just clicked! if(!iMouseDown && lMouseState) // button just released! */ var mouseOffset = null; var iMouseDown = false; var lMouseState = false; var dragObject = null; // Demo 0 variables var DragDrops = []; var curTarget = null; var lastTarget = null; var dragHelper = null; var tempDiv = null; var rootParent = null; var rootSibling = null; Number.prototype.NaN0=function(){return isNaN(this)?0:this;} function CreateDragContainer(){ /* Create a new &quot;Container Instance&quot; so that items from one &quot;Set&quot; can not be dragged into items from another &quot;Set&quot; */ var cDrag = DragDrops.length; DragDrops[cDrag] = []; /* Each item passed to this function should be a &quot;container&quot;. Store each of these items in our current container */ for(var i=0; i<arguments.length; i++){ var cObj = arguments[i]; DragDrops[cDrag].push(cObj); cObj.setAttribute('DropObj', cDrag); /* Every top level item in these containers should be draggable. Do this by setting the DragObj attribute on each item and then later checking this attribute in the mouseMove function */ for(var j=0; j<cObj.childNodes.length; j++){ // Firefox puts in lots of #text nodes...skip these if(cObj.childNodes[j].nodeName=='#text') continue; cObj.childNodes[j].setAttribute('DragObj', cDrag); } } } function mouseMove(ev){ ev = ev || window.event; /* We are setting target to whatever item the mouse is currently on Firefox uses event.target here, MSIE uses event.srcElement */ var target = ev.target || ev.srcElement; var mousePos = mouseCoords(ev); // mouseOut event - fires if the item the mouse is on has changed if(lastTarget && (target!==lastTarget)){ // reset the classname for the target element var origClass = lastTarget.getAttribute('origClass'); if(origClass) lastTarget.className = origClass; } /* dragObj is the grouping our item is in (set from the createDragContainer function). if the item is not in a grouping we ignore it since it can't be dragged with this script. */ var dragObj = target.getAttribute('DragObj'); // if the mouse was moved over an element that is draggable if(dragObj!=null){ // mouseOver event - Change the item's class if necessary if(target!=lastTarget){ var oClass = target.getAttribute('overClass'); if(oClass){ target.setAttribute('origClass', target.className); target.className = oClass; } } // if the user is just starting to drag the element if(iMouseDown && !lMouseState){ // mouseDown target curTarget = target; // Record the mouse x and y offset for the element rootParent = curTarget.parentNode; rootSibling = curTarget.nextSibling; mouseOffset = getMouseOffset(target, ev); // We remove anything that is in our dragHelper DIV so we can put a new item in it. for(var i=0; i<dragHelper.childNodes.length; i++) dragHelper.removeChild(dragHelper.childNodes[i]); // Make a copy of the current item and put it in our drag helper. dragHelper.appendChild(curTarget.cloneNode(true)); dragHelper.style.display = 'block'; // set the class on our helper DIV if necessary var dragClass = curTarget.getAttribute('dragClass'); if(dragClass){ dragHelper.firstChild.className = dragClass; } // disable dragging from our helper DIV (it's already being dragged) dragHelper.firstChild.removeAttribute('DragObj'); /* Record the current position of all drag/drop targets related to the element. We do this here so that we do not have to do it on the general mouse move event which fires when the mouse moves even 1 pixel. If we don't do this here the script would run much slower. */ var dragConts = DragDrops[dragObj]; /* first record the width/height of our drag item. Then hide it since it is going to (potentially) be moved out of its parent. */ curTarget.setAttribute('startWidth', parseInt(curTarget.offsetWidth)); curTarget.setAttribute('startHeight', parseInt(curTarget.offsetHeight)); curTarget.style.display = 'none'; // loop through each possible drop container for(var i=0; i<dragConts.length; i++){ with(dragConts[i]){ var pos = getPosition(dragConts[i]); /* save the width, height and position of each container. Even though we are saving the width and height of each container back to the container this is much faster because we are saving the number and do not have to run through any calculations again. Also, offsetHeight and offsetWidth are both fairly slow. You would never normally notice any performance hit from these two functions but our code is going to be running hundreds of times each second so every little bit helps! Note that the biggest performance gain here, by far, comes from not having to run through the getPosition function hundreds of times. */ setAttribute('startWidth', parseInt(offsetWidth)); setAttribute('startHeight', parseInt(offsetHeight)); setAttribute('startLeft', pos.x); setAttribute('startTop', pos.y); } // loop through each child element of each container for(var j=0; j<dragConts[i].childNodes.length; j++){ with(dragConts[i].childNodes[j]){ if((nodeName=='#text') || (dragConts[i].childNodes[j]==curTarget)) continue; var pos = getPosition(dragConts[i].childNodes[j]); // save the width, height and position of each element setAttribute('startWidth', parseInt(offsetWidth)); setAttribute('startHeight', parseInt(offsetHeight)); setAttribute('startLeft', pos.x); setAttribute('startTop', pos.y); } } } } } // If we get in here we are dragging something if(curTarget){ // move our helper div to wherever the mouse is (adjusted by mouseOffset) dragHelper.style.top = mousePos.y - mouseOffset.y; dragHelper.style.left = mousePos.x - mouseOffset.x; var dragConts = DragDrops[curTarget.getAttribute('DragObj')]; var activeCont = null; var xPos = mousePos.x - mouseOffset.x + (parseInt(curTarget.getAttribute('startWidth')) /2); var yPos = mousePos.y - mouseOffset.y + (parseInt(curTarget.getAttribute('startHeight'))/2); // check each drop container to see if our target object is &quot;inside&quot; the container for(var i=0; i<dragConts.length; i++){ with(dragConts[i]){ if(((getAttribute('startLeft')) < xPos) && ((getAttribute('startTop')) < yPos) && ((getAttribute('startLeft') + getAttribute('startWidth')) > xPos) && ((getAttribute('startTop') + getAttribute('startHeight')) > yPos)){ /* our target is inside of our container so save the container into the activeCont variable and then exit the loop since we no longer need to check the rest of the containers */ activeCont = dragConts[i]; // exit the for loop break; } } } // Our target object is in one of our containers. Check to see where our div belongs if(activeCont){ // beforeNode will hold the first node AFTER where our div belongs var beforeNode = null; // loop through each child node (skipping text nodes). for(var i=activeCont.childNodes.length-1; i>=0; i--){ with(activeCont.childNodes[i]){ if(nodeName=='#text') continue; // if the current item is &quot;After&quot; the item being dragged if( curTarget != activeCont.childNodes[i] && ((getAttribute('startLeft') + getAttribute('startWidth')) > xPos) && ((getAttribute('startTop') + getAttribute('startHeight')) > yPos)){ beforeNode = activeCont.childNodes[i]; } } } // the item being dragged belongs before another item if(beforeNode){ if(beforeNode!=curTarget.nextSibling){ activeCont.insertBefore(curTarget, beforeNode); } // the item being dragged belongs at the end of the current container } else { if((curTarget.nextSibling) || (curTarget.parentNode!=activeCont)){ activeCont.appendChild(curTarget); } } // make our drag item visible if(curTarget.style.display!=''){ curTarget.style.display = ''; } } else { // our drag item is not in a container, so hide it. if(curTarget.style.display!='none'){ curTarget.style.display = 'none'; } } } // track the current mouse state so we can compare against it next time lMouseState = iMouseDown; // mouseMove target lastTarget = target; // track the current mouse state so we can compare against it next time lMouseState = iMouseDown; // this helps prevent items on the page from being highlighted while dragging return false; } function mouseUp(ev){ if(curTarget){ // hide our helper object - it is no longer needed dragHelper.style.display = 'none'; // if the drag item is invisible put it back where it was before moving it if(curTarget.style.display == 'none'){ if(rootSibling){ rootParent.insertBefore(curTarget, rootSibling); } else { rootParent.appendChild(curTarget); } } // make sure the drag item is visible curTarget.style.display = ''; } curTarget = null; iMouseDown = false; } function mouseDown(){ iMouseDown = true; if(lastTarget){ return false; } } document.onmousemove = mouseMove; document.onmousedown = mouseDown; document.onmouseup = mouseUp; window.onload = function(){ // Create our helper object that will show the item while dragging dragHelper = document.createElement('DIV'); dragHelper.style.cssText = 'position:absolute;display:none;'; CreateDragContainer( document.getElementById('DragContainer1'), document.getElementById('DragContainer2'), document.getElementById('DragContainer3') ); document.body.appendChild(dragHelper); } <!--the mouse over and dragging class are defined on each item--> <div class=&quot;DragContainer&quot; id=&quot;DragContainer1&quot;> <div class=&quot;DragBox&quot; id=&quot;Item1&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #1</div> <div class=&quot;DragBox&quot; id=&quot;Item2&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #2</div> <div class=&quot;DragBox&quot; id=&quot;Item3&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #3</div> <div class=&quot;DragBox&quot; id=&quot;Item4&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #4</div> </div> <div class=&quot;DragContainer&quot; id=&quot;DragContainer2&quot;> <div class=&quot;DragBox&quot; id=&quot;Item5&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #5</div> <div class=&quot;DragBox&quot; id=&quot;Item6&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #6</div> <div class=&quot;DragBox&quot; id=&quot;Item7&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #7</div> <div class=&quot;DragBox&quot; id=&quot;Item8&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #8</div> </div> <div class=&quot;DragContainer&quot; id=&quot;DragContainer3&quot;> <div class=&quot;DragBox&quot; id=&quot;Item9&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #9</div> <div class=&quot;DragBox&quot; id=&quot;Item10&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #10</div> <div class=&quot;DragBox&quot; id=&quot;Item11&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #11</div> <div class=&quot;DragBox&quot; id=&quot;Item12&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #12</div> </div>  Taken from  http://www.webreference.com/programming/javascript/mk/column2/3.html
Here's the code needed for Silverlight var beginX; var beginY; var trackingMouseMove = false; var zIndex = 0; function onMouseDown(sender, mouseEventArgs) { beginX = mouseEventArgs.getPosition(null).x; beginY = mouseEventArgs.getPosition(null).y; trackingMouseMove = true; sender.captureMouse(); //zIndex += 1; //sender[&quot;Canvas.ZIndex&quot;] = zIndex; } function onMouseUp(sender, mouseEventArgs) { sender.releaseMouseCapture(); trackingMouseMove = false; } function onMouseMove(sender, mouseEventArgs) { if (trackingMouseMove == true) { var currentX = mouseEventArgs.getPosition(null).x; var currentY = mouseEventArgs.getPosition(null).y; sender[&quot;Canvas.Left&quot;] += currentX - beginX; sender[&quot;Canvas.Top&quot;] += currentY - beginY; beginX = currentX; beginY = currentY; } }
Drag and Drop (using Event Handlers) mouseEnter = “EatCheese”
How To Contact Me © 2007 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries. The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation.  Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION. Email:  [email_address] Blog:  http://www.jeffblankenburg.com Twitter:  http://www.twitter.com/jeffblankenburg

More Related Content

PDF
Understanding Asynchronous JavaScript
PDF
Build Widgets
PDF
Advanced javascript
PDF
The evolution of asynchronous javascript
PDF
Callbacks, promises, generators - asynchronous javascript
PDF
Promise pattern
PPT
Advanced JavaScript
PDF
JavaScript Promise
Understanding Asynchronous JavaScript
Build Widgets
Advanced javascript
The evolution of asynchronous javascript
Callbacks, promises, generators - asynchronous javascript
Promise pattern
Advanced JavaScript
JavaScript Promise

What's hot (20)

PPTX
Promises, Promises
PDF
Object Oriented JavaScript
PPTX
JavaScript Promises
PDF
JavaScript Promises
PDF
Integrating React.js with PHP projects
PDF
JavaScript Best Pratices
PDF
Avoiding callback hell with promises
PDF
Advanced Object-Oriented JavaScript
PDF
Java Script Best Practices
PDF
Even more java script best practices
PDF
Maintainable JavaScript 2011
PPTX
Avoiding callback hell in Node js using promises
PDF
Containers & Dependency in Ember.js
PDF
Javascript Promises/Q Library
PDF
Asynchronous programming done right - Node.js
PPTX
The Many Ways to Build Modular JavaScript
PDF
$q and Promises in AngularJS
PPTX
Avoiding Callback Hell with Async.js
PDF
Présentation de HomeKit
PDF
Javascript Module Patterns
Promises, Promises
Object Oriented JavaScript
JavaScript Promises
JavaScript Promises
Integrating React.js with PHP projects
JavaScript Best Pratices
Avoiding callback hell with promises
Advanced Object-Oriented JavaScript
Java Script Best Practices
Even more java script best practices
Maintainable JavaScript 2011
Avoiding callback hell in Node js using promises
Containers & Dependency in Ember.js
Javascript Promises/Q Library
Asynchronous programming done right - Node.js
The Many Ways to Build Modular JavaScript
$q and Promises in AngularJS
Avoiding Callback Hell with Async.js
Présentation de HomeKit
Javascript Module Patterns
Ad

Viewers also liked (7)

PPT
Reach End Users With Next Generation Web Applications
PPT
Introduction To Silverlight
PPTX
Silverlight An Introduction
PPTX
Mix09 Overview
PPT
Cool Microsoft Stuff
PDF
Cdr stats-vo ip-analytics_solution_mongodb_meetup
PDF
Twitter
Reach End Users With Next Generation Web Applications
Introduction To Silverlight
Silverlight An Introduction
Mix09 Overview
Cool Microsoft Stuff
Cdr stats-vo ip-analytics_solution_mongodb_meetup
Twitter
Ad

Similar to Advanced Silverlight (20)

KEY
An in-depth look at jQuery UI
PDF
YUI Evolved
PDF
Famo.us: From Zero to UI
PPTX
Java
PDF
Ajax-Tutorial
PDF
Taming the browser with the YUI Dom Component
PPTX
CSS3 2D/3D transform
PPTX
CSS3 TTA (Transform Transition Animation)
PDF
Mastering CSS Animations
DOCX
Replicating the Swipe Gesture iPhone Gallery for mobile web– HTML5 – Part 2
PPTX
Email template editor
PPTX
jQuery for Sharepoint Dev
PDF
Intro To Jquery
PDF
PPTX
HTML5 Introduction
PPT
JQuery Basics
PPT
Rotoscope inthebrowserppt billy
PDF
HTML5 APIs - Where no man has gone before! - Altran
PDF
Ruby-ying Javascript: Avoiding jQuery Spaghetti
PPT
Raphael JavaScript Library
An in-depth look at jQuery UI
YUI Evolved
Famo.us: From Zero to UI
Java
Ajax-Tutorial
Taming the browser with the YUI Dom Component
CSS3 2D/3D transform
CSS3 TTA (Transform Transition Animation)
Mastering CSS Animations
Replicating the Swipe Gesture iPhone Gallery for mobile web– HTML5 – Part 2
Email template editor
jQuery for Sharepoint Dev
Intro To Jquery
HTML5 Introduction
JQuery Basics
Rotoscope inthebrowserppt billy
HTML5 APIs - Where no man has gone before! - Altran
Ruby-ying Javascript: Avoiding jQuery Spaghetti
Raphael JavaScript Library

Recently uploaded (20)

PDF
KodekX | Application Modernization Development
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Approach and Philosophy of On baking technology
PDF
Machine learning based COVID-19 study performance prediction
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
Spectroscopy.pptx food analysis technology
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPTX
sap open course for s4hana steps from ECC to s4
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
Cloud computing and distributed systems.
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
cuic standard and advanced reporting.pdf
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
KodekX | Application Modernization Development
20250228 LYD VKU AI Blended-Learning.pptx
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
“AI and Expert System Decision Support & Business Intelligence Systems”
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Approach and Philosophy of On baking technology
Machine learning based COVID-19 study performance prediction
Network Security Unit 5.pdf for BCA BBA.
Spectroscopy.pptx food analysis technology
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Building Integrated photovoltaic BIPV_UPV.pdf
sap open course for s4hana steps from ECC to s4
Reach Out and Touch Someone: Haptics and Empathic Computing
Cloud computing and distributed systems.
Understanding_Digital_Forensics_Presentation.pptx
Diabetes mellitus diagnosis method based random forest with bat algorithm
Digital-Transformation-Roadmap-for-Companies.pptx
cuic standard and advanced reporting.pdf
Chapter 3 Spatial Domain Image Processing.pdf
Per capita expenditure prediction using model stacking based on satellite ima...

Advanced Silverlight

  • 1. Advanced Silverlight Jeff Blankenburg Developer Evangelist [email_address] http://www.jeffblankenburg.com
  • 2. Who's Even Using Silverlight 1.0?
  • 3. What are we going to see today?
  • 4. Why HTML elements? Silverlight user controls are coming with the 2.0 release. 3 rd party vendors are creating control suites as we speak. No effective way to generate a Silverlight 1.0 user control currently We are actually laying HTML <div> tags over the Silverlight content, and communicating via Javascript.
  • 5. Overlaying HTML Elements <div style=“position:awesome;”></div>
  • 6. What about using actual data? It’s as easy as using AJAX was, because that’s exactly what you’re doing. Silverlight is not meant to replace AJAX, it’s a presentation layer. They’re meant to be complimentary. We’re actually using AJAX to call our web service, and then rewriting the XAML on the server. This updates our Silverlight presentation.
  • 7. Using Web Services getMeSomeData();
  • 8. Where's the cool user interactions? Have you ever tried to do Drag & Drop using <div> elements and Javascript? Let’s compare straight Javascript to Silverlight.
  • 9. // iMouseDown represents the current mouse button state: up or down /* lMouseState represents the previous mouse button state so that we can check for button clicks and button releases: if(iMouseDown && !lMouseState) // button just clicked! if(!iMouseDown && lMouseState) // button just released! */ var mouseOffset = null; var iMouseDown = false; var lMouseState = false; var dragObject = null; // Demo 0 variables var DragDrops = []; var curTarget = null; var lastTarget = null; var dragHelper = null; var tempDiv = null; var rootParent = null; var rootSibling = null; Number.prototype.NaN0=function(){return isNaN(this)?0:this;} function CreateDragContainer(){ /* Create a new &quot;Container Instance&quot; so that items from one &quot;Set&quot; can not be dragged into items from another &quot;Set&quot; */ var cDrag = DragDrops.length; DragDrops[cDrag] = []; /* Each item passed to this function should be a &quot;container&quot;. Store each of these items in our current container */ for(var i=0; i<arguments.length; i++){ var cObj = arguments[i]; DragDrops[cDrag].push(cObj); cObj.setAttribute('DropObj', cDrag); /* Every top level item in these containers should be draggable. Do this by setting the DragObj attribute on each item and then later checking this attribute in the mouseMove function */ for(var j=0; j<cObj.childNodes.length; j++){ // Firefox puts in lots of #text nodes...skip these if(cObj.childNodes[j].nodeName=='#text') continue; cObj.childNodes[j].setAttribute('DragObj', cDrag); } } } function mouseMove(ev){ ev = ev || window.event; /* We are setting target to whatever item the mouse is currently on Firefox uses event.target here, MSIE uses event.srcElement */ var target = ev.target || ev.srcElement; var mousePos = mouseCoords(ev); // mouseOut event - fires if the item the mouse is on has changed if(lastTarget && (target!==lastTarget)){ // reset the classname for the target element var origClass = lastTarget.getAttribute('origClass'); if(origClass) lastTarget.className = origClass; } /* dragObj is the grouping our item is in (set from the createDragContainer function). if the item is not in a grouping we ignore it since it can't be dragged with this script. */ var dragObj = target.getAttribute('DragObj'); // if the mouse was moved over an element that is draggable if(dragObj!=null){ // mouseOver event - Change the item's class if necessary if(target!=lastTarget){ var oClass = target.getAttribute('overClass'); if(oClass){ target.setAttribute('origClass', target.className); target.className = oClass; } } // if the user is just starting to drag the element if(iMouseDown && !lMouseState){ // mouseDown target curTarget = target; // Record the mouse x and y offset for the element rootParent = curTarget.parentNode; rootSibling = curTarget.nextSibling; mouseOffset = getMouseOffset(target, ev); // We remove anything that is in our dragHelper DIV so we can put a new item in it. for(var i=0; i<dragHelper.childNodes.length; i++) dragHelper.removeChild(dragHelper.childNodes[i]); // Make a copy of the current item and put it in our drag helper. dragHelper.appendChild(curTarget.cloneNode(true)); dragHelper.style.display = 'block'; // set the class on our helper DIV if necessary var dragClass = curTarget.getAttribute('dragClass'); if(dragClass){ dragHelper.firstChild.className = dragClass; } // disable dragging from our helper DIV (it's already being dragged) dragHelper.firstChild.removeAttribute('DragObj'); /* Record the current position of all drag/drop targets related to the element. We do this here so that we do not have to do it on the general mouse move event which fires when the mouse moves even 1 pixel. If we don't do this here the script would run much slower. */ var dragConts = DragDrops[dragObj]; /* first record the width/height of our drag item. Then hide it since it is going to (potentially) be moved out of its parent. */ curTarget.setAttribute('startWidth', parseInt(curTarget.offsetWidth)); curTarget.setAttribute('startHeight', parseInt(curTarget.offsetHeight)); curTarget.style.display = 'none'; // loop through each possible drop container for(var i=0; i<dragConts.length; i++){ with(dragConts[i]){ var pos = getPosition(dragConts[i]); /* save the width, height and position of each container. Even though we are saving the width and height of each container back to the container this is much faster because we are saving the number and do not have to run through any calculations again. Also, offsetHeight and offsetWidth are both fairly slow. You would never normally notice any performance hit from these two functions but our code is going to be running hundreds of times each second so every little bit helps! Note that the biggest performance gain here, by far, comes from not having to run through the getPosition function hundreds of times. */ setAttribute('startWidth', parseInt(offsetWidth)); setAttribute('startHeight', parseInt(offsetHeight)); setAttribute('startLeft', pos.x); setAttribute('startTop', pos.y); } // loop through each child element of each container for(var j=0; j<dragConts[i].childNodes.length; j++){ with(dragConts[i].childNodes[j]){ if((nodeName=='#text') || (dragConts[i].childNodes[j]==curTarget)) continue; var pos = getPosition(dragConts[i].childNodes[j]); // save the width, height and position of each element setAttribute('startWidth', parseInt(offsetWidth)); setAttribute('startHeight', parseInt(offsetHeight)); setAttribute('startLeft', pos.x); setAttribute('startTop', pos.y); } } } } } // If we get in here we are dragging something if(curTarget){ // move our helper div to wherever the mouse is (adjusted by mouseOffset) dragHelper.style.top = mousePos.y - mouseOffset.y; dragHelper.style.left = mousePos.x - mouseOffset.x; var dragConts = DragDrops[curTarget.getAttribute('DragObj')]; var activeCont = null; var xPos = mousePos.x - mouseOffset.x + (parseInt(curTarget.getAttribute('startWidth')) /2); var yPos = mousePos.y - mouseOffset.y + (parseInt(curTarget.getAttribute('startHeight'))/2); // check each drop container to see if our target object is &quot;inside&quot; the container for(var i=0; i<dragConts.length; i++){ with(dragConts[i]){ if(((getAttribute('startLeft')) < xPos) && ((getAttribute('startTop')) < yPos) && ((getAttribute('startLeft') + getAttribute('startWidth')) > xPos) && ((getAttribute('startTop') + getAttribute('startHeight')) > yPos)){ /* our target is inside of our container so save the container into the activeCont variable and then exit the loop since we no longer need to check the rest of the containers */ activeCont = dragConts[i]; // exit the for loop break; } } } // Our target object is in one of our containers. Check to see where our div belongs if(activeCont){ // beforeNode will hold the first node AFTER where our div belongs var beforeNode = null; // loop through each child node (skipping text nodes). for(var i=activeCont.childNodes.length-1; i>=0; i--){ with(activeCont.childNodes[i]){ if(nodeName=='#text') continue; // if the current item is &quot;After&quot; the item being dragged if( curTarget != activeCont.childNodes[i] && ((getAttribute('startLeft') + getAttribute('startWidth')) > xPos) && ((getAttribute('startTop') + getAttribute('startHeight')) > yPos)){ beforeNode = activeCont.childNodes[i]; } } } // the item being dragged belongs before another item if(beforeNode){ if(beforeNode!=curTarget.nextSibling){ activeCont.insertBefore(curTarget, beforeNode); } // the item being dragged belongs at the end of the current container } else { if((curTarget.nextSibling) || (curTarget.parentNode!=activeCont)){ activeCont.appendChild(curTarget); } } // make our drag item visible if(curTarget.style.display!=''){ curTarget.style.display = ''; } } else { // our drag item is not in a container, so hide it. if(curTarget.style.display!='none'){ curTarget.style.display = 'none'; } } } // track the current mouse state so we can compare against it next time lMouseState = iMouseDown; // mouseMove target lastTarget = target; // track the current mouse state so we can compare against it next time lMouseState = iMouseDown; // this helps prevent items on the page from being highlighted while dragging return false; } function mouseUp(ev){ if(curTarget){ // hide our helper object - it is no longer needed dragHelper.style.display = 'none'; // if the drag item is invisible put it back where it was before moving it if(curTarget.style.display == 'none'){ if(rootSibling){ rootParent.insertBefore(curTarget, rootSibling); } else { rootParent.appendChild(curTarget); } } // make sure the drag item is visible curTarget.style.display = ''; } curTarget = null; iMouseDown = false; } function mouseDown(){ iMouseDown = true; if(lastTarget){ return false; } } document.onmousemove = mouseMove; document.onmousedown = mouseDown; document.onmouseup = mouseUp; window.onload = function(){ // Create our helper object that will show the item while dragging dragHelper = document.createElement('DIV'); dragHelper.style.cssText = 'position:absolute;display:none;'; CreateDragContainer( document.getElementById('DragContainer1'), document.getElementById('DragContainer2'), document.getElementById('DragContainer3') ); document.body.appendChild(dragHelper); } <!--the mouse over and dragging class are defined on each item--> <div class=&quot;DragContainer&quot; id=&quot;DragContainer1&quot;> <div class=&quot;DragBox&quot; id=&quot;Item1&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #1</div> <div class=&quot;DragBox&quot; id=&quot;Item2&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #2</div> <div class=&quot;DragBox&quot; id=&quot;Item3&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #3</div> <div class=&quot;DragBox&quot; id=&quot;Item4&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #4</div> </div> <div class=&quot;DragContainer&quot; id=&quot;DragContainer2&quot;> <div class=&quot;DragBox&quot; id=&quot;Item5&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #5</div> <div class=&quot;DragBox&quot; id=&quot;Item6&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #6</div> <div class=&quot;DragBox&quot; id=&quot;Item7&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #7</div> <div class=&quot;DragBox&quot; id=&quot;Item8&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #8</div> </div> <div class=&quot;DragContainer&quot; id=&quot;DragContainer3&quot;> <div class=&quot;DragBox&quot; id=&quot;Item9&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #9</div> <div class=&quot;DragBox&quot; id=&quot;Item10&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #10</div> <div class=&quot;DragBox&quot; id=&quot;Item11&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #11</div> <div class=&quot;DragBox&quot; id=&quot;Item12&quot; overClass=&quot;OverDragBox&quot; dragClass=&quot;DragDragBox&quot;>Item #12</div> </div> Taken from http://www.webreference.com/programming/javascript/mk/column2/3.html
  • 10. Here's the code needed for Silverlight var beginX; var beginY; var trackingMouseMove = false; var zIndex = 0; function onMouseDown(sender, mouseEventArgs) { beginX = mouseEventArgs.getPosition(null).x; beginY = mouseEventArgs.getPosition(null).y; trackingMouseMove = true; sender.captureMouse(); //zIndex += 1; //sender[&quot;Canvas.ZIndex&quot;] = zIndex; } function onMouseUp(sender, mouseEventArgs) { sender.releaseMouseCapture(); trackingMouseMove = false; } function onMouseMove(sender, mouseEventArgs) { if (trackingMouseMove == true) { var currentX = mouseEventArgs.getPosition(null).x; var currentY = mouseEventArgs.getPosition(null).y; sender[&quot;Canvas.Left&quot;] += currentX - beginX; sender[&quot;Canvas.Top&quot;] += currentY - beginY; beginX = currentX; beginY = currentY; } }
  • 11. Drag and Drop (using Event Handlers) mouseEnter = “EatCheese”
  • 12. How To Contact Me © 2007 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries. The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION. Email: [email_address] Blog: http://www.jeffblankenburg.com Twitter: http://www.twitter.com/jeffblankenburg