SnipperImages(Silverlight DEMO)控件设计之--ImageSelector

SnipperImages(Silverlight DEMO)控件设计之--ImageSelector,第1张

概述     在SnipperImages中为了进行图片列表导航(前后方向)设计了ImageSelector控件,而这个控件不同于 之前介绍过的Button, CheckBox, Slider,主要是其xaml中的UI元素变得数量庞大且行为更加复杂。所以通过 了解这个控件,我们能够更好的熟悉StoryBoard,Path,ImageBrush,ScaleTransform,TranslateTrans      在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  ="pathfigure_leftimg3"  IsClosed ="True"  StartPoint ="130,15"
        
linesegment  ="line1_leftimg3"  Point ="250,25" /> ="line2_leftimg3" ="line3_leftimg3" </ Pathfigure Path.Fill ImageBrush  ="leftimg3Brush"  Stretch ="Fill"
Path >

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

  ="left3Reflection" ="White"
          
="pathfigure_left3Reflection"
            
="line1_left3Reflection" ="line2_left3Reflection" ="line3_left3Reflection" ="leftReflection3Brush" ImageBrush.relativetransform transformGroup
              
<!-- 实现投影效果 --> Scaletransform  ScaleX ="1"  ScaleY ="-1"   Translatetransform  Y ImageBrush Path.OpacityMask linearGradIEntBrush  StartPoint ="0.5,0"  EndPoint linearGradIEntBrush.GradIEntStops GradIEntStop  Offset ="0.0"  color ="#2F000000" ="1.0" ="#00000000" linearGradIEntBrush >
     
      而有关如何实现倒影效果可以参考 这篇文章。当然如果使用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 x:name='flowForward' Completed='onForwardFlowCompleted'>
        
PointAnimation Storyboard.Targetname='pathfigure_centerimg' Storyboard.TargetProperty='StartPoint' From='250,15' To='330,5' Duration='0:0:0.5'/>='line1_centerimg'='Point'='370,25'='470,255);">='line2_centerimg'='line3_centerimg'

        
='pathfigure_centerReflection'='line1_centerReflection'='line2_centerReflection'='490,195'='line3_centerReflection'='310,255);">='pathfigure_rightimg1'='430,255);">='line1_rightimg1'='550,255);">='line2_rightimg1'='line3_rightimg1'='pathfigure_right1Reflection'='line1_right1Reflection'='line2_right1Reflection'='line3_right1Reflection'='pathfigure_rightimg2'='500,255);">='line1_rightimg2'='620,255);">='line2_rightimg2'='line3_rightimg2'='pathfigure_right2Reflection'='line1_right2Reflection'='line2_right2Reflection'='line3_right2Reflection'='pathfigure_rightimg3'='line1_rightimg3'='670,255);">='line2_rightimg3'='line3_rightimg3'='pathfigure_right3Reflection'='line1_right3Reflection'='line2_right3Reflection'='line3_right3Reflection'='pathfigure_leftimg1'='180,255);">='line1_leftimg1'='300,255);">='line2_leftimg1'='line3_leftimg1'='pathfigure_left1Reflection'='line1_left1Reflection'='line2_left1Reflection'='line3_left1Reflection'='pathfigure_leftimg2'='130,255);">='line1_leftimg2'='line2_leftimg2'='line3_leftimg2'='pathfigure_left2Reflection'='line1_left2Reflection'='line2_left2Reflection'='line3_left2Reflection'
</Storyboard>
      
      然后是点击左侧导航时的StoryBoard代码:     
     

Code
='flowBackward'='onBackwardFlowCompleted'='pathfigure_leftimg3'='line1_leftimg3'='line2_leftimg3'='line3_leftimg3'='pathfigure_left3Reflection'='line1_left3Reflection'='line2_left3Reflection'='line3_left3Reflection'>
      
      
    上面的两块xaml代码分别 *** 作UI元素(注意只有六组,而不是七组,因为整体动态效果用六组PATH对象移动即可实现)。       注:目前无法在BLEND下对两个StoryBoard的运行效果进行设计测试,也就是之前BLEND截图中箭头所指示的 "No StoryBoard Open",造成这个问题的原因目前我还不大清楚,有兴趣的朋友不妨也帮助分析一下原因。
    
    到这里,页面上的图象展示元素和StoryBoard就介绍完了,当然还有两个按钮控件(Repeatbutton类型)没有介绍,因为
其功能只是实现按钮事件触发Storyboard运行,而且有关button按钮控件的类继承关系及设计原理我之前已写过一篇文章作
了一些介绍,大家参考一下即可。

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

///   <summary>
 ImageSelector事件参数
</summary>
public class  ImageSelectedEventArgs : EventArgs
{
        

        
 当前选择的图片源信息
        
         string  Source;
        
 当前选择的图片位图对象
        
 BitmAPImage ImageSource;
}

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

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

 ImageSelector控件类
partial  ImageSelector : UserControl
{
     

     
 声明ImageSelected事件处理句柄的实例
     
      event  ImageSelectedEventHandler ImageSelected;

     
 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           reflectionBrushArray[  leftReflection3Brush;
         reflectionBrushArray[
 leftReflection2Brush;
         reflectionBrushArray[
 leftReflection1Brush;
         reflectionBrushArray[
 centerReflectionBrush;
         reflectionBrushArray[
 rightReflection1Brush;
         reflectionBrushArray[
 rightReflection2Brush;
         reflectionBrushArray[
 rightReflection3Brush;

         
绑定鼠标点击图片(外侧Path对象)后的事件          leftimg3.MouseleftbuttonDown  +=  MousebuttonEventHandler(OnimgClicked);
         leftimg2.MouseleftbuttonDown 
 MousebuttonEventHandler(OnimgClicked);
         leftimg1.MouseleftbuttonDown 
 MousebuttonEventHandler(OnimgClicked);
         rightimg3.MouseleftbuttonDown 
 MousebuttonEventHandler(OnimgClicked);
         rightimg2.MouseleftbuttonDown 
 MousebuttonEventHandler(OnimgClicked);
         rightimg1.MouseleftbuttonDown 
 MousebuttonEventHandler(OnimgClicked);
         centerimg.MouseleftbuttonDown 
 MousebuttonEventHandler(OnimgClicked);
     }

     
 定义图像点击事件
     
 OnimgClicked(  ImageSelectedEventArgs();
         
设置事件参数          args.ImageSource   ((Path)sender).Fill.GetValue(ImageBrush.ImageSourceProperty)  as  BitmAPImage;
         
调用图片选择事件          OnImageSelected(args);
     }

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

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

    
     
 定义“flowForward(前进)”对象(Storyboard类型) 的Completed处理事件
     
 onForwardFlowCompleted( 当storyboard动画效果完成时置为NulL          firstimgBrush.ImageSource  ;
         lastimgBrush.ImageSource 
;
         firstReflectionBrush.ImageSource 
;
         lastReflectionBrush.ImageSource 
;
     }

     
 定义“flowBackward(后退)”对象(Storyboard类型) 的Completed处理事件
     
 onBackwardFlowCompleted(  “后退”按钮点击事件
     
 btnBack_Click(  (imageIndex  - 更新最左侧图像刷和“倒影”对象,使其在下面storyboard运动过程中逐渐被遮盖
             firstimgBrush.ImageSource  =   new  BitmAPImage(  Uri(imageArray[imageIndex],                                                                                         UriKind.relativeOrabsolute));                  firstReflectionBrush.ImageSource  UriKind.relativeOrabsolute));

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

     
 “前进”按钮点击事件
     
 btnForward_Click( 更新最右侧图像刷和“倒影”对象,使其在下面storyboard运动过程中逐渐被遮盖              lastimgBrush.ImageSource   Uri(imageArray[(imageIndex  +   6 %                                                                           imageArray.Length], UriKind.relativeOrabsolute));                  lastReflectionBrush.ImageSource  注:前进方向与我们通常认为方向相反(通常是imageIndex++),这块不知道是作者的疏忽还是别的原因 -- < )
             {
                 imageIndex 
 imageArray.Length  - 运行"前进"storyboard效果              flowForward.Begin();
         }           
     }

     
 绑定相应的图像Brush
     
 UpdateImages()
     {
         
int  brushIndex   imageIndex;
         
for  (  i  ; i  ; i 加载图像信息              imageBrushArray[i].ImageSource   Uri(imageArray[brushIndex],                                                                                                             reflectionBrushArray[i].ImageSource  UriKind.relativeOrabsolute));                  brushIndex 当到达最大长度时,则清零(回到起始位置,实现循环效果)                (brushIndex   imageArray.Length)
             {
                 brushIndex 
;
             }
         }
     }
    

     
 图像刷数组用于绑定(显示)指定的BitmAPImage信息
     
private  ImageBrush[] imageBrushArray;
     
 "倒影"效果图像刷数组
     
 ImageBrush[] reflectionBrushArray;
     
 图片路径信息数组
     
[] imageArray;
     
 当前显示的图片数组的左起索引数
     
 imageIndex  ;
}

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

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

Code
   <!--控件声明-->
 
ctl:ImageSelector ='imageSelector' ImageSelected='OnImageSelected' Canvas.top='400' Loaded='imageSelector_Loaded'当用户点某一图片时显示元素InkPresenter ="snipCanvas" Background="#80F5F5DC" Opacity="0" Canvas.left="100"="70" WIDth="600" Height="430" Cursor="Hand"
            
InkPresenter.Resources
                
="snipCanvasFadeIn"
                    
DoubleAnimation ="Opacity"="0.0"="1.0"="snipCanvasScale"="ScaleX"="ScaleY"="snipCanvasFadeOut"InkPresenter.RendertransformScaletransform  ScaleX ScaleY CenterX="300" CenterY="215"

            
Canvas Canvas.left="577"="3"="20"="Crimson" MouseleftbuttonUp="onExitMouseUp"line X1="4" Y1 X2="16" Y2 stroke="White" strokeThickness CanvasImage ="snipImage"="10"="40"
                       WIDth
="580"="380" Stretch="Uniform"
             
        
InkPresenter>

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

 imageSelector_Loaded(  baseUri    Application.Current.Host.source.absoluteUri.Substring( " / " ));
    
初始化设置图片链接数组     imageSelector.Setimages( []
    {
        String.Concat(baseUri, 
/../Images/1.jpg ),
        String.Concat(baseUri,0);">/../Images/2.jpg
/../Images/3.jpg /../Images/4.jpg /../Images/5.jpg /../Images/6.jpg /../Images/7.jpg /../Images/8.jpg )              
    });
}

 OnImageSelected( 当选择某一图片时,放大显示     snipCanvas.Cursor   Cursors.Hand;
    snipCanvasFadeIn.Begin();
    snipImage.SetValue(Image.sourceProperty, e.ImageSource);
}

     
 onExitMouseUp( 当点击关闭时     snipCanvasFadeOut.Begin();
}

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

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

     tag:silverlight,imageselector,imagesnipper

     作者:代震军,daizhj

     原文链接:[url]http://www.cnblogs.com/daizhj/archive/2008/09/10/1288315.HTML[/url]

     源码下载,请 点击这里:) 总结

以上是内存溢出为你收集整理的SnipperImages(Silverlight DEMO)控件设计之--ImageSelector全部内容,希望文章能够帮你解决SnipperImages(Silverlight DEMO)控件设计之--ImageSelector所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1054331.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存