<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>EZTIER LLC</title>
	<atom:link href="http://eztier.com/dba2day/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://eztier.com/dba2day</link>
	<description></description>
	<pubDate>Tue, 10 Jan 2012 22:40:47 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>jBASE ETL - T24 Accounting Tables</title>
		<link>http://eztier.com/dba2day/?p=387</link>
		<comments>http://eztier.com/dba2day/?p=387#comments</comments>
		<pubDate>Tue, 10 Jan 2012 22:39:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[T24]]></category>

		<category><![CDATA[jBASE]]></category>

		<category><![CDATA[Add new tag]]></category>

		<guid isPermaLink="false">http://eztier.com/dba2day/?p=387</guid>
		<description><![CDATA[A practical scenario in using the jBASE ETL is feeding your bank&#8217;s accounting/ALM system with data from the T24 accounting tables on a daily basis.
Typically, you will want to extract the data from distribution (archived) files rather than the actual accounting tables.  For example, instead of running the following:
td24 -server 10.10.59.42 -user INPUTT -pass [...]]]></description>
			<content:encoded><![CDATA[<p>A practical scenario in using the <a href="http://eztier.com/web/?p=118" target="_blank">jBASE ETL</a> is feeding your bank&#8217;s accounting/ALM system with data from the T24 accounting tables on a daily basis.</p>
<p>Typically, you will want to extract the data from distribution (archived) files rather than the actual accounting tables.  For example, instead of running the following:</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">td24 -server 10.10.59.42 -user INPUTT -pass 123456 -file FBNK.STMT.ENTRY -with "BOOKING.DATE EQ '20120109'"</pre>
<p>You would use the distribution file instead:</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">td24 -server 10.10.59.42 -user INPUTT -pass 123456 -file FBNK.STMT.ENTRY.DIST01 -with "BOOKING.DATE EQ '20120109'"</pre>
<p>Here is an <a href="http://eztier.com/samples/t24/grid/examples/fbnkcategentry.html">ONLINE example</a> of extracted data for the FBNK.CATEG.ENTRY table.</p>
<p>Other notable distribution files are the other 2 accounting tables as well as FBNK.FUNDS.TRANSFER$HIS.  You would extract from their distribution files in a similar way:</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">td24 -server 10.10.59.42 -user INPUTT -pass 123456 -file FBNK.CATEG.ENT.DIST01 -with "BOOKING.DATE EQ '20120109'"
td24 -server 10.10.59.42 -user INPUTT -pass 123456 -file FBNK.RE.CON.DIST01 -with "BOOKING.DATE EQ '20120109'"
td24 -server 10.10.59.42 -user INPUTT -pass 123456 -file FBNK.FUNDS.TRANSFER$HIS.PART1 -with "PROCESSING.DATE EQ '20120109'"
</pre>
<p>To automate the extraction processing, simply create a script and have it run daily after the COB.  Here&#8217;s an example in Wndows jscript:</p>
<pre style="background-color:#000;color:#fff;padding: 10px;height:225px;">var today = new Date();
var y= today.getFullYear();
var m = today.getMonth()+1;
var m1 = (m < 10 ? "0" : "") + m;
var d = today.getDate();
var d1 = (d < 10 ? "0" : "") + d;
var iso_date = (y + m1 + d1);
WScript.Echo("td24 -server 10.10.59.42 -user INPUTT -pass 123456 -file FBNK.STMT.ENTRY.DIST" + m1 + " -with \"BOOKING.DATE EQ '" + iso_date + "'\"");
WScript.Echo("td24 -server 10.10.59.42 -user INPUTT -pass 123456 -file FBNK.CATEG.ENT.DIST" + m1 + " -with \"BOOKING.DATE EQ '" + iso_date + "'\"");
WScript.Echo("td24 -server 10.10.59.42 -user INPUTT -pass 123456 -file FBNK.RE.CON.DIST" + m1 + " -with \"BOOKING.DATE EQ '" + iso_date + "'\"");
WScript.Echo("td24 -server 10.10.59.42 -user INPUTT -pass 123456 -file FBNK.FUNDS.TRANSFER$HIS.PART" + m + " -with \"PROCESSING.DATE EQ '" + iso_date + "'\"");</pre>
<p>Simple, not a lot of hassle, and plain productive.</p>
]]></content:encoded>
			<wfw:commentRss>http://eztier.com/dba2day/?feed=rss2&amp;p=387</wfw:commentRss>
		</item>
		<item>
		<title>jBASE ETL - Simple, Secure, Blazing Fast</title>
		<link>http://eztier.com/dba2day/?p=287</link>
		<comments>http://eztier.com/dba2day/?p=287#comments</comments>
		<pubDate>Sat, 17 Dec 2011 21:27:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[T24]]></category>

		<category><![CDATA[jBASE]]></category>

		<category><![CDATA[Add new tag]]></category>

		<category><![CDATA[C# (2)]]></category>

		<category><![CDATA[SSH2]]></category>

		<guid isPermaLink="false">http://eztier.com/dba2day/?p=287</guid>
		<description><![CDATA[If your company&#8217;s data resides inside jBASE, chances are you&#8217;ve wrestled with extracting that data out and inserting it into a table.  There are various commercial solutions that can accomplish this such as Vultar ODBC, mv.NET, and jBLoader.
These implementations typically require custom jBC code installed on the jBASE server as well as setting up [...]]]></description>
			<content:encoded><![CDATA[<p>If your company&#8217;s data resides inside <a href="http://en.wikipedia.org/wiki/JBASE" target="_blank">jBASE</a>, chances are you&#8217;ve wrestled with extracting that data out and inserting it into a table.  There are various commercial solutions that can accomplish this such as <a href="http://www.vultar.md/products/odbc-driver-for-jbase" target="_blank">Vultar ODBC</a>, <a href="http://www.bluefinity.com/v4/Products/mvnet/index.html" target="_blank">mv.NET</a>, and <a href="http://jbloader.com/t24-data-warehouse.html" target="_blank">jBLoader</a>.</p>
<p>These implementations typically require custom jBC code installed on the jBASE server as well as setting up an application server responsible for connection pooling.  There may also be run-time (distribution) fees and onsite consultancy requirements to consider.  Costs add up quickly.</p>
<p>If your primary goal is to deliver usable grid data from jBASE to the users, then we have a simple tool that does just that.  Here&#8217;s an <a href="http://eztier.com//Samples/t24/grid/examples/fbnkaccount.html">ONLINE EXAMPLE</a> of the data that this tool produces.  And unlike the above solutions, we do not have developer licenses and absolutely no distribution fees  You only pay for the product one time.</p>
<p>See this tool in action by downloading the <a href="http://eztier.com/products/downloads/trial/jBASE-ETL-v1.0-installer-x64-TRIAL.exe" target="_blank">TRIAL</a> edition.  The trial edition has all the features described in this post, but it can ONLY extract one table, FBNK.CUSTOMER.</p>
<p>You can <a href="http://sites.fastspring.com/eztier/product/jbaseetltoolversion10" target="_top">PURCHASE</a> the retail edition, which has no such limitations.<br />
<span id="more-287"></span></p>
<p><span style="font-weight:bolder;">td24 Version 1.0</span></p>
<p>Our solution, &#8220;td24&#8243;, is a command line tool on the client machine.  There is no application server setup and nothing to install on the jBASE server.  Connections to the jBASE server are done securely via SSH2.  After an installation that takes a few seconds, you&#8217;re ready to download data.  Nothing to configure.</p>
<p>Pass it a &#8220;-help&#8221; argument and you&#8217;ll see all the available options (that&#8217;s right, there&#8217;s only 4 required arguments!):</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">td24 [-server] [-port] [-user] [-pass] [-file] [-with]
     [-explode] [-dest] [maxrow] [-xfile]

Required:

        server  IP address of the server where jBASE is installed.
                example: -server 192.168.1.22
        user    A valid user account that has access to jBASE.
                example: -user jschmoe
        pass    A valid password for the above user account.
                example: -pass abc123
        file    The jBASE filename to be extracted.
                example: -file FBNK.ACCOUNT

Optional:

        port    The SSH port number.
                If this argument is not included, the default value is 22.
                example: -port 2222
        with    A valid jQL selection clause.
                If this argument is not included, all fields
                will be extracted
                example: -with "CATEGORY='1234' AND ALL.IN.ONE.PRODUCT NE ''"
        explode Pipe delimited list of field names to explode.
                If this argument is not included, all fields with
                multi and sub values will be exploded.
                example: -explode "CAP.DATE.CR.INT|ACCT.CREDIT.INT"
        dest    The absolute path to the directory where the extracted
                files will be exported.  Do not include a "\" at the end.
                If this argument is not included, a subfolder "done" will
                be created in the application working directory.
                example: -dest "c:\users\jschmoe\my downloaded files"
        maxrow  The maximum number of rows to write to a file.
                After this numbe is reached, a new file will be created.
                If this argument is not included, the default value is 999.
                The maximum value is 999.
                example: -maxrow 300
        xfile   The absolute path to the text file that contains a list of
                multi value fields to be exploded.  This argument and the
                "-explode" argument are mutually exclusive.  This argument
                will be ignored if the "-explode" argument is included
                Each field name should be followed a newline or CRLF.
                example: -xfile "c:\users\jschmoe\my_mv_list.txt"</pre>
<p><span style="font-weight:bolder;">EXAMPLES</span></p>
<p><span style="font-weight:bolder;">Sampling</span></p>
<p>To get an idea of table structure and which fields are MultiValue.  We can simply pass &#8220;SAMPLE 1&#8243; to the &#8220;-with&#8221; argument.</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">td24 -server 192.168.1.22 -user INPUTT -pass 123456 -file FBNK.ACCOUNT -with "SAMPLE 1"</pre>
<p>This is exported file:</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">11398^100401^1001^Queen Elizabeth Ii^^Queen Elizabeth Ii^QEIIUSD^TR^USD^1^^1^^^^^^^^^^1^^^^^^^^^^^^^^^^^^^^^^^^^20081231^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^NO^^20081201^^^^^^^1001^^^^^^^^USD^1^USD^1^^^LEGACY^^^^^^^^^NO^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Y^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2^28_INPUTTER^0903241641^SY_CUSTOMER^GB0010001^1^</pre>
<p>Upon executing the command, td24 will also write 2 files:</p>
<p>FBNK.ACCOUNT.DICT.txt<br />
FBNK.ACCOUNT.DICT.MV.txt</p>
<p>The first file will list all the fields in ordinal position:</p>
<pre style="padding: 10px; height: 100px; color: #ffffff; background-color: #000000;">0^ACCOUNT.NUMBER
1^CUSTOMER
2^CATEGORY
3^ACCOUNT.TITLE.1
4^ACCOUNT.TITLE.2
5^SHORT.TITLE
6^MNEMONIC
7^POSITION.TYPE
8^CURRENCY
9^CURRENCY.MARKET
10^LIMIT.REF
11^ACCOUNT.OFFICER
12^OTHER.OFFICER
13^POSTING.RESTRICT
14^RECONCILE.ACCT
15^INTEREST.LIQU.ACCT
16^INTEREST.COMP.ACCT
17^INT.NO.BOOKING
18^REFERAL.CODE
19^WAIVE.LEDGER.FEE
20^LOCAL.REF
21^CONDITION.GROUP
22^INACTIV.MARKER
23^OPEN.ACTUAL.BAL
24^OPEN.CLEARED.BAL
25^ONLINE.ACTUAL.BAL
26^ONLINE.CLEARED.BAL
27^WORKING.BALANCE
28^DATE.LAST.CR.CUST
29^AMNT.LAST.CR.CUST
30^TRAN.LAST.CR.CUST
31^DATE.LAST.CR.AUTO
32^AMNT.LAST.CR.AUTO
33^TRAN.LAST.CR.AUTO
34^DATE.LAST.CR.BANK
35^AMNT.LAST.CR.BANK
36^TRAN.LAST.CR.BANK
37^DATE.LAST.DR.CUST
38^AMNT.LAST.DR.CUST
39^TRAN.LAST.DR.CUST
40^DATE.LAST.DR.AUTO
41^AMNT.LAST.DR.AUTO
42^TRAN.LAST.DR.AUTO
43^DATE.LAST.DR.BANK
44^AMNT.LAST.DR.BANK
45^TRAN.LAST.DR.BANK
46^CAP.DATE.CHARGE
47^CAP.DATE.CR.INT
48^CAP.DATE.C2.INT
49^CAP.DATE.DR.INT
50^CAP.DATE.D2.INT
51^CAP.BACK.VALUE
52^ACCR.CHG.CATEG
53^ACCR.CHG.TRANS
54^ACCR.CHG.AMOUNT
55^ACCR.CHG.SUSP
56^ACCR.CR.CATEG
57^ACCR.CR.TRANS
58^ACCR.CR.AMOUNT
59^ACCR.CR.SUSP
60^ACCR.CR2.CATEG
61^ACCR.CR2.TRANS
62^ACCR.CR2.AMOUNT
63^ACCR.CR2.SUSP
64^ACCR.DR.CATEG
65^ACCR.DR.TRANS
66^ACCR.DR.AMOUNT
67^ACCR.DR.SUSP
68^ACCR.DR2.CATEG
69^ACCR.DR2.TRANS
70^ACCR.DR2.AMOUNT
71^ACCR.DR2.SUSP
72^CONSOL.KEY
73^INT.LIQU.TYPE
74^INT.LIQU.ACCT
75^INT.LIQ.CCY
76^PASSBOOK
77^START.YEAR.BAL
78^OPENING.DATE
79^VALUE.DATE
80^CREDIT.MOVEMENT
81^DEBIT.MOVEMENT
82^VALUE.DATED.BAL
83^CONTINGENT.BAL.CR
84^CONTINGENT.BAL.DR
85^OPEN.CATEGORY
86^OPEN.VAL.DATED.BAL
87^ACCT.CREDIT.INT
88^ACCT.DEBIT.INT
89^LINK.TO.LIMIT
90^CLOSURE.DATE
91^RESERVED01
92^CHARGE.ACCOUNT
93^CHARGE.CCY
94^CHARGE.MKT
95^INTEREST.CCY
96^INTEREST.MKT
97^CON.CHARGE.ACCR
98^CON.INTEREST.ACCR
99^ALT.ACCT.TYPE
100^ALT.ACCT.ID
101^PREMIUM.TYPE
102^CAP.DATE.PRM
103^PREMIUM.FREQ
104^APR
105^JOINT.HOLDER
106^RELATION.CODE
107^JOINT.NOTES
108^ALLOW.NETTING
109^LEDG.RECO.WITH
110^STMT.RECO.WITH
111^OUR.EXT.ACCT.NO
112^RECO.TOLERANCE
113^PENDING.ID
114^TOTAL.PENDING
115^STOCK.CONTROL.TYPE
116^SERIAL.NO.FORMAT
117^AUTO.PAY.ACCT
118^ORIG.CCY.PAYMENT
119^AUTO.REC.CCY
120^ORIGINAL.ACCT
121^FROM.DATE
122^LOCKED.AMOUNT
123^DISPO.OFFICER
124^DISPO.EXEMPT
125^TAX.SUSPEND
126^TAX.AT.SETTLE
127^ICA.MAIN.ACCOUNT
128^ICA.DISTRIB.RATIO
129^ICA.MAIN.ACCT.IND
130^ICA.DISTRIB.TYPE
131^ICA.POST.INTEREST
132^ICA.MAIN.RATIO
133^ICA.NEW.MAIN.ACC
134^ICA.START.DATE
135^ICA.ADD.REMOVE
136^ICA.BACK.VALUE
137^ICA.MAIN.ACCT
138^ICA.MAIN.DATE
139^LIQUIDATION.MODE
140^OVERDUE.STATUS
141^RESERVED11
142^SINGLE.LIMIT
143^CONTINGENT.INT
144^ALL.IN.ONE.PRODUCT
145^ER.VALUE.DATE
146^ER.BALANCE
147^EP.BALANCE
148^SB.GROUP.ID
149^OPEN.AVAILABLE.BAL
150^AVAILABLE.DATE
151^AV.AUTH.DB.MVMT
152^AV.NAU.DB.MVMT
153^AV.AUTH.CR.MVMT
154^AV.NAU.CR.MVMT
155^AVAILABLE.BAL
156^FORWARD.MVMTS
157^CREDIT.CHECK
158^AVAILABLE.BAL.UPD
159^CONSOLIDATE.ENT
160^MAX.SUB.ACCOUNT
161^MASTER.ACCOUNT
162^RESERVED2
163^CLOSED.ONLINE
164^NEXT.AF.DATE
165^NEXT.ACCT.CAP
166^NEXT.EXP.DATE
167^DATE.LAST.UPDATE
168^NEXT.STMT.DATE
169^EXPOSURE.DATES
170^PORTFOLIO.NO
171^ENTRY.HOLD
172^FWD.ENTRY.HOLD
173^FIRST.AF.DATE
174^CASH.POOL.GROUP
175^OPEN.ASSET.TYPE
176^LAST.COM.CHG.DATE
177^IC.CHARGE.ID
178^IC.NEXT.CAP.DATE
179^IC.PRODUCT
180^IC.LST.PROD.CAP
181^ARRANGEMENT.ID
182^ACC.DEB.LIMIT
183^MANDATE.APPL
184^MANDATE.REG
185^MANDATE.RECORD
186^DR.ADJ.AMOUNT
187^DR2.ADJ.AMOUNT
188^CR.ADJ.AMOUNT
189^CR2.ADJ.AMOUNT
190^OVERRIDE
191^RECORD.STATUS
192^CURR.NO
193^INPUTTER
194^DATE.TIME
195^AUTHORISER
196^CO.CODE
197^DEPT.CODE</pre>
<p>The second file will list only fields that are MultiValue in ordinal position:</p>
<pre style="padding: 10px; height: 100px; color: #ffffff; background-color: #000000;">12^OTHER.OFFICER
18^REFERAL.CODE
20^LOCAL.REF
46^CAP.DATE.CHARGE
47^CAP.DATE.CR.INT
48^CAP.DATE.C2.INT
49^CAP.DATE.DR.INT
50^CAP.DATE.D2.INT
52^ACCR.CHG.CATEG
53^ACCR.CHG.TRANS
54^ACCR.CHG.AMOUNT
55^ACCR.CHG.SUSP
56^ACCR.CR.CATEG
57^ACCR.CR.TRANS
58^ACCR.CR.AMOUNT
59^ACCR.CR.SUSP
60^ACCR.CR2.CATEG
61^ACCR.CR2.TRANS
62^ACCR.CR2.AMOUNT
63^ACCR.CR2.SUSP
64^ACCR.DR.CATEG
65^ACCR.DR.TRANS
66^ACCR.DR.AMOUNT
67^ACCR.DR.SUSP
68^ACCR.DR2.CATEG
69^ACCR.DR2.TRANS
70^ACCR.DR2.AMOUNT
71^ACCR.DR2.SUSP
73^INT.LIQU.TYPE
74^INT.LIQU.ACCT
75^INT.LIQ.CCY
79^VALUE.DATE
80^CREDIT.MOVEMENT
81^DEBIT.MOVEMENT
82^VALUE.DATED.BAL
87^ACCT.CREDIT.INT
88^ACCT.DEBIT.INT
99^ALT.ACCT.TYPE
100^ALT.ACCT.ID
101^PREMIUM.TYPE
102^CAP.DATE.PRM
103^PREMIUM.FREQ
105^JOINT.HOLDER
106^RELATION.CODE
107^JOINT.NOTES
109^LEDG.RECO.WITH
110^STMT.RECO.WITH
113^PENDING.ID
114^TOTAL.PENDING
119^AUTO.REC.CCY
120^ORIGINAL.ACCT
121^FROM.DATE
122^LOCKED.AMOUNT
137^ICA.MAIN.ACCT
138^ICA.MAIN.DATE
145^ER.VALUE.DATE
146^ER.BALANCE
147^EP.BALANCE
150^AVAILABLE.DATE
151^AV.AUTH.DB.MVMT
152^AV.NAU.DB.MVMT
153^AV.AUTH.CR.MVMT
154^AV.NAU.CR.MVMT
155^AVAILABLE.BAL
156^FORWARD.MVMTS
168^NEXT.STMT.DATE
169^EXPOSURE.DATES
170^PORTFOLIO.NO
171^ENTRY.HOLD
172^FWD.ENTRY.HOLD
179^IC.PRODUCT
180^IC.LST.PROD.CAP
182^ACC.DEB.LIMIT
183^MANDATE.APPL
184^MANDATE.REG
185^MANDATE.RECORD
190^OVERRIDE
193^INPUTTER
194^DATE.TIME</pre>
<p><span style="font-weight:bolder;">Getting Everything Without Exploding</span></p>
<p>Suppose we don&#8217;t want know what MultiValue fields to explode and just want to see everything.  Simple enough:</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">td24 -server 192.168.1.22 -user INPUTT -pass 123456 -file FBNK.ACCOUNT</pre>
<p>Immediately after executing the command, you&#8217;re see files raining down.  All files are in caret &#8220;^&#8221; delimited format.  A portion of a file is shown below:</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">28282^111111^4001^Ukwarb Stock Borrow Margin Acct^^Ukwarb Stock Borrow Margin Acct^UKWARBSB^TR^USD^1^^1^^^^^^^^^^99^^^^^^^^^^^^^^^^^^^^^^^^^20081231^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^NO^^20081201^^^^^^^4001^^^^^^^^USD^1^USD^1^^^LEGACY^^^^^^^^^NO^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^111111-955^^^^^^^^^^^^^^^^^^^^^^2^12_INPUTTER^0903211145^SY_UPDATE.INACTIVE.MARKER^GB0010001^1^
GBP149550001^^14955^Suspense Account^^Suspense Account^SUSP^TR^GBP^1^^5^^^^^^^^^^^^947368.42^947368.42^947368.42^947368.42^947368.42^20090107^947368.42^306^^^^20090107^1000000^219^20090102^-1000000.00^307^^^^^^^20081231^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^NO^^20081205^^^^^^^14955^^^^^^^^GBP^1^GBP^1^^^LEGACY^^^^^^^^^NO^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^20090107^^^^^^^^^^^^^^^^^^^^^^^^^1^40_INPUTTER___OFS_OFS.LOAD^0903181430^40_INPUTTER_OFS_OFS.LOAD^GB0010001^1^
10782^100224^6603^Dbl Az Multi Dep1^^Dbl Az Multi Dep1^^TR^USD^1^^5^^^^37044^^^^^^99^^^^^^^^^^^^^^^^^^^^^^^^^20090131^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^NO^^20090107^^^^^^^6603^^^^^^^^USD^^USD^^^^^^^^^^^^^NO^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^37761^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1^4_BUILDUSER87^0904041853^SY_37761^GB0010001^1^
15393^100592^5001^Hsbc Bank^^Hsbc Bank^HSBCGBP^TR^GBP^1^NOSTRO^27^^^Y^^^^^^^5^^-21231545.25^-21231545.25^-19897484.98^-19897484.98^-19897484.98^20090122^1335000.00^306^^^^20090120^3192.00^674^20090121^-958.90^437^20090121^-64.73^281^20090122^-939.73^701^20081231^20081231^20081231^20081231^20081231^^^^^^^^^^^^^^^^^^^^^^^^^^NO^^20081201^^^^^^^5001^^^^^^^^GBP^1^GBP^1^^^LEGACY^^^^^^^^^NO^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-10395326.71^20090122]20090123]20090124]20090126]20090128]20090129]20090131^-939.73]]-1438.35]]-1004688.764109589041]-939.73]-1438.35^^1335230.14]1342.4657534246574]939.73]4002972.5986301369862]959.86]]2585936.99^^-9061036.3]-9059693.8342465753426]-9060192.4542465753426]-5057219.8556164383564]-6060948.7597260273974]-6061888.4897260273974]-3477389.8497260273974^230.14]1342.4657534246574]-498.62]4002972.5986301369862]-1003728.904109589041]-939.73]2584498.64^^^^^^^^20090204^^^20090122^^^^^^20090122^^^^^^^^^^^^^^^^^^^1^40_BUILDUSER1___OFS_MB.OFS.AUTH^0903181432^40_BUILDUSER1_OFS_MB.OFS.AUTH^GB0010001^1^
USD111050001^^11105^Building - Own Usage^^Building - Own^BUILD11105^TR^USD^1^^1^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^20081231^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^NO^^20081202^^^^^^^11105^^^^^^^^USD^1^USD^1^^^^^^^^^^^^NO^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1^63_INPUTTER___OFS_MB.OFS.AUTH^0903171747^63_INPUTTER_OFS_MB.OFS.AUTH^GB0010001^1^</pre>
<p>It&#8217;s probably not a good idea to download everything in sight, but you&#8217;ll be surprised that for about 0.5 GB of data for FBNK.ACCOUNT, the extraction only takes 5 minutes.</p>
<p>Generally, it&#8217;s best to break up the download with selection clauses (which we&#8217;ll see shortly).</p>
<p>Since the MultiValue fields were not exploded, each item has exactly one row.  In the example above, record &#8220;15393&#8243; has a few MultiValue fields that require exploding.</p>
<p><span style="font-weight:bolder;">Selectively Exploding Fields</span></p>
<p>For the next example, we&#8217;re going to explode the fields &#8220;AVAILABLE.DATE&#8221; and &#8220;AVAILABLE.BAL&#8221;:</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">td24 -server 192.168.1.22 -file FBNK.ACCOUNT -explode "AVAILABLE.DATE|AVAILABLE.BAL" -user INPUTT -pass 123456</pre>
<p>The result would now look like this:</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">GBP149550001^^
10782^^
15393^20090122^-9061036.3
15393^20090123^-9059693.8342465753426
15393^20090124^-9060192.4542465753426
15393^20090126^-5057219.8556164383564
15393^20090128^-6060948.7597260273974
15393^20090129^-6061888.4897260273974
15393^20090131^-3477389.8497260273974
USD111050001^^
13838^^</pre>
<p><span style="font-weight:bolder;">Using a File to List Fields to Explode.</span></p>
<p>In the above example, we only exploded 2 fields.  If we wanted to explode many fields, it may be easier to use the &#8220;-xfile&#8221; argument to specify a user-defined text file that lists those fields.</p>
<p>Let&#8217;s create a file called &#8220;my-mv-list.txt&#8221; with a list of fields:</p>
<pre style="padding: 10px; height: 100px; color: #ffffff; background-color: #000000;">CAP.DATE.CHARGE
CAP.DATE.CR.INT
CAP.DATE.C2.INT
CAP.DATE.DR.INT
CAP.DATE.D2.INT
ACCR.CHG.CATEG
ACCR.CHG.TRANS
ACCR.CHG.AMOUNT
ACCR.CHG.SUSP
ACCR.CR.CATEG
ACCR.CR.TRANS
ACCR.CR.AMOUNT
ACCR.CR.SUSP
ACCR.CR2.CATEG
ACCR.CR2.TRANS
ACCR.CR2.AMOUNT
ACCR.CR2.SUSP
ACCR.DR.CATEG
ACCR.DR.TRANS
ACCR.DR.AMOUNT
ACCR.DR.SUSP
ACCR.DR2.CATEG
ACCR.DR2.TRANS
ACCR.DR2.AMOUNT
ACCR.DR2.SUSP</pre>
<p>Then execute the following command:</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">td24 -server 192.168.1.22 -file FBNK.ACCOUNT -xfile "my-mv-list.txt" -user INPUTT -pass 123456</pre>
<p>A portion of the results look like this:</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">35254^20081231^20081231^20081231^20081231^20081231^^^^^^^^^^^^^^^^^^^^
37718^20081231^20090114^^^^^^^^50000^380^1704.24^^^^^^^^^^^^^
37718^20081231^20090107^^^^^^^^50000^380^1704.24^^^^^^^^^^^^^
37718^20081231^20081231^^^^^^^^50000^380^1704.24^^^^^^^^^^^^^
37718^20081231^20081224^^^^^^^^50000^380^1704.24^^^^^^^^^^^^^
37718^20081231^20081217^^^^^^^^50000^380^1704.24^^^^^^^^^^^^^
37718^20081231^20081210^^^^^^^^50000^380^1704.24^^^^^^^^^^^^^
19167^20081231^^^^^^^^^^^^^^^^^^^^^^^^</pre>
<p><span style="font-weight:bolder;">Selection Clause</span></p>
<p>We&#8217;ve already used a form of a selection clause before with the &#8220;SAMPLE&#8221; keyword.  In the above example, there are many records without a &#8220;ACCR.CR.CATEG&#8221; value.  We can simply filter those records out:</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">td24 -server 192.168.1.22 -file FBNK.ACCOUNT -xfile "my-mv-list.txt" -with "ACCR.CR.CATEG NE '' OR ACCR.DR.CATEG NE ''" -user INPUTT -pass 123456</pre>
<p>A portion of the results now look like this:</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">10731^20081231^20081231^20081231^20081231^20081231^^^^^^^^^^^^^51000^390^-21595^^^^^
23876^20081231^20081231^20081231^20081231^20081231^^^^^^^^^^^^^51000^390^-278.87^^^^^
37718^20081231^20090114^^^^^^^^50000^380^1704.24^^^^^^^^^^^^^
37718^20081231^20090107^^^^^^^^50000^380^1704.24^^^^^^^^^^^^^
37718^20081231^20081231^^^^^^^^50000^380^1704.24^^^^^^^^^^^^^
37718^20081231^20081224^^^^^^^^50000^380^1704.24^^^^^^^^^^^^^
37718^20081231^20081217^^^^^^^^50000^380^1704.24^^^^^^^^^^^^^
37718^20081231^20081210^^^^^^^^50000^380^1704.24^^^^^^^^^^^^^
36706^20081231^20081231^20081231^20081231^20081231^^^^^^^^^^^^^51000^390^-0.41^^^^^</pre>
<p><span style="font-weight:bolder;">Concurrency</span></p>
<p>Where td24 really shines is the ability to download multiple tables concurrently.  There is no real limitation on how many connections you can make when using td24.  This ultimately depends on how powerful the jBASE server is.  On a beefy Solaris box, 40 or more concurrent connections is possible.</p>
<p>The following is a sample script to download 10 tables concurrently:</p>
<pre style="background-color:#000;color:#fff;padding: 10px;">start "0" /B td24.exe -file FBNK.ACCOUNT -server 192.168.1.22 -port 22 -user INPUTT -pass 123456
start "1" /B td24.exe -file FBNK.LIMIT -server 192.168.1.22 -port 22 -user INPUTT -pass 123456
start "2" /B td24.exe -file FBNK.ACCOUNT.STATEMENT -server 192.168.1.22 -port 22 -user INPUTT -pass 123456
start "3" /B td24.exe -file FBNK.GROUP.ACCOUNT -server 192.168.1.22 -port 22 -user INPUTT -pass 123456
start "4" /B td24.exe -file FBNK.CUSTOMER -server 192.168.1.22 -port 22 -user INPUTT -pass 123456
start "5" /B td24.exe -file FBNK.ACCOUNT.CREDIT.INT -server 192.168.1.22 -port 22 -user INPUTT -pass 123456
start "6" /B td24.exe -file FBNK.ACCOUNT.DEBIT.INT -server 192.168.1.22 -port 22 -user INPUTT -pass 123456
start "7" /B td24.exe -file F.DE.ADDRESS -server 192.168.1.22 -port 22 -user INPUTT -pass 123456
start "8" /B td24.exe -file FBNK.PD.BALANCES.HIST -server 192.168.1.22 -port 22 -user INPUTT -pass 123456
start "9" /B td24.exe -file FBNK.AC.LOCKED.EVENTS -server 192.168.1.22 -port 22 -user INPUTT -pass 123456</pre>
<p><span style="font-weight:bolder;">Usability</span></p>
<p>The files are readily usable in Excel.  But of course, you can bulk load them to a relational database easily.</p>
]]></content:encoded>
			<wfw:commentRss>http://eztier.com/dba2day/?feed=rss2&amp;p=287</wfw:commentRss>
		</item>
		<item>
		<title>jQuery Grid Plugin with WCF</title>
		<link>http://eztier.com/dba2day/?p=264</link>
		<comments>http://eztier.com/dba2day/?p=264#comments</comments>
		<pubDate>Sun, 26 Jul 2009 22:30:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[AJAX (2)]]></category>

		<category><![CDATA[WCF (2)]]></category>

		<category><![CDATA[Add new tag]]></category>

		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://eztier.com/dba2day/?p=264</guid>
		<description><![CDATA[One of best grid plugins out there for jQuery is jqGrid because of its good documentation and online samples.
There&#8217;s plenty of code examples with php/mySql as the backend but I wished they had one with WCF as the application tier.  With a little plumbing in WCF and some trial and error testing, I was [...]]]></description>
			<content:encoded><![CDATA[<p>One of best grid plugins out there for jQuery is <a href="http://www.trirand.com/blog/">jqGrid</a> because of its good documentation and online samples.</p>
<p>There&#8217;s plenty of code examples with php/mySql as the backend but I wished they had one with WCF as the application tier.  With a little plumbing in WCF and some trial and error testing, I was able to get a small jqGrid application up and running.</p>
<p>If you are thinking about implementing jqGrid in your application with WCF, this post will include some code samples and hopefully help you speed your development process.</p>
<p><a href="http://eztier.com/dba2day/wp-content/uploads/2009/07/jgridwithwcf.jpg"><img class="size-medium wp-image-265" title="jqGridWithWCF" src="http://eztier.com/dba2day/wp-content/uploads/2009/07/jgridwithwcf-300x167.jpg" alt="jqGrid With WCF" width="300" height="167" /></a><br />
Online sample below. . .<br />
<span id="more-264"></span><br />
You can see the <a href="http://eztier.com/samples/ajax/jqgridwithwcf/default.aspx">ONLINE sample here</a>.</p>
<p>The version of jqGrid I used was 3.4.4 and you can download it <a>here</a>.  The jQuery library (v1.3.1) came with the download.</p>
<p><span style="font-weight:bolder;">Setting Up WCF</span></p>
<p>jqGrid invokes REST-ful style services.  In WCF (.NET Framework 3.5), we simply decorate the operation contract with the WebGet() attribute:</p>
<pre style="300px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="br0">&#91;</span>OperationContract<span class="br0">&#93;</span>
&nbsp; &nbsp; <span class="br0">&#91;</span>WebGet<span class="br0">&#40;</span>
&nbsp; &nbsp; &nbsp; &nbsp; UriTemplate = <span class="st0">&quot;OperationContract?param1={param1}&amp;amp;param2={param2}&amp;amp;param3={param3}&quot;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; ResponseFormat = WebMessageFormat.<span class="me1">Json</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="br0">&#93;</span>
&nbsp; &nbsp; jGridPagedResult GetHeader<span class="br0">&#40;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> param1,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> param2,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> param3
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</div>
</div>
</pre>
<p>But jqGrid is very particular about the Uri parameters you&#8217;ll be invoking from javascript.  Along with your own parameters to a opearation contract, you&#8217;ll have to make room for 6 additional parameters in your Uri string.</p>
<p>Your Uri string will look like this if your operation method requires one parameter (&#8221;Param1&#8243;):</p>
<p>http://localhost/ServiceName/OperationName?<span style="color:DarkGreen;">Param1=abc&amp;nd=1246883438361&amp;_search=false&amp;rows=10&amp;page=1&amp;sidx=Uid&amp;sord=asc</span></p>
<p>Or with no parameters:</p>
<p>http://localhost/ServiceName/OperationName?<span style="color:DarkGreen;">nd=1246883438361&amp;_search=false&amp;rows=10&amp;page=1&amp;sidx=Uid&amp;sord=asc</span></p>
<p>The 6 parameters that jqGrid will attach to the Uri are:<br />
<span style="color:DarkBlue;"><br />
nd (a timestamp value to force no caching on the server)<br />
_search<br />
rows<br />
page<br />
sidx (index to sort on)<br />
sord</span></p>
<p>They are included to aid the development of a &#8220;Paging&#8221; mechanism in server-side code.  To make jqGrid functional, we have to at least pay attention to &#8220;rows&#8221; and &#8220;page&#8221;.  You may want to implement the other 4 parameters if your application requires sorting and search capabilities.</p>
<p>Although this post will only focus on the minimum, that is, the &#8220;rows&#8221; and &#8220;page&#8221; parameters, we still have to include them in the UriTemplate:</p>
<pre style="height: 300px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="br0">&#91;</span>OperationContract<span class="br0">&#93;</span>
&nbsp; &nbsp; <span class="br0">&#91;</span>WebGet<span class="br0">&#40;</span>
&nbsp; &nbsp; &nbsp; &nbsp; UriTemplate = <span class="st0">&quot;OperationName?Param1={Param1}&amp;amp;Param2={Param2}&amp;amp;nd={nd}&amp;amp;_search={search}&amp;amp;rows={rows}&amp;amp;page={page}&amp;amp;sidx={sidx}&amp;amp;sord={sord}&quot;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; ResponseFormat = WebMessageFormat.<span class="me1">Json</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="br0">&#93;</span>
&nbsp; &nbsp; jGridPagedResult OperationName<span class="br0">&#40;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> Param1,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> Param2,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> nd,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> search,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> rows,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> page,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> sidx,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> sord
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</div>
</div>
</pre>
<p>The return type &#8220;jGridPagedResult&#8221; can be any DataContract that MUST include 4 DataMember&#8217;s and MUST have the names of &#8220;rows&#8221;,&#8221;records&#8221;,&#8221;total&#8221;,&#8221;page&#8221;.  (You can actually convert the DataMember&#8217;s names to the expected names in javascript (ie. &#8220;MyRows&#8221; -&gt; &#8220;rows&#8221;), but we&#8217;re going to keep it very straight forward here.)</p>
<pre style="height: 470px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="br0">&#91;</span>DataContract<span class="br0">&#93;</span>
&nbsp; &nbsp; <span class="kw1">public</span> abstract <span class="kw4">class</span> BindableObjects
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// dummy abstract class</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="br0">&#91;</span>DataContract<span class="br0">&#93;</span>
&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">class</span> jGridPagedResult where T : BindableObjects
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>DataMember<span class="br0">&#93;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> List rows
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>get; set;<span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>DataMember<span class="br0">&#93;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">int</span> records
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>DataMember<span class="br0">&#93;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">int</span> total
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>DataMember<span class="br0">&#93;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">int</span> page
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="br0">&#91;</span>DataContract<span class="br0">&#93;</span>
&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">class</span> SomeType : BindableObjects
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>DataMember<span class="br0">&#93;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">string</span> Column1<span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="br0">&#91;</span>DataContract<span class="br0">&#93;</span>
&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">class</span> AnotherType : BindableObjects
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>DataMember<span class="br0">&#93;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">int</span> Column1 <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>DataMember<span class="br0">&#93;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">string</span> Column2 <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="font-weight:bolder;">Paging using Linq</span></p>
<p>The remaining task for the WCF implementation is to populate the response object with an array of data.  Typically, we&#8217;ll be tapping into some backend database.  For this example, I&#8217;m just going to use LinqToSql to fetch some data in Sql Server 2005/2008.</p>
<p>Paging is done simply with a combination of Skip() and Take() extension methods.  Prior to Linq, we would have to implement some dynamic sql using the &#8220;row_number() over (order by&#8230;&#8221; window function.  The response basically returns an array of data, total number of records, total number of pages, and the page number (which is actually the page that was passed in thru the Uri).</p>
<pre style="height: 700px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">jGridPagedResult GetCustomers<span class="br0">&#40;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> nd,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> search,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> rows,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> page,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> sidx,
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> sord<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//We're only interested in the &quot;rows&quot; and &quot;page&quot; parameters passed into the method.</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//We'll ignore the &quot;nd&quot;, &quot;search&quot;, &quot;sidx&quot;, &quot;sord&quot; parameters.</span>

&nbsp; &nbsp; &nbsp; &nbsp; List returnList = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> List<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; NorthwindDataContext context = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> NorthwindDataContext<span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> SqlConnection<span class="br0">&#40;</span>ConfigurationManager.<span class="me1">ConnectionStrings</span><span class="br0">&#91;</span><span class="st0">&quot;NorthwindConnectionString&quot;</span><span class="br0">&#93;</span>.<span class="me1">ConnectionString</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> total_pages = <span class="nu0">0</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> count = <span class="nu0">0</span>;

&nbsp; &nbsp; &nbsp; &nbsp; count = context.<span class="me1">Customers</span>.<span class="me1">Count</span><span class="br0">&#40;</span><span class="br0">&#41;</span>; 

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>count &amp;gt; <span class="nu0">0</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; total_pages = <span class="br0">&#40;</span><span class="kw4">int</span><span class="br0">&#41;</span>Math.<span class="me1">Ceiling</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw4">double</span><span class="br0">&#41;</span>count / rows<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">null</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>page &amp;gt; total_pages<span class="br0">&#41;</span> page = total_pages;

&nbsp; &nbsp; &nbsp; &nbsp; var customers= from c <span class="kw1">in</span> context.<span class="me1">Customers</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; select c;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>page &amp;gt; <span class="nu0">0</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; customers = customers.<span class="me1">Skip</span><span class="br0">&#40;</span><span class="br0">&#40;</span>page - <span class="nu0">1</span><span class="br0">&#41;</span> * rows<span class="br0">&#41;</span>.<span class="me1">Take</span><span class="br0">&#40;</span>rows<span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span><span class="br0">&#40;</span>var customer <span class="kw1">in</span> customers<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; returnList.<span class="me1">Add</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Customer
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CustomerID = customer.<span class="me1">CustomerID</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CompanyName = customer.<span class="me1">CompanyName</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; jGridPagedResult response =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> jGridPagedResult<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; page = page,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; total = total_pages,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rows = returnList,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; records = count
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> response;
&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="font-weight:bolder;">Setting Up jqGrid</span></p>
<p>In the HTML page, add links to the jquery.js and jquery.jGrid.js libraries in the head tag.  The jquery.jGrid.js actually is responsible for downloading a bunch of .js files.  You can choose to download the compact (ie, &#8220;*-min.js) versions of the required files by updating &#8220;var minver = true;&#8221; in the jquery.jGrid.js file.</p>
<p>I noticed that the download list in jquery.jGrid.js does not include the 3 other required files for the grid to work properly: &#8220;jqDnR.js&#8221;, &#8220;jqModal.js&#8221;, and &#8220;jquery.tablednd.js&#8221;.  They are in fact there as part of the zip file.  Just add them in the &#8220;head&#8221; tag or include them in the download list of jquery.jGrid.js:</p>
<pre style="height: 150px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">...
&nbsp; &nbsp; <span class="br0">&#123;</span> include: <span class="kw2">true</span>, incfile: <span class="st0">'jqDnR.js'</span>, minfile: <span class="st0">'min/jqDnR-min.js'</span> <span class="br0">&#125;</span>,
&nbsp; &nbsp; <span class="br0">&#123;</span> include: <span class="kw2">true</span>, incfile: <span class="st0">'jqModal.js'</span>, minfile: <span class="st0">'min/jqModal-min.js'</span> <span class="br0">&#125;</span>,
&nbsp; &nbsp; <span class="br0">&#123;</span> include: <span class="kw2">true</span>, incfile: <span class="st0">'jquery.tablednd.js'</span>, minfile: <span class="st0">'min/jquery.tablednd-min.js'</span> <span class="br0">&#125;</span>,
&nbsp; &nbsp; ...</div>
</div>
</pre>
<p>Next, in the body section, add a table and div element that will actually hold the jqGrid and paging control components.</p>
<pre style="height: 100px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">&nbsp;</div>
</div>
</pre>
<p>Lastly, add the javascript that will create the jqGrid and paging controls AFTER the above HTML elements have been added in the body.  Hope this post will help speed up your development with jqGrid and WCF!</p>
<p>(One final note is that the grid did not bind the data until I explicitly added the &#8220;<span style="font-weight:bolder;">jsonReader: {&#8230;</span>&#8221; object in the jqGrid() constructor.)</p>
<pre style="height: 600px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw2">var</span> service_endpoint = <span class="st0">&quot;http://localhost/northwindservice.svc/&quot;</span>;
$<span class="br0">&#40;</span>document<span class="br0">&#41;</span>.<span class="me1">ready</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">&quot;#customers&quot;</span><span class="br0">&#41;</span>.<span class="me1">jqGrid</span><span class="br0">&#40;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; url: service_endpoint + <span class="st0">&quot;GetCustomers?&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; datatype: <span class="st0">&quot;json&quot;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; colNames: <span class="br0">&#91;</span><span class="st0">'CustomerID'</span>, <span class="st0">'CompanyName'</span><span class="br0">&#93;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; colModel: <span class="br0">&#91;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> <span class="kw3">name</span>: <span class="st0">'CustomerID'</span>, index: <span class="st0">'CustomerID'</span>, width: <span class="nu0">60</span>, align: <span class="st0">&quot;right&quot;</span> <span class="br0">&#125;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> <span class="kw3">name</span>: <span class="st0">'CompanyName'</span>, index: <span class="st0">'CompanyName'</span>, width: <span class="nu0">120</span>, sortable: <span class="kw2">false</span> <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#93;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; pager: $<span class="br0">&#40;</span><span class="st0">'#pager1'</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; rowNum: <span class="nu0">10</span>,
&nbsp; &nbsp; &nbsp; &nbsp; rowList: <span class="br0">&#91;</span><span class="nu0">10</span>, <span class="nu0">20</span>, <span class="nu0">30</span><span class="br0">&#93;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; imgpath: <span class="st0">'themes/steel/images'</span>,
&nbsp; &nbsp; &nbsp; &nbsp; sortname: <span class="st0">'ProcessId'</span>,
&nbsp; &nbsp; &nbsp; &nbsp; viewrecords: <span class="kw2">true</span>,
&nbsp; &nbsp; &nbsp; &nbsp; sortorder: <span class="st0">&quot;asc&quot;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; jsonReader: <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; root: <span class="st0">&quot;rows&quot;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; page: <span class="st0">&quot;page&quot;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; total: <span class="st0">&quot;total&quot;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; records: <span class="st0">&quot;records&quot;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; repeatitems: <span class="kw2">false</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; id: <span class="st0">&quot;CustomerID&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; caption: <span class="st0">&quot;Northwind Customers&quot;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>.<span class="me1">navGrid</span><span class="br0">&#40;</span><span class="st0">'#pager1'</span>, <span class="br0">&#123;</span> edit: <span class="kw2">false</span>, add: <span class="kw2">false</span>, del: <span class="kw2">false</span>, view: <span class="kw2">false</span>, refresh: <span class="kw2">false</span>, search: <span class="kw2">false</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://eztier.com/dba2day/?feed=rss2&amp;p=264</wfw:commentRss>
		</item>
		<item>
		<title>Combining ASP.NET Authentication and Message Encryption with Silverlight 2</title>
		<link>http://eztier.com/dba2day/?p=247</link>
		<comments>http://eztier.com/dba2day/?p=247#comments</comments>
		<pubDate>Thu, 04 Jun 2009 17:53:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Silverlight 2 (5)]]></category>

		<category><![CDATA[WCF (2)]]></category>

		<guid isPermaLink="false">http://eztier.com/dba2day/?p=247</guid>
		<description><![CDATA[Silverlight 2 as a Line of Business (LOB) application must be able to handle your company&#8217;s data securely.  Out of the box, if your IDE is Visual Studio 2008, you can incorporate ASP.NET authentication by adding a &#8220;Silverlight-enabled WCF Service&#8221; item to an existing WCF project.  You can also enable the Authentication Service [...]]]></description>
			<content:encoded><![CDATA[<p>Silverlight 2 as a Line of Business (LOB) application must be able to handle your company&#8217;s data securely.  Out of the box, if your IDE is Visual Studio 2008, you can incorporate ASP.NET authentication by adding a &#8220;Silverlight-enabled WCF Service&#8221; item to an existing WCF project.  You can also enable the Authentication Service provider in web.config by following <a href="http://msdn.microsoft.com/en-us/library/bb398990.aspx">MSDN&#8217;s tutotial</a>.  Ideally, this is implemented over SSL and will provide transport security for the application.  </p>
<p>The above implementaion does not support message level encryption.  Since Silverlight 2 only supports BasicHttpBinding, WS-* security features like message encryption and digital signing with X.509 certicates are not available.</p>
<p>However, Silverlight 2 does support symmetric key (&#8221;shared secret&#8221;) encryption using AES algorithm.  Here is a descriptive <a href="http://silverlightuk.blogspot.com/2008/06/silverlight-encryption-part-2.html">series of articles</a> on the topic.  With a little bit of plumbing on the WCF service side, it is possible to create a custom authentication and message encryption security architecture for Silverlight 2.  </p>
<p><a href="http://eztier.com/dba2day/wp-content/uploads/2009/06/messageencryptionpage.jpg"><img src="http://eztier.com/dba2day/wp-content/uploads/2009/06/messageencryptionpage.jpg" alt="" title="Message Encryption Page" width="500" height="332" class="alignnone size-full wp-image-256" /></a></p>
<p><a href="http://eztier.com/dba2day/wp-content/uploads/2009/06/logonpage.jpg"><img src="http://eztier.com/dba2day/wp-content/uploads/2009/06/logonpage.jpg" alt="" title="Logon Page Screenshot" width="400" height="299" class="alignnone size-full wp-image-251" /></a></p>
<p>Online sample below. . .<br />
<span id="more-247"></span></p>
<p>You can check out the <a target="_blank" href="http://eztier.com/samples/sl2/security/logon.html">ONLINE DEMO</a>.</p>
<p><span style="font-weight:bolder;">Router Service</span></p>
<p>At the heart of this project is the router service.  It acts as the gatekeeper to any WCF service calls made by the Silverlight client.  It&#8217;s job is to intercept and decide what to do with the message.  An excellent article on how to implement a WCF router can be found <a href="http://msdn.microsoft.com/en-us/magazine/cc500646.aspx?pr=blog">here</a>.  </p>
<p>An important take-away from the article is that the channel dispatcher allows for one and only one operation to receive ANY message if the &#8220;Action&#8221; or &#8220;Reply&#8221; cannot be mapped to any operation contracts at that endpoint.  That one operation needs to be assigned a &#8220;*&#8221; value to the Action and Reply attribute as follows:  </p>
<pre style="height:170px;overflow:hidden;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="br0">&#91;</span>ServiceContract<span class="br0">&#93;</span>
&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">interface</span> IRouterService
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span>OperationContract<span class="br0">&#40;</span>Action = <span class="st0">&quot;*&quot;</span>, ReplyAction = <span class="st0">&quot;*&quot;</span><span class="br0">&#41;</span><span class="br0">&#93;</span>
&nbsp; &nbsp; &nbsp; &nbsp; Message ProcessMessage<span class="br0">&#40;</span>Message request_message<span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</div>
</pre>
<p>The authentication process can be summarized as follows:</p>
<p>1.  The Silverlight application calls the Authentication Service VIA the Router.<br />
2.  The Router intercepts and forwards the message to the Authentication Sevice.<br />
3.  Upon receiving a response, the Router inspects the message to check the logon result.  If sucessful, it will create a session id and a symmetric key and store the information in a Cache Backing Store (in memory or database).<br />
4.  The session id, symmetric key, and expiration data is injected as additional headers of the response message to the client application if the logon was successful. </p>
<p>The diagram below visualizes the authentication workflow:</p>
<p><a href="http://eztier.com/dba2day/wp-content/uploads/2009/06/authenticationworkflow.jpg"><img src="http://eztier.com/dba2day/wp-content/uploads/2009/06/authenticationworkflow.jpg" alt="" title="Authentication Workflow" width="500" height="375" class="alignnone size-full wp-image-253" /></a></p>
<p>Once authenticated, the Silverlight client can retrieve the session id and symmetric key from the message headers in the response.  In any subsequent remote calls to any WCF service, the Silverlight client will include the session id in the request message header and will use the symmetric key to encrypt the request.  </p>
<p>The message encryption process can be summarized as follows:</p>
<p>1.  The Silverlight client adds the session id given to it by the Router to the request header.<br />
2.  The client also encrypts the request body with the symmetric key.<br />
3.  The client sends the message to the WCF service but again VIA the Router.<br />
4.  The Router intercepts the request and extracts the session id from the header.  It then queries the Cache Backing Store to see if the session id exists.  If the session id is valid, the Router will grab the symmetric key from the Backing Store.<br />
5.  The Router decrypts the request body using the symmetric key and forwards the message to the WCF service.<br />
5.  Once the Router receives a response from the WCF service, the Router encrypts the response body with the same key and forwards the message back to the Silverlight client.<br />
6.  The Silverlight client decrypts the message body with the symmetric key.</p>
<p>The diagram below visualizes the message encryption workflow:</p>
<p><a href="http://eztier.com/dba2day/wp-content/uploads/2009/06/messageencryptionworkflow.jpg"><img src="http://eztier.com/dba2day/wp-content/uploads/2009/06/messageencryptionworkflow.jpg" alt="" title="Message Encryption Workflow" width="500" height="375" class="alignnone size-full wp-image-254" /></a></p>
<p>As indicated above, the Router will inspect the action header and decide what to do with the message.</p>
<pre style="overflow:hidden;height:290px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">Func&lt;Message, <span class="kw4">string</span>, Message&gt; ProcessAction;
Message Authenticate<span class="br0">&#40;</span>
&nbsp; &nbsp; Message request_message, 
&nbsp; &nbsp; <span class="kw4">string</span> endpoint_configuration<span class="br0">&#41;</span> <span class="br0">&#123;</span>
. . . <span class="br0">&#125;</span>
Message SecureMessage<span class="br0">&#40;</span>
&nbsp; &nbsp; Message request_message, 
&nbsp; &nbsp; <span class="kw4">string</span> endpoint_configuration<span class="br0">&#41;</span> <span class="br0">&#123;</span>
. . . <span class="br0">&#125;</span>
Message ForwardMessage<span class="br0">&#40;</span>
&nbsp; &nbsp; Message request_message, 
&nbsp; &nbsp; <span class="kw4">string</span> endpoint_configuration<span class="br0">&#41;</span> <span class="br0">&#123;</span>
. . . <span class="br0">&#125;</span></div>
</div>
</pre>
<p>Depending on the content of the Action header, the Router will choose how the message will be fowarded to the ultimate WCF service.</p>
<pre style="height:720px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">public</span> Message ProcessMessage<span class="br0">&#40;</span>Message request_message<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw4">string</span> operation_contract = 
&nbsp; &nbsp; &nbsp; &nbsp; request_message.<span class="me1">Headers</span>.<span class="me1">GetHeader</span>&lt;string&gt;<span class="br0">&#40;</span><span class="st0">&quot;Action&quot;</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;http://schemas.microsoft.com/ws/2005/05/addressing/none&quot;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw4">string</span> endpoint_configuration = <span class="st0">&quot;&quot;</span>;

&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>operation_contract.<span class="me1">ToLower</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.
&nbsp; &nbsp; <span class="me1">Contains</span><span class="br0">&#40;</span><span class="st0">&quot;login&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; ProcessAction = Authenticate;
&nbsp; &nbsp; &nbsp; &nbsp; endpoint_configuration = 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;BasicHttpBinding_AuthenticationService&quot;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">else</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Message that requires security</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>operation_contract.<span class="me1">ToLower</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.
&nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">Contains</span><span class="br0">&#40;</span><span class="st0">&quot;some_operation_requiring_security&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Check if there is a valid session id in header</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> sessionId = 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; request_message.<span class="me1">Headers</span>.<span class="me1">GetHeader</span>&lt;string&gt;<span class="br0">&#40;</span><span class="st0">&quot;SessionId&quot;</span>, <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; symmetric_key = <span class="br0">&#40;</span><span class="kw4">byte</span><span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>cacheManager.<span class="me1">GetData</span><span class="br0">&#40;</span>sessionId<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>symmetric_key == <span class="kw1">null</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">throw</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MessageHeaderException<span class="br0">&#40;</span><span class="st0">&quot;Session Id does not exist or has expired.&quot;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">catch</span> <span class="br0">&#40;</span>MessageHeaderException messageHeaderException<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">throw</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MessageHeaderException<span class="br0">&#40;</span>messageHeaderException.<span class="me1">Message</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ProcessAction = SecureMessage;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; endpoint_configuration = 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;BasicHttpBinding_IRequireSecurityService&quot;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Message that does not require security</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>operation_contract.<span class="me1">ToLower</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.
&nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">Contains</span><span class="br0">&#40;</span><span class="st0">&quot;some_operation_not_requiring_security&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ProcessAction = ForwardMessage;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; endpoint_configuration = 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;BasicHttpBinding_IDoesNotRequireSecurityService&quot;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">return</span> ProcessAction<span class="br0">&#40;</span>request_message, endpoint_configuration<span class="br0">&#41;</span>;
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="font-weight:bolder;">Authenticate() Method</span></p>
<pre style="height:720px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">Message Authenticate<span class="br0">&#40;</span>Message request_message, 
&nbsp; &nbsp; <span class="kw4">string</span> endpoint_configuration<span class="br0">&#41;</span> 
<span class="br0">&#123;</span>

Message response_message = <span class="kw1">null</span>;

<span class="kw1">try</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">using</span> <span class="br0">&#40;</span>ChannelFactory&lt;IRouterService&gt; factory = 
&nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> ChannelFactory&lt;IRouterService&gt;<span class="br0">&#40;</span>endpoint_configuration<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; factory.<span class="me1">Endpoint</span>.<span class="me1">Behaviors</span>.<span class="me1">Add</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MustUnderstandBehavior<span class="br0">&#40;</span><span class="kw1">false</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; IRouterService proxy = factory.<span class="me1">CreateChannel</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">using</span> <span class="br0">&#40;</span>proxy <span class="kw1">as</span> IDisposable<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Forward the message and intercept the response</span>
&nbsp; &nbsp; &nbsp; &nbsp; response_message = proxy.<span class="me1">ProcessMessage</span><span class="br0">&#40;</span>request_message<span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; XElement elements = XElement.<span class="me1">Parse</span><span class="br0">&#40;</span>response_message.<span class="me1">ToString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; var body = 
&nbsp; &nbsp; &nbsp; &nbsp; elements.<span class="me1">Element</span><span class="br0">&#40;</span><span class="st0">&quot;{http://schemas.xmlsoap.org/soap/envelope/}Body&quot;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> asp_ns = <span class="st0">&quot;{http://asp.net/ApplicationServices/v200}&quot;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; var login_response = 
&nbsp; &nbsp; &nbsp; &nbsp; from detail <span class="kw1">in</span> body.<span class="me1">Descendants</span><span class="br0">&#40;</span>asp_ns + <span class="st0">&quot;LoginResponse&quot;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; select <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> <span class="br0">&#123;</span> LoginResult = detail.<span class="me1">Element</span><span class="br0">&#40;</span>asp_ns + <span class="st0">&quot;LoginResult&quot;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>login_response == <span class="kw1">null</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">throw</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Exception<span class="br0">&#40;</span><span class="st0">&quot;No response&quot;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">byte</span><span class="br0">&#91;</span><span class="br0">&#93;</span> session_key = <span class="kw1">null</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> session_id = <span class="st0">&quot;&quot;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">bool</span> login_result = <span class="kw1">false</span>;
&nbsp; &nbsp; &nbsp; &nbsp; MessageHeader header = <span class="kw1">null</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//Authenticated: issue a symmetric key </span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>login_response.<span class="me1">FirstOrDefault</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.
&nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">LoginResult</span>.<span class="me1">Value</span> == <span class="st0">&quot;true&quot;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//Issue a new key</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">String</span> random_string = AesManagedExtensions.<span class="me1">GetRandomString</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; session_key = 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AesManagedExtensions.<span class="me1">GetHashKey</span><span class="br0">&#40;</span>random_string, random_string<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; session_id = Guid.<span class="me1">NewGuid</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">ToString</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//Cache the key</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CacheObject<span class="br0">&#40;</span>session_id, session_key<span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; login_result = <span class="kw1">true</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//Add the symmetric key, authentication result to the header</span>
&nbsp; &nbsp; &nbsp; &nbsp; header = MessageHeader.
&nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">CreateHeader</span><span class="br0">&#40;</span><span class="st0">&quot;SessionKey&quot;</span>, <span class="st0">&quot;&quot;</span>, session_key, <span class="kw1">false</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; response_message.<span class="me1">Headers</span>.<span class="me1">Add</span><span class="br0">&#40;</span>header<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; header = MessageHeader.
&nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">CreateHeader</span><span class="br0">&#40;</span><span class="st0">&quot;SessionId&quot;</span>, <span class="st0">&quot;&quot;</span>, session_id, <span class="kw1">false</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; response_message.<span class="me1">Headers</span>.<span class="me1">Add</span><span class="br0">&#40;</span>header<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; header = MessageHeader.
&nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">CreateHeader</span><span class="br0">&#40;</span><span class="st0">&quot;LoginResult&quot;</span>, <span class="st0">&quot;&quot;</span>, login_result, <span class="kw1">false</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; response_message.<span class="me1">Headers</span>.<span class="me1">Add</span><span class="br0">&#40;</span>header<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; header = MessageHeader.
&nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">CreateHeader</span><span class="br0">&#40;</span><span class="st0">&quot;CacheExpiration&quot;</span>, <span class="st0">&quot;&quot;</span>, cache_expiration_interval, <span class="kw1">false</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; response_message.<span class="me1">Headers</span>.<span class="me1">Add</span><span class="br0">&#40;</span>header<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
<span class="kw1">catch</span> <span class="br0">&#40;</span>Exception ex<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">throw</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> CommunicationException<span class="br0">&#40;</span>ex.<span class="me1">Message</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">return</span> response_message;
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="font-weight:bolder;">SecureMessage() Method</span></p>
<pre style="height:720px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">Message SecureMessage<span class="br0">&#40;</span>Message request_message, 
&nbsp; &nbsp; <span class="kw4">string</span> endpoint_configuration<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; Message new_request_message = <span class="kw1">null</span>;
&nbsp; &nbsp; Message new_response_message = <span class="kw1">null</span>;
&nbsp; &nbsp; XmlWriter writer;
&nbsp; &nbsp; XmlReader reader;
&nbsp; &nbsp; MemoryStream memory_stream = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MemoryStream<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; MessageBuffer buffer = <span class="kw1">null</span>;
&nbsp; &nbsp; Message tmp_message = <span class="kw1">null</span>;
&nbsp; &nbsp; XElement body = <span class="kw1">null</span>;

&nbsp; &nbsp; Action DecryptRequest = <span class="br0">&#40;</span><span class="br0">&#41;</span> =&gt;
&nbsp; &nbsp; <span class="br0">&#123;</span>

&nbsp; &nbsp; <span class="co1">// Make a copy of the message to avoid </span>
&nbsp; &nbsp; <span class="co1">// &quot;... message has been read error...&quot;</span>
&nbsp; &nbsp; buffer = request_message.<span class="me1">CreateBufferedCopy</span><span class="br0">&#40;</span>Int32.<span class="me1">MaxValue</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; <span class="co1">//Load old message into XML</span>
&nbsp; &nbsp; tmp_message = buffer.<span class="me1">CreateMessage</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; buffer.<span class="me1">Close</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; <span class="co1">//Transform the xmldocument</span>
&nbsp; &nbsp; body = tmp_message.<span class="me1">GetBody</span>&lt;XElement&gt;<span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; var test = body.<span class="me1">Descendants</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; body.<span class="me1">Descendants</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">ToList</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="kw1">ForEach</span><span class="br0">&#40;</span>d =&gt;
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Decrypt the value for each xelement</span>
&nbsp; &nbsp; &nbsp; &nbsp; d.<span class="me1">SetValue</span><span class="br0">&#40;</span>d.<span class="me1">Value</span>.<span class="me1">AesDecrypt</span><span class="br0">&#40;</span>symmetric_key<span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; writer = XmlWriter.<span class="me1">Create</span><span class="br0">&#40;</span>memory_stream<span class="br0">&#41;</span>;
&nbsp; &nbsp; body.<span class="me1">Save</span><span class="br0">&#40;</span>writer<span class="br0">&#41;</span>;
&nbsp; &nbsp; writer.<span class="me1">Flush</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; memory_stream.<span class="me1">Position</span> = <span class="nu0">0</span>;

&nbsp; &nbsp; reader = XmlReader.<span class="me1">Create</span><span class="br0">&#40;</span>memory_stream<span class="br0">&#41;</span>;

&nbsp; &nbsp; <span class="co1">//create new request message with decrypted message</span>
&nbsp; &nbsp; new_request_message = Message.
&nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">CreateMessage</span><span class="br0">&#40;</span>request_message.<span class="me1">Version</span>, <span class="kw1">null</span>, reader<span class="br0">&#41;</span>;
&nbsp; &nbsp; new_request_message.<span class="me1">Headers</span>.
&nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">CopyHeadersFrom</span><span class="br0">&#40;</span>request_message<span class="br0">&#41;</span>;
&nbsp; &nbsp; new_request_message.<span class="me1">Properties</span>.
&nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">CopyProperties</span><span class="br0">&#40;</span>request_message.<span class="me1">Properties</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>;

&nbsp; &nbsp; Action EncryptResponse = <span class="br0">&#40;</span><span class="br0">&#41;</span> =&gt;
&nbsp; &nbsp; <span class="br0">&#123;</span>

&nbsp; &nbsp; <span class="kw1">try</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">using</span> <span class="br0">&#40;</span>ChannelFactory&lt;IRouterService&gt; factory = 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> ChannelFactory&lt;IRouterService&gt;<span class="br0">&#40;</span>endpoint_configuration<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; factory.<span class="me1">Endpoint</span>.<span class="me1">Behaviors</span>.<span class="me1">Add</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MustUnderstandBehavior<span class="br0">&#40;</span><span class="kw1">false</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IRouterService proxy = factory.<span class="me1">CreateChannel</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">using</span> <span class="br0">&#40;</span>proxy <span class="kw1">as</span> IDisposable<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Forward decrypted request message and intercept the response</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Message response_message = proxy.<span class="me1">ProcessMessage</span><span class="br0">&#40;</span>new_request_message<span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buffer = response_message.<span class="me1">CreateBufferedCopy</span><span class="br0">&#40;</span><span class="kw4">int</span>.<span class="me1">MaxValue</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tmp_message = buffer.<span class="me1">CreateMessage</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buffer.<span class="me1">Close</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; body = tmp_message.<span class="me1">GetBody</span>&lt;XElement&gt;<span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var result_element = body.<span class="me1">Descendants</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">FirstOrDefault</span><span class="br0">&#40;</span>r =&gt; r.<span class="me1">Name</span>.<span class="me1">LocalName</span>.<span class="me1">ToLower</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">Contains</span><span class="br0">&#40;</span><span class="st0">&quot;result&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var encrypted_content = 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result_element.<span class="me1">ToString</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">AesEncrypt</span><span class="br0">&#40;</span>symmetric_key<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result_element.<span class="me1">SetValue</span><span class="br0">&#40;</span>encrypted_content<span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Write to memory response with encrypted results</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; memory_stream.<span class="me1">SetLength</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; writer = XmlWriter.<span class="me1">Create</span><span class="br0">&#40;</span>memory_stream<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; body.<span class="me1">Save</span><span class="br0">&#40;</span>writer<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; writer.<span class="me1">Flush</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; writer.<span class="me1">Close</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; memory_stream.<span class="me1">Position</span> = <span class="nu0">0</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reader = XmlReader.<span class="me1">Create</span><span class="br0">&#40;</span>memory_stream<span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//Create new message from modified XML document</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_response_message = Message.
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">CreateMessage</span><span class="br0">&#40;</span>response_message.<span class="me1">Version</span>, <span class="kw1">null</span>, reader<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_response_message.<span class="me1">Headers</span>.
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">CopyHeadersFrom</span><span class="br0">&#40;</span>response_message<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_response_message.<span class="me1">Properties</span>.
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">CopyProperties</span><span class="br0">&#40;</span>response_message.<span class="me1">Properties</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">catch</span> <span class="br0">&#40;</span>Exception ex<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">throw</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> CommunicationException<span class="br0">&#40;</span>ex.<span class="me1">Message</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>;

&nbsp; &nbsp; DecryptRequest<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; EncryptResponse<span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; <span class="kw1">return</span> new_response_message;
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>And finally, here is the method that just forwards the message.</p>
<pre style="height:530px;overflow:hidden;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">Message ForwardMessage<span class="br0">&#40;</span>Message request_message, 
&nbsp; &nbsp; <span class="kw4">string</span> endpoint_configuration<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">try</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">using</span> <span class="br0">&#40;</span>ChannelFactory&lt;IRouterService&gt; factory = 
&nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> ChannelFactory&lt;IRouterService&gt;<span class="br0">&#40;</span>endpoint_configuration<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; factory.<span class="me1">Endpoint</span>.<span class="me1">Behaviors</span>.
&nbsp; &nbsp; &nbsp; &nbsp; <span class="me1">Add</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MustUnderstandBehavior<span class="br0">&#40;</span><span class="kw1">false</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; IRouterService proxy = factory.<span class="me1">CreateChannel</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">using</span> <span class="br0">&#40;</span>proxy <span class="kw1">as</span> IDisposable<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Message response_message = 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proxy.<span class="me1">ProcessMessage</span><span class="br0">&#40;</span>request_message<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> response_message;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">catch</span> <span class="br0">&#40;</span>Exception ex<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">throw</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> CommunicationException<span class="br0">&#40;</span>ex.<span class="me1">Message</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://eztier.com/dba2day/?feed=rss2&amp;p=247</wfw:commentRss>
		</item>
		<item>
		<title>AJAX with WCF</title>
		<link>http://eztier.com/dba2day/?p=238</link>
		<comments>http://eztier.com/dba2day/?p=238#comments</comments>
		<pubDate>Thu, 30 Apr 2009 03:41:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[AJAX (2)]]></category>

		<guid isPermaLink="false">http://eztier.com/dba2day/?p=238</guid>
		<description><![CDATA[With the upcoming release of ASP.NET AJAX 4.0, consuming and presenting cloud data in grid format without adding third-party components will be a reality. Until then, among the free grid components for ASP.NET for AJAX 1.0 that are out there, the one I found the most user friendly is the Ajax Data Controls Version 1.0. [...]]]></description>
			<content:encoded><![CDATA[<p>With the upcoming release of ASP.NET AJAX 4.0, consuming and presenting cloud data in grid format without adding third-party components will be a reality. Until then, among the free grid components for ASP.NET for AJAX 1.0 that are out there, the one I found the most user friendly is the <a href="http://www.codeplex.com/AjaxDataControls">Ajax Data Controls Version 1.0</a>. There are plenty of samples showing how the component can be used <a href="http://dotnetslackers.com/projects/AjaxDataControls/DataList/MasterDetail.aspx">here</a>. </p>
<p>I took a stab at implementing this component with WCF as the web service provider.</p>
<p><a href="http://eztier.com/dba2day/wp-content/uploads/2009/04/ajaxwithwcf-preview.png"><img class="alignnone size-full wp-image-239" title="AJAX with WCF" src="http://eztier.com/dba2day/wp-content/uploads/2009/04/ajaxwithwcf-preview.png" alt="" width="499" height="336" /></a></p>
<p><span id="more-238"></span></p>
<p>In the implemention, I incorporated paging, editing, and master/detail features of the component by following the samples.  After updating the CSS, I was up and running with an AJAX-enabled grid formatted application.</p>
<p>You can see the <a href="http://eztier.com/samples/ajax/ajaxwithwcf/default.aspx">online demo here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://eztier.com/dba2day/?feed=rss2&amp;p=238</wfw:commentRss>
		</item>
		<item>
		<title>Data Driven Application Demo with Silverlight 2</title>
		<link>http://eztier.com/dba2day/?p=228</link>
		<comments>http://eztier.com/dba2day/?p=228#comments</comments>
		<pubDate>Sat, 18 Apr 2009 16:47:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Silverlight 2 (5)]]></category>

		<guid isPermaLink="false">http://eztier.com/dba2day/?p=228</guid>
		<description><![CDATA[Recently, I submitted an entry to the Silverlight.net Showcase based on some of my previous posts on custom sortables and path animation.  In this application, users can drag and reorder the sortables to refresh the charts. The charts also support drill thru.  The visual elements consume data from WCF REST, ATOM, and POX [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I submitted an entry to the Silverlight.net Showcase based on some of my previous posts on <a href="http://eztier.com/dba2day/?p=133">custom sortables</a> and <a href="http://eztier.com/dba2day/?p=81">path animation</a>.  In this application, users can drag and reorder the sortables to refresh the charts. The charts also support drill thru.  The visual elements consume data from WCF REST, ATOM, and POX services and exchange notifications upon data binding.  There are a few free charting solutions for Silverlight 2 and I decided to use the Visifire component.</p>
<p>
<a href="http://eztier.com/dba2day/wp-content/uploads/2009/04/silverlightshowcasepreview.jpg"><img src="http://eztier.com/dba2day/wp-content/uploads/2009/04/silverlightshowcasepreview.jpg" alt="" title="Silverlight.net Showcase Preview" width="400" height="315" class="alignnone size-full wp-image-229" /></a>
</p>
<p><span id="more-228"></span><br />
You can see the <a href="http://eztier.com/samples/sl2/rest/clouddataconsumer.html">online demo here.</a></p>
<p>
<a href="http://eztier.com/dba2day/wp-content/uploads/2009/04/silverlightdataapp.png"><img src="http://eztier.com/dba2day/wp-content/uploads/2009/04/silverlightdataapp.png" alt="" title="Silverlight Data Driven Application" width="177" height="172" class="alignnone size-full wp-image-230" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://eztier.com/dba2day/?feed=rss2&amp;p=228</wfw:commentRss>
		</item>
		<item>
		<title>Path Animation with Silverlight 2 (Part 2)</title>
		<link>http://eztier.com/dba2day/?p=181</link>
		<comments>http://eztier.com/dba2day/?p=181#comments</comments>
		<pubDate>Wed, 15 Apr 2009 00:20:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Silverlight 2 (5)]]></category>

		<guid isPermaLink="false">http://eztier.com/dba2day/?p=181</guid>
		<description><![CDATA[In my previous blog on path animation, a path element was given a &#8220;spinning wheel&#8221; effect by transforming the StrokeDashArray property. This time around, let&#8217;s animate some visual along a path element. I will reuse the spinning wheel project and it will serve as the target to move around with. The path element will be [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://eztier.com/dba2day/?p=81">previous blog</a> on path animation, a path element was given a &#8220;spinning wheel&#8221; effect by transforming the StrokeDashArray property. This time around, let&#8217;s animate some visual along a path element. I will reuse the spinning wheel project and it will serve as the target to move around with. The path element will be made up of a bunch of bezier curve segments. The final project should look like a planet with a spinning ring looping thru 3 irregular ellipses like this.</p>
<p><a href="http://eztier.com/dba2day/wp-content/uploads/2009/04/animationalongpath.jpg"><img src="http://eztier.com/dba2day/wp-content/uploads/2009/04/animationalongpath.jpg" alt="" title="Animation Along a Path" width="400" height="212" class="alignnone size-full wp-image-182" /></a></p>
<p><span id="more-181"></span><br />
You can see the <a href="http://eztier.com/samples/sl2/pathanimation/pathanimation.html">online demo here.</a></p>
<p><span style="font-weight:bolder;">Some Math</span> </p>
<p>Although the object may seem to move along a curve, it is actually performing a lot of small incremental linear TranslateTransform animations.  To calculate all the points between a start and end point along a curve, you need to perform what mathematisians call interpolation or &#8220;curve fitting.&#8221;  I came across a great <a href="http://www.paultondeur.com/2008/03/09/drawing-a-cubic-bezier-curve-using-actionscript-3/">article</a> on doing exactly this for ActionScript and implemented the same calculation method for my project.</p>
<pre style="height:200px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">void</span> CalculateNextBezierSegmentPoint<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; posx = Math.<span class="me1">Pow</span><span class="br0">&#40;</span>counter, <span class="nu0">3</span><span class="br0">&#41;</span> * <span class="br0">&#40;</span>anchor2.<span class="me1">X</span> + <span class="nu0">3</span> * <span class="br0">&#40;</span>control1.<span class="me1">X</span> - control2.<span class="me1">X</span><span class="br0">&#41;</span> - anchor1.<span class="me1">X</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp;+ <span class="nu0">3</span> * Math.<span class="me1">Pow</span><span class="br0">&#40;</span>counter, <span class="nu0">2</span><span class="br0">&#41;</span> * <span class="br0">&#40;</span>anchor1.<span class="me1">X</span> - <span class="nu0">2</span> * control1.<span class="me1">X</span> + control2.<span class="me1">X</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp;+ <span class="nu0">3</span> * counter * <span class="br0">&#40;</span>control1.<span class="me1">X</span> - anchor1.<span class="me1">X</span><span class="br0">&#41;</span> + anchor1.<span class="me1">X</span>;

&nbsp; &nbsp; posy = Math.<span class="me1">Pow</span><span class="br0">&#40;</span>counter, <span class="nu0">3</span><span class="br0">&#41;</span> * <span class="br0">&#40;</span>anchor2.<span class="me1">Y</span> + <span class="nu0">3</span> * <span class="br0">&#40;</span>control1.<span class="me1">Y</span> - control2.<span class="me1">Y</span><span class="br0">&#41;</span> - anchor1.<span class="me1">Y</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; + <span class="nu0">3</span> * Math.<span class="me1">Pow</span><span class="br0">&#40;</span>counter, <span class="nu0">2</span><span class="br0">&#41;</span> * <span class="br0">&#40;</span>anchor1.<span class="me1">Y</span> - <span class="nu0">2</span> * control1.<span class="me1">Y</span> + control2.<span class="me1">Y</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; + <span class="nu0">3</span> * counter * <span class="br0">&#40;</span>control1.<span class="me1">Y</span> - anchor1.<span class="me1">Y</span><span class="br0">&#41;</span> + anchor1.<span class="me1">Y</span>;
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>The variables &#8220;anchor1&#8243; and &#8220;anchor2&#8243; are the start and end points. The variables &#8220;control1&#8243; and &#8220;control2&#8243; are the control points of the cubic bezier curve.  This resembles the path markup syntax in Silverlight for defining a cubic bezier segment: &#8220;C control1, control2, anchor2&#8243;.  The count variable is a fraction (ie, 0.01, 0.2, etc) and is very important not only in the calculation of the incremental data points but will also serve as the checkpoint as to when to stop calculating once we have reached the end point (anchor2) as we&#8217;ll see shortly.</p>
<p><span style="font-weight:bolder;">Parsing Path Markup</span></p>
<p>The 3 irregular ellipses in the above image is made of 6 bezier curve segments as defined below.</p>
<pre style="height:75px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">const</span> <span class="kw4">string</span> path_markup = <span class="st0">&quot;M 85,135 C 80 ,0 235,0 285,135 C 345,350 750,450 545,175 C365,0 705,0 715,125 C735,250 570,250 515,135 C 425,0 125,0 285,160 C 500,400 110,450 85,135&quot;</span>;</div>
</div>
</pre>
<p>There are various ways you can implement a method to parse a path markup.  My approach was to use regular expressions and some Linq expressions to arrive at a sequence of data points.  For this project, I will only look for a start point &#8220;M&#8221; and cubic bezier segments &#8220;C&#8221;.  But you can easily change the regular expression to return more matches like &#8220;Q&#8221; for a quadratic bezier segment or &#8220;A&#8221; for an ellipse.  (Just remember to impement the logic to handle those type of path segments.)</p>
<p>I will perform 2 regular expression searches.  The first is for a path segment markup: &#8220;C 80,0 235,0 285,135&#8243;.  If I find matches for a path segment, I perform a second regular expression search for groups of data points within the path segment: &#8220;80,0&#8243;, &#8220;235,0&#8243;; &#8220;285,135&#8243;.  Once I have a sequence of data points, I will queue them up.</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">void</span> QueuePathSegments<span class="br0">&#40;</span><span class="kw4">string</span> path_markup<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="co1">// only parsing for cubic bezier segments for now...</span>
&nbsp; &nbsp; <span class="kw4">string</span> get_control_points_expression = <span class="st0">@"\s*(-?\d*(\.\d*)?\s*,\s*-?\d*(\.\d*)?\s*)&quot;</span>;
&nbsp; &nbsp; <span class="kw4">string</span> get_curve_commands_expression = <span class="kw4">string</span>.<span class="me1">Format</span><span class="br0">&#40;</span><span class="st0">@"([MmCc]{0}{{1,3}})&quot;</span>, get_control_points_expression<span class="br0">&#41;</span>;

&nbsp; &nbsp; var curve_commands_matches = from Match curve_commands <span class="kw1">in</span> Regex.<span class="me1">Matches</span><span class="br0">&#40;</span>path_markup, get_curve_commands_expression<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;select curve_commands;

&nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span>Match curve_command <span class="kw1">in</span> curve_commands_matches<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; var points =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; from control_point <span class="kw1">in</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>from Match control_points <span class="kw1">in</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Regex.<span class="me1">Matches</span><span class="br0">&#40;</span>curve_command.<span class="me1">Value</span>, get_control_points_expression<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;select control_points<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; select control_point.<span class="me1">Value</span>.<span class="me1">Replace</span><span class="br0">&#40;</span><span class="st0">&quot; &quot;</span>, <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Start Point &quot;M&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>curve_command.<span class="me1">Value</span>.<span class="me1">StartsWith</span><span class="br0">&#40;</span><span class="st0">&quot;m&quot;</span>, StringComparison.<span class="me1">InvariantCultureIgnoreCase</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span><span class="br0">&#91;</span><span class="br0">&#93;</span> coordinates = points.<span class="me1">FirstOrDefault</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">Split</span><span class="br0">&#40;</span><span class="st0">','</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BezierSegment bezier_segment = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> BezierSegment<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bezier_segment.<span class="me1">Point3</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> X = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, Y = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; path_segments.<span class="me1">Enqueue</span><span class="br0">&#40;</span>bezier_segment<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Cubic Bezier Point &quot;C&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>curve_command.<span class="me1">Value</span>.<span class="me1">StartsWith</span><span class="br0">&#40;</span><span class="st0">&quot;c&quot;</span>, StringComparison.<span class="me1">InvariantCultureIgnoreCase</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> point_counter = <span class="nu0">0</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BezierSegment bezier_segment = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> BezierSegment<span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; points.<span class="me1">ToList</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="kw1">ForEach</span><span class="br0">&#40;</span>p =&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span><span class="br0">&#91;</span><span class="br0">&#93;</span> coordinates = p.<span class="me1">Split</span><span class="br0">&#40;</span><span class="st0">','</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">switch</span> <span class="br0">&#40;</span>point_counter<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="nu0">0</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bezier_segment.<span class="me1">Point1</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> X = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, Y = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="nu0">1</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bezier_segment.<span class="me1">Point2</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> X = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, Y = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="nu0">2</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bezier_segment.<span class="me1">Point3</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> X = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, Y = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; point_counter++;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; path_segments.<span class="me1">Enqueue</span><span class="br0">&#40;</span>bezier_segment<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="font-weight:bolder;">Processing the Queue</span></p>
<p>Once the path segments are queued up, I&#8217;ll just create a routine to loop thru the queue and perform an animation for each path segment.  For each path segment in the queue, the second anchor point becomes the first anchor point of the path segment.  When one path segment has been processed, I&#8217;ll signal an event to fetch another path segemnt to process.</p>
<p>The CalculateNextBezierSegmentPoint() function that does the interpolation will now be passed as a variable to an &#8220;Animate&#8221; method.</p>
<pre style="height:610px">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">void</span> Page_Loaded<span class="br0">&#40;</span><span class="kw4">object</span> sender, RoutedEventArgs e<span class="br0">&#41;</span>
<span class="br0">&#123;</span> &nbsp; 
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">one_animation_completed_event</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> EventHandler<span class="br0">&#40;</span><span class="kw4">delegate</span> <span class="br0">&#123;</span> LookForSegmentToAnimate<span class="br0">&#40;</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span>

<span class="kw1">void</span> LookForSegmentToAnimate<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>path_segments.<span class="me1">Count</span> &amp;gt; <span class="nu0">0</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// start one animation</span>
&nbsp; &nbsp; &nbsp; &nbsp; StartOneAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">else</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// signal all animations are done</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>all_animations_completed_events != <span class="kw1">null</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; all_animations_completed_events<span class="br0">&#40;</span><span class="kw1">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> EventArgs<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>

<span class="kw1">void</span> StartOneAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="co1">// dequeue and set global control points variables</span>
&nbsp; &nbsp; PathSegment path_segment = path_segments.<span class="me1">Dequeue</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>path_segment <a href="http://www.google.com/search?q=is+msdn.microsoft.com"><span class="kw3">is</span></a> BezierSegment<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; var bezier_segemnt = path_segment <span class="kw1">as</span> BezierSegment;
&nbsp; &nbsp; &nbsp; &nbsp; control1 = bezier_segemnt.<span class="me1">Point1</span>;
&nbsp; &nbsp; &nbsp; &nbsp; control2 = bezier_segemnt.<span class="me1">Point2</span>;
&nbsp; &nbsp; &nbsp; &nbsp; anchor2 = bezier_segemnt.<span class="me1">Point3</span>;

&nbsp; &nbsp; &nbsp; &nbsp; Action calculate_path_segment_point = CalculateNextBezierSegmentPoint;
&nbsp; &nbsp; &nbsp; &nbsp; Animate<span class="br0">&#40;</span>calculate_path_segment_point<span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span> &nbsp; 
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="font-weight:bolder;">Performing the Animation</span></p>
<p>As for the &#8220;Animate&#8221; method, I need to create a routine that creates a bunch (say, about 100) of TranslateTransform animations that move the object in small steps from one anchor point to the next.  When the Animate method has processed a pre-determined number of TranslateTransform animations (in this case, 100), it will signal an event that all animations for a given path segment has finished and that event will be handled by the LookForSegmentToAnimate() as described above.</p>
<pre style="height:700px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="co1">// This UIElement will move along the path</span>
MovablePanel movable_panel = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MovablePanel<span class="br0">&#40;</span><span class="br0">&#41;</span>;

<span class="co1">// Variables used as discrete set of points to define a bezier curve for interpolation</span>
Point anchor1 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span>;
Point control1 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span>;
Point control2 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>,<span class="nu0">0</span><span class="br0">&#41;</span>;
Point anchor2 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>,<span class="nu0">0</span><span class="br0">&#41;</span>;

<span class="co1">// Variables used for interpolation (curve fitting) calculation</span>
<span class="kw1">const</span> <span class="kw4">int</span> step_size = <span class="nu0">100</span>;
<span class="kw4">Double</span> counter = <span class="nu0">0.0</span>;
<span class="kw4">Double</span> posx, posy;

<span class="kw1">void</span> Animate<span class="br0">&#40;</span>Action calculate_path_segment_point<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; calculate_path_segment_point<span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; movable_panel.<span class="me1">TranslateToPoint</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span>posx, posy<span class="br0">&#41;</span>;
&nbsp; &nbsp; storyboard = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Storyboard<span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; storyboard.<span class="me1">Completed</span> += <span class="kw4">delegate</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//storyboard = null;</span>
&nbsp; &nbsp; &nbsp; &nbsp; storyboard.<span class="me1">Stop</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; storyboard.<span class="me1">Children</span>.<span class="me1">Clear</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; counter += <span class="br0">&#40;</span><span class="nu0">1.0</span> / step_size<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>counter &gt; <span class="nu0">1</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// the last point of an animation becomes the first point of the next animation</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; anchor1 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span>posx, posy<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// need to reset counter for next animation block</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; counter = <span class="nu0">0</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// signal archor2 point has been reached and animation is done</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>one_animation_completed_event != <span class="kw1">null</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; one_animation_completed_event<span class="br0">&#40;</span><span class="kw1">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> EventArgs<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Animate<span class="br0">&#40;</span>calculate_path_segment_point<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>;

&nbsp; &nbsp; BuildTranslateTransformStoryboard<span class="br0">&#40;</span>storyboard, movable_panel, movable_panel.<span class="me1">OffsetPoint</span>, step_size<span class="br0">&#41;</span>;
&nbsp; &nbsp; storyboard.<span class="me1">Begin</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>You may notice that I am actually moving something called a &#8220;movable_panel&#8221;.  It derives from ItemsControl so you can add any UIElement to the container and all objects within the container will appear to move along the path.  The &#8220;TranslateToPoint&#8221; property is a DependencyProperty which calculates a relative Point property from a given container like a Grid or ItemsControl which is explained more in detail in my blog on <a href="http://eztier.com/dba2day/?p=133">a custom hit test</a>.</p>
<p>Finally, here is the complete code.</p>
<p><span style="font-weight:bolder;">MovablePanel.cs</span></p>
<pre style="height:600px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">public</span> <span class="kw4">class</span> MovablePanel : ItemsControl
<span class="br0">&#123;</span>
<span class="kw1">public</span> MovablePanel<span class="br0">&#40;</span><span class="br0">&#41;</span> 
<span class="br0">&#123;</span>
&nbsp; &nbsp; TransformGroup transformgroup = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> TransformGroup<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; transformgroup.<span class="me1">Children</span>.<span class="me1">Add</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> TranslateTransform<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">RenderTransform</span> = transformgroup;
<span class="br0">&#125;</span>

<span class="kw1">public</span> Point StartPosition <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span> &nbsp;<span class="co1">// sets the initial position of object; will be (0,0) by default if not set</span>
<span class="kw1">public</span> Point OffsetPoint <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span> &nbsp;<span class="co1">// this property is updated by the dependency property TranslateToPoint; translate animation will use this value</span>

<span class="co2">#region &quot;Dependency Objects&quot;</span>

<span class="kw1">public</span> <span class="kw1">static</span> <span class="kw1">readonly</span> DependencyProperty TranslateToPointProperty = DependencyProperty.<span class="me1">Register</span><span class="br0">&#40;</span><span class="st0">&quot;TranslateToPoint&quot;</span>, <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span class="kw3">typeof</span></a><span class="br0">&#40;</span>Point<span class="br0">&#41;</span>, <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span class="kw3">typeof</span></a><span class="br0">&#40;</span>MovablePanel<span class="br0">&#41;</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> PropertyMetadata<span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> PropertyChangedCallback<span class="br0">&#40;</span>OnTranslateToPointPropertyChanged<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;

<span class="kw1">public</span> Point TranslateToPoint
<span class="br0">&#123;</span>
&nbsp; &nbsp; get <span class="br0">&#123;</span> <span class="kw1">return</span> <span class="br0">&#40;</span>Point<span class="br0">&#41;</span>GetValue<span class="br0">&#40;</span>TranslateToPointProperty<span class="br0">&#41;</span>; <span class="br0">&#125;</span>
&nbsp; &nbsp; set <span class="br0">&#123;</span> SetValue<span class="br0">&#40;</span>TranslateToPointProperty, value<span class="br0">&#41;</span>; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>

<span class="kw1">static</span> <span class="kw1">void</span> OnTranslateToPointPropertyChanged<span class="br0">&#40;</span>DependencyObject d, DependencyPropertyChangedEventArgs e<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; var ui_element = d <span class="kw1">as</span> MovablePanel;
&nbsp; &nbsp; var newPoint = <span class="br0">&#40;</span>Point<span class="br0">&#41;</span>e.<span class="me1">NewValue</span>;

&nbsp; &nbsp; var offsetX = newPoint.<span class="me1">X</span> - ui_element.<span class="me1">StartPosition</span>.<span class="me1">X</span>;
&nbsp; &nbsp; var offsetY = newPoint.<span class="me1">Y</span> - ui_element.<span class="me1">StartPosition</span>.<span class="me1">Y</span>;

&nbsp; &nbsp; ui_element.<span class="me1">OffsetPoint</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span>offsetX, offsetY<span class="br0">&#41;</span>;
<span class="br0">&#125;</span>

<span class="co2">#endregion &nbsp; </span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p style="font-weight:bolder;">Page.xaml.cs</p>
<p><span style="color:DarkGreen">Variables</span></p>
<pre style="height:330px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="co1">// This UIElement will move along the path</span>
MovablePanel movable_panel = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MovablePanel<span class="br0">&#40;</span><span class="br0">&#41;</span>;

<span class="co1">// You can substitute SpinAnimation with any UIElement derived object</span>
SpinAnimation animation_to_move = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> SpinAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span>;

<span class="co1">// Variables used as discrete set of points to define a bezier curve for interpolation</span>
Point anchor1 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span>;
Point control1 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span>;
Point control2 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span>;
Point anchor2 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span>;

<span class="co1">// Variables used for interpolation (curve fitting) calculation</span>
<span class="kw1">const</span> <span class="kw4">int</span> step_size = <span class="nu0">100</span>;
<span class="kw4">Double</span> counter = <span class="nu0">0.0</span>;
<span class="kw4">Double</span> posx, posy;

<span class="co1">// Variables used in project to animate object along a path</span>
<span class="kw1">const</span> <span class="kw4">string</span> path_markup = <span class="st0">&quot;M 85,135 C 80 ,0 235,0 285,135 C 345,350 750,450 545,175 C365,0 705,0 715,125 C735,250 570,250 515,135 C 425,0 125,0 285,160 C 500,400 110,450 85,135&quot;</span>;
Storyboard storyboard;
Queue&lt;PathSegment&gt; path_segments = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Queue&lt;PathSegment&gt;<span class="br0">&#40;</span><span class="br0">&#41;</span>;
<span class="kw1">public</span> <span class="kw1">event</span> EventHandler all_animations_completed_events;
<span class="kw1">public</span> <span class="kw1">event</span> EventHandler one_animation_completed_event;</div>
</div>
</pre>
<p><span style="color:DarkGreen">EventHandlers</span></p>
<pre style="height:530px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">public</span> Page<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; InitializeComponent<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">Loaded</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> RoutedEventHandler<span class="br0">&#40;</span>Page_Loaded<span class="br0">&#41;</span>;
<span class="br0">&#125;</span>

<span class="kw1">void</span> Page_Loaded<span class="br0">&#40;</span><span class="kw4">object</span> sender, RoutedEventArgs e<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="co1">// Add any UIElement to the moving panel and add the moving panel to the layout</span>
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">LayoutRoot</span>.<span class="me1">Children</span>.<span class="me1">Add</span><span class="br0">&#40;</span>movable_panel<span class="br0">&#41;</span>;
&nbsp; &nbsp; movable_panel.<span class="me1">Items</span>.<span class="me1">Add</span><span class="br0">&#40;</span>animation_to_move<span class="br0">&#41;</span>;

&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">one_animation_completed_event</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> EventHandler<span class="br0">&#40;</span><span class="kw4">delegate</span> <span class="br0">&#123;</span> LookForSegmentToAnimate<span class="br0">&#40;</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">all_animations_completed_events</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> EventHandler<span class="br0">&#40;</span>OnAllAnimationsCompletedAlongPath<span class="br0">&#41;</span>;

&nbsp; &nbsp; <span class="co1">//Parse some path markup syntax and queue it up for animating</span>
&nbsp; &nbsp; QueuePathSegments<span class="br0">&#40;</span>path_markup<span class="br0">&#41;</span>;

&nbsp; &nbsp; <span class="co1">//Start the animating along the path defined above</span>
&nbsp; &nbsp; StartOneAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span>

<span class="kw1">void</span> OnAllAnimationsCompletedAlongPath<span class="br0">&#40;</span><span class="kw4">object</span> sender, EventArgs e<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="co1">// queue up the bezier segments again, and take out first data point &quot;M&quot; &nbsp; &nbsp; &nbsp; </span>
&nbsp; &nbsp; QueuePathSegments<span class="br0">&#40;</span>path_markup<span class="br0">&#41;</span>;
&nbsp; &nbsp; path_segments.<span class="me1">Dequeue</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; StartOneAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="color:DarkGreen">Parsing Path Markup</span></p>
<pre style="height:850px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">void</span> QueuePathSegments<span class="br0">&#40;</span><span class="kw4">string</span> path_markup<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="co1">// only parsing for cubic bezier segments for now...</span>
&nbsp; &nbsp; <span class="kw4">string</span> get_control_points_expression = <span class="st0">@"\s*(-?\d*(\.\d*)?\s*,\s*-?\d*(\.\d*)?\s*)&quot;</span>;
&nbsp; &nbsp; <span class="kw4">string</span> get_curve_commands_expression = <span class="kw4">string</span>.<span class="me1">Format</span><span class="br0">&#40;</span><span class="st0">@"([MmCc]{0}{{1,3}})&quot;</span>, get_control_points_expression<span class="br0">&#41;</span>;

&nbsp; &nbsp; var curve_commands_matches = from Match curve_commands <span class="kw1">in</span> Regex.<span class="me1">Matches</span><span class="br0">&#40;</span>path_markup, get_curve_commands_expression<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;select curve_commands;

&nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span>Match curve_command <span class="kw1">in</span> curve_commands_matches<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; var points =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; from control_point <span class="kw1">in</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>from Match control_points <span class="kw1">in</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Regex.<span class="me1">Matches</span><span class="br0">&#40;</span>curve_command.<span class="me1">Value</span>, get_control_points_expression<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;select control_points<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; select control_point.<span class="me1">Value</span>.<span class="me1">Replace</span><span class="br0">&#40;</span><span class="st0">&quot; &quot;</span>, <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Start Point &quot;M&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>curve_command.<span class="me1">Value</span>.<span class="me1">StartsWith</span><span class="br0">&#40;</span><span class="st0">&quot;m&quot;</span>, StringComparison.<span class="me1">InvariantCultureIgnoreCase</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span><span class="br0">&#91;</span><span class="br0">&#93;</span> coordinates = points.<span class="me1">FirstOrDefault</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">Split</span><span class="br0">&#40;</span><span class="st0">','</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BezierSegment bezier_segment = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> BezierSegment<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bezier_segment.<span class="me1">Point3</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> X = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, Y = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; path_segments.<span class="me1">Enqueue</span><span class="br0">&#40;</span>bezier_segment<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Cubic Bezier Point &quot;C&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>curve_command.<span class="me1">Value</span>.<span class="me1">StartsWith</span><span class="br0">&#40;</span><span class="st0">&quot;c&quot;</span>, StringComparison.<span class="me1">InvariantCultureIgnoreCase</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> point_counter = <span class="nu0">0</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BezierSegment bezier_segment = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> BezierSegment<span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; points.<span class="me1">ToList</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="kw1">ForEach</span><span class="br0">&#40;</span>p =&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span><span class="br0">&#91;</span><span class="br0">&#93;</span> coordinates = p.<span class="me1">Split</span><span class="br0">&#40;</span><span class="st0">','</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">switch</span> <span class="br0">&#40;</span>point_counter<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="nu0">0</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bezier_segment.<span class="me1">Point1</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> X = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, Y = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="nu0">1</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bezier_segment.<span class="me1">Point2</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> X = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, Y = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">case</span> <span class="nu0">2</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bezier_segment.<span class="me1">Point3</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> X = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, Y = <span class="kw4">Double</span>.<span class="me1">Parse</span><span class="br0">&#40;</span>coordinates<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.<span class="me1">Trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; point_counter++;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; path_segments.<span class="me1">Enqueue</span><span class="br0">&#40;</span>bezier_segment<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>

<span class="kw1">void</span> CalculateNextBezierSegmentPoint<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; posx = Math.<span class="me1">Pow</span><span class="br0">&#40;</span>counter, <span class="nu0">3</span><span class="br0">&#41;</span> * <span class="br0">&#40;</span>anchor2.<span class="me1">X</span> + <span class="nu0">3</span> * <span class="br0">&#40;</span>control1.<span class="me1">X</span> - control2.<span class="me1">X</span><span class="br0">&#41;</span> - anchor1.<span class="me1">X</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp;+ <span class="nu0">3</span> * Math.<span class="me1">Pow</span><span class="br0">&#40;</span>counter, <span class="nu0">2</span><span class="br0">&#41;</span> * <span class="br0">&#40;</span>anchor1.<span class="me1">X</span> - <span class="nu0">2</span> * control1.<span class="me1">X</span> + control2.<span class="me1">X</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp;+ <span class="nu0">3</span> * counter * <span class="br0">&#40;</span>control1.<span class="me1">X</span> - anchor1.<span class="me1">X</span><span class="br0">&#41;</span> + anchor1.<span class="me1">X</span>;

&nbsp; &nbsp; posy = Math.<span class="me1">Pow</span><span class="br0">&#40;</span>counter, <span class="nu0">3</span><span class="br0">&#41;</span> * <span class="br0">&#40;</span>anchor2.<span class="me1">Y</span> + <span class="nu0">3</span> * <span class="br0">&#40;</span>control1.<span class="me1">Y</span> - control2.<span class="me1">Y</span><span class="br0">&#41;</span> - anchor1.<span class="me1">Y</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; + <span class="nu0">3</span> * Math.<span class="me1">Pow</span><span class="br0">&#40;</span>counter, <span class="nu0">2</span><span class="br0">&#41;</span> * <span class="br0">&#40;</span>anchor1.<span class="me1">Y</span> - <span class="nu0">2</span> * control1.<span class="me1">Y</span> + control2.<span class="me1">Y</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; + <span class="nu0">3</span> * counter * <span class="br0">&#40;</span>control1.<span class="me1">Y</span> - anchor1.<span class="me1">Y</span><span class="br0">&#41;</span> + anchor1.<span class="me1">Y</span>;
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="color:DarkGreen">Animation</span></p>
<pre style="height:650px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="co2">#region &quot;Animation Block&quot;</span>

Action&lt;Storyboard, UIElement, Point, int&gt; BuildTranslateTransformStoryboard = <span class="br0">&#40;</span>storyboard, item, offset, step_size<span class="br0">&#41;</span> =&gt;
<span class="br0">&#123;</span>
&nbsp; &nbsp; var translationAnimationX = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> DoubleAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> SpeedRatio = <span class="nu0">0.8</span>, Duration = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Duration<span class="br0">&#40;</span>TimeSpan.<span class="me1">FromSeconds</span><span class="br0">&#40;</span><span class="nu0">1.0</span> / step_size<span class="br0">&#41;</span><span class="br0">&#41;</span>, To = offset.<span class="me1">X</span>, AutoReverse = <span class="kw1">false</span> <span class="br0">&#125;</span>;
&nbsp; &nbsp; storyboard.<span class="me1">Children</span>.<span class="me1">Add</span><span class="br0">&#40;</span>translationAnimationX<span class="br0">&#41;</span>;
&nbsp; &nbsp; Storyboard.<span class="me1">SetTargetProperty</span><span class="br0">&#40;</span>translationAnimationX, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> PropertyPath<span class="br0">&#40;</span><span class="st0">&quot;(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; Storyboard.<span class="me1">SetTarget</span><span class="br0">&#40;</span>storyboard, item<span class="br0">&#41;</span>;

&nbsp; &nbsp; var translationAnimationY = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> DoubleAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> SpeedRatio = <span class="nu0">0.8</span>, Duration = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Duration<span class="br0">&#40;</span>TimeSpan.<span class="me1">FromSeconds</span><span class="br0">&#40;</span><span class="nu0">1.0</span> / step_size<span class="br0">&#41;</span><span class="br0">&#41;</span>, To = offset.<span class="me1">Y</span>, AutoReverse = <span class="kw1">false</span> <span class="br0">&#125;</span>;
&nbsp; &nbsp; storyboard.<span class="me1">Children</span>.<span class="me1">Add</span><span class="br0">&#40;</span>translationAnimationY<span class="br0">&#41;</span>;
&nbsp; &nbsp; Storyboard.<span class="me1">SetTargetProperty</span><span class="br0">&#40;</span>translationAnimationY, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> PropertyPath<span class="br0">&#40;</span><span class="st0">&quot;(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; Storyboard.<span class="me1">SetTarget</span><span class="br0">&#40;</span>storyboard, item<span class="br0">&#41;</span>;
<span class="br0">&#125;</span>;

<span class="kw1">void</span> Animate<span class="br0">&#40;</span>Action calculate_path_segment_point<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; calculate_path_segment_point<span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; movable_panel.<span class="me1">TranslateToPoint</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span>posx, posy<span class="br0">&#41;</span>;
&nbsp; &nbsp; storyboard = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Storyboard<span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; storyboard.<span class="me1">Completed</span> += <span class="kw4">delegate</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; storyboard.<span class="me1">Stop</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; storyboard.<span class="me1">Children</span>.<span class="me1">Clear</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; counter += <span class="br0">&#40;</span><span class="nu0">1.0</span> / step_size<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>counter &gt; <span class="nu0">1</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// the last point of an animation becomes the first point of the next animation</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; anchor1 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span>posx, posy<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// need to reset counter for next animation block</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; counter = <span class="nu0">0</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// signal archor2 point has been reached and animation is done</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>one_animation_completed_event != <span class="kw1">null</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; one_animation_completed_event<span class="br0">&#40;</span><span class="kw1">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> EventArgs<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Animate<span class="br0">&#40;</span>calculate_path_segment_point<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>;

&nbsp; &nbsp; BuildTranslateTransformStoryboard<span class="br0">&#40;</span>storyboard, movable_panel, movable_panel.<span class="me1">OffsetPoint</span>, step_size<span class="br0">&#41;</span>;
&nbsp; &nbsp; storyboard.<span class="me1">Begin</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span>

<span class="co2">#endregion</span></div>
</div>
</pre>
<p><span style="color:DarkGreen">Processing the Queue</span></p>
<pre style="height:610px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="co2">#region &quot;Queue animation block&quot;</span>

<span class="kw1">void</span> LookForSegmentToAnimate<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>path_segments.<span class="me1">Count</span> &gt; <span class="nu0">0</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// start one animation</span>
&nbsp; &nbsp; &nbsp; &nbsp; StartOneAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">else</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// signal all animations are done</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>all_animations_completed_events != <span class="kw1">null</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; all_animations_completed_events<span class="br0">&#40;</span><span class="kw1">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> EventArgs<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>

<span class="kw1">void</span> StartOneAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="co1">// dequeue and set global control points variables</span>
&nbsp; &nbsp; PathSegment path_segment = path_segments.<span class="me1">Dequeue</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>path_segment <a href="http://www.google.com/search?q=is+msdn.microsoft.com"><span class="kw3">is</span></a> BezierSegment<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; var bezier_segemnt = path_segment <span class="kw1">as</span> BezierSegment;
&nbsp; &nbsp; &nbsp; &nbsp; control1 = bezier_segemnt.<span class="me1">Point1</span>;
&nbsp; &nbsp; &nbsp; &nbsp; control2 = bezier_segemnt.<span class="me1">Point2</span>;
&nbsp; &nbsp; &nbsp; &nbsp; anchor2 = bezier_segemnt.<span class="me1">Point3</span>;

&nbsp; &nbsp; &nbsp; &nbsp; Action calculate_path_segment_point = CalculateNextBezierSegmentPoint;
&nbsp; &nbsp; &nbsp; &nbsp; Animate<span class="br0">&#40;</span>calculate_path_segment_point<span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<span class="br0">&#125;</span>
<span class="co2">#endregion</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="font-weight:bolder;">SpinAnimation.xaml</span></p>
<pre style="height:700px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="sc3"><span class="re1">&lt;UserControl</span> <span class="re0">x:Class</span>=<span class="st0">&quot;PathAnimation.SpinAnimation&quot;</span>
&nbsp; &nbsp; <span class="re0">xmlns</span>=<span class="st0">&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span> 
&nbsp; &nbsp; <span class="re0">xmlns:x</span>=<span class="st0">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span> <span class="re0">x:Name</span>=<span class="st0">&quot;LayoutRoot&quot;</span> <span class="re0">Background</span>=<span class="st0">&quot;Transparent&quot;</span> <span class="re0">Height</span>=<span class="st0">&quot;100&quot;</span> <span class="re0">Width</span>=<span class="st0">&quot;100&quot;</span> <span class="re0">HorizontalAlignment</span>=<span class="st0">&quot;Left&quot;</span> <span class="re0">VerticalAlignment</span>=<span class="st0">&quot;Top&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span>.ColumnDefinitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ColumnDefinition</span> <span class="re0">Width</span>=<span class="st0">&quot;5&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ColumnDefinition</span> <span class="re0">Width</span>=<span class="st0">&quot;90&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ColumnDefinition</span> <span class="re0">Width</span>=<span class="st0">&quot;5&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid</span>.ColumnDefinitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span>.RowDefinitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;RowDefinition</span> <span class="re0">Height</span>=<span class="st0">&quot;5&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;RowDefinition</span> <span class="re0">Height</span>=<span class="st0">&quot;90&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;RowDefinition</span> <span class="re0">Height</span>=<span class="st0">&quot;5&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid</span>.RowDefinitions<span class="re2">&gt;</span></span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span> Grid.<span class="re0">Column</span>=<span class="st0">&quot;1&quot;</span> Grid.<span class="re0">Row</span>=<span class="st0">&quot;1&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Ellipse</span> <span class="re0">Height</span>=<span class="st0">&quot;50&quot;</span> <span class="re0">Width</span>=<span class="st0">&quot;50&quot;</span> <span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Ellipse</span>.Fill<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;RadialGradientBrush</span> <span class="re0">GradientOrigin</span>=<span class="st0">&quot;0.75,0.75&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;GradientStop</span> <span class="re0">Offset</span>=<span class="st0">&quot;0.25&quot;</span> <span class="re0">Color</span>=<span class="st0">&quot;White&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;GradientStop</span> <span class="re0">x:Name</span>=<span class="st0">&quot;FinalOffset&quot;</span> <span class="re0">Offset</span>=<span class="st0">&quot;1.0&quot;</span> <span class="re0">Color</span>=<span class="st0">&quot;DarkGoldenrod&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/RadialGradientBrush<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Ellipse</span>.Fill<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Ellipse<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Path</span> <span class="re0">x:Name</span>=<span class="st0">&quot;pathMarkup&quot;</span> <span class="re0">StrokeDashArray</span>=<span class="st0">&quot;53,0.75&quot;</span> <span class="re0">StrokeDashOffset</span>=<span class="st0">&quot;0&quot;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">StrokeEndLineCap</span>=<span class="st0">&quot;Flat&quot;</span> <span class="re0">StrokeStartLineCap</span>=<span class="st0">&quot;Flat&quot;</span> <span class="re0">StrokeThickness</span>=<span class="st0">&quot;5&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">HorizontalAlignment</span>=<span class="st0">&quot;Center&quot;</span> <span class="re0">VerticalAlignment</span>=<span class="st0">&quot;Center&quot;</span> &nbsp;<span class="re0">Stretch</span>=<span class="st0">&quot;UniformToFill&quot;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">Data</span>=<span class="st0">&quot;M 0,80 A 40,40 0 0 0 80,0 A 40,40 0 0 0 0,80&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Path</span>.Stroke<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;LinearGradientBrush</span> <span class="re0">StartPoint</span>=<span class="st0">&quot;0.5,0&quot;</span> <span class="re0">EndPoint</span>=<span class="st0">&quot;0.5,1&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;GradientStop</span> <span class="re0">Color</span>=<span class="st0">&quot;DarkGoldenrod&quot;</span> <span class="re0">Offset</span>=<span class="st0">&quot;0&quot;</span> <span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;GradientStop</span> <span class="re0">Color</span>=<span class="st0">&quot;White&quot;</span> <span class="re0">Offset</span>=<span class="st0">&quot;1&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/LinearGradientBrush<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Path</span>.Stroke<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Path</span>.RenderTransform<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;MatrixTransform<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;MatrixTransform</span>.Matrix<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Matrix</span> M11=<span class="st0">&quot;1&quot;</span> M12=<span class="st0">&quot;0.5&quot;</span> M21=<span class="st0">&quot;0&quot;</span> M22=<span class="st0">&quot;0.5&quot;</span> <span class="re0">OffsetX</span>=<span class="st0">&quot;0&quot;</span> <span class="re0">OffsetY</span>=<span class="st0">&quot;0&quot;</span><span class="re2">/&gt;</span></span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/MatrixTransform</span>.Matrix<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/MatrixTransform<span class="re2">&gt;</span></span></span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Path</span>.RenderTransform<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Path<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;TextBlock</span> <span class="re0">Text</span>=<span class="st0">&quot;Loading&quot;</span> <span class="re0">HorizontalAlignment</span>=<span class="st0">&quot;Center&quot;</span> <span class="re0">VerticalAlignment</span>=<span class="st0">&quot;Center&quot;</span> <span class="re0">Foreground</span>=<span class="st0">&quot;Bisque&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid<span class="re2">&gt;</span></span></span>
<span class="sc3"><span class="re1">&lt;/UserControl<span class="re2">&gt;</span></span></span></div>
</div>
</pre>
<p><span style="font-weight:bolder;">Page.xaml</span></p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="sc3"><span class="re1">&lt;UserControl</span> <span class="re0">x:Class</span>=<span class="st0">&quot;PathAnimation.Page&quot;</span>
&nbsp; &nbsp; &nbsp;<span class="re0">xmlns</span>=<span class="st0">&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span> 
&nbsp; &nbsp; <span class="re0">xmlns:x</span>=<span class="st0">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span> 
&nbsp; &nbsp; <span class="re0">xmlns:local</span>=<span class="st0">&quot;clr-namespace:PathAnimation;assembly=PathAnimation&quot;</span>
&nbsp; &nbsp; <span class="re0">Width</span>=<span class="st0">&quot;1000&quot;</span> <span class="re0">Height</span>=<span class="st0">&quot;600&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span> <span class="re0">x:Name</span>=<span class="st0">&quot;LayoutRoot&quot;</span> <span class="re0">Background</span>=<span class="st0">&quot;Black&quot;</span> <span class="re0">HorizontalAlignment</span>=<span class="st0">&quot;Center&quot;</span> <span class="re0">VerticalAlignment</span>=<span class="st0">&quot;Center&quot;</span> <span class="re0">Width</span>=<span class="st0">&quot;900&quot;</span> <span class="re0">Height</span>=<span class="st0">&quot;500&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Path</span> <span class="re0">Stretch</span>=<span class="st0">&quot;None&quot;</span> &nbsp;<span class="re0">StrokeDashOffset</span>=<span class="st0">&quot;2000&quot;</span> <span class="re0">StrokeEndLineCap</span>=<span class="st0">&quot;Triangle&quot;</span> <span class="re0">StrokeStartLineCap</span>=<span class="st0">&quot;Round&quot;</span> <span class="re0">StrokeThickness</span>=<span class="st0">&quot;5&quot;</span> <span class="re0">HorizontalAlignment</span>=<span class="st0">&quot;Left&quot;</span> <span class="re0">Margin</span>=<span class="st0">&quot;10,20,0,0&quot;</span> <span class="re0">x:Name</span>=<span class="st0">&quot;path&quot;</span> <span class="re0">VerticalAlignment</span>=<span class="st0">&quot;Top&quot;</span> &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">Data</span>=<span class="st0">&quot;M 85,135 C 80,0 235,0 285,135 C 345,350 750,450 545,175 C365,0 705,0 715,125 C735,250 570,250 515,135 C 425,0 125,0 285,160 C 500,400 110,450 85,135&quot;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">Visibility</span>=<span class="st0">&quot;Visible&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Path</span>.Stroke<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;LinearGradientBrush</span> <span class="re0">StartPoint</span>=<span class="st0">&quot;0.5,0&quot;</span> <span class="re0">EndPoint</span>=<span class="st0">&quot;0.5,1&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;GradientStop</span> <span class="re0">Color</span>=<span class="st0">&quot;DarkGoldenrod&quot;</span> <span class="re0">Offset</span>=<span class="st0">&quot;0&quot;</span> <span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;GradientStop</span> <span class="re0">Color</span>=<span class="st0">&quot;White&quot;</span> <span class="re0">Offset</span>=<span class="st0">&quot;1&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/LinearGradientBrush<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Path</span>.Stroke<span class="re2">&gt;</span></span> &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Path<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid<span class="re2">&gt;</span></span></span> &nbsp; &nbsp;
<span class="sc3"><span class="re1">&lt;/UserControl<span class="re2">&gt;</span></span></span></div>
</div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://eztier.com/dba2day/?feed=rss2&amp;p=181</wfw:commentRss>
		</item>
		<item>
		<title>Custom Sortables and Hit Test with Silverlight 2</title>
		<link>http://eztier.com/dba2day/?p=133</link>
		<comments>http://eztier.com/dba2day/?p=133#comments</comments>
		<pubDate>Tue, 31 Mar 2009 00:08:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Silverlight 2 (5)]]></category>

		<guid isPermaLink="false">http://eztier.com/dba2day/?p=133</guid>
		<description><![CDATA[One common technique for implementing sortables in Silverlight 2 is to create a placeholder for the dragging element and exchange the positioning of the targeted dropped area where an existing element resides by using the &#8220;RemoveAt&#8221; and &#8220;Add&#8221; methods of an UIElementCollection object (i.e., the Children property of a StackPanel).  I really like the [...]]]></description>
			<content:encoded><![CDATA[<p>One common technique for implementing sortables in Silverlight 2 is to create a placeholder for the dragging element and exchange the positioning of the targeted dropped area where an existing element resides by using the &#8220;RemoveAt&#8221; and &#8220;Add&#8221; methods of an UIElementCollection object (i.e., the Children property of a StackPanel).  I really like the simplicity, but not the visual presentation because the effect happens literally in a split second.  </p>
<p>Here&#8217;s my interpretation of a sortable list implementation, that is more visually appealing and suitable for a menu component.</p>
<p><a href="http://eztier.com/dba2day/wp-content/uploads/2009/03/customhittest.jpg"><img src="http://eztier.com/dba2day/wp-content/uploads/2009/03/customhittest.jpg" alt="" title="Custom Sortables and Hit Test" width="272" height="290" class="alignnone size-full wp-image-134" /></a></p>
<p><span id="more-133"></span><br />
You can check out the online demo <a target="_blank" href="http://eztier.com/samples/sl2/customhittest/customhittest.html">here</a>.</p>
<p>The implementation basically involves switching the positions of 2 sortable objects.  The process of switching positions will be accomplished by creating a Translate animation for each object.  Finally, I need a way to check whether the overlapping objects should change positions.  For example, if the dragging element has just a hair on an hovered object, that does not qualify as an exchange.  So, I&#8217;ll have to calculate when a dragging object has more than 50% of its area on top of the hovered object and invoke the animation when it happens. </p>
<p>Let&#8217;s define a layout boundary where a dragging element is free to roam.  If a page is 900 x 600, the dragging element may only be limited to roam in a 225 x 250 area of that space.  I&#8217;ll call this the &#8220;DroppableRoot&#8221; and it&#8217;ll derive ItemsControl.  Within the 225 x 250 Control, I need to present to the user some visual that &#8220;groups&#8221; a bunch of sortables.  This could be another ItemsControl that is 165 x 200 and differs in background color.  And I&#8217;ll call this the &#8220;DroppablePanel&#8221;.  The XAML looks like this.</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="sc3"><span class="re1">&lt;UserControl</span> <span class="re0">x:Class</span>=<span class="st0">&quot;CustomHitTest.Page&quot;</span>
&nbsp; &nbsp; <span class="re0">xmlns</span>=<span class="st0">&quot;http://schemas.microsoft.com/client/2007&quot;</span> 
&nbsp; &nbsp; <span class="re0">xmlns:x</span>=<span class="st0">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span> 
&nbsp; &nbsp; <span class="re0">xmlns:local</span>=<span class="st0">&quot;clr-namespace:CustomHitTest;assembly=CustomHitTest&quot;</span>
&nbsp; &nbsp; <span class="re0">Width</span>=<span class="st0">&quot;900&quot;</span> <span class="re0">Height</span>=<span class="st0">&quot;600&quot;</span><span class="re2">&gt;</span></span>

&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span> <span class="re0">Background</span>=<span class="st0">&quot;White&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;local:DroppableRoot</span> <span class="re0">x:Name</span>=<span class="st0">&quot;DroppableRoot&quot;</span> <span class="re0">Width</span>=<span class="st0">&quot;225&quot;</span> <span class="re0">Height</span>=<span class="st0">&quot;250&quot;</span> <span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span> <span class="re0">Margin</span>=<span class="st0">&quot;0&quot;</span> <span class="re0">HorizontalAlignment</span>=<span class="st0">&quot;Center&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span>.ColumnDefinitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ColumnDefinition</span> <span class="re0">Width</span>=<span class="st0">&quot;192&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid</span>.ColumnDefinitions<span class="re2">&gt;</span></span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span>.RowDefinitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;RowDefinition</span> <span class="re0">Height</span>=<span class="st0">&quot;Auto&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;RowDefinition</span> <span class="re0">Height</span>=<span class="st0">&quot;230&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid</span>.RowDefinitions<span class="re2">&gt;</span></span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;TextBlock</span> <span class="re0">Text</span>=<span class="st0">&quot;Try Reordering the Sortables&quot;</span> &nbsp;<span class="re0">FontSize</span>=<span class="st0">&quot;9&quot;</span> <span class="re0">Foreground</span>=<span class="st0">&quot;DarkSeaGreen&quot;</span> Grid.<span class="re0">Column</span>=<span class="st0">&quot;0&quot;</span> Grid.<span class="re0">Row</span>=<span class="st0">&quot;0&quot;</span> <span class="re0">HorizontalAlignment</span>=<span class="st0">&quot;Center&quot;</span> <span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;local:DroppablePanel</span> <span class="re0">Width</span>=<span class="st0">&quot;165&quot;</span> <span class="re0">Height</span>=<span class="st0">&quot;200&quot;</span> Grid.<span class="re0">Column</span>=<span class="st0">&quot;0&quot;</span> Grid.<span class="re0">Row</span>=<span class="st0">&quot;1&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/local:DroppablePanel<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/local:DroppableRoot<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid<span class="re2">&gt;</span></span></span>
<span class="sc3"><span class="re1">&lt;/UserControl<span class="re2">&gt;</span></span></span></div>
</div>
</pre>
<p>The sortables will derive ContentControl and will require a TranslateTransform object for animating movements.  The sortables in this project will be called &#8220;DroppableObject&#8221;.  </p>
<pre style="height:300px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">public</span> <span class="kw4">class</span> DroppableObject : ContentControl
<span class="br0">&#123;</span>
&nbsp; &nbsp; TransformGroup transformGroup;
&nbsp; &nbsp; TranslateTransform translateTransform;

&nbsp; &nbsp; <span class="kw1">public</span> DroppableObject<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">RenderTransform</span> <a href="http://www.google.com/search?q=is+msdn.microsoft.com"><span class="kw3">is</span></a> TransformGroup<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transformGroup = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> TransformGroup<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; translateTransform = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> TranslateTransform<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transformGroup.<span class="me1">Children</span>.<span class="me1">Add</span><span class="br0">&#40;</span>translateTransform<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">RenderTransform</span> = transformGroup;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>Next, I&#8217;ll need to make the DroppableObject capable of being dragged and dropped.  There are basically 2 ways of implementing dragging and dropping.  One is to use absolute positioning using the Canvas.Top and Canvas.Left properties, or in the case of this project, relative positioning using TranslateTransform.</p>
<p>The following properties are added to the DroppableObject and are pretty standard whether your implementation go the absolute or relative positioning path.  (There are plenty of articles written on dragging/dropping and I won&#8217;t review the topic here.  However, the complete code at the end of the article will include the relative-positioning drag/drop implementation for this project.)  </p>
<p>The lone property that stands out is the &#8220;OffsetPoint&#8221; property. </p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="co1">//signals that mouse events are being captured</span>
<span class="kw1">public</span> <span class="kw4">bool</span> IsDragging <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
<span class="co1">// indicates whether StartPosition has been established</span>
<span class="kw1">public</span> <span class="kw4">bool</span> Initialized <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span> 
<span class="co1">// where the object has been translated to</span>
<span class="kw1">public</span> Point CurrentPosition <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span> &nbsp;
<span class="co1">// when mouse is moving, this is stored and compared against run-time mouse position to create an offset for the transform property of the dragging object</span>
<span class="kw1">public</span> Point LastMousePosition <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
<span class="co1">// sets the initial position of object &nbsp; &nbsp; &nbsp; &nbsp; </span>
<span class="kw1">public</span> Point StartPosition <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
<span class="co1">// this property is updated by the dependency property TranslateToPoint; translate animation will use this value</span>
<span class="kw1">public</span> Point OffsetPoint <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span></div>
</div>
</pre>
<p>The OffsetPoint property will tell the Translate animation how far to go from the original starting position.  Inituition would suggest that we should just capture the last location of an object and calculate the offset distance to the new location if we wanted to move an object from one point to another.  Unfortunately, that plan will fail miserably.  Actually, the calculation should be done against the very first location when the UIElement is loaded and updated in the Visual Tree because TranslateTransform object will always work against this fixed position during lifetime of the UIElement.  </p>
<p>For example, if an UIElement&#8217;s location when first loaded in the Visual Tree was (10,10) and we then used a Translate animation to move it to (0,0), the TranslateTransform X and Y properties would be (-10,-10).  Great, that makes sense.  Now from (0,0), we will move the UIElement to (20,20), the TranslateTransform X and Y pair should just be (10,10) and NOT (20,20).</p>
<p>I decided to encapsulate the above logic as a Dependency Property of the DroppableObject.  Notice that the callback uses the StartPosition property of the DroppableObject for calculating the OffsetPoint property.</p>
<pre style="height:300px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">public</span> <span class="kw1">static</span> <span class="kw1">readonly</span> DependencyProperty TranslateToPointProperty = DependencyProperty.<span class="me1">Register</span><span class="br0">&#40;</span><span class="st0">&quot;TranslateToPoint&quot;</span>, <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span class="kw3">typeof</span></a><span class="br0">&#40;</span>Point<span class="br0">&#41;</span>, <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span class="kw3">typeof</span></a><span class="br0">&#40;</span>UIElement<span class="br0">&#41;</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> PropertyMetadata<span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> PropertyChangedCallback<span class="br0">&#40;</span>OnTranslateToPointPropertyChanged<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;

<span class="kw1">public</span> Point TranslateToPoint
<span class="br0">&#123;</span>
&nbsp; &nbsp; get <span class="br0">&#123;</span> <span class="kw1">return</span> <span class="br0">&#40;</span>Point<span class="br0">&#41;</span>GetValue<span class="br0">&#40;</span>TranslateToPointProperty<span class="br0">&#41;</span>; <span class="br0">&#125;</span>
&nbsp; &nbsp; set <span class="br0">&#123;</span> SetValue<span class="br0">&#40;</span>TranslateToPointProperty, value<span class="br0">&#41;</span>; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>

<span class="kw1">static</span> <span class="kw1">void</span> OnTranslateToPointPropertyChanged<span class="br0">&#40;</span>DependencyObject d, DependencyPropertyChangedEventArgs e<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>d <a href="http://www.google.com/search?q=is+msdn.microsoft.com"><span class="kw3">is</span></a> DroppableObject<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; var droppableObject = d <span class="kw1">as</span> DroppableObject;
&nbsp; &nbsp; &nbsp; &nbsp; var newPoint = <span class="br0">&#40;</span>Point<span class="br0">&#41;</span>e.<span class="me1">NewValue</span>;

&nbsp; &nbsp; &nbsp; &nbsp; var offsetX = newPoint.<span class="me1">X</span> - droppableObject.<span class="me1">StartPosition</span>.<span class="me1">X</span>;
&nbsp; &nbsp; &nbsp; &nbsp; var offsetY = newPoint.<span class="me1">Y</span> - droppableObject.<span class="me1">StartPosition</span>.<span class="me1">Y</span>;

&nbsp; &nbsp; &nbsp; &nbsp; droppableObject.<span class="me1">OffsetPoint</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span>offsetX, offsetY<span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>So when 2 DroppableObject&#8217;s decide to exchange places, the partial code looks like this.<br />
(Note that the CurrentPosition property is the current location of the DroppableObject in the Visual Tree.) </p>
<pre style="height:200px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">. . .
<span class="me1">droppableDragging</span>.<span class="me1">TranslateToPoint</span> = droppableOver.<span class="me1">CurrentPosition</span>;
storyboard1 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Storyboard<span class="br0">&#40;</span><span class="br0">&#41;</span>;
BuildTranslateTransformStoryboard<span class="br0">&#40;</span>storyboard1, droppableDragging, droppableDragging.<span class="me1">OffsetPoint</span><span class="br0">&#41;</span>;
. . .
<span class="me1">droppableOver</span>.<span class="me1">TranslateToPoint</span> = droppableDragging.<span class="me1">CurrentPosition</span>;
storyboard2 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Storyboard<span class="br0">&#40;</span><span class="br0">&#41;</span>;
BuildTranslateTransformStoryboard<span class="br0">&#40;</span>storyboard2, droppableOver, droppableOver.<span class="me1">OffsetPoint</span><span class="br0">&#41;</span>;
. . .</div>
</div>
</pre>
<p><span style="font-weight:bolder">Custom Hit Test</span><br />
Now that we&#8217;ve determined how the sortables will exchange positions within the Visual Tree, we need to implement the logic for when these animations will actually take place.  In a drag/drop implementation, we need to handle three types of mouse events: MouseMove, MouseLeftButtonUp, and MouseLeftButtonDown.  The MouseMove handler is where all the heavy lifting takes place.</p>
<pre style="height:100px">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">CurDroppableObject.<span class="me1">MouseMove</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MouseEventHandler<span class="br0">&#40;</span>DroppableObjectMouseEventHandler<span class="br0">&#41;</span>;
CurDroppableObject.<span class="me1">MouseLeftButtonUp</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MouseButtonEventHandler<span class="br0">&#40;</span>DroppableObjectMouseLeftButtonUp<span class="br0">&#41;</span>;
CurDroppableObject.<span class="me1">MouseLeftButtonDown</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MouseButtonEventHandler<span class="br0">&#40;</span>DroppableObjectMouseLeftButtonDown<span class="br0">&#41;</span>;</div>
</div>
</pre>
<p>As previously discussed,  I want to keep the dragging element within the boundaries of the DroppableRoot element because its only has relevance witin this scope.  To prevent the user from dragging an element beyond the DroppableRoot, I&#8217;m going to compare the top and left corner of the dragging element relative to the top and left corner of the DroppableRoot.  The difference of the 2 coordinates is my offset.  Comparing the Top-Left corner of the DroppableRoot and the Top-Left corner of an UIElement is the primary technique for the custom hit test for this project.</p>
<pre style="height:600px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">void</span> DroppableObjectMouseEventHandler<span class="br0">&#40;</span><span class="kw4">object</span> sender, MouseEventArgs e<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>sender == <span class="kw1">null</span><span class="br0">&#41;</span> <span class="kw1">return</span>;

&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!storyboard1Active<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; var item = sender <span class="kw1">as</span> DroppableObject;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>item.<span class="me1">IsDragging</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var transform = DroppableManager.<span class="me1">GetTransformation</span>&lt;TranslateTransform&gt;<span class="br0">&#40;</span>item<span class="br0">&#41;</span> <span class="kw1">as</span> TranslateTransform;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Point currentMousePosition = e.<span class="me1">GetPosition</span><span class="br0">&#40;</span>CurDroppableRoot<span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">double</span> deltaV = currentMousePosition.<span class="me1">Y</span> - item.<span class="me1">LastMousePosition</span>.<span class="me1">Y</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">double</span> deltaH = currentMousePosition.<span class="me1">X</span> - item.<span class="me1">LastMousePosition</span>.<span class="me1">X</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">double</span> newTop = deltaV + transform.<span class="me1">Y</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">double</span> newLeft = deltaH + transform.<span class="me1">X</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GeneralTransform gt = item.<span class="me1">TransformToVisual</span><span class="br0">&#40;</span>CurDroppableRoot<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Point offset = gt.<span class="me1">Transform</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>offset.<span class="me1">Y</span> &lt;= CurDroppableRoot.<span class="me1">ActualHeight</span> - item.<span class="me1">ActualHeight</span><span class="br0">&#41;</span> &amp;&amp; <span class="br0">&#40;</span>offset.<span class="me1">Y</span> &gt;= <span class="nu0">0</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>newLeft + item.<span class="me1">Width</span> &lt;= CurDroppableRoot.<span class="me1">ActualWidth</span><span class="br0">&#41;</span> &amp;&amp; <span class="br0">&#40;</span>newLeft &gt;= -<span class="br0">&#40;</span>offset.<span class="me1">X</span> + item.<span class="me1">ActualWidth</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// the DroppableObject is within the boundaries of the DroppableRoot</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transform.<span class="me1">X</span> = newLeft;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transform.<span class="me1">Y</span> = newTop;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// further processing</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; . . .
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>We also want to add the effect of transparency when an object is being hovered or left by the dragging element.  This cannot be done with MouseOver or MouseLeave of an element because the visual effect should be initialited by the dragging element and not the moving mouse pointer.  So if I were to drag an element by it&#8217;s tail and the mouse pointer was pinning the bottom-right hand corner of the element, I would still expect to see the transparency effect if the dragging element&#8217;s top-left corner was over another element.  </p>
<p>In order to calculate overlapping between 2 elements, I&#8217;ll also need the position of the element that&#8217;s being hovered relative to the DroppableRoot.  The code is very straightforward, if the top-left corner of the dragging element is anywhere within the area of the element, an overlap has occured.</p>
<p>If we don&#8217;t take the dragging element&#8217;s height and width into consideration when determining the offset, we would be able to drag the element beyond the DroppableRoot&#8217;s boundaries.</p>
<p>The Translate animations will be invoked by a custom event which we&#8217;ll call &#8220;Collision&#8221; and the arguments it&#8217;ll carry is the element being dragged and the element that is being hovered.</p>
<pre style="height:180px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">public</span> <span class="kw4">class</span> CollisonElements
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">public</span> UIElement Element <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">public</span> UIElement CollidedElement <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>

<span class="kw1">public</span> <span class="kw1">event</span> EventHandlerFor&lt;CollisonElements&gt; Collision;</div>
</div>
</pre>
<p>So, I&#8217;ll add the following checkpoints to the DroppableObjectMouseEventHandler method.  </p>
<pre style="height:620px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">if</span> <span class="br0">&#40;</span>Collision != <span class="kw1">null</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; UIElement elementCollided = <span class="kw1">null</span>;
&nbsp; &nbsp; DroppableObjectList.<span class="kw1">ForEach</span><span class="br0">&#40;</span>d =&gt;
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; var droppableOver = d <span class="kw1">as</span> DroppableObject;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!item.<span class="me1">Equals</span><span class="br0">&#40;</span>droppableOver<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GeneralTransform droppableOverTransform = droppableOver.<span class="me1">TransformToVisual</span><span class="br0">&#40;</span>CurDroppableRoot<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Point droppableOverCoordinates = droppableOverTransform.<span class="me1">Transform</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>offset.<span class="me1">Y</span> + <span class="br0">&#40;</span>item.<span class="me1">ActualHeight</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &gt;= droppableOverCoordinates.<span class="me1">Y</span> &amp;&amp; <span class="br0">&#40;</span>offset.<span class="me1">Y</span><span class="br0">&#41;</span> &lt;= droppableOverCoordinates.<span class="me1">Y</span> + droppableOver.<span class="me1">ActualHeight</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&amp;&amp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span><span class="br0">&#40;</span>offset.<span class="me1">X</span> + <span class="br0">&#40;</span>item.<span class="me1">ActualWidth</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &gt;= droppableOverCoordinates.<span class="me1">X</span> &amp;&amp; <span class="br0">&#40;</span>offset.<span class="me1">X</span><span class="br0">&#41;</span> &lt;= droppableOverCoordinates.<span class="me1">X</span> + droppableOver.<span class="me1">ActualWidth</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; droppableOver.<span class="me1">Opacity</span> = <span class="nu0">0.3</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; droppableOver.<span class="me1">Opacity</span> = <span class="nu0">1.0</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>offset.<span class="me1">Y</span> + <span class="br0">&#40;</span>item.<span class="me1">ActualHeight</span> / <span class="nu0">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &gt;= droppableOverCoordinates.<span class="me1">Y</span> &amp;&amp; <span class="br0">&#40;</span>offset.<span class="me1">Y</span> + <span class="br0">&#40;</span>item.<span class="me1">ActualHeight</span> / <span class="nu0">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &lt;= droppableOverCoordinates.<span class="me1">Y</span> + droppableOver.<span class="me1">ActualHeight</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&amp;&amp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span><span class="br0">&#40;</span>offset.<span class="me1">X</span> + <span class="br0">&#40;</span>item.<span class="me1">ActualWidth</span> / <span class="nu0">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &gt;= droppableOverCoordinates.<span class="me1">X</span> &amp;&amp; <span class="br0">&#40;</span>offset.<span class="me1">X</span> + <span class="br0">&#40;</span>item.<span class="me1">ActualWidth</span> / <span class="nu0">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &lt;= droppableOverCoordinates.<span class="me1">X</span> + droppableOver.<span class="me1">ActualWidth</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; elementCollided = droppableOver <span class="kw1">as</span> UIElement;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp;
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>elementCollided != <span class="kw1">null</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">Cursor</span> = Cursors.<span class="me1">Wait</span>;
&nbsp; &nbsp; &nbsp; &nbsp; CollisonElements collidedElements = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> CollisonElements<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> Element = item, CollidedElement = elementCollided <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; EventArgs&lt;CollisonElements&gt; args = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> EventArgs&lt;CollisonElements&gt;<span class="br0">&#40;</span>collidedElements<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; Collision<span class="br0">&#40;</span><span class="kw1">this</span>, args<span class="br0">&#41;</span>; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="font-weight:bolder">Enter the DroppableManager</span></p>
<p>Wow, there seems to be a lot of stuff going on.  There are differing camps on design patterns for Silverlight, but for this project I&#8217;ve decided to implement the &#8220;Model-View-Presenter&#8221; approach.  The presenter is called the DroppableManager and it is not an observer but actively engages in all that&#8217;s going on.</p>
<p>Recall back when we created the DroppableRoot element in XAML, the class will also instantiate an instance of the DroppableManager class and pass itself to the whim of this class.  The DroppableManager is responsible for grabbing the layout of the DroppableRoot and DroppablePanel, dynamically populating the DroppablePanel with DroppableObject&#8217;s, and monitoring the DroppableObject collection&#8217;s every move.</p>
<p>Finally, here&#8217;s the complete code.</p>
<p><span style="font-weight:bolder">DroppableManager.cs</span></p>
<pre style="height:850px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">public</span> <span class="kw4">class</span> DroppableManager 
<span class="br0">&#123;</span>
&nbsp; &nbsp; List&lt;DroppableDataContextItem&gt; droppableDataContextItemList;
&nbsp; &nbsp; List&lt;DroppableObject&gt; DroppableObjectList = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> List&lt;DroppableObject&gt;<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; List&lt;DroppableObject&gt; DroppedObjectList = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> List&lt;DroppableObject&gt;<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; 
&nbsp; &nbsp; DroppableObject CurDroppableObject; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; DroppablePanel CurDroppablePanel;

&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw1">static</span> DroppableRoot CurDroppableRoot;
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="kw1">const</span> <span class="kw4">String</span> DroppableObjectPrefix = <span class="st0">&quot;DroppableObject&quot;</span>;

&nbsp; &nbsp; <span class="kw4">bool</span> Initialized;
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="co1">// for animating droppableobjects</span>
&nbsp; &nbsp; <span class="kw4">bool</span> storyboard1Active = <span class="kw1">false</span>;
&nbsp; &nbsp; <span class="kw4">bool</span> storyboard2Active = <span class="kw1">false</span>; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; Storyboard storyboard1;
&nbsp; &nbsp; Storyboard storyboard2;

&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw1">event</span> EventHandlerFor&lt;CollisonElements&gt; Collision;

&nbsp; &nbsp; Action&lt;List&lt;DroppableDataContextItem&gt;&gt; SetDataContextList;
&nbsp; &nbsp; Func&lt;List&lt;DroppableDataContextItem&gt;, List&lt;DroppableObject&gt;&gt; CreateDroppableObjectFromDataContextList;
&nbsp; &nbsp; Action&lt;List&lt;DroppableObject&gt;&gt; SetDroppableActualPosition;

&nbsp; &nbsp; <span class="kw1">public</span> DroppableManager<span class="br0">&#40;</span>FrameworkElement elementToManage<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//Collided element delegate</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">Collision</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> EventHandlerFor&lt;CollisonElements&gt;<span class="br0">&#40;</span>DroppableManager_ElementsCollision<span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; CurDroppableRoot = elementToManage <span class="kw1">as</span> CustomHitTest.<span class="me1">DroppableRoot</span>;
&nbsp; &nbsp; &nbsp; &nbsp; CurDroppableRoot.<span class="me1">LayoutUpdated</span> += <span class="kw4">delegate</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>CurDroppableRoot.<span class="me1">IsInitialized</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//this is called here because TransformToVisual will not be valid until layout has been actually updated</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetDroppableActualPosition<span class="br0">&#40;</span>DroppableObjectList<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Generate the Visuals that can be dragged around</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetDataContextList = <span class="br0">&#40;</span>list<span class="br0">&#41;</span> =&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> List&lt;DroppableDataContextItem&gt;<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> DroppableDataContextItem<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> Name = <span class="st0">&quot;Customer&quot;</span> <span class="br0">&#125;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> DroppableDataContextItem<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> Name = <span class="st0">&quot;Category&quot;</span> <span class="br0">&#125;</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> DroppableDataContextItem<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> Name = <span class="st0">&quot;Year&quot;</span> <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RecurseCollection<span class="br0">&#40;</span>CurDroppableRoot.<span class="me1">Items</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CreateDroppableObjectFromDataContextList<span class="br0">&#40;</span>list<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CreateDroppableObjectFromDataContextList = <span class="br0">&#40;</span>list<span class="br0">&#41;</span> =&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list.<span class="kw1">ForEach</span><span class="br0">&#40;</span>a =&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CurDroppableObject = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> DroppableObject<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TextBlock tb = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> TextBlock<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tb.<span class="me1">Text</span> = a.<span class="me1">Name</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tb.<span class="me1">FontSize</span> = <span class="nu0">12.0</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CurDroppableObject.<span class="me1">Content</span> = tb;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CurDroppablePanel.<span class="me1">Items</span>.<span class="me1">Add</span><span class="br0">&#40;</span>CurDroppableObject<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CurDroppableObject.<span class="me1">MouseMove</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MouseEventHandler<span class="br0">&#40;</span>DroppableObjectMouseEventHandler<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CurDroppableObject.<span class="me1">MouseLeftButtonUp</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MouseButtonEventHandler<span class="br0">&#40;</span>DroppableObjectMouseLeftButtonUp<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CurDroppableObject.<span class="me1">MouseLeftButtonDown</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MouseButtonEventHandler<span class="br0">&#40;</span>DroppableObjectMouseLeftButtonDown<span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DroppableObjectList.<span class="me1">Add</span><span class="br0">&#40;</span>CurDroppableObject<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> DroppableObjectList;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetDroppableActualPosition = <span class="br0">&#40;</span>droppableObjectList<span class="br0">&#41;</span> =&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// We only need to get the positions of the droppable objects the first time</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!Initialized<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; droppableObjectList.<span class="kw1">ForEach</span><span class="br0">&#40;</span>d =&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>d <a href="http://www.google.com/search?q=is+msdn.microsoft.com"><span class="kw3">is</span></a> DroppableObject<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var item = d <span class="kw1">as</span> DroppableObject;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>item.<span class="me1">Initialized</span><span class="br0">&#41;</span> <span class="kw1">return</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GeneralTransform gt = item.<span class="me1">TransformToVisual</span><span class="br0">&#40;</span>CurDroppableRoot<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Point offset = gt.<span class="me1">Transform</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">StartPosition</span> = offset;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">Initialized</span> = <span class="kw1">true</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Initialized = <span class="kw1">true</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetDataContextList<span class="br0">&#40;</span>droppableDataContextItemList<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CurDroppableRoot.<span class="me1">IsInitialized</span> = <span class="kw1">true</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">void</span> RecurseCollection&lt;T&gt;<span class="br0">&#40;</span>IEnumerable&lt;T&gt; collection<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span>T item <span class="kw1">in</span> collection<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>item <a href="http://www.google.com/search?q=is+msdn.microsoft.com"><span class="kw3">is</span></a> DroppablePanel<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CurDroppablePanel = <span class="br0">&#40;</span>item <span class="kw1">as</span> DroppablePanel<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>item <a href="http://www.google.com/search?q=is+msdn.microsoft.com"><span class="kw3">is</span></a> Panel<span class="br0">&#41;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RecurseCollection<span class="br0">&#40;</span><span class="br0">&#40;</span>item <span class="kw1">as</span> Panel<span class="br0">&#41;</span>.<span class="me1">Children</span><span class="br0">&#41;</span>; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">public</span> DroppableManager<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span> &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//Collided element delegate</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">Collision</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> EventHandlerFor&lt;CollisonElements&gt;<span class="br0">&#40;</span>DroppableManager_ElementsCollision<span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; Action&lt;Storyboard, UIElement, Point&gt; BuildTranslateTransformStoryboard = <span class="br0">&#40;</span>storyboard, item, offset<span class="br0">&#41;</span> =&gt;
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; var translationAnimationX = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> DoubleAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> SpeedRatio = <span class="nu0">0.8</span>, Duration = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Duration<span class="br0">&#40;</span>TimeSpan.<span class="me1">FromSeconds</span><span class="br0">&#40;</span><span class="nu0">0.6</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, To = offset.<span class="me1">X</span> <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; storyboard.<span class="me1">Children</span>.<span class="me1">Add</span><span class="br0">&#40;</span>translationAnimationX<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; Storyboard.<span class="me1">SetTargetProperty</span><span class="br0">&#40;</span>translationAnimationX, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> PropertyPath<span class="br0">&#40;</span><span class="st0">&quot;(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; Storyboard.<span class="me1">SetTarget</span><span class="br0">&#40;</span>storyboard, item<span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; var translationAnimationY = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> DoubleAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> SpeedRatio = <span class="nu0">0.8</span>, Duration = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Duration<span class="br0">&#40;</span>TimeSpan.<span class="me1">FromSeconds</span><span class="br0">&#40;</span><span class="nu0">0.6</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, To = offset.<span class="me1">Y</span> <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; storyboard.<span class="me1">Children</span>.<span class="me1">Add</span><span class="br0">&#40;</span>translationAnimationY<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; Storyboard.<span class="me1">SetTargetProperty</span><span class="br0">&#40;</span>translationAnimationY, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> PropertyPath<span class="br0">&#40;</span><span class="st0">&quot;(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; Storyboard.<span class="me1">SetTarget</span><span class="br0">&#40;</span>storyboard, item<span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>;

&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw1">static</span> &nbsp;T GetTransformation&lt;T&gt;<span class="br0">&#40;</span>UIElement Element<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; T translate = <span class="kw1">default</span><span class="br0">&#40;</span>T<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; var renderTransform = Element.<span class="me1">RenderTransform</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>renderTransform <a href="http://www.google.com/search?q=is+msdn.microsoft.com"><span class="kw3">is</span></a> TransformGroup<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TransformGroup transformGroup = <span class="br0">&#40;</span>TransformGroup<span class="br0">&#41;</span>renderTransform;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span>var transform <span class="kw1">in</span> transformGroup.<span class="me1">Children</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>transform <a href="http://www.google.com/search?q=is+msdn.microsoft.com"><span class="kw3">is</span></a> T<span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; translate = <span class="br0">&#40;</span>T<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="kw4">object</span><span class="br0">&#41;</span>transform; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> translate;
&nbsp; &nbsp; <span class="br0">&#125;</span>


&nbsp; &nbsp; <span class="kw1">void</span> DroppableObjectMouseLeftButtonDown<span class="br0">&#40;</span><span class="kw4">object</span> sender, MouseButtonEventArgs e<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; var item = sender <span class="kw1">as</span> DroppableObject;

&nbsp; &nbsp; &nbsp; &nbsp; DroppableObjectList.<span class="kw1">ForEach</span><span class="br0">&#40;</span>d =&gt;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>d <a href="http://www.google.com/search?q=is+msdn.microsoft.com"><span class="kw3">is</span></a> DroppableObject<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var droppable = d <span class="kw1">as</span> DroppableObject;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GeneralTransform gt = droppable.<span class="me1">TransformToVisual</span><span class="br0">&#40;</span>CurDroppableRoot<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Point offset = gt.<span class="me1">Transform</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; droppable.<span class="me1">CurrentPosition</span> = offset; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!storyboard1Active<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">SetValue</span><span class="br0">&#40;</span>Canvas.<span class="me1">ZIndexProperty</span>, <span class="nu0">1000</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">lastMousePosition</span> = e.<span class="me1">GetPosition</span><span class="br0">&#40;</span>CurDroppableRoot<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">isDragging</span> = <span class="kw1">true</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">CaptureMouse</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">Cursor</span> = Cursors.<span class="me1">Hand</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; <span class="br0">&#125;</span> &nbsp;

&nbsp; &nbsp; <span class="kw1">void</span> DroppableObjectMouseEventHandler<span class="br0">&#40;</span><span class="kw4">object</span> sender, MouseEventArgs e<span class="br0">&#41;</span><span class="br0">&#123;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>sender == <span class="kw1">null</span><span class="br0">&#41;</span> <span class="kw1">return</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!storyboard1Active<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var item = sender <span class="kw1">as</span> DroppableObject;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>item.<span class="me1">isDragging</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var transform = DroppableManager.<span class="me1">GetTransformation</span>&lt;TranslateTransform&gt;<span class="br0">&#40;</span>item<span class="br0">&#41;</span> <span class="kw1">as</span> TranslateTransform;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Point currentMousePosition = e.<span class="me1">GetPosition</span><span class="br0">&#40;</span>CurDroppableRoot<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">double</span> deltaV = currentMousePosition.<span class="me1">Y</span> - item.<span class="me1">lastMousePosition</span>.<span class="me1">Y</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">double</span> deltaH = currentMousePosition.<span class="me1">X</span> - item.<span class="me1">lastMousePosition</span>.<span class="me1">X</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">double</span> newTop = deltaV + transform.<span class="me1">Y</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">double</span> newLeft = deltaH + transform.<span class="me1">X</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GeneralTransform gt = item.<span class="me1">TransformToVisual</span><span class="br0">&#40;</span>CurDroppableRoot<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Point offset = gt.<span class="me1">Transform</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>offset.<span class="me1">Y</span> &lt;= CurDroppableRoot.<span class="me1">ActualHeight</span> - item.<span class="me1">ActualHeight</span><span class="br0">&#41;</span> &amp;&amp; <span class="br0">&#40;</span>offset.<span class="me1">Y</span> &gt;= <span class="nu0">0</span><span class="br0">&#41;</span> &amp;&amp; <span class="br0">&#40;</span>newLeft + item.<span class="me1">Width</span> &lt;= CurDroppableRoot.<span class="me1">ActualWidth</span><span class="br0">&#41;</span> &amp;&amp; <span class="br0">&#40;</span>newLeft &gt;= -<span class="br0">&#40;</span>offset.<span class="me1">X</span> + item.<span class="me1">ActualWidth</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transform.<span class="me1">X</span> = newLeft;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transform.<span class="me1">Y</span> = newTop;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>Collision != <span class="kw1">null</span><span class="br0">&#41;</span><span class="br0">&#123;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UIElement elementCollided = <span class="kw1">null</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DroppableObjectList.<span class="kw1">ForEach</span><span class="br0">&#40;</span>d =&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var droppableOver = d <span class="kw1">as</span> DroppableObject;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!item.<span class="me1">Equals</span><span class="br0">&#40;</span>droppableOver<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GeneralTransform droppableOverTransform = droppableOver.<span class="me1">TransformToVisual</span><span class="br0">&#40;</span>CurDroppableRoot<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Point droppableOverCoordinates = droppableOverTransform.<span class="me1">Transform</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>offset.<span class="me1">Y</span> + <span class="br0">&#40;</span>item.<span class="me1">ActualHeight</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &gt;= droppableOverCoordinates.<span class="me1">Y</span> &amp;&amp; <span class="br0">&#40;</span>offset.<span class="me1">Y</span><span class="br0">&#41;</span> &lt;= droppableOverCoordinates.<span class="me1">Y</span> + droppableOver.<span class="me1">ActualHeight</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&amp;&amp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span><span class="br0">&#40;</span>offset.<span class="me1">X</span> + <span class="br0">&#40;</span>item.<span class="me1">ActualWidth</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &gt;= droppableOverCoordinates.<span class="me1">X</span> &amp;&amp; <span class="br0">&#40;</span>offset.<span class="me1">X</span><span class="br0">&#41;</span> &lt;= droppableOverCoordinates.<span class="me1">X</span> + droppableOver.<span class="me1">ActualWidth</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; droppableOver.<span class="me1">Opacity</span> = <span class="nu0">0.3</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; droppableOver.<span class="me1">Opacity</span> = <span class="nu0">1.0</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>offset.<span class="me1">Y</span> + <span class="br0">&#40;</span>item.<span class="me1">ActualHeight</span> / <span class="nu0">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &gt;= droppableOverCoordinates.<span class="me1">Y</span> &amp;&amp; <span class="br0">&#40;</span>offset.<span class="me1">Y</span> + <span class="br0">&#40;</span>item.<span class="me1">ActualHeight</span> / <span class="nu0">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &lt;= droppableOverCoordinates.<span class="me1">Y</span> + droppableOver.<span class="me1">ActualHeight</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&amp;&amp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span><span class="br0">&#40;</span>offset.<span class="me1">X</span> + <span class="br0">&#40;</span>item.<span class="me1">ActualWidth</span> / <span class="nu0">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &gt;= droppableOverCoordinates.<span class="me1">X</span> &amp;&amp; <span class="br0">&#40;</span>offset.<span class="me1">X</span> + <span class="br0">&#40;</span>item.<span class="me1">ActualWidth</span> / <span class="nu0">2</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &lt;= droppableOverCoordinates.<span class="me1">X</span> + droppableOver.<span class="me1">ActualWidth</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; elementCollided = droppableOver <span class="kw1">as</span> UIElement;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>elementCollided != <span class="kw1">null</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">Cursor</span> = Cursors.<span class="me1">Wait</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CollisonElements collidedElements = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> CollisonElements<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> Element = item, CollidedElement = elementCollided <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EventArgs&lt;CollisonElements&gt; args = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> EventArgs&lt;CollisonElements&gt;<span class="br0">&#40;</span>collidedElements<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Collision<span class="br0">&#40;</span><span class="kw1">this</span>, args<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Update position global variable</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">lastMousePosition</span> = currentMousePosition; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">Cursor</span> = Cursors.<span class="me1">Hand</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">void</span> DroppableManager_ElementsCollision<span class="br0">&#40;</span><span class="kw4">object</span> sender, EventArgs&lt;CollisonElements&gt; e<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// droppable hovered over by dragging object</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!storyboard2Active<span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var droppableOver = e.<span class="me1">Data</span>.<span class="me1">CollidedElement</span> <span class="kw1">as</span> DroppableObject;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var droppableDragging = e.<span class="me1">Data</span>.<span class="me1">Element</span> <span class="kw1">as</span> DroppableObject;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; droppableDragging.<span class="me1">isDragging</span> = <span class="kw1">false</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; droppableOver.<span class="me1">TranslateToPoint</span> = droppableDragging.<span class="me1">CurrentPosition</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard2 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Storyboard<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BuildTranslateTransformStoryboard<span class="br0">&#40;</span>storyboard2, droppableOver, droppableOver.<span class="me1">OffsetPoint</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard2.<span class="me1">Completed</span> += <span class="br0">&#40;</span>o, ev<span class="br0">&#41;</span> =&gt; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard2Active = <span class="kw1">false</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard2 = <span class="kw1">null</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard2.<span class="me1">Begin</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard2Active = <span class="kw1">true</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// droppable dragging</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!storyboard1Active<span class="br0">&#41;</span><span class="br0">&#123;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; droppableDragging.<span class="me1">TranslateToPoint</span> = droppableOver.<span class="me1">CurrentPosition</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard1 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Storyboard<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BuildTranslateTransformStoryboard<span class="br0">&#40;</span>storyboard1, droppableDragging, droppableDragging.<span class="me1">OffsetPoint</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard1.<span class="me1">Completed</span> += <span class="br0">&#40;</span>o, ev<span class="br0">&#41;</span> =&gt; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard1Active = <span class="kw1">false</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard1 = <span class="kw1">null</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DroppableObjectList.<span class="kw1">ForEach</span><span class="br0">&#40;</span>d =&gt;<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; d.<span class="me1">Opacity</span> = <span class="nu0">1.0</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; d.<span class="me1">Cursor</span> = <span class="kw1">null</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard1.<span class="me1">Begin</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard1Active = <span class="kw1">true</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">void</span> DroppableObjectMouseLeftButtonUp<span class="br0">&#40;</span><span class="kw4">object</span> sender, MouseButtonEventArgs e<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; var item = sender <span class="kw1">as</span> DroppableObject;

&nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">Opacity</span> = <span class="nu0">1.0</span>;

&nbsp; &nbsp; &nbsp; &nbsp; GeneralTransform gt = item.<span class="me1">TransformToVisual</span><span class="br0">&#40;</span>CurDroppableRoot<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; Point offset = gt.<span class="me1">Transform</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// compare with the object's current position:</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>item.<span class="me1">isDragging</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="br0">&#40;</span>item.<span class="me1">CurrentPosition</span>.<span class="me1">X</span> - offset.<span class="me1">X</span><span class="br0">&#41;</span> != <span class="nu0">0</span> || <span class="br0">&#40;</span>item.<span class="me1">CurrentPosition</span>.<span class="me1">Y</span> - offset.<span class="me1">Y</span><span class="br0">&#41;</span> != <span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!storyboard1Active<span class="br0">&#41;</span><span class="br0">&#123;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">TranslateToPoint</span> = item.<span class="me1">CurrentPosition</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard1 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Storyboard<span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BuildTranslateTransformStoryboard<span class="br0">&#40;</span>storyboard1, item, item.<span class="me1">OffsetPoint</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard1.<span class="me1">Completed</span> += <span class="br0">&#40;</span>o, ev<span class="br0">&#41;</span> =&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard1Active = <span class="kw1">false</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard1 = <span class="kw1">null</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard1.<span class="me1">Begin</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard1Active = <span class="kw1">true</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">isDragging</span> = <span class="kw1">false</span>;
&nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">lastMousePosition</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; item.<span class="me1">ReleaseMouseCapture</span><span class="br0">&#40;</span><span class="br0">&#41;</span>; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; 
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="font-weight:bolder">DroppableObject.cs</span></p>
<pre style="height:850px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="br0">&#91;</span>TemplateVisualState<span class="br0">&#40;</span>Name = &amp;quot;Normal&amp;quot;, GroupName = &amp;quot;GroupCommon&amp;quot;<span class="br0">&#41;</span><span class="br0">&#93;</span>
<span class="br0">&#91;</span>TemplateVisualState<span class="br0">&#40;</span>Name = &amp;quot;StateMouseOver&amp;quot;, GroupName = &amp;quot;GroupCommon&amp;quot;<span class="br0">&#41;</span><span class="br0">&#93;</span>
<span class="kw1">public</span> <span class="kw4">class</span> DroppableObject : ContentControl
<span class="br0">&#123;</span> &nbsp; 
&nbsp; &nbsp; <span class="kw1">static</span> DroppableRoot droppableRoot;
&nbsp; &nbsp; 
&nbsp; &nbsp; TransformGroup transformGroup;
&nbsp; &nbsp; TranslateTransform translateTransform;

&nbsp; &nbsp; <span class="kw1">public</span> DroppableObject<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">DefaultStyleKey</span> = <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span class="kw3">typeof</span></a><span class="br0">&#40;</span>DroppableObject<span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">MouseEnter</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MouseEventHandler<span class="br0">&#40;</span>DroppableObject_MouseEnter<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">MouseLeave</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> MouseEventHandler<span class="br0">&#40;</span>DroppableObject_MouseLeave<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">LayoutUpdated</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> EventHandler<span class="br0">&#40;</span>DroppableObject_LayoutUpdated<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">RenderTransform</span> <a href="http://www.google.com/search?q=is+msdn.microsoft.com"><span class="kw3">is</span></a> TransformGroup<span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transformGroup = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> TransformGroup<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; translateTransform = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> TranslateTransform<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transformGroup.<span class="me1">Children</span>.<span class="me1">Add</span><span class="br0">&#40;</span>translateTransform<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">RenderTransform</span> = transformGroup;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">StartPosition</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">-1</span>, <span class="nu0">-1</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">bool</span> isDragging <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">public</span> Point lastMousePosition <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span> &nbsp;<span class="co1">// when mouse is moving, this is stored and compared against run-time mouse position to create an offset for the transform property of the dragging object &nbsp; &nbsp; &nbsp; &nbsp;</span>
&nbsp; &nbsp; <span class="kw1">public</span> Point StartPosition <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span> &nbsp;<span class="co1">// sets the initial position of object</span>
&nbsp; &nbsp; <span class="kw1">public</span> Point CurrentPosition <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span> &nbsp;<span class="co1">// where the object has been translated to</span>
&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">bool</span> Initialized <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span> <span class="co1">// indicates whether StartPosition has been established</span>
&nbsp; &nbsp; <span class="kw1">public</span> Point OffsetPoint <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span> &nbsp;<span class="co1">// this property is updated by the dependency property TranslateToPoint; translate animation will use this value</span>

&nbsp; &nbsp; <span class="kw4">string</span> text = <span class="st0">&quot;&quot;</span>;

&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">string</span> Text
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; get <span class="br0">&#123;</span> <span class="kw1">return</span> text; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; set
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">Content</span> == <span class="kw1">null</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TextBlock tb = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> TextBlock<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tb.<span class="me1">Text</span> = value;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tb.<span class="me1">FontSize</span> = <span class="nu0">12</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">Content</span> = tb;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">void</span> DroppableObject_LayoutUpdated<span class="br0">&#40;</span><span class="kw4">object</span> sender, EventArgs e<span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>droppableRoot == <span class="kw1">null</span><span class="br0">&#41;</span> droppableRoot = DroppableManager.<span class="me1">CurDroppableRoot</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">void</span> DroppableObject_MouseLeave<span class="br0">&#40;</span><span class="kw4">object</span> sender, MouseEventArgs e<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; VisualStateManager.<span class="me1">GoToState</span><span class="br0">&#40;</span><span class="kw1">this</span>, <span class="st0">&quot;Normal&quot;</span>, <span class="kw1">true</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">void</span> DroppableObject_MouseEnter<span class="br0">&#40;</span><span class="kw4">object</span> sender, MouseEventArgs e<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; VisualStateManager.<span class="me1">GoToState</span><span class="br0">&#40;</span><span class="kw1">this</span>, <span class="st0">&quot;MouseOver&quot;</span>, <span class="kw1">true</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw1">static</span> <span class="kw1">readonly</span> DependencyProperty TranslateToPointProperty = DependencyProperty.<span class="me1">Register</span><span class="br0">&#40;</span><span class="st0">&quot;TranslateToPoint&quot;</span>, <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span class="kw3">typeof</span></a><span class="br0">&#40;</span>Point<span class="br0">&#41;</span>, <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span class="kw3">typeof</span></a><span class="br0">&#40;</span>UIElement<span class="br0">&#41;</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> PropertyMetadata<span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> PropertyChangedCallback<span class="br0">&#40;</span>OnTranslateToPointPropertyChanged<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; <span class="kw1">public</span> Point TranslateToPoint
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; get <span class="br0">&#123;</span> <span class="kw1">return</span> <span class="br0">&#40;</span>Point<span class="br0">&#41;</span>GetValue<span class="br0">&#40;</span>TranslateToPointProperty<span class="br0">&#41;</span>; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; set <span class="br0">&#123;</span> SetValue<span class="br0">&#40;</span>TranslateToPointProperty, value<span class="br0">&#41;</span>; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">static</span> <span class="kw1">void</span> OnTranslateToPointPropertyChanged<span class="br0">&#40;</span>DependencyObject d, DependencyPropertyChangedEventArgs e<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>d <a href="http://www.google.com/search?q=is+msdn.microsoft.com"><span class="kw3">is</span></a> DroppableObject<span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var droppableObject = d <span class="kw1">as</span> DroppableObject;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var newPoint = <span class="br0">&#40;</span>Point<span class="br0">&#41;</span>e.<span class="me1">NewValue</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var offsetX = newPoint.<span class="me1">X</span> - droppableObject.<span class="me1">StartPosition</span>.<span class="me1">X</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var offsetY = newPoint.<span class="me1">Y</span> - droppableObject.<span class="me1">StartPosition</span>.<span class="me1">Y</span>;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; droppableObject.<span class="me1">OffsetPoint</span> = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span>offsetX, offsetY<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="font-weight:bolder">DroppableRoot.cs</span>
<pre style="height:220px">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">public</span> <span class="kw4">class</span> DroppableRoot : ItemsControl
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">bool</span> IsInitialized = <span class="kw1">false</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; <span class="kw1">public</span> DroppableRoot<span class="br0">&#40;</span><span class="br0">&#41;</span> : <span class="kw1">base</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span> &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">DefaultStyleKey</span> = <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span class="kw3">typeof</span></a><span class="br0">&#40;</span>DroppableRoot<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; DroppableManager droppableManager = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> DroppableManager<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="font-weight:bolder">DroppablePanel.cs</span>
<pre style="height:135px">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">public</span> <span class="kw4">class</span> DroppablePanel : ItemsControl
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">public</span> DroppablePanel<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">DefaultStyleKey</span> = <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span class="kw3">typeof</span></a><span class="br0">&#40;</span>DroppablePanel<span class="br0">&#41;</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; <span class="br0">&#125;</span> &nbsp; 
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="font-weight:bolder">Common.cs</span>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">public</span> <span class="kw4">delegate</span> <span class="kw1">void</span> EventHandlerFor&lt;T&gt;<span class="br0">&#40;</span><span class="kw4">object</span> sender, EventArgs&lt;T&gt; args<span class="br0">&#41;</span>;

<span class="kw1">public</span> <span class="kw4">class</span> EventArgs&lt;T&gt; : EventArgs
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">public</span> T Data <span class="br0">&#123;</span> get; <span class="kw1">private</span> set; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">public</span> EventArgs<span class="br0">&#40;</span>T data<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; Data = data;
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>

<span class="kw1">public</span> <span class="kw4">class</span> CollisonElements
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">public</span> UIElement Element <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">public</span> UIElement CollidedElement <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>

<span class="kw1">public</span> <span class="kw4">class</span> DroppableDataContextItem
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">string</span> Name <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span style="font-weight:bolder;">Generic.xaml</span></p>
<pre style="height:620px">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="sc3"><span class="re1">&lt;ResourceDictionary</span> 
&nbsp; &nbsp; <span class="re0">xmlns</span>=<span class="st0">&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span>
&nbsp; &nbsp; <span class="re0">xmlns:x</span>=<span class="st0">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span>
&nbsp; &nbsp; <span class="re0">xmlns:view</span>=<span class="st0">&quot;clr-namespace:CustomHitTest;assembly=CustomHitTest&quot;</span>
&nbsp; &nbsp; <span class="re0">xmlns:vsm</span>=<span class="st0">&quot;clr-namespace:System.Windows;assembly=System.Windows&quot;</span>
&nbsp; &nbsp; <span class="re2">&gt;</span></span>

&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Style</span> <span class="re0">TargetType</span>=<span class="st0">&quot;view:DroppableRoot&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span> <span class="re0">Property</span>=<span class="st0">&quot;Template&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span>.Value<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ControlTemplate</span> <span class="re0">TargetType</span>=<span class="st0">&quot;view:DroppableRoot&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Border</span> <span class="re0">x:Name</span>=<span class="st0">&quot;RootElement&quot;</span> <span class="re0">BorderBrush</span>=<span class="st0">&quot;Crimson&quot;</span> <span class="re0">BorderThickness</span>=<span class="st0">&quot;1&quot;</span> <span class="re0">CornerRadius</span>=<span class="st0">&quot;10&quot;</span> <span class="re0">Height</span>=<span class="st0">&quot;{TemplateBinding Height}&quot;</span> <span class="re0">Width</span>=<span class="st0">&quot;{TemplateBinding Width}&quot;</span> <span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Border</span>.Background<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;LinearGradientBrush</span> <span class="re0">StartPoint</span>=<span class="st0">&quot;0.5,0&quot;</span> <span class="re0">EndPoint</span>=<span class="st0">&quot;0.5,1&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;GradientStop</span> <span class="re0">Color</span>=<span class="st0">&quot;#333333&quot;</span> <span class="re0">Offset</span>=<span class="st0">&quot;0&quot;</span> <span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;GradientStop</span> <span class="re0">Color</span>=<span class="st0">&quot;WhiteSmoke&quot;</span> <span class="re0">Offset</span>=<span class="st0">&quot;1&quot;</span> <span class="re0">x:Name</span>=<span class="st0">&quot;FinalOffset&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/LinearGradientBrush<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Border</span>.Background<span class="re2">&gt;</span></span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualStateManager</span>.VisualStateGroups<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualStateGroup</span> <span class="re0">x:Name</span>=<span class="st0">&quot;CommonStates&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualStateGroup</span>.Transitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualTransition</span> <span class="re0">To</span>=<span class="st0">&quot;Normal&quot;</span> &nbsp;<span class="re0">GeneratedDuration</span>=<span class="st0">&quot;0:0:1&quot;</span> <span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualTransition</span> <span class="re0">To</span>=<span class="st0">&quot;Disabled&quot;</span> <span class="re0">GeneratedDuration</span>=<span class="st0">&quot;0:0:0.8&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/vsm:VisualStateGroup</span>.Transitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualState</span> <span class="re0">x:Name</span>=<span class="st0">&quot;Normal&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualState</span> <span class="re0">x:Name</span>=<span class="st0">&quot;Disabled&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Storyboard<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ColorAnimation</span> Storyboard.<span class="re0">TargetName</span>=<span class="st0">&quot;FinalOffset&quot;</span> Storyboard.<span class="re0">TargetProperty</span>=<span class="st0">&quot;(GradientStop.Color)&quot;</span> <span class="re0">To</span>=<span class="st0">&quot;Crimson&quot;</span> <span class="re0">Duration</span>=<span class="st0">&quot;0:0:0.8&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;DoubleAnimation</span> Storyboard.<span class="re0">TargetName</span>=<span class="st0">&quot;RootElement&quot;</span> Storyboard.<span class="re0">TargetProperty</span>=<span class="st0">&quot;Opacity&quot;</span> <span class="re0">From</span>=<span class="st0">&quot;1.0&quot;</span> <span class="re0">To</span>=<span class="st0">&quot;0.55&quot;</span> <span class="re0">Duration</span>=<span class="st0">&quot;0:0:0.8&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Storyboard<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/vsm:VisualState<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/vsm:VisualStateGroup<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/vsm:VisualStateManager</span>.VisualStateGroups<span class="re2">&gt;</span></span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ItemsPresenter</span> <span class="re0">Height</span>=<span class="st0">&quot;{TemplateBinding Height}&quot;</span> <span class="re0">Width</span>=<span class="st0">&quot;{TemplateBinding Width}&quot;</span> <span class="re0">x:Name</span>=<span class="st0">&quot;ItemsPresenter&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Border<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/ControlTemplate<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Setter</span>.Value<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Setter<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Style<span class="re2">&gt;</span></span></span>

&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Style</span> <span class="re0">TargetType</span>=<span class="st0">&quot;view:DroppablePanel&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span> <span class="re0">Property</span>=<span class="st0">&quot;HorizontalAlignment&quot;</span> <span class="re0">Value</span>=<span class="st0">&quot;Center&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span> <span class="re0">Property</span>=<span class="st0">&quot;VerticalAlignment&quot;</span> <span class="re0">Value</span>=<span class="st0">&quot;Center&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span> <span class="re0">Property</span>=<span class="st0">&quot;Template&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span>.Value<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ControlTemplate</span> <span class="re0">TargetType</span>=<span class="st0">&quot;view:DroppablePanel&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Border</span> <span class="re0">x:Name</span>=<span class="st0">&quot;RootElement&quot;</span> <span class="re0">BorderBrush</span>=<span class="st0">&quot;Crimson&quot;</span> <span class="re0">BorderThickness</span>=<span class="st0">&quot;1&quot;</span> <span class="re0">CornerRadius</span>=<span class="st0">&quot;10&quot;</span> <span class="re0">Height</span>=<span class="st0">&quot;{TemplateBinding Height}&quot;</span> <span class="re0">Width</span>=<span class="st0">&quot;{TemplateBinding Width}&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Border</span>.Background<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;SolidColorBrush</span> <span class="re0">Color</span>=<span class="st0">&quot;AliceBlue&quot;</span> &nbsp;<span class="re0">x:Name</span>=<span class="st0">&quot;ColorOffset&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Border</span>.Background<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualStateManager</span>.VisualStateGroups<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualStateGroup</span> <span class="re0">x:Name</span>=<span class="st0">&quot;CommonStates&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualStateGroup</span>.Transitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualTransition</span> <span class="re0">To</span>=<span class="st0">&quot;Normal&quot;</span> &nbsp;<span class="re0">GeneratedDuration</span>=<span class="st0">&quot;0:0:1&quot;</span> <span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualTransition</span> <span class="re0">To</span>=<span class="st0">&quot;Disabled&quot;</span> <span class="re0">GeneratedDuration</span>=<span class="st0">&quot;0:0:1&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/vsm:VisualStateGroup</span>.Transitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualState</span> <span class="re0">x:Name</span>=<span class="st0">&quot;Normal&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualState</span> <span class="re0">x:Name</span>=<span class="st0">&quot;Disabled&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Storyboard<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ColorAnimation</span> Storyboard.<span class="re0">TargetName</span>=<span class="st0">&quot;ColorOffset&quot;</span> Storyboard.<span class="re0">TargetProperty</span>=<span class="st0">&quot;Color&quot;</span> <span class="re0">To</span>=<span class="st0">&quot;#333333&quot;</span> <span class="re0">Duration</span>=<span class="st0">&quot;0:0:07&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Storyboard<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/vsm:VisualState<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/vsm:VisualStateGroup<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/vsm:VisualStateManager</span>.VisualStateGroups<span class="re2">&gt;</span></span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ItemsPresenter<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/ItemsPresenter<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Border<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/ControlTemplate<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Setter</span>.Value<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Setter<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Style<span class="re2">&gt;</span></span></span>

&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Style</span> <span class="re0">TargetType</span>=<span class="st0">&quot;view:DroppableObject&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span> <span class="re0">Property</span>=<span class="st0">&quot;Width&quot;</span> <span class="re0">Value</span>=<span class="st0">&quot;85&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span> <span class="re0">Property</span>=<span class="st0">&quot;Height&quot;</span> <span class="re0">Value</span>=<span class="st0">&quot;35&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span> <span class="re0">Property</span>=<span class="st0">&quot;Background&quot;</span> <span class="re0">Value</span>=<span class="st0">&quot;Lavender&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span> <span class="re0">Property</span>=<span class="st0">&quot;HorizontalAlignment&quot;</span> <span class="re0">Value</span>=<span class="st0">&quot;Center&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span> <span class="re0">Property</span>=<span class="st0">&quot;VerticalAlignment&quot;</span> <span class="re0">Value</span>=<span class="st0">&quot;Center&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span> <span class="re0">Property</span>=<span class="st0">&quot;Margin&quot;</span> <span class="re0">Value</span>=<span class="st0">&quot;0,2.5,0,2.5&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span> <span class="re0">Property</span>=<span class="st0">&quot;FontSize&quot;</span> <span class="re0">Value</span>=<span class="st0">&quot;12&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span> <span class="re0">Property</span>=<span class="st0">&quot;Template&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Setter</span>.Value<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ControlTemplate</span> <span class="re0">TargetType</span>=<span class="st0">&quot;view:DroppableObject&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span> <span class="re0">x:Name</span>=<span class="st0">&quot;Root&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualStateManager</span>.VisualStateGroups<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualStateGroup</span> <span class="re0">x:Name</span>=<span class="st0">&quot;CommonStates&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualStateGroup</span>.Transitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualTransition</span> <span class="re0">To</span>=<span class="st0">&quot;Normal&quot;</span> &nbsp;<span class="re0">GeneratedDuration</span>=<span class="st0">&quot;0:0:0.2&quot;</span> <span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualTransition</span> <span class="re0">To</span>=<span class="st0">&quot;MouseOver&quot;</span> <span class="re0">GeneratedDuration</span>=<span class="st0">&quot;0:0:0.2&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualTransition</span> <span class="re0">To</span>=<span class="st0">&quot;Disabled&quot;</span> <span class="re0">GeneratedDuration</span>=<span class="st0">&quot;0:0:0.2&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/vsm:VisualStateGroup</span>.Transitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualState</span> <span class="re0">x:Name</span>=<span class="st0">&quot;Normal&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualState</span> <span class="re0">x:Name</span>=<span class="st0">&quot;MouseOver&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Storyboard<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ColorAnimation</span> Storyboard.<span class="re0">TargetName</span>=<span class="st0">&quot;FinalOffset&quot;</span> Storyboard.<span class="re0">TargetProperty</span>=<span class="st0">&quot;(GradientStop.Color)&quot;</span> <span class="re0">To</span>=<span class="st0">&quot;Pink&quot;</span> <span class="re0">Duration</span>=<span class="st0">&quot;0&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Storyboard<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/vsm:VisualState<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;vsm:VisualState</span> <span class="re0">x:Name</span>=<span class="st0">&quot;Disabled&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Storyboard<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;DoubleAnimation</span> Storyboard.<span class="re0">TargetName</span>=<span class="st0">&quot;Body&quot;</span> Storyboard.<span class="re0">TargetProperty</span>=<span class="st0">&quot;Opacity&quot;</span> <span class="re0">From</span>=<span class="st0">&quot;1.0&quot;</span> <span class="re0">To</span>=<span class="st0">&quot;0.45&quot;</span> <span class="re0">Duration</span>=<span class="st0">&quot;0:0:0&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Storyboard<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/vsm:VisualState<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/vsm:VisualStateGroup<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/vsm:VisualStateManager</span>.VisualStateGroups<span class="re2">&gt;</span></span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Rectangle</span> <span class="re0">x:Name</span>=<span class="st0">&quot;Body&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">Width</span>=<span class="st0">&quot;{TemplateBinding Width}&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">Height</span>=<span class="st0">&quot;{TemplateBinding Height}&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">Stroke</span>=<span class="st0">&quot;Purple&quot;</span> <span class="re0">RadiusX</span>=<span class="st0">&quot;5&quot;</span> <span class="re0">RadiusY</span>=<span class="st0">&quot;5&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">HorizontalAlignment</span>=<span class="st0">&quot;Left&quot;</span> <span class="re0">VerticalAlignment</span>=<span class="st0">&quot;Top&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Rectangle</span>.Fill<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;RadialGradientBrush</span> <span class="re0">GradientOrigin</span>=<span class="st0">&quot;0.25,0.25&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;GradientStop</span> <span class="re0">Offset</span>=<span class="st0">&quot;0.25&quot;</span> <span class="re0">Color</span>=<span class="st0">&quot;White&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;GradientStop</span> <span class="re0">x:Name</span>=<span class="st0">&quot;FinalOffset&quot;</span> <span class="re0">Offset</span>=<span class="st0">&quot;1.0&quot;</span> <span class="re0">Color</span>=<span class="st0">&quot;Red&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/RadialGradientBrush<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Rectangle</span>.Fill<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Rectangle</span>.RenderTransform<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;TransformGroup<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;TranslateTransform</span> <span class="re0">X</span>=<span class="st0">&quot;{TemplateBinding X}&quot;</span> <span class="re0">Y</span>=<span class="st0">&quot;{TemplateBinding Y}&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/TransformGroup<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Rectangle</span>.RenderTransform<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Rectangle<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ContentPresenter</span> <span class="re0">Content</span>=<span class="st0">&quot;{TemplateBinding Content}&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">HorizontalAlignment</span>=<span class="st0">&quot;Center&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">VerticalAlignment</span>=<span class="st0">&quot;Center&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/ControlTemplate<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Setter</span>.Value<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Setter<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Style<span class="re2">&gt;</span></span></span>
<span class="sc3"><span class="re1">&lt;/ResourceDictionary<span class="re2">&gt;</span></span></span></div>
</div>
</pre>
<p><span style="font-weight:bolder;">Page.xaml</span></p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="sc3"><span class="re1">&lt;UserControl</span> <span class="re0">x:Class</span>=<span class="st0">&quot;CustomHitTest.Page&quot;</span>
&nbsp; &nbsp; <span class="re0">xmlns</span>=<span class="st0">&quot;http://schemas.microsoft.com/client/2007&quot;</span> 
&nbsp; &nbsp; <span class="re0">xmlns:x</span>=<span class="st0">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span> 
&nbsp; &nbsp; <span class="re0">xmlns:local</span>=<span class="st0">&quot;clr-namespace:CustomHitTest;assembly=CustomHitTest&quot;</span>
&nbsp; &nbsp; <span class="re0">Width</span>=<span class="st0">&quot;900&quot;</span> <span class="re0">Height</span>=<span class="st0">&quot;600&quot;</span><span class="re2">&gt;</span></span>

&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span> <span class="re0">Background</span>=<span class="st0">&quot;White&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;local:DroppableRoot</span> <span class="re0">x:Name</span>=<span class="st0">&quot;DroppableRoot&quot;</span> <span class="re0">Width</span>=<span class="st0">&quot;225&quot;</span> <span class="re0">Height</span>=<span class="st0">&quot;250&quot;</span> <span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span> <span class="re0">Margin</span>=<span class="st0">&quot;0&quot;</span> <span class="re0">HorizontalAlignment</span>=<span class="st0">&quot;Center&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span>.ColumnDefinitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ColumnDefinition</span> <span class="re0">Width</span>=<span class="st0">&quot;192&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid</span>.ColumnDefinitions<span class="re2">&gt;</span></span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span>.RowDefinitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;RowDefinition</span> <span class="re0">Height</span>=<span class="st0">&quot;Auto&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;RowDefinition</span> <span class="re0">Height</span>=<span class="st0">&quot;230&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid</span>.RowDefinitions<span class="re2">&gt;</span></span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;TextBlock</span> <span class="re0">Text</span>=<span class="st0">&quot;Try Reordering the Sortables&quot;</span> &nbsp;<span class="re0">FontSize</span>=<span class="st0">&quot;9&quot;</span> <span class="re0">Foreground</span>=<span class="st0">&quot;DarkSeaGreen&quot;</span> Grid.<span class="re0">Column</span>=<span class="st0">&quot;0&quot;</span> Grid.<span class="re0">Row</span>=<span class="st0">&quot;0&quot;</span> <span class="re0">HorizontalAlignment</span>=<span class="st0">&quot;Center&quot;</span> <span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;local:DroppablePanel</span> <span class="re0">Width</span>=<span class="st0">&quot;165&quot;</span> <span class="re0">Height</span>=<span class="st0">&quot;200&quot;</span> Grid.<span class="re0">Column</span>=<span class="st0">&quot;0&quot;</span> Grid.<span class="re0">Row</span>=<span class="st0">&quot;1&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/local:DroppablePanel<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/local:DroppableRoot<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid<span class="re2">&gt;</span></span></span>
<span class="sc3"><span class="re1">&lt;/UserControl<span class="re2">&gt;</span></span></span></div>
</div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://eztier.com/dba2day/?feed=rss2&amp;p=133</wfw:commentRss>
		</item>
		<item>
		<title>Path Animation With Silverlight 2</title>
		<link>http://eztier.com/dba2day/?p=81</link>
		<comments>http://eztier.com/dba2day/?p=81#comments</comments>
		<pubDate>Thu, 19 Mar 2009 21:15:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Silverlight 2 (5)]]></category>

		<guid isPermaLink="false">http://eztier.com/dba2day/?p=81</guid>
		<description><![CDATA[In a recent Silverlight 2 project, I wanted create my own ubiquitous &#8220;spinning wheel&#8221;. The implementation options are endless and my approach was to create the visual using the Path element and animate it to give it that spinning effect.
The visual looks like this:


To draw the wheel, I&#8217;m going to use the Path object and [...]]]></description>
			<content:encoded><![CDATA[<p>In a recent Silverlight 2 project, I wanted create my own ubiquitous &#8220;spinning wheel&#8221;. The implementation options are endless and my approach was to create the visual using the Path element and animate it to give it that spinning effect.</p>
<p>The visual looks like this:</p>
<p><a href="http://eztier.com/dba2day/wp-content/uploads/2009/03/waitanimation.jpg"><img class="alignnone size-full wp-image-83" title="Spinning Wheel Path Animation" src="http://eztier.com/dba2day/wp-content/uploads/2009/03/waitanimation.jpg" alt="" width="129" height="128" /></a><br />
<span id="more-81"></span><br />
To draw the wheel, I&#8217;m going to use the Path object and define Data property using the Path mini-language.</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="sc3"><span class="re1">&lt;UserControl</span> <span class="re0">x:Class</span>=<span class="st0">&quot;WaitAnimation.Page&quot;</span>
&nbsp; &nbsp; <span class="re0">xmlns</span>=<span class="st0">&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span> 
&nbsp; &nbsp; <span class="re0">xmlns:x</span>=<span class="st0">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span> <span class="re0">x:Name</span>=<span class="st0">&quot;LayoutRoot&quot;</span> <span class="re0">Background</span>=<span class="st0">&quot;Black&quot;</span> <span class="re0">Height</span>=<span class="st0">&quot;130&quot;</span> <span class="re0">Width</span>=<span class="st0">&quot;130&quot;</span> <span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span>.ColumnDefinitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ColumnDefinition</span> <span class="re0">Width</span>=<span class="st0">&quot;20&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ColumnDefinition</span> <span class="re0">Width</span>=<span class="st0">&quot;90&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;ColumnDefinition</span> <span class="re0">Width</span>=<span class="st0">&quot;20&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid</span>.ColumnDefinitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span>.RowDefinitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;RowDefinition</span> <span class="re0">Height</span>=<span class="st0">&quot;20&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;RowDefinition</span> <span class="re0">Height</span>=<span class="st0">&quot;90&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;RowDefinition</span> <span class="re0">Height</span>=<span class="st0">&quot;20&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid</span>.RowDefinitions<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Grid</span> Grid.<span class="re0">Column</span>=<span class="st0">&quot;1&quot;</span> Grid.<span class="re0">Row</span>=<span class="st0">&quot;1&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Path</span> <span class="re0">x:Name</span>=<span class="st0">&quot;pathMarkup&quot;</span> &nbsp;<span class="re0">Fill</span>=<span class="st0">&quot;Black&quot;</span> <span class="re0">StrokeDashArray</span>=<span class="st0">&quot;53,0.75&quot;</span> <span class="re0">StrokeDashOffset</span>=<span class="st0">&quot;0&quot;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">StrokeEndLineCap</span>=<span class="st0">&quot;Flat&quot;</span> <span class="re0">StrokeStartLineCap</span>=<span class="st0">&quot;Flat&quot;</span> <span class="re0">StrokeThickness</span>=<span class="st0">&quot;5&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">HorizontalAlignment</span>=<span class="st0">&quot;Center&quot;</span> <span class="re0">VerticalAlignment</span>=<span class="st0">&quot;Center&quot;</span> <span class="re0">Stretch</span>=<span class="st0">&quot;UniformToFill&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">Data</span>=<span class="st0">&quot;M 0,80 A 40,40 0 0 0 80,0 A 40,40 0 0 0 0,80&quot;</span><span class="re2">&gt;</span></span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Path</span>.Stroke<span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;LinearGradientBrush</span> <span class="re0">StartPoint</span>=<span class="st0">&quot;0.5,0&quot;</span> <span class="re0">EndPoint</span>=<span class="st0">&quot;0.5,1&quot;</span><span class="re2">&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;GradientStop</span> <span class="re0">Color</span>=<span class="st0">&quot;DarkGoldenrod&quot;</span> <span class="re0">Offset</span>=<span class="st0">&quot;0&quot;</span> <span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;GradientStop</span> <span class="re0">Color</span>=<span class="st0">&quot;White&quot;</span> <span class="re0">Offset</span>=<span class="st0">&quot;1&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/LinearGradientBrush<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Path</span>.Stroke<span class="re2">&gt;</span></span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Path<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;TextBlock</span> <span class="re0">Text</span>=<span class="st0">&quot;Loading&quot;</span> <span class="re0">HorizontalAlignment</span>=<span class="st0">&quot;Center&quot;</span> <span class="re0">VerticalAlignment</span>=<span class="st0">&quot;Center&quot;</span> <span class="re0">Foreground</span>=<span class="st0">&quot;Bisque&quot;</span><span class="re2">/&gt;</span></span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid<span class="re2">&gt;</span></span></span>
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Grid<span class="re2">&gt;</span></span></span>
<span class="sc3"><span class="re1">&lt;/UserControl<span class="re2">&gt;</span></span></span></div>
</div>
</pre>
<p>Let&#8217;s take note on the circumference of the wheel.  It is &#8220;Pi&#8221; (3.14159&#8230;) multiplied by the diameter of the circle.  </p>
<p>My wheel, as defined in XAML, has a diameter of 80px but also a StrokeThickness of 5px so we&#8217;ll tack on an additonal 5px (not 10px as intuition would tell us) to the diameter.<br />
The wheel&#8217;s circumference is about 270px (85px * 3.14).</p>
<p>The StrokeDashArray property defines a pattern of dashes and gaps of a Shape object like Path relative to the thickness of the StrokeThickness.  </p>
<p>To completely fill a dash around the wheel, we&#8217;ll divide 270px by 5, which is 54px.  But I want to leave a small gap that is almost equal to the StrokeThickness.</p>
<p>So we set our StrokeDashArray property to &#8220;53,0.75&#8243; (dash value, gap value).</p>
<p>Let&#8217;s also check out the StrokeDashOffset property.  This is actually the property that we will target in our animation that will give the wheel that spinning effect.  MSDN defines it as the distance where our dash pattern (defined by StrokeDashArray) begins.  We will set it to 0 initially.</p>
<p>Now we&#8217;re ready to add animation to the Path object.  I want to make the animation flexible, that is, if I wanted to define 2 different types of animations for the same target, I should be allowed to define the animation, and then choose the animation that I want the Storyboard to use.<br />
So I&#8217;ll simply declare a delegate that would allow me to add this functionality.</p>
<pre style="height:50px">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">Func&lt;UIElement, Timeline&gt; DefineAnimationForWaitElement 
<span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span></div>
</div>
</pre>
<p>And I&#8217;m going to define two animations for my Path object.  Note that the targeted PropertyPath is the &#8220;(Shape.StrokeDashOffset)&#8221; and the final value is &#8220;53&#8243;.  As mentioned above, a value of 53 basically moves the StrokeDashOffset completely around the circumference one time.</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">Timeline Spin<span class="br0">&#40;</span>UIElement item<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; var pathDashOffsetAnimation = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> DoubleAnimationUsingKeyFrames<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; pathDashOffsetAnimation.<span class="me1">KeyFrames</span>.<span class="me1">Add</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> SplineDoubleKeyFrame<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> Value = <span class="nu0">0.0</span>, KeyTime = KeyTime.<span class="me1">FromTimeSpan</span><span class="br0">&#40;</span>TimeSpan.<span class="me1">FromSeconds</span><span class="br0">&#40;</span><span class="nu0">0.0</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; var keySpline = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> KeySpline<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> ControlPoint1 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0.25</span>, <span class="nu0">0.75</span><span class="br0">&#41;</span>, ControlPoint2 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0.75</span>, <span class="nu0">0.25</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;
&nbsp; &nbsp; pathDashOffsetAnimation.<span class="me1">KeyFrames</span>.<span class="me1">Add</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> SplineDoubleKeyFrame<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> Value = <span class="nu0">53.0</span>, KeyTime = KeyTime.<span class="me1">FromTimeSpan</span><span class="br0">&#40;</span>TimeSpan.<span class="me1">FromSeconds</span><span class="br0">&#40;</span><span class="nu0">1.35</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, KeySpline = keySpline <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; Storyboard.<span class="me1">SetTargetProperty</span><span class="br0">&#40;</span>pathDashOffsetAnimation, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> PropertyPath<span class="br0">&#40;</span><span class="st0">&quot;(Shape.StrokeDashOffset)&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> pathDashOffsetAnimation;
<span class="br0">&#125;</span>

Timeline SpinLinear<span class="br0">&#40;</span>UIElement item<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; var pathDashOffsetAnimation = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> DoubleAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> SpeedRatio = <span class="nu0">0.5</span>, Duration = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Duration<span class="br0">&#40;</span>TimeSpan.<span class="me1">FromSeconds</span><span class="br0">&#40;</span><span class="nu0">1.0</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, To = <span class="nu0">53</span> <span class="br0">&#125;</span>;
&nbsp; &nbsp; Storyboard.<span class="me1">SetTargetProperty</span><span class="br0">&#40;</span>pathDashOffsetAnimation, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> PropertyPath<span class="br0">&#40;</span><span class="st0">&quot;(Shape.StrokeDashOffset)&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="kw1">return</span> pathDashOffsetAnimation;
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>To choose between animations, I will assign the animation to the delegate that I had defined earlier and then invoke the delegate.<br />
I like the fact that if I wanted to pass an animation definition from another project, I can just pass the function definition to the delegate, instead of having to access and create a new method in the main code.</p>
<pre style="height:100px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">UIElement element = <span class="kw1">this</span>.<span class="me1">pathMarkup</span>;
<span class="kw1">if</span> <span class="br0">&#40;</span>DefineAnimationForWaitElement == <span class="kw1">null</span><span class="br0">&#41;</span>
&nbsp; &nbsp; DefineAnimationForWaitElement = Spin;

var timeLine = DefineAnimationForWaitElement<span class="br0">&#40;</span>element<span class="br0">&#41;</span>;</div>
</div>
</pre>
<p>The complete code looks like this.</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">public</span> partial <span class="kw4">class</span> Page : UserControl
<span class="br0">&#123;</span>
&nbsp; &nbsp; Storyboard WaitAnimationStoryboard = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Storyboard<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; Func&lt;UIElement, Timeline&gt; DefineAnimationForWaitElement <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">public</span> Page<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; InitializeComponent<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; CreateWaitAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">void</span> CreateWaitAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; UIElement element = <span class="kw1">this</span>.<span class="me1">pathMarkup</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>DefineAnimationForWaitElement == <span class="kw1">null</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DefineAnimationForWaitElement = Spin;

&nbsp; &nbsp; &nbsp; &nbsp; var timeLine = DefineAnimationForWaitElement<span class="br0">&#40;</span>element<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; CreateStoryboardForWaitAnimation<span class="br0">&#40;</span>element, timeLine<span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">void</span> CreateStoryboardForWaitAnimation<span class="br0">&#40;</span>UIElement item, Timeline animation<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; WaitAnimationStoryboard.<span class="me1">Stop</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; WaitAnimationStoryboard.<span class="me1">Children</span>.<span class="me1">Clear</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; WaitAnimationStoryboard.<span class="me1">Children</span>.<span class="me1">Add</span><span class="br0">&#40;</span>animation<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; Storyboard.<span class="me1">SetTarget</span><span class="br0">&#40;</span>WaitAnimationStoryboard, item<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; WaitAnimationStoryboard.<span class="me1">RepeatBehavior</span> = RepeatBehavior.<span class="me1">Forever</span>;
&nbsp; &nbsp; &nbsp; &nbsp; WaitAnimationStoryboard.<span class="me1">Begin</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; Timeline Spin<span class="br0">&#40;</span>UIElement item<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; var pathDashOffsetAnimation = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> DoubleAnimationUsingKeyFrames<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; pathDashOffsetAnimation.<span class="me1">KeyFrames</span>.<span class="me1">Add</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> SplineDoubleKeyFrame<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> Value = <span class="nu0">0.0</span>, KeyTime = KeyTime.<span class="me1">FromTimeSpan</span><span class="br0">&#40;</span>TimeSpan.<span class="me1">FromSeconds</span><span class="br0">&#40;</span><span class="nu0">0.0</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; var keySpline = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> KeySpline<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> ControlPoint1 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0.25</span>, <span class="nu0">0.75</span><span class="br0">&#41;</span>, ControlPoint2 = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Point<span class="br0">&#40;</span><span class="nu0">0.75</span>, <span class="nu0">0.25</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; pathDashOffsetAnimation.<span class="me1">KeyFrames</span>.<span class="me1">Add</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> SplineDoubleKeyFrame<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> Value = <span class="nu0">53.0</span>, KeyTime = KeyTime.<span class="me1">FromTimeSpan</span><span class="br0">&#40;</span>TimeSpan.<span class="me1">FromSeconds</span><span class="br0">&#40;</span><span class="nu0">1.35</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, KeySpline = keySpline <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; Storyboard.<span class="me1">SetTargetProperty</span><span class="br0">&#40;</span>pathDashOffsetAnimation, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> PropertyPath<span class="br0">&#40;</span><span class="st0">&quot;(Shape.StrokeDashOffset)&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> pathDashOffsetAnimation;
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; Timeline SpinLinear<span class="br0">&#40;</span>UIElement item<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; var pathDashOffsetAnimation = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> DoubleAnimation<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> SpeedRatio = <span class="nu0">0.5</span>, Duration = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Duration<span class="br0">&#40;</span>TimeSpan.<span class="me1">FromSeconds</span><span class="br0">&#40;</span><span class="nu0">1.0</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, To = <span class="nu0">53</span> <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; Storyboard.<span class="me1">SetTargetProperty</span><span class="br0">&#40;</span>pathDashOffsetAnimation, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> PropertyPath<span class="br0">&#40;</span><span class="st0">&quot;(Shape.StrokeDashOffset)&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> pathDashOffsetAnimation;
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://eztier.com/dba2day/?feed=rss2&amp;p=81</wfw:commentRss>
		</item>
		<item>
		<title>Sandboxing Asynchronous Processes</title>
		<link>http://eztier.com/dba2day/?p=87</link>
		<comments>http://eztier.com/dba2day/?p=87#comments</comments>
		<pubDate>Sat, 14 Mar 2009 17:58:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[C# (2)]]></category>

		<guid isPermaLink="false">http://eztier.com/dba2day/?p=87</guid>
		<description><![CDATA[Creating process boundaries offer the advantages of isolation and the ability to load and unload other processes within one main process. We can do this easily with AppDomains. But I also want the application that is running in another AppDomain to perform its processing asynchronously. Since I have little control over the remote class if [...]]]></description>
			<content:encoded><![CDATA[<p>Creating process boundaries offer the advantages of isolation and the ability to load and unload other processes within one main process. We can do this easily with AppDomains. But I also want the application that is running in another AppDomain to perform its processing asynchronously. Since I have little control over the remote class if it is faulting, I&#8217;m quite happy with a &#8220;fire and forget&#8221; strategy.</p>
<p>First, I&#8217;m going to create a class that sets and returns a List of some Type. Since I will instantiate this class in another AppDomain, this class must derive MarshallByRef. To make it easy for the calling program to invoke its methods, this class will also implement an interface. This interface exists in the same namespace of the calling and remote classes and is visible to both.</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw4">interface</span> IParser&lt;T&gt; where T : <span class="kw4">class</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">void</span> Set_PENDING_PROCESSING_List<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; List&lt;T&gt; Get_PENDING_PROCESSING_List<span class="br0">&#40;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span>

<span class="kw1">public</span> <span class="kw4">class</span> Parser: MarshalByRefObject, IParser&lt;PENDING_PROCESSING&gt; 
<span class="br0">&#123;</span>
&nbsp; &nbsp; List&lt;PENDING_PROCESSING&gt; _pending_processing_list = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> List&lt;PENDING_PROCESSING&gt;<span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; <span class="kw1">public</span> Parser<span class="br0">&#40;</span><span class="kw4">string</span> uploadPath, <span class="kw4">string</span> file<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Set_PENDING_PROCESSING_List<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw1">void</span> Set_PENDING_PROCESSING_List<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thread.<span class="me1">Sleep</span><span class="br0">&#40;</span><span class="nu0">5000</span><span class="br0">&#41;</span>; &nbsp;<span class="co1">//Implement actual code here.</span>
&nbsp; &nbsp; <span class="br0">&#125;</span> 

&nbsp; &nbsp; <span class="kw1">public</span> List&lt;PENDING_PROCESSING&gt; Get_PENDING_PROCESSING_List<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> _pending_processing_list;
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span id="more-87"></span><br />
I&#8217;ll need to create a manager class that queues up and assigns jobs to available threads.  The assigned job creates an instance of the above class in another AppDomain and invokes one of its methods.  The manager class will also be responsible for creatiing the new AppDomain and unloading it once all the jobs have finished processing.</p>
<p>First, let&#8217;s create a new AppDomain if it doesn&#8217;t exist in the manager class.</p>
<pre style="height:150px;">
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">void</span> CreateSandBox<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>AppDomain.<span class="me1">CurrentDomain</span>.<span class="me1">FriendlyName</span> != <span class="st0">&quot;SandBoxAppDomain&quot;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; domain = AppDomain.<span class="me1">CreateDomain</span><span class="br0">&#40;</span><span class="st0">&quot;SandBoxAppDomain&quot;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>Next, I&#8217;ll nest a class inside of the manager that will be used hold job information.  After creating a list of jobs, I&#8217;ll queue them up.  Once they are queued, I will dequeue one job at a time until I&#8217;ve used up my available thread limit.  For this application, we&#8217;ll just limit the thread count to 5. </p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw4">class</span> Tracker
<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> Tracker<span class="br0">&#40;</span><span class="kw4">string</span> fileName, <span class="kw4">bool</span> archived<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">this</span>.<span class="me1">FileName</span> = fileName; <span class="kw1">this</span>.<span class="me1">Archived</span> = archived; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">string</span> FileName <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">bool</span> Archived <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>


<span class="kw4">int</span> THREAD_POOL_SIZE = <span class="nu0">5</span>;
Queue&lt;string&gt; queue = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Queue&lt;string&gt;<span class="br0">&#40;</span><span class="br0">&#41;</span>;
<span class="kw4">delegate</span> <span class="kw4">string</span> AsyncTryDoWork<span class="br0">&#40;</span><span class="kw4">string</span> file, WorkflowType workflowType<span class="br0">&#41;</span>;

List&lt;Tracker&gt; TrackerList = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> List&lt;Tracker&gt;<span class="br0">&#40;</span><span class="br0">&#41;</span> 
<span class="br0">&#123;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File1.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File2.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File3.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File4.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File5.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File6.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File7.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File8.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File9.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File10.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File11.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp;
<span class="br0">&#125;</span>;
<span class="kw1">readonly</span> <span class="kw4">object</span> lockItem = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> <span class="kw4">object</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;

<span class="kw1">void</span> QueueWork<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span>Tracker tracker <span class="kw1">in</span> TrackerList<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; queue.<span class="me1">Enqueue</span><span class="br0">&#40;</span>tracker.<span class="me1">FileName</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> NumberToQueue = queue.<span class="me1">Count</span> &lt; THREAD_POOL_SIZE ? queue.<span class="me1">Count</span> : THREAD_POOL_SIZE;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">lock</span> <span class="br0">&#40;</span>lockItem<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">int</span> assignment = <span class="nu0">0</span>; assignment &lt; NumberToQueue; assignment++<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">string</span> file = queue.<span class="me1">Dequeue</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;StartOneWork<span class="br0">&#40;</span>file, WorkflowType.<span class="me1">Upload</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> AsyncTryDoWork<span class="br0">&#40;</span>TryDoWork<span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>As a job is being dequeued, it will initiate an asynchronous method &#8220;TryDoWork&#8221;.  This is the method that will instantiate the remote object in the new AppDomain that had been previously created.  The method will pass the job information to this instance for processing.  </p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">void</span> StartOneWork<span class="br0">&#40;</span><span class="kw4">string</span> file, WorkflowType workflowType, AsyncTryDoWork asyncTryDoWork<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">lock</span> <span class="br0">&#40;</span>lockItem<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; asyncTryDoWork.<span class="me1">BeginInvoke</span><span class="br0">&#40;</span>file, workflowType, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> AsyncCallback<span class="br0">&#40;</span>CallBackTryDoWork<span class="br0">&#41;</span>, asyncTryDoWork<span class="br0">&#41;</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<span class="br0">&#125;</span>

<span class="kw4">string</span> TryDoWork<span class="br0">&#40;</span><span class="kw4">string</span> file, WorkflowType workflowType<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; IParser&lt;PENDING_PROCESSING&gt; parser = 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>IParser&lt;PENDING_PROCESSING&gt;<span class="br0">&#41;</span>domain.<span class="me1">CreateInstanceAndUnwrap</span><span class="br0">&#40;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;Sandbox.Interface&quot;</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;Sandbox.Interface.Parser&quot;</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">true</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BindingFlags.<span class="me1">CreateInstance</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">null</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> <span class="kw4">object</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="br0">&#123;</span> <span class="st0">&quot;&quot;</span>, <span class="st0">&quot;&quot;</span> <span class="br0">&#125;</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">null</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">null</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">null</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; List&lt;PENDING_PROCESSING&gt; ldr = parser.<span class="me1">Get_PENDING_PROCESSING_List</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> file;
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>After the remote object has processed the job and the asynchronous method has called back, we&#8217;ll update the job list and mark the job completed and also go and check out the job queue to see if there are any more jobs to dequeue.</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">void</span> CallBackTryDoWork<span class="br0">&#40;</span>IAsyncResult result<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; AsyncTryDoWork asyncTryDoWork = <span class="br0">&#40;</span>AsyncTryDoWork<span class="br0">&#41;</span>result.<span class="me1">AsyncState</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> file = asyncTryDoWork.<span class="me1">EndInvoke</span><span class="br0">&#40;</span>result<span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">lock</span> <span class="br0">&#40;</span>lockItem<span class="br0">&#41;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TrackerList.<span class="kw1">ForEach</span><span class="br0">&#40;</span>t =&gt; <span class="br0">&#123;</span> <span class="kw1">if</span> <span class="br0">&#40;</span>t.<span class="me1">FileName</span> == file<span class="br0">&#41;</span> <span class="br0">&#123;</span> t.<span class="me1">Archived</span> = <span class="kw1">true</span>; <span class="br0">&#125;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LookForWork<span class="br0">&#40;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span>

<span class="kw1">void</span> LookForWork<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">lock</span> <span class="br0">&#40;</span>lockItem<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>queue.<span class="me1">Count</span> &gt; <span class="nu0">0</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uploadResetEventList.<span class="me1">Add</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> AutoResetEvent<span class="br0">&#40;</span><span class="kw1">false</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">string</span> file = queue.<span class="me1">Dequeue</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;StartOneWork<span class="br0">&#40;</span>file, WorkflowType.<span class="me1">Upload</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> AsyncTryDoWork<span class="br0">&#40;</span>TryDoWork<span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>!TrackerList.<span class="me1">Exists</span><span class="br0">&#40;</span> t =&gt; <span class="br0">&#123;</span> <span class="kw1">return</span> t.<span class="me1">Archived</span> == <span class="kw1">false</span>; <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WorkIsDoneEventArgs e = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> WorkIsDoneEventArgs<span class="br0">&#40;</span><span class="kw1">true</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OnWorkIsDone<span class="br0">&#40;</span>e<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> &nbsp;
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>Finally, when all jobs have been dequeued and there are no jobs to process, we&#8217;ll signal the main application to unload the new AppDomain.</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">public</span> <span class="kw4">class</span> WorkIsDoneEventArgs : EventArgs
<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">bool</span> _Completed = <span class="kw1">false</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">bool</span> Completed <span class="br0">&#123;</span> get <span class="br0">&#123;</span> <span class="kw1">return</span> _Completed; <span class="br0">&#125;</span> set <span class="br0">&#123;</span> _Completed = value; <span class="br0">&#125;</span> <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> WorkIsDoneEventArgs<span class="br0">&#40;</span><span class="kw4">bool</span> completed<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">this</span>.<span class="me1">Completed</span> = completed; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>

<span class="kw1">public</span> <span class="kw4">delegate</span> <span class="kw1">void</span> WorkIsDoneEventHandler<span class="br0">&#40;</span><span class="kw4">object</span> sender, WorkIsDoneEventArgs e<span class="br0">&#41;</span>;
<span class="kw1">public</span> <span class="kw1">event</span> WorkIsDoneEventHandler workIsDoneEvent;

<span class="kw1">protected</span> <span class="kw1">virtual</span> <span class="kw1">void</span> OnWorkIsDone<span class="br0">&#40;</span>WorkIsDoneEventArgs e<span class="br0">&#41;</span> 
<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; WorkIsDoneEventHandler handler = workIsDoneEvent;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>handler != <span class="kw1">null</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; handler<span class="br0">&#40;</span><span class="kw1">this</span>, e<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AppDomain.<span class="me1">Unload</span><span class="br0">&#40;</span>domain<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>The completed code looks like this.</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw4">interface</span> IParser&lt;T&gt; where T : <span class="kw4">class</span> 
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw1">void</span> Set_PENDING_PROCESSING_List<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; List&lt;T&gt; Get_PENDING_PROCESSING_List<span class="br0">&#40;</span><span class="br0">&#41;</span>; &nbsp; &nbsp; &nbsp; &nbsp;
<span class="br0">&#125;</span>

<span class="kw1">public</span> <span class="kw4">class</span> Parser: MarshalByRefObject, IParser&lt;PENDING_PROCESSING&gt; 
<span class="br0">&#123;</span>

&nbsp; &nbsp; List&lt;PENDING_PROCESSING&gt; _pending_processing_list = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> List&lt;PENDING_PROCESSING&gt;<span class="br0">&#40;</span><span class="br0">&#41;</span>;

&nbsp; &nbsp; <span class="kw1">public</span> Parser<span class="br0">&#40;</span><span class="kw4">string</span> uploadPath, <span class="kw4">string</span> file<span class="br0">&#41;</span> 
&nbsp; &nbsp; <span class="br0">&#123;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Set_PENDING_PROCESSING_List<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw1">void</span> Set_PENDING_PROCESSING_List<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; Thread.<span class="me1">Sleep</span><span class="br0">&#40;</span><span class="nu0">5000</span><span class="br0">&#41;</span>; &nbsp;<span class="co1">//TODO: actually implement some work here.</span>
&nbsp; &nbsp; <span class="br0">&#125;</span> 

&nbsp; &nbsp; <span class="kw1">public</span> List&lt;PENDING_PROCESSING&gt; Get_PENDING_PROCESSING_List<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> _pending_processing_list;
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>


<span class="kw1">public</span> <span class="kw4">class</span> FileController 
<span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">enum</span> WorkflowType 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Upload,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Archive
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">class</span> Tracker
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> Tracker<span class="br0">&#40;</span><span class="kw4">string</span> fileName, <span class="kw4">bool</span> archived<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">this</span>.<span class="me1">FileName</span> = fileName; <span class="kw1">this</span>.<span class="me1">Archived</span> = archived; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">string</span> FileName <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">bool</span> Archived <span class="br0">&#123;</span> get; set; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">class</span> WorkIsDoneEventArgs : EventArgs
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">bool</span> _Completed = <span class="kw1">false</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">bool</span> Completed <span class="br0">&#123;</span> get <span class="br0">&#123;</span> <span class="kw1">return</span> _Completed; <span class="br0">&#125;</span> set <span class="br0">&#123;</span> _Completed = value; <span class="br0">&#125;</span> <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> WorkIsDoneEventArgs<span class="br0">&#40;</span><span class="kw4">bool</span> completed<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">this</span>.<span class="me1">Completed</span> = completed; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">delegate</span> <span class="kw1">void</span> WorkIsDoneEventHandler<span class="br0">&#40;</span><span class="kw4">object</span> sender, WorkIsDoneEventArgs e<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <span class="kw1">event</span> WorkIsDoneEventHandler workIsDoneEvent;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">delegate</span> <span class="kw4">string</span> AsyncTryDoWork<span class="br0">&#40;</span><span class="kw4">string</span> file, WorkflowType workflowType<span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> THREAD_POOL_SIZE = <span class="nu0">5</span>;
&nbsp; &nbsp; &nbsp; Queue&lt;string&gt; queue = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Queue&lt;string&gt;<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; List&lt;Tracker&gt; TrackerList = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> List&lt;Tracker&gt;<span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File1.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File2.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File3.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File4.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File5.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File6.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File7.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File8.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File9.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File10.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span>,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Tracker<span class="br0">&#40;</span><span class="st0">&quot;File11.txt&quot;</span>,<span class="kw1">false</span><span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; <span class="kw1">readonly</span> <span class="kw4">object</span> lockItem = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> <span class="kw4">object</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; AppDomain domain = <span class="kw1">null</span>;

&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">public</span> FileController<span class="br0">&#40;</span><span class="br0">&#41;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CreateSandBox<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; QueueWork<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">void</span> CreateSandBox<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>AppDomain.<span class="me1">CurrentDomain</span>.<span class="me1">FriendlyName</span> != <span class="st0">&quot;SandBoxAppDomain&quot;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; domain = AppDomain.<span class="me1">CreateDomain</span><span class="br0">&#40;</span><span class="st0">&quot;SandBoxAppDomain&quot;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; domain.<span class="me1">ProcessExit</span> += <span class="kw4">delegate</span> <span class="br0">&#123;</span> Console.<span class="me1">WriteLine</span><span class="br0">&#40;</span><span class="st0">&quot;Process has exited.&quot;</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; domain.<span class="me1">DomainUnload</span> += <span class="kw4">delegate</span> <span class="br0">&#123;</span> Console.<span class="me1">WriteLine</span><span class="br0">&#40;</span><span class="st0">&quot;Domain unloading.&quot;</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span>;
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">void</span> QueueWork<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span>Tracker tracker <span class="kw1">in</span> TrackerList<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; queue.<span class="me1">Enqueue</span><span class="br0">&#40;</span>tracker.<span class="me1">FileName</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> NumberToQueue = queue.<span class="me1">Count</span> &lt; THREAD_POOL_SIZE ? queue.<span class="me1">Count</span> : THREAD_POOL_SIZE;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">lock</span> <span class="br0">&#40;</span>lockItem<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">int</span> assignment = <span class="nu0">0</span>; assignment &lt; NumberToQueue; assignment++<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> file = queue.<span class="me1">Dequeue</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StartOneWork<span class="br0">&#40;</span>file, WorkflowType.<span class="me1">Upload</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> AsyncTryDoWork<span class="br0">&#40;</span>TryDoWork<span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> TryDoWork<span class="br0">&#40;</span><span class="kw4">string</span> file, WorkflowType workflowType<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IParser&lt;PENDING_PROCESSING&gt; parser = 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>IParser&lt;PENDING_PROCESSING&gt;<span class="br0">&#41;</span>domain.<span class="me1">CreateInstanceAndUnwrap</span><span class="br0">&#40;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;Sandbox.Interface&quot;</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;Sandbox.Interface.Parser&quot;</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">true</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BindingFlags.<span class="me1">CreateInstance</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">null</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> <span class="kw4">object</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="br0">&#123;</span> <span class="st0">&quot;&quot;</span>, <span class="st0">&quot;&quot;</span> <span class="br0">&#125;</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">null</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">null</span>, 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">null</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List&lt;PENDING_PROCESSING&gt; ldr = parser.<span class="me1">Get_PENDING_PROCESSING_List</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> file;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">void</span> StartOneWork<span class="br0">&#40;</span><span class="kw4">string</span> file, WorkflowType workflowType, AsyncTryDoWork asyncTryDoWork<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">lock</span> <span class="br0">&#40;</span>lockItem<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; asyncTryDoWork.<span class="me1">BeginInvoke</span><span class="br0">&#40;</span>file, workflowType, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> AsyncCallback<span class="br0">&#40;</span>CallBackTryDoWork<span class="br0">&#41;</span>, asyncTryDoWork<span class="br0">&#41;</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">void</span> CallBackTryDoWork<span class="br0">&#40;</span>IAsyncResult result<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AsyncTryDoWork asyncTryDoWork = <span class="br0">&#40;</span>AsyncTryDoWork<span class="br0">&#41;</span>result.<span class="me1">AsyncState</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> file = asyncTryDoWork.<span class="me1">EndInvoke</span><span class="br0">&#40;</span>result<span class="br0">&#41;</span>;

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">lock</span> <span class="br0">&#40;</span>lockItem<span class="br0">&#41;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TrackerList.<span class="kw1">ForEach</span><span class="br0">&#40;</span>t =&gt; <span class="br0">&#123;</span> <span class="kw1">if</span> <span class="br0">&#40;</span>t.<span class="me1">FileName</span> == file<span class="br0">&#41;</span> <span class="br0">&#123;</span> t.<span class="me1">Archived</span> = <span class="kw1">true</span>; <span class="br0">&#125;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LookForWork<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">void</span> LookForWork<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">lock</span> <span class="br0">&#40;</span>lockItem<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>queue.<span class="me1">Count</span> &gt; <span class="nu0">0</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uploadResetEventList.<span class="me1">Add</span><span class="br0">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> AutoResetEvent<span class="br0">&#40;</span><span class="kw1">false</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">string</span> file = queue.<span class="me1">Dequeue</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StartOneWork<span class="br0">&#40;</span>file, WorkflowType.<span class="me1">Upload</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> AsyncTryDoWork<span class="br0">&#40;</span>TryDoWork<span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!TrackerList.<span class="me1">Exists</span><span class="br0">&#40;</span>t =&gt; <span class="br0">&#123;</span> <span class="kw1">return</span> t.<span class="me1">Archived</span> == <span class="kw1">false</span>; <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WorkIsDoneEventArgs e = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> WorkIsDoneEventArgs<span class="br0">&#40;</span><span class="kw1">true</span><span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OnWorkIsDone<span class="br0">&#40;</span>e<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">protected</span> <span class="kw1">virtual</span> <span class="kw1">void</span> OnWorkIsDone<span class="br0">&#40;</span>WorkIsDoneEventArgs e<span class="br0">&#41;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WorkIsDoneEventHandler handler = workIsDoneEvent;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>handler != <span class="kw1">null</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; handler<span class="br0">&#40;</span><span class="kw1">this</span>, e<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AppDomain.<span class="me1">Unload</span><span class="br0">&#40;</span>domain<span class="br0">&#41;</span>;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>

<span class="br0">&#125;</span></div>
</div>
</pre>
<p>Now let&#8217;s run the application and monitor the results.</p>
<pre>
<div class="codesnip-container" >3/14/2009 5:39:13 PM - File Controller in MainDomain is Thread Id: 11
3/14/2009 5:39:13 PM - SandboxDomain has been created
3/14/2009 5:39:14 PM - File Controller in MainAppDomain. obtained Thread Id: 7
3/14/2009 5:39:14 PM - Thread 7 created Parser for File1.txt in SandBoxAppDomain.
3/14/2009 5:39:14 PM - File Controller in MainAppDomain. obtained Thread Id: 3
3/14/2009 5:39:14 PM - Thread 3 created Parser for File2.txt in SandBoxAppDomain.
3/14/2009 5:39:15 PM - File Controller in MainAppDomain. obtained Thread Id: 13
3/14/2009 5:39:15 PM - Thread 13 created Parser for File3.txt in SandBoxAppDomain.
3/14/2009 5:39:15 PM - File Controller in MainAppDomain. obtained Thread Id: 14
3/14/2009 5:39:15 PM - Thread 14 created Parser for File4.txt in SandBoxAppDomain.
3/14/2009 5:39:16 PM - File Controller in MainAppDomain. obtained Thread Id: 15
3/14/2009 5:39:16 PM - Thread 15 created Parser for File5.txt in SandBoxAppDomain.
3/14/2009 5:39:19 PM - Thread3 obtained result from Parser for File2.txt in SandBoxAppDomain.
3/14/2009 5:39:19 PM - Thread7 obtained result from Parser for File1.txt in SandBoxAppDomain.
3/14/2009 5:39:19 PM - Thread Id 3 picked up File6.txt from queue.
3/14/2009 5:39:19 PM - File Controller in MainAppDomain. obtained Thread Id: 3
3/14/2009 5:39:19 PM - Thread 3 created Parser for File6.txt in SandBoxAppDomain.
3/14/2009 5:39:19 PM - Thread Id 7 picked up File7.txt from queue.
3/14/2009 5:39:19 PM - File Controller in MainAppDomain. obtained Thread Id: 7
3/14/2009 5:39:19 PM - Thread 7 created Parser for File7.txt in SandBoxAppDomain.
3/14/2009 5:39:20 PM - Thread13 obtained result from Parser for File3.txt in SandBoxAppDomain.
3/14/2009 5:39:20 PM - Thread Id 13 picked up File8.txt from queue.
3/14/2009 5:39:20 PM - File Controller in MainAppDomain. obtained Thread Id: 13
3/14/2009 5:39:20 PM - Thread 13 created Parser for File8.txt in SandBoxAppDomain.
3/14/2009 5:39:20 PM - Thread14 obtained result from Parser for File4.txt in SandBoxAppDomain.
3/14/2009 5:39:20 PM - Thread Id 14 picked up File9.txt from queue.
3/14/2009 5:39:20 PM - File Controller in MainAppDomain. obtained Thread Id: 14
3/14/2009 5:39:20 PM - Thread 14 created Parser for File9.txt in SandBoxAppDomain.
3/14/2009 5:39:21 PM - Thread15 obtained result from Parser for File5.txt in SandBoxAppDomain.
3/14/2009 5:39:21 PM - Thread Id 15 picked up File10.txt from queue.
3/14/2009 5:39:21 PM - File Controller in MainAppDomain. obtained Thread Id: 15
3/14/2009 5:39:21 PM - Thread 15 created Parser for File10.txt in SandBoxAppDomain.
3/14/2009 5:39:24 PM - Thread3 obtained result from Parser for File6.txt in SandBoxAppDomain.
3/14/2009 5:39:24 PM - Thread Id 3 picked up File11.txt from queue.
3/14/2009 5:39:24 PM - Thread7 obtained result from Parser for File7.txt in SandBoxAppDomain.
3/14/2009 5:39:24 PM - File Controller in MainAppDomain. obtained Thread Id: 3
3/14/2009 5:39:24 PM - Thread 3 created Parser for File11.txt in SandBoxAppDomain.
3/14/2009 5:39:25 PM - Thread13 obtained result from Parser for File8.txt in SandBoxAppDomain.
3/14/2009 5:39:25 PM - Thread14 obtained result from Parser for File9.txt in SandBoxAppDomain.
3/14/2009 5:39:26 PM - Thread15 obtained result from Parser for File10.txt in SandBoxAppDomain.
3/14/2009 5:39:29 PM - Thread3 obtained result from Parser for File11.txt in SandBoxAppDomain.
3/14/2009 5:39:29 PM - SandboxDomain has been unloaded.</div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://eztier.com/dba2day/?feed=rss2&amp;p=87</wfw:commentRss>
		</item>
	</channel>
</rss>

