Wednesday, October 01, 2008

I don’t have any ideas yet, but Netflix is one of my favorite services.   This is completely awesome.  I hope they have the APIs enabled for cross-domain stuff so I could perhaps do some Silverlight mojo without having to Proxy the calls.

http://developer.netflix.com/page

Actually, in the process of writing this email, I did get some ideas for uses of the Netflix API.  I'm not sharing yet!

Wednesday, October 01, 2008 1:52:56 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, September 30, 2008

MySQL is a decent product.  I've been very critical of it in the past, but it has been evolving nicely.  It's probably the most popular open source database and plays nicely with .NET due to a solid ADO.Net provider.  What's been lacking up to this point, though, is LINQ to SQL support, and more recently a provider for the Entity Framework.  The EF has gotten a lot of flak, but I for one like it for the most part and I think it will hugely speed up a lot of database-heavy development. Sure, you need to write some extension methods to get around the lack of foresight for how change-tracking would work in ASP.Net applications, but once you've cracked that nut (and grokking aggregates with Entity SQL)  you can go back to happily writing LINQ queries.

I have been watching the MySQL forums for a while. The MySQL team had said during the Beta of VS2008 SP1 that there would be something we could test "real soon".  This was followed by months of radio silence.  Recently, silence was finally broken by the lead developer that September 30th was the date.  MySQL subsequently set up a webcast to demonstrate the new functionality.  Today, the day of the webcast, it seems that registered participants got messages saying that November 4th was the new date.  Unbelievable.  See: http://forums.mysql.com/read.php?38,194470,228269#msg-228269

When I was in consulting, we had a tongue-in-cheek (yet very true) rule about deadlines.  If the deadline was to be pushed back, it could only be pushed back by the amount of time remaining until the delivery date.  If you have 3 weeks until the deadline, you can only move the deadline out 3 weeks.  If it's due tomorrow, you can only push it out one day.  You do not wait until it's due today and push it back a month.  I'm sure there's a reason, but it's just bad form.  People are on the edge of their seats over this feature.  This isn't how open source is supposed to work.

Tuesday, September 30, 2008 12:32:41 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Saturday, September 27, 2008

The AGT (Argentum Tela) series of articles is an effort to do two things.  Usually an idea is presented only in its finished form.  The first goal is to do some Reality Blogging, to show an idea evolve over time without pulling any punches.  The second goal, and the example vehicle for the evolution aspect, is an extensible Design Surface for Silverlight similar to what we have in Visual Studio 2008.   This type of application has all sorts of interesting uses.  My example is a Home Theater layout tool.  Read the entire saga: http://www.damonpayne.com/2008/09/14/RunTimeIsDesignTimeForAGT0.aspx

RC0

As promised, my next task was to make any changes needed to prepare the app so far for working with the RC0 Silverlight release.

Object Tag

The first thing I noticed is that when I tried to run the application I was presented with “Get Silverlight”.  I figured the version # had changed, but it was actually the type attribute of the object tag:

    <object data="data:application/x-silverlight," type="application/x-silverlight-2" width="100%" height="100%">

          <param name="source" value="ClientBin/DamonPayne.HTLayout.xap"/>

          <param name="onerror" value="onSilverlightError" />

          <param name="background" value="white" />

          <a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">

            <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>

          </a>

      </object>   

Note the type is now “application/x-silverlight-2”.

XAML weirdness

The next error I noticed was a seemingly uncatchable error that percolated all the way up to the onSilverlightError JavaScript function.

“Can not set ItemTemplate and DisplayMemberPath simultaneously.”

Looking at the XAML, this makes sense.

        <ListBox x:Name="_itemLst" Grid.Row="1" DisplayMemberPath="Name"  ItemsSource="{Binding ToolboxItems}" SelectedItem="{Binding Path=SelectedToolboxItem, Mode=TwoWay}">

            <ListBox.ItemTemplate>

                <DataTemplate>

                    <StackPanel Orientation="Horizontal" >

                        <TextBlock Text="{Binding Name}"

This makes sense, it just didn’t cause an error before.  I’m setting DisplayMemberPath in XAML, which is then not used since I’ve provided the entire ItemTemplate.  It would be useful if the error told me which XAML file the error is in, but this is a small project so far and future Silverlight developers will be starting out with Silverlight 2 Release.

HitTest missed

At this point I thought I’d better do a Clean Solution just to be safe, and sure enough this turned up another issue.  At some point, my DesignSurface.HitTest method (required by IDropTarget) disappeared.  The Clean Solution found this out for me.  Looking back through my code snapshots taken at the end of each article, it’s been gone for quite some time.  This behavior from VS2008/Silverlight Tools is just not ok.  This was my last breaking change though.  UIElement.HitTest is gone, replaced with a method in VisualTreeHelper:

        public IEnumerable<UIElement> HitTest(Point p)

        {

            return VisualTreeHelper.FindElementsInHostCoordinates(p, LayoutRoot);

   }

Moving On

I find now that my Selection code is absolutely broken, but that was under repair anyway.

Source code: Because the code was in a state of flux pending the selection/sizing updates, the next source code will be at the end of AGT[12].

Saturday, September 27, 2008 12:31:33 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, September 26, 2008

You have probably seen that Silverlight RC 0 is now available: http://weblogs.asp.net/scottgu/archive/2008/09/25/silverlight-2-release-candidate-now-available.aspx

I was in the middle of writing AGT[11] and got sick, requiring a 16 hour sleeping spree, and I'm still not over it. AGT[11] also represented some frustrating material, so it was going slow.  Figuring out the Silverlight Layout-->Measure-->Clip-->Render process well enough to acheive my next goal is turning out to be challenging.  I'll preface it with some recommended reading.  At any rate, the material for AGT[11] will now become AGT[12].  The articles and the live demo are immediately switching over to use Silverlight RC0 before I accumulate any more breaking changes or write code to Measure behavior that changes.  Some of the solutions I was pursuing just became private/internal/sealed as of yesterday.

Recommended reading:

http://msdn.microsoft.com/en-us/library/cc645025(VS.95).aspx

http://msdn.microsoft.com/en-us/library/cc189087(VS.95).aspx

http://blogs.msdn.com/silverlight_sdk/archive/2008/05/06/more-on-layout-and-the-layoutinformation-apis.aspx

http://silverlight.net/forums/t/20520.aspx

http://nerddawg.blogspot.com/2008/04/silverlight-2-layout-and-rendering.html

http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.layoutinformation_members(VS.95).aspx

 

Friday, September 26, 2008 3:56:32 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, September 25, 2008

I have contacted my Federal representatives today to let them know I am firmly against the proposed $700 billion bailout proposal.  You should do the same.

Thursday, September 25, 2008 11:34:20 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, September 24, 2008

http://blogs.suntimes.com/ebert/2008/09/this_is_the_dawning_of_the_age.html

Art imitates life, and life in turn imitates art (which is a part of life)

I have often remarked to friends that the enduring success of Roger Ebert is hard to understand, though I am happy to see it.  After all, this is the 2000's we are living in.  He is, forgive me, not a particularly attractive man, nor does he speak and write at a level accessible to to the average high school graduate.  This is after all the age in which we vote for politicians based not on their qualifications to make decisions that are "far above our pay grade" but rather on whether or not we would feel comfortable having them over for BBQ chicken without having a chance to clean the house first or if they would fit in at our local church.  What I mean to say is that Roger Ebert does not have qualities which would immediately invoke the words "mass appeal".  He is, rather, an elitist - a word which should be badge of honor and not the insult is has become in our praise of mediocrity in this nation.

Roger Ebert writes thoughtful insights about Film, which I consider to be our highest art form to date.  Why?  Because it combines music, philosophy, dancing, drama, words, and technology into a single medium.  Each of these expressions can be profound in themselves, but combined into a single human experience moving through time can approach something truly sublime.   Surely all these things are excellent achievements of Humans and the combinatorial effects of overlapping them are worthwile of educated commentary.   The success of Roger Ebert, then, I attribute to there being just enough intelligent people in America who care just enough about things that matter to humans to give this man an enduring audience.

Ebert tells us that these days there are few rewards for critical thinking, and I must sadly agree to a point.  It would seem to me that his true talents lie not in interpreting Art, but in observing and reporting on human behavior.  Keep up the good work, sir.

Tuesday, September 23, 2008 11:06:43 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Monday, September 22, 2008

The AGT (Argentum Tela) series of articles is an effort to do two things.  Usually an idea is presented only in its finished form.  The first goal is to do some Reality Blogging, to show an idea evolve over time without pulling any punches.  The second goal, and the example vehicle for the evolution aspect, is an extensible Design Surface for Silverlight similar to what we have in Visual Studio 2008.   This type of application has all sorts of interesting uses.  My example is a Home Theater layout tool.  Read the entire saga: http://www.damonpayne.com/2008/09/14/RunTimeIsDesignTimeForAGT0.aspx

Selection

Now that we’ve got things on the surface, we need to think about selecting, moving, editing, and resizing them.  It makes sense for Selection to come first.

Selection is slightly more complicated than it sounds.  In a tool like VS2008 or Visio things could be added or removed from the selection in several ways:

·         Clicking on a component

·         Control+Click on multiple components to select and deselect

·         Shift+Click to add contiguous components to the selection

·         Click and draw a rectangle, selecting components within the bounds of said rectangle.

Since I’m extending the olive branch to the dozens and dozens of unfortunate Mac users in the world, I’ll have to make any gesture code I write smart enough to not use any normal keys that are missing from the Mac, such as: Control, Window Key, Right-click Key, Pause/Break, up arrow, and the letter Q.

Back in the Dark Ages when I was writing code to host the WinForms 2 design surface, I think my selection service implementation was quite a few lines of code.  While I still like the idea of a selection service, I’m not going to go look at the old code and corrupt my pure thoughts.  First, let’s create a cross platform Keyboard service:

    public class CrossPlatformKeyboardService : IKeyboardService

    {

        /// <summary>

        /// Control key, or open-apple on the Mac "platform"

        /// </summary>

        public bool ControlKeyDown

        {

            get

            {

                return ( Test(ModifierKeys.Control) || Test(ModifierKeys.Apple));

            }

        }

 

        public bool AltKeyDown

        {

            get { return Test(ModifierKeys.Alt); }

        }

 

        public bool ShiftDown

        {

            get { return Test(ModifierKeys.Shift); }

        }

 

        protected bool Test(ModifierKeys target)

        {

            return target == (target & Keyboard.Modifiers);

        }

Next I’ll define what I expect the interface for a selection service to be.

    public interface ISelectionService : IService

    {

        void SetSelectedControls(IList<IDesignableControl> selection);

        IList<IDesignableControl> GetSelection();

        int SelectionCount { get; }

        IDesignableControl PrimarySelection { get; }

        event EventHandler SelectionChanged;

    }

In WinForms, adding to the ISelectionService can optionally come with a parameter of type “SelectionType”, which is a discriminator for things like adding to a selection vs. starting a new selection.  I’d rather leave those details behind the ISelectionService wherever possible.  You will also note that I am using a plain old .Net event here and not something from EventAggregator.  I feel this is highly appropriate in this case.  The EventAggregator exists so that components can respond to interesting events without referencing each other, but selection events are specific to this Service, and components that need ISelectionService will magically receive it from the container.   Now I can start working on a default ISelectionService implementation, with a dependency on IKeyboardService.

Siteing, not Sighting

We need to take another step before Selection can make sense.  The WinForms designer has the notion of an ISite, where an ISite is an adapter between a designed component and its designer.  Once sited, the component can request various things of its container.  While not quite what I’m about to do, it’s a point for interested users to research.   I will explain this concept further in the next article.  I have created a UserControl called DesignSite.  DesignSite contains a border whose thickness is set to zero by default.  Inside DefaultDesignTypeCreator I shove the real IDesignableControl inside my DesignSite and let DesignSite handle the selection code when the real IDesignableControl is clicked on.

Back to Selection

The Site mentioned above wires up selection by resolving the ISelectionService.  Here, then, is the selection service implementation.

    public class DefaultSelectionService : ISelectionService

    {

        public DefaultSelectionService()

        {

            _selection = new List<IDesignableControl>();

        }

 

        public IKeyboardService KBService { get; set; }

 

        private List<IDesignableControl> _selection;

 

        public void Select(System.Collections.Generic.IList<IDesignableControl> incoming)

        {

            if (!KBService.ControlKeyDown)

            {

                _selection.Clear();

                _selection.AddRange(incoming);

                OnSelectionChanged();           

            }

            else

            {

                foreach (IDesignableControl idc in incoming)

                {

                    if (!_selection.Contains(idc))

                    {

                        _selection.Add(idc);

                    }

                    OnSelectionChanged();           

                }

            }           

        }

 

        public System.Collections.Generic.IList<IDesignableControl> GetSelection()

        {

            return _selection;

        }

 

        public int SelectionCount

        {

            get { return _selection.Count; }

        }

 

        public IDesignableControl PrimarySelection

        {

            get

            {

                return _selection[0];

            }

        }

 

        public event EventHandler SelectionChanged;

 

        protected void OnSelectionChanged()

        {

            if (null != SelectionChanged)

            {

                SelectionChanged(this, EventArgs.Empty);

            }

        }

Much simpler and shorter than I remember the WinForms implementation I remember.  We’ll see if I eat crow for saying so later.  Here is my site-style selection with a single component selected.

Shown here with multiple components selected by holding in Control or Open Apple:

You will note I don’t have any little “knobs” on the corners or anything.  I like how this looks better with a solid border and a gradient brush.  As we saw with Couch v1, perhaps my taste in visual appeal should not be trusted.  Speaking of couches, I have a chair now too.  You can take a look at my freshly painted Red Chair in the live demo.  Live demo….?

More ControlExtensions

Ever since being enlightened by Generics (the answer to everything) using the (cast) bothers me.  Casting using “as” bothers me more.  For this reason, I don’t know why the whole DependencyProperty framework deals with getting and setting of values as Object.  When I ported some code from Silverlight 2 beta 1 to beta 2, some of it was broken because I was using SetValue(Canvas.Left, 3) when in fact Canvas.Left wanted to be of type double and some auto-conversion was lost in the move to beta 2.  This error only pops up at runtime since SetValue takes type Object.  At least I can save myself some casting here and there by adding another extension method:

        public static T GetValue<T>(this DependencyObject d, DependencyProperty p)

        {

            return (T)d.GetValue(p);

        }

Which allows glorious code like:

double left = SiteBorder.GetValue<double>(Canvas.LeftProperty);

It isn’t much but I’ll take it.

Conclusion & Next Steps

I have created a live demo at http://www.damonpayne.com/agt ; obviously this is a work in progress but feedback is welcome. 

I have a pretty good idea how I’m going to do resizing, that will come next.  After that I will do multi-select by drawing a rectangle and then Moving.  After moving works I will have to think of how I want object editing to work, some kind of Property Grid I’m sure.  From there, I’ll have to take stock of where I’m at, review my goals, and decide what to do next.

Source code:DamonPayne.AGT[10].zip (1.28 MB)

Monday, September 22, 2008 9:28:30 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Sunday, September 21, 2008

The AGT (Argentum Tela) series of articles is an effort to do two things. Usually an idea is presented only in its finished form. The first goal is to do some Reality Blogging, to show an idea evolve over time without pulling any punches. The second goal, and the example vehicle for the evolution aspect, is an extensible Design Surface for Silverlight similar to what we have in Visual Studio 2008. This type of application has all sorts of interesting uses. My example is a Home Theater layout tool. Read the entire saga: http://www.damonpayne.com/2008/09/14/RunTimeIsDesignTimeForAGT0.aspx

Visual Refactoring

Since this is a Silverlight application I thought I should spend some time making it look good. I hit my frustration limit in a very short period of time and what you see here is as far as I got. I am guessing Styling is not entirely baked in Silverlight 2 beta 2, or else doing a complete control template is really the way to go.

My first issue was with fonts. I downloaded a copy of the Trajan Regular font. Ever since Klipsch started using Trajan pro in the Palladium branding I’ve been digging the Trajan font family. At any rate, it seems that Silverlight is very picky about using extra fonts, be they set from a style or per control. Worse, it’s very difficult to track down where the issue might be. I have three primary tools available to me for Silverlight debugging: Blend 2.5 June CTP, VS2008 SP1, and running the application for inspection. Debugging is not fun when all three tools show different output, check out the ToolboxView:

clip_image002

Blend shows the correct font and color. VS2008 shows the correct nothing. Runtime shows the correct color but not font. I’ve tried obvious things like double checking relative paths and so forth. At this point I’m admitting defeat and moving on. At least my bad taste and visual look stolen from Klipschcorner’s CSS is better than black and grey. Right? Let’s skip to the punchline, here is what the application looks like now:

clip_image004

Couch++

I tricked a visual designer into making me a better purple couch. This person happens to be an extreme Adobe fanboy, to the degree that they didn’t believe me when I said there were other drawing programs for both vector and raster graphics. The Adobe fans are easily worse than the Mac fans. At any rate, that sure looks like a couch, at least. It’s rather large in relation to the design surface, but we’ll fix that with resizification later.

Speakers

I haven’t really thought of what all I want to include in the example HT Layout program, but I figured some speakers would be nice. I’m getting slightly better at drawing some things in Blend: these speakers look better than my original couch. If you’re not familiar with horn-loaded speakers you’ll have to trust me that the white horn shape is actually a reasonable caricature.

Conclusion

I’ll refactor later as I get to read more about the control templating and style creation. I think the app is starting to look like a real program, and we’re still less than 1000 lines of code. The next articles are not written yet, but the next step is to implement functionality that allows me to move, resize, and otherwise Transform things once they are on the designer surface. As it turns out, this is a very interesting problem for all sorts of reasons. I’m not breaking my Reality Blogging pledge, but remember I’ve done this in WinForms before, and I recall things like “selection” being more complex than it sounds: http://msdn.microsoft.com/en-us/library/system.componentmodel.design.iselectionservice_members.aspx . Once selection is implemented moving and resizing come free in WinForms, and I’ve got to build those from scratch now. I’m sure I’ll be spending some time in traffic this week and I’ll spend many mental cycles thinking about the interactions.

Source Code:DamonPayne.AGT[9].zip (1.26 MB)

Sunday, September 21, 2008 7:25:35 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback

This article and AGT[8] were written with Windows Live Writer, after Larry talked me into trying it.  So far, I really like the idea, but the implementation could be better.  I typically write my articles in Word 2007, since I may be working on one for days or weeks.  Cut 'n pasting out of Word into the DasBlog FreeTextBox just works.  Sure, it generates the ugliest HTML you've ever seen, but it looks like code in both IE7 and FF3.  Copy/pasting out of VS2008 into Live Writer looks like this:

ToolboxItem speakItem = new ToolboxItem("Tower speaker", "This is a generic 2-way tower speaker with horn-loaded mid & high range", typeof(HornSpeaker));
Toolbox.AddItem(speakItem, "Audio");

Copy/pasting out of MS Word 2007 into Live Writer looks like this, using the "keep formatting" option.

            ToolboxItem speakItem = new ToolboxItem("Tower speaker", "This is a generic 2-way tower speaker with horn-loaded mid & high range", typeof(HornSpeaker));

            Toolbox.AddItem(speakItem, "Audio");

It's not bad, but it insists on inserting some extra spaces between lines.  I've also been uploading a .zip file of the source code as it stands at the end of each article, and I find no way to do this from Live Writer - perhaps that's not supported by the blogger API.  I do like it inserting & uploading images for me.

For complex articles, I'll still be copy/pasting from Word, but for a free program I do rather like Live Writer.

Sunday, September 21, 2008 7:16:10 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [2]  |  Trackback