在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例桌面应用界面/GUI → C# 实现 outlookbar控件 示例完整源码下载 有截图 含UtilityLibrary以及完整源码

C# 实现 outlookbar控件 示例完整源码下载 有截图 含UtilityLibrary以及完整源码

桌面应用界面/GUI

下载此实例
  • 开发语言:C#
  • 实例大小:1.50M
  • 下载次数:131
  • 浏览次数:4533
  • 发布时间:2014-01-25
  • 实例类别:桌面应用界面/GUI
  • 发 布 人:星火燎原
  • 文件格式:.rar
  • 所需积分:2
 相关标签: 截图 C# OutLook 下载

实例介绍

【实例简介】包含outlookbar示例源码以及 含UtilityLibrary.dll以及 UtilityLibrary完整源码

【实例截图】

【核心代码】

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.Reflection;
using System.IO;
using System.Drawing.Design;

using UtilityLibrary.Collections;
using UtilityLibrary.Win32;
using UtilityLibrary.General;
using UtilityLibrary.Menus;

namespace UtilityLibrary.WinControls
{
		
	#region Delegates
	public delegate void OutlookBarPropertyChangedHandler(OutlookBarBand band, OutlookBarProperty property);
	public delegate void OutlookBarItemClickedHandler(OutlookBarBand band, OutlookBarItem item);
	public delegate void OutlookBarItemDroppedHandler(OutlookBarBand band, OutlookBarItem item);
	public delegate void OutlookBarIconViewChangedHandler(OutlookBarBand band);
	#endregion

	#region Enumerations
	public enum OutlookBarProperty
	{
		CurrentBandChanged,
		ShortcutNameChanged,
		GroupNameChanged
	}

	enum ItemSizeType
	{
		Icon,
		Label,
		All
	}

	public enum IconView
	{
		Small,
		Large
	}

	public enum HitTestType
	{
		UpScroll,
		DownScroll,
		Header,
		Item,
		DropLine,
		DropLineLastItem,
		Nothing
	}

	public enum ContextMenuType
	{
		Item,
		Header,
		Bar
	}

	public enum BorderType
	{
		None,
		FixedSingle,
		Fixed3D,
		Custom
	}
	#endregion

	#region OutlookBarBand class
	[ToolboxItem(false)]
	public class OutlookBarBand : Control
	{
		#region Class variables
		Control childControl = null;
        ImageList smallImageList = null;
		ImageList largeImageList = null;
		OutlookBarItemCollection items = null;
		Color background = ColorUtil.VSNetControlColor;
		Color textColor = SystemColors.ControlText;
		IconView iconView = IconView.Large;
		#endregion

		#region Events
		public event OutlookBarIconViewChangedHandler IconViewChanged;
		#endregion
						        		
		#region Constructors
		public OutlookBarBand(string text, Control childControl)
		{
			this.Text = text;
			this.childControl = childControl;
		}

		public OutlookBarBand(string text)
		{
			this.Text = text;
			// When using the constructor that just use the name,
			// it means that this band will have child items
			items = new OutlookBarItemCollection();
		}

		public OutlookBarBand()
		{
			// Constructor for designer support
			items = new OutlookBarItemCollection();
			if( this.Site!= null)
				Name = Site.Name;
			else
				Name = null;
		}
		#endregion

		#region Overrides
		protected override void Dispose( bool disposing )
		{
			if( items!= null)
				items.Clear();
			base.Dispose( disposing);
		}
		#endregion

		private void InitializeComponent()
		{

		}
        
		#region Properties
		public Control ChildControl
		{
			get { return childControl; }
		}

		public ImageList SmallImageList
		{
			set { smallImageList = value; }
			get { return smallImageList; }
		}

		public ImageList LargeImageList
		{
			set { largeImageList = value; }
			get { return largeImageList; }
		}

		public Color Background
		{
			set { background = value; }
			get { return background; }
		}

		public Color TextColor
		{
			set { textColor = value; }
			get { return textColor; }
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		public OutlookBarItemCollection Items
		{
			get { return items; }
		}

		public IconView IconView 
		{
			set { iconView = value; }
			get { return iconView; }
		}
		#endregion

		#region Methods
		#endregion

		#region Implementation
		void FireIconViewChanged()
		{
			if ( IconViewChanged != null )
			{
				IconViewChanged(this);
			}
		}
		#endregion
	
	}
	#endregion

	#region OutlookBar Item class
	[ToolboxItem(false)]
	public class OutlookBarItem : Component
	{
		#region Class variables
		string text;
        int imageIndex = -1;
		object tag;
		#endregion

		#region Events
		#endregion
		
		#region Constructors
		public OutlookBarItem(string text, int ImageIndex)
		{
			this.text = text;
			this.imageIndex = ImageIndex;
		}

		public OutlookBarItem(string text, int imageIndex, object tag)
		{
			this.text = text;
			this.imageIndex = imageIndex;
			tag = tag;
		}

		public OutlookBarItem()
		{
			// To support designer
			imageIndex = -1;
		}

		#endregion

		#region Overrides
		#endregion

		#region Methods 
		#endregion
		
		#region Properties
		public int ImageIndex
		{
			set { imageIndex = value; }
			get { return imageIndex; }
		}

		public string Text
		{
			set { text = value; }
			get { return text; }
		}

		public object Tag
		{
			set { tag = value; }
			get { return tag; }
		}

		#endregion

		#region Implementation
		#endregion
	}
	#endregion

    #region OutlookBar class
	[ToolboxBitmap(typeof(UtilityLibrary.WinControls.OutlookBar), 
    "UtilityLibrary.WinControls.OutlookBar.bmp")]
	public class OutlookBar : System.Windows.Forms.Control
	{
		
		#region Class variables
		const int BAND_HEADER_HEIGHT = 22;
		int currentBandIndex = -1;
		BorderType borderType = BorderType.None;
		int firstItem = 0;
		int lastHighlightedHeader = -1;
		int lastHighlightedItem = -1;
		Rectangle upArrowRect;
		Rectangle downArrowRect;
		DrawState upArrowDrawState = DrawState.Normal;
		DrawState downArrowDrawState = DrawState.Normal;
		bool upArrowVisible = false;
		bool downArrowVisible = false;
		bool upArrowPressed = false;
		bool downArrowPressed = false;
		bool upTimerTicking = false;
		bool downTimerTicking = false;
		bool doScrollingLoop = false;
		bool buttonPushed = false;
		Bitmap backgroundBitmap = null;
		bool needBackgroundBitmapResize = true;
		bool flatArrowButtons = false;
			
		// Custom Border colors
		Color leftTopColor = Color.Empty;
		Color rightBottomColor = Color.Empty;
		
		// Context Menus
		ContextMenu contextMenu = null;
		Point lastClickedPoint = Point.Empty;
		
		int selectedHeader = -1;
		System.Windows.Forms.Timer highlightTimer = new System.Windows.Forms.Timer();
		bool previousPressed = false;
		int animationSpeed = 20;
		Cursor dragCursor = null;
		int lastDrawnLineIndex = -1;
        bool paintedDropLineLastItem = false;
		int droppedPosition = -1;
		bool forceHightlight = false;
		int forceHightlightIndex = -1;
		
		// For in place editing of the 
		TextBoxEx textBox = new TextBoxEx();
		bool editingAnItem = false;
        						
		const int X_SMALLICON_LABEL_OFFSET = 2;
		const int Y_LARGEICON_LABEL_OFFSET = 3;
		const int Y_SMALLICON_SPACING = 10;
		const int Y_LARGEICON_SPACING = 8;
		const int LEFT_MARGIN = 5;
		const int LARGE_TOP_MARGIN = 10;
		const int SMALL_TOP_MARGIN = 6;
		const int ARROW_BUTTON_MARGIN = 5;

		// Flat Arrow Buttons helpers
		DrawState upFlatArrowState = DrawState.Normal;
		DrawState downFlatArrowState = DrawState.Normal;
		
		// Bands
		OutlookBarBandCollection bands = null;
		#endregion

		#region Events
		public event OutlookBarPropertyChangedHandler PropertyChanged;
		public event OutlookBarItemClickedHandler ItemClicked;
		public event OutlookBarItemDroppedHandler ItemDropped;
		#endregion
				
		#region Constructors
		public OutlookBar()
		{
            // Construct band collection
			bands = new OutlookBarBandCollection(this);

			Dock = DockStyle.Left;
			// We are going to do all of the painting so better setup the control
			// to use double buffering
			SetStyle(ControlStyles.AllPaintingInWmPaint|ControlStyles.ResizeRedraw
				|ControlStyles.Opaque|ControlStyles.UserPaint|ControlStyles.DoubleBuffer, true);
			Font = SystemInformation.MenuFont;
			
			CreateContextMenu();

			// Setup timer
			highlightTimer.Tick  = new EventHandler(OnHighlightHeader);
			highlightTimer.Interval = 100;

			// Load drag cursor
			Assembly myAssembly = Assembly.GetAssembly(Type.GetType("UtilityLibrary.WinControls.OutlookBar"));
            Stream cursorStream = myAssembly.GetManifestResourceStream("UtilityLibrary.Resources.DragCursor.cur");
			dragCursor = new Cursor(cursorStream);
               
			// don't display it until we need to
			textBox.Visible = false;
			// Hook up notification for the Enter and LostFocus events
			textBox.KeyUp  = new KeyEventHandler(TextBoxKeyDown);
			textBox.LostFocus  = new EventHandler(TextBoxLostFocus);

		}
		#endregion

		#region Overrides
		protected override Size DefaultSize
		{
			get { return new Size(100, 10); }
		}

		protected override void OnPaint(PaintEventArgs pe)
		{
			base.OnPaint(pe);
			Graphics g = pe.Graphics;
			
			// Manipulate child window in case there is one
			if ( currentBandIndex == -1 && bands.Count > 0)
				SetCurrentBand(0);
			
			// Background if it needs to be painted
			DrawBackground(g);
			// If we have a border
			DrawBorder(g);
			// The little headers
			DrawHeaders(g);
			
			// If there is a child window
			// it will paint itself, otherwise we do the painting
			if ( !HasChild() )
			{
				// The items themselves
				DrawItems(g, Rectangle.Empty, null);

				// The buttons for scrolling items
				// Drawing second so that they don't get written over by the items
				DrawArrowButtons(g);
			}

			// Highlight last item clicked
			if ( forceHightlight )
			{
                ForceHighlightItem(g, forceHightlightIndex);
				forceHightlight = false;
			}

		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			base.OnMouseDown(e);
			// If the textbox is being displayed cancel editing
			if ( textBox.Visible )
			{
				ProcessTextBoxEditing();
				return;
			}

			int index;
			HitTestType ht = HitTest(new Point(e.X, e.Y), out index, false);
			if ( e.Button == MouseButtons.Left)
			{
				// Handle arrow button hit
				if( ht == HitTestType.UpScroll || ht == HitTestType.DownScroll)
				{
					if ( ht == HitTestType.UpScroll )
					{
						ProcessArrowScrolling(upArrowRect,   
							ref upArrowVisible, ref upArrowPressed, ref upTimerTicking);
						return;
					}
					else
					{
						ProcessArrowScrolling(downArrowRect, 
							ref downArrowVisible, ref downArrowPressed, ref downTimerTicking);
						return;
					}
				}
                
				// Handle header hit
				if ( ht == HitTestType.Header )
				{
					ProcessHeaderHit(index);
					return;
				}

				// Handle item hit
				if ( ht == HitTestType.Item )
				{
					ProcessItemHit(index, new Point(e.X, e.Y));
					return;
				}
			}
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			base.OnMouseMove(e);
           		
			Point MousePos = new Point(e.X, e.Y);

			// Change cursor if over a header
			int index;
			HitTestType ht = HitTest(MousePos, out index, false);

			if ( ht != HitTestType.Header && lastHighlightedHeader >=0 )HighlightHeader(-1);			
			if ( ht != HitTestType.Item  && lastHighlightedItem  >= 0 ) HighlightItem(-1, false);
			
			if ( upArrowDrawState == DrawState.Hot && ht != HitTestType.UpScroll
				|| flatArrowButtons )
				if ( flatArrowButtons )
					if ( upArrowVisible && UpFlatArrowState != DrawState.Normal)
						DrawArrowButton(upArrowRect, ButtonState.Normal);
				else
					DrawArrowButton(upArrowRect, ButtonState.Normal);
			if ( downArrowDrawState == DrawState.Hot && ht == HitTestType.DownScroll
				|| flatArrowButtons )
				if ( flatArrowButtons )
					if ( downArrowVisible && DownFlatArrowState != DrawState.Normal )
						DrawArrowButton(downArrowRect, ButtonState.Normal);
				else
                    DrawArrowButton(downArrowRect, ButtonState.Normal);

			if ( ht == HitTestType.Header )
			{
				Cursor.Current = Cursors.Hand;
				HighlightHeader(index);
				highlightTimer.Start();
			}
			else if (ht == HitTestType.Item )
			{
				HighlightItem(index, false);
				highlightTimer.Start();
			}
			else if ( ht == HitTestType.UpScroll )
			{
				if ( flatArrowButtons 
					&& upArrowVisible )
				{
					if ( UpFlatArrowState != DrawState.Hot )
						DrawArrowButton(upArrowRect, ButtonState.Pushed);
				}
			}
			else if ( ht == HitTestType.DownScroll )
			{
				if ( flatArrowButtons
					&& downArrowVisible)
				{
					if ( DownFlatArrowState != DrawState.Hot )
						DrawArrowButton(downArrowRect, ButtonState.Pushed);
				}
			}
		}

		protected override void OnSizeChanged(EventArgs e)
		{
			base.OnSizeChanged(e);
			if ( HasChild() )
			{
				Rectangle rc = GetViewPortRect();
				OutlookBarBand newBand = bands[currentBandIndex];
				Control childControl = newBand.ChildControl;
				childControl.Bounds = rc;
			}

			// flag that we need to update the bitmap background
			// if there is one
			needBackgroundBitmapResize = true;
		}

		protected override void OnHandleCreated(EventArgs e)
		{
			base.OnHandleCreated(e);
			// Make text box a child of the outlookbar control
			WindowsAPI.SetParent(textBox.Handle, Handle);
		}

		protected override  void WndProc(ref Message m)
		{
			bool callBase = true;
			switch(m.Msg)
			{
				case ((int)Msg.WM_CONTEXTMENU):
				{
					Point pt = WindowsAPI.GetPointFromLPARAM((int)m.LParam);
					pt = PointToClient(pt);
					Rectangle viewPortRect = GetViewPortRect();
					
					// Save the point so that we can update our popup menu correctly
					lastClickedPoint = pt;
                    
					// If the user click on the child window don't
					// show a context menu
					if ( HasChild() && viewPortRect.Contains(pt)) 
					{
						callBase = false;
						break;
					}
				}
					break;
				default:
					break;
			}

			if ( callBase )
				base.WndProc(ref m);
		
		}
		#endregion

        #region Properties
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		public OutlookBarBandCollection Bands
		{
			get { return bands; }
		}

		public BorderType BorderType 
		{
			set { borderType = value; }
			get { return borderType; }
		}

		public int AnimationSpeed  
		{
			set { animationSpeed = value; }
			get { return animationSpeed; }
		}

		public Color LeftTopColor  
		{
			set { leftTopColor = value; }
			get { return leftTopColor; }
		}

		public Color RightBottomColor  
		{
			set { rightBottomColor = value; }
			get { return rightBottomColor; }
		}

		public Bitmap BackgroundBitmap
		{
			set 
			{ 
				backgroundBitmap = value; 
				needBackgroundBitmapResize = true;
			}
			get { return backgroundBitmap; }
		}

		public bool FlatArrowButtons
		{
			set { flatArrowButtons = value; }
			get { return flatArrowButtons; }
		}

		internal DrawState UpFlatArrowState
		{
			set { upFlatArrowState = value; }
			get { return upFlatArrowState; }
		}

		internal DrawState DownFlatArrowState
		{
			set { downFlatArrowState = value; }
			get { return downFlatArrowState; }
		}
		#endregion

		#region Methods
		public HitTestType HitTest(Point point, out int index, bool doingDragging)
		{
			
			// If we don't have any bands just return
			index = 0;
			if ( bands.Count == 0 || currentBandIndex == -1 )	return HitTestType.Nothing;
					
			// Check if we hit the arrow buttons
			if (upArrowVisible && upArrowRect.Contains(point)) return HitTestType.UpScroll;
			if (downArrowVisible && downArrowRect.Contains(point)) return HitTestType.DownScroll;

			// Check to see if we hit a header
			for ( int i = 0; i < bands.Count; i   )
			{
				Rectangle rc = GetHeaderRect(i);
				if ( rc.Contains(point) )
				{
					index = i;
					return HitTestType.Header;
				}
			}

			// Don't do any hit testing for items if
			// the current band has a child
			if ( HasChild() ) return HitTestType.Nothing;

			// Check to see if we hit an item
			int itemCount = bands[currentBandIndex].Items.Count;
			Rectangle viewPortRect = GetViewPortRect();
			Rectangle iconRect = Rectangle.Empty;
			Rectangle labelRect = Rectangle.Empty;
			for ( int i = firstItem; i < itemCount; i   )
			{
				// Check if we hit the icon
				iconRect = GetIconRect(i);
				if ( iconRect.Contains(point) )
				{
					index = i;
					return HitTestType.Item;
				}
				else
					if ( iconRect.Bottom > viewPortRect.Bottom && !doingDragging) break;

				// Check to see if we hit the label
				labelRect = GetLabelRect(i);
				if ( labelRect.Contains(point) )
				{
					index = i;
					return HitTestType.Item;
				}
				else
					if ( labelRect.Bottom > viewPortRect.Bottom && !doingDragging) break;

				// If we are dragging, hit test for the drop line
				if ( doingDragging )
				{
					Rectangle dragRect = new Rectangle(viewPortRect.Left, iconRect.Top - Y_LARGEICON_SPACING,
						viewPortRect.Width, Y_LARGEICON_SPACING);
						
					if ( dragRect.Contains(point) )
					{
						index = i;
						return HitTestType.DropLine;
					}

					// if this is the last icon and the point is farther down the last item
					if ( (i == itemCount - 1) && point.Y > labelRect.Bottom )
					{
						index = itemCount - 1;
						return HitTestType.DropLineLastItem;
					}
				}
			}
			
			return HitTestType.Nothing;

		}

		public Rectangle GetItemRect(Graphics g, OutlookBarBand band, int index, Rectangle targetRect)
		{
			Rectangle rc = GetViewPortRect();
			if ( targetRect != Rectangle.Empty ) rc = targetRect;
			Size itemSize = new Size(0,0);
			int top = rc.Top;
			int y = 0;
			for ( int i = 0; i < index; i   )
			{
				itemSize = GetItemSize(g, band, i, ItemSizeType.All);
				top  = itemSize.Height;
				if ( band.IconView == IconView.Small )
					top  = Y_SMALLICON_SPACING;
				else
					top  = Y_LARGEICON_SPACING;
				if ( i == (firstItem - 1) )
				{
					// Subtract the hidden items height
					y = top - rc.Top;
				}
			}

			itemSize = GetItemSize(g, band, index, ItemSizeType.All);
			int margin = SMALL_TOP_MARGIN;
			if ( band.IconView == IconView.Large )
				margin = LARGE_TOP_MARGIN;

			// Work with Windows Rect is easier to change settings
			RECT rcItem = new RECT();
			rcItem.left = rc.Left;
			rcItem.top = top;
			rcItem.right = rc.Left   itemSize.Width;
			rcItem.bottom = top   itemSize.Height;

			// Adjust rectangle
			rcItem.top -= y;
			rcItem.bottom -= y;
			rcItem.top  = margin;
			rcItem.bottom  = margin;
			
			if ( band.IconView == IconView.Small )
			{
				rcItem.left  = rc.Left   LEFT_MARGIN;
				rcItem.right = rc.Right;
			}

			// Construct final rectangle
			Rectangle actualRect = new Rectangle(rcItem.left,  
				rcItem.top, rcItem.right - rcItem.left, rcItem.bottom - rcItem.top);
			       
			return actualRect;
		}
		public void ProcessOnMouseDown(MouseEventArgs e)
		{
			// To be used from the designer
			OnMouseDown(e);
		}

		public void OnContextMenu(object sender, EventArgs e)
		{
			OutlookBarBand band = bands[currentBandIndex];

			if (typeof(MenuItemEx).IsInstanceOfType(sender)) 
			{
				MenuItemEx item = (MenuItemEx)sender;
				if ( item.Text == "Large Icons")
				{
					band.IconView = IconView.Large;
					item.RadioCheck = true;
					contextMenu.MenuItems[1].RadioCheck = false;
				}
				else if ( item.Text == "Small Icons")
				{
					item.RadioCheck = true;
					band.IconView = IconView.Small;
					contextMenu.MenuItems[0].RadioCheck = false;
				}
				else if ( item.Text == "Rename Shortcut" )
				{
					RenameItem();
				}
				else if ( item.Text == "Rename Group" )
				{
					RenameHeader();
				}
			}
			Invalidate();
		}

		public int GetCurrentBand()
		{
			return currentBandIndex;
		}

		public void SetCurrentBand(int index)
		{
			// If in design mode and index equals -1 just don't do anything
			if ( DesignMode && index == -1 )
				return;

			// Make sure index is valid
			Debug.Assert(index >= 0 && index < bands.Count, "Invalid Band Index");
			// Don't do anything if requested to set it to the same one
			if ( currentBandIndex == index)
				return;
						
			// Hide current child control if any
			Control childControl;
			if ( currentBandIndex != -1 && bands.Count > 0)
			{
				OutlookBarBand oldBand = bands[currentBandIndex];
				childControl = oldBand.ChildControl;
				if ( childControl != null )
					childControl.Visible = false;
			}

			// Animate showing the new band
			if ( index != currentBandIndex )
			{
				AnimateScroll(currentBandIndex, index);
			}

			// Reset parameter
			currentBandIndex = index;
			firstItem = 0;
			lastHighlightedItem = -1;

			OutlookBarBand newBand = bands[currentBandIndex];
			childControl = newBand.ChildControl;
			if ( childControl != null )
			{
				// Make the outlookbar the parent of the child control
				// so that when we change the bounds of the control they
				// would be relative to the parent control
				// Don't do this every time since it causes flickering
				IntPtr hParent = WindowsAPI.GetParent(childControl.Handle);
				if ( hParent != Handle )
				{
					WindowsAPI.SetParent(childControl.Handle, Handle);

					// Hook up into control recreation
					childControl.HandleCreated  = new EventHandler(HandleRecreated);
				}
				
				Rectangle rc = GetViewPortRect();
				childControl.Bounds = rc;
				childControl.Visible = true;
				childControl.Focus();
			}

			// update the bar
			Invalidate();

			// Fire property changed
			FirePropertyChanged(OutlookBarProperty.CurrentBandChanged);

		}

		#endregion

		#region Implementation
		void ProcessArrowScrolling(Rectangle arrowButton, ref bool arrowVisible, ref bool arrowPressed, ref bool timerTicking)
		{
			
			// Capture the mouse
			Capture = true;
			// Draw the arrow button pushed
			timerTicking = true;
			// Draw pushed button
			buttonPushed = true;
			DrawArrowButton(arrowButton, ButtonState.Pushed);
			
			// Start timer
			System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
			timer.Tick  = new EventHandler(ScrollingTick);
			timer.Interval = 300;
			timer.Start();
             
			doScrollingLoop = true;           
			while ( doScrollingLoop ) 
			{
				// Check messages until we find a condition to break out of the loop
				Win32.MSG msg = new Win32.MSG();
				WindowsAPI.GetMessage(ref msg, 0, 0, 0);
				Point point = new Point(0,0);
				if ( msg.message == (int)Msg.WM_MOUSEMOVE || msg.message == (int)Msg.WM_LBUTTONUP )
				{
					point = WindowsAPI.GetPointFromLPARAM((int)msg.lParam);
				}

				switch(msg.message)
				{
					case (int)Msg.WM_MOUSEMOVE:
					{
						if ( arrowButton.Contains(point) )
						{
							if ( !buttonPushed )
							{
								DrawArrowButton(arrowButton, ButtonState.Pushed);
								arrowVisible =  true;
								arrowPressed = true;
								buttonPushed =  true;
							}
						}
						else
						{
							if ( buttonPushed )
							{
								DrawArrowButton(arrowButton, ButtonState.Normal);
								arrowVisible =  false;
								arrowPressed = false;
								buttonPushed =  false;
							}
						}
						break;
					}
					case (int)Msg.WM_LBUTTONUP:
					{
						if ( buttonPushed )
						{
							if ( !flatArrowButtons )
							{
								// Only if using regular buttons
								DrawArrowButton(arrowButton, ButtonState.Normal);
							}
							buttonPushed =  false;
						}
						arrowVisible = false;
						if ( arrowButton.Contains(point) ) 
						{
							if ( arrowButton.Equals(upArrowRect) )
							{
								if ( firstItem > 0 )
								{
									firstItem--;
									Rectangle rc = GetViewPortRect();
									Invalidate(rc);
								}
							}
							else if ( arrowButton.Equals(downArrowRect) )
							{
								using ( Graphics g = Graphics.FromHwnd(Handle) )
								{
									// Get the last item rectangle
									OutlookBarBand band = bands[currentBandIndex];
									if ( band != null )
									{
										Rectangle rcItem = GetItemRect(g, band, band.Items.Count - 1, Rectangle.Empty);
										Rectangle rc = GetViewPortRect();
										if ( rcItem.Bottom > rc.Bottom )
										{
											firstItem  ;
											Invalidate(rc);
										}
									}
								}
							}
						}
						doScrollingLoop = false;
						break;
					}
					case (int)Msg.WM_KEYDOWN:
					{
						if ( (int)msg.wParam == (int)VirtualKeys.VK_ESCAPE) 
							doScrollingLoop = false;
						break;
					}
					default:
						WindowsAPI.DispatchMessage(ref msg);
						break;
				}
			}

			// Release the capture
			Capture = false;
			// Stop timer
			timer.Stop();
			timer.Dispose();
			// Reset flags
			arrowVisible = false;
			arrowPressed = false;
			timerTicking = false;
			Rectangle viewPortRect = GetViewPortRect();
			Invalidate(viewPortRect);
		
		}

		void ScrollingTick(Object timeObject, EventArgs eventArgs) 
		{
			// Get mouse coordinates
			Point point = Control.MousePosition;
			point = PointToClient(point);

			if ( upTimerTicking )
			{
				if ( buttonPushed )
				{
					if ( upArrowRect.Contains(point))
					{
						upArrowPressed = true;
						if ( firstItem > 0 )
						{
							firstItem--;
							Rectangle rc = GetViewPortRect();
							Invalidate(rc);
						}
						else
							doScrollingLoop = false;
					}
					else
						upArrowPressed = false;
				}
			}
			else if ( downTimerTicking )
			{
				if ( buttonPushed )
				{
					if ( downArrowRect.Contains(point))
					{
						downArrowPressed = true;
						using ( Graphics g = Graphics.FromHwnd(Handle) )
						{
							// Get the last item rectangle
							OutlookBarBand band = bands[currentBandIndex];
							Rectangle rcItem = GetItemRect(g, band, band.Items.Count - 1, Rectangle.Empty);
							Rectangle rc = GetViewPortRect();
							if ( rcItem.Bottom > rc.Bottom )
							{
								firstItem  ;
								Invalidate(rc);
							}
						}
					}
					else
						doScrollingLoop = false;
				}
				else
					downArrowPressed = false;
			}

		}

		void ProcessHeaderHit(int index)
		{
			Capture = true;
			Rectangle rc = GetHeaderRect(index);
			// Draw header pressed
			Graphics g = Graphics.FromHwnd(Handle);
			bool headerPressed = true;
			DrawHeader(g, index, rc, Border3DStyle.Sunken);
			            
			bool doLoop = true;
			while (doLoop)
			{
				// Check messages until we find a condition to break out of the loop
				Win32.MSG msg = new Win32.MSG();
				WindowsAPI.GetMessage(ref msg, 0, 0, 0);
				Point point = new Point(0,0);
				if ( msg.message == (int)Msg.WM_MOUSEMOVE || msg.message == (int)Msg.WM_LBUTTONUP )
				{
					point = WindowsAPI.GetPointFromLPARAM((int)msg.lParam);
				}

				switch(msg.message)
				{
					case (int)Msg.WM_MOUSEMOVE:
					{
						int currentIndex;
						HitTestType hit = HitTest(point, out currentIndex, false);
						if (hit == HitTestType.Header && currentIndex == index)
						{
							if (!headerPressed)
							{
								DrawHeader(g, index, rc, Border3DStyle.Sunken);
								headerPressed = true;
							}
						}
						else
						{
							if (headerPressed)
							{
								DrawHeader(g, index, rc, Border3DStyle.RaisedInner);
								headerPressed = false;
							}
						}
						break;
					}
					case (int)Msg.WM_LBUTTONUP:
					{
						if (headerPressed)
						{
							DrawHeader(g, index, rc, Border3DStyle.RaisedInner);
							headerPressed = false;
						}
						int newIndex;
						HitTestType ht = HitTest(point, out newIndex, false);
						if ( ht == HitTestType.Header && newIndex != selectedHeader )
							SetCurrentBand(newIndex);
						doLoop = false;
						break;
					}
					case (int)Msg.WM_KEYDOWN:
					{
						if ( (int)msg.wParam == (int)VirtualKeys.VK_ESCAPE) 
							doLoop = false;
						break;
					}
					default:
						WindowsAPI.DispatchMessage(ref msg);
						break;
				}
			}

			// Reset flags
			Capture = false;
			g.Dispose();
			
		}

		void ProcessItemHit(int index, Point pt)
		{
			bool itemPressed = true;
			Capture = true;
			Graphics g = Graphics.FromHwnd(Handle);
            Rectangle itemRect = GetItemRect(g, bands[currentBandIndex], index, Rectangle.Empty);
			DrawItem(g, index, itemRect, true, true, Rectangle.Empty, null);
			bool dragging = false;
			int deltaX = 0;
			int deltaY = 0;
			bool itemHighlighted = false;
			int dragItemIndex = -1;
            			            
			bool doLoop = true;
			while ( doLoop )
			{
				// Check messages until we find a condition to break out of the loop
				Win32.MSG msg = new Win32.MSG();
				WindowsAPI.GetMessage(ref msg, 0, 0, 0);
				Point point = new Point(0,0);
				if ( msg.message == (int)Msg.WM_MOUSEMOVE || msg.message == (int)Msg.WM_LBUTTONUP )
				{
					point = WindowsAPI.GetPointFromLPARAM((int)msg.lParam);
					if ( msg.message == (int)Msg.WM_MOUSEMOVE )
					{
						deltaX = pt.X - point.X;
						deltaY = pt.Y - point.Y;
					}
				}

				switch(msg.message)
				{
					case (int)Msg.WM_MOUSEMOVE:
					{
						int currentIndex;
                        HitTestType hit = HitTest(point, out currentIndex, dragging);
						if ( dragging ) 
						{
							
							if ( hit == HitTestType.DropLine || hit == HitTestType.DropLineLastItem  )
							{
								Cursor.Current = dragCursor;
								// Draw the Dragline
                                DrawDropLine(g, currentIndex, true, hit);
							}
							else
							{
								Cursor.Current = Cursors.No;
								// Erase the Dragline
								DrawDropLine(g, index, false, hit);
							}
							
							if ( hit == HitTestType.Item && currentIndex == index)
							{
								if ( itemHighlighted == false )
								{
									DrawItem(g, index, itemRect, 
										true, false, Rectangle.Empty, null);
									itemHighlighted = true;                                
								}
							}
							else 
							{
								if ( hit == HitTestType.Item )
								{
									
									// Erase previous highlighting first
									if ( itemHighlighted ) 
									{ 
										DrawItem(g, index, itemRect, 
											false, false, Rectangle.Empty, null);
									}
									
									// Highlight new item
									itemRect = GetItemRect(g, bands[currentBandIndex], currentIndex, Rectangle.Empty);
									index = currentIndex;
									DrawItem(g, index, itemRect, 
										true, false, Rectangle.Empty, null);
								}
								else 
								{
									// the mouse did not hit an item
									if ( itemHighlighted ) 
									{
										DrawItem(g, index, itemRect, 
											false, false, Rectangle.Empty, null);
										itemHighlighted = false;
									}
								}
							}
						}
						else 
						{
							if (hit == HitTestType.Item && currentIndex == index)
							{
								
								// Set no drag cursor if there have been at least
								// a 5 pixel movement
								int pixelmov = 5;
								if ( bands[currentBandIndex].IconView == IconView.Small ) pixelmov = 2;
								bool unpressed = false;
								if ( Math.Abs(deltaX) >= pixelmov || Math.Abs(deltaY) >= pixelmov )
								{
									unpressed = true;
									Cursor.Current = Cursors.No;
									dragging = true;
									dragItemIndex = index;
								}
								
								if (itemPressed && unpressed)
								{
									DrawItem(g, index, itemRect, 
										true, false, Rectangle.Empty, null);
									itemPressed = false;
									itemHighlighted = true;
								}
							}
						}
						break;
					}
					case (int)Msg.WM_LBUTTONUP:
					{
						
						// Highlight the item
						if (itemPressed)
						{
							DrawItem(g, index, itemRect, true, false, Rectangle.Empty, null);
							itemPressed = false;
						}

						int newIndex;
						HitTestType ht = HitTest(point, out newIndex, true);
						bool doDrop = false;
						if ( dragging && (ht == HitTestType.DropLine || ht == HitTestType.DropLineLastItem) )
						{
                            // Delete dropline
							Cursor.Current = Cursors.Default;
							// Erase the Dragline
							DrawDropLine(g, index, false, ht);

							// Move the dragged item to the new location
							// only if the new location is not contiguous to its
							// own location
							if ( dragItemIndex > droppedPosition 
								&& Math.Abs(dragItemIndex - droppedPosition) > 0 )
								doDrop = true;
							else if ( dragItemIndex < droppedPosition 
								&& Math.Abs(dragItemIndex - droppedPosition) > 1 )
								doDrop = true;

							if ( doDrop )
							{
                                // Remove item from its old location
								OutlookBarItem dragItem = bands[currentBandIndex].Items[dragItemIndex];
								bands[currentBandIndex].Items.RemoveAt(dragItemIndex);
								// Insert item in its new location
								if ( dragItemIndex < droppedPosition )
									droppedPosition--;
								
								bands[currentBandIndex].Items.Insert(droppedPosition, dragItem);
							}
						}
						
						// Repaint the bar just in case we had a dropline painted
						Invalidate();
						
						// Highlight item
						if ( !dragging )
						{
							// do not highlight if we are dropping
							forceHightlight = true;
							forceHightlightIndex = index;
							// Fire item clicked property
							FireItemClicked(index);
						}
						else
						{
							// Fire item dropped event
							if ( droppedPosition != -1 && doDrop )
								FireItemDropped(droppedPosition);
						}
						
						doLoop = false;
						break;
					}
					case (int)Msg.WM_KEYDOWN:
					{
						if ( (int)msg.wParam == (int)VirtualKeys.VK_ESCAPE) 
							doLoop = false;
						break;
					}
					default:
						WindowsAPI.DispatchMessage(ref msg);
						break;
				}
			}

			g.Dispose();
			Capture = false;
		}

		void DrawDropLine(Graphics g, int index, bool drawLine, HitTestType hit)
		{
			Brush brush;
			Pen pen;
			if ( drawLine )
			{
				droppedPosition  = index;
				lastDrawnLineIndex = index;
				brush = SystemBrushes.ControlText;
				pen = SystemPens.ControlText;
			}
			else
			{
				// If there is nothing painted, no need to erase
				if ( lastDrawnLineIndex == -1) return;

				index = lastDrawnLineIndex;
				brush = new SolidBrush(bands[currentBandIndex].Background);
				pen = new Pen(bands[currentBandIndex].Background);
				lastDrawnLineIndex = -1;
			}

			int itemsCount = bands[currentBandIndex].Items.Count;
            Rectangle itemRect = GetItemRect(g, bands[currentBandIndex], index, Rectangle.Empty);

			Rectangle viewPortRect = GetViewPortRect();
			int y;
			if  ( bands[currentBandIndex].IconView == IconView.Small)
				y = itemRect.Top - Y_SMALLICON_SPACING/2;
			else
				y = itemRect.Top - Y_LARGEICON_SPACING;
			
			if ( hit == HitTestType.DropLineLastItem )
			{
				// use the bottom of the label if dealing with the last item
				Rectangle labelRect = GetLabelRect(itemsCount-1);
				y = labelRect.Bottom   Y_LARGEICON_SPACING;
				paintedDropLineLastItem = true;
				// the none existing item index
				droppedPosition = itemsCount;

			}
			else if ( paintedDropLineLastItem )
			{
				Rectangle labelRect = GetLabelRect(itemsCount-1);
				y = labelRect.Bottom   Y_LARGEICON_SPACING;
				paintedDropLineLastItem = false;
			}

			// If we are using a bitmap background, erase
			// by painting the portion of the bitmap background
			if ( backgroundBitmap != null && lastDrawnLineIndex == -1 )
			{
                Rectangle rcStrip = new Rectangle(viewPortRect.Left, y-6, viewPortRect.Width, 12);
                g.DrawImage(backgroundBitmap, rcStrip, rcStrip, GraphicsUnit.Pixel);
				return;
			}
			
			// Draw horizontal line
			Point p1 = new Point(viewPortRect.Left 11, y);
			Point p2 = new Point(viewPortRect.Right-11, y);
			g.DrawLine(pen, p1, p2);
            
			// Draw left triangle
			Point top;
			Point bottom;
			if ( index == firstItem )
				top = new Point(viewPortRect.Left 5, y);
			else
				top = new Point(viewPortRect.Left 5, y-6);

			if ( hit == HitTestType.DropLineLastItem )
				bottom =  new Point(viewPortRect.Left 5, y 1);
			else
				bottom = new Point(viewPortRect.Left 5, y 6);

			Point middle = new Point(viewPortRect.Left 11, y);
			Point[] points = new Point[3];
			points.SetValue(top, 0);
			points.SetValue(middle, 1);
			points.SetValue(bottom, 2);
			g.FillPolygon(brush, points);

			// Draw right triangle
			if ( index == firstItem )
				top = new Point(viewPortRect.Right-5, y);
			else
				top = new Point(viewPortRect.Right-5, y - 6);

			if ( hit == HitTestType.DropLineLastItem  )
				bottom = new Point(viewPortRect.Right-5, y 1);
			else
				bottom = new Point(viewPortRect.Right-5, y   6);
 
			middle = new Point(viewPortRect.Right-11, y);
			points.SetValue(top, 0);
			points.SetValue(middle, 1);
			points.SetValue(bottom, 2);
			g.FillPolygon(brush, points);

			if ( !drawLine )
			{
				brush.Dispose();
				pen.Dispose();
			}

		}

		void HighlightHeader(int index)
		{
			if ( lastHighlightedHeader == index ) return;
            
			Graphics g = Graphics.FromHwnd(Handle);
			Rectangle rc;
			if ( lastHighlightedHeader >= 0 )
			{
				rc = GetHeaderRect(lastHighlightedHeader);
				DrawHeader(g, lastHighlightedHeader, rc, Border3DStyle.RaisedInner);
			}

			lastHighlightedHeader = index;
			if ( lastHighlightedHeader >= 0 )
			{
				rc = GetHeaderRect(lastHighlightedHeader);
				DrawHeader(g, lastHighlightedHeader, rc, Border3DStyle.Raised);
			} 
		}

		void OnHighlightHeader(Object timeObject, EventArgs eventArgs) 
		{
			Point mousePos = Control.MousePosition;
			mousePos = PointToClient(mousePos);
			Rectangle rc = ClientRectangle;
			if ( !rc.Contains(mousePos) )
			{
				HighlightHeader(-1);
				HighlightItem(-1, false);
				highlightTimer.Stop();
			}
		}

		void HighlightItem(int index, bool pressed)
		{
			// Exit if item state has not changed
			if ( lastHighlightedItem == index && previousPressed == pressed ) return;
			// Remember if we were pressed or not
			previousPressed = pressed;

			if ( lastHighlightedItem >= 0 )
			{
				// Draw the previously highlighted item in normal state
				using ( Graphics g = Graphics.FromHwnd(Handle) )
				{
					Rectangle itemRect = GetItemRect(g, bands[currentBandIndex], lastHighlightedItem, Rectangle.Empty);
					DrawItem(g, lastHighlightedItem, itemRect, false, false, Rectangle.Empty, null);
				}
			}

			lastHighlightedItem = index;
			if ( lastHighlightedItem >= 0 )
			{
				// Draw this item hightlighed
				using ( Graphics g = Graphics.FromHwnd(Handle) )
				{
					Rectangle itemRect = GetItemRect(g, bands[currentBandIndex], lastHighlightedItem, Rectangle.Empty);
					DrawItem(g, lastHighlightedItem, itemRect, true, pressed, Rectangle.Empty, null);
				}
			}
		}

		void ForceHighlightItem(Graphics g, int index)
		{
		
			// Draw this item hightlighed
			Rectangle itemRect = GetItemRect(g, bands[currentBandIndex], index, Rectangle.Empty);
			DrawItem(g, index, itemRect, true, false, Rectangle.Empty, null);
			
		}

		public void PerformClick(int index)
		{
			FireItemClicked(index);
        }

		void FirePropertyChanged(OutlookBarProperty property)
		{
			if ( PropertyChanged != null )
				PropertyChanged(bands[currentBandIndex], property);

		}

		void FireItemClicked(int index)
		{
			if ( ItemClicked != null )
			{
				if ( currentBandIndex == -1)
					SetCurrentBand(0);
				if ( index >= 0 && index < bands[currentBandIndex].Items.Count )
					ItemClicked(bands[currentBandIndex], bands[currentBandIndex].Items[index]);
			}
		}

		void FireItemDropped(int index)
		{
			if ( ItemDropped != null )
			{
				if ( currentBandIndex == -1)
					SetCurrentBand(0);
				if ( index >= 0 && index < bands[currentBandIndex].Items.Count )
					ItemDropped(bands[currentBandIndex], bands[currentBandIndex].Items[index]);
			}

		}

		Rectangle GetWorkRect()
		{
			Rectangle rc = ClientRectangle;
			if ( borderType != BorderType.None )
				rc.Inflate(-2,-2);
			return rc;
		}

		Rectangle GetViewPortRect()
		{
			// This is the area of the control minus
			// the bands headers
			Rectangle rect = GetWorkRect();
			if ( bands.Count > 0 )
			{
				// Decrease the client area by the number of headers
				int top = rect.Top   1   BAND_HEADER_HEIGHT * (currentBandIndex   1);
				int bottom = rect.Bottom - 1 - BAND_HEADER_HEIGHT * (bands.Count - currentBandIndex - 1);   
				return new Rectangle(rect.Left, top, rect.Width, bottom - top);
			}
			return rect;
		}

		Rectangle GetHeaderRect(int index)
		{
			// Make sure we are within bounds
			Debug.Assert((index >= 0 && index <= bands.Count-1), "Invalid Header Index");
			Rectangle rect = GetWorkRect();

			int top = rect.Top;
			int bottom = rect.Bottom;
			int max = bands.Count;

			if ( index > currentBandIndex )
			{
				top = rect.Bottom - 1 - (max - index) * BAND_HEADER_HEIGHT;
				bottom = rect.Bottom - 1 - (max - index - 1) * BAND_HEADER_HEIGHT;
			}
			else
			{
				top = rect.Top   1   index * BAND_HEADER_HEIGHT;
				bottom = rect.Top   1   (index 1) * BAND_HEADER_HEIGHT;
			}
			return  new Rectangle(rect.Left, top, rect.Width, bottom-top);
		}

		void DrawBackground(Graphics g)
		{
			Rectangle rc = ClientRectangle;
			// If we don't have any bands, just fill the rectangle
			// with the System Control Color
			if ( bands.Count == 0 || currentBandIndex == -1 )
			{
				g.FillRectangle(SystemBrushes.Control, rc);
				return;
			}
			
			if ( backgroundBitmap == null )
			{
				if ( currentBandIndex >= 0 && bands[currentBandIndex] != null )
				{
					using ( SolidBrush b = new SolidBrush(bands[currentBandIndex].Background) )
					{
						// If there is a child control clip the area where the child
						// control will be drawn to avoid flickering
						if ( HasChild() )
						{
							Rectangle clipRect = GetViewPortRect();
							g.ExcludeClip(clipRect);
						}
						g.FillRectangle(b, rc);
					}
				}
			}
			else 
			{
				// Draw custom background bitmap
				// -- I don't know why but the bitmap is not painted properly if using the right size
			    // I use the WindowsAPI to work around the problem
				GDIUtil.StrechBitmap(g, rc, backgroundBitmap);
						
				if ( needBackgroundBitmapResize )
				{
					needBackgroundBitmapResize = false;
					backgroundBitmap = GDIUtil.GetStrechedBitmap(g, rc, backgroundBitmap);
				}
			}

		}

		void DrawBorder(Graphics g)
		{
			Rectangle rc = ClientRectangle;
			if ( borderType == BorderType.FixedSingle )
			{
				g.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width-1, rc.Height-1);
			}
			else if ( borderType == BorderType.Fixed3D )
			{
				ControlPaint.DrawBorder3D(g, rc, Border3DStyle.Sunken);
			}
			else if ( borderType == BorderType.Custom )
			{
				Pen p1 = new Pen(leftTopColor);
				Pen p2 = new Pen(RightBottomColor);
				g.DrawRectangle(p1, rc.Left, rc.Top, rc.Width-1, rc.Height-1);
				g.DrawRectangle(p2, rc.Left 1, rc.Top 1, rc.Width-3, rc.Height-3);
				p1.Dispose();
				p2.Dispose();
			}
		}

		void DrawHeaders(Graphics g)
		{
			Rectangle rc;
			for (int i = 0; i < bands.Count; i  )
			{
				rc = GetHeaderRect(i);
				DrawHeader(g, i, rc, Border3DStyle.RaisedInner);
			}
		}

		void DrawHeader(Graphics g, int index, Rectangle rc, Border3DStyle style)
		{
			string bandName = bands[index].Text;
			using ( Brush b = new SolidBrush(ColorUtil.VSNetControlColor) ) 
			{
				g.FillRectangle(b, rc);
			}
			
			if ( ColorUtil.UsingCustomColor )
			{
				Pen p;
				if ( style == Border3DStyle.RaisedInner )
				{
					p = new Pen(ColorUtil.VSNetBorderColor);
					g.DrawRectangle(p, rc.Left, rc.Top, rc.Width-1, rc.Height-1);
				}
				else 
				{
					using ( Brush fillColor = new SolidBrush(ColorUtil.VSNetSelectionColor))
					{
						g.FillRectangle(fillColor, rc);
					}
					p = new Pen(ColorUtil.VSNetBorderColor);	
					g.DrawRectangle(p, rc.Left, rc.Top, rc.Width-1, rc.Height-1);
				}
				p.Dispose();
			}
			else 
			{
				ControlPaint.DrawBorder3D(g, rc, style);
			}
			StringFormat stringFormat = new StringFormat();
			stringFormat.LineAlignment = StringAlignment.Center;
			stringFormat.Alignment = StringAlignment.Center;	
			g.DrawString(bandName, Font, SystemBrushes.WindowText, rc, stringFormat);
			
		}

		void DrawArrowButtons(Graphics g)
		{
			// If we don't have any bands just return
			if ( bands.Count == 0 )	return;
			
			int first, last;
			GetVisibleRange(g, out first, out last);
						
			Rectangle rc = GetViewPortRect();
			upArrowRect = new Rectangle(0, 0, SystemInformation.VerticalScrollBarWidth, 
				SystemInformation.VerticalScrollBarWidth);
			downArrowRect = upArrowRect;
			upArrowRect.Offset(rc.Right - ARROW_BUTTON_MARGIN - SystemInformation.VerticalScrollBarWidth,
				rc.Top   ARROW_BUTTON_MARGIN);
			downArrowRect.Offset(rc.Right - ARROW_BUTTON_MARGIN - SystemInformation.VerticalScrollBarWidth,
				rc.Bottom - ARROW_BUTTON_MARGIN - SystemInformation.VerticalScrollBarWidth);
			
			// Do we need to show top scroll button
			if ( first > 0 )
			{
				if ( flatArrowButtons )
					DrawFlatArrowButton(g, upArrowRect, true, UpFlatArrowState);
				else
				{
					if ( upArrowPressed )
						ControlPaint.DrawScrollButton(g, upArrowRect, ScrollButton.Up, ButtonState.Pushed);
					else
						ControlPaint.DrawScrollButton(g, upArrowRect, ScrollButton.Up, ButtonState.Normal);
				}
				upArrowVisible = true;
			}
			else
			{
				upArrowVisible = false;
				UpFlatArrowState = DrawState.Normal;
			}

			// Do we need to show bottom scroll button
			if ( last < bands[currentBandIndex].Items.Count -1 )
			{
				
				if ( flatArrowButtons )
					DrawFlatArrowButton(g, downArrowRect, false, DownFlatArrowState);	
				else
				{
					if ( downArrowPressed )
						ControlPaint.DrawScrollButton(g, downArrowRect, ScrollButton.Down, ButtonState.Pushed);
					else
						ControlPaint.DrawScrollButton(g, downArrowRect, ScrollButton.Down, ButtonState.Normal);
				}
				downArrowVisible = true;
			}
			else
			{
				downArrowVisible = false;
				DownFlatArrowState = DrawState.Normal;
			}
		}

		void DrawFlatArrowButton(Graphics g, Rectangle rc, bool up, DrawState state)
		{
			if ( HasChild() )
			{
				// Dont' draw flat button if there is a band with a child control
				return;
			}
			
			Brush b;
			if ( state == DrawState.Hot )
			{
				b = new SolidBrush(ColorUtil.VSNetCheckedColor);
			}
			else
			{
				b = new SolidBrush(ColorUtil.VSNetControlColor);
			}

			g.FillRectangle(b, rc.Left, rc.Top, rc.Width-1, rc.Height-1);
			b.Dispose();

			using ( Pen p = new Pen(ColorUtil.VSNetBorderColor) )
			{
				if ( state == DrawState.Hot )
					g.DrawRectangle(p, rc.Left, rc.Top, rc.Width-2, rc.Height-2);
				GDIUtil.DrawArrowGlyph(g, rc, 7, 4, up, Brushes.Black);
			}

			// Remember last state of the flat arrow button
			if ( up )
			{
				UpFlatArrowState = state;
			}
			else
			{	
				DownFlatArrowState = state;
			}
		}

		void DrawArrowButton(Rectangle buttonRect, ButtonState state)
		{
			if ( HasChild() )
			{
				// No drawing buttons if there is a child control in the current band
				return;
			}
			
			// Directly draw the arrow button
			Graphics g = Graphics.FromHwnd(Handle);
			bool up = true;
			ScrollButton buttonType = ScrollButton.Up;
			if ( buttonRect.Equals(downArrowRect ))
			{
				buttonType = ScrollButton.Down;
				up = false;
			}
			
			if ( flatArrowButtons && !HasChild() )
			{
				int first;
				int last;
				GetVisibleRange(g, out first, out last);

				if ( up && first == 0 ) 
				{
					// up arrow is not visible no need to pain it
					return;
				}
				else if ( up == false && last == bands[currentBandIndex].Items.Count -1)
				{
					// down arrow is not visible no need to pain it
					return;
				}

				// If using flat button and the mouse is still over the button
				// then don't allow drawing it without the hightlight
				Point pos = Control.MousePosition;
				pos = PointToClient(pos);
				if ( buttonRect.Contains(pos) )
				{
					if ( up )
						UpFlatArrowState = DrawState.Hot;
					else
						DownFlatArrowState = DrawState.Hot;

					DrawFlatArrowButton(g, buttonRect, up, DrawState.Hot);
				}
				else
				{
					if ( up )
						UpFlatArrowState = DrawState.Normal;
					else
						DownFlatArrowState = DrawState.Normal;

					DrawFlatArrowButton(g, buttonRect, up, DrawState.Normal);
				}
			}
			else 
				ControlPaint.DrawScrollButton(g, buttonRect, buttonType, state);
			g.Dispose();
		}

		void DrawItems(Graphics g, Rectangle targetRect, OutlookBarBand drawBand)
		{
			
			// If we don't have any bands just return
			if ( bands.Count == 0 )	return;

			Rectangle rc = GetViewPortRect();
			OutlookBarBand band = bands[currentBandIndex];
			if ( drawBand != null ) band = drawBand;
			Debug.Assert(band != null);
			for ( int i = firstItem; i < band.Items.Count; i   )
			{
				Rectangle itemRect = GetItemRect(g, band, i, targetRect);
				if ( itemRect.Top > rc.Bottom )
					break;
				else
					DrawItem(g, i, itemRect, false, false, targetRect, drawBand);
			}
		}

		void DrawItem(Graphics g, int index, Rectangle itemRect, bool hot, bool pressed, Rectangle targetRect, OutlookBarBand drawingBand)
		{
			OutlookBarBand band = bands[currentBandIndex];
			if ( drawingBand != null ) band = drawingBand;

			Point pt = new Point(0,0);
			// Set clip region so that we don't draw outside the viewport
			Rectangle viewPortRect = GetViewPortRect();
			if ( targetRect != Rectangle.Empty )
				viewPortRect = targetRect;
				
			Region clippingRegion = new Region(viewPortRect);
			g.Clip = clippingRegion;
			// Clip the arrow buttons
			g.ExcludeClip(downArrowRect);
			g.ExcludeClip(upArrowRect);
			
			Color textColor = band.TextColor;
			Color backColor = band.Background; 
			Color highLight = band.Background;

			if ( ColorUtil.UsingCustomColor )
			{
				backColor = ColorUtil.VSNetControlColor;
				highLight = ColorUtil.VSNetControlColor;
			}

			if ( hot )
			{
				backColor = ColorUtil.VSNetSelectionColor;
				highLight = ColorUtil.VSNetBorderColor;
			}
			
			if ( pressed ) backColor = ColorUtil.VSNetPressedColor;
			
			if ( band.IconView == IconView.Large && band.LargeImageList != null ) 
			{
				Size largeImageSize = band.LargeImageList.ImageSize;
				pt.X = itemRect.Left   (viewPortRect.Width - largeImageSize.Width) / 2;
				pt.Y = itemRect.Top;

				Rectangle iconRect = new Rectangle(pt, largeImageSize);
				using ( Brush b = new SolidBrush(backColor) )
				{
					iconRect.Inflate(2,2);
					if ( backgroundBitmap != null )
					{
						g.DrawImage(backgroundBitmap, iconRect, iconRect, GraphicsUnit.Pixel);
						// If we have a background bitmap, draw the item background
						// only during the hot state
						if ( hot)
						{
							g.FillRectangle(b, iconRect.Left, iconRect.Top, 
								iconRect.Width, iconRect.Height);
						}
					}
					else 
					{

						// If we don't have a background, always draw the 
						// item backgound
						g.FillRectangle(b, iconRect.Left, iconRect.Top, 
							iconRect.Width, iconRect.Height);
					}
					
					using ( Pen p = new Pen(highLight) )
					{
						if ( backgroundBitmap == null || hot == true )
						{
							g.DrawRectangle(p,  iconRect.Left, iconRect.Top, iconRect.Width-1, iconRect.Height-1);
						}
					}
				}
				
				// I dont' use the image list to do the drawing because cliping does not work
				if ( band.Items[index].ImageIndex != -1 && band.LargeImageList != null )
				{
					// Only if we have a valid image index
					g.SmoothingMode  = SmoothingMode.HighQuality;
					g.DrawImage(band.LargeImageList.Images[band.Items[index].ImageIndex], pt);
					g.SmoothingMode  = SmoothingMode.Default;
				}

				// Draw the label
				int top = itemRect.Top   largeImageSize.Height   Y_LARGEICON_LABEL_OFFSET;
				Size textSize = GetLabelSize(g, band, index);
				int left = itemRect.Left   (viewPortRect.Width - textSize.Width) / 2;
				using ( Brush b = new SolidBrush(textColor) )
				{
					g.DrawString(band.Items[index].Text, Font, b, new Point(left, top));
				}

				// Reset clip region to the whole rectangle so that the arrows can be painted
				clippingRegion.Dispose();
				g.Clip = new Region(viewPortRect);


			}
			else if ( band.IconView == IconView.Small && band.SmallImageList != null ) 
			{
				
				Size smallImageSize = band.SmallImageList.ImageSize;
				pt.X = itemRect.Left;
				pt.Y = itemRect.Top   (itemRect.Height - smallImageSize.Height)/2;

				Rectangle iconRect = new Rectangle(pt, smallImageSize);
				using ( Brush b = new SolidBrush(backColor) )
				{
					iconRect.Inflate(1,1);
					if ( backgroundBitmap != null )
					{
						g.DrawImage(backgroundBitmap, iconRect, iconRect, GraphicsUnit.Pixel);
						// If we have a background bitmap, draw the item background
						// only during the hot state
						if ( hot)
						{
							g.FillRectangle(b, iconRect.Left, iconRect.Top, 
								iconRect.Width, iconRect.Height);
						}
					}
					else 
					{
						// If we don't have a background, always draw the 
						// item backgound
						g.FillRectangle(b, iconRect.Left, iconRect.Top, 
							iconRect.Width, iconRect.Height);
					}
					
					using ( Pen p = new Pen(highLight) )
					{
						if ( backgroundBitmap == null || hot == true )
						{
							g.DrawRectangle(p,  iconRect.Left, iconRect.Top, iconRect.Width-1, iconRect.Height-1);
						}
					}
				}
			
				// I dont' use the image list to do the drawing because cliping does not work
				if ( band.Items[index].ImageIndex != -1 && band.SmallImageList != null )
				{
					// Only if we have a valid image index
					g.DrawImage(band.SmallImageList.Images[band.Items[index].ImageIndex], pt);
				}

				// Draw the label
				Size labelSize = GetLabelSize(g, band, index);
				pt.X = pt.X   smallImageSize.Width   X_SMALLICON_LABEL_OFFSET;
				pt.Y = itemRect.Top   (itemRect.Height - labelSize.Height)/2;
				using ( Brush b = new SolidBrush(textColor) )
				{
					g.DrawString(band.Items[index].Text, Font, b, pt);
				}
			}
	
		}

		void AnimateScroll(int From, int To)
		{
			if ( currentBandIndex == -1 || bands.Count == 0 ) return;
			
			OutlookBarBand band = bands[currentBandIndex];
			// Make sure we are whithin bounds
			Debug.Assert(From >= 0 && From < bands.Count);
			Debug.Assert(To >= 0 &&  To < bands.Count);

			// Get needed dimensions
			Rectangle viewPortRect = GetViewPortRect();
			Rectangle headerRect = new Rectangle(0, 0, viewPortRect.Width, BAND_HEADER_HEIGHT);
			Rectangle drawingRect = new Rectangle(0, 0, viewPortRect.Width, viewPortRect.Height   headerRect.Height * 2);

			// Use straight GDI to do the drawing	
			IntPtr hDC = WindowsAPI.GetDC(Handle);
            IntPtr hDCFrom = WindowsAPI.CreateCompatibleDC(hDC);
			IntPtr hDCTo = WindowsAPI.CreateCompatibleDC(hDC);
			IntPtr bmFrom = WindowsAPI.CreateCompatibleBitmap(hDC, drawingRect.Width, drawingRect.Height);
			IntPtr bmTo = WindowsAPI.CreateCompatibleBitmap(hDC, drawingRect.Width, drawingRect.Height);
			
			// Select in the drawing surface
			IntPtr hOldFromBitmap = WindowsAPI.SelectObject(hDCFrom, bmFrom);
			IntPtr hOldToBitmap = WindowsAPI.SelectObject(hDCTo, bmTo);
            
			// Draw in the memory device context
			Graphics gHeaderDC;
			if ( To > From )
				gHeaderDC = Graphics.FromHdc(hDCTo);
			else
			    gHeaderDC = Graphics.FromHdc(hDCFrom);

			DrawBandBitmap(hDCFrom, bands[From], From, drawingRect);
			DrawBandBitmap(hDCTo,  bands[To], To, drawingRect);
			DrawHeader(gHeaderDC, To, new Rectangle(drawingRect.Left, drawingRect.Top, 
				drawingRect.Width, drawingRect.Top   BAND_HEADER_HEIGHT), Border3DStyle.RaisedInner);
			
			Rectangle rectFrom = GetHeaderRect(From);
			Rectangle rectTo = GetHeaderRect(To);
			int headerHeight = rectFrom.Height;

			// Do the animation with the bitmaps
			if ( To > From)
			{
				for (int y = rectTo.Top - headerHeight; y > rectFrom.Bottom; y -= headerHeight)
				{
					// Draw From bitmap
					WindowsAPI.BitBlt(hDC, viewPortRect.Left ,rectFrom.Bottom   1, 
						viewPortRect.Width, y - rectFrom.Bottom - 1, hDCFrom, 0 , 0, (int)PatBltTypes.SRCCOPY);

					// Draw To Bitmap
					WindowsAPI.BitBlt(hDC, viewPortRect.Left, y, viewPortRect.Width, 
						viewPortRect.Bottom - y   headerHeight, hDCTo, 0, 0, (int)PatBltTypes.SRCCOPY);
					Thread.Sleep(animationSpeed);
				}
			}
			else
			{
				Rectangle rcTo = new Rectangle(viewPortRect.Left, 
					viewPortRect.Bottom, viewPortRect.Width, viewPortRect.Bottom - headerHeight);
				for (int y = rectFrom.Top   1; y < rcTo.Top - headerHeight; y  = headerHeight)
				{
					
					// Draw To Bitmap
					WindowsAPI.BitBlt(hDC, viewPortRect.Left, rectFrom.Top,  viewPortRect.Width, 
						y - rectFrom.Top - 1, hDCTo, 0, 0, (int)PatBltTypes.SRCCOPY);
										
					// Draw From bitmap
					WindowsAPI.BitBlt(hDC, viewPortRect.Left , y, 
						viewPortRect.Width, viewPortRect.Bottom - y, hDCFrom, 0 , 0, (int)PatBltTypes.SRCCOPY);
					Thread.Sleep(animationSpeed);
					
				}
			}

			// Cleanup
			WindowsAPI.ReleaseDC(Handle, hDC);
			WindowsAPI.DeleteDC(hDCFrom);
			WindowsAPI.DeleteDC(hDCTo);
			WindowsAPI.SelectObject(hDCFrom, bmFrom);
			WindowsAPI.SelectObject(hDCTo, bmTo);
			WindowsAPI.DeleteObject(bmFrom);
			WindowsAPI.DeleteObject(bmTo);
            
		}

		void DrawBandBitmap(IntPtr hDC, OutlookBarBand band, int bandIndex, Rectangle drawingRect)
		{
			// Don't do GDI  calls since you cannot mix them with GDI calls
			if ( !HasChild(bandIndex))
			{
				Color cb = band.Background;
				IntPtr brush = WindowsAPI.CreateSolidBrush(ColorUtil.RGB(cb.R, cb.G, cb.B));
			
				RECT rect;
				rect.left = drawingRect.Left;
				rect.top = drawingRect.Top;
				rect.right = drawingRect.Left   drawingRect.Width;
				rect.bottom = drawingRect.Top   drawingRect.Height;

				WindowsAPI.FillRect(hDC, ref rect, brush);
				WindowsAPI.DeleteObject(brush);
			}
				
			if ( HasChild(bandIndex) )
			{
				// Paint child control into memory device context
				Control child = bands[bandIndex].ChildControl;
				bool visible = child.Visible;
				child.Visible = true;
				
				// Change viewport if needed
				POINT pt = new POINT();
				WindowsAPI.SendMessage( child.Handle, 
					(int)Msg.WM_ERASEBKGND, (int)hDC, 0);
				WindowsAPI.SendMessage( child.Handle, 
					(int)Msg.WM_PAINT, (int)hDC, 0);
				if ( !visible) child.Visible = false;
			}
			else 
			{
				DrawItems(Graphics.FromHdc(hDC), drawingRect, bands[bandIndex]);
			}
		}

		bool HasChild()
		{
			// Flag that tell us if the current band 
			// has a child window
			Control childControl = null;
			if ( currentBandIndex != -1 && bands.Count > 0)
			{
				OutlookBarBand band = bands[currentBandIndex];
				childControl = band.ChildControl;
			}
			return childControl != null;
		}

		bool HasChild(int index)
		{
			// Flag that tell us if the current band 
			// has a child window
			Control childControl = null;
			if ( index != -1 && bands.Count > 0 && index >= 0 && index < bands.Count)
			{
				OutlookBarBand band = bands[index];
				childControl = band.ChildControl;
			}
			return childControl != null;
		}

		void GetVisibleRange(Graphics g, out int first, out int last)
		{
			first = firstItem;
			last = 0;
			
			OutlookBarBand band = bands[currentBandIndex];
			Rectangle rc = GetViewPortRect();
			Rectangle itemRect;
			for ( int i = firstItem; i < band.Items.Count; i   )
			{
                itemRect = GetItemRect(g, band, i, Rectangle.Empty);
				if ( itemRect.Bottom > rc.Bottom )
				{
					last = i-1;
					break;
				}
				else 
				{
					last = i;
				}
			}
		}

		Size GetItemSize(Graphics g, OutlookBarBand band, int itemIndex, ItemSizeType itemSizeType)
		{
			Size iconSize = new Size(0,0);
			Size labelSize = new Size(0,0);

			if ( itemSizeType == ItemSizeType.Icon || itemSizeType == ItemSizeType.All )
			{
				iconSize = GetIconSize(band);
				if (itemSizeType == ItemSizeType.Icon)
					return iconSize;
			}
			
			if ( itemSizeType == ItemSizeType.Label || itemSizeType == ItemSizeType.All )
			{
				labelSize = GetLabelSize(g, band, itemIndex);
				if ( itemSizeType == ItemSizeType.Label )
					return labelSize;
			}
			
			if ( itemSizeType == ItemSizeType.All )
			{
				if ( band.IconView == IconView.Small )
					return new Size(iconSize.Width   labelSize.Width   X_SMALLICON_LABEL_OFFSET, 
						iconSize.Height > labelSize.Height?iconSize.Height:labelSize.Height);
				else
					return new Size(iconSize.Width>labelSize.Width?iconSize.Width:labelSize.Width, iconSize.Height  
					labelSize.Height   Y_LARGEICON_LABEL_OFFSET   Y_LARGEICON_SPACING);
			}

			return new Size(0,0);
		}

		Size GetIconSize(OutlookBarBand band)
		{
			
			if ( band.IconView == IconView.Large && band.LargeImageList != null )
				return band.LargeImageList.ImageSize;
			else if ( band.IconView == IconView.Small && band.SmallImageList != null )
				return band.SmallImageList.ImageSize;
			return new Size(0,0);
		}

		Size GetLabelSize(Graphics g, OutlookBarBand band, int itemIndex)
		{
            
			Size textSize = new Size(0,0);
			if ( band.IconView == IconView.Large )
			{
				// Calculate text rectangle including word breaks if needed
				Rectangle rect = GetViewPortRect();
				Rectangle textRect = Rectangle.FromLTRB(rect.Left, rect.Top, rect.Width, rect.Top);
				
				// The TextUtil function is going to call GDI, but the Graphics object
				// is already being used by GDI . Pass a null reference so that the TextUtil
				// function uses the Screen Device to calculate the text size
				if ( band.Items[itemIndex].Text != null )
				{
					textSize = TextUtil.GetTextSize(null, band.Items[itemIndex].Text, 
						Font, ref textRect, DrawTextFormatFlags.DT_CALCRECT | 
						DrawTextFormatFlags.DT_CENTER|DrawTextFormatFlags.DT_WORDBREAK); 				
				}
				return textSize;
			}
			else
			{
				// Same as above
				// Calculate text rectangle single line
				if ( band.Items[itemIndex].Text != null )
				{
					textSize = TextUtil.GetTextSize(null, band.Items[itemIndex].Text, Font); 				
				}
				return textSize;
			}
		}

		Rectangle GetIconRect(int index)
		{
			Rectangle viewPortRect = GetViewPortRect();
			OutlookBarBand band = bands[currentBandIndex];
            Debug.Assert(band != null);
            Size imageSize = Size.Empty;
			Rectangle itemRect = Rectangle.Empty;
			Point pt = new Point(0,0);
			
			using ( Graphics g = Graphics.FromHwnd(Handle) )
			{
				itemRect = GetItemRect(g, band, index, Rectangle.Empty);
			}

			if (  band.IconView == IconView.Small )
			{
				if ( band.SmallImageList != null )
				{
					imageSize = band.SmallImageList.ImageSize;
					pt.X = itemRect.Left;
					pt.Y = itemRect.Top   (itemRect.Height - imageSize.Height)/2;
				}
				return new Rectangle(pt, imageSize);
			}
			else
			{
				if ( band.LargeImageList != null )
				{
					imageSize = band.LargeImageList.ImageSize;
					pt.X = itemRect.Left   (viewPortRect.Width - imageSize.Width) / 2;
					pt.Y = itemRect.Top;
				}
				return new Rectangle(pt, imageSize);
			}
		}

		Rectangle GetLabelRect(int index)
		{
			Rectangle viewPortRect = GetViewPortRect();
			OutlookBarBand band = bands[currentBandIndex];
			Debug.Assert(band != null);
			Size imageSize = Size.Empty;
			Rectangle itemRect = Rectangle.Empty;
			Size labelSize = Size.Empty;
			Point pt = new Point(0,0);
			
			using ( Graphics g = Graphics.FromHwnd(Handle) )
			{
				itemRect = GetItemRect(g, band, index, Rectangle.Empty);
				labelSize = GetLabelSize(g, band, index);
			}

			if (  band.IconView == IconView.Small )
			{
				if ( band.SmallImageList != null )
				{ 
					imageSize = band.SmallImageList.ImageSize;
					// Don't include the offset between the icon and the label
					// so that we don't leave a miss hit gap
					pt.X = itemRect.Left   imageSize.Width;
					pt.Y = itemRect.Top   (itemRect.Height - labelSize.Height)/2;
				}
				return new Rectangle(pt.X, pt.Y  , labelSize.Width   X_SMALLICON_LABEL_OFFSET 2 , labelSize.Height);
			}
			else
			{
				if ( band.LargeImageList != null )
				{
					imageSize = band.LargeImageList.ImageSize;
					pt.X = itemRect.Left   (viewPortRect.Width - labelSize.Width) / 2;
					// Don't include the offset between the icon and the label
					// so that we don't leave a miss hit gap
					pt.Y = itemRect.Top   imageSize.Height;
				}
				return new Rectangle(pt.X, pt.Y, labelSize.Width, labelSize.Height  Y_LARGEICON_LABEL_OFFSET 2);
			}
		}

		private void HandleRecreated(object sender, EventArgs e)
		{
			// If any of the child destroy itself and recreate
			// reattach the Outlookbar as the parent
			Control c = (Control)sender;
			IntPtr hParent = WindowsAPI.GetParent(c.Handle);
			if ( hParent != Handle )
			{
				WindowsAPI.SetParent(c.Handle, Handle);
			}
		}

		void CreateContextMenu()
		{
			// context menu
			MenuItemEx largeIconsMenu = new MenuItemEx("Large Icons", new EventHandler(OnContextMenu));
			MenuItemEx smallIconsMenu = new MenuItemEx("Small Icons", new EventHandler(OnContextMenu));
			MenuItemEx separator1 = new MenuItemEx("-", new EventHandler(OnContextMenu));
			MenuItemEx renameGroup = new MenuItemEx("Rename Group", new EventHandler(OnContextMenu));
			MenuItemEx separator2 = new MenuItemEx("-", new EventHandler(OnContextMenu));
			MenuItemEx renameShortcut = new MenuItemEx("Rename Shortcut", new EventHandler(OnContextMenu));
            			
			contextMenu = new ContextMenu();
			contextMenu.MenuItems.Add(0, largeIconsMenu);
			contextMenu.MenuItems.Add(1, smallIconsMenu);
			contextMenu.MenuItems.Add(2, separator1);
			contextMenu.MenuItems.Add(3, renameGroup);
            contextMenu.MenuItems.Add(4, separator2);
			contextMenu.MenuItems.Add(5, renameShortcut);
            			
			contextMenu.Popup  = new EventHandler(ContextMenuPopup);
			this.ContextMenu = contextMenu;
		}

		public void ContextMenuPopup(object sender, EventArgs e)
		{
			// Update the menu state before displaying it
			OutlookBarBand band = bands[currentBandIndex];

			MenuItemEx largeIconsMenu = (MenuItemEx)ContextMenu.MenuItems[0];
			MenuItemEx smallIconsMenu = (MenuItemEx)ContextMenu.MenuItems[1];
			MenuItemEx renameGroup = (MenuItemEx)ContextMenu.MenuItems[3];
			MenuItemEx renameShortcut = (MenuItemEx)ContextMenu.MenuItems[5];

            
			int index;
			HitTestType hit = HitTest(lastClickedPoint, out index, false);
			if ( hit == HitTestType.Header )
			{
				renameGroup.Enabled = true;
				largeIconsMenu.Enabled = false;
				smallIconsMenu.Enabled = false;
				renameShortcut.Enabled = false;
			}
			else if ( hit == HitTestType.Item )
			{
				renameGroup.Enabled = false;
				largeIconsMenu.Enabled = false;
				smallIconsMenu.Enabled = false;
				renameShortcut.Enabled = true;
			}
			else 
			{
				renameGroup.Enabled = false;
				largeIconsMenu.Enabled = true;
				smallIconsMenu.Enabled = true;
				renameShortcut.Enabled = false;

			}
			
			if ( HasChild() )
			{
				largeIconsMenu.RadioCheck = false;
				smallIconsMenu.RadioCheck = false;
			}
			else 
			{
				largeIconsMenu.RadioCheck = (band.IconView == IconView.Large);
				smallIconsMenu.RadioCheck = (band.IconView == IconView.Small);
			}
		
		}

		void RenameItem()
		{
            // Display a edit control that will do the editing of  the item
          	// Get the item index first
			int index;
			HitTestType hit = HitTest(lastClickedPoint, out index, false);
			using ( Graphics g = Graphics.FromHwnd(Handle) )
			{
				Rectangle itemRect = GetLabelRect(index);
				// Empty the text box first
				textBox.Text = "";
				// Move it to the top of the item rectangle
				if ( bands[currentBandIndex].IconView == IconView.Large )
                    itemRect.Inflate(5, 0);
				else
					itemRect = new Rectangle(itemRect.Left, itemRect.Top, itemRect.Right, itemRect.Height   5);

				textBox.Bounds = itemRect;
				// initialize the text box to the item text
				textBox.Text = bands[currentBandIndex].Items[index].Text;
                // Flag that we are editing an item and not a header
				// --We'll use this on the textbox event handlers  
				editingAnItem = true;
				textBox.Visible = true;
				textBox.Focus();
			}
		}

		void RenameHeader()
		{
			// Display a edit control that will do the editing of the header
			// Get the item index first
			int index;
			HitTestType hit = HitTest(lastClickedPoint, out index, false);
			using ( Graphics g = Graphics.FromHwnd(Handle) )
			{
				Rectangle headerRect = GetHeaderRect(index);
				// Empty the text box first
				textBox.Text = "";
				textBox.Bounds = headerRect;
				// initialize the text box to the item text
				textBox.Text = bands[index].Text;
				// Flag that we are editing an header and not a item
				// --We'll use this on the textbox event handlers 
				editingAnItem = false;
				textBox.Visible = true;
				textBox.Focus();
			}
		}
        
		void TextBoxKeyDown(object sender, KeyEventArgs e)
		{
            if ( e.KeyCode == Keys.Enter )
				ProcessTextBoxEditing();
		}

		void TextBoxLostFocus(object sender, EventArgs e)
		{
			ProcessTextBoxEditing();
		}

		void ProcessTextBoxEditing()
		{
			// Only if the textbox is actually visible
			if ( textBox.Visible == false ) return;
            
			string text = textBox.Text;
			textBox.Visible = false;
			int index;
			HitTestType hit = HitTest(lastClickedPoint, out index, false);
			if ( editingAnItem )
			{
				bands[currentBandIndex].Items[index].Text = text;
				// Fire property changed
				FirePropertyChanged(OutlookBarProperty.ShortcutNameChanged);
			}
			else
			{
				bands[index].Text = text;
				// Fire property changed
				FirePropertyChanged(OutlookBarProperty.GroupNameChanged);
			}
			// Invalidate control so that new label size
			// is recalculated
			Invalidate();
		}
		#endregion
		
	}
	#endregion
}

标签: 截图 C# OutLook 下载

实例下载地址

C# 实现 outlookbar控件 示例完整源码下载 有截图 含UtilityLibrary以及完整源码

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

第 1 楼 china521 发表于: 2015-12-16 22:13 23
确实不错

支持(0) 盖楼(回复)

第 2 楼 Liangbaiyu 发表于: 2018-03-14 09:50 23
看着不错。。未试。。

支持(0) 盖楼(回复)

发表评论

(您的评论需要经过审核才能显示)

查看所有2条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警