Showing posts with label silverlight. Show all posts
Showing posts with label silverlight. Show all posts

Wednesday, May 20, 2009

How to Create a Sivlerlight Fly Out Panel

-Note: This example is built on Silverlight 2.0

clip_image002

clip_image004

Description:

Using fly out panels is a good way to add a touch of animation to applications while also increasing the amount of available browser real estate. In this post, I will show you how to create a basic fly out panel using Expression Blend and minimal C# code. The progression depicted in the images above begins with the panel will out of view except for its right border. When the border is clicked, the panel will fly into view. Clicking the panel again causes the panel to return to its hidden position.

Level of Difficulty: clip_image006 Easy

Preparation/Directions:

1. Create a New Silverlight application in Blend and name it FlyOutPanelBlend.

2. Set the Height and Width of the UserControl to Auto

a. Open Page.xaml by double clicking on it on the Project tab.

b. Select the [UserControl] node on the Objects and Timeline panel.

c. In the Properties tab, go to the Layout section and Change the Width and Height properties from their defaults, 640 and 480, to Auto.
clip_image008

This can be done by either typing the “Auto” in the appropriate textboxes, or by clicking the Set to Auto button clip_image009 to the right of each textbox.

3. After setting the Width and Height to Auto, the UserControl will be too small for laying out the user interface using the designer in Blend. To fix this, change the design time Height and Width properties of the UserControl.

a. Select the [UserControl] node on the Objects and Timeline panel.

b. Three extra handles are displayed around the UserControl, one on the bottom, one on the right, and one on the bottom right hand corner. These are used to click and drag in order to modify the design time Width and Height of the UserControl. Click and drag the triangle handle on the bottom right hand corner down and to the right. Notice that as you drag small labels display the values for the design time Height and Width.

clip_image011

c. To modify these values with greater accuracy, click on the Split view to show the designer and the XAML code simultaneously.
clip_image013

d. When dragging the handles for the design time Width and Height, Blend adds several extra attributes to the UserControl element telling it to display the user control in design time at the appropriate Width and Height. Change the d:DesignWidth value to 1024 and the d:DesignHeight property to 768. Note: The XAML show below has been formatted for easier reading.
clip_image015

e. Set the background color of the main grid by selecting the grid LayoutRoot on the Objects and Timeline panel. In the Properties tab, select the Background property and set it to a solid color brush by selecting the second sub-tab (Solid color brush), and choosing black from the color picker.

clip_image017

f. Right click on the Grid icon clip_image019 on the toolbox to show other panel control options. Select Border from the list to hide options. The Grid icon has now been replaced with the Border icon. Double click on the Border icon to place a Border object inside the LayoutRoot grid.
clip_image021

g. Set the background color of the border and name it bdrMenu by selecting the border on the Objects and Timeline panel. In the Properties tab, set the Name property to bdrMenu and select the Background property and set it to a solid color brush by selecting the second sub-tab (Solid color brush), and choosing white from the color picker.

h. Now stretch the border vertically to fill the entire height of the window. Do this by going to the Layout panel in the Properties tab and setting the Height property to Auto clip_image009[1] and the VerticalAlignment property to Stretch.

clip_image023

i. Change the width of the border to 200 and give it rounded corners on the tob and bottom right corners by setting the CornerRadius to “0,10,0,10” (top left, top right, bottom left, bottom right).

j. Place a title on top of the menu by double clicking on the TextBlock icon clip_image025 in the toolbox. This will place a textblock inside bdrMenu. If a TextBlock does not appear inside the Border, undo the last action (Ctrl+Z) and make sure the bdrMenu was selected in the Objects and Timeline panel before double clicking the TextBlock icon.

k. In the Properties panel, give the TextBlock the following properties: Text=”Menu”, FontSize=”22”, HorizontalAlignment=”Center”, and VerticalAlignment=”Top”.

l. Move the menu almost entirely off the screen, leaving the right border visible. To do this, select bdrMenu on the Objects and Timeline panel. Then, Properties tab, go to the Transform panel and set the value next to the X to -180. This will give the border a TranslateTransform with a value of -180 for the X property.
clip_image027

m. Create a new Storyboard for animating the panel into view. In the Objects and Timeline panel, click the New Storyboard buttonclip_image029 and name it ShowPanel.

clip_image031

n. You will see a timeline appear. Drag the yellow line to .5 seconds and select bdMenu on the Objects and Timeline panel.

o. Set the TranslateTransform’s X value to 0 in the Translate panel of the Properties tab. This will cause the panel to be visible after half a second whenever the storyboard is played. When making this change, you should see the property recorded in the timeline with a little sphere on the .5 marker. If you wish to make the animation take longer or shorter than .5 seconds, simply drag it left or right accordingly.

clip_image033

p. Expand the dropdown menu by the New Storyboard button by clicking the
triangle and select Duplicate.
clip_image035

q. This will create a copy of the previously created storyboard. Expand this same menu again and choose Reverse. Expand the menu once again and choose Rename. Rename the storyboard to HidePanel.
Generated Xaml
clip_image037

4. Open Page.xaml.cs in Visual Studio and add an AddEventHandlers method in the constructor. In the implementation of AddEventHandlers, assign a new event handler to the MouseLeftButtonDown event of bdrMenu.

5. Add a private member variable of type bool named _hidden. This will be used to keep track of the state of the panel. If the panel is hidden, this value will be set to true, otherwise it will be set to false.

6. In the event handler, create a conditional statement. If _hidden is true, begin the ShowPanel storyboard and set the _hidden flag to false. Conversely, if _hidden is false, begin the HidePanel storyboard and set the _hidden flag to true.

7. Finally, clean up the unnecessary using statements from the top of the file only keeping using System.Windows.Controls; and using System.Windows.Input;.

clip_image039

Thursday, January 29, 2009

Getting Professional Quality Animations with the KeySpline Editor in Expression Blend

When I first started working with WPF and Silverlight, I was amazed at how simple it was to create animations, especially when using Expression Blend. I was always frustrated with one thing though... they just didn't look very professional. I could edit the speed of my animations, but the interpolation of the values in the animation was always linear. That is, if I had an animation that changed a button from size 1px to size 10 px, which lasted 10 seconds, it would cause the button to change at a rate of 1 px per second. This linear interpolation frustrated me. I wanted some of my animations to ease in, or ease out. For instance, when I Show a pop-out panel, I typically like to make the animation occur really fast at first, and then slow down towards the end. Like in the button example, I would like the button to grow to 8 px in the first 3 seconds, and grow from 8 px to 10 pix in the last 7 seconds. This tends to make the animations look more professional.

So... how do you do it?

First, create your animation in Blend. Once you have your animation (storyboard) created, you should see something like this in your Objects and Timeline panel. In this example, I have applied an animation to a grid named grdSelectDate which takes 1 second to complete. This is indicated by the little egg-shaped dot placed in the timeline next to the grdSelectDate grid.

image

If you click on this dot, it will change colors from white to gray. This now gives you the ability to use the KeySpline editor.

image

You can see the editor under the Properties tab. You can think of this editor like this. The X axis represents the value of the affected property. In my example, it would represent the size of my button (this is a made up example... the size would actually be two different properties.... height and width or a single scaleTransform property... you get the idea though!). When X = 0, the value is at it's original state, so the size of my button has not changed, when X = 1 (top of the scale), the value has now reached it's final value (10 px in my fictional example). The Y axis is a function of time. Y=0 is the start of your storyboard and Y=1 represents the end of the storyboard (10 seconds in my button example).

To edit these values, you can simply click and drag on the yellow dots or enter values in the textboxes below(not as easy...) to change the speed of easing in/out of your animations. In this example, the animation starts really quickly (indicated by the steep incline of the line) and then slows down towards the end (indicated by the very small change in the x value while the y value keeps changing).

image

Keep playing around with this graph to ease in and out and you will see your WPF and Silverlight applications kicking it up a notch in no time!

Wednesday, July 16, 2008

What timer to use for WPF and Silverlight Applications

When working on WPF or Silverlight Applications, instead of using your typical .Net timers, developers should stick with the DispatcherTimer. Handlers for the DispatcherTimer are invoked on the UI thread, so you don't have to worry about threading issues. The DispatchTimer class is located in the System.Windows.Threading namespace. To use it, you set an Interval property from a TimeSpan property, add a handler for the Tick event and call the start method to start the timing.

//------------------------------------------
//DispatcherTimer code snippet
//------------------------------------------

DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(100);
timer.Tick += timerOnTick;
timer.Start();

void timerOnTick(object sender, EventArgs args)
{
//do something
}

Very Cool Silverlight Example

Silverlight is very powerful. It is a relatively new technology, so it is not as advanced in some aspects as its rival Flash. Microsoft is rapidly adding new features to make it comparable to Flash. In my opinion, Silverlight is much better than Flash now. I have developed a few flash applications using Adobe Flex. I have also worked on an Adobe AIR application. Adobe has done some pretty cool things to make Flash development easier, but the main drawback is that I have to become familiar with ActionScript.

With Silverlight, I can keep developing in C#! (I also think XAML is more powerful than MXML)

Check out the link above to see an example of what can be done with the current Silverlight bits.

WPF and Silverlight Best Practice: Event Handlers


When developing WPF and Silverlight applications, developers and designers can create a clean line of separation between the look and feel of the application and its functionality. This is possible because of XAML. Although it is possible to create WPF or Silverlight applications entirely of procedural code (VB or C#), it is highly unlikely you would see such an application. Typically, designers work on the XAML files while developers work on the code behind files. In the XAML files, designers can specify what the UI looks like, while developers deal with the behavior. It is possible, however, for designers to embed some basic functionality within the XAML itself. One example is in defining event handlers. In the following code snippet I am defining a button.

<Button x:Name="btnSave" Content="Save" Width="90" Height="25" VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="118,0,0,11.33899974823" Click="MyClickHandler"/>

This button has various properties that define its look and feel including Content, Width, Height, etc. I have also specified an event handler for the button's Click event. The body of this even handler is found in the code behind file of my Silverlight or WPF control. This code is perfectly legitimate. In fact, it can clean up your code behind files significantly. If you have 50 buttons, each of which need to point to this event handler, it removes a lot of these statements.


btnSave.Click += new RoutedEventHandler(MyClickHandler);

This was my reasoning when I first started writing WPF apps. I thought I would clean up my .cs files as much as possible. If I could write it in XAML, I would. There is a small problem with this approach. Lets say the XAML snipped above was found in a xaml file that was then handed off to a designer. The designer opens it up in a design tool like Expression Blend and decides the button looks terrible with all those attributes. Instead, he/she wants the button to look a lot different, so he/she decides to completely wipe out that button and start from scratch. As long as there is a button named btnSave, the application should build. So, he/she ends up with this

<Button x:Name="btnSave" Content="Click to Save" Style="{StaticResource SaveButtonStyle}" Margin="0,4.5,2,0" VerticalAlignment="Top" d:LayoutOverrides="Height"/>

This button now has a completely different look and feel. It points to a style resource which may drastically change the appearance of the button. At this point the designer builds the application and there are no errors, so he/she is happy. There have been no breaking changes and the button looks great…. WRONG! Although the application builds and it looks great, there has been a major change in the behavior of the button. With the following code, there is no handler for the click event. The designer accidentally wiped out the old XAML not realizing that a little bit of functionality had been defined there. This is the problem with defining event handlers inside XAML code.

As a best practice… Always assign your event handlers in your procedural code. Here is what I do… Inside the constructor of all my WPF and Silverlight controls, I add a method called AddEventHandlers(). Inside this method, I take care of adding the event handler to all my controls defined in my XAML. The code looks something like this:


public MyControl()

{

InitializeComponent();

AddEventHandlers();

}

private void AddEventHandlers()

{

btnSave.Click += new RoutedEventHandler(MySaveClickHandler);

btnExit.Click += new RoutedEventHandler(MyExitClickHandler);

btnOk.Click += new RoutedEventHandler(MyOkClickHandler);

}