zoukankan      html  css  js  c++  java
  • 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设置好布局后效果如下,是不是有点感觉了。

  • 相关阅读:
    二维数组最大子数组算法
    寻找最大子数组
    最大值bug 调试
    多路电梯调度算法
    分析一个文本文件各个词出现的频率,并把频率最高的十个词打印出来。
    使用redis实现生产者消费者模式
    简单使用redis实现sso单点登录
    MongoDB批量导入及简单的性能优化
    mysql安装
    字符串操作性能优化
  • 原文地址:https://www.cnblogs.com/kiminozo/p/2329621.html
Copyright © 2011-2022 走看看