⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 outlookbar.cs

📁 c#编写的仿OUTLOOK工具条的Winform菜单
💻 CS
📖 第 1 页 / 共 5 页
字号:
				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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -