<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DUMMSHYzfip7ImA9WxNUFkQ.&quot;"><id>tag:blogger.com,1999:blog-14267103</id><updated>2009-11-08T18:24:49.886+02:00</updated><title>Siderite Zackwehdex's Blog</title><subtitle type="html">You find here some programming tips and useless rants and personal opinions. I am a fan of the  band &lt;a href="http://www.myspace.com/nerostitele" title="Best Romanian rock band"&gt;Coma&lt;/a&gt;. My movie comments can be found &lt;a href="http://imdb.com/user/ur3146136/comments?order=date" title="my IMDb comments"&gt;here&lt;/a&gt;. Please leave any general message for me &lt;a href="http://siderite.blogspot.com/2007/01/leave-your-comments-here.html" title="Add a comment to send me a message"&gt;&lt;b&gt;here&lt;/b&gt;&lt;/a&gt;.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://siderite.blogspot.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>651</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/Siderite" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;CUQERH49eip7ImA9WxNUFE8.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-2242194152843464342</id><published>2009-11-05T14:02:00.002+02:00</published><updated>2009-11-05T14:15:05.062+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-05T14:15:05.062+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="web design" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Use CSS expression to initialize html elements</title><content type="html">Internet Explorer added something called &lt;strong&gt;expression&lt;/strong&gt; to CSS, something purists have booed at for mingling javascript and CSS. Well, boo back! I happen to like stuff that can solve problems. If I were at Microsoft I would create an entire subset of javascript and css functionality. But hey, that's just me.&lt;br /&gt;&lt;br /&gt;  Anyway, I have decided to use &lt;strong&gt;expression&lt;/strong&gt; to run an initialize function on newly created elements. It would work like this:&lt;pre&gt;initialize:expression(window.initializeElement?initializeElement(this):null);&lt;/pre&gt;This CSS bit tells Internet Explorer (and none of the other browsers) that the &lt;em&gt;initialize&lt;/em&gt; style property should get the value of the &lt;em&gt;initializeElement&lt;/em&gt; function every time the browser refreshes the layout of the element. In the function itself I would do something like this:&lt;pre&gt;function initializeElement(elem) {&lt;br /&gt;  if (!elem.style.initialize) {&lt;br /&gt;    doSomethingWith(elem);&lt;br /&gt;  }&lt;br /&gt;  return true;&lt;br /&gt;}&lt;/pre&gt;This basically executes &lt;em&gt;doSomethingWith&lt;/em&gt; on each element matched by the CSS rule and only once.&lt;br /&gt;&lt;br /&gt;  Good theory, but in practice it was terribly slow and, after a while, it managed to kill Internet Explorer with a strange &lt;strong&gt;System.AccessViolationException: Attempted to read or write protected memory&lt;/strong&gt; error.&lt;br /&gt;&lt;br /&gt;  What happened? The slowness, I gathered after a while, was caused by the function &lt;em&gt;doSomethingWith&lt;/em&gt; because it changed the style of the element. That meant that the css rule was being applied again before the function ended and returned true. Changing things to:&lt;pre&gt;function initializeElement(elem) {&lt;br /&gt;  if (!elem.style.initialize) {&lt;br /&gt;    elem.style.initialize=true;&lt;br /&gt;    doSomethingWith(elem);   &lt;br /&gt;  }&lt;br /&gt;  return true;&lt;br /&gt;}&lt;/pre&gt; fixed it.&lt;br /&gt;&lt;br /&gt;  The error that killed Internet Explorer was even stranger. After a while I narrowed it down to using jQuery. I have no idea what it did, probably trying to access &lt;em&gt;computedStyle&lt;/em&gt; or something like that. The thing is that changing an &lt;strong&gt;$(elem).height()&lt;/strong&gt; with &lt;strong&gt;elem.offsetHeight&lt;/strong&gt; solved it.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-2242194152843464342?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/WChwvg-GO_A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/2242194152843464342/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=2242194152843464342" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/2242194152843464342?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/2242194152843464342?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/WChwvg-GO_A/use-css-expression-to-initialize-html.html" title="Use CSS expression to initialize html elements" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/11/use-css-expression-to-initialize-html.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQFRHw7eip7ImA9WxNUFE8.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-913975480210109909</id><published>2009-11-04T13:12:00.004+02:00</published><updated>2009-11-05T14:31:55.202+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-05T14:31:55.202+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio" /><title>Get Visual Studio to use (better) more than 2GB of memory</title><content type="html">I actually didn't know that a 32bit program could not use more than 2Gb of virtual memory by default. It makes sense, now that I think of it, but I just didn't make the connection. My office computer has 3Gb of memory and there is also the swap file, so having a program using more than 2GB of memory would be beneficial. And I am talking about Visual Studio here, especially since today I got an error I've never seen before: "&lt;em&gt;Not enough storage is available to complete this operation&lt;/em&gt;".&lt;br /&gt;&lt;br /&gt;  So I've stumbled upon this article: &lt;a href="http://stevenharman.net/blog/archive/2008/04/29/hacking-visual-studio-to-use-more-than-2gigabytes-of-memory.aspx" target="_blank" title="by Steven Harman"&gt;Hacking Visual Studio to Use More Than 2Gigabytes of Memory&lt;/a&gt; which told me how to convince Visual Studio to use more than 2GB of memory. Also, since I am a ReSharper user, I found this little wrapper for Visual Studio that makes it use a different memory allocation method that reduces memory fragmentation: &lt;a href="http://www.jetbrains.net/confluence/display/ReSharper/OutOfMemoryException%2BFix" target="_blank" title="overrides Visual Studio's memory allocation policy to ensure more continuous address space for Common Language Runtime"&gt;OutOfMemoryException Fix&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Short story shorter (for XP users with Visual Studio 2008 only - read the full articles for other configuration):&lt;ol&gt;&lt;li&gt;Edit boot.ini to have &lt;a href="http://www.microsoft.com/whdc/system/platform/server/PAE/PAEmem.mspx" target="_blank" title="Only for XP professional and above"&gt;the &lt;strong&gt;/3GB&lt;/strong&gt; option&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Use &lt;em&gt;editbin /LARGEADDRESSAWARE devenv.exe&lt;/em&gt; to change Visual Studio to have IMAGE_FILE_LARGE_ADDRESS_AWARE in the process header (editbin can be found in &lt;em&gt;\Program Files\Microsoft Visual Studio 9.0\VC\bin\&lt;/em&gt;&lt;/li&gt;&lt;li&gt;Download the Jetbrains &lt;a href="http://www.jetbrains.net/confluence/download/attachments/37364/wrappers.zip?version=1" target="_blank" title="Direct download link"&gt;devenv wrappers&lt;/a&gt; and change the signature of the Visual Studio shortcut to point to devenv2008_wrap.exe instead of devenv.exe&lt;/li&gt;&lt;li&gt;(of course) Restart the computer&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Update:&lt;br /&gt;Thanks to the warnings from Lex Li, I went to study the &lt;strong&gt;/3G&lt;/strong&gt; switch some more. The most important thing seems to be to also &lt;a href="http://support.microsoft.com/kb/316739/" target="_blank" title="How to use the /userva switch with the /3GB switch to tune the User-mode space to a value between 2 GB and 3 GB"&gt;use the &lt;strong&gt;/USERVA&lt;/strong&gt; switch&lt;/a&gt; to tune the /3G functionality. &lt;br /&gt;&lt;br /&gt;More details here:&lt;br /&gt;&lt;a href="http://blogs.technet.com/askperf/archive/2007/03/23/memory-management-demystifying-3gb.aspx" target="_blank" title="from Ask the Performance Team"&gt;Memory Management - Demystifying /3GB&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/oldnewthing/archive/2004/08/22/218527.aspx" target="_blank" title="from The Old New Thing"&gt;Summary of the recent spate of /3GB articles&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-913975480210109909?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/sn5KMq4PbKI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/913975480210109909/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=913975480210109909" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/913975480210109909?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/913975480210109909?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/sn5KMq4PbKI/get-visual-studio-to-use-better-more.html" title="Get Visual Studio to use (better) more than 2GB of memory" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/11/get-visual-studio-to-use-better-more.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMMSHYyfip7ImA9WxNUFkQ.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-4831451382078585013</id><published>2009-11-02T16:30:00.008+02:00</published><updated>2009-11-08T18:24:49.896+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-08T18:24:49.896+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows Forms" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows API" /><category scheme="http://www.blogger.com/atom/ns#" term="essay" /><title>Things I've learned from HotBabe.NET</title><content type="html">&lt;img style="float:left;margin:0; border:0;width: 134px; height: 200px;" src="http://4.bp.blogspot.com/_6GyQjwWOmQA/Su77m3vkWpI/AAAAAAAAAgA/1pt4YtSYrWM/s400/HotBabe.png" border="0" alt="Rebecca Romijn as the icon of HotBabe" /&gt;&lt;br /&gt;Today &lt;strong&gt;I've released version 1.2 of the &lt;a href="http://hotbabenet.codeplex.com/" target="_blank" title="Get it while it's hot! (get it? :) )"&gt;HotBabe.NET&lt;/a&gt; application&lt;/strong&gt;. It is a program that stays in the traybar, showing a transparent picture, originally of a woman, sitting on top of your other applications. Clicks go through the image and the opacity of the picture is set so that it doesn't bother the use of the computer. When the CPU use or the memory use or other custom measurements change, the image changes as well. The original would show a girl getting naked as the use of CPU went up. Since I couldn't use what images it should use, I did my own program in .NET. This blog post is about what I have learned about Windows Forms while creating this application.&lt;br /&gt;&lt;br /&gt;  &lt;h4&gt;Step 1: Making the form transparent&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;  Making a Windows Form transparent is not as simple as setting the background transparent. It needs to have:&lt;ul&gt;&lt;li&gt;&lt;em&gt;FormBorderStyle = FormBorderStyle.None&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;AllowTransparency = true&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;TransparencyKey = BackColor&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt; However, when changing the &lt;em&gt;Opacity&lt;/em&gt; of the form, I noticed that the background color would start showing! The solution for this is to set the &lt;em&gt;BackColor&lt;/em&gt; to &lt;strong&gt;Color.White&lt;/strong&gt;, as White is not affected by opacity when set as &lt;em&gt;TransparencyKey&lt;/em&gt;, for some reason.&lt;br /&gt;&lt;br /&gt;  &lt;h4&gt;Step 2: Making the form stay on top all other windows&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;  That is relatively easy. Set &lt;em&gt;TopMost = true&lt;/em&gt;. You have to set it to true the first time, during load, otherwise you won't be able to set it later on. I don't know why, it just happened.&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;Update:&lt;/em&gt; I noticed that, even when TopMost was set, the image would vanish beneath other windows. I've doubled the property with setting &lt;strong&gt;WS_EX_TopMost&lt;/strong&gt; on the params ExStyle (see step 4).&lt;br /&gt;&lt;br /&gt;  &lt;h4&gt;Step 3: Show the application icon in the traybar and hide the taskbar&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;  Hiding the taskbar is as easy as &lt;em&gt;ShowInTaskbar = false&lt;/em&gt; and putting a notification icon in the traybar is simple as well: &lt;pre&gt;_icon = new NotifyIcon(new Container())&lt;br /&gt;{&lt;br /&gt;    Visible = true&lt;br /&gt;};&lt;/pre&gt;  Set the &lt;em&gt;ContextMenu&lt;/em&gt; to &lt;em&gt;_icon&lt;/em&gt; and you have a tray icon with a menu. There is a catch, though. A &lt;em&gt;NotifyIcon&lt;/em&gt; control needs an &lt;em&gt;Icon&lt;/em&gt;, an image of a certain format. My solution was, instead of bundling an icon especially for this, to convert the main girl image into an icon, so I used &lt;a href="http://www.dreamincode.net/code/snippet1684.htm" target="_blank" title="Convert Image to Icon in C#"&gt;this code&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;  &lt;h4&gt;Step 4: Hide the application from Alt-Tab, make it not get focus and make it so that the mouse clicks through&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;  In order to do that, something must be done at the &lt;strong&gt;PInvoke&lt;/strong&gt; level, in other words, using unsafe system libraries. At first I found out that I need to change a flag value which can be read and written to using &lt;em&gt;GetWindowLong&lt;/em&gt; and &lt;em&gt;SetWindowLong&lt;/em&gt; from &lt;strong&gt;user32.dll&lt;/strong&gt;. I needed to set the window style with the following attributes:&lt;br /&gt;&lt;em&gt;WS_EX_Layered&lt;/em&gt; (Windows Xp/2000+ layered window)&lt;br /&gt;&lt;em&gt;WS_EX_Transparent&lt;/em&gt; (Allows the windows to be transparent to the mouse)&lt;br /&gt;&lt;em&gt;WS_EX_ToolWindow&lt;/em&gt; (declares the window as a tool window, therefore it does not appear in the Alt-Tab application list)&lt;br /&gt;&lt;em&gt;WS_EX_NoActivate&lt;/em&gt; (Windows 2000/XP: A top-level window created with this style does not become the foreground window when the user clicks it).&lt;br /&gt;&lt;br /&gt;  Then I found out that Form has a virtual method called &lt;em&gt;CreateParams&lt;/em&gt; giving me access to the style flag value. Here is the complete code:&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; CreateParams CreateParams&lt;br /&gt;    {&lt;br /&gt;      get&lt;br /&gt;      {&lt;br /&gt;        CreateParams ws = &lt;span class="kwrd"&gt;base&lt;/span&gt;.CreateParams;&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (ClickThrough)&lt;br /&gt;        {&lt;br /&gt;          ws.ExStyle |= UnsafeNativeMethods.WS_EX_Layered;&lt;br /&gt;          ws.ExStyle |= UnsafeNativeMethods.WS_EX_Transparent;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="rem"&gt;// do not show in Alt-tab&lt;/span&gt;&lt;br /&gt;        ws.ExStyle |= UnsafeNativeMethods.WS_EX_ToolWindow;&lt;br /&gt;        &lt;span class="rem"&gt;// do not make foreground window&lt;/span&gt;&lt;br /&gt;        ws.ExStyle |= UnsafeNativeMethods.WS_EX_NoActivate;&lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; ws;&lt;br /&gt;      }&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    However, the problem was that if I changed &lt;em&gt;ClickThrough&lt;/em&gt;, it didn't seem to do anything. It was set once and that was it. I noticed that changing &lt;em&gt;Opacity&lt;/em&gt; would also set the click through style, so I Reflector-ed the &lt;strong&gt;System.Windows.Forms.dll&lt;/strong&gt; and looked in the source of &lt;em&gt;Opacity&lt;/em&gt;. Something called &lt;em&gt;UpdateStyles&lt;/em&gt; was used (This method calls the &lt;em&gt;CreateParams&lt;/em&gt; method to get the styles to apply) so I used it.&lt;br /&gt;&lt;br /&gt;   &lt;em&gt;Update:&lt;/em&gt; Apparently, the no activate behaviour can also be set by overriding ShowWithoutActivation and returning true. I've set it, too, just to be sure.&lt;br /&gt;&lt;br /&gt;    &lt;h4&gt;Step 5: Now that the form is transparent and has no border or control box,  I can't move the window around. I need to make it draggable from anywhere&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;   There is no escape from native methods this time:&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; mainMouseDown(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, MouseEventArgs e)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="rem"&gt;// Draggable from anywhere&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;if&lt;/span&gt; (e.Button == MouseButtons.Left)&lt;br /&gt;  {&lt;br /&gt;    UnsafeNativeMethods.ReleaseCapture();&lt;br /&gt;    UnsafeNativeMethods.SendMessage(Handle, &lt;br /&gt;    UnsafeNativeMethods.WM_NCLBUTTONDOWN,&lt;br /&gt;    UnsafeNativeMethods.HT_CAPTION, 0);&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt; Both &lt;em&gt;ReleaseCapture&lt;/em&gt; and &lt;em&gt;SendMessage&lt;/em&gt; are &lt;strong&gt;user32.dll&lt;/strong&gt; functions. What this mouse down event handler does is say to the Window that no matter where it was clicked, it actually clicked the draggable area.&lt;br /&gt;&lt;br /&gt;  &lt;h4&gt;Step 6: Remove flicker&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;  Well, I am getting a bit ahead of myself, here, the flickering becomes annoying only when I implement the blending of an image into another, but since it is also a style setting, I am putting it here:&lt;pre class="csharpcode"&gt;&lt;br /&gt;SetStyle(ControlStyles.AllPaintingInWmPaint &lt;br /&gt;       | ControlStyles.UserPaint&lt;br /&gt;       | ControlStyles.OptimizedDoubleBuffer, &lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;/pre&gt;This piece of code, placed in the &lt;em&gt;Form&lt;/em&gt; constructor, tells the form to use a double buffer for drawing and to not clear the form before drawing something else.&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;Update:&lt;/em&gt; It seems the same thing can be achieved by setting the Control property &lt;strong&gt;DoubleBuffer&lt;/strong&gt; to &lt;strong&gt;true&lt;/strong&gt; as it seems to be setting &lt;em&gt;ControlStyles.OptimizedDoubleBuffer&lt;/em&gt; | &lt;em&gt;ControlStyles.AllPaintingInWmPaint&lt;/em&gt; and &lt;em&gt;ControlStyles.UserPaint&lt;/em&gt; seems to be set by default.&lt;br /&gt;&lt;br /&gt;  &lt;h4&gt;Step 7: Blend the images one into the other&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;  Well, in order to make an image blend nicely into the next, I used a &lt;em&gt;Timer&lt;/em&gt;. 10 times a second I would decrease the opacity of the first, increase the opacity of the second and draw them one over the other.&lt;br /&gt;&lt;br /&gt;  A small detour: if you think about it, this is not absolutely correct. A 70% opacity pixel blocks 70% of the light and lets 30% of the image behind show. If the image underneath has 30% opacity, then it shows 30% left from 30% of the image and it doesn't get opaque. But if I just set the opacity of the bakground image to 100%, it shows really strong on the parts of the images that are not overlapping, where image1 is transparent and image2 is not.&lt;br /&gt;&lt;br /&gt;  Unfortunately there is no resource friendly way to read write/pixels. It's either &lt;em&gt;GetPixel/SetPixel&lt;/em&gt; in a &lt;em&gt;Bitmap&lt;/em&gt; class (which are very slow) or using pinvoke again. I prefered to use the opacity hack which looks ok.&lt;br /&gt;&lt;br /&gt;I was already using an extension method to invoke any change on the form on its own thread (as the &lt;em&gt;Timer&lt;/em&gt; ran on its own thread and I would have gotten the "&lt;em&gt;Cross-thread operation not valid: Control [...] accessed from a thread other than the thread it was created on&lt;/em&gt;" exception or "&lt;em&gt;Invoke or BeginInvoke cannot be called on a control until the window handle has been created&lt;/em&gt;"):&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SafeInvoke(&lt;span class="kwrd"&gt;this&lt;/span&gt; Control control, Action action)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="kwrd"&gt;if&lt;/span&gt; (control.IsDisposed)&lt;br /&gt;  {&lt;br /&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt;;&lt;br /&gt;  }&lt;br /&gt;  &lt;span class="kwrd"&gt;if&lt;/span&gt; (!control.IsHandleCreated)&lt;br /&gt;  {&lt;br /&gt;    &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;      action();&lt;br /&gt;    }&lt;br /&gt;    &lt;span class="kwrd"&gt;catch&lt;/span&gt; (InvalidOperationException ex)&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt;;&lt;br /&gt;  }&lt;br /&gt;  &lt;span class="kwrd"&gt;if&lt;/span&gt; (control.InvokeRequired)&lt;br /&gt;  {&lt;br /&gt;    control.BeginInvoke(action);&lt;br /&gt;  }&lt;br /&gt;  &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;  {&lt;br /&gt;    action();&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;  This is where I got the "&lt;strong&gt;Object is currently in use elsewhere&lt;/strong&gt;" &lt;em&gt;InvalidOperationException&lt;/em&gt;. Apparently the &lt;em&gt;Image&lt;/em&gt; class is not thread-safe, so both the timer and the form were trying to access it. I tried &lt;strong&gt;&lt;em&gt;lock&lt;/em&gt;&lt;/strong&gt;ing the setter and getter of the Image property on the class responsible with the image blending effect, with no real effect. Strangely enough, the only solution was to &lt;em&gt;Clone&lt;/em&gt; the image when I move it around. I am still looking for a solution that makes sense!&lt;br /&gt;&lt;br /&gt;  &lt;h4&gt;Step 8: Showing the window while dragging it&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;  Using WS_EX_NOACTIVATE was great, but there is a minor inconvenience when trying to move the form around. Not only that the image is not shown while moving the form (On my computer it is set to not show the window contents while dragging it), but the rectangular hint that normally shows is not displayed either. The only way to know where your image ended up was to release the mouse button.&lt;br /&gt;&lt;br /&gt;  It appears that fixing this is not so easy as it seems. One needs to override &lt;strong&gt;WndProc&lt;/strong&gt; and handle the &lt;strong&gt;WM_MOVING&lt;/strong&gt; message. While handling it, a manual redraw of the form must be initiated via the &lt;em&gt;user32.dll&lt;/em&gt; &lt;strong&gt;SetWindowPos&lt;/strong&gt; method.&lt;br /&gt;&lt;br /&gt;  The nice part is that in this method you can actually specify how you want the form draw. I have chosen &lt;em&gt;SWP_NoActivate&lt;/em&gt;, &lt;em&gt;SWP_ShowWindow&lt;/em&gt; and &lt;em&gt;SWP_NoSendChanging&lt;/em&gt; as flags, where NoActivate is similar with the exstyle flag, ShowWindow shows the entire form (not only the rectangle hint) and NoSendChanging seems to improve the movement smoothness.&lt;br /&gt;&lt;br /&gt;  Quirky enough, if I start the application without &lt;em&gt;Click through&lt;/em&gt; set, then the rectangle hint DOES appear while dragging the window. And with my fix, both the image and the rectangle are shown, but not at the same time. It is a funny effect I don't know how to fix and I thought it was strange enough to not bother me: the rectangle is trying to keep up with the hot babe and never catches on :)&lt;br /&gt;&lt;br /&gt;  &lt;h4&gt;Step 9: Dragging custom images&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;  I am a programmer, that means that it is likely to add too many features in my creations and never make any money out of them. That's why I've decided to add a new feature to HotBabe.NET: droppping your own images on it to display over your applications. &lt;br /&gt;&lt;br /&gt;  At first I have solved this via ExStyle, where a flag tells Windows the form accepts files dragged over it. A WndProc override handling the WM_DROPFILES message would do the rest. But then I've learned that Windows Forms have their own mechanism for handling file drops.&lt;br /&gt;&lt;br /&gt;  Here are the steps. First set &lt;strong&gt;AllowDrop&lt;/strong&gt; to &lt;em&gt;true&lt;/em&gt;. Then handle the &lt;strong&gt;DragEnter&lt;/strong&gt; and &lt;strong&gt;DragDrop&lt;/strong&gt; events. In my implementation I am checking that only one file is being dropped and that the file itself can be converted into an image BEFORE I display the mouse cursor hint telling the user a drop is allowed. That pretty much makes the ugly &lt;strong&gt;MessageBox&lt;/strong&gt; that I was showing in the previous implementation unnecessary.&lt;br /&gt;&lt;br /&gt;  The rest are details and you can download the source of HotBabe.NET and see the exact implementation. Please let me know what you think and of any improvement you can imagine.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-4831451382078585013?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/OqPYRXmhrik" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/4831451382078585013/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=4831451382078585013" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/4831451382078585013?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/4831451382078585013?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/OqPYRXmhrik/things-ive-learned-from-hotbabenet.html" title="Things I've learned from HotBabe.NET" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_6GyQjwWOmQA/Su77m3vkWpI/AAAAAAAAAgA/1pt4YtSYrWM/s72-c/HotBabe.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/11/things-ive-learned-from-hotbabenet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQFRHY8eip7ImA9WxNVFUg.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-6192825811124445615</id><published>2009-10-26T13:31:00.002+02:00</published><updated>2009-10-26T13:41:55.872+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-26T13:41:55.872+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="CodePlex" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>HotBabe.NET a new project at CodePlex</title><content type="html">I've stumbled upon this &lt;a href="http://hotbabe.planlos.org/" target="_blank" title="Hot-Babe for Windows"&gt;Windows port&lt;/a&gt; of a &lt;a href="http://dindinx.net/hotbabe/" target="_blank" title="Hot-Babe"&gt;Linux application&lt;/a&gt; called HotBabe. What it does is show a transparent image of a girl over your applications that looks more naked as the CPU is used more. I wanted to use my own pictures and explore some of the concepts of desktop programming that are still a bit new to me, so I rewrote it from scratch.&lt;br /&gt;&lt;br /&gt;  The project is now up on &lt;a href="http://hotbabenet.codeplex.com/" target="_blank" title="Project page for HotBabe.NET"&gt;CodePlex&lt;/a&gt; and is functional. Please report any bugs or write any feature requests here or on the project page in order to make this even cooler.&lt;br /&gt;&lt;br /&gt;  Features:&lt;ul&gt;&lt;li&gt;Custom images responding to custom measurements&lt;/li&gt;&lt;li&gt;Custom measures (included are Cpu, Memory and Random, but an abstract class for custom monitor classes is included)&lt;/li&gt;&lt;li&gt;AutoRun, ClickThrough, Opacity control&lt;/li&gt;&lt;li&gt;Interface for custom images and custom monitors&lt;/li&gt;&lt;li&gt;XML config file&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;  Additional remarks: yeah, I know, the advanced settings form is really bad, but I am not one for good interface design. Please help with improving the program if you feel you can do better. Also, the blending images effect and command line settings are not yet implemented. I am working on a restructured version of the application.&lt;br /&gt;&lt;br /&gt;  Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-6192825811124445615?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/zOsR1NCcyKY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/6192825811124445615/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=6192825811124445615" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/6192825811124445615?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/6192825811124445615?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/zOsR1NCcyKY/hotbabenet-new-project-at-codeplex.html" title="HotBabe.NET a new project at CodePlex" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/hotbabenet-new-project-at-codeplex.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08HRX49eyp7ImA9WxNVFUg.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-3030644090824830947</id><published>2009-10-26T13:02:00.004+02:00</published><updated>2009-10-26T13:17:14.063+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-26T13:17:14.063+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><category scheme="http://www.blogger.com/atom/ns#" term="books" /><category scheme="http://www.blogger.com/atom/ns#" term="picture" /><title>Dexter by Design by Jeff Lindsay</title><content type="html">&lt;img style="float:left; margin:0; border:none;width: 155px; height: 240px;" src="http://4.bp.blogspot.com/_6GyQjwWOmQA/SuWFAuQandI/AAAAAAAAAf4/gqNu6XwIRV8/s400/DexterByDesign.jpg" border="0" alt="Book Cover" /&gt;  After the horrible dissappointment with the third book from the Dexter series by &lt;a href="http://en.wikipedia.org/wiki/Jeff_Lindsay_(writer)" target="_blank" title="pen name of American playwright and crime novelist Jeffry P. Freundlich"&gt;Jeff Lindsay&lt;/a&gt;, I even forgot there was a fourth book coming. Thanks to my friend &lt;a href="http://skynetsoftware.net/" target="_blank" title="Not a very active blogger, I know"&gt;Meaflux&lt;/a&gt;, who kindly remembered me to not miss on my education as a serial killer, I found out the fourth book, &lt;a href="http://en.wikipedia.org/wiki/Dexter_by_Design" target="_blank" title="The major themes of this particular novel are the arts, specifically modern and experimental art"&gt;Dexter by Design&lt;/a&gt;, was out and, (&lt;span title="See what I did here? They are both called Jeff :)"&gt;thank you, Jeff!&lt;/span&gt;), without any of the fantasy monster crap that made Dexter in the Dark so bad.&lt;br /&gt;&lt;br /&gt;  Dexter by Design was a really nice book. It captured the dark humour only a geeky psychopath would have, caught in a world of emotional people, it added a lot of tension, it went cursively from start to end. The only problem I could possibly have with it is that it made Dexter look bad, easily surclasses by not one but three people on three separate ocasions.&lt;br /&gt;&lt;br /&gt;  The conclusion is that it was one of the best, if not THE best in the series. Not a lot of killing is done, though, not by Dexter in any case. And if you are wondering, it has no connection with the third season of the Dexter TV series, except for the ending :).&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-3030644090824830947?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/yuTPMEMg8A4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/3030644090824830947/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=3030644090824830947" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/3030644090824830947?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/3030644090824830947?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/yuTPMEMg8A4/dexter-by-design-by-jeff-lindsay.html" title="Dexter by Design by Jeff Lindsay" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_6GyQjwWOmQA/SuWFAuQandI/AAAAAAAAAf4/gqNu6XwIRV8/s72-c/DexterByDesign.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/dexter-by-design-by-jeff-lindsay.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04HSXs7fSp7ImA9WxNVEU4.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-8850345717230419996</id><published>2009-10-17T13:29:00.009+03:00</published><updated>2009-10-21T17:38:58.505+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-21T17:38:58.505+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WPF/Silverlight" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="essay" /><title>Exploring the Model-View-ViewModel pattern</title><content type="html">This will be a long article, one that I intend to add on while understanding more about the MVVM pattern and patterns in general. Also, while I am sure I will add some code during the development of the post, this is intended mostly as a theoretical understanding of the said pattern.&lt;br /&gt;&lt;br /&gt;  For an easy and short explanation of the concepts, read this article: &lt;a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx" title="from Josh Smith, the authority on WPF" target="_blank"&gt;WPF Apps With The Model-View-ViewModel Design Pattern&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;  The start of every concept research these days seems to start with Wikipedia. The wiki article about &lt;a href="http://en.wikipedia.org/wiki/Model_View_ViewModel" title="Don't read it now, though!" target="_blank"&gt;Model View ViewModel&lt;/a&gt; says that MVVM is &lt;em&gt;a specialization of the &lt;a href="http://martinfowler.com/eaaDev/PresentationModel.html" target="_blank" title="Represent the state and behavior of the presentation independently of the GUI "&gt;PresentationModel&lt;/a&gt; design pattern introduced by Martin Fowler specific for the Windows Presentation Foundation (WPF). Largely based on the &lt;a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" target="_blank" title="isolates business logic from input and presentation"&gt;Model-view-controller pattern (MVC)&lt;/a&gt;&lt;/em&gt;.&lt;br /&gt;  Further reading from &lt;a href="http://www.martinfowler.com/eaaDev/uiArchs.html#ModelViewController" target="_blank" title="GUI Architectures"&gt;Martin Fowler's site&lt;/a&gt; on the MVC pattern, which seems to stand at the core of all this specialization, revealed this: &lt;em&gt;Probably the widest quoted pattern in UI development is Model View Controller (MVC) - it's also the most misquoted. [...] In MVC, the domain element is referred to as the model. Model objects are completely ignorant of the UI. [...] The presentation part of MVC is made of the two remaining elements: view and controller. The controller's job is to take the user's input and figure out what to do with it.&lt;/em&gt; There is a lot more there, about how in the early MVC concept there were no events or binding of any sort. Instead the controller would get the input from the UI, update the model, then the View would change as the model changes using some sort of Observer pattern. Even from these few quotes, one can see that in this "holy trinity" there are actually two basic actors: &lt;strong&gt;the Model&lt;/strong&gt; (which, to make it easier to differentiate later on from other models, I will call Data Model) and &lt;strong&gt;the Presentation&lt;/strong&gt; (controller+view in MVC).&lt;br /&gt;  Let's see what the PresentationModel pattern is all about: &lt;em&gt;Presentation Model pulls the state and behavior of the view out into a model class that is part of the presentation. The Presentation Model coordinates with the domain layer and provides an interface to the view that minimizes decision making in the view. The view either stores all its state in the Presentation Model or synchonizes its state with Presentation Model frequently.&lt;/em&gt; As I see it, it introduces a new model, one specific to the Presentation side but independent of the UI controls. Martin Fowler specifically says about the PresentationModel pattern: &lt;em&gt;Probably the most annoying part of Presentation Model is the synchronization between Presentation Model and view. It's simple code to write, but I always like to minimize this kind of boring repetitive code. Ideally some kind of framework could handle this, which I'm hoping will happen some day with technologies like .NET's data binding.&lt;/em&gt; and &lt;em&gt;Presentation Model allows you to write logic that is completely independent of the views used for display. You also do not need to rely on the view to store state. The downside is that you need a synchronization mechanism between the presentation model and the view. This synchronization can be very simple, but it is required.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;  I also find &lt;a href="http://www.ctrl-shift-b.com/2007/08/interactive-application-architecture.html" target="_blank" title="Interactive Application Architecture Patterns"&gt;this article&lt;/a&gt; about different Model View Presenter patterns very informative and the diagrams easier to understand than Fowlers UML or whatever that horrible diagraming he uses is :)&lt;br /&gt;&lt;br /&gt;  This brings us to MVVM. It is basically the PresentationModel pattern, where WPF/Silverlight types of complex binding take care of the synchronization of View and ViewModel. For me, one of the most important aspects of this approach is that the complex interactions between UI components (and that don't involve the data in the DataModel) can be left in the View and completely ignored further down. That makes interchanging Views something very easy to do, as the entire "UI logic" can be separated from the more general presentation logic. In this, I see that the UI becomes a third layer by the introduction of the ViewModel/PresentationModel in between the Data Model and the Presentation.&lt;br /&gt;  I have imagined doing this in a Web or stricly Windows Forms environment. As Fowler said, the plumbing required for synchronization between the view and the viewmodel makes it not worth the effort. That is where the WPF &lt;a href="http://msdn.microsoft.com/en-us/library/ms750612.aspx" target="_blank" title="Windows Presentation Foundation (WPF) data binding provides a simple and consistent way for applications to present and interact with data"&gt;Data Binding&lt;/a&gt; comes in.&lt;br /&gt;&lt;br /&gt;  Let's start the MVVM chapter with a simple example. There is a need to search people by using different filters, display the list of found people and give the ability to click a person and see the details in a separate detail pane. The filters can be simple (Google like textbox) or complex (specific role, age, etc searches). The complex filters of the search are hidden in a separate panel that can be shown or not.&lt;br /&gt;  An ASP.Net or Windows Forms application would probably create a form containing the searchbox, the additional filters in a panel with a checkbox or button to show/hide it, the details panel with textual information and a grid where the list of people would be displayed. Events would provide all the needed plumbing, with the code executed on them placed in the code behind of the form, changing what was needed. See, the code behind was already an attempt to separate the presentation from code, although the separation was mostly symbolic. One might have employed a flavour of the MVC pattern, creating a separate controller class that would have worked with the data model and the form (as a view) through interfaces. That means a lot of plumbing, anyway.&lt;br /&gt;  In WPF, one creates the form, as in the Windows Forms approach above, but then it binds no events (or very few, I will talk about that later). Instead, it uses data binding to link UI components to properties that it expects to find on the object that will be provided to the view as a DataContext, that is the ViewModel. It doesn't know what the format of this object is and, indeed, the properties are found using reflection, which makes this slightly slower than other methods.&lt;br /&gt;  What this means is that any code that reacts to a change of a UI component would be placed on an event handler of the property to which it is bound. When the property changes, stuff happens, not when someone clicks a checkbox. This makes the architecture a lot more testable from code, as all a test needs to do is change a property, not perform a click. It also means that a lot of extra plumbing must be done on those properties, for example the ViewModels could implement INotifyPropertyChanged and then notify on any property being changed. Also lists must not only inform on the get/set operations on them, but also on their items, which implies using ObservableCollection, ObservableDictionary, BindingList and other objects that observer their items and notify on change. On the Views, &lt;a href="http://joshsmithonwpf.wordpress.com/2007/05/16/demystifying-dependency-properties/" target="_blank" title="Demystifying dependency properties"&gt;Dependency&lt;/a&gt; and &lt;a href="http://joshsmithonwpf.wordpress.com/2007/06/22/overview-of-attached-properties-in-wpf/" target="_blank" title="http://joshsmithonwpf.wordpress.com/2007/06/22/overview-of-attached-properties-in-wpf/"&gt;Attached&lt;/a&gt; properties come into play , and I will link to some explanatory posts later on. They are extremely important in WPF, because they compute the value, rather than store it, but that's another story altogether.&lt;br /&gt;  What this also means is that events, in the way there are used in Windows Forms scenarios, are almost a hinderance. Events cannot be bound. If they are handled in bits of code that change properties in the ViewModel, then the code must either have a reference to a specific type of ViewModel, which defeats the whole purpose of MVVM, or to read/write properties using reflection, which means extra plumbing in the View code. Not that this cannot be done, and there are several solutions to that. However, it would be ugly to write a view completely in XAML, binding everything you need to properties that are to be found on the ViewModel, then starting writing code just for a few events. Here is where commands come in.&lt;br /&gt;  The &lt;a href="http://en.wikipedia.org/wiki/Command_pattern" target="_blank" title="an object is used to represent and encapsulate all the information needed to call a method at a later time."&gt;Command pattern&lt;/a&gt; is an &lt;a href="http://en.wikipedia.org/wiki/Design_Patterns_(book)" target="_blank" title=""&gt;Gang of Four pattern&lt;/a&gt;, useful in WPF by providing objects that can be bound and that encapsulate a behaviour that will be executed. Read more about &lt;a href="http://msdn.microsoft.com/en-us/library/ms752308.aspx" target="_blank" title="Commanding overview"&gt;Commanding on MSDN&lt;/a&gt;. Many WPF controls exposes events as well as commands for common actions, for example the Button class exposes the OnClick event, but also the Command property (which will be executed on click) and the Clicked property (which will be set on click).&lt;br /&gt;  Commands in WPF implement the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.aspx" target="_blank" title="MSDN reference"&gt;ICommand interface&lt;/a&gt; which exposes the Execute method as well as the CanExecute method. A default WPF button that has a command bound to its Command member will appear as disabled if the CanExecute method returns false, that because the ButtonBae class implements ICommandSource. More about commands when I present the RelayCommand class, which has become quite commonplace in the MVVM world.&lt;br /&gt;  A problem is that not all controls have a command for every concievable event. A solution is, of course, to inherit from the control and create your own command for a specific event. It only requires that you handle the event internally, expose a property that implements ICommand and execute that command inside the event handler. This brings the advantage that the control can be reused with minimal changes in the XAML. There are other solutions, one of them is to &lt;a href="http://blogs.microsoft.co.il/blogs/tomershamam/archive/2009/04/14/wpf-commands-everywhere.aspx" target="_blank" title="WPF Commands Everywhere"&gt;use Attached Properties&lt;/a&gt;. If you don't want an attached property for every event that you use, read &lt;a href="http://marlongrech.wordpress.com/2008/12/04/attachedcommandbehavior-aka-acb/" target="_blank" title="AttachedCommandBehavior aka ACB"&gt;this article&lt;/a&gt;. A very comprehensive article about the application of Commanding in WPF can be found here: &lt;a href="http://www.codeproject.com/KB/WPF/WpfCommandPatternApplied.aspx" target="_blank" title="By Jani Giannoudis"&gt;WPF Command-Pattern Applied&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;  So far so good. Using the concepts above we can separate the UI from the data completely, as the View only uses binding on the Data Model and can be replaced with any other View that binds to existing properties. This pattern can be used on any level, be it the window or the user control level. Controls that are strictly UI, of course, don't need to implement MVVM. There are other aspects that were not covered here, more specific to WPF, like Routed Commands and Events and concepts like global messaging. But since they are not really part of the MVVM idea, I will leave them for other posts.&lt;br /&gt;  There is also the question of code. I will not be doing any in the post for now. However, I will be ending this with a few links that seem relevant.&lt;br /&gt;&lt;br /&gt;  Extra links:&lt;br /&gt;&lt;a href="http://geekswithblogs.net/HouseOfBilz/archive/2009/06/19/adventures-in-mvvm----ball-of-mud-vs-mvvm.aspx" target="_blank" title="Comparative sample between MVVM and unstructured WPF apps"&gt;Adventures in MVVM -- Ball of Mud vs MVVM&lt;/a&gt;&lt;br /&gt;&lt;a href="http://weblogs.asp.net/craigshoemaker/archive/2009/02/26/hands-on-model-view-viewmodel-mvvm-for-silverlight-and-wpf.aspx" target="_blank" title="Videos on comparing MVVM on WPF and Silverlight"&gt;Hands-On Model-View-ViewModel (MVVM) for Silverlight and WPF&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/KB/WPF/ExploringWPFMVVM.aspx" target="_blank" title="By Karl Shifflett"&gt;Exploring a Model-View-ViewModel Application; WPF Password Manager, Cipher Text&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;  Another important thing to consider is the myriad MVVM frameworks out there, all of them implementing some helper classes and prewiring of applications. I was talking earlier about the RelayCommand. Imagine you want to create a ViewModel that exposes a Command. That command would need to implement ICommand, therefore being an object that has two methods: one to execute and the other to determine if it is possible. Creating a class for each such command would be tedious. The RelayCommand is a generic class of T (where T is the type of the command parameter) with a constructor that accepts an Action of T and a Func of T. You instantiate it with the methods in your class that are to be used and that is it.&lt;br /&gt;&lt;br /&gt;  I will update this material with more information as it becomes available and if I have enough time for it.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-8850345717230419996?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/V5BIJGqqA9U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/8850345717230419996/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=8850345717230419996" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/8850345717230419996?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/8850345717230419996?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/V5BIJGqqA9U/exploring-model-view-viewmodel-pattern.html" title="Exploring the Model-View-ViewModel pattern" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/exploring-model-view-viewmodel-pattern.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4NRXY-eCp7ImA9WxNWFk0.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-2366303014750811525</id><published>2009-10-15T12:09:00.004+03:00</published><updated>2009-10-15T13:03:14.850+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-15T13:03:14.850+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="web design" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Script elements with height (and scrollbar issues)</title><content type="html">I've encountered this situations a couple of times, what happends is that, at the end of the body of the document or of a major element like a &lt;em&gt;form&lt;/em&gt; or a page wide &lt;em&gt;div&lt;/em&gt;, sometimes (I haven't really been able to reproduce it at will) &lt;strong&gt;hidden elements start having height&lt;/strong&gt;. The includes hidden divs and spans and even script elements. It seems to be happening mostly on Internet Explorer, but the behaviour has reportedly also been found on Opera and even Chrome.&lt;br /&gt;&lt;br /&gt;  For a specific example, I had this page with a lot of script tags at the end of the &lt;em&gt;form&lt;/em&gt; element. Curiously, only when some &lt;em&gt;span&lt;/em&gt;s with &lt;em&gt;display:none&lt;/em&gt; were added at the end of the &lt;em&gt;body&lt;/em&gt; element the problem would become evident as the height of the page would increase by &lt;strong&gt;12px&lt;/strong&gt; and a vertical scrollbar would appear. I also encountered the issue when I moved, via script, the calendar popup &lt;em&gt;div&lt;/em&gt; for a datetime editor at the end of the &lt;em&gt;body&lt;/em&gt; element to solve a positioning issue. Both were happening in "&lt;strong&gt;quirks mode&lt;/strong&gt;" because I am forced to use a &lt;strong&gt;HTML 4.01 Transitional doctype&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;  To me it seems that the browser considers that &lt;em&gt;script&lt;/em&gt; tags have no layout, so there is no problem to put them all one above the other in that extra 12px bit, but it does consider it needs to reserve that 12px space. Well, does it have layout or doesn't it?&lt;br /&gt;&lt;br /&gt;  I looked on the web for people with similar problems and I have encountered very few that actually tackled it. Here is one example of a solution from the Perishable Press blog: &lt;a href="http://perishablepress.com/press/2007/11/12/prevent-javascript-elements-from-breaking-page-layout/" target="_blank" title="Great solution if you can implement it"&gt;Prevent JavaScript Elements from Breaking Page Layout when Following Yahoo Performance Tip #6: Place Scripts at the Bottom&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;  For short, the solution in the above link is to &lt;strong&gt;place all the scripts at the end of the page, but inside a hidden div element&lt;/strong&gt;. If you have access to all the layout, that is a great solution. However, I found that I could not use it, since the scripts were not added by me and I had no control over their placements. So I found an alternative solution, after noticing that the extra size would dissappear if the popup div of a control was shown.&lt;br /&gt;&lt;br /&gt;  Well, my solution is quite obvious: if there are issues with hidden and script elements placed at the end of the page, then why not &lt;strong&gt;try to add an element at the end of the page and thus make hidden elements NOT be at the end&lt;/strong&gt;? :)&lt;br /&gt;&lt;br /&gt;  A short jQuery script did it for me:&lt;pre&gt;$('script').each(function() { &lt;br /&gt;if ($(this).height()&amp;gt;0 &amp;&amp; !$('form').children(':last').is('div.scrollFix'))&lt;br /&gt;  $(this).parent().append('&amp;lt;div style=\'position:absolute;background:transparent;width:0px;height:0px;line-height:0px;font-size:1px;\' class=\'scrollFix\' /&amp;gt;'); &lt;br /&gt;});&lt;/pre&gt;or, in normal Javascript:&lt;pre&gt;var scripts=document.getElementsByTagName('script');&lt;br /&gt;for (var i=0; i&amp;lt;scripts.length; i++) {&lt;br /&gt;  var script=scripts[i];&lt;br /&gt;  var parent=script.parentNode;&lt;br /&gt;  var lastChild;&lt;br /&gt;  if (parent&amp;&amp;parent.childNodes.length&amp;gt;0)&lt;br /&gt;    lastChild=parent.childNodes[parent.childNodes.length-1];&lt;br /&gt;  var isFixed=(lastChild&amp;&amp;lastChild.tagName&amp;&amp;lastChild.tagName.toLowerCase()=='div'&amp;&amp;lastChild.className=='scrollFix');&lt;br /&gt;  if (script.offsetHeight&amp;gt;0&amp;&amp;!isFixed) {&lt;br /&gt;    var div=document.createElement('&amp;lt;div style=\'position:absolute;background:transparent;width:0px;height:0px;line-height:0px;font-size:1px;\' class=\'scrollFix\' /&amp;gt;');&lt;br /&gt;    parent.appendChild(div);&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  The script is improved by actually scanning the last element of the parent element for the hidden div so that it doesn't add a zillion divs, one for each script tag. However, it doesn't cover the situation where other elements, rather than the script elements, cause the problem. However, the principle remains sound.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-2366303014750811525?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/R4BpPOU6lNk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/2366303014750811525/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=2366303014750811525" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/2366303014750811525?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/2366303014750811525?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/R4BpPOU6lNk/script-elements-with-height-and.html" title="Script elements with height (and scrollbar issues)" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/script-elements-with-height-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YESXs_fip7ImA9WxNWFUQ.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-1199717395548501236</id><published>2009-10-15T10:10:00.002+03:00</published><updated>2009-10-15T10:18:28.546+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-15T10:18:28.546+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="web design" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>CSS Differences in Internet Explorer 6, 7 and 8</title><content type="html">A very informative article, one that examines the differences of CSS interpretation between versions of Internet Explorer (and ignores any other browser), appeared yesterday in Smashing Magazine. Since I found it very informative, I am blogging the link to it: &lt;a href="http://www.smashingmagazine.com/2009/10/14/css-differences-in-internet-explorer-6-7-and-8/" target="_blank" title="By Louis Lazaris"&gt;CSS Differences in Internet Explorer 6, 7 and 8&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-1199717395548501236?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/bDhx-zqeyxY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/1199717395548501236/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=1199717395548501236" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/1199717395548501236?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/1199717395548501236?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/bDhx-zqeyxY/css-differences-in-internet-explorer-6.html" title="CSS Differences in Internet Explorer 6, 7 and 8" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/css-differences-in-internet-explorer-6.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIDRHY8eSp7ImA9WxNWE0o.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-5831432938324642396</id><published>2009-10-12T22:21:00.003+03:00</published><updated>2009-10-12T22:42:55.871+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-12T22:42:55.871+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><category scheme="http://www.blogger.com/atom/ns#" term="books" /><category scheme="http://www.blogger.com/atom/ns#" term="picture" /><title>The God of Clocks by Alan Campbell</title><content type="html">&lt;img style="float:right; margin 0; border none; width: 263px; height: 400px;" src="http://2.bp.blogspot.com/_6GyQjwWOmQA/StOGI2FFq1I/AAAAAAAAAfw/jAAB3-37Fug/s400/godOfClocks.jpg" border="0" alt="Book cover"/&gt;The last book (in story time) in the Deepgate Codex series, God of Clocks was a huge disappointment. It started nicely enough, preparing us for epic battles of wit and weirdness. Reading it, I was about to forget all about the slight drop in quality in the second book, Iron Angel, and was preparing for something grand. Then Mr. Campbell did what he never should have done: he altered the time space continuum. Before I knew it I was thinking at that old sci-fi movie where a ship boards another ship while in hyperspace and because of chaotical relativistic effects they all end up getting old, then young, then meeting themselves, fighting along their older grandsons, fighting the enemy with sticks and so on. For the love of God, I don't remember the name and I did Google it, but got only crap pages.&lt;br /&gt;&lt;br /&gt;  Anyway, Mr. Campbell, haven't you watched sci fi movies until now? Haven't you read a lot of SF books that make the same mistake, drowning in their own pool of possibilities. Time travel, unless it is the main subject, always messes up a story. And I was already confused with all the gods that were nothing more than angels with over inflated egos that anyone could capture and kill, the assassin that turned into mother-do-good, the boy demon who thought John Anchor was his father and that little child that is older and more powerful than him... so all this became very jumbled. No wonder a lot of the threads just remained hanging. What happened to Devon? Who the hell was the little girl? What did Carnival do? Everything just got negated by a race towards the beginning of time, when Ayen blocked the gates of Heaven. And then poof! A lot of fast scan scenes and the book ended. The fight never took place, or if it did, it was never described. And don't worry, if you preferred any other ending, there must be a broken timeline floating like a disolving icecube in a water glass that you can climb on and enjoy whatever reality you desire.&lt;br /&gt;&lt;br /&gt;  This book must be one of the most (if not THE most) WTF book I have ever read. In the end I was pacing, swearing and regretting my lost time. If the Deepgate Codex series would have been a video game, it would have never been released, with all the lack of documentation and obvious bugs.&lt;br /&gt;&lt;br /&gt;  My conclusion: what a nice beginning with Scar Night, but what a faltering fiasco up to and through God of Clocks. It did manage to make me think of a book where the main character would be Carnival, and all the rest would be just detail. I just loved her character and I feel so unfulfilled because it was never properly developed.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-5831432938324642396?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/WSilo-qPROE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/5831432938324642396/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=5831432938324642396" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/5831432938324642396?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/5831432938324642396?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/WSilo-qPROE/god-of-clocks-by-alan-campbell.html" title="The God of Clocks by Alan Campbell" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_6GyQjwWOmQA/StOGI2FFq1I/AAAAAAAAAfw/jAAB3-37Fug/s72-c/godOfClocks.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/god-of-clocks-by-alan-campbell.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUESXo-eSp7ImA9WxNWE0g.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-193311798485837660</id><published>2009-10-12T16:28:00.002+03:00</published><updated>2009-10-12T16:30:08.451+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-12T16:30:08.451+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><category scheme="http://www.blogger.com/atom/ns#" term="music" /><category scheme="http://www.blogger.com/atom/ns#" term="picture" /><title>Com'on Com'on - Von Bondies</title><content type="html">If you watched one of the episodes of Rescue Me you possibly have noticed that there is a cool song in the opening. It is Com'on Com'on by Von Bondies. Here is a live performance for Letterman's Show:&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Px6zUe3y7c8&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/Px6zUe3y7c8&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-193311798485837660?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/Q2U0yPwqKac" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/193311798485837660/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=193311798485837660" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/193311798485837660?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/193311798485837660?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/Q2U0yPwqKac/comon-comon-von-bondies.html" title="Com'on Com'on - Von Bondies" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/comon-comon-von-bondies.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUEEQnc_fip7ImA9WxNWE0k.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-1414372444141877570</id><published>2009-10-12T13:20:00.002+03:00</published><updated>2009-10-12T13:33:23.946+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-12T13:33:23.946+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WPF/Silverlight" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Resource not found when using Merged Dictionaries in WPF themes</title><content type="html">I was creating this XAML to hold the design of all the controls in a library as a theme (generic.xaml). After a while it just got too big and so I had to use merged dictionaries to split the file into smaller parts.&lt;br /&gt;&lt;br /&gt;  First problem is that you can't just use the name of the file as the source of a ResourceDictionary, you need to specify the assembly name kind of like this:&lt;pre&gt;&amp;lt;ResourceDictionary.MergedDictionaries&amp;gt;&lt;br /&gt;  &amp;lt;ResourceDictionary Source="/Library.Namespace;component/Themes/OneOfMyControls.xaml" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;Notice the keyword &lt;strong&gt;component&lt;/strong&gt;, which is NOT part of the folder or namespace structure.&lt;br /&gt;&lt;br /&gt;  The second problem is when you want to use merged dictionaries and then reuse a style key, for example, that you would expect to just place directly in generic.xaml or in the first merged dictionary. You will soon get a "Resource not found" error. Googling, one notices a lot of people having the same problem, but only in the generic.xaml/themes scenario. The solution is to add the common style file as a merged dictionary &lt;strong&gt;in each of the dictionaries merged in generic.xaml&lt;/strong&gt;. That means that if you have 5 controls that use the same style and you have a xaml file for each control and one for the style, you need to add a MergedDictionaries entry in each of the 5 control files and merge the style xaml there.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-1414372444141877570?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/TaPXNToBrWE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/1414372444141877570/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=1414372444141877570" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/1414372444141877570?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/1414372444141877570?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/TaPXNToBrWE/resource-not-found-when-using-merged.html" title="Resource not found when using Merged Dictionaries in WPF themes" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/resource-not-found-when-using-merged.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUICRXk_eyp7ImA9WxNWE08.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-2262905207499335300</id><published>2009-10-12T08:52:00.002+03:00</published><updated>2009-10-12T09:06:04.743+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-12T09:06:04.743+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><category scheme="http://www.blogger.com/atom/ns#" term="books" /><category scheme="http://www.blogger.com/atom/ns#" term="picture" /><title>Iron Angel by Alan Campbell</title><content type="html">&lt;img style="margin:0; border:none; float:left; width: 170px; height: 280px;" src="http://4.bp.blogspot.com/_6GyQjwWOmQA/StLHFyjA93I/AAAAAAAAAfo/MLeJThnfHJc/s400/deepgate-iron-angel.jpg" border="0" alt="Book cover" /&gt;&lt;A href="http://en.wikipedia.org/wiki/Iron_Angel_(novel)" target="_blank" title="Second book in the Deepgate Codex series"&gt;Iron Angel&lt;/a&gt; starts where &lt;a href="http://siderite.blogspot.com/2009/10/scar-night-by-alan-campbell.html" target="_blank" title="My review of the first book in the series"&gt;Scar Night&lt;/a&gt; left us. Even if the scope of the story now expands tremendously, doing credit to the author's imagination, I didn't feel so good reading it as I did Scar Night. Frankly, I don't know exactly why. It may have to do with the several character groups in the plot, which we follow separately for quite some time and that I know are bound to encounter each other or influence each others destinies. When that fails to happen for a long time, I get nervous. Also, while the description of hell was very nice, I found it difficult to swallow.&lt;br /&gt;&lt;br /&gt;  That doesn't mean it is not still a brilliant story, just that it seemed to falter a little in the middle. Now, almost close to the end of God of Clocks, I can say that the quality will improve, at least as measured from my own level of pleasure, although it doesn't get close to Scar Night yet.&lt;br /&gt;&lt;br /&gt;  I love that Alan Campbell really worked on his characters, making them very different to the formulas we are used to see in the field. Heroes are cowardly and impotent, women are strong, gods are flawed and some characters are simply likeable even if they don't see reason and exist for the sole purpose of physical revenge. &lt;br /&gt;&lt;br /&gt;  I can say that God of Clocks is at least intriguing, although I have to ask myself if the author didn't bite more than he can chew with the new concepts involved. Anyway, that is another post, coming soon on a blog near you.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-2262905207499335300?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/JgMTuZE8228" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/2262905207499335300/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=2262905207499335300" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/2262905207499335300?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/2262905207499335300?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/JgMTuZE8228/iron-angel-by-alan-campbell.html" title="Iron Angel by Alan Campbell" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_6GyQjwWOmQA/StLHFyjA93I/AAAAAAAAAfo/MLeJThnfHJc/s72-c/deepgate-iron-angel.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/iron-angel-by-alan-campbell.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkANRXkzeCp7ImA9WxNWEkg.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-9175636900424872804</id><published>2009-10-11T12:48:00.002+03:00</published><updated>2009-10-11T12:53:14.780+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-11T12:53:14.780+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><category scheme="http://www.blogger.com/atom/ns#" term="news" /><category scheme="http://www.blogger.com/atom/ns#" term="manga" /><title>Inuyasha anime continues story</title><content type="html">&lt;a href="http://siderite.blogspot.com/2007/02/inuyasha-fans-read-on.html" target="_blank" title="This article holds all information about the Inuyasha anime" &gt;A while ago&lt;/a&gt; I was writing of the ending of the anime series, well before the story in the manga, leaving me wanting more. Well, a new series has been started that continues the plot. The English translated first episode of Inuyasha Kanketsu-hen has been released on the 4th of October 2009.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-9175636900424872804?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/34N-kG59ovk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/9175636900424872804/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=9175636900424872804" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/9175636900424872804?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/9175636900424872804?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/34N-kG59ovk/inuyasha-anime-continues-story.html" title="Inuyasha anime continues story" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/inuyasha-anime-continues-story.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEMSH88eSp7ImA9WxNXGU8.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-6243008078713767752</id><published>2009-10-07T18:10:00.002+03:00</published><updated>2009-10-07T18:18:09.171+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-07T18:18:09.171+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="database" /><title>Select and change collation of T-SQL tables and databases</title><content type="html">I could have sworn I wrote a collation article a while ago. Anyway, here are some links:&lt;ul&gt;&lt;li&gt;an article about getting and setting the collation for Transact SQL databases and tables:&lt;a href="http://sqlblogcasts.com/blogs/ssqanet/archive/2008/03/12/tsql-to-change-collation-of-database-whats-new-in-sql-2008-then.aspx" target="_blank" title="from SQL Server Knowledge Sharing Network"&gt;TSQL to change collation of database&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms144250.aspx" target="_blank" title="Selecting a SQL Server Collation"&gt;A list of available collations&lt;/a&gt;&lt;/li&gt;&lt;li&gt;if you get a collation conflict error, you need to collate every join or where like in this example:&lt;em&gt;select * from profile, userinfo&lt;br /&gt;where profile.custid &lt;strong&gt;collate database_default&lt;/strong&gt; = userinfo.custid &lt;strong&gt;collate database_default&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-6243008078713767752?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/h-XJRjOnSO0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/6243008078713767752/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=6243008078713767752" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/6243008078713767752?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/6243008078713767752?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/h-XJRjOnSO0/select-and-change-collation-of-t-sql.html" title="Select and change collation of T-SQL tables and databases" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/select-and-change-collation-of-t-sql.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ENSXszcCp7ImA9WxNXGU8.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-108510601923080305</id><published>2009-10-07T16:36:00.004+03:00</published><updated>2009-10-07T17:28:18.588+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-07T17:28:18.588+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><category scheme="http://www.blogger.com/atom/ns#" term="WPF/Silverlight" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="essay" /><title>Attached properties in Windows Presentation Foundation</title><content type="html">&lt;a href="http://msdn.microsoft.com/en-us/library/ms749011.aspx" target="_blank" title="Attached Properties Overview"&gt;Attached properties&lt;/a&gt; allow you to add new properties and functionality without changing one bit of the code of the affected classes. Attached properties are quite similar to Dependency properties, but they don't need an actual property in the affected object. You have probably worked with one when setting the Grid.Column property of controls inside a WPF Grid.&lt;br /&gt;&lt;br /&gt;  How does one implement it? Well, any class can have the static declaration of an Attached property for any other class. There are decorative attributes that indicate to which specific classes the property should appear in the Visual Studio property window. The caveat here is that if the namespace of the class has not been loaded by VS, the property will not appear, so it is better to place the class containining the property in the same namespace as the classes that the property is attached to.&lt;br /&gt;&lt;br /&gt;  Well, enough with the theory. Here is an example:&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; DependencyProperty SizeModeProperty&lt;br /&gt;    = DependencyProperty.RegisterAttached(&lt;br /&gt;        &lt;span class="str"&gt;"SizeMode"&lt;/span&gt;,&lt;br /&gt;        &lt;span class="kwrd"&gt;typeof&lt;/span&gt; (ControlSize), &lt;span class="kwrd"&gt;typeof&lt;/span&gt; (MyEditor),&lt;br /&gt;        &lt;span class="kwrd"&gt;new&lt;/span&gt; FrameworkPropertyMetadata(&lt;br /&gt;            ControlSize.Custom,&lt;br /&gt;            FrameworkPropertyMetadataOptions.OverridesInheritanceBehavior,&lt;br /&gt;            sizeModeChanged)&lt;br /&gt;        );&lt;br /&gt;&lt;br /&gt;[AttachedPropertyBrowsableForType(&lt;span class="kwrd"&gt;typeof&lt;/span&gt; (TextBox))]&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; ControlSize GetSizeMode(DependencyObject element)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="kwrd"&gt;if&lt;/span&gt; (element == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;  {&lt;br /&gt;    &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="str"&gt;"element"&lt;/span&gt;);&lt;br /&gt;  }&lt;br /&gt;  &lt;span class="kwrd"&gt;return&lt;/span&gt; (ControlSize) element.GetValue(SizeModeProperty);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SetSizeMode(DependencyObject element, ControlSize &lt;span class="kwrd"&gt;value&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="kwrd"&gt;if&lt;/span&gt; (element == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;  {&lt;br /&gt;    &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="str"&gt;"element"&lt;/span&gt;);&lt;br /&gt;  }&lt;br /&gt;  element.SetValue(SizeModeProperty, &lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;  In this piece of code I have just defined a SizeMode property for a class called &lt;strong&gt;MyEditor&lt;/strong&gt;, the default value being &lt;em&gt;ControlSize.Custom&lt;/em&gt;. To use it, I would write in the XAML something like &lt;strong&gt;MyEditor.SizeMode="Large"&lt;/strong&gt; and it would attach to any DependencyObject. The &lt;em&gt;FrameworkPropertyMetadataOptions&lt;/em&gt; flags are important, I will review them later on. This also declares a &lt;strong&gt;sizeModeChanged&lt;/strong&gt; method that will be executed when the SizeMode changes. &lt;br /&gt;&lt;br /&gt;The &lt;em&gt;GetSizeMode&lt;/em&gt; and &lt;em&gt;SetSizeMode&lt;/em&gt; methods are needed for the attached property to work. You might also notice this line: &lt;strong&gt;[AttachedPropertyBrowsableForType(typeof (TextBox))]&lt;/strong&gt;, decorating the getter, which tells Visual Studio to display SizeMode in the properties window of TextBox objects. Another possible attribute is &lt;strong&gt;[AttachedPropertyBrowsableForChildren(IncludeDescendants = true)]&lt;/strong&gt; which tells Visual Studio to display the property for all the children of the control as well.&lt;br /&gt;&lt;br /&gt;  Now, how can this be useful? There are more ways it can.&lt;br /&gt;  One of them is to bind stuff to the property in Triggers or Templates like this: &lt;strong&gt;Binding="{Binding Path=(Controls:MyEditor.SizeMode), RelativeSource={RelativeSource Self}}"&lt;/strong&gt;. This is interesting because one can use in the visual UI properties that are not part of the actual code or ViewModel.&lt;br /&gt;  Another solution is to use the change method, but be careful that the method must consider all possible uses for the property and also it will not work for when you explicitly set the default value (as it doesn't actually change)! Let me detail with a piece of code:&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; sizeModeChanged(DependencyObject d,&lt;br /&gt;    DependencyPropertyChangedEventArgs e)&lt;br /&gt;{&lt;br /&gt;  FrameworkElement elem = d &lt;span class="kwrd"&gt;as&lt;/span&gt; FrameworkElement;&lt;br /&gt;  &lt;span class="kwrd"&gt;if&lt;/span&gt; (elem == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;  {&lt;br /&gt;    &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentException(&lt;br /&gt;      &lt;span class="str"&gt;"Size mode only works on FrameworkElement objects"&lt;/span&gt;);&lt;br /&gt;  }&lt;br /&gt;  &lt;span class="kwrd"&gt;switch&lt;/span&gt; ((ControlSize) e.NewValue)&lt;br /&gt;  {&lt;br /&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; ControlSize.Small:&lt;br /&gt;      elem.Width = 110;&lt;br /&gt;      &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;br /&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; ControlSize.Medium:&lt;br /&gt;      elem.Width = 200;&lt;br /&gt;      &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;br /&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; ControlSize.Large:&lt;br /&gt;      elem.Width = 290;&lt;br /&gt;      &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;br /&gt;    &lt;span class="kwrd"&gt;case&lt;/span&gt; ControlSize.Custom:&lt;br /&gt;      &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;br /&gt;    &lt;span class="kwrd"&gt;default&lt;/span&gt;:&lt;br /&gt;      &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentOutOfRangeException(&lt;span class="str"&gt;"e"&lt;/span&gt;,&lt;br /&gt;        &lt;span class="str"&gt;" ControlSize not supported"&lt;/span&gt;);&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  Here I am setting the Width of a control (provided it is a FrameworkElement) based on the change in SizeMode.&lt;br /&gt;&lt;br /&gt;  Ok, that is almost it. I wanted to shaed some extra light to the &lt;em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkpropertymetadataoptions.aspx" target="_blank" title="follow the link to see them all"&gt;FrameworkPropertyMetadataOptions&lt;/a&gt;&lt;/em&gt; flags. One that is very important is &lt;strong&gt;Inherits&lt;/strong&gt;. If set, the property will apply to all the children of the control that has the property defined. In the example above I first set FrameworkPropertyMetadataOptions.Inherits as a flag and I got an error, because it would try to set the Width to children controls that were not FrameworkElements like Border.&lt;br /&gt;&lt;br /&gt;  Another interesting page that is closely related to this is &lt;a href="http://stackoverflow.com/questions/1531468/ive-created-an-attached-property-now-how-do-i-use-it" target="_blank" title="Look for the Behavior answer"&gt;I’ve created an Attached Property, now how do I use it?&lt;/a&gt; where an Attached property is used in a Behavior, which is actually implemented by the Blend team and, as such it is still in the Expression assembly. Here are two other pages about this:&lt;br /&gt;&lt;a href="http://geekswithblogs.net/lbugnion/archive/2009/04/05/using-a-behavior-to-magnify-your-wpf-applications.aspx" target="_blank" title="by Laurent Bugnion from GalaSoft"&gt;Using a Behavior to magnify your WPF applications&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/johngossman/archive/2008/05/07/the-attached-behavior-pattern.aspx" target="_blank" title="from Tales from the Smart Client"&gt;The Attached Behavior pattern&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-108510601923080305?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/0O-fRxjs8_0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/108510601923080305/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=108510601923080305" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/108510601923080305?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/108510601923080305?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/0O-fRxjs8_0/attached-properties-in-windows.html" title="Attached properties in Windows Presentation Foundation" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/attached-properties-in-windows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ANQ3s5eyp7ImA9WxNXGU0.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-1338107683945637696</id><published>2009-10-07T11:40:00.003+03:00</published><updated>2009-10-07T11:56:32.523+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-07T11:56:32.523+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><category scheme="http://www.blogger.com/atom/ns#" term="books" /><category scheme="http://www.blogger.com/atom/ns#" term="picture" /><title>Scar Night by Alan Campbell</title><content type="html">&lt;img style="width: 261px; height: 400px; float:left; border:none; margin:0px;" src="http://4.bp.blogspot.com/_6GyQjwWOmQA/SsxXhR3QbUI/AAAAAAAAAfg/aaA53fIHLt4/s400/ScarNight.jpg" border="0" alt="Book cover" /&gt;I was reading this interview of the guy from &lt;a href="http://thewertzone.blogspot.com/" target="_blank" title="SF&amp;F In Print &amp; On Screen"&gt;The Wertzone blog&lt;/a&gt;, a Sci-fi and fantasy blog that I enjoy reading, and he recommended some movies and some games and some books. So, on his recommendation, I started reading &lt;a href="http://en.wikipedia.org/wiki/Scar_Night" target="_blank" title="set in the city of Deepgate, a city of pilgrims and priests to Ulcis, God of Chains and Hoarder of Souls"&gt;Scar Night&lt;/a&gt;, by &lt;a href="http://www.alanmcampbell.co.uk/" target="_blank" title="the offical website of fantasy novelist Alan Campbell"&gt;Alan Campbell&lt;/a&gt;, and I have no reason to regret my decision (other than the one I will not be able to read another technical book until I finish the saga).&lt;br /&gt;&lt;br /&gt;  The writing style is nice, although I wouldn't say it rocked my world, however the world the author has envisioned is really great. Imagine a large city built upon great chains of alien metal, suspended over hell itself, inhabited by people worshiping a version of the devil, their church defended by angels called archons and armies of assassins. There is more, but you just have to read the book. What I also enjoyed tremendously is that the characters are very different from one another, ranging from mad scientists to priests corrupted by their desire for the greater good, from good hearted assassins to undead gods and inept cowardly angels.&lt;br /&gt;&lt;br /&gt;  I can only recommend you read this book, the first from the &lt;a href="http://en.wikipedia.org/wiki/Deepgate_Codex" target="_blank" title="The earliest book in Deepgate time is Lye Street, though"&gt;Deepgate Codex&lt;/a&gt; trilogy. Funny enough, the writer, Alan Campbell, was one of the authors of the Grand Theft Auto game, so he is also a software developer. I am hooked.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-1338107683945637696?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/PcrzaugUgAU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/1338107683945637696/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=1338107683945637696" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/1338107683945637696?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/1338107683945637696?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/PcrzaugUgAU/scar-night-by-alan-campbell.html" title="Scar Night by Alan Campbell" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_6GyQjwWOmQA/SsxXhR3QbUI/AAAAAAAAAfg/aaA53fIHLt4/s72-c/ScarNight.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/scar-night-by-alan-campbell.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4DSHY7fSp7ImA9WxNXGEQ.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-1849121184383111356</id><published>2009-10-07T08:16:00.001+03:00</published><updated>2009-10-07T08:22:59.805+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-07T08:22:59.805+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><category scheme="http://www.blogger.com/atom/ns#" term="news" /><category scheme="http://www.blogger.com/atom/ns#" term="books" /><category scheme="http://www.blogger.com/atom/ns#" term="picture" /><title>Peter F. Hamilton answers questions from fans</title><content type="html">Did I mention I love how this guy writes?&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/OFa4s0gRHcw&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en&amp;feature=player_embedded&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/OFa4s0gRHcw&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Rd4ZGcpmMBU&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en&amp;feature=player_embedded&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/Rd4ZGcpmMBU&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-1849121184383111356?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/SCHnDbumU84" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/1849121184383111356/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=1849121184383111356" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/1849121184383111356?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/1849121184383111356?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/SCHnDbumU84/peter-f-hamilton-answers-questions-from.html" title="Peter F. Hamilton answers questions from fans" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/peter-f-hamilton-answers-questions-from.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcCQn0yfip7ImA9WxNXFEQ.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-4316687909791976198</id><published>2009-10-02T18:20:00.002+03:00</published><updated>2009-10-02T18:24:23.396+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-02T18:24:23.396+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="administrative" /><title>Major changes to the blog</title><content type="html">As you may have noticed, I am now working on a new interface for communicating with my blog reader. It features the old Plugoo chat, a whiteboard like interface and a public chat along with administrative news. In the future I will probably also Google Wave.&lt;br /&gt;&lt;br /&gt;That allows for the main blog to get simpler and more information friendly, while the other would serve for interaction with my friends and people that need my help.&lt;br /&gt;&lt;br /&gt;Please leave a comment on any improvements you might want. It is important to me to get this right.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-4316687909791976198?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/8y0wzqVCJs0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/4316687909791976198/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=4316687909791976198" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/4316687909791976198?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/4316687909791976198?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/8y0wzqVCJs0/major-changes-to-blog.html" title="Major changes to the blog" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/10/major-changes-to-blog.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUGSHs8cSp7ImA9WxNXEk8.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-4188556027401942533</id><published>2009-09-29T13:58:00.002+03:00</published><updated>2009-09-29T14:03:49.579+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-29T14:03:49.579+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>How to list the items in a Resource class</title><content type="html">When you want to enumerate through the items in a Resource class, you find that its ResourceManager class doesn't have a method for it, only GetString or GetObject for when you know the key. The solution to get all of the items in a Resource class comes with the GetResourceSet method of the ResourceManager, which returns an IEnumerable class, but not a collection. The enumerator can be of different types, but by default it is a HashTable, therefore the items the enumerator returns are of the type of DictionaryEntry.&lt;br /&gt;&lt;br /&gt;  So the code is as follows:&lt;pre&gt;var resourceSet = ResourceClass.ResourceManager.GetResourceSet(CultureInfo.CurrentCulture, false, true);&lt;br /&gt;foreach (DictionaryEntry resource in resourceSet)&lt;br /&gt;{&lt;br /&gt;    DoSomethingWith(resource.Key, resource.Value);&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-4188556027401942533?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/6xZ-eHEVYcs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/4188556027401942533/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=4188556027401942533" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/4188556027401942533?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/4188556027401942533?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/6xZ-eHEVYcs/how-to-list-items-in-resource-class.html" title="How to list the items in a Resource class" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/09/how-to-list-items-in-resource-class.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AHRH45cSp7ImA9WxNXEUk.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-3556317515630207225</id><published>2009-09-28T16:43:00.004+03:00</published><updated>2009-09-28T16:48:55.029+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-28T16:48:55.029+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="web design" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>There are 19 extra pixels in my scrollHeight and the scroll bar is showing!</title><content type="html">I had this situation where in Internet Explorer, in quirks mode, I would open a dropdown calendar (so showing an absolutely positioned element that was until then hidden) and the &lt;em&gt;scrollHeight&lt;/em&gt; of the entire page would increase by a magical &lt;strong&gt;19px&lt;/strong&gt;. &lt;br /&gt;&lt;br /&gt;  This was caused by a fix for another problem, where the displayed calendar would not position itself under the text input element where it should have positioned, so I made it so that the displayed calendar would be the last child of the body element. This way it would always show in the correct position, but displaying this situation when elements were trying to fit in the height of the page.&lt;br /&gt;&lt;br /&gt;  I could not find the cause other than a problem in the Internet Explorer render engine, but I did find a fix. &lt;strong&gt;Instead of placing it at the end of the body element, place it at the beginning&lt;/strong&gt;. With jQuery that simply translates into: &lt;pre&gt;if (!elem.parent().is('body')) $('body').prepend(elem);&lt;/pre&gt; Notice my use of &lt;em&gt;prepend&lt;/em&gt; instead of &lt;em&gt;append&lt;/em&gt;.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-3556317515630207225?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/gHSk-iN0Mzk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/3556317515630207225/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=3556317515630207225" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/3556317515630207225?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/3556317515630207225?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/gHSk-iN0Mzk/there-are-19-extra-pixels-in-my.html" title="There are 19 extra pixels in my scrollHeight and the scroll bar is showing!" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/09/there-are-19-extra-pixels-in-my.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0ENRn47cSp7ImA9WxNQFkQ.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-5956303267284225159</id><published>2009-09-22T22:05:00.003+03:00</published><updated>2009-09-23T10:41:37.009+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-23T10:41:37.009+03:00</app:edited><title>The Internet as an utopian tool</title><content type="html">It has been a while since I've posted an entry about TED. In case you don't know what it is, go to &lt;strong&gt;&lt;a href="www.ted.com" target="_blank" title="subscribe to the TEB blog, it is worth it!"&gt;ted.com&lt;/a&gt;&lt;/strong&gt; and marvel of the interesting things one can find there. Well, in this post I am going to post two talks about the Internet. One talks about how concepts that would never have worked in real life have caught on in cyberspace (see Wikipedia, where people add information voluntarily, without any remuneration) and the second is about how the Internet can be used by totalitarian(&lt;span title="do they have to be totalitarian? Think about it!"&gt;?&lt;/span&gt;) states to oppress, rather than being a magic tool that spwens democracy. My comments are at the end of the post.&lt;br /&gt;&lt;br /&gt;&lt;object width="446" height="326"&gt;&lt;param name="movie" value="http://video.ted.com/assets/player/swf/EmbedPlayer.swf"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;param name="bgColor" value="#ffffff"&gt;&lt;/param&gt; &lt;param name="flashvars" value="vu=http://video.ted.com/talks/dynamic/JonathanZittrain_2009G-medium.flv&amp;su=http://images.ted.com/images/ted/tedindex/embed-posters/JonathanZittrain-2009G.embed_thumbnail.jpg&amp;vw=432&amp;vh=240&amp;ap=0&amp;ti=640&amp;introDuration=16500&amp;adDuration=4000&amp;postAdDuration=2000&amp;adKeys=talk=jonathan_zittrain_the_web_is_a_random_act_of_kindness;year=2009;theme=the_rise_of_collaboration;theme=speaking_at_tedglobal2009;theme=new_on_ted_com;theme=media_that_matters;event=TEDGlobal+2009;&amp;preAdTag=tconf.ted/embed;tile=1;sz=512x288;" /&gt;&lt;embed src="http://video.ted.com/assets/player/swf/EmbedPlayer.swf" pluginspace="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" wmode="transparent" bgColor="#ffffff" width="446" height="326" allowFullScreen="true" flashvars="vu=http://video.ted.com/talks/dynamic/JonathanZittrain_2009G-medium.flv&amp;su=http://images.ted.com/images/ted/tedindex/embed-posters/JonathanZittrain-2009G.embed_thumbnail.jpg&amp;vw=432&amp;vh=240&amp;ap=0&amp;ti=640&amp;introDuration=16500&amp;adDuration=4000&amp;postAdDuration=2000&amp;adKeys=talk=jonathan_zittrain_the_web_is_a_random_act_of_kindness;year=2009;theme=the_rise_of_collaboration;theme=speaking_at_tedglobal2009;theme=new_on_ted_com;theme=media_that_matters;event=TEDGlobal+2009;"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="446" height="326"&gt;&lt;param name="movie" value="http://video.ted.com/assets/player/swf/EmbedPlayer.swf"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;param name="bgColor" value="#ffffff"&gt;&lt;/param&gt; &lt;param name="flashvars" value="vu=http://video.ted.com/talks/dynamic/EvgenyMorozov_2009G-medium.flv&amp;su=http://images.ted.com/images/ted/tedindex/embed-posters/EvgenyMorozov-2009G.embed_thumbnail.jpg&amp;vw=432&amp;vh=240&amp;ap=0&amp;ti=641&amp;introDuration=16500&amp;adDuration=4000&amp;postAdDuration=2000&amp;adKeys=talk=evgeny_morozov_is_the_internet_what_orwell_feared;year=2009;theme=unconventional_explanations;theme=technology_history_and_destiny;theme=bold_predictions_stern_warnings;event=TEDGlobal+2009;&amp;preAdTag=tconf.ted/embed;tile=1;sz=512x288;" /&gt;&lt;embed src="http://video.ted.com/assets/player/swf/EmbedPlayer.swf" pluginspace="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" wmode="transparent" bgColor="#ffffff" width="446" height="326" allowFullScreen="true" flashvars="vu=http://video.ted.com/talks/dynamic/EvgenyMorozov_2009G-medium.flv&amp;su=http://images.ted.com/images/ted/tedindex/embed-posters/EvgenyMorozov-2009G.embed_thumbnail.jpg&amp;vw=432&amp;vh=240&amp;ap=0&amp;ti=641&amp;introDuration=16500&amp;adDuration=4000&amp;postAdDuration=2000&amp;adKeys=talk=evgeny_morozov_is_the_internet_what_orwell_feared;year=2009;theme=unconventional_explanations;theme=technology_history_and_destiny;theme=bold_predictions_stern_warnings;event=TEDGlobal+2009;"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;I have to say that &lt;a href="http://en.wikipedia.org/wiki/Jonathan_Zittrain" target="_blank" title="professor of Internet law at Harvard Law School"&gt;Jonathan Zittrain&lt;/a&gt;'s talk made me immediately think of &lt;a href="http://en.wikipedia.org/wiki/FidoNet" target="_blank" title="And yes, the name comes from a dog!"&gt;Fidonet&lt;/a&gt;. Long before there was the ubiquitous Internet, amateurs would host Bulletin Board Systems where people could connect and send/read mail, download files and engage in social activities. Actually, one could think even further back, to pirate radio stations, that people would run on their own money (and seldom their own risk) without any chance of a profit.&lt;br /&gt;&lt;br /&gt;So yes, given a method of reducing the cost of help significantly, I think a vast majority of people would help others without considering it a bother. However, to adapt the theory that any altruistic person is helping others because of personal reasons, therefore it is a form of egotism, I think a better way of putting it is: given a method of reducing the cost of coagulating in a group, people will enlarge their concept of clan and start doing stuff they would do for themselves for a lot more people.&lt;br /&gt;&lt;br /&gt;That brings me to the second talk, &lt;a href="http://www.evgenymorozov.com/" target="_blank" title="Belarus-born researcher and blogger who works on the political effects of the internet"&gt;Evgeni Morozov&lt;/a&gt;'s,that would have been a lot more powerful if the guy would have stopped a few times to take a breath, right? :) He talks about the ease of using the Internet to determine the network structure of groups of people (clans again) and then striking where it is most effective with minimal cost to the establishment. There are mathematical algorithms that can do this automatically, just give them a graph of people and they will determine the leaders of opinion, the hubs of information. Then you can either persuade or remove them, giving you the power to control their entire "flock", just like pruning a bonsai tree to make it look like you want it to. And I think this system is a lot more used in democracies, rather than in totalitarian regimes, for the simple reason that despots have other options.&lt;br /&gt;&lt;br /&gt;Both ideas seem to have a point in common, in my view, that in any strongly connected group of people leaders will naturally emerge , without any other reason than that they feel good about it, and stear a lot of passive people, whether in opinion or action. In an ideal situation, where all connections between people would be transparent (and I imagine Google is not far from having this kind of information), the entire humanity could be reduced to an active minority and an inertial mass of people.&lt;br /&gt;&lt;br /&gt;This is interesting as a case study, because I am talking of an elite group of people, and not one that is organized, but one that is emerging naturally from chaotic personal behaviour. Something like Asimov's &lt;a href="http://en.wikipedia.org/wiki/Psychohistory_(fictional)" target="_blank" title="The Foundation of my childhood :)"&gt;psychohistory&lt;/a&gt; could use that, with the axioms slightly modified to talk about "active population" as opposed to total population.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-5956303267284225159?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/MpJgt1QUegA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/5956303267284225159/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=5956303267284225159" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/5956303267284225159?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/5956303267284225159?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/MpJgt1QUegA/internet-as-a-utopian-tool.html" title="The Internet as an utopian tool" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/09/internet-as-a-utopian-tool.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQMRXk8cCp7ImA9WxNQFk8.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-648659760532651586</id><published>2009-09-22T15:26:00.003+03:00</published><updated>2009-09-22T15:43:04.778+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-22T15:43:04.778+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows API" /><title>OutOfMemoryException in System.Drawing.Graphics.DrawImage</title><content type="html">I was using these GIF images stored as embedded resources and suddenly I got an Out of memory exception from a component that I had no control over. All images were icon size, 16x16 or a little more, so a lot of the explanations for the error based on "you don't have enough memory!" (duh!) were not helpful. The images did have transparent pixels, and my gut feeling is that it all came from there.&lt;br /&gt;&lt;br /&gt;  I still don't know what caused it, but I did find a solution. Where I get the image I add an additional &lt;pre&gt;image = image.GetThumbnailImage(image.Width, image.Height, null, IntPtr.Zero);&lt;/pre&gt; I know it's not something very intuitive, but it solved the problem.&lt;br /&gt;&lt;br /&gt;  The only significant difference between the image before and after the &lt;span title="I love inventing words :)"&gt;thumbnailization&lt;/span&gt; is the &lt;em&gt;PixelFormat&lt;/em&gt; property that changed from &lt;em&gt;PixelFormat.Format8bppIndexed&lt;/em&gt; to &lt;em&gt;PixelFormat.Format32bppArgb&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;  The stack looks like this:&lt;pre&gt;   at System.Drawing.Graphics.CheckErrorStatus(Int32 status)&lt;br /&gt;   at System.Drawing.Graphics.DrawImage(Image image, Rectangle destRect, Int32 srcX, Int32 srcY, Int32 srcWidth, Int32 srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttrs, DrawImageAbort callback, IntPtr callbackData)&lt;br /&gt;   at System.Drawing.Graphics.DrawImage(Image image, Rectangle destRect, Int32 srcX, Int32 srcY, Int32 srcWidth, Int32 srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttr, DrawImageAbort callback)&lt;br /&gt;   at System.Drawing.Graphics.DrawImage(Image image, Rectangle destRect, Int32 srcX, Int32 srcY, Int32 srcWidth, Int32 srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttr)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  And, using Reflector, I could go as far as pinpointing the error to the method &lt;strong&gt;System.Drawing.SafeNativeMethods.Gdip.GdipDrawImageRectRectI&lt;/strong&gt; which wraps the &lt;em&gt;gdiplus.dll&lt;/em&gt; &lt;strong&gt;GdipDrawImageRectRectI&lt;/strong&gt; function. It returns &lt;em&gt;error status 3&lt;/em&gt;, which is Out of memory, and that is that. I couldn't find a C++ code for the GdiPlus library and even if I had, who I am kidding? :)&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-648659760532651586?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/p0V8rlMkiGg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/648659760532651586/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=648659760532651586" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/648659760532651586?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/648659760532651586?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/p0V8rlMkiGg/outofmemoryexception-in.html" title="OutOfMemoryException in System.Drawing.Graphics.DrawImage" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/09/outofmemoryexception-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMAQ386cCp7ImA9WxNQE0s.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-8995368886998835786</id><published>2009-09-19T13:06:00.003+03:00</published><updated>2009-09-19T14:40:42.118+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-19T14:40:42.118+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><category scheme="http://www.blogger.com/atom/ns#" term="personal" /><category scheme="http://www.blogger.com/atom/ns#" term="science" /><category scheme="http://www.blogger.com/atom/ns#" term="essay" /><title>The Teaching Company. Realy nice courses on just about anything</title><content type="html">My world view is limited by the data that comes to me. I have my tiny slice of reality, a few friends, my work, then there are movies, news, documentaries, the Internet and so on. You will notice that I placed them in a certain order, it is the order that to me seems to go from more bullshit and less information to more information. I never believed the expression "&lt;span title="Mark Twain: Truth is stranger than fiction, but it is because Fiction is obliged to stick to possibilities; Truth isn't."&gt;Truth is stranger than fiction&lt;/span&gt;", so lets set the slice of reality aside. And, being first on my list... full of bullshit :)&lt;br /&gt;&lt;br /&gt;Movies teach me a lot, but there is just as much untruth and deceit in them as there is stuff worth knowing. News are focused on a part of life that normally doesn't interest me, but they still have a higher percent of useful information. Then there are the documentaries, stuff from Discovery Channel and the likes. Well, I have mixed feelings about those. There are things that they teach me and they do it in a pleasant manner, yet, by the time they end, I feel like there is so much more that I wanted to know and that it all just stopped when it got interesting. On further analysis, it seems the quantum of information in an hour of film was something I could blog in two or three paragraphs.&lt;br /&gt;&lt;br /&gt;And then there is the Internet. It is bursting with information, if only I knew where to look and only if I had the discipline of researching, summarising and storing that information. I am working on that, even this blog is used to store what I find, but I am still only an amateur. There is something that attracted me a while ago, something called &lt;a href="http://siderite.blogspot.com/2008/02/open-course-ware-be-student-onlie-free.html" target="_blank" title="Open Course Ware! Be a student online, free and at any time!"&gt;Open Courseware&lt;/a&gt;. There were courses from the largest universities, freely available on the net. However, they left me feeling disappointed as they were mostly text, the few that were in media format were mostly audio and, in the end, they were only poor recordings of classroom courses, sounds of scribling on the blackboard included.&lt;br /&gt;&lt;br /&gt;Enter &lt;a href="http://en.wikipedia.org/wiki/The_Teaching_Company" target="_blank" title="They do courses for media recording"&gt;The Teaching Company&lt;/a&gt;, a company that produces recordings of lectures by nationally top-ranked university professors as well as high-school teachers. The lectures are well done, they feature some guy or gal that present the information without having to write stuff on blackboards. If anything is to be shown, it will be a computer slide or animation, while the details on spoken information are added to the screen (for example the names of people). Wonderful stuff, only it is not free. &lt;br /&gt;&lt;br /&gt;If you go to &lt;a href="http://www.teach12.com" title="The Teaching Company brings engaging professors into your home or car through courses on DVD, audio CD, and other formats." target="_blank"&gt;the official site&lt;/a&gt; you will find courses on just about anything, priced at around 35$ per download and 70$ per DVD if they are "on sale" and the rest of them going to about 250$, with a range of 20-40 lectures per course. Of course, there is the option of looking for "&lt;strong&gt;TTC torrent&lt;/strong&gt;" on Google and see what you find there. For the people in Africa that just got an Internet cable installed, I mean.&lt;br /&gt;&lt;br /&gt;I had the luck to start with linguistics (&lt;strong&gt;&lt;a href="http://www.teach12.com/ttcx/coursedesclong2.aspx?cid=2270" target="_blank" title="Beginner level linguistics: phonetics, language drift, etc"&gt;Understanding Linguistics: The Science of Language&lt;/a&gt; by &lt;a href="http://en.wikipedia.org/wiki/John_McWhorter" target="_blank" title="I really liked the guy"&gt;John McWhorter&lt;/a&gt;&lt;/strong&gt;), lucky not because linguistics is so interesting, but because John McWhorter was really charismatic and had a very well constructed set of lectures. And because linguistics is an interesting topic, at least at the introductory level of this course. It was funny, too, the guy is what I imagine a typical New Yorker to be. He is black with a Scottish name, he talks a lot of Broadway plays and old movies, he is socially astute; very cosmopolitan.&lt;br /&gt;&lt;br /&gt;Then I went for astronomy (&lt;strong&gt;&lt;a href="http://www.teach12.com/ttcx/CourseDescLong2.aspx?cid=1823" target="_blank" title="Interesting start, but a rather dragged towards the end"&gt;New Frontiers: Modern Perspectives on Our Solar System&lt;/a&gt; by &lt;a href="http://terpsichore.stsci.edu/~summers/" target="_blank" title="He reminded me of Raymond, from the series :)"&gt;Frank Summers&lt;/a&gt;&lt;/strong&gt;). If you like those National Geographic documentaries about the solar system, you will love this. Towards the end it got detailed in a bad way, but only compared with the beginning of the course, which was really well done. The lectures are about the Solar System, from the standpoint of a modern astronomer, in light of all the recent discoveries. Also, a very well made point about why the structure of the solar system was revised and Pluto got demoted. At the end it talks of other star systems and what are the methods to detect and study them.&lt;br /&gt;&lt;br /&gt;Not all the courses are so good, though. I had the misfortune of trying out &lt;strong&gt;&lt;a href="http://www.teach12.com/ttcx/CourseDescLong2.aspx?cid=1284" target="_blank" title="How NOT to make a lecture"&gt;Superstring Theory: The DNA of Reality&lt;/a&gt; by Sylvester James Gates, Jr.&lt;/strong&gt; The guy is a black man in his late fifties who tries to explain Superstring theory without using any mathematics. He starts by repeating a lot of what he said in previous lectures and, indeed, in the same one earlier on, then goes asking these stupid questions that repeat what he said again. Something like "As I said in a previous lecture this and this and this happened. But why did this and this and this happen?". Ugh. If it was only about that, I would have finished watching the course, but it was something completely unstructured, boring and dragging. After 12 lectures out of 24 I knew nothing about string theory, except vague things like "if I imagine a ball that goes towards another ball and they shout at each other and the waves make other balls while the previous balls disappear but wait they appear again...". What I knew is that I had to stop watching. Sorry, Mr. Gates, lecturing... just not your thing. Stick to short appearances on Nova PBS shows.&lt;br /&gt;&lt;br /&gt;Right now I am on &lt;strong&gt;&lt;a href="http://www.teach12.com/ttcx/coursedesclong2.aspx?cid=2368" target="_blank" title="I have mixed feelings about this..."&gt;Building Great Sentences: Exploring the Writer's Craft&lt;/a&gt; by &lt;a href="http://www.english.uiowa.edu/faculty/landon/index.html" target="_blank" title="His voice and face don't seem to be compatible :)"&gt;Brooks Landon&lt;/a&gt;&lt;/strong&gt;. It talks about constructing good sentences in order to improve one's writing. I have the feeling that the guy uses more detail than necessary. Like when he explains a concept he has to give at least 5 examples, when 2 or 3 would have been enough. But then again, maybe I am wrong. I will have to finish the course to give you a definite opinion.&lt;br /&gt;&lt;br /&gt;Next on my list:&lt;br /&gt;&lt;strong&gt;Quantum Mechanics: The Physics of the Microscopic World by Benjamin Schumacher&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Understanding Genetics: DNA, Genes, and Their Real-World Applications by David Sadava&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Introduction to Number Theory by  Edward B. Burger&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Understanding the Brain by Jeanette Norden&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Does all this make me a very smart person? Not really. Remember that most of these are introductory courses. They do not contain exercises or books that you need to read, nor do they require a very high level of previous knowledge in order to understand them. They are, pure and simple, like those Discovery Channel shows, only they don't end when they get interesting and they are not so full of bullshit. After watching one of these courses (or, indeed, listening to them as podcasts while you are going to work) you will have an idea on where to go digging deeper for the topics that interest you.&lt;br /&gt;&lt;br /&gt;Good learning!&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-8995368886998835786?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/d4Meq1UNEwY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/8995368886998835786/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=8995368886998835786" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/8995368886998835786?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/8995368886998835786?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/d4Meq1UNEwY/teaching-company-realy-nice-courses-on.html" title="The Teaching Company. Realy nice courses on just about anything" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/09/teaching-company-realy-nice-courses-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YHRHw5fSp7ImA9WxNQEkw.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-2871327335101313393</id><published>2009-09-17T21:25:00.005+03:00</published><updated>2009-09-17T23:25:35.225+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-17T23:25:35.225+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>Creating a self validating ASP.Net control</title><content type="html">It started with a simple request for a custom control to perform some validation. Seems easy enough, but it is not. Sure, there is an easy solution and that is to &lt;em&gt;create a composite control&lt;/em&gt;, containing the original control and a normal validator, but that means you don't inherit from neither control and you have to copy all the properties and methods you are interested in. If, as I did, do not like this solution, you will soon find out that there are a lots of obstacles to be conquered if you want all the features of a validator, the first of which is that a control cannot easily change the Controls collection of its parent. It would be bad design. Therefore simply adding a Validator from inside the control does not work.&lt;br /&gt;&lt;br /&gt;  Let's start with what others did: &lt;a href="http://www.codeproject.com/KB/custom-controls/selfvalidatingtextbox.aspx" target="_blank" title="by Patrick Meyer"&gt;Self Validating ASP.NET Text Box&lt;/a&gt;. This CodeProject article shows how you can build a control that is validated only on the server side and implements the &lt;strong&gt;IValidator&lt;/strong&gt; interface. However, you will notice that it did not implement the &lt;em&gt;ValidationGroup&lt;/em&gt; behaviour. And that is due to a simple fact: there is a method of the &lt;strong&gt;Page&lt;/strong&gt; class called &lt;em&gt;GetValidators(string validationGroup)&lt;/em&gt; that is used all around ASP.Net. It looks kind of like this:&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ValidatorCollection GetValidators(&lt;span class="kwrd"&gt;string&lt;/span&gt; validationGroup)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (validationGroup == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;        validationGroup = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Empty;&lt;br /&gt;    }&lt;br /&gt;    ValidatorCollection validators = &lt;span class="kwrd"&gt;new&lt;/span&gt; ValidatorCollection();&lt;br /&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;._validators != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.Validators.Count; i++)&lt;br /&gt;        {&lt;br /&gt;            BaseValidator validator = &lt;span class="kwrd"&gt;this&lt;/span&gt;.Validators[i] &lt;span class="kwrd"&gt;as&lt;/span&gt; BaseValidator;&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (validator != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;.Compare(validator.ValidationGroup,&lt;br /&gt;                   validationGroup, StringComparison.Ordinal) == 0)&lt;br /&gt;                {&lt;br /&gt;                    validators.Add(validator);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (validationGroup.Length == 0)&lt;br /&gt;            {&lt;br /&gt;                validators.Add(&lt;span class="kwrd"&gt;this&lt;/span&gt;.Validators[i]);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; validators;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Notice anything? There is no mention of &lt;strong&gt;IValidator&lt;/strong&gt;, instead only &lt;strong&gt;BaseValidator&lt;/strong&gt;s are seeked and the reason the &lt;strong&gt;IValidator&lt;/strong&gt; approach works at all is the line before last where a validator is added to the list if the &lt;em&gt;validationGroup&lt;/em&gt; parameter is empty. That is, it will work with &lt;strong&gt;IValidator&lt;/strong&gt;s but only on &lt;strong&gt;Button&lt;/strong&gt;s or other postback controls that have an empty &lt;em&gt;ValidationGroup&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;So let's start from the idea of the original article: an &lt;strong&gt;IValidator&lt;/strong&gt; &lt;strong&gt;TextBox&lt;/strong&gt; control with server validation only. For simplicity I will compare the value of the control with a constant string and fail the validation if the comparison fails.&lt;br /&gt;&lt;br /&gt;&lt;fieldset&gt;&lt;legend onclick="var div=document.getElementById('initialSource'); div.style.display=div.style.display=='none'?'':'none';"&gt;Click to expand&lt;/legend&gt;&lt;div id="initialSource" style="display:none;"&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ValidatedTextBox : TextBox, IValidator&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt;? _isValid;&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; _errorMessage;&lt;br /&gt;&lt;br /&gt;    &lt;span class="preproc"&gt;#region&lt;/span&gt; IValidator Members&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Validate()&lt;br /&gt;    {&lt;br /&gt;        IsValid = Text == &lt;span class="str"&gt;"Good"&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsValid&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (_isValid == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (ViewState[&lt;span class="str"&gt;"IsValid"&lt;/span&gt;] == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;                    IsValid = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;br /&gt;                &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;                    IsValid = (&lt;span class="kwrd"&gt;bool&lt;/span&gt;)ViewState[&lt;span class="str"&gt;"IsValid"&lt;/span&gt;];&lt;br /&gt;            }&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; _isValid ?? &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            _isValid = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;            ViewState[&lt;span class="str"&gt;"IsValid"&lt;/span&gt;] = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ErrorMessage&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (_errorMessage == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (ViewState[&lt;span class="str"&gt;"ErrorMessage"&lt;/span&gt;] == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;                    ErrorMessage = &lt;span class="str"&gt;""&lt;/span&gt;;&lt;br /&gt;                &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;                    ErrorMessage = (&lt;span class="kwrd"&gt;string&lt;/span&gt;)ViewState[&lt;span class="str"&gt;"ErrorMessage"&lt;/span&gt;];&lt;br /&gt;            }&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; _errorMessage;&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            _errorMessage = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;            ViewState[&lt;span class="str"&gt;"ErrorMessage"&lt;/span&gt;] = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnInit(EventArgs e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnInit(e);&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (Page != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            Page.Validators.Add(&lt;span class="kwrd"&gt;this&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnUnload(EventArgs e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (Page != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            Page.Validators.Remove(&lt;span class="kwrd"&gt;this&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnUnload(e);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/fieldset&gt;&lt;br /&gt;&lt;br /&gt;You notice that the entire logic of this method is that the validators in the &lt;em&gt;Page.Validators&lt;/em&gt; collection will be validated when need arises. In order to implement the &lt;em&gt;ValidationGroup&lt;/em&gt; behaviour, we need to either fool the &lt;em&gt;GetValidators&lt;/em&gt; method or to actually add a &lt;strong&gt;BaseValidator&lt;/strong&gt; to the collection, not the &lt;strong&gt;IValidator&lt;/strong&gt; control. I would have prefered the first method, but &lt;em&gt;GetValidators&lt;/em&gt; is executed not only in &lt;em&gt;Page.Validate&lt;/em&gt; but, being public, can also be executed in other situations (and in fact it is called by every control that wants to cause a postback).&lt;br /&gt;&lt;br /&gt;My first attempt was to simply add a dummy validator to the collection, with the proper &lt;em&gt;ValidationGroup&lt;/em&gt; set. It worked for the client side (we'll get to that) but then it failed miserably when &lt;em&gt;Page.Validate&lt;/em&gt; tried to loop through the collection. I was forced to create my own validator control that inherits from &lt;strong&gt;BaseValidator&lt;/strong&gt;. Do not worry, though, it is very lightweight and does not need to be added to the &lt;em&gt;Controls&lt;/em&gt; collection. Here is the source:&lt;br /&gt;&lt;fieldset&gt;&lt;legend onclick="var div=document.getElementById('dummyValidator'); div.style.display=div.style.display=='none'?'':'none';"&gt;Click to expand&lt;/legend&gt;&lt;div id="dummyValidator" &gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DummyValidator:BaseValidator&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; IValidator _realValidator;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; DummyValidator(IValidator realValidator)&lt;br /&gt;    {&lt;br /&gt;        _realValidator = realValidator;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; EvaluateIsValid()&lt;br /&gt;    {&lt;br /&gt;        _realValidator.Validate();&lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; _realValidator.IsValid;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; ControlPropertiesValid()&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/fieldset&gt;&lt;br /&gt;&lt;br /&gt;Note: the following code has a property called &lt;em&gt;ValidationGroup&lt;/em&gt;. The TextBox already has it, for its own &lt;em&gt;AutoPostBack&lt;/em&gt; behaviour. I left it there, though, because you might want to use this on a control that doesn't have it natively.&lt;br /&gt;&lt;br /&gt;Now the code for the &lt;strong&gt;ValidatedTextBox&lt;/strong&gt; class looks like this:&lt;br /&gt;&lt;fieldset&gt;&lt;legend onclick="var div=document.getElementById('addedValidationGroup'); div.style.display=div.style.display=='none'?'':'none';"&gt;Click to expand&lt;/legend&gt;&lt;div id="addedValidationGroup" &gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; DummyValidator _dummyValidator;&lt;br /&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnInit(EventArgs e)&lt;br /&gt; {&lt;br /&gt;     &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnInit(e);&lt;br /&gt;     &lt;span class="kwrd"&gt;if&lt;/span&gt; (Page != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;     {&lt;br /&gt;         _dummyValidator = &lt;span class="kwrd"&gt;new&lt;/span&gt; DummyValidator(&lt;span class="kwrd"&gt;this&lt;/span&gt;){ValidationGroup = ValidationGroup};&lt;br /&gt;         Page.Validators.Add(_dummyValidator);&lt;br /&gt;         &lt;span class="rem"&gt;//Page.Validators.Add(this);&lt;/span&gt;&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnUnload(EventArgs e)&lt;br /&gt; {&lt;br /&gt;     &lt;span class="kwrd"&gt;if&lt;/span&gt; (Page != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;     {&lt;br /&gt;         &lt;span class="rem"&gt;//Page.Validators.Remove(this);&lt;/span&gt;&lt;br /&gt;         Page.Validators.Remove(_dummyValidator);&lt;br /&gt;     }&lt;br /&gt;     &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnUnload(e);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; _validationGroup;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ValidationGroup&lt;br /&gt; {&lt;br /&gt;     get&lt;br /&gt;     {&lt;br /&gt;         &lt;span class="kwrd"&gt;if&lt;/span&gt; (_validationGroup == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;         {&lt;br /&gt;             &lt;span class="kwrd"&gt;if&lt;/span&gt; (ViewState[&lt;span class="str"&gt;"ValidationGroup"&lt;/span&gt;] == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;                 ValidationGroup = &lt;span class="str"&gt;""&lt;/span&gt;;&lt;br /&gt;             &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;                 ValidationGroup = (&lt;span class="kwrd"&gt;string&lt;/span&gt;) ViewState[&lt;span class="str"&gt;"ValidationGroup"&lt;/span&gt;];&lt;br /&gt;         }&lt;br /&gt;         &lt;span class="kwrd"&gt;return&lt;/span&gt; _validationGroup;&lt;br /&gt;     }&lt;br /&gt;     set&lt;br /&gt;     {&lt;br /&gt;         _validationGroup = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;         ViewState[&lt;span class="str"&gt;"ValidationGroup"&lt;/span&gt;] = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/fieldset&gt;&lt;br /&gt;&lt;br /&gt;So the &lt;em&gt;ValidationGroup&lt;/em&gt; is now working on the server side since there is an actual &lt;strong&gt;BaseValidator&lt;/strong&gt; in the &lt;em&gt;Validators&lt;/em&gt; collection calling the &lt;em&gt;Validate&lt;/em&gt; method of our control. Since the &lt;strong&gt;DummyValidator&lt;/strong&gt; class doesn't implement any specific behaviour, it can be reused for any type of validated control.&lt;br /&gt;&lt;br /&gt;Now for the client side part. The client validation scripts work with a javascript array called &lt;em&gt;Page_Validators&lt;/em&gt;. Yhe validators are rendered as &lt;strong&gt;span&lt;/strong&gt; elements (where the error message is displayed) and the array holds all these elements, with some extra properties like &lt;em&gt;isValid, errorMessage, evaluationfunction, controltovalidate, validationGroup, focusOnError, enabled and display&lt;/em&gt;. The first three are like the &lt;strong&gt;IValidator&lt;/strong&gt; members, only in javascript, &lt;em&gt;controltovalidate&lt;/em&gt; is the client id of the control to be validated while &lt;em&gt;focusOnError&lt;/em&gt; is used to scroll the page/container in order to see the invalid control without looking all over the page to find it.&lt;br /&gt;&lt;br /&gt;All the ASP.Net validation functions are in a javascript file called &lt;strong&gt;WebUIValidation.js&lt;/strong&gt; and embedded in the System.Web.dll library. We need to load it in order for validation to work. Then we need to render a &lt;strong&gt;span&lt;/strong&gt; element and set its attributes. Lastly, but most important of all, we must create a function that will evaluate the validity of the control.&lt;br /&gt;&lt;br /&gt;I will just post the entire source, since all the client code is practically copied from the &lt;strong&gt;BaseValidator&lt;/strong&gt; code.&lt;br /&gt;&lt;br /&gt;&lt;fieldset&gt;&lt;legend onclick="var div=document.getElementById('completeSource'); div.style.display=div.style.display=='none'?'':'none';"&gt;Click to expand&lt;/legend&gt;&lt;div id="completeSource" style="display:none;"&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ValidatedTextBox : TextBox, IValidator&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; _validationGroup;&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt;? _isValid;&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; _errorMessage;&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; ValidatorDisplay? _display;&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt;? _setFocusOnError;&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; DummyValidator _dummyValidator;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ValidationGroup&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (_validationGroup == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (ViewState[&lt;span class="str"&gt;"ValidationGroup"&lt;/span&gt;] == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;                    ValidationGroup = &lt;span class="str"&gt;""&lt;/span&gt;;&lt;br /&gt;                &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;                    ValidationGroup = (&lt;span class="kwrd"&gt;string&lt;/span&gt;)ViewState[&lt;span class="str"&gt;"ValidationGroup"&lt;/span&gt;];&lt;br /&gt;            }&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; _validationGroup;&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            _validationGroup = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;            ViewState[&lt;span class="str"&gt;"ValidationGroup"&lt;/span&gt;] = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; ValidatorDisplay Display&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (_display == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (ViewState[&lt;span class="str"&gt;"Display"&lt;/span&gt;] == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;                    Display = ValidatorDisplay.Dynamic;&lt;br /&gt;                &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;                    Display = (ValidatorDisplay)ViewState[&lt;span class="str"&gt;"Display"&lt;/span&gt;];&lt;br /&gt;            }&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; _display ?? ValidatorDisplay.Dynamic;&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            _display = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;            ViewState[&lt;span class="str"&gt;"Display"&lt;/span&gt;] = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; SetFocusOnError&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (_setFocusOnError == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (ViewState[&lt;span class="str"&gt;"SetFocusOnError"&lt;/span&gt;] == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;                    SetFocusOnError = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;br /&gt;                &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;                    SetFocusOnError = (&lt;span class="kwrd"&gt;bool&lt;/span&gt;)ViewState[&lt;span class="str"&gt;"SetFocusOnError"&lt;/span&gt;];&lt;br /&gt;            }&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; _setFocusOnError ?? &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            _setFocusOnError = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;            ViewState[&lt;span class="str"&gt;"SetFocusOnError"&lt;/span&gt;] = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="preproc"&gt;#region&lt;/span&gt; IValidator Members&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Validate()&lt;br /&gt;    {&lt;br /&gt;        IsValid = Text == &lt;span class="str"&gt;"Good"&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsValid&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (_isValid == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (ViewState[&lt;span class="str"&gt;"IsValid"&lt;/span&gt;] == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;                    IsValid = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;br /&gt;                &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;                    IsValid = (&lt;span class="kwrd"&gt;bool&lt;/span&gt;)ViewState[&lt;span class="str"&gt;"IsValid"&lt;/span&gt;];&lt;br /&gt;            }&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; _isValid ?? &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            _isValid = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;            ViewState[&lt;span class="str"&gt;"IsValid"&lt;/span&gt;] = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ErrorMessage&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (_errorMessage == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (ViewState[&lt;span class="str"&gt;"ErrorMessage"&lt;/span&gt;] == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;                    ErrorMessage = &lt;span class="str"&gt;""&lt;/span&gt;;&lt;br /&gt;                &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;                    ErrorMessage = (&lt;span class="kwrd"&gt;string&lt;/span&gt;)ViewState[&lt;span class="str"&gt;"ErrorMessage"&lt;/span&gt;];&lt;br /&gt;            }&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; _errorMessage;&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            _errorMessage = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;            ViewState[&lt;span class="str"&gt;"ErrorMessage"&lt;/span&gt;] = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnInit(EventArgs e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnInit(e);&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (Page != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            _dummyValidator = &lt;span class="kwrd"&gt;new&lt;/span&gt; DummyValidator(&lt;span class="kwrd"&gt;this&lt;/span&gt;) { ValidationGroup = ValidationGroup };&lt;br /&gt;            Page.Validators.Add(_dummyValidator);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnUnload(EventArgs e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (Page != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            Page.Validators.Remove(_dummyValidator);&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnUnload(e);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnPreRender(EventArgs e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnPreRender(e);&lt;br /&gt;        registerValidationScripts();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; registerValidationScripts()&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (Page != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            ScriptManager.RegisterClientScriptResource(&lt;span class="kwrd"&gt;this&lt;/span&gt;,&lt;br /&gt;                &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(BaseValidator), &lt;span class="str"&gt;"WebUIValidation.js"&lt;/span&gt;);&lt;br /&gt;            var script = &lt;span class="str"&gt;@"var Page_ValidationActive = false;&lt;br /&gt;if (window.ValidatorOnLoad) ValidatorOnLoad();&lt;br /&gt;&lt;br /&gt;function ValidatorOnSubmit() {&lt;br /&gt;    return Page_ValidationActive&lt;br /&gt;        ? ValidatorCommonOnSubmit()&lt;br /&gt;        : true;&lt;br /&gt;}"&lt;/span&gt;;&lt;br /&gt;            ScriptManager.RegisterStartupScript(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(BaseValidator),&lt;br /&gt;                &lt;span class="str"&gt;"ValidatorIncludeScript"&lt;/span&gt;, script, &lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;br /&gt;            script = &lt;span class="str"&gt;@"if (window.ValidatorOnSubmit &lt;br /&gt;                    &amp;amp;&amp;amp; ValidatorOnSubmit() == false) return false;"&lt;/span&gt;;&lt;br /&gt;            ScriptManager.RegisterOnSubmitStatement(&lt;span class="kwrd"&gt;this&lt;/span&gt;,&lt;br /&gt;                &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(BaseValidator), &lt;span class="str"&gt;"ValidatorOnSubmit"&lt;/span&gt;, script);&lt;br /&gt;&lt;br /&gt;            script = &lt;span class="str"&gt;@"function evaluateValidatedTextBox(val) {&lt;br /&gt;    var value = ValidatorGetValue(val.controltovalidate);&lt;br /&gt;    var valid=value=='Good';&lt;br /&gt;    var control=document.getElementById(val.controltovalidate);&lt;br /&gt;    if (control) {&lt;br /&gt;        control.style.backgroundColor=valid?'white':'pink';&lt;br /&gt;    }&lt;br /&gt;    return valid;&lt;br /&gt;}"&lt;/span&gt;;&lt;br /&gt;            ScriptManager.RegisterClientScriptBlock(&lt;span class="kwrd"&gt;this&lt;/span&gt;,&lt;br /&gt;                GetType(), &lt;span class="str"&gt;"evaluateValidatedTextBox"&lt;/span&gt;, script, &lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Render(HtmlTextWriter writer)&lt;br /&gt;    {&lt;br /&gt;        registerValidatorDeclaration();&lt;br /&gt;        &lt;span class="kwrd"&gt;base&lt;/span&gt;.Render(writer);&lt;br /&gt;        renderClientValidator(writer);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; renderClientValidator(HtmlTextWriter writer)&lt;br /&gt;    {&lt;br /&gt;        writer.AddAttribute(&lt;span class="str"&gt;"id"&lt;/span&gt;, ClientID + &lt;span class="str"&gt;"_validatorSpan"&lt;/span&gt;);&lt;br /&gt;        writer.AddAttribute(&lt;span class="str"&gt;"controltovalidate"&lt;/span&gt;, ClientID);&lt;br /&gt;        writer.AddAttribute(&lt;span class="str"&gt;"evaluationfunction"&lt;/span&gt;, &lt;span class="str"&gt;"evaluateValidatedTextBox"&lt;/span&gt;);&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (SetFocusOnError)&lt;br /&gt;            writer.AddAttribute(&lt;span class="str"&gt;"focusOnError"&lt;/span&gt;, &lt;span class="str"&gt;"t"&lt;/span&gt;);&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(ErrorMessage))&lt;br /&gt;            writer.AddAttribute(&lt;span class="str"&gt;"errorMessage"&lt;/span&gt;, ErrorMessage);&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!IsValid)&lt;br /&gt;            writer.AddAttribute(&lt;span class="str"&gt;"isValid"&lt;/span&gt;, &lt;span class="str"&gt;"False"&lt;/span&gt;);&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!Enabled)&lt;br /&gt;            writer.AddAttribute(&lt;span class="str"&gt;"enabled"&lt;/span&gt;, &lt;span class="str"&gt;"False"&lt;/span&gt;);&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(ValidationGroup))&lt;br /&gt;            writer.AddAttribute(&lt;span class="str"&gt;"validationGroup"&lt;/span&gt;, ValidationGroup);&lt;br /&gt;        writer.AddAttribute(&lt;span class="str"&gt;"display"&lt;/span&gt;,&lt;br /&gt;            PropertyConverter.EnumToString(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(ValidatorDisplay), Display));&lt;br /&gt;        writer.RenderBeginTag(&lt;span class="str"&gt;"span"&lt;/span&gt;);&lt;br /&gt;        writer.RenderEndTag();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; registerValidatorDeclaration()&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; arrayValue = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"document.getElementById('{0}_validatorSpan')"&lt;/span&gt;, ClientID);&lt;br /&gt;        ScriptManager.RegisterArrayDeclaration(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="str"&gt;"Page_Validators"&lt;/span&gt;, arrayValue);&lt;br /&gt;        var script = &lt;span class="str"&gt;@"document.getElementById('"&lt;/span&gt; + ClientID + &lt;span class="str"&gt;@"').dispose = function() {&lt;br /&gt;    var val=document.getElementById('"&lt;/span&gt; + ClientID + &lt;span class="str"&gt;@"_validatorSpan');&lt;br /&gt;    Array.remove(Page_Validators, val);&lt;br /&gt;};&lt;br /&gt;"&lt;/span&gt;;&lt;br /&gt;        ScriptManager.RegisterStartupScript(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(BaseValidator),&lt;br /&gt;                                            ClientID + &lt;span class="str"&gt;"_DisposeScript"&lt;/span&gt;, script, &lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/fieldset&gt;&lt;br /&gt;&lt;br /&gt;There are several things you need to take care of.&lt;br /&gt;   One of them is the client display of the validators. Normally, a validator's span element is rendered with the &lt;em&gt;ErrorMessage&lt;/em&gt; as inner html. The ASP.Net framework then changes the visibility of the &lt;strong&gt;span&lt;/strong&gt; depending on the validity of the control. I have chosen to not render the error message, as I wanted a different behaviour (in this case, a red background). The span element is still shown and hidden, but being empty, there is no visible effect.&lt;br /&gt;   Another thing is when you would use validation summaries. The error message is being rendered as a property of the &lt;strong&gt;span&lt;/strong&gt;. It WILL be used in the summary, even if it is not normally displayed.&lt;br /&gt;&lt;br /&gt;  This code will work with almost no change for any control, so you could encapsulate it into a &lt;strong&gt;ValidatorHelper&lt;/strong&gt; class or something. The only variants are the &lt;em&gt;Validate&lt;/em&gt; method and &lt;em&gt;evaluatefunction&lt;/em&gt; function. &lt;br /&gt;&lt;br /&gt;  Also note that having inherited from &lt;strong&gt;BaseValidator&lt;/strong&gt;, I bypassed the normal functionality of the default validator controls. If you want to inherit from one of those, like &lt;strong&gt;RegularExpressionValidator&lt;/strong&gt;, you might encounter problems, especially for controls that are not normally validated and for which the normal validator controls try to get their value. Take a look at the &lt;em&gt;&lt;strong&gt;ValidationProperty&lt;/strong&gt;&lt;/em&gt; attribute that you might need to use to decorate your control in order to work with default validators. Also, the javascript behaviour is to look for a control that has a &lt;em&gt;value&lt;/em&gt; attribute. If not found it searches deeper into the children. So if you want to use a default validator, you might want to add script to keep a &lt;em&gt;value&lt;/em&gt; attribute updated on the validated control HTML element.&lt;br /&gt;&lt;br /&gt;  And that was all.&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-2871327335101313393?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/qUByqSwTyQs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/2871327335101313393/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=2871327335101313393" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/2871327335101313393?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/2871327335101313393?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/qUByqSwTyQs/creating-self-validating-aspnet-control.html" title="Creating a self validating ASP.Net control" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/09/creating-self-validating-aspnet-control.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QFRH0-fCp7ImA9WxNQEUQ.&quot;"><id>tag:blogger.com,1999:blog-14267103.post-3620365989462477976</id><published>2009-09-17T17:46:00.005+03:00</published><updated>2009-09-17T17:55:15.354+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-17T17:55:15.354+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><category scheme="http://www.blogger.com/atom/ns#" term="books" /><category scheme="http://www.blogger.com/atom/ns#" term="picture" /><title>The Prefect by Alastair Reynolds</title><content type="html">&lt;img style="float:left; margin:0; border 0;width: 277px; height: 400px;" src="http://2.bp.blogspot.com/_6GyQjwWOmQA/SrJNNdxMWAI/AAAAAAAAAfE/1AC1BzELmCE/s400/ThePrefect.jpg" border="0" alt="Book cover" /&gt;Ugh! The fifth book of the Revelation Space series , &lt;a href="http://en.wikipedia.org/wiki/The_Prefect" target="_blank" title="takes place prior to the four previously released Revelation Space novels, but after some of the short stories"&gt;The Prefect&lt;/a&gt;, is the worst so far. Not only is it standalone, but it is also a prequel, something that happends pre-plague. All the characters seem to have been lobotomized some time in the past (possibly in an operation that also mixed their brains around so that they all sound and act the same), including the bad guys, and the story is completely boring. Nothing in this novel makes any sense, nor does it make you feel anything special, quite the contrary, the scenes that were supposed to bring out feelings for the reader felt really forced and had the opposite effect.&lt;br /&gt;&lt;br /&gt;The only good thing in the book was the ClockMaker, all 10 pages of it or whatever. Couldn't you start with the ClockMaker, continue with the ClockMaker and end with the ClockMaker and forget all about the stupid and randomly emotional people, mr Reynolds?&lt;div class="blogger-post-footer"&gt;&lt;a href="http://siderite.blogspot.com" style="font-size:3px;" title="Content taken from Siderite's blog"&gt;Content taken from Siderite's blog&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14267103-3620365989462477976?l=siderite.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Siderite/~4/mk_LJupwynk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://siderite.blogspot.com/feeds/3620365989462477976/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=14267103&amp;postID=3620365989462477976" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/3620365989462477976?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14267103/posts/default/3620365989462477976?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Siderite/~3/mk_LJupwynk/prefect-by-alastair-reynolds.html" title="The Prefect by Alastair Reynolds" /><author><name>Siderite</name><uri>http://www.blogger.com/profile/15900117719824630437</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="08503586710257064835" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_6GyQjwWOmQA/SrJNNdxMWAI/AAAAAAAAAfE/1AC1BzELmCE/s72-c/ThePrefect.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://siderite.blogspot.com/2009/09/prefect-by-alastair-reynolds.html</feedburner:origLink></entry></feed>
