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

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

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (21投票s)

2003 年 1 月 11 日

3分钟阅读

viewsIcon

207171

downloadIcon

296

为什么又一个按钮控件?因为我搜索网络,想找一个能够模仿 XP/VS.NET 风格的按钮,但是没有找到一个合适的。我认为这个按钮具有所有需要的功能:酷炫的风格,快捷键,图标,对齐方式,等等...

Sample Image - top.jpg

引言

最近我在寻找一个看起来像新的 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 文件类型支持,... 如果你还有其他需求或想法,请告知!

© . All rights reserved.