Friday, March 07, 2008
« Silverlight 2.0 Carousel | Main | CarSpot Carousel »

Ok, here is my silverlight 2 port of the ever popular Image Carousel sample.  For me, at least, it's much easier to follow what's going on than the JavaScript version.  Here's the markup required in the page:

<UserControl x:Class="ImageUploader.ImageCarousel"

    xmlns="http://schemas.microsoft.com/client/2007"

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

    Width="800" Height="600" Canvas.Top="0">   

<Canvas x:Name="_mainCanvas" Loaded="mainCanvasLoaded" MouseMove="whenMouseMoves"

        MouseLeftButtonDown="mainDown" MouseLeftButtonUp="mainUp" MouseLeave="mainCanvasMouseLeave" >

    <Canvas Name="imagesHolder" Canvas.Left="0" Canvas.Top="0">

        <Canvas Name="mainImageHolder" Canvas.Left="200" Canvas.Top="60" Canvas.ZIndex="169" Opacity="1.0">

            <Image Name="mainImage" Stretch="UniformToFill" Height="225" Width="300"/>

        </Canvas>

    </Canvas>

</Canvas>

</UserControl>

And here is the code-behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;

namespace ImageUploader
{
public partial class ImageCarousel : UserControl
{
public ImageCarousel()
{
InitializeComponent();
_mainDown = false;
_urls = new Dictionary<Image, string>();
_angles = new List<double>();
_imagePaths = new List<string>();
//_imagePaths.Add("Upload/1.jpg");
//_imagePaths.Add("Upload/2.jpg");
//_imagePaths.Add("Upload/3.jpg");
_dispTimer = new System.Windows.Threading.DispatcherTimer();
_dispTimer.Interval = TimeSpan.FromMilliseconds(25);
_dispTimer.Tick += new EventHandler(dt_Tick);
_dispTimer.Stop();
}

private List<double> _angles;
private bool _mainDown = false;
private List<string> _imagePaths;
private List<ScaleTransform> _scaleTransforms = new List<ScaleTransform>();
private double _speed = -0.0425;
private Dictionary<Image, string> _urls;
private System.Windows.Threading.DispatcherTimer _dispTimer;

public void AddImage(string imageUrl)
{
_mainDown = false;
_dispTimer.Stop();
_angles.Clear();
_scaleTransforms.Clear();
_urls.Clear();

for (int i = 0; i < _imagePaths.Count; ++i)
{
Canvas holder = (Canvas)_mainCanvas.FindName("imgHolder" + i);
_mainCanvas.Children.Remove(holder);
}

_imagePaths.Add(imageUrl);
Image img = (Image)_mainCanvas.FindName("mainImage");
string srcPath = _imagePaths[_imagePaths.Count -1 ];
img.Source = new BitmapImage(new Uri(GetURLBase() + srcPath));
img.SetValue(Canvas.ZIndexProperty, 169);

BuildImages();
}

private void mainCanvasLoaded(object sender, RoutedEventArgs e)
{
if (_imagePaths.Count > 0)
{
Image img = (Image)_mainCanvas.FindName("mainImage");
img.Source = new BitmapImage(new Uri(GetURLBase() + _imagePaths[0]));
img.SetValue(Canvas.ZIndexProperty, 169);
//
BuildImages();
}
}

public List<string> ServerImagePaths { get; set; }

protected void BuildImages()
{
int leftPos = 0;
for (int i = 0; i < _imagePaths.Count; ++i)
{
Canvas imgHolder = new Canvas();
imgHolder.SetValue(Canvas.NameProperty, "imgHolder" + i);
imgHolder.SetValue(Canvas.LeftProperty, leftPos);
imgHolder.SetValue(Canvas.TopProperty, 0);
//Come back to reflections...
//Canvas imgHolderReflection = new Canvas();
//imgHolderReflection.SetValue(Canvas.NameProperty, "imgHolderRef" + i);
//imgHolderReflection.SetValue(Canvas.TopProperty, 160);
//imgHolderReflection.Opacity = 1;
//LinearGradientBrush lgb = new LinearGradientBrush();
//lgb.StartPoint = new Point(0, 0);
//lgb.EndPoint = new Point(0, 1);
//lgb.GradientStops.Add(new GradientStop());
//lgb.GradientStops.Add(new GradientStop());
//lgb.GradientStops[0].Offset = .37;
//lgb.GradientStops[0].Color = Color.FromArgb(0x00, 0x00, 0x00, 0x00);
//lgb.GradientStops[1].Offset = 1;
//lgb.GradientStops[1].Color = Color.FromArgb(0x88, 0x00, 0x00, 0x00);
//imgHolderReflection.OpacityMask = lgb;
//imgHolder.Children.Add(imgHolderReflection);
//
Rectangle rec = new Rectangle();
rec.SetValue(Rectangle.NameProperty, "rec" + i);
rec.SetValue(Canvas.TopProperty, -6);
rec.SetValue(Canvas.LeftProperty, -6);
rec.Height = 92.0;
rec.Width = 92.0;
rec.Fill = new SolidColorBrush(Colors.LightGray);
imgHolder.Children.Add(rec);
//
Image img = new Image();
img.Cursor = Cursors.Hand;
img.MouseEnter +=new MouseEventHandler(img_MouseEnter);
img.MouseLeave +=new MouseEventHandler(img_MouseLeave);
img.MouseLeftButtonDown +=new MouseButtonEventHandler(img_MouseLeftButtonDown);
img.MouseLeftButtonUp +=new MouseButtonEventHandler(img_MouseLeftButtonUp);
img.Stretch = Stretch.UniformToFill;
img.SetValue(Image.NameProperty, "img" + i);
BitmapImage imgSource = new BitmapImage(new Uri(GetURLBase() + _imagePaths[i]));
_urls.Add(img, GetURLBase() + _imagePaths[i]);
img.Source = imgSource;
img.Width = 300;
img.Height = 225;

img.Opacity = 1;
imgHolder.Children.Add(img);
ScaleTransform imgCanvasScaleTrans = new ScaleTransform();
_scaleTransforms.Add(imgCanvasScaleTrans);
imgCanvasScaleTrans.ScaleX = 1;
imgCanvasScaleTrans.ScaleY = 1;
imgCanvasScaleTrans.CenterX = 50;
imgCanvasScaleTrans.CenterY = 50;
imgHolder.RenderTransform = imgCanvasScaleTrans;
//
_mainCanvas.Children.Add(imgHolder);
//
_angles.Add( i*((Math.PI*2)/_imagePaths.Count) );
}
PositionItems();
_mainDown = true;// huh?
//Set dispatcher interval
_dispTimer.Start();
}

/// <summary>
/// Not used yet
/// </summary>
/// <param name="i"></param>
protected void AddOne(int i)
{
}

void dt_Tick(object sender, EventArgs e)
{
MoveItems();
}

protected void PositionItems()
{
int radiusX=400;
int radiusY=110;
int centerX=425;
int centerY = 260;

for(int i = 0; i < _imagePaths.Count;++i)
{
double myX = Math.Cos(_angles[i])*radiusX + centerX;
double myY = Math.Sin(_angles[i])*radiusY + centerY;
Canvas imgCanvas = (Canvas)_mainCanvas.FindName("imgHolder" + i);
imgCanvas.SetValue(Canvas.LeftProperty, myX);
imgCanvas.SetValue(Canvas.TopProperty, myY);
ScaleTransform stRef = _scaleTransforms[i];
double sc = (myY - stRef.ScaleY) / (centerY + radiusY-stRef.ScaleY);
stRef.ScaleX = sc;
stRef.ScaleY = sc;
_angles[i] += _speed;
imgCanvas.SetValue(Canvas.ZIndexProperty, (int)myY);
}
}

protected void MoveItems()
{
if (_mainDown)
{
PositionItems();
}
}

void img_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{

}

void img_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Image img = (Image)sender;

     Image mainImg = (Image)_mainCanvas.FindName("mainImage");
mainImg.Source = new BitmapImage(new Uri(_urls[img]));
mainImg.SetValue(Canvas.ZIndexProperty, 169);
}

void img_MouseLeave(object sender, MouseEventArgs e)
{
//Change color BACK or something cool
}

void img_MouseEnter(object sender, MouseEventArgs e)
{
//Change color or something cool
}

private void whenMouseMoves(object sender, MouseEventArgs e)
{
Point pt = e.GetPosition(null);
double _root_xmouse = pt.X;
     double _root_ymouse = pt.Y    ;
_speed = ((_root_xmouse - 500) / 500) * 0.0755;
}

private void mainDown(object sender, MouseButtonEventArgs e)
{
_mainDown = true;
}

private void mainUp(object sender, MouseButtonEventArgs e)
{
_mainDown = false;

}

private void mainCanvasMouseLeave(object sender, MouseEventArgs e)
{

}


protected string GetURLBase()
{
string str = System.Windows.Application.Current.Host.Source.OriginalString;
return str.Substring(0, str.LastIndexOf("/")).Replace("ClientBin", string.Empty);
}
}
}


 

Not formatted as well as my last posts, I know.  It seems that Google reader doesn't like it when I paste out of Word. Now, one thing that is not very apparent is how to add this UserControl to another UserControl, assuming that JUST having an image carousel is not what you're after.  You need to include the following on the top-level user control:

xmlns:CarSpot="clr-namespace:ImageUploader"

which then allows you to refer to the code:

<CarSpot:ImageCarousel x:Name="_carousel"></CarSpot:ImageCarousel>

This is an aspect of XAML I don't like. There's nothing (that I can see) in the structure/XSD of a XAML document that tells me that an attribute value starting with "clr-namespace:" is something special.  There's a lot of magic like this in XAML.  The Visual Studio "Silverlight Chainer" as the file calls the Beta 1 tools are definately buggy and incomplete.  I am lucky to be able to hit F5 10 times before I get errors trying to debug and having to kill Cassini and VS2008.  I've also found that it's very easy to crash the designer by having naughty things in your code-behind.  It appears that unlike more mature design-time experiences there is no "IsDesignTime" flag that would allow you to keep from having code execute while designing.  I can tell that this is Cider by the wonderfully descriptive stack traces I get, yet things like dragging the new Silverlight controls onto the surface or even moving them around (I'm sick of tweaking location with Canvas.Top/Canvas.Left) are not working yet.  This is a huge step forward, but I've got to think there'll be another beta after this one now.

And that's that.  I should have some more Silverlight 2 observations later, especially about the threading and HTTP aspects.

Friday, March 07, 2008 4:36:07 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [4]  |  Trackback Related posts:
AGT so far
Run time is design time for AGT [12]
Netflix API
Run time is design time for AGT [11]
Silverlight RC 0
Run time is design time for AGT [10]
Tracked by:
http://blastpr.com/wiki/js/pages/nexium/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/clomid/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/celebrex/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/celexa/index.html [Pingback]
http://blastpr.com/wiki/js/pages/cymbalta/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/hoodia/index.html [Pingback]
http://blastpr.com/wiki/js/pages/prozac/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/lipitor/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/effexor/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/wellbutrin/index.html [Pingback]
http://blastpr.com/wiki/js/pages/tramadol/index.html [Pingback]
http://blastpr.com/wiki/js/pages/paxil/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/ultram/index.html [Pingback]
http://blastpr.com/wiki/js/pages/synthroid/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/rainbow-brite/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/prilosec/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/nexium/index.html [Pingback]
http://blastpr.com/wiki/js/pages/lipitor/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/cialis/index.html [Pingback]
http://blastpr.com/wiki/js/pages/celexa/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/synthroid/index.html [Pingback]
http://blastpr.com/wiki/js/pages/celebrex/index.html [Pingback]
http://blastpr.com/wiki/js/pages/lexapro/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/prozac/index.html [Pingback]
http://blastpr.com/wiki/js/pages/wellbutrin/index.html [Pingback]
http://blastpr.com/wiki/js/pages/effexor/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/melatonin/index.html [Pingback]
http://blastpr.com/wiki/js/pages/coumadin/index.html [Pingback]
http://blastpr.com/wiki/js/pages/hoodia/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/cymbalta/index.html [Pingback]
http://blastpr.com/wiki/js/pages/ultram/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/claritin/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/lexapro/index.html [Pingback]
http://morningside.edu/mics/_notes/pages/soma/index.html [Pingback]
http://blog.netmedia.hr/wp-includes/js/docs/84238305/index.html [Pingback]
http://swellhead.netswellhead.net/docs/79619129/index.html [Pingback]
http://realestate.hr/templates/css/docs/28593877/index.html [Pingback]
http://lecouac.org/ecrire/lang/docs/49649526/index.html [Pingback]
http://thejohnslater.com/pix/img/docs/86193101/index.html [Pingback]
http://thejohnslater.com/pix/img/docs/56008043/index.html [Pingback]
http://islands-croatia.comislands-croatia.com/includes/js/docs/06712704/index.ht... [Pingback]
http://promocija.com.hr/promocija.com.hr/includes/js/docs/37348396/index.html [Pingback]
http://coolioness.com/attachments/docs/03698289/index.html [Pingback]
http://hrvatska.biz/wp-includes/js/docs/80692203/index.html [Pingback]
http://promocija.com.hr/promocija.com.hr/includes/js/docs/63224938/index.html [Pingback]
http://temerav.com/images/menu/20420171/index.html [Pingback]
http://swellhead.netswellhead.net/docs/92808772/index.html [Pingback]
http://islands-croatia.comislands-croatia.com/includes/js/docs/82710340/index.ht... [Pingback]
http://slaterjohn.com/downloads/2col/28436634/index.html [Pingback]
http://witze-humor.de/templates/images/docs/83157240/index.html [Pingback]
http://lecouac.org/ecrire/lang/docs/30125734/index.html [Pingback]
http://split-dalmatia.com/split-dalmatia.com/images/docs/73811526/index.html [Pingback]
http://jivest2006.com/docs/42940613/index.html [Pingback]
http://temerav.com/images/menu/05559064/index.html [Pingback]
http://lecouac.org/ecrire/lang/docs/25282359/index.html [Pingback]
http://coolioness.com/attachments/docs/76375390/index.html [Pingback]
http://witze-humor.de/templates/images/docs/69259068/index.html [Pingback]
http://ncdtnanotechportal.info/generator/docs/87198700/index.html [Pingback]
http://islands-croatia.comislands-croatia.com/includes/js/docs/60974094/index.ht... [Pingback]
http://vladan.strigo.net/wp-includes/js/docs/09763218/index.html [Pingback]
http://pspdesktops.com/fileupload/store/docs/33460308/index.html [Pingback]
http://islands-croatia.comislands-croatia.com/includes/js/docs/87090382/index.ht... [Pingback]
http://coolioness.com/attachments/docs/60340594/index.html [Pingback]
http://temerav.com/images/menu/96509501/index.html [Pingback]
http://islands-croatia.comislands-croatia.com/includes/js/docs/68291686/index.ht... [Pingback]
http://blog.netmedia.hr/wp-includes/js/docs/91708760/index.html [Pingback]
http://islands-croatia.comislands-croatia.com/includes/js/docs/54089144/index.ht... [Pingback]
http://ncdtnanotechportal.info/generator/docs/13227634/index.html [Pingback]
http://thejohnslater.com/pix/img/docs/73486930/index.html [Pingback]
http://split-dalmatia.com/split-dalmatia.com/images/docs/84431573/index.html [Pingback]
http://pddownloads.com/docs/66275653/index.html [Pingback]
http://add2rss.com/img/design/docs/73396176/index.html [Pingback]
http://thejohnslater.com/pix/img/docs/42082955/index.html [Pingback]
http://discussgod.com/cpstyles/docs/90092602/index.html [Pingback]
http://blog.netmedia.hr/wp-includes/js/docs/08493171/index.html [Pingback]
http://thebix.com/includes/compat/docs/29852280/index.html [Pingback]
http://add2rss.com/img/design/docs/90861918/index.html [Pingback]
http://thejohnslater.com/pix/img/docs/41914710/index.html [Pingback]
http://promocija.com.hr/promocija.com.hr/includes/js/docs/52060005/index.html [Pingback]
http://martinrozon.com/images/photos/docs/82037625/index.html [Pingback]
http://ipsilon.hr/ipsilon.hr/cms/4/lib/docs/24066563/index.html [Pingback]
http://easytravelcanada.info/js/pages/6/lipitor/ [Pingback]
http://easytravelcanada.info/js/pages/6/lexapro/ [Pingback]
http://sevainc.com/bad_denise/img/3/clomid/ [Pingback]
http://sevainc.com/bad_denise/img/4/cymbalta/ [Pingback]
http://easytravelcanada.info/js/pages/1/celebrex/ [Pingback]
http://birds.sk/img/cialis/ [Pingback]
http://easytravelcanada.info/js/pages/5/effexor/ [Pingback]
http://easytravelcanada.info/js/pages/12/wellbutrin/ [Pingback]
http://sevainc.com/bad_denise/img/7/nexium/ [Pingback]
http://sevainc.com/bad_denise/img/11/ultram/ [Pingback]
http://easytravelcanada.info/js/pages/11/ultram/ [Pingback]
http://sevainc.com/bad_denise/img/6/lexapro/ [Pingback]
http://sevainc.com/bad_denise/img/5/hoodia/ [Pingback]
http://sevainc.com/bad_denise/img/5/effexor/ [Pingback]
http://easytravelcanada.info/js/pages/9/rainbow-brite/ [Pingback]
http://sevainc.com/bad_denise/img/12/zoloft/ [Pingback]
http://easytravelcanada.info/js/pages/10/soma/ [Pingback]
http://sevainc.com/bad_denise/img/1/celebrex/ [Pingback]
http://easytravelcanada.info/js/pages/4/coumadin/ [Pingback]
http://adventure-traveling.com/images/img/cialis/ [Pingback]
http://sevainc.com/bad_denise/img/2/celexa/ [Pingback]
http://ina-tv.sk/img/cialis/ [Pingback]
http://sevainc.com/bad_denise/img/7/melatonin/ [Pingback]
http://sevainc.com/bad_denise/img/10/soma/ [Pingback]
http://jemnemelodierecords.sk/img/cialis/ [Pingback]
http://easytravelcanada.info/js/pages/9/prozac/ [Pingback]
http://cidesi.com/images/metro/metro2/pages/32162341/vip-adult-clubs.html [Pingback]
http://odin.net/images/pages/35694472/mature-chat.html [Pingback]
http://cidesi.com/images/metro/metro2/pages/32162341/caught-masturbating.html [Pingback]
http://odin.net/images/pages/35694472/romance-stories-novels-or-reads.html [Pingback]
http://cidesi.com/images/metro/metro2/pages/99493954/oops-babes.html [Pingback]
http://cidesi.com/images/metro/metro2/pages/99493954/asian-climate.html [Pingback]
http://odin.net/images/pages/35694472/thumbs-of-squirting-babes.html [Pingback]
http://odin.net/images/pages/35694472/time-square-webcam.html [Pingback]
http://gatewayplayhouse.com/photos/cai/pages/53348735/denise-davies-anal.html [Pingback]
http://odin.net/images/pages/52807681/marathon-florida-webcam.html [Pingback]
http://odin.net/images/pages/35694472/hot-mom-pics.html [Pingback]
http://odin.net/images/pages/35694472/baby-boy-s-name.html [Pingback]
"http://www.signalprocessingsociety.org/community/forum/buy-phentermine-online.h... [Pingback]
"http://www.signalprocessingsociety.org/community/forum/buy-viagra-online.html" ... [Pingback]
"http://www.signalprocessingsociety.org/community/forum/buy-soma-online.html" (h... [Pingback]
"http://www.signalprocessingsociety.org/community/forum/buy-hydrocodone-online.h... [Pingback]
"http://www.signalprocessingsociety.org/community/forum/buy-cialis-online.html" ... [Pingback]
"http://www.signalprocessingsociety.org/community/forum/buy-vicodin-online.html"... [Pingback]