<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0">
  <channel>
    <title>Dutch TechEd 2005 Bloggers</title>
    <description>Dutch TechEd 2005 Bloggers</description>
    <link>http://www3.devtips.net/services/rss.aspx</link>
    <lastBuildDate>Mon, 06 Oct 2008 12:13:00 GMT</lastBuildDate>
    <docs>http://backend.userland.com/rss</docs>
    <generator>RSS.NET: http://www.rssdotnet.com/</generator>
    <item>
      <title>LINQ to XML instead of XPath</title>
      <description>&lt;P&gt;Working on a new project, I needed to read some elements from an XML file. As a matter of habit, I used XPath, but later I figured this was a good opportunity to try it out using LINQ. So here goes.&lt;/P&gt;
&lt;P&gt;The XML source is a file, stored as Resources.xml with the following contents.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&amp;lt;?&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;xml&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;version&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;1.0&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;encoding&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;utf-8&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; ?&amp;gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;resources&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;culture&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;code&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;en-US&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;resource&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;key&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;MetaData.Description&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;value&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: red"&gt;&amp;amp;quot;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Realtime data on ... !&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;&amp;amp;quot;&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;resource&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;key&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;MetaData.Keywords&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;value&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: red"&gt;&amp;amp;quot;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;images, keyword1, keyword2, keyword3&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;&amp;amp;quot;&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;resource&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;key&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;Homepage.Title&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;value&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;just a random title&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;culture&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;culture&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;code&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;nl-NL&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;resource&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;key&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;MetaData.Description&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;value&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: red"&gt;&amp;amp;quot;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Realtime beelden ...&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;&amp;amp;quot;&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;resource&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;key&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;MetaData.Keywords&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;value&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: red"&gt;&amp;amp;quot;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;beelden, plaatjes, etc.&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;&amp;amp;quot;&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;resource&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;key&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;Homepage.Title&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;value&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;Een willekeurige titel&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;culture&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;culture&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;code&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;fr-FR&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;...&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;culture&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: #a31515; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;resources&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;The relevant data is in the value-attribute. The input parameters is &lt;STRONG&gt;culture&lt;/STRONG&gt; of type CultureInfo and &lt;STRONG&gt;resourceKey&lt;/STRONG&gt; of type string. &lt;STRONG&gt;resourceFile&lt;/STRONG&gt; holds the path to the XML file. &lt;/P&gt;
&lt;P&gt;The XPath version of getting to that data is this:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #2b91af; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;XmlDocument&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; resourceXml = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;XmlDocument&lt;/SPAN&gt;();&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;resourceXml.Load(resourceFile);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;string&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; xpathQuery = &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;.Format(&lt;SPAN style="COLOR: #a31515"&gt;"//culture[@code='{0}']/resource[@key='{1}']"&lt;/SPAN&gt;, culture.Name, resourceKey);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #2b91af; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;XmlNode&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; resourceElement = resourceXml.SelectSingleNode(xpathQuery);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;if&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; (resourceElement != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;) resourceValue = resourceElement.Attributes[&lt;SPAN style="COLOR: #a31515"&gt;"value"&lt;/SPAN&gt;].InnerText;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;
&lt;P&gt;Using LINQ to XML we can use the following snippet:&lt;/P&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #2b91af; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;XDocument&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; xdoc = &lt;SPAN style="COLOR: #2b91af"&gt;XDocument&lt;/SPAN&gt;.Load(resourceFile);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;var&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; q = &lt;SPAN style="COLOR: blue"&gt;from&lt;/SPAN&gt; c &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; xdoc.Descendants(&lt;SPAN style="COLOR: #a31515"&gt;"culture"&lt;/SPAN&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 35.4pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;where&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; c.Attribute(&lt;SPAN style="COLOR: #a31515"&gt;"code"&lt;/SPAN&gt;).Value == culture.Name&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;from&lt;/SPAN&gt; r &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; c.Descendants(&lt;SPAN style="COLOR: #a31515"&gt;"resource"&lt;/SPAN&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;where&lt;/SPAN&gt; r.Attribute(&lt;SPAN style="COLOR: #a31515"&gt;"key"&lt;/SPAN&gt;).Value == resourceKey&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;select&lt;/SPAN&gt; r.Attribute(&lt;SPAN style="COLOR: #a31515"&gt;"value"&lt;/SPAN&gt;).Value;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;if&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; (q.Count&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;gt;() == 1) resourceValue = q.First&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;
&lt;P&gt;Either version works fine. The only issue is that LINQ is supposed to help the developer by IntelliSense and strong typing. Unfortunately, that doesn't happen here, at least not with the&amp;nbsp;elements in the XML file. &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;/P&gt;&lt;img src ="http://todotnet.com/aggbug/11365.aspx" width = "1" height = "1" /&gt;</description>
      <link>http://todotnet.com/archive/2008/10/06/11365.aspx</link>
      <author>Sander Gerz</author>
      <pubDate>Mon, 06 Oct 2008 12:13:00 GMT</pubDate>
    </item>
    <item>
      <title>October 2nd Links: ASP.NET, ASP.NET MVC, ASP.NET Dynamic Data</title>
      <description>&lt;font size="2" face="arial"&gt;   &lt;p&gt;Here is the latest in my &lt;a target="_blank" href="http://weblogs.asp.net/scottgu/archive/2008/05/20/may-20th-links-asp-net-asp-net-ajax-net-visual-studio-silverlight-wpf.aspx"&gt;link-listing series&lt;/a&gt;.&amp;#160; Also check out my &lt;a target="_blank" href="http://weblogs.asp.net/scottgu/pages/ASP.NET-2.0-Tips_2C00_-Tricks_2C00_-Recipes-and-Gotchas.aspx"&gt;ASP.NET Tips, Tricks and Tutorials page&lt;/a&gt; and &lt;a target="_blank" href="http://weblogs.asp.net/scottgu/pages/silverlight-posts.aspx"&gt;Silverlight Tutorials page&lt;/a&gt; for links to popular articles I've done myself in the past.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;ASP.NET&lt;/u&gt;&lt;/h3&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a target="_blank" href="http://aws.typepad.com/aws/2008/10/coming-soon-ama.html"&gt;Amazon EC2 Support for Windows and ASP.NET:&lt;/a&gt; Big news announced this week: Amazon will be offering Windows Server 2008 as an option in their EC2 service.&amp;#160; This enables you to use ASP.NET, IIS7 and SQL Server in the cloud.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a target="_blank" href="http://www.hanselman.com/blog/PlugInHybridsASPNETWebFormsAndASPMVCAndASPNETDynamicDataSideBySide.aspx"&gt;Using ASP.NET WebForms, MVC and Dynamic Data in a Single Application&lt;/a&gt;: Scott Hanselman has a nice post that demonstrates how you can have a single ASP.NET application that uses ASP.NET WebForms, MVC, WebServices and Dynamic Data.&amp;#160; You have the flexibility to mix and match them however you want, which allows you to always use the right tool depending on the specific job.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a target="_blank" href="http://mattberseth.com/blog/2008/05/modifying_data_with_the_listvi.html"&gt;Modifying Data with the ListView's EditItemTemplate&lt;/a&gt;: Matt Berseth has a great post that talks about how to use the ASP.NET 3.5 ListView control to enable in-place editing scenarios - with total html markup control.&amp;#160; &lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a target="_blank" href="http://mattberseth.com/blog/2008/06/4_new_grouping_grid_skins_vist.html"&gt;4 New Grouping Grid Skins: Vista, Bold, Win2k3 and Soft&lt;/a&gt;: Matt Berseth has another nice post that demonstrates how to skin the ASP.NET ListView control to enable some sweet data grouping scenarios.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a target="_blank" href="http://www.asp.net/learn/security/tutorial-14-vb.aspx"&gt;Unlocking and Approving User Accounts&lt;/a&gt;: Scott Mitchell posts another in his great series of articles on ASP.NET security (&lt;a target="_blank" href="http://www.asp.net/learn/security/"&gt;click here&lt;/a&gt; for all the articles in the series).&amp;#160; This article talks about how you can setup administration pages that allow admins to lock out and approve user accounts using the ASP.NET Membership system.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a target="_blank" href="http://danhounshell.com/blogs/dan/archive/2008/07/18/adding-openid-to-your-web-site-in-conjunction-with-asp-net-membership.aspx"&gt;Adding OpenID to you website in conjunction to ASP.NET Membership&lt;/a&gt;: Dan Hounshell has a nice article that discusses how to add OpenID authentication support to your web-site, and use it in conjunction to ASP.NET's built-in membership system.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;h3&gt;&lt;u&gt;ASP.NET MVC&lt;/u&gt;&lt;/h3&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a target="_blank" href="http://www.squaredroot.com/post/2008/09/06/MVC-Membership-Preview-5.aspx"&gt;MVC Membership with Preview 5&lt;/a&gt;: Troy Goode posts an update of his popular MVC Membership template that works with ASP.NET MVC Preview 5.&amp;#160; It provides a set of administration pages you can use for user/role management, as well as adds support for OpenID and Windows LiveID.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a target="_blank" href="http://weblogs.asp.net/mehfuzh/archive/2008/05/27/flickr-viewer-an-asp-net-mvc-photo-app-for-flickr.aspx"&gt;MVC Flickr Xplorer&lt;/a&gt;: Mehfuz Hossain has a cool ASP.NET MVC sample application posted that enables a nice picture explorer for FlickR photos.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;h3&gt;&lt;u&gt;ASP.NET Dynamic Data&lt;/u&gt;&lt;/h3&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a target="_blank" href="http://mattberseth.com/blog/2008/08/aspnet_dynamic_data_simple_5_t.html"&gt;Simple 5 Table Northwind Example&lt;/a&gt;: Matt Berseth kicks off his ASP.NET Dynamic Data tutorial series with a nice post that shows how to build a simple 5 table application using ASP.NET Dynamic Data with .NET 3.5 SP1.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a target="_blank" href="http://mattberseth.com/blog/2008/08/dynamic_data_and_custom_metada.html"&gt;Dynamic Data And Custom Metadata Providers&lt;/a&gt;: Matt continues the series and covers the MetadataType attribute, and how you can use it to annotate your entities with additional metadata.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a target="_blank" href="http://mattberseth.com/blog/2008/08/a_dynamic_menu_for_your_dynami.html"&gt;Dynamic Menu for your Dynamic Data:&lt;/a&gt; Matt continues and covers how to add a data-driven menu to the site.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a target="_blank" href="http://mattberseth.com/blog/2008/09/dynamic_data_customizing_the_d.html"&gt;Customizing the Delete Confirmation Dialog&lt;/a&gt;: Matt continues and demonstrates how to build a nice UI experience when deleting records in a dynamic data application.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a target="_blank" href="http://mattberseth.com/blog/2008/09/dynamic_data_experimenting_wit.html"&gt;Experimenting with YUI's DataTable and DataSource Controls&lt;/a&gt;: Matt experiments with how to use client-side AJAX components together with dynamic data.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;Hope this helps,&lt;/p&gt;    &lt;p&gt;Scott&lt;/p&gt; &lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6652294" width="1" height="1"&gt;</description>
      <link>http://weblogs.asp.net/scottgu/archive/2008/10/02/october-2nd-links-asp-net-asp-net-mvc-asp-net-dynamic-data.aspx</link>
      <author>ScottGu</author>
      <pubDate>Thu, 02 Oct 2008 10:23:21 GMT</pubDate>
    </item>
    <item>
      <title>MVP Visual Developer C#, I feel great!</title>
      <description>&lt;p&gt;Gisteren, 1 oktober, was weer een spannende dag. De dag waarop ik te horen zou krijgen of ik me weer een vol jaar Microsoft Most Valuable Professional mocht noemen. En ja hoor, om 4 uur 's middags (wat kan zo'n dag lang duren zeg...) kreeg ik het verlossende mailtje: Congratulations!&lt;/p&gt;  &lt;p&gt;Even een impressie van hoe ik de rest van de dag op kantoor rond liep: &lt;a target="_blank" href="http://www.youtube.com/watch?v=lQ7goW7oFO8"&gt;bekijk dit filmpje&lt;/a&gt; Nou ja, niet helemaal zo, maar toch wel een beetje.&lt;/p&gt;  &lt;p&gt;Dat betekent dat ik weer een jaar lang aangewezen bent om je te helpen met alle vragen die je mocht hebben op gebied van .net ontwikkelingen!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=907" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/10/02/907.aspx</link>
      <author>dvroegop</author>
      <pubDate>Thu, 02 Oct 2008 09:14:53 GMT</pubDate>
    </item>
    <item>
      <title>jQuery and Microsoft</title>
      <description>&lt;font size="2" face="arial"&gt;   &lt;p&gt;&lt;a target="_blank" href="http://jquery.com/"&gt;jQuery&lt;/a&gt; is a lightweight open source JavaScript library (only 15kb in size) that in a relatively short span of time has become one of the most popular libraries on the web.&lt;/p&gt;    &lt;p&gt;A big part of the appeal of jQuery is that it allows you to elegantly (and efficiently) find and manipulate HTML elements with minimum lines of code.&amp;#160; jQuery supports this via a nice &amp;quot;selector&amp;quot; API that allows developers to query for HTML elements, and then apply &amp;quot;commands&amp;quot; to them.&amp;#160; One of the characteristics of jQuery commands is that they can be &amp;quot;chained&amp;quot; together - so that the result of one command can feed into another.&amp;#160; jQuery also includes a built-in set of animation APIs that can be used as commands.&amp;#160; The combination allows you to do some really cool things with only a few keystrokes.&lt;/p&gt;    &lt;p&gt;For example, the below JavaScript uses jQuery to find all &amp;lt;div&amp;gt; elements within a page that have a CSS class of &amp;quot;product&amp;quot;, and then animate them to slowly disappear:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/jquery/step1.png" /&gt; &lt;/p&gt;    &lt;p&gt;As another example, the JavaScript below uses jQuery to find a specific &amp;lt;table&amp;gt; on the page with an id of &amp;quot;datagrid1&amp;quot;, then retrieves every other &amp;lt;tr&amp;gt; row within the datagrid, and sets those &amp;lt;tr&amp;gt; elements to have a CSS class of &amp;quot;even&amp;quot; - which could be used to alternate the background color of each row:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/jquery/step2.png" /&gt; &lt;/p&gt;    &lt;p&gt;&lt;em&gt;[Note: both of these samples were adapted from code snippets in the excellent &lt;a target="_blank" href="http://www.amazon.com/gp/product/1933988355/102-4745100-5076967?ie=UTF8&amp;amp;tag=scoblo04-20&amp;amp;linkCode=xm2&amp;amp;camp=1789&amp;amp;creativeASIN=1933988355"&gt;jQuery in Action&lt;/a&gt; book]&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;Providing the ability to perform selection and animation operations like above is something that a lot of developers have asked us to add to ASP.NET AJAX, and this support was something we listed as a proposed feature in the &lt;a target="_blank" href="http://weblogs.asp.net/bleroy/archive/2008/07/02/asp-net-ajax-roadmap-published.aspx"&gt;ASP.NET AJAX Roadmap&lt;/a&gt; we published a few months ago.&amp;#160; As the team started to investigate building it, though, they quickly realized that the jQuery support for these scenarios is already excellent, and that there is a huge ecosystem and community built up around it already.&amp;#160; The jQuery library also works well on the same page with ASP.NET AJAX and the ASP.NET AJAX Control Toolkit.&lt;/p&gt;    &lt;p&gt;Rather than duplicate functionality, we thought, wouldn't it be great to just use jQuery as-is, and add it as a standard, supported, library in VS/ASP.NET, and then focus our energy building new features that took advantage of it?&amp;#160; We sent mail the jQuery team to gauge their interest in this, and quickly heard back that they thought that it sounded like an interesting idea too.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Supporting jQuery&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;I'm excited today to announce that Microsoft will be shipping jQuery with Visual Studio going forward.&amp;#160; We will distribute the jQuery JavaScript library as-is, and will not be forking or changing the source from the main jQuery branch.&amp;#160; The files will continue to use and ship under the existing jQuery MIT license.&lt;/p&gt;    &lt;p&gt;We will also distribute intellisense-annotated versions that provide great Visual Studio intellisense and help-integration at design-time.&amp;#160; For example:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/jquery/step3.png" /&gt; &lt;/p&gt;    &lt;p&gt;and with a chained command:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/jquery/step4.png" /&gt; &lt;/p&gt;    &lt;p&gt;The jQuery intellisense annotation support will be available as a free web-download in a few weeks (and will work great with VS 2008 SP1 and the free Visual Web Developer 2008 Express SP1).&amp;#160; The new ASP.NET MVC download will also distribute it, and add the jQuery library by default to all new projects.&lt;/p&gt;    &lt;p&gt;We will also extend Microsoft product support to jQuery beginning later this year, which will enable developers and enterprises to call and open jQuery support cases 24x7 with Microsoft PSS.&lt;/p&gt;    &lt;p&gt;Going forward we'll use jQuery as one of the libraries used to implement higher-level controls in the ASP.NET AJAX Control Toolkit, as well as to implement new Ajax server-side helper methods for ASP.NET MVC.&amp;#160; New features we add to ASP.NET AJAX (like the new &lt;a target="_blank" href="http://weblogs.asp.net/bleroy/archive/2008/09/16/javascript-and-client-templates-on-hanselminutes.aspx"&gt;client&lt;/a&gt; &lt;a target="_blank" href="http://weblogs.asp.net/bleroy/archive/2008/07/30/using-client-templates-part-1.aspx"&gt;template&lt;/a&gt; &lt;a target="_blank" href="http://weblogs.asp.net/bleroy/archive/2008/09/02/using-client-templates-part-2-live-bindings.aspx"&gt;support&lt;/a&gt;) will be designed to integrate nicely with jQuery as well.&amp;#160; &lt;/p&gt;    &lt;p&gt;We also plan to contribute tests, bug fixes, and patches back to the jQuery open source project.&amp;#160; These will all go through the standard jQuery patch review process.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Summary&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;We are really excited to be able to partner with the jQuery team on this.&amp;#160; jQuery is a fantastic library, and something we think can really benefit ASP.NET and ASP.NET AJAX developers.&amp;#160; We are looking forward to having it work great with Visual Studio and ASP.NET, and to help bring it to an even larger set of developers.&lt;/p&gt;    &lt;p&gt;For more details on today's announcement, please check out &lt;a target="_blank" href="http://jquery.com/blog/2008/09/28/jquery-microsoft-nokia/"&gt;John Resig's post&lt;/a&gt; on the jQuery team blog.&amp;#160; Scott Hanselman is also about to post a &lt;a target="_blank" href="http://www.hanselman.com/blog/jQuerytoshipwithASPNETMVCandVisualStudio.aspx"&gt;nice tutorial&lt;/a&gt; that shows off integrating jQuery with ASP.NET AJAX (including the new client templating engine) as well as ADO.NET Data Services (which shipped in .NET 3.5 SP1 and was previously code-named &amp;quot;Astoria&amp;quot;).&lt;/p&gt;    &lt;p&gt;Hope this helps,&lt;/p&gt;    &lt;p&gt;Scott&lt;/p&gt; &lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6645594" width="1" height="1"&gt;</description>
      <link>http://weblogs.asp.net/scottgu/archive/2008/09/28/jquery-and-microsoft.aspx</link>
      <author>ScottGu</author>
      <pubDate>Sun, 28 Sep 2008 20:32:31 GMT</pubDate>
    </item>
    <item>
      <title>Silverlight 2 Release Candidate Now Available</title>
      <description>&lt;font size="2" face="arial"&gt;   &lt;p&gt;This evening we published the first public release candidate of Silverlight 2.&lt;/p&gt;    &lt;p&gt;There are still a small handful of bugs fixes that we plan to make before we finally ship.&amp;#160; We are releasing today's build, though, so that developers can start to update their existing Silverlight Beta2 applications so that they'll work the day the final release ships, as well as to enable developers to report any last minute showstopper issues that we haven't found internally (please report any of these on the &lt;a target="_blank" href="http://silverlight.net/forums/"&gt;www.silverlight.net&lt;/a&gt; forums).&lt;/p&gt;    &lt;p&gt;Important: We are releasing only the Silverlight Developer Runtime edition (as well as the VS and Blend tools to support it) today, and &lt;u&gt;are not&lt;/u&gt; releasing the regular end-user edition of Silverlight.&amp;#160; This is because we want to give existing developers a short amount of time to update their applications to work with the final Silverlight 2 APIs before sites are allowed to go live with it.&amp;#160; There are some breaking changes between Beta2 and this RC, and we want to make sure that existing sites can update to the final release quickly once the final release is out.&amp;#160; As such, you can only use the RC for development right now - you can't go live with the new APIs until the final release is shipped (which will be soon though).&lt;/p&gt;    &lt;p&gt;You can download today's Silverlight Release Candidate and accompanying VS and Blend support for it &lt;a target="_blank" href="http://silverlight.net/GetStarted/sl2rc0.aspx"&gt;here&lt;/a&gt;.&amp;#160; Note that Expression Blend support for Silverlight 2 is now provided using Blend 2.0 SP1.&amp;#160; You will need to install Blend 2.0 before applying the SP1 service pack that adds Silverlight 2 support.&amp;#160; If you don't already have Blend 2.0 installed you can download a free trial of it &lt;a target="_blank" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=5FF08106-B9F4-43CD-ABAD-4CC9D9C208D7&amp;amp;displaylang=en"&gt;here&lt;/a&gt;.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Beta2-&amp;gt;RC API Updates&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;Today's release candidate includes a ton of bug fix and some significant performance optimization work.&lt;/p&gt;    &lt;p&gt;Today's release candidate also includes a number of final API tweaks designed to fix differences between Silverlight and the full .NET Framework.&amp;#160; Most of these changes are relatively small (order of parameters, renames of methods/properties, movement of types across namespaces, etc) although there are a number of them.&amp;#160; You can read &lt;a target="_blank" href="http://silverlight.net/blogs/msnow/archive/2008/09/25/silverlight-version-2-rc0-release.aspx"&gt;this blog post&lt;/a&gt; and download &lt;a target="_blank" href="http://download.microsoft.com/download/6/F/E/6FE1F43D-9D0C-4346-AD08-602DF9BCB3CF/BreakingChangesBetweenBeta2andRelease.doc"&gt;this document&lt;/a&gt; to get a listing of the known API breaking changes made from the Beta2 release.&amp;#160; &lt;/p&gt;    &lt;p&gt;We have updated the styles of the controls shipped with Silverlight, and have also modified some of the state groups and control template names they use.&amp;#160; When upgrading from Beta2 you might find it useful to temporarily remove any custom style templates you've defined, and get your application functionality working using the RC first - and then after that works add back in the styles one style definition at a time to catch any rename/behavior change issues with them.&lt;/p&gt;    &lt;p&gt;If you find yourself stuck with an question/issue moving from Beta2 to the RC, please report it on the &lt;a target="_blank" href="http://silverlight.net/forums/"&gt;www.silverlight.net&lt;/a&gt; forums (Silverlight team members will be on there helping folks).&amp;#160; If after a day or two you aren't getting an answer please send me email (&lt;a href="mailto:scottgu@microsoft.com"&gt;scottgu@microsoft.com&lt;/a&gt;) and I can help or connect you with someone who knows the answer.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;New Controls&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;Today's release candidate includes a bunch of feature additions and tweaks across Silverlight 2, as well as in the VS and Blend tools targeting it. In general you'll find a number of nice improvements across the controls, networking, data caching, layout, rendering, media stack, and other components and sub-systems.&lt;/p&gt;    &lt;p&gt;Over the next few months we will be releasing a lot of new Silverlight 2 controls (more details on these soon).&amp;#160; Today's release candidate includes three new core controls - ComboBox, ProgressBar, and PasswordBox - that we are adding directly to the core Silverlight runtime download (which is still only 4.6MB in size, and only takes a few seconds to install):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/slrc0/step2.png" /&gt; &lt;/p&gt;    &lt;p&gt;At runtime these controls by default look like:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/slrc0/step1.png" /&gt; &lt;/p&gt;    &lt;p&gt;The ComboBox in Silverlight 2 supports standard DropDownList semantics.&amp;#160; In addition to statically defining items like above, you can also use databinding with it.&amp;#160; For example, we could define a &amp;quot;Person&amp;quot; class like below:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/slrc0/step3.png" /&gt; &lt;/p&gt;    &lt;p&gt;And the add a ComboBox to a page like so:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/slrc0/step22.png" /&gt; &lt;/p&gt;    &lt;p&gt;And then write the below code to databind a collection of Person objects to the ComboBox (by setting its ItemSource property):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/slrc0/step17.png" /&gt; &lt;/p&gt;    &lt;p&gt;At runtime our simple app will then display the data-bound Person names (note that we set the DisplayMemberPath property on the ComboBox above to display the &amp;quot;Name&amp;quot; value from our Person objects):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/slrc0/step6.png" /&gt; &lt;/p&gt;    &lt;p&gt;We could then implement a SelectionChanged event handler like below to run code when a person is selected from the ComboBox:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/slrc0/step18.png" /&gt; &lt;/p&gt;    &lt;p&gt;Notice above how we can retrieve a reference to the selected &amp;quot;Person&amp;quot; object from the databound ComboBox using the ComboBox's &amp;quot;SelectedItem&amp;quot; property.&amp;#160; &lt;/p&gt;    &lt;p&gt;We can then call the MessageBox.Show() helper method (new in the RC) to display a modal dialog box that displays some details about our selected person:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/slrc0/step19.png" /&gt;&amp;#160;&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;New Control Skins&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;The final release of Silverlight 2 will have a much more polished set of default control template skins than those that were in Beta1 and Beta2.&amp;#160; Our goal with the default control templates is to have a look that is professional and attractive, can be used in the majority of applications as-is (without requiring you to author custom style templates), and which is also easily tweakable using Expression Blend.&lt;/p&gt;    &lt;p&gt;Today's RC build has skins that are close to the final look we plan to ship (there are a few final tweaks we are doing post RC on the focus color of controls, as well as to tighten up and tweak a few issues in some of the control templates).&amp;#160; Below is the default look for the DataGrid, RadioButton, CheckBoxes, and the DatePicker controls with today's RC build:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/slrc0/step11.png" /&gt; &lt;/p&gt;    &lt;p&gt;Note that the DatePicker control above allows users to type in a date (with a masked edit to ensure it is a valid date), or they can click the calendar icon to the right of the textbox and select the date using a popup Calendar control:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/slrc0/step12.png" /&gt; &lt;/p&gt;    &lt;p&gt;One of the most powerful features of Silverlight and WPF, of course, is the ability for designers and developers to completely customize the look and feel of any control.&amp;#160; This goes beyond simple styling of colors and fonts - you can literally completely change the visual UI of a control, as well as customize its behavior (for example: add animation) without writing any code.&lt;/p&gt;    &lt;p&gt;Within Expression Blend, simply right-click on any Silverlight control and choose the &amp;quot;Edit Control Parts&amp;quot; sub-menu to open and edit its control template:&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/slrc0/step15.png" /&gt; &lt;/p&gt;    &lt;p&gt;When in control template editing mode, you can manipulate any sub-element of a control (for example: a checkbox's inner content), as well as customize each &amp;quot;state&amp;quot; its in (notice the states pane circled in red below).&amp;#160; This allows designers to customize what the control looks like in individual states (for example: checked, unchecked, mouseover, etc).&amp;#160; Silverlight will then automatically handle animating the control from state to state depending on the user action:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/slrc0/step14.png" /&gt; &lt;/p&gt;    &lt;p&gt;You can learn more about how Silverlight's Visual State Model works from my previous blog post &lt;a target="_blank" href="http://weblogs.asp.net/scottgu/archive/2008/06/06/silverlight-2-beta2-released.aspx"&gt;here&lt;/a&gt;.&amp;#160; &lt;/p&gt;    &lt;p&gt;Previous releases of Silverlight often rendered graphics on sub-pixel locations - which could cause lines and shapes to sometimes appear &amp;quot;fuzzy&amp;quot;.&amp;#160; The RC of Silverlight has a new features called &amp;quot;layout rounding&amp;quot; that causes the layout system to round the final measure of a control to an integer (&amp;quot;pixel snapping&amp;quot;), which results in crisper lines and fewer rendering artifacts.&amp;#160; This feature is now on by default, and helps make applications look nicer.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Summary&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;The final release of Silverlight is not that far off now.&amp;#160; It has been a pretty amazing project that has come a long way in a pretty short amount of time.&lt;/p&gt;    &lt;p&gt;If you have existing Beta2 applications, please start getting them ready for the final release - as once we release Silverlight 2, users that have existing beta releases installed will automatically be upgraded to use the final version.&amp;#160; Testing your application out with the release candidate will ensure that you can easily update your applications and have them ready within hours of the final release.&lt;/p&gt;    &lt;p&gt;Let us know if you find issues with today's release candidate, and please make sure to post them on the forums on &lt;a target="_blank" href="http://silverlight.net/forums/"&gt;http://www.silverlight.net&lt;/a&gt;. &lt;/p&gt;    &lt;p&gt;Hope this helps,&lt;/p&gt;    &lt;p&gt;Scott&lt;/p&gt; &lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6642225" width="1" height="1"&gt;</description>
      <link>http://weblogs.asp.net/scottgu/archive/2008/09/25/silverlight-2-release-candidate-now-available.aspx</link>
      <author>ScottGu</author>
      <pubDate>Fri, 26 Sep 2008 06:54:32 GMT</pubDate>
    </item>
    <item>
      <title>Donderdag 25 september: TFS bij Detrio!</title>
      <description>&lt;p&gt;&lt;a href="http://www.detrio.nl/"&gt;&lt;img style="margin: 10px 10px 10px 0px" align="left" src="http://www.dotned.nl/sponsors/Detrio.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Team Foundation Server is een enorm complex product. Er zitten heel veel haken en ogen aan, voor je het goed aan de praat heb ben je een tijd verder. Maar als het dan ook draait heb je een enorm waardevol stuk gereedschap in handen!&lt;/p&gt;  &lt;p&gt; Nu hebben we bij dotNed al vaker over TFS gesproken, we hebben echter gekozen voor de 'bottom-up' aanpak: we hebben een aantal sessies gehad over bepaalde onderwerpen. Het wordt tijd om nu eens te gaan kijken hoe het overal plaatje er uit ziet. Wat kan TFS? Wat is de toegevoegde waarde voor mijn organisatie? Hoe regel ik mijn projecten nu in? Welke problemen kan ik verwachten als we TFS gaan implementeren?&lt;/p&gt;  &lt;p&gt;Dit soort vragen, en vele anderen zullen worden beantwoord op de dotNed meeting van 25 september. Hassan Fadili, senior developer bij Detrio en bestuurslid van dotNed zal ons een overview geven van TFS met alle mogelijkheden en problemen die er bij horen.&lt;/p&gt;  &lt;p&gt;Hassan is een van de mensen die vanaf het begin met TFS zijn gaan werken. Er zijn maar weinig mensen in Nederland die zijn kennisniveau op dit product hebben, dus als er iemand is die je vragen kan beantwoorden, dan is het Hassan wel.&lt;/p&gt;  &lt;p&gt;Deze avond wordt gesponsord door Detrio Consultancy, een organisatie die &lt;a href="http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/26/870.aspx"&gt;3D rapportage systemen in WPF &lt;/a&gt;bouwt. Uiteraard staan al haar projecten in TFS waardoor ze veel hands-on ervaring heeft opgedaan met deze producten. &lt;/p&gt;  &lt;p&gt;Mocht je dus denken over de implementatie van een TFS server, of heb je er al een draaien en heb je vragen, of wil je gewoon meer weten, dan ben je van harte welkom op 25 september in Utrecht bij deze gratis bijeenkomst!&lt;/p&gt;  &lt;p&gt;We zien je graag op de 25e te Utrecht!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=893" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/09/12/893.aspx</link>
      <author>dvroegop</author>
      <pubDate>Fri, 12 Sep 2008 11:53:35 GMT</pubDate>
    </item>
    <item>
      <title>dotNed meeting 4 september 2008: Project Velocity</title>
      <description>&lt;p&gt;Voor iedereen die bij de meeting van 4 september 2008 aanwezig waren, &lt;a target="_blank" href="http://www.dotned.nl/files/8/ppt/entry891.aspx"&gt;hier&lt;/a&gt; staat de presentatie van Dennis over Project Velocity.&lt;/p&gt;  &lt;p&gt;Uiteraard mogen ook diegene die er niet bij waren dit downloaden, maar of je er veel aan hebt zonder het bijbehorende verhaal gelezen te hebben is nog maar de vraag.&lt;/p&gt;  &lt;p&gt;Het was een uiterst geslaagde avond. Dennis is een erg goede spreker met enorm veel kennis over het onderwerp. Zeker gezien de beperkte hoeveelheid documentatie over Project Velocity was het indrukwekkend om te zien hoeveel hij er nog van af weet!&lt;/p&gt;  &lt;p&gt;Project Velocity is duidelijk nog niet af, maar als ze kunnen waarmaken wat ze beloven, heeft dit Distributed Cache framework alles in zich om erg handig en eigenlijk ook onmisbaar te worden.&lt;/p&gt;  &lt;p&gt;We bedanken &lt;a title="Class-A" target="_blank" href="http://www.class-a.nl"&gt;Class-A&lt;/a&gt; voor het hosten van een geslaagde avond!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=892" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/09/05/892.aspx</link>
      <author>dvroegop</author>
      <pubDate>Fri, 05 Sep 2008 08:39:14 GMT</pubDate>
    </item>
    <item>
      <title>3D Graphics in WPF, deel 9 (Materialen)</title>
      <description>&lt;p&gt;Tot nu toe hebben we twee kubussen en vlakken gezien: een zwarte (in het begin, voordat er licht was) en een blauwe. Als je naar mijn &lt;a title="eerste post over WPF" target="_blank" href="http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/26/870.aspx"&gt;eerste post&lt;/a&gt; over dit onderwerp kijkt, zie je dat ik daar iets meer kleuren en textures gebruik. Hoe werkt dat dan?&lt;/p&gt;  &lt;p&gt;Het geheim zit in het gebruik van materialen, oftewel Materials. Dat is waar we nu naar gaan kijken.&lt;/p&gt;  &lt;p&gt;Ik heb een beetje uitgelegd hoe de renderer van WPF werkt: voor ieder punt wordt gekeken hoeveel licht er op valt en dan wordt aan de hand van dat percentage licht berekend hoe zichtbaar iets is. Maar in het echte leven (je weet wel, die wereld BUITEN je computer) is de hoeveelheid en kleur van het licht maar een deel van de reden dat we de dingen zien zoals we ze zien: als je een geel papiertje naast een rood papiertje legt,&amp;#160; dan krijgen ze allebei exact dezelfde hoeveelheid licht maar toch zie je twee kleuren. Dat ligt uiteraard aan de kleur van het papier. En niet alleen de kleur, maar ook de textuur en de bedrukking van het papier draagt bij aan het beeld dat we hebben van het papiertje.&lt;/p&gt;  &lt;p&gt;In WPF kunnen we dat gedrag simuleren door het gebruik van de verschillende materials. Je moet een material zien als een soort behang dat je over je objecten plakt. Hoe dat in code werkt hebben we al gezien, maar ik zal het nog even herhalen:&lt;/p&gt;   &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;detrio:Box&lt;/span&gt; &lt;span class="attr"&gt;LeftBottomCorner&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Depth&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;detrio:Box.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Blue&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;detrio:Box.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;detrio:Box&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;detrio:Box&lt;/span&gt; &lt;span class="attr"&gt;LeftBottomCorner&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1 0 -2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0.5&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Depth&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0.5&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;detrio:Box.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Yellow&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;detrio:Box.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;detrio:Box&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;In regel 1 en in regel 7 maak ik twee boxen aan, met behulp van de code uit &lt;a target="_blank" href="http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/28/883.aspx"&gt;post 8a&lt;/a&gt;. In regel 2-4 en 8-10 geef ik ze een kleurtje. De eerste wordt blauw, de tweede geel (mits je het licht wit hebt gemaakt uiteraard). Maar eigenlijk klopt dat niet: we schilderen de box niet blauw en geel, maar we geven ze een Material mee die blauw of geel is. En dat maakt een groot verschil!&lt;/p&gt;

&lt;p&gt;In dit voorbeeld gebruik ik de DiffuseMaterial. Deze zul je waarschijnlijk het meest gebruiken: dit is een Material die het licht dat er op valt in alle richtingen weerkaatst. Het is te vergelijken met het vel papier dat ik eerder noemde. Een vel papier weerkaatst licht heel anders dan een glimmend stuk plastic, een gelakt tafelblad of een stuk glas (al dan niet matglas). De keuze van het materiaal bepaalt dus hoe je je objecten ziet.&lt;/p&gt;

&lt;p&gt;In WPF hebben we de keuze uit de volgende materialen, allen afgeleid van de class Material:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;DiffuseMaterial, die hebben we net besproken &lt;/li&gt;

  &lt;li&gt;SpecularMaterial, een material die licht 'weerkaatst' (het werkt niet als een spiegel,maar lijkt er wel een beetje op) &lt;/li&gt;

  &lt;li&gt;EmmisiveMaterial, deze straalt meer licht uit dan dat er op komt. Let op: dit is geen light object, dus andere objecten worden hier niet mee verlicht. Dit houdt in dat als je twee objecten zou hebben in je scene, een met een DiffuseMaterial en een met een EmmisiveMaterial, maar je hebt geen lights in je scene, dan zie je het object met de DiffuseMaterial als een zwart object, en de EmmisiveMaterial zie je met de kleur die je het gegeven hebt &lt;/li&gt;

  &lt;li&gt;MaterialGroup. Dit is geen echt material, maar hiermee kun je verschillende materials combineren in een object (de DependencyProperty Material van GeometryModel3D heeft een content, wat maar een object kan bevatten: door hier een MaterialGroup in te stoppen kun je materialen combineren). &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hieronder zie je een voorbeeld van een scene met 2 objecten en geen lampen: het voorste object heeft een DiffuseMaterial, het achterste heeft een EmmisiveMaterial, beiden hebben als Brush 'Blue'.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel9Materialen_8162/image.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="twee materialen" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel9Materialen_8162/image_thumb.png" width="304" height="304" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Je ziet dat de voorste gewoon zwart wordt (er valt immers geen licht op), terwijl bij de achterste alles gelijkmatig blauw is: er valt immers geen licht op dus er is geen verschil in de belichting per kant. Dat hij toch zichtbaar is, komt omdat hij zelf licht uitstraalt (maar zoals je aan de voorste box ziet straalt hij niet echt licht uit naar andere objecten).&lt;/p&gt;

&lt;p&gt;Het wordt pas leuk als we materials gaan combineren. Ik heb twee cylinders genomen (het effect is sterker bij gebogen oppervlaktes) en die naast elkaar geplaatst:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel9Materialen_8162/image_3.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel9Materialen_8162/image_thumb_3.png" width="304" height="304" /&gt;&lt;/a&gt; De material voor de linker cylinder is als volgt gedefinieerd:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;detrioCL:Cylinder.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MaterialGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Blue&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;SpecularMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;White&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;SpecularPower&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0.8&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;MaterialGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;detrioCL:Cylinder.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Hier combineer ik twee materialen, een DiffuseMaterial met een blauwe brush, en een SpecularMaterial. Deze laatste weerkaatst wit licht, met een intensiteit van 80%. Dus 80% van de hoeveelheid licht die er opvalt wordt wit teruggegeven. De rechter cylinder heeft alleen een DiffuseMaterial met een blauwe brush. Je ziet het verschil.&lt;/p&gt;

&lt;p&gt;Naast de keuze voor de Material soort moet je ook een bepaalde brush kiezen. Tot nu toe hebben we steeds een standaard Brush genomen, uit de Enum Brushes (die heel veel kleuren in zich heeft). Je bent echter niet gebonden aan een brush met een kleur: je kunt heel veel brushes toepassen.&lt;/p&gt;

&lt;p&gt;Brushes zijn afgeleid van System.Windows.Media.Brush, een abstract class (gebruik niet de oude System.Drawing.Brush, die werkt niet in 3D WPF!). We hebben de volgende brushes tot onze beschikking:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;SolidColorBrush. De standaard die we al gezien hebben, deze tekent met 1 kleur &lt;/li&gt;

  &lt;li&gt;LinearGradientBrush. Een verloop die van een kleur naar een ander loopt, in een rechthoek (bijvoorbeeld van linksboven naar rechtsonder) &lt;/li&gt;

  &lt;li&gt;RadialGradientBrush. Een verloop in een cirkel, dus van binnen naar buiten. &lt;/li&gt;

  &lt;li&gt;ImageBrush. Deze kan een image bevatten die getekend wordt. Hier kun je dus een jpg, png, gif enz. gebruiken als brush &lt;/li&gt;

  &lt;li&gt;DrawingBrush. Een brush die een 2D drawing bevat. Hier teken je zelf de inhoud van de brush &lt;/li&gt;

  &lt;li&gt;VisualBrush. Deze bevat een visual als tekenobject. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We gaan even terug naar onze begin applicatie:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt; &lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;WpfApplication11.Window1&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;Title&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Window1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Viewport3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;&amp;lt;!-- Te tekenen objecten --&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;            
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MeshGeometry3D&lt;/span&gt; &lt;span class="attr"&gt;Positions&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 0, 1 0 0, 1 1 0, 0 1 0&amp;quot;&lt;/span&gt;
                                        &lt;span class="attr"&gt;TriangleIndices&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 2 0 2 3&amp;quot;&lt;/span&gt;
                                        &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="rem"&gt;&amp;lt;!-- Hier gaan we met de material spelen --&amp;gt;&lt;/span&gt;
                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Blue&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="rem"&gt;&amp;lt;!-- Lampjes! --&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Model3DGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AmbientLight&lt;/span&gt; &lt;span class="attr"&gt;Color&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;#404040&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DirectionalLight&lt;/span&gt; &lt;span class="attr"&gt;Color&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;#BFBFBF&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Direction&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1 -1 -1&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Model3DGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="rem"&gt;&amp;lt;!-- Camera --&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Viewport3D.Camera&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;PerspectiveCamera&lt;/span&gt; &lt;span class="attr"&gt;Position&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.5 1.0 2.0&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;LookDirection&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;-0.5 -0.3 -1&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;UpDirection&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 0&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;FieldOfView&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;45.0&amp;quot;&lt;/span&gt; 
                           &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Viewport3D.Camera&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Viewport3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Dit is onze standaard applicatie, met een vierkant in het midden, wat verlichting en een camera. Als we de regel &amp;lt;DiffuseMaterial Brush=&amp;quot;Blue&amp;quot;/&amp;gt; vervangen door de volgende code:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;&amp;lt;!-- Hier gaan we met de material spelen --&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial.Brush&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;SolidColorBrush&lt;/span&gt; &lt;span class="attr"&gt;Color&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Blue&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial.Brush&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;krijgen we precies hetzelfde effect. Dit is eigenlijk wat de standaard Brushes collectie doet: het maakt een SolidColorBrush aan. Dit ziet er dus als volgt uit:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel9Materialen_8162/image_4.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel9Materialen_8162/image_thumb_4.png" width="304" height="304" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Als we de Brush nu eens vervangen door een LinearGradientBrush, krijgen we de volgende code en het volgende resultaat:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;&amp;lt;!-- Hier gaan we met de material spelen --&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial.Brush&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;LinearGradientBrush&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;LinearGradientBrush.GradientStops&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GradientStop&lt;/span&gt; &lt;span class="attr"&gt;Color&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Blue&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Offset&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0.0&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GradientStop&lt;/span&gt; &lt;span class="attr"&gt;Color&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;White&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Offset&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0.5&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GradientStop&lt;/span&gt; &lt;span class="attr"&gt;Color&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Red&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Offset&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;LinearGradientBrush.GradientStops&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;LinearGradientBrush&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial.Brush&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel9Materialen_8162/image_5.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel9Materialen_8162/image_thumb_5.png" width="304" height="304" /&gt;&lt;/a&gt; Geef toe: dit is niet het effect wat je verwacht had.&lt;/p&gt;

&lt;p&gt;Dit ga ik zo oplossen. Laten we eens naar de ImageBrush kijken. Voeg aan je applicatie een plaatje toe, bijvoorbeeld een jpeg of een png. Gewoon toevoegen aan je solution:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel9Materialen_8162/image_6.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Solution with image" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel9Materialen_8162/image_thumb_6.png" width="315" height="588" /&gt;&lt;/a&gt; Ik heb ons logo genomen en die gesleept naar de solution. Standaard staan de properties al goed: het wordt een resource die meegelinkt wordt in onze applicatie.&lt;/p&gt;

&lt;p&gt;De code ziet er dan als volgt uit:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;&amp;lt;!-- Hier gaan we met de material spelen --&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial.Brush&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ImageBrush&lt;/span&gt; &lt;span class="attr"&gt;ImageSource&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;DETRIO-logo.png&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial.Brush&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Run de applicatie en zie het resultaat: niets...&lt;/p&gt;

&lt;p&gt;De reden hiervoor is dezelfde als dat we in het vorige voorbeeld een rood vlak zagen. We hebben nog iets extras te doen om het aan de praat te krijgen.&lt;/p&gt;

&lt;p&gt;Ik zei al dat je een Material moet zien als een behang dat je op je objecten plakt. Dat zei ik niet zomaar, die analogie gaat verder dan je misschien dacht. Als je gaat behangen en je hebt simpel, eenkleurig behang, maakt het eigenlijk niet uit hoe je de banen plakt (de naadjes tussen de banen even daargelaten). Of je ze nu van boven naar beneden, van beneden naar boven of voor mijn part van links naar rechts plakt: het is allemaal hetzelfde. Maar als je behang met een print hebt, is de richting waarin je plakt wel belangrijk! Bij Materials is dat precies hetzelfde: WPF moet weten in welke richting je materials op je objecten geplaats moeten worden.&lt;/p&gt;

&lt;p&gt;Om dat aan te geven moeten we een mapping maken van onze 2D materialen naar de 3D coordinaten van onze objecten. &lt;/p&gt;

&lt;p&gt;Neem even onze referentie tekening met een kubus. Ik heb hierin de coordinaten gezet van de hoekpunten. Ook zie je een blauwe material op het voorvlak. In het rood zie je de 2D coordinaten van ons plaatje (het blauwe vierkant)&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel9Materialen_8162/image_7.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel9Materialen_8162/image_thumb_7.png" width="404" height="404" /&gt;&lt;/a&gt; Vergeet niet: in 3D is een positieve Y waarde een richting naar boven, in 2D is dat naar beneden! Dus de linkeronderhoek van onze kubus heeft als coordinaten (0,0,0) maar van onze material plaatje is dat (0,1)! Ik heb al gewaarschuwd dat we hier nog last mee gaan krijgen, dit is waar dat gebeurdt!&lt;/p&gt;

&lt;p&gt;We moeten voor ieder punt in onze kubus aangeven hoe de mapping met onze toekomstige material is. Dit is een property van de MeshGeometry3D, en heet TextureCoordinates.&lt;/p&gt;

&lt;p&gt;We moeten dus aan WPF zeggen dat op punt (0,0,0) van onze kubus het punt (0,1) van de brush geplaatst moet worden, op punt (1,0,0) moet brush coordinaat (1,1) komen, enzovoorts. (ik ga er even vanuit dat je wilt dat het plaatje rechtop staat en niet op zijn kop). We krijgen dus nu de volgende definitie van onze MeshGeometry3D&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MeshGeometry3D&lt;/span&gt; &lt;span class="attr"&gt;Positions&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 0, 1 0 0, 1 1 0, 0 1 0&amp;quot;&lt;/span&gt;
                &lt;span class="attr"&gt;TriangleIndices&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 2 0 2 3&amp;quot;&lt;/span&gt;
                &lt;span class="attr"&gt;TextureCoordinates&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1, 1 1, 1 0, 0 0&amp;quot;&lt;/span&gt;
                &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;We gebruiken relatieve coordinaten, we normaliseren de coordinaten van onze texture naar waardes tussen 0 en 1. Als je dus alleen de bovenste helft wilt laten zien, dan gebruik je als TextureCoordinates 0 0.5, 1 0.5, 1 0, 0 0. &lt;/p&gt;

&lt;p&gt;Nu krijgen we dit plaatje:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel9Materialen_8162/image_8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel9Materialen_8162/image_thumb_8.png" width="304" height="304" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Als je nu bij het voorbeeld van de LinearGradientBrush ook de TextureCoordinates plaatst, zul je zien dat het daar ook werkt.&lt;/p&gt;

&lt;p&gt;Volgende keer meer over de DrawingBrush en de VisualBrush. Die laatste is echt leuk, hiermee kunnen we bijvoorbeeld een video afspelen op onze kubus!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=886" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/09/03/886.aspx</link>
      <author>dvroegop</author>
      <pubDate>Wed, 03 Sep 2008 11:17:02 GMT</pubDate>
    </item>
    <item>
      <title>ASP.NET MVC Preview 5 and Form Posting Scenarios</title>
      <description>&lt;font face="arial" size="2"&gt;   &lt;p&gt;This past Thursday the ASP.NET MVC feature team published a new &amp;quot;Preview 5&amp;quot; release of the ASP.NET MVC framework.&amp;#160; You can download the new release &lt;a href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=16775" target="_blank"&gt;here&lt;/a&gt;.&amp;#160; This &amp;quot;Preview 5&amp;quot; release works with both .NET 3.5 and the recently released .NET 3.5 SP1.&amp;#160; It can also now be used with both Visual Studio 2008 as well as (the free) Visual Web Developer 2008 Express SP1 edition (which now supports both class library and web application projects).&lt;/p&gt;    &lt;p&gt;Preview 5 includes a bunch of new features and refinements (these build on the additions in &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx" target="_blank"&gt;&amp;quot;Preview 4&amp;quot;&lt;/a&gt;).&amp;#160; You can read detailed &amp;quot;Preview 5&amp;quot; release notes that cover changes/additions &lt;a href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=16775" target="_blank"&gt;here&lt;/a&gt;.&amp;#160; In this blog post I'm going to cover one of the biggest areas of focus with this release: form posting scenarios.&amp;#160; You can download a completed version of the application I'll build below &lt;a href="http://www.scottgu.com/blogposts/mvcpreview5/mvcapplication49.zip" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Basic Form Post with a Web MVC Pattern&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;Let's look at a simple form post scenario - adding a new product to a products database:&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step2.png" /&gt; &lt;/p&gt;    &lt;p&gt;The page above is returned when a user navigates to the &amp;quot;/Products/Create&amp;quot; URL in our application.&amp;#160; The HTML form markup for this page looks like below:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step3.png" /&gt; &lt;/p&gt;    &lt;p&gt;The markup above is standard HTML.&amp;#160; We have two &amp;lt;input type=&amp;quot;text&amp;quot;/&amp;gt; textboxes within a &amp;lt;form&amp;gt; element.&amp;#160; We then have an HTML submit button at the bottom of the form.&amp;#160; When pressed it will cause the form it is nested within to post the form inputs to the server.&amp;#160; The form will post the contents to the URL indicated by its &amp;quot;action&amp;quot; attribute - in this case &amp;quot;/Products/Save&amp;quot;.&lt;/p&gt;    &lt;p&gt;Using the previous &amp;quot;Preview 4&amp;quot; release of ASP.NET we might have implemented the above scenario using a ProductsController class like below that implements two action methods - &amp;quot;Create&amp;quot; and &amp;quot;Save&amp;quot;:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step5.png" /&gt; &lt;/p&gt;    &lt;p&gt;The &amp;quot;Create&amp;quot; action method above is responsible for returning an html view that displays our initial empty form.&amp;#160; The &amp;quot;Save&amp;quot; action method then handles the scenario when the form is posted back to the server.&amp;#160; The ASP.NET MVC framework automatically maps the &amp;quot;ProductName&amp;quot; and &amp;quot;UnitPrice&amp;quot; form post values to the method parameters on the Save method with the same names.&amp;#160; The Save action then uses LINQ to SQL to create a new Product object, assigns its ProductName and UnitPrice values with the values posted by the end-user, and then attempts to save the new product in the database.&amp;#160; If the product is successfully saved, the user is redirected to a &amp;quot;/ProductsAdded&amp;quot; URL that will display a success message.&amp;#160; If there is an error we redisplay our &amp;quot;Create&amp;quot; html view again so that the user can fix the issue and retry.&lt;/p&gt;    &lt;p&gt;We could then implement a &amp;quot;Create&amp;quot; HTML view template like below that would work with the above ProductsController to generate the appropriate HTML.&amp;#160; Note below that we are using the Html.TextBox helper methods to generate the &amp;lt;input type=&amp;quot;text&amp;quot;/&amp;gt; elements for us (and automatically populate their value from the appropriate property in our Product model object that we passed to the view):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step6.png" /&gt; &lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Form Post Improvements with Preview 5&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;The above code works with the previous &amp;quot;Preview 4&amp;quot; release, and continues to work fine with &amp;quot;Preview 5&amp;quot;.&amp;#160; The &amp;quot;Preview 5&amp;quot; release, though, adds several additional features that will allow us to make this scenario even better.&amp;#160; &lt;/p&gt;    &lt;p&gt;These new features include:&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;The ability to publish a single action URL and dispatch it differently depending on the HTTP Verb &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;Model Binders that allow rich parameter objects to be constructed from form input values and passed to action methods &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;Helper methods that enable incoming form input values to be mapped to existing model object instances within action methods &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;Improved support for handling input and validation errors (for example: automatically highlighting bad fields and preserving end-user entered form values when the form is redisplayed to the user) &lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;I'll use the remainder of this blog post to drill into each of these scenarios.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;[AcceptVerbs] and [ActionName] attributes&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;In our sample above we implemented our product add scenario across two action methods: &amp;quot;Create&amp;quot; and &amp;quot;Save&amp;quot;.&amp;#160; One motivation for partitioning the implementation like this is that it makes our Controller code cleaner and easier to read.&lt;/p&gt;    &lt;p&gt;The downside to using two actions in this scenario, though, is that we end up publishing two URLs from our site: &amp;quot;/Products/Create&amp;quot; and &amp;quot;/Products/Save&amp;quot;.&amp;#160; This gets problematic in scenarios where we need to redisplay the HTML form because of an input error - since the URL of the redisplayed form in the error scenario will end up being &amp;quot;/Products/Save&amp;quot; instead of &amp;quot;/Products/Create&amp;quot; (because &amp;quot;Save&amp;quot; that was the URL the form was posted to).&amp;#160; If an end-user adds this redisplayed page to their browser favorites, or copy/pastes the URL and emails it to a friend, they will end up saving the wrong URL - and will likely have an error when they try and access it later.&amp;#160; Publishing two URLs can also cause problems with some search engines if your site is crawled and they attempt to automatically traverse your action attributes.&lt;/p&gt;    &lt;p&gt;One way to work around these issues is to publish a single &amp;quot;/Products/Create&amp;quot; URL, and then have different server logic depending on whether it is a GET or POST request.&amp;#160; One common approach used to-do this with other web MVC frameworks is to simply have a giant if/else statement within the action method and branch accordingly:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step7.png" /&gt; &lt;/p&gt;    &lt;p&gt;The downside with the above approach, though, is that it can make the action implementation harder to read, as well as harder to test.&amp;#160; &lt;/p&gt;    &lt;p&gt;ASP.NET MVC &amp;quot;Preview 5&amp;quot; now offers a better option to handle this scenario.&amp;#160; You can create overloaded implementations of action methods, and use a new [AcceptVerbs] attribute to have ASP.NET MVC filter how they are dispatched.&amp;#160; For example, below we can declare two Create action methods - one that will be called in GET scenarios, and one that will be called in POST scenarios:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step27.png" /&gt; &lt;/p&gt;    &lt;p&gt;This approach avoids the need for giant &amp;quot;if/else&amp;quot; statement within your action methods, and enables a cleaner structuring of your action logic.&amp;#160; It also eliminates the need to mock the Request object in order to test these two different scenarios.&lt;/p&gt;    &lt;p&gt;You can also optionally now use a new [ActionName] attribute to allow the method name implementation on your controller class to be different than that from the published URL.&amp;#160; For example, if rather than having two overloaded Create methods in your controller you instead wanted to have the POST method be named &amp;quot;Save&amp;quot;, you could apply the [ActionName] attribute to it like so:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step28.png" /&gt; &lt;/p&gt;    &lt;p&gt;Above we have the same controller method signature (Create and Save) that we had in our initial form post sample.&amp;#160; The difference, though, is that we are now publishing a single URL (/Products/Create) and are automatically varying the handling based on the incoming HTTP verb (and so are browser favorites and search engine friendly).&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Model Binders&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;In our sample above the signature of the Controller action method that handles the form-post takes a String and a Decimal as method arguments.&amp;#160; The action method then creates a new Product object, assigns these input values to it, and then attempts to insert it into the database:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step13.png" /&gt; &lt;/p&gt;    &lt;p&gt;One of the new capabilities in &amp;quot;Preview 5&amp;quot; that can make this scenario cleaner is its &amp;quot;Model Binder&amp;quot; support.&amp;#160; Model Binders provide a way for complex types to be de-serialized from the incoming HTTP input, and passed to a Controller action method as arguments.&amp;#160; They also provide support for handling input exceptions, and make it easier to redisplay forms when errors occur (without requiring the end-user to have to re-enter all their data again - more on this later in this blog post).&amp;#160; &lt;/p&gt;    &lt;p&gt;For example, using the model binder support we could re-factor the above action method to instead take a Product object as an argument like so:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step15.png" /&gt; &lt;/p&gt;    &lt;p&gt;This makes the code a little more terse and clean.&amp;#160; It also allows us to avoid having repetitive form-parsing code scattered across multiple controllers/actions (allowing us to maintain the DRY principle: &amp;quot;don't repeat yourself&amp;quot;).&lt;/p&gt;    &lt;p&gt;&lt;u&gt;Registering Model Binders&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;Model Binders in ASP.NET MVC are classes that implement the IModelBinder interface, and can be used to help manage the binding of types to input parameters.&amp;#160; A model binder can be written to work against a specific object type, or can alternatively be used to handle a broad range of types. The IModelBinder interface allows you to unit test binders independent of the web-server or any specific controller implementation.&lt;/p&gt;    &lt;p&gt;Model Binders can be registered at 4 different levels within an ASP.NET MVC application, which enables a great deal of flexibility in how you use them:&amp;#160; &lt;/p&gt;    &lt;p&gt;1) ASP.NET MVC first looks for the presence of a model binder declared as a parameter attribute on an action method.&amp;#160; For example, we could indicate that we wanted to use a hypothetical &amp;quot;Bind&amp;quot; binder by annotating our product parameter using an attribute like below (note how we are indicating that only two properties should be bound using a parameter on the attribute):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step16.png" /&gt; &lt;/p&gt;    &lt;p&gt;&lt;em&gt;Note: &amp;quot;Preview 5&amp;quot; doesn't have a built-in [Bind] attribute like above just yet (although we are considering adding it as a built-in feature of ASP.NET MVC in the future).&amp;#160; However all of the framework infrastructure necessary to implement a [Bind] attribute like above &lt;/em&gt;&lt;u&gt;is&lt;/u&gt;&lt;em&gt; now implemented in preview 5. The open source MVCContrib project also has a DataBind attribute like above that you can use today.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;2) If no binder attribute is present on the action parameter, ASP.NET MVC then looks for the presence of a binder registered as an attribute on the type of the parameter being passed to the action method.&amp;#160; For example, we could register an explicit &amp;quot;ProductBinder&amp;quot; binder for our LINQ to SQL &amp;quot;Product&amp;quot; object by adding code like below to our Product partial class:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step17.png" /&gt; &lt;/p&gt;    &lt;p&gt;3) ASP.NET MVC also supports the ability to register binders at application startup using the ModelBinders.Binders collection.&amp;#160; This is useful when you want to use a type written by a third party (that you can't annotate) or if you don't want to add a binder attribute annotation on your model object directly.&amp;#160; The below code demonstrates how to register two type-specific binders at application startup in your global.asax:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step18.png" /&gt; &lt;/p&gt;    &lt;p&gt;4) In addition to registering type-specific global binders, you can use the ModelBinders.DefaultBinder property to register a default binder that will be used when a type-specific binder isn't found.&amp;#160; Included in the MVCFutures assembly (which is currently referenced by default with the mvc preview builds) is a &lt;em&gt;ComplexModelBinder&lt;/em&gt; implementation that uses reflection to set properties based on incoming form post names/values.&amp;#160; You could register it to be used as the fallback for all complex types passed as Controller action arguments using the code below:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step19.png" /&gt; &lt;/p&gt;    &lt;p&gt;&lt;em&gt;Note: the MVC team plans to tweak the IModelBinder interface further for the next drop (they recently discovered a few scenarios that necessitate a few changes).&amp;#160; So if you build a custom model binder with preview 5 expect to have to make a few tweaks when the next drop comes out (probably nothing too major - but just a heads up that we know a few arguments will change on its methods).&lt;/em&gt;&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;UpdateModel and TryUpdateModel Methods&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;The ModelBinder support above is great for scenarios where you want to instantiate new objects and pass them in as arguments to a controller action method.&amp;#160; There are also scenarios, though, when you want to be able to bind input values to existing object instances that you own retrieving/creating yourself within the action method.&amp;#160; For example, when enabling an edit scenario for an existing product in the database, you might want to use an ORM to retrieve an existing product instance from the database first within your action method, then bind the new input values to the retrieved product instance, and then save the changes back to the database.&lt;/p&gt;    &lt;p&gt;&amp;quot;Preview 5&amp;quot; adds two new methods on the Controller base class to help enable this - UpdateModel() and TryUpdateModel().&amp;#160; Both allow you to pass in an existing object instance as the first argument, and then as a second argument you pass in a security white-list of properties you want to update on them using the form post values.&amp;#160; For example, below I'm retrieving a Product object using LINQ to SQL, and then using the UpdateModel method to update the product's name and price properties with form data.&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step20.png" /&gt; &lt;/p&gt;    &lt;p&gt;The UpdateModel methods will attempt to update all of the properties you list (even if there is an error on an early one in the list).&amp;#160; If it encounters an error for a property (for example: you entered bogus string data for a UnitPrice property which is of type Decimal), it will store the exception object raised &lt;em&gt;as well the original form posted value &lt;/em&gt;in a new &amp;quot;ModelState&amp;quot; collection added with &amp;quot;Preview 5&amp;quot;.&amp;#160; We'll cover this new ModelState collection in a little bit - but in a nutshell it provides an easy way for us to redisplay forms with the user-entered values automatically populated for them to fix when there is an error.&lt;/p&gt;    &lt;p&gt;After attempting to update all of the indicated properties, the UpdateModel method will raise an exception if any of them failed.&amp;#160; The TryUpdateModel method works the same way - except that instead of raising an exception it will return a boolean true/false value which indicates whether there were any errors.&amp;#160; You can choose whichever method works best with your error handling preferences.&lt;/p&gt;    &lt;p&gt;&lt;u&gt;Product Edit Example&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;To see an example of using the UpdateModel method in use, let's implement a simple product editing form.&amp;#160; We'll use a URL format of &lt;em&gt;/Products/Edit/{ProductId}&lt;/em&gt; to indicate which product we want to edit.&amp;#160; For example, below the URL is /Products/Edit/4 - which means we are going to edit the product whose ProductId is 4:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step21.png" /&gt; &lt;/p&gt;    &lt;p&gt;Users can change the product name or unit price, and then click the Save button.&amp;#160; When they do our post action method will update the database and then show the user a &amp;quot;Product Updated!&amp;quot; message if it was successful:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step22.png" /&gt; &lt;/p&gt;    &lt;p&gt;We can implement the above functionality using the two Controller actions methods below.&amp;#160; Notice how we are using the [AcceptVerbs] attribute to differentiate the Edit action that displays the initial form, and the one that handles the form post submission:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step61.png" /&gt; &lt;/p&gt;    &lt;p&gt;Our POST action method above uses LINQ to SQL to retrieve an instance of the product object we are editing from the database, then uses UpdateModel to attempt to update the product's ProductName and UnitPrice values using the form post values.&amp;#160; It then calls SubmitChanges() on the LINQ to SQL datacontext to save the updates back to the database.&amp;#160; If that was successful, we then store a success message string in the TempData collection and redirect the user back to the GET action method using a client-side redirect (which will cause the newly saved product to be redisplayed - along with our TempData message string indicating it was updated).&amp;#160; If there is an error either with the form posted values, or with updating the database, an exception will be raised and caught in our catch block - and we will redisplay the form view again to the user for them to fix.&lt;/p&gt;    &lt;p&gt;You might wonder - what is up with this redirect when we are successful?&amp;#160; Why not just redisplay the form again and show the success message?&amp;#160; The reason for the client-redirect is to ensure that if the user hits the refresh button after successfully pressing the save button, they don't resubmit the form again and get hit with a browser prompt like this:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step25.png" /&gt; &lt;/p&gt;    &lt;p&gt;Doing the redirect back to the GET version of the action method ensures that a user hitting refresh will simply reload the page again and not post back.&amp;#160; This approach is called the &lt;a href="http://en.wikipedia.org/wiki/Post/Redirect/Get" target="_blank"&gt;&amp;quot;Post/Redirect/Get&amp;quot; (aka PRG) pattern&lt;/a&gt;.&amp;#160; Tim Barcz has a nice article &lt;a href="http://devlicio.us/blogs/tim_barcz/archive/2008/08/22/prg-pattern-in-the-asp-net-mvc-framework.aspx" target="_blank"&gt;here&lt;/a&gt; that talks about this more with ASP.NET MVC.&lt;/p&gt;    &lt;p&gt;The above two controller action methods are all we need to implement in order to handle editing and updating a Product object.&amp;#160; Below is the &amp;quot;Edit&amp;quot; view to go with the above Controller:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step26.png" /&gt; &lt;/p&gt;    &lt;p&gt;&lt;em&gt;Useful Tip&lt;/em&gt;: In the past once you started added parameters to URLs (for example: /Products/Edit/4) you had to write code in your view to update the form's action attribute to include the parameters in the post URL.&amp;#160; &amp;quot;Preview 5&amp;quot; includes a Html.Form() helper method that can make this easier.&amp;#160; Html.Form() has many overloaded versions that allow you to specify a variety of parameter options.&amp;#160; A new overloaded Html.Form() method that takes with no parameters has been added that will now output the same URL as the current request.&amp;#160; &lt;/p&gt;    &lt;p&gt;For example, if the incoming URL to the Controller that rendered the above view was &amp;quot;/Products/Edit/5&amp;quot;, calling Html.Form() like above would automatically output &amp;lt;form action=&amp;quot;/Products/Edit/5&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt; as the markup output.&amp;#160; If the incoming URL to the Controller that rendered the above view was &amp;quot;/Products/Edit/55&amp;quot;, calling Html.Form() like above would automatically output &amp;lt;form action=&amp;quot;/Products/Edit/55&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt; as the markup output.&amp;#160; This provides a nifty way to avoid having to write any custom code yourself to construct the URL or indicate parameters.&lt;/p&gt;    &lt;p&gt;&lt;u&gt;Unit Testing and UpdateModel&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;In this week's Preview 5 drop the UpdateModel methods always work against the Request object's Form post collection to retrieve values.&amp;#160; This means that to test the above form post action method you'd need to mock the request object in your unit test.&amp;#160; &lt;/p&gt;    &lt;p&gt;With the next MVC drop we'll also add an overloaded UpdateModel method that allows you to pass in your own collection of values to use instead.&amp;#160; For example, we would be able to use the new FormCollection type in preview 5 (which has a ModelBuilder that automatically populates it with all form post values) and pass it to the UpdateModel method as an argument like so:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step29.png" /&gt; &lt;/p&gt;    &lt;p&gt;Using an approach like above will allow us to unit test our form-post scenario without having to use any mocking. Below is an example unit test we could write that tests that a POST scenario successfully updates with new values and redirects back to the GET version of our action method.&amp;#160; Notice that we do not need to mock anything (nor do we have to rely on any special helper methods) in order to unit test all the functionality in our controller:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step32.png" /&gt; &lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Handling Error Scenarios - Redisplaying Forms with Error Messages&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;One of the important things to take care of when handling form post scenarios are error conditions.&amp;#160; These includes cases where an end-user posts incorrect input (for example: a string instead of a number for a Decimal unit-price), as well as cases where the input format is valid, but the business rules behind the application disallow something from being created/updated/saved (for example: making a new order for a discontinued product).&lt;/p&gt;    &lt;p&gt;If a user makes a mistake when filling out a form, the form should be redisplayed with informative error messages that guide them towards fixing it.&amp;#160; The form should also preserve the input data the user originally entered - so that they don't have to refill this manually.&amp;#160; This process should repeat as many times as necessary until the form successfully completes.&lt;/p&gt;    &lt;p&gt;&lt;u&gt;Basic Form Entry Error Handling and Input Validation with ASP.NET MVC&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;In our product edit sample above we haven't written much error handling code in either our Controller or our View.&amp;#160; Our Edit post action simply wraps a try/catch error handling block around the UpdateModel() input mapping call, as well as the database save SubmitChanges() call.&amp;#160; If an error occurs, the controller saves an output message in the TempData collection, and then returns our edit view to be redisplayed:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step33.png" /&gt; &lt;/p&gt;    &lt;p&gt;With earlier preview releases of ASP.NET MVC the above code wouldn't be enough to deliver a good end-user experience (since it wouldn't highlight the problem, nor preserve user input if there was an error).&lt;/p&gt;    &lt;p&gt;However, with &amp;quot;Preview 5&amp;quot; you'll find that you now get a decent end-user error experience out of the box with just the above code.&amp;#160; Specifically, you'll find that when our edit view is redisplayed because of an input error it now highlights all input controls that have problems, and preserves their input for us to fix:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step34.png" /&gt; &lt;/p&gt;    &lt;p&gt;How, you might ask, did the Unit Price textbox highlight itself in red and know to output the originally entered user value?&lt;/p&gt;    &lt;p&gt;&amp;quot;Preview 5&amp;quot; introduces a new &amp;quot;ModelState&amp;quot; collection that is passed as part of the &amp;quot;ViewData&amp;quot; sent from the Controller to the View when it renders.&amp;#160; The ModelState collection provides a way for Controllers to indicate that an error exists with a model object or model property being passed to the View, and allows a human friendly error message to be specified that describes the issue, as well as the original value entered by the end-user.&lt;/p&gt;    &lt;p&gt;Developers can explicitly write code to add items into the ModelState collection within their Controller actions.&amp;#160; ASP.NET MVC's ModelBinders and UpdateModel() helper methods also automatically populate this collection by default when they encounter input errors.&amp;#160; Because we were using the UpdateModel() helper method in our Edit action above, when it failed in its attempt to map the UnitPrice TextBox's &amp;quot;gfgff23.02&amp;quot; input to the Product.UnitPrice property (which is of type Decimal) it automatically added an entry to the ModelState collection.&lt;/p&gt;    &lt;p&gt;Html helper methods inside the View by default now check the ModelState collection when rendering output.&amp;#160; If an error for an item they are rendering exists, they will now render the originally entered user value as well as a CSS error class to the HTML input element.&amp;#160; For example, for our &amp;quot;Edit&amp;quot; View above we are using the Html.TextBox() helper method to render the UnitPrice of our Product object:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step35.png" /&gt; &lt;/p&gt;    &lt;p&gt;When the view was rendered during the error scenario above the Html.TextBox() method checked the ViewData.ModelState collection to see if there were any issues with the &amp;quot;UnitPrice&amp;quot; property of our Product object, and when it saw that there was rendered the originally entered user input (&amp;quot;gfgff23.02&amp;quot;) and added a css class to the &amp;lt;input type=&amp;quot;textbox&amp;quot;/&amp;gt; it output:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step37.png" /&gt; &lt;/p&gt;    &lt;p&gt;You can customize the appearance of the the error css classes to look however you want.&amp;#160; The default CSS error rule for input elements in the stylesheet created in new ASP.NET MVC projects looks like below:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step38.png" /&gt; &lt;/p&gt;    &lt;p&gt;&lt;u&gt;Adding Additional Validation Messages&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;The built-in HTML form helpers provide basic visual identification of input fields with issues.&amp;#160; Let's now add some more descriptive error messages to the page as well.&amp;#160; To-do this we can use the new Html.ValidationMessage() helper method in &amp;quot;Preview 5&amp;quot;.&amp;#160; This method will output the error message in the ModelState collection that is associated with a given Model or Model property.&lt;/p&gt;    &lt;p&gt;For example: we could update our view to use the Html.ValidationMessage() helper to the right of the textboxes like so:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step39.png" /&gt; &lt;/p&gt;    &lt;p&gt;Now when the page renders with an error, an error message will be displayed next to the fields with problems:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step40.png" /&gt; &lt;/p&gt;    &lt;p&gt;There is an overloaded version of the Html.ValidationMessage() method that takes a second parameter that allows the view to specify an alternative text to display:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step41.png" /&gt; &lt;/p&gt;    &lt;p&gt;One common use case is to output the * character next to the input fields, and then add the new Html.ValidationSummary() helper method (new in &amp;quot;Preview 5&amp;quot;) near the top of the page to list all the error messages:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step42.png" /&gt; &lt;/p&gt;    &lt;p&gt;The Html.ValidationSummary() helper method will then render a &amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;/ul&amp;gt; list of all the error messages our ModelState collection, and a * and red border will indicate each input element that has a problem:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step43.png" /&gt; &lt;/p&gt;    &lt;p&gt;Note that we haven't had to change our ProductsController class at all to achieve this.&lt;/p&gt;    &lt;p&gt;&lt;u&gt;Supporting Business Rules Validation&lt;/u&gt; &lt;/p&gt;    &lt;p&gt;Supporting input validation scenarios like above is useful, but rarely sufficient for most applications.&amp;#160; In most scenarios you also want to be able to enforce business rules, and have your application UI cleanly integrate with them.&lt;/p&gt;    &lt;p&gt;ASP.NET MVC supports any data layer abstraction (both ORM and non-ORM based), and allows you to structure your domain model, as well as associated rules/constraints, however you want.&amp;#160; Capabilities like Model Binders, the UpdateModel helper method, and all of the error display and validation message support are explicitly designed so that you can use whatever preferred data access story you want within your MVC applications (including LINQ to SQL, LINQ to Entities, NHibernate, SubSonic, CSLA.NET, LLBLGen Pro, WilsonORMapper, DataSets, ActiveRecord, and any other).&lt;/p&gt;    &lt;p&gt;&lt;u&gt;Adding Business Rules to a LINQ to SQL Entity&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;In the sample above I've been using LINQ to SQL to define my Product entity and perform my data access.&amp;#160; So far, the only level of domain rules/validation that I am using on my Product entity are those inferred by LINQ to SQL from the SQL Server metadata (nulls, data type and length, etc).&amp;#160; This will catch scenarios like above (where we are trying to assign bogus input to a Decimal).&amp;#160; However, they won't be able to model business issues that can't be easily declared using SQL metadata.&amp;#160; For example: disallowing the reorder level of a product to be greater than zero if it has been discontinued, or disallowing a product to be sold for less than what our supplier price is, etc.&amp;#160; For scenarios like these we need to add code to our model to express and integrate these business rules.&lt;/p&gt;    &lt;p&gt;The &lt;em&gt;wrong place&lt;/em&gt; to add this business rule logic is in the UI layer of our application.&amp;#160; Adding them there is bad for many reasons.&amp;#160; Among others it will almost certainly lead to duplicated code - since you'll end up copying the rules around from UI to UI and from form to form.&amp;#160; In addition to being time-consuming, there is an excellent chance doing so will lead to bugs when you change your business rule logic, and you forget to update it everywhere.&amp;#160; &lt;/p&gt;    &lt;p&gt;A much better place to incorporate these business rules is at your model or domain level.&amp;#160; That way they can be used and applied regardless of what type of UI or form or service works with it.&amp;#160; Changes to the rules can be made once, and picked up everywhere without having to duplicate any logic.&lt;/p&gt;    &lt;p&gt;There are several patterns and approaches we could take to integrate richer business rules to the Product model object we've been using above: we could define the rules within the object, or external from the object.&amp;#160; We could use declarative rules, a re-usable rules engine framework, or imperative code.&amp;#160; The key point is that ASP.NET MVC allows us to use any or all of these approaches (there aren't a bunch of features that require you to always do it one way - you instead have the flexibility to reflect them however you want, and the MVC features are extensible enough to integrate with almost anything).&lt;/p&gt;    &lt;p&gt;For this blog post I'm going to use a relatively simple rules approach.&amp;#160; First I'm going to define a &amp;quot;RuleViolation&amp;quot; class like below that we can use to capture information about a business rule that is being violated within our model.&amp;#160; This class will expose an ErrorMessage string with details about the error, as well as expose the primary property name and property value associated with it that is causing the violation:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step44.png" /&gt; &lt;/p&gt;    &lt;p&gt;(note: For simplicity sake I'm only going to store only one property - in more complex applications this might instead be a list so that multiple properties could be specified).&lt;/p&gt;    &lt;p&gt;I will then define an IRuleEntity interface that has a single method - GetRuleViolations() - which returns back a list of all current business rule violations with that entity:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step54.png" /&gt; &lt;/p&gt;    &lt;p&gt;I can then have my Product class implement this interface.&amp;#160; To keep the sample simple I'm embedding the rule definition and evaluation logic inside the method.&amp;#160; There are better patterns that you can use to enable reusable rules, as well as to handle more complex rules. If this sample grew I'd refactor the method so that the rules and their evaluation where defined elsewhere, but for now to keep this simple we'll just evaluate three business rules below like so:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step55.png" /&gt;&amp;#160; &lt;/p&gt;    &lt;p&gt;Our application can now query the Product (or any other IRuleEntity) instance to check its current validation status, as well as retrieve back RuleViolation objects that can be used to help present UI that can guide an end-user of the application to help fix them.&amp;#160; It also allows us to easily unit test our business rules independent of the application UI.&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step49.png" /&gt; &lt;/p&gt;    &lt;p&gt;For this particular sample I am going to choose to enforce that our Product object is never saved in the database in an invalid state (meaning all RuleViolations must be fixed before the Product object can be saved in the database).&amp;#160; We can do this with LINQ to SQL by adding an OnValidate partial method to the Product partial class.&amp;#160; This method will get called automatically by LINQ to SQL any time database persistence occurs.&amp;#160; Below I'm calling the GetRuleViolations() method we added above, and am raising an exception if there are unresolved errors.&amp;#160; This will abort the transaction and prevent the database from being updated:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step50.png" /&gt; &lt;/p&gt;    &lt;p&gt;And now in addition to having a friendly helper method that allows us to retrieve RuleViolations from a Product, we have enforcement that those RuleViolations must be fixed before our database is ever updated.&lt;/p&gt;    &lt;p&gt;&lt;u&gt;Integrating the above Rules into our ASP.NET MVC UI&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;Once we've implemented our business rules, and exposed our RuleViolations like above, it will be relatively easy to integrate it into our ASP.NET MVC sample.&lt;/p&gt;    &lt;p&gt;Because we added the OnValidate partial method to our Product class, calling northwind.SubmitChanges() will raise an exception if there are any business rule validation issues with a Product object that we are trying to save.&amp;#160; This exception will abort any database transactions, and will be caught in our catch block below:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step57.png" /&gt; &lt;/p&gt;    &lt;p&gt;The one extra line of code we'll then add to our error catch block is some logic to call a UpdateModelStateWithViolations() helper method defined below.&amp;#160; This method retrieves a list of all rule violations from an entity, and then updates a ModelState collection with appropriate model errors (including references to the properties on our entity object that caused them):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step56.png" /&gt; &lt;/p&gt;    &lt;p&gt;Once we do this, we can re-run our application.&amp;#160; Now, in addition to seeing input format related error messages, ASP.NET MVC's validation helpers will also display our business rule violations as well.&amp;#160; &lt;/p&gt;    &lt;p&gt;For example, we could set the unit price to be less than a $1, and try to set the Reorder level to be -1 (both values are legal from an input format perspective - but both violate our business rules).&amp;#160; When we do this and hit save we'll see the errors show up in our Html.ValidationSummary() list, and the corresponding textboxes will be flagged:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step58.png" /&gt; &lt;/p&gt;    &lt;p&gt;Our business rules can span multiple Product properties.&amp;#160; For example: you might have noticed above that I added a rule that said that the reorder level can't be greater than zero if the product is discontinued:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step59.png" /&gt; &lt;/p&gt;    &lt;p&gt;The only changes we needed to make to our &amp;quot;Edit&amp;quot; view template throughout this entire business rules process has been to add two more Product properties (Reorder and Discontinued) to the file:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview5/step60.png" /&gt; &lt;/p&gt;    &lt;p&gt;Now we can add any number of additional business validation rules we want to our Product entity, and &lt;em&gt;&lt;u&gt;we do not need to update the Edit view nor the ProductsController in order to have our UI support them.&lt;/u&gt;&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;We can also unit-test our model and business rules separately from our Controller and View.&amp;#160; We can unit-test our URL routing separately from our Controller, Views and Models.&amp;#160; And we can unit test our Controller separately from our Views.&amp;#160; All of the scenarios shown in this blog post will support unit testing without requiring any mocking or stubbing to be used.&amp;#160; The end result are applications that are easily testable, and which can support a nice TDD workflow.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Summary&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;This post has provided a quick look at how form post scenarios work with ASP.NET MVC Preview 5.&amp;#160; Hopefully after reading it you have a better sense of how you handle form and input entry scenarios using a MVC model.&amp;#160; You can download a completed C# version of the application I built above &lt;a href="http://www.scottgu.com/blogposts/mvcpreview5/mvcapplication49.zip" target="_blank"&gt;here&lt;/a&gt;.&amp;#160; I will post a VB version a little later this week (it is unfortunately 4:30am while I'm typing this and I need to hop on a plane in a few short hours and have not started packing yet).&lt;/p&gt;    &lt;p&gt;Important: If you don't like the MVC model or don't find it natural to your style of development, you definitely don't have to use it.&amp;#160; It is a totally optional offering - and &lt;u&gt;does not&lt;/u&gt; replace the existing WebForms model.&amp;#160; Both WebForms and MVC will be fully supported and enhanced going forward (the next release of ASP.NET WebForms will add richer URL routing features, better HTML markup/client-side ID/CSS support, and more).&amp;#160; So if after reading the above post you think &amp;quot;hmm - that doesn't feel natural to me&amp;quot;, then both don't worry, and don't feel like you should or need to use it (you don't).&amp;#160; &lt;/p&gt;    &lt;p&gt;In my next post on MVC I'll cover how to integrate AJAX into your ASP.NET MVC applications.&amp;#160; &lt;/p&gt;    &lt;p&gt;Hope this helps,&lt;/p&gt;    &lt;p&gt;Scott&lt;/p&gt; &lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6592229" width="1" height="1"&gt;</description>
      <link>http://weblogs.asp.net/scottgu/archive/2008/09/02/asp-net-mvc-preview-5-and-form-posting-scenarios.aspx</link>
      <author>ScottGu</author>
      <pubDate>Tue, 02 Sep 2008 14:22:52 GMT</pubDate>
    </item>
    <item>
      <title>Quick Update</title>
      <description>&lt;font face="arial" size="2"&gt;   &lt;p&gt;I've received a number of (very nice) emails recently asking if I was ok - since my blog has been silent the last few weeks (and much of the summer).&amp;#160; &lt;/p&gt;    &lt;p&gt;Just to address people's concerns - I'm alive and well. :-)&amp;#160; I've just been on vacation the last 6 weeks, and have unfortunately not had free time to post (I've been changing a lot of diapers).&amp;#160; &lt;/p&gt;    &lt;p&gt;I am still on vacation another week before I officially return to work.&amp;#160; I did get a chance to write up a quick post this weekend that covers some of the new ASP.NET MVC Preview 5 features, though, that will hopefully provide some interim reading until I can resume a more regular posting schedule over the next month when I get back into the office.&lt;/p&gt;    &lt;p&gt;Thanks,&lt;/p&gt;    &lt;p&gt;Scott&lt;/p&gt; &lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6592226" width="1" height="1"&gt;</description>
      <link>http://weblogs.asp.net/scottgu/archive/2008/09/02/quick-update.aspx</link>
      <author>ScottGu</author>
      <pubDate>Tue, 02 Sep 2008 14:21:59 GMT</pubDate>
    </item>
    <item>
      <title>6 september: de 2e Nederlandse CodeCamp!</title>
      <description>&lt;p&gt;Op zaterdag 6 september is het weer zo ver: we hebben weer een codecamp! Voor diegene die niet weten wat het is, zal ik je niet vermoeien met een lang verhaal (er zijn hele websites vol over geschreven). Het komt neer op het volgende: een dag van code, code sharing, freaking en gezellig samenzijn. Een evenement door ontwikkelaars, voor ontwikkelaars. De regie ligt voor een belangrijk deel bij de deelnemers! Het aantal plaatsen voor deelnemers is wel beperkt tot maximaal 120. Wacht dus niet te lang met beslissen want voor je het weet is er geen plaats meer.   &lt;br /&gt;Een Code Camp is volledig gratis voor alle deelnemers, en dat is inclusief koffie, lunch en andere noodzakelijke randvoorwaarden. De reden dat we het gratis kunnen organiseren is dat Microsoft onze hoofdsponsor is en Class-A onze silversponsor (ja, inderdaad: hetzelfde &lt;a href="http://www.class-a.nl/" target="_blank"&gt;Class-A&lt;/a&gt; waar we 2 dagen eerder, dus 4 september een dotNed meeting hebben: heb je je al &lt;a href="http://www.dotned.nl/meetings.default.aspx" target="_blank"&gt;ingeschreven&lt;/a&gt;? )&lt;/p&gt;  &lt;p&gt;Het enige wat we van je verlangen is dat je je even inschrijft op &lt;a href="http://www.codecamp.nl"&gt;http://www.codecamp.nl&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;We hebben er voor gezorgd dat we een indrukwekkende lijst met onderwerpen hebben. Ook de sprekerslijst mag er zijn: het is een mix van sprekers uit de community en professionele sprekers die regelmatig op events als TechEd staan. En dat allemaal voor niets!&lt;/p&gt;  &lt;p&gt;Kijk voor meer informatie en natuurlijk om je in te schrijven op &lt;a href="http://www.codecamp.nl"&gt;http://www.codecamp.nl&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Graag zie ik je op zaterdag 6 september!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=884" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/28/884.aspx</link>
      <author>dvroegop</author>
      <pubDate>Thu, 28 Aug 2008 20:20:47 GMT</pubDate>
    </item>
    <item>
      <title>3D Graphics in WPF, deel 8a (de source code)</title>
      <description>&lt;p&gt;Ik heb alle source code even in een projectje geplaatst, zodat je er mee kunt spelen. Je vindt de&amp;#160; sources &lt;a title="Source files voor 3D WPF" target="_blank" href="http://www.dotned.nl/files/13/code/entry882.aspx"&gt;hier&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=883" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/28/883.aspx</link>
      <author>dvroegop</author>
      <pubDate>Thu, 28 Aug 2008 11:10:04 GMT</pubDate>
    </item>
    <item>
      <title>3D Graphics in WPF, deel 8 (het tekenen van de box in code)</title>
      <description>&lt;p&gt;We hebben bijna alle elementen op hun plaats staan voor onze Box class. Het enige wat we nu nog moeten doen is het daadwerkelijke tekenen. Hier is de code&lt;/p&gt;  &lt;div class="cf"&gt;   &lt;p class="cl"&gt;&lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb1"&gt;void&lt;/span&gt; DrawIt()&lt;/p&gt;    &lt;p class="cl"&gt;{&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb2"&gt;// Maak een kopie&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb1"&gt;var&lt;/span&gt; positions = _mesh.Positions;&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb1"&gt;var&lt;/span&gt; indices = _mesh.TriangleIndices;&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb1"&gt;var&lt;/span&gt; normals = _mesh.Normals;&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb1"&gt;var&lt;/span&gt; textures = _mesh.TextureCoordinates;&lt;/p&gt;    &lt;p class="cl"&gt; &lt;/p&gt;    &lt;p class="cl"&gt;    _mesh.Positions = &lt;span class="cb1"&gt;null&lt;/span&gt;;&lt;/p&gt;    &lt;p class="cl"&gt;    _mesh.TriangleIndices = &lt;span class="cb1"&gt;null&lt;/span&gt;;&lt;/p&gt;    &lt;p class="cl"&gt;    _mesh.Normals = &lt;span class="cb1"&gt;null&lt;/span&gt;;&lt;/p&gt;    &lt;p class="cl"&gt;    _mesh.TextureCoordinates = &lt;span class="cb1"&gt;null&lt;/span&gt;;&lt;/p&gt;    &lt;p class="cl"&gt; &lt;/p&gt;    &lt;p class="cl"&gt;    positions.Clear();&lt;/p&gt;    &lt;p class="cl"&gt;    indices.Clear();&lt;/p&gt;    &lt;p class="cl"&gt;    normals.Clear();&lt;/p&gt;    &lt;p class="cl"&gt;    textures.Clear();&lt;/p&gt;    &lt;p class="cl"&gt; &lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb2"&gt;// Definieer de punten&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb3"&gt;Point3D&lt;/span&gt; pointA = LeftBottomCorner;&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb3"&gt;Point3D&lt;/span&gt; pointB = &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb3"&gt;Point3D&lt;/span&gt;(LeftBottomCorner.X + Width, LeftBottomCorner.Y, LeftBottomCorner.Z);&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb3"&gt;Point3D&lt;/span&gt; pointC = &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb3"&gt;Point3D&lt;/span&gt;(LeftBottomCorner.X + Width, LeftBottomCorner.Y, LeftBottomCorner.Z - Depth);&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb3"&gt;Point3D&lt;/span&gt; pointD = &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb3"&gt;Point3D&lt;/span&gt;(LeftBottomCorner.X, LeftBottomCorner.Y, LeftBottomCorner.Z - Depth);&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb3"&gt;Point3D&lt;/span&gt; pointE = &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb3"&gt;Point3D&lt;/span&gt;(LeftBottomCorner.X, LeftBottomCorner.Y + Height, LeftBottomCorner.Z);&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb3"&gt;Point3D&lt;/span&gt; pointF = &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb3"&gt;Point3D&lt;/span&gt;(LeftBottomCorner.X + Width, LeftBottomCorner.Y + Height, LeftBottomCorner.Z);&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb3"&gt;Point3D&lt;/span&gt; pointG = &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb3"&gt;Point3D&lt;/span&gt;(LeftBottomCorner.X + Width, LeftBottomCorner.Y + Height, LeftBottomCorner.Z - Depth);&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb3"&gt;Point3D&lt;/span&gt; pointH = &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb3"&gt;Point3D&lt;/span&gt;(LeftBottomCorner.X, LeftBottomCorner.Y + Height, LeftBottomCorner.Z - Depth);&lt;/p&gt;    &lt;p class="cl"&gt; &lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb2"&gt;// Voeg de punten toe &lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb2"&gt;// Grond vlak&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointD);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointC);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointB);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointA);&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb2"&gt;// Voor vlak&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointA);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointB);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointF);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointE);&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb2"&gt;// Rechtervlak&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointB);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointC);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointG);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointF);&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb2"&gt;// Achter vlak&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointC);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointD);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointH);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointG);&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb2"&gt;// Linker vlak&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointD);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointA);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointE);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointH);&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb2"&gt;// Boven vlak&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointE);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointF);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointG);&lt;/p&gt;    &lt;p class="cl"&gt;    positions.Add(pointH);&lt;/p&gt;    &lt;p class="cl"&gt; &lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb2"&gt;// Voeg de TriangleIndices toe.&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb1"&gt;for&lt;/span&gt; (&lt;span class="cb1"&gt;int&lt;/span&gt; i = 0; i     &lt;p class="cl"&gt;    {&lt;/p&gt;    &lt;p class="cl"&gt;        indices.Add((i * 4) + 0);&lt;/p&gt;    &lt;p class="cl"&gt;        indices.Add((i * 4) + 1);&lt;/p&gt;    &lt;p class="cl"&gt;        indices.Add((i * 4) + 2);&lt;/p&gt;    &lt;p class="cl"&gt;        indices.Add((i * 4) + 0);&lt;/p&gt;    &lt;p class="cl"&gt;        indices.Add((i * 4) + 2);&lt;/p&gt;    &lt;p class="cl"&gt;        indices.Add((i * 4) + 3);&lt;/p&gt;    &lt;p class="cl"&gt;    }&lt;/p&gt;    &lt;p class="cl"&gt; &lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb2"&gt;// Zet de collections terug in de mesh&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;    _mesh.TextureCoordinates = textures;&lt;/p&gt;    &lt;p class="cl"&gt;    _mesh.Normals = normals;&lt;/p&gt;    &lt;p class="cl"&gt;    _mesh.TriangleIndices = indices;&lt;/p&gt;    &lt;p class="cl"&gt;    _mesh.Positions = positions;&lt;/p&gt;    &lt;p class="cl"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Het lijkt veel maar echt ingewikkeld is het niet. Er is echter een klein dingetje dat wel erg belangrijk is: de properties Positions, TriangleIndices, Normals en TextureCoordinates (die laaste is nieuw, daar kom ik op terug als we het over materialen gaan hebben) zijn DependencyProperties. Als we iets wijzigigen in deze collections, zal er een PropertyChanged even afgevuurd worden in onze _mesh member (van het type MeshGeometry3D) en wordt de boel opnieuw getekend. Voor ieder punt dat we toevoegen zal hij opnieuw berekend worden. Ook voor iedere TriangleIndex die we toevoegen gaan WPF opnieuw rekenen. Hetzelfde geldt voor de Normals en TextureCoordinates collections. Aangezien we een hoop punten en zo toevoegen zal er een hoop nodeloze berekeningen plaats gaan vinden! &lt;/p&gt;  &lt;p&gt;Om dat te voorkomen maken we eerst een kopie van de collections. Vervolgens zetten we de properties van de _mesh op null. Als we nu iets doen met de kopie van de collections heeft dat geen enkele invloed op de _mesh. Aan het einde van de method plaatsen we de gewijzigde collecties weer terug in de _mesh waarna WPF alles opnieuw gaat berekenen. Dit scheelt enorm veel tijd!&lt;/p&gt;  &lt;p&gt;Nu we een kopie hebben van de collecties, wissen we de inhoud. Immers: we gaan alles opnieuw maken!&lt;/p&gt;  &lt;p&gt;Ik definieer eerst de 8 hoekpunten. Dat hoef ik maar een maal te doen, we hergebruiken de gemaakte punten later bij het toevoegen aan de positions collectie. Je ziet dat de punten gelijk op de goede plaats staan: ik tel de linkeronder hoek er bij op en zorg ervoor dat de Width, Height en Depth gelijk meegenomen worden.&lt;/p&gt;  &lt;p&gt;Nu definieren we de zes vlakken. Let er op dat je het wel in de goede volgorde doet, alle punten worden tegen de klok in gedefinieerd. &lt;/p&gt;  &lt;p&gt;Als we alle punten toegevoegd hebben, wordt het tijd om de TriangleIndices berekent. Dit is hetzelfde als wat je gezien hebt in mijn vorige post, nu alleen voor alle vlakken. Als dat gebeurdt is, plaatsen we de collecties terug en we zijn klaar!&lt;/p&gt;  &lt;p&gt;Nou ja.. we moeten nog een aanroep naar DrawIt() plaatsen in de constructor (aan het einde) en belangrijker: in de PropertyChanged:&lt;/p&gt;  &lt;div class="cf"&gt;   &lt;p class="cl"&gt;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Initializes a new instance of the &lt;/span&gt;&lt;span class="cb1"&gt;&lt;/span&gt;&lt;span class="cb2"&gt; class.&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb3"&gt;public&lt;/span&gt; Box()&lt;/p&gt;    &lt;p class="cl"&gt;{&lt;/p&gt;    &lt;p class="cl"&gt;    _model = &lt;span class="cb3"&gt;new&lt;/span&gt; &lt;span class="cb4"&gt;GeometryModel3D&lt;/span&gt;();&lt;/p&gt;    &lt;p class="cl"&gt;    _mesh = &lt;span class="cb3"&gt;new&lt;/span&gt; &lt;span class="cb4"&gt;MeshGeometry3D&lt;/span&gt;();&lt;/p&gt;    &lt;p class="cl"&gt;    _model.Geometry = _mesh;&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb3"&gt;this&lt;/span&gt;.Content = _model;&lt;/p&gt;    &lt;p class="cl"&gt; &lt;/p&gt;    &lt;p class="cl"&gt;    DrawIt();&lt;/p&gt;    &lt;p class="cl"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;en...&lt;/p&gt;  &lt;div class="cf"&gt;   &lt;p class="cl"&gt;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Handles the Property Changed event (static)&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&lt;/span&gt;&lt;span class="cb2"&gt;The &lt;/span&gt;&lt;span class="cb1"&gt;&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; instance containing the event data.&lt;/span&gt;&lt;span class="cb1"&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb3"&gt;private&lt;/span&gt; &lt;span class="cb3"&gt;void&lt;/span&gt; PropertyChanged(&lt;span class="cb4"&gt;DependencyPropertyChangedEventArgs&lt;/span&gt; args)&lt;/p&gt;    &lt;p class="cl"&gt;{&lt;/p&gt;    &lt;p class="cl"&gt;    &lt;span class="cb2"&gt;// opnieuw tekenen!&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;    DrawIt();&lt;/p&gt;    &lt;p class="cl"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Om dit nu zichtbaar te maken in onze XAML file, moeten we een referentie naar deze code in de header van de file maken.&lt;/p&gt;  &lt;p&gt;De XAML ziet er nu als volgt uit:&lt;/p&gt; 
&lt;pre class="csharpcode"&gt;
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt; &lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;="WpfApplication11.Window1"&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;="http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:detrio&lt;/span&gt;&lt;span class="kwrd"&gt;="clr-namespace:WpfApplication11"&lt;/span&gt;
    &lt;span class="attr"&gt;Title&lt;/span&gt;&lt;span class="kwrd"&gt;="Window1"&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;="300"&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;="300"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Viewport3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;detrio:Box&lt;/span&gt; &lt;span class="attr"&gt;LeftBottomCorner&lt;/span&gt;&lt;span class="kwrd"&gt;="0 0 0"&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;="1"&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;="1"&lt;/span&gt; &lt;span class="attr"&gt;Depth&lt;/span&gt;&lt;span class="kwrd"&gt;="1"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;detrio:Box.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;="Blue"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;detrio:Box.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;detrio:Box&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="rem"&gt;&amp;lt;!-- Lampjes! --&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Model3DGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AmbientLight&lt;/span&gt; &lt;span class="attr"&gt;Color&lt;/span&gt;&lt;span class="kwrd"&gt;="#404040"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DirectionalLight&lt;/span&gt; &lt;span class="attr"&gt;Color&lt;/span&gt;&lt;span class="kwrd"&gt;="#BFBFBF"&lt;/span&gt; &lt;span class="attr"&gt;Direction&lt;/span&gt;&lt;span class="kwrd"&gt;="1 -1 -1"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Model3DGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="rem"&gt;&amp;lt;!-- Camera --&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Viewport3D.Camera&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;PerspectiveCamera&lt;/span&gt; &lt;span class="attr"&gt;Position&lt;/span&gt;&lt;span class="kwrd"&gt;="2.1 2 2"&lt;/span&gt; 
                           &lt;span class="attr"&gt;LookDirection&lt;/span&gt;&lt;span class="kwrd"&gt;="-0.5 -0.7 -1"&lt;/span&gt; 
                           &lt;span class="attr"&gt;UpDirection&lt;/span&gt;&lt;span class="kwrd"&gt;="0 1 0"&lt;/span&gt; 
                           &lt;span class="attr"&gt;FieldOfView&lt;/span&gt;&lt;span class="kwrd"&gt;="60.0"&lt;/span&gt; 
                           &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Viewport3D.Camera&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Viewport3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;En meer hebben we niet nodig!&lt;/p&gt;

&lt;p&gt;Ik weet niet hoe het met jou zit, maar ik ben dat blauwe blokje een beetje zat. Laten we de volgende keer eens kijken of we die niet mooier kunnen maken, laten we het eens over Materials gaan hebben!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=881" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/28/881.aspx</link>
      <author>dvroegop</author>
      <pubDate>Thu, 28 Aug 2008 10:24:00 GMT</pubDate>
    </item>
    <item>
      <title>3D Graphics in WPF, deel 7 (de box in code)</title>
      <description>&lt;p&gt;Ik ben MVP voor C#, dus het wordt tijd dat ik terug ga naar mijn roots en wat C# code laat zien.&lt;/p&gt;  &lt;p&gt;In mijn &lt;a href="http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/27/876.aspx" target="_blank"&gt;vorige post&lt;/a&gt; heb ik laten zien hoe je een kubus definieert. Het kwam neer op veel punten berekenen en vervolgens aangeven hoe je die punten met elkaar verbindt. Nu hebben we allemaal een computer voor onze neus staan en als er iets is waar computers goed in zijn, is het wel in rekenen. Waarom zouden we dat dan handmatig doen? Laten we de punten voor de kubussen in code berekenen!&lt;/p&gt;  &lt;p&gt;Nu is het natuurlijk erg eenvoudig om een stuk code te schrijven die een paar parameters krijgt (een positie en de afmetingen) en die dan XAML code uitspuugt die je kunt plakken in je XAML bestand, maar dat is niet wat we willen.&lt;/p&gt;  &lt;p&gt;We willen dat we in onze XAML code de volgende code op kunnen nemen met als resultaat dat er een mooi kubusje op het scherm staat:&lt;/p&gt;   &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;detrio:Box&lt;/span&gt; &lt;span class="attr"&gt;LeftBottomCorner&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 0&amp;quot;&lt;/span&gt;
            &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;2.0&amp;quot;&lt;/span&gt;
            &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt;
            &lt;span class="attr"&gt;Depth&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.5&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;detrio:Box.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Blue&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;detrio:Box.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;detrio:Box&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Dat gaan we dan ook doen.&lt;/p&gt;

&lt;p&gt;We moeten onze Box class kunnen toevoegen aan onze Viewport3D. We hebben gezien hoe we dat in XAML doen: we maken een GeometryModel3D, zetten de punten en triangleindices goed en klaar. Het lijkt voor de hand liggend om onze Box class af te leiden van GeometryModel3D ware het niet dat dat niet kan: bijna alles in WPF is sealed en kan dus niet als base-class gebruikt worden.&lt;/p&gt;

&lt;p&gt;Een van de weinige classes die dat niet hebben is ModelVisual3D. Nu is dit gelukkig ook de class die in de Children collection van een Viewport3D geplaatst kan worden, dus laten we die maar gebruiken.&lt;/p&gt;

&lt;p&gt;Definieer de volgende class:&lt;/p&gt;

&lt;div class="cf"&gt;
  &lt;p class="cl"&gt;&lt;span class="cb1"&gt;//-----------------------------------------------------------------------&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cb1"&gt;// &amp;lt;copyright file=&amp;quot;Box.cs&amp;quot; company=&amp;quot;Detrio Consultancy b.v.&amp;quot;&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cb1"&gt;//&amp;#160;&amp;#160;&amp;#160; Copyright (c) Detrio Consultancy b.v. All rights reserved.&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cb1"&gt;// &amp;lt;/copyright&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cb1"&gt;// &amp;lt;author&amp;gt;Dennis Vroegop&amp;lt;/author&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cb1"&gt;//-----------------------------------------------------------------------&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cb2"&gt;namespace&lt;/span&gt; WpfApplication11&lt;/p&gt;

  &lt;p class="cl"&gt;{&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cb2"&gt;&amp;#160;&amp;#160;&amp;#160; #region&lt;/span&gt; Using statements&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb2"&gt;using&lt;/span&gt; System;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb2"&gt;using&lt;/span&gt; System.Windows.Media.Media3D;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cb2"&gt;&amp;#160;&amp;#160;&amp;#160; #endregion&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;///&lt;/span&gt;&lt;span class="cb1"&gt; &lt;/span&gt;&lt;span class="cb3"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;///&lt;/span&gt;&lt;span class="cb1"&gt; Een rechthoekig ding voor op het scherm&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;///&lt;/span&gt;&lt;span class="cb1"&gt; &lt;/span&gt;&lt;span class="cb3"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb2"&gt;internal&lt;/span&gt; &lt;span class="cb2"&gt;class&lt;/span&gt; &lt;span class="cb4"&gt;Box&lt;/span&gt; : &lt;span class="cb4"&gt;ModelVisual3D&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;

  &lt;p class="cl"&gt;}&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;We hebben nu een Box class welke afgeleid is van ModelVisual3D. Hier kunnen we in de Content dan onze GeometryModel3D maken, en in de GeometryModel3D onze MeshGeometry3D. Aangezien we dat altijd moeten doen kunnen we daar gelijk even een paar private fields van maken:&lt;/p&gt;

&lt;div class="cf"&gt;
  &lt;p class="cl"&gt;&lt;span class="cb1"&gt;internal&lt;/span&gt; &lt;span class="cb1"&gt;class&lt;/span&gt; &lt;span class="cb2"&gt;Box&lt;/span&gt; : &lt;span class="cb2"&gt;ModelVisual3D&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;{&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb2"&gt;GeometryModel3D&lt;/span&gt; _model;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb2"&gt;MeshGeometry3D&lt;/span&gt; _mesh;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;///&lt;/span&gt;&lt;span class="cb4"&gt; &lt;/span&gt;&lt;span class="cb3"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;///&lt;/span&gt;&lt;span class="cb4"&gt; Initializes a new instance of the &lt;/span&gt;&lt;span class="cb3"&gt;&amp;lt;see cref=&amp;quot;Box&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="cb4"&gt; class.&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;///&lt;/span&gt;&lt;span class="cb4"&gt; &lt;/span&gt;&lt;span class="cb3"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb1"&gt;public&lt;/span&gt; Box()&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _model = &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb2"&gt;GeometryModel3D&lt;/span&gt;();&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _mesh = &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb2"&gt;MeshGeometry3D&lt;/span&gt;();&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _model.Geometry = _mesh;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb1"&gt;this&lt;/span&gt;.Content = _model;&lt;/p&gt;

  &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;

  &lt;p class="cl"&gt;}&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Die hebben we maar alvast! &lt;/p&gt;

&lt;p&gt;Om een object zichtbaar te maken moeten we ook Materials kunnen toevoegen. Dus daar maken we gelijk maar even een property van. Of liever gezegd: een DependencyProperty. Voor diegene die niet weten wat een DependencyProperty is, raad ik je aan om &lt;a href="http://www.dotned.nl/blogs/dennis_blog/archive/2008/05/21/844.aspx" target="_blank"&gt;deze post&lt;/a&gt; eens te bekijken. Ik wacht wel even....&lt;/p&gt;

&lt;p&gt;Voeg de volgende code toe:&lt;/p&gt;

&lt;div class="cf"&gt;
  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; De material property die het uiterlijk bepaalt&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;span class="cb3"&gt;private&lt;/span&gt; &lt;span class="cb3"&gt;static&lt;/span&gt; &lt;span class="cb3"&gt;readonly&lt;/span&gt; &lt;span class="cb4"&gt;DependencyProperty&lt;/span&gt; MaterialProperty = &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb4"&gt;GeometryModel3D&lt;/span&gt;.MaterialProperty.AddOwner(&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;typeof&lt;/span&gt;(&lt;span class="cb4"&gt;Box&lt;/span&gt;), &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;new&lt;/span&gt; &lt;span class="cb4"&gt;PropertyMetadata&lt;/span&gt;(MaterialPropertyChanged));&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Gets or sets the material.&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt;The material.&lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&lt;span class="cb3"&gt;public&lt;/span&gt; &lt;span class="cb4"&gt;Material&lt;/span&gt; Material&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt; {&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;get&lt;/span&gt; { &lt;span class="cb3"&gt;return&lt;/span&gt; (&lt;span class="cb4"&gt;Material&lt;/span&gt;)GetValue(MaterialProperty); }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;set&lt;/span&gt; { SetValue(MaterialProperty, &lt;span class="cb3"&gt;value&lt;/span&gt;); }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt; }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Wordt aangeroepen als de MaterialProperty van inhoud wijzigt &lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; (static).&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 23&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 24&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;param name=&amp;quot;obj&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt;The obj.&lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 25&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;param name=&amp;quot;args&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt;The &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;see cref=&amp;quot;System.Windows.DependencyPropertyChangedEventArgs&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 26&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; instance containing the event data.&lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 27&lt;/span&gt;&amp;#160;&lt;span class="cb3"&gt;private&lt;/span&gt; &lt;span class="cb3"&gt;static&lt;/span&gt; &lt;span class="cb3"&gt;void&lt;/span&gt; MaterialPropertyChanged(&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 28&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb4"&gt;DependencyObject&lt;/span&gt; obj, &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 29&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb4"&gt;DependencyPropertyChangedEventArgs&lt;/span&gt; args)&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 30&lt;/span&gt; {&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 31&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (obj &lt;span class="cb3"&gt;as&lt;/span&gt; &lt;span class="cb4"&gt;Box&lt;/span&gt;).MaterialPropertyChanged(args);&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 32&lt;/span&gt; }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 33&lt;/span&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 34&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 35&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Wordt aangeroepen als de MaterialProperty van inhoud wijzigt &lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 36&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; (van deze instance)&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 37&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 38&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;param name=&amp;quot;args&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt;The &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;see cref=&amp;quot;System.Windows.DependencyPropertyChangedEventArgs&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 39&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; instance containing the event data.&lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 40&lt;/span&gt;&amp;#160;&lt;span class="cb3"&gt;private&lt;/span&gt; &lt;span class="cb3"&gt;void&lt;/span&gt; MaterialPropertyChanged(&lt;span class="cb4"&gt;DependencyPropertyChangedEventArgs&lt;/span&gt; args)&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 41&lt;/span&gt; {&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 42&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _model.Material = args.NewValue &lt;span class="cb3"&gt;as&lt;/span&gt; &lt;span class="cb4"&gt;Material&lt;/span&gt;;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 43&lt;/span&gt; }&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Dit is nogal wat. Ik zal uitleggen wat er hier gebeurt.&lt;/p&gt;

&lt;p&gt;In regels 1 tot en met 7 maken we de nieuwe DependencyProperty. Of liever gezegd, we vertellen de Material property van _model (die heeft immers de Material property al) dat er een nieuwe owner bij gekomen is: onze Box! Als er nu iets gebeurt met de Material property op de _model, dan krijgen wij daar ook een notificatie van. En andersom uiteraard ook: als wij iets met Material doen, komt dat uiteindelijk bij de GeometryModel3D _model aan. &lt;/p&gt;

&lt;p&gt;In regels 10 tot en met 18 maken we de normale CLR property aan, die niets anders doet dan de waardes doorgeven naar en van de DependencyProperty.&lt;/p&gt;

&lt;p&gt;In regels 20 tot en met 32 hebben we de static method die aangeroepen wordt als er iets met de Material gebeurd. Het enige wat we hier doen is het aanroepen van de instance method MaterialPropertyChanged zodat de juiste instance actie kan ondernemen. Dit gebeurdt in regels 34 tot en met 43. We geven hier de nieuwe material door aan onze _model.&lt;/p&gt;

&lt;p&gt;Laten we gelijk een paar andere DependencyProperties toevoegen:&lt;/p&gt;

&lt;p&gt;1. Een Point3D voor de LeftBottomCorner waar de box in de scene geplaatst moet worden&lt;/p&gt;

&lt;p&gt;2. Een double die de Width aangeeft&lt;/p&gt;

&lt;p&gt;3. Een double die de Height aangeeft&lt;/p&gt;

&lt;p&gt;4. Een double die de Depth aangeeft.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Komt 'ie:&lt;/p&gt;

&lt;div class="cf"&gt;
  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Left bottom corner&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;span class="cb3"&gt;private&lt;/span&gt; &lt;span class="cb3"&gt;static&lt;/span&gt; &lt;span class="cb3"&gt;readonly&lt;/span&gt; &lt;span class="cb4"&gt;DependencyProperty&lt;/span&gt; LeftBottomCornerProperty = &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb4"&gt;DependencyProperty&lt;/span&gt;.Register(&lt;span class="cb5"&gt;&amp;quot;LeftBottomCorner&amp;quot;&lt;/span&gt;, &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;typeof&lt;/span&gt;(&lt;span class="cb4"&gt;Point3D&lt;/span&gt;), &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;typeof&lt;/span&gt;(&lt;span class="cb4"&gt;Box&lt;/span&gt;), &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;new&lt;/span&gt; &lt;span class="cb4"&gt;PropertyMetadata&lt;/span&gt;(&lt;span class="cb3"&gt;new&lt;/span&gt; &lt;span class="cb4"&gt;Point3D&lt;/span&gt;(0.0, 0.0, 0.0), PropertyChanged));&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Width &lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&lt;span class="cb3"&gt;private&lt;/span&gt; &lt;span class="cb3"&gt;static&lt;/span&gt; &lt;span class="cb3"&gt;readonly&lt;/span&gt; &lt;span class="cb4"&gt;DependencyProperty&lt;/span&gt; WidthProperty = &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb4"&gt;DependencyProperty&lt;/span&gt;.Register(&lt;span class="cb5"&gt;&amp;quot;Width&amp;quot;&lt;/span&gt;, &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;typeof&lt;/span&gt;(&lt;span class="cb3"&gt;double&lt;/span&gt;), &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;typeof&lt;/span&gt;(&lt;span class="cb4"&gt;Box&lt;/span&gt;), &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;new&lt;/span&gt; &lt;span class="cb4"&gt;PropertyMetadata&lt;/span&gt;(1.0, PropertyChanged));&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Height &lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt;&amp;#160;&lt;span class="cb3"&gt;private&lt;/span&gt; &lt;span class="cb3"&gt;static&lt;/span&gt; &lt;span class="cb3"&gt;readonly&lt;/span&gt; &lt;span class="cb4"&gt;DependencyProperty&lt;/span&gt; HeightProperty = &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 23&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb4"&gt;DependencyProperty&lt;/span&gt;.Register(&lt;span class="cb5"&gt;&amp;quot;Height&amp;quot;&lt;/span&gt;, &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 24&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;typeof&lt;/span&gt;(&lt;span class="cb3"&gt;double&lt;/span&gt;), &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 25&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;typeof&lt;/span&gt;(&lt;span class="cb4"&gt;Box&lt;/span&gt;), &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 26&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;new&lt;/span&gt; &lt;span class="cb4"&gt;PropertyMetadata&lt;/span&gt;(1.0, PropertyChanged));&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 27&lt;/span&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 28&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 29&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Depth &lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 30&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 31&lt;/span&gt;&amp;#160;&lt;span class="cb3"&gt;private&lt;/span&gt; &lt;span class="cb3"&gt;static&lt;/span&gt; &lt;span class="cb3"&gt;readonly&lt;/span&gt; &lt;span class="cb4"&gt;DependencyProperty&lt;/span&gt; DepthProperty = &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 32&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb4"&gt;DependencyProperty&lt;/span&gt;.Register(&lt;span class="cb5"&gt;&amp;quot;Depth&amp;quot;&lt;/span&gt;, &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 33&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;typeof&lt;/span&gt;(&lt;span class="cb3"&gt;double&lt;/span&gt;), &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 34&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;typeof&lt;/span&gt;(&lt;span class="cb4"&gt;Box&lt;/span&gt;), &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 35&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;new&lt;/span&gt; &lt;span class="cb4"&gt;PropertyMetadata&lt;/span&gt;(1.0, PropertyChanged));&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 36&lt;/span&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 37&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 38&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Gets or sets the left bottom corner.&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 39&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 40&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt;The left bottom corner.&lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 41&lt;/span&gt;&amp;#160;&lt;span class="cb3"&gt;public&lt;/span&gt; &lt;span class="cb4"&gt;Point3D&lt;/span&gt; LeftBottomCorner&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 42&lt;/span&gt; {&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 43&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;get&lt;/span&gt; { &lt;span class="cb3"&gt;return&lt;/span&gt; (&lt;span class="cb4"&gt;Point3D&lt;/span&gt;)GetValue(LeftBottomCornerProperty); }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 44&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;set&lt;/span&gt; { SetValue(LeftBottomCornerProperty, &lt;span class="cb3"&gt;value&lt;/span&gt;); }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 45&lt;/span&gt; }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 46&lt;/span&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 47&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 48&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Gets or sets the width.&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 49&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 50&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt;The width.&lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 51&lt;/span&gt;&amp;#160;&lt;span class="cb3"&gt;public&lt;/span&gt; &lt;span class="cb3"&gt;double&lt;/span&gt; Width&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 52&lt;/span&gt; {&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 53&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;get&lt;/span&gt; { &lt;span class="cb3"&gt;return&lt;/span&gt; (&lt;span class="cb3"&gt;double&lt;/span&gt;)GetValue(WidthProperty); }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 54&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;set&lt;/span&gt; { SetValue(WidthProperty, &lt;span class="cb3"&gt;value&lt;/span&gt;); }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 55&lt;/span&gt; }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 56&lt;/span&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 57&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 58&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Gets or sets the height.&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 59&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 60&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt;The height.&lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 61&lt;/span&gt;&amp;#160;&lt;span class="cb3"&gt;public&lt;/span&gt; &lt;span class="cb3"&gt;double&lt;/span&gt; Height &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 62&lt;/span&gt; {&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 63&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;get&lt;/span&gt; { &lt;span class="cb3"&gt;return&lt;/span&gt; (&lt;span class="cb3"&gt;double&lt;/span&gt;)GetValue(HeightProperty); }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 64&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;set&lt;/span&gt; { SetValue(HeightProperty, &lt;span class="cb3"&gt;value&lt;/span&gt;); }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 65&lt;/span&gt; }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 66&lt;/span&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 67&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 68&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Gets or sets the depth.&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 69&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 70&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt;The depth.&lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 71&lt;/span&gt;&amp;#160;&lt;span class="cb3"&gt;public&lt;/span&gt; &lt;span class="cb3"&gt;double&lt;/span&gt; Depth &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 72&lt;/span&gt; {&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 73&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;get&lt;/span&gt; { &lt;span class="cb3"&gt;return&lt;/span&gt; (&lt;span class="cb3"&gt;double&lt;/span&gt;)GetValue(DepthProperty); }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 74&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;set&lt;/span&gt; { SetValue(DepthProperty, &lt;span class="cb3"&gt;value&lt;/span&gt;); }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 75&lt;/span&gt; }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 76&lt;/span&gt;&amp;#160;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 77&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 78&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Handles the Property Changed event (static)&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 79&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 80&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;param name=&amp;quot;obj&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt;The sender.&lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 81&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;param name=&amp;quot;args&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt;The &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;see cref=&amp;quot;System.Windows.DependencyPropertyChangedEventArgs&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 82&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; instance containing the event data.&lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 83&lt;/span&gt;&amp;#160;&lt;span class="cb3"&gt;private&lt;/span&gt; &lt;span class="cb3"&gt;static&lt;/span&gt; &lt;span class="cb3"&gt;void&lt;/span&gt; PropertyChanged(&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 84&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb4"&gt;DependencyObject&lt;/span&gt; obj, &lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 85&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb4"&gt;DependencyPropertyChangedEventArgs&lt;/span&gt; args)&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 86&lt;/span&gt; {&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 87&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (obj &lt;span class="cb3"&gt;as&lt;/span&gt; &lt;span class="cb4"&gt;Box&lt;/span&gt;).PropertyChanged(args);&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 88&lt;/span&gt; }&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 89&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 90&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; Handles the Property Changed event (static)&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 91&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 92&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;param name=&amp;quot;args&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt;The &lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;see cref=&amp;quot;System.Windows.DependencyPropertyChangedEventArgs&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="cb2"&gt; &lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 93&lt;/span&gt;&amp;#160;&lt;span class="cb1"&gt;///&lt;/span&gt;&lt;span class="cb2"&gt; instance containing the event data.&lt;/span&gt;&lt;span class="cb1"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 94&lt;/span&gt;&amp;#160;&lt;span class="cb3"&gt;private&lt;/span&gt; &lt;span class="cb3"&gt;void&lt;/span&gt; PropertyChanged(&lt;span class="cb4"&gt;DependencyPropertyChangedEventArgs&lt;/span&gt; args)&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 95&lt;/span&gt; {&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 96&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb2"&gt;// opnieuw tekenen!&lt;/span&gt;&lt;/p&gt;

  &lt;p class="cl"&gt;&lt;span class="cln"&gt;&amp;#160;&amp;#160; 97&lt;/span&gt; }&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Een hele lap, maar het meeste moet duidelijk zijn.&lt;/p&gt;

&lt;p&gt;We definieren een aantal DependencyProperties, maken de CLR properties en zorgen ervoor dat ze allemaal de PropertyChanged method aanroepen.&lt;/p&gt;

&lt;p&gt;Als er een wijziging komt in een van deze properties moeten we de box opnieuw gaan tekenen. Dat is wat we de volgende keer gaan doen!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=878" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/27/878.aspx</link>
      <author>dvroegop</author>
      <pubDate>Wed, 27 Aug 2008 17:18:28 GMT</pubDate>
    </item>
    <item>
      <title>3D Graphics in WPF, deel 6 (de box)</title>
      <description>&lt;p&gt;In de vorige posting liet ik je zien hoe je een vierkant definieert. Ik sloot af met de opmerking dat als je een kubus wilt tekenen, je vooral je gang moest gaan maar ik zou de code niet voor je intypen. De reden daarvoor is dat het heel veel saai werk is (waar heel makkelijk fouten insluipen!). Nou is het altijd aan te raden om mensen zelf aan het werk te zetten als ze iets willen leren, daar leren ze immers het meest van. Toch vond ik het een beetje flauw van me. Vandaar dat ik de code hier alsnog plaats. Let op: hier komt 'ie:&lt;/p&gt;   &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MeshGeometry3D&lt;/span&gt; 
            &lt;span class="attr"&gt;Positions&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 0, 1 0 0, 1 0 -1, 0 0 -1,
                       0 1 0, 1 1 0, 1 1 -1, 0 1 -1&amp;quot;&lt;/span&gt;
            &lt;span class="attr"&gt;TriangleIndices&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 5, 0 5 4,
                             1 2 6, 1 6 5,
                             2 3 7, 2 7 6,
                             3 0 4, 3 4 7,
                             4 5 6, 4 6 7,
                             0 3 2, 0 2 1&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Blue&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.BackMaterial&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;HotPink&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; 
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.BackMaterial&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Tja. Zoals ik al zei: niet echt spannend, maar wel veel werk en vooral saai. Ik definieer eerst de punten voor het grondvlak, daarna de punten voor het bovenste vlak. Dan in de TriangleIndices verbind ik alle punten met elkaar, tegen de klok in. Als je nu met je camera gaat draaien zal er een box uitkomen. Maar... hij ziet er een beetje raar uit:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel6debox_DE87/image.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="image" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel6debox_DE87/image_thumb.png" width="244" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;(ik gebruik voor de camera als Position (2.1, 2.0, 2.0) en als LookDirection (-0.5, -0.7, -1.0) )&lt;/p&gt;

&lt;p&gt;Geen mooie vlakken, maar wel een mooi verloop in de kleuren. Niet helemaal zoals mijn box er in &lt;a href="http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/27/873.aspx" target="_blank"&gt;deel 3&lt;/a&gt; er uit zag. Hoe kan dat nou? &lt;/p&gt;

&lt;p&gt;Het antwoord heeft te maken met de belichting en hoe WPF die berekent. In deel 3 vertelde ik je dat de DirectionalLight voor ieder punt berekend hoeveel licht er op valt. Dat doet hij door naar de vector van de DirectionalLight.Direction te kijken en dan te berekenen hoe die zich verhoudt tot de normalvectors van onze vlakken. Als de direction vector het tegenovergestelde is van de normalvector van ons vlak, is de lichtinval 100%. Als hij er haaks op staat (of zelfs enigzins de zelfde richting opgaat) dan is de lichtinval 0%. En voor vectoren daar tussen in is de lichtinval een percentage van de totale hoeveelheid licht.&lt;/p&gt;

&lt;p&gt;Dit doet WPF echter niet voor iedere normalvector per driehoek maar voor iedere normalvector op een punt.... Dus: WPF berekent voor ieder punt in onze objecten een normal vector en vermenigvuldigt die met de direction vector van het licht. Maar hoe berekent hij nu de normalvector van een punt? Een punt is namelijk geen vlak (daar heb je minstens 3 punten voor nodig) dus hoe doet hij dat nu? Het antwoord is simpel. WPF kijkt naar de vlakken waar dit punt deel uit van maakt, berekent voor die vlakken de normalvector en dat is dat de normalvector van de punten die bij dat vlak horen. &lt;/p&gt;

&lt;p&gt;In theorie is dat simpel, in de praktijk is dat wat lastiger. Kijk bijvoorbeeld eens naar ons punt met de coordinaten (0,0,0). Bij welk vlak hoort dat? Volgens mij hoort dat bij 3 vlakken: het voorste vlak, het linkervlak en het onderste vlak. Dus hoe ziet de normalvector er dan uit? Tja: dat moet er wel uitzien als in het volgende plaatje. Ik heb gelijk de vectoren voor de andere punten erbij geplaatst.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel6debox_DE87/image_3.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="image" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel6debox_DE87/image_thumb_3.png" width="244" height="226" /&gt;&lt;/a&gt; Als de lichtinval op het grondvlak 100% zou moeten zijn, zou dat alleen gebeuren als de normaalvectoren loodrecht op dat vlak staan. Maar aangezien de verschillende hoekpunten onderdeel van meerdere vlakken zijn, wordt de normaalvectoren van die punten het gemiddelde van de normaalvectoren van de drie vlakken waar ieder punt bij hoort.&lt;/p&gt;

&lt;p&gt;Erger nog: de kleur tussen de punten A en E wordt voor iedere pixel tussen die punten berekend: aangezien A en E totaal verschillende normaalvectoren en dus lichtintensiteiten hebben, zal het resultaat een verloop zijn. WPF gaat de kleuren mooi in elkaar over laten lopen.&lt;/p&gt;

&lt;p&gt;Dit effect kan heel handig zijn. Als je een gebogen oppervlakte wilt tekenen zonder al te veel driehoeken te moeten tekenen, is dit precies het effect dat je wilt: door de gradients lijken de oppervlaktes gebogen te zijn. Maar in het geval van een box is dat helemaal niet handig! &lt;/p&gt;

&lt;p&gt;We kunnen dit oplossen door het probleem bij de wortel aan te pakken. Als de oorzaak van het probleem ligt bij het delen van punten door verschillende vlakken, moeten we eenvoudigweg voor ieder vlak een eigen set punten definieren.&lt;/p&gt;

&lt;p&gt;We krijgen dus in plaats van 8 punten 6 vlakken maal 4 punten per vlak = 24 punten (we delen per vierkant wel een paar punten maar aangezien die in hetzelfde vlak liggen geeft het niet: ze hebben toch al dezelfde normaalvector). Dat er van die 24 punten veel hetzelfde zijn is iets dat we dan maar voor lief moeten nemen.&lt;/p&gt;

&lt;p&gt;De code ziet er nu als volgt uit:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MeshGeometry3D&lt;/span&gt; 
            &lt;span class="attr"&gt;Positions&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 0, 1 0 0, 1 1 0, 0 1 0,
                       1 0 0, 1 0 -1, 1 1 -1, 1 1 0,
                       1 0 -1, 0 0 -1, 0 1 -1, 1 1 -1,
                       0 0 -1, 0 0 0, 0 1 0, 0 1 -1,
                       0 1 0, 1 1 0, 1 1 -1, 0 1 -1,
                       0 0 0, 0 0 -1, 1 0 -1, 1 0 0&amp;quot;&lt;/span&gt;
            &lt;span class="attr"&gt;TriangleIndices&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 2 0 2 3
                             4 5 6 4 6 7
                             8 9 10 8 10 11
                             12 13 14 12 14 15
                             16 17 18 16 18 19
                             20 21 22 20 22 23&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Meer punten maar maak je daar geen zorgen om: WPF is erg efficient met het geheugengebruik en dit zal geen noemenswaardige effecten op je performance hebben.&lt;/p&gt;

&lt;p&gt;Het resultaat is een stuk beter: &lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel6debox_DE87/image_4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="image" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel6debox_DE87/image_thumb_4.png" width="244" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Dit lijkt tenminste op een kubus! &lt;/p&gt;

&lt;p&gt;Maar nu willen we niet 1 kubus hebben, maar een paar honderd. En allemaal op verschillende plekken, en uiteraard van verschillende afmetingen! Dat wordt een hoop rekenwerk ben ik bang. Of toch niet? Kunnen we dit niet op de een of andere manier in code vatten?&lt;/p&gt;

&lt;p&gt;Ik zou die vraag niet stellen als het antwoord niet &amp;quot;ja&amp;quot; zou zijn. En dat is precies wat ik in de volgende post ga doen! We maken een C# class die dit voor ons doet zodat we in XAML de volgende code kunnen plakken:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;detrio:Box&lt;/span&gt; &lt;span class="attr"&gt;LeftBottomCorner&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 0&amp;quot;&lt;/span&gt;
            &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;2.0&amp;quot;&lt;/span&gt;
            &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt;
            &lt;span class="attr"&gt;Depth&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.5&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;detrio:Box.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Blue&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;detrio:Box.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;detrio:Box&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;En dat is een stuk beter leesbaar dan dat gedoe met die Positions toch?&lt;/p&gt;

&lt;p&gt;PS We hadden het probleem ook anders op kunnen lossen: we hadden zelf de normals kunnen berekenen en dan toch de punten kunnen hergebruiken. Ik wilde je echter laten zien hoe hergebruik van punten rare effecten op kan leveren. Daarnaast is het berekenen van Normals vrij ingewikkeld als je verder gaat dan een simpel kubusje, waardoor het veel eenvoudiger is om de punten te herdefinieren. Het zelf berekenen van normals kan wel een performance winst opleveren...&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=876" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/27/876.aspx</link>
      <author>dvroegop</author>
      <pubDate>Wed, 27 Aug 2008 16:35:29 GMT</pubDate>
    </item>
    <item>
      <title>3D Graphics in WPF, deel 5 (GeometryModel3D)</title>
      <description>&lt;p&gt;Eindelijk: we gaan dingen tekenen! Na alle noodzakelijk gepraat over camera's, lampen, punten en vectoren gaan we eindelijk aan de slag met iets dat zichtbaar op het scherm komt!&lt;/p&gt;  &lt;p&gt;In het eerste voorbeeld gaf ik al een vierkantje weer, zodat we in ieder geval &lt;em&gt;iets &lt;/em&gt;op het scherm zagen. Ik geef toe: echt indrukwekkend is het niet maar het was een begin!&lt;/p&gt;  &lt;p&gt;Als je denkt: waarom liet hij de code voor een vierkantje zien en in de screenshots liet hij kubusjes zien, dan is het antwoord: omdat dat eenvoudiger was.&lt;/p&gt;  &lt;p&gt;In WPF is er helaas geen enkele class met de naam Cube. Of Cylinder. Of Sphere, Torus, Teapot of wat voor fraais dan ook. WPF kent alleen maar verzamelingen van punten. Een vierkant is voor WPF niets anders dan een set met 4 punten die op een bepaalde plek in de 3D scene staan en de volgorde waarin die punten getekend moeten worden. Nu is een vierkant niet zo ingewikkeld: het zijn maar 4 punten verbonden door 4 lijnen. Een kubus is al ingewikkelder, die bestaat immers uit 8 punten verbonden door 12 lijnen. &lt;/p&gt;  &lt;p&gt;Het wordt nog ingewikkelder als je je realiseert dat WPF eigenlijk alleen maar driehoeken kan tekenen.... Een vierkant bestaat uit 2 driehoeken, een kubus uit 12 driehoeken. Uit hoeveel driehoeken een bol bestaat ligt er maar net aan hoe je hem definieert, maar het aantal driehoeken loopt al gauw in de honderden of zelfs duizenden.&lt;/p&gt;  &lt;p&gt;Nu is dat niets om je zorgen over te maken: grafische kaarten tegenwoordig zijn helemaal geoptimaliseerd in het tekenen van heel, heel erg veel driehoeken. Iets anders kennen ze niet maar driehoeken: daar zijn ze dol op!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel5GeometryModel3D_BFED/image.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 5px; border-right-width: 0px" border="0" alt="image" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel5GeometryModel3D_BFED/image_thumb.png" width="484" height="484" /&gt;&lt;/a&gt;Laten we even kijken naar ons vierkantje. Deze bestaat uit 4 punten (A, B, C, en D) en 2 driehoeken ( (A,B,C) en (A,C,D)). We vertellen WPF dus dat we een driehoek willen tekenen. We geven eerst de punten mee (de volgorde maakt eigenlijk niet uit). In ons geval dus de punten A, B en C. Dan vertellen we WPF dat hij de punten in een bepaalde volgorde moet verbinden. Vanuit punt A naar punt B, vanuit B naar punt C. Aangezien we met driehoeken werken en een driehoek altijd 3 zijdes heeft, 'weet' WPF dat het laaste punt dus vanuit C naar A gaat: hij sluit hem zelf wel af.&lt;/p&gt;  &lt;p&gt;De volgorde van de lijnen is&lt;em&gt;&amp;#160; wel &lt;/em&gt;belangrijk: dit moet altijd tegen de klok in! Waarom is dat nou weer? Een vlak (zoals onze driehoek) heeft twee kanten: een voorkant en een achterkant. Wat precies de voorkant is en wat de achterkant, weet WPF niet: dat hangt af van de plaats, de rotatie en van de plek van de camera. Om te bepalen wat nou de voorkant is berekent WPF de normaal vector uit. De drie opgeven punten A, B en C liggen in 1 vlak (in ons geval liggen ze allemaal op het vlak dat recht voor ons is: langs de Y as recht omhoog of omlaag). De normaal vector is een vector die daar haaks op staat.&amp;#160; Als we ons vlak zouden neerleggen zie je dat de normaalvector haaks op onze driehoek staat en uit het scherm wijst:&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel5GeometryModel3D_BFED/image_3.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="image" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel5GeometryModel3D_BFED/image_thumb_3.png" width="539" height="238" /&gt;&lt;/a&gt; De voorkant van ons driehoekje is het punt vanuit waar de normaal vector wijst. WPF berekent dat door de 3 punten te nemen en daar een vector haaks op te zetten. Nu is de volgorde van belang. Omdat we aangegeven hebben dat we vanuit A naar B, vanuit B naar C (en automatisch vanuit C naar A) gaan, is de normaal vector een Vector3D (0,0,1). Als we nu de punten aangegeven hadden als vanuit A naar C, vanuit C naar B en vanuit B naar A (dus met de klok mee) dan had de normaal vector precies de andere kant opgegaan (0,0,-1). Dat betekent dus dat de achterkant van het driehoekje naar de kijker toe had gestaan!&lt;/p&gt;  &lt;p&gt;Geloof me: deze fout ga je nog regelmatig maken.... Gelukkig is er een hulpmiddel die je hier bij helpt, daar kom ik later nog op.&lt;/p&gt;  &lt;p&gt;Ok. We hebben dus drie punten gegeven en verteld in welke volgorde die aan elkaar geknoopt moeten worden. Maar nu zijn we er nog niet: dit is pas de helft van ons vierkantje! We hebben nog een driehoek te tekenen. Nu kunnen we aan WPF de punten A, C en D geven en vertellen dat ze in die volgorde aan elkaar moeten worden geknoopt. Als we dat gedaan hebben zijn we in principe klaar!&lt;/p&gt;  &lt;p&gt;Laten we eens wat code bekijken. Onze vierkantje staat, zoals alles in 3D WPF, in een ModelVisual3D (of liever: in de Content van een ModelVisual3D). We voegen dus deze code toe aan onze WPF applicatie. Het resultaat (inclusief lampen en camera) is dan:&lt;/p&gt;   &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt; &lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;WpfApplication11.Window1&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;Title&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Window1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Viewport3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="rem"&gt;&amp;lt;!-- Hier komt ons vierkantje en later onze kubus --&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="rem"&gt;&amp;lt;!-- Lampjes! --&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Model3DGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AmbientLight&lt;/span&gt; &lt;span class="attr"&gt;Color&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;#404040&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DirectionalLight&lt;/span&gt; &lt;span class="attr"&gt;Color&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;#BFBFBF&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Direction&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1 -1 -1&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Model3DGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="rem"&gt;&amp;lt;!-- Camera --&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Viewport3D.Camera&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;PerspectiveCamera&lt;/span&gt; &lt;span class="attr"&gt;Position&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 5&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;LookDirection&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 -1&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;UpDirection&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 0&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;FieldOfView&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;60.0&amp;quot;&lt;/span&gt; 
                           &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Viewport3D.Camera&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Viewport3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Deze code compileert niet: de content mag niet leeg zijn. Dit gaan we zo oplossen. &lt;/p&gt;

&lt;p&gt;Ik ga vanaf nu niet meer de hele code plakken (ik word niet per blogregel betaald :-) ) maar ik hou me alleen bezig met het stuk dat in de plaats van de commentaar regel &amp;lt;!-- hier komt ... --&amp;gt; komt. Dat houdt het allemaal wat leesbaarder.&lt;/p&gt;

&lt;p&gt;We kunnen behalve lampjes maar 1 ding toevoegen op deze plaats: een GeometryModel3D. Deze class bevat alles wat WPF nodig heeft om te tekenen (in een volgende versie van WPF hoop ik dat er naast de GeometryModel3D ook een Cube3D, Cylinder3D enzovoorts komen...) Deze GeometryModel3D heeft 4 belangrijke dependency&amp;#160; properties: Geometry, Material, BackMaterial en Transform. &lt;/p&gt;

&lt;p&gt;In Geometry plaatsen we de punten en de verbindingen tussen de punten. In Material en BackMaterial geven we aan hoe de driehoeken er uit moeten gaan zien en in Transform kunnen we de boel draaien, vergroten, verkleinen en/of verplaatsen.&lt;/p&gt;

&lt;p&gt;In Geometry kan maar 1 class geplaatst worden: de MeshGeometry3D. Een MeshGeometry3D is een verzameling van driehoeken.... Deze heeft (onder andere) de volgende properties: Positions en TriangleIndices. De Positions is een collection van Point3D structs, dus alle punten van onze driehoek, terwijl de TriangleIndices een collection van Int32 waardes zijn die aangeven in welke volgorde de punten verbonden moeten worden. Meer hebben we niet nodig!&lt;/p&gt;

&lt;p&gt;De code ziet er als volgt uit:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MeshGeometry3D&lt;/span&gt; &lt;span class="attr"&gt;Positions&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 0, 1 0 0, 1 1 0&amp;quot;&lt;/span&gt;
                        &lt;span class="attr"&gt;TriangleIndices&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 2&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Dit is de definitie van onze eerste driehoek. We geven de positions op in 3 Point3D structs, te weten (0 0 0), (1 0 0) en (1 1 0) oftewel punt A, B en C in mijn eerste tekening. Daarna geven we in TriangleIndices aan in welke volgorde ze moeten worden verbonden: begin bij punt 0 (0 0 0), dan naar punt 1 (1 0 0) en als laatste naar punt 2 (1 1 0) in het lijst met positions. Van punt 2 naar punt 0 hoeven we niet aan te geven, zoals ik al eerder zei doet WPF dat zelf wel.&lt;/p&gt;

&lt;p&gt;En de andere driehoek? Die kunnen we als volgt doen:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MeshGeometry3D&lt;/span&gt; &lt;span class="attr"&gt;Positions&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 0, 1 0 0, 1 1 0, 0 0 0, 1 1 0, 0 1 0&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;TriangleIndices&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 2 3 4 5&amp;quot;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;We definieren nu de punten A (0 0 0), C (1 1 0) en D (0 1 0) en de lijnen vanuit het 3e punt (dus de tweede keer dat we punt A definieren) naar het 4e punt (dus de tweede keer dat we punt C definieren) naar het 5e punt (dat is punt D). Mmmm.. dubbel definieren van punten? Niet handig! Dat vinden ze bij het WPF team ook, dus we hoeven de punten maar een keer te definieren en dan de TriangleIndices aan te passen:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MeshGeometry3D&lt;/span&gt; &lt;span class="attr"&gt;Positions&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 0, 1 0 0, 1 1 0, 0 1 0&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;TriangleIndices&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 2 0 2 3&amp;quot;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Dat ziet er al veel beter uit. We definieren in Positions de punten A, B, C en D en vervolgens geven we in de TriangleIndices aan dat we vanuit 0 naar 1, vanuit 1 naar 2 (en dan automatisch vanuit 2 naar 0 gaan!). Dan zeggen we vanuit 0 naar 2 en vanuit 2 naar 3 (en automatisch vanuit 3 naar 0) en daarmee is ons vierkant genoeg gedefinieerd!&lt;/p&gt;

&lt;p&gt;Overigens is WPF heel erg makkelijk als het gaat om het formatten van dit soort constructies. De volgende code is ook goed en een stuk leesbaarder:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MeshGeometry3D&lt;/span&gt; 
        &lt;span class="attr"&gt;Positions&lt;/span&gt;= &lt;span class="kwrd"&gt;&amp;quot;0 0 0, 
                    1 0 0, 
                    1 1 0, 
                    0 1 0&amp;quot;&lt;/span&gt;
        &lt;span class="attr"&gt;TriangleIndices&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 2 
                         0 2 3&amp;quot;&lt;/span&gt;
    &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Het is een kwestie van smaak maar ik denk dat deze versie beter is: je ziet beter waar de definitie van 1 punt ophoudt en de volgende begint (namelijk op de volgende regel), ook de driehoeken zijn duidelijker :van 0 naar 1 naar 2, vervolgens een nieuwe driehoek van 0 naar 2 naar 3. Ook het plaatsen van de komma's om de elementen te scheiden kan heel anders, maar ik vind dit een mooie layout.&lt;/p&gt;

&lt;p&gt;Als je je code nu gaat draaien, zie je.... niets. Waarom niet? Omdat we geen Material hebt gedefinieerd. Over Materials wil ik het later uitgebreid hebben, maar om je toch iets te geven om mee te spelen even kort dit:&lt;/p&gt;

&lt;p&gt;Een material kun je zien als het behangtje dat je op je objecten plak om ze zichtbaar te maken. GeometryModel3D heeft, zoals je al zag, een Material en een BackMaterial property. Deze gaan we nu zetten:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MeshGeometry3D&lt;/span&gt; 
                            &lt;span class="attr"&gt;Positions&lt;/span&gt;= &lt;span class="kwrd"&gt;&amp;quot;0 0 0, 
                                        1 0 0, 
                                        1 1 0, 
                                        0 1 0&amp;quot;&lt;/span&gt;
                            &lt;span class="attr"&gt;TriangleIndices&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 2 
                                             0 2 3&amp;quot;&lt;/span&gt;
                        &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Blue&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;We hebben een blauw materiaal gemaakt zodat er in ieder geval iets zichtbaar is.&lt;/p&gt;

&lt;p&gt;Oh ja; ik had het over het hulpmiddel om je te helpen voorkomen dat je de TriangleIndices in de verkeerde volgorde zet (zodat je tegen de achterkant aankijkt): ik definieer als ik in XAML objecten maak &lt;strong&gt;altijd&lt;/strong&gt; de BackMaterial. Dit is het material dat aan de achterkant van onze object komt. Ik geef deze altijd een mooi opvallend kleurtje die ik niet gauw zou gebruiken in mijn applicatie. Op die manier valt een fout direct op. In de volgende code heb ik bewust de tweede driehoek verkeerd getekend maar aangezien ik ook een BackMaterial heb ingesteld is het meteen zichtbaar:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MeshGeometry3D&lt;/span&gt; 
            &lt;span class="attr"&gt;Positions&lt;/span&gt;= &lt;span class="kwrd"&gt;&amp;quot;0 0 0, 
                        1 0 0, 
                        1 1 0, 
                        0 1 0&amp;quot;&lt;/span&gt;
            &lt;span class="attr"&gt;TriangleIndices&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 3 2 
                             0 2 1&amp;quot;&lt;/span&gt; 
        &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Blue&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.BackMaterial&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;HotPink&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; 
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.BackMaterial&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Dat levert dit mooie plaatje op:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel5GeometryModel3D_BFED/image_4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="image" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel5GeometryModel3D_BFED/image_thumb_4.png" width="244" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Ik heb dus TriangleIndices hier even met de klok meegeven om het effect weer te geven. Zet ze weer terug in de juiste plek om een mooi blauw vierkantje weer te geven.&lt;/p&gt;

&lt;p&gt;Goed. De kubus. &lt;/p&gt;

&lt;p&gt;Tja, die is niet echt ingewikkeld: een kubus bestaat uit 8 Point3D structures, 12 driehoeken en dus 12 TriangleIndices entries. Het is alleen een hoop werk om in te typen: ik laat het graag aan je zelf over om dat te doen :-) &lt;/p&gt;

&lt;p&gt;Overigens: mocht je die kubus gaan maken: let er dan op dat je in ons voorbeeld recht van voren naar de kubus kijkt en dus de zijkanten en onder- en bovenkant niet ziet. Je zult met de camera positie en LookDirection moeten spelen om hem helemaal zichtbaar te maken!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=875" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/27/875.aspx</link>
      <author>dvroegop</author>
      <pubDate>Wed, 27 Aug 2008 14:49:42 GMT</pubDate>
    </item>
    <item>
      <title>3D Graphics in WPF, deel 4 (intermezzo 2 over vectors, punten en andere wiskunde)</title>
      <description>&lt;p&gt;Laat de titel je niet afschrikken: we gaan niet samen je hele middelbare school wiskunde herhalen. Toch zal je, als je serieus met WPF 3D bezig wilt zijn, iets van vector berekeningen moeten weten. In deze post geen mooie plaatjes van vierkantjes en kubussen, maar we gaan rekenen! Geloof me: je zult het nodig hebben.&lt;/p&gt;  &lt;p&gt;Als eerste: wat is een punt? Deze is eenvoudig te beantwoorden. In computer graphics worden punten op het scherm weergegeven als pixels (samenvoeging van picture element). Deze hebben een X en een Y waarde waarbij X=0 en Y=0 het punt links boven het scherm is. Als je de X waarde positief laat oplopen ga je meer naar rechts, terwijl je als je Y waarde positief laat oplopen je naar beneden op het scherm gaat. Een punt op je scherm kun je dus weergeven door het getallen paar X en Y. Op mijn scherm hier is het punt (X=0, Y=0) links boven, (X=1440, Y=0) rechtsboven, (X=0, Y=900) links onder en (X=1440, Y=900) rechts onder. Meestal laten we de X en Y weg in getallenparen en geven we deze vier punten weer als (0,0), (1440,0), (0,900) en (1440, 900). &lt;/p&gt;  &lt;p&gt;Als we het over pixels hebben zijn de getallen meestal integers: je kunt immers niet een halve pixel tekenen. &lt;/p&gt;  &lt;p&gt;In 3D WPF is dat iets anders. Zoals ik al eerder opmerkte kunnen we niet over pixels praten omdat we niet weten hoe groot een object gerenderd wordt: dit hangt af van de positie van het object, de positie van de camera, het type camera en de instellingen van de camera. In plaats daarvan praten we over logische eenheden. Of 1 unit nu 1 milimeter, 1 kilometer, 1 lichtjaar of 1 micrometer voorstelt hangt af van wat JIJ vindt dat het voorstelt: voor WPF maakt het niets uit. Deze werkt gewoon met eenheden. Deze eenheden zijn altijd doubles: we werken dus met waardes achter de komma.&lt;/p&gt;  &lt;p&gt;Uiteraard hebben we niet genoeg aan een X en Y waarde om iets in een 3D ruimte aan te duiden. We hebben ook de Z waarde nodig. X en Y hebben dezelfde betekenis als in de 2D wereld (behalve dat Y oplopend naar &lt;em&gt;boven &lt;/em&gt;gaat in plaats van naar beneden, iets waar we later nog last mee gaan krijgen!) maar we hebben ook een Z waarde. Deze Z-waarde geeft aan of iets meer in de diepte ligt of juist meer naar de voorgrond. Met de Z-waarde gaan we dus het scherm in, of juist er uit! &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel4intermezzo2overVecto_B1F6/image.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 5px; border-right-width: 0px" border="0" alt="image" align="right" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel4intermezzo2overVecto_B1F6/image_thumb.png" width="480" height="480" /&gt;&lt;/a&gt;Als we nu even voorstellen dat ons 3D wereldje een grootte heeft van 1 eenheid bij 1 eenheid bij 1 eenheid (nogmaals: we weten niet hoe groot dat is op het scherm) dan is de hoek linksboven vooraan (X=0, Y=1, Z=0), rechtsboven vooraan (X=1, Y=1, Z=0), links onder vooraan (X=0, Y=0, Z=0), rechts onder vooraan (X=1, Y=0, Z=0). Uiteraard laten we hier ook de X,Y en Z weg, dus dat wordt (0,1,0), (1,1,0), (0,0,0) en (1,0,0). &lt;/p&gt;  &lt;p&gt;Dit zijn alle punten die voor aan in onze wereld liggen. De punten aan de achterkant hebben als coordinaten, linksboven achter (0, 1, -1), rechtsboven achter (1, 1, -1), linksonder achter (0, 0, -1) en rechtsonder achter (1, 0, -1). Je ziet dat de Z waarde negatief wordt als we naar achter gaan. Je kunt besluiten om dat niet te doen, maar ik garandeer je dat je dan later enorm in de moelijkheden komt. Hou deze conventie maar vast: naar achter in het scherm is negatief voor Z. En nogmaals: Y naar beneden is richting 0, precies omgekeerd ten opzichte van standaard 2D grafieken).&lt;/p&gt;  &lt;p&gt;We kunnen in WPF coordinaten vast leggen met de structure Point3D. Deze heeft als properties X, Y en Z: allen zijn double.&lt;/p&gt;  &lt;p&gt;Als tweede: wat is een vector?&lt;/p&gt;  &lt;p&gt;Een vector is een eenheid die grootte en richting heeft. In de natuurkunde gebruiken we vectoren om bijvoorbeeld krachten weer te geven. Er zijn enorm veel wiskundige boeken verschenen over het onderwerp vectoren, met name hoe je berekeningen met ze uitvoert. Je kunt vectoren bij elkaar optellen, vermenigvuldigen (met elkaar en met normale waardes) enzovoorts. Het slechte nieuws is dat we dat ook moeten gaan doen in WPF. Het goede nieuws is dat we heel veel details kunnen overlaten aan WPF.&lt;/p&gt;  &lt;p&gt;Stel je voor dat je in de kubus die je hier ziet staan met je 3D mousepointer (als die zou bestaan) op de linkeronderhoek vooraan zou staan, oftewel op punt (0,0,0). Als we de mousepointer zouden willen vertellen dat die naar de linker beneden hoek achter (0,0,-1) moet gaan, dan zouden we hem moeten vertellen dat hij zijn X waarde niet moet wijzigen, ook zijn Y waarde blijft gelijk maar de Z waarde moet met 1 verminderd worden. Dat geven we aan met een vector, om precies te zijn de Vector (0,0,-1). Dit zegt dus: ga 0 stappen naar rechts, 0 stappen naar boven en -1 stappen naar de voorkant van het scherm (oftewel 1 stap naar achteren...). &lt;/p&gt;  &lt;p&gt;Als we vanuit dat punt naar rechtsboven vooraan willen gaan, dus vanuit (0,0,-1) naar (1,1,0) dan moet hij de vector (1,1,1) mee krijgen: ga 1 stap naar rechts, 1 stap omhoog en 1 stap naar voren. &lt;/p&gt;  &lt;p&gt;Je ziet dat de wiskunde van het optellen van vectors bij punten niet zo moelijk is: Point3d(0,0,-1) + Vector3D (1,1,1) levert Point3D (1,1,0) op: we tellen bij de X waarde van de punt de X waarde van de vector op, bij de Y waarde van de punt de Y waarde van de vector en bij de Z waarde van de punt de Z waarde van de vector. Het resultaat is dus (0 + 1, 0 + 1, -1 + 1) = (1, 1, 0).&lt;/p&gt;  &lt;p&gt;Zoals je al zag is in WPF een vector weergegeven met de struct Vector3D. Deze heeft dezelfde X, Y en Z properties als de Point3D. Maar vergeet niet dat een vector een richting en grootte aangeeft en niet een punt!&lt;/p&gt;  &lt;p&gt;Kijk nog eens naar de code voor onze PerspectiveCamera. Deze had als positie (0,0,5) en een LookDirection van (0,0,-1). De position is een Point3D (de camera 'staat' immers op een punt in onze scene) maar de LookDirection is een Vector3D: deze wijst in de richting waarnaar de camera kijkt: 0,0,-1 oftewel recht het scherm in (en niet naar links, rechts, beneden of boven). Wat had er nu gebeurdt als we als LookDirection (0,0,-5) hadden opgegeven? Het antwoord is: niets. De vector hier is een richting. Als je een pijl tekent om iemand te laten zien waar hij heen moet rijden, is het niet van belang hoe lang die pijl is: of deze nu 1 cm of 1 meter lang is: de richting is hier waar het om gaat.&lt;/p&gt;  &lt;p&gt;Maar wat als we nu als LookDirection (0.5, 0, -1) hadden gezet? Dan had de camera het scherm en en schuin naar rechts gekeken. Ook dit kunnen we veranderen in (1,0, -2), dat maakt niets uit: het gaat niet om de lengte van de pijl (de tweede is twee keer zo lang als de eerste) maar om de richting.&lt;/p&gt;  &lt;p&gt;Als we nog eens nadenken over ons voorbeeld van de mousepointer die we willen verplaatsen: daar is het wel van belang hoe lang de pijl is! Als we die waardes niet goed maken komt de muis op de verkeerde plek uit.&lt;/p&gt;  &lt;p&gt;Onthoudt dus: soms is de richting van de Vector van belang, soms de grootte, soms allebei....&lt;/p&gt;  &lt;p&gt;De reden dat we als lookdirection (0,0,-1) opgeven en niet (0,0,-5242) is dat de eerste een zogenaamde genormaliseerde vector is: dit is een vector met waardes als fracties van 1. WPF probeert dit soort vectoren zoveel mogelijk te gebruiken waar het kan (dus wanneer alleen de richting van belang is) en zal altijd dit soort vectoren omrekenen. Dit kost rekentijd, wat we in dit geval makkelijk zelf hadden kunnen doen door (0,0,-1) te gebruiken.&lt;/p&gt;  &lt;p&gt;Hetzelfde geldt voor de UpDirection van onze camera: die is (0,1,0) oftewel recht naar boven.&lt;/p&gt;  &lt;p&gt;Mocht je nu een vector willen normalizeren, dan is dat niet zo moeilijk: de struct heeft als method Normalize. Kijk eens naar de volgende code:&lt;/p&gt;  &lt;div class="cf"&gt;   &lt;p class="cl"&gt;&lt;span class="cb1"&gt;Vector3D&lt;/span&gt; myVector = &lt;span class="cb2"&gt;new&lt;/span&gt; &lt;span class="cb1"&gt;Vector3D&lt;/span&gt;(0.0, 0.0, -515423.243);&lt;/p&gt;    &lt;p class="cl"&gt;myVector.Normalize(&amp;#160; );&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb1"&gt;MessageBox&lt;/span&gt;.Show(myVector.Z.ToString(&amp;#160; )) ;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Als resultaat krijg je een messagebox met de waarde -1.&lt;/p&gt;  &lt;p&gt;De struct Vector3D heeft nog meer handigheidjes in zich, bekijk de help eens.&lt;/p&gt;  &lt;p&gt;Naast punten en vectoren zijn ook matrixen erg belangrijk in WPF 3D. Dit is echter iets wat vele malen ingewikkelder is dan dit stukje dus dat zal ik je nu besparen. We zien die wel verschijnen als het over transformaties (roteren, schalen en verplaatsten!) gaan hebben.&lt;/p&gt;  &lt;p&gt;Goed. We weten nu wat punten en wat vectoren zijn. Dank je dat je je door dit toch wat saaie stuk heen gelezen hebt. Ik zal het de volgende keer goed maken: we gaan ons vierkantje vervangen door een kubus! En uiteraard komen we daar heel veel Point3D en Vector3D tegen zodat je dit niet voor niets gelezen hebt!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=874" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/27/874.aspx</link>
      <author>dvroegop</author>
      <pubDate>Wed, 27 Aug 2008 13:26:04 GMT</pubDate>
    </item>
    <item>
      <title>3D Graphics in WPF, deel 3 (intermezzo 1 over lampjes)</title>
      <description>&lt;p&gt;Ik moet iets bekenen: ik heb valsgespeeld in mijn vorige post. Ik heb als laatste een vierkant getekend en die de kleur zwart gegeven. De waarheid is dat het niet uitmaakt welke kleur ik hem had gegeven, hij zou altijd zwart worden weergegeven. Probeer maar eens om de de kleur Brush=&amp;quot;Black&amp;quot; bij de DiffuseMaterial te vervangen door Brush=&amp;quot;White&amp;quot;. Je krijgt nog steeds een saai zwart vierkantje.&lt;/p&gt;  &lt;p&gt;De reden daarvoor is simpel. Denk maar eens na: wat gebeurdt er als je een foto neemt in een ruimte zonder licht? Het antwoord: alles wordt zwart. De reden dat bij ons alleen het vierkant zwart is en niet het hele scherm is dat de default achtergrond kleur (die niet door de camera gerenderd wordt!) wit is. Dus we krijgen een zwart vierkant op een witte achtergrond. &lt;/p&gt;  &lt;p&gt;Hoe los je dat op? Wel, net als in het echte leven: als je in een ruimte niets kunt zien doe je het licht aan. In WPF is dat niet anders. In tegenstelling tot de 2D graphics in WPF (of welk ander framework dan ook) zul je moeten aangeven wat voor licht er is.&lt;/p&gt;  &lt;p&gt;En nu wordt het ingewikkeld. Licht is een enorm complex iets, zowel in het echte leven als in onze gesimuleerde computer omgeving. Er zijn heel veel verschillende soorten licht, ieder met een eigen gedrag. Zo moet je aangeven wat voor kleur licht je hebt (met een rode lamp op een wit oppervlak schijnen levert een rood vlak op) maar ook wat voor soort lampen je hebt.&lt;/p&gt;  &lt;p&gt;WPF heeft 4 soorten licht. Je kunt deze classes zien als lampen (waarbij er een is, AmbientLight die geen echte lamp voorstelt). Deze zijn: AmbientLight, DirectionalLight, PointLight en SpotLight. De eerste twee zul je het meeste gebruiken.&lt;/p&gt;  &lt;p&gt;Alle light objecten bij elkaar leveren licht op. Je moet er op letten dat je niet teveel lampen in je scene zet: je loopt anders het risico dat je scene overbelicht raakt en je geen details meer kunt zien. &lt;/p&gt;  &lt;p&gt;Bij het renderen berekent WPF hoeveel licht er op een object valt en wat voor kleur er dan zichtbaar is. Een object kan niet helderder zijn dan puur wit (RGB waarde 255, 255, 255). Meer licht erop levert niet witter wit op: het blijft RGB(255,255,255). &lt;/p&gt;  &lt;p&gt;Als eerste kijken we even naar AmbientLight. AmbientLight is het licht dat er altijd is. Dit is vergelijkbaar met wat je ziet op een grijze, bewolkte dag: alles is zichtbaar maar mist diepte. Schaduwen zie je eigenlijk niet, alles wordt vanuit alle kanten gelijkmatig verlicht. Door AmbientLight te gebruiken geef je een basis belichting op.&lt;/p&gt;  &lt;p&gt;DirectionalLight is hetzelfde als AmbientLight behalve dat het een richting heeft. Een DirectionalLight heeft geen duidelijke oorsprong, maar het licht gaat wel duidelijk een kant op. Objecten die geraakt worden door de DirectionalLight zijn zichtbaar, objecten die in de &amp;quot;schaduw&amp;quot; liggen zijn zwart (WPF heeft geen schaduw berekening, maar het heeft wel ongeveer hetzelfde effect). Een screenshot maakt dit duidelijker. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/59c55ae9788c_A34B/image.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="ambientLight" src="http://www.dotned.nl/blogs/dvroegop/59c55ae9788c_A34B/image_thumb.png" width="304" height="304" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In het eerste plaatje zie je een box die 45 graden gedraaid is over de X,Y en Z as. Ik heb er alleen een puur witte AmbientLight bijgezet. Je ziet dat alle vlakken dezelfde hoeveelheid licht ontvangen en dat er dus geen enkel verschil zichtbaar is in de kanten. &lt;/p&gt;  &lt;p&gt;Niet echt realistisch lijkt mij.&lt;/p&gt;  &lt;p&gt;Als we de AmbientLight nu vervangen door een DirectionalLight die vanaf links boven achter naar rechts beneden voor schijnt, krijgen we een ander effect.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/59c55ae9788c_A34B/image_3.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="image" src="http://www.dotned.nl/blogs/dvroegop/59c55ae9788c_A34B/image_thumb_3.png" width="304" height="304" /&gt;&lt;/a&gt; Hier zie je dat het bovenste vlak goed uitgelicht wordt: deze staat volop in het zonnetje. Het vlak aan de linkerkant is een stuk donkerder: het licht komt immers van schuin boven dus dit is minder zichtbaar. Het vlak aan de voorkant is zwart: hier valt geen licht op.&lt;/p&gt;  &lt;p&gt;In het echte leven zien we dit niet: er is immers vrijwel altijd wel wat omgevingslicht (= ambientlight) beschikbaar dus we kunnen altijd wel details zien.&lt;/p&gt;  &lt;p&gt;Als we nu een klein beetje AmbientLight nemen (RGB kleur 64, 64, 64 dus donker grijs) en een lichte DirectionalLight (RGB 191, 191, 191 dus&amp;#160; licht grijs) dan krijgen we het volgende effect:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/59c55ae9788c_A34B/image_4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="image" src="http://www.dotned.nl/blogs/dvroegop/59c55ae9788c_A34B/image_thumb_4.png" width="304" height="304" /&gt;&lt;/a&gt; Het verschil is subtiel, maar de kleuren komen nu wel beter uit: je kunt zien dat het voorvlak inderdaad blauw is (en het linkervlak is nu ook beter zichtbaar). Overigens: de totale lichtwaarde (RGB (64,64,64) + RGB(191, 191, 191)) is puur wit: we komen niet boven RGB (255,255,255) uit. &lt;/p&gt;  &lt;p&gt;Het is in de praktijk erg lastig om je belichting goed te krijgen. Je moet er op letten dat je niet boven de totale waarde van wit uitkomt (meer heeft geen zin, dat doet niets) en je moet er goed opletten dat alle kanten van de objecten genoeg licht krijgen om zichtbaar te zien, zonder het 3D effect te niet te doen zoals in het eerste plaatje met alleen AmbientLight.&lt;/p&gt;  &lt;p&gt;Naast de AmbientLight en DirectionalLight hebben we ook nog de PointLight en SpotLight. Deze kun je gebruiken om nog realistischer effecten te krijgen. Let echter op: dit soort geavanceerde technieken zorgen ervoor dat WPF veel meer tijd nodig heeft om je scene te berekenen. Als je met animaties gaat werken merk je dat door het gebruik van SpotLight en PointLight het aantal frames per seconde die je kunt halen erg naar beneden gaat (wij gebruiken ze dan ook niet in onze Business Visualization oplossingen).&lt;/p&gt;  &lt;p&gt;Een PointLight begint al op een echt lampje te lijken. Je geeft hem een plaats in je 3D wereld, en de hoeveelheid licht die het verspreid neemt af naarmate de objecten verder weg liggen van de lamp (dit is allemaal instelbaar). Een SpotLight is een gespecialiseerde vorm van de PointLight (die in alle richtingen schijnt): deze schijnt in een bepaalde richting en heeft een duidelijke 'cone', dwz een gebied waar het licht duidelijk zichtbaar is en een gebied waar het licht minder zichtbaar is en dus in sterkte afneemt.&lt;/p&gt;  &lt;p&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="Spotlight" src="http://www.dotned.nl/blogs/dvroegop/59c55ae9788c_A34B/image_5.png" width="265" height="217" /&gt; Een spotlight heeft een innercone, waar het licht 100% is, en een outercone, waarin de lichtsterkte afneemt naarmate je meer naar de buitenkant gaat. De cones worden ingesteld door de hoeken op te geven. Zo kun je dus een dunne, felle bundel licht maken of een brede waaier van licht. &lt;/p&gt;  &lt;p&gt;Tot zover de theorie: laten we de lampjes eens in onze scene plaatsen.&lt;/p&gt;  &lt;p&gt;Nog een keer de code van vorige keer (maar dan met een vierkant die blauw moet worden):&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt; &lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;WpfApplication11.Window1&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;Title&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Window1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Viewport3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MeshGeometry3D&lt;/span&gt; &lt;span class="attr"&gt;Positions&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 0 1 0 0 1 1 0 0 1 0&amp;quot;&lt;/span&gt;
                                        &lt;span class="attr"&gt;TriangleIndices&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 2 0 2 3&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Blue&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;                
            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;                       
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Viewport3D.Camera&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;PerspectiveCamera&lt;/span&gt; &lt;span class="attr"&gt;Position&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 5&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;LookDirection&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 -1&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;UpDirection&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 0&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;FieldOfView&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;60.0&amp;quot;&lt;/span&gt; 
                           &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Viewport3D.Camera&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Viewport3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Dit levert dus een zwart vierkantje op... &lt;/p&gt;

&lt;p&gt;Tussen de &amp;lt;/ModelVisual3D&amp;gt; en de &amp;lt;Viewport3D.Camera&amp;gt; plaatsen we nu de volgende code:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;        &lt;span class="rem"&gt;&amp;lt;!-- Lampjes! --&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AmbientLight&lt;/span&gt; &lt;span class="attr"&gt;Color&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;White&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; 
            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;We maken een ModelVisual3D aan (die bevat alles wat getekend moet worden, wat ook voor lampen geldt), in de content daarvan plaatsen we een AmbientLight. Deze geeft wit licht. Run je applicatie en voila: een blauw vierkantje!&lt;/p&gt;

&lt;p&gt;Mocht je nu een DirectionalLight willen plaatsen dan vervang je de AmbientLight regel door&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DirectionalLight&lt;/span&gt; &lt;span class="attr"&gt;Color&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;White&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Direction&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1 -1 -1&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;... en je hebt een DirectionalLight. Het vierkantje wordt nu een stuk donkerder: ons lampje schijnt van linksboven voor naar rechtsonder beneden (Vector: 1, -1, -1)) en dus 'strijkt' het licht langs ons vierkantje. &lt;/p&gt;

&lt;p&gt;Wat als je nu zowel een Ambient als een DirectionalLight wil hebben? Dan moet je even een trucje uithalen: De ModelVisual3D.Content kan maar 1 item bevatten... Dat is niet zo moelijk op te lossen. We voegen als Content een Model3DGroup toe (dat is precies 1 item) en die Model3DGroup bevat op zijn (haar?) beurt weer andere items:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;&amp;lt;!-- Lampjes! --&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Model3DGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AmbientLight&lt;/span&gt; &lt;span class="attr"&gt;Color&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;#404040&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DirectionalLight&lt;/span&gt; &lt;span class="attr"&gt;Color&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;#BFBFBF&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Direction&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1 -1 -1&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Model3DGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Probleem opgelost! Je ziet dat ik hier met RGB waardes werk (in hexadecimale waardes) in plaats van de named colors: op deze manier heb ik precieze controle over de totale hoeveelheid licht in mijn scene.&lt;/p&gt;

&lt;p&gt;Speel eens met deze code, verander het licht (de kleuren bijvoorbeeld) en voeg een spotlight toe. Kijk eens wat er gebeurd als je je vierkant wit maakt en je met andere kleuren licht werk!&lt;/p&gt;

&lt;p&gt;Volgende post wordt weer een intermezzo waar ik dieper in ga op de Vector3D en Point3D: we hebben ze al voorbij zien komen maar we hebben het er eigenlijk niet over gehad. Daarna gaan we dan echt kijken naar andere figuurtjes behalve dit nuttige maar toch wel saaie vierkantje!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=873" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/27/873.aspx</link>
      <author>dvroegop</author>
      <pubDate>Wed, 27 Aug 2008 12:34:41 GMT</pubDate>
    </item>
    <item>
      <title>3D Graphics in WPF, deel 2</title>
      <description>&lt;p&gt;In mijn vorige post liet ik zien hoe we bij Detrio Excel grafieken vervangen door 3D interactieve grafieken. Het wordt tijd om te kijken hoe we dit soort applicaties nu maken. Hoe kun je nu 3D plaatjes maken in WPF?&lt;/p&gt;  &lt;p&gt;WPF heeft een enorm rijke ondersteuning voor 3D. In de eerste versies van onze 3D toolkit, waar we dit soort systemen mee maken, was helemaal van de grond af aan geschreven in Delphi en C++, waarbij we gebruik maakten van OpenGL om de 3D plaatjes te maken. Veel van het werk dat we gedaan hebben in die library hebben we weggegooid: alle low-level code zit nu standaard in WPF (zodat wij ons kunnen orienteren op de dingen die echt belangrijk zijn).&lt;/p&gt;  &lt;p&gt;Maar laten we beginnen bij het begin.&lt;/p&gt;  &lt;p&gt;In Visual Studio (Express, Professional of hoger: maakt niet uit welke versie je hebt) maak je een nieuw WPF project aan. Je krijgt een XAML bestand met daarin de volgende code:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt; &lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;WpfApplication10.Window1&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;Title&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Window1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Grid&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Grid&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Dit is onze basis. We krijgen een Window met daarin een Grid. Die Grid kan weg, die hebben we nu niet nodig. &lt;/p&gt;

&lt;p&gt;Om 3D plaatjes te tekenen moeten we als eerste een soort van Canvas hebben. Een canvas is het stuk waarop getekend kan gaan worden. WPF heeft daarvoor de Viewport3D class: dit is ons tekengebied. Onze code ziet er nu als volgt uit:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt; &lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;WpfApplication10.Window1&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;Title&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Window1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;&amp;lt;!-- De Viewport3D is ons tekengebied --&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Viewport3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Viewport3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Tot zover is het niet echt spannend. Als je dit runt krijg je een leeg, wit scherm. Had je anders verwacht?&lt;/p&gt;

&lt;p&gt;Laten we eens iets toevoegen. Er zijn een paar dingen die je altijd moet doen. Alles wat je in 3D WPF tekent wordt geplaatst in een soort virtuele wereld. Deze wereld bestaat alleen in het geheugen van je computer: dit wordt niet weergegeven op je scherm. Om te laten zien wat je getekend hebt zul je een camera moeten toevoegen: deze camera zorgt ervoor dat alles wat in het bereik van deze camera is ook daadwerkelijk op het scherm geplaatst wordt. Je kunt dus meerdere camera's maken en in je applicatie tussen camera's switchen!&lt;/p&gt;

&lt;p&gt;WPF heeft twee soorten camera's: de OrthographicCamera en de PerspectiveCamera. De eerste is een camera waarbij geen rekening gehouden wordt met perspectief, de tweede doet dat wel. In de praktijk komt het neer op het volgende: als je twee blokken van dezelfde grootte hebt, waar er een dicht bij de camera staat en de tweede staat ver weg, dan zal bij de OrthographicCamera het tweede blok net zo groot getekend worden als de eerste. Bij de PerspectiveCamera zal de tweede kleiner worden getekend dan de eerste (wat meer overeenkomt hoe wij mensen de wereld zien).&lt;/p&gt;

&lt;p&gt;De OrthographicCamera wordt voornamelijk gebruikt voor architectuur toepassingen: daar is het belangrijk dat alle objecten weergegeven worden op het formaat dat ze ook echt zijn. Natuurlijk zien wij het anders: wij zien twee blokken waarbij er een groter lijkt dan de ander. Kijk eens naar het volgende voorbeeld. Als eerste zie je een scene met twee blokken en een PerspectiveCamera. Daarnaast zie je dezelfde scene maar met de OrthographicCamera.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel2_9433/image.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="PerspectiveCamera" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel2_9433/image_thumb.png" width="304" height="304" /&gt;&lt;/a&gt; &lt;a href="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel2_9433/image_3.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="OrthographicCamera" src="http://www.dotned.nl/blogs/dvroegop/3DGraphicsinWPFdeel2_9433/image_thumb_3.png" width="304" height="304" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Ik heb hier alleen de camera verandert: je ziet dat het hele perspectief vertekend wordt (en het 'bovenste' blok lijkt groter!). &lt;/p&gt;

&lt;p&gt;Voor realistische weergave is het beter om een PerspectiveCamera te gebruiken: OrthographicCamera wordt niet al te vaak toegepast.&lt;/p&gt;

&lt;p&gt;We voegen deze camera toe aan onze ViewPort3D:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt; &lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;WpfApplication10.Window1&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;Title&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Window1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Viewport3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Viewport3D.Camera&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;PerspectiveCamera&lt;/span&gt; &lt;span class="attr"&gt;Position&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 5&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;LookDirection&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 -1&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;UpDirection&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 0&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;FieldOfView&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;60.0&amp;quot;&lt;/span&gt; 
                           &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Viewport3D.Camera&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Viewport3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;De camera heeft een aantal properties die je moet zetten. Als eerste de position. Zoals ik al zei worden alle object in het geheugen van je computer geplaatst, dit geldt ook voor de camera. Je moet wel leren om in 3 dimensies te denken: er is een z-positie bijgekomen. Als je gewend bent aan het tekenen in een 2D omgeving is er nog iets wat je moet weten: de coordinaten zijn anders dan je gewend bent. Ten eerste is bij een 2D applicatie het punt (0,0) linksboven in je tekening, bij 3D is (0,0,0) links&lt;strong&gt;onder. &lt;/strong&gt;Daarnaast is er dus de 3e dimensie bijgekomen, dit is de z-as. Hoe je die definieert is eigenlijk iets wat je zelf kunt bepalen, maar meestal zie je dat de z-as naar je toe een positieve waarde geeft en van je af (dus de diepte in) een negatieve. Dit is even wennen, maar als snel weet je niet beter. Als laatste moet je weten dat bij 2D applicaties je de coordinaten meestal in pixels opgeeft: bij 3D in WPF is dat niet zo. Als we zeggen dat we een box hebben met een breedte van 1, dan zegt dat eigenlijk niets over de grootte op het scherm. Hoeveel pixels hij op het scherm in gebruik heeft is afhankelijk van de locatie van de box in de 3D wereld, van de plaatsing van de camera en van het type camera. Alle locaties en punten in WPF 3D zijn dan ook doubles. In de tekeningen hierboven zijn de boxen 1 logische unit hoog, breed en diep. Ze staan 4 units van elkaar. Zoals je ziet heeft dat niets met pixels te maken!&lt;/p&gt;

&lt;p&gt;Goed. Onze camera staat dus op locatie 0, 0, 5, oftewel op de X en Y as, maar 5 punten naar ons toe. Als we dat bepaalt hebben moeten we ook opgeven waar de camera naar kijkt. Hier geven we een vector op: we zeggen dat de LookDirection recht langs de z-as naar achteren kijkt (dus vooruit gezien vanuit ons: negatieve z-waardes gaan de diepte in!): LookDirection is 0,0,-1. Als we een andere waarde voor X opgeven dan kijkt de camera meer naar links of rechts, bij andere waardes van Y omhoog of omlaag. &lt;/p&gt;

&lt;p&gt;Dan kunnen we ook nog aangeven wat de bovenkant van de camera is: we kunnen de camera immers ook op z'n kop houden! In ons geval is de UpDirection (0,1,0) oftewel rechtomhoog langs de Y-as.&lt;/p&gt;

&lt;p&gt;Bij de PerspectiveCamera geven we als laatste ook nog de FieldOfView op: dit geeft aan hoe groot de hoek is waarmee we kijken (60 graden in ons geval). Eigenlijk bepalen we hier of we een groothoek of zoomlens gebruiken. Ook kun je door deze waarde te varieren een zoom-effect bereiken (verkleinen van de FieldOfView haalt objecten dichterbij).&lt;/p&gt;

&lt;p&gt;Als we nu onze applicatie runnen zien we.... niets.&lt;/p&gt;

&lt;p&gt;Nee, natuurlijk niet: met een virtuele camera een lege ruimte fotograferen levert een foto van een lege ruimte op.&lt;/p&gt;

&lt;p&gt;Ik ga in een volgende post in op de objecten die daadwerkelijk zichtbaar zijn, maar om je alvast iets te geven om mee te spelen, moet je even de volgende code toevoegen aan je applicatie:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt; &lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;WpfApplication10.Window1&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;Title&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Window1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Viewport3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MeshGeometry3D&lt;/span&gt; &lt;span class="attr"&gt;Positions&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 0 1 0 0 1 1 0 0 1 0&amp;quot;&lt;/span&gt;
                                        &lt;span class="attr"&gt;TriangleIndices&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 2 0 2 3&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Geometry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DiffuseMaterial&lt;/span&gt; &lt;span class="attr"&gt;Brush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Black&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D.Material&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;GeometryModel3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D.Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ModelVisual3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Viewport3D.Camera&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;PerspectiveCamera&lt;/span&gt; &lt;span class="attr"&gt;Position&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 5&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;LookDirection&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 0 -1&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;UpDirection&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0 1 0&amp;quot;&lt;/span&gt; 
                           &lt;span class="attr"&gt;FieldOfView&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;60.0&amp;quot;&lt;/span&gt; 
                           &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Viewport3D.Camera&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Viewport3D&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Window&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;We tekenen hier een vierkant, die als het goed is op het scherm verschijnt.&lt;/p&gt;

&lt;p&gt;Speel eens met verschillende waardes in de PerspectiveCamera en kijk wat er gebeurt! De volgende post gaat meer in op de Geometry die je hier in de code ziet.&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=872" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/27/872.aspx</link>
      <author>dvroegop</author>
      <pubDate>Wed, 27 Aug 2008 11:27:34 GMT</pubDate>
    </item>
    <item>
      <title>3D Business Visualization in WPF: de intro (deel 1 van de heel veel)</title>
      <description>&lt;p&gt;Ik vind dat ik de mooiste baan ter wereld heb: bij &lt;a title="Detrio Consultancy bv" href="http://www.detrio.nl" target="_blank"&gt;Detrio&lt;/a&gt; maken we virtual reality achtige systemen voor het bedrijfsleven. We onderschrijven het cliche dat &amp;quot;een plaatje meer zegt dat 1000 woorden&amp;quot; en vinden het dan ook vreemd dat organisaties hier niet meer mee doen: wij hebben daar een hele goede oplossing voor (ondertussen beginnen de bedrijven dit ook in te zien: mensen willen graag gebruik maken van onze oplossingen :-) ) En ik mag dat soort oplossingen bedenken, en implementeren (samen met mijn collega's, en ja: we zoeken nog meer mensen die bij ons in Alkmaar dit willen bouwen ;-))&lt;/p&gt;  &lt;p&gt;Wat we doen is het volgende: we nemen de bestaande databases van de klant, kijken welke data zij gebruiken om beslissingen te nemen en bouwen daar een 3D grafiek voor. Nou is de term 3D grafiek een beetje misleidend. Immers: in Excel kun je ook 3D grafieken maken. Kijk eens naar het volgende voorbeeld.&lt;/p&gt;  &lt;p&gt;Stel je voor dat je in een organisatie werkzaam bent die spullen verkoopt. Je hebt 4 produktgroepen: Groep A, Groep B, Groep C en hoe kan het ook anders: Groep D.&lt;/p&gt;  &lt;p&gt;Deze produkten verkoop je door het hele land (we zijn nog niet internationaal). Om precies te zijn: je verkoopt ze in de regios Noord Holland, Zuid Holland, Limburg, Groningen en Friesland. Mocht jij nu in een provincie wonen die ik hier niet noem: dat is niet persoonlijk, ik wil het voorbeeld simpel houden....&lt;/p&gt;  &lt;p&gt;Hieronder zie je de verkoopcijfers over het afgelopen jaar.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;table cellspacing="1" cellpadding="2"&gt;     &lt;tr&gt;       &lt;td&gt;Regio&lt;/td&gt;        &lt;td&gt;Omzet A&lt;/td&gt;        &lt;td&gt;Omzet B&lt;/td&gt;        &lt;td&gt;Omzet C&lt;/td&gt;        &lt;td&gt;Omzet D&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;NH&lt;/td&gt;        &lt;td&gt;1000&lt;/td&gt;        &lt;td&gt;1100&lt;/td&gt;        &lt;td&gt;1400&lt;/td&gt;        &lt;td&gt;500&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;ZH&lt;/td&gt;        &lt;td&gt;1100&lt;/td&gt;        &lt;td&gt;1300&lt;/td&gt;        &lt;td&gt;900&lt;/td&gt;        &lt;td&gt;300&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;LI&lt;/td&gt;        &lt;td&gt;800&lt;/td&gt;        &lt;td&gt;600&lt;/td&gt;        &lt;td&gt;900&lt;/td&gt;        &lt;td&gt;400&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;GR&lt;/td&gt;        &lt;td&gt;500&lt;/td&gt;        &lt;td&gt;450&lt;/td&gt;        &lt;td&gt;600&lt;/td&gt;        &lt;td&gt;800&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;FR&lt;/td&gt;        &lt;td&gt;650&lt;/td&gt;        &lt;td&gt;700&lt;/td&gt;        &lt;td&gt;800&lt;/td&gt;        &lt;td&gt;900&lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;p&gt;We hebben studies uit laten voeren waaruit blijkt dat mensen dit soort staatje niet kunnen lezen. Je kunt niet in een oogopslag zien waar je nu veel verkoopt en waar weinig. Het is beter om dit in een grafiek weer te geven. Gelukkig hebben we Excel waar we dat heel eenvoudig kunnen doen:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DapplicatiesinWPFdebasis_D073/image.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="Excel Grafiek" src="http://www.dotned.nl/blogs/dvroegop/3DapplicatiesinWPFdebasis_D073/image_thumb.png" width="644" height="409" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Tot zover is er niets aan de hand. Maar.... Kunnen we nu goed zien wat produktgroep D doet? Hoeveel er van verkocht is in laten we zeggen Zuid Holland? Nee: de andere produktgroepen verkopen meer dus die staan in de weg....&lt;/p&gt;  &lt;p&gt;Daarnaast willen veel managers weten hoe deze cijfers tot stand zijn gekomen. Het zou mooi zijn als ze op 1 van deze kolommen kunnen klikken waarna ze een andere grafiek zien die detail informatie weergeeft. En dat tot uiteindelijk de transactie aan toe.&lt;/p&gt;  &lt;p&gt;Bij Detrio maken we dat soort applicaties. Hoewel we bovenstaand plaatje best mooi vinden geeft dit niet de informatie die een manager nodig heeft. Het is een mooi plaatje met relatief weinig toegevoegde waarde (behalve dat het heel mooi staat in een lijvig rapport dat iedere 2 weken geproduceerd wordt). De systemen die wij bouwen hebben interactie: je kunt er op klikken. Ook kun je de grafiek roteren zodat je alles van alle kanten kunt bekijken. Desnoods bekijk je de data terwijl deze op z'n kop staat: als jij daar gelukkig van wordt vinden wij het best! Ook ondersteunen we het doorklikken, wat wij dan drill-down noemen (die term hebben we uit Analysis Services geleend). &lt;/p&gt;  &lt;p&gt;Bij ons ziet dat er allemaal heel anders uit.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dotned.nl/blogs/dvroegop/3DapplicatiesinWPFdebasis_D073/image_3.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" border="0" alt="image" src="http://www.dotned.nl/blogs/dvroegop/3DapplicatiesinWPFdebasis_D073/image_thumb_3.png" width="644" height="378" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Nu vertelde ik net dat het bij ons veel mooier is omdat je daar de boel kunt bewegen. Kijk eens op &lt;a title="http://www.dotned.nl/flash/firstDemo.htm" href="http://www.dotned.nl/flash/firstDemo.htm"&gt;http://www.dotned.nl/flash/firstDemo.htm&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Zoals je ziet hoef je niet te lezen om welke regio het gaat: dat zie je direct: de grafiekjes voor Noord Holland staan in Noord Holland, die voor Limburg in Limburg, enzovoorts.&lt;/p&gt;  &lt;p&gt;Alles wat je hier ziet is gemaakt in native WPF. Hoe doen we dat? Daar gaan de volgende artikelen over!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=870" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/26/870.aspx</link>
      <author>dvroegop</author>
      <pubDate>Tue, 26 Aug 2008 17:02:59 GMT</pubDate>
    </item>
    <item>
      <title>4 september 2008: Project Velocity bij Class-A</title>
      <description>&lt;p&gt;De vakantie is weer voorbij, we beginnen weer met onze reguliere meetings! We beginnen het nieuwe seizoen met een bijeenkomst bij &lt;a href="http://www.class-a.nl/"&gt;Class-A&lt;/a&gt;. Dennis van der Stelt zal deze avond spreken over Project Velocity.&lt;/p&gt;  &lt;p&gt;Project Velocity is een nieuw framework om het gebruik van caching veel eenvoudiger te maken. Zoals Microsoft het zelf stelt: &amp;quot;Velocity is a distributed in-memory application cache platform for developing scalable, available, and high-performance applications.&amp;quot; &lt;/p&gt;  &lt;p&gt;Tja. High-performance, scalable en available: wie wil dit nou niet?&lt;/p&gt;  &lt;p&gt;Dus als je meer wilt weten over Velocity ben je van harte uitgenodigd om je in te schrijven voor deze gratis bijeenkomst en te luisteren wat Dennis vd Stelt over dit onderwerp te vertellen heeft! De avond begint zoals gewoonlijk om 6 uur 's avonds met wat te eten, waarna om 7 uur de sessie zal gaan beginnen.&lt;/p&gt;  &lt;p&gt;We zien je graag op de 4e te Woerden!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=868" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/08/25/868.aspx</link>
      <author>dvroegop</author>
      <pubDate>Mon, 25 Aug 2008 10:15:20 GMT</pubDate>
    </item>
    <item>
      <title>Passed 70-642</title>
      <description>&lt;P&gt;Just took &lt;A href="http://www.microsoft.com/learning/en/us/exams/70-642.mspx"&gt;exam 70-642 - Windows Server 2008 Network Infrastructure, Configuring&lt;/A&gt;. I was&amp;nbsp;a little bit worried about this exam because manually calculating subnets and figuring out routing options was never my strength. That's what we have &lt;A href="http://www.t1shopper.com/tools/calculate/ip-subnet/"&gt;subnet calculators&lt;/A&gt; for, right? &lt;/P&gt;
&lt;P&gt;Nonetheless, I passed with a 1000/1000 score. Admittedly, there was some luck involved here, because I had the feeling a lot of questions were about DNS and DHCP, and that was just the topic of the chapter I'm was recently working on for my Windows Server 2008 book. &lt;/P&gt;
&lt;P&gt;Next on the todo-list: &lt;A href="http://www.microsoft.com/learning/en/us/exams/70-640.aspx"&gt;70-640 - Windows Server 2008 Active Directory, Configuring&lt;/A&gt;. &lt;/P&gt;&lt;img src ="http://todotnet.com/aggbug/11363.aspx" width = "1" height = "1" /&gt;</description>
      <link>http://todotnet.com/archive/2008/07/18/11363.aspx</link>
      <author>Sander Gerz</author>
      <pubDate>Fri, 18 Jul 2008 16:41:00 GMT</pubDate>
    </item>
    <item>
      <title>ASP.NET MVC Preview 4 Release (Part 1)</title>
      <description>&lt;font face="arial" size="2"&gt;   &lt;p&gt;The ASP.NET MVC team is in the final stages of finishing up a new &amp;quot;Preview 4&amp;quot; release that they hope to ship later this week.&amp;#160; The &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/05/27/asp-net-mvc-preview-3-release.aspx" target="_blank"&gt;Preview 3&lt;/a&gt; release focused on finishing up a lot of the underlying core APIs and extensibility points in ASP.NET MVC.&amp;#160; Starting with Preview 4 this week you'll start to see more and more higher level features begin to appear that build on top of the core foundation and add nice productivity.&lt;/p&gt;    &lt;p&gt;There are a bunch of new features and capabilities in this new build - so much in fact that I decided I needed two posts to cover them all.&amp;#160; This first post will cover the new Caching, Error Handling and Security features in Preview 4, as well as some testing improvements it brings.&amp;#160; My next post will cover the new AJAX features being added with this release as well.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Understanding Filter Interceptors&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;Action Filter Attributes are a useful extensibility capability in ASP.NET MVC that was first added with the &amp;quot;Preview 2&amp;quot; release.&amp;#160; These enable you to inject code interceptors into the request of a MVC controller that can execute before and after a Controller or its Action methods execute.&amp;#160; This enables some nice encapsulation scenarios where you can easily package-up and re-use functionality in a clean declarative way.&lt;/p&gt;    &lt;p&gt;Below is an example of a super simple &amp;quot;ScottGuLog&amp;quot; filter that I could use to log details about exceptions raised during the execution of a request.&amp;#160; Implementing a custom filter class is easy - just subclass the &amp;quot;ActionFilterAttribute&amp;quot; type and override the appropriate methods to run code before or after an Action method on the Controller is invoked, and/or before or after an ActionResult is processed into a response.&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step1.png" /&gt; &lt;/p&gt;    &lt;p&gt;Using a filter within a ASP.NET MVC Controller is easy - just declare it as an attribute on an Action method, or alternatively on the Controller class itself (in which case it will apply to all Action methods within the Controller):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step2.png" /&gt; &lt;/p&gt;    &lt;p&gt;Above you can see an example of two filters being applied.&amp;#160; I've indicated that I want my &amp;quot;ScottGuLog&amp;quot; to be applied to the &amp;quot;About&amp;quot; action method, and that I want the &amp;quot;HandleError&amp;quot; filter to be applied to all Action methods on the HomeController.&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;Previous preview releases of ASP.NET MVC enabled this filter extensibility, but didn't ship with pre-built filters.&amp;#160; ASP.NET Preview 4 now includes several useful filters for handling output caching, error handling and security scenarios.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;OutputCache Filter&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;The [OutputCache] filter provides an easy way to integrate ASP.NET MVC with the output caching features of ASP.NET (with ASP.NET MVC Preview 3 you had to write code to achieve this).&amp;#160; &lt;/p&gt;    &lt;p&gt;To try this out, modify the &amp;quot;Message&amp;quot; value set within the &amp;quot;Index&amp;quot; action method of the HomeController (created by the VS ASP.NET MVC project template) to display the current time:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step3.png" /&gt; &lt;/p&gt;    &lt;p&gt;When you run your application you'll see that a timestamp updates each time you refresh the page:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step4.png" /&gt; &lt;/p&gt;    &lt;p&gt;We can enable output caching for this URL by adding the [OutputCache] attribute to the our Action method.&amp;#160; We'll configure it to cache the response for a 10 second duration using the declaration below:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step5.png" /&gt; &lt;/p&gt;    &lt;p&gt;Now when you hit refresh on the page you'll see that the timestamp only updates every 10 seconds.&amp;#160; This is because the action method is only being called once every 10 seconds - all requests between those time intervals are served out of the ASP.NET output cache (meaning no code needs to run - which makes it super fast).&lt;/p&gt;    &lt;p&gt;In addition to supporting time duration, the OutputCache attribute also supports the standard ASP.NET output cache vary options (vary by params, headers, content encoding, and custom logic).&amp;#160; For example, the sample below would save different cached versions of the page depending on the value of an optional &amp;quot;PageIndex&amp;quot; QueryString parameter, and automatically render the correct version depending on the incoming URL's querystring value:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step6.png" /&gt; &lt;/p&gt;    &lt;p&gt;You can also integrate with the ASP.NET Database Cache Invalidation feature - which allows you to automatically invalidate the cache when a database the URL depends on is modified (tip: the best way to-do this is to setup a CacheProfile section in your web.config and then point to it in the OutputCache attribute).&amp;#160; &lt;/p&gt;    &lt;h3&gt;&lt;u&gt;HandleError Filter&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;The [HandleError] filter provides a way to declaratively indicate on a Controller or Action method that a friendly error response should be displayed if an error occurs during the processing of a ASP.NET MVC request.&amp;#160; &lt;/p&gt;    &lt;p&gt;To try this out, add a new &amp;quot;TestController&amp;quot; to a project and implement an action method that raise an exception like below:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step7.png" /&gt; &lt;/p&gt;    &lt;p&gt;By default when you point your browser at this URL, it will display a default ASP.NET error page to remote users (unless you've gone in and configured a &amp;lt;customErrors&amp;gt; section in your web.config file):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step26.png" /&gt; &lt;/p&gt;    &lt;p&gt;We can change the HTML error displayed to be a more friendly end-user message by adding a [HandleError] attribute to either our Controller or to an Action method on our Controller:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step9.png" /&gt; &lt;/p&gt;    &lt;p&gt;The HandleError filter will catch all exceptions (including errors raised when processing View templates), and display a custom Error view response when they occur.&amp;#160; By default it attempts to resolve a View template in your project called &amp;quot;Error&amp;quot; to generate the response.&amp;#160; You can place the &amp;quot;Error&amp;quot; view either in the same directory as your other Controller specific views (for example: \Views\Test for the TestController above), or within the \Views\Shared folder (it will look first for a controller specific error view, and then if it doesn't find one it will look in the shared folder - which contains views that are shared across all controllers).&lt;/p&gt;    &lt;p&gt;Visual Studio now automatically adds a default &amp;quot;Error&amp;quot; view template for you inside the \Views\Shared folder when you create new ASP.NET MVC Projects starting with Preview 4:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step11.png" /&gt; &lt;/p&gt;    &lt;p&gt;When we add a [HandleError] attribute to our TestController, this will by default show remote users an html error page like below (note that it picks up the master page template from the project so that the error message is integrated into the site).&amp;#160; You can obviously go in and customize the Error view template to display whatever HTML and/or friendlier customer error message you want - below is simply what you get out of the box:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step12.png" /&gt; &lt;/p&gt;    &lt;p&gt;To help developers, the default Error view template provided by the new project template in Visual Studio is written to display additional error stack trace information when you are browsing the application locally:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step13.png" /&gt; &lt;/p&gt;    &lt;p&gt;You can turn this off either by deleting the code from the Error view template, or by setting &amp;lt;customErrors&amp;gt; to &amp;quot;off&amp;quot; inside your web.config file.&lt;/p&gt;    &lt;p&gt;By default the [HandleError] filter will catch and handle all exceptions that get raised during the request.&amp;#160; You can alternatively specify specific exception types you are interested in catching, and specify custom error views for them by specifying the &amp;quot;ExceptionType&amp;quot; and &amp;quot;View&amp;quot; properties on [HandleError] attributes:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step15.png" /&gt; &lt;/p&gt;    &lt;p&gt;In the code above I'm choosing to display custom error views for SqlExceptions and NullReferenceExceptions.&amp;#160; All other exceptions will then use the default &amp;quot;Error&amp;quot; view template.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Authorize Filter&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;The [Authorize] filter provides a way to declaratively control security access on a Controller or Action method.&amp;#160; It allows you to indicate that a user must be logged in, and optionally require that they are a specific user or in a specific security role in order to gain access.&amp;#160; The filter works with all types of authentication (including Windows as well as Forms based authentication), and provides support for automatically redirecting anonymous users to a login form as needed.&lt;/p&gt;    &lt;p&gt;To try this out, add an [Authorize] filter to the &amp;quot;About&amp;quot; action in the HomeController created by default with Visual Studio:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step16.png" /&gt; &lt;/p&gt;    &lt;p&gt;Declaring an [Authorize] attribute like above indicates that a user must be logged into the site in order for them to request the &amp;quot;About&amp;quot; action.&amp;#160; When non-logged-in users attempt to hit the /Home/About URL, they will be blocked from gaining access.&amp;#160; If the web application is configured to use Windows based authentication, ASP.NET will automatically authenticate the user using their Windows login identity, and if successful allow them to proceed.&amp;#160; If the web application is configured to use Forms based authentication, the [Authorize] attribute will automatically redirect the user to a login page in order to authenticate (after which they'll have access):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step17.png" /&gt; &lt;/p&gt;    &lt;p&gt;The [Authorize] attribute optionally allows you to grant access only to specific users and/or roles.&amp;#160; For example, if I wanted to limit access to the &amp;quot;About&amp;quot; action to just myself and Bill Gates I could write:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step18.png" /&gt; &lt;/p&gt;    &lt;p&gt;Typically for all but trivial applications you don't want to hard-code user names within your code.&amp;#160; Instead you usually want to use a higher-level concept like &amp;quot;roles&amp;quot; to define permissions, and then map users into roles separately (for example: using active directory or a database to store the mappings).&amp;#160; The [Authorize] attribute makes it easy to control access to Controllers and Actions using a &amp;quot;Roles&amp;quot; property:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step19.png" /&gt; &lt;/p&gt;    &lt;p&gt;The [Authorize] attribute &lt;u&gt;does not&lt;/u&gt; have a dependency on any specific user identity or role management mechanism.&amp;#160; Instead it works against the ASP.NET &amp;quot;User&amp;quot; object - which is extensible and allows any identity system to be used.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;AccountController Class&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;I mentioned above that the [Authorize] attribute can be used with any authentication or user identity management system.&amp;#160; You can write or use any custom login UI and/or username/password management system you want with it.&lt;/p&gt;    &lt;p&gt;To help you get started, though, the ASP.NET MVC Project Template in Visual Studio now includes a pre-built &amp;quot;AccountController&amp;quot; and associated login views that implement a forms-authentication membership system with support for logging in, logging out, registering new users, and changing passwords.&amp;#160; All of the views templates and UI can be easily customized independent of the AccountController class or implementation:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step20.png" /&gt; &lt;/p&gt;    &lt;p&gt;The Site.master template also now includes UI at the top-right that provides login/logout functionality.&amp;#160; When using forms-based authentication it will prompt you to login if you are not currently authenticated:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step21.png" /&gt; &lt;/p&gt;    &lt;p&gt;And it displays a welcome message along with a logout link if you are authenticated on the site:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step22.png" /&gt; &lt;/p&gt;    &lt;p&gt;Clicking the Login link above takes users to a Login screen like below that they can use to authenticate:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step23.png" /&gt; &lt;/p&gt;    &lt;p&gt;New users can click the register link to create new accounts:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step24.png" /&gt; &lt;/p&gt;    &lt;p&gt;Error handing and error display is also built-in:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvcpreview4/step25.png" /&gt; &lt;/p&gt;    &lt;p&gt;The AccountController class that is added to new projects uses the built-in ASP.NET Membership API to store and manage user credentials (the Membership system uses a provider API allowing any back-end storage to be plugged-in, and ASP.NET includes built-in providers for Active Directory and SQL Server).&amp;#160; If you don't want to use the built-in Membership system you can keep the same AccountController action method signatures, View templates, and Forms Authentication ticket logic, and just replace the user account logic within the AccountController class.&amp;#160; For the next ASP.NET MVC preview release we are planning to encapsulate the interaction logic between the AccountController and the user identity system behind an interface - which will make it easier to plug-in your own user storage system (without having to implement a full membership provider) as well as to easily unit test both it and the AccountController.&lt;/p&gt;    &lt;p&gt;Our hope is that this provides a nice way for people to quickly get started, and enable them to have a working end to end security system as soon as they create a new project.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Testing TempData&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;One last improvement to touch on in this first preview 4 post is some improvements being made on the Controller class that allow you to more easily unit test the TempData collection.&amp;#160; The TempData property allows you to store data that you want to persist for a future request from a user.&amp;#160; It has the semantic of only lasting one future request (after which it is removed).&amp;#160; It is typically used for MVC scenarios where you want to perform a client-side redirect to change the URL in the browser, and want a simple way to store scratch data.&lt;/p&gt;    &lt;p&gt;With previous ASP.NET MVC Previews you had to mock objects in order to test the TempData collection.&amp;#160; With Preview 4 you no longer need to mock or setup anything.&amp;#160; You can now add and verify objects within the Controller's TempData collection directly within your unit tests (for example: populate a controller's TempData property before calling its action method, or verify that the action updated the TempData after the action returned).&amp;#160; The actual storage semantics of the TempData collection is now encapsulated within a separate TempDataProvider property.&amp;#160; &lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Conclusion&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;Hopefully the above post provides a quick look at a number of the new features and changes coming with ASP.NET MVC Preview 4.&amp;#160; My next post on ASP.NET MVC Preview 4 will cover the new AJAX functionality that has been added, and demonstrate how to take advantage of it.&lt;/p&gt;    &lt;p&gt;Hope this helps,&lt;/p&gt;    &lt;p&gt;Scott&lt;/p&gt; &lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6399407" width="1" height="1"&gt;</description>
      <link>http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx</link>
      <author>ScottGu</author>
      <pubDate>Mon, 14 Jul 2008 11:18:31 GMT</pubDate>
    </item>
    <item>
      <title>Passed 70-643</title>
      <description>&lt;P&gt;In order to upgrade my MCSE certification, I'm taking exams for Windows Server 2008. I could upgrade through a special &amp;nbsp;upgrade path, but since I never took any exam on Windows 2003, I would first have to upgrade from 2000 to 2003, and then to 2008. I preferred to focus entirely on Windows Server 2008.&lt;/P&gt;
&lt;P&gt;The end-goal is the &lt;A href="http://www.microsoft.com/learning/mcp/mcitp/windowsserver/2008/enterprise/default.mspx"&gt;MCITP: Enterprise Administrator certification&lt;/A&gt;. In order to achieve that, there are 4 exams to pass. For starters, I took exam &lt;A href="http://www.microsoft.com/learning/en/us/exams/70-643.mspx"&gt;70-643&lt;/A&gt; (Windows Server 2008 Applications Infrastructure Configuration). My hope was that my experience in the webhosting business&amp;nbsp;made the&amp;nbsp;preparation bit easier and would also be a benefit taking the exam. As a result, I focussed more on topics like Terminal Server and Windows deployment options, and less on IIS. &lt;/P&gt;
&lt;P&gt;I passed. 953 out of 1000. Topic needing more attention: IIS &lt;/P&gt;
&lt;P&gt;:-O&lt;/P&gt;
&lt;P&gt;Next up: &lt;A href="http://www.microsoft.com/learning/en/us/exams/70-642.mspx"&gt;70-642&lt;/A&gt;. I'm almost getting my head around ipv6.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src ="http://todotnet.com/aggbug/11362.aspx" width = "1" height = "1" /&gt;</description>
      <link>http://todotnet.com/archive/2008/07/11/11362.aspx</link>
      <author>Sander Gerz</author>
      <pubDate>Fri, 11 Jul 2008 13:37:00 GMT</pubDate>
    </item>
    <item>
      <title>Dinsdag 24 juni: Software Factories &amp;amp; DSL's</title>
      <description>&lt;h4&gt;&amp;nbsp;&lt;/h4&gt; &lt;p&gt;&lt;a href="http://www.ordina.nl/"&gt;&lt;img alt="Oosterkamp" src="http://www.dotned.nl/sponsors/ordina.gif" border="0"&gt;&lt;/a&gt; &lt;p&gt;Software factories en DSL's zijn een hot item in ons vakgebied. Er is veel informatie over te vinden, zoveel dat je eigenlijk door de bomen het bos niet meer ziet. Een goede bron van informatie zijn uiteraard de webcasts van Microsoft.  &lt;p&gt;Het is wel opvallend dat in veel van die webcasts verwezen wordt naar een Nederlands bedrijf die erg veel gedaan heeft op dit gebied: ze noemen bijna allemaal Ordina als reference site...  &lt;p&gt;Het leek ons dus handig om de mensen van Ordina eens aan het woord te laten over dit onderwerp. En op dinsdag (ja ja, dinsdag) 24 juni gaat dat gebeuren! &lt;p&gt;Dus als je meer wilt weten over Software Factories ben je van harte uitgenodigd om je in te schrijven voor deze gratis bijeenkomst en te luisteren wat Ordina over dit onderwerp te vertellen heeft!&amp;nbsp; &lt;p&gt;We zien je graag op de 24e te Nieuwegein! &lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=853" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/06/17/853.aspx</link>
      <author>dvroegop</author>
      <pubDate>Tue, 17 Jun 2008 11:02:28 GMT</pubDate>
    </item>
    <item>
      <title>Silverlight 2 Beta2 Released</title>
      <description>&lt;font face="arial" size="2"&gt;   &lt;p&gt;Silverlight 2 Beta2 was released today.&amp;#160; You can download both Silverlight 2 Beta2 and the Visual Studio and Expression Blend tools support to target it &lt;a href="http://silverlight.net/GetStarted/" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;    &lt;p&gt;Beta2 adds a lot of new features (more details below), but is still a 4.6 MB download that takes less than 10 seconds to install on a machine.&amp;#160; It does not require the .NET Framework or any other software to be installed for it to work, and all features work cross-browser on both Mac and Windows machines.&amp;#160; These features will also be supported on Linux via the Moonlight 2 release.&lt;/p&gt;    &lt;p&gt;Silverlight 2 Beta2 supports a go-live license that allows you to start using and deploying Silverlight 2 for commercial applications. There will be some API changes between Beta2 and the final release, so you should expect that applications you write with Beta2 will need to make some updates when the final release comes out.&amp;#160; But we think that these changes will be straight-forward and relatively easy, and that you can begin planning and starting commercial projects now.&lt;/p&gt;    &lt;p&gt;You can build Silverlight Beta2 applications using the VS 2008 Tools for Silverlight and Expression Blend 2.5 June Preview downloads.&amp;#160; You can download both of them &lt;a href="http://silverlight.net/GetStarted/" target="_blank"&gt;here&lt;/a&gt;.&amp;#160; The VS 2008 Tools for Silverlight download works with both VS 2008 and the recent &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/05/12/visual-studio-2008-and-net-framework-3-5-service-pack-1-beta.aspx" target="_blank"&gt;VS 2008 SP1 beta&lt;/a&gt; release.&amp;#160; &lt;/p&gt;    &lt;h3&gt;&lt;u&gt;UI and Control Improvements&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;Silverlight 2 Beta2 includes a bunch of work in the UI and Control space:&lt;/p&gt;    &lt;p&gt;&lt;u&gt;&lt;strong&gt;More Built-in Controls&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;In Beta 1 only a few controls were included with the core Silverlight setup.&amp;#160; Most common controls (including Button, ListBox, Slider, etc) were shipped within separate assemblies that you had to bundle with your applications (which increased the app download size).&amp;#160; Beta 2 now installs 30+ of the most common controls as part of the core Silverlight 2 download.&amp;#160; This means that you can now build Silverlight 2 applications that use core controls that are as small as 3kb in size - making Silverlight application downloads small and startup time fast.&lt;/p&gt;    &lt;p&gt;In addition to the core controls included with the base Silverlight 2 setup, we are also this week shipping additional higher-level controls that are implemented in separate assemblies that you can then reference and include with your applications.&amp;#160; This includes controls like DataGrid (more details on its new Beta2 features below), Calendar (now with multi-day selection and blackout date support in Beta2), and a TabPanel control (new in Beta2).&lt;/p&gt;    &lt;p&gt;We ultimately expect to ship over a 100 controls for Silverlight.&lt;/p&gt;    &lt;p&gt;&lt;u&gt;&lt;strong&gt;Control Template Editing Support&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;One of the most powerful features of the WPF and Silverlight programming model is the ability to completely customize the look and feel of controls.&amp;#160; This allows developers and designers to sculpt the UI of controls in both subtle and dramatic ways, and enables a tremendous amount of flexibility.&amp;#160; I covered these concepts a little in my previous Silverlight Control Templating blog post &lt;a href="http://weblogs.asp.net/scottgu/pages/silverlight-tutorial-part-7-using-control-templates-to-customize-a-control-s-look-and-feel.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;    &lt;p&gt;This week's Expression Blend 2.5 June Preview now adds designer support for editing control templates - which makes it easy for you to quickly change the look of &lt;u&gt;any control&lt;/u&gt; without having to drop-down to XAML source to-do it.&amp;#160; &lt;/p&gt;    &lt;p&gt;To see control template editing in action, just drag/drop two Slider controls onto the Expression Blend design surface:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step1.png" /&gt; &lt;/p&gt;    &lt;p&gt;We might decide that the slider head in the default Slider control template is too large and wide for our application.&amp;#160; To use control template editing to change it, we can right-click on one of the sliders in the designer and select the &amp;quot;Edit Control Parts&amp;quot; context menu item.&amp;#160; We can choose to create a new empty control template for our slider (and start from scratch), or alternatively edit a copy of the built-in control template (and start from that and tweak it):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step2.png" /&gt; &lt;/p&gt;    &lt;p&gt;After we choose to edit a copy of the existing control template, Blend will prompt us to create and name a re-usable style resource that we'll define our control template within.&amp;#160; We can name it and then choose to store the style at either the application level (within App.xaml) or within our current page/user-control:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step3.png" /&gt; &lt;/p&gt;    &lt;p&gt;When we click &amp;quot;ok&amp;quot; we'll find ourselves in template editing mode for our Slider control.&amp;#160; We can change, tweak, or add/remove any of the underlying elements within the Slider control's template.&amp;#160; Notice below how in template editing mode we can see and select any of the underlying elements that make up the slider's control template (these are circled in red below in the &amp;quot;Objects&amp;quot; window).&amp;#160; &lt;/p&gt;    &lt;p&gt;To make our slider head narrower, we can select the &amp;quot;HorizontalThumb&amp;quot; element within the control template and adjust its width (either graphically or via the property grid):&amp;#160; &lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step4.png" /&gt; &lt;/p&gt;    &lt;p&gt;We can then use the breadcrumb navigation bar at the top of the designer to navigate back to our page and see the control template changes applied:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step5.png" /&gt; &lt;/p&gt;    &lt;p&gt;Notice that right now only one of our slider controls is using the new Style resource with the control template we defined.&amp;#160; &lt;/p&gt;    &lt;p&gt;To apply the same style resource to the other slider control as well, we can select it, right-click, and then use the &amp;quot;Apply Resource&amp;quot; context menu to apply our &amp;quot;ScottSlider&amp;quot; style to it as well:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step6.png" /&gt; &lt;/p&gt;    &lt;p&gt;Once we do this both our sliders reference the same style:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step7.png" /&gt; &lt;/p&gt;    &lt;p&gt;Changes we make to the &amp;quot;ScottSlider&amp;quot; style going forward will automatically apply to both controls.&lt;/p&gt;    &lt;p&gt;Note that &lt;u&gt;all controls &lt;/u&gt;shipped with Silverlight 2 support control templates and will support the above editing experience in Expression Blend. &lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Visual State Manager (VSM) Support&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Control templates in Silverlight and WPF support customizing both the &amp;quot;look&amp;quot; of a control, as well as the &amp;quot;feel&amp;quot; of a control.&amp;#160; By &amp;quot;feel&amp;quot; I mean changing its interactive responsiveness.&amp;#160; For example: how it reacts when pushed, when it gets focus, loses focus, is in a pushed state, is in a disabled state, has something inside it selected, etc.&amp;#160; Often you want animations to execute when the user interacts with a control like this.&lt;/p&gt;    &lt;p&gt;One of the new things we are introducing with Silverlight 2 Beta2 is a &amp;quot;Visual State Manager&amp;quot; (VSM) feature that makes it much easier to build interactive control templates.&amp;#160; VSM introduces two basic concepts that you can take advantage of within control templates: &amp;quot;Visual States&amp;quot; and &amp;quot;State Transitions&amp;quot;.&amp;#160; For example, a control like Button defines multiple visual states for itself - &amp;quot;Normal&amp;quot;, &amp;quot;MouseOver&amp;quot;, &amp;quot;Pressed&amp;quot;, &amp;quot;Disabled&amp;quot;, &amp;quot;Focused&amp;quot;, &amp;quot;Unfocused&amp;quot;.&amp;#160;&amp;#160; When in template editing mode in Blend, designers now have the ability to easily edit what the button looks like in each particular state, as well as setup transition rules to control how long it should take to animate when moving from one state to another.&amp;#160; At runtime Silverlight will then dynamically run the appropriate animation Storyboards to smoothly move the control from one state to another.&lt;/p&gt;    &lt;p&gt;What is nice about this model is that designers &lt;u&gt;do not&lt;/u&gt; need to write code, &lt;u&gt;do not&lt;/u&gt; need to manually create animation storyboards, and &lt;u&gt;do not&lt;/u&gt; need to understand the object model of controls in order to be productive.&amp;#160; This makes the learning curve for creating interactive control templates really easy, and means that existing graphic designers can very easily work on Silverlight projects.&amp;#160; Later this year we will also be adding Visual State Manager (VSM) support to WPF as well, which will let you use the same approach with Windows applications as well as share control templates between WPF and Silverlight projects. &lt;/p&gt;    &lt;p&gt;To see an example of this in action, let's add a Button control onto our design surface:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step23.png" /&gt; &lt;/p&gt;    &lt;p&gt;We can then right click on the button and edit its control template. Instead of starting with the existing default control template (like we did with the slider example above), let's create an empty control template and start from scratch:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step10.png" /&gt; &lt;/p&gt;    &lt;p&gt;Blend will prompt us for the name of the Style resource we want to create.&amp;#160; We'll name it &amp;quot;ScottButton&amp;quot; and click ok.&amp;#160; This will then put the designer in control editing mode for the Button, and start with an empty control template:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step11.png" /&gt; &lt;/p&gt;    &lt;p&gt;One of the things to notice above is the new &amp;quot;States&amp;quot; window inside Blend.&amp;#160; This will show us all of the available &amp;quot;Visual States&amp;quot; that the Button control exposes.&amp;#160; Above the &amp;quot;Base&amp;quot; state is currently selected - which allows us to define the common visual tree of our Button control template.&amp;#160; &lt;/p&gt;    &lt;p&gt;We can then add some vector elements into our base state that defines the look of a custom button like below.&amp;#160; We could use the built-in vector drawing tool support provided by Blend to author these graphics, or alternatively use Expression Design or Adobe Illustrator to build the vector art and then import it into Blend.&amp;#160; Below we are adding 4 &amp;quot;Path&amp;quot; elements into our control template - one a rounded background (named &amp;quot;background&amp;quot;), one a drop shadow (named &amp;quot;shadow&amp;quot;), one a 40% opacity &amp;quot;shine&amp;quot; that adds a glow near the top, and one that defines the default inner content (in this case a picture of a house):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step12.png" /&gt; &lt;/p&gt;    &lt;p&gt;&lt;em&gt;Note: we could have alternatively imported an image, but using vector elements will give us the flexibility to scale/stretch/transform the button later and retain a crisp look and feel at any resolution or scale (particularly useful with Silverlight mobile scenarios - where screen resolutions might be different or smaller).&amp;#160; It will also allow us to easily animate/change any vector element within the artwork.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;Once we've finished designing our base state above, we can press F5 to run our application in the browser:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step13.png" /&gt; &lt;/p&gt;    &lt;p&gt;As you can see above - our Button control now has a nicer look.&amp;#160; Despite its new look, the button still raises the same focus, click and hover events just like before - so a developer using the button &lt;u&gt;does not need to change any code&lt;/u&gt; when working with a button that uses our new control template.&lt;/p&gt;    &lt;p&gt;One downside with our new button control template, though, is that it isn't interactive.&amp;#160; This means that I don't get any visual feedback if the button gains/looses focus, or if a mouse hovers over it.&amp;#160; I also don't get a nice depress/bounce-back animation when I click it.&lt;/p&gt;    &lt;p&gt;To add interactivity to our button, we'll return back to Blend and work with our Button's control template again.&amp;#160; Previously we added vector graphic elements to the &amp;quot;Base&amp;quot; state of our Button control.&amp;#160; This allowed us to define the default visual look of all visual states of our Button.&amp;#160; We can now go back and customize individual Button visual states further.&lt;/p&gt;    &lt;p&gt;For example, to implement a mouse-over behavior for our Button, we can select the &amp;quot;MouseOver&amp;quot; state in the &amp;quot;States&amp;quot; window, and then tweak the look of the button when it is in that state.&amp;#160; Below I've selected the &amp;quot;shine&amp;quot; vector element inside our control template and adjusted its Opacity property in the property grid to have it be more visible when in the MouseOver state.&amp;#160; Notice how Blend automatically highlighted the &amp;quot;Shine&amp;quot; element with a red dot and then listed the Opacity property below it in our objects window.&amp;#160; This makes it easy to quickly track all changes that we've made between the &amp;quot;Base&amp;quot; state and the &amp;quot;MouseOver&amp;quot; state in our control template:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step14.png" /&gt; &lt;/p&gt;    &lt;p&gt;We can then select the &amp;quot;Pressed&amp;quot; state in the &amp;quot;States&amp;quot; window, and customize what a button looks like when it is pressed.&amp;#160; We'll change two things from the &amp;quot;base&amp;quot; state.&amp;#160; The first change is to make the &amp;quot;shine&amp;quot; element visible (like the MouseOver state). The second change will be to slightly offset the contents of the button control - while keeping the shadow element stationary.&amp;#160; This will give the button a nice &amp;quot;depressed&amp;quot; look and contrast nicely with its base visual:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step15.png" /&gt; &lt;/p&gt;    &lt;p&gt;We can implement the offset change to the background, content and shine elements by selecting them in the designer, and then apply an offset render transform to them in the property browser:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step16.png" /&gt; &lt;/p&gt;    &lt;p&gt;And now when we run our application again in the browser, we'll find that our Button now has interactive visual feedback when it is being used.&amp;#160; Below is the &amp;quot;normal&amp;quot; look of our Button:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step17.png" /&gt; &lt;/p&gt;    &lt;p&gt;Hovering the mouse over the Button will then cause it to glow like below:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step18.png" /&gt; &lt;/p&gt;    &lt;p&gt;Clicking the button will then cause it to depress and hide the shadow (it will then bounce back once the mouse button is released):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step19.png" /&gt; &lt;/p&gt;    &lt;p&gt;Note that we &lt;u&gt;did not&lt;/u&gt; have to write any code or XAML to change our Button's look and feel - the new Visual State Manager feature automatically handled moving between visual states for us.&amp;#160; &lt;/p&gt;    &lt;p&gt;By default Silverlight dynamically constructs and runs a transition Storyboard for you as you move from visual state to visual state (providing a smooth animation between the two states).&amp;#160; You &lt;u&gt;do not&lt;/u&gt; need to write any code in order to make this happen (note: you do still have the ability to drop down and add a custom Storyboard transition if you want to, but for most cases you can probably use the automatic Storyboard transition).&lt;/p&gt;    &lt;p&gt;One feature you can take advantage of with Silverlight's automatic transition feature is to customize the time duration it takes for a visual state transition to occur.&amp;#160; You can do this by clicking the arrow to the right of a visual state and setup a rule that controls how long it should take the transition animation to run when moving from one particular state to another.&lt;/p&gt;    &lt;p&gt;For example, we could indicate that we want it to take .2 seconds to transition from the &amp;quot;Normal&amp;quot; to &amp;quot;MouseOver&amp;quot; visual state by adding the rule below: &lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step20.png" /&gt; &lt;/p&gt;    &lt;p&gt;We can then configure this rule to take .2 seconds to transition between Normal-&amp;gt;MouseOver like so:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step21.png" /&gt; &lt;/p&gt;    &lt;p&gt;We can then click on the &amp;quot;MouseOver&amp;quot; state and setup a rule that causes the transition from MouseOver-&amp;gt;Normal to take .4 seconds:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step22.png" /&gt; &lt;/p&gt;    &lt;p&gt;Now when we re-run our application we'll have slower animation transitions for MouseOver scenarios, which adds a slightly smoother and more polished feel to our application.&amp;#160; We did not have to write a single line of code to enable this.&amp;#160; &lt;u&gt;All controls &lt;/u&gt;shipped with Silverlight 2 will have built-in support for Control Template and Visual State Manager customization like above.&lt;/p&gt;    &lt;p&gt;To learn more about the new Visual State Manager and Control Template Editing features, please check out the tutorials &lt;a href="http://timheuer.com/blog/archive/2008/06/04/skinning-silverlight-controls-made-easier.aspx" target="_blank"&gt;here&lt;/a&gt; and &lt;a href="http://timheuer.com/blog/archive/2008/06/04/silverlight-introduces-visual-state-manager-vsm.aspx" target="_blank"&gt;here&lt;/a&gt;, and the videos on it &lt;a href="http://electricbeach.org/?p=98" target="_blank"&gt;here&lt;/a&gt;, &lt;a href="http://expression.microsoft.com/en-us/cc643423.aspx" target="_blank"&gt;here&lt;/a&gt;, and &lt;a href="http://electricbeach.org/?p=107" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;TextBox&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Beta2 includes some significant improvements to the built-in TextBox editing control.&amp;#160; Text scrolling with text-wrap, multi-line text selection, document navigation keys, and copy/paste from the clipboard are now supported.&lt;/p&gt;    &lt;p&gt;Beta2 also now includes IME Level 3 input support (including candidate window selection) for non-western character sets:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/sl2beta2/step24.png" /&gt; &lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Input Support&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Beta2 adds additional keyboard support in FullScreen mode (arrow, tab, enter, home, end, pageup/pagedown, space).&amp;#160; Note: full key input support isn't allowed to avoid password spoofing scenarios.&lt;/p&gt;    &lt;p&gt;Beta2 also adds new APIs to support inking and stylus input support.&lt;/p&gt;    &lt;p&gt;&lt;u&gt;&lt;strong&gt;UI Automation and Accessibility &lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;Beta2 adds UI Automation Framework support into Silverlight.&amp;#160; UI Automation (or UIA) enables screen readers and other assistive tools to identify and interact with the components that make up your Silverlight 2 application.&lt;/p&gt;    &lt;p&gt;Beta2 uses the UIA framework and adds UIA based behaviors to an initial set of Silverlight controls.&amp;#160; By the final release of Silverlight 2 all controls will have UIA based behaviors built-in.&amp;#160; We will also add support for high-contrast scenarios.&amp;#160; These features will enable you to build accessible, section 508 compliant, applications.&amp;#160; This UIA support will also enable automated UI testing of applications.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Animation and Graphic System&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Beta2 adds support for animating custom dependency properties.&amp;#160; Object animation support (animating structs) is also now supported.&amp;#160; Beta2 also supports the ability to create Storyboards in code that can animate parts of the render tree without having to be added to it (allowing you to embed animations entirely in code).&amp;#160; Per frame animation callback support will be added in the final release.&lt;/p&gt;    &lt;p&gt;Beta2 includes a new Visual Tree Helper static class that provides advanced visual tree inspection APIs.&amp;#160; It provides features such as the ability to enumerate children of an element and getting the ancestor/parent of a given reference element.&amp;#160; These APIs work against any UIElement you pass to it.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;DeepZoom&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Beta2 now supports an XML based manifest file for DeepZoom collections.&amp;#160; Beta2 also adds extensible MultiScaleTileSource support for DeepZoom (which allows developers to hook up existing image pyramids that don&amp;#8217;t conform with the Deep Zoom format to the high performance rendering of Deep Zoom).&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;WPF Compatibility&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Silverlight Beta2 includes a lot of fixes/changes to improve API compatibility between Silverlight and WPF (note: the final Silverlight release will contain some additional compatibility work as well).&amp;#160; We are also adding some new APIs we are introducing in Silverlight 2 to WPF in .NET 3.5 SP1 this summer.&lt;/p&gt;    &lt;p&gt;This work, combined with the VSM support we are adding to WPF later this year, will enable good code re-use across browser and desktop applications.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Media Improvements&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;Silverlight 2 Beta2 includes some significant Media related feature work:&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Adaptive Streaming&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Beta2 adds support for &amp;quot;adaptive streaming&amp;quot; - which enables you to encode media at multiple bit-rates and then have a Silverlight application dynamically switch between them depending on the network and CPU conditions.&lt;/p&gt;    &lt;p&gt;This enables much richer end-user media experiences - since it makes it possible for content providers to provide both lower-end and higher-end bit rate versions of a video, and then have Silverlight choose the optimal one to use based on an end-user's machine hardware and network capacity.&amp;#160; If while watching the video the machine or network conditions change, Silverlight can automatically switch to a more appropriate bit-rate without any buffering or interruption glitch.&lt;/p&gt;    &lt;p&gt;Silverlight's support for adaptive streaming is extensible - which enables anyone to plug-in their own logic to control where the media content comes from, and what bit-rate should be used.&amp;#160; This means that any CDN or media delivery provider can easily integrate their systems with Silverlight and deliver super high quality video delivery.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Content Protection&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Beta2 includes DRM content protection, and supports Windows DRM and PlayReady DRM.&amp;#160; Both work cross browser and cross platform. &lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Server Side Playlists&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Beta2 adds support for server side playlists (previous releases only supported client-side playlists).&amp;#160; &lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Networking Improvements&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;Silverlight 2 Beta2 includes a bunch of work in the networking space:&lt;/p&gt;    &lt;p&gt;&lt;u&gt;&lt;strong&gt;Cross Domain Sockets&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;Beta2 now enables cross domain networking support using both HTTP and Sockets (meaning your application can call sites other than the one the application was downloaded from).&lt;/p&gt;    &lt;p&gt;Silverlight will check for the existence of an XML policy file on target servers that indicates whether cross domain network access is allowed.&amp;#160; Silverlight supports a new XML policy file format that we've developed, as well as Flash policy files (which means existing sites open to Flash can be called from Silverlight without any additional work).&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Background Thread Networking&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Beta2 now allows Silverlight applications to initiate network requests on background threads, as well as process/handle network responses on background threads.&amp;#160; This enables a bunch of powerful scenarios, and allows you to avoid blocking the browser's UI thread while doing both HTTP and Socket network communication.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Duplex Communication (Server Push)&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Beta2 enables support for setting up duplex communication channels with a WCF service on a server.&amp;#160; This enables a clean programming model that allows servers to &amp;quot;push&amp;quot; messages to Silverlight clients without the developer having to manually poll servers for changes.&amp;#160; This programming model is very useful in a variety of scenarios, including instant messenger/chat applications, and monitoring/update applications like stock tickers and trader applications.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Web Services&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Beta2 enables significantly improved interop with SOAP based web-services.&amp;#160; Web service proxy class end-point URLs can now be configured without recompiling applications.&amp;#160; Visual Studio also now has a new &amp;quot;Silverlight-enabled WCF Service&amp;quot; project item template that you can add to ASP.NET web projects to publish services to clients.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;REST and ADO.NET Data Services&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Silverlight includes support for working with REST based web-services.&amp;#160; &lt;/p&gt;    &lt;p&gt;Beta2 adds support for calling and consuming ADO.NET Data Services (formerly code-named: &amp;quot;Astoria&amp;quot;).&amp;#160; ADO.NET Data Services will ship as part of .NET 3.5 SP1 and makes it easy to publish data end-points within an ASP.NET web project that are consumable from any client using REST URIs.&amp;#160; Silverlight Beta2 now includes ADO.NET Data Service client support that allows you to easily call these services (and optionally use LINQ expressions within Silverlight to express remote REST queries to them).&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;JSON&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Silverlight supports calling JSON-based services on the web.&amp;#160; &lt;/p&gt;    &lt;p&gt;Beta2 now includes LINQ to JSON support that enables you to easily query, filter, and map JSON results to .NET objects within a Silverlight application.&amp;#160; This makes it easy to call and work with existing AJAX end-points and services published on the web.&amp;#160; &lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Data Improvements&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;Silverlight 2 Beta2 includes a bunch of work in the data space:&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;DataGrid&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Beta2 adds a number of new features to the DataGrid control. These include:&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;Auto-sizing support for columns and rows &lt;/li&gt;      &lt;li&gt;Column sorting (with both single column and multi-column sort support)&amp;#160; &lt;/li&gt;      &lt;li&gt;Column re-ordering support by end-users (allowing them to drag/drop columns to re-arrange the order) &lt;/li&gt;      &lt;li&gt;Frozen column support (allowing you to prevent a particular column from being customized) &lt;/li&gt;      &lt;li&gt;Performance and bug fixes &lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;DataBinding&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Beta2 adds more core data-binding features and better validation support.&amp;#160; These include:&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;Per-binding Validation and BindingValidationError event handler support on controls (allowing you to handle input validation with TwoWay bindings)&lt;/li&gt;      &lt;li&gt;Support for binding expressions on attached properties &lt;/li&gt;      &lt;li&gt;Richer binding value conversion support (including value conversion fallback support) &lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Isolated Storage&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Silverlight enables applications to store data locally on a client (via a feature we call &amp;quot;Isolated Storage&amp;quot;).&amp;#160; Applications can prompt users to grant them size permissions for this storage (for example: a user might grant an email program 50MB of local storage).&amp;#160; &lt;/p&gt;    &lt;p&gt;Beta2 increases the default local storage space provided to Silverlight applications to 1MB in size.&amp;#160; Beta2 also now provides better end-user support for managing per-site storage permissions, as well as the ability to easily revoke/delete an application's local storage.&amp;#160; Management UI to control this can now be brought up by an end-user by right-clicking on a Silverlight application and choosing the &amp;quot;Silverlight Configuration&amp;quot; menu option.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Understanding Compatibility with Silverlight 1.0 and Silverlight 2 Beta 1&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;Silverlight 2 Beta2 is compatible with applications that target Silverlight 1.0.&lt;/p&gt;    &lt;p&gt;Silverlight 2 Beta2 will not run applications that target Silverlight 2 Beta1, since we've made a number of API changes between the two betas for the new features being added in Silverlight 2.&amp;#160; Browsers that have Silverlight 2 Beta1 installed which visit a site that hosts a Silverlight Beta2 application will be prompted to upgrade to the newer beta of Silverlight.&amp;#160; Once they do this they won't be able to run Beta1 applications without uninstalling Beta2.&amp;#160; This means that if you have published a running sample on the web built with Beta1 you will probably want to update it to Beta2 soon.&amp;#160; &lt;/p&gt;    &lt;p&gt;We have published a document that details the changes between Beta1 and Beta2 &lt;a href="http://go.microsoft.com/fwlink/?LinkID=120655&amp;amp;clcid=0x409 " target="_blank"&gt;here&lt;/a&gt; that can help with this.&amp;#160; I also recommend reading Shawn Wildermuth's &lt;a href="http://adoguy.com/2008/06/06/What_s_Changed_in_Silverlight_2_Beta_2.aspx" target="_blank"&gt;What Changed in Silverlight 2 Beta2&lt;/a&gt; and &lt;a href="http://adoguy.com/2008/06/06/Upgrading_your_Silverlight_2_Projects_to_Beta_2.aspx" target="_blank"&gt;Upgrading your Silverlight 2 Projects to Beta2&lt;/a&gt; posts for more details on some of the changes between Beta1 and Beta2.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Summary&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;To learn more about Silverlight 2 and download the Beta2 release, please visit the &lt;a href="http://silverlight.net/GetStarted/" target="_blank"&gt;http://www.silverlight.net&lt;/a&gt; and &lt;a href="http://expression.microsoft.com/en-us/cc643423.aspx" target="_blank"&gt;http://expression.microsoft.com&lt;/a&gt; web-sites.&amp;#160; We'll be posting articles, tutorials, videos and more on both sites in the days and weeks ahead.&amp;#160; I'll also be posting some tutorials of my own here on my blog as well.&amp;#160; &lt;/p&gt;    &lt;p&gt;If you haven't already read them I'd also recommend checking out my previous &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/02/22/first-look-at-silverlight-2.aspx" target="_blank"&gt;First Look at Silverlight 2&lt;/a&gt; and &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/02/28/first-look-at-using-expression-blend-with-silverlight-2.aspx" target="_blank"&gt;First Look at Expression Blend with Silverlight 2&lt;/a&gt; blog posts that I wrote a few months ago when Beta1 shipped, since they provide a good overview of the Silverlight programming model and how to target it using both Visual Studio 2008 and Expression Blend.&lt;/p&gt;    &lt;p&gt;Hope this helps,&lt;/p&gt;    &lt;p&gt;Scott&lt;/p&gt; &lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6255040" width="1" height="1"&gt;</description>
      <link>http://weblogs.asp.net/scottgu/archive/2008/06/06/silverlight-2-beta2-released.aspx</link>
      <author>ScottGu</author>
      <pubDate>Sat, 07 Jun 2008 04:50:26 GMT</pubDate>
    </item>
    <item>
      <title>Powershell door Marc van Orsouw: demo code staan online</title>
      <description>&lt;p&gt;Voor diegene die er bij waren en ook voor diegene die er niet bij waren maar wel geinteresseerd zijn: de demo code van Marc van Orsouw staat online op &lt;a title="http://www.dotned.nl/files/8/ppt/entry849.aspx" href="http://www.dotned.nl/files/8/ppt/entry849.aspx"&gt;http://www.dotned.nl/files/8/ppt/entry849.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=850" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/06/05/850.aspx</link>
      <author>dvroegop</author>
      <pubDate>Thu, 05 Jun 2008 16:42:27 GMT</pubDate>
    </item>
    <item>
      <title>ASP.NET MVC Support with Visual Web Developer 2008 Express</title>
      <description>&lt;font face="arial" size="2"&gt;   &lt;p&gt;Last week I blogged about the &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/05/27/asp-net-mvc-preview-3-release.aspx" target="_blank"&gt;ASP.NET MVC Preview 3 release&lt;/a&gt;.&amp;#160; One important thing I forgot to mention about this release is that you can now use it with both Visual Studio 2008 as well as the free Visual Web Developer 2008 Express edition.&amp;#160; &lt;/p&gt;    &lt;p&gt;The SP1 release of Visual Web Developer 2008 Express adds support for both class library projects as well as web application projects (previously only web site projects could be used with it).&amp;#160; This new support is useful in itself, as well as in enabling both ASP.NET MVC and Silverlight project support with VWD Express.&amp;#160; If you install the Visual Web Developer Express &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/05/12/visual-studio-2008-and-net-framework-3-5-service-pack-1-beta.aspx" target="_blank"&gt;SP1 Beta&lt;/a&gt; you can start using ASP.NET MVC Preview 3 with it immediately.&lt;/p&gt;    &lt;p&gt;Important: ASP.NET MVC Preview 3 &lt;em&gt;&lt;u&gt;does not&lt;/u&gt;&lt;/em&gt; require SP1 to be installed if you are using Visual Studio 2008.&amp;#160; ASP.NET MVC Preview 3 will work with both VS 2008 and VS 2008 SP1 just fine.&amp;#160; &lt;/p&gt;    &lt;p&gt;You can learn more about the new VWD Express support for ASP.NET MVC from the VS Web Tools team blog &lt;a href="http://blogs.msdn.com/webdevtools/archive/2008/05/30/asp-net-mvc-preview-3-tooling-updates.aspx" target="_blank"&gt;here&lt;/a&gt;.&amp;#160; This post also includes a free web download that provides ASP.NET MVC Test project support for NUnit-based unit tests.&amp;#160; You can use these NUnit project templates with both Visual Studio 2008 as well as with Visual Web Developer Express 2008.&lt;/p&gt;    &lt;p&gt;Hope this helps,&lt;/p&gt;    &lt;p&gt;Scott&lt;/p&gt; &lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6240690" width="1" height="1"&gt;</description>
      <link>http://weblogs.asp.net/scottgu/archive/2008/06/01/asp-net-mvc-support-with-visual-web-developer-2008-express.aspx</link>
      <author>ScottGu</author>
      <pubDate>Mon, 02 Jun 2008 03:50:22 GMT</pubDate>
    </item>
    <item>
      <title>ASP.NET MVC Preview 3 Release</title>
      <description>&lt;font face="arial" size="2"&gt;   &lt;p&gt;This morning we released the Preview 3 build of the ASP.NET MVC framework.&amp;#160; I blogged details last month about &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/04/16/asp-net-mvc-source-refresh-preview.aspx" target="_blank"&gt;an interim source release&lt;/a&gt; we did that included many of the changes with this Preview 3 release.&amp;#160; Today's build includes some additional features not in last month's drop, some nice enhancements/refinements, as well as Visual Studio tool integration and documentation.&lt;/p&gt;    &lt;p&gt;You can download an integrated ASP.NET MVC Preview 3 setup package &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=92F2A8F0-9243-4697-8F9A-FCF6BC9F66AB&amp;amp;displaylang=en" target="_blank"&gt;here&lt;/a&gt;.&amp;#160; You can also optionally download the ASP.NET MVC Preview 3 framework source code and framework unit tests &lt;a href="http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=aspnet&amp;amp;ReleaseId=13792" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Controller Action Method Changes&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;ASP.NET MVC Preview 3 includes the MVC Controller changes we first discussed and previewed with the &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/04/16/asp-net-mvc-source-refresh-preview.aspx" target="_blank"&gt;April MVC source release&lt;/a&gt;, along with some additional tweaks and adjustments.&amp;#160; &lt;/p&gt;    &lt;p&gt;You can continue to write controller action methods that return void and encapsulate all of their logic within the action method.&amp;#160; For example:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvc3announce/step2.png" /&gt; &lt;/p&gt;    &lt;p&gt;which would render the below HTML when run:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvc3announce/step3.png" /&gt; &lt;/p&gt;    &lt;p&gt;Preview 3 also now supports using an approach where you return an &amp;quot;ActionResult&amp;quot; object that indicates the result of the action method, and enables deferred execution of it.&amp;#160; This allows much easier unit testing of actions (without requiring the need to mock anything).&amp;#160; It also enables much cleaner composition and overall execution control flow.&lt;/p&gt;    &lt;p&gt;For example, we could use LINQ to SQL within our Browse action method to retrieve a sequence of Product objects from our database and indicate that we want to render a View of them.&amp;#160; The code below will cause three pieces of &amp;quot;ViewData&amp;quot; to be passed to the view - &amp;quot;Title&amp;quot; and &amp;quot;CategoryName&amp;quot; string values, and a strongly typed sequence of products (passed as the ViewData.Model object):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvc3announce/step5.png" /&gt; &lt;/p&gt;    &lt;p&gt;One advantage of using the above ActionResult approach is that it makes unit testing Controller actions really easy (no mocking required).&amp;#160; Below is a unit test that verifies the behavior of our Browse action method above:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvc3announce/step11.png" /&gt;&amp;#160; &lt;/p&gt;    &lt;p&gt;We can then author a &amp;quot;Browse&amp;quot; ViewPage within the \Views\Products sub-directory to render a response using the ViewData populated by our Browse action:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvc3announce/step6.png" /&gt; &lt;/p&gt;    &lt;p&gt;When we hit the /Products/Browse/Beverages URL we'll then get an HTML response like below (with the three usages of ViewData circled in red):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvc3announce/step7.png" /&gt; &lt;/p&gt;    &lt;p&gt;Note that in addition to support a &amp;quot;ViewResult&amp;quot; response (for indicating that a View should be rendered), ASP.NET MVC Preview 3 also adds support for returning &amp;quot;JsonResult&amp;quot; (for AJAX JSON serialization scenarios), &amp;quot;ContentResult&amp;quot; (for streaming content without a View), as well as HttpRedirect and RedirectToAction/Route results.&amp;#160;&amp;#160; &lt;/p&gt;    &lt;p&gt;The overall ActionResult approach is extensible (allowing you to create your own result types), and overtime you'll see us add several more built-in result types.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Improved HTML Helper Methods&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;The HTML helper methods have been updated with ASP.NET MVC Preview 3.&amp;#160; In addition to a bunch of bug fixes, they also include a number of nice usability improvements.&lt;/p&gt;    &lt;p&gt;&lt;u&gt;Automatic Value Lookup&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;With previous preview releases you needed to always explicitly pass in the value to render when calling the Html helpers.&amp;#160; For example: to include a value within a &amp;lt;input type=&amp;quot;text&amp;quot; value=&amp;quot;some value&amp;quot;/&amp;gt; element you would write:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvc3announce/step13.png" /&gt; &lt;/p&gt;    &lt;p&gt;The above code continues to work - although now you can also just write:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvc3announce/step14.png" /&gt; &lt;/p&gt;    &lt;p&gt;The HTML helpers will now by default check both the ViewData dictionary and any Model object passed to the view for a ProductName key or property value to use.&lt;/p&gt;    &lt;p&gt;&lt;u&gt;SelectList and MultiSelectList ViewModels&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;New SelectList and MultiSelectList View-Model classes are now included that provide a cleaner way to populate HTML dropdowns and multi-select listboxes (and manage things like current selection, etc).&amp;#160; One approach that can make form scenarios cleaner is to instantiate and setup these View-Model objects in a controller action, and then pass them in the ViewData dictionary to the View to format/render.&amp;#160; &lt;/p&gt;    &lt;p&gt;For example, below I'm creating a SelectList view-model class over the set of unique category objects in our database.&amp;#160; I'm indicating that I want to use the &amp;quot;CategoryID&amp;quot; property as the value of each item in the list, and the &amp;quot;CategoryName&amp;quot; as the display text.&amp;#160; I'm also setting the list selection to the current CategoryId of the Product we are editing:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvc3announce/step23.png" /&gt; &lt;/p&gt;    &lt;p&gt;Within our view we then just have to write the below code to indicate that we want to create a drop-downlist against the SelectList we put into ViewData:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvc3announce/step17.png" /&gt; &lt;/p&gt;    &lt;p&gt;This will then render the appropriate drop down with items and selection for us at runtime:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvc3announce/step20.png" /&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvc3announce/step19.png" /&gt; &lt;/p&gt;    &lt;p&gt;Built-in error validation support isn't included with our HTML helpers yet (you currently need to write code for this) - but will show up in the future, which will make form editing scenarios even easier.&lt;/p&gt;    &lt;p&gt;You'll also start to see ASP.NET AJAX helper methods show up in future preview releases as well, which will make it easier to integrate AJAX into MVC applications with a minimum of code.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;URL Routing Improvements&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;ASP.NET MVC Preview 3 includes a number of improvements to the URL routing system.&amp;#160; URL routing is one of the most &amp;quot;fundamental&amp;quot; components of a web MVC framework to get right, hence the reason we've spent a lot of focus the first few previews getting this area nailed.&amp;#160; Our new URL routing engine will ship in .NET 3.5 SP1 this summer, and will support both Web Forms and MVC requests.&amp;#160; ASP.NET MVC will be able to use the built-in .NET 3.5 SP1 routing engine when running on .NET 3.5 SP1. ASP.NET MVC will also include its own copy of the assembly so that it can also work on non-SP1 systems.&lt;/p&gt;    &lt;p&gt;Some of the URL Routing Improvements in the Preview 3 release include:&lt;/p&gt;    &lt;p&gt;&lt;u&gt;MapRoute() and IgnoreRoute() helper methods&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;ASP.NET MVC Preview 3 includes new &amp;quot;MapRoute&amp;quot; and &amp;quot;IgnoreRoute&amp;quot; helper methods that you can use to more easily register routing rules.&amp;#160; MapRoute() provides an easy way to add a new MVC Route rule to the Routes collection.&amp;#160; IgnoreRoute() provides an easy way to tell the URL routing system to stop processing certain URL patterns (for example: handler .axd resources in ASP.NET that are used to serve up JavaScript, images, etc).&amp;#160; &lt;/p&gt;    &lt;p&gt;Below is an example of the default RegisterRoutes() method within Global.asax when you create a new ASP.NET MVC project where you can see both of these new helper methods in action.&amp;#160; &lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/mvc3announce/step1.png" /&gt; &lt;/p&gt;    &lt;p&gt;The MapRoute() helper method is overloaded and takes two, three or four parameters (route name, URL syntax, URL parameter default, and optional URL parameter regular expression constraints).&amp;#160; &lt;/p&gt;    &lt;p&gt;You can call MapRoute() as many times as you want to register multiple named routes in the system.&amp;#160; For example, in addition to the default convention rule, we could add a &amp;quot;Products-Browse&amp;quot; named routing rule like below:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/aprilmvc/step28.png" /&gt;&lt;/p&gt;    &lt;p&gt;We can then refer to this &amp;quot;Products-Browse&amp;quot; rule explicitly within our Controllers and Views when we want to generate a URL to it.&amp;#160; For example, we could use the Html.RouteLink view helper to indicate that we want to link to our &amp;quot;Products-Browse&amp;quot; route and pass it a &amp;quot;Food&amp;quot; category parameter using code in our view template like below:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/aprilmvc/step29.png" /&gt;&lt;/p&gt;    &lt;p&gt;This view helper would then access the routing system and output an appropriate HTML hyperlink URL like below (note: how it did automatic parameter substitution of the category parameter into the URL using the route rule):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/aprilmvc/step30.png" /&gt;&lt;/p&gt;    &lt;p&gt;We could alternatively use the new &lt;em&gt;Url.RouteUrl(routeName, values)&lt;/em&gt; within views if we wanted to just retrieve the URL for a named route (and not output the &amp;lt;a&amp;gt; html element).&amp;#160; &lt;/p&gt;    &lt;p&gt;We could also use the new &lt;em&gt;RedirectToRoute(routeName, values)&lt;/em&gt; helper method on the Controller base class to issues browser redirects based on named routing rules.&amp;#160; &lt;/p&gt;    &lt;h5&gt;&lt;u&gt;Richer URL Route Mapping Features&lt;/u&gt;&lt;/h5&gt;    &lt;p&gt;ASP.NET MVC Preview 3 also supports a bunch of new URL route mapping features.&amp;#160; You can now include &amp;quot;-&amp;quot;, &amp;quot;.&amp;quot;, &amp;quot;;&amp;quot; or any other characters you want as part of your route rules.&lt;/p&gt;    &lt;p&gt;For example, using a &amp;quot;-&amp;quot; separator you can now parse the language and locale values from your URLs separately using a rule like below:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/aprilmvc/step32.png" /&gt;&lt;/p&gt;    &lt;p&gt;This would pass appropriate &amp;quot;language&amp;quot;, &amp;quot;locale&amp;quot;, and &amp;quot;category&amp;quot; parameters to a ProductsController.Browse action method when invoked:&lt;/p&gt;    &lt;table cellspacing="0" cellpadding="2" width="856" border="1"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="297"&gt;&lt;font face="arial" size="2"&gt;&lt;u&gt;URL Route Rule&lt;/u&gt;&lt;/font&gt;&lt;/td&gt;          &lt;td valign="top" width="198"&gt;&lt;font face="arial" size="2"&gt;&lt;u&gt;Example URL&lt;/u&gt;&lt;/font&gt;&lt;/td&gt;          &lt;td valign="top" width="355"&gt;&lt;font face="arial" size="2"&gt;&lt;u&gt;Parameters Passed to Action method&lt;/u&gt;&lt;/font&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="297"&gt;&lt;font face="arial" size="2"&gt;{language}-{locale}/products/browse/{category}&lt;/font&gt;&lt;/td&gt;          &lt;td valign="top" width="198"&gt;&lt;font face="arial" size="2"&gt;/en-us/products/browse/food&lt;/font&gt;&lt;/td&gt;          &lt;td valign="top" width="355"&gt;&lt;font face="arial" size="2"&gt;language=en, locale=us, category=food&lt;/font&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="296"&gt;&amp;#160;&lt;/td&gt;          &lt;td valign="top" width="198"&gt;&lt;font face="arial" size="2"&gt;/en-uk/products/browse/food&lt;/font&gt;&lt;/td&gt;          &lt;td valign="top" width="355"&gt;&lt;font face="arial" size="2"&gt;language=en, locale=uk, category=food&lt;/font&gt;&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;    &lt;p&gt;Or you can use the &amp;quot;.&amp;quot; file extension type at the end of a URL to determine whether to render back the result in either a XML or HTML format:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/aprilmvc/step33.png" /&gt;&lt;/p&gt;    &lt;p&gt;This would pass both &amp;quot;category&amp;quot; and a &amp;quot;format&amp;quot; parameters to the ProductsController.Browse action method when invoked: &lt;/p&gt;    &lt;p&gt;     &lt;table cellspacing="0" cellpadding="2" width="852" border="1"&gt;&lt;tbody&gt;         &lt;tr&gt;           &lt;td valign="top" width="297"&gt;&lt;font face="arial" size="2"&gt;&lt;u&gt;URL Route Rule&lt;/u&gt;&lt;/font&gt;&lt;/td&gt;            &lt;td valign="top" width="198"&gt;&lt;font face="arial" size="2"&gt;&lt;u&gt;Example URL&lt;/u&gt;&lt;/font&gt;&lt;/td&gt;            &lt;td valign="top" width="355"&gt;&lt;font face="arial" size="2"&gt;&lt;u&gt;Parameters Passed to Action method&lt;/u&gt;&lt;/font&gt;&lt;/td&gt;         &lt;/tr&gt;          &lt;tr&gt;           &lt;td valign="top" width="297"&gt;&lt;font face="arial" size="2"&gt;products/browse/{category}.{format}&lt;/font&gt;&lt;/td&gt;            &lt;td valign="top" width="198"&gt;&lt;font face="arial" size="2"&gt;/products/browse/food.xml&lt;/font&gt; &lt;/td&gt;            &lt;td valign="top" width="355"&gt;&lt;font face="arial" size="2"&gt;category=food, format=xml&lt;/font&gt;&lt;/td&gt;         &lt;/tr&gt;          &lt;tr&gt;           &lt;td valign="top" width="296"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="198"&gt;&lt;font face="arial" size="2"&gt;/products/browse/food.html&lt;/font&gt;&lt;/td&gt;            &lt;td valign="top" width="355"&gt;&lt;font face="arial" size="2"&gt;category=food, format=html&lt;/font&gt;&lt;/td&gt;         &lt;/tr&gt;       &lt;/tbody&gt;&lt;/table&gt;   &lt;/p&gt;    &lt;p&gt;ASP.NET MVC Preview 3 also supports wildcard route rules (these were also in Preview 2).&amp;#160; &lt;font face="arial" size="2"&gt;For example, you can indicate in a rule to pass all remaining URI content on as a named parameter to an action method: &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;img src="http://www.scottgu.com/blogposts/aprilmvc/step34.png" /&gt; &lt;/p&gt;    &lt;p&gt;This would pass a &amp;quot;contentUrl&amp;quot; parameter to the WikiController.DisplayPage action method when invoked:&lt;/p&gt;    &lt;table cellspacing="0" cellpadding="2" width="852" border="1"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="297"&gt;&lt;font face="arial" size="2"&gt;&lt;u&gt;URL Route Rule&lt;/u&gt;&lt;/font&gt;&lt;/td&gt;          &lt;td valign="top" width="198"&gt;&lt;font face="arial" size="2"&gt;&lt;u&gt;Example URL&lt;/u&gt;&lt;/font&gt;&lt;/td&gt;          &lt;td valign="top" width="355"&gt;&lt;font face="arial" size="2"&gt;&lt;u&gt;Parameters Passed to Action method&lt;/u&gt;&lt;/font&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="297"&gt;&lt;font face="arial" size="2"&gt;Wiki/Pages/{*contentUrl}&lt;/font&gt;&lt;/td&gt;          &lt;td valign="top" width="198"&gt;&lt;font face="arial" size="2"&gt;/Wiki/Pages/People/Scott&lt;/font&gt;&lt;/td&gt;          &lt;td valign="top" width="355"&gt;&lt;font face="arial" size="2"&gt;contentUrl=&amp;quot;People/Scott&amp;quot;&lt;/font&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="296"&gt;&amp;#160;&lt;/td&gt;          &lt;td valign="top" width="198"&gt;&lt;font face="arial" size="2"&gt;/Wiki/Pages/Countries/UK&lt;/font&gt;&lt;/td&gt;          &lt;td valign="top" width="355"&gt;&lt;font face="arial" size="2"&gt;contentUrl=&amp;quot;Countries/UK&amp;quot;&lt;/font&gt;&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;    &lt;p&gt;These wildcard routes are very useful to look at if you are building a blogging, wiki, cms or other content based system.&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Summary&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;Today's Preview 3 release of ASP.NET MVC includes a bunch of improvements and refinements.&amp;#160; We are starting to feel good about the URL routing and Controller/Action programming model of MVC, and feel that those areas are starting to bake really well.&amp;#160; In future preview releases you'll start to see more improvements higher-up the programming model stack in areas like Views (html helpers, validation helpers, etc), AJAX, sub-controllers and site composition, deeper Login, Authentication, Authorization and Caching integration, as well as data scaffolding support.&amp;#160; &lt;/p&gt;    &lt;p&gt;I also have a (very) long tutorial post that I started putting together this past weekend that walks-through building an application using ASP.NET MVC Preview 3 that I'm hoping to wrap up and post in the next few days.&amp;#160; This should provide both a good intro to ASP.NET MVC, as well as help provide some context on how all the pieces fit together if you are interested in using the ASP.NET MVC option.&lt;/p&gt;    &lt;p&gt;Hope this helps,&lt;/p&gt;    &lt;p&gt;Scott&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6225249" width="1" height="1"&gt;</description>
      <link>http://weblogs.asp.net/scottgu/archive/2008/05/27/asp-net-mvc-preview-3-release.aspx</link>
      <author>ScottGu</author>
      <pubDate>Tue, 27 May 2008 22:26:36 GMT</pubDate>
    </item>
    <item>
      <title>Altijd zicht op alle events: de dotnetevents site</title>
      <description>&lt;p&gt;Zoals je weet organiseren wij bij dotNed iedere maand een gratis bijeenkomst. Het enige wat we van je verlangen is dat je je inschrijft zodat we weten hoeveel mensen er komen. Naast deze bijeenkomsten (komende donderdag weer: dit keer over Powershell, er zijn nog plaatsen over, dus schrijf je in op &lt;a href="http://www.dotned.nl/meetings/default.aspx"&gt;http://www.dotned.nl/meetings/default.aspx&lt;/a&gt; !) zijn wij ook aanwezig op evenementen zoals de &lt;a title="DevDays" href="http://www.devdays.nl" target="_blank"&gt;DevDays&lt;/a&gt;, de &lt;a title="Software Development Network" href="http://www.sdn.nl" target="_blank"&gt;SDN bijeenkomsten&lt;/a&gt;, de &lt;a title="De Nederlandse CodeCamp" href="http://www.codecamp.nl/" target="_blank"&gt;CodeCamp&lt;/a&gt; en natuurlijk de &lt;a title="SDC" href="http://www.sdc.nl" target="_blank"&gt;SDC&lt;/a&gt;. Mocht dit nou nog niet genoeg zijn, dan hebben we goed nieuws: er zijn meer evenementen in Nederland voor de .net ontwikkelaar dan bovengenoemde!&lt;/p&gt;  &lt;p&gt;Het is alleen wel af en toe lastig om bij te houden wanneer nou wat gebeurt. Om dit probleem te omzeilen heeft MVP &lt;a title="Site van Maurice" href="http://www.theproblemsolver.nl/" target="_blank"&gt;Maurice de Beijer&lt;/a&gt; (beter bekend als 'The Problemsolver') een nieuwe site gebouwd met daarop alle events die eventueel voor jou interessant kunnen zijn (mits het met .net te maken heeft, uiteraard). Je vindt deze kalender op &lt;a title="http://www.dotnetevents.nl/Default.aspx" href="http://www.dotnetevents.nl/Default.aspx"&gt;http://www.dotnetevents.nl/Default.aspx&lt;/a&gt; En ja: ook de dotNed events worden hier opgenomen. Een aanrader!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=846" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/05/27/846.aspx</link>
      <author>dvroegop</author>
      <pubDate>Tue, 27 May 2008 09:30:33 GMT</pubDate>
    </item>
    <item>
      <title>DevDays, verslag volgt...</title>
      <description>&lt;p&gt;Maar tot die tijd wilde ik je dit niet onthouden. Mochten er nu nog mensen zijn die denken dat er rivaliteit tussen de Nederlandse Usergroups bestaat, dan moeten ze dit zeker lezen!&lt;/p&gt;  &lt;p&gt;&lt;a title="http://tweakers.net/advertorials/devdays/article/17/brug-tussen-ontwikkelaars-en-microsoft.html" href="http://tweakers.net/advertorials/devdays/article/17/brug-tussen-ontwikkelaars-en-microsoft.html"&gt;http://tweakers.net/advertorials/devdays/article/17/brug-tussen-ontwikkelaars-en-microsoft.html&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=845" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/05/23/845.aspx</link>
      <author>dvroegop</author>
      <pubDate>Fri, 23 May 2008 19:07:56 GMT</pubDate>
    </item>
    <item>
      <title>WPF: Attached dependency properties</title>
      <description>&lt;H2&gt;Dependency Properties&lt;/H2&gt;
&lt;P&gt;Wie wel eens met WPF gespeeld heeft kent waarschijnlijk de term Dependency Property wel. Het is een nieuwe manier om met properties om te gaan, en ik moet zeggen: ze hebben er iets moois van gemaakt. Niet verwonderlijk als je bedenkt dat Dependency Properties een van de eerste dingen die ze bedacht hebben voor WPF: de eerste voorstellen voor deze techniek stammen uit het jaar 2000!&lt;/P&gt;
&lt;P&gt;Voor diegene die het niet kennen volgt hier een korte uitleg.&lt;/P&gt;
&lt;P&gt;We kennen allemaal wel de 'normale' properties. Neem bijvoorbeeld het volgende stuk code:&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;SomeClass&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 9&lt;/SPAN&gt; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 10&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; _Getal;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 11&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 12&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; Getal&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 13&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 14&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; _Getal; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 15&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 16&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 17&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (_Getal == &lt;SPAN style="COLOR: blue"&gt;value&lt;/SPAN&gt;)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 18&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 19&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _Getal = &lt;SPAN style="COLOR: blue"&gt;value&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 20&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 21&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 22&lt;/SPAN&gt; }&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Dit is allemaal leuk en aardig maar heeft een klein probleem. Stel dat we 100 instances maken van deze class (dus 100 objecten in het geheugen hebben van dit type). Het geheugen ziet er dan als volgt uit: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;1 maal de code 
&lt;LI&gt;100 maal de virtual method table (met pointers vanuit ieder object naar de code) 
&lt;LI&gt;100 pointers naar de virtual method table (de pointers naar de objecten) 
&lt;LI&gt;100 integers met de standaard waarde 0 &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;De eerste 3 kunnen we niets aan doen. Maar die laatste... laten we daar eens over nadenken. Stel je hebt een class met daarin tientallen properties. Niet alle worden gevuld, veel hebben de default waardes en die blijven ook zo. Neem bijvoorbeeld een Button class (de welbekende knop uit WinForms). Die heeft enorm veel properties die vrijwel allemaal ongewijzigd blijven. De name, location, size en caption, ja: die worden aangepast. Maar de rest? Blijft meestal standaard. Toch nemen al die properties ruimte in beslag: voor iedere instance, dus ieder object, weer opnieuw.&lt;/P&gt;
&lt;P&gt;Het zou mooier zijn als we de defaultwaardes ergens kunnen parkeren, bijvoorbeeld bij het stuk code. Een keer slechts, en niet iedere keer opnieuw. Alleen als we willen dat de waarde afwijkt van de default waarde, dan moet de waarde opgeslagen worden bij het object zelf. Op die manier kunnen we enorm veel geheugen besparen. &lt;/P&gt;
&lt;P&gt;Dit is nou precies een van de dingen die DependencyProperties voor ons doen. Een voorbeeld:&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 9&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;SomeClass&lt;/SPAN&gt; : &lt;SPAN style="COLOR: #2b91af"&gt;DependencyObject&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 10&lt;/SPAN&gt; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 11&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;readonly&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;DependencyProperty&lt;/SPAN&gt; GetalProperty = &lt;SPAN style="COLOR: #2b91af"&gt;DependencyProperty&lt;/SPAN&gt;.Register(&lt;SPAN style="COLOR: #a31515"&gt;"Getal"&lt;/SPAN&gt;, &lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 12&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;), &lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 13&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;SomeClass&lt;/SPAN&gt;), &lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 14&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;PropertyMetadata&lt;/SPAN&gt;(0, PropertyChanged));&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 15&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 16&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; PropertyChanged(&lt;SPAN style="COLOR: #2b91af"&gt;DependencyObject&lt;/SPAN&gt; obj, &lt;SPAN style="COLOR: #2b91af"&gt;DependencyPropertyChangedEventArgs&lt;/SPAN&gt; args)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 17&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 18&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt;(obj &lt;SPAN style="COLOR: blue"&gt;is&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;SomeClass&lt;/SPAN&gt;)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 19&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((&lt;SPAN style="COLOR: #2b91af"&gt;SomeClass&lt;/SPAN&gt;)obj).ObjectPropertyChanged(args);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 20&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 21&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 22&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ObjectPropertyChanged(&lt;SPAN style="COLOR: #2b91af"&gt;DependencyPropertyChangedEventArgs&lt;/SPAN&gt; args)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 23&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 24&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// Doe iets met de nieuwe waarde&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 25&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 26&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 27&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; Getal&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 28&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 29&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;)GetValue(GetalProperty); }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 30&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt; { SetValue(GetalProperty, &lt;SPAN style="COLOR: blue"&gt;value&lt;/SPAN&gt;); }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 31&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 32&lt;/SPAN&gt; }&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Ik geef toe: het ziet er een stuk ingewikkelder uit dan de eerste code, maar als je even meeloopt door de code heen zul je zien dat het eigenlijk enorm meevalt.&lt;/P&gt;
&lt;P&gt;We beginnen met de class declaration: deze is nu afgeleid van DependencyObject, en niet meer van Object. Voor dit verhaal moet je nu maar even aannemen dat DependencyObject hetzelde doet als Object. &lt;/P&gt;
&lt;P&gt;Dan op regel 11 definieren we de DependencyProperty. Zoals je ziet is hij static en readonly. Static is mooi. Dat betekent dus dat hij inderdaad maar een keer in het geheugen staat. Hij is readonly, want de gebruikers van de class kunnen de property niet wijzigen. De naam van de DependencyProperty eindigt op ...Property. Dat is een coding convention waarvan ik je aanraadt hem ook te gebruiken. &lt;/P&gt;
&lt;P&gt;Een DependencyProperty moet geregistreerd worden. Daartoe gebruiken we de static method Register in de DependencyPropert class. Deze heeft een aantal overloads, in dit geval gebruik ik de volgende parameters (dit is gelijk de meest voorkomende vorm). Als eerste geven we hem een naam. Als tweede het type (int in ons geval), als derde het type van de class die de owner is (vrijwel altijd de class waarin hij gedefinieerd is) en als laatste maken we een PropertyMetaData object aan.&lt;/P&gt;
&lt;P&gt;Dit PropertyMetaData object bevat in ons geval als eerste de default waarde (die inderdaad maar 1 keer opgeslagen wordt in het geheugen!) en de naam van de method die aangeroepen wordt als de waarde van de property verandert ten opzichte van de default waarde.&lt;/P&gt;
&lt;P&gt;Aangezien de DependencyProperty een static is, moet de PropertyChanged method ook static zijn. Die zie je in regel 16 staan. We kijken eerst even of de DependencyObject die ons aanroept inderdaad een SomeClass is (in ons geval is dat altijd zo: we hebben maar 1 DependencyProperty en de owner daarvan is... inderdaad: SomeClass) en vervolgens roepen we de instance method ObjectPropertyChanged aan. Daarin kunnen we allerlei dingen doen die moeten gebeuren als een property wijzigt. Denk bijvoorbeeld weer aan een button: als de Width wijzigt, zullen we de code moeten aanroepen die de Paint verzorgd. &lt;/P&gt;
&lt;P&gt;De DependencyProperty is readonly. We kunnen er dus niet veel mee doen behalve uitlezen. Om nu toch toegang te geven definieren we een standaard property met dezelfde naam als de DependencyProperty maar zonder de postfix Property (en dezelfde naam als we gedefinieerd hebben in de Register method): Getal. Dit is een int en bevat een getter en een setter. In plaats van dat we in de getter en setter een backing field benaderen (die hebben we immers niet) gebruiken we de methods GetValue en SetValue. Deze komen uit de DependencyObject class en zorgen ervoor dat de waardes op de juiste plek komen. Als de waarde die gezet is gelijk is aan de default waarde, wordt er geen extra geheugen gebruikt. Als de waarde echter afwijkt, wordt er een int gealloceerd bij het object en daarin komt de nieuwe waarde te staan.&lt;/P&gt;
&lt;P&gt;GetValue en SetValue nemen als waarde altijd een object van het type Object aan, dus bij de getter moeten we die even casten naar het juiste type.&lt;/P&gt;
&lt;P&gt;Lees het nog een keer door en je zult zien dat het eigenlijk voor zich spreekt.&lt;/P&gt;
&lt;H2&gt;Attached Dependency Properties&lt;/H2&gt;
&lt;P&gt;Laten we het nog even ingewikkelder maken.&lt;/P&gt;
&lt;P&gt;Naast de normale dependency properties kennen we ook de attached dependency properties. Deze zijn helemaal leuk.&lt;/P&gt;
&lt;P&gt;Als het goed is heb je wel eens met de Grid gewerkt. Die krijg je immers standaard bij een Windows WPF Applicatie. De XAML code ziet er als volgt uit (ik heb even wat columns en rows toegevoegd):&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;P&gt;&amp;lt;Window x:Class="WpfApplication2.Window1" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&lt;/A&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Title="Window1" Height="300" Width="300"&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Grid&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Grid.ColumnDefinitions&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ColumnDefinition/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ColumnDefinition/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Grid.ColumnDefinitions&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Grid.RowDefinitions&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;RowDefinition/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;RowDefinition/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;RowDefinition/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Grid.RowDefinitions&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Label Grid.Column="0" Grid.Row="0"&amp;gt;0 - 0&amp;lt;/Label&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Label Grid.Column="1" Grid.Row="0"&amp;gt;1 - 0&amp;lt;/Label&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Label Grid.Column="0" Grid.Row="1"&amp;gt;0 - 1&amp;lt;/Label&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Label Grid.Column="1" Grid.Row="1"&amp;gt;1 - 1&amp;lt;/Label&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Label Grid.Column="0" Grid.Row="2"&amp;gt;0 - 2&amp;lt;/Label&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Label Grid.Column="1" Grid.Row="2"&amp;gt;1 - 2&amp;lt;/Label&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Grid&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;lt;/Window&amp;gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Hier is iets vreemds aan de hand. Als je naar de help gaat van Label, zie je daar tussen de properties geen property Grid.Row en Grid.Column staan. Dat is op zich te begrijpen: een label hoeft niets te weten van een grid en al helemaal niet van de plaatsing in dat grid. Als dat wel zo zou zijn, zouden alle UIElements en afgeleiden deze properties moeten hebben. En de properties om de plaats in de DockPanel te kunnen zetten, en ook voor.. nou ja, je snapt het al: de code zou absoluut ondoorzichtig worden.&lt;/P&gt;
&lt;P&gt;Nee, in plaats daarvan is Row en Column een DependencyProperty op de Grid class. Dit verklaart voor een deel de syntax: aangezien DependencyProperties static zijn kunnen we ze op deze manier aanroepen: Grid.Row="0" &lt;/P&gt;
&lt;P&gt;Dit zijn de zogenaamde Attached Dependency Properties. Het zijn dependencyproperties die aan een andere class ge-attached worden, zodat het lijkt dat ze bij die andere class horen. Op die manier kan de container, in ons geval de Grid, invloed uitoefenen op de plaatsing van de labels.&lt;/P&gt;
&lt;P&gt;Laten we dat zelf eens maken. Stel je voor dat je een listbox wilt hebben waarin je bepaalde regels of items anders wilt weergeven dan de rest. Denk aan dit:&lt;/P&gt;
&lt;P&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=300 alt="Screen dump " src="/blogs/dvroegop/210508screenshot.jpg" width=300 border=0&gt; &lt;/P&gt;
&lt;P&gt;Regel 1 en regel 3 in onze listbox zijn normaal, regel 2 daarentegen is cursief en vet.&lt;/P&gt;
&lt;P&gt;De XAML code ziet er als volgt uit:&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;P&gt;&amp;lt;Window x:Class="WpfApplication2.Window1" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;/A&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xmlns:detrio="clr-namespace:WpfApplication2" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Title="Window1" Height="300" Width="300"&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Grid&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;detrio:MyListBox x:Name="myListbox"&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Label&amp;gt;Regel 1&amp;lt;/Label&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Label detrio:MyListBox.IsEmphasized="true"&amp;gt;Regel 2&amp;lt;/Label&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Label&amp;gt;Regel 3&amp;lt;/Label&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/detrio:MyListBox&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Grid&amp;gt; &lt;BR&gt;&amp;lt;/Window&amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;We voegen een extra namespace toe: detrio (in clr-namespace:WpfApplication2, oftewel deze applicatie). Vervolgens heb ik mijn eigen listbox gedefinieerd (detrio:MyListBox) en daarin een aantal labels geplaatst. We geven hem een naam (x:name="myListbox"), wat niet nodig is voor de XAML maar wel als je er bij code bij wilt komen. Een van de labels, de tweede, heeft de detrio:MyListBox.IsEmphasized="true" meegekregen, wat er toe leidt dat het scherm er uit ziet zoals in bovenstaande screenshot.&lt;/P&gt;
&lt;P&gt;We gaan de source van detrio:MyListBox eens bekijken en analyseren.&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 10&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;MyListBox&lt;/SPAN&gt; : &lt;SPAN style="COLOR: #2b91af"&gt;ListBox&lt;/SPAN&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;We maken een nieuwe class die we afleiden van ListBox (let op: gebruik System.Windows.Controls.ListBox en niet System.Windows.Forms.ListBox: die laatste is immers de oude winforms listbox). Niet spannend tot nu toe. De ListBox die voor ons als baseclass dient, is onderdeel van een classHierarchy: &lt;/P&gt;
&lt;P&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=187 alt="Class Hierarchy van ListBox" src="/blogs/dvroegop/210508classhierarchie.jpg" width=389 border=0&gt; &lt;/P&gt;
&lt;P&gt;Zoals je kunt zien is de ListBox afgeleid van (via andere classes) DependencyObject, wat ik voorheen noemde als vereiste. Nu is het bij een Attached Property niet echt nodig dat er in de inheritance tree een DependencyObject zit, maar dat leg ik zo uit. Kwaad kan het in ieder geval niet.&lt;/P&gt;
&lt;P&gt;Het wordt tijd voor onze nieuwe property:&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 12&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;readonly&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;DependencyProperty&lt;/SPAN&gt; IsEmphasizedProperty = &lt;SPAN style="COLOR: #2b91af"&gt;DependencyProperty&lt;/SPAN&gt;.RegisterAttached(&lt;SPAN style="COLOR: #a31515"&gt;"IsEmphasized"&lt;/SPAN&gt;, &lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 13&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt;), &lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 14&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;MyListBox&lt;/SPAN&gt;), &lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 15&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;PropertyMetadata&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;, PropertyChanged));&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Deze code hebben we al gezien, met een klein verschil: we roepen nu RegisterAttached aan in plaats van Register. Klein verschil, maar met dramatische gevolgen. &lt;/P&gt;
&lt;P&gt;Als je namelijk een Attached Property maakt, hoef je geen standaard property aan te maken (met in ons geval de naam bool IsEmphasized). Dat mag wel, maar hij zal waarschijnlijk nooit gebruikt worden. Wat je echter &lt;EM&gt;wel&lt;/EM&gt; moet doen bij een attached property, is twee methods maken die de waardes zetten of ophalen. In plaats van onze normale property dus. Deze zien er als volgt uit:&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 17&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; SetIsEmphasized(&lt;SPAN style="COLOR: #2b91af"&gt;UIElement&lt;/SPAN&gt; element, &lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt; value)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 18&lt;/SPAN&gt; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 19&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; element.SetValue(IsEmphasizedProperty, value);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 20&lt;/SPAN&gt; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 21&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 22&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt; GetIsEmphasized(&lt;SPAN style="COLOR: #2b91af"&gt;UIElement&lt;/SPAN&gt; element)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 23&lt;/SPAN&gt; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 24&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt;)element.GetValue(IsEmphasizedProperty);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 25&lt;/SPAN&gt; }&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Twee methods, een om te zetten en een om uit te lezen. Ze moeten deze namen hebben: Getxxx en Setxxx. Het type van de eerste parameter (bij ons UIElement) mag je zelf bedenken. Hier zeg je dus eigenlijk welke classes de nieuwe property kunnen krijgen (zoals in ons geval de labels). Ik heb het wat breder gehouden en voor een UIElement gekozen. De tweede parameter bij de Setxxx en de returnvalue bij Getxxx is uiteraard gelijk als wat je bij de RegisterAttached hebt gebruikt.&lt;/P&gt;
&lt;P&gt;Daarna rest alleen de implementatie: je roept SetValue aan op het element, en geeft hem onze DependencyProperty mee en de waarde (of bij de getter: je leest deze uit). Met andere woorden: een DependencyObject kan properties krijgen vanuit een andere class. Dat is precies wat hier gebeurt: een UIElement krijgt een link naar onze IsEmphasizedProperty.&lt;/P&gt;
&lt;P&gt;In de RegisterAttached method geven we als callback mee de PropertyChanged method. Laten we die eens bekijken:&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 27&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; PropertyChanged(&lt;SPAN style="COLOR: #2b91af"&gt;DependencyObject&lt;/SPAN&gt; obj, &lt;SPAN style="COLOR: #2b91af"&gt;DependencyPropertyChangedEventArgs&lt;/SPAN&gt; args)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 28&lt;/SPAN&gt; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 29&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt;(obj &lt;SPAN style="COLOR: blue"&gt;is&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Label&lt;/SPAN&gt;)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 30&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SetLabelEmphasized(obj &lt;SPAN style="COLOR: blue"&gt;as&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Label&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 31&lt;/SPAN&gt; }&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;In dit geval is obj meestal van het type Label. Immers, wij zetten alleen maar labels in onze listbox (technisch gezien zouden het allemaal type UIElement kunnen zijn, maar die gebruiken we niet in onze XAML code). Als het inderdaad een Label is, roepen we de static method SetLabelEmphasized aan en geven hem de label mee waarvan de attached property is gewijzigd. Let op: formeel is dit niet waar: de attached property hoort niet bij de label, immers: het is een onderdeel van MyListBox. Toch lijkt het wel zo te zijn, vandaar dat ik het ook zo benoem: de attached property van de label is gewijzigd. Jij weet nu beter: de property van MyListBox die gekoppeld is aan de label is gewijzigd, maar dat is zo'n mond vol....&lt;/P&gt;
&lt;P&gt;De volgende code is erg eenvoudig:&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 33&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; SetLabelEmphasized(&lt;SPAN style="COLOR: #2b91af"&gt;Label&lt;/SPAN&gt; labelToSet)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 34&lt;/SPAN&gt; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 35&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ((&lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt;)(labelToSet.GetValue(&lt;SPAN style="COLOR: #2b91af"&gt;MyListBox&lt;/SPAN&gt;.IsEmphasizedProperty)))&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 36&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 37&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; labelToSet.FontStyle = &lt;SPAN style="COLOR: #2b91af"&gt;FontStyles&lt;/SPAN&gt;.Italic;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 38&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; labelToSet.FontWeight = &lt;SPAN style="COLOR: #2b91af"&gt;FontWeights&lt;/SPAN&gt;.ExtraBold;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 39&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 40&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;else&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 41&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 42&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; labelToSet.FontStyle = &lt;SPAN style="COLOR: #2b91af"&gt;FontStyles&lt;/SPAN&gt;.Normal;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 43&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; labelToSet.FontWeight = &lt;SPAN style="COLOR: #2b91af"&gt;FontWeights&lt;/SPAN&gt;.Normal;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 44&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 45&lt;/SPAN&gt; }&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Deze method (static, uiteraard) krijgt een label en daarin zetten we wat font attributen. Een kind kan de was doen.&lt;/P&gt;
&lt;P&gt;Als je dit vanuit de code wilt, werkt het iets anders. Op het eerste gezicht is dat niet zo duidelijk waarom dat zo moet, maar nu je weet hoe de attached properties werken is het vrij voor de hand liggend:&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 22&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; Window1()&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 23&lt;/SPAN&gt; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 24&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; InitializeComponent();&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 25&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;Label&lt;/SPAN&gt; label4 = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Label&lt;/SPAN&gt;();&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 26&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; label4.Content = &lt;SPAN style="COLOR: #a31515"&gt;"Regel 4"&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 27&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; label4.SetValue(&lt;SPAN style="COLOR: #2b91af"&gt;MyListBox&lt;/SPAN&gt;.IsEmphasizedProperty, &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 28&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; myListbox.Items.Add(label4);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 29&lt;/SPAN&gt; }&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;En dat is alles! Deze class kan, in XAML of in code, een aantal labels als content krijgen en die labels kunnen zelf aangeven of ze emphasized weergegeven worden of niet! Pure magie, als je het mij vraagt....&lt;/P&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=844" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/05/21/844.aspx</link>
      <author>dvroegop</author>
      <pubDate>Wed, 21 May 2008 15:18:00 GMT</pubDate>
    </item>
    <item>
      <title>May 20th Links: ASP.NET, ASP.NET AJAX, .NET, Visual Studio, Silverlight, WPF</title>
      <description>&lt;font face="arial" size="2"&gt;   &lt;p&gt;Apologies for the sparseness of my posting the last few weeks - work and life have been busy here lately.&amp;#160; Below is a new post in my &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/04/28/april-28th-links-asp-net-asp-net-ajax-asp-net-mvc-silverlight.aspx" target="_blank"&gt;link-listing series&lt;/a&gt; to help kick things up a little.&amp;#160; Also check out my &lt;a href="http://weblogs.asp.net/scottgu/pages/ASP.NET-2.0-Tips_2C00_-Tricks_2C00_-Recipes-and-Gotchas.aspx" target="_blank"&gt;ASP.NET Tips, Tricks and Tutorials page&lt;/a&gt; and &lt;a href="http://weblogs.asp.net/scottgu/pages/silverlight-posts.aspx" target="_blank"&gt;Silverlight Tutorials page&lt;/a&gt; for links to popular articles I've done myself in the past.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;ASP.NET&lt;/u&gt;&lt;/h3&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://mattberseth.com/blog/2008/05/bulk_inserting_data_with_the_l.html" target="_blank"&gt;Bulk Inserting Data with the ListView Control&lt;/a&gt;: Matt Berseth continues his awesome posts with one that shows how to handle bulk-editing of data using the ASP.NET ListView control in .NET 3.5.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://mattberseth.com/blog/2008/04/masterdetail_with_the_gridview.html" target="_blank"&gt;Master-Detail with the GridView, DetailsView, and ModalPopup Controls&lt;/a&gt;: Another great post from Matt that describes how to cleanly handle a common data entry scenario.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://www.thebrainparasite.com/post/Creating-great-thumbnails-in-ASPNET.aspx" target="_blank"&gt;Creating Great Thumbnail Images in ASP.NET&lt;/a&gt;: A really nice blog post by a different Matt that details an approach that generates high quality (and small) thumbnail images.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://aspnet.4guysfromrolla.com/articles/051408-1.aspx" target="_blank"&gt;Warning the User when Caps-Lock is on&lt;/a&gt;: Scott Mitchell has a nice article that describes how to automatically detect and warn users in login pages when the caps-lock button is on.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://blogs.msdn.com/tess/archive/2008/05/14/asp-net-performance-issue-large-number-of-application-restarts-due-to-virus-scanning.aspx" target="_blank"&gt;ASP.NET Perf Issue: Large numbers of application-restarts due to virus scanners&lt;/a&gt;: Tess Ferrandez has a great post that details a debug session to determine why an ASP.NET application was restarting frequently (causing performance slowdowns).&amp;#160; The issue was a virus scanner that was causing files to be constantly updated.&amp;#160; Make sure to check out the logging code you can add to your application to identify restart causes like this.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;h3&gt;&lt;u&gt;ASP.NET AJAX&lt;/u&gt;&lt;/h3&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://mattberseth.com/blog/2008/05/aspnet_ajax_progress_bar_contr.html" target="_blank"&gt;ASP.NET AJAX Progress Bar Control&lt;/a&gt;: Matt Berseth has another great article that describes his new ASP.NET AJAX Progress Bar control.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://msmvps.com/blogs/omar/archive/2008/05/10/fast-asp-net-web-page-loading-by-downloading-multiple-javascripts-in-batch.aspx" target="_blank"&gt;Faster Page Loading By Combining Multiple JavaScript files in Batch&lt;/a&gt;: Omar Al Zabir (founder of &lt;a href="http://www.pageflakes.com" target="_blank"&gt;PageFlakes.com&lt;/a&gt; and author of the great &lt;a href="http://www.amazon.com/gp/product/0596510500/102-8343841-3890548?ie=UTF8&amp;amp;tag=scoblo04-20&amp;amp;linkCode=xm2&amp;amp;camp=1789&amp;amp;creativeASIN=0596510500" target="_blank"&gt;Building a Web 2.0 Portal with ASP.NET 3.5&lt;/a&gt; book) has a good article that describes the performance benefit of merging multiple JavaScript file downloads.&amp;#160; Note that &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/05/12/visual-studio-2008-and-net-framework-3-5-service-pack-1-beta.aspx" target="_blank"&gt;.NET 3.5 SP1&lt;/a&gt; will include a new script combiner feature that helps make doing this even easier.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://pietschsoft.com/post/2008/05/ASPNET_Create_AJAX_Server_Controls_using_the_ScriptControl_base_class.aspx" target="_blank"&gt;Create ASP.NET AJAX Server Controls using the ScriptControl base class&lt;/a&gt;: Chris Pietschmann has a nice article that talks about how to build new ASP.NET AJAX server controls by deriving from the built-in ScriptControl base class.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://encosia.com/2008/05/16/inline-edit-box-on-codeplex-and-new-postback-ritalin-beta/" target="_blank"&gt;Inline Edit Box and Postback Ritalin Beta&lt;/a&gt;: Dave Ward and Mike Davis have created a new CodePlex project for their popular Inline Edit Box and PostBack Ritalin ASP.NET AJAX controls.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;h3&gt;&lt;u&gt;.NET&lt;/u&gt;&lt;/h3&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/" target="_blank"&gt;7 Ways to Simplify your code with LINQ&lt;/a&gt;: Igor Ostrovsky has a great blog post that talks about new code techniques you can use to improve your code using .NET 3.5 and the new language and LINQ features in it.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://blogs.msdn.com/mitsu/archive/2008/04/02/visual-linq-query-builder-for-linq-to-sql-vlinq.aspx" target="_blank"&gt;Visual LINQ Query Builder for LINQ to SQL&lt;/a&gt;: Mitsu Furuta has created a cool Visual Studio designer that allows you to graphically construct LINQ to SQL queries.&amp;#160; Also make sure to download download the latest &lt;a href="http://www.linqpad.net/" target="_blank"&gt;LINQPad&lt;/a&gt; utility - which is invaluable for learning LINQ and trying out LINQ queries.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://www.pluralsight.com/blogs/aaron/archive/2008/05/13/50934.aspx" target="_blank"&gt;DataContracts without Attributes (POCO support):&lt;/a&gt; Aaron Skonnard has a good post that talks about a nice usability change with .NET 3.5 SP1 that allows you to serialize POCO (plain old objects) using the WCF serializers.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://www.thejoyofcode.com/Introducing_Ukadc_Diagnostics.aspx" target="_blank"&gt;Ukadc.Diagnostics&lt;/a&gt;: Josh Twist pointed me at a new CodePlex project he is working on that extends the System.Diagnostics features in .NET to include richer logging features (SQL trace support, email support, etc).&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;h3&gt;&lt;u&gt;Visual Studio&lt;/u&gt;&lt;/h3&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://www.dev102.com/2008/05/06/11-more-visual-studio-shortcuts-you-should-know/" target="_blank"&gt;11 More VS Short Cuts you Should Know&lt;/a&gt;: A great post that talks about a bunch of useful shortcuts to print out and remember when using Visual Studio.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://blogs.msdn.com/saraford/archive/2008/05/20/did-you-know-you-can-show-extension-methods-in-the-object-browser-219.aspx" target="_blank"&gt;Did you know you can show extension methods in the object browser?:&lt;/a&gt; Sara Ford continues her excellent &amp;quot;Did you know&amp;quot; series.&amp;#160; I confess I didn't know this one.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;h3&gt;&lt;u&gt;Silverlight&lt;/u&gt;&lt;/h3&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/05/15/10402.aspx" target="_blank"&gt;50 New Silverlight 2 Beta 1 Screencasts:&lt;/a&gt; Mike Taulty and Mike Ormond have put together 50 nice tutorial screen-casts that cover Silverlight 2 - all in their &amp;quot;spare time&amp;quot;.&amp;#160; Wow.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://www.nikhilk.net/Entry.aspx?id=195" target="_blank"&gt;AutoComplete for Silverlight TextBoxes&lt;/a&gt;: Nikhil Kothari has a nice blog post that demonstrates how he built an auto-complete behavior control for Silverlight.&amp;#160; &lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://blogs.msdn.com/swiss_dpe_team/archive/2008/05/09/scrolling-through-large-resultset-with-silverlight-2-beta1-and-linq-to-sql.aspx" target="_blank"&gt;Scrolling through Large Resultsets with Silverlight 2 and LINQ to SQL&lt;/a&gt;: The Swiss MSDN team has a nice blog post that demonstrates how to scroll through large resultsets using the Silverlight DataGrid and LINQ to SQL.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://blogs.msdn.com/delay/archive/2008/05/04/ivalueconverter-the-swiss-army-knife-of-bindings-propertyviewer-sample-is-a-wpf-silverlight-visualization-and-debugging-aid.aspx" target="_blank"&gt;IValueConverter: The Swiss Army Knife of Bindings&lt;/a&gt;: David Anson has a useful blog post and sample that demonstrates how to use the IValueConverter feature in Silverlight and WPF to support richer bindings against complex objects.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://petermcg.wordpress.com/2008/05/18/silverlight-20-pie-chart/" target="_blank"&gt;Silverlight 2 Pie Chart:&lt;/a&gt; Peter McGrattan has posted a nice control and article that demonstrates how to use a new Silverlight charting control he has written.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;h3&gt;&lt;u&gt;WPF&lt;/u&gt;&lt;/h3&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://channel9.msdn.com/Showforum.aspx?forumid=14&amp;amp;tagid=329" target="_blank"&gt;WPF week on Channel9&lt;/a&gt;: Watch 6 great videos on Channel9.&amp;#160; Each one includes interviews and demos with members of the WPF team talking about some of the awesome work that went into WPF 3.5 SP1 (read my blog post &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/05/12/visual-studio-2008-and-net-framework-3-5-service-pack-1-beta.aspx" target="_blank"&gt;here&lt;/a&gt; for a summary of some of it).&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://windowsclient.net/wpf/white-papers/wpf-app-quality-guide.aspx" target="_blank"&gt;WPF Testing and Application Quality Guide&lt;/a&gt;: Check out the 0.2 release of a free online book being developed by Microsoft that covers how to test WPF applications.&amp;#160; Definitely worth book-marking if you are doing WPF development.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://www.codeproject.com/KB/WPF/MovingTowardWpfBinding.aspx" target="_blank"&gt;Moving Toward WPF Data Binding One Step at a Time&lt;/a&gt;: Josh Smith has a great article on CodeProject.com that explains WPF data binding and walksthrough how to use it.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;p&gt;&lt;a href="http://blogs.msdn.com/llobo/archive/2008/05/19/wpf-3-5-sp1-feature-stringformat.aspx" target="_blank"&gt;WPF 3.5 SP1 StringFormat&lt;/a&gt;: Lester has a nice post that describes how to use the new StringFormat feature in WPF 3.5 SP1.&amp;#160; This makes it much easier to handle formatting of databound values.&lt;/p&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;Hope this helps,&lt;/p&gt;    &lt;p&gt;Scott&lt;/p&gt; &lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6206432" width="1" height="1"&gt;</description>
      <link>http://weblogs.asp.net/scottgu/archive/2008/05/20/may-20th-links-asp-net-asp-net-ajax-net-visual-studio-silverlight-wpf.aspx</link>
      <author>ScottGu</author>
      <pubDate>Wed, 21 May 2008 07:02:44 GMT</pubDate>
    </item>
    <item>
      <title>29 mei: Powershell MVP Marc van Orsouw over... Powershell!</title>
      <description>&lt;p&gt;&lt;a href="http://www.oosterkamp.nl/"&gt;&lt;img style="margin: 0px 10px 10px 0px" alt="Oosterkamp" src="http://www.dotned.nl/sponsors/Logo_Oosterkamp.gif" align="left" border="0" /&gt;&lt;/a&gt;Veel mensen denken bij Powershell aan ingewikkelde scripts voor beheerders. Nu is het zo dat Powershell daar inderdaad veel gebruikt wordt. Maar wist je dat ook ontwikkelaars enorm veel kunnen doen met Powershell? Je kunt vanuit je scripts gebruik maken van het .net framework om zo de meest fantastische (en tijdsbesparende!) dingen te doen, dingen die je eigenlijk alleen vanuit een full-blown .net applicatie zou kunnen. En dus niet vanuit een script. En nu dus wel, met behulp van Powershell!&lt;/p&gt;  &lt;p&gt;Wist je dit niet? Kom dan langs op 29 mei in Doorn voor een sessie over Powershell!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;De spreker van deze avond is Marc van Orsouw. &lt;a title="MVP Site Marc" href="https://mvp.support.microsoft.com/profile=59DD61DD-41A3-4C93-AAB5-FB2504EF003B" target="_blank"&gt;&lt;img style="margin: 10px" alt="MVP" src="http://www.dotned.nl/sponsors/logo_mvp_80.jpg" align="right" /&gt;&lt;/a&gt;Hij wordt beschouwd als een van de grootste experts op het gebied van Powershell. Hij was de eerste MVP op dit gebied (dit jaar zijn er een paar bij gekomen zodat er nu wereldwijd 12 Powershell MVP's zijn). Hij wordt regelmatig door het Powershell team gevraagd om zijn mening over bepaalde features te geven. Je ziet het: ook als je al expert ben op het gebied van Powershell is dit een avond om niet te missen: als er iemand is die vragen kan beantwoorden op dit gebied is Marc het wel. &lt;/p&gt;  &lt;p&gt;Voor de voorbereiding voor deze avond kun je je alvast inlezen op Marcs site op &lt;a href="http://www.thepowershellguy.com"&gt;http://www.thepowershellguy.com&lt;/a&gt; Maar het is beter om het van de man zelf te horen!&lt;/p&gt;  &lt;p&gt;We zien je graag op de 29e te Doorn!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=843" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/05/20/843.aspx</link>
      <author>dvroegop</author>
      <pubDate>Tue, 20 May 2008 09:11:03 GMT</pubDate>
    </item>
    <item>
      <title>29 mei: Powershell MVP Marc van Orsouw over... Powershell!</title>
      <description>&lt;P&gt;&lt;A href="http://www.oosterkamp.nl/"&gt;&lt;IMG style="MARGIN: 0px 10px 10px 0px" alt=Oosterkamp src="/sponsors/Logo_Oosterkamp.gif" align=left border=0&gt;&lt;/A&gt;Veel mensen denken bij Powershell aan ingewikkelde scripts voor beheerders. Nu is het zo dat Powershell daar inderdaad veel gebruikt wordt. Maar wist je dat ook ontwikkelaars enorm veel kunnen doen met Powershell? Je kunt vanuit je scripts gebruik maken van het .net framework om zo de meest fantastische (en tijdsbesparende!) dingen te doen, dingen die je eigenlijk alleen vanuit een full-blown .net applicatie zou kunnen. En dus niet vanuit een script. En nu dus wel, met behulp van Powershell!&lt;/P&gt;
&lt;P&gt;Wist je dit niet? Kom dan langs op 29 mei in Doorn voor een sessie over Powershell!&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;De spreker van deze avond is Marc van Orsouw. &lt;A title="MVP Site Marc" href="https://mvp.support.microsoft.com/profile=59DD61DD-41A3-4C93-AAB5-FB2504EF003B" target=_blank&gt;&lt;IMG style="MARGIN: 10px" alt=MVP src="/sponsors/logo_mvp_80.jpg" align=right&gt;&lt;/A&gt;Hij wordt beschouwd als een van de grootste experts op het gebied van Powershell. Hij was de eerste MVP op dit gebied (dit jaar zijn er een paar bij gekomen zodat er nu wereldwijd 12 Powershell MVP's zijn). Hij wordt regelmatig door het Powershell team gevraagd om zijn mening over bepaalde features te geven. Je ziet het: ook als je al expert ben op het gebied van Powershell is dit een avond om niet te missen: als er iemand is die vragen kan beantwoorden op dit gebied is Marc het wel. &lt;/P&gt;
&lt;P&gt;Voor de voorbereiding voor deze avond kun je je alvast inlezen op Marcs site op &lt;A href="http://www.thepowershellguy.com"&gt;http://www.thepowershellguy.com&lt;/A&gt; Maar het is beter om het van de man zelf te horen!&lt;/P&gt;
&lt;P&gt;Je kunt je inschrijven op &lt;A HREF="/meetings/default.aspx"&gt;http://www.dotned.nl/meetings/default.aspx&lt;/A&gt; Uiteraard is zoals altijd het bezoek aan onze avonden, inclusief wat eten en te drinken, gratis.&lt;/P&gt;
&lt;P&gt;We zien je graag op de 29e te Doorn! &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=843" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/05/20/843.aspx</link>
      <author>dvroegop</author>
      <pubDate>Tue, 20 May 2008 09:11:00 GMT</pubDate>
    </item>
    <item>
      <title>VB for C# programmers - a little gotcha</title>
      <description>&lt;P&gt;The debate whether to use C# or Visual Basic .NET is not uncommon for most .NET developers. Certainly, one has a distinct preference, but the general idea is that you can do in C# what you can do in VB and vice versa, because the .NET Framework is our common denominator. No, I don't mean XML literals versus automatic properties. It's the end result that counts. &lt;/P&gt;
&lt;P&gt;So I'm currently involved in some VB programming when we stumbled upon something peculiar. Here's a simplified form of what my predecessor, also preferring C#,&amp;nbsp;tried to do:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;Public&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; &lt;SPAN style="COLOR: blue"&gt;Class&lt;/SPAN&gt; PropertyClass&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Private&lt;/SPAN&gt; m_name &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt; = &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;.Empty&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Property&lt;/SPAN&gt; Name() &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Get&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;If&lt;/SPAN&gt; m_name = &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;.Empty &lt;SPAN style="COLOR: blue"&gt;Then&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Name = &lt;SPAN style="COLOR: #a31515"&gt;"Unknown"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;If&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Return&lt;/SPAN&gt; m_name&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Get&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Set&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; value &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;m_name = value&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Set&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Property&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;End&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; &lt;SPAN style="COLOR: blue"&gt;Class&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Simple enough, and here's the C# version:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;PropertyClass&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; m_name = &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;.Empty;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; Name&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (m_name == &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;.Empty) Name = &lt;SPAN style="COLOR: #a31515"&gt;"Unknown"&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; m_name;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt; { m_name = &lt;SPAN style="COLOR: blue"&gt;value&lt;/SPAN&gt;; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;
&lt;P&gt;What do you expect to happen here, using the C# version?&lt;/P&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;PropertyClass&lt;/SPAN&gt; pc = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;PropertyClass&lt;/SPAN&gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.WriteLine(pc.Name);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;
&lt;P&gt;The output would show &lt;FONT face="Courier New"&gt;Unknown&lt;/FONT&gt; and that's expected, right?&lt;/P&gt;
&lt;P&gt;And what would it be using the VB version?&lt;/P&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; pc &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt; PropertyClass&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Console.Write(pc.Name)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;
&lt;P&gt;Well, surpsingly, at least to me, the output is... nothing! Yes, you try it. If we look at the compiler output. Here's what the C# compiler made of it:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face="Courier New"&gt;L_0016: brtrue.s L_0024&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0018: ldarg.0 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0019: ldstr "Unknown"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_001e: call instance void CSharpProperty.PropertyClass::set_Name(string)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0023: nop &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0024: ldarg.0&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;/FONT&gt;&amp;nbsp;&lt;BR&gt;&lt;/P&gt;&lt;/P&gt;
&lt;P&gt;
&lt;P&gt;I'm no expert in reading IL, but clearly you see a call to the set_Name method.&amp;nbsp;For VB, the compiler turns it into:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0015: stloc.1 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0016: ldloc.1 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0017: brfalse.s L_001f&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0019: ldstr "Unknown"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_001e: stloc.0 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_001f: nop &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0020: ldarg.0&lt;/FONT&gt; &lt;/P&gt;
&lt;P&gt;It's completely gone. The compiler simply removed the &lt;/P&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Name = &lt;SPAN style="COLOR: #a31515"&gt;"Unknown"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;
&lt;P&gt;It appears there's more difference between VB.NET and C# than I thought. I certainly hope to return to some C# code soon.&lt;/P&gt;&lt;/P&gt;&lt;img src ="http://todotnet.com/aggbug/11355.aspx" width = "1" height = "1" /&gt;</description>
      <link>http://todotnet.com/archive/2008/05/15/11355.aspx</link>
      <author>Sander Gerz</author>
      <pubDate>Thu, 15 May 2008 13:59:00 GMT</pubDate>
    </item>
    <item>
      <title>Visual Studio 2008 SP1 / .net 3.5 SP1 betas beschikbaar</title>
      <description>&lt;p&gt;Heet van de naald: de langverwachte Service Packs zijn bijna af, de beta's kunnen worden gedownload van de site van Microsoft. Ik heb hem geinstalleerd en ben nu aan het kijken waar ik allemaal tegen aan ga lopen. De downloads vind je hier onder:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Visual Studio 2008 SP1&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://download.microsoft.com/download/7/3/8/7382EA08-4DD6-4134-9B92-8585A5B07973/VS90sp1-KB945140-ENU.exe"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=cf99c752-1391-4bc3-babc-86bc0b9e8e5a&amp;amp;DisplayLang=en&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;.NET Framework 3.5 SP1&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://download.microsoft.com/download/8/f/c/8fc1fe13-55de-4bf5-b43e-375daf01452e/dotNetFx35setup.exe"&gt;http://download.microsoft.com/download/8/f/c/8fc1fe13-55de-4bf5-b43e-375daf01452e/dotNetFx35setup.exe&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Visual Studio Express 2008 met SP1&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://download.microsoft.com/download/F/E/7/FE754BA4-140B-413C-933F-8D35FB150F12/vbsetup.exe"&gt;http://download.microsoft.com/download/F/E/7/FE754BA4-140B-413C-933F-8D35FB150F12/vbsetup.exe&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://download.microsoft.com/download/F/E/7/FE754BA4-140B-413C-933F-8D35FB150F12/vcsetup.exe"&gt;http://download.microsoft.com/download/F/E/7/FE754BA4-140B-413C-933F-8D35FB150F12/vcsetup.exe&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://download.microsoft.com/download/F/E/7/FE754BA4-140B-413C-933F-8D35FB150F12/vcssetup.exe"&gt;http://download.microsoft.com/download/F/E/7/FE754BA4-140B-413C-933F-8D35FB150F12/vcssetup.exe&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://download.microsoft.com/download/F/E/7/FE754BA4-140B-413C-933F-8D35FB150F12/vnssetup.exe"&gt;http://download.microsoft.com/download/F/E/7/FE754BA4-140B-413C-933F-8D35FB150F12/vnssetup.exe&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Team Foundation Server 2008 SP1&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://download.microsoft.com/download/a/e/2/ae2eb0ff-e687-4221-9c3e-9165a942bc1c/TFS90sp1-KB949786.exe"&gt;http://download.microsoft.com/download/a/e/2/ae2eb0ff-e687-4221-9c3e-9165a942bc1c/TFS90sp1-KB949786.exe&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Je weet wat ze zeggen: don't install Beta software on machines you care about. Het risico bestaat immers dat je de boel dusdanig beschadigt dat een complete herinstallatie de enige optie is om de boel aan de praat te krijgen. Tot nu toe werkt het bij mij wel aardig, maar ik moet er nog verder mee stoeien.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Ik hou je op de hoogte!&lt;/p&gt;&lt;img src="http://www.dotned.nl/aggbug.aspx?PostID=836" width="1" height="1"&gt;</description>
      <link>http://www.dotned.nl/blogs/dennis_blog/archive/2008/05/13/836.aspx</link>
      <author>dvroegop</author>
      <pubDate>Tue, 13 May 2008 07:57:53 GMT</pubDate>
    </item>
    <item>
      <title>Visual Studio 2008 and .NET Framework 3.5 Service Pack 1 Beta</title>
      <description>&lt;font face="arial" size="2"&gt;   &lt;p&gt;Earlier today we shipped a public beta of our upcoming .NET 3.5 SP1 and VS 2008 SP1 releases.&amp;#160; These servicing updates provide a roll-up of bug fixes and performance improvements for issues reported since we released the products last November.&amp;#160; They also contain a number of feature additions and enhancements that make building .NET applications better (see below for details on some of them).&lt;/p&gt;    &lt;p&gt;We plan to ship the final release of both .NET 3.5 SP1 and VS 2008 SP1 this summer as free updates.&amp;#160; You can download and install the beta &lt;a href="http://msdn.microsoft.com/en-us/vstudio/products/cc533447.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Important: SP1 Beta Installation Notes&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;The SP1 beta released today is still in beta form - so you should be careful about installing it on critical machines.&amp;#160; There are a few important SP1 Beta installation notes to be aware of:&lt;/p&gt;    &lt;p&gt;1) If you are running Windows Vista you should make sure you have Vista SP1 installed before trying to install .NET 3.5 SP1 Beta.&amp;#160; There are some setup issues with .NET 3.5 SP1 when running on the Vista RTM release.&amp;#160; These issues will be fixed for the final .NET 3.5 SP1 release - until then please make sure to have Vista SP1 installed &lt;em&gt;before&lt;/em&gt; trying to install .NET 3.5 SP1 beta.&lt;/p&gt;    &lt;p&gt;2) If you have installed the VS 2008 Tools for Silverlight 2 Beta1 package on your machine, you must uninstall it - as well as uninstall the KB949325 update for VS 2008 - &lt;em&gt;before &lt;/em&gt;installing VS 2008 SP1 Beta (otherwise you will get a setup failure).&amp;#160; You can find more details on the exact steps to follow &lt;a href="http://blogs.msdn.com/webdevtools/archive/2008/05/12/error-installing-visual-studio-2008-sp1-beta-and-silverlight-tools-beta-1.aspx" target="_blank"&gt;here&lt;/a&gt; (note: you must uninstall two separate things).&amp;#160; It is fine to have the Silverlight 2 runtime on your machine with .NET 3.5 SP1 - the component that needs to be uninstalled is the VS 2008 Tools for Silverlight 2 package.&amp;#160; We will release an updated VS 2008 Tools for Silverlight package in a few weeks that works with the VS 2008 SP1 beta.&lt;/p&gt;    &lt;p&gt;3) There is a change in behavior in the .NET 3.5 SP1 beta that causes a problem with the shipping versions of Expression Blend.&amp;#160; This behavior change is being reverted for the final .NET 3.5 SP1 release, at which time all versions of Blend will have no problems running.&amp;#160; Until then, you need to download &lt;a href="http://blogs.msdn.com/expression/archive/2008/04/18/vs2008sp1.aspx" target="_blank"&gt;this recently updated version of Blend 2.5&lt;/a&gt; to work around this issue.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Improvements for Web Development&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;.NET 3.5 SP1 and VS 2008 SP1 contain a bunch of feature improvements targeted at web application development.&amp;#160; &lt;/p&gt;    &lt;p&gt;The VS Web Dev Tools team has more details (including specific bug fix details) on some of the VS specific work &lt;a href="http://blogs.msdn.com/webdevtools/archive/2008/05/12/visual-studio-2008-sp1-beta.aspx" target="_blank"&gt;here&lt;/a&gt;.&amp;#160; Below are more details on some of the work in the web-space:&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;ASP.NET Data Scaffolding Support (ASP.NET Dynamic Data)&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;.NET 3.5 SP1 adds support for a rich ASP.NET data &amp;quot;scaffolding&amp;quot; framework that enables you to quickly build functional data-driven web application. With the ASP.NET Dynamic Data feature you can automatically build web UI (with full CRUD - create, read, update, delete - support) against a variety of data object models (including LINQ to SQL, LINQ to Entities, REST Services, and any other ORM or object model with a dynamic data provider).&lt;/p&gt;    &lt;p&gt;SP1 adds this new functionality to the existing GridView, ListView, DetailsView and FormView controls in ASP.NET, and enables smart validation and flexible data templating options.&amp;#160; It also delivers new smart filtering server controls, as well as adds support for automatically traversing primary-key/foreign-key relationships and displaying friendly foreign key names - all of which saves you from having to write a ton of code.&lt;/p&gt;    &lt;p&gt;You can learn more more about this feature from Scott Hanselman's videos and tutorials &lt;a href="http://www.asp.net/dynamicdata/" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;ASP.NET Routing Engine (System.Web.Routing)&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;.NET 3.5 SP1 includes a flexible new URL routing engine that allows you to map incoming URLs to route handlers.&amp;#160; It includes support for both parsing parameters from clean URLs (for example: /Products/Browse/Beverages), as well as support to dynamically calculate and generate new URLs from route registrations.&lt;/p&gt;    &lt;p&gt;This new routing engine is used by both ASP.NET Dynamic Data as well as the new ASP.NET MVC framework.&amp;#160; It will support both WebForms and MVC based requests.&amp;#160; &lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;ASP.NET AJAX Back/Forward Button History Support&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;.NET 3.5 SP1 adds new APIs to ASP.NET AJAX to allow you to better control the history list of a browser (enabling you to control the behavior of the back/forward button of the browser).&lt;/p&gt;    &lt;p&gt;You can learn more about this feature in the article &lt;a href="http://weblogs.asp.net/davidbarkol/archive/2007/12/28/asp-net-3-5-extensions-history-control-tip.aspx" target="_blank"&gt;here&lt;/a&gt; and the screencast &lt;a href="http://weblogs.asp.net/bleroy/archive/2008/01/04/screencast-how-to-enable-server-side-history-management-in-an-asp-net-ajax-application.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;ASP.NET AJAX Script Combining Support&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;.NET 3.5 SP1 introduces a new &amp;lt;CompositeScript&amp;gt; element on the &amp;lt;asp:ScriptManager&amp;gt; server control, which allows you to declaratively define multiple script references within it.&amp;#160; All the script references within the CompositeScript element are combined together on the server and served as a single script to the client, reducing the number of requests to the server and improving page load time for ASP.NET AJAX applications.&lt;/p&gt;    &lt;p&gt;The script combining feature supports both path based scripts and assembly resource based scripts, and dynamically serves up the combined scripts using the ScriptResources.axd handler.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Visual Studio 2008 Performance Improvements HTML Designer and HTML Source Editor&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;In February we released a &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/02/08/vs-2008-web-development-hot-fix-roll-up-available.aspx" target="_blank"&gt;HotFix roll-up&lt;/a&gt; that included a number of performance improvements and bug fixes for the VS 2008 Web Designer.&amp;#160; VS 2008 SP1 includes all of these fixes, as well as a number of additional performance improvements.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Visual Studio 2008 JavaScript Script Formatting and Code Preferences&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Visual Studio has for several releases supported rich source code formatting options for VB and C# (spacing, line breaks, brace positions, etc).&lt;/p&gt;    &lt;p&gt;VS 2008 SP1 adds richer source code formatting support for JavaScript as well (both inline &amp;lt;script&amp;gt; blocks and .js files).&amp;#160; You can now set your Javascript coding preferences using the Tools-&amp;gt;Options dialog:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step3.png" /&gt; &lt;/p&gt;    &lt;p&gt;These preferences will be automatically used as you type new Javascript code in the source editor.&amp;#160; You can also select existing code, right-click, and choose the &amp;quot;Format Selection&amp;quot; option to apply your style preferences to existing JavaScript code.&amp;#160; You can learn more about this new feature &lt;a href="http://blogs.msdn.com/webdevtools/archive/2008/05/12/introducing-jscript-formatting-in-vs-2008-sp1.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;    &lt;p&gt;&lt;u&gt;&lt;strong&gt;Better Visual Studio Javascript Intellisense for Multiple Javascript/AJAX Frameworks&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;VS 2008 includes &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/06/21/vs-2008-javascript-intellisense.aspx" target="_blank"&gt;Javascript Intellisense support&lt;/a&gt; in source view.&amp;#160; The intellisense support with the initial VS 2008 release works well with vanilla JavaScript as well as code written using the ASP.NET AJAX JavaScript type patterns.&amp;#160; JavaScript is a &lt;em&gt;very&lt;/em&gt; flexible language, though, and many JavaScript libraries use this flexibility to full advantage to implement their features - sometimes in ways that prevented the intellisense engine from providing completion support.&lt;/p&gt;    &lt;p&gt;VS 2008 SP1 adds much better intellisense support for popular Javascript libraries (we specifically did work to support JQuery, Prototype, Scriptaculous, ExtJS, and other popular libraries).&amp;#160; You will get better default intellisense when you reference these libraries.&amp;#160; We are also looking at whether we can maintain additional intellisense hint files that you can download to get even better intellisense and documentation support for some of the more popular libraries.&lt;/p&gt;    &lt;p&gt;Below is an example of using a JQuery startup function with the VS 2008 SP1 JavaScript intellisense engine:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step23.png" /&gt; &lt;/p&gt;    &lt;p&gt;Notice below how VS 2008 SP1 can now provide method argument completion even on chained JQuery selectors:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step24.png" /&gt; &lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Visual Studio Refactoring Support for WCF Services in ASP.NET Projects&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;VS 2008 SP1 adds better refactoring support for WCF services included within both ASP.NET Web Site and ASP.NET Web Application Projects. &lt;/p&gt;    &lt;p&gt;If you use the refactoring support to rename the class name, interface contract, or namespace of a WCF service, VS 2008 SP1 will now automatically fix up the web.config and SVC file references to it.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Visual Studio Support for Classic ASP Intellisense and Debugging &lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Previous versions of Visual Studio included support for intellisense and debugging within classic ASP (.asp) pages.&amp;#160; The file and project templates to create classic ASP pages/projects hasn't been in VS for a few releases, though, and with the initial VS 2008 we incorrectly assumed this meant that people weren't still using the classic ASP support.&amp;#160; We heard feedback after we shipped that indeed they were.&amp;#160; &lt;/p&gt;    &lt;p&gt;With VS 2008 SP1 this support for classic ASP intellisense and debugging is back:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step2.png" /&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;&lt;u&gt;&lt;strong&gt;Visual Web Developer Express Edition support for Class Library and Web Application Projects&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;    &lt;p&gt;The Visual Web Developer 2008 Express edition (which is free) is being updated in SP1 to add support for both class library and ASP.NET Web Application project types.&amp;#160; Previous versions of Visual Web Developer Express only supported ASP.NET web-site projects.&lt;/p&gt;    &lt;p&gt;Among other benefits, the support of class library and web application projects will enable ASP.NET MVC and Silverlight projects to be built with the free Visual Web Developer 2008 Express.&amp;#160; All of the above JavaScript, Dynamic Data, Classic ASP, and AJAX improvements work with Visual Web Developer Express as well.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Improvements for Client Development&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;.NET 3.5 SP1 and VS 2008 SP1 contain major performance, deployment, and feature improvements for building client applications.&amp;#160; &lt;/p&gt;    &lt;p&gt;Tim Sneath has a great blog post that talks about some of the client improvements &lt;a href="http://blogs.msdn.com/tims/archive/2008/05/12/introducing-the-third-major-release-of-windows-presentation-foundation.aspx" target="_blank"&gt;here&lt;/a&gt;.&amp;#160; Below are more details on them:&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Application Startup and Working Set Performance Improvements&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;.NET 3.5 SP1 includes significant performance improvements to the CLR that enable much faster application startup times - in particular with &amp;quot;cold start&amp;quot; scenarios (where no .NET application is already running).&amp;#160; Much of these gains were achieved by changing the layout of blocks within CLR NGEN images, and by significantly optimizing disk IO access patterns.&amp;#160; We also made some nice optimizations to our JIT code generator that allow much better inlining of methods that utilize structs.&lt;/p&gt;    &lt;p&gt;We are today measuring up to 40% faster application startup improvements for large .NET client applications with SP1 installed.&amp;#160; These optimizations also have the nice side-effect of improving ASP.NET application request per second throughput by up to 10% in some cases.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;New .NET Framework Client Profile Setup Package&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;.NET 3.5 SP1 introduces a new setup package option for developers building .NET client applications called the &amp;quot;.NET Framework Client Profile&amp;quot;.&amp;#160; This provides a new setup installer that enables a smaller, faster, and simpler installation experience for .NET client applications on machines that do not already have the .NET Framework installed.&lt;/p&gt;    &lt;p&gt;The .NET Framework Client Profile setup contains just those assemblies and files in the .NET Framework that are typically used for client application scenarios.&amp;#160; For example: it includes Windows Forms, WPF, and WCF.&amp;#160; It does not include ASP.NET and those libraries and components used primarily for server scenarios.&amp;#160; We expect this setup package to be about 26MB in size, and it can be downloaded and installed much quicker than the full .NET Framework setup package.&lt;/p&gt;    &lt;p&gt;The assemblies and APIs in the .NET Framework Client setup package are 100% identical to those in the full .NET Framework setup package (they are literally the same binaries).&amp;#160; This means that applications can target both the client profile and full profile of .NET 3.5 SP1 (no recompilation required).&amp;#160; All .NET applications that work using the .NET Client Profile setup automatically work with the full .NET Framework.&lt;/p&gt;    &lt;p&gt;A developer can indicate that the client application they are building supports both the .NET Framework Client Profile and the full .NET Framework by pulling up the project properties page for a client application within VS 2008 SP1.&amp;#160; Within the project properties page they can select a new checkbox that indicates it only requires those assemblies included in the .NET Framework Client Profile:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step5_1.png" /&gt; &lt;/p&gt;    &lt;p&gt;VS 2008 will then ensure that the project can only reference those assemblies shipped in the client profile setup package (and it will generate a compile error if you try and use a type in an assembly not included in the client redist).&amp;#160; The compiled client application will then run on machines that have both the full .NET Framework installed, as well as machines that only have the .NET Framework Client Profile installed.&lt;/p&gt;    &lt;p&gt;If you have a machine that only has the .NET Framework Client Profile installed, and you try and run a .NET application on it that did not mark itself as supporting the .NET Framework Client Profile, then the CLR will refuse to run the application - and will instead prompt the end-user to upgrade to the full .NET Framework package.&amp;#160; This ensures that applications always run correctly - and that developers do not need to worry about missing assembly exceptions at runtime if a user tries to run an application that requires the full .NET Framework on a machine that only has the .NET Framework Client Profile installed.&lt;/p&gt;    &lt;p&gt;We believe that a large class of .NET client applications will be able to use this new .NET Client Profile setup to significantly speed up their installation, and enable a much more consumer friendly experience.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;New .NET Framework Setup Bootstrapper for Client Applications&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;.NET 3.5 SP1 introduces a new &amp;quot;bootstrapper&amp;quot; component that you can use with client applications to help automate making sure that the right version of the .NET Framework is installed.&amp;#160; &lt;/p&gt;    &lt;p&gt;The bootstrapper component can handle automatically downloading and installing either the .NET Framework Client Profile or the full .NET Framework Setup Package from the Internet if your machine doesn't have either of them installed.&amp;#160; The boostrapper can also automatically handle upgrading machines that have a previous version of the .NET Framework installed.&amp;#160; For example, if your machine already has .NET 3.0 installed, and your application requires .NET 3.5, the bootstrapper can optionally download just the update files needed to upgrade it to .NET 3.5 (and avoid having to download the full .NET Framework setup download).&lt;/p&gt;    &lt;p&gt;The setup bootstrapper component can be used with both ClickOnce based setup packages, as well as with third party installer products (like Installshield).&amp;#160; The boostrapper optionally enables fully customized setup branding experiences (splash screens, custom setup wizard steps, etc) and should make it much easier to build optimized client setup experiences.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;ClickOnce Client Application Deployment Improvements&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;.NET 3.5 SP1 includes several improvements for ClickOnce deployment of both Windows Forms and WPF applications.&amp;#160; Some of these improvements include:&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;Support for the .NET Framework Client Profile (all ClickOnce features are supported with it) &lt;/li&gt;      &lt;li&gt;ClickOnce applications can now be programmatically installed through a &amp;#8216;Setup.exe&amp;#8217; while displaying a customized, branded install UX &lt;/li&gt;      &lt;li&gt;ClickOnce improvements for generating MSI + ClickOnce application packages &lt;/li&gt;      &lt;li&gt;ClickOnce error dialog boxes now support links to application specific support sites on the Web &lt;/li&gt;      &lt;li&gt;ClickOnce now has design-time support for setting up file associations &lt;/li&gt;      &lt;li&gt;ClickOnce application publishers can now decide to opt out of signing and hashing the ClickOnce manifests as they see appropriate for their scenarios. &lt;/li&gt;      &lt;li&gt;Enterprises can now choose to run only Clickonce Applications Authenticode signed by &amp;#8216;Known Publishers&amp;#8217; and block anything else from running &lt;/li&gt;      &lt;li&gt;FireFox browser extension to support Clickonce installations using FireFox browsers &lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Windows Forms Controls&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;SP1 adds several new Windows Forms controls - including new vector shape, Printing, and DataRepeater controls:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step25.png" /&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;WPF Performance Improvements&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;.NET 3.5 SP1 includes several significant performance optimizations and improvements to WPF.&amp;#160; Some of the specific graphics improvements include:&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;Smoother animations &lt;/li&gt;      &lt;li&gt;Hardware accelerated rendering of Blur and DropShadow Bitmap Effects &lt;/li&gt;      &lt;li&gt;Text Rendering speed improvements - especially with VisualBrish and 3D scenes &lt;/li&gt;      &lt;li&gt;2D graphics improvements - especially with z-index scenarios &lt;/li&gt;      &lt;li&gt;A new WriteableBitmap class that enables real-time and tear-free bitmap updates.&amp;#160; This enables custom &amp;quot;paint&amp;quot;-style applications, data visualizations, charts and graphs that optionally bypass the default WPF 2D graphics APIs. &lt;/li&gt;      &lt;li&gt;Layered window performance improvements &lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;SP1 also adds support for better data scalability in WPF.&amp;#160; The ListView, ListBox and TreeView controls now support &amp;quot;item container recycling&amp;quot; and &amp;quot;virtualization&amp;quot; support which allows you to easily achieve a 40% performance improvement with scrolling scenarios.&amp;#160; These controls also now optionally support a &amp;quot;deferred scrolling&amp;quot; feature which allows you to avoid scrolling in real time and instead wait until a user releases the scroll thumb (the default scrolling mode in Outlook). This can be useful when scrolling over very large data sets quickly.&amp;#160; &lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;WPF Data Improvements&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;.NET 3.5 SP1 includes several data binding and editing improvements to WPF.&amp;#160; These include:&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;StringFormat support within {{ Binding }} expressions to enable easy formatting of bound values &lt;/li&gt;      &lt;li&gt;New alternating rows support within controls derived from ItemsControl, which makes it easier to set alternating properties on rows (for example: alternating background colors) &lt;/li&gt;      &lt;li&gt;Better handling and conversion support for null values in editable controls &lt;/li&gt;      &lt;li&gt;Item-level validation that applies validation rules to an entire bound item &lt;/li&gt;      &lt;li&gt;MultiSelector support to handle multi-selection and bulk editing scenarios &lt;/li&gt;      &lt;li&gt;IEditableCollectionView support to interface data controls to data sources and enable editing/adding/removing items in a transactional way &lt;/li&gt;      &lt;li&gt;Performance improvements when binding to IEnumerable data sources &lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;WPF also now exposes hooks that enable developers to write custom panels w/ virtualized scrolling.&amp;#160; We'll be using this support together with the above data binding improvements to build the new WPF datagrid that will be shipping later this year.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;WPF Extensible Shader Effects &lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;.NET 3.5 SP1 adds support in WPF for a new shader effects architecture and API that allows extremely expressive visual effects to be created and applied to any control or element within WPF.&amp;#160; These shader effects support blending multiple input compositions together.&amp;#160; What makes them particularly powerful is that WPF executes effects (including custom effects you build yourself) using the GPU - giving you fully hardware accelerated graphics performance.&amp;#160; Like almost everything in WPF, you can also use WPF databinding and animation on the properties of an effect (allowing them to be fully integrated into an experience).&lt;/p&gt;    &lt;p&gt;Applying an effect onto a Control is super easy - just set a Control's &amp;quot;Effect&amp;quot; property.&amp;#160; For example, to add a hardware accelerated drop-shadow effect on a button you can use the built-in &amp;lt;DropShadowEffect&amp;gt; on it via either code or XAML:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step10.png" /&gt; &lt;/p&gt;    &lt;p&gt;Which will cause the button to render like so:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step11.png" /&gt; &lt;/p&gt;    &lt;p&gt;Because Effects are extensible, developers can create their own custom Effect objects and apply them.&amp;#160; For example, a custom &amp;quot;DirectionalBlurEffect&amp;quot; could be created and added to a ListBox control to change its scroll appearance to use a blur effect if you rapidly scroll across it:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step12.png" /&gt; &lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step13.png" /&gt; &lt;/p&gt;    &lt;p&gt;Keep an eye on &lt;a href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/a-series-on-gpu-based-effects-for-wpf.aspx" target="_blank"&gt;Greg Schechter's blog&lt;/a&gt; to learn more about how the Effects architecture works and to learn how you can both create and apply new effects within your applications (his first set of posts are &lt;a href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/a-series-on-gpu-based-effects-for-wpf.aspx" target="_blank"&gt;here&lt;/a&gt;).&amp;#160; &lt;/p&gt;    &lt;p&gt;&lt;em&gt;Note: In addition to introducing the new Shader Effects API, WPF in SP1 also has updated the existing Blur and DropShadow Bitmap effects already in WPF to be hardware accelerated.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;WPF Interoperability with Direct3D&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;.NET 3.5 SP1 adds support to efficiently integrate Direct3D directly into WPF.&amp;#160; This gives you more direct access to the hardware and to take full advantage of the Direct3D API within WPF applications.&amp;#160; You will be able to treat Direct3D content just like an image within an application, as well as use Direct3D content as textures on WPF controls.&amp;#160; &lt;/p&gt;    &lt;p&gt;For example, below are three samples from the Direct3D SDK:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step14.png" /&gt; &lt;/p&gt;    &lt;p&gt;We could either load them in as image surfaces within a WPF application, or map them as textures on WPF controls.&amp;#160; Below is an example of mapping them as textures onto cubes in a WPF 3D application:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step15.png" /&gt; &lt;/p&gt;    &lt;p&gt;&lt;em&gt;Note: the Direct3D integration isn't today's SP1 beta release.&amp;#160; It will appear in the final SP1 release.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;VS 2008 for WPF Improvements&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;VS 2008 SP1 includes several significant improvements for WPF projects and the WPF designer.&amp;#160; These include:&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;Several performance improvements &lt;/li&gt;      &lt;li&gt;Events tab support within the property browser &lt;/li&gt;      &lt;li&gt;Ability to sort properties alphabetically in the property browser &lt;/li&gt;      &lt;li&gt;Margin snaplines which makes form layout much quicker &lt;/li&gt;      &lt;li&gt;Better designer support for TabControl, Expander, and Grid &lt;/li&gt;      &lt;li&gt;Code initiated refactoring now updates your XAML (including both control declarations and event declarations in XAML) &lt;/li&gt;      &lt;li&gt;Go to Definition and Find All References now support things declared in XAML &lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;The debugger has also been updated in SP1 so that runtime errors in XAML markup (for example: referencing styles, datasources and/or other objects that don't exist) will now be better identified within the debugger:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step16.png" /&gt; &lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Data Development Improvements&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;.NET 3.5 SP1 and VS 2008 SP1 include a bunch of improvements for data development. Some of them include:&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;SQL 2008 Support&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;VS 2008 and .NET 3.5 are being updated to include support for the upcoming SQL 2008 release.&amp;#160; Visual Studio 2008 data designers, projects and wizards now fully supporting connecting and working against SQL 2008 databases.&amp;#160; &lt;/p&gt;    &lt;p&gt;&lt;b&gt;&lt;u&gt;ADO.NET Entity Framework and LINQ to Entities: &lt;/u&gt;&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;.NET 3.5 SP1 includes the new ADO.NET Entity Framework, which allows developers to define a higher-level Entity Data Model over their relational data, and then program in terms of this model.&amp;#160; Concepts like inheritance, complex types and relationships (including M:M support) can be modeled using it.&amp;#160; VS 2008 SP1 now includes built-in designer support to help with this modeling:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step22.png" /&gt; &lt;/p&gt;    &lt;p&gt;The ADO.NET Entity Framework and the VS 2008 Entity Framework Designer both support a pluggable provider model that allows them to be used with any database (including Oracle, DB2, MySql, PostgreSQL, SQLite, VistaDB, Informix, Sybase, and others).&lt;/p&gt;    &lt;p&gt;Developers can then use LINQ and LINQ to Entities to query, manipulate, and update these entity objects.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;ADO.NET Data Services (formerly code-named &amp;quot;Astoria&amp;quot;)&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;.NET 3.5 SP1 includes a flexible framework that enables the creation of REST-based data services.&amp;#160; Formerly code-named &amp;quot;Astoria&amp;quot;, the ADO.NET Data Services framework provides support for publishing data through a standard REST URI syntax and using standard HTTP verbs to operate on the data resources.&amp;#160; Developers can easily expose data models created using the ADO.NET Entity Framework, and/or use a pluggable provider model to expose other data models.&lt;/p&gt;    &lt;p&gt;In addition to publishing data sources, the framework also adds a client API for working with remote REST services.&amp;#160; Included with this client API is a LINQ library that allows the remote query of REST services.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;WCF Development Improvements&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;.NET 3.5 SP1 and VS 2008 SP1 include several enhancements for WCF development.&amp;#160; Some of these include:&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;Significant scalability improvements (5-10x) in Web-hosted application scenarios &lt;/li&gt;      &lt;li&gt;Support for using ADO.NET Entity Framework entities in WCF contracts &lt;/li&gt;      &lt;li&gt;API usability improvements with DataContract Serializers, and with the UriTemplate and WCF web programming models &lt;/li&gt;      &lt;li&gt;Enhanced TestClient support within VS 2008 SP1 &lt;/li&gt;      &lt;li&gt;New Hosting Wizard in VS 2008 SP1 for WCF Service Projects &lt;/li&gt;      &lt;li&gt;Improved debugging support in partial trust scenarios &lt;/li&gt;   &lt;/ul&gt;    &lt;h3&gt;&lt;u&gt;VB and C# Improvements&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;The VB and C# teams have also added some nice improvements to VS 2008 SP1:&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;Visual Basic&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;You can now add &amp;quot;XML to Schema&amp;quot; items to Visual Basic projects.&amp;#160; On adding these project items a wizard will open that allows you to create a XSD schema set from a variety of XML sources.&amp;#160; This schema set is then added to the project and it enables VB XML intellisense. This support was previously available as a web download - you can learn more about it &lt;a href="http://msdn.microsoft.com/en-us/vbasic/bb840042.aspx" target="_blank"&gt;here&lt;/a&gt;. &lt;/p&gt;    &lt;p&gt;A XSD browser is also now included with VS 2008 SP1 and allows you to browse XSD schema sets.&amp;#160; With the final SP1 release, developers will be able to right-click on XML element names (either in XML properties or XML literals) in the VB code editor and select &amp;#8220;Go To XML Schema Definition&amp;#8221; - this will open the XSD browser and display the schema set (and select the current element) for the VB project. &lt;/p&gt;    &lt;p&gt;&lt;strong&gt;&lt;u&gt;C#&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;The C# code editor now identifies and displays red squiggle errors for many semantic code issues that previously required an explicit compilation to identify.&amp;#160; For example, if you try to declare and use an unknown type in the C# code-editor today you won't see a compile error until you do a build.&amp;#160; Now with SP1 you'll see live red squiggle errors immediately (no explicit compile required):&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step19.png" /&gt; &lt;/p&gt;    &lt;p&gt;The debugger in VS 2008 SP1 has also been improved to provide more debugging support for evaluating LINQ expressions and viewing results at debug time:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step20.png" /&gt; &lt;/p&gt;    &lt;p&gt;LINQ enabled data sources now have a &amp;quot;Results View&amp;quot; node show up within the debugger watch window.&amp;#160; Expanding this node will evaluate a LINQ expression and allow you to examine the materialized objects it returns:&lt;/p&gt;    &lt;p&gt;&lt;img src="http://scottguvs2008sp1beta.s3.amazonaws.com/step21.png" /&gt; &lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Team Foundation Server Improvements&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;TFS 2008 SP1 includes a ton of improvements.&amp;#160; Please read Brian Harry's &lt;a href="http://blogs.msdn.com/bharry/archive/2008/04/28/team-foundation-server-2008-sp1.aspx" target="_blank"&gt;Team Foundation Server 2008 SP1 Preview blog post&lt;/a&gt; for more details.&lt;/p&gt;    &lt;h3&gt;&lt;u&gt;Summary&lt;/u&gt;&lt;/h3&gt;    &lt;p&gt;.NET 3.5 SP1 and VS 2008 SP1 provide a bunch of bug fixes, performance improvements, and additional feature enhancements that make building all types of .NET applications better.&amp;#160; It will be a fully compatible service pack release.&amp;#160; &lt;/p&gt;    &lt;p&gt;We plan to ship the final release of both .NET 3.5 SP1 and VS 2008 SP1 this summer as free updates.&amp;#160; You can download and use the beta now &lt;a href="http://msdn.microsoft.com/en-us/vstudio/products/cc533447.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;    &lt;p&gt;Hope this helps,&lt;/p&gt;    &lt;p&gt;Scott&lt;/p&gt; &lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6183094" width="1" height="1"&gt;</description>
      <link>http://weblogs.asp.net/scottgu/archive/2008/05/12/visual-studio-2008-and-net-framework-3-5-service-pack-1-beta.aspx</link>
      <author>ScottGu</author>
      <pubDate>Mon, 12 May 2008 18:51:33 GMT</pubDate>
    </item>
    <item>
      <title>Visual Studio 2008 and .NET Framework 3.5 Service Pack 1 Beta</title>
      <description>&lt;FONT face=arial size=2&gt;
&lt;P&gt;Earlier today we shipped a public beta of our upcoming .NET 3.5 SP1 and VS 2008 SP1 releases.&amp;nbsp; These servicing updates provide a roll-up of bug fixes and performance improvements for issues reported since we released the products last November.&amp;nbsp; They also contain a number of feature additions and enhancements that make building .NET applications better (see below for details on some of them).&lt;/P&gt;
&lt;P&gt;We plan to ship the final release of both .NET 3.5 SP1 and VS 2008 SP1 this summer as free updates.&amp;nbsp; You can download and install the beta &lt;A href="http://msdn.microsoft.com/en-us/vstudio/products/cc533447.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/vstudio/products/cc533447.aspx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;H3&gt;&lt;U&gt;Important: SP1 Beta Installation Notes&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;The SP1 beta released today is still in beta form - so you should be careful about installing it on critical machines.&amp;nbsp; There are a few important SP1 Beta installation notes to be aware of:&lt;/P&gt;
&lt;P&gt;1) If you are running Windows Vista you should make sure you have Vista SP1 installed before trying to install .NET 3.5 SP1 Beta.&amp;nbsp; There are some setup issues with .NET 3.5 SP1 when running on the Vista RTM release.&amp;nbsp; These issues will be fixed for the final .NET 3.5 SP1 release - until then please make sure to have Vista SP1 installed &lt;EM&gt;before&lt;/EM&gt; trying to install .NET 3.5 SP1 beta.&lt;/P&gt;
&lt;P&gt;2) If you have installed the VS 2008 Tools for Silverlight 2 Beta1 package on your machine, you must uninstall it - as well as uninstall the KB949325 update for VS 2008 - &lt;EM&gt;before &lt;/EM&gt;installing VS 2008 SP1 Beta (otherwise you will get a setup failure).&amp;nbsp; You can find more details on the exact steps to follow &lt;A href="http://blogs.msdn.com/webdevtools/archive/2008/05/12/error-installing-visual-studio-2008-sp1-beta-and-silverlight-tools-beta-1.aspx" target=_blank mce_href="http://blogs.msdn.com/webdevtools/archive/2008/05/12/error-installing-visual-studio-2008-sp1-beta-and-silverlight-tools-beta-1.aspx"&gt;here&lt;/A&gt; (note: you must uninstall two separate things).&amp;nbsp; It is fine to have the Silverlight 2 runtime on your machine with .NET 3.5 SP1 - the component that needs to be uninstalled is the VS 2008 Tools for Silverlight 2 package.&amp;nbsp; We will release an updated VS 2008 Tools for Silverlight package in a few weeks that works with the VS 2008 SP1 beta.&lt;/P&gt;
&lt;P&gt;3) There is a change in behavior in the .NET 3.5 SP1 beta that causes a problem with the shipping versions of Expression Blend.&amp;nbsp; This behavior change is being reverted for the final .NET 3.5 SP1 release, at which time all versions of Blend will have no problems running.&amp;nbsp; Until then, you need to download &lt;A href="http://blogs.msdn.com/expression/archive/2008/04/18/vs2008sp1.aspx" target=_blank mce_href="http://blogs.msdn.com/expression/archive/2008/04/18/vs2008sp1.aspx"&gt;this recently updated version of Blend 2.5&lt;/A&gt; to work around this issue.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT color=#ff3300&gt;&lt;U&gt;Important Update&lt;/U&gt;:&lt;/FONT&gt;&lt;/STRONG&gt; If you previously installed a VS 2008 Hotfix, you must run the HotFix Cleanup Utility before installing the VS 2008 SP1 Beta.&amp;nbsp; &lt;A class="" href="http://code.msdn.microsoft.com/RemoveKB944899/Release/ProjectReleases.aspx?ReleaseId=1030" mce_href="http://code.msdn.microsoft.com/RemoveKB944899/Release/ProjectReleases.aspx?ReleaseId=1030"&gt;Click here&lt;/A&gt; to download and run this.&lt;/P&gt;
&lt;H3&gt;&lt;U&gt;Improvements for Web Development&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;.NET 3.5 SP1 and VS 2008 SP1 contain a bunch of feature improvements targeted at web application development.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The VS Web Dev Tools team has more details (including specific bug fix details) on some of the VS specific work &lt;A href="http://blogs.msdn.com/webdevtools/archive/2008/05/12/visual-studio-2008-sp1-beta.aspx" target=_blank mce_href="http://blogs.msdn.com/webdevtools/archive/2008/05/12/visual-studio-2008-sp1-beta.aspx"&gt;here&lt;/A&gt;.&amp;nbsp; Below are more details on some of the work in the web-space:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;ASP.NET Data Scaffolding Support (ASP.NET Dynamic Data)&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;.NET 3.5 SP1 adds support for a rich ASP.NET data "scaffolding" framework that enables you to quickly build functional data-driven web application. With the ASP.NET Dynamic Data feature you can automatically build web UI (with full CRUD - create, read, update, delete - support) against a variety of data object models (including LINQ to SQL, LINQ to Entities, REST Services, and any other ORM or object model with a dynamic data provider).&lt;/P&gt;
&lt;P&gt;SP1 adds this new functionality to the existing GridView, ListView, DetailsView and FormView controls in ASP.NET, and enables smart validation and flexible data templating options.&amp;nbsp; It also delivers new smart filtering server controls, as well as adds support for automatically traversing primary-key/foreign-key relationships and displaying friendly foreign key names - all of which saves you from having to write a ton of code.&lt;/P&gt;
&lt;P&gt;You can learn more more about this feature from Scott Hanselman's videos and tutorials &lt;A href="http://www.asp.net/dynamicdata/" target=_blank mce_href="http://www.asp.net/dynamicdata/"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;ASP.NET Routing Engine (System.Web.Routing)&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;.NET 3.5 SP1 includes a flexible new URL routing engine that allows you to map incoming URLs to route handlers.&amp;nbsp; It includes support for both parsing parameters from clean URLs (for example: /Products/Browse/Beverages), as well as support to dynamically calculate and generate new URLs from route registrations.&lt;/P&gt;
&lt;P&gt;This new routing engine is used by both ASP.NET Dynamic Data as well as the new ASP.NET MVC framework.&amp;nbsp; It will support both WebForms and MVC based requests.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;ASP.NET AJAX Back/Forward Button History Support&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;.NET 3.5 SP1 adds new APIs to ASP.NET AJAX to allow you to better control the history list of a browser (enabling you to control the behavior of the back/forward button of the browser).&lt;/P&gt;
&lt;P&gt;You can learn more about this feature in the article &lt;A href="http://weblogs.asp.net/davidbarkol/archive/2007/12/28/asp-net-3-5-extensions-history-control-tip.aspx" target=_blank mce_href="http://weblogs.asp.net/davidbarkol/archive/2007/12/28/asp-net-3-5-extensions-history-control-tip.aspx"&gt;here&lt;/A&gt; and the screencast &lt;A href="http://weblogs.asp.net/bleroy/archive/2008/01/04/screencast-how-to-enable-server-side-history-management-in-an-asp-net-ajax-application.aspx" target=_blank mce_href="http://weblogs.asp.net/bleroy/archive/2008/01/04/screencast-how-to-enable-server-side-history-management-in-an-asp-net-ajax-application.aspx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;ASP.NET AJAX Script Combining Support&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;.NET 3.5 SP1 introduces a new &amp;lt;CompositeScript&amp;gt; element on the &amp;lt;asp:ScriptManager&amp;gt; server control, which allows you to declaratively define multiple script references within it.&amp;nbsp; All the script references within the CompositeScript element are combined together on the server and served as a single script to the client, reducing the number of requests to the server and improving page load time for ASP.NET AJAX applications.&lt;/P&gt;
&lt;P&gt;The script combining feature supports both path based scripts and assembly resource based scripts, and dynamically serves up the combined scripts using the ScriptResources.axd handler.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;Visual Studio 2008 Performance Improvements HTML Designer and HTML Source Editor&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In February we released a &lt;A href="http://weblogs.asp.net/scottgu/archive/2008/02/08/vs-2008-web-development-hot-fix-roll-up-available.aspx" target=_blank mce_href="http://weblogs.asp.net/scottgu/archive/2008/02/08/vs-2008-web-development-hot-fix-roll-up-available.aspx"&gt;HotFix roll-up&lt;/A&gt; that included a number of performance improvements and bug fixes for the VS 2008 Web Designer.&amp;nbsp; VS 2008 SP1 includes all of these fixes, as well as a number of additional performance improvements.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;Visual Studio 2008 JavaScript Script Formatting and Code Preferences&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Visual Studio has for several releases supported rich source code formatting options for VB and C# (spacing, line breaks, brace positions, etc).&lt;/P&gt;
&lt;P&gt;VS 2008 SP1 adds richer source code formatting support for JavaScript as well (both inline &amp;lt;script&amp;gt; blocks and .js files).&amp;nbsp; You can now set your Javascript coding preferences using the Tools-&amp;gt;Options dialog:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step3.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step3.png"&gt; &lt;/P&gt;
&lt;P&gt;These preferences will be automatically used as you type new Javascript code in the source editor.&amp;nbsp; You can also select existing code, right-click, and choose the "Format Selection" option to apply your style preferences to existing JavaScript code.&amp;nbsp; You can learn more about this new feature &lt;A href="http://blogs.msdn.com/webdevtools/archive/2008/05/12/introducing-jscript-formatting-in-vs-2008-sp1.aspx" target=_blank mce_href="http://blogs.msdn.com/webdevtools/archive/2008/05/12/introducing-jscript-formatting-in-vs-2008-sp1.aspx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;Better Visual Studio Javascript Intellisense for Multiple Javascript/AJAX Frameworks&lt;/STRONG&gt;&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;VS 2008 includes &lt;A href="http://weblogs.asp.net/scottgu/archive/2007/06/21/vs-2008-javascript-intellisense.aspx" target=_blank mce_href="http://weblogs.asp.net/scottgu/archive/2007/06/21/vs-2008-javascript-intellisense.aspx"&gt;Javascript Intellisense support&lt;/A&gt; in source view.&amp;nbsp; The intellisense support with the initial VS 2008 release works well with vanilla JavaScript as well as code written using the ASP.NET AJAX JavaScript type patterns.&amp;nbsp; JavaScript is a &lt;EM&gt;very&lt;/EM&gt; flexible language, though, and many JavaScript libraries use this flexibility to full advantage to implement their features - sometimes in ways that prevented the intellisense engine from providing completion support.&lt;/P&gt;
&lt;P&gt;VS 2008 SP1 adds much better intellisense support for popular Javascript libraries (we specifically did work to support JQuery, Prototype, Scriptaculous, ExtJS, and other popular libraries).&amp;nbsp; You will get better default intellisense when you reference these libraries.&amp;nbsp; We are also looking at whether we can maintain additional intellisense hint files that you can download to get even better intellisense and documentation support for some of the more popular libraries.&lt;/P&gt;
&lt;P&gt;Below is an example of using a JQuery startup function with the VS 2008 SP1 JavaScript intellisense engine:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step23.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step23.png"&gt; &lt;/P&gt;
&lt;P&gt;Notice below how VS 2008 SP1 can now provide method argument completion even on chained JQuery selectors:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step24.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step24.png"&gt; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;Visual Studio Refactoring Support for WCF Services in ASP.NET Projects&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;VS 2008 SP1 adds better refactoring support for WCF services included within both ASP.NET Web Site and ASP.NET Web Application Projects. &lt;/P&gt;
&lt;P&gt;If you use the refactoring support to rename the class name, interface contract, or namespace of a WCF service, VS 2008 SP1 will now automatically fix up the web.config and SVC file references to it.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;Visual Studio Support for Classic ASP Intellisense and Debugging &lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Previous versions of Visual Studio included support for intellisense and debugging within classic ASP (.asp) pages.&amp;nbsp; The file and project templates to create classic ASP pages/projects hasn't been in VS for a few releases, though, and with the initial VS 2008 we incorrectly assumed this meant that people weren't still using the classic ASP support.&amp;nbsp; We heard feedback after we shipped that indeed they were.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;With VS 2008 SP1 this support for classic ASP intellisense and debugging is back:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step2.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step2.png"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;Visual Web Developer Express Edition support for Class Library and Web Application Projects&lt;/STRONG&gt;&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;The Visual Web Developer 2008 Express edition (which is free) is being updated in SP1 to add support for both class library and ASP.NET Web Application project types.&amp;nbsp; Previous versions of Visual Web Developer Express only supported ASP.NET web-site projects.&lt;/P&gt;
&lt;P&gt;Among other benefits, the support of class library and web application projects will enable ASP.NET MVC and Silverlight projects to be built with the free Visual Web Developer 2008 Express.&amp;nbsp; All of the above JavaScript, Dynamic Data, Classic ASP, and AJAX improvements work with Visual Web Developer Express as well.&lt;/P&gt;
&lt;H3&gt;&lt;U&gt;Improvements for Client Development&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;.NET 3.5 SP1 and VS 2008 SP1 contain major performance, deployment, and feature improvements for building client applications.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Tim Sneath has a great blog post that talks about some of the client improvements &lt;A href="http://blogs.msdn.com/tims/archive/2008/05/12/introducing-the-third-major-release-of-windows-presentation-foundation.aspx" target=_blank mce_href="http://blogs.msdn.com/tims/archive/2008/05/12/introducing-the-third-major-release-of-windows-presentation-foundation.aspx"&gt;here&lt;/A&gt;.&amp;nbsp; Below are more details on them:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;Application Startup and Working Set Performance Improvements&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;.NET 3.5 SP1 includes significant performance improvements to the CLR that enable much faster application startup times - in particular with "cold start" scenarios (where no .NET application is already running).&amp;nbsp; Much of these gains were achieved by changing the layout of blocks within CLR NGEN images, and by significantly optimizing disk IO access patterns.&amp;nbsp; We also made some nice optimizations to our JIT code generator that allow much better inlining of methods that utilize structs.&lt;/P&gt;
&lt;P&gt;We are today measuring up to 40% faster application startup improvements for large .NET client applications with SP1 installed.&amp;nbsp; These optimizations also have the nice side-effect of improving ASP.NET application request per second throughput by up to 10% in some cases.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;New .NET Framework Client Profile Setup Package&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;.NET 3.5 SP1 introduces a new setup package option for developers building .NET client applications called the ".NET Framework Client Profile".&amp;nbsp; This provides a new setup installer that enables a smaller, faster, and simpler installation experience for .NET client applications on machines that do not already have the .NET Framework installed.&lt;/P&gt;
&lt;P&gt;The .NET Framework Client Profile setup contains just those assemblies and files in the .NET Framework that are typically used for client application scenarios.&amp;nbsp; For example: it includes Windows Forms, WPF, and WCF.&amp;nbsp; It does not include ASP.NET and those libraries and components used primarily for server scenarios.&amp;nbsp; We expect this setup package to be about 26MB in size, and it can be downloaded and installed much quicker than the full .NET Framework setup package.&lt;/P&gt;
&lt;P&gt;The assemblies and APIs in the .NET Framework Client setup package are 100% identical to those in the full .NET Framework setup package (they are literally the same binaries).&amp;nbsp; This means that applications can target both the client profile and full profile of .NET 3.5 SP1 (no recompilation required).&amp;nbsp; All .NET applications that work using the .NET Client Profile setup automatically work with the full .NET Framework.&lt;/P&gt;
&lt;P&gt;A developer can indicate that the client application they are building supports both the .NET Framework Client Profile and the full .NET Framework by pulling up the project properties page for a client application within VS 2008 SP1.&amp;nbsp; Within the project properties page they can select a new checkbox that indicates it only requires those assemblies included in the .NET Framework Client Profile:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step5_1.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step5_1.png"&gt; &lt;/P&gt;
&lt;P&gt;VS 2008 will then ensure that the project can only reference those assemblies shipped in the client profile setup package (and it will generate a compile error if you try and use a type in an assembly not included in the client redist).&amp;nbsp; The compiled client application will then run on machines that have both the full .NET Framework installed, as well as machines that only have the .NET Framework Client Profile installed.&lt;/P&gt;
&lt;P&gt;If you have a machine that only has the .NET Framework Client Profile installed, and you try and run a .NET application on it that did not mark itself as supporting the .NET Framework Client Profile, then the CLR will refuse to run the application - and will instead prompt the end-user to upgrade to the full .NET Framework package.&amp;nbsp; This ensures that applications always run correctly - and that developers do not need to worry about missing assembly exceptions at runtime if a user tries to run an application that requires the full .NET Framework on a machine that only has the .NET Framework Client Profile installed.&lt;/P&gt;
&lt;P&gt;We believe that a large class of .NET client applications will be able to use this new .NET Client Profile setup to significantly speed up their installation, and enable a much more consumer friendly experience.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;New .NET Framework Setup Bootstrapper for Client Applications&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;.NET 3.5 SP1 introduces a new "bootstrapper" component that you can use with client applications to help automate making sure that the right version of the .NET Framework is installed.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The bootstrapper component can handle automatically downloading and installing either the .NET Framework Client Profile or the full .NET Framework Setup Package from the Internet if your machine doesn't have either of them installed.&amp;nbsp; The boostrapper can also automatically handle upgrading machines that have a previous version of the .NET Framework installed.&amp;nbsp; For example, if your machine already has .NET 3.0 installed, and your application requires .NET 3.5, the bootstrapper can optionally download just the update files needed to upgrade it to .NET 3.5 (and avoid having to download the full .NET Framework setup download).&lt;/P&gt;
&lt;P&gt;The setup bootstrapper component can be used with both ClickOnce based setup packages, as well as with third party installer products (like Installshield).&amp;nbsp; The boostrapper optionally enables fully customized setup branding experiences (splash screens, custom setup wizard steps, etc) and should make it much easier to build optimized client setup experiences.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;ClickOnce Client Application Deployment Improvements&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;.NET 3.5 SP1 includes several improvements for ClickOnce deployment of both Windows Forms and WPF applications.&amp;nbsp; Some of these improvements include:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Support for the .NET Framework Client Profile (all ClickOnce features are supported with it) &lt;/LI&gt;
&lt;LI&gt;ClickOnce applications can now be programmatically installed through a 'Setup.exe' while displaying a customized, branded install UX &lt;/LI&gt;
&lt;LI&gt;ClickOnce improvements for generating MSI + ClickOnce application packages &lt;/LI&gt;
&lt;LI&gt;ClickOnce error dialog boxes now support links to application specific support sites on the Web &lt;/LI&gt;
&lt;LI&gt;ClickOnce now has design-time support for setting up file associations &lt;/LI&gt;
&lt;LI&gt;ClickOnce application publishers can now decide to opt out of signing and hashing the ClickOnce manifests as they see appropriate for their scenarios. &lt;/LI&gt;
&lt;LI&gt;Enterprises can now choose to run only Clickonce Applications Authenticode signed by 'Known Publishers' and block anything else from running &lt;/LI&gt;
&lt;LI&gt;FireFox browser extension to support Clickonce installations using FireFox browsers &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;Windows Forms Controls&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;SP1 adds several new Windows Forms controls - including new vector shape, Printing, and DataRepeater controls:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step25.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step25.png"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;WPF Performance Improvements&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;.NET 3.5 SP1 includes several significant performance optimizations and improvements to WPF.&amp;nbsp; Some of the specific graphics improvements include:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Smoother animations &lt;/LI&gt;
&lt;LI&gt;Hardware accelerated rendering of Blur and DropShadow Bitmap Effects &lt;/LI&gt;
&lt;LI&gt;Text Rendering speed improvements - especially with VisualBrish and 3D scenes &lt;/LI&gt;
&lt;LI&gt;2D graphics improvements - especially with z-index scenarios &lt;/LI&gt;
&lt;LI&gt;A new WriteableBitmap class that enables real-time and tear-free bitmap updates.&amp;nbsp; This enables custom "paint"-style applications, data visualizations, charts and graphs that optionally bypass the default WPF 2D graphics APIs. &lt;/LI&gt;
&lt;LI&gt;Layered window performance improvements &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;SP1 also adds support for better data scalability in WPF.&amp;nbsp; The ListView, ListBox and TreeView controls now support "item container recycling" and "virtualization" support which allows you to easily achieve a 40% performance improvement with scrolling scenarios.&amp;nbsp; These controls also now optionally support a "deferred scrolling" feature which allows you to avoid scrolling in real time and instead wait until a user releases the scroll thumb (the default scrolling mode in Outlook). This can be useful when scrolling over very large data sets quickly.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;WPF Data Improvements&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;.NET 3.5 SP1 includes several data binding and editing improvements to WPF.&amp;nbsp; These include:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;StringFormat support within {{ Binding }} expressions to enable easy formatting of bound values &lt;/LI&gt;
&lt;LI&gt;New alternating rows support within controls derived from ItemsControl, which makes it easier to set alternating properties on rows (for example: alternating background colors) &lt;/LI&gt;
&lt;LI&gt;Better handling and conversion support for null values in editable controls &lt;/LI&gt;
&lt;LI&gt;Item-level validation that applies validation rules to an entire bound item &lt;/LI&gt;
&lt;LI&gt;MultiSelector support to handle multi-selection and bulk editing scenarios &lt;/LI&gt;
&lt;LI&gt;IEditableCollectionView support to interface data controls to data sources and enable editing/adding/removing items in a transactional way &lt;/LI&gt;
&lt;LI&gt;Performance improvements when binding to IEnumerable data sources &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;WPF also now exposes hooks that enable developers to write custom panels w/ virtualized scrolling.&amp;nbsp; We'll be using this support together with the above data binding improvements to build the new WPF datagrid that will be shipping later this year.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;WPF Extensible Shader Effects &lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;.NET 3.5 SP1 adds support in WPF for a new shader effects architecture and API that allows extremely expressive visual effects to be created and applied to any control or element within WPF.&amp;nbsp; These shader effects support blending multiple input compositions together.&amp;nbsp; What makes them particularly powerful is that WPF executes effects (including custom effects you build yourself) using the GPU - giving you fully hardware accelerated graphics performance.&amp;nbsp; Like almost everything in WPF, you can also use WPF databinding and animation on the properties of an effect (allowing them to be fully integrated into an experience).&lt;/P&gt;
&lt;P&gt;Applying an effect onto a Control is super easy - just set a Control's "Effect" property.&amp;nbsp; For example, to add a hardware accelerated drop-shadow effect on a button you can use the built-in &amp;lt;DropShadowEffect&amp;gt; on it via either code or XAML:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step10.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step10.png"&gt; &lt;/P&gt;
&lt;P&gt;Which will cause the button to render like so:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step11.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step11.png"&gt; &lt;/P&gt;
&lt;P&gt;Because Effects are extensible, developers can create their own custom Effect objects and apply them.&amp;nbsp; For example, a custom "DirectionalBlurEffect" could be created and added to a ListBox control to change its scroll appearance to use a blur effect if you rapidly scroll across it:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step12.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step12.png"&gt; &lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step13.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step13.png"&gt; &lt;/P&gt;
&lt;P&gt;Keep an eye on &lt;A href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/a-series-on-gpu-based-effects-for-wpf.aspx" target=_blank mce_href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/a-series-on-gpu-based-effects-for-wpf.aspx"&gt;Greg Schechter's blog&lt;/A&gt; to learn more about how the Effects architecture works and to learn how you can both create and apply new effects within your applications (his first set of posts are &lt;A href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/a-series-on-gpu-based-effects-for-wpf.aspx" target=_blank mce_href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/a-series-on-gpu-based-effects-for-wpf.aspx"&gt;here&lt;/A&gt;).&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Note: In addition to introducing the new Shader Effects API, WPF in SP1 also has updated the existing Blur and DropShadow Bitmap effects already in WPF to be hardware accelerated.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;WPF Interoperability with Direct3D&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;.NET 3.5 SP1 adds support to efficiently integrate Direct3D directly into WPF.&amp;nbsp; This gives you more direct access to the hardware and to take full advantage of the Direct3D API within WPF applications.&amp;nbsp; You will be able to treat Direct3D content just like an image within an application, as well as use Direct3D content as textures on WPF controls.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;For example, below are three samples from the Direct3D SDK:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step14.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step14.png"&gt; &lt;/P&gt;
&lt;P&gt;We could either load them in as image surfaces within a WPF application, or map them as textures on WPF controls.&amp;nbsp; Below is an example of mapping them as textures onto cubes in a WPF 3D application:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step15.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step15.png"&gt; &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Note: the Direct3D integration isn't today's SP1 beta release.&amp;nbsp; It will appear in the final SP1 release.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;VS 2008 for WPF Improvements&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;VS 2008 SP1 includes several significant improvements for WPF projects and the WPF designer.&amp;nbsp; These include:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Several performance improvements &lt;/LI&gt;
&lt;LI&gt;Events tab support within the property browser &lt;/LI&gt;
&lt;LI&gt;Ability to sort properties alphabetically in the property browser &lt;/LI&gt;
&lt;LI&gt;Margin snaplines which makes form layout much quicker &lt;/LI&gt;
&lt;LI&gt;Better designer support for TabControl, Expander, and Grid &lt;/LI&gt;
&lt;LI&gt;Code initiated refactoring now updates your XAML (including both control declarations and event declarations in XAML) &lt;/LI&gt;
&lt;LI&gt;Go to Definition and Find All References now support things declared in XAML &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The debugger has also been updated in SP1 so that runtime errors in XAML markup (for example: referencing styles, datasources and/or other objects that don't exist) will now be better identified within the debugger:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step16.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step16.png"&gt; &lt;/P&gt;
&lt;H3&gt;&lt;U&gt;Data Development Improvements&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;.NET 3.5 SP1 and VS 2008 SP1 include a bunch of improvements for data development. Some of them include:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;SQL 2008 Support&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;VS 2008 and .NET 3.5 are being updated to include support for the upcoming SQL 2008 release.&amp;nbsp; Visual Studio 2008 data designers, projects and wizards now fully supporting connecting and working against SQL 2008 databases.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;U&gt;ADO.NET Entity Framework and LINQ to Entities: &lt;/U&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;.NET 3.5 SP1 includes the new ADO.NET Entity Framework, which allows developers to define a higher-level Entity Data Model over their relational data, and then program in terms of this model.&amp;nbsp; Concepts like inheritance, complex types and relationships (including M:M support) can be modeled using it.&amp;nbsp; VS 2008 SP1 now includes built-in designer support to help with this modeling:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step22.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step22.png"&gt; &lt;/P&gt;
&lt;P&gt;The ADO.NET Entity Framework and the VS 2008 Entity Framework Designer both support a pluggable provider model that allows them to be used with any database (including Oracle, DB2, MySql, PostgreSQL, SQLite, VistaDB, Informix, Sybase, and others).&lt;/P&gt;
&lt;P&gt;Developers can then use LINQ and LINQ to Entities to query, manipulate, and update these entity objects.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;ADO.NET Data Services (formerly code-named "Astoria")&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;.NET 3.5 SP1 includes a flexible framework that enables the creation of REST-based data services.&amp;nbsp; Formerly code-named "Astoria", the ADO.NET Data Services framework provides support for publishing data through a standard REST URI syntax and using standard HTTP verbs to operate on the data resources.&amp;nbsp; Developers can easily expose data models created using the ADO.NET Entity Framework, and/or use a pluggable provider model to expose other data models.&lt;/P&gt;
&lt;P&gt;In addition to publishing data sources, the framework also adds a client API for working with remote REST services.&amp;nbsp; Included with this client API is a LINQ library that allows the remote query of REST services.&lt;/P&gt;
&lt;H3&gt;&lt;U&gt;WCF Development Improvements&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;.NET 3.5 SP1 and VS 2008 SP1 include several enhancements for WCF development.&amp;nbsp; Some of these include:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Significant scalability improvements (5-10x) in Web-hosted application scenarios &lt;/LI&gt;
&lt;LI&gt;Support for using ADO.NET Entity Framework entities in WCF contracts &lt;/LI&gt;
&lt;LI&gt;API usability improvements with DataContract Serializers, and with the UriTemplate and WCF web programming models &lt;/LI&gt;
&lt;LI&gt;Enhanced TestClient support within VS 2008 SP1 &lt;/LI&gt;
&lt;LI&gt;New Hosting Wizard in VS 2008 SP1 for WCF Service Projects &lt;/LI&gt;
&lt;LI&gt;Improved debugging support in partial trust scenarios &lt;/LI&gt;&lt;/UL&gt;
&lt;H3&gt;&lt;U&gt;VB and C# Improvements&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;The VB and C# teams have also added some nice improvements to VS 2008 SP1:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;Visual Basic&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;You can now add "XML to Schema" items to Visual Basic projects.&amp;nbsp; On adding these project items a wizard will open that allows you to create a XSD schema set from a variety of XML sources.&amp;nbsp; This schema set is then added to the project and it enables VB XML intellisense. This support was previously available as a web download - you can learn more about it &lt;A href="http://msdn.microsoft.com/en-us/vbasic/bb840042.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/vbasic/bb840042.aspx"&gt;here&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;A XSD browser is also now included with VS 2008 SP1 and allows you to browse XSD schema sets.&amp;nbsp; With the final SP1 release, developers will be able to right-click on XML element names (either in XML properties or XML literals) in the VB code editor and select "Go To XML Schema Definition" - this will open the XSD browser and display the schema set (and select the current element) for the VB project. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;C#&lt;/U&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The C# code editor now identifies and displays red squiggle errors for many semantic code issues that previously required an explicit compilation to identify.&amp;nbsp; For example, if you try to declare and use an unknown type in the C# code-editor today you won't see a compile error until you do a build.&amp;nbsp; Now with SP1 you'll see live red squiggle errors immediately (no explicit compile required):&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step19.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step19.png"&gt; &lt;/P&gt;
&lt;P&gt;The debugger in VS 2008 SP1 has also been improved to provide more debugging support for evaluating LINQ expressions and viewing results at debug time:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step20.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step20.png"&gt; &lt;/P&gt;
&lt;P&gt;LINQ enabled data sources now have a "Results View" node show up within the debugger watch window.&amp;nbsp; Expanding this node will evaluate a LINQ expression and allow you to examine the materialized objects it returns:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://scottguvs2008sp1beta.s3.amazonaws.com/step21.png" mce_src="http://scottguvs2008sp1beta.s3.amazonaws.com/step21.png"&gt; &lt;/P&gt;
&lt;H3&gt;&lt;U&gt;Team Foundation Server Improvements&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;TFS 2008 SP1 includes a ton of improvements.&amp;nbsp; Please read Brian Harry's &lt;A href="http://blogs.msdn.com/bharry/archive/2008/04/28/team-foundation-server-2008-sp1.aspx" target=_blank mce_href="http://blogs.msdn.com/bharry/archive/2008/04/28/team-foundation-server-2008-sp1.aspx"&gt;Team Foundation Server 2008 SP1 Preview blog post&lt;/A&gt; for more details.&lt;/P&gt;
&lt;H3&gt;&lt;U&gt;Summary&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;.NET 3.5 SP1 and VS 2008 SP1 provide a bunch of bug fixes, performance improvements, and additional feature enhancements that make building all types of .NET applications better.&amp;nbsp; It will be a fully compatible service pack release.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;We plan to ship the final release of both .NET 3.5 SP1 and VS 2008 SP1 this summer as free updates.&amp;nbsp; You can download and use the beta now &lt;A href="http://msdn.microsoft.com/en-us/vstudio/products/cc533447.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/vstudio/products/cc533447.aspx"&gt;here&lt;/A&gt;.
