zoukankan      html  css  js  c++  java
  • SnipperImages(Silverlight DEMO)控件设计之ImageSelector

         在SnipperImages中为了进行图片列表导航(前后方向)设计了ImageSelector控件,而这个控件不同于

    之前介绍过的Button, CheckBox, Slider,主要是其xaml中的UI元素变得数量庞大且行为更加复杂。所以通过

    了解这个控件,我们能够更好的熟悉StoryBoard,Path,ImageBrush,ScaleTransform,TranslateTransform

    等对象及属性的使用场景。


      首先来看一下DEMO运行效果:

     



         显示一张图片所使用的ui元素如下所示(其中之一):

    <Path x:Name="leftImg3" Stroke="White" MouseLeftButtonDown="OnImgClicked">
      
    <Path.Data>
        
    <PathGeometry>
          
    <PathFigure x:Name="pathFigure_leftImg3" IsClosed="True" StartPoint="130,15">
            
    <LineSegment x:Name="line1_leftImg3" Point="250,25"/>
            
    <LineSegment x:Name="line2_leftImg3" Point="250,95"/>
            
    <LineSegment x:Name="line3_leftImg3" Point="130,115"/>
          
    </PathFigure>
        
    </PathGeometry>
      
    </Path.Data>
      
    <Path.Fill>
        
    <ImageBrush x:Name="leftImg3Brush" Stretch="Fill"/>
      
    </Path.Fill>
    </Path>


         大家发现了,上面的内容只是可以正常显示一个图像(通过设置leftImg3Brush的ImageSource属性)而
    在每一个图片下方都会有一个倒影效果,其使用的就是ScaleTransform,其代码布局如下:

     <Path x:Name="left3Reflection" Stroke="White">
          
    <Path.Data>
            
    <PathGeometry>
              
    <PathFigure x:Name="pathFigure_left3Reflection" IsClosed="True" StartPoint="130,120">
                
    <LineSegment x:Name="line1_left3Reflection" Point="250,100"/>
                
    <LineSegment x:Name="line2_left3Reflection" Point="250,170"/>
                
    <LineSegment x:Name="line3_left3Reflection" Point="130,190"/>
              
    </PathFigure>
            
    </PathGeometry>
          
    </Path.Data>
          
    <Path.Fill>
            
    <ImageBrush x:Name="leftReflection3Brush" Stretch="Fill">
              
    <ImageBrush.RelativeTransform>
                
    <TransformGroup>
                  
    <!--实现投影效果-->
                  
    <ScaleTransform ScaleX="1" ScaleY="-1" />
                  
    <TranslateTransform Y="1" />
                
    </TransformGroup>
              
    </ImageBrush.RelativeTransform>
            
    </ImageBrush>
          
    </Path.Fill>
          
    <Path.OpacityMask>
            
    <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
              
    <LinearGradientBrush.GradientStops>
                
    <GradientStop Offset="0.0" Color="#2F000000" />
                
    <GradientStop Offset="1.0" Color="#00000000" />
              
    </LinearGradientBrush.GradientStops>
            
    </LinearGradientBrush>
          
    </Path.OpacityMask>
        
    </Path>

         
          而有关如何实现倒影效果可以参考这篇文章。当然如果使用BLEND来制作倒影效果会更容易,但不知道为

    什么,目前的BLEND还无法实现对子对象的属性设置(因为上面的XAML代码被放在了PATH对象中,而BLEND

    在可视状态下只能看到PATH那一层的对象,而无法设置ImageBrush="leftReflection2Brush"这个对象)。


         有了7个path对象加载图像(使用里面的ImageBrush的ImageSource属性)。还有7个path对象分别对应

    实现7个图像的倒影效果。也就是下图中所显示的:

     



         当然除此以外,还有2组PATH对象分别是:

      lastImgBrush,lastReflectionBrush:用于当点击右侧导航按钮时,设置为当前分页下最右侧图像,以

                                                    避免出现图片为空(空框)的情况。

         firstImgBrush,firstReflectionBrush:用于当点击左侧导航按钮时,设置为当前分页下最左侧图像,以
                       避免出现图片为空(空框)的情况。
                       
         有了这些静态的UI元素之后,我们还需要让其动起来,所以要用到StoryBoard(故事板)。而有关该内容

    介绍可参见如下链接:使用silverlight中的Storyboard实现动画效果


         因为本DEMO中用的是PointAnimation(当动画值的变化[FROM ...TO...]类型是 Point型时使用), 所以这
    里直接就把相应的Xaml代码放在这里了,代码很简单。
         首先是当点击右侧导航按钮时的Storyboard代码:  

    Code
          
          然后是点击左侧导航时的StoryBoard代码:     
         
    Code
          
          

        上面的两块xaml代码分别操作UI元素(注意只有六组,而不是七组,因为整体动态效果用六组PATH对象移动即可实现)。

        注:目前无法在BLEND下对两个StoryBoard的运行效果进行设计测试,也就是之前BLEND截图中箭头所指示的

    "No StoryBoard Open",造成这个问题的原因目前我还不大清楚,有兴趣的朋友不妨也帮助分析一下原因。

        
        到这里,页面上的图象展示元素和StoryBoard就介绍完了,当然还有两个按钮控件(RepeatButton类型)没有介绍,因为
    其功能只是实现按钮事件触发Storyboard运行,而且有关Button按钮控件的类继承关系及设计原理我之前已写过一篇文章作
    了一些介绍,大家参考一下即可。

         好了,xaml内容介绍完了,下面介绍一下CS代码,首先是事件参数声明(详细内容见注释):

    /// <summary>
    /// ImageSelector事件参数
    /// </summary>
    public class ImageSelectedEventArgs : EventArgs
    {
            
    /// <summary>
            
    /// 当前选择的图片源信息
            
    /// </summary>
            public string Source;
            
    /// <summary>
            
    /// 当前选择的图片位图对象
            
    /// </summary>
            public BitmapImage ImageSource;
    }

        
        然后是选择图片时的事件处理句柄(关于使用参见接下来的代码):
        
        /// <summary>
        
    /// ImageSelected事件处理句柄
        
    /// </summary>
        
    /// <param name="sender"></param>
        
    /// <param name="e"></param>
        public delegate void ImageSelectedEventHandler(object sender, ImageSelectedEventArgs e);


         接着是控件的主体类了(详情见注释):

    /// <summary>
    /// ImageSelector控件类
    /// </summary>
    public partial class ImageSelector : UserControl
    {
         
    /// <summary>
         
    /// 声明ImageSelected事件处理句柄的实例
         
    /// </summary>
         public event ImageSelectedEventHandler ImageSelected;

         
    public ImageSelector()
         {
             InitializeComponent();

             
    //图像刷数组初始化,用于绑定指定的BitmapImage信息
             imageBrushArray = new ImageBrush[7];//7为当前页图片数
             imageBrushArray[0= leftImg3Brush;
             imageBrushArray[
    1= leftImg2Brush;
             imageBrushArray[
    2= leftImg1Brush;
             imageBrushArray[
    3= centerImgBrush;
             imageBrushArray[
    4= rightImg1Brush;
             imageBrushArray[
    5= rightImg2Brush;
             imageBrushArray[
    6= rightImg3Brush;

             
    //“倒影效果”图像刷数组初始化,用于绑定指定的BitmapImage信息
             reflectionBrushArray = new ImageBrush[7];//7为当前页图片数
             reflectionBrushArray[0= leftReflection3Brush;
             reflectionBrushArray[
    1= leftReflection2Brush;
             reflectionBrushArray[
    2= leftReflection1Brush;
             reflectionBrushArray[
    3= centerReflectionBrush;
             reflectionBrushArray[
    4= rightReflection1Brush;
             reflectionBrushArray[
    5= rightReflection2Brush;
             reflectionBrushArray[
    6= rightReflection3Brush;

             
    //绑定鼠标点击图片(外侧Path对象)后的事件
             leftImg3.MouseLeftButtonDown += new MouseButtonEventHandler(OnImgClicked);
             leftImg2.MouseLeftButtonDown 
    += new MouseButtonEventHandler(OnImgClicked);
             leftImg1.MouseLeftButtonDown 
    += new MouseButtonEventHandler(OnImgClicked);
             rightImg3.MouseLeftButtonDown 
    += new MouseButtonEventHandler(OnImgClicked);
             rightImg2.MouseLeftButtonDown 
    += new MouseButtonEventHandler(OnImgClicked);
             rightImg1.MouseLeftButtonDown 
    += new MouseButtonEventHandler(OnImgClicked);
             centerImg.MouseLeftButtonDown 
    += new MouseButtonEventHandler(OnImgClicked);
         }

         
    /// <summary>
         
    /// 定义图像点击事件
         
    /// </summary>
         
    /// <param name="sender"></param>
         
    /// <param name="e"></param>
         void OnImgClicked(object sender, MouseButtonEventArgs e)
         {
             ImageSelectedEventArgs args 
    = new ImageSelectedEventArgs();
             
    //设置事件参数
             args.ImageSource = ((Path)sender).Fill.GetValue(ImageBrush.ImageSourceProperty) as BitmapImage;
             
    //调用图片选择事件
             OnImageSelected(args);
         }

         
    /// <summary>
         
    /// 定义图片选择事件
         
    /// </summary>
         
    /// <param name="e"></param>
         protected void OnImageSelected(ImageSelectedEventArgs e)
         {
             
    if (ImageSelected != null)
             {
                 
    //调用绑定的处理事件代码
                 ImageSelected(this, e);
             }
         }

         
    /// <summary>
         
    /// 实始化图像数组并绑定相应的图像Brush
         
    /// </summary>
         
    /// <param name="imageUris">图片路径信息</param>
         public void SetImages(string[] imageUris)
         {
             imageArray 
    = imageUris;
             
    if (imageArray.Length >= 7)
             {
                 
    //设置当前显示的图片数组的左起索引数
                 imageIndex = 0;
                 
    //绑定相应的图像Brush
                 UpdateImages();
             }
         }

        
         
    /// <summary>
         
    /// 定义“flowForward(前进)”对象(Storyboard类型) 的Completed处理事件
         
    /// </summary>
         
    /// <param name="sender"></param>
         
    /// <param name="e"></param>
         void onForwardFlowCompleted(object sender, EventArgs e)
         {  
             
    //当storyboard动画效果完成时置为NULL
             firstImgBrush.ImageSource = null;
             lastImgBrush.ImageSource 
    = null;
             firstReflectionBrush.ImageSource 
    = null;
             lastReflectionBrush.ImageSource 
    = null;
         }

         
    /// <summary>
         
    /// 定义“flowBackward(后退)”对象(Storyboard类型) 的Completed处理事件
         
    /// </summary>
         
    /// <param name="sender"></param>
         
    /// <param name="e"></param>
         void onBackwardFlowCompleted(object sender, EventArgs e)
         {
             
    //当storyboard动画效果完成时置为NULL
             firstImgBrush.ImageSource = null;
             lastImgBrush.ImageSource 
    = null;
             firstReflectionBrush.ImageSource 
    = null;
             lastReflectionBrush.ImageSource 
    = null;
         }

         
    /// <summary>
         
    /// “后退”按钮点击事件
         
    /// </summary>
         
    /// <param name="sender"></param>
         
    /// <param name="e"></param>
         void btnBack_Click(object sender, EventArgs e)
         {
             
    if (imageIndex != -1)
             {
                 
    //更新最左侧图像刷和“倒影”对象,使其在下面storyboard运动过程中逐渐被遮盖

                 firstImgBrush.ImageSource = new BitmapImage(new Uri(imageArray[imageIndex], 

                                                                                           UriKind.RelativeOrAbsolute));

                 firstReflectionBrush.ImageSource = new BitmapImage(new Uri(imageArray[imageIndex], 

                                                                                           UriKind.RelativeOrAbsolute));


                 
    //注:后退方向与我们通常认为的方向相反(通常是imageIndex--),这块不知道是作者的疏忽还是别的原因
                 imageIndex++;
                 
    if (imageIndex == imageArray.Length)
                 {
                     imageIndex 
    = 0;
                 }
                 UpdateImages();
                 
    //运行"后退"storyboard效果
                 flowBackward.Begin();
             }
         }

         
    /// <summary>
         
    /// “前进”按钮点击事件
         
    /// </summary>
         
    /// <param name="sender"></param>
         
    /// <param name="e"></param>
         void btnForward_Click(object sender, EventArgs e)
         {            
             
    if (imageIndex != -1)
             {
                 
    //更新最右侧图像刷和“倒影”对象,使其在下面storyboard运动过程中逐渐被遮盖

                 lastImgBrush.ImageSource = new BitmapImage(new Uri(imageArray[(imageIndex + 6% 

                                                                            imageArray.Length], UriKind.RelativeOrAbsolute));

                 lastReflectionBrush.ImageSource = new BitmapImage(new Uri(imageArray[(imageIndex + 6% 

                                                                            imageArray.Length], UriKind.RelativeOrAbsolute));


                 
    //注:前进方向与我们通常认为方向相反(通常是imageIndex++),这块不知道是作者的疏忽还是别的原因
                 imageIndex--;
                 
    if (imageIndex < 0)
                 {
                     imageIndex 
    = imageArray.Length - 1;
                 }
                 UpdateImages();
                 
    //运行"前进"storyboard效果
                 flowForward.Begin();
             }           
         }

         
    /// <summary>
         
    /// 绑定相应的图像Brush
         
    /// </summary>
         void UpdateImages()
         {
             
    int brushIndex = imageIndex;
             
    for (int i = 0; i < 7; i++)
             {
                 
    //加载图像信息

                 imageBrushArray[i].ImageSource = new BitmapImage(new Uri(imageArray[brushIndex], 

                                                                                                  UriKind.RelativeOrAbsolute));

                 reflectionBrushArray[i].ImageSource = new BitmapImage(new Uri(imageArray[brushIndex], 

                                                                                                  UriKind.RelativeOrAbsolute));

                 brushIndex++;
                 
    //当到达最大长度时,则清零(回到起始位置,实现循环效果)
                 if (brushIndex == imageArray.Length)
                 {
                     brushIndex 
    = 0;
                 }
             }
         }
        

         
    /// <summary>
         
    /// 图像刷数组用于绑定(显示)指定的BitmapImage信息
         
    /// </summary>
         private ImageBrush[] imageBrushArray;
         
    /// <summary>
         
    /// "倒影"效果图像刷数组
         
    /// </summary>
         private ImageBrush[] reflectionBrushArray;
         
    /// <summary>
         
    /// 图片路径信息数组
         
    /// </summary>
         private string[] imageArray;
         
    /// <summary>
         
    /// 当前显示的图片数组的左起索引数
         
    /// </summary>
         private int imageIndex = -1;
    }

         上面的控件类主要是实现了初始化属性成员(图片数组)和相应UI元素事件的绑定(MouseLeftButtonDown),
    然后是相应的事件处理代码(前进,后退按钮事件)。当然在实现上我个人认为还有一些问题(在注释中已说明)。
    但总体上代码布局还是很清爽的。

         下面即是本文开头DEMO页面的xaml代码(源码包中的Page3.xaml):

    Code

         而相应的CS代码如下所示:

    void imageSelector_Loaded(object sender, RoutedEventArgs e)
    {

        
    string baseUri =  Application.Current.Host.Source.AbsoluteUri.Substring(0,
                                                           Application.Current.Host.Source.AbsoluteUri.LastIndexOf(
    "/"));
        
    //初始化设置图片链接数组
        imageSelector.SetImages(new string[]
        {
            String.Concat(baseUri, 
    "/../Images/1.jpg"),
            String.Concat(baseUri, 
    "/../Images/2.jpg"),
            String.Concat(baseUri, 
    "/../Images/3.jpg"),
            String.Concat(baseUri, 
    "/../Images/4.jpg"),
            String.Concat(baseUri, 
    "/../Images/5.jpg"),
            String.Concat(baseUri, 
    "/../Images/6.jpg"),
            String.Concat(baseUri, 
    "/../Images/7.jpg"),
            String.Concat(baseUri, 
    "/../Images/8.jpg")              
        });
    }

    void OnImageSelected(object sender, ImageSelectedEventArgs e)
    {
        
    //当选择某一图片时,放大显示
        snipCanvas.Cursor = Cursors.Hand;
        snipCanvasFadeIn.Begin();
        snipImage.SetValue(Image.SourceProperty, e.ImageSource);
    }

         
    void onExitMouseUp(object sender, MouseButtonEventArgs e)
    { 
        
    //当点击关闭时
        snipCanvasFadeOut.Begin();
    }

      上面代码中的OnImageSelected用于单击某张图片时放大显示,如下图:

     


         好了,今天的内容就先到这里了。

         tag:silverlight,imageselector,imagesnipper

         作者:代震军,daizhj

         原文链接:http://www.cnblogs.com/daizhj/archive/2008/09/10/1288315.html

         源码下载,请点击这里:)
  • 相关阅读:
    SQL Server的数据库镜像实施笔记(3)
    MVC3缓存之三:MVC3中的局部缓存
    MVC3缓存之二:页面缓存中的局部动态
    SQL Server的数据库镜像实施笔记(2)
    ab工具
    数据库灾难备份,和负载均衡 主从数据库配置
    SQL Server的数据库镜像实施笔记 一
    ArcGIS version not specified. You must call RuntimeManager.
    SL命名空间书写
    通过文件tnsnames.ora连接
  • 原文地址:https://www.cnblogs.com/daizhj/p/1288315.html
Copyright © 2011-2022 走看看