Friday, December 19, 2008

Re: Disappearing Row Problem.

Just a quick update. Previously I posted a workaround for the disappearing row problem with the Silverlight datagrid. Well, if you update to the latest Silverlight datagrid (http://silverlight.net/forums/t/59990.aspx) you will no longer need this workaround. Thank you Microsoft!!!!

image

How to get the Mouse Position in a Silverlight Application

Silverlight provides several Mouse events that can be used to determine the position of the mouse. These include

  • MouseMove
  • MouseEnter
  • MouseLeave
  • MouseLeftButtonDown
  • MouseLeftButtonUp

Depending on the event that is fired, you have access to either an object of type MouseEventArgs or MouseButtonEventArgs. This object inside your event handler contains the information you need to determine the current mouse position. In the event handler, call the GetPosition method to retrieve the current mouse position. If you pass in an object, you will get the mouse position relative to that object. If you pass in Null, you will get the mouse position relative to the Silverlight plugin on the page.

Here is a quick example of how to do this.

LayoutRoot.MouseMove += new MouseEventHandler(LayoutRoot_MouseMove);



void LayoutRoot_MouseMove(object sender, MouseEventArgs e)
{
Point position = e.GetPosition(null);
}

Netflix on Silverlight!

YEAH!!!! Netflix has started a rollout of their new movie player. The new player is now built on Silverlight. If you want to get the new player before it is rolled out to everyone, go to http://www.netflix.com/silverlightoptin This will take you to the following screen showing the system requirements.

image 

When you are done you'll get a confirmation that the new player has been enabled... that's it!

image

Here is what the player looks like.... When you scrub the video you get a nice timeline showing you where you are scrubbing to on the movie... Very cool!

image

You still have the fullscreen support.

image

So checkout the new Silverlight movie player on Netflix. I'm very pleased with it.

Friday, December 12, 2008

Why Not User Your Own Technology?

image

Seriously?!?!?!? Why does the Surface website (www.microsoft.com/surface) use Adobe Flash? Isn't Silverlight just as good (If not better)? I'm using the technology and telling others that it is a better technology (younger... and therefore not as robust in some areas, but none the less better), yet Microsoft decides to go with Flash in sites like this one. Really? Practice what you preach Microsoft!

Tuesday, December 9, 2008

Data Grid Disappearing Line Trick/Bug

I've been working with the Silverlight Datagrid for a while now. Nifty control.  But it has caused me a great deal of frustration! One bug I have run across (on the 2.0 bits) is the occasional disappearing of rows. After a lot of debugging, yelling at my computer, and many, many Google searches, I was able to figure it out.

It seems this problem occurs whenever a control inside the datagrid has focus and the ItemsSource is modified. I have seen this when I add, update or delete items in the ItemsSource. Ahhh! Very annoying bug! The easiest work around.... make sure no controls inside the datagrid have focus prior to messing with the ItemsSource. In my application, I have several checkboxes and buttons in every row of the datagrid. In the event handlers for the click events or checked/unchecked events, I simply set focus to the entire datagrid (myGrid.Focus()), before I run any of the code that modifies that row. That seemed to take care of the situation.

From other posts I have read out there, a different way to do this is to remove the datagrid from the visual tree and replace it every time you modify the ItemsSource... but that seems a bit drastic. Hopefully this post will become obsolete very soon. (Hint hint. Microsoft... Please fix this soon!)

Monday, December 8, 2008

Java FX?

So, Java has their own version of Silverlight/Flash now called JavaFx. I spent some time looking at it today and have mixed emotions. On the one hand, they are advertising that this works on "All the Screens of Your Life." You should be able to write JavaFx applications that run on your pc, your mobile device, or your tv if you would like. Two points Java. I'm still not sold on the technology though. I took a look at some of the sample applications. They did look cool (Flash/Silverlight like), but the install experience was not as smooth. Check it out for yourself and see what you think. One downer... The way in which UI's are created. They are going with a declarative model much like silverlight and Adobe Flex. So far so good, but the language is.... not very elegant in my opinion. It makes sense to declare it in an xml language, not this...

image 

Ok, not a huge deal. I could probably get used to it. The second, and I think biggest thing that Silverlight has going for it over this and any other technology out there is its templating capabilities. It's one thing to skin a control, its a totally different thing to be able to create a lookless control.

Friday, December 5, 2008

How to Make a Silverlight Image Slide Show

There's a lot of websites out there with some very cool image slideshows. I figured I would take the time to write a short tutorial on how to make a basic image slideshow with fade in/out transitions between images.

First things first... The xaml...

<UserControl x:Class="ImageSlideshow.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<
UserControl.Resources>
<
Storyboard x:Name="FadeOutAnimation">
<
DoubleAnimation Duration="00:00:00.50" From="1" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="theImage" />
</
Storyboard>
<
Storyboard x:Name="FadeInAnimation">
<
DoubleAnimation Duration="00:00:00.50" From="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="theImage" />
</
Storyboard>
</
UserControl.Resources>
<
Grid x:Name="LayoutRoot" Background="Black">
<
Image x:Name="theImage" Stretch="Uniform"/>
</
Grid>
</
UserControl>

This is all the xaml it takes to make a very basic slide show. The application itself consists of a Grid and an image inside the grid. I have set the Stretch property to Uniform so the image will take up the entire screen or as much of it as the aspect ratio of the image will allow. The other important piece here is the Resources section. The FadeInAnimation and FadeOutAnimation modify the image's Opacity property from 0 to 1 or 1 to 0 respectively.


On to the code behind.



Now, create a timer which will be used to transition between images. To initialize the timer, create a new event handler for the tick. Set the value of 'INTERVAL' to the number of seconds you wish to display each image.


timer.Interval = new TimeSpan(0, 0, 0, INTERVAL, 0);
timer.Tick += new EventHandler(timer_Tick);
timer.Start();

Now create an ObservableCollection of strings to hold the names of the images. Also create an integer to indicate which image is currently displayed.


private ObservableCollection<string> _images;
private int _currentIndex = 0;

To initialize the _images collection I created a separate method (good programming practice!)

private void InitializeImages()
{
_images = new ObservableCollection<string>()
{
"Autumn Leaves.jpg",
"Creek.jpg",
"Desert Landscape.jpg",
"Dock.jpg",
"Forest Flowers.jpg",
"Forest.jpg"
};

SetImageSource(_images[_currentIndex]);
}

These strings correspond to the names of the images I placed in a new directory I created in the solution named Images. Next, create a method named SetSource (which is the method I call at the end of the InitializeImages method). I separated this into a separate method because the code inside the method will be run over and over.


private void SetImageSource(string imageName)
{
string name = "Images/" + imageName;
BitmapImage bmi = new BitmapImage(new Uri(name, UriKind.Relative));
theImage.Source = bmi;
}

All this method does is set the source of the image object to the image that has the name that is passed in as the input parameter. You cannot just set the images.Source property to the string passed in, you need to set it to a BitmapImage object which we can create based on the string passed in.

We're getting close! Now implement the timer's tick event handler


void timer_Tick(object sender, EventArgs e)
{
_currentIndex++;

if (_currentIndex == _images.Count)
{
_currentIndex = 0;
}

FadeOutAnimation.Begin();
}

Here, you increment the _currentIndex. If the index reaches the end of the list, simply set it back to zero. Once the index has been updated, fade out the image. Do this by calling the Begin method of the FadeOutAnimation defined in the xaml. The last thing that needs to be done is to define an even handler (in the class constructor) for the Completed event of the FadeOutAnimation. When the animation is finished, set the image source to the next image and fade the image back in by calling the FadeInAnimation's Begin method.

void FadeOutAnimation_Completed(object sender, EventArgs e)
{
SetImageSource(_images[_currentIndex]);
FadeInAnimation.Begin();
}


That's it! Not a lot of code! This could easily be modified to add some play, stop, pause, next, previous controls. It would also not take a lot of work to add different animations to change the transitions between the images. 

Good luck and have fun with this one!

Monday, December 1, 2008

Help! I Can't Access Anything Inside My Silverlight Viewbox!

The much anticipated Viewbox control is finally here. I have been waiting patiently for this control for a while now. It behaves the same way the Viewbox in WPF does. It takes its content and allows it to stretch and contract to fill the desired space... Very handy!

One small issue... a bug. As of the latest release (11/29/08), you cannot directly access any object you place inside the Viewbox. For example, you can have a viewbox that contains a Button named myButton.

<controls:Viewbox x:Name="vBox">
<
Button x:Name="myButton"/>
</
controls:Viewbox>

In your code behind, if you try to access myButton, it will always return null. This is a known issue that the Silverlight team working on the toolkit has promised to fix. For now, here is the workaround. Simply access myButton by looking at the Child property of the Viewbox.


((Button)vBox.Child).Text = "myButton Text";