advanced web statistics

Way to Go Vista File Transfers!

Better grab a lunch, or 9.

kick it on DotNetKicks.com

The Zune Update Totally Sucks

Updated the Zune application software this morning at about 7:00am.  Since I had no choice in the matter, I went ahead and did it ;)

Wow.  Talk about a change... for the worst.  The application seems to lag a lot even when I have nothing else open.  If I try to listen to it with Visual Studio 2008, SQL Management Studio, and Outlook forget about it.  Too bad because those are all the things I use on a daily basis for work.  That's also when I listen to the most of my music.

Luckily I've got 4 stereos in the house wired up to my Zune player so depending on where in the house I'm working (laptop) I can listen to my music.  I've also got 2 30GB zunes for this and am thinking of buying another when the new line is released (if it hasn't been already).

Like any Microsoft product there will be a patch released for the Zune software if enough people are experiencing these symptoms and at the end of the day I'm still glad I don't use any Apple products.

Does anyone else find that the Zune software responds a lot like a poorly-written RIA (rich internet application)?  To me it responds like Silverlight applications do when they are first written; before any story board animations / overlays are added to let the user know that SOMETHING is actually happening.  Just a thought....

If anyone from Zune reads this you might want to update the Zune Card widget (see left navigation column) to utilize Silverlight instead of Flash.  It would probably be a good look since, you know; you're Microsoft and you have this new technology you want to promote.

Looks like I'll try this again later.  Maybe rebooting (again) will help.

UPDATE
Unresponsiveness of the application aside, the hardware update seems to be pretty sweet! Now I can play games while listening to tasty licks by The Chameleons.  The wireless feature is pretty sweet. I wonder if I have to be at one of 9,800 McDonald's restaurants to be able to download?  I'd guess not...

kick it on DotNetKicks.com

No Generic List FindAll Method in Silverlight 2 Beta 2

Came across a need this morning to use the FindAll method. To my dismay it wasn't there.  I know that Silverlight uses a subset of the .NET Framework but the System.Collections.Generic namespace is definitely there.

System.Collections.Generic namespace in Silverlight 2 Beta 2

You can clearly see that I'm using the namespace in the above image.

ReSharper List.FindAll Error Silverlight 2 Beta 2

Here you can see that ReSharper's background compiling caught it right away. For a second there I thought: "You know, maybe ReSharper is full of shit. This can't be right." I tried to compile to make sure (which was the case with the version 4 nightly builds).

'System.Collections.Generic.List' does not contain a definition for 'FindAll' and no extension method 'FindAll' accepting a first argument of type 'System.Collections.Generic.List' could be found (are you missing a using directive or an assembly reference?)

Weird.

kick it on DotNetKicks.com

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:

kick it on DotNetKicks.com

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.

kick it on DotNetKicks.com

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:

Article != 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.

Article object local information

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!

kick it on DotNetKicks.com

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. :)

kick it on DotNetKicks.com

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.

Digg Example

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.

kick it on DotNetKicks.com

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 :(

kick it on DotNetKicks.com

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.

kick it on DotNetKicks.com

<< Newer Entries Older Entries >>