Blend ---- 自定义ImageButton(图片按钮)

这几天看了一些Blend的使用blog,碰巧有人问我做过ImageButton没,一时兴起就尝试着做了一个。效果如下:

不喜勿喷。  源码下载:https://files.cnblogs.com/qq278360339/ImageButtonPro.zip

 

接下来,我们就开始动手制作这样一个 ImageButton 控件。
第一步:编写自定义控件类
由于我们要制作一个按钮控件,所以我们自定义的这个控件类要继承Button,从而获得了Button已实现的所有功能.
首先创建一个Silverlight for Windows Phone应用程序.添加一个类代码如下:
View Code
 1 using System;
 2 using System.Net;
 3 using System.Windows;
 4 using System.Windows.Controls;
 5 using System.Windows.Documents;
 6 using System.Windows.Ink;
 7 using System.Windows.Input;
 8 using System.Windows.Media;
 9 using System.Windows.Media.Animation;
10 using System.Windows.Shapes;
11 
12 namespace ImageButtonPro
13 {
14     public class ImageButton : Button
15     {
16         public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(ImageButton), null);
17         public ImageSource ImageSource
18         {
19             get { return (ImageSource)GetValue(ImageSourceProperty); }
20             set { SetValue(ImageSourceProperty, value); }
21         }
22 
23         public static readonly DependencyProperty PrevImageSourceProperty = DependencyProperty.Register("PrevImageSource", typeof(ImageSource), typeof(ImageButton), null);
24         public ImageSource PrevImageSource
25         {
26             get { return (ImageSource)GetValue(PrevImageSourceProperty); }
27             set { SetValue(PrevImageSourceProperty, value); }
28         }
29 
30         public static readonly DependencyProperty BackImageSourceProperty = DependencyProperty.Register("BackImageSource", typeof(ImageSource), typeof(ImageButton), null);
31         public ImageSource BackImageSource
32         {
33             get { return (ImageSource)GetValue(BackImageSourceProperty); }
34             set { SetValue(BackImageSourceProperty, value); }
35         }
36     }
37 
38 }

上面的类声明了3个依赖属性,作为我们的按钮的图片资源。

第二步:设计自定义控件的外观和行为

在Visual Studio中先编译下我们的程序,目的是在我们打开Blend后能在找到我们自定义的控件。接下来就是打开Blend,在Blend界面的左上角Assets中找到我们的控件,双击把控件添加到视图区域。

然后选中视图里的ImageButton控件,右键选择 Edit Template| Edit a Copy。

会弹出下面对话框:

选择其中的Apply to all 和 Application,为什么选择这2个前面几篇Blend中有提到,这里不做赘述。点击OK看到如下界面

 接下来我们把图中圈中的ButtonBackground和ContentContainer删除掉。接下来在Button里添加3个Image控件。添加方法,在Assets里选择Image拖到Button里。

下面对3个Image依次做处理,注意顺序是不能改的,因为越是在上面的Image控件,显示的时候越在最底层。

首先,对第一个Image做处理,其命名为ImageBack,Opacity设置为0%(因为它是ImageButton的选中背景),然后点击 Margin 属性右侧的白色方块(Advanced options),然后选择重置(Reset),将所有 Margin 值清零。VerticalAlignment 和 HorizontalAlignment设置为居中,点击 Source属性右侧的浏览按钮,为其指定图片资源ImageButtonBack。加载图片后,如果 Image 控件的大小发生明显的变化,则适当调整预览区下方的 [查看百分比] 来调整视野,但千万不要直接调整 Image 控件本身的 Width 及 Height。整个模板定义的过程中,这两个 Image 控件的 Width 及 Height 都应该显示 Auto (某数字) 。

然后,处理第二个Image,命名为ImagePrev,Opacity设置为100%(因为它是ImageButton的正常状态下背景),点击 Source属性右侧的浏览按钮,为其指定图片资源ImageButtonPrev,其他操作同上。

最后,处理第三个Image,命名为ImageCurrent,Opacity设置为100%(因为它是ImageButton的正常状态下背景),Margin属性全部设置为17,为什么这么设置,是因为它是被背景包裹其中的,要适当的缩进,点击 Source属性右侧的浏览按钮,为其指定图片资源ImageButton,其他操作同上。

设置完效果如下,其中要设置的地方被圈住:

 

在界面左上区域的 States 分页中,选择 CommonStates 下的 Pressed 状态(Visual State)。然后点击 Show Timeline 按钮,显示故事板(StoryBoard)编辑栏。

选中ImageBack,在故事版中,我们建立三个关键帧,时间间隔大约在0.3秒。在前一个关键帧里,设置 ImageBack 控件的透明度(Opacity)为 0%,并且将其大小(Scale)的 X 和 Y 值设置为 1。在第二个关键帧,设置 ImageBack 控件的透明度为 0%,并且将其大小(Scale)的 X 和 Y 值设置为 0.8。在第三个关键帧,设置 ImageBack 控件的透明度为 100%,并且将其大小(Scale)的 X 和 Y 值设置为 1。

选中ImagePrev,在故事版中,我们建立三个关键帧,时间间隔大约在0.3秒。在前一个关键帧里,设置 ImagePrev控件的透明度(Opacity)为 100%,并且将其大小(Scale)的 X 和 Y 值设置为 1。在第二个关键帧,设置 ImagePrev控件的透明度为 0%,并且将其大小(Scale)的 X 和 Y 值设置为 0.8。在第三个关键帧,设置 ImagePrev控件的透明度为 0%,并且将其大小(Scale)的 X 和 Y 值设置为 1。

 

选中ImageCurrent,在故事版中,我们建立三个关键帧,时间间隔大约在0.3秒。在前一个关键帧里,设置 ImageCurrent控件的透明度(Opacity)为 100%,并且将其大小(Scale)的 X 和 Y 值设置为 1。在第二个关键帧,设置 ImageBack 控件的透明度为 100%,并且将其大小(Scale)的 X 和 Y 值设置为 0.8。在第三个关键帧,设置 ImageCurrent控件的透明度为 100%,并且将其大小(Scale)的 X 和 Y 值设置为 1。

 

效果如下,要设置的被圈住:

点击播放按钮就能够预览效果了。

接下来,选择 ImageBack 控件, 点击 Source 属性右侧的白色方块,设置 Template Binding 为 BackImageSource,stretch设置为fill。然后选择 ImagePrev 控件,设置 Template Binding 为 PrevImageSource,stretch设置为fill。最后选择 ImageCurrent 控件,设置 Template Binding 为 ImageSource,stretch设置为fill。这一步操作,是将三个 ImageButton 控件的图片资源绑定到我们在一开始声明的 BackImageSource、PrevImageSource和ImageSource 属性上,从而实现在实际使用 ImageButton 控件的地方,根据需求来指定不同的图标。由于模板内的 Image 控件不再是“硬编码”到某一特定的图片上,而是通过绑定来显示实际 ImageSource 属性所提供的值,因此我们就能够实现一个可以重复使用的按钮控件。

保存工作成果,然后点击界面上方的导航条,回到使用 ImageButton 控件的 page 编辑页面。

在该页面中,选择 ImageButton 控件,在属性栏中,找到 BackImageSource、PrevImageSource和ImageSource 属性,为其指定任意一个图片资源。指定完成后,可以在预览区看到图片加载后的效果

调整 ImageButton 控件的大小及位置,然后运行程序,在模拟器中查看效果。当点击该按钮时,会呈现如下效果。

最后的样式代码:

View Code
 1 <Style TargetType="local:ImageButton">
 2             <Setter Property="Background" Value="Transparent"/>
 3             <Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>
 4             <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
 5             <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
 6             <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
 7             <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
 8             <Setter Property="Padding" Value="10,3,10,5"/>
 9             <Setter Property="Template">
10                 <Setter.Value>
11                     <ControlTemplate TargetType="local:ImageButton">
12                         <Grid Background="Transparent">
13                             <VisualStateManager.VisualStateGroups>
14                                 <VisualStateGroup x:Name="CommonStates">
15                                     <VisualState x:Name="Normal"/>
16                                     <VisualState x:Name="MouseOver"/>
17                                     <VisualState x:Name="Pressed">
18                                         <Storyboard>
19                                             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="ImageCurrent">
20                                                 <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
21                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0.8"/>
22                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="1"/>
23                                             </DoubleAnimationUsingKeyFrames>
24                                             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="ImagePrev">
25                                                 <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
26                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0.8"/>
27                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="1"/>
28                                             </DoubleAnimationUsingKeyFrames>
29                                             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="ImageBack">
30                                                 <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
31                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0.8"/>
32                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="1"/>
33                                             </DoubleAnimationUsingKeyFrames>
34                                             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="ImageBack">
35                                                 <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
36                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0.8"/>
37                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="1"/>
38                                             </DoubleAnimationUsingKeyFrames>
39                                             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="ImagePrev">
40                                                 <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
41                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0.8"/>
42                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="1"/>
43                                             </DoubleAnimationUsingKeyFrames>
44                                             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ImagePrev">
45                                                 <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
46                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
47                                             </DoubleAnimationUsingKeyFrames>
48                                             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="ImageCurrent">
49                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0.8"/>
50                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="1"/>
51                                             </DoubleAnimationUsingKeyFrames>
52                                             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ImageBack">
53                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
54                                                 <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="1"/>
55                                             </DoubleAnimationUsingKeyFrames>
56                                         </Storyboard>
57                                     </VisualState>
58                                     <VisualState x:Name="Disabled"/>
59                                 </VisualStateGroup>
60                             </VisualStateManager.VisualStateGroups>
61                             <Image x:Name="ImageBack" VerticalAlignment="Center" Opacity="0" Source="{TemplateBinding BackImageSource}" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Center">
62                                 <Image.RenderTransform>
63                                     <CompositeTransform/>
64                                 </Image.RenderTransform>
65                             </Image>
66                             <Image x:Name="ImagePrev" HorizontalAlignment="Center" Source="{TemplateBinding PrevImageSource}" RenderTransformOrigin="0.5,0.5" VerticalAlignment="Center">
67                                 <Image.RenderTransform>
68                                     <CompositeTransform/>
69                                 </Image.RenderTransform>
70                             </Image>
71                             <Image x:Name="ImageCurrent" HorizontalAlignment="Center" Margin="17" VerticalAlignment="Center" Source="{TemplateBinding ImageSource}" RenderTransformOrigin="0.5,0.5">
72                                 <Image.RenderTransform>
73                                     <CompositeTransform/>
74                                 </Image.RenderTransform>
75                             </Image>
76                         </Grid>
77                     </ControlTemplate>
78                 </Setter.Value>
79             </Setter>
80         </Style>

 

源码下载:https://files.cnblogs.com/qq278360339/ImageButtonPro.zip

 

 

本文参考:虫虫 的blog

posted @ 2012-05-18 15:51  ╰→劉じ尛鶴  阅读(1876)  评论(0编辑  收藏  举报