Matt Casto's .NET Journal RSS 2.0
 Monday, April 21, 2008

This is a very simple animation that can be used just about anywhere.

[[ If you're viewing this post through an RSS reader, you won't be able to see the Silverlight example ]]

Following is my Page.xaml for this example.  There was no code needed.

<UserControl x:Class="AnimationSample.Page"
    xmlns="http://schemas.microsoft.com/client/2007" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="300" Height="150">
  <Grid x:Name="LayoutRoot" Background="White">
    <Grid.Triggers>
      <EventTrigger RoutedEvent="Grid.Loaded">
        <EventTrigger.Actions>
          <BeginStoryboard>
            <Storyboard x:Name="CrawlingBorder" RepeatBehavior="Forever">
              <DoubleAnimationUsingKeyFrames Storyboard.TargetName="rectangle" 
                Storyboard.TargetProperty="(Shape.StrokeDashOffset)" BeginTime="00:00:00">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" />
                <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="5" />
              </DoubleAnimationUsingKeyFrames>
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger.Actions>
      </EventTrigger>
    </Grid.Triggers>
    <Rectangle Stroke="Green" StrokeThickness="6" StrokeDashArray="3,2" StrokeDashCap="Round" 
               Margin="20" StrokeDashOffset="0" StrokeLineJoin="Round" x:Name="rectangle">
    </Rectangle>
    <TextBlock FontFamily="Lucida Sans Unicode" FontSize="24" 
               Text="Crawling Border" FontWeight="Bold" 
               HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="#FFDE680A"/>
  </Grid>
</UserControl>
Monday, April 21, 2008 9:55:36 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
silverlight

I gave a talk at the Central Ohio Day of .NET last Saturday about Silverlight 2.  The presentation was written in Silverlight 2 Beta 1 and included examples of functionality built into Silverlight versions 1 and 2, and the beginning steps in creating the presentation itself.

I have much more planned to be added to the presentation, so I created a CodePlex project called PresentLight.  I'm hoping that other people will like the idea of giving a presentation in the technology that they're speaking about, and maybe they'll use the framework or even add their own content!

I uploaded a slightly older version than the one I gave at CODoDN to silverlight.live.com, check it out by clicking on the following preview image.  The XAP is 14 MB so expect a decent wait for everything to load ... I need to reduce the size.  I'll update this post with a better example as soon as I have it available.

Much thanks goes out to Jeff Blankenburg for building the original slide deck that I based this presentation on.  Also, I got the idea from David Sleeckx's WPF presentation, which is an excellent way to get an overview of WPF.

Using the Presentation

You can navigate the slides through the menu on the left, or move forward one slide by clicking on the header area.  A few of the slides don't have much at first, but clicking in the slide area will show text which was talking points for that part of the presentation.  The interactive slides in the middle should be pretty self explanatory - you can modify the XAML in most of the examples to see changes in real time.

The screen shots at the end can be clicked on to view the full size.  I wanted to keep the entire presentation in Silverlight, so I was trying to use screen shots instead of jumping into Visual Studio.  These slides were taking over an hour each to prepare, because I was trying to give each one a different type of animation.  I think they ended up being a little disjointed though - its much more natural to see someone working with the environment than seeing screen shots of some code, then the solution explorer, then XAML.  I'm definitely going to have to give more thought to that area.

Plans for the Future

I plan to have the slides stored in data rather than hard coded in the page code behind.  I'm going to integrate more examples, such as Isolated Storage, Communications with web services and through sockets, and dynamic languages integrated directly into the slides, like I did with the XAML examples.

Also, I'm going to expand more on some of the user controls that I created as part of the application.  I already went into the scrolling textbox control in my last post, so there will be more of that on the way.

Monday, April 21, 2008 9:15:26 PM (Eastern Standard Time, UTC-05:00)  #    Comments [2] -
silverlight
 Sunday, April 13, 2008

The TextBox control included with Silverlight 2 Beta 1 is a welcome addition.  There was no such control in previous versions of Silverlight, including the alpha.

Unfortunately, the TextBox control is very limited at this point.  It does not support scrollbars when it's content is larger than it's size.  You can "scroll" the next by moving the cursor, but that's just enough to make it functional.  Selecting text past what's visible doesn't automatically scroll to the cursor.  Also, there's no text wrapping, although setting the AcceptsReturn property to True will allow line breaks in the text.

I wanted to have a text box with a little more functionality for my projects, so I decided to see what I could do.  What follows is the simple ScrollingTextBox control that I created.  I didn't spend a ton of time on this because I fully expect this "missing" functionality to be included by Beta 2, or at least by the time Silverlight 2 is released.

 

To build this, I first created a Silverlight application project and added a Silverlight control called ScrollingTextBox.

<UserControl x:Class="PresentLight.ScrollingTextBox"
    xmlns="http://schemas.microsoft.com/client/2007" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid x:Name="LayoutRoot">
    <ScrollViewer x:Name="sv" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
      <TextBlock x:Name="hiddenTextBlock" Opacity="0" />
      <TextBox x:Name="tb" AcceptsReturn="True" TextChanged="tb_TextChanged" />
    </ScrollViewer>
  </Grid>
</UserControl>

The internal TextBlock control is only there to serve as a way to get the actual size of the text.  TextBlock controls will automatically resize to fit their contents, so if I keep it's text the same as the internal textbox control, it will resize accordingly.  The default value for Width and Height dependency properties in Silverlight is Auto, which causes this resize behavior.

Since the ScrollViewer control automatically set's it's scrollable region to fit it's contents, it will be resized to fit the internal textblock.  The internal textbox control will automatically resize to fit it's container, since I haven't set any width or height on it.

Then I added a dependency property for setting the control's Text, which takes care of setting the textbox's text value.  Finally, I handled the TextChanged event on the internal TextBox control to resize based on my internal TextBlock's size.

using System.Windows;
using System.Windows.Controls;

namespace PresentLight
{
    public partial class ScrollingTextBox : UserControl
    {
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set
            {
                SetValue(TextProperty, value);
                tb.Text = value;
            }
        }

        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), 
                               typeof(ScrollingTextBox), null);


        public ScrollingTextBox()
        {
            InitializeComponent();
        }

        private void tb_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (hiddenTextBlock != null)
            {
                hiddenTextBlock.Text = tb.Text;
                tb.Width = hiddenTextBlock.ActualWidth;
                tb.Height = hiddenTextBlock.ActualHeight;
            }
        }
    }
}

The result is a marginally better control.  There are a lot of possible improvements for me to make, such as possibly handing the selection changed event on the textbox to scroll the ScrollViewer to the cursor's position.  That will have to wait for a future post.

Sunday, April 13, 2008 9:41:18 AM (Eastern Standard Time, UTC-05:00)  #    Comments [2] -
silverlight
 Saturday, April 12, 2008

I haven't been posting much lately because I've been very busy preparing for my session at the Central Ohio Day of .NET.  I'm creating a presentation about Silverlight 2.0 Beta 1, but with a twist - the presentation is actually a Silverlight application!

Templates

For the last day or so I've been working on getting my application's main control to use templates to define the interface.  This gives me the option to create multiple "skins" for the application.

To accomplish this, I've been referencing two very excellent tutorials by Jesse Liberty and Shawn Burke.  But, as usual for me, I ran into a problem that sucked up a ton of time.

The Problem

I was trying to set up my template to include buttons for navigation between slides.  I started by building a simple XAML interface for the buttons, like so.

<StackPanel Orientation="Horizontal">
    <Button Height="75" Width="75" Margin="0,0,8,0">
        <TextBlock Text="First" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Button>
    <Button Height="75" Width="75" Margin="0,0,8,0">
        <TextBlock Text="Prev" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Button>
    <Button Height="75" Width="75" Margin="0,0,8,0">
        <TextBlock Text="Next" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Button>
    <Button Height="75" Width="75">
        <TextBlock Text="Last" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Button>
</StackPanel>

 

And that looks good enough for this example.

 

Then I took that same XAML and put it into a template stored in the application resources (in App.xaml).

<Application.Resources>
  <Style x:Key="TestTemplate" TargetType="pl:Presentation">
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="pl:Presentation">
          <StackPanel Orientation="Horizontal">
            <Button Height="75" Width="75" Margin="0,0,8,0">
              <TextBlock Text="First" HorizontalAlignment="Center" VerticalAlignment="Center" />
            </Button>
            <Button Height="75" Width="75" Margin="0,0,8,0">
              <TextBlock Text="Prev" HorizontalAlignment="Center" VerticalAlignment="Center" />
            </Button>
            <Button Height="75" Width="75" Margin="0,0,8,0">
              <TextBlock Text="Next" HorizontalAlignment="Center" VerticalAlignment="Center" />
            </Button>
            <Button Height="75" Width="75">
              <TextBlock Text="Last" HorizontalAlignment="Center" VerticalAlignment="Center" />
            </Button>
          </StackPanel>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</Application.Resources>

And modified my Page.xaml to have my Presentation UserControl class (modeled after Shawn Burke's tutorial) with the template applied as a style.

<local:Presentation x:Name="PresentationControl" Style="{StaticResource TestTemplate}" />

But running this treated me to a browser window that's stuck loading.  My break point in OnApplyTemplate in my Presentation class never got hit.  Pausing Visual Studio didn't tell me anything, so I knew it wasn't stuck in a loop.  This had me stuck for several hours.

The Solution

What I eventually found was that certain things that are perfectly acceptable XAML in a user control won't work in a template.  Furthermore, if Silverlight encounters these elements in the template it just hangs.

The problem XAML was the buttons.  Instead of including your actual buttons in your template, you should instead create a separate template for the buttons, and reference that as your button style.

<Style x:Key="TestButton" TargetType="Button">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="Button">
        <Button Width="75" Height="75">
          <Button.Content>
            <ContentPresenter Content="{TemplateBinding Content}" 
                              HorizontalAlignment="Center" 
                              VerticalAlignment="Center" />
          </Button.Content>
        </Button>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

Then modify the previous template to use the new button template.

<Application.Resources>
  <Style x:Key="TestTemplate" TargetType="pl:Presentation">
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="pl:Presentation">
          <StackPanel Orientation="Horizontal">
            <Button x:Name="FirstButtonElement" Content="First" 
                    Style="{StaticResource TestButton}" Margin="0,0,8,0" />
            <Button x:Name="PreviousButtonElement" Content="Prev" 
                    Style="{StaticResource TestButton}" Margin="0,0,8,0" />
            <Button x:Name="NextButtonElement" Content="Next" 
                    Style="{StaticResource TestButton}" Margin="0,0,8,0" />
            <Button x:Name="LastButtonElement" Content="Last" 
                    Style="{StaticResource TestButton}" />
          </StackPanel>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</Application.Resources>

Finally, this works.  It looks the same, but now I can take the template and make it look much nicer if I want.

Hopefully this tip will help others working on templating in Silverlight avoid the pitfalls I ran into.

Saturday, April 12, 2008 5:45:08 PM (Eastern Standard Time, UTC-05:00)  #    Comments [1] -
silverlight
 Thursday, March 06, 2008

In Windows XP's Add/Remove Programs you get information about installed applications such as copyright, version, last run, etc.  At first glance this information appears to be gone in Windows Vista's Programs and Features.

Where'd the Program Information Go?

I was recently trying to figure out the version of Silverlight that I have installed, but selecting the item from Programs and Features doesn't tell me anything.  Also, clicking Uninstall immediately starts the uninstallation without showing me the version, and clicking Change didn't do anything at all.

I was thinking to myself, "Microsoft wouldn't just remove this information totally ... that would be stupid," so I spent a little more time poking around and found that you can right click on the column headers, click on More... and get a dialog that allows you to select other columns to display.

Programs and Features - Choose Columns

The information that used to be available by default in Add/Remove Programs is now displays in these columns.  It sucks that it's apparently hidden from view, but I guess it didn't take me too long to find it.

Loading

Another change in Programs and Features is the loading.  Add/Remove Programs could take a long time to display, but once it did you had everything available.  Programs and Features loads installed applications bit by bit, and refreshes the screen.  This is annoying if you've started scrolling down or selected an item before its done loading, because the refresh causes things to jump around.

While its nice that it loads a lot quicker in Vista, it almost appears to be worse because it punishes you for trying to use it too quickly.  This reminds me of how Windows boots a lot more quickly in XP and Vista, but it does more things after you've logged in so the system really isn't available immediately.  If you click on the Start menu too quickly it will go away.  Again, punishing you for working too quickly.

I'd like an OS that keeps up with how fast I want to work.

Thursday, March 06, 2008 10:19:08 PM (Eastern Standard Time, UTC-05:00)  #    Comments [1] -
misc
 Wednesday, March 05, 2008

I arrived at work this morning only to find that the Silverlight 2.0 Beta 1 plugin and some documentation was discovered and available for download.  A few hours later the SDK and documentation was available, then after the keynote at Mix that whole lot was officially released.  I couldn't wait to try it out when I got home.

Unfortunately, the install experience hasn't been good.  I've got the Silverlight 2.0 plugin and SDK installed, but I can't get the tools for Visual Studio 2008 installed.  Here's step by step what I've done so far.

  1. Downloaded and installed the Silverlight 2 Beta 1 plugin (runtime) without a hitch.
  2. Downloaded Silverlight 2 Beta 1 SDK, Silverlight 2 Beta 1 Tools for Visual Studio 2008, and Expression Blend 2.5 March Preview.
  3. Uninstalled Silverlight 1.1 Alpha Tools for Visual Studio 2008 and Expression Blend 2 December Preview.
  4. Installed Silverlight 2 Beta 1 SDK.
  5. Tried to install Silverlight 2 Beta 1 Tools for Visual Studio but got the following error message:
    1. An Error Has Occurred:
      Silverlight Tools cannot be installed because one or more of the following conditions is true:

      1. Visual Studio 2008 RTM is not installed.
      2. The Web Authoring feature of Visual Studio is not installed.
      3. A previous version of the Silverlight Runtime is installed.
      4. A previous version of the Silverlight SDK is installed.
      5. The Visual Studio Update KB949325 is installed.
      6. A previous version of Silverlight Tools is installed.

      To continue, please install or uninstall the appropriate products and run this installer again.

  6. Verified what I had installed.  I've got Visual Studio Team System 2008 RTM, Microsoft Visual Studio Web Authoring Component, Silverlight runtime, Silverlight 2 SDK, Silverlight 1.0 SDK.  Oops, maybe that's the problem?  Also, I didn't uninstall Silverlight 1.1 Alpha runtime before installing Silverlight 2.0 runtime, but that shouldn't be a problem.
  7. Uninstalled Silverlight runtime and both SDKs, then rebooted for good measure.
  8. Installed Silverlight runtime, 2.0 SDK, ran silverlight_chainer.exe again and got the same error.
  9. Did a web search and found http://blog.steeleprice.net/archive/2008/03/05/1362.aspx which mentions a registry key that needs to be removed, but I don't have that registry key on my system.

At this point I can't find any more information through web searches or in the Silverlight.Net forums.  I'm posting this problem in the forums with a link here for a complete description of the problem.

I was really hoping to get few things done in Silverlight 2.0 and posted online tonight, but I'm kind of stuck and frustrated at this point.

UPDATE

Chad Campbell responded to my Silverlight.net forum post with a solution.  The solution definitely isn't something that I'd say is obvious, but hey, do whatever works.  I'm just a little surprised that I'd have more trouble with the beta than the alpha.

A big thanks goes out to Chad for his quick reply.  I'm definitely going to have to buy his book now!

Oops!

Even though the tools are now installed, something is still wrong.  Here's what I get when I try to create a Silverlight project in Visual Studio 2008.


Resolution

It turns out that the Silverlight 2 Tools Beta 1 for Visual Studio 2008 installs the Silverlight 2 Beta 1 runtime and SDK as part of the package.  This causes a problem if you already installed the plugin or the SDK.  I uninstalled everything Silverlight related, then installed silverlight_chainer.exe, this time successfully.  I'm now ready to go.

Wednesday, March 05, 2008 9:56:34 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
betas | silverlight
 Friday, February 29, 2008
I just got into a nerd fight with another developer on my team about which style of LINQ join syntax looks better.

Normally I wouldn't be one to get too worked up about syntax differences like this, but in this case my code was changed from one to the other for no reason other than "I don't like the way your wrote it."

Which do you prefer?



or


Friday, February 29, 2008 3:29:42 PM (Eastern Standard Time, UTC-05:00)  #    Comments [10] -
programming
 Thursday, February 21, 2008
I had to response to my soon-to-be-former boss' post about how an architect packs when moving offices.

A Silverlight guy could pack today with some great looking boxes that work with all major moving trucks, but they won't really hold all of his stuff.  They're kind of like those XAML boxes, but with huge gaps.  He feels the need to defend his box choice when compared with the competitor's boxes, which have been in production for years and total market penetration.

The Silverlight guy would rather wait another month or so, for the 2.0 beta of the box.  This version will solve all of his packing needs, can be loaded 1000 times faster than other common boxes and comes with a license allowing it to be used immediately.  The 2.0 boxes will also feature data cateloguing, content memory, multiple languages and can be used to build even better composite boxes.  So the Silverlight guy will probably wait until after the big conference when the new box is supposed to be announced.

Thursday, February 21, 2008 9:12:15 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
silverlight
 Sunday, January 20, 2008
I haven't stayed on top of this blog because I've been so busy with so many different things that taking time to write a post seems to be far down on the priority list.  I'm not going to say that will change this year, because that's almost cliche, but some of the things on my goal list will naturally lead to some posts here.

CodeMash

CodeMash v2.0.0.8 was awesome.  There have already been so many other blog posts talking about how great it was, so I'm not going to go into detail.  I'll sum it up by saying that it was totally worth it, and I'd be insane to miss it next year.

Resolutions

I have some goals for 2008, but really only one resolution.  My resolution is to do the push-up a day challenge.  But I decided to also do a sit-up per day, and throw in jumping jacks to toss in some cardio.  Today I've done 20 of each.  As the year moves on and things get harder, I may have to only do the exercises every other day, in order to give my muscles a chance to recover.


Goals for 2008
  • Present at at least 2 technical user groups
  • Write at least 2 articles for established websites
  • Contribute to a well known open source project
  • Create a fun game in Silverlight and host it at CodePlex
  • Create a custom layout for this blog and port it to SubText

Wow, that's a lot, but I already have one user group talk scheduled.  Should be a fun year.
Sunday, January 20, 2008 9:13:42 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1] -
blog | codemash | misc
Central Ohio Day of .NET

About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Matt Casto
Sign In
All Content © 2008, Matt Casto
Theme based on DasBlog theme 'Business' created by Christoph De Baene (delarou)