Wednesday, September 9, 2009

Working with Silverlight 3's DataPager Control

Silverligth 3's DataPager control works great if you are working with the .Net Ria Services. The .Net Ria Services make it easy for you to retrieve data from a db and page it so it is not all retrieved at once (improving performance). But how do you use the control if you want to manually create it yourself? What if you already have your paging scheme implemented and all you wish to do is use a new pager control?

This is relatively simple to do, but it isn't the most elegant code. You will need to use a PagedCollectionView. This is what you have to set the source to in your pager in order to get it to work. In order to use this class, you will need to add the following using statement to your source file.

using System.Collections.Specialized;

Once you have that, you can create a PagedCollectionView by passing an array to the constructor. In this example, I have an integer array (pagerSource) which is filled with a bunch of 1's. You could really put whatever you want in here. You can make it any type of array too, I just chose and integer one. Once I have my array the appropriate length (length will equal the pager's # of pages), I can create the PagedCollectionView object and set that as the source of my pager. I can then assign event handlers as you would expect to see when the pageIndex changes and perform my logic accordingly.

Enjoy!

int totalPages =  .//... logic to figure out my # of pages

int[] pagerSource = new int[totalPages];
for (int i = 0; i < totalPages; i++)
{
     pagerSource[i] = 1;
}

pagedCollectionView = new PagedCollectionView(pagerSource);
myPager.Source = pagedCollectionView;

Thursday, September 3, 2009

This Saved My Neck!

Just a quick post in case you are ever in the situation I was in today. I was told to have a presentation ready in a couple of days to present to management in our company. Great. I have had those materials prepared for a while, so all I have to do is tweak them a bit and I'm ready to go... WRONG! I somehow lost all my files. The directory where I had my presentation saved vanished!!!

I searched for a while for applications to recover my deleted files. I found a few that looked ok, so I downloaded the trials. I started searching my pc, but it was taking forever (and I did not have that kind of time). I finally remembered a Vista commercial that briefly mentioned something about how easy Vista makes it to recover deleted files, so I started searching for that. With that search I found ShadowExplorer. Now, the first post I saw on it mentioned that it was built in to all of the versions of Vista, but I did not see it in mine (Vista Business). I searched for a download of it and found this site...

http://forums.techarena.in/tips-tweaks/1063644.htm

From there, I was able to download the latest version and recover my files with just a few clicks of the mouse!!!

ShadowExplorer is a life-saver, so I thought I'd share in case anyone else finds themselves in a similar conundrum.

Enjoy!!!!

Monday, August 10, 2009

Surface Website ... Meet Silverlight

Ok, so first of all, my apologies for not updating this blog in such a long time. Things have been a bit hectic around here lately. I have also spent some time away from the office. Anyway ... I'm back.
Just a quick post this time. In a previous post I ragged on Microsoft for not eating its own dog food. They preached about Microsoft Silverlight, but then would not even use the technology in its own websites, like http://www.microsoft.com/surface/.
Well, that's changed now. Microsoft has finally decided to use it's own technology over Adobe Flash. Way to go Microsoft. It took you a while, but you finally did it. You'll find it to be a great technology. I'm sure you'll run into bugs along the way like the rest of us, but you should be in a much better position to get bug fixes in whenever you encounter them!

Wednesday, July 22, 2009

DeepZoomComposer.Dll

Wow! It's been a very long time since I've updated this blog. My bad. I've been extremely busy since the last post. I just thought I add a quick entry here about something I just learned today. If you are wanting to create a DeepZoom image programatically, it is not very difficult. With the new release of DeepZoomComposer for Silverlight 3, all you have to do is add a reference to the DeepZoomTools.Dll found in the DeepZoom composer program files after installing DeepZoomComposer.

Once you've got that it's only a matter of two lines of code. Here is a sample I created. You simply call the Create() method on an Image creator object and pass in the path to the image you want to create a DeepZoom image out of and then the path for the output directory. It's that simple!

ImageCreator creator = new ImageCreator();

Creator.Create();

Enjoy!

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

Friday, April 24, 2009

Connecting Wii Balance Board to PC

.Ok. It's been a long time since I've had the chance to blog. I have been playing around with the Nintendo Wii, and I am extremely excited about all the possibilities this little device opens up. Today I just got my balance board hooked up to my pc. I am going to investigate what kinds of interactions and cool applications I can come up with. I just thought I would take a second to jot down the little problem I had connecting to it in case anyone else is having similar issues.

 

To connect the balance board I pressed the sync button found by the batteries. While pressing that button, I went to my control panel->Bluetooth Devices and clicked on the Add button.

image

check the checkbox on the wizard and click next. Then I saw a list of all the available devices. I clicked on the balance board "RVL-WBC-01". From there I clicked next and selected not to use a passkey. After that the device showed up on my list of devices, but it did not say it was connected. I searched for a while trying to figure out what was going on. Finally, I decided to select the board from the device list and click on properties. This showed a list of services available for the device. I selected the 'Drivers for keyboard, mice, etc(HID)' checkbox, clicked the Apply button and I was good to go. The balance board was connected and ready to use.

I hope this helps you out if you are running into the same issues I was.

Monday, March 9, 2009

How to Create Dependency Properties in Silverlight

You can pretty much cut and paste this snippet in your code and change a few names and values in order to properly register a dependency property for your Silverlight class.

First of all, you need to create public property whose getter and setter call GetValue and SetValue respectively. You then define a public static read only Dependency property. This must have the name given to the public property defined earlier with "Property" appended to it. In this step you want to register this dependency property and specify the name, type, type of object to which it is being registered, and specify the method to call when the property is changed. If you do not need to call a method to do some processing every time the property value changes, the last parameter in the Register method can be set to null. That's about it.

So, in this snippet I am registering a dependency property named HorizontalOffset of type double. I am registering this property on a class I called Stack3DPanel. This class happens to be a custom panel, so whenever I change this property, I want all the elements in my panel to be redrawn, so I'm calling the InvalidateArange method. The body of this method can be whatever you need it to be. Again, if you do not need to do anything when the property is changed, you can set that fourth parameter in the Register call to null.

Here is the code.

 

        public double HorizontalOffset
{
get { return (double)GetValue(HorizontalOffsetProperty); }
set { SetValue(HorizontalOffsetProperty, value); }
}

public static readonly DependencyProperty HorizontalOffsetProperty =
DependencyProperty.Register("HorizontalOffset",
typeof(double),
typeof(Stack3DPanel),
new PropertyMetadata(new PropertyChangedCallback(Stack3DPanel.OnHorizontalOffsetPropertyChanged)));

private static void OnHorizontalOffsetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Stack3DPanel pnl = d as Stack3DPanel;
if (pnl != null)
{
pnl.InvalidateArrange();
}
}

Friday, February 6, 2009

Help! My breakpoints are not being hit!

Man! I have wasted a lot of time the past two days with this one, so I thought I would blog about it immediately in case anyone else is seeing this. As I was working on a Silverlight app, I ran into a bug. I decided to add a breakpoint and run the debugger in order to see what was going on. I added the breakpoint and ran the debugger (F5). I noticed the red circle that indicates the breakpoint changed from a red circle to a little warning sign with an error message. "The breakpoint will not currently be hit. No symbols have been loaded for this document."

image

This started me off on an incredibly painful, and long search for answers. I tried deleting every possible temporary file I could think of. I tried cleaning the solution and rebuilding it. I restarted Visual Studio. I ran IISReset. I rebooted my machine. I tried a handful of other things and... nothing! I was still not able to debug! Finally, one of my co-workers saw a post on that said to check the properties of the web project you are trying to debug (right click on it in the solution explorer). Next click on the Web tab and make sure that Silverlight is selected as one of the Debugger options.

image

Some way or another, the Silverlight option became unchecked. Once I checked it, I was able to run and debug with no problems. I hope this saves some of you a lot of headaches and hours of wasted time.

Good find on this one Scott!

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!

Monday, January 19, 2009

Presidential Swearing-In Ceremony On Silverlight

http://www.pic2009.org/blog/entry/watch_the_swearing-in_ceremony_on_the_web/

image 

Yeah. I think Silverlight has caught on fairly well. If you are considering Silverlight but are wondering if the adoption rate is an issue, consider this. Many big players including NBC Olympics, Netflix, AOL, and now the Presidential Inaugural Committee. Yeah... I think it's safe to say Silverlight is here to stay. Watch out Flash!

Thursday, January 15, 2009

Silverlight Tip: Give Your Silverlight App Focus

I am working on a Silverlight application that starts off with a login page. Typically, users do not like to use the mouse when they get to a login page. They expect to go to the page, type their user name, tab, type their password, click return and they should be logged in. In order to get this type of behavior in a Silverlight application, you need to set the tab order of your fields, set the focus to the username textbox and also set the focus to your Silverlight app (remember... this is content inside of an aspx page.. or an htm page). To give the Silverlight content focus, simply make this call:

HtmlPage.Plugin.Focus();


Then, give the username textbox focus and you should be set to go. One other thing... if you want users to be able to hit the return key immediately after typing their password, you will have to check for the return key in the text changed event handler of the password textbox. If the enter key is detected, then you can attempt to login at that time. If you do not do this, you will force your users to tab to the login button and then hit return. This just saves them a few clicks.

Friday, January 9, 2009

Weird Silverlight Bug!

Ok. This is a weird one. It had been causing problems in one of my apps for a very long time, and it was making me very frustrated... so I decided to hunt this one down. Anyway.. Last night, I figured it out.

Tablet Pc + Listboxes inside Tab Panels = CRASH!

 

This doesn't make too much sense, so let me explain. Listboxes work great in Silverlight. Tab controls work great as well. If you have a listbox in one of the TabPanels it works great as well. If you do this in a Tablet PC (Vista... XP works fine... Go figure!), things are not so good. I built this little app just to verify my find. It consists of a simple TabControl with two tabs. The first tab has a listbox with three items. the second tab has a button.

<UserControl x:Class="TestSlTabletPcBug.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tools="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls">
<
Grid x:Name="LayoutRoot" Background="White">
<
tools:TabControl Height="300" Width="500">
<
tools:TabItem Header="list">
<
ListBox>
<
ListBoxItem Content="1"/>
<
ListBoxItem Content="2"/>
<
ListBoxItem Content="3"/>
</
ListBox>
</
tools:TabItem>
<
tools:TabItem Header="button">
<
Button Content="hi"/>
</
tools:TabItem>
</
tools:TabControl>

</
Grid>
</
UserControl>



image



I do not have a tablet pc, but I do have a Tooya tablet. When this tablet is not plugged in, the application works fine. I can select any item in the listbox and switch between tabs. As soon as I plug my tablet in it doesn't behave as nicely. If there is any item on the listbox, I can't switch tabs. If I do, the application crashes and IE shuts down. Weird!



The workaround....



My workaround was easy... unplug the Tooya tablet and then it worked fine. If you are running on an actual Tablet Pc, simply go to the list of services and stop the Tablet Pc Input Service. Once this is stopped, the application should work fine.



Well... there it is. Hopefully this will save some of you some frustration.

Tuesday, January 6, 2009

Detecting a Double Click in Silverlight 2

Nope! It's not supported. In Silverlight 2, you can only detect single clicks. So... here's a way of faking it.

First of all, you are going to need an integer variable indicating how much time between two consecutive clicks constitute a double click. In this example, I am setting it to 175 milliseconds.

private const int DOUBLE_CLICK_TIME = 175;  // milliseconds between MouseUp and subsequent MouseDown


Next, you will need a DateTime variable to store the time of the last MouseLeftButtonUp event. Initially, you can set this to DateTime.MinValue.



private DateTime _lastTimeClicked = DateTime.MinValue;


Next, you will need to assign event handlers for your object's MouseLeftButtonDown and MouseLeftButtonUp events. In this case, I want to detect the double click on an object named LayoutPanel.



this.LayoutPanel.MouseLeftButtonDown += new MouseButtonEventHandler(LayoutRoot_MouseLeftButtonDown);
this.LayoutPanel.MouseLeftButtonUp += new MouseButtonEventHandler(LayoutRoot_MouseLeftButtonUp);


Now implement the event handlers. In the Button Up event handler simply store the current time as the last time clicked. Then in the down event handler call the IsDoubleClicked Method.



void LayoutRoot_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
_lastTimeClicked = DateTime.Now;
}

void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (IsDoubleClick())
{
//Double Click Logic Here
}
}


Finally, implement the IsDoubleClick event. This method returns true if there has been a double click, and false if not. It simply measures the current time agains the time last clicked. If the elapsed time between the two is less than the time specified in the DOUBLE_CLICK_TIME constant previously defined, it returns true... indicating a double click.




private bool IsDoubleClick()
{
TimeSpan elapsed = DateTime.Now.Subtract(this._lastTimeClicked);
return elapsed.TotalMilliseconds < DOUBLE_CLICK_TIME;
}



So that's it. As with some of my other posts, I hope this information will become useless soon because it gets included in a future release of Silverlight, but in the mean time, you can use this simple workaround to get the double click functionality into your Silverlight applications.