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

MediaSlider - Trackbar控件的替代品 - v1.3

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.94/5 (58投票s)

2010年2月7日

CPOL

5分钟阅读

viewsIcon

176321

downloadIcon

14581

一个功能齐全的动画滑块控件

MediaSlider

按钮的结构

与其直接给你一些无聊的代码(反正没人看...),我想分享一些关于我如何构建此控件中使用的视觉样式的见解。

我做的第一件事,也是过程中的第一步,就是充分了解用户对用户控件的需求,以及对最终控件外观的设想。我经常浏览wincustomize.com或专业的控件制作网站,以了解可能的功能和UI线索,还可以看看Windows/Mac,并尝试想象他们是如何创建那些图形的,甚至是如何改进它们的。

下一步是搭建控件的框架。创建用户控件,为其添加所有基本功能,并尝试创建一个简单无故障的框架来使用。我是这样开始这个滑块的,直到所有基本功能都正常工作后,我才开始编写图形代码。在此过程中,保持一切组织有序至关重要。我最喜欢.NET的一点是#region指令。它允许您将大型类和方法分割成可管理的块。此外,我建议为内部测量使用private属性或常量,因为随着代码变得越来越复杂,硬编码的数字需要更改的可能性就越来越大。这是我在编写此控件的Autosize功能时遇到的问题;因为一些数字被硬编码在一个方法中,一个错误导致我花了一个小时才找到问题。

绘制一个闪亮的按钮..

第一步是用纯色填充按钮。这是为了确保在使用透明颜色时,按钮保持不透明。如果您使用半透明颜色并想要发光效果,则使用白色,否则使用按钮的基础颜色。

anatomy1.jpg

从上面的图像中可以看到,按钮的比例不正确。我这样做是为了使渐变阴影的细微差别更加明显。您还可以看到这只是一个普通的黑色边框,带有白色填充,这只是在添加三个渐变之前的画布。

anatomy2.jpg

第一个渐变是一个垂直线性渐变,其混合因子在中心使用180个alpha值的半透明白色,渐变到按钮的基础颜色。这给人一种立体感,让按钮仿佛从平面上凸起。

using (GraphicsPath gp = new GraphicsPath())
{
    gp.AddEllipse(buttonRect);
    // fill with base color
    using (Brush br = new SolidBrush(Color.FromArgb(255, this.ButtonColor)))
        g.FillPath(br, gp);
    // add top sheen
    using (LinearGradientBrush fillBrush = new LinearGradientBrush(
        buttonRect,
        Color.FromArgb(180, Color.White),
        this.ButtonColor,
        LinearGradientMode.Vertical))
    {
        Blend blnd = new Blend();
        blnd.Positions = new float[] { 0f, .1f, .2f, .3f, .6f, 1f };
        blnd.Factors = new float[] { .2f, .3f, .4f, .5f, 1f, 1f };
        fillBrush.Blend = blnd;
        g.FillPath(fillBrush, gp);
    }

anatomy3.jpg

我还想从下方添加一个类似MediaPlayer按钮的亮光效果,使用强调色。强调色是用户可定义的,这意味着您可以选择从微妙到非常明显的效果。尽管这些图像在白色背景上显示了按钮的属性颜色,但在设计它们时,我在黑色背景上使用了红色和白色。这让您对渐变如何相互作用有了更好的认识。底部发光是通过向graphics path添加一个新的椭圆,将其推到按钮底部,并使用PathGradientBrush绘制来实现的。

// add the bottom glow
using (PathGradientBrush borderBrush = new PathGradientBrush(gp))
{
    using (GraphicsPath ga = new GraphicsPath())
    {
        accentRect.Inflate(0, (int)-(accentRect.Height * .2f));
        accentRect.Offset(0, (int)(ButtonSize.Width * .2f));
        ga.AddEllipse(accentRect);
        // center focus
        fx = accentRect.Width * .5f;
        fy = accentRect.Height * 1f;
        borderBrush.CenterColor = this.ButtonColor;
        borderBrush.SurroundColors = new Color[] { this.ButtonAccentColor };
        borderBrush.FocusScales = new PointF(1f, 0f);
        borderBrush.CenterPoint = new PointF(fx, fy);
        g.FillPath(borderBrush, ga);
    }

anatomy4.jpg

最后一个渐变在按钮顶部大约300度处添加了一个聚光灯效果,使其看起来像是光源位于按钮图像的左上方。

// spotight offsets
fx = buttonRect.Width * .2f;
fy = buttonRect.Height * .05f;
// draw the spotlight
borderBrush.CenterColor = Color.FromArgb(120, Color.White);
 borderBrush.SurroundColors = new Color[] { Color.FromArgb(5, Color.Silver) };
borderBrush.FocusScales = new PointF(.2f, .2f);
borderBrush.CenterPoint = new PointF(fx, fy);
g.FillPath(borderBrush, gp);

这一切可能对于这样一个小的按钮来说似乎付出了很多努力,但我认为细节很重要,而且,按钮的图形甚至可以做得更加复杂。另外请注意,所有按钮样式实际上都渲染到Bitmap上,只创建一次,只需要一个DrawImage命令即可渲染。否则就不会没有闪烁。

anatomy5.jpg

属性

我希望此控件的绝大多数方面都可以修改,因此保留了许多开放式属性以供自定义。

  • Animated:在获得焦点时运行动画效果。
  • AnimationSpeed:动画周期速度 [快 中 慢]。
  • AnimationSize:精灵宽度占轨道宽度的百分比 [最小值 0.05 - 最大值 0.2]。
  • BackGroundImage:使用图像作为滑块背景。
  • ButtonAccentColor:修改按钮强调色。
  • ButtonBorderColor:修改按钮边框颜色。
  • ButtonColor:修改按钮基础颜色。
  • ButtonCornerRadius:调整滑块按钮的圆角半径。
  • ButtonSize:修改滑块按钮大小。
  • ButtonStyle:设置按钮样式 [Round RoundedRectOverlap RoundedRectInline Hybrid PointerUpLeft PointerDownRight GlassInline GlassOverlap]。
  • IsInited:返回控件的初始化状态。
  • LargeChange:鼠标单击或PageUp/PageDown时滑块移动的点击次数。
  • Maximum:滑块位置的最大值。
  • MaxSize:控件的最大尺寸值 [私有设置]。
  • Minimum:滑块位置的最小值。
  • MinSize:控件的最小尺寸值 [私有设置]。
  • Orientation:控件的方向。
  • PrecisionValue:将滑块位置返回为浮点数,需要将SmoothScrolling设置为true
  • SmallChange:按下箭头键时滑块移动的位置数。
  • SmoothScrolling:启用平滑滚动样式。
  • Value:滑块的位置。
  • ShowButtonOnHover:仅在控件获得焦点或鼠标悬停时显示滑块按钮。
  • SliderFlyOut:启用弹出式标题窗口 [无、获得焦点时、持续显示]。
  • TickColor:修改滑块刻度线颜色。
  • TickStyle:选择刻度线样式。
  • TickType:选择刻度线绘制样式。
  • TrackBorderColor:修改滑块边框颜色。
  • TrackDepth:调整滑块轨道的深度。
  • TrackFillColor:设置轨道背景色。
  • TrackProgressColor:设置轨道背景色。
  • TrackShadow:启用轨道阴影。
  • TrackShadowColor:修改轨道阴影颜色。
  • TrackStyle:轨道的显示样式 [进度、值]。

样式

一些亮点

精确模式
precision.jpg
Round

trackshadow.jpg

圆角矩形

rect-inline.jpg

玻璃效果

glass-over2.jpg

WMC克隆带弹出式标题

flyout.jpg

WMP克隆带焦点动画

animation.jpg

标题工具栏

toolbar.jpg

如果您正在运行Aero,标题区域的工具栏可能引起了您的注意...这是一个如何使用此功能的绝佳示例(为什么要在演示窗体中弄得一团糟?)。

一切都是可移植的,只需复制ExtendFrame区域的内容,更新您的指令,然后调用ExtendMargin方法,就像示例中一样,或者查看我关于此主题的文章

© . All rights reserved.