一个简单的 XP/VS.NET 风格按钮控件





4.00/5 (21投票s)
2003 年 1 月 11 日
3分钟阅读

207171

296
为什么又一个按钮控件?因为我搜索网络,想找一个能够模仿 XP/VS.NET 风格的按钮,但是没有找到一个合适的。我认为这个按钮具有所有需要的功能:酷炫的风格,快捷键,图标,对齐方式,等等...
- 下载源代码文件 + 演示 (Visual Studio 2003 Final Beta, .NET Framework 1.1) - 68.4 Kb
- 下载源代码文件 + 演示 (Visual Studio 2002, .NET Framework 1.0) - 21.3 Kb
引言
最近我在寻找一个看起来像新的 XP/VS.NET 风格按钮控件的控件。这个按钮控件需要具有本文中描述的功能。但是我找不到一个提供所有这些功能的免费控件,所以我自己创建了一个。 这是我的第一个版本,它提供你可以使用的基本功能。 但很快就会添加更多功能。
功能 1:基本按钮功能
啊,这对于大多数人来说是一个很容易的想法。 当然,必须有一个简单的 OnClick
事件
Public Shadows Event Click(ByVal sender As Object, ByVal e As EventArgs)
但是,如果你查看 .NET 框架中提供的 Button
控件的标准功能,你会发现基本按钮功能还需要一些其他的东西。 首先,你可以将 Text
属性设置为 '&Save',当你按下键 alt+S 时,将会触发按钮的 Click
事件。 我已经搜索了很长时间,但在一些新闻组的帮助下,我设法通过重写 ProcessMnenomic
函数来添加此功能
Protected Overrides Function ProcessMnemonic(ByVal charCode As Char) _
As Boolean
Dim ampPosition As Integer = _text.IndexOf("&")
Dim charToCheck As Char
If ampPosition > -1 And ampPosition < _text.Length Then
charToCheck = _text.Chars(ampPosition + 1)
If Char.ToLower(charToCheck) = Char.ToLower(charCode) Then
'BINGO!
Me.PerformClick()
Return True
End If
End If
Return False
End Function
当你在 Form
上放置一个 Button
控件时,你可以指定该按钮是 AcceptButton
还是 CancelButton
。 要完成此操作,必须实现 IButtonControl
接口
<System.ComponentModel.DefaultValue(GetType(DialogResult), Nothing)> _
Public Overridable Overloads Property DialogResult() As DialogResult _
Implements IButtonControl.DialogResult
Get
Return _dialogResult
End Get
Set(ByVal Value As DialogResult)
_dialogResult = Value
End Set
End Property
Public Overridable Overloads Sub NotifyDefault(ByVal value As Boolean) _
Implements IButtonControl.NotifyDefault
'Not needed
End Sub
Public Overridable Overloads Sub PerformClick() Implements _
IButtonControl.PerformClick
SetMouseOver()
clickHandler(Me, Nothing)
SetMouseLeave()
End Sub
这是按钮控件所需的基本功能。
功能 2:XP 风格的边框和背景色
在 Office XP 或 VS.NET 中,当你将鼠标移动到按钮上时,按钮的边框会绘制为蓝色,背景色也是蓝色。 这很容易编码
Private Sub NewFlatButton_Paint(ByVal sender As Object, _
ByVal e As System.Windows.Forms.PaintEventArgs)_
Handles MyBase.Paint
If Me.blueBorder Then
e.Graphics.DrawRectangle(New Pen(_bordercolorFocus), _
0, 0, Me.Width - 1, Me.Height - 1)
Else
e.Graphics.DrawRectangle(New Pen(_bordercolor), _
0, 0, Me.Width - 1, Me.Height - 1)
End If
End Sub
功能 3:XP 风格的图像
这是最有趣的部分! 当你仔细观察 XP 风格的按钮时,你会注意到图像有一些非常简洁的效果。 在正常状态下(鼠标不在按钮上),按钮会显示一张颜色比正常颜色稍亮的图片。 当你将鼠标移动到按钮上时,图片会收到阴影并将以正常颜色显示(比以前更暗)。 当你按下按钮时,图片会失去阴影,但仍以较暗的(正常)颜色显示。 该控件只需要 1 张图片,并通过代码生成其他 2 张所需的图片。
这是 3 种可能状态下的图片示例
正常,具有平滑、明亮的颜色。
凸起,颜色较深,带有阴影。
按下,颜色较深,没有阴影。
首先,我需要一个函数来计算颜色向更明亮的颜色转变 (我在 www.vbsmart.com 上找到了该公式)
Private Function TransformColor(ByVal x As Long) As Long
Return 76 - Int((x + 32) / 64) * 19 + x
End Function
创建更亮图像的函数是
Private Function GetSmoothImage(ByVal image As Image) As Image
Dim bmp As New Bitmap(image)
Dim x As Integer, y As Integer
For x = 0 To bmp.Width - 1
For y = 0 To bmp.Height - 1
Dim oldColor As Color = bmp.GetPixel(x, y)
If Not oldColor.Equals(Color.FromArgb(0, 0, 0, 0)) Then
Dim newColor As Color = _
Color.FromArgb(TransformColor(oldColor.R), _
TransformColor(oldColor.G), _
TransformColor(oldColor.B))
bmp.SetPixel(x, y, newColor)
End If
Next
Next
Return bmp
End Function
要生成鼠标悬停在其上时按钮的图像,首先将图像转换为黑白(以灰色)。 然后将原始图像绘制在其上,但向上和向右 2 个像素。 这样你就获得了一个不错的下拉阴影效果
Private Function GetRaisedImage(ByVal image As Image) As Image
Dim bmp As New Bitmap(image)
Dim newBmp As New Bitmap(bmp.Width + 2, bmp.Height + 2)
Dim x As Integer, y As Integer
For x = 0 To bmp.Width - 1
For y = 0 To bmp.Height - 1
Dim oldcolor As Color = bmp.GetPixel(x, y)
If oldcolor.Equals(Color.FromArgb(0, 0, 0, 0)) Then
newBmp.SetPixel(x + 2, y + 2, Color.Transparent)
Else
newBmp.SetPixel(x + 2, y + 2, Color.Gray)
End If
Next
Next
Dim g As Graphics = Graphics.FromImage(newBmp)
g.DrawImage(image, 0, 0)
Return newBmp
End Function
最后,按下按钮时需要的图像与原始图像相同
Private Function GetDownImage(ByVal image As Image) As Image
Return _image
End Function
其他功能
此控件中内置的其他一些功能,但我将不在此处解释:文本对齐、不同的边框颜色和图像边距。 你可以在源项目中找到代码。
未来功能
你已经可以使用此控件,因为它具有所有需要的功能。 但是,还有一些不错的功能将在(不久的将来?)实现:图像对齐,.ICO 文件类型支持,... 如果你还有其他需求或想法,请告知!