Hacking Silverlight, ObservableCollections, & Scarface
In working with Silverlight lately I've found that there's not a lot of documentation, especially for more complex functionality. More times than not I find myself sort of scratching my head and wondering if the solution provided is really the best way to accomplish a certain task.
Let's say you're creating an application that serves up articles (i.e. for a library search application). You have an ItemsControl that uses a article item control as it's DataTemplate. The ItemsSource of this ItemsControl is an ObservableCollection<T> of type, I don't know; SearchResult. The DataContext for your ItemsControl is, you guessed it; SearchResult.
Now say you have, above your search results, a little panel that provides filtering. The filters are List<T> -bound that expand when clicked (and roll up when done). In keeping with our library search application let's pretend the filters are by year (Last Week, Last Month, Last Year, Last 2 Years, etc....) and by topic (Sociology, Psychology, Political Science, Computer Science, etc..). The year filter allows you to select only one (the selection of a listitem triggers the list to hide and the listing of articles below to refresh). The user can select any number of topics. Each listitem in the topic filter has an overlay that provides button functionality such as "SELECT / DESELECT, CLEAR ALL, DONE". When you select an item, it highlights that row. DESELECT unhighlights the row. DONE means you are done selecting and rolls (hides) the list back up. CLEAR ALL is the problem child. Behind the scenes we are storing the id for the listitem in a List<T>. We have easy access to these on MouseLeftButtonUp due to our DataContext being set earlier. Clicking done will trigger the enumeration of this list to build our query and then that is sent to a web service. There is a subscription to the ArticleRefresh trigger and the ItemsControl listing is updated. Easy.
The issue is the unhighlighting of all the listitems in the topic list upon clicking CLEAR ALL. That sounds really easy (and it may very well be!) but I haven't seemed to figure out an efficient way to do this.
In ASP.NET it was extremely easy to enumerate all the controls from within, let's say a Repeater. You have in your ItemTemplate a control that you want to repeat. You could write a little bit of code to enumerate every RepeaterItem and alter the display of certain text and controls within that Repeater. It's extremely easy.
In Silverlight you don't have that luxury. Well, you're supposed to have an easier way of doing business but I haven't yet found it. By the way, I'm talking about Silverlight 2 Beta 2.
My first attempt at this was to create a Converter that sets the IsSelected property based on the presence of the topic's id in the List<T> it is bound to. I get a BAD_PROPERTY_VALUE error when that is attempted.
The next attempt was creating an event handler for the Loaded event of my topic filter control that will cast the sender to the filter object, check to see if the id of the objects DataContext is contained in the List<T>. If it is, highlight, else, no highlight. This works the first time the application is loaded but not on subsequent list views. Reason being the use of the ObservableCollection<T>. The collection itself hasn't changed, so no rebinding needs to occur. This is probably a good thing. What if the collection had 100's, 1000's of items? Makes for quick UI responsiveness.
The only way I have found to accomplish this is instantiating an IEnumerable object, setting its collection to that of the ObservableCollection<T> that the filter list is bound to (public property), then setting said public property to this IEnumerable object that is, in a sense, the same exact thing. This way the collection has changed (sort of), and the CollectionChanged event now gets fired. The list is re-bound and we start from scratch with no highlighted rows.
That seems like kind of a hack to me. Anyone else care to chime in?
I'll try to get a code sample but this is one of those things that I had to voice out first. I hope it's not too hard to follow. For some reason today I had Paul Engemann's "Push it to the Limit" in my head while trying out all sorts of different ways of accomplishing this task. I kind of laughed to myself at the idea of a programming montage set to this song (kind of like in the South Park episode with the skiing contest. And, of course, Scarface).
For the first time EVER on this blog, musical accompaniment:

JSON Serialization with Silverlight Isolated Storage For the Win
I'm going to post this to help others who are killing themselves trying to figure out IsolatedStorage in Silverlight 2 Beta 2. Ordinarily I'd post stuff like this for my own reference but I have had it beaten into my head for the past 12 straight hours.
The IsolatedStorageFile class abstracts the virtual file system for isolated storage. It can be used to store stuff such as application settings or user login information. The application settings being persisted on a user's machine were exactly what we needed to accomplish so that led me down this road. I read numerous blogs, watched countless videos, and did endless searching and finally crafted my solution as a hodge-podge of all of them!
First, what didn't work.
Channel 9 had a video on "how easy it is to persist user application settings" using IsolatedStorage. Their solution consisted of the following:
public class LocalStorageHelper
{
private const string KEY = "FOO";
public static object RetrieveObjectFromLocalStorage()
{
if (IsolatedStorageSettings.ApplicationSettings.Contains(KEY))
return IsolatedStorageSettings.ApplicationSettings[KEY];
return null;
}
public static void UpdateLocalStorageObject(object value)
{
if (IsolatedStorageSettings.ApplicationSettings.Contains(KEY))
IsolatedStorageSettings.ApplicationSettings[KEY] = value;
else
IsolatedStorageSettings.ApplicationSettings.Add(KEY, value);
}
}
Simple enough. The video presenter did all sorts of cool things like shut down the browser, open it back up, press F5 repeatedly and the storage still contained the user data. I'm guessing this solution worked flawlessly in Beta 1. I also had to add the checks for whether or not the ApplicationSettings contained the specified key. Needless to say this implementation isn't very reliable.
It was then that I started looking into JSON and other storage options. I remember in .NET 2.0 I was used to serializing objects into XML and thought I would take this route. This was easier said than done because Silverlight is using a subset of the .NET Framework and the XML Serialization namespace didn't make it. (NOTE: I could've used Linq XML but it was an after thought!).
Enter the DataContractJsonSerializer class. Since we are only given a default storage of 1MB (more can be requested but the end-user has the option of shutting you down) JSON is a likely candidate since it isn't as verbose as XML. A simple string written in a text file within the file store is more than sufficient enough to give us an instance of the object which holds the properties we want to persist.
Some code for converting an object to JSON string and vice-versa.
public
static string ConvertObjectToJsonString(object input)
{
try
{
using (MemoryStream memoryStream = new MemoryStream())
{
DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(input.GetType());
dataContractJsonSerializer.WriteObject(memoryStream, input);
memoryStream.Position = 0;
using (StreamReader streamReader = new StreamReader(memoryStream))
return streamReader.ReadToEnd();
}
}
catch (InvalidDataContractException)
{
return string.Empty;
}
}
public
static T ConvertJsonStringToObject<T>(string json)
{
try
{
using (MemoryStream memoryStream = new MemoryStream())
{
byte[] bytes = Encoding.Unicode.GetBytes(json);
memoryStream.Write(bytes, 0, bytes.Length);
memoryStream.Position = 0;
DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(T));
return (T)dataContractJsonSerializer.ReadObject(memoryStream);
}
}
catch (SerializationException)
{
return default(T);
}
}
You might notice the InvalidDataContractException I am catching above. Like with XML Serialization you want to mark a class & properties as Serializable. If you don't you won't be able to serialize it. Hence the catch block. Here's an example of a serializable class:
using
System.Runtime.Serialization;
namespace
LocalStorage.Objects
{
[DataContract]
public class UserAccount
{
[DataMember] public string EmailAddress { get; set; }
[DataMember] public string Password { get; set; }
}
}
I'll show an example of how to store the user account in a second. First how to open / create this in isolated storage.
public
static void SaveDataToLocalStorage(string data, string filename)
{
try
{
using (IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!isolatedStorageFile.FileExists(filename))
{
using (IsolatedStorageFileStream isolatedStorageFileStream = new IsolatedStorageFileStream(filename, FileMode.Create, isolatedStorageFile))
using (StreamWriter streamWriter = new StreamWriter(isolatedStorageFileStream))
streamWriter.Write(data);
}
else
{
using (IsolatedStorageFileStream isolatedStorageFileStream = new IsolatedStorageFileStream(filename, FileMode.Open, isolatedStorageFile))
using (StreamWriter streamWriter = new StreamWriter(isolatedStorageFileStream))
streamWriter.Write(data);
}
}
}
catch (IsolatedStorageException)
{
}
}
public static string RetrieveDataFromLocalStorage(string filename)
{
try
{
using (IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!isolatedStorageFile.FileExists(filename))|
return string.Empty;
using (IsolatedStorageFileStream isolatedStorageFileStream = new IsolatedStorageFileStream(filename, FileMode.Open, isolatedStorageFile))
using (StreamReader streamReader = new StreamReader(isolatedStorageFileStream))
return streamReader.ReadToEnd();
}
}
catch (IsolatedStorageException)
{
return string.Empty;
}
}
I apologize for the mess but those are some pretty lengthy class names and descriptive variable names 8^)
So now how to use:
// instantiate our user
UserAccount user = new UserAccount
{
EmailAddress = "asdf@asdf.asdf",
Password = "stupid"
};
// convert to JSON string
string json = ConvertObjectToJsonString(user);
SaveDataToLocalStorage(json, "UserAccount.txt");
// convert back to UserAccount
string json = RetrieveDataFromLocalStorage("UserAccount.txt");
if (!string.IsNullOrEmpty(json))
{
UserAccount account = ConvertJsonStringToObject<UserAccount>(json);
// do stuff with userAccount here...
}
Now the user can be persisted on each site visit. If you wanted to store the email address and password you could log your user in when they visit the application. Think "remember me" checkbox or something similar. Another good use would be to serialize the RSS categories and only display those articles from within your silverlight application.
The possibilities are endless. Remember that this information is stored with the client in their AppData folder so don't put anything too private in there ;)
Easy.
UPDATE
If this is a little too cluttered for you to read might I suggest viewing the RSS feed.

Silverlight Databinding and Interaction with Controls
Busy, busy with Silverlight lately. I'm starting to really enjoy it and am learning a ton. It's still so new to me that I don't know if I'm doing everything correctly but I am getting stuff to work ;)
The biggest issue I've had with Silverlight lately is databinding and interacting with the bound data. For example, with ASP.NET you can bind a List<Foo> to a Repeater and implement a method for ItemDataBound event that wires up each of the hyperlinks, buttons, etc... to perform certain actions when each Repeater item is databound. In Silverlight you do not have this luxury. The more I work with Silverlight the more I realize that you don't need this.
The way I have been working with Silverlight is the same as working with ASP.NET in that I am a big fan of encapsulation of functionality. This means modularizing a XAML control with a C# code-behind much like an ASCX in ASP.NET. Let's say you have 2 controls: Article, and ArticleList. ArticleList is simply an ItemsControl of Article's. Simple. Here is the XAML:
ArticleListing.xaml
<StackPanel x:Name="stackPanelArticleListing">
<ItemsControl x:Name="itemsControlArticleListing">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Controls:Article x:Name="article" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
Simple enough. All the binding syntax is in the Article.xaml. In the Article.xaml I have a TextBox called "textArticle" that displays the entire article.
What if I have a button in my Article control that, when clicked, displays the full article in an ArticleViewer control? It's actually pretty easy if you set the DataContext of the ItemsControl control. I've got another Silverlight Class Library as part of my solution and I've got a class called Article. Article looks like this:
public
class Article
{
public Guid ArticleId { get; set; }
public string Author { get; set; }
public string Body { get; set; }
public string Introduction { get; set; }
public DateTime PublishDate { get; set; }
public string PublishDateShort { get; set; }
public string AuthorUrl { get; set; }
public string AuthorImageUrl { get; set; }
}
So when I go to bind my List<Article> to the ItemsControl I would do this:
itemsControlArticleListing.DataContext = new ArticleLibrary.Article();
var results = ArticleLibrary.Article.RetrieveAllArticles();
itemsControlArticleListing.ItemsSource = results;
So now in my Article control I can get the current DataContext by way of the following:
TextBlock
textBlock = sender as TextBlock;
if (textBlock != null)
{
var article = textBlock.DataContext as ArticleLibrary.Article;
if (article != null)
{
// set another control's text property to article stuff :D
}
}
So I set a breakpoint and you can see that my article object above won't be null:

You can also see that I was able to get the exact object that I clicked on. Well, you really can't see it because of the lack of screen grabs but take my word that this is the one that I clicked on.

Awesome right?
Sorry if this post is all over the place. It's been a work in progress and I've been adding snippets here and there in between work!

So I'm Zuning Now
I've had a Zune for a little while now and am just getting around to the social side of things. I'm a Microsoft geekboy for life so that's why I didn't get an iPod.
Peep my uber-cool Zune username and slick Zune Card gadget on the left.
Feel free to add me to your social if you're a Zuner as well. :)

Using Converters for Conditional Silverlight Databinding
Yesterday I posed a question about conditional syntax and how one would accomplish this in xaml / silverlight pages & controls. There were no responses and I'm attributing that to the fact that it is a Friday. Anyway, after a day of much next-level blog-reading and trial-and-error I have come up with a solution that might not be the most elegant but it works.
I'm going to use a converter utility to provide this functionality. This will be a class that implements IValueConverter. This is is an interface that allows one to apply custom logic to a binding which is pretty much what I wanted to do in the first place.
If you are familiar with Scott Guthrie's 8-part series on Silverlight (which is fairly outdated btw with the new release of Beta 2) I will be building on the Digg example from that as that is the most pertinent "Hello World"'ey example I can think of.
So anyone familiar with Digg will know that there is a little box on the left of a story that displays how many diggs a story has.

That screenshot is from the example I built awhile ago following Scott's tutorial. See how even if a story has 1 or 2 the text below still says "diggs" ? With the example I will show you can customize that to where if a story has more than 1 digg it will read "diggs" or else it will simply read "digg". It sounds like a very trivial task (and it kind of is) but not anywhere near as trivial as with ASP.NET.
First add a class file to your SilverlightUI class library and name it something like NumberOfDiggsConverter.cs (what I did).
Here's my class. It's very important to implement the IValueConverter interface.
using
System;
using System.Windows.Data;
using System.Globalization;
namespace
SilverlightSandbox.Converters
{
public class NumberOfDiggsConverter : IValueConverter
{
public object Convert(object value,
Type targetType,
object parameter,
CultureInfo culture)
{
return System.Convert.ToInt32(value) > 1 ? "diggs" : "digg";
}
public object ConvertBack(object value,
Type targetType,
object parameter,
CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
Easy enough. Notice I didn't check the value parameter for null or anything fancy. Again, just a quick example and if you use something like this in production you might want to think about something a little better.
Now that we have our converter class we should register it and use it within our xaml user control.
Here is what my xaml looks like.
BEFORE REGISTERING CONVERTER
<
UserControl x:Class="SilverlightSandbox.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
AFTER REGISTERING CONVERTER
<
UserControl x:Class="SilverlightSandbox.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Converters="clr-namespace:SilverlightSandbox.Converters">
Now create a UserControl.Resources section. I added mine at the top of my page right before my main grid.
<UserControl.Resources>
<Converters:NumberOfDiggsConverter x:Key="DiggConverter" />
</UserControl.Resources>
The next, and final, step is to actually implement this. In our case we will set the text property of the digg block to the NumberOfDiggs property of my Digg object. I'll show the before and after syntax of the # of diggs text block.
BEFORE
<
TextBlock Text="diggs" />
AFTER
<
TextBlock Text="{Binding Diggs, Converter={StaticResource DiggConverter}}" />
Here's the final result:

Easy.

Is There A Conditional Syntax for Silverlight UI Databinding?
I'm working on a Silverlight 2 project currently and am running into sort of a wall when it comes to databinding. Without going into too much detail let's take into the consideration that I have the following objects.
List<Foo> list;
Repeater repeaterFoo;
My repeaterFoo's DataSource property is the list above. Let's say depending on a certain property of Foo that I want to display a 1 or a 2 in my UI. That's a pretty basic requirement right?
Here's how I would do this in ASP.NET:
<asp:Repeater ID="repeaterFoo" runat="server">
<ItemTemplate>
<%# string.IsNullOrEmpty(Eval("Name").ToString()) ? "1" : "2" %>
</ItemTemplate>
</asp:Repeater>
Now, for the sake of argument (and proof of concept); let's pretend that this example is 100% useful. How would I accomplish this in Silverlight 2 with it's funky { Binding PropertyName } syntax?
I'm not expecting any simple answer after seeing the dog-and-pony show that is formatting a date / currency in a Grid.
Don't get me wrong, I absolutely love Silverlight so far, it's just kind of frustrating trying to get used to the little things that were oh-so-easy in ASP.NET!
Thanks in advance.
UPDATE
I figured this out. New entry to come soon.
Hint: It relates to the dog-and-pony show I alluded to earlier :(

Outlook Doesn't Respond After Latest Windows Update
Just installed a bunch of Windows Updates for my laptop and now I can't send / receive e-mail with Outlook. After about a minute or so it NOT RESPONDING's out. It was mostly updates dealing with Office 2007 so I'm guessing something went south. Needless to say I am uninstalling all of them and turning off automatic updates.
The only difference between now and last night at midnight when I went to bed was that I could send / receive e-mail then and updates were installed in the meantime.
WTF Microsoft?
UPDATE
Restored my system to the point right before installing the updates (thankfully this restore point is automatically created) and my Outlook works as it did before.
I think it's safe to say there was something iffy about this update as it relates to my computer. Weird.

LINQ to SQL and Using Multiple Connection Strings
So I found something pretty interesting today in regards to LINQ and LINQ-to-SQL classes. I was setting up a staging server to deploy a new 3.5 web application. I then realized, "Oh crap, different connection string!". This should be easy as all I should have to do is modify the app.config and update the connectionString accordingly. WRONG!
The connection string is actually compiled into the code. That sucks. Here's what I see in Reflector:
[SpecialSetting(SpecialSetting.ConnectionString), ApplicationScopedSetting, DebuggerNonUserCode, DefaultSettingValue("Data Source=(local);Initial Catalog=FooDB;User ID=;Password=")]
public string FooDBConnectionString
{
get
{
return (string) this["FooDBConnectionString"];
}
}
Gross. I thought of a work-around that could work. This code is in the Settings.Designer.cs class so I could do something like:
public
string FooDBConnectionString
{
#if DEBUG
get { return ((string)(this["FooDBConnectionStringDev"])); }
#else
get { return ((string)(this["FooDBConnectionStringProduction"])); }
#endif
}
This way the appropriate connection string could be compiled into the code depending on whether or not the configuration for the project is set to Debug or Release. The thing about this solution is that you would have to write this code each and every time you regenerate your LINQ-to-SQL class file(s). Very inefficient. *NOTE* For this to even work you have to add another connection string in your Settings file. No thanks.
The REAL way to solve this:
- Create a LINQ-to-SQL dbml file with an initial connection string
- Right-click dbml surface
- Click 'Properties'
- Expand the 'Connection' node
- Select 'None' for Connection String
- Select 'True' for Application Settings (don't know if this is completely necessary)
- Create a partial class for 'YourDataContextHere'
- Within this partial class create a parameterless constructor for 'YourDataContextHere'
- Set your base connection string accordingly a la:
public
FooDB() : base(ConfigurationManager.ConnectionStrings["FooDB"].ConnectionString, mappingSource)
{
// anything else
}
Just make sure you have ConnectionStrings node in your app/web configuration files and that you have the specified key in there or this won't work :D
Easy. Now you can throw a different connection string in your Business Layer's configuration file and be good to go.
Thanks to Jon Gallant and David Klein for the initial posts.

Elegant Way of Executing a Stored Procedure using LINQ?
I was working in a project today and I was trying to create a generic way of using a DataContext class to execute a stored procedure. Of course there's the way of dragging a stored procedure onto the designer, etc... but I'm not interested in this at the moment. TBQH, I haven't even been doing the ORM mapping in this manner lately after using the System.Data.Linq.Mapping namespace to map a POCO (Plain 'Ole CLR Object) to an actual SQL table (as well as using ColumnAttribute's to map the properties to columns. This is extremely helpful for larger 2.0 projects that were recently converted to 3.5. Some might argue that this isn't how LINQ was supposed to be used or that it makes it more complicated. First of all, I don't think that there is any right or wrong way to use LINQ. Secondly, I find it can be a pain to have to remove the table from the designer, reconnect via Server Explorer, refresh the database, re-drag onto designer over-and-over when making changes to tables, views, procedures, etc... This is also problematic if you don't have access to a production database from your dev environment. Most web servers I experience don't have Visual Studio 2008 installed so it's not like I can quickly generate a newer set of LINQ-to-SQL classes. If a table column name changes, I simply refactor the corresponding property in my library and I'm good to go.
[Table(Name = "dbo.FooTable")]
public class Foo
{
#region Table Columns / Properties
[Column]
public long FooId { get; set; }
[Column]
public string FooName { get; set; }
[Column]
public string FooDescription { get; set; }
#endregion Table Columns / Properties
}
Easy.
public
class Database<TDataContext, TEntity>
{
// ...
}
Take the previous data access helper class. Let's say I want to create just a generic function to execute a stored procedure against my database. Let's call it "ExecuteCommand".
public
static void ExecuteCommand(string command, object[] parameters)
{
if (string.IsNullOrEmpty(command))
throw new ArgumentNullException("command");
using (var database = new TDataContext())
database.ExecuteCommand(command, parameters);
}
Basic. The implementation is pretty mindless as well.
Database
<MyDataContext, TFoo>.ExecuteCommand("CommandName", null);
This sucks when you have parameters because I haven't found any documentation on how to execute a procedure elegantly using this approach. It appears that the DataContext.ExecuteCommand approach is best-suited for on-the-fly dynamic SQL.... gross! I also read (need to find the link again) that some super-sleuthing uncovered that parameter substitution is silently ignored. (I'll have to check back on that)
I did find a way to implement using a stored procedure....
string
command = string.Format("exec Command '{0}', {1}", "string", 1);
Database<MyDataContext, TFoo>.ExecuteCommand(command, null);
That is disgusting. Not a huge fan. What if you have a procedure that has 5, 10, 20 parameters? Ouch. What if your input parameters contain ' 's? You would then have to replace all ' with a ''.
Any suggestions? I'm hoping that there is a much more elegant / succinct way of doing this that I haven't found yet. I've tried to "RTFM" as they say but a couple thousand pages of LINQ reference books and I've got nothing.
Here's a little 2.0 throwback of what I'm trying to accomplish. Like I said before, there has to bge a more elegant way of doing this with the 3.5 Framework / LINQ / DataContext that doesn't involve dragging-and-dropping procedures onto the designer.
public
static int ExecuteProcedure(List<SqlParameter> parameters, string command)
{
try
{
using (DBManager manager = ...)
{
manager.Open();
manager.CreateParameters(parameters.Count);
for (int i = 0; i < parameters.Count; ++i)
manager.AddParameters(i, parameters[i].ParameterName, parameters[i].Value);
return (int) manager.ExecuteScalar(CommandType.StoredProcedure, command);
}
}
catch (SqlException)
{
return 0;
}
}
Help me from the following please!!
StringBuilder
query = new StringBuilder("exec Command ");
query.AppendFormat("{0},", foo.FooProperty1);
query.AppendFormat("'{0}',", foo.FooProperty2.Replace("'", "''"));
query.AppendFormat("'{0}',", foo.FooProperty3.Replace("'", "''"));
query.AppendFormat("'{0}',", foo.FooProperty4.Replace("'", "''"));
query.AppendFormat("'{0}',", foo.FooProperty5.Replace("'", "''"));
query.AppendFormat("'{0}',", foo.FooProperty6.Replace("'", "''"));
query.AppendFormat("'{0}'", foo.FooProperty7.Replace("'", "''"));
Database<MyDataContext, Foo>.ExecuteCommand(query.ToString(), null);

SQL 2005 & Full-Text Indexing on Vista Ultimate
I tried to setup a database with full-text indexing today as part of an application I'm working on. I followed instructions to a T and I received the following error:

Awesome. The only difference I can think of is that the machine that this was successfully created on happened to be running Windows XP SP2. I am running Vista Ultimate.
Naturally I started Googling the error only to find nothing really helpful. It's all speculation. I just downloaded a 284MB .msi for SQL Server 2005 SP2 since "you have to install SP2 if you are running Vista and you want SQL Server 2005 to work properly."
At this point I'll try anything. If you have any suggestions, by all means...
UPDATE
I'm awesome. Not really (yes) but through extensive Google-searching, next-level blogging and waving a dead chicken over my laptop I have finally resolved this.
The culprit was a NTLMSSP (NT LAN Manager Security Support Provider aka NAMBLA)service dependency. TBQH, I don't really give a shit what it does, all I needed to know is that:
This service has been removed from Windows Vista and Windows Server 2008 in favor of the newer Kerberos authentication protocol.
So, a service is removed entirely from Windows Vista and Server 2008 and a dev team thought it would be a good idea to either a) take it out of the OS entirely or b) make SQL Server 2005 depend on it. That makes perfect sense.
All kidding aside, get to your registry settings by way of regedit.exe or Start -> Run -> regedit and look for:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\msftesql
Remove NTLMSSP and reboot. Easy. Thanks Tanzim and some dba-type from a Google Groups thread!
