<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Andy Smith's Blog</title><subtitle type="html">Page.RegisterStartupScript('Andy', 'MetaBuilders_WebControls_GainKnowledge();');</subtitle><id>http://weblogs.asp.net/asmith/atom.aspx</id><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/default.aspx" /><link rel="self" type="application/atom+xml" href="http://weblogs.asp.net/asmith/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20510.895">Community Server</generator><updated>2004-06-30T18:16:00Z</updated><entry><title>partial nested classes</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2005/09/05/424465.aspx" /><id>http://weblogs.asp.net/asmith/archive/2005/09/05/424465.aspx</id><published>2005-09-05T20:29:00Z</published><updated>2005-09-05T20:29:00Z</updated><content type="html">"Partial classes" is on of the new features of v2 that, while I totally get why Microsoft wanted to add it, I didn't really see any use of them beyond the vstudio code gen world.&lt;br /&gt; "Nested classes" was one of the features of v1 that, while I completely understood the theoretical point of them, I had a HECK of a time coming up with any possible senario where it would actually be useful and the Right Decision.&lt;br /&gt; &lt;br /&gt; And now, within the last week, I've ran across 2 instances where the combination of both of these features made the project better and more managable.&lt;br /&gt; &lt;br /&gt; I'll only talk about one of them because only one is my code :)&lt;br /&gt; &lt;br /&gt; I'm working on a control on v2 to get a feel for various new technologies we get to play with, like callbacks and new designer possibilities. One such new designer feature is the Smart Tags that pop open next to controls which give you quick access to various actions on the control. I'm using the smart tag to let you show or hide areas of the control, so you can see them as you set the various styles.&lt;br /&gt; &lt;br /&gt; Implementing these smart tag actions isn't quite as simple as it could be for the simple cases, but I can see that it's quite powerful. So, getting back on topic, the implementation requires a custom Designer for the control, an ActionList class which handles the selection of the smart tag actions, and a TypeConverter class that supplies the list of actions shown in the smart tag. Neither the ActionList nor the TypeConverter class are useful outside of the Designer and the ActionList needs to access members of the Designer which really should be private. Therefore, they are both prime candidates for being nested classes.&lt;br /&gt; &lt;br /&gt; However, having three classes in one code file can get tedioius with the scrolling and such. And that is where partial classes come in. Before partial classes I would have just set them as internal to avoid the problem, but that is more exposure than they require. So with partial classes, I put each nested class in its own file, with the parents' "partial class" declaration becoming an extended namespace of sorts.&lt;br /&gt; &lt;br /&gt; So with the combination of these two features, I now have the classes having the least amount of exposure they require while still getting all the file management features I would normally have with seperate internal classes.&lt;br /&gt; &lt;br /&gt; So ya, call me a convert.&lt;br /&gt; &lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=424465" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author><category term="asp.net controls" scheme="http://weblogs.asp.net/asmith/archive/tags/asp.net+controls/default.aspx" /></entry><entry><title>Import Settings toy for VStudio</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2005/08/30/import-settings-toy-for-vstudio.aspx" /><id>http://weblogs.asp.net/asmith/archive/2005/08/30/import-settings-toy-for-vstudio.aspx</id><published>2005-08-30T05:37:00Z</published><updated>2005-08-30T05:37:00Z</updated><content type="html">As you can tell by the sheer size of the c# formatting options area in vstudio 2005, different companies and people love their own personal code formatting style. However, that can present a pretty serious problem to those of use who bounce around various clients, because they almost invariably all have their own style documented in some holy document. &lt;BR&gt;&lt;BR&gt;For a while, i would just go through the settings dialogs to change to the current project i was working on. That got tedious very quickly. Then I started exporting/importing vssettings files through the wizard. But even that 10 click game gets old. So one night, after dealing with 3 different projects or 3 different clients, I got sufficiently annoyed and decided to &lt;A href="http://weblogs.asp.net/erobillard/archive/tags/Lazy+Programming/default.aspx" mce_href="http://weblogs.asp.net/erobillard/archive/tags/Lazy+Programming/default.aspx"&gt;get lazy&lt;/A&gt; about the whole thing.&lt;BR&gt;&lt;BR&gt;So now I have a vstudio 2005 macro that makes it easy to add a simple macro command to my Tools menu for this. Open a project, click a menu item. yay for easiness. The only thing easier would be if it were automatic, which is something i'm working on in the background.&lt;BR&gt;&lt;BR&gt;After building that, I just had another idea about importing settings that, while I'm not going to use myself right now, I thought would be an interesting little side project. So I also created a macro project for automaticly importing from a vssettings file over the web. Uploading the file is up to you for now, but vstudio will, upon open, download and import those settings. The idea here is to make it a bit easier to keep 2 locations ( home and work? ) in sync as far as options go.&lt;BR&gt;&lt;BR&gt;So if these toys interest you, &lt;A href="http://www.metabuilders.com/ImportSettings.zip" mce_href="http://www.metabuilders.com/ImportSettings.zip"&gt;download and give them a try&lt;/A&gt;.&lt;BR&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=423996" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author></entry><entry><title>yay @ atlas</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2005/06/29/416451.aspx" /><id>http://weblogs.asp.net/asmith/archive/2005/06/29/416451.aspx</id><published>2005-06-29T07:18:00Z</published><updated>2005-06-29T07:18:00Z</updated><content type="html">&lt;p&gt;The cat's out of the bag about &lt;A href="http://weblogs.asp.net/scottgu/archive/2005/06/28/416185.aspx"&gt;Atlas&lt;/a&gt;. AJAX may actually get productive soon.&amp;nbsp;Not to dismiss the other frameworks in place at all. ( AJAX.net has some great ideas there )&amp;nbsp;It's just easier to incorporate a library into custom controls when it's already baked into the system.&lt;/p&gt; &lt;p&gt;Boy, I would _kill_ to be on the team working on that.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=416451" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author><category term="asp.net controls" scheme="http://weblogs.asp.net/asmith/archive/tags/asp.net+controls/default.aspx" /></entry><entry><title>Fooling Around With Media Center and Messenger</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2005/06/03/410313.aspx" /><id>http://weblogs.asp.net/asmith/archive/2005/06/03/410313.aspx</id><published>2005-06-03T16:58:00Z</published><updated>2005-06-03T16:58:00Z</updated><content type="html">&lt;p&gt;I took a little time last nite and today to put together something that i've been wanting since msn messenger 7 came out with its What I'm Listening To feature. See, I don't run any local-machine music players anymore since I got my Windows Media Center box from HP, so this neat little feature was fairly useless.&lt;/p&gt; &lt;p&gt;But since it's all player-plugin based, I figured it'd be completely possible to write some code and get that info zipping across the lan. So looking into it a bit, it turns out that Messenger does it with good ol' SendMessage, and I downloaded a nice little vb.net module that does all that win32 gunk for me.&lt;/p&gt; &lt;p&gt;So then the question becomes, "how do I send that info across the network?". I decided to have a little fun and use Remoting. I ended up with a local-machine Service ( that runs as System but can interact with the desktop so I can use FindWindow and SendMessage ) that exposes my VB module thru a named remoting uri. And so on the MCE box, I have a Service that gets media-state events from MCE and remotes them to my local machine.&lt;/p&gt; &lt;p&gt;Unfortunately, it doesn't quite completely work yet. :) So far, I've only been successfull with a normal windows app running on the MCE. When I put the same code into a service, I get nothing, but I haven't been able to figure out how to properly debug the bugger. But hey, with the media center shell running fullscreen, it's not like i can see my remoting app anyway... So it might just stay the way it is for a little while.&lt;/p&gt; &lt;p&gt;At any rate, Yay @ fun little projects. :)&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=410313" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author></entry><entry><title>Marco-Polo as software development methodology</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2004/11/10/255273.aspx" /><id>http://weblogs.asp.net/asmith/archive/2004/11/10/255273.aspx</id><published>2004-11-10T20:52:00Z</published><updated>2004-11-10T20:52:00Z</updated><content type="html">&lt;p&gt;In one of the most infsightfull-tho-slightly-bitter posts i've seen in a while...&lt;/p&gt; &lt;p&gt;&lt;a href="http://dotnetjunkies.com/WebLog/cbryan/archive/2004/11/09/31505.aspx"&gt;Chuck Bryan brings together the seemingly seperate worlds of software development and childhood&amp;nbsp;pool games&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=255273" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author></entry><entry><title>Event handler declarations in the tag are the right thing</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2004/09/14/229646.aspx" /><id>http://weblogs.asp.net/asmith/archive/2004/09/14/229646.aspx</id><published>2004-09-14T21:59:00Z</published><updated>2004-09-14T21:59:00Z</updated><content type="html">&lt;p&gt;&lt;a href="http://blogs.aspadvice.com/joteke/archive/2004/09/14/1657.aspx"&gt;Teemu brought up the current event declaration behavior&lt;/a&gt; today, and even pointed to a &lt;a href="http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=f2e73831-9d83-4685-9f10-ed7939a1ba46"&gt;bug report&lt;/a&gt; about it.&lt;/p&gt; &lt;p&gt;I'm going to take the opposite stance. putting the onclick="whatever" attribute on the tag is the best solution to a complicated problem. Now, if the problem were limited to the points that Teemu addresses, then yes, it&amp;nbsp;looks like it should changable based on the current dev model. However, the thing that makes this problem more complicated is that not every control is at the top level of your page. Asp.net uses a hierarchal declaration system with containers and child controls. One by-product of this system is that not all design-time-selectable controls on your page have references at the page level, or even refer to a single instance of a control ( in the case of a databound template declaration ). &lt;/p&gt; &lt;p&gt;So, if you drag a button onto your form, and double click it to add a hook to the Click event, there are&amp;nbsp;2 or 3&amp;nbsp;basic choices ( depending on language ( VB has the Handles thing going on ))... add the glue to the tag, or add it in some initialization code block. Some want to use the code block because they don't like their UI declration to know the name of the handler function of the event.&lt;/p&gt; &lt;p&gt;However, the hole there is that if you now move that button from the top level of the page's heirarchy, into a INamingContainer like a Repeater's ItemTemplate, then the instance referenced in the initialization-block doesn't exist. ( VB's Handles doodad breaks here too )&lt;/p&gt; &lt;p&gt;So how should the designer attach to events in child controls if there is no top level instance to code against, nor any guarentee that the child control will exist at any given initialization time ( or be instantiated at all during that request for that matter&amp;nbsp;)? To me, it seems it can't&amp;nbsp;ensure correctness with any way but declarative.&amp;nbsp;Which follows to the next point... Should it really use two completely different hookup mechanisms for top-level and child controls? I assert that it shouldn't as that would lead to some nitemare maintainability problems. ( "I know that it's hooked up somewhere, where&amp;nbsp;did that code block go now?" )&amp;nbsp;Therefore... the tag declaration is the correct place for the designer to hook up event handlers.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=229646" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author><category term="asp.net controls" scheme="http://weblogs.asp.net/asmith/archive/tags/asp.net+controls/default.aspx" /></entry><entry><title>Top 2 reasons why WMP10 isn't my audio player</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2004/09/02/224978.aspx" /><id>http://weblogs.asp.net/asmith/archive/2004/09/02/224978.aspx</id><published>2004-09-02T23:37:00Z</published><updated>2004-09-02T23:37:00Z</updated><content type="html">&lt;p&gt;1) No OGG support. Come on Microsoft, you can do it. I know you can. You were even willing to ( apparently ) pony up the money to include high bitrate mp3 encoding. You can't hire a contract/temp developer for&amp;nbsp;like a month to add support for completely free and open codecs? This is really a non-starter for me. If your player doesn't support 1/3 of my music, i'm not going to be using it.&lt;/p&gt; &lt;p&gt;2) The "web video" problem. Ok, this one is a bit more complicated. I'm the kinda guy that plays music 24x7. Regardless of what else i'm doing, I want my music playing. So, ok, here's the scenario... I'm surfing... I click a video link... Now, the old behavior was horrible. It used to just completely blow out&amp;nbsp;your current playlist and play the video. For v10, they "solved" this problem in a half-assed way. Now, your current playlist is saved, the music is paused, and the video plays. Sure, this means you can go back to your music after the video is done, but that's not the behavior I want. What&amp;nbsp;I want is for the music to CONTINUE PLAYING while the video plays. And more than just complain about it, I'll offer a solution too. It seems to me that the right way to solve this is to allow the user to "pin" an instance of wmp. A pinned instance won't be reused by other applications which open media. So I could open one instance of wmp, get my music going, and pin that instance. Then if I want to view a video clip those will be opened in a new window. Unfortunately, since something like v7 of wmp, multiple instances of wmp has not been possible. So while this is the right answer, I doubt it will ever happen.&lt;/p&gt; &lt;p&gt;So anyway, until BOTH of&amp;nbsp;these issues are fixed, it's winamp for me.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=224978" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author><category term="rambling" scheme="http://weblogs.asp.net/asmith/archive/tags/rambling/default.aspx" /></entry><entry><title>Composite controls that do their own databinding</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2004/08/29/222442.aspx" /><id>http://weblogs.asp.net/asmith/archive/2004/08/29/222442.aspx</id><published>2004-08-30T00:55:00Z</published><updated>2004-08-30T00:55:00Z</updated><content type="html">&lt;p&gt;Most databound controls are written from the perspective that they will be databound to something, but the control writer doesn’t know what that would be. It is assumed that the control’s container will set the datasource and databind it. Therefore the same container knows about and handles the datasource, databinding, viewstate usages, event handling, etc. This works great.&lt;/p&gt; &lt;p&gt;But then application developers come along and want self contained controls, like, say… A composite control which contains a DropDownList that always contains items databound from a database, and a button that performs magic on those items. The app developer of course calls on his local control guru to make him this control. &lt;/p&gt; &lt;p&gt;This gives us 3 different people with 3 very different perspectives. There is the app developer, the custom control developer, and the asp.net team control developer who made the DropDownList control. The asp.net team guy does the Right Thing in exposing a DataSource property which DataBind uses, and an EnableViewState property which says whether or not the items created should be serialized to ViewState. He’s thinking, “If a consumer of my control does want to use viewstate, they can just bind on every request.” This is a reasonable position. Then on the other end we have the app developer who is using the custom control. He had the custom control made exactly BECAUSE he doesn’t want to think about datasources and databinding and such. However, the trickiness presents itself because he does still want to be in control of ViewState usage. Maybe some specific page is hit so often that ViewState should be disabled to save on bandwidth. “My custom control should just get the data every hit, I can cache at the data-access level to make up for it.” This is also a reasonable position.&lt;/p&gt; &lt;p&gt;So now the custom control developer is in a bit of a pickle. The break in the chain is that the lower levels assume that one person would be both databinding and deciding on ViewState policy. That isn’t the case here.&lt;/p&gt; &lt;p&gt;Ignoring the ViewState issue for a second, the straightforward solution to this is that the composite control does a “if not postback then databind” thing during Load, and override its DataBind method to databind its child DropDownList to the database. But then what happens if the app developer sets EnableViewState to false? Obviously the control is broken. So the control dev needs to databind during load in both first-request and disabled-viewstate states. This mostly solves the problem; however there is one last problem that I just don’t see a good solution to. Think of the case where an app dev sets the EnableViewState property to false during PreRender. In this case the Load-time DataBind never runs on subsequent requests even though there won’t be ViewState to load and thus the control is broken. Now don’t think that I imagine this is a common scenario, but it’s unfortunate. The only thing I can think is that you’d have to push the responsibility of DataBind() onto the app dev in this case. It’s not something I particularly like, because I think the app dev shouldn’t have to worry about the datasources of controls contained by it’s composite control children. However, it’s the best I’ve come up with so far.&lt;/p&gt; &lt;p&gt;Any other ideas?&lt;br /&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=222442" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author><category term="asp.net controls" scheme="http://weblogs.asp.net/asmith/archive/tags/asp.net+controls/default.aspx" /></entry><entry><title>SP2 IE and about:mozilla</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2004/08/17/215627.aspx" /><id>http://weblogs.asp.net/asmith/archive/2004/08/17/215627.aspx</id><published>2004-08-17T11:41:00Z</published><updated>2004-08-17T11:41:00Z</updated><content type="html">So one change in IE that came with sp2, that I haven't seen anybody comment on, is that about:mozilla is gone. Before I installed sp2, i had my homepage set to about:mozilla because it gave a nice colored window as the default. But now all it does it show the word "mozilla" on a white background. If you are annoyed that your nice default html is no longer around, there is a little trick that not many people know, which is that you can put any html you want in an about url, and IE will show it. So just write a simple html page that displays any color/design you want and set that text as your homepage.&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=215627" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author></entry><entry><title>The Death of DynamicImage</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2004/08/17/215541.aspx" /><id>http://weblogs.asp.net/asmith/archive/2004/08/17/215541.aspx</id><published>2004-08-17T06:17:00Z</published><updated>2004-08-17T06:17:00Z</updated><content type="html">Of all the &lt;a href="http://blogs.msdn.com/ShankuN/archive/2004/08/16/215487.aspx"&gt;features cut from asp.net v2&lt;/a&gt;, the only one that I'm really going to miss is the loss of DyanmicImage and the Image Generation Service.&amp;nbsp; Not so much because it's a little harder to do dynamic images in my app without them, but because it's much harder to do dynamic images in my 3rd party&amp;nbsp;server controls without them. The fact that you&amp;nbsp;will be able&amp;nbsp;progmatticly register custom IHttpHandlers in web.config mitigates the situation a bit, but not enough.&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=215541" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author><category term="asp.net controls" scheme="http://weblogs.asp.net/asmith/archive/tags/asp.net+controls/default.aspx" /></entry><entry><title>MetaBuilders and Telligent</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2004/08/08/210799.aspx" /><id>http://weblogs.asp.net/asmith/archive/2004/08/08/210799.aspx</id><published>2004-08-08T09:40:00Z</published><updated>2004-08-08T09:40:00Z</updated><content type="html">&lt;p&gt;It's not often that a contractor says, "wow, I’m so incredibly happy about my latest client", but I see myself in that position. And seeing that I have a voice, I just need to tell y’all.&lt;/p&gt; &lt;p&gt;I recently signed up to help out &lt;a href="http://www.telligentsystems.com/"&gt;Telligent&lt;/a&gt; with their &lt;a href="http://www.telligentsystems.com/Solutions/Forums/"&gt;Community Server: Forums&lt;/a&gt; project.&lt;/p&gt; &lt;p&gt;I can’t express how big the smile on my face was when I started working with &lt;A href="http://weblogs.asp.net/rhoward"&gt;Rob&lt;/a&gt;, &lt;A href="http://weblogs.asp.net/jalexander"&gt;Jason&lt;/a&gt;, &lt;a href="http://scottwater.com/blog/"&gt;Scott&lt;/a&gt;, and Terry Denham.&lt;/p&gt; &lt;p&gt;You know, when I started &lt;a href="http://www.metabuilders.com/"&gt;MetaBuilders&lt;/a&gt; as a business, I had plans that that selling server control products would be my main business, but the bottom line has lead me to selling my services as an asp.net/control guru, helping others get their business done. It’s worked out pretty well for me, but I’ve never been more excited about work than I am right now.&lt;/p&gt; &lt;p&gt;You’ll have to excuse me for the complete lack of useful technical information in this post… I know that’s what regular readers are used to seeing… but this is really such a high point in my recent history that I really need to publish it.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=210799" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author><category term="asp.net controls" scheme="http://weblogs.asp.net/asmith/archive/tags/asp.net+controls/default.aspx" /></entry><entry><title>Web Control Developer Macro Goodness</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2004/08/02/204936.aspx" /><id>http://weblogs.asp.net/asmith/archive/2004/08/02/204936.aspx</id><published>2004-08-02T09:23:00Z</published><updated>2004-08-02T09:23:00Z</updated><content type="html">&lt;P&gt;I've had these control dev&amp;nbsp;macros sitting around for a while, and I thought I'd share them finally. First I looked for a wiki I could post them to, but I was surprised to not find one for vstudio addins/macros/whatnot. The closest I found was the &lt;A href="http://www.gotdotnet.com/team/ide/"&gt;gotdotnet developer powertoy site&lt;/A&gt;, but the whole submission/wait-for-approval thing just bores me. So, I decided to post the macro file here. I hope you find them useful:&lt;/P&gt;&lt;CODE&gt;&lt;PRE&gt;
Imports EnvDTE
Imports System
Imports System.Diagnostics
Imports System.IO
Imports System.Text

Public Module CodeGen

    ' Creates A Public Style Property
    ' Write the following line into the code area:
    ' &amp;lt;StyleType&amp;gt; &amp;lt;PropertyName&amp;gt;
    ' Select the text, run this macro
    Public Sub CreateStyleProperty()
        CheckLanguage()
        Dim ts As TextSelection = DTE.ActiveDocument.Selection
        Dim selection As String = ts.Text.Replace(vbTab, " ").Trim(" ")
        Dim words() As String = selection.Split(" ")
        If words.Length &amp;lt;&amp;gt; 2 Then
            Return
        End If
        Dim typeName As String = words(0)
        Dim propertyName As String = words(1)
        Dim memberName As String = "_" &amp;amp; propertyName.Substring(0, 1).ToLower() &amp;amp; propertyName.Substring(1)
        Dim code As New StringBuilder
        Dim codeWriter As New StringWriter(code)
        Try
            codeWriter.WriteLine("[")
            codeWriter.WriteLine("Category( ""Style"" ),")
            codeWriter.WriteLine("Description( """" ),")
            codeWriter.WriteLine("DefaultValue( null ),")
            codeWriter.WriteLine("DesignerSerializationVisibility(DesignerSerializationVisibility.Content),")
            codeWriter.WriteLine("PersistenceMode(PersistenceMode.InnerProperty),")
            codeWriter.WriteLine("]")
            codeWriter.WriteLine("public {0} {1} {{", typeName, propertyName)
            codeWriter.WriteLine("get {")
            codeWriter.WriteLine("if ( {0} == null ) {{", memberName)
            codeWriter.WriteLine("{0} = new {1}();", memberName, typeName)
            codeWriter.WriteLine("if ( IsTrackingViewState ) {")
            codeWriter.WriteLine("((IStateManager){0}).TrackViewState();", memberName)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("return {0};", memberName)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("private {0} {1};", typeName, memberName)
            codeWriter.Flush()
        Finally
            If Not codeWriter Is Nothing Then
                DirectCast(codeWriter, IDisposable).Dispose()
            End If
        End Try
        ReplaceCode(code.ToString(), "CreateStyleProperty" &amp;amp; propertyName)
    End Sub

    ' Creates a Public ITemplate Property
    ' Write the following line into the code area:
    ' &amp;lt;PropertyName&amp;gt; [&amp;lt;TemplateContainerType&amp;gt;]
    ' Select the text, run this macro
    Public Sub CreateTemplateProperty()
        CheckLanguage()
        Dim ts As TextSelection = DTE.ActiveDocument.Selection
        Dim selection As String = ts.Text.Replace(vbTab, " ").Trim(" ")
        Dim words() As String = selection.Split(" ")
        If 1 &amp;gt; words.Length OrElse words.Length &amp;gt; 2 Then
            Return
        End If
        Dim propertyName As String = words(0)
        Dim templateContainer As String = ""
        If words.Length = 2 Then
            templateContainer = words(1)
        End If
        Dim memberName As String = "_" &amp;amp; propertyName.Substring(0, 1).ToLower() &amp;amp; propertyName.Substring(1)
        Dim code As New StringBuilder
        Dim codeWriter As New StringWriter(code)
        Try
            codeWriter.WriteLine("[")
            codeWriter.WriteLine("Browsable( false ),")
            codeWriter.WriteLine("DefaultValue( null ),")
            codeWriter.WriteLine("Description( """" ),")
            codeWriter.WriteLine("PersistenceMode(PersistenceMode.InnerProperty),")
            If templateContainer &amp;lt;&amp;gt; "" Then
                codeWriter.WriteLine("TemplateContainer( typeof( {0} ) ),", templateContainer)
            End If
            codeWriter.WriteLine("]")
            codeWriter.WriteLine("public ITemplate {0} {{", propertyName)
            codeWriter.WriteLine("get {")
            codeWriter.WriteLine("return {0};", memberName)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("set {")
            codeWriter.WriteLine("{0} = value;", memberName)
            codeWriter.WriteLine("ChildControlsCreated = false;")
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("private ITemplate {0};", memberName)
            codeWriter.Flush()
        Finally
            If Not codeWriter Is Nothing Then
                DirectCast(codeWriter, IDisposable).Dispose()
            End If
        End Try
        ReplaceCode(code.ToString(), "CreateStyleProperty" &amp;amp; propertyName)
    End Sub

    ' Creates A Public ViewState-Backed Property
    ' Write the following line into the code area:
    ' &amp;lt;PropertyType&amp;gt; &amp;lt;PropertyName&amp;gt; = &amp;lt;DefaultValue&amp;gt;;
    ' Select the text, run this macro
    Public Sub CreateViewStateProperty()
        CheckLanguage()

        Dim ts As TextSelection = DTE.ActiveDocument.Selection
        Dim selection As String = ts.Text.Replace(vbTab, " ").Trim(" ")
        Dim words() As String = selection.Split(" ")
        If words.Length &amp;lt; 3 Then
            Return
        End If

        Dim typeName As String
        Dim propertyName As String
        Dim defaultValue As String
        typeName = words(0)
        propertyName = words(1)
        defaultValue = selection.Substring(selection.IndexOf("=") + 2)
        defaultValue = defaultValue.Substring(0, defaultValue.Length - 1)
        Dim code As New StringBuilder
        Dim codeWriter As New StringWriter(code)
        Try
            codeWriter.WriteLine("[")
            codeWriter.WriteLine("Bindable(true),")
            codeWriter.WriteLine("Category( """" ),")
            codeWriter.WriteLine("Description( """" ),")
            codeWriter.WriteLine("DefaultValue( {0} ),", defaultValue)
            codeWriter.WriteLine("]")
            codeWriter.WriteLine("public virtual " &amp;amp; typeName &amp;amp; " " &amp;amp; propertyName &amp;amp; " {")
            codeWriter.WriteLine("get {")
            codeWriter.WriteLine("Object state = ViewState[""{0}""];", propertyName)
            codeWriter.WriteLine("if ( state != null ) {")
            codeWriter.WriteLine("return ({0})state;", typeName)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("return {0};", defaultValue)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("set {")
            codeWriter.WriteLine("ViewState[""{0}""] = value;", propertyName)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("}")
            codeWriter.Flush()
        Finally
            If Not codeWriter Is Nothing Then
                DirectCast(codeWriter, IDisposable).Dispose()
            End If
        End Try
        ReplaceCode(code.ToString(), "CreateViewStateProperty" &amp;amp; propertyName)
    End Sub

    ' Creates A Public Event and Protected OnEvent Method
    ' Write the following line into the code area:
    ' &amp;lt;EventName&amp;gt; [&amp;lt;DelegateType&amp;gt; &amp;lt;EventArgsType&amp;gt;]
    ' Select the text, run this macro
    Public Sub CreateEvent()
        CheckLanguage()
        Dim ts As TextSelection = DTE.ActiveDocument.Selection
        Dim selection As String = ts.Text.Replace(vbTab, " ").Trim(" ")
        Dim words() As String = selection.Split(" ")
        If words.Length &amp;lt;&amp;gt; 1 AndAlso words.Length &amp;lt;&amp;gt; 3 Then
            Return
        End If
        Dim eventName As String = words(0)
        Dim delegateTypeName As String = "EventHandler"
        Dim eventArgsTypeName As String = "EventArgs"
        If words.Length = 3 Then
            delegateTypeName = words(1)
            eventArgsTypeName = words(2)
        End If

        Dim raiserName As String = "On" &amp;amp; eventName
        Dim eventObjectName As String = "event" &amp;amp; eventName
        Dim code As New StringBuilder
        Dim codeWriter As New StringWriter(code)
        Try
            codeWriter.WriteLine("#region {0} Event", eventName)
            codeWriter.WriteLine()
            codeWriter.WriteLine("public event {0} {1} {{", delegateTypeName, eventName)
            codeWriter.WriteLine("add {")
            codeWriter.WriteLine("Events.AddHandler( {0}, value );", eventObjectName)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("remove {")
            codeWriter.WriteLine("Events.RemoveHandler( {0}, value );", eventObjectName)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("}")
            codeWriter.WriteLine()
            codeWriter.WriteLine("protected void {0}( {1} e ) {{", raiserName, eventArgsTypeName)
            codeWriter.WriteLine("{0} handler = Events[ {1} ] as {0};", delegateTypeName, eventObjectName)
            codeWriter.WriteLine("if ( handler != null ) {")
            codeWriter.WriteLine("handler( this, e );")
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("}")
            codeWriter.WriteLine()
            codeWriter.WriteLine("private static readonly Object {0} = new Object();", eventObjectName)
            codeWriter.WriteLine()
            codeWriter.WriteLine("#endregion")
            codeWriter.Flush()
        Finally
            If Not codeWriter Is Nothing Then
                DirectCast(codeWriter, IDisposable).Dispose()
            End If
        End Try
        ReplaceCode(code.ToString(), "CreateEvent" &amp;amp; eventName)
    End Sub

    ' Surrounds the selected code with a try/catch/finally block
    Public Sub InsertTryCatchFinally()
        Dim endCode As New StringBuilder
        Dim writer As New StringWriter(endCode)
        Try
            writer.WriteLine("")
            writer.WriteLine("} catch( Exception ex ) {")
            writer.WriteLine("")
            writer.WriteLine("} finally {")
            writer.WriteLine("")
            writer.WriteLine("}")
            writer.Flush()
        Finally
            If Not writer Is Nothing Then
                DirectCast(writer, IDisposable).Dispose()
            End If
        End Try
        SurroundSelectionWithCode("try {" &amp;amp; Environment.NewLine, endCode.ToString(), "InsertTryCatchFinally")
    End Sub

    ' Replaces the selected code with the given new code
    Private Sub ReplaceCode(ByVal newCode As String, ByVal undoContextName As String)
        Dim selection As TextSelection = DTE.ActiveDocument.Selection
        Dim undoContextOpened As Boolean = False
        Try
            If Not DTE.UndoContext.IsOpen Then
                Call DTE.UndoContext.Open(undoContextName, False)
                undoContextOpened = True
            End If
            ' Replace the text and SmartFormat it
            selection.Delete()
            selection.Insert(newCode, vsInsertFlags.vsInsertFlagsInsertAtStart)
            selection.TopPoint.CreateEditPoint.SmartFormat(selection.BottomPoint)
        Catch ex As Exception
            MsgBox("Unable To Perform Code Alteration:" &amp;amp; Environment.NewLine &amp;amp; ex.Message, MsgBoxStyle.OKOnly, "Problem Running Macro")
        Finally
            If undoContextOpened Then
                Call DTE.UndoContext.Close()
            End If
        End Try
    End Sub

    ' Surrounds the selected code with the given prefix and suffix code
    Private Sub SurroundSelectionWithCode(ByVal startCode As String, ByVal endCode As String, ByVal undoContextName As String)
        Dim selection As TextSelection = DTE.ActiveDocument.Selection
        Dim undoContextOpened As Boolean = False
        Try
            If Not DTE.UndoContext.IsOpen Then
                Call DTE.UndoContext.Open(undoContextName, False)
                undoContextOpened = True
            End If
            Dim tp As EditPoint = selection.TopPoint.CreateEditPoint()
            selection.TopPoint.CreateEditPoint().Insert(startCode)
            Dim bp As EditPoint = selection.BottomPoint.CreateEditPoint()
            bp.Insert(endCode)
            tp.SmartFormat(bp)
        Catch ex As Exception
            MsgBox("Unable To Perform Code Alteration:" &amp;amp; Environment.NewLine &amp;amp; ex.Message, MsgBoxStyle.OKOnly, "Problem Running Macro")
        Finally
            If undoContextOpened Then
                Call DTE.UndoContext.Close()
            End If
        End Try
    End Sub

    ' Ensures that the macro is modifying only c# documents
    Private Sub CheckLanguage()
        If DTE.ActiveDocument.Language &amp;lt;&amp;gt; "CSharp" Then
            Throw New System.Exception("This Macro only works on C# code")
        End If
    End Sub
End Module
&lt;/PRE&gt;&lt;/CODE&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=204936" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author><category term="asp.net controls" scheme="http://weblogs.asp.net/asmith/archive/tags/asp.net+controls/default.aspx" /></entry><entry><title>Firefox nonbug that caused me some grief today</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2004/07/14/183532.aspx" /><id>http://weblogs.asp.net/asmith/archive/2004/07/14/183532.aspx</id><published>2004-07-14T22:18:00Z</published><updated>2004-07-14T22:18:00Z</updated><content type="html">		&lt;P&gt;I ran into a rather unfortunate issue today with a server control that I 
			thought would probably be good to talk about. The issue is created by non-bugs 
			that come together to make a bug.&lt;/P&gt;
		&lt;UL&gt;
			&lt;LI&gt;
				Firefox persists the values of form fields when the user refreshes 
				the page.&lt;/LI&gt;
			&lt;LI&gt;
				Firefox does not persist any script objects applied to the document or the 
				window&lt;/LI&gt;
			&lt;LI&gt;
				Complex server controls will commonly use script objects for the lifetime of 
				the page, and use hidden inputs to round trip values from server to client to 
				server.&lt;/LI&gt;&lt;/UL&gt;
		&lt;P&gt;So this is the result of these 3 items...
		&lt;/P&gt;
		&lt;UL&gt;
			&lt;LI&gt;
				A user with firefox hits your page with your control on it the first time...&lt;/LI&gt;
			&lt;LI&gt;
				Your initialization script runs, and all script objects and hidden inputs are 
				in the initialized state.&lt;/LI&gt;
			&lt;LI&gt;
				The user plays with the page a bit, and your control changes its state, 
				changing object properties and hidden input values.&lt;/LI&gt;
			&lt;LI&gt;
				The user hits refresh in their browser. Firefox nullifies all script objects, 
				but retains the values of the hidden inputs.&lt;/LI&gt;
			&lt;LI&gt;
				Your control's initialization runs again, but now the script objects are 
				created with hidden input state that is not the original.&lt;/LI&gt;&lt;/UL&gt;
		&lt;P&gt;Now, as you can imagine, this has a very high possibility of completely borking 
			your control. Now, before I get flames, let me restate that I don't consider 
			this a bug in Firefox. It's just a behavior that I hadn't planned for. However, 
			ultimately, it has a way of changing my methods for roundtripping values 
			between client and server.&lt;/P&gt;
		&lt;P&gt;For now, my best solution is to include any "initial" values in the 
			RegisterArrayDeclaration call for the control, while previously i would 
			normally only put them in the hidden input.&lt;/P&gt;
&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=183532" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author><category term="asp.net controls" scheme="http://weblogs.asp.net/asmith/archive/tags/asp.net+controls/default.aspx" /></entry><entry><title>Windows XP Royale theme</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2004/06/30/170380.aspx" /><id>http://weblogs.asp.net/asmith/archive/2004/06/30/170380.aspx</id><published>2004-07-01T00:39:00Z</published><updated>2004-07-01T00:39:00Z</updated><content type="html">Thought I'd mention this, just because I like the look so much. Somebody snagged the &lt;a href="http://www.winbeta.org/comments.php?id=352&amp;catid=1"&gt;windows theme from media center edition&lt;/a&gt; and it's been posted on winbeta.org. It's basically a lickable version of the standard blue/green xp theme. Very nice.&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=170380" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author></entry><entry><title>Materials from my usergroup presentation</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/asmith/archive/2004/06/30/170363.aspx" /><id>http://weblogs.asp.net/asmith/archive/2004/06/30/170363.aspx</id><published>2004-07-01T00:16:00Z</published><updated>2004-07-01T00:16:00Z</updated><content type="html">&lt;p&gt;It's taken me a while to remember to do this...&lt;br&gt;
I gave a presentation on monday to the &lt;a href="http://www.denvervisualstudio.net/"&gt;denver .net user group&lt;/a&gt; on developing asp.net server controls and i'm positing the presentation materials on for those that want it. So anyway,  grab the &lt;a href="http://www.metabuilders.com/developingservercontrols.zip"&gt;powerpoint and code from my presentation&lt;/a&gt; if you want it.&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=170363" width="1" height="1"&gt;</content><author><name>Andy Smith</name><uri>http://weblogs.asp.net/members/Andy-Smith.aspx</uri></author><category term="asp.net controls" scheme="http://weblogs.asp.net/asmith/archive/tags/asp.net+controls/default.aspx" /></entry></feed>