[CodeProject每日一荐] PopupNotifier: 一个Office 2003风格的通知控件(VB.NET)
很高兴找到一篇最近这个话题的新的文章:2006.3.23,一个长于编程,短于文档的程序员作品:)有时间准备把VB.NET翻译成C#版本.以便自己以后使用:)
An Office 2003-like popup notifier By Nick Wälti
[介绍/特色]
看图说话:
Office 2003新邮件通知的风格:
渐隐渐出: 透明度
可定制为MSN Messsenger风格:
其他风格实例:
在PopupNotifier.vb 类中加入:
An Office 2003-like popup notifier By Nick Wälti
[介绍/特色]
看图说话:
Office 2003新邮件通知的风格:
渐隐渐出: 透明度
可定制为MSN Messsenger风格:
其他风格实例:
该控件完全在代码中完成绘制,不依赖于System.Drawing
和System.Windows.Forms
.你可以包含一个ContextMenuStrip,
当点击第一个图中"向下"的箭头图标时显示出来.
[使用代码]
该控件有两个基本的类组成:
- 一个 form (会实际显示出来的部分).
- 一个包含所有可在form中包含的属性的类.
类包含两个timers, 一个用来控制渐隐渐出的动画效果,另一个可配置为定义弹出窗口显示多久.下面是一个演示:
fPopup.Size = Size
fPopup.Opacity = 0
fPopup.Location = _
New Point(Screen.PrimaryScreen.WorkingArea.Right_
- fPopup.Size.Width - 1, _
Screen.PrimaryScreen.WorkingArea.Bottom)
fPopup.Show()
form在Paint事件中完成绘制. 笔者使用了一下函数来获取比指定颜色更浅/更深的颜色
,但不确定是否有更好的方法.
Private Function GetDarkerColor(ByVal Color As Color) As Color
Dim clNew As Color
clNew = Drawing.Color.FromArgb(255, DedValueMin0(CInt(Color.R), _
Parent.GradientPower), DedValueMin0(CInt(Color.G), _
Parent.GradientPower), DedValueMin0(CInt(Color.B), _
Parent.GradientPower))
Return clNew
End Function
为避免闪烁:
Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
Me.SetStyle(ControlStyles.ResizeRedraw, True)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
[译者:内容很简洁,因为刚出来,才V1.0,肯定还会有所补充完善,下面摘取一些问题的评论和反馈]
[问题的评论和反馈]
[1]如何为控件实现一个隐藏窗体的方法在PopupNotifier.vb 类中加入:
Sub Hide()
tmWait.Stop()
tmAnimation.Start()
End Sub
tmWait.Stop()
tmAnimation.Start()
End Sub
在form中如此调用:
Private Sub PopupNotifier1_Close() Handles PopupNotifier1.Close
PopupNotifier1.Hide()
End Sub
PopupNotifier1.Hide()
End Sub
[2]如何为控件实现一个定渐隐渐出速度的属性
Private iAnimationDelay As Integer = 50
<Category("Behavior"), _
DefaultValue(50)> _
Property AnimationDelay() As Integer
Get
Return iAnimationDelay
End Get
Set(ByVal value As Integer)
iAnimationDelay = value
End Set
End Property
Sub Popup()
tmAnimation.Interval = AnimationDelay
' .... REST OF THE SUBROUTINE ....
End Sub
<Category("Behavior"), _
DefaultValue(50)> _
Property AnimationDelay() As Integer
Get
Return iAnimationDelay
End Get
Set(ByVal value As Integer)
iAnimationDelay = value
End Set
End Property
Sub Popup()
tmAnimation.Interval = AnimationDelay
' .... REST OF THE SUBROUTINE ....
End Sub
[3]如何实现类似MSN Messenger的同时处理多个提示消息的效果(向上层叠):
写一个PopupNotifierCollection封装多个PopupNotifier,加一个YOrigin属性来控制位置
Imports System.ComponentModel
Public Class PopupNotifierCollectionClass PopupNotifierCollection
Inherits CollectionBase
Sub New()Sub New()
End Sub
Protected Overrides Sub OnSet()Sub OnSet(ByVal index As Integer, ByVal oldValue As Object, ByVal newValue As Object)
MyBase.OnSet(index, oldValue, newValue)
End Sub
Protected Overrides Sub OnInsert()Sub OnInsert(ByVal index As Integer, ByVal value As Object)
MyBase.OnInsert(index, value)
End Sub
Default ReadOnly Property Item()Property Item(ByVal Index As Integer) As PopupNotifier
Get
Return DirectCast(List(Index), PopupNotifier)
End Get
End Property
Public Function Add()Function Add(ByVal value As PopupNotifier) As PopupNotifier
List.Add(value)
Return value
End Function
Public Function Contains()Function Contains(ByVal value As PopupNotifier) As Boolean
Return List.Contains(value)
End Function
Public Sub Remove()Sub Remove(ByVal value As PopupNotifier)
List.Remove(value)
End Sub
Public Function IndexOf()Function IndexOf(ByVal value As PopupNotifier) As Integer
Return List.IndexOf(value)
End Function
Public Shadows Sub Clear()Sub Clear()
MyBase.Clear()
End Sub
Sub Popup()Sub Popup()
For Each Item As PopupNotifier In List
Item.Popup(List.IndexOf(Item))
Next
Clear()
End Sub
End Class
Public Class PopupNotifierCollectionClass PopupNotifierCollection
Inherits CollectionBase
Sub New()Sub New()
End Sub
Protected Overrides Sub OnSet()Sub OnSet(ByVal index As Integer, ByVal oldValue As Object, ByVal newValue As Object)
MyBase.OnSet(index, oldValue, newValue)
End Sub
Protected Overrides Sub OnInsert()Sub OnInsert(ByVal index As Integer, ByVal value As Object)
MyBase.OnInsert(index, value)
End Sub
Default ReadOnly Property Item()Property Item(ByVal Index As Integer) As PopupNotifier
Get
Return DirectCast(List(Index), PopupNotifier)
End Get
End Property
Public Function Add()Function Add(ByVal value As PopupNotifier) As PopupNotifier
List.Add(value)
Return value
End Function
Public Function Contains()Function Contains(ByVal value As PopupNotifier) As Boolean
Return List.Contains(value)
End Function
Public Sub Remove()Sub Remove(ByVal value As PopupNotifier)
List.Remove(value)
End Sub
Public Function IndexOf()Function IndexOf(ByVal value As PopupNotifier) As Integer
Return List.IndexOf(value)
End Function
Public Shadows Sub Clear()Sub Clear()
MyBase.Clear()
End Sub
Sub Popup()Sub Popup()
For Each Item As PopupNotifier In List
Item.Popup(List.IndexOf(Item))
Next
Clear()
End Sub
End Class
Dim colPopupNotifiers As New PopupNotifierCollection
Dim pnNotifier1 As PopupNotifier = New PopupNotifier
Dim pnNotifier2 As PopupNotifier = New PopupNotifier
colPopupNotifiers.Add(pnNotifier1)
colPopupNotifiers.Add(pnNotifier2)
colPopupNotifiers.Popup()
Dim pnNotifier1 As PopupNotifier = New PopupNotifier
Dim pnNotifier2 As PopupNotifier = New PopupNotifier
colPopupNotifiers.Add(pnNotifier1)
colPopupNotifiers.Add(pnNotifier2)
colPopupNotifiers.Popup()
Popup()会调用PopupNotifier的Popup(),PopupNotifier要做一些改变:
加入Private iOffset As Integer = 0
在Popup()中:
Sub Popup(Optional ByVal Number As Integer = 0)
tmWait.Interval = ShowDelay
fPopup.Size = Size
fPopup.Opacity = 0
iOffset = (Number * fPopup.Size.Height) + (Number * 5)
fPopup.Location = New Point(Screen.PrimaryScreen.WorkingArea.Right - fPopup.Size.Width - 1, Screen.PrimaryScreen.WorkingArea.Bottom - iOffset)
fPopup.Show()
tmAnimation.Start()
End Sub
tmWait.Interval = ShowDelay
fPopup.Size = Size
fPopup.Opacity = 0
iOffset = (Number * fPopup.Size.Height) + (Number * 5)
fPopup.Location = New Point(Screen.PrimaryScreen.WorkingArea.Right - fPopup.Size.Width - 1, Screen.PrimaryScreen.WorkingArea.Bottom - iOffset)
fPopup.Show()
tmAnimation.Start()
End Sub
在tmAnimation_Tick()中:
...
If fPopup.Top + fPopup.Height < Screen.PrimaryScreen.WorkingArea.Bottom - iOffset
...
If fPopup.Top > Screen.PrimaryScreen.WorkingArea.Bottom - iOffset
...
If fPopup.Top + fPopup.Height < Screen.PrimaryScreen.WorkingArea.Bottom - iOffset
...
If fPopup.Top > Screen.PrimaryScreen.WorkingArea.Bottom - iOffset
...
[4]如何隐藏任务栏上的小图标
在New中 加一句ShowInTaskbar = False.[译者:当然也可以定义为一种属性,方便重用]