制作播放器控制按钮组合控件 GDI+绘制

制作一个播放器的控制按钮组合控件 较好的封装子控件 并提供公开属性更换外观

 

组合控件还差按钮上的图形 比如中间的播放图标 上一个 下一个 打开 停止的图标,控件使用alpha混合和渐变

组合控件一共上下左右四个按钮 自身作为中间的按钮使用,并且可以适应各种宽度和高度

我的思路是这样的:总共有五个类 组合控件MP3Buttons 上下左右四个按钮类 ,主要实现一个周边按钮 其它3个按钮继承自这个按钮,并重写一个方法就可以了,所以主要是实现2个类 组合按钮类,任意一个周边按钮

1.先设计一个左边按钮的类 LeftButton:UserControl 本可以继承Control类 不过Control不支持背景透明 UserControl支持背景透明,在Resize事件中限制控件的区域

2.创建RightButton TopButton BottomButton 它们继承自LeftButton

3.创建MP3Buttons组合控件 继承自UserControl 设计对外属性以更改控件的外观 设计各按钮的单击事件

 

一.LeftButton的实现

 

代码
  1 internal partial class LeftButton : UserControl
  2 {
  3     private enum MouseStatus { Eneter, Leave, Down, Up }
  4 
  5     private Color _themeColor = Color.Black;
  6     private Color _normalColor = Color.FromArgb(200, Color.Black);
  7     private Color _enterColor = Color.FromArgb(100, Color.Black);
  8     private Color _dowmColor = Color.FromArgb(150, Color.Black);
  9     private MouseStatus _state = MouseStatus.Leave;
 10     public GraphicsPath _borderPath;
 11     
 12     public Color ThemeColor
 13     {
 14         set
 15         {
 16             _themeColor = value;
 17             _normalColor = Color.FromArgb(200, _themeColor);
 18             _enterColor = Color.FromArgb(100, _themeColor);
 19             _dowmColor = Color.FromArgb(150, _themeColor);
 20             Refresh();
 21         }
 22         get { return _themeColor; }
 23     }
 24 
 25     public LeftButton()
 26     {
 27         InitializeComponent();
 28         SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.SupportsTransparentBackColor, true);
 29         UpdateStyles();
 30     }
 31 
 32     protected override void OnPaint(PaintEventArgs pe)
 33     {
 34         Graphics g = pe.Graphics;
 35         g.SmoothingMode = SmoothingMode.HighQuality;
 36         GraphicsPath path = new GraphicsPath();
 37         path.AddEllipse(this.ClientRectangle);
 38 
 39         PathGradientBrush pgBrunsh = new PathGradientBrush(path);
 40         pgBrunsh.CenterColor = Color.FromArgb(0, ThemeColor);
 41         switch (_state)
 42         {
 43             case MouseStatus.Leave:
 44                 {
 45                     pgBrunsh.SurroundColors = new Color[] { _normalColor };
 46                     g.FillRectangle(pgBrunsh, this.ClientRectangle);
 47                     break;
 48                 }
 49             case MouseStatus.Eneter:
 50                 {
 51                     pgBrunsh.SurroundColors = new Color[] { _enterColor };
 52                     g.FillRectangle(pgBrunsh, this.ClientRectangle);
 53                     break;
 54                 }
 55             case MouseStatus.Down:
 56                 {
 57                     pgBrunsh.SurroundColors = new Color[] { _dowmColor };
 58                     g.FillRectangle(pgBrunsh, this.ClientRectangle);
 59                     break;
 60                 }
 61             case MouseStatus.Up:
 62                 {
 63                     pgBrunsh.SurroundColors = new Color[] { _enterColor };
 64                     g.FillRectangle(pgBrunsh, this.ClientRectangle);
 65                     break;
 66                 }
 67             default:
 68                 {
 69                     pgBrunsh.SurroundColors = new Color[] { _normalColor };
 70                     g.FillRectangle(pgBrunsh, this.ClientRectangle);
 71                     break;
 72                 }
 73         }
 74         try
 75         {
 76             g.DrawPath(new Pen(new SolidBrush(_themeColor), 1), _borderPath);
 77         }
 78         catch
 79         {
 80         }
 81         g.SmoothingMode = SmoothingMode.HighQuality;
 82         base.OnPaint(pe);
 83     }
 84     protected override void OnResize(EventArgs e)
 85     {
 86         GraphicsPath path1 = new GraphicsPath();
 87         GraphicsPath path2 = new GraphicsPath();
 88         Rectangle rect = new Rectangle(this.Width / 3this.Height / 3this.Width / 3this.Height / 3);
 89         path1.AddPie(00this.Width, this.Height, 13590);
 90         _borderPath = path1;
 91         this.Refresh();
 92         float a = (float)this.Width / 3;
 93         float b = (float)this.Height / 3;
 94         path2.AddPie(a, b, a, b, 13590);
 95         Region region = new Region(path1);
 96         region.Exclude(path2);
 97         this.Region = region;
 98         base.OnResize(e);
 99     }
100     protected override void OnMouseEnter(EventArgs e)
101     {
102         _state = MouseStatus.Eneter;
103         this.Refresh();
104         base.OnMouseEnter(e);
105     }
106     protected override void OnMouseLeave(EventArgs e)
107     {
108         _state = MouseStatus.Leave;
109         this.Refresh();
110         base.OnMouseLeave(e);
111     }
112     protected override void OnMouseDown(MouseEventArgs e)
113     {
114         _state = MouseStatus.Down;
115         this.Refresh();
116         base.OnMouseDown(e);
117     }
118     protected override void OnMouseUp(MouseEventArgs e)
119     {
120         _state = MouseStatus.Up;
121         this.Refresh();
122         base.OnMouseUp(e);
123     }
124     protected override void OnClick(EventArgs e)
125     {
126         base.OnClick(e);
127         _state = MouseStatus.Leave;
128         Invalidate();
129     }
130 }

 

 

此类有一个ThemeColor属性 通过设置此属性更改其外观

二.实现其它周边3个按钮 只需要重写一个方法以更改有效区域

 

代码
 1 internal partial class RightButton :LeftButton
 2 {
 3     public RightButton()
 4     {
 5         InitializeComponent();
 6     }
 7     protected override void OnResize(EventArgs e)
 8     {
 9         GraphicsPath path1 = new GraphicsPath();
10         GraphicsPath path2 = new GraphicsPath();
11         Rectangle rect = new Rectangle(this.Width / 3this.Height / 3this.Width / 3this.Height / 3);
12         path1.AddPie(00this.Width, this.Height, 31590);
13         _borderPath = path1;
14         this.Refresh();
15         float a = (float)this.Width / 3;
16         float b = (float)this.Height / 3;
17         path2.AddPie(a, b, a, b, 310100);
18         Region region = new Region(path1);
19         region.Exclude(path2);
20         this.Region = region;
21     }
22 }

 

 

代码
 1 internal partial class TopButton : LeftButton
 2 {
 3     public TopButton()
 4     {
 5         InitializeComponent();
 6     }
 7 
 8     protected override void OnResize(EventArgs e)
 9     {
10         GraphicsPath path1 = new GraphicsPath();
11         GraphicsPath path2 = new GraphicsPath();
12         Rectangle rect = new Rectangle(this.Width / 3this.Height / 3this.Width / 3this.Height / 3);
13         path1.AddPie(00this.Width, this.Height, 22590);
14         _borderPath = path1;
15         this.Refresh();
16         float a = (float)this.Width / 3;
17         float b = (float)this.Height / 3;
18         path2.AddPie(a, b, a, b, 215100);
19         Region region = new Region(path1);
20         region.Exclude(path2);
21         this.Region = region;
22     }
23 }

 

 

 

代码
 1 internal partial class BottomButton : LeftButton
 2 {
 3     public BottomButton()
 4     {
 5         InitializeComponent();
 6     }
 7     protected override void OnResize(EventArgs e)
 8     {
 9         GraphicsPath path1 = new GraphicsPath();
10         GraphicsPath path2 = new GraphicsPath();
11         Rectangle rect = new Rectangle(this.Width / 3this.Height / 3this.Width / 3this.Height / 3);
12         path1.AddPie(00this.Width, this.Height, 4590);
13         _borderPath = path1;
14         this.Refresh();
15         float a = (float)this.Width / 3;
16         float b = (float)this.Height / 3;
17         path2.AddPie(a, b, a, b, 40100);
18         Region region = new Region(path1);
19         region.Exclude(path2);
20         this.Region = region;
21     }
22 }

 

 

这样 周边四个按钮就完成了

三.设计MP3Buttons:UserControl

把4个按钮从工具箱中拖到控件上 并设置它们的Dock属性为Fill 充满整个控件

此时在MP3Buttons上有4个实例化的子控件 LeftButton1 RightButton1 TopButton1 BottomButton1

 

1.设计辅助类型和字段

 

代码
1 private enum ButtonSta { Down, Up }
2 private bool _isPlaying = false;
3 private ButtonSta _state = ButtonSta.Up;
4 private Color _themeColor = Color.Red;
5 private Color _downColor = Color.FromArgb(100, Color.Red);
6 private Color _surroundingColor = Color.Black;
7 private EventHandler _themeColorChanged = null;
8 private EventHandler _surroundingColorChanged = null;

 

 

2.属性和构造函数 有2个属性 一个用于更改自身的外观 一个用于更改周边按钮的外观,这样可以形成外观组合  获得更丰富的外观

 

代码
 1 public Color ThemeColor
 2 {
 3     set
 4     {
 5         _themeColor = value;
 6         _downColor = Color.FromArgb(100, _themeColor);
 7         Invalidate();
 8         if (_themeColorChanged != null)
 9             _themeColorChanged(thisnew EventArgs());
10     }
11     get
12     {
13         return _themeColor;
14     }
15 }
16 public Color SurroundingColor
17 {
18     set
19     {
20         _surroundingColor = value;
21         leftButtonl1.ThemeColor = _surroundingColor;
22         rightButton1.ThemeColor = _surroundingColor;
23         topButton1.ThemeColor = _surroundingColor;
24         buttomButton1.ThemeColor = _surroundingColor;
25 
26         if (_surroundingColorChanged != null)
27             _surroundingColorChanged(thisnew EventArgs());
28     }
29     get
30     {
31         return _surroundingColor;
32     }
33 }
34 public bool IsPlaying
35 {
36     get { return _isPlaying; }
37     set
38     {
39         _isPlaying = value;
40         this.Invalidate();
41     }
42 }
43 public Mp3Buttons()
44 {
45     InitializeComponent();
46     SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.SupportsTransparentBackColor, true);
47     UpdateStyles();
48     leftButtonl1.ThemeColor = _surroundingColor;
49     rightButton1.ThemeColor = _surroundingColor;
50     topButton1.ThemeColor = _surroundingColor;
51     buttomButton1.ThemeColor = _surroundingColor;
52 
53 
54 }

 

 

3.设计事件 为了提供更好的封装 组合按钮类是公开的密封类 也不允许外部访问其子控件,由此控件对外提供六个事件 方便使用

这6个事件是 LeftButtonClick RightButtonClick TopButtonClick ButtomClick ThemeColorChanged SurroundingColorChanged

 

代码
 1 public event EventHandler ThemeColorChanged
 2 {
 3     add { _themeColorChanged += value; }
 4     remove { _themeColorChanged = value; }
 5 }
 6 public event EventHandler SurroundingColorChanged
 7 {
 8     add { _surroundingColorChanged += value; }
 9     remove { _surroundingColorChanged -= value; }
10 }
11 public event EventHandler LeftButtonClick
12 {
13     add { this.leftButtonl1.Click += value; }
14     remove { this.leftButtonl1.Click -= value; }
15 }
16 public event EventHandler RightButtonClick
17 {
18     add { rightButton1.Click += value; }
19     remove { rightButton1.Click -= value; }
20 }
21 public event EventHandler TopButtonClick
22 {
23     add { topButton1.Click += value; }
24     remove { topButton1.Click -= value; }
25 }
26 public event EventHandler BottomButtonClick
27 {
28     add { buttomButton1.Click += value; }
29     remove { buttomButton1.Click -= value; }
30 }

 

 

最后 重写少数几个函数就算完成了主要功能了

 

代码
 1 protected override void OnPaint(PaintEventArgs e)
 2 {
 3     GraphicsPath path = new GraphicsPath();
 4     path.AddEllipse(new Rectangle(Point.Empty, this.Size));
 5     this.Region = new Region(path);
 6     Graphics g = e.Graphics;
 7     g.SmoothingMode = SmoothingMode.HighQuality;
 8     PathGradientBrush pgb = new PathGradientBrush(path);
 9     if (_state == ButtonSta.Up)
10         pgb.CenterColor = ThemeColor;
11     else
12         pgb.CenterColor = _downColor;
13     Color endColor = Color.FromArgb(100, ThemeColor);
14     pgb.SurroundColors = new Color[] {endColor };
15     g.FillPath(pgb, path);
16     g.SmoothingMode = SmoothingMode.HighQuality;
17 }
18 protected override void OnSizeChanged(EventArgs e)
19 {
20     base.OnSizeChanged(e);
21     Refresh();
22 }
23 protected override void OnMouseDown(MouseEventArgs e)
24 {
25     _state = ButtonSta.Down;
26     this.Invalidate();
27     base.OnMouseDown(e);
28 }
29 protected override void OnMouseUp(MouseEventArgs e)
30 {
31     _state = ButtonSta.Up;
32     this.Invalidate();
33     base.OnMouseUp(e);
34 }

 

 

 

posted on 2010-12-05 21:38  狐狸狡猾不  阅读(1615)  评论(2编辑  收藏  举报

导航



Powered by: 博客园 copyright © 2009-2012 狐狸狡猾不