zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    poj 2485 Highways 最小生成树
    hdu 3415 Max Sum of MaxKsubsequence
    poj 3026 Borg Maze
    poj 2823 Sliding Window 单调队列
    poj 1258 AgriNet
    hdu 1045 Fire Net (二分图匹配)
    poj 1789 Truck History MST(最小生成树)
    fafu 1181 割点
    减肥瘦身健康秘方
    人生的问题
  • 原文地址:https://www.cnblogs.com/qq278360339/p/2507911.html
Copyright © 2011-2022 走看看