| Comments

Flickr4Writer is a plug-in for Windows Live Writer, a blog authoring tool available free to anyone.  The plug-in enables a Flickr user (Flickr account is required) to browse their own photos as well as others and insert the content into a blog post using Writer.

The plug-in enables you to search all your content, photosets, or search by tags.  It is available for free and can be downloaded from Codeplex.  For developers, the code is also made available if you want to contribute fixes and features (that comply with Flickr API terms of use). 

UPDATE: Plugin has been updated to follow new Flickr API terms of use.  Get the latest version here.

I hope that you enjoy the plug-in!

| Comments

Sometimes I think reading materials get overlooked in SDKs and we miss some hidden gems.  One such gem I’d like to bring to your attention is the ability to add some subtle styling to an AutoCompleteBox from the Silverlight Toolkit to provide you with a cheap version of an editable ComboBox.

Sure Silverlight 2 has a ComboBox as part of the core controls now, but as I’ve previously noted, the ComboBox in current form exhibits only DropDownList behaviors.  I’m sure this will likely change with future versions, but if you have a need for an editable ComboBox feel, here’s a start.

If you think about the AutoCompleteBox functionality, it provides a list of items that are filtered when the user starts typing in there.  Well, that’s one function of a ComboBox right?  The other exhibited behavior we need is to be able to click to activate the DropDownList functionality and select.  Here’s where styling comes in (with a little help from some properties on AutoCompleteBox as well).

Let’s start by adding the items we’ll be dealing with: AutoCompleteBox and a data class (I’ll use a local hard-coded data class for portability in this code).  To use the AutoCompleteBox, make sure you’ve downloaded the Silverlight Toolkit and then add a reference in your Silverlight project to Microsoft.Windows.Controls.dll.  Then add the xmlns decoration in your UserControl…here’s mine (I use “toolkit”):

   1: <UserControl x:Class="ACBEditCombo.Page"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:toolkit="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
   5:     Width="400" Height="300">
   6:     <Grid x:Name="LayoutRoot" Background="White">
   7:         <toolkit:AutoCompleteBox MinimumPrefixLength="0" 
   8:                                  MinimumPopulateDelay="200" 
   9:                                  x:Name="FruitChoice"
  10:                                  Width="200" Height="25" />
  11:     </Grid>
  12: </UserControl>

Here’s the Fruit class I’ll be using:

   1: #region Fruit Class
   2:     public class Fruit
   3:     {
   4:         public string Name { get; set; }
   5:         public override string ToString()
   6:         {
   7:             return this.Name;
   8:         }
   9:  
  10:         public static List<Fruit> GetFruitChoices()
  11:         {
  12:             List<Fruit> choices = new List<Fruit>();
  13:  
  14:             choices.Add(new Fruit() { Name = "Apple" });
  15:             choices.Add(new Fruit() { Name = "Apricot" });
  16:             choices.Add(new Fruit() { Name = "Banana" });
  17:             choices.Add(new Fruit() { Name = "Orange" });
  18:             choices.Add(new Fruit() { Name = "Pineapple" });
  19:             choices.Add(new Fruit() { Name = "Mango" });
  20:             choices.Add(new Fruit() { Name = "Papaya" });
  21:             choices.Add(new Fruit() { Name = "Pumpkin" });
  22:  
  23:             return choices;
  24:         }
  25:     }
  26:     #endregion

As you can see it is simple, but I wanted to make sure I was using more than just a string (yes I know essentially it is an object with only a string, but think outside the box :-)).  Now we can wire up this code here to get our AutoCompleteBox behavior working:

   1: public partial class Page : UserControl
   2: {
   3:     List<Fruit> choices = Fruit.GetFruitChoices();
   4:  
   5:     public Page()
   6:     {
   7:         InitializeComponent();
   8:         Loaded += new RoutedEventHandler(Page_Loaded);
   9:     }
  10:  
  11:     void Page_Loaded(object sender, RoutedEventArgs e)
  12:     {
  13:         FruitChoice.ItemsSource = choices;
  14:         FruitChoice.ItemFilter = (prefix, item) =>
  15:             {
  16:                 if (string.IsNullOrEmpty(prefix))
  17:                 {
  18:                     return true;
  19:                 }
  20:  
  21:                 Fruit f = item as Fruit;
  22:  
  23:                 if (f == null)
  24:                 {
  25:                     return false;
  26:                 }
  27:  
  28:                 return f.Name.ToLower().Contains(prefix.ToLower());
  29:             };
  30:     }
  31: }

Here we are using the same ItemFilter method I noted previously about AutoCompleteBox.  Once we have this when we start typing we’ll get:

Now all we need to do is make it look and act also like a ComboBox.  Here we can take styles and apply them.  We’re going to do three things using Style resources:

    1. Modify the control template for our toolkit:AutoCompleteBox to include a ToggleButton
    2. Create a style for the ToggleButton that looks like an arrow to cue the user what to do with it
    3. Style the list displayed a little bit

Best of all – we’re not going to change any of our logic code.  None.  First let’s modify the control template.  I’m putting these in my App.xaml resources so my app could use them globally.  Here’s the full style for the new control template which has new content in there and a ToggleButton added (I’ll keep it collapsed here for the sake of making this post less verbose than it already is):

   1: <Style x:Key="EditableComboStyle" TargetType="toolkit:AutoCompleteBox">
   2:             <Setter Property="SearchMode" Value="StartsWith" />
   3:             <Setter Property="Background" Value="#FF1F3B53"/>
   4:             <Setter Property="IsTabStop" Value="False" />
   5:             <Setter Property="HorizontalContentAlignment" Value="Left"/>
   6:             <Setter Property="BorderBrush">
   7:                 <Setter.Value>
   8:                     <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
   9:                         <GradientStop Color="#FFA3AEB9" Offset="0"/>
  10:                         <GradientStop Color="#FF8399A9" Offset="0.375"/>
  11:                         <GradientStop Color="#FF718597" Offset="0.375"/>
  12:                         <GradientStop Color="#FF617584" Offset="1"/>
  13:                     </LinearGradientBrush>
  14:                 </Setter.Value>
  15:             </Setter>
  16:             <Setter Property="Template">
  17:                 <Setter.Value>
  18:                     <ControlTemplate TargetType="toolkit:AutoCompleteBox">
  19:                         <Grid Margin="{TemplateBinding Padding}">
  20:                             <VisualStateManager.VisualStateGroups>
  21:                                 <VisualStateGroup x:Name="PopupStates">
  22:                                     <VisualStateGroup.Transitions>
  23:                                         <VisualTransition GeneratedDuration="0:0:0.1" To="PopupOpened" />
  24:                                         <VisualTransition GeneratedDuration="0:0:0.2" To="PopupClosed" />
  25:                                     </VisualStateGroup.Transitions>
  26:                                     <VisualState x:Name="PopupOpened">
  27:                                         <Storyboard>
  28:                                             <DoubleAnimation Storyboard.TargetName="PopupBorder" Storyboard.TargetProperty="Opacity" To="1.0" />
  29:                                         </Storyboard>
  30:                                     </VisualState>
  31:                                     <VisualState x:Name="PopupClosed">
  32:                                         <Storyboard>
  33:                                             <DoubleAnimation Storyboard.TargetName="PopupBorder" Storyboard.TargetProperty="Opacity" To="0.0" />
  34:                                         </Storyboard>
  35:                                     </VisualState>
  36:                                 </VisualStateGroup>
  37:                             </VisualStateManager.VisualStateGroups>
  38:                             <TextBox IsTabStop="True" x:Name="Text" Style="{TemplateBinding TextBoxStyle}" Margin="0" />
  39:                             <ToggleButton 
  40:                                 x:Name="DropDownToggle" 
  41:                                 HorizontalAlignment="Right"
  42:                                 VerticalAlignment="Center"
  43:                                 Style="{StaticResource ComboToggleButton}"
  44:                                 Margin="0"
  45:                                 HorizontalContentAlignment="Center" 
  46:                                 Background="{TemplateBinding Background}" 
  47:                                 BorderThickness="0" 
  48:                                 Height="16" Width="16"
  49:                                 >
  50:                                 <ToggleButton.Content>
  51:                                     <Path x:Name="BtnArrow" Height="4" Width="8" Stretch="Uniform" Data="F1 M 301.14,-189.041L 311.57,-189.041L 306.355,-182.942L 301.14,-189.041 Z " 
  52:                                           Margin="0,0,6,0" HorizontalAlignment="Right">
  53:                                         <Path.Fill>
  54:                                             <SolidColorBrush x:Name="BtnArrowColor" Color="#FF333333"/>
  55:                                         </Path.Fill>
  56:                                     </Path>
  57:                                 </ToggleButton.Content>
  58:                             </ToggleButton>
  59:                             <Popup x:Name="Popup">
  60:                                 <Border x:Name="PopupBorder" HorizontalAlignment="Stretch" Opacity="0.0" BorderThickness="0" CornerRadius="3">
  61:                                     <Border.RenderTransform>
  62:                                         <TranslateTransform X="2" Y="2" />
  63:                                     </Border.RenderTransform>
  64:                                     <Border.Background>
  65:                                         <SolidColorBrush Color="#11000000" />
  66:                                     </Border.Background>
  67:                                     <Border HorizontalAlignment="Stretch" BorderThickness="0" CornerRadius="3">
  68:                                         <Border.Background>
  69:                                             <SolidColorBrush Color="#11000000" />
  70:                                         </Border.Background>
  71:                                         <Border.RenderTransform>
  72:                                             <TransformGroup>
  73:                                                 <ScaleTransform />
  74:                                                 <SkewTransform />
  75:                                                 <RotateTransform />
  76:                                                 <TranslateTransform X="-1" Y="-1" />
  77:                                             </TransformGroup>
  78:                                         </Border.RenderTransform>
  79:                                         <Border HorizontalAlignment="Stretch" Opacity="1.0" Padding="2" BorderThickness="2" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3">
  80:                                             <Border.RenderTransform>
  81:                                                 <TransformGroup>
  82:                                                     <ScaleTransform />
  83:                                                     <SkewTransform />
  84:                                                     <RotateTransform />
  85:                                                     <TranslateTransform X="-2" Y="-2" />
  86:                                                 </TransformGroup>
  87:                                             </Border.RenderTransform>
  88:                                             <Border.Background>
  89:                                                 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
  90:                                                     <GradientStop Color="#FFDDDDDD" Offset="0"/>
  91:                                                     <GradientStop Color="#AADDDDDD" Offset="1"/>
  92:                                                 </LinearGradientBrush>
  93:                                             </Border.Background>
  94:                                             <ListBox x:Name="SelectionAdapter" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" ItemTemplate="{TemplateBinding ItemTemplate}" />
  95:                                         </Border>
  96:                                     </Border>
  97:                                 </Border>
  98:                             </Popup>
  99:                         </Grid>
 100:                     </ControlTemplate>
 101:                 </Setter.Value>
 102:             </Setter>
 103:         </Style>

Now if you look you’ll see that the ToggleButton itself has a Style attribute, so here’s the Style we use for that:

   1: <Style x:Name="ComboToggleButton" TargetType="ToggleButton">
   2:             <Setter Property="Foreground" Value="#FF333333"/>
   3:             <Setter Property="Background" Value="#FF1F3B53"/>
   4:             <Setter Property="Padding" Value="0"/>
   5:             <Setter Property="Template">
   6:                 <Setter.Value>
   7:                     <ControlTemplate TargetType="ToggleButton">
   8:                         <Grid>
   9:                             <Rectangle Fill="Transparent" />
  10:                             <ContentPresenter
  11:                             x:Name="contentPresenter"
  12:                             Content="{TemplateBinding Content}"
  13:                             ContentTemplate="{TemplateBinding ContentTemplate}"
  14:                             HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
  15:                             VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
  16:                             Margin="{TemplateBinding Padding}"/>
  17:                         </Grid>
  18:                     </ControlTemplate>
  19:                 </Setter.Value>
  20:             </Setter>
  21:         </Style>

Now the only thing we need to do is add the Style attribute for our AutoCompleteBox as reflected here (notice the added Style attribute):

   1: <UserControl x:Class="ACBEditCombo.Page"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:toolkit="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
   5:     Width="400" Height="300">
   6:     <Grid x:Name="LayoutRoot" Background="White">
   7:         <toolkit:AutoCompleteBox MinimumPrefixLength="0" 
   8:                                  MinimumPopulateDelay="200" 
   9:                                  x:Name="FruitChoice"
  10:                                  Width="200" Height="25"
  11:                                  Style="{StaticResource EditableComboStyle}"/>
  12:     </Grid>
  13: </UserControl>

And now when we look at our application running we have what looks to be an editable ComboBox:

The ComboBox behavior is enabled now via the ToggleButton and the MinimumPrefixLength attribute on the AutoCompleteBox (try changing it to 1 and you’ll see that you don’t get exactly the same behavior).

It’s little gems like this that should cause you to pay attention to the finer details of SDKs, samples, etc.  I hope you found this helpful…if you have, please consider subscribing for more samples like this (and no I’m not planning on just emitting all the SDK samples :-)).  You can download my code for this above in a complete solution here: ACBEditCombo.zip.

| Comments

Remember DreamSpark, the program for students in higher education to get access to the developer tools and platforms from Microsoft at no charge?  How about some love for individuals in startup organizations trying to create the next great innovation in technology as a service, an application, some Silverlight love perhaps :-)?

Done.

A new program has just launched for startups.  From the site it is described as:

Microsoft® BizSpark™ is a global program designed to help accelerate the success of early stage startups by providing key resources when they need it the most:

  • Software. Receive fast and easy access to current full-featured Microsoft development tools, platform technologies, and production licenses of server products for immediate use in developing and bringing to market innovative and interoperable solutions. There is no upfront cost to enroll.
  • Support. Get connected to Network Partners around the world — incubators, investors, advisors, government agencies and hosters — that are equally involved and vested in software-fueled innovation and entrepreneurship who will provide a wide range of support resources.
  • Visibility. Achieve global visibility to an audience of potential investors, clients and partners
    As a Microsoft BizSpark member, you’ll be tapping into a rich, vibrant ecosystem of peers, partners and support resources around the globe, helping you grow and succeed. Microsoft BizSpark is the quickest way to get your Startup fired up.

Source: http://www.microsoftstartupzone.com/BizSpark/Pages/At_a_Glance.aspx

So what do you get as benefits in the program?

    • All the software included in the Microsoft® Visual Studio® Team System Team Suite (VSTS) with MSDN® Premium subscription
    • Expression® Studio Version 2
    • VSTS Team Foundation Server (standard edition)
    • Production use rights to host a “software as a service” solution (developed during participation in the BizSpark Program, on any platform) over the Internet, with regard to products including:
      • Microsoft Windows Server® (all versions up to and including Enterprise)
      • Microsoft SQL Server® (all versions)
      • Microsoft Office SharePoint® Portal Server
      • Microsoft System Center
      • Microsoft BizTalk® Server

There are key requirements for qualifying, so be sure to read about them.

To qualify for BizSpark, your startup must be:

  • Actively engaged in development of a software-based product or service that will form a core piece of its current or intended business[1],
  • Privately held,
  • In business for less than 3 years[2], and
  • Generating less than USD $1 million in annual revenue[3].

To be eligible to use the software for production and deployment of hosted solutions, startups must also be developing a new "software as a service" solution (on any platform) to be delivered over the Internet. Source: http://www.microsoftstartupzone.com/BizSpark/Pages/Do_I_Qualify.aspx

You can read all about the program details on the BizSpark information site.  So if you are a startup and looking to accelerate, take a look at this program.  It looks like the BizSpark team is also creating BizSparkDB, a center for startups to be profiled and visible.

What are you waiting for?  See if you qualify and then enroll!

| Comments

PDX baby.  That’s where I’m headed next week.  The Portland area user experience group (a SIG formed out of the Portland .NET user group) is hosting a Silverlight 2 launch party next week (11 NOV 2008).  They’ve invited me to attend and share some fun stuff about Silverlight 2.  I’m very excited to be going there because Portland is one of my favorite towns.  It has some of the best public transportation there and I think that makes for a great downtown experience and a lot of personality in the city.

Aside from the city itself, there are some great folks that will be there: Jason Mauer, Erik Mork, and Kelly White.  Maybe we can convince Hanselman to show up as well?  There will be dinner provided by Microsoft I’m told and then we’ll show some Silverlight stuff.  What will I be talking about?  I think I’ve decided to show a couple things:

    • Accessing data with Astoria
    • Building “traditional” line-of-business applications
    • Silverlight offline applications

There will also be some demo station areas after the main presentation where myself, Erik, Kelly and Jason will be showing some other stuff or to answer questions.  I’m seriously hoping there is some Rock Band action there so I can show my Chop Suey skills on the guitar.  If there isn’t, I know there will be a great group of folks to geek out with anyway.

So if you are in the area (or if you’re not, consider a short drive), please join us on 11 NOV @ 6:30 PM Pacific for the November meeting of the PDXUX group.  You can find all the details and a map to the location on the PDXUX web site.  Please also visit the registration site to RSVP your intent to come so that their planning team can estimate accordingly.  I’m looking forward to talking with some Portland developers about Silverlight and getting some feedback!

Hope to see you there!

| Comments

I’m sorry, but the link you clicked on or the page you were looking for couldn’t be found here.  I’ve tried my best to maintain all the permalinks on this site since I started it in 2003.  For the most part everything should be here, but it seems you’ve hit an area that I couldn’t find.

I’d encourage you to perform a search by starting here with Live search and adding your term into the search box.  You may also visit the archives or view the tag listing (it’s verbose, but you may find what you are looking for) to find a starting point.

If you still cannot find what you are looking for from my site, please feel free to reach out and contact me.  I’m usually immediately responsive if I’m available and have various ways to contact me.

I hope that you find this site valuable to you and ask that you consider subscribing to my site with your favorite RSS reader or you may also subscribe through email.