SilverLight学习笔记--实际应用(二) 建立一个轮盘图片展示程序

这里我们一起来制作一个Silverlight轮盘图片展示程序,效果如下图:

我们要实现的功能包括:
1、通过图片数量滑条来改变轮盘中图片的数目
2、通过图片X轴与Y轴半径滑条来改变轮盘的X轴方向与Y轴方向的大小
3、通过Auospin按钮来让轮盘自动转动,且其转动速度取决于鼠标距离程序背景中线的距离
4、通过Reset按钮让轮盘恢复初始设置
5、通过按下鼠标左键手工让轮盘转动,且其转动速度取决于鼠标距离程序背景中线的距离
,释放鼠标左键让轮盘停止转动。

6、点击轮盘图片时就在放映区显示此图片的大图
下面我们来创建我们的程序。
打开Vs2008,新建项目,创建一个名为SLImageCarousel的Silverlight应用程序,然后在SilverlightApplication1项目上新建一个名为images的文件夹,请拷贝二三十张图片到此文件夹下,分别改名字从0.jpg,1.jpg,......n.jpg,另外再拷贝一张图片1.jpg到外面,程序如下图:

一、界面代码如下(Page.xaml文件):


Code

二、程序后台代码如下:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
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.Threading; //因为要用到DispatcherTimer等
using System.Windows.Media.Imaging;  //因为要用到BitmapImage
using System.Diagnostics;  //因为要用到Debug

namespace SilverlightApplication1
{
    
public partial class Page : UserControl
    
{

        
定义变量

        
定义要调用的函数

        
public Page()
        
{
            InitializeComponent();

            ResetImagesButton.Click 
+= new RoutedEventHandler(ResetImagesButton_Click); //按下Reset按钮时做ResetImagesButton_Click操作

            myTimer 
= new DispatcherTimer();
            myTimer.Interval 
= TimeSpan.FromMilliseconds(33);
            myTimer.Tick 
+= new EventHandler(myTimer_Tick);

            
//Console.WriteLine("call start");

            
//设置数量控制滑条的最大值与最小值
            numPhotosSlider.Maximum = 180;
            numPhotosSlider.Minimum 
= 10;

            
//设置X半径控制滑条的最大值与最小值
            radiusSliderX.Maximum = 500;
            radiusSliderX.Minimum 
= 320;

            
//设置Y半径控制滑条的最大值与最小值
            radiusSliderY.Maximum = 200;
            radiusSliderY.Minimum 
= 100;

            Loaded 
+= new RoutedEventHandler(Page_Loaded);

            BuildImages();
        }



        
private void numPhotosSliderChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        
{
            Slider s 
= sender as Slider;

            
if (page_loaded) //如果页面已经加载
            {
                RemoveImages();  
//移除所有图片

                num_images 
= (int)s.Value; //重新设置当前应该加载的图片数量

                BuildImages();  
//重新加载图片
            }

        }


        
private void ResetImagesButton_Click(object sender, RoutedEventArgs e)
        
{
            RemoveImages();  
//清除所有图片

            
恢复变量默认初始值

            BuildImages();  
//重新加载指定数量的图片

            
重新设置滑条默认值
        }


        
private void radiusSliderChangedX(object sender, RoutedPropertyChangedEventArgs<double> e)
        
{
            Slider s 
= sender as Slider;

            
if (page_loaded) //如果页面已经成功加载则作后续处理
            {
                RemoveImages();  
//移除所有图片

                radiusX 
= (int)s.Value; //取得新的半径值

                
if (s.Value < 450)  //如果新的半径值低于我们要求的上限,则作调整,否则不作变动
                {
                    
//调整mainImage控件的ZIndexProperty属性,以免它因为radius的变动被后面的图片轮挡住
                    int z = (int)mainImage.GetValue(Canvas.ZIndexProperty);
                    z 
+= 2;
                    mainImage.SetValue(Canvas.ZIndexProperty, z);
                }

                
else
                
{
                    mainImage.SetValue(Canvas.ZIndexProperty, 
169);
                }


                BuildImages(); 
//重新加载图片 
            }


        }



        
private void MainContactDown(object sender, MouseButtonEventArgs e)
        
{
            Point p 
= e.GetPosition(this);
            Debug.WriteLine(
">>" + p.Y);
            
if (p.Y > 500 && p.Y < 650)  //判断是否在指定的区域内按下了鼠标
            {
                main_down 
= true;
            }

        }


        
private void MainContactUp(object sender, MouseButtonEventArgs e)
        
{
            main_down 
= false;
        }


        
private void root_MouseMove(object sender, MouseEventArgs e)
        
{
            Point p 
= e.GetPosition(this);
            speed 
= ((p.X - 500/ 500* 0.0755;  //调整轮盘的转速
            
//Debug.WriteLine("changed: " + speed);
        }


        
private void radiusSliderChangedY(object sender, RoutedPropertyChangedEventArgs<double> e)
        
{
            Slider s 
= sender as Slider;
            
if (page_loaded) //如果页面已经成功加载则作后续处理
            {
                RemoveImages();  
//移除所有图片

                radiusY 
= (int)s.Value; //取得新的半径值
                if (s.Value < 200)  //如果新的半径值低于我们要求的上限,则作调整,否则不作变动
                {
                    
//调整mainImage控件的ZIndexProperty属性,以免它因为radius的变动被后面的图片轮挡住
                    int z = (int)mainImage.GetValue(Canvas.ZIndexProperty);
                    z 
+= 2;
                    mainImage.SetValue(Canvas.ZIndexProperty, z);
                }

                
else
                
{
                    mainImage.SetValue(Canvas.ZIndexProperty, 
169);
                }


                BuildImages(); 
//重新加载图片 
            }

        }


        
autoTimer_Tick 事件处理函数

        
private void AutoSpinButton_Click(object sender, RoutedEventArgs e)
        
{
            autoTimer.Start();
            autoTimer.Interval 
= TimeSpan.FromMilliseconds(33);
            autoTimer.Tick 
+= new EventHandler(autoTimer_Tick);
        }



    }

}

代码说明:
1、关于轮盘上图片位置的确定
 根据以下的椭圆图


 在椭圆 (x2 /a)+(y2  /b ) =1 中,令 x/a=cosθ, y/b=sinθ 得 x=a cos θ   y=b sin θ,这就是椭圆的参数方程,其中θ为参数(注意:θ 的几何意义是椭圆上点P对应的参数θ 应是∠AOx ,而不是 ∠POx);而 a 为椭圆的外切圆半径,b为椭圆的内切圆半径。
 当我们确定椭圆轨道上放置N张图片时,我们可以计算得到图片间的夹角 θ= 360/N。此图这个椭圆正好在坐标中心,而在程序中,它可能位于于坐标(x,y)处。所以我们代码实现如下:
  取得夹角

              #region 图片角度位置的计算与保存
                
double ang = (double)i * ((Math.PI * 2/ num_images);  //取得对应位置的角度值                
                angleValues.Add(ang);  //把角度值保存到List中
                #endregion

  取得坐标

              //根据角度确定椭圆轨迹上的坐标值
                double my_x = (double)Math.Cos((double)angleValues[i]) * radiusX + centerX; //取得X轴坐标值
                double my_y = (double)Math.Sin((double)angleValues[i]) * radiusY + centerY; //取得Y轴坐标值

2、关于图片大小

  为了产生轨道上离我们近的图片大,离我们远的图片小的效果,我们需要根据图片放置的位置调整图片显示的大小,我们用以下方式来实现此目的

              //缩放变换ScaleTransform允许我们对元素进行缩放,通过属性ScaleX和ScaleY来分别指定在X轴和Y轴上的缩放比例,
                
//同样也可以使用属性CenterX和CenterY来指定缩放中心
                ScaleTransform st = c.RenderTransform as ScaleTransform; 
              
double my_scale = (my_y - st.ScaleY) / (centerY + radiusY - st.ScaleY);  //按一定方式进行缩放,原则是Y轴值大的图片大,Y轴值小的图片小
                
//double my_scale = (my_x - st.ScaleX) / (centerX + radiusX - st.ScaleX); //另外一种缩放公式  
                
//double my_scale = 2 + (double)Math.Cos((double)angleValues[i] - Math.PI / 2);  //另外一种缩放公式  

                st.ScaleX 
= my_scale;
              st.ScaleY 
= my_scale;

3、关于轮盘转速

我们有个Speed参数来调整轮盘旋转速度,实现思路是根据鼠标当前位置相对于轮盘Y轴的相对位置来调整,实现代码如下:

 

            Point p = e.GetPosition(this);
            speed 
= ((p.X - 500/ 500* 0.0755;  //调整轮盘的转速

 

运行程序即可看到效果


 

本文程序在Silverlight2.0和VS2008环境中调试通过。本文参照了部分网络资料,希望能够抛砖引玉,大家共同学习。
(转载本文请注明出处)

前往:Silverlight学习笔记清单
posted @ 2009-10-25 13:03  wsdj  阅读(2933)  评论(7编辑  收藏  举报