• WP7应用开发笔记(11) 自定义按钮


    不知不觉写了很多东西,不过结构有点乱了,写完了需要整理一下。回顾一下界面设计,这草图又要出来献丑了。

    除了已经实现的圆形触控控件以外,其他按钮都是圆环+图片的方式,有比较有写一个自定义控件,取个名字叫RoundButton。

    RoundButton类

    RoundButton具有和Button相同的行为和视觉状态,唯一区别是RoundButton拥有图标

    那么继承Button并添加依赖属性ImageSource类型为ImageSource。

    再添加一个ImageBrush用于绘制图片。

    代码如下:

        public class RoundButton : Button
    {
    protected ImageBrush OpacityImageBrush;
    private const string OpacityImageBrushName = "OpacityImageBrush";

    public RoundButton()
    {
    DefaultStyleKey = typeof(RoundButton);
    }

    public readonly DependencyProperty ImageSourceProperty
    = DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(RoundButton), new PropertyMetadata(OnImageSourceChanged));

    private static void OnImageSourceChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
    var sender = o as RoundButton;

    if (sender == null || e.NewValue == e.OldValue)
    return;

    sender.SetImageBrush(e.NewValue as ImageSource);
    }

    public ImageSource ImageSource
    {
    get { return (ImageSource)GetValue(ImageSourceProperty); }
    set { SetValue(ImageSourceProperty, value); }
    }

    public override void OnApplyTemplate()
    {
    base.OnApplyTemplate();
    OpacityImageBrush = GetTemplateChild(OpacityImageBrushName) as ImageBrush;

    if (ImageSource == null)
    ImageSource = new BitmapImage(new Uri("/VirtualKeyboard.Controls;component/Icons/word.ok.png", UriKind.RelativeOrAbsolute));
    else
    SetImageBrush(ImageSource);
    }

    private void SetImageBrush(ImageSource imageSource)
    {
    if (OpacityImageBrush == null)
    return;

    OpacityImageBrush.ImageSource = imageSource;
    }
    }

    RoundButton模板

    编写好RoundButton类后还需要编写其模板已呈现出圆形按钮的效果

    基本模板由两个重叠的圆Ellipse构成:

    <StackPanel>
    <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Margin="3">
    <Ellipse
    x:Name="ButtonBackground"
    Stroke
    ="{TemplateBinding BorderBrush}"
    StrokeThickness
    ="{StaticResource PhoneStrokeThickness}"
    Fill
    ="{TemplateBinding Background}"
    Margin
    ="{StaticResource PhoneTouchTargetOverhang}" />
    <Ellipse
    x:Name="ButtonForeground"
    Fill
    ="{TemplateBinding Foreground}"
    Margin
    ="{StaticResource PhoneTouchTargetOverhang}">
    <Ellipse.OpacityMask>
    <ImageBrush x:Name="OpacityImageBrush" />
    </Ellipse.OpacityMask>
    </Ellipse>
    </Grid>
    </StackPanel>

    呈现如下:

    为了对输入响应我需要按下的视觉状态VisualState Pressed 通过VisualStateGroups添加相应的动画板Storyboard实现

    <VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="CommonStates">
    <VisualState x:Name="Normal" />
    <VisualState x:Name="MouseOver"/>
    <VisualState x:Name="Pressed">
    <Storyboard>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="ButtonBackground">
    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneContrastBackgroundBrush}"/>
    </ObjectAnimationUsingKeyFrames>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="ButtonBackground">
    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneContrastBackgroundBrush}"/>
    </ObjectAnimationUsingKeyFrames>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="ButtonForeground">
    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneBackgroundBrush}"/>
    </ObjectAnimationUsingKeyFrames>
    </Storyboard>
    </VisualState>

    呈现效果:

    完整XAML代码

    View Code
    <Style TargetType="local:RoundButton">
    <Setter Property="BorderBrush" Value="{StaticResource PhoneContrastBackgroundBrush}"/>
    <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
    <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
    <Setter Property="FontSize" Value="12" />
    <Setter Property="Padding" Value="10,3,10,5"/>
    <Setter Property="VerticalAlignment" Value="Top"/>
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="local:RoundButton">
    <Grid>
    <VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="CommonStates">
    <VisualState x:Name="Normal" />
    <VisualState x:Name="MouseOver"/>
    <VisualState x:Name="Pressed">
    <Storyboard>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="ButtonBackground">
    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneContrastBackgroundBrush}"/>
    </ObjectAnimationUsingKeyFrames>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="ButtonBackground">
    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneContrastBackgroundBrush}"/>
    </ObjectAnimationUsingKeyFrames>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="ButtonForeground">
    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneBackgroundBrush}"/>
    </ObjectAnimationUsingKeyFrames>
    </Storyboard>
    </VisualState>
    <VisualState x:Name="Disabled" />
    </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <StackPanel>
    <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Margin="3">
    <Ellipse
    x:Name="ButtonBackground"
    Stroke
    ="{TemplateBinding BorderBrush}"
    StrokeThickness
    ="{StaticResource PhoneStrokeThickness}"
    Fill
    ="{TemplateBinding Background}"
    Margin
    ="{StaticResource PhoneTouchTargetOverhang}" />
    <Ellipse
    x:Name="ButtonForeground"
    Fill
    ="{TemplateBinding Foreground}"
    Margin
    ="{StaticResource PhoneTouchTargetOverhang}">
    <Ellipse.OpacityMask>
    <ImageBrush x:Name="OpacityImageBrush" />
    </Ellipse.OpacityMask>
    </Ellipse>
    </Grid>
    </StackPanel>
    </Grid>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>


    完成播放器界面布局

    有了按钮,我还PS了一套图标,将RoundButton设置好布局后效果如下,是不是有点感觉了。

  • 相关阅读:
    【一个蒟蒻的挣扎】单源最短路(Dijkstra)
    【字符串大模拟】潜伏者—— NOIP2009原题
    【一个蒟蒻的挣扎】最长上升子序列
    【球的序列】——最长上升子序列
    【洛谷P1886】滑动窗口——单调队列
    【实时更新】你永远都不会想到上了考场会犯什么样的**错误——汇总
    【洛谷P1816】忠诚——ST表做法
    【一道来自老师的题的题解】equip——奇妙的最短路
    【洛谷P1119题解】灾后重建——(floyd)
    济南集训总结
  • 原文地址:https://www.cnblogs.com/kiminozo/p/2329621.html
Copyright © 2020-2023  润新知