65.9K
CodeProject 正在变化。 阅读更多。
Home

Expression Blend & Silverlight 中 10 个超酷的下载按钮

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (146投票s)

2010 年 4 月 7 日

CPOL

29分钟阅读

viewsIcon

178088

downloadIcon

5133

WC 门按钮,涵盖了我第一个教程中创建按钮所需的所有技能。以及所有 10 个可下载按钮!

引言

欢迎来到我的第四个Expression BlendSilverlight入门教程。

我请求您的投票,因为我似乎是CodeProject上唯一的纯图形Silverlight样式人员。

所以您决定我是否应该留在这里!

10FreeButtons/img21.jpg

本教程旨在完成构建我先前展示的所有按钮所需的全部技能。可能也是我关于构建按钮主题的最后一篇。虽然我还有其他例子,但这些例子作为静态图像效果不佳,所以没有包含在内。但这些值得专门做一个教程,所以不保证这是最后一个按钮和矢量图形教程。Expression Blend还有更多有趣的内容,还有更复杂、更有趣的控件等待您去探索和掌握,例如ComboBoxListBox

也许我会根据收到的请求来添加和扩展本教程,但仅限于按钮的范围!

在我的前两个教程中,我最初认为我已经涵盖了创建所有展示按钮所需的一切。除了可能在WC门按钮中使用的路径路径操作圆角半径。因此,起初我不太愿意再做任何按钮构建教程,并且害怕只是重复自己。事实证明并非如此,所以请继续阅读!

概述

在开始本教程之前,我建议您阅读我之前的Code Project教程。
我正在将它们写成一个系列,因此本教程将假定您具有先前的知识。

马桶(WC)门按钮(卫生间按钮)

第一部分 - 制作底板

创建一个名为WCDoorButton的新项目,或类似名称。

(或者加载您在上一个教程/课程中保存的BlankButtonTemplate)。

无论哪种方式,都像我在之前的教程中展示的那样,设置六个按钮。

(确保重命名或复制您的“BlankButtonTemplate”项目,以进行保存)。

选择其中一个按钮,右键单击并选择编辑模板 > 编辑副本

将此新Style命名为“WCDoorButton”,并将此Style应用于另外个按钮。

(使用返回范围以退出控件模板。)

如果您加载了BlankButtonTemplate项目,则已将ArcadeButton Style应用于所有按钮。

您可以将其重命名为WCDoorButton,而不是创建全新的Style

您可以在资源选项卡中执行此操作,以及删除任何不需要的Style

因此,一切设置妥当,让我们开始一个空白按钮模板,除了ContentPresenter

选中Grid元素,拖出一个Rectangle以填充模板

确保它设置为拉伸,并且边距重置

(或者双击工具栏中的Rectangle Tool,插入一个具有这些默认设置的矩形。)

Rectangle重命名为“BaseBGround”,右键单击并选择组合为 > Grid,然后将Grid重命名为“Base”。

选择BaseBGround元素并复制两次。

将它们重命名为“BaseFace”和“BaseTexture”。

10FreeButtons/img6.jpg

这三个元素就是我们设置Base(门锁的背面)所需的一切。

现在转到Style并将背景颜色设置为深蓝色。

(默认值:#FF1F3B53 (Hex Value) 即可 - 直接复制粘贴Blend中)。

回到模板中,将BaseBGround元素的填充设置为模板绑定 > 背景

删除描边,然后通过单击旁边眼睛图标隐藏BaseTexture元素。

接下来,选择BaseFace元素,删除描边,并将不透明度设置为20%

现在,将ScaleTransform应用于BaseFace元素,X和Y轴均为0.95

此元素的目的就是模拟底座的平面。

并且通过显示边缘周围的元素来模拟底座的锥形边缘。

10FreeButtons/img7.jpg

(边缘只有几像素宽,所以不值得应用任何渐变效果来突出它)。

我们希望此边缘细节适合所有按钮尺寸,这在我们之前讨论过。

因此,我们可以通过以下方式控制边缘:MarginsScaleTransformGrid分隔符。

我们还希望底座具有圆角,所以我们先来看看这一点。

选择BaseBGround元素,在属性选项卡的外观部分,将XY半径设置为6

10FreeButtons/imgB.jpg

显然,这将为所有按钮尺寸应用6像素的圆角Radius

这可能适合中等尺寸按钮的Radius大小,但对于最大或最小按钮则不适合。

10FreeButtons/img9.jpg

再次,我们有一个属性:不缩放

那么这次我们如何解决这个问题呢?

如果您正在编辑最大按钮的控件模板,请将BaseBGround的圆角Radius设置为X和Y均为10像素。

(如果您正在编辑较小按钮的控件模板,请使用较低的像素值。)

现在右键单击BaseBGround元素,选择Path > 转换为Path

10FreeButtons/9a.jpg

(密切关注Artboard和较小的按钮,看看角落如何变化。)

所有按钮现在都具有比例的圆角Radius

因为它们复制了我们正在编辑的控件模板的相对比例。

现在选择BaseFace元素,将所有边距设置为1,以帮助最小按钮的边缘间距。

接下来,选择BaseFace元素,将X和Y的圆角Radius设置为8像素。

(由于ScaleTransformMargins,我们需要比用于BaseBGround元素的值更低。)

像对待BaseBGround元素一样,将BaseFace元素转换为Path

现在为了微调,将BaseFace元素的ScaleTransform更改为X和Y轴均为0.97

我现在对所有按钮尺寸的设置都满意了,如下图所示。

10FreeButtons/imgD.jpg

(如果您愿意,可以随意调整您的设置。)

现在选择BaseTexture元素,取消隐藏它,并删除Stroke

应用与BaseBGround元素相同的圆角Radius,然后将其转换为Path

BaseTexture元素的Fill设置为Linear Gradient,并使用Gradient Tool将其设置为对角线方向。

10FreeButtons/imgF.jpg

我喜欢将StartPoint设置为0,0,将EndPoint设置为1,1,以确保我正好在45%

10FreeButtons/img10.jpg

(可能对于准确性和强迫症来说有点过头了,但它让我很开心!)。

将两个Gradient Stops都设置为白色,并添加另外5个Gradient Stops

将第一个Gradient Stop保持在100% Alpha,将第二个设置为0% Alpha,并沿着Ribbon重复。

10FreeButtons/img11.jpg

如上图所示调整Gradient Stops后,您的Base应该看起来如下图所示。

10FreeButtons/img37.jpg

(不要过度调整Gradient Stops,因为大部分Base将被隐藏。)

BaseTexture元素的Opacity设置为40%,这样Base就完成了!

您从以上步骤中学到的,除了圆角Radius缩放之外。

Rectangle Tool/Control“基本上”是一个继承的Control,基于描述矩形的Path
但它有额外的功能,例如调整圆角Radius的功能。

Border Tool/Control类似,但具有单独编辑单个圆角Radius的功能,以及单独的Edge/Stroke厚度)。

第二部分 - 固定底板

现在让我们制作并定位底座每个角落的螺钉

我们可以通过多种方式创建螺钉头,有些会缩放,有些则不会!

我们是否希望螺钉头细节成比例并缩放,还是在较小的按钮中更突出?

我问的原因是,创建螺钉头外边缘的最简单方法……

是设置一个Ellipse描边1像素,但这不会为所有按钮尺寸缩放

在某些情况下这可能足够了,但在这里不行。(对我来说不行!)

所以,我们真正想要的是成比例地缩放,同时在较小的按钮中强调边缘。

我们能做到吗?让我们试试看!

选择Grid元素(Base Grid元素的父级)并插入一个新的Grid

将此Grid重命名为“Screw1”,确保其设置为Stretch,并将Margins设置为0

现在选择Screw1元素,选择Group Into > Grid,将此Grid重命名为“ScrewLayout”。

10FreeButtons/img3.jpg

选中ScrewLayout,设置Grid分隔符,如下图所示。

10FreeButtons/img4.jpg

(我为ColumnRow定义设置的Grid分隔符是0.2*0.6*0.2*。)

这是分隔符的XAML,如下图所示。

10FreeButtons/img5.jpg

现在选择Screw1元素,并在Screw1元素中插入一个新的Ellipse以填充它。(Stretch0 Margins)。

将此元素重命名为Screw1BGround,删除Stroke,并将Fill模板绑定StyleBackground

希望在Artboard中,您会看到一个EllipseCircle)填充了底座,如下图所示。

10FreeButtons/img8.jpg

现在选择Screw1元素,使用Selection Tool,将其大小调整为仅填充父级Grid的左上角部分。

现在重置子元素(Screw1BGround)的Margins,以适合其父级的边界。

Artboard看起来应该如下图所示。

10FreeButtons/img13.jpg

现在设置Screw1元素的ScaleTransform,X和Y轴均为0.6

接下来,在Screw1元素中插入另一个Ellipse,并将其重命名为“Screw1Texture”。

Screw1TextureFill设置为Radial Gradient,在Ribbon9091处带有白色Gradient Stops

将第一个Gradient StopAlpha值保持为100%,将第二个设置为0%

Screw1Texture元素的Opacity设置为40%Artboard应该看起来如下图所示。

10FreeButtons/img14.jpg

现在我们有了可以与按钮尺寸缩放螺钉边缘,以及柔化边缘细节的能力。

所以选择Screw1Texture元素,并将Ribbon91处的Gradient StopAlpha值更改为30%

(看看螺钉边缘的对比度是如何降低的。)

这对于最大的按钮效果很好,但在最小的按钮中却丢失了,变得模糊。

因为我们基本上处理的是像素的几分之一。(可能吗?)

那么我们如何为最小的按钮增强这一点呢?

(因为将Screw1TextureMargin设置为1,太多了。)

(如果我们能指定像素的分数就好了 - 哦,我忘了,我们可以!!!)

Margins不一定是整数值,我们也可以指定分数!

(在Layout Rounding的范围内,基本上是:如何处理像素的分数)。

这可能导致偏离中心的定位(因为BlendSilverlight会尽力渲染它)。

但这仍然对我们有用,并且为螺钉头增加了一点随机性,我喜欢。(为什么它必须是完美的?)

所以将Screw1TextureMargins设置为所有边距为0.2

现在将Screw1Texture的元素Opacity设置为60%,使螺钉头更突出一些。

如果运气好的话,当您运行应用程序(F5)时,螺钉头在每个按钮尺寸中应该大致可见。

10FreeButtons/img15.jpg

现在让我们将螺钉头“微调”到按钮中心。

(但在较小的按钮中比在最大的按钮中进行更多操作,但使用Margins)。

选择Screw1元素,并将TopLeftMargin设置为1

10FreeButtons/imgA.jpg

运行您的应用程序并查看结果。

10FreeButtons/imgB1.jpg

(您可能更喜欢我的螺钉头比我的大)。
(但我将保持我的原样,或者至少在我创建了按钮的中心部分之前)。

现在让我们在螺钉上制作一个,我们可以用一个带有2个点的Path来完成。

然后设置描边粗细,但这也不会缩放……

(当与ScaleTransform结合使用时,它有点缩放,但不够优雅,所以这里不讨论。)

所以选择Screw1元素,并插入一个新的Rectangle。(设置为Stretch0 Margins)。

将此Rectangle重命名为“Screw1Slot”,删除Stroke,并将Fill设置为Template Binding > Background

现在设置X轴的ScaleTransform0.1,并将元素Opacity更改为70%

搞定!但为什么我没有在Screw1Texture元素上设置Linear Opacity Mask来形成Slot呢?

Opacity Mask的问题是,我们通常在Blend环境中看不到结果。)

但在我们摆弄Slot角度之前,让我们生成其他3个螺钉

选择Screw1元素,使用CopyPaste复制它。

使用Selection Tool,将其拖到父级Grid右上角

TopRight边的Margins设置为1

为其他2个螺钉重复这些步骤,并记住相应地设置Margins

现在像下图所示那样重命名所有复制的元素。

10FreeButtons/imgC.jpg

(尽量确保良好的整理和逻辑命名。)

选择Screw1元素,并在Transform部分,设置35度的Rotation

10FreeButtons/imgF1.jpg

现在为剩下的3个螺钉设置合适的角度。

10FreeButtons/img16.jpg

(我使用了-60-4020度)。

这样螺钉就完成了,除了回顾我们学到的东西。

我们可以指定像素的分数。

我们可以使用Margins来“微调”事物,从而定制适合不同按钮尺寸的元素。

第三部分 - 形成锁面(糕点切割)

为了形成门锁的锁面盖板),我们需要考虑锁面顶部和底部的切口。

我喜欢称之为糕点切割,即我们制作一个糕点切割器,然后用它来切割一块糕点

糕点只是一个CircleEllipse),但切割器更复杂,如果我们要做下面的Path形状。

10FreeButtons/img12.jpg

(这通常是这样,因为我通常花在制作切割器上的时间比制作糕点的时间多。)

有许多方法可以组合和切割糕点,并且有许多在线教程涵盖了所有主要的Vector Packages

所以我不会涵盖如何做,而是下载我在 Expression Design 中创建的 PastryCutter.zip

使用Project菜单中的Add Existing Item,将“PastryCutter”文件添加到项目中。

现在选择名为Grid的根元素,并通过双击左侧工具栏中的Grid工具插入一个新的Grid

Margins应设置为0Alignments设置为Stretch。)

将此新Grid重命名为LockFace

现在转到Projects选项卡,双击PastryCutter.xaml以打开它。

Objects and Timeline中,选择Path元素并将其复制到剪贴板。

现在返回MainPage.xaml(通过单击Artboard顶部)。

选择LockFace元素,并粘贴Pastry Cutter Path”。

(您现在可以删除Projects选项卡中的PastryCutter.xaml)。

选择新粘贴的Path元素,将Margins重置0

在我们ScalePath以获得正确比例之前,让我们添加一个参考对象(The Pastry)。

选择LockFace元素,然后双击Ellipse工具以插入一个新的Ellipse

(确保Margins0Alignments设置为Stretch。)

选择Ellipse,并通过在Objects and Timeline中将其拖到Path后面来将其放置在Path后面。

10FreeButtons/img17.jpg

EllipseFill设置为白色,并确保Stroke已删除。

现在应用X和Y轴均为0.9ScaleTransform

接下来选择Path元素,将X轴的ScaleTransform设置为0.68,Y轴设置为0.91

这样您应该得到与下图相同的结果。

10FreeButtons/img18.jpg

(为了清晰起见,我将Path元素的Opacity设置为50%。)

现在“Shift”选择Path元素和Ellipse元素。(按此顺序!)

转到Object菜单,选择Combine > Subtract(如下图所示)。

10FreeButtons/img19.jpg

(元素选择顺序很重要:选择Cutter,应用于Pastry。)

通过一点魔法,您现在有了一个从Cutter Path形状中减去的Pastry Ellipse

10FreeButtons/img20.jpg

(这个新的“糖果”形状的Path,并非适用于所有按钮尺寸,但这只是一个小小的Margin问题)。

Path元素重命名为“LockFaceBGround”,重置Margins,并将Fill设置为Template Binding > Background

现在我们所有的按钮看起来都应该如下图所示。

10FreeButtons/img1A.jpg

再次,我们需要一个参考来Scale糖果形状,但我们需要此样式中多个元素作为按钮的一部分。

因此,我们应该将ScaleTransform应用于父对象LockFace及其所有子元素。

所以选择Root元素Grid,插入一个Ellipse并将其放置在LockFace元素后面。

删除Stroke,确保Fill为白色(为清晰起见),并应用X和Y轴均为0.9ScaleTransform

现在为了帮助设置正确的ScaleTransform,选择LockFace元素并将Opacity设置为50%

在仍然选中LockFace元素的情况下,在Y轴上设置一个ScaleTransform,以匹配其后面的Ellipse

(我发现Y轴上的ScaleTransform0.666效果很好! - 不,我不是魔鬼,现在还不是!)。

选择LockFaceBGround元素,并复制它以在LockFace父级中创建一个新的Path类型元素。

LockFace元素的Opacity改回100%,并将新复制的Ellipse重命名为“LockFaceTexture”。

显然,我们已经在Base上应用了纹理效果,所以选择BaseTexture并将Fill转换为New Resource

将此New Resource重命名为“WCDoorButtonTexture”。

(如果您使用的是包含多个按钮的Resource Dictionaries,最好相应地命名您的Resources。)

回到选中LockFaceTexture,将Fill更改为新创建的Resource

LockFaceTexture的元素Opacity更改为40%,以降低对比度。

但是降低对比度会使Lock Face变暗,所以再次复制LockFaceTexture

将此新元素重命名为“LockFaceEdgeOverlay”,将Fill设置为Radial Gradient

将两个Gradient Stops都设置为白色,并在Ribbon90处添加另一个。

选择Ribbon100处的Gradient Stop,并将Alpha值更改为0%

使用Gradient Tool,将形状更改为匹配后面的EllipseCircle)。

10FreeButtons/img1C.jpg

目前,Lock Face就处理好了,让我们来考虑下一个旋转旋转)圆盘。

第四部分 - 信息旋转器(启用/空闲)

选择白色Ellipse,选择Group Into > Grid

Grid重命名为“Spinner”,将子Ellipse重命名为“SpinnerBGround”。

将应用于SpinnerBGroundScaleTransform0.9重置回1.0

并为Spinner Grid元素设置0.85ScaleTransform,以及所有边距为1

这样Spinner应该能很好地放置在Lock Face中,如下图所示。

10FreeButtons/img1D.jpg

我们现在需要生成四张不同的Spinner图片。

(一张“启用”,一张“空闲”,一种绿色颜色和一种红色颜色。)

因为本教程是关于Expression Blend而不是Vector Graphics,这里是“Vacant”和“Engaged”的Paths

(我想避免本教程过于冗长……)

将这2Existing Items添加到Project。并在Projects选项卡中,双击Engaged.xaml进行访问。

Path元素复制并返回到MainPage(通过单击Artboard顶部)。

在按钮Template中选择Spinner元素,并PastePath元素。

将此Path元素重命名为SpinnerEngagedText,将Margins重置,并将WidthHeight设置为Auto

10FreeButtons/img1E.jpg

我们将使用Grid来定位SpinnerEngagedText元素,然后Rotate父级Grid

(如果没有父级GridPath元素将围绕其自身中心旋转,而不会是Spinner的中心)。

选择SpinnerEngagedText元素,右键单击并选择Group Into > Grid

Grid元素重命名为SpinnerEngaged,设置Grid分隔符,如下图所示。

10FreeButtons/img23.jpg

SpinnerEngagedText元素放置在这些新的RowDefinitions中。

我发现RowDefinitions设置为0.02*0.25*0.73*对我有用,如下面的XAML所示。

10FreeButtons/img24.jpg

现在设置ColumnDefinitions0.225*0.54*0.235*

10FreeButtons/img25.jpg

Column分隔符略微偏离中心,以帮助居中SpinnerEngagedText元素)。

SpinnerEngagedText元素放置在这些分隔符内,使其看起来如下图所示。

10FreeButtons/img26.jpg

(我在SpinnerEngagedText元素上应用了0.5度的Rotation进行微调。)

我们需要为Vacant部分Spinner做同样的事情,所以CopyPasteSpinnerEngaged元素。

将此复制的Grid重命名为SpinnerVacant,并DeleteText元素。

选择原始的SpinnerEngaged元素,并将其移开,将其Rotate90度。

(这应该将其隐藏在LockFace的右侧。)

现在找到Vacant.xaml文件,并将其Path复制SpinnerVacant Grid(就像您为Engaged Path所做的那样)。

(您现在可以从Project中删除Vacant.xaml)。

Vacant Path元素重命名为SpinnerVacantText,并将其放置在Grid分隔符内。

10FreeButtons/img28.jpg

令人惊讶的是,这似乎很适合,尽管Text比“EngagedText大。

(将LockFaceOpacity更改为50%,以显示“EngagedText。)

根据您的需要更改RowColumn分隔符,并记住重置子元素的Margins

我将保持我的原样,除了将SpinnerVacantText元素Rotate -0.5度。

这样就只剩下红色绿色指示器需要考虑了。

我们可以使用LockFacePastry)作为这些元素的基础。

所以选择LockFaceBGround元素,使用CopyPasteSpinner Grid中创建一个副本。

将此新元素重命名为“SpinnerRed”,将Margins重置,并确保Alignments设置为Stretch

将X轴的ScaleTransform更改为0.95,Y轴更改为0.6

现在在Objects and Timeline中,通过单击旁边的眼睛图标隐藏LockFace元素。

SpinnerRedFill重置,并将其Fill设置为Linear Gradient

使用Gradient Tool,按照下图所示排列箭头。

10FreeButtons/img2A.jpg

将第一个Gradient Stop更改为丰富的红色#FFD20000),并将其放在Ribbon49处。

将另一个Gradient Stop放在Ribbon50处,并将Alpha值设置为0%

这样您应该得到与下图相同的结果。

10FreeButtons/img2B.jpg

现在复制SpinnerRed元素,将其重命名为SpinnerGreen,并将其Rotate-90度。

Red Gradient Stop更改为丰富的绿色#FF00B400),这样Spinner就完成了。

取消隐藏LockFace元素,并如上图所示查看结果。

10FreeButtons/img2C.jpg

现在选择Spinner元素,并将其Rotate90度,哦!-90度以显示Engaged状态。

(也许使用正值Rotation会更好。)

Rotation重置为0,选择SpinnerEngaged元素,并将Rotation更改为-90度。

接下来选择SpinnerRed元素,并将其Rotate180度。

这样,我们就可以将Spinner元素Rotate90度来显示Engaged状态。

如下图所示。

10FreeButtons/img2D.jpg

这样Spinner就完成了。(这次,至少目前是这样。)

第五部分 - 完成面板(中心销和旋转器凹槽)

让我们从中心销开始,这应该很简单。

(我知道我总是拼错“Center”,但我说英语,抱歉!)。

Objects and Timeline中选择Root元素,插入一个新的Ellipse并将其重命名为“CentrePinBGround”。

Fill设置为Template Binding > Background,并删除Stroke

CentrePinBGround元素Group到一个Grid中,并将Grid重命名为CentrePin

CentrePin Grid上设置XY轴均为0.25ScaleTransform

(我希望中心销非常小,并在MouseOver时变大。)

现在在CentrePin Grid中插入一个新的Ellipse,并将其重命名为CentrePinOverlay

Fill设置为Radial Gradient,在Ribbon085100处有白色Gradient Stops

将第一个Gradient StopAlpha值保持为100%,将第二个更改为85%,第三个更改为40%

现在将元素Opacity设置为60%,并祈祷,它应该看起来如下图所示。

10FreeButtons/img2E.jpg

再次选择CentrePin Grid元素,插入一个Rectangle并将其重命名为“CentrePinSlot”。

Fill设置为Template Binding > Background,并删除Stroke

将Y轴的ScaleTransform设置为0.1,并将元素Opacity设置为60%

搞定,应该看起来如下图所示。

10FreeButtons/img2F.jpg

现在为了在底座上创建一个凹陷的圆盘区域,Spinner可以放在里面。

(它需要位于Base前面,并且在Spinner后面。)

所以选择Root元素,插入一个Ellipse,将其重命名为DishBGround

现在将DishBGroundGroup到一个Grid中,并将Grid重命名为Dish”。

接下来在Objects and Timeline中,将Dish Grid拖到Spinner Grid上方。

10FreeButtons/img30.jpg

选择DishBGround元素,删除Stroke,并将Fill设置为Template Binding > Background。(一如既往!)

现在选择Dish元素,并设置X和Y轴均为0.9ScaleTransform

Dish元素中插入另一个Ellipse,删除Stroke,并将Fill设置为Radial Gradient

反转Gradient Stops,将白色Gradient Stop移到Ribbon93处,并将元素Opacity设置为30%

这样基本上就完成了,如下图所示。

10FreeButtons/img31.jpg

第六部分 - 最后润饰

我一直避免在此之前应用任何指示光线方向的指示,因为在所有元素都到位之前这是徒劳的。

此外,LockFace需要更多的边缘定义,CentrePin也是如此。

但我在这里不是为了重复我在先前教程中展示的效果和技术。

所以我不会在本教程中涵盖这些,只是说:

尝试一些DropShadow Effects。 - 其余的就看您了!

(如果您卡住了,可以查看我的完成版本!)

看看我应用在Lock Face上的Stroke,使其边缘更加突出。
以及我如何为Centre Pin制作Slot

查看我应用于SpinnerDish元素的Shine

第七部分 - 动画(按钮状态)

现在,在我开始摆弄VSM(Visual States Manager)之前,让我们考虑一下这是什么类型的按钮?

它目前是一个标准按钮,但此Control的功能更适合作为Toggle按钮。

Toggle按钮有CheckStates,这允许我们为UncheckedCheckedIntermediate设置视觉States

10FreeButtons/img32.jpg

(例如,CheckBox也有这3个CheckStates。)

两个States比较容易理解,按钮可以处于PressedNot-Pressed State

但第三个Intermediate State有点复杂,可以视为Half-Pressed

(为了不冒犯太多开发者,请记住这是一个入门教程,这并不完全准确。)

考虑我页面上有一个Toggle按钮,表示“”或“”。

但是由于我在页面上选择了其他选项,“”或“”可能不适用于这些选项。

如果“”或“”不适用于所选选项,我需要另一个State来定义“不适用”或“不确定”。

因此,Intermediate State! - (这就是我为设计师提供的关于Intermediate State的“新手”解释。)

(您可能认为Disabled State可以工作,但Disabled和“Not Sure”完全不同。)

那么我们如何将这个按钮变成一个Toggle按钮呢? - 老实说,我不知道!

我不确定是否有简单的转换方法,至少对于设计师来说没有。

但实际上没有必要,因为我们可以简单地将Button Template中的所有元素CopyPasteToggle Button Template中。

您也可以选择Button TemplateRoot元素,右键单击并选择Make Into Control,基于Toggle Button

但这会将一个Toggle Button放置在一个Normal Button内(导致嵌套的Controls)。

所以Copy我们当前Button TemplateRoot元素,退出Template并删除所有六个按钮。

(不用担心,我们所有的工作都还在剪贴板上!)

Assets library中,将一个Toggle Button放置在页面上,并编辑Template

将新 Style 命名为WCDoorToggleButton,然后单击OK

Delete模板中的所有内容,除了ContentPresenter

(如果真的要用,我们宁愿使用这个Template自带的ContentPresenter,而不是我们Pasting进去的。)

(因为它已经通过Template Binding连接到Style。)

选择Root Grid元素,并将旧Template中的所有元素Paste进来。

您可能会在Root处看到一个Grid嵌套在另一个Grid中,所以CopyPaste,将其安排如下。

10FreeButtons/img33.jpg

(我们可能不会使用ContentPresenter,但为什么要删除它?你永远不知道?)
(我们也可以把它移到前面,并在Style中将Content留空? - 您决定!)

现在退回Toggle Button Template,使用CopyPaste,像之前一样设置六个按钮。

现在来进行一些动画,这次我们将忽略VSM中的Pressed State

相反,我们将使用Checked State作为Pressed State

所以转到Visual States ManagerVSM)选项卡。(Blend左上角 - 在布局模式下)。

转到Checked State,并将Spinner元素Rotate90度。

设置Duration0.5秒,然后运行您的应用程序(F5)。

希望您的WC Door Lock现在可以在VacantEngaged States之间动画。

现在我们需要动画CentrePin,使其与Spinner一起Rotate

所以,在Checked State中,将CentrePinRotate90度。

接下来转到MouseOver State,并将CentrePin ScaleTransform0.25更改为0.35

Pressed State中重复以上步骤,以防止CentrePin在按钮按下时收缩。

为上述States组设置Duration0.2秒,然后运行您的应用程序(F5)查看结果。

我们可以为这 2 个不同的State组添加一些EasingFunctions,所以请去玩吧!

(查看我的完成版本,了解我做了什么。)

继续,让我们考虑一下如果我们只想让按钮的圆形中心部分接受鼠标事件会怎样?

这样点击Base和相关的Screw就不会触发按钮。

我们只需要将这些元素及其子元素的IsHitTestVisible属性关闭

所以选择Base,在Common PropertiesAdvanced Properties中,将IsHitTestVisible关闭

10FreeButtons/img35.jpg

ScrewLayout元素重复以上步骤,运行您的应用程序以查看结果。

希望您的 Toggle Button 现在只会在内部圆形区域接受鼠标事件。

第八部分 - 总结

我希望我们从本教程中学到的不仅仅是重复我以前展示的内容。

相反,我希望您学到的是,良好的布局和逻辑命名很重要,因为Control变得更加复杂。

我几乎将所有内容都放在了Grid中,而Grid是您处理Layout时最好的朋友。

它能保持一切整洁,同时又能提供对子元素的控制(家长控制)。

如果我不合乎逻辑地分组,我将不得不四处寻找,才能使Control的某些部分不IsHitTestVisible

当然,在VSM中为Control的某些部分进行动画处理时,这也很重要!

所以不要偷懒,否则以后会吃苦头的!

现在,尽管我们已经根据我指定的参数创建了这个按钮。

我不会说它是最终成品,因为我也是从头开始创建的。

(不是复制我现有的例子 - 而是 Rolf Harris 式的!)

所以您会发现我的完成示例已根据我个人的品味进行了编辑和增强。

就这些了,感谢您的阅读和投票!!!

祝好!

第九部分 - 来源

下面是包含UserControl中按钮的整个project的链接。

下面是仅包含Resource Dictionary的列表,除非您将Styles放回UserControl中,否则很难编辑。

第十部分 - 注释

Plunger按钮的柱塞深度会根据其大小进行Scale。而Arcade按钮则不会。
这是因为它使用了Center Point的变化和Scale Transform,允许它为所有按钮尺寸进行Scale

Celtic Cross按钮与WC按钮一样,是Toggle按钮。

我使用了Blur EffectsDrop Shadows,其大小在平均情况下效果很好,但对于较小的Scales则不会过度。总是需要根据尺寸对这些Effects进行一些编辑。

© . All rights reserved.