Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Windows.Forms.Design
Imports Ascend.Windows.Forms
Public Enum DisplayStyle
OfficeXP
Office2003
End Enum
'http://msdn.microsoft.com/msdnmag/issues/05/07/DesignerActions/#S7
'http://www.codeproject.com/useritems/TheCodeProject_DesignTime.asp
<Designer(GetType(TaskPaneDesigner))> _
Public Class TaskPane
Inherits System.Windows.Forms.UserControl
Public Event TaskPaneCloseClick(ByVal sender As Object, ByVal e As EventArgs)
Public Event SelectedIndexChanging(ByVal sender As Object, ByVal e As CancelEventArgs)
Public Event SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
#Region " Member Variables"
Friend Const DefaultCornerRadius As Integer = 8
Friend Shared NavigationAreaSize As New Size(87, 19)
Private m_HardMinimumSize As New Size(100, 60)
Private m_NavigationStyle As DisplayStyle = DisplayStyle.Office2003
Private m_CaptionStyle As DisplayStyle = DisplayStyle.Office2003
Private m_TaskPanePages As New TaskPanePageCollection
Private m_NavigationPanelAppearance As NavigationPanelAppearance
Private m_HomePane As TaskPanePage = Nothing
Private m_CurrentIndex As Integer = -1
Private m_IsClearingCollection As Boolean
#End Region
#Region " Properties"
Public Property SelectedIndex() As Integer
Get
Return m_CurrentIndex
End Get
Set(ByVal value As Integer)
SelectTaskPanePage(value)
End Set
End Property
Public Property SelectedPage() As TaskPanePage
Get
If m_CurrentIndex >= 0 AndAlso m_CurrentIndex < m_TaskPanePages.Count Then
Return m_TaskPanePages(m_CurrentIndex)
Else
Return Nothing
End If
End Get
Set(ByVal value As TaskPanePage)
SelectTaskPanePage(value)
End Set
End Property
<DefaultValue(GetType(DisplayStyle), "Office2003"), RefreshProperties(RefreshProperties.All)> _
Public Property NavigationStyle() As DisplayStyle
Get
Return m_NavigationStyle
End Get
Set(ByVal value As DisplayStyle)
If m_NavigationStyle = value Then Return
m_NavigationStyle = value
UpdateDisplayStyles()
End Set
End Property
<DefaultValue(GetType(DisplayStyle), "Office2003")> _
Public Property CaptionStyle() As DisplayStyle
Get
Return m_CaptionStyle
End Get
Set(ByVal value As DisplayStyle)
m_CaptionStyle = value
UpdateDisplayStyles()
End Set
End Property
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public ReadOnly Property NavigationPanelAppearance() As NavigationPanelAppearance
Get
Return m_NavigationPanelAppearance
End Get
End Property
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public ReadOnly Property TaskPanePages() As TaskPanePageCollection
Get
Return m_TaskPanePages
End Get
End Property
''' <summary>
''' Indicates whether the panel should have a border
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
<Description("Indicates whether the panel should have a border"), _
DefaultValue(GetType(BorderStyle), "None")> _
Public Shadows Property BorderStyle() As BorderStyle
Get
Return MyBase.BorderStyle
End Get
Set(ByVal value As BorderStyle)
' Apparently, the designer doesn't bother to re-calculate
' the control bounds when the border changes until a genuine
' resize event occurs. This override is intended to fix that
' problem.
MyBase.BorderStyle = value
Me.PerformLayout()
Me.Invalidate()
End Set
End Property
<DefaultValue(True)> _
Public Property AllowClose() As Boolean
Get
Return btnClose.Enabled
End Get
Set(ByVal value As Boolean)
btnClose.Enabled = value
End Set
End Property
<DefaultValue(True)> _
Public Property ShowClose() As Boolean
Get
Return btnClose.Visible
End Get
Set(ByVal value As Boolean)
btnClose.Visible = value
UpdateDropdownSize()
End Set
End Property
Private Function ShouldSerializeStartPane() As Boolean
Return m_HomePane IsNot Nothing
End Function
Public Property StartPane() As TaskPanePage
Get
Return m_HomePane
End Get
Set(ByVal value As TaskPanePage)
m_HomePane = value
Me.btnNavHome.Enabled = (btnToolTaskTools.Tag IsNot m_HomePane)
End Set
End Property
<DefaultValue(False)> _
Public Property ShowImageColumnInDropdown() As Boolean
Get
Return CType(btnToolTaskTools.DropDown, ToolStripDropDownMenu).ShowImageMargin
End Get
Set(ByVal value As Boolean)
CType(btnToolTaskTools.DropDown, ToolStripDropDownMenu).ShowImageMargin = value
End Set
End Property
#End Region
#Region " Constructor"
Public Sub New()
MyBase.New()
'This call is required by the Component Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
SetStyle(ControlStyles.ResizeRedraw, True)
SetStyle(ControlStyles.AllPaintingInWmPaint, True)
SetStyle(ControlStyles.SupportsTransparentBackColor, False)
Me.DoubleBuffered = True
MyBase.MinimumSize = m_HardMinimumSize
DirectCast(btnToolTaskTools.DropDown, ToolStripDropDownMenu).ShowCheckMargin = True
btnToolTaskTools.DropDownDirection = ToolStripDropDownDirection.BelowLeft
m_NavigationPanelAppearance = New NavigationPanelAppearance(pnlNavButtons)
AddHandler m_TaskPanePages.CollectionChanged, AddressOf TaskPaneToolCollectionChanged
UpdateCaptionStyle()
End Sub
#End Region
#Region " Overrides"
Private Function ShouldSerializeMinimumSize() As Boolean
Return MyBase.MinimumSize <> m_HardMinimumSize
End Function
Public Overrides Property MinimumSize() As System.Drawing.Size
Get
Return MyBase.MinimumSize
End Get
Set(ByVal value As System.Drawing.Size)
If value = MyBase.MinimumSize Then Return
If value.Width < m_HardMinimumSize.Width Then
value.Width = m_HardMinimumSize.Width
End If
If value.Height < m_HardMinimumSize.Height Then
value.Height = m_HardMinimumSize.Height
End If
MyBase.MinimumSize = value
End Set
End Property
Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
MyBase.OnResize(e)
UpdateDropdownSize()
End Sub
Protected Overrides Sub OnControlAdded(ByVal e As System.Windows.Forms.ControlEventArgs)
MyBase.OnControlAdded(e)
If Not e.Control Is toolStripToolsButtons AndAlso Not e.Control Is pnlNavButtons Then
e.Control.BringToFront()
End If
End Sub
Protected Overrides Sub OnControlRemoved(ByVal e As System.Windows.Forms.ControlEventArgs)
MyBase.OnControlRemoved(e)
If m_IsClearingCollection Then Return
If TypeOf (e.Control) Is TaskPanePage Then
Dim page As TaskPanePage = DirectCast(e.Control, TaskPanePage)
m_TaskPanePages.Remove(page)
End If
End Sub
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
MyBase.OnLoad(e)
GoHome()
End Sub
#End Region
#Region " Navigation Handlers"
Private Sub btnToolTaskTools_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles btnToolTaskTools.MouseDown
If Me.DesignMode Then
btnToolTaskTools.ShowDropDown()
End If
End Sub
Private Sub btnToolBack_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles btnToolBack.MouseDown, btnNavBack.MouseDown
If Me.DesignMode Then
Back()
End If
End Sub
Private Sub btnToolForward_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles btnToolForward.MouseDown, btnNavForward.MouseDown
If Me.DesignMode Then
[Next]()
End If
End Sub
Private Sub btnNavHome_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles btnNavHome.MouseDown
If Me.DesignMode Then
GoHome()
End If
End Sub
Private Sub btnClose_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles btnClose.MouseDown
If Me.DesignMode Then
MessageBox.Show("Close Clicked")
End If
End Sub
Private Sub Back_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnToolBack.Click, btnNavBack.Click
Back()
End Sub
Private Sub Forward_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnToolForward.Click, btnNavForward.Click
[Next]()
End Sub
Private Sub Home_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNavHome.Click
GoHome()
End Sub
Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
RaiseEvent TaskPaneCloseClick(Me, New EventArgs())
End Sub
#End Region
#Region " Methods"
#Region " Style Update Methods"
Private Sub UpdateDisplayStyles()
Select Case m_NavigationStyle
Case DisplayStyle.OfficeXP
btnToolBack.Visible = True
btnToolForward.Visible = True
pnlNavButtons.Visible = False
NavigationAreaSize = New Size(0, 0)
Case DisplayStyle.Office2003
btnToolBack.Visible = False
btnToolForward.Visible = False
pnlNavButtons.Visible = True
pnlNavButtons.BringToFront()
NavigationAreaSize = pnlNavButtons.Size
Case Else
' Nothing
End Select
UpdateCaptionStyle()
m_NavigationPanelAppearance.Style = m_NavigationStyle
If Me.DesignMode Then
Me.Invalidate()
End If
End Sub
Private Sub UpdateCaptionStyle()
Dim lblTxt As String = "No Tools Yet"
If m_TaskPanePages.Count > 0 Then
lblTxt = m_TaskPanePages(m_CurrentIndex).Caption
End If
Select Case m_CaptionStyle
Case DisplayStyle.OfficeXP
lblToolTaskCaption.Text = lblTxt
btnToolTaskTools.Text = ""
btnToolTaskTools.AutoSize = True
Case DisplayStyle.Office2003
btnToolTaskTools.Text = lblTxt
lblToolTaskCaption.Text = ""
btnToolTaskTools.AutoSize = False
Case Else
' Nothing
End Select
UpdateDropdownSize()
End Sub
Private Sub UpdateDropdownSize()
If m_CaptionStyle = DisplayStyle.Office2003 Then
btnToolTaskTools.AutoSize = False
' Calculate all non-dropdown space
Dim leftBound As Integer = btnToolBack.Width + btnToolBack.Margin.Horizontal _
+ btnToolForward.Width + btnToolForward.Margin.Horizontal _
+ lblToolTaskCaption.Width + lblToolTaskCaption.Margin.Horizontal _
+ btnClose.Width
If Not btnToolBack.Visible Then
leftBound = leftBound - btnToolBack.Width - btnToolBack.Margin.Horizontal
End If
If Not btnToolForward.Visible Then
leftBound = leftBound - btnToolForward.Width - btnToolForward.Margin.Horizontal
End If
If Not lblToolTaskCaption.Visible Then
leftBound -= lblToolTaskCaption.Width '- lblToolTaskCaption.Margin.Horizontal
'ElseIf lblToolTaskCaption.Width = 0 Then
' leftBound -= lblToolTaskCaption.Margin.Horizontal
End If
If Not btnClose.Visible Then
leftBound = leftBound - btnClose.Width
End If
' autosized label now
btnToolTaskTools.Width = toolStripToolsButtons.Width - leftBound - 1
If btnToolTaskTools.DropDown IsNot Nothing Then
' Temporarily allow the drop down to autosize
' This forces it to properly calculate its height
' from its dropdown items
btnToolTaskTools.DropDown.AutoSize = True
' Retake control of it to make it be full width.
btnToolTaskTools.DropDown.AutoSize = False
btnToolTaskTools.DropDown.Width = btnToolTaskTools.Width
End If
Else
btnToolTaskTools.AutoSize = True
If btnToolTaskTools.DropDown IsNot Nothing Then
btnToolTaskTools.DropDown.AutoSize = True
End If
End If
For Each item As TaskPanePage In m_TaskPanePages
item.Style = m_NavigationStyle
If m_CaptionStyle = DisplayStyle.Office2003 Then
item.MenuItem.AutoSize = False
item.MenuItem.Width = btnToolTaskTools.Width - 1
Else
item.MenuItem.AutoSize = True
End If
Next
End Sub
Private Sub UpdateCaption(ByVal caption As String, ByVal img As Image)
If m_CaptionStyle = DisplayStyle.OfficeXP Then
btnToolTaskTools.Text = ""
lblToolTaskCaption.Text = caption
Else
btnToolTaskTools.Text = caption
lblToolTaskCaption.Text = ""
End If
lblToolTaskCaption.Image = img
End Sub
Private Sub UpdateNavigationButtonStates()
Me.btnNavForward.Enabled = (m_CurrentIndex < btnToolTaskTools.DropDownItems.Count - 1)
Me.btnToolForward.Enabled = (m_CurrentIndex < btnToolTaskTools.DropDownItems.Count - 1)
Me.btnNavBack.Enabled = (m_CurrentIndex <> 0)
Me.btnToolBack.Enabled = (m_CurrentIndex <> 0)
If m_HomePane IsNot Nothing Then
Me.btnNavHome.Enabled = (btnToolTaskTools.Tag IsNot m_HomePane.MenuItem)
Else
Me.btnNavHome.Enabled = (m_CurrentIndex <> 0)
End If
End Sub
#End Region
Private Sub TaskPaneToolCollectionChanged(ByVal sender As Object, ByVal e As TaskPanePageCollectionChangedEventArgs)
If e.ChangeType = CollectionChangeType.Clear Then
m_IsClearingCollection = True
For Each tItem As TaskPanePage In m_TaskPanePages
Me.Controls.Remove(tItem)
Next
btnToolTaskTools.DropDownItems.Clear()
btnToolTaskTools.Enabled = False
m_IsClearingCollection = False
Return
End If
Select Case e.ChangeType
Case CollectionChangeType.Insert
CreateTaskPanePage(e.Index, e.Pane)
Case CollectionChangeType.Remove
RemoveTaskPanePage(e.Pane)
Case CollectionChangeType.Set
e.Pane.MenuItem.Text = e.Pane.Caption
e.Pane.MenuItem.Image = e.Pane.CaptionImage
End Select
End Sub
Private Sub RemoveTaskPanePage(ByVal pane As TaskPanePage)
Me.Controls.Remove(pane)
RemoveHandler pane.CaptionChanged, AddressOf PageCaptionChanged
RemoveHandler pane.CaptionImageChanged, AddressOf PageCaptionImageChanged
RemoveHandler pane.MenuItem.Click, AddressOf TaskMenuItemClicked
btnToolTaskTools.DropDownItems.Remove(pane.MenuItem)
If btnToolTaskTools.DropDownItems.Count = 0 Then
UpdateCaption("No Tools Yet", Nothing)
btnToolTaskTools.Enabled = False
pnlNavButtons.Parent = Me
pnlNavButtons.BringToFront()
pnlNavButtons.Location = New Point(0, btnToolTaskTools.Height)
Else
btnToolTaskTools.Enabled = True
If m_CurrentIndex = 0 Then
btnToolTaskTools.DropDownItems(m_CurrentIndex).PerformClick()
Else
btnToolTaskTools.DropDownItems(m_CurrentIndex - 1).PerformClick()
End If
End If
UpdateDropdownSize()
Me.Invalidate()
End Sub
Private Sub CreateTaskPanePage(ByVal idx As Integer, ByVal item As TaskPanePage)
Dim menu As New ToolStripMenuItem
menu.Text = item.Caption
menu.Tag = item
'menu.CheckOnClick = True
menu.Image = item.CaptionImage
menu.ImageScaling = ToolStripItemImageScaling.SizeToFit 'None?
item.MenuItem = menu
item.Style = m_NavigationStyle
If item.Caption.Length = 0 AndAlso item.Site IsNot Nothing Then
item.Caption = item.Site.Name
End If
AddHandler item.CaptionChanged, AddressOf PageCaptionChanged
AddHandler item.CaptionImageChanged, AddressOf PageCaptionImageChanged
AddHandler menu.Click, AddressOf TaskMenuItemClicked
Me.Controls.Add(item)
Me.Controls.SetChildIndex(item, idx)
btnToolTaskTools.DropDownItems.Add(menu)
btnToolTaskTools.Enabled = True
pnlNavButtons.BringToFront()
UpdateDropdownSize() ' autosizes dropdown if style is VisualStudio2005
UpdateNavigationButtonStates()
If m_NavigationStyle = DisplayStyle.Office2003 Then
menu.AutoSize = False
menu.Width = btnToolTaskTools.Width - 1
Else
menu.AutoSize = True
End If
' Automatically select this page
menu.PerformClick()
End Sub
Private Sub TaskMenuItemClicked(ByVal sender As Object, ByVal e As EventArgs)
Dim menu As ToolStripMenuItem = TryCast(sender, ToolStripMenuItem)
If menu Is Nothing Then Return
Dim page As TaskPanePage = TryCast(menu.Tag, TaskPanePage)
If page Is Nothing Then Return
SelectTaskPanePage(page)
End Sub
Private Sub PageCaptionChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim pane As TaskPanePage = TryCast(sender, TaskPanePage)
If pane Is Nothing Then Return
If btnToolTaskTools.DropDownItems.IndexOf(pane.MenuItem) = m_CurrentIndex Then
UpdateCaption(pane.Caption, pane.CaptionImage)
UpdateDropdownSize()
If Me.DesignMode Then
' refresh the control drop area text
Me.Invalidate()
End If
End If
End Sub
Private Sub PageCaptionImageChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim pane As TaskPanePage = TryCast(sender, TaskPanePage)
If pane Is Nothing Then Return
If btnToolTaskTools.DropDownItems.IndexOf(pane.MenuItem) = m_CurrentIndex Then
UpdateCaption(pane.Caption, pane.CaptionImage)
UpdateDropdownSize()
End If
End Sub
' Navigation
Public Sub Back()
If m_CurrentIndex > 0 AndAlso m_CurrentIndex < btnToolTaskTools.DropDownItems.Count Then
btnToolTaskTools.DropDownItems(m_CurrentIndex - 1).PerformClick()
End If
End Sub
Public Sub [Next]()
If m_CurrentIndex < btnToolTaskTools.DropDownItems.Count - 1 Then
btnToolTaskTools.DropDownItems(m_CurrentIndex + 1).PerformClick()
End If
End Sub
Public Sub GoHome()
If m_HomePane IsNot Nothing Then
m_HomePane.MenuItem.PerformClick()
ElseIf btnToolTaskTools.DropDownItems.Count > 0 Then
btnToolTaskTools.DropDownItems(0).PerformClick()
End If
End Sub
Public Sub SelectTaskPanePage(ByVal index As Integer)
If index >= 0 AndAlso index < m_TaskPanePages.Count Then
SelectTaskPanePage(m_TaskPanePages(index))
End If
End Sub
Public Sub SelectTaskPanePage(ByVal page As TaskPanePage)
Dim args As New CancelEventArgs
RaiseEvent SelectedIndexChanging(Me, args)
If args.Cancel Then
Return
End If
If page Is Nothing Then Return
If page.MenuItem Is Nothing Then Return
Dim menu As ToolStripMenuItem = page.MenuItem
' Uncheck all items
For Each mnu As ToolStripMenuItem In btnToolTaskTools.DropDownItems
mnu.Checked = False
Next
' Now set the current item
menu.Checked = True
btnToolTaskTools.Tag = menu
UpdateCaption(menu.Text, menu.Image)
m_CurrentIndex = btnToolTaskTools.DropDownItems.IndexOf(menu)
page.Visible = True
page.BringToFront()
pnlNavButtons.Parent = page
pnlNavButtons.Location = New Point(0, 1)
If pnlNavButtons.Visible Then
' Has the effect of putting controls Docked to the page
' at the top of the z-order, forcing them to not overlap
' the nav panel. This is because items at the bottom of the
' z-order are guaranteed to be displayed if items above it have
' an overlapping dock state.
pnlNavButtons.SendToBack()
End If
UpdateDropdownSize() ' autosizes dropdown if style is VisualStudio2005
UpdateNavigationButtonStates()
Me.Focus()
page.Focus()
RaiseEvent SelectedIndexChanged(Me, New EventArgs())
End Sub
#End Region
End Class