这几天看了一些Blend的使用blog,碰巧有人问我做过ImageButton没,一时兴起就尝试着做了一个。效果如下:
不喜勿喷。 源码下载:https://files.cnblogs.com/qq278360339/ImageButtonPro.zip
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 控件的大小及位置,然后运行程序,在模拟器中查看效果。当点击该按钮时,会呈现如下效果。
最后的样式代码:
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