Silverlight Feeds - All your Silverlight feeds in one place.

Sponsors

Wednesday, December 31, 2008

Tour around Silverlight Contrib

by JustinAngel via Justin myJustin = new Microsoft.Silverlight.Justin(); on 12/31/2008 3:23:14 AM

I’m a huge supporter of open source software development and I'd like to take this opportunity to go over the Silverlight Contrib O/S project.

Fair disclosure first though, my current role is Program Manager for the Silverlight Toolkit team which ships on codeplex (at http://www.codeplex.com/Silverlight). 
I’ve got a very high quality bar and I expect nothing less from any O/S project that I ask customers to put into their technology stack.

Standard Microsoft disclaimer: KGB Assassins will be hired toWait, other Disclaimer: I do not speak for my employer.

 

Getting Started

OK, this is straight forward and well-organized.

Codeplex website @ http://www.codeplex.com/SilverlightContrib.
I went to the Release Tab and downloaded the latest Alpha 3 release from December 15th.

Official Website @ http://SilverlightContrib.org.

And live demo @ http://silverlightcontrib.org/demo/.

Silverlight Contrib Demo App

First impressions is really important, especially in a open source projects. A real problem that plagues open source initiatives is the lack of proper documentation and support.
Silverlight Contrib has an excellent first impression. Excellent website organization, solid sample app, and it even comes with a CHM file!

image

Unfortunately some of the subjects in the CHM file clearly say they’re missing documentation:

image

 

OK, Let’s start a new SIlverlight Application and add the (3?) Silverlight Contrib DLLs.

image

image 

image

And here’s how our solution looks like after we added the DLLs:

image

 

Inside the XAML editor, we’ll go to “Choose Items” and add the “SilverlightContrib.Controls.dll” to the Visual Studio Toolbox:

image    --> image

 

 

Color Picker

Ok, enough fooling around. Let’s build something. We’ll start from the Color Picker.

Based on the CHM file here’s what we’ve got In ColorPicker:

image

We’ve got a ColorSelected event and a SelectedColor property.

Let’s build a simple app that has a color picker and a rectangle that uses that colour as fill.

<UserControl x:Class="SL_Contrib.Page"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:SilverlightContrib="clr-namespace:SilverlightContrib.Controls;assembly=SilverlightContrib.Controls"

   Width="400" Height="200">

    <StackPanel x:Name="LayoutRoot" Background="White">

        <SilverlightContrib:ColorPicker x:Name="colorPicker" Width="200" Height="200" SelectedColor="Green" />

        <Rectangle x:Name="myRect" Fill="Green" Width="100" Height="100" />

    </StackPanel>

</UserControl>

Hmm… I was writing the event registration there for a second and got confused… Why is the Property called “SelectedColor” and the change event called “ColorChanged”? Shouldn’t it be “SelectedColorChanged”? Minor annoyance, but still.

    public partial class Page : UserControl

    {

        public Page()

        {

            InitializeComponent();

            colorPicker.ColorSelected += new ColorSelectedHandler(colorPicker_ColorSelected);

        }

 

        private void colorPicker_ColorSelected(object sender, ColorSelectedEventArgs e)

        {

            myRect.Fill.As<SolidColorBrush>().Color = e.SelectedColor;

        }

    }

 

    public static class Extensions

    {

        public static T As<T>(this object obj)

        {

            return (T) obj;

        }

    }

(I’ve added my As<T> extension method)

Let’s run this sample:

image

Truly a master-piece app.

Yep, and when we select another color the rectangle gets updated.

image image image

It looks like the ColorPicker isn’t invoking the ColorChanged event when you just drag & drop…

image image

You can see that the in the first picture I’ve started dragging and the second picture is while still dragging.
The control visuals get updated, but there’s no external event you can use to pick up on that until the user drops and release the mouse capture.

 

The TextBlock on the bottom left isn’t editable, so we’ll create another TextBox and try to change the selected colour.

<SilverlightContrib:ColorPicker x:Name="colorPicker" Width="200" Height="200" SelectedColor="Green" />

<TextBox x:Name="tbxColour" />

<Button x:Name="btnCommit" Content="Change colour" />

<Rectangle x:Name="myRect" Fill="Green" Width="100" Height="100" />

   

    public Page()

    {

        InitializeComponent();

        colorPicker.ColorSelected += new ColorSelectedHandler(colorPicker_ColorSelected);

        btnCommit.Click += new RoutedEventHandler(btnCommit_Click);

    }

 

    void btnCommit_Click(object sender, RoutedEventArgs e)

    {

        byte alpha = Convert.ToByte(tbxColour.Text.Substring(0, 2), 16);

        byte red = Convert.ToByte(tbxColour.Text.Substring(2, 2), 16);

        byte green = Convert.ToByte(tbxColour.Text.Substring(4, 2), 16);

        byte blue = Convert.ToByte(tbxColour.Text.Substring(6, 2), 16);

        colorPicker.SelectedColor = Color.FromArgb(alpha, red, green, blue);

    }

And when we run our sample:

imageimage

Works like a charm.

 

I’ve opened the application in Blend to try and change the default layout of the ColorPicker.

image

Now, I changed the default visual tree for this control to move the Hue selector from the left to the right and viola:

image

Still works like a charm:

image

One cool thing though that I’ve noticed in Blend is how the nice spectrum is built:

image

It’s basically a Gradient with a bunch of GradientStops. cool stuff. I keep being amazed by how people use the basic 2d drawing abilities of Silverlight.

 

 

 

All and all, this is a very cool control.

Pros:

  1. Very cool visuals appearance. Main color selection palette, side spectrum selection palette and an area that shows the currently selected color and it’s Hex.
  2. Solid control.

Minor cons:

  • The event naming for “ColorChanged” is not consistent with the property name “SelectedColor”.
  • No event “ColorChanging” that fired while the eye dropper is being dragged.
  • The Hex textbox isn’t editable

 

 

Cool Menu

From the sample app:

image

 

Here’s the CHM file doc on this control:

image

So we’ve got Items, MaxItemHeight, MaxItemWidth, MenuIndexChanged, MenuItemClicked  & MenuItemClickEffect.

 

Let’s build a quick cool menu with some items.
I’ll use Dobby the penguin from Jose Farajdo’s blog - http://advertboy.wordpress.com/blendcandy/.

   <SilverlightContrib:CoolMenu Height="200">

            <SilverlightContrib:CoolMenu.Items>

                <SilverlightContrib:CoolMenuItemCollection>

                    <SilverlightContrib:CoolMenuItem>

                        <SilverlightContrib:CoolMenuItem.Content>

                            <SL_Contrib:PenguinControl />

                        </SilverlightContrib:CoolMenuItem.Content>

                    </SilverlightContrib:CoolMenuItem>

                    <SilverlightContrib:CoolMenuItem>

                        <SilverlightContrib:CoolMenuItem.Content>

                            <SL_Contrib:PenguinControl />

                        </SilverlightContrib:CoolMenuItem.Content>

                    </SilverlightContrib:CoolMenuItem>

                    <SilverlightContrib:CoolMenuItem>

                        <SilverlightContrib:CoolMenuItem.Content>

                            <SL_Contrib:PenguinControl />

                        </SilverlightContrib:CoolMenuItem.Content>

                    </SilverlightContrib:CoolMenuItem>

                    <SilverlightContrib:CoolMenuItem>

                        <SilverlightContrib:CoolMenuItem.Content>

                            <SL_Contrib:PenguinControl />

                        </SilverlightContrib:CoolMenuItem.Content>

                    </SilverlightContrib:CoolMenuItem>

                    <SilverlightContrib:CoolMenuItem>

                        <SilverlightContrib:CoolMenuItem.Content>

                            <SL_Contrib:PenguinControl />

                        </SilverlightContrib:CoolMenuItem.Content>

                    </SilverlightContrib:CoolMenuItem>

                    <SilverlightContrib:CoolMenuItem>

                        <SilverlightContrib:CoolMenuItem.Content>

                            <SL_Contrib:PenguinControl />

                        </SilverlightContrib:CoolMenuItem.Content>

                    </SilverlightContrib:CoolMenuItem>

                </SilverlightContrib:CoolMenuItemCollection>

            </SilverlightContrib:CoolMenu.Items>

        </SilverlightContrib:CoolMenu>

I’m not crazy about this syntax.

First, I have to specify I’m using the Items collectiom, than the specific collection CollMenuItemCollection, than a CoolMenuItem, than Content and finally I can specify the actual Items. Why not support a much simpler syntax?

        <SilverlightContrib:CoolMenu Height="200">

            <SL_Contrib:PenguinControl />

            <SL_Contrib:PenguinControl />

            <SL_Contrib:PenguinControl />

            <SL_Contrib:PenguinControl />

            <SL_Contrib:PenguinControl />

        </SilverlightContrib:CoolMenu>

 

Anyway, let’s run our app with the extended syntax:

image

When we mouse over one of the items:

image

image

This menu is pretty cool.

 

Oh, this is cool: When I click Dobby he drops down and up in a nice elastic bounce motion.

image

image

image

image

Pretty cool.

 

OK, Now I’d like to grab a click on one of the menu items.
We’ll name the menu and add a Text property to the MenuItem.

        <SilverlightContrib:CoolMenu Height="200" x:Name="menu">

            <SilverlightContrib:CoolMenu.Items>

                <SilverlightContrib:CoolMenuItemCollection>

                    <SilverlightContrib:CoolMenuItem Text="Penguin #1">

                        <SilverlightContrib:CoolMenuItem.Content>

                            <SL_Contrib:PenguinControl />

                        </SilverlightContrib:CoolMenuItem.Content>

                    </SilverlightContrib:CoolMenuItem>

                    <SilverlightContrib:CoolMenuItem Text="Penguin #2">

                        <SilverlightContrib:CoolMenuItem.Content>

                            <SL_Contrib:PenguinControl />

                        </SilverlightContrib:CoolMenuItem.Content>

                    </SilverlightContrib:CoolMenuItem>

                    <SilverlightContrib:CoolMenuItem Text="Penguin #3">

                        <SilverlightContrib:CoolMenuItem.Content>

                            <SL_Contrib:PenguinControl />

                        </SilverlightContrib:CoolMenuItem.Content>

                    </SilverlightContrib:CoolMenuItem>

                    <SilverlightContrib:CoolMenuItem Text="Penguin #4">

                        <SilverlightContrib:CoolMenuItem.Content>

                            <SL_Contrib:PenguinControl />

                        </SilverlightContrib:CoolMenuItem.Content>

                    </SilverlightContrib:CoolMenuItem>

                    <SilverlightContrib:CoolMenuItem Text="Penguin #5">

                        <SilverlightContrib:CoolMenuItem.Content>

                            <SL_Contrib:PenguinControl />

                        </SilverlightContrib:CoolMenuItem.Content>

                    </SilverlightContrib:CoolMenuItem>

                    <SilverlightContrib:CoolMenuItem Text="Penguin #6">

                        <SilverlightContrib:CoolMenuItem.Content>

                            <SL_Contrib:PenguinControl />

                        </SilverlightContrib:CoolMenuItem.Content>

                    </SilverlightContrib:CoolMenuItem>

                </SilverlightContrib:CoolMenuItemCollection>

            </SilverlightContrib:CoolMenu.Items>

        </SilverlightContrib:CoolMenu>

 

    public partial class CoolMenuPage : UserControl

    {

        public CoolMenuPage()

        {

            InitializeComponent();

            menu.MenuItemClicked += new SilverlightContrib.Controls.MenuIndexChangedHandler(menu_MenuItemClicked);

        }

 

        void menu_MenuItemClicked(object sender, SilverlightContrib.Controls.SelectedMenuItemArgs e)

        {

            txt.Text = e.Item.Text;

        }

    }

 

image

image

 

Nice.

 

Pros:

  1. Pretty cool all and all. The resizing effect, the nice elastic bounce on click and how the rest of the items move. All of these create a solid User eXprience.

Cons:

  • The menu only ships with 2 types of effects “Bounce” and “None”. There’s no extensible mechanisms to add your own effect. Not even through VSM. 
  • The menu should inherit from ItemsControl, which it doesn’t. I can’t use any Item templating goodness with this control. I’d like to be able to run this code:

menu.ItemSource = new List<Person>()

           {

               new Person(Name = "Justin", Picture = "Awesomeness.jpg"),

               new Person(Name = "RJ", Picture = "YaImADutch.jpg"),

               new Person(Name = "Dobby", Picture = "Penguin.jpg"),

           };

        <SilverlightContrib:CoolMenu>

            <SilverlightContrib:CoolMenu.ItemTemplate>

                <DataTemplate>

                    <StackPanel>

                        <Image Source="{Binding Picture}" />

                        <TextBlock Text="{Binding Name}" />

                    </StackPanel>

                </DataTemplate>

            </SilverlightContrib:CoolMenu.ItemTemplate>

        </SilverlightContrib:CoolMenu>

 

 

 

Tweening

From Wikipedia:

“Inbetweening or tweening is the process of generating intermediate frames between two images to give the appearance that the first image evolves smoothly into the second image. Inbetweens are the drawings between the keyframes which help to create the illusion of motion. Inbetweening is a key process in all types of animation, including computer animation.” – copied from http://en.wikipedia.org/wiki/Tweening 

Basically, Tweening is creating cool effects :)

Let’s see a basic example of this.

Here’s a basketball I draw in a few seconds in Blend:

image

(Yes, It’s a Basketball. Prove that it isn’t.)

Now, I’d like for it to bounce down and up and down again in a realistic fashion.

image

 

In order to do that, We’ll add a storyboard in Blend.

image

 

At 0.0 we want the basketball to be at the initial position.

image

At 0.5 seconds we want it at the bottom.

image

At 0.7 seconds we want it to back up a bit.

image

And down again in 0.8 seconds:

image

And on load we’ll start the stortboard:

        void SilverlightControl1_Loaded(object sender, RoutedEventArgs e)

        {

            Resources["Storyboard1"].As<Storyboard>().Begin();

        }

 

 

Than once we run the page we’ll see the full animation.

However, we might not want to specify each possible frame to build realistic effects.
It’s hard, and it’s a very hard task.

In comes the Tweening library.
First, we’ll delete all keyframes besides the last one.

image

Than, back in Visual studio we’ll have a look at that last keyframe.

        <Storyboard x:Name="Storyboard1">

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="canvas" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">

                <SplineDoubleKeyFrame KeyTime="00:00:00.8000000" Value="186"/>

            </DoubleAnimationUsingKeyFrames>

        </Storyboard>

We’ll start by deleting even that last animation and copying it’s Keyframe time to the Duration.

        <Storyboard x:Name="Storyboard1">

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"

                                          Duration="00:00:00.8000000"

                                          Storyboard.TargetName="canvas"

                                          Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" />

        </Storyboard>

Next, We’ll add some Tweening attached properties.

image

Now, let’s set the initial value, the target value, the number of frames we’d like generated for us and the Transition type. .

image image image

And here’s our final storyboard XAML:

<Storyboard x:Name="Storyboard1">

    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"

                                  Duration="00:00:00.8000000"

                                  Storyboard.TargetName="canvas"

                                  Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)"

                                  Tweener:Tween.From="0"

                                  Tweener:Tween.To="186"

                                  Tweener:Tween.Fps="20"

                                  Tweener:Tween.TransitionType="EaseInOutBounce"

                                  />

</Storyboard>

 

And once we run our app we can see the ball falls down, bounces up a bit and falls back down.

 

Pro:

  1. Tweening is a well established concept in the designer audience and a very productive way of creating complex animations quickly.

Con:

  • No blend support.

 

 

Clipboard support

At times you might want to have Silverlight access directly into your clipboard. Which isn’t natively supported in Silverlight.

<StackPanel x:Name="LayoutRoot" Background="White">

    <TextBox x:Name="tbx" />

    <Button Click="Copy_Click" Content="Copy TextBox to clipboard" />

    <Button Click="Paste_Click" Content="Paste clipboard to TextBox" />

    <Button Click="Clear_Click" Content="Clear clipboard" />

</StackPanel>

 

Here’s how this page looks like when we run it.

image

 

We’d like the copy button to copy the Text from the TextBox to the clipboard.

First, we’ll create a property that will use lazy initialization to Initialize a ClipboardHelper class.

private ClipboardHelper _clipboard = null;

ClipboardHelper Clipboard

{

    get

    {

        try

        {

            if (_clipboard == null)

                _clipboard = new ClipboardHelper();

        }

        catch (InvalidOperationException)

        {

            MessageBox.Show("Current browser isn't supported for clip board opearations.");

        }

        return _clipboard;

    }

}

This class has resource implications and browser support implications, so it’s best to cache it once initialized.

 

Now, once the Copy button is clicked we’d like to copy the contents of the TextBox into the Clipboard.

        private void Copy_Click(object sender, RoutedEventArgs e)

        {

            if (Clipboard != null)

                Clipboard.SetData(tbx.Text);

        }

Let’s run this application and put some text into the TextBox:

image

 

Once we click the button the user will be prompted to allow the browser app to access the clipboard:

image

The user must click “Allow Access”.

 

Now let’s paste this outside our browser:

image

 

So we can use the Clipboard helper from SIlverlight contrib to cross through browsers boundaries.

 

Now, let’s implement all buttons.

        private void Copy_Click(object sender, RoutedEventArgs e)

        {

            if (Clipboard != null)

                Clipboard.SetData(tbx.Text);

        }

 

        private void Paste_Click(object sender, RoutedEventArgs e)

        {

            if (Clipboard != null && !string.IsNullOrEmpty(Clipboard.GetData()))

                tbx.Text = Clipboard.GetData();

        }

 

        private void Clear_Click(object sender, RoutedEventArgs e)

        {

            if (Clipboard != null)

                Clipboard.ClearData();

        }

And once we run our application we see that we can copy information from outside the browser inside our Silverlight Application.

image

image

 

And we can clear the clipboard and paste again to see it’s been emptied out.

image

 

Pros:

  1. Clipboard support is something that can make or break certain apps.
  2. This is an excellent API for something that is basically a huge managed wrapper around Javascript. Having a Dispose method on the ClipboardHelper shows the Contrib team really did a good job here.
  3. This could enable a range of scenarios (copying whole files from outside the browser?)

Con:

  • The current implementation is not supported in FireFox.

image

 

 

Sum up

The Silverlight Contrib is a top notch open source project with some excellent controls, utilities and helpers you should definitely take a look at.

Go get it at http://codeplex.com/SilverlightContrib.

 

 

-- Justin Angel 

Microsoft Silverlight Toolkit Program Manager

email it!bookmark it!digg it!

Original Post: Tour around Silverlight Contrib

Subscribe

New Feed

Product Spotlight

Recently Updated Sources

Legal Note

The content of the postings is owned by the respective author. Silverlight Feeds is not responsible for the contents of the postings. This site is automatically generated and cannot be reviewed for abusive content. If you find abusive content on Silverlight Feeds, please contact us. Designated trademarks and brands are the property of their respective owners. All rights reserved.

Advertise with us