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

📄 comboboxbase.cs

📁 c#编写的仿OUTLOOK工具条的Winform菜单
💻 CS
📖 第 1 页 / 共 2 页
字号:
				base.OnSelectedIndexChanged(e);
			}
			
			fireOnSelectedIndexChanged = true;

		}

		#endregion

		#region Properties
		public bool ToolBarUse
		{
			set { toolBarUse = value; }
			get { return toolBarUse; }
		}
		#endregion

		#region Methods
		public void SetFontHeight(int newHeight)
		{
			FontHeight = newHeight;
		}
		
		#endregion
		
		#region Implementation
		void PaintComboBoxBackground(Graphics g, Color backColor)
		{
			Rectangle rc = ClientRectangle;
			rc.Inflate(-1, -1);
			g.FillRectangle(new SolidBrush(backColor), rc);
		}

		internal void DrawComboBoxBorder(Graphics g, Color color)
		{
            // Keep track of what we painted last
			if ( color.Equals(ColorUtil.VSNetBorderColor) )
			{
				highlighted =  true;
			}
			else
			{
				highlighted = false;
			}
			
			Pen pen = new Pen(new SolidBrush(color), 1);
			g.DrawRectangle(pen, ClientRectangle.Left, ClientRectangle.Top, ClientRectangle.Width-1, ClientRectangle.Height-1);
			
			// We need to draw an extra "inner" border to erase the ugly 3D look of  the combobox
			g.DrawRectangle(Pens.White, ClientRectangle.Left+1, ClientRectangle.Top+1, 
				ClientRectangle.Width-SystemInformation.VerticalScrollBarWidth, ClientRectangle.Height-3);
		

		}

		internal void DrawComboBoxArrowNormal(Graphics g, bool disable)
		{
			int left, top, arrowWidth, height;
			CalculateArrowBoxCoordinates(out left, out top, out arrowWidth, out height);

			// We are not going to draw the arrow background using the total
			// width of the arrow button in the combobox because it is too wide
			// and it does not look nice. However, we need to paint over the section
			// that correspond to the "original" arrow button dimension to avoid
			// clipping or painting problems
			Brush stripeColorBrush = new SolidBrush(ColorUtil.VSNetControlColor);
			if ( Enabled )
			{
				int width = SystemInformation.VerticalScrollBarWidth - ARROW_WIDTH;
				g.FillRectangle(Brushes.White, new Rectangle(left-width, top, 
					SystemInformation.VerticalScrollBarWidth, height));
			}

			if ( !disable) 
			{
				// Erase previous selected rectangle first
				DrawComboBoxArrowSelected(g, true);
				// Now draw the unselected background
				g.FillRectangle(stripeColorBrush, left, top, arrowWidth, height);
			}
			else 
			{
				// Now draw the unselected background
				g.FillRectangle(stripeColorBrush, left-1, top-1, arrowWidth+2, height+2);
			}
			
			DrawArrowGlyph(g, disable);
			
		}

		internal void DrawComboBoxArrowSelected(Graphics g, bool erase)
		{
			
			int left, top, arrowWidth, height;
			CalculateArrowBoxCoordinates(out left, out top, out arrowWidth, out height);

			// We are not going to draw the arrow background using the total
			// width of the arrow button in the combobox because it too wide
			// and it does not look nice. However, we need to paint over the section
			// that correspond to the "original" arrow button dimension to avoid
			// clipping or painting problems
			if ( Enabled )
			{
				int width = SystemInformation.VerticalScrollBarWidth - ARROW_WIDTH;
				g.FillRectangle(Brushes.White, new Rectangle(left-width, top, 
					SystemInformation.VerticalScrollBarWidth, height));
			}
									
			if ( !erase )
			{
				if (DroppedDown) 
				{
					// If showing the list portion of the combo box, draw the arrow portion background using
					// the highlight color with some transparency
					// Don't use the graphics object that we get passed because that is associated
					// to the edit control of the combobox and we actually want to paint on the combobox area
					// and not be clipped only to the edit control client area
					Graphics cbg = CreateGraphics();
					cbg.FillRectangle(new SolidBrush(ColorUtil.VSNetPressedColor), left-1, top-1, arrowWidth+2, height+2);
					cbg.DrawRectangle(new Pen( new SolidBrush(ColorUtil.VSNetBorderColor), 1), left-1, top-1, arrowWidth+2, height+3);
					// The DrawArrow won't work with the passed Graphics object since it is the one for
					// the edit control and we need to paint on the combobox
					DrawArrowGlyph(cbg, false);
					cbg.Dispose();
					forceUpdate = true;
					return;
				}
				else
				{
					g.FillRectangle(new SolidBrush(ColorUtil.VSNetSelectionColor), left-1, top-1, arrowWidth+2, height+2);
					g.DrawRectangle(new Pen( new SolidBrush(ColorUtil.VSNetBorderColor), 1), left-1, top-2, arrowWidth+2, height+3);
				}
				
			}
			else 
			{
				g.FillRectangle(Brushes.White, left-1, top-1, arrowWidth+2, height+2);
			}

			DrawArrowGlyph(g, false);
         			
		}

		void CalculateArrowBoxCoordinates(out int left, out int top, out int width, out int height)
		{
			Rectangle rc = ClientRectangle;
			width = ARROW_WIDTH;
			left = rc.Right - width - 2;
			top = rc.Top + 2;
			height = rc.Height - 4;
		}

		void DrawArrowGlyph(Graphics g, bool disable)
		{
            int left, top, arrowWidth, height;
			CalculateArrowBoxCoordinates(out left, out top, out arrowWidth, out height);

			// Draw arrow glyph
			Point[] pts = new Point[3];
			pts[0] = new Point(left + arrowWidth/2 - 2, top + height/2-1);
			pts[1] = new Point(left + arrowWidth/2 + 3,  top + height/2-1);
			pts[2] = new Point(left + arrowWidth/2, (top + height/2-1) + 3);
			
			if ( disable ) 
			{
				g.FillPolygon(new SolidBrush(SystemColors.ControlDark), pts);	
			}
			else 
			{
				g.FillPolygon(Brushes.Black, pts);
			}
		}

		void ForcePaint(ref Message m)
		{
			// Similar code to the OnPaint handler
			Graphics g = Graphics.FromHwnd(Handle);
			if (Enabled == false)
			{
				DrawDisableState();
				return;
			}

			Rectangle rc = ClientRectangle;
			if ( SelectedIndex == -1 ) 
				if ( Items.Count > 0 )
				{
					fireOnSelectedIndexChanged = false;
					SelectedIndex = 0;
				}
			
			DrawComboBoxItemEx( g, rc, SelectedIndex, false, true);
						
			if ( !ContainsFocus )
			{
				DrawComboBoxBorder(g, SystemColors.Window);
				DrawComboBoxArrowNormal(g, false);
			}
			else 
			{
                DrawComboBoxBorder(g, ColorUtil.VSNetBorderColor);
			}
		}

		internal void ForceUpdate()
		{
			using (	Graphics g = CreateGraphics())
			{
				if ( ContainsFocus )
					DrawComboBoxArrowSelected(g, false);
			}
		}

		void StartHook()
		{     
			// Mouse hook
			WindowsAPI.HookProc mouseHookProc = new WindowsAPI.HookProc(MouseHook);
			mouseProcHandle = GCHandle.Alloc(mouseHookProc);
			mouseHookHandle = WindowsAPI.SetWindowsHookEx((int)WindowsHookCodes.WH_MOUSE, 
				mouseHookProc, IntPtr.Zero, WindowsAPI.GetCurrentThreadId());
			if ( mouseHookHandle == IntPtr.Zero) 
				throw new SecurityException();
		}

		void EndHook()
		{
			// Unhook		
			WindowsAPI.UnhookWindowsHookEx(mouseHookHandle);
			mouseProcHandle.Free();
			mouseHookHandle = IntPtr.Zero;

		}

		IntPtr MouseHook(int code, IntPtr wparam, IntPtr lparam) 
		{
			MOUSEHOOKSTRUCT mh = (MOUSEHOOKSTRUCT )Marshal.PtrToStructure(lparam, typeof(MOUSEHOOKSTRUCT));
			if ( mh.hwnd != Handle && !DroppedDown
				&& (wparam == (IntPtr)Msg.WM_LBUTTONDOWN || wparam == (IntPtr)Msg.WM_RBUTTONDOWN) 
				|| wparam == (IntPtr)Msg.WM_NCLBUTTONDOWN )
			{
				// Loose focus
				WindowsAPI.SetFocus(IntPtr.Zero);
			}
			else if ( mh.hwnd != Handle && !DroppedDown 
				&& (wparam == (IntPtr)Msg.WM_LBUTTONUP || wparam == (IntPtr)Msg.WM_RBUTTONUP) 
				|| wparam == (IntPtr)Msg.WM_NCLBUTTONUP )
			{
				WindowsAPI.SetFocus(IntPtr.Zero);

			}
			return WindowsAPI.CallNextHookEx(mouseHookHandle, code, wparam, lparam);
		}

		protected virtual void DrawDisableState()
		{
			Graphics g = CreateGraphics();
			PaintComboBoxBackground(g, SystemColors.Window);
			DrawComboBoxBorder(g, SystemColors.ControlDark);
			DrawComboBoxArrowNormal(g, true);
			g.Dispose();
		}

		protected virtual void DrawComboBoxItem(Graphics g, Rectangle bounds, int Index, bool selected, bool editSel)
		{
			// Draw the the combo item
			using ( Brush b = new SolidBrush(SystemColors.Window) )
			{
				g.FillRectangle( b, bounds.Left, bounds.Top, bounds.Width, bounds.Height);
			}
						
			if ( selected && !editSel)
			{
				// Draw highlight rectangle
				Pen p1 = new Pen(ColorUtil.VSNetBorderColor);
				Brush b1 = new SolidBrush(ColorUtil.VSNetSelectionColor);
				g.FillRectangle(b1, bounds.Left, bounds.Top, bounds.Width, bounds.Height);
				g.DrawRectangle(p1, bounds.Left, bounds.Top, bounds.Width-1, bounds.Height-1);
				p1.Dispose();
				b1.Dispose();
			}
			else
			{
				// Erase highlight rectangle
				g.FillRectangle(new SolidBrush(SystemColors.Window), bounds.Left, bounds.Top, bounds.Width, bounds.Height);
				
				if ( editSel && ContainsFocus ) 
				{
					// Draw higlighted arrow
					Debug.WriteLine("Drawing ComboBox Arrow...");
					DrawComboBoxArrowSelected(g, false);
				}
			}
		}

		protected virtual void DrawComboBoxItemEx(Graphics g, Rectangle bounds, int Index, bool selected, bool editSel)
		{
			// This function is only called form the OnPaint handler and the Graphics object passed is the one
			// for the combobox itself as opossed to the one for the edit control in the combobox
			// doing this allows us to be able to avoid clipping problems with text strings
			
			// Draw the the combo item
			bounds.Inflate(-3, -3);
			using ( Brush b = new SolidBrush(SystemColors.Window) )
			{
				g.FillRectangle( b, bounds.Left, bounds.Top, bounds.Width, bounds.Height);
			}
						
			if ( selected && !editSel)
			{
				// Draw highlight rectangle
				Pen p1 = new Pen(ColorUtil.VSNetBorderColor);
				Brush b1 = new SolidBrush(ColorUtil.VSNetSelectionColor);
				g.FillRectangle(b1, bounds.Left, bounds.Top, bounds.Width, bounds.Height);
				g.DrawRectangle(p1, bounds.Left, bounds.Top, bounds.Width-1, bounds.Height-1);
				p1.Dispose();
				b1.Dispose();
			}
			else
			{
				// Erase highlight rectangle
				g.FillRectangle(new SolidBrush(SystemColors.Window), bounds.Left, bounds.Top, bounds.Width, bounds.Height);
				if ( editSel && ContainsFocus ) 
				{
					// Draw higlighted arrow
					DrawComboBoxArrowSelected(g, false);
				}
			}
		}

		#endregion
	
	}
	
}

⌨️ 快捷键说明

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