You've reached the internet home of Chris Sells, who has a long history as a contributing member of the Windows developer community. He enjoys long walks on the beach and various computer technologies.
Saturday, Apr 30, 2005, 1:31 AM in The Spout
I enjoyed THGTTG
It wasn't perfect, e.g. lots of the fun bits were gone and at least one sub-plot never got resolved, but I liked the new stuff, e.g. the motivation for the end of the movie and the romance. Bottom line: I laughed a lot. We did have a pretty decent local geek turn-out, so that made it even more fun, but it was a completely watchable movie and I'd definitely see it again.
Tuesday, Apr 26, 2005, 9:21 AM in The Spout
The Value of Scoble
There is huge value in Robert Scoble publicly criticizing his employer's CEO. The value is this: when the GM of VSTS says "ask me anything you want" concerning a recent pricing controversy, you can have confidence that Robert is going to ask the hard questions and push out the results as unedited as MS PR will let him get away with (I detected no edits in this piece). The world may not like the answers he digs out, but because Robert is risk-his-job honest, you have a high degree of confidence that what he says is the truth as he finds it.
Robert Scoble has become the Geraldo Rivera of technology reporting. Even if MS took away Robert's camcorder, I expect O'Reilly, Fawcette, CNET, ServerSide, CodeProject or any of a number of other technology eyeball companies to hand it right back to him.
Sunday, Apr 24, 2005, 10:08 AM in The Spout
Status of ATL Internals 2e
More people than you'd expect have been asking, so here's an update on ATL Internals 2e.
This effort actually started in 2003, when Kirk Fertita updated the first 9 chapters to ATL7 as provided in VS 2002. Then he had to go work on his start-up, which represented his only income stream and would've gone belly up w/o him (selfish bastard! : ).
Then George Shepherd did a little work, writing bits of two new chapters on ATL Server before he had to bale.
Now, finally, we have an author that's going to see this book to the finish line: Chris Tavares. I've written with him before and he's excellent. He's already ported chapters 1-4 to ATL8 as provided in VS 2005 and is on schedule to bring my and Brent's work on ATL3, Kirk and George's work on ATL7 and his own new work into a cohesive ATL8 book to hit the shelves 3-4 months after VS05 has hit RTM.
Sunday, Apr 24, 2005, 9:56 AM in The Spout
Status on Windows Forms Programming 2e
Jose "heard" that I'm working on an update for the first edition of Windows Forms Programming in C# for Windows Forms 2.0 (we're not updating the VB.NET version due to poor sales for VB.NET-related titles in general). I didn't mean to keep it a secret; it's been listed at the top of my writing page for a year or more. : )
While we've been working closely together on the update, the bulk of the writing work is being done by Micheal Weinhardt, my main writing partner for the last coupla years or so. He's got 90% of the book updated for VS05b1 already and is in the process of updating the whole thing to b2. After that, we pass it back and forth between ourselves for review-edit 'til we're both happy. By the end of May, hopefully the whole thing will be out for review. After that, we apply reviewer comments and update at each successive beta/release candidate until the Whidbey team decides they're done, at which point we send it to the publisher and 3-4 months later, it hits the shelves.
In addition to updating the existing material for WF2, we've made the following changes:
- Split a Layout chapter out of the Forms chapter due to all of the extra WF2 layout functionality
- Refactored the existing design-time and controls chapters and the standard components & controls appendix into the following chapters: components, controls, design-time 1 and design-time 2 (includes smart tags)
- Split the applications & settings chapters into 2
- Added a Document Management chapter for MFC folks finding themselves in the app framework-free environment of Windows Forms
- Dropped the data access chapter as covered better in other sources
- Re-wrote the data binding chapter from scratch with a story I always wanted to tell in WF1, but isn't supported nicely 'til WF2 (object-centric binding instead of relational database-centric)
- Refactored the drag 'n' drop material into it's own appendix
- Added a "What's New in Windows Forms 2.0" appendix for those already familiar with Windows Forms 1.x
- Dropped the delegates bedtime story in favor of beefed up coverage in chapter 1 (and a more general knowledge of delegates in the universe as a whole). Don't get my wrong, I love that story, but it doesn't fit into the overall theme of the rest of the book. I knew this when I first edition shipped, but I just didn't take the time to update the book properly to live w/o it
I have to say that working with Mike on this process has been fabulous. An ordinary author faced with updating to a new version of a technology might just update the material and leave the story alone, even if it needs update. Instead, Mike took the time to reexamine the book from first principles, fixing the problems in the story that always nagged at me in the 1st edition and proposing improvements to stuff I was pretty proud of. In general, even without the update to the new technology, the book is better than the 1st edition.
Friday, Apr 15, 2005, 7:26 AM in The Spout
Now *that's* how you want a Virtual PC to be!
I was using one of my computers this morning, surfing around, reading my email, getting started with the day, etc. After a bit of fooling about, I went looking for the work I wanted to continue from yesterday. I couldn't find it. Then I went looking for the program I was using to work on the file. I couldn't find it.
Just before I was about to reinstall things, I realized -- I was running a VPC image, not the computer's native image. I couldn't freakin' tell the difference! Nice...
Monday, Apr 11, 2005, 6:11 PM in The Spout
Reviewers Should Be More Like Roger
If you read the April 10th, 2005 review of my WinForms book, it has one feature that most of the other reviews don't have (and I don't mean pegging me as a "from the VB world" : ); Roger has placed his email address on the review! If everyone did that, I wouldn't spam the 5s, but I would follow up with the 1s, 2s and 3s to see what I could've done to improve the next edition. When I followed up with Roger, he had a bunch of specifics he'd have liked to see me fix. I don't agree with all of them, but you better believe he's on the list of reviewers for the second edition. Thanks, Roger!
Monday, Apr 11, 2005, 6:03 AM in The Spout
My First Week on an MS Product Team: Wallowing
Here.
The one where I describe the frustration and then enlightenment of my first week on a Microsoft product team.
Monday, Apr 11, 2005, 12:00 AM in The Spout
My First Week on a Microsoft Product Team: Wallowing
Last week was my first week on my new team. A lot of interesting things happened, some of which Don has already mentioned. For me, two especially interesting things happened. One, I found out why I was hired, in spite of my preference to work from kitchen most of the time, even though I'm working on a product group (which typically avoids my kind unless they've already worked for the team for a long time) and even though I'm working for a manager that's never had a remote employee (he doesn't even run IM!). Don't get me wrong; it's not like a skated through the interview process w/o "passing." But "passing" isn't enough when you work in a "shower optional" environment (my house, not Microsoft : ). My team needs people with a skill that I've never seen applied to product development. Most of the people that have this skill are either a) already busy shipping Indigo or b) marked as a target (some of you should feel the laser sights on your forehead : ). The skill is the thing that allows me to write books and articles in my own special way. My team has a name for this skill; it's called "wallowing."
For my team, the ability to "wallow" means the ability to dig into a discipline, any discipline, and "wallow like a pig in the mud" in that new discipline, forming questions, getting to the root of things, gathering fragmented truths together into wholes, communicating the truths to each other, gaining intuition, and generally spending time understanding the space without first coming to firm conclusions about what it is that we're actually going to build. This skill is by far the most important thing I learned at DevelopMentor. The "popping" sound I got in my head when I finally figured out COM is something that I'll never forget (mostly because my head stopped hurting after 6 weeks of hurting very much) and it's served me well over the years. For example, I wrote my WinForms book not because I had a ton of "real-world experience" as my Amazon reviews claim, but because I knew very little about WinForms and was interested in learning. I wallowed in WinForms for 9 months, writing articles and an instructor-led short-course before ever writing a single word in my book. Once I'd wallowed, however, I was able to write the book itself in 5 months.
So, while I've used to wallowing as a way to produce talks and prose, it's not a technique I've ever applied to product selection. In the past, I've come to a team where the goal was very clearly known, although the details were still up in the air (often 'til they were discovered as coding problems). I've even started my own software organization from scratch, but only after the core vision of what needed building came to me whole and I'd already built the prototype. However, with my new team, we've got a group of folks actively wallowing in a space, figuring out the right thing to build. This led to some initial frustration on my part.
Actually, frustration is too weak; for the 3 days of my employment, I was a drooling idiot with no hope of recovery. I'm used to not knowing stuff (that's when the wallowing behavior is triggered), but I'm not used to not knowing what I don't know. The reason that I was so frustrated was that I didn't know my team was wallowing. My team has already been working together in this problem space for months. They've already put together a prototype and showed it to BillG. This evidence made think that the team already had a firm vision of what they were building, so I was in coming-to-a-team-to-help-build-a-known-product-mode as with every single product team I'd ever been on or heard of.
Firmly in this mode, I spent my first 3 days in architecture meetings, brainstorming our way through the main issues of our "product." At each meeting, it seemed like people had a firm idea of what they were building, because the items on the brainstorm list flowed like water from everyone but me. To give myself some ground on which to stand, I kept asking whether we were going to cover this customer scenario or that one and the answer would always be "yes."
This went on for three days and each day I felt like I knew less about what we were doing. Instead of drawing up a plan to build a v1 settlement on the moon, I felt like we were listing the issues associated with covering the entire surface with a 10-story city. My head was swimming. How could a brand new team be targeting that kind of scope? What the hell had I gotten myself into?!?
I'm not the kind of person that keeps frustration to myself. I spent a good deal of time trying to express my despair to my boss and my new team mates, but it took me 3 days to be able to wind back my assumptions enough to be able to ask, "Do we even know what we're building?" The answer that shined light into my gloom was "no, we're wallowing."
And suddenly, all the conversations made sense. When they kept saying "yes," they meant "yes, we're still considering that possibility." We were discussing enough issues to cover the surface of the moon not because we were going to do that in v1, but because we were still figuring out the right place and kind of settlement to build. We'd picked the moon and we'd put up a tiny shed to see what it was like to live there, but we hadn't yet figured out what the next wave of settlers would need. And because we didn't want to die in the process or kill that next wave, we were going to spend some real time exploring to make sure we were proud of our first city.
This process was a revelation to me. In the small to medium-sized software engineering projects in which I'd been involved to date, this kind of product planning was outside of my experience. I mean, even when I plan to wallow in the implementation details, I've never once wallowed in the issue of what to build. When I picked my WinForms book, I didn't survey the .NET developer landscape for their needs; I just picked something I was interested in. I got lucky, but in the case of other projects, I have been less so (and sometimes expensively, spectacularly less lucky).
I told my sister-in-law this story and she was all ready to be upset for me. "You mean, they never told you? You signed up to do product development and they don't even know what they're building?" she asked. I told her that I wasn't upset at all. In retrospect, I was told that my team was wallowing, it's just that my preconceptions about what a product team does at Microsoft blocked it out.
Further, this way of figuring out what to build is one I'm looking forward to. I've never been any good at this part of the product construction process. In fact, I once drove 2 hours north and cajoled Eric Sink into driving 2 hours south so that I could ask him how to answer this very question (micro-ISVs sound cool, don't they?). His advice was "fail fast." That's good advice and, having talked to my new boss, it's something we'll be doing, but we hope to do it while exercising wallowing as a product selection technique.
The second thing I learned this week is that, while I didn't know this 'til after my 3rd day, my team is still wallowing. I told my sister-in-law that I wasn't upset at all. I love wallowing. : )
Saturday, Apr 9, 2005, 6:42 AM in The Spout
Geeks Rule and MBAs Drool
Eric Sink takes a long, long time to say the following (learn to let go, Chris [1]...):
"The following is an example of one of the most common questions I get from developers who are creating a brand new software company:
"Where can I find a partner to be a co-founder and handle the business side of things?
"My answer: Don't.
...
"Do all that stuff yourself. You need the experience anyway. If you really want a partner, don't find an MBA, find another geek like yourself. Don't be afraid to allow your company to be very developer-centric for a very long time. By doing it this way, you'll avoid a lot of problems and you'll learn a lot."
Like agile programming, Eric has just given us permission to do what we want to do anyway. Wahoo!
[1] One of my favorite duties at MSDN used to be developmental editing on Eric's writing. I used to love how he'd work certain things into his piece, e.g. the thing my 9-year old son posts on his door, modulo s/Geeks/Boys and s/MBAs/Girls.
Friday, Apr 1, 2005, 9:53 AM in The Spout
My First New Job at Microsoft
Here. The one where I stop working for MSDN.
Friday, Apr 1, 2005, 12:00 AM in The Spout
My First New Job at Microsoft
Today's my last day at MSDN. I will no longer be content strategizing for Longhorn/WinFX or smart clients or acting as liaison between marketing, evangelism and the product teams internally and developers externally. And I'm really going to miss it. MSDN took a flier on me being a successful Microsoft employee in a culture that doesn't much like remote folk and made a very comfortable home for me. I could've gone on for a long time in that role.
Still, I felt another calling. At Microsoft, it seems like all of the action is with the product teams. To come to Microsoft as a software engineer and not work on a product team seemed like starting with the Yankees but never getting out of the dugout.
So, on Monday, I start in DSG (the Distributed Systems Group) aka the team that owns Indigo. I'll be "are looking at ways to extend the notions of modeling that we've incorporated deeply into the stack and make them more general" (or so my new boss says). I can't tell begin to describe how lucky I feel. Not only do I get to be on a real product team, still mostly from my house in Oregon, but I get to work on a very juicy problem. Further, I get to do it with Oliver Sharp, one of the prime movers on the Indigo team, along with a growing group of other people way smarter than I. It reminds me of the heyday of a certain training company with which I once had a deep relationship.
Two weeks ago, Oliver sent me a list of 10 fun computer sciency things to dig into that could take months. Last week I was helping the team get ready for a BillG review. This week I was trading emails with the team and a Sr. VP on the direction of the market and how it affects our product plans. Is this what it's like for an addict that's given up their habit to take it up again? If software engineering is wrong, I don't want to be right! : )
Wednesday, Mar 30, 2005, 2:53 PM in The Spout
Leaders and Legacy
Here. For an internal thingie, I was asked to write a short bio, define what I think a "leader" is, describe my target legacy and list my biggest source of pride. This is what I came up with.
Wednesday, Mar 30, 2005, 12:00 AM in The Spout
I can feel Avalon changing me...
I'm writing a tiny little application for my writing on ClickOnce in Avalon. In fact, to demonstrate ClickOnce, the app hardly matters, so I picked something really simple: an excuse generator. I didn't even have to make up the excuses, as I stole them from an office gag gift two years ago and wrapped them in an excuse web service (which is a whole other story : ).
Binding to Data Defined in Code
The idea was to have an array of excuse strings like so:
public partial class Window1 : Window { static string[] excuses = { "Jury Duty", ... "It's Not My Job", }; public Window1() { InitializeComponent(); this.DataContext = Window1.excuses; } ... }
Once I had the collection of strings, I make them available for binding by setting them to the DataContext of the main window and the rest of the code would simply be a matter of binding a TextBlock to the current excuse like so:
<Window ...> ... <TextBlock TextContent="{Bind Path=/}" /> <Button x:ID="newExcuseButton">New Excuse</Button> ... </Window>
By binding the TextContent property of the TextBlock to a Path of "/", I'm explicitly saying "don't try to dig into each object in the collection looking for sub-properties, but binding to the item itself." Initially, the TextBlock will show the first item in the list:
When the button is pressed, I change the output by selecting a random item from the collection and setting it as the "current" item in the collection:
Random rnd = new Random(); void newExcuseButton_Click(object sender, RoutedEventArgs e) { ListCollectionView view = (ListCollectionView)Binding.GetDefaultView((IEnumerable)Window1.excuses); view.MoveCurrentToPosition(rnd.Next(view.Count - 1)); }
By grabbing the view for the excuses collection, I can do a number of things with it, including move the current item in the view to some specific position. When I do that, the data bound TextContent property of the TextBlock will be updated to show whatever is current:
So here's the first thing that I'm notice that I really approach differently in Avalon: the data binding hammer is almost always the first tool I reach for in the programming box. In the old days, to write this app, I'd set the TextContent property directly in code. Now, I don't even think to do that. Instead, I've got data and a property to set, so that's data binding.
Binding to Objects Defined in XAML
"But wait!" I hear you howl. "What about internationalization?!?" I know. Hard-coded data in the source code is a bad idea. So where does it go? Into the XAML itself, of course, so that anyone working on the UI, whether for an English-speaking country or not, can add new items, port them to another language, etc. How to do it? Well, since XAML is an XML dialect for describing object hierarchies, I could define a new type (roughly):
class Excuse { string value; public string Value { get { ... } set { ... } } } class ExcuseData : List<Excuse> { }
Then I could write my excuse data as a hydration of objects using the ObjectDataSource (roughly):
... <Window.Resources> <ObjectDataSource x:Key="ExcuseData"> <l:ExcuseData> <l:Excuse Value="Jury Duty" /> ... <l:Excuse Value="It's Not My Job" /> </l:ExcuseData> </ObjectDataSource> </Window.Resources> ...
The XAML inside the ObjectDataSource will create an instance of the ExcuseData type, adding an object of type Excuse for each <Excuse> element, setting the Value property of the object using the Value attribute from the XAML. With the object data source, I can create a little "data island" in the middle of my app where the list of excuses can be poked and prodded without touching the code.
Binding to Data Defined in XAML
Still, why go to the trouble of defining my own custom data type, which doesn't have any behavior to speak of, when I've got the universal behavior-less data type -- XML? I can use the XmlDataSource without any custom type at all:
<Window.Resources>
<XmlDataSource x:Key="ExcuseData" XPath="/Excuses/Excuse">
<Excuses xmlns="">
<Excuse>Jury Duty</Excuse>
...
<Excuse>It's Not My Job</Excuse>
</Excuses>
</XmlDataSource>
</Window.Resources>
You'll notice that the XML looks almost exactly like the object data source, except that instead of using an attribute to keep the juicy bits, I use the content area itself to store the data, very like the initial array example (I could have used XML attributes, but it seemed overkill in this case). One other interesting bit is that XPath of the XML data source itself. It defines the bit of the data island from which I'm pulling the data. If I had used /Excuses, the data collection would have had a single item with a bunch of children. But using /Excuses/Excuse, I'm exposing the children directly.
To use the XML data source, I need to set it as somebody's data context in the hierarchy of controls and bind to it:
<Window ...> <Window.Resources> <XmlDataSource x:Key="ExcuseData" XPath="/Excuses/Excuse">...</XmlDataSource> </Window.Resources> <Grid ... DataContext="{Bind DataSource={StaticResource ExcuseData}}"> ... <TextBlock ... TextContent="{Bind XPath=.}" /> <Button ... x:ID="newExcuseButton">New Excuse</Button> </Grid> </Window>
I should note that in future bits, I'll be able to set the grid's data context to {StaticResource ExcuseData} directly, but in the March 2005 CTP Avalon bits, I have to actually bind the data source to the data context in a double bind that blows my mind.
More importantly, notice that instead of using a Path to get to the data I want, I use an XPath. This allows me to further refine the XPath statement provided as part of the XML data source itself. However, since I don't want to refine it any further, I use the XPath statement that says "just use the content of each of the elements." You'll notice that I used "." in the XPath statement to provide this meaning instead of "/" as I did in the case where I was using an object Path. The two syntaxi look the same, but are very different and you'll want to watch yourself switching between the two.
Anyway, with the data moved to the XAML along with the UI and the binding logic, my actual code boils down to only the following:
public partial class Window1 : Window { Random rnd = new Random(); public Window1() { InitializeComponent(); this.newExcuseButton.Click += newExcuseButton_Click; } void newExcuseButton_Click(object sender, RoutedEventArgs e) { IDataSource dataSource = (IDataSource)this.FindResource("ExcuseData"); ListCollectionView view = (ListCollectionView)Binding.GetDefaultView((IEnumerable)dataSource.Data); view.MoveCurrentToPosition(rnd.Next(view.Count - 1)); } }
So, this is really only a few lines of code, one to hook up the button event handler, one to find the excuse data from the window resources, one to get the view on the excuse data and one to move the currency pointer to some other random spot. The actual display of the data is left to the data binding code (which somebody else gets to maintain).
One other thing worth noting is that I had defining event handlers in the XAML. Even when it's me writing both the XAML and the code, I don't like the XAML making demands on the code. If the XAML handles an event, e.g. with an event trigger, than that's fine, but don't make requirements of the code form the XAML. Instead, provide hooks for the code to do its work, e.g. the x:ID on the ExcuseData and the TextBlock are both used in the code, but neither requires anything of the code. If you're going to separate the presentation from the logic, this is the kind of thing you'll want to think about.
Where Are We?
Two things I'm finding that Avalon has changed about my thinking. The first is that data binding makes itself into even trivial Avalon applications and its presence is appreciated. The second is that I want to push as much stuff into XAML as I can. Keeping the data separate from the code makes a bunch of sense and, for my trivial application, keeping the data inline with the rest of the UI was very useful. It allows for easy maintenance and localization while pushing as much of my application into declarations and out of imperative statements. The more I can tell the computer what I want instead of how I want to accomplish it, the better off I am.
Wednesday, Mar 30, 2005, 12:00 AM in The Spout
Leaders and Legacy
For an internal thingie, I was asked to write a short bio, define what I think a "leader" is, describe my target legacy and list my biggest source of price. This is what I came up with:
I've been pretty much everything you can be in the IT industry including author, speaker, consultant, conference organizer, grunt in a start-up, CEO in a start-up, developer, tester, documenter, etc. I'm currently a content strategist for MSDN in the areas of WinFX/Longhorn and smart clients. I'm passionate about building products to make people happier, whether that's because they're more productive or because I've solved some hard problem or just because they lean back and say "cool!" My biggest regret is that I've never yet been on a product team at Microsoft; to get the full experience, someday I need to do that! After that, I can retire and write novels from coffee shops around the world. : )
A great leader is someone that inspires you to do things you didn't even know you were capable of doing.
The legacy I'd like to leave behind is that people can look back at their interactions with me and think that I helped make their lives better, whether it was an answer to a tough question or an insight that they hadn't had before or a comment that tickled their funny bone.
The biggest source of pride in my life is the family I've built with my wife and two sons (the Sells brothers, whence the name of my web site came: www.sellsbrothers.com).
Tuesday, Mar 29, 2005, 7:04 AM in The Spout
La Vida Robot
This story of a set of illegal alien high school students from the wrong side of the tracks in Phoenix competing against MIT college students was heart warming and heart breaking at the same time.